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