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 classes.
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.
127 * @remarks After creating an instance of the %Buffer class, one of the Construct() methods must be called explicitly to initialize this instance.
137 * This is the destructor for this class.
141 virtual ~Buffer(void)
148 * Initializes this instance of %Buffer which is a view of the specified @c buffer. @n
149 * This is similar to a copy constructor.
153 * @param[in] buffer The other %Buffer instance
154 * @exception E_SUCCESS The method is successful.
155 * @exception E_INVALID_ARG The specified input parameter is invalid, or
156 * the source buffer is not constructed.
159 result Construct(const Buffer< Type >& buffer)
161 TryReturn(null != buffer._pData, E_INVALID_ARG, ("[E_INVALID_ARG] The source buffer is not constructed."));
163 _capacity = buffer._capacity;
164 _position = buffer._position;
165 _limit = buffer._limit;
166 _mark = buffer._mark;
167 _pData = buffer._pData;
170 __pArrayStart = buffer.__pArrayStart;
176 * Initializes this instance of %Buffer with the specified @c capacity.
180 * @return An error code
181 * @param[in] capacity The number of elements
182 * @exception E_SUCCESS The method is successful.
183 * @exception E_INVALID_ARG The specified @c capacity is negative.
186 result Construct(int capacity)
188 return BufferBase::Construct(capacity);
192 * Initializes this instance of %Buffer with the specified @c buffer which is shared with this instance.
196 * @return An error code
197 * @param[in] pBuffer The buffer which is shared
198 * @param[in] index The starting index of the buffer from where the first @c byte value is read
199 * @param[in] length The number of bytes to read from the given buffer @n This is a limit of this instance.
200 * @param[in] capacity The capacity of this instance
201 * @exception E_SUCCESS The method is successful.
202 * @exception E_INVALID_ARG A specified input parameter is invalid, or
203 * the @c pBuffer is @c null.
204 * @exception E_OUT_OF_RANGE The specified @c index is outside the bounds of the data structure, or
205 * the @c index is larger than the @c length.
207 result Construct(const Type* pBuffer, int index, int length, int capacity)
209 TryReturn(pBuffer != null, E_INVALID_ARG, "[E_INVALID_ARG] The pBuffer is null.");
210 TryReturn(index >= 0 && length >= 0 && capacity >= 0, E_OUT_OF_RANGE,
211 "[E_OUT_OF_RANGE] index(%d), length(%d) and capacity(%d) MUST be greater than or equal to 0.", index,
213 TryReturn(index < capacity && length <= capacity && index + length <= capacity, E_OUT_OF_RANGE,
214 "[E_OUT_OF_RANGE] index(%d), length(%d) and capacity(%d) MUST be greater than or equal to 0.", index,
218 int sizeofBufferData = sizeof(_BufferData);
220 Type* tempByte = const_cast< Type* >(pBuffer + index);
221 __pArrayStart = reinterpret_cast< byte* >(tempByte);
223 pTemp = malloc(sizeofBufferData);
224 TryReturn(pTemp != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]");
226 memset(pTemp, 0, sizeofBufferData);
227 _pData = static_cast< _BufferData* >(pTemp);
229 _pData->refCount = 1;
230 _pData->capacityInByte = capacity * sizeof(Type);
232 _capacity = capacity;
239 * This subscript operator returns the reference to the element indicated by the given @c index.
243 * @return A reference to the indexed element
244 * @param[in] index The index of the element @n
245 * It must be less than the limit.
247 Type& operator [](int index) const
249 AppAssertf(index < _limit, "index out of range.\n");
250 AppAssertf(index >= 0, "index out of range.\n");
252 return ((Type*) __pArrayStart)[index];
256 * Overloaded equality operator to compare two %Buffer instances.
260 * @return @c true if the buffers being compared are equal, @n
262 * @param[in] buffer The buffer to compare with the current instance of %Buffer
263 * @remarks This method returns @c true only if the two buffers have the same number of remaining elements @n
264 * and the two sequences of remaining elements are equal (considered independently of their starting positions).
267 bool operator ==(const Buffer< Type >& buffer) const
270 if (this == (void*) (&buffer))
274 else if (GetRemaining() != buffer.GetRemaining())
280 void* p1 = &(((Type*) __pArrayStart)[_position]);
281 void* p2 = &(((Type*) buffer.__pArrayStart)[buffer._position]);
282 if ((p1 != p2) && (memcmp(p1, p2, sizeof(Type) * GetRemaining()) != 0))
292 * Checks whether the two %Buffer instances are not equal.
296 * @return @c true if the buffers are not equal, @n
298 * @param[in] buffer The buffer to compare with the current instance of %Buffer
299 * @remarks This method returns @c false only if the two buffers being compared have the same @n
300 * number of remaining elements and the two sequences of remaining elements are equal @n
301 * (considered independently of their starting positions).
304 bool operator !=(const Buffer< Type >& buffer) const
306 return !(*this == buffer);
310 * Copies the remaining elements of the input %Buffer instance into the current
311 * %Buffer instance. @n
312 * It returns E_OVERFLOW if the remaining part of the current instance is smaller
313 * than the remaining part of the input instance.
317 * @return An error code
318 * @param[in] buffer The source buffer from which bytes are read @n
319 * It must not be the current instance of %Buffer.
320 * @exception E_SUCCESS The method is successful.
321 * @exception E_INVALID_ARG The specified input parameter is invalid, or
322 * the source buffer is same as destination buffer,
323 * that is, the current instance of %Buffer.
324 * @exception E_OVERFLOW The operation (arithmetic/casting/conversion) has caused an overflow. @n
325 * The number of remaining bytes of the current buffer is less than
326 * the number of remaining bytes of the given buffer.
327 * @remarks After the copy operation, the current (destination) buffer's position and the given
328 * (source) buffer's position are incremented by the number of elements copied (the number
329 * of remaining elements of the given buffer). @n
330 * If the remaining part of the current instance is not less than the remaining part of the input instance,
331 * the effect of this method and the ReadFrom() method is the same. But when the remaining part of the
332 * current instance is less, ReadFrom() method copies the number of remaining elements of the current
333 * instance while this method returns E_OVERFLOW and does not transfer.
336 * The following example demonstrates how to use the %CopyFrom() method.
340 * // Create instances of IntBuffer to act as source and destination buffers
344 * // Declare an array of integers
345 * int pArray[] = {0,1,2,3,4,5,6,7,8,9};
347 * // Initialize the source buffer with 10 elements.
348 * srcBuf.Construct(10);
350 * // Copy the 10 values from pArray starting at position 0 to srcBuf
351 * // Now srcBuf's position = 10
352 * srcBuf.SetArray(pArray, 0, 10);
354 * // Flip the buffer: The limit is set to the current position
355 * // and then the position is set to zero
356 * srcBuf.Flip(); // srcBuf's position = 0 and limit = 10
359 * destBuf.Construct(20);
361 * // Copy from srcBuf to destBuf
362 * // Now srcBuf's position = 10, destBuf's position = 10
363 * destBuf.CopyFrom(srcBuf);
367 * The following example has exactly the same effect as the above %CopyFrom() method.
371 * int copyNum = srcBuf.GetRemaining();
372 * for (int i = 0; i < copyNum; i++)
376 * // Read from the source buffer
377 * srcBuf.Get(value); // srcBuf position is incremented by one.
379 * // Write to the destination buffer
380 * destBuf.Set(value); // destBuf position is incremented by one.
385 result CopyFrom(Buffer< Type >& buffer)
387 TryReturn(this != static_cast< void* >(&buffer), E_INVALID_ARG,
388 "[E_INVALID_ARG] The source and target buffers are identical.");
389 int copyLength = buffer.GetRemaining();
390 TryReturn(GetRemaining() >= copyLength, E_OVERFLOW, "[E_OVERFLOW]");
392 memcpy(__pArrayStart + _position * sizeof(Type), buffer.__pArrayStart + buffer._position * sizeof(Type),
393 copyLength * sizeof(Type));
395 _position += copyLength;
396 buffer._position += copyLength;
402 * Reads the value from the current position in the buffer, and then increments the position. @n
403 * Provides a way for relative indexing and reading.
407 * @return An error code
408 * @param[out] value The value at the current position
409 * @exception E_SUCCESS The method is successful.
410 * @exception E_UNDERFLOW The operation (arithmetic/casting/conversion) has caused an underflow. @n
411 * The current position is greater than the limit.
414 result Get(Type& value)
416 TryReturn(_position < _limit, E_UNDERFLOW, "[E_UNDERFLOW]");
418 value = ((Type*) __pArrayStart)[_position++];
423 * Reads the value at the given @c index. @n
424 * Provides a way for absolute indexing and reading.
428 * @return An error code
429 * @param[in] index The index into the buffer from where the value is read
430 * @param[out] value The value at the given index
431 * @exception E_SUCCESS The method is successful.
432 * @exception E_OUT_OF_RANGE The specified @c index is outside the bounds of the data structure. @n
433 * The @c index is greater than the limit or less than @c 0.
436 result Get(int index, Type& value) const
438 TryReturn(index < _limit && index >= 0, E_OUT_OF_RANGE,
439 "[E_OUT_OF_RANGE] The index(%d) MUST be greater than or equal to 0, and less then the current limit(%d).",
442 value = ((Type*) __pArrayStart)[index];
448 * Copies the specified range of values from the calling buffer to the specified destination array as per the given @c index of the array.
452 * @return An error code
453 * @param[out] pArray A pointer to the array into which values are written
454 * @param[in] index The starting index in the array of the first value to write
455 * @param[in] length The number of values from the buffer to write to the array
456 * @exception E_SUCCESS The method is successful.
457 * @exception E_INVALID_ARG A specified input parameter is invalid, or
458 * the @c pArray is @c null.
459 * @exception E_OUT_OF_RANGE The specified index is outside the bounds of the data structure, or
460 * the @c index or length is less than @c 0.
461 * @exception E_UNDERFLOW The operation (arithmetic/casting/conversion) has caused an underflow. @n
462 * The remaining elements of this buffer are smaller than @c length.
463 * @remarks After the copy operation, the position is incremented by @c length.
466 result GetArray(Type* pArray, int index, int length)
468 TryReturn(0 != pArray, E_INVALID_ARG, "[E_INVALID_ARG] The pArray is null.");
469 TryReturn(index >= 0 && length >= 0, E_OUT_OF_RANGE,
470 "[E_OUT_OF_RANGE] Both of index(%d) and length(%d) MUST be greater than or equal to 0.", index, length);
471 TryReturn(GetRemaining() >= length, E_UNDERFLOW, "[E_UNDERFLOW]");
473 memcpy(pArray + index, __pArrayStart + _position * sizeof(Type), length * sizeof(Type));
480 * Transfers bytes from the input buffer into the calling buffer. @n
481 * If the empty space in the calling buffer is larger than the remaining values from the input buffer,
482 * all the remaining elements from the input are copied to the destination. @n
483 * Otherwise, the number of bytes copied equals the number of elements remaining in the calling buffer.
487 * @return An error code
488 * @param[in] buffer The source buffer from where the bytes are read @n
489 * It must not be this buffer.
490 * @exception E_SUCCESS The method is successful.
491 * @exception E_INVALID_ARG The specified input parameter is invalid. @n
492 * The given buffer is same as the current buffer instance.
493 * @remarks After the copy operation, the current (destination) buffer's position and the given
494 * (source) buffer's position are incremented by the number of elements copied (the smaller value
495 * between the number of elements remaining in the calling buffer and the source buffer). @n
496 * If there are more elements remaining in the calling buffer than elements remaining in the input instance,
497 * this method is equivalent to CopyFrom() method. If there are less remaining elements in the
498 * calling buffer, the %CopyFrom() method returns @c E_OVERFLOW and does not transfer
499 * while this method copies the number of remaining elements of the current instance.
502 * The following example demonstrates how to use the %ReadFrom() method.
506 * // Create instances of IntBuffer to act as the source and destination buffers
510 * // Declare an array of integers
511 * int pArray[] = {0,1,2,3,4,5,6,7,8,9};
513 * // Initialize the source buffer with a capacity of 10 elements.
514 * srcBuf.Construct(10);
516 * // Copy the 10 values from pArray starting at position 0 to srcBuf
517 * // Now srcBuf's position = 10
518 * srcBuf.SetArray(pArray, 0, 10);
520 * // Flip the buffer: The limit is set to the current position
521 * // and then the position is set to zero
522 * srcBuf.Flip(); // srcBuf's position = 0 and limit = 10
525 * // Initialize the destination buffer with a capacity of 10 elements.
526 * destBuf.Construct(10);
528 * // Set the limit of destBuf to 5
529 * destBuf.SetLimit(5);
531 * // Read from srcBuf to destBuf
532 * // destBuf's remaining is 5, smaller than the srcBuf's (10).
533 * // Therefore, five elements are transferred.
534 * // srcBuf's position = 5, destBuf's position = 5
535 * destBuf.ReadFrom(srcBuf);
540 * The following example has exactly the same effect as the above %ReadFrom() method.
544 * int copyNum = (destBuf.GetRemaining() < srcBuf.GetRemaing())? destBuf.GetRemaining() : srcBuf.GetRemaining();
545 * for (int i = 0; i < copyNum; i++)
549 * // Read from source buffer
550 * srcBuf.Get(value); // srcBuf position is incremented by one.
552 * // Write to destination buffer
553 * destBuf.Set(value); // destBuf position is incremented by one.
558 result ReadFrom(Buffer< Type >& buffer)
560 TryReturn(this != static_cast< void* >(&buffer), E_INVALID_ARG,
561 "[E_INVALID_ARG] The source and target buffers are identical.");
563 int copyLength = (GetRemaining() < buffer.GetRemaining()) ? GetRemaining() : buffer.GetRemaining();
565 memcpy(__pArrayStart + _position * sizeof(Type), buffer.__pArrayStart + buffer._position * sizeof(Type),
566 copyLength * sizeof(Type));
568 _position += copyLength;
569 buffer._position += copyLength;
576 * Writes the specified @c value into the current buffer instance at the current position,
577 * and then increments the position. @n
578 * Provides a way for relative indexing and writing.
582 * @return An error code
583 * @param[in] value The value to write to the calling %Buffer
584 * @exception E_SUCCESS The method is successful.
585 * @exception E_OVERFLOW The operation (arithmetic/casting/conversion) has caused an overflow. @n
586 * The current position is not smaller than the limit.
589 result Set(Type value)
591 TryReturn(_position < _limit, E_OVERFLOW, "[E_OVERFLOW]");
593 ((Type*) __pArrayStart)[_position++] = value;
598 * Writes the specified @c value into the current instance of buffer at the given @c index. @n
599 * Provides a way for absolute indexing and writing.
603 * @return An error code
604 * @param[in] index The index at which the value is written
605 * @param[in] value The value to write
606 * @exception E_SUCCESS The method is successful.
607 * @exception E_OUT_OF_RANGE The specified index is outside the bounds of the data structure, or
608 * the @c index is not smaller than the limit or less than @c 0.
611 result Set(int index, Type value)
613 TryReturn(index < _limit && index >= 0, E_OUT_OF_RANGE,
614 "[E_OUT_OF_RANGE] The index(%d) MUST be greater than or equal to 0, and less then the current limit(%d).",
617 ((Type*) __pArrayStart)[index] = value;
622 * Copies values from the input source array into the calling buffer.
626 * @return An error code
627 * @param[in] pArray A pointer to the array from where the values are read
628 * @param[in] index The starting index of the array
629 * @param[in] length The number of values read from the given array
630 * @exception E_SUCCESS The method is successful.
631 * @exception E_INVALID_ARG A specified input parameter is invalid, or
632 * the @c pArray is @c null.
633 * @exception E_OUT_OF_RANGE The specified index is outside the bounds of the data structure, or
634 * the @c index or length is less than @c 0.
635 * @exception E_OVERFLOW The operation (arithmetic/casting/conversion) has caused an overflow. @n
636 * The remainder of this buffer is smaller than @c length.
637 * @remarks This method copies @c length number of values from the source array,
638 * starting from the given @c index in the array, into the calling
639 * buffer, starting at the current position.
640 * After the copy operation, the position is incremented by @c length.
643 result SetArray(const Type* pArray, int index, int length)
645 TryReturn(null != pArray, E_INVALID_ARG, "[E_INVALID_ARG] The pArray is null.");
646 TryReturn(index >= 0 && length >= 0, E_OUT_OF_RANGE,
647 "[E_OUT_OF_RANGE] Both of index(%d) and length(%d) MUST be greater than or equal to 0.", index, length);
648 TryReturn(GetRemaining() >= length, E_OVERFLOW, "[E_OVERFLOW]");
650 memcpy(__pArrayStart + _position * sizeof(Type), pArray + index, length * sizeof(Type));
657 * Creates a new %Buffer instance. @n
658 * Its content is a shared portion of
659 * the calling %Buffer instance that starts from the current position of calling %Buffer instance.
663 * @return A pointer to the new buffer
664 * @remarks The content of the new buffer starts at the current position of this instance of %Buffer.
665 * The new buffer's position is @c 0, its capacity and limit is
666 * the number of bytes remaining in the current instance of %Buffer,
667 * and it is marked as undefined.
669 Buffer< Type >* SliceN(void) const
671 Buffer< Type >* pBuffer = new Buffer< Type >();
672 pBuffer->_pData = _pData;
674 pBuffer->_capacity = GetRemaining();
675 pBuffer->_limit = pBuffer->_capacity;
676 if (pBuffer->_capacity > 0)
678 pBuffer->__pArrayStart = (byte*) &((Type*) __pArrayStart)[_position];
685 * Gets a raw array pointer to calling buffer.
689 * @return A raw array pointer to the buffer, @n
690 * else @c null if the capacity is @c 0
692 const Type* GetPointer(void) const
694 return (Type*) __pArrayStart;
698 * Compares the Object instance with the calling %Buffer instance for equivalence.
702 * @return @c true if the input equals the calling %Buffer instance, @n
704 * @param[in] obj The object to compare with the calling %Buffer
705 * @remarks This method returns @c true if and only if the specified object is also an instance of %Buffer class,
706 * the two buffers have the same number of remaining elements, and the two sequences of
707 * remaining elements are equal (considered independently of their starting positions).
708 * @see Tizen::Base::BufferBase::GetHashCode()
710 virtual bool Equals(const Tizen::Base::Object& obj) const
713 const Buffer< Type >* other = static_cast< const Buffer< Type >* >(&obj);
714 if ((other == this) || (*other == *this))
723 * Gets the hash value of the current instance.
727 * @return The hash value of the current instance
728 * @remarks The hash code of a buffer depends only upon its remaining elements.
730 virtual int GetHashCode(void) const
732 int len = (GetRemaining() * GetTypeSize()) / sizeof(int);
735 int offset = _position * GetTypeSize();
736 for (int i = 0; i < len; ++i)
738 hash = (hash << 5) - hash + (int) __pArrayStart[offset + (i * sizeof(int))];
746 * This is the copy constructor for this class.
748 Buffer(const Buffer< Type >& buffer)
754 * This is the assignment operator.
756 Buffer< Type >& operator =(const Buffer< Type >& buffer);
759 * Returns the size of the type of this buffer.
761 * @return The size of the buffer
763 virtual int GetTypeSize(void) const
768 friend class ByteBuffer;
774 * The @c double buffer type
777 typedef Buffer< double > DoubleBuffer;
780 * The @c float buffer type
783 typedef Buffer< float > FloatBuffer;
786 * The @c int buffer type
789 typedef Buffer< int > IntBuffer;
792 * The @c long buffer type
795 typedef Buffer< long > LongBuffer;
798 * The @c long @c long buffer type
801 typedef Buffer< long long > LongLongBuffer;
804 * The @c wchar_t buffer type
807 typedef Buffer< wchar_t > WcharBuffer;
810 * The @c short buffer type
813 typedef Buffer< short > ShortBuffer;
817 template class _OSP_EXPORT_ Buffer< double >;
818 template class _OSP_EXPORT_ Buffer< float >;
819 template class _OSP_EXPORT_ Buffer< int >;
820 template class _OSP_EXPORT_ Buffer< long >;
821 template class _OSP_EXPORT_ Buffer< long long >;
822 template class _OSP_EXPORT_ Buffer< wchar_t >;
823 template class _OSP_EXPORT_ Buffer< short >;
828 #endif // _FBASE_BUFFER_H_