1
0
Fork 0
mirror of git://git.psyc.eu/libpsyc synced 2024-08-15 03:19:02 +00:00

Merge commit 'origin'

This commit is contained in:
psyc://psyced.org/~lynX 2011-06-11 09:00:56 +02:00
commit 96da1b7e6a
18 changed files with 401 additions and 119 deletions

View file

@ -338,7 +338,7 @@ EXTRACT_PRIVATE = NO
# If the EXTRACT_STATIC tag is set to YES all static members of a file # If the EXTRACT_STATIC tag is set to YES all static members of a file
# will be included in the documentation. # will be included in the documentation.
EXTRACT_STATIC = NO EXTRACT_STATIC = YES
# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
# defined locally in source files will be included in the documentation. # defined locally in source files will be included in the documentation.

View file

@ -138,8 +138,7 @@ Parsing time of 1 000 000 packets, in milliseconds.
A simple strlen() scan of the respective message is provided for comparison. A simple strlen() scan of the respective message is provided for comparison.
These tests were performed on a 2.53 GHz Intel(R) Core(TM)2 Duo P9500 CPU. These tests were performed on a 2.53 GHz Intel(R) Core(TM)2 Duo P9500 CPU.
| input: | PSYC | | JSON | | | XML | | | | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml |
| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml |
|-----------------+--------+---------+--------+-----------+------------+--------+----------| |-----------------+--------+---------+--------+-----------+------------+--------+----------|
| user profile | 55 | 608 | 4715 | 16503 | 7350 | 12377 | 2477 | | user profile | 55 | 608 | 4715 | 16503 | 7350 | 12377 | 2477 |
| psyc-unfriendly | 70 | 286 | 2892 | 12567 | 5538 | 8659 | 1896 | | psyc-unfriendly | 70 | 286 | 2892 | 12567 | 5538 | 8659 | 1896 |
@ -151,21 +150,20 @@ These tests were performed on a 2.53 GHz Intel(R) Core(TM)2 Duo P9500 CPU.
Pure syntax comparisons above, protocol performance comparisons below: Pure syntax comparisons above, protocol performance comparisons below:
| input: | | PSYC | | JSON | | | XMPP | | | | strlen | libpsyc | libpsyc compact | json-c | json-glib | libxml sax | libxml | rapidxml |
| parser: | strlen | libpsyc | compact | json-c | json-glib | libxml sax | libxml | rapidxml | |----------+--------+---------+-----------------+--------+-----------+------------+--------+----------|
|----------+--------+---------+---------+--------+-----------+------------+--------+----------| | presence | 30 | 236 | 122 | 2463 | 10016 | 4997 | 7557 | 1719 |
| presence | 30 | 236 | 122 | 2463 | 10016 | 4997 | 7557 | 1719 | | chat msg | 40 | 295 | 258 | 2147 | 9526 | 5911 | 8999 | 1850 |
| chat msg | 40 | 295 | 258 | 2147 | 9526 | 5911 | 8999 | 1850 | | activity | 42 | 353 | 279 | 4666 | 16327 | 13357 | 28858 | 4356 |
| activity | 42 | 353 | 279 | 4666 | 16327 | 13357 | 28858 | 4356 | |----------+--------+---------+-----------------+--------+-----------+------------+--------+----------|
|----------+--------+---------+---------+--------+-----------+------------+--------+----------| | / | < | | > | < | > | < | | > |
| / | < | | > | < | > | < | | > | | | | | <c> | | | | | |
Parsing large amounts of binary data. For JSON & XML base64 encoding was used. Parsing large amounts of binary data. For JSON & XML base64 encoding was used.
Note that the results below include only the parsing time, base64 decoding was Note that the results below include only the parsing time, base64 decoding was
not performed. not performed.
| input: | PSYC | | JSON | | | XML | | | | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml |
| parser: | strlen | libpsyc | json-c | json-glib | libxml sax | libxml | rapidxml |
|---------+----------+---------+-----------+------------+------------+-----------+----------| |---------+----------+---------+-----------+------------+------------+-----------+----------|
| 7K | 978 | 77 | 18609 | 98000 | 11445 | 19299 | 8701 | | 7K | 978 | 77 | 18609 | 98000 | 11445 | 19299 | 8701 |
| 70K | 9613 | 77 | 187540 | 1003900 | 96209 | 167738 | 74296 | | 70K | 9613 | 77 | 187540 | 1003900 | 96209 | 167738 | 74296 |

