00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _VARINT_H
00029 #define _VARINT_H
00030
00031 #include "basictypes.h"
00032
00033
00034 class Varint {
00035 public:
00036
00037 static const int kMax32 = 5;
00038 static const int kMax64 = 10;
00039
00040
00041
00042
00043
00044 static const char* Parse32(const char* ptr, uint32* OUTPUT);
00045 static const char* Parse64(const char* ptr, uint64* OUTPUT);
00046
00047
00048
00049
00050 static char* Encode32(char* ptr, uint32 v);
00051 static char* Encode64(char* ptr, uint64 v);
00052
00053
00054 static int Length32(uint32 v);
00055 static int Length64(uint64 v);
00056 };
00057
00058
00059
00060 inline const char* Varint::Parse32(const char* ptr, uint32* OUTPUT) {
00061
00062 uint32 byte, result;
00063 byte = *(ptr++); result = byte & 127; if (byte < 128) goto done;
00064 byte = *(ptr++); result |= (byte & 127) << 7; if (byte < 128) goto done;
00065 byte = *(ptr++); result |= (byte & 127) << 14; if (byte < 128) goto done;
00066 byte = *(ptr++); result |= (byte & 127) << 21; if (byte < 128) goto done;
00067 byte = *(ptr++); result |= (byte & 127) << 28; if (byte < 128) goto done;
00068 return NULL;
00069 done:
00070 *OUTPUT = result;
00071 return ptr;
00072 }
00073
00074 inline const char* Varint::Parse64(const char* ptr, uint64* OUTPUT) {
00075
00076
00077
00078
00079 uint32 byte, res1, res2=0, res3=0;
00080
00081 byte = *(ptr++); res1 = byte & 127; if (byte < 128) goto done;
00082 byte = *(ptr++); res1 |= (byte & 127) << 7; if (byte < 128) goto done;
00083 byte = *(ptr++); res1 |= (byte & 127) << 14; if (byte < 128) goto done;
00084 byte = *(ptr++); res1 |= (byte & 127) << 21; if (byte < 128) goto done;
00085
00086 byte = *(ptr++); res2 = byte & 127; if (byte < 128) goto done;
00087 byte = *(ptr++); res2 |= (byte & 127) << 7; if (byte < 128) goto done;
00088 byte = *(ptr++); res2 |= (byte & 127) << 14; if (byte < 128) goto done;
00089 byte = *(ptr++); res2 |= (byte & 127) << 21; if (byte < 128) goto done;
00090
00091 byte = *(ptr++); res3 = byte & 127; if (byte < 128) goto done;
00092 byte = *(ptr++); res3 |= (byte & 127) << 7; if (byte < 128) goto done;
00093
00094 return NULL;
00095
00096 done:
00097 *OUTPUT = res1 | (uint64(res2) << 28) | (uint64(res3) << 56);
00098 return ptr;
00099 }
00100
00101 inline int Varint::Length32(uint32 v) {
00102
00103 int nbytes = 0;
00104 do {
00105 nbytes++;
00106 v >>= 7;
00107 } while (v != 0);
00108 return nbytes;
00109 }
00110
00111 inline int Varint::Length64(uint64 v) {
00112
00113 int nbytes = 0;
00114 do {
00115 nbytes++;
00116 v >>= 7;
00117 } while (v != 0);
00118 return nbytes;
00119 }
00120
00121 #endif