system_values.cpp

Go to the documentation of this file.
00001 #ifndef SYSTEM_VALUES_IMPLEMENTATION_FILE
00002 #define SYSTEM_VALUES_IMPLEMENTATION_FILE
00003 
00004 /*****************************************************************************\
00005 *                                                                             *
00006 *  Name   : system_values                                                     *
00007 *  Author : Chris Koeritz                                                     *
00008 *                                                                             *
00009 *******************************************************************************
00010 * Copyright (c) 2004-$now By Author.  This program is free software; you can  *
00011 * redistribute it and/or modify it under the terms of the GNU General Public  *
00012 * License as published by the Free Software Foundation; either version 2 of   *
00013 * the License or (at your option) any later version.  This is online at:      *
00014 *     http://www.fsf.org/copyleft/gpl.html                                    *
00015 * Please send any updates to: fred@gruntose.com                               *
00016 \*****************************************************************************/
00017 
00018 #include "ini_config.h"
00019 #include "system_values.h"
00020 
00021 #include <basis/shell_sort.h>
00022 #include <data_struct/int_hash.cpp>
00023 #include <data_struct/string_table.h>
00024 #include <textual/list_parsing.h>
00025 
00026 const int MAX_VALUE_BITS = 8;  // we provide 2^n slots in hash.
00027 
00028 #undef LOG
00029 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger(), s)
00030 
00032 
00033 class value_record
00034 {
00035 public:
00036   istring _name;  // the name of the value.
00037   istring _descrip;  // the description of the value.
00038   istring _location;  // the file defining the value.
00039 
00040   value_record(const istring &name = istring::empty_string(),
00041       const istring &description = istring::empty_string(),
00042       const istring &location = istring::empty_string())
00043   : _name(name), _descrip(description), _location(location) {}
00044 };
00045 
00047 
00048 class system_values_lookup_list : public int_hash<value_record>
00049 {
00050 public:
00051   system_values_lookup_list() : int_hash<value_record>(MAX_VALUE_BITS) {}
00052 
00053   // finds the symbolic "name" in the table, which is not as efficient as
00054   // lookin up integers.
00055   value_record *text_find(const istring &name, int &value) {
00056     // scoot across all of the ids.
00057     const int_set &cids = ids();
00058     for (int i = 0; i < cids.elements(); i++) {
00059       int current_id = cids[i];
00060       value_record *curr = find(current_id);
00061       if (!curr) {
00062 //serious error.
00063         continue;
00064       }
00065       if (curr->_name == name) {
00066         // this is a match to the name they were seeking.
00067         value = current_id;
00068         return curr;
00069       }
00070     }
00071     return NIL;
00072   }
00073 };
00074 
00076 
00077 system_values::system_values(const istring &section_tag)
00078 : _tag(new istring(section_tag)),
00079   _list(new system_values_lookup_list),
00080   _file(new istring(DEFAULT_MANIFEST))
00081 {
00082   FUNCDEF("constructor");
00083   open_values();
00084 }
00085   
00086 system_values::~system_values()
00087 {
00088   WHACK(_list);
00089   WHACK(_tag);
00090   WHACK(_file);
00091 }
00092 
00093 const char *system_values::DEFAULT_MANIFEST = "manifest.txt";
00094   // this is the default manifest and it is expected to live right in
00095   // the folder where the applications are.
00096 
00097 bool system_values::use_other_manifest(const istring &manifest_file)
00098 {
00099   *_file = manifest_file;
00100   return open_values();
00101 }
00102 
00103 const char *system_values::OUTCOME_VALUES() { return "DEFINE_OUTCOME"; }
00104 
00105 const char *system_values::FILTER_VALUES() { return "DEFINE_FILTER"; }
00106 
00107 const char *system_values::EVENT_VALUES() { return "DEFINE_EVENT"; }
00108 
00109 bool system_values::open_values()
00110 {
00111   FUNCDEF("open_values");
00112   ini_configurator ini(*_file, ini_configurator::RETURN_ONLY,
00113       ini_configurator::APPLICATION_DIRECTORY);
00114 
00115   string_table full_section;
00116   bool got_section = ini.get_section(*_tag, full_section);
00117   if (!got_section) return false;  // nothing there to look up.
00118   for (int i = 0; i < full_section.symbols(); i++) {
00119 
00120     string_array items;
00121     list_parsing::parse_csv_line(full_section.name(i), items);
00122     if (items.length() < 4) {
00123       continue;
00124     }
00125 
00126     value_record *entry = new value_record(items[0], items[2], items[3]);
00127     int value = items[1].convert(0);
00128     _list->add(value, entry);
00129   }
00130 
00131   return true;
00132 }
00133 
00134 #define SV_EOL log_base::platform_ending()
00135 
00136 //hmmm: it might be nice to have an alternate version sorted by name...
00137 
00138 istring system_values::text_form() const
00139 {
00140   int_set cids = _list->ids();
00141 
00142   if (*_tag != "DEFINE_OUTCOME") {
00143     // sort the list in identifier order.
00144     shell_sort(cids.access(), cids.elements());
00145   } else {
00146     // sort the list in reverse identifier order, since zero is first
00147     // for outcomes and then they go negative.
00148     shell_sort(cids.access(), cids.elements(), true);
00149   }
00150 
00151   istring to_return("values for ");
00152   to_return += *_tag;
00153   to_return += SV_EOL;
00154   for (int i = 0; i < cids.elements(); i++) {
00155     int current_id = cids[i];
00156     value_record *curr = _list->find(current_id);
00157     if (!curr) {
00158 //serious error.
00159       continue;
00160     }
00161     to_return += isprintf("%d: ", current_id);
00162     to_return += curr->_name + " \"" + curr->_descrip + "\" from "
00163         + curr->_location;
00164     to_return += SV_EOL;
00165   }
00166   return to_return;
00167 }
00168 
00169 bool system_values::lookup(int value, istring &symbolic_name,
00170     istring &description, istring &file_location)
00171 {
00172   value_record *found = _list->find(value);
00173   if (!found) return false;
00174   symbolic_name = found->_name;
00175   description = found->_descrip;
00176   file_location = found->_location;
00177   return true;
00178 }
00179 
00180 bool system_values::lookup(const istring &symbolic_name, int &value,
00181     istring &description, istring &file_location)
00182 {
00183   value_record *found = _list->text_find(symbolic_name, value);
00184   if (!found) return false;
00185   description = found->_descrip;
00186   file_location = found->_location;
00187   return true;
00188 }
00189 
00190 int system_values::elements() const { return _list->ids().elements(); }
00191 
00192 bool system_values::get(int index, istring &symbolic_name, int &value,
00193     istring &description, istring &file_location)
00194 {
00195   bounds_return(index, 0, _list->ids().elements() - 1, false);  // bad index.
00196   value = _list->ids()[index];
00197   return lookup(value, symbolic_name, description, file_location);
00198 }
00199 
00200 
00201 #endif //SYSTEM_VALUES_IMPLEMENTATION_FILE
00202 

Generated on Fri Aug 29 04:29:04 2008 for HOOPLE Libraries by  doxygen 1.5.1