Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00027
00028
00029 DataTypeRegistry::ImplPtr DataTypeRegistry::impl(new DataTypeRegistry::Impl());
00030
00031
00032
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
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
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
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 }