diff options
Diffstat (limited to 'ACE/apps/JAWS3/jaws3/Config_File.cpp')
-rw-r--r-- | ACE/apps/JAWS3/jaws3/Config_File.cpp | 304 |
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 (); +} + |