TDengine/source/util/src/tbuffer.c

425 lines
10 KiB
C
Raw Normal View History

/*
* 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/>.
*/
2022-02-03 11:47:27 +00:00
#define _DEFAULT_SOURCE
#include "tbuffer.h"
2022-02-28 01:52:30 +00:00
#include "texception.h"
typedef union Un4B {
uint32_t ui;
2021-12-28 06:23:45 +00:00
float f;
} Un4B;
2022-06-21 12:04:55 +00:00
#if __STDC_VERSION__ >= 201112LL
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;
2021-12-28 06:23:45 +00:00
double d;
} Un8B;
2022-06-21 12:04:55 +00:00
#if __STDC_VERSION__ >= 201112LL
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
////////////////////////////////////////////////////////////////////////////////
2020-04-27 01:16:56 +00:00
// reader functions
2020-04-27 01:16:56 +00:00
size_t tbufSkip(SBufferReader* buf, size_t size) {
2021-12-28 06:23:45 +00:00
if ((buf->pos + size) > buf->size) {
THROW(-1);
}
size_t old = buf->pos;
2020-04-27 01:16:56 +00:00
buf->pos += size;
return old;
}
2021-12-28 06:23:45 +00:00
const char* tbufRead(SBufferReader* buf, size_t size) {
2020-04-27 02:23:07 +00:00
const char* ret = buf->data + buf->pos;
2021-12-28 06:23:45 +00:00
tbufSkip(buf, size);
return ret;
}
2021-12-28 06:23:45 +00:00
void tbufReadToBuffer(SBufferReader* buf, void* dst, size_t size) {
assert(dst != NULL);
// always using memcpy, leave optimization to compiler
2021-12-28 06:23:45 +00:00
memcpy(dst, tbufRead(buf, size), size);
}
2021-12-28 06:23:45 +00:00
static size_t tbufReadLength(SBufferReader* buf) {
2020-04-19 10:52:24 +00:00
// maximum length is 65535, if larger length is required
// this function and the corresponding write function need to be
// revised.
2021-12-28 06:23:45 +00:00
uint16_t l = tbufReadUint16(buf);
2020-04-19 10:52:24 +00:00
return l;
}
2021-12-28 06:23:45 +00:00
const char* tbufReadString(SBufferReader* buf, size_t* len) {
size_t l = tbufReadLength(buf);
2020-04-27 02:23:07 +00:00
const char* ret = buf->data + buf->pos;
2021-12-28 06:23:45 +00:00
tbufSkip(buf, l + 1);
if (ret[l] != 0) {
THROW(-1);
2020-04-27 01:16:56 +00:00
}
2021-12-28 06:23:45 +00:00
if (len != NULL) {
*len = l;
}
return ret;
}
2021-12-28 06:23:45 +00:00
size_t tbufReadToString(SBufferReader* buf, char* dst, size_t size) {
assert(dst != NULL);
size_t len;
const char* str = tbufReadString(buf, &len);
2020-02-17 04:33:36 +00:00
if (len >= size) {
len = size - 1;
}
2021-12-28 06:23:45 +00:00
memcpy(dst, str, len);
dst[len] = 0;
return len;
}
2021-12-28 06:23:45 +00:00
const char* tbufReadBinary(SBufferReader* buf, size_t* len) {
size_t l = tbufReadLength(buf);
2020-04-27 02:23:07 +00:00
const char* ret = buf->data + buf->pos;
2021-12-28 06:23:45 +00:00
tbufSkip(buf, l);
if (len != NULL) {
2020-04-19 10:52:24 +00:00
*len = l;
}
return ret;
}
2021-12-28 06:23:45 +00:00
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) {
2020-04-19 10:52:24 +00:00
len = size;
}
2021-12-28 06:23:45 +00:00
memcpy(dst, data, len);
2020-04-19 10:52:24 +00:00
return len;
}
2021-12-28 06:23:45 +00:00
bool tbufReadBool(SBufferReader* buf) {
2020-04-27 01:16:56 +00:00
bool ret;
2021-12-28 06:23:45 +00:00
tbufReadToBuffer(buf, &ret, sizeof(ret));
2020-04-27 01:16:56 +00:00
return ret;
}
2021-12-28 06:23:45 +00:00
char tbufReadChar(SBufferReader* buf) {
2020-04-27 01:16:56 +00:00
char ret;
2021-12-28 06:23:45 +00:00
tbufReadToBuffer(buf, &ret, sizeof(ret));
2020-04-27 01:16:56 +00:00
return ret;
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
int8_t tbufReadInt8(SBufferReader* buf) {
2020-04-27 01:16:56 +00:00
int8_t ret;
2021-12-28 06:23:45 +00:00
tbufReadToBuffer(buf, &ret, sizeof(ret));
2020-04-27 01:16:56 +00:00
return ret;
}
2021-12-28 06:23:45 +00:00
uint8_t tbufReadUint8(SBufferReader* buf) {
2020-04-27 01:16:56 +00:00
uint8_t ret;
2021-12-28 06:23:45 +00:00
tbufReadToBuffer(buf, &ret, sizeof(ret));
2020-04-27 01:16:56 +00:00
return ret;
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
int16_t tbufReadInt16(SBufferReader* buf) {
2020-04-27 01:16:56 +00:00
int16_t ret;
2021-12-28 06:23:45 +00:00
tbufReadToBuffer(buf, &ret, sizeof(ret));
if (buf->endian) {
return (int16_t)ntohs(ret);
}
2020-04-27 01:16:56 +00:00
return ret;
}
2021-12-28 06:23:45 +00:00
uint16_t tbufReadUint16(SBufferReader* buf) {
2020-04-27 01:16:56 +00:00
uint16_t ret;
2021-12-28 06:23:45 +00:00
tbufReadToBuffer(buf, &ret, sizeof(ret));
if (buf->endian) {
return ntohs(ret);
2020-04-27 01:16:56 +00:00
}
return ret;
}
2021-12-28 06:23:45 +00:00
int32_t tbufReadInt32(SBufferReader* buf) {
2020-04-27 01:16:56 +00:00
int32_t ret;
2021-12-28 06:23:45 +00:00
tbufReadToBuffer(buf, &ret, sizeof(ret));
if (buf->endian) {
return (int32_t)ntohl(ret);
2020-04-27 01:16:56 +00:00
}
return ret;
}
2021-12-28 06:23:45 +00:00
uint32_t tbufReadUint32(SBufferReader* buf) {
2020-04-27 01:16:56 +00:00
uint32_t ret;
2021-12-28 06:23:45 +00:00
tbufReadToBuffer(buf, &ret, sizeof(ret));
if (buf->endian) {
return ntohl(ret);
2020-04-27 01:16:56 +00:00
}
return ret;
}
2021-12-28 06:23:45 +00:00
int64_t tbufReadInt64(SBufferReader* buf) {
2020-04-27 01:16:56 +00:00
int64_t ret;
2021-12-28 06:23:45 +00:00
tbufReadToBuffer(buf, &ret, sizeof(ret));
if (buf->endian) {
return (int64_t)htobe64(ret); // TODO: ntohll
2020-04-27 01:16:56 +00:00
}
return ret;
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
uint64_t tbufReadUint64(SBufferReader* buf) {
2020-04-27 01:16:56 +00:00
uint64_t ret;
2021-12-28 06:23:45 +00:00
tbufReadToBuffer(buf, &ret, sizeof(ret));
if (buf->endian) {
return htobe64(ret); // TODO: ntohll
2020-04-27 01:16:56 +00:00
}
return ret;
}
2021-12-28 06:23:45 +00:00
float tbufReadFloat(SBufferReader* buf) {
Un4B _un;
2021-12-28 06:23:45 +00:00
tbufReadToBuffer(buf, &_un, sizeof(_un));
if (buf->endian) {
_un.ui = ntohl(_un.ui);
}
return _un.f;
}
2020-04-19 10:52:24 +00:00
2020-04-27 01:16:56 +00:00
double tbufReadDouble(SBufferReader* buf) {
Un8B _un;
2021-12-28 06:23:45 +00:00
tbufReadToBuffer(buf, &_un, sizeof(_un));
if (buf->endian) {
_un.ull = htobe64(_un.ull);
}
return _un.d;
2020-04-19 10:52:24 +00:00
}
////////////////////////////////////////////////////////////////////////////////
2020-04-27 01:16:56 +00:00
// writer functions
2020-04-19 10:52:24 +00:00
2021-12-28 06:23:45 +00:00
void tbufCloseWriter(SBufferWriter* buf) {
2022-03-25 16:29:53 +00:00
taosMemoryFreeClear(buf->data);
2021-12-28 06:23:45 +00:00
// (*buf->allocator)( buf->data, 0 ); // potential memory leak.
2020-04-27 01:16:56 +00:00
buf->data = NULL;
buf->pos = 0;
buf->size = 0;
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufEnsureCapacity(SBufferWriter* buf, size_t size) {
2020-04-27 01:16:56 +00:00
size += buf->pos;
2021-12-28 06:23:45 +00:00
if (size > buf->size) {
2020-04-27 01:16:56 +00:00
size_t nsize = size + buf->size;
2021-12-28 06:23:45 +00:00
char* data = (*buf->allocator)(buf->data, nsize);
2020-04-27 01:16:56 +00:00
// TODO: the exception should be thrown by the allocator function
2021-12-28 06:23:45 +00:00
if (data == NULL) {
THROW(-1);
2020-04-27 01:16:56 +00:00
}
buf->data = data;
buf->size = nsize;
}
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
size_t tbufReserve(SBufferWriter* buf, size_t size) {
tbufEnsureCapacity(buf, size);
2020-04-27 01:16:56 +00:00
size_t old = buf->pos;
buf->pos += size;
return old;
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
char* tbufGetData(SBufferWriter* buf, bool takeOver) {
2020-04-27 01:16:56 +00:00
char* ret = buf->data;
2021-12-28 06:23:45 +00:00
if (takeOver) {
2020-04-27 01:16:56 +00:00
buf->pos = 0;
buf->size = 0;
buf->data = NULL;
}
2020-04-19 10:52:24 +00:00
return ret;
}
2021-12-28 06:23:45 +00:00
void tbufWrite(SBufferWriter* buf, const void* data, size_t size) {
assert(data != NULL);
tbufEnsureCapacity(buf, size);
memcpy(buf->data + buf->pos, data, size);
2020-04-27 01:16:56 +00:00
buf->pos += size;
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteAt(SBufferWriter* buf, size_t pos, const void* data, size_t size) {
assert(data != NULL);
2020-04-27 01:16:56 +00:00
// this function can only be called to fill the gap on previous writes,
// so 'pos + size <= buf->pos' must be true
2021-12-28 06:23:45 +00:00
assert(pos + size <= buf->pos);
memcpy(buf->data + pos, data, size);
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
static void tbufWriteLength(SBufferWriter* buf, size_t len) {
2020-04-27 01:16:56 +00:00
// maximum length is 65535, if larger length is required
// this function and the corresponding read function need to be
// revised.
2021-12-28 06:23:45 +00:00
assert(len <= 0xffff);
tbufWriteUint16(buf, (uint16_t)len);
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteStringLen(SBufferWriter* buf, const char* str, size_t len) {
tbufWriteLength(buf, len);
tbufWrite(buf, str, len);
tbufWriteChar(buf, '\0');
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteString(SBufferWriter* buf, const char* str) { tbufWriteStringLen(buf, str, strlen(str)); }
2020-04-19 10:52:24 +00:00
2021-12-28 06:23:45 +00:00
void tbufWriteBinary(SBufferWriter* buf, const void* data, size_t len) {
tbufWriteLength(buf, len);
tbufWrite(buf, data, len);
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteBool(SBufferWriter* buf, bool data) { tbufWrite(buf, &data, sizeof(data)); }
2020-04-19 10:52:24 +00:00
2021-12-28 06:23:45 +00:00
void tbufWriteBoolAt(SBufferWriter* buf, size_t pos, bool data) { tbufWriteAt(buf, pos, &data, sizeof(data)); }
2020-04-19 10:52:24 +00:00
2021-12-28 06:23:45 +00:00
void tbufWriteChar(SBufferWriter* buf, char data) { tbufWrite(buf, &data, sizeof(data)); }
2020-04-19 10:52:24 +00:00
2021-12-28 06:23:45 +00:00
void tbufWriteCharAt(SBufferWriter* buf, size_t pos, char data) { tbufWriteAt(buf, pos, &data, sizeof(data)); }
2020-04-19 10:52:24 +00:00
2021-12-28 06:23:45 +00:00
void tbufWriteInt8(SBufferWriter* buf, int8_t data) { tbufWrite(buf, &data, sizeof(data)); }
2020-04-19 10:52:24 +00:00
2021-12-28 06:23:45 +00:00
void tbufWriteInt8At(SBufferWriter* buf, size_t pos, int8_t data) { tbufWriteAt(buf, pos, &data, sizeof(data)); }
2020-04-19 10:52:24 +00:00
2021-12-28 06:23:45 +00:00
void tbufWriteUint8(SBufferWriter* buf, uint8_t data) { tbufWrite(buf, &data, sizeof(data)); }
2020-04-19 10:52:24 +00:00
2021-12-28 06:23:45 +00:00
void tbufWriteUint8At(SBufferWriter* buf, size_t pos, uint8_t data) { tbufWriteAt(buf, pos, &data, sizeof(data)); }
2020-04-19 10:52:24 +00:00
2021-12-28 06:23:45 +00:00
void tbufWriteInt16(SBufferWriter* buf, int16_t data) {
if (buf->endian) {
data = (int16_t)htons(data);
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
tbufWrite(buf, &data, sizeof(data));
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteInt16At(SBufferWriter* buf, size_t pos, int16_t data) {
if (buf->endian) {
data = (int16_t)htons(data);
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
tbufWriteAt(buf, pos, &data, sizeof(data));
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteUint16(SBufferWriter* buf, uint16_t data) {
if (buf->endian) {
data = htons(data);
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
tbufWrite(buf, &data, sizeof(data));
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteUint16At(SBufferWriter* buf, size_t pos, uint16_t data) {
if (buf->endian) {
data = htons(data);
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
tbufWriteAt(buf, pos, &data, sizeof(data));
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteInt32(SBufferWriter* buf, int32_t data) {
if (buf->endian) {
data = (int32_t)htonl(data);
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
tbufWrite(buf, &data, sizeof(data));
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteInt32At(SBufferWriter* buf, size_t pos, int32_t data) {
if (buf->endian) {
data = (int32_t)htonl(data);
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
tbufWriteAt(buf, pos, &data, sizeof(data));
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteUint32(SBufferWriter* buf, uint32_t data) {
if (buf->endian) {
data = htonl(data);
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
tbufWrite(buf, &data, sizeof(data));
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteUint32At(SBufferWriter* buf, size_t pos, uint32_t data) {
if (buf->endian) {
data = htonl(data);
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
tbufWriteAt(buf, pos, &data, sizeof(data));
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteInt64(SBufferWriter* buf, int64_t data) {
if (buf->endian) {
data = (int64_t)htobe64(data);
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
tbufWrite(buf, &data, sizeof(data));
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteInt64At(SBufferWriter* buf, size_t pos, int64_t data) {
if (buf->endian) {
data = (int64_t)htobe64(data);
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
tbufWriteAt(buf, pos, &data, sizeof(data));
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteUint64(SBufferWriter* buf, uint64_t data) {
if (buf->endian) {
data = htobe64(data);
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
tbufWrite(buf, &data, sizeof(data));
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteUint64At(SBufferWriter* buf, size_t pos, uint64_t data) {
if (buf->endian) {
data = htobe64(data);
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
tbufWriteAt(buf, pos, &data, sizeof(data));
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteFloat(SBufferWriter* buf, float data) {
Un4B _un;
_un.f = data;
2021-12-28 06:23:45 +00:00
if (buf->endian) {
_un.ui = htonl(_un.ui);
}
2021-12-28 06:23:45 +00:00
tbufWrite(buf, &_un, sizeof(_un));
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteFloatAt(SBufferWriter* buf, size_t pos, float data) {
Un4B _un;
_un.f = data;
2021-12-28 06:23:45 +00:00
if (buf->endian) {
_un.ui = htonl(_un.ui);
}
2021-12-28 06:23:45 +00:00
tbufWriteAt(buf, pos, &_un, sizeof(_un));
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteDouble(SBufferWriter* buf, double data) {
Un8B _un;
_un.d = data;
2021-12-28 06:23:45 +00:00
if (buf->endian) {
_un.ull = htobe64(_un.ull);
}
2021-12-28 06:23:45 +00:00
tbufWrite(buf, &_un, sizeof(_un));
2020-04-19 10:52:24 +00:00
}
2021-12-28 06:23:45 +00:00
void tbufWriteDoubleAt(SBufferWriter* buf, size_t pos, double data) {
Un8B _un;
_un.d = data;
2021-12-28 06:23:45 +00:00
if (buf->endian) {
_un.ull = htobe64(_un.ull);
}
2021-12-28 06:23:45 +00:00
tbufWriteAt(buf, pos, &_un, sizeof(_un));
2020-04-19 10:52:24 +00:00
}