a3476c891622f355ab6619fd3de1d1be44f953bc
[platform/framework/native/appfw.git] / inc / FBaseBuffer.h
1 //
2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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 /**
18  * @file                FBaseBuffer.h
19  * @brief               This is the header file for the %Buffer class.
20  *
21  * This header file contains the declarations of the %Buffer classes.
22  */
23 #ifndef _FBASE_BUFFER_H_
24 #define _FBASE_BUFFER_H_
25
26 #include <string.h>
27 #include <FBaseBufferBase.h>
28 #include <FBaseResult.h>
29
30
31 namespace Tizen { namespace Base
32 {
33
34 // Forward declaration
35 class ByteBuffer;
36
37 /**
38  * @class       Buffer
39  * @brief       This class represents a linear finite sequence of elements of the same type.
40  *
41  * @since 2.0
42  *
43  * The %Buffer class represents a linear finite sequence of elements of the same type.
44  * It is a means of defining an aggregation of the same type of objects, similar to an array.
45  * @n
46  * For more information on the class features, see <a href="../org.tizen.native.appprogramming/html/guide/base/buffer.htm">Buffer</a>.
47  *
48  * @see         Tizen::Base::BufferBase
49  *
50  * The following example demonstrates how to use the %Buffer class.
51  *
52  * @code
53  *
54  *      #include <FBase.h>
55  *
56  *      using namespace Tizen::Base;
57  *
58  *      void
59  *      MyClass::BufferSample(void)
60  *      {
61  *              // Sets the buffer capacity to 1024
62  *              const int BUFFER_SIZE_MAX = 1024;
63  *
64  *              // Initializes intBuf with capacity
65  *              IntBuffer intBuf;
66  *              intBuf.Construct(BUFFER_SIZE_MAX);
67  *
68  *              int intArray[] = {0,1,2,3,4,5,6,7,8,9};
69  *
70  *              // Copies all values from intArray to intBuffer instance
71  *              // position = 10 (num of element copied)
72  *              intBuf.SetArray(intArray, 0, (sizeof(intArray) / sizeof(int)));
73  *
74  *              // Flips the buffer: The limit is set to the current position and
75  *              // then the position is set to zero
76  *              intBuf.Flip(); // position = 0, limit = 10
77  *
78  *              // Gets the number of elements between the current position and the limit
79  *              int remaining = intBuf.GetRemaining();
80  *
81  *              // Initializes a doubleBuf with capacity(10) using Construct() method
82  *              DoubleBuffer doubleBuf;
83  *              doubleBuf.Construct(remaining);
84  *
85  *              // Reads and writes elements from the intBuf to the doubleBuf
86  *              for (int i = 0; i < remaining; i++)
87  *              {
88  *                      int value;
89  *
90  *                      // Demonstrates relative reading and writing
91  *
92  *                      // Reads the value at the current position, and then increments the position
93  *                      intBuf.Get(value);
94  *
95  *                      // Writes the value * 12.34 at the current position of the doubleBuf
96  *                      // and then increment the position
97  *                      doubleBuf.Set(value * 12.34);
98  *
99  *                      // Now, positions of the intBuf and the doubleBuf have been incremented by one
100  *              }
101  *
102  *              // Flips the doubleBuf
103  *              doubleBuf.Flip();
104  *              // Now, the doubleBuf's position = 0 and limit = 10
105  *
106  *              // Gets the remaining elements of the doubleBuf
107  *              remaining = doubleBuf.GetRemaining();
108  *
109  *              // Gets the second double value with index
110  *              double doubleValue;
111  *              doubleBuf.Get(1, doubleValue);                  // 12.34
112  *      }
113  *
114  * @endcode
115  */
116 template< class Type >
117 class _OSP_EXPORT_ Buffer
118         : public BufferBase
119 {
120
121 public:
122         /**
123          * This is the default constructor for this class.
124          *
125          * @since 2.0
126          *
127          * @remarks             After creating an instance of the %Buffer class, one of the Construct() methods must be called explicitly to initialize this instance.
128          * @see                         Construct()
129          */
130         Buffer(void)
131         {
132
133         }
134
135
136         /**
137          * This is the destructor for this class.
138          *
139          * @since 2.0
140          */
141         virtual ~Buffer(void)
142         {
143
144         }
145
146
147         /**
148          * Initializes this instance of %Buffer which is a view of the specified @c buffer. @n
149          * This is similar to a copy constructor.
150          *
151          * @since 2.0
152          *
153          * @param[in]   buffer                  The other %Buffer instance
154          * @exception   E_SUCCESS               The method is successful.
155          * @exception   E_INVALID_ARG   The specified input parameter is invalid, or
156          *                                                              the source buffer is not constructed.
157          * @see                 Buffer()
158          */
159         result Construct(const Buffer< Type >& buffer)
160         {
161                 TryReturn(null != buffer._pData, E_INVALID_ARG, ("[E_INVALID_ARG] The source buffer is not constructed."));
162
163                 _capacity = buffer._capacity;
164                 _position = buffer._position;
165                 _limit = buffer._limit;
166                 _mark = buffer._mark;
167                 _pData = buffer._pData;
168
169                 AddRef();
170                 __pArrayStart = buffer.__pArrayStart;
171
172                 return E_SUCCESS;
173         }
174
175         /**
176          * Initializes this instance of %Buffer with the specified @c capacity.
177          *
178          * @since 2.0
179          *
180          * @return              An error code
181          * @param[in]   capacity                The number of elements
182          * @exception   E_SUCCESS               The method is successful.
183          * @exception   E_INVALID_ARG   The specified @c capacity is negative.
184          * @see                 Buffer()
185          */
186         result Construct(int capacity)
187         {
188                 return BufferBase::Construct(capacity);
189         }
190
191         /**
192         * Initializes this instance of %Buffer with the specified @c buffer which is shared with this instance.
193         *
194         * @since 2.0
195         *
196         * @return                       An error code
197         * @param[in]            pBuffer                         The buffer which is shared
198         * @param[in]            index                           The starting index of the buffer from where the first @c byte value is read
199         * @param[in]            length                          The number of bytes to read from the given buffer @n This is a limit of this instance.
200         * @param[in]            capacity                        The capacity of this instance
201         * @exception       E_SUCCESS                    The method is successful.
202         * @exception       E_INVALID_ARG                A specified input parameter is invalid, or
203         *                                                                               the @c pBuffer is @c null.
204         * @exception       E_OUT_OF_RANGE               The specified @c index is outside the bounds of the data structure, or
205         *                                                                               the @c index is larger than the @c length.
206         */
207         result Construct(const Type* pBuffer, int index, int length, int capacity)
208         {
209                 TryReturn(pBuffer != null, E_INVALID_ARG, "[E_INVALID_ARG] The pBuffer is null.");
210                 TryReturn(index >= 0 && length >= 0 && capacity >= 0, E_OUT_OF_RANGE,
211                         "[E_OUT_OF_RANGE] index(%d), length(%d) and capacity(%d) MUST be greater than or equal to 0.", index,
212                         length, capacity);
213                 TryReturn(index < capacity && length <= capacity && index + length <= capacity, E_OUT_OF_RANGE,
214                         "[E_OUT_OF_RANGE] index(%d), length(%d) and capacity(%d) MUST be greater than or equal to 0.", index,
215                         length, capacity);
216
217                 void* pTemp = null;
218                 int sizeofBufferData = sizeof(_BufferData);
219
220                 Type* tempByte = const_cast< Type* >(pBuffer + index);
221                 __pArrayStart = reinterpret_cast< byte* >(tempByte);
222
223                 pTemp = malloc(sizeofBufferData);
224                 TryReturn(pTemp != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]");
225
226                 memset(pTemp, 0, sizeofBufferData);
227                 _pData = static_cast< _BufferData* >(pTemp);
228
229                 _pData->refCount = 1;
230                 _pData->capacityInByte = capacity * sizeof(Type);
231
232                 _capacity = capacity;
233                 _limit = length;
234
235                 return E_SUCCESS;
236         }
237
238         /**
239          * This subscript operator returns the reference to the element indicated by the given @c index.
240          *
241          * @since 2.0
242          *
243          * @return              A reference to the indexed element
244          * @param[in]   index   The index of the element @n
245          *                              It must be less than the limit.
246          */
247         Type& operator [](int index) const
248         {
249                 AppAssertf(index < _limit, "index out of range.\n");
250                 AppAssertf(index >= 0, "index out of range.\n");
251
252                 return ((Type*) __pArrayStart)[index];
253         }
254
255         /**
256          * Overloaded equality operator to compare two %Buffer instances.
257          *
258          * @since 2.0
259          *
260          * @return              @c true if the buffers being compared are equal, @n
261          *                              else @c false
262          * @param[in]   buffer The buffer to compare with the current instance of %Buffer
263          * @remarks     This method returns @c true only if the two buffers have the same number of remaining elements @n
264          *                              and the two sequences of remaining elements are equal (considered independently of their starting positions).
265          * @see                 Equals()
266          */
267         bool operator ==(const Buffer< Type >& buffer) const
268         {
269                 bool r = true;
270                 if (this == (void*) (&buffer))
271                 {
272                         r = true;
273                 }
274                 else if (GetRemaining() != buffer.GetRemaining())
275                 {
276                         r = false;
277                 }
278                 else
279                 {
280                         void* p1 = &(((Type*) __pArrayStart)[_position]);
281                         void* p2 = &(((Type*) buffer.__pArrayStart)[buffer._position]);
282                         if ((p1 != p2) && (memcmp(p1, p2, sizeof(Type) * GetRemaining()) != 0))
283                         {
284                                 r = false;
285                         }
286                 }
287
288                 return r;
289         }
290
291         /**
292          * Checks whether the two %Buffer instances are not equal.
293          *
294          * @since 2.0
295          *
296          * @return              @c true if the buffers are not equal, @n
297          *                              else @c false
298          * @param[in]   buffer The buffer to compare with the current instance of %Buffer
299          * @remarks     This method returns @c false only if the two buffers being compared have the same @n
300          *                              number of remaining elements and the two sequences of remaining elements are equal @n
301          *                              (considered independently of their starting positions).
302          * @see                 Equals()
303          */
304         bool operator !=(const Buffer< Type >& buffer) const
305         {
306                 return !(*this == buffer);
307         }
308
309         /**
310          * Copies the remaining elements of the input %Buffer instance into the current
311          * %Buffer instance. @n
312          * It returns E_OVERFLOW if the remaining part of the current instance is smaller
313          * than the remaining part of the input instance.
314          *
315          * @since 2.0
316          *
317          * @return              An error code
318          * @param[in]   buffer  The source buffer from which bytes are read @n
319          *                                              It must not be the current instance of %Buffer.
320          * @exception   E_SUCCESS               The method is successful.
321          * @exception   E_INVALID_ARG   The specified input parameter is invalid, or
322          *                                                              the source buffer is same as destination buffer,
323          *                                                              that is, the current instance of %Buffer.
324          * @exception   E_OVERFLOW              The operation (arithmetic/casting/conversion) has caused an overflow. @n
325          *                                                              The number of remaining bytes of the current buffer is less than
326          *                                                              the number of remaining bytes of the given buffer.
327          * @remarks     After the copy operation, the current (destination) buffer's position and the given
328          *                              (source) buffer's position are incremented by the number of elements copied (the number
329          *                              of remaining elements of the given buffer). @n
330          *                              If the remaining part of the current instance is not less than the remaining part of the input instance,
331          *                              the effect of this method and the ReadFrom() method is the same. But when the remaining part of the
332          *                              current instance is less, ReadFrom() method copies the number of remaining elements of the current
333          *                              instance while this method returns E_OVERFLOW and does not transfer.
334          * @see                 ReadFrom()
335          *
336          * The following example demonstrates how to use the %CopyFrom() method.
337          *
338          * @code
339          *
340          *      // Create instances of IntBuffer to act as source and destination buffers
341          *      IntBuffer srcBuf;
342          *      IntBuffer destBuf;
343          *
344          *      // Declare an array of integers
345          *      int pArray[] = {0,1,2,3,4,5,6,7,8,9};
346          *
347          *      // Initialize the source buffer with 10 elements.
348          *      srcBuf.Construct(10);
349          *
350          *      // Copy the 10 values from pArray starting at position 0 to srcBuf
351          *      // Now srcBuf's position = 10
352          *      srcBuf.SetArray(pArray, 0, 10);
353          *
354          *      // Flip the buffer: The limit is set to the current position
355          *      // and then the position is set to zero
356          *      srcBuf.Flip();          // srcBuf's position = 0 and limit = 10
357          *
358          *
359          *      destBuf.Construct(20);
360          *
361          *      // Copy from srcBuf to destBuf
362          *      // Now srcBuf's position = 10, destBuf's position = 10
363          *      destBuf.CopyFrom(srcBuf);
364          *
365          * @endcode
366          *
367          * The following example has exactly the same effect as the above %CopyFrom() method.
368          *
369          * @code
370          *
371          *      int copyNum = srcBuf.GetRemaining();
372          *      for (int i = 0; i < copyNum; i++)
373          *      {
374          *              int value;
375          *
376          *              // Read from the source buffer
377          *              srcBuf.Get(value);                      // srcBuf position is incremented by one.
378          *
379          *              // Write to the destination buffer
380          *              destBuf.Set(value);                     // destBuf position is incremented by one.
381          *
382          *      }
383          * @endcode
384          */
385         result CopyFrom(Buffer< Type >& buffer)
386         {
387                 TryReturn(this != static_cast< void* >(&buffer), E_INVALID_ARG,
388                         "[E_INVALID_ARG] The source and target buffers are identical.");
389                 int copyLength = buffer.GetRemaining();
390                 TryReturn(GetRemaining() >= copyLength, E_OVERFLOW, "[E_OVERFLOW]");
391
392                 memcpy(__pArrayStart + _position * sizeof(Type), buffer.__pArrayStart + buffer._position * sizeof(Type),
393                         copyLength * sizeof(Type));
394
395                 _position += copyLength;
396                 buffer._position += copyLength;
397
398                 return E_SUCCESS;
399         }
400
401         /**
402          * Reads the value from the current position in the buffer, and then increments the position. @n
403          * Provides a way for relative indexing and reading.
404          *
405          * @since 2.0
406          *
407          * @return                      An error code
408          * @param[out]          value The value at the current position
409          * @exception           E_SUCCESS               The method is successful.
410          * @exception           E_UNDERFLOW             The operation (arithmetic/casting/conversion) has caused an underflow. @n
411          *                                                                      The current position is greater than the limit.
412          * @see                         Set()
413          */
414         result Get(Type& value)
415         {
416                 TryReturn(_position < _limit, E_UNDERFLOW, "[E_UNDERFLOW]");
417
418                 value = ((Type*) __pArrayStart)[_position++];
419                 return E_SUCCESS;
420         }
421
422         /**
423          * Reads the value at the given @c index. @n
424          * Provides a way for absolute indexing and reading.
425          *
426          * @since 2.0
427          *
428          * @return                      An error code
429          * @param[in]           index The index into the buffer from where the value is read
430          * @param[out]          value The value at the given index
431          * @exception           E_SUCCESS                       The method is successful.
432          * @exception           E_OUT_OF_RANGE          The specified @c index is outside the bounds of the data structure. @n
433          *                                                                              The @c index is greater than the limit or less than @c 0.
434          * @see                         Set()
435          */
436         result Get(int index, Type& value) const
437         {
438                 TryReturn(index < _limit && index >= 0, E_OUT_OF_RANGE,
439                         "[E_OUT_OF_RANGE] The index(%d) MUST be greater than or equal to 0, and less then the current limit(%d).",
440                         index, _limit);
441
442                 value = ((Type*) __pArrayStart)[index];
443                 return E_SUCCESS;
444         }
445
446
447         /**
448          * Copies the specified range of values from the calling buffer to the specified destination array as per the given @c index of the array.
449          *
450          * @since 2.0
451          *
452          * @return              An error code
453          * @param[out]  pArray  A pointer to the array into which values are written
454          * @param[in]   index   The starting index in the array of the first value to write
455          * @param[in]   length  The number of values from the buffer to write to the array
456          * @exception   E_SUCCESS                       The method is successful.
457          * @exception   E_INVALID_ARG           A specified input parameter is invalid, or
458          *                                                                      the @c pArray is @c null.
459          * @exception   E_OUT_OF_RANGE          The specified index is outside the bounds of the data structure, or
460          *                                                                      the @c index or length is less than @c 0.
461          * @exception   E_UNDERFLOW                     The operation (arithmetic/casting/conversion) has caused an underflow. @n
462          *                                                                      The remaining elements of this buffer are smaller than @c length.
463          * @remarks     After the copy operation, the position is incremented by @c length.
464          * @see                 SetArray()
465          */
466         result GetArray(Type* pArray, int index, int length)
467         {
468                 TryReturn(0 != pArray, E_INVALID_ARG, "[E_INVALID_ARG] The pArray is null.");
469                 TryReturn(index >= 0 && length >= 0, E_OUT_OF_RANGE,
470                         "[E_OUT_OF_RANGE] Both of index(%d) and length(%d) MUST be greater than or equal to 0.", index, length);
471                 TryReturn(GetRemaining() >= length, E_UNDERFLOW, "[E_UNDERFLOW]");
472
473                 memcpy(pArray + index, __pArrayStart + _position * sizeof(Type), length * sizeof(Type));
474                 _position += length;
475
476                 return E_SUCCESS;
477         }
478
479         /**
480          * Transfers bytes from the input buffer into the calling buffer. @n
481          * If the empty space in the calling buffer is larger than the remaining values from the input buffer,
482          * all the remaining elements from the input are copied to the destination. @n
483          * Otherwise, the number of bytes copied equals the number of elements remaining in the calling buffer.
484          *
485          * @since 2.0
486          *
487          * @return              An error code
488          * @param[in]   buffer  The source buffer from where the bytes are read @n
489          *                                              It must not be this buffer.
490          * @exception   E_SUCCESS               The method is successful.
491          * @exception   E_INVALID_ARG   The specified input parameter is invalid. @n
492          *                                                              The given buffer is same as the current buffer instance.
493          * @remarks     After the copy operation, the current (destination) buffer's position and the given
494          *                              (source) buffer's position are  incremented by the number of elements copied (the smaller value
495          *                              between the number of elements remaining in the calling buffer and the source buffer). @n
496          *                              If there are more elements remaining in the calling buffer than elements remaining in the input instance,
497          *                              this method is equivalent to CopyFrom() method. If there are less remaining elements in the
498          *                              calling buffer, the %CopyFrom() method returns @c E_OVERFLOW and does not transfer
499          *                              while this method copies the number of remaining elements of the current instance.
500          * @see                 CopyFrom()
501          *
502          * The following example demonstrates how to use the %ReadFrom() method.
503          *
504          * @code
505          *
506          *      // Create instances of IntBuffer to act as the source and destination buffers
507          *      IntBuffer srcBuf;
508          *      IntBuffer destBuf;
509          *
510          *      // Declare an array of integers
511          *      int pArray[] = {0,1,2,3,4,5,6,7,8,9};
512          *
513          *      // Initialize the source buffer with a capacity of 10 elements.
514          *      srcBuf.Construct(10);
515          *
516          *      // Copy the 10 values from pArray starting at position 0 to srcBuf
517          *      // Now srcBuf's position = 10
518          *      srcBuf.SetArray(pArray, 0, 10);
519          *
520          *      // Flip the buffer: The limit is set to the current position
521          *      // and then the position is set to zero
522          *      srcBuf.Flip();  // srcBuf's position = 0 and limit = 10
523          *
524          *
525          *      // Initialize the destination buffer with a capacity of 10 elements.
526          *      destBuf.Construct(10);
527          *
528          *      // Set the limit of destBuf to 5
529          *      destBuf.SetLimit(5);
530          *
531          *      // Read from srcBuf to destBuf
532          *      // destBuf's remaining is 5, smaller than the srcBuf's (10).
533          *      // Therefore, five elements are transferred.
534          *      // srcBuf's position = 5, destBuf's position = 5
535          *      destBuf.ReadFrom(srcBuf);
536          *
537          *
538          * @endcode
539          *
540          * The following example has exactly the same effect as the above %ReadFrom() method.
541          *
542          * @code
543          *
544          *      int copyNum = (destBuf.GetRemaining() < srcBuf.GetRemaing())? destBuf.GetRemaining() : srcBuf.GetRemaining();
545          *      for (int i = 0; i < copyNum; i++)
546          *      {
547          *              int value;
548          *
549          *              // Read from source buffer
550          *              srcBuf.Get(value);                      // srcBuf position is incremented by one.
551          *
552          *              // Write to destination buffer
553          *              destBuf.Set(value);                     // destBuf position is incremented by one.
554          *
555          *      }
556          * @endcode
557          */
558         result ReadFrom(Buffer< Type >& buffer)
559         {
560                 TryReturn(this != static_cast< void* >(&buffer), E_INVALID_ARG,
561                         "[E_INVALID_ARG] The source and target buffers are identical.");
562
563                 int copyLength = (GetRemaining() < buffer.GetRemaining()) ? GetRemaining() : buffer.GetRemaining();
564
565                 memcpy(__pArrayStart + _position * sizeof(Type), buffer.__pArrayStart + buffer._position * sizeof(Type),
566                         copyLength * sizeof(Type));
567
568                 _position += copyLength;
569                 buffer._position += copyLength;
570
571                 return E_SUCCESS;
572         }
573
574
575         /**
576          * Writes the specified @c value into the current buffer instance at the current position,
577          * and then increments the position. @n
578          * Provides a way for relative indexing and writing.
579          *
580          * @since 2.0
581          *
582          * @return              An error code
583          * @param[in]   value           The value to write to the calling %Buffer
584          * @exception   E_SUCCESS               The method is successful.
585          * @exception   E_OVERFLOW              The operation (arithmetic/casting/conversion) has caused an overflow. @n
586          *                                                              The current position is not smaller than the limit.
587          * @see                 Get()
588          */
589         result Set(Type value)
590         {
591                 TryReturn(_position < _limit, E_OVERFLOW, "[E_OVERFLOW]");
592
593                 ((Type*) __pArrayStart)[_position++] = value;
594                 return E_SUCCESS;
595         }
596
597         /**
598          * Writes the specified @c value into the current instance of buffer at the given @c index. @n
599          * Provides a way for absolute indexing and writing.
600          *
601          * @since 2.0
602          *
603          * @return              An error code
604          * @param[in]   index   The index at which the value is written
605          * @param[in]   value   The value to write
606          * @exception   E_SUCCESS           The method is successful.
607          * @exception   E_OUT_OF_RANGE          The specified index is outside the bounds of the data structure, or
608          *                                                                      the @c index is not smaller than the limit or less than @c 0.
609          * @see                 Get()
610          */
611         result Set(int index, Type value)
612         {
613                 TryReturn(index < _limit && index >= 0, E_OUT_OF_RANGE,
614                         "[E_OUT_OF_RANGE] The index(%d) MUST be greater than or equal to 0, and less then the current limit(%d).",
615                         index, _limit);
616
617                 ((Type*) __pArrayStart)[index] = value;
618                 return E_SUCCESS;
619         }
620
621         /**
622          * Copies values from the input source array into the calling buffer.
623          *
624          * @since 2.0
625          *
626          * @return              An error code
627          * @param[in]   pArray          A pointer to the array from where the values are read
628          * @param[in]   index           The starting index of the array
629          * @param[in]   length          The number of values read from the given array
630          * @exception   E_SUCCESS                       The method is successful.
631          * @exception   E_INVALID_ARG           A specified input parameter is invalid, or
632          *                                                                      the @c pArray is @c null.
633          * @exception   E_OUT_OF_RANGE          The specified index is outside the bounds of the data structure, or
634          *                                                                      the @c index or length is less than @c 0.
635          * @exception   E_OVERFLOW                      The operation (arithmetic/casting/conversion) has caused an overflow. @n
636          *                                                                      The remainder of this buffer is smaller than @c length.
637          * @remarks     This method copies @c length number of values from the source array,
638          *                              starting from the given @c index in the array, into the calling
639          *                              buffer, starting at the current position.
640          *                              After the copy operation, the position is incremented by @c length.
641          * @see                 GetArray()
642          */
643         result SetArray(const Type* pArray, int index, int length)
644         {
645                 TryReturn(null != pArray, E_INVALID_ARG, "[E_INVALID_ARG] The pArray is null.");
646                 TryReturn(index >= 0 && length >= 0, E_OUT_OF_RANGE,
647                         "[E_OUT_OF_RANGE] Both of index(%d) and length(%d) MUST be greater than or equal to 0.", index, length);
648                 TryReturn(GetRemaining() >= length, E_OVERFLOW, "[E_OVERFLOW]");
649
650                 memcpy(__pArrayStart + _position * sizeof(Type), pArray + index, length * sizeof(Type));
651                 _position += length;
652
653                 return E_SUCCESS;
654         }
655
656         /**
657          * Creates a new %Buffer instance. @n
658          * Its content is a shared portion of
659          * the calling %Buffer instance that starts from the current position of calling %Buffer instance.
660          *
661          * @since 2.0
662          *
663          * @return              A pointer to the new buffer
664          * @remarks     The content of the new buffer starts at the current position of this instance of %Buffer.
665          *                              The new buffer's position is @c 0, its capacity and limit is
666          *                              the number of bytes remaining in the current instance of %Buffer,
667          *                              and it is marked as undefined.
668          */
669         Buffer< Type >* SliceN(void) const
670         {
671                 Buffer< Type >* pBuffer = new Buffer< Type >();
672                 pBuffer->_pData = _pData;
673                 AddRef();
674                 pBuffer->_capacity = GetRemaining();
675                 pBuffer->_limit = pBuffer->_capacity;
676                 if (pBuffer->_capacity > 0)
677                 {
678                         pBuffer->__pArrayStart = (byte*) &((Type*) __pArrayStart)[_position];
679                 }
680
681                 return pBuffer;
682         }
683
684         /**
685          * Gets a raw array pointer to calling buffer.
686          *
687          * @since 2.0
688          *
689          * @return              A raw array pointer to the buffer, @n
690          *                              else @c null if the capacity is @c 0
691          */
692         const Type* GetPointer(void) const
693         {
694                 return (Type*) __pArrayStart;
695         }
696
697         /**
698          * Compares the Object instance with the calling %Buffer instance for equivalence.
699          *
700          * @since 2.0
701          *
702          * @return              @c true if the input equals the calling %Buffer instance, @n
703          *                              else @c false
704          * @param[in]   obj     The object to compare with the calling %Buffer
705          * @remarks     This method returns @c true if and only if the specified object is also an instance of %Buffer class,
706          *                              the two buffers have the same number of remaining elements, and the two sequences of
707          *                              remaining elements are equal (considered independently of their starting positions).
708          * @see                 Tizen::Base::BufferBase::GetHashCode()
709          */
710         virtual bool Equals(const Tizen::Base::Object& obj) const
711         {
712                 bool out = false;
713                 const Buffer< Type >* other = static_cast< const Buffer< Type >* >(&obj);
714                 if ((other == this) || (*other == *this))
715                 {
716                         out = true;
717                 }
718
719                 return out;
720         }
721
722         /**
723          *      Gets the hash value of the current instance.
724          *
725          *      @since 2.0
726          *
727          *      @return         The hash value of the current instance
728          *      @remarks                The hash code of a buffer depends only upon its remaining elements.
729          */
730         virtual int GetHashCode(void) const
731         {
732                 int len = (GetRemaining() * GetTypeSize()) / sizeof(int);
733
734                 int hash = 0;
735                 int offset = _position * GetTypeSize();
736                 for (int i = 0; i < len; ++i)
737                 {
738                         hash = (hash << 5) - hash + (int) __pArrayStart[offset + (i * sizeof(int))];
739                 }
740
741                 return hash;
742         }
743
744 private:
745         /**
746          * This is the copy constructor for this class.
747          */
748         Buffer(const Buffer< Type >& buffer)
749         {
750                 Construct(buffer);
751         }
752
753         /**
754          * This is the assignment operator.
755          */
756         Buffer< Type >& operator =(const Buffer< Type >& buffer);
757
758         /**
759          * Returns the size of the type of this buffer.
760          *
761          * @return              The size of the buffer
762          */
763         virtual int GetTypeSize(void) const
764         {
765                 return sizeof(Type);
766         }
767
768         friend class ByteBuffer;
769
770 }; // Buffer
771
772
773 /**
774  * The @c double buffer type
775  * @since 2.0
776  */
777 typedef Buffer< double > DoubleBuffer;
778
779 /**
780 * The @c float buffer type
781 * @since 2.0
782 */
783 typedef Buffer< float > FloatBuffer;
784
785 /**
786 * The @c int buffer type
787 * @since 2.0
788 */
789 typedef Buffer< int > IntBuffer;
790
791 /**
792 * The @c long buffer type
793 * @since 2.0
794 */
795 typedef Buffer< long > LongBuffer;
796
797 /**
798 * The @c long @c long buffer type
799 * @since 2.0
800 */
801 typedef Buffer< long long > LongLongBuffer;
802
803 /**
804 * The @c wchar_t buffer type
805 * @since 2.0
806 */
807 typedef Buffer< wchar_t > WcharBuffer;
808
809 /**
810 * The @c short buffer type
811 * @since 2.0
812 */
813 typedef Buffer< short > ShortBuffer;
814
815
816 #ifdef _MSC_VER
817 template class _OSP_EXPORT_ Buffer< double >;
818 template class _OSP_EXPORT_ Buffer< float >;
819 template class _OSP_EXPORT_ Buffer< int >;
820 template class _OSP_EXPORT_ Buffer< long >;
821 template class _OSP_EXPORT_ Buffer< long long >;
822 template class _OSP_EXPORT_ Buffer< wchar_t >;
823 template class _OSP_EXPORT_ Buffer< short >;
824 #endif
825
826 }} // Tizen::Base
827
828 #endif // _FBASE_BUFFER_H_