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