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.
24 #ifndef _FBASE_BUFFER_H_
25 #define _FBASE_BUFFER_H_
28 #include <FBaseBufferBase.h>
29 #include <FBaseResult.h>
32 namespace Tizen { namespace Base
35 // Forward declaration
40 * @brief This class represents a linear finite sequence of elements of the same type.
44 * The %Buffer class represents a linear finite sequence of elements of the same type.
45 * It is a means of defining an aggregation of the same type of objects, similar to an array.
47 * For more information on the class features, see <a href="../org.tizen.native.appprogramming/html/guide/base/buffer.htm">Buffer</a>.
49 * @see Tizen::Base::BufferBase
51 * The following example demonstrates how to use the %Buffer class.
57 * using namespace Tizen::Base;
60 * MyClass::BufferSample(void)
62 * // Sets the buffer capacity to 1024
63 * const int BUFFER_SIZE_MAX = 1024;
65 * // Initializes intBuf with capacity
67 * intBuf.Construct(BUFFER_SIZE_MAX);
69 * int intArray[] = {0,1,2,3,4,5,6,7,8,9};
71 * // Copies all values from intArray to intBuffer instance
72 * // position = 10 (num of element copied)
73 * intBuf.SetArray(intArray, 0, (sizeof(intArray) / sizeof(int)));
75 * // Flips the buffer: The limit is set to the current position and
76 * // then the position is set to zero
77 * intBuf.Flip(); // position = 0, limit = 10
79 * // Gets the number of elements between the current position and the limit
80 * int remaining = intBuf.GetRemaining();
82 * // Initializes a doubleBuf with capacity(10) using Construct() method
83 * DoubleBuffer doubleBuf;
84 * doubleBuf.Construct(remaining);
86 * // Reads and writes elements from the intBuf to the doubleBuf
87 * for (int i = 0; i < remaining; i++)
91 * // Demonstrates relative reading and writing
93 * // Reads the value at the current position, and then increments the position
96 * // Writes the value * 12.34 at the current position of the doubleBuf
97 * // and then increment the position
98 * doubleBuf.Set(value * 12.34);
100 * // Now, positions of the intBuf and the doubleBuf have been incremented by one
103 * // Flips the doubleBuf
105 * // Now, the doubleBuf's position = 0 and limit = 10
107 * // Gets the remaining elements of the doubleBuf
108 * remaining = doubleBuf.GetRemaining();
110 * // Gets the second double value with index
111 * double doubleValue;
112 * doubleBuf.Get(1, doubleValue); // 12.34
118 class _OSP_EXPORT_ Buffer
124 * This is the default constructor for this class.
128 * @remarks After creating an instance of the %Buffer class, one of the Construct() methods must be called explicitly to initialize this instance.
138 * This is the destructor for this class.
142 virtual ~Buffer(void)
149 * Initializes this instance of %Buffer which is a view of the specified @c buffer. @n
150 * This is similar to a copy constructor.
154 * @param[in] buffer The other %Buffer instance
155 * @exception E_SUCCESS The method is successful.
156 * @exception E_INVALID_ARG The specified input parameter is invalid, or
157 * the source buffer is not constructed.
160 result Construct(const Buffer <Type>& buffer)
162 TryReturn(null != buffer._pData, E_INVALID_ARG, ("[E_INVALID_ARG] The source buffer is not constructed."));
164 _capacity = buffer._capacity;
165 _position = buffer._position;
166 _limit = buffer._limit;
167 _mark = buffer._mark;
168 _pData = buffer._pData;
171 __pArrayStart = buffer.__pArrayStart;
177 * Initializes this instance of %Buffer with the specified @c capacity.
181 * @return An error code
182 * @param[in] capacity The number of elements
183 * @exception E_SUCCESS The method is successful.
184 * @exception E_INVALID_ARG The specified @c capacity is negative.
187 result Construct(int capacity)
189 return BufferBase::Construct(capacity);
193 * Initializes this instance of %Buffer with the specified @c buffer which is shared with this instance.
197 * @return An error code
198 * @param[in] pBuffer The buffer which is shared
199 * @param[in] index The starting index of the buffer from where the first @c byte value is read
200 * @param[in] length The number of bytes to read from the given buffer @n This is a limit of this instance.
201 * @param[in] capacity The capacity of this instance
202 * @exception E_SUCCESS The method is successful.
203 * @exception E_INVALID_ARG A specified input parameter is invalid, or
204 * the @c pBuffer is @c null.
205 * @exception E_OUT_OF_RANGE The specified @c index is outside the bounds of the data structure, or
206 * the @c index is larger than the @c length.
208 result Construct(const Type* pBuffer, int index, int length, int capacity)
210 TryReturn(pBuffer != null, E_INVALID_ARG, "[E_INVALID_ARG] The pBuffer is null.");
211 TryReturn(index >= 0 && length >= 0 && capacity >=0, E_OUT_OF_RANGE,
212 "[E_OUT_OF_RANGE] index(%d), length(%d) and capacity(%d) MUST be greater than or equal to 0.", index,
214 TryReturn(index < capacity && length <= capacity && index + length <= capacity, E_OUT_OF_RANGE,
215 "[E_OUT_OF_RANGE] index(%d), length(%d) and capacity(%d) MUST be greater than or equal to 0.", index,
219 int sizeofBufferData = sizeof(_BufferData);
221 Type* tempByte = const_cast <Type *> (pBuffer + index);
222 __pArrayStart = reinterpret_cast <byte *> (tempByte);
224 pTemp = malloc(sizeofBufferData);
225 TryReturn(pTemp != null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY]");
227 memset(pTemp, 0, sizeofBufferData);
228 _pData = static_cast <_BufferData*>(pTemp);
230 _pData->refCount = 1;
231 _pData->capacityInByte = capacity * sizeof(Type);
233 _capacity = capacity;
240 * This subscript operator returns the reference to the element indicated by the given @c index.
244 * @return A reference to the indexed element
245 * @param[in] index The index of the element @n
246 * It must be less than the limit.
248 Type& operator [](int index) const
250 AppAssertf(index < _limit, "index out of range.\n");
251 AppAssertf(index >= 0, "index out of range.\n");
253 return ((Type*) __pArrayStart)[index];
257 * Overloaded equality operator to compare two %Buffer instances.
261 * @return @c true if the buffers being compared are equal, @n
263 * @param[in] buffer The buffer to compare with the current instance of %Buffer
264 * @remarks This method returns @c true only if the two buffers have the same number of remaining elements @n
265 * and the two sequences of remaining elements are equal (considered independently of their starting positions).
268 bool operator ==(const Buffer <Type>& buffer) const
271 if (this == (void*) (&buffer))
275 else if (GetRemaining() != buffer.GetRemaining())
281 void* p1 = &(((Type*) __pArrayStart)[_position]);
282 void* p2 = &(((Type*) buffer.__pArrayStart)[buffer._position]);
283 if ((p1 != p2) && (memcmp(p1, p2, sizeof(Type) * GetRemaining()) != 0))
293 * Checks whether the two %Buffer instances are not equal.
297 * @return @c true if the buffers are not equal, @n
299 * @param[in] buffer The buffer to compare with the current instance of %Buffer
300 * @remarks This method returns @c false only if the two buffers being compared have the same @n
301 * number of remaining elements and the two sequences of remaining elements are equal @n
302 * (considered independently of their starting positions).
305 bool operator !=(const Buffer <Type>& buffer) const
307 return !(*this == buffer);
311 * Copies the remaining elements of the input %Buffer instance into the current
312 * %Buffer instance. @n
313 * It returns E_OVERFLOW if the remaining part of the current instance is smaller
314 * than the remaining part of the input instance.
318 * @return An error code
319 * @param[in] buffer The source buffer from which bytes are read @n
320 * It must not be the current instance of %Buffer.
321 * @exception E_SUCCESS The method is successful.
322 * @exception E_INVALID_ARG The specified input parameter is invalid, or
323 * the source buffer is same as destination buffer,
324 * that is, the current instance of %Buffer.
325 * @exception E_OVERFLOW The operation (arithmetic/casting/conversion) has caused an overflow. @n
326 * The number of remaining bytes of the current buffer is less than
327 * the number of remaining bytes of the given buffer.
328 * @remarks After the copy operation, the current (destination) buffer's position and the given
329 * (source) buffer's position are incremented by the number of elements copied (the number
330 * of remaining elements of the given buffer). @n
331 * If the remaining part of the current instance is not less than the remaining part of the input instance,
332 * the effect of this method and the ReadFrom() method is the same. But when the remaining part of the
333 * current instance is less, ReadFrom() method copies the number of remaining elements of the current
334 * instance while this method returns E_OVERFLOW and does not transfer.
337 * The following example demonstrates how to use the %CopyFrom() method.
341 * // Create instances of IntBuffer to act as source and destination buffers
345 * // Declare an array of integers
346 * int pArray[] = {0,1,2,3,4,5,6,7,8,9};
348 * // Initialize the source buffer with 10 elements.
349 * srcBuf.Construct(10);
351 * // Copy the 10 values from pArray starting at position 0 to srcBuf
352 * // Now srcBuf's position = 10
353 * srcBuf.SetArray(pArray, 0, 10);
355 * // Flip the buffer: The limit is set to the current position
356 * // and then the position is set to zero
357 * srcBuf.Flip(); // srcBuf's position = 0 and limit = 10
360 * destBuf.Construct(20);
362 * // Copy from srcBuf to destBuf
363 * // Now srcBuf's position = 10, destBuf's position = 10
364 * destBuf.CopyFrom(srcBuf);
368 * The following example has exactly the same effect as the above %CopyFrom() method.
372 * int copyNum = srcBuf.GetRemaining();
373 * for (int i = 0; i < copyNum; i++)
377 * // Read from the source buffer
378 * srcBuf.Get(value); // srcBuf position is incremented by one.
380 * // Write to the destination buffer
381 * destBuf.Set(value); // destBuf position is incremented by one.
386 result CopyFrom(Buffer<Type>& buffer)
388 TryReturn(this != static_cast <void*>(&buffer), E_INVALID_ARG,
389 "[E_INVALID_ARG] The source and target buffers are identical.");
390 int copyLength = buffer.GetRemaining();
391 TryReturn(GetRemaining() >= copyLength, E_OVERFLOW, "[E_OVERFLOW]");
393 memcpy(__pArrayStart + _position * sizeof(Type), buffer.__pArrayStart + buffer._position * sizeof(Type),
394 copyLength * sizeof(Type));
396 _position += copyLength;
397 buffer._position += copyLength;
403 * Reads the value from the current position in the buffer, and then increments the position. @n
404 * Provides a way for relative indexing and reading.
408 * @return An error code
409 * @param[out] value The value at the current position
410 * @exception E_SUCCESS The method is successful.
411 * @exception E_UNDERFLOW The operation (arithmetic/casting/conversion) has caused an underflow. @n
412 * The current position is greater than the limit.
415 result Get(Type& value)
417 TryReturn(_position < _limit, E_UNDERFLOW, "[E_UNDERFLOW]");
419 value = ((Type*) __pArrayStart)[_position++];
424 * Reads the value at the given @c index. @n
425 * Provides a way for absolute indexing and reading.
429 * @return An error code
430 * @param[in] index The index into the buffer from where the value is read
431 * @param[out] value The value at the given index
432 * @exception E_SUCCESS The method is successful.
433 * @exception E_OUT_OF_RANGE The specified @c index is outside the bounds of the data structure. @n
434 * The @c index is greater than the limit or less than @c 0.
437 result Get(int index, Type& value) const
439 TryReturn(index < _limit && index >= 0, E_OUT_OF_RANGE,
440 "[E_OUT_OF_RANGE] The index(%d) MUST be greater than or equal to 0, and less then the current limit(%d).",
443 value = ((Type*) __pArrayStart)[index];
449 * Copies the specified range of values from the calling buffer to the specified destination array as per the given @c index of the array.
453 * @return An error code
454 * @param[out] pArray A pointer to the array into which values are written
455 * @param[in] index The starting index in the array of the first value to write
456 * @param[in] length The number of values from the buffer to write to the array
457 * @exception E_SUCCESS The method is successful.
458 * @exception E_INVALID_ARG A specified input parameter is invalid, or
459 * the @c pArray is @c null.
460 * @exception E_OUT_OF_RANGE The specified index is outside the bounds of the data structure, or
461 * the @c index or length is less than @c 0.
462 * @exception E_UNDERFLOW The operation (arithmetic/casting/conversion) has caused an underflow. @n
463 * The remaining elements of this buffer are smaller than @c length.
464 * @remarks After the copy operation, the position is incremented by @c length.
467 result GetArray(Type* pArray, int index, int length)
469 TryReturn(0 != pArray, E_INVALID_ARG, "[E_INVALID_ARG] The pArray is null.");
470 TryReturn(index >= 0 && length >= 0, E_OUT_OF_RANGE,
471 "[E_OUT_OF_RANGE] Both of index(%d) and length(%d) MUST be greater than or equal to 0.", index, length);
472 TryReturn(GetRemaining() >= length, E_UNDERFLOW, "[E_UNDERFLOW]");
474 memcpy(pArray + index, __pArrayStart + _position * sizeof(Type), length * sizeof(Type));
481 * Transfers bytes from the input buffer into the calling buffer. @n
482 * If the empty space in the calling buffer is larger than the remaining values from the input buffer,
483 * all the remaining elements from the input are copied to the destination. @n
484 * Otherwise, the number of bytes copied equals the number of elements remaining in the calling buffer.
488 * @return An error code
489 * @param[in] buffer The source buffer from where the bytes are read @n
490 * It must not be this buffer.
491 * @exception E_SUCCESS The method is successful.
492 * @exception E_INVALID_ARG The specified input parameter is invalid. @n
493 * The given buffer is same as the current buffer instance.
494 * @remarks After the copy operation, the current (destination) buffer's position and the given
495 * (source) buffer's position are incremented by the number of elements copied (the smaller value
496 * between the number of elements remaining in the calling buffer and the source buffer). @n
497 * If there are more elements remaining in the calling buffer than elements remaining in the input instance,
498 * this method is equivalent to CopyFrom() method. If there are less remaining elements in the
499 * calling buffer, the %CopyFrom() method returns @c E_OVERFLOW and does not transfer
500 * while this method copies the number of remaining elements of the current instance.
503 * The following example demonstrates how to use the %ReadFrom() method.
507 * // Create instances of IntBuffer to act as the source and destination buffers
511 * // Declare an array of integers
512 * int pArray[] = {0,1,2,3,4,5,6,7,8,9};
514 * // Initialize the source buffer with a capacity of 10 elements.
515 * srcBuf.Construct(10);
517 * // Copy the 10 values from pArray starting at position 0 to srcBuf
518 * // Now srcBuf's position = 10
519 * srcBuf.SetArray(pArray, 0, 10);
521 * // Flip the buffer: The limit is set to the current position
522 * // and then the position is set to zero
523 * srcBuf.Flip(); // srcBuf's position = 0 and limit = 10
526 * // Initialize the destination buffer with a capacity of 10 elements.
527 * destBuf.Construct(10);
529 * // Set the limit of destBuf to 5
530 * destBuf.SetLimit(5);
532 * // Read from srcBuf to destBuf
533 * // destBuf's remaining is 5, smaller than the srcBuf's (10).
534 * // Therefore, five elements are transferred.
535 * // srcBuf's position = 5, destBuf's position = 5
536 * destBuf.ReadFrom(srcBuf);
541 * The following example has exactly the same effect as the above %ReadFrom() method.
545 * int copyNum = (destBuf.GetRemaining() < srcBuf.GetRemaing())? destBuf.GetRemaining() : srcBuf.GetRemaining();
546 * for (int i = 0; i < copyNum; i++)
550 * // Read from source buffer
551 * srcBuf.Get(value); // srcBuf position is incremented by one.
553 * // Write to destination buffer
554 * destBuf.Set(value); // destBuf position is incremented by one.
559 result ReadFrom(Buffer<Type>& buffer)
561 TryReturn(this != static_cast <void*>(&buffer), E_INVALID_ARG,
562 "[E_INVALID_ARG] The source and target buffers are identical.");
564 int copyLength = (GetRemaining() < buffer.GetRemaining()) ? GetRemaining() : buffer.GetRemaining();
566 memcpy(__pArrayStart + _position * sizeof(Type), buffer.__pArrayStart + buffer._position * sizeof(Type),
567 copyLength * sizeof(Type));
569 _position += copyLength;
570 buffer._position += copyLength;
577 * Writes the specified @c value into the current buffer instance at the current position,
578 * and then increments the position. @n
579 * Provides a way for relative indexing and writing.
583 * @return An error code
584 * @param[in] value The value to write to the calling %Buffer
585 * @exception E_SUCCESS The method is successful.
586 * @exception E_OVERFLOW The operation (arithmetic/casting/conversion) has caused an overflow. @n
587 * The current position is not smaller than the limit.
590 result Set(Type value)
592 TryReturn(_position < _limit, E_OVERFLOW, "[E_OVERFLOW]");
594 ((Type*) __pArrayStart)[_position++] = value;
599 * Writes the specified @c value into the current instance of buffer at the given @c index. @n
600 * Provides a way for absolute indexing and writing.
604 * @return An error code
605 * @param[in] index The index at which the value is written
606 * @param[in] value The value to write
607 * @exception E_SUCCESS The method is successful.
608 * @exception E_OUT_OF_RANGE The specified index is outside the bounds of the data structure, or
609 * the @c index is not smaller than the limit or less than @c 0.
612 result Set(int index, Type value)
614 TryReturn(index < _limit && index >= 0, E_OUT_OF_RANGE,
615 "[E_OUT_OF_RANGE] The index(%d) MUST be greater than or equal to 0, and less then the current limit(%d).",
618 ((Type*) __pArrayStart)[index] = value;
623 * Copies values from the input source array into the calling buffer.
627 * @return An error code
628 * @param[in] pArray A pointer to the array from where the values are read
629 * @param[in] index The starting index of the array
630 * @param[in] length The number of values read from the given array
631 * @exception E_SUCCESS The method is successful.
632 * @exception E_INVALID_ARG A specified input parameter is invalid, or
633 * the @c pArray is @c null.
634 * @exception E_OUT_OF_RANGE The specified index is outside the bounds of the data structure, or
635 * the @c index or length is less than @c 0.
636 * @exception E_OVERFLOW The operation (arithmetic/casting/conversion) has caused an overflow. @n
637 * The remainder of this buffer is smaller than @c length.
638 * @remarks This method copies @c length number of values from the source array,
639 * starting from the given @c index in the array, into the calling
640 * buffer, starting at the current position.
641 * After the copy operation, the position is incremented by @c length.
644 result SetArray(const Type* pArray, int index, int length)
646 TryReturn(null != pArray, E_INVALID_ARG, "[E_INVALID_ARG] The pArray is null.");
647 TryReturn(index >= 0 && length >= 0, E_OUT_OF_RANGE,
648 "[E_OUT_OF_RANGE] Both of index(%d) and length(%d) MUST be greater than or equal to 0.", index, length);
649 TryReturn(GetRemaining() >= length, E_OVERFLOW, "[E_OVERFLOW]");
651 memcpy(__pArrayStart + _position * sizeof(Type), pArray + index, length * sizeof(Type));
658 * Creates a new %Buffer instance. @n
659 * Its content is a shared portion of
660 * the calling %Buffer instance that starts from the current position of calling %Buffer instance.
664 * @return A pointer to the new buffer
665 * @remarks The content of the new buffer starts at the current position of this instance of %Buffer.
666 * The new buffer's position is @c 0, its capacity and limit is
667 * the number of bytes remaining in the current instance of %Buffer,
668 * and it is marked as undefined.
670 Buffer <Type>* SliceN(void) const
672 Buffer <Type>* pBuffer = new Buffer <Type>();
673 pBuffer->_pData = _pData;
675 pBuffer->_capacity = GetRemaining();
676 pBuffer->_limit = pBuffer->_capacity;
677 if (pBuffer->_capacity > 0)
679 pBuffer->__pArrayStart = (byte*) &((Type*) __pArrayStart)[_position];
686 * Gets a raw array pointer to calling buffer.
690 * @return A raw array pointer to the buffer, @n
691 * else @c null if the capacity is @c 0
693 const Type* GetPointer(void) const
695 return (Type*) __pArrayStart;
699 * Compares the Object instance with the calling %Buffer instance for equivalence.
703 * @return @c true if the input equals the calling %Buffer instance, @n
705 * @param[in] obj The object to compare with the calling %Buffer
706 * @remarks This method returns @c true if and only if the specified object is also an instance of %Buffer class,
707 * the two buffers have the same number of remaining elements, and the two sequences of
708 * remaining elements are equal (considered independently of their starting positions).
709 * @see Tizen::Base::BufferBase::GetHashCode()
711 virtual bool Equals(const Tizen::Base::Object& obj) const
714 const Buffer <Type>* other = static_cast <const Buffer <Type>*>(&obj);
715 if ((other == this) || (*other == *this))
724 * Gets the hash value of the current instance.
728 * @return The hash value of the current instance
729 * @remarks The hash code of a buffer depends only upon its remaining elements.
731 virtual int GetHashCode(void) const
733 int len = (GetRemaining() * GetTypeSize()) / sizeof(int);
736 int offset = _position * GetTypeSize();
737 for (int i = 0; i < len; ++i)
739 hash = (hash<<5) - hash + (int) __pArrayStart[offset + (i * sizeof(int))];
747 * This is the copy constructor for this class.
749 Buffer(const Buffer <Type>& buffer)
755 * This is the assignment operator.
757 Buffer <Type>& operator =(const Buffer <Type>& buffer);
760 * Returns the size of the type of this buffer.
762 * @return The size of the buffer
764 virtual int GetTypeSize(void) const
769 friend class ByteBuffer;
775 * The @c double buffer type.
778 typedef Buffer <double> DoubleBuffer;
781 * The @c float buffer type.
784 typedef Buffer <float> FloatBuffer;
787 * The @c int buffer type.
790 typedef Buffer <int> IntBuffer;
793 * The @c long buffer type.
796 typedef Buffer <long> LongBuffer;
799 * The @c long @c long buffer type.
802 typedef Buffer <long long> LongLongBuffer;
805 * The @c wchar_t buffer type.
808 typedef Buffer <wchar_t> WcharBuffer;
811 * The @c short buffer type.
814 typedef Buffer <short> ShortBuffer;
818 template class _OSP_EXPORT_ Buffer <double>;
819 template class _OSP_EXPORT_ Buffer <float>;
820 template class _OSP_EXPORT_ Buffer <int>;
821 template class _OSP_EXPORT_ Buffer <long>;
822 template class _OSP_EXPORT_ Buffer <long long>;
823 template class _OSP_EXPORT_ Buffer <wchar_t>;
824 template class _OSP_EXPORT_ Buffer <short>;
829 #endif // _FBASE_BUFFER_H_