mirror of
git://git.psyc.eu/libpsyc
synced 2024-08-15 03:19:02 +00:00
isRoutingVar, rendering, some renames
This commit is contained in:
parent
f31a44ea6a
commit
ec76ea765e
13 changed files with 326 additions and 172 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,6 +5,7 @@ src/match
|
||||||
test/testMatch
|
test/testMatch
|
||||||
test/testParser
|
test/testParser
|
||||||
test/testRender
|
test/testRender
|
||||||
|
test/isRoutingVar
|
||||||
|
|
||||||
.config
|
.config
|
||||||
~$*
|
~$*
|
||||||
|
|
|
@ -36,7 +36,7 @@ typedef enum
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
PSYC_PART_RESET = -1,
|
PSYC_PART_RESET = -1,
|
||||||
PSYC_PART_HEADER = 0,
|
PSYC_PART_ROUTING,
|
||||||
PSYC_PART_LENGTH,
|
PSYC_PART_LENGTH,
|
||||||
PSYC_PART_CONTENT,
|
PSYC_PART_CONTENT,
|
||||||
PSYC_PART_METHOD,
|
PSYC_PART_METHOD,
|
||||||
|
@ -54,6 +54,7 @@ typedef enum
|
||||||
*/
|
*/
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
PSYC_TYPE_UNKNOWN,
|
||||||
PSYC_TYPE_AMOUNT,
|
PSYC_TYPE_AMOUNT,
|
||||||
PSYC_TYPE_COLOR,
|
PSYC_TYPE_COLOR,
|
||||||
PSYC_TYPE_DATE,
|
PSYC_TYPE_DATE,
|
||||||
|
@ -78,15 +79,26 @@ typedef enum
|
||||||
PSYC_LIST_BINARY = 2,
|
PSYC_LIST_BINARY = 2,
|
||||||
} PSYC_ListType;
|
} PSYC_ListType;
|
||||||
|
|
||||||
/**
|
typedef struct
|
||||||
* Get the type of variable name.
|
{
|
||||||
*/
|
size_t length;
|
||||||
PSYC_Type PSYC_getVarType(char* name, size_t len);
|
const char* ptr;
|
||||||
|
} PSYC_Array;
|
||||||
|
|
||||||
|
/// Routing vars in alphabetical order.
|
||||||
|
extern const PSYC_Array PSYC_routingVars[];
|
||||||
|
/// Number of routing vars.
|
||||||
|
extern const size_t PSYC_routingVarsNum;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the type of variable name.
|
* Get the type of variable name.
|
||||||
*/
|
*/
|
||||||
PSYC_Bool PSYC_isRoutingVar(char* name, size_t len);
|
PSYC_Bool PSYC_isRoutingVar(const char* name, size_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type of variable name.
|
||||||
|
*/
|
||||||
|
PSYC_Type PSYC_getVarType(char* name, size_t len);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if long keyword string inherits from short keyword string.
|
* Checks if long keyword string inherits from short keyword string.
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#ifndef DEBUG_H
|
||||||
|
# define DEBUG_H
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
# include <stdio.h>
|
# include <stdio.h>
|
||||||
# define PP(args) printf args;
|
# define PP(args) printf args;
|
||||||
|
@ -93,3 +96,4 @@
|
||||||
# define ASSERT(NAME,CONDITION,VALUE)
|
# define ASSERT(NAME,CONDITION,VALUE)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // DEBUG_H
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
/* this is needed to compile the library, not to use it */
|
/* this is needed to compile the library, not to use it */
|
||||||
|
|
||||||
|
#ifndef PSYC_LIB_H
|
||||||
|
# define PSYC_LIB_H
|
||||||
|
|
||||||
#include "../psyc.h"
|
#include "../psyc.h"
|
||||||
#include "./debug.h"
|
#include "./debug.h"
|
||||||
|
|
||||||
|
@ -12,3 +15,4 @@ void *memmem(const void *haystack, size_t haystacklen,
|
||||||
const void *needle, size_t needlelen);
|
const void *needle, size_t needlelen);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif // PSYC_LIB_H
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
PSYC_HEADER_ONLY = 1,
|
PSYC_PARSE_HEADER_ONLY = 1,
|
||||||
} PSYC_ParseFlag;
|
} PSYC_ParseFlag;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -30,35 +30,35 @@ typedef enum
|
||||||
*/
|
*/
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
PSYC_ERROR_END = -7,
|
PSYC_PARSE_ERROR_END = -7,
|
||||||
PSYC_ERROR_METHOD = -6,
|
PSYC_PARSE_ERROR_METHOD = -6,
|
||||||
PSYC_ERROR_VAR_LEN = -5,
|
PSYC_PARSE_ERROR_VAR_LEN = -5,
|
||||||
PSYC_ERROR_VAR_TAB = -4,
|
PSYC_PARSE_ERROR_VAR_TAB = -4,
|
||||||
PSYC_ERROR_VAR_NAME = -3,
|
PSYC_PARSE_ERROR_VAR_NAME = -3,
|
||||||
PSYC_ERROR_LENGTH = -2,
|
PSYC_PARSE_ERROR_LENGTH = -2,
|
||||||
PSYC_ERROR = -1,
|
PSYC_PARSE_ERROR = -1,
|
||||||
PSYC_SUCCESS = 0,
|
PSYC_PARSE_SUCCESS = 0,
|
||||||
/// Buffer contains insufficient amount of data.
|
/// Buffer contains insufficient amount of data.
|
||||||
/// Fill another buffer and concatenate it with the end of the current buffer,
|
/// Fill another buffer and concatenate it with the end of the current buffer,
|
||||||
/// from the cursor position to the end.
|
/// from the cursor position to the end.
|
||||||
PSYC_INSUFFICIENT = 1,
|
PSYC_PARSE_INSUFFICIENT = 1,
|
||||||
/// Routing variable parsing done.
|
/// Routing variable parsing done.
|
||||||
/// Modifier, name & value contains the respective parts.
|
/// Modifier, name & value contains the respective parts.
|
||||||
PSYC_ROUTING = 2,
|
PSYC_PARSE_ROUTING = 2,
|
||||||
/// Entity variable parsing done.
|
/// Entity variable parsing done.
|
||||||
/// Modifier, name & value contains the respective parts.
|
/// Modifier, name & value contains the respective parts.
|
||||||
PSYC_ENTITY = 3,
|
PSYC_PARSE_ENTITY = 3,
|
||||||
/// Entity variable parsing is incomplete.
|
/// Entity variable parsing is incomplete.
|
||||||
/// Modifier & name are complete, value is incomplete.
|
/// Modifier & name are complete, value is incomplete.
|
||||||
PSYC_ENTITY_INCOMPLETE = 4,
|
PSYC_PARSE_ENTITY_INCOMPLETE = 4,
|
||||||
/// Body parsing done, name contains method, value contains body.
|
/// Body parsing done, name contains method, value contains body.
|
||||||
PSYC_BODY = 5,
|
PSYC_PARSE_BODY = 5,
|
||||||
/// Body parsing is incomplete, name contains method, value contains part of the body.
|
/// Body parsing is incomplete, name contains method, value contains part of the body.
|
||||||
PSYC_BODY_INCOMPLETE = 6,
|
PSYC_PARSE_BODY_INCOMPLETE = 6,
|
||||||
/// Reached end of packet, parsing done.
|
/// Reached end of packet, parsing done.
|
||||||
PSYC_COMPLETE = 7,
|
PSYC_PARSE_COMPLETE = 7,
|
||||||
/// Binary value parsing incomplete, used internally.
|
/// Binary value parsing incomplete, used internally.
|
||||||
PSYC_INCOMPLETE = 8,
|
PSYC_PARSE_INCOMPLETE = 8,
|
||||||
} PSYC_ParseRC;
|
} PSYC_ParseRC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,25 +67,19 @@ typedef enum
|
||||||
*/
|
*/
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
PSYC_ERROR_LIST_DELIM = -5,
|
PSYC_PARSE_LIST_ERROR_DELIM = -5,
|
||||||
PSYC_ERROR_LIST_LEN = -4,
|
PSYC_PARSE_LIST_ERROR_LEN = -4,
|
||||||
PSYC_ERROR_LIST_TYPE = -3,
|
PSYC_PARSE_LIST_ERROR_TYPE = -3,
|
||||||
PSYC_ERROR_LIST_NAME = -2,
|
PSYC_PARSE_LIST_ERROR_NAME = -2,
|
||||||
PSYC_ERROR_LIST= -1,
|
PSYC_PARSE_LIST_ERROR= -1,
|
||||||
/// Completed parsing a list element.
|
/// Completed parsing a list element.
|
||||||
PSYC_LIST_ELEM = 1,
|
PSYC_PARSE_LIST_ELEM = 1,
|
||||||
/// Reached end of buffer.
|
/// Reached end of buffer.
|
||||||
PSYC_LIST_END = 2,
|
PSYC_PARSE_LIST_END = 2,
|
||||||
/// Binary list is incomplete.
|
/// Binary list is incomplete.
|
||||||
PSYC_LIST_INCOMPLETE = 3,
|
PSYC_PARSE_LIST_INCOMPLETE = 3,
|
||||||
} PSYC_ParseListRC;
|
} PSYC_ParseListRC;
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
size_t length;
|
|
||||||
const uint8_t* ptr; // just an unsigned char for opaque data
|
|
||||||
} PSYC_Array; // to be renamed or solved differently..
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Struct for keeping parser state.
|
* Struct for keeping parser state.
|
||||||
*/
|
*/
|
||||||
|
@ -118,7 +112,6 @@ typedef struct
|
||||||
size_t elemLength; ///< expected length of the elem
|
size_t elemLength; ///< expected length of the elem
|
||||||
} PSYC_ParseListState;
|
} PSYC_ParseListState;
|
||||||
|
|
||||||
#ifndef PSYC_COMPILE_LIBRARY
|
|
||||||
/**
|
/**
|
||||||
* Shortcut for creating an array.
|
* Shortcut for creating an array.
|
||||||
*
|
*
|
||||||
|
@ -127,7 +120,7 @@ typedef struct
|
||||||
*
|
*
|
||||||
* @return An instance of the PSYC_Array struct.
|
* @return An instance of the PSYC_Array struct.
|
||||||
*/
|
*/
|
||||||
inline PSYC_Array PSYC_createArray (uint8_t* const memory, size_t length)
|
inline PSYC_Array PSYC_createArray (const char* memory, size_t length)
|
||||||
{
|
{
|
||||||
PSYC_Array arr = {length, memory};
|
PSYC_Array arr = {length, memory};
|
||||||
return arr;
|
return arr;
|
||||||
|
@ -139,7 +132,7 @@ inline PSYC_Array PSYC_createArray (uint8_t* const memory, size_t length)
|
||||||
* @param state Pointer to the state struct that should be initiated.
|
* @param state Pointer to the state struct that should be initiated.
|
||||||
* @param flags Flags to be set for the parser, see PSYC_ParseFlag.
|
* @param flags Flags to be set for the parser, see PSYC_ParseFlag.
|
||||||
*/
|
*/
|
||||||
inline void PSYC_initState2 (PSYC_ParseState* state, uint8_t flags)
|
inline void PSYC_initParseState2 (PSYC_ParseState* state, uint8_t flags)
|
||||||
{
|
{
|
||||||
memset(state, 0, sizeof(PSYC_ParseState));
|
memset(state, 0, sizeof(PSYC_ParseState));
|
||||||
state->flags = flags;
|
state->flags = flags;
|
||||||
|
@ -150,7 +143,7 @@ inline void PSYC_initState2 (PSYC_ParseState* state, uint8_t flags)
|
||||||
*
|
*
|
||||||
* @param state Pointer to the state struct that should be initiated.
|
* @param state Pointer to the state struct that should be initiated.
|
||||||
*/
|
*/
|
||||||
inline void PSYC_initState (PSYC_ParseState* state)
|
inline void PSYC_initParseState (PSYC_ParseState* state)
|
||||||
{
|
{
|
||||||
memset(state, 0, sizeof(PSYC_ParseState));
|
memset(state, 0, sizeof(PSYC_ParseState));
|
||||||
}
|
}
|
||||||
|
@ -160,18 +153,18 @@ inline void PSYC_initState (PSYC_ParseState* state)
|
||||||
*
|
*
|
||||||
* @param state Pointer to the list state struct that should be initiated.
|
* @param state Pointer to the list state struct that should be initiated.
|
||||||
*/
|
*/
|
||||||
inline void PSYC_initListState (PSYC_ParseListState* state)
|
inline void PSYC_initParseListState (PSYC_ParseListState* state)
|
||||||
{
|
{
|
||||||
memset(state, 0, sizeof(PSYC_ParseListState));
|
memset(state, 0, sizeof(PSYC_ParseListState));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void PSYC_nextBuffer (PSYC_ParseState* state, PSYC_Array newBuf)
|
inline void PSYC_nextParseBuffer (PSYC_ParseState* state, PSYC_Array newBuf)
|
||||||
{
|
{
|
||||||
state->buffer = newBuf;
|
state->buffer = newBuf;
|
||||||
state->cursor = 0;
|
state->cursor = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void PSYC_nextListBuffer (PSYC_ParseListState* state, PSYC_Array newBuf)
|
inline void PSYC_nextParseListBuffer (PSYC_ParseListState* state, PSYC_Array newBuf)
|
||||||
{
|
{
|
||||||
state->buffer = newBuf;
|
state->buffer = newBuf;
|
||||||
state->cursor = 0;
|
state->cursor = 0;
|
||||||
|
@ -182,8 +175,6 @@ inline size_t PSYC_getContentLength (PSYC_ParseState* s)
|
||||||
return s->contentLength;
|
return s->contentLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse PSYC packets.
|
* Parse PSYC packets.
|
||||||
*
|
*
|
||||||
|
@ -197,7 +188,7 @@ inline size_t PSYC_getContentLength (PSYC_ParseState* s)
|
||||||
* @param value A pointer to a PSYC_Array. It will point to the
|
* @param value A pointer to a PSYC_Array. It will point to the
|
||||||
* value/body the variable/method and its length will be set accordingly
|
* value/body the variable/method and its length will be set accordingly
|
||||||
*/
|
*/
|
||||||
PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value);
|
PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* modifier, PSYC_Array* name, PSYC_Array* value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List value parser.
|
* List value parser.
|
||||||
|
|
|
@ -1,18 +1,33 @@
|
||||||
|
#ifndef PSYC_RENDER_H
|
||||||
|
# define PSYC_RENDER_H
|
||||||
|
|
||||||
#include "syntax.h"
|
#include "syntax.h"
|
||||||
|
|
||||||
|
#define PSYC_FLAG_UNDEFINED 0
|
||||||
|
#define PSYC_FLAG_NOT_BINARY 1
|
||||||
|
#define PSYC_FLAG_YES_BINARY 2
|
||||||
|
#define PSYC_FLAG_CHECK_BINARY 3
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PSYC_RENDER_CHECK_BINARY = 0,
|
||||||
|
PSYC_RENDER_BINARY = 1,
|
||||||
|
PSYC_RENDER_NOT_BINARY = 2,
|
||||||
|
PSYC_RENDER_ROUTING = 3,
|
||||||
|
} PSYC_RenderFlag;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
PSYC_RENDER_ERROR_ROUTING = -2,
|
||||||
|
PSYC_RENDER_ERROR = -1,
|
||||||
|
PSYC_RENDER_SUCCESS = 0,
|
||||||
|
} PSYC_RenderRC;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Struct for keeping render state.
|
* Struct for keeping render state.
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
typedef struct
|
||||||
PSYC_FINE = 0,
|
{
|
||||||
PSYC_NEED_LENGTH = 1
|
|
||||||
} PSYC_RenderFlag;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
PSYC_FLAG_ROUTING = 1
|
|
||||||
} PSYC_RenderHeaderFlag;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
PSYC_RenderFlag flag; ///< flags for the renderer
|
PSYC_RenderFlag flag; ///< flags for the renderer
|
||||||
PSYC_Part part; ///< part of the packet being rendered
|
PSYC_Part part; ///< part of the packet being rendered
|
||||||
size_t cursor; ///< current position in buffer
|
size_t cursor; ///< current position in buffer
|
||||||
|
@ -22,14 +37,23 @@ typedef struct {
|
||||||
char buffer[]; ///< OMG a C99 feature! variable size buffer!
|
char buffer[]; ///< OMG a C99 feature! variable size buffer!
|
||||||
} PSYC_RenderState;
|
} PSYC_RenderState;
|
||||||
|
|
||||||
int PSYC_renderHeader(PSYC_RenderState* render,
|
/**
|
||||||
|
* Initiates the state struct.
|
||||||
|
*
|
||||||
|
* @param state Pointer to the state struct that should be initiated.
|
||||||
|
*/
|
||||||
|
inline void PSYC_initRenderState (PSYC_RenderState* state)
|
||||||
|
{
|
||||||
|
memset(state, 0, sizeof(PSYC_RenderState));
|
||||||
|
}
|
||||||
|
|
||||||
|
int PSYC_renderVar(PSYC_RenderState* render,
|
||||||
const char* name, size_t nlength,
|
const char* name, size_t nlength,
|
||||||
const char* value, size_t vlength,
|
const char* value, size_t vlength,
|
||||||
PSYC_RenderHeaderFlag flags, char modifier);
|
PSYC_RenderFlag flags, char modifier);
|
||||||
|
|
||||||
int PSYC_renderBody(PSYC_RenderState* render,
|
int PSYC_renderBody(PSYC_RenderState* render,
|
||||||
const char* method, size_t mlength,
|
const char* method, size_t mlength,
|
||||||
const char* data, size_t dlength);
|
const char* data, size_t dlength);
|
||||||
|
|
||||||
int PSYC_doneRender(PSYC_RenderState* render,
|
#endif // PSYC_RENDER_H
|
||||||
uint8_t** buf, size_t* written);
|
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
CFLAGS=-I../../include -DDEBUG=2 -DPSYC_COMPILE_LIBRARY -g -O0 -Wall
|
CFLAGS=-I../include -DDEBUG=2 -DPSYC_COMPILE_LIBRARY -g -O0 -Wall
|
||||||
CC=cc -I../include
|
CC=cc
|
||||||
# CC=clang
|
# CC=clang
|
||||||
|
|
||||||
S=parser.c match.c render.c memmem.c
|
S=parser.c match.c render.c memmem.c variable.c
|
||||||
O=parser.o match.o render.o memmem.o
|
O=parser.o match.o render.o memmem.o variable.o
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc"
|
@/bin/echo -e "Usage:\n\tmake diet - compile with diet libc\n\tmake lib - compile with normal gnu libc"
|
||||||
|
|
124
src/parser.c
124
src/parser.c
|
@ -66,7 +66,7 @@ inline char isKwChar(uint8_t c)
|
||||||
/**
|
/**
|
||||||
* Parse variable name or method name.
|
* Parse variable name or method name.
|
||||||
* It should contain one or more keyword characters.
|
* It should contain one or more keyword characters.
|
||||||
* @return PSYC_ERROR or PSYC_SUCCESS
|
* @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS
|
||||||
*/
|
*/
|
||||||
inline PSYC_ParseRC PSYC_parseName(PSYC_ParseState* state, PSYC_Array* name)
|
inline PSYC_ParseRC PSYC_parseName(PSYC_ParseState* state, PSYC_Array* name)
|
||||||
{
|
{
|
||||||
|
@ -76,10 +76,10 @@ inline PSYC_ParseRC PSYC_parseName(PSYC_ParseState* state, PSYC_Array* name)
|
||||||
while (isKwChar(state->buffer.ptr[state->cursor]))
|
while (isKwChar(state->buffer.ptr[state->cursor]))
|
||||||
{
|
{
|
||||||
name->length++; // was a valid char, increase length
|
name->length++; // was a valid char, increase length
|
||||||
ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT);
|
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return name->length > 0 ? PSYC_SUCCESS : PSYC_ERROR;
|
return name->length > 0 ? PSYC_PARSE_SUCCESS : PSYC_PARSE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -90,7 +90,7 @@ inline PSYC_ParseRC PSYC_parseName(PSYC_ParseState* state, PSYC_Array* name)
|
||||||
* @param length Expected length of the data.
|
* @param length Expected length of the data.
|
||||||
* @param parsed Number of bytes parsed so far.
|
* @param parsed Number of bytes parsed so far.
|
||||||
*
|
*
|
||||||
* @return PSYC_COMPLETE or PSYC_INCOMPLETE
|
* @return PSYC_PARSE_COMPLETE or PSYC_PARSE_INCOMPLETE
|
||||||
*/
|
*/
|
||||||
inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParseState* state, PSYC_Array* value, size_t* length, size_t* parsed)
|
inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParseState* state, PSYC_Array* value, size_t* length, size_t* parsed)
|
||||||
{
|
{
|
||||||
|
@ -101,27 +101,27 @@ inline PSYC_ParseRC PSYC_parseBinaryValue(PSYC_ParseState* state, PSYC_Array* va
|
||||||
{
|
{
|
||||||
value->length = state->buffer.length - state->cursor;
|
value->length = state->buffer.length - state->cursor;
|
||||||
*parsed += value->length;
|
*parsed += value->length;
|
||||||
return PSYC_INCOMPLETE;
|
return PSYC_PARSE_INCOMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
value->length += remaining;
|
value->length += remaining;
|
||||||
state->cursor += remaining;
|
state->cursor += remaining;
|
||||||
*parsed += value->length;
|
*parsed += value->length;
|
||||||
|
|
||||||
return PSYC_COMPLETE;
|
return PSYC_PARSE_COMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse simple or binary variable.
|
* Parse simple or binary variable.
|
||||||
* @return PSYC_ERROR or PSYC_SUCCESS
|
* @return PSYC_PARSE_ERROR or PSYC_PARSE_SUCCESS
|
||||||
*/
|
*/
|
||||||
inline PSYC_ParseRC PSYC_parseVar(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value)
|
inline PSYC_ParseRC PSYC_parseVar(PSYC_ParseState* state, char* modifier, PSYC_Array* name, PSYC_Array* value)
|
||||||
{
|
{
|
||||||
*modifier = *(state->buffer.ptr + state->cursor);
|
*modifier = *(state->buffer.ptr + state->cursor);
|
||||||
ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT);
|
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||||
|
|
||||||
if (PSYC_parseName(state, name) != PSYC_SUCCESS)
|
if (PSYC_parseName(state, name) != PSYC_PARSE_SUCCESS)
|
||||||
return PSYC_ERROR_VAR_NAME;
|
return PSYC_PARSE_ERROR_VAR_NAME;
|
||||||
|
|
||||||
value->length = 0;
|
value->length = 0;
|
||||||
state->valueLength = 0;
|
state->valueLength = 0;
|
||||||
|
@ -131,55 +131,55 @@ inline PSYC_ParseRC PSYC_parseVar(PSYC_ParseState* state, uint8_t* modifier, PSY
|
||||||
// If we're in the content part check if it's a binary var.
|
// If we're in the content part check if it's a binary var.
|
||||||
if (state->part == PSYC_PART_CONTENT && state->buffer.ptr[state->cursor] == ' ') // binary arg
|
if (state->part == PSYC_PART_CONTENT && state->buffer.ptr[state->cursor] == ' ') // binary arg
|
||||||
{ // After SP the length follows.
|
{ // After SP the length follows.
|
||||||
ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT);
|
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||||
|
|
||||||
if (isNumeric(state->buffer.ptr[state->cursor]))
|
if (isNumeric(state->buffer.ptr[state->cursor]))
|
||||||
{
|
{
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
state->valueLength = 10 * state->valueLength + state->buffer.ptr[state->cursor] - '0';
|
state->valueLength = 10 * state->valueLength + state->buffer.ptr[state->cursor] - '0';
|
||||||
ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT);
|
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||||
}
|
}
|
||||||
while (isNumeric(state->buffer.ptr[state->cursor]));
|
while (isNumeric(state->buffer.ptr[state->cursor]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return PSYC_ERROR_VAR_LEN;
|
return PSYC_PARSE_ERROR_VAR_LEN;
|
||||||
|
|
||||||
// After the length a TAB follows.
|
// After the length a TAB follows.
|
||||||
if (state->buffer.ptr[state->cursor] != '\t')
|
if (state->buffer.ptr[state->cursor] != '\t')
|
||||||
return PSYC_ERROR_VAR_TAB;
|
return PSYC_PARSE_ERROR_VAR_TAB;
|
||||||
|
|
||||||
if (state->buffer.length <= ++(state->cursor)) // Incremented cursor inside length?
|
if (state->buffer.length <= ++(state->cursor)) // Incremented cursor inside length?
|
||||||
return PSYC_ENTITY_INCOMPLETE;
|
return PSYC_PARSE_ENTITY_INCOMPLETE;
|
||||||
|
|
||||||
if (PSYC_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)) == PSYC_INCOMPLETE)
|
if (PSYC_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed)) == PSYC_PARSE_INCOMPLETE)
|
||||||
return PSYC_ENTITY_INCOMPLETE;
|
return PSYC_PARSE_ENTITY_INCOMPLETE;
|
||||||
|
|
||||||
state->cursor++;
|
state->cursor++;
|
||||||
return PSYC_SUCCESS;
|
return PSYC_PARSE_SUCCESS;
|
||||||
}
|
}
|
||||||
else if (state->buffer.ptr[state->cursor] == '\t') // simple arg
|
else if (state->buffer.ptr[state->cursor] == '\t') // simple arg
|
||||||
{
|
{
|
||||||
ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT);
|
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||||
value->ptr = state->buffer.ptr + state->cursor;
|
value->ptr = state->buffer.ptr + state->cursor;
|
||||||
|
|
||||||
while (state->buffer.ptr[state->cursor] != '\n')
|
while (state->buffer.ptr[state->cursor] != '\n')
|
||||||
{
|
{
|
||||||
value->length++;
|
value->length++;
|
||||||
ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT);
|
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||||
}
|
}
|
||||||
state->cursor++;
|
state->cursor++;
|
||||||
return PSYC_SUCCESS;
|
return PSYC_PARSE_SUCCESS;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return PSYC_ERROR_VAR_TAB;
|
return PSYC_PARSE_ERROR_VAR_TAB;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse PSYC packets.
|
* Parse PSYC packets.
|
||||||
* Generalized line-based parser.
|
* Generalized line-based parser.
|
||||||
*/
|
*/
|
||||||
PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value)
|
PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, char* modifier, PSYC_Array* name, PSYC_Array* value)
|
||||||
{
|
{
|
||||||
int ret; // a return value
|
int ret; // a return value
|
||||||
size_t pos; // a cursor position
|
size_t pos; // a cursor position
|
||||||
|
@ -190,7 +190,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n
|
||||||
|
|
||||||
// First we test if we can access the first char.
|
// First we test if we can access the first char.
|
||||||
if (state->cursor >= state->buffer.length) // cursor is not inside the length
|
if (state->cursor >= state->buffer.length) // cursor is not inside the length
|
||||||
return PSYC_INSUFFICIENT;
|
return PSYC_PARSE_INSUFFICIENT;
|
||||||
|
|
||||||
switch (state->part)
|
switch (state->part)
|
||||||
{
|
{
|
||||||
|
@ -200,17 +200,17 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n
|
||||||
state->contentParsed = 0;
|
state->contentParsed = 0;
|
||||||
state->contentLength = 0;
|
state->contentLength = 0;
|
||||||
state->contentLengthFound = 0;
|
state->contentLengthFound = 0;
|
||||||
state->part = PSYC_PART_HEADER;
|
state->part = PSYC_PART_ROUTING;
|
||||||
// fall thru
|
// fall thru
|
||||||
|
|
||||||
case PSYC_PART_HEADER:
|
case PSYC_PART_ROUTING:
|
||||||
// Each line of the header starts with a glyph,
|
// Each line of the header starts with a glyph,
|
||||||
// i.e. :_name, -_name +_name etc,
|
// i.e. :_name, -_name +_name etc,
|
||||||
// so just test if the first char is a glyph.
|
// so just test if the first char is a glyph.
|
||||||
if (isGlyph(state->buffer.ptr[state->cursor])) // is the first char a glyph?
|
if (isGlyph(state->buffer.ptr[state->cursor])) // is the first char a glyph?
|
||||||
{ // it is a glyph, so a variable starts here
|
{ // it is a glyph, so a variable starts here
|
||||||
ret = PSYC_parseVar(state, modifier, name, value);
|
ret = PSYC_parseVar(state, modifier, name, value);
|
||||||
return ret == PSYC_SUCCESS ? PSYC_ROUTING : ret;
|
return ret == PSYC_PARSE_SUCCESS ? PSYC_PARSE_ROUTING : ret;
|
||||||
}
|
}
|
||||||
else // not a glyph
|
else // not a glyph
|
||||||
{
|
{
|
||||||
|
@ -227,7 +227,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0';
|
state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0';
|
||||||
ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT);
|
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||||
}
|
}
|
||||||
while (isNumeric(state->buffer.ptr[state->cursor]));
|
while (isNumeric(state->buffer.ptr[state->cursor]));
|
||||||
}
|
}
|
||||||
|
@ -236,7 +236,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n
|
||||||
{
|
{
|
||||||
// If we need to parse the header only and we know the content length,
|
// If we need to parse the header only and we know the content length,
|
||||||
// then skip content parsing.
|
// then skip content parsing.
|
||||||
if (state->flags & PSYC_HEADER_ONLY && state->contentLengthFound)
|
if (state->flags & PSYC_PARSE_HEADER_ONLY && state->contentLengthFound)
|
||||||
state->part = PSYC_PART_DATA;
|
state->part = PSYC_PART_DATA;
|
||||||
else
|
else
|
||||||
state->part = PSYC_PART_CONTENT;
|
state->part = PSYC_PART_CONTENT;
|
||||||
|
@ -245,13 +245,13 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n
|
||||||
{
|
{
|
||||||
// If we have a length then it should've been followed by a \n
|
// If we have a length then it should've been followed by a \n
|
||||||
if (state->contentLengthFound)
|
if (state->contentLengthFound)
|
||||||
return PSYC_ERROR_LENGTH;
|
return PSYC_PARSE_ERROR_LENGTH;
|
||||||
|
|
||||||
state->part = PSYC_PART_END;
|
state->part = PSYC_PART_END;
|
||||||
goto PSYC_PART_END;
|
goto PSYC_PART_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT);
|
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||||
state->startc = state->cursor;
|
state->startc = state->cursor;
|
||||||
// fall thru
|
// fall thru
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n
|
||||||
if (state->valueParsed < state->valueLength) {
|
if (state->valueParsed < state->valueLength) {
|
||||||
ret = PSYC_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed));
|
ret = PSYC_parseBinaryValue(state, value, &(state->valueLength), &(state->valueParsed));
|
||||||
state->contentParsed += value->length;
|
state->contentParsed += value->length;
|
||||||
return ret == PSYC_COMPLETE ? PSYC_ENTITY : PSYC_ENTITY_INCOMPLETE;
|
return ret == PSYC_PARSE_COMPLETE ? PSYC_PARSE_ENTITY : PSYC_PARSE_ENTITY_INCOMPLETE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Each line of the header starts with a glyph,
|
// Each line of the header starts with a glyph,
|
||||||
|
@ -273,7 +273,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n
|
||||||
pos = state->cursor;
|
pos = state->cursor;
|
||||||
ret = PSYC_parseVar(state, modifier, name, value);
|
ret = PSYC_parseVar(state, modifier, name, value);
|
||||||
state->contentParsed += state->cursor - pos;
|
state->contentParsed += state->cursor - pos;
|
||||||
return ret == PSYC_SUCCESS ? PSYC_ENTITY : ret;
|
return ret == PSYC_PARSE_SUCCESS ? PSYC_PARSE_ENTITY : ret;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -284,17 +284,17 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n
|
||||||
|
|
||||||
case PSYC_PART_METHOD:
|
case PSYC_PART_METHOD:
|
||||||
pos = state->cursor;
|
pos = state->cursor;
|
||||||
if (PSYC_parseName(state, name) == PSYC_SUCCESS)
|
if (PSYC_parseName(state, name) == PSYC_PARSE_SUCCESS)
|
||||||
{ // the method ends with a \n then the data follows
|
{ // the method ends with a \n then the data follows
|
||||||
if (state->buffer.ptr[state->cursor] != '\n')
|
if (state->buffer.ptr[state->cursor] != '\n')
|
||||||
return PSYC_ERROR_METHOD;
|
return PSYC_PARSE_ERROR_METHOD;
|
||||||
|
|
||||||
state->cursor++;
|
state->cursor++;
|
||||||
state->startc = state->cursor;
|
state->startc = state->cursor;
|
||||||
state->contentParsed += state->cursor - pos;
|
state->contentParsed += state->cursor - pos;
|
||||||
state->part = PSYC_PART_DATA;
|
state->part = PSYC_PART_DATA;
|
||||||
if (state->cursor >= state->buffer.length)
|
if (state->cursor >= state->buffer.length)
|
||||||
return PSYC_INSUFFICIENT;
|
return PSYC_PARSE_INSUFFICIENT;
|
||||||
// fall thru
|
// fall thru
|
||||||
}
|
}
|
||||||
else // No method, which means the packet should end now.
|
else // No method, which means the packet should end now.
|
||||||
|
@ -310,12 +310,12 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n
|
||||||
|
|
||||||
if (state->contentLengthFound) // We know the length of the packet.
|
if (state->contentLengthFound) // We know the length of the packet.
|
||||||
{
|
{
|
||||||
if (PSYC_parseBinaryValue(state, value, &(state->contentLength), &(state->contentParsed)) == PSYC_INCOMPLETE)
|
if (PSYC_parseBinaryValue(state, value, &(state->contentLength), &(state->contentParsed)) == PSYC_PARSE_INCOMPLETE)
|
||||||
return PSYC_BODY_INCOMPLETE;
|
return PSYC_PARSE_BODY_INCOMPLETE;
|
||||||
|
|
||||||
state->cursor++;
|
state->cursor++;
|
||||||
state->part = PSYC_PART_END;
|
state->part = PSYC_PART_END;
|
||||||
return PSYC_BODY;
|
return PSYC_PARSE_BODY;
|
||||||
}
|
}
|
||||||
else // Search for the terminator.
|
else // Search for the terminator.
|
||||||
{
|
{
|
||||||
|
@ -326,7 +326,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n
|
||||||
if (state->cursor+2 >= state->buffer.length) // incremented cursor inside length?
|
if (state->cursor+2 >= state->buffer.length) // incremented cursor inside length?
|
||||||
{
|
{
|
||||||
state->cursor = state->startc;
|
state->cursor = state->startc;
|
||||||
return PSYC_INSUFFICIENT;
|
return PSYC_PARSE_INSUFFICIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->buffer.ptr[state->cursor+1] == '|' &&
|
if (state->buffer.ptr[state->cursor+1] == '|' &&
|
||||||
|
@ -334,11 +334,11 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n
|
||||||
{
|
{
|
||||||
state->cursor++;
|
state->cursor++;
|
||||||
state->part = PSYC_PART_END;
|
state->part = PSYC_PART_END;
|
||||||
return PSYC_BODY;
|
return PSYC_PARSE_BODY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
value->length++;
|
value->length++;
|
||||||
ADVANCE_CURSOR_OR_RETURN(PSYC_INSUFFICIENT);
|
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_INSUFFICIENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,22 +347,22 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n
|
||||||
// End of packet, at this point we have already passed a \n
|
// End of packet, at this point we have already passed a \n
|
||||||
// and the cursor should point to |
|
// and the cursor should point to |
|
||||||
if (state->cursor+1 >= state->buffer.length) // incremented cursor inside length?
|
if (state->cursor+1 >= state->buffer.length) // incremented cursor inside length?
|
||||||
return PSYC_INSUFFICIENT;
|
return PSYC_PARSE_INSUFFICIENT;
|
||||||
|
|
||||||
if (state->buffer.ptr[state->cursor] == '|' &&
|
if (state->buffer.ptr[state->cursor] == '|' &&
|
||||||
state->buffer.ptr[state->cursor+1] == '\n') // packet ends here
|
state->buffer.ptr[state->cursor+1] == '\n') // packet ends here
|
||||||
{
|
{
|
||||||
state->cursor += 2;
|
state->cursor += 2;
|
||||||
state->part = PSYC_PART_RESET;
|
state->part = PSYC_PART_RESET;
|
||||||
return PSYC_COMPLETE;
|
return PSYC_PARSE_COMPLETE;
|
||||||
}
|
}
|
||||||
else // packet should've ended here, return error
|
else // packet should've ended here, return error
|
||||||
{
|
{
|
||||||
state->part = PSYC_PART_RESET;
|
state->part = PSYC_PART_RESET;
|
||||||
return PSYC_ERROR_END;
|
return PSYC_PARSE_ERROR_END;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PSYC_ERROR; // should not be reached
|
return PSYC_PARSE_ERROR; // should not be reached
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -372,7 +372,7 @@ PSYC_ParseRC PSYC_parse(PSYC_ParseState* state, uint8_t* modifier, PSYC_Array* n
|
||||||
PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem)
|
PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PSYC_Array* value, PSYC_Array* elem)
|
||||||
{
|
{
|
||||||
if (state->cursor >= state->buffer.length)
|
if (state->cursor >= state->buffer.length)
|
||||||
return PSYC_LIST_INCOMPLETE;
|
return PSYC_PARSE_LIST_INCOMPLETE;
|
||||||
|
|
||||||
state->startc = state->cursor;
|
state->startc = state->cursor;
|
||||||
|
|
||||||
|
@ -380,7 +380,7 @@ PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PS
|
||||||
{
|
{
|
||||||
if (name->length < 5 || memcmp(name->ptr, "_list", 5) != 0 ||
|
if (name->length < 5 || memcmp(name->ptr, "_list", 5) != 0 ||
|
||||||
(name->length > 5 && name->ptr[5] != '_')) // name should be _list or should start with _list_
|
(name->length > 5 && name->ptr[5] != '_')) // name should be _list or should start with _list_
|
||||||
return PSYC_ERROR_LIST_NAME;
|
return PSYC_PARSE_LIST_ERROR_NAME;
|
||||||
|
|
||||||
// First character is either | for text lists, or a number for binary lists
|
// First character is either | for text lists, or a number for binary lists
|
||||||
if (state->buffer.ptr[state->cursor] == '|')
|
if (state->buffer.ptr[state->cursor] == '|')
|
||||||
|
@ -391,7 +391,7 @@ PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PS
|
||||||
else if (isNumeric(state->buffer.ptr[state->cursor]))
|
else if (isNumeric(state->buffer.ptr[state->cursor]))
|
||||||
state->type = PSYC_LIST_BINARY;
|
state->type = PSYC_LIST_BINARY;
|
||||||
else
|
else
|
||||||
return PSYC_ERROR_LIST_TYPE;
|
return PSYC_PARSE_LIST_ERROR_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state->type == PSYC_LIST_TEXT)
|
if (state->type == PSYC_LIST_TEXT)
|
||||||
|
@ -400,16 +400,16 @@ PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PS
|
||||||
elem->length = 0;
|
elem->length = 0;
|
||||||
|
|
||||||
if (state->cursor >= state->buffer.length)
|
if (state->cursor >= state->buffer.length)
|
||||||
return PSYC_LIST_END;
|
return PSYC_PARSE_LIST_END;
|
||||||
|
|
||||||
while (state->buffer.ptr[state->cursor] != '|')
|
while (state->buffer.ptr[state->cursor] != '|')
|
||||||
{
|
{
|
||||||
elem->length++;
|
elem->length++;
|
||||||
if (++(state->cursor) >= state->buffer.length)
|
if (++(state->cursor) >= state->buffer.length)
|
||||||
return PSYC_LIST_END;
|
return PSYC_PARSE_LIST_END;
|
||||||
}
|
}
|
||||||
state->cursor++;
|
state->cursor++;
|
||||||
return PSYC_LIST_ELEM;
|
return PSYC_PARSE_LIST_ELEM;
|
||||||
}
|
}
|
||||||
else // binary list
|
else // binary list
|
||||||
{
|
{
|
||||||
|
@ -421,15 +421,15 @@ PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PS
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
state->elemLength = 10 * state->elemLength + state->buffer.ptr[state->cursor] - '0';
|
state->elemLength = 10 * state->elemLength + state->buffer.ptr[state->cursor] - '0';
|
||||||
ADVANCE_CURSOR_OR_RETURN(PSYC_LIST_INCOMPLETE);
|
ADVANCE_CURSOR_OR_RETURN(PSYC_PARSE_LIST_INCOMPLETE);
|
||||||
}
|
}
|
||||||
while (isNumeric(state->buffer.ptr[state->cursor]));
|
while (isNumeric(state->buffer.ptr[state->cursor]));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return PSYC_ERROR_LIST_LEN;
|
return PSYC_PARSE_LIST_ERROR_LEN;
|
||||||
|
|
||||||
if (state->buffer.ptr[state->cursor] != ' ')
|
if (state->buffer.ptr[state->cursor] != ' ')
|
||||||
return PSYC_ERROR_LIST_LEN;
|
return PSYC_PARSE_LIST_ERROR_LEN;
|
||||||
|
|
||||||
state->cursor++;
|
state->cursor++;
|
||||||
elem->ptr = state->buffer.ptr + state->cursor;
|
elem->ptr = state->buffer.ptr + state->cursor;
|
||||||
|
@ -440,21 +440,21 @@ PSYC_ParseListRC PSYC_parseList(PSYC_ParseListState* state, PSYC_Array *name, PS
|
||||||
// Start or resume parsing the binary data
|
// Start or resume parsing the binary data
|
||||||
if (state->elemParsed < state->elemLength)
|
if (state->elemParsed < state->elemLength)
|
||||||
{
|
{
|
||||||
if (PSYC_parseBinaryValue((PSYC_ParseState*)state, elem, &(state->elemLength), &(state->elemParsed)) == PSYC_INCOMPLETE)
|
if (PSYC_parseBinaryValue((PSYC_ParseState*)state, elem, &(state->elemLength), &(state->elemParsed)) == PSYC_PARSE_INCOMPLETE)
|
||||||
return PSYC_LIST_INCOMPLETE;
|
return PSYC_PARSE_LIST_INCOMPLETE;
|
||||||
|
|
||||||
state->elemLength = 0;
|
state->elemLength = 0;
|
||||||
|
|
||||||
if (state->cursor >= state->buffer.length)
|
if (state->cursor >= state->buffer.length)
|
||||||
return PSYC_LIST_END;
|
return PSYC_PARSE_LIST_END;
|
||||||
|
|
||||||
if (state->buffer.ptr[state->cursor] != '|')
|
if (state->buffer.ptr[state->cursor] != '|')
|
||||||
return PSYC_ERROR_LIST_DELIM;
|
return PSYC_PARSE_LIST_ERROR_DELIM;
|
||||||
|
|
||||||
state->cursor++;
|
state->cursor++;
|
||||||
return PSYC_LIST_ELEM;
|
return PSYC_PARSE_LIST_ELEM;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return PSYC_ERROR_LIST; // should not be reached
|
return PSYC_PARSE_LIST_ERROR; // should not be reached
|
||||||
}
|
}
|
||||||
|
|
71
src/render.c
71
src/render.c
|
@ -1,51 +1,70 @@
|
||||||
#include "psyc/lib.h"
|
#include "psyc/lib.h"
|
||||||
#include "psyc/render.h"
|
#include "psyc/render.h"
|
||||||
|
|
||||||
int PSYC_renderHeader(PSYC_RenderState* r,
|
PSYC_RenderRC PSYC_renderVar(PSYC_RenderState* state,
|
||||||
const char* name, size_t nlength,
|
const char* name, size_t nlength,
|
||||||
const char* value, size_t vlength,
|
const char* value, size_t vlength,
|
||||||
const PSYC_RenderHeaderFlag flags,
|
const PSYC_RenderFlag flags, char modifier)
|
||||||
char modifier) {
|
{
|
||||||
|
size_t startc = state->cursor;
|
||||||
|
|
||||||
unless (nlength) nlength = strlen(name);
|
unless (nlength) nlength = strlen(name);
|
||||||
// vlength 0 means an empty variable.. no cheating there
|
// vlength 0 means an empty variable.. no cheating there
|
||||||
unless (modifier) modifier = C_GLYPH_MODIFIER_SET;
|
unless (modifier) modifier = C_GLYPH_MODIFIER_SET;
|
||||||
|
|
||||||
r->buffer[r->cursor++] = modifier;
|
state->buffer[state->cursor++] = modifier;
|
||||||
strncpy(&r->buffer[r->cursor], name, nlength);
|
strncpy(&state->buffer[state->cursor], name, nlength);
|
||||||
r->cursor += nlength;
|
state->cursor += nlength;
|
||||||
if (vlength) {
|
|
||||||
r->buffer[r->cursor++] = '\t';
|
if (vlength)
|
||||||
strncpy(&r->buffer[r->cursor], value, vlength);
|
{
|
||||||
r->cursor += vlength;
|
state->buffer[state->cursor++] = '\t';
|
||||||
|
strncpy(&state->buffer[state->cursor], value, vlength);
|
||||||
|
state->cursor += vlength;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (flags == PSYC_FLAG_ROUTING) {
|
//if (flags == PSYC_RENDER_ROUTING)
|
||||||
if (r->spot != 0) {
|
if (PSYC_isRoutingVar(name, nlength))
|
||||||
P1(("Too late to add a routing variable!\n"))
|
{ // no more routing headers allowed after content started
|
||||||
return -1;
|
if (state->part != PSYC_PART_ROUTING)
|
||||||
|
{
|
||||||
|
P1(("Too late to add a routing variable!\n"));
|
||||||
|
return PSYC_RENDER_ERROR_ROUTING;
|
||||||
}
|
}
|
||||||
} else if (r->spot == 0) {
|
}
|
||||||
|
else if (state->part == PSYC_PART_ROUTING)
|
||||||
|
{ // first entity header, set part to content
|
||||||
|
state->part = PSYC_PART_CONTENT;
|
||||||
// add "\n000000000" to buffer
|
// add "\n000000000" to buffer
|
||||||
// and make spot point to the first 0
|
// and make spot point to the first 0
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
|
// update content length if we're in the content part
|
||||||
|
if (state->part == PSYC_PART_CONTENT)
|
||||||
|
state->contentLength += state->cursor - startc;
|
||||||
|
|
||||||
|
return PSYC_RENDER_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int PSYC_renderBody(PSYC_RenderState* render,
|
/* render PSYC packets */
|
||||||
|
PSYC_RenderRC PSYC_renderBody(PSYC_RenderState* state,
|
||||||
const char* method, size_t mlength,
|
const char* method, size_t mlength,
|
||||||
const char* data, size_t dlength) {
|
const char* data, size_t dlength)
|
||||||
|
{
|
||||||
|
if (state->flag == PSYC_RENDER_CHECK_BINARY)
|
||||||
|
{
|
||||||
// find out if this packet needs a prepended length
|
// find out if this packet needs a prepended length
|
||||||
if (dlength == 1 && data[0] == C_GLYPH_PACKET_DELIMITER)
|
if (dlength == 1 && data[0] == C_GLYPH_PACKET_DELIMITER)
|
||||||
render->flag = PSYC_NEED_LENGTH;
|
state->flag = PSYC_RENDER_BINARY;
|
||||||
else if (dlength > 404)
|
else if (dlength > 404)
|
||||||
render->flag = PSYC_NEED_LENGTH;
|
state->flag = PSYC_RENDER_BINARY;
|
||||||
else if (memmem(data, dlength, PSYC_PACKET_DELIMITER,
|
else if (memmem(data, dlength, PSYC_PACKET_DELIMITER, sizeof(PSYC_PACKET_DELIMITER)))
|
||||||
sizeof(PSYC_PACKET_DELIMITER)))
|
state->flag = PSYC_RENDER_BINARY;
|
||||||
render->flag = PSYC_NEED_LENGTH;
|
|
||||||
else
|
else
|
||||||
render->flag = PSYC_FINE;
|
state->flag = PSYC_RENDER_NOT_BINARY;
|
||||||
|
}
|
||||||
|
|
||||||
// TBD
|
// TBD
|
||||||
return 0;
|
|
||||||
|
return PSYC_RENDER_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
73
src/variable.c
Normal file
73
src/variable.c
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
#include <psyc.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
const PSYC_Array PSYC_routingVars[] =
|
||||||
|
{
|
||||||
|
{17, "_amount_fragments"},
|
||||||
|
{ 8, "_context"},
|
||||||
|
{ 6, "_count"},
|
||||||
|
{ 8, "_counter"}, // the name for this is supposed to be _count, not _counter
|
||||||
|
{ 9, "_fragment"},
|
||||||
|
{ 7, "_length"},
|
||||||
|
{ 7, "_source"},
|
||||||
|
{22, "_source_identification"},
|
||||||
|
{13, "_source_relay"},
|
||||||
|
{19, "_source_relay_relay"}, // until you have a better idea.. is this really in use?
|
||||||
|
{ 4, "_tag"},
|
||||||
|
{10, "_tag_relay"},
|
||||||
|
{10, "_tag_reply"}, // should be obsolete, but.. TODO
|
||||||
|
{ 7, "_target"},
|
||||||
|
{15, "_target_forward"},
|
||||||
|
{13, "_target_relay"},
|
||||||
|
{19, "_understand_modules"},
|
||||||
|
{14, "_using_modules"},
|
||||||
|
};
|
||||||
|
|
||||||
|
const size_t PSYC_routingVarsNum = sizeof(PSYC_routingVars) / sizeof(*PSYC_routingVars);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type of variable name.
|
||||||
|
*/
|
||||||
|
PSYC_Bool PSYC_isRoutingVar(const char* name, size_t len)
|
||||||
|
{
|
||||||
|
size_t cursor = 1;
|
||||||
|
int8_t matching[PSYC_routingVarsNum]; // indexes of matching vars
|
||||||
|
memset(&matching, -1, sizeof(matching));
|
||||||
|
uint8_t i, m = 0;
|
||||||
|
|
||||||
|
if (len < 2 || name[0] != '_')
|
||||||
|
return PSYC_FALSE;
|
||||||
|
|
||||||
|
// first find the vars with matching length
|
||||||
|
for (i=0; i<PSYC_routingVarsNum; i++)
|
||||||
|
if (len == PSYC_routingVars[i].length)
|
||||||
|
matching[m++] = i;
|
||||||
|
|
||||||
|
while (cursor < len && matching[0] >= 0)
|
||||||
|
{
|
||||||
|
for (i = m = 0; i < PSYC_routingVarsNum; i++)
|
||||||
|
{
|
||||||
|
if (matching[i] < 0)
|
||||||
|
break;
|
||||||
|
if (PSYC_routingVars[matching[i]].ptr[cursor] == name[cursor])
|
||||||
|
matching[m++] = matching[i]; // found a match, update matching indexes
|
||||||
|
else if (PSYC_routingVars[matching[i]].ptr[cursor] > name[cursor])
|
||||||
|
break; // passed the possible matches in alphabetical order
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m < PSYC_routingVarsNum)
|
||||||
|
matching[m] = -1; // mark the end of matching indexes
|
||||||
|
|
||||||
|
cursor++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return matching[0] >= 0 ? PSYC_TRUE : PSYC_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type of variable name.
|
||||||
|
*/
|
||||||
|
PSYC_Type PSYC_getVarType(char* name, size_t len)
|
||||||
|
{
|
||||||
|
return PSYC_TYPE_UNKNOWN;
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
CFLAGS=-I../include -DDEBUG -g -O0 -Wall
|
CFLAGS=-I../include -DDEBUG -g -O0 -Wall
|
||||||
LDFLAGS=-L../src
|
LDFLAGS=-L../src
|
||||||
LOADLIBES=-lpsyc
|
LOADLIBES=-lpsyc
|
||||||
TARGETS=testParser testMatch testRender
|
TARGETS=testParser testMatch testRender isRoutingVar
|
||||||
|
|
||||||
all: $(TARGETS)
|
all: $(TARGETS)
|
||||||
|
|
||||||
|
|
26
test/isRoutingVar.c
Normal file
26
test/isRoutingVar.c
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
#include <psyc.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
char* vars[] =
|
||||||
|
{
|
||||||
|
"_source",
|
||||||
|
"_source_relay",
|
||||||
|
"_source_foo",
|
||||||
|
"_sourcherry",
|
||||||
|
"_foo",
|
||||||
|
"bar",
|
||||||
|
"_",
|
||||||
|
};
|
||||||
|
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < sizeof(vars) / sizeof(*vars); i++)
|
||||||
|
{
|
||||||
|
printf("%s: %d\n", vars[i], PSYC_isRoutingVar(vars[i], strlen(vars[i])));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -21,18 +21,18 @@ int main(int argc, char** argv)
|
||||||
write(1, buffer, index);
|
write(1, buffer, index);
|
||||||
write(1, ">> PARSE\n", 9);
|
write(1, ">> PARSE\n", 9);
|
||||||
|
|
||||||
PSYC_initState(&state);
|
PSYC_initParseState(&state);
|
||||||
PSYC_nextBuffer(&state, PSYC_createArray(buffer, index));
|
PSYC_nextParseBuffer(&state, PSYC_createArray(buffer, index));
|
||||||
|
|
||||||
// try parsing that now
|
// try parsing that now
|
||||||
while ((ret = PSYC_parse(&state, &modifier, &name, &value)))
|
while ((ret = PSYC_parse(&state, &modifier, &name, &value)))
|
||||||
{
|
{
|
||||||
switch (ret)
|
switch (ret)
|
||||||
{
|
{
|
||||||
case PSYC_ROUTING:
|
case PSYC_PARSE_ROUTING:
|
||||||
case PSYC_ENTITY:
|
case PSYC_PARSE_ENTITY:
|
||||||
write(1, &modifier, 1);
|
write(1, &modifier, 1);
|
||||||
case PSYC_BODY:
|
case PSYC_PARSE_BODY:
|
||||||
// printf("the string is '%.*s'\n", name);
|
// printf("the string is '%.*s'\n", name);
|
||||||
write(1, name.ptr, name.length);
|
write(1, name.ptr, name.length);
|
||||||
write(1, " = ", 3);
|
write(1, " = ", 3);
|
||||||
|
@ -41,14 +41,14 @@ int main(int argc, char** argv)
|
||||||
if (memcmp(name.ptr, "_list", 5) == 0)
|
if (memcmp(name.ptr, "_list", 5) == 0)
|
||||||
{
|
{
|
||||||
write(1, ">>> LIST START\n", 15);
|
write(1, ">>> LIST START\n", 15);
|
||||||
PSYC_initListState(&listState);
|
PSYC_initParseListState(&listState);
|
||||||
PSYC_nextListBuffer(&listState, value);
|
PSYC_nextParseListBuffer(&listState, value);
|
||||||
while ((ret = PSYC_parseList(&listState, &name, &value, &elem)))
|
while ((ret = PSYC_parseList(&listState, &name, &value, &elem)))
|
||||||
{
|
{
|
||||||
switch (ret)
|
switch (ret)
|
||||||
{
|
{
|
||||||
case PSYC_LIST_END:
|
case PSYC_PARSE_LIST_END:
|
||||||
case PSYC_LIST_ELEM:
|
case PSYC_PARSE_LIST_ELEM:
|
||||||
write(1, "|", 1);
|
write(1, "|", 1);
|
||||||
write(1, elem.ptr, elem.length);
|
write(1, elem.ptr, elem.length);
|
||||||
write(1, "\n", 1);
|
write(1, "\n", 1);
|
||||||
|
@ -58,7 +58,7 @@ int main(int argc, char** argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == PSYC_LIST_END)
|
if (ret == PSYC_PARSE_LIST_END)
|
||||||
{
|
{
|
||||||
write(1, ">>> LIST END\n", 13);
|
write(1, ">>> LIST END\n", 13);
|
||||||
break;
|
break;
|
||||||
|
@ -66,10 +66,10 @@ int main(int argc, char** argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PSYC_COMPLETE:
|
case PSYC_PARSE_COMPLETE:
|
||||||
printf("Done parsing.\n");
|
printf("Done parsing.\n");
|
||||||
continue;
|
continue;
|
||||||
case PSYC_INSUFFICIENT:
|
case PSYC_PARSE_INSUFFICIENT:
|
||||||
printf("Insufficient data.\n");
|
printf("Insufficient data.\n");
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in a new issue