Version 6.3
Copyright © 2005 - 2012 Lowell D. Thomas
APG
  … ABNF Parser Generator
All Data Structures Files Functions Variables Typedefs Macros Pages
SIPUdtLib.c
Go to the documentation of this file.
1 /*******************************************************************************
2  APG Version 6.3
3  Copyright (C) 2005 - 2012 Lowell D. Thomas, all rights reserved
4 
5  author: Lowell D. Thomas
6  email: lowell@coasttocoastresearch.com
7  website: http://www.coasttocoastresearch.com
8 
9  This program is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 2 of the License, or
12  (at your option) any later version.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program. If not, see
21  <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
22  or write to the Free Software Foundation, Inc.,
23  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 *******************************************************************************/
25 
26 #include "main.h"
33 #define UDTLIB_TAB (apg_achar)9
34 #define UDTLIB_LF (apg_achar)10
35 #define UDTLIB_CR (apg_achar)13
36 #define UDTLIB_SP (apg_achar)32
37 #define UDTLIB_DOUBLE_QUOTE (apg_achar)34
38 #define UDTLIB_SINGLE_QUOTE (apg_achar)39
39 #define UDTLIB_STAR (apg_achar)42
40 #define UDTLIB_PERIOD (apg_achar)46
41 #define UDTLIB_SLASH (apg_achar)47
42 #define UDTLIB_SEMI (apg_achar)59
43 #define UDTLIB_HYPHEN (apg_achar)45
44 #define UDTLIB_0 (apg_achar)48
45 #define UDTLIB_9 (apg_achar)57
46 #define UDTLIB_UPPER_A (apg_achar)65
47 #define UDTLIB_UPPER_F (apg_achar)70
48 #define UDTLIB_UPPER_Z (apg_achar)90
49 #define UDTLIB_UNDERSCORE (apg_achar)95
50 #define UDTLIB_LOWER_A (apg_achar)97
51 #define UDTLIB_LOWER_F (apg_achar)102
52 #define UDTLIB_LOWER_X (apg_achar)120
53 #define UDTLIB_LOWER_Z (apg_achar)122
54 
55 #define UDTLIB_PRINT_MIN (apg_achar)32
56 #define UDTLIB_PRINT_MAX (apg_achar)127
57 
59 // UDT STATIC HELPERS
61 static apg_uint uiIsAlpha(apg_achar acChar){
62  return ((acChar >= UDTLIB_UPPER_A && acChar <= UDTLIB_UPPER_Z) ||
63  (acChar >= UDTLIB_LOWER_A && acChar <= UDTLIB_LOWER_Z));
64 }
65 static apg_uint uiIsDigit(apg_achar acChar){
66  return ((acChar >= UDTLIB_0 && acChar <= UDTLIB_9));
67 }
68 static apg_uint uiIsHexDigit(apg_achar acChar){
69  return ((acChar >= UDTLIB_0 && acChar <= UDTLIB_9) ||
70  (acChar >= UDTLIB_UPPER_A && acChar <= UDTLIB_UPPER_F) ||
71  (acChar >= UDTLIB_LOWER_A && acChar <= UDTLIB_LOWER_F));
72 }
73 static apg_uint uiLineEnd(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength){
74  apg_uint uiRet = 0;
75  if(uiMaxPhraseLength > 0){
76  if(acpPhrase[0] == UDTLIB_LF){uiRet = 1;}
77  else if(acpPhrase[0] == UDTLIB_CR){
78  if(uiMaxPhraseLength > 1 && acpPhrase[1] == UDTLIB_LF){uiRet = 2;}
79  else{uiRet = 1;}
80  }
81  }
82  return uiRet;
83 }
84 static apg_uint uiLineContinue(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength){
85  apg_uint uiRet = 0;
86  apg_uint uiTest;
87  if((0 < uiMaxPhraseLength) && (uiTest = uiLineEnd(&acpPhrase[0], uiMaxPhraseLength))){
88  if((uiTest < uiMaxPhraseLength) && acpPhrase[uiTest] == UDTLIB_SP){
89  uiRet = uiTest + 1;
90  }
91  }
92  return uiRet;
93 }
94 static apg_uint uiWsp(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength){
95  apg_uint uiPhraseCount = 0;
96  apg_uint uiLeft = uiMaxPhraseLength;
97  while(uiLeft > 0){
98  if(acpPhrase[uiPhraseCount] == UDTLIB_SP){uiLeft--;}
99  else if(acpPhrase[uiPhraseCount] == UDTLIB_TAB){uiLeft--;}
100 
101  // uncomment to include line continuations as white space
102 // else if((uiTest = uiLineContinue(&acpPhrase[uiPhraseCount], uiLeft))){uiLeft -= uiTest;}
103 
104  // uncomment any or all of the following to include comments as white space
105 // else if((uiTest = uiSemiComment(&acpPhrase[uiPhraseCount], uiLeft))){uiLeft -= uiTest;}
106 // else if((uiTest = uiCppComment(&acpPhrase[uiPhraseCount], uiLeft))){uiLeft -= uiTest;}
107 // else if((uiTest = uiCComment(&acpPhrase[uiPhraseCount], uiLeft))){uiLeft -= uiTest;}
108  else{break;}
109  uiPhraseCount = uiMaxPhraseLength - uiLeft;
110  }
111 
112  return uiPhraseCount;
113 }
114 
115 static apg_uint uiOneOrMoreAlphaDigit(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength){
116  apg_uint uiPhraseCount;
117  for(uiPhraseCount = 0; uiPhraseCount < uiMaxPhraseLength; uiPhraseCount++){
118  if(!(uiIsAlpha(acpPhrase[uiPhraseCount]) || uiIsDigit(acpPhrase[uiPhraseCount]))){break;}
119  }
120  return uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
121 }
122 static apg_uint uiZeroOrMoreHyphenAlphaDigit(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength){
123  apg_uint uiLen1, uiLen2;
124  apg_uint uiPhraseCount = 0;
125  while(uiPhraseCount < uiMaxPhraseLength){
126  for(uiLen1 = uiPhraseCount; uiLen1 < uiMaxPhraseLength; uiLen1++){
127  if(acpPhrase[uiLen1] != UDTLIB_HYPHEN){break;}
128  }
129  if(uiLen1 == uiPhraseCount){break;}
130 
131  // must be followed by one or more alpha/digit
132  for(uiLen2 = uiLen1; uiLen2 < uiMaxPhraseLength; uiLen2++){
133  if(!(uiIsAlpha(acpPhrase[uiLen2]) || uiIsDigit(acpPhrase[uiLen2]))){break;}
134  }
135  if(uiLen2 == uiLen1){break;}
136  uiPhraseCount = uiLen2;
137  }
138  return uiPhraseCount;
139 }
140 static apg_uint uiAlphaNum(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength){
141  apg_uint uiPhraseCount = 0;
142  if(uiPhraseCount < uiMaxPhraseLength && uiIsAlpha(acpPhrase[uiPhraseCount])){
143  uiPhraseCount++;
144  for(; uiPhraseCount < uiMaxPhraseLength; uiPhraseCount++){
145  if(!(uiIsAlpha(acpPhrase[uiPhraseCount]) || uiIsDigit(acpPhrase[uiPhraseCount]))){break;}
146  }
147  }
148  return uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
149 }
150 static apg_uint uiZeroOrMoreAlphaDigit(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength){
151  apg_uint uiPhraseCount;
152  for(uiPhraseCount = 0; uiPhraseCount < uiMaxPhraseLength; uiPhraseCount++){
153  if(!(uiIsAlpha(acpPhrase[uiPhraseCount]) || uiIsDigit(acpPhrase[uiPhraseCount]))){break;}
154  }
155  return uiPhraseCount;
156 }
157 static apg_uint uiRFC1035label(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength){
158  apg_uint uiPhraseCount = 0;
159  if((uiPhraseCount < uiMaxPhraseLength) && uiIsAlpha(acpPhrase[uiPhraseCount])){
160  uiPhraseCount++;
161  if(uiPhraseCount < uiMaxPhraseLength){
162  uiPhraseCount += uiZeroOrMoreAlphaDigit(&acpPhrase[uiPhraseCount], uiMaxPhraseLength-uiPhraseCount);
163  }
164  if(uiPhraseCount < uiMaxPhraseLength){
165  uiPhraseCount += uiZeroOrMoreHyphenAlphaDigit(&acpPhrase[uiPhraseCount], uiMaxPhraseLength-uiPhraseCount);
166  }
167  }
168  return uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
169 }
170 static apg_uint uiRFC1035subdomain(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength){
171  apg_uint uiPeriod;
172  apg_uint uiLabel;
173  apg_uint uiPhraseCount = uiRFC1035label(acpPhrase, uiMaxPhraseLength);
174  if(uiPhraseCount == APG_UNDEFINED){uiPhraseCount = 0;}
175  else{
176  while(uiPhraseCount < uiMaxPhraseLength){
177  uiPeriod = uiPhraseCount;
178  if(acpPhrase[uiPeriod] == UDTLIB_PERIOD){
179  uiPeriod++;
180  if(uiPeriod < uiMaxPhraseLength){
181  uiLabel = uiRFC1035label(&acpPhrase[uiPeriod], uiMaxPhraseLength-uiPeriod);
182  if(uiLabel != APG_UNDEFINED){
183  uiPhraseCount = uiPeriod + uiLabel;
184  continue;
185  } else{break;}
186  }else{break;}
187  }else{break;}
188  break;
189  }
190  }
191  return uiPhraseCount;
192 }
193 static apg_uint uiSws(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength){
194  apg_uint uiCrlf = 0;
195  apg_uint uiStart2;
196  apg_uint uiWhiteSpace1;
197  apg_uint uiWhiteSpace2;
198  apg_uint uiPhraseCount;
199  //[*WSP CRLF]
200  for(uiWhiteSpace1 = 0; uiWhiteSpace1 < uiMaxPhraseLength; uiWhiteSpace1++){
201  if(!((acpPhrase[uiWhiteSpace1] == UDTLIB_SP) || (acpPhrase[uiWhiteSpace1] == UDTLIB_TAB))){break;}
202  }
203  uiCrlf = uiLineEnd(&acpPhrase[uiWhiteSpace1], uiMaxPhraseLength-uiWhiteSpace1);
204  if(uiCrlf > 0){
205  uiWhiteSpace2 = uiWhiteSpace1 + uiCrlf;
206  uiStart2 = uiWhiteSpace2;
207  }else{
208  uiWhiteSpace2 = 0;
209  uiStart2 = 0;
210  }
211 
212  //1*WSP
213  for(; uiWhiteSpace2 < uiMaxPhraseLength; uiWhiteSpace2++){
214  if(!((acpPhrase[uiWhiteSpace2] == UDTLIB_SP) || (acpPhrase[uiWhiteSpace2] == UDTLIB_TAB))){break;}
215  }
216  uiPhraseCount =(uiWhiteSpace2 > uiStart2) ? uiWhiteSpace2 : uiWhiteSpace1;
217  return uiPhraseCount;
218 }
220 // SIP UDT CALLBACK LIBRARY
222 apg_uint uiSIP_e_domainlabel(APG_CBDATA* spData){
223  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
224  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
225  apg_uint uiPhraseCount = 0;
226  apg_uint uiItLen, uiItCount;
227  while(uiPhraseCount < uiMaxPhraseLength){
228  uiItLen = uiOneOrMoreAlphaDigit(&acpPhrase[uiPhraseCount], uiMaxPhraseLength-uiPhraseCount);
229  if(uiItLen == APG_UNDEFINED){break;}
230  uiItCount = uiItLen + uiPhraseCount;
231  uiItLen = uiZeroOrMoreHyphenAlphaDigit(&acpPhrase[uiItCount], uiMaxPhraseLength-uiItCount);
232  uiItCount += uiItLen;
233  if(uiItCount >= uiMaxPhraseLength){break;}
234  if(acpPhrase[uiItCount] != UDTLIB_PERIOD){break;}
235  uiItCount++;
236  if(!(uiIsAlpha(acpPhrase[uiItCount]) || uiIsDigit(acpPhrase[uiItCount]))){break;}
237  uiPhraseCount = uiItCount;
238  }
239  spData->uiPhraseLength = uiPhraseCount;
240  return 0;
241 }
242 apg_uint uiSIP_u_toplabel(APG_CBDATA* spData){
243  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
244  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
245  apg_uint uiPhraseCount = 0;
246  apg_uint uiLen = uiAlphaNum(acpPhrase, uiMaxPhraseLength);
247  while(APG_TRUE){
248  if((uiLen == APG_UNDEFINED)){break;}
249  uiLen += uiZeroOrMoreHyphenAlphaDigit(&acpPhrase[uiLen], uiMaxPhraseLength-uiLen);
250  if(uiLen >= uiMaxPhraseLength){uiPhraseCount = uiLen;break;}
251  if(acpPhrase[uiLen] == UDTLIB_PERIOD){uiLen++;}
252  uiPhraseCount = uiLen;
253  break;
254  }
255  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
256  return 0;
257 }
258 
259 apg_uint uiSIP_u_token(APG_CBDATA* spData){
260  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
261  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
262  apg_uint uiPhraseCount;
263  for(uiPhraseCount = 0; uiPhraseCount < uiMaxPhraseLength; uiPhraseCount++){
264  apg_achar acChar = acpPhrase[uiPhraseCount];
265  if(uiIsAlpha(acChar)){continue;}
266  if(uiIsDigit(acChar)){continue;}
267  if(acChar == (apg_achar)33){continue;}
268  if(acChar == (apg_achar)37){continue;}
269  if(acChar == (apg_achar)39){continue;}
270  if(acChar == (apg_achar)42){continue;}
271  if(acChar == (apg_achar)43){continue;}
272  if(acChar == (apg_achar)45){continue;}
273  if(acChar == (apg_achar)46){continue;}
274  if(acChar == (apg_achar)95){continue;}
275  if(acChar == (apg_achar)96){continue;}
276  if(acChar == (apg_achar)126){continue;}
277  break;
278  }
279  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
280  return 0;
281 }
282 
283 apg_uint uiSIP_u_unreserved(APG_CBDATA* spData){
284  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
285  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
286  apg_uint uiPhraseCount = 0;
287  while(uiMaxPhraseLength > 0){
288  apg_achar acChar = acpPhrase[0];
289  if(uiIsAlpha(acChar)){uiPhraseCount = 1;break;}
290  if(uiIsDigit(acChar)){uiPhraseCount = 1;break;}
291  if(acChar == (apg_achar)33){uiPhraseCount = 1;break;}
292  if(acChar >= (apg_achar)39 && acChar <= (apg_achar)42){uiPhraseCount = 1;break;}
293  if(acChar == (apg_achar)45){uiPhraseCount = 1;break;}
294  if(acChar == (apg_achar)46){uiPhraseCount = 1;break;}
295  if(acChar == (apg_achar)95){uiPhraseCount = 1;break;}
296  if(acChar == (apg_achar)126){uiPhraseCount = 1;break;}
297  break;
298  }
299  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
300  return 0;
301 }
302 apg_uint uiSIP_u_one_or_more_unreserved(APG_CBDATA* spData){
303  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
304  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
305  apg_uint uiPhraseCount = 0;
306  while(uiPhraseCount < uiMaxPhraseLength){
307  apg_achar acChar = acpPhrase[uiPhraseCount];
308  if(uiIsAlpha(acChar)){uiPhraseCount++;continue;}
309  if(uiIsDigit(acChar)){uiPhraseCount++;continue;}
310  if(acChar == (apg_achar)33){uiPhraseCount++;continue;}
311  if(acChar >= (apg_achar)39 && acChar <= (apg_achar)42){uiPhraseCount++;continue;}
312  if(acChar == (apg_achar)45){uiPhraseCount++;continue;}
313  if(acChar == (apg_achar)46){uiPhraseCount++;continue;}
314  if(acChar == (apg_achar)95){uiPhraseCount++;continue;}
315  if(acChar == (apg_achar)126){uiPhraseCount++;continue;}
316  break;
317  }
318  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
319  return 0;
320 }
321 
322 apg_uint uiSIP_u_scheme(APG_CBDATA* spData){
323  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
324  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
325  apg_uint uiPhraseCount = 0;
326  if(uiIsAlpha(acpPhrase[0])){
327  uiPhraseCount++;
328  for(; uiPhraseCount < uiMaxPhraseLength; uiPhraseCount++){
329  apg_achar acChar = acpPhrase[uiPhraseCount];
330  if(uiIsAlpha(acChar)){continue;}
331  if(uiIsDigit(acChar)){continue;}
332  if(acChar == (apg_achar)'+'){continue;}
333  if(acChar == (apg_achar)'-'){continue;}
334  if(acChar == (apg_achar)'.'){continue;}
335  break;
336  }
337  }
338  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
339  return 0;
340 }
341 
342 apg_uint uiSIP_u_callid(APG_CBDATA* spData){
343  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
344  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
345  apg_uint uiPhraseCount = 0;
346  while(APG_TRUE){
347  for(; uiPhraseCount < uiMaxPhraseLength; uiPhraseCount++){
348  apg_achar acChar = acpPhrase[uiPhraseCount];
349  if(uiIsAlpha(acChar)){continue;}
350  if(uiIsDigit(acChar)){continue;}
351  if(acChar == (apg_achar)'-'){continue;}
352  if(acChar == (apg_achar)'.'){continue;}
353  if(acChar == (apg_achar)'!'){continue;}
354  if(acChar == (apg_achar)'%'){continue;}
355  if(acChar == (apg_achar)'*'){continue;}
356  if(acChar == (apg_achar)'_'){continue;}
357  if(acChar == (apg_achar)'+'){continue;}
358  if(acChar == (apg_achar)'`'){continue;}
359  if(acChar == (apg_achar)'\''){continue;}
360  if(acChar == (apg_achar)'~'){continue;}
361  if(acChar == (apg_achar)'('){continue;}
362  if(acChar == (apg_achar)')'){continue;}
363  if(acChar == (apg_achar)'<'){continue;}
364  if(acChar == (apg_achar)'>'){continue;}
365  if(acChar == (apg_achar)':'){continue;}
366  if(acChar == (apg_achar)'\\'){continue;}
367  if(acChar == (apg_achar)'"'){continue;}
368  if(acChar == (apg_achar)'/'){continue;}
369  if(acChar == (apg_achar)'+'){continue;}
370  if(acChar == (apg_achar)'['){continue;}
371  if(acChar == (apg_achar)']'){continue;}
372  if(acChar == (apg_achar)'?'){continue;}
373  if(acChar == (apg_achar)'{'){continue;}
374  if(acChar == (apg_achar)'}'){continue;}
375  break;
376  }
377  if(uiPhraseCount == 0){break;}
378  if(uiPhraseCount >= uiMaxPhraseLength){break;}
379  if(acpPhrase[uiPhraseCount] != (apg_achar)'@'){break;}
380  uiPhraseCount++;
381  for(; uiPhraseCount < uiMaxPhraseLength; uiPhraseCount++){
382  apg_achar acChar = acpPhrase[uiPhraseCount];
383  if(uiIsAlpha(acChar)){continue;}
384  if(uiIsDigit(acChar)){continue;}
385  if(acChar == (apg_achar)'-'){continue;}
386  if(acChar == (apg_achar)'.'){continue;}
387  if(acChar == (apg_achar)'!'){continue;}
388  if(acChar == (apg_achar)'%'){continue;}
389  if(acChar == (apg_achar)'*'){continue;}
390  if(acChar == (apg_achar)'_'){continue;}
391  if(acChar == (apg_achar)'+'){continue;}
392  if(acChar == (apg_achar)'`'){continue;}
393  if(acChar == (apg_achar)'\''){continue;}
394  if(acChar == (apg_achar)'~'){continue;}
395  if(acChar == (apg_achar)'('){continue;}
396  if(acChar == (apg_achar)')'){continue;}
397  if(acChar == (apg_achar)'<'){continue;}
398  if(acChar == (apg_achar)'>'){continue;}
399  if(acChar == (apg_achar)':'){continue;}
400  if(acChar == (apg_achar)'\\'){continue;}
401  if(acChar == (apg_achar)'"'){continue;}
402  if(acChar == (apg_achar)'/'){continue;}
403  if(acChar == (apg_achar)'+'){continue;}
404  if(acChar == (apg_achar)'['){continue;}
405  if(acChar == (apg_achar)']'){continue;}
406  if(acChar == (apg_achar)'?'){continue;}
407  if(acChar == (apg_achar)'{'){continue;}
408  if(acChar == (apg_achar)'}'){continue;}
409  break;
410  }
411  break;
412  }
413  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
414  return 0;
415 }
416 
417 apg_uint uiSIP_u_rfc1035domain(APG_CBDATA* spData){
418  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
419  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
420  apg_uint uiPhraseCount = 0;
421  if(uiMaxPhraseLength > 0){
422  uiPhraseCount = uiRFC1035subdomain(acpPhrase, uiMaxPhraseLength);
423  if(uiPhraseCount == 0 && acpPhrase[0] == UDTLIB_SP){uiPhraseCount++;}
424 
425  // should fail if ends in "." or "-"
426  if(uiPhraseCount > 0){
427  if((acpPhrase[uiPhraseCount] == UDTLIB_PERIOD) || (acpPhrase[uiPhraseCount] == UDTLIB_HYPHEN)){uiPhraseCount = 0;}
428  }
429  }
430  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
431  return 0;
432 }
433 
434 apg_uint uiSIP_u_LWS(APG_CBDATA* spData){
435  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
436  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
437  apg_uint uiPhraseCount = uiSws(acpPhrase, uiMaxPhraseLength);
438  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
439  return 0;
440 }
441 
442 apg_uint uiSIP_e_SWS(APG_CBDATA* spData){
443  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
444  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
445  spData->uiPhraseLength = uiSws(acpPhrase, uiMaxPhraseLength);
446  return 0;
447 }
448 
449 apg_uint uiSIP_u_HColon(APG_CBDATA* spData){
450  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
451  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
452  apg_uint uiWspLen = 0;
453  apg_uint uiSwsLen = 0;
454  uiWspLen = uiWsp(acpPhrase, uiMaxPhraseLength);
455  uiMaxPhraseLength -= uiWspLen;
456  if(uiMaxPhraseLength){
457  if(acpPhrase[uiWspLen] == (apg_uint)':'){
458  uiMaxPhraseLength--;
459  uiWspLen++;
460  uiSwsLen = uiWspLen + uiSws(&acpPhrase[uiWspLen], uiMaxPhraseLength);
461  }
462  }
463  spData->uiPhraseLength = uiSwsLen ? uiSwsLen : APG_UNDEFINED;
464  return 0;
465 }
466 
467 static apg_uint uiHLetter(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength, apg_achar acLetter){
468  apg_uint uiSwsLen1 = 0;
469  apg_uint uiSwsLen2 = 0;
470  uiSwsLen1 = uiSws(acpPhrase, uiMaxPhraseLength);
471  uiMaxPhraseLength -= uiSwsLen1;
472  if(uiMaxPhraseLength){
473  if(acpPhrase[uiSwsLen1] == acLetter){
474  uiMaxPhraseLength--;
475  uiSwsLen1++;
476  uiSwsLen2 = uiSwsLen1 + uiSws(&acpPhrase[uiSwsLen1], uiMaxPhraseLength);
477  }
478  }
479  return uiSwsLen2;
480 }
481 
482 static apg_uint uiHLeftLetter(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength, apg_achar acLetter){
483  apg_uint uiSwsLen1;
484  uiSwsLen1 = uiSws(acpPhrase, uiMaxPhraseLength);
485  uiMaxPhraseLength -= uiSwsLen1;
486  if(uiMaxPhraseLength){
487  if(acpPhrase[uiSwsLen1] == acLetter){
488  uiSwsLen1++;
489  } else{uiSwsLen1 = 0;}
490  }
491  return uiSwsLen1;
492 }
493 
494 static apg_uint uiHRightLetter(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength, apg_achar acLetter){
495  apg_uint uiSwsLen1 = 0;
496  if(uiMaxPhraseLength){
497  if(acpPhrase[uiSwsLen1] == acLetter){
498  uiSwsLen1 = 1 + uiSws(&acpPhrase[uiSwsLen1], uiMaxPhraseLength);
499  }
500  }
501  return uiSwsLen1;
502 }
503 
504 apg_uint uiSIP_u_Comma(APG_CBDATA* spData){
505  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
506  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
507  apg_uint uiPhraseCount = uiHLetter(acpPhrase, uiMaxPhraseLength, (apg_achar)',');
508  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
509  return 0;
510 }
511 
512 apg_uint uiSIP_u_Semi(APG_CBDATA* spData){
513  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
514  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
515  apg_uint uiPhraseCount = uiHLetter(acpPhrase, uiMaxPhraseLength, (apg_achar)';');
516  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
517  return 0;
518 }
519 
520 apg_uint uiSIP_u_Slash(APG_CBDATA* spData){
521  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
522  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
523  apg_uint uiPhraseCount = uiHLetter(acpPhrase, uiMaxPhraseLength, (apg_achar)'/');
524  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
525  return 0;
526 }
527 
528 apg_uint uiSIP_u_Equal(APG_CBDATA* spData){
529  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
530  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
531  apg_uint uiPhraseCount = uiHLetter(acpPhrase, uiMaxPhraseLength, (apg_achar)'=');
532  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
533  return 0;
534 }
535 
536 apg_uint uiSIP_u_Star(APG_CBDATA* spData){
537  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
538  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
539  apg_uint uiPhraseCount = uiHLetter(acpPhrase, uiMaxPhraseLength, (apg_achar)'*');
540  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
541  return 0;
542 }
543 
544 apg_uint uiSIP_u_Colon(APG_CBDATA* spData){
545  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
546  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
547  apg_uint uiPhraseCount = uiHLetter(acpPhrase, uiMaxPhraseLength, (apg_achar)':');
548  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
549  return 0;
550 }
551 
552 apg_uint uiSIP_u_LParen(APG_CBDATA* spData){
553  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
554  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
555  apg_uint uiPhraseCount = uiHLetter(acpPhrase, uiMaxPhraseLength, (apg_achar)'(');
556  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
557  return 0;
558 }
559 
560 apg_uint uiSIP_u_RParen(APG_CBDATA* spData){
561  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
562  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
563  apg_uint uiPhraseCount = uiHLetter(acpPhrase, uiMaxPhraseLength, (apg_achar)')');
564  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
565  return 0;
566 }
567 
568 apg_uint uiSIP_u_RAQuot(APG_CBDATA* spData){
569  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
570  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
571  apg_uint uiPhraseCount = uiHRightLetter(acpPhrase, uiMaxPhraseLength, (apg_achar)'>');
572  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
573  return 0;
574 }
575 
576 apg_uint uiSIP_u_LAQuot(APG_CBDATA* spData){
577  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
578  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
579  apg_uint uiPhraseCount = uiHLeftLetter(acpPhrase, uiMaxPhraseLength, (apg_achar)'<');
580  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
581  return 0;
582 }
583 
584 apg_uint uiSIP_u_RDQuot(APG_CBDATA* spData){
585  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
586  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
587  apg_uint uiPhraseCount = uiHRightLetter(acpPhrase, uiMaxPhraseLength, (apg_achar)34);
588  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
589  return 0;
590 }
591 
592 apg_uint uiSIP_u_LDQuot(APG_CBDATA* spData){
593  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
594  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
595  apg_uint uiPhraseCount = uiHLeftLetter(acpPhrase, uiMaxPhraseLength, (apg_achar)34);
596  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
597  return 0;
598 }
599 
600 apg_uint uiSIP_u_LHEX(APG_CBDATA* spData){
601  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
602  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
603  apg_uint uiPhraseCount = 0;
604  if(uiMaxPhraseLength){
605  if(uiIsDigit(acpPhrase[0]) ||
606  ((acpPhrase[0] >= (apg_achar)97) && (acpPhrase[0]) <= (apg_achar)102)){uiPhraseCount++;}
607  }
608  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
609  return 0;
610 }
611 
612 apg_uint uiSIP_u_nc_value(APG_CBDATA* spData){
613  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
614  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
615  apg_uint uiPhraseCount = 0;
616  while(uiPhraseCount < uiMaxPhraseLength){
617  if(uiIsDigit(acpPhrase[uiPhraseCount]) ||
618  ((acpPhrase[uiPhraseCount] >= (apg_achar)97) && (acpPhrase[uiPhraseCount]) <= (apg_achar)102)){uiPhraseCount++;}
619  else{break;}
620  }
621  spData->uiPhraseLength = (uiPhraseCount == 8) ? uiPhraseCount : APG_UNDEFINED;
622  return 0;
623 }
624 
625 apg_uint uiSIP_u_request_digest(APG_CBDATA* spData){
626  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
627  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
628  apg_uint uiPhraseCount = 0;
629  apg_uint uiHex;
630  apg_uint uiRDQuot;
631  apg_uint uiLDQuot = uiHLeftLetter(acpPhrase, uiMaxPhraseLength, (apg_achar)34);
632  if(uiLDQuot){
633  uiHex = uiLDQuot;
634  while(uiHex < uiMaxPhraseLength){
635  if(uiIsDigit(acpPhrase[uiHex]) ||
636  ((acpPhrase[uiHex] >= (apg_achar)97) && (acpPhrase[uiHex]) <= (apg_achar)102)){uiHex++;}
637  else{break;}
638  }
639  if(uiHex == (uiLDQuot + 32)){
640  uiRDQuot = uiHRightLetter(&acpPhrase[uiHex], uiMaxPhraseLength-uiHex, (apg_achar)34);
641  if(uiRDQuot){uiPhraseCount = uiHex + uiRDQuot;}
642  }
643  }
644  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
645  return 0;
646 }
647 
648 apg_uint uiSIP_e_MessageBody(APG_CBDATA* spData){
649  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
650  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
651  apg_uint uiPhraseCount = 0;
652  for(; uiPhraseCount < uiMaxPhraseLength; uiPhraseCount++){
653  if(acpPhrase[uiPhraseCount] > (apg_achar)255){break;}
654  }
655  spData->uiPhraseLength = uiPhraseCount;
656  return 0;
657 }
658 
659 static apg_uint uiEscaped(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength){
660  apg_uint uiRet = 0;
661  if(uiMaxPhraseLength >= 3){
662  if((acpPhrase[0] == (apg_achar)'%') && uiIsHexDigit(acpPhrase[1]) && uiIsHexDigit(acpPhrase[2])){uiRet = 3;}
663  }
664  return uiRet;
665 }
666 static apg_uint uiParamChars(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength){
667  apg_uint uiEscapedLen;
668  apg_uint uiPhraseCount = 0;
669  while(uiPhraseCount < uiMaxPhraseLength){
670  apg_achar acChar = acpPhrase[uiPhraseCount];
671  if(uiIsAlpha(acChar)){uiPhraseCount++;continue;}
672  if(uiIsDigit(acChar)){uiPhraseCount++;continue;}
673  if(acChar == (apg_achar)33){uiPhraseCount++;continue;}
674  if(acChar >= (apg_achar)39 && acChar <= (apg_achar)42){uiPhraseCount++;continue;}
675  if(acChar == (apg_achar)45){uiPhraseCount++;continue;}
676  if(acChar == (apg_achar)46){uiPhraseCount++;continue;}
677  if(acChar == (apg_achar)95){uiPhraseCount++;continue;}
678  if(acChar == (apg_achar)126){uiPhraseCount++;continue;}
679  if(acChar == (apg_achar)'['){uiPhraseCount++;continue;}
680  if(acChar == (apg_achar)']'){uiPhraseCount++;continue;}
681  if(acChar == (apg_achar)'/'){uiPhraseCount++;continue;}
682  if(acChar == (apg_achar)':'){uiPhraseCount++;continue;}
683  if(acChar == (apg_achar)'&'){uiPhraseCount++;continue;}
684  if(acChar == (apg_achar)'+'){uiPhraseCount++;continue;}
685  if(acChar == (apg_achar)'&'){uiPhraseCount++;continue;}
686  // escaped
687  uiEscapedLen = uiEscaped(&acpPhrase[uiPhraseCount], uiMaxPhraseLength-uiPhraseCount);
688  if(uiEscapedLen){uiPhraseCount += uiEscapedLen;continue;}
689  break;
690  }
691  return uiPhraseCount;
692 }
693 apg_uint uiSIP_u_escaped(APG_CBDATA* spData){
694  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
695  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
696  apg_uint uiPhraseCount = uiEscaped(acpPhrase, uiMaxPhraseLength);
697  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
698  return 0;
699 }
700 apg_uint uiSIP_u_pname(APG_CBDATA* spData){
701  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
702  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
703  apg_uint uiPhraseCount = uiParamChars(acpPhrase, uiMaxPhraseLength);
704  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
705  return 0;
706 }
707 apg_uint uiSIP_u_pvalue(APG_CBDATA* spData){
708  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
709  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
710  apg_uint uiPhraseCount = uiParamChars(acpPhrase, uiMaxPhraseLength);
711  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
712  return 0;
713 }
714 
715 static apg_uint uiUtf8Cont(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength){
716  apg_uint uiPhraseCount = 0;
717  while(uiPhraseCount < uiMaxPhraseLength){
718  apg_achar acChar = acpPhrase[uiPhraseCount];
719  if(acChar >= 0x80 && acChar <= 0xbf){uiPhraseCount++;}
720  else{break;}
721  }
722  return uiPhraseCount;
723 }
724 
725 
726 static apg_uint uiTextUtf8Char(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength){
727  apg_uint uiLen, uiCont;
728  apg_uint uiPhraseCount = 0;
729  while(uiPhraseCount < uiMaxPhraseLength){
730  apg_achar acChar = acpPhrase[uiPhraseCount];
731 
732  // ASCII
733  if(acChar >= 0x21 && acChar <= 0x7e){uiPhraseCount++;}
734 
735  // UTF8-NONASCII
736  else if(acChar >= 0xc0 && acChar <= 0xdf){
737  uiLen = uiPhraseCount + 1;
738  uiCont = uiUtf8Cont(&acpPhrase[uiLen], uiMaxPhraseLength-uiLen);
739  if(uiCont == 1){uiPhraseCount += 2;}
740  else{break;}
741  }else if(acChar >= 0xe0 && acChar <= 0xef){
742  uiLen = uiPhraseCount + 1;
743  uiCont = uiUtf8Cont(&acpPhrase[uiLen], uiMaxPhraseLength-uiLen);
744  if(uiCont == 2){uiPhraseCount += 3;}
745  else{break;}
746  }else if(acChar >= 0xf0 && acChar <= 0xf7){
747  uiLen = uiPhraseCount + 1;
748  uiCont = uiUtf8Cont(&acpPhrase[uiLen], uiMaxPhraseLength-uiLen);
749  if(uiCont == 3){uiPhraseCount += 4;}
750  else{break;}
751  }else if(acChar >= 0xf8 && acChar <= 0xfb){
752  uiLen = uiPhraseCount + 1;
753  uiCont = uiUtf8Cont(&acpPhrase[uiLen], uiMaxPhraseLength-uiLen);
754  if(uiCont == 4){uiPhraseCount += 5;}
755  else{break;}
756  }else if(acChar >= 0xfc && acChar <= 0xfd){
757  uiLen = uiPhraseCount + 1;
758  uiCont = uiUtf8Cont(&acpPhrase[uiLen], uiMaxPhraseLength-uiLen);
759  if(uiCont == 5){uiPhraseCount += 6;}
760  else{break;}
761  }else{break;}
762  }
763  return uiPhraseCount;
764 }
765 
766 apg_uint uiSIP_e_text_utf8trim(APG_CBDATA* spData){
767  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
768  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
769  apg_uint uiPhraseCount = uiTextUtf8Char(acpPhrase, uiMaxPhraseLength);
770  apg_uint uiLws, uiMoreText;
771  while(uiPhraseCount < uiMaxPhraseLength){
772  uiLws = uiSws(&acpPhrase[uiPhraseCount], uiMaxPhraseLength-uiPhraseCount);
773  if(uiLws){
774  uiMoreText = uiTextUtf8Char(&acpPhrase[uiPhraseCount+uiLws], uiMaxPhraseLength-uiPhraseCount-uiLws);
775  if(uiMoreText){
776  uiPhraseCount += uiLws + uiMoreText;
777  }else{break;}
778  }else{break;}
779  }
780  spData->uiPhraseLength = uiPhraseCount;
781  return 0;
782 }
783 
784 apg_uint uiSIP_u_extension_header(APG_CBDATA* spData){
785  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
786  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
787  apg_uint uiPhraseCount = 0;
788  apg_uint uiText;
789  while(uiPhraseCount < uiMaxPhraseLength){
790  uiText = uiTextUtf8Char(&acpPhrase[uiPhraseCount], uiMaxPhraseLength-uiPhraseCount);
791  if(uiText){uiPhraseCount += uiText;continue;}
792  uiText = uiUtf8Cont(&acpPhrase[uiPhraseCount], uiMaxPhraseLength-uiPhraseCount);
793  if(uiText){uiPhraseCount += uiText;continue;}
794  uiText = uiSws(&acpPhrase[uiPhraseCount], uiMaxPhraseLength-uiPhraseCount);
795  if(uiText){uiPhraseCount += uiText;continue;}
796  break;
797  }
798  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
799  return 0;
800 }
801 
802 apg_uint uiSIP_u_OneOrMoreDigit(APG_CBDATA* spData){
803  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
804  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
805  apg_uint uiPhraseCount = 0;
806  for(;uiPhraseCount < uiMaxPhraseLength; uiPhraseCount++){
807  if(!uiIsDigit(acpPhrase[uiPhraseCount])){break;}
808  }
809  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
810  return 0;
811 }
812 apg_uint uiSIP_e_digit(APG_CBDATA* spData){
813  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
814  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
815  apg_uint uiPhraseCount = 0;
816  for(;uiPhraseCount < uiMaxPhraseLength; uiPhraseCount++){
817  if(!uiIsDigit(acpPhrase[uiPhraseCount])){break;}
818  }
819  spData->uiPhraseLength = uiPhraseCount;
820  return 0;
821 }
822 apg_uint uiSIP_u_CRLF(APG_CBDATA* spData){
823  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
824  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
825  apg_uint uiPhraseCount = uiLineEnd(acpPhrase, uiMaxPhraseLength);
826  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
827  return 0;
828 }
829 
830 apg_uint uiSIP_u_IPv4address(APG_CBDATA* spData){
831  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
832  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
833  apg_uint uiPhraseCount = 0;
834  apg_uint i;
835  apg_uint uiLenEven = 0;
836  apg_uint uiLenOdd = 0;
837  while(uiPhraseCount < uiMaxPhraseLength){
838  for(i = 0; i < 3 && uiLenEven < uiMaxPhraseLength; i++, uiLenEven++){
839  if(!uiIsDigit(acpPhrase[uiLenEven])){break;}
840  }
841  if(uiLenEven == uiLenOdd){break;}
842  if(!(acpPhrase[uiLenEven] != (apg_achar)':')){break;}
843 
844  uiLenOdd = uiLenEven + 1;
845  for(i = 0; i < 3 && uiLenOdd < uiMaxPhraseLength; i++, uiLenOdd++){
846  if(!uiIsDigit(acpPhrase[uiLenOdd])){break;}
847  }
848  if(uiLenEven == uiLenOdd){break;}
849  if(!(acpPhrase[uiLenOdd] != (apg_achar)':')){break;}
850 
851  uiLenEven = uiLenOdd +1;
852  for(i = 0; i < 3 && uiLenEven < uiMaxPhraseLength; i++, uiLenEven++){
853  if(!uiIsDigit(acpPhrase[uiLenEven])){break;}
854  }
855  if(uiLenEven == uiLenOdd){break;}
856  if(!(acpPhrase[uiLenEven] != (apg_achar)':')){break;}
857 
858  uiLenOdd = uiLenEven + 1;
859  for(i = 0; i < 3 && uiLenOdd < uiMaxPhraseLength; i++, uiLenOdd++){
860  if(!uiIsDigit(acpPhrase[uiLenOdd])){break;}
861  }
862  if(uiLenEven == uiLenOdd){break;}
863  uiPhraseCount = uiLenOdd;
864  break;
865  }
866  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
867  return 0;
868 }
869 
870 apg_uint uiSIP_u_user(APG_CBDATA* spData){
871  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
872  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
873  apg_uint uiPhraseCount = 0;
874  apg_uint uiEscLen;
875  while(uiPhraseCount < uiMaxPhraseLength){
876  apg_achar acChar = acpPhrase[uiPhraseCount];
877 
878  // u_one-or-more-unreserved
879  if(uiIsAlpha(acChar)){uiPhraseCount++;continue;}
880  if(uiIsDigit(acChar)){uiPhraseCount++;continue;}
881  if(acChar == (apg_achar)33){uiPhraseCount++;continue;}
882  if(acChar >= (apg_achar)39 && acChar <= (apg_achar)42){uiPhraseCount++;continue;}
883  if(acChar == (apg_achar)45){uiPhraseCount++;continue;}
884  if(acChar == (apg_achar)46){uiPhraseCount++;continue;}
885  if(acChar == (apg_achar)95){uiPhraseCount++;continue;}
886  if(acChar == (apg_achar)126){uiPhraseCount++;continue;}
887 
888  // user-unreserved
889  if(acChar == (apg_achar)'&'){uiPhraseCount++;continue;}
890  if(acChar == (apg_achar)'='){uiPhraseCount++;continue;}
891  if(acChar == (apg_achar)'+'){uiPhraseCount++;continue;}
892  if(acChar == (apg_achar)'$'){uiPhraseCount++;continue;}
893  if(acChar == (apg_achar)','){uiPhraseCount++;continue;}
894  if(acChar == (apg_achar)';'){uiPhraseCount++;continue;}
895  if(acChar == (apg_achar)'?'){uiPhraseCount++;continue;}
896  if(acChar == (apg_achar)'/'){uiPhraseCount++;continue;}
897 
898  // u_escaped
899  uiEscLen = uiEscaped(&acpPhrase[uiPhraseCount], uiMaxPhraseLength-uiPhraseCount);
900  if(uiEscLen){uiPhraseCount += uiEscLen;continue;}
901  break;
902  }
903  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
904  return 0;
905 }
906 
907 apg_uint uiSIP_u_quoted_string(APG_CBDATA* spData){
908  const apg_achar* acpPhrase = spData->acpSrc + spData->uiPhraseOffset;
909  apg_uint uiMaxPhraseLength = spData->uiSrcLen - spData->uiPhraseOffset;
910  const apg_achar* acpNextPhrase;
911  apg_uint uiNextMax;
912  apg_uint uiPhraseCount = 0;
913  apg_uint uiLen;
914  apg_uint uiQuotedPair, uiNonAscii, uiTest;
915  apg_achar acChar;
916  while(APG_TRUE){
917  // e_SWS
918  uiLen = uiSws(acpPhrase, uiMaxPhraseLength);
919  if(uiLen >= uiMaxPhraseLength){break;}
920 
921  // %x22 ('"')
922  if(acpPhrase[uiLen] != (apg_achar)'"'){break;}
923  uiLen++;
924  if(uiLen >= uiMaxPhraseLength){break;}
925 
926  // q-string
927  while(uiLen < uiMaxPhraseLength){
928  acpNextPhrase = &acpPhrase[uiLen];
929  uiNextMax = uiMaxPhraseLength - uiLen;
930 
931  // qdtext
932  uiTest = uiSws(acpNextPhrase, uiNextMax);
933  if(uiTest){uiLen += uiTest;continue;}
934  // ASCII except '"' and '\'
935  acChar = acpPhrase[uiLen];
936  if(acChar == (apg_achar)0x21){uiLen++;continue;}
937  if(acChar >= (apg_achar)0x23 && acChar <= (apg_achar)0x5b){uiLen++;continue;}
938  if(acChar >= (apg_achar)0x5d && acChar <= (apg_achar)0x7e){uiLen++;continue;}
939  // UTF8-NONASCII
940  uiNonAscii = uiLen;
941  while(uiNonAscii < uiMaxPhraseLength){
942  if(acChar >= 0xc0 && acChar <= 0xdf){
943  uiTest = uiNonAscii + 1;
944  acpNextPhrase = &acpPhrase[uiTest];
945  uiNextMax = uiMaxPhraseLength - uiTest;
946  uiTest = uiUtf8Cont(acpNextPhrase, uiNextMax);
947  if(uiTest == 1){uiNonAscii += 2;}
948  else{break;}
949  }else if(acChar >= 0xe0 && acChar <= 0xef){
950  uiTest = uiNonAscii + 1;
951  acpNextPhrase = &acpPhrase[uiTest];
952  uiNextMax = uiMaxPhraseLength - uiTest;
953  uiTest = uiUtf8Cont(acpNextPhrase, uiNextMax);
954  if(uiTest == 2){uiNonAscii += 3;}
955  else{break;}
956  }else if(acChar >= 0xf0 && acChar <= 0xf7){
957  uiTest = uiNonAscii + 1;
958  acpNextPhrase = &acpPhrase[uiTest];
959  uiNextMax = uiMaxPhraseLength - uiTest;
960  uiTest = uiUtf8Cont(acpNextPhrase, uiNextMax);
961  if(uiTest == 3){uiNonAscii += 4;}
962  else{break;}
963  }else if(acChar >= 0xf8 && acChar <= 0xfb){
964  uiTest = uiNonAscii + 1;
965  acpNextPhrase = &acpPhrase[uiTest];
966  uiNextMax = uiMaxPhraseLength - uiTest;
967  uiTest = uiUtf8Cont(acpNextPhrase, uiNextMax);
968  if(uiTest == 4){uiNonAscii += 5;}
969  else{break;}
970  }else if(acChar >= 0xfc && acChar <= 0xfd){
971  uiTest = uiNonAscii + 1;
972  acpNextPhrase = &acpPhrase[uiTest];
973  uiNextMax = uiMaxPhraseLength - uiTest;
974  uiTest = uiUtf8Cont(acpNextPhrase, uiNextMax);
975  if(uiTest == 5){uiNonAscii += 6;}
976  else{break;}
977  }else{break;}
978  break;
979  }
980  if(uiNonAscii > uiLen){uiLen = uiNonAscii;continue;}
981 
982  // quoted-pair
983  uiQuotedPair = uiLen;
984  while(APG_TRUE){
985  acpNextPhrase = &acpPhrase[uiQuotedPair];
986  uiNextMax = uiMaxPhraseLength - uiQuotedPair;
987  if(*acpNextPhrase != (apg_achar)'\\'){break;}
988  uiQuotedPair++;
989  if(uiQuotedPair >= uiMaxPhraseLength){break;}
990  acChar = acpPhrase[uiQuotedPair];
991  if(acChar <= (apg_achar)0x09){uiQuotedPair++;break;}
992  if(acChar >= (apg_achar)0x0b && acChar <= (apg_achar)0x0c){uiQuotedPair++;break;}
993  if(acChar >= (apg_achar)0x0e && acChar <= (apg_achar)0x7f){uiQuotedPair++;break;}
994  break;
995  }
996  if(uiQuotedPair != uiLen + 2){break;}
997  uiLen += 2;
998  }
999 
1000  // %x22 ('"')
1001  if(uiLen >= uiMaxPhraseLength){break;}
1002  acChar = acpPhrase[uiLen];
1003  if(acpPhrase[uiLen] != (apg_achar)'"'){break;}
1004  uiPhraseCount = uiLen + 1;
1005  break;
1006  }
1007  spData->uiPhraseLength = uiPhraseCount ? uiPhraseCount : APG_UNDEFINED;
1008  return 0;
1009 }
1010 
1011 enum {
1012  MSG_HDR_Accept = 0
1013 , MSG_HDR_Accept_Encoding
1014 , MSG_HDR_Accept_Language
1015 , MSG_HDR_Alert_Info
1016 , MSG_HDR_Allow
1017 , MSG_HDR_Authentication_Info
1018 , MSG_HDR_Authorization
1019 , MSG_HDR_Call_ID
1020 , MSG_HDR_Call_Info
1021 , MSG_HDR_Contact
1022 , MSG_HDR_Content_Disposition
1023 , MSG_HDR_Content_Encoding
1024 , MSG_HDR_Content_Language
1025 , MSG_HDR_Content_Length
1026 , MSG_HDR_Content_Type
1027 , MSG_HDR_CSeq
1028 , MSG_HDR_Date
1029 , MSG_HDR_Error_Info
1030 , MSG_HDR_Expires
1031 , MSG_HDR_From
1032 , MSG_HDR_In_Reply_To
1033 , MSG_HDR_Max_Forwards
1034 , MSG_HDR_MIME_Version
1035 , MSG_HDR_Min_Expires
1036 , MSG_HDR_Organization
1037 , MSG_HDR_Priority
1038 , MSG_HDR_Proxy_Authenticate
1039 , MSG_HDR_Proxy_Authorization
1040 , MSG_HDR_Proxy_Require
1041 , MSG_HDR_Record_Route
1042 , MSG_HDR_Reply_To
1043 , MSG_HDR_Require
1044 , MSG_HDR_Retry_After
1045 , MSG_HDR_Route
1046 , MSG_HDR_Server
1047 , MSG_HDR_Subject
1048 , MSG_HDR_Supported
1049 , MSG_HDR_Timestamp
1050 , MSG_HDR_To
1051 , MSG_HDR_Unsupported
1052 , MSG_HDR_User_Agent
1053 , MSG_HDR_Via
1054 , MSG_HDR_Warning
1055 , MSG_HDR_WWW_Authenticate
1056 , MSG_HDR_extension_header
1057 , MSG_HDR_COUNT
1058 };
1059 typedef struct{
1060  char* cpName;
1061  apg_uint uiLength;
1062 } BNAMES;
1063 static BNAMES saHdrNames[] = {
1064  {"accept", 6},
1065  {"accept-encoding", 15},
1066  {"accept-language", 15},
1067  {"alert-info", 10},
1068  {"allow", 5},
1069  {"authentication-info", 19},
1070  {"authorization", 13},
1071  {"call-id", 7},
1072  {"call-info", 9},
1073  {"contact", 7},
1074  {"content-disposition", 19},
1075  {"content-encoding", 16},
1076  {"content-language", 16},
1077  {"content-length", 14},
1078  {"content-type", 12},
1079  {"cseq", 4},
1080  {"date", 4},
1081  {"error-info", 10},
1082  {"expires", 7},
1083  {"from", 4},
1084  {"in-reply-to", 11},
1085  {"maxforwards", 11},
1086  {"mime-version", 12},
1087  {"min-expires", 11},
1088  {"organization", 12},
1089  {"priority", 8},
1090  {"proxy-authenticate", 18},
1091  {"proxy-authorization", 19},
1092  {"proxy-require", 13},
1093  {"record-route", 12},
1094  {"reply-to", 8},
1095  {"require", 7},
1096  {"retry-after", 11},
1097  {"route", 5},
1098  {"server", 6},
1099  {"subject", 7},
1100  {"supported", 9},
1101  {"timestamp", 9},
1102  {"to", 2},
1103  {"unsupported", 11},
1104  {"user-agent", 10},
1105  {"via", 3},
1106  {"warning", 7},
1107  {"www-authenticate", 16},
1108 };
1109 static apg_uint uiACharStricmp(const apg_achar* acpPhrase, apg_uint uiPhraseLength, BNAMES* spNames){
1110  apg_uint uiRet = 0;
1111  apg_uint i;
1112  char cChar;
1113  if(uiPhraseLength == spNames->uiLength){
1114  uiRet = uiPhraseLength;
1115  for(i = 0; i < uiPhraseLength; i++){
1116  cChar = (char)acpPhrase[i];
1117  if(cChar >= (char)65 && cChar <= (char)90){cChar += 32;}
1118  if(cChar != spNames->cpName[i]){uiRet = 0;break;}
1119  }
1120  }
1121  return uiRet;
1122 }
1123 static apg_uint uiMsgHdrName(const apg_achar* acpPhrase, apg_uint uiMaxPhraseLength, apg_uint* uipName, apg_uint* uipIsUdt){
1124  apg_uint uiHdr = 0;
1125  apg_uint uiNameId = UDT_GRAMMAR5_U_EXTENSION_HEADER;
1126  apg_uint uiIsUdt = APG_TRUE;
1127  apg_uint uiHColon;
1128  apg_uint uiNameLen = 0;
1129  apg_uint uiLen;
1130  char cChar;
1131  while(APG_TRUE){
1132  // get the name
1133  for(; uiNameLen < uiMaxPhraseLength; uiNameLen++){
1134  if(acpPhrase[uiNameLen] == (apg_achar)32 ||
1135  acpPhrase[uiNameLen] == (apg_achar)9 ||
1136  acpPhrase[uiNameLen] == (apg_achar)':'){break;}
1137  }
1138  if(uiNameLen == 0){break;} // name length must be > 0
1139 
1140  // get position of header
1141  for(uiHColon = uiNameLen; uiHColon < uiMaxPhraseLength; uiHColon++){
1142  if(!(acpPhrase[uiHColon] == (apg_achar)32 || acpPhrase[uiHColon] == (apg_achar)9)){break;}
1143  }
1144  if(acpPhrase[uiHColon] != (apg_achar)':'){break;} // end of space must be colon
1145  uiHdr = uiHColon + 1;
1146  while(uiHdr < uiMaxPhraseLength){
1147  if(acpPhrase[uiHdr] == (apg_achar)32){uiHdr++;continue;}
1148  if(acpPhrase[uiHdr] == (apg_achar)9){uiHdr++;continue;}
1149  uiLen = uiLineContinue(&acpPhrase[uiHdr], uiMaxPhraseLength-uiHdr);
1150  if(uiLen){uiHdr += uiLen;continue;}
1151  break;
1152  }
1153 
1154  cChar = (char)acpPhrase[0];
1155  if(cChar >= (char)65 && cChar <= (char)90){cChar += 32;}
1156  if(uiNameLen == 1){
1157  // get the abreviated header name
1158  switch(cChar){
1159  case 'i': uiNameId = UDT_GRAMMAR5_U_CALLID; uiIsUdt = APG_TRUE; break;
1160  case 'm': uiNameId = RULE_GRAMMAR5_CONTACT; uiIsUdt = APG_FALSE; break;
1161  case 'e': uiNameId = RULE_GRAMMAR5_CONTENT_ENCODING; uiIsUdt = APG_FALSE; break;
1162  case 'l': uiNameId = RULE_GRAMMAR5_CONTENT_LENGTH; uiIsUdt = APG_FALSE; break;
1163  case 'c': uiNameId = RULE_GRAMMAR5_CONTENT_TYPE; uiIsUdt = APG_FALSE; break;
1164  case 'f': uiNameId = RULE_GRAMMAR5_FROM; uiIsUdt = APG_FALSE; break;
1165  case 's': uiNameId = RULE_GRAMMAR5_SUBJECT; uiIsUdt = APG_FALSE; break;
1166  case 'k': uiNameId = RULE_GRAMMAR5_SUPPORTED; uiIsUdt = APG_FALSE; break;
1167  case 't': uiNameId = RULE_GRAMMAR5_TO; uiIsUdt = APG_FALSE; break;
1168  case 'v': uiNameId = RULE_GRAMMAR5_VIA; uiIsUdt = APG_FALSE; break;
1169  }
1170  } else{
1171  // identify the full header name
1172  switch(cChar){
1173  case 'a':
1174  switch(uiNameLen){
1175  case 5:
1176  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Allow]) == uiNameLen){
1177  uiNameId = RULE_GRAMMAR5_ALLOW;
1178  uiIsUdt = APG_FALSE;
1179  }
1180  break;
1181  case 6:
1182  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Accept]) == uiNameLen){
1183  uiNameId = RULE_GRAMMAR5_ACCEPT;
1184  uiIsUdt = APG_FALSE;
1185  }
1186  break;
1187  case 10:
1188  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Alert_Info]) == uiNameLen){
1189  uiNameId = RULE_GRAMMAR5_ALERT_INFO;
1190  uiIsUdt = APG_FALSE;
1191  }
1192  break;
1193  case 13:
1194  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Authorization]) == uiNameLen){
1195  uiNameId = RULE_GRAMMAR5_AUTHORIZATION;
1196  uiIsUdt = APG_FALSE;
1197  }
1198  break;
1199  case 15:
1200  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Accept_Encoding]) == uiNameLen){
1201  uiNameId = RULE_GRAMMAR5_ACCEPT_ENCODING;
1202  uiIsUdt = APG_FALSE;
1203  }else if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Accept_Language]) == uiNameLen){
1204  uiNameId = RULE_GRAMMAR5_ACCEPT_LANGUAGE;
1205  uiIsUdt = APG_FALSE;
1206  }
1207  break;
1208  case 19:
1209  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Authentication_Info]) == uiNameLen){
1210  uiNameId = RULE_GRAMMAR5_AUTHENTICATION_INFO;
1211  uiIsUdt = APG_FALSE;
1212  }
1213  break;
1214  default:
1215  break;
1216  }
1217  break;
1218  case 'c':
1219  switch(uiNameLen){
1220  case 4:
1221  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_CSeq]) == uiNameLen){
1222  uiNameId = RULE_GRAMMAR5_CSEQ;
1223  uiIsUdt = APG_FALSE;
1224  }
1225  break;
1226  case 7:
1227  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Call_ID]) == uiNameLen){
1228  uiNameId = UDT_GRAMMAR5_U_CALLID;
1229  uiIsUdt = APG_TRUE;
1230  }else if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Contact]) == uiNameLen){
1231  uiNameId = RULE_GRAMMAR5_CONTACT;
1232  uiIsUdt = APG_FALSE;
1233  }
1234  break;
1235  case 9:
1236  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Call_Info]) == uiNameLen){
1237  uiNameId = RULE_GRAMMAR5_CALL_INFO;
1238  uiIsUdt = APG_FALSE;
1239  }
1240  break;
1241  case 12:
1242  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Content_Type]) == uiNameLen){
1243  uiNameId = RULE_GRAMMAR5_CONTENT_TYPE;
1244  uiIsUdt = APG_FALSE;
1245  }
1246  break;
1247  case 14:
1248  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Content_Length]) == uiNameLen){
1249  uiNameId = RULE_GRAMMAR5_CONTENT_LENGTH;
1250  uiIsUdt = APG_FALSE;
1251  }
1252  break;
1253  case 16:
1254  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Content_Encoding]) == uiNameLen){
1255  uiNameId = RULE_GRAMMAR5_CONTENT_ENCODING;
1256  uiIsUdt = APG_FALSE;
1257  }else if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Content_Language]) == uiNameLen){
1258  uiNameId = RULE_GRAMMAR5_CONTENT_LANGUAGE;
1259  uiIsUdt = APG_FALSE;
1260  }
1261  break;
1262  case 19:
1263  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Content_Disposition]) == uiNameLen){
1264  uiNameId = RULE_GRAMMAR5_CONTENT_DISPOSITION;
1265  uiIsUdt = APG_FALSE;
1266  }
1267  break;
1268  default:
1269  break;
1270  }
1271  break;
1272  case 'd':
1273  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Date]) == uiNameLen){
1274  uiNameId = RULE_GRAMMAR5_DATE;
1275  uiIsUdt = APG_FALSE;
1276  }
1277  break;
1278  case 'e':
1279  if(uiNameLen == 7){
1280  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Expires]) == uiNameLen){
1281  uiNameId = RULE_GRAMMAR5_EXPIRES;
1282  uiIsUdt = APG_FALSE;
1283  }
1284  } else if(uiNameLen == 10){
1285  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Error_Info]) == uiNameLen){
1286  uiNameId = RULE_GRAMMAR5_ERROR_INFO;
1287  uiIsUdt = APG_FALSE;
1288  }
1289  }
1290  break;
1291  case 'f':
1292  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_From]) == uiNameLen){
1293  uiNameId = RULE_GRAMMAR5_FROM;
1294  uiIsUdt = APG_FALSE;
1295  }
1296  break;
1297  case 'i':
1298  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_In_Reply_To]) == uiNameLen){
1299  uiNameId = RULE_GRAMMAR5_REPLY_TO;
1300  uiIsUdt = APG_FALSE;
1301  }
1302  break;
1303  case 'm':
1304  switch(uiNameLen){
1305  case 11:
1306  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Min_Expires]) == uiNameLen){
1307  uiNameId = RULE_GRAMMAR5_MIN_EXPIRES;
1308  uiIsUdt = APG_FALSE;
1309  }else if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Max_Forwards]) == uiNameLen){
1310  uiNameId = RULE_GRAMMAR5_MAX_FORWARDS;
1311  uiIsUdt = APG_FALSE;
1312  }
1313  break;
1314  case 12:
1315  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_MIME_Version]) == uiNameLen){
1316  uiNameId = RULE_GRAMMAR5_MIME_VERSION;
1317  uiIsUdt = APG_FALSE;
1318  }
1319  break;
1320  default:
1321  break;
1322  }
1323  break;
1324  case 'o':
1325  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Organization]) == uiNameLen){
1326  uiNameId = RULE_GRAMMAR5_ORGANIZATION;
1327  uiIsUdt = APG_FALSE;
1328  }
1329  break;
1330  case 'p':
1331  switch(uiNameLen){
1332  case 8:
1333  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Priority]) == uiNameLen){
1334  uiNameId = RULE_GRAMMAR5_PRIORITY;
1335  uiIsUdt = APG_FALSE;
1336  }
1337  break;
1338  case 13:
1339  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Proxy_Require]) == uiNameLen){
1340  uiNameId = RULE_GRAMMAR5_PROXY_REQUIRE;
1341  uiIsUdt = APG_FALSE;
1342  }
1343  break;
1344  case 18:
1345  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Proxy_Authenticate]) == uiNameLen){
1346  uiNameId = RULE_GRAMMAR5_PROXY_AUTHENTICATE;
1347  uiIsUdt = APG_FALSE;
1348  }
1349  break;
1350  case 19:
1351  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Proxy_Authorization]) == uiNameLen){
1352  uiNameId = RULE_GRAMMAR5_PROXY_AUTHORIZATION;
1353  uiIsUdt = APG_FALSE;
1354  }
1355  break;
1356  default:
1357  break;
1358  }
1359  break;
1360  case 'r':
1361  switch(uiNameLen){
1362  case 5:
1363  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Route]) == uiNameLen){
1364  uiNameId = RULE_GRAMMAR5_ROUTE;
1365  uiIsUdt = APG_FALSE;
1366  }
1367  break;
1368  case 7:
1369  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Require]) == uiNameLen){
1370  uiNameId = RULE_GRAMMAR5_REQUIRE;
1371  uiIsUdt = APG_FALSE;
1372  }
1373  break;
1374  case 8:
1375  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Reply_To]) == uiNameLen){
1376  uiNameId = RULE_GRAMMAR5_REPLY_TO;
1377  uiIsUdt = APG_FALSE;
1378  }
1379  break;
1380  case 11:
1381  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Retry_After]) == uiNameLen){
1382  uiNameId = RULE_GRAMMAR5_ALLOW;
1383  uiIsUdt = APG_FALSE;
1384  }
1385  break;
1386  case 12:
1387  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Record_Route]) == uiNameLen){
1388  uiNameId = RULE_GRAMMAR5_RECORD_ROUTE;
1389  uiIsUdt = APG_FALSE;
1390  }
1391  break;
1392  default:
1393  break;
1394  }
1395  break;
1396  case 's':
1397  switch(uiNameLen){
1398  case 6:
1399  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Server]) == uiNameLen){
1400  uiNameId = RULE_GRAMMAR5_SERVER;
1401  uiIsUdt = APG_FALSE;
1402  }
1403  break;
1404  case 7:
1405  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Subject]) == uiNameLen){
1406  uiNameId = RULE_GRAMMAR5_SUBJECT;
1407  uiIsUdt = APG_FALSE;
1408  }
1409  break;
1410  case 9:
1411  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Supported]) == uiNameLen){
1412  uiNameId = RULE_GRAMMAR5_SUPPORTED;
1413  uiIsUdt = APG_FALSE;
1414  }
1415  break;
1416  default:
1417  break;
1418  }
1419  break;
1420  case 't':
1421  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_To]) == uiNameLen){
1422  uiNameId = RULE_GRAMMAR5_TO;
1423  uiIsUdt = APG_FALSE;
1424  }
1425  break;
1426  case 'u':
1427  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Unsupported]) == uiNameLen){
1428  uiNameId = RULE_GRAMMAR5_UNSUPPORTED;
1429  uiIsUdt = APG_FALSE;
1430  }
1431  break;
1432  case 'v':
1433  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Via]) == uiNameLen){
1434  uiNameId = RULE_GRAMMAR5_VIA;
1435  uiIsUdt = APG_FALSE;
1436  }
1437  break;
1438  case 'w':
1439  switch(uiNameLen){
1440  case 7:
1441  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_Warning]) == uiNameLen){
1442  uiNameId = RULE_GRAMMAR5_WARNING;
1443  uiIsUdt = APG_FALSE;
1444  }
1445  break;
1446  case 16:
1447  if(uiACharStricmp(acpPhrase, uiNameLen, &saHdrNames[MSG_HDR_WWW_Authenticate]) == uiNameLen){
1448  uiNameId = RULE_GRAMMAR5_WWW_AUTHENTICATE;
1449  uiIsUdt = APG_FALSE;
1450  }
1451  break;
1452  default:
1453  break;
1454  }
1455  break;
1456  default:
1457  uiNameId = UDT_GRAMMAR5_U_EXTENSION_HEADER;
1458  uiIsUdt = APG_TRUE;
1459  break;
1460  }
1461  }
1462  // success
1463  break;
1464  }
1465  *uipName = uiNameId;
1466  *uipIsUdt = uiIsUdt;
1467  return uiHdr;
1468 }
1469 apg_uint uiSIP_e_message_header(APG_CBDATA* spData){
1470  const apg_achar* acpPhrase;
1471  apg_uint uiMaxPhraseLength;
1472  apg_uint uiNameId;
1473  apg_uint uiIsUdt;
1474  apg_uint uiEnd;
1475  apg_uint uiOffset = spData->uiPhraseOffset;
1476  apg_uint uiSaveOffset = spData->uiPhraseOffset;
1477  apg_uint uiPhraseCount = 0;
1478  apg_uint uiMsgLen = 0;
1479  apg_uint uiFoundLineEnd;
1480  acpPhrase = spData->acpSrc + uiOffset;
1481  uiMaxPhraseLength = spData->uiSrcLen - uiOffset;
1482  while(APG_TRUE){
1483  uiFoundLineEnd = uiLineEnd(acpPhrase, uiMaxPhraseLength);
1484  if(uiFoundLineEnd){break;} // if line begins with line end, no more headers
1485  uiMsgLen = uiMsgHdrName(acpPhrase, uiMaxPhraseLength, &uiNameId, &uiIsUdt);
1486  if(uiMsgLen){
1487  uiOffset += uiMsgLen;
1488  acpPhrase = spData->acpSrc + uiOffset;
1489  uiMaxPhraseLength = spData->uiSrcLen - uiOffset;
1490  if(uiIsUdt){
1491  vExecuteUdt(spData, uiNameId, uiOffset);
1492  } else{
1493  vExecuteRule(spData, uiNameId, uiOffset);
1494  }
1495  if(spData->uiPhraseLength == APG_UNDEFINED){break;} // didn't find a valid header value
1496  uiOffset += spData->uiPhraseLength;
1497  acpPhrase = spData->acpSrc + uiOffset;
1498  uiMaxPhraseLength = spData->uiSrcLen - uiOffset;
1499  } else{break;} // didn't find a valid header name (eg. "name : ")
1500 
1501  // get the line end
1502  uiEnd = uiLineEnd(acpPhrase, uiMaxPhraseLength);
1503  if(uiEnd == 0){break;} // header value not followed by CRLF
1504  uiOffset += uiEnd;
1505  acpPhrase = spData->acpSrc + uiOffset;
1506  uiMaxPhraseLength = spData->uiSrcLen - uiOffset;
1507  uiPhraseCount = uiOffset - uiSaveOffset; // found a valid message-header, increment the phrase length
1508  }
1509  spData->uiPhraseOffset = uiSaveOffset;
1510  spData->uiPhraseLength = uiPhraseCount;
1511  return 0;
1512 }
APG_CBDATA::acpSrc
const apg_achar * acpSrc
Definition: Apg.h:455
apg_uint
unsigned int apg_uint
Definition: Apg.h:169
vExecuteUdt
void vExecuteUdt(APG_CBDATA *spData, apg_uint uiId, apg_uint uiOffset)
Definition: Parser.c:559
uiLineEnd
apg_uint uiLineEnd(APG_CBDATA *spData)
Definition: Callbacks.c:282
APG_CBDATA::uiPhraseOffset
apg_uint uiPhraseOffset
Definition: Apg.h:457
APG_CBDATA::uiPhraseLength
apg_uint uiPhraseLength
Definition: Apg.h:459
APG_TRUE
#define APG_TRUE
Definition: Apg.h:187
vExecuteRule
void vExecuteRule(APG_CBDATA *spData, apg_uint uiId, apg_uint uiOffset)
Definition: Parser.c:537
apg_achar
unsigned char apg_achar
Definition: Apg.h:183
APG_CBDATA
The data structure passed to all syntax and AST callback functions, both rule and UDT.
Definition: Apg.h:453
APG_CBDATA::uiSrcLen
apg_uint uiSrcLen
Definition: Apg.h:456
APG_UNDEFINED
#define APG_UNDEFINED
Definition: Apg.h:194
APG_FALSE
#define APG_FALSE
Definition: Apg.h:190
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/licenses.html or write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.