Skip to content

Commit

Permalink
Add parser for json
Browse files Browse the repository at this point in the history
+ fix requirements-linter.txt
landscapeio/prospector#438
  • Loading branch information
bansan85 committed Nov 13, 2021
1 parent f85a0cb commit 6d8bd57
Show file tree
Hide file tree
Showing 13 changed files with 485 additions and 14 deletions.
5 changes: 4 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,10 @@
"shared_mutex": "cpp",
"source_location": "cpp",
"strstream": "cpp",
"valarray": "cpp"
"valarray": "cpp",
"ranges": "cpp",
"span": "cpp",
"*.ipp": "cpp"
},
"git.ignoreLimitWarning": true,
"editor.tabSize": 2,
Expand Down
3 changes: 3 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ set(CMAKE_VERBOSE_MAKEFILE ON)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED True)
set(CMAKE_CXX_EXTENSIONS OFF)

include(CheckCXXCompilerFlag)
include(CheckIncludeFileCXX)
Expand All @@ -15,6 +16,8 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)

find_package(spdlog REQUIRED)
find_package(simdjson REQUIRED)
find_package(nlohmann_json REQUIRED)

# Ubuntu/gcc don't have the cereal-config.cmake but emscripten needs it.
check_include_file_cxx("cereal/cereal.hpp" HAVE_CEREAL)
Expand Down
87 changes: 87 additions & 0 deletions include/jessica/helper/adapter/json_parser/json_nlohmann.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
#pragma once

#include <concepts>
#include <memory>
#include <string>

#include <nlohmann/json.hpp>

#include <jessica/helper/adapter/json_parser/json_parser.h>

namespace jessica
{
template <class Type>
struct S;
class JsonNlohmann
{
public:
JsonNlohmann() = default;
JsonNlohmann(const JsonNlohmann&) = default;
JsonNlohmann(JsonNlohmann&&) = default;
JsonNlohmann& operator=(const JsonNlohmann&) = delete;
JsonNlohmann& operator=(JsonNlohmann&&) = delete;

void ReadStr(const std::string& text) { doc = nlohmann::json::parse(text); }

void ReadFile(const std::string& file)
{
std::ifstream ifs(file);
doc = nlohmann::json::parse(ifs);
}

std::string Get(const std::vector<std::string>& list) const
{
std::string x = Get(const_cast<nlohmann::json&>(doc), list, 0).dump();
return x;
}

JsonNlohmann Set(const std::vector<std::string>& list,
const nlohmann::json& val) const
{
JsonNlohmann retval(*this);
retval.Get(retval.doc, list, 0) = val;
return retval;
}

~JsonNlohmann() = default;

private:
nlohmann::json doc;

static nlohmann::json& Get(nlohmann::json& data,
const std::vector<std::string>& list, size_t i)
{
nlohmann::json* retval2 = [&data, &list, i]()
{
nlohmann::json* retval = &data[list[i]];
auto decorator = retval->find("decorator");
if (decorator == retval->end())
{
auto ptr_wrapper = retval->find("ptr_wrapper");
if (ptr_wrapper == retval->end())
{
return retval;
}
else
{
return &(*retval)["ptr_wrapper"]["data"];
}
}
else
{
return &(*retval)["decorator"]["ptr_wrapper"]["data"];
}
}();

if (i == list.size() - 1)
{
return *retval2;
}
else
{
return Get(*retval2, list, i + 1);
}
}
};
//static_assert(JsonParser<JsonNlohmann, nlohmann::json>);
} // namespace jessica
35 changes: 35 additions & 0 deletions include/jessica/helper/adapter/json_parser/json_parser.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#pragma once

#include <concepts>
#include <string>
#include <vector>

namespace jessica
{
template <typename T>
concept JsonParserReader = requires(T t, const std::string& str,
const std::vector<std::string>& vec)
{
{
t.ReadStr(str)
} -> std::same_as<void>;
{
t.ReadFile(str)
} -> std::same_as<void>;
{
t.Get(vec)
} -> std::same_as<std::string>;
};

template <typename T, typename U>
concept JsonParserWriter = requires(T t, U u,
const std::vector<std::string>& vec)
{
{
t.Set(vec, u)
} -> std::same_as<T>;
};

template <typename T, typename U>
concept JsonParser = JsonParserReader<T> && JsonParserWriter<T, U>;
} // namespace jessica
94 changes: 94 additions & 0 deletions include/jessica/helper/adapter/json_parser/json_simdjson.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#pragma once

