summaryrefslogtreecommitdiff
path: root/trunk/ACE/apps/JAWS/server/Parse_Headers.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/ACE/apps/JAWS/server/Parse_Headers.cpp')
-rw-r--r--trunk/ACE/apps/JAWS/server/Parse_Headers.cpp362
1 files changed, 362 insertions, 0 deletions
diff --git a/trunk/ACE/apps/JAWS/server/Parse_Headers.cpp b/trunk/ACE/apps/JAWS/server/Parse_Headers.cpp
new file mode 100644
index 00000000000..0d7dd273c59
--- /dev/null
+++ b/trunk/ACE/apps/JAWS/server/Parse_Headers.cpp
@@ -0,0 +1,362 @@
+// $Id$
+
+#include "ace/Log_Msg.h"
+
+#include "Parse_Headers.h"
+#include "ace/OS_NS_string.h"
+#include "ace/OS_NS_strings.h"
+#include "ace/OS_NS_stdlib.h"
+#include "ace/os_include/os_ctype.h"
+
+ACE_RCSID(server, Parse_Headers, "$Id$")
+
+// Implementation of class Headers
+
+Headers::Headers (void) : done_(0)
+{
+}
+
+Headers::~Headers (void)
+{
+}
+
+void
+Headers::recognize (const char * const header)
+{
+ (void)this->map_[header];
+}
+
+void
+Headers::parse_header_line (char * const header_line)
+{
+ char *ptr = header_line;
+ char *buf = header_line;
+ int offset = 1;
+
+ ptr = ACE_OS::strchr (header_line, '\n');
+
+ if (ptr > header_line && ptr[-1] == '\r')
+ {
+ ptr--;
+ offset++;
+ }
+
+ if (ptr == header_line)
+ {
+ this->done_ = 1;
+ return;
+ }
+
+ *ptr = '\0';
+ ptr += offset;
+
+ char *value = 0;
+ char *header = ACE_OS::strtok_r (buf, ":", &value);
+
+ ACE_DEBUG((LM_DEBUG, " (%t) Headers::parse_header_line [%s]\n",
+ header ? header : "<empty>"));
+
+ if (header != NULL && this->map_.mapped (header))
+ {
+ while (isspace (*value))
+ value++;
+
+ this->map_[header] = value;
+
+ ACE_DEBUG((LM_DEBUG, " (%t) Headers::parse_header_line <%s>\n",
+ value ? value : "<empty>"));
+ }
+
+ // Write back the unused portion of the input.
+ ACE_OS::memmove (header_line, ptr, ACE_OS::strlen(ptr) + 1);
+}
+
+int
+Headers::complete_header_line (char *const header_line)
+{
+ // Algorithm --
+ // Scan for end of line marker.
+ // If the next character is linear white space, then unfold the header.
+ // Else, if the next character is printable, we have a complete header line.
+ // Else, presumably the next character is '\0', so the header is incomplete.
+
+ // return -1 if end of line but not complete header line
+ // return 0 if no end of line marker
+ // return 1 if complete header line
+
+ char *ptr = header_line;
+ int offset;
+
+ if (!this->end_of_line (ptr, offset))
+ return 0;
+
+ if (ptr == header_line)
+ {
+ ACE_OS::memmove (ptr, ptr+offset, ACE_OS::strlen (ptr + offset) + 1);
+ this->done_ = 1;
+ ACE_DEBUG ((LM_DEBUG, " (%t) no more headers\n"));
+ return 0;
+ }
+
+ do
+ {
+ switch (ptr[offset])
+ {
+ case ' ':
+ case '\t':
+ ACE_OS::memmove (ptr, ptr+offset, ACE_OS::strlen (ptr + offset) + 1);
+ break;
+
+ case '\n':
+ case '\r':
+ return 1;
+
+ default:
+ if (isalpha (ptr[offset]))
+ return 1;
+ else
+ return -1;
+ }
+ }
+ while (this->end_of_line (ptr, offset) != 0);
+
+ return 0;
+}
+
+int
+Headers::end_of_headers (void) const
+{
+ return this->done_;
+}
+
+Headers_Map_Item &
+Headers::operator[] (const char * const header)
+{
+ return this->map_[header];
+}
+
+const Headers_Map_Item &
+Headers::operator[] (const char * const header) const
+{
+ return this->map_[header];
+}
+
+int
+Headers::end_of_line (char *&line, int &offset) const
+{
+ char *old_line = line;
+ char *ptr = ACE_OS::strchr (old_line, '\n');
+
+ if (ptr == NULL)
+ return 0;
+
+ line = ptr;
+ offset = 1;
+
+ if (line > old_line
+ && line[-1] == '\r')
+ {
+ line--;
+ offset = 2;
+ }
+
+ return 1;
+}
+
+
+// Implementation of class Headers_Map
+
+Headers_Map::Headers_Map (void)
+ : num_headers_(0)
+{
+}
+
+Headers_Map::~Headers_Map (void)
+{
+}
+
+Headers_Map_Item::Headers_Map_Item (void)
+ : header_(0),
+ value_(0)
+{
+}
+
+Headers_Map_Item::~Headers_Map_Item (void)
+{
+ ACE_OS::free ((void *) this->header_);
+ ACE_OS::free ((void *) this->value_);
+ this->header_ = this->value_ = 0;
+}
+
+// Headers_Map_Item::operator const char * (void) const
+// {
+// return this->value_ == NULL ? this->no_value_ : this->value_;
+// }
+
+Headers_Map_Item &
+Headers_Map_Item::operator= (char * value)
+{
+ ACE_OS::free ((void *) this->value_);
+ this->value_ = ACE_OS::strdup (value);
+ return *this;
+}
+
+Headers_Map_Item &
+Headers_Map_Item::operator= (const char * value)
+{
+ ACE_OS::free ((void *) this->value_);
+ this->value_ = ACE_OS::strdup (value);
+ return *this;
+}
+
+Headers_Map_Item &
+Headers_Map_Item::operator= (const Headers_Map_Item & mi)
+{
+ ACE_OS::free ((void *) this->value_);
+ ACE_OS::free ((void *) this->header_);
+ this->header_ = ACE_OS::strdup (mi.header_);
+ this->value_ = (mi.value_ ? ACE_OS::strdup (mi.value_) : 0);
+ return *this;
+}
+
+const char *
+Headers_Map_Item::header (void) const
+{
+ return this->header_;
+}
+
+const char *
+Headers_Map_Item::value (void) const
+{
+ return this->value_;
+}
+
+Headers_Map_Item &
+Headers_Map::operator[] (const char * const header)
+{
+ Headers_Map_Item *item_ptr;
+
+ item_ptr = this->find (header);
+
+ if (item_ptr == NULL)
+ item_ptr = this->place (header);
+
+ return *item_ptr;
+}
+
+const Headers_Map_Item &
+Headers_Map::operator[] (const char * const header) const
+{
+ Headers_Map_Item *item_ptr;
+ Headers_Map *mutable_this = (Headers_Map *)this;
+
+ item_ptr = this->find (header);
+
+ if (item_ptr == NULL)
+ item_ptr = mutable_this->place (header);
+
+ return *item_ptr;
+}
+
+int
+Headers_Map::mapped (const char * const header) const
+{
+ int result = this->find (header) != NULL;
+
+ return result;
+}
+
+Headers_Map_Item *
+Headers_Map::find (const char * const header) const
+{
+ Headers_Map *const mutable_this = (Headers_Map *) this;
+
+ mutable_this->garbage_.header_ = header;
+#if 0
+ Headers_Map_Item *mi_ptr = (Headers_Map_Item *)
+ ::bsearch (&this->garbage_,
+ this->map_,
+ this->num_headers_,
+ sizeof (Headers_Map_Item),
+ Headers_Map::compare);
+#else
+ int i = 0;
+ int j = this->num_headers_;
+
+ while (i < j-1)
+ {
+ int k = (i+j)/2;
+ if (Headers_Map::compare (&this->garbage_, this->map_+k) < 0)
+ j = k;
+ else
+ i = k;
+ }
+
+ Headers_Map_Item *mi_ptr = mutable_this->map_ + i;
+ if (Headers_Map::compare (&this->garbage_, mi_ptr) != 0)
+ mi_ptr = 0;
+#endif
+
+ mutable_this->garbage_.header_ = 0;
+
+ return mi_ptr;
+}
+
+Headers_Map_Item *
+Headers_Map::place (const char *const header)
+{
+ this->garbage_.header_ = ACE_OS::strdup (header);
+
+ int i = this->num_headers_++;
+ ACE_OS::free ((void *) this->map_[i].header_);
+ ACE_OS::free ((void *) this->map_[i].value_);
+ this->map_[i].header_ = 0;
+ this->map_[i].value_ = 0;
+ Headers_Map_Item temp_item;
+
+ while (i > 0)
+ {
+ if (Headers_Map::compare (&this->garbage_,
+ &this->map_[i - 1]) > 0)
+ break;
+
+ this->map_[i].header_ = this->map_[i - 1].header_;
+ this->map_[i].value_ = this->map_[i - 1].value_;
+ this->map_[i - 1].header_ = 0;
+ this->map_[i - 1].value_ = 0;
+
+ i--;
+ }
+
+ this->map_[i].header_ = this->garbage_.header_;
+ this->map_[i].value_ = this->garbage_.value_;
+
+ this->garbage_.header_ = 0;
+
+ return &this->map_[i];
+}
+
+int
+Headers_Map::compare (const void *item1,
+ const void *item2)
+{
+ Headers_Map_Item *a, *b;
+ int result;
+
+ a = (Headers_Map_Item *) item1;
+ b = (Headers_Map_Item *) item2;
+
+ if (a->header_ == 0 || b->header_ == 0)
+ {
+ if (a->header_ == 0 && b->header_ == 0)
+ result = 0;
+ else if (a->header_ == 0)
+ result = 1;
+ else
+ result = -1;
+ }
+ else
+ result = ACE_OS::strcasecmp (a->header_, b->header_);
+
+ return (result < 0) ? -1 : (result > 0);
+}