From 23ff3f990152971827afeb03d4a69533a9f5418f Mon Sep 17 00:00:00 2001 From: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com> Date: Thu, 13 Apr 2023 01:35:02 -0400 Subject: [PATCH] Make serialize_json_to_string output compactly (without newlines) when indent argument is less than 1 (#1578) * Make serialize_json_to_string output compact when indent is less than 1 * Add C++ test --------- Signed-off-by: Jean-Christophe Morin --- src/opentimelineio/serialization.cpp | 56 ++++++++++++- tests/CMakeLists.txt | 2 +- tests/test_serialization.cpp | 117 +++++++++++++++++++++++++++ 3 files changed, 171 insertions(+), 4 deletions(-) create mode 100644 tests/test_serialization.cpp diff --git a/src/opentimelineio/serialization.cpp b/src/opentimelineio/serialization.cpp index 32f107deb..5be9575d0 100644 --- a/src/opentimelineio/serialization.cpp +++ b/src/opentimelineio/serialization.cpp @@ -1216,7 +1216,7 @@ SerializableObject::clone(ErrorStatus* error_status) const // to json_string std::string -serialize_json_to_string( +serialize_json_to_string_pretty( const any& value, const schema_version_map* schema_version_targets, ErrorStatus* error_status, @@ -1232,11 +1232,39 @@ serialize_json_to_string( OTIO_rapidjson::kWriteNanAndInfFlag> json_writer(output_string_buffer); - if (indent >= 0) + json_writer.SetIndent(' ', indent); + + JSONEncoder json_encoder(json_writer); + + if (!SerializableObject::Writer::write_root( + value, + json_encoder, + schema_version_targets, + error_status)) { - json_writer.SetIndent(' ', indent); + return std::string(); } + return std::string(output_string_buffer.GetString()); +} + +// to json_string +std::string +serialize_json_to_string_compact( + const any& value, + const schema_version_map* schema_version_targets, + ErrorStatus* error_status) +{ + OTIO_rapidjson::StringBuffer output_string_buffer; + + OTIO_rapidjson::Writer< + decltype(output_string_buffer), + OTIO_rapidjson::UTF8<>, + OTIO_rapidjson::UTF8<>, + OTIO_rapidjson::CrtAllocator, + OTIO_rapidjson::kWriteNanAndInfFlag> + json_writer(output_string_buffer); + JSONEncoder json_encoder(json_writer); if (!SerializableObject::Writer::write_root( @@ -1251,6 +1279,28 @@ serialize_json_to_string( return std::string(output_string_buffer.GetString()); } +// to json_string +std::string +serialize_json_to_string( + const any& value, + const schema_version_map* schema_version_targets, + ErrorStatus* error_status, + int indent) +{ + if (indent > 0) + { + return serialize_json_to_string_pretty( + value, + schema_version_targets, + error_status, + indent); + } + return serialize_json_to_string_compact( + value, + schema_version_targets, + error_status); +} + bool serialize_json_to_file( any const& value, diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 57a5231c8..00e545e6c 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -15,7 +15,7 @@ foreach(test ${tests_opentime}) WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) endforeach() -list(APPEND tests_opentimelineio test_clip test_serializableCollection test_timeline test_track) +list(APPEND tests_opentimelineio test_clip test_serialization test_serializableCollection test_timeline test_track) foreach(test ${tests_opentimelineio}) add_executable(${test} utils.h utils.cpp ${test}.cpp) diff --git a/tests/test_serialization.cpp b/tests/test_serialization.cpp new file mode 100644 index 000000000..53c352b2c --- /dev/null +++ b/tests/test_serialization.cpp @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: Apache-2.0 +// Copyright Contributors to the OpenTimelineIO project + +#include "utils.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace otime = opentime::OPENTIME_VERSION; +namespace otio = opentimelineio::OPENTIMELINEIO_VERSION; + +int +main(int argc, char** argv) +{ + Tests tests; + + tests.add_test( + "success with default indent", [] { + otio::SerializableObject::Retainer cl = + new otio::Clip(); + otio::SerializableObject::Retainer tr = + new otio::Track(); + tr->append_child(cl); + otio::SerializableObject::Retainer tl = + new otio::Timeline(); + tl->tracks()->append_child(tr); + + otio::ErrorStatus err; + auto output = tl.value->to_json_string(&err, {}); + assertFalse(otio::is_error(err)); + assertEqual(output.c_str(), R"CONTENT({ + "OTIO_SCHEMA": "Timeline.1", + "metadata": {}, + "name": "", + "global_start_time": null, + "tracks": { + "OTIO_SCHEMA": "Stack.1", + "metadata": {}, + "name": "tracks", + "source_range": null, + "effects": [], + "markers": [], + "enabled": true, + "children": [ + { + "OTIO_SCHEMA": "Track.1", + "metadata": {}, + "name": "", + "source_range": null, + "effects": [], + "markers": [], + "enabled": true, + "children": [ + { + "OTIO_SCHEMA": "Clip.2", + "metadata": {}, + "name": "", + "source_range": null, + "effects": [], + "markers": [], + "enabled": true, + "media_references": { + "DEFAULT_MEDIA": { + "OTIO_SCHEMA": "MissingReference.1", + "metadata": {}, + "name": "", + "available_range": null, + "available_image_bounds": null + } + }, + "active_media_reference_key": "DEFAULT_MEDIA" + } + ], + "kind": "Video" + } + ] + } +})CONTENT"); + }); + + tests.add_test( + "success with indent set to 0", [] { + otio::SerializableObject::Retainer so = + new otio::SerializableObjectWithMetadata(); + + otio::ErrorStatus err; + auto output = so.value->to_json_string(&err, {}, 0); + assertFalse(otio::is_error(err)); + assertEqual(output.c_str(), R"CONTENT({"OTIO_SCHEMA":"SerializableObjectWithMetadata.1","metadata":{},"name":""})CONTENT"); + }); + + tests.add_test( + "success with indent set to 2", [] { + otio::SerializableObject::Retainer so = + new otio::SerializableObjectWithMetadata(); + + otio::ErrorStatus err; + auto output = so.value->to_json_string(&err, {}, 2); + assertFalse(otio::is_error(err)); + assertEqual(output.c_str(), R"CONTENT({ + "OTIO_SCHEMA": "SerializableObjectWithMetadata.1", + "metadata": {}, + "name": "" +})CONTENT"); + }); + + tests.run(argc, argv); + return 0; +}