mirror of
git://git.psyc.eu/libpsyc
synced 2024-08-15 03:19:02 +00:00
parser: fixes routing-only mode, set valueParsed & valueLength for data as well; render: added support for rendering raw content
This commit is contained in:
parent
289de97bea
commit
07c6711db0
6 changed files with 116 additions and 46 deletions
|
@ -39,12 +39,12 @@ typedef enum
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
PSYC_PART_RESET = -1,
|
PSYC_PART_RESET = -1,
|
||||||
PSYC_PART_ROUTING,
|
PSYC_PART_ROUTING = 0,
|
||||||
PSYC_PART_LENGTH,
|
PSYC_PART_LENGTH = 1,
|
||||||
PSYC_PART_CONTENT,
|
PSYC_PART_CONTENT = 2,
|
||||||
PSYC_PART_METHOD,
|
PSYC_PART_METHOD = 3,
|
||||||
PSYC_PART_DATA,
|
PSYC_PART_DATA = 4,
|
||||||
PSYC_PART_END,
|
PSYC_PART_END = 5,
|
||||||
} psycPart;
|
} psycPart;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -56,6 +56,7 @@ typedef struct
|
||||||
psycHeader entity; ///< Entity header.
|
psycHeader entity; ///< Entity header.
|
||||||
psycString method;
|
psycString method;
|
||||||
psycString data;
|
psycString data;
|
||||||
|
psycString content;
|
||||||
size_t routingLength; ///< Length of routing part.
|
size_t routingLength; ///< Length of routing part.
|
||||||
size_t contentLength; ///< Length of content part.
|
size_t contentLength; ///< Length of content part.
|
||||||
size_t length; ///< Total length of packet.
|
size_t length; ///< Total length of packet.
|
||||||
|
@ -135,4 +136,11 @@ psycPacket psyc_newPacket2 (psycModifier *routing, size_t routinglen,
|
||||||
const char *data, size_t datalen,
|
const char *data, size_t datalen,
|
||||||
psycPacketFlag flag);
|
psycPacketFlag flag);
|
||||||
|
|
||||||
|
psycPacket psyc_newPacketContent (psycHeader *routing, psycString *content,
|
||||||
|
psycPacketFlag flag);
|
||||||
|
|
||||||
|
psycPacket psyc_newPacketContent2 (psycModifier *routing, size_t routinglen,
|
||||||
|
const char *content, size_t contentlen,
|
||||||
|
psycPacketFlag flag);
|
||||||
|
|
||||||
#endif // PSYC_PACKET_H
|
#endif // PSYC_PACKET_H
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
*
|
*
|
||||||
* All parsing functions and the definitions they use are
|
* All parsing functions and the definitions they use are
|
||||||
* defined in this file.
|
* defined in this file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup parser Parsing Functions
|
* @defgroup parser Parsing Functions
|
||||||
|
|
47
src/packet.c
47
src/packet.c
|
@ -114,15 +114,20 @@ size_t psyc_setPacketLength(psycPacket *p)
|
||||||
for (i = 0; i < p->routing.lines; i++)
|
for (i = 0; i < p->routing.lines; i++)
|
||||||
p->routingLength += psyc_getModifierLength(&(p->routing.modifiers[i]));
|
p->routingLength += psyc_getModifierLength(&(p->routing.modifiers[i]));
|
||||||
|
|
||||||
// add entity header length
|
if (p->content.length)
|
||||||
for (i = 0; i < p->entity.lines; i++)
|
p->contentLength = p->content.length;
|
||||||
p->contentLength += psyc_getModifierLength(&(p->entity.modifiers[i]));
|
else
|
||||||
|
{
|
||||||
|
// add entity header length
|
||||||
|
for (i = 0; i < p->entity.lines; i++)
|
||||||
|
p->contentLength += psyc_getModifierLength(&(p->entity.modifiers[i]));
|
||||||
|
|
||||||
// add length of method, data & delimiter
|
// add length of method, data & delimiter
|
||||||
if (p->method.length)
|
if (p->method.length)
|
||||||
p->contentLength += p->method.length + 1; // method\n
|
p->contentLength += p->method.length + 1; // method\n
|
||||||
if (p->data.length)
|
if (p->data.length)
|
||||||
p->contentLength += p->data.length + 1; // data\n
|
p->contentLength += p->data.length + 1; // data\n
|
||||||
|
}
|
||||||
|
|
||||||
// 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;
|
||||||
|
@ -141,7 +146,7 @@ psycPacket psyc_newPacket (psycHeader *routing, psycHeader *entity,
|
||||||
psycString *method, psycString *data,
|
psycString *method, psycString *data,
|
||||||
psycPacketFlag flag)
|
psycPacketFlag flag)
|
||||||
{
|
{
|
||||||
psycPacket p = {*routing, *entity, *method, *data, 0, 0, flag};
|
psycPacket p = {*routing, *entity, *method, *data, {0,0}, 0, 0, flag};
|
||||||
|
|
||||||
if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs a length
|
if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs a length
|
||||||
p.flag = psyc_checkPacketLength(&p);
|
p.flag = psyc_checkPacketLength(&p);
|
||||||
|
@ -164,3 +169,27 @@ psycPacket psyc_newPacket2 (psycModifier *routing, size_t routinglen,
|
||||||
|
|
||||||
return psyc_newPacket(&r, &e, &m, &d, flag);
|
return psyc_newPacket(&r, &e, &m, &d, flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
psycPacket psyc_newPacketContent (psycHeader *routing, psycString *content,
|
||||||
|
psycPacketFlag flag)
|
||||||
|
{
|
||||||
|
psycPacket p = {*routing, {0,0}, {0,0}, {0,0}, *content, 0, 0, flag};
|
||||||
|
|
||||||
|
if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs a length
|
||||||
|
p.flag = psyc_checkPacketLength(&p);
|
||||||
|
|
||||||
|
psyc_setPacketLength(&p);
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
psycPacket psyc_newPacketContent2 (psycModifier *routing, size_t routinglen,
|
||||||
|
const char *content, size_t contentlen,
|
||||||
|
psycPacketFlag flag)
|
||||||
|
{
|
||||||
|
psycHeader r = {routinglen, routing};
|
||||||
|
psycString c = {contentlen, content};
|
||||||
|
|
||||||
|
return psyc_newPacketContent(&r, &c, flag);
|
||||||
|
}
|
||||||
|
|
49
src/parser.c
49
src/parser.c
|
@ -222,6 +222,7 @@ psycParseRC psyc_parse (psycParseState *state, char *oper,
|
||||||
case PSYC_PART_RESET: // New packet starts here, reset state.
|
case PSYC_PART_RESET: // New packet starts here, reset state.
|
||||||
state->valueParsed = 0;
|
state->valueParsed = 0;
|
||||||
state->valueLength = 0;
|
state->valueLength = 0;
|
||||||
|
state->valueLengthFound = 0;
|
||||||
state->routingLength = 0;
|
state->routingLength = 0;
|
||||||
state->contentParsed = 0;
|
state->contentParsed = 0;
|
||||||
state->contentLength = 0;
|
state->contentLength = 0;
|
||||||
|
@ -354,6 +355,10 @@ 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_METHOD;
|
return PSYC_PARSE_ERROR_METHOD;
|
||||||
|
|
||||||
|
state->valueLengthFound = 0;
|
||||||
|
state->valueParsed = 0;
|
||||||
|
state->valueLength = 0;
|
||||||
|
|
||||||
if (state->contentLengthFound)
|
if (state->contentLengthFound)
|
||||||
{ // if length was found set start position to the beginning of data
|
{ // if length was found set start position to the beginning of data
|
||||||
state->cursor++;
|
state->cursor++;
|
||||||
|
@ -362,7 +367,9 @@ 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
|
||||||
|
{
|
||||||
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||||
|
}
|
||||||
|
|
||||||
// fall thru
|
// fall thru
|
||||||
}
|
}
|
||||||
|
@ -380,19 +387,21 @@ psycParseRC psyc_parse (psycParseState *state, char *oper,
|
||||||
|
|
||||||
if (state->contentLengthFound) // We know the length of the packet.
|
if (state->contentLengthFound) // We know the length of the packet.
|
||||||
{
|
{
|
||||||
if (state->contentParsed < state->contentLength &&
|
if (!state->valueLengthFound) // start of data
|
||||||
psyc_parseBinaryValue(state, value, &(state->contentLength),
|
{
|
||||||
&(state->contentParsed)) == PSYC_PARSE_INCOMPLETE)
|
state->valueLengthFound = 1;
|
||||||
return PSYC_PARSE_BODY_INCOMPLETE;
|
state->valueLength = state->contentLength - state->contentParsed; // length of data
|
||||||
|
if (state->valueLength && !(state->flags & PSYC_PARSE_ROUTING_ONLY))
|
||||||
|
state->valueLength--; // \n at the end is not part of data
|
||||||
|
}
|
||||||
|
if (state->valueParsed < state->valueLength)
|
||||||
|
{
|
||||||
|
ret = psyc_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed));
|
||||||
|
state->contentParsed += value->length;
|
||||||
|
|
||||||
if (value->length)
|
if (ret == PSYC_PARSE_INCOMPLETE)
|
||||||
value->length--; // \n at the end is not part of the body
|
return PSYC_PARSE_BODY_INCOMPLETE;
|
||||||
|
}
|
||||||
if (state->cursor >= state->buffer.length)
|
|
||||||
return PSYC_PARSE_BODY;
|
|
||||||
|
|
||||||
if (state->buffer.ptr[state->cursor] != '|')
|
|
||||||
return PSYC_PARSE_ERROR_BODY;
|
|
||||||
|
|
||||||
state->part = PSYC_PART_END;
|
state->part = PSYC_PART_END;
|
||||||
return PSYC_PARSE_BODY;
|
return PSYC_PARSE_BODY;
|
||||||
|
@ -415,6 +424,9 @@ psycParseRC psyc_parse (psycParseState *state, char *oper,
|
||||||
if (state->buffer.ptr[state->cursor+nl] == '|' &&
|
if (state->buffer.ptr[state->cursor+nl] == '|' &&
|
||||||
state->buffer.ptr[state->cursor+1+nl] == '\n') // packet ends here
|
state->buffer.ptr[state->cursor+1+nl] == '\n') // packet ends here
|
||||||
{
|
{
|
||||||
|
if (state->flags & PSYC_PARSE_ROUTING_ONLY)
|
||||||
|
value->length++;
|
||||||
|
|
||||||
state->contentParsed += state->cursor - pos;
|
state->contentParsed += state->cursor - pos;
|
||||||
state->cursor += nl;
|
state->cursor += nl;
|
||||||
state->part = PSYC_PART_END;
|
state->part = PSYC_PART_END;
|
||||||
|
@ -428,6 +440,19 @@ psycParseRC psyc_parse (psycParseState *state, char *oper,
|
||||||
|
|
||||||
case PSYC_PART_END:
|
case PSYC_PART_END:
|
||||||
PSYC_PART_END:
|
PSYC_PART_END:
|
||||||
|
if (state->contentLengthFound && state->valueLengthFound && state->valueLength &&
|
||||||
|
!(state->flags & PSYC_PARSE_ROUTING_ONLY))
|
||||||
|
{ // if data was not empty next is the \n at the end of data
|
||||||
|
state->valueLength = 0;
|
||||||
|
state->valueLengthFound = 0;
|
||||||
|
|
||||||
|
if (state->buffer.ptr[state->cursor] != '\n')
|
||||||
|
return PSYC_PARSE_ERROR_END;
|
||||||
|
|
||||||
|
state->contentParsed++;
|
||||||
|
state->cursor++;
|
||||||
|
}
|
||||||
|
|
||||||
// End of packet, at this point we have already passed a \n
|
// End of packet, at this point we have already passed a \n
|
||||||
// and the cursor should point to |
|
// and the cursor should point to |
|
||||||
if (state->cursor+1 >= state->buffer.length) // incremented cursor inside length?
|
if (state->cursor+1 >= state->buffer.length) // incremented cursor inside length?
|
||||||
|
|
44
src/render.c
44
src/render.c
|
@ -82,29 +82,37 @@ 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->flag == PSYC_PACKET_NEED_LENGTH ||
|
if (packet->flag == PSYC_PACKET_NEED_LENGTH || packet->content.length ||
|
||||||
packet->entity.lines || packet->method.length || packet->data.length)
|
packet->entity.lines || packet->method.length || packet->data.length)
|
||||||
buffer[cur++] = '\n'; // start of content part if there's content or length
|
buffer[cur++] = '\n'; // start of content part if there's content or length
|
||||||
|
|
||||||
// render entity modifiers
|
if (packet->content.length) // render raw content if present
|
||||||
for (i = 0; i < packet->entity.lines; i++)
|
|
||||||
cur += psyc_renderModifier(&packet->entity.modifiers[i], buffer + cur);
|
|
||||||
|
|
||||||
if (packet->method.length) // add method\n
|
|
||||||
{
|
{
|
||||||
memcpy(buffer + cur, packet->method.ptr, packet->method.length);
|
memcpy(buffer + cur, packet->content.ptr, packet->content.length);
|
||||||
cur += packet->method.length;
|
cur += packet->content.length;
|
||||||
buffer[cur++] = '\n';
|
}
|
||||||
|
else
|
||||||
if (packet->data.length) // add data\n
|
{
|
||||||
{
|
// render entity modifiers
|
||||||
memcpy(buffer + cur, packet->data.ptr, packet->data.length);
|
for (i = 0; i < packet->entity.lines; i++)
|
||||||
cur += packet->data.length;
|
cur += psyc_renderModifier(&packet->entity.modifiers[i], buffer + cur);
|
||||||
buffer[cur++] = '\n';
|
|
||||||
}
|
if (packet->method.length) // add method\n
|
||||||
|
{
|
||||||
|
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';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (packet->data.length) // error, we have data but no modifier
|
||||||
|
return PSYC_RENDER_ERROR_METHOD_MISSING;
|
||||||
}
|
}
|
||||||
else if (packet->data.length) // error, we have data but no modifier
|
|
||||||
return PSYC_RENDER_ERROR_METHOD_MISSING;
|
|
||||||
|
|
||||||
// add packet delimiter
|
// add packet delimiter
|
||||||
buffer[cur++] = C_GLYPH_PACKET_DELIMITER;
|
buffer[cur++] = C_GLYPH_PACKET_DELIMITER;
|
||||||
|
|
Loading…
Reference in a new issue