#include #include "Json2Flatbuffer.hpp" #define VECTOR_EXTRACT(FLATBUFFER_TYPE, CPP_TYPE, JSON_TYPE)\ case flatbuffers::ET_##FLATBUFFER_TYPE:\ {\ std::vector data(array.Size());\ for (int i=0; ivalue.JSON_TYPE()), (CPP_TYPE)0);\ break;\ } namespace MNN { flatbuffers::Offset Json2Flatbuffer::writeJsonToFlatbuffer(const flatbuffers::TypeTable * table, flatbuffers::FlatBufferBuilder& builder, const rapidjson::GenericObject>>& object) { std::vector>> indexes; // Load union type for easy to use std::map unionNames; for (int i=0; inum_elems; ++i) { if (table->type_codes[i].sequence_ref == -1) { continue; } const flatbuffers::TypeTable *ref = table->type_refs[table->type_codes[i].sequence_ref](); if (ref->st == flatbuffers::ST_UNION) { unionNames.insert(std::make_pair(std::string(table->names[i]) + "_type", i)); } } // Find index and cache std::map unionTypes; for (auto iter = object.begin(); iter !=object.end(); iter++) { auto name = iter->name.GetString(); int index = -1; for (int i=0; inum_elems; ++i) { if (0 == ::strcmp(table->names[i], name)) { index = i; break; } } auto uiter = unionNames.find(name); if (uiter != unionNames.end()) { // Find union type id auto value = iter->value.GetString(); int typePos = -1; auto unionIndex = uiter->second; auto ref = table->type_refs[table->type_codes[unionIndex].sequence_ref](); for (int j=0; jnum_elems; ++j) { if (0 == ::strcmp(ref->names[j], value)) { typePos = j; break; } } if (-1 == typePos) { MNN_ERROR("Can't find union type\n"); continue; } if (typePos > 0) { // First is None unionTypes.insert(std::make_pair(unionIndex, typePos-1)); } } if (index == -1) { MNN_PRINT("Invalid: %s, Skip it\n", name); } indexes.emplace_back(std::make_pair(index, 0)); } // resolve single object int pos = 0; for (auto iter = object.begin(); iter !=object.end(); iter++, pos++) { int index = indexes[pos].first; if (-1 == index) { continue; } auto code = table->type_codes[index]; if (code.is_vector) { continue; } if (code.sequence_ref != -1 && code.base_type == flatbuffers::ET_SEQUENCE) { const flatbuffers::TypeTable *ref = table->type_refs[code.sequence_ref](); if (ref->st == flatbuffers::ST_TABLE) { indexes[pos].second = writeJsonToFlatbuffer(ref, builder, iter->value.GetObject()); } else if (ref->st == flatbuffers::ST_UNION) { auto unionInd = unionTypes.find(index)->second; ref = ref->type_refs[unionInd](); indexes[pos].second = writeJsonToFlatbuffer(ref, builder, iter->value.GetObject()); } } } // Resolve Vector and String pos = 0; for (auto iter = object.begin(); iter !=object.end(); iter++, pos++) { int index = indexes[pos].first; if (-1 == index) { continue; } auto code = table->type_codes[index]; if (!code.is_vector) { if (code.base_type == flatbuffers::ET_STRING) { indexes[pos].second = builder.CreateString(iter->value.GetString()).Union(); } continue; } auto array = iter->value.GetArray(); if (code.sequence_ref != -1) { const flatbuffers::TypeTable *ref = table->type_refs[code.sequence_ref](); std::vector> offsets(array.Size()); for (int i=0; i data(array.Size()); for (int i=0; itype_codes[index]; if (code.sequence_ref != -1) { const flatbuffers::TypeTable *ref = table->type_refs[code.sequence_ref](); int value = -1; if (ref->st == flatbuffers::ST_UNION || ref->st == flatbuffers::ST_ENUM) { auto type = iter->value.GetString(); for (int i=0; inum_elems; ++i) { if (0 == ::strcmp(type, ref->names[i])) { if (nullptr == ref->values) { value = i; } else { value = ref->values[i]; } } } switch (code.base_type) { case flatbuffers::ET_UTYPE: case flatbuffers::ET_UINT: builder.AddElement(field, (uint32_t)value, (uint32_t)0); break; case flatbuffers::ET_INT: builder.AddElement(field, (int32_t)value, (int32_t)-1); break; case flatbuffers::ET_UCHAR: builder.AddElement(field, (uint8_t)value, (uint8_t)0); break; case flatbuffers::ET_CHAR: builder.AddElement(field, (int8_t)value, (int8_t)0); break; default: break; } continue; } } switch (code.base_type) { SCALAR_EXTRACT(BOOL, bool, GetBool); SCALAR_EXTRACT(CHAR, char, GetInt); SCALAR_EXTRACT(UCHAR, uint8_t, GetInt); SCALAR_EXTRACT(SHORT, int16_t, GetInt); SCALAR_EXTRACT(USHORT, uint16_t, GetInt); SCALAR_EXTRACT(INT, int, GetInt); SCALAR_EXTRACT(UINT, uint32_t, GetUint); SCALAR_EXTRACT(LONG, int64_t, GetInt64); SCALAR_EXTRACT(ULONG, uint64_t, GetUint64); SCALAR_EXTRACT(FLOAT, float, GetFloat); SCALAR_EXTRACT(DOUBLE, double, GetDouble); default: break; } } return builder.EndTable(start); } };