#include <concepts>
#include <memory>
#include <string>

#include <simdjson.h>

#include <jessica/helper/adapter/json_parser/json_parser.h>

namespace jessica
{
class JsonSimdjson
{
public:
JsonSimdjson() = default;
JsonSimdjson(const JsonSimdjson&) = delete;
JsonSimdjson(JsonSimdjson&&) = delete;
JsonSimdjson& operator=(const JsonSimdjson&) = delete;
JsonSimdjson& operator=(JsonSimdjson&&) = delete;

void ReadStr(const std::string& text)
{
padded = simdjson::padded_string(text);
doc = parser.iterate(padded);
}

void ReadFile(const std::string& file)
{
padded = simdjson::padded_string::load(file);
doc = parser.iterate(padded);
}

std::string Get(const std::vector<std::string>& list) const
{
doc.rewind();
std::string_view v;
auto error = simdjson::to_json_string(Get(doc.get_value(), list, 0)).get(v);
if (error == simdjson::SUCCESS)
{
return std::string{v};
}
else
{
return {};
}
}

~JsonSimdjson() = default;

private:
simdjson::ondemand::parser parser;
simdjson::padded_string padded;
// Parsing document need to modify document iterator.
mutable simdjson::ondemand::document doc;

static simdjson::simdjson_result<simdjson::fallback::ondemand::value>
Get(simdjson::simdjson_result<simdjson::fallback::ondemand::value> data,
const std::vector<std::string>& list, size_t i)
{
simdjson::simdjson_result<simdjson::fallback::ondemand::value> retval2 =
[&data, &list, i]()
{
simdjson::simdjson_result<simdjson::fallback::ondemand::value> retval =
data[list[i]];
if (retval["decorator"].error() != simdjson::SUCCESS)
{
if (retval["ptr_wrapper"].error() != simdjson::SUCCESS)
{
return retval;
}
else
{
return retval["ptr_wrapper"]["data"];
}
}
else
{
return retval["decorator"]["ptr_wrapper"]["data"];
}
}();

if (i == list.size() - 1)
{
return retval2;
}
else
{
return Get(retval2, list, i + 1);
}
}
};
static_assert(JsonParserReader<JsonSimdjson>);
} // namespace jessica
25 changes: 25 additions & 0 deletions include/jessica/helper/string.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#pragma once

#include <string>

namespace jessica
{
class String
{
public:
template <typename Iter>
static std::string join(Iter begin, Iter end, const std::string& separator)
{
std::ostringstream result;
if (begin != end)
{
result << *begin++;
}
while (begin != end)
{
result << separator << *begin++;
}
return result.str();
}
};
} // namespace jessica
2 changes: 1 addition & 1 deletion include/jessica/util/decorator/start.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class JESSICA_DLL_PUBLIC DecoratorStart
template <class Archive>
void serialize(Archive& ar)
{
ar(cereal::make_nvp("data", impl_));
ar(cereal::make_nvp("decorator", impl_));
}

private:
Expand Down
5 changes: 3 additions & 2 deletions test/backend/calc/geotechnical/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
add_executable(test_calc_meyerhof ${CMAKE_CURRENT_SOURCE_DIR}/meyerhof.cc)

target_link_libraries(
test_calc_meyerhof PRIVATE GTest::GTest GTest::Main
spdlog::spdlog_header_only jessica::header_only)
test_calc_meyerhof
PRIVATE GTest::GTest GTest::Main nlohmann_json::nlohmann_json simdjson
spdlog::spdlog_header_only jessica::header_only)
if(cereal_DIR)
target_link_libraries(test_calc_meyerhof PRIVATE cereal)
endif()
Expand Down
Loading

0 comments on commit 6d8bd57

Please sign in to comment.