Sfoglia il codice sorgente

[add] write formatted json

isundil 9 anni fa
parent
commit
804fa52dd4

+ 7 - 3
CMakeLists.txt

@@ -1,14 +1,18 @@
 cmake_minimum_required(VERSION 2.8)
 
-add_executable(jsonstroll src/main.cpp src/params.cpp src/streamConsumer.cpp src/jsonArray.cpp src/jsonObject.cpp src/jsonElement.cpp src/jsonPrimitive.cpp src/jsonException.cpp)
-add_executable(json_test test/src/main.cpp src/params.cpp src/streamConsumer.cpp src/jsonArray.cpp src/jsonObject.cpp src/jsonElement.cpp src/jsonPrimitive.cpp src/jsonException.cpp)
+add_executable(jsonstroll src/main.cpp src/jsonContainer.cpp src/params.cpp src/curseOutput.cpp src/streamConsumer.cpp src/jsonArray.cpp src/jsonObject.cpp src/jsonElement.cpp src/jsonPrimitive.cpp src/jsonException.cpp)
+add_executable(json_test test/src/main.cpp src/jsonContainer.cpp src/params.cpp src/streamConsumer.cpp src/jsonArray.cpp src/jsonObject.cpp src/jsonElement.cpp src/jsonPrimitive.cpp src/jsonException.cpp)
 
 set_property(TARGET jsonstroll PROPERTY RUNTIME_OUTPUT_DIRECTORY bin)
 
 add_definitions ("-Wall")
 add_definitions ("-g3")
 
-include_directories(include)
+# Add ncurses
+SET(CURSES_NEED_NCURSES TRUE)
+find_package(Curses)
+target_link_libraries(jsonstroll ${ncurses++_LIBRARIES} ${CURSES_LIBRARIES})
+include_directories(include ${CURSES_INCLUDE_DIRS})
 
 enable_testing()
 set_property(TARGET json_test PROPERTY RUNTIME_OUTPUT_DIRECTORY test)

+ 29 - 0
include/curseOutput.hh

@@ -0,0 +1,29 @@
+#pragma once
+
+class JSonElement;
+
+class CurseOutput
+{
+    public:
+        CurseOutput(JSonElement *rootData);
+        virtual ~CurseOutput();
+
+        void run();
+
+    protected:
+        void init();
+        void shutdown();
+        void redraw();
+        void redraw(std::pair<int, int> &, const std::pair<int, int>&, const JSonElement *);
+        bool readInput();
+        void getScreenSize(std::pair<int, int> &);
+        void write(const int &x, const int &y, JSonElement *item);
+        void write(const int &x, const int &y, const std::string &item);
+
+        unsigned int offset_x;
+        unsigned int offset_y;
+
+        const JSonElement *data;
+        const unsigned int indentLevel;
+};
+

+ 3 - 2
include/jsonArray.hh

@@ -1,11 +1,12 @@
 #pragma once
 
 #include <list>
-#include "jsonElement.hh"
+#include "jsonContainer.hh"
 
-class JSonArray: public JSonElement, public std::list<JSonElement *>
+class JSonArray: public JSonContainer, public std::list<JSonElement *>
 {
     public:
         virtual ~JSonArray();
+        virtual unsigned int size() const;
 };
 

+ 13 - 0
include/jsonContainer.hh

@@ -0,0 +1,13 @@
+#pragma once
+
+#include "jsonElement.hh"
+
+class JSonContainer: public JSonElement
+{
+    public:
+        virtual ~JSonContainer();
+        virtual unsigned int size() const =0;
+
+        virtual std::string stringify() const;
+};
+

+ 4 - 0
include/jsonElement.hh

@@ -1,8 +1,12 @@
 #pragma once
 
+#include <string>
+
 class JSonElement
 {
     public:
         virtual ~JSonElement();
+
+        virtual std::string stringify() const =0;
 };
 

+ 3 - 2
include/jsonObject.hh

@@ -1,16 +1,17 @@
 #pragma once
 
 #include <map>
-#include "jsonElement.hh"
+#include "jsonContainer.hh"
 
 template<typename T> class JSonPrimitive;
 
-class JSonObject: public JSonElement, public std::map<std::string, JSonElement*>
+class JSonObject: public JSonContainer, public std::map<std::string, JSonElement*>
 {
     public:
         virtual ~JSonObject();
 
         void push(const std::string &key, JSonElement *child);
+        virtual unsigned int size() const;
         bool contains(const std::string &) const;
 
         const JSonElement* get(const std::string &) const;

+ 1 - 1
include/jsonPrimitive.hh

@@ -1,6 +1,5 @@
 #pragma once
 
-#include <string>
 #include "jsonElement.hh"
 
 template <typename T>
@@ -11,6 +10,7 @@ class JSonPrimitive: public JSonElement
         virtual ~JSonPrimitive();
 
         T getValue() const;
+        virtual std::string stringify() const;
 
         bool operator<(const JSonPrimitive<T> &other) const;
         bool operator==(const JSonPrimitive<T> &other) const;

+ 98 - 0
src/curseOutput.cpp

@@ -0,0 +1,98 @@
+#include<iostream>
+
+#include <unistd.h>
+#include <ncurses.h>
+#include <utility>
+#include "curseOutput.hh"
+#include "jsonObject.hh"
+#include "jsonArray.hh"
+#include "jsonPrimitive.hh"
+
+CurseOutput::CurseOutput(JSonElement *root): data(root), indentLevel(4)
+{ }
+
+CurseOutput::~CurseOutput()
+{ }
+
+void CurseOutput::run()
+{
+    init();
+    do
+    {
+        redraw();
+        refresh();
+        sleep(9);
+    } while(readInput());
+    shutdown();
+}
+
+void CurseOutput::redraw()
+{
+    std::pair<int, int> screenSize;
+    std::pair<int, int> cursor(0, 0);
+
+    redraw(cursor, screenSize, data);
+}
+
+void CurseOutput::redraw(std::pair<int, int> &cursor, const std::pair<int, int> &maxSize, const JSonElement *item)
+{
+    if (dynamic_cast<const JSonObject*>(item) != nullptr)
+    {
+        for (JSonObject::const_iterator i = ((JSonObject *)item)->cbegin(); i != ((JSonObject *)item)->cend(); ++i)
+        {
+            const std::pair<std::string, JSonElement *> ipair = *i;
+            std::string key = ipair.first;
+            write(cursor.first, cursor.second, key +": ");
+            cursor.first += indentLevel;
+            cursor.second++;
+            redraw(cursor, maxSize, ipair.second);
+            cursor.first -= indentLevel;
+        }
+    }
+    else if (dynamic_cast<const JSonArray*>(item) != nullptr)
+    {
+    }
+    else
+    {
+        write(cursor.first, cursor.second, item->stringify());
+        cursor.second++;
+    }
+}
+
+void CurseOutput::write(const int &x, const int &y, JSonElement *item)
+{
+    std::string str = item->stringify();
+    write(x, y, str);
+}
+
+void CurseOutput::write(const int &x, const int &y, const std::string &str)
+{
+    mvprintw(y, x, str.c_str());
+}
+
+/**
+ * Read input and expect signal
+ * @Return true on:
+ *  - Windows resized
+ *  - Key press and need redraw
+ * false on:
+ *  - exit signal
+**/
+bool CurseOutput::readInput()
+{
+    //TODO
+    return false;
+}
+
+void CurseOutput::init()
+{
+    initscr();
+    noecho();
+    curs_set(false);
+}
+
+void CurseOutput::shutdown()
+{
+    endwin();
+}
+

+ 5 - 0
src/jsonArray.cpp

@@ -8,3 +8,8 @@ JSonArray::~JSonArray()
     }
 }
 
+unsigned int JSonArray::size() const
+{
+    return std::list<JSonElement *>::size();
+}
+

+ 10 - 0
src/jsonContainer.cpp

@@ -0,0 +1,10 @@
+#include "jsonContainer.hh"
+
+JSonContainer::~JSonContainer()
+{ }
+
+std::string JSonContainer::stringify() const
+{
+    return std::string();
+}
+

+ 5 - 0
src/jsonObject.cpp

@@ -25,3 +25,8 @@ const JSonElement *JSonObject::get(const std::string &key) const
     return item == cend() ? nullptr : (*item).second;
 }
 
+unsigned int JSonObject::size() const
+{
+    return std::map<std::string, JSonElement *>::size();
+}
+

+ 25 - 1
src/jsonPrimitive.cpp

@@ -3,7 +3,31 @@
 template<> JSonPrimitive<float>::~JSonPrimitive() {}
 template<> JSonPrimitive<bool>::~JSonPrimitive() {}
 template<> JSonPrimitive<int>::~JSonPrimitive() {}
-
 template<> JSonPrimitive<long long>::~JSonPrimitive() {}
 template<> JSonPrimitive<std::string>::~JSonPrimitive() {}
 
+template<> std::string JSonPrimitive<std::string>::stringify() const
+{
+    return value;
+}
+
+template<> std::string JSonPrimitive<float>::stringify() const
+{
+    return std::to_string(value);
+}
+
+template<> std::string JSonPrimitive<long long>::stringify() const
+{
+    return std::to_string(value);
+}
+
+template<> std::string JSonPrimitive<int>::stringify() const
+{
+    return std::to_string(value);
+}
+
+template<> std::string JSonPrimitive<bool>::stringify() const
+{
+    return value ? "true" : "false";
+}
+

+ 17 - 6
src/main.cpp

@@ -1,15 +1,26 @@
-
-#include <iostream>
 #include "streamConsumer.hh"
+#include "curseOutput.hh"
 #include "params.hh"
 
+void run(Params *params)
+{
+    StreamConsumer *stream;
+    CurseOutput *out;
+
+    stream = StreamConsumer::read(params->getInput());
+    out = new CurseOutput(stream->getRoot());
+    out->run();
+    delete out;
+    delete stream;
+}
+
 int main(int ac, char **av)
 {
     Params *params = new Params(ac, av);
-    JSonElement *rootNode;
 
-    if (!params->isValid())
-        return 0;
-    rootNode = StreamConsumer::read(params->getInput())->getRoot();
+    if (params->isValid())
+        run(params);
+    delete params;
+    return 0;
 }
 

+ 42 - 28
test/src/main.cpp

@@ -6,63 +6,68 @@
 #include "jsonElement.hh"
 #include "streamConsumer.hh"
 
+const char testJson[] = "{\"widget\": {\"debug\": \"on\",\"window\": {\"title\": \"Sample Konfabulator Widget\",\"name\": \"main_window\",\"width\": 500,\"height\": 500},\"image\": { \"src\": \"Images/Sun.png\",\"name\": \"sun1\",\"hOffset\": 250,\"vOffset\": 250,\"alignment\": \"center\"},\"text\": {\"data\": \"Click Here\",\"size\": 36,\"style\": \"bold\",\"name\": \"text1\",\"hOffset\": 250,\"vOffset\": 100,\"alignment\": \"center\",\"onMouseUp\": \"sun1.opacity = (sun1.opacity / 100) * 90;\"}}}";
+
 StreamConsumer *toJson(std::string str)
 {
     std::stringstream input(str);
     return StreamConsumer::read(input);
 }
 
+void checkArray()
+{
+    //Check array
+    StreamConsumer *root = toJson("[true, 42, \"coucou\", 12.34, false]");
+    JSonArray *arr = dynamic_cast<JSonArray *>(root->getRoot());
+    assert(arr != nullptr);
+    JSonArray::const_iterator it = arr->cbegin();
+    assert((dynamic_cast<JSonPrimitive<bool> *> (*it)) != nullptr);
+    assert(((JSonPrimitive<bool> *)(*it))->getValue() == true);
+    it++;
+    assert((dynamic_cast<JSonPrimitive<int> *> (*it)) != nullptr);
+    assert(((JSonPrimitive<int> *)(*it))->getValue() == 42);
+    it++;
+    assert((dynamic_cast<JSonPrimitive<std::string> *> (*it)) != nullptr);
+    assert(((JSonPrimitive<std::string> *)(*it))->getValue() == "coucou");
+    it++;
+    assert((dynamic_cast<JSonPrimitive<float> *> (*it)) != nullptr);
+    assert(((JSonPrimitive<float> *)(*it))->getValue() == 12.34f);
+    it++;
+    assert((dynamic_cast<JSonPrimitive<bool> *> (*it)) != nullptr);
+    assert(((JSonPrimitive<bool> *)(*it))->getValue() == false);
+    delete root;
+}
+
 void checkTypes()
 {
+    //Check basic types
     StreamConsumer *root = toJson("{\"test\":\"value\"}");
     assert(dynamic_cast<JSonObject*>(root->getRoot()) != nullptr);
     delete root;
-
     root = toJson("[\"test\",\"value\"]");
     assert(dynamic_cast<JSonArray*>(root->getRoot()) != nullptr);
     delete root;
-
     root = toJson("\"test\"");
     assert(dynamic_cast<JSonPrimitive<std::string> *>(root->getRoot()) != nullptr);
     delete root;
-
     root = toJson("42");
     assert(dynamic_cast<JSonPrimitive<int> *>(root->getRoot()) != nullptr);
     delete root;
-
     root = toJson("42.2");
     assert(dynamic_cast<JSonPrimitive<float> *>(root->getRoot()) != nullptr);
     delete root;
-
     root = toJson(std::to_string((long long)LLONG_MAX));
     assert(dynamic_cast<JSonPrimitive<long long> *>(root->getRoot()) != nullptr);
     delete root;
-
     root = toJson("true");
     assert(dynamic_cast<JSonPrimitive<bool> *>(root->getRoot()) != nullptr);
     delete root;
+}
 
-    root = toJson("[true, 42, \"coucou\", 12.34, false]");
-    JSonArray *arr = dynamic_cast<JSonArray *>(root->getRoot());
-    assert(arr != nullptr);
-    JSonArray::const_iterator it = arr->cbegin();
-    assert((dynamic_cast<JSonPrimitive<bool> *> (*it)) != nullptr);
-    assert(((JSonPrimitive<bool> *)(*it))->getValue() == true);
-    it++;
-    assert((dynamic_cast<JSonPrimitive<int> *> (*it)) != nullptr);
-    assert(((JSonPrimitive<int> *)(*it))->getValue() == 42);
-    it++;
-    assert((dynamic_cast<JSonPrimitive<std::string> *> (*it)) != nullptr);
-    assert(((JSonPrimitive<std::string> *)(*it))->getValue() == "coucou");
-    it++;
-    assert((dynamic_cast<JSonPrimitive<float> *> (*it)) != nullptr);
-    assert(((JSonPrimitive<float> *)(*it))->getValue() == 12.34f);
-    it++;
-    assert((dynamic_cast<JSonPrimitive<bool> *> (*it)) != nullptr);
-    assert(((JSonPrimitive<bool> *)(*it))->getValue() == false);
-    delete root;
-
-    root = toJson("{\"bool\":true, \"int\":42, \"str\":\"coucou\", \"float\":12.34, \"arrayOfInt\":[1, 2, 3, 4.5]}");
+void checkObject()
+{
+    //Check Obj
+    StreamConsumer *root = toJson("{\"bool\":true, \"int\":42, \"str\":\"coucou\", \"float\":12.34, \"arrayOfInt\":[1, 2, 3, 4.5]}");
     assert(dynamic_cast<JSonObject *>(root->getRoot()) != nullptr);
     assert(((JSonObject *)(root->getRoot()))->size() == 5);
     const JSonElement *tmp = ((JSonObject *)(root->getRoot()))->get("bool");
@@ -81,7 +86,7 @@ void checkTypes()
     const JSonArray *arr2 = dynamic_cast<const JSonArray *> (tmp);
     assert(arr2 != nullptr);
     assert(arr2->size() == 4);
-    it = arr2->cbegin();
+    JSonArray::const_iterator it = arr2->cbegin();
     assert((dynamic_cast<JSonPrimitive<int> *> (*it)) != nullptr);
     assert(((JSonPrimitive<int> *)(*it))->getValue() == 1);
     it++;
@@ -96,9 +101,18 @@ void checkTypes()
     delete root;
 }
 
+void checkSample()
+{
+    StreamConsumer *root = toJson(testJson);
+    root->getRoot();
+}
+
 int main(int ac, char **av)
 {
     checkTypes();
+    checkArray();
+    checkObject();
+    checkSample();
     exit(EXIT_SUCCESS);
 }