tbuffer.c 10.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*
 * 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/>.
 */

H
Haojun Liao 已提交
16 17
#define _DEFAULT_SOURCE

18
#include "tbuffer.h"
weixin_48148422's avatar
weixin_48148422 已提交
19
#include "exception.h"
H
refact  
Hongze Cheng 已提交
20
#include "os.h"
H
Haojun Liao 已提交
21
//#include "taoserror.h"
22

23 24
typedef union Un4B {
  uint32_t ui;
H
refact  
Hongze Cheng 已提交
25
  float    f;
26 27 28 29 30 31 32 33
} Un4B;
#if __STDC_VERSION__ >= 201112L
static_assert(sizeof(Un4B) == sizeof(uint32_t), "sizeof(Un4B) must equal to sizeof(uint32_t)");
static_assert(sizeof(Un4B) == sizeof(float), "sizeof(Un4B) must equal to sizeof(float)");
#endif

typedef union Un8B {
  uint64_t ull;
H
refact  
Hongze Cheng 已提交
34
  double   d;
35 36 37 38 39 40
} Un8B;
#if __STDC_VERSION__ >= 201112L
static_assert(sizeof(Un8B) == sizeof(uint64_t), "sizeof(Un8B) must equal to sizeof(uint64_t)");
static_assert(sizeof(Un8B) == sizeof(double), "sizeof(Un8B) must equal to sizeof(double)");
#endif

41
////////////////////////////////////////////////////////////////////////////////
42
// reader functions
43

44
size_t tbufSkip(SBufferReader* buf, size_t size) {
H
refact  
Hongze Cheng 已提交
45 46
  if ((buf->pos + size) > buf->size) {
    THROW(-1);
47 48
  }
  size_t old = buf->pos;
49
  buf->pos += size;
50 51 52
  return old;
}

H
refact  
Hongze Cheng 已提交
53
const char* tbufRead(SBufferReader* buf, size_t size) {
weixin_48148422's avatar
weixin_48148422 已提交
54
  const char* ret = buf->data + buf->pos;
H
refact  
Hongze Cheng 已提交
55
  tbufSkip(buf, size);
56 57 58
  return ret;
}

H
refact  
Hongze Cheng 已提交
59 60
void tbufReadToBuffer(SBufferReader* buf, void* dst, size_t size) {
  assert(dst != NULL);
61
  // always using memcpy, leave optimization to compiler
H
refact  
Hongze Cheng 已提交
62
  memcpy(dst, tbufRead(buf, size), size);
63 64
}

H
refact  
Hongze Cheng 已提交
65
static size_t tbufReadLength(SBufferReader* buf) {
weixin_48148422's avatar
weixin_48148422 已提交
66 67 68
  // maximum length is 65535, if larger length is required
  // this function and the corresponding write function need to be
  // revised.
H
refact  
Hongze Cheng 已提交
69
  uint16_t l = tbufReadUint16(buf);
weixin_48148422's avatar
weixin_48148422 已提交
70 71 72
  return l;
}

H
refact  
Hongze Cheng 已提交
73 74
const char* tbufReadString(SBufferReader* buf, size_t* len) {
  size_t      l = tbufReadLength(buf);
weixin_48148422's avatar
weixin_48148422 已提交
75
  const char* ret = buf->data + buf->pos;
H
refact  
Hongze Cheng 已提交
76 77 78
  tbufSkip(buf, l + 1);
  if (ret[l] != 0) {
    THROW(-1);
79
  }
H
refact  
Hongze Cheng 已提交
80
  if (len != NULL) {
81 82 83 84 85
    *len = l;
  }
  return ret;
}

H
refact  
Hongze Cheng 已提交
86 87 88 89
size_t tbufReadToString(SBufferReader* buf, char* dst, size_t size) {
  assert(dst != NULL);
  size_t      len;
  const char* str = tbufReadString(buf, &len);
weixin_48148422's avatar
weixin_48148422 已提交
90 91 92
  if (len >= size) {
    len = size - 1;
  }
H
refact  
Hongze Cheng 已提交
93
  memcpy(dst, str, len);
94 95 96 97
  dst[len] = 0;
  return len;
}

