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)
20 Headers::recognize (const char * const header
)
22 (void)this->map_
[header
];
26 Headers::parse_header_line (char * const header_line
)
28 char *ptr
= header_line
;
29 char *buf
= header_line
;
32 ptr
= ACE_OS::strchr (header_line
, '\n');
34 if (ptr
> header_line
&& ptr
[-1] == '\r')
40 if (ptr
== header_line
)
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
))
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);
71 Headers::complete_header_line (char *const header_line
)
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
;
86 if (!this->end_of_line (ptr
, offset
))
89 if (ptr
== header_line
)
91 ACE_OS::memmove (ptr
, ptr
+offset
, ACE_OS::strlen (ptr
+ offset
) + 1);
93 ACE_DEBUG ((LM_DEBUG
, " (%t) no more headers\n"));
103 ACE_OS::memmove (ptr
, ptr
+offset
, ACE_OS::strlen (ptr
+ offset
) + 1);
111 if (ACE_OS::ace_isalpha (ptr
[offset
]))
117 while (this->end_of_line (ptr
, offset
) != 0);
123 Headers::end_of_headers () const
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');
163 // Implementation of class Headers_Map
165 Headers_Map::Headers_Map ()
170 Headers_Map::~Headers_Map ()
174 Headers_Map_Item::Headers_Map_Item ()
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
189 // return this->value_ == 0 ? this->no_value_ : this->value_;
193 Headers_Map_Item::operator= (char * value
)
195 ACE_OS::free ((void *) this->value_
);
196 this->value_
= ACE_OS::strdup (value
);
201 Headers_Map_Item::operator= (const char * value
)
203 ACE_OS::free ((void *) this->value_
);
204 this->value_
= ACE_OS::strdup (value
);
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);
219 Headers_Map_Item::header () const
221 return this->header_
;
225 Headers_Map_Item::value () const
231 Headers_Map::operator[] (const char * const header
)
233 Headers_Map_Item
*item_ptr
;
235 item_ptr
= this->find (header
);
238 item_ptr
= this->place (header
);
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
);
252 item_ptr
= mutable_this
->place (header
);
258 Headers_Map::mapped (const char * const header
) const
260 int result
= this->find (header
) != 0;
266 Headers_Map::find (const char * const header
) const
268 Headers_Map
*const mutable_this
= (Headers_Map
*) this;
270 mutable_this
->garbage_
.header_
= header
;
272 Headers_Map_Item
*mi_ptr
= (Headers_Map_Item
*)
273 ACE_OS::bsearch (&this->garbage_
,
276 sizeof (Headers_Map_Item
),
277 Headers_Map::compare
);
280 int j
= this->num_headers_
;
285 if (Headers_Map::compare (&this->garbage_
, this->map_
+k
) < 0)
291 Headers_Map_Item
*mi_ptr
= mutable_this
->map_
+ i
;
292 if (Headers_Map::compare (&this->garbage_
, mi_ptr
) != 0)
296 mutable_this
->garbage_
.header_
= 0;
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
;
315 if (Headers_Map::compare (&this->garbage_
,
316 &this->map_
[i
- 1]) > 0)
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;
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
,
339 Headers_Map_Item
*a
, *b
;
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)
349 else if (a
->header_
== 0)
355 result
= ACE_OS::strcasecmp (a
->header_
, b
->header_
);
357 return (result
< 0) ? -1 : (result
> 0);