Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / ACE / apps / JAWS / server / Parse_Headers.cpp
blob614369df50c79c8c9ebbae8ec0d54f5e1a36bc3c
1 #include "ace/Log_Msg.h"
3 #include "Parse_Headers.h"
4 #include "ace/OS_NS_string.h"
5 #include "ace/OS_NS_strings.h"
6 #include "ace/OS_NS_stdlib.h"
7 #include "ace/OS_NS_ctype.h"
9 // Implementation of class Headers
11 Headers::Headers () : done_(0)
15 Headers::~Headers ()
19 void
20 Headers::recognize (const char * const header)
22 (void)this->map_[header];
25 void
26 Headers::parse_header_line (char * const header_line)
28 char *ptr = header_line;
29 char *buf = header_line;
30 int offset = 1;
32 ptr = ACE_OS::strchr (header_line, '\n');
34 if (ptr > header_line && ptr[-1] == '\r')
36 ptr--;
37 offset++;
40 if (ptr == header_line)
42 this->done_ = 1;
43 return;
46 *ptr = '\0';
47 ptr += offset;
49 char *value = 0;
50 char *header = ACE_OS::strtok_r (buf, ":", &value);
52 ACE_DEBUG((LM_DEBUG, " (%t) Headers::parse_header_line [%s]\n",
53 header ? header : "<empty>"));
55 if (header != 0 && this->map_.mapped (header))
57 while (ACE_OS::ace_isspace (*value))
58 value++;
60 this->map_[header] = value;
62 ACE_DEBUG((LM_DEBUG, " (%t) Headers::parse_header_line <%s>\n",
63 value ? value : "<empty>"));
66 // Write back the unused portion of the input.
67 ACE_OS::memmove (header_line, ptr, ACE_OS::strlen(ptr) + 1);
70 int
71 Headers::complete_header_line (char *const header_line)
73 // Algorithm --
74 // Scan for end of line marker.
75 // If the next character is linear white space, then unfold the header.
76 // Else, if the next character is printable, we have a complete header line.
77 // Else, presumably the next character is '\0', so the header is incomplete.
79 // return -1 if end of line but not complete header line
80 // return 0 if no end of line marker
81 // return 1 if complete header line
83 char *ptr = header_line;
84 int offset;
86 if (!this->end_of_line (ptr, offset))
87 return 0;
89 if (ptr == header_line)
91 ACE_OS::memmove (ptr, ptr+offset, ACE_OS::strlen (ptr + offset) + 1);
92 this->done_ = 1;
93 ACE_DEBUG ((LM_DEBUG, " (%t) no more headers\n"));
94 return 0;
99 switch (ptr[offset])
101 case ' ':
102 case '\t':
103 ACE_OS::memmove (ptr, ptr+offset, ACE_OS::strlen (ptr + offset) + 1);
104 break;
106 case '\n':
107 case '\r':
108 return 1;
110 default:
111 if (ACE_OS::ace_isalpha (ptr[offset]))
112 return 1;
113 else
114 return -1;
117 while (this->end_of_line (ptr, offset) != 0);
119 return 0;
123 Headers::end_of_headers () const
125 return this->done_;
128 Headers_Map_Item &
129 Headers::operator[] (const char * const header)
131 return this->map_[header];
134 const Headers_Map_Item &
135 Headers::operator[] (const char * const header) const
137 return this->map_[header];
141 Headers::end_of_line (char *&line, int &offset) const
143 char *old_line = line;
144 char *ptr = ACE_OS::strchr (old_line, '\n');
146 if (ptr == 0)
147 return 0;
149 line = ptr;
150 offset = 1;
152 if (line > old_line
153 && line[-1] == '\r')
155 line--;
156 offset = 2;
159 return 1;
163 // Implementation of class Headers_Map
165 Headers_Map::Headers_Map ()
166 : num_headers_(0)
170 Headers_Map::~Headers_Map ()
174 Headers_Map_Item::Headers_Map_Item ()
175 : header_(0),
176 value_(0)
180 Headers_Map_Item::~Headers_Map_Item ()
182 ACE_OS::free ((void *) this->header_);
183 ACE_OS::free ((void *) this->value_);
184 this->header_ = this->value_ = 0;
187 // Headers_Map_Item::operator const char * () const
188 // {
189 // return this->value_ == 0 ? this->no_value_ : this->value_;
190 // }
192 Headers_Map_Item &
193 Headers_Map_Item::operator= (char * value)
195 ACE_OS::free ((void *) this->value_);
196 this->value_ = ACE_OS::strdup (value);
197 return *this;
200 Headers_Map_Item &
201 Headers_Map_Item::operator= (const char * value)
203 ACE_OS::free ((void *) this->value_);
204 this->value_ = ACE_OS::strdup (value);
205 return *this;
208 Headers_Map_Item &
209 Headers_Map_Item::operator= (const Headers_Map_Item & mi)
211 ACE_OS::free ((void *) this->value_);
212 ACE_OS::free ((void *) this->header_);
213 this->header_ = ACE_OS::strdup (mi.header_);
214 this->value_ = (mi.value_ ? ACE_OS::strdup (mi.value_) : 0);
215 return *this;
218 const char *
219 Headers_Map_Item::header () const
221 return this->header_;
224 const char *
225 Headers_Map_Item::value () const
227 return this->value_;
230 Headers_Map_Item &
231 Headers_Map::operator[] (const char * const header)
233 Headers_Map_Item *item_ptr;
235 item_ptr = this->find (header);
237 if (item_ptr == 0)
238 item_ptr = this->place (header);
240 return *item_ptr;
243 const Headers_Map_Item &
244 Headers_Map::operator[] (const char * const header) const
246 Headers_Map_Item *item_ptr;
247 Headers_Map *mutable_this = (Headers_Map *)this;
249 item_ptr = this->find (header);
251 if (item_ptr == 0)
252 item_ptr = mutable_this->place (header);
254 return *item_ptr;
258 Headers_Map::mapped (const char * const header) const
260 int result = this->find (header) != 0;
262 return result;
265 Headers_Map_Item *
266 Headers_Map::find (const char * const header) const
268 Headers_Map *const mutable_this = (Headers_Map *) this;
270 mutable_this->garbage_.header_ = header;
271 #if 0
272 Headers_Map_Item *mi_ptr = (Headers_Map_Item *)
273 ACE_OS::bsearch (&this->garbage_,
274 this->map_,
275 this->num_headers_,
276 sizeof (Headers_Map_Item),
277 Headers_Map::compare);
278 #else
279 int i = 0;
280 int j = this->num_headers_;
282 while (i < j-1)
284 int k = (i+j)/2;
285 if (Headers_Map::compare (&this->garbage_, this->map_+k) < 0)
286 j = k;
287 else
288 i = k;
291 Headers_Map_Item *mi_ptr = mutable_this->map_ + i;
292 if (Headers_Map::compare (&this->garbage_, mi_ptr) != 0)
293 mi_ptr = 0;
294 #endif
296 mutable_this->garbage_.header_ = 0;
298 return mi_ptr;
301 Headers_Map_Item *
302 Headers_Map::place (const char *const header)
304 this->garbage_.header_ = ACE_OS::strdup (header);
306 int i = this->num_headers_++;
307 ACE_OS::free ((void *) this->map_[i].header_);
308 ACE_OS::free ((void *) this->map_[i].value_);
309 this->map_[i].header_ = 0;
310 this->map_[i].value_ = 0;
311 Headers_Map_Item temp_item;
313 while (i > 0)
315 if (Headers_Map::compare (&this->garbage_,
316 &this->map_[i - 1]) > 0)
317 break;
319 this->map_[i].header_ = this->map_[i - 1].header_;
320 this->map_[i].value_ = this->map_[i - 1].value_;
321 this->map_[i - 1].header_ = 0;
322 this->map_[i - 1].value_ = 0;
324 i--;
327 this->map_[i].header_ = this->garbage_.header_;
328 this->map_[i].value_ = this->garbage_.value_;
330 this->garbage_.header_ = 0;
332 return &this->map_[i];
336 Headers_Map::compare (const void *item1,
337 const void *item2)
339 Headers_Map_Item *a, *b;
340 int result;
342 a = (Headers_Map_Item *) item1;
343 b = (Headers_Map_Item *) item2;
345 if (a->header_ == 0 || b->header_ == 0)
347 if (a->header_ == 0 && b->header_ == 0)
348 result = 0;
349 else if (a->header_ == 0)
350 result = 1;
351 else
352 result = -1;
354 else
355 result = ACE_OS::strcasecmp (a->header_, b->header_);
357 return (result < 0) ? -1 : (result > 0);