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

L
Liu Jicong 已提交
16
#define _DEFAULT_SOURCE
17
#include "tbuffer.h"
S
Shengliang Guan 已提交
18
#include "texception.h"
19

20 21
typedef union Un4B {
  uint32_t ui;
H
refact  
Hongze Cheng 已提交
22
  float    f;
23
} Un4B;
wafwerar's avatar
wafwerar 已提交
24
#if __STDC_VERSION__ >= 201112LL
25 26 27 28 29 30
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 已提交
31
  double   d;
32
} Un8B;
wafwerar's avatar
wafwerar 已提交
33
#if __STDC_VERSION__ >= 201112LL
34 35 36 37
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

38
////////////////////////////////////////////////////////////////////////////////
39
// reader functions
40

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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