summaryrefslogtreecommitdiff
path: root/common/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/buffer.c')
-rw-r--r--common/buffer.c926
1 files changed, 463 insertions, 463 deletions
diff --git a/common/buffer.c b/common/buffer.c
index 5a77922..07fa059 100644
--- a/common/buffer.c
+++ b/common/buffer.c
@@ -31,399 +31,399 @@
typedef struct ha_buffer_internal
{
- char* end;
- struct ha_buffer_internal* next;
+ char* end;
+ struct ha_buffer_internal* next;
}
internal_t;
void buffer_bump(ha_buffer_t* buf, int count)
{
- int allocated;
- internal_t* intl;
-
- ASSERT(buf && count);
-
- if(ha_buferr(buf))
- return;
-
- ASSERT(BUF_DELTA < BUF_INITIAL);
-
- /* Handle this common case first for efficiency */
- if(buf->_rp + (count + BUF_DELTA) < buf->_dt->end)
- return;
-
- /* Now when in joins we let it go closer */
- if(BUF_IN_JOIN(buf) && (buf->_rp + count < buf->_dt->end))
- return;
-
- /* Okay now we know we have to extend */
- allocated = buf->_dt->end - (char*)(buf->_dt);
- ASSERT(allocated > 0 && (allocated % BUF_INITIAL) == 0);
-
- /* Enlarge the size as much as needed */
- do
- {
- allocated *= 2;
- }
- while(allocated < count);
-
- ASSERT(sizeof(internal_t) < allocated);
- intl = (internal_t*)malloc(allocated);
- if(!intl)
- {
- ha_messagex(LOG_CRIT, "out of memory");
- buf->_dt = NULL;
- buf->_pp = buf->_rp = NULL;
- return;
- }
- else
- {
- void* beg = INTERNAL_DATA(intl);
- intl->end = ((char*)(intl) + allocated);
- intl->next = NULL;
+ int allocated;
+ internal_t* intl;
+
+ ASSERT(buf && count);
+
+ if(ha_buferr(buf))
+ return;
+
+ ASSERT(BUF_DELTA < BUF_INITIAL);
+
+ /* Handle this common case first for efficiency */
+ if(buf->_rp + (count + BUF_DELTA) < buf->_dt->end)
+ return;
+
+ /* Now when in joins we let it go closer */
+ if(BUF_IN_JOIN(buf) && (buf->_rp + count < buf->_dt->end))
+ return;
+
+ /* Okay now we know we have to extend */
+ allocated = buf->_dt->end - (char*)(buf->_dt);
+ ASSERT(allocated > 0 && (allocated % BUF_INITIAL) == 0);
+
+ /* Enlarge the size as much as needed */
+ do
+ {
+ allocated *= 2;
+ }
+ while(allocated < count);
+
+ ASSERT(sizeof(internal_t) < allocated);
+ intl = (internal_t*)malloc(allocated);
+ if(!intl)
+ {
+ ha_messagex(NULL, LOG_CRIT, "out of memory");
+ buf->_dt = NULL;
+ buf->_pp = buf->_rp = NULL;
+ return;
+ }
+ else
+ {
+ void* beg = INTERNAL_DATA(intl);
+ intl->end = ((char*)(intl) + allocated);
+ intl->next = NULL;
#ifdef _DEBUG
- FILL_BETWEEN(beg, intl->end, 0xCD);
+ FILL_BETWEEN(beg, intl->end, 0xCD);
#endif
- if(BUF_IN_JOIN(buf))
- {
- int diff = buf->_rp - buf->_pp;
+ if(BUF_IN_JOIN(buf))
+ {
+ int diff = buf->_rp - buf->_pp;
- /* Always true in a join */
- ASSERT(buf->_pp < buf->_rp);
+ /* Always true in a join */
+ ASSERT(buf->_pp < buf->_rp);
- /* Copy the memory and blank out old */
- memcpy(beg, buf->_pp, diff);
+ /* Copy the memory and blank out old */
+ memcpy(beg, buf->_pp, diff);
#ifdef _DEBUG
- FILL_BETWEEN(buf->_pp, buf->_rp, 0xDD);
+ FILL_BETWEEN(buf->_pp, buf->_rp, 0xDD);
#endif
- buf->_pp = beg;
- buf->_rp = buf->_pp + diff;
- }
- else
- {
- buf->_rp = buf->_pp = INTERNAL_DATA(intl);
- }
+ buf->_pp = beg;
+ buf->_rp = buf->_pp + diff;
+ }
+ else
+ {
+ buf->_rp = buf->_pp = INTERNAL_DATA(intl);
+ }
- buf->_dt->next = intl;
- buf->_dt = intl;
- }
+ buf->_dt->next = intl;
+ buf->_dt = intl;
+ }
}
void ha_bufinit(ha_buffer_t* buf)
{
- ASSERT(buf);
- memset(buf, 0, sizeof(*buf));
+ ASSERT(buf);
+ memset(buf, 0, sizeof(*buf));
- ASSERT(BUF_INITIAL > sizeof(internal_t));
- buf->_ft = (internal_t*)malloc(BUF_INITIAL);
- if(buf->_ft)
- {
- buf->_ft->end = ((char*)(buf->_ft) + BUF_INITIAL);
- buf->_ft->next = NULL;
+ ASSERT(BUF_INITIAL > sizeof(internal_t));
+ buf->_ft = (internal_t*)malloc(BUF_INITIAL);
+ if(buf->_ft)
+ {
+ buf->_ft->end = ((char*)(buf->_ft) + BUF_INITIAL);
+ buf->_ft->next = NULL;
#ifdef _DEBUG
- FILL_BETWEEN(INTERNAL_DATA(buf->_ft), buf->_ft->end, 0xCD);
+ FILL_BETWEEN(INTERNAL_DATA(buf->_ft), buf->_ft->end, 0xCD);
#endif
- ha_bufreset(buf);
- }
+ ha_bufreset(buf);
+ }
}
void ha_bufreset(ha_buffer_t* buf)
{
#ifdef _DEBUG
- internal_t* intl;
+ internal_t* intl;
#endif
- ASSERT(buf);
- ASSERT(buf->_ft);
+ ASSERT(buf);
+ ASSERT(buf->_ft);
#ifdef _DEBUG
- /* Go through all the buffers and set them to 0xCD */
- for(intl = buf->_ft; intl; intl = intl->next)
- FILL_BETWEEN(INTERNAL_DATA(intl), intl->end, 0xCD);
+ /* Go through all the buffers and set them to 0xCD */
+ for(intl = buf->_ft; intl; intl = intl->next)
+ FILL_BETWEEN(INTERNAL_DATA(intl), intl->end, 0xCD);
#endif
- buf->_dt = buf->_ft;
- buf->_rp = buf->_pp = (char*)INTERNAL_DATA(buf->_ft);
+ buf->_dt = buf->_ft;
+ buf->_rp = buf->_pp = (char*)INTERNAL_DATA(buf->_ft);
}
void ha_buffree(ha_buffer_t* buf)
{
- internal_t* intl;
- internal_t* next;
+ internal_t* intl;
+ internal_t* next;
- ASSERT(buf);
+ ASSERT(buf);
- /* Go through free all the buffers and set them to 0xDD */
- for(intl = buf->_ft; intl; intl = next)
- {
- next = intl->next;
- FILL_BETWEEN(INTERNAL_DATA(intl), intl->end, 0xDD);
- free(intl);
- }
+ /* Go through free all the buffers and set them to 0xDD */
+ for(intl = buf->_ft; intl; intl = next)
+ {
+ next = intl->next;
+ FILL_BETWEEN(INTERNAL_DATA(intl), intl->end, 0xDD);
+ free(intl);
+ }
- buf->_ft = buf->_dt = NULL;
- buf->_rp = buf->_pp = NULL;
+ buf->_ft = buf->_dt = NULL;
+ buf->_rp = buf->_pp = NULL;
}
int ha_bufreadline(int fd, ha_buffer_t* buf)
{
- int l;
-
- ASSERT(buf);
- ASSERT(fd != -1);
+ int l;
- if(ha_buferr(buf))
- return 0;
+ ASSERT(buf);
+ ASSERT(fd != -1);
- for(;;)
- {
- buffer_bump(buf, 1);
- l = read(fd, (void*)buf->_rp, sizeof(char));
-
- /* We got a character */
- if(l == 1)
- {
- /* Skip junky CRLFs */
- if(*(buf->_rp) == '\r')
- {
- *(buf->_rp) = ' ';
- continue;
- }
-
- /* End of line */
- else if(*(buf->_rp) == '\n')
- {
- buf->_rp++;
- break;
- }
-
- /* All other characters */
- else
- {
- buf->_rp++;
- }
- }
-
- /* If it's the end of file then return that */
- else if(l == 0)
- return 0;
-
- /* Transient errors */
- else if(l == -1 && errno == EAGAIN)
- continue;
+ if(ha_buferr(buf))
+ return 0;
- /* Fatal errors */
- else if(l == -1)
+ for(;;)
{
- if(errno != EINTR)
- ha_message(LOG_ERR, "couldn't read data");
-
- return 0;
+ buffer_bump(buf, 1);
+ l = read(fd, (void*)buf->_rp, sizeof(char));
+
+ /* We got a character */
+ if(l == 1)
+ {
+ /* Skip junky CRLFs */
+ if(*(buf->_rp) == '\r')
+ {
+ *(buf->_rp) = ' ';
+ continue;
+ }
+
+ /* End of line */
+ else if(*(buf->_rp) == '\n')
+ {
+ buf->_rp++;
+ break;
+ }
+
+ /* All other characters */
+ else
+ {
+ buf->_rp++;
+ }
+ }
+
+ /* If it's the end of file then return that */
+ else if(l == 0)
+ return 0;
+
+ /* Transient errors */
+ else if(l == -1 && errno == EAGAIN)
+ continue;
+
+ /* Fatal errors */
+ else if(l == -1)
+ {
+ if(errno != EINTR)
+ ha_message(NULL, LOG_ERR, "couldn't read data");
+
+ return 0;
+ }
}
- }
- return 1;
+ return 1;
}
char* ha_bufparseword(ha_buffer_t* buf, const char* delims)
{
- char* word = NULL;
+ char* word = NULL;
- ASSERT(buf && delims);
+ ASSERT(buf && delims);
- if(ha_buferr(buf))
- return NULL;
-
- /* Knock out any previous delims */
- while(buf->_pp < buf->_rp && strchr(delims, *(buf->_pp)))
- buf->_pp++;
+ if(ha_buferr(buf))
+ return NULL;
- /* If at end of buffer or end of line return null */
- if(buf->_pp == buf->_rp || *(buf->_pp) == '\n')
- return NULL;
+ /* Knock out any previous delims */
+ while(buf->_pp < buf->_rp && strchr(delims, *(buf->_pp)))
+ buf->_pp++;
- /* We do this before we stash away a pointer */
- buffer_bump(buf, 1);
+ /* If at end of buffer or end of line return null */
+ if(buf->_pp == buf->_rp || *(buf->_pp) == '\n')
+ return NULL;
- word = buf->_pp;
+ /* We do this before we stash away a pointer */
+ buffer_bump(buf, 1);
- while(!strchr(delims, *(buf->_pp)))
- {
- buf->_pp++;
+ word = buf->_pp;
- /* At the end of the buffer */
- if(buf->_pp == buf->_rp)
+ while(!strchr(delims, *(buf->_pp)))
{
- *(buf->_rp) = 0;
- buf->_rp++;
- break;
+ buf->_pp++;
+
+ /* At the end of the buffer */
+ if(buf->_pp == buf->_rp)
+ {
+ *(buf->_rp) = 0;
+ buf->_rp++;
+ break;
+ }
+
+ /* At the end of a line */
+ else if(*(buf->_pp) == '\n')
+ break;
}
- /* At the end of a line */
- else if(*(buf->_pp) == '\n')
- break;
- }
-
- /* Now null terminate what we found */
- *(buf->_pp) = 0;
- buf->_pp++;
+ /* Now null terminate what we found */
+ *(buf->_pp) = 0;
+ buf->_pp++;
- /* We don't return empty strings */
- if(word[0] == 0)
- return NULL;
+ /* We don't return empty strings */
+ if(word[0] == 0)
+ return NULL;
- return word;
+ return word;
}
char* ha_bufparseline(ha_buffer_t* buf, int trim)
{
- char* t;
- char* line = NULL;
+ char* t;
+ char* line = NULL;
- ASSERT(buf);
+ ASSERT(buf);
- if(ha_buferr(buf))
- return NULL;
+ if(ha_buferr(buf))
+ return NULL;
- if(trim)
- {
- /* Knock out any previous whitespace */
- while(buf->_pp < buf->_rp && isblank(*(buf->_pp)))
- buf->_pp++;
- }
+ if(trim)
+ {
+ /* Knock out any previous whitespace */
+ while(buf->_pp < buf->_rp && isblank(*(buf->_pp)))
+ buf->_pp++;
+ }
- if(buf->_pp == buf->_rp)
- return NULL;
+ if(buf->_pp == buf->_rp)
+ return NULL;
- /* We do this before we stash away a pointer */
- buffer_bump(buf, 1);
+ /* We do this before we stash away a pointer */
+ buffer_bump(buf, 1);
- line = buf->_pp;
+ line = buf->_pp;
- t = (char*)memchr(buf->_pp, '\n', ha_buflen(buf));
- if(t == NULL)
- {
- t = (buf->_rp);
- buf->_rp++;
- }
+ t = (char*)memchr(buf->_pp, '\n', ha_buflen(buf));
+ if(t == NULL)
+ {
+ t = (buf->_rp);
+ buf->_rp++;
+ }
- *t = 0;
- buf->_pp = t + 1;
+ *t = 0;
+ buf->_pp = t + 1;
- if(trim)
- line = trim_space(line);
+ if(trim)
+ line = trim_space(line);
- /* We don't return empty strings */
- if(line[0] == 0)
- return NULL;
+ /* We don't return empty strings */
+ if(line[0] == 0)
+ return NULL;
- return line;
+ return line;
}
char* ha_bufmcat(ha_buffer_t* buf, ...)
{
- const char* str;
- va_list ap;
+ const char* str;
+ va_list ap;
- ASSERT(buf);
+ ASSERT(buf);
- va_start(ap, buf);
+ va_start(ap, buf);
- if(ha_buferr(buf))
- return NULL;
+ if(ha_buferr(buf))
+ return NULL;
- if(!BUF_IN_JOIN(buf))
- BUF_NEW_BLOCK(buf);
+ if(!BUF_IN_JOIN(buf))
+ BUF_NEW_BLOCK(buf);
- while((str = va_arg(ap, char*)) != NULL)
- {
- int len = strlen(str);
+ while((str = va_arg(ap, char*)) != NULL)
+ {
+ int len = strlen(str);
- /* Always add one for the terminating char */
- buffer_bump(buf, len + 1);
+ /* Always add one for the terminating char */
+ buffer_bump(buf, len + 1);
- if(ha_buferr(buf))
- return NULL;
+ if(ha_buferr(buf))
+ return NULL;
- /* _rp always points to the next write point */
- strcpy(buf->_rp, str);
- buf->_rp += len;
- }
+ /* _rp always points to the next write point */
+ strcpy(buf->_rp, str);
+ buf->_rp += len;
+ }
- buf->_rp++;
- return buf->_pp;
+ buf->_rp++;
+ return buf->_pp;
}
char* ha_bufcpy(ha_buffer_t* buf, const char* src)
{
- size_t len;
+ size_t len;
- ASSERT(buf && src);
+ ASSERT(buf && src);
- len = strlen(src);
- return ha_bufncpy(buf, src, len);
+ len = strlen(src);
+ return ha_bufncpy(buf, src, len);
}
char* ha_bufncpy(ha_buffer_t* buf, const char* src, size_t len)
{
- ASSERT(buf && src);
+ ASSERT(buf && src);
- if(ha_buferr(buf))
- return NULL;
+ if(ha_buferr(buf))
+ return NULL;
- /* Always add one for the terminating char */
- buffer_bump(buf, len + 1);
+ /* Always add one for the terminating char */
+ buffer_bump(buf, len + 1);
- if(ha_buferr(buf))
- return NULL;
+ if(ha_buferr(buf))
+ return NULL;
- if(!BUF_IN_JOIN(buf))
- BUF_NEW_BLOCK(buf);
+ if(!BUF_IN_JOIN(buf))
+ BUF_NEW_BLOCK(buf);
- memcpy(buf->_rp, src, len * sizeof(char));
- buf->_rp += (len + 1);
- *(buf->_rp - 1) = 0;
- return buf->_pp;
+ memcpy(buf->_rp, src, len * sizeof(char));
+ buf->_rp += (len + 1);
+ *(buf->_rp - 1) = 0;
+ return buf->_pp;
}
void* ha_bufmalloc(ha_buffer_t* buf, size_t sz)
{
- void* ret;
+ void* ret;
- ASSERT(buf && sz);
+ ASSERT(buf && sz);
- if(ha_buferr(buf))
- return NULL;
+ if(ha_buferr(buf))
+ return NULL;
- /* TODO: Align memory on an appropriate boundary here */
- buffer_bump(buf, sz);
+ /* TODO: Align memory on an appropriate boundary here */
+ buffer_bump(buf, sz);
- if(ha_buferr(buf))
- return NULL;
+ if(ha_buferr(buf))
+ return NULL;
- BUF_NEW_BLOCK(buf);
- ret = (void*)buf->_pp;
- buf->_rp += sz;
- buf->_pp = buf->_rp;
- return ret;
+ BUF_NEW_BLOCK(buf);
+ ret = (void*)buf->_pp;
+ buf->_rp += sz;
+ buf->_pp = buf->_rp;
+ return ret;
}
void* ha_bufmemdup(ha_buffer_t* buf, const void* src, size_t bytes)
{
- void* mem;
+ void* mem;
- ASSERT(buf && src && bytes);
+ ASSERT(buf && src && bytes);
- if((mem = ha_bufmalloc(buf, bytes)) != NULL)
- memcpy(mem, src, bytes);
+ if((mem = ha_bufmalloc(buf, bytes)) != NULL)
+ memcpy(mem, src, bytes);
- return mem;
+ return mem;
}
/*
@@ -457,251 +457,251 @@ static const char PAD64C = '=';
char* ha_bufenc64(ha_buffer_t* buf, const void* source, size_t len)
{
- unsigned char input[3];
- unsigned char output[4];
- unsigned char* src = (unsigned char*)source;
- size_t i;
+ unsigned char input[3];
+ unsigned char output[4];
+ unsigned char* src = (unsigned char*)source;
+ size_t i;
- ASSERT(buf && source && len);
-
- if(ha_buferr(buf))
- return NULL;
-
- if(!BUF_IN_JOIN(buf))
- BUF_NEW_BLOCK(buf);
-
- while(2 < len)
- {
- input[0] = *src++;
- input[1] = *src++;
- input[2] = *src++;
- len -= 3;
-
- output[0] = input[0] >> 2;
- output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
- output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
- output[3] = input[2] & 0x3f;
-
- /* This also accounts for the null terminator */
- buffer_bump(buf, 5);
+ ASSERT(buf && source && len);
if(ha_buferr(buf))
- return NULL;
-
- *(buf->_rp++) = BASE64C[output[0]];
- *(buf->_rp++) = BASE64C[output[1]];
- *(buf->_rp++) = BASE64C[output[2]];
- *(buf->_rp++) = BASE64C[output[3]];
- }
+ return NULL;
- /* Now we worry about padding. */
- if(0 != len)
- {
- /* Get what's left. */
- input[0] = input[1] = input[2] = '\0';
- for(i = 0; i < len; i++)
- input[i] = *src++;
+ if(!BUF_IN_JOIN(buf))
+ BUF_NEW_BLOCK(buf);
- output[0] = input[0] >> 2;
- output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
- output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
-
- /* This also accounts for the null terminator */
- buffer_bump(buf, 5);
-
- if(ha_buferr(buf))
- return NULL;
+ while(2 < len)
+ {
+ input[0] = *src++;
+ input[1] = *src++;
+ input[2] = *src++;
+ len -= 3;
+
+ output[0] = input[0] >> 2;
+ output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+ output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+ output[3] = input[2] & 0x3f;
+
+ /* This also accounts for the null terminator */
+ buffer_bump(buf, 5);
+
+ if(ha_buferr(buf))
+ return NULL;
+
+ *(buf->_rp++) = BASE64C[output[0]];
+ *(buf->_rp++) = BASE64C[output[1]];
+ *(buf->_rp++) = BASE64C[output[2]];
+ *(buf->_rp++) = BASE64C[output[3]];
+ }
- *(buf->_rp++) = BASE64C[output[0]];
- *(buf->_rp++) = BASE64C[output[1]];
- if(len == 1)
- *(buf->_rp++) = PAD64C;
- else
- *(buf->_rp++) = BASE64C[output[2]];
- *(buf->_rp++) = PAD64C;
- }
+ /* Now we worry about padding. */
+ if(0 != len)
+ {
+ /* Get what's left. */
+ input[0] = input[1] = input[2] = '\0';
+ for(i = 0; i < len; i++)
+ input[i] = *src++;
+
+ output[0] = input[0] >> 2;
+ output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
+ output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
+
+ /* This also accounts for the null terminator */
+ buffer_bump(buf, 5);
+
+ if(ha_buferr(buf))
+ return NULL;
+
+ *(buf->_rp++) = BASE64C[output[0]];
+ *(buf->_rp++) = BASE64C[output[1]];
+ if(len == 1)
+ *(buf->_rp++) = PAD64C;
+ else
+ *(buf->_rp++) = BASE64C[output[2]];
+ *(buf->_rp++) = PAD64C;
+ }
- *(buf->_rp++) = '\0';
- return buf->_pp;
+ *(buf->_rp++) = '\0';
+ return buf->_pp;
}
void* ha_bufdec64(ha_buffer_t* buf, const char* src, size_t* bytes)
{
- int state = 0;
- int ch;
- char* pos;
- void* ret;
- size_t todo = 0;
- size_t done = 0;
-
- ASSERT(buf && src);
-
- if(ha_buferr(buf))
- return NULL;
-
- BUF_NEW_BLOCK(buf);
+ int state = 0;
+ int ch;
+ char* pos;
+ void* ret;
+ size_t todo = 0;
+ size_t done = 0;
- if(!bytes || *bytes == 0)
- todo = ~0;
- else
- todo = *bytes;
+ ASSERT(buf && src);
- while((ch = *src++) != '\0' && done < todo)
- {
- if(isspace(ch)) /* Skip whitespace anywhere. */
- continue;
-
- if(ch == PAD64C)
- break;
-
- pos = strchr(BASE64C, ch);
- if(pos == 0) /* A non-base64 character. */
- break;
+ if(ha_buferr(buf))
+ return NULL;
- buffer_bump(buf, 4);
+ BUF_NEW_BLOCK(buf);
- if(ha_buferr(buf))
- return NULL;
+ if(!bytes || *bytes == 0)
+ todo = ~0;
+ else
+ todo = *bytes;
- switch(state)
+ while((ch = *src++) != '\0' && done < todo)
{
- case 0:
- *(buf->_rp) = (pos - BASE64C) << 2;
- state = 1;
- break;
-
- case 1:
- *(buf->_rp++) |= (pos - BASE64C) >> 4;
- done++;
- *(buf->_rp) = ((pos - BASE64C) & 0x0f) << 4;
- state = 2;
- break;
-
- case 2:
- *(buf->_rp++) |= (pos - BASE64C) >> 2;
- done++;
- *(buf->_rp) = ((pos - BASE64C) & 0x03) << 6;
- state = 3;
- break;
-
- case 3:
- *(buf->_rp++) |= (pos - BASE64C);
- done++;
- state = 0;
- break;
- };
- }
-
- if(state != 3)
- buf->_rp++;
+ if(isspace(ch)) /* Skip whitespace anywhere. */
+ continue;
+
+ if(ch == PAD64C)
+ break;
+
+ pos = strchr(BASE64C, ch);
+ if(pos == 0) /* A non-base64 character. */
+ break;
+
+ buffer_bump(buf, 4);
+
+ if(ha_buferr(buf))
+ return NULL;
+
+ switch(state)
+ {
+ case 0:
+ *(buf->_rp) = (pos - BASE64C) << 2;
+ state = 1;
+ break;
+
+ case 1:
+ *(buf->_rp++) |= (pos - BASE64C) >> 4;
+ done++;
+ *(buf->_rp) = ((pos - BASE64C) & 0x0f) << 4;
+ state = 2;
+ break;
+
+ case 2:
+ *(buf->_rp++) |= (pos - BASE64C) >> 2;
+ done++;
+ *(buf->_rp) = ((pos - BASE64C) & 0x03) << 6;
+ state = 3;
+ break;
+
+ case 3:
+ *(buf->_rp++) |= (pos - BASE64C);
+ done++;
+ state = 0;
+ break;
+ };
+ }
+
+ if(state != 3)
+ buf->_rp++;
- /* TODO: Validate ending and return error if invalid somehow */
+ /* TODO: Validate ending and return error if invalid somehow */
- /* We always null terminate anyway */
- *(buf->_rp++) = 0;
+ /* We always null terminate anyway */
+ *(buf->_rp++) = 0;
- if(bytes)
- *bytes = done;
+ if(bytes)
+ *bytes = done;
- ret = (void*)buf->_pp;
- buf->_pp = buf->_rp;
- return ret;
+ ret = (void*)buf->_pp;
+ buf->_pp = buf->_rp;
+ return ret;
}
static const char HEXC[] = "0123456789abcdef";
char* ha_bufenchex(ha_buffer_t* buf, const void* source, size_t len)
{
- unsigned char* src = (unsigned char*)source;
- unsigned char j;
+ unsigned char* src = (unsigned char*)source;
+ unsigned char j;
- ASSERT(buf && source && len);
+ ASSERT(buf && source && len);
- buffer_bump(buf, (len * 2) + 1);
+ buffer_bump(buf, (len * 2) + 1);
- if(ha_buferr(buf))
- return NULL;
+ if(ha_buferr(buf))
+ return NULL;
- if(!BUF_IN_JOIN(buf))
- BUF_NEW_BLOCK(buf);
+ if(!BUF_IN_JOIN(buf))
+ BUF_NEW_BLOCK(buf);
- while(len > 0)
- {
- j = *(src) >> 4 & 0xf;
- *(buf->_rp++) = HEXC[j];
+ while(len > 0)
+ {
+ j = *(src) >> 4 & 0xf;
+ *(buf->_rp++) = HEXC[j];
- j = *(src++) & 0xf;
- *(buf->_rp++) = HEXC[j];
+ j = *(src++) & 0xf;
+ *(buf->_rp++) = HEXC[j];
- len--;
- }
+ len--;
+ }
- *(buf->_rp++) = 0;
- return buf->_pp;
+ *(buf->_rp++) = 0;
+ return buf->_pp;
}
void* ha_bufdechex(ha_buffer_t* buf, const char* src, size_t* bytes)
{
- unsigned short j;
- int state = 0;
- char* pos;
- void* ret;
- size_t done = 0;
- size_t todo = 0;
-
- ASSERT(buf && src);
-
- if(bytes && *bytes != 0)
- {
- buffer_bump(buf, *bytes + 1);
- todo = *bytes;
- }
- else
- {
- todo = ~0;
- buffer_bump(buf, (strlen(src) / 2) + 1);
- }
-
- if(ha_buferr(buf))
- return NULL;
-
- BUF_NEW_BLOCK(buf);
-
- while(src[0] && done < todo)
- {
- /* Find the position */
- pos = strchr(HEXC, tolower(src[0]));
- if(pos == 0)
- break;
-
- j = pos - HEXC;
-
- if(!state)
+ unsigned short j;
+ int state = 0;
+ char* pos;
+ void* ret;
+ size_t done = 0;
+ size_t todo = 0;
+
+ ASSERT(buf && src);
+
+ if(bytes && *bytes != 0)
{
- *(buf->_rp) = (j & 0xf) << 4;
- state = 1;
+ buffer_bump(buf, *bytes + 1);
+ todo = *bytes;
}
else
{
- *(buf->_rp++) |= (j & 0xf);
- done++;
- state = 0;
+ todo = ~0;
+ buffer_bump(buf, (strlen(src) / 2) + 1);
}
- src++;
- }
+ if(ha_buferr(buf))
+ return NULL;
+
+ BUF_NEW_BLOCK(buf);
+
+ while(src[0] && done < todo)
+ {
+ /* Find the position */
+ pos = strchr(HEXC, tolower(src[0]));
+ if(pos == 0)
+ break;
+
+ j = pos - HEXC;
+
+ if(!state)
+ {
+ *(buf->_rp) = (j & 0xf) << 4;
+ state = 1;
+ }
+ else
+ {
+ *(buf->_rp++) |= (j & 0xf);
+ done++;
+ state = 0;
+ }
+
+ src++;
+ }
- /* We always null terminate anyway */
- *(buf->_rp++) = 0;
+ /* We always null terminate anyway */
+ *(buf->_rp++) = 0;
- /* All bytes have to come in pairs */
- if(state != 0)
- return NULL;
+ /* All bytes have to come in pairs */
+ if(state != 0)
+ return NULL;
- if(bytes)
- *bytes = done;
+ if(bytes)
+ *bytes = done;
- ret = (void*)buf->_pp;
- buf->_pp = buf->_rp;
- return ret;
+ ret = (void*)buf->_pp;
+ buf->_pp = buf->_rp;
+ return ret;
}