preparing for release of 2.2.3a
[Samba.git] / source / aparser / parser.c
blobc2348b84f964c86461115c96fbe54bc05c30b696
1 #include "parser.h"
3 /*******************************************************************
4 Attempt, if needed, to grow a data buffer.
5 Also depends on the data stream mode (io).
6 ********************************************************************/
8 BOOL io_grow(io_struct *ps, uint32 extra_space)
10 uint32 new_size;
11 char *new_data;
13 ps->grow_size = MAX(ps->grow_size, ps->data_offset + extra_space);
15 if(ps->data_offset + extra_space <= ps->buffer_size)
16 return True;
19 * We cannot grow the buffer if we're not reading
20 * into the io_struct, or if we don't own the memory.
23 if(UNMARSHALLING(ps) || !ps->is_dynamic) {
24 DEBUG(0,("io_grow: Buffer overflow - unable to expand buffer by %u bytes.\n",
25 (unsigned int)extra_space));
26 return False;
30 * Decide how much extra space we really need.
33 extra_space -= (ps->buffer_size - ps->data_offset);
34 if(ps->buffer_size == 0) {
35 new_size = extra_space;
37 if((new_data = malloc(new_size)) == NULL) {
38 DEBUG(0,("io_grow: Malloc failure for size %u.\n", (unsigned int)new_size));
39 return False;
41 memset(new_data, '\0', new_size );
42 } else {
44 * If the current buffer size is bigger than the space needed, just
45 * double it, else add extra_space.
47 new_size = MAX(ps->buffer_size*2, ps->buffer_size + extra_space);
49 if ((new_data = Realloc(ps->data_p, new_size)) == NULL) {
50 DEBUG(0,("io_grow: Realloc failure for size %u.\n",
51 (unsigned int)new_size));
52 return False;
55 ps->buffer_size = new_size;
56 ps->data_p = new_data;
58 return True;
62 /*******************************************************************
63 Ensure we can read/write to a given offset.
64 ********************************************************************/
66 char *io_mem_get(io_struct *ps, uint32 extra_size)
68 if(UNMARSHALLING(ps)) {
70 * If reading, ensure that we can read the requested size item.
72 if (ps->data_offset + extra_size > ps->buffer_size) {
73 DEBUG(0,("io_mem_get: reading data of size %u would overrun buffer.\n",
74 (unsigned int)extra_size ));
75 return NULL;
77 } else {
79 * Writing - grow the buffer if needed.
81 if(!io_grow(ps, extra_size))
82 return False;
84 return &ps->data_p[ps->data_offset];
87 /*******************************************************************
88 Initialise a parse structure - malloc the data if requested.
89 ********************************************************************/
91 BOOL io_init(io_struct *ps, uint32 size, BOOL io)
93 ZERO_STRUCTP(ps);
94 ps->io = io;
95 ps->bigendian_data = False;
96 ps->is_dynamic = False;
97 ps->data_offset = 0;
98 ps->buffer_size = 0;
99 ps->data_p = NULL;
101 if (size != 0) {
102 ps->buffer_size = size;
103 if((ps->data_p = (char *)malloc((size_t)size)) == NULL) {
104 DEBUG(0,("io_init: malloc fail for %u bytes.\n", (unsigned int)size));
105 return False;
107 ps->is_dynamic = True; /* We own this memory. */
110 return True;
113 /*******************************************************************
114 debug output for parsing info.
116 XXXX side-effect of this function is to increase the debug depth XXXX
118 ********************************************************************/
119 void io_debug(io_struct *ps, int depth, char *desc, char *fn_name)
121 DEBUG(5+depth, ("%s%06x %s %s\n", tab_depth(depth), ps->data_offset, fn_name, desc));
124 /*******************************************************************
125 Align a the data_len to a multiple of align bytes - filling with
126 zeros.
127 ********************************************************************/
129 BOOL io_align2(io_struct *ps, int offset)
131 uint32 mod = (ps->data_offset + offset) & (2-1);
133 if (mod != 0) {
134 uint32 extra_space = (2 - mod);
135 if(!io_grow(ps, extra_space))
136 return False;
137 memset(&ps->data_p[ps->data_offset], '\0', (size_t)extra_space);
138 ps->data_offset += extra_space;
141 return True;
144 BOOL io_align4(io_struct *ps, int offset)
146 uint32 mod = (ps->data_offset + offset) & (4-1);
148 if (mod != 0) {
149 uint32 extra_space = (4 - mod);
150 if(!io_grow(ps, extra_space))
151 return False;
152 memset(&ps->data_p[ps->data_offset], '\0', (size_t)extra_space);
153 ps->data_offset += extra_space;
156 return True;
159 /*******************************************************************
160 Align a the data_len to a multiple of align bytes - filling with
161 zeros.
162 ********************************************************************/
164 BOOL io_align(io_struct *ps, int align)
166 uint32 mod;
168 if (!ps->autoalign) return True;
170 mod = ps->data_offset & (align-1);
172 if (align != 0 && mod != 0) {
173 uint32 extra_space = (align - mod);
174 if(!io_grow(ps, extra_space))
175 return False;
176 memset(&ps->data_p[ps->data_offset], '\0', (size_t)extra_space);
177 ps->data_offset += extra_space;
180 return True;
184 /*******************************************************************
185 read from a socket into memory.
186 ********************************************************************/
187 BOOL io_read(io_struct *ps, int fd, size_t len, int timeout)
189 BOOL ok;
190 size_t prev_size = ps->buffer_size;
191 if (!io_grow(ps, len))
193 return False;
196 if (timeout > 0)
198 ok = (read(fd, &ps->data_p[prev_size], len) == len);
200 else
202 ok = (read(fd, &ps->data_p[prev_size], len) == len);
204 return ok;
208 /*******************************************************************
209 do IO on a uint32.
210 ********************************************************************/
211 BOOL io_uint32(char *name, io_struct *ps, int depth, uint32 *data32, unsigned flags)
213 char *q;
215 if (!(flags & PARSE_SCALARS)) return True;
217 if (!io_align(ps, 4)) return False;
219 q = io_mem_get(ps, sizeof(uint32));
220 if (q == NULL) return False;
222 DBG_RW_IVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data32)
223 ps->data_offset += sizeof(uint32);
225 return True;
228 /*******************************************************************
229 do IO on a uint16.
230 ********************************************************************/
231 BOOL io_uint16(char *name, io_struct *ps, int depth, uint16 *data16, unsigned flags)
233 char *q;
235 if (!(flags & PARSE_SCALARS)) return True;
237 if (!io_align(ps, 2)) return False;
239 q = io_mem_get(ps, sizeof(uint16));
240 if (q == NULL) return False;
242 DBG_RW_SVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data16)
243 ps->data_offset += sizeof(uint16);
245 return True;
248 /*******************************************************************
249 do IO on a uint8.
250 ********************************************************************/
251 BOOL io_uint8(char *name, io_struct *ps, int depth, uint8 *data8, unsigned flags)
253 char *q;
255 if (!(flags & PARSE_SCALARS)) return True;
257 q = io_mem_get(ps, sizeof(uint8));
258 if (q == NULL) return False;
260 DBG_RW_IVAL(name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, *data8)
261 ps->data_offset += sizeof(uint8);
263 return True;
266 /*******************************************************************
267 do IO on a pointer
268 ********************************************************************/
269 BOOL io_pointer(char *desc, io_struct *ps, int depth, void **p, unsigned flags)
271 uint32 v;
273 if (!(flags & PARSE_SCALARS)) return True;
275 v = (*p) ? 0xdeadbeef : 0;
276 if (!io_uint32(desc, ps, depth, &v, flags)) return False;
277 *p = (void *) (v ? 0xdeadbeef : 0);
278 return True;
281 /*******************************************************************
282 Stream a null-terminated string.
283 ********************************************************************/
284 BOOL io_SMBSTR(char *name, io_struct *ps, int depth, char **str, unsigned flags)
286 char *q;
287 uint8 *start;
288 int i;
289 size_t len;
290 int start_offset = ps->data_offset;
292 if (!(flags & PARSE_SCALARS)) return True;
294 if (UNMARSHALLING(ps)) {
295 *str = io_mem_get(ps, 0);
296 if (*str == NULL)
297 return False;
298 len = strlen(*str);
299 ps->data_offset += len + 1;
301 else
303 len = strlen(*str)+1;
304 start = (uint8*)q;
306 for(i = 0; i < len; i++) {
307 q = io_mem_get(ps, 1);
308 if (q == NULL)
309 return False;
311 RW_CVAL(ps->io, q, (*str)[i],0);
312 ps->data_offset++;
316 DEBUG(5,("%s%04x %s: %s\n", tab_depth(depth),
317 start_offset, name, *str));
318 return True;
321 /******************************************************************
322 do IO on a byte array
323 ********************************************************************/
324 BOOL io_uint8s(char *name, io_struct *ps, int depth, uint8 **data8s, int len, unsigned flags)
326 char *q;
327 size_t num_bytes = len * sizeof(uint8);
329 if (!(flags & PARSE_SCALARS)) return True;
331 q = io_mem_get(ps, num_bytes);
332 if (q == NULL) return False;
334 if (MARSHALLING(ps))
336 DBG_RW_PCVAL(True, name, depth, ps->data_offset, ps->io, q, *data8s, len)
338 else
340 *data8s = q;
341 dump_data(depth+5, *data8s, num_bytes);
343 ps->data_offset += num_bytes;
345 return True;
347 /******************************************************************
348 do IO on a fixed-size byte array
349 ********************************************************************/
350 BOOL io_uint8s_fixed(char *name, io_struct *ps, int depth, uint8 *data8s, int len, unsigned flags)
352 char *q;
353 size_t num_bytes = len * sizeof(uint8);
355 if (!(flags & PARSE_SCALARS)) return True;
357 q = io_mem_get(ps, num_bytes);
358 if (q == NULL) return False;
360 DBG_RW_PCVAL(True, name, depth, ps->data_offset, ps->io, q, data8s, len)
361 ps->data_offset += num_bytes;
363 return True;
367 /******************************************************************
368 do IO on an io (eh?? :)
369 ********************************************************************/
370 BOOL io_io_struct(char *name, io_struct *ps, int depth, io_struct *io, unsigned flags)
372 char *q;
373 uint16 len;
375 if (!(flags & PARSE_SCALARS)) return True;
377 q = io_mem_get(ps, sizeof(uint16));
378 if (q == NULL) return False;
380 /* length first */
381 if (MARSHALLING(ps))
383 len = io->data_offset;
385 if (!io_uint16("len", ps, depth+1, &len, flags))
387 return False;
389 if (UNMARSHALLING(ps))
391 if (!io_init(io, len, UNMARSHALL))
393 return False;
397 /* now data */
398 q = io_mem_get(ps, len * sizeof(uint8));
399 if (q == NULL) return False;
401 if (MARSHALLING(ps))
403 DBG_RW_PCVAL(False, name, depth+1, ps->data_offset, ps->io, q, io->data_p, len)
405 else
407 io->data_p = q;
408 dump_data(depth+5, q, len);
410 ps->data_offset += len;
412 return True;
415 /******************************************************************
416 do IO on a unicode array
417 ********************************************************************/
418 BOOL io_wstring(char *name, io_struct *ps, int depth, uint16 *data16s, int len, unsigned flags)
420 char *q;
422 if (!(flags & PARSE_SCALARS)) return True;
424 if (!io_align(ps, 2)) return False;
426 q = io_mem_get(ps, len * sizeof(uint16));
427 if (q == NULL) return False;
429 DBG_RW_PSVAL(True, name, depth, ps->data_offset, ps->io, ps->bigendian_data, q, data16s, len)
430 ps->data_offset += (len * sizeof(uint16));
432 return True;
436 /******************************************************************
437 allocate some memory for a parse structure
438 ********************************************************************/
439 void io_free(io_struct *ps)
441 if (ps->is_dynamic && ps->data_p)
443 free(ps->data_p);
444 ps->data_p = NULL;
448 /******************************************************************
449 allocate some memory for a parse structure
450 ********************************************************************/
451 BOOL io_alloc(char *name, io_struct *ps, void **ptr, unsigned size)
453 (*ptr) = (void *)malloc(size);
454 if (*ptr) return True;
455 return False;
458 /******************************************************************
459 realloc some memory for a parse structure
460 ********************************************************************/
461 BOOL io_realloc(char *name, io_struct *ps, void **ptr, unsigned size)
463 (*ptr) = (void *)Realloc(*ptr, size);
464 if (*ptr) return True;
465 return False;