summaryrefslogtreecommitdiff
path: root/gnu/usr.bin/lynx/WWW/Library/Implementation/HTChunk.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/lynx/WWW/Library/Implementation/HTChunk.c')
-rw-r--r--gnu/usr.bin/lynx/WWW/Library/Implementation/HTChunk.c204
1 files changed, 204 insertions, 0 deletions
diff --git a/gnu/usr.bin/lynx/WWW/Library/Implementation/HTChunk.c b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTChunk.c
new file mode 100644
index 00000000000..fd66a482324
--- /dev/null
+++ b/gnu/usr.bin/lynx/WWW/Library/Implementation/HTChunk.c
@@ -0,0 +1,204 @@
+/* Chunk handling: Flexible arrays
+** ===============================
+**
+*/
+
+#include "HTUtils.h"
+#include "HTChunk.h"
+/*#include <stdio.h> included by HTUtils.h -- FM */
+
+#include "LYLeaks.h"
+
+#define FREE(x) if (x) {free(x); x = NULL;}
+
+/* Create a chunk with a certain allocation unit
+** --------------
+*/
+PUBLIC HTChunk * HTChunkCreate ARGS1 (int,grow)
+{
+ HTChunk * ch = (HTChunk *) calloc(1, sizeof(HTChunk));
+ if (ch == NULL)
+ outofmem(__FILE__, "creation of chunk");
+
+ ch->data = 0;
+ ch->growby = grow;
+ ch->size = 0;
+ ch->allocated = 0;
+ return ch;
+}
+
+/* Create a chunk with a certain allocation unit and ensured size
+** --------------
+*/
+PUBLIC HTChunk * HTChunkCreate2 ARGS2 (int,grow, size_t, needed)
+{
+ HTChunk * ch = (HTChunk *) calloc(1, sizeof(HTChunk));
+ if (ch == NULL)
+ outofmem(__FILE__, "HTChunkCreate2");
+
+ ch->growby = grow;
+ if (needed > 0) {
+ ch->allocated = needed-1 - ((needed-1) % ch->growby)
+ + ch->growby; /* Round up */
+ ch->data = (char *)calloc(1, ch->allocated);
+ if (!ch->data)
+ outofmem(__FILE__, "HTChunkCreate2 data");
+ }
+ ch->size = 0;
+ return ch;
+}
+
+
+/* Clear a chunk of all data
+** --------------------------
+*/
+PUBLIC void HTChunkClear ARGS1 (HTChunk *,ch)
+{
+ FREE(ch->data);
+ ch->size = 0;
+ ch->allocated = 0;
+}
+
+
+/* Free a chunk
+** ------------
+*/
+PUBLIC void HTChunkFree ARGS1 (HTChunk *,ch)
+{
+ FREE(ch->data);
+ FREE(ch);
+}
+
+
+/* Append a character
+** ------------------
+*/
+PUBLIC void HTChunkPutc ARGS2 (HTChunk *,ch, char,c)
+{
+ if (ch->size >= ch->allocated) {
+ ch->allocated = ch->allocated + ch->growby;
+ ch->data = ch->data ? (char *)realloc(ch->data, ch->allocated)
+ : (char *)calloc(1, ch->allocated);
+ if (!ch->data)
+ outofmem(__FILE__, "HTChunkPutc");
+ }
+ ch->data[ch->size++] = c;
+}
+
+
+/* Ensure a certain size
+** ---------------------
+*/
+PUBLIC void HTChunkEnsure ARGS2 (HTChunk *,ch, int,needed)
+{
+ if (needed <= ch->allocated) return;
+ ch->allocated = needed-1 - ((needed-1) % ch->growby)
+ + ch->growby; /* Round up */
+ ch->data = ch->data ? (char *)realloc(ch->data, ch->allocated)
+ : (char *)calloc(1, ch->allocated);
+ if (ch->data == NULL)
+ outofmem(__FILE__, "HTChunkEnsure");
+}
+
+PUBLIC void HTChunkPutb ARGS3 (HTChunk *,ch, CONST char *,b, int,l)
+{
+ int needed = ch->size + l;
+ if (l <= 0) return;
+ if (needed > ch->allocated) {
+ ch->allocated = needed-1 - ((needed-1) % ch->growby)
+ + ch->growby; /* Round up */
+ ch->data = ch->data ? (char *)realloc(ch->data, ch->allocated)
+ : (char *)calloc(1, ch->allocated);
+ if (ch->data == NULL)
+ outofmem(__FILE__, "HTChunkPutb");
+ }
+ memcpy(ch->data + ch->size, b, l);
+ ch->size += l;
+}
+
+#define PUTC(code) ch->data[ch->size++] = (char)(code)
+#define PUTC2(code) ch->data[ch->size++] = (char)(0x80|(0x3f &(code)))
+
+PUBLIC void HTChunkPutUtf8Char ARGS2(
+ HTChunk *, ch,
+ UCode_t, code)
+{
+ int utflen;
+
+ if (code < 128)
+ utflen = 1;
+ else if (code < 0x800L) {
+ utflen = 2;
+ } else if (code < 0x10000L) {
+ utflen = 3;
+ } else if (code < 0x200000L) {
+ utflen = 4;
+ } else if (code < 0x4000000L) {
+ utflen = 5;
+ } else if (code<=0x7fffffffL) {
+ utflen = 6;
+ } else
+ utflen = 0;
+
+ if (ch->size + utflen > ch->allocated) {
+ int growby = (ch->growby >= utflen) ? ch->growby : utflen;
+ ch->allocated = ch->allocated + growby;
+ ch->data = ch->data ? (char *)realloc(ch->data, ch->allocated)
+ : (char *)calloc(1, ch->allocated);
+ if (!ch->data)
+ outofmem(__FILE__, "HTChunkPutUtf8Char");
+ }
+
+ switch (utflen) {
+ case 0:
+ return;
+ case 1:
+ ch->data[ch->size++] = (char)code;
+ return;
+ case 2:
+ PUTC(0xc0 | (code>>6));
+ break;
+ case 3:
+ PUTC(0xe0 | (code>>12));
+ break;
+ case 4:
+ PUTC(0xf0 | (code>>18));
+ break;
+ case 5:
+ PUTC(0xf8 | (code>>24));
+ break;
+ case 6:
+ PUTC(0xfc | (code>>30));
+ }
+ switch (utflen) {
+ case 6:
+ PUTC2(code>>24);
+ case 5:
+ PUTC2(code>>18);
+ case 4:
+ PUTC2(code>>12);
+ case 3:
+ PUTC2(code>>6);
+ case 2:
+ PUTC2(code);
+ }
+}
+
+/* Terminate a chunk
+** -----------------
+*/
+PUBLIC void HTChunkTerminate ARGS1 (HTChunk *,ch)
+{
+ HTChunkPutc(ch, (char)0);
+}
+
+
+/* Append a string
+** ---------------
+*/
+PUBLIC void HTChunkPuts ARGS2 (HTChunk *,ch, CONST char *,s)
+{
+ CONST char * p;
+ for (p=s; *p; p++)
+ HTChunkPutc(ch, *p);
+}