PostGIS  2.2.8dev-r@@SVN_REVISION@@
bytebuffer.c
Go to the documentation of this file.
1 /**********************************************************************
2  * $Id: bytebuffer.c 11218 2013-03-28 13:32:44Z robe $
3  *
4  * PostGIS - Spatial Types for PostgreSQL
5  * Copyright 2015 Nicklas Avén <nicklas.aven@jordogskog.no>
6  *
7  * Redistribution and use in source and binary forms, with or
8  * without modification, are permitted provided that the following
9  * conditions are met:
10  *
11  * Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  *
14  * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  *
19  * The name of the author may not be used to endorse or promote
20  * products derived from this software without specific prior
21  * written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
24  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
26  * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR
27  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
31  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
33  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
34  * THE POSSIBILITY OF SUCH DAMAGE.
35  *
36  **********************************************************************/
37 
38 
39 #include "liblwgeom_internal.h"
40 #include "bytebuffer.h"
41 
47 {
48  LWDEBUG(2,"Entered bytebuffer_create");
50 }
51 
57 {
58  LWDEBUGF(2,"Entered bytebuffer_create_with_size %d", size);
59  bytebuffer_t *s;
60 
61  s = lwalloc(sizeof(bytebuffer_t));
62  s->buf_start = lwalloc(size);
63  s->readcursor = s->writecursor = s->buf_start;
64  s->capacity = size;
65  memset(s->buf_start,0,size);
66  LWDEBUGF(4,"We create a buffer on %p of %d bytes", s->buf_start, size);
67  return s;
68 }
69 
74 void
76 {
77  b->buf_start = lwalloc(size);
78  b->readcursor = b->writecursor = b->buf_start;
79  b->capacity = size;
80  memset(b->buf_start, 0, size);
81 }
82 
86 void
88 {
89  LWDEBUG(2,"Entered bytebuffer_destroy");
90  LWDEBUGF(4,"The buffer has used %d bytes",bytebuffer_getlength(s));
91 
92  if ( s->buf_start )
93  {
94  LWDEBUGF(4,"let's free buf_start %p",s->buf_start);
95  lwfree(s->buf_start);
96  LWDEBUG(4,"buf_start is freed");
97  }
98  if ( s )
99  {
100  lwfree(s);
101  LWDEBUG(4,"bytebuffer_t is freed");
102  }
103  return;
104 }
105 
109 void
111 {
112  s->readcursor = s->buf_start;
113 }
114 
120 void
122 {
123  s->readcursor = s->writecursor = s->buf_start;
124 }
125 
130 static inline void
131 bytebuffer_makeroom(bytebuffer_t *s, size_t size_to_add)
132 {
133  LWDEBUGF(2,"Entered bytebuffer_makeroom with space need of %d", size_to_add);
134  size_t current_write_size = (s->writecursor - s->buf_start);
135  size_t capacity = s->capacity;
136  size_t required_size = current_write_size + size_to_add;
137 
138  LWDEBUGF(2,"capacity = %d and required size = %d",capacity ,required_size);
139  while (capacity < required_size)
140  capacity *= 2;
141 
142  if ( capacity > s->capacity )
143  {
144  LWDEBUGF(4,"We need to realloc more memory. New capacity is %d", capacity);
145  s->buf_start = lwrealloc(s->buf_start, capacity);
146  s->capacity = capacity;
147  s->writecursor = s->buf_start + current_write_size;
148  s->readcursor = s->buf_start + (s->readcursor - s->buf_start);
149  }
150  return;
151 }
152 
156 void
158 {
159  LWDEBUGF(2,"Entered bytebuffer_append_byte with value %d", val);
160  bytebuffer_makeroom(s, 1);
161  *(s->writecursor)=val;
162  s->writecursor += 1;
163  return;
164 }
165 
166 
170 void
171 bytebuffer_append_bulk(bytebuffer_t *s, void * start, size_t size)
172 {
173  LWDEBUGF(2,"bytebuffer_append_bulk with size %d",size);
174  bytebuffer_makeroom(s, size);
175  memcpy(s->writecursor, start, size);
176  s->writecursor += size;
177  return;
178 }
179 
183 void
185 {
186  LWDEBUG(2,"bytebuffer_append_bytebuffer");
187  size_t size = bytebuffer_getlength(write_from);
188  bytebuffer_makeroom(write_to, size);
189  memcpy(write_to->writecursor, write_from->buf_start, size);
190  write_to->writecursor += size;
191  return;
192 }
193 
194 
198 void
200 {
201  size_t size;
202  bytebuffer_makeroom(b, 16);
203  size = varint_s64_encode_buf(val, b->writecursor);
204  b->writecursor += size;
205  return;
206 }
207 
211 void
213 {
214  size_t size;
215  bytebuffer_makeroom(b, 16);
216  size = varint_u64_encode_buf(val, b->writecursor);
217  b->writecursor += size;
218  return;
219 }
220 
221 
222 /*
223 * Writes Integer to the buffer
224 */
225 void
226 bytebuffer_append_int(bytebuffer_t *buf, const int val, int swap)
227 {
228  LWDEBUGF(2,"Entered bytebuffer_append_int with value %d, swap = %d", val, swap);
229 
230  LWDEBUGF(4,"buf_start = %p and write_cursor=%p", buf->buf_start,buf->writecursor);
231  char *iptr = (char*)(&val);
232  int i = 0;
233 
234  if ( sizeof(int) != WKB_INT_SIZE )
235  {
236  lwerror("Machine int size is not %d bytes!", WKB_INT_SIZE);
237  }
238 
240  /* Machine/request arch mismatch, so flip byte order */
241  if ( swap)
242  {
243  LWDEBUG(4,"Ok, let's do the swaping thing");
244  for ( i = 0; i < WKB_INT_SIZE; i++ )
245  {
246  *(buf->writecursor) = iptr[WKB_INT_SIZE - 1 - i];
247  buf->writecursor += 1;
248  }
249  }
250  /* If machine arch and requested arch match, don't flip byte order */
251  else
252  {
253  LWDEBUG(4,"Ok, let's do the memcopying thing");
254  memcpy(buf->writecursor, iptr, WKB_INT_SIZE);
255  buf->writecursor += WKB_INT_SIZE;
256  }
257 
258  LWDEBUGF(4,"buf_start = %p and write_cursor=%p", buf->buf_start,buf->writecursor);
259  return;
260 
261 }
262 
263 
264 
265 
266 
270 void
271 bytebuffer_append_double(bytebuffer_t *buf, const double val, int swap)
272 {
273  LWDEBUGF(2,"Entered bytebuffer_append_double with value %lf swap = %d", val, swap);
274 
275  LWDEBUGF(4,"buf_start = %p and write_cursor=%p", buf->buf_start,buf->writecursor);
276  char *dptr = (char*)(&val);
277  int i = 0;
278 
279  if ( sizeof(double) != WKB_DOUBLE_SIZE )
280  {
281  lwerror("Machine double size is not %d bytes!", WKB_DOUBLE_SIZE);
282  }
283 
285 
286  /* Machine/request arch mismatch, so flip byte order */
287  if ( swap )
288  {
289  LWDEBUG(4,"Ok, let's do the swapping thing");
290  for ( i = 0; i < WKB_DOUBLE_SIZE; i++ )
291  {
292  *(buf->writecursor) = dptr[WKB_DOUBLE_SIZE - 1 - i];
293  buf->writecursor += 1;
294  }
295  }
296  /* If machine arch and requested arch match, don't flip byte order */
297  else
298  {
299  LWDEBUG(4,"Ok, let's do the memcopying thing");
300  memcpy(buf->writecursor, dptr, WKB_DOUBLE_SIZE);
302  }
303 
304  LWDEBUG(4,"Return from bytebuffer_append_double");
305  return;
306 
307 }
308 
312 int64_t
314 {
315  size_t size;
316  int64_t val = varint_s64_decode(b->readcursor, b->buf_start + b->capacity, &size);
317  b->readcursor += size;
318  return val;
319 }
320 
324 uint64_t
326 {
327  size_t size;
328  uint64_t val = varint_u64_decode(b->readcursor, b->buf_start + b->capacity, &size);
329  b->readcursor += size;
330  return val;
331 }
332 
336 size_t
338 {
339  return (size_t) (s->writecursor - s->buf_start);
340 }
341 
342 
348 bytebuffer_merge(bytebuffer_t **buff_array, int nbuffers)
349 {
350  size_t total_size = 0, current_size, acc_size = 0;
351  int i;
352  for ( i = 0; i < nbuffers; i++ )
353  {
354  total_size += bytebuffer_getlength(buff_array[i]);
355  }
356 
358  for ( i = 0; i < nbuffers; i++)
359  {
360  current_size = bytebuffer_getlength(buff_array[i]);
361  memcpy(res->buf_start+acc_size, buff_array[i]->buf_start, current_size);
362  acc_size += current_size;
363  }
364  res->writecursor = res->buf_start + total_size;
365  res->readcursor = res->buf_start;
366  return res;
367 }
368 
369 
int64_t bytebuffer_read_varint(bytebuffer_t *b)
Reads a signed varInt from the buffer.
Definition: bytebuffer.c:313
#define WKB_INT_SIZE
uint8_t * writecursor
Definition: bytebuffer.h:53
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:184
bytebuffer_t * bytebuffer_create(void)
Allocate a new bytebuffer_t.
Definition: bytebuffer.c:46
void lwfree(void *mem)
Definition: lwutil.c:214
uint8_t * readcursor
Definition: bytebuffer.h:54
void bytebuffer_init_with_size(bytebuffer_t *b, size_t size)
Allocate just the internal buffer of an existing bytebuffer_t struct.
Definition: bytebuffer.c:75
void bytebuffer_append_byte(bytebuffer_t *s, const uint8_t val)
Writes a uint8_t value to the buffer.
Definition: bytebuffer.c:157
#define WKB_DOUBLE_SIZE
Well-Known Binary (WKB) Output Variant Types.
#define LWDEBUG(level, msg)
Definition: lwgeom_log.h:50
bytebuffer_t * bytebuffer_create_with_size(size_t size)
Allocate a new bytebuffer_t.
Definition: bytebuffer.c:56
int64_t varint_s64_decode(const uint8_t *the_start, const uint8_t *the_end, size_t *size)
Definition: varint.c:94
void bytebuffer_append_double(bytebuffer_t *buf, const double val, int swap)
Writes a float64 to the buffer.
Definition: bytebuffer.c:271
bytebuffer_t * bytebuffer_merge(bytebuffer_t **buff_array, int nbuffers)
Returns a new bytebuffer were both ingoing bytebuffers is merged.
Definition: bytebuffer.c:348
void bytebuffer_reset_reading(bytebuffer_t *s)
Set the read cursor to the beginning.
Definition: bytebuffer.c:110
size_t capacity
Definition: bytebuffer.h:51
void bytebuffer_clear(bytebuffer_t *s)
Reset the bytebuffer_t.
Definition: bytebuffer.c:121
void bytebuffer_append_uvarint(bytebuffer_t *b, const uint64_t val)
Writes a unsigned varInt to the buffer.
Definition: bytebuffer.c:212
#define BYTEBUFFER_STARTSIZE
Definition: bytebuffer.h:47
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:87
uint64_t varint_u64_decode(const uint8_t *the_start, const uint8_t *the_end, size_t *size)
Definition: varint.c:101
void bytebuffer_append_bulk(bytebuffer_t *s, void *start, size_t size)
Writes a uint8_t value to the buffer.
Definition: bytebuffer.c:171
size_t varint_u64_encode_buf(uint64_t val, uint8_t *buf)
Definition: varint.c:68
void * lwrealloc(void *mem, size_t size)
Definition: lwutil.c:207
void bytebuffer_append_int(bytebuffer_t *buf, const int val, int swap)
Definition: bytebuffer.c:226
size_t varint_s64_encode_buf(int64_t val, uint8_t *buf)
Definition: varint.c:81
uint8_t * buf_start
Definition: bytebuffer.h:52
uint64_t bytebuffer_read_uvarint(bytebuffer_t *b)
Reads a unsigned varInt from the buffer.
Definition: bytebuffer.c:325
void * lwalloc(size_t size)
Definition: lwutil.c:199
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:55
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:131
void bytebuffer_append_varint(bytebuffer_t *b, const int64_t val)
Writes a signed varInt to the buffer.
Definition: bytebuffer.c:199
size_t bytebuffer_getlength(bytebuffer_t *s)
Returns the length of the current buffer.
Definition: bytebuffer.c:337
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:74