/*! * Change the size of the buffer, retaining it's current content. If the new size is * smaller than the previous size, trailing bytes in the buffer are lost. If the new * size is greater than the previous size, the \a fill parameter tells whether the new * buffer space is left unspecified or is zero-filled. * * @param[in] newSize The new buffer size (bytes). * @param[in] fill Tells what to do with the new buffer space if \a newSize is * greater than the existing buffer size. */ void Resize(size_t newSize, FILL fill = FILL_UNSPECIFIED) { if (newSize <= _size) { if (!newSize) { DetachBuf(); _sbuf = 0; _start = 0; _size = 0; return; } _size = newSize; } else { // If we grow, we must re-allocate the input buffer, so we may as well copy // any "lazy" buffer too. Note that we do NOT want to share the copied buffer // with any other DATA because doing so would invalidate any GetBuf() pointers // in the other DATA. Therefore, any other DATA's continue to use the old buffer. // SHARED_BUF *sbuf = new SHARED_BUF(newSize); std::memcpy(sbuf->_buf, _start, _size); if (fill == FILL_ZERO) std::memset(static_cast<FUND::UINT8 *>(sbuf->_buf) + _size, 0, newSize - _size); DetachBuf(); _sbuf = sbuf; _start = sbuf->_buf; _size = newSize; } }
/*! * Reconstruct the buffer to a new size. The contents of the buffer are unspecified. * * @param[in] size Size (bytes) of the buffer. */ void Assign(size_t size) { DetachBuf(); _sbuf = new SHARED_BUF(size); _start = _sbuf->_buf; _size = size; }
/*! * Clear the content of the buffer, making it empty. */ void Clear() { DetachBuf(); _sbuf = 0; _start = 0; _size = 0; }
/*! * Reconstruct the buffer to be a copy of a string (not including its terminating NUL). * * @param[in] str The string, which is copied. */ void Assign(const std::string &str) { DetachBuf(); _size = str.size(); _sbuf = new SHARED_BUF(_size); _start = _sbuf->_buf; memcpy(_sbuf->_buf, str.c_str(), _size); }
/*! * Reconstruct the buffer to be a copy of some existing data. * * @param[in] buf Points to the data to copy. * @param[in] size Size (bytes) of data in \a buf. */ template<typename T> void Assign(const T *buf, size_t size) { DetachBuf(); _sbuf = new SHARED_BUF(size); _start = _sbuf->_buf; _size = size; memcpy(_sbuf->_buf, static_cast<const void *>(buf), size); }
/*! * Reconstruct the buffer to be a copy of a string (not including its terminating NUL). * * @param[in] str NUL-terminated string, which is copied. */ void Assign(const char *str) { DetachBuf(); _size = strlen(str); _sbuf = new SHARED_BUF(_size); _start = _sbuf->_buf; memcpy(_sbuf->_buf, str, _size); }
/*! * Reconstruct the buffer to a new size. * * @param[in] size Size (bytes) of the buffer. * @param[in] fill Tells whether the initial contents are zero-filled or left unspecified. */ void Assign(size_t size, FILL fill = FILL_UNSPECIFIED) { DetachBuf(); _sbuf = new SHARED_BUF(size); _start = _sbuf->_buf; _size = size; if (fill == FILL_ZERO) std::memset(_start, 0, _size); }
/*! * Remove trailing bytes from the end of the buffer, making it shorter. * * @param[in] num This many bytes are removed from the buffer. If \a num * is larger than the length of the buffer, the buffer becomes empty. */ void PopBack(size_t num) { if (num >= _size) { DetachBuf(); _sbuf = 0; _start = 0; _size = 0; return; } _size -= num; }
/*! * Reconstruct the buffer to be a copy of a subrange of an existing buffer. * * @param[in] other The contents of this buffer are copied. * @param[in] off This buffer starts at \a off bytes from the start of \a other. * If \a off is larger than \a other, the new buffer is empty. */ void Assign(const DATA &other, size_t off=0) { if (this != &other) { DetachBuf(); CopyFromData(other, off); } else { PopFront(off); } }
/*! * Remove initial bytes from the start of the buffer, making it shorter. * * @param[in] num This many bytes are removed from the buffer. If \a num * is larger than the length of the buffer, the buffer becomes empty. */ void PopFront(size_t num) { if (num >= _size) { DetachBuf(); _sbuf = 0; _start = 0; _size = 0; return; } _start = static_cast<FUND::UINT8 *>(_start) + num; _size -= num; }
/*! * Reconstruct the buffer to be a copy of a subrange of an existing buffer. * * @param[in] other The contents of this buffer are a copy of the contents of \a other. * @param[in] off This buffer starts at \a off bytes from the start of \a other. * If \a off is larger than \a other, the new buffer is empty. * @param[in] len This buffer is at most \a len bytes long. If \a off + \a len * is greater than the length of \a other, the new buffer is a copy * of the data up to the end of \a other. */ void Assign(const DATA &other, size_t off, size_t len) { if (this != &other) { DetachBuf(); CopyFromDataWithLen(other, off, len); } else { PopFront(off); if (len < _size) _size = len; } }
/*! * Change the size of the buffer, retaining it's current content. If the new size is * smaller than the previous size, trailing bytes in the buffer are lost. If the new * size is greater than the previous size, the newly allocated bytes have an unspecified * value. * * @param[in] newSize The new buffer size (bytes). */ void Resize(size_t newSize) { if (newSize <= _size) { if (!newSize) { DetachBuf(); _sbuf = 0; _start = 0; _size = 0; return; } _size = newSize; } else { SHARED_BUF *sbuf = new SHARED_BUF(newSize); memcpy(sbuf->_buf, _start, _size); DetachBuf(); _sbuf = sbuf; _start = sbuf->_buf; _size = newSize; } }
/*! * Reconstruct the buffer to be a copy of a subrange of an existing buffer. * * @param[in] other The contents of this buffer are copied. * @param[in] off This buffer starts at \a off bytes from the start of \a other. * If \a off is larger than \a other, the new buffer is empty. */ void Assign(const DATA &other, size_t off=0) { DetachBuf(); if (off >= other._size) { _sbuf = 0; _start = 0; _size = 0; return; } _sbuf = other._sbuf; _sbuf->_refCount++; _start = other._start + off; _size = other._size - off; }
/*! * Reconstruct the buffer to be a copy of some existing data. * * @param[in] buf Points to the data to copy. * @param[in] size Size (bytes) of data in \a buf. * @param[in] copy Tells whether \a buf is copied eagerly or lazily. */ void Assign(const void *buf, size_t size, COPY copy = COPY_EAGER) { DetachBuf(); CopyFromBuffer(buf, size, copy); }
/*! * Reconstruct the buffer to be a copy of an C++ string. * * @param[in] str The string. * @param[in] copy Tells whether \a str is copied eagerly or lazily. */ void Assign(const std::string &str, COPY copy = COPY_EAGER) { DetachBuf(); CopyFromBuffer(str.c_str(), str.size(), copy); }
/*! * Reconstruct the buffer to be a copy of a C string (not including its terminating NUL). * * @param[in] str NUL-terminated string. * @param[in] copy Tells whether \a str is copied eagerly or lazily. */ void Assign(const char *str, COPY copy = COPY_EAGER) { DetachBuf(); CopyFromBuffer(str, std::strlen(str), copy); }
~DATA() {DetachBuf();}