H
refact  
Hongze Cheng 已提交
98 99
const char* tbufReadBinary(SBufferReader* buf, size_t* len) {
  size_t      l = tbufReadLength(buf);
weixin_48148422's avatar
weixin_48148422 已提交
100
  const char* ret = buf->data + buf->pos;
H
refact  
Hongze Cheng 已提交
101 102
  tbufSkip(buf, l);
  if (len != NULL) {
weixin_48148422's avatar
weixin_48148422 已提交
103 104 105 106 107
    *len = l;
  }
  return ret;
}

H
refact  
Hongze Cheng 已提交
108 109 110 111 112
size_t tbufReadToBinary(SBufferReader* buf, void* dst, size_t size) {
  assert(dst != NULL);
  size_t      len;
  const char* data = tbufReadBinary(buf, &len);
  if (len >= size) {
weixin_48148422's avatar
weixin_48148422 已提交
113 114
    len = size;
  }
H
refact  
Hongze Cheng 已提交
115
  memcpy(dst, data, len);
weixin_48148422's avatar
weixin_48148422 已提交
116 117
  return len;
}
118

H
refact  
Hongze Cheng 已提交
119
bool tbufReadBool(SBufferReader* buf) {
120
  bool ret;
H
refact  
Hongze Cheng 已提交
121
  tbufReadToBuffer(buf, &ret, sizeof(ret));
122 123
  return ret;
}
124

H
refact  
Hongze Cheng 已提交
125
char tbufReadChar(SBufferReader* buf) {
126
  char ret;
H
refact  
Hongze Cheng 已提交
127
  tbufReadToBuffer(buf, &ret, sizeof(ret));
128
  return ret;
weixin_48148422's avatar
weixin_48148422 已提交
129 130
}

H
refact  
Hongze Cheng 已提交
131
int8_t tbufReadInt8(SBufferReader* buf) {
132
  int8_t ret;
H
refact  
Hongze Cheng 已提交
133
  tbufReadToBuffer(buf, &ret, sizeof(ret));
134
  return ret;
135 136
}

H
refact  
Hongze Cheng 已提交
137
uint8_t tbufReadUint8(SBufferReader* buf) {
138
  uint8_t ret;
H
refact  
Hongze Cheng 已提交
139
  tbufReadToBuffer(buf, &ret, sizeof(ret));
140
  return ret;
weixin_48148422's avatar
weixin_48148422 已提交
141 142
}

H
refact  
Hongze Cheng 已提交
143
int16_t tbufReadInt16(SBufferReader* buf) {
144
  int16_t ret;
H
refact  
Hongze Cheng 已提交
145 146 147
  tbufReadToBuffer(buf, &ret, sizeof(ret));
  if (buf->endian) {
    return (int16_t)ntohs(ret);
148
  }
149 150
  return ret;
}
151

H
refact  
Hongze Cheng 已提交
152
uint16_t tbufReadUint16(SBufferReader* buf) {
153
  uint16_t ret;
H
refact  
Hongze Cheng 已提交
154 155 156
  tbufReadToBuffer(buf, &ret, sizeof(ret));
  if (buf->endian) {
    return ntohs(ret);
157
  }
158
  return ret;
159 160
}

H
refact  
Hongze Cheng 已提交
161
int32_t tbufReadInt32(SBufferReader* buf) {
162
  int32_t ret;
H
refact  
Hongze Cheng 已提交
163 164 165
  tbufReadToBuffer(buf, &ret, sizeof(ret));
  if (buf->endian) {
    return (int32_t)ntohl(ret);
166 167
  }
  return ret;
168 169
}

H
refact  
Hongze Cheng 已提交
170
uint32_t tbufReadUint32(SBufferReader* buf) {
171
  uint32_t ret;
H
refact  
Hongze Cheng 已提交
172 173 174
  tbufReadToBuffer(buf, &ret, sizeof(ret));
  if (buf->endian) {
    return ntohl(ret);
175 176
  }
  return ret;
177 178
}

