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
1.4.7