File diff r18781:e1de9a06f7cd → r18782:6453522c2154
src/misc/blob.hpp
Show inline comments
 
@@ -71,17 +71,17 @@ public:
 
	static const size_t header_size = sizeof(BlobHeader);
 

	
 
	/** default constructor - initializes empty blob */
 
	FORCEINLINE ByteBlob() { InitEmpty(); }
 
	inline ByteBlob() { InitEmpty(); }
 

	
 
	/** copy constructor */
 
	FORCEINLINE ByteBlob(const ByteBlob &src)
 
	inline ByteBlob(const ByteBlob &src)
 
	{
 
		InitEmpty();
 
		AppendRaw(src);
 
	}
 

	
 
	/** move constructor - take ownership of blob data */
 
	FORCEINLINE ByteBlob(BlobHeader * const & src)
 
	inline ByteBlob(BlobHeader * const & src)
 
	{
 
		assert(src != NULL);
 
		header = src;
 
@@ -89,14 +89,14 @@ public:
 
	}
 

	
 
	/** destructor */
 
	FORCEINLINE ~ByteBlob()
 
	inline ~ByteBlob()
 
	{
 
		Free();
 
	}
 

	
 
protected:
 
	/** all allocation should happen here */
 
	static FORCEINLINE BlobHeader *RawAlloc(size_t num_bytes)
 
	static inline BlobHeader *RawAlloc(size_t num_bytes)
 
	{
 
		return (BlobHeader*)MallocT<byte>(num_bytes);
 
	}
 
