diff options
author | Charles Pigott <charlespigott@googlemail.com> | 2021-04-02 21:20:22 +0100 |
---|---|---|
committer | Charles Pigott <charlespigott@googlemail.com> | 2021-04-04 08:01:54 +0100 |
commit | e8a94dc8bbffbf3a48c9826531e116af5ff31396 (patch) | |
tree | e4548e16578fc4f5a0357d7773599ebe6522e851 /src/misc | |
parent | e8022a589d4f011cae4c3f449d91296ebcc3d947 (diff) | |
download | openttd-e8a94dc8bbffbf3a48c9826531e116af5ff31396.tar.xz |
Cleanup: Delete remaining Blob code
Diffstat (limited to 'src/misc')
-rw-r--r-- | src/misc/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/misc/blob.hpp | 421 | ||||
-rw-r--r-- | src/misc/dbg_helpers.cpp | 4 |
3 files changed, 0 insertions, 426 deletions
diff --git a/src/misc/CMakeLists.txt b/src/misc/CMakeLists.txt index 76780679f..ee2ca6a41 100644 --- a/src/misc/CMakeLists.txt +++ b/src/misc/CMakeLists.txt @@ -1,7 +1,6 @@ add_files( array.hpp binaryheap.hpp - blob.hpp countedobj.cpp countedptr.hpp dbg_helpers.cpp diff --git a/src/misc/blob.hpp b/src/misc/blob.hpp deleted file mode 100644 index 7784b6af6..000000000 --- a/src/misc/blob.hpp +++ /dev/null @@ -1,421 +0,0 @@ -/* - * This file is part of OpenTTD. - * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. - * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>. - */ - -/** @file blob.hpp Support for storing random binary data. */ - -#ifndef BLOB_HPP -#define BLOB_HPP - -#include "../core/alloc_func.hpp" - -/** - * Base class for simple binary blobs. - * Item is byte. - * The word 'simple' means: - * - no configurable allocator type (always made from heap) - * - no smart deallocation - deallocation must be called from the same - * module (DLL) where the blob was allocated - * - no configurable allocation policy (how big blocks should be allocated) - * - no extra ownership policy (i.e. 'copy on write') when blob is copied - * - no thread synchronization at all - * - * Internal member layout: - * 1. The only class member is pointer to the first item (see union). - * 2. Allocated block contains the blob header (see BlobHeader) followed by the raw byte data. - * Always, when it allocates memory the allocated size is: - * sizeof(BlobHeader) + <data capacity> - * 3. Two 'virtual' members (items and capacity) are stored in the BlobHeader at beginning - * of the allocated block. - * 4. The pointer of the union pobsize_ts behind the header (to the first data byte). - * When memory block is allocated, the sizeof(BlobHeader) it added to it. - * 5. Benefits of this layout: - * - items are accessed in the simplest possible way - just dereferencing the pointer, - * which is good for performance (assuming that data are accessed most often). - * - sizeof(blob) is the same as the size of any other pointer - * 6. Drawbacks of this layout: - * - the fact that a pointer to the allocated block is adjusted by sizeof(BlobHeader) before - * it is stored can lead to several confusions: - * - it is not a common pattern so the implementation code is bit harder to read. - * - valgrind may generate a warning that the allocated block is lost (not accessible). - */ -class ByteBlob { -protected: - /** header of the allocated memory block */ - struct BlobHeader { - size_t items; ///< actual blob size in bytes - size_t capacity; ///< maximum (allocated) size in bytes - }; - - /** type used as class member */ - union { - byte *data; ///< ptr to the first byte of data - BlobHeader *header; ///< ptr just after the BlobHeader holding items and capacity - }; - -private: - /** - * Just to silence an unsilencable GCC 4.4+ warning - * Note: This cannot be 'const' as we do a lot of 'hdrEmpty[0]->items += 0;' and 'hdrEmpty[0]->capacity += 0;' - * after const_casting. - */ - static BlobHeader hdrEmpty[]; - -public: - static const size_t tail_reserve = 4; ///< four extra bytes will be always allocated and zeroed at the end - static const size_t header_size = sizeof(BlobHeader); - - /** default constructor - initializes empty blob */ - inline ByteBlob() - { - InitEmpty(); - } - - /** copy constructor */ - inline ByteBlob(const ByteBlob &src) - { - InitEmpty(); - AppendRaw(src); - } - - /** move constructor - take ownership of blob data */ - inline ByteBlob(BlobHeader * const & src) - { - assert(src != nullptr); - header = src; - *const_cast<BlobHeader**>(&src) = nullptr; - } - - /** destructor */ - inline ~ByteBlob() - { - Free(); - } - -protected: - /** all allocation should happen here */ - static inline BlobHeader *RawAlloc(size_t num_bytes) - { - return (BlobHeader*)MallocT<byte>(num_bytes); - } - - /** - * Return header pointer to the static BlobHeader with - * both items and capacity containing zero - */ - static inline BlobHeader *Zero() - { - return const_cast<BlobHeader *>(&ByteBlob::hdrEmpty[1]); - } - - /** simple allocation policy - can be optimized later */ - static inline size_t AllocPolicy(size_t min_alloc) - { - if (min_alloc < (1 << 9)) { - if (min_alloc < (1 << 5)) return (1 << 5); - return (min_alloc < (1 << 7)) ? (1 << 7) : (1 << 9); - } - if (min_alloc < (1 << 15)) { - if (min_alloc < (1 << 11)) return (1 << 11); - return (min_alloc < (1 << 13)) ? (1 << 13) : (1 << 15); - } - if (min_alloc < (1 << 20)) { - if (min_alloc < (1 << 17)) return (1 << 17); - return (min_alloc < (1 << 19)) ? (1 << 19) : (1 << 20); - } - min_alloc = (min_alloc | ((1 << 20) - 1)) + 1; - return min_alloc; - } - - /** all deallocations should happen here */ - static inline void RawFree(BlobHeader *p) - { - /* Just to silence an unsilencable GCC 4.4+ warning. */ - assert(p != ByteBlob::hdrEmpty); - - /* In case GCC warns about the following, see GCC's PR38509 why it is bogus. */ - free(p); - } - - /** initialize the empty blob */ - inline void InitEmpty() - { - header = Zero(); - } - - /** initialize blob by attaching it to the given header followed by data */ - inline void Init(BlobHeader *src) - { - header = &src[1]; - } - - /** blob header accessor - use it rather than using the pointer arithmetic directly - non-const version */ - inline BlobHeader& Hdr() - { - return *(header - 1); - } - - /** blob header accessor - use it rather than using the pointer arithmetic directly - const version */ - inline const BlobHeader& Hdr() const - { - return *(header - 1); - } - - /** return reference to the actual blob size - used when the size needs to be modified */ - inline size_t& LengthRef() - { - return Hdr().items; - } - -public: - /** return true if blob doesn't contain valid data */ - inline bool IsEmpty() const - { - return Length() == 0; - } - - /** return the number of valid data bytes in the blob */ - inline size_t Length() const - { - return Hdr().items; - } - - /** return the current blob capacity in bytes */ - inline size_t Capacity() const - { - return Hdr().capacity; - } - - /** return pointer to the first byte of data - non-const version */ - inline byte *Begin() - { - return data; - } - - /** return pointer to the first byte of data - const version */ - inline const byte *Begin() const - { - return data; - } - - /** invalidate blob's data - doesn't free buffer */ - inline void Clear() - { - LengthRef() = 0; - } - - /** free the blob's memory */ - inline void Free() - { - if (Capacity() > 0) { - RawFree(&Hdr()); - InitEmpty(); - } - } - - /** append new bytes at the end of existing data bytes - reallocates if necessary */ - inline void AppendRaw(const void *p, size_t num_bytes) - { - assert(p != nullptr); - if (num_bytes > 0) { - memcpy(Append(num_bytes), p, num_bytes); - } - } - - /** append bytes from given source blob to the end of existing data bytes - reallocates if necessary */ - inline void AppendRaw(const ByteBlob& src) - { - if (!src.IsEmpty()) { - memcpy(Append(src.Length()), src.Begin(), src.Length()); - } - } - - /** - * Reallocate if there is no free space for num_bytes bytes. - * @return pointer to the new data to be added - */ - inline byte *Prepare(size_t num_bytes) - { - size_t new_size = Length() + num_bytes; - if (new_size > Capacity()) SmartAlloc(new_size); - return data + Length(); - } - - /** - * Increase Length() by num_bytes. - * @return pointer to the new data added - */ - inline byte *Append(size_t num_bytes) - { - byte *pNewData = Prepare(num_bytes); - LengthRef() += num_bytes; - return pNewData; - } - - /** reallocate blob data if needed */ - void SmartAlloc(size_t new_size) - { - if (Capacity() >= new_size) return; - /* calculate minimum block size we need to allocate - * and ask allocation policy for some reasonable block size */ - assert(new_size < SIZE_MAX - header_size - tail_reserve); - new_size = AllocPolicy(header_size + new_size + tail_reserve); - - /* allocate new block and setup header */ - BlobHeader *tmp = RawAlloc(new_size); - tmp->items = Length(); - tmp->capacity = new_size - (header_size + tail_reserve); - - /* copy existing data */ - if (tmp->items != 0) { - memcpy(tmp + 1, data, tmp->items); - } - - /* replace our block with new one */ - if (Capacity() > 0) { - RawFree(&Hdr()); - } - Init(tmp); - } - - /** fixing the four bytes at the end of blob data - useful when blob is used to hold string */ - inline void FixTail() const - { - if (Capacity() > 0) { - byte *p = &data[Length()]; - for (uint i = 0; i < tail_reserve; i++) { - p[i] = 0; - } - } - } -}; - -/** - * Blob - simple dynamic T array. T (template argument) is a placeholder for any type. - * T can be any integral type, pointer, or structure. Using Blob instead of just plain C array - * simplifies the resource management in several ways: - * 1. When adding new item(s) it automatically grows capacity if needed. - * 2. When variable of type Blob comes out of scope it automatically frees the data buffer. - * 3. Takes care about the actual data size (number of used items). - * 4. Dynamically constructs only used items (as opposite of static array which constructs all items) - */ -template <typename T> -class CBlobT : public ByteBlob { - /* make template arguments public: */ -public: - typedef ByteBlob base; - - static const size_t type_size = sizeof(T); - - struct OnTransfer { - typename base::BlobHeader *header; - - OnTransfer(const OnTransfer& src) : header(src.header) - { - assert(src.header != nullptr); - *const_cast<typename base::BlobHeader**>(&src.header) = nullptr; - } - - OnTransfer(CBlobT& src) : header(src.header) - { - src.InitEmpty(); - } - - ~OnTransfer() - { - assert(header == nullptr); - } - }; - - /** Default constructor - makes new Blob ready to accept any data */ - inline CBlobT() - : base() - {} - - /** Take ownership constructor */ - inline CBlobT(const OnTransfer& ot) - : base(ot.header) - {} - - /** Destructor - ensures that allocated memory (if any) is freed */ - inline ~CBlobT() - { - Free(); - } - - /** Check the validity of item index (only in debug mode) */ - inline void CheckIdx(size_t index) const - { - assert(index < Size()); - } - - /** Return pointer to the first data item - non-const version */ - inline T *Data() - { - return (T*)base::Begin(); - } - - /** Return pointer to the first data item - const version */ - inline const T *Data() const - { - return (const T*)base::Begin(); - } - - /** Return pointer to the index-th data item - non-const version */ - inline T *Data(size_t index) - { - CheckIdx(index); - return (Data() + index); - } - - /** Return pointer to the index-th data item - const version */ - inline const T *Data(size_t index) const - { - CheckIdx(index); - return (Data() + index); - } - - /** Return number of items in the Blob */ - inline size_t Size() const - { - return (base::Length() / type_size); - } - - /** Return total number of items that can fit in the Blob without buffer reallocation */ - inline size_t MaxSize() const - { - return (base::Capacity() / type_size); - } - - /** Return number of additional items that can fit in the Blob without buffer reallocation */ - 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 */ - inline T *GrowSizeNC(size_t num_items) - { - return (T*)base::Append(num_items * type_size); - } - - /** - * Ensures that given number of items can be added to the end of Blob. Returns pointer to the - * first free (unused) item - */ - inline T *MakeFreeSpace(size_t num_items) - { - return (T*)base::Prepare(num_items * type_size); - } - - inline OnTransfer Transfer() - { - return OnTransfer(*this); - } -}; - - -#endif /* BLOB_HPP */ diff --git a/src/misc/dbg_helpers.cpp b/src/misc/dbg_helpers.cpp index 85d6ea1b9..b197e9a8a 100644 --- a/src/misc/dbg_helpers.cpp +++ b/src/misc/dbg_helpers.cpp @@ -10,7 +10,6 @@ #include "../stdafx.h" #include "../rail_map.h" #include "dbg_helpers.h" -#include "blob.hpp" #include <sstream> #include <iomanip> @@ -169,6 +168,3 @@ void DumpTarget::EndStruct() /* remove current struct name from the stack */ m_cur_struct.pop(); } - -/** Just to silence an unsilencable GCC 4.4+ warning */ -/* static */ ByteBlob::BlobHeader ByteBlob::hdrEmpty[] = {{0, 0}, {0, 0}}; |