added state op return codes for psyc_parse, added stateop to PsycPacket

This commit is contained in:
Gabor Adam Toth 2011-11-09 21:22:58 +01:00
parent 27dbed5dc7
commit af6106c125
9 changed files with 91 additions and 91 deletions

View File

@ -8,27 +8,8 @@ const PSYC_CONTENT_SIZE_THRESHOLD = 444;
/* beyond this a modifier value length must be provided */
const PSYC_MODIFIER_SIZE_THRESHOLD = 404;
const C_GLYPH_PACKET_DELIMITER = '|';
const S_GLYPH_PACKET_DELIMITER = "|";
const PSYC_PACKET_DELIMITER = "\n|\n";
const C_GLYPH_SEPARATOR_KEYWORD = '_';
const S_GLYPH_SEPARATOR_KEYWORD = "_";
const C_GLYPH_OPERATOR_SET = ':';
const S_GLYPH_OPERATOR_SET = ":";
const C_GLYPH_OPERATOR_ASSIGN = '=';
const S_GLYPH_OPERATOR_ASSIGN = "=";
const C_GLYPH_OPERATOR_AUGMENT = '+';
const S_GLYPH_OPERATOR_AUGMENT = "+";
const C_GLYPH_OPERATOR_DIMINISH = '-';
const S_GLYPH_OPERATOR_DIMINISH = "-";
const C_GLYPH_OPERATOR_QUERY = '?';
const S_GLYPH_OPERATOR_QUERY = "?";
const PSYC_PACKET_DELIMITER_CHAR = '|';
const PSYC_PACKET_DELIMITER = "\n|\n";
/* might move into routing.h or something */
const PSYC_ROUTING = 1;

View File

@ -63,6 +63,13 @@ typedef enum
PSYC_OPERATOR_QUERY = '?',
} PsycOperator;
typedef enum
{
PSYC_STATE_NOOP = 0,
PSYC_STATE_RESET = '=',
PSYC_STATE_SYNC = '?',
} PsycStateOp;
/** Structure for a modifier. */
typedef struct
{
@ -91,15 +98,16 @@ typedef struct
/** Intermediate struct for a PSYC packet */
typedef struct
{
PsycHeader routing; ///< Routing header.
PsycHeader entity; ///< Entity header.
PsycString method; ///< Contains the method.
PsycString data; ///< Contains the data.
PsycString content; ///< Contains the whole content.
PsycHeader routing; ///< Routing header.
PsycHeader entity; ///< Entity header.
char stateop; ///< State operation. @see PsycStateOp
PsycString method; ///< Contains the method.
PsycString data; ///< Contains the data.
PsycString content; ///< Contains the whole content.
size_t routingLength; ///< Length of routing part.
size_t contentLength; ///< Length of content part.
size_t length; ///< Total length of packet.
PsycPacketFlag flag; ///< Packet flag.
size_t length; ///< Total length of packet.
PsycPacketFlag flag; ///< Packet flag.
} PsycPacket;
/**
@ -182,7 +190,7 @@ void psyc_packet_init (PsycPacket *packet,
PsycModifier *entity, size_t entitylen,
char *method, size_t methodlen,
char *data, size_t datalen,
PsycPacketFlag flag);
char stateop, PsycPacketFlag flag);
/** Initialize packet with raw content. */
void psyc_packet_init_raw (PsycPacket *packet,

View File

@ -152,42 +152,46 @@ typedef enum {
/// Routing modifier parsing done.
/// Operator, name & value contains the respective parts.
PSYC_PARSE_ROUTING = 2,
/// State sync operation.
PSYC_PARSE_STATE_SYNC = 3,
/// State reset operation.
PSYC_PARSE_STATE_RESET = 4,
/// Start of an incomplete entity modifier.
/// Operator & name are complete, value is incomplete.
PSYC_PARSE_ENTITY_START = 3,
PSYC_PARSE_ENTITY_START = 5,
/// Continuation of an incomplete entity modifier.
PSYC_PARSE_ENTITY_CONT = 4,
PSYC_PARSE_ENTITY_CONT = 6,
/// End of an incomplete entity modifier.
PSYC_PARSE_ENTITY_END = 5,
PSYC_PARSE_ENTITY_END = 7,
/// Entity modifier parsing done in one go.
/// Operator, name & value contains the respective parts.
PSYC_PARSE_ENTITY = 6,
PSYC_PARSE_ENTITY = 8,
/// Start of an incomplete body.
/// Name contains method, value contains part of the body.
/// Used when packet length is given
PSYC_PARSE_BODY_START = 7,
PSYC_PARSE_BODY_START = 9,
/// Continuation of an incomplete body.
/// Used when packet length is given
PSYC_PARSE_BODY_CONT = 8,
PSYC_PARSE_BODY_CONT = 10,
/// End of an incomplete body.
/// Used when packet length is given
PSYC_PARSE_BODY_END = 9,
PSYC_PARSE_BODY_END = 11,
/// Body parsing done in one go, name contains method, value contains body.
PSYC_PARSE_BODY = 10,
PSYC_PARSE_BODY = 12,
/// Start of an incomplete content, value contains part of content.
/// Used when PSYC_PARSE_ROUTING_ONLY is set.
PSYC_PARSE_CONTENT_START = 7,
PSYC_PARSE_CONTENT_START = 9,
/// Continuation of an incomplete content.
/// Used when PSYC_PARSE_ROUTING_ONLY is set.
PSYC_PARSE_CONTENT_CONT = 8,
PSYC_PARSE_CONTENT_CONT = 10,
/// End of an incomplete content.
/// Used when PSYC_PARSE_ROUTING_ONLY is set.
PSYC_PARSE_CONTENT_END = 9,
PSYC_PARSE_CONTENT_END = 11,
/// Content parsing done in one go, value contains the whole content.
/// Used when PSYC_PARSE_ROUTING_ONLY is set.
PSYC_PARSE_CONTENT = 10,
PSYC_PARSE_CONTENT = 12,
/// Finished parsing packet.
PSYC_PARSE_COMPLETE = 11,
PSYC_PARSE_COMPLETE = 13,
} PsycParseRC;
/**

View File

@ -14,32 +14,8 @@
# define PSYC_MODIFIER_SIZE_THRESHOLD 404
#endif
#define C_GLYPH_PACKET_DELIMITER '|'
#define S_GLYPH_PACKET_DELIMITER "|"
#define PSYC_PACKET_DELIMITER "\n|\n"
#define C_GLYPH_SEPARATOR_KEYWORD '_'
#define S_GLYPH_SEPARATOR_KEYWORD "_"
#define C_GLYPH_OPERATOR_SET ':'
#define S_GLYPH_OPERATOR_SET ":"
#define C_GLYPH_OPERATOR_ASSIGN '='
#define S_GLYPH_OPERATOR_ASSIGN "="
#define C_GLYPH_OPERATOR_AUGMENT '+'
#define S_GLYPH_OPERATOR_AUGMENT "+"
#define C_GLYPH_OPERATOR_DIMINISH '-'
#define S_GLYPH_OPERATOR_DIMINISH "-"
#define C_GLYPH_OPERATOR_QUERY '?'
#define S_GLYPH_OPERATOR_QUERY "?"
/* might move into routing.h or something */
#define PSYC_ROUTING 1
#define PSYC_ROUTING_MERGE 2
#define PSYC_ROUTING_RENDER 4
#define PSYC_PACKET_DELIMITER_CHAR '|'
#define PSYC_PACKET_DELIMITER "\n|\n"
#define PSYC_SYNTAX_H
#endif

View File

@ -76,7 +76,7 @@ size_t psyc_modifier_length (PsycModifier *m)
inline
PsycPacketFlag psyc_packet_length_check (PsycPacket *p)
{
if (p->data.length == 1 && p->data.data[0] == C_GLYPH_PACKET_DELIMITER)
if (p->data.length == 1 && p->data.data[0] == PSYC_PACKET_DELIMITER_CHAR)
return PSYC_PACKET_NEED_LENGTH;
if (p->data.length > PSYC_CONTENT_SIZE_THRESHOLD)
@ -110,6 +110,10 @@ size_t psyc_packet_length_set (PsycPacket *p)
p->contentLength = p->content.length;
else
{
// add state operation
if (p->stateop != PSYC_STATE_NOOP)
p->contentLength += 2; // op\n
// add entity header length
for (i = 0; i < p->entity.lines; i++)
p->contentLength += psyc_modifier_length(&(p->entity.modifiers[i]));
@ -139,9 +143,9 @@ void psyc_packet_init (PsycPacket *p,
PsycModifier *entity, size_t entitylen,
char *method, size_t methodlen,
char *data, size_t datalen,
PsycPacketFlag flag)
char stateop, PsycPacketFlag flag)
{
*p = (PsycPacket) {{routinglen, routing}, {entitylen, entity},
*p = (PsycPacket) {{routinglen, routing}, {entitylen, entity}, stateop,
{methodlen, method}, {datalen, data}, {0,0}, 0, 0, flag};
if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs length
@ -156,7 +160,7 @@ void psyc_packet_init_raw (PsycPacket *p,
char *content, size_t contentlen,
PsycPacketFlag flag)
{
*p = (PsycPacket) {{routinglen, routing}, {0,0}, {0,0}, {0,0},
*p = (PsycPacket) {{routinglen, routing}, {0,0}, 0, {0,0}, {0,0},
{contentlen, content}, 0, 0, flag};
if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs length

View File

@ -88,10 +88,6 @@ ParseRC psyc_parse_modifier (PsycParseState *state, char *oper,
*oper = *(state->buffer.data + state->cursor);
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
if (state->part == PSYC_PART_CONTENT && state->buffer.data[state->cursor] == '\n' &&
(*oper == PSYC_OPERATOR_ASSIGN || *oper == PSYC_OPERATOR_QUERY))
return PARSE_SUCCESS; // only oper is present, used for state sync/reset
ParseRC ret = psyc_parse_keyword(state, name);
if (ret == PARSE_ERROR)
return PSYC_PARSE_ERROR_MOD_NAME;
@ -287,6 +283,24 @@ PsycParseRC psyc_parse (PsycParseState *state, char *oper,
// method does not start with a glyph.
if (psyc_is_glyph(state->buffer.data[state->cursor]))
{
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
if (state->contentParsed == 0 && state->buffer.data[state->cursor] == '\n')
{
*oper = *(state->buffer.data + state->cursor - 1);
switch (*oper)
{
case PSYC_STATE_SYNC:
state->contentParsed += 2;
return PSYC_PARSE_STATE_SYNC;
case PSYC_STATE_RESET:
state->contentParsed += 2;
return PSYC_PARSE_STATE_RESET;
default:
return PSYC_PARSE_ERROR_MOD_NAME;
}
}
state->cursor--;
ret = psyc_parse_modifier(state, oper, name, value);
state->contentParsed += state->cursor - pos;

View File

@ -1,4 +1,5 @@
#include "lib.h"
#include <psyc/packet.h>
#include <psyc/render.h>
#include <psyc/syntax.h>
@ -46,25 +47,24 @@ static inline
size_t psyc_render_modifier (PsycModifier *mod, char *buffer)
{
size_t cur = 0;
buffer[cur++] = mod->oper;
memcpy(buffer + cur, mod->name.data, mod->name.length);
cur += mod->name.length;
if (cur == 1)
return cur; // error, name can't be empty
if (mod->name.length > 0)
if (mod->flag == PSYC_MODIFIER_NEED_LENGTH)
{
memcpy(buffer + cur, mod->name.data, mod->name.length);
cur += mod->name.length;
if (mod->flag == PSYC_MODIFIER_NEED_LENGTH)
{
buffer[cur++] = ' ';
cur += itoa(mod->value.length, buffer + cur, 10);
}
buffer[cur++] = '\t';
memcpy(buffer + cur, mod->value.data, mod->value.length);
cur += mod->value.length;
buffer[cur++] = ' ';
cur += itoa(mod->value.length, buffer + cur, 10);
}
buffer[cur++] = '\t';
memcpy(buffer + cur, mod->value.data, mod->value.length);
cur += mod->value.length;
buffer[cur++] = '\n';
return cur;
}
@ -92,7 +92,8 @@ PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen)
cur += itoa(packet->contentLength, buffer + cur, 10);
if (packet->flag == PSYC_PACKET_NEED_LENGTH || packet->content.length ||
packet->entity.lines || packet->method.length || packet->data.length)
packet->stateop || 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
@ -102,6 +103,11 @@ PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen)
}
else
{
if (packet->stateop) {
buffer[cur++] = packet->stateop;
buffer[cur++] = '\n';
}
// render entity modifiers
for (i = 0; i < packet->entity.lines; i++)
cur += psyc_render_modifier(&packet->entity.modifiers[i], buffer + cur);
@ -124,7 +130,7 @@ PsycRenderRC psyc_render (PsycPacket *packet, char *buffer, size_t buflen)
}
// add packet delimiter
buffer[cur++] = C_GLYPH_PACKET_DELIMITER;
buffer[cur++] = PSYC_PACKET_DELIMITER_CHAR;
buffer[cur++] = '\n';
// actual length should be equal to pre-calculated length at this point

View File

@ -98,6 +98,11 @@ int test_input (int i, char *recvbuf, size_t nbytes) {
packet->routing.lines++;
break;
case PSYC_PARSE_STATE_SYNC:
case PSYC_PARSE_STATE_RESET:
packet->stateop = oper;
break;
case PSYC_PARSE_ENTITY_START:
case PSYC_PARSE_ENTITY_CONT:
case PSYC_PARSE_ENTITY_END:

View File

@ -30,6 +30,7 @@ int testPresence (const char *avail, int availlen,
entity, PSYC_NUM_ELEM(entity),
PSYC_C2ARG("_notice_presence"),
NULL, 0,
PSYC_STATE_NOOP,
PSYC_PACKET_CHECK_LENGTH);
char buffer[512];
@ -82,6 +83,7 @@ int testList (const char *rendered, uint8_t verbose)
entity, PSYC_NUM_ELEM(entity),
PSYC_C2ARG("_test_list"),
PSYC_C2ARG("list test"),
PSYC_STATE_NOOP,
PSYC_PACKET_CHECK_LENGTH);
char buffer[512];