diff --git a/.gitignore b/.gitignore index 3910d12..30cd0c5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,11 +1,11 @@ -CVS .config ~$* .DS_Store .metadata -.actionScriptProperties .#* *~ +\#* +*.a *.o *.swf *.swp @@ -19,3 +19,4 @@ CVS src/match src/tests/parser/testParser src/tests/testMatch +src/tests/testParser diff --git a/include/psyc/parser.h b/include/psyc/parser.h index 0e49b7e..c1b9435 100644 --- a/include/psyc/parser.h +++ b/include/psyc/parser.h @@ -9,12 +9,15 @@ enum PSYC_Flags enum PSYC_ReturnCodes { - PSYC_METHOD = 1, + PSYC_ERROR_EXPECTED_TAB = -8, + PSYC_BODY = 1, + PSYC_BODY_INCOMPLETE, PSYC_INSUFFICIENT, PSYC_ROUTING, PSYC_ENTITY, + PSYC_ENTITY_INCOMPLETE, + PSYC_HEADER_COMPLETE, PSYC_COMPLETE, - PSYC_HEADER_COMPLETE, }; @@ -24,14 +27,16 @@ typedef struct const uint8_t * ptr; } PSYC_Array; + typedef struct { unsigned int cursor; // current position in buffer PSYC_Array buffer; uint8_t flags; - char inBody; - unsigned int length; + unsigned int contentParsed; // + char inContent; + unsigned int valueRemaining; unsigned int contentLength; } PSYC_State; @@ -42,22 +47,26 @@ typedef struct * @param length length of that buffer * * @returns an instance of the PSYC_Array struct */ -inline PSYC_Array PSYC_CreateArray (uint8_t* const memory, unsigned int length) +inline PSYC_Array PSYC_createArray (uint8_t* const memory, unsigned int length) { PSYC_Array arr = {length, memory}; return arr; } + /* @brief initiates the state struct with flags * * @param state pointer to the state struct that should be initiated - * @param flags the flags that one ones to set, se PSYC_Flags */ + * @param flags the flags that one ones to set, see PSYC_Flags */ inline void PSYC_initState2 (PSYC_State* state, uint8_t flags ) { memset(state, 0, sizeof(PSYC_State)); state->flags = flags; } +/* @brief initiates the state struct + * + * @param state pointer to the state struct that should be initiated */ inline void PSYC_initState (PSYC_State* state) { memset(state, 0, sizeof(PSYC_State)); @@ -66,16 +75,20 @@ inline void PSYC_initState (PSYC_State* state) inline void PSYC_nextBuffer (PSYC_State* state, PSYC_Array newBuf) { state->buffer = newBuf; + state->cursor = 0; } -inline unsigned int PSYC_getBodyLength (PSYC_State* state) +inline unsigned int PSYC_getContentLength (PSYC_State* s) { - return state->length; + return s->contentLength; } + +inline unsigned int PSYC_getValueRemaining (PSYC_State* s) +{ + return s->valueRemaining; +} + #endif int PSYC_parse(PSYC_State* state, - PSYC_Array* name, PSYC_Array* value, - uint8_t* modifier, unsigned long *expectedBytes); - - + uint8_t* modifier, PSYC_Array* name, PSYC_Array* value); diff --git a/src/.gitignore b/src/.gitignore deleted file mode 100644 index b96ae54..0000000 --- a/src/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -*.o -*.a -tests/testParser diff --git a/src/parser.c b/src/parser.c index 23e505d..ba7c209 100644 --- a/src/parser.c +++ b/src/parser.c @@ -47,10 +47,13 @@ inline char isAlphaNumeric(uint8_t c) /** @brief generalized linebased parser */ inline int PSYC_parse( PSYC_State* state, - PSYC_Array* name, PSYC_Array* value, - uint8_t* modifier, unsigned long* expectedBytes) + uint8_t* modifier, PSYC_Array* name, PSYC_Array* value) { start: + + if (state->valueRemaining != 0) + goto binaryArg; + /* first we test if we can access the first char */ if(state->buffer.length<=state->cursor) // cursor is not inside the length return PSYC_INSUFFICIENT; // return insufficient data. @@ -58,16 +61,19 @@ start: // in case we return insufficent, we rewind to the start. unsigned int startc=state->cursor; + /****************************************** + * * * * * * * Inspect Header * * * * * * * + *******************************************/ /* each line of the header starts with a glyph. * iE :_name, -_name +_name etc, so just test if * the first char is a glyph. */ - if(0==state->inBody) + if(0==state->inContent) { if(!isGlyph(state->buffer.ptr[state->cursor])) // is the first char not a glyph? - { + { // parse length of content here if(isNumeric(state->buffer.ptr[state->cursor])) { - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient @@ -75,45 +81,51 @@ start: while(isNumeric(state->buffer.ptr[state->cursor])); { - state->length = 10 * state->length + state->buffer.ptr[state->cursor] - '0'; + state->contentLength = 10 * state->contentLength + state->buffer.ptr[state->cursor] - '0'; - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient } } + } + // header ends with a NL + if (state->buffer.ptr[state->cursor] != '\n') + { + return -10; + } - // a NL follows the length - if (state->buffer.ptr[state->cursor] != '\n') - { - return -10; - } + if (state->buffer.length<=++(state->cursor)) // incremented cursor inside length? + { + state->cursor=startc; // set to start value + return PSYC_INSUFFICIENT; // return insufficient } // the only other possibility now is that the packet // is complete(empty packet) or that the method started. - if(isAlphaNumeric(state->buffer.ptr[state->cursor])) + if (isAlphaNumeric(state->buffer.ptr[state->cursor])) { - state->inBody = 1; + state->inContent = 1; + if (state->flags & PSYC_HEADER_ONLY) return PSYC_HEADER_COMPLETE; // return header finished else goto start; } - if(state->buffer.ptr[state->cursor] == '|') + if (state->buffer.ptr[state->cursor] == '|') { - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + if (state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient } - if(state->buffer.ptr[state->cursor]=='\n') + if (state->buffer.ptr[state->cursor]=='\n') { ++(state->cursor); - state->inBody = 0; + state->inContent = 0; return PSYC_COMPLETE; // return packet finished } } @@ -121,6 +133,10 @@ start: } else // it is a glyph, so a variable name starts here { + /*************************************************** + * * * * * * * Routing Variable Start * * * * * * * + **************************************************/ + *modifier = *(state->buffer.ptr+state->cursor); if (state->buffer.length <= ++(state->cursor)) @@ -133,7 +149,7 @@ start: name->length = 1; } - } // endif inBody=0 + } // endif inContent=0 char method=0; /* each line of the header starts with a glyph. @@ -141,7 +157,7 @@ start: * the first char is a glyph. */ /* in the body, the same applies, only that the * method does not start with a glyph.*/ - if(1==state->inBody) + if(1==state->inContent) { if(!isGlyph(state->buffer.ptr[state->cursor])) { @@ -151,7 +167,7 @@ start: // that now also just |\n can follow. if(state->buffer.ptr[state->cursor] == '|') { - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient @@ -160,7 +176,7 @@ start: if(state->buffer.ptr[state->cursor]=='\n') { ++(state->cursor); - state->inBody = 0; + state->inContent = 0; return PSYC_COMPLETE; // return packet finished } } @@ -209,7 +225,7 @@ start: unsigned int i=0; while(1) { - if(state->buffer.length<= ++(state->cursor)) // incremented cursor inside lenght? + if(state->buffer.length<= ++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient @@ -259,18 +275,18 @@ start: else { value->ptr=state->buffer.ptr+state->cursor+1; - if (0 != state->length) // we know the length of the packet + if (0 != state->contentLength) // we know the length of the packet { // is the packet in the buffer? - if (value->ptr + state->length + 3 > state->buffer.ptr + state->buffer.length) + if (value->ptr + state->contentLength + 3 > state->buffer.ptr + state->buffer.length) { // no value->length = state->buffer.length - state->cursor; - *expectedBytes = state->length - value->length; + //*expectedBytes = state->contentLength - value->length; } else // yes, the packet is complete in the buffer. { value->length= state->buffer.length - state->cursor -3; - *expectedBytes = 0; + //*expectedBytes = 0; } } else // else search for the terminator @@ -279,7 +295,7 @@ start: while (1) { - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT ; // return insufficient @@ -290,7 +306,7 @@ start: if(1 == method && state->buffer.ptr[state->cursor] == '\n') { - if(state->buffer.length<=(state->cursor)+2) // incremented cursor inside lenght? + if(state->buffer.length<=(state->cursor)+2) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient @@ -301,7 +317,7 @@ start: { /* packet finishes here */ state->cursor+=3; - state->inBody = 0; + state->inContent = 0; return PSYC_COMPLETE; } @@ -311,11 +327,9 @@ start: } } } - else if(state->inBody == 1 && method==0 && state->buffer.ptr[state->cursor] == ' ') // oi, its a binary var! + else if(state->inContent == 1 && method==0 && state->buffer.ptr[state->cursor] == ' ') // oi, its a binary var! { // after SP the length follows. - unsigned int binLength= 0; - - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient @@ -323,9 +337,9 @@ start: while(isNumeric(state->buffer.ptr[state->cursor])) { - binLength = 10 * binLength + state->buffer.ptr[state->cursor] - '0'; + value->length = 10 * value->length + state->buffer.ptr[state->cursor] - '0'; - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient @@ -333,18 +347,35 @@ start: } // after the length a TAB follows if (state->buffer.ptr[state->cursor] != '\t') - return -8; + return PSYC_ERROR_EXPECTED_TAB; - // is the length still in this buffer? - if(state->buffer.length <= state->cursor+binLength+1 ) +binaryArg: + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { - state->cursor=startc; - return PSYC_INSUFFICIENT; + state->valueRemaining = value->length - state->cursor; + state->cursor=0; + + value->length = 0; + value->ptr = state->buffer.ptr; + + return PSYC_ENTITY_INCOMPLETE; } - value->ptr = state->buffer.ptr + state->cursor+1; - value->length=binLength; - state->cursor += binLength+1; + // is the length still in this buffer? + if(state->buffer.length <= state->cursor+value->length+1 ) + { + state->valueRemaining = value->length - state->cursor; + state->cursor=0; + + value->ptr = state->buffer.ptr + state->cursor; + value->length = state->buffer.length - state->cursor; + + return PSYC_ENTITY_INCOMPLETE; + } + + value->ptr = state->buffer.ptr + state->cursor; + state->cursor += value->length; + state->valueRemaining = 0; } else return -8; @@ -369,28 +400,28 @@ start: /* if a \n follows now, the an body is attached. * if not, a |\n must follow */ - if(state->buffer.length<=++(state->cursor)) // incremented cursor inside lenght? + if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient } - if(0 == state->inBody && state->buffer.ptr[state->cursor] == '\n') + if(0 == state->inContent && state->buffer.ptr[state->cursor] == '\n') { state->cursor+=1; - state->inBody = 1; + state->inContent = 1; return PSYC_ROUTING; // return header finished } if(state->buffer.ptr[state->cursor] != '|') // no pipe, then only line complete, not the packet. { - if (state->inBody == 0) + if (state->inContent == 0) 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 length? { state->cursor=startc; // set to start value return PSYC_INSUFFICIENT; // return insufficient @@ -399,7 +430,7 @@ start: return -4; state->cursor+=1; - state->inBody = 0; + state->inContent = 0; return PSYC_COMPLETE; // packet is complete } diff --git a/src/tests/parser/testParser.c b/src/tests/parser/testParser.c index 773f831..e224783 100644 --- a/src/tests/parser/testParser.c +++ b/src/tests/parser/testParser.c @@ -23,10 +23,10 @@ int main(int argc, char** argv) int ret; PSYC_Array name, value; - PSYC_nextBuffer(&state, PSYC_CreateArray(buffer, index)); + PSYC_nextBuffer(&state, PSYC_createArray(buffer, index)); // try parsing that now - while(ret=PSYC_parse(&state, &name, &value, &modifier, &expectedBytes)) + while(ret=PSYC_parse(&state, &name, &value, &modifier)) { switch (ret) {