1
0
mirror of https://github.com/VCMP-SqMod/SqMod.git synced 2025-07-31 13:11:48 +02:00

Updated the buffer class to include an optional numeric value to be used as an edit cursor or to mark the used buffer size.

Basic implementation of the system path class and several fuctions to retrieve information about the running system.
This commit is contained in:
Sandu Liviu Catalin
2016-03-11 04:14:28 +02:00
parent 58891f1e8b
commit 4cac7d2d30
11 changed files with 4503 additions and 104 deletions

View File

@@ -1,5 +1,5 @@
// ------------------------------------------------------------------------------------------------
#include "Buffer.hpp"
#include "Base/Buffer.hpp"
// ------------------------------------------------------------------------------------------------
#include <cstdlib>
@@ -40,7 +40,9 @@ void ThrowMemExcept(const char * msg, ...)
int ret = vsnprintf(buffer, sizeof(buffer), msg, args);
// Check for formatting errors
if (ret < 0)
{
throw std::runtime_error("Unknown memory error");
}
// Throw the actual exception
throw std::runtime_error(buffer);
}
@@ -54,7 +56,9 @@ static Buffer::Pointer AllocMem(Buffer::SzType size)
Buffer::Pointer ptr = reinterpret_cast< Buffer::Pointer >(malloc(size));
// Validate the allocated memory
if (!ptr)
{
ThrowMemExcept("Unable to allocate (%u) bytes of memory", size);
}
// Return the allocated memory
return ptr;
}
@@ -100,7 +104,9 @@ private:
* Base constructor.
*/
Node(Node * next)
: mCap(0), mPtr(nullptr), mNext(next)
: mCap(0)
, mPtr(nullptr)
, mNext(next)
{
/* ... */
}
@@ -130,7 +136,9 @@ private:
{
// Free the memory (if any)
if (node->mPtr)
{
free(node->mPtr);
}
// Save the next node
next = node->mNext;
// Release the node instance
@@ -149,7 +157,9 @@ private:
{
// Free the memory (if any)
if (node->mPtr)
{
free(node->mPtr);
}
// Save the next node
next = node->mNext;
// Release the node instance
@@ -173,10 +183,14 @@ private:
{
// Was there a previous node?
if (prev)
{
prev->mNext = node->mNext;
}
// Probably this was the head
else
{
m_Head = node->mNext;
}
// Assign the memory
ptr = node->mPtr;
// Assign the size
@@ -208,7 +222,9 @@ private:
void Drop(Pointer & ptr, SzType & size)
{
if (!ptr)
{
ThrowMemExcept("Cannot store invalid memory buffer");
}
// Request a node instance
Node * node = Pull();
// Assign the specified memory
@@ -232,7 +248,9 @@ private:
s_Nodes = new Node(s_Nodes);
// Validate the head node
if (!s_Nodes)
{
ThrowMemExcept("Unable to allocate memory nodes");
}
}
}
@@ -243,7 +261,9 @@ private:
{
// Are there any nodes available?
if (!s_Nodes)
{
Make(); // Make some!
}
// Grab the head node
Node * node = s_Nodes;
// Promote the next node as the head
@@ -259,7 +279,9 @@ private:
{
// See if the node is even valid
if (!node)
{
ThrowMemExcept("Attempting to push invalid node");
}
// Demote the current head node
node->mNext = s_Nodes;
// Promote as the head node
@@ -324,7 +346,9 @@ MemRef MemRef::s_Mem;
void MemRef::Grab()
{
if (m_Ptr)
{
++(*m_Ref);
}
}
// ------------------------------------------------------------------------------------------------
@@ -354,7 +378,8 @@ const MemRef & MemRef::Get()
// ------------------------------------------------------------------------------------------------
Buffer::Buffer(const Buffer & o)
: m_Ptr(nullptr)
, m_Cap(0)
, m_Cap(o.m_Cap)
, m_Cur(o.m_Cur)
, m_Mem(o.m_Mem)
{
if (m_Cap)
@@ -369,7 +394,9 @@ Buffer::~Buffer()
{
// Do we have a buffer?
if (m_Ptr)
{
Release(); // Release it!
}
}
// ------------------------------------------------------------------------------------------------
@@ -379,30 +406,51 @@ Buffer & Buffer::operator = (const Buffer & o)
{
// Can we work in the current buffer?
if (m_Cap && o.m_Cap <= m_Cap)
{
// It's safe to copy the data
memcpy(m_Ptr, o.m_Ptr, m_Cap);
memcpy(m_Ptr, o.m_Ptr, o.m_Cap);
}
// Do we even have data to copy?
else if (!o.m_Cap)
{
// Do we have a buffer?
if (m_Ptr)
{
Release(); // Release it!
}
}
else
{
// Do we have a buffer?
if (m_Ptr)
{
Release(); // Release it!
}
// Request a larger buffer
Request(o.m_Cap);
// Now it's safe to copy the data
memcpy(m_Ptr, o.m_Ptr, o.m_Cap);
}
// Also copy the edit cursor
m_Cur = o.m_Cur;
}
return *this;
}
// ------------------------------------------------------------------------------------------------
void Buffer::Grow(SzType n)
{
// Backup the current memory
Buffer bkp(m_Ptr, m_Cap, m_Cur, m_Mem);
// Acquire a bigger buffer
Request(bkp.m_Cap + n);
// Copy the data from the old buffer
memcpy(m_Ptr, bkp.m_Ptr, bkp.m_Cap);
// Copy the previous edit cursor
m_Cur = bkp.m_Cur;
}
// ------------------------------------------------------------------------------------------------
void Buffer::Request(SzType n)
{
@@ -417,11 +465,17 @@ void Buffer::Request(SzType n)
}
// Find out in which category does this buffer reside
else if (n <= 1024)
{
m_Mem->m_Small.Grab(m_Ptr, n);
}
else if (n <= 4096)
{
m_Mem->m_Medium.Grab(m_Ptr, n);
}
else
{
m_Mem->m_Large.Grab(m_Ptr, n);
}
// If no errors occurred then we can set the size
m_Cap = n;
}
@@ -432,32 +486,41 @@ void Buffer::Release()
// TODO: Implement a limit on how much memory can actually be pooled.
// Is there a memory manager available?
if (!m_Mem)
{
free(m_Ptr); // Deallocate the memory directly
}
// Find out to which category does this buffer belong
else if (m_Cap <= 1024)
{
m_Mem->m_Small.Drop(m_Ptr, m_Cap);
}
else if (m_Cap <= 4096)
{
m_Mem->m_Medium.Drop(m_Ptr, m_Cap);
}
else
{
m_Mem->m_Large.Drop(m_Ptr, m_Cap);
}
// Explicitly reset the buffer
m_Ptr = nullptr;
m_Cap = 0;
m_Cur = 0;
}
// ------------------------------------------------------------------------------------------------
Buffer::SzType Buffer::Write(SzType pos, ConstPtr data, SzType size)
{
// Make sure the position is not out of bounds
if (pos > m_Cap || !data || !size)
// Do we have what to write?
if (!data || !size)
{
return 0;
}
// See if the buffer size must be adjusted
else if ((pos + size) >= m_Cap)
{
// Allocate a larger memory chunk and backup old data
Buffer bkp(Adjust< Value >(NextPow2(pos + size)));
// Copy data back from the old buffer
memcpy(m_Ptr, bkp.m_Ptr, bkp.m_Cap);
// Acquire a larger buffer
Grow((pos + size) - m_Cap + 32);
}
// Copy the data into the internal buffer
memcpy(m_Ptr + pos, data, size);
@@ -472,7 +535,7 @@ Buffer::SzType Buffer::WriteF(SzType pos, const char * fmt, ...)
va_list args;
va_start(args, fmt);
// Call the function that takes the variable argument list
SzType ret = WriteF(pos, fmt, args);
const SzType ret = WriteF(pos, fmt, args);
// Finalize the variable argument list
va_end(args);
// Return the result
@@ -482,9 +545,12 @@ Buffer::SzType Buffer::WriteF(SzType pos, const char * fmt, ...)
// ------------------------------------------------------------------------------------------------
Buffer::SzType Buffer::WriteF(SzType pos, const char * fmt, va_list args)
{
// Make sure the position is not out of bounds
if (pos > m_Cap)
return 0;
// Is the specified position within range?
if (pos >= m_Cap)
{
// Acquire a larger buffer
Grow(pos - m_Cap + 32);
}
// Backup the variable argument list
va_list args_cpy;
va_copy(args_cpy, args);
@@ -494,18 +560,53 @@ Buffer::SzType Buffer::WriteF(SzType pos, const char * fmt, va_list args)
// Do we need a bigger buffer?
if ((pos + ret) >= m_Cap)
{
// Allocate a larger memory chunk and backup old data
Buffer bkp(Adjust< Value >(NextPow2(pos + ret)));
// Copy data back from the old buffer
memcpy(m_Ptr, bkp.m_Ptr, bkp.m_Cap);
// Acquire a larger buffer
Grow((pos + ret) - m_Cap + 32);
// Retry writing the requested information
ret = vsnprintf(m_Ptr + pos, m_Cap, fmt, args_cpy);
}
// Return the value 0 if data could not be written
if (ret < 0)
{
return 0;
}
// Return the number of written characters
return static_cast< SzType >(ret);
}
// ------------------------------------------------------------------------------------------------
Buffer::SzType Buffer::WriteS(SzType pos, ConstPtr str)
{
// Is there any string to write?
if (str && *str != '\0')
{
// Forward this to the regular write function
return Write(pos, str, strlen(str));
}
// Nothing to write
return 0;
}
// ------------------------------------------------------------------------------------------------
void Buffer::AppendF(const char * fmt, ...)
{
// Initialize the variable argument list
va_list args;
va_start(args, fmt);
// Forward this to the regular write function
m_Cur += WriteF(m_Cur, fmt, args);
// Finalize the variable argument list
va_end(args);
}
// ------------------------------------------------------------------------------------------------
void Buffer::AppendS(const char * str)
{
// Is there any string to write?
if (str)
{
m_Cur += Write(m_Cur, str, strlen(str));
}
}
} // Namespace:: SqMod

View File

@@ -52,7 +52,8 @@ public:
* Default constructor (null).
*/
MemRef()
: m_Ptr(s_Mem.m_Ptr), m_Ref(s_Mem.m_Ref)
: m_Ptr(s_Mem.m_Ptr)
, m_Ref(s_Mem.m_Ref)
{
Grab();
}
@@ -61,7 +62,8 @@ public:
* Copy constructor.
*/
MemRef(const MemRef & o)
: m_Ptr(o.m_Ptr), m_Ref(o.m_Ref)
: m_Ptr(o.m_Ptr)
, m_Ref(o.m_Ref)
{
Grab();
@@ -189,13 +191,15 @@ private:
/* --------------------------------------------------------------------------------------------
* Construct and take ownership of the specified buffer.
*/
Buffer(Pointer & ptr, SzType & cap, const MemRef & mem)
Buffer(Pointer & ptr, SzType & cap, SzType & cur, const MemRef & mem)
: m_Ptr(ptr)
, m_Cap(cap)
, m_Cur(cur)
, m_Mem(mem)
{
ptr = nullptr;
cap = 0;
cur = 0;
}
public:
@@ -206,6 +210,7 @@ public:
Buffer()
: m_Ptr(nullptr)
, m_Cap(0)
, m_Cur(0)
, m_Mem(MemRef::Get())
{
/* ... */
@@ -217,6 +222,7 @@ public:
Buffer(SzType n)
: m_Ptr(nullptr)
, m_Cap(0)
, m_Cur(0)
, m_Mem(MemRef::Get())
{
Request(n < 8 ? 8 : n);
@@ -231,7 +237,10 @@ public:
* Move constructor.
*/
Buffer(Buffer && o)
: m_Ptr(o.m_Ptr), m_Cap(o.m_Cap), m_Mem(o.m_Mem)
: m_Ptr(o.m_Ptr)
, m_Cap(o.m_Cap)
, m_Cur(o.m_Cur)
, m_Mem(o.m_Mem)
{
o.m_Ptr = nullptr;
}
@@ -254,9 +263,12 @@ public:
if (m_Ptr != o.m_Ptr)
{
if (m_Ptr)
{
Release();
}
m_Ptr = o.m_Ptr;
m_Cap = o.m_Cap;
m_Cur = o.m_Cur;
m_Mem = o.m_Mem;
o.m_Ptr = nullptr;
}
@@ -319,72 +331,6 @@ public:
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the internal buffer casted as a different type.
*/
template < typename T = Value> T * Get()
{
return reinterpret_cast< T * >(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the internal buffer casted as a different type.
*/
template < typename T = Value> const T * Get() const
{
return reinterpret_cast< const T * >(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the a certain element.
*/
template < typename T = Value> T & At(SzType n)
{
assert(n < m_Cap);
return reinterpret_cast< T * >(m_Ptr)[n];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the a certain element.
*/
template < typename T = Value> const T & At(SzType n) const
{
assert(n < m_Cap);
return reinterpret_cast< const T * >(m_Ptr)[n];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the internal buffer casted as a different type.
*/
template < typename T = Value> T * Begin()
{
return reinterpret_cast< T * >(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the internal buffer casted as a different type.
*/
template < typename T = Value> const T * Begin() const
{
return reinterpret_cast< const T * >(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the internal buffer casted as a different type.
*/
template < typename T = Value> T * End()
{
return reinterpret_cast< T * >(m_Ptr) + (m_Cap / sizeof(T));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the internal buffer casted as a different type.
*/
template < typename T = Value> const T * End() const
{
return reinterpret_cast< const T * >(m_Ptr) + (m_Cap / sizeof(T));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the internal buffer.
*/
@@ -401,20 +347,273 @@ public:
return m_Ptr;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the internal buffer casted as a different type.
*/
template < typename T = Value > T * Get()
{
return reinterpret_cast< T * >(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the internal buffer casted as a different type.
*/
template < typename T = Value > const T * Get() const
{
return reinterpret_cast< const T * >(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the a certain element.
*/
template < typename T = Value > T & At(SzType n)
{
assert(n < m_Cap);
return reinterpret_cast< T * >(m_Ptr)[n];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the a certain element.
*/
template < typename T = Value > const T & At(SzType n) const
{
assert(n < m_Cap);
return reinterpret_cast< const T * >(m_Ptr)[n];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the internal buffer casted as a different type.
*/
template < typename T = Value > T * Begin()
{
return reinterpret_cast< T * >(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the internal buffer casted as a different type.
*/
template < typename T = Value > const T * Begin() const
{
return reinterpret_cast< const T * >(m_Ptr);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the internal buffer casted as a different type.
*/
template < typename T = Value > T * End()
{
return reinterpret_cast< T * >(m_Ptr) + (m_Cap / sizeof(T));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the internal buffer casted as a different type.
*/
template < typename T = Value > const T * End() const
{
return reinterpret_cast< const T * >(m_Ptr) + (m_Cap / sizeof(T));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element at the front of the buffer.
*/
template < typename T = Value > T & Front()
{
assert(m_Cap >= sizeof(T));
return reinterpret_cast< T * >(m_Ptr)[0];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element at the front of the buffer.
*/
template < typename T = Value > const T & Front() const
{
assert(m_Cap >= sizeof(T));
return reinterpret_cast< const T * >(m_Ptr)[0];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element after the first element in the buffer.
*/
template < typename T = Value > T & Next()
{
assert(m_Cap >= (sizeof(T) * 2));
return reinterpret_cast< T * >(m_Ptr)[1];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element after the first element in the buffer.
*/
template < typename T = Value > const T & Next() const
{
assert(m_Cap >= (sizeof(T) * 2));
return reinterpret_cast< const T * >(m_Ptr)[1];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element at the back of the buffer.
*/
template < typename T = Value > T & Back()
{
assert(m_Cap >= sizeof(T));
return reinterpret_cast< T * >(m_Ptr)[m_Cap-1];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element at the back of the buffer.
*/
template < typename T = Value > const T & Back() const
{
assert(m_Cap >= sizeof(T));
return reinterpret_cast< const T * >(m_Ptr)[m_Cap-1];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element before the last element in the buffer.
*/
template < typename T = Value > T & Prev()
{
assert(m_Cap >= (sizeof(T) * 2));
return reinterpret_cast< T * >(m_Ptr)[m_Cap-2];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element before the last element in the buffer.
*/
template < typename T = Value > const T & Prev() const
{
assert(m_Cap >= (sizeof(T) * 2));
return reinterpret_cast< const T * >(m_Ptr)[m_Cap-2];
}
/* --------------------------------------------------------------------------------------------
* Reposition the edit cursor to the specified number of elements ahead.
*/
template < typename T = Value > void Advance(SzType n)
{
// Do we need to scale the buffer?
if ((m_Cur + (n * sizeof(T))) >= m_Cap)
{
Grow(m_Cur + (n * sizeof(T)));
}
// Advance to the specified position
m_Cur += (n * sizeof(T));
}
/* --------------------------------------------------------------------------------------------
* Reposition the edit cursor to the specified number of elements behind.
*/
template < typename T = Value > void Retreat(SzType n)
{
// Can we move that much backward?
if ((n * sizeof(T)) <= m_Cur)
{
m_Cur -= (n * sizeof(T));
}
// Just got to the beginning
else
{
m_Cur = 0;
}
}
/* --------------------------------------------------------------------------------------------
* Reposition the edit cursor to a fixed position within the buffer.
*/
template < typename T = Value > void Move(SzType n)
{
// Do we need to scale the buffer?
if ((n * sizeof(T)) >= m_Cap)
{
Grow(n * sizeof(T));
}
// Move to the specified position
m_Cur = (n * sizeof(T));
}
/* --------------------------------------------------------------------------------------------
* Reposition the edit cursor to a fixed position within the buffer.
*/
template < typename T = Value > void Push(T v)
{
// Do we need to scale the buffer?
if ((m_Cur + sizeof(T)) >= m_Cap)
{
Grow(m_Cap + sizeof(T));
}
// Assign the specified value
reinterpret_cast< T * >(m_Ptr)[m_Cur] = v;
// Move to the next element
m_Cur += sizeof(T);
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element at the cursor position.
*/
template < typename T = Value > T & Cursor()
{
assert((m_Cur / sizeof(T)) < (m_Cap / sizeof(T)));
return reinterpret_cast< T * >(m_Ptr)[m_Cur];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element at the cursor position.
*/
template < typename T = Value > const T & Cursor() const
{
assert((m_Cur / sizeof(T)) < (m_Cap / sizeof(T)));
return reinterpret_cast< const T * >(m_Ptr)[m_Cur];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element before the cursor position.
*/
template < typename T = Value > T & Before()
{
assert(m_Cur >= sizeof(T));
return reinterpret_cast< T * >(m_Ptr)[m_Cur-1];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element before the cursor position.
*/
template < typename T = Value > const T & Before() const
{
assert(m_Cur >= sizeof(T));
return reinterpret_cast< const T * >(m_Ptr)[m_Cur-1];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element after the cursor position.
*/
template < typename T = Value > T & After()
{
assert((m_Cur + sizeof(T)) <= (m_Cap - sizeof(T)));
return reinterpret_cast< T * >(m_Ptr)[m_Cur+1];
}
/* --------------------------------------------------------------------------------------------
* Retrieve the element after the cursor position.
*/
template < typename T = Value > const T & After() const
{
assert((m_Cur + sizeof(T)) <= (m_Cap - sizeof(T)));
return reinterpret_cast< const T * >(m_Ptr)[m_Cur+1];
}
/* --------------------------------------------------------------------------------------------
* Retrieve maximum elements it can hold for a certain type.
*/
template < typename T = Value> static SzType Max()
template < typename T = Value > static SzType Max()
{
return (0xFFFFFFFF / sizeof(T));
return static_cast< SzType >(0xFFFFFFFF / sizeof(T));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the current buffer capacity in element count.
*/
template < typename T = Value> SzType Size() const
template < typename T = Value > SzType Size() const
{
return (m_Cap / sizeof(T));
return static_cast< SzType >(m_Cap / sizeof(T));
}
/* --------------------------------------------------------------------------------------------
@@ -425,25 +624,52 @@ public:
return m_Cap;
}
/* --------------------------------------------------------------------------------------------
* Retrieve the current position of the cursor in the buffer.
*/
template < typename T = Value > SzType Position() const
{
return static_cast< SzType >(m_Cur / sizeof(T));
}
/* --------------------------------------------------------------------------------------------
* Retrieve the amount of unused buffer after the edit cursor.
*/
template < typename T = Value > SzType Remaining() const
{
return static_cast< SzType >((m_Cap - m_Cur) / sizeof(T));
}
/* --------------------------------------------------------------------------------------------
* Grow the size of the internal buffer by the specified amount of bytes.
*/
void Grow(SzType n);
/* --------------------------------------------------------------------------------------------
* Makes sure there is enough capacity to hold the specified element count.
*/
template < typename T = Value> Buffer Adjust(SzType n)
template < typename T = Value > Buffer Adjust(SzType n)
{
// Do we meet the minimum size?
if (n < 8)
{
n = 8; // Adjust to minimum size
}
// See if the requested capacity doesn't exceed the limit
if (n > Max< T >())
{
ThrowMemExcept("Requested buffer of (%u) elements exceeds the (%u) limit", n, Max< T >());
}
// Is there an existing buffer?
else if (n && !m_Cap)
{
Request(n * sizeof(T)); // Request the memory
}
// Should the size be increased?
else if (n > m_Cap)
{
// Backup the current memory
Buffer bkp(m_Ptr, m_Cap, m_Mem);
Buffer bkp(m_Ptr, m_Cap, m_Cur, m_Mem);
// Request the memory
Request(n * sizeof(T));
// Return the backup
@@ -459,7 +685,9 @@ public:
void Reset()
{
if (m_Ptr)
{
Release();
}
}
/* --------------------------------------------------------------------------------------------
@@ -476,10 +704,18 @@ public:
}
/* --------------------------------------------------------------------------------------------
* Write a portion of a buffet to the internal buffer.
* Write a portion of a buffer to the internal buffer.
*/
SzType Write(SzType pos, ConstPtr data, SzType size);
/* --------------------------------------------------------------------------------------------
* Write another buffer to the internal buffer.
*/
SzType Write(SzType pos, const Buffer & b)
{
return Write(pos, b.m_Ptr, b.m_Cur);
}
/* --------------------------------------------------------------------------------------------
* Write a formatted string to the internal buffer.
*/
@@ -490,6 +726,61 @@ public:
*/
SzType WriteF(SzType pos, const char * fmt, va_list args);
/* --------------------------------------------------------------------------------------------
* Write a string to the internal buffer.
*/
SzType WriteS(SzType pos, const char * str);
/* --------------------------------------------------------------------------------------------
* Write a portion of a string to the internal buffer.
*/
SzType WriteS(SzType pos, const char * str, SzType size)
{
return Write(pos, str, size);
}
/* --------------------------------------------------------------------------------------------
* Append a portion of a buffer to the internal buffer.
*/
void Append(ConstPtr data, SzType size)
{
m_Cur += Write(m_Cur, data, size);
}
/* --------------------------------------------------------------------------------------------
* Append another buffer to the internal buffer.
*/
void Append(const Buffer & b)
{
m_Cur += Write(m_Cur, b.m_Ptr, b.m_Cur);
}
/* --------------------------------------------------------------------------------------------
* Append a formatted string to the internal buffer.
*/
void AppendF(const char * fmt, ...);
/* --------------------------------------------------------------------------------------------
* Append a formatted string to the internal buffer.
*/
void AppendF(const char * fmt, va_list args)
{
m_Cur += WriteF(m_Cur, fmt, args);
}
/* --------------------------------------------------------------------------------------------
* Append a string to the internal buffer.
*/
void AppendS(const char * str);
/* --------------------------------------------------------------------------------------------
* Append a portion of a string to the internal buffer.
*/
void AppendS(const char * str, SzType size)
{
m_Cur += Write(m_Cur, str, size);
}
protected:
/* --------------------------------------------------------------------------------------------
@@ -507,9 +798,10 @@ private:
// --------------------------------------------------------------------------------------------
Pointer m_Ptr; /* Pointer to the memory buffer. */
SzType m_Cap; /* The total size of the buffer. */
SzType m_Cur; /* The buffer edit cursor. */
// --------------------------------------------------------------------------------------------
MemRef m_Mem;
MemRef m_Mem; /* Reference to the associated memory manager. */
};
} // Namespace:: SqMod