Check-in [4111861b47]

Not logged in

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
SHA1 Hash:4111861b47ffcd6b6057369a6f064bf044e67775
Date: 2008-11-14 14:15:56
User: stephan
Comment:s/whclob/memblob/g
Changes
hide diffs unified diffs patch

Changes to include/s11n.net/c11n/c11n.h

Old (6edd5438695ea732) New (b3be28219ec53288)
1 #ifndef S11N_NET_C11N_H_INCLUDED 1 #ifndef S11N_NET_C11N_H_INCLUDED
2 #define S11N_NET_C11N_H_INCLUDED 1 2 #define S11N_NET_C11N_H_INCLUDED 1
3 3
4 /** @page c11n_page_main c11n: generic serialization library for C 4 /** @page c11n_page_main c11n: generic serialization library for C
5 5
166 hidden lines
172 172
173 - All functions and types in the core c11n API start with <tt>c11n_</tt>. 173 - All functions and types in the core c11n API start with <tt>c11n_</tt>.
174 It may use some utility types which are delivered with c11n but do not 174 It may use some utility types which are delivered with c11n but do not
175 really belong to the c11n API. Those routines may have their own naming 175 really belong to the c11n API. Those routines may have their own naming
176 conventions (e.g. the <tt>vappendf()</tt> family of functions and 176 conventions (e.g. the <tt>vappendf()</tt> family of functions and
177 the <tt>whclob</tt> API.). | 177 the <tt>memblob</tt> API.).
178 178
179 - Functions which related to a specific data type normally have that 179 - Functions which related to a specific data type normally have that
180 type's name as a prefix. e.g. The functions related to c11n_node 180 type's name as a prefix. e.g. The functions related to c11n_node
181 are called c11n_node_something(). 181 are called c11n_node_something().
182 182
1608 hidden lines
1791 #ifdef __cplusplus 1791 #ifdef __cplusplus
1792 } /* extern "C" */ 1792 } /* extern "C" */
1793 #endif 1793 #endif
1794 1794
1795 #endif /* S11N_NET_C11N_H_INCLUDED */ 1795 #endif /* S11N_NET_C11N_H_INCLUDED */

Deleted include/s11n.net/c11n/detail/whclob.h

Old (2b0b5649e2f46674) New ()
1 #ifndef WANDERINGHORSE_NET_WHCLOB_H_INCLUDED_ <
2 #define WANDERINGHORSE_NET_WHCLOB_H_INCLUDED_ 1 <
3 #include <stdarg.h> <
4 #include <stddef.h> <
5 <
6 /*! @page whclob_page_main whclob: dynamic char array utilities <
7 <
8 @section whclob_sec_about About whclob <
9 <
10 The whclob API encapsulates behaviours related to creating, appending, <
11 reading, writing, and freeing C-style blobs (stored in memory as char <
12 arrays). <
13 <
14 It is primarily intended to act as an output buffer for binary or <
15 string data. It provides, for example, printf-like functionality which <
16 makes use of the dynamic resize features blobs to simplify the <
17 creation and ownership management of dynamic C-style strings. <
18 <
19 whclob is heavily inspired and influenced by code in the Fossil source <
20 tree (http://www.fossil-scm.org) written by D. Richard Hipp. In that <
21 tree, blobs are used to store files in memory and to provide output <
22 buffering support for the built-in web/cgi servers. <
23 <
24 Rather than being a fork of Dr. Hipp's code, this is a <
25 reimplementation done solely for licensing reasons - his code is GPL <
26 and this is Public Domain. <
27 <
28 Much of the heavy lifting of this API is done by the vappendf API <
29 (see: \ref vappendf_page_main). <
30 <
31 Author: Stephan Beal (http://wanderinghorse.net/home/stephan/) <
32 <
33 @section whclob_sec_usage Usage <
34 <
35 A whclob object must be initialized via whclob_init() (or equivalent) <
36 and finalized via whclob_finalize(). Between those two calls, any <
37 number of other clob-API functions may be used (unless documented <
38 otherwise). As an example: <
39 <
40 @code <
41 whclob * c; <
42 whclob_init( &c, 0, 0 ); <
43 whclob_appendf( c, "Hello, %s!", "world"); <
44 ... <
45 printf("%s\n",whclob_bufferc(c)); <
46 whclob_finalize( c ); <
47 @endcode <
48 <
49 You can dump a whclob to stdout with the whclob_export() API: <
50 <
51 whclob_export( c, stdout, whclob_exporter_FILE ); <
52 <
53 But doing so with binary data is not recommended. <
54 <
55 Some example uses for clobs are: <
56 <
57 - Creating and copying strings. <
58 - Buffering input or output. <
59 - Easily reading a whole file (or other input source) into memory. <
60 <
61 @section whclob_sec_todo TODOs <
62 <
63 - The read/write API is not complete. (Can't quite remember what's <
64 missing, though.) <
65 <
66 - We really need to move from using 'long' to 'size_t' in many places. <
67 In some places that's not practical because we need to have room for <
68 negative error codes. <
69 <
70 ************************************************************************/ <
71 <
72 <
73 /** @def WHCLOB_USE_FILE <
74 <
75 If whclob is built with WHCLOB_USE_FILE set to a true value then <
76 an import/export API is included for importing/export whclob <
77 objects from/to FILE handles. <
78 */ <
79 #if !defined(WHCLOB_USE_FILE) <
80 #define WHCLOB_USE_FILE 1 <
81 #endif <
82 #if WHCLOB_USE_FILE <
83 #include <stdio.h> <
84 #endif <
85 <
86 /** @def WHCLOB_USE_ZLIB <
87 <
88 If whclob is built with WHCLOB_USE_ZLIB set to a true value then <
89 some routines are added which use zlib to de/compress whclob <
90 objects in memory. Enabling this requires that the client link <
91 with zlib (e.g. with the -lz linker argument). <
92 */ <
93 #if !defined(WHCLOB_USE_ZLIB) <
94 #define WHCLOB_USE_ZLIB 0 <
95 #endif <
96 <
97 /** @def WHCLOB_USE_BASE64 <
98 <
99 If whclob is built with WHCLOB_USE_BASE64 set to a true value then <
100 an import/export API is included for importing/export whclob <
101 objects from/to FILE handles. <
102 */ <
103 #if !defined(WHCLOB_USE_BASE64) <
104 #define WHCLOB_USE_BASE64 1 <
105 #endif <
106 <
107 <
108 <
109 #ifdef __cplusplus <
110 extern "C" { <
111 #endif <
112 <
113 /** <
114 whclob_rc_t holds status codes for the clob API. <
115 Their values must be unique negative integers, with <
116 the exception of OK, which must be 0. <
117 <
118 Many functions in the clob API return 0 or a positive <
119 number on success and one of these codes on error. <
120 <
121 The are accessed like: whclob_rc.AllocError. This is <
122 unconventional, but the intention is so that debuggers can get an <
123 actual symbol name. It also provides a namespace for <
124 our enum-like values. <
125 */ <
126 struct whclob_rc_t <
127 { <
128 /** The success status code. Must have the value 0. */ <
129 const long OK; <
130 /** Generic error code. */ <
131 const long Err; <
132 /** Signals that an allocation or reallocation failed. */ <
133 const long AllocError; <
134 /** Signals that a null was passed or received where <
135 one was not expected. */ <
136 const long UnexpectedNull; <
137 /** Signals that some value was out of range. */ <
138 const long RangeError; <
139 /** Signals an I/O error of some sort. */ <
140 const long IOError; <
141 /** Signals some sort of argument-type error (e.g. (void *) args). */ <
142 const long ArgError; <
143 }; <
144 typedef struct whclob_rc_t whclob_rc_t; <
145 <
146 /** <
147 The official way to get the clob status code values <
148 is via the whclob_rc object. <
149 */ <
150 extern const whclob_rc_t whclob_rc; <
151 <
152 /** <
153 @struct whclob <
154 <
155 The whclob type (an opaque struct) holds data relating to in-memory <
156 blobs allocated by malloc(). A whclob holds (and owns) a <
157 varying-length character array for storing arbitrary binary data. <
158 <
159 Note that because client code cannot see the whclob implementation, <
160 they cannot create whclob objects on the stack. The proper way <
161 to create, initialize, and free whclob objects is: <
162 <
163 \code <
164 whclob * c; <
165 if( whclob_rc.OK != whclob_init(&c,0,0) ) { ... error ... } <
166 ... <
167 whclob_finalize( c ); <
168 \endcode <
169 <
170 Or to use the whclob_new() convenience function: <
171 <
172 \code <
173 whclob * c = whclob_new(); <
174 if( !c ) { ... OOM ... } <
175 ... <
176 whclob_finalize( c ); <
177 \endcode <
178 <
179 */ <
180 struct whclob; <
181 typedef struct whclob whclob; <
182 <
183 <
184 /** <
185 Allocates a new whclob object and assigns (*cb) to it. It initializes <
186 the object as described below. On error it assigns (*cb) to 0. <
187 <
188 It is only legal to call this on fresh, uninitialized whclob <
189 pointer. A clob is considered to be "uninitialized" just after <
190 declaration (before it is assigned to) and after whclob_finalize() has <
191 been called on it. <
192 <
193 To avoid memory leaks, for each successful call to whclob_init() you <
194 must have a matching call to whclob_finalize(). If this function <
195 fails then (*cb) is set to 0, so there is no need to call <
196 whclob_finalize() (but it is still safe (but a no-op) to do so, for <
197 the cases where doing so may simplify error handling). <
198 <
199 Interpretation of the 'data' and 'n' arguments: <
200 <
201 - If data is null and n is less than 1 then cb is initialized <
202 to a zero-length string. <
203 <
204 - If data is non-null and n is less than 0 then strlen(data) is used <
205 to calculate n. <
206 <
207 - If data is non-null and n is greater than 0 then the first n <
208 bytes of data are copied and data is assumed to be at least that <
209 long. <
210 <
211 - If data is 0 and n is positive then n bytes are reserved and <
212 zeroed. <
213 <
214 RETURNS: <
215 <
216 If this function returns whclob_rc.OK then (*cb) points to a new whclob <
217 object. On error it returns one of the negative integers defined in <
218 whclob_rc: <
219 <
220 - whclob_rc.UnexpectedNull if (!cb). <
221 <
222 - whclob_rc.AllocError if allocation of the new whclob fails. <
223 <
224 USAGE NOTES: <
225 <
226 Calling whclob_finalize(0) has no ill effects (other than an <
227 ignorable error code), so algorithms may be organized a call <
228 whclob_finalize() regardless of whether whclob_init() succeeds or <
229 fails. It is anticipated that this may simplify some error-handling <
230 cases. <
231 */ <
232 long whclob_init( whclob ** cb, char const * data, long n ); <
233 <
234 /** <
235 A simplified form of whclob_init() which allocates a new, empty whclob <
236 of the given size and returns it. The caller owns it and must finalize it with <
237 whclob_finalize(). On error (out of memory) it returns 0. <
238 */ <
239 whclob * whclob_new_n( size_t reserved ); <
240 <
241 /** <
242 Equivalent to whclob_new_n(0). <
243 */ <
244 whclob * whclob_new(); <
245 <
246 /** <
247 See whclob_set_alloc_policy() and <
248 See whclob_set_default_alloc_policy(). <
249 */ <
250 typedef long (*whclob_alloc_policy_t)( long ); <
251 <
252 /** <
253 Sets the current allocation size determination policy and returns <
254 the previous one (so you may politely reset it when yours goes out <
255 of scope). <
256 <
257 When the framework wants to (re)allocate memory it will call the <
258 current policy function and pass it the suggested amount of memory <
259 it wants to reallocate. The policy may return that number as-is or <
260 adjust it upwards (e.g. *= 1.5) (never downwards) and return that <
261 number, which the reallocation will then use. If a smaller number <
262 is returned it will be ignored. <
263 <
264 Note that the policy only specifies a requested size, not where the <
265 memory will come from. The memory will always be pulled from <
266 malloc(). Likewise, the cleanup routines always use free() to <
267 delete the memory. <
268 <
269 The intention is to allow clients to who know they will append <
270 blobs a lot to increase the size of the allocs to reduce the number <
271 of potential reallocations. <
272 <
273 Be aware that the reallocation internals may allocate slightly more <
274 memory than requested, e.g. to unsure that the blob always has a <
275 trailing null character. <
276 <
277 If passed 0 it will use a default policy, which simply returns the <
278 value passed to it. You can fetch the current policy, if you like, <
279 by passing 0 to this function, then passing that return value <
280 back to this function. <
281 */ <
282 whclob_alloc_policy_t whclob_set_default_alloc_policy( whclob_alloc_policy_t ); <
283 <
284 /** <
285 Works just like whclob_set_default_alloc_policy() except that it <
286 applies only to cb and takes precedence over <
287 whclob_set_default_alloc_policy(). <
288 */ <
289 whclob_alloc_policy_t whclob_set_alloc_policy( whclob * cb, whclob_alloc_policy_t ); <
290 <
291 <
292 /** <
293 Free the resources, if any, associated with cb and zeroes out the <
294 freed memory. After calling this, whclob_buffer(cb) will be an empty <
295 string and both whclob_size(cb) and whclob_capacity(cb) will be 0. <
296 <
297 It is illegal to pass a whclob which was not initialized by <
298 whclob_init() (or equivalent). Doing so results in undefined <
299 behaviour. <
300 <
301 Note that this function does not actually free the cb pointer <
302 itself. After this function returns, cb can be re-used by any clob <
303 API which is append-friendly (e.g. not whclob_char_filln()). <
304 <
305 On success it returns whclob_rc.OK. On error it returns: <
306 <
307 - whclob_rc.UnexpectedNull if (!cb). <
308 */ <
309 long whclob_reset( whclob * cb ); <
310 <
311 /** <
312 whclob_finalize() works just like whclob_reset(), plus it <
313 deallocates cb by calling free(). After calling this, cb is invalid <
314 until/unless it is passed to whclob_init() again. <
315 <
316 Returns whclob_rc.OK on success and whclob_rc.UnexpectedNull if <
317 (!cb). <
318 */ <
319 long whclob_finalize( whclob * cb ); <
320 <
321 /** <
322 Force's cb's cursor and used counter to be in bounds of the <
323 actual allocated memory. They are moved forwards or backwards, <
324 as necessary, to bring them into bounds. <
325 */ <
326 void whclob_force_in_bounds( whclob * cb ); <
327 <
328 /** <
329 Tries to reserve at least sz bytes of memory for the native blob <
330 associated with cb. It will not shrink the blob, only grow it or <
331 leave it alone, with one exception: if sz is 0 then the effect is <
332 the same as whclob_reset(). <
333 <
334 This function may invalidate any old pointers obtained via <
335 whclob_buffer(). <
336 <
337 Note that shrinking a clob may cause the internal position <
338 cursor (used by the read/write API) to move backwards to the <
339 new logical EOF. <
340 <
341 If cb is "const" (points to a blob but has an allocated size of 0) <
342 then calling this with a non-zero sz will cause sz bytes of the <
343 referenced blob data to be deeply copied to cb. <
344 <
345 On success it returns the number of bytes allocated to cb. The <
346 number may be larger than sz, due to internal details of this API <
347 and the implementation of the current allocation policy (see <
348 whclob_set_default_alloc_policy()). <
349 <
350 On error it returns one of the negative numbers specified <
351 by whclob_rc: <
352 <
353 - whclob_rc.AllocError = (re)allocation failed. <
354 <
355 - whclob_rc.UnexpectedNull = cb parameter was 0. <
356 <
357 */ <
358 long whclob_reserve( whclob * cb, unsigned int sz ); <
359 <
360 /** <
361 Works like whclob_reserve(), but marks all memory <
362 in the clob as used. This means that appending <
363 will start from sz, rather than from whatever <
364 the end previously was. It returns the same values <
365 as whclob_reserve(). <
366 */ <
367 long whclob_resize( whclob * cb, unsigned int sz ); <
368 <
369 /** <
370 Returns the number of "used" bytes in cb. Appending to a clob will <
371 start after the last "used" byte. Note that clobs may (and normally do) <
372 have more memory allocated to them than is "used". <
373 <
374 Returns 0 or greater (the size of cb) on success and <
375 whclob_rc.UnexpectedNull if (!cb). <
376 */ <
377 long whclob_size( whclob const * cb ); <
378 <
379 /** <
380 Returns the current allocated capacity of cb, or <
381 whclob_rc.UnexpectedNull if (!cb). <
382 <
383 The capacity will always be equal to or greater than whclob_size(cb). <
384 */ <
385 long whclob_capacity( whclob const * cb ); <
386 <
387 /** <
388 Returns a pointer to cb's buffer (may be 0). The buffer is owned by <
389 cb. <
390 <
391 Do not keep ahold of the returned pointer for longer than <
392 necessary, as any operations which change cb may invalidate that <
393 pointer. <
394 <
395 Do not generically depend on the returned array being a <
396 null-terminated string, as cb can hold arbitrary data. Use <
397 whclob_size(sb) to get the length of the data. <
398 */ <
399 char * whclob_buffer( whclob * cb ); <
400 <
401 /** <
402 A variant of whclob_buffer() for places where a const is needed. <
403 */ <
404 char const * whclob_bufferc( whclob const * cb ); <
405 <
406 /** <
407 Gives up cb's control of any allocated memory and returns it to the <
408 caller, who takes over ownership. <
409 <
410 If a blob is storing binary data then there is no way to know the <
411 size of the returned buffer. Thus if you need its length, be sure <
412 to call whclob_size(cb) before calling this. <
413 <
414 This function effectively does whclob_reset(cb) but does not finalize <
415 cb. Thus after calling this function cb is still a valid object for <
416 purposes of the other whclob_xxx() functions. <
417 */ <
418 char * whclob_take_buffer( whclob * cb ); <
419 <
420 /** <
421 Flags for whclob_seek(), they are identical in nature to SEEK_SET, <
422 SEEK_CUR, and SEEK_END used by the conventional fseek() C function. <
423 <
424 WHCLOB_SEEK_SET: moves the cursor to absolute position (offset). <
425 <
426 WHCLOB_SEEK_CUR: moves the cursor to (cursor + offset). <
427 <
428 WHCLOB_SEEK_END: moves the cursor to relative postition (end - <
429 offset), where 'end' is the index 1 after the last character of the <
430 USED portion of the blob. e.g. the end of "abcd" is at position 4. <
431 */ <
432 enum WHClobSeekWhence { WHCLOB_SEEK_SET = 0, <
433 WHCLOB_SEEK_CUR = 1, <
434 WHCLOB_SEEK_END = -1 <
435 }; <
436 <
437 /** <
438 Similar to the standard fseek(), whclob_seek() moves the blob's <
439 cursor to its (current pos + offset), relative to whence, which <
440 must be one of of the ClobSeekFlags values. Once the seek is <
441 complete, the cursor is bumped back into bounds (or at EOF). The <
442 return value is the new cursor position within the blob. <
443 <
444 Note that when using WHCLOB_SEEK_END, only a negative offset makes <
445 sense, as a positive offset is out of bounds. <
446 <
447 The return value is a positive integer on success, indicting the <
448 new position within the blob. On error a negative number is <
449 returned: <
450 <
451 - whclob_rc.RangeError = the 'whence' value is unknown. <
452 <
453 */ <
454 long whclob_seek( whclob * cb, long offset, int whence ); <
455 <
456 /** <
457 Moves cb's cursor back to the begining of the blob. <
458 */ <
459 void whclob_rewind( whclob * cb ); <
460 <
461 /** Returns whclob_rc.OK if pos is within the used bounds of cb, <
462 else returns whclob_rc.RangeError. <
463 */ <
464 long whclob_pos_in_bounds( whclob * cb, long pos ); <
465 <
466 <
467 /** <
468 Fills the pointed-to memory with char specified by c, starting at <
469 blob offset specified by startPos and copying the next n bytes. It ignores <
470 the "used" space boundary and fills any allocated space. It does <
471 not change the size of the allocated memory block or its used-space <
472 count. <
473 <
474 On success it returns the number of zeroes which it fills <
475 in. Normally this is n, but if (startPos + n) would overflow, the <
476 blob is filled to the end and that (smaller) length is returned. <
477 <
478 On failure it returns one of the values defined in whclob_rc: <
479 <
480 - whclob_rc.Err if cb does not contain a blob, or points <
481 to a blob but does not own it. <
482 <
483 - whclob_rc.RangeError if startPos is out of bounds or n <= 0. <
484 */ <
485 long whclob_char_filln( whclob * cb, char c, long startPos, long n ); <
486 <
487 /** <
488 Same as whclob_char_filln( cb, '\\0', 0, whclob_size( cb ) ); <
489 */ <
490 long whclob_zero_fill( whclob * cb ); <
491 <
492 <
493 /** <
494 Appends the first dsize bytes of data to cb's blob, exanding the <
495 blob as needed. If dsize is -1 then strlen(data) is used to <
496 calculate the length. If dsize is 0 an error code is returned (see <
497 below). This does not modify cb's internal position cursor. <
498 <
499 If cb does not currently own the blob it points to then this <
500 function may cause it to create a copy of that object, and append <
501 to that copy. This may or may not be expensive, depending on the <
502 size of the copy. <
503 <
504 Unlike whclob_appendf(), this function is safe for use with binary <
505 data, but only if dsize is explicitly set. Otherwise it will only <
506 append up to the first null character in data. <
507 <
508 On success a positive integer is returned, the number of bytes by <
509 which the blob extended. On failure, one of the negative values <
510 defined in whclob_rc is returned: <
511 <
512 - whclob_rc.AllocError if a memory (re)allocation fails. <
513 <
514 - whclob_rc.RangeError if dsize is 0. <
515 */ <
516 long whclob_append( whclob * cb, char const * data, long dsize ); <
517 <
518 /** <
519 Appends n copies of ch to cb and returns the number added. If n is less <
520 than 1 then whclob_rc.RangeError is returned and cb is not modified. <
521 */ <
522 long whclob_append_char_n( whclob * cb, char ch, const long n ); <
523 <
524 /** <
525 Makes a deep copy of src, placing it into dest. <
526 <
527 Neither src nor dest may be 0. dest is deallocated before the copy <
528 happens. <
529 <
530 Returns one of the values defined in whclob_rc: <
531 <
532 - whclob_rc.RangeError if (src==dest). <
533 <
534 - whclob_rc.AllocError if a memory (re)allocation fails. <
535 <
536 - whclob_rc.OK on success. <
537 */ <
538 long whclob_copy( whclob * src, whclob * dest ); <
539 <
540 <
541 <
542 /** <
543 Like printf, but output is appended to the end of cb, expanding it <
544 as necessary. It also imlements a couple extension conversions, to <
545 be documented in the docs for vappendf(). <
546 <
547 Return value: if the number is >= 0 then it is the size by which <
548 the target blob grew as a result of the printf (i.e. the number of <
549 bytes printf added to it). If the return value is negative then it <
550 is an error code from whclob_rc. <
551 <
552 This function is not safe for binary data - if fmt contains <
553 any null characters the processing will stop. <
554 <
555 For the list of non-standard format specifiers, see <
556 the documentation for vappendf(). <
557 */ <
558 long whclob_vappendf( whclob * cb, char const * fmt, va_list vargs ); <
559 <
560 <
561 /** <
562 See whclob_vappendf(whclob*,char const *,va_list). This is identical <
563 except that it takes an elipses list instead of va_list. <
564 */ <
565 long whclob_appendf( whclob * cb, const char * fmt, ... ); <
566 <
567 <
568 <
569 /** <
570 Reads up to n bytes from src, starting at startPos, and copies them <
571 to dest. This does not advance cb's internal cursor. <
572 <
573 On success the return value is the number of bytes read, which may <
574 be less than n (or 0 on EOF). <
575 <
576 On error it returns one of the negative values defined <
577 in whclob_rc: <
578 <
579 - whclob_rc.UnexpectedNull if src or dest are null <
580 <
581 - whclob_rc.RangeError if n is less than 1 or if startPos is out of <
582 src's bounds. <
583 */ <
584 long whclob_copy_slice( whclob * src, whclob * dest, long startPos, long n ); <
585 <
586 /** <
587 Reads up to n bytes from src, starting at the current <
588 cursor position (whclob_tell()). Reading advances <
589 the cursor. <
590 <
591 The return value is the number of bytes read, which <
592 may be less than n (or 0 on EOF). <
593 */ <
594 long whclob_read( whclob * src, whclob * dest, long n ); <
595 <
596 /** <
597 Returns the current position of cb's internal cursor, analogous to <
598 the standard ftell() function. <
599 */ <
600 long whclob_tell( whclob const * cb ); <
601 <
602 /** <
603 This function is just like whclob_append() but it starts writing <
604 at the position returned by whclob_tell(cb). Writing advances <
605 the internal cursor. It returns the number of bytes written. <
606 <
607 If dsize is -1 then strlen(data) is used for dsize. <
608 <
609 On success it returns the number of bytes written. On failure it <
610 returns a negative integer error code defined in whclob_rc: <
611 <
612 - whclob_rc.AllocationError if memory could not be allocated. <
613 <
614 - whclob_rc.RangeError if dsize is 0. <
615 <
616 - whclob_rc.UnexpectedNull if data is 0. <
617 */ <
618 long whclob_write( whclob * cb, char const * data, long dsize ); <
619 <
620 <
621 <
622 /** <
623 This function ensures that the one-past-the-last item in the blob <
624 to 0. The "used" size of cb does not change. <
625 <
626 On success it returns whclob_rc.OK. On failure it returns one of the <
627 negitive integer values defined in whclob_rc: <
628 <
629 - whclob_rc.Err if cb does not own a pointer to an underlying blob. <
630 <
631 - whclob_rc.AllocError if a memory (re)allocation fails. <
632 */ <
633 long whclob_null_terminate( whclob * cb ); <
634 <
635 /** <
636 "Chops" cb off at a given length. If the current used space is <
637 smaller than pos then it will be padded with NULLs to make it fit. <
638 It is is longer than pos then the clob will be reallocated (if <
639 necessary) to fit the new space and any old data which is now <
640 outside the used range will be zeroed out (this is necessary for <
641 sane behaviour in some use cases). In any case, on success the new <
642 position of the clob will be the given position. <
643 <
644 If allocPolicy is 0 then the amount of memory allocated by cb is <
645 not adjusted (unless (pos>whclob_size(cb)), in which case we have <
646 to expand the clob). If it is >0, whclob_reserve() will be called <
647 to try to reserve at least pos bytes. If (allocPolicy<0) then the <
648 allocated memory is shrunk to fit (if possible). If pos is past the <
649 current end-of-data position then allocPolicy is forced to 1 so <
650 that the buffer can be expanded (if needed). <
651 <
652 Returns whclob_rc.OK or a positive value on success or a negative <
653 value from whclob_rc on error. <
654 <
655 The two most common uses for this function: <
656 <
657 - "Shrink-wrapping" the value (eliminating extra allocated space) <
658 <
659 - Re-using a clob's buffer as a target for, e.g. fread(), by <
660 reserving a certain amount of space then truncating it at position <
661 0 but with an allocPolicy of >=0. This can save on allocations compared <
662 to using, e.g. whclob_reset(). <
663 <
664 */ <
665 long whclob_truncate( whclob * cb, long pos, int allocPolicy ); <
666 <
667 /* TODO???: whclob_trim() */ <
668 <
669 <
670 /** <
671 whclob_exporter is a generic interface to exporting whclob objects <
672 (e.g. to arbitrary streams). <
673 <
674 Policy for implementations: <
675 <
676 - Take a (char const *) data pointer and "export" n bytes of it, <
677 where the meaning of "export" is implementation-specified. <
678 <
679 - The 'arg' argument is an implementation-specific pointer. This API <
680 does not use it, but passes it on so that client code can use it, e.g. <
681 to accumulate or export data (e.g. by passing an output stream handle). <
682 <
683 - On success it must return 0 or greater. Ideally it should return the <
684 exact number of bytes processed, but that might not be feasible for <
685 some implementations. In those cases, returning n is the best approach. <
686 <
687 - On failure it must return a negative number, prefferably one of those <
688 defined by whclob_rc. <
689 */ <
690 typedef long (*whclob_exporter)( void * arg, char const * data, long n ); <
691 <
692 /** <
693 whclob_export() is a generic interface for exporting blobs to <
694 "external representations". <
695 <
696 It calls pf( arg, ... ) one time to export cb's data using whatever <
697 approach pf implements. The return value is that of calling pf. <
698 */ <
699 long whclob_export( whclob const * cb, void * arg, whclob_exporter pf ); <
700 <
701 /** <
702 whclob_importer is the import counterpart of whclob_exporter. It <
703 defines an interface for callbacks which can provide a blob with <
704 data. <
705 <
706 Note that for input it is not generically possible to <
707 get the length of the data before starting. Thus this <
708 API takes a whclob object, which it can append to, whereas <
709 the whclob_exporter functions take raw data pointers as <
710 sources. <
711 <
712 target must be an initialized whclob. It is appended to, <
713 not overwritten. It is expanded as necessary. <
714 <
715 Return value is the number of bytes appended to the target, or a <
716 negative number on error (preferably one of the whclob_rc error <
717 codes). <
718 */ <
719 typedef long (*whclob_importer)( whclob * target, void * arg ); <
720 <
721 /** <
722 Returns the same as pf( arg, dest ). <
723 */ <
724 long whclob_import( whclob * dest, void * arg, whclob_importer pf ); <
725 <
726 /** <
727 Moves a block of memory within cb, starting at start1, moving n <
728 bytes to the position starting at start2. All points and ranges <
729 must be in the whclob_size() range. start2 may be less than start1 <
730 but they may not be equal. A value of less than 1 for n is not <
731 currently supported, though it should be to support backwards <
732 movement of memory. <
733 <
734 Memory which is "moved" gets filled with the specified filler char <
735 after its contents are copied to its new location. <
736 <
737 This function does not change the size of cb. <
738 <
739 On success it returns the number of bytes moved (n) <
740 and on failure it returns: <
741 <
742 - whclob_rc.RangeError if any values or ranges are out of bounds <
743 <
744 - whclob_rc.UnexpectedNull if cb is null. <
745 */ <
746 long whclob_memmove_fill( whclob * cb, char const filler, int start1, int n, int start2 ); <
747 <
748 /** <
749 A convenience form of whclob_memmove_fill(cb,0,start1,n,start2). <
750 */ <
751 long whclob_memmove( whclob * cb, int start1, int n, int start2 ); <
752 <
753 /** <
754 Swaps the contents of n bytes between two blobs. start1 is relative <
755 to cb1 and start2 is relative to cb2. <
756 <
757 On success it returns the number of bytes swapped. On error it returns <
758 one of: <
759 <
760 - whclob_rc.UnexpectedNull if (!cb1) or (!cb2). <
761 <
762 - whclob_rc.RangeError if start1 and n are not within cb1's bounds <
763 or start2 and n are not within cb2's bounds. <
764 <
765 This is a linear operation (based on the value of n). If you want <
766 to swap the entire contents of two clobs, you can do so in constant <
767 time by using whclob_swap() instead of this routine. <
768 */ <
769 long whclob_memswap( whclob * cb1, int start1, int n, whclob * cb2, int start2 ); <
770 <
771 <
772 /** <
773 Efficiently swaps the contents of blobs c1 and c2, which must <
774 both be initialized clobs. <
775 <
776 Returns whclob_rc.OK on success or whclob_rc.UnexpectedNull <
777 if either c1 or c2 are null. <
778 */ <
779 long whclob_swap( whclob * c1, whclob * c2 ); <
780 <
781 /** <
782 Copies the contents of src to the dest, which <
783 must be an UNINITIALIZED whclob object. <
784 <
785 Returns whclob_rc.OK on success or, on error: <
786 <
787 - whclob_rc.AllocError <
788 <
789 - whclob_rc.UnexpectedNull if src is null. <
790 <
791 Example usage: <
792 <
793 \code <
794 <
795 whclob * orig; <
796 whclob_init( &orig ); <
797 whclob_appendf( orig, "Hi, world." ); <
798 whclob * clone; <
799 whclob_clone( orig, &clone ); <
800 <
801 \endcode <
802 <
803 Note the pointer-to-pointer parameter for whclob_init() <
804 and the second parameter to whclob_clone(). <
805 <
806 */ <
807 long whclob_clone( whclob * src, whclob ** dest ); <
808 <
809 /** <
810 Works more or less like sprintf(), but supports the printf <
811 specifiers accepted by whclob_appendf() and can automatically <
812 extends the string as necessary. The caller owns the returned <
813 null-terminated string and must free it using free(). <
814 */ <
815 char * whclob_vmprintf( char const * fmt, va_list vargs ); <
816 <
817 /** <
818 Functionally identical to whclob_vmprintf() but takes <
819 a (...) ellipses list instead of a va_list. <
820 */ <
821 char * whclob_mprintf( char const * fmt, ... ); <
822 <
823 <
824 #if WHCLOB_USE_FILE <
825 /** @implements whclob_exporter <
826 <
827 This is a sample whclob_exporter for use with whclob_export. <
828 It is used like this: <
829 <
830 whclob_export( clob, an_open_FILE_handle, whclob_exporter_FILE ); <
831 <
832 The second argument to whclob_export must be an open (FILE*). <
833 <
834 Returns n on success and a negative number on error. <
835 <
836 The file handle is not closed by this routine. <
837 */ <
838 long whclob_exporter_FILE( void * fh, char const * data, long n ); <
839 <
840 /** <
841 Like whclob_exporter_FILE(), but expects arg to be a (char const *) <
842 filename. Returns the same as the equivalent whclob_exporter_FILE() <
843 unless arg cannot be opened as a file, in which case <
844 whclob_rc.IOError is returned. <
845 */ <
846 long whclob_exporter_filename( void * arg, char const * data, long n ); <
847 <
848 /** <
849 A whclob_importer implementation for whclob_import. It expects <
850 arg to be an open (FILE*). The target is appended with the <
851 contents of the file. On error, a negative number is returned. <
852 On success, the number of bytes added to the target. <
853 <
854 If arg is not a (FILE*) then whclob_rc.ArgError is returned. <
855 <
856 The file handle is not closed by this routine. <
857 */ <
858 long whclob_importer_FILE( whclob * target, void * arg ); <
859 <
860 /** <
861 A whclob_importer implementation similar to whclob_importer_FILE(), but <
862 expects arg to be a (char const *) filename. Returns the same as <
863 the equivalent whclob_importer_FILE() call unless arg cannot be <
864 opened as a file, in which case whclob_rc.IOError is returned. <
865 */ <
866 long whclob_importer_filename( whclob * target, void * arg ); <
867 <
868 /** <
869 Sends cb's blob to the given file handle, which must have been <
870 previously opened. Returns the number of bytes written on success <
871 or a negative number (probably whclob_rc.IOError) on error. <
872 <
873 The file handle is not closed by this routine. <
874 */ <
875 long whclob_export_FILE( whclob const * cb, FILE * dest ); <
876 <
877 /** <
878 Identical to whclob_export_to_FILE() but takes a file <
879 name. <
880 */ <
881 long whclob_export_filename( whclob const * cb, char const * dest ); <
882 <
883 /** <
884 The read counterpart of whclob_export_FILE(), appends all data <
885 from src to cb. Return value is as for whclob_import(). <
886 */ <
887 long whclob_import_FILE( whclob * cb, FILE * src ); <
888 <
889 /** <
890 Identical to whclob_import_FILE() but takes a file <
891 name. <
892 */ <
893 long whclob_import_filename( whclob * dest, char const * src ); <
894 #endif /* WHCLOB_USE_FILE */ <
895 <
896 #if WHCLOB_USE_ZLIB <
897 /** <
898 Compresses the contents of src to dest using the zlib compress() <
899 function. dest may be either the same as src or an initialized <
900 clob. If dest is not src then this function will clear dest's <
901 contents whether or not this routine succeeds. If (dest==src) <
902 then src is only modified if this routine succeeds. <
903 <
904 Returns whclob_rc.OK on success, some other value on error: <
905 <
906 - whclob_rc.IOError: compression failed <
907 <
908 - whclob_rc.AllocError = a (re)allocation failed. <
909 <
910 Note that the compressed data is compressed using zlib but contains <
911 its own header, so it will not be usable by tools like gunzip. <
912 */ <
913 int whclob_compress( whclob * src, whclob * dest ); <
914 <
915 /** <
916 The converse of whclob_compress(), src is expected to be clob containing <
917 data compressed with whclob_compress(). dest must be an initialized clob. <
918 If dest is not the same as src then dest will be reset whether not <
919 this routine succeeds. If (dest==src) then it is only modified <
920 if this routine succeeds. <
921 <
922 Returns whclob_rc.OK on success, some other value on error: <
923 <
924 - whclob_rc.RangeError: source does not appear to contain any <
925 compressed data or data was written by a different version of this <
926 API. <
927 <
928 - whclob_rc.ArgError: input is too small to contain the compression <
929 header. <
930 <
931 - whclob_rc.IOError: decompression failed <
932 <
933 - whclob_rc.AllocError = a (re)allocation failed. <
934 <
935 */ <
936 int whclob_uncompress( whclob * src, whclob * dest ); <
937 <
938 <
939 /** <
940 Works equivalently to whclob_compress(), but uses the zlib deflate() <
941 algorithm instead of the compress() algorithm. <
942 */ <
943 int whclob_deflate( whclob *cIn, whclob *cOut ); <
944 <
945 /** <
946 The converse of whclob_deflate(), this works equivalently to <
947 whclob_uncompress(), but uses the zlib inflate() algorithm instead of <
948 the uncompress() algorithm. <
949 */ <
950 int whclob_inflate( whclob *cIn, whclob *cOut ); <
951 #endif /* WHCLOB_USE_ZLIB */ <
952 <
953 #if WHCLOB_USE_BASE64 <
954 /** <
955 Encodes cIn's contents in base64 and sends it to cOut. <
956 cIn may be the same as cOut. If cOut is not cIn then <
957 it is cleared before encoding begins. On success, cOut is populated with <
958 the encoded data and whclob_rc.OK is returned. On error: <
959 <
960 - If (!cIn, !cOut, or !whclob_size(cIn)) then whclob_rc.ArgError <
961 is returned and cOut is unmodified. <
962 <
963 - On any other error, if (cIn!=cOut) then cOut will contain no <
964 data, otherwise cIn/cOut will be unmodified. In these cases some <
965 other error code from whclob_rc will be returned. <
966 */ <
967 long whclob_base64_enc( whclob const *cIn, whclob *cOut ); <
968 <
969 /** <
970 The converse of whclob_base64_enc(), with the same <
971 conventions. <
972 */ <
973 long whclob_base64_dec( whclob const *cIn, whclob *cOut ); <
974 #endif /* WHCLOB_USE_BASE64 */ <
975 <
976 <
977 #ifdef __cplusplus <
978 } /* extern "C" */ <
979 #endif <
980 #endif /* WANDERINGHORSE_NET_WHCLOB_H_INCLUDED_ */ <

