From 6804cdb6fb3bf877ff785c27dc4306df993ce830 Mon Sep 17 00:00:00 2001 From: Marenz Date: Thu, 2 Jun 2011 21:59:00 +0200 Subject: [PATCH] added rudimentary binding for render.h --- d/include/psyc/packet.d | 182 ++++++++++++++++++++++++++++++++++++++++ d/include/psyc/render.d | 57 +++++++++++++ d/include/psyc/syntax.d | 36 ++++++++ 3 files changed, 275 insertions(+) create mode 100644 d/include/psyc/packet.d create mode 100644 d/include/psyc/render.d create mode 100644 d/include/psyc/syntax.d diff --git a/d/include/psyc/packet.d b/d/include/psyc/packet.d new file mode 100644 index 0000000..b9584cb --- /dev/null +++ b/d/include/psyc/packet.d @@ -0,0 +1,182 @@ + /* + * Packet data structures and functions for creating them are defined here. + */ + +module psyc.packet; + +import psyc.common; +import psyc.syntax; + + +/** Modifier flags. */ +enum ModifierFlag +{ + /// Modifier needs to be checked if it needs length. + CHECK_LENGTH = 0, + /// Modifier needs length. + NEED_LENGTH = 1, + /// Modifier doesn't need length. + NO_LENGTH = 2, + /// Routing modifier, which implies that it doesn't need length. + ROUTING = 3, +}; + +/** List flags. */ +enum ListFlag +{ + /// List needs to be checked if it needs length. + CHECK_LENGTH = 0, + /// List needs length. + NEED_LENGTH = 1, + /// List doesn't need length. + NO_LENGTH = 2, +} ; + +/** Packet flags. */ +enum PacketFlag +{ + /// Packet needs to be checked if it needs content length. + CHECK_LENGTH = 0, + /// Packet needs content length. + NEED_LENGTH = 1, + /// Packet doesn't need content length. + NO_LENGTH = 2, +} ; + +/** Structure for a modifier. */ +struct Modifier +{ + char oper; + String name; + String value; + ModifierFlag flag; +} ; + +/** Structure for an entity or routing header. */ +struct Header +{ + size_t lines; + Modifier *modifiers; +} ; + +/** Structure for a list. */ +struct List +{ + size_t num_elems; + String *elems; + size_t length; + ListFlag flag; +} ; + +/** intermediate struct for a PSYC packet */ +struct Packet +{ + Header routing; ///< Routing header. + Header entity; ///< Entity header. + String method; ///< Contains the method. + String data; ///< Contains the data. + String 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. + PacketFlag flag; ///< Packet flag. +} ; + +/** + * \internal + * Check if a modifier needs length. + */ + +ModifierFlag psyc_checkModifierLength (Modifier *m) +{ + ModifierFlag flag; + + if (m->value.length > PSYC_MODIFIER_SIZE_THRESHOLD) + flag = ModifierFlag.NEED_LENGTH; + else if (memchr(m->value.ptr, (int)'\n', m->value.length)) + flag = ModifierFlag.NEED_LENGTH; + else + flag = ModifierFlag.NO_LENGTH; + + return flag; +} + +/** Create new modifier. */ + +Modifier psyc_newModifier (char oper, String *name, String *value, + ModifierFlag flag) +{ + Modifier m = {oper, *name, *value, flag}; + + if (flag == ModifierFlag.CHECK_LENGTH) // find out if it needs a length + m.flag = psyc_checkModifierLength(&m); + + return m; +} + +/** Create new modifier */ +Modifier psyc_newModifier2 (char oper, + char *name, size_t namelen, + char *value, size_t valuelen, + ModifierFlag flag) +{ + String n = {namelen, name}; + String v = {valuelen, value}; + + return psyc_newModifier(oper, &n, &v, flag); +} + +/** + * \internal + * Get the total length of a modifier when rendered. + */ +size_t psyc_getModifierLength (Modifier *m); + +/** + * \internal + * Check if a list needs length. + */ +ListFlag psyc_checkListLength (List *list); + +/** + * \internal + * Get the total length of a list when rendered. + */ +ListFlag psyc_getListLength (List *list); + +/** + * \internal + * Check if a packet needs length. + */ +PacketFlag psyc_checkPacketLength (Packet *p); + +/** + * Calculate and set the rendered length of packet parts and total packet length. + */ +size_t psyc_setPacketLength (Packet *p); + +/** Create new list. */ +List psyc_newList (String *elems, size_t num_elems, ListFlag flag); + +/** Create new packet. */ +Packet psyc_newPacket (Header *routing, + Header *entity, + String *method, String *data, + PacketFlag flag); + +/** Create new packet. */ +Packet psyc_newPacket2 (Modifier *routing, size_t routinglen, + Modifier *entity, size_t entitylen, + char *method, size_t methodlen, + char *data, size_t datalen, + PacketFlag flag); + +/** Create new packet with raw content. */ +Packet psyc_newRawPacket (Header *routing, String *content, + PacketFlag flag); + +/** Create new packet with raw content. */ +Packet psyc_newRawPacket2 (Modifier *routing, size_t routinglen, + char *content, size_t contentlen, + PacketFlag flag); + diff --git a/d/include/psyc/render.d b/d/include/psyc/render.d new file mode 100644 index 0000000..f12bbbe --- /dev/null +++ b/d/include/psyc/render.d @@ -0,0 +1,57 @@ +module psyc.render; + +import psyc.packet; + + /* + * All rendering functions and the definitions they use are defined here. + */ + +/** + * Return codes for psyc_render. + */ +enum RenderRC +{ + /// Error, method is missing, but data is present. + ERROR_METHOD_MISSING = -3, + /// Error, a modifier name is missing. + ERROR_MODIFIER_NAME_MISSING = -2, + /// Error, buffer is too small to render the packet. + ERROR = -1, + /// Packet is rendered successfully in the buffer. + SUCCESS = 0, +} ; + +/** + * Return codes for psyc_renderList. + */ +enum RenderListRC +{ + /// Error, buffer is too small to render the list. + ERROR = -1, + /// List is rendered successfully in the buffer. + SUCCESS = 0, +}; + +/** + * Render a PSYC packet into a buffer. + * + * The packet structure should contain the packet parts, either routing, entity, + * method & data, or routing & content when rendering raw content. + * It should also contain the contentLength & total length of the packet, + * you can use psyc_setPacketLength() for calculating & setting these values. + * This function renders packet->length bytes to the buffer, + * if buflen is less than that an error is returned. + * + * @see psyc_newPacket + * @see psyc_newPacket2 + * @see psyc_newRawPacket + * @see psyc_newRawPacket2 + * @see psyc_setPacketLength + */ +RenderRC psyc_render (Packet *packet, char *buffer, size_t buflen); + +/** + * Render a PSYC list into a buffer. + */ +RenderListRC psyc_renderList (List *list, char *buffer, size_t buflen); + diff --git a/d/include/psyc/syntax.d b/d/include/psyc/syntax.d new file mode 100644 index 0000000..a5fcfe3 --- /dev/null +++ b/d/include/psyc/syntax.d @@ -0,0 +1,36 @@ +module psyc.syntax; + +const PSYC_LIST_SIZE_LIMIT = 404; + +/* beyond this a content length must be provided */ +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 = "?"; + +/* might move into routing.h or something */ +const PSYC_ROUTING = 1; +const PSYC_ROUTING_MERGE = 2; +const PSYC_ROUTING_RENDER = 4;