tcoding.h 10.9 KB
Newer Older
H
hzcheng 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 * Copyright (c) 2019 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/>.
 */
S
Shengliang Guan 已提交
15 16 17

#ifndef _TD_UTIL_CODING_H_
#define _TD_UTIL_CODING_H_
H
hzcheng 已提交
18

S
coding  
Shengliang Guan 已提交
19 20
#include "os.h"

H
hzcheng 已提交
21 22 23 24
#ifdef __cplusplus
extern "C" {
#endif

S
coding  
Shengliang Guan 已提交
25
#define ENCODE_LIMIT  (((uint8_t)1) << 7)
H
Hongze Cheng 已提交
26 27 28
#define ZIGZAGE(T, v) ((u##T)((v) >> (sizeof(T) * 8 - 1))) ^ (((u##T)(v)) << 1)  // zigzag encode
#define ZIGZAGD(T, v) ((v) >> 1) ^ -((T)((v)&1))                                 // zigzag decode

H
more  
Hongze Cheng 已提交
29 30
/* ------------------------ LEGACY CODES ------------------------ */
#if 1
H
Hongze Cheng 已提交
31
// ---- Fixed U8
S
coding  
Shengliang Guan 已提交
32
static FORCE_INLINE int32_t taosEncodeFixedU8(void **buf, uint8_t value) {
H
TD-353  
Hongze Cheng 已提交
33 34 35 36 37
  if (buf != NULL) {
    ((uint8_t *)(*buf))[0] = value;
    *buf = POINTER_SHIFT(*buf, sizeof(value));
  }

S
coding  
Shengliang Guan 已提交
38
  return (int32_t)sizeof(value);
H
TD-185  
Hongze Cheng 已提交
39 40
}

L
Liu Jicong 已提交
41
static FORCE_INLINE void *taosDecodeFixedU8(const void *buf, uint8_t *value) {
H
Hongze Cheng 已提交
42 43 44 45 46
  *value = ((uint8_t *)buf)[0];
  return POINTER_SHIFT(buf, sizeof(*value));
}

// ---- Fixed I8
S
coding  
Shengliang Guan 已提交
47
static FORCE_INLINE int32_t taosEncodeFixedI8(void **buf, int8_t value) {
H
TD-353  
Hongze Cheng 已提交
48 49 50 51
  if (buf != NULL) {
    ((int8_t *)(*buf))[0] = value;
    *buf = POINTER_SHIFT(*buf, sizeof(value));
  }
S
coding  
Shengliang Guan 已提交
52
  return (int32_t)sizeof(value);
H
Hongze Cheng 已提交
53 54
}

L
Liu Jicong 已提交
55
static FORCE_INLINE void *taosDecodeFixedI8(const void *buf, int8_t *value) {
H
Hongze Cheng 已提交
56 57 58 59 60
  *value = ((int8_t *)buf)[0];
  return POINTER_SHIFT(buf, sizeof(*value));
}

// ---- Fixed U16
S
coding  
Shengliang Guan 已提交
61
static FORCE_INLINE int32_t taosEncodeFixedU16(void **buf, uint16_t value) {
H
TD-353  
Hongze Cheng 已提交
62 63 64 65 66 67 68 69
  if (buf != NULL) {
    if (IS_LITTLE_ENDIAN()) {
      memcpy(*buf, &value, sizeof(value));
    } else {
      ((uint8_t *)(*buf))[0] = value & 0xff;
      ((uint8_t *)(*buf))[1] = (value >> 8) & 0xff;
    }
    *buf = POINTER_SHIFT(*buf, sizeof(value));
H
hzcheng 已提交
70 71
  }

S
coding  
Shengliang Guan 已提交
72
  return (int32_t)sizeof(value);
H
hzcheng 已提交
73 74
}

L
Liu Jicong 已提交
75
static FORCE_INLINE void *taosDecodeFixedU16(const void *buf, uint16_t *value) {
H
hzcheng 已提交
76
  if (IS_LITTLE_ENDIAN()) {
H
Hongze Cheng 已提交
77
    memcpy(value, buf, sizeof(*value));
H
hzcheng 已提交
78
  } else {
H
Hongze Cheng 已提交
79 80
    ((uint8_t *)value)[1] = ((uint8_t *)buf)[0];
    ((uint8_t *)value)[0] = ((uint8_t *)buf)[1];
H
hzcheng 已提交
81 82
  }

H
Hongze Cheng 已提交
83 84 85 86
  return POINTER_SHIFT(buf, sizeof(*value));
}

// ---- Fixed I16
S
coding  
Shengliang Guan 已提交
87
static FORCE_INLINE int32_t taosEncodeFixedI16(void **buf, int16_t value) {
H
Hongze Cheng 已提交
88
  return taosEncodeFixedU16(buf, ZIGZAGE(int16_t, value));
H
hzcheng 已提交
89 90
}

L
Liu Jicong 已提交
91
static FORCE_INLINE void *taosDecodeFixedI16(const void *buf, int16_t *value) {
H
Hongze Cheng 已提交
92
  uint16_t tvalue = 0;
L
Liu Jicong 已提交
93
  void    *ret = taosDecodeFixedU16(buf, &tvalue);
H
Hongze Cheng 已提交
94 95 96 97 98
  *value = ZIGZAGD(int16_t, tvalue);
  return ret;
}

// ---- Fixed U32
S
coding  
Shengliang Guan 已提交
99
static FORCE_INLINE int32_t taosEncodeFixedU32(void **buf, uint32_t value) {
H
TD-353  
Hongze Cheng 已提交
100 101 102 103 104 105 106 107 108 109
  if (buf != NULL) {
    if (IS_LITTLE_ENDIAN()) {
      memcpy(*buf, &value, sizeof(value));
    } else {
      ((uint8_t *)(*buf))[0] = value & 0xff;
      ((uint8_t *)(*buf))[1] = (value >> 8) & 0xff;
      ((uint8_t *)(*buf))[2] = (value >> 16) & 0xff;
      ((uint8_t *)(*buf))[3] = (value >> 24) & 0xff;
    }
    *buf = POINTER_SHIFT(*buf, sizeof(value));
H
hzcheng 已提交
110 111
  }

S
coding  
Shengliang Guan 已提交
112
  return (int32_t)sizeof(value);
H
hzcheng 已提交
113 114
}

L
Liu Jicong 已提交
115
static FORCE_INLINE void *taosDecodeFixedU32(const void *buf, uint32_t *value) {
H
hzcheng 已提交
116 117 118
  if (IS_LITTLE_ENDIAN()) {
    memcpy(value, buf, sizeof(*value));
  } else {
H
Hongze Cheng 已提交
119 120 121 122
    ((uint8_t *)value)[3] = ((uint8_t *)buf)[0];
    ((uint8_t *)value)[2] = ((uint8_t *)buf)[1];
    ((uint8_t *)value)[1] = ((uint8_t *)buf)[2];
    ((uint8_t *)value)[0] = ((uint8_t *)buf)[3];
H
hzcheng 已提交
123 124
  }

H
hzcheng 已提交
125
  return POINTER_SHIFT(buf, sizeof(*value));
H
hzcheng 已提交
126 127
}

H
Hongze Cheng 已提交
128
// ---- Fixed I32
S
coding  
Shengliang Guan 已提交
129
static FORCE_INLINE int32_t taosEncodeFixedI32(void **buf, int32_t value) {
H
Hongze Cheng 已提交
130 131 132
  return taosEncodeFixedU32(buf, ZIGZAGE(int32_t, value));
}

L
Liu Jicong 已提交
133
static FORCE_INLINE void *taosDecodeFixedI32(const void *buf, int32_t *value) {
H
Hongze Cheng 已提交
134
  uint32_t tvalue = 0;
L
Liu Jicong 已提交
135
  void    *ret = taosDecodeFixedU32(buf, &tvalue);
H
Hongze Cheng 已提交
136 137 138 139 140
  *value = ZIGZAGD(int32_t, tvalue);
  return ret;
}

// ---- Fixed U64
S
coding  
Shengliang Guan 已提交
141
static FORCE_INLINE int32_t taosEncodeFixedU64(void **buf, uint64_t value) {
H
TD-353  
Hongze Cheng 已提交
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
  if (buf != NULL) {
    if (IS_LITTLE_ENDIAN()) {
      memcpy(*buf, &value, sizeof(value));
    } else {
      ((uint8_t *)(*buf))[0] = value & 0xff;
      ((uint8_t *)(*buf))[1] = (value >> 8) & 0xff;
      ((uint8_t *)(*buf))[2] = (value >> 16) & 0xff;
      ((uint8_t *)(*buf))[3] = (value >> 24) & 0xff;
      ((uint8_t *)(*buf))[4] = (value >> 32) & 0xff;
      ((uint8_t *)(*buf))[5] = (value >> 40) & 0xff;
      ((uint8_t *)(*buf))[6] = (value >> 48) & 0xff;
      ((uint8_t *)(*buf))[7] = (value >> 56) & 0xff;
    }

    *buf = POINTER_SHIFT(*buf, sizeof(value));
H
hzcheng 已提交
157 158
  }

S
coding  
Shengliang Guan 已提交
159
  return (int32_t)sizeof(value);
H
hzcheng 已提交
160 161
}

L
Liu Jicong 已提交
162
static FORCE_INLINE void *taosDecodeFixedU64(const void *buf, uint64_t *value) {
H
hzcheng 已提交
163 164 165
  if (IS_LITTLE_ENDIAN()) {
    memcpy(value, buf, sizeof(*value));
  } else {
H
hzcheng 已提交
166 167 168 169 170 171 172 173
    ((uint8_t *)value)[7] = ((uint8_t *)buf)[0];
    ((uint8_t *)value)[6] = ((uint8_t *)buf)[1];
    ((uint8_t *)value)[5] = ((uint8_t *)buf)[2];
    ((uint8_t *)value)[4] = ((uint8_t *)buf)[3];
    ((uint8_t *)value)[3] = ((uint8_t *)buf)[4];
    ((uint8_t *)value)[2] = ((uint8_t *)buf)[5];
    ((uint8_t *)value)[1] = ((uint8_t *)buf)[6];
    ((uint8_t *)value)[0] = ((uint8_t *)buf)[7];
H
hzcheng 已提交
174 175
  }

H
hzcheng 已提交
176 177 178
  return POINTER_SHIFT(buf, sizeof(*value));
}

H
Hongze Cheng 已提交
179
// ---- Fixed I64
S
coding  
Shengliang Guan 已提交
180
static FORCE_INLINE int32_t taosEncodeFixedI64(void **buf, int64_t value) {
H
Hongze Cheng 已提交
181
  return taosEncodeFixedU64(buf, ZIGZAGE(int64_t, value));
H
hzcheng 已提交
182 183
}

L
Liu Jicong 已提交
184
static FORCE_INLINE void *taosDecodeFixedI64(const void *buf, int64_t *value) {
H
Hongze Cheng 已提交
185
  uint64_t tvalue = 0;
L
Liu Jicong 已提交
186
  void    *ret = taosDecodeFixedU64(buf, &tvalue);
H
Hongze Cheng 已提交
187 188
  *value = ZIGZAGD(int64_t, tvalue);
  return ret;
H
hzcheng 已提交
189 190
}

H
Hongze Cheng 已提交
191
// ---- Variant U16
S
coding  
Shengliang Guan 已提交
192 193
static FORCE_INLINE int32_t taosEncodeVariantU16(void **buf, uint16_t value) {
  int32_t i = 0;
H
hzcheng 已提交
194
  while (value >= ENCODE_LIMIT) {
195
    if (buf != NULL) ((uint8_t *)(*buf))[i] = (uint8_t)(value | ENCODE_LIMIT);
H
hzcheng 已提交
196 197
    value >>= 7;
    i++;
H
Hongze Cheng 已提交
198
    ASSERT(i < 3);
H
hzcheng 已提交
199 200
  }

H
TD-353  
Hongze Cheng 已提交
201
  if (buf != NULL) {
202
    ((uint8_t *)(*buf))[i] = (uint8_t)value;
H
TD-353  
Hongze Cheng 已提交
203 204
    *buf = POINTER_SHIFT(*buf, i + 1);
  }
H
hzcheng 已提交
205

H
TD-353  
Hongze Cheng 已提交
206
  return i + 1;
H
hzcheng 已提交
207 208
}

L
Liu Jicong 已提交
209
static FORCE_INLINE void *taosDecodeVariantU16(const void *buf, uint16_t *value) {
S
coding  
Shengliang Guan 已提交
210
  int32_t  i = 0;
H
hzcheng 已提交
211
  uint16_t tval = 0;
H
hzcheng 已提交
212
  *value = 0;
H
hzcheng 已提交
213 214 215 216 217 218 219 220 221 222 223 224 225 226
  while (i < 3) {
    tval = (uint16_t)(((uint8_t *)buf)[i]);
    if (tval < ENCODE_LIMIT) {
      (*value) |= (tval << (7 * i));
      return POINTER_SHIFT(buf, i + 1);
    } else {
      (*value) |= ((tval & (ENCODE_LIMIT - 1)) << (7 * i));
      i++;
    }
  }

  return NULL;  // error happened
}

H
Hongze Cheng 已提交
227
// ---- Variant I16
S
coding  
Shengliang Guan 已提交
228
static FORCE_INLINE int32_t taosEncodeVariantI16(void **buf, int16_t value) {
H
Hongze Cheng 已提交
229 230 231
  return taosEncodeVariantU16(buf, ZIGZAGE(int16_t, value));
}

L
Liu Jicong 已提交
232
static FORCE_INLINE void *taosDecodeVariantI16(const void *buf, int16_t *value) {
H
Hongze Cheng 已提交
233
  uint16_t tvalue = 0;
L
Liu Jicong 已提交
234
  void    *ret = taosDecodeVariantU16(buf, &tvalue);
H
Hongze Cheng 已提交
235 236 237 238 239
  *value = ZIGZAGD(int16_t, tvalue);
  return ret;
}

// ---- Variant U32
S
coding  
Shengliang Guan 已提交
240 241
static FORCE_INLINE int32_t taosEncodeVariantU32(void **buf, uint32_t value) {
  int32_t i = 0;
H
Hongze Cheng 已提交
242
  while (value >= ENCODE_LIMIT) {
H
TD-353  
Hongze Cheng 已提交
243
    if (buf != NULL) ((uint8_t *)(*buf))[i] = (value | ENCODE_LIMIT);
H
Hongze Cheng 已提交
244 245 246 247 248
    value >>= 7;
    i++;
    ASSERT(i < 5);
  }

H
TD-353  
Hongze Cheng 已提交
249 250 251 252
  if (buf != NULL) {
    ((uint8_t *)(*buf))[i] = value;
    *buf = POINTER_SHIFT(*buf, i + 1);
  }
H
Hongze Cheng 已提交
253

H
TD-353  
Hongze Cheng 已提交
254
  return i + 1;
H
Hongze Cheng 已提交
255 256
}

L
Liu Jicong 已提交
257
static FORCE_INLINE void *taosDecodeVariantU32(const void *buf, uint32_t *value) {
S
coding  
Shengliang Guan 已提交
258
  int32_t  i = 0;
H
hzcheng 已提交
259 260 261 262 263 264 265 266 267 268 269
  uint32_t tval = 0;
  *value = 0;
  while (i < 5) {
    tval = (uint32_t)(((uint8_t *)buf)[i]);
    if (tval < ENCODE_LIMIT) {
      (*value) |= (tval << (7 * i));
      return POINTER_SHIFT(buf, i + 1);
    } else {
      (*value) |= ((tval & (ENCODE_LIMIT - 1)) << (7 * i));
      i++;
    }
H
hzcheng 已提交
270 271
  }

H
hzcheng 已提交
272
  return NULL;  // error happened
H
hzcheng 已提交
273 274
}

H
Hongze Cheng 已提交
275
// ---- Variant I32
S
coding  
Shengliang Guan 已提交
276
static FORCE_INLINE int32_t taosEncodeVariantI32(void **buf, int32_t value) {
H
Hongze Cheng 已提交
277 278 279
  return taosEncodeVariantU32(buf, ZIGZAGE(int32_t, value));
}

L
Liu Jicong 已提交
280
static FORCE_INLINE void *taosDecodeVariantI32(const void *buf, int32_t *value) {
H
Hongze Cheng 已提交
281
  uint32_t tvalue = 0;
L
Liu Jicong 已提交
282
  void    *ret = taosDecodeVariantU32(buf, &tvalue);
H
Hongze Cheng 已提交
283 284 285 286 287
  *value = ZIGZAGD(int32_t, tvalue);
  return ret;
}

// ---- Variant U64
S
coding  
Shengliang Guan 已提交
288 289
static FORCE_INLINE int32_t taosEncodeVariantU64(void **buf, uint64_t value) {
  int32_t i = 0;
H
Hongze Cheng 已提交
290
  while (value >= ENCODE_LIMIT) {
291
    if (buf != NULL) ((uint8_t *)(*buf))[i] = (uint8_t)(value | ENCODE_LIMIT);
H
Hongze Cheng 已提交
292 293 294 295 296
    value >>= 7;
    i++;
    ASSERT(i < 10);
  }

H
TD-353  
Hongze Cheng 已提交
297
  if (buf != NULL) {
298
    ((uint8_t *)(*buf))[i] = (uint8_t)value;
H
TD-353  
Hongze Cheng 已提交
299 300
    *buf = POINTER_SHIFT(*buf, i + 1);
  }
H
Hongze Cheng 已提交
301

H
TD-353  
Hongze Cheng 已提交
302
  return i + 1;
H
Hongze Cheng 已提交
303 304
}

L
Liu Jicong 已提交
305
static FORCE_INLINE void *taosDecodeVariantU64(const void *buf, uint64_t *value) {
S
coding  
Shengliang Guan 已提交
306
  int32_t  i = 0;
H
hzcheng 已提交
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
  uint64_t tval = 0;
  *value = 0;
  while (i < 10) {
    tval = (uint64_t)(((uint8_t *)buf)[i]);
    if (tval < ENCODE_LIMIT) {
      (*value) |= (tval << (7 * i));
      return POINTER_SHIFT(buf, i + 1);
    } else {
      (*value) |= ((tval & (ENCODE_LIMIT - 1)) << (7 * i));
      i++;
    }
  }

  return NULL;  // error happened
}
H
hzcheng 已提交
322

H
Hongze Cheng 已提交
323
// ---- Variant I64
S
coding  
Shengliang Guan 已提交
324
static FORCE_INLINE int32_t taosEncodeVariantI64(void **buf, int64_t value) {
H
Hongze Cheng 已提交
325 326 327
  return taosEncodeVariantU64(buf, ZIGZAGE(int64_t, value));
}

L
Liu Jicong 已提交
328
static FORCE_INLINE void *taosDecodeVariantI64(const void *buf, int64_t *value) {
H
Hongze Cheng 已提交
329
  uint64_t tvalue = 0;
L
Liu Jicong 已提交
330
  void    *ret = taosDecodeVariantU64(buf, &tvalue);
H
Hongze Cheng 已提交
331 332 333 334 335
  *value = ZIGZAGD(int64_t, tvalue);
  return ret;
}

// ---- string
S
coding  
Shengliang Guan 已提交
336 337 338
static FORCE_INLINE int32_t taosEncodeString(void **buf, const char *value) {
  int32_t tlen = 0;
  size_t  size = strlen(value);
H
TD-354  
Hongze Cheng 已提交
339

H
TD-353  
Hongze Cheng 已提交
340 341 342 343 344
  tlen += taosEncodeVariantU64(buf, size);
  if (buf != NULL) {
    memcpy(*buf, value, size);
    *buf = POINTER_SHIFT(*buf, size);
  }
S
coding  
Shengliang Guan 已提交
345
  tlen += (int32_t)size;
H
TD-354  
Hongze Cheng 已提交
346

H
TD-353  
Hongze Cheng 已提交
347
  return tlen;
H
TD-354  
Hongze Cheng 已提交
348 349
}

L
Liu Jicong 已提交
350
static FORCE_INLINE void *taosDecodeString(const void *buf, char **value) {
H
TD-354  
Hongze Cheng 已提交
351 352
  uint64_t size = 0;

H
Hongze Cheng 已提交
353
  buf = taosDecodeVariantU64(buf, &size);
wafwerar's avatar
wafwerar 已提交
354
  *value = (char *)taosMemoryMalloc((size_t)size + 1);
355

H
TD-354  
Hongze Cheng 已提交
356
  if (*value == NULL) return NULL;
357
  memcpy(*value, buf, (size_t)size);
H
TD-354  
Hongze Cheng 已提交
358 359 360 361 362 363

  (*value)[size] = '\0';

  return POINTER_SHIFT(buf, size);
}

L
Liu Jicong 已提交
364
static FORCE_INLINE void *taosDecodeStringTo(const void *buf, char *value) {
H
more  
Hongze Cheng 已提交
365 366 367 368 369 370 371 372 373 374
  uint64_t size = 0;

  buf = taosDecodeVariantU64(buf, &size);
  memcpy(value, buf, (size_t)size);

  value[size] = '\0';

  return POINTER_SHIFT(buf, size);
}

L
Liu Jicong 已提交
375
// ---- binary
S
coding  
Shengliang Guan 已提交
376 377
static FORCE_INLINE int32_t taosEncodeBinary(void **buf, const void *value, int32_t valueLen) {
  int32_t tlen = 0;
L
Liu Jicong 已提交
378 379 380 381 382

  if (buf != NULL) {
    memcpy(*buf, value, valueLen);
    *buf = POINTER_SHIFT(*buf, valueLen);
  }
S
coding  
Shengliang Guan 已提交
383
  tlen += (int32_t)valueLen;
L
Liu Jicong 已提交
384 385 386 387

  return tlen;
}

L
Liu Jicong 已提交
388
static FORCE_INLINE void *taosDecodeBinary(const void *buf, void **value, int32_t valueLen) {
wafwerar's avatar
wafwerar 已提交
389
  *value = taosMemoryMalloc((size_t)valueLen);
L
Liu Jicong 已提交
390
  if (*value == NULL) return NULL;
L
Liu Jicong 已提交
391
  memcpy(*value, buf, (size_t)valueLen);
L
Liu Jicong 已提交
392

L
Liu Jicong 已提交
393 394 395
  return POINTER_SHIFT(buf, valueLen);
}

L
Liu Jicong 已提交
396
static FORCE_INLINE void *taosDecodeBinaryTo(const void *buf, void *value, int32_t valueLen) {
L
Liu Jicong 已提交
397 398
  memcpy(value, buf, (size_t)valueLen);
  return POINTER_SHIFT(buf, valueLen);
L
Liu Jicong 已提交
399 400
}

H
more  
Hongze Cheng 已提交
401 402
#endif

H
hzcheng 已提交
403 404 405 406
#ifdef __cplusplus
}
#endif

S
Shengliang Guan 已提交
407
#endif /*_TD_UTIL_CODING_H_*/