H
refact  
Hongze Cheng 已提交
179
int64_t tbufReadInt64(SBufferReader* buf) {
180
  int64_t ret;
H
refact  
Hongze Cheng 已提交
181 182 183
  tbufReadToBuffer(buf, &ret, sizeof(ret));
  if (buf->endian) {
    return (int64_t)htobe64(ret);  // TODO: ntohll
184 185
  }
  return ret;
weixin_48148422's avatar
weixin_48148422 已提交
186 187
}

H
refact  
Hongze Cheng 已提交
188
uint64_t tbufReadUint64(SBufferReader* buf) {
189
  uint64_t ret;
H
refact  
Hongze Cheng 已提交
190 191 192
  tbufReadToBuffer(buf, &ret, sizeof(ret));
  if (buf->endian) {
    return htobe64(ret);  // TODO: ntohll
193 194
  }
  return ret;
195 196
}

H
refact  
Hongze Cheng 已提交
197
float tbufReadFloat(SBufferReader* buf) {
198
  Un4B _un;
H
refact  
Hongze Cheng 已提交
199 200 201
  tbufReadToBuffer(buf, &_un, sizeof(_un));
  if (buf->endian) {
    _un.ui = ntohl(_un.ui);
202 203
  }
  return _un.f;
204
}
weixin_48148422's avatar
weixin_48148422 已提交
205

206
double tbufReadDouble(SBufferReader* buf) {
207
  Un8B _un;
H
refact  
Hongze Cheng 已提交
208 209 210
  tbufReadToBuffer(buf, &_un, sizeof(_un));
  if (buf->endian) {
    _un.ull = htobe64(_un.ull);
211 212
  }
  return _un.d;
weixin_48148422's avatar
weixin_48148422 已提交
213 214 215
}

////////////////////////////////////////////////////////////////////////////////
216
// writer functions
weixin_48148422's avatar
weixin_48148422 已提交
217

H
refact  
Hongze Cheng 已提交
218
void tbufCloseWriter(SBufferWriter* buf) {
H
Haojun Liao 已提交
219
  tfree(buf->data);
H
refact  
Hongze Cheng 已提交
220
  //  (*buf->allocator)( buf->data, 0 );  // potential memory leak.
221 222 223
  buf->data = NULL;
  buf->pos = 0;
  buf->size = 0;
weixin_48148422's avatar
weixin_48148422 已提交
224 225
}

H
refact  
Hongze Cheng 已提交
226
void tbufEnsureCapacity(SBufferWriter* buf, size_t size) {
227
  size += buf->pos;
H
refact  
Hongze Cheng 已提交
228
  if (size > buf->size) {
229
    size_t nsize = size + buf->size;
H
refact  
Hongze Cheng 已提交
230
    char*  data = (*buf->allocator)(buf->data, nsize);
231
    // TODO: the exception should be thrown by the allocator function
H
refact  
Hongze Cheng 已提交
232 233
    if (data == NULL) {
      THROW(-1);
234 235 236 237
    }
    buf->data = data;
    buf->size = nsize;
  }
weixin_48148422's avatar
weixin_48148422 已提交
238 239
}

H
refact  
Hongze Cheng 已提交
240 241
size_t tbufReserve(SBufferWriter* buf, size_t size) {
  tbufEnsureCapacity(buf, size);
242 243 244
  size_t old = buf->pos;
  buf->pos += size;
  return old;
weixin_48148422's avatar
weixin_48148422 已提交
245 246
}

H
refact  
Hongze Cheng 已提交
247
char* tbufGetData(SBufferWriter* buf, bool takeOver) {
248
  char* ret = buf->data;
H
refact  
Hongze Cheng 已提交
249
  if (takeOver) {
250 251 252 253
    buf->pos = 0;
    buf->size = 0;
    buf->data = NULL;
  }
weixin_48148422's avatar
weixin_48148422 已提交
254 255 256
  return ret;
}

