summaryrefslogtreecommitdiff
path: root/ACE/apps/JAWS3/jaws3/Config_File.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ACE/apps/JAWS3/jaws3/Config_File.cpp')
-rw-r--r--ACE/apps/JAWS3/jaws3/Config_File.cpp304
1 files changed, 304 insertions, 0 deletions
diff --git a/ACE/apps/JAWS3/jaws3/Config_File.cpp b/ACE/apps/JAWS3/jaws3/Config_File.cpp
new file mode 100644
index 00000000000..cf8ab94d3a4
--- /dev/null
+++ b/ACE/apps/JAWS3/jaws3/Config_File.cpp
@@ -0,0 +1,304 @@
+// $Id$
+
+#include "ace/OS_NS_stdlib.h"
+#include "ace/OS_NS_string.h"
+#include "ace/FILE_Connector.h"
+#include "ace/Message_Block.h"
+#include "ace/Singleton.h"
+#include "ace/Unbounded_Queue.h"
+
+#ifndef JAWS_BUILD_DLL
+#define JAWS_BUILD_DLL
+#endif
+
+#include "jaws3/Config_File.h"
+#include "jaws3/Symbol_Table.h"
+
+// = Helper class to manage "constant" strings.
+
+class JAWS_strings
+{
+public:
+
+ ~JAWS_strings (void)
+ {
+ void *p;
+ while (this->queue_.dequeue_head (p) != -1)
+ ACE_OS::free (p);
+ }
+
+ const ACE_TCHAR * duplicate (const ACE_TCHAR *s)
+ {
+ void **x;
+ const ACE_TCHAR *d = 0;
+ ACE_Unbounded_Queue_Iterator<void *> iter (this->queue_);
+
+ while (iter.next (x))
+ {
+ d = (const ACE_TCHAR *) *x;
+ if (ACE_OS::strcmp (d, s) == 0)
+ break;
+ d = 0;
+ iter.advance ();
+ }
+
+ if (d == 0)
+ {
+ d = ACE_OS::strdup (s);
+ this->queue_.enqueue_tail ((void *) d);
+ }
+
+ return d;
+ }
+
+private:
+
+ ACE_Unbounded_Queue<void *> queue_;
+
+};
+
+
+// = Underlying implementation class.
+
+
+class JAWS_Config_File_Impl
+{
+public:
+
+ JAWS_Config_File_Impl (const ACE_TCHAR *config_file);
+ ~JAWS_Config_File_Impl (void);
+ int find (const ACE_TCHAR *key, const ACE_TCHAR *&value);
+
+ void parse_file (void);
+ void reset (void);
+ void dump (void);
+
+ enum { JAWS_CONFIG_FILE_SYMBOL_TABLE_SIZE = 211 };
+
+private:
+
+ ACE_FILE_Addr faddr_;
+ JAWS_strings *strings_;
+ JAWS_Symbol_Table *symbols_;
+
+};
+
+JAWS_Config_File_Impl::JAWS_Config_File_Impl (const ACE_TCHAR *config_file)
+ : faddr_ (config_file)
+ , strings_ (0)
+ , symbols_ (0)
+{
+ this->strings_ = new JAWS_strings;
+ this->symbols_ = new JAWS_Symbol_Table (JAWS_CONFIG_FILE_SYMBOL_TABLE_SIZE);
+ this->parse_file ();
+}
+
+JAWS_Config_File_Impl::~JAWS_Config_File_Impl (void)
+{
+ delete this->symbols_;
+ this->symbols_ = 0;
+ delete this->strings_;
+ this->strings_ = 0;
+}
+
+int
+JAWS_Config_File_Impl::find (const ACE_TCHAR *key, const ACE_TCHAR *&value)
+{
+ return this->symbols_->find (key, value);
+}
+
+void
+JAWS_Config_File_Impl::parse_file (void)
+{
+ ACE_FILE_Connector fconnector;
+ ACE_FILE_IO fio;
+
+ if (fconnector.connect ( fio
+ , this->faddr_
+ , 0
+ , ACE_Addr::sap_any
+ , 0
+ , O_RDONLY
+ ) == -1)
+ return;
+
+ ACE_Message_Block buffer (8192);
+ ACE_Message_Block line (4096);
+ ssize_t count = 0;
+ const ACE_TCHAR *sym_name;
+ const ACE_TCHAR *sym_value;
+ int last_line_was_read = 0;
+ ACE_TCHAR *end_of_current_line = 0;
+ ACE_TCHAR *p = 0;
+
+ while (last_line_was_read
+ || (count = fio.recv (buffer.wr_ptr (), buffer.space () - 2)) >= 0)
+ {
+ end_of_current_line = 0;
+
+ // Make sure input is newline terminated if it is the last line,
+ // and always null terminated.
+ if (! last_line_was_read)
+ {
+ if (count > 0)
+ {
+ buffer.wr_ptr (count);
+ // Scan forward for at least one newline character
+ p = buffer.rd_ptr ();
+ while (p != buffer.wr_ptr ())
+ {
+ if (*p == '\n')
+ break;
+ p++;
+ }
+
+ if (p == buffer.wr_ptr ())
+ continue;
+
+ end_of_current_line = p;
+ }
+ else
+ {
+ if (buffer.wr_ptr ()[-1] != '\n')
+ {
+ buffer.wr_ptr ()[0] = '\n';
+ buffer.wr_ptr (1);
+ }
+
+ last_line_was_read = 1;
+ }
+
+ buffer.wr_ptr ()[0] = '\0';
+ }
+
+ if (end_of_current_line == 0)
+ {
+ end_of_current_line = buffer.rd_ptr ();
+ while (*end_of_current_line != '\n')
+ end_of_current_line++;
+ }
+
+ // If buffer is not pointing to a continuation line, or there is
+ // no more input, then can commit the scanned configuration
+ // line.
+ if (line.length () != 0
+ && ((last_line_was_read && buffer.length () == 0)
+ || (buffer.rd_ptr ()[0] != ' '
+ && buffer.rd_ptr ()[0] != '\t')))
+ {
+ ACE_TCHAR *name = 0;
+ ACE_TCHAR *value = 0;
+
+ name = line.rd_ptr ();
+ for (p = name; *p != '\0'; p++)
+ {
+ if (*p == '=')
+ {
+ line.rd_ptr (p+1);
+ while (p != name && (p[-1] == ' ' || p[-1] == '\t'))
+ p--;
+ *p = '\0';
+ }
+ }
+
+ if (*name)
+ {
+ value = line.rd_ptr ();
+ while (*value == ' ' || *value == '\t')
+ value++;
+ p = line.wr_ptr ();
+ while (p != value && (p[-1] == ' ' || p[-1] == '\t'))
+ p--;
+ *p = '\0';
+
+ sym_name = this->strings_->duplicate (name);
+ sym_value = this->strings_->duplicate (value);
+ this->symbols_->rebind (sym_name, sym_value);
+ }
+
+ line.reset ();
+ }
+
+ // If we are done, we are done!
+ if (last_line_was_read && buffer.length () == 0)
+ break;
+
+ // If the buffer is pointing at a comment line, ignore it.
+ if (buffer.rd_ptr ()[0] == '#'
+ || buffer.rd_ptr ()[0] == '\n'
+ || (buffer.rd_ptr ()[0] == '\r' && buffer.rd_ptr ()[1] == '\n'))
+ {
+ buffer.rd_ptr (end_of_current_line + 1);
+ buffer.crunch ();
+ continue;
+ }
+
+ // Whatever is left is either the start of a name-value-pair or a
+ // continuation of one.
+ line.copy (buffer.rd_ptr (),
+ end_of_current_line - buffer.rd_ptr ());
+ p = line.wr_ptr ();
+ while (p != line.rd_ptr () && (p[-1] == ' ' || p[-1] == '\t'))
+ p--;
+ line.wr_ptr (p);
+ line.wr_ptr ()[0] = '\0';
+ buffer.rd_ptr (end_of_current_line + 1);
+ buffer.crunch ();
+ }
+
+ fio.close ();
+}
+
+void
+JAWS_Config_File_Impl::reset (void)
+{
+ delete this->symbols_;
+ delete this->strings_;
+ this->strings_ = new JAWS_strings;
+ this->symbols_ = new JAWS_Symbol_Table (JAWS_CONFIG_FILE_SYMBOL_TABLE_SIZE);
+ this->parse_file ();
+}
+
+void
+JAWS_Config_File_Impl::dump (void)
+{
+ JAWS_SYMBOL_TABLE_ITERATOR iter (*this->symbols_);
+ JAWS_SYMBOL_TABLE_ENTRY *entry = 0;
+
+ while (iter.next (entry))
+ {
+ ACE_DEBUG ((LM_DEBUG, "[%D|%t] %s=%s\n",
+ entry->ext_id_,
+ entry->int_id_));
+ iter.advance ();
+ }
+}
+
+JAWS_Config_File::JAWS_Config_File (const ACE_TCHAR *config_file,
+ const ACE_TCHAR *config_dir)
+{
+ ACE_TCHAR filename[MAXPATHLEN];
+ ACE_OS::strcpy (filename, config_dir);
+ ACE_OS::strcat (filename, config_file);
+
+ this->impl_ = new JAWS_Config_File_Impl (filename);
+}
+
+int
+JAWS_Config_File::find (const ACE_TCHAR *key, const ACE_TCHAR *&value)
+{
+ return this->impl_->find (key, value);
+}
+
+void
+JAWS_Config_File::reset (void)
+{
+ this->impl_->reset ();
+}
+
+void
+JAWS_Config_File::dump (void)
+{
+ this->impl_->dump ();
+}
+