From fd5d886053ae81c2b0d52ec0cccec5e3d037ab13 Mon Sep 17 00:00:00 2001 From: "tg(x)" <*@tg-x.net> Date: Fri, 6 May 2011 00:13:37 +0200 Subject: [PATCH] parser: fixes routing-only mode, set valueParsed & valueLength for data as well; render: added support for rendering raw content --- include/psyc.h | 12 +++++------ include/psyc/packet.h | 8 +++++++ include/psyc/parser.h | 2 +- src/packet.c | 47 +++++++++++++++++++++++++++++++++-------- src/parser.c | 49 ++++++++++++++++++++++++++++++++----------- src/render.c | 44 ++++++++++++++++++++++---------------- 6 files changed, 116 insertions(+), 46 deletions(-) diff --git a/include/psyc.h b/include/psyc.h index 6d8f1bc..c4fca1d 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -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; /** diff --git a/include/psyc/packet.h b/include/psyc/packet.h index 173b3d9..31c7748 100644 --- a/include/psyc/packet.h +++ b/include/psyc/packet.h @@ -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 diff --git a/include/psyc/parser.h b/include/psyc/parser.h index edbb84e..b28d064 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -4,7 +4,7 @@ * * All parsing functions and the definitions they use are * defined in this file. -*/ + */ /** * @defgroup parser Parsing Functions diff --git a/src/packet.c b/src/packet.c index 5fbfccc..d96e31a 100644 --- a/src/packet.c +++ b/src/packet.c @@ -114,15 +114,20 @@ size_t psyc_setPacketLength(psycPacket *p) for (i = 0; i < p->routing.lines; i++) p->routingLength += psyc_getModifierLength(&(p->routing.modifiers[i])); - // add entity header length - for (i = 0; i < p->entity.lines; i++) - p->contentLength += psyc_getModifierLength(&(p->entity.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])); - // add length of method, data & delimiter - if (p->method.length) - p->contentLength += p->method.length + 1; // method\n - if (p->data.length) - p->contentLength += p->data.length + 1; // data\n + // add length of method, data & delimiter + if (p->method.length) + 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); +} diff --git a/src/parser.c b/src/parser.c index b706c50..36c8bb9 100644 --- a/src/parser.c +++ b/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) - return PSYC_PARSE_BODY_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 (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; + if (ret == PSYC_PARSE_INCOMPLETE) + return PSYC_PARSE_BODY_INCOMPLETE; + } 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? diff --git a/src/render.c b/src/render.c index 74ba859..5990f4b 100644 --- a/src/render.c +++ b/src/render.c @@ -82,29 +82,37 @@ 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 - // render entity modifiers - for (i = 0; i < packet->entity.lines; i++) - cur += psyc_renderModifier(&packet->entity.modifiers[i], buffer + cur); - - if (packet->method.length) // add method\n + if (packet->content.length) // render raw content if present { - 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'; - } + 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); + + 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 buffer[cur++] = C_GLYPH_PACKET_DELIMITER;