2011-04-20 20:22:55 +00:00
|
|
|
#include "psyc/lib.h"
|
|
|
|
#include "psyc/render.h"
|
2011-04-25 21:14:22 +00:00
|
|
|
#include "psyc/syntax.h"
|
2011-04-20 20:22:55 +00:00
|
|
|
|
2011-05-03 23:00:35 +00:00
|
|
|
psycRenderRC psyc_renderList (psycList *list, char *buffer, size_t buflen)
|
2011-04-26 15:23:06 +00:00
|
|
|
{
|
|
|
|
size_t i, cur = 0;
|
|
|
|
psycString *elem;
|
|
|
|
|
|
|
|
if (list->length > buflen)
|
|
|
|
return PSYC_RENDER_ERROR; // return error if list doesn't fit in buffer
|
|
|
|
|
|
|
|
if (list->flag == PSYC_LIST_NEED_LENGTH)
|
|
|
|
{
|
|
|
|
for (i = 0; i < list->num_elems; i++)
|
|
|
|
{
|
|
|
|
elem = &list->elems[i];
|
|
|
|
if (i > 0)
|
|
|
|
buffer[cur++] = '|';
|
|
|
|
cur += itoa(elem->length, buffer + cur, 10);
|
|
|
|
buffer[cur++] = ' ';
|
|
|
|
memcpy(buffer + cur, elem->ptr, elem->length);
|
|
|
|
cur += elem->length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for (i = 0; i < list->num_elems; i++)
|
|
|
|
{
|
|
|
|
elem = &list->elems[i];
|
|
|
|
buffer[cur++] = '|';
|
|
|
|
memcpy(buffer + cur, elem->ptr, elem->length);
|
|
|
|
cur += elem->length;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return PSYC_RENDER_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2011-05-03 23:00:35 +00:00
|
|
|
static inline
|
|
|
|
size_t psyc_renderModifier (psycModifier *mod, char *buffer)
|
2011-04-25 12:20:13 +00:00
|
|
|
{
|
2011-04-25 19:57:03 +00:00
|
|
|
size_t cur = 0;
|
2011-04-25 12:20:13 +00:00
|
|
|
|
2011-04-26 15:23:06 +00:00
|
|
|
buffer[cur++] = mod->oper;
|
|
|
|
memcpy(buffer + cur, mod->name.ptr, mod->name.length);
|
|
|
|
cur += mod->name.length;
|
2011-05-04 13:41:35 +00:00
|
|
|
if (cur <= 1)
|
|
|
|
return cur; // error, name can't be empty
|
|
|
|
|
2011-04-26 15:23:06 +00:00
|
|
|
if (mod->flag == PSYC_MODIFIER_NEED_LENGTH)
|
2011-04-25 12:20:13 +00:00
|
|
|
{
|
2011-04-25 12:47:16 +00:00
|
|
|
buffer[cur++] = ' ';
|
2011-04-26 15:23:06 +00:00
|
|
|
cur += itoa(mod->value.length, buffer + cur, 10);
|
2011-04-25 12:20:13 +00:00
|
|
|
}
|
2011-04-25 19:57:03 +00:00
|
|
|
|
|
|
|
buffer[cur++] = '\t';
|
2011-04-26 15:23:06 +00:00
|
|
|
memcpy(buffer + cur, mod->value.ptr, mod->value.length);
|
|
|
|
cur += mod->value.length;
|
2011-04-25 12:47:16 +00:00
|
|
|
buffer[cur++] = '\n';
|
2011-04-25 12:20:13 +00:00
|
|
|
|
|
|
|
return cur;
|
|
|
|
}
|
|
|
|
|
2011-05-03 23:00:35 +00:00
|
|
|
psycRenderRC psyc_render (psycPacket *packet, char *buffer, size_t buflen)
|
2011-04-25 12:20:13 +00:00
|
|
|
{
|
2011-05-04 13:41:35 +00:00
|
|
|
size_t i, cur = 0, len;
|
2011-04-25 12:20:13 +00:00
|
|
|
|
|
|
|
if (packet->length > buflen)
|
2011-04-25 21:14:22 +00:00
|
|
|
return PSYC_RENDER_ERROR; // return error if packet doesn't fit in buffer
|
2011-04-25 12:20:13 +00:00
|
|
|
|
2011-04-25 21:14:22 +00:00
|
|
|
// render routing modifiers
|
2011-04-25 12:39:58 +00:00
|
|
|
for (i = 0; i < packet->routing.lines; i++)
|
2011-05-04 13:41:35 +00:00
|
|
|
{
|
|
|
|
len = psyc_renderModifier(&packet->routing.modifiers[i], buffer + cur);
|
|
|
|
cur += len;
|
|
|
|
if (len <= 1)
|
|
|
|
return PSYC_RENDER_ERROR_MODIFIER_NAME_MISSING;
|
|
|
|
}
|
2011-04-25 12:20:13 +00:00
|
|
|
|
2011-04-25 21:14:22 +00:00
|
|
|
// add length if needed
|
2011-04-30 16:34:43 +00:00
|
|
|
if (packet->flag == PSYC_PACKET_NEED_LENGTH)
|
2011-04-25 14:11:47 +00:00
|
|
|
cur += itoa(packet->contentLength, buffer + cur, 10);
|
2011-04-25 12:20:13 +00:00
|
|
|
|
2011-05-05 22:13:37 +00:00
|
|
|
if (packet->flag == PSYC_PACKET_NEED_LENGTH || packet->content.length ||
|
2011-05-04 15:46:20 +00:00
|
|
|
packet->entity.lines || packet->method.length || packet->data.length)
|
|
|
|
buffer[cur++] = '\n'; // start of content part if there's content or length
|
2011-04-25 12:20:13 +00:00
|
|
|
|
2011-05-05 22:13:37 +00:00
|
|
|
if (packet->content.length) // render raw content if present
|
2011-04-25 19:57:03 +00:00
|
|
|
{
|
2011-05-05 22:13:37 +00:00
|
|
|
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);
|
2011-05-04 15:46:20 +00:00
|
|
|
|
2011-05-05 22:13:37 +00:00
|
|
|
if (packet->method.length) // add method\n
|
2011-05-04 13:41:35 +00:00
|
|
|
{
|
2011-05-05 22:13:37 +00:00
|
|
|
memcpy(buffer + cur, packet->method.ptr, packet->method.length);
|
|
|
|
cur += packet->method.length;
|
2011-05-04 13:41:35 +00:00
|
|
|
buffer[cur++] = '\n';
|
2011-05-05 22:13:37 +00:00
|
|
|
|
|
|
|
if (packet->data.length) // add data\n
|
|
|
|
{
|
|
|
|
memcpy(buffer + cur, packet->data.ptr, packet->data.length);
|
|
|
|
cur += packet->data.length;
|
|
|
|
buffer[cur++] = '\n';
|
|
|
|
}
|
2011-05-04 13:41:35 +00:00
|
|
|
}
|
2011-05-05 22:13:37 +00:00
|
|
|
else if (packet->data.length) // error, we have data but no modifier
|
|
|
|
return PSYC_RENDER_ERROR_METHOD_MISSING;
|
2011-04-25 19:57:03 +00:00
|
|
|
}
|
2011-04-25 12:20:13 +00:00
|
|
|
|
2011-04-25 21:14:22 +00:00
|
|
|
// add packet delimiter
|
2011-04-25 20:57:08 +00:00
|
|
|
buffer[cur++] = C_GLYPH_PACKET_DELIMITER;
|
|
|
|
buffer[cur++] = '\n';
|
2011-04-25 20:31:21 +00:00
|
|
|
|
2011-04-25 21:14:22 +00:00
|
|
|
// actual length should be equal to pre-calculated length at this point
|
2011-04-25 20:31:21 +00:00
|
|
|
assert(cur == packet->length);
|
2011-04-25 12:20:13 +00:00
|
|
|
return PSYC_RENDER_SUCCESS;
|
|
|
|
}
|