PostGIS  2.4.9dev-r@@SVN_REVISION@@
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 
35 {
36  LWDEBUG(2,"Entered bytebuffer_create");
38 }
39 
45 {
46  LWDEBUGF(2,"Entered bytebuffer_create_with_size %d", size);
47  bytebuffer_t *s;
48 
49  s = lwalloc(sizeof(bytebuffer_t));
50  if ( size < BYTEBUFFER_STATICSIZE )
51  {
53  s->buf_start = s->buf_static;
54  }
55  else
56  {
57  s->buf_start = lwalloc(size);
58  s->capacity = size;
59  }
60  s->readcursor = s->writecursor = s->buf_start;
61  memset(s->buf_start,0,s->capacity);
62  LWDEBUGF(4,"We create a buffer on %p of %d bytes", s->buf_start, s->capacity);
63  return s;
64 }
65 
70 void
72 {
73  if ( size < BYTEBUFFER_STATICSIZE )
74  {
76  s->buf_start = s->buf_static;
77  }
78  else
79  {
80  s->buf_start = lwalloc(size);
81  s->capacity = size;
82  }
83  s->readcursor = s->writecursor = s->buf_start;
84  memset(s->buf_start, 0, s->capacity);
85 }
86 
90 void
92 {
94  if ( s )
95  lwfree(s);
96 
97  return;
98 }
99 
103 void
105 {
106  if ( s->buf_start != s->buf_static )
107  {
108  lwfree(s->buf_start);
109  s->buf_start = NULL;
110  }
111 
112  return;
113 }
114 
118 void
120 {
121  s->readcursor = s->buf_start;
122 }
123 
129 void
131 {
132  s->readcursor = s->writecursor = s->buf_start;
133 }
134 
139 static inline void
140 bytebuffer_makeroom(bytebuffer_t *s, size_t size_to_add)
141 {
142  LWDEBUGF(2,"Entered bytebuffer_makeroom with space need of %d", size_to_add);
143  size_t current_write_size = (s->writecursor - s->buf_start);
144  size_t current_read_size = (s->readcursor - s->buf_start);
145  size_t capacity = s->capacity;
146  size_t required_size = current_write_size + size_to_add;
147 
148  LWDEBUGF(2,"capacity = %d and required size = %d",capacity ,required_size);
149  while (capacity < required_size)
150  capacity *= 2;
151 
152  if ( capacity > s->capacity )
153  {
154  LWDEBUGF(4,"We need to realloc more memory. New capacity is %d", capacity);
155  if ( s->buf_start == s->buf_static )
156  {
157  s->buf_start = lwalloc(capacity);
158  memcpy(s->buf_start, s->buf_static, s->capacity);
159  }
160  else
161  {
162  s->buf_start = lwrealloc(s->buf_start, capacity);
163  }
164  s->capacity = capacity;
165  s->writecursor = s->buf_start + current_write_size;
166  s->readcursor = s->buf_start + current_read_size;
167  }
168  return;
169 }
170 
172 uint8_t*
173 bytebuffer_get_buffer_copy(const bytebuffer_t *s, size_t *buffer_length)
174 {
175  size_t bufsz = bytebuffer_getlength(s);
176  uint8_t *buf = lwalloc(bufsz);
177  memcpy(buf, s->buf_start, bufsz);
178  if ( buffer_length )
179  *buffer_length = bufsz;
180  return buf;
181 }
182 
184 const uint8_t*
185 bytebuffer_get_buffer(const bytebuffer_t *s, size_t *buffer_length)
186 {
187  if ( buffer_length )
188  *buffer_length = bytebuffer_getlength(s);
189  return s->buf_start;
190 }
191 
192 
196 void
198 {
199  LWDEBUGF(2,"Entered bytebuffer_append_byte with value %d", val);
200  bytebuffer_makeroom(s, 1);
201  *(s->writecursor)=val;
202  s->writecursor += 1;
203  return;
204 }
205 
206 
210 void
211 bytebuffer_append_bulk(bytebuffer_t *s, void * start, size_t size)
212 {
213  LWDEBUGF(2,"bytebuffer_append_bulk with size %d",size);
214  bytebuffer_makeroom(s, size);
215  memcpy(s->writecursor, start, size);
216  s->writecursor += size;
217  return;
218 }
219 
223 void
225 {
226  LWDEBUG(2,"bytebuffer_append_bytebuffer");
227  size_t size = bytebuffer_getlength(write_from);
228  bytebuffer_makeroom(write_to, size);
229  memcpy(write_to->writecursor, write_from->buf_start, size);
230  write_to->writecursor += size;
231  return;
232 }
233 
234 
238 void
240 {
241  size_t size;
242  bytebuffer_makeroom(b, 16);
243  size = varint_s64_encode_buf(val, b->writecursor);
244  b->writecursor += size;
245  return;
246 }
247 
251 void
253 {
254  size_t size;
255  bytebuffer_makeroom(b, 16);
256  size = varint_u64_encode_buf(val, b->writecursor);
257  b->writecursor += size;
258  return;
259 }
260 
261 
262 /*
263 * Writes Integer to the buffer
264 */
265 void
266 bytebuffer_append_int(bytebuffer_t *buf, const int val, int swap)
267 {
268  LWDEBUGF(2,"Entered bytebuffer_append_int with value %d, swap = %d", val, swap);
269 
270  LWDEBUGF(4,"buf_start = %p and write_cursor=%p", buf->buf_start,buf->writecursor);
271  char *iptr = (char*)(&val);
272  int i = 0;
273 
274  if ( sizeof(int) != WKB_INT_SIZE )
275  {
276  lwerror("Machine int size is not %d bytes!", WKB_INT_SIZE);
277  }
278 
280  /* Machine/request arch mismatch, so flip byte order */
281  if ( swap)
282  {
283  LWDEBUG(4,"Ok, let's do the swaping thing");
284  for ( i = 0; i < WKB_INT_SIZE; i++ )
285  {
286  *(buf->writecursor) = iptr[WKB_INT_SIZE - 1 - i];
287  buf->writecursor += 1;
288  }
289  }
290  /* If machine arch and requested arch match, don't flip byte order */
291  else
292  {
293  LWDEBUG(4,"Ok, let's do the memcopying thing");
294  memcpy(buf->writecursor, iptr, WKB_INT_SIZE);
295  buf->writecursor += WKB_INT_SIZE;
296  }
297 
298  LWDEBUGF(4,"buf_start = %p and write_cursor=%p", buf->buf_start,buf->writecursor);
299  return;
300 
301 }
302 
303 
304 
305 
306 
310 void
311 bytebuffer_append_double(bytebuffer_t *buf, const double val, int swap)
312 {
313  LWDEBUGF(2,"Entered bytebuffer_append_double with value %lf swap = %d", val, swap);
314 
315  LWDEBUGF(4,"buf_start = %p and write_cursor=%p", buf->buf_start,buf->writecursor);
316  char *dptr = (char*)(&val);
317  int i = 0;
318 
319  if ( sizeof(double) != WKB_DOUBLE_SIZE )
320  {
321  lwerror("Machine double size is not %d bytes!", WKB_DOUBLE_SIZE);
322  }
323 
325 
326  /* Machine/request arch mismatch, so flip byte order */
327  if ( swap )
328  {
329  LWDEBUG(4,"Ok, let's do the swapping thing");
330  for ( i = 0; i < WKB_DOUBLE_SIZE; i++ )
331  {
332  *(buf->writecursor) = dptr[WKB_DOUBLE_SIZE - 1 - i];
333  buf->writecursor += 1;
334  }
335  }
336  /* If machine arch and requested arch match, don't flip byte order */
337  else
338  {
339  LWDEBUG(4,"Ok, let's do the memcopying thing");
340  memcpy(buf->writecursor, dptr, WKB_DOUBLE_SIZE);
342  }
343 
344  LWDEBUG(4,"Return from bytebuffer_append_double");
345  return;
346 
347 }
348 
352 int64_t
354 {
355  size_t size;
356  int64_t val = varint_s64_decode(b->readcursor, b->buf_start + b->capacity, &size);
357  b->readcursor += size;
358  return val;
359 }
360 
364 uint64_t
366 {
367  size_t size;
368  uint64_t val = varint_u64_decode(b->readcursor, b->buf_start + b->capacity, &size);
369  b->readcursor += size;
370  return val;
371 }
372 
376 size_t
378 {
379  return (size_t) (s->writecursor - s->buf_start);
380 }
381 
382 
388 bytebuffer_merge(bytebuffer_t **buff_array, int nbuffers)
389 {
390  size_t total_size = 0, current_size, acc_size = 0;
391  int i;
392  for ( i = 0; i < nbuffers; i++ )
393  {
394  total_size += bytebuffer_getlength(buff_array[i]);
395  }
396 
398  for ( i = 0; i < nbuffers; i++)
399  {
400  current_size = bytebuffer_getlength(buff_array[i]);
401  memcpy(res->buf_start+acc_size, buff_array[i]->buf_start, current_size);
402  acc_size += current_size;
403  }
404  res->writecursor = res->buf_start + total_size;
405  res->readcursor = res->buf_start;
406  return res;
407 }
408 
409 
uint8_t buf_static[BYTEBUFFER_STATICSIZE]
Definition: bytebuffer.h:44
int64_t bytebuffer_read_varint(bytebuffer_t *b)
Reads a signed varInt from the buffer.
Definition: bytebuffer.c:353
#define WKB_INT_SIZE
uint8_t * writecursor
Definition: bytebuffer.h:42
tuple res
Definition: window.py:78
void bytebuffer_append_bytebuffer(bytebuffer_t *write_to, bytebuffer_t *write_from)
Writes a uint8_t value to the buffer.
Definition: bytebuffer.c:224
bytebuffer_t * bytebuffer_create(void)
Allocate a new bytebuffer_t.
Definition: bytebuffer.c:34
void lwfree(void *mem)
Definition: lwutil.c:244
#define BYTEBUFFER_STATICSIZE
Definition: bytebuffer.h:36
uint8_t * readcursor
Definition: bytebuffer.h:43
void bytebuffer_append_byte(bytebuffer_t *s, const uint8_t val)
Writes a uint8_t value to the buffer.
Definition: bytebuffer.c:197
#define WKB_DOUBLE_SIZE
Well-Known Binary (WKB) Output Variant Types.
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
bytebuffer_t * bytebuffer_create_with_size(size_t size)
Allocate a new bytebuffer_t.
Definition: bytebuffer.c:44
size_t bytebuffer_getlength(const bytebuffer_t *s)
Returns the length of the current buffer.
Definition: bytebuffer.c:377
int64_t varint_s64_decode(const uint8_t *the_start, const uint8_t *the_end, size_t *size)
Definition: varint.c:102
void bytebuffer_append_double(bytebuffer_t *buf, const double val, int swap)
Writes a float64 to the buffer.
Definition: bytebuffer.c:311
bytebuffer_t * bytebuffer_merge(bytebuffer_t **buff_array, int nbuffers)
Returns a new bytebuffer were both ingoing bytebuffers is merged.
Definition: bytebuffer.c:388
void bytebuffer_reset_reading(bytebuffer_t *s)
Set the read cursor to the beginning.
Definition: bytebuffer.c:119
size_t capacity
Definition: bytebuffer.h:40
void bytebuffer_clear(bytebuffer_t *s)
Reset the bytebuffer_t.
Definition: bytebuffer.c:130
void bytebuffer_append_uvarint(bytebuffer_t *b, const uint64_t val)
Writes a unsigned varInt to the buffer.
Definition: bytebuffer.c:252
#define BYTEBUFFER_STARTSIZE
Definition: bytebuffer.h:35
char * s
Definition: cu_in_wkt.c:23
void bytebuffer_destroy(bytebuffer_t *s)
Free the bytebuffer_t and all memory managed within it.
Definition: bytebuffer.c:91
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:71
uint64_t varint_u64_decode(const uint8_t *the_start, const uint8_t *the_end, size_t *size)
Definition: varint.c:109
void bytebuffer_append_bulk(bytebuffer_t *s, void *start, size_t size)
Writes a uint8_t value to the buffer.
Definition: bytebuffer.c:211
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:185
uint8_t * bytebuffer_get_buffer_copy(const bytebuffer_t *s, size_t *buffer_length)
Returns a copy of the internal buffer.
Definition: bytebuffer.c:173
size_t varint_u64_encode_buf(uint64_t val, uint8_t *buf)
Definition: varint.c:76
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:237
void bytebuffer_append_int(bytebuffer_t *buf, const int val, int swap)
Definition: bytebuffer.c:266
size_t varint_s64_encode_buf(int64_t val, uint8_t *buf)
Definition: varint.c:89
uint8_t * buf_start
Definition: bytebuffer.h:41
uint64_t bytebuffer_read_uvarint(bytebuffer_t *b)
Reads a unsigned varInt from the buffer.
Definition: bytebuffer.c:365
void * lwalloc(size_t size)
Definition: lwutil.c:229
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
unsigned char uint8_t
Definition: uthash.h:79
static void bytebuffer_makeroom(bytebuffer_t *s, size_t size_to_add)
If necessary, expand the bytebuffer_t internal buffer to accomodate the specified additional size...
Definition: bytebuffer.c:140
void bytebuffer_append_varint(bytebuffer_t *b, const int64_t val)
Writes a signed varInt to the buffer.
Definition: bytebuffer.c:239
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
void bytebuffer_destroy_buffer(bytebuffer_t *s)
Free the bytebuffer_t and all memory managed within it.
Definition: bytebuffer.c:104