Release 4.0.0-preview1-00051
[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     /// <summary>
24     /// Provides functionality to read a media buffer.
25     /// </summary>
26     public interface IReadOnlyBuffer
27     {
28         /// <summary>
29         /// Gets or sets a value at the specified index.
30         /// </summary>
31         /// <param name="index">The index of the value to get or set.</param>
32         /// <exception cref="ArgumentOutOfRangeException">
33         ///     index is less than zero.\n
34         ///     -or-\n
35         ///     index is equal to or greater than <see cref="Length"/>.
36         /// </exception>
37         /// <exception cref="ObjectDisposedException">The object that owns the current buffer already has been disposed of.</exception>
38         /// <exception cref="InvalidOperationException">The buffer is not available. i.e. not writable state.</exception>
39         byte this[int index]
40         {
41             get;
42             set;
43         }
44         /// <summary>
45         /// Gets the size of the buffer, in bytes.
46         /// </summary>
47         int Length
48         {
49             get;
50         }
51
52         /// <summary>
53         /// Copies data from a byte array to the buffer.
54         /// </summary>
55         /// <param name="dest">The array to copy to.</param>
56         /// <param name="startIndex">The zero-based index in the source array where copying should start.</param>
57         /// <param name="length">The number of array elements to copy.</param>
58         /// <exception cref="ArgumentOutOfRangeException">startIndex or length is not valid.</exception>
59         /// <exception cref="ObjectDisposedException">The object that owns the current buffer already has been disposed of.</exception>
60         void CopyTo(byte[] dest, int startIndex, int length);
61
62         /// <summary>
63         /// Copies data from a byte array to the buffer.
64         /// </summary>
65         /// <param name="dest">The array to copy to.</param>
66         /// <param name="startIndex">The zero-based index in the source array where copying should start.</param>
67         /// <param name="length">The number of array elements to copy.</param>
68         /// <param name="offset">The zero-based index in the buffer where copying should start.</param>
69         /// <exception cref="ArgumentOutOfRangeException">startIndex, offset or length is not valid.</exception>
70         /// <exception cref="ObjectDisposedException">The object that owns the current buffer already has been disposed of.</exception>
71         void CopyTo(byte[] dest, int startIndex, int length, int offset);
72     }
73
74     /// <summary>
75     /// Provides functionality to read and write a media buffer.
76     /// </summary>
77     public interface IMediaBuffer : IReadOnlyBuffer
78     {
79         /// <summary>
80         /// Copies data from the buffer to a byte array.
81         /// </summary>
82         /// <param name="source">The array to copy from.</param>
83         /// <param name="startIndex">The zero-based index in the dest array where copying should start.</param>
84         /// <param name="length">The number of elements to copy.</param>
85         /// <exception cref="ArgumentOutOfRangeException">startIndex or length is not valid.</exception>
86         /// <exception cref="ObjectDisposedException">The object that owns the current buffer already has been disposed of.</exception>
87         /// <exception cref="InvalidOperationException">The buffer is not available. i.e. not writable state.</exception>
88
89         void CopyFrom(byte[] source, int startIndex, int length);
90
91         /// <summary>
92         /// Copies data from the buffer to a byte array.
93         /// </summary>
94         /// <param name="source">The array to copy from.</param>
95         /// <param name="startIndex">The zero-based index in the dest array where copying should start.</param>
96         /// <param name="length">The number of elements to copy.</param>
97         /// <param name="offset">The zero-based index in the buffer where copying should start.</param>
98         /// <exception cref="ArgumentOutOfRangeException">startIndex, offset or length is not valid.</exception>
99         /// <exception cref="ObjectDisposedException">The object that owns the current buffer already has been disposed of.</exception>
100         /// <exception cref="InvalidOperationException">The buffer is not available. i.e. not writable state.</exception>
101         void CopyFrom(byte[] source, int startIndex, int length, int offset);
102     }
103
104     /// <summary>
105     /// Represents a buffer for a <see cref="MediaPacket"/>.
106     /// </summary>
107     internal class DependentMediaBuffer : IMediaBuffer
108     {
109         private readonly IBufferOwner _owner;
110         private readonly IntPtr _dataHandle;
111
112         internal DependentMediaBuffer(IBufferOwner owner, IntPtr dataHandle, int size)
113         {
114             Debug.Assert(owner != null, "Owner is null!");
115             Debug.Assert(!owner.IsDisposed, "Owner has been already disposed!");
116             Debug.Assert(dataHandle != IntPtr.Zero, "dataHandle is null!");
117             Debug.Assert(size >= 0, "size must not be negative!");
118
119             _owner = owner;
120             _dataHandle = dataHandle;
121             Length = size;
122         }
123
124         public byte this[int index]
125         {
126             get
127             {
128                 _owner.ValidateBufferReadable(this);
129
130                 if (index < 0 || index >= Length)
131                 {
132                     throw new ArgumentOutOfRangeException($"Valid index range is [0, { nameof(Length) }).");
133                 }
134
135                 return Marshal.ReadByte(_dataHandle, index);
136             }
137             set
138             {
139                 _owner.ValidateBufferWritable(this);
140
141                 Marshal.WriteByte(_dataHandle, index, value);
142             }
143         }
144
145         /// <summary>
146         /// Validates the range
147         /// </summary>
148         /// <param name="offset"></param>
149         /// <param name="length"></param>
150         /// <exception cref="ArgumentOutOfRangeException">
151         ///     offset + length is greater than <see cref="Length"/>.\n
152         ///     -or-\n
153         ///     offset or length is less than zero.
154         /// </exception>
155         private void ValidateRange(int offset, int length)
156         {
157             if (offset + length > Length)
158             {
159                 throw new ArgumentOutOfRangeException("offset + length can't be greater than length of the buffer.");
160             }
161             if (length < 0)
162             {
163                 throw new ArgumentOutOfRangeException($"Length can't be less than zero : { length }.");
164             }
165             if (offset < 0)
166             {
167                 throw new ArgumentOutOfRangeException($"Offset can't be less than zero : { offset }.");
168             }
169         }
170
171         public void CopyFrom(byte[] source, int startIndex, int length, int offset)
172         {
173             _owner.ValidateBufferReadable(this);
174
175             if (startIndex < 0)
176             {
177                 throw new ArgumentOutOfRangeException("startIndex can't be less than zero.");
178             }
179             if (startIndex + length > source.Length)
180             {
181                 throw new ArgumentOutOfRangeException("startIndex + length can't be greater than source.Length.");
182             }
183
184             ValidateRange(offset, length);
185
186             Marshal.Copy(source, startIndex, IntPtr.Add(_dataHandle, offset), length);
187         }
188
189         public void CopyFrom(byte[] source, int startIndex, int length)
190         {
191             CopyFrom(source, startIndex, length, 0);
192         }
193
194         public void CopyTo(byte[] dest, int startIndex, int length, int offset)
195         {
196             _owner.ValidateBufferWritable(this);
197
198             if (startIndex < 0)
199             {
200                 throw new ArgumentOutOfRangeException("Start index can't be less than zero.");
201             }
202             if (startIndex + length > dest.Length)
203             {
204                 throw new ArgumentOutOfRangeException("startIndex + length can't be greater than dest.Length.");
205             }
206
207             ValidateRange(offset, length);
208
209             Marshal.Copy(IntPtr.Add(_dataHandle, offset), dest, startIndex, length);
210         }
211
212         public void CopyTo(byte[] dest, int startIndex, int length)
213         {
214             CopyTo(dest, startIndex, length, 0);
215         }
216
217         public int Length { get; }
218     }
219 }