mirror of
git://git.psyc.eu/libpsyc
synced 2024-08-15 03:19:02 +00:00
fix for 0 length content/modifiers
This commit is contained in:
parent
a67cc24c40
commit
e7a4df6180
4 changed files with 37 additions and 26 deletions
21
src/packet.c
21
src/packet.c
|
@ -4,6 +4,12 @@
|
|||
|
||||
#include <math.h>
|
||||
|
||||
static inline
|
||||
size_t psyc_getNumLength(size_t n)
|
||||
{
|
||||
return n < 10 ? 1 : log10(n) + 1;
|
||||
}
|
||||
|
||||
inline
|
||||
psycListFlag psyc_checkListLength (psycList *list)
|
||||
{
|
||||
|
@ -37,7 +43,7 @@ psycListFlag psyc_getListLength (psycList *list)
|
|||
{
|
||||
if (i > 0)
|
||||
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
|
||||
|
@ -69,8 +75,8 @@ size_t psyc_getModifierLength (psycModifier *m)
|
|||
m->name.length + 1 + // name\t
|
||||
m->value.length + 1; // value\n
|
||||
|
||||
if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed
|
||||
length += log10((double)m->value.length) + 2; // SP length
|
||||
if (m->flag == PSYC_MODIFIER_NEED_LENGTH && m->value.length) // add length of length if needed
|
||||
length += psyc_getNumLength(m->value.length) + 1; // SP length
|
||||
|
||||
return length;
|
||||
}
|
||||
|
@ -121,12 +127,11 @@ size_t psyc_setPacketLength(psycPacket *p)
|
|||
// set total length: routing-header content |\n
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
|
29
src/parser.c
29
src/parser.c
|
@ -8,14 +8,13 @@
|
|||
#include <psyc/lib.h>
|
||||
#include <psyc/parser.h>
|
||||
|
||||
#define PSYC_ADVANCE_CURSOR_OR_RETURN(ret) \
|
||||
#define ADVANCE_CURSOR_OR_RETURN(ret) \
|
||||
if (++(state->cursor) >= state->buffer.length) \
|
||||
{ \
|
||||
state->cursor = state->startc; \
|
||||
return ret; \
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the argument is a glyph.
|
||||
* Glyphs are: : = + - ? !
|
||||
|
@ -82,7 +81,7 @@ psycParseRC psyc_parseKeyword (psycParseState* state, psycString* name)
|
|||
while (isKwChar(state->buffer.ptr[state->cursor]))
|
||||
{
|
||||
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;
|
||||
|
@ -130,7 +129,7 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper,
|
|||
psycString *name, psycString *value)
|
||||
{
|
||||
*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);
|
||||
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 (state->part == PSYC_PART_CONTENT && state->buffer.ptr[state->cursor] == ' ') // binary arg
|
||||
{ // 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]))
|
||||
{
|
||||
do
|
||||
{
|
||||
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]));
|
||||
state->valueLength = length;
|
||||
|
@ -177,13 +176,13 @@ psycParseRC psyc_parseModifier (psycParseState *state, char *oper,
|
|||
}
|
||||
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;
|
||||
|
||||
while (state->buffer.ptr[state->cursor] != '\n')
|
||||
{
|
||||
value->length++;
|
||||
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||
}
|
||||
|
||||
return PSYC_PARSE_SUCCESS;
|
||||
|
@ -233,7 +232,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
|
|||
{
|
||||
if (state->buffer.ptr[state->cursor] != '\n')
|
||||
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,
|
||||
|
@ -262,7 +261,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
|
|||
do
|
||||
{
|
||||
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]));
|
||||
}
|
||||
|
@ -292,7 +291,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
|
|||
}
|
||||
|
||||
state->startc = state->cursor + 1;
|
||||
PSYC_ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||
// fall thru
|
||||
|
||||
case PSYC_PART_CONTENT:
|
||||
|
@ -314,7 +313,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
|
|||
{
|
||||
if (state->buffer.ptr[state->cursor] != '\n')
|
||||
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,
|
||||
|
@ -361,7 +360,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
|
|||
state->part = PSYC_PART_DATA;
|
||||
}
|
||||
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
|
||||
}
|
||||
|
@ -421,7 +420,7 @@ psycParseRC psyc_parse (psycParseState* state, char* oper,
|
|||
}
|
||||
}
|
||||
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
|
||||
{
|
||||
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]));
|
||||
}
|
||||
|
|
|
@ -82,8 +82,9 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen)
|
|||
if (packet->flag == PSYC_PACKET_NEED_LENGTH)
|
||||
cur += itoa(packet->contentLength, buffer + cur, 10);
|
||||
|
||||
if (packet->entity.lines || packet->method.length || packet->data.length)
|
||||
buffer[cur++] = '\n'; // start of content part if there's content
|
||||
if (packet->flag == PSYC_PACKET_NEED_LENGTH ||
|
||||
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
|
||||
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);
|
||||
cur += packet->method.length;
|
||||
buffer[cur++] = '\n';
|
||||
|
||||
if (packet->data.length) // add data\n
|
||||
{
|
||||
memcpy(buffer + cur, packet->data.ptr, packet->data.length);
|
||||
cur += packet->data.length;
|
||||
|
||||
buffer[cur++] = '\n';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ uint8_t verbose;
|
|||
|
||||
psycTextValueRC getValueFooBar (const char *name, size_t len, psycString *value)
|
||||
{
|
||||
if (verbose)
|
||||
printf("> getValue: %.*s\n", (int)len, name);
|
||||
value->ptr = "Foo Bar";
|
||||
value->length = 7;
|
||||
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)
|
||||
{
|
||||
if (verbose)
|
||||
printf("> getValue: %.*s\n", (int)len, name);
|
||||
value->ptr = "";
|
||||
value->length = 0;
|
||||
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)
|
||||
{
|
||||
if (verbose)
|
||||
printf("> getValue: %.*s\n", (int)len, name);
|
||||
return PSYC_TEXT_VALUE_NOT_FOUND;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue