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
|
||||
{
|
||||
PSYC_PART_RESET = -1,
|
||||
PSYC_PART_ROUTING,
|
||||
PSYC_PART_LENGTH,
|
||||
PSYC_PART_CONTENT,
|
||||
PSYC_PART_METHOD,
|
||||
PSYC_PART_DATA,
|
||||
PSYC_PART_END,
|
||||
PSYC_PART_ROUTING = 0,
|
||||
PSYC_PART_LENGTH = 1,
|
||||
PSYC_PART_CONTENT = 2,
|
||||
PSYC_PART_METHOD = 3,
|
||||
PSYC_PART_DATA = 4,
|
||||
PSYC_PART_END = 5,
|
||||
} psycPart;
|
||||
|
||||
/**
|
||||
|
|
|
@ -56,6 +56,7 @@ typedef struct
|
|||
psycHeader entity; ///< Entity header.
|
||||
psycString method;
|
||||
psycString data;
|
||||
psycString content;
|
||||
size_t routingLength; ///< Length of routing part.
|
||||
size_t contentLength; ///< Length of content part.
|
||||
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,
|
||||
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
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* All parsing functions and the definitions they use are
|
||||
* defined in this file.
|
||||
*/
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup parser Parsing Functions
|
||||
|
|
31
src/packet.c
31
src/packet.c
|
@ -114,6 +114,10 @@ size_t psyc_setPacketLength(psycPacket *p)
|
|||
for (i = 0; i < p->routing.lines; i++)
|
||||
p->routingLength += psyc_getModifierLength(&(p->routing.modifiers[i]));
|
||||
|
||||
if (p->content.length)
|
||||
p->contentLength = p->content.length;
|
||||
else
|
||||
{
|
||||
// add entity header length
|
||||
for (i = 0; i < p->entity.lines; i++)
|
||||
p->contentLength += psyc_getModifierLength(&(p->entity.modifiers[i]));
|
||||
|
@ -123,6 +127,7 @@ size_t psyc_setPacketLength(psycPacket *p)
|
|||
p->contentLength += p->method.length + 1; // method\n
|
||||
if (p->data.length)
|
||||
p->contentLength += p->data.length + 1; // data\n
|
||||
}
|
||||
|
||||
// set total length: routing-header content |\n
|
||||
p->length = p->routingLength + p->contentLength + 2;
|
||||
|
@ -141,7 +146,7 @@ psycPacket psyc_newPacket (psycHeader *routing, psycHeader *entity,
|
|||
psycString *method, psycString *data,
|
||||
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
|
||||
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);
|
||||
}
|
||||
|
||||
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.
|
||||
state->valueParsed = 0;
|
||||
state->valueLength = 0;
|
||||
state->valueLengthFound = 0;
|
||||
state->routingLength = 0;
|
||||
state->contentParsed = 0;
|
||||
state->contentLength = 0;
|
||||
|
@ -354,6 +355,10 @@ psycParseRC psyc_parse (psycParseState *state, char *oper,
|
|||
if (state->buffer.ptr[state->cursor] != '\n')
|
||||
return PSYC_PARSE_ERROR_METHOD;
|
||||
|
||||
state->valueLengthFound = 0;
|
||||
state->valueParsed = 0;
|
||||
state->valueLength = 0;
|
||||
|
||||
if (state->contentLengthFound)
|
||||
{ // if length was found set start position to the beginning of data
|
||||
state->cursor++;
|
||||
|
@ -362,7 +367,9 @@ psycParseRC psyc_parse (psycParseState *state, char *oper,
|
|||
state->part = PSYC_PART_DATA;
|
||||
}
|
||||
else // otherwise keep it at the beginning of method
|
||||
{
|
||||
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||
}
|
||||
|
||||
// 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->contentParsed < state->contentLength &&
|
||||
psyc_parseBinaryValue(state, value, &(state->contentLength),
|
||||
&(state->contentParsed)) == PSYC_PARSE_INCOMPLETE)
|
||||
if (!state->valueLengthFound) // start of data
|
||||
{
|
||||
state->valueLengthFound = 1;
|
||||
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 (ret == PSYC_PARSE_INCOMPLETE)
|
||||
return PSYC_PARSE_BODY_INCOMPLETE;
|
||||
|
||||
if (value->length)
|
||||
value->length--; // \n at the end is not part of the body
|
||||
|
||||
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;
|
||||
return PSYC_PARSE_BODY;
|
||||
|
@ -415,6 +424,9 @@ psycParseRC psyc_parse (psycParseState *state, char *oper,
|
|||
if (state->buffer.ptr[state->cursor+nl] == '|' &&
|
||||
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->cursor += nl;
|
||||
state->part = PSYC_PART_END;
|
||||
|
@ -428,6 +440,19 @@ psycParseRC psyc_parse (psycParseState *state, char *oper,
|
|||
|
||||
case 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
|
||||
// and the cursor should point to |
|
||||
if (state->cursor+1 >= state->buffer.length) // incremented cursor inside length?
|
||||
|
|
10
src/render.c
10
src/render.c
|
@ -82,10 +82,17 @@ 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->flag == PSYC_PACKET_NEED_LENGTH ||
|
||||
if (packet->flag == PSYC_PACKET_NEED_LENGTH || packet->content.length ||
|
||||
packet->entity.lines || packet->method.length || packet->data.length)
|
||||
buffer[cur++] = '\n'; // start of content part if there's content or length
|
||||
|
||||
if (packet->content.length) // render raw content if present
|
||||
{
|
||||
memcpy(buffer + cur, packet->content.ptr, packet->content.length);
|
||||
cur += packet->content.length;
|
||||
}
|
||||
else
|
||||
{
|
||||
// render entity modifiers
|
||||
for (i = 0; i < packet->entity.lines; i++)
|
||||
cur += psyc_renderModifier(&packet->entity.modifiers[i], buffer + cur);
|
||||
|
@ -105,6 +112,7 @@ psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen)
|
|||
}
|
||||
else if (packet->data.length) // error, we have data but no modifier
|
||||
return PSYC_RENDER_ERROR_METHOD_MISSING;
|
||||
}
|
||||
|
||||
// add packet delimiter
|
||||
buffer[cur++] = C_GLYPH_PACKET_DELIMITER;
|
||||
|
|
Loading…
Reference in a new issue