PostGIS  2.3.8dev-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  s->buf_start = lwalloc(size);
51  s->readcursor = s->writecursor = s->buf_start;
52  s->capacity = size;
53  memset(s->buf_start,0,size);
54  LWDEBUGF(4,"We create a buffer on %p of %d bytes", s->buf_start, size);
55  return s;
56 }
57 
62 void
64 {
65  b->buf_start = lwalloc(size);
66  b->readcursor = b->writecursor = b->buf_start;
67  b->capacity = size;
68  memset(b->buf_start, 0, size);
69 }
70 
74 void
76 {
77  LWDEBUG(2,"Entered bytebuffer_destroy");
78  LWDEBUGF(4,"The buffer has used %d bytes",bytebuffer_getlength(s));
79 
80  if ( s->buf_start )
81  {
82  LWDEBUGF(4,"let's free buf_start %p",s->buf_start);
83  lwfree(s->buf_start);
84  LWDEBUG(4,"buf_start is freed");
85  }
86  if ( s )
87  {
88  lwfree(s);
89  LWDEBUG(4,"bytebuffer_t is freed");
90  }
91  return;
92 }
93 
97 void
99 {
100  s->readcursor = s->buf_start;
101 }
102 
108 void
110 {
111  s->readcursor = s->writecursor = s->buf_start;
112 }
113 
118 static inline void
119 bytebuffer_makeroom(bytebuffer_t *s, size_t size_to_add)
120 {
121  LWDEBUGF(2,"Entered bytebuffer_makeroom with space need of %d", size_to_add);
122  size_t current_write_size = (s->writecursor - s->buf_start);
123  size_t capacity = s->capacity;
124  size_t required_size = current_write_size + size_to_add;
125 
126  LWDEBUGF(2,"capacity = %d and required size = %d",capacity ,required_size);
127  while (capacity < required_size)
128  capacity *= 2;
129 
130  if ( capacity > s->capacity )
131  {
132  LWDEBUGF(4,"We need to realloc more memory. New capacity is %d", capacity);
133  s->buf_start = lwrealloc(s->buf_start, capacity);
134  s->capacity = capacity;
135  s->writecursor = s->buf_start + current_write_size;
136  s->readcursor = s->buf_start + (s->readcursor - s->buf_start);
137  }
138  return;
139 }
140 
144 void
146 {
147  LWDEBUGF(2,"Entered bytebuffer_append_byte with value %d", val);
148  bytebuffer_makeroom(s, 1);
149  *(s->writecursor)=val;
150  s->writecursor += 1;
151  return;
152 }
153 
154 
158 void
159 bytebuffer_append_bulk(bytebuffer_t *s, void * start, size_t size)
160 {
161  LWDEBUGF(2,"bytebuffer_append_bulk with size %d",size);
162  bytebuffer_makeroom(s, size);
163  memcpy(s->writecursor, start, size);
164  s->writecursor += size;
165  return;
166 }
167 
171 void
173 {
174  LWDEBUG(2,"bytebuffer_append_bytebuffer");
175  size_t size = bytebuffer_getlength(write_from);
176  bytebuffer_makeroom(write_to, size);
177  memcpy(write_to->writecursor, write_from->buf_start, size);
178  write_to->writecursor += size;
179  return;
180 }
181 
182 
186 void
188 {
189  size_t size;
190  bytebuffer_makeroom(b, 16);
191  size = varint_s64_encode_buf(val, b->writecursor);
192  b->writecursor += size;
193  return;
194 }
195 
199 void
201 {
202  size_t size;
203  bytebuffer_makeroom(b, 16);
204  size = varint_u64_encode_buf(val, b->writecursor);
205  b->writecursor += size;
206  return;
207 }
208 
209 
210 /*
211 * Writes Integer to the buffer
212 */
213 void
214 bytebuffer_append_int(bytebuffer_t *buf, const int val, int swap)
215 {
216  LWDEBUGF(2,"Entered bytebuffer_append_int with value %d, swap = %d", val, swap);
217 
218  LWDEBUGF(4,"buf_start = %p and write_cursor=%p", buf->buf_start,buf->writecursor);
219  char *iptr = (char*)(&val);
220  int i = 0;
221 
222  if ( sizeof(int) != WKB_INT_SIZE )
223  {
224  lwerror("Machine int size is not %d bytes!", WKB_INT_SIZE);
225  }
226 
228  /* Machine/request arch mismatch, so flip byte order */
229  if ( swap)
230  {
231  LWDEBUG(4,"Ok, let's do the swaping thing");
232  for ( i = 0; i < WKB_INT_SIZE; i++ )
233  {
234  *(buf->writecursor) = iptr[WKB_INT_SIZE - 1 - i];
235  buf->writecursor += 1;
236  }
237  }
238  /* If machine arch and requested arch match, don't flip byte order */
239  else
240  {
241  LWDEBUG(4,"Ok, let's do the memcopying thing");
242  memcpy(buf->writecursor, iptr, WKB_INT_SIZE);
243  buf->writecursor += WKB_INT_SIZE;
244  }
245 
246  LWDEBUGF(4,"buf_start = %p and write_cursor=%p", buf->buf_start,buf->writecursor);
247  return;
248 
249 }
250 
251 
252 
253 
254 
258 void
259 bytebuffer_append_double(bytebuffer_t *buf, const double val, int swap)
260 {
261  LWDEBUGF(2,"Entered bytebuffer_append_double with value %lf swap = %d", val, swap);
262 
263  LWDEBUGF(4,"buf_start = %p and write_cursor=%p", buf->buf_start,buf->writecursor);
264  char *dptr = (char*)(&val);
265  int i = 0;
266 
267  if ( sizeof(double) != WKB_DOUBLE_SIZE )
268  {
269  lwerror("Machine double size is not %d bytes!", WKB_DOUBLE_SIZE);
270  }
271 
273 
274  /* Machine/request arch mismatch, so flip byte order */
275  if ( swap )
276  {
277  LWDEBUG(4,"Ok, let's do the swapping thing");
278  for ( i = 0; i < WKB_DOUBLE_SIZE; i++ )
279  {
280  *(buf->writecursor) = dptr[WKB_DOUBLE_SIZE - 1 - i];
281  buf->writecursor += 1;
282  }
283  }
284  /* If machine arch and requested arch match, don't flip byte order */
285  else
286  {
287  LWDEBUG(4,"Ok, let's do the memcopying thing");
288  memcpy(buf->writecursor, dptr, WKB_DOUBLE_SIZE);
290  }
291 
292  LWDEBUG(4,"Return from bytebuffer_append_double");
293  return;
294 
295 }
296 
300 int64_t
302 {
303  size_t size;
304  int64_t val = varint_s64_decode(b->readcursor, b->buf_start + b->capacity, &size);
305  b->readcursor += size;
306  return val;
307 }
308 
312 uint64_t
314 {
315  size_t size;
316  uint64_t val = varint_u64_decode(b->readcursor, b->buf_start + b->capacity, &size);
317  b->readcursor += size;
318  return val;
319 }
320 
324 size_t
326 {
327  return (size_t) (s->writecursor - s->buf_start);
328 }
329 
330 
336 bytebuffer_merge(bytebuffer_t **buff_array, int nbuffers)
337 {
338  size_t total_size = 0, current_size, acc_size = 0;
339  int i;
340  for ( i = 0; i < nbuffers; i++ )
341  {
342  total_size += bytebuffer_getlength(buff_array[i]);
343  }
344 
346  for ( i = 0; i < nbuffers; i++)
347  {
348  current_size = bytebuffer_getlength(buff_array[i]);
349  memcpy(res->buf_start+acc_size, buff_array[i]->buf_start, current_size);
350  acc_size += current_size;
351  }
352  res->writecursor = res->buf_start + total_size;
353  res->readcursor = res->buf_start;
354  return res;
355 }
356 
357 
int64_t bytebuffer_read_varint(bytebuffer_t *b)
Reads a signed varInt from the buffer.
Definition: bytebuffer.c:301
#define WKB_INT_SIZE
uint8_t * writecursor
Definition: bytebuffer.h:41
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:172
bytebuffer_t * bytebuffer_create(void)
Allocate a new bytebuffer_t.
Definition: bytebuffer.c:34
void lwfree(void *mem)
Definition: lwutil.c:242
uint8_t * readcursor
Definition: bytebuffer.h:42
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:63
void bytebuffer_append_byte(bytebuffer_t *s, const uint8_t val)
Writes a uint8_t value to the buffer.
Definition: bytebuffer.c:145
#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
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:259
bytebuffer_t * bytebuffer_merge(bytebuffer_t **buff_array, int nbuffers)
Returns a new bytebuffer were both ingoing bytebuffers is merged.
Definition: bytebuffer.c:336
void bytebuffer_reset_reading(bytebuffer_t *s)
Set the read cursor to the beginning.
Definition: bytebuffer.c:98
size_t capacity
Definition: bytebuffer.h:39
void bytebuffer_clear(bytebuffer_t *s)
Reset the bytebuffer_t.
Definition: bytebuffer.c:109
void bytebuffer_append_uvarint(bytebuffer_t *b, const uint64_t val)
Writes a unsigned varInt to the buffer.
Definition: bytebuffer.c:200
#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:75
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:159
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:235
void bytebuffer_append_int(bytebuffer_t *buf, const int val, int swap)
Definition: bytebuffer.c:214
size_t varint_s64_encode_buf(int64_t val, uint8_t *buf)
Definition: varint.c:89
uint8_t * buf_start
Definition: bytebuffer.h:40
uint64_t bytebuffer_read_uvarint(bytebuffer_t *b)
Reads a unsigned varInt from the buffer.
Definition: bytebuffer.c:313
void * lwalloc(size_t size)
Definition: lwutil.c:227
#define LWDEBUGF(level, msg,...)
Definition: lwgeom_log.h:88
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:119
void bytebuffer_append_varint(bytebuffer_t *b, const int64_t val)
Writes a signed varInt to the buffer.
Definition: bytebuffer.c:187
size_t bytebuffer_getlength(bytebuffer_t *s)
Returns the length of the current buffer.
Definition: bytebuffer.c:325
void lwerror(const char *fmt,...)
Write a notice out to the error handler.
Definition: lwutil.c:102