Finalized varint implementation along with zigzag implementation

This commit is contained in:
Gabriel Tofvesson 2018-11-25 17:08:53 +01:00
parent a0e8c61008
commit 14104ebb54
3 changed files with 66 additions and 8 deletions

3
.gitignore vendored
View File

@ -50,3 +50,6 @@ modules.order
Module.symvers
Mkfile.old
dkms.conf
# Output build artifacts
bin/

6
bits.h
View File

@ -12,7 +12,7 @@ union sig_ll {
signed long long value : SIZE_LL;
struct {
unsigned long long value : SIZE_LL - 1;
unsigned char sig : 1;
signed char sig : 1;
} signature;
};
@ -21,7 +21,7 @@ union sig_l {
signed long value : SIZE_L;
struct {
unsigned long value : SIZE_L - 1;
unsigned char sig : 1;
signed char sig : 1;
} signature;
};
@ -29,7 +29,7 @@ union sig_i {
signed int value : SIZE_I;
struct {
unsigned int value : SIZE_I - 1;
unsigned char sig : 1;
signed char sig : 1;
} signature;
};

View File

@ -1,18 +1,73 @@
#include "varint.h"
#include <stdlib.h>
varint varint_encode(unsigned long long value){
varint result;
if (value <= 240){
result = (varint)malloc(1);
result[0] = (char)value;
}
else if (value <= 2287)
{
result = (varint)malloc(2);
result[0] = (char)(((value - 240) >> 8) + 241);
result[1] = (char)(value - 240);
}
else if (value <= 67823)
{
result = (varint)malloc(3);
result[0] = 249;
result[1] = (char)((value - 2288) >> 8);
result[2] = (char)(value - 2288);
}
else
{
unsigned long long header = 255;
unsigned long long match = 0x00FFFFFFFFFFFFFFUL;
while (value <= match)
{
--header;
match >>= 8;
}
int max = (int)(header - 247);
result = (varint)malloc(max + 1);
result[0] = (char) header;
for (int i = 0; i < max; ++i)
result[i+1] = (char)(value >> (i << 3));
}
return result;
}
unsigned long long varint_decode(varint varint){
unsigned long long header = (unsigned char)varint[0];
if(header <= 240){
free(varint);
return header;
}
if(header <= 248){
free(varint);
return 240UL + ((header - 241) << 8) + (unsigned char)varint[1];
}
if(header == 249){
free(varint);
return 2288UL + ((unsigned char)varint[1] << 8) + (unsigned char)varint[2];
}
unsigned long result = (unsigned char)varint[1] | ((unsigned char)varint[2] << 8) | ((unsigned char)varint[3]);
int compare = 2;
int head = (int)(header - 247);
while(head > ++compare) result |= (unsigned char)varint[compare + 2] << (compare << 3);
free(varint);
return result;
}
unsigned long long zigzag_encode(signed long long value){
return ((unsigned long long)value << 1) ^ (value >> 63);
union sig_ll convert = {value};
return (convert.signature.value << 1) ^ (unsigned long long)convert.signature.sig;
}
signed long long zigzag_decode(unsigned long long value){
union sig_ll convert = {value << 63};
return (signed long long)((value >> 1) ^ (unsigned long long)convert.signature.sig);
}