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
)
13 ps
->grow_size
= MAX(ps
->grow_size
, ps
->data_offset
+ extra_space
);
15 if(ps
->data_offset
+ extra_space
<= ps
->buffer_size
)
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
));
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
));
41 memset(new_data
, '\0', new_size
);
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
));
55 ps
->buffer_size
= new_size
;
56 ps
->data_p
= new_data
;
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
));
79 * Writing - grow the buffer if needed.
81 if(!io_grow(ps
, extra_size
))
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
)
95 ps
->bigendian_data
= False
;
96 ps
->is_dynamic
= False
;
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
));
107 ps
->is_dynamic
= True
; /* We own this memory. */
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
127 ********************************************************************/
129 BOOL
io_align2(io_struct
*ps
, int offset
)
131 uint32 mod
= (ps
->data_offset
+ offset
) & (2-1);
134 uint32 extra_space
= (2 - mod
);
135 if(!io_grow(ps
, extra_space
))
137 memset(&ps
->data_p
[ps
->data_offset
], '\0', (size_t)extra_space
);
138 ps
->data_offset
+= extra_space
;
144 BOOL
io_align4(io_struct
*ps
, int offset
)
146 uint32 mod
= (ps
->data_offset
+ offset
) & (4-1);
149 uint32 extra_space
= (4 - mod
);
150 if(!io_grow(ps
, extra_space
))
152 memset(&ps
->data_p
[ps
->data_offset
], '\0', (size_t)extra_space
);
153 ps
->data_offset
+= extra_space
;
159 /*******************************************************************
160 Align a the data_len to a multiple of align bytes - filling with
162 ********************************************************************/
164 BOOL
io_align(io_struct
*ps
, int align
)
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
))
176 memset(&ps
->data_p
[ps
->data_offset
], '\0', (size_t)extra_space
);
177 ps
->data_offset
+= extra_space
;
184 /*******************************************************************
185 read from a socket into memory.
186 ********************************************************************/
187 BOOL
io_read(io_struct
*ps
, int fd
, size_t len
, int timeout
)
190 size_t prev_size
= ps
->buffer_size
;
191 if (!io_grow(ps
, len
))
198 ok
= (read(fd
, &ps
->data_p
[prev_size
], len
) == len
);
202 ok
= (read(fd
, &ps
->data_p
[prev_size
], len
) == len
);
208 /*******************************************************************
210 ********************************************************************/
211 BOOL
io_uint32(char *name
, io_struct
*ps
, int depth
, uint32
*data32
, unsigned flags
)
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
);
228 /*******************************************************************
230 ********************************************************************/
231 BOOL
io_uint16(char *name
, io_struct
*ps
, int depth
, uint16
*data16
, unsigned flags
)
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
);
248 /*******************************************************************
250 ********************************************************************/
251 BOOL
io_uint8(char *name
, io_struct
*ps
, int depth
, uint8
*data8
, unsigned flags
)
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
);
266 /*******************************************************************
268 ********************************************************************/
269 BOOL
io_pointer(char *desc
, io_struct
*ps
, int depth
, void **p
, unsigned flags
)
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);
281 /*******************************************************************
282 Stream a null-terminated string.
283 ********************************************************************/
284 BOOL
io_SMBSTR(char *name
, io_struct
*ps
, int depth
, char **str
, unsigned flags
)
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);
299 ps
->data_offset
+= len
+ 1;
303 len
= strlen(*str
)+1;
306 for(i
= 0; i
< len
; i
++) {
307 q
= io_mem_get(ps
, 1);
311 RW_CVAL(ps
->io
, q
, (*str
)[i
],0);
316 DEBUG(5,("%s%04x %s: %s\n", tab_depth(depth
),
317 start_offset
, name
, *str
));
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
)
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
;
336 DBG_RW_PCVAL(True
, name
, depth
, ps
->data_offset
, ps
->io
, q
, *data8s
, len
)
341 dump_data(depth
+5, *data8s
, num_bytes
);
343 ps
->data_offset
+= num_bytes
;
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
)
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
;
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
)
375 if (!(flags
& PARSE_SCALARS
)) return True
;
377 q
= io_mem_get(ps
, sizeof(uint16
));
378 if (q
== NULL
) return False
;
383 len
= io
->data_offset
;
385 if (!io_uint16("len", ps
, depth
+1, &len
, flags
))
389 if (UNMARSHALLING(ps
))
391 if (!io_init(io
, len
, UNMARSHALL
))
398 q
= io_mem_get(ps
, len
* sizeof(uint8
));
399 if (q
== NULL
) return False
;
403 DBG_RW_PCVAL(False
, name
, depth
+1, ps
->data_offset
, ps
->io
, q
, io
->data_p
, len
)
408 dump_data(depth
+5, q
, len
);
410 ps
->data_offset
+= len
;
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
)
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
));
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
)
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
;
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
;