mirror of
git://git.psyc.eu/libpsyc
synced 2024-08-15 03:19:02 +00:00
started to fix the return values. WIP
This commit is contained in:
parent
dbadcf407d
commit
8507dd9659
2 changed files with 82 additions and 167 deletions
|
@ -1,6 +1,15 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
PSYC_SUCCESS = 0,
|
||||||
|
PSYC_INSUFFICIENT = 1,
|
||||||
|
PSYC_ROUTING = 2,
|
||||||
|
PSYC_ENTITY = 3,
|
||||||
|
PSYC_COMPLETE = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
@ -16,6 +25,7 @@ typedef struct
|
||||||
|
|
||||||
char inHeader;
|
char inHeader;
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
|
unsigned int contentLength;
|
||||||
} PSYC_State;
|
} PSYC_State;
|
||||||
|
|
||||||
|
|
||||||
|
@ -48,141 +58,4 @@ inline unsigned int PSYC_getBodyLength (PSYC_State* state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @brief parses a routerVariable
|
|
||||||
*
|
|
||||||
* This function parses one routing variable,
|
|
||||||
* advances the cursor after the variable,
|
|
||||||
* writes the variables name, value and their
|
|
||||||
* lengths in the corresponding out parameters
|
|
||||||
* and returns 0 or an errorcode.
|
|
||||||
*
|
|
||||||
* Note that a return value of 3 does
|
|
||||||
* not exclude the possibility of
|
|
||||||
* the variable related parameters being
|
|
||||||
* filled.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @param data pointer to the packet data
|
|
||||||
* @param dlength length of the data (amount of bytes)
|
|
||||||
* @param cursor pointer to the current parsing position
|
|
||||||
* @param name pointer-pointer, used to return the position
|
|
||||||
* of the name string
|
|
||||||
* @param nlength pointer to which the length of
|
|
||||||
* the name string will be written
|
|
||||||
* @param value pointer-pointer, used to retrun the position
|
|
||||||
* of the value string
|
|
||||||
* @param vlength pointer to which the length of
|
|
||||||
* the value string will be written
|
|
||||||
*
|
|
||||||
* @returns 0 on success
|
|
||||||
* 1 on insufficient data.
|
|
||||||
* This does not advance
|
|
||||||
* the cursor.
|
|
||||||
* 2 when no longer in the header,
|
|
||||||
* This advances the cursor to the
|
|
||||||
* body/entity section, but leaves
|
|
||||||
* the other out parameters invalid.
|
|
||||||
* 3 the packet is complete.
|
|
||||||
* >3 on a context error,
|
|
||||||
* <0 on a parsing error.
|
|
||||||
* This invalidates all but the cursor
|
|
||||||
* out paramater. */
|
|
||||||
int PSYC_parseHeader(
|
|
||||||
unsigned int* cursor,
|
|
||||||
const uint8_t * data, unsigned int dlength,
|
|
||||||
const uint8_t** name, unsigned int *nlength,
|
|
||||||
const uint8_t** value, unsigned int *vlength);
|
|
||||||
|
|
||||||
/** @brief parses one variable in two buffers
|
|
||||||
*
|
|
||||||
* This function is nearly identical to its
|
|
||||||
* brother parseHeader. The difference is,
|
|
||||||
* it uses two buffers and return parameters
|
|
||||||
* for everything. It is meant to be used
|
|
||||||
* in case parseHeader returned 2 for
|
|
||||||
* insufficient data and you don’t
|
|
||||||
* like to copy memory around to
|
|
||||||
* have all the data in one buffer.
|
|
||||||
* Using this function, you can pass two
|
|
||||||
* data buffers. The consequence is,
|
|
||||||
* that name and value can be distributed
|
|
||||||
* on two different buffers and thus need
|
|
||||||
* also two out paramaters. If only one
|
|
||||||
* will be used, length of the second
|
|
||||||
* will be 0.
|
|
||||||
*
|
|
||||||
* If your data is spread over more
|
|
||||||
* than two buffers, you need to
|
|
||||||
* copy that in one or two buffers.
|
|
||||||
* Given the unlikleyness of that
|
|
||||||
* event, we don't offer a three
|
|
||||||
* or more buffer function here.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
int PSYC_parseHeader2(
|
|
||||||
unsigned int* cursor,
|
|
||||||
const uint8_t * data1, unsigned int dlength1,
|
|
||||||
const uint8_t * data2, unsigned int dlength2,
|
|
||||||
const uint8_t** name1, unsigned int *nlength1,
|
|
||||||
const uint8_t** name2, unsigned int *nlength2,
|
|
||||||
const uint8_t** value1, unsigned int *vlength1,
|
|
||||||
const uint8_t** value2, unsigned int *vlength2);
|
|
||||||
|
|
||||||
/** @brief parses one bodyelement
|
|
||||||
*
|
|
||||||
* This parses one body element, that is
|
|
||||||
* either an entity-variable or the method
|
|
||||||
*
|
|
||||||
* The function assumes that dlength is set
|
|
||||||
* to the exact length of the packet
|
|
||||||
* so that data[dlength-1] would be the
|
|
||||||
* ending "|" of the packet.
|
|
||||||
*
|
|
||||||
* The parameters are nearly the same as for
|
|
||||||
* PSYC_routerVariable, only difference is
|
|
||||||
* that a returnvalue of 2 means, we encountered
|
|
||||||
* the method.
|
|
||||||
* This means that the out paramterer
|
|
||||||
* name contains the methodname and
|
|
||||||
* value the content.
|
|
||||||
* */
|
|
||||||
int PSYC_parseClosedBody(
|
|
||||||
unsigned int* cursor,
|
|
||||||
const uint8_t * data, unsigned int dlength,
|
|
||||||
const uint8_t** name, unsigned int *nlength,
|
|
||||||
const uint8_t** value, unsigned int *vlength);
|
|
||||||
|
|
||||||
/** @brief parses one bodyelement
|
|
||||||
*
|
|
||||||
* This function is nearly identical to
|
|
||||||
* its brother parseClosedBody. *
|
|
||||||
*
|
|
||||||
* It assumes that we don’t know the
|
|
||||||
* real length of the packet and thus
|
|
||||||
* searches for the terminator.
|
|
||||||
*/
|
|
||||||
int PSYC_parseOpenBody(
|
|
||||||
unsigned int* cursor,
|
|
||||||
const uint8_t * data, unsigned int dlength,
|
|
||||||
const uint8_t** name, unsigned int *nlength,
|
|
||||||
const uint8_t** value, unsigned int *vlength);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* @brief parses an bodyelement in two buffers
|
|
||||||
*
|
|
||||||
* This function is the borther of parseHeader2.
|
|
||||||
* It behaives the same as
|
|
||||||
* parseOpenBody and parseHeader2. */
|
|
||||||
int PSYC_parseOpenBody2(
|
|
||||||
unsigned int* cursor,
|
|
||||||
const uint8_t * data1, unsigned int dlength1,
|
|
||||||
const uint8_t * data2, unsigned int dlength2,
|
|
||||||
const uint8_t** name1, unsigned int *nlength1,
|
|
||||||
const uint8_t** name2, unsigned int *nlength2,
|
|
||||||
const uint8_t** value1, unsigned int *vlength1,
|
|
||||||
const uint8_t** value2, unsigned int *vlength2);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
102
src/parser.c
102
src/parser.c
|
@ -52,7 +52,7 @@ inline int PSYC_parse(
|
||||||
{
|
{
|
||||||
/* first we test if we can access the first char */
|
/* first we test if we can access the first char */
|
||||||
if(state->buffer.length<=state->cursor) // cursor is not inside the length
|
if(state->buffer.length<=state->cursor) // cursor is not inside the length
|
||||||
return 1; // return insufficient data.
|
return PSYC_INSUFFICIENT; // return insufficient data.
|
||||||
|
|
||||||
// in case we return insufficent, we rewind to the start.
|
// in case we return insufficent, we rewind to the start.
|
||||||
unsigned int startc=state->cursor;
|
unsigned int startc=state->cursor;
|
||||||
|
@ -64,6 +64,32 @@ inline int PSYC_parse(
|
||||||
{
|
{
|
||||||
if(!isGlyph(state->buffer.ptr[state->cursor])) // is the first char not a glyph?
|
if(!isGlyph(state->buffer.ptr[state->cursor])) // is the first char not a glyph?
|
||||||
{
|
{
|
||||||
|
if(isNumeric(state->buffer.ptr[state->cursor]))
|
||||||
|
{
|
||||||
|
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght?
|
||||||
|
{
|
||||||
|
state->cursor=startc; // set to start value
|
||||||
|
return PSYC_INSUFFICIENT; // return insufficient
|
||||||
|
}
|
||||||
|
|
||||||
|
while(isNumeric(state->buffer.ptr[state->cursor]));
|
||||||
|
{
|
||||||
|
state->length = 10 * state->length + state->buffer.ptr[state->cursor] - '0';
|
||||||
|
|
||||||
|
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght?
|
||||||
|
{
|
||||||
|
state->cursor=startc; // set to start value
|
||||||
|
return PSYC_INSUFFICIENT; // return insufficient
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// a NL follows the length
|
||||||
|
if (state->buffer.ptr[state->cursor] != '\n')
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// the only other possibility now is that the packet
|
// the only other possibility now is that the packet
|
||||||
// is complete(empty packet) or that the method started.
|
// is complete(empty packet) or that the method started.
|
||||||
if(isAlphaNumeric(state->buffer.ptr[state->cursor]))
|
if(isAlphaNumeric(state->buffer.ptr[state->cursor]))
|
||||||
|
@ -77,7 +103,7 @@ inline int PSYC_parse(
|
||||||
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght?
|
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght?
|
||||||
{
|
{
|
||||||
state->cursor=startc; // set to start value
|
state->cursor=startc; // set to start value
|
||||||
return 1; // return insufficient
|
return PSYC_INSUFFICIENT; // return insufficient
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state->buffer.ptr[state->cursor]=='\n')
|
if(state->buffer.ptr[state->cursor]=='\n')
|
||||||
|
@ -87,14 +113,15 @@ inline int PSYC_parse(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -6; // report error
|
return -6; // report error
|
||||||
}else // it is a glyph, so a variable name starts here
|
}
|
||||||
|
else // it is a glyph, so a variable name starts here
|
||||||
{
|
{
|
||||||
*modifier = *(state->buffer.ptr+state->cursor);
|
*modifier = *(state->buffer.ptr+state->cursor);
|
||||||
|
|
||||||
if (state->buffer.length <= ++(state->cursor))
|
if (state->buffer.length <= ++(state->cursor))
|
||||||
{
|
{
|
||||||
state->cursor = startc; // rewind to start of line
|
state->cursor = startc; // rewind to start of line
|
||||||
return 1; // return insufficient
|
return PSYC_INSUFFICIENT; // return insufficient
|
||||||
}
|
}
|
||||||
|
|
||||||
name->ptr = state->buffer.ptr + state->cursor;
|
name->ptr = state->buffer.ptr + state->cursor;
|
||||||
|
@ -117,7 +144,7 @@ inline int PSYC_parse(
|
||||||
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght?
|
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght?
|
||||||
{
|
{
|
||||||
state->cursor=startc; // set to start value
|
state->cursor=startc; // set to start value
|
||||||
return 1; // return insufficient
|
return PSYC_INSUFFICIENT; // return insufficient
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state->buffer.ptr[state->cursor]=='\n')
|
if(state->buffer.ptr[state->cursor]=='\n')
|
||||||
|
@ -142,7 +169,7 @@ inline int PSYC_parse(
|
||||||
if (state->buffer.length <= ++(state->cursor))
|
if (state->buffer.length <= ++(state->cursor))
|
||||||
{
|
{
|
||||||
state->cursor = startc; // rewind
|
state->cursor = startc; // rewind
|
||||||
return 1; // return insufficient
|
return PSYC_INSUFFICIENT; // return insufficient
|
||||||
}
|
}
|
||||||
|
|
||||||
name->ptr = state->buffer.ptr+state->cursor;
|
name->ptr = state->buffer.ptr+state->cursor;
|
||||||
|
@ -153,7 +180,7 @@ inline int PSYC_parse(
|
||||||
if(state->buffer.length <= ++(state->cursor))
|
if(state->buffer.length <= ++(state->cursor))
|
||||||
{
|
{
|
||||||
state->cursor=startc;
|
state->cursor=startc;
|
||||||
return 1;
|
return PSYC_INSUFFICIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* what follows is the name. At least one char.
|
/* what follows is the name. At least one char.
|
||||||
|
@ -173,7 +200,7 @@ inline int PSYC_parse(
|
||||||
if(state->buffer.length<= ++(state->cursor)) // incremented cursor inside lenght?
|
if(state->buffer.length<= ++(state->cursor)) // incremented cursor inside lenght?
|
||||||
{
|
{
|
||||||
state->cursor=startc; // set to start value
|
state->cursor=startc; // set to start value
|
||||||
return 1; // return insufficient
|
return PSYC_INSUFFICIENT; // return insufficient
|
||||||
}
|
}
|
||||||
|
|
||||||
// same as bevore
|
// same as bevore
|
||||||
|
@ -187,7 +214,7 @@ inline int PSYC_parse(
|
||||||
/* we now parsed the variable name successfully
|
/* we now parsed the variable name successfully
|
||||||
* after the name either a \n or a \t follows.
|
* after the name either a \n or a \t follows.
|
||||||
*
|
*
|
||||||
* for the method, the state->buffer.ptr starts after an \n
|
* for the method, the data starts after an \n
|
||||||
* so checking for \n too here
|
* so checking for \n too here
|
||||||
|
|
||||||
* We dont check if cursor inside length, because
|
* We dont check if cursor inside length, because
|
||||||
|
@ -195,24 +222,24 @@ inline int PSYC_parse(
|
||||||
*/
|
*/
|
||||||
if(state->buffer.ptr[state->cursor] == '\t' || state->buffer.ptr[state->cursor] == '\n') // && method==1))
|
if(state->buffer.ptr[state->cursor] == '\t' || state->buffer.ptr[state->cursor] == '\n') // && method==1))
|
||||||
{
|
{
|
||||||
/* after the \t the arg-state->buffer.ptr follows, which is
|
/* after the \t the data follows, which is
|
||||||
* anything but \n. arg-state->buffer.ptr can be of length 0
|
* anything but \n. data can be of length 0
|
||||||
*
|
*
|
||||||
* for the method: after the \n state->buffer.ptr follows,
|
* for the method: after the \n data follows,
|
||||||
* which is anything but \n|\n
|
* which is anything but \n|\n
|
||||||
*
|
*
|
||||||
* but state->buffer.ptr is optional, so we first check
|
* but data is optional, so we first check
|
||||||
* here if state->buffer.ptr follows at all.
|
* here if data follows at all.
|
||||||
*
|
*
|
||||||
* arg-state->buffer.ptr=value->ptr. we set value here so it
|
* arg-data=value. we set value here so it
|
||||||
* points to a valid range and so we point
|
* points to a valid range and so we point
|
||||||
* to the first potential arg-state->buffer.ptr byte.
|
* to the first potential arg-data byte.
|
||||||
* If there is no arg-state->buffer.ptr, we still have
|
* If there is no arg-data, we still have
|
||||||
* the length attribute on 0. */
|
* the length attribute on 0. */
|
||||||
if((method == 0 && state->buffer.ptr[state->cursor] == '\n') /* emptyvar */ ||
|
if((method == 0 && state->buffer.ptr[state->cursor] == '\n') /* emptyvar */ ||
|
||||||
(method == 1 && state->cursor+2 < state->buffer.length &&
|
(method == 1 && state->cursor+2 < state->buffer.length &&
|
||||||
state->buffer.ptr[state->cursor+1] == '|' &&
|
state->buffer.ptr[state->cursor+1] == '|' &&
|
||||||
state->buffer.ptr[state->cursor+2] == '\n') /*no state->buffer.ptr */ )
|
state->buffer.ptr[state->cursor+2] == '\n') /*no data */ )
|
||||||
{
|
{
|
||||||
value->ptr=state->buffer.ptr+state->cursor;
|
value->ptr=state->buffer.ptr+state->cursor;
|
||||||
value->length=0;
|
value->length=0;
|
||||||
|
@ -220,9 +247,19 @@ inline int PSYC_parse(
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
value->ptr=state->buffer.ptr+state->cursor+1;
|
value->ptr=state->buffer.ptr+state->cursor+1;
|
||||||
if (1==state->length) // we know the length of the packet
|
if (0 != state->length) // we know the length of the packet
|
||||||
{
|
{
|
||||||
value->length= state->buffer.length - state->cursor -3;
|
// is the packet in the buffer?
|
||||||
|
if (value->ptr + state->length + 3 > state->buffer.ptr + state->buffer.length)
|
||||||
|
{ // no
|
||||||
|
value->length = state->buffer.length - state->cursor;
|
||||||
|
*expectedBytes = state->length - value->length;
|
||||||
|
}
|
||||||
|
else // yes, the packet is complete in the buffer.
|
||||||
|
{
|
||||||
|
value->length= state->buffer.length - state->cursor -3;
|
||||||
|
*expectedBytes = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else // else search for the terminator
|
else // else search for the terminator
|
||||||
{
|
{
|
||||||
|
@ -233,7 +270,7 @@ inline int PSYC_parse(
|
||||||
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght?
|
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght?
|
||||||
{
|
{
|
||||||
state->cursor=startc; // set to start value
|
state->cursor=startc; // set to start value
|
||||||
return 1; // return insufficient
|
return PSYC_INSUFFICIENT ; // return insufficient
|
||||||
}
|
}
|
||||||
|
|
||||||
if(0 == method && state->buffer.ptr[state->cursor] == '\n')
|
if(0 == method && state->buffer.ptr[state->cursor] == '\n')
|
||||||
|
@ -244,7 +281,7 @@ inline int PSYC_parse(
|
||||||
if(state->buffer.length<=(state->cursor)+2) // incremented cursor inside lenght?
|
if(state->buffer.length<=(state->cursor)+2) // incremented cursor inside lenght?
|
||||||
{
|
{
|
||||||
state->cursor=startc; // set to start value
|
state->cursor=startc; // set to start value
|
||||||
return 1; // return insufficient
|
return PSYC_INSUFFICIENT; // return insufficient
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state->buffer.ptr[state->cursor+1] == '|')
|
if(state->buffer.ptr[state->cursor+1] == '|')
|
||||||
|
@ -260,14 +297,15 @@ inline int PSYC_parse(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else if(state->inHeader == 0 && method==0 && state->buffer.ptr[state->cursor] == ' ') // oi, its a binary var!
|
}
|
||||||
|
else if(state->inHeader == 0 && method==0 && state->buffer.ptr[state->cursor] == ' ') // oi, its a binary var!
|
||||||
{ // after SP the length follows.
|
{ // after SP the length follows.
|
||||||
unsigned int binLength= 0;
|
unsigned int binLength= 0;
|
||||||
|
|
||||||
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght?
|
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght?
|
||||||
{
|
{
|
||||||
state->cursor=startc; // set to start value
|
state->cursor=startc; // set to start value
|
||||||
return 1; // return insufficient
|
return PSYC_INSUFFICIENT; // return insufficient
|
||||||
}
|
}
|
||||||
|
|
||||||
while(isNumeric(state->buffer.ptr[state->cursor]));
|
while(isNumeric(state->buffer.ptr[state->cursor]));
|
||||||
|
@ -277,7 +315,7 @@ inline int PSYC_parse(
|
||||||
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght?
|
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght?
|
||||||
{
|
{
|
||||||
state->cursor=startc; // set to start value
|
state->cursor=startc; // set to start value
|
||||||
return 1; // return insufficient
|
return PSYC_INSUFFICIENT; // return insufficient
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// after the length a TAB follows
|
// after the length a TAB follows
|
||||||
|
@ -288,7 +326,7 @@ inline int PSYC_parse(
|
||||||
if(state->buffer.length <= state->cursor+binLength+1 )
|
if(state->buffer.length <= state->cursor+binLength+1 )
|
||||||
{
|
{
|
||||||
state->cursor=startc;
|
state->cursor=startc;
|
||||||
return 1;
|
return PSYC_INSUFFICIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
value->ptr = state->buffer.ptr + state->cursor+1;
|
value->ptr = state->buffer.ptr + state->cursor+1;
|
||||||
|
@ -321,7 +359,7 @@ inline int PSYC_parse(
|
||||||
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght?
|
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght?
|
||||||
{
|
{
|
||||||
state->cursor=startc; // set to start value
|
state->cursor=startc; // set to start value
|
||||||
return 1; // return insufficient
|
return PSYC_INSUFFICIENT; // return insufficient
|
||||||
}
|
}
|
||||||
|
|
||||||
if(1 == state->inHeader && state->buffer.ptr[state->cursor] == '\n')
|
if(1 == state->inHeader && state->buffer.ptr[state->cursor] == '\n')
|
||||||
|
@ -332,12 +370,16 @@ inline int PSYC_parse(
|
||||||
}
|
}
|
||||||
|
|
||||||
if(state->buffer.ptr[state->cursor] != '|') // no pipe, then only line complete, not the packet.
|
if(state->buffer.ptr[state->cursor] != '|') // no pipe, then only line complete, not the packet.
|
||||||
return 0;
|
{
|
||||||
|
if (state->inHeader == 1)
|
||||||
|
return PSYC_ROUTING;
|
||||||
|
else
|
||||||
|
return PSYC_ENTITY;
|
||||||
|
}
|
||||||
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght?
|
if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght?
|
||||||
{
|
{
|
||||||
state->cursor=startc; // set to start value
|
state->cursor=startc; // set to start value
|
||||||
return 1; // return insufficient
|
return PSYC_INSUFFICIENT; // return insufficient
|
||||||
}
|
}
|
||||||
if(state->buffer.ptr[state->cursor] != '\n')
|
if(state->buffer.ptr[state->cursor] != '\n')
|
||||||
return -4;
|
return -4;
|
||||||
|
|
Loading…
Reference in a new issue