Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| SHA1 Hash: | 7b76c29e3c3c03616434fdce19481d748ccb9a85 |
|---|---|
| Date: | 2008-11-13 17:29:03 |
| User: | stephan |
| Comment: | seemed to have fixed whclob_truncate() to work how it should |
Changes
Changes to include/s11n.net/c11n/detail/whclob.h
| Old (b809f26690d058a7) | New (0a98da244b21da3a) | |||
|---|---|---|---|---|
| 1 | #ifndef WANDERINGHORSE_NET_WHCLOB_H_INCLUDED_ | 1 | #ifndef WANDERINGHORSE_NET_WHCLOB_H_INCLUDED_ | |
| 2 | #define WANDERINGHORSE_NET_WHCLOB_H_INCLUDED_ 1 | 2 | #define WANDERINGHORSE_NET_WHCLOB_H_INCLUDED_ 1 | |
| 3 | #include <stdarg.h> | 3 | #include <stdarg.h> | |
| 4 | #include <stddef.h> | 4 | #include <stddef.h> | |
| 5 | 5 | |||
| 34 hidden lines | ||||
| 40 | @code | 40 | @code | |
| 41 | whclob * c; | 41 | whclob * c; | |
| 42 | whclob_init( &c, 0, 0 ); | 42 | whclob_init( &c, 0, 0 ); | |
| 43 | whclob_appendf( c, "Hello, %s!", "world"); | 43 | whclob_appendf( c, "Hello, %s!", "world"); | |
| 44 | ... | 44 | ... | |
| > | 45 | printf("%s\n",whclob_bufferc(c)); | ||
| 45 | whclob_finalize( c ); | 46 | whclob_finalize( c ); | |
| 46 | @endcode | 47 | @endcode | |
| 47 | 48 | |||
| 48 | You can dump a whclob to stdout with the whclob_export() API: | 49 | You can dump a whclob to stdout with the whclob_export() API: | |
| 49 | 50 | |||
| 51 | 52 | |||
| 52 | But doing so with binary data is not recommended. | 53 | But doing so with binary data is not recommended. | |
| 53 | 54 | |||
| 54 | Some example uses for clobs are: | 55 | Some example uses for clobs are: | |
| 55 | 56 | |||
| 56 | - Copying strings. | | | 57 | - Creating and copying strings. |
| 57 | - Buffering input or output. | 58 | - Buffering input or output. | |
| 58 | - Easily reading a whole file (or other input source) into memory. | 59 | - Easily reading a whole file (or other input source) into memory. | |
| 59 | 60 | |||
| 60 | @section whclob_sec_todo TODOs | 61 | @section whclob_sec_todo TODOs | |
| 61 | 62 | |||
| 62 | - The read/write API is not complete. (Can't quite remember what's | 63 | - The read/write API is not complete. (Can't quite remember what's | |
| 63 | missing, though.) | 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. | ||
| 64 | 69 | |||
| 65 | ************************************************************************/ | 70 | ************************************************************************/ | |
| 66 | 71 | |||
| 67 | 72 | |||
| 68 | /** @def WHCLOB_USE_FILE | 73 | /** @def WHCLOB_USE_FILE | |
| 547 hidden lines | ||||
| 616 | - whclob_rc.AllocError if a memory (re)allocation fails. | 621 | - whclob_rc.AllocError if a memory (re)allocation fails. | |
| 617 | */ | 622 | */ | |
| 618 | long whclob_null_terminate( whclob * cb ); | 623 | long whclob_null_terminate( whclob * cb ); | |
| 619 | 624 | |||
| 620 | /** | 625 | /** | |
| 621 | If whclob_size(cb) "used space" is currently less than pos then this | | | 626 | "Chops" cb off at a given length. If the current used space is |
| 622 | function does nothing, otherwise cb is truncated to that length. | | | 627 | smaller than pos then it will be padded with NULLs to make it fit. |
| | | 628 | It is is longer than pos then the clob will be reallocated (if | ||
| | | 629 | necessary) to fit the new space and any old data which is now | ||
| | | 630 | outside the used range will be zeroed out (this is necessary for | ||
| | | 631 | sane behaviour in some use cases). In any case, on success the new | ||
| | | 632 | position of the clob will be the given position. | ||
| 623 | 633 | |||
| 624 | If allocPolicy is 0 then the amount of memory allocated by cb is | 634 | If allocPolicy is 0 then the amount of memory allocated by cb is | |
| 625 | not adjusted. If it is >0, whclob_reserve() will be called to try | | | 635 | not adjusted (unless (pos>whclob_size(cb)), in which case we have |
| 626 | to reserve at least pos bytes. If (allocPolicy<0) then the | | | 636 | to expand the clob). If it is >0, whclob_reserve() will be called |
| 627 | allocated memory is shrunk to fit (if possible). | | | 637 | to try to reserve at least pos bytes. If (allocPolicy<0) then the |
| | | 638 | allocated memory is shrunk to fit (if possible). If pos is past the | ||
| | | 639 | current end-of-data position then allocPolicy is forced to 1 so | ||
| | | 640 | that the buffer can be expanded (if needed). | ||
| 628 | 641 | |||
| 629 | Returns whclob_rc.OK or a positive value on success or another | | | 642 | Returns whclob_rc.OK or a positive value on success or a negative |
| 630 | value from whclob_rc on error. | 643 | value from whclob_rc on error. | |
| > | 644 | |||
| > | 645 | The two most common uses for this function: | ||
| > | 646 | |||
| > | 647 | - "Shrink-wrapping" the value (eliminating extra allocated space) | ||
| > | 648 | |||
| > | 649 | - Re-using a clob's buffer as a target for, e.g. fread(), by | ||
| > | 650 | reserving a certain amount of space then truncating it at position | ||
| > | 651 | 0 but with an allocPolicy of >=0. This can save on allocations compared | ||
| > | 652 | to using, e.g. whclob_reset(). | ||
| > | 653 | |||
| 631 | */ | 654 | */ | |
| 632 | long whclob_truncate( whclob * cb, long pos, int allocPolicy ); | 655 | long whclob_truncate( whclob * cb, long pos, int allocPolicy ); | |
| 633 | 656 | |||
| 634 | /* TODO???: whclob_trim() */ | 657 | /* TODO???: whclob_trim() */ | |
| 635 | 658 | |||
| 283 hidden lines | ||||
| 919 | 942 | |||
| 920 | #ifdef __cplusplus | 943 | #ifdef __cplusplus | |
| 921 | } /* extern "C" */ | 944 | } /* extern "C" */ | |
| 922 | #endif | 945 | #endif | |
| 923 | #endif /* WANDERINGHORSE_NET_WHCLOB_H_INCLUDED_ */ | 946 | #endif /* WANDERINGHORSE_NET_WHCLOB_H_INCLUDED_ */ | |
Changes to src/whclob.c
| Old (ba85cfdfe05c8db1) | New (bf41c0a532db1e43) | |||
|---|---|---|---|---|
| 1 | #include <string.h> | 1 | #include <string.h> | |
| 2 | #include <stdlib.h> | 2 | #include <stdlib.h> | |
| 3 | #include <stdio.h> | 3 | #include <stdio.h> | |
| 4 | #include <stdarg.h> | 4 | #include <stdarg.h> | |
| 5 | 5 | |||
| 115 hidden lines | ||||
| 121 | else | 121 | else | |
| 122 | { | 122 | { | |
| 123 | whclob_appendf( dest, "=[NULL]", cb ); | 123 | whclob_appendf( dest, "=[NULL]", cb ); | |
| 124 | } | 124 | } | |
| 125 | } | 125 | } | |
| 126 | fappendf( stdout, "%s\n", whclob_buffer( dest ) ); | | | 126 | fappendf( stderr, "%s\n", whclob_buffer( dest ) ); |
| 127 | whclob_finalize( dest ); | 127 | whclob_finalize( dest ); | |
| 128 | } | 128 | } | |
| 129 | 129 | |||
| 130 | 130 | |||
| 131 | long whclob_reset( whclob * cb ) | 131 | long whclob_reset( whclob * cb ) | |
| 181 hidden lines | ||||
| 313 | else | 313 | else | |
| 314 | { | 314 | { | |
| 315 | if( !n ) return whclob_rc.OK; | 315 | if( !n ) return whclob_rc.OK; | |
| 316 | } | 316 | } | |
| 317 | if( data && (n < 0) ) n = strlen( data ); | 317 | if( data && (n < 0) ) n = strlen( data ); | |
| > | 318 | #if 1 | ||
| 318 | rc = whclob_reserve( *cb, n ); | 319 | rc = whclob_reserve( *cb, n ); | |
| 319 | if( rc < whclob_rc.OK ) | 320 | if( rc < whclob_rc.OK ) | |
| 320 | { | 321 | { | |
| 321 | free( *cb ); | 322 | free( *cb ); | |
| 322 | *cb = 0; | 323 | *cb = 0; | |
| 324 | } | 325 | } | |
| 325 | if( data ) | 326 | if( data ) | |
| 326 | { | 327 | { | |
| 327 | memcpy( (*cb)->aData, data, n ); | 328 | memcpy( (*cb)->aData, data, n ); | |
| 328 | } | 329 | } | |
| > | 330 | #else | ||
| > | 331 | rc = whclob_append( *cb, data, n ); | ||
| > | 332 | if( rc < whclob_rc.OK ) | ||
| > | 333 | { | ||
| > | 334 | free( *cb ); | ||
| > | 335 | *cb = 0; | ||
| > | 336 | return rc; | ||
| > | 337 | } | ||
| > | 338 | #endif | ||
| 329 | return whclob_rc.OK; | 339 | return whclob_rc.OK; | |
| 330 | } | 340 | } | |
| 331 | 341 | |||
| 332 | 342 | |||
| 333 | long whclob_seek( whclob * cb, long offset, int whence ) | 343 | long whclob_seek( whclob * cb, long offset, int whence ) | |
| 190 hidden lines | ||||
| 524 | long whclob_truncate( whclob * cb, long pos, int memPolicy ) | 534 | long whclob_truncate( whclob * cb, long pos, int memPolicy ) | |
| 525 | { | 535 | { | |
| 526 | long rc = 0; | 536 | long rc = 0; | |
| 527 | if( ! cb ) return whclob_rc.UnexpectedNull; | 537 | if( ! cb ) return whclob_rc.UnexpectedNull; | |
| 528 | /* if( cb->nUsed <= pos ) return whclob_rc.OK; */ | 538 | /* if( cb->nUsed <= pos ) return whclob_rc.OK; */ | |
| 529 | if( cb->nUsed <= pos ) | | | 539 | |
| | | 540 | if( pos < cb->nAlloc ) | ||
| | | 541 | { /* adding a single \0 to the data isn't sufficient here. */ | ||
| | | 542 | memset( cb->aData + pos, 0, (cb->nAlloc-pos)); | ||
| | | 543 | } | ||
| | | 544 | |||
| | | 545 | if( cb->nAlloc <= pos ) | ||
| 530 | { | 546 | { | |
| 531 | return whclob_rc.OK; | | | 547 | //return whclob_rc.OK; |
| | | 548 | memPolicy = 1; | ||
| 532 | } | 549 | } | |
| 533 | rc = whclob_rc.OK; | 550 | rc = whclob_rc.OK; | |
| 534 | if( memPolicy > 0 ) | 551 | if( memPolicy > 0 ) | |
| 535 | { | 552 | { | |
| 536 | rc = whclob_reserve( cb, pos ); | 553 | rc = whclob_reserve( cb, pos ); | |
| 21 hidden lines | ||||
| 558 | /* rc = whclob_do_resize( cb, cb->nUsed, 0 ); */ | 575 | /* rc = whclob_do_resize( cb, cb->nUsed, 0 ); */ | |
| 559 | //MARKER("TRUNCATED: alloc=%ld len=%ld, rc=%ld\n", cb->nAlloc, cb->nUsed, rc ); | 576 | //MARKER("TRUNCATED: alloc=%ld len=%ld, rc=%ld\n", cb->nAlloc, cb->nUsed, rc ); | |
| 560 | #endif | 577 | #endif | |
| 561 | } | 578 | } | |
| 562 | cb->nUsed = pos; | 579 | cb->nUsed = pos; | |
| 563 | whclob_null_terminate( cb ); | | | 580 | //whclob_null_terminate( cb ); |
| 564 | return rc; | 581 | return rc; | |
| 565 | } | 582 | } | |
| 566 | 583 | |||
| 567 | 584 | |||
| 568 | long whclob_memmove( whclob * cb, int start1, int n, int start2 ) | 585 | long whclob_memmove( whclob * cb, int start1, int n, int start2 ) | |
| 575 hidden lines | ||||
| 1144 | return whclob_size(dest) - oldUsed; | 1161 | return whclob_size(dest) - oldUsed; | |
| 1145 | } | 1162 | } | |
| 1146 | 1163 | |||
| 1147 | long whclob_importer_filename( whclob * dest, void * arg ) | 1164 | long whclob_importer_filename( whclob * dest, void * arg ) | |
| 1148 | { | 1165 | { | |
| 1149 | char const * fname = (char *)arg; | | | 1166 | char const * fname = (char const *)arg; |
| 1150 | FILE * fh = 0; | 1167 | FILE * fh = 0; | |
| 1151 | long ret = 0; | 1168 | long ret = 0; | |
| 1152 | if( ! fname ) return whclob_rc.ArgError; | 1169 | if( ! fname ) return whclob_rc.ArgError; | |
| 1153 | fh = fopen( fname, "rb" ); | 1170 | fh = fopen( fname, "rb" ); | |
| 1154 | if( !fh ) return whclob_rc.IOError; | | | 1171 | if( !fh ) |
| 1155 | ret = whclob_import( dest, fh, whclob_importer_FILE ); | | | 1172 | { |
| 1156 | fclose( fh ); | | | 1173 | ret = whclob_rc.IOError; |
| | | 1174 | } | ||
| | | 1175 | else | ||
| | | 1176 | { | ||
| | | 1177 | ret = whclob_import( dest, fh, whclob_importer_FILE ); | ||
| | | 1178 | fclose( fh ); | ||
| | | 1179 | } | ||
| 1157 | return ret; | 1180 | return ret; | |
| 1158 | } | 1181 | } | |
| 1159 | 1182 | |||
| 1160 | long whclob_import_FILE( whclob * dest, FILE * fp ) | 1183 | long whclob_import_FILE( whclob * dest, FILE * fp ) | |
| 1161 | { | 1184 | { | |
| 7 hidden lines | ||||
| 1169 | } | 1192 | } | |
| 1170 | #endif /* WHCLOB_USE_FILE */ | 1193 | #endif /* WHCLOB_USE_FILE */ | |
| 1171 | 1194 | |||
| 1172 | #undef WHCLOB_USE_ZLIB | 1195 | #undef WHCLOB_USE_ZLIB | |
| 1173 | #undef WHCLOB_DEBUG | 1196 | #undef WHCLOB_DEBUG | |