tbuffer.h 7.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * 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 TDENGINE_TBUFFER_H
#define TDENGINE_TBUFFER_H

weixin_48148422's avatar
weixin_48148422 已提交
19 20
#include <stdint.h>
#include <stdbool.h>
21 22 23 24

#ifdef __cplusplus
extern "C" {
#endif
25

weixin_48148422's avatar
weixin_48148422 已提交
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
////////////////////////////////////////////////////////////////////////////////
// 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 );
    // throw it again and the exception will be caught in main
    THROW( code );
  } END_TRY

  tbufCloseWriter( &bw );
  return 0;
}
*/

78 79 80 81 82 83
typedef struct {
  bool endian;
  const char* data;
  size_t pos;
  size_t size;
} SBufferReader;
weixin_48148422's avatar
weixin_48148422 已提交
84

85
typedef struct {
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
  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 );

weixin_48148422's avatar
weixin_48148422 已提交
106
const char* tbufRead( SBufferReader* buf, size_t size );
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
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
weixin_48148422's avatar
weixin_48148422 已提交
145 146 147
// 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.
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
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 );
174 175 176 177

#ifdef __cplusplus
}
#endif
178

weixin_48148422's avatar
weixin_48148422 已提交
179
#endif