Revert "Revert "Fix intApp TC failure""
[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 class.
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  *
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. @n
124          * After creating an instance of the %Buffer class, one of the Construct() methods must be called explicitly to initialize this instance.
125          *
126          * @since               2.0
127          */
128         Buffer(void)
129         {
130
131         }
132
133
134         /**
135          * This is the destructor for this class.
136          *
137          * @since 2.0
138          */
139         virtual ~Buffer(void)
140         {
141
142         }
143
144
145         /**
146          * Initializes this instance of %Buffer which is a view of the specified @c buffer. @n
147          * This is similar to a copy constructor.
148          *
149          * @since 2.0
150          *
151          * @param[in]   buffer                  The other %Buffer instance
152          * @exception   E_SUCCESS               The method is successful.
153          * @exception   E_INVALID_ARG   Either of the following conditions has occured:
154          *                                                              - The specified input parameter is invalid.
155          *                                                              - The source buffer has not been constructed.
156          * @see                 Buffer()
157          */
158         result Construct(const Buffer< Type >& buffer)
159         {
160                 TryReturn(null != buffer._pData, E_INVALID_ARG, ("[E_INVALID_ARG] The source buffer is not constructed."));
161
162                 _capacity = buffer._capacity;
163                 _position = buffer._position;
164                 _limit = buffer._limit;
165                 _mark = buffer._mark;
166                 _pData = buffer._pData;
167
168                 AddRef();
169                 __pArrayStart = buffer.__pArrayStart;
170
171                 return E_SUCCESS;
172         }
173
174         /**
175          * Initializes this instance of %Buffer with the specified @c capacity.
176          *
177          * @since 2.0
178          *
179          * @return              An error code
180          * @param[in]   capacity                The number of elements
181          * @exception   E_SUCCESS               The method is successful.
182          * @exception   E_INVALID_ARG   The specified @c capacity is negative.
183          * @see                 Buffer()
184          */
185         result Construct(int capacity)
186         {
187                 return BufferBase::Construct(capacity);
188         }
189
190         /**
191         * Initializes this instance of %Buffer with the specified @c buffer which is shared with this instance.
192         *
193         * @since 2.0
194         *
195         * @return                       An error code
196         * @param[in]            pBuffer                         The shared buffer
197         * @param[in]            index                           The starting index of the buffer from where the first @c byte value is read
198         * @param[in]            length                          The number of bytes to read from the given buffer @n 
199         *                                                                               This is the 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                Either of the following conditions has occured:
203         *                                                                               - A specified input parameter is invalid.
204         *                                                                               - The specified @c pBuffer is @c null.
205         * @exception       E_OUT_OF_RANGE               Either of the following conditions has occured:
206         *                                                                               - The specified @c index is outside the bounds of the data structure.
207         *                                                                               - The specified @c index is larger than the specified @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          * Returns a reference to the element indicated by the given @c 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          * Checks whether two %Buffer instances are equal.
259          *
260          * @since 2.0
261          *
262          * @return              @c true if the two %Buffer instances 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 sequences of the remaining elements are equal (considered independent 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 two %Buffer instances are not equal.
295          *
296          * @since 2.0
297          *
298          * @return              @c true if the two %Buffer instances 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 have the same @n
302          *                              number of remaining elements and the sequences of the remaining elements are equal @n
303          *                              (considered independent 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 @c 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   Either of the following conditions has occured:
324          *                                                              - The specified input parameter is invalid.
325          *                                                              - The source buffer is same as destination buffer,
326          *                                                              that is, the current instance of %Buffer.
327          * @exception   E_OVERFLOW              Either of the following conditions has occured:
328          *                                                              - The operation (arithmetic/casting/conversion) has caused an overflow.
329          *                                                              - The number of remaining bytes in the current buffer is less than
330          *                                                              the number of remaining bytes in the given buffer.
331          * @remarks     After the copy operation, the current (destination) buffer's position and the given
332          *                              (source) buffer's position are incremented by the number of elements copied (the number
333          *                              of remaining elements of the given buffer). @n
334          *                              If the remaining part of the current instance is not less than the remaining part of the input instance,
335          *                              the effect of this method and the ReadFrom() method is the same. @n
336          *                              But when the remaining part of the current instance is less, the ReadFrom() method copies the number of remaining 
337          *                              elements of the current instance while this method returns @c E_OVERFLOW and does not transfer.
338          *
339          * The following example demonstrates how to use the %CopyFrom() method.
340          *
341          * @code
342          *
343          *      // Create instances of IntBuffer to act as source and destination buffers
344          *      IntBuffer srcBuf;
345          *      IntBuffer destBuf;
346          *
347          *      // Declare an array of integers
348          *      int pArray[] = {0,1,2,3,4,5,6,7,8,9};
349          *
350          *      // Initialize the source buffer with 10 elements.
351          *      srcBuf.Construct(10);
352          *
353          *      // Copy the 10 values from pArray starting at position 0 to srcBuf
354          *      // Now srcBuf's position = 10
355          *      srcBuf.SetArray(pArray, 0, 10);
356          *
357          *      // Flip the buffer: The limit is set to the current position
358          *      // and then the position is set to zero
359          *      srcBuf.Flip();          // srcBuf's position = 0 and limit = 10
360          *
361          *
362          *      destBuf.Construct(20);
363          *
364          *      // Copy from srcBuf to destBuf
365          *      // Now srcBuf's position = 10, destBuf's position = 10
366          *      destBuf.CopyFrom(srcBuf);
367          *
368          * @endcode
369          *
370          * The following example has exactly the same effect as the above %CopyFrom() method.
371          *
372          * @code
373          *
374          *      int copyNum = srcBuf.GetRemaining();
375          *      for (int i = 0; i < copyNum; i++)
376          *      {
377          *              int value;
378          *
379          *              // Read from the source buffer
380          *              srcBuf.Get(value);                      // srcBuf position is incremented by one.
381          *
382          *              // Write to the destination buffer
383          *              destBuf.Set(value);                     // destBuf position is incremented by one.
384          *
385          *      }
386          * @endcode
387          */
388         result CopyFrom(Buffer< Type >& buffer)
389         {
390                 TryReturn(this != static_cast< void* >(&buffer), E_INVALID_ARG,
391                         "[E_INVALID_ARG] The source and target buffers are identical.");
392                 int copyLength = buffer.GetRemaining();
393                 TryReturn(GetRemaining() >= copyLength, E_OVERFLOW, "[E_OVERFLOW]");
394
395                 memcpy(__pArrayStart + _position * sizeof(Type), buffer.__pArrayStart + buffer._position * sizeof(Type),
396                         copyLength * sizeof(Type));
397
398                 _position += copyLength;
399                 buffer._position += copyLength;
400
401                 return E_SUCCESS;
402         }
403
404         /**
405          * Reads the value of the current position in the buffer, and then increments the position. @n
406          * Provides a way to perform relative indexing and reading.
407          *
408          * @since 2.0
409          *
410          * @return                      An error code
411          * @param[out]          value                   The value at the current position
412          * @exception           E_SUCCESS               The method is successful.
413          * @exception           E_UNDERFLOW             Either of the following conditions has occured:
414          *                                                                      - The operation (arithmetic/casting/conversion) has caused an underflow.
415          *                                                                      - The current position is greater than the limit.
416          * @see                         Set()
417          */
418         result Get(Type& value)
419         {
420                 TryReturn(_position < _limit, E_UNDERFLOW, "[E_UNDERFLOW]");
421
422                 value = ((Type*) __pArrayStart)[_position++];
423                 return E_SUCCESS;
424         }
425
426         /**
427          * Reads the value at the given @c index. @n
428          * Provides a way to preform absolute indexing and reading.
429          *
430          * @since 2.0
431          *
432          * @return                      An error code
433          * @param[in]           index                   The buffer index from where the value is read
434          * @param[out]          value                   The value at the given index
435          * @exception           E_SUCCESS               The method is successful.
436          * @exception           E_OUT_OF_RANGE  Either of the following conditions has occured:
437          *                                                                      - The specified @c index is outside the bounds of the data structure.
438          *                                                                      - The specified @c index is greater than the limit.
439          *                                                                      - The specified @c index is less than @c 0.
440          * @see                         Set()
441          */
442         result Get(int index, Type& value) const
443         {
444                 TryReturn(index < _limit && index >= 0, E_OUT_OF_RANGE,
445                         "[E_OUT_OF_RANGE] The index(%d) MUST be greater than or equal to 0, and less then the current limit(%d).",
446                         index, _limit);
447
448                 value = ((Type*) __pArrayStart)[index];
449                 return E_SUCCESS;
450         }
451
452
453         /**
454          * Copies the specified range of values from the calling buffer to the specified @c index of the destination array.
455          *
456          * @since 2.0
457          *
458          * @return              An error code
459          * @param[out]  pArray                          A pointer to the array into which the values are written
460          * @param[in]   index                           The starting index in the array where the first value is written
461          * @param[in]   length                          The number of values to write from the buffer to the array
462          * @exception   E_SUCCESS                       The method is successful.
463          * @exception   E_INVALID_ARG           Either of the following conditions has occured:
464          *                                                                      - A specified input parameter is invalid.
465          *                                                                      - The specified @c pArray is @c null.
466          * @exception   E_OUT_OF_RANGE          Either of the following conditions has occured:
467          *                                                                      - The specified @c index is outside the bounds of the data structure.
468          *                                                                      - The specified @c index or @c length is less than @c 0.
469          * @exception   E_UNDERFLOW                     Either of the following conditions has occured:
470          *                                                                      - The operation (arithmetic/casting/conversion) has caused an underflow.
471          *                                                                      - The remaining elements of this buffer are smaller than the specified @c length.
472          * @remarks             After the copy operation, the position is incremented by @c length.
473          * @see                 SetArray()
474          */
475         result GetArray(Type* pArray, int index, int length)
476         {
477                 TryReturn(0 != pArray, E_INVALID_ARG, "[E_INVALID_ARG] The pArray is null.");
478                 TryReturn(index >= 0 && length >= 0, E_OUT_OF_RANGE,
479                         "[E_OUT_OF_RANGE] Both of index(%d) and length(%d) MUST be greater than or equal to 0.", index, length);
480                 TryReturn(GetRemaining() >= length, E_UNDERFLOW, "[E_UNDERFLOW]");
481
482                 memcpy(pArray + index, __pArrayStart + _position * sizeof(Type), length * sizeof(Type));
483                 _position += length;
484
485                 return E_SUCCESS;
486         }
487
488         /**
489          * Transfers bytes from the input buffer into the calling buffer. @n
490          * If the empty space in the calling buffer is larger than the remaining values of the input buffer,
491          * then all the remaining elements from the input are copied to the destination. @n
492          * Otherwise, the number of bytes copied equals the number of elements remaining in the calling buffer.
493          *
494          * @since 2.0
495          *
496          * @return              An error code
497          * @param[in]   buffer                  The source buffer from where the bytes are read @n
498          *                                                              It must not be this buffer.
499          * @exception   E_SUCCESS               The method is successful.
500          * @exception   E_INVALID_ARG   Either of the following conditions has occured:
501          *                                                              - The specified input parameter is invalid.
502          *                                                              - The given buffer is same as the current buffer instance.
503          * @remarks     After the copy operation, the current (destination) buffer's position and the given
504          *                              (source) buffer's position are incremented by the number of elements copied (the smaller value
505          *                              between the number of elements remaining in the calling buffer and the source buffer). @n
506          *                              If there are more elements remaining in the calling buffer than the elements remaining in the input instance,
507          *                              then this method is equivalent to the CopyFrom() method. @n
508          *                              If there are less elements remaining in the calling buffer, then the %CopyFrom() method 
509          *                              returns @c E_OVERFLOW and does not transfer, while this method copies the number of remaining elements 
510          *                              of the current instance.
511          *
512          * The following example demonstrates how to use the %ReadFrom() method.
513          *
514          * @code
515          *
516          *      // Create instances of IntBuffer to act as the source and destination buffers
517          *      IntBuffer srcBuf;
518          *      IntBuffer destBuf;
519          *
520          *      // Declare an array of integers
521          *      int pArray[] = {0,1,2,3,4,5,6,7,8,9};
522          *
523          *      // Initialize the source buffer with a capacity of 10 elements.
524          *      srcBuf.Construct(10);
525          *
526          *      // Copy the 10 values from pArray starting at position 0 to srcBuf
527          *      // Now srcBuf's position = 10
528          *      srcBuf.SetArray(pArray, 0, 10);
529          *
530          *      // Flip the buffer: The limit is set to the current position
531          *      // and then the position is set to zero
532          *      srcBuf.Flip();  // srcBuf's position = 0 and limit = 10
533          *
534          *
535          *      // Initialize the destination buffer with a capacity of 10 elements.
536          *      destBuf.Construct(10);
537          *
538          *      // Set the limit of destBuf to 5
539          *      destBuf.SetLimit(5);
540          *
541          *      // Read from srcBuf to destBuf
542          *      // destBuf's remaining is 5, smaller than the srcBuf's (10).
543          *      // Therefore, five elements are transferred.
544          *      // srcBuf's position = 5, destBuf's position = 5
545          *      destBuf.ReadFrom(srcBuf);
546          *
547          *
548          * @endcode
549          *
550          * The following example has exactly the same effect as the above %ReadFrom() method.
551          *
552          * @code
553          *
554          *      int copyNum = (destBuf.GetRemaining() < srcBuf.GetRemaing())? destBuf.GetRemaining() : srcBuf.GetRemaining();
555          *      for (int i = 0; i < copyNum; i++)
556          *      {
557          *              int value;
558          *
559          *              // Read from source buffer
560          *              srcBuf.Get(value);                      // srcBuf position is incremented by one.
561          *
562          *              // Write to destination buffer
563          *              destBuf.Set(value);                     // destBuf position is incremented by one.
564          *
565          *      }
566          * @endcode
567          */
568         result ReadFrom(Buffer< Type >& buffer)
569         {
570                 TryReturn(this != static_cast< void* >(&buffer), E_INVALID_ARG,
571                         "[E_INVALID_ARG] The source and target buffers are identical.");
572
573                 int copyLength = (GetRemaining() < buffer.GetRemaining()) ? GetRemaining() : buffer.GetRemaining();
574
575                 memcpy(__pArrayStart + _position * sizeof(Type), buffer.__pArrayStart + buffer._position * sizeof(Type),
576                         copyLength * sizeof(Type));
577
578                 _position += copyLength;
579                 buffer._position += copyLength;
580
581                 return E_SUCCESS;
582         }
583
584
585         /**
586          * Writes the specified @c value into the current buffer instance at the current position,
587          * and then increments the position. @n
588          * Provides a way to perform relative indexing and writing.
589          *
590          * @since 2.0
591          *
592          * @return              An error code
593          * @param[in]   value           The value to write into the calling %Buffer
594          * @exception   E_SUCCESS               The method is successful.
595          * @exception   E_OVERFLOW              Either of the following conditions has occured:
596          *                                                              - The operation (arithmetic/casting/conversion) has caused an overflow.
597          *                                                              - The current position is not smaller than the limit.
598          * @see                 Get()
599          */
600         result Set(Type value)
601         {
602                 TryReturn(_position < _limit, E_OVERFLOW, "[E_OVERFLOW]");
603
604                 ((Type*) __pArrayStart)[_position++] = value;
605                 return E_SUCCESS;
606         }
607
608         /**
609          * Writes the specified @c value into the current instance of the buffer at the given @c index. @n
610          * Provides a way to perform absolute indexing and writing.
611          *
612          * @since 2.0
613          *
614          * @return              An error code
615          * @param[in]   index                           The index at which the value is written
616          * @param[in]   value                           The value to write
617          * @exception   E_SUCCESS           The method is successful.
618          * @exception   E_OUT_OF_RANGE          Either of the following conditions has occured:
619          *                                                                      - The specified index is outside the bounds of the data structure.
620          *                                                                      - The specified @c index is not smaller than the limit.
621      *                                                                  - The specified @c index is less than @c 0.
622          * @see                 Get()
623          */
624         result Set(int index, Type value)
625         {
626                 TryReturn(index < _limit && index >= 0, E_OUT_OF_RANGE,
627                         "[E_OUT_OF_RANGE] The index(%d) MUST be greater than or equal to 0, and less then the current limit(%d).",
628                         index, _limit);
629
630                 ((Type*) __pArrayStart)[index] = value;
631                 return E_SUCCESS;
632         }
633
634         /**
635          * Copies values from the input source array into the calling buffer.
636          *
637          * @since 2.0
638          *
639          * @return              An error code
640          * @param[in]   pArray                          A pointer to the array from where the values are read
641          * @param[in]   index                           The starting index of the array
642          * @param[in]   length                          The number of values read from the given array
643          * @exception   E_SUCCESS                       The method is successful.
644          * @exception   E_INVALID_ARG           Either of the following conditions has occured:
645          *                                                                      - A specified input parameter is invalid.
646          *                                                                      - The specified @c pArray is @c null.
647          * @exception   E_OUT_OF_RANGE          Either of the following conditions has occured:
648          *                                                                      - The specified @c index is outside the bounds of the data structure.
649          *                                                                      - The specified @c index or @c length is less than @c 0.
650          * @exception   E_OVERFLOW                      Either of the following conditions has occured:
651          *                                                                      - The operation (arithmetic/casting/conversion) has caused an overflow.
652          *                                                                      - The remainder of this buffer is smaller than the specified @c length.
653          * @remarks     This method copies @c length number of values starting from the given @c index of the source array,
654          *                              into the calling buffer, starting from the current position. @n
655          *                              After the copy operation, the position is incremented by @c length.
656          * @see                 GetArray()
657          */
658         result SetArray(const Type* pArray, int index, int length)
659         {
660                 TryReturn(null != pArray, E_INVALID_ARG, "[E_INVALID_ARG] The pArray is null.");
661                 TryReturn(index >= 0 && length >= 0, E_OUT_OF_RANGE,
662                         "[E_OUT_OF_RANGE] Both of index(%d) and length(%d) MUST be greater than or equal to 0.", index, length);
663                 TryReturn(GetRemaining() >= length, E_OVERFLOW, "[E_OVERFLOW]");
664
665                 memcpy(__pArrayStart + _position * sizeof(Type), pArray + index, length * sizeof(Type));
666                 _position += length;
667
668                 return E_SUCCESS;
669         }
670
671         /**
672          * Creates a new %Buffer instance. @n
673          * Its content is a shared portion of
674          * the calling %Buffer instance that starts from the current position of the calling %Buffer instance.
675          *
676          * @since 2.0
677          *
678          * @return              A pointer to the new %Buffer instance
679          * @remarks     The content of the new buffer starts at the current position of this %Buffer instance. @n
680          *                              The new buffer's position is @c 0, its capacity and limit is
681          *                              the number of bytes remaining in the current instance of %Buffer,
682          *                              and it is marked as undefined.
683          */
684         Buffer< Type >* SliceN(void) const
685         {
686                 Buffer< Type >* pBuffer = new Buffer< Type >();
687                 pBuffer->_pData = _pData;
688                 AddRef();
689                 pBuffer->_capacity = GetRemaining();
690                 pBuffer->_limit = pBuffer->_capacity;
691                 if (pBuffer->_capacity > 0)
692                 {
693                         pBuffer->__pArrayStart = (byte*) &((Type*) __pArrayStart)[_position];
694                 }
695
696                 return pBuffer;
697         }
698
699         /**
700          * Gets a raw array pointer to calling buffer.
701          *
702          * @since 2.0
703          *
704          * @return              A raw array pointer to the buffer, @n
705          *                              else @c null if the capacity is @c 0
706          */
707         const Type* GetPointer(void) const
708         {
709                 return (Type*) __pArrayStart;
710         }
711
712         /**
713          * Compares the Object instance with the current %Buffer instance for equality.
714          *
715          * @since 2.0
716          *
717          * @return              @c true if the input equals the current %Buffer instance, @n
718          *                              else @c false
719          * @param[in]   obj     The object to compare with the current %Buffer instance
720          * @remarks             This method returns @c true if and only if the specified object is also an instance of %Buffer,
721          *                              the two buffers have the same number of remaining elements, and the two sequences of
722          *                              remaining elements are equal (considered independent of their starting positions).
723          * @see                 Tizen::Base::BufferBase::GetHashCode()
724          */
725         virtual bool Equals(const Tizen::Base::Object& obj) const
726         {
727                 bool out = false;
728                 const Buffer< Type >* other = static_cast< const Buffer< Type >* >(&obj);
729                 if ((other == this) || (*other == *this))
730                 {
731                         out = true;
732                 }
733
734                 return out;
735         }
736
737         /**
738          *      Gets the hash value of the current instance.
739          *
740          *      @since 2.0
741          *
742          *      @return                 The hash value of the current instance
743          *      @remarks                The hash code of a buffer depends only upon its remaining elements.
744          */
745         virtual int GetHashCode(void) const
746         {
747                 int len = (GetRemaining() * GetTypeSize()) / sizeof(int);
748
749                 int hash = 0;
750                 int offset = _position * GetTypeSize();
751                 for (int i = 0; i < len; ++i)
752                 {
753                         hash = (hash << 5) - hash + (int) __pArrayStart[offset + (i * sizeof(int))];
754                 }
755
756                 return hash;
757         }
758
759 private:
760         /**
761          * This is the copy constructor for this class.
762          */
763         Buffer(const Buffer< Type >& buffer)
764         {
765                 Construct(buffer);
766         }
767
768         /**
769          * This is the assignment operator.
770          */
771         Buffer< Type >& operator =(const Buffer< Type >& buffer);
772
773         /**
774          * Returns the size of the type of this buffer.
775          *
776          * @return              The size of the buffer
777          */
778         virtual int GetTypeSize(void) const
779         {
780                 return sizeof(Type);
781         }
782
783         friend class ByteBuffer;
784
785 }; // Buffer
786
787
788 /**
789  * The @c double buffer type
790  * @since 2.0
791  */
792 typedef Buffer< double > DoubleBuffer;
793
794 /**
795 * The @c float buffer type
796 * @since 2.0
797 */
798 typedef Buffer< float > FloatBuffer;
799
800 /**
801 * The @c int buffer type
802 * @since 2.0
803 */
804 typedef Buffer< int > IntBuffer;
805
806 /**
807 * The @c long buffer type
808 * @since 2.0
809 */
810 typedef Buffer< long > LongBuffer;
811
812 /**
813 * The @c long @c long buffer type
814 * @since 2.0
815 */
816 typedef Buffer< long long > LongLongBuffer;
817
818 /**
819 * The @c wchar_t buffer type
820 * @since 2.0
821 */
822 typedef Buffer< wchar_t > WcharBuffer;
823
824 /**
825 * The @c short buffer type
826 * @since 2.0
827 */
828 typedef Buffer< short > ShortBuffer;
829
830
831 #ifdef _MSC_VER
832 template class _OSP_EXPORT_ Buffer< double >;
833 template class _OSP_EXPORT_ Buffer< float >;
834 template class _OSP_EXPORT_ Buffer< int >;
835 template class _OSP_EXPORT_ Buffer< long >;
836 template class _OSP_EXPORT_ Buffer< long long >;
837 template class _OSP_EXPORT_ Buffer< wchar_t >;
838 template class _OSP_EXPORT_ Buffer< short >;
839 #endif
840
841 }} // Tizen::Base
842
843 #endif // _FBASE_BUFFER_H_