2 // Open Service Platform
3 // Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 // Licensed under the Apache License, Version 2.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
20 * @brief This is the header file for the %Buffer class.
22 * This header file contains the declarations of the %Buffer classes.
25 #ifndef _FBASE_BUFFER_H_
26 #define _FBASE_BUFFER_H_
29 #include <FBaseBufferBase.h>
30 #include <FBaseResult.h>
33 namespace Tizen { namespace Base
36 // Forward declaration
41 * @brief This class represents a linear finite sequence of elements of the same type.
45 * The %Buffer class represents a linear finite sequence of elements of the same type.
46 * It is a means of defining an aggregation of the same type of objects, similar to an array.
48 * For more information on the class features, see <a href="../org.tizen.native.appprogramming/html/guide/base/buffer.htm">Buffer</a>.
50 * @see Tizen::Base::BufferBase
52 * The following example demonstrates how to use the %Buffer class.
58 * using namespace Tizen::Base;
61 * MyClass::BufferSample(void)
63 * // Sets the buffer capacity to 1024
64 * const int BUFFER_SIZE_MAX = 1024;
66 * // Initializes intBuf with capacity
68 * intBuf.Construct(BUFFER_SIZE_MAX);
70 * int intArray[] = {0,1,2,3,4,5,6,7,8,9};
72 * // Copies all values from intArray to intBuffer instance
73 * // position = 10 (num of element copied)
74 * intBuf.SetArray(intArray, 0, (sizeof(intArray) / sizeof(int)));
76 * // Flips the buffer: The limit is set to the current position and
77 * // then the position is set to zero
78 * intBuf.Flip(); // position = 0, limit = 10
80 * // Gets the number of elements between the current position and the limit
81 * int remaining = intBuf.GetRemaining();
83 * // Initializes a doubleBuf with capacity(10) using Construct() method
84 * DoubleBuffer doubleBuf;
85 * doubleBuf.Construct(remaining);
87 * // Reads and writes elements from the intBuf to the doubleBuf
88 * for (int i = 0; i < remaining; i++)
92 * // Demonstrates relative reading and writing
94 * // Reads the value at the current position, and then increments the position
97 * // Writes the value * 12.34 at the current position of the doubleBuf
98 * // and then increment the position
99 * doubleBuf.Set(value * 12.34);
101 * // Now, positions of the intBuf and the doubleBuf have been incremented by one
104 * // Flips the doubleBuf
106 * // Now, the doubleBuf's position = 0 and limit = 10
108 * // Gets the remaining elements of the doubleBuf
109 * remaining = doubleBuf.GetRemaining();
111 * // Gets the second double value with index
112 * double doubleValue;
113 * doubleBuf.Get(1, doubleValue); // 12.34
119 class _OSP_EXPORT_ Buffer
125 * This is the default constructor for this class.
129 * @remarks After creating an instance of the %Buffer class, one of the Construct() methods must be called explicitly to initialize this instance.
139 * This is the destructor for this class.
143 virtual ~Buffer(void)
150 * Initializes this instance of %Buffer which is a view of the specified buffer. @n
151 * This is similar to a copy constructor.
155 * @param[in] buffer The other %Buffer instance
156 * @exception E_SUCCESS The method is successful.
157 * @exception E_INVALID_ARG The specified input parameter is invalid, or
158 * the source buffer is not constructed.
161 result Construct(const Buffer <Type>& buffer)
163 TryReturn(null != buffer._pData, E_INVALID_ARG, ("[E_INVALID_ARG] The source buffer is not constructed."));
165 _capacity = buffer._capacity;
166 _position = buffer._position;
167 _limit = buffer._limit;
168 _mark = buffer._mark;
169 _pData = buffer._pData;
172 __pArrayStart = buffer.__pArrayStart;
178 * Initializes this instance of %Buffer with the specified capacity.
182 * @return An error code
183 * @param[in] capacity The number of elements
184 * @exception E_SUCCESS The method is successful.
185 * @exception E_INVALID_ARG The specified @c capacity is negative.
188 result Construct(int capacity)
190 return BufferBase::Construct(capacity);
194 * Initializes this instance of %Buffer with the specified @c buffer which is shared with this instance.
198 * @return An error code
199 * @param[in] pBuffer The buffer which is shared
200 * @param[in] index The starting index of the buffer from where the first @c byte value is read
201 * @param[in] length The number of bytes to read from the given buffer @n This is a limit of this instance.
202 * @param[in] capacity The capacity of this instance
203 * @exception E_SUCCESS The method is successful.
204 * @exception E_INVALID_ARG A specified input parameter is invalid, or
205 * the @c pBuffer is @c null.
206 * @exception E_OUT_OF_RANGE The specified index is outside the bounds of the data structure, or
207 * the @c index is larger than the @c length.
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 * This subscript operator returns the reference to the element indicated by the given 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 * Overloaded equality operator to compare two %Buffer instances.
262 * @return @c true if the buffers being compared 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 two sequences of remaining elements are equal (considered independently 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 the two %Buffer instances are not equal.
298 * @return @c true if the buffers 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 being compared have the same @n
302 * number of remaining elements and the two sequences of remaining elements are equal @n
303 * (considered independently of their starting positions).
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 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 The specified input parameter is invalid, or
324 * the source buffer is same as destination buffer,
325 * that is, the current instance of %Buffer.
326 * @exception E_OVERFLOW The operation (arithmetic/casting/conversion) has caused an overflow. @n
327 * The number of remaining bytes of the current buffer is less than
328 * the number of remaining bytes of the given buffer.
329 * @remarks After the copy operation, the current (destination) buffer's position and the given
330 * (source) buffer's position are incremented by the number of elements copied (the number
331 * of remaining elements of the given buffer). @n
332 * If the remaining part of the current instance is not less than the remaining part of the input instance,
333 * the effect of this method and the ReadFrom() method is the same. But when the remaining part of the
334 * current instance is less, ReadFrom() method copies the number of remaining elements of the current
335 * instance while this method returns E_OVERFLOW and does not transfer.
338 * The following example demonstrates how to use the %CopyFrom() method.
342 * // Create instances of IntBuffer to act as source and destination buffers
346 * // Declare an array of integers
347 * int pArray[] = {0,1,2,3,4,5,6,7,8,9};
349 * // Initialize the source buffer with 10 elements.
350 * srcBuf.Construct(10);
352 * // Copy the 10 values from pArray starting at position 0 to srcBuf
353 * // Now srcBuf's position = 10
354 * srcBuf.SetArray(pArray, 0, 10);
356 * // Flip the buffer: The limit is set to the current position
357 * // and then the position is set to zero
358 * srcBuf.Flip(); // srcBuf's position = 0 and limit = 10
361 * destBuf.Construct(20);
363 * // Copy from srcBuf to destBuf
364 * // Now srcBuf's position = 10, destBuf's position = 10
365 * destBuf.CopyFrom(srcBuf);
369 * The following example has exactly the same effect as the above %CopyFrom() method.
373 * int copyNum = srcBuf.GetRemaining();
374 * for (int i = 0; i < copyNum; i++)
378 * // Read from the source buffer
379 * srcBuf.Get(value); // srcBuf position is incremented by one.
381 * // Write to the destination buffer
382 * destBuf.Set(value); // destBuf position is incremented by one.
387 result CopyFrom(Buffer<Type>& buffer)
389 TryReturn(this != static_cast <void*>(&buffer), E_INVALID_ARG,
390 "[E_INVALID_ARG] The source and target buffers are identical.");
391 int copyLength = buffer.GetRemaining();
392 TryReturn(GetRemaining() >= copyLength, E_OVERFLOW, "[E_OVERFLOW]");
394 memcpy(__pArrayStart + _position * sizeof(Type), buffer.__pArrayStart + buffer._position * sizeof(Type),
395 copyLength * sizeof(Type));
397 _position += copyLength;
398 buffer._position += copyLength;
404 * Reads the value from the current position in the buffer, and then increments the position. @n
405 * Provides a way for relative indexing and reading.
409 * @return An error code
410 * @param[out] value The value at the current position
411 * @exception E_SUCCESS The method is successful.
412 * @exception E_UNDERFLOW The operation (arithmetic/casting/conversion) has caused an underflow. @n
413 * The current position is greater than the limit.
416 result Get(Type& value)
418 TryReturn(_position < _limit, E_UNDERFLOW, "[E_UNDERFLOW]");
420 value = ((Type*) __pArrayStart)[_position++];
425 * Reads the value at the given index. @n
426 * Provides a way for absolute indexing and reading.
430 * @return An error code
431 * @param[in] index The index into the buffer from where the value is read
432 * @param[out] value The value at the given index
433 * @exception E_SUCCESS The method is successful.
434 * @exception E_OUT_OF_RANGE The specified @c index is outside the bounds of the data structure. @n
435 * The @c index is greater than the limit or less than @c 0.
438 result Get(int index, Type& value) const
440 TryReturn(index < _limit && index >= 0, E_OUT_OF_RANGE,
441 "[E_OUT_OF_RANGE] The index(%d) MUST be greater than or equal to 0, and less then the current limit(%d).",
444 value = ((Type*) __pArrayStart)[index];
450 * Copies the specified range of values from the calling buffer to the specified destination array as per the given index of the array.
454 * @return An error code
455 * @param[out] pArray A pointer to the array into which values are written
456 * @param[in] index The starting index in the array of the first value to write
457 * @param[in] length The number of values from the buffer to write to the array
458 * @exception E_SUCCESS The method is successful.
459 * @exception E_INVALID_ARG A specified input parameter is invalid, or
460 * the @c pArray is @c null.
461 * @exception E_OUT_OF_RANGE The specified index is outside the bounds of the data structure, or
462 * the @c index or length is less than @c 0.
463 * @exception E_UNDERFLOW The operation (arithmetic/casting/conversion) has caused an underflow. @n
464 * The remaining elements of this buffer are smaller than @c length.
465 * @remarks After the copy operation, the position is incremented by @c length.
468 result GetArray(Type* pArray, int index, int length)
470 TryReturn(0 != pArray, E_INVALID_ARG, "[E_INVALID_ARG] The pArray is null.");
471 TryReturn(index >= 0 && length >= 0, E_OUT_OF_RANGE,
472 "[E_OUT_OF_RANGE] Both of index(%d) and length(%d) MUST be greater than or equal to 0.", index, length);
473 TryReturn(GetRemaining() >= length, E_UNDERFLOW, "[E_UNDERFLOW]");
475 memcpy(pArray + index, __pArrayStart + _position * sizeof(Type), length * sizeof(Type));
482 * Transfers bytes from the input buffer into the calling buffer. @n
483 * If the empty space in the calling buffer is larger than the remaining values from the input buffer,
484 * all the remaining elements from the input are copied to the destination. @n
485 * Otherwise, the number of bytes copied equals the number of elements remaining in the calling buffer.
489 * @return An error code
490 * @param[in] buffer The source buffer from which bytes are read @n
491 * It must not be this buffer.
492 * @exception E_SUCCESS The method is successful.
493 * @exception E_INVALID_ARG The specified input parameter is invalid. @n
494 * The given buffer is same as the current buffer instance.
495 * @remarks After the copy operation, the current (destination) buffer's position and the given
496 * (source) buffer's position are incremented by the number of elements copied (the smaller value
497 * between the number of elements remaining in the calling buffer and the source buffer). @n
498 * If there are more elements remaining in the calling buffer than elements remaining in the input instance,
499 * this method is equivalent to CopyFrom() method. If there are less remaining elements in the
500 * calling buffer, the CopyFrom() method returns E_OVERFLOW and does not transfer
501 * while this method copies the number of remaining elements of the current instance.
504 * The following example demonstrates how to use the %ReadFrom() method.
508 * // Create instances of IntBuffer to act as the source and destination buffers
512 * // Declare an array of integers
513 * int pArray[] = {0,1,2,3,4,5,6,7,8,9};
515 * // Initialize the source buffer with a capacity of 10 elements.
516 * srcBuf.Construct(10);
518 * // Copy the 10 values from pArray starting at position 0 to srcBuf
519 * // Now srcBuf's position = 10
520 * srcBuf.SetArray(pArray, 0, 10);
522 * // Flip the buffer: The limit is set to the current position
523 * // and then the position is set to zero
524 * srcBuf.Flip(); // srcBuf's position = 0 and limit = 10
527 * // Initialize the destination buffer with a capacity of 10 elements.
528 * destBuf.Construct(10);
530 * // Set the limit of destBuf to 5
531 * destBuf.SetLimit(5);
533 * // Read from srcBuf to destBuf
534 * // destBuf's remaining is 5, smaller than the srcBuf's (10).
535 * // Therefore, five elements are transferred.
536 * // srcBuf's position = 5, destBuf's position = 5
537 * destBuf.ReadFrom(srcBuf);
542 * The following example has exactly the same effect as the above %ReadFrom() method.
546 * int copyNum = (destBuf.GetRemaining() < srcBuf.GetRemaing())? destBuf.GetRemaining() : srcBuf.GetRemaining();
547 * for (int i = 0; i < copyNum; i++)
551 * // Read from source buffer
552 * srcBuf.Get(value); // srcBuf position is incremented by one.
554 * // Write to destination buffer
555 * destBuf.Set(value); // destBuf position is incremented by one.
560 result ReadFrom(Buffer<Type>& buffer)
562 TryReturn(this != static_cast <void*>(&buffer), E_INVALID_ARG,
563 "[E_INVALID_ARG] The source and target buffers are identical.");
565 int copyLength = (GetRemaining() < buffer.GetRemaining()) ? GetRemaining() : buffer.GetRemaining();
567 memcpy(__pArrayStart + _position * sizeof(Type), buffer.__pArrayStart + buffer._position * sizeof(Type),
568 copyLength * sizeof(Type));
570 _position += copyLength;
571 buffer._position += copyLength;
578 * Writes the specified value into the current buffer instance at the current position,
579 * and then increments the position. @n
580 * Provides a way for relative indexing and writing.
584 * @return An error code
585 * @param[in] value The value to write to the calling %Buffer
586 * @exception E_SUCCESS The method is successful.
587 * @exception E_OVERFLOW The operation (arithmetic/casting/conversion) has caused an overflow. @n
588 * The current position is not smaller than the limit.
591 result Set(Type value)
593 TryReturn(_position < _limit, E_OVERFLOW, "[E_OVERFLOW]");
595 ((Type*) __pArrayStart)[_position++] = value;
600 * Writes the specified value into the current instance of buffer at the given index. @n
601 * Provides a way for absolute indexing and writing.
605 * @return An error code
606 * @param[in] index The index at which the value is written
607 * @param[in] value The value to write
608 * @exception E_SUCCESS The method is successful.
609 * @exception E_OUT_OF_RANGE The specified index is outside the bounds of the data structure, or
610 * the @c index is not smaller than the limit or less than @c 0.
613 result Set(int index, Type value)
615 TryReturn(index < _limit && index >= 0, E_OUT_OF_RANGE,
616 "[E_OUT_OF_RANGE] The index(%d) MUST be greater than or equal to 0, and less then the current limit(%d).",
619 ((Type*) __pArrayStart)[index] = value;
624 * Copies values from the input source array into the calling buffer.
628 * @return An error code
629 * @param[in] pArray A pointer to the array from which values are read
630 * @param[in] index The starting index of the array
631 * @param[in] length The number of values read from the given array
632 * @exception E_SUCCESS The method is successful.
633 * @exception E_INVALID_ARG A specified input parameter is invalid, or
634 * the @c pArray is @c null.
635 * @exception E_OUT_OF_RANGE The specified index is outside the bounds of the data structure, or
636 * the @c index or length is less than @c 0.
637 * @exception E_OVERFLOW The operation (arithmetic/casting/conversion) has caused an overflow. @n
638 * The remainder of this buffer is smaller than @c length.
639 * @remarks This method copies @c length number of values from the source array,
640 * starting from the given index in the array, into the calling
641 * buffer, starting at the current position.
642 * After the copy operation, the position is incremented by @c length.
645 result SetArray(const Type* pArray, int index, int length)
647 TryReturn(null != pArray, E_INVALID_ARG, "[E_INVALID_ARG] The pArray is null.");
648 TryReturn(index >= 0 && length >= 0, E_OUT_OF_RANGE,
649 "[E_OUT_OF_RANGE] Both of index(%d) and length(%d) MUST be greater than or equal to 0.", index, length);
650 TryReturn(GetRemaining() >= length, E_OVERFLOW, "[E_OVERFLOW]");
652 memcpy(__pArrayStart + _position * sizeof(Type), pArray + index, length * sizeof(Type));
659 * Creates a new %Buffer instance. @n
660 * Its content is a shared portion of
661 * the calling %Buffer instance that starts from the current position of calling %Buffer instance.
665 * @return A pointer to the new buffer
666 * @remarks The content of the new buffer starts at the current position of this instance of %Buffer.
667 * The new buffer's position is @c 0, its capacity and limit is
668 * the number of bytes remaining in the current instance of %Buffer,
669 * and it is marked as undefined.
671 Buffer <Type>* SliceN(void) const
673 Buffer <Type>* pBuffer = new Buffer <Type>();
674 pBuffer->_pData = _pData;
676 pBuffer->_capacity = GetRemaining();
677 pBuffer->_limit = pBuffer->_capacity;
678 if (pBuffer->_capacity > 0)
680 pBuffer->__pArrayStart = (byte*) &((Type*) __pArrayStart)[_position];
687 * Gets a raw array pointer to calling buffer.
691 * @return A raw array pointer to the buffer, @n
692 * else @c null if the capacity is @c 0
694 const Type* GetPointer(void) const
696 return (Type*) __pArrayStart;
700 * Compares the Object instance with the calling %Buffer instance for equivalence.
704 * @return @c true if the input equals the calling %Buffer instance, @n
706 * @param[in] obj The object to compare with the calling %Buffer
707 * @remarks This method returns @c true if and only if the specified object is also an instance of %Buffer class,
708 * the two buffers have the same number of remaining elements, and the two sequences of
709 * remaining elements are equal (considered independently of their starting positions).
710 * @see Tizen::Base::BufferBase::GetHashCode()
712 virtual bool Equals(const Tizen::Base::Object& obj) const
715 const Buffer <Type>* other = static_cast <const Buffer <Type>*>(&obj);
716 if ((other == this) || (*other == *this))
725 * Gets the hash value of the current instance.
729 * @return The hash value of the current instance
730 * @remarks The hash code of a buffer depends only upon its remaining elements.
732 virtual int GetHashCode(void) const
734 int len = (GetRemaining() * GetTypeSize()) / sizeof(int);
737 int offset = _position * GetTypeSize();
738 for (int i = 0; i < len; ++i)
740 hash = (hash<<5) - hash + (int) __pArrayStart[offset + (i * sizeof(int))];
748 * This is the copy constructor for this class.
750 Buffer(const Buffer <Type>& buffer)
756 * This is the assignment operator.
758 Buffer <Type>& operator =(const Buffer <Type>& buffer);
761 * Returns the size of the type of this buffer.
763 * @return The size of the buffer
765 virtual int GetTypeSize(void) const
770 friend class ByteBuffer;
776 * The @c double buffer type.
779 typedef Buffer <double> DoubleBuffer;
782 * The @c float buffer type.
785 typedef Buffer <float> FloatBuffer;
788 * The @c int buffer type.
791 typedef Buffer <int> IntBuffer;
794 * The @c long buffer type.
797 typedef Buffer <long> LongBuffer;
800 * The @c long @c long buffer type.
803 typedef Buffer <long long> LongLongBuffer;
806 * The @c wchar_t buffer type.
809 typedef Buffer <wchar_t> WcharBuffer;
812 * The @c short buffer type.
815 typedef Buffer <short> ShortBuffer;
819 template class _OSP_EXPORT_ Buffer <double>;
820 template class _OSP_EXPORT_ Buffer <float>;
821 template class _OSP_EXPORT_ Buffer <int>;
822 template class _OSP_EXPORT_ Buffer <long>;
823 template class _OSP_EXPORT_ Buffer <long long>;
824 template class _OSP_EXPORT_ Buffer <wchar_t>;
825 template class _OSP_EXPORT_ Buffer <short>;
830 #endif // _FBASE_BUFFER_H_