176 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			176 lines
		
	
	
		
			6.9 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Copyright (c) 2020 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 _TD_UTIL_BUFFER_H
 | 
						|
#define _TD_UTIL_BUFFER_H
 | 
						|
 | 
						|
#ifdef __cplusplus
 | 
						|
extern "C" {
 | 
						|
#endif
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////
 | 
						|
// usage example
 | 
						|
/*
 | 
						|
#include <stdio.h>
 | 
						|
#include "exception.h"
 | 
						|
 | 
						|
int main( int 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( int 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( int 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)
 | 
						|
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////
 | 
						|
// reader functions & 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 );
 | 
						|
 | 
						|
 | 
						|
////////////////////////////////////////////////////////////////////////////////
 | 
						|
// 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
 | 
						|
// 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 );
 | 
						|
 | 
						|
#ifdef __cplusplus
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
#endif /*_TD_UTIL_BUFFER_H*/
 |