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/>.
 */

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

21 22
typedef union Un4B {
  uint32_t ui;
H
refact  
Hongze Cheng 已提交
23
  float    f;
24 25 26 27 28 29 30 31
} 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 已提交
32
  double   d;
33 34 35 36 37 38
} 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

39
////////////////////////////////////////////////////////////////////////////////
40
// reader functions
41

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

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

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

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

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

H
refact  
Hongze Cheng 已提交
84 85 86 87
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 已提交
88 89 90
  if (len >= size) {
    len = size - 1;
  }
H
refact  
Hongze Cheng 已提交
91
  memcpy(dst, str, len);
92 93 94 95
  dst[len] = 0;
  return len;
}

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

H
refact  
Hongze Cheng 已提交
106 107 108 109 110
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 已提交
111 112
    len = size;
  }
H
refact  
Hongze Cheng 已提交
113
  memcpy(dst, data, len);
weixin_48148422's avatar
weixin_48148422 已提交
114 115
  return len;
}
116

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

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

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

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

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

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

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

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

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

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

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

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

////////////////////////////////////////////////////////////////////////////////
214
// writer functions
weixin_48148422's avatar
weixin_48148422 已提交
215

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

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

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

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

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

H
refact  
Hongze Cheng 已提交
262 263
void tbufWriteAt(SBufferWriter* buf, size_t pos, const void* data, size_t size) {
  assert(data != NULL);
264 265
  // 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 已提交
266 267
  assert(pos + size <= buf->pos);
  memcpy(buf->data + pos, data, size);
weixin_48148422's avatar
weixin_48148422 已提交
268 269
}

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

H
refact  
Hongze Cheng 已提交
278 279 280 281
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 已提交
282 283
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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