JSON-97: merge 'default'

JSON-97
Claudio Luck 5 years ago
commit 2ac00a885a

@ -10,7 +10,7 @@
#include <thread>
#include <sstream>
#include <vector>
#include <sys/time.h>
#include <alloca>
#ifdef LOGGER_ENABLE_SYSLOG
extern "C" {
@ -213,22 +213,18 @@ void Logger::start(const std::string& program_name, const std::string& filename)
std::string Logger::gmtime(time_t t)
{
char buf[24]; // long enough to hold YYYYY-MM-DD.hh:mm:ss" (y10k-safe!)
std::tm T;
gmtime_r(&t, &T); // TODO: GNU extension also in std:: ?
std::snprintf(buf, sizeof(buf)-1, "%04d-%02d-%02d.%02d:%02d:%02d",
T.tm_year+1900, T.tm_mon+1, T.tm_mday, T.tm_hour, T.tm_min, T.tm_sec );
return buf;
}
// Win32 does not have gmtime_r(), but its gmtime() returns ptr to thread-local struct tm. :-)
#ifdef _WIN32
std::tm* T = ::gmtime(&t);
#else
std::tm myT;
gmtime_r(&t, &myT); // TODO: GNU extension, conform to POSIX.1; works on Linux and MacOS.
std::tm* T = &myT;
#endif
std::string Logger::gmtime(timeval t)
{
char buf[31]; // long enough to hold YYYYY-MM-DD.hh:mm:ss.uuuuuu
std::tm T;
gmtime_r(&t.tv_sec, &T); // TODO: GNU extension also in std:: ?
std::snprintf(buf, sizeof(buf)-1, "%04d-%02d-%02d.%02d:%02d:%02d.%06lu",
T.tm_year+1900, T.tm_mon+1, T.tm_mday, T.tm_hour, T.tm_min, T.tm_sec, (long unsigned)t.tv_usec);
std::snprintf(buf, sizeof(buf)-1, "%04d-%02d-%02d.%02d:%02d:%02d",
T->tm_year+1900, T->tm_mon+1, T->tm_mday, T->tm_hour, T->tm_min, T->tm_sec );
return buf;
}
@ -320,7 +316,7 @@ void Logger::log(Severity s, const char* format, ...)
{
va_list va;
va_start(va, format);
char buf[ LoggerS::max_line_length + 1];
char *buf = (char*) alloca (sizeof(char) * ( LoggerS::max_line_length + 1 ));
std::vsnprintf(buf, LoggerS::max_line_length, format, va);
va_end(va);
@ -333,7 +329,7 @@ void LogP(Logger::Severity s, Logger::Severity my_loglevel, const std::string& p
{
if(s<=my_loglevel && s<=LoggerS::loglevel)
{
char buf[ LoggerS::max_line_length + 1];
char *buf = (char*) alloca (sizeof(char) * ( LoggerS::max_line_length + 1 ));
std::vsnprintf(buf, LoggerS::max_line_length, format, va);
LoggerS::log(s, prefix + buf );
}

@ -4,8 +4,6 @@
#include <cstdio>
#include <string>
#include <cerrno>
#include <sys/time.h>
#ifdef DEBUG_ENABLED
#define DEBUG_OUT( LL , ... ) LL.debug( __VA_ARGS__ )
@ -59,9 +57,6 @@ public:
// returns a string in YYYY-MM-DD.hh:mm:ss format of the given time_t t
static std::string gmtime(time_t t);
// returns a string in YYYY-MM-DD.hh:mm:ss.uuuuuu format (u=microseconds) of the given timval
static std::string gmtime(timeval t);
void emergency(const char* format, ...) PRINTF;
void emergency(const std::string& line);

@ -8,7 +8,9 @@
#define LOGGER_MAX_LINE_LENGTH (1000)
// enable logging to syslog
#ifndef _WIN32
#define LOGGER_ENABLE_SYSLOG (1)
#endif
// use ASCII-only characters to tag log lines
// #define LOGGER_USE_ASCII_TAGS (1)

@ -1,42 +1,23 @@
#include "pep-types.hh"
#include "pep-utils.hh"
#include "json_spirit/json_spirit_utils.h"
#include "pep-utils-json.hh"
#include <pEp/pEp_string.h>
#include <iostream> // Just to print debug stuff to std::cerr
#include "base64.hh"
using pEp::utility::from_json_object;
using pEp::utility::to_json_object;
namespace
{
// fetch a member from the given object, if set. (return a sensible NULL/default value if not)
template<class T, js::Value_type VALUE_TYPE>
T from_json_object(const js::Object& obj, const std::string& key)
{
const auto v = find_value(obj, key);
if(v.type() == js::null_type) return T{};
if(v.type() == VALUE_TYPE) return from_json<T>(v);
throw std::runtime_error("JSON object has a member for key \"" + key + "\""
" with incompatible type " + js::value_type_to_string( v.type())
+ " instead of expected type " + js::value_type_to_string(VALUE_TYPE)
);
}
std::string base64_from_json_object(const js::Object& obj, const std::string& key)
{
const std::string b64String = from_json_object<std::string, js::str_type> (obj, key);
return base64_decode(b64String);
}
template<class T>
void to_json_object(js::Object& obj, const std::string& key, const T& value)
{
if(value!=T{})
{
obj.emplace_back( key, js::Value( to_json<T>(value) ));
}
}
void to_base64_json_object(js::Object& obj, const std::string& key, char *value, size_t size)
{
if(value != nullptr && size>0)
@ -827,3 +808,6 @@ js::Value Type2String<PEP_STATUS>::get() { return "PEP_STATUS"; }
template<>
js::Value Type2String<Language>::get() { return "Language"; }
template<>
js::Value Type2String<JsonAdapter *>::get() { return "JsonAdapter"; }

@ -0,0 +1,39 @@
// some helper functions to deal with JSON data
#ifndef PEP_UTILS_JSON_HH
#define PEP_UTILS_JSON_HH
#include "json_spirit/json_spirit_utils.h"
namespace pEp {
namespace utility {
// fetch a member from the given object, if set. (return a sensible NULL/default value if not)
template<class T, js::Value_type VALUE_TYPE>
T from_json_object(const js::Object& obj, const std::string& key)
{
const auto v = find_value(obj, key);
if(v.type() == js::null_type) return T{};
if(v.type() == VALUE_TYPE) return from_json<T>(v);
throw std::runtime_error("JSON object has a member for key \"" + key + "\""
" with incompatible type " + js::value_type_to_string( v.type())
+ " instead of expected type " + js::value_type_to_string(VALUE_TYPE)
);
}
template<class T>
void to_json_object(js::Object& obj, const std::string& key, const T& value)
{
if(value!=T{})
{
obj.emplace_back( key, js::Value( to_json<T>(value) ));
}
}
} // end of namespace pEp::utility
} // end of namespace pEp
#endif // PEP_UTILS_JSON_HH

@ -1,14 +1,21 @@
#include "server_version.hh"
#include "inout.hh"
#include <fstream>
#include <sstream>
#include "pep-utils.hh"
#include "pep-utils-json.hh"
#include <pEp/pEpEngine.h> // for PEP_VERSION and get_engine_version()
#include <boost/algorithm/string/trim.hpp>
#include "json_spirit/json_spirit_reader.h"
namespace js = json_spirit;
namespace {
#ifdef PACKAGE_VERSION
const char* const PackageVersion = PACKAGE_VERSION;
char* PackageVersion = PACKAGE_VERSION;
#else
const char* const PackageVersion = nullptr;
char* PackageVersion = nullptr;
#endif
@ -83,7 +90,27 @@ ServerVersion::ServerVersion(unsigned maj, unsigned min, unsigned p)
, patch{p}
, name {VersionName}
, package_version{PackageVersion}
{}
{
if (!PackageVersion)
try{
const std::string file_content =
boost::algorithm::trim_copy(
pEp::utility::slurp("PackageVersion")
);
js::Value v;
js::read_or_throw(file_content, v);
const js::Object obj = v.get_obj();
PackageVersion = pEp::utility::from_json_object<char*, js::str_type>(obj, "package_version");
PackageVersion = strdup(file_content.c_str());
this->package_version = PackageVersion;
}
catch(std::runtime_error&)
{
// slurp() throws when it cannot read the file.
}
}
const ServerVersion& server_version()
{

@ -17,7 +17,7 @@ struct ServerVersion
// The version name is of the form "(##) name" where ## is a monotonic increasing number.
std::string name;
const char* const package_version; // must be set via -D, e.g. -D'PACKAGE_VERSION="deb9-0.1"'
const char* package_version; // must be set via -D, e.g. -D'PACKAGE_VERSION="deb9-0.1"'
// returns "major.minor.patch"
std::string major_minor_patch() const;

Loading…
Cancel
Save