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;
}
Esempio n. 2
0
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);
        }
      }
    }
  }
}