~ubuntu-branches/ubuntu/edgy/lynx/edgy

« back to all changes in this revision

Viewing changes to WWW/Library/Implementation/HTChunk.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2004-09-16 12:14:10 UTC
  • Revision ID: james.westby@ubuntu.com-20040916121410-cz1gu92c4nqfeyrg
Tags: upstream-2.8.5
ImportĀ upstreamĀ versionĀ 2.8.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*              Chunk handling: Flexible arrays
 
2
**              ===============================
 
3
**
 
4
*/
 
5
 
 
6
#include <HTUtils.h>
 
7
#include <HTChunk.h>
 
8
 
 
9
#include <LYLeaks.h>
 
10
 
 
11
/*
 
12
**      Initialize a chunk with a certain allocation unit
 
13
*/
 
14
PUBLIC void HTChunkInit ARGS2 (HTChunk *,ch, int,grow)
 
15
{
 
16
    ch->data = 0;
 
17
    ch->growby = grow;
 
18
    ch->size = 0;
 
19
    ch->allocated = 0;
 
20
}
 
21
 
 
22
/*      Create a chunk with a certain allocation unit
 
23
**      --------------
 
24
*/
 
25
PUBLIC HTChunk * HTChunkCreate ARGS1 (int,grow)
 
26
{
 
27
    HTChunk * ch = typecalloc(HTChunk);
 
28
    if (ch == NULL)
 
29
        outofmem(__FILE__, "creation of chunk");
 
30
 
 
31
    HTChunkInit (ch, grow);
 
32
    return ch;
 
33
}
 
34
 
 
35
PUBLIC HTChunk * HTChunkCreateMayFail ARGS2 (int,grow, int,failok)
 
36
{
 
37
    HTChunk * ch = typecalloc(HTChunk);
 
38
    if (ch == NULL) {
 
39
        if (!failok) {
 
40
            outofmem(__FILE__, "creation of chunk");
 
41
        } else {
 
42
            return ch;
 
43
        }
 
44
    }
 
45
    HTChunkInit (ch, grow);
 
46
    ch->failok = failok;
 
47
    return ch;
 
48
}
 
49
 
 
50
/*      Create a chunk with a certain allocation unit and ensured size
 
51
**      --------------
 
52
*/
 
53
PUBLIC HTChunk * HTChunkCreate2 ARGS2 (int,grow, size_t, needed)
 
54
{
 
55
    HTChunk * ch = typecalloc(HTChunk);
 
56
    if (ch == NULL)
 
57
        outofmem(__FILE__, "HTChunkCreate2");
 
58
 
 
59
    HTChunkInit (ch, grow);
 
60
    if (needed > 0) {
 
61
        ch->allocated = needed-1 - ((needed-1) % ch->growby)
 
62
            + ch->growby; /* Round up */
 
63
        CTRACE((tfp, "HTChunkCreate2: requested %d, allocate %d\n",
 
64
               (int) needed, ch->allocated));
 
65
        ch->data = typecallocn(char, ch->allocated);
 
66
        if (!ch->data)
 
67
            outofmem(__FILE__, "HTChunkCreate2 data");
 
68
    }
 
69
    return ch;
 
70
}
 
71
 
 
72
 
 
73
/*      Clear a chunk of all data
 
74
**      --------------------------
 
75
*/
 
76
PUBLIC void HTChunkClear ARGS1 (HTChunk *,ch)
 
77
{
 
78
    FREE(ch->data);
 
79
    ch->size = 0;
 
80
    ch->allocated = 0;
 
81
}
 
82
 
 
83
 
 
84
/*      Free a chunk
 
85
**      ------------
 
86
*/
 
87
PUBLIC void HTChunkFree ARGS1 (HTChunk *,ch)
 
88
{
 
89
    FREE(ch->data);
 
90
    FREE(ch);
 
91
}
 
92
 
 
93
 
 
94
/*      Realloc the chunk
 
95
**      -----------------
 
96
*/
 
97
PUBLIC BOOL HTChunkRealloc ARGS2 (HTChunk *,ch, int,growby)
 
98
{
 
99
    char *data;
 
100
    ch->allocated = ch->allocated + growby;
 
101
 
 
102
    data = ch->data ? (char *)realloc(ch->data, ch->allocated)
 
103
                        : typecallocn(char, ch->allocated);
 
104
    if (data) {
 
105
        ch->data = data;
 
106
    } else if (ch->failok) {
 
107
        HTChunkClear(ch);       /* allocation failed, clear all data - kw */
 
108
        return FALSE;           /* caller should check ch->allocated - kw */
 
109
    } else {
 
110
        outofmem(__FILE__, "HTChunkRealloc");
 
111
    }
 
112
    return TRUE;
 
113
}
 
114
 
 
115
 
 
116
/*      Append a character
 
117
**      ------------------
 
118
*/
 
119
/* Warning: the code of this function is defined as macro in SGML.c. Change
 
120
  the macro or undefine it in SGML.c when changing this function. -VH */
 
