/[resiprocate]/main/sip/resiprocate/MsgHeaderScanner.hxx
ViewVC logotype

Contents of /main/sip/resiprocate/MsgHeaderScanner.hxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4599 - (show annotations) (download)
Wed May 11 23:10:19 2005 UTC (14 years, 7 months ago) by derek
File size: 7879 byte(s)
set svn:eol-style to LF
1 #if !defined(RESIP_MSG_HEADER_SCANNER_HXX)
2 #define RESIP_MSG_HEADER_SCANNER_HXX
3 namespace resip
4 {
5
6 class SipMessage;
7
8 ///////////////////////////////////////////////////////////////////////////////
9 // This class scans a message header for its status line (the first non-empty
10 // line) and then any number of field name/value pairs, terminated by an empty
11 // line.
12 // The message header text may be divided into arbitrary chunks.
13 // A single instance may be used to scan any number of message headers.
14 //
15 // Its intended usage pattern is as follows:
16 //
17 // MsgHeaderScanner scanner;
18 // for (;;) {
19 // SipMessage *msg = ...
20 // scanner.prepareForMessage(msg);
21 // MsgHeaderScanner::ScanChunkResult scanChunkResult;
22 // do {
23 // (Input the next chunk of the message.)
24 // scanChunkResult = scanner.scanChunk(...);
25 // } while (scanChunkResult == MsgHeaderScanner::scrNextChunk);
26 // ...
27 // }//for
28 //
29 // Note that during the input of each message header chunk this class
30 // encapsulates the full state of the message header scan, so that input may
31 // be performed in whatever manner desired (eg without blocking).
32 //
33 // In this class, "multi-value" refers to associating multiple values with a
34 // single field name by separating the individual values with commas.
35 //
36 // Some assertions about message headers:
37 // Only space and tab are whitespace characters.
38 // A carriage return must always be followed by a line feed.
39 // A line feed must always be preceded by a carriage return.
40 // A field name always starts at the beginning of a line.
41 // A value may contain a line break (a carriage return / line feed pair)
42 // before any whitespace, but not otherwise. (The scanner allows
43 // whitespace in a few extra places for simplicity.)
44 // A ',' within '"' pair or '<'/'>' pair does not separate multi-values.
45 // A '\\' is used only within a '"' pair, and not to escape a carriage
46 // return or line feed.
47 // '<'/'>' pairs do not nest, nor contain '"' pairs.
48 // '('/')' pair comments cannot be combined with any multi-values.
49 // A multi-value cannot be empty, except as needed to specify 0 multi-values.
50
51 class MsgHeaderScanner
52 {
53
54 public:
55 enum { MaxNumCharsChunkOverflow = 5 };
56 enum TextPropBitMaskEnum
57 {
58 tpbmContainsLineBreak = 1 << 0, // '\r' or '\n', always paired
59 tpbmContainsWhiteSpace = 1 << 1, // ' ' or '\t'
60 tpbmContainsBackSlash = 1 << 2, // '\\'
61 tpbmContainsPercent = 1 << 3, // '%'
62 tpbmContainsSemiColon = 1 << 4, // ';'
63 tpbmContainsParen = 1 << 5 // '(' or ')', possibly mismatched
64 };
65 typedef unsigned char TextPropBitMask;
66
67 private:
68
69 // Fields:
70 SipMessage * mMsg;
71 /*State*/int mState; // Type defined in .cxx file.
72 int mPrevScanChunkNumSavedTextChars;
73 MsgHeaderScanner::TextPropBitMask mTextPropBitMask;
74 const char * mFieldName;
75 unsigned int mFieldNameLength;
76 int mFieldKind;
77 /*
78 "mState" and "mPrevScanChunkNumSavedTextChars" are meaningful only between
79 input chunks.
80 "mTextPropBitMask" is meaningful only between input chunks and only when
81 scanning a field name or value.
82 "mFieldName", "mFieldNameLength", and "mFieldKind" are meaningful only
83 between terminating a field name and finding the termination of its value.
84 */
85
86 public:
87
88 MsgHeaderScanner();
89
90 // Destructor: defined implicitly
91 void prepareForMessage(SipMessage * msg);
92 // allow proper parsing of message/sipfrag & msg/external
93 // presence of start line is determined in SipFrag
94 void prepareForFrag(SipMessage * msg, bool hasStartLine);
95
96
97 enum ScanChunkResult {
98 scrEnd, // Message header scan ended.
99 scrNextChunk, // Another chunk is needed.
100 scrError // The message header is in error.
101 };
102
103
104 // The meaning of "*unprocessedCharPtr" depends on the result:
105 // scrEnd: The character that terminates the message header.
106 // scrError: The erroneous character.
107 // scrNextChunk: The first character of some incomplete text unit. The
108 // remaining portion of the old chunk must be placed
109 // in the beginning of the new chunk.
110 // This method writes a sentinel in the chunk's terminal character.
111 MsgHeaderScanner::ScanChunkResult scanChunk(char * chunk,
112 unsigned int chunkLength,
113 char **unprocessedCharPtr);
114
115 // !ah! DEBUG only, write to fd.
116 // !ah! for documentation generation
117 static int dumpStateMachine(int fd);
118
119 private:
120
121
122 // Copy constructor: declared but not defined
123 MsgHeaderScanner(const MsgHeaderScanner & from);
124
125 // Assignment: declared but not defined
126 MsgHeaderScanner & operator=(const MsgHeaderScanner & from);
127
128 // Automatically called when 1st MsgHeaderScanner constructed.
129 bool initialize();
130 static bool mInitialized;
131
132
133 };
134
135
136 ///////////////////////////////////////////////////////////////////////////////
137
138 } // namespace resip
139
140 #endif
141 /* ====================================================================
142 * The Vovida Software License, Version 1.0
143 *
144 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved.
145 *
146 * Redistribution and use in source and binary forms, with or without
147 * modification, are permitted provided that the following conditions
148 * are met:
149 *
150 * 1. Redistributions of source code must retain the above copyright
151 * notice, this list of conditions and the following disclaimer.
152 *
153 * 2. Redistributions in binary form must reproduce the above copyright
154 * notice, this list of conditions and the following disclaimer in
155 * the documentation and/or other materials provided with the
156 * distribution.
157 *
158 * 3. The names "VOCAL", "Vovida Open Communication Application Library",
159 * and "Vovida Open Communication Application Library (VOCAL)" must
160 * not be used to endorse or promote products derived from this
161 * software without prior written permission. For written
162 * permission, please contact vocal@vovida.org.
163 *
164 * 4. Products derived from this software may not be called "VOCAL", nor
165 * may "VOCAL" appear in their name, without prior written
166 * permission of Vovida Networks, Inc.
167 *
168 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
169 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
170 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
171 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA
172 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
173 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
174 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
175 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
176 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
177 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
178 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
179 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
180 * DAMAGE.
181 *
182 * ====================================================================
183 *
184 * This software consists of voluntary contributions made by Vovida
185 * Networks, Inc. and many individuals on behalf of Vovida Networks,
186 * Inc. For more information on Vovida Networks, Inc., please see
187 * <http://www.vovida.org/>.
188 *
189 */

Properties

Name Value
svn:eol-style LF

webmaster AT resiprocate DOT org
ViewVC Help
Powered by ViewVC 1.1.27