From bf364b7c7deabe95dea0cf62180cdbf36c7c2031 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Tue, 22 Nov 2005 23:51:50 +0000 Subject: More optimizations for msg parser etc. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@77 74dad513-b988-da41-8d7b-12977e46ad98 --- pjlib-util/build/pjlib_util.dsp | 2 +- pjlib-util/include/pjlib-util/scanner.h | 79 +++++++++++---- pjlib-util/src/pjlib-util/scanner.c | 166 +++++++++++++------------------- pjlib-util/src/pjlib-util/xml.c | 2 +- 4 files changed, 129 insertions(+), 120 deletions(-) (limited to 'pjlib-util') diff --git a/pjlib-util/build/pjlib_util.dsp b/pjlib-util/build/pjlib_util.dsp index 5497aff9..692e32d8 100644 --- a/pjlib-util/build/pjlib_util.dsp +++ b/pjlib-util/build/pjlib_util.dsp @@ -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 diff --git a/pjlib-util/include/pjlib-util/scanner.h b/pjlib-util/include/pjlib-util/scanner.h index 1a4a69ef..b8f8f761 100644 --- a/pjlib-util/include/pjlib-util/scanner.h +++ b/pjlib-util/include/pjlib-util/scanner.h @@ -193,12 +193,12 @@ typedef void (*pj_syn_err_func_ptr)(struct pj_scanner *scanner); */ typedef struct pj_scanner { - char *begin; /**< Start of input buffer. */ - char *end; /**< End of input buffer. */ - char *curptr; /**< Current pointer. */ - int line; /**< Current line. */ - int col; /**< Current column. */ - int skip_ws; /**< Skip whitespace flag. */ + char *begin; /**< Start of input buffer. */ + char *end; /**< End of input buffer. */ + char *curptr; /**< Current pointer. */ + int line; /**< Current line. */ + char *start_line; /**< Where current line starts. */ + int skip_ws; /**< Skip whitespace flag. */ pj_syn_err_func_ptr callback; /**< Syntax error callback. */ } pj_scanner; @@ -210,8 +210,8 @@ typedef struct pj_scanner typedef struct pj_scan_state { char *curptr; /**< Current scanner's pointer. */ - int line; /**< Current line. */ - int col; /**< Current column. */ + int line; /**< Current line. */ + 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. @@ -333,8 +334,8 @@ PJ_DECL(void) pj_scan_get( pj_scanner *scanner, * @param out String to store the result. */ PJ_DECL(void) pj_scan_get_quote( pj_scanner *scanner, - int begin_quote, int end_quote, - pj_str_t *out); + int begin_quote, int end_quote, + pj_str_t *out); /** * Get N characters from the scanner. @@ -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; +} + /** * @} */ diff --git a/pjlib-util/src/pjlib-util/scanner.c b/pjlib-util/src/pjlib-util/scanner.c index 77d2db03..f4ef54c6 100644 --- a/pjlib-util/src/pjlib-util/scanner.c +++ b/pjlib-util/src/pjlib-util/scanner.c @@ -23,9 +23,10 @@ #include #include -#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_SPACE(c) ((c)==' ' || (c)=='\t') +#define PJ_SCAN_IS_NEWLINE(c) ((c)=='\r' || (c)=='\n') +#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,11 +281,7 @@ 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) { pj_scan_syntax_err(scanner); @@ -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,34 +335,26 @@ 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); } } PJ_DEF(void) pj_scan_get_n( pj_scanner *scanner, - unsigned N, pj_str_t *out) + 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; - - PJ_CHECK_STACK(); + int speclen; - 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; } diff --git a/pjlib-util/src/pjlib-util/xml.c b/pjlib-util/src/pjlib-util/xml.c index 35ec96c5..f502df0e 100644 --- a/pjlib-util/src/pjlib-util/xml.c +++ b/pjlib-util/src/pjlib-util/xml.c @@ -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 ); -- cgit v1.2.3