split SBuffer to Reader & Writer
This commit is contained in:
parent
058c8912e3
commit
9fdf34552b
|
@ -23,160 +23,102 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
typedef struct {
|
||||||
// SBuffer can be used to read or write a buffer, but cannot be used for both
|
bool endian;
|
||||||
// read & write at a same time. Below is an example:
|
const char* data;
|
||||||
#include <stdio.h>
|
size_t pos;
|
||||||
#include <stdlib.h>
|
size_t size;
|
||||||
#include "exception.h"
|
} SBufferReader;
|
||||||
#include "tbuffer.h"
|
|
||||||
|
|
||||||
int foo() {
|
|
||||||
SBuffer wbuf, rbuf;
|
|
||||||
tbufSetup(&wbuf, NULL, false);
|
|
||||||
tbufSetup(&rbuf, NULL, false);
|
|
||||||
|
|
||||||
TRY {
|
|
||||||
//--------------------- write ------------------------
|
|
||||||
tbufBeginWrite(&wbuf);
|
|
||||||
// reserve 1024 bytes for the buffer to improve performance
|
|
||||||
tbufEnsureCapacity(&wbuf, 1024);
|
|
||||||
// write 5 integers to the buffer
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
tbufWriteInt32(&wbuf, i);
|
|
||||||
}
|
|
||||||
// write a string to the buffer
|
|
||||||
tbufWriteString(&wbuf, "this is a string.\n");
|
|
||||||
// acquire the result and close the write buffer
|
|
||||||
size_t size = tbufTell(&wbuf);
|
|
||||||
char* data = tbufGetData(&wbuf, true);
|
|
||||||
|
|
||||||
//------------------------ read -----------------------
|
|
||||||
tbufBeginRead(&rbuf, data, size);
|
|
||||||
// read & print out 5 integers
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
printf("%d\n", tbufReadInt32(&rbuf));
|
|
||||||
}
|
|
||||||
// read & print out a string
|
|
||||||
puts(tbufReadString(&rbuf, NULL));
|
|
||||||
// try read another integer, this result in an error as there no this integer
|
|
||||||
tbufReadInt32(&rbuf);
|
|
||||||
printf("you should not see this message.\n");
|
|
||||||
} CATCH( code ) {
|
|
||||||
printf("exception code is: %d, you will see this message after print out 5 integers and a string.\n", code);
|
|
||||||
THROW( code );
|
|
||||||
} END_CATCH
|
|
||||||
|
|
||||||
tbufClose(&wbuf, true);
|
|
||||||
tbufClose(&rbuf, false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
|
||||||
TRY {
|
|
||||||
printf("in main: you will see this line\n");
|
|
||||||
foo();
|
|
||||||
printf("in main: you will not see this line\n");
|
|
||||||
} CATCH( code ) {
|
|
||||||
printf("foo raise an exception with code %d\n", code);
|
|
||||||
} END_CATCH
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void* (*allocator)(void*, size_t);
|
bool endian;
|
||||||
bool endian;
|
char* data;
|
||||||
char* data;
|
size_t pos;
|
||||||
size_t pos;
|
size_t size;
|
||||||
size_t size;
|
void* (*allocator)( void*, size_t );
|
||||||
} SBuffer;
|
} SBufferWriter;
|
||||||
|
|
||||||
// common functions can be used in both read & write
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// common functions & macros for both reader & writer
|
||||||
|
#define tbufTell( buf ) ((buf)->pos)
|
||||||
|
|
||||||
// tbufSetup setup the buffer, should be called before tbufBeginRead / tbufBeginWrite
|
|
||||||
// *allocator*, function to allocate memory, will use 'realloc' if NULL
|
|
||||||
// *endian*, if true, read/write functions of primitive types will do 'ntoh' or 'hton' automatically
|
|
||||||
void tbufSetup(SBuffer* buf, void* (*allocator)(void*, size_t), bool endian);
|
|
||||||
size_t tbufTell(SBuffer* buf);
|
|
||||||
size_t tbufSeekTo(SBuffer* buf, size_t pos);
|
|
||||||
void tbufClose(SBuffer* buf, bool keepData);
|
|
||||||
|
|
||||||
// basic read functions
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
void tbufBeginRead(SBuffer* buf, void* data, size_t len);
|
// reader functions & macros
|
||||||
size_t tbufSkip(SBuffer* buf, size_t size);
|
|
||||||
char* tbufRead(SBuffer* buf, size_t size);
|
|
||||||
void tbufReadToBuffer(SBuffer* buf, void* dst, size_t size);
|
|
||||||
const char* tbufReadString(SBuffer* buf, size_t* len);
|
|
||||||
size_t tbufReadToString(SBuffer* buf, char* dst, size_t size);
|
|
||||||
const char* tbufReadBinary(SBuffer* buf, size_t *len);
|
|
||||||
size_t tbufReadToBinary(SBuffer* buf, void* dst, size_t size);
|
|
||||||
|
|
||||||
// basic write functions
|
// *Endian*, if true, reader functions of primitive types will do 'ntoh' automatically
|
||||||
void tbufBeginWrite(SBuffer* buf);
|
#define tbufInitReader( Data, Size, Endian ) {.endian = (Endian), .data = (Data), .pos = 0, .size = ((Data) == NULL ? 0 :(Size))}
|
||||||
void tbufEnsureCapacity(SBuffer* buf, size_t size);
|
|
||||||
size_t tbufReserve(SBuffer* buf, size_t size);
|
size_t tbufSkip( SBufferReader* buf, size_t size );
|
||||||
char* tbufGetData(SBuffer* buf, bool takeOver);
|
|
||||||
void tbufWrite(SBuffer* buf, const void* data, size_t size);
|
char* tbufRead( SBufferReader* buf, size_t size );
|
||||||
void tbufWriteAt(SBuffer* buf, size_t pos, const void* data, size_t size);
|
void tbufReadToBuffer( SBufferReader* buf, void* dst, size_t size );
|
||||||
void tbufWriteStringLen(SBuffer* buf, const char* str, size_t len);
|
const char* tbufReadString( SBufferReader* buf, size_t* len );
|
||||||
void tbufWriteString(SBuffer* buf, const char* str);
|
size_t tbufReadToString( SBufferReader* buf, char* dst, size_t size );
|
||||||
// the prototype of WriteBinary and Write is identical
|
const char* tbufReadBinary( SBufferReader* buf, size_t *len );
|
||||||
// the difference is: WriteBinary writes the length of the data to the buffer
|
size_t tbufReadToBinary( SBufferReader* buf, void* dst, size_t size );
|
||||||
|
|
||||||
|
bool tbufReadBool( SBufferReader* buf );
|
||||||
|
char tbufReadChar( SBufferReader* buf );
|
||||||
|
int8_t tbufReadInt8( SBufferReader* buf );
|
||||||
|
uint8_t tbufReadUint8( SBufferReader* buf );
|
||||||
|
int16_t tbufReadInt16( SBufferReader* buf );
|
||||||
|
uint16_t tbufReadUint16( SBufferReader* buf );
|
||||||
|
int32_t tbufReadInt32( SBufferReader* buf );
|
||||||
|
uint32_t tbufReadUint32( SBufferReader* buf );
|
||||||
|
int64_t tbufReadInt64( SBufferReader* buf );
|
||||||
|
uint64_t tbufReadUint64( SBufferReader* buf );
|
||||||
|
float tbufReadFloat( SBufferReader* buf );
|
||||||
|
double tbufReadDouble( SBufferReader* buf );
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// writer functions & macros
|
||||||
|
|
||||||
|
// *Allocator*, function to allocate memory, will use 'realloc' if NULL
|
||||||
|
// *Endian*, if true, writer functions of primitive types will do 'hton' automatically
|
||||||
|
#define tbufInitWriter( Allocator, Endian ) {.endian = (Endian), .data = NULL, .pos = 0, .size = 0, .allocator = ((Allocator) == NULL ? realloc : (Allocator))}
|
||||||
|
void tbufCloseWriter( SBufferWriter* buf );
|
||||||
|
|
||||||
|
void tbufEnsureCapacity( SBufferWriter* buf, size_t size );
|
||||||
|
size_t tbufReserve( SBufferWriter* buf, size_t size );
|
||||||
|
char* tbufGetData( SBufferWriter* buf, bool takeOver );
|
||||||
|
|
||||||
|
void tbufWrite( SBufferWriter* buf, const void* data, size_t size );
|
||||||
|
void tbufWriteAt( SBufferWriter* buf, size_t pos, const void* data, size_t size );
|
||||||
|
void tbufWriteStringLen( SBufferWriter* buf, const char* str, size_t len );
|
||||||
|
void tbufWriteString( SBufferWriter* buf, const char* str );
|
||||||
|
// the prototype of tbufWriteBinary and tbufWrite are identical
|
||||||
|
// the difference is: tbufWriteBinary writes the length of the data to the buffer
|
||||||
// first, then the actual data, which means the reader don't need to know data
|
// first, then the actual data, which means the reader don't need to know data
|
||||||
// size before read. Write only write the data itself, which means the reader
|
// size before read. Write only write the data itself, which means the reader
|
||||||
// need to know data size before read.
|
// need to know data size before read.
|
||||||
void tbufWriteBinary(SBuffer* buf, const void* data, size_t len);
|
void tbufWriteBinary( SBufferWriter* buf, const void* data, size_t len );
|
||||||
|
|
||||||
// read / write functions for primitive types
|
void tbufWriteBool( SBufferWriter* buf, bool data );
|
||||||
bool tbufReadBool(SBuffer* buf);
|
void tbufWriteBoolAt( SBufferWriter* buf, size_t pos, bool data );
|
||||||
void tbufWriteBool(SBuffer* buf, bool data);
|
void tbufWriteChar( SBufferWriter* buf, char data );
|
||||||
void tbufWriteBoolAt(SBuffer* buf, size_t pos, bool data);
|
void tbufWriteCharAt( SBufferWriter* buf, size_t pos, char data );
|
||||||
|
void tbufWriteInt8( SBufferWriter* buf, int8_t data );
|
||||||
char tbufReadChar(SBuffer* buf);
|
void tbufWriteInt8At( SBufferWriter* buf, size_t pos, int8_t data );
|
||||||
void tbufWriteChar(SBuffer* buf, char data);
|
void tbufWriteUint8( SBufferWriter* buf, uint8_t data );
|
||||||
void tbufWriteCharAt(SBuffer* buf, size_t pos, char data);
|
void tbufWriteUint8At( SBufferWriter* buf, size_t pos, uint8_t data );
|
||||||
|
void tbufWriteInt16( SBufferWriter* buf, int16_t data );
|
||||||
int8_t tbufReadInt8(SBuffer* buf);
|
void tbufWriteInt16At( SBufferWriter* buf, size_t pos, int16_t data );
|
||||||
void tbufWriteInt8(SBuffer* buf, int8_t data);
|
void tbufWriteUint16( SBufferWriter* buf, uint16_t data );
|
||||||
void tbufWriteInt8At(SBuffer* buf, size_t pos, int8_t data);
|
void tbufWriteUint16At( SBufferWriter* buf, size_t pos, uint16_t data );
|
||||||
|
void tbufWriteInt32( SBufferWriter* buf, int32_t data );
|
||||||
uint8_t tbufReadUint8(SBuffer* buf);
|
void tbufWriteInt32At( SBufferWriter* buf, size_t pos, int32_t data );
|
||||||
void tbufWriteUint8(SBuffer* buf, uint8_t data);
|
void tbufWriteUint32( SBufferWriter* buf, uint32_t data );
|
||||||
void tbufWriteUint8At(SBuffer* buf, size_t pos, uint8_t data);
|
void tbufWriteUint32At( SBufferWriter* buf, size_t pos, uint32_t data );
|
||||||
|
void tbufWriteInt64( SBufferWriter* buf, int64_t data );
|
||||||
int16_t tbufReadInt16(SBuffer* buf);
|
void tbufWriteInt64At( SBufferWriter* buf, size_t pos, int64_t data );
|
||||||
void tbufWriteInt16(SBuffer* buf, int16_t data);
|
void tbufWriteUint64( SBufferWriter* buf, uint64_t data );
|
||||||
void tbufWriteInt16At(SBuffer* buf, size_t pos, int16_t data);
|
void tbufWriteUint64At( SBufferWriter* buf, size_t pos, uint64_t data );
|
||||||
|
void tbufWriteFloat( SBufferWriter* buf, float data );
|
||||||
uint16_t tbufReadUint16(SBuffer* buf);
|
void tbufWriteFloatAt( SBufferWriter* buf, size_t pos, float data );
|
||||||
void tbufWriteUint16(SBuffer* buf, uint16_t data);
|
void tbufWriteDouble( SBufferWriter* buf, double data );
|
||||||
void tbufWriteUint16At(SBuffer* buf, size_t pos, uint16_t data);
|
void tbufWriteDoubleAt( SBufferWriter* buf, size_t pos, double data );
|
||||||
|
|
||||||
int32_t tbufReadInt32(SBuffer* buf);
|
|
||||||
void tbufWriteInt32(SBuffer* buf, int32_t data);
|
|
||||||
void tbufWriteInt32At(SBuffer* buf, size_t pos, int32_t data);
|
|
||||||
|
|
||||||
uint32_t tbufReadUint32(SBuffer* buf);
|
|
||||||
void tbufWriteUint32(SBuffer* buf, uint32_t data);
|
|
||||||
void tbufWriteUint32At(SBuffer* buf, size_t pos, uint32_t data);
|
|
||||||
|
|
||||||
int64_t tbufReadInt64(SBuffer* buf);
|
|
||||||
void tbufWriteInt64(SBuffer* buf, int64_t data);
|
|
||||||
void tbufWriteInt64At(SBuffer* buf, size_t pos, int64_t data);
|
|
||||||
|
|
||||||
uint64_t tbufReadUint64(SBuffer* buf);
|
|
||||||
void tbufWriteUint64(SBuffer* buf, uint64_t data);
|
|
||||||
void tbufWriteUint64At(SBuffer* buf, size_t pos, uint64_t data);
|
|
||||||
|
|
||||||
float tbufReadFloat(SBuffer* buf);
|
|
||||||
void tbufWriteFloat(SBuffer* buf, float data);
|
|
||||||
void tbufWriteFloatAt(SBuffer* buf, size_t pos, float data);
|
|
||||||
|
|
||||||
double tbufReadDouble(SBuffer* buf);
|
|
||||||
void tbufWriteDouble(SBuffer* buf, double data);
|
|
||||||
void tbufWriteDoubleAt(SBuffer* buf, size_t pos, double data);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,137 +22,188 @@
|
||||||
#include <taoserror.h>
|
#include <taoserror.h>
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// common functions
|
// reader functions
|
||||||
|
|
||||||
void tbufSetup(
|
size_t tbufSkip(SBufferReader* buf, size_t size) {
|
||||||
SBuffer* buf,
|
if( (buf->pos + size) > buf->size ) {
|
||||||
void* (*allocator)(void*, size_t),
|
|
||||||
bool endian
|
|
||||||
) {
|
|
||||||
if (allocator != NULL) {
|
|
||||||
buf->allocator = allocator;
|
|
||||||
} else {
|
|
||||||
buf->allocator = realloc;
|
|
||||||
}
|
|
||||||
|
|
||||||
buf->endian = endian;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t tbufTell(SBuffer* buf) {
|
|
||||||
return buf->pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t tbufSeekTo(SBuffer* buf, size_t pos) {
|
|
||||||
if (pos > buf->size) {
|
|
||||||
THROW( TSDB_CODE_MEMORY_CORRUPTED );
|
THROW( TSDB_CODE_MEMORY_CORRUPTED );
|
||||||
}
|
}
|
||||||
size_t old = buf->pos;
|
size_t old = buf->pos;
|
||||||
buf->pos = pos;
|
buf->pos += size;
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufClose(SBuffer* buf, bool keepData) {
|
char* tbufRead( SBufferReader* buf, size_t size ) {
|
||||||
if (!keepData) {
|
|
||||||
(*buf->allocator)(buf->data, 0);
|
|
||||||
}
|
|
||||||
buf->data = NULL;
|
|
||||||
buf->pos = 0;
|
|
||||||
buf->size = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// read functions
|
|
||||||
|
|
||||||
void tbufBeginRead(SBuffer* buf, void* data, size_t len) {
|
|
||||||
buf->data = data;
|
|
||||||
buf->pos = 0;
|
|
||||||
buf->size = (data == NULL) ? 0 : len;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t tbufSkip(SBuffer* buf, size_t size) {
|
|
||||||
return tbufSeekTo(buf, buf->pos + size);
|
|
||||||
}
|
|
||||||
|
|
||||||
char* tbufRead(SBuffer* buf, size_t size) {
|
|
||||||
char* ret = buf->data + buf->pos;
|
char* ret = buf->data + buf->pos;
|
||||||
tbufSkip(buf, size);
|
tbufSkip( buf, size );
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufReadToBuffer(SBuffer* buf, void* dst, size_t size) {
|
void tbufReadToBuffer( SBufferReader* buf, void* dst, size_t size ) {
|
||||||
assert(dst != NULL);
|
assert( dst != NULL );
|
||||||
// always using memcpy, leave optimization to compiler
|
// always using memcpy, leave optimization to compiler
|
||||||
memcpy(dst, tbufRead(buf, size), size);
|
memcpy( dst, tbufRead(buf, size), size );
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t tbufReadLength(SBuffer* buf) {
|
static size_t tbufReadLength( SBufferReader* buf ) {
|
||||||
// maximum length is 65535, if larger length is required
|
// maximum length is 65535, if larger length is required
|
||||||
// this function and the corresponding write function need to be
|
// this function and the corresponding write function need to be
|
||||||
// revised.
|
// revised.
|
||||||
uint16_t l = tbufReadUint16(buf);
|
uint16_t l = tbufReadUint16( buf );
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* tbufReadString(SBuffer* buf, size_t* len) {
|
const char* tbufReadString( SBufferReader* buf, size_t* len ) {
|
||||||
size_t l = tbufReadLength(buf);
|
size_t l = tbufReadLength( buf );
|
||||||
char* ret = buf->data + buf->pos;
|
char* ret = buf->data + buf->pos;
|
||||||
tbufSkip(buf, l + 1);
|
tbufSkip( buf, l + 1 );
|
||||||
ret[l] = 0; // ensure the string end with '\0'
|
if( ret[l] != 0 ) {
|
||||||
if (len != NULL) {
|
THROW( TSDB_CODE_MEMORY_CORRUPTED );
|
||||||
|
}
|
||||||
|
if( len != NULL ) {
|
||||||
*len = l;
|
*len = l;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t tbufReadToString(SBuffer* buf, char* dst, size_t size) {
|
size_t tbufReadToString( SBufferReader* buf, char* dst, size_t size ) {
|
||||||
assert(dst != NULL);
|
assert( dst != NULL );
|
||||||
size_t len;
|
size_t len;
|
||||||
const char* str = tbufReadString(buf, &len);
|
const char* str = tbufReadString( buf, &len );
|
||||||
if (len >= size) {
|
if (len >= size) {
|
||||||
len = size - 1;
|
len = size - 1;
|
||||||
}
|
}
|
||||||
memcpy(dst, str, len);
|
memcpy( dst, str, len );
|
||||||
dst[len] = 0;
|
dst[len] = 0;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* tbufReadBinary(SBuffer* buf, size_t *len) {
|
const char* tbufReadBinary( SBufferReader* buf, size_t *len ) {
|
||||||
size_t l = tbufReadLength(buf);
|
size_t l = tbufReadLength( buf );
|
||||||
char* ret = buf->data + buf->pos;
|
char* ret = buf->data + buf->pos;
|
||||||
tbufSkip(buf, l);
|
tbufSkip( buf, l );
|
||||||
if (len != NULL) {
|
if( len != NULL ) {
|
||||||
*len = l;
|
*len = l;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t tbufReadToBinary(SBuffer* buf, void* dst, size_t size) {
|
size_t tbufReadToBinary( SBufferReader* buf, void* dst, size_t size ) {
|
||||||
assert(dst != NULL);
|
assert( dst != NULL );
|
||||||
size_t len;
|
size_t len;
|
||||||
const char* data = tbufReadBinary(buf, &len);
|
const char* data = tbufReadBinary( buf, &len );
|
||||||
if (len >= size) {
|
if( len >= size ) {
|
||||||
len = size;
|
len = size;
|
||||||
}
|
}
|
||||||
memcpy(dst, data, len);
|
memcpy( dst, data, len );
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
bool tbufReadBool( SBufferReader* buf ) {
|
||||||
// write functions
|
bool ret;
|
||||||
|
tbufReadToBuffer( buf, &ret, sizeof(ret) );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void tbufBeginWrite(SBuffer* buf) {
|
char tbufReadChar( SBufferReader* buf ) {
|
||||||
|
char ret;
|
||||||
|
tbufReadToBuffer( buf, &ret, sizeof(ret) );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int8_t tbufReadInt8( SBufferReader* buf ) {
|
||||||
|
int8_t ret;
|
||||||
|
tbufReadToBuffer( buf, &ret, sizeof(ret) );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t tbufReadUint8( SBufferReader* buf ) {
|
||||||
|
uint8_t ret;
|
||||||
|
tbufReadToBuffer( buf, &ret, sizeof(ret) );
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int16_t tbufReadInt16( SBufferReader* buf ) {
|
||||||
|
int16_t ret;
|
||||||
|
tbufReadToBuffer( buf, &ret, sizeof(ret) );
|
||||||
|
if( buf->endian ) {
|
||||||
|
return (int16_t)ntohs( ret );
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t tbufReadUint16( SBufferReader* buf ) {
|
||||||
|
uint16_t ret;
|
||||||
|
tbufReadToBuffer( buf, &ret, sizeof(ret) );
|
||||||
|
if( buf->endian ) {
|
||||||
|
return ntohs( ret );
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t tbufReadInt32( SBufferReader* buf ) {
|
||||||
|
int32_t ret;
|
||||||
|
tbufReadToBuffer( buf, &ret, sizeof(ret) );
|
||||||
|
if( buf->endian ) {
|
||||||
|
return (int32_t)ntohl( ret );
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t tbufReadUint32( SBufferReader* buf ) {
|
||||||
|
uint32_t ret;
|
||||||
|
tbufReadToBuffer( buf, &ret, sizeof(ret) );
|
||||||
|
if( buf->endian ) {
|
||||||
|
return ntohl( ret );
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t tbufReadInt64( SBufferReader* buf ) {
|
||||||
|
int64_t ret;
|
||||||
|
tbufReadToBuffer( buf, &ret, sizeof(ret) );
|
||||||
|
if( buf->endian ) {
|
||||||
|
return (int64_t)htobe64( ret ); // TODO: ntohll
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t tbufReadUint64( SBufferReader* buf ) {
|
||||||
|
uint64_t ret;
|
||||||
|
tbufReadToBuffer( buf, &ret, sizeof(ret) );
|
||||||
|
if( buf->endian ) {
|
||||||
|
return htobe64( ret ); // TODO: ntohll
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
float tbufReadFloat( SBufferReader* buf ) {
|
||||||
|
uint32_t ret = tbufReadUint32( buf );
|
||||||
|
return *(float*)( &ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
double tbufReadDouble(SBufferReader* buf) {
|
||||||
|
uint64_t ret = tbufReadUint64( buf );
|
||||||
|
return *(double*)( &ret );
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// writer functions
|
||||||
|
|
||||||
|
void tbufCloseWriter( SBufferWriter* buf ) {
|
||||||
|
(*buf->allocator)( buf->data, 0 );
|
||||||
buf->data = NULL;
|
buf->data = NULL;
|
||||||
buf->pos = 0;
|
buf->pos = 0;
|
||||||
buf->size = 0;
|
buf->size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufEnsureCapacity(SBuffer* buf, size_t size) {
|
void tbufEnsureCapacity( SBufferWriter* buf, size_t size ) {
|
||||||
size += buf->pos;
|
size += buf->pos;
|
||||||
if (size > buf->size) {
|
if( size > buf->size ) {
|
||||||
size_t nsize = size + buf->size;
|
size_t nsize = size + buf->size;
|
||||||
char* data = (*buf->allocator)(buf->data, nsize);
|
char* data = (*buf->allocator)( buf->data, nsize );
|
||||||
if (data == NULL) {
|
// TODO: the exception should be thrown by the allocator function
|
||||||
// TODO: handle client out of memory
|
if( data == NULL ) {
|
||||||
THROW( TSDB_CODE_SERV_OUT_OF_MEMORY );
|
THROW( TSDB_CODE_SERV_OUT_OF_MEMORY );
|
||||||
}
|
}
|
||||||
buf->data = data;
|
buf->data = data;
|
||||||
|
@ -160,279 +211,189 @@ void tbufEnsureCapacity(SBuffer* buf, size_t size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t tbufReserve(SBuffer* buf, size_t size) {
|
size_t tbufReserve( SBufferWriter* buf, size_t size ) {
|
||||||
tbufEnsureCapacity(buf, size);
|
tbufEnsureCapacity( buf, size );
|
||||||
return tbufSeekTo(buf, buf->pos + size);
|
size_t old = buf->pos;
|
||||||
|
buf->pos += size;
|
||||||
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
char* tbufGetData(SBuffer* buf, bool takeOver) {
|
char* tbufGetData( SBufferWriter* buf, bool takeOver ) {
|
||||||
char* ret = buf->data;
|
char* ret = buf->data;
|
||||||
if (takeOver) {
|
if( takeOver ) {
|
||||||
buf->pos = 0;
|
buf->pos = 0;
|
||||||
buf->size = 0;
|
buf->size = 0;
|
||||||
buf->data = NULL;
|
buf->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWrite(SBuffer* buf, const void* data, size_t size) {
|
void tbufWrite( SBufferWriter* buf, const void* data, size_t size ) {
|
||||||
assert(data != NULL);
|
assert( data != NULL );
|
||||||
tbufEnsureCapacity(buf, size);
|
tbufEnsureCapacity( buf, size );
|
||||||
memcpy(buf->data + buf->pos, data, size);
|
memcpy( buf->data + buf->pos, data, size );
|
||||||
buf->pos += size;
|
buf->pos += size;
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteAt(SBuffer* buf, size_t pos, const void* data, size_t size) {
|
void tbufWriteAt( SBufferWriter* buf, size_t pos, const void* data, size_t size ) {
|
||||||
assert(data != NULL);
|
assert( data != NULL );
|
||||||
// this function can only be called to fill the gap on previous writes,
|
// this function can only be called to fill the gap on previous writes,
|
||||||
// so 'pos + size <= buf->pos' must be true
|
// so 'pos + size <= buf->pos' must be true
|
||||||
assert(pos + size <= buf->pos);
|
assert( pos + size <= buf->pos );
|
||||||
memcpy(buf->data + pos, data, size);
|
memcpy( buf->data + pos, data, size );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tbufWriteLength(SBuffer* buf, size_t len) {
|
static void tbufWriteLength( SBufferWriter* buf, size_t len ) {
|
||||||
// maximum length is 65535, if larger length is required
|
// maximum length is 65535, if larger length is required
|
||||||
// this function and the corresponding read function need to be
|
// this function and the corresponding read function need to be
|
||||||
// revised.
|
// revised.
|
||||||
assert(len <= 0xffff);
|
assert( len <= 0xffff );
|
||||||
tbufWriteUint16(buf, (uint16_t)len);
|
tbufWriteUint16( buf, (uint16_t)len );
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteStringLen(SBuffer* buf, const char* str, size_t len) {
|
void tbufWriteStringLen( SBufferWriter* buf, const char* str, size_t len ) {
|
||||||
tbufWriteLength(buf, len);
|
tbufWriteLength( buf, len );
|
||||||
tbufWrite(buf, str, len);
|
tbufWrite( buf, str, len );
|
||||||
tbufWriteChar(buf, '\0');
|
tbufWriteChar( buf, '\0' );
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteString(SBuffer* buf, const char* str) {
|
void tbufWriteString( SBufferWriter* buf, const char* str ) {
|
||||||
tbufWriteStringLen(buf, str, strlen(str));
|
tbufWriteStringLen( buf, str, strlen(str) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteBinary(SBuffer* buf, const void* data, size_t len) {
|
void tbufWriteBinary( SBufferWriter* buf, const void* data, size_t len ) {
|
||||||
tbufWriteLength(buf, len);
|
tbufWriteLength( buf, len );
|
||||||
tbufWrite(buf, data, len);
|
tbufWrite( buf, data, len );
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
void tbufWriteBool( SBufferWriter* buf, bool data ) {
|
||||||
// read / write functions for primitive types
|
tbufWrite( buf, &data, sizeof(data) );
|
||||||
|
|
||||||
bool tbufReadBool(SBuffer* buf) {
|
|
||||||
bool ret;
|
|
||||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteBool(SBuffer* buf, bool data) {
|
void tbufWriteBoolAt( SBufferWriter* buf, size_t pos, bool data ) {
|
||||||
tbufWrite(buf, &data, sizeof(data));
|
tbufWriteAt( buf, pos, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteBoolAt(SBuffer* buf, size_t pos, bool data) {
|
void tbufWriteChar( SBufferWriter* buf, char data ) {
|
||||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
tbufWrite( buf, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
char tbufReadChar(SBuffer* buf) {
|
void tbufWriteCharAt( SBufferWriter* buf, size_t pos, char data ) {
|
||||||
char ret;
|
tbufWriteAt( buf, pos, &data, sizeof(data) );
|
||||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteChar(SBuffer* buf, char data) {
|
void tbufWriteInt8( SBufferWriter* buf, int8_t data ) {
|
||||||
tbufWrite(buf, &data, sizeof(data));
|
tbufWrite( buf, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteCharAt(SBuffer* buf, size_t pos, char data) {
|
void tbufWriteInt8At( SBufferWriter* buf, size_t pos, int8_t data ) {
|
||||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
tbufWriteAt( buf, pos, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
int8_t tbufReadInt8(SBuffer* buf) {
|
void tbufWriteUint8( SBufferWriter* buf, uint8_t data ) {
|
||||||
int8_t ret;
|
tbufWrite( buf, &data, sizeof(data) );
|
||||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteInt8(SBuffer* buf, int8_t data) {
|
void tbufWriteUint8At( SBufferWriter* buf, size_t pos, uint8_t data ) {
|
||||||
tbufWrite(buf, &data, sizeof(data));
|
tbufWriteAt( buf, pos, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteInt8At(SBuffer* buf, size_t pos, int8_t data) {
|
void tbufWriteInt16( SBufferWriter* buf, int16_t data ) {
|
||||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
if( buf->endian ) {
|
||||||
}
|
data = (int16_t)htons( data );
|
||||||
|
|
||||||
uint8_t tbufReadUint8(SBuffer* buf) {
|
|
||||||
uint8_t ret;
|
|
||||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tbufWriteUint8(SBuffer* buf, uint8_t data) {
|
|
||||||
tbufWrite(buf, &data, sizeof(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
void tbufWriteUint8At(SBuffer* buf, size_t pos, uint8_t data) {
|
|
||||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
int16_t tbufReadInt16(SBuffer* buf) {
|
|
||||||
int16_t ret;
|
|
||||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
|
||||||
if (buf->endian) {
|
|
||||||
return (int16_t)ntohs(ret);
|
|
||||||
}
|
}
|
||||||
return ret;
|
tbufWrite( buf, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteInt16(SBuffer* buf, int16_t data) {
|
void tbufWriteInt16At( SBufferWriter* buf, size_t pos, int16_t data ) {
|
||||||
if (buf->endian) {
|
if( buf->endian ) {
|
||||||
data = (int16_t)htons(data);
|
data = (int16_t)htons( data );
|
||||||
}
|
}
|
||||||
tbufWrite(buf, &data, sizeof(data));
|
tbufWriteAt( buf, pos, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteInt16At(SBuffer* buf, size_t pos, int16_t data) {
|
void tbufWriteUint16( SBufferWriter* buf, uint16_t data ) {
|
||||||
if (buf->endian) {
|
if( buf->endian ) {
|
||||||
data = (int16_t)htons(data);
|
data = htons( data );
|
||||||
}
|
}
|
||||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
tbufWrite( buf, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t tbufReadUint16(SBuffer* buf) {
|
void tbufWriteUint16At( SBufferWriter* buf, size_t pos, uint16_t data ) {
|
||||||
uint16_t ret;
|
if( buf->endian ) {
|
||||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
data = htons( data );
|
||||||
if (buf->endian) {
|
|
||||||
return ntohs(ret);
|
|
||||||
}
|
}
|
||||||
return ret;
|
tbufWriteAt( buf, pos, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteUint16(SBuffer* buf, uint16_t data) {
|
void tbufWriteInt32( SBufferWriter* buf, int32_t data ) {
|
||||||
if (buf->endian) {
|
if( buf->endian ) {
|
||||||
data = htons(data);
|
data = (int32_t)htonl( data );
|
||||||
}
|
}
|
||||||
tbufWrite(buf, &data, sizeof(data));
|
tbufWrite( buf, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteUint16At(SBuffer* buf, size_t pos, uint16_t data) {
|
void tbufWriteInt32At( SBufferWriter* buf, size_t pos, int32_t data ) {
|
||||||
if (buf->endian) {
|
if( buf->endian ) {
|
||||||
data = htons(data);
|
data = (int32_t)htonl( data );
|
||||||
}
|
}
|
||||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
tbufWriteAt( buf, pos, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t tbufReadInt32(SBuffer* buf) {
|
void tbufWriteUint32( SBufferWriter* buf, uint32_t data ) {
|
||||||
int32_t ret;
|
if( buf->endian ) {
|
||||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
data = htonl( data );
|
||||||
if (buf->endian) {
|
|
||||||
return (int32_t)ntohl(ret);
|
|
||||||
}
|
}
|
||||||
return ret;
|
tbufWrite( buf, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteInt32(SBuffer* buf, int32_t data) {
|
void tbufWriteUint32At( SBufferWriter* buf, size_t pos, uint32_t data ) {
|
||||||
if (buf->endian) {
|
if( buf->endian ) {
|
||||||
data = (int32_t)htonl(data);
|
data = htonl( data );
|
||||||
}
|
}
|
||||||
tbufWrite(buf, &data, sizeof(data));
|
tbufWriteAt( buf, pos, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteInt32At(SBuffer* buf, size_t pos, int32_t data) {
|
void tbufWriteInt64( SBufferWriter* buf, int64_t data ) {
|
||||||
if (buf->endian) {
|
if( buf->endian ) {
|
||||||
data = (int32_t)htonl(data);
|
data = (int64_t)htobe64( data );
|
||||||
}
|
}
|
||||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
tbufWrite( buf, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t tbufReadUint32(SBuffer* buf) {
|
void tbufWriteInt64At( SBufferWriter* buf, size_t pos, int64_t data ) {
|
||||||
uint32_t ret;
|
if( buf->endian ) {
|
||||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
data = (int64_t)htobe64( data );
|
||||||
if (buf->endian) {
|
|
||||||
return ntohl(ret);
|
|
||||||
}
|
}
|
||||||
return ret;
|
tbufWriteAt( buf, pos, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteUint32(SBuffer* buf, uint32_t data) {
|
void tbufWriteUint64( SBufferWriter* buf, uint64_t data ) {
|
||||||
if (buf->endian) {
|
if( buf->endian ) {
|
||||||
data = htonl(data);
|
data = htobe64( data );
|
||||||
}
|
}
|
||||||
tbufWrite(buf, &data, sizeof(data));
|
tbufWrite( buf, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteUint32At(SBuffer* buf, size_t pos, uint32_t data) {
|
void tbufWriteUint64At( SBufferWriter* buf, size_t pos, uint64_t data ) {
|
||||||
if (buf->endian) {
|
if( buf->endian ) {
|
||||||
data = htonl(data);
|
data = htobe64( data );
|
||||||
}
|
}
|
||||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
tbufWriteAt( buf, pos, &data, sizeof(data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t tbufReadInt64(SBuffer* buf) {
|
void tbufWriteFloat( SBufferWriter* buf, float data ) {
|
||||||
int64_t ret;
|
tbufWriteUint32( buf, *(uint32_t*)(&data) );
|
||||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
|
||||||
if (buf->endian) {
|
|
||||||
return (int64_t)htobe64(ret); // TODO: ntohll
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteInt64(SBuffer* buf, int64_t data) {
|
void tbufWriteFloatAt( SBufferWriter* buf, size_t pos, float data ) {
|
||||||
if (buf->endian) {
|
tbufWriteUint32At( buf, pos, *(uint32_t*)(&data) );
|
||||||
data = (int64_t)htobe64(data);
|
|
||||||
}
|
|
||||||
tbufWrite(buf, &data, sizeof(data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tbufWriteInt64At(SBuffer* buf, size_t pos, int64_t data) {
|
void tbufWriteDouble( SBufferWriter* buf, double data ) {
|
||||||
if (buf->endian) {
|
tbufWriteUint64( buf, *(uint64_t*)(&data) );
|
||||||
data = (int64_t)htobe64(data);
|
|
||||||
}
|
|
||||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t tbufReadUint64(SBuffer* buf) {
|
void tbufWriteDoubleAt( SBufferWriter* buf, size_t pos, double data ) {
|
||||||
uint64_t ret;
|
tbufWriteUint64At( buf, pos, *(uint64_t*)(&data) );
|
||||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
|
||||||
if (buf->endian) {
|
|
||||||
return htobe64(ret); // TODO: ntohll
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void tbufWriteUint64(SBuffer* buf, uint64_t data) {
|
|
||||||
if (buf->endian) {
|
|
||||||
data = htobe64(data);
|
|
||||||
}
|
|
||||||
tbufWrite(buf, &data, sizeof(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
void tbufWriteUint64At(SBuffer* buf, size_t pos, uint64_t data) {
|
|
||||||
if (buf->endian) {
|
|
||||||
data = htobe64(data);
|
|
||||||
}
|
|
||||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
float tbufReadFloat(SBuffer* buf) {
|
|
||||||
uint32_t ret = tbufReadUint32(buf);
|
|
||||||
return *(float*)(&ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tbufWriteFloat(SBuffer* buf, float data) {
|
|
||||||
tbufWriteUint32(buf, *(uint32_t*)(&data));
|
|
||||||
}
|
|
||||||
|
|
||||||
void tbufWriteFloatAt(SBuffer* buf, size_t pos, float data) {
|
|
||||||
tbufWriteUint32At(buf, pos, *(uint32_t*)(&data));
|
|
||||||
}
|
|
||||||
|
|
||||||
double tbufReadDouble(SBuffer* buf) {
|
|
||||||
uint64_t ret = tbufReadUint64(buf);
|
|
||||||
return *(double*)(&ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
void tbufWriteDouble(SBuffer* buf, double data) {
|
|
||||||
tbufWriteUint64(buf, *(uint64_t*)(&data));
|
|
||||||
}
|
|
||||||
|
|
||||||
void tbufWriteDoubleAt(SBuffer* buf, size_t pos, double data) {
|
|
||||||
tbufWriteUint64At(buf, pos, *(uint64_t*)(&data));
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue