PostGIS  3.4.0dev-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 
30 
35 void
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 
55 void
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 
71 static inline void
72 bytebuffer_makeroom(bytebuffer_t *s, size_t size_to_add)
73 {
74  LWDEBUGF(2,"Entered bytebuffer_makeroom with space need of %d", 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 = %d and required size = %d",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 %d", 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 
104 lwvarlena_t *
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 
115 const uint8_t*
116 bytebuffer_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 
126 void
128 {
129  LWDEBUGF(2,"Entered bytebuffer_append_byte with value %d", val);
131  *(s->writecursor)=val;
132  s->writecursor += 1;
133  return;
134 }
135 
139 void
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 
153 void
155 {
156  bytebuffer_makeroom(b, 16);
158  return;
159 }
160 
164 void
166 {
167  bytebuffer_makeroom(b, 16);
169  return;
170 }
171 
175 size_t
177 {
178  return (size_t)(s->writecursor - s->buf_start);
179 }
180 
181 /* Unused functions */
182 #if 0
183 
185 uint8_t*
186 bytebuffer_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 
200 bytebuffer_create(void)
201 {
202  LWDEBUG(2,"Entered bytebuffer_create");
203  return bytebuffer_create_with_size(BYTEBUFFER_STARTSIZE);
204 }
205 
210 bytebuffer_create_with_size(size_t size)
211 {
212  LWDEBUGF(2,"Entered bytebuffer_create_with_size %d", size);
213  bytebuffer_t *s;
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 
235 void
236 bytebuffer_destroy(bytebuffer_t *s)
237 {
239  if ( s )
240  lwfree(s);
241 
242  return;
243 }
244 
248 void
249 bytebuffer_reset_reading(bytebuffer_t *s)
250 {
251  s->readcursor = s->buf_start;
252 }
253 
259 void
260 bytebuffer_clear(bytebuffer_t *s)
261 {
262  s->readcursor = s->writecursor = s->buf_start;
263 }
264 
268 void
269 bytebuffer_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 */
281 void
282 bytebuffer_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 swaping 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);
311  buf->writecursor += 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 
326 void
327 bytebuffer_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 
368 int64_t
369 bytebuffer_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 
380 uint64_t
381 bytebuffer_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 
395 bytebuffer_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
void bytebuffer_destroy_buffer(bytebuffer_t *s)
Free the bytebuffer_t and all memory managed within it.
Definition: bytebuffer.c:56
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
lwvarlena_t * bytebuffer_get_buffer_varlena(const bytebuffer_t *s)
Returns a copy of the internal buffer.
Definition: bytebuffer.c:105
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 accomodate the specified additional size.
Definition: bytebuffer.c:72
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
#define BYTEBUFFER_STATICSIZE
Definition: bytebuffer.h:38
#define BYTEBUFFER_STARTSIZE
Definition: bytebuffer.h:37
char * s
Definition: cu_in_wkt.c:23
#define LWVARHDRSZ
Definition: liblwgeom.h:311
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:235
void lwfree(void *mem)
Definition: lwutil.c:242
#define LWSIZE_SET(varsize, len)
Definition: liblwgeom.h:325
void * lwalloc(size_t size)
Definition: lwutil.c:227
#define WKB_INT_SIZE
#define WKB_DOUBLE_SIZE
Well-Known Binary (WKB) Output Variant Types.
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:83
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:190
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