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:
Benny Prijono 2005-11-22 23:51:50 +00:00
parent 3818c93ec1
commit cec5f4ae2c
15 changed files with 369 additions and 297 deletions

View File

@ -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

View File

@ -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;
}
/**
* @}
*/

View File

@ -23,9 +23,10 @@
#include <pj/errno.h>
#include <pj/assert.h>
#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;
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;
}

View File

@ -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 );

View File

@ -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.

View File

@ -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;

View File

@ -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.

View File

@ -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"

View File

@ -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); \
@ -76,16 +52,13 @@ 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; \
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; \
} \
if (str2.slen) { \
if (len1+str2.slen >= (endbuf-buf)) return -1; \
pj_memcpy(buf,str1,len1); \
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) \
@ -117,10 +89,10 @@ static char *imp_copy_advance_pair(char *buf, char *endbuf, const char *str1, in
#define copy_advance_pair_quote_cond(buf,str1,len1,str2,quotebegin,quoteend) \
do { \
if (str2.slen && *str2.ptr!=quotebegin) \
copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend); \
else \
copy_advance_pair(buf,str1,len1,str2); \
if (str2.slen && *str2.ptr!=quotebegin) \
copy_advance_pair_quote(buf,str1,len1,str2,quotebegin,quoteend); \
else \
copy_advance_pair(buf,str1,len1,str2); \
} while (0)
/*

View File

@ -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.

View File

@ -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;

View File

@ -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,19 +614,20 @@ 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;
}
hdr_end = pos+1;
body_start = pos+3;
/* 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. */
do {
pj_str_t hname;
pjsip_parse_hdr_func * handler;
pjsip_hdr *hdr = NULL;
parse_headers:
/* Get hname. */
pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &hname);
ch = pj_scan_get_char( scanner );
if (ch != ':') {
PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
}
/* Find handler. */
handler = find_handler(&hname);
PJ_TRY {
PJ_TRY
{
do {
pjsip_parse_hdr_func * handler;
pjsip_hdr *hdr = NULL;
/* Get hname. */
pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &hname);
if (pj_scan_get_char( scanner ) != ':') {
PJ_THROW(PJSIP_SYN_ERR_EXCEPTION);
}
/* Find handler. */
handler = find_handler(&hname);
/* Call the handler if found.
* If no handler is found, then treat the header as generic
* hname/hvalue pair.
@ -795,46 +800,15 @@ static pjsip_msg *int_parse_msg( pjsip_parse_ctx *ctx,
hdr->type = PJSIP_H_OTHER;
hdr->name = hdr->sname = hname;
}
/* 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,11 +816,44 @@ 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);
}
/* Parse until EOF or an empty line is found. */
} while (!pj_scan_is_eof(scanner) &&
*scanner->curptr != '\r' && *scanner->curptr != '\n');
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)) {
@ -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,13 +1272,13 @@ 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,
&hdr->values[hdr->count]);
pj_scan_get( scanner, &pjsip_NOT_COMMA_OR_NEWLINE,
&hdr->values[hdr->count]);
hdr->count++;
}
parse_hdr_end(scanner);
@ -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);

View File

@ -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) {

View File

@ -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;

View File

@ -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: