summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt6
-rw-r--r--include/text/json_formatter.h45
-rw-r--r--src/text/json_formatter.cpp151
-rw-r--r--test/format_test.cpp14
4 files changed, 213 insertions, 3 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 39de6c6715..3baaf4fd66 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -15,8 +15,10 @@ add_library(nbt++ STATIC
src/tag_string.cpp
src/value.cpp
src/value_initializer.cpp
-
- src/io/stream_reader.cpp)
+
+ src/io/stream_reader.cpp
+
+ src/text/json_formatter.cpp)
enable_testing()
add_subdirectory(test)
diff --git a/include/text/json_formatter.h b/include/text/json_formatter.h
new file mode 100644
index 0000000000..6288a734b0
--- /dev/null
+++ b/include/text/json_formatter.h
@@ -0,0 +1,45 @@
+/*
+ * libnbt++ - A library for the Minecraft Named Binary Tag format.
+ * Copyright (C) 2013, 2015 ljfa-ag
+ *
+ * This file is part of libnbt++.
+ *
+ * libnbt++ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * libnbt++ 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libnbt++. If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef JSON_FORMATTER_H_INCLUDED
+#define JSON_FORMATTER_H_INCLUDED
+
+#include "tagfwd.h"
+#include <ostream>
+
+namespace nbt
+{
+namespace text
+{
+
+/**
+ * @brief Prints tags in a JSON-like syntax into a stream
+ *
+ * @todo Make it configurable and able to produce actual standard-conformant JSON
+ */
+class json_formatter
+{
+public:
+ void write(std::ostream& os, const tag& t);
+};
+
+}
+}
+
+#endif // JSON_FORMATTER_H_INCLUDED
diff --git a/src/text/json_formatter.cpp b/src/text/json_formatter.cpp
new file mode 100644
index 0000000000..eb94d8af63
--- /dev/null
+++ b/src/text/json_formatter.cpp
@@ -0,0 +1,151 @@
+/*
+ * libnbt++ - A library for the Minecraft Named Binary Tag format.
+ * Copyright (C) 2013, 2015 ljfa-ag
+ *
+ * This file is part of libnbt++.
+ *
+ * libnbt++ is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * libnbt++ 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libnbt++. If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "text/json_formatter.h"
+#include "nbt_tags.h"
+#include "nbt_visitor.h"
+#include <cmath>
+
+namespace nbt
+{
+namespace text
+{
+
+namespace //anonymous
+{
+ class json_fmt_visitor : public const_nbt_visitor
+ {
+ public:
+ json_fmt_visitor(std::ostream& os): os(os) {}
+
+ void visit(const tag_byte& b) override
+ { os << static_cast<int>(b.get()) << "b"; } //We don't want to print a character
+
+ void visit(const tag_short& s) override
+ { os << s.get() << "s"; }
+
+ void visit(const tag_int& i) override
+ { os << i.get(); }
+
+ void visit(const tag_long& l) override
+ { os << l.get() << "l"; }
+
+ void visit(const tag_float& f) override
+ {
+ write_double(f.get());
+ os << "f";
+ }
+
+ void visit(const tag_double& d) override
+ {
+ write_double(d.get());
+ os << "d";
+ }
+
+ void visit(const tag_byte_array& ba) override
+ { os << "[" << ba.size() << " bytes]"; }
+
+ void visit(const tag_string& s) override
+ { os << '"' << s.get() << '"'; } //TODO: escape special characters
+
+ void visit(const tag_list& l) override
+ {
+ os << "[\n";
+ ++indent_lvl;
+ for(unsigned int i = 0; i < l.size(); ++i)
+ {
+ indent();
+ l[i].get().accept(*this);
+ if(i != l.size()-1)
+ os << ",";
+ os << "\n";
+ }
+ --indent_lvl;
+ indent();
+ os << "]";
+ }
+
+ void visit(const tag_compound& c) override
+ {
+ os << "{\n";
+ ++indent_lvl;
+ unsigned int i = 0;
+ for(const auto& kv: c)
+ {
+ indent();
+ os << kv.first << ": ";
+ kv.second.get().accept(*this);
+ if(i != c.size()-1)
+ os << ",";
+ os << "\n";
+ ++i;
+ }
+ --indent_lvl;
+ indent();
+ os << "}";
+ }
+
+ void visit(const tag_int_array& ia) override
+ {
+ os << "[";
+ for(unsigned int i = 0; i < ia.size(); ++i)
+ {
+ os << ia[i];
+ if(i != ia.size()-1)
+ os << ", ";
+ }
+ os << "]";
+ }
+
+ private:
+ const std::string indent_str = " ";
+
+ std::ostream& os;
+ int indent_lvl = 0;
+
+ void indent()
+ {
+ for(int i = 0; i < indent_lvl; ++i)
+ os << indent_str;
+ }
+
+ void write_double(double d)
+ {
+ if(std::isfinite(d))
+ os << d;
+ else if(std::isinf(d))
+ {
+ if(std::signbit(d))
+ os << "-";
+ os << "Infinity";
+ }
+ else
+ os << "NaN";
+ }
+ };
+}
+
+void json_formatter::write(std::ostream& os, const tag& t)
+{
+ json_fmt_visitor v(os);
+ t.accept(v);
+}
+
+}
+}
diff --git a/test/format_test.cpp b/test/format_test.cpp
index 7fb7ca45d8..893637c19d 100644
--- a/test/format_test.cpp
+++ b/test/format_test.cpp
@@ -17,12 +17,24 @@
* You should have received a copy of the GNU Lesser General Public License
* along with libnbt++. If not, see <http://www.gnu.org/licenses/>.
*/
+#include "microtest.h"
+#include "text/json_formatter.h"
+#include "io/stream_reader.h"
+#include <fstream>
#include <iostream>
+#include "nbt_tags.h"
using namespace nbt;
int main()
{
+ std::ifstream file("bigtest_uncompr", std::ios::binary);
+ ASSERT(file);
+ std::string key;
+ std::unique_ptr<tag_compound> comp;
+ std::tie(key, comp) = io::stream_reader(file).read_compound();
+ std::cout << "----- json_formatter:\n";
+ text::json_formatter().write(std::cout, *comp);
+ std::cout << "\n-----" << std::endl;
}
-