/* * Copyright (c) 2020 TAOS Data, Inc. * * 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 . */ #ifndef _TD_UTIL_BUFFER_H_ #define _TD_UTIL_BUFFER_H_ #include "os.h" #ifdef __cplusplus extern "C" { #endif //////////////////////////////////////////////////////////////////////////////// // usage example /* #include #include "texception.h" int32_t main( int32_t argc, char** argv ) { SBufferWriter bw = tbufInitWriter( NULL, false ); TRY( 1 ) { //--------------------- write ------------------------ // reserve 1024 bytes for the buffer to improve performance tbufEnsureCapacity( &bw, 1024 ); // reserve space for the interger count size_t pos = tbufReserve( &bw, sizeof(int32_t) ); // write 5 integers to the buffer for( int32_t i = 0; i < 5; i++) { tbufWriteInt32( &bw, i ); } // write the integer count to buffer at reserved position tbufWriteInt32At( &bw, pos, 5 ); // write a string to the buffer tbufWriteString( &bw, "this is a string.\n" ); // acquire the result and close the write buffer size_t size = tbufTell( &bw ); char* data = tbufGetData( &bw, false ); //------------------------ read ----------------------- SBufferReader br = tbufInitReader( data, size, false ); // read & print out all integers int32_t count = tbufReadInt32( &br ); for( int32_t i = 0; i < count; i++ ) { printf( "%d\n", tbufReadInt32(&br) ); } // read & print out a string puts( tbufReadString(&br, NULL) ); // try read another integer, this result in an error as there no this integer tbufReadInt32( &br ); 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 ); } END_TRY tbufCloseWriter( &bw ); return 0; } */ typedef struct SBufferReader { bool endian; const char* data; size_t pos; size_t size; } SBufferReader; typedef struct SBufferWriter { bool endian; char* data; size_t pos; size_t size; void* (*allocator)(void*, size_t); } SBufferWriter; // common functions & macros for both reader & writer #define tbufTell(buf) ((buf)->pos) /* ------------------------ BUFFER WRITER FUNCTIONS AND 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 // size before read. Write only write the data itself, which means the reader // need to know data size before read. void tbufWriteBinary(SBufferWriter* buf, const void* data, size_t len); void tbufWriteBool(SBufferWriter* buf, bool data); void tbufWriteBoolAt(SBufferWriter* buf, size_t pos, bool data); void tbufWriteChar(SBufferWriter* buf, char data); void tbufWriteCharAt(SBufferWriter* buf, size_t pos, char data); void tbufWriteInt8(SBufferWriter* buf, int8_t data); void tbufWriteInt8At(SBufferWriter* buf, size_t pos, int8_t data); void tbufWriteUint8(SBufferWriter* buf, uint8_t data); void tbufWriteUint8At(SBufferWriter* buf, size_t pos, uint8_t data); void tbufWriteInt16(SBufferWriter* buf, int16_t data); void tbufWriteInt16At(SBufferWriter* buf, size_t pos, int16_t data); void tbufWriteUint16(SBufferWriter* buf, uint16_t data); void tbufWriteUint16At(SBufferWriter* buf, size_t pos, uint16_t data); void tbufWriteInt32(SBufferWriter* buf, int32_t data); void tbufWriteInt32At(SBufferWriter* buf, size_t pos, int32_t data); void tbufWriteUint32(SBufferWriter* buf, uint32_t data); void tbufWriteUint32At(SBufferWriter* buf, size_t pos, uint32_t data); void tbufWriteInt64(SBufferWriter* buf, int64_t data); void tbufWriteInt64At(SBufferWriter* buf, size_t pos, int64_t data); void tbufWriteUint64(SBufferWriter* buf, uint64_t data); void tbufWriteUint64At(SBufferWriter* buf, size_t pos, uint64_t data); void tbufWriteFloat(SBufferWriter* buf, float data); void tbufWriteFloatAt(SBufferWriter* buf, size_t pos, float data); void tbufWriteDouble(SBufferWriter* buf, double data); void tbufWriteDoubleAt(SBufferWriter* buf, size_t pos, double data); /* ------------------------ BUFFER READER FUNCTIONS AND MACROS ------------------------ */ // *Endian*, if true, reader functions of primitive types will do 'ntoh' automatically #define tbufInitReader(Data, Size, Endian) \ { .endian = (Endian), .data = (Data), .pos = 0, .size = ((Data) == NULL ? 0 : (Size)) } size_t tbufSkip(SBufferReader* buf, size_t size); const char* tbufRead(SBufferReader* buf, size_t size); void tbufReadToBuffer(SBufferReader* buf, void* dst, size_t size); const char* tbufReadString(SBufferReader* buf, size_t* len); size_t tbufReadToString(SBufferReader* buf, char* dst, size_t size); const char* tbufReadBinary(SBufferReader* buf, size_t* len); 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); #ifdef __cplusplus } #endif #endif /*_TD_UTIL_BUFFER_H_*/