diff --git a/CMakeLists.txt b/CMakeLists.txt index 2f58c73..94aaafa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -117,13 +117,20 @@ set(LIBSIGMF_GEN_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/sigmf_protocols") ######################################################################## # Our interface target that downstream have to use ######################################################################## -add_library(libsigmf INTERFACE) -target_include_directories(libsigmf INTERFACE +add_library(libsigmf + STATIC + ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/flatbuffers_json_visitor.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/json_wrap.cpp + ) +target_include_directories(libsigmf + INTERFACE $ - $ + $ $ $ -) + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/src/include + ) if (${Flatbuffers_FOUND}) # System flatbuffers can import this target @@ -131,8 +138,11 @@ if (${Flatbuffers_FOUND}) flatbuffers::flatbuffers_shared ) else() - target_include_directories(libsigmf INTERFACE + target_include_directories(libsigmf + INTERFACE $ + PRIVATE + ${FLATBUFFERS_INCLUDE_DIR} ) endif(${Flatbuffers_FOUND}) @@ -140,8 +150,11 @@ if (${nlohmann_json_FOUND}) # TODO: add target_link_libraries interface to nlohmann json # when we use the system version else() - target_include_directories(libsigmf INTERFACE + target_include_directories(libsigmf + INTERFACE $ + PRIVATE + ${JSON_INCLUDE_DIR} ) endif(${nlohmann_json_FOUND}) @@ -176,15 +189,15 @@ configure_file( ######################################################################## install( # install flatbuf proto defs DIRECTORY ${LIBSIGMF_GEN_HEADERS}/ - DESTINATION include/sigmf/fbs + DESTINATION include/libsigmf/fbs FILES_MATCHING PATTERN "*.fbs)") install( # install generated headers DIRECTORY ${LIBSIGMF_GEN_HEADERS}/ - DESTINATION include/sigmf + DESTINATION include/libsigmf FILES_MATCHING PATTERN "*.h") install( # install original headers - DIRECTORY ${CMAKE_SOURCE_DIR}/src/ - DESTINATION include/sigmf + DIRECTORY ${CMAKE_SOURCE_DIR}/src/include + DESTINATION include/ FILES_MATCHING PATTERN "*.h") ######################################################################## diff --git a/examples/example_reading_sigmf_file.cpp b/examples/example_reading_sigmf_file.cpp index 3bf3cfb..c45c0c7 100644 --- a/examples/example_reading_sigmf_file.cpp +++ b/examples/example_reading_sigmf_file.cpp @@ -16,8 +16,8 @@ #include "sigmf_core_generated.h" #include "sigmf_antenna_generated.h" -#include "sigmf.h" -#include "sigmf_helpers.h" +#include "libsigmf/sigmf.h" +#include "libsigmf/sigmf_helpers.h" #include #include @@ -27,5 +27,5 @@ int main(int argc, char* argv[]) { auto record = sigmf::metadata_file_to_json(meta_fstream); std::cout << "The record we read is: \n" << - record->to_json().dump(2) << std::endl; + to_json(record).dump(2) << std::endl; } \ No newline at end of file diff --git a/examples/example_record_with_multiple_namespaces.cpp b/examples/example_record_with_multiple_namespaces.cpp index f6b078d..e75b165 100644 --- a/examples/example_record_with_multiple_namespaces.cpp +++ b/examples/example_record_with_multiple_namespaces.cpp @@ -16,7 +16,8 @@ #include "sigmf_core_generated.h" #include "sigmf_antenna_generated.h" -#include "sigmf.h" +#include "libsigmf/sigmf.h" +#include int main() { diff --git a/examples/example_record_with_variadic_dataclass.cpp b/examples/example_record_with_variadic_dataclass.cpp index 4b40e66..87e2beb 100644 --- a/examples/example_record_with_variadic_dataclass.cpp +++ b/examples/example_record_with_variadic_dataclass.cpp @@ -16,7 +16,7 @@ #include "sigmf_core_generated.h" -#include "sigmf.h" +#include "libsigmf/sigmf.h" #include int main() { diff --git a/examples/example_sigmf_json_roundtrip.cpp b/examples/example_sigmf_json_roundtrip.cpp index 25927f0..1139d9f 100644 --- a/examples/example_sigmf_json_roundtrip.cpp +++ b/examples/example_sigmf_json_roundtrip.cpp @@ -14,8 +14,9 @@ * limitations under the License. */ -#include "sigmf.h" +#include "libsigmf/sigmf.h" #include +#include int main() { diff --git a/external/json b/external/json index 68ec3eb..e7b3b40 160000 --- a/external/json +++ b/external/json @@ -1 +1 @@ -Subproject commit 68ec3eb8d633770fabb2029c10511bd4664577dc +Subproject commit e7b3b40b5a95bc74b9a7f662830a27c49ffc01b4 diff --git a/src/annotation.h b/src/include/libsigmf/annotation.h similarity index 100% rename from src/annotation.h rename to src/include/libsigmf/annotation.h diff --git a/src/capture.h b/src/include/libsigmf/capture.h similarity index 100% rename from src/capture.h rename to src/include/libsigmf/capture.h diff --git a/src/include/libsigmf/flatbuffers_json_visitor.h b/src/include/libsigmf/flatbuffers_json_visitor.h new file mode 100644 index 0000000..6920872 --- /dev/null +++ b/src/include/libsigmf/flatbuffers_json_visitor.h @@ -0,0 +1,114 @@ +/* + * Copyright 2019 DeepSig Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LIBSIGMF_FLATBUFFERS_TO_JSON_VISITOR_H +#define LIBSIGMF_FLATBUFFERS_TO_JSON_VISITOR_H + +#include "json_wrap.h" +#include + + +/* + * Designed to be run by our TypeIterator-- it adds fields to a flatbuffer (fbb) it owns by reading from a json + * object given in its ctor. After the TypeIterator runs the flatbuffer can be made in to a specific flatbuffer + * object or shipped somewhere + */ +struct FromSigMFVisitor : public flatbuffers::IterationVisitor { + flatbuffers::uoffset_t _start; + flatbuffers::uoffset_t _stop; + std::unique_ptr narrowest_json; + std::string p; + std::string last_field_name; + flatbuffers::FlatBufferBuilder fbb; + flatbuffers::voffset_t last_offset; + flatbuffers::Offset last_fb_offset; + + explicit FromSigMFVisitor(std::string namespace_prefix, const json &j); + + void StartSequence() override; + + void EndSequence() override; + + void Field(size_t field_idx, size_t set_idx, flatbuffers::ElementaryType e_type, + bool is_vector, const flatbuffers::TypeTable *type_table, + const char *name, const uint8_t *val, json jj); + + template + void Named(T x, const char *name); + + void UType(uint8_t x, const char *name) override; + + // void Bool(bool x) override { s += x ? "true" : "false"; } + virtual void Char(int8_t x, const char *name) override; + + virtual void UChar(uint8_t x, const char *name) override; + + virtual void Short(int16_t x, const char *name) override; + + virtual void UShort(uint16_t x, const char *name) override; + + virtual void Int(int32_t x, const char *name) override; + + virtual void UInt(uint32_t x, const char *name) override; + + virtual void Long(int64_t x) override; + + virtual void ULong(uint64_t x) override; + + virtual void Float(float x) override; + + virtual void Double(double x) override; + + virtual void String(const struct flatbuffers::String *str) override; + + virtual void StartVector() override; + + virtual void EndVector() override; + + virtual void Element(size_t i, flatbuffers::ElementaryType /*type*/, + const flatbuffers::TypeTable * /*type_table*/, const uint8_t * /*val*/) override; +}; + +/** + * Iterate through a typetable-- I'll be honest here. This is kind of bullshit. We need to create all of + * the types like Strings, Lists, Vectors, and other flatbuffer types before we create our table. I'm not + * sure there's a better way to fill in the buffer than iterate over it twice-- i wonder how flatbuffers + * does this internally (look at Parsers). We're just going to construct shit in the fbb in the first loop + * and then fill in the fixed-width fields. I know this does the string creation correctly, but I don't + * know that lists(Vectors) or other tables/structs will work. The Vectors and Tables will probably require + * some recursion + * + * @param type_table the table to iterate over + * @param visitor the visitor responsible for creating objects and adding fields to its internal flatbufferbuilder + */ +void IterateType(const flatbuffers::TypeTable *type_table, FromSigMFVisitor *visitor, json original_json); + +/** + * A function to iterate through a flatbuffer that is described by the type and build up a json object to return. + * The flatbuffer should have already been Finished, and the result of FlatBufferBuilder::Finish() -> GetRoot should + * be the buffer_root. See variadic_data_class where we do the following: + * auto bfrptr = fbb.GetBufferPointer(); + * auto rtptr = flatbuffers::GetRoot(bfrptr); + * + * The gist of this is to get information about each field inside of a flatbuffers Table, then for each field, check + * if there is a value. If so, serialize it to json and shove its value inside the json_object we want to return + * using the name of the field as the key. + */ +json +FlatBufferToJson(const uint8_t *buffer_root, const flatbuffers::TypeTable *typetable, const std::string &ns_prefix, + bool include_defaults); + +#endif //LIBSIGMF_FLATBUFFERS_TO_JSON_VISITOR_H diff --git a/src/flatbuffers_type_to_json.h b/src/include/libsigmf/flatbuffers_type_to_json.h similarity index 100% rename from src/flatbuffers_type_to_json.h rename to src/include/libsigmf/flatbuffers_type_to_json.h diff --git a/src/global.h b/src/include/libsigmf/global.h similarity index 100% rename from src/global.h rename to src/include/libsigmf/global.h diff --git a/src/include/libsigmf/json_wrap.h b/src/include/libsigmf/json_wrap.h new file mode 100644 index 0000000..d4f68ac --- /dev/null +++ b/src/include/libsigmf/json_wrap.h @@ -0,0 +1,4 @@ + +#include + +using json = nlohmann::json; \ No newline at end of file diff --git a/src/sigmf.h b/src/include/libsigmf/sigmf.h similarity index 56% rename from src/sigmf.h rename to src/include/libsigmf/sigmf.h index 9bc42c3..fb20e57 100644 --- a/src/sigmf.h +++ b/src/include/libsigmf/sigmf.h @@ -17,77 +17,74 @@ #ifndef LIBSIGMF_SIGMF_H #define LIBSIGMF_SIGMF_H -#include "variadic_data_class.h" #include "global.h" #include "capture.h" #include "annotation.h" +#include "json_wrap.h" +#include +#include "sigmf_forward.h" #include "sigmf_core_generated.h" #include -#include namespace sigmf { - template - class SigMFVector : public std::vector { - public: - T &create_new() { - T new_element; - this->emplace_back(new_element); - return this->back(); - } - }; + /* + * This makes conversion between json types and SigMF types work out of the box + */ + + template + json to_json(const SigMF t) { + json j; + j["global"] = t.global.to_json(); + j["captures"] = t.captures; + j["annotations"] = t.annotations; + return j; + } template - struct SigMF { - GlobalType global; - SigMFVector captures; - SigMFVector annotations; + void to_json(json &j, const SigMF t) { + j["global"] = t.global.to_json(); + j["captures"] = t.captures; + j["annotations"] = t.annotations; + } - /** - * Export the record to a JSON object - */ - json to_json() const { - json j; - j["global"] = global.to_json(); - j["captures"] = captures; - j["annotations"] = annotations; - return j; + template + SigMF from_json(const json &j) { + SigMF t; + t.global.from_json(j["global"]); + t.captures.clear(); + t.annotations.clear(); + for (auto &element : j["annotations"]) { + AnnotationType a; + a.from_json(element); + t.annotations.emplace_back(a); + } + for (auto &element : j["captures"]) { + CaptureType c; + c.from_json(element); + t.captures.emplace_back(c); } + return t; + } - /** - * Write over the fields with a new record from a JSON object - */ - void from_json(const json &j) { - global.from_json(j["global"]); - captures.clear(); - annotations.clear(); + template + void from_json(const json &j, SigMF &t) { + t.global.from_json(j["global"]); + t.captures.clear(); + t.annotations.clear(); for (auto &element : j["annotations"]) { AnnotationType a; a.from_json(element); - annotations.emplace_back(a); + t.annotations.emplace_back(a); } for (auto &element : j["captures"]) { CaptureType c; c.from_json(element); - captures.emplace_back(c); + t.captures.emplace_back(c); } } - }; - - /* - * This makes conversion between json types and SigMF types work out of the box - */ - - template - void to_json(json &j, const SigMF t) { - j = t.to_json(); } - template - void from_json(const json &j, SigMF &t) { - t.from_json(j); - } -} #endif //LIBSIGMF_SIGMF_H diff --git a/src/include/libsigmf/sigmf_forward.h b/src/include/libsigmf/sigmf_forward.h new file mode 100644 index 0000000..9b61da1 --- /dev/null +++ b/src/include/libsigmf/sigmf_forward.h @@ -0,0 +1,50 @@ +/* + * Copyright 2019 DeepSig Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LIBSIGMF_SIGMF_FORWARD_H +#define LIBSIGMF_SIGMF_FORWARD_H + +namespace sigmf { + + template + class Global; + + template + class Captures; + + template + class Annotations; + + template + class SigMFVector : public std::vector { + public: + T &create_new() { + T new_element; + this->emplace_back(new_element); + return this->back(); + } + }; + + template + struct SigMF { + GlobalType global; + SigMFVector captures; + SigMFVector annotations; + }; + +} + +#endif // LIBSIGMF_SIGMF_FORWARD_H \ No newline at end of file diff --git a/src/sigmf_helpers.h b/src/include/libsigmf/sigmf_helpers.h similarity index 95% rename from src/sigmf_helpers.h rename to src/include/libsigmf/sigmf_helpers.h index d1fa585..88ddcd9 100644 --- a/src/sigmf_helpers.h +++ b/src/include/libsigmf/sigmf_helpers.h @@ -171,17 +171,17 @@ namespace sigmf { * @return Pointer to SigMF object * */ - static std::unique_ptr, + static sigmf::SigMF, sigmf::Capture, - sigmf::Annotation>> metadata_file_to_json(const std::ifstream &meta_file) { + sigmf::Annotation> metadata_file_to_json(const std::ifstream &meta_file) { std::ostringstream meta_buffer; meta_buffer << meta_file.rdbuf(); - auto sigmf_md = std::make_unique, + auto sigmf_md = sigmf::SigMF, sigmf::Capture, - sigmf::Annotation>>(); - - *sigmf_md = json::parse(meta_buffer.str()); + sigmf::Annotation>(); + + from_json(json::parse(meta_buffer.str()), sigmf_md); return sigmf_md; } diff --git a/src/variadic_data_class.h b/src/include/libsigmf/variadic_data_class.h similarity index 98% rename from src/variadic_data_class.h rename to src/include/libsigmf/variadic_data_class.h index 4676318..14c05a0 100644 --- a/src/variadic_data_class.h +++ b/src/include/libsigmf/variadic_data_class.h @@ -17,7 +17,11 @@ #ifndef LIBSIGMF_VARIADICDATACLASS_H #define LIBSIGMF_VARIADICDATACLASS_H +#include "variadic_data_class_forward.h" #include "flatbuffers_json_visitor.h" +#include "json_wrap.h" +#include +#include #include #include #include @@ -25,7 +29,6 @@ namespace sigmf { - template struct SameType { static const bool value = false; diff --git a/src/include/libsigmf/variadic_data_class_forward.h b/src/include/libsigmf/variadic_data_class_forward.h new file mode 100644 index 0000000..f0d1312 --- /dev/null +++ b/src/include/libsigmf/variadic_data_class_forward.h @@ -0,0 +1,27 @@ +/* + * Copyright 2019 DeepSig Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef LIBSIGMF_VARIADICDATACLASS_FORWARD_H +#define LIBSIGMF_VARIADICDATACLASS_FORWARD_H + +namespace sigmf { + + template + class VariadicDataClass; + +} + +#endif // LIBSIGMF_VARIADICDATACLASS_FORWARD_H \ No newline at end of file diff --git a/src/flatbuffers_json_visitor.h b/src/lib/flatbuffers_json_visitor.cpp similarity index 81% rename from src/flatbuffers_json_visitor.h rename to src/lib/flatbuffers_json_visitor.cpp index 1c310ad..49c9c56 100644 --- a/src/flatbuffers_json_visitor.h +++ b/src/lib/flatbuffers_json_visitor.cpp @@ -1,144 +1,12 @@ -/* - * Copyright 2019 DeepSig Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#ifndef LIBSIGMF_FLATBUFFERS_TO_JSON_VISITOR_H -#define LIBSIGMF_FLATBUFFERS_TO_JSON_VISITOR_H -#include "variadic_data_class.h" -#include +#include "libsigmf/flatbuffers_json_visitor.h" #include -#include -#include - -using json = nlohmann::json; - - -/* - * Designed to be run by our TypeIterator-- it adds fields to a flatbuffer (fbb) it owns by reading from a json - * object given in its ctor. After the TypeIterator runs the flatbuffer can be made in to a specific flatbuffer - * object or shipped somewhere - */ -struct FromSigMFVisitor : public flatbuffers::IterationVisitor { - flatbuffers::uoffset_t _start; - flatbuffers::uoffset_t _stop; - json narrowest_json; - std::string p; - std::string last_field_name; - flatbuffers::FlatBufferBuilder fbb; - flatbuffers::voffset_t last_offset; - flatbuffers::Offset last_fb_offset; - - - explicit FromSigMFVisitor(std::string namespace_prefix, const json &j) - : p(namespace_prefix), last_offset(0), _start(0), _stop(0) { - fbb = flatbuffers::FlatBufferBuilder(); - } - - void StartSequence() override { - _start = fbb.StartTable(); - } - - void EndSequence() override { - _stop = fbb.EndTable(_start); - } - - void Field(size_t field_idx, size_t set_idx, flatbuffers::ElementaryType e_type, - bool is_vector, const flatbuffers::TypeTable *type_table, - const char *name, const uint8_t *val, json jj) { - narrowest_json = jj; - last_field_name = name; - last_offset = flatbuffers::FieldIndexToOffset(static_cast(field_idx)); - } - - template - void Named(T x, const char *name) { - try { - fbb.AddElement(last_offset, narrowest_json.at(p + last_field_name).get(), T{}); - } catch (nlohmann::detail::out_of_range &e) { - } - } - - void UType(uint8_t x, const char *name) override { Named(x, name); } - - // void Bool(bool x) override { s += x ? "true" : "false"; } - void Char(int8_t x, const char *name) override { Named(x, name); } - - void UChar(uint8_t x, const char *name) override { Named(x, name); } - - void Short(int16_t x, const char *name) override { Named(x, name); } - - void UShort(uint16_t x, const char *name) override { Named(x, name); } - - void Int(int32_t x, const char *name) override { Named(x, name); } - - void UInt(uint32_t x, const char *name) override { Named(x, name); } - - void Long(int64_t x) override { - try { - fbb.AddElement(last_offset, narrowest_json.at(p + last_field_name).get(), int64_t(0)); - } catch (nlohmann::detail::out_of_range &e) { - } - } - - void ULong(uint64_t x) override { - try { - fbb.AddElement(last_offset, narrowest_json.at(p + last_field_name).get(), uint64_t(0)); - } catch (nlohmann::detail::out_of_range &e) { - } - } - - void Float(float x) override { - try { - fbb.AddElement(last_offset, narrowest_json.at(p + last_field_name).get(), 0.f); - } catch (nlohmann::detail::out_of_range &e) { - } - } - - void Double(double x) override { - try { - fbb.AddElement(last_offset, narrowest_json.at(p + last_field_name).get(), 0.0); - } catch (nlohmann::detail::out_of_range &e) { - } - } - - void String(const struct flatbuffers::String *str) override { - try { - auto strval = narrowest_json.at(p + last_field_name).get(); - last_fb_offset = flatbuffers::Offset(fbb.CreateString(strval).o); - } catch (nlohmann::detail::out_of_range &e) { - last_fb_offset.o = 0; - }; - } - - void StartVector() override { - std::cout << "the visitor was called on startvector... not implemented" << std::endl; - - } - - void EndVector() override { - std::cout << "the visitor was called on endvector... not implemented" << std::endl; - } - - void Element(size_t i, flatbuffers::ElementaryType /*type*/, - const flatbuffers::TypeTable * /*type_table*/, const uint8_t * /*val*/) override {} -}; +#include "json_wrap.cpp" template -flatbuffers::Offset json_vector_to_flatbuffer(flatbuffers::FlatBufferBuilder &fbb, const json &jvec) { +flatbuffers::Offset json_vector_to_flatbuffer(flatbuffers::FlatBufferBuilder &fbb, json jvec) { size_t dtype_size = sizeof(T); std::vector tmpvec; tmpvec.reserve(jvec.size()); @@ -146,10 +14,10 @@ flatbuffers::Offset json_vector_to_flatbuffer(flatbuffers::FlatBufferBuild tmpvec.emplace_back(elem->get()); } return flatbuffers::Offset(fbb.CreateVector(tmpvec).o); - } -inline flatbuffers::Offset + +flatbuffers::Offset json_vector_to_chararray(flatbuffers::FlatBufferBuilder &fbb, const json &jvec, flatbuffers::ElementaryType type) { size_t dtype_size; size_t num_elements = jvec.size(); @@ -196,7 +64,6 @@ json_vector_to_chararray(flatbuffers::FlatBufferBuilder &fbb, const json &jvec, } } - /** * Iterate through a typetable-- I'll be honest here. This is kind of bullshit. We need to create all of * the types like Strings, Lists, Vectors, and other flatbuffer types before we create our table. I'm not @@ -209,7 +76,7 @@ json_vector_to_chararray(flatbuffers::FlatBufferBuilder &fbb, const json &jvec, * @param type_table the table to iterate over * @param visitor the visitor responsible for creating objects and adding fields to its internal flatbufferbuilder */ -inline void IterateType(const flatbuffers::TypeTable *type_table, FromSigMFVisitor *visitor, json original_json) { +void IterateType(const flatbuffers::TypeTable *type_table, FromSigMFVisitor *visitor, json original_json) { const uint8_t *prev_val = nullptr; const uint8_t val[8] = {}; auto comosite_type_offsets = std::map >(); @@ -303,18 +170,13 @@ inline void IterateType(const flatbuffers::TypeTable *type_table, FromSigMFVisit } visitor->EndSequence(); } - - -// forward declare so we can create objects as fields -inline json -FlatBufferToJson(const uint8_t *buffer_root, const flatbuffers::TypeTable *typetable, const std::string &ns_prefix, - bool include_defaults = false); - -inline json -flatbuffer_field_to_json(const uint8_t *val, flatbuffers::ElementaryType type, - const flatbuffers::TypeTable *tt = nullptr, - const std::string &ns_prefix = "", - bool include_defaults = false) { + +json +flatbuffer_field_to_json(const uint8_t *val, + flatbuffers::ElementaryType type, + const flatbuffers::TypeTable *tt, + const std::string &ns_prefix, + bool include_defaults) { switch (type) { case flatbuffers::ET_UTYPE: { uint8_t tval = 0; @@ -469,7 +331,6 @@ flatbuffer_field_to_json(const uint8_t *val, flatbuffers::ElementaryType type, } } - /** * A function to iterate through a flatbuffer that is described by the type and build up a json object to return. * The flatbuffer should have already been Finished, and the result of FlatBufferBuilder::Finish() -> GetRoot should @@ -481,7 +342,7 @@ flatbuffer_field_to_json(const uint8_t *val, flatbuffers::ElementaryType type, * if there is a value. If so, serialize it to json and shove its value inside the json_object we want to return * using the name of the field as the key. */ -inline json +json FlatBufferToJson(const uint8_t *buffer_root, const flatbuffers::TypeTable *typetable, const std::string &ns_prefix, bool include_defaults) { json json_object; @@ -541,4 +402,98 @@ FlatBufferToJson(const uint8_t *buffer_root, const flatbuffers::TypeTable *typet } -#endif //LIBSIGMF_FLATBUFFERS_TO_JSON_VISITOR_H +FromSigMFVisitor::FromSigMFVisitor(std::string namespace_prefix, const json &j) + : p(namespace_prefix), last_offset(0), _start(0), _stop(0) { + fbb = flatbuffers::FlatBufferBuilder(); + narrowest_json = std::make_unique(); + *narrowest_json = j; +} + +void FromSigMFVisitor::StartSequence() { + _start = fbb.StartTable(); +} + +void FromSigMFVisitor::EndSequence() { + _stop = fbb.EndTable(_start); +} + +void FromSigMFVisitor::Field(size_t field_idx, size_t set_idx, flatbuffers::ElementaryType e_type, + bool is_vector, const flatbuffers::TypeTable *type_table, + const char *name, const uint8_t *val, json jj) { + *narrowest_json = jj; + last_field_name = name; + last_offset = flatbuffers::FieldIndexToOffset(static_cast(field_idx)); +} + + template + void FromSigMFVisitor::Named(T x, const char *name) { + try { + fbb.AddElement(last_offset, narrowest_json->at(p + last_field_name).get(), T{}); + } catch (nlohmann::detail::out_of_range &e) { + } + } + +void FromSigMFVisitor::UType(uint8_t x, const char *name) { + Named(x, name); +} + + + void FromSigMFVisitor::Char(int8_t x, const char *name) { Named(x, name); } + + void FromSigMFVisitor::UChar(uint8_t x, const char *name) { Named(x, name); } + + void FromSigMFVisitor::Short(int16_t x, const char *name) { Named(x, name); } + + void FromSigMFVisitor::UShort(uint16_t x, const char *name) { Named(x, name); } + + void FromSigMFVisitor::Int(int32_t x, const char *name) { Named(x, name); } + + void FromSigMFVisitor::UInt(uint32_t x, const char *name) { Named(x, name); } + + void FromSigMFVisitor::Long(int64_t x) { + try { + fbb.AddElement(last_offset, narrowest_json->at(p + last_field_name).get(), int64_t(0)); + } catch (nlohmann::detail::out_of_range &e) { + } + } + + void FromSigMFVisitor::ULong(uint64_t x) { + try { + fbb.AddElement(last_offset, narrowest_json->at(p + last_field_name).get(), uint64_t(0)); + } catch (nlohmann::detail::out_of_range &e) { + } + } + + void FromSigMFVisitor::Float(float x) { + try { + fbb.AddElement(last_offset, narrowest_json->at(p + last_field_name).get(), 0.f); + } catch (nlohmann::detail::out_of_range &e) { + } + } + + void FromSigMFVisitor::Double(double x) { + try { + fbb.AddElement(last_offset, narrowest_json->at(p + last_field_name).get(), 0.0); + } catch (nlohmann::detail::out_of_range &e) { + } + } + + void FromSigMFVisitor::String(const struct flatbuffers::String *str) { + try { + auto strval = narrowest_json->at(p + last_field_name).get(); + last_fb_offset = flatbuffers::Offset(fbb.CreateString(strval).o); + } catch (nlohmann::detail::out_of_range &e) { + last_fb_offset.o = 0; + }; + } + + void FromSigMFVisitor::StartVector() { + throw std::runtime_error("the visitor was called on startvector... not implemented"); + } + + void FromSigMFVisitor::EndVector() { + throw std::runtime_error("the visitor was called on endvector... not implemented"); + } + + void FromSigMFVisitor::Element(size_t i, flatbuffers::ElementaryType /*type*/, + const flatbuffers::TypeTable * /*type_table*/, const uint8_t * /*val*/) {} diff --git a/src/lib/json_wrap.cpp b/src/lib/json_wrap.cpp new file mode 100644 index 0000000..c24b74b --- /dev/null +++ b/src/lib/json_wrap.cpp @@ -0,0 +1,3 @@ + +#include "libsigmf/json_wrap.h" +#include \ No newline at end of file