@@ -105,13 +105,13 @@ protected:
 
	 * Return header pointer to the static BlobHeader with
 
	 * both items and capacity containing zero
 
	 */
 
	static FORCEINLINE BlobHeader *Zero()
 
	static inline BlobHeader *Zero()
 
	{
 
		return const_cast<BlobHeader *>(&ByteBlob::hdrEmpty[1]);
 
	}
 

	
 
	/** simple allocation policy - can be optimized later */
 
	static FORCEINLINE size_t AllocPolicy(size_t min_alloc)
 
	static inline size_t AllocPolicy(size_t min_alloc)
 
	{
 
		if (min_alloc < (1 << 9)) {
 
			if (min_alloc < (1 << 5)) return (1 << 5);
 
@@ -130,7 +130,7 @@ protected:
 
	}
 

	
 
	/** all deallocations should happen here */
 
	static FORCEINLINE void RawFree(BlobHeader *p)
 
	static inline void RawFree(BlobHeader *p)
 
	{
 
		/* Just to silence an unsilencable GCC 4.4+ warning. */
 
		assert(p != ByteBlob::hdrEmpty);
 
@@ -140,74 +140,74 @@ protected:
 
	}
 

	
 
	/** initialize the empty blob */
 
	FORCEINLINE void InitEmpty()
 
	inline void InitEmpty()
 
	{
 
		header = Zero();
 
	}
 

	
 
	/** initialize blob by attaching it to the given header followed by data */
 
	FORCEINLINE void Init(BlobHeader *src)
 
	inline void Init(BlobHeader *src)
 
	{
 
		header = &src[1];
 
	}
 

	
 
	/** blob header accessor - use it rather than using the pointer arithmetics directly - non-const version */
 
	FORCEINLINE BlobHeader& Hdr()
 
	inline BlobHeader& Hdr()
 
	{
 
		return *(header - 1);
 
	}
 

	
 
	/** blob header accessor - use it rather than using the pointer arithmetics directly - const version */
 
	FORCEINLINE const BlobHeader& Hdr() const
 
	inline const BlobHeader& Hdr() const
 
	{
 
		return *(header - 1);
 
	}
 

	
 
	/** return reference to the actual blob size - used when the size needs to be modified */
 
	FORCEINLINE size_t& LengthRef()
 
	inline size_t& LengthRef()
 
	{
 
		return Hdr().items;
 
	}
 

	
 
public:
 
	/** return true if blob doesn't contain valid data */
 
	FORCEINLINE bool IsEmpty() const
 
	inline bool IsEmpty() const
 
	{
 
		return Length() == 0;
 
	}
 

	
 
	/** return the number of valid data bytes in the blob */
 
	FORCEINLINE size_t Length() const
 
	inline size_t Length() const
 
	{
 
		return Hdr().items;
 
	}
 

	
 
	/** return the current blob capacity in bytes */
 
	FORCEINLINE size_t Capacity() const
 
	inline size_t Capacity() const
 
	{
 
		return Hdr().capacity;
 
	}
 

	
 
	/** return pointer to the first byte of data - non-const version */
 
	FORCEINLINE byte *Begin()
 
	inline byte *Begin()
 
	{
 
		return data;
 
	}
 

	
 
	/** return pointer to the first byte of data - const version */
 
	FORCEINLINE const byte *Begin() const
 
	inline const byte *Begin() const
 
	{
 
		return data;
 
	}
 

	
 
	/** invalidate blob's data - doesn't free buffer */
 
	FORCEINLINE void Clear()
 
	inline void Clear()
 
	{
 
		LengthRef() = 0;
 
	}
 

	
 
	/** free the blob's memory */
 
	FORCEINLINE void Free()
 
	inline void Free()
 
	{
 
		if (Capacity() > 0) {
 
			RawFree(&Hdr());
 
@@ -216,7 +216,7 @@ public:
 
	}
 

	
 
	/** append new bytes at the end of existing data bytes - reallocates if necessary */
 
	FORCEINLINE void AppendRaw(const void *p, size_t num_bytes)
 
	inline void AppendRaw(const void *p, size_t num_bytes)
 
	{
 
		assert(p != NULL);
 
		if (num_bytes > 0) {
 
@@ -225,7 +225,7 @@ public:
 
	}
 

	
 
	/** append bytes from given source blob to the end of existing data bytes - reallocates if necessary */
 
	FORCEINLINE void AppendRaw(const ByteBlob& src)
 
	inline void AppendRaw(const ByteBlob& src)
 
	{
 
		if (!src.IsEmpty()) {
 
			memcpy(Append(src.Length()), src.Begin(), src.Length());
 
@@ -236,7 +236,7 @@ public:
 
	 * Reallocate if there is no free space for num_bytes bytes.
 
	 *  @return pointer to the new data to be added
 
	 */
 
	FORCEINLINE byte *Prepare(size_t num_bytes)
 
	inline byte *Prepare(size_t num_bytes)
 
	{
 
		size_t new_size = Length() + num_bytes;
 
		if (new_size > Capacity()) SmartAlloc(new_size);
 
@@ -247,7 +247,7 @@ public:
 
	 * Increase Length() by num_bytes.
 
	 *  @return pointer to the new data added
 
	 */
 
	FORCEINLINE byte *Append(size_t num_bytes)
 
	inline byte *Append(size_t num_bytes)
 
	{
 
		byte *pNewData = Prepare(num_bytes);
 
		LengthRef() += num_bytes;
 
@@ -281,7 +281,7 @@ public:
 
	}
 

	
 
	/** fixing the four bytes at the end of blob data - useful when blob is used to hold string */
 
	FORCEINLINE void FixTail() const
 
	inline void FixTail() const
 
	{
 
		if (Capacity() > 0) {
 
			byte *p = &data[Length()];
 
@@ -317,73 +317,73 @@ public:
 
	};
 

	
 
	/** Default constructor - makes new Blob ready to accept any data */
 
	FORCEINLINE CBlobT()
 
	inline CBlobT()
 
		: base()
 
	{}
 

	
 
	/** Take ownership constructor */
 
	FORCEINLINE CBlobT(const OnTransfer& ot)
 
	inline CBlobT(const OnTransfer& ot)
 
		: base(ot.header)
 
	{}
 

	
 
	/** Destructor - ensures that allocated memory (if any) is freed */
 
	FORCEINLINE ~CBlobT()
 
	inline ~CBlobT()
 
	{
 
		Free();
 
	}
 

	
 
	/** Check the validity of item index (only in debug mode) */
 
	FORCEINLINE void CheckIdx(size_t index) const
 
	inline void CheckIdx(size_t index) const
 
	{
 
		assert(index < Size());
 
	}
 

	
 
	/** Return pointer to the first data item - non-const version */
 
	FORCEINLINE T *Data()
 
	inline T *Data()
 
	{
 
		return (T*)base::Begin();
 
	}
 

	
 
	/** Return pointer to the first data item - const version */
 
	FORCEINLINE const T *Data() const
 
	inline const T *Data() const
 
	{
 
		return (const T*)base::Begin();
 
	}
 

	
 
	/** Return pointer to the index-th data item - non-const version */
 
	FORCEINLINE T *Data(size_t index)
 
	inline T *Data(size_t index)
 
	{
 
		CheckIdx(index);
 
		return (Data() + index);
 
	}
 

	
 
	/** Return pointer to the index-th data item - const version */
 
	FORCEINLINE const T *Data(size_t index) const
 
	inline const T *Data(size_t index) const
 
	{
 
		CheckIdx(index);
 
		return (Data() + index);
 
	}
 

	
 
	/** Return number of items in the Blob */
 
	FORCEINLINE size_t Size() const
 
	inline size_t Size() const
 
	{
 
		return (base::Length() / type_size);
 
	}
 

	
 
	/** Return total number of items that can fit in the Blob without buffer reallocation */
 
	FORCEINLINE size_t MaxSize() const
 
	inline size_t MaxSize() const
 
	{
 
		return (base::Capacity() / type_size);
 
	}
 

	
 
	/** Return number of additional items that can fit in the Blob without buffer reallocation */
 
	FORCEINLINE size_t GetReserve() const
 
	inline size_t GetReserve() const
 
	{
 
		return ((base::Capacity() - base::Length()) / type_size);
 
	}
 

	
 
	/** Grow number of data items in Blob by given number - doesn't construct items */
 
	FORCEINLINE T *GrowSizeNC(size_t num_items)
 
	inline T *GrowSizeNC(size_t num_items)
 
	{
 
		return (T*)base::Append(num_items * type_size);
 
	}
 
@@ -392,12 +392,12 @@ public:
 
	 * Ensures that given number of items can be added to the end of Blob. Returns pointer to the
 
	 *  first free (unused) item
 
	 */
 
	FORCEINLINE T *MakeFreeSpace(size_t num_items)
 
	inline T *MakeFreeSpace(size_t num_items)
 
	{
 
		return (T*)base::Prepare(num_items * type_size);
 
	}
 

	
 
	FORCEINLINE OnTransfer Transfer()
 
	inline OnTransfer Transfer()
 
	{
 
		return OnTransfer(*this);
 
	}