parser: fixes routing-only mode, set valueParsed & valueLength for data as well; render: added support for rendering raw content

This commit is contained in:
tg(x) 2011-05-06 00:13:37 +02:00
parent fea30e3688
commit fd5d886053
6 changed files with 116 additions and 46 deletions

View File

@ -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;
/** /**

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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?

View File

@ -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;