From ee720ed3bcc18fad43127d27e9d57781ecc91393 Mon Sep 17 00:00:00 2001
From: Daniel Friesel <derf@finalrewind.org>
Date: Mon, 12 Nov 2018 13:47:44 +0100
Subject: [PATCH] prototest: json serialization

---
 Makefile                      |  4 +++
 include/object/outputstream.h |  7 ++++++
 src/app/prototest/main.cc     | 46 ++++++++++++++++++++++++++++++++---
 src/os/object/outputstream.cc | 10 ++++++++
 4 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/Makefile b/Makefile
index 3148fdc..ff1e070 100644
--- a/Makefile
+++ b/Makefile
@@ -116,6 +116,10 @@ ifeq (${wakeup}, 1)
 	COMMON_FLAGS += -DWITH_WAKEUP
 endif
 
+ifeq (${ostream}, 1)
+	COMMON_FLAGS += -DWITH_OSTREAM
+endif
+
 include src/arch/${arch}/Makefile.inc
 
 clean: arch_clean
diff --git a/include/object/outputstream.h b/include/object/outputstream.h
index 70ebece..c6b503f 100644
--- a/include/object/outputstream.h
+++ b/include/object/outputstream.h
@@ -2,6 +2,9 @@
 #define OUTPUTSTREAM_H
 
 #include <stdint.h>
+#ifdef WITH_OSTREAM
+#include <ostream>
+#endif
 
 class OutputStream {
  private:
@@ -39,6 +42,10 @@ class OutputStream {
 	OutputStream & operator<<(double number);
 	OutputStream & operator<<(OutputStream & (*fun) (OutputStream &));
 
+#ifdef WITH_OSTREAM
+	OutputStream & operator<<(std::string s);
+#endif
+
 	void setBase(uint8_t b);
 	void printf_uint8(uint8_t num);
 	void printf_float(float num);
diff --git a/src/app/prototest/main.cc b/src/app/prototest/main.cc
index 05c3469..43c24f9 100644
--- a/src/app/prototest/main.cc
+++ b/src/app/prototest/main.cc
@@ -9,15 +9,48 @@
 
 char buf[256];
 
+// TODOs
+//
+// Code -> JSON
+// Code -> XDR
+// Code -> MsgPack
+// Code -> ProtoBuf
+// Code -> CBOR
+//
+// JSON -> Code/Data
+// XDR -> Code/Data
+// MsgPack -> Code/Data
+// ProtoBuf -> Code/Data
+// CBOR -> Code/Data
+
 void loop(void)
 {
+	static unsigned int ts = 0;
 	char json[] = "{\"sensor\":\"gps\",\"time\":1351824120,\"data\":[48.756080,2.302038]}";
 	ArduinoJson::StaticJsonBuffer<200> jsonBuffer;
 	ArduinoJson::JsonObject& root = jsonBuffer.parseObject(json);
 	const char *sensor = root["sensor"];
 	kout << "sensor: " << sensor << endl;
 
+	/*
+	 * nlohmann modernjson serialization
+	 */
+
+	nlohmann::json js1;
+	js1["sensor"] = "gps";
+	js1["time"] = ts;
+	js1["data"] = {48.756080, 2.302038};
+	kout << js1.dump() << endl;
+
+	nlohmann::json js2 = {
+		{"sensor", "gps"},
+		{"time", ts},
+		{"data", {48.756080, 2.302038} }
+	};
+	kout << js2.dump() << endl;
+
 	nlohmann::json j = R"({"compact": true, "schema": 0})"_json;
+	j["ts"] = ts;
 	std::vector<std::uint8_t> v_cbor = nlohmann::json::to_cbor(j);
 
 	kout << "CBOR vector is " << hex;
@@ -26,15 +59,21 @@ void loop(void)
 	}
 	kout << endl;
 
-	kout << "manual JSON: {\"sensor\":\"gps\",\"time\":" << dec << 1351824120;
+	kout << "manual JSON: {\"sensor\":\"gps\",\"time\":" << dec << ts;
 	kout << ",\"data\":[" << 48.756080 << "," << 2.302038 << "]}" << endl;
 
+	/*
+	 * nlohmann modernjson deserialization
+	 */
+
+	auto jd1 = R"({"compact": true, "schema": 0})"_json; 
+
 	BufferOutput<XDRStream> foostream(buf);
 	XDRInput input(buf);
 
 	char test[] = "Obai World!";
 
-	foostream << 123 << -2 << 123456 << 0 << 4294967296 << 0;
+	foostream << 123 << -2 << ts << 0 << 4294967296 << 0;
 	foostream.setNextArrayLen(3);
 	foostream << fixed << "Hai";
 	foostream.setNextArrayLen(sizeof(test));
@@ -50,7 +89,7 @@ void loop(void)
 	kout << dec;
 	kout << "foostream = " << input.get_uint32() << " = " << 123;
 	kout << ", " << input.get_int32() << " = " << -2;
-	kout << ", " << input.get_uint32() << " = " << 123456;
+	kout << ", " << input.get_uint32() << " = " << ts;
 	kout << ", " << input.get_uint32();
 	kout << ", " << input.get_uint64();
 	kout << ", " << input.get_uint32();
@@ -63,6 +102,7 @@ void loop(void)
 #ifdef TIMER_S
 	kout << dec << uptime.get_s() << endl;
 #endif
+	ts++;
 }
 
 int main(void)
diff --git a/src/os/object/outputstream.cc b/src/os/object/outputstream.cc
index 1ce260e..4359874 100644
--- a/src/os/object/outputstream.cc
+++ b/src/os/object/outputstream.cc
@@ -140,6 +140,16 @@ OutputStream & OutputStream::operator<<(OutputStream & (*fkt) (OutputStream &))
 	return fkt(*this);
 }
 
+#ifdef WITH_OSTREAM
+OutputStream & OutputStream::operator<<(std::string s)
+{
+	for (auto c : s) {
+		put(c);
+	}
+	return *this;
+}
+#endif
+
 void OutputStream::setBase(uint8_t b)
 {
 	if (b == 2 || b == 8 || b == 10 || b == 16) {
-- 
GitLab