H
refact  
Hongze Cheng 已提交
257 258 259 260
void tbufWrite(SBufferWriter* buf, const void* data, size_t size) {
  assert(data != NULL);
  tbufEnsureCapacity(buf, size);
  memcpy(buf->data + buf->pos, data, size);
261
  buf->pos += size;
weixin_48148422's avatar
weixin_48148422 已提交
262 263
}

H
refact  
Hongze Cheng 已提交
264 265
void tbufWriteAt(SBufferWriter* buf, size_t pos, const void* data, size_t size) {
  assert(data != NULL);
266 267
  // this function can only be called to fill the gap on previous writes,
  // so 'pos + size <= buf->pos' must be true
H
refact  
Hongze Cheng 已提交
268 269
  assert(pos + size <= buf->pos);
  memcpy(buf->data + pos, data, size);
weixin_48148422's avatar
weixin_48148422 已提交
270 271
}

H
refact  
Hongze Cheng 已提交
272
static void tbufWriteLength(SBufferWriter* buf, size_t len) {
273 274 275
  // maximum length is 65535, if larger length is required
  // this function and the corresponding read function need to be
  // revised.
H
refact  
Hongze Cheng 已提交
276 277
  assert(len <= 0xffff);
  tbufWriteUint16(buf, (uint16_t)len);
weixin_48148422's avatar
weixin_48148422 已提交
278 279
}

H
refact  
Hongze Cheng 已提交
280 281 282 283
void tbufWriteStringLen(SBufferWriter* buf, const char* str, size_t len) {
  tbufWriteLength(buf, len);
  tbufWrite(buf, str, len);
  tbufWriteChar(buf, '\0');
weixin_48148422's avatar
weixin_48148422 已提交
284 285
}

H
refact  
Hongze Cheng 已提交
286
void tbufWriteString(SBufferWriter* buf, const char* str) { tbufWriteStringLen(buf, str, strlen(str)); }
weixin_48148422's avatar
weixin_48148422 已提交
287

H
refact  
Hongze Cheng 已提交
288 289 290
void tbufWriteBinary(SBufferWriter* buf, const void* data, size_t len) {
  tbufWriteLength(buf, len);
  tbufWrite(buf, data, len);
weixin_48148422's avatar
weixin_48148422 已提交
291 292
}

H
refact  
Hongze Cheng 已提交
293
void tbufWriteBool(SBufferWriter* buf, bool data) { tbufWrite(buf, &data, sizeof(data)); }
weixin_48148422's avatar
weixin_48148422 已提交
294

H
refact  
Hongze Cheng 已提交
295
void tbufWriteBoolAt(SBufferWriter* buf, size_t pos, bool data) { tbufWriteAt(buf, pos, &data, sizeof(data)); }
weixin_48148422's avatar
weixin_48148422 已提交
296

H
refact  
Hongze Cheng 已提交
297
void tbufWriteChar(SBufferWriter* buf, char data) { tbufWrite(buf, &data, sizeof(data)); }
weixin_48148422's avatar
weixin_48148422 已提交
298

H
refact  
Hongze Cheng 已提交
299
void tbufWriteCharAt(SBufferWriter* buf, size_t pos, char data) { tbufWriteAt(buf, pos, &data, sizeof(data)); }
weixin_48148422's avatar
weixin_48148422 已提交
300

H
refact  
Hongze Cheng 已提交
301
void tbufWriteInt8(SBufferWriter* buf, int8_t data) { tbufWrite(buf, &data, sizeof(data)); }
weixin_48148422's avatar
weixin_48148422 已提交
302

H
refact  
Hongze Cheng 已提交
303
void tbufWriteInt8At(SBufferWriter* buf, size_t pos, int8_t data) { tbufWriteAt(buf, pos, &data, sizeof(data)); }
weixin_48148422's avatar
weixin_48148422 已提交
304

H
refact  
Hongze Cheng 已提交
305
void tbufWriteUint8(SBufferWriter* buf, uint8_t data) { tbufWrite(buf, &data, sizeof(data)); }
weixin_48148422's avatar
weixin_48148422 已提交
306

