1
0
Fork 0
mirror of git://git.psyc.eu/libpsyc synced 2024-08-15 03:19:02 +00:00
This commit is contained in:
psyc://psyced.org/~lynX 2011-04-18 14:49:03 +02:00
commit d6e439625f
5 changed files with 111 additions and 69 deletions

5
.gitignore vendored
View file

@ -1,11 +1,11 @@
CVS
.config .config
~$* ~$*
.DS_Store .DS_Store
.metadata .metadata
.actionScriptProperties
.#* .#*
*~ *~
\#*
*.a
*.o *.o
*.swf *.swf
*.swp *.swp
@ -19,3 +19,4 @@ CVS
src/match src/match
src/tests/parser/testParser src/tests/parser/testParser
src/tests/testMatch src/tests/testMatch
src/tests/testParser

View file

@ -9,12 +9,15 @@ enum PSYC_Flags
enum PSYC_ReturnCodes enum PSYC_ReturnCodes
{ {
PSYC_METHOD = 1, PSYC_ERROR_EXPECTED_TAB = -8,
PSYC_BODY = 1,
PSYC_BODY_INCOMPLETE,
PSYC_INSUFFICIENT, PSYC_INSUFFICIENT,
PSYC_ROUTING, PSYC_ROUTING,
PSYC_ENTITY, PSYC_ENTITY,
PSYC_ENTITY_INCOMPLETE,
PSYC_HEADER_COMPLETE,
PSYC_COMPLETE, PSYC_COMPLETE,
PSYC_HEADER_COMPLETE,
}; };
@ -24,14 +27,16 @@ typedef struct
const uint8_t * ptr; const uint8_t * ptr;
} PSYC_Array; } PSYC_Array;
typedef struct typedef struct
{ {
unsigned int cursor; // current position in buffer unsigned int cursor; // current position in buffer
PSYC_Array buffer; PSYC_Array buffer;
uint8_t flags; uint8_t flags;
char inBody; unsigned int contentParsed; //
unsigned int length; char inContent;
unsigned int valueRemaining;
unsigned int contentLength; unsigned int contentLength;
} PSYC_State; } PSYC_State;
@ -42,22 +47,26 @@ typedef struct
* @param length length of that buffer * @param length length of that buffer
* *
* @returns an instance of the PSYC_Array struct */ * @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}; PSYC_Array arr = {length, memory};
return arr; return arr;
} }
/* @brief initiates the state struct with flags /* @brief initiates the state struct with flags
* *
* @param state pointer to the state struct that should be initiated * @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 ) inline void PSYC_initState2 (PSYC_State* state, uint8_t flags )
{ {
memset(state, 0, sizeof(PSYC_State)); memset(state, 0, sizeof(PSYC_State));
state->flags = flags; 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) inline void PSYC_initState (PSYC_State* state)
{ {
memset(state, 0, sizeof(PSYC_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) inline void PSYC_nextBuffer (PSYC_State* state, PSYC_Array newBuf)
{ {
state->buffer = 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 #endif
int PSYC_parse(PSYC_State* state, int PSYC_parse(PSYC_State* state,
PSYC_Array* name, PSYC_Array* value, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value);
uint8_t* modifier, unsigned long *expectedBytes);

3
src/.gitignore vendored
View file

@ -1,3 +0,0 @@
*.o
*.a
tests/testParser

View file

@ -47,10 +47,13 @@ inline char isAlphaNumeric(uint8_t c)
/** @brief generalized linebased parser */ /** @brief generalized linebased parser */
inline int PSYC_parse( inline int PSYC_parse(
PSYC_State* state, PSYC_State* state,
PSYC_Array* name, PSYC_Array* value, uint8_t* modifier, PSYC_Array* name, PSYC_Array* value)
uint8_t* modifier, unsigned long* expectedBytes)
{ {
start: start:
if (state->valueRemaining != 0)
goto binaryArg;
/* 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 PSYC_INSUFFICIENT; // return insufficient data. return PSYC_INSUFFICIENT; // return insufficient data.
@ -58,16 +61,19 @@ start:
// 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;
/******************************************
* * * * * * * Inspect Header * * * * * * *
*******************************************/
/* each line of the header starts with a glyph. /* each line of the header starts with a glyph.
* iE :_name, -_name +_name etc, so just test if * iE :_name, -_name +_name etc, so just test if
* the first char is a glyph. */ * 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? 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(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 state->cursor=startc; // set to start value
return PSYC_INSUFFICIENT; // return insufficient return PSYC_INSUFFICIENT; // return insufficient
@ -75,45 +81,51 @@ start:
while(isNumeric(state->buffer.ptr[state->cursor])); 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 state->cursor=startc; // set to start value
return PSYC_INSUFFICIENT; // return insufficient 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.length<=++(state->cursor)) // incremented cursor inside length?
if (state->buffer.ptr[state->cursor] != '\n') {
{ state->cursor=startc; // set to start value
return -10; return PSYC_INSUFFICIENT; // return insufficient
}
} }
// 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]))
{ {
state->inBody = 1; state->inContent = 1;
if (state->flags & PSYC_HEADER_ONLY) if (state->flags & PSYC_HEADER_ONLY)
return PSYC_HEADER_COMPLETE; // return header finished return PSYC_HEADER_COMPLETE; // return header finished
else else
goto start; 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 state->cursor=startc; // set to start value
return PSYC_INSUFFICIENT; // return insufficient return PSYC_INSUFFICIENT; // return insufficient
} }
if(state->buffer.ptr[state->cursor]=='\n') if (state->buffer.ptr[state->cursor]=='\n')
{ {
++(state->cursor); ++(state->cursor);
state->inBody = 0; state->inContent = 0;
return PSYC_COMPLETE; // return packet finished return PSYC_COMPLETE; // return packet finished
} }
} }
@ -121,6 +133,10 @@ start:
} }
else // it is a glyph, so a variable name starts here else // it is a glyph, so a variable name starts here
{ {
/***************************************************
* * * * * * * Routing Variable Start * * * * * * *
**************************************************/
*modifier = *(state->buffer.ptr+state->cursor); *modifier = *(state->buffer.ptr+state->cursor);
if (state->buffer.length <= ++(state->cursor)) if (state->buffer.length <= ++(state->cursor))
@ -133,7 +149,7 @@ start:
name->length = 1; name->length = 1;
} }
} // endif inBody=0 } // endif inContent=0
char method=0; char method=0;
/* each line of the header starts with a glyph. /* each line of the header starts with a glyph.
@ -141,7 +157,7 @@ start:
* the first char is a glyph. */ * the first char is a glyph. */
/* in the body, the same applies, only that the /* in the body, the same applies, only that the
* method does not start with a glyph.*/ * method does not start with a glyph.*/
if(1==state->inBody) if(1==state->inContent)
{ {
if(!isGlyph(state->buffer.ptr[state->cursor])) if(!isGlyph(state->buffer.ptr[state->cursor]))
{ {
@ -151,7 +167,7 @@ start:
// that now also just |\n can follow. // that now also just |\n can follow.
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 state->cursor=startc; // set to start value
return PSYC_INSUFFICIENT; // return insufficient return PSYC_INSUFFICIENT; // return insufficient
@ -160,7 +176,7 @@ start:
if(state->buffer.ptr[state->cursor]=='\n') if(state->buffer.ptr[state->cursor]=='\n')
{ {
++(state->cursor); ++(state->cursor);
state->inBody = 0; state->inContent = 0;
return PSYC_COMPLETE; // return packet finished return PSYC_COMPLETE; // return packet finished
} }
} }
@ -209,7 +225,7 @@ start:
unsigned int i=0; unsigned int i=0;
while(1) 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 state->cursor=startc; // set to start value
return PSYC_INSUFFICIENT; // return insufficient return PSYC_INSUFFICIENT; // return insufficient
@ -259,18 +275,18 @@ start:
else else
{ {
value->ptr=state->buffer.ptr+state->cursor+1; 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? // 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 { // no
value->length = state->buffer.length - state->cursor; 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. else // yes, the packet is complete in the buffer.
{ {
value->length= state->buffer.length - state->cursor -3; value->length= state->buffer.length - state->cursor -3;
*expectedBytes = 0; //*expectedBytes = 0;
} }
} }
else // else search for the terminator else // else search for the terminator
@ -279,7 +295,7 @@ start:
while (1) 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 state->cursor=startc; // set to start value
return PSYC_INSUFFICIENT ; // return insufficient return PSYC_INSUFFICIENT ; // return insufficient
@ -290,7 +306,7 @@ start:
if(1 == method && state->buffer.ptr[state->cursor] == '\n') 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 state->cursor=startc; // set to start value
return PSYC_INSUFFICIENT; // return insufficient return PSYC_INSUFFICIENT; // return insufficient
@ -301,7 +317,7 @@ start:
{ {
/* packet finishes here */ /* packet finishes here */
state->cursor+=3; state->cursor+=3;
state->inBody = 0; state->inContent = 0;
return PSYC_COMPLETE; 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. { // after SP the length follows.
unsigned int binLength= 0; if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length?
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 PSYC_INSUFFICIENT; // return insufficient return PSYC_INSUFFICIENT; // return insufficient
@ -323,9 +337,9 @@ start:
while(isNumeric(state->buffer.ptr[state->cursor])) 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 state->cursor=startc; // set to start value
return PSYC_INSUFFICIENT; // return insufficient return PSYC_INSUFFICIENT; // return insufficient
@ -333,18 +347,35 @@ start:
} }
// 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 -8; return PSYC_ERROR_EXPECTED_TAB;
// is the length still in this buffer? binaryArg:
if(state->buffer.length <= state->cursor+binLength+1 ) if(state->buffer.length<=++(state->cursor)) // incremented cursor inside length?
{ {
state->cursor=startc; state->valueRemaining = value->length - state->cursor;
return PSYC_INSUFFICIENT; state->cursor=0;
value->length = 0;
value->ptr = state->buffer.ptr;
return PSYC_ENTITY_INCOMPLETE;
} }
value->ptr = state->buffer.ptr + state->cursor+1; // is the length still in this buffer?
value->length=binLength; if(state->buffer.length <= state->cursor+value->length+1 )
state->cursor += binLength+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 else
return -8; return -8;
@ -369,28 +400,28 @@ start:
/* if a \n follows now, the an body is attached. /* if a \n follows now, the an body is attached.
* if not, a |\n must follow */ * 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 state->cursor=startc; // set to start value
return PSYC_INSUFFICIENT; // return insufficient 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->cursor+=1;
state->inBody = 1; state->inContent = 1;
return PSYC_ROUTING; // return header finished return PSYC_ROUTING; // return header finished
} }
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.
{ {
if (state->inBody == 0) if (state->inContent == 0)
return PSYC_ROUTING; return PSYC_ROUTING;
else else
return PSYC_ENTITY; 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 state->cursor=startc; // set to start value
return PSYC_INSUFFICIENT; // return insufficient return PSYC_INSUFFICIENT; // return insufficient
@ -399,7 +430,7 @@ start:
return -4; return -4;
state->cursor+=1; state->cursor+=1;
state->inBody = 0; state->inContent = 0;
return PSYC_COMPLETE; // packet is complete return PSYC_COMPLETE; // packet is complete
} }

View file

@ -23,10 +23,10 @@ int main(int argc, char** argv)
int ret; int ret;
PSYC_Array name, value; PSYC_Array name, value;
PSYC_nextBuffer(&state, PSYC_CreateArray(buffer, index)); PSYC_nextBuffer(&state, PSYC_createArray(buffer, index));
// try parsing that now // try parsing that now
while(ret=PSYC_parse(&state, &name, &value, &modifier, &expectedBytes)) while(ret=PSYC_parse(&state, &name, &value, &modifier))
{ {
switch (ret) switch (ret)
{ {