121
PUBLIC void HTChunkPutc ARGS2 (HTChunk *,ch, char,c)
 
122
{
 
123
    if (ch->size >= ch->allocated) {
 
124
        if (!HTChunkRealloc(ch, ch->growby))
 
125
            return;
 
126
    }
 
127
    ch->data[ch->size++] = c;
 
128
}
 
129
 
 
130
 
 
131
/*      Ensure a certain size
 
132
**      ---------------------
 
133
*/
 
134
PUBLIC void HTChunkEnsure ARGS2 (HTChunk *,ch, int,needed)
 
135
{
 
136
    if (needed <= ch->allocated) return;
 
137
    ch->allocated = needed-1 - ((needed-1) % ch->growby)
 
138
                             + ch->growby; /* Round up */
 
139
    ch->data = ch->data ? (char *)realloc(ch->data, ch->allocated)
 
140
                        : typecallocn(char, ch->allocated);
 
141
    if (ch->data == NULL)
 
142
        outofmem(__FILE__, "HTChunkEnsure");
 
143
}
 
144
 
 
145
PUBLIC void HTChunkPutb ARGS3 (HTChunk *,ch, CONST char *,b, int,l)
 
146
{
 
147
    if (l <= 0) return;
 
148
    if (ch->size + l > ch->allocated) {
 
149
        int growby = l - (l % ch->growby) + ch->growby; /* Round up */
 
150
        if (!HTChunkRealloc(ch, growby))
 
151
            return;
 
152
    }
 
153
    memcpy(ch->data + ch->size, b, l);
 
154
    ch->size += l;
 
155
}
 
156
 
 
157
#define PUTC(code) ch->data[ch->size++] = (char)(code)
 
158
#define PUTC2(code) ch->data[ch->size++] = (char)(0x80|(0x3f &(code)))
 
159
 
 
160
PUBLIC void HTChunkPutUtf8Char ARGS2(
 
161
        HTChunk *,      ch,
 
162
        UCode_t,        code)
 
163
{
 
164
    int utflen;
 
165
 
 
166
    if (TOASCII(code) < 128)
 
167
        utflen = 1;
 
168
    else if   (code <     0x800L) {
 
169
        utflen = 2;
 
170
    } else if (code <   0x10000L) {
 
171
        utflen = 3;
 
172
    } else if (code <  0x200000L) {
 
173
        utflen = 4;
 
174
    } else if (code < 0x4000000L) {
 
175
        utflen = 5;
 
176
    } else if (code<=0x7fffffffL) {
 
177
        utflen = 6;
 
178
    } else
 
179
        utflen = 0;
 
180
 
 
181
    if (ch->size + utflen > ch->allocated) {
 
182
        int growby = (ch->growby >= utflen) ? ch->growby : utflen;
 
183
        if (!HTChunkRealloc(ch, growby))
 
184
            return;
 
185
    }
 
186
 
 
187
    switch (utflen) {
 
188
    case 0:
 
189
        return;
 
190
    case 1:
 
191
        ch->data[ch->size++] = (char)code;
 
192
        return;
 
193
    case 2:
 
194
        PUTC(0xc0 | (code>>6));
 
195
        break;
 
196
    case 3:
 
197
        PUTC(0xe0 | (code>>12));
 
198
        break;
 
199
    case 4:
 
200
        PUTC(0xf0 | (code>>18));
 
201
        break;
 
202
    case 5:
 
203
        PUTC(0xf8 | (code>>24));
 
204
        break;
 
205
    case 6:
 
206
        PUTC(0xfc | (code>>30));
 
207
        break;
 
208
    }
 
209
    switch (utflen) {
 
210
    case 6:
 
211
        PUTC2(code>>24);
 
212
        /* FALLTHRU */
 
213
    case 5:
 
214
        PUTC2(code>>18);
 
215
        /* FALLTHRU */
 
216
    case 4:
 
217
        PUTC2(code>>12);
 
218
        /* FALLTHRU */
 
219
    case 3:
 
220
        PUTC2(code>>6);
 
221
        /* FALLTHRU */
 
222
    case 2:
 
223
        PUTC2(code);
 
224
        break;
 
225
    }
 
226
}
 
227
 
 
228
/*      Terminate a chunk
 
229
**      -----------------
 
230
*/
 
231
PUBLIC void HTChunkTerminate ARGS1 (HTChunk *,ch)
 
232
{
 
233
    HTChunkPutc(ch, (char)0);
 
234
}
 
235
 
 
236
 
 
237
/*      Append a string
 
238
**      ---------------
 
239
*/
 
240
PUBLIC void HTChunkPuts ARGS2 (HTChunk *,ch, CONST char *,s)
 
241
{
 
242
    CONST char * p;
 
243
    for (p = s; *p; p++) {
 
244
        if (ch->size >= ch->allocated) {
 
245
            if (!HTChunkRealloc(ch, ch->growby))
 
246
                return;
 
247
        }
 
248
        ch->data[ch->size++] = *p;
 
249
    }
 
250
}