mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-12 10:04:14 +02:00
Refactor String, Buffer, and Variant types with inline getters.
Extend the pattern introduced in 79a2d02c
to the String, Buffer, and Variant types.
This commit is contained in:
parent
1edcfde93e
commit
066fbcf268
@ -28,8 +28,7 @@ Contains information about the buffer
|
||||
***********************************************************************************************************************************/
|
||||
struct Buffer
|
||||
{
|
||||
BUFFER_COMMON // Variables that are common to static and dynamic buffers
|
||||
unsigned char *buffer; // Internal buffer
|
||||
BufferPub pub; // Publicly accessible variables
|
||||
};
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
@ -49,14 +48,17 @@ bufNew(size_t size)
|
||||
|
||||
*this = (Buffer)
|
||||
{
|
||||
.memContext = MEM_CONTEXT_NEW(),
|
||||
.sizeAlloc = size,
|
||||
.size = size,
|
||||
.pub =
|
||||
{
|
||||
.memContext = MEM_CONTEXT_NEW(),
|
||||
.sizeAlloc = size,
|
||||
.size = size,
|
||||
},
|
||||
};
|
||||
|
||||
// Allocate buffer
|
||||
if (size > 0)
|
||||
this->buffer = memNew(this->sizeAlloc);
|
||||
this->pub.buffer = memNew(this->pub.sizeAlloc);
|
||||
}
|
||||
MEM_CONTEXT_NEW_END();
|
||||
|
||||
@ -76,8 +78,8 @@ bufNewC(const void *buffer, size_t size)
|
||||
|
||||
// Create object and copy data
|
||||
Buffer *this = bufNew(size);
|
||||
memcpy(this->buffer, buffer, this->size);
|
||||
this->used = this->size;
|
||||
memcpy(this->pub.buffer, buffer, bufSize(this));
|
||||
this->pub.used = bufSize(this);
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
@ -110,9 +112,9 @@ bufDup(const Buffer *buffer)
|
||||
ASSERT(buffer != NULL);
|
||||
|
||||
// Create object and copy data
|
||||
Buffer *this = bufNew(buffer->used);
|
||||
memcpy(this->buffer, buffer->buffer, this->size);
|
||||
this->used = this->size;
|
||||
Buffer *this = bufNew(buffer->pub.used);
|
||||
memcpy(this->pub.buffer, buffer->pub.buffer, bufSize(this));
|
||||
this->pub.used = bufSize(this);
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
@ -129,7 +131,7 @@ bufCat(Buffer *this, const Buffer *cat)
|
||||
ASSERT(this != NULL);
|
||||
|
||||
if (cat != NULL)
|
||||
bufCatC(this, cat->buffer, 0, cat->used);
|
||||
bufCatC(this, cat->pub.buffer, 0, cat->pub.used);
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
@ -150,14 +152,14 @@ bufCatC(Buffer *this, const unsigned char *cat, size_t catOffset, size_t catSize
|
||||
|
||||
if (catSize > 0)
|
||||
{
|
||||
if (this->used + catSize > bufSize(this))
|
||||
bufResize(this, this->used + catSize);
|
||||
if (bufUsed(this) + catSize > bufSize(this))
|
||||
bufResize(this, bufUsed(this) + catSize);
|
||||
|
||||
// Just here to silence nonnull warnings from clang static analyzer
|
||||
ASSERT(this->buffer != NULL);
|
||||
ASSERT(bufPtr(this) != NULL);
|
||||
|
||||
memcpy(this->buffer + this->used, cat + catOffset, catSize);
|
||||
this->used += catSize;
|
||||
memcpy(bufPtr(this) + bufUsed(this), cat + catOffset, catSize);
|
||||
this->pub.used += catSize;
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
@ -178,10 +180,10 @@ bufCatSub(Buffer *this, const Buffer *cat, size_t catOffset, size_t catSize)
|
||||
|
||||
if (cat != NULL)
|
||||
{
|
||||
ASSERT(catOffset <= cat->used);
|
||||
ASSERT(catSize <= cat->used - catOffset);
|
||||
ASSERT(catOffset <= cat->pub.used);
|
||||
ASSERT(catSize <= cat->pub.used - catOffset);
|
||||
|
||||
bufCatC(this, cat->buffer, catOffset, catSize);
|
||||
bufCatC(this, cat->pub.buffer, catOffset, catSize);
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
@ -199,12 +201,10 @@ bufEq(const Buffer *this, const Buffer *compare)
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(compare != NULL);
|
||||
|
||||
bool result = false;
|
||||
if (bufUsed(this) == bufUsed(compare))
|
||||
FUNCTION_TEST_RETURN(memcmp(bufPtrConst(this), bufPtrConst(compare), bufUsed(compare)) == 0);
|
||||
|
||||
if (this->used == compare->used)
|
||||
result = memcmp(this->buffer, compare->buffer, compare->used) == 0;
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
FUNCTION_TEST_RETURN(false);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
@ -220,7 +220,7 @@ bufHex(const Buffer *this)
|
||||
String *result = strNew("");
|
||||
|
||||
for (unsigned int bufferIdx = 0; bufferIdx < bufUsed(this); bufferIdx++)
|
||||
strCatFmt(result, "%02x", this->buffer[bufferIdx]);
|
||||
strCatFmt(result, "%02x", bufPtrConst(this)[bufferIdx]);
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
}
|
||||
@ -237,45 +237,45 @@ bufResize(Buffer *this, size_t size)
|
||||
ASSERT(this != NULL);
|
||||
|
||||
// Only resize if it the new size is different
|
||||
if (this->sizeAlloc != size)
|
||||
if (bufSizeAlloc(this) != size)
|
||||
{
|
||||
// If new size is zero then free memory if allocated
|
||||
if (size == 0)
|
||||
{
|
||||
// When setting size down to 0 the buffer should always be allocated
|
||||
ASSERT(this->buffer != NULL);
|
||||
ASSERT(bufPtrConst(this) != NULL);
|
||||
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
MEM_CONTEXT_BEGIN(this->pub.memContext)
|
||||
{
|
||||
memFree(this->buffer);
|
||||
memFree(bufPtr(this));
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
||||
this->buffer = NULL;
|
||||
this->sizeAlloc = 0;
|
||||
this->pub.buffer = NULL;
|
||||
this->pub.sizeAlloc = 0;
|
||||
}
|
||||
// Else allocate or resize
|
||||
else
|
||||
{
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
MEM_CONTEXT_BEGIN(this->pub.memContext)
|
||||
{
|
||||
if (this->buffer == NULL)
|
||||
this->buffer = memNew(size);
|
||||
if (bufPtrConst(this) == NULL)
|
||||
this->pub.buffer = memNew(size);
|
||||
else
|
||||
this->buffer = memResize(this->buffer, size);
|
||||
this->pub.buffer = memResize(bufPtr(this), size);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
||||
this->sizeAlloc = size;
|
||||
this->pub.sizeAlloc = size;
|
||||
}
|
||||
|
||||
if (this->used > this->sizeAlloc)
|
||||
this->used = this->sizeAlloc;
|
||||
if (bufUsed(this) > bufSizeAlloc(this))
|
||||
this->pub.used = bufSizeAlloc(this);
|
||||
|
||||
if (!this->sizeLimit)
|
||||
this->size = this->sizeAlloc;
|
||||
else if (this->size > this->sizeAlloc)
|
||||
this->size = this->sizeAlloc;
|
||||
if (!bufSizeLimit(this))
|
||||
this->pub.size = bufSizeAlloc(this);
|
||||
else if (bufSize(this) > bufSizeAlloc(this))
|
||||
this->pub.size = bufSizeAlloc(this);
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
@ -291,8 +291,8 @@ bufLimitClear(Buffer *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
this->sizeLimit = false;
|
||||
this->size = this->sizeAlloc;
|
||||
this->pub.sizeLimit = false;
|
||||
this->pub.size = bufSizeAlloc(this);
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
@ -306,11 +306,11 @@ bufLimitSet(Buffer *this, size_t limit)
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(limit <= this->sizeAlloc);
|
||||
ASSERT(limit >= this->used);
|
||||
ASSERT(limit <= bufSizeAlloc(this));
|
||||
ASSERT(limit >= bufUsed(this));
|
||||
|
||||
this->size = limit;
|
||||
this->sizeLimit = true;
|
||||
this->pub.size = limit;
|
||||
this->pub.sizeLimit = true;
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
@ -325,9 +325,9 @@ bufUsedInc(Buffer *this, size_t inc)
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(this->used + inc <= bufSize(this));
|
||||
ASSERT(bufUsed(this) + inc <= bufSize(this));
|
||||
|
||||
this->used += inc;
|
||||
this->pub.used += inc;
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
@ -343,7 +343,7 @@ bufUsedSet(Buffer *this, size_t used)
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(used <= bufSize(this));
|
||||
|
||||
this->used = used;
|
||||
this->pub.used = used;
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
@ -357,7 +357,7 @@ bufUsedZero(Buffer *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
this->used = 0;
|
||||
this->pub.used = 0;
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
@ -367,8 +367,8 @@ String *
|
||||
bufToLog(const Buffer *this)
|
||||
{
|
||||
String *result = strNewFmt(
|
||||
"{used: %zu, size: %zu%s", this->used, this->size,
|
||||
this->sizeLimit ? strZ(strNewFmt(", sizeAlloc: %zu}", this->sizeAlloc)) : "}");
|
||||
"{used: %zu, size: %zu%s", bufUsed(this), bufSize(this),
|
||||
bufSizeLimit(this) ? strZ(strNewFmt(", sizeAlloc: %zu}", bufSizeAlloc(this))) : "}");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -13,27 +13,6 @@ typedef struct Buffer Buffer;
|
||||
#include "common/type/object.h"
|
||||
#include "common/type/string.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Fields that are common between dynamically allocated and constant buffers
|
||||
|
||||
There is nothing user-accessible here but this construct allows constant buffers to be created and then handled by the same
|
||||
functions that process dynamically allocated buffers.
|
||||
***********************************************************************************************************************************/
|
||||
#define BUFFER_COMMON \
|
||||
MemContext *memContext; /* Mem context */ \
|
||||
size_t sizeAlloc; /* Allocated size of the buffer */ \
|
||||
size_t size; /* Reported size of the buffer */ \
|
||||
bool sizeLimit; /* Is the size limited to make the buffer appear smaller? */ \
|
||||
size_t used; /* Amount of buffer used */
|
||||
|
||||
typedef struct BufferConst
|
||||
{
|
||||
BUFFER_COMMON
|
||||
|
||||
// This version of buffer is for const macro assignments because casting can be dangerous
|
||||
const void *buffer;
|
||||
} BufferConst;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructors
|
||||
***********************************************************************************************************************************/
|
||||
@ -48,6 +27,90 @@ Buffer *bufNewDecode(EncodeType type, const String *string);
|
||||
// Duplicate a buffer
|
||||
Buffer *bufDup(const Buffer *buffer);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters/Setters
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct BufferPub
|
||||
{
|
||||
MemContext *memContext; // Mem context
|
||||
size_t sizeAlloc; // Allocated size of the buffer
|
||||
size_t size; // Reported size of the buffer
|
||||
bool sizeLimit; // Is the size limited to make the buffer appear smaller?
|
||||
size_t used; // Amount of buffer used
|
||||
unsigned char *buffer; // Buffer
|
||||
} BufferPub;
|
||||
|
||||
// Amount of the buffer actually used. This will be updated automatically when possible but if the buffer is modified by using
|
||||
// bufPtr() then the user is responsible for updating used.
|
||||
__attribute__((always_inline)) static inline size_t
|
||||
bufUsed(const Buffer *const this)
|
||||
{
|
||||
return THIS_PUB(Buffer)->used;
|
||||
}
|
||||
|
||||
// Is the buffer empty?
|
||||
__attribute__((always_inline)) static inline bool
|
||||
bufEmpty(const Buffer *const this)
|
||||
{
|
||||
return bufUsed(this) == 0;
|
||||
}
|
||||
|
||||
// Buffer size
|
||||
__attribute__((always_inline)) static inline size_t
|
||||
bufSize(const Buffer *const this)
|
||||
{
|
||||
return THIS_PUB(Buffer)->size;
|
||||
}
|
||||
|
||||
// Is the buffer full?
|
||||
__attribute__((always_inline)) static inline bool
|
||||
bufFull(const Buffer *const this)
|
||||
{
|
||||
return bufUsed(this) == bufSize(this);
|
||||
}
|
||||
|
||||
// Buffer pointer
|
||||
__attribute__((always_inline)) static inline unsigned char *
|
||||
bufPtr(Buffer *const this)
|
||||
{
|
||||
return THIS_PUB(Buffer)->buffer;
|
||||
}
|
||||
|
||||
// Const buffer pointer
|
||||
__attribute__((always_inline)) static inline const unsigned char *
|
||||
bufPtrConst(const Buffer *const this)
|
||||
{
|
||||
return THIS_PUB(Buffer)->buffer;
|
||||
}
|
||||
|
||||
// Remaining space in the buffer
|
||||
__attribute__((always_inline)) static inline size_t
|
||||
bufRemains(const Buffer *const this)
|
||||
{
|
||||
return bufSize(this) - bufUsed(this);
|
||||
}
|
||||
|
||||
// Pointer to remaining buffer space (after used space)
|
||||
__attribute__((always_inline)) static inline unsigned char *
|
||||
bufRemainsPtr(Buffer *const this)
|
||||
{
|
||||
return bufPtr(this) + bufUsed(this);
|
||||
}
|
||||
|
||||
// Allocated buffer size. This may be different from bufSize() if a limit has been set.
|
||||
__attribute__((always_inline)) static inline size_t
|
||||
bufSizeAlloc(const Buffer *const this)
|
||||
{
|
||||
return THIS_PUB(Buffer)->sizeAlloc;
|
||||
}
|
||||
|
||||
// Is the size limited to make the buffer appear smaller?
|
||||
__attribute__((always_inline)) static inline bool
|
||||
bufSizeLimit(const Buffer *const this)
|
||||
{
|
||||
return THIS_PUB(Buffer)->sizeLimit;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
@ -80,82 +143,10 @@ Buffer *bufResize(Buffer *this, size_t size);
|
||||
void bufLimitClear(Buffer *this);
|
||||
void bufLimitSet(Buffer *this, size_t limit);
|
||||
|
||||
// Buffer size
|
||||
__attribute__((always_inline)) static inline size_t
|
||||
bufSize(const Buffer *const this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return ((const BufferConst *)this)->size;
|
||||
}
|
||||
|
||||
// Allocated buffer size. This may be different from bufSize() if a limit has been set.
|
||||
__attribute__((always_inline)) static inline size_t
|
||||
bufSizeAlloc(const Buffer *const this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return ((const BufferConst *)this)->sizeAlloc;
|
||||
}
|
||||
|
||||
// Amount of the buffer actually used. This will be updated automatically when possible but if the buffer is modified by using
|
||||
// bufPtr() then the user is responsible for updating used.
|
||||
__attribute__((always_inline)) static inline size_t
|
||||
bufUsed(const Buffer *const this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return ((const BufferConst *)this)->used;
|
||||
}
|
||||
|
||||
void bufUsedInc(Buffer *this, size_t inc);
|
||||
void bufUsedSet(Buffer *this, size_t used);
|
||||
void bufUsedZero(Buffer *this);
|
||||
|
||||
// Is the buffer empty?
|
||||
__attribute__((always_inline)) static inline bool
|
||||
bufEmpty(const Buffer *const this)
|
||||
{
|
||||
return bufUsed(this) == 0;
|
||||
}
|
||||
|
||||
// Remaining space in the buffer
|
||||
__attribute__((always_inline)) static inline size_t
|
||||
bufRemains(const Buffer *const this)
|
||||
{
|
||||
return bufSize(this) - bufUsed(this);
|
||||
}
|
||||
|
||||
// Is the buffer full?
|
||||
__attribute__((always_inline)) static inline bool
|
||||
bufFull(const Buffer *const this)
|
||||
{
|
||||
return bufUsed(this) == bufSize(this);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters/Setters
|
||||
***********************************************************************************************************************************/
|
||||
// Buffer pointer
|
||||
__attribute__((always_inline)) static inline unsigned char *
|
||||
bufPtr(Buffer *const this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return (void *)((BufferConst *)this)->buffer;
|
||||
}
|
||||
|
||||
// Const buffer pointer
|
||||
__attribute__((always_inline)) static inline const unsigned char *
|
||||
bufPtrConst(const Buffer *const this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return ((const BufferConst *)this)->buffer;
|
||||
}
|
||||
|
||||
// Pointer to remaining buffer space (after used space)
|
||||
__attribute__((always_inline)) static inline unsigned char *
|
||||
bufRemainsPtr(Buffer *const this)
|
||||
{
|
||||
return bufPtr(this) + bufUsed(this);
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
@ -177,7 +168,7 @@ By convention all buffer constant identifiers are appended with _BUF.
|
||||
***********************************************************************************************************************************/
|
||||
// Create a buffer constant inline from an unsigned char[]
|
||||
#define BUF(bufferParam, sizeParam) \
|
||||
((const Buffer *)&(const BufferConst){.size = sizeParam, .used = sizeParam, .buffer = bufferParam})
|
||||
((const Buffer *)&(const BufferPub){.size = sizeParam, .used = sizeParam, .buffer = (unsigned char *)bufferParam})
|
||||
|
||||
// Create a buffer constant inline from a non-constant zero-terminated string
|
||||
#define BUFSTRZ(stringz) \
|
||||
|
@ -57,7 +57,7 @@ Object type
|
||||
***********************************************************************************************************************************/
|
||||
struct String
|
||||
{
|
||||
STRING_COMMON // Shared in common with constant strings
|
||||
StringPub pub; // Publicly accessible variables
|
||||
MemContext *memContext; // Required for dynamically allocated strings
|
||||
};
|
||||
|
||||
@ -80,16 +80,19 @@ strNew(const char *string)
|
||||
|
||||
*this = (String)
|
||||
{
|
||||
.memContext = memContextCurrent(),
|
||||
.size = (unsigned int)stringSize,
|
||||
.pub =
|
||||
{
|
||||
.size = (unsigned int)stringSize,
|
||||
|
||||
// A zero-length string is not very useful so assume this string is being created for appending and allocate extra space
|
||||
.extra = stringSize == 0 ? STRING_EXTRA_MIN : 0,
|
||||
// A zero-length string is not very useful so assume this string is being created for appending and allocate extra space
|
||||
.extra = stringSize == 0 ? STRING_EXTRA_MIN : 0,
|
||||
},
|
||||
.memContext = memContextCurrent(),
|
||||
};
|
||||
|
||||
// Allocate and assign string
|
||||
this->buffer = memNew(this->size + this->extra + 1);
|
||||
strcpy(this->buffer, string);
|
||||
this->pub.buffer = memNew(strSize(this) + this->pub.extra + 1);
|
||||
strcpy(this->pub.buffer, string);
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
@ -126,14 +129,17 @@ strNewBuf(const Buffer *buffer)
|
||||
|
||||
*this = (String)
|
||||
{
|
||||
.pub =
|
||||
{
|
||||
.size = (unsigned int)bufUsed(buffer),
|
||||
},
|
||||
.memContext = memContextCurrent(),
|
||||
.size = (unsigned int)bufUsed(buffer),
|
||||
};
|
||||
|
||||
// Allocate and assign string
|
||||
this->buffer = memNew(this->size + 1);
|
||||
memcpy(this->buffer, bufPtrConst(buffer), this->size);
|
||||
this->buffer[this->size] = 0;
|
||||
this->pub.buffer = memNew(strSize(this) + 1);
|
||||
memcpy(this->pub.buffer, bufPtrConst(buffer), strSize(this));
|
||||
this->pub.buffer[strSize(this)] = 0;
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
@ -158,13 +164,16 @@ strNewEncode(EncodeType type, const Buffer *buffer)
|
||||
|
||||
*this = (String)
|
||||
{
|
||||
.pub =
|
||||
{
|
||||
.size = (unsigned int)size,
|
||||
},
|
||||
.memContext = memContextCurrent(),
|
||||
.size = (unsigned int)size,
|
||||
};
|
||||
|
||||
// Allocate and encode buffer
|
||||
this->buffer = memNew(this->size + 1);
|
||||
encodeToStr(type, bufPtrConst(buffer), bufUsed(buffer), this->buffer);
|
||||
this->pub.buffer = memNew(strSize(this) + 1);
|
||||
encodeToStr(type, bufPtrConst(buffer), bufUsed(buffer), this->pub.buffer);
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
@ -197,10 +206,10 @@ strNewFmt(const char *format, ...)
|
||||
CHECK_SIZE(formatSize);
|
||||
|
||||
// Allocate and assign string
|
||||
this->size = (unsigned int)formatSize;
|
||||
this->buffer = memNew(this->size + 1);
|
||||
this->pub.size = (unsigned int)formatSize;
|
||||
this->pub.buffer = memNew(strSize(this) + 1);
|
||||
va_start(argumentList, format);
|
||||
vsnprintf(this->buffer, this->size + 1, format, argumentList);
|
||||
vsnprintf(this->pub.buffer, strSize(this) + 1, format, argumentList);
|
||||
va_end(argumentList);
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
@ -225,14 +234,17 @@ strNewN(const char *string, size_t size)
|
||||
|
||||
*this = (String)
|
||||
{
|
||||
.pub =
|
||||
{
|
||||
.size = (unsigned int)size,
|
||||
},
|
||||
.memContext = memContextCurrent(),
|
||||
.size = (unsigned int)size,
|
||||
};
|
||||
|
||||
// Allocate and assign string
|
||||
this->buffer = memNew(this->size + 1);
|
||||
strncpy(this->buffer, string, this->size);
|
||||
this->buffer[this->size] = 0;
|
||||
this->pub.buffer = memNew(strSize(this) + 1);
|
||||
strncpy(this->pub.buffer, string, strSize(this));
|
||||
this->pub.buffer[strSize(this)] = 0;
|
||||
|
||||
// Return buffer
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
@ -260,9 +272,9 @@ strBaseZ(const String *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
const char *end = this->buffer + this->size;
|
||||
const char *end = this->pub.buffer + strSize(this);
|
||||
|
||||
while (end > this->buffer && *(end - 1) != '/')
|
||||
while (end > this->pub.buffer && *(end - 1) != '/')
|
||||
end--;
|
||||
|
||||
FUNCTION_TEST_RETURN(end);
|
||||
@ -297,7 +309,7 @@ strBeginsWithZ(const String *this, const char *beginsWith)
|
||||
bool result = false;
|
||||
unsigned int beginsWithSize = (unsigned int)strlen(beginsWith);
|
||||
|
||||
if (this->size >= beginsWithSize)
|
||||
if (strSize(this) >= beginsWithSize)
|
||||
result = strncmp(strZ(this), beginsWith, beginsWithSize) == 0;
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
@ -314,21 +326,21 @@ strResize(String *this, size_t requested)
|
||||
FUNCTION_TEST_PARAM(SIZE, requested);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
if (requested > this->extra)
|
||||
if (requested > this->pub.extra)
|
||||
{
|
||||
// Check size
|
||||
CHECK_SIZE((size_t)this->size + requested);
|
||||
CHECK_SIZE(strSize(this) + requested);
|
||||
|
||||
// Calculate new extra needs to satisfy request and leave extra space for new growth
|
||||
this->extra = (unsigned int)requested + ((this->size + (unsigned int)requested) / 2);
|
||||
this->pub.extra = (unsigned int)(requested + ((strSize(this) + requested) / 2));
|
||||
|
||||
// Adding too little extra space usually leads to immediate resizing so enforce a minimum
|
||||
if (this->extra < STRING_EXTRA_MIN)
|
||||
this->extra = STRING_EXTRA_MIN;
|
||||
if (this->pub.extra < STRING_EXTRA_MIN)
|
||||
this->pub.extra = STRING_EXTRA_MIN;
|
||||
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
this->buffer = memResize(this->buffer, this->size + this->extra + 1);
|
||||
this->pub.buffer = memResize(this->pub.buffer, strSize(this) + this->pub.extra + 1);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
@ -369,9 +381,9 @@ strCatZ(String *this, const char *cat)
|
||||
strResize(this, sizeGrow);
|
||||
|
||||
// Append the string
|
||||
strcpy(this->buffer + this->size, cat);
|
||||
this->size += (unsigned int)sizeGrow;
|
||||
this->extra -= (unsigned int)sizeGrow;
|
||||
strcpy(this->pub.buffer + strSize(this), cat);
|
||||
this->pub.size += (unsigned int)sizeGrow;
|
||||
this->pub.extra -= (unsigned int)sizeGrow;
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
@ -392,12 +404,12 @@ strCatZN(String *this, const char *cat, size_t size)
|
||||
strResize(this, size);
|
||||
|
||||
// Append the string
|
||||
strncpy(this->buffer + this->size, cat, size);
|
||||
this->buffer[this->size + size] = '\0';
|
||||
strncpy(this->pub.buffer + strSize(this), cat, size);
|
||||
this->pub.buffer[strSize(this) + size] = '\0';
|
||||
|
||||
// Update size/extra
|
||||
this->size += (unsigned int)size;
|
||||
this->extra -= (unsigned int)size;
|
||||
this->pub.size += (unsigned int)size;
|
||||
this->pub.extra -= (unsigned int)size;
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
@ -418,9 +430,9 @@ strCatChr(String *this, char cat)
|
||||
strResize(this, 1);
|
||||
|
||||
// Append the character
|
||||
this->buffer[this->size++] = cat;
|
||||
this->buffer[this->size] = 0;
|
||||
this->extra--;
|
||||
this->pub.buffer[this->pub.size++] = cat;
|
||||
this->pub.buffer[this->pub.size] = 0;
|
||||
this->pub.extra--;
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
@ -443,11 +455,11 @@ strCatEncode(String *this, EncodeType type, const Buffer *buffer)
|
||||
strResize(this, encodeSize);
|
||||
|
||||
// Append the encoded string
|
||||
encodeToStr(type, bufPtrConst(buffer), bufUsed(buffer), this->buffer + this->size);
|
||||
encodeToStr(type, bufPtrConst(buffer), bufUsed(buffer), this->pub.buffer + strSize(this));
|
||||
|
||||
// Update size/extra
|
||||
this->size += (unsigned int)encodeSize;
|
||||
this->extra -= (unsigned int)encodeSize;
|
||||
this->pub.size += (unsigned int)encodeSize;
|
||||
this->pub.extra -= (unsigned int)encodeSize;
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
@ -475,11 +487,11 @@ strCatFmt(String *this, const char *format, ...)
|
||||
|
||||
// Append the formatted string
|
||||
va_start(argumentList, format);
|
||||
vsnprintf(this->buffer + this->size, sizeGrow + 1, format, argumentList);
|
||||
vsnprintf(this->pub.buffer + strSize(this), sizeGrow + 1, format, argumentList);
|
||||
va_end(argumentList);
|
||||
|
||||
this->size += (unsigned int)sizeGrow;
|
||||
this->extra -= (unsigned int)sizeGrow;
|
||||
this->pub.size += (unsigned int)sizeGrow;
|
||||
this->pub.extra -= (unsigned int)sizeGrow;
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
@ -573,8 +585,8 @@ strEndsWithZ(const String *this, const char *endsWith)
|
||||
bool result = false;
|
||||
unsigned int endsWithSize = (unsigned int)strlen(endsWith);
|
||||
|
||||
if (this->size >= endsWithSize)
|
||||
result = strcmp(strZ(this) + (this->size - endsWithSize), endsWith) == 0;
|
||||
if (strSize(this) >= endsWithSize)
|
||||
result = strcmp(strZ(this) + (strSize(this) - endsWithSize), endsWith) == 0;
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
}
|
||||
@ -595,7 +607,7 @@ strEq(const String *this, const String *compare)
|
||||
|
||||
if (this != NULL && compare != NULL)
|
||||
{
|
||||
if (this->size == compare->size)
|
||||
if (strSize(this) == strSize(compare))
|
||||
result = strcmp(strZ(this), strZ(compare)) == 0;
|
||||
}
|
||||
else
|
||||
@ -628,8 +640,8 @@ strFirstUpper(String *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
if (this->size > 0)
|
||||
this->buffer[0] = (char)toupper(this->buffer[0]);
|
||||
if (strSize(this) > 0)
|
||||
this->pub.buffer[0] = (char)toupper(this->pub.buffer[0]);
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
@ -644,8 +656,8 @@ strFirstLower(String *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
if (this->size > 0)
|
||||
this->buffer[0] = (char)tolower(this->buffer[0]);
|
||||
if (strSize(this) > 0)
|
||||
this->pub.buffer[0] = (char)tolower(this->pub.buffer[0]);
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
@ -660,9 +672,9 @@ strUpper(String *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
if (this->size > 0)
|
||||
for (unsigned int idx = 0; idx <= this->size; idx++)
|
||||
this->buffer[idx] = (char)toupper(this->buffer[idx]);
|
||||
if (strSize(this) > 0)
|
||||
for (size_t idx = 0; idx <= strSize(this); idx++)
|
||||
this->pub.buffer[idx] = (char)toupper(this->pub.buffer[idx]);
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
@ -677,9 +689,9 @@ strLower(String *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
if (this->size > 0)
|
||||
for (unsigned int idx = 0; idx <= this->size; idx++)
|
||||
this->buffer[idx] = (char)tolower(this->buffer[idx]);
|
||||
if (strSize(this) > 0)
|
||||
for (size_t idx = 0; idx <= strSize(this); idx++)
|
||||
this->pub.buffer[idx] = (char)tolower(this->pub.buffer[idx]);
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
}
|
||||
@ -694,15 +706,15 @@ strPath(const String *this)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
const char *end = this->buffer + this->size;
|
||||
const char *end = this->pub.buffer + strSize(this);
|
||||
|
||||
while (end > this->buffer && *(end - 1) != '/')
|
||||
while (end > this->pub.buffer && *(end - 1) != '/')
|
||||
end--;
|
||||
|
||||
FUNCTION_TEST_RETURN(
|
||||
strNewN(
|
||||
this->buffer,
|
||||
end - this->buffer <= 1 ? (size_t)(end - this->buffer) : (size_t)(end - this->buffer - 1)));
|
||||
this->pub.buffer,
|
||||
end - this->pub.buffer <= 1 ? (size_t)(end - this->pub.buffer) : (size_t)(end - this->pub.buffer - 1)));
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
@ -797,7 +809,7 @@ strZNull(const String *this)
|
||||
FUNCTION_TEST_PARAM(STRING, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
FUNCTION_TEST_RETURN(this == NULL ? NULL : this->buffer);
|
||||
FUNCTION_TEST_RETURN(this == NULL ? NULL : strZ(this));
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
@ -841,10 +853,10 @@ strReplaceChr(String *this, char find, char replace)
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
for (unsigned int stringIdx = 0; stringIdx < this->size; stringIdx++)
|
||||
for (size_t stringIdx = 0; stringIdx < strSize(this); stringIdx++)
|
||||
{
|
||||
if (this->buffer[stringIdx] == find)
|
||||
this->buffer[stringIdx] = replace;
|
||||
if (this->pub.buffer[stringIdx] == find)
|
||||
this->pub.buffer[stringIdx] = replace;
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(this);
|
||||
@ -860,9 +872,9 @@ strSub(const String *this, size_t start)
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(start <= this->size);
|
||||
ASSERT(start <= this->pub.size);
|
||||
|
||||
FUNCTION_TEST_RETURN(strSubN(this, start, this->size - start));
|
||||
FUNCTION_TEST_RETURN(strSubN(this, start, strSize(this) - start));
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
@ -876,10 +888,10 @@ strSubN(const String *this, size_t start, size_t size)
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(start <= this->size);
|
||||
ASSERT(start + size <= this->size);
|
||||
ASSERT(start <= strSize(this));
|
||||
ASSERT(start + size <= strSize(this));
|
||||
|
||||
FUNCTION_TEST_RETURN(strNewN(this->buffer + start, size));
|
||||
FUNCTION_TEST_RETURN(strNewN(strZ(this) + start, size));
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
@ -893,16 +905,16 @@ strTrim(String *this)
|
||||
ASSERT(this != NULL);
|
||||
|
||||
// Nothing to trim if size is zero
|
||||
if (this->size > 0)
|
||||
if (strSize(this) > 0)
|
||||
{
|
||||
// Find the beginning of the string skipping all whitespace
|
||||
char *begin = this->buffer;
|
||||
char *begin = this->pub.buffer;
|
||||
|
||||
while (*begin != 0 && (*begin == ' ' || *begin == '\t' || *begin == '\r' || *begin == '\n'))
|
||||
begin++;
|
||||
|
||||
// Find the end of the string skipping all whitespace
|
||||
char *end = this->buffer + (this->size - 1);
|
||||
char *end = this->pub.buffer + (strSize(this) - 1);
|
||||
|
||||
while (end > begin && (*end == ' ' || *end == '\t' || *end == '\r' || *end == '\n'))
|
||||
end--;
|
||||
@ -910,20 +922,20 @@ strTrim(String *this)
|
||||
// Is there anything to trim?
|
||||
size_t newSize = (size_t)(end - begin + 1);
|
||||
|
||||
if (begin != this->buffer || newSize < strSize(this))
|
||||
if (begin != this->pub.buffer || newSize < strSize(this))
|
||||
{
|
||||
// Calculate new size
|
||||
this->size = (unsigned int)newSize;
|
||||
this->pub.size = (unsigned int)newSize;
|
||||
|
||||
// Move the substr to the beginning of the buffer
|
||||
memmove(this->buffer, begin, this->size);
|
||||
this->buffer[this->size] = 0;
|
||||
this->extra = 0;
|
||||
memmove(this->pub.buffer, begin, strSize(this));
|
||||
this->pub.buffer[strSize(this)] = 0;
|
||||
this->pub.extra = 0;
|
||||
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
// Resize the buffer
|
||||
this->buffer = memResize(this->buffer, this->size + 1);
|
||||
this->pub.buffer = memResize(this->pub.buffer, strSize(this) + 1);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
@ -945,12 +957,12 @@ strChr(const String *this, char chr)
|
||||
|
||||
int result = -1;
|
||||
|
||||
if (this->size > 0)
|
||||
if (strSize(this) > 0)
|
||||
{
|
||||
const char *ptr = strchr(this->buffer, chr);
|
||||
const char *ptr = strchr(this->pub.buffer, chr);
|
||||
|
||||
if (ptr != NULL)
|
||||
result = (int)(ptr - this->buffer);
|
||||
result = (int)(ptr - this->pub.buffer);
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
@ -965,19 +977,19 @@ strTrunc(String *this, int idx)
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(idx >= 0 && (size_t)idx <= this->size);
|
||||
ASSERT(idx >= 0 && (size_t)idx <= strSize(this));
|
||||
|
||||
if (this->size > 0)
|
||||
if (strSize(this) > 0)
|
||||
{
|
||||
// Reset the size to end at the index
|
||||
this->size = (unsigned int)(idx);
|
||||
this->buffer[this->size] = 0;
|
||||
this->extra = 0;
|
||||
this->pub.size = (unsigned int)(idx);
|
||||
this->pub.buffer[strSize(this)] = 0;
|
||||
this->pub.extra = 0;
|
||||
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
// Resize the buffer
|
||||
this->buffer = memResize(this->buffer, this->size + 1);
|
||||
this->pub.buffer = memResize(this->pub.buffer, strSize(this) + 1);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
@ -1060,7 +1072,7 @@ strFree(String *this)
|
||||
{
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
memFree(this->buffer);
|
||||
memFree(this->pub.buffer);
|
||||
memFree(this);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
@ -39,22 +39,6 @@ typedef struct String String;
|
||||
#include "common/encode.h"
|
||||
#include "common/type/buffer.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Fields that are common between dynamically allocated and constant strings
|
||||
|
||||
There is nothing user-accessible here but this construct allows constant strings to be created and then handled by the same
|
||||
functions that process dynamically allocated strings.
|
||||
***********************************************************************************************************************************/
|
||||
#define STRING_COMMON \
|
||||
uint64_t size:32; /* Actual size of the string */ \
|
||||
uint64_t extra:32; /* Extra space allocated for expansion */ \
|
||||
char *buffer; /* String buffer */
|
||||
|
||||
typedef struct StringConst
|
||||
{
|
||||
STRING_COMMON
|
||||
} StringConst;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Constructors
|
||||
***********************************************************************************************************************************/
|
||||
@ -81,6 +65,32 @@ String *strNewN(const char *string, size_t size);
|
||||
// Duplicate a string
|
||||
String *strDup(const String *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters/setters
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct StringPub
|
||||
{
|
||||
uint64_t size:32; // Actual size of the string
|
||||
uint64_t extra:32; // Extra space allocated for expansion
|
||||
char *buffer; // String buffer
|
||||
} StringPub;
|
||||
|
||||
// String size minus null-terminator, i.e. the same value that strlen() would return
|
||||
__attribute__((always_inline)) static inline size_t
|
||||
strSize(const String *this)
|
||||
{
|
||||
return THIS_PUB(String)->size;
|
||||
}
|
||||
|
||||
// Pointer to zero-terminated string. strZNull() returns NULL when the String is NULL.
|
||||
__attribute__((always_inline)) static inline const char *
|
||||
strZ(const String *this)
|
||||
{
|
||||
return THIS_PUB(String)->buffer;
|
||||
}
|
||||
|
||||
const char *strZNull(const String *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
@ -146,16 +156,6 @@ String *strPath(const String *this);
|
||||
// Combine with a base path to get an absolute path
|
||||
String *strPathAbsolute(const String *this, const String *base);
|
||||
|
||||
// Pointer to zero-terminated string. strZNull() returns NULL when the String is NULL.
|
||||
__attribute__((always_inline)) static inline const char *
|
||||
strZ(const String *const this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return ((const StringConst *)this)->buffer;
|
||||
}
|
||||
|
||||
const char *strZNull(const String *this);
|
||||
|
||||
// Quote a string
|
||||
String *strQuote(const String *this, const String *quote);
|
||||
String *strQuoteZ(const String *this, const char *quote);
|
||||
@ -163,14 +163,6 @@ String *strQuoteZ(const String *this, const char *quote);
|
||||
// Replace a character with another character
|
||||
String *strReplaceChr(String *this, char find, char replace);
|
||||
|
||||
// String size minus null-terminator, i.e. the same value that strlen() would return
|
||||
__attribute__((always_inline)) static inline size_t
|
||||
strSize(const String *const this)
|
||||
{
|
||||
ASSERT_INLINE(this != NULL);
|
||||
return ((const StringConst *)this)->size;
|
||||
}
|
||||
|
||||
// Format sizes (file, buffer, etc.) in human-readable form
|
||||
String *strSizeFormat(const uint64_t fileSize);
|
||||
|
||||
@ -203,11 +195,11 @@ By convention all string constant identifiers are appended with _STR.
|
||||
***********************************************************************************************************************************/
|
||||
// Create a String constant inline from any zero-terminated string
|
||||
#define STR(bufferParam) \
|
||||
((const String *)&(const StringConst){.buffer = (char *)(bufferParam), .size = (unsigned int)strlen(bufferParam)})
|
||||
((const String *)&(const StringPub){.buffer = (char *)(bufferParam), .size = (unsigned int)strlen(bufferParam)})
|
||||
|
||||
// Create a String constant inline from a #define or inline string constant
|
||||
#define STRDEF(bufferParam) \
|
||||
((const String *)&(const StringConst){.buffer = (char *)(bufferParam), .size = (unsigned int)sizeof(bufferParam) - 1})
|
||||
((const String *)&(const StringPub){.buffer = (char *)(bufferParam), .size = (unsigned int)sizeof(bufferParam) - 1})
|
||||
|
||||
// Used to declare String constants that will be externed using STRING_DECLARE(). Must be used in a .c file.
|
||||
#define STRING_EXTERN(name, buffer) \
|
||||
|
@ -21,7 +21,7 @@ Constant variants that are generally useful
|
||||
***********************************************************************************************************************************/
|
||||
// Used to declare Bool Variant constants that will be externed using VARIANT_DECLARE(). Must be used in a .c file.
|
||||
#define VARIANT_BOOL_EXTERN(name, dataParam) \
|
||||
const Variant *const name = ((const Variant *)&(const VariantBoolConst){.type = varTypeBool, .data = dataParam})
|
||||
const Variant *const name = ((const Variant *)&(const VariantBoolPub){.type = varTypeBool, .data = dataParam})
|
||||
|
||||
VARIANT_BOOL_EXTERN(BOOL_FALSE_VAR, false);
|
||||
VARIANT_BOOL_EXTERN(BOOL_TRUE_VAR, true);
|
||||
@ -31,62 +31,56 @@ Information about the variant
|
||||
***********************************************************************************************************************************/
|
||||
struct Variant
|
||||
{
|
||||
VARIANT_COMMON
|
||||
VariantPub pub; // Publicly accessible variables
|
||||
};
|
||||
|
||||
typedef struct VariantBool
|
||||
{
|
||||
VARIANT_COMMON
|
||||
VARIANT_BOOL_COMMON
|
||||
VariantBoolPub pub; // Publicly accessible variables
|
||||
MemContext *memContext;
|
||||
} VariantBool;
|
||||
|
||||
typedef struct VariantInt
|
||||
{
|
||||
VARIANT_COMMON
|
||||
VARIANT_INT_COMMON
|
||||
VariantIntPub pub; // Publicly accessible variables
|
||||
MemContext *memContext;
|
||||
} VariantInt;
|
||||
|
||||
typedef struct VariantInt64
|
||||
{
|
||||
VARIANT_COMMON
|
||||
VARIANT_INT64_COMMON
|
||||
VariantInt64Pub pub; // Publicly accessible variables
|
||||
MemContext *memContext;
|
||||
} VariantInt64;
|
||||
|
||||
typedef struct VariantKeyValue
|
||||
{
|
||||
VARIANT_COMMON
|
||||
KeyValue *data; /* KeyValue data */
|
||||
KeyValue *data; // KeyValue data
|
||||
MemContext *memContext;
|
||||
} VariantKeyValue;
|
||||
|
||||
typedef struct VariantString
|
||||
{
|
||||
VARIANT_COMMON
|
||||
VARIANT_STRING_COMMON
|
||||
VariantStringPub pub; // Publicly accessible variables
|
||||
MemContext *memContext;
|
||||
} VariantString;
|
||||
|
||||
typedef struct VariantUInt
|
||||
{
|
||||
VARIANT_COMMON
|
||||
VARIANT_UINT_COMMON
|
||||
VariantUIntPub pub; // Publicly accessible variables
|
||||
MemContext *memContext;
|
||||
} VariantUInt;
|
||||
|
||||
typedef struct VariantUInt64
|
||||
{
|
||||
VARIANT_COMMON
|
||||
VARIANT_UINT64_COMMON
|
||||
VariantUInt64Pub pub; // Publicly accessible variables
|
||||
MemContext *memContext;
|
||||
} VariantUInt64;
|
||||
|
||||
typedef struct VariantVariantList
|
||||
{
|
||||
VARIANT_COMMON
|
||||
VariantList *data; /* VariantList data */
|
||||
VariantList *data; // VariantList data
|
||||
MemContext *memContext;
|
||||
} VariantVariantList;
|
||||
|
||||
@ -117,7 +111,7 @@ varDup(const Variant *this)
|
||||
|
||||
if (this != NULL)
|
||||
{
|
||||
switch (this->type)
|
||||
switch (varType(this))
|
||||
{
|
||||
case varTypeBool:
|
||||
result = varNewBool(varBool(this));
|
||||
@ -211,7 +205,7 @@ varEq(const Variant *this1, const Variant *this2)
|
||||
break;
|
||||
|
||||
default:
|
||||
THROW_FMT(AssertError, "unable to test equality for %s", variantTypeName[this1->type]);
|
||||
THROW_FMT(AssertError, "unable to test equality for %s", variantTypeName[varType(this1)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -222,19 +216,6 @@ varEq(const Variant *this1, const Variant *this2)
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
VariantType
|
||||
varType(const Variant *this)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(VARIANT, this);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
|
||||
FUNCTION_TEST_RETURN(this->type);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
Variant *
|
||||
varNewBool(bool data)
|
||||
@ -248,9 +229,12 @@ varNewBool(bool data)
|
||||
|
||||
*this = (VariantBool)
|
||||
{
|
||||
.pub =
|
||||
{
|
||||
.type = varTypeBool,
|
||||
.data = data,
|
||||
},
|
||||
.memContext = memContextCurrent(),
|
||||
.type = varTypeBool,
|
||||
.data = data,
|
||||
};
|
||||
|
||||
FUNCTION_TEST_RETURN((Variant *)this);
|
||||
@ -265,9 +249,9 @@ varBool(const Variant *this)
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(this->type == varTypeBool);
|
||||
ASSERT(varType(this) == varTypeBool);
|
||||
|
||||
FUNCTION_TEST_RETURN(((VariantBool *)this)->data);
|
||||
FUNCTION_TEST_RETURN(((VariantBool *)this)->pub.data);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -281,7 +265,7 @@ varBoolForce(const Variant *this)
|
||||
|
||||
bool result = false;
|
||||
|
||||
switch (this->type)
|
||||
switch (varType(this))
|
||||
{
|
||||
case varTypeBool:
|
||||
result = varBool(this);
|
||||
@ -331,7 +315,7 @@ varBoolForce(const Variant *this)
|
||||
break;
|
||||
|
||||
default:
|
||||
THROW_FMT(AssertError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeBool]);
|
||||
THROW_FMT(AssertError, "unable to force %s to %s", variantTypeName[varType(this)], variantTypeName[varTypeBool]);
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
@ -350,9 +334,12 @@ varNewInt(int data)
|
||||
|
||||
*this = (VariantInt)
|
||||
{
|
||||
.pub =
|
||||
{
|
||||
.type = varTypeInt,
|
||||
.data = data,
|
||||
},
|
||||
.memContext = memContextCurrent(),
|
||||
.type = varTypeInt,
|
||||
.data = data,
|
||||
};
|
||||
|
||||
FUNCTION_TEST_RETURN((Variant *)this);
|
||||
@ -367,9 +354,9 @@ varInt(const Variant *this)
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(this->type == varTypeInt);
|
||||
ASSERT(varType(this) == varTypeInt);
|
||||
|
||||
FUNCTION_TEST_RETURN(((VariantInt *)this)->data);
|
||||
FUNCTION_TEST_RETURN(((VariantInt *)this)->pub.data);
|
||||
}
|
||||
|
||||
int
|
||||
@ -383,7 +370,7 @@ varIntForce(const Variant *this)
|
||||
|
||||
int result = 0;
|
||||
|
||||
switch (this->type)
|
||||
switch (varType(this))
|
||||
{
|
||||
case varTypeBool:
|
||||
result = varBool(this);
|
||||
@ -400,7 +387,7 @@ varIntForce(const Variant *this)
|
||||
// Make sure the value fits into a normal 32-bit int range since 32-bit platforms are supported
|
||||
if (resultTest > INT32_MAX || resultTest < INT32_MIN)
|
||||
THROW_FMT(
|
||||
FormatError, "unable to convert %s %" PRId64 " to %s", variantTypeName[this->type], resultTest,
|
||||
FormatError, "unable to convert %s %" PRId64 " to %s", variantTypeName[varType(this)], resultTest,
|
||||
variantTypeName[varTypeInt]);
|
||||
|
||||
result = (int)resultTest;
|
||||
@ -418,7 +405,7 @@ varIntForce(const Variant *this)
|
||||
// Make sure the value fits into a normal 32-bit int range
|
||||
if (resultTest > INT32_MAX)
|
||||
THROW_FMT(
|
||||
FormatError, "unable to convert %s %u to %s", variantTypeName[this->type], resultTest,
|
||||
FormatError, "unable to convert %s %u to %s", variantTypeName[varType(this)], resultTest,
|
||||
variantTypeName[varTypeInt]);
|
||||
|
||||
result = (int)resultTest;
|
||||
@ -432,7 +419,7 @@ varIntForce(const Variant *this)
|
||||
// Make sure the value fits into a normal 32-bit int range
|
||||
if (resultTest > INT32_MAX)
|
||||
THROW_FMT(
|
||||
FormatError, "unable to convert %s %" PRIu64 " to %s", variantTypeName[this->type], resultTest,
|
||||
FormatError, "unable to convert %s %" PRIu64 " to %s", variantTypeName[varType(this)], resultTest,
|
||||
variantTypeName[varTypeInt]);
|
||||
|
||||
result = (int)resultTest;
|
||||
@ -440,7 +427,7 @@ varIntForce(const Variant *this)
|
||||
}
|
||||
|
||||
default:
|
||||
THROW_FMT(AssertError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeInt]);
|
||||
THROW_FMT(AssertError, "unable to force %s to %s", variantTypeName[varType(this)], variantTypeName[varTypeInt]);
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
@ -459,9 +446,12 @@ varNewInt64(int64_t data)
|
||||
|
||||
*this = (VariantInt64)
|
||||
{
|
||||
.pub =
|
||||
{
|
||||
.type = varTypeInt64,
|
||||
.data = data,
|
||||
},
|
||||
.memContext = memContextCurrent(),
|
||||
.type = varTypeInt64,
|
||||
.data = data,
|
||||
};
|
||||
|
||||
FUNCTION_TEST_RETURN((Variant *)this);
|
||||
@ -476,9 +466,9 @@ varInt64(const Variant *this)
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(this->type == varTypeInt64);
|
||||
ASSERT(varType(this) == varTypeInt64);
|
||||
|
||||
FUNCTION_TEST_RETURN(((VariantInt64 *)this)->data);
|
||||
FUNCTION_TEST_RETURN(((VariantInt64 *)this)->pub.data);
|
||||
}
|
||||
|
||||
int64_t
|
||||
@ -492,7 +482,7 @@ varInt64Force(const Variant *this)
|
||||
|
||||
int64_t result = 0;
|
||||
|
||||
switch (this->type)
|
||||
switch (varType(this))
|
||||
{
|
||||
case varTypeBool:
|
||||
result = varBool(this);
|
||||
@ -525,7 +515,7 @@ varInt64Force(const Variant *this)
|
||||
else
|
||||
{
|
||||
THROW_FMT(
|
||||
FormatError, "unable to convert %s %" PRIu64 " to %s", variantTypeName[this->type], resultTest,
|
||||
FormatError, "unable to convert %s %" PRIu64 " to %s", variantTypeName[varType(this)], resultTest,
|
||||
variantTypeName[varTypeInt64]);
|
||||
}
|
||||
|
||||
@ -533,7 +523,7 @@ varInt64Force(const Variant *this)
|
||||
}
|
||||
|
||||
default:
|
||||
THROW_FMT(AssertError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeInt64]);
|
||||
THROW_FMT(AssertError, "unable to force %s to %s", variantTypeName[varType(this)], variantTypeName[varTypeInt64]);
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
@ -552,9 +542,12 @@ varNewUInt(unsigned int data)
|
||||
|
||||
*this = (VariantUInt)
|
||||
{
|
||||
.pub =
|
||||
{
|
||||
.type = varTypeUInt,
|
||||
.data = data,
|
||||
},
|
||||
.memContext = memContextCurrent(),
|
||||
.type = varTypeUInt,
|
||||
.data = data,
|
||||
};
|
||||
|
||||
FUNCTION_TEST_RETURN((Variant *)this);
|
||||
@ -569,9 +562,9 @@ varUInt(const Variant *this)
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(this->type == varTypeUInt);
|
||||
ASSERT(varType(this) == varTypeUInt);
|
||||
|
||||
FUNCTION_TEST_RETURN(((VariantUInt *)this)->data);
|
||||
FUNCTION_TEST_RETURN(((VariantUInt *)this)->pub.data);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
@ -585,7 +578,7 @@ varUIntForce(const Variant *this)
|
||||
|
||||
unsigned int result = 0;
|
||||
|
||||
switch (this->type)
|
||||
switch (varType(this))
|
||||
{
|
||||
case varTypeBool:
|
||||
result = varBool(this);
|
||||
@ -601,7 +594,7 @@ varUIntForce(const Variant *this)
|
||||
else
|
||||
{
|
||||
THROW_FMT(
|
||||
FormatError, "unable to convert %s %d to %s", variantTypeName[this->type], resultTest,
|
||||
FormatError, "unable to convert %s %d to %s", variantTypeName[varType(this)], resultTest,
|
||||
variantTypeName[varTypeUInt]);
|
||||
}
|
||||
|
||||
@ -618,7 +611,7 @@ varUIntForce(const Variant *this)
|
||||
else
|
||||
{
|
||||
THROW_FMT(
|
||||
FormatError, "unable to convert %s %" PRId64 " to %s", variantTypeName[this->type], resultTest,
|
||||
FormatError, "unable to convert %s %" PRId64 " to %s", variantTypeName[varType(this)], resultTest,
|
||||
variantTypeName[varTypeUInt]);
|
||||
}
|
||||
|
||||
@ -639,7 +632,7 @@ varUIntForce(const Variant *this)
|
||||
else
|
||||
{
|
||||
THROW_FMT(
|
||||
FormatError, "unable to convert %s %" PRIu64 " to %s", variantTypeName[this->type], resultTest,
|
||||
FormatError, "unable to convert %s %" PRIu64 " to %s", variantTypeName[varType(this)], resultTest,
|
||||
variantTypeName[varTypeUInt]);
|
||||
}
|
||||
|
||||
@ -651,7 +644,7 @@ varUIntForce(const Variant *this)
|
||||
break;
|
||||
|
||||
default:
|
||||
THROW_FMT(AssertError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeUInt]);
|
||||
THROW_FMT(AssertError, "unable to force %s to %s", variantTypeName[varType(this)], variantTypeName[varTypeUInt]);
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
@ -670,9 +663,12 @@ varNewUInt64(uint64_t data)
|
||||
|
||||
*this = (VariantUInt64)
|
||||
{
|
||||
.pub =
|
||||
{
|
||||
.type = varTypeUInt64,
|
||||
.data = data,
|
||||
},
|
||||
.memContext = memContextCurrent(),
|
||||
.type = varTypeUInt64,
|
||||
.data = data,
|
||||
};
|
||||
|
||||
FUNCTION_TEST_RETURN((Variant *)this);
|
||||
@ -687,9 +683,9 @@ varUInt64(const Variant *this)
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
ASSERT(this != NULL);
|
||||
ASSERT(this->type == varTypeUInt64);
|
||||
ASSERT(varType(this) == varTypeUInt64);
|
||||
|
||||
FUNCTION_TEST_RETURN(((VariantUInt64 *)this)->data);
|
||||
FUNCTION_TEST_RETURN(((VariantUInt64 *)this)->pub.data);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
@ -703,7 +699,7 @@ varUInt64Force(const Variant *this)
|
||||
|
||||
uint64_t result = 0;
|
||||
|
||||
switch (this->type)
|
||||
switch (varType(this))
|
||||
{
|
||||
case varTypeBool:
|
||||
result = varBool(this);
|
||||
@ -719,7 +715,7 @@ varUInt64Force(const Variant *this)
|
||||
else
|
||||
{
|
||||
THROW_FMT(
|
||||
FormatError, "unable to convert %s %d to %s", variantTypeName[this->type], resultTest,
|
||||
FormatError, "unable to convert %s %d to %s", variantTypeName[varType(this)], resultTest,
|
||||
variantTypeName[varTypeUInt64]);
|
||||
}
|
||||
|
||||
@ -736,7 +732,7 @@ varUInt64Force(const Variant *this)
|
||||
else
|
||||
{
|
||||
THROW_FMT(
|
||||
FormatError, "unable to convert %s %" PRId64 " to %s", variantTypeName[this->type], resultTest,
|
||||
FormatError, "unable to convert %s %" PRId64 " to %s", variantTypeName[varType(this)], resultTest,
|
||||
variantTypeName[varTypeUInt64]);
|
||||
}
|
||||
|
||||
@ -756,7 +752,7 @@ varUInt64Force(const Variant *this)
|
||||
break;
|
||||
|
||||
default:
|
||||
THROW_FMT(AssertError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeUInt64]);
|
||||
THROW_FMT(AssertError, "unable to force %s to %s", variantTypeName[varType(this)], variantTypeName[varTypeUInt64]);
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
@ -797,7 +793,7 @@ varKv(const Variant *this)
|
||||
|
||||
if (this != NULL)
|
||||
{
|
||||
ASSERT(this->type == varTypeKeyValue);
|
||||
ASSERT(varType(this) == varTypeKeyValue);
|
||||
result = ((VariantKeyValue *)this)->data;
|
||||
}
|
||||
|
||||
@ -817,9 +813,12 @@ varNewStr(const String *data)
|
||||
|
||||
*this = (VariantString)
|
||||
{
|
||||
.pub =
|
||||
{
|
||||
.type = varTypeString,
|
||||
.data = strDup(data),
|
||||
},
|
||||
.memContext = memContextCurrent(),
|
||||
.type = varTypeString,
|
||||
.data = strDup(data),
|
||||
};
|
||||
|
||||
FUNCTION_TEST_RETURN((Variant *)this);
|
||||
@ -847,8 +846,8 @@ varStr(const Variant *this)
|
||||
|
||||
if (this != NULL)
|
||||
{
|
||||
ASSERT(this->type == varTypeString);
|
||||
result = ((VariantString *)this)->data;
|
||||
ASSERT(varType(this) == varTypeString);
|
||||
result = ((VariantString *)this)->pub.data;
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
@ -912,7 +911,7 @@ varStrForce(const Variant *this)
|
||||
}
|
||||
|
||||
default:
|
||||
THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[this->type], variantTypeName[varTypeString]);
|
||||
THROW_FMT(FormatError, "unable to force %s to %s", variantTypeName[varType(this)], variantTypeName[varTypeString]);
|
||||
}
|
||||
|
||||
FUNCTION_TEST_RETURN(result);
|
||||
@ -953,7 +952,7 @@ varVarLst(const Variant *this)
|
||||
|
||||
if (this != NULL)
|
||||
{
|
||||
ASSERT(this->type == varTypeVariantList);
|
||||
ASSERT(varType(this) == varTypeVariantList);
|
||||
result = ((VariantVariantList *)this)->data;
|
||||
}
|
||||
|
||||
@ -1011,7 +1010,7 @@ varFree(Variant *this)
|
||||
{
|
||||
MemContext *memContext = NULL;
|
||||
|
||||
switch (this->type)
|
||||
switch (varType(this))
|
||||
{
|
||||
case varTypeBool:
|
||||
memContext = ((VariantBool *)this)->memContext;
|
||||
@ -1032,7 +1031,7 @@ varFree(Variant *this)
|
||||
|
||||
case varTypeString:
|
||||
memContext = ((VariantString *)this)->memContext;
|
||||
strFree(((VariantString *)this)->data);
|
||||
strFree(((VariantString *)this)->pub.data);
|
||||
break;
|
||||
|
||||
case varTypeUInt:
|
||||
|
@ -66,18 +66,53 @@ Variant *varNewVarLst(const VariantList *data);
|
||||
|
||||
Variant *varDup(const Variant *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
// Test if Variants are equal
|
||||
bool varEq(const Variant *this1, const Variant *this2);
|
||||
|
||||
// Variant type
|
||||
VariantType varType(const Variant *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Getters/Setters
|
||||
***********************************************************************************************************************************/
|
||||
#define VARIANT_COMMON \
|
||||
VariantType type; /* Variant type */
|
||||
|
||||
typedef struct VariantPub
|
||||
{
|
||||
VARIANT_COMMON
|
||||
} VariantPub;
|
||||
|
||||
typedef struct VariantBoolPub
|
||||
{
|
||||
VARIANT_COMMON
|
||||
bool data; // Boolean data
|
||||
} VariantBoolPub;
|
||||
|
||||
typedef struct VariantIntPub
|
||||
{
|
||||
VARIANT_COMMON
|
||||
int data; // Signed integer data
|
||||
} VariantIntPub;
|
||||
|
||||
typedef struct VariantInt64Pub
|
||||
{
|
||||
VARIANT_COMMON
|
||||
int64_t data; // 64-bit signed integer data
|
||||
} VariantInt64Pub;
|
||||
|
||||
typedef struct VariantStringPub
|
||||
{
|
||||
VARIANT_COMMON
|
||||
String *data; // String data
|
||||
} VariantStringPub;
|
||||
|
||||
typedef struct VariantUIntPub
|
||||
{
|
||||
VARIANT_COMMON
|
||||
unsigned int data; // Unsigned integer data
|
||||
} VariantUIntPub;
|
||||
|
||||
typedef struct VariantUInt64Pub
|
||||
{
|
||||
VARIANT_COMMON
|
||||
uint64_t data; // 64-bit unsigned integer data
|
||||
} VariantUInt64Pub;
|
||||
|
||||
bool varBool(const Variant *this);
|
||||
bool varBoolForce(const Variant *this);
|
||||
|
||||
@ -100,74 +135,24 @@ uint64_t varUInt64Force(const Variant *this);
|
||||
|
||||
VariantList *varVarLst(const Variant *this);
|
||||
|
||||
// Variant type
|
||||
__attribute__((always_inline)) static inline VariantType
|
||||
varType(const Variant *const this)
|
||||
{
|
||||
return THIS_PUB(Variant)->type;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
// Test if Variants are equal
|
||||
bool varEq(const Variant *this1, const Variant *this2);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Destructor
|
||||
***********************************************************************************************************************************/
|
||||
void varFree(Variant *this);
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Fields that are common between dynamically allocated and constant variants
|
||||
|
||||
There is nothing user-accessible here but this construct allows constant variants to be created and then handled by the same
|
||||
functions that process dynamically allocated variants.
|
||||
***********************************************************************************************************************************/
|
||||
#define VARIANT_COMMON \
|
||||
VariantType type; /* Variant type */
|
||||
|
||||
#define VARIANT_BOOL_COMMON \
|
||||
bool data; /* Boolean data */
|
||||
|
||||
typedef struct VariantBoolConst
|
||||
{
|
||||
VARIANT_COMMON
|
||||
const VARIANT_BOOL_COMMON
|
||||
} VariantBoolConst;
|
||||
|
||||
#define VARIANT_INT_COMMON \
|
||||
int data; /* Signed integer data */
|
||||
|
||||
typedef struct VariantIntConst
|
||||
{
|
||||
VARIANT_COMMON
|
||||
const VARIANT_INT_COMMON
|
||||
} VariantIntConst;
|
||||
|
||||
#define VARIANT_INT64_COMMON \
|
||||
int64_t data; /* 64-bit signed integer data */
|
||||
|
||||
typedef struct VariantInt64Const
|
||||
{
|
||||
VARIANT_COMMON
|
||||
const VARIANT_INT64_COMMON
|
||||
} VariantInt64Const;
|
||||
|
||||
#define VARIANT_STRING_COMMON \
|
||||
String *data; /* String data */
|
||||
|
||||
typedef struct VariantStringConst
|
||||
{
|
||||
VARIANT_COMMON
|
||||
const VARIANT_STRING_COMMON
|
||||
} VariantStringConst;
|
||||
|
||||
#define VARIANT_UINT_COMMON \
|
||||
unsigned int data; /* unsigned integer data */
|
||||
|
||||
typedef struct VariantUIntConst
|
||||
{
|
||||
VARIANT_COMMON
|
||||
const VARIANT_UINT_COMMON
|
||||
} VariantUIntConst;
|
||||
|
||||
#define VARIANT_UINT64_COMMON \
|
||||
uint64_t data; /* 64-bit unsigned integer data */
|
||||
|
||||
typedef struct VariantUInt64Const
|
||||
{
|
||||
VARIANT_COMMON
|
||||
const VARIANT_UINT64_COMMON
|
||||
} VariantUInt64Const;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Macros for constant variants
|
||||
|
||||
@ -180,27 +165,27 @@ By convention all variant constant identifiers are appended with _VAR.
|
||||
***********************************************************************************************************************************/
|
||||
// Create a Bool Variant constant inline from a bool
|
||||
#define VARBOOL(dataParam) \
|
||||
((const Variant *)&(const VariantBoolConst){.type = varTypeBool, .data = dataParam})
|
||||
((const Variant *)&(const VariantBoolPub){.type = varTypeBool, .data = dataParam})
|
||||
|
||||
// Create an Int Variant constant inline from an int
|
||||
#define VARINT(dataParam) \
|
||||
((const Variant *)&(const VariantIntConst){.type = varTypeInt, .data = dataParam})
|
||||
((const Variant *)&(const VariantIntPub){.type = varTypeInt, .data = dataParam})
|
||||
|
||||
// Create an Int64 Variant constant inline from an int64_t
|
||||
#define VARINT64(dataParam) \
|
||||
((const Variant *)&(const VariantInt64Const){.type = varTypeInt64, .data = dataParam})
|
||||
((const Variant *)&(const VariantInt64Pub){.type = varTypeInt64, .data = dataParam})
|
||||
|
||||
// Create a String Variant constant inline from any zero-terminated string
|
||||
#define VARSTRZ(dataParam) \
|
||||
((const Variant *)&(const VariantStringConst){.type = varTypeString, .data = STR(dataParam)})
|
||||
((const Variant *)&(const VariantStringPub){.type = varTypeString, .data = (String *)STR(dataParam)})
|
||||
|
||||
// Create a String Variant constant inline from a #define or inline string constant
|
||||
#define VARSTRDEF(dataParam) \
|
||||
((const Variant *)&(const VariantStringConst){.type = varTypeString, .data = STRDEF(dataParam)})
|
||||
((const Variant *)&(const VariantStringPub){.type = varTypeString, .data = (String *)STRDEF(dataParam)})
|
||||
|
||||
// Create a String Variant constant inline from a String constant
|
||||
#define VARSTR(dataParam) \
|
||||
((const Variant *)&(const VariantStringConst){.type = varTypeString, .data = dataParam})
|
||||
((const Variant *)&(const VariantStringPub){.type = varTypeString, .data = (String *)(dataParam)})
|
||||
|
||||
// Used to declare String Variant constants that will be externed using VARIANT_DECLARE(). Must be used in a .c file.
|
||||
#define VARIANT_STRDEF_EXTERN(name, dataParam) \
|
||||
@ -212,11 +197,11 @@ By convention all variant constant identifiers are appended with _VAR.
|
||||
|
||||
// Create a UInt Variant constant inline from an unsigned int
|
||||
#define VARUINT(dataParam) \
|
||||
((const Variant *)&(const VariantUIntConst){.type = varTypeUInt, .data = dataParam})
|
||||
((const Variant *)&(const VariantUIntPub){.type = varTypeUInt, .data = dataParam})
|
||||
|
||||
// Create a UInt64 Variant constant inline from a uint64_t
|
||||
#define VARUINT64(dataParam) \
|
||||
((const Variant *)&(const VariantUInt64Const){.type = varTypeUInt64, .data = dataParam})
|
||||
((const Variant *)&(const VariantUInt64Pub){.type = varTypeUInt64, .data = dataParam})
|
||||
|
||||
// Used to extern String Variant constants declared with VARIANT_STRDEF_EXTERN/STATIC(). Must be used in a .h file.
|
||||
#define VARIANT_DECLARE(name) \
|
||||
|
@ -22,7 +22,7 @@ testRun(void)
|
||||
}
|
||||
MEM_CONTEXT_TEMP_END();
|
||||
|
||||
TEST_RESULT_PTR(bufPtr(buffer), buffer->buffer, "buffer pointer");
|
||||
TEST_RESULT_PTR(bufPtr(buffer), buffer->pub.buffer, "buffer pointer");
|
||||
TEST_RESULT_UINT(bufSize(buffer), 256, "buffer size");
|
||||
TEST_RESULT_UINT(bufSizeAlloc(buffer), 256, "buffer allocation size");
|
||||
|
||||
@ -99,7 +99,7 @@ testRun(void)
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("error when used > new limit");
|
||||
|
||||
TEST_ERROR(bufLimitSet(buffer, 64), AssertError, "assertion 'limit >= this->used' failed");
|
||||
TEST_ERROR(bufLimitSet(buffer, 64), AssertError, "assertion 'limit >= bufUsed(this)' failed");
|
||||
TEST_RESULT_VOID(bufUsedSet(buffer, 64), "set used");
|
||||
|
||||
// Use limits to change size reporting
|
||||
|
@ -35,7 +35,7 @@ testRun(void)
|
||||
{
|
||||
// We don't want this struct to grow since there are generally a lot of strings, so make sure it doesn't grow without us
|
||||
// knowing about it
|
||||
TEST_RESULT_UINT(sizeof(StringConst), TEST_64BIT() ? 16 : 12, "check StringConst struct size");
|
||||
TEST_RESULT_UINT(sizeof(StringPub), TEST_64BIT() ? 16 : 12, "check StringConst struct size");
|
||||
|
||||
// Test the size macro
|
||||
TEST_RESULT_VOID(CHECK_SIZE(555), "valid size");
|
||||
@ -77,8 +77,8 @@ testRun(void)
|
||||
TEST_TITLE("empty string is allocated extra space");
|
||||
|
||||
TEST_ASSIGN(string, strNew(""), "new empty string");
|
||||
TEST_RESULT_UINT(string->size, 0, " check size");
|
||||
TEST_RESULT_UINT(string->extra, 64, " check extra");
|
||||
TEST_RESULT_UINT(string->pub.size, 0, " check size");
|
||||
TEST_RESULT_UINT(string->pub.extra, 64, " check extra");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_TITLE("strNewEncode()");
|
||||
@ -126,19 +126,19 @@ testRun(void)
|
||||
String *string2 = strNew("ZZZZ");
|
||||
|
||||
TEST_RESULT_STR_Z(strCat(string, STRDEF("YYYY")), "XXXXYYYY", "cat string");
|
||||
TEST_RESULT_UINT(string->extra, 60, "check extra");
|
||||
TEST_RESULT_UINT(string->pub.extra, 60, "check extra");
|
||||
TEST_RESULT_STR_Z(strCatFmt(string, "%05d", 777), "XXXXYYYY00777", "cat formatted string");
|
||||
TEST_RESULT_UINT(string->extra, 55, "check extra");
|
||||
TEST_RESULT_UINT(string->pub.extra, 55, "check extra");
|
||||
TEST_RESULT_STR_Z(strCatChr(string, '!'), "XXXXYYYY00777!", "cat chr");
|
||||
TEST_RESULT_UINT(string->extra, 54, "check extra");
|
||||
TEST_RESULT_UINT(string->pub.extra, 54, "check extra");
|
||||
TEST_RESULT_STR_Z(
|
||||
strCatZN(string, "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*", 55),
|
||||
"XXXXYYYY00777!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$", "cat chr");
|
||||
TEST_RESULT_UINT(string->extra, 34, "check extra");
|
||||
TEST_RESULT_UINT(string->pub.extra, 34, "check extra");
|
||||
TEST_RESULT_STR_Z(
|
||||
strCatEncode(string, encodeBase64, BUFSTRDEF("zzzzz")),
|
||||
"XXXXYYYY00777!$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$enp6eno=", "cat encode");
|
||||
TEST_RESULT_UINT(string->extra, 26, "check extra");
|
||||
TEST_RESULT_UINT(string->pub.extra, 26, "check extra");
|
||||
|
||||
TEST_RESULT_STR_Z(string2, "ZZZZ", "check unaltered string");
|
||||
}
|
||||
@ -265,8 +265,8 @@ testRun(void)
|
||||
String *val = strNew("abcdef");
|
||||
TEST_ERROR(
|
||||
strTrunc(val, (int)(strSize(val) + 1)), AssertError,
|
||||
"assertion 'idx >= 0 && (size_t)idx <= this->size' failed");
|
||||
TEST_ERROR(strTrunc(val, -1), AssertError, "assertion 'idx >= 0 && (size_t)idx <= this->size' failed");
|
||||
"assertion 'idx >= 0 && (size_t)idx <= strSize(this)' failed");
|
||||
TEST_ERROR(strTrunc(val, -1), AssertError, "assertion 'idx >= 0 && (size_t)idx <= strSize(this)' failed");
|
||||
|
||||
TEST_RESULT_STR_Z(strTrunc(val, strChr(val, 'd')), "abc", "simple string truncated");
|
||||
strCatZ(val, "\r\n to end");
|
||||
|
@ -15,7 +15,7 @@ testRun(void)
|
||||
if (testBegin("bool"))
|
||||
{
|
||||
// Ensure type sizes are as expected
|
||||
TEST_RESULT_UINT(sizeof(VariantBoolConst), 8, "check VariantBoolConst size");
|
||||
TEST_RESULT_UINT(sizeof(VariantBoolPub), 8, "check VariantBoolConst size");
|
||||
TEST_RESULT_UINT(sizeof(VariantBool), TEST_64BIT() ? 16 : 12, "check VariantBool size");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@ -24,7 +24,7 @@ testRun(void)
|
||||
varFree(boolean);
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ERROR(varBool(varNewStrZ("string")), AssertError, "assertion 'this->type == varTypeBool' failed");
|
||||
TEST_ERROR(varBool(varNewStrZ("string")), AssertError, "assertion 'varType(this) == varTypeBool' failed");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_BOOL(varBool(BOOL_TRUE_VAR), true, "true bool variant");
|
||||
@ -56,7 +56,7 @@ testRun(void)
|
||||
if (testBegin("int"))
|
||||
{
|
||||
// Ensure type sizes are as expected
|
||||
TEST_RESULT_UINT(sizeof(VariantIntConst), 8, "check VariantIntConst size");
|
||||
TEST_RESULT_UINT(sizeof(VariantIntPub), 8, "check VariantIntConst size");
|
||||
TEST_RESULT_UINT(sizeof(VariantInt), TEST_64BIT() ? 16 : 12, "check VariantInt size");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@ -77,7 +77,7 @@ testRun(void)
|
||||
TEST_ERROR(varIntForce(VARUINT64(2147483648)), FormatError, "unable to convert uint64 2147483648 to int");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ERROR(varInt(varNewStrZ("string")), AssertError, "assertion 'this->type == varTypeInt' failed");
|
||||
TEST_ERROR(varInt(varNewStrZ("string")), AssertError, "assertion 'varType(this) == varTypeInt' failed");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_INT(varInt(varDup(VARINT(88976))), 88976, "dup int");
|
||||
@ -95,7 +95,7 @@ testRun(void)
|
||||
if (testBegin("int64"))
|
||||
{
|
||||
// Ensure type sizes are as expected
|
||||
TEST_RESULT_UINT(sizeof(VariantInt64Const), TEST_64BIT() ? 16 : 12, "check VariantInt64Const size");
|
||||
TEST_RESULT_UINT(sizeof(VariantInt64Pub), TEST_64BIT() ? 16 : 12, "check VariantInt64Const size");
|
||||
TEST_RESULT_UINT(sizeof(VariantInt64), TEST_64BIT() ? 24 : 16, "check VariantInt64 size");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@ -119,7 +119,7 @@ testRun(void)
|
||||
"unable to convert uint64 9223372036854775808 to int64");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ERROR(varInt64(varNewStrZ("string")), AssertError, "assertion 'this->type == varTypeInt64' failed");
|
||||
TEST_ERROR(varInt64(varNewStrZ("string")), AssertError, "assertion 'varType(this) == varTypeInt64' failed");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_INT(varInt64(varDup(VARINT64(88976))), 88976, "dup int64");
|
||||
@ -136,7 +136,7 @@ testRun(void)
|
||||
if (testBegin("unsigned int"))
|
||||
{
|
||||
// Ensure type sizes are as expected
|
||||
TEST_RESULT_UINT(sizeof(VariantUIntConst), 8, "check VariantUIntConst size");
|
||||
TEST_RESULT_UINT(sizeof(VariantUIntPub), 8, "check VariantUIntConst size");
|
||||
TEST_RESULT_UINT(sizeof(VariantUInt), TEST_64BIT() ? 16 : 12, "check VariantUInt size");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@ -163,7 +163,7 @@ testRun(void)
|
||||
TEST_ERROR(varUIntForce(VARINT(-1)), FormatError, "unable to convert int -1 to unsigned int");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ERROR(varUInt(varNewStrZ("string")), AssertError, "assertion 'this->type == varTypeUInt' failed");
|
||||
TEST_ERROR(varUInt(varNewStrZ("string")), AssertError, "assertion 'varType(this) == varTypeUInt' failed");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_UINT(varUInt(varDup(VARUINT(88976))), 88976, "dup uint");
|
||||
@ -177,7 +177,7 @@ testRun(void)
|
||||
if (testBegin("uint64"))
|
||||
{
|
||||
// Ensure type sizes are as expected
|
||||
TEST_RESULT_UINT(sizeof(VariantUInt64Const), TEST_64BIT() ? 16 : 12, "check VariantUInt64Const size");
|
||||
TEST_RESULT_UINT(sizeof(VariantUInt64Pub), TEST_64BIT() ? 16 : 12, "check VariantUInt64Const size");
|
||||
TEST_RESULT_UINT(sizeof(VariantUInt64), TEST_64BIT() ? 24 : 16, "check VariantUInt64 size");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@ -203,7 +203,7 @@ testRun(void)
|
||||
TEST_ERROR(varUInt64Force(VARINT(-1)), FormatError, "unable to convert int -1 to uint64");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ERROR(varUInt64(varNewStrZ("string")), AssertError, "assertion 'this->type == varTypeUInt64' failed");
|
||||
TEST_ERROR(varUInt64(varNewStrZ("string")), AssertError, "assertion 'varType(this) == varTypeUInt64' failed");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_UINT(varUInt64(varDup(VARUINT64(88976))), 88976, "dup uint64");
|
||||
@ -223,7 +223,7 @@ testRun(void)
|
||||
TEST_RESULT_UINT(sizeof(VariantKeyValue), TEST_64BIT() ? 24 : 12, "check VariantKeyValue size");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ERROR(varKv(VARINT(66)), AssertError, "assertion 'this->type == varTypeKeyValue' failed");
|
||||
TEST_ERROR(varKv(VARINT(66)), AssertError, "assertion 'varType(this) == varTypeKeyValue' failed");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
Variant *keyValue = NULL;
|
||||
@ -253,7 +253,7 @@ testRun(void)
|
||||
if (testBegin("String"))
|
||||
{
|
||||
// Ensure type sizes are as expected
|
||||
TEST_RESULT_UINT(sizeof(VariantStringConst), TEST_64BIT() ? 16 : 8, "check VariantStringConst size");
|
||||
TEST_RESULT_UINT(sizeof(VariantStringPub), TEST_64BIT() ? 16 : 8, "check VariantStringConst size");
|
||||
TEST_RESULT_UINT(sizeof(VariantString), TEST_64BIT() ? 24 : 12, "check VariantString size");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
@ -267,7 +267,7 @@ testRun(void)
|
||||
TEST_RESULT_STR(varStr(NULL), NULL, "get null string variant");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ERROR(varStr(varNewBool(true)), AssertError, "assertion 'this->type == varTypeString' failed");
|
||||
TEST_ERROR(varStr(varNewBool(true)), AssertError, "assertion 'varType(this) == varTypeString' failed");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_INT(varIntForce(VARSTR(STRDEF("777"))), 777, "int from string");
|
||||
@ -319,7 +319,7 @@ testRun(void)
|
||||
TEST_RESULT_UINT(sizeof(VariantVariantList), TEST_64BIT() ? 24 : 12, "check VariantVariantList size");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_ERROR(varVarLst(VARINT(66)), AssertError, "assertion 'this->type == varTypeVariantList' failed");
|
||||
TEST_ERROR(varVarLst(VARINT(66)), AssertError, "assertion 'varType(this) == varTypeVariantList' failed");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
Variant *listVar = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user