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