182
d/include/psyc/packet.d Normal file
View file

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

View file

@ -159,25 +159,6 @@ struct ParseState
return psyc_parse(this, &oper, cast(String*) &name, cast(String*) &value); return psyc_parse(this, &oper, cast(String*) &name, cast(String*) &value);
} }
/**
* Change parse flags in state
*
* Params:
* state = Pointer to the state struct that should be initialized.
* flags = Flags to be set for the parser, see psycParseFlag.
*
* See_Also: psyc_initParseState psycParseFlag
*/
void setParseFlags (ParseFlag flags)
{
this.flags = flags;
if (flags & ParseFlag.START_AT_CONTENT)
this.part = Part.CONTENT;
else
this.part = Part.ROUTING;
}
/** /**
* Sets a new buffer in the parser state struct with data to be parsed. * Sets a new buffer in the parser state struct with data to be parsed.
* *
@ -265,6 +246,7 @@ struct ParseState
void getRemainingBuffer ( ref ubyte[] buf ) void getRemainingBuffer ( ref ubyte[] buf )
{ {
buf = this.buffer.ptr[cursor .. cursor + getRemainingLength()]; buf = this.buffer.ptr[cursor .. cursor + getRemainingLength()];
} }

57
d/include/psyc/render.d Normal file
View file

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

36
d/include/psyc/syntax.d Normal file
View file

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

View file

@ -92,7 +92,10 @@ typedef struct
psycPacketFlag flag; ///< Packet flag. psycPacketFlag flag; ///< Packet flag.
} psycPacket; } psycPacket;
/** Check if a modifier needs length. */ /**
* \internal
* Check if a modifier needs length.
*/
static inline static inline
psycModifierFlag psyc_checkModifierLength (psycModifier *m) psycModifierFlag psyc_checkModifierLength (psycModifier *m)
{ {
@ -134,19 +137,33 @@ psycModifier psyc_newModifier2 (char oper,
return psyc_newModifier(oper, &n, &v, flag); return psyc_newModifier(oper, &n, &v, flag);
} }
/** Get the total length of a modifier when rendered. */ /**
* \internal
* Get the total length of a modifier when rendered.
*/
size_t psyc_getModifierLength (psycModifier *m); size_t psyc_getModifierLength (psycModifier *m);
/** Check if a list needs length. */ /**
* \internal
* Check if a list needs length.
*/
psycListFlag psyc_checkListLength (psycList *list); psycListFlag psyc_checkListLength (psycList *list);
/** Get the total length of a list when rendered. */ /**
* \internal
* Get the total length of a list when rendered.
*/
psycListFlag psyc_getListLength (psycList *list); psycListFlag psyc_getListLength (psycList *list);
/** Check if a packet needs length. */ /**
* \internal
* Check if a packet needs length.
*/
psycPacketFlag psyc_checkPacketLength (psycPacket *p); psycPacketFlag psyc_checkPacketLength (psycPacket *p);
/** Calculate and set the rendered length of packet parts and total packet length. */ /**
* Calculate and set the rendered length of packet parts and total packet length.
*/
size_t psyc_setPacketLength (psycPacket *p); size_t psyc_setPacketLength (psycPacket *p);
/** Create new list. */ /** Create new list. */

View file

@ -40,9 +40,7 @@
* char* raw_data; // points to our (possibly incomplete) packet * char* raw_data; // points to our (possibly incomplete) packet
* size_t raw_len; // how many bytes of data * size_t raw_len; // how many bytes of data
* *
* psyc_setParseBuffer(&state, // our initialized state from before * psyc_setParseBuffer(&state, raw_data, raw_len); // state is our initialized state from before
* raw_data,
* raw_len);
* @endcode * @endcode
* *
* Now the the variables that will save the output of the parser need to be * Now the the variables that will save the output of the parser need to be
@ -179,10 +177,10 @@ typedef enum
/// Start of an incomplete content, value contains part of content. /// Start of an incomplete content, value contains part of content.
/// Used when PSYC_PARSE_ROUTING_ONLY is set. /// Used when PSYC_PARSE_ROUTING_ONLY is set.
PSYC_PARSE_CONTENT_START = 7, PSYC_PARSE_CONTENT_START = 7,
/// Continuation of an incomplete body. /// Continuation of an incomplete content.
/// Used when PSYC_PARSE_ROUTING_ONLY is set. /// Used when PSYC_PARSE_ROUTING_ONLY is set.
PSYC_PARSE_CONTENT_CONT = 8, PSYC_PARSE_CONTENT_CONT = 8,
/// End of an incomplete body. /// End of an incomplete content.
/// Used when PSYC_PARSE_ROUTING_ONLY is set. /// Used when PSYC_PARSE_ROUTING_ONLY is set.
PSYC_PARSE_CONTENT_END = 9, PSYC_PARSE_CONTENT_END = 9,
/// Content parsing done in one go, value contains the whole content. /// Content parsing done in one go, value contains the whole content.
@ -274,27 +272,6 @@ void psyc_initParseState2 (psycParseState *state, uint8_t flags)
state->part = PSYC_PART_CONTENT; state->part = PSYC_PART_CONTENT;
} }
/**
* Change parse flags in state
*
* @param state Pointer to the state struct that should be initialized.
* @param flags Flags to be set for the parser, see psycParseFlag.
* @see psyc_initParseState
* @see psycParseFlag
*/
static inline
void psyc_setParseFlags (psycParseState *state, uint8_t flags)
{
state->flags = flags;
if (flags & PSYC_PARSE_START_AT_CONTENT)
state->part = PSYC_PART_CONTENT;
else
state->part = 0;
}
/** /**
* Sets a new buffer in the parser state struct with data to be parsed. * Sets a new buffer in the parser state struct with data to be parsed.
* *
@ -330,7 +307,7 @@ void psyc_setParseBuffer (psycParseState *state, psycString buffer)
* @see psycString * @see psycString
*/ */
static inline static inline
void psyc_setParseBuffer2 (psycParseState *state, char *buffer, size_t length) void psyc_setParseBuffer2 (psycParseState *state, const char *buffer, size_t length)
{ {
psycString buf = {length, buffer}; psycString buf = {length, buffer};
psyc_setParseBuffer(state, buf); psyc_setParseBuffer(state, buf);
@ -358,7 +335,7 @@ void psyc_setParseListBuffer (psycParseListState *state, psycString buffer)
} }
static inline static inline
void psyc_setParseListBuffer2 (psycParseListState *state, char *buffer, size_t length) void psyc_setParseListBuffer2 (psycParseListState *state, const char *buffer, size_t length)
{ {
psycString buf = {length, buffer}; psycString buf = {length, buffer};
psyc_setParseListBuffer(state, buf); psyc_setParseListBuffer(state, buf);

View file

@ -26,7 +26,7 @@ typedef enum
/// Text template parsing & rendering complete. /// Text template parsing & rendering complete.
PSYC_TEXT_COMPLETE = 0, PSYC_TEXT_COMPLETE = 0,
/// Text template parsing & rendering is incomplete, because the buffer was too small. /// Text template parsing & rendering is incomplete, because the buffer was too small.
/// Another call is required to this function with a new buffer. /// Another call is required to this function after setting a new buffer.
PSYC_TEXT_INCOMPLETE = 1, PSYC_TEXT_INCOMPLETE = 1,
} psycTextRC; } psycTextRC;
@ -48,8 +48,8 @@ typedef struct
{ {
size_t cursor; ///< current position in the template size_t cursor; ///< current position in the template
size_t written; ///< number of bytes written to buffer size_t written; ///< number of bytes written to buffer
psycString template; ///< template to parse psycString tmpl; ///< input buffer with text template to parse
psycString buffer; ///< buffer for writing to psycString buffer; ///< output buffer for rendered text
psycString open; psycString open;
psycString close; psycString close;
} psycTextState; } psycTextState;
@ -70,32 +70,32 @@ typedef psycTextValueRC (*psycTextCB)(const char *name, size_t len, psycString *
* Initializes the PSYC text state struct. * Initializes the PSYC text state struct.
* *
* @param state Pointer to the PSYC text state struct that should be initialized. * @param state Pointer to the PSYC text state struct that should be initialized.
* @param template Text template to be parsed. * @param tmpl Input buffer with text template to be parsed.
* @param tlen Length of template. * @param tmplen Length of input buffer.
* @param buffer Buffer where the rendered text is going to be written. * @param buffer Output buffer where the rendered text is going to be written.
* @param blen Length of buffer. * @param buflen Length of output buffer.
*/ */
static inline static inline
void psyc_initTextState (psycTextState *state, void psyc_initTextState (psycTextState *state,
char *template, size_t tlen, const char *tmpl, size_t tmplen,
char *buffer, size_t blen) char *buffer, size_t buflen)
{ {
state->cursor = 0; state->cursor = 0;
state->written = 0; state->written = 0;
state->template = (psycString) {tlen, template}; state->tmpl = (psycString) {tmplen, tmpl};
state->buffer = (psycString) {blen, buffer}; state->buffer = (psycString) {buflen, buffer};
state->open = (psycString) {1, "["}; state->open = (psycString) {1, "["};
state->close = (psycString) {1, "]"}; state->close = (psycString) {1, "]"};
} }
/** /**
* Initializes the PSYC text state struct with custom open & closing braces. * Initializes the PSYC text state struct with custom opening & closing braces.
* *
* @param state Pointer to the PSYC text state struct that should be initialized. * @param state Pointer to the PSYC text state struct that should be initialized.
* @param template Text template to be parsed. * @param tmpl Input buffer with text template to be parsed.
* @param tlen Length of template. * @param tmplen Length of input buffer.
* @param buffer Buffer where the rendered text is going to be written. * @param buffer Output buffer where the rendered text is going to be written.
* @param blen Length of buffer. * @param buflen Length of output buffer.
* @param open Opening brace. * @param open Opening brace.
* @param openlen Length of opening brace. * @param openlen Length of opening brace.
* @param close Closing brace. * @param close Closing brace.
@ -103,19 +103,21 @@ void psyc_initTextState (psycTextState *state,
*/ */
static inline static inline
void psyc_initTextState2 (psycTextState *state, void psyc_initTextState2 (psycTextState *state,
char *template, size_t tlen, const char *tmpl, size_t tmplen,
char *buffer, size_t blen, char *buffer, size_t buflen,
char *open, size_t openlen, const char *open, size_t openlen,
char *close, size_t closelen) const char *close, size_t closelen)
{ {
state->template = (psycString) {tlen, template}; state->cursor = 0;
state->buffer = (psycString) {blen, buffer}; state->written = 0;
state->open = (psycString) {openlen, open}; state->tmpl = (psycString) {tmplen, tmpl};
state->close = (psycString) {closelen, close}; state->buffer = (psycString) {buflen, buffer};
state->open = (psycString) {openlen, open};
state->close = (psycString) {closelen, close};
} }
/** /**
* Sets a new buffer in the PSYC text state struct. * Sets a new output buffer in the PSYC text state struct.
*/ */
static inline static inline
void psyc_setTextBuffer (psycTextState *state, psycString buffer) void psyc_setTextBuffer (psycTextState *state, psycString buffer)
@ -149,10 +151,10 @@ size_t psyc_getTextBytesWritten (psycTextState *state)
* string between these braces. Should the callback return * string between these braces. Should the callback return
* PSYC_TEXT_VALUE_NOT_FOUND, the original template text is copied as is. * PSYC_TEXT_VALUE_NOT_FOUND, the original template text is copied as is.
* *
* Before calling this function psyc_initTextState or psyc_initTextState should * Before calling this function psyc_initTextState should be called to initialize
* be called to initialze the state struct. By default PSYC's "[" and "]" are * the state struct. By default PSYC's "[" and "]" are used but you can provide
* used but you can provide any other brace strings such as "${" and "}" or * any other brace strings such as "${" and "}" or "<!--" and "-->" if you use
* "<!--" and "-->". * the psyc_initTextState2 variant.
* *
* @see http://about.psyc.eu/psyctext * @see http://about.psyc.eu/psyctext
**/ **/

View file

@ -1,12 +1,15 @@
OPT = -O2 OPT = -O2
DEBUG = 2 DEBUG = 2
CFLAGS = -I../include -Wall -std=c99 ${OPT} CFLAGS = -I../include -Wall -std=c99 -fPIC ${OPT}
DIET = diet DIET = diet
S = packet.c parse.c match.c render.c memmem.c itoa.c variable.c text.c S = packet.c parse.c match.c render.c memmem.c itoa.c variable.c text.c
O = packet.o parse.o match.o render.o memmem.o itoa.o variable.o text.o O = packet.o parse.o match.o render.o memmem.o itoa.o variable.o text.o
P = match itoa P = match itoa
A = ../lib/libpsyc.a
SO = ../lib/libpsyc.so
all: CC := ${WRAPPER} ${CC} all: CC := ${WRAPPER} ${CC}
all: lib all: lib
@ -18,9 +21,15 @@ diet: WRAPPER = ${DIET}
diet: CC := ${WRAPPER} ${CC} diet: CC := ${WRAPPER} ${CC}
diet: lib diet: lib
lib: $O lib: $O $A ${SO}
${SO}:
@mkdir -p ../lib @mkdir -p ../lib
${WRAPPER} ${AR} rcs ../lib/libpsyc.a $O ${CC} ${CFLAGS} -shared -lm -o $@ $O
$A:
@mkdir -p ../lib
${WRAPPER} ${AR} rcs $@ $O
match: match.c match: match.c
${CC} -o $@ -DDEBUG=4 -DCMDTOOL -DTEST $< ${CC} -o $@ -DDEBUG=4 -DCMDTOOL -DTEST $<

View file

@ -3,29 +3,29 @@
psycTextRC psyc_text (psycTextState *state, psycTextCB getValue) psycTextRC psyc_text (psycTextState *state, psycTextCB getValue)
{ {
const char *start = state->template.ptr, *end; // start & end of variable name const char *start = state->tmpl.ptr, *end; // start & end of variable name
const char *prev = state->template.ptr + state->cursor; const char *prev = state->tmpl.ptr + state->cursor;
psycString value; psycString value;
int ret; int ret;
size_t len; size_t len;
uint8_t no_subst = (state->cursor == 0); // whether we can return NO_SUBST uint8_t no_subst = (state->cursor == 0); // whether we can return NO_SUBST
while (state->cursor < state->template.length) while (state->cursor < state->tmpl.length)
{ {
start = memmem(state->template.ptr + state->cursor, start = memmem(state->tmpl.ptr + state->cursor,
state->template.length - state->cursor, state->tmpl.length - state->cursor,
state->open.ptr, state->open.length); state->open.ptr, state->open.length);
if (!start) if (!start)
break; break;
state->cursor = (start - state->template.ptr) + state->open.length; state->cursor = (start - state->tmpl.ptr) + state->open.length;
if (state->cursor >= state->template.length) if (state->cursor >= state->tmpl.length)
break; // [ at the end break; // [ at the end
end = memmem(state->template.ptr + state->cursor, end = memmem(state->tmpl.ptr + state->cursor,
state->template.length - state->cursor, state->tmpl.length - state->cursor,
state->close.ptr, state->close.length); state->close.ptr, state->close.length);
state->cursor = (end - state->template.ptr) + state->close.length; state->cursor = (end - state->tmpl.ptr) + state->close.length;
if (!end) if (!end)
break; // ] not found break; // ] not found
@ -40,12 +40,12 @@ psycTextRC psyc_text (psycTextState *state, psycTextCB getValue)
if (ret < 0) if (ret < 0)
continue; // value not found, no substitution continue; // value not found, no substitution
// first copy the part in the template from the previous subst. to the current one // first copy the part in the input from the previous subst. to the current one
// if there's enough buffer space for that // if there's enough buffer space for that
len = start - prev; len = start - prev;
if (state->written + len > state->buffer.length) if (state->written + len > state->buffer.length)
{ {
state->cursor = prev - state->template.ptr; state->cursor = prev - state->tmpl.ptr;
return PSYC_TEXT_INCOMPLETE; return PSYC_TEXT_INCOMPLETE;
} }
@ -55,7 +55,7 @@ psycTextRC psyc_text (psycTextState *state, psycTextCB getValue)
// now substitute the value if there's enough buffer space // now substitute the value if there's enough buffer space
if (state->written + value.length > state->buffer.length) if (state->written + value.length > state->buffer.length)
{ {
state->cursor = start - state->template.ptr; state->cursor = start - state->tmpl.ptr;
return PSYC_TEXT_INCOMPLETE; return PSYC_TEXT_INCOMPLETE;
} }
@ -63,7 +63,7 @@ psycTextRC psyc_text (psycTextState *state, psycTextCB getValue)
state->written += value.length; state->written += value.length;
// mark the start of the next chunk of text in the template // mark the start of the next chunk of text in the template
prev = state->template.ptr + state->cursor; prev = state->tmpl.ptr + state->cursor;
no_subst = 0; no_subst = 0;
} }
@ -71,7 +71,7 @@ psycTextRC psyc_text (psycTextState *state, psycTextCB getValue)
return PSYC_TEXT_NO_SUBST; return PSYC_TEXT_NO_SUBST;
// copy the rest of the template after the last var // copy the rest of the template after the last var
len = state->template.length - (prev - state->template.ptr); len = state->tmpl.length - (prev - state->tmpl.ptr);
if (state->written + len > state->buffer.length) if (state->written + len > state->buffer.length)
return PSYC_TEXT_INCOMPLETE; return PSYC_TEXT_INCOMPLETE;

View file

@ -0,0 +1,4 @@
_message_private
OHAI
|

1
test/packets/00-empty Normal file
View file

@ -0,0 +1 @@
|

View file

@ -0,0 +1,4 @@
22
_message_private
OHAI
|

View file

@ -0,0 +1,6 @@
:_source psyc://foo.example.com/
:_target psyc://bar.example.com/
22
_message_private
OHAI
|

View file

@ -0,0 +1,3 @@
_
|

View file

@ -80,6 +80,8 @@ int test_input (int i, char *recvbuf, size_t nbytes) {
value.length = 0; value.length = 0;
do { do {
if (verbose >= 3)
printf("\n# buffer = [%.*s]\n# part = %d\n", (int)parsers[i].buffer.length, parsers[i].buffer.ptr, parsers[i].part);
// Parse the next part of the packet (a routing/entity modifier or the body) // Parse the next part of the packet (a routing/entity modifier or the body)
ret = exit_code = psyc_parse(&parsers[i], &oper, &name, &value); ret = exit_code = psyc_parse(&parsers[i], &oper, &name, &value);
if (verbose >= 2) if (verbose >= 2)
@ -188,6 +190,8 @@ int test_input (int i, char *recvbuf, size_t nbytes) {
contbytes = psyc_getParseRemainingLength(&parsers[i]); contbytes = psyc_getParseRemainingLength(&parsers[i]);
if (contbytes > 0) { // copy end of parsebuf before start of recvbuf if (contbytes > 0) { // copy end of parsebuf before start of recvbuf
if (verbose >= 3)
printf("# remaining = [%.*s]\n", (int)contbytes, psyc_getParseRemainingBuffer(&parsers[i]));
assert(contbytes <= CONT_BUF_SIZE); // make sure it's still in the buffer assert(contbytes <= CONT_BUF_SIZE); // make sure it's still in the buffer
memmove(recvbuf - contbytes, psyc_getParseRemainingBuffer(&parsers[i]), contbytes); memmove(recvbuf - contbytes, psyc_getParseRemainingBuffer(&parsers[i]), contbytes);
} }