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