protoverse

A metaverse protocol
git clone git://jb55.com/protoverse
Log | Files | Refs | README | LICENSE

varint.c (1323B)


      1 
      2 #include "varint.h"
      3 
      4 size_t varint_size(uint64_t v)
      5 {
      6 	if (v < 0xfd)
      7 		return 1;
      8 	if (v <= 0xffff)
      9 		return 3;
     10 	if (v <= 0xffffffff)
     11 		return 5;
     12 	return 9;
     13 }
     14 
     15 size_t varint_put(unsigned char buf[VARINT_MAX_LEN], uint64_t v)
     16 {
     17 	unsigned char *p = buf;
     18 
     19 	if (v < 0xfd) {
     20 		*(p++) = v;
     21 	} else if (v <= 0xffff) {
     22 		(*p++) = 0xfd;
     23 		(*p++) = v;
     24 		(*p++) = v >> 8;
     25 	} else if (v <= 0xffffffff) {
     26 		(*p++) = 0xfe;
     27 		(*p++) = v;
     28 		(*p++) = v >> 8;
     29 		(*p++) = v >> 16;
     30 		(*p++) = v >> 24;
     31 	} else {
     32 		(*p++) = 0xff;
     33 		(*p++) = v;
     34 		(*p++) = v >> 8;
     35 		(*p++) = v >> 16;
     36 		(*p++) = v >> 24;
     37 		(*p++) = v >> 32;
     38 		(*p++) = v >> 40;
     39 		(*p++) = v >> 48;
     40 		(*p++) = v >> 56;
     41 	}
     42 	return p - buf;
     43 }
     44 
     45 size_t varint_get(const unsigned char *p, size_t max, int64_t *val)
     46 {
     47 	if (max < 1)
     48 		return 0;
     49 
     50 	switch (*p) {
     51 	case 0xfd:
     52 		if (max < 3)
     53 			return 0;
     54 		*val = ((uint64_t)p[2] << 8) + p[1];
     55 		return 3;
     56 	case 0xfe:
     57 		if (max < 5)
     58 			return 0;
     59 		*val = ((uint64_t)p[4] << 24) + ((uint64_t)p[3] << 16)
     60 			+ ((uint64_t)p[2] << 8) + p[1];
     61 		return 5;
     62 	case 0xff:
     63 		if (max < 9)
     64 			return 0;
     65 		*val = ((uint64_t)p[8] << 56) + ((uint64_t)p[7] << 48)
     66 			+ ((uint64_t)p[6] << 40) + ((uint64_t)p[5] << 32)
     67 			+ ((uint64_t)p[4] << 24) + ((uint64_t)p[3] << 16)
     68 			+ ((uint64_t)p[2] << 8) + p[1];
     69 		return 9;
     70 	default:
     71 		*val = *p;
     72 		return 1;
     73 	}
     74 }
     75