Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JSON flags #4

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
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
10 changes: 10 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,16 @@ else
fi
fi

PKG_CHECK_EXISTS([yajl >= 2.1.0], [have_yajl=yes], [have_yajl=no])
if test $have_yajl = yes
then
AC_DEFINE([HAVE_YAJL], 1, [yajl functions are available])
PKG_CHECK_MODULES(YAJL,[yajl])
else
AC_MSG_WARN([compiling without yajl: JSON flags support will be disabled])
fi
AM_CONDITIONAL([YAJL], [test x"$have_yajl" = x"yes"])

AC_PATH_PROG([PYTHON], [python])
if test x$PYTHON = x
then
Expand Down
12 changes: 11 additions & 1 deletion meteo-vm2/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
DEVEL_CPPFLAGS = \
-I$(top_srcdir) -I$(top_builddir) $(LUA_CFLAGS) \
-DMETEO_VM2_DEFAULT_SOURCE='"$(sharedstatedir)/$(PACKAGE)/source/default.luac"' \
$(YAJL_FLAGS)

if YAJL
LIBS += $(YAJL_LIBS)
endif

pkgincludedir = $(includedir)/meteo-vm2

dist_pkginclude_HEADERS = \
Expand All @@ -16,7 +25,8 @@ libmeteo_vm2_la_LIBADD = $(LUA_LIBS)

libmeteo_vm2_la_SOURCES = \
source.cc \
parser.cc
parser.cc \
value.cc

# check_PROGRAMS = meteo-vm2-test
#
Expand Down
2 changes: 1 addition & 1 deletion meteo-vm2/parser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class PatternException : public std::runtime_error {
PatternException(int lineno, const std::string& msg) : std::runtime_error("line " + std::to_string(lineno) + ": " + msg) {}
};

std::string Parser::regexp_str = "^([0-9]{12}([0-9][0-9])?),([0-9]+),([0-9]+),([+-]?[0-9.]*),([+-]?[0-9.]*),([^,\n\r]*),([^,\n\r]*[\r\n]*)$";
std::string Parser::regexp_str = "^([0-9]{12}([0-9][0-9])?),([0-9]+),([0-9]+),([+-]?[0-9.]*),([+-]?[0-9.]*),([^,\n\r]*),([^\r\n]*)$";

#if GCC_VERSION >= 40900
static std::regex regexp(Parser::regexp_str);
Expand Down
62 changes: 62 additions & 0 deletions meteo-vm2/value.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* value - value class
*
* Copyright (C) 2012,2013 ARPA-SIM <[email protected]>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Author: Emanuele Di Giacomo <[email protected]>
*/
#include "config.h"

#include <stdexcept>
#include <iostream>

#include <meteo-vm2/value.h>
#include <yajl/yajl_tree.h>

struct YajlValRAII {
yajl_val node = nullptr;
~YajlValRAII() {
if (node)
yajl_tree_free(node);
}
};

namespace meteo{
namespace vm2 {
std::map<std::string, std::string> Value::jsonflags() const {
#ifdef HAVE_YAJL
std::map<std::string, std::string> f;

YajlValRAII raii;
yajl_val node = raii.node;

node = yajl_tree_parse(flags.c_str(), NULL, 0);
if (node == nullptr || not YAJL_IS_OBJECT(node))
throw std::runtime_error("Invalid JSON");
for (size_t i = 0; i < YAJL_GET_OBJECT(node)->len; ++i) {
const char* k = YAJL_GET_OBJECT(node)->keys[i];
const char* v = YAJL_GET_STRING((YAJL_GET_OBJECT(node)->values[i]));
if (v)
f[k] = v;
}
return f;
#else
throw std::runtime_error("Not supported");
#endif
}
}
}
3 changes: 3 additions & 0 deletions meteo-vm2/value.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* @brief Value class
* @see @ref VM2ValueFile
*/
#include <map>
#include <string>
#include <limits>

Expand Down Expand Up @@ -56,6 +57,8 @@ struct Value {
double value2;
std::string value3;
std::string flags;

std::map<std::string, std::string> jsonflags() const;
};

}
Expand Down
10 changes: 8 additions & 2 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ man_MANS += \

endif

if YAJL

DEVEL_CPPFLAGS += $(YAJL_CFLAGS)

endif

CLEANFILES += \
meteo-vm2-to-bufr.1 \
bufr-to-meteo-vm2.1
Expand All @@ -32,13 +38,13 @@ CLEANFILES += \

meteo_vm2_to_bufr_CPPFLAGS = $(DEVEL_CPPFLAGS) $(AM_CPPFLAGS)

meteo_vm2_to_bufr_LDADD = $(top_builddir)/meteo-vm2/libmeteo-vm2.la $(DBALLE_LIBS)
meteo_vm2_to_bufr_LDADD = $(top_builddir)/meteo-vm2/libmeteo-vm2.la $(DBALLE_LIBS) $(YAJL_LIBS)

meteo_vm2_to_bufr_SOURCES = meteo-vm2-to-bufr.cc

bufr_to_meteo_vm2_CPPFLAGS = $(DEVEL_CPPFLAGS) $(AM_CPPFLAGS)

bufr_to_meteo_vm2_LDADD = $(top_builddir)/meteo-vm2/libmeteo-vm2.la $(DBALLE_LIBS)
bufr_to_meteo_vm2_LDADD = $(top_builddir)/meteo-vm2/libmeteo-vm2.la $(DBALLE_LIBS) $(YAJL_LIBS)