H
refact  
Hongze Cheng 已提交
307
void tbufWriteUint8At(SBufferWriter* buf, size_t pos, uint8_t data) { tbufWriteAt(buf, pos, &data, sizeof(data)); }
weixin_48148422's avatar
weixin_48148422 已提交
308

H
refact  
Hongze Cheng 已提交
309 310 311
void tbufWriteInt16(SBufferWriter* buf, int16_t data) {
  if (buf->endian) {
    data = (int16_t)htons(data);
weixin_48148422's avatar
weixin_48148422 已提交
312
  }
H
refact  
Hongze Cheng 已提交
313
  tbufWrite(buf, &data, sizeof(data));
weixin_48148422's avatar
weixin_48148422 已提交
314 315
}

H
refact  
Hongze Cheng 已提交
316 317 318
void tbufWriteInt16At(SBufferWriter* buf, size_t pos, int16_t data) {
  if (buf->endian) {
    data = (int16_t)htons(data);
weixin_48148422's avatar
weixin_48148422 已提交
319
  }
H
refact  
Hongze Cheng 已提交
320
  tbufWriteAt(buf, pos, &data, sizeof(data));
weixin_48148422's avatar
weixin_48148422 已提交
321 322
}

H
refact  
Hongze Cheng 已提交
323 324 325
void tbufWriteUint16(SBufferWriter* buf, uint16_t data) {
  if (buf->endian) {
    data = htons(data);
weixin_48148422's avatar
weixin_48148422 已提交
326
  }
H
refact  
Hongze Cheng 已提交
327
  tbufWrite(buf, &data, sizeof(data));
weixin_48148422's avatar
weixin_48148422 已提交
328 329
}

H
refact  
Hongze Cheng 已提交
330 331 332
void tbufWriteUint16At(SBufferWriter* buf, size_t pos, uint16_t data) {
  if (buf->endian) {
    data = htons(data);
weixin_48148422's avatar
weixin_48148422 已提交
333
  }
H
refact  
Hongze Cheng 已提交
334
  tbufWriteAt(buf, pos, &data, sizeof(data));
weixin_48148422's avatar
weixin_48148422 已提交
335 336
}

H
refact  
Hongze Cheng 已提交
337 338 339
void tbufWriteInt32(SBufferWriter* buf, int32_t data) {
  if (buf->endian) {
    data = (int32_t)htonl(data);
weixin_48148422's avatar
weixin_48148422 已提交
340
  }
H
refact  
Hongze Cheng 已提交
341
  tbufWrite(buf, &data, sizeof(data));
weixin_48148422's avatar
weixin_48148422 已提交
342 343
}

H
refact  
Hongze Cheng 已提交
344 345 346
void tbufWriteInt32At(SBufferWriter* buf, size_t pos, int32_t data) {
  if (buf->endian) {
    data = (int32_t)htonl(data);
weixin_48148422's avatar
weixin_48148422 已提交
347
  }
H
refact  
Hongze Cheng 已提交
348
  tbufWriteAt(buf, pos, &data, sizeof(data));
weixin_48148422's avatar
weixin_48148422 已提交
349 350
}

H
refact  
Hongze Cheng 已提交
351 352 353
void tbufWriteUint32(SBufferWriter* buf, uint32_t data) {
  if (buf->endian) {
    data = htonl(data);
weixin_48148422's avatar
weixin_48148422 已提交
354
  }
H
refact  
Hongze Cheng 已提交
355
  tbufWrite(buf, &data, sizeof(data));
weixin_48148422's avatar
weixin_48148422 已提交
356 357
}

H
refact  
Hongze Cheng 已提交
358 359 360
void tbufWriteUint32At(SBufferWriter* buf, size_t pos, uint32_t data) {
  if (buf->endian) {
    data = htonl(data);
weixin_48148422's avatar
weixin_48148422 已提交
361
  }
H
refact  
Hongze Cheng 已提交
362
  tbufWriteAt(buf, pos, &data, sizeof(data));
weixin_48148422's avatar
weixin_48148422 已提交
363 364
}

