From 793117367155fd9e92ebb6e086d65e6b03afc5e6 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 17 Jun 2014 12:33:31 -0700 Subject: [PATCH] Working on tools to convert bitstreams to/from json. --- CMakeLists.txt | 1 + cmake/macros/AutoMTC.cmake | 6 +- libraries/metavoxels/src/Bitstream.cpp | 1 + libraries/metavoxels/src/Bitstream.h | 4 ++ tests/metavoxels/src/MetavoxelTests.cpp | 2 + tools/CMakeLists.txt | 6 ++ tools/bitstream2json/CMakeLists.txt | 20 +++++++ tools/bitstream2json/src/main.cpp | 70 +++++++++++++++++++++++ tools/json2bitstream/CMakeLists.txt | 20 +++++++ tools/json2bitstream/src/main.cpp | 76 +++++++++++++++++++++++++ 10 files changed, 201 insertions(+), 5 deletions(-) create mode 100644 tools/CMakeLists.txt create mode 100644 tools/bitstream2json/CMakeLists.txt create mode 100644 tools/bitstream2json/src/main.cpp create mode 100644 tools/json2bitstream/CMakeLists.txt create mode 100644 tools/json2bitstream/src/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index cb1e4224cf..a399e11168 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -49,4 +49,5 @@ add_subdirectory(assignment-client) add_subdirectory(domain-server) add_subdirectory(interface) add_subdirectory(tests) +add_subdirectory(tools) add_subdirectory(voxel-edit) diff --git a/cmake/macros/AutoMTC.cmake b/cmake/macros/AutoMTC.cmake index 1682b9cd56..6f0216de7f 100644 --- a/cmake/macros/AutoMTC.cmake +++ b/cmake/macros/AutoMTC.cmake @@ -9,13 +9,9 @@ # macro(AUTO_MTC TARGET ROOT_DIR) - if (NOT TARGET mtc) - add_subdirectory("${ROOT_DIR}/tools/mtc" "${ROOT_DIR}/tools/mtc") - endif () - set(AUTOMTC_SRC ${TARGET}_automtc.cpp) file(GLOB INCLUDE_FILES src/*.h) add_custom_command(OUTPUT ${AUTOMTC_SRC} COMMAND mtc -o ${AUTOMTC_SRC} ${INCLUDE_FILES} DEPENDS mtc ${INCLUDE_FILES}) -endmacro() \ No newline at end of file +endmacro() diff --git a/libraries/metavoxels/src/Bitstream.cpp b/libraries/metavoxels/src/Bitstream.cpp index 86f508ca11..0667e71fb1 100644 --- a/libraries/metavoxels/src/Bitstream.cpp +++ b/libraries/metavoxels/src/Bitstream.cpp @@ -33,6 +33,7 @@ REGISTER_SIMPLE_TYPE_STREAMER(QByteArray) REGISTER_SIMPLE_TYPE_STREAMER(QColor) REGISTER_SIMPLE_TYPE_STREAMER(QScriptValue) REGISTER_SIMPLE_TYPE_STREAMER(QString) +REGISTER_SIMPLE_TYPE_STREAMER(QVariant) REGISTER_SIMPLE_TYPE_STREAMER(QUrl) REGISTER_SIMPLE_TYPE_STREAMER(QVariantList) REGISTER_SIMPLE_TYPE_STREAMER(QVariantHash) diff --git a/libraries/metavoxels/src/Bitstream.h b/libraries/metavoxels/src/Bitstream.h index 776a362717..66a42e6991 100644 --- a/libraries/metavoxels/src/Bitstream.h +++ b/libraries/metavoxels/src/Bitstream.h @@ -805,6 +805,8 @@ public: template JSONWriter& operator<<(const T& value) { _contents.append(getData(value)); return *this; } + void appendToContents(const QJsonValue& value) { _contents.append(value); } + void addSharedObject(const SharedObjectPointer& object); void addObjectStreamer(const ObjectStreamer* streamer); void addTypeStreamer(const TypeStreamer* streamer); @@ -893,6 +895,8 @@ public: template JSONReader& operator>>(T& value) { putData(*_contentsIterator++, value); return *this; } + QJsonValue retrieveNextFromContents() { return *_contentsIterator++; } + TypeStreamerPointer getTypeStreamer(const QString& name) const; ObjectStreamerPointer getObjectStreamer(const QString& name) const { return _objectStreamers.value(name); } SharedObjectPointer getSharedObject(int id) const { return _sharedObjects.value(id); } diff --git a/tests/metavoxels/src/MetavoxelTests.cpp b/tests/metavoxels/src/MetavoxelTests.cpp index 4a3010caf4..85be9a5c8b 100644 --- a/tests/metavoxels/src/MetavoxelTests.cpp +++ b/tests/metavoxels/src/MetavoxelTests.cpp @@ -255,6 +255,8 @@ static bool testSerialization(Bitstream::MetadataType metadataType) { jsonWriter << endRead; QByteArray encodedJson = jsonWriter.getDocument().toJson(); + qDebug() << encodedJson; + // and read from JSON JSONReader jsonReader(QJsonDocument::fromJson(encodedJson), Bitstream::ALL_GENERICS); jsonReader >> testObjectReadA; diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 0000000000..79db82e90f --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 2.8) + +# add the tool directories +add_subdirectory(bitstream2json) +add_subdirectory(json2bitstream) +add_subdirectory(mtc) diff --git a/tools/bitstream2json/CMakeLists.txt b/tools/bitstream2json/CMakeLists.txt new file mode 100644 index 0000000000..6483c024a7 --- /dev/null +++ b/tools/bitstream2json/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 2.8) + +if (WIN32) + cmake_policy (SET CMP0020 NEW) +endif (WIN32) + +set(TARGET_NAME bitstream2json) + +set(ROOT_DIR ../..) +set(MACRO_DIR "${ROOT_DIR}/cmake/macros") + +find_package(Qt5 COMPONENTS Network Script Widgets) + +include(${MACRO_DIR}/SetupHifiProject.cmake) +setup_hifi_project(${TARGET_NAME} TRUE) + +link_hifi_library(metavoxels ${TARGET_NAME} "${ROOT_DIR}") +link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") + +target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script) diff --git a/tools/bitstream2json/src/main.cpp b/tools/bitstream2json/src/main.cpp new file mode 100644 index 0000000000..0f299527b0 --- /dev/null +++ b/tools/bitstream2json/src/main.cpp @@ -0,0 +1,70 @@ +// +// main.cpp +// tools/bitstream2json/src +// +// Created by Andrzej Kapolka on 6/17/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + +#include + +#include +#include +#include + +#include + +using namespace std; + +int main (int argc, char** argv) { + // need the core application for the script engine + QCoreApplication app(argc, argv); + + if (argc < 3) { + cerr << "Usage: bitstream2json inputfile outputfile [types...]" << endl; + return 0; + } + QFile inputFile(argv[1]); + if (!inputFile.open(QIODevice::ReadOnly)) { + cerr << "Failed to open input file: " << inputFile.errorString().toLatin1().constData() << endl; + return 1; + } + QDataStream inputData(&inputFile); + Bitstream input(inputData, Bitstream::FULL_METADATA, Bitstream::ALL_GENERICS); + + QFile outputFile(argv[2]); + if (!outputFile.open(QIODevice::WriteOnly)) { + cerr << "Failed to open output file: " << outputFile.errorString().toLatin1().constData() << endl; + return 1; + } + JSONWriter output; + + if (argc < 4) { + // default type is a single QVariant + QVariant value; + input >> value; + output << value; + + } else { + for (int i = 3; i < argc; i++) { + int type = QMetaType::type(argv[i]); + if (type == QMetaType::UnknownType) { + cerr << "Unknown type: " << argv[i] << endl; + return 1; + } + const TypeStreamer* streamer = Bitstream::getTypeStreamer(type); + if (!streamer) { + cerr << "Non-streamable type: " << argv[i] << endl; + return 1; + } + QVariant value = streamer->read(input); + output.appendToContents(streamer->getJSONData(output, value)); + } + } + + outputFile.write(output.getDocument().toJson()); + + return 0; +} diff --git a/tools/json2bitstream/CMakeLists.txt b/tools/json2bitstream/CMakeLists.txt new file mode 100644 index 0000000000..799f3bcc4c --- /dev/null +++ b/tools/json2bitstream/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 2.8) + +if (WIN32) + cmake_policy (SET CMP0020 NEW) +endif (WIN32) + +set(TARGET_NAME json2bitstream) + +set(ROOT_DIR ../..) +set(MACRO_DIR "${ROOT_DIR}/cmake/macros") + +find_package(Qt5 COMPONENTS Network Script Widgets) + +include(${MACRO_DIR}/SetupHifiProject.cmake) +setup_hifi_project(${TARGET_NAME} TRUE) + +link_hifi_library(metavoxels ${TARGET_NAME} "${ROOT_DIR}") +link_hifi_library(shared ${TARGET_NAME} "${ROOT_DIR}") + +target_link_libraries(${TARGET_NAME} Qt5::Network Qt5::Widgets Qt5::Script) diff --git a/tools/json2bitstream/src/main.cpp b/tools/json2bitstream/src/main.cpp new file mode 100644 index 0000000000..ff09bcfdc6 --- /dev/null +++ b/tools/json2bitstream/src/main.cpp @@ -0,0 +1,76 @@ +// +// main.cpp +// tools/json2bitstream/src +// +// Created by Andrzej Kapolka on 6/17/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + +#include + +#include +#include +#include + +#include + +using namespace std; + +int main (int argc, char** argv) { + // need the core application for the script engine + QCoreApplication app(argc, argv); + + if (argc < 3) { + cerr << "Usage: bitstream2json inputfile outputfile [types...]" << endl; + return 0; + } + QFile inputFile(argv[1]); + if (!inputFile.open(QIODevice::ReadOnly)) { + cerr << "Failed to open input file: " << inputFile.errorString().toLatin1().constData() << endl; + return 1; + } + QJsonParseError error; + QJsonDocument document = QJsonDocument::fromJson(inputFile.readAll(), &error); + if (error.error != QJsonParseError::NoError) { + cerr << "Failed to read input file: " << error.errorString().toLatin1().constData() << endl; + return 1; + } + JSONReader input(document, Bitstream::ALL_GENERICS); + + QFile outputFile(argv[2]); + if (!outputFile.open(QIODevice::WriteOnly)) { + cerr << "Failed to open output file: " << outputFile.errorString().toLatin1().constData() << endl; + return 1; + } + QDataStream outputData(&outputFile); + Bitstream output(outputData, Bitstream::FULL_METADATA); + + if (argc < 4) { + // default type is a single QVariant + QVariant value; + input >> value; + output << value; + + } else { + for (int i = 3; i < argc; i++) { + int type = QMetaType::type(argv[i]); + if (type == QMetaType::UnknownType) { + cerr << "Unknown type: " << argv[i] << endl; + return 1; + } + const TypeStreamer* streamer = Bitstream::getTypeStreamer(type); + if (!streamer) { + cerr << "Non-streamable type: " << argv[i] << endl; + return 1; + } + QVariant value; + streamer->putJSONData(input, input.retrieveNextFromContents(), value); + streamer->write(output, value); + } + } + output.flush(); + + return 0; +}