Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 23 additions & 10 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,31 +117,44 @@ 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
$<INSTALL_INTERFACE:include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src/include>
$<INSTALL_INTERFACE:include/sigmf/fbs>
$<BUILD_INTERFACE:${LIBSIGMF_GEN_HEADERS}>
)
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src/include
)

if (${Flatbuffers_FOUND})
# System flatbuffers can import this target
target_link_libraries(libsigmf INTERFACE
flatbuffers::flatbuffers_shared
)
else()
target_include_directories(libsigmf INTERFACE
target_include_directories(libsigmf
INTERFACE
$<BUILD_INTERFACE:${FLATBUFFERS_INCLUDE_DIR}>
PRIVATE
${FLATBUFFERS_INCLUDE_DIR}
)
endif(${Flatbuffers_FOUND})

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
$<BUILD_INTERFACE:${JSON_INCLUDE_DIR}>
PRIVATE
${JSON_INCLUDE_DIR}
)
endif(${nlohmann_json_FOUND})

Expand Down Expand Up @@ -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")

########################################################################
Expand Down
6 changes: 3 additions & 3 deletions examples/example_reading_sigmf_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 <iostream>
#include <fstream>

Expand All @@ -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;
}
3 changes: 2 additions & 1 deletion examples/example_record_with_multiple_namespaces.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@

#include "sigmf_core_generated.h"
#include "sigmf_antenna_generated.h"
#include "sigmf.h"
#include "libsigmf/sigmf.h"
#include <iostream>

int main() {

Expand Down
2 changes: 1 addition & 1 deletion examples/example_record_with_variadic_dataclass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@


#include "sigmf_core_generated.h"
#include "sigmf.h"
#include "libsigmf/sigmf.h"
#include <iostream>

int main() {
Expand Down
3 changes: 2 additions & 1 deletion examples/example_sigmf_json_roundtrip.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@
* limitations under the License.
*/

#include "sigmf.h"
#include "libsigmf/sigmf.h"
#include <nlohmann/json.hpp>
#include <iostream>

int main() {

Expand Down
2 changes: 1 addition & 1 deletion external/json
Submodule json updated 149 files
File renamed without changes.
File renamed without changes.
114 changes: 114 additions & 0 deletions src/include/libsigmf/flatbuffers_json_visitor.h
Original file line number Diff line number Diff line change
@@ -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 <flatbuffers/minireflect.h>


/*
* 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<json> narrowest_json;
std::string p;
std::string last_field_name;
flatbuffers::FlatBufferBuilder fbb;
flatbuffers::voffset_t last_offset;
flatbuffers::Offset<void> 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<typename T>
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<uint8_t>(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
File renamed without changes.
4 changes: 4 additions & 0 deletions src/include/libsigmf/json_wrap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

#include <nlohmann/json_fwd.hpp>

using json = nlohmann::json;
91 changes: 44 additions & 47 deletions src/sigmf.h → src/include/libsigmf/sigmf.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <nlohmann/json.hpp>
#include "sigmf_forward.h"
#include "sigmf_core_generated.h"
#include <vector>
#include <iostream>


namespace sigmf {

template<typename T>
class SigMFVector : public std::vector<T> {
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<typename GlobalType, typename CaptureType, typename AnnotationType>
json to_json(const SigMF<GlobalType, CaptureType, AnnotationType> t) {
json j;
j["global"] = t.global.to_json();
j["captures"] = t.captures;
j["annotations"] = t.annotations;
return j;
}

template<typename GlobalType, typename CaptureType, typename AnnotationType>
struct SigMF {
GlobalType global;
SigMFVector<CaptureType> captures;
SigMFVector<AnnotationType> annotations;
void to_json(json &j, const SigMF<GlobalType, CaptureType, AnnotationType> 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<typename GlobalType, typename CaptureType, typename AnnotationType>
SigMF<GlobalType, CaptureType, AnnotationType> from_json(const json &j) {
SigMF<GlobalType, CaptureType, AnnotationType> 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<typename GlobalType, typename CaptureType, typename AnnotationType>
void from_json(const json &j, SigMF<GlobalType, CaptureType, AnnotationType> &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<typename GlobalType, typename CaptureType, typename AnnotationType>
void to_json(json &j, const SigMF<GlobalType, CaptureType, AnnotationType> t) {
j = t.to_json();
}

template<typename GlobalType, typename CaptureType, typename AnnotationType>
void from_json(const json &j, SigMF<GlobalType, CaptureType, AnnotationType> &t) {
t.from_json(j);
}
}

#endif //LIBSIGMF_SIGMF_H
Loading