a922efcf374c60309ef597608b753de1ff361cd7
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia / Common / IMediaBuffer.cs
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Diagnostics;
19 using System.Runtime.InteropServices;
20
21 namespace Tizen.Multimedia
22 {
23     public interface IReadOnlyBuffer
24     {
25         /// <summary>
26         /// Gets or sets a value at the specified index.
27         /// </summary>
28         /// <param name="index">The index of the value to get or set.</param>
29         /// <exception cref="ArgumentOutOfRangeException">
30         ///     index is less than zero.
31         ///     <para>-or-</para>
32         ///     index is equal to or greater than <see cref="Length"/>.
33         /// </exception>
34         /// <exception cref="ObjectDisposedException">The object that owns the current buffer already has been disposed of.</exception>
35         /// <exception cref="InvalidOperationException">The buffer is not available. i.e. not writable state.</exception>
36         byte this[int index]
37         {
38             get;
39         }
40         /// <summary>
41         /// Gets the size of the buffer, in bytes.
42         /// </summary>
43         int Length
44         {
45             get;
46         }
47
48         /// <summary>
49         /// Copies data from a byte array to the buffer.
50         /// </summary>
51         /// <param name="source">The array to copy from.</param>
52         /// <param name="startIndex">The zero-based index in the source array where copying should start.</param>
53         /// <param name="length">The number of array elements to copy.</param>
54         /// <exception cref="ArgumentOutOfRangeException">startIndex or length is not valid.</exception>
55         /// <exception cref="ObjectDisposedException">The object that owns the current buffer already has been disposed of.</exception>
56         void CopyTo(byte[] dest, int startIndex, int length);
57
58         /// <summary>
59         /// Copies data from a byte array to the buffer.
60         /// </summary>
61         /// <param name="source">The array to copy from.</param>
62         /// <param name="startIndex">The zero-based index in the source array where copying should start.</param>
63         /// <param name="length">The number of array elements to copy.</param>
64         /// <param name="offset">The zero-based index in the buffer where copying should start.</param>
65         /// <exception cref="ArgumentOutOfRangeException">startIndex, offset or length is not valid.</exception>
66         /// <exception cref="ObjectDisposedException">The object that owns the current buffer already has been disposed of.</exception>
67         void CopyTo(byte[] dest, int startIndex, int length, int offset);
68     }
69
70     public interface IMediaBuffer : IReadOnlyBuffer
71     {
72         /// <summary>
73         /// Gets or sets a value at the specified index.
74         /// </summary>
75         /// <param name="index">The index of the value to get or set.</param>
76         /// <exception cref="ArgumentOutOfRangeException">
77         ///     index is less than zero.
78         ///     <para>-or-</para>
79         ///     index is equal to or greater than <see cref="Length"/>.
80         /// </exception>
81         /// <exception cref="ObjectDisposedException">The object that owns the current buffer already has been disposed of.</exception>
82         /// <exception cref="InvalidOperationException">The buffer is not available. i.e. not writable state.</exception>
83         byte this[int index]
84         {
85             get;
86             set;
87         }
88         /// <summary>
89         /// Copies data from the buffer to a byte array.
90         /// </summary>
91         /// <param name="dest">The array to copy to.</param>
92         /// <param name="startIndex">The zero-based index in the dest array where copying should start.</param>
93         /// <param name="length">The number of elements to copy.</param>
94         /// <exception cref="ArgumentOutOfRangeException">startIndex or length is not valid.</exception>
95         /// <exception cref="ObjectDisposedException">The object that owns the current buffer already has been disposed of.</exception>
96         /// <exception cref="InvalidOperationException">The buffer is not available. i.e. not writable state.</exception>
97
98         void CopyFrom(byte[] source, int startIndex, int length);
99
100         /// <summary>
101         /// Copies data from the buffer to a byte array.
102         /// </summary>
103         /// <param name="dest">The array to copy to.</param>
104         /// <param name="startIndex">The zero-based index in the dest array where copying should start.</param>
105         /// <param name="length">The number of elements to copy.</param>
106         /// <param name="offset">The zero-based index in the buffer where copying should start.</param>
107         /// <exception cref="ArgumentOutOfRangeException">startIndex, offset or length is not valid.</exception>
108         /// <exception cref="ObjectDisposedException">The object that owns the current buffer already has been disposed of.</exception>
109         /// <exception cref="InvalidOperationException">The buffer is not available. i.e. not writable state.</exception>
110         void CopyFrom(byte[] source, int startIndex, int length, int offset);
111
112     }
113
114     /// <summary>
115     /// Represents a buffer for a <see cref="MediaPacket"/>.
116     /// </summary>
117     internal class DependentMediaBuffer : IMediaBuffer
118     {
119         private readonly IBufferOwner _owner;
120         private readonly IntPtr _dataHandle;
121
122         internal DependentMediaBuffer(IBufferOwner owner, IntPtr dataHandle, int size)
123         {
124             Debug.Assert(owner != null, "Owner is null!");
125             Debug.Assert(!owner.IsDisposed, "Owner has been already disposed!");
126             Debug.Assert(dataHandle != IntPtr.Zero, "dataHandle is null!");
127             Debug.Assert(size >= 0, "size must not be negative!");
128
129             _owner = owner;
130             _dataHandle = dataHandle;
131             Length = size;
132         }
133
134         public byte this[int index]
135         {
136             get
137             {
138                 _owner.ValidateBufferReadable(this);
139
140                 if (index < 0 || index >= Length)
141                 {
142                     throw new ArgumentOutOfRangeException($"Valid index range is [0, { nameof(Length) }).");
143                 }
144
145                 return Marshal.ReadByte(_dataHandle, index);
146             }
147             set
148             {
149                 _owner.ValidateBufferWritable(this);
150
151                 Marshal.WriteByte(_dataHandle, index, value);
152             }
153         }
154
155         /// <summary>
156         /// Validates the range
157         /// </summary>
158         /// <param name="offset"></param>
159         /// <param name="length"></param>
160         /// <exception cref="ArgumentOutOfRangeException">
161         ///     offset + length is greater than <see cref="Length"/>.
162         ///     <para>-or-</para>
163         ///     offset or length is less than zero.
164         /// </exception>
165         private void ValidateRange(int offset, int length)
166         {
167             if (offset + length > Length)
168             {
169                 throw new ArgumentOutOfRangeException("offset + length can't be greater than length of the buffer.");
170             }
171             if (length < 0)
172             {
173                 throw new ArgumentOutOfRangeException($"Length can't be less than zero : { length }.");
174             }
175             if (offset < 0)
176             {
177                 throw new ArgumentOutOfRangeException($"Offset can't be less than zero : { offset }.");
178             }
179         }
180
181         public void CopyFrom(byte[] source, int startIndex, int length, int offset)
182         {
183             _owner.ValidateBufferReadable(this);
184
185             if (startIndex < 0)
186             {
187                 throw new ArgumentOutOfRangeException("startIndex can't be less than zero.");
188             }
189             if (startIndex + length > source.Length)
190             {
191                 throw new ArgumentOutOfRangeException("startIndex + length can't be greater than source.Length.");
192             }
193
194             ValidateRange(offset, length);
195
196             Marshal.Copy(source, startIndex, IntPtr.Add(_dataHandle, offset), length);
197         }
198
199         public void CopyFrom(byte[] source, int startIndex, int length)
200         {
201             CopyFrom(source, startIndex, length, 0);
202         }
203
204          public void CopyTo(byte[] dest, int startIndex, int length, int offset)
205         {
206             _owner.ValidateBufferWritable(this);
207
208             if (startIndex < 0)
209             {
210                 throw new ArgumentOutOfRangeException("Start index can't be less than zero.");
211             }
212             if (startIndex + length > dest.Length)
213             {
214                 throw new ArgumentOutOfRangeException("startIndex + length can't be greater than dest.Length.");
215             }
216
217             ValidateRange(offset, length);
218
219             Marshal.Copy(IntPtr.Add(_dataHandle, offset), dest, startIndex, length);
220         }
221
222         public void CopyTo(byte[] dest, int startIndex, int length)
223         {
224             CopyTo(dest, startIndex, length, 0);
225         }
226
227         public int Length { get; }
228     }
229 }