2 * $Id: parse_hname2.c,v 1.19 2004/12/03 17:11:36 jamey Exp $
4 * Fast 32-bit Header Field Name Parser
6 * Copyright (C) 2001-2003 FhG Fokus
8 * This file is part of ser, a free SIP server.
10 * ser is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version
15 * For a license to use the ser software under conditions
16 * other than those described here, or to purchase support for this
17 * software, please contact iptel.org by e-mail at the following addresses:
20 * ser is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 * 2003-02-28 scratchpad compatibility abandoned (jiri)
32 * 2003-01-27 next baby-step to removing ZT - PRESERVE_ZT (jiri)
33 * 2003-05-01 added support for Accept HF (janakj)
37 #include "../comp_defs.h"
38 #include "parse_hname2.h"
40 #include "../ut.h" /* q_memchr */
42 #define LOWER_BYTE(b) ((b) | 0x20)
43 #define LOWER_DWORD(d) ((d) | 0x20202020)
46 * Skip all white-chars and return position of the first
49 static inline char* skip_ws(char* p, unsigned int size)
55 if ((*p != ' ') && (*p != '\t')) return p;
63 #include "case_via.h" /* Via */
64 #include "case_from.h" /* From */
65 #include "case_to.h" /* To */
66 #include "case_cseq.h" /* CSeq */
67 #include "case_call.h" /* Call-ID */
68 #include "case_cont.h" /* Contact, Content-Type, Content-Length, Content-Purpose,
69 * Content-Action, Content-Disposition */
70 #include "case_rout.h" /* Route */
71 #include "case_max.h" /* Max-Forwards */
72 #include "case_reco.h" /* Record-Route */
73 #include "case_auth.h" /* Authorization */
74 #include "case_expi.h" /* Expires */
75 #include "case_prox.h" /* Proxy-Authorization, Proxy-Require */
76 #include "case_allo.h" /* Allow */
77 #include "case_unsu.h" /* Unsupported */
78 #include "case_even.h" /* Event */
79 #include "case_acce.h" /* Accept, Accept-Language */
80 #include "case_orga.h" /* Organization */
81 #include "case_prio.h" /* Priority */
82 #include "case_subj.h" /* Subject */
83 #include "case_user.h" /* User-Agent */
84 #include "case_supp.h" /* Supported */
85 #include "case_dive.h" /* Diversion */
86 #include "case_remo.h" /* Remote-Party-ID */
90 (*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
93 #define FIRST_QUATERNIONS \
94 case _via1_: via1_CASE; \
95 case _from_: from_CASE; \
96 case _to12_: to12_CASE; \
97 case _cseq_: cseq_CASE; \
98 case _call_: call_CASE; \
99 case _cont_: cont_CASE; \
100 case _rout_: rout_CASE; \
101 case _max__: max_CASE; \
102 case _reco_: reco_CASE; \
103 case _via2_: via2_CASE; \
104 case _auth_: auth_CASE; \
105 case _supp_: supp_CASE; \
106 case _expi_: expi_CASE; \
107 case _prox_: prox_CASE; \
108 case _allo_: allo_CASE; \
109 case _unsu_: unsu_CASE; \
110 case _even_: even_CASE; \
111 case _acce_: acce_CASE; \
112 case _orga_: orga_CASE; \
113 case _prio_: prio_CASE; \
114 case _subj_: subj_CASE; \
115 case _user_: user_CASE; \
116 case _dive_: dive_CASE; \
117 case _remo_: remo_CASE;
120 #define PARSE_COMPACT(id) \
134 char* parse_hname2(char* begin, char* end, struct hdr_field* hdr)
137 register unsigned int val;
139 if ((end - begin) < 4) {
140 hdr->type = HDR_ERROR;
146 val = LOWER_DWORD(READ(p));
153 switch(LOWER_BYTE(*p)) {
155 switch(LOWER_BYTE(*(p + 1))) {
169 case 'v': PARSE_COMPACT(HDR_VIA); break;
170 case 'f': PARSE_COMPACT(HDR_FROM); break;
171 case 'i': PARSE_COMPACT(HDR_CALLID); break;
172 case 'm': PARSE_COMPACT(HDR_CONTACT); break;
173 case 'l': PARSE_COMPACT(HDR_CONTENTLENGTH); break;
174 case 'k': PARSE_COMPACT(HDR_SUPPORTED); break;
175 case 'c': PARSE_COMPACT(HDR_CONTENTTYPE); break;
176 case 'o': PARSE_COMPACT(HDR_EVENT); break;
181 /* Double colon hasn't been found yet */
183 p = skip_ws(p, end - p);
187 hdr->name.len = p - hdr->name.s;
191 /* Unknown header type */
193 p = q_memchr(p, ':', end - p);
194 if (!p) { /* No double colon found, error.. */
195 hdr->type = HDR_ERROR;
200 hdr->type = HDR_OTHER;
201 hdr->name.len = p - hdr->name.s;