bufr_to_meteo_vm2_SOURCES = bufr-to-meteo-vm2.cc

Expand Down
56 changes: 27 additions & 29 deletions src/bufr-to-meteo-vm2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,35 @@
#include <dballe/msg/msg.h>
#include <dballe/msg/context.h>
#include <dballe/msg/wr_codec.h>
#include <yajl/yajl_gen.h>

#include <meteo-vm2/source.h>

std::string attrs2json(const wreport::Var& var)
{
const unsigned char* buf;
size_t buflen;
yajl_gen g;

const wreport::Var* a = var.next_attr();
if (a == nullptr)
return "";

g = yajl_gen_alloc(NULL);
yajl_gen_map_open(g);
for (const wreport::Var* a = var.next_attr(); a != NULL; a = a->next_attr()) {
std::string k = wreport::varcode_format(a->code());
std::string v = a->format();
yajl_gen_string(g, (const unsigned char*)k.c_str(), k.size());
yajl_gen_string(g, (const unsigned char*)v.c_str(), v.size());
}
yajl_gen_map_close(g);
yajl_gen_get_buf(g, &buf, &buflen);
std::string s((const char*)buf, buflen);
yajl_gen_free(g);
return s;
}

template<typename T>
static std::string join(std::vector<T> l)
{
Expand Down Expand Up @@ -235,35 +261,7 @@ int main(int argc, const char** argv)

vm2value.value2 = meteo::vm2::MISSING_DOUBLE;
vm2value.value3 = "";
// TODO: flags
const wreport::Var* vattr = v.next_attr();
if (vattr == NULL) {
vm2value.flags = "";
} else {
vm2value.flags = "000000000";
for (vattr = v.next_attr(); vattr != NULL;
vattr = vattr->next_attr()) {
if (vattr->code() == WR_VAR(0,33,196) && vattr->enqi() == 1)
vm2value.flags[0] = '1';
if (vattr->code() == WR_VAR(0,33,197) && vattr->enqi() == 1)
vm2value.flags[0] = '2';
if (vattr->code() == WR_VAR(0,33,192)) {
std::string qc = convert_qc_back(vattr->enqi());
vm2value.flags[1] = qc.at(0);
vm2value.flags[2] = qc.at(1);
}
if (vattr->code() == WR_VAR(0,33,193)) {
std::string qc = convert_qc_back(vattr->enqi());
vm2value.flags[3] = qc.at(0);
vm2value.flags[4] = qc.at(1);
}
if (vattr->code() == WR_VAR(0,33,194)) {
std::string qc = convert_qc_back(vattr->enqi());
vm2value.flags[5] = qc.at(0);
vm2value.flags[6] = qc.at(1);
}
}
}
vm2value.flags = attrs2json(v);
meteo::vm2::Parser::serialize(std::cout, vm2value);
}
}
Expand Down
35 changes: 24 additions & 11 deletions src/meteo-vm2-to-bufr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include <iostream>
#include <fstream>
#include <cstring>
#include <algorithm>
#include <cctype>

#include <meteo-vm2/source.h>
#include <meteo-vm2/parser.h>
Expand Down Expand Up @@ -132,17 +134,28 @@ static inline void set_variable(meteo::vm2::Source* source, const meteo::vm2::Va
value.value1);

wreport::Var var = dballe::var(varcode, val);
if (value.flags.size() == 9) {
if (value.flags[0] == '1')
var.seta(dballe::var(WR_VAR(0, 33, 196), 1));
if (value.flags[0] == '2')
var.seta(dballe::var(WR_VAR(0, 33, 197), 1));
if (value.flags.substr(1,2) != "00")
var.seta(dballe::var(WR_VAR(0, 33, 192), convert_qc(value.flags.substr(1,2))));
if (value.flags.substr(3,2) != "00")
var.seta(dballe::var(WR_VAR(0, 33, 193), convert_qc(value.flags.substr(3,2))));
if (value.flags.substr(5,2) != "00")
var.seta(dballe::var(WR_VAR(0, 33, 194), convert_qc(value.flags.substr(5,2))));
try {
for (const auto& i : value.jsonflags()) {
wreport::Var a(dballe::varinfo(i.first));
a.setf(i.second.c_str());
var.seta(a);
}
} catch(const std::exception& e) {
if (value.flags.size() == 9
and std::all_of(value.flags.begin(), value.flags.end(), [](int ch) {
return std::isdigit(ch);
})) {
if (value.flags[0] == '1')
var.seta(dballe::var(WR_VAR(0, 33, 196), 1));
if (value.flags[0] == '2')
var.seta(dballe::var(WR_VAR(0, 33, 197), 1));
if (value.flags.substr(1,2) != "00")
var.seta(dballe::var(WR_VAR(0, 33, 192), convert_qc(value.flags.substr(1,2))));
if (value.flags.substr(3,2) != "00")
var.seta(dballe::var(WR_VAR(0, 33, 193), convert_qc(value.flags.substr(3,2))));
if (value.flags.substr(5,2) != "00")
var.seta(dballe::var(WR_VAR(0, 33, 194), convert_qc(value.flags.substr(5,2))));
}
}
msg.set(var, varcode, level, trange);
}
Expand Down