platform/src/Vocabulary.cpp

00001 // ------------------------------------------------------------------------
00002 // Pion is a development platform for building Reactors that process Events
00003 // ------------------------------------------------------------------------
00004 // Copyright (C) 2007-2008 Atomic Labs, Inc.  (http://www.atomiclabs.com)
00005 //
00006 // Pion is free software: you can redistribute it and/or modify it under the
00007 // terms of the GNU Affero General Public License as published by the Free
00008 // Software Foundation, either version 3 of the License, or (at your option)
00009 // any later version.
00010 //
00011 // Pion is distributed in the hope that it will be useful, but WITHOUT ANY
00012 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00013 // FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for
00014 // more details.
00015 //
00016 // You should have received a copy of the GNU Affero General Public License
00017 // along with Pion.  If not, see <http://www.gnu.org/licenses/>.
00018 //
00019 
00020 #include <boost/lexical_cast.hpp>
00021 #include <pion/platform/Vocabulary.hpp>
00022 
00023 
00024 namespace pion {        // begin namespace pion
00025 namespace platform {    // begin namespace platform (Pion Platform Library)
00026 
00027 
00028 // static members of Vocabulary
00029 const Vocabulary::TermRef   Vocabulary::UNDEFINED_TERM_REF = 0;
00030     
00031         
00032 // Vocabulary member functions
00033 
00034 Vocabulary::Vocabulary(void)
00035     : m_num_terms(0)
00036 {
00037     // add an initial "null" term to the vocabulary
00038     m_ref_map.push_back(TermPtr(new Term()));
00039 }
00040 
00041 Vocabulary::Vocabulary(const Vocabulary& v)
00042     : m_num_terms(0)
00043 {
00044     // add an initial "null" term to the vocabulary
00045     m_ref_map.push_back(TermPtr(new Term()));
00046 
00047     // copy over all terms
00048     operator+=(v);
00049 }
00050 
00051 Vocabulary::TermRef Vocabulary::addTerm(const Term& t)
00052 {
00053     // make sure that the uri is not empty
00054     if (t.term_id.empty()) throw EmptyTermIdException();
00055     
00056     // make sure the Term does not already exist
00057     if (m_uri_map.find(t.term_id) != m_uri_map.end())
00058         throw DuplicateTermException(t.term_id);
00059     
00060     // create a new Term
00061     TermPtr term_ptr(new Term(t.term_id));
00062     term_ptr->term_ref = ++m_num_terms;
00063     term_ptr->term_type = t.term_type;
00064     term_ptr->term_comment = t.term_comment;
00065     // use a default size of '1' for char data type
00066     if (t.term_type == TYPE_CHAR && t.term_size == 0)
00067         term_ptr->term_size = 1;
00068     else
00069         term_ptr->term_size = t.term_size;
00070     term_ptr->term_format = t.term_format;
00071     
00072     // add it to the memory structures
00073     m_ref_map.push_back(term_ptr);
00074     m_uri_map.insert(std::make_pair(term_ptr->term_id, term_ptr));
00075     
00076     // return the new numeric identifier
00077     return term_ptr->term_ref;
00078 }
00079 
00080 void Vocabulary::removeTerm(const std::string& term_id)
00081 {
00082     // make sure the term_id is not empty
00083     if (term_id.empty())
00084         throw TermNotFoundException(term_id);
00085     
00086     // find the Term to remove
00087     TermStringMap::iterator uri_iterator = m_uri_map.find(term_id);
00088     if (uri_iterator == m_uri_map.end())
00089         throw TermNotFoundException(term_id);
00090 
00091     // change the TermRef so it doesn't get copied into other vocabularies
00092     uri_iterator->second->term_ref = UNDEFINED_TERM_REF;
00093     
00094     // remove the Term from the URI map
00095     m_uri_map.erase(uri_iterator);
00096     
00097     // leave the TermRef reference in-tact for any existing events
00098 }
00099 
00100 void Vocabulary::updateTerm(const Term& t)
00101 {
00102     // make sure the term_id is not empty
00103     if (t.term_id.empty())
00104         throw TermNotFoundException(t.term_id);
00105 
00106     // find the Term to update
00107     TermStringMap::iterator uri_iterator = m_uri_map.find(t.term_id);
00108     if (uri_iterator == m_uri_map.end())
00109         throw TermNotFoundException(t.term_id);
00110     Term& term_ref = *(uri_iterator->second);
00111     
00112     if (term_ref.term_type == t.term_type) {
00113         // same data type:
00114         // ok to just update the values in memory
00115         // since existing events should still be valid
00116         term_ref.term_comment = t.term_comment;
00117         term_ref.term_size = t.term_size;
00118         term_ref.term_format = t.term_format;
00119     } else {
00120         // don't change existing term so that existing events
00121         // with references always stay in-tact
00122 
00123         // remove the Term from the URI map
00124         m_uri_map.erase(uri_iterator);
00125 
00126         // add a new Term
00127         addTerm(t);
00128     }
00129 }
00130     
00131 void Vocabulary::refreshTerm(Term& t) const
00132 {
00133     // find Term in updated Vocabulary
00134     TermRef term_ref = findTerm(t.term_id);
00135 
00136     // check if the Term has been removed
00137     if (term_ref == UNDEFINED_TERM_REF)
00138         throw TermNoLongerDefinedException(t.term_id);
00139 
00140     // refresh term values
00141     t = *m_ref_map[term_ref];
00142 }
00143 
00144 const Vocabulary& Vocabulary::operator+=(const Vocabulary& v)
00145 {
00146     // copy over term object pointers
00147     for (TermRef n = 1; n <= v.m_num_terms; ++n) {
00148         if (v.m_ref_map[n]->term_ref != UNDEFINED_TERM_REF) {
00149             try { addTerm(*(v.m_ref_map[n])); }
00150             catch (...) {}
00151         }
00152     }
00153     return *this;
00154 }
00155     
00156 Vocabulary::DataType Vocabulary::parseDataType(std::string str)
00157 {
00158     // convert to lowercase
00159     for (std::string::iterator i=str.begin(); i!=str.end(); ++i)
00160         if (isupper(*i)) *i = tolower(*i);
00161     
00162     // parse str
00163     if (str=="null")
00164         return TYPE_NULL;
00165     else if (str == "int8") 
00166         return TYPE_INT8;
00167     else if (str == "uint8") 
00168         return TYPE_UINT8;
00169     else if (str == "int16") 
00170         return TYPE_INT16;
00171     else if (str == "uint16") 
00172         return TYPE_UINT16;
00173     else if (str == "int32") 
00174         return TYPE_INT32;
00175     else if (str == "uint32") 
00176         return TYPE_UINT32;
00177     else if (str == "int64") 
00178         return TYPE_INT64;
00179     else if (str == "uint64") 
00180         return TYPE_UINT64;
00181     else if (str == "float") 
00182         return TYPE_FLOAT;
00183     else if (str == "double") 
00184         return TYPE_DOUBLE;
00185     else if (str == "longdouble") 
00186         return TYPE_LONG_DOUBLE;
00187     else if (str == "shortstring") 
00188         return TYPE_SHORT_STRING;
00189     else if (str == "string") 
00190         return TYPE_STRING;
00191     else if (str == "longstring") 
00192         return TYPE_LONG_STRING;
00193     else if (str == "datetime") 
00194         return TYPE_DATE_TIME;
00195     else if (str == "date") 
00196         return TYPE_DATE;
00197     else if (str == "time") 
00198         return TYPE_TIME;
00199     else if (str == "char") 
00200         return TYPE_CHAR;
00201     else if (str == "blob")
00202         return TYPE_BLOB;
00203     else if (str == "zblob")
00204         return TYPE_ZBLOB;
00205     else if (str == "object") 
00206         return TYPE_OBJECT;
00207     
00208     throw UnknownDataTypeException(str);
00209 }
00210     
00211 std::string Vocabulary::getDataTypeAsString(const DataType data_type)
00212 {
00213     std::string str;
00214     switch(data_type) {
00215         case TYPE_NULL:
00216             str = "null";
00217             break;
00218         case TYPE_INT8:
00219             str = "int8";
00220             break;
00221         case TYPE_UINT8:
00222             str = "uint8";
00223             break;
00224         case TYPE_INT16:
00225             str = "int16";
00226             break;
00227         case TYPE_UINT16:
00228             str = "uint16";
00229             break;
00230         case TYPE_INT32:
00231             str = "int32";
00232             break;
00233         case TYPE_UINT32:
00234             str = "uint32";
00235             break;
00236         case TYPE_INT64:
00237             str = "int64";
00238             break;
00239         case TYPE_UINT64:
00240             str = "uint64";
00241             break;
00242         case TYPE_FLOAT:
00243             str = "float";
00244             break;
00245         case TYPE_DOUBLE:
00246             str = "double";
00247             break;
00248         case TYPE_LONG_DOUBLE:
00249             str = "longdouble";
00250             break;
00251         case TYPE_SHORT_STRING:
00252             str = "shortstring";
00253             break;
00254         case TYPE_STRING:
00255             str = "string";
00256             break;
00257         case TYPE_LONG_STRING:
00258             str = "longstring";
00259             break;
00260         case TYPE_DATE_TIME:
00261             str = "datetime";
00262             break;
00263         case TYPE_DATE:
00264             str = "date";
00265             break;
00266         case TYPE_TIME:
00267             str = "time";
00268             break;
00269         case TYPE_CHAR:
00270             str = "char";
00271             break;
00272         case TYPE_BLOB:
00273             str = "blob";
00274             break;
00275         case TYPE_ZBLOB:
00276             str = "zblob";
00277             break;
00278         case TYPE_OBJECT:
00279             str = "object";
00280             break;
00281     }
00282     return str;
00283 }
00284     
00285     
00286 }   // end namespace platform
00287 }   // end namespace pion

Generated on Wed Apr 13 16:38:34 2011 for pion-platform by  doxygen 1.4.7