Changes to include/s11n.net/c11n/io/c11n_io.h

Old (836884ee4f81529a) New (2df8e7de086cd98b)
1 #ifndef S11N_NET_C11N_IO_H_INCLUDED 1 #ifndef S11N_NET_C11N_IO_H_INCLUDED
2 #define S11N_NET_C11N_IO_H_INCLUDED 1 2 #define S11N_NET_C11N_IO_H_INCLUDED 1
3 /* 3 /*
4 This file contains declarations and documentation for the generic 4 This file contains declarations and documentation for the generic
5 i/o routines for c11n. The core does not know about this API and no 5 i/o routines for c11n. The core does not know about this API and no
307 hidden lines
313 member, as documented in c11n_stream_api. Ownership of the underlying 313 member, as documented in c11n_stream_api. Ownership of the underlying
314 native stream is defined by the factory function which creates 314 native stream is defined by the factory function which creates
315 the stream. 315 the stream.
316 316
317 For examples of creating concrete implementations of this type, 317 For examples of creating concrete implementations of this type,
318 see the files c11n_stream_FILE.c and c11n_stream_whclob.c. | 318 see the files c11n_stream_FILE.c and c11n_stream_memblob.c.
319 */ 319 */
320 struct c11n_stream 320 struct c11n_stream
321 { 321 {
322 /** 322 /**
323 The api object represents the public API of this class. 323 The api object represents the public API of this class.
490 hidden lines
814 strings containing backslash escapes in them. 814 strings containing backslash escapes in them.
815 */ 815 */
816 size_t esc_len; 816 size_t esc_len;
817 } c11n_string_escape_info; 817 } c11n_string_escape_info;
818 818
819 struct whclob; // Provided by whclob.h | 819 struct memblob; // Provided by memblob.h
820 820
821 /** 821 /**
822 c11n_io_escape_string() is a generic string escaping/unescaping 822 c11n_io_escape_string() is a generic string escaping/unescaping
823 routine. It scans the first inlen characters of input for entries 823 routine. It scans the first inlen characters of input for entries
824 from the given table. On a match, it "replaces" the original with 824 from the given table. On a match, it "replaces" the original with
29 hidden lines
854 {"&",1,"&amp;",5}, 854 {"&",1,"&amp;",5},
855 {"<",1,"&lt;",4}, 855 {"<",1,"&lt;",4},
856 {">",1,"&gt;",4}, 856 {">",1,"&gt;",4},
857 {0,0,0,0} 857 {0,0,0,0}
858 }; 858 };
859 whclob * dest = whclob_new(); | 859 memblob * dest = memblob_new();
860 c11n_io_escape_str( input, inlen, escapes, true, dest ); 860 c11n_io_escape_str( input, inlen, escapes, true, dest );
861 printf("%s\n", whclob_bufferc(dest) ); // A%20B%20&lt;C&gt; | 861 printf("%s\n", memblob_bufferc(dest) ); // A%20B%20&lt;C&gt;
862 whclob_finalize(dest); | 862 memblob_finalize(dest);
863 @endcode 863 @endcode
864 */ 864 */
865 size_t c11n_io_escape_string( c11n_const_string_t input, size_t inlen, 865 size_t c11n_io_escape_string( c11n_const_string_t input, size_t inlen,
866 c11n_string_escape_info const * table, 866 c11n_string_escape_info const * table,
867 bool doEscape, 867 bool doEscape,
868 struct whclob * target ); | 868 struct memblob * target );
869 869
870 870
871 /** 871 /**
872 Consumes stream to the first \\n character. It appends that data, minus the newline, 872 Consumes stream to the first \\n character. It appends that data, minus the newline,
873 to dest. Returns the number of characters appended to dest, or 0 at EOF or on a read 873 to dest. Returns the number of characters appended to dest, or 0 at EOF or on a read
874 error. 874 error.
875 875
876 Note that the stream is consumed and the trailing newline character 876 Note that the stream is consumed and the trailing newline character
877 (if any) is effectively lost. 877 (if any) is effectively lost.
878 */ 878 */
879 size_t c11n_stream_readln_membuf(c11n_stream * stream, struct whclob * dest ); | 879 size_t c11n_stream_readln_membuf(c11n_stream * stream, struct memblob * dest );
880 880
881 /** 881 /**
882 Functionally identical to c11n_stream_readln_membuf() except that the 882 Functionally identical to c11n_stream_readln_membuf() except that the
883 line is returned as a null-termined string which the caller must 883 line is returned as a null-termined string which the caller must
884 clean up using free(). On error or EOF 0 is returned. 884 clean up using free(). On error or EOF 0 is returned.
3 hidden lines
888 #ifdef __cplusplus 888 #ifdef __cplusplus
889 } /* extern "C" */ 889 } /* extern "C" */
890 #endif 890 #endif
891 891
892 #endif // S11N_NET_C11N_IO_H_INCLUDED 892 #endif // S11N_NET_C11N_IO_H_INCLUDED

Added include/s11n.net/c11n/io/c11n_stream_memblob.h

Old () New (08275c48f0dba287)
> 1 #if !defined(_S11N_NET_C11N_STREAM_MEMBLOB_H_INCLUDED_)
> 2 #define _S11N_NET_C11N_STREAM_MEMBLOB_H_INCLUDED_ 1
> 3
> 4 #include "c11n_io.h"
> 5 #ifdef __cplusplus
> 6 extern "C" {
> 7 #endif
> 8
> 9 /** Provided by memblob.h */
> 10 struct memblob;
> 11
> 12 /**
> 13 Creates a stream which uses memblob object as its i/o
> 14 source/destination, thus providing an in-memory i/o buffer. The
> 15 clob parameter is of type memblob, which is defined in the
> 16 memblob API (see: @ref memblob_page_main).
> 17
> 18 It supports both read and write modes, but be aware of the
> 19 cursor semantics of the memblob API before trying to use it for
> 20 both. It is safest (and most predictable) to use it for only
> 21 reading or writing, not both.
> 22
> 23 The returned stream object must be destroyed by calling
> 24 stream->api->destroy(stream).
> 25
> 26 Requirements of the clob object are:
> 27
> 28 - It is owned by the caller. Calling stream->api->destroy(stream)
> 29 does not modify the clob (but does destroy the stream object).
> 30
> 31 - When the stream is written to, the data is appended to the current
> 32 cursor position of clob, growing the clob as needed.
> 33
> 34 - When the stream is read, the data is read from the current
> 35 cursor position of clob. It will not, of course, read past
> 36 the logical EOF.
> 37
> 38 In other words:
> 39
> 40 If stream->api->read() is called then the source clob must be
> 41 pre-populated by the caller so that we have something to read
> 42 out. That data is then copied to the stream->api->read()
> 43 destination pointer. If stream->api->write() is called, the data
> 44 from that source will be appended to the clob using
> 45 memblob_append().
> 46
> 47 Behaviour is undefined if calls to stream->api->read(),
> 48 stream->api->write(), and/or the memblob API are inter-mixed,
> 49 with the exception that it is safe to use memblob_rewind()
> 50 to re-set an input buffer to its begining position.
> 51
> 52 When using output clob-streams to buffer any significant
> 53 amount of data, it is a good idea to initialize the clob
> 54 to some reasonable buffer size, e.g. using either memblob_init()
> 55 or memblob_reserve().
> 56 */
> 57 c11n_stream * c11n_stream_for_memblob( struct memblob * clob );
> 58
> 59 /**
> 60 Reads at most max bytes from src and appends them to dest. Returns
> 61 the number of bytes read, or 0 if any arguments are 0, if 0 bytes
> 62 are read, or if dest needs to grow and a re-allocation fails.
> 63 */
> 64 size_t c11n_stream_buffer_read( c11n_stream * src, struct memblob * dest, size_t max );
> 65
> 66
> 67 #ifdef __cplusplus
> 68 } /* extern "C" */
> 69 #endif
> 70 #endif /* _S11N_NET_C11N_STREAM_MEMBLOB_H_INCLUDED_ */

Deleted include/s11n.net/c11n/io/c11n_stream_whclob.h

Old (b57814d48905a293) New ()
1 #if !defined(_S11N_NET_C11N_STREAM_WHCLOB_H_INCLUDED_) <
2 #define _S11N_NET_C11N_STREAM_WHCLOB_H_INCLUDED_ 1 <
3 <
4 #include "c11n_io.h" <
5 #ifdef __cplusplus <
6 extern "C" { <
7 #endif <
8 <
9 /** Provided by whclob.h */ <
10 struct whclob; <
11 <
12 /** <
13 Creates a stream which uses whclob object as its i/o <
14 source/destination, thus providing an in-memory i/o buffer. The <
15 clob parameter is of type whclob, which is defined in the <
16 whclob API (see: @ref whclob_page_main). <
17 <
18 It supports both read and write modes, but be aware of the <
19 cursor semantics of the whclob API before trying to use it for <
20 both. It is safest (and most predictable) to use it for only <
21 reading or writing, not both. <
22 <
23 The returned stream object must be destroyed by calling <
24 stream->api->destroy(stream). <
25 <
26 Requirements of the clob object are: <
27 <
28 - It is owned by the caller. Calling stream->api->destroy(stream) <
29 does not modify the clob (but does destroy the stream object). <
30 <
31 - When the stream is written to, the data is appended to the current <
32 cursor position of clob, growing the clob as needed. <
33 <
34 - When the stream is read, the data is read from the current <
35 cursor position of clob. It will not, of course, read past <
36 the logical EOF. <
37 <
38 In other words: <
39 <
40 If stream->api->read() is called then the source clob must be <
41 pre-populated by the caller so that we have something to read <
42 out. That data is then copied to the stream->api->read() <
43 destination pointer. If stream->api->write() is called, the data <
44 from that source will be appended to the clob using <
45 whclob_append(). <
46 <
47 Behaviour is undefined if calls to stream->api->read(), <
48 stream->api->write(), and/or the whclob API are inter-mixed, <
49 with the exception that it is safe to use whclob_rewind() <
50 to re-set an input buffer to its begining position. <
51 <
52 When using output clob-streams to buffer any significant <
53 amount of data, it is a good idea to initialize the clob <
54 to some reasonable buffer size, e.g. using either whclob_init() <
55 or whclob_reserve(). <
56 */ <
57 c11n_stream * c11n_stream_for_whclob( struct whclob * clob ); <
58 <
59 /** <
60 Reads at most max bytes from src and appends them to dest. Returns <
61 the number of bytes read, or 0 if any arguments are 0, if 0 bytes <
62 are read, or if dest needs to grow and a re-allocation fails. <
63 */ <
64 size_t c11n_stream_buffer_read( c11n_stream * src, struct whclob * dest, size_t max ); <
65 <
66 <
67 #ifdef __cplusplus <
68 } /* extern "C" */ <
69 #endif <
70 #endif /* _S11N_NET_C11N_STREAM_WHCLOB_H_INCLUDED_ */ <

