Annotation of libwww/Library/src/HTChunk.c, revision 2.26
2.10 frystyk 1: /* HTChunk.c
2: ** CHUNK HANDLING: FLEXIBLE ARRAYS
3: **
2.13 frystyk 4: ** (c) COPYRIGHT MIT 1995.
2.10 frystyk 5: ** Please first read the full copyright statement in the file COPYRIGH.
2.26 ! kahan 6: ** @(#) $Id: HTChunk.c,v 2.25 1999/02/05 17:34:01 frystyk Exp $
1.1 timbl 7: **
2.6 frystyk 8: ** history: AL, HF 28 Apr 94, Now chunk->data is filled by '\0' so
9: ** that the string is terminated at any time. That makes
2.15 frystyk 10: ** HTChunk_terminate not needed any more, but never mind.
2.20 eric 11: ** EGP 15 Mar 96, Added CString conversions.
2.6 frystyk 12: **
1.1 timbl 13: */
14:
2.12 frystyk 15: /* Library include files */
2.23 frystyk 16: #include "wwwsys.h"
1.1 timbl 17: #include "HTUtils.h"
2.12 frystyk 18: #include "HTChunk.h" /* Implemented here */
1.1 timbl 19:
2.25 frystyk 20: struct _HTChunk {
21: int size; /* In bytes */
22: int growby; /* Allocation unit in bytes */
23: int allocated; /* Current size of *data */
24: char * data; /* Pointer to malloced area or 0 */
25: };
26:
27: /* --------------------------------------------------------------------------*/
28:
1.1 timbl 29: /* Create a chunk with a certain allocation unit
30: ** --------------
31: */
2.15 frystyk 32: PUBLIC HTChunk * HTChunk_new (int grow)
1.1 timbl 33: {
2.18 frystyk 34: HTChunk * ch;
35: if ((ch = (HTChunk *) HT_CALLOC(1, sizeof(HTChunk))) == NULL)
36: HT_OUTOFMEM("HTChunk_new");
1.1 timbl 37: ch->growby = grow;
38: return ch;
39: }
40:
41:
42: /* Clear a chunk of all data
43: ** --------------------------
2.19 frystyk 44: ** Zero the space but do NOT HT_FREE it. We zero because we promise to have
2.17 frystyk 45: ** a NUL terminated string at all times.
1.1 timbl 46: */
2.15 frystyk 47: PUBLIC void HTChunk_clear (HTChunk * ch)
1.1 timbl 48: {
2.16 frystyk 49: if (ch) {
50: ch->size = 0;
2.24 frystyk 51: if (ch->data) memset((void *) ch->data, '\0', ch->allocated);
1.1 timbl 52: }
53: }
54:
55:
56: /* Free a chunk
57: ** ------------
58: */
2.15 frystyk 59: PUBLIC void HTChunk_delete (HTChunk * ch)
1.1 timbl 60: {
2.16 frystyk 61: if (ch) {
2.18 frystyk 62: HT_FREE(ch->data);
63: HT_FREE(ch);
2.16 frystyk 64: }
1.1 timbl 65: }
66:
2.25 frystyk 67: PUBLIC char * HTChunk_data (HTChunk * ch)
68: {
69: return ch ? ch->data : NULL;
70: }
71:
72: PUBLIC int HTChunk_size (HTChunk * ch)
73: {
74: return ch ? ch->size : -1;
75: }
76:
2.26 ! kahan 77: PUBLIC BOOL HTChunk_truncate (HTChunk * ch, int length)
2.25 frystyk 78: {
2.26 ! kahan 79: if (ch && length >= 0 && length < ch->size) {
! 80: memset(ch->data+length, '\0', ch->size-length);
! 81: ch->size = length;
! 82: return YES;
! 83: }
! 84: return NO;
! 85: }
! 86:
! 87: /* Set the "size" of the Chunk's data
! 88: ** -----------------------------------
! 89: ** The actual allocated length must be at least 1 byte longer to hold the
! 90: ** mandatory null terminator.
! 91: */
! 92: PUBLIC BOOL HTChunk_setSize (HTChunk * ch, int length)
! 93: {
! 94: if (ch && length >= 0) {
! 95: if (length < ch->size)
! 96: memset(ch->data+length, '\0', ch->size-length);
! 97: else if (length >= ch->allocated)
! 98: HTChunk_ensure(ch, length - ch->size);
! 99: ch->size = length;
2.25 frystyk 100: return YES;
101: }
102: return NO;
103: }
104:
2.20 eric 105: /* Create a chunk from an allocated string
106: ** ---------------------------------------
107: */
108: PUBLIC HTChunk * HTChunk_fromCString (char * str, int grow)
109: {
110: HTChunk * ch;
111: ch = HTChunk_new(grow);
2.22 frystyk 112: if (str) {
113: ch->data = str; /* can't handle non-allocated str */
114: ch->size = strlen(str);
2.24 frystyk 115: ch->allocated = ch->size + 1; /* [SIC] bobr */
2.22 frystyk 116: }
2.20 eric 117: return ch;
118: }
119:
120: /* Free a chunk but keep the data
121: ** ------------------------------
122: */
123: PUBLIC char * HTChunk_toCString (HTChunk * ch)
124: {
125: char * ret = 0;
126: if (ch) {
127: ret = ch->data;
128: HT_FREE(ch);
129: }
130: return ret;
131: }
1.1 timbl 132:
133: /* Append a character
134: ** ------------------
135: */
2.15 frystyk 136: PUBLIC void HTChunk_putc (HTChunk * ch, char c)
1.1 timbl 137: {
2.24 frystyk 138: if (ch) {
139: if (!ch->data || ch->size >= ch->allocated-1) { /* [SIC] bobr */
2.17 frystyk 140: if (ch->data) {
2.18 frystyk 141: if ((ch->data = (char *) HT_REALLOC(ch->data,ch->allocated+ch->growby)) == NULL)
142: HT_OUTOFMEM("HTChunk_putc");
2.17 frystyk 143: memset((void *) (ch->data + ch->allocated), '\0', ch->growby);
144: } else {
2.18 frystyk 145: if ((ch->data = (char *) HT_CALLOC(1, ch->allocated+ch->growby)) == NULL)
146: HT_OUTOFMEM("HTChunk_putc");
2.17 frystyk 147: }
148: ch->allocated += ch->growby;
2.6 frystyk 149: }
2.17 frystyk 150: *(ch->data+ch->size++) = c;
1.1 timbl 151: }
2.16 frystyk 152: }
153:
154: /* Append a string
155: ** ---------------
156: */
2.19 frystyk 157: PUBLIC void HTChunk_puts (HTChunk * ch, const char * s)
2.16 frystyk 158: {
159: HTChunk_putb(ch, s, (int) strlen(s));
160: }
161:
162: /* Append a block
163: ** ---------------
164: ** The string is always zero terminated
165: */
2.19 frystyk 166: PUBLIC void HTChunk_putb (HTChunk * ch, const char * block, int len)
2.16 frystyk 167: {
168: if (ch && block && len) {
169: int needed = ch->size+len;
170: if (needed >= ch->allocated) {
171: ch->allocated = needed - needed%ch->growby + ch->growby;
172: if (ch->data) {
2.18 frystyk 173: if ((ch->data = (char *) HT_REALLOC(ch->data, ch->allocated)) == NULL)
174: HT_OUTOFMEM("HTChunk_putb");
2.16 frystyk 175: memset((void *) (ch->data + needed), '\0', ch->allocated-needed);
176: } else {
2.18 frystyk 177: if ((ch->data = (char *) HT_CALLOC(1, ch->allocated)) == NULL)
178: HT_OUTOFMEM("HTChunk_putb");
2.16 frystyk 179: }
180: }
181: memcpy((void *) (ch->data+ch->size), block, len);
182: ch->size = needed;
183: }
1.1 timbl 184: }
185:
2.25 frystyk 186: PUBLIC void HTChunk_terminate (HTChunk * ch)
187: {
188: HTChunk_putc(ch, '\0');
189: }
1.1 timbl 190:
191: /* Ensure a certain size
192: ** ---------------------
193: */
2.16 frystyk 194: PUBLIC void HTChunk_ensure (HTChunk * ch, int len)
1.1 timbl 195: {
2.26 ! kahan 196: if (ch && len > 0) {
2.16 frystyk 197: int needed = ch->size+len;
198: if (needed >= ch->allocated) {
199: ch->allocated = needed - needed%ch->growby + ch->growby;
200: if (ch->data) {
2.18 frystyk 201: if ((ch->data = (char *) HT_REALLOC(ch->data, ch->allocated)) == NULL)
2.26 ! kahan 202: HT_OUTOFMEM("HTChunk_ensure");
2.16 frystyk 203: memset((void *) (ch->data + ch->size), '\0', ch->allocated-ch->size);
204: } else {
2.18 frystyk 205: if ((ch->data = (char *) HT_CALLOC(1, ch->allocated)) == NULL)
2.26 ! kahan 206: HT_OUTOFMEM("HTChunk_ensure");
2.16 frystyk 207: }
208: }
209: }
210: #if 0
1.1 timbl 211: if (needed <= ch->allocated) return;
212: ch->allocated = needed-1 - ((needed-1) % ch->growby)
213: + ch->growby; /* Round up */
214: ch->data = ch->data ? (char *)realloc(ch->data, ch->allocated)
2.19 frystyk 215: : (char *)HT_MALLOC(ch->allocated);
216: if (ch->data == NULL) HT_OUTOFMEM(__FILE__, "HTChunk_ensure");
2.16 frystyk 217: #endif
1.1 timbl 218: }
Webmaster