Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Multimedia / MediaTool / MediaPacketBuffer.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     /// Represents a buffer for a <see cref="MediaPacket"/>.
25     /// </summary>
26     public class MediaPacketBuffer
27     {
28         private readonly MediaPacket _packet;
29         private readonly IntPtr _dataHandle;
30
31         internal MediaPacketBuffer(MediaPacket packet, IntPtr dataHandle, int size)
32         {
33             Debug.Assert(packet != null, "Packet is null!");
34             Debug.Assert(!packet.IsDisposed, "Packet is already disposed!");
35             Debug.Assert(dataHandle != IntPtr.Zero, "dataHandle is null!");
36             Debug.Assert(size >= 0, "size must not be negative!");
37
38             _packet = packet;
39             _dataHandle = dataHandle;
40             _length = size;
41         }
42
43         /// <summary>
44         /// Gets or sets a value at the specified index.
45         /// </summary>
46         /// <param name="index">The index of the value to get or set.</param>
47         /// <exception cref="ArgumentOutOfRangeException">
48         ///     index is less than zero.\n
49         ///     -or-\n
50         ///     index is equal to or greater than <see cref="Length"/>.
51         /// </exception>
52         /// <exception cref="ObjectDisposedException">The MediaPacket that owns the current buffer already has been disposed of.</exception>
53         /// <exception cref="InvalidOperationException">The MediaPacket that owns the current buffer is being used by another module.</exception>
54         public byte this[int index]
55         {
56             get
57             {
58                 _packet.EnsureReadableState();
59
60                 if (index < 0 || index >= Length)
61                 {
62                     throw new ArgumentOutOfRangeException($"Valid index range is [0, { nameof(Length) }).");
63                 }
64
65                 return Marshal.ReadByte(_dataHandle, index);
66             }
67             set
68             {
69                 _packet.EnsureWritableState();
70
71                 Marshal.WriteByte(_dataHandle, index, value);
72             }
73         }
74
75         /// <summary>
76         /// Validates the range
77         /// </summary>
78         /// <param name="offset"></param>
79         /// <param name="length"></param>
80         /// <exception cref="ArgumentOutOfRangeException">
81         ///     offset + length is greater than <see cref="Length"/>.\n
82         ///     -or-\n
83         ///     offset or length is less than zero.
84         /// </exception>
85         private void ValidateRange(int offset, int length)
86         {
87             if (offset + length > _length)
88             {
89                 throw new ArgumentOutOfRangeException("offset + length can't be greater than length of the buffer.");
90             }
91             if (length < 0)
92             {
93                 throw new ArgumentOutOfRangeException($"Length can't be less than zero : { length }.");
94             }
95             if (offset < 0)
96             {
97                 throw new ArgumentOutOfRangeException($"Offset can't be less than zero : { offset }.");
98             }
99         }
100
101         /// <summary>
102         /// Copies data from a byte array to the buffer.
103         /// </summary>
104         /// <param name="source">The array to copy from.</param>
105         /// <param name="startIndex">The zero-based index in the source array where copying should start.</param>
106         /// <param name="length">The number of array elements to copy.</param>
107         /// <param name="offset">The zero-based index in the buffer where copying should start.</param>
108         /// <exception cref="ArgumentOutOfRangeException">startIndex, offset or length is not valid.</exception>
109         /// <exception cref="ObjectDisposedException">The MediaPacket that owns the current buffer already has been disposed of.</exception>
110         public void CopyFrom(byte[] source, int startIndex, int length, int offset = 0)
111         {
112             _packet.EnsureReadableState();
113
114             if (startIndex < 0)
115             {
116                 throw new ArgumentOutOfRangeException("startIndex can't be less than zero.");
117             }
118             if (startIndex + length > source.Length)
119             {
120                 throw new ArgumentOutOfRangeException("startIndex + length can't be greater than source.Length.");
121             }
122
123             ValidateRange(offset, length);
124
125             Marshal.Copy(source, startIndex, IntPtr.Add(_dataHandle, offset), length);
126         }
127
128         /// <summary>
129         /// Copies data from the buffer to a byte array.
130         /// </summary>
131         /// <param name="dest">The array to copy to.</param>
132         /// <param name="startIndex">The zero-based index in the dest array where copying should start.</param>
133         /// <param name="length">The number of elements to copy.</param>
134         /// <param name="offset">The zero-based index in the buffer where copying should start.</param>
135         /// <exception cref="ArgumentOutOfRangeException">startIndex, offset or length is not valid.</exception>
136         /// <exception cref="ObjectDisposedException">The MediaPacket that owns the current buffer already has been disposed of.</exception>
137         /// <exception cref="InvalidOperationException">The MediaPacket that owns the current buffer is being used by another module.</exception>
138         public void CopyTo(byte[] dest, int startIndex, int length, int offset = 0)
139         {
140             _packet.EnsureWritableState();
141
142             if (startIndex < 0)
143             {
144                 throw new ArgumentOutOfRangeException("Start index can't be less than zero.");
145             }
146             if (startIndex + length > dest.Length)
147             {
148                 throw new ArgumentOutOfRangeException("startIndex + length can't be greater than dest.Length.");
149             }
150
151             ValidateRange(offset, length);
152
153             Marshal.Copy(IntPtr.Add(_dataHandle, offset), dest, startIndex, length);
154         }
155
156         private readonly int _length;
157
158         /// <summary>
159         /// Gets the size of the buffer, in bytes.
160         /// </summary>
161         /// <exception cref="ObjectDisposedException">The MediaPacket that owns the current buffer already has been disposed of.</exception>
162         public int Length
163         {
164             get
165             {
166                 _packet.EnsureReadableState();
167
168                 return _length;
169             }
170         }
171     }
172 }