PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
cu_varint.c
Go to the documentation of this file.
1/**********************************************************************
2 *
3 * PostGIS - Spatial Types for PostgreSQL
4 * http://postgis.net
5 *
6 * Copyright (C) 2013 Nicklas Avén
7 *
8 * This is free software; you can redistribute and/or modify it under
9 * the terms of the GNU General Public Licence. See the COPYING file.
10 *
11 **********************************************************************/
12
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include "CUnit/Basic.h"
17#include "CUnit/CUnit.h"
18#include "liblwgeom_internal.h"
19#include "varint.h"
20#include "cu_tester.h"
21
22
23
24// size_t varint_u32_encode_buf(uint32_t val, uint8_t *buf);
25// size_t varint_s32_encode_buf(int32_t val, uint8_t *buf);
26// size_t varint_u64_encode_buf(uint64_t val, uint8_t *buf);
27// size_t varint_s64_encode_buf(int64_t val, uint8_t *buf);
28// int64_t varint_s64_decode(const uint8_t *the_start, const uint8_t *the_end, size_t *size);
29// uint64_t varint_u64_decode(const uint8_t *the_start, const uint8_t *the_end, size_t *size);
30//
31// size_t varint_size(const uint8_t *the_start, const uint8_t *the_end);
32//
33
34static void do_test_u32_varint(uint32_t nr, int expected_size, char* expected_res)
35{
36 int size;
37 char *hex;
38 uint8_t buf[16];
39
40 size = varint_u32_encode_buf(nr, buf);
41 if ( size != expected_size )
42 printf("Expected: %d\nObtained: %d\n", expected_size, size);
43
44 CU_ASSERT_EQUAL(size, expected_size);
45
46 hex = hexbytes_from_bytes(buf, size);
47 ASSERT_STRING_EQUAL(hex, expected_res);
48 lwfree(hex);
49}
50
51static void do_test_s32_varint(int32_t nr,int expected_size, char* expected_res)
52{
53 uint8_t buf[16];
54 int size;
55 char *hex;
56
57 size = varint_s32_encode_buf(nr, buf);
58 if ( size != expected_size )
59 {
60 printf("Expected: %d\nObtained: %d\n", expected_size, size);
61 }
62 CU_ASSERT_EQUAL(size,expected_size);
63
64 hex = hexbytes_from_bytes(buf, size);
65 ASSERT_STRING_EQUAL(hex, expected_res);
66 lwfree(hex);
67}
68
69static void do_test_u64_varint(uint64_t nr,int expected_size, char* expected_res)
70{
71 uint8_t buf[16];
72 int size;
73 char *hex;
74
75 size = varint_u64_encode_buf(nr, buf);
76 if ( size != expected_size )
77 {
78 printf("Expected: %d\nObtained: %d\n", expected_size, size);
79 }
80 CU_ASSERT_EQUAL(size,expected_size);
81
82 hex = hexbytes_from_bytes(buf,size);
83 ASSERT_STRING_EQUAL(hex, expected_res);
84 lwfree(hex);
85}
86
87static void do_test_s64_varint(int64_t nr,int expected_size, char* expected_res)
88{
89 uint8_t buf[16];
90 int size;
91 char *hex;
92
93 size = varint_s64_encode_buf(nr, buf);
94 if ( size != expected_size )
95 {
96 printf("Expected: %d\nObtained: %d\n", expected_size, size);
97 }
98 CU_ASSERT_EQUAL(size,expected_size);
99
100 hex = hexbytes_from_bytes(buf,size);
101 ASSERT_STRING_EQUAL(hex, expected_res);
102 lwfree(hex);
103}
104
105static void test_varint(void)
106{
107
108 do_test_u64_varint(1, 1, "01");
109 do_test_u64_varint(300, 2, "AC02");
110 do_test_u64_varint(150, 2, "9601");
111 do_test_u64_varint(240, 2, "F001");
112 do_test_u64_varint(0x4000, 3, "808001");
113 /*
114 0100:0000 0000:0000 - input (0x4000)
115 1000:0000 1000:0000 0000:0001 - output (0x808001)
116 000:0000 000:0000 000:0001 - chop
117 000:0001 000:0000 000:0000 - swap
118 0:0000 0100:0000 0000:0000 - concat = input
119 */
120 do_test_u64_varint(2147483647, 5, "FFFFFFFF07");
121 /*
122 0111:1111 1111:1111 1111:1111 1111:1111 - input (0x7FFFFFFF)
123 1111:1111 1111:1111 1111:1111 1111:1111 0000:0111 - output(0xFFFFFFFF07)
124 111:1111 111:1111 111:1111 111:1111 000:0111 - chop
125 000:0111 111:1111 111:1111 111:1111 111:1111 - swap
126 0111:1111 1111:1111 1111:1111 1111:1111 - concat = input
127 | | | |
128 2^32 2^16 2^8 2^0
129 */
130 do_test_s64_varint(1, 1, "02");
131 do_test_s64_varint(-1, 1, "01");
132 do_test_s64_varint(-2, 1, "03");
133
134 do_test_u32_varint(2147483647, 5, "FFFFFFFF07");
135 /*
136 0111:1111 1111:1111 1111:1111 1111:1111 - input (7fffffff)
137 1111:1111 1111:1111 1111:1111 1111:1111 0000:0111 - output (ffffff07)
138 111:1111 111:1111 111:1111 111:1111 000:0111 - chop
139 000:0111 111:1111 111:1111 111:1111 111:1111 - swap
140 0111:1111 1111:1111 1111:1111 1111:1111 - concat = input
141 | | | |
142 2^32 2^16 2^8 2^0
143 */
144 do_test_s32_varint(2147483647, 5, "FEFFFFFF0F");
145 /*
146 0111:1111 1111:1111 1111:1111 1111:1111 - input (7fffffff)
147 1111:1110 1111:1111 1111:1111 1111:1111 0000:1111 - output(feffffff0f)
148 1111:1111 1111:1111 1111:1111 1111:1111 0000:0111 - zigzag (ffffff07)
149 111:1111 111:1111 111:1111 111:1111 000:0111 - chop
150 000:0111 111:1111 111:1111 111:1111 111:1111 - swap
151 0111:1111 1111:1111 1111:1111 1111:1111 - concat = input
152 | | | |
153 2^32 2^16 2^8 2^0
154 */
155 do_test_s32_varint(-2147483648, 5, "FFFFFFFF0F");
156
157 do_test_s32_varint(1, 1, "02");
158 /*
159 0000:0001 - input (01)
160 0000:0010 - A: input << 1
161 0000:0000 - B: input >> 31
162 0000:0010 - zigzag (A xor B) == output
163 */
164
165 do_test_s32_varint(-1, 1, "01");
166 /*
167 1111:1111 ... 1111:1111 - input (FFFFFFFF)
168 1111:1111 ... 1111:1110 - A: input << 1
169 1111:1111 ... 1111:1111 - B: input >> 31
170 0000:0000 ... 0000:0001 - zigzag (A xor B) == output
171 */
172
173
174}
175
176
177static void do_test_u64_roundtrip(uint64_t i64_in)
178{
179 uint8_t buffer[16];
180 uint64_t i64_out;
181 size_t size_in, size_out;
182 size_in = varint_u64_encode_buf(i64_in, buffer);
183 i64_out = varint_u64_decode(buffer, buffer + size_in, &size_out);
184 CU_ASSERT_EQUAL(i64_in, i64_out);
185 CU_ASSERT_EQUAL(size_in, size_out);
186}
187
188static void do_test_s64_roundtrip(int64_t i64_in)
189{
190 uint8_t buffer[16];
191 int64_t i64_out;
192 size_t size_in, size_out;
193 size_in = varint_s64_encode_buf(i64_in, buffer);
194 i64_out = varint_s64_decode(buffer, buffer + size_in, &size_out);
195 CU_ASSERT_EQUAL(i64_in, i64_out);
196 CU_ASSERT_EQUAL(size_in, size_out);
197}
198
199static void test_varint_roundtrip(void)
200{
201
202 do_test_u64_roundtrip(0xFFFFFFFFFFFFFFFF);
203
204 int i;
205 for ( i = 0; i < 1024; i += 63 )
206 {
210 }
211}
212
213static void test_zigzag(void)
214{
215 int64_t a;
216 int32_t b;
217 int i;
218
219 for ( i = 1; i < 1024; i += 31 )
220 {
221 a = b = i;
222 CU_ASSERT_EQUAL(a, unzigzag64(zigzag64(a)));
223 CU_ASSERT_EQUAL(b, unzigzag32(zigzag32(b)));
224
225 a = b = -1 * i;
226 CU_ASSERT_EQUAL(a, unzigzag64(zigzag64(a)));
227 CU_ASSERT_EQUAL(b, unzigzag32(zigzag32(b)));
228 }
229
230 //8
231 CU_ASSERT_EQUAL(-INT8_MAX, unzigzag8(zigzag8(-INT8_MAX)));
232 CU_ASSERT_EQUAL(INT8_MAX, unzigzag8(zigzag8(INT8_MAX)));
233 CU_ASSERT_EQUAL(0, unzigzag8(zigzag8(0)));
234
235 //32
236 CU_ASSERT_EQUAL(-INT32_MAX, unzigzag32(zigzag32(-INT32_MAX)));
237 CU_ASSERT_EQUAL(INT32_MAX, unzigzag32(zigzag32(INT32_MAX)));
238 CU_ASSERT_EQUAL(0, unzigzag32(zigzag32(0)));
239
240 //64
241 CU_ASSERT_EQUAL(-INT64_MAX, unzigzag64(zigzag64(-INT64_MAX)));
242 CU_ASSERT_EQUAL(INT64_MAX, unzigzag64(zigzag64(INT64_MAX)));
243 CU_ASSERT_EQUAL(0, unzigzag64(zigzag64(0)));
244}
245
246
247/*
248** Used by the test harness to register the tests in this file.
249*/
250void varint_suite_setup(void);
252{
253 CU_pSuite suite = CU_add_suite("varint", NULL, NULL);
254 PG_ADD_TEST(suite, test_zigzag);
255 PG_ADD_TEST(suite, test_varint);
257}
static void do_test_s32_varint(int32_t nr, int expected_size, char *expected_res)
Definition cu_varint.c:51
static void do_test_u32_varint(uint32_t nr, int expected_size, char *expected_res)
Definition cu_varint.c:34
static void test_zigzag(void)
Definition cu_varint.c:213
static void test_varint_roundtrip(void)
Definition cu_varint.c:199
static void test_varint(void)
Definition cu_varint.c:105
static void do_test_u64_varint(uint64_t nr, int expected_size, char *expected_res)
Definition cu_varint.c:69
static void do_test_u64_roundtrip(uint64_t i64_in)
Definition cu_varint.c:177
static void do_test_s64_roundtrip(int64_t i64_in)
Definition cu_varint.c:188
void varint_suite_setup(void)
Definition cu_varint.c:251
static void do_test_s64_varint(int64_t nr, int expected_size, char *expected_res)
Definition cu_varint.c:87
#define PG_ADD_TEST(suite, testfunc)
#define ASSERT_STRING_EQUAL(o, e)
char * hexbytes_from_bytes(const uint8_t *bytes, size_t size)
Definition lwout_wkb.c:40
void lwfree(void *mem)
Definition lwutil.c:248
#define INT32_MAX
#define INT8_MAX
Datum buffer(PG_FUNCTION_ARGS)
int64_t unzigzag64(uint64_t val)
Definition varint.c:190
int32_t unzigzag32(uint32_t val)
Definition varint.c:197
size_t varint_s32_encode_buf(int32_t val, uint8_t *buf)
Definition varint.c:95
size_t varint_s64_encode_buf(int64_t val, uint8_t *buf)
Definition varint.c:89
int8_t unzigzag8(uint8_t val)
Definition varint.c:204
size_t varint_u64_encode_buf(uint64_t val, uint8_t *buf)
Definition varint.c:76
int64_t varint_s64_decode(const uint8_t *the_start, const uint8_t *the_end, size_t *size)
Definition varint.c:102
uint64_t zigzag64(int64_t val)
Definition varint.c:169
uint64_t varint_u64_decode(const uint8_t *the_start, const uint8_t *the_end, size_t *size)
Definition varint.c:109
uint32_t zigzag32(int32_t val)
Definition varint.c:176
uint8_t zigzag8(int8_t val)
Definition varint.c:183
size_t varint_u32_encode_buf(uint32_t val, uint8_t *buf)
Definition varint.c:83