PostGIS 3.7.0dev-r@@SVN_REVISION@@
Loading...
Searching...
No Matches
bytebuffer.c
Go to the documentation of this file.
1/**********************************************************************
2 *
3 * PostGIS - Spatial Types for PostgreSQL
4 * http://postgis.net
5 *
6 * PostGIS is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * PostGIS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with PostGIS. If not, see <http://www.gnu.org/licenses/>.
18 *
19 **********************************************************************
20 *
21 * Copyright 2015 Nicklas Avén <nicklas.aven@jordogskog.no>
22 *
23 **********************************************************************/
24
25
26
27#include "liblwgeom_internal.h"
28#include "bytebuffer.h"
29
30
35void
37{
38 if ( size < BYTEBUFFER_STATICSIZE )
39 {
40 s->capacity = BYTEBUFFER_STATICSIZE;
41 s->buf_start = s->buf_static;
42 }
43 else
44 {
45 s->buf_start = lwalloc(size);
46 s->capacity = size;
47 }
48 s->readcursor = s->writecursor = s->buf_start;
49 memset(s->buf_start, 0, s->capacity);
50}
51
55void
57{
58 if ( s->buf_start != s->buf_static )
59 {
60 lwfree(s->buf_start);
61 s->buf_start = NULL;
62 }
63
64 return;
65}
66
71static inline void
72bytebuffer_makeroom(bytebuffer_t *s, size_t size_to_add)
73{
74 LWDEBUGF(2,"Entered bytebuffer_makeroom with space need of %zu", size_to_add);
75 size_t current_write_size = (s->writecursor - s->buf_start);
76 size_t capacity = s->capacity;
77 size_t required_size = current_write_size + size_to_add;
78
79 LWDEBUGF(2,"capacity = %zu and required size = %zu", capacity, required_size);
80 while (capacity < required_size)
81 capacity *= 2;
82
83 if ( capacity > s->capacity )
84 {
85 size_t current_read_size = (s->readcursor - s->buf_start);
86 LWDEBUGF(4,"We need to realloc more memory. New capacity is %zu", capacity);
87 if ( s->buf_start == s->buf_static )
88 {
89 s->buf_start = lwalloc(capacity);
90 memcpy(s->buf_start, s->buf_static, s->capacity);
91 }
92 else
93 {
94 s->buf_start = lwrealloc(s->buf_start, capacity);
95 }
96 s->capacity = capacity;
97 s->writecursor = s->buf_start + current_write_size;
98 s->readcursor = s->buf_start + current_read_size;
99 }
100 return;
101}
102
106{
107 size_t bufsz = bytebuffer_getlength(s);
108 lwvarlena_t *v = lwalloc(bufsz + LWVARHDRSZ);
109 memcpy(v->data, s->buf_start, bufsz);
110 LWSIZE_SET(v->size, bufsz + LWVARHDRSZ);
111 return v;
112}
113
115const uint8_t*
116bytebuffer_get_buffer(const bytebuffer_t *s, size_t *buffer_length)
117{
118 if ( buffer_length )
119 *buffer_length = bytebuffer_getlength(s);
120 return s->buf_start;
121}
122
126void
128{
129 LWDEBUGF(2,"Entered bytebuffer_append_byte with value %d", val);
131 *(s->writecursor)=val;
132 s->writecursor += 1;
133 return;
134}
135
139void
141{
142 LWDEBUG(2,"bytebuffer_append_bytebuffer");
143 size_t size = bytebuffer_getlength(write_from);
144 bytebuffer_makeroom(write_to, size);
145 memcpy(write_to->writecursor, write_from->buf_start, size);
146 write_to->writecursor += size;
147 return;
148}
149
153void
155{
156 bytebuffer_makeroom(b, 16);
158 return;
159}
160
164void
166{
167 bytebuffer_makeroom(b, 16);
169 return;
170}
171
175size_t
177{
178 return (size_t)(s->writecursor - s->buf_start);
179}
180
181/* Unused functions */
182#if 0
183
185uint8_t*
186bytebuffer_get_buffer_copy(const bytebuffer_t *s, size_t *buffer_length)
187{
188 size_t bufsz = bytebuffer_getlength(s);
189 uint8_t *buf = lwalloc(bufsz);
190 memcpy(buf, s->buf_start, bufsz);
191 if ( buffer_length )
192 *buffer_length = bufsz;
193 return buf;
194}
195
200bytebuffer_create(void)
201{
202 LWDEBUG(2,"Entered bytebuffer_create");
203 return bytebuffer_create_with_size(BYTEBUFFER_STARTSIZE);
204}
205
210bytebuffer_create_with_size(size_t size)
211{
212 LWDEBUGF(2,"Entered bytebuffer_create_with_size %d", size);
214
215 s = lwalloc(sizeof(bytebuffer_t));
216 if ( size < BYTEBUFFER_STATICSIZE )
217 {
218 s->capacity = BYTEBUFFER_STATICSIZE;
219 s->buf_start = s->buf_static;
220 }
221 else
222 {
223 s->buf_start = lwalloc(size);
224 s->capacity = size;
225 }
226 s->readcursor = s->writecursor = s->buf_start;
227 memset(s->buf_start,0,s->capacity);
228 LWDEBUGF(4,"We create a buffer on %p of %d bytes", s->buf_start, s->capacity);
229 return s;
230}
231
235void
236bytebuffer_destroy(bytebuffer_t *s)
237{
239 if ( s )
240 lwfree(s);
241
242 return;
243}
244
248void
249bytebuffer_reset_reading(bytebuffer_t *s)
250{
251 s->readcursor = s->buf_start;
252}
253
259void
260bytebuffer_clear(bytebuffer_t *s)
261{
262 s->readcursor = s->writecursor = s->buf_start;
263}
264
268void
269bytebuffer_append_bulk(bytebuffer_t *s, void * start, size_t size)
270{
271 LWDEBUGF(2,"bytebuffer_append_bulk with size %d",size);
272 bytebuffer_makeroom(s, size);
273 memcpy(s->writecursor, start, size);
274 s->writecursor += size;
275 return;
276}
277
278/*
279* Writes Integer to the buffer
280*/
281void
282bytebuffer_append_int(bytebuffer_t *buf, const int val, int swap)
283{
284 LWDEBUGF(2,"Entered bytebuffer_append_int with value %d, swap = %d", val, swap);
285
286 LWDEBUGF(4,"buf_start = %p and write_cursor=%p", buf->buf_start,buf->writecursor);
287 char *iptr = (char*)(&val);
288 int i = 0;
289
290 if ( sizeof(int) != WKB_INT_SIZE )
291 {
292 lwerror("Machine int size is not %d bytes!", WKB_INT_SIZE);
293 }
294
296 /* Machine/request arch mismatch, so flip byte order */
297 if ( swap)
298 {
299 LWDEBUG(4,"Ok, let's do the swapping thing");
300 for ( i = 0; i < WKB_INT_SIZE; i++ )
301 {
302 *(buf->writecursor) = iptr[WKB_INT_SIZE - 1 - i];
303 buf->writecursor += 1;
304 }
305 }
306 /* If machine arch and requested arch match, don't flip byte order */
307 else
308 {
309 LWDEBUG(4,"Ok, let's do the memcopying thing");
310 memcpy(buf->writecursor, iptr, WKB_INT_SIZE);
312 }
313
314 LWDEBUGF(4,"buf_start = %p and write_cursor=%p", buf->buf_start,buf->writecursor);
315 return;
316
317 }
318
319
320
321
322
326void
327bytebuffer_append_double(bytebuffer_t *buf, const double val, int swap)
328{
329 LWDEBUGF(2,"Entered bytebuffer_append_double with value %lf swap = %d", val, swap);
330
331 LWDEBUGF(4,"buf_start = %p and write_cursor=%p", buf->buf_start,buf->writecursor);
332 char *dptr = (char*)(&val);
333 int i = 0;
334
335 if ( sizeof(double) != WKB_DOUBLE_SIZE )
336 {
337 lwerror("Machine double size is not %d bytes!", WKB_DOUBLE_SIZE);
338 }
339
341
342 /* Machine/request arch mismatch, so flip byte order */
343 if ( swap )
344 {
345 LWDEBUG(4,"Ok, let's do the swapping thing");
346 for ( i = 0; i < WKB_DOUBLE_SIZE; i++ )
347 {
348 *(buf->writecursor) = dptr[WKB_DOUBLE_SIZE - 1 - i];
349 buf->writecursor += 1;
350 }
351 }
352 /* If machine arch and requested arch match, don't flip byte order */
353 else
354 {
355 LWDEBUG(4,"Ok, let's do the memcopying thing");
356 memcpy(buf->writecursor, dptr, WKB_DOUBLE_SIZE);
358 }
359
360 LWDEBUG(4,"Return from bytebuffer_append_double");
361 return;
362
363 }
364
368int64_t
369bytebuffer_read_varint(bytebuffer_t *b)
370{
371 size_t size;
372 int64_t val = varint_s64_decode(b->readcursor, b->buf_start + b->capacity, &size);
373 b->readcursor += size;
374 return val;
375}
376
380uint64_t
381bytebuffer_read_uvarint(bytebuffer_t *b)
382{
383 size_t size;
384 uint64_t val = varint_u64_decode(b->readcursor, b->buf_start + b->capacity, &size);
385 b->readcursor += size;
386 return val;
387}
388
389
395bytebuffer_merge(bytebuffer_t **buff_array, int nbuffers)
396{
397 size_t total_size = 0, current_size, acc_size = 0;
398 int i;
399 for ( i = 0; i < nbuffers; i++ )
400 {
401 total_size += bytebuffer_getlength(buff_array[i]);
402 }
403
404 bytebuffer_t *res = bytebuffer_create_with_size(total_size);
405 for ( i = 0; i < nbuffers; i++)
406 {
407 current_size = bytebuffer_getlength(buff_array[i]);
408 memcpy(res->buf_start+acc_size, buff_array[i]->buf_start, current_size);
409 acc_size += current_size;
410 }
411 res->writecursor = res->buf_start + total_size;
412 res->readcursor = res->buf_start;
413 return res;
414}
415
416#endif
const uint8_t * bytebuffer_get_buffer(const bytebuffer_t *s, size_t *buffer_length)
Returns a read-only reference to the internal buffer.
Definition bytebuffer.c:116
void bytebuffer_destroy_buffer(bytebuffer_t *s)
Free the bytebuffer_t and all memory managed within it.
Definition bytebuffer.c:56
lwvarlena_t * bytebuffer_get_buffer_varlena(const bytebuffer_t *s)
Returns a copy of the internal buffer.
Definition bytebuffer.c:105
void bytebuffer_append_bytebuffer(bytebuffer_t *write_to, bytebuffer_t *write_from)
Writes a uint8_t value to the buffer.
Definition bytebuffer.c:140
size_t bytebuffer_getlength(const bytebuffer_t *s)
Returns the length of the current buffer.
Definition bytebuffer.c:176
void bytebuffer_append_byte(bytebuffer_t *s, const uint8_t val)
Writes a uint8_t value to the buffer.
Definition bytebuffer.c:127
void bytebuffer_append_uvarint(bytebuffer_t *b, const uint64_t val)
Writes a unsigned varInt to the buffer.
Definition bytebuffer.c:165
void bytebuffer_append_varint(bytebuffer_t *b, const int64_t val)
Writes a signed varInt to the buffer.
Definition bytebuffer.c:154
void bytebuffer_init_with_size(bytebuffer_t *s, size_t size)
Allocate just the internal buffer of an existing bytebuffer_t struct.
Definition bytebuffer.c:36
static void bytebuffer_makeroom(bytebuffer_t *s, size_t size_to_add)
If necessary, expand the bytebuffer_t internal buffer to accommodate the specified additional size.
Definition bytebuffer.c:72
#define BYTEBUFFER_STATICSIZE
Definition bytebuffer.h:38
#define BYTEBUFFER_STARTSIZE
Definition bytebuffer.h:37
char * s
Definition cu_in_wkt.c:23
void * lwrealloc(void *mem, size_t size)
Definition lwutil.c:242
#define LWVARHDRSZ
Definition liblwgeom.h:311
void * lwalloc(size_t size)
Definition lwutil.c:227
void lwfree(void *mem)
Definition lwutil.c:248
#define LWSIZE_SET(varsize, len)
Definition liblwgeom.h:325
#define WKB_INT_SIZE
#define WKB_DOUBLE_SIZE
Well-Known Binary (WKB) Output Variant Types.
#define LWDEBUG(level, msg)
Definition lwgeom_log.h:101
#define LWDEBUGF(level, msg,...)
Definition lwgeom_log.h:106
void void lwerror(const char *fmt,...) __attribute__((format(printf
Write a notice out to the error handler.
tuple res
Definition window.py:79
size_t capacity
Definition bytebuffer.h:42
uint8_t * readcursor
Definition bytebuffer.h:45
uint8_t * writecursor
Definition bytebuffer.h:44
uint8_t * buf_start
Definition bytebuffer.h:43
uint32_t size
Definition liblwgeom.h:307
char data[]
Definition liblwgeom.h:308
size_t varint_s64_encode_buf(int64_t val, uint8_t *buf)
Definition varint.c:89
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 varint_u64_decode(const uint8_t *the_start, const uint8_t *the_end, size_t *size)
Definition varint.c:109