2 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
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
8 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 * @brief This is the header file for the %Buffer class.
21 * This header file contains the declarations of the %Buffer class.
23 #ifndef _FBASE_BUFFER_H_
24 #define _FBASE_BUFFER_H_
27 #include <FBaseBufferBase.h>
28 #include <FBaseResult.h>
31 namespace Tizen { namespace Base
34 // Forward declaration
39 * @brief This class represents a linear finite sequence of elements of the same type.
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.
46 * For more information on the class features, see <a href="../org.tizen.native.appprogramming/html/guide/base/buffer.htm">Buffer</a>.
48 * @see Tizen::Base::BufferBase
50 * The following example demonstrates how to use the %Buffer class.
56 * using namespace Tizen::Base;
59 * MyClass::BufferSample(void)
61 * // Sets the buffer capacity to 1024
62 * const int BUFFER_SIZE_MAX = 1024;
64 * // Initializes intBuf with capacity
66 * intBuf.Construct(BUFFER_SIZE_MAX);
68 * int intArray[] = {0,1,2,3,4,5,6,7,8,9};
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)));
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
78 * // Gets the number of elements between the current position and the limit
79 * int remaining = intBuf.GetRemaining();
81 * // Initializes a doubleBuf with capacity(10) using Construct() method
82 * DoubleBuffer doubleBuf;
83 * doubleBuf.Construct(remaining);
85 * // Reads and writes elements from the intBuf to the doubleBuf
86 * for (int i = 0; i < remaining; i++)
90 * // Demonstrates relative reading and writing
92 * // Reads the value at the current position, and then increments the position
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);
99 * // Now, positions of the intBuf and the doubleBuf have been incremented by one
102 * // Flips the doubleBuf
104 * // Now, the doubleBuf's position = 0 and limit = 10
106 * // Gets the remaining elements of the doubleBuf
107 * remaining = doubleBuf.GetRemaining();
109 * // Gets the second double value with index
110 * double doubleValue;
111 * doubleBuf.Get(1, doubleValue); // 12.34
116 template< class Type >
117 class _OSP_EXPORT_ Buffer
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.
135 * This is the destructor for this class.
139 virtual ~Buffer(void)
146 * Initializes this instance of %Buffer which is a view of the specified @c buffer. @n
147 * This is similar to a copy constructor.
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.
158 result Construct(const Buffer< Type >& buffer)
160 TryReturn(null != buffer._pData, E_INVALID_ARG, ("[E_INVALID_ARG] The source buffer is not constructed."));
162 _capacity = buffer._capacity;
163 _position = buffer._position;
164 _limit = buffer._limit;
165 _mark = buffer._mark;
166 _pData = buffer._pData;
169 __pArrayStart = buffer.__pArrayStart;
175 * Initializes this instance of %Buffer with the specified @c capacity.
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.
185 result Construct(int capacity)
187 return BufferBase::Construct(capacity);
191 * Initializes this instance of %Buffer with the specified @c buffer which is shared with this instance.
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.
209 result Construct(const Type* pBuffer, int index, int length, int capacity)
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,
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,
220 int sizeofBufferData = sizeof(_BufferData);
222 Type* tempByte = const_cast< Type* >(pBuffer + index);
223 __pArrayStart = reinterpret_cast< byte* >(tempByte);
225 pTemp = malloc(sizeofBufferData);
226 TryReturn(pTemp != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]");
228 memset(pTemp, 0, sizeofBufferData);
229 _pData = static_cast< _BufferData* >(pTemp);
231 _pData->refCount = 1;
232 _pData->capacityInByte = capacity * sizeof(Type);
234 _capacity = capacity;
241 * Returns a reference to the element indicated by the given @c index.
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.
249 Type& operator [](int index) const
251 AppAssertf(index < _limit, "index out of range.\n");
252 AppAssertf(index >= 0, "index out of range.\n");
254 return ((Type*) __pArrayStart)[index];
258 * Checks whether two %Buffer instances are equal.
262 * @return @c true if the two %Buffer instances are equal, @n
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).
269 bool operator ==(const Buffer< Type >& buffer) const
272 if (this == (void*) (&buffer))
276 else if (GetRemaining() != buffer.GetRemaining())
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))
294 * Checks whether two %Buffer instances are not equal.
298 * @return @c true if the two %Buffer instances are not equal, @n
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).
306 bool operator !=(const Buffer< Type >& buffer) const
308 return !(*this == buffer);
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.
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.
339 * The following example demonstrates how to use the %CopyFrom() method.
343 * // Create instances of IntBuffer to act as source and destination buffers
347 * // Declare an array of integers
348 * int pArray[] = {0,1,2,3,4,5,6,7,8,9};
350 * // Initialize the source buffer with 10 elements.
351 * srcBuf.Construct(10);
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);
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
362 * destBuf.Construct(20);
364 * // Copy from srcBuf to destBuf
365 * // Now srcBuf's position = 10, destBuf's position = 10
366 * destBuf.CopyFrom(srcBuf);
370 * The following example has exactly the same effect as the above %CopyFrom() method.
374 * int copyNum = srcBuf.GetRemaining();
375 * for (int i = 0; i < copyNum; i++)
379 * // Read from the source buffer
380 * srcBuf.Get(value); // srcBuf position is incremented by one.
382 * // Write to the destination buffer
383 * destBuf.Set(value); // destBuf position is incremented by one.
388 result CopyFrom(Buffer< Type >& buffer)
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]");
395 memcpy(__pArrayStart + _position * sizeof(Type), buffer.__pArrayStart + buffer._position * sizeof(Type),
396 copyLength * sizeof(Type));
398 _position += copyLength;
399 buffer._position += copyLength;
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.
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.
418 result Get(Type& value)
420 TryReturn(_position < _limit, E_UNDERFLOW, "[E_UNDERFLOW]");
422 value = ((Type*) __pArrayStart)[_position++];
427 * Reads the value at the given @c index. @n
428 * Provides a way to preform absolute indexing and reading.
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.
442 result Get(int index, Type& value) const
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).",
448 value = ((Type*) __pArrayStart)[index];
454 * Copies the specified range of values from the calling buffer to the specified @c index of the destination array.
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.
475 result GetArray(Type* pArray, int index, int length)
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]");
482 memcpy(pArray + index, __pArrayStart + _position * sizeof(Type), length * sizeof(Type));
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.
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.
512 * The following example demonstrates how to use the %ReadFrom() method.
516 * // Create instances of IntBuffer to act as the source and destination buffers
520 * // Declare an array of integers
521 * int pArray[] = {0,1,2,3,4,5,6,7,8,9};
523 * // Initialize the source buffer with a capacity of 10 elements.
524 * srcBuf.Construct(10);
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);
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
535 * // Initialize the destination buffer with a capacity of 10 elements.
536 * destBuf.Construct(10);
538 * // Set the limit of destBuf to 5
539 * destBuf.SetLimit(5);
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);
550 * The following example has exactly the same effect as the above %ReadFrom() method.
554 * int copyNum = (destBuf.GetRemaining() < srcBuf.GetRemaing())? destBuf.GetRemaining() : srcBuf.GetRemaining();
555 * for (int i = 0; i < copyNum; i++)
559 * // Read from source buffer
560 * srcBuf.Get(value); // srcBuf position is incremented by one.
562 * // Write to destination buffer
563 * destBuf.Set(value); // destBuf position is incremented by one.
568 result ReadFrom(Buffer< Type >& buffer)
570 TryReturn(this != static_cast< void* >(&buffer), E_INVALID_ARG,
571 "[E_INVALID_ARG] The source and target buffers are identical.");
573 int copyLength = (GetRemaining() < buffer.GetRemaining()) ? GetRemaining() : buffer.GetRemaining();
575 memcpy(__pArrayStart + _position * sizeof(Type), buffer.__pArrayStart + buffer._position * sizeof(Type),
576 copyLength * sizeof(Type));
578 _position += copyLength;
579 buffer._position += copyLength;
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.
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.
600 result Set(Type value)
602 TryReturn(_position < _limit, E_OVERFLOW, "[E_OVERFLOW]");
604 ((Type*) __pArrayStart)[_position++] = value;
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.
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.
624 result Set(int index, Type value)
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).",
630 ((Type*) __pArrayStart)[index] = value;
635 * Copies values from the input source array into the calling buffer.
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.
658 result SetArray(const Type* pArray, int index, int length)
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]");
665 memcpy(__pArrayStart + _position * sizeof(Type), pArray + index, length * sizeof(Type));
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.
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.
684 Buffer< Type >* SliceN(void) const
686 Buffer< Type >* pBuffer = new Buffer< Type >();
687 pBuffer->_pData = _pData;
689 pBuffer->_capacity = GetRemaining();
690 pBuffer->_limit = pBuffer->_capacity;
691 if (pBuffer->_capacity > 0)
693 pBuffer->__pArrayStart = (byte*) &((Type*) __pArrayStart)[_position];
700 * Gets a raw array pointer to calling buffer.
704 * @return A raw array pointer to the buffer, @n
705 * else @c null if the capacity is @c 0
707 const Type* GetPointer(void) const
709 return (Type*) __pArrayStart;
713 * Compares the Object instance with the current %Buffer instance for equality.
717 * @return @c true if the input equals the current %Buffer instance, @n
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()
725 virtual bool Equals(const Tizen::Base::Object& obj) const
728 const Buffer< Type >* other = static_cast< const Buffer< Type >* >(&obj);
729 if ((other == this) || (*other == *this))
738 * Gets the hash value of the current instance.
742 * @return The hash value of the current instance
743 * @remarks The hash code of a buffer depends only upon its remaining elements.
745 virtual int GetHashCode(void) const
747 int len = (GetRemaining() * GetTypeSize()) / sizeof(int);
750 int offset = _position * GetTypeSize();
751 for (int i = 0; i < len; ++i)
753 hash = (hash << 5) - hash + (int) __pArrayStart[offset + (i * sizeof(int))];
761 * This is the copy constructor for this class.
763 Buffer(const Buffer< Type >& buffer)
769 * This is the assignment operator.
771 Buffer< Type >& operator =(const Buffer< Type >& buffer);
774 * Returns the size of the type of this buffer.
776 * @return The size of the buffer
778 virtual int GetTypeSize(void) const
783 friend class ByteBuffer;
789 * The @c double buffer type
792 typedef Buffer< double > DoubleBuffer;
795 * The @c float buffer type
798 typedef Buffer< float > FloatBuffer;
801 * The @c int buffer type
804 typedef Buffer< int > IntBuffer;
807 * The @c long buffer type
810 typedef Buffer< long > LongBuffer;
813 * The @c long @c long buffer type
816 typedef Buffer< long long > LongLongBuffer;
819 * The @c wchar_t buffer type
822 typedef Buffer< wchar_t > WcharBuffer;
825 * The @c short buffer type
828 typedef Buffer< short > ShortBuffer;
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 >;
843 #endif // _FBASE_BUFFER_H_