H
refact  
Hongze Cheng 已提交
365 366 367
void tbufWriteInt64(SBufferWriter* buf, int64_t data) {
  if (buf->endian) {
    data = (int64_t)htobe64(data);
weixin_48148422's avatar
weixin_48148422 已提交
368
  }
H
refact  
Hongze Cheng 已提交
369
  tbufWrite(buf, &data, sizeof(data));
weixin_48148422's avatar
weixin_48148422 已提交
370 371
}

H
refact  
Hongze Cheng 已提交
372 373 374
void tbufWriteInt64At(SBufferWriter* buf, size_t pos, int64_t data) {
  if (buf->endian) {
    data = (int64_t)htobe64(data);
weixin_48148422's avatar
weixin_48148422 已提交
375
  }
H
refact  
Hongze Cheng 已提交
376
  tbufWriteAt(buf, pos, &data, sizeof(data));
weixin_48148422's avatar
weixin_48148422 已提交
377 378
}

H
refact  
Hongze Cheng 已提交
379 380 381
void tbufWriteUint64(SBufferWriter* buf, uint64_t data) {
  if (buf->endian) {
    data = htobe64(data);
weixin_48148422's avatar
weixin_48148422 已提交
382
  }
H
refact  
Hongze Cheng 已提交
383
  tbufWrite(buf, &data, sizeof(data));
weixin_48148422's avatar
weixin_48148422 已提交
384 385
}

H
refact  
Hongze Cheng 已提交
386 387 388
void tbufWriteUint64At(SBufferWriter* buf, size_t pos, uint64_t data) {
  if (buf->endian) {
    data = htobe64(data);
weixin_48148422's avatar
weixin_48148422 已提交
389
  }
H
refact  
Hongze Cheng 已提交
390
  tbufWriteAt(buf, pos, &data, sizeof(data));
weixin_48148422's avatar
weixin_48148422 已提交
391 392
}

H
refact  
Hongze Cheng 已提交
393
void tbufWriteFloat(SBufferWriter* buf, float data) {
394 395
  Un4B _un;
  _un.f = data;
H
refact  
Hongze Cheng 已提交
396 397
  if (buf->endian) {
    _un.ui = htonl(_un.ui);
398
  }
H
refact  
Hongze Cheng 已提交
399
  tbufWrite(buf, &_un, sizeof(_un));
weixin_48148422's avatar
weixin_48148422 已提交
400 401
}

H
refact  
Hongze Cheng 已提交
402
void tbufWriteFloatAt(SBufferWriter* buf, size_t pos, float data) {
403 404
  Un4B _un;
  _un.f = data;
H
refact  
Hongze Cheng 已提交
405 406
  if (buf->endian) {
    _un.ui = htonl(_un.ui);
407
  }
H
refact  
Hongze Cheng 已提交
408
  tbufWriteAt(buf, pos, &_un, sizeof(_un));
weixin_48148422's avatar
weixin_48148422 已提交
409 410
}

H
refact  
Hongze Cheng 已提交
411
void tbufWriteDouble(SBufferWriter* buf, double data) {
412 413
  Un8B _un;
  _un.d = data;
H
refact  
Hongze Cheng 已提交
414 415
  if (buf->endian) {
    _un.ull = htobe64(_un.ull);
416
  }
H
refact  
Hongze Cheng 已提交
417
  tbufWrite(buf, &_un, sizeof(_un));
weixin_48148422's avatar
weixin_48148422 已提交
418 419
}

H
refact  
Hongze Cheng 已提交
420
void tbufWriteDoubleAt(SBufferWriter* buf, size_t pos, double data) {
421 422
  Un8B _un;
  _un.d = data;
H
refact  
Hongze Cheng 已提交
423 424
  if (buf->endian) {
    _un.ull = htobe64(_un.ull);
425
  }
H
refact  
Hongze Cheng 已提交
426
  tbufWriteAt(buf, pos, &_un, sizeof(_un));
weixin_48148422's avatar
weixin_48148422 已提交
427
}