Changes to src/Makefile

Old (32cc1aaa4916df68) New (7db471d71f7f96e9)
1 #!/usr/bin/make -f 1 #!/usr/bin/make -f
2 # Requires GNU Make 3.80+! 2 # Requires GNU Make 3.80+!
3 default: all 3 default: all
4 4
5 ifeq (1,$(TCC)) 5 ifeq (1,$(TCC))
97 hidden lines
103 $(call ShakeNMake.CALL.RULES.LIBS,libwhgc) 103 $(call ShakeNMake.CALL.RULES.LIBS,libwhgc)
104 $(libwhgc.LIB): $(libwhhash.LIB) 104 $(libwhgc.LIB): $(libwhhash.LIB)
105 105
106 ######################################################################## 106 ########################################################################
107 # Clob lib 107 # Clob lib
108 WHCLOB_OBJ := whclob.o vappendf.o cencode.o cdecode.o | 108 MEMBLOB_OBJ := memblob.o vappendf.o cencode.o cdecode.o
109 libwhclob.LIB.OBJECTS = $(WHCLOB_OBJ) | 109 libmemblob.LIB.OBJECTS = $(MEMBLOB_OBJ)
110 $(call ShakeNMake.CALL.RULES.LIBS,libwhclob) | 110 $(call ShakeNMake.CALL.RULES.LIBS,libmemblob)
111 libs: $(libwhclob.LIB) | 111 libs: $(libmemblob.LIB)
112 112
113 ######################################################################## 113 ########################################################################
114 # Reference counting lib 114 # Reference counting lib
115 #WHRC_OBJ := whrc.o 115 #WHRC_OBJ := whrc.o
116 #libwhrc.LIB.OBJECTS = $(WHRC_OBJ) $(libwhhash.LIB) 116 #libwhrc.LIB.OBJECTS = $(WHRC_OBJ) $(libwhhash.LIB)
118 #libs: $(libwhrc.LIB) 118 #libs: $(libwhrc.LIB)
119 119
120 120
121 ######################################################################## 121 ########################################################################
122 # c11n lib: 122 # c11n lib:
123 libc11n.LIB.EXTRALIBS := $(libwhclob.LIB) | 123 libc11n.LIB.EXTRALIBS := $(libmemblob.LIB)
124 libc11n.LIB.EXTRAOBJ := $(libwhclob.LIB.OBJECTS) $(libwhhash.LIB.OBJECTS) | 124 libc11n.LIB.EXTRAOBJ := $(libmemblob.LIB.OBJECTS) $(libwhhash.LIB.OBJECTS)
125 # libc11n.DLL.EXTRAOBJ := $(libc11n.LIB.EXTRAOBJ) 125 # libc11n.DLL.EXTRAOBJ := $(libc11n.LIB.EXTRAOBJ)
126 # libc11n.DLL.LDFLAGS := -L. -lwhclob -L. -lwhhash | 126 # libc11n.DLL.LDFLAGS := -L. -lmemblob -L. -lwhhash
127 # $(libwhgc.LIB) $(libwhhash.LIB) 127 # $(libwhgc.LIB) $(libwhhash.LIB)
128 libc11n.LIB.OBJECTS := c11n.o c11n_io.o 128 libc11n.LIB.OBJECTS := c11n.o c11n_io.o
129 libc11n.LIB.OBJECTS += c11n_io_handler_binarish.o 129 libc11n.LIB.OBJECTS += c11n_io_handler_binarish.o
130 libc11n.LIB.OBJECTS += c11n_stream_FILE.o 130 libc11n.LIB.OBJECTS += c11n_stream_FILE.o
131 libc11n.LIB.OBJECTS += c11n_stream_whclob.o | 131 libc11n.LIB.OBJECTS += c11n_stream_memblob.o
132 libc11n.DLL.LDFLAGS += $(SQLITE3.LDFLAGS) $(EXPAT_LDFLAGS) 132 libc11n.DLL.LDFLAGS += $(SQLITE3.LDFLAGS) $(EXPAT_LDFLAGS)
133 133
134 ifeq (1,$(USE_SQLITE3)) 134 ifeq (1,$(USE_SQLITE3))
135 libc11n.LIB.OBJECTS += c11n_io_handler_sql.o 135 libc11n.LIB.OBJECTS += c11n_io_handler_sql.o
136 test.o c11n_io.o c11n_io_handler_sql.o: CPPFLAGS+=$(SQLITE3.CPPFLAGS) 136 test.o c11n_io.o c11n_io_handler_sql.o: CPPFLAGS+=$(SQLITE3.CPPFLAGS)
13 hidden lines
150 libc11n.LIB.OBJECTS += $(libc11n.LIB.EXTRALIBS) 150 libc11n.LIB.OBJECTS += $(libc11n.LIB.EXTRALIBS)
151 endif 151 endif
152 libc11n.DLL.OBJECTS := $(libc11n.LIB.OBJECTS) 152 libc11n.DLL.OBJECTS := $(libc11n.LIB.OBJECTS)
153 $(call ShakeNMake.CALL.RULES.LIBS,libc11n) 153 $(call ShakeNMake.CALL.RULES.LIBS,libc11n)
154 $(call ShakeNMake.CALL.RULES.DLLS,libc11n) 154 $(call ShakeNMake.CALL.RULES.DLLS,libc11n)
155 $(libc11n.LIB): $(libwhhash.LIB) $(libwhclob.LIB) | 155 $(libc11n.LIB): $(libwhhash.LIB) $(libmemblob.LIB)
156 $(libc11n.DLL): $(libwhhash.LIB) $(libwhclob.LIB) | 156 $(libc11n.DLL): $(libwhhash.LIB) $(libmemblob.LIB)
157 libs: $(libc11n.LIB) 157 libs: $(libc11n.LIB)
158 ifneq (1,$(TCC)) 158 ifneq (1,$(TCC))
159 libs: $(libc11n.DLL) 159 libs: $(libc11n.DLL)
160 endif 160 endif
161 161
9 hidden lines
171 bins: $(test.BIN) 171 bins: $(test.BIN)
172 bins: 172 bins:
173 173
174 scratch.o: CFLAGS += -Wno-format 174 scratch.o: CFLAGS += -Wno-format
175 scratch.BIN.LDFLAGS := $(libc11n.LIB) $(EXPAT_LDFLAGS) $(SQLITE3.LDFLAGS) 175 scratch.BIN.LDFLAGS := $(libc11n.LIB) $(EXPAT_LDFLAGS) $(SQLITE3.LDFLAGS)
176 scratch.BIN.OBJECTS := scratch.o whclob.o | 176 scratch.BIN.OBJECTS := scratch.o memblob.o
177 $(call ShakeNMake.CALL.RULES.BINS,scratch) 177 $(call ShakeNMake.CALL.RULES.BINS,scratch)
178 $(scratch.BIN): $(libc11n.LIB) 178 $(scratch.BIN): $(libc11n.LIB)
179 bins: $(scratch.BIN) 179 bins: $(scratch.BIN)
180 180
181 181
182 clobtest.o: CFLAGS += -Wno-format 182 clobtest.o: CFLAGS += -Wno-format
183 clobtest.BIN.LDFLAGS := $(libwhclob.LIB) | 183 clobtest.BIN.LDFLAGS := $(libmemblob.LIB)
184 clobtest.BIN.OBJECTS := test-clob.o 184 clobtest.BIN.OBJECTS := test-clob.o
185 $(call ShakeNMake.CALL.RULES.BINS,clobtest) 185 $(call ShakeNMake.CALL.RULES.BINS,clobtest)
186 $(clobtest.BIN): $(libwhclob.LIB) | 186 $(clobtest.BIN): $(libmemblob.LIB)
187 bins: $(clobtest.BIN) 187 bins: $(clobtest.BIN)
188 188
189 189
190 c11nconvert.BIN.LDFLAGS := $(libc11n.LIB) $(libwhgc.LIB) $(SQLITE3.LDFLAGS) $(EXPAT_LDFLAGS) 190 c11nconvert.BIN.LDFLAGS := $(libc11n.LIB) $(libwhgc.LIB) $(SQLITE3.LDFLAGS) $(EXPAT_LDFLAGS)
191 c11nconvert.BIN.OBJECTS := c11nconvert.o 191 c11nconvert.BIN.OBJECTS := c11nconvert.o
11 hidden lines
203 #$(MEGA.BIN): $(libc11n.LIB) $(libwhgc.LIB) 203 #$(MEGA.BIN): $(libc11n.LIB) $(libwhgc.LIB)
204 # tcc $(INCLUDES) -r -o $(MEGA.OBJ) $(wildcard c11n*.c wh*.c vappendf.c) 204 # tcc $(INCLUDES) -r -o $(MEGA.OBJ) $(wildcard c11n*.c wh*.c vappendf.c)
205 # tcc -o $(MEGA.BIN) $(MEGA.OBJ) $(SQLITE3.LDFLAGS) 205 # tcc -o $(MEGA.BIN) $(MEGA.OBJ) $(SQLITE3.LDFLAGS)
206 206
207 all: libs bins 207 all: libs bins

Changes to src/c11n.c

Old (b5a36e9c9e733543) New (086c5ad92b49d852)
1 /** 1 /**
2 This the main implementation file for the c11n core library. Some 2 This the main implementation file for the c11n core library. Some
3 maintenance notes: 3 maintenance notes:
4 4
5 - NO dependency on any code from the c11n_io API is allowed. 5 - NO dependency on any code from the c11n_io API is allowed.
51 hidden lines
57 57
58 See 'man feature_test_macros': 58 See 'man feature_test_macros':
59 59
60 _FORTIFY_SOURCE 60 _FORTIFY_SOURCE
61 61
62 we should add that to the whclob and whhash APIs. ??? | 62 we should add that to the memblob and whhash APIs. ???
63 63
64 */ 64 */
65 65
66 #include <stdlib.h> 66 #include <stdlib.h>
67 #include <string.h> /* strcmp() */ 67 #include <string.h> /* strcmp() */
68 68
69 #include "s11n.net/c11n/c11n.h" 69 #include "s11n.net/c11n/c11n.h"
70 //#include "whgc.h" 70 //#include "whgc.h"
71 //#include "whhash.h" 71 //#include "whhash.h"
72 #include "s11n.net/c11n/detail/whclob.h" | 72 #include "s11n.net/c11n/detail/memblob.h"
73 #include "s11n.net/c11n/detail/vappendf.h" 73 #include "s11n.net/c11n/detail/vappendf.h"
74 74
75 #ifdef __cplusplus 75 #ifdef __cplusplus
76 #define ARG_UNUSED(X) 76 #define ARG_UNUSED(X)
77 extern "C" { 77 extern "C" {
337 hidden lines
415 Maybe todo: don't implement in terms of c11n_node_prop_give_kvp() because 415 Maybe todo: don't implement in terms of c11n_node_prop_give_kvp() because
416 doing so costs us one extra copy of key when re-setting an existing 416 doing so costs us one extra copy of key when re-setting an existing
417 property. 417 property.
418 */ 418 */
419 return c11n_node_prop_give_kvp( n, c11n_copy_str(key), 419 return c11n_node_prop_give_kvp( n, c11n_copy_str(key),
420 fmt ? whclob_vmprintf( fmt, vargs ) : 0 ); | 420 fmt ? memblob_vmprintf( fmt, vargs ) : 0 );
421 } 421 }
422 422
423 bool c11n_node_prop_set_fe( c11n_node *n, c11n_key_type key, c11n_const_string_t fmt, ... ) 423 bool c11n_node_prop_set_fe( c11n_node *n, c11n_key_type key, c11n_const_string_t fmt, ... )
424 { 424 {
425 va_list vargs; 425 va_list vargs;
639 hidden lines
1065 } 1065 }
1066 1066
1067 bool c11n_serialize_binary( c11n_node * dest, void const * src, size_t sizeOf ) 1067 bool c11n_serialize_binary( c11n_node * dest, void const * src, size_t sizeOf )
1068 { 1068 {
1069 if( ! dest || !src || !sizeOf ) return false; 1069 if( ! dest || !src || !sizeOf ) return false;
1070 whclob * buf = whclob_new_n( sizeOf ); | 1070 memblob * buf = memblob_new_n( sizeOf );
1071 if( ! buf ) return false; 1071 if( ! buf ) return false;
1072 whclob_append( buf, src, sizeOf ); | 1072 memblob_append( buf, src, sizeOf );
1073 whclob_base64_enc( buf, buf ); | 1073 memblob_base64_enc( buf, buf );
1074 c11n_node_prop_set_fe( dest, "size", "%u", sizeOf ); 1074 c11n_node_prop_set_fe( dest, "size", "%u", sizeOf );
1075 c11n_string_t key = c11n_copy_str( "base64" ); 1075 c11n_string_t key = c11n_copy_str( "base64" );
1076 char * val = whclob_take_buffer( buf ); | 1076 char * val = memblob_take_buffer( buf );
1077 if( ! c11n_node_prop_give_kvp( dest, key, val ) ) 1077 if( ! c11n_node_prop_give_kvp( dest, key, val ) )
1078 { 1078 {
1079 free(key); 1079 free(key);
1080 free(val); 1080 free(val);
1081 } 1081 }
1082 whclob_finalize( buf ); | 1082 memblob_finalize( buf );
1083 return true; 1083 return true;
1084 } 1084 }
1085 1085
1086 bool c11n_deserialize_binary( c11n_node const * src, c11n_binary_data * dest ) 1086 bool c11n_deserialize_binary( c11n_node const * src, c11n_binary_data * dest )
1087 { 1087 {
6 hidden lines
1094 c11n_const_string_t val = 0; 1094 c11n_const_string_t val = 0;
1095 if( ! c11n_node_prop_get( src, "base64", &val ) || !val ) return false; 1095 if( ! c11n_node_prop_get( src, "base64", &val ) || !val ) return false;
1096 dest->data = malloc(sz); 1096 dest->data = malloc(sz);
1097 if( ! dest->data ) return false; 1097 if( ! dest->data ) return false;
1098 memset( dest->data, 0, sz ); 1098 memset( dest->data, 0, sz );
1099 whclob * cb = whclob_new(); | 1099 memblob * cb = memblob_new();
1100 whclob_append( cb, val, -1 ); | 1100 memblob_append( cb, val, -1 );
1101 //MARKER("whclob_size(cb) ==%ld, strlen(val)=%d val=[%s]\n",whclob_size(cb),strlen(val),val); | 1101 //MARKER("memblob_size(cb) ==%ld, strlen(val)=%d val=[%s]\n",memblob_size(cb),strlen(val),val);
1102 bool rc = true; 1102 bool rc = true;
1103 if( ! cb ) 1103 if( ! cb )
1104 { 1104 {
1105 rc = false; 1105 rc = false;
1106 free( dest->data ); 1106 free( dest->data );
1107 dest->data = 0; 1107 dest->data = 0;
1108 } 1108 }
1109 else 1109 else
1110 { 1110 {
1111 whclob_base64_dec( cb, cb ); | 1111 memblob_base64_dec( cb, cb );
1112 if( (size_t)whclob_size(cb) != sz ) | 1112 if( (size_t)memblob_size(cb) != sz )
1113 { 1113 {
1114 rc = false; 1114 rc = false;
1115 C11N_LOG(C11N_LOG_ERROR)("Declared size of data (%u) is not the same as the decoded size (%ld)", 1115 C11N_LOG(C11N_LOG_ERROR)("Declared size of data (%u) is not the same as the decoded size (%ld)",
1116 sz, whclob_size(cb)); | 1116 sz, memblob_size(cb));
1117 } 1117 }
1118 else 1118 else
1119 { 1119 {
1120 memcpy( dest->data, whclob_bufferc(cb), sz ); | 1120 memcpy( dest->data, memblob_bufferc(cb), sz );
1121 } 1121 }
1122 } 1122 }
1123 whclob_finalize( cb ); | 1123 memblob_finalize( cb );
1124 return rc; 1124 return rc;
1125 } 1125 }
1126 1126
1127 1127
1128 1128
373 hidden lines
1502 #undef C11N_MARSHALLER_INIT 1502 #undef C11N_MARSHALLER_INIT
1503 #undef C11N_MARSHALLER_API_DEFAULT 1503 #undef C11N_MARSHALLER_API_DEFAULT
1504 #ifdef __cplusplus 1504 #ifdef __cplusplus
1505 } /* extern "C" */ 1505 } /* extern "C" */
1506 #endif 1506 #endif

Changes to src/c11n_io.c

Old (05c59b17a65104d1) New (0ffdba378af16ac7)
1 #ifndef _FILE_OFFSET_BITS 1 #ifndef _FILE_OFFSET_BITS
2 /** See 'man feature_test_macros' on a gcc system */ 2 /** See 'man feature_test_macros' on a gcc system */
3 # define _FILE_OFFSET_BITS 64 3 # define _FILE_OFFSET_BITS 64
4 #endif 4 #endif
5 #ifndef _ISOC99_SOURCE 5 #ifndef _ISOC99_SOURCE
12 hidden lines
18 #include <string.h> /* strlen() */ 18 #include <string.h> /* strlen() */
19 #include <ctype.h> /* isspace() and friends. */ 19 #include <ctype.h> /* isspace() and friends. */
20 #include <stddef.h> /* size_t */ 20 #include <stddef.h> /* size_t */
21 21
22 #include "s11n.net/c11n/io/c11n_io.h" 22 #include "s11n.net/c11n/io/c11n_io.h"
23 #include "s11n.net/c11n/detail/whclob.h" | 23 #include "s11n.net/c11n/detail/memblob.h"
24 #include "s11n.net/c11n/detail/vappendf.h" 24 #include "s11n.net/c11n/detail/vappendf.h"
25 25
26 #ifdef __cplusplus 26 #ifdef __cplusplus
27 #define ARG_UNUSED(X) 27 #define ARG_UNUSED(X)
28 extern "C" { 28 extern "C" {
277 hidden lines
306 306
307 307
308 c11n_node * c11n_load_node( c11n_stream * src ) 308 c11n_node * c11n_load_node( c11n_stream * src )
309 { 309 {
310 if( ! src ) return 0; 310 if( ! src ) return 0;
311 whclob * cb = 0; | 311 memblob * cb = 0;
312 whclob_init( &cb, 0, 80 ); | 312 memblob_init( &cb, 0, 80 );
313 char ch; 313 char ch;
314 while( c11n_stream_getchar( src, &ch ) ) 314 while( c11n_stream_getchar( src, &ch ) )
315 { 315 {
316 if( (ch < 32) || (ch>=127) ) 316 if( (ch < 32) || (ch>=127) )
317 { 317 {
318 break; 318 break;
319 } 319 }
320 whclob_append( cb, &ch, 1 ); | 320 memblob_append( cb, &ch, 1 );
321 } 321 }
322 char const * cookie = whclob_bufferc(cb); | 322 char const * cookie = memblob_bufferc(cb);
323 //MARKER("cookie=[%s]\n",cookie); 323 //MARKER("cookie=[%s]\n",cookie);
324 if( ! cookie || (whclob_size(cb)<1) ) | 324 if( ! cookie || (memblob_size(cb)<1) )
325 { 325 {
326 whclob_finalize(cb); | 326 memblob_finalize(cb);
327 return 0; 327 return 0;
328 } 328 }
329 c11n_node * n = 0; 329 c11n_node * n = 0;
330 c11n_io_handler * h = c11n_io_handler_by_name(cookie); 330 c11n_io_handler * h = c11n_io_handler_by_name(cookie);
331 whclob_finalize(cb); | 331 memblob_finalize(cb);
332 if( h ) 332 if( h )
333 { 333 {
334 n = h->api->load_node( h, src ); 334 n = h->api->load_node( h, src );
335 //MARKER("h->load_node() == %p\n",n); 335 //MARKER("h->load_node() == %p\n",n);
336 h->api->destroy(h); 336 h->api->destroy(h);
59 hidden lines
396 396
397 397
398 size_t c11n_io_escape_string( c11n_const_string_t input, size_t inlen, 398 size_t c11n_io_escape_string( c11n_const_string_t input, size_t inlen,
399 c11n_string_escape_info const * table, 399 c11n_string_escape_info const * table,
400 bool doEscape, 400 bool doEscape,
401 whclob * target ) | 401 memblob * target )
402 { 402 {
403 c11n_const_string_t at = input; 403 c11n_const_string_t at = input;
404 size_t count = 0; 404 size_t count = 0;
405 if( ! input || !*input || !inlen || ! table || !target ) return 0; 405 if( ! input || !*input || !inlen || ! table || !target ) return 0;
406 c11n_string_escape_info bogo; /* simplifies unescaping. */ 406 c11n_string_escape_info bogo; /* simplifies unescaping. */
11 hidden lines
418 bogo.esc = e->unesc; 418 bogo.esc = e->unesc;
419 bogo.esc_len = e->unesc_len; 419 bogo.esc_len = e->unesc_len;
420 } 420 }
421 if( bogo.unesc_len && (0 == strncmp( at, bogo.unesc, bogo.unesc_len )) ) 421 if( bogo.unesc_len && (0 == strncmp( at, bogo.unesc, bogo.unesc_len )) )
422 { 422 {
423 whclob_append( target, bogo.esc, (long) bogo.esc_len ); | 423 memblob_append( target, bogo.esc, (long) bogo.esc_len );
424 at += bogo.unesc_len; 424 at += bogo.unesc_len;
425 ++count; 425 ++count;
426 gotmatch = true; 426 gotmatch = true;
427 break; 427 break;
428 } 428 }
429 } 429 }
430 if( ! gotmatch ) 430 if( ! gotmatch )
431 { 431 {
432 whclob_append( target, at++, 1 ); | 432 memblob_append( target, at++, 1 );
433 } 433 }
434 } 434 }
435 return count; 435 return count;
436 } 436 }
437 437
438 438
439 size_t c11n_stream_readln_membuf(c11n_stream * stream, whclob * dest ) | 439 size_t c11n_stream_readln_membuf(c11n_stream * stream, memblob * dest )
440 { 440 {
441 if( !stream || !dest || !stream->api->isgood(stream)) return 0; 441 if( !stream || !dest || !stream->api->isgood(stream)) return 0;
442 char ch = 0; 442 char ch = 0;
443 size_t ret = 0; 443 size_t ret = 0;
444 while( '\n' != ch ) 444 while( '\n' != ch )
446 if( ! c11n_stream_getchar( stream, &ch ) ) 446 if( ! c11n_stream_getchar( stream, &ch ) )
447 { 447 {
448 return 0; 448 return 0;
449 } 449 }
450 ++ret; 450 ++ret;
451 whclob_append( dest, &ch, 1 ); | 451 memblob_append( dest, &ch, 1 );
452 } 452 }
453 return ret; 453 return ret;
454 } 454 }
455 455
456 char * c11n_stream_readln(c11n_stream * stream) 456 char * c11n_stream_readln(c11n_stream * stream)
457 { 457 {
458 if(0) c11n_stream_readln(0); /* kludge for "static defined but not used" warning. */ 458 if(0) c11n_stream_readln(0); /* kludge for "static defined but not used" warning. */
459 if( !stream || !stream->api->isgood(stream)) return 0; 459 if( !stream || !stream->api->isgood(stream)) return 0;
460 whclob * cb = whclob_new(); | 460 memblob * cb = memblob_new();
461 c11n_stream_readln_membuf( stream, cb ); 461 c11n_stream_readln_membuf( stream, cb );
462 char * buf = whclob_take_buffer(cb); | 462 char * buf = memblob_take_buffer(cb);
463 whclob_finalize(cb); | 463 memblob_finalize(cb);
464 return buf; 464 return buf;
465 } 465 }
466 466
467 #ifdef __cplusplus 467 #ifdef __cplusplus
468 } /* extern "C" */ 468 } /* extern "C" */
469 #endif 469 #endif

Changes to src/c11n_io_handler_binarish.c

Old (253bb514b07d1350) New (55e9331e47b86198)
1 #include "s11n.net/c11n/io/c11n_io.h" 1 #include "s11n.net/c11n/io/c11n_io.h"
2 #include "s11n.net/c11n/detail/whclob.h" | 2 #include "s11n.net/c11n/detail/memblob.h"
3 3
4 #include <stdlib.h> 4 #include <stdlib.h>
5 #include <ctype.h> /* isspace() and friends. */ 5 #include <ctype.h> /* isspace() and friends. */
6 #include <string.h> /* memset() */ 6 #include <string.h> /* memset() */
7 #include <assert.h> 7 #include <assert.h>
102 hidden lines
110 c11n_stream * stream; 110 c11n_stream * stream;
111 /** 111 /**
112 Blob for accumulating read-in tokens. Owned by 112 Blob for accumulating read-in tokens. Owned by
113 this object. 113 this object.
114 */ 114 */
115 whclob * clob; | 115 memblob * clob;
116 } c11n_io_binarish_data; 116 } c11n_io_binarish_data;
117 117
118 static const c11n_io_binarish_data c11n_io_binarish_data_init = 118 static const c11n_io_binarish_data c11n_io_binarish_data_init =
119 { 119 {
120 C11N_IO_TREE_BUILDER_INIT, 120 C11N_IO_TREE_BUILDER_INIT,
129 hidden lines
250 if(0) return binarish_save_root_node(self,src,dest);/* kludge to avoid "static func defined but not used" warning*/ 250 if(0) return binarish_save_root_node(self,src,dest);/* kludge to avoid "static func defined but not used" warning*/
251 impl->stream = dest; 251 impl->stream = dest;
252 #define WF c11n_stream_writef 252 #define WF c11n_stream_writef
253 #define LEN(S) c11n_strlen(S) 253 #define LEN(S) c11n_strlen(S)
254 254
255 whclob_finalize( impl->clob ); | 255 memblob_finalize( impl->clob );
256 impl->clob = whclob_new(); | 256 impl->clob = memblob_new();
257 257
258 WF( dest, "%s\n", self->api->cookie_string ); 258 WF( dest, "%s\n", self->api->cookie_string );
259 259
260 bool ret = binarish_save_node( self, src ); 260 bool ret = binarish_save_node( self, src );
261 if( ret ) 261 if( ret )
262 { 262 {
263 263
264 WF( dest, "%s\n", impl->cookie_close ); 264 WF( dest, "%s\n", impl->cookie_close );
265 } 265 }
266 whclob_finalize( impl->clob ); | 266 memblob_finalize( impl->clob );
267 impl->clob = 0; 267 impl->clob = 0;
268 impl->stream = 0; 268 impl->stream = 0;
269 #undef LEN 269 #undef LEN
270 #undef WF 270 #undef WF
271 return ret; 271 return ret;
26 hidden lines
298 { 298 {
299 IMPLDECL(false); 299 IMPLDECL(false);
300 if( !self || (0 == size) ) return false; 300 if( !self || (0 == size) ) return false;
301 #if 1 301 #if 1
302 /* 302 /*
303 This requires much fewer allocs than whclob_reset(), though it | 303 This requires much fewer allocs than memblob_reset(), though it
304 also means that impl->clob will stay the size of the largest 304 also means that impl->clob will stay the size of the largest
305 token throughout the parse process. 305 token throughout the parse process.
306 */ 306 */
307 whclob_reserve( impl->clob, size ? size : 1 ); | 307 memblob_reserve( impl->clob, size ? size : 1 );
308 whclob_truncate( impl->clob, 0, 0 ); | 308 memblob_truncate( impl->clob, 0, 0 );
309 #else 309 #else
310 whclob_reset(impl->clob); | 310 memblob_reset(impl->clob);
311 whclob_reserve( impl->clob, size ); | 311 memblob_reserve( impl->clob, size );
312 #endif 312 #endif
313 char * buf = whclob_buffer(impl->clob); | 313 char * buf = memblob_buffer(impl->clob);
314 if( skipWS ) 314 if( skipWS )
315 { 315 {
316 char ch = binarish_read_skip_space( impl->stream ); 316 char ch = binarish_read_skip_space( impl->stream );
317 if( ! ch ) 317 if( ! ch )
318 { 318 {
319 C11N_LOG(C11N_LOG_IO_ERR)("hit EOF while expecting a length-%u token",size); 319 C11N_LOG(C11N_LOG_IO_ERR)("hit EOF while expecting a length-%u token",size);
320 return false; 320 return false;
321 } 321 }
322 whclob_append( impl->clob, &ch, 1 ); | 322 memblob_append( impl->clob, &ch, 1 );
323 if( 1 == size ) return true; 323 if( 1 == size ) return true;
324 --size; 324 --size;
325 buf += 1; 325 buf += 1;
326 } 326 }
327 if( size != impl->stream->api->read(impl->stream, buf, size ) ) 327 if( size != impl->stream->api->read(impl->stream, buf, size ) )
8 hidden lines
336 */ 336 */
337 static bool binarish_compare_token(c11n_io_handler * self, c11n_key_type key, bool skipWS ) 337 static bool binarish_compare_token(c11n_io_handler * self, c11n_key_type key, bool skipWS )
338 { 338 {
339 IMPLDECL(false); 339 IMPLDECL(false);
340 return binarish_read_token( self, c11n_strlen(key),skipWS ) 340 return binarish_read_token( self, c11n_strlen(key),skipWS )
341 ? c11n_compare_str( key, whclob_bufferc(impl->clob) ) | 341 ? c11n_compare_str( key, memblob_bufferc(impl->clob) )
342 : false; 342 : false;
343 } 343 }
344 344
345 static int binarish_read_size_token( c11n_io_handler * self, size_t sizeLen ) 345 static int binarish_read_size_token( c11n_io_handler * self, size_t sizeLen )
346 { 346 {
347 IMPLDECL(-1); 347 IMPLDECL(-1);
348 if( ! self || !sizeLen ) return false; 348 if( ! self || !sizeLen ) return false;
349 if( ! binarish_read_token(self,sizeLen,false) ) return false; 349 if( ! binarish_read_token(self,sizeLen,false) ) return false;
350 char const * digits = whclob_bufferc(impl->clob); | 350 char const * digits = memblob_bufferc(impl->clob);
351 int num = -1; 351 int num = -1;
352 char fmt[10]; memset(fmt,0,10); 352 char fmt[10]; memset(fmt,0,10);
353 sprintf( fmt, "%%%ux", sizeLen ); 353 sprintf( fmt, "%%%ux", sizeLen );
354 if( 1 != sscanf( digits, fmt, &num) ) return -1; 354 if( 1 != sscanf( digits, fmt, &num) ) return -1;
355 return num; 355 return num;
4 hidden lines
360 if( -1 == rdlen ) return false; 360 if( -1 == rdlen ) return false;
361 //MARKER("rdlen=%d/%x\n",rdlen,rdlen); 361 //MARKER("rdlen=%d/%x\n",rdlen,rdlen);
362 return binarish_read_token( self, rdlen, false ); 362 return binarish_read_token( self, rdlen, false );
363 } 363 }
364 364
365 #define TOKEN whclob_bufferc(impl->clob) | 365 #define TOKEN memblob_bufferc(impl->clob)
366 #define SHOWTOKEN if(0){MARKER("token=[%s]\n",TOKEN);} 366 #define SHOWTOKEN if(0){MARKER("token=[%s]\n",TOKEN);}
367 367
368 static bool binarish_read_prop( c11n_io_handler * self ) 368 static bool binarish_read_prop( c11n_io_handler * self )
369 { 369 {
370 IMPLDECL(false); 370 IMPLDECL(false);
371 if( ! binarish_read_sized_token( self, impl->keySizeLen ) ) return false; 371 if( ! binarish_read_sized_token( self, impl->keySizeLen ) ) return false;
372 SHOWTOKEN; 372 SHOWTOKEN;
373 /* 373 /*
374 FIXME: add this whclob as a member of impl, to avoid having to | 374 FIXME: add this memblob as a member of impl, to avoid having to
375 re-alloc it (and its internals) for every property. 375 re-alloc it (and its internals) for every property.
376 */ 376 */
377 whclob * key = 0; | 377 memblob * key = 0;
378 if( whclob_rc.OK != whclob_init(&key,TOKEN,-1) ) return false; | 378 if( memblob_rc.OK != memblob_init(&key,TOKEN,-1) ) return false;
379 if( ! binarish_read_sized_token( self, impl->valSizeLen ) ) 379 if( ! binarish_read_sized_token( self, impl->valSizeLen ) )
380 { 380 {
381 SHOWTOKEN; 381 SHOWTOKEN;
382 whclob_finalize(key); | 382 memblob_finalize(key);
383 return false; 383 return false;
384 } 384 }
385 impl->bld.set_prop( &impl->bld, whclob_bufferc(key), TOKEN ); | 385 impl->bld.set_prop( &impl->bld, memblob_bufferc(key), TOKEN );
386 SHOWTOKEN; 386 SHOWTOKEN;
387 whclob_finalize(key); | 387 memblob_finalize(key);
388 return true; 388 return true;
389 389
390 } 390 }
391 // bool binarish_read_kvp( c11n_io_handler *, 391 // bool binarish_read_kvp( c11n_io_handler *,
392 static bool binarish_load_a_node( c11n_io_handler * self, bool requireOpener ) 392 static bool binarish_load_a_node( c11n_io_handler * self, bool requireOpener )
66 hidden lines
459 459
460 static c11n_node * binarish_load_root_node( c11n_io_handler * self, c11n_stream * src ) 460 static c11n_node * binarish_load_root_node( c11n_io_handler * self, c11n_stream * src )
461 { 461 {
462 IMPLDECL(0); 462 IMPLDECL(0);
463 impl->stream = src; 463 impl->stream = src;
464 whclob_finalize( impl->clob ); | 464 memblob_finalize( impl->clob );
465 impl->clob = whclob_new(); | 465 impl->clob = memblob_new();
466 c11n_node * ret = 0; 466 c11n_node * ret = 0;
467 if( binarish_load_start( self ) ) 467 if( binarish_load_start( self ) )
468 { 468 {
469 ret = impl->bld.root_node; 469 ret = impl->bld.root_node;
470 impl->bld.root_node = 0; 470 impl->bld.root_node = 0;
471 } 471 }
472 impl->bld.clear( &impl->bld ); 472 impl->bld.clear( &impl->bld );
473 whclob_finalize( impl->clob ); | 473 memblob_finalize( impl->clob );
474 impl->clob = 0; 474 impl->clob = 0;
475 impl->stream = 0; 475 impl->stream = 0;
476 return ret; 476 return ret;
477 } 477 }
478 static void binarish_clear( c11n_io_handler * self ) 478 static void binarish_clear( c11n_io_handler * self )
480 if( self ) 480 if( self )
481 { 481 {
482 IMPLDECL(); 482 IMPLDECL();
483 if( impl->clob) 483 if( impl->clob)
484 { 484 {
485 whclob_finalize(impl->clob); | 485 memblob_finalize(impl->clob);
486 impl->clob = 0; 486 impl->clob = 0;
487 } 487 }
488 impl->stream = 0; 488 impl->stream = 0;
489 impl->bld.clear( &impl->bld ); 489 impl->bld.clear( &impl->bld );
490 } 490 }
41 hidden lines
532 532
533 c11n_io_handler * c11n_io_handler_factory_binarish( c11n_const_string_t ignored ) 533 c11n_io_handler * c11n_io_handler_factory_binarish( c11n_const_string_t ignored )
534 { 534 {
535 return c11n_io_handler_create_binarish(); 535 return c11n_io_handler_create_binarish();
536 } 536 }

Changes to src/c11n_io_handler_expat.c

Old (735eeeee89d7518e) New (8c2659da55349183)
1 #include "s11n.net/c11n/io/c11n_io.h" 1 #include "s11n.net/c11n/io/c11n_io.h"
2 #include "s11n.net/c11n/io/c11n_io_handler_expat.h" 2 #include "s11n.net/c11n/io/c11n_io_handler_expat.h"
3 #include "s11n.net/c11n/detail/whclob.h" | 3 #include "s11n.net/c11n/detail/memblob.h"
4 4
5 #include <stdlib.h> 5 #include <stdlib.h>
6 #include <ctype.h> /* isspace() and friends. */ 6 #include <ctype.h> /* isspace() and friends. */
7 #include <string.h> /* memset() */ 7 #include <string.h> /* memset() */
8 #include <assert.h> 8 #include <assert.h>
20 hidden lines
29 c11n_stream * stream; 29 c11n_stream * stream;
30 /** 30 /**
31 Blob for accumulating read-in tokens. Owned by 31 Blob for accumulating read-in tokens. Owned by
32 this object. 32 this object.
33 */ 33 */
34 whclob * clob; | 34 memblob * clob;
35 whclob * tabs; | 35 memblob * tabs;
36 whclob * xlate; | 36 memblob * xlate;
37 XML_Parser expat; 37 XML_Parser expat;
38 } c11n_io_expat_data; 38 } c11n_io_expat_data;
39 39
40 static const c11n_io_expat_data c11n_io_expat_data_init = 40 static const c11n_io_expat_data c11n_io_expat_data_init =
41 { 41 {
47 hidden lines
89 #define WF c11n_stream_writef 89 #define WF c11n_stream_writef
90 c11n_stream * dest = impl->stream; 90 c11n_stream * dest = impl->stream;
91 91
92 if( impl->indentLevel++ != 0 ) 92 if( impl->indentLevel++ != 0 )
93 { 93 {
94 whclob_append( impl->tabs, "\t", 1 ); | 94 memblob_append( impl->tabs, "\t", 1 );
95 //whclob_null_terminate( impl->tabs ); | 95 //memblob_null_terminate( impl->tabs );
96 } 96 }
97 char const * tabs = whclob_bufferc( impl->tabs ); | 97 char const * tabs = memblob_bufferc( impl->tabs );
98 if( ! tabs || !*tabs ) tabs = ""; 98 if( ! tabs || !*tabs ) tabs = "";
99 99
100 WF( dest, "%s<%s class=\"%s\">\n", tabs, c11n_node_get_name( src ), c11n_node_get_class(src) ); 100 WF( dest, "%s<%s class=\"%s\">\n", tabs, c11n_node_get_name( src ), c11n_node_get_class(src) );
101 #if 1 101 #if 1
102 c11n_prop_iter piter = c11n_node_prop_iter(src); 102 c11n_prop_iter piter = c11n_node_prop_iter(src);
103 while( c11n_prop_iter_isvalid( &piter ) ) 103 while( c11n_prop_iter_isvalid( &piter ) )
104 { 104 {
105 c11n_const_string_t key = c11n_prop_iter_key( &piter ); 105 c11n_const_string_t key = c11n_prop_iter_key( &piter );
106 c11n_const_string_t val = c11n_prop_iter_val( &piter ); 106 c11n_const_string_t val = c11n_prop_iter_val( &piter );
107 whclob_truncate( impl->xlate, 0, 0 ); | 107 memblob_truncate( impl->xlate, 0, 0 );
108 if( val ) 108 if( val )
109 { 109 {
110 c11n_io_escape_string( val, c11n_strlen( val ), expat_val_escapes, true, impl->xlate ); 110 c11n_io_escape_string( val, c11n_strlen( val ), expat_val_escapes, true, impl->xlate );
111 } 111 }
112 WF( dest, "\t%s<%s>%s</%s>\n", tabs, key, 112 WF( dest, "\t%s<%s>%s</%s>\n", tabs, key,
113 whclob_size(impl->xlate) ? whclob_bufferc(impl->xlate) : "", | 113 memblob_size(impl->xlate) ? memblob_bufferc(impl->xlate) : "",
114 key ); 114 key );
115 c11n_prop_iter_next(&piter); 115 c11n_prop_iter_next(&piter);
116 } 116 }
117 #endif 117 #endif
118 #if 1 118 #if 1
3 hidden lines
122 if( ! expat_save_node( self, chi.node ) ) return false; 122 if( ! expat_save_node( self, chi.node ) ) return false;
123 c11n_node_iter_next_c(&chi); 123 c11n_node_iter_next_c(&chi);
124 } 124 }
125 #endif 125 #endif
126 --impl->indentLevel; 126 --impl->indentLevel;
127 whclob_truncate( impl->tabs, impl->indentLevel, 0 ); | 127 memblob_truncate( impl->tabs, impl->indentLevel, 0 );
128 WF( dest, "%s</%s>\n", tabs, c11n_node_get_name( src ) ); 128 WF( dest, "%s</%s>\n", tabs, c11n_node_get_name( src ) );
129 #undef WF 129 #undef WF
130 #undef W 130 #undef W
131 //whclob_null_terminate( impl->tabs ); | 131 //memblob_null_terminate( impl->tabs );
132 return true; 132 return true;
133 } 133 }
134 134
135 static bool expat_save_root_node( c11n_io_handler * self, 135 static bool expat_save_root_node( c11n_io_handler * self,
136 c11n_node const * src, 136 c11n_node const * src,
2 hidden lines
139 IMPLDECL(false); 139 IMPLDECL(false);
140 if( !src || (!dest || !dest->api->isgood(dest)) ) return false; 140 if( !src || (!dest || !dest->api->isgood(dest)) ) return false;
141 if(0) return expat_save_root_node(self,src,dest);/* kludge to avoid "static func defined but not used" warning*/ 141 if(0) return expat_save_root_node(self,src,dest);/* kludge to avoid "static func defined but not used" warning*/
142 self->api->clear(self); 142 self->api->clear(self);
143 impl->stream = dest; 143 impl->stream = dest;
144 impl->tabs = whclob_new(); | 144 impl->tabs = memblob_new();
145 impl->xlate = whclob_new(); | 145 impl->xlate = memblob_new();
146 c11n_stream_writef( dest, "%s\n", self->api->cookie_string ); 146 c11n_stream_writef( dest, "%s\n", self->api->cookie_string );
147 bool ret = expat_save_node( self, src ); 147 bool ret = expat_save_node( self, src );
148 self->api->clear(self); 148 self->api->clear(self);
149 return ret; 149 return ret;
150 } 150 }
2 hidden lines
153 #define XSELFDECL c11n_io_expat_data * impl = (c11n_io_expat_data *)uArg; assert(impl && "impl failed!"); if(!impl) return 153 #define XSELFDECL c11n_io_expat_data * impl = (c11n_io_expat_data *)uArg; assert(impl && "impl failed!"); if(!impl) return
154 154
155 static void XMLCALL expat_start_node( void * uArg, const char * name, const char ** attr ) 155 static void XMLCALL expat_start_node( void * uArg, const char * name, const char ** attr )
156 { 156 {
157 XSELFDECL; 157 XSELFDECL;
158 //whclob_truncate(impl->clob, 0, 0 ); | 158 //memblob_truncate(impl->clob, 0, 0 );
159 if( attr[0] ) 159 if( attr[0] )
160 { /* object node */ 160 { /* object node */
161 impl->propKey = 0; 161 impl->propKey = 0;
162 c11n_const_string_t cln = 0; 162 c11n_const_string_t cln = 0;
163 int i = 0; 163 int i = 0;
20 hidden lines
184 { /* object node */ 184 { /* object node */
185 impl->bld.close_node( &impl->bld ); 185 impl->bld.close_node( &impl->bld );
186 } 186 }
187 else 187 else
188 { /* property node */ 188 { /* property node */
189 whclob_null_terminate( impl->clob ); | 189 memblob_null_terminate( impl->clob );
190 impl->bld.set_prop( &impl->bld, impl->propKey, whclob_bufferc(impl->clob) ); | 190 impl->bld.set_prop( &impl->bld, impl->propKey, memblob_bufferc(impl->clob) );
191 impl->propKey = 0; 191 impl->propKey = 0;
192 whclob_truncate( impl->clob, 0, 0 ); | 192 memblob_truncate( impl->clob, 0, 0 );
193 } 193 }
194 } 194 }
195 195
196 static void XMLCALL expat_char_handler( void * uArg, const char * txt, int len ) 196 static void XMLCALL expat_char_handler( void * uArg, const char * txt, int len )
197 { 197 {
198 XSELFDECL; 198 XSELFDECL;
199 if( ! impl->propKey ) return; /* we're not in a property. */ 199 if( ! impl->propKey ) return; /* we're not in a property. */
200 whclob_append( impl->clob, txt, len ); | 200 memblob_append( impl->clob, txt, len );
201 } 201 }
202 202
203 static bool expat_load_a_node( c11n_io_handler * self ) 203 static bool expat_load_a_node( c11n_io_handler * self )
204 { 204 {
205 IMPLDECL(false); 205 IMPLDECL(false);
206 206
207 char * line = 0; 207 char * line = 0;
208 whclob * lineBuf = whclob_new(); | 208 memblob * lineBuf = memblob_new();
209 while( true ) 209 while( true )
210 { 210 {
211 size_t len = c11n_stream_readln_membuf( impl->stream, lineBuf ); 211 size_t len = c11n_stream_readln_membuf( impl->stream, lineBuf );
212 if( XML_STATUS_ERROR == XML_Parse( impl->expat, whclob_bufferc(lineBuf), len, (len == 0) ) ) | 212 if( XML_STATUS_ERROR == XML_Parse( impl->expat, memblob_bufferc(lineBuf), len, (len == 0) ) )
213 { 213 {
214 C11N_LOG(C11N_LOG_IO_ERR)("Parse error at line %d: %s: buffer=[%s]", 214 C11N_LOG(C11N_LOG_IO_ERR)("Parse error at line %d: %s: buffer=[%s]",
215 XML_GetCurrentLineNumber(impl->expat), 215 XML_GetCurrentLineNumber(impl->expat),
216 XML_ErrorString(XML_GetErrorCode(impl->expat)), 216 XML_ErrorString(XML_GetErrorCode(impl->expat)),
217 line ); 217 line );
218 break; 218 break;
219 } 219 }
220 whclob_truncate( lineBuf, 0, 0 ); | 220 memblob_truncate( lineBuf, 0, 0 );
221 if( !len ) break; 221 if( !len ) break;
222 } 222 }
223 whclob_finalize( lineBuf ); | 223 memblob_finalize( lineBuf );
224 return impl->bld.root_node && !impl->bld.current_node; 224 return impl->bld.root_node && !impl->bld.current_node;
225 } 225 }
226 226
227 static c11n_node * expat_load_root_node( c11n_io_handler * self, c11n_stream * src ) 227 static c11n_node * expat_load_root_node( c11n_io_handler * self, c11n_stream * src )
228 { 228 {
229 IMPLDECL(0); 229 IMPLDECL(0);
230 c11n_node * ret = 0; 230 c11n_node * ret = 0;
231 231
232 impl->expat = XML_ParserCreate(NULL); 232 impl->expat = XML_ParserCreate(NULL);
233 if( ! impl->expat ) return 0; 233 if( ! impl->expat ) return 0;
234 impl->clob = whclob_new(); | 234 impl->clob = memblob_new();
235 impl->xlate = whclob_new(); | 235 impl->xlate = memblob_new();
236 236
237 XML_SetUserData( impl->expat, impl ); 237 XML_SetUserData( impl->expat, impl );
238 XML_SetElementHandler( impl->expat, expat_start_node, expat_end_node); 238 XML_SetElementHandler( impl->expat, expat_start_node, expat_end_node);
239 XML_SetCharacterDataHandler( impl->expat, expat_char_handler ); 239 XML_SetCharacterDataHandler( impl->expat, expat_char_handler );
240 240
12 hidden lines
253 { 253 {
254 if( self ) 254 if( self )
255 { 255 {
256 IMPLDECL(); 256 IMPLDECL();
257 if( impl->expat ) XML_ParserFree( impl->expat ); 257 if( impl->expat ) XML_ParserFree( impl->expat );
258 whclob_finalize(impl->clob); | 258 memblob_finalize(impl->clob);
259 whclob_finalize(impl->tabs); | 259 memblob_finalize(impl->tabs);
260 whclob_finalize(impl->xlate); | 260 memblob_finalize(impl->xlate);
261 impl->bld.clear( &impl->bld ); 261 impl->bld.clear( &impl->bld );
262 *impl = c11n_io_expat_data_init; 262 *impl = c11n_io_expat_data_init;
263 } 263 }
264 } 264 }
265 static void expat_dtor( c11n_io_handler * self ) 265 static void expat_dtor( c11n_io_handler * self )
37 hidden lines
303 303
304 c11n_io_handler * c11n_io_handler_factory_expat( c11n_const_string_t ignored ) 304 c11n_io_handler * c11n_io_handler_factory_expat( c11n_const_string_t ignored )
305 { 305 {
306 return c11n_io_handler_create_expat(); 306 return c11n_io_handler_create_expat();
307 } 307 }

Changes to src/c11n_io_handler_sql.c

Old (f6ec0e47e47cda19) New (33a14a2c8b91e5ba)
1 #include <stdlib.h> /* malloc()/free() */ 1 #include <stdlib.h> /* malloc()/free() */
2 #include <sqlite3.h> 2 #include <sqlite3.h>
3 #include <assert.h> 3 #include <assert.h>
4 #include "s11n.net/c11n/io/c11n_io_handler_sql.h" 4 #include "s11n.net/c11n/io/c11n_io_handler_sql.h"
5 #include "s11n.net/c11n/io/c11n_stream_whclob.h" | 5 #include "s11n.net/c11n/io/c11n_stream_memblob.h"
6 #include "s11n.net/c11n/detail/whclob.h" | 6 #include "s11n.net/c11n/detail/memblob.h"
7 #include "s11n.net/c11n/detail/whhash.h" 7 #include "s11n.net/c11n/detail/whhash.h"
8 8
9 #if 1 9 #if 1
10 #define MARKER if(1) printf("MARKER: %s:%d:%s(): ",__FILE__,__LINE__,__func__); if(1) printf 10 #define MARKER if(1) printf("MARKER: %s:%d:%s(): ",__FILE__,__LINE__,__func__); if(1) printf
11 #else 11 #else
30 hidden lines
42 42
43 static bool 43 static bool
44 c11n_io_handler_sql_do_props( c11n_io_handler * self, c11n_node * tgt, size_t nid ) 44 c11n_io_handler_sql_do_props( c11n_io_handler * self, c11n_node * tgt, size_t nid )
45 { 45 {
46 IMPLDECL(false); 46 IMPLDECL(false);
47 whclob * sql = 0; | 47 memblob * sql = 0;
48 whclob_init( &sql, 0, 128 ); | 48 memblob_init( &sql, 0, 128 );
49 sqlite3_stmt * stmt = 0; 49 sqlite3_stmt * stmt = 0;
50 int rc = 0; 50 int rc = 0;
51 whclob_appendf( sql, "SELECT k,v FROM p WHERE n=%u;",nid); | 51 memblob_appendf( sql, "SELECT k,v FROM p WHERE n=%u;",nid);
52 rc = sqlite3_prepare_v2( impl->db, 52 rc = sqlite3_prepare_v2( impl->db,
53 whclob_bufferc(sql), | 53 memblob_bufferc(sql),
54 -1,&stmt,0 ); 54 -1,&stmt,0 );
55 whclob_finalize(sql); | 55 memblob_finalize(sql);
56 if( SQLITE_OK == rc ) rc = sqlite3_step(stmt); 56 if( SQLITE_OK == rc ) rc = sqlite3_step(stmt);
57 while( SQLITE_ROW == rc ) 57 while( SQLITE_ROW == rc )
58 { 58 {
59 const char * k = (char const *)sqlite3_column_text(stmt,0); 59 const char * k = (char const *)sqlite3_column_text(stmt,0);
60 const char * v = (char const *)sqlite3_column_text(stmt,1); 60 const char * v = (char const *)sqlite3_column_text(stmt,1);
8 hidden lines
69 69
70 static bool 70 static bool
71 c11n_io_handler_sql_desql( c11n_io_handler * self ) 71 c11n_io_handler_sql_desql( c11n_io_handler * self )
72 { 72 {
73 IMPLDECL(false); 73 IMPLDECL(false);
74 whclob * sql = 0; | 74 memblob * sql = 0;
75 whclob_init( &sql, 0, 128 ); | 75 memblob_init( &sql, 0, 128 );
76 sqlite3_stmt * stmt = 0; 76 sqlite3_stmt * stmt = 0;
77 int rc = 0; 77 int rc = 0;
78 whclob_append( sql, "SELECT id,pid,name,class FROM n ORDER BY pid",-1); | 78 memblob_append( sql, "SELECT id,pid,name,class FROM n ORDER BY pid",-1);
79 rc = sqlite3_prepare_v2( impl->db, 79 rc = sqlite3_prepare_v2( impl->db,
80 whclob_bufferc(sql), | 80 memblob_bufferc(sql),
81 -1,&stmt,0 ); 81 -1,&stmt,0 );
82 whclob_finalize(sql); | 82 memblob_finalize(sql);
83 /** 83 /**
84 We first read in all nodes and then iterate through them to get 84 We first read in all nodes and then iterate through them to get
85 their properties. This avoids us having nested sqlite3_stmt 85 their properties. This avoids us having nested sqlite3_stmt
86 activations (which i'm not sure sqlite3 allows?). To do this we 86 activations (which i'm not sure sqlite3 allows?). To do this we
87 have to add a kludge: we temporarily add two bogus properties 87 have to add a kludge: we temporarily add two bogus properties
103 hidden lines
191 sqlite3_close( impl->db ); 191 sqlite3_close( impl->db );
192 impl->db = 0; 192 impl->db = 0;
193 return 0; 193 return 0;
194 } 194 }
195 195
196 whclob * sql = 0; | 196 memblob * sql = 0;
197 if( whclob_rc.OK != whclob_init( &sql, 0, 1024 * 16 ) ) | 197 if( memblob_rc.OK != memblob_init( &sql, 0, 1024 * 16 ) )
198 { 198 {
199 return false; 199 return false;
200 } 200 }
201 size_t rd = 0; 201 size_t rd = 0;
202 bool isokay = true; 202 bool isokay = true;
203 while( (rd = c11n_stream_buffer_read( src, sql, 1024 )) ) 203 while( (rd = c11n_stream_buffer_read( src, sql, 1024 )) )
204 { 204 {
205 } 205 }
206 if( ! whclob_size(sql) ) | 206 if( ! memblob_size(sql) )
207 { 207 {
208 C11N_LOG(C11N_LOG_IO_ERR)("SQL input is empty!"); 208 C11N_LOG(C11N_LOG_IO_ERR)("SQL input is empty!");
209 isokay = false; 209 isokay = false;
210 } 210 }
211 211
212 if( isokay 212 if( isokay
213 && (SQLITE_OK != 213 && (SQLITE_OK !=
214 sqlite3_exec( impl->db, whclob_bufferc( sql ), 0, 0, 0 )) | 214 sqlite3_exec( impl->db, memblob_bufferc( sql ), 0, 0, 0 ))
215 ) 215 )
216 { 216 {
217 C11N_LOG(C11N_LOG_IO_ERR)("SQL error: [%s]",sqlite3_errmsg(impl->db)); 217 C11N_LOG(C11N_LOG_IO_ERR)("SQL error: [%s]",sqlite3_errmsg(impl->db));
218 isokay = false; 218 isokay = false;
219 } 219 }
220 whclob_finalize( sql ); | 220 memblob_finalize( sql );
221 //C11N_LOG(C11N_LOG_FYI)("Loaded SQL data!"); 221 //C11N_LOG(C11N_LOG_FYI)("Loaded SQL data!");
222 if( isokay && ! c11n_io_handler_sql_desql( self ) ) 222 if( isokay && ! c11n_io_handler_sql_desql( self ) )
223 { 223 {
224 isokay = false; 224 isokay = false;
225 } 225 }
211 hidden lines
437 437
438 c11n_io_handler * c11n_io_handler_factory_sql( c11n_const_string_t ignored ) 438 c11n_io_handler * c11n_io_handler_factory_sql( c11n_const_string_t ignored )
439 { 439 {
440 return c11n_io_handler_sql_new(); 440 return c11n_io_handler_sql_new();
441 } 441 }

Added src/c11n_stream_memblob.c

Old () New (adaed3400e1112d8)
> 1 #include <stdlib.h> /* malloc()/free() */
> 2 #include "s11n.net/c11n/io/c11n_stream_memblob.h"
> 3 #include "s11n.net/c11n/detail/memblob.h"
> 4 #include <assert.h>
> 5
> 6 #if 1
> 7 #include <stdio.h> // only for debuggering
> 8 #define MARKER if(1) printf("MARKER: %s:%d:%s():\n",__FILE__,__LINE__,__func__); if(1) printf
> 9 #else
> 10 static void bogo_printf(char const * fmt, ...) {}
> 11 #define MARKER if(0) bogo_printf
> 12 #endif
> 13
> 14
> 15 static void c11n_stream_memblob_destroy( c11n_stream * self );
> 16 static bool c11n_stream_memblob_write( c11n_stream * self, char const * src, size_t len );
> 17 static size_t c11n_stream_memblob_read( c11n_stream * self, char * dest, size_t max );
> 18 static bool c11n_stream_memblob_isgood( c11n_stream * self );
> 19
> 20 static const c11n_stream_api c11n_stream_api_memblob =
> 21 C11N_STREAM_API_INIT(c11n_stream_memblob_isgood,
> 22 c11n_stream_memblob_read,
> 23 c11n_stream_memblob_write,
> 24 c11n_stream_memblob_destroy);
> 25 #define CLOBDECL(RV) memblob * clob = self ? ((memblob *)self->implData) : 0; assert(clob && "meta failed!"); if(!clob) return RV
> 26 /**
> 27 c11n_stream_api::isgood() implementation for c11n_stream_memblob.
> 28 */
> 29 static bool c11n_stream_memblob_isgood( c11n_stream * self )
> 30 {
> 31 CLOBDECL(false);
> 32 return clob != 0;
> 33 }
> 34 /**
> 35 c11n_stream_api::read() implementation for c11n_stream_memblob.
> 36 */
> 37 static size_t c11n_stream_memblob_read( c11n_stream * self, char * dest, size_t max )
> 38 {
> 39 if( ! self || !max || !dest ) return 0;
> 40 //MARKER("READ 1\n");
> 41 CLOBDECL(0);
> 42 //MARKER("READ 2\n");
> 43 const long pos = memblob_tell( clob );
> 44 const long npos = memblob_seek( clob, (long)max, MEMBLOB_SEEK_CUR );
> 45 const long count = npos - pos;
> 46 //MARKER("Reading %ld bytes from the clob (size=%ld).\n",count,memblob_size(clob));
> 47 if( 0 >= count ) return 0;
> 48 char const * buf = memblob_bufferc( clob ) + pos;
> 49 long i = 0;
> 50 for( ; i < count; ++i )
> 51 {
> 52 *(dest++) = *(buf++);
> 53 }
> 54 //MARKER("READ 3: %ld\n",count);
> 55 return (size_t)count;
> 56 }
> 57
> 58 /**
> 59 c11n_stream_api::write() implementation for c11n_stream_memblob.
> 60 */
> 61 static bool c11n_stream_memblob_write( c11n_stream * self, char const * src, size_t len )
> 62 {
> 63 if( !len
> 64 || !self
> 65 //|| (!self || !self->api->isgood( self ))
> 66 ) return false;
> 67 // || !SELF->writeMode
> 68 CLOBDECL(false);
> 69 //MARKER("Appending %u/%ld bytes to clob.",len,(long)len);
> 70 long x = memblob_append( clob, src, (long)len);
> 71 bool ret = ((long)len == x);
> 72 //MARKER("AppendED %ld of %u bytes to clob (size=%ld).",x,len,memblob_size(clob));
> 73 return ret;
> 74 }
> 75 #undef CLOBDECL
> 76
> 77 /**
> 78 c11n_stream_api::destroy() implementation for c11n_stream_memblob.
> 79 */
> 80 static void c11n_stream_memblob_destroy( c11n_stream * self )
> 81 {
> 82 /* Reminder: we don't own self->implData */
> 83 free(self);
> 84 }
> 85
> 86 c11n_stream * c11n_stream_for_memblob( memblob * clob )
> 87 {
> 88 if( ! clob ) return 0;
> 89 c11n_stream * st = (c11n_stream*)malloc(sizeof(c11n_stream));
> 90 if( st )
> 91 {
> 92 st->implData = clob;
> 93 st->api = &c11n_stream_api_memblob;
> 94 }
> 95 return st;
> 96 }
> 97
> 98 size_t c11n_stream_buffer_read( c11n_stream * src, memblob * dest, const size_t max )
> 99 {
> 100 if( ! src || !dest || !max ) return false;
> 101 long pos = memblob_tell(dest);
> 102 //MARKER("buffering read of %u bytes at pos %ld\n",max,pos);
> 103 if( memblob_rc.OK > memblob_reserve( dest, max + pos ) ) return false;
> 104 memblob_append_char_n( dest, 0, max ); // unfortunate, but necessary to get the clob cursor and our stuff to match
> 105 //MARKER("buffering read of %u bytes at pos %ld. clob size=%ld, capacity=%ld\n",max,pos,memblob_size(dest),memblob_capacity(dest));
> 106 char * buf = memblob_buffer(dest) + pos;
> 107 size_t rd = src->api->read(src, buf, max );
> 108 if( 0 != rd )
> 109 {
> 110 long newpos = (long)(pos + rd);
> 111 //MARKER("seek()ing to pos %ld\n",newpos);
> 112 memblob_seek( dest, newpos, MEMBLOB_SEEK_SET );
> 113 //MARKER("seek()ed to pos %ld\n",memblob_tell(dest));
> 114 }
> 115 {
> 116 //MARKER("read() returned 0!\n");
> 117 }
> 118 return (size_t)rd;
> 119 }

Deleted src/c11n_stream_whclob.c

Old (3009bc207d2f11f0) New ()
1 #include <stdlib.h> /* malloc()/free() */ <
2 #include "s11n.net/c11n/io/c11n_stream_whclob.h" <
3 #include "s11n.net/c11n/detail/whclob.h" <
4 #include <assert.h> <
5 <
6 #if 1 <
7 #include <stdio.h> // only for debuggering <
8 #define MARKER if(1) printf("MARKER: %s:%d:%s():\n",__FILE__,__LINE__,__func__); if(1) printf <
9 #else <
10 static void bogo_printf(char const * fmt, ...) {} <
11 #define MARKER if(0) bogo_printf <
12 #endif <
13 <
14 <
15 static void c11n_stream_whclob_destroy( c11n_stream * self ); <
16 static bool c11n_stream_whclob_write( c11n_stream * self, char const * src, size_t len ); <
17 static size_t c11n_stream_whclob_read( c11n_stream * self, char * dest, size_t max ); <
18 static bool c11n_stream_whclob_isgood( c11n_stream * self ); <
19 <
20 static const c11n_stream_api c11n_stream_api_whclob = <
21 C11N_STREAM_API_INIT(c11n_stream_whclob_isgood, <
22 c11n_stream_whclob_read, <
23 c11n_stream_whclob_write, <
24 c11n_stream_whclob_destroy); <
25 #define CLOBDECL(RV) whclob * clob = self ? ((whclob *)self->implData) : 0; assert(clob && "meta failed!"); if(!clob) return RV <
26 /** <
27 c11n_stream_api::isgood() implementation for c11n_stream_whclob. <
28 */ <
29 static bool c11n_stream_whclob_isgood( c11n_stream * self ) <
30 { <
31 CLOBDECL(false); <
32 return clob != 0; <
33 } <
34 /** <
35 c11n_stream_api::read() implementation for c11n_stream_whclob. <
36 */ <
37 static size_t c11n_stream_whclob_read( c11n_stream * self, char * dest, size_t max ) <
38 { <
39 if( ! self || !max || !dest ) return 0; <
40 //MARKER("READ 1\n"); <
41 CLOBDECL(0); <
42 //MARKER("READ 2\n"); <
43 const long pos = whclob_tell( clob ); <
44 const long npos = whclob_seek( clob, (long)max, WHCLOB_SEEK_CUR ); <
45 const long count = npos - pos; <
46 //MARKER("Reading %ld bytes from the clob (size=%ld).\n",count,whclob_size(clob)); <
47 if( 0 >= count ) return 0; <
48 char const * buf = whclob_bufferc( clob ) + pos; <
49 long i = 0; <
50 for( ; i < count; ++i ) <
51 { <
52 *(dest++) = *(buf++); <
53 } <
54 //MARKER("READ 3: %ld\n",count); <
55 return (size_t)count; <
56 } <
57 <
58 /** <
59 c11n_stream_api::write() implementation for c11n_stream_whclob. <
60 */ <
61 static bool c11n_stream_whclob_write( c11n_stream * self, char const * src, size_t len ) <
62 { <
63 if( !len <
64 || !self <
65 //|| (!self || !self->api->isgood( self )) <
66 ) return false; <
67 // || !SELF->writeMode <
68 CLOBDECL(false); <
69 //MARKER("Appending %u/%ld bytes to clob.",len,(long)len); <
70 long x = whclob_append( clob, src, (long)len); <
71 bool ret = ((long)len == x); <
72 //MARKER("AppendED %ld of %u bytes to clob (size=%ld).",x,len,whclob_size(clob)); <
73 return ret; <
74 } <
75 #undef CLOBDECL <
76 <
77 /** <
78 c11n_stream_api::destroy() implementation for c11n_stream_whclob. <
79 */ <
80 static void c11n_stream_whclob_destroy( c11n_stream * self ) <
81 { <
82 /* Reminder: we don't own self->implData */ <
83 free(self); <
84 } <
85 <
86 c11n_stream * c11n_stream_for_whclob( whclob * clob ) <
87 { <
88 if( ! clob ) return 0; <
89 c11n_stream * st = (c11n_stream*)malloc(sizeof(c11n_stream)); <
90 if( st ) <
91 { <
92 st->implData = clob; <
93 st->api = &c11n_stream_api_whclob; <
94 } <
95 return st; <
96 } <
97 <
98 size_t c11n_stream_buffer_read( c11n_stream * src, whclob * dest, const size_t max ) <
99 { <
100 if( ! src || !dest || !max ) return false; <
101 long pos = whclob_tell(dest); <
102 //MARKER("buffering read of %u bytes at pos %ld\n",max,pos); <
103 if( whclob_rc.OK > whclob_reserve( dest, max + pos ) ) return false; <
104 whclob_append_char_n( dest, 0, max ); // unfortunate, but necessary to get the clob cursor and our stuff to match <
105 //MARKER("buffering read of %u bytes at pos %ld. clob size=%ld, capacity=%ld\n",max,pos,whclob_size(dest),whclob_capacity(dest)); <
106 char * buf = whclob_buffer(dest) + pos; <
107 size_t rd = src->api->read(src, buf, max ); <
108 if( 0 != rd ) <
109 { <
110 long newpos = (long)(pos + rd); <
111 //MARKER("seek()ing to pos %ld\n",newpos); <
112 whclob_seek( dest, newpos, WHCLOB_SEEK_SET ); <
113 //MARKER("seek()ed to pos %ld\n",whclob_tell(dest)); <
114 } <
115 { <
116 //MARKER("read() returned 0!\n"); <
117 } <
118 return (size_t)rd; <
119 } <

Changes to src/c11nconvert.c

Old (8470a76984a6c793) New (6bc923952ec0057a)
1 #include "s11n.net/c11n/c11n.h" 1 #include "s11n.net/c11n/c11n.h"
2 #include "s11n.net/c11n/io/c11n_io.h" 2 #include "s11n.net/c11n/io/c11n_io.h"
3 #include "s11n.net/c11n/io/c11n_stream_FILE.h" 3 #include "s11n.net/c11n/io/c11n_stream_FILE.h"
4 4
5 #include <stdio.h> 5 #include <stdio.h>
7 #include <string.h> 7 #include <string.h>
8 #include <ctype.h> 8 #include <ctype.h>
9 #include "s11n.net/c11n/c11n.h" 9 #include "s11n.net/c11n/c11n.h"
10 #include "s11n.net/c11n/io/c11n_io.h" 10 #include "s11n.net/c11n/io/c11n_io.h"
11 #include "s11n.net/c11n/io/c11n_stream_FILE.h" 11 #include "s11n.net/c11n/io/c11n_stream_FILE.h"
12 #include "s11n.net/c11n/io/c11n_stream_whclob.h" | 12 #include "s11n.net/c11n/io/c11n_stream_memblob.h"
13 #include "s11n.net/c11n/detail/whclob.h" | 13 #include "s11n.net/c11n/detail/memblob.h"
14 #include "s11n.net/c11n/detail/whgc.h" 14 #include "s11n.net/c11n/detail/whgc.h"
15 15
16 /** 16 /**
17 A test/demo app for libc11n. Note that we don't take too much care 17 A test/demo app for libc11n. Note that we don't take too much care
18 to free up memory on an error, because we expect that the app will 18 to free up memory on an error, because we expect that the app will
162 hidden lines
181 (0==rc) 181 (0==rc)
182 ? "You win :)" 182 ? "You win :)"
183 : "You lose :("); 183 : "You lose :(");
184 return rc; 184 return rc;
185 } 185 }

Changes to src/scratch.c

Old (4b4b55ed6892218f) New (7026ceb311271115)
1 #include <stdio.h> 1 #include <stdio.h>
2 #include <stdlib.h> 2 #include <stdlib.h>
3 #include <string.h> 3 #include <string.h>
4 #include <ctype.h> 4 #include <ctype.h>
5 #include <assert.h> 5 #include <assert.h>
6 6
7 #include "s11n.net/c11n/c11n.h" 7 #include "s11n.net/c11n/c11n.h"
8 #include "s11n.net/c11n/io/c11n_io.h" 8 #include "s11n.net/c11n/io/c11n_io.h"
9 #include "s11n.net/c11n/detail/whclob.h" | 9 #include "s11n.net/c11n/detail/memblob.h"
10 10
11 #if 1 11 #if 1
12 #define MARKER if(1) printf("MARKER: %s:%d:%s(): ",__FILE__,__LINE__,__func__); if(1) printf 12 #define MARKER if(1) printf("MARKER: %s:%d:%s(): ",__FILE__,__LINE__,__func__); if(1) printf
13 #else 13 #else
14 #define MARKER if(0) printf 14 #define MARKER if(0) printf
19 hidden lines
34 {">",1,"&gt;",4}, 34 {">",1,"&gt;",4},
35 {0,0,0,0} 35 {0,0,0,0}
36 }; 36 };
37 MARKER("Input = [%s]\n",input); 37 MARKER("Input = [%s]\n",input);
38 38
39 whclob * cdec = whclob_new(); | 39 memblob * cdec = memblob_new();
40 size_t rc = c11n_io_escape_string( input, inlen, escapes, true, cdec ); 40 size_t rc = c11n_io_escape_string( input, inlen, escapes, true, cdec );
41 MARKER("Escaped: [%s]\n", whclob_bufferc(cdec) ); | 41 MARKER("Escaped: [%s]\n", memblob_bufferc(cdec) );
42 whclob * cb = whclob_new(); | 42 memblob * cb = memblob_new();
43 rc = c11n_io_escape_string( whclob_bufferc(cdec), whclob_size(cdec), escapes, false, cb ); | 43 rc = c11n_io_escape_string( memblob_bufferc(cdec), memblob_size(cdec), escapes, false, cb );
44 MARKER( "Unescaped: [%s]\n", whclob_bufferc(cb) ); | 44 MARKER( "Unescaped: [%s]\n", memblob_bufferc(cb) );
45 whclob_finalize(cb); | 45 memblob_finalize(cb);
46 whclob_finalize(cdec); | 46 memblob_finalize(cdec);
47 47
48 return 0; 48 return 0;
49 } 49 }

Changes to src/test-clob.c

Old (05fbebc50bbe33f8) New (ce88e7ed005276b6)
1 #include <stdio.h> 1 #include <stdio.h>
2 #include <stdlib.h> 2 #include <stdlib.h>
3 #include <string.h> 3 #include <string.h>
4 #include <ctype.h> 4 #include <ctype.h>
5 #include <assert.h> 5 #include <assert.h>
6 6
7 #include "s11n.net/c11n/detail/whclob.h" | 7 #include "s11n.net/c11n/detail/memblob.h"
8 8
9 #if 1 9 #if 1
10 #define MARKER if(1) printf("MARKER: %s:%d:%s(): ",__FILE__,__LINE__,__func__); if(1) printf 10 #define MARKER if(1) printf("MARKER: %s:%d:%s(): ",__FILE__,__LINE__,__func__); if(1) printf
11 #else 11 #else
12 #define MARKER if(0) printf 12 #define MARKER if(0) printf
13 #endif 13 #endif
14 14
15 #define DUMP(CL) MARKER("clob@%p size=%ld capacity=%ld data=[%s]\n",(void const *)CL,whclob_size(CL),whclob_capacity(CL),whclob_bufferc(CL)) | 15 #define DUMP(CL) MARKER("clob@%p size=%ld capacity=%ld data=[%s]\n",(void const *)CL,memblob_size(CL),memblob_capacity(CL),memblob_bufferc(CL))
16 16
17 typedef struct MyStruct 17 typedef struct MyStruct
18 { 18 {
19 int x; 19 int x;
20 int y; 20 int y;
3 hidden lines
24 { 24 {
25 char const * input = 25 char const * input =
26 //"a b c" 26 //"a b c"
27 "A <B> C*D \"inner string\"" 27 "A <B> C*D \"inner string\""
28 ; 28 ;
29 whclob * cb = whclob_new_n(40); | 29 memblob * cb = memblob_new_n(40);
| 30 DUMP(cb);
| 31 memblob_appendf( cb, "%s", input );
| 32 DUMP(cb);
| 33 memblob_truncate(cb,3,1);
30 DUMP(cb); 34 DUMP(cb);
31 whclob_appendf( cb, "%s", input ); | 35 memblob_append( cb, "HIHI", 4 );
32 DUMP(cb); 36 DUMP(cb);
33 whclob_truncate(cb,3,1); | 37 memblob_truncate(cb,5,0);
34 DUMP(cb); 38 DUMP(cb);
35 whclob_append( cb, "HIHI", 4 ); | 39 memblob_truncate(cb,8,-1);
36 DUMP(cb); |
37 whclob_truncate(cb,5,0); |
38 DUMP(cb); |
39 whclob_truncate(cb,8,-1); |
40 DUMP(cb); 40 DUMP(cb);
41 whclob_reset(cb); | 41 memblob_reset(cb);
42 42
43 long rc = whclob_import_filename( cb, __FILE__ ); | 43 long rc = memblob_import_filename( cb, __FILE__ );
44 MARKER("Import [%s] rc = %ld\n",__FILE__, rc); 44 MARKER("Import [%s] rc = %ld\n",__FILE__, rc);
45 whclob_base64_enc( cb, cb ); | 45 memblob_base64_enc( cb, cb );
46 46
47 MARKER("base64-encoded (size=%ld):\n",whclob_size(cb)); | 47 MARKER("base64-encoded (size=%ld):\n",memblob_size(cb));
48 //whclob_export_FILE( cb, stdout ); | 48 //memblob_export_FILE( cb, stdout );
49 //fputc( '\n', stdout ); 49 //fputc( '\n', stdout );
50 MARKER("End encoded data.\n"); 50 MARKER("End encoded data.\n");
51 whclob_base64_dec( cb, cb ); | 51 memblob_base64_dec( cb, cb );
52 MARKER("base64-decoded size=%ld\n",whclob_size(cb)); | 52 MARKER("base64-decoded size=%ld\n",memblob_size(cb));
53 //MARKER("base64-decoded:\n"); 53 //MARKER("base64-decoded:\n");
54 //whclob_export_FILE( cb, stdout ); | 54 //memblob_export_FILE( cb, stdout );
55 55
56 whclob_reset(cb); | 56 memblob_reset(cb);
57 MyStruct my; 57 MyStruct my;
58 my.x = 42; 58 my.x = 42;
59 my.y = -42; 59 my.y = -42;
60 whclob_append( cb, (char const *)&my, sizeof(MyStruct)); | 60 memblob_append( cb, (char const *)&my, sizeof(MyStruct));
61 MARKER("MyStruct clob size: %ld\n", whclob_size(cb) ); | 61 MARKER("MyStruct clob size: %ld\n", memblob_size(cb) );
62 whclob_base64_enc( cb, cb ); | 62 memblob_base64_enc( cb, cb );
63 MARKER("MyStruct clob encoded size: %ld\n", whclob_size(cb) ); | 63 MARKER("MyStruct clob encoded size: %ld\n", memblob_size(cb) );
64 whclob_export_FILE( cb, stdout ); | 64 memblob_export_FILE( cb, stdout );
65 65
66 MyStruct my2; 66 MyStruct my2;
67 whclob_base64_dec( cb, cb ); | 67 memblob_base64_dec( cb, cb );
68 memcpy( &my2, whclob_bufferc(cb), (size_t) whclob_size(cb) ); | 68 memcpy( &my2, memblob_bufferc(cb), (size_t) memblob_size(cb) );
69 MARKER("my2: x=%d y=%d\n", my2.x, my2.y ); 69 MARKER("my2: x=%d y=%d\n", my2.x, my2.y );
70 whclob_reset(cb); | 70 memblob_reset(cb);
71 71
72 whclob_finalize(cb); | 72 memblob_finalize(cb);
73 return 0; 73 return 0;
74 } 74 }

Changes to src/test.c

Old (5a68ab0207bd4620) New (caa3355a092dd802)
1 #include <stdio.h> 1 #include <stdio.h>
2 #include <stdlib.h> 2 #include <stdlib.h>
3 #include <string.h> 3 #include <string.h>
4 #include <ctype.h> 4 #include <ctype.h>
5 #include <assert.h> 5 #include <assert.h>
6 6
7 #include "s11n.net/c11n/c11n.h" 7 #include "s11n.net/c11n/c11n.h"
8 #include "s11n.net/c11n/io/c11n_io.h" 8 #include "s11n.net/c11n/io/c11n_io.h"
9 #include "s11n.net/c11n/io/c11n_stream_FILE.h" 9 #include "s11n.net/c11n/io/c11n_stream_FILE.h"
10 #include "s11n.net/c11n/io/c11n_stream_whclob.h" | 10 #include "s11n.net/c11n/io/c11n_stream_memblob.h"
11 #include "s11n.net/c11n/detail/whclob.h" | 11 #include "s11n.net/c11n/detail/memblob.h"
12 #include "s11n.net/c11n/io/c11n_io_handler_binarish.h" 12 #include "s11n.net/c11n/io/c11n_io_handler_binarish.h"
13 #include "MyType.h" /* example class */ 13 #include "MyType.h" /* example class */
14 14
15 /** 15 /**
16 A test/demo app for libc11n. Note that we don't take too much care 16 A test/demo app for libc11n. Note that we don't take too much care
13 hidden lines
30 whgc_context * gc; 30 whgc_context * gc;
31 c11n_stream * cout; 31 c11n_stream * cout;
32 } ThisApp; 32 } ThisApp;
33 33
34 /** 34 /**
35 Increasing the whclob alloc policy to around 1.5x actually lowers | 35 Increasing the memblob alloc policy to around 1.5x actually lowers
36 the peak max aggregate memory allocated (per valgrind data). 36 the peak max aggregate memory allocated (per valgrind data).
37 */ 37 */
38 long my_whclob_alloc_policy( long n ) | 38 long my_memblob_alloc_policy( long n )
39 { 39 {
40 long ret = n; 40 long ret = n;
41 #if 0 41 #if 0
42 ret = (long) (n * 1.5); 42 ret = (long) (n * 1.5);
43 #else 43 #else
55 hidden lines
99 GET(N,"pX"); 99 GET(N,"pX");
100 100
101 c11n_node * CH = c11n_node_create_child( N, "aChild" ); 101 c11n_node * CH = c11n_node_create_child( N, "aChild" );
102 SET(CH, "anglebone", "hi, world" ); 102 SET(CH, "anglebone", "hi, world" );
103 int i = 0; 103 int i = 0;
104 whclob * clob = whclob_new(); | 104 memblob * clob = memblob_new();
105 for( ; i < 3; ++i ) 105 for( ; i < 3; ++i )
106 { 106 {
107 whclob_appendf( clob, "key%d",i); | 107 memblob_appendf( clob, "key%d",i);
108 c11n_node_prop_set_fe( CH, whclob_bufferc(clob), "value #%d",i ); | 108 c11n_node_prop_set_fe( CH, memblob_bufferc(clob), "value #%d",i );
109 whclob_reset(clob); | 109 memblob_reset(clob);
110 } 110 }
111 //whclob_finalize(clob); | 111 //memblob_finalize(clob);
112 GET(CH,"key2"); 112 GET(CH,"key2");
113 #undef SET 113 #undef SET
114 #undef GET 114 #undef GET
115 115
116 typedef double CType; 116 typedef double CType;
120 hidden lines
237 return 22; 237 return 22;
238 } 238 }
239 o1t->api->destroy(o1t); 239 o1t->api->destroy(o1t);
240 240
241 c11n_node_destroy( N ); 241 c11n_node_destroy( N );
242 whclob_finalize(clob); | 242 memblob_finalize(clob);
243 return rc; 243 return rc;
244 } 244 }
245 245
246 static void gc_c11n_stream( void * v ) 246 static void gc_c11n_stream( void * v )
247 { 247 {
2 hidden lines
250 { 250 {
251 MARKER("GC'ing c11n_stream @%p\n",v); 251 MARKER("GC'ing c11n_stream @%p\n",v);
252 s->api->destroy(s); 252 s->api->destroy(s);
253 } 253 }
254 } 254 }
255 static void gc_whclob( void * v) | 255 static void gc_memblob( void * v)
256 { 256 {
257 whclob * s = v ? (whclob *)v : 0; | 257 memblob * s = v ? (memblob *)v : 0;
258 if( s ) 258 if( s )
259 { 259 {
260 MARKER("GC'ing whclob @%p\n",v); | 260 MARKER("GC'ing memblob @%p\n",v);
261 whclob_finalize(s); | 261 memblob_finalize(s);
262 } 262 }
263 } 263 }
264 int test_streams() 264 int test_streams()
265 { 265 {
266 c11n_stream * is = 0; 266 c11n_stream * is = 0;
267 const size_t blockSize = 1024; 267 const size_t blockSize = 1024;
268 char const * ofile = "ostr.out"; 268 char const * ofile = "ostr.out";
269 char const * infile = __FILE__; 269 char const * infile = __FILE__;
270 270
271 whclob * cb = 0; | 271 memblob * cb = 0;
272 whclob_init( &cb, 0, blockSize ); | 272 memblob_init( &cb, 0, blockSize );
273 whgc_add( ThisApp.gc, cb, gc_whclob ); | 273 whgc_add( ThisApp.gc, cb, gc_memblob );
274 274
275 275
276 char * buf = whclob_buffer(cb); | 276 char * buf = memblob_buffer(cb);
277 277
278 size_t count = 0; 278 size_t count = 0;
279 279
280 whclob * membuf = whclob_new(); | 280 memblob * membuf = memblob_new();
281 whclob_reserve( membuf, blockSize * 10 ); | 281 memblob_reserve( membuf, blockSize * 10 );
282 whclob_set_alloc_policy( membuf, my_whclob_alloc_policy ); | 282 memblob_set_alloc_policy( membuf, my_memblob_alloc_policy );
283 whgc_add( ThisApp.gc, membuf, gc_whclob ); | 283 whgc_add( ThisApp.gc, membuf, gc_memblob );
284 c11n_stream * mems = c11n_stream_for_whclob( membuf ); | 284 c11n_stream * mems = c11n_stream_for_memblob( membuf );
285 assert(mems && "Got memory stream"); 285 assert(mems && "Got memory stream");
286 whgc_add( ThisApp.gc, mems, gc_c11n_stream ); 286 whgc_add( ThisApp.gc, mems, gc_c11n_stream );
287 MARKER("***** START OF FILE %s\n",infile); 287 MARKER("***** START OF FILE %s\n",infile);
288 is = c11n_stream_for_filename( infile, false ); 288 is = c11n_stream_for_filename( infile, false );
289 if( ! is ) { return 1; } 289 if( ! is ) { return 1; }
7 hidden lines
297 if( ! mems->api->write( mems, buf, count ) ) 297 if( ! mems->api->write( mems, buf, count ) )
298 { 298 {
299 MARKER("Write of %u bytes to memory buffer failed!\n",count ); 299 MARKER("Write of %u bytes to memory buffer failed!\n",count );
300 return 3; 300 return 3;
301 } 301 }
302 MARKER("buf=%p, membuf size=%ld capacity=%ld\n",buf,whclob_size(membuf),whclob_capacity(membuf)); | 302 MARKER("buf=%p, membuf size=%ld capacity=%ld\n",buf,memblob_size(membuf),memblob_capacity(membuf));
303 //whclob_append( cb, "\0", 1 );//same thing: buf[count] = 0; | 303 //memblob_append( cb, "\0", 1 );//same thing: buf[count] = 0;
304 //MARKER("Read %u of %u byte(s).\n",count,blockSize); 304 //MARKER("Read %u of %u byte(s).\n",count,blockSize);
305 //printf("[[%s]]",buf); 305 //printf("[[%s]]",buf);
306 } 306 }
307 whgc_unregister( ThisApp.gc, is ); 307 whgc_unregister( ThisApp.gc, is );
308 is->api->destroy(is); 308 is->api->destroy(is);
309 MARKER("***** END OF FILE %s\n",infile); 309 MARKER("***** END OF FILE %s\n",infile);
310 //MARKER("membuf size=%ld capacity=%ld\n",whclob_size(membuf),whclob_capacity(membuf)); | 310 //MARKER("membuf size=%ld capacity=%ld\n",memblob_size(membuf),memblob_capacity(membuf));
311 //whclob_truncate( membuf, whclob_size( membuf ), -1 ); | 311 //memblob_truncate( membuf, memblob_size( membuf ), -1 );
312 MARKER("membuf size=%ld capacity=%ld\n",whclob_size(membuf),whclob_capacity(membuf)); | 312 MARKER("membuf size=%ld capacity=%ld\n",memblob_size(membuf),memblob_capacity(membuf));
313 whclob_export_filename( membuf, "membuf.out" ); | 313 memblob_export_filename( membuf, "membuf.out" );
314 314
315 c11n_stream * ostr = c11n_stream_for_filename( ofile, true ); 315 c11n_stream * ostr = c11n_stream_for_filename( ofile, true );
316 if( ! ostr ) return 4; 316 if( ! ostr ) return 4;
317 whgc_add( ThisApp.gc, ostr, gc_c11n_stream ); 317 whgc_add( ThisApp.gc, ostr, gc_c11n_stream );
318 if( ! ostr->api->isgood(ostr) ) { ostr->api->destroy(ostr); return 5; } 318 if( ! ostr->api->isgood(ostr) ) { ostr->api->destroy(ostr); return 5; }
319 //whclob_rewind(membuf); | 319 //memblob_rewind(membuf);
320 size_t total = 0; 320 size_t total = 0;
321 whclob * checker = whclob_new(); | 321 memblob * checker = memblob_new();
322 whgc_add( ThisApp.gc, checker, gc_whclob ); | 322 whgc_add( ThisApp.gc, checker, gc_memblob );
323 while( (count = mems->api->read( mems, buf, blockSize ) ) ) 323 while( (count = mems->api->read( mems, buf, blockSize ) ) )
324 { 324 {
325 total += count; 325 total += count;
326 whclob_append( checker, buf, count ); | 326 memblob_append( checker, buf, count );
327 if( ! ostr->api->write( ostr, buf, count ) ) 327 if( ! ostr->api->write( ostr, buf, count ) )
328 { 328 {
329 MARKER("Write of %u bytes to file %s failed!\n",count, ofile); 329 MARKER("Write of %u bytes to file %s failed!\n",count, ofile);
330 return 6; 330 return 6;
331 } 331 }
332 //MARKER("buf=%p Wrote %u of %u byte-block. Total=%u.\n",buf,count,blockSize,total); 332 //MARKER("buf=%p Wrote %u of %u byte-block. Total=%u.\n",buf,count,blockSize,total);
333 } 333 }
334 whclob_export_filename( checker, "checker.out" ); | 334 memblob_export_filename( checker, "checker.out" );
335 whgc_unregister( ThisApp.gc, ostr ); 335 whgc_unregister( ThisApp.gc, ostr );
336 ostr->api->destroy(ostr); 336 ostr->api->destroy(ostr);
337 337
338 MARKER("Wrote %ld bytes to file %s.\n",whclob_size(membuf),ofile); | 338 MARKER("Wrote %ld bytes to file %s.\n",memblob_size(membuf),ofile);
339 339
340 whclob_rewind(membuf); | 340 memblob_rewind(membuf);
341 ostr = c11n_stream_for_filename( "FILE.out", true ); 341 ostr = c11n_stream_for_filename( "FILE.out", true );
342 bool worked = ostr->api->write( ostr, whclob_bufferc(membuf), whclob_size(membuf) ); | 342 bool worked = ostr->api->write( ostr, memblob_bufferc(membuf), memblob_size(membuf) );
343 MARKER("ostr->api->write worked? == %d\n",worked); 343 MARKER("ostr->api->write worked? == %d\n",worked);
344 ostr->api->destroy(ostr); 344 ostr->api->destroy(ostr);
345 //mems->api->destroy(mems); 345 //mems->api->destroy(mems);
346 whclob_export_filename( membuf, "membuf2.out" ); | 346 memblob_export_filename( membuf, "membuf2.out" );
347 whgc_clear_context( ThisApp.gc ); 347 whgc_clear_context( ThisApp.gc );
348 #endif 348 #endif
349 return 0; 349 return 0;
350 } 350 }
351 351
55 hidden lines
407 return 0; 407 return 0;
408 } 408 }
409 409
410 int test_otherstuff() 410 int test_otherstuff()
411 { 411 {
412 whclob * cb = whclob_new(); | 412 memblob * cb = memblob_new();
413 whgc_add( ThisApp.gc, cb, gc_whclob ); | 413 whgc_add( ThisApp.gc, cb, gc_memblob );
414 whclob_import_filename(cb,__FILE__); | 414 memblob_import_filename(cb,__FILE__);
415 c11n_stream * is = c11n_stream_for_whclob( cb ); | 415 c11n_stream * is = c11n_stream_for_memblob( cb );
416 whgc_add( ThisApp.gc, is, gc_c11n_stream ); 416 whgc_add( ThisApp.gc, is, gc_c11n_stream );
417 whclob * check = 0; | 417 memblob * check = 0;
418 whclob_init( &check, 0, 1024 ); | 418 memblob_init( &check, 0, 1024 );
419 whgc_add( ThisApp.gc, check, gc_whclob ); | 419 whgc_add( ThisApp.gc, check, gc_memblob );
420 size_t at = 1; 420 size_t at = 1;
421 bool rc = true; 421 bool rc = true;
422 for( ; at < 31; at += at ) 422 for( ; at < 31; at += at )
423 { 423 {
424 rc = c11n_stream_buffer_read( is, check, at ); 424 rc = c11n_stream_buffer_read( is, check, at );
425 if( ! rc ) break; 425 if( ! rc ) break;
426 MARKER("buffered read. clob size=%ld, capacity=%ld\n",whclob_size(check),whclob_capacity(check)); | 426 MARKER("buffered read. clob size=%ld, capacity=%ld\n",memblob_size(check),memblob_capacity(check));
427 } 427 }
428 if( ! rc ) 428 if( ! rc )
429 { 429 {
430 MARKER("c11n_stream_buffer_read() failed.\n"); 430 MARKER("c11n_stream_buffer_read() failed.\n");
431 return -1; 431 return -1;
432 } 432 }
433 else 433 else
434 { 434 {
435 MARKER("Read in %ld bytes: [%s]\n",whclob_size(check),whclob_bufferc(check)); | 435 MARKER("Read in %ld bytes: [%s]\n",memblob_size(check),memblob_bufferc(check));
436 } 436 }
437 if( ! c11n_io_handler_register( "bin", c11n_io_handler_factory_binarish ) ) 437 if( ! c11n_io_handler_register( "bin", c11n_io_handler_factory_binarish ) )
438 { 438 {
439 MARKER("Factory registration failed!\n"); 439 MARKER("Factory registration failed!\n");
440 return -2; 440 return -2;
8 hidden lines
449 { 449 {
450 MARKER("Loaded file handler for cookie.\n"); 450 MARKER("Loaded file handler for cookie.\n");
451 } 451 }
452 h->api->destroy(h); 452 h->api->destroy(h);
453 453
454 //whclob_finalize(check); | 454 //memblob_finalize(check);
455 //whclob_finalize(cb); | 455 //memblob_finalize(cb);
456 return 0; 456 return 0;
457 } 457 }
458 458
459 int test_binary() 459 int test_binary()
460 { 460 {
87 hidden lines
548 #endif // C11N_IO_USE_SQL 548 #endif // C11N_IO_USE_SQL
549 549
550 550
551 int main( int argc, char ** argv ) 551 int main( int argc, char ** argv )
552 { 552 {
553 //whclob_set_default_alloc_policy( my_whclob_alloc_policy ); | 553 //memblob_set_default_alloc_policy( my_memblob_alloc_policy );
554 ThisApp.gc = whgc_create_context(&ThisApp); 554 ThisApp.gc = whgc_create_context(&ThisApp);
555 ThisApp.cout = c11n_stream_for_FILE( stdout ); 555 ThisApp.cout = c11n_stream_for_FILE( stdout );
556 556
557 c11n_log_set_stream( stderr ); 557 c11n_log_set_stream( stderr );
558 //c11n_log_set_flags( c11n_log_get_flags() | C11N_LOG_DEALLOC ); 558 //c11n_log_set_flags( c11n_log_get_flags() | C11N_LOG_DEALLOC );
17 hidden lines
576 : "You lose :("); 576 : "You lose :(");
577 ThisApp.cout->api->destroy(ThisApp.cout); 577 ThisApp.cout->api->destroy(ThisApp.cout);
578 whgc_destroy_context(ThisApp.gc); 578 whgc_destroy_context(ThisApp.gc);
579 return rc; 579 return rc;
580 } 580 }

Deleted src/whclob.c

Old (11d6042d3c580e26) New ()
1 #include <string.h> <
2 #include <stdlib.h> <
3 #include <stdio.h> <
4 #include <stdarg.h> <
5 <
6 #include "s11n.net/c11n/detail/whclob.h" <
7 #include "s11n.net/c11n/detail/vappendf.h" <
8 <
9 #if WHCLOB_USE_ZLIB <
10 # include <zlib.h> <
11 #endif <
12 <
13 #define MARKER if(1) printf("MARKER: %s:%d:%s() ",__FILE__,__LINE__,__func__);if(1)printf <
14 <
15 #define WHCLOB_DEBUG 0 <
16 <
17 <
18 const whclob_rc_t whclob_rc = {0, /* OK */ <
19 -1, /* Err */ <
20 -2, /* AllocError */ <
21 -3, /* UnexpectedNull */ <
22 -4, /* RangeError */ <
23 -5, /* IOError */ <
24 -6 /* ArgError */ <
25 }; <
26 <
27 <
28 struct whclob <
29 { <
30 /* <
31 The address of the memory this blob refers to. See below <
32 for more info. <
33 <
34 If aData is pointed to a const string or a string owned by <
35 another entity, then nAlloc must be set to 0. This indicates <
36 to the framework that aData is not to be deleted when the <
37 blob is freed. In this case, nUsed must be set to the full <
38 length of the pointed-to data object. When shallow copies <
39 like this exist, any change made to pointed-to copies will <
40 invalidate the state of the doing-the-pointing whclob object. <
41 <
42 The framework tries to ensure that aData[nUsed] is always <
43 set to 0 (assuming that aData is not manipulated outside of <
44 the clob API). Note that since aData may contain binary data <
45 (and embedded nulls), such a trailing null cannot be used <
46 for length determination purposes. <
47 */ <
48 char * aData; <
49 /** <
50 long nAlloc = the number of contiguous bytes allocated to <
51 aData. See below for more info. <
52 */ <
53 long nAlloc; <
54 /* <
55 long nUsed = the number of contiguous bytes "used" in the <
56 aData array. <
57 */ <
58 long nUsed; <
59 /* <
60 The current position marker for some read operations. <
61 */ <
62 long nCursor; <
63 whclob_alloc_policy_t allocPolicy; <
64 }; <
65 <
66 <
67 /** <
68 Default alloc size policy, simply returns n. <
69 */ <
70 static long whclob_default_alloc_policy( long n ) <
71 { <
72 return n; <
73 } <
74 <
75 /* <
76 Clob_empty is an empty whclob used for init purposes. <
77 */ <
78 static const whclob Clob_empty = {0, /* aData */ <
79 0, /* nAlloc */ <
80 0, /* nUsed */ <
81 0, /* nCursor */ <
82 whclob_default_alloc_policy <
83 }; <
84 <
85 /** <
86 A debugging-only function. Do not use it in client code. <
87 */ <
88 void whclob_dump( whclob * cb, int doString ); <
89 <
90 typedef whclob_alloc_policy_t RePol; <
91 static RePol whclob_current_alloc_policy = whclob_default_alloc_policy; <
92 RePol whclob_set_default_alloc_policy( RePol f ) <
93 { <
94 RePol old = whclob_current_alloc_policy; <
95 whclob_current_alloc_policy = f ? f : whclob_default_alloc_policy; <
96 return old; <
97 } <
98 whclob_alloc_policy_t whclob_set_alloc_policy( whclob * cb, whclob_alloc_policy_t f ) <
99 { <
100 RePol old = cb ? cb->allocPolicy : 0; <
101 if( cb ) cb->allocPolicy = f; <
102 return old; <
103 } <
104 <
105 <
106 #define WHCLOB_DUMP(X,B) if(WHCLOB_DEBUG) { printf(X ": blob [%s]: ", # B ); whclob_dump(B,1); } <
107 void whclob_dump( whclob * cb, int doString ) <
108 { <
109 whclob * dest = whclob_new(); <
110 if( ! dest ) return; <
111 whclob_appendf( dest, <
112 "whclob@%p[nUsed=%d, nAlloc=%d, nCursor=%d][data@%p]", <
113 cb, cb->nUsed, cb->nAlloc, cb->nCursor, cb->aData <
114 ); <
115 if( doString ) <
116 { <
117 if( cb->nAlloc && cb->aData[0] ) <
118 { <
119 whclob_appendf( dest, "=[%s]", whclob_buffer(cb) ); <
120 } <
121 else <
122 { <
123 whclob_appendf( dest, "=[NULL]", cb ); <
124 } <
125 } <
126 fappendf( stderr, "%s\n", whclob_buffer( dest ) ); <
127 whclob_finalize( dest ); <
128 } <
129 <
130 <
131 long whclob_reset( whclob * cb ) <
132 { <
133 if( cb ) <
134 { <
135 #if WHCLOB_DEBUG <
136 printf( "Freeing clob @ [%p], bytes=%ld\n", cb, cb->nAlloc ); <
137 /* endless loop: whclob_dump(cb,1); */ <
138 #endif <
139 if( cb->nAlloc ) <
140 { <
141 /* crash? memset( cb->aData, 0, cb->nAlloc ); */ <
142 free( cb->aData ); <
143 cb->aData = 0; <
144 } <
145 *cb = Clob_empty; <
146 return whclob_rc.OK; <
147 } <
148 return whclob_rc.UnexpectedNull; <
149 } <
150 <
151 long whclob_finalize( whclob * cb ) <
152 { <
153 if( ! cb ) return whclob_rc.UnexpectedNull; <
154 whclob_reset(cb); <
155 free( cb ); <
156 return whclob_rc.OK; <
157 } <
158 <
159 void whclob_force_in_bounds( whclob * cb ) <
160 { <
161 if( cb->nUsed > cb->nAlloc ) cb->nUsed = (cb->nAlloc ? (cb->nAlloc - 1) : 0); <
162 if( cb->nCursor > cb->nUsed ) cb->nCursor = cb->nUsed; <
163 } <
164 <
165 static long whclob_do_resize( whclob * cb, <
166 unsigned int sz, <
167 short usePolicyHint) <
168 { <
169 static const int fudge = 2; <
170 char const * zOld = 0; <
171 long oldUsed = 0; <
172 long oldAlloc = 0; <
173 long allocsize = 0; <
174 char * pNew = 0; <
175 if( !cb ) return whclob_rc.UnexpectedNull; <
176 if( cb->nAlloc == (long)sz ) return cb->nAlloc; <
177 /* ^^^ over-allocate by 1 to ensure we have space for <
178 a trailing 0. */ <
179 /* const int shrinkage = 16; */ <
180 /* if we can save more than this much, then try to do so. */ <
181 if( 0 == sz ) <
182 { <
183 whclob_reset( cb ); <
184 return 0; <
185 } <
186 zOld = cb->aData; <
187 oldUsed = cb->nUsed; <
188 oldAlloc = cb->nAlloc; <
189 allocsize = 0; <
190 if( (usePolicyHint && (0 != cb->allocPolicy)) ) <
191 { <
192 allocsize = cb->allocPolicy(sz); <
193 } <
194 else if( (usePolicyHint && (0 != whclob_current_alloc_policy)) ) <
195 { <
196 allocsize = (*whclob_current_alloc_policy)(sz); <
197 } <
198 else <
199 { <
200 allocsize = (long)sz; <
201 } <
202 allocsize += fudge; <
203 if( allocsize < (fudge + (long)sz) ) allocsize = fudge + sz; <
204 #if 0 <
205 pNew = cb->aData /* oldAlloc */ <
206 ? realloc( cb->aData, allocsize ) <
207 : malloc( fudge + allocsize ); <
208 #else <
209 pNew = realloc( cb->aData, allocsize ); <
210 #endif <
211 if( ! pNew ) return whclob_rc.AllocError; <
212 /* if( !oldAlloc ) */ <
213 if( ! cb->aData ) <
214 { /** cb has/had no data */ <
215 if( zOld ) <
216 { /* cb was pointing to shared data. Copy it. */ <
217 memcpy( pNew, zOld, (oldUsed > allocsize) ? allocsize : oldUsed ); <
218 } <
219 else <
220 { /* cb had no buffer - create one. */ <
221 memset( pNew, 0, allocsize ); <
222 cb->nUsed = cb->nCursor = 0; <
223 } <
224 } <
225 else <
226 { /** cb had data and we realloced. Zero out any new <
227 memory. */ <
228 if( oldAlloc && (oldAlloc < allocsize) ) <
229 { <
230 memset( pNew + oldAlloc, 0, allocsize - oldAlloc); <
231 } <
232 } <
233 pNew[allocsize-fudge] = 0; <
234 cb->aData = pNew; <
235 cb->nAlloc = allocsize; <
236 whclob_force_in_bounds( cb ); <
237 return cb->nAlloc; <
238 } <
239 <
240 long whclob_reserve( whclob * cb, unsigned int sz ) <
241 { <
242 long rc = cb->nAlloc; <
243 if( ((long)sz > cb->nAlloc) || (sz==0) ) <
244 { <
245 rc = whclob_do_resize( cb, sz, 1 ); <
246 } <
247 return rc; <
248 } <
249 <
250 long whclob_size( whclob const * cb ) { return cb ? cb->nUsed : whclob_rc.UnexpectedNull; } <
251 long whclob_capacity( whclob const * cb ) { return cb ? cb->nAlloc : whclob_rc.UnexpectedNull; } <
252 char * whclob_buffer( whclob * cb ) { return cb ? cb->aData : 0; } <
253 char const * whclob_bufferc( whclob const * cb ) { return cb ? cb->aData : 0; } <
254 <
255 long whclob_resize( whclob * cb, unsigned int sz ) <
256 { <
257 unsigned long ret = whclob_do_resize( cb, sz, 1 ); <
258 if( sz && (ret >= sz) ) <
259 { <
260 cb->nUsed = sz; <
261 cb->aData[sz] = 0; <
262 } <
263 return ret; <
264 } <
265 <
266 #if 0 <
267 /* <
268 NOT part of the public API! <
269 <
270 sz is forced into bounds (>=0 and <=cb->nAlloc) then cb->nUsed is <
271 set to sz. cb->aData[sz] is set to 0 to enforce the null-termination <
272 policy. <
273 */ <
274 static long whclob_set_used_size( whclob * cb, long sz ) <
275 { <
276 if( sz < 0 ) sz = 0; <
277 else if( sz > cb->nAlloc ) sz = cb->nAlloc-1; <
278 cb->nUsed = sz; <
279 cb->aData[sz] = 0; <
280 return sz; <
281 } <
282 #endif /* 0|1 */ <
283 <
284 whclob * whclob_new_n( size_t reserved ) <
285 { <
286 whclob * c = 0; <
287 whclob_init( &c, 0, (long)reserved ); <
288 return c; <
289 } <
290 whclob * whclob_new() <
291 { <
292 return whclob_new_n(0); <
293 } <
294 <
295 <
296 long whclob_init( whclob ** cb, char const * data, long n ) <
297 { <
298 long rc = 0; <
299 if( ! cb ) <
300 { <
301 return whclob_rc.UnexpectedNull; <
302 } <
303 *cb = (whclob *) malloc( sizeof(whclob) ); <
304 if( ! *cb ) <
305 { <
306 return whclob_rc.AllocError; <
307 } <
308 *(*cb) = Clob_empty; <
309 if( !data ) <
310 { <
311 if( n < 1 ) return whclob_rc.OK; <
312 } <
313 else <
314 { <
315 if( !n ) return whclob_rc.OK; <
316 } <
317 if( data && (n < 0) ) n = strlen( data ); <
318 #if 1 <
319 rc = whclob_reserve( *cb, n ); <
320 //rc = whclob_resize( *cb, n ); <
321 if( rc < whclob_rc.OK ) <
322 { <
323 free( *cb ); <
324 *cb = 0; <
325 return rc; <
326 } <
327 if( data ) <
328 { <
329 memcpy( (*cb)->aData, data, n ); <
330 } <
331 #else <
332 rc = whclob_append( *cb, data, n ); <
333 if( rc < whclob_rc.OK ) <
334 { <
335 free( *cb ); <
336 *cb = 0; <
337 return rc; <
338 } <
339 #endif <
340 return whclob_rc.OK; <
341 } <
342 <
343 <
344 long whclob_seek( whclob * cb, long offset, int whence ) <
345 { <
346 long pos = cb->nCursor; <
347 switch( whence ) <
348 { <
349 case WHCLOB_SEEK_SET: <
350 pos = offset; <
351 break; <
352 case WHCLOB_SEEK_CUR: <
353 pos += offset; <
354 break; <
355 case WHCLOB_SEEK_END: <
356 pos = cb->nUsed + offset; <
357 break; <
358 default: <
359 return whclob_rc.RangeError; <
360 }; <
361 if( pos < 0 ) pos = 0; <
362 else if( pos > cb->nUsed ) pos = cb->nUsed; <
363 return (cb->nCursor = pos); <
364 } <
365 <
366 void whclob_rewind( whclob * cb ) <
367 { <
368 cb->nCursor = 0; <
369 } <
370 <
371 long whclob_tell( whclob const * cb ) <
372 { <
373 return cb->nCursor; <
374 } <
375 <
376 long whclob_pos_in_bounds( whclob * cb, long pos ) <
377 { <
378 return (cb && (pos >= 0) && (pos < cb->nUsed)) <
379 ? whclob_rc.OK <
380 : whclob_rc.RangeError; <
381 } <
382 <
383 long whclob_char_filln( whclob * cb, char ch, long startPos, long n ) <
384 { <
385 long rc = 0; <
386 if( ! cb->nAlloc ) return whclob_rc.Err; <
387 if( n <= 0 ) return whclob_rc.RangeError; <
388 rc = whclob_pos_in_bounds(cb,startPos); <
389 if( whclob_rc.OK != rc ) return rc; <
390 /* if( whclob_rc.OK == rc ) rc = whclob_is_in_bounds(cb,startPos + n); */ <
391 if( (startPos + n) > cb->nAlloc ) n = cb->nAlloc - startPos; <
392 memset( cb->aData + startPos, ch, n ); <
393 return n; <
394 } <
395 <
396 long whclob_zero_fill( whclob * cb ) <
397 { <
398 return whclob_char_filln( cb, '\0', 0, cb->nAlloc ); <
399 } <
400 <
401 /** <
402 This function ensures that the one-past-the-last item in the blob <
403 to 0. The "used" size of cb does not change. <
404 <
405 Returns one of the values defined in whclob_rc: <
406 <
407 - whclob_rc.AllocError if a memory (re)allocation fails. <
408 <
409 - whclob_rc.OK on success. <
410 */ <
411 long whclob_null_terminate( whclob * cb ) <
412 { <
413 if( ! cb->nAlloc ) return whclob_rc.Err; /* do not modify a data obj we don't own. */ <
414 if( (cb->nUsed + 1) >= cb->nAlloc ) <
415 { <
416 long rc = whclob_reserve( cb, cb->nUsed + 1 ); <
417 if( rc < whclob_rc.OK ) return rc; <
418 } <
419 cb->aData[cb->nUsed] = 0; <
420 return whclob_rc.OK; <
421 } <
422 <
423 /** <
424 Writes n bytes of data from cb, starting at startPos. It expands cb <
425 if needed. It does NOT move the cursor. <
426 <
427 If n is -1 then strlen(data) is used for n. <
428 <
429 On success returns the number of bytes added. On failure it returns <
430 a negative integer error code defined in whclob_rc. If either data or <
431 dsize are 0 then 0 is returned. If cb is null then <
432 whclob_rc.UnexpectedNull is returned. <
433 */ <
434 static long whclob_writeat( whclob * cb, long startPos, char const * data, long dsize ) <
435 { <
436 if( ! cb ) return whclob_rc.UnexpectedNull; <
437 if( ! data || !dsize ) return 0; <
438 if( dsize < 0 ) dsize = strlen(data); <
439 if( (startPos + dsize) >= cb->nAlloc ) <
440 { <
441 long allocsz = startPos + dsize; /* + (cb->nAlloc * 11 / 20); */ <
442 long rc = whclob_reserve( cb, allocsz ); <
443 if( rc < whclob_rc.OK ) return rc; <
444 } <
445 memcpy( cb->aData + startPos, data, dsize ); <
446 return dsize; <
447 } <
448 <
449 <
450 long whclob_write( whclob * cb, char const * data, long dsize ) <
451 { <
452 long old = cb->nCursor; <
453 WHCLOB_DUMP("whclob_write()", cb ); <
454 cb->nCursor += whclob_writeat( cb, cb->nCursor, data, dsize ); <
455 if( cb->nUsed < cb->nCursor ) <
456 { <
457 cb->nUsed = cb->nCursor; <
458 } <
459 WHCLOB_DUMP("whclob_write()", cb ); <
460 return cb->nCursor - old; <
461 } <
462 <
463 <
464 long whclob_append( whclob * cb, char const * data, long dsize ) <
465 { <
466 long old = cb->nUsed; <
467 long rc = whclob_writeat( cb, cb->nUsed, data, dsize ); <
468 if( rc < whclob_rc.OK ) return rc; <
469 cb->nUsed += rc; <
470 //cb->aData[cb->nUsed] = 0; <
471 whclob_null_terminate(cb); <
472 return cb->nUsed - old; <
473 } <
474 <
475 long whclob_append_char_n( whclob * cb, char c, long n ) <
476 { <
477 long rc = 0; <
478 if( !cb || (n <= 0) ) return whclob_rc.RangeError; <
479 rc = whclob_reserve( cb, cb->nUsed + n ); <
480 if( rc < 0 ) return rc; <
481 memset( cb->aData + cb->nUsed, c, n ); <
482 cb->nUsed += n; <
483 /* do we want to do a whclob_null_terminate() here? */ <
484 /* whclob_null_terminate(cb); */ <
485 return n; <
486 } <
487 <
488 <
489 long whclob_copy( whclob * src, whclob * dest ) <
490 { <
491 long allocsz = 0; <
492 long rc = 0; <
493 if( src == dest ) return whclob_rc.RangeError; <
494 if( src->aData == dest->aData ) return whclob_rc.RangeError; <
495 allocsz = src->nAlloc; <
496 WHCLOB_DUMP( "copy src before",src ); <
497 WHCLOB_DUMP( "copy dest before",dest ); <
498 whclob_reset( dest ); <
499 rc = whclob_reserve( dest, allocsz ); <
500 if( rc < whclob_rc.OK ) return rc; <
501 dest->nUsed = src->nUsed; <
502 dest->nAlloc = allocsz; <
503 dest->nCursor = src->nCursor; <
504 memcpy( dest->aData, src->aData, allocsz ); <
505 WHCLOB_DUMP( "copy src after",src ); <
506 WHCLOB_DUMP( "copy dest after",dest ); <
507 return whclob_rc.OK; <
508 } <
509 <
510 long whclob_copy_slice( whclob * src, whclob * dest, long startPos, long n ) <
511 { <
512 long bpos = 0; <
513 long epos = 0; <
514 long ret = 0; <
515 if( ! src || !dest ) return whclob_rc.UnexpectedNull; <
516 if( n<1 ) return whclob_rc.RangeError; <
517 if( whclob_rc.OK != whclob_pos_in_bounds( src, startPos ) ) return whclob_rc.RangeError; <
518 bpos = startPos; <
519 if( bpos >= src->nUsed ) return 0; <
520 epos = bpos + n; /* 1-past-end marker */ <
521 if( epos > src->nUsed ) epos = src->nUsed; <
522 ret = whclob_append( dest, src->aData + bpos, epos - bpos ); <
523 return ret; <
524 } <
525 <
526 long whclob_read( whclob * src, whclob * dest, long n ) <
527 { <
528 long bpos = 0; <
529 long epos = 0; <
530 long ret = 0; <
531 if( ! src || !dest || n<1 ) return 0; <
532 bpos = src->nCursor; <
533 if( bpos == src->nUsed ) return 0; <
534 epos = bpos + n; /* 1-past-end marker */ <
535 if( epos > src->nUsed ) epos = src->nUsed; <
536 ret = whclob_append( dest, src->aData + bpos, epos - bpos ); <
537 src->nCursor += ret; <
538 return ret; <
539 } <
540 <
541 long whclob_truncate( whclob * cb, long pos, int memPolicy ) <
542 { <
543 long rc = 0; <
544 if( ! cb ) return whclob_rc.UnexpectedNull; <
545 /* if( cb->nUsed <= pos ) return whclob_rc.OK; */ <
546 <
547 if( pos < cb->nAlloc ) <
548 { /* adding a single \0 to the data isn't sufficient here. */ <
549 memset( cb->aData + pos, 0, (cb->nAlloc-pos)); <
550 } <
551 <
552 if( cb->nAlloc <= pos ) <
553 { <
554 //return whclob_rc.OK; <
555 memPolicy = 1; <
556 } <
557 rc = whclob_rc.OK; <
558 if( memPolicy > 0 ) <
559 { <
560 rc = whclob_reserve( cb, pos ); <
561 } <
562 else if( memPolicy < 0 ) <
563 { <
564 #if 0 <
565 /* try a simple heuristic to calculate whether a <
566 realloc is worth it... */ <
567 const long diff = (cb->nAlloc - pos); <
568 const int rel = 4; /* ((diff) >= (cb->nAlloc/rel)) = do realloc */ <
569 const int abs = 512; /* (diff >= abs) = do realloc */ <
570 if( <
571 ( diff >= abs ) <
572 || <
573 ((diff) >= (cb->nAlloc/rel) ) <
574 ) <
575 { <
576 /* rc = whclob_resize( cb, cb->nUsed ); */ <
577 rc = whclob_do_resize( cb, pos, 0 ); <
578 } <
579 #else <
580 //MARKER("TRUNCATE alloc=%ld len=%ld\n", cb->nAlloc, cb->nUsed ); <
581 rc = whclob_resize( cb, pos ); <
582 /* rc = whclob_do_resize( cb, cb->nUsed, 0 ); */ <
583 //MARKER("TRUNCATED: alloc=%ld len=%ld, rc=%ld\n", cb->nAlloc, cb->nUsed, rc ); <
584 #endif <
585 } <
586 cb->nUsed = pos; <
587 //whclob_null_terminate( cb ); <
588 return rc; <
589 } <
590 <
591 <
592 long whclob_memmove( whclob * cb, int start1, int n, int start2 ) <
593 { <
594 return whclob_memmove_fill( cb, 0, start1, n, start2 ); <
595 } <
596 long whclob_memmove_fill( whclob * cb, char const filler, int start1, int n, int start2 ) <
597 { <
598 char * src = 0; <
599 char * dest = 0; <
600 long pos = 0; /* here we'll take a long "pos" ... */ <
601 if( ! cb ) return whclob_rc.UnexpectedNull; <
602 if( <
603 ( (n<1) || (start2 == start1) ) <
604 || <
605 (whclob_rc.OK != whclob_pos_in_bounds(cb,start1)) <
606 || <
607 (whclob_rc.OK != whclob_pos_in_bounds(cb,start1+n)) <
608 || <
609 (whclob_rc.OK != whclob_pos_in_bounds(cb,start2)) <
610 || <
611 (whclob_rc.OK != whclob_pos_in_bounds(cb,start2+n)) <
612 ) <
613 { <
614 return whclob_rc.RangeError; <
615 } <
616 src = cb->aData + start1; <
617 dest = cb->aData + start2; <
618 pos = 0; <
619 while( pos < n ) <
620 { <
621 dest[start2++] = src[pos]; <
622 src[pos++] = filler; <
623 } <
624 return n; <
625 } <
626 <
627 /** <
628 Swaps n bytes of memory contents between m1 and m2. No bounds <
629 checking is (or can be) done here, so m1 and m2 must both be large <
630 enough for the given start1, start2, and n parameters. <
631 */ <
632 static long memswap( char * m1, <
633 long n, <
634 char * m2 ) <
635 { <
636 char buf; <
637 long pos = 0; <
638 for( ; pos < n; ++pos ) <
639 { <
640 buf = m2[pos]; <
641 m2[pos] = m1[pos]; <
642 m1[pos] = buf; <
643 } <
644 return pos; <
645 } <
646 <
647 long whclob_memswap( whclob * c1, int start1, int n, whclob * c2, int start2 ) <
648 { <
649 if( ! c1 || ! c2 ) return whclob_rc.UnexpectedNull; <
650 if( <
651 ( (n<1) ) <
652 || <
653 (whclob_rc.OK != whclob_pos_in_bounds(c1,start1)) <
654 || <
655 (whclob_rc.OK != whclob_pos_in_bounds(c1,start1+n)) <
656 || <
657 (whclob_rc.OK != whclob_pos_in_bounds(c2,start2)) <
658 || <
659 (whclob_rc.OK != whclob_pos_in_bounds(c2,start2+n)) <
660 ) <
661 { <
662 return whclob_rc.RangeError; <
663 } <
664 return memswap( c1->aData + start1, n, c2->aData + start2 ); <
665 } <
666 <
667 <
668 long whclob_swap( whclob * c1, whclob * c2 ) <
669 { <
670 whclob x; <
671 if( ! c1 || ! c2 ) return whclob_rc.UnexpectedNull; <
672 x = *c1; <
673 *c1 = *c2; <
674 *c2 = x; <
675 return whclob_rc.OK; <
676 } <
677 <
678 long whclob_clone( whclob * src, whclob ** dest ) <
679 { <
680 long rc = 0; <
681 if( ! src ) return whclob_rc.UnexpectedNull; <
682 rc = whclob_init( dest, src->aData, src->nUsed ); <
683 if( whclob_rc.OK != rc ) return rc; <
684 memcpy( (*dest)->aData, src->aData, src->nUsed ); <
685 (*dest)->nUsed = src->nUsed; <
686 (*dest)->nCursor = src->nCursor; <
687 return whclob_rc.OK; <
688 } <
689 <
690 /** <
691 A whclob vappendf_appender implementation. It assumes that <
692 arg is a (whclob *) and uses whclob_append() to push <
693 all data to that clob. <
694 <
695 If s is null then 0 is returned. <
696 <
697 Returns the number of bytes appended. <
698 */ <
699 static long whclob_vappendf_appender( void * arg, char const * s, long n ) <
700 { <
701 whclob * c = (whclob *)arg; <
702 if( ! c ) return 0; <
703 return whclob_append( c, s, n ); <
704 } <
705 <
706 long whclob_vappendf( whclob * cb, char const * fmt, va_list vargs ) <
707 { <
708 return vappendf( whclob_vappendf_appender, cb, fmt, vargs ); <
709 } <
710 <
711 long whclob_appendf( whclob * cb, const char * fmt, ... ) <
712 { <
713 va_list vargs; <
714 long ret = 0; <
715 va_start( vargs, fmt ); <
716 ret = whclob_vappendf( cb, fmt, vargs ); <
717 va_end(vargs); <
718 return ret; <
719 } <
720 <
721 <
722 <
723 long whclob_export( whclob const * cb, void * varg, whclob_exporter pf ) <
724 { <
725 if( ! cb->nAlloc ) return whclob_rc.UnexpectedNull; <
726 return pf( varg, cb->aData, cb->nUsed ); <
727 } <
728 <
729 <
730 long whclob_import( whclob * dest, void * arg, whclob_importer pf ) <
731 { <
732 return pf( dest, arg ); <
733 } <
734 <
735 <
736 char * whclob_vmprintf( char const * fmt, va_list vargs ) <
737 { <
738 whclob * buf = 0; <
739 char * ret = 0; <
740 if( whclob_rc.OK != whclob_init(&buf,0,0) ) return 0; <
741 whclob_vappendf( buf, fmt, vargs ); <
742 ret = buf->aData; <
743 *buf = Clob_empty; <
744 whclob_finalize( buf ); <
745 return ret; <
746 } <
747 char * whclob_mprintf( char const * fmt, ... ) <
748 { <
749 va_list vargs; <
750 char * ret = 0; <
751 va_start( vargs, fmt ); <
752 ret = whclob_vmprintf( fmt, vargs ); <
753 va_end(vargs); <
754 return ret; <
755 } <
756 <
757 char * whclob_take_buffer( whclob * cb ) <
758 { <
759 char * c = cb->aData; <
760 *cb = Clob_empty; <
761 return c; <
762 } <
763 <
764 <
765 <
766 #if WHCLOB_USE_ZLIB <
767 /* ! whclob_zheader_prefix == magic cookie for our compressed whclob.header */ <
768 static char const whclob_zheader_version = '1'; <
769 static char const * whclob_zheader_prefix = "clob32"; <
770 static int const whclob_zheader_prefix_len = 7; /* ^^^^ must be 1 + strlen(whclob_zheader_prefix)! */ <
771 /* ! whclob_zheader_lensize == number of bytes used to store size in compressed data */ <
772 static short const whclob_zheader_lensize = 4; <
773 /* ! whclob_zheader_crcsize == number of bytes used to store size in compressed data */ <
774 static short const whclob_zheader_crcsize = 4; <
775 static int const whclob_zheader_size = 15; /* 1 + prefix_len + lensize + whclob_zheader_crcsize */ <
776 <
777 /** <
778 Stamps the initial header in cIn, which must be an initialized clob <
779 with at least whclob_zheader_size bytes allocated. srcSize must be <
780 the decompressed size of data which will presumably be compressed <
781 into the cIn clob at some point and crc must be the adler32 <
782 checksum of the uncompressed data. Returns whclob_zheader_size on <
783 success, or a negative number on error. <
784 */ <
785 static int whclob_write_zheader( whclob * cIn, unsigned int srcSize, unsigned long crc ) <
786 { <
787 if( whclob_size(cIn) < whclob_zheader_size ) <
788 { <
789 return whclob_rc.RangeError; <
790 } <
791 whclob_writeat( cIn, 0, whclob_zheader_prefix, whclob_zheader_prefix_len ); <
792 { <
793 int i = whclob_zheader_prefix_len - 1; <
794 unsigned char * oBuf = (unsigned char *)whclob_buffer(cIn); <
795 oBuf[i++] = whclob_zheader_version; <
796 oBuf[i++] = srcSize>>24 & 0xff; <
797 oBuf[i++] = srcSize>>16 & 0xff; <
798 oBuf[i++] = srcSize>>8 & 0xff; <
799 oBuf[i++] = srcSize & 0xff; <
800 <
801 oBuf[i++] = crc>>24 & 0xff; <
802 oBuf[i++] = crc>>16 & 0xff; <
803 oBuf[i++] = crc>>8 & 0xff; <
804 oBuf[i++] = crc & 0xff; <
805 /* MARKER; printf( "Writing zsize header at pos %d-%d: %u\n", whclob_zheader_prefix_len, i, srcSize ); */ <
806 MARKER( "Writing zsize header: version=%c uSize=%u adler32=%lx\n", whclob_zheader_version, srcSize, crc ); <
807 } <
808 return whclob_zheader_size; <
809 } <
810 <
811 /** <
812 Checks first bytes of cIn to see if this is data compressed <
813 by this API. If it is, the decompressed size of the compressed <
814 data is set in sz and the adler32 checksum of the uncompressed <
815 data is written to crc. On success 0 or greater is returned, else <
816 a negative value from whclob_rc is returned: <
817 <
818 - whclob_rc.RangeError: cIn is too small to contain the header or <
819 the header was written by a different API version. <
820 <
821 - whclob_rc.ArgError: header seems to be invalid, or maybe not <
822 produced by the same version of this API. <
823 <
824 */ <
825 static int whclob_confirm_zheader( whclob const * cIn, unsigned int * sz, unsigned long * crc ) <
826 { <
827 int i; <
828 char ver; <
829 if( whclob_size(cIn) < whclob_zheader_size ) <
830 { <
831 return whclob_rc.RangeError; <
832 } <
833 unsigned char const * inBuf = (unsigned char *) whclob_bufferc(cIn); <
834 for( i = 0; i < (whclob_zheader_prefix_len-1); ++i, ++inBuf ) <
835 { <
836 if( *inBuf != whclob_zheader_prefix[i] ) <
837 { <
838 return whclob_rc.ArgError; <
839 } <
840 /* MARKER( "confirm header: %c\n", *inBuf ); */ <
841 } <
842 /* MARKER( "confirm header: %d\n", *inBuf ); */ <
843 inBuf = (unsigned const char *) whclob_bufferc(cIn) + (whclob_zheader_prefix_len - 1); <
844 ver = *inBuf; <
845 if( ver != whclob_zheader_version ) <
846 { <
847 return whclob_rc.RangeError; <
848 } <
849 ++inBuf; <
850 /* MARKER( "confirm header: %d\n", *inBuf ); */ <
851 *sz = (inBuf[0]<<24) + (inBuf[1]<<16) + (inBuf[2]<<8) + inBuf[3]; <
852 *crc = (inBuf[4]<<24) + (inBuf[5]<<16) + (inBuf[6]<<8) + inBuf[7]; <
853 /* MARKER( "header says zsize == %u\n", *sz ); */ <
854 /* MARKER( "header says adler32 == %lx\n", *crc ); */ <
855 return whclob_rc.OK; <
856 } <
857 <
858 <
859 int whclob_compress( whclob * cIn, whclob * cOut ) <
860 { <
861 const unsigned int szIn = whclob_size(cIn); <
862 const unsigned int szOut = 13 + szIn + (szIn+999)/1000; <
863 unsigned long nOut; <
864 int rc; <
865 whclob * tmp; <
866 unsigned long adler; <
867 tmp = 0; <
868 if( cOut != cIn ) whclob_reset(cOut); <
869 nOut = (long int) szOut; <
870 rc = whclob_init( &tmp, 0, nOut+whclob_zheader_size ); <
871 if( 0 != rc ) return rc; <
872 <
873 adler = adler32(0L, Z_NULL, 0); <
874 adler = adler32( adler, (const Byte *) whclob_bufferc(cIn), szIn ); <
875 /* MARKER( "adler=%lx\n", adler ); */ <
876 whclob_write_zheader( tmp, szIn, adler ); <
877 rc = compress( (unsigned char *)(whclob_buffer(tmp) + whclob_zheader_size), <
878 &nOut, <
879 (unsigned char *)whclob_buffer(cIn), <
880 szIn ); <
881 if( Z_OK != rc ) <
882 { <
883 whclob_finalize(tmp); <
884 return whclob_rc.IOError; <
885 } <
886 if( cOut == cIn ) <
887 { <
888 whclob_reset(cOut); <
889 } <
890 <
891 rc = whclob_resize( tmp, nOut+whclob_zheader_size ); <
892 if( rc < (nOut+whclob_zheader_size) ) <
893 { <
894 whclob_finalize( tmp ); <
895 return rc; <
896 } <
897 whclob_swap( cOut, tmp ); <
898 whclob_finalize( tmp ); <
899 return whclob_rc.OK; <
900 } <
901 <
902 <
903 <
904 int whclob_uncompress(whclob *pIn, whclob *pOut) <
905 { <
906 unsigned int unzSize; <
907 unsigned int nIn = whclob_size(pIn); <
908 whclob * temp; <
909 int rc; <
910 unsigned long int nOut2; <
911 unsigned long adlerExp; <
912 unsigned long adlerGot; <
913 if( nIn<=4 ) <
914 { <
915 /* MARKER; */ <
916 return whclob_rc.Err; <
917 } <
918 if( pOut != pIn ) whclob_reset(pOut); <
919 <
920 rc = whclob_confirm_zheader( pIn, &unzSize, &adlerExp ); <
921 /* MARKER( "zsize = %u\n", unzSize ); */ <
922 /* MARKER( "zsize = %u, adlerExp=%lx\n", unzSize, adlerExp ); */ <
923 if( whclob_rc.OK > rc) <
924 { <
925 /* MARKER; */ <
926 return rc; <
927 } <
928 rc = whclob_init(&temp,0,unzSize+1); <
929 if( whclob_rc.OK != rc ) <
930 { <
931 /* MARKER; */ <
932 return rc; <
933 } <
934 <
935 { <
936 unsigned char *inBuf; <
937 inBuf = (unsigned char*) (whclob_buffer(pIn) + whclob_zheader_size); <
938 nOut2 = whclob_size( temp ); <
939 /* MARKER( "nOut2 = %ld\n", nOut2 ); */ <
940 /* MARKER( "input length = %u\n", nIn - whclob_zheader_size ); */ <
941 /* MARKER( "zsize = %u\n", unzSize ); */ <
942 /* MARKER( "zblob size = %u\n",nIn ); */ <
943 rc = uncompress((unsigned char*)whclob_buffer(temp), &nOut2, <
944 inBuf, nIn - whclob_zheader_size); <
945 } <
946 if( rc!=Z_OK ) <
947 { <
948 /* MARKER; */ <
949 whclob_finalize(temp); <
950 return whclob_rc.IOError; <
951 } <
952 adlerGot = adler32(0L,Z_NULL,0); <
953 adlerGot = adler32( adlerGot, (Bytef const *) whclob_bufferc(temp), nOut2 ); <
954 if( adlerGot != adlerExp ) <
955 { <
956 /* MARKER( "adler32 mismatch: %lx != %lx\n", adlerExp, adlerGot ); */ <
957 return whclob_rc.RangeError; <
958 } <
959 <
960 rc = whclob_resize(temp, nOut2); <
961 if( rc < nOut2 ) <
962 { <
963 /* MARKER; */ <
964 whclob_finalize(temp); <
965 return rc; <
966 } <
967 whclob_swap( temp, pOut ); <
968 whclob_finalize(temp); <
969 return whclob_rc.OK; <
970 } <
971 <
972 int whclob_deflate( whclob *cIn, whclob *cOut ) <
973 { <
974 const int kludge = 4; <
975 z_stream zS; <
976 unsigned int szIn = whclob_size(cIn); <
977 unsigned int szOut = kludge + 13 + szIn + (szIn+999)/1000; <
978 int rc; <
979 whclob * tmp; <
980 tmp = 0; <
981 zS.zalloc = Z_NULL; <
982 zS.zfree = Z_NULL; <
983 zS.opaque = Z_NULL; <
984 <
985 if( cOut != cIn ) whclob_reset(cOut); <
986 rc = whclob_init( &tmp, 0, szOut ); <
987 if( 0 != rc ) <
988 { <
989 return rc; <
990 } <
991 <
992 { <
993 unsigned char * cBuf; <
994 cBuf = (unsigned char *) whclob_buffer(tmp); <
995 cBuf[0] = szIn>>24 & 0xff; <
996 cBuf[1] = szIn>>16 & 0xff; <
997 cBuf[2] = szIn>>8 & 0xff; <
998 cBuf[3] = szIn & 0xff; <
999 <
1000 zS.next_in = (Bytef*) whclob_buffer(cIn); <
1001 zS.avail_in = whclob_size(cIn); <
1002 zS.next_out = (Bytef*) (cBuf + kludge); <
1003 zS.avail_out = szOut; <
1004 } <
1005 <
1006 if( Z_OK != deflateInit( &zS, Z_DEFAULT_COMPRESSION ) ) <
1007 { <
1008 whclob_finalize(tmp); <
1009 return whclob_rc.IOError; <
1010 } <
1011 <
1012 /* printf("sizes: in=%d out=%d\n", zS.avail_in, zS.avail_out ); */ <
1013 <
1014 rc = deflate( &zS, Z_FINISH ); <
1015 szOut = szOut - zS.avail_out; <
1016 deflateEnd( &zS ); <
1017 /* printf("deflate() rc == %d\n", rc ); */ <
1018 /* printf("sizes: in=%d out=%d\n", zS.avail_in, zS.avail_out ); */ <
1019 if( Z_STREAM_END != rc ) <
1020 { <
1021 /* printf("deflate() rc == %d\n", rc ); */ <
1022 whclob_finalize(tmp); <
1023 return whclob_rc.IOError; <
1024 } <
1025 if( cOut == cIn ) <
1026 { <
1027 whclob_reset(cOut); <
1028 } <
1029 rc = whclob_resize( tmp, szOut ); <
1030 if( rc < (szOut) ) <
1031 { <
1032 whclob_finalize( tmp ); <
1033 return rc; <
1034 } <
1035 whclob_swap( cOut, tmp ); <
1036 whclob_finalize( tmp ); <
1037 return whclob_rc.OK; <
1038 } <
1039 <
1040 <
1041 int whclob_inflate(whclob *cIn, whclob *cOut) <
1042 { <
1043 unsigned int uSize; <
1044 unsigned int nIn = whclob_size(cIn); <
1045 whclob * temp; <
1046 int rc; <
1047 z_stream zS; <
1048 const int kludge = 4; <
1049 unsigned int infSize; <
1050 zS.zalloc = Z_NULL; <
1051 zS.zfree = Z_NULL; <
1052 zS.opaque = Z_NULL; <
1053 <
1054 if( cOut != cIn ) whclob_reset(cOut); <
1055 if( nIn<=kludge ) <
1056 { <
1057 return whclob_rc.Err; <
1058 } <
1059 <
1060 <
1061 { <
1062 unsigned char * cBuf = (unsigned char *) whclob_buffer(cIn); <
1063 uSize = (cBuf[0]<<24) + (cBuf[1]<<16) + (cBuf[2]<<8) + cBuf[3]; <
1064 } <
1065 rc = whclob_init( &temp, 0, uSize + (uSize * 10 / 100)); <
1066 if( whclob_rc.OK != rc ) <
1067 { <
1068 return rc; <
1069 } <
1070 /* fprintf(stderr,"uSize = %u, whclob_capacity(temp) = %ld\n", uSize, whclob_capacity(temp) ); */ <
1071 zS.avail_out = whclob_capacity(temp); <
1072 zS.next_out = (Bytef*) whclob_buffer(temp); <
1073 zS.next_in = (Bytef*) (whclob_buffer(cIn) + kludge); <
1074 zS.avail_in = whclob_size(cIn) - kludge; <
1075 <
1076 /* fprintf(stderr,"avail_in == %d avail_out == %d\n", zS.avail_in, zS.avail_out ); */ <
1077 <
1078 rc = inflateInit( &zS ); <
1079 if( Z_OK != rc ) <
1080 { <
1081 /* fprintf(stderr,"inflateInit() failed. rc == %d\n", rc ); */ <
1082 whclob_finalize(temp); <
1083 return whclob_rc.IOError; <
1084 } <
1085 /** weird: the return from inflate() is always an error (normally <
1086 Z_DATA_ERR) for me, but inflateEnd() succeeds and the data is <
1087 correct. <
1088 */ <
1089 rc = inflate( &zS, Z_FINISH ); <
1090 /* fprintf(stderr,"inflate() rc == %d\n", rc ); */ <
1091 infSize = whclob_capacity(temp) - zS.avail_out; <
1092 /* fprintf(stderr,"post: infSize == %d uSize == %d\n", infSize, uSize ); */ <
1093 /* fprintf(stderr,"post: avail_in == %d avail_out == %d\n", zS.avail_in, zS.avail_out ); */ <
1094 rc = inflateEnd( &zS ); <
1095 if( rc != Z_OK ) /* STREAM_END ) */ <
1096 { <
1097 /* fprintf(stderr, "inflate() rc == %d\n",rc); */ <
1098 whclob_finalize(temp); <
1099 return whclob_rc.IOError; <
1100 } <
1101 rc = whclob_resize(temp, infSize); <
1102 if( rc < infSize ) <
1103 { <
1104 whclob_finalize(temp); <
1105 return rc; <
1106 } <
1107 if( cOut == cIn ) whclob_reset(cOut); <
1108 whclob_swap( temp, cOut ); <
1109 whclob_finalize(temp); <
1110 return whclob_rc.OK; <
1111 } <
1112 #endif /* WHCLOB_USE_ZLIB */ <
1113 <
1114 #if WHCLOB_USE_FILE <
1115 long whclob_exporter_FILE( void * arg, char const * data, long n ) <
1116 { <
1117 FILE * fp = (FILE *) arg; <
1118 if( ! fp ) return whclob_rc.UnexpectedNull; <
1119 return (n == (long)fwrite( data, 1, n, fp )) <
1120 ? n <
1121 : whclob_rc.IOError; <
1122 } <
1123 <
1124 long whclob_export_FILE( whclob const * cb, FILE * dest ) <
1125 { <
1126 return whclob_export( cb, dest, whclob_exporter_FILE ); <
1127 } <
1128 <
1129 long whclob_exporter_filename( void * arg, char const * data, long n ) <
1130 { <
1131 char const * fname = (char const *)arg; <
1132 FILE * fp = 0; <
1133 long ret = 0; <
1134 if( ! fname ) return whclob_rc.UnexpectedNull; <
1135 fp = fopen( fname, "wb" ); <
1136 if( ! fp ) return whclob_rc.IOError; <
1137 ret = whclob_exporter_FILE( fp, data, n ); <
1138 fclose( fp ); <
1139 return ret; <
1140 } <
1141 <
1142 long whclob_export_filename( whclob const * cb, char const * dest ) <
1143 { <
1144 return whclob_export( cb, (char *)dest, whclob_exporter_filename ); <
1145 /* ^^ i hate that cast, but it's the least evil option here. */ <
1146 } <
1147 long whclob_importer_FILE( whclob * dest, void * arg ) <
1148 { <
1149 FILE * fp = (FILE *) arg; <
1150 long oldUsed = whclob_size(dest); <
1151 /*const long blocksize = 4096;*/ <
1152 #define blocksize 4096 <
1153 long rdsz = 0; <
1154 char * bcbuf[blocksize]; <
1155 int rc; <
1156 if( ! fp ) return whclob_rc.ArgError; <
1157 while( ! feof(fp) ) <
1158 { <
1159 rdsz = fread( bcbuf, sizeof(char), blocksize, fp ); <
1160 if( rdsz == 0 ) break; <
1161 rc = whclob_append( dest, (char const *)bcbuf, rdsz ); <
1162 if( rc < 0 ) <
1163 { <
1164 return rc; <
1165 } <
1166 } <
1167 #undef blocksize <
1168 return whclob_size(dest) - oldUsed; <
1169 } <
1170 <
1171 long whclob_importer_filename( whclob * dest, void * arg ) <
1172 { <
1173 char const * fname = (char const *)arg; <
1174 FILE * fh = 0; <
1175 long ret = 0; <
1176 if( ! fname ) return whclob_rc.ArgError; <
1177 fh = fopen( fname, "rb" ); <
1178 if( !fh ) <
1179 { <
1180 ret = whclob_rc.IOError; <
1181 } <
1182 else <
1183 { <
1184 ret = whclob_import( dest, fh, whclob_importer_FILE ); <
1185 fclose( fh ); <
1186 } <
1187 return ret; <
1188 } <
1189 <
1190 long whclob_import_FILE( whclob * dest, FILE * fp ) <
1191 { <
1192 return whclob_import( dest, fp, whclob_importer_FILE ); <
1193 } <
1194 <
1195 long whclob_import_filename( whclob * dest, char const * fn ) <
1196 { <
1197 return whclob_import( dest, (void*)fn, whclob_importer_filename ); <
1198 /* i HATE that cast, but we know the importer won't change fn. */ <
1199 } <
1200 #endif /* WHCLOB_USE_FILE */ <
1201 <
1202 #if WHCLOB_USE_BASE64 <
1203 #include "s11n.net/c11n/detail/b64/cencode.h" <
1204 #include "s11n.net/c11n/detail/b64/cdecode.h" <
1205 long whclob_base64_enc( whclob const *cIn, whclob *cOut ) <
1206 { <
1207 unsigned int szIn = whclob_size(cIn); <
1208 unsigned int szOut = (unsigned int) ((szIn+1) * 1.4); <
1209 long rc = 0; <
1210 whclob * tmp = 0; <
1211 if( ! cIn || !cOut || !szIn ) return whclob_rc.ArgError; <
1212 if( szOut < (szIn-5) ) szOut = szIn + 5; <
1213 if( cOut != cIn ) whclob_reset( cOut ); <
1214 rc = whclob_init( &tmp, 0, szOut ); <
1215 if( whclob_rc.OK != rc ) <
1216 { <
1217 return rc; <
1218 } <
1219 base64_encodestate state; <
1220 base64_init_encodestate( &state ); <
1221 char * outBuf = whclob_buffer(tmp); <
1222 rc = base64_encode_block( whclob_bufferc(cIn), whclob_size(cIn), outBuf, &state ); <
1223 //MARKER("enc inSize=%ld, rc=%ld\n",whclob_size(cIn), rc); <
1224 rc += base64_encode_blockend( outBuf+rc, &state); <
1225 //MARKER("enc rc=%ld\n",rc); <
1226 whclob_resize( tmp, rc ); <
1227 whclob_swap( cOut, tmp ); <
1228 whclob_finalize( tmp ); <
1229 return whclob_rc.OK; <
1230 } <
1231 <
1232 long whclob_base64_dec( whclob const *cIn, whclob *cOut ) <
1233 { <
1234 unsigned int szIn = whclob_size(cIn); <
1235 unsigned int szOut = szIn; <
1236 long rc = 0; <
1237 whclob * tmp = 0; <
1238 if( ! cIn || !cOut || !szIn ) return whclob_rc.ArgError; <
1239 if( cOut != cIn ) whclob_reset( cOut ); <
1240 rc = whclob_init( &tmp, 0, szOut ); <
1241 if( whclob_rc.OK != rc ) <
1242 { <
1243 return rc; <
1244 } <
1245 base64_decodestate state; <
1246 base64_init_decodestate( &state ); <
1247 rc = base64_decode_block( whclob_bufferc(cIn), whclob_size(cIn), whclob_buffer(tmp), &state ); <
1248 whclob_resize( tmp, rc ); <
1249 //MARKER("dec inSize=%ld, outSize=%ld, rc=%ld\n",whclob_size(cIn), whclob_size(tmp), rc); <
1250 whclob_swap( cOut, tmp ); <
1251 whclob_finalize( tmp ); <
1252 return whclob_rc.OK; <
1253 } <
1254 #endif /* WHCLOB_USE_BASE64 */ <
1255 <
1256 #undef WHCLOB_DEBUG <