DataTypeRegistry.cpp
Go to the documentation of this file.
00001 /******************************************************************************
00002  * Copyright (C) 2014 by Ralf Kaestner                                        *
00003  * ralf.kaestner@gmail.com                                                    *
00004  *                                                                            *
00005  * This program is free software; you can redistribute it and/or modify       *
00006  * it under the terms of the Lesser GNU General Public License as published by*
00007  * the Free Software Foundation; either version 3 of the License, or          *
00008  * (at your option) any later version.                                        *
00009  *                                                                            *
00010  * This program is distributed in the hope that it will be useful,            *
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the               *
00013  * Lesser GNU General Public License for more details.                        *
00014  *                                                                            *
00015  * You should have received a copy of the Lesser GNU General Public License   *
00016  * along with this program. If not, see <http://www.gnu.org/licenses/>.       *
00017  ******************************************************************************/
00018 
00019 #include "variant_topic_tools/DataTypeRegistry.h"
00020 #include "variant_topic_tools/Exceptions.h"
00021 #include "variant_topic_tools/MessageDefinitionParser.h"
00022 
00023 namespace variant_topic_tools {
00024 
00025 /*****************************************************************************/
00026 /* Static initializations                                                    */
00027 /*****************************************************************************/
00028 
00029 DataTypeRegistry::ImplPtr DataTypeRegistry::impl(new DataTypeRegistry::Impl());
00030 
00031 /*****************************************************************************/
00032 /* Constructors and Destructor                                               */
00033 /*****************************************************************************/
00034 
00035 DataTypeRegistry::DataTypeRegistry() {
00036   if (impl->dataTypesByIdentifier.empty()) {
00037     addBuiltinDataType<bool>("bool");
00038     addBuiltinDataType<double>("float64");
00039     addBuiltinDataType<float>("float32");
00040     addBuiltinDataType<int16_t>("int16");
00041     addBuiltinDataType<int32_t>("int32");
00042     addBuiltinDataType<int64_t>("int64");
00043     addBuiltinDataType<int8_t>("int8");
00044     addBuiltinDataType<uint16_t>("uint16");
00045     addBuiltinDataType<uint32_t>("uint32");
00046     addBuiltinDataType<uint64_t>("uint64");
00047     addBuiltinDataType<uint8_t>("uint8");
00048     
00049     addBuiltinDataType<uint8_t>("char");
00050     addBuiltinDataType<int8_t>("byte");
00051     
00052     addBuiltinDataType<ros::Duration>("duration");
00053     addBuiltinDataType<std::string>("string");
00054     addBuiltinDataType<ros::Time>("time");
00055   }
00056 }
00057 
00058 DataTypeRegistry::~DataTypeRegistry() {
00059 }
00060 
00061 DataTypeRegistry::Impl::Impl() {
00062 }
00063 
00064 DataTypeRegistry::Impl::~Impl() {
00065 }
00066 
00067 /*****************************************************************************/
00068 /* Accessors                                                                 */
00069 /*****************************************************************************/
00070 
00071 DataType DataTypeRegistry::getDataType(const std::string& identifier) {
00072   boost::unordered_map<std::string, DataType>::const_iterator it =
00073     impl->dataTypesByIdentifier.find(identifier);
00074   
00075   if (it != impl->dataTypesByIdentifier.end())
00076     return it->second;
00077   
00078   std::string name, memberType;
00079   size_t size;
00080   
00081   if (MessageDefinitionParser::matchArrayType(identifier, memberType,
00082       size)) {
00083     boost::unordered_map<std::string, DataType>::const_iterator jt =
00084       impl->dataTypesByIdentifier.find(memberType);
00085     
00086     if (jt != impl->dataTypesByIdentifier.end())
00087       return addArrayDataType(jt->second, size);
00088   }
00089   
00090   return DataType();
00091 }
00092 
00093 DataType DataTypeRegistry::getDataType(const std::string& identifier) const {
00094   boost::unordered_map<std::string, DataType>::const_iterator it =
00095     impl->dataTypesByIdentifier.find(identifier);
00096   
00097   if (it != impl->dataTypesByIdentifier.end())
00098     return it->second;
00099   else
00100     return DataType();
00101 }
00102 
00103 DataType DataTypeRegistry::getDataType(const std::type_info& typeInfo) const {
00104   boost::unordered_multimap<const std::type_info*, DataType, TypeInfoHash>::
00105     const_iterator it = impl->dataTypesByInfo.find(&typeInfo);
00106     
00107   if (it != impl->dataTypesByInfo.end())
00108     return it->second;
00109   else
00110     return DataType();
00111 }
00112 
00113 /*****************************************************************************/
00114 /* Methods                                                                   */
00115 /*****************************************************************************/
00116 
00117 ArrayDataType DataTypeRegistry::addArrayDataType(const DataType& memberType,
00118     size_t numMembers) {
00119   ArrayDataType arrayDataType(memberType, numMembers);
00120   addDataType(arrayDataType);
00121   
00122   return arrayDataType;
00123 }
00124 
00125 MessageDataType DataTypeRegistry::addMessageDataType(const std::string&
00126     identifier, const MessageFieldCollection<MessageConstant>& constantMembers,
00127     const MessageFieldCollection<MessageVariable>& variableMembers) {
00128   MessageDataType messageDataType(identifier, constantMembers,
00129     variableMembers);
00130   addDataType(messageDataType);
00131   
00132   return messageDataType;
00133 }
00134 
00135 MessageDataType DataTypeRegistry::addMessageDataType(const std::string&
00136     identifier, const std::string& definition) {
00137   MessageDataType messageDataType(identifier, definition);
00138   addDataType(messageDataType);
00139   
00140   return messageDataType;
00141 }
00142 
00143 void DataTypeRegistry::addDataType(const DataType& dataType) {
00144   if (dataType.isValid()) {
00145     boost::unordered_map<std::string, DataType>::iterator it =
00146       impl->dataTypesByIdentifier.find(dataType.getIdentifier());
00147       
00148     if (it == impl->dataTypesByIdentifier.end()) {
00149       impl->dataTypesByIdentifier.insert(
00150         std::make_pair(dataType.getIdentifier(), dataType));
00151       
00152       if (dataType.hasTypeInfo())
00153         impl->dataTypesByInfo.insert(
00154           std::make_pair(&dataType.getTypeInfo(), dataType));
00155     }
00156     else if (!it->second.hasTypeInfo() && dataType.hasTypeInfo()) {
00157       it->second = dataType;
00158       
00159       impl->dataTypesByInfo.insert(
00160         std::make_pair(&dataType.getTypeInfo(), dataType));
00161     }
00162     else
00163       throw AmbiguousDataTypeIdentifierException(it->first);
00164   }
00165   else
00166     throw InvalidDataTypeException();
00167 }
00168 
00169 void DataTypeRegistry::removeDataType(const DataType& dataType) {
00170   if (dataType.isValid()) {
00171     boost::unordered_map<std::string, DataType>::iterator it =
00172       impl->dataTypesByIdentifier.find(dataType.getIdentifier());
00173       
00174     if ((it != impl->dataTypesByIdentifier.end()) &&
00175         (it->second.impl == dataType.impl))
00176       impl->dataTypesByIdentifier.erase(it);
00177     
00178     if (dataType.hasTypeInfo()) {
00179       typedef boost::unordered_multimap<const std::type_info*, DataType,
00180         TypeInfoHash>::iterator Iterator;
00181         
00182       std::pair<Iterator, Iterator> range =
00183         impl->dataTypesByInfo.equal_range(&dataType.getTypeInfo());
00184       for (Iterator it = range.first; it != range.second; ++it) {
00185         if (it->second.impl == dataType.impl) {
00186           impl->dataTypesByInfo.erase(it);
00187           break;
00188         }
00189       }
00190     }
00191   }
00192   else
00193     throw InvalidDataTypeException();
00194 }
00195 
00196 void DataTypeRegistry::clear() {
00197   impl->dataTypesByIdentifier.clear();
00198   impl->dataTypesByInfo.clear();
00199 }
00200 
00201 void DataTypeRegistry::write(std::ostream& stream) const {
00202   for (boost::unordered_map<std::string, DataType>::const_iterator
00203       it = impl->dataTypesByIdentifier.begin();
00204       it != impl->dataTypesByIdentifier.end(); ++it) {
00205     if (it != impl->dataTypesByIdentifier.begin())
00206       stream << "\n";
00207     stream << it->second;
00208   }
00209 }
00210 
00211 /*****************************************************************************/
00212 /* Operators                                                                 */
00213 /*****************************************************************************/
00214 
00215 DataType DataTypeRegistry::operator[](const std::string& identifier) {
00216   return getDataType(identifier);
00217 }
00218 
00219 DataType DataTypeRegistry::operator[](const std::string& identifier) const {
00220   return getDataType(identifier);
00221 }
00222 
00223 DataType DataTypeRegistry::operator[](const std::type_info& typeInfo) const {
00224   return getDataType(typeInfo);
00225 }
00226 
00227 std::ostream& operator<<(std::ostream& stream, const DataTypeRegistry&
00228     dataTypeRegistry) {
00229   dataTypeRegistry.write(stream);
00230   return stream;
00231 }
00232 
00233 }


variant_topic_tools
Author(s): Ralf Kaestner
autogenerated on Tue Jul 9 2019 03:18:42