/* PIP - Platform Independent Primitives Code model generator Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ #include "json.h" #include "pitranslator.h" bool writeClassJSONMembersOut(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix) { if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += "."; PIVector ml; for (const PICodeParser::Member & m: e->members) { if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue; ml << m; } bool is_union = e->type == "union"; for (const PICodeParser::Member & m: ml) { if (m.isBitfield()) continue; if (m.attributes[PICodeParser::Static]) continue; if (m.meta.value("id") == "-") continue; // if (m.meta.contains("id")) cnt = m.meta.value("id").toInt(); auto type = findEntity(rt, m.type); if (type) { if (type->is_anonymous) { writeClassJSONMembersOut(rt, type, var_prefix + m.name); continue; } } if (m.dims.isEmpty()) { rt.ts << "\tret[\"" << var_prefix << m.name << "\"] = piSerializeJSON(v." << var_prefix << m.name << ");\n"; } else { PIString ptype = m.type.left(m.type.find('[')).trim(); PIString size = m.dims[0]; for (int i = 1; i < m.dims.size_s(); ++i) { size += " * "; size += m.dims[i]; } rt.ts << "\tret[\"" << var_prefix << m.name << "\"] = piSerializeJSON(PIVector<" << ptype << " >((const " << ptype << " *)(v." << var_prefix << m.name << "), " << size << "));\n"; } if (is_union) break; } if (is_union) return true; /*for (const PICodeParser::Entity * ce: e->children) { if (!ce->is_anonymous) continue; if (!writeClassJSONMembersOut(rt, ce)) return false; }*/ return true; } bool writeClassJSONMembersIn(Runtime & rt, const PICodeParser::Entity * e, PIString var_prefix) { if (var_prefix.isNotEmpty() && !var_prefix.endsWith('.')) var_prefix += "."; PIVector ml; for (const PICodeParser::Member & m: e->members) { if (m.is_type_ptr || (m.visibility != PICodeParser::Public)) continue; ml << m; } bool is_union = e->type == "union"; PISet used_id; for (const PICodeParser::Member & m: ml) { if (m.isBitfield()) continue; if (m.attributes[PICodeParser::Static]) continue; if (m.meta.value("id") == "-") continue; auto type = findEntity(rt, m.type); if (type) { if (type->is_anonymous) { writeClassJSONMembersIn(rt, type, var_prefix + m.name); continue; } } // if (m.meta.contains("id")) cnt = m.meta.value("id").toInt(); if (m.dims.isEmpty()) { rt.ts << "\tpiDeserializeJSON(v." << var_prefix << m.name << ", js[\"" << var_prefix << m.name << "\"]);\n"; } else { PIString ptype = m.type.left(m.type.find('[')).trim(); PIString size = m.dims[0]; for (int i = 1; i < m.dims.size_s(); ++i) { size += " * "; size += m.dims[i]; } rt.ts << "\t{\n\t\tPIVector<" << ptype << " > d;\n"; rt.ts << "\t\tpiDeserializeJSON(d, js[\"" << var_prefix << m.name << "\"]);\n"; rt.ts << "\t\tint cnt = piMini(d.size_s(), " << size << ");\n"; rt.ts << "\t\tfor (int i = 0; i < cnt; ++i)\n"; rt.ts << "\t\t\t((" << ptype << " *)(v." << var_prefix << m.name << "))[i] = d[i];\n"; rt.ts << "\t}\n"; } if (is_union) break; } if (is_union) return true; /*for (const PICodeParser::Entity * ce: e->children) { if (!ce->is_anonymous) continue; if (!writeClassJSONMembersIn(rt, ce)) return false; }*/ return true; } bool needClassJSON(const PICodeParser::Entity * e) { if (e->meta.contains("no-json")) return false; for (const PICodeParser::Member & m: e->members) { if (m.is_type_ptr || m.isBitfield() || !m.dims.isEmpty() || (m.visibility != PICodeParser::Public)) continue; if (m.attributes[PICodeParser::Static]) continue; if (m.meta.value("id") == "-") continue; return true; } return false; } bool makeClassJSON(Runtime & rt, const PICodeParser::Entity * e) { if (!needClassJSON(e)) return true; rt.ts << "\ntemplate<> inline PIJSON piSerializeJSON(const " << e->name << " & v) {\n"; rt.ts << "\tPIJSON ret;\n"; if (!writeClassJSONMembersOut(rt, e)) return false; rt.ts << "\treturn ret;\n}\n"; rt.ts << "\ntemplate<> inline void piDeserializeJSON(" << e->name << " & v, const PIJSON & js) {\n"; if (!writeClassJSONMembersIn(rt, e)) return false; rt.ts << "}\n"; return true; }