Ignore:
Timestamp:
Nov 22, 2005 11:51:50 PM (17 years ago)
Author:
bennylp
Message:

More optimizations for msg parser etc.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjsip/src/pjsip/sip_parser.c

    r76 r77  
    6666static int parser_is_initialized; 
    6767 
    68  
    6968/* 
    7069 * Global vars (also extern). 
     
    102101            pjsip_PASSWD_SPEC,          /* Password. */ 
    103102            pjsip_USER_SPEC,            /* User */ 
    104             pjsip_ARRAY_ELEMENTS,      /* Array separator. */ 
    105             pjsip_NEWLINE_OR_EOF_SPEC,  /* For eating up header.*/ 
    106             pjsip_DISPLAY_SCAN_SPEC;    /* Used when searching for display name 
     103            pjsip_NOT_COMMA_OR_NEWLINE, /* Array separator. */ 
     104            pjsip_NOT_NEWLINE,          /* For eating up header.*/ 
     105            pjsip_DISPLAY_SPEC;         /* Used when searching for display name 
    107106                                         * in URL. */ 
    108107 
     
    259258    pj_cis_add_num( &pjsip_ALNUM_SPEC ); 
    260259 
    261     status = pj_cis_init(&cis_buf, &pjsip_NEWLINE_OR_EOF_SPEC); 
    262     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 
    263     pj_cis_add_str(&pjsip_NEWLINE_OR_EOF_SPEC, "\r\n"); 
    264     //pj_cs_set(pjsip_NEWLINE_OR_EOF_SPEC, 0); 
    265  
    266     status = pj_cis_init(&cis_buf, &pjsip_ARRAY_ELEMENTS); 
    267     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 
    268     pj_cis_add_str( &pjsip_ARRAY_ELEMENTS, ",\r\n"); 
     260    status = pj_cis_init(&cis_buf, &pjsip_NOT_NEWLINE); 
     261    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 
     262    pj_cis_add_str(&pjsip_NOT_NEWLINE, "\r\n"); 
     263    pj_cis_invert(&pjsip_NOT_NEWLINE); 
     264 
     265    status = pj_cis_init(&cis_buf, &pjsip_NOT_COMMA_OR_NEWLINE); 
     266    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 
     267    pj_cis_add_str( &pjsip_NOT_COMMA_OR_NEWLINE, ",\r\n"); 
     268    pj_cis_invert(&pjsip_NOT_COMMA_OR_NEWLINE); 
    269269 
    270270    status = pj_cis_dup(&pjsip_TOKEN_SPEC, &pjsip_ALNUM_SPEC); 
     
    301301    pj_cis_invert( &pjsip_PROBE_USER_HOST_SPEC ); 
    302302 
    303     status = pj_cis_init(&cis_buf, &pjsip_DISPLAY_SCAN_SPEC); 
    304     PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 
    305     pj_cis_add_str( &pjsip_DISPLAY_SCAN_SPEC, ":\r\n<"); 
     303    status = pj_cis_init(&cis_buf, &pjsip_DISPLAY_SPEC); 
     304    PJ_ASSERT_RETURN(status == PJ_SUCCESS, status); 
     305    pj_cis_add_str( &pjsip_DISPLAY_SPEC, ":\r\n<"); 
     306    pj_cis_invert(&pjsip_DISPLAY_SPEC); 
    306307 
    307308    status = pjsip_register_hdr_parser( "Accept", NULL, &parse_hdr_accept); 
     
    375376} 
    376377 
    377 static void init_sip_parser(void) 
     378void init_sip_parser(void) 
    378379{ 
    379380    if (!parser_is_initialized) { 
     
    393394 * - >0 if handler is 'greater' than header name. 
    394395 */ 
    395 static int compare_handler( const handler_rec *r1,  
     396PJ_INLINE(int) compare_handler( const handler_rec *r1,  
    396397                            const char *name,  
    397398                            pj_size_t name_len, 
    398399                            pj_uint32_t hash ) 
    399400{ 
     401    PJ_UNUSED_ARG(name_len); 
     402 
     403    /* Compare hashed value. */ 
     404    if (r1->hname_hash < hash) 
     405        return -1; 
     406    if (r1->hname_hash > hash) 
     407        return 1; 
     408 
    400409    /* Compare length. */ 
     410    /* 
    401411    if (r1->hname_len < name_len) 
    402412        return -1; 
    403413    if (r1->hname_len > name_len) 
    404414        return 1; 
    405  
    406     /* Length is equal, compare hashed value. */ 
    407     if (r1->hname_hash < hash) 
    408         return -1; 
    409     if (r1->hname_hash > hash) 
    410         return 1; 
     415     */ 
    411416 
    412417    /* Equal length and equal hash. compare the strings. */ 
     
    610615 
    611616    /* Find the end of header area by finding an empty line. */ 
    612     if ((pos = pj_native_strstr(buf, "\n\r\n")) == NULL) { 
     617    pos = pj_native_strstr(buf, "\n\r\n"); 
     618    if (pos == NULL) { 
    613619        return PJSIP_EPARTIALMSG; 
    614620    } 
    615  
     621  
    616622    hdr_end = pos+1; 
    617623    body_start = pos+3; 
     
    619625    /* Find "Content-Length" header the hard way. */ 
    620626    line = pj_native_strchr(buf, '\n'); 
    621     while (line && line < hdr_end-14) { 
     627    while (line && line < hdr_end) { 
    622628        ++line; 
    623629        if ( ((*line=='C' || *line=='c') &&  
    624               pj_native_strncasecmp(line, "Content-Length", 14) == 0) || 
     630              strnicmp_alnum(line, "Content-Length", 14) == 0) || 
    625631             ((*line=='l' || *line=='L') &&  
    626632              (*(line+1)==' ' || *(line+1)=='\t' || *(line+1)==':'))) 
     
    745751                                 pjsip_parser_err_report *err_list) 
    746752{ 
    747     int ch; 
    748753    pjsip_msg *msg; 
     754    pj_str_t hname; 
    749755    pjsip_ctype_hdr *ctype_hdr = NULL; 
    750756    pj_scanner *scanner = ctx->scanner; 
     
    753759 
    754760    /* Skip leading newlines. */ 
    755     ch = *scanner->curptr; 
    756     while (ch=='\r' || ch=='\n') { 
    757         pj_scan_get_char(scanner); 
    758         ch = *scanner->curptr; 
     761    while (*scanner->curptr=='\r' || *scanner->curptr=='\n') { 
     762        pj_scan_get_newline(scanner); 
    759763    } 
    760764 
    761765    /* Parse request or status line */ 
    762     if (pj_scan_stricmp( scanner, PJSIP_VERSION, 7) == 0) { 
     766    if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION, 7) == 0) { 
    763767        msg = pjsip_msg_create(pool, PJSIP_RESPONSE_MSG); 
    764768        int_parse_status_line( scanner, &msg->line.status ); 
     
    769773 
    770774    /* Parse headers. */ 
    771     do { 
    772         pj_str_t hname; 
    773         pjsip_parse_hdr_func * handler; 
    774         pjsip_hdr *hdr = NULL; 
    775  
    776         /* Get hname. */ 
    777         pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &hname); 
    778         ch = pj_scan_get_char( scanner ); 
    779         if (ch != ':') { 
    780             PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); 
    781         } 
    782  
    783         /* Find handler. */ 
    784         handler = find_handler(&hname); 
    785  
    786         PJ_TRY { 
     775parse_headers: 
     776 
     777    PJ_TRY  
     778    { 
     779        do { 
     780            pjsip_parse_hdr_func * handler; 
     781            pjsip_hdr *hdr = NULL; 
     782             
     783            /* Get hname. */ 
     784            pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &hname); 
     785            if (pj_scan_get_char( scanner ) != ':') { 
     786                PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); 
     787            } 
     788             
     789            /* Find handler. */ 
     790            handler = find_handler(&hname); 
     791             
    787792            /* Call the handler if found. 
    788793             * If no handler is found, then treat the header as generic 
     
    796801                hdr->name = hdr->sname = hname; 
    797802            } 
    798  
     803             
    799804            /* Check if we've just parsed a Content-Type header.  
    800              * We will check for a message body if we've got Content-Type header. 
     805             * We will check for a message body if we've got Content-Type  
     806             * header. 
    801807             */ 
    802808            if (hdr->type == PJSIP_H_CONTENT_TYPE) { 
    803809                ctype_hdr = (pjsip_ctype_hdr*)hdr; 
    804810            } 
    805  
    806         } 
    807         PJ_CATCH_ANY { 
    808             /* Exception was thrown during parsing.  
    809              * Skip until newline, and parse next header.  
    810              */ 
    811             pj_str_t token; 
    812             hdr = NULL; 
    813  
    814             //PJ_LOG(4,("sipparser",  
    815             //          "Syntax error in line %d col %d (hname=%.*s)", 
    816             //        scanner->line, scanner->col, hname.slen, hname.ptr)); 
    817  
    818             if (err_list) { 
    819                 pjsip_parser_err_report *err_info; 
    820811                 
    821                 err_info = pj_pool_alloc(pool, sizeof(*err_info)); 
    822                 err_info->except_code = PJ_GET_EXCEPTION(); 
    823                 err_info->line = scanner->line; 
    824                 err_info->col = scanner->col; 
    825                 err_info->hname = hname; 
    826  
    827                 pj_list_insert_before(err_list, err_info); 
    828             } 
    829  
    830             if (!pj_scan_is_eof(scanner)) { 
    831                 pj_scan_get_until(scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &token); 
    832                 parse_hdr_end(scanner); 
    833             } 
    834         } 
    835         PJ_END; 
    836  
    837         if (hdr) { 
    838812            /* Single parse of header line can produce multiple headers. 
    839813             * For example, if one Contact: header contains Contact list 
     
    843817             */ 
    844818            pj_list_insert_nodes_before(&msg->hdr, hdr); 
    845         } 
    846  
    847         /* Parse until EOF or an empty line is found. */ 
    848     } while (!pj_scan_is_eof(scanner) &&  
    849               *scanner->curptr != '\r' && *scanner->curptr != '\n'); 
     819             
     820            /* Parse until EOF or an empty line is found. */ 
     821        } while (!pj_scan_is_eof(scanner) &&  
     822                  *scanner->curptr != '\r' && *scanner->curptr != '\n'); 
     823         
     824    } 
     825    PJ_CATCH_ANY  
     826    { 
     827        /* Exception was thrown during parsing.  
     828         * Skip until newline, and parse next header.  
     829         */ 
     830        pj_str_t token; 
     831         
     832        if (err_list) { 
     833            pjsip_parser_err_report *err_info; 
     834             
     835            err_info = pj_pool_alloc(pool, sizeof(*err_info)); 
     836            err_info->except_code = PJ_GET_EXCEPTION(); 
     837            err_info->line = scanner->line; 
     838            err_info->col = pj_scan_get_col(scanner); 
     839            err_info->hname = hname; 
     840             
     841            pj_list_insert_before(err_list, err_info); 
     842        } 
     843         
     844        if (!pj_scan_is_eof(scanner)) { 
     845            pj_scan_get(scanner, &pjsip_NOT_NEWLINE, &token); 
     846            parse_hdr_end(scanner); 
     847        } 
     848 
     849        if (!pj_scan_is_eof(scanner) &&  
     850            *scanner->curptr != '\r' && *scanner->curptr != '\n'); 
     851        { 
     852            goto parse_headers; 
     853        } 
     854    } 
     855    PJ_END; 
     856 
    850857 
    851858    /* If empty line is found, eat it. */ 
     
    859866    if (ctype_hdr && scanner->curptr!=scanner->end) { 
    860867        pjsip_msg_body *body = pj_pool_alloc(pool, sizeof(pjsip_msg_body)); 
    861         pj_strdup(pool, &body->content_type.type, &ctype_hdr->media.type); 
    862         pj_strdup(pool, &body->content_type.subtype, &ctype_hdr->media.subtype); 
    863         pj_strdup(pool, &body->content_type.param, &ctype_hdr->media.param); 
     868        body->content_type.type = ctype_hdr->media.type; 
     869        body->content_type.subtype = ctype_hdr->media.subtype; 
     870        body->content_type.param = ctype_hdr->media.param; 
     871 
    864872        body->data = scanner->curptr; 
    865873        body->len = scanner->end - scanner->curptr; 
     
    10021010        is_name_addr = 1; 
    10031011    } else { 
    1004         pj_scan_state backtrack; 
    10051012        pj_str_t scheme; 
    1006         int colon; 
    1007  
    1008         pj_scan_save_state( scanner, &backtrack); 
    1009         pj_scan_get( scanner, &pjsip_TOKEN_SPEC, &scheme); 
    1010         colon = pj_scan_get_char( scanner ); 
    1011         pj_scan_restore_state( scanner, &backtrack); 
    1012  
    1013         if (colon==':' &&  
     1013        int next_ch; 
     1014 
     1015        next_ch = pj_scan_peek( scanner, &pjsip_DISPLAY_SPEC, &scheme); 
     1016 
     1017        if (next_ch==':' &&  
    10141018            (parser_stricmp(scheme, pjsip_SIP_STR)==0 ||  
    10151019             parser_stricmp(scheme, pjsip_SIPS_STR)==0))  
     
    10191023                                   (opt & PJSIP_PARSE_URI_IN_FROM_TO_HDR)== 0); 
    10201024 
    1021         } else if (colon==':' && parser_stricmp( scheme, pjsip_TEL_STR)==0) { 
     1025        } else if (next_ch==':') { 
    10221026 
    10231027            /* Not supported. */ 
     
    11901194         * will be parser later. 
    11911195         */ 
    1192         next = pj_scan_peek_until(scanner, &pjsip_DISPLAY_SCAN_SPEC, &dummy); 
     1196        next = pj_scan_peek(scanner, &pjsip_DISPLAY_SPEC, &dummy); 
    11931197        if (next == '<') { 
    11941198            /* Ok, this is what we're looking for, a display name. */ 
     
    12061210        pj_scan_get_char(scanner); 
    12071211    name_addr->uri = int_parse_uri( scanner, pool, PJ_TRUE ); 
    1208     if (has_bracket) 
    1209         pj_scan_get_char(scanner); 
     1212    if (has_bracket) { 
     1213        if (pj_scan_get_char(scanner) != '>') 
     1214            PJ_THROW( PJSIP_SYN_ERR_EXCEPTION); 
     1215    } 
    12101216 
    12111217    return name_addr; 
     
    12231229 
    12241230    req_line->uri = int_parse_uri(scanner, pool, PJ_TRUE); 
    1225     if (pj_scan_stricmp( scanner, PJSIP_VERSION, 7) != 0) 
     1231    if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION, 7) != 0) 
    12261232        PJ_THROW( PJSIP_SYN_ERR_EXCEPTION); 
    12271233    pj_scan_advance_n (scanner, 7, 1); 
     
    12351241    pj_str_t token; 
    12361242 
    1237     if (pj_scan_stricmp(scanner, PJSIP_VERSION, 7) != 0) 
     1243    if (pj_scan_stricmp_alnum(scanner, PJSIP_VERSION, 7) != 0) 
    12381244        PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); 
    12391245    pj_scan_advance_n( scanner, 7, 1); 
     
    12411247    pj_scan_get( scanner, &pjsip_DIGIT_SPEC, &token); 
    12421248    status_line->code = pj_strtoul(&token); 
    1243     pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC,  
    1244                        &status_line->reason); 
     1249    pj_scan_get( scanner, &pjsip_NOT_NEWLINE, &status_line->reason); 
    12451250    pj_scan_get_newline( scanner ); 
    12461251} 
     
    12681273                                     pj_scanner *scanner) 
    12691274{ 
    1270     pj_scan_get_until( scanner, &pjsip_ARRAY_ELEMENTS, &hdr->values[0]); 
     1275    pj_scan_get( scanner, &pjsip_NOT_COMMA_OR_NEWLINE, &hdr->values[0]); 
    12711276    hdr->count++; 
    12721277 
    12731278    while (*scanner->curptr == ',') { 
    12741279        pj_scan_get_char(scanner); 
    1275         pj_scan_get_until( scanner, &pjsip_ARRAY_ELEMENTS,  
    1276                            &hdr->values[hdr->count]); 
     1280        pj_scan_get( scanner, &pjsip_NOT_COMMA_OR_NEWLINE,  
     1281                     &hdr->values[hdr->count]); 
    12771282        hdr->count++; 
    12781283    } 
     
    12841289                                      pj_scanner *scanner ) 
    12851290{ 
    1286     pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &hdr->hvalue); 
     1291    if (pj_cis_match(&pjsip_NOT_NEWLINE, *scanner->curptr)) 
     1292        pj_scan_get( scanner, &pjsip_NOT_NEWLINE, &hdr->hvalue); 
     1293    else 
     1294        hdr->hvalue.slen = 0; 
     1295 
    12871296    parse_hdr_end(scanner); 
    12881297} 
     
    12931302{ 
    12941303    pj_str_t tmp; 
    1295     pj_scan_get_until( scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &tmp); 
     1304    pj_scan_get( scanner, &pjsip_DIGIT_SPEC, &tmp); 
    12961305    hdr->ivalue = pj_strtoul(&tmp); 
    12971306    parse_hdr_end(scanner); 
     
    13191328{ 
    13201329    pjsip_cid_hdr *hdr = pjsip_cid_hdr_create(ctx->pool); 
    1321     pj_scan_get_until( ctx->scanner, &pjsip_NEWLINE_OR_EOF_SPEC, &hdr->id); 
     1330    pj_scan_get( ctx->scanner, &pjsip_NOT_NEWLINE, &hdr->id); 
    13221331    parse_hdr_end(ctx->scanner); 
    13231332 
     
    17011710            pj_list_insert_before(first, hdr); 
    17021711 
    1703         if (pj_scan_stricmp( scanner, PJSIP_VERSION "/", 8) != 0) 
     1712        if (pj_scan_stricmp_alnum( scanner, PJSIP_VERSION "/", 8) != 0) 
    17041713            PJ_THROW(PJSIP_SYN_ERR_EXCEPTION); 
    17051714 
Note: See TracChangeset for help on using the changeset viewer.