def gen_field_map_assgin_stmt(self, prefix, typename, name, row_name, map_delims, tabs): assert len(map_delims) == 2, map_delims delim1 = map_delims[0].strip() if delim1 == '\\': delim1 = '\\\\' delim2 = map_delims[1].strip() if delim2 == '\\': delim2 = '\\\\' k, v = types.map_key_value_types(typename) key_type = lang.map_cpp_type(k) val_type = lang.map_cpp_type(v) space = self.TAB_SPACE * (tabs + 1) content = '%s{\n' % (self.TAB_SPACE * tabs) content += '%sconst auto& mapitems = Split(%s, "%s", true);\n' % ( space, row_name, delim1) content += '%sfor (size_t i = 0; i < mapitems.size(); i++)\n' % space content += '%s{\n' % space content += '%s const auto& kv = Split(mapitems[i], "%s", true);\n' % ( space, delim2) content += '%s ASSERT(kv.size() == 2);\n' % space content += '%s if(kv.size() == 2)\n' % space content += '%s {\n' % space content += '%s const auto& key = ParseValue<%s>(kv[0]);\n' % ( space, key_type) content += '%s ASSERT(%s%s.count(key) == 0);\n' % (space, prefix, name) content += '%s %s%s[key] = ParseValue<%s>(kv[1]);\n' % ( space, prefix, name, val_type) content += '%s }\n' % space content += '%s}\n' % space content += '%s}\n' % (self.TAB_SPACE * tabs) return content
def gen_cpp_struct_define(self, struct): content = '// %s\n' % struct['comment'] content += 'struct %s \n{\n' % struct['name'] fields = struct['fields'] if struct['options'][predef.PredefParseKVMode]: fields = genutil.get_struct_kv_fields(struct) inner_class_done = False inner_typename = '' inner_var_name = '' inner_field_names, mapped_inner_fields = genutil.get_inner_class_mapped_fields( struct) if len(mapped_inner_fields) > 0: content += self.gen_inner_struct_define(struct) inner_type_class = struct["options"][predef.PredefInnerTypeClass] inner_var_name = struct["options"][predef.PredefInnerTypeName] inner_typename = 'std::vector<%s>' % inner_type_class vec_done = False vec_names, vec_name = genutil.get_vec_field_range(struct) max_name_len = strutil.max_field_length(fields, 'name', None) max_type_len = strutil.max_field_length(fields, 'original_type_name', lang.map_cpp_type) if len(inner_typename) > max_type_len: max_type_len = len(inner_typename) for field in fields: field_name = field['name'] if field_name in inner_field_names: if not inner_class_done: typename = strutil.pad_spaces(inner_typename, max_type_len + 1) name = strutil.pad_spaces(inner_var_name, max_name_len + 8) content += ' %s %s; //\n' % (typename, name) inner_class_done = True else: typename = lang.map_cpp_type(field['original_type_name']) assert typename != "", field['original_type_name'] typename = strutil.pad_spaces(typename, max_type_len + 1) if field_name not in vec_names: name = lang.name_with_default_cpp_value(field, typename) name = strutil.pad_spaces(name, max_name_len + 8) content += ' %s %s // %s\n' % (typename, name, field['comment']) elif not vec_done: name = '%s[%d];' % (vec_name, len(vec_names)) name = strutil.pad_spaces(name, max_name_len + 8) content += ' %s %s // %s\n' % (typename, name, field['comment']) vec_done = True return content
def gen_all_field_assign_stmt(self, struct, prefix, tabs): content = '' idx = 0 array_delim = struct['options'].get(predef.OptionArrayDelimeter, predef.DefaultArrayDelimiter) map_delims = struct['options'].get(predef.OptionMapDelimeters, predef.DefaultMapDelimiters) inner_class_done = False inner_field_names, inner_fields = genutil.get_inner_class_mapped_fields( struct) vec_names, vec_name = genutil.get_vec_field_range(struct) vec_idx = 0 space = self.TAB_SPACE * tabs for field in struct['fields']: field_name = field['name'] if field_name in inner_field_names: if not inner_class_done: inner_class_done = True content += self.gen_inner_class_field_assgin_stmt( struct, prefix) else: origin_type = field['original_type_name'] typename = lang.map_cpp_type(origin_type) if typename != 'std::string' and field['name'] in vec_names: content += '%s%s%s[%d] = %s;\n' % ( space, prefix, vec_name, vec_idx, lang.default_value_by_cpp_type(origin_type)) if origin_type.startswith('array'): content += self.gen_field_array_assign_stmt( prefix, origin_type, field_name, ('row[%d]' % idx), array_delim, tabs) elif origin_type.startswith('map'): content += self.gen_field_map_assgin_stmt( prefix, origin_type, field_name, ('row[%d]' % idx), map_delims, tabs) else: if field['name'] in vec_names: content += '%s%s%s[%d] = ParseValue<%s>(row[%d]);\n' % ( self.TAB_SPACE * (tabs), prefix, vec_name, vec_idx, typename, idx) vec_idx += 1 else: content += '%s%s%s = ParseValue<%s>(row[%d]);\n' % ( self.TAB_SPACE * (tabs), prefix, field_name, typename, idx) idx += 1 return content
def gen_field_array_assign_stmt(self, prefix, typename, name, row_name, array_delim, tabs): assert len(array_delim) == 1 array_delim = array_delim.strip() if array_delim == '\\': array_delim = '\\\\' space = self.TAB_SPACE * (tabs + 1) elemt_type = lang.map_cpp_type(types.array_element_type(typename)) content = '%s{\n' % (self.TAB_SPACE * tabs) content += '%sconst auto& array = Split(%s, "%s", true);\n' % (space, row_name, array_delim) content += '%sfor (size_t i = 0; i < array.size(); i++)\n' % space content += '%s{\n' % space content += '%s %s%s.push_back(ParseValue<%s>(array[i]));\n' % (space, prefix, name, elemt_type) content += '%s}\n' % space content += '%s}\n' % (self.TAB_SPACE * tabs) return content
def gen_inner_class_field_assgin_stmt(self, struct, prefix): content = '' inner_class_type = struct["options"][predef.PredefInnerTypeClass] inner_var_name = struct["options"][predef.PredefInnerTypeName] inner_fields = genutil.get_inner_class_struct_fields(struct) start, end, step = genutil.get_inner_class_range(struct) assert start > 0 and end > 0 and step > 1 content += ' for (int i = %s; i < %s; i += %s) \n' % (start, end, step) content += ' {\n' content += ' %s item;\n' % inner_class_type for n in range(step): field = inner_fields[n] origin_type = field['original_type_name'] typename = lang.map_cpp_type(origin_type) content += ' item.%s = ParseValue<%s>(row[i + %d]);\n' % (field['name'], typename, n) content += ' %s%s.push_back(item);\n' % (prefix, inner_var_name) content += ' }\n' return content
def gen_kv_parse_method(self, struct): rows = struct['data_rows'] keycol = struct['options'][predef.PredefKeyColumn] valcol = struct['options'][predef.PredefValueColumn] typcol = int(struct['options'][predef.PredefValueTypeColumn]) assert keycol > 0 and valcol > 0 and typcol > 0 keyidx, keyfield = genutil.get_field_by_column_index(struct, keycol) validx, valfield = genutil.get_field_by_column_index(struct, valcol) typeidx, typefield = genutil.get_field_by_column_index(struct, typcol) array_delim = struct['options'].get(predef.OptionArrayDelimeter, predef.DefaultArrayDelimiter) map_delims = struct['options'].get(predef.OptionMapDelimeters, predef.DefaultMapDelimiters) content = '' content += '// parse data object from csv rows\n' content += 'int %s::ParseFromRows(const vector<vector<StringPiece>>& rows, %s* ptr)\n' % ( struct['name'], struct['name']) content += '{\n' content += ' ASSERT(rows.size() >= %d && rows[0].size() >= %d);\n' % ( len(rows), validx) content += ' ASSERT(ptr != nullptr);\n' idx = 0 for row in rows: name = rows[idx][keyidx].strip() origin_typename = rows[idx][typeidx].strip() typename = lang.map_cpp_type(origin_typename) row_name = 'rows[%d][%d]' % (idx, validx) if origin_typename.startswith('array'): content += self.gen_field_array_assign_stmt( 'ptr->', origin_typename, name, row_name, array_delim, 1) elif origin_typename.startswith('map'): content += self.gen_field_map_assgin_stmt( 'ptr->', origin_typename, name, row_name, map_delims, 1) else: content += '%sptr->%s = ParseValue<%s>(%s);\n' % ( self.TAB_SPACE, name, typename, row_name) idx += 1 content += ' return 0;\n' content += '}\n\n' return content
def gen_inner_struct_define(self, struct): inner_fields = genutil.get_inner_class_struct_fields(struct) content = '' class_name = struct["options"][predef.PredefInnerTypeClass] content += ' struct %s \n' % class_name content += ' {\n' max_name_len = strutil.max_field_length(inner_fields, 'name', None) max_type_len = strutil.max_field_length(inner_fields, 'original_type_name', lang.map_cpp_type) for field in inner_fields: typename = lang.map_cpp_type(field['original_type_name']) assert typename != "", field['original_type_name'] typename = strutil.pad_spaces(typename, max_type_len + 1) name = lang.name_with_default_cpp_value(field, typename) name = strutil.pad_spaces(name, max_name_len + 8) content += ' %s %s // %s\n' % (typename, name, field['comment']) content += ' };\n\n' return content