diff options
Diffstat (limited to 'common/buffer.c')
-rw-r--r-- | common/buffer.c | 926 |
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; } |