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); } } } } }