2 Unix SMB/Netbios implementation.
4 Samba memory buffer functions
5 Copyright (C) Andrew Tridgell 1992-1997
6 Copyright (C) Luke Kenneth Casson Leighton 1996-1997
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 extern int DEBUGLEVEL
;
28 /*******************************************************************
29 debug output for parsing info.
31 XXXX side-effect of this function is to increase the debug depth XXXX
33 ********************************************************************/
34 void prs_debug(prs_struct
*ps
, int depth
, char *desc
, char *fn_name
)
36 DEBUG(5+depth
, ("%s%06x %s %s\n", tab_depth(depth
), ps
->offset
, fn_name
, desc
));
39 /*******************************************************************
40 initialise a parse structure
41 ********************************************************************/
42 void prs_init(prs_struct
*ps
, uint32 size
,
43 uint8 align
, uint32 margin
,
51 mem_buf_init(&(ps
->data
), margin
);
55 mem_alloc_data(ps
->data
, size
);
56 ps
->data
->offset
.start
= 0;
57 ps
->data
->offset
.end
= 0xffffffff;
61 /*******************************************************************
62 initialise a parse structure
63 ********************************************************************/
64 void prs_mem_free(prs_struct
*ps
)
66 mem_buf_free(&(ps
->data
));
69 /*******************************************************************
70 link one parsing structure to another
71 ********************************************************************/
72 void prs_link(prs_struct
*prev
, prs_struct
*ps
, prs_struct
*next
)
74 ps
->data
->offset
.start
= prev
!= NULL
? prev
->data
->offset
.end
: 0;
75 ps
->data
->offset
.end
= ps
->data
->offset
.start
+ ps
->offset
;
76 ps
->data
->next
= next
!= NULL
? next
->data
: NULL
;
79 /*******************************************************************
80 align a pointer to a multiple of align_offset bytes. looks like it
81 will work for offsets of 0, 2 and 4...
82 ********************************************************************/
83 void prs_align(prs_struct
*ps
)
85 int mod
= ps
->offset
& (ps
->align
-1);
86 if (ps
->align
!= 0 && mod
!= 0)
88 ps
->offset
+= ps
->align
- mod
;
92 /*******************************************************************
93 attempt, if appropriate, to grow a data buffer.
95 depends on the data stream mode (io)
96 ********************************************************************/
97 BOOL
prs_grow(prs_struct
*ps
)
99 return mem_grow_data(&(ps
->data
), ps
->io
, ps
->offset
, False
);
103 /*******************************************************************
105 ********************************************************************/
106 BOOL
prs_uint8(char *name
, prs_struct
*ps
, int depth
, uint8
*data8
)
108 char *q
= mem_data(&(ps
->data
), ps
->offset
);
109 if (q
== NULL
) return False
;
111 DBG_RW_CVAL(name
, depth
, ps
->offset
, ps
->io
, q
, *data8
)
117 /*******************************************************************
119 ********************************************************************/
120 BOOL
prs_uint16(char *name
, prs_struct
*ps
, int depth
, uint16
*data16
)
122 char *q
= mem_data(&(ps
->data
), ps
->offset
);
123 if (q
== NULL
) return False
;
125 DBG_RW_SVAL(name
, depth
, ps
->offset
, ps
->io
, q
, *data16
)
131 /*******************************************************************
133 ********************************************************************/
134 BOOL
prs_uint32(char *name
, prs_struct
*ps
, int depth
, uint32
*data32
)
136 char *q
= mem_data(&(ps
->data
), ps
->offset
);
137 if (q
== NULL
) return False
;
139 DBG_RW_IVAL(name
, depth
, ps
->offset
, ps
->io
, q
, *data32
)
146 /******************************************************************
147 stream an array of uint8s. length is number of uint8s
148 ********************************************************************/
149 BOOL
prs_uint8s(BOOL charmode
, char *name
, prs_struct
*ps
, int depth
, uint8
*data8s
, int len
)
151 char *q
= mem_data(&(ps
->data
), ps
->offset
);
152 if (q
== NULL
) return False
;
154 DBG_RW_PCVAL(charmode
, name
, depth
, ps
->offset
, ps
->io
, q
, data8s
, len
)
160 /******************************************************************
161 stream an array of uint32s. length is number of uint32s
162 ********************************************************************/
163 BOOL
prs_uint32s(BOOL charmode
, char *name
, prs_struct
*ps
, int depth
, uint32
*data32s
, int len
)
165 char *q
= mem_data(&(ps
->data
), ps
->offset
);
166 if (q
== NULL
) return False
;
168 DBG_RW_PIVAL(charmode
, name
, depth
, ps
->offset
, ps
->io
, q
, data32s
, len
)
169 ps
->offset
+= len
* sizeof(uint32
);
174 /******************************************************************
175 stream a "not" unicode string, length/buffer specified separately,
177 ********************************************************************/
178 BOOL
prs_uninotstr2(BOOL charmode
, char *name
, prs_struct
*ps
, int depth
, UNINOTSTR2
*str
)
180 char *q
= mem_data(&(ps
->data
), ps
->offset
);
181 if (q
== NULL
) return False
;
183 DBG_RW_PSVAL(charmode
, name
, depth
, ps
->offset
, ps
->io
, q
, str
->buffer
, str
->uni_max_len
)
184 ps
->offset
+= str
->uni_buf_len
;
189 /******************************************************************
190 stream a string, length/buffer specified separately,
192 ********************************************************************/
193 BOOL
prs_string2(BOOL charmode
, char *name
, prs_struct
*ps
, int depth
, STRING2
*str
)
195 char *q
= mem_data(&(ps
->data
), ps
->offset
);
196 if (q
== NULL
) return False
;
198 DBG_RW_PCVAL(charmode
, name
, depth
, ps
->offset
, ps
->io
, q
, str
->buffer
, str
->str_max_len
)
199 ps
->offset
+= str
->str_str_len
* sizeof(uint8
);
204 /******************************************************************
205 stream a unicode string, length/buffer specified separately,
207 ********************************************************************/
208 BOOL
prs_unistr2(BOOL charmode
, char *name
, prs_struct
*ps
, int depth
, UNISTR2
*str
)
210 char *q
= mem_data(&(ps
->data
), ps
->offset
);
211 if (q
== NULL
) return False
;
213 DBG_RW_PSVAL(charmode
, name
, depth
, ps
->offset
, ps
->io
, q
, str
->buffer
, str
->uni_max_len
)
214 ps
->offset
+= str
->uni_str_len
* sizeof(uint16
);
219 /*******************************************************************
220 stream a unicode null-terminated string
221 ********************************************************************/
222 BOOL
prs_unistr(char *name
, prs_struct
*ps
, int depth
, UNISTR
*str
)
224 char *q
= mem_data(&(ps
->data
), ps
->offset
);
226 uint8
*start
= (uint8
*)q
;
228 if (q
== NULL
) return False
;
232 RW_SVAL(ps
->io
, q
, str
->buffer
[i
],0);
236 } while ((i
< sizeof(str
->buffer
) / sizeof(str
->buffer
[0])) &&
237 (str
->buffer
[i
] != 0));
241 dump_data(5+depth
, (char *)start
, i
* 2);
246 /*******************************************************************
247 stream a null-terminated string. len is strlen, and therefore does
248 not include the null-termination character.
250 len == 0 indicates variable length string
251 (up to max size of pstring - 1024 chars).
253 ********************************************************************/
254 BOOL
prs_string(char *name
, prs_struct
*ps
, int depth
, char *str
, uint16 len
, uint16 max_buf_size
)
256 char *q
= mem_data(&(ps
->data
), ps
->offset
);
257 uint8
*start
= (uint8
*)q
;
258 int i
= -1; /* start off at zero after 1st i++ */
260 if (q
== NULL
) return False
;
266 if (i
< len
|| len
== 0)
268 RW_CVAL(ps
->io
, q
, str
[i
],0);
273 RW_CVAL(ps
->io
, q
, dummy
,0);
278 } while (i
< max_buf_size
&& (len
== 0 ? str
[i
] != 0 : i
< len
) );
282 dump_data(5+depth
, (char *)start
, i
);