mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-03-03 14:52:21 +02:00
Add Buffer object.
This commit is contained in:
parent
f89b027dec
commit
c4b30af645
@ -76,6 +76,10 @@
|
||||
<release-item>
|
||||
<p>Improve <code>MemContext</code> module. Add temporary context blocks and refactor allocation arrays to include allocation size.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Add <code>Buffer</code> object.</p>
|
||||
</release-item>
|
||||
</release-development-list>
|
||||
</release-core-list>
|
||||
|
||||
|
@ -6,6 +6,7 @@ pgbackrest: \
|
||||
common/error.o \
|
||||
common/errorType.o \
|
||||
common/memContext.o \
|
||||
common/type/buffer.o \
|
||||
common/type/list.o \
|
||||
common/type/string.o \
|
||||
common/type/stringList.o \
|
||||
@ -18,6 +19,7 @@ pgbackrest: \
|
||||
common/error.o \
|
||||
common/errorType.o \
|
||||
common/memContext.o \
|
||||
common/type/buffer.o \
|
||||
common/type/list.o \
|
||||
common/type/string.o \
|
||||
common/type/stringList.o \
|
||||
|
123
src/common/type/buffer.c
Normal file
123
src/common/type/buffer.c
Normal file
@ -0,0 +1,123 @@
|
||||
/***********************************************************************************************************************************
|
||||
String Handler
|
||||
***********************************************************************************************************************************/
|
||||
#include <string.h>
|
||||
|
||||
#include "common/memContext.h"
|
||||
#include "common/type/buffer.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Contains information about the buffer
|
||||
***********************************************************************************************************************************/
|
||||
struct Buffer
|
||||
{
|
||||
MemContext *memContext;
|
||||
size_t size;
|
||||
unsigned char *buffer;
|
||||
};
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create a new buffer
|
||||
***********************************************************************************************************************************/
|
||||
Buffer *
|
||||
bufNew(size_t size)
|
||||
{
|
||||
// Create object
|
||||
Buffer *this = memNew(sizeof(Buffer));
|
||||
this->memContext = memContextCurrent();
|
||||
this->size = size;
|
||||
|
||||
// Allocate buffer
|
||||
if (size > 0)
|
||||
this->buffer = memNewRaw(this->size);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create a new buffer from a string
|
||||
***********************************************************************************************************************************/
|
||||
Buffer *
|
||||
bufNewStr(const String *string)
|
||||
{
|
||||
// Create object
|
||||
Buffer *this = bufNew(strSize(string));
|
||||
|
||||
// Copy the data
|
||||
memcpy(this->buffer, strPtr(string), this->size);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Return buffer ptr
|
||||
***********************************************************************************************************************************/
|
||||
unsigned char *
|
||||
bufPtr(const Buffer *this)
|
||||
{
|
||||
return this->buffer;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Resize the buffer
|
||||
***********************************************************************************************************************************/
|
||||
Buffer *
|
||||
bufResize(Buffer *this, size_t size)
|
||||
{
|
||||
// If new size is zero then free memory if allocated
|
||||
if (size == 0)
|
||||
{
|
||||
if (this->buffer != NULL)
|
||||
{
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
memFree(this->buffer);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
||||
|
||||
this->buffer = NULL;
|
||||
this->size = 0;
|
||||
}
|
||||
// Else allocate or resize
|
||||
else
|
||||
{
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
if (this->buffer == NULL)
|
||||
this->buffer = memNew(size);
|
||||
else
|
||||
this->buffer = memGrowRaw(this->buffer, size);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
||||
this->size = size;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Return buffer size
|
||||
***********************************************************************************************************************************/
|
||||
size_t
|
||||
bufSize(const Buffer *this)
|
||||
{
|
||||
return this->size;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Free the buffer
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
bufFree(Buffer *this)
|
||||
{
|
||||
MEM_CONTEXT_BEGIN(this->memContext)
|
||||
{
|
||||
if (this->buffer != NULL)
|
||||
memFree(this->buffer);
|
||||
|
||||
memFree(this);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
}
|
22
src/common/type/buffer.h
Normal file
22
src/common/type/buffer.h
Normal file
@ -0,0 +1,22 @@
|
||||
/***********************************************************************************************************************************
|
||||
Buffer Handler
|
||||
***********************************************************************************************************************************/
|
||||
#ifndef COMMON_TYPE_BUFFER_H
|
||||
#define COMMON_TYPE_BUFFER_H
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Buffer object
|
||||
***********************************************************************************************************************************/
|
||||
typedef struct Buffer Buffer;
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
Buffer *bufNew(size_t size);
|
||||
Buffer *bufNewStr(const String *string);
|
||||
Buffer *bufResize(Buffer *this, size_t size);
|
||||
size_t bufSize(const Buffer *this);
|
||||
unsigned char *bufPtr(const Buffer *this);
|
||||
void bufFree(Buffer *this);
|
||||
|
||||
#endif
|
@ -37,6 +37,29 @@ strNew(const char *string)
|
||||
return this;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create a new string from a buffer
|
||||
|
||||
If the buffer has a NULL character this may not work as expected. All the data will be copied but only the data before the NULL
|
||||
character will be used as a string.
|
||||
***********************************************************************************************************************************/
|
||||
String *
|
||||
strNewBuf(const Buffer *buffer)
|
||||
{
|
||||
// Create object
|
||||
String *this = memNew(sizeof(String));
|
||||
this->memContext = memContextCurrent();
|
||||
this->size = bufSize(buffer);
|
||||
|
||||
// Allocate and assign string
|
||||
this->buffer = memNewRaw(this->size + 1);
|
||||
memcpy(this->buffer, (char *)bufPtr(buffer), this->size);
|
||||
this->buffer[this->size] = 0;
|
||||
|
||||
// Return buffer
|
||||
return this;
|
||||
}
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Create a new string from a format string with parameters (i.e. sprintf)
|
||||
***********************************************************************************************************************************/
|
||||
|
@ -12,7 +12,10 @@ typedef struct String String;
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
#include "common/type/buffer.h"
|
||||
|
||||
String *strNew(const char *string);
|
||||
String *strNewBuf(const Buffer *buffer);
|
||||
String *strNewFmt(const char *format, ...);
|
||||
String *strNewSzN(const char *string, size_t size);
|
||||
|
||||
|
@ -161,6 +161,16 @@ my $oTestDef =
|
||||
'common/type/stringList' => TESTDEF_COVERAGE_FULL,
|
||||
},
|
||||
},
|
||||
{
|
||||
&TESTDEF_NAME => 'type-buffer',
|
||||
&TESTDEF_TOTAL => 2,
|
||||
&TESTDEF_C => true,
|
||||
|
||||
&TESTDEF_COVERAGE =>
|
||||
{
|
||||
'common/type/buffer' => TESTDEF_COVERAGE_FULL,
|
||||
},
|
||||
},
|
||||
{
|
||||
&TESTDEF_NAME => 'encode',
|
||||
&TESTDEF_TOTAL => 1,
|
||||
|
74
test/src/module/common/typeBufferTest.c
Normal file
74
test/src/module/common/typeBufferTest.c
Normal file
@ -0,0 +1,74 @@
|
||||
/***********************************************************************************************************************************
|
||||
Test Buffers
|
||||
***********************************************************************************************************************************/
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Test Run
|
||||
***********************************************************************************************************************************/
|
||||
void testRun()
|
||||
{
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("bufNew(), bufNewStr(), bufSize(), bufPtr(), and bufFree()"))
|
||||
{
|
||||
Buffer *buffer = NULL;
|
||||
|
||||
TEST_ASSIGN(buffer, bufNew(256), "new buffer");
|
||||
TEST_RESULT_PTR(bufPtr(buffer), buffer->buffer, "buffer pointer");
|
||||
TEST_RESULT_INT(bufSize(buffer), 256, "buffer size");
|
||||
|
||||
TEST_ASSIGN(buffer, bufNewStr(strNew("TEST-STR")), "new buffer from string");
|
||||
TEST_RESULT_BOOL(memcmp(bufPtr(buffer), "TEST-STR", 8) == 0, true, "check buffer");
|
||||
|
||||
TEST_RESULT_VOID(bufFree(buffer), "free buffer");
|
||||
}
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("bufResize()"))
|
||||
{
|
||||
Buffer *buffer = NULL;
|
||||
unsigned char *bufferPtr = NULL;
|
||||
|
||||
TEST_ASSIGN(buffer, bufNew(0), "new zero buffer");
|
||||
TEST_RESULT_INT(bufSize(buffer), 0, "check size");
|
||||
TEST_RESULT_PTR(bufResize(buffer, 256), buffer, "resize buffer");
|
||||
TEST_RESULT_INT(bufSize(buffer), 256, "check size");
|
||||
|
||||
// Load data
|
||||
TEST_ASSIGN(bufferPtr, bufPtr(buffer), "buffer pointer");
|
||||
|
||||
for (unsigned int bufferIdx = 0; bufferIdx < bufSize(buffer); bufferIdx++)
|
||||
bufferPtr[bufferIdx] = bufferIdx;
|
||||
|
||||
// Increase buffer size
|
||||
TEST_ASSIGN(bufferPtr, bufPtr(bufResize(buffer, 512)), "increase buffer size");
|
||||
TEST_RESULT_INT(bufSize(buffer), 512, "check size");
|
||||
|
||||
// Test that no bytes have changed in the original data
|
||||
unsigned int sameTotal = 0;
|
||||
|
||||
for (unsigned int bufferIdx = 0; bufferIdx < 256; bufferIdx++)
|
||||
if (bufferPtr[bufferIdx] == bufferIdx)
|
||||
sameTotal++;
|
||||
|
||||
TEST_RESULT_INT(sameTotal, 256, "original bytes match");
|
||||
|
||||
// Decrease buffer size
|
||||
TEST_ASSIGN(bufferPtr, bufPtr(bufResize(buffer, 128)), "decrease buffer size");
|
||||
TEST_RESULT_INT(bufSize(buffer), 128, "check size");
|
||||
|
||||
// Test that no bytes have changed in the original data
|
||||
sameTotal = 0;
|
||||
|
||||
for (unsigned int bufferIdx = 0; bufferIdx < bufSize(buffer); bufferIdx++)
|
||||
if (bufferPtr[bufferIdx] == bufferIdx)
|
||||
sameTotal++;
|
||||
|
||||
TEST_RESULT_INT(sameTotal, 128, "original bytes match");
|
||||
|
||||
// Resize to zero buffer
|
||||
TEST_ASSIGN(bufferPtr, bufPtr(bufResize(buffer, 0)), "decrease to zero");
|
||||
TEST_RESULT_INT(bufSize(buffer), 0, "check size");
|
||||
TEST_ASSIGN(bufferPtr, bufPtr(bufResize(buffer, 0)), "decrease to zero again");
|
||||
TEST_RESULT_INT(bufSize(buffer), 0, "check size");
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
/***********************************************************************************************************************************
|
||||
Test Strings
|
||||
***********************************************************************************************************************************/
|
||||
#include "common/type/buffer.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Test Run
|
||||
@ -8,7 +9,7 @@ Test Run
|
||||
void testRun()
|
||||
{
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("strNew(), strNewSzN(), and strFree()"))
|
||||
if (testBegin("strNew(), strNewBuf(), strNewSzN(), and strFree()"))
|
||||
{
|
||||
String *string = strNew("static string");
|
||||
TEST_RESULT_STR(strPtr(string), "static string", "new with static string");
|
||||
@ -21,6 +22,12 @@ void testRun()
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
TEST_RESULT_STR(strPtr(strNewSzN("testmorestring", 4)), "test", "new string with size limit");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
Buffer *buffer = bufNew(8);
|
||||
memcpy(bufPtr(buffer), "12345678", 8);
|
||||
|
||||
TEST_RESULT_STR(strPtr(strNewBuf(buffer)), "12345678", "new string from buffer");
|
||||
|
||||
// -------------------------------------------------------------------------------------------------------------------------
|
||||
string = strNewFmt("formatted %s %04d", "string", 1);
|
||||
TEST_RESULT_STR(strPtr(string), "formatted string 0001", "new with formatted string");
|
||||
|
Loading…
x
Reference in New Issue
Block a user