Skip to content

Commit

Permalink
Merge branch 'release/2.1.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
deflinhec committed Feb 7, 2021
2 parents 3999fa9 + 4b28a89 commit ff892b8
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 20 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.1.3)

include(CheckCXXCompilerFlag)

project(Gsx2Jsonpp VERSION 2.0.0)
project(Gsx2Jsonpp VERSION 2.1.0)

# Set minimum C++ to 2011 standards
set(CMAKE_CXX_STANDARD 11)
Expand Down
81 changes: 62 additions & 19 deletions src/gsx2json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,25 @@
#include <iostream>
#include <uriparser/Uri.h>
#include <nlohmann/json.hpp>
#include <openssl/md5.h>
#include <exception>

using namespace nlohmann;

namespace Gxs2Json
{
static bool is_number(const std::string& _s)
bool is_number(const std::string& _s)
{
if (_s.empty())
if(_s.empty())
return false;

auto pred = [](unsigned char c) { return !std::isdigit(c); };
return std::find_if(_s.begin(), _s.end(), pred) == _s.end();
if ((!isdigit(_s[0])) && (_s[0] != '-') && (_s[0] != '+'))
return false;

char* p = nullptr;
strtod(_s.c_str(), &p);

return (*p == 0);
}

void parse(const std::string& _uri, Config* _cfg, Identifier* _id)
Expand Down Expand Up @@ -94,9 +100,10 @@ void parse(const std::string& _uri, Config* _cfg, Identifier* _id)
}
uriFreeQueryListA(list);
}

void parse(Content* _content, const std::string& _json, Config _cfg)
{
using json = ordered_json;
json object, dict, rows, columns;
auto raw = json::parse(_json);
auto timestamp = raw["feed"]["updated"]["$t"];
Expand All @@ -108,24 +115,19 @@ void parse(Content* _content, const std::string& _json, Config _cfg)
bool queried = _cfg.query.empty();
for (auto it = entry.begin(); it != entry.end(); it++)
{
// left most column as key
if (it.key().compare("title") == 0)
{
auto value = it.value()["$t"].get<std::string>();
if (is_number(value))
{
pkey = std::atoi(value.c_str());
}
}
// seek for actual data
else if (it.key().rfind("gsx$", 0) == 0)
if (it.key().rfind("gsx$", 0) == 0)
{
auto key = it.key();
key = key.substr(strlen("gsx$"));
// skip prefix with "noex" (non export)
if (key.rfind("noex", 0) == 0)
continue;
auto value = it.value()["$t"].get<std::string>();
if (is_number(value) && pkey == 0)
{
pkey = std::atoi(value.c_str());
}
if (!_cfg.query.empty())
{
std::string lkey, lvalue, lquery;
Expand Down Expand Up @@ -183,12 +185,53 @@ void parse(Content* _content, const std::string& _json, Config _cfg)
{
object["dict"] = dict;
}
if (_cfg.showColumns)
{
auto buffer = columns.dump();
MD5_CTX ctx; MD5_Init(&ctx);
MD5_Update(&ctx, (unsigned char *)buffer.data(), buffer.size());
unsigned char md5[MD5_DIGEST_LENGTH]; MD5_Final(md5, &ctx);
std::string checksum; checksum.reserve(32);
for (std::size_t i = 0; i != 16; ++i)
{
checksum += "0123456789ABCDEF"[md5[i] / 16];
checksum += "0123456789ABCDEF"[md5[i] % 16];
}
object["meta"]["columns"]["md5"] = checksum;
object["meta"]["columns"]["bytes"] = buffer.size();
}
if (_cfg.showRows)
{
auto buffer = rows.dump();
MD5_CTX ctx; MD5_Init(&ctx);
MD5_Update(&ctx, (unsigned char *)buffer.data(), buffer.size());
unsigned char md5[MD5_DIGEST_LENGTH]; MD5_Final(md5, &ctx);
std::string checksum; checksum.reserve(32);
for (std::size_t i = 0; i != 16; ++i)
{
checksum += "0123456789ABCDEF"[md5[i] / 16];
checksum += "0123456789ABCDEF"[md5[i] % 16];
}
object["meta"]["rows"]["md5"] = checksum;
object["meta"]["rows"]["bytes"] = buffer.size();
}
if (_cfg.showDict)
{
auto buffer = dict.dump();
MD5_CTX ctx; MD5_Init(&ctx);
MD5_Update(&ctx, (unsigned char *)buffer.data(), buffer.size());
unsigned char md5[MD5_DIGEST_LENGTH]; MD5_Final(md5, &ctx);
std::string checksum; checksum.reserve(32);
for (std::size_t i = 0; i != 16; ++i)
{
checksum += "0123456789ABCDEF"[md5[i] / 16];
checksum += "0123456789ABCDEF"[md5[i] % 16];
}
object["meta"]["dict"]["md5"] = checksum;
object["meta"]["dict"]["bytes"] = buffer.size();
}
const int indent = _cfg.prettyPrint ? 1 : -1;
object["meta"]["time"] = _content->timestamp;
auto size = _cfg.showColumns ? columns.dump(indent).length() : 0u;
size += _cfg.showRows ? rows.dump(indent).length() : 0u;
size += _cfg.showDict ? dict.dump(indent).length() : 0u;
object["meta"]["size"] = size;
_content->payload = object.dump(indent);
}
}
2 changes: 2 additions & 0 deletions src/gsx2json.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
namespace Gxs2Json
{

bool is_number(const std::string& _s);

struct Identifier
{
std::string id;
Expand Down
15 changes: 15 additions & 0 deletions test/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,21 @@ TEST(URI, ParseCompondQueries)
EXPECT_STREQ(config.query.c_str(), "aabb");
}

TEST(Number, LiteralNumber)
{
using namespace Gxs2Json;
EXPECT_TRUE(is_number("1"));
EXPECT_TRUE(is_number("0"));
EXPECT_TRUE(is_number("-1"));
EXPECT_TRUE(is_number("1.0"));
EXPECT_TRUE(is_number("0.0"));
EXPECT_TRUE(is_number("-1.0"));
EXPECT_FALSE(is_number("-1.0A"));
EXPECT_FALSE(is_number("1.0A"));
EXPECT_FALSE(is_number("-1A"));
EXPECT_FALSE(is_number("1A"));
}

class ParserTests: public ::testing::Test
{
protected:
Expand Down

0 comments on commit ff892b8

Please sign in to comment.