fix for 0 length content/modifiers

This commit is contained in:
Gabor Adam Toth 2011-05-04 17:46:20 +02:00
parent c0a6ba7530
commit 29a72caf6f
4 changed files with 37 additions and 26 deletions

View File

@ -4,6 +4,12 @@
#include <math.h> #include <math.h>
static inline
size_t psyc_getNumLength(size_t n)
{
return n < 10 ? 1 : log10(n) + 1;
}
inline inline
psycListFlag psyc_checkListLength (psycList *list) psycListFlag psyc_checkListLength (psycList *list)
{ {
@ -37,7 +43,7 @@ psycListFlag psyc_getListLength (psycList *list)
{ {
if (i > 0) if (i > 0)
length++; // | length++; // |
length += log10((double)list->elems[i].length) + 2 + list->elems[i].length; // length SP elem length += psyc_getNumLength(list->elems[i].length) + 1 + list->elems[i].length; // length SP elem
} }
} }
else else
@ -69,8 +75,8 @@ size_t psyc_getModifierLength (psycModifier *m)
m->name.length + 1 + // name\t m->name.length + 1 + // name\t
m->value.length + 1; // value\n m->value.length + 1; // value\n
if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed if (m->flag == PSYC_MODIFIER_NEED_LENGTH && m->value.length) // add length of length if needed
length += log10((double)m->value.length) + 2; // SP length length += psyc_getNumLength(m->value.length) + 1; // SP length
return length; return length;
} }
@ -121,12 +127,11 @@ size_t psyc_setPacketLength(psycPacket *p)
// set total length: routing-header content |\n // set total length: routing-header content |\n
p->length = p->routingLength + p->contentLength + 2; p->length = p->routingLength + p->contentLength + 2;
if (p->contentLength > 0) if (p->contentLength > 0 || p->flag == PSYC_PACKET_NEED_LENGTH)
{
p->length++; // add \n at the start of the content part p->length++; // add \n at the start of the content part
if (p->flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed
p->length += log10((double)p->contentLength) + 1; if (p->flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed
} p->length += psyc_getNumLength(p->contentLength);
return p->length; return p->length;
} }

View File

@ -8,14 +8,13 @@
#include <psyc/lib.h> #include <psyc/lib.h>
#include <psyc/parser.h> #include <psyc/parser.h>
#define PSYC_ADVANCE_CURSOR_OR_RETURN(ret) \ #define ADVANCE_CURSOR_OR_RETURN(ret) \
if (++(state->cursor) >= state->buffer.length) \ if (++(state->cursor) >= state->buffer.length) \
{ \ { \
state->cursor = state->startc; \ state->cursor = state->startc; \
return ret; \ return ret; \
} }
/** /**
* Determines if the argument is a glyph. * Determines if the argument is a glyph.
* Glyphs are: : = + - ? ! * Glyphs are: : = + - ? !
@ -82,7 +81,7 @@ psycParseRC psyc_parseKeyword (psycParseState* state, psycString* name)
while (isKwChar(state->buffer.ptr[state->cursor])) while (isKwChar(state->buffer.ptr[state->cursor]))
{ {
name->length++; // was a valid char, increase length name->length++; // was a valid char, increase length
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
} }
return name->length > 0 ? PSYC_PARSE_SUCCESS : PSYC_PARSE_ERROR; return name->length > 0 ? PSYC_PARSE_SUCCESS : PSYC_PARSE_ERROR;
@ -130,7 +129,7 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper,
psycString *name, psycString *value) psycString *name, psycString *value)
{ {
*oper = *(state->buffer.ptr + state->cursor); *oper = *(state->buffer.ptr + state->cursor);
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
psycParseRC ret = psyc_parseKeyword(state, name); psycParseRC ret = psyc_parseKeyword(state, name);
if (ret == PSYC_PARSE_ERROR) if (ret == PSYC_PARSE_ERROR)
@ -147,14 +146,14 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper,
// If we're in the content part check if it's a binary var. // If we're in the content part check if it's a binary var.
if (state->part == PSYC_PART_CONTENT && state->buffer.ptr[state->cursor] == ' ') // binary arg if (state->part == PSYC_PART_CONTENT && state->buffer.ptr[state->cursor] == ' ') // binary arg
{ // After SP the length follows. { // After SP the length follows.
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
if (isNumeric(state->buffer.ptr[state->cursor])) if (isNumeric(state->buffer.ptr[state->cursor]))
{ {
do do
{ {
length = 10 * length + state->buffer.ptr[state->cursor] - '0'; length = 10 * length + state->buffer.ptr[state->cursor] - '0';
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
} }
while (isNumeric(state->buffer.ptr[state->cursor])); while (isNumeric(state->buffer.ptr[state->cursor]));
state->valueLength = length; state->valueLength = length;
@ -177,13 +176,13 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper,
} }
else if (state->buffer.ptr[state->cursor] == '\t') // simple arg else if (state->buffer.ptr[state->cursor] == '\t') // simple arg
{ {
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
value->ptr = state->buffer.ptr + state->cursor; value->ptr = state->buffer.ptr + state->cursor;
while (state->buffer.ptr[state->cursor] != '\n') while (state->buffer.ptr[state->cursor] != '\n')
{ {
value->length++; value->length++;
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
} }
return PSYC_PARSE_SUCCESS; return PSYC_PARSE_SUCCESS;
@ -233,7 +232,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
{ {
if (state->buffer.ptr[state->cursor] != '\n') if (state->buffer.ptr[state->cursor] != '\n')
return PSYC_PARSE_ERROR_MOD_NL; return PSYC_PARSE_ERROR_MOD_NL;
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
} }
// Each line of the header starts with a glyph, // Each line of the header starts with a glyph,
@ -262,7 +261,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
do do
{ {
state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0'; state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0';
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
} }
while (isNumeric(state->buffer.ptr[state->cursor])); while (isNumeric(state->buffer.ptr[state->cursor]));
} }
@ -292,7 +291,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
} }
state->startc = state->cursor + 1; state->startc = state->cursor + 1;
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
// fall thru // fall thru
case PSYC_PART_CONTENT: case PSYC_PART_CONTENT:
@ -314,7 +313,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
{ {
if (state->buffer.ptr[state->cursor] != '\n') if (state->buffer.ptr[state->cursor] != '\n')
return PSYC_PARSE_ERROR_MOD_NL; return PSYC_PARSE_ERROR_MOD_NL;
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
} }
// Each line of the header starts with a glyph, // Each line of the header starts with a glyph,
@ -361,7 +360,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
state->part = PSYC_PART_DATA; state->part = PSYC_PART_DATA;
} }
else // otherwise keep it at the beginning of method else // otherwise keep it at the beginning of method
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
// fall thru // fall thru
} }
@ -421,7 +420,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
} }
} }
value->length++; value->length++;
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
} }
} }
@ -505,7 +504,7 @@ psycParseListRC psyc_parseList (psycParseListState* state, psycString *name,
do do
{ {
state->elemLength = 10 * state->elemLength + state->buffer.ptr[state->cursor] - '0'; state->elemLength = 10 * state->elemLength + state->buffer.ptr[state->cursor] - '0';
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE); ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE);
} }
while (isNumeric(state->buffer.ptr[state->cursor])); while (isNumeric(state->buffer.ptr[state->cursor]));
} }

View File

@ -82,8 +82,9 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen)
if (packet->flag == PSYC_PACKET_NEED_LENGTH) if (packet->flag == PSYC_PACKET_NEED_LENGTH)
cur += itoa(packet->contentLength, buffer + cur, 10); cur += itoa(packet->contentLength, buffer + cur, 10);
if (packet->entity.lines || packet->method.length || packet->data.length) if (packet->flag == PSYC_PACKET_NEED_LENGTH ||
buffer[cur++] = '\n'; // start of content part if there's content packet->entity.lines || packet->method.length || packet->data.length)
buffer[cur++] = '\n'; // start of content part if there's content or length
// render entity modifiers // render entity modifiers
for (i = 0; i < packet->entity.lines; i++) for (i = 0; i < packet->entity.lines; i++)
@ -94,11 +95,11 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen)
memcpy(buffer + cur, packet->method.ptr, packet->method.length); memcpy(buffer + cur, packet->method.ptr, packet->method.length);
cur += packet->method.length; cur += packet->method.length;
buffer[cur++] = '\n'; buffer[cur++] = '\n';
if (packet->data.length) // add data\n if (packet->data.length) // add data\n
{ {
memcpy(buffer + cur, packet->data.ptr, packet->data.length); memcpy(buffer + cur, packet->data.ptr, packet->data.length);
cur += packet->data.length; cur += packet->data.length;
buffer[cur++] = '\n'; buffer[cur++] = '\n';
} }
} }

View File

@ -9,6 +9,8 @@ uint8_t verbose;
psycTextValueRC getValueFooBar (const char *name, size_t len, psycString *value) psycTextValueRC getValueFooBar (const char *name, size_t len, psycString *value)
{ {
if (verbose)
printf("> getValue: %.*s\n", (int)len, name);
value->ptr = "Foo Bar"; value->ptr = "Foo Bar";
value->length = 7; value->length = 7;
return PSYC_TEXT_VALUE_FOUND; return PSYC_TEXT_VALUE_FOUND;
@ -16,6 +18,8 @@ psycTextValueRC getValueFooBar (const char *name, size_t len, psycString *value)
psycTextValueRC getValueEmpty (const char *name, size_t len, psycString *value) psycTextValueRC getValueEmpty (const char *name, size_t len, psycString *value)
{ {
if (verbose)
printf("> getValue: %.*s\n", (int)len, name);
value->ptr = ""; value->ptr = "";
value->length = 0; value->length = 0;
return PSYC_TEXT_VALUE_FOUND; return PSYC_TEXT_VALUE_FOUND;
@ -23,6 +27,8 @@ psycTextValueRC getValueEmpty (const char *name, size_t len, psycString *value)
psycTextValueRC getValueNotFound (const char *name, size_t len, psycString *value) psycTextValueRC getValueNotFound (const char *name, size_t len, psycString *value)
{ {
if (verbose)
printf("> getValue: %.*s\n", (int)len, name);
return PSYC_TEXT_VALUE_NOT_FOUND; return PSYC_TEXT_VALUE_NOT_FOUND;
} }