void BagInfo::readRawMsgDefs(const vector<const rosbag::ConnectionInfo*> &connections) { for (int i = 0; i < connections.size(); ++i) { const rosbag::ConnectionInfo *ci = connections.at(i); if (msg_defs_.count(ci->datatype) == 0) { const boost::regex msg_sep_re(g_message_split_regexp); vector<string> split; boost::split_regex(split, ci->msg_def, msg_sep_re); ROSMessageFields rmf; boost::trim(split.at(0)); ROSType type; type.populate(ci->datatype); // Add mapping from fully qualified type msg_defs_[type.base_type] = split.at(0); // Add mapping from name (i.e., no package) msg_defs_[type.msg_name] = "MSG: " + ci->datatype + "\n" + split.at(0); for (size_t i = 1; i < split.size(); ++i) { rmf.populate(split.at(i)); size_t first_newline = split.at(i).find('\n'); if (first_newline == string::npos) { throw invalid_argument(split.at(i)); } string msg_def = split.at(i).substr(first_newline); boost::trim(msg_def); // Add mapping from fully qualified type msg_defs_[rmf.type().base_type] = msg_def; // Add mapping from name (i.e., no package) boost::trim(split.at(i)); msg_defs_[rmf.type().msg_name] = split.at(i); } } } }
bool is_flattenable(const ROSMessageFields &fields) { bool flattenable = true; for (int i = 0; i < fields.nfields(); ++i) { const ROSMessageFields::Field &rmf = fields.at(i); const ROSType &type = rmf.type; flattenable &= (!rmf.constant && type.is_builtin && !type.is_array && type.type_size != -1); } return flattenable; }
void ROSTypeMap::populate(const string &msg_def) { // Split into disparate message type definitions std::vector<std::string> split; boost::regex msg_sep_re(g_message_split_regexp); boost::split_regex(split, msg_def, msg_sep_re); // Parse individual message types and make map from msg_name -> qualified name std::vector<ROSMessageFields*> types(split.size()); for (size_t i = 0; i < split.size(); ++i) { ROSMessageFields *rmf = new ROSMessageFields(); try { rmf->populate(split[i]); } catch (exception &e) { delete rmf; throw; } type_map_[rmf->type().name] = rmf; resolver_[rmf->type().msg_name].push_back(rmf->type().pkg_name); // If we throw, rmf will be freed because it's in type_map_ if (!rmf->type().is_qualified) { throw invalid_argument("Couldn't determine type in message:\n" + split[i] + "\nFull message def is:\n" + msg_def); } } for (map<string, ROSMessageFields*>::iterator it = type_map_.begin(); it != type_map_.end(); ++it) { ROSMessageFields *rmf = (*it).second; for (int i = 0; i < rmf->nfields(); ++i) { const ROSMessageFields::Field &field = rmf->at(i); if (!field.type.is_qualified) { const vector<string> qualified_names = resolver_[field.type.msg_name]; if (qualified_names.size() == 1) { rmf->setFieldPkgName(i, qualified_names[0]); } else { throw invalid_argument("Multiple types for " + field.type.msg_name + "\nMessage def: \n" + msg_def); } } } } }