TD-153: add exception handling
This commit is contained in:
parent
8eb0f95bc1
commit
736ddfbbff
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
|
||||
*
|
||||
* This program is free software: you can use, redistribute, and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3
|
||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef TDENGINE_EXCEPTION_H
|
||||
#define TDENGINE_EXCEPTION_H
|
||||
|
||||
#include <setjmp.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct SExceptionNode {
|
||||
struct SExceptionNode* prev;
|
||||
jmp_buf jb;
|
||||
int code;
|
||||
} SExceptionNode;
|
||||
|
||||
void expPushNode( SExceptionNode* node );
|
||||
int expPopNode();
|
||||
void expThrow( int code );
|
||||
|
||||
#define TRY do { \
|
||||
SExceptionNode expNode = { 0 }; \
|
||||
expPushNode( &expNode ); \
|
||||
if( setjmp(expNode.jb) == 0 ) {
|
||||
|
||||
#define CATCH( code ) expPopNode(); \
|
||||
} else { \
|
||||
int code = expPopNode();
|
||||
|
||||
#define END_CATCH } } while( 0 );
|
||||
|
||||
#define THROW( x ) expThrow( (x) )
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -16,122 +16,170 @@
|
|||
#ifndef TDENGINE_TBUFFER_H
|
||||
#define TDENGINE_TBUFFER_H
|
||||
|
||||
#include "setjmp.h"
|
||||
#include "os.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
SBuffer can be used to read or write a buffer, but cannot be used for both
|
||||
read & write at a same time. Below is an example:
|
||||
// SBuffer can be used to read or write a buffer, but cannot be used for both
|
||||
// read & write at a same time. Below is an example:
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "exception.h"
|
||||
#include "tbuffer.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
//--------------------- write ------------------------
|
||||
SBuffer wbuf;
|
||||
int32_t code = tbufBeginWrite(&wbuf);
|
||||
if (code != 0) {
|
||||
// handle errors
|
||||
return 0;
|
||||
}
|
||||
int foo() {
|
||||
SBuffer wbuf, rbuf;
|
||||
tbufSetup(&wbuf, NULL, false);
|
||||
tbufSetup(&rbuf, NULL, false);
|
||||
|
||||
// reserve 1024 bytes for the buffer to improve performance
|
||||
tbufEnsureCapacity(&wbuf, 1024);
|
||||
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);
|
||||
|
||||
// write 5 integers to the buffer
|
||||
for (int i = 0; i < 5; i++) {
|
||||
tbufWriteInt32(&wbuf, i);
|
||||
}
|
||||
//------------------------ 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
|
||||
|
||||
// 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);
|
||||
tbufClose(&wbuf, true);
|
||||
|
||||
|
||||
//------------------------ read -----------------------
|
||||
SBuffer rbuf;
|
||||
code = tbufBeginRead(&rbuf, data, size);
|
||||
if (code != 0) {
|
||||
printf("you will see this message after print out 5 integers and a string.\n");
|
||||
tbufClose(&rbuf, false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// read & print out 5 integers
|
||||
for (int i = 0; i < 5; i++) {
|
||||
printf("%d\n", tbufReadInt32(&rbuf));
|
||||
}
|
||||
|
||||
// read & print out a string
|
||||
printf(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");
|
||||
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 {
|
||||
jmp_buf jb;
|
||||
void* (*allocator)(void*, size_t);
|
||||
bool endian;
|
||||
char* data;
|
||||
size_t pos;
|
||||
size_t size;
|
||||
} SBuffer;
|
||||
|
||||
// common functions can be used in both read & write
|
||||
#define tbufThrowError(buf, code) longjmp((buf)->jb, (code))
|
||||
|
||||
// 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);
|
||||
size_t tbufSkip(SBuffer* buf, size_t size);
|
||||
void tbufClose(SBuffer* buf, bool keepData);
|
||||
|
||||
// basic read functions
|
||||
#define tbufBeginRead(buf, _data, len) ((buf)->data = (char*)(_data), ((buf)->pos = 0), ((buf)->size = ((_data) == NULL) ? 0 : (len)), setjmp((buf)->jb))
|
||||
void tbufBeginRead(SBuffer* buf, void* data, size_t len);
|
||||
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
|
||||
#define tbufBeginWrite(buf) ((buf)->data = NULL, ((buf)->pos = 0), ((buf)->size = 0), setjmp((buf)->jb))
|
||||
void tbufEnsureCapacity(SBuffer* buf, size_t size);
|
||||
char* tbufGetData(SBuffer* buf, bool takeOver);
|
||||
void tbufWrite(SBuffer* buf, const void* data, size_t size);
|
||||
void tbufWriteAt(SBuffer* buf, size_t pos, const void* data, size_t size);
|
||||
void tbufWriteStringLen(SBuffer* buf, const char* str, size_t len);
|
||||
void tbufWriteString(SBuffer* buf, const char* str);
|
||||
void tbufBeginWrite(SBuffer* buf);
|
||||
void tbufEnsureCapacity(SBuffer* buf, size_t size);
|
||||
size_t tbufReserve(SBuffer* buf, size_t size);
|
||||
char* tbufGetData(SBuffer* buf, bool takeOver);
|
||||
void tbufWrite(SBuffer* buf, const void* data, size_t size);
|
||||
void tbufWriteAt(SBuffer* buf, size_t pos, const void* data, size_t size);
|
||||
void tbufWriteStringLen(SBuffer* buf, const char* str, size_t len);
|
||||
void tbufWriteString(SBuffer* buf, const char* str);
|
||||
// the prototype of WriteBinary and Write is identical
|
||||
// the difference is: WriteBinary writes the length of the data to the buffer
|
||||
// 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
|
||||
// need to know data size before read.
|
||||
void tbufWriteBinary(SBuffer* buf, const void* data, size_t len);
|
||||
|
||||
// read & write function for primitive types
|
||||
#ifndef TBUFFER_DEFINE_FUNCTION
|
||||
#define TBUFFER_DEFINE_FUNCTION(type, name) \
|
||||
type tbufRead##name(SBuffer* buf); \
|
||||
void tbufWrite##name(SBuffer* buf, type data); \
|
||||
void tbufWrite##name##At(SBuffer* buf, size_t pos, type data);
|
||||
#endif
|
||||
// read / write functions for primitive types
|
||||
bool tbufReadBool(SBuffer* buf);
|
||||
void tbufWriteBool(SBuffer* buf, bool data);
|
||||
void tbufWriteBoolAt(SBuffer* buf, size_t pos, bool data);
|
||||
|
||||
TBUFFER_DEFINE_FUNCTION(bool, Bool)
|
||||
TBUFFER_DEFINE_FUNCTION(char, Char)
|
||||
TBUFFER_DEFINE_FUNCTION(int8_t, Int8)
|
||||
TBUFFER_DEFINE_FUNCTION(uint8_t, Uint8)
|
||||
TBUFFER_DEFINE_FUNCTION(int16_t, Int16)
|
||||
TBUFFER_DEFINE_FUNCTION(uint16_t, Uint16)
|
||||
TBUFFER_DEFINE_FUNCTION(int32_t, Int32)
|
||||
TBUFFER_DEFINE_FUNCTION(uint32_t, Uint32)
|
||||
TBUFFER_DEFINE_FUNCTION(int64_t, Int64)
|
||||
TBUFFER_DEFINE_FUNCTION(uint64_t, Uint64)
|
||||
TBUFFER_DEFINE_FUNCTION(float, Float)
|
||||
TBUFFER_DEFINE_FUNCTION(double, Double)
|
||||
char tbufReadChar(SBuffer* buf);
|
||||
void tbufWriteChar(SBuffer* buf, char data);
|
||||
void tbufWriteCharAt(SBuffer* buf, size_t pos, char data);
|
||||
|
||||
int8_t tbufReadInt8(SBuffer* buf);
|
||||
void tbufWriteInt8(SBuffer* buf, int8_t data);
|
||||
void tbufWriteInt8At(SBuffer* buf, size_t pos, int8_t data);
|
||||
|
||||
uint8_t tbufReadUint8(SBuffer* buf);
|
||||
void tbufWriteUint8(SBuffer* buf, uint8_t data);
|
||||
void tbufWriteUint8At(SBuffer* buf, size_t pos, uint8_t data);
|
||||
|
||||
int16_t tbufReadInt16(SBuffer* buf);
|
||||
void tbufWriteInt16(SBuffer* buf, int16_t data);
|
||||
void tbufWriteInt16At(SBuffer* buf, size_t pos, int16_t data);
|
||||
|
||||
uint16_t tbufReadUint16(SBuffer* buf);
|
||||
void tbufWriteUint16(SBuffer* buf, uint16_t data);
|
||||
void tbufWriteUint16At(SBuffer* buf, size_t pos, uint16_t 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
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
#include "exception.h"
|
||||
|
||||
|
||||
static _Thread_local SExceptionNode* expList;
|
||||
|
||||
void expPushNode( SExceptionNode* node ) {
|
||||
node->prev = expList;
|
||||
expList = node;
|
||||
}
|
||||
|
||||
int expPopNode() {
|
||||
SExceptionNode* node = expList;
|
||||
expList = node->prev;
|
||||
return node->code;
|
||||
}
|
||||
|
||||
void expThrow( int code ) {
|
||||
expList->code = code;
|
||||
longjmp( expList->jb, 1 );
|
||||
}
|
|
@ -16,47 +16,44 @@
|
|||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <assert.h>
|
||||
|
||||
#define TBUFFER_DEFINE_FUNCTION(type, name) \
|
||||
type tbufRead##name(SBuffer* buf) { \
|
||||
type ret; \
|
||||
tbufReadToBuffer(buf, &ret, sizeof(type)); \
|
||||
return ret; \
|
||||
}\
|
||||
void tbufWrite##name(SBuffer* buf, type data) {\
|
||||
tbufWrite(buf, &data, sizeof(data));\
|
||||
}\
|
||||
void tbufWrite##name##At(SBuffer* buf, size_t pos, type data) {\
|
||||
tbufWriteAt(buf, pos, &data, sizeof(data));\
|
||||
}
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include "tbuffer.h"
|
||||
|
||||
#include "exception.h"
|
||||
#include <taoserror.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// common functions
|
||||
|
||||
void tbufSetup(
|
||||
SBuffer* buf,
|
||||
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) {
|
||||
// TODO: update error code, other tbufThrowError need to be changed too
|
||||
tbufThrowError(buf, 1);
|
||||
THROW( TSDB_CODE_MEMORY_CORRUPTED );
|
||||
}
|
||||
size_t old = buf->pos;
|
||||
buf->pos = pos;
|
||||
return old;
|
||||
}
|
||||
|
||||
size_t tbufSkip(SBuffer* buf, size_t size) {
|
||||
return tbufSeekTo(buf, buf->pos + size);
|
||||
}
|
||||
|
||||
void tbufClose(SBuffer* buf, bool keepData) {
|
||||
if (!keepData) {
|
||||
free(buf->data);
|
||||
(*buf->allocator)(buf->data, 0);
|
||||
}
|
||||
buf->data = NULL;
|
||||
buf->pos = 0;
|
||||
|
@ -66,6 +63,16 @@ void tbufClose(SBuffer* buf, bool keepData) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 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;
|
||||
tbufSkip(buf, size);
|
||||
|
@ -78,8 +85,16 @@ void tbufReadToBuffer(SBuffer* buf, void* dst, size_t size) {
|
|||
memcpy(dst, tbufRead(buf, size), size);
|
||||
}
|
||||
|
||||
const char* tbufReadString(SBuffer* buf, size_t* len) {
|
||||
static size_t tbufReadLength(SBuffer* buf) {
|
||||
// maximum length is 65535, if larger length is required
|
||||
// this function and the corresponding write function need to be
|
||||
// revised.
|
||||
uint16_t l = tbufReadUint16(buf);
|
||||
return l;
|
||||
}
|
||||
|
||||
const char* tbufReadString(SBuffer* buf, size_t* len) {
|
||||
size_t l = tbufReadLength(buf);
|
||||
char* ret = buf->data + buf->pos;
|
||||
tbufSkip(buf, l + 1);
|
||||
ret[l] = 0; // ensure the string end with '\0'
|
||||
|
@ -101,23 +116,55 @@ size_t tbufReadToString(SBuffer* buf, char* dst, size_t size) {
|
|||
return len;
|
||||
}
|
||||
|
||||
const char* tbufReadBinary(SBuffer* buf, size_t *len) {
|
||||
size_t l = tbufReadLength(buf);
|
||||
char* ret = buf->data + buf->pos;
|
||||
tbufSkip(buf, l);
|
||||
if (len != NULL) {
|
||||
*len = l;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t tbufReadToBinary(SBuffer* buf, void* dst, size_t size) {
|
||||
assert(dst != NULL);
|
||||
size_t len;
|
||||
const char* data = tbufReadBinary(buf, &len);
|
||||
if (len >= size) {
|
||||
len = size;
|
||||
}
|
||||
memcpy(dst, data, len);
|
||||
return len;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// write functions
|
||||
|
||||
void tbufBeginWrite(SBuffer* buf) {
|
||||
buf->data = NULL;
|
||||
buf->pos = 0;
|
||||
buf->size = 0;
|
||||
}
|
||||
|
||||
void tbufEnsureCapacity(SBuffer* buf, size_t size) {
|
||||
size += buf->pos;
|
||||
if (size > buf->size) {
|
||||
size_t nsize = size + buf->size;
|
||||
char* data = realloc(buf->data, nsize);
|
||||
char* data = (*buf->allocator)(buf->data, nsize);
|
||||
if (data == NULL) {
|
||||
tbufThrowError(buf, 2);
|
||||
// TODO: handle client out of memory
|
||||
THROW( TSDB_CODE_SERV_OUT_OF_MEMORY );
|
||||
}
|
||||
buf->data = data;
|
||||
buf->size = nsize;
|
||||
}
|
||||
}
|
||||
|
||||
size_t tbufReserve(SBuffer* buf, size_t size) {
|
||||
tbufEnsureCapacity(buf, size);
|
||||
return tbufSeekTo(buf, buf->pos + size);
|
||||
}
|
||||
|
||||
char* tbufGetData(SBuffer* buf, bool takeOver) {
|
||||
char* ret = buf->data;
|
||||
if (takeOver) {
|
||||
|
@ -129,13 +176,6 @@ char* tbufGetData(SBuffer* buf, bool takeOver) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
void tbufEndWrite(SBuffer* buf) {
|
||||
free(buf->data);
|
||||
buf->data = NULL;
|
||||
buf->pos = 0;
|
||||
buf->size = 0;
|
||||
}
|
||||
|
||||
void tbufWrite(SBuffer* buf, const void* data, size_t size) {
|
||||
assert(data != NULL);
|
||||
tbufEnsureCapacity(buf, size);
|
||||
|
@ -151,15 +191,248 @@ void tbufWriteAt(SBuffer* buf, size_t pos, const void* data, size_t size) {
|
|||
memcpy(buf->data + pos, data, size);
|
||||
}
|
||||
|
||||
void tbufWriteStringLen(SBuffer* buf, const char* str, size_t len) {
|
||||
// maximum string length is 65535, if longer string is required
|
||||
static void tbufWriteLength(SBuffer* buf, size_t len) {
|
||||
// maximum length is 65535, if larger length is required
|
||||
// this function and the corresponding read function need to be
|
||||
// revised.
|
||||
assert(len <= 0xffff);
|
||||
tbufWriteUint16(buf, (uint16_t)len);
|
||||
tbufWrite(buf, str, len + 1);
|
||||
}
|
||||
|
||||
void tbufWriteStringLen(SBuffer* buf, const char* str, size_t len) {
|
||||
tbufWriteLength(buf, len);
|
||||
tbufWrite(buf, str, len);
|
||||
tbufWriteChar(buf, '\0');
|
||||
}
|
||||
|
||||
void tbufWriteString(SBuffer* buf, const char* str) {
|
||||
tbufWriteStringLen(buf, str, strlen(str));
|
||||
}
|
||||
|
||||
void tbufWriteBinary(SBuffer* buf, const void* data, size_t len) {
|
||||
tbufWriteLength(buf, len);
|
||||
tbufWrite(buf, data, len);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// read / write functions for primitive types
|
||||
|
||||
bool tbufReadBool(SBuffer* buf) {
|
||||
bool ret;
|
||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void tbufWriteBool(SBuffer* buf, bool data) {
|
||||
tbufWrite(buf, &data, sizeof(data));
|
||||
}
|
||||
|
||||
void tbufWriteBoolAt(SBuffer* buf, size_t pos, bool data) {
|
||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
||||
}
|
||||
|
||||
char tbufReadChar(SBuffer* buf) {
|
||||
char ret;
|
||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void tbufWriteChar(SBuffer* buf, char data) {
|
||||
tbufWrite(buf, &data, sizeof(data));
|
||||
}
|
||||
|
||||
void tbufWriteCharAt(SBuffer* buf, size_t pos, char data) {
|
||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
||||
}
|
||||
|
||||
int8_t tbufReadInt8(SBuffer* buf) {
|
||||
int8_t ret;
|
||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void tbufWriteInt8(SBuffer* buf, int8_t data) {
|
||||
tbufWrite(buf, &data, sizeof(data));
|
||||
}
|
||||
|
||||
void tbufWriteInt8At(SBuffer* buf, size_t pos, int8_t data) {
|
||||
tbufWriteAt(buf, pos, &data, sizeof(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;
|
||||
}
|
||||
|
||||
void tbufWriteInt16(SBuffer* buf, int16_t data) {
|
||||
if (buf->endian) {
|
||||
data = (int16_t)htons(data);
|
||||
}
|
||||
tbufWrite(buf, &data, sizeof(data));
|
||||
}
|
||||
|
||||
void tbufWriteInt16At(SBuffer* buf, size_t pos, int16_t data) {
|
||||
if (buf->endian) {
|
||||
data = (int16_t)htons(data);
|
||||
}
|
||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
||||
}
|
||||
|
||||
uint16_t tbufReadUint16(SBuffer* buf) {
|
||||
uint16_t ret;
|
||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
||||
if (buf->endian) {
|
||||
return ntohs(ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void tbufWriteUint16(SBuffer* buf, uint16_t data) {
|
||||
if (buf->endian) {
|
||||
data = htons(data);
|
||||
}
|
||||
tbufWrite(buf, &data, sizeof(data));
|
||||
}
|
||||
|
||||
void tbufWriteUint16At(SBuffer* buf, size_t pos, uint16_t data) {
|
||||
if (buf->endian) {
|
||||
data = htons(data);
|
||||
}
|
||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
||||
}
|
||||
|
||||
int32_t tbufReadInt32(SBuffer* buf) {
|
||||
int32_t ret;
|
||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
||||
if (buf->endian) {
|
||||
return (int32_t)ntohl(ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void tbufWriteInt32(SBuffer* buf, int32_t data) {
|
||||
if (buf->endian) {
|
||||
data = (int32_t)htonl(data);
|
||||
}
|
||||
tbufWrite(buf, &data, sizeof(data));
|
||||
}
|
||||
|
||||
void tbufWriteInt32At(SBuffer* buf, size_t pos, int32_t data) {
|
||||
if (buf->endian) {
|
||||
data = (int32_t)htonl(data);
|
||||
}
|
||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
||||
}
|
||||
|
||||
uint32_t tbufReadUint32(SBuffer* buf) {
|
||||
uint32_t ret;
|
||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
||||
if (buf->endian) {
|
||||
return ntohl(ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void tbufWriteUint32(SBuffer* buf, uint32_t data) {
|
||||
if (buf->endian) {
|
||||
data = htonl(data);
|
||||
}
|
||||
tbufWrite(buf, &data, sizeof(data));
|
||||
}
|
||||
|
||||
void tbufWriteUint32At(SBuffer* buf, size_t pos, uint32_t data) {
|
||||
if (buf->endian) {
|
||||
data = htonl(data);
|
||||
}
|
||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
||||
}
|
||||
|
||||
int64_t tbufReadInt64(SBuffer* buf) {
|
||||
int64_t ret;
|
||||
tbufReadToBuffer(buf, &ret, sizeof(ret));
|
||||
if (buf->endian) {
|
||||
return (int64_t)htobe64(ret); // TODO: ntohll
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void tbufWriteInt64(SBuffer* buf, int64_t data) {
|
||||
if (buf->endian) {
|
||||
data = (int64_t)htobe64(data);
|
||||
}
|
||||
tbufWrite(buf, &data, sizeof(data));
|
||||
}
|
||||
|
||||
void tbufWriteInt64At(SBuffer* buf, size_t pos, int64_t data) {
|
||||
if (buf->endian) {
|
||||
data = (int64_t)htobe64(data);
|
||||
}
|
||||
tbufWriteAt(buf, pos, &data, sizeof(data));
|
||||
}
|
||||
|
||||
uint64_t tbufReadUint64(SBuffer* buf) {
|
||||
uint64_t ret;
|
||||
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