More optimizations for msg parser etc.
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@77 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
parent
3818c93ec1
commit
cec5f4ae2c
|
@ -41,7 +41,7 @@ RSC=rc.exe
|
|||
# PROP Intermediate_Dir "./output/pjlib-util-i386-win32-vc6-release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /Ob2 /I "../include" /I "../../pjlib/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /Oy /Ob2 /I "../include" /I "../../pjlib/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
|
|
|
@ -197,7 +197,7 @@ typedef struct pj_scanner
|
|||
char *end; /**< End of input buffer. */
|
||||
char *curptr; /**< Current pointer. */
|
||||
int line; /**< Current line. */
|
||||
int col; /**< Current column. */
|
||||
char *start_line; /**< Where current line starts. */
|
||||
int skip_ws; /**< Skip whitespace flag. */
|
||||
pj_syn_err_func_ptr callback; /**< Syntax error callback. */
|
||||
} pj_scanner;
|
||||
|
@ -211,7 +211,7 @@ typedef struct pj_scan_state
|
|||
{
|
||||
char *curptr; /**< Current scanner's pointer. */
|
||||
int line; /**< Current line. */
|
||||
int col; /**< Current column. */
|
||||
char *start_line; /**< Start of current line. */
|
||||
} pj_scan_state;
|
||||
|
||||
|
||||
|
@ -325,7 +325,8 @@ PJ_DECL(void) pj_scan_get( pj_scanner *scanner,
|
|||
|
||||
/**
|
||||
* Get characters between quotes. If current input doesn't match begin_quote,
|
||||
* syntax error will be thrown.
|
||||
* syntax error will be thrown. Note that the resulting string will contain
|
||||
* the enclosing quote.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param begin_quote The character to begin the quote.
|
||||
|
@ -357,15 +358,6 @@ PJ_DECL(void) pj_scan_get_n( pj_scanner *scanner,
|
|||
PJ_DECL(int) pj_scan_get_char( pj_scanner *scanner );
|
||||
|
||||
|
||||
/**
|
||||
* Get a newline from the scanner. A newline is defined as '\\n', or '\\r', or
|
||||
* "\\r\\n". If current input is not newline, syntax error will be thrown.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_get_newline( pj_scanner *scanner );
|
||||
|
||||
|
||||
/**
|
||||
* Get characters from the scanner and move the scanner position until the
|
||||
* current character matches the spec.
|
||||
|
@ -438,6 +430,34 @@ PJ_DECL(int) pj_scan_strcmp( pj_scanner *scanner, const char *s, int len);
|
|||
*/
|
||||
PJ_DECL(int) pj_scan_stricmp( pj_scanner *scanner, const char *s, int len);
|
||||
|
||||
/**
|
||||
* Perform case insensitive string comparison of string in current position,
|
||||
* knowing that the string to compare only consists of alphanumeric
|
||||
* characters.
|
||||
*
|
||||
* Note that unlike #pj_scan_stricmp, this function can only return zero or
|
||||
* -1.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
* @param s The string to compare with.
|
||||
* @param len Length of the string to compare with.
|
||||
*
|
||||
* @return zero if equal or -1.
|
||||
*
|
||||
* @see strnicmp_alnum, pj_stricmp_alnum
|
||||
*/
|
||||
PJ_DECL(int) pj_scan_stricmp_alnum( pj_scanner *scanner, const char *s,
|
||||
int len);
|
||||
|
||||
|
||||
/**
|
||||
* Get a newline from the scanner. A newline is defined as '\\n', or '\\r', or
|
||||
* "\\r\\n". If current input is not newline, syntax error will be thrown.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_get_newline( pj_scanner *scanner );
|
||||
|
||||
|
||||
/**
|
||||
* Manually skip whitespaces according to flag that was specified when
|
||||
|
@ -448,6 +468,13 @@ PJ_DECL(int) pj_scan_stricmp( pj_scanner *scanner, const char *s, int len);
|
|||
PJ_DECL(void) pj_scan_skip_whitespace( pj_scanner *scanner );
|
||||
|
||||
|
||||
/**
|
||||
* Skip current line.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
*/
|
||||
PJ_DECL(void) pj_scan_skip_line( pj_scanner *scanner );
|
||||
|
||||
/**
|
||||
* Save the full scanner state.
|
||||
*
|
||||
|
@ -468,6 +495,18 @@ PJ_DECL(void) pj_scan_save_state( pj_scanner *scanner, pj_scan_state *state);
|
|||
PJ_DECL(void) pj_scan_restore_state( pj_scanner *scanner,
|
||||
pj_scan_state *state);
|
||||
|
||||
/**
|
||||
* Get current column position.
|
||||
*
|
||||
* @param scanner The scanner.
|
||||
*
|
||||
* @return The column position.
|
||||
*/
|
||||
PJ_INLINE(int) pj_scan_get_col( pj_scanner *scanner )
|
||||
{
|
||||
return scanner->curptr - scanner->start_line;
|
||||
}
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
|
||||
#define PJ_SCAN_IS_SPACE(c) ((c)==' ' || (c)=='\t')
|
||||
#define PJ_SCAN_IS_NEWLINE(c) ((c)=='\r' || (c)=='\n')
|
||||
#define PJ_SCAN_CHECK_EOF(s) (s != end)
|
||||
#define PJ_SCAN_IS_PROBABLY_SPACE(c) ((c) <= 32)
|
||||
#define PJ_SCAN_CHECK_EOF(s) (*s)
|
||||
|
||||
|
||||
#if defined(PJ_SCANNER_USE_BITWISE) && PJ_SCANNER_USE_BITWISE != 0
|
||||
|
@ -107,14 +108,12 @@ PJ_DEF(void) pj_scan_init( pj_scanner *scanner, char *bufstart, int buflen,
|
|||
scanner->begin = scanner->curptr = bufstart;
|
||||
scanner->end = bufstart + buflen;
|
||||
scanner->line = 1;
|
||||
scanner->col = 1;
|
||||
scanner->start_line = scanner->begin;
|
||||
scanner->callback = callback;
|
||||
scanner->skip_ws = options;
|
||||
|
||||
if (scanner->skip_ws)
|
||||
pj_scan_skip_whitespace(scanner);
|
||||
|
||||
scanner->col = scanner->curptr - scanner->begin + 1;
|
||||
}
|
||||
|
||||
|
||||
|
@ -128,25 +127,21 @@ PJ_DEF(void) pj_scan_skip_whitespace( pj_scanner *scanner )
|
|||
{
|
||||
register char *s = scanner->curptr;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
while (PJ_SCAN_IS_SPACE(*s)) {
|
||||
++s;
|
||||
}
|
||||
|
||||
if ((scanner->skip_ws & PJ_SCAN_AUTOSKIP_NEWLINE) && PJ_SCAN_IS_NEWLINE(*s)) {
|
||||
if (PJ_SCAN_IS_NEWLINE(*s) && (scanner->skip_ws & PJ_SCAN_AUTOSKIP_NEWLINE)) {
|
||||
for (;;) {
|
||||
if (*s == '\r') {
|
||||
++s;
|
||||
if (*s == '\n') ++s;
|
||||
++scanner->line;
|
||||
scanner->col = 1;
|
||||
scanner->curptr = s;
|
||||
scanner->curptr = scanner->start_line = s;
|
||||
} else if (*s == '\n') {
|
||||
++s;
|
||||
++scanner->line;
|
||||
scanner->col = 1;
|
||||
scanner->curptr = s;
|
||||
scanner->curptr = scanner->start_line = s;
|
||||
} else if (PJ_SCAN_IS_SPACE(*s)) {
|
||||
do {
|
||||
++s;
|
||||
|
@ -159,7 +154,6 @@ PJ_DEF(void) pj_scan_skip_whitespace( pj_scanner *scanner )
|
|||
|
||||
if (PJ_SCAN_IS_NEWLINE(*s) && (scanner->skip_ws & PJ_SCAN_AUTOSKIP_WS_HEADER)==PJ_SCAN_AUTOSKIP_WS_HEADER) {
|
||||
/* Check for header continuation. */
|
||||
scanner->col += s - scanner->curptr;
|
||||
scanner->curptr = s;
|
||||
|
||||
if (*s == '\r') {
|
||||
|
@ -168,6 +162,8 @@ PJ_DEF(void) pj_scan_skip_whitespace( pj_scanner *scanner )
|
|||
if (*s == '\n') {
|
||||
++s;
|
||||
}
|
||||
scanner->start_line = s;
|
||||
|
||||
if (PJ_SCAN_IS_SPACE(*s)) {
|
||||
register char *t = s;
|
||||
do {
|
||||
|
@ -175,33 +171,43 @@ PJ_DEF(void) pj_scan_skip_whitespace( pj_scanner *scanner )
|
|||
} while (PJ_SCAN_IS_SPACE(*t));
|
||||
|
||||
++scanner->line;
|
||||
scanner->col = t-s;
|
||||
scanner->curptr = t;
|
||||
}
|
||||
} else {
|
||||
scanner->col += s - scanner->curptr;
|
||||
scanner->curptr = s;
|
||||
}
|
||||
}
|
||||
|
||||
PJ_DEF(void) pj_scan_skip_line( pj_scanner *scanner )
|
||||
{
|
||||
char *s = pj_native_strchr(scanner->curptr, '\n');
|
||||
if (!s) {
|
||||
scanner->curptr = scanner->end;
|
||||
} else {
|
||||
scanner->curptr = scanner->start_line = s+1;
|
||||
scanner->line++;
|
||||
if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
|
||||
pj_scan_skip_whitespace(scanner);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PJ_DEF(int) pj_scan_peek( pj_scanner *scanner,
|
||||
const pj_cis_t *spec, pj_str_t *out)
|
||||
{
|
||||
register char *s = scanner->curptr;
|
||||
register char *end = scanner->end;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
if (pj_scan_is_eof(scanner)) {
|
||||
if (s >= scanner->end) {
|
||||
pj_scan_syntax_err(scanner);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (PJ_SCAN_CHECK_EOF(s) && pj_cis_match(spec, *s))
|
||||
/* Don't need to check EOF with PJ_SCAN_CHECK_EOF(s) */
|
||||
while (pj_cis_match(spec, *s))
|
||||
++s;
|
||||
|
||||
pj_strset3(out, scanner->curptr, s);
|
||||
return s < scanner->end ? *s : 0;
|
||||
return *s;
|
||||
}
|
||||
|
||||
|
||||
|
@ -210,8 +216,6 @@ PJ_DEF(int) pj_scan_peek_n( pj_scanner *scanner,
|
|||
{
|
||||
char *endpos = scanner->curptr + len;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
if (endpos > scanner->end) {
|
||||
pj_scan_syntax_err(scanner);
|
||||
return -1;
|
||||
|
@ -227,11 +231,8 @@ PJ_DEF(int) pj_scan_peek_until( pj_scanner *scanner,
|
|||
pj_str_t *out)
|
||||
{
|
||||
register char *s = scanner->curptr;
|
||||
register char *end = scanner->end;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
if (pj_scan_is_eof(scanner)) {
|
||||
if (s >= scanner->end) {
|
||||
pj_scan_syntax_err(scanner);
|
||||
return -1;
|
||||
}
|
||||
|
@ -240,7 +241,7 @@ PJ_DEF(int) pj_scan_peek_until( pj_scanner *scanner,
|
|||
++s;
|
||||
|
||||
pj_strset3(out, scanner->curptr, s);
|
||||
return s!=scanner->end ? *s : 0;
|
||||
return *s;
|
||||
}
|
||||
|
||||
|
||||
|
@ -248,14 +249,11 @@ PJ_DEF(void) pj_scan_get( pj_scanner *scanner,
|
|||
const pj_cis_t *spec, pj_str_t *out)
|
||||
{
|
||||
register char *s = scanner->curptr;
|
||||
register char *end = scanner->end;
|
||||
char *start = s;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
pj_assert(pj_cis_match(spec,0)==0);
|
||||
|
||||
if (pj_scan_is_eof(scanner) || !pj_cis_match(spec, *s)) {
|
||||
/* EOF is detected implicitly */
|
||||
if (!pj_cis_match(spec, *s)) {
|
||||
pj_scan_syntax_err(scanner);
|
||||
return;
|
||||
}
|
||||
|
@ -270,10 +268,9 @@ PJ_DEF(void) pj_scan_get( pj_scanner *scanner,
|
|||
|
||||
pj_strset3(out, scanner->curptr, s);
|
||||
|
||||
scanner->col += (s - start);
|
||||
scanner->curptr = s;
|
||||
|
||||
if (scanner->skip_ws) {
|
||||
if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
|
||||
pj_scan_skip_whitespace(scanner);
|
||||
}
|
||||
}
|
||||
|
@ -284,10 +281,6 @@ PJ_DEF(void) pj_scan_get_quote( pj_scanner *scanner,
|
|||
pj_str_t *out)
|
||||
{
|
||||
register char *s = scanner->curptr;
|
||||
register char *end = scanner->end;
|
||||
char *start = s;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
/* Check and eat the begin_quote. */
|
||||
if (*s != begin_quote) {
|
||||
|
@ -300,9 +293,9 @@ PJ_DEF(void) pj_scan_get_quote( pj_scanner *scanner,
|
|||
*/
|
||||
do {
|
||||
/* loop until end_quote is found. */
|
||||
do {
|
||||
while (*s && *s != '\n' && *s != end_quote) {
|
||||
++s;
|
||||
} while (s != end && *s != '\n' && *s != end_quote);
|
||||
}
|
||||
|
||||
/* check that no backslash character precedes the end_quote. */
|
||||
if (*s == end_quote) {
|
||||
|
@ -318,8 +311,10 @@ PJ_DEF(void) pj_scan_get_quote( pj_scanner *scanner,
|
|||
}
|
||||
/* break from main loop if we have odd number of backslashes */
|
||||
if (((unsigned)(q-r) & 0x01) == 1) {
|
||||
++s;
|
||||
break;
|
||||
}
|
||||
++s;
|
||||
}
|
||||
} else {
|
||||
/* end_quote is not preceeded by backslash. break now. */
|
||||
|
@ -340,10 +335,9 @@ PJ_DEF(void) pj_scan_get_quote( pj_scanner *scanner,
|
|||
|
||||
pj_strset3(out, scanner->curptr, s);
|
||||
|
||||
scanner->col += (s - start);
|
||||
scanner->curptr = s;
|
||||
|
||||
if (scanner->skip_ws) {
|
||||
if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
|
||||
pj_scan_skip_whitespace(scanner);
|
||||
}
|
||||
}
|
||||
|
@ -351,23 +345,16 @@ PJ_DEF(void) pj_scan_get_quote( pj_scanner *scanner,
|
|||
PJ_DEF(void) pj_scan_get_n( pj_scanner *scanner,
|
||||
unsigned N, pj_str_t *out)
|
||||
{
|
||||
register char *s = scanner->curptr;
|
||||
char *start = scanner->curptr;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
if (scanner->curptr + N > scanner->end) {
|
||||
pj_scan_syntax_err(scanner);
|
||||
return;
|
||||
}
|
||||
|
||||
pj_strset(out, s, N);
|
||||
pj_strset(out, scanner->curptr, N);
|
||||
|
||||
s += N;
|
||||
scanner->col += (s - start);
|
||||
scanner->curptr = s;
|
||||
scanner->curptr += N;
|
||||
|
||||
if (scanner->skip_ws) {
|
||||
if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {
|
||||
pj_scan_skip_whitespace(scanner);
|
||||
}
|
||||
}
|
||||
|
@ -375,20 +362,16 @@ PJ_DEF(void) pj_scan_get_n( pj_scanner *scanner,
|
|||
|
||||
PJ_DEF(int) pj_scan_get_char( pj_scanner *scanner )
|
||||
{
|
||||
char *start = scanner->curptr;
|
||||
int chr = *start;
|
||||
int chr = *scanner->curptr;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
if (pj_scan_is_eof(scanner)) {
|
||||
if (!chr) {
|
||||
pj_scan_syntax_err(scanner);
|
||||
return 0;
|
||||
}
|
||||
|
||||
++scanner->curptr;
|
||||
scanner->col += (scanner->curptr - start);
|
||||
|
||||
if (scanner->skip_ws) {
|
||||
if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {
|
||||
pj_scan_skip_whitespace(scanner);
|
||||
}
|
||||
return chr;
|
||||
|
@ -397,8 +380,6 @@ PJ_DEF(int) pj_scan_get_char( pj_scanner *scanner )
|
|||
|
||||
PJ_DEF(void) pj_scan_get_newline( pj_scanner *scanner )
|
||||
{
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
if (!PJ_SCAN_IS_NEWLINE(*scanner->curptr)) {
|
||||
pj_scan_syntax_err(scanner);
|
||||
return;
|
||||
|
@ -412,9 +393,9 @@ PJ_DEF(void) pj_scan_get_newline( pj_scanner *scanner )
|
|||
}
|
||||
|
||||
++scanner->line;
|
||||
scanner->col = 1;
|
||||
scanner->start_line = scanner->curptr;
|
||||
|
||||
if (scanner->skip_ws) {
|
||||
if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && scanner->skip_ws) {
|
||||
pj_scan_skip_whitespace(scanner);
|
||||
}
|
||||
}
|
||||
|
@ -424,12 +405,8 @@ PJ_DEF(void) pj_scan_get_until( pj_scanner *scanner,
|
|||
const pj_cis_t *spec, pj_str_t *out)
|
||||
{
|
||||
register char *s = scanner->curptr;
|
||||
register char *end = scanner->end;
|
||||
char *start = s;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
if (pj_scan_is_eof(scanner)) {
|
||||
if (s >= scanner->end) {
|
||||
pj_scan_syntax_err(scanner);
|
||||
return;
|
||||
}
|
||||
|
@ -440,10 +417,9 @@ PJ_DEF(void) pj_scan_get_until( pj_scanner *scanner,
|
|||
|
||||
pj_strset3(out, scanner->curptr, s);
|
||||
|
||||
scanner->col += (s - start);
|
||||
scanner->curptr = s;
|
||||
|
||||
if (scanner->skip_ws) {
|
||||
if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
|
||||
pj_scan_skip_whitespace(scanner);
|
||||
}
|
||||
}
|
||||
|
@ -453,12 +429,8 @@ PJ_DEF(void) pj_scan_get_until_ch( pj_scanner *scanner,
|
|||
int until_char, pj_str_t *out)
|
||||
{
|
||||
register char *s = scanner->curptr;
|
||||
register char *end = scanner->end;
|
||||
char *start = s;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
if (pj_scan_is_eof(scanner)) {
|
||||
if (s >= scanner->end) {
|
||||
pj_scan_syntax_err(scanner);
|
||||
return;
|
||||
}
|
||||
|
@ -469,10 +441,9 @@ PJ_DEF(void) pj_scan_get_until_ch( pj_scanner *scanner,
|
|||
|
||||
pj_strset3(out, scanner->curptr, s);
|
||||
|
||||
scanner->col += (s - start);
|
||||
scanner->curptr = s;
|
||||
|
||||
if (scanner->skip_ws) {
|
||||
if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
|
||||
pj_scan_skip_whitespace(scanner);
|
||||
}
|
||||
}
|
||||
|
@ -482,26 +453,23 @@ PJ_DEF(void) pj_scan_get_until_chr( pj_scanner *scanner,
|
|||
const char *until_spec, pj_str_t *out)
|
||||
{
|
||||
register char *s = scanner->curptr;
|
||||
register char *end = scanner->end;
|
||||
char *start = scanner->curptr;
|
||||
int speclen;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
if (pj_scan_is_eof(scanner)) {
|
||||
if (s >= scanner->end) {
|
||||
pj_scan_syntax_err(scanner);
|
||||
return;
|
||||
}
|
||||
|
||||
while (PJ_SCAN_CHECK_EOF(s) && !strchr(until_spec, *s)) {
|
||||
speclen = strlen(until_spec);
|
||||
while (PJ_SCAN_CHECK_EOF(s) && !memchr(until_spec, *s, speclen)) {
|
||||
++s;
|
||||
}
|
||||
|
||||
pj_strset3(out, scanner->curptr, s);
|
||||
|
||||
scanner->col += (s - start);
|
||||
scanner->curptr = s;
|
||||
|
||||
if (scanner->skip_ws) {
|
||||
if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
|
||||
pj_scan_skip_whitespace(scanner);
|
||||
}
|
||||
}
|
||||
|
@ -511,17 +479,14 @@ PJ_DEF(void) pj_scan_advance_n( pj_scanner *scanner,
|
|||
{
|
||||
char *start = scanner->curptr;
|
||||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
if (scanner->curptr + N > scanner->end) {
|
||||
pj_scan_syntax_err(scanner);
|
||||
return;
|
||||
}
|
||||
|
||||
scanner->curptr += N;
|
||||
scanner->col += (scanner->curptr - start);
|
||||
|
||||
if (skip_ws) {
|
||||
if (PJ_SCAN_IS_PROBABLY_SPACE(*scanner->curptr) && skip_ws) {
|
||||
pj_scan_skip_whitespace(scanner);
|
||||
}
|
||||
}
|
||||
|
@ -546,25 +511,30 @@ PJ_DEF(int) pj_scan_stricmp( pj_scanner *scanner, const char *s, int len)
|
|||
return strnicmp(scanner->curptr, s, len);
|
||||
}
|
||||
|
||||
PJ_DEF(int) pj_scan_stricmp_alnum( pj_scanner *scanner, const char *s,
|
||||
int len)
|
||||
{
|
||||
if (scanner->curptr + len > scanner->end) {
|
||||
pj_scan_syntax_err(scanner);
|
||||
return -1;
|
||||
}
|
||||
return strnicmp_alnum(scanner->curptr, s, len);
|
||||
}
|
||||
|
||||
PJ_DEF(void) pj_scan_save_state( pj_scanner *scanner, pj_scan_state *state)
|
||||
{
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
state->curptr = scanner->curptr;
|
||||
state->line = scanner->line;
|
||||
state->col = scanner->col;
|
||||
state->start_line = scanner->start_line;
|
||||
}
|
||||
|
||||
|
||||
PJ_DEF(void) pj_scan_restore_state( pj_scanner *scanner,
|
||||
pj_scan_state *state)
|
||||
{
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
scanner->curptr = state->curptr;
|
||||
scanner->line = state->line;
|
||||
scanner->col = state->col;
|
||||
scanner->start_line = state->start_line;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -173,7 +173,7 @@ PJ_DEF(pj_xml_node*) pj_xml_parse( pj_pool_t *pool, char *msg, pj_size_t len)
|
|||
}
|
||||
PJ_CATCH_ANY {
|
||||
PJ_LOG(4,(THIS_FILE, "Syntax error parsing XML in line %d column %d",
|
||||
scanner.line, scanner.col));
|
||||
scanner.line, pj_scan_get_col(&scanner)));
|
||||
}
|
||||
PJ_END;
|
||||
pj_scan_fini( &scanner );
|
||||
|
|
|
@ -342,11 +342,29 @@ PJ_IDECL(int) pj_stricmp(const pj_str_t *str1, const pj_str_t *str2);
|
|||
/**
|
||||
* Perform lowercase comparison to the strings which consists of only
|
||||
* alnum characters. More over, it will only return non-zero if both
|
||||
* strings are not equal, and is not able to detect which string is
|
||||
* 'less'.
|
||||
* strings are not equal, not the usual negative or positive value.
|
||||
*
|
||||
* If non-alnum inputs are given, then the function may mistakenly
|
||||
* treat two strings as equal while they're not.
|
||||
* treat two strings as equal.
|
||||
*
|
||||
* @param str1 The string to compare.
|
||||
* @param str2 The string to compare.
|
||||
* @param len The length to compare.
|
||||
*
|
||||
* @return
|
||||
* - 0 if str1 is equal to str2
|
||||
* - (-1) if not equal.
|
||||
*/
|
||||
PJ_IDECL(int) strnicmp_alnum(const char *str1, const char *str2,
|
||||
int len);
|
||||
|
||||
/**
|
||||
* Perform lowercase comparison to the strings which consists of only
|
||||
* alnum characters. More over, it will only return non-zero if both
|
||||
* strings are not equal, not the usual negative or positive value.
|
||||
*
|
||||
* If non-alnum inputs are given, then the function may mistakenly
|
||||
* treat two strings as equal.
|
||||
*
|
||||
* @param str1 The string to compare.
|
||||
* @param str2 The string to compare.
|
||||
|
|
|
@ -169,6 +169,39 @@ PJ_IDEF(int) pj_stricmp( const pj_str_t *str1, const pj_str_t *str2)
|
|||
}
|
||||
}
|
||||
|
||||
PJ_IDEF(int) strnicmp_alnum( const char *str1, const char *str2,
|
||||
int len)
|
||||
{
|
||||
if (len==0)
|
||||
return 0;
|
||||
else {
|
||||
register const pj_uint32_t *p1 = (pj_uint32_t*)str1,
|
||||
*p2 = (pj_uint32_t*)str2;
|
||||
while (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F))
|
||||
++p1, ++p2, len-=4;
|
||||
|
||||
if (len > 3)
|
||||
return -1;
|
||||
#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
|
||||
else if (len==3)
|
||||
return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1;
|
||||
else if (len==2)
|
||||
return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1;
|
||||
else if (len==1)
|
||||
return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1;
|
||||
#else
|
||||
else if (len==3)
|
||||
return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1;
|
||||
else if (len==2)
|
||||
return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1;
|
||||
else if (len==1)
|
||||
return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1;
|
||||
#endif
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PJ_IDEF(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2)
|
||||
{
|
||||
register int len = str1->slen;
|
||||
|
@ -180,25 +213,25 @@ PJ_IDEF(int) pj_stricmp_alnum(const pj_str_t *str1, const pj_str_t *str2)
|
|||
} else {
|
||||
register const pj_uint32_t *p1 = (pj_uint32_t*)str1->ptr,
|
||||
*p2 = (pj_uint32_t*)str2->ptr;
|
||||
while (len > 3 && (*p1 & 0x1F1F1F1F)==(*p2 & 0x1F1F1F1F))
|
||||
while (len > 3 && (*p1 & 0x5F5F5F5F)==(*p2 & 0x5F5F5F5F))
|
||||
++p1, ++p2, len-=4;
|
||||
|
||||
if (len > 3)
|
||||
return -1;
|
||||
#if defined(PJ_IS_LITTLE_ENDIAN) && PJ_IS_LITTLE_ENDIAN!=0
|
||||
else if (len==3)
|
||||
return ((*p1 & 0x001F1F1F)==(*p2 & 0x001F1F1F)) ? 0 : -1;
|
||||
return ((*p1 & 0x005F5F5F)==(*p2 & 0x005F5F5F)) ? 0 : -1;
|
||||
else if (len==2)
|
||||
return ((*p1 & 0x00001F1F)==(*p2 & 0x00001F1F)) ? 0 : -1;
|
||||
return ((*p1 & 0x00005F5F)==(*p2 & 0x00005F5F)) ? 0 : -1;
|
||||
else if (len==1)
|
||||
return ((*p1 & 0x0000001F)==(*p2 & 0x0000001F)) ? 0 : -1;
|
||||
return ((*p1 & 0x0000005F)==(*p2 & 0x0000005F)) ? 0 : -1;
|
||||
#else
|
||||
else if (len==3)
|
||||
return ((*p1 & 0x1F1F1F00)==(*p2 & 0x1F1F1F00)) ? 0 : -1;
|
||||
return ((*p1 & 0x5F5F5F00)==(*p2 & 0x5F5F5F00)) ? 0 : -1;
|
||||
else if (len==2)
|
||||
return ((*p1 & 0x1F1F0000)==(*p2 & 0x1F1F0000)) ? 0 : -1;
|
||||
return ((*p1 & 0x5F5F0000)==(*p2 & 0x5F5F0000)) ? 0 : -1;
|
||||
else if (len==1)
|
||||
return ((*p1 & 0x1F000000)==(*p2 & 0x1F000000)) ? 0 : -1;
|
||||
return ((*p1 & 0x5F000000)==(*p2 & 0x5F000000)) ? 0 : -1;
|
||||
#endif
|
||||
else
|
||||
return 0;
|
||||
|
|
|
@ -103,6 +103,7 @@ static int stricmp_test(void)
|
|||
len=1;
|
||||
STRTEST( 0, "a",buf+0,-510);
|
||||
STRTEST( 0, "a",buf+1,-512);
|
||||
STRTEST( -1, "0", "P", -514);
|
||||
|
||||
/* equal, length=2
|
||||
* use buffer to simulate non-aligned string.
|
||||
|
|
|
@ -41,7 +41,7 @@ RSC=rc.exe
|
|||
# PROP Intermediate_Dir ".\output\pjsip-core-i386-win32-vc6-release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
|
||||
# ADD CPP /nologo /MD /W4 /Zi /O2 /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
|
||||
# ADD CPP /nologo /MD /W4 /Zi /O2 /Oy /I "../include" /I "../../pjlib/include" /I "../../pjlib-util/include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /D PJ_WIN32=1 /D PJ_M_I386=1 /FR /FD /c
|
||||
# SUBTRACT CPP /YX
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
|
|
|
@ -19,53 +19,29 @@
|
|||
#ifndef __PJSIP_PRINT_H__
|
||||
#define __PJSIP_PRINT_H__
|
||||
|
||||
/* Minimum space left in the buffer */
|
||||
#define MIN_SPACE 10
|
||||
|
||||
#define copy_advance_check(buf,str) \
|
||||
do { \
|
||||
if ((str).slen+MIN_SPACE >= (endbuf-buf)) return -1; \
|
||||
if ((str).slen >= (endbuf-buf)) return -1; \
|
||||
pj_memcpy(buf, (str).ptr, (str).slen); \
|
||||
buf += (str).slen; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
static char *imp_copy_advance_pair(char *buf, char *endbuf, const char *str1, int len1, const pj_str_t *str2)
|
||||
{
|
||||
if (str2->slen) {
|
||||
int printed = len1+str2->slen;
|
||||
if (printed+MIN_SPACE >= (endbuf-buf)) return NULL;
|
||||
pj_memcpy(buf,str1,len1);
|
||||
pj_memcpy(buf+len1, str2->ptr, str2->slen);
|
||||
return buf + printed;
|
||||
} else
|
||||
return buf;
|
||||
}
|
||||
*/
|
||||
|
||||
#define copy_advance_pair_check(buf,str1,len1,str2) \
|
||||
do { \
|
||||
if (str2.slen) { \
|
||||
printed = len1+str2.slen; \
|
||||
if (printed+MIN_SPACE >= (endbuf-buf)) return -1; \
|
||||
if (printed >= (endbuf-buf)) return -1; \
|
||||
pj_memcpy(buf,str1,len1); \
|
||||
pj_memcpy(buf+len1, str2.ptr, str2.slen); \
|
||||
buf += printed; \
|
||||
} \
|
||||
} while (0)
|
||||
/*
|
||||
#define copy_advance_pair(buf,str1,len1,str2) \
|
||||
do { \
|
||||
buf = imp_copy_advance_pair(buf, endbuf, str1, len1, &str2); \
|
||||
if (buf == NULL) return -1; \
|
||||
} while (0)
|
||||
*/
|
||||
|
||||
#define copy_advance_pair_quote_check(buf,str1,len1,str2,quotebegin,quoteend) \
|
||||
do { \
|
||||
if (str2.slen) { \
|
||||
printed = len1+str2.slen+2; \
|
||||
if (printed+MIN_SPACE >= (endbuf-buf)) return -1; \
|
||||
if (printed >= (endbuf-buf)) return -1; \
|
||||
pj_memcpy(buf,str1,len1); \
|
||||
*(buf+len1)=quotebegin; \
|
||||
pj_memcpy(buf+len1+1, str2.ptr, str2.slen); \
|
||||
|
@ -77,14 +53,11 @@ static char *imp_copy_advance_pair(char *buf, char *endbuf, const char *str1, in
|
|||
#define copy_advance_pair_escape(buf,str1,len1,str2,unres) \
|
||||
do { \
|
||||
if (str2.slen) { \
|
||||
pj_ssize_t esc_len; \
|
||||
if (len1+str2.slen+MIN_SPACE >= (endbuf-buf)) return -1; \
|
||||
if (len1+str2.slen >= (endbuf-buf)) return -1; \
|
||||
pj_memcpy(buf,str1,len1); \
|
||||
buf += len1; \
|
||||
esc_len=pj_strncpy2_escape(buf, &str2, (endbuf-buf), &unres); \
|
||||
if (esc_len < 0) return -1; \
|
||||
buf += esc_len; \
|
||||
if (endbuf-buf < MIN_SPACE) return -1; \
|
||||
printed=pj_strncpy2_escape(buf,&str2,(endbuf-buf-len1),&unres);\
|
||||
if (printed < 0) return -1; \
|
||||
buf += (printed+len1); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
@ -97,11 +70,10 @@ static char *imp_copy_advance_pair(char *buf, char *endbuf, const char *str1, in
|
|||
|
||||
#define copy_advance_escape(buf,str,unres) \
|
||||
do { \
|
||||
pj_ssize_t len = \
|
||||
printed = \
|
||||
pj_strncpy2_escape(buf, &(str), (endbuf-buf), &(unres)); \
|
||||
if (len < 0) return -1; \
|
||||
buf += len; \
|
||||
if (endbuf-buf < MIN_SPACE) return -1; \
|
||||
if (printed < 0) return -1; \
|
||||
buf += printed; \
|
||||
} while (0)
|
||||
|
||||
#define copy_advance_pair_no_check(buf,str1,len1,str2) \
|
||||
|
|
|
@ -307,8 +307,10 @@ extern pj_cis_t
|
|||
pjsip_PROBE_USER_HOST_SPEC, /**< Hostname characters. */
|
||||
pjsip_PASSWD_SPEC, /**< Password. */
|
||||
pjsip_USER_SPEC, /**< User */
|
||||
pjsip_NEWLINE_OR_EOF_SPEC, /**< For eating up header.*/
|
||||
pjsip_DISPLAY_SCAN_SPEC; /**< Used when searching for display name. */
|
||||
pjsip_NOT_NEWLINE, /**< For eating up header, basicly any chars
|
||||
except newlines or zero. */
|
||||
pjsip_NOT_COMMA_OR_NEWLINE, /**< Array elements. */
|
||||
pjsip_DISPLAY_SPEC; /**< Used when searching for display name. */
|
||||
|
||||
/*
|
||||
* Various string constants.
|
||||
|
|
|
@ -104,6 +104,7 @@ struct pjsip_endpoint
|
|||
static void endpt_transport_callback(pjsip_endpoint*,
|
||||
pj_status_t, pjsip_rx_data*);
|
||||
|
||||
void init_sip_parser(void);
|
||||
|
||||
/*
|
||||
* This is the global handler for memory allocation failure, for pools that
|
||||
|
@ -373,6 +374,9 @@ PJ_DEF(pj_status_t) pjsip_endpt_create(pj_pool_factory *pf,
|
|||
endpt->pool = pool;
|
||||
endpt->pf = pf;
|
||||
|
||||
/* Init parser. */
|
||||
init_sip_parser();
|
||||
|
||||
/* Get name. */
|
||||
if (name != NULL) {
|
||||
pj_str_t temp;
|
||||
|
|
|
@ -65,7 +65,6 @@ static handler_rec handler[127];
|
|||
static unsigned handler_count;
|
||||
static int parser_is_initialized;
|
||||
|
||||
|
||||
/*
|
||||
* Global vars (also extern).
|
||||
*/
|
||||
|
@ -101,9 +100,9 @@ pj_cis_t pjsip_HOST_SPEC, /* For scanning host part. */
|
|||
pjsip_PROBE_USER_HOST_SPEC, /* Hostname characters. */
|
||||
pjsip_PASSWD_SPEC, /* Password. */
|
||||
pjsip_USER_SPEC, /* User */
|
||||
pjsip_ARRAY_ELEMENTS, /* Array separator. */
|
||||
pjsip_NEWLINE_OR_EOF_SPEC, /* For eating up header.*/
|
||||
pjsip_DISPLAY_SCAN_SPEC; /* Used when searching for display name
|
||||
pjsip_NOT_COMMA_OR_NEWLINE, /* Array separator. */
|
||||
pjsip_NOT_NEWLINE, /* For eating up header.*/
|
||||
pjsip_DISPLAY_SPEC; /* Used when searching for display name
|
||||
* in URL. */
|
||||
|
||||
|
||||
|
@ -258,14 +257,15 @@ static pj_status_t init_parser()
|
|||
pj_cis_add_alpha( &pjsip_ALNUM_SPEC );
|
||||
pj_cis_add_num( &pjsip_ALNUM_SPEC );
|
||||
|
||||
status = pj_cis_init(&cis_buf, &pjsip_NEWLINE_OR_EOF_SPEC);
|
||||
status = pj_cis_init(&cis_buf, &pjsip_NOT_NEWLINE);
|
||||
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
|
||||
pj_cis_add_str(&pjsip_NEWLINE_OR_EOF_SPEC, "\r\n");
|
||||
//pj_cs_set(pjsip_NEWLINE_OR_EOF_SPEC, 0);
|
||||
pj_cis_add_str(&pjsip_NOT_NEWLINE, "\r\n");
|
||||
pj_cis_invert(&pjsip_NOT_NEWLINE);
|
||||
|
||||
status = pj_cis_init(&cis_buf, &pjsip_ARRAY_ELEMENTS);
|
||||
status = pj_cis_init(&cis_buf, &pjsip_NOT_COMMA_OR_NEWLINE);
|
||||
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
|
||||
pj_cis_add_str( &pjsip_ARRAY_ELEMENTS, ",\r\n");
|
||||
pj_cis_add_str( &pjsip_NOT_COMMA_OR_NEWLINE, ",\r\n");
|
||||
pj_cis_invert(&pjsip_NOT_COMMA_OR_NEWLINE);
|
||||
|
||||
status = pj_cis_dup(&pjsip_TOKEN_SPEC, &pjsip_ALNUM_SPEC);
|
||||
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
|
||||
|
@ -300,9 +300,10 @@ static pj_status_t init_parser()
|
|||
pj_cis_add_str( &pjsip_PROBE_USER_HOST_SPEC, "@ \n>");
|
||||
pj_cis_invert( &pjsip_PROBE_USER_HOST_SPEC );
|
||||
|
||||
status = pj_cis_init(&cis_buf, &pjsip_DISPLAY_SCAN_SPEC);
|
||||
status = pj_cis_init(&cis_buf, &pjsip_DISPLAY_SPEC);
|
||||
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
|
||||
pj_cis_add_str( &pjsip_DISPLAY_SCAN_SPEC, ":\r\n<");
|
||||
pj_cis_add_str( &pjsip_DISPLAY_SPEC, ":\r\n<");
|
||||
pj_cis_invert(&pjsip_DISPLAY_SPEC);
|
||||
|
||||
status = pjsip_register_hdr_parser( "Accept", NULL, &parse_hdr_accept);
|
||||
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
|
||||
|
@ -374,7 +375,7 @@ static pj_status_t init_parser()
|
|||
return status;
|
||||
}
|
||||
|
||||
static void init_sip_parser(void)
|
||||
void init_sip_parser(void)
|
||||
{
|
||||
if (!parser_is_initialized) {
|
||||
/* Prevent race cond. */
|
||||
|
@ -392,23 +393,27 @@ static void init_sip_parser(void)
|
|||
* - <0 if handler is 'less' than the header name.
|
||||
* - >0 if handler is 'greater' than header name.
|
||||
*/
|
||||
static int compare_handler( const handler_rec *r1,
|
||||
PJ_INLINE(int) compare_handler( const handler_rec *r1,
|
||||
const char *name,
|
||||
pj_size_t name_len,
|
||||
pj_uint32_t hash )
|
||||
{
|
||||
/* Compare length. */
|
||||
if (r1->hname_len < name_len)
|
||||
return -1;
|
||||
if (r1->hname_len > name_len)
|
||||
return 1;
|
||||
PJ_UNUSED_ARG(name_len);
|
||||
|
||||
/* Length is equal, compare hashed value. */
|
||||
/* Compare hashed value. */
|
||||
if (r1->hname_hash < hash)
|
||||
return -1;
|
||||
if (r1->hname_hash > hash)
|
||||
return 1;
|
||||
|
||||
/* Compare length. */
|
||||
/*
|
||||
if (r1->hname_len < name_len)
|
||||
return -1;
|
||||
if (r1->hname_len > name_len)
|
||||
return 1;
|
||||
*/
|
||||
|
||||
/* Equal length and equal hash. compare the strings. */
|
||||
return pj_native_strcmp(r1->hname, name);
|
||||
}
|
||||
|
@ -609,7 +614,8 @@ PJ_DEF(pj_bool_t) pjsip_find_msg( const char *buf, pj_size_t size,
|
|||
|
||||
|
||||
/* Find the end of header area by finding an empty line. */
|
||||
if ((pos = pj_native_strstr(buf, "\n\r\n")) == NULL) {
|
||||
pos = pj_native_strstr(buf, "\n\r\n");
|
||||
if (pos == NULL) {
|
||||
return PJSIP_EPARTIALMSG;
|
||||
}
|
||||
|
||||
|
@ -618,10 +624,10 @@ PJ_DEF(pj_bool_t) pjsip_find_msg( const char *buf, pj_size_t size,
|
|||
|
||||
/* Find "Content-Length" header the hard way. */
|
||||
line = pj_native_strchr(buf, '\n');
|
||||
while (line && line < hdr_end-14) {
|
||||
while (line && line < hdr_end) {
|
||||
++line;
|
||||
if ( ((*line=='C' || *line=='c') &&
|
||||
pj_native_strncasecmp(line, "Content-Length", 14) == 0) ||
|
||||
strnicmp_alnum(line, "Content-Length", 14) == 0) ||
|
||||
((*line=='l' || *line=='L') &&
|
||||
(*(line+1)==' ' || *(line+1)=='\t' || *(line+1)==':')))
|
||||
{
|
||||
|
@ -744,22 +750,20 @@ static int generic_print_body (pjsip_msg_body *msg_body,
|
|||
static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx,
|
||||
pjsip_parser_err_report *err_list)
|
||||
{
|
||||
int ch;
|
||||
pjsip_msg *msg;
|
||||
pj_str_t hname;
|
||||
pjsip_ctype_hdr *ctype_hdr = NULL;
|
||||
pj_scanner *scanner = ctx->scanner;
|
||||
pj_pool_t *pool = ctx->pool;
|
||||
PJ_USE_EXCEPTION;
|
||||
|
||||
/* Skip leading newlines. */
|
||||
ch = *scanner->curptr;
|
||||
while (ch=='\r' || ch=='\n') {
|
||||
pj_scan_get_char(scanner);
|
||||
ch = *scanner->curptr;
|
||||
while (*scanner->curptr=='\r' || *scanner->curptr=='\n') {
|
||||
pj_scan_get_newline(scanner);
|
||||
}
|
||||
|
||||
/* Parse request or status line */
|
||||
if (pj_scan_stricmp( scanner, PJSIP_VERSION, 7) == 0) {
|
||||
if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION, 7) == 0) {
|
||||
msg = pjsip_msg_create(pool, PJSIP_RESPONSE_MSG);
|
||||
int_parse_status_line( scanner, &msg->line.status );
|
||||
} else {
|
||||
|
@ -768,22 +772,23 @@ static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx,
|
|||
}
|
||||
|
||||
/* Parse headers. */
|
||||
parse_headers:
|
||||
|
||||
PJ_TRY
|
||||
{
|
||||
do {
|
||||
pj_str_t hname;
|
||||
pjsip_parse_hdr_func * handler;
|
||||
pjsip_hdr *hdr = NULL;
|
||||
|
||||
/* Get hname. */
|
||||
pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &hname);
|
||||
ch = pj_scan_get_char( scanner );
|
||||
if (ch != ':') {
|
||||
if (pj_scan_get_char( scanner ) != ':') {
|
||||
PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
|
||||
}
|
||||
|
||||
/* Find handler. */
|
||||
handler = find_handler(&hname);
|
||||
|
||||
PJ_TRY {
|
||||
/* Call the handler if found.
|
||||
* If no handler is found, then treat the header as generic
|
||||
* hname/hvalue pair.
|
||||
|
@ -797,44 +802,13 @@ static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx,
|
|||
}
|
||||
|
||||
/* Check if we've just parsed a Content-Type header.
|
||||
* We will check for a message body if we've got Content-Type header.
|
||||
* We will check for a message body if we've got Content-Type
|
||||
* header.
|
||||
*/
|
||||
if (hdr->type == PJSIP_H_CONTENT_TYPE) {
|
||||
ctype_hdr = (pjsip_ctype_hdr*)hdr;
|
||||
}
|
||||
|
||||
}
|
||||
PJ_CATCH_ANY {
|
||||
/* Exception was thrown during parsing.
|
||||
* Skip until newline, and parse next header.
|
||||
*/
|
||||
pj_str_t token;
|
||||
hdr = NULL;
|
||||
|
||||
//PJ_LOG(4,("sipparser",
|
||||
// "Syntax error in line %d col %d (hname=%.*s)",
|
||||
// scanner->line, scanner->col, hname.slen, hname.ptr));
|
||||
|
||||
if (err_list) {
|
||||
pjsip_parser_err_report *err_info;
|
||||
|
||||
err_info = pj_pool_alloc(pool, sizeof(*err_info));
|
||||
err_info->except_code = PJ_GET_EXCEPTION();
|
||||
err_info->line = scanner->line;
|
||||
err_info->col = scanner->col;
|
||||
err_info->hname = hname;
|
||||
|
||||
pj_list_insert_before(err_list, err_info);
|
||||
}
|
||||
|
||||
if (!pj_scan_is_eof(scanner)) {
|
||||
pj_scan_get_until(scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &token);
|
||||
parse_hdr_end(scanner);
|
||||
}
|
||||
}
|
||||
PJ_END;
|
||||
|
||||
if (hdr) {
|
||||
/* Single parse of header line can produce multiple headers.
|
||||
* For example, if one Contact: header contains Contact list
|
||||
* separated by comma, then these Contacts will be split into
|
||||
|
@ -842,12 +816,45 @@ static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx,
|
|||
* So here we must insert list instead of just insert one header.
|
||||
*/
|
||||
pj_list_insert_nodes_before(&msg->hdr, hdr);
|
||||
}
|
||||
|
||||
/* Parse until EOF or an empty line is found. */
|
||||
} while (!pj_scan_is_eof(scanner) &&
|
||||
*scanner->curptr != '\r' && *scanner->curptr != '\n');
|
||||
|
||||
}
|
||||
PJ_CATCH_ANY
|
||||
{
|
||||
/* Exception was thrown during parsing.
|
||||
* Skip until newline, and parse next header.
|
||||
*/
|
||||
pj_str_t token;
|
||||
|
||||
if (err_list) {
|
||||
pjsip_parser_err_report *err_info;
|
||||
|
||||
err_info = pj_pool_alloc(pool, sizeof(*err_info));
|
||||
err_info->except_code = PJ_GET_EXCEPTION();
|
||||
err_info->line = scanner->line;
|
||||
err_info->col = pj_scan_get_col(scanner);
|
||||
err_info->hname = hname;
|
||||
|
||||
pj_list_insert_before(err_list, err_info);
|
||||
}
|
||||
|
||||
if (!pj_scan_is_eof(scanner)) {
|
||||
pj_scan_get(scanner, &pjsip_NOT_NEWLINE, &token);
|
||||
parse_hdr_end(scanner);
|
||||
}
|
||||
|
||||
if (!pj_scan_is_eof(scanner) &&
|
||||
*scanner->curptr != '\r' && *scanner->curptr != '\n');
|
||||
{
|
||||
goto parse_headers;
|
||||
}
|
||||
}
|
||||
PJ_END;
|
||||
|
||||
|
||||
/* If empty line is found, eat it. */
|
||||
if (!pj_scan_is_eof(scanner)) {
|
||||
if (*scanner->curptr=='\r' || *scanner->curptr=='\n') {
|
||||
|
@ -858,9 +865,10 @@ static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx,
|
|||
/* If we have Content-Type header, treat the rest of the message as body.*/
|
||||
if (ctype_hdr && scanner->curptr!=scanner->end) {
|
||||
pjsip_msg_body *body = pj_pool_alloc(pool, sizeof(pjsip_msg_body));
|
||||
pj_strdup(pool, &body->content_type.type, &ctype_hdr->media.type);
|
||||
pj_strdup(pool, &body->content_type.subtype, &ctype_hdr->media.subtype);
|
||||
pj_strdup(pool, &body->content_type.param, &ctype_hdr->media.param);
|
||||
body->content_type.type = ctype_hdr->media.type;
|
||||
body->content_type.subtype = ctype_hdr->media.subtype;
|
||||
body->content_type.param = ctype_hdr->media.param;
|
||||
|
||||
body->data = scanner->curptr;
|
||||
body->len = scanner->end - scanner->curptr;
|
||||
body->print_body = &generic_print_body;
|
||||
|
@ -1001,16 +1009,12 @@ static pjsip_uri *int_parse_uri_or_name_addr( pj_scanner *scanner, pj_pool_t *po
|
|||
uri = (pjsip_uri*)int_parse_name_addr( scanner, pool );
|
||||
is_name_addr = 1;
|
||||
} else {
|
||||
pj_scan_state backtrack;
|
||||
pj_str_t scheme;
|
||||
int colon;
|
||||
int next_ch;
|
||||
|
||||
pj_scan_save_state( scanner, &backtrack);
|
||||
pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &scheme);
|
||||
colon = pj_scan_get_char( scanner );
|
||||
pj_scan_restore_state( scanner, &backtrack);
|
||||
next_ch = pj_scan_peek( scanner, &pjsip_DISPLAY_SPEC, &scheme);
|
||||
|
||||
if (colon==':' &&
|
||||
if (next_ch==':' &&
|
||||
(parser_stricmp(scheme, pjsip_SIP_STR)==0 ||
|
||||
parser_stricmp(scheme, pjsip_SIPS_STR)==0))
|
||||
{
|
||||
|
@ -1018,7 +1022,7 @@ static pjsip_uri *int_parse_uri_or_name_addr( pj_scanner *scanner, pj_pool_t *po
|
|||
int_parse_sip_url( scanner, pool,
|
||||
(opt & PJSIP_PARSE_URI_IN_FROM_TO_HDR)== 0);
|
||||
|
||||
} else if (colon==':' && parser_stricmp( scheme, pjsip_TEL_STR)==0) {
|
||||
} else if (next_ch==':') {
|
||||
|
||||
/* Not supported. */
|
||||
PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
|
||||
|
@ -1189,7 +1193,7 @@ static pjsip_name_addr *int_parse_name_addr( pj_scanner *scanner,
|
|||
* We're only interested in display name, because SIP URL
|
||||
* will be parser later.
|
||||
*/
|
||||
next = pj_scan_peek_until(scanner, &pjsip_DISPLAY_SCAN_SPEC, &dummy);
|
||||
next = pj_scan_peek(scanner, &pjsip_DISPLAY_SPEC, &dummy);
|
||||
if (next == '<') {
|
||||
/* Ok, this is what we're looking for, a display name. */
|
||||
pj_scan_get_until_ch( scanner, '<', &name_addr->display);
|
||||
|
@ -1205,8 +1209,10 @@ static pjsip_name_addr *int_parse_name_addr( pj_scanner *scanner,
|
|||
if (has_bracket)
|
||||
pj_scan_get_char(scanner);
|
||||
name_addr->uri = int_parse_uri( scanner, pool, PJ_TRUE );
|
||||
if (has_bracket)
|
||||
pj_scan_get_char(scanner);
|
||||
if (has_bracket) {
|
||||
if (pj_scan_get_char(scanner) != '>')
|
||||
PJ_THROW( PJSIP_SYN_ERR_EXCEPTION);
|
||||
}
|
||||
|
||||
return name_addr;
|
||||
}
|
||||
|
@ -1222,7 +1228,7 @@ static void int_parse_req_line( pj_scanner *scanner, pj_pool_t *pool,
|
|||
pjsip_method_init_np( &req_line->method, &token);
|
||||
|
||||
req_line->uri = int_parse_uri(scanner, pool, PJ_TRUE);
|
||||
if (pj_scan_stricmp( scanner, PJSIP_VERSION, 7) != 0)
|
||||
if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION, 7) != 0)
|
||||
PJ_THROW( PJSIP_SYN_ERR_EXCEPTION);
|
||||
pj_scan_advance_n (scanner, 7, 1);
|
||||
pj_scan_get_newline( scanner );
|
||||
|
@ -1234,14 +1240,13 @@ static void int_parse_status_line( pj_scanner *scanner,
|
|||
{
|
||||
pj_str_t token;
|
||||
|
||||
if (pj_scan_stricmp(scanner, PJSIP_VERSION, 7) != 0)
|
||||
if (pj_scan_stricmp_alnum(scanner, PJSIP_VERSION, 7) != 0)
|
||||
PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
|
||||
pj_scan_advance_n( scanner, 7, 1);
|
||||
|
||||
pj_scan_get( scanner, &pjsip_DIGIT_SPEC, &token);
|
||||
status_line->code = pj_strtoul(&token);
|
||||
pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC,
|
||||
&status_line->reason);
|
||||
pj_scan_get( scanner, &pjsip_NOT_NEWLINE, &status_line->reason);
|
||||
pj_scan_get_newline( scanner );
|
||||
}
|
||||
|
||||
|
@ -1267,12 +1272,12 @@ void pjsip_parse_end_hdr_imp( pj_scanner *scanner )
|
|||
static void parse_generic_array_hdr( pjsip_generic_array_hdr *hdr,
|
||||
pj_scanner *scanner)
|
||||
{
|
||||
pj_scan_get_until( scanner, &pjsip_ARRAY_ELEMENTS, &hdr->values[0]);
|
||||
pj_scan_get( scanner, &pjsip_NOT_COMMA_OR_NEWLINE, &hdr->values[0]);
|
||||
hdr->count++;
|
||||
|
||||
while (*scanner->curptr == ',') {
|
||||
pj_scan_get_char(scanner);
|
||||
pj_scan_get_until( scanner, &pjsip_ARRAY_ELEMENTS,
|
||||
pj_scan_get( scanner, &pjsip_NOT_COMMA_OR_NEWLINE,
|
||||
&hdr->values[hdr->count]);
|
||||
hdr->count++;
|
||||
}
|
||||
|
@ -1283,7 +1288,11 @@ static void parse_generic_array_hdr( pjsip_generic_array_hdr *hdr,
|
|||
static void parse_generic_string_hdr( pjsip_generic_string_hdr *hdr,
|
||||
pj_scanner *scanner )
|
||||
{
|
||||
pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &hdr->hvalue);
|
||||
if (pj_cis_match(&pjsip_NOT_NEWLINE, *scanner->curptr))
|
||||
pj_scan_get( scanner, &pjsip_NOT_NEWLINE, &hdr->hvalue);
|
||||
else
|
||||
hdr->hvalue.slen = 0;
|
||||
|
||||
parse_hdr_end(scanner);
|
||||
}
|
||||
|
||||
|
@ -1292,7 +1301,7 @@ static void parse_generic_int_hdr( pjsip_generic_int_hdr *hdr,
|
|||
pj_scanner *scanner )
|
||||
{
|
||||
pj_str_t tmp;
|
||||
pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &tmp);
|
||||
pj_scan_get( scanner, &pjsip_DIGIT_SPEC, &tmp);
|
||||
hdr->ivalue = pj_strtoul(&tmp);
|
||||
parse_hdr_end(scanner);
|
||||
}
|
||||
|
@ -1318,7 +1327,7 @@ static pjsip_hdr* parse_hdr_allow(pjsip_parse_ctx *ctx)
|
|||
static pjsip_hdr* parse_hdr_call_id(pjsip_parse_ctx *ctx)
|
||||
{
|
||||
pjsip_cid_hdr *hdr = pjsip_cid_hdr_create(ctx->pool);
|
||||
pj_scan_get_until( ctx->scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &hdr->id);
|
||||
pj_scan_get( ctx->scanner, &pjsip_NOT_NEWLINE, &hdr->id);
|
||||
parse_hdr_end(ctx->scanner);
|
||||
|
||||
if (ctx->rdata)
|
||||
|
@ -1700,7 +1709,7 @@ static pjsip_hdr* parse_hdr_via( pjsip_parse_ctx *ctx )
|
|||
else
|
||||
pj_list_insert_before(first, hdr);
|
||||
|
||||
if (pj_scan_stricmp( scanner, PJSIP_VERSION "/", 8) != 0)
|
||||
if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION "/", 8) != 0)
|
||||
PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
|
||||
|
||||
pj_scan_advance_n( scanner, 8, 1);
|
||||
|
|
|
@ -89,11 +89,19 @@ PJ_DEF(pj_ssize_t) pjsip_param_print_on( const pjsip_param *param_list,
|
|||
char *buf, pj_size_t size,
|
||||
int sep)
|
||||
{
|
||||
const pjsip_param *p = param_list->next;
|
||||
char *startbuf = buf;
|
||||
char *endbuf = buf + size;
|
||||
const pjsip_param *p;
|
||||
char *startbuf;
|
||||
char *endbuf;
|
||||
int printed;
|
||||
|
||||
while (p != param_list) {
|
||||
p = param_list->next;
|
||||
if (p == param_list)
|
||||
return 0;
|
||||
|
||||
startbuf = buf;
|
||||
endbuf = buf + size;
|
||||
|
||||
do {
|
||||
*buf++ = (char)sep;
|
||||
copy_advance_escape(buf, p->name, pjsip_PARAM_CHAR_SPEC);
|
||||
if (p->value.slen) {
|
||||
|
@ -101,7 +109,8 @@ PJ_DEF(pj_ssize_t) pjsip_param_print_on( const pjsip_param *param_list,
|
|||
copy_advance_escape(buf, p->value, pjsip_PARAM_CHAR_SPEC);
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
} while (p != param_list);
|
||||
|
||||
return buf-startbuf;
|
||||
}
|
||||
|
||||
|
@ -248,6 +257,9 @@ static int pjsip_url_print( pjsip_uri_context_e context,
|
|||
*/
|
||||
//PJ_TODO(SHOULD_DISALLOW_URI_PORT_IN_FROM_TO_HEADER)
|
||||
if (url->port && context != PJSIP_URI_IN_FROMTO_HDR) {
|
||||
if (endbuf - buf < 10)
|
||||
return -1;
|
||||
|
||||
*buf++ = ':';
|
||||
printed = pj_utoa(url->port, buf);
|
||||
buf += printed;
|
||||
|
@ -270,8 +282,10 @@ static int pjsip_url_print( pjsip_uri_context_e context,
|
|||
|
||||
/* TTL param is not allowed in From, To, Route, and Record-Route header. */
|
||||
if (url->ttl_param >= 0 && context != PJSIP_URI_IN_FROMTO_HDR &&
|
||||
context != PJSIP_URI_IN_ROUTING_HDR && (endbuf-buf) > 15)
|
||||
context != PJSIP_URI_IN_ROUTING_HDR)
|
||||
{
|
||||
if (endbuf - buf < 15)
|
||||
return -1;
|
||||
pj_memcpy(buf, ";ttl=", 5);
|
||||
printed = pj_utoa(url->ttl_param, buf+5);
|
||||
buf += printed + 5;
|
||||
|
@ -288,6 +302,8 @@ static int pjsip_url_print( pjsip_uri_context_e context,
|
|||
context != PJSIP_URI_IN_CONTACT_HDR)
|
||||
{
|
||||
pj_str_t lr = { ";lr", 3 };
|
||||
if (endbuf - buf < 3)
|
||||
return -1;
|
||||
copy_advance_check(buf, lr);
|
||||
}
|
||||
|
||||
|
@ -300,6 +316,8 @@ static int pjsip_url_print( pjsip_uri_context_e context,
|
|||
/* Header param. */
|
||||
param = url->header_param.next;
|
||||
while (param != &url->header_param) {
|
||||
if (endbuf - buf < param->name.slen+2)
|
||||
return -1;
|
||||
*buf++ = hparam_char;
|
||||
copy_advance_escape(buf, param->name, pjsip_HDR_CHAR_SPEC);
|
||||
if (param->value.slen) {
|
||||
|
|
|
@ -34,7 +34,7 @@ static pjsip_msg *create_msg1(pj_pool_t *pool);
|
|||
#define FLAG_PARSE_ONLY 4
|
||||
#define FLAG_PRINT_ONLY 8
|
||||
|
||||
static int flag = FLAG_PARSE_ONLY;
|
||||
static int flag = 0;
|
||||
|
||||
struct test_msg
|
||||
{
|
||||
|
@ -105,6 +105,7 @@ static pj_timestamp detect_time, parse_time, print_time;
|
|||
static pj_status_t test_entry( pj_pool_t *pool, struct test_msg *entry )
|
||||
{
|
||||
pjsip_msg *parsed_msg, *ref_msg;
|
||||
static pjsip_msg *print_msg;
|
||||
pj_status_t status = PJ_SUCCESS;
|
||||
int len;
|
||||
pj_str_t str1, str2;
|
||||
|
@ -114,15 +115,18 @@ static pj_status_t test_entry( pj_pool_t *pool, struct test_msg *entry )
|
|||
pj_size_t msg_size;
|
||||
char msgbuf1[PJSIP_MAX_PKT_LEN];
|
||||
char msgbuf2[PJSIP_MAX_PKT_LEN];
|
||||
|
||||
enum { BUFLEN = 512 };
|
||||
|
||||
entry->len = pj_native_strlen(entry->msg);
|
||||
|
||||
if (flag & FLAG_PARSE_ONLY)
|
||||
goto parse_msg;
|
||||
if (flag & FLAG_PRINT_ONLY)
|
||||
|
||||
if (flag & FLAG_PRINT_ONLY) {
|
||||
if (print_msg == NULL)
|
||||
print_msg = entry->creator(pool);
|
||||
goto print_msg;
|
||||
}
|
||||
|
||||
/* Detect message. */
|
||||
detect_len = detect_len + entry->len;
|
||||
|
@ -144,7 +148,7 @@ static pj_status_t test_entry( pj_pool_t *pool, struct test_msg *entry )
|
|||
pj_sub_timestamp(&t2, &t1);
|
||||
pj_add_timestamp(&detect_time, &t2);
|
||||
|
||||
if (flag & FLAG_PARSE_ONLY)
|
||||
if (flag & FLAG_DETECT_ONLY)
|
||||
return PJ_SUCCESS;
|
||||
|
||||
/* Parse message. */
|
||||
|
@ -302,7 +306,9 @@ parse_msg:
|
|||
print_msg:
|
||||
print_len = print_len + entry->len;
|
||||
pj_get_timestamp(&t1);
|
||||
len = pjsip_msg_print(parsed_msg, msgbuf1, PJSIP_MAX_PKT_LEN);
|
||||
if (flag && FLAG_PRINT_ONLY)
|
||||
ref_msg = print_msg;
|
||||
len = pjsip_msg_print(ref_msg, msgbuf1, PJSIP_MAX_PKT_LEN);
|
||||
if (len < 1) {
|
||||
status = -150;
|
||||
goto on_return;
|
||||
|
|
|
@ -81,8 +81,8 @@ int test_main(void)
|
|||
|
||||
PJ_LOG(3,("",""));
|
||||
|
||||
//DO_TEST(uri_test());
|
||||
DO_TEST(msg_test());
|
||||
DO_TEST(uri_test());
|
||||
//DO_TEST(msg_test());
|
||||
|
||||
on_return:
|
||||
|
||||
|
|
Loading…
Reference in New Issue