diff --git a/include/psyc.h b/include/psyc.h index 8752748..149b903 100644 --- a/include/psyc.h +++ b/include/psyc.h @@ -147,7 +147,7 @@ typedef struct typedef struct { psycHeader routing; ///< Routing header. - psycHeader entity; ///< Entitiy header. + psycHeader entity; ///< Entitiy header. psycString method; psycString data; size_t routingLength; ///< Length of routing part. @@ -158,26 +158,49 @@ typedef struct inline int psyc_version(); +/** Check if a modifier needs length */ +inline psycModifierFlag psyc_checkModifierLength(psycModifier *m); + +/** Get the total length of a modifier. */ +inline size_t psyc_getModifierLength(psycModifier *m); + +/** Create new modifier */ inline psycModifier psyc_newModifier(char oper, psycString *name, psycString *value, + psycModifierFlag flag); + +/** Create new modifier */ +inline psycModifier psyc_newModifier2(char oper, + const char *name, size_t namelen, + const char *value, size_t valuelen, psycModifierFlag flag); -inline psycModifier psyc_newModifier2(char oper, - const char *name, size_t namelen, - const char *value, size_t valuelen, - psycModifierFlag flag); +/** Check if a list needs length */ +inline psycListFlag psyc_checkListLength(psycList *list); +/** Get the total length of a list. */ +inline psycListFlag psyc_getListLength(psycList *list); + +/** Check if a packet needs length */ +inline psycPacketFlag psyc_checkPacketLength(psycPacket *p); + +/** Calculate and set the length of packet parts and total packet length */ +inline size_t psyc_setPacketLength(psycPacket *p); + +/** Create new list */ inline psycList psyc_newList(psycString *elems, size_t num_elems, psycListFlag flag); +/** Create new packet */ inline psycPacket psyc_newPacket(psycHeader *routing, - psycHeader *entity, - psycString *method, psycString *data, - psycPacketFlag flag); + psycHeader *entity, + psycString *method, psycString *data, + psycPacketFlag flag); +/** Create new packet */ inline psycPacket psyc_newPacket2(psycModifier *routing, size_t routinglen, - psycModifier *entity, size_t entitylen, - const char *method, size_t methodlen, - const char *data, size_t datalen, - psycPacketFlag flag); + psycModifier *entity, size_t entitylen, + const char *method, size_t methodlen, + const char *data, size_t datalen, + psycPacketFlag flag); /// Routing vars in alphabetical order. extern const psycString PSYC_routingVars[]; diff --git a/src/packet.c b/src/packet.c index 6bf4fb1..3676c2c 100644 --- a/src/packet.c +++ b/src/packet.c @@ -9,20 +9,39 @@ inline psycString psyc_newString(const char *str, size_t strlen) return s; } +inline psycModifierFlag psyc_checkModifierLength(psycModifier *m) +{ + psycModifierFlag flag; + + if (m->value.length > PSYC_MODIFIER_SIZE_THRESHOLD) + flag = PSYC_MODIFIER_NEED_LENGTH; + else if (memchr(m->value.ptr, (int)'\n', m->value.length)) + flag = PSYC_MODIFIER_NEED_LENGTH; + else + flag = PSYC_MODIFIER_NO_LENGTH; + + return flag; +} + +inline size_t psyc_getModifierLength(psycModifier *m) +{ + size_t length = 1 + // oper + m->name.length + 1 + // name\t + m->value.length + 1; // value\n + + if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed + length += log10((double)m->value.length) + 2; // SP length + + return length; +} + inline psycModifier psyc_newModifier(char oper, psycString *name, psycString *value, psycModifierFlag flag) { psycModifier m = {oper, *name, *value, flag}; if (flag == PSYC_MODIFIER_CHECK_LENGTH) // find out if it needs a length - { - if (value->length > PSYC_MODIFIER_SIZE_THRESHOLD) - m.flag = PSYC_MODIFIER_NEED_LENGTH; - else if (memchr(value->ptr, (int)'\n', value->length)) - m.flag = PSYC_MODIFIER_NEED_LENGTH; - else - m.flag = PSYC_MODIFIER_NO_LENGTH; - } + m.flag = psyc_checkModifierLength(&m); return m; } @@ -38,14 +57,45 @@ inline psycModifier psyc_newModifier2(char oper, return psyc_newModifier(oper, &n, &v, flag); } -inline size_t psyc_getModifierLength(psycModifier *m) +inline psycListFlag psyc_checkListLength(psycList *list) { - size_t length = 1 + // oper - m->name.length + 1 + // name\t - m->value.length + 1; // value\n + psycListFlag flag = PSYC_LIST_NO_LENGTH; + size_t i, length = 0; - if (m->flag == PSYC_MODIFIER_NEED_LENGTH) // add length of length if needed - length += log10((double)m->value.length) + 2; // SP length + for (i = 0; i < list->num_elems; i++) + { + psycString *elem = &list->elems[i]; + length += 1 + elem->length; // |elem + if (length > PSYC_MODIFIER_SIZE_THRESHOLD || + memchr(elem->ptr, (int)'|', elem->length) || + memchr(elem->ptr, (int)'\n', elem->length)) + { + flag = PSYC_LIST_NEED_LENGTH; + break; + } + } + + return flag; +} + +inline psycListFlag psyc_getListLength(psycList *list) +{ + size_t i, length = 0; + + if (list->flag == PSYC_LIST_NEED_LENGTH) + { + for (i = 0; i < list->num_elems; i++) + { + if (i > 0) + length++; // | + length += log10((double)list->elems[i].length) + 2 + list->elems[i].length; // length SP elem + } + } + else + { + for (i = 0; i < list->num_elems; i++) + length += 1 + list->elems[i].length; // |elem + } return length; } @@ -53,78 +103,67 @@ inline size_t psyc_getModifierLength(psycModifier *m) inline psycList psyc_newList(psycString *elems, size_t num_elems, psycListFlag flag) { psycList list = {num_elems, elems, 0, flag}; - size_t i; if (flag == PSYC_LIST_CHECK_LENGTH) // check if list elements need length - { - for (i = 0; i < num_elems; i++) - { - if (memchr(elems[i].ptr, (int)'|', elems[i].length) || - memchr(elems[i].ptr, (int)'\n', elems[i].length)) - { - list.flag = PSYC_LIST_NEED_LENGTH; - break; - } - } - } - - if (list.flag == PSYC_LIST_NEED_LENGTH) - { - for (i = 0; i < num_elems; i++) - { - if (i > 0) - list.length++; // | - list.length += log10((double)elems[i].length) + 2 + elems[i].length; // length SP elem - } - } - else - { - for (i = 0; i < num_elems; i++) - list.length += 1 + elems[i].length; // |elem - } + list.flag = psyc_checkListLength(&list); + list.length = psyc_getListLength(&list); return list; } +inline psycPacketFlag psyc_checkPacketLength(psycPacket *p) +{ + psycPacketFlag flag; + + if (p->data.length == 1 && p->data.ptr[0] == C_GLYPH_PACKET_DELIMITER) + flag = PSYC_PACKET_NEED_LENGTH; + else if (p->data.length > PSYC_CONTENT_SIZE_THRESHOLD) + flag = PSYC_PACKET_NEED_LENGTH; + else if (memmem(p->data.ptr, p->data.length, PSYC_C2ARG(PSYC_PACKET_DELIMITER))) + flag = PSYC_PACKET_NEED_LENGTH; + else + flag = PSYC_PACKET_NO_LENGTH; + + return flag; +} + +inline size_t psyc_setPacketLength(psycPacket *p) +{ + size_t i; + + // add routing header length + 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])); + + // 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 \n content |\n + p->length = p->routingLength + 1 + p->contentLength + sizeof(PSYC_PACKET_DELIMITER) - 2; + if (p->flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed + p->length += log10((double)p->data.length) + 1; + + return p->length; +} + inline psycPacket psyc_newPacket(psycHeader *routing, psycHeader *entity, psycString *method, psycString *data, psycPacketFlag flag) { psycPacket p = {*routing, *entity, *method, *data, 0, 0, flag}; - size_t i; if (flag == PSYC_PACKET_CHECK_LENGTH) // find out if it needs a length - { - if (data->length == 1 && data->ptr[0] == C_GLYPH_PACKET_DELIMITER) - p.flag = PSYC_PACKET_NEED_LENGTH; - else if (data->length > PSYC_CONTENT_SIZE_THRESHOLD) - p.flag = PSYC_PACKET_NEED_LENGTH; - else if (memmem(data->ptr, data->length, PSYC_C2ARG(PSYC_PACKET_DELIMITER))) - p.flag = PSYC_PACKET_NEED_LENGTH; - else - p.flag = PSYC_PACKET_NO_LENGTH; - } - - // add routing header length - for (i = 0; i < routing->lines; i++) - p.routingLength += psyc_getModifierLength(&routing->modifiers[i]); - - // add entity header length - for (i = 0; i < entity->lines; i++) - p.contentLength += psyc_getModifierLength(&entity->modifiers[i]); - - // add length of method, data & delimiter - if (method->length) - p.contentLength += method->length + 1; // method\n - if (data->length) - p.contentLength += data->length + 1; // data\n - - // set total length: routing-header \n content |\n - p.length = p.routingLength + 1 + p.contentLength + sizeof(PSYC_PACKET_DELIMITER) - 2; - if (flag == PSYC_PACKET_NEED_LENGTH) // add length of length if needed - p.length += log10((double)data->length) + 1; + p.flag = psyc_checkPacketLength(&p); + psyc_setPacketLength(&p); return p; } diff --git a/test/testParser.c b/test/testParser.c index e3b0a0d..0473e88 100644 --- a/test/testParser.c +++ b/test/testParser.c @@ -1,29 +1,30 @@ -#include -#include #include #include #include -int main(int argc, char** argv) +#include +#include + +int main(int argc, char **argv) { - int indx, ret, verbose = argc > 2; + int idx, ret, verbose = argc > 2; char buffer[2048], oper; psycString name, value, elem; psycParseState state; psycParseListState listState; int file = open(argv[1],O_RDONLY); - if(file < 0) + if (file < 0) return -1; - indx = read(file,(void*)buffer,sizeof(buffer)); + idx = read(file,(void*)buffer,sizeof(buffer)); if (verbose) { write(1, ">> INPUT\n", 9); - write(1, buffer, indx); + write(1, buffer, idx); write(1, ">> PARSE\n", 9); } psyc_initParseState(&state); - psyc_nextParseBuffer(&state, psyc_newString(buffer, indx)); + psyc_nextParseBuffer(&state, psyc_newString(buffer, idx)); // try parsing that now // while ((ret = psyc_parse(&state, &oper, &name, &value))) diff --git a/test/testRender.c b/test/testRender.c index 0bdddda..249ead2 100644 --- a/test/testRender.c +++ b/test/testRender.c @@ -23,10 +23,10 @@ int testPresence(const char *avail, int availlen, const char *desc, int desclen, }; psycPacket packet = psyc_newPacket2(routing, PSYC_NUM_ELEM(routing), - entity, PSYC_NUM_ELEM(entity), - PSYC_C2ARG("_notice_presence"), - NULL, 0, - PSYC_PACKET_CHECK_LENGTH); + entity, PSYC_NUM_ELEM(entity), + PSYC_C2ARG("_notice_presence"), + NULL, 0, + PSYC_PACKET_CHECK_LENGTH); char buffer[512]; psyc_render(&packet, buffer, sizeof(buffer)); @@ -68,7 +68,7 @@ int testList(const char *rendered, uint8_t verbose) psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_list_text"), buf_text, list_text.length, list_text.flag), psyc_newModifier2(C_GLYPH_OPERATOR_SET, PSYC_C2ARG("_list_binary"), - buf_bin, list_bin.length, list_text.flag), + buf_bin, list_bin.length, list_bin.flag), }; psycPacket packet = psyc_newPacket2(routing, PSYC_NUM_ELEM(routing), @@ -84,7 +84,7 @@ int testList(const char *rendered, uint8_t verbose) return strncmp(rendered, buffer, packet.length); } -int main(int argc, char* argv[]) { +int main(int argc, char **argv) { uint8_t verbose = argc > 1; if (testPresence(PSYC_C2ARG("_here"), PSYC_C2ARG("I'm omnipresent right now"), "\