diff --git a/library/linux/include/flutter_desktop_embedding/json_method_codec.h b/library/linux/include/flutter_desktop_embedding/json_method_codec.h index 6d1064ce1..38ac8fcc6 100644 --- a/library/linux/include/flutter_desktop_embedding/json_method_codec.h +++ b/library/linux/include/flutter_desktop_embedding/json_method_codec.h @@ -14,8 +14,6 @@ #ifndef LIBRARY_LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_JSON_METHOD_CODEC_H_ #define LIBRARY_LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_JSON_METHOD_CODEC_H_ -#include - #include "method_codec.h" namespace flutter_desktop_embedding { @@ -49,11 +47,6 @@ class JsonMethodCodec : public MethodCodec { std::unique_ptr> EncodeErrorEnvelopeInternal( const std::string &error_code, const std::string &error_message, const void *error_details) const override; - - private: - // Serializes |json| into a byte stream. - std::unique_ptr> EncodeJsonObject( - const Json::Value &json) const; }; } // namespace flutter_desktop_embedding diff --git a/library/linux/src/internal/json_message_codec.cc b/library/linux/src/internal/json_message_codec.cc new file mode 100644 index 000000000..ad40e807b --- /dev/null +++ b/library/linux/src/internal/json_message_codec.cc @@ -0,0 +1,55 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#include "library/linux/src/internal/json_message_codec.h" + +#include +#include + +namespace flutter_desktop_embedding { + +// static +const JsonMessageCodec &JsonMessageCodec::GetInstance() { + static JsonMessageCodec sInstance; + return sInstance; +} + +std::unique_ptr> JsonMessageCodec::EncodeMessage( + const Json::Value &message) const { + Json::StreamWriterBuilder writer_builder; + std::string serialization = Json::writeString(writer_builder, message); + + return std::make_unique>(serialization.begin(), + serialization.end()); +} + +std::unique_ptr JsonMessageCodec::DecodeMessage( + const uint8_t *message, const size_t message_size) const { + Json::CharReaderBuilder reader_builder; + std::unique_ptr parser(reader_builder.newCharReader()); + + auto raw_message = reinterpret_cast(message); + auto json_message = std::make_unique(); + std::string parse_errors; + bool parsing_successful = + parser->parse(raw_message, raw_message + message_size, json_message.get(), + &parse_errors); + if (!parsing_successful) { + std::cerr << "Unable to parse JSON message:" << std::endl + << parse_errors << std::endl; + return nullptr; + } + return json_message; +} + +} // namespace flutter_desktop_embedding diff --git a/library/linux/src/internal/json_message_codec.h b/library/linux/src/internal/json_message_codec.h new file mode 100644 index 000000000..34d47ca88 --- /dev/null +++ b/library/linux/src/internal/json_message_codec.h @@ -0,0 +1,59 @@ +// Copyright 2018 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#ifndef LIBRARY_LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_JSON_MESSAGE_CODEC_H_ +#define LIBRARY_LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_JSON_MESSAGE_CODEC_H_ + +#include +#include + +#include + +namespace flutter_desktop_embedding { + +// A message encoding/decoding mechanism for communications to/from the +// Flutter engine via JSON channels. +// +// TODO: Make this public, once generalizing a MessageCodec parent interface is +// addressed; this is complicated by the return type of EncodeMessage. +// Part of issue #102. +class JsonMessageCodec { + public: + // Returns the shared instance of the codec. + static const JsonMessageCodec &GetInstance(); + + ~JsonMessageCodec() = default; + + // Prevent copying. + JsonMessageCodec(JsonMessageCodec const &) = delete; + JsonMessageCodec &operator=(JsonMessageCodec const &) = delete; + + // Returns a binary encoding of the given message, or nullptr if the + // message cannot be serialized by this codec. + std::unique_ptr> EncodeMessage( + const Json::Value &message) const; + + // Returns the JSON object encoded in |message|, or nullptr if it cannot be + // decoded. + // TODO: Consider adding absl as a dependency and using absl::Span. + std::unique_ptr DecodeMessage(const uint8_t *message, + const size_t message_size) const; + + protected: + // Instances should be obtained via GetInstance. + JsonMessageCodec() = default; +}; + +} // namespace flutter_desktop_embedding + +#endif // LIBRARY_LINUX_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_JSON_MESSAGE_CODEC_H_ diff --git a/library/linux/src/json_method_codec.cc b/library/linux/src/json_method_codec.cc index f11c3df35..29107110f 100644 --- a/library/linux/src/json_method_codec.cc +++ b/library/linux/src/json_method_codec.cc @@ -13,9 +13,8 @@ // limitations under the License. #include "library/linux/include/flutter_desktop_embedding/json_method_codec.h" -#include - #include "library/linux/include/flutter_desktop_embedding/json_method_call.h" +#include "library/linux/src/internal/json_message_codec.h" namespace flutter_desktop_embedding { @@ -33,25 +32,17 @@ const JsonMethodCodec &JsonMethodCodec::GetInstance() { std::unique_ptr JsonMethodCodec::DecodeMethodCallInternal( const uint8_t *message, const size_t message_size) const { - Json::CharReaderBuilder reader_builder; - std::unique_ptr parser(reader_builder.newCharReader()); - - auto raw_message = reinterpret_cast(message); - Json::Value json_message; - std::string parse_errors; - bool parsing_successful = parser->parse( - raw_message, raw_message + message_size, &json_message, &parse_errors); - if (!parsing_successful) { - std::cerr << "Unable to parse JSON method call:" << std::endl - << parse_errors << std::endl; + std::unique_ptr json_message = + JsonMessageCodec::GetInstance().DecodeMessage(message, message_size); + if (!json_message) { return nullptr; } - Json::Value method = json_message[kMessageMethodKey]; + Json::Value method = (*json_message)[kMessageMethodKey]; if (method.isNull()) { return nullptr; } - Json::Value arguments = json_message[kMessageArgumentsKey]; + Json::Value arguments = (*json_message)[kMessageArgumentsKey]; return std::make_unique(method.asString(), arguments); } @@ -62,7 +53,7 @@ std::unique_ptr> JsonMethodCodec::EncodeMethodCallInternal( message[kMessageArgumentsKey] = *static_cast(method_call.arguments()); - return EncodeJsonObject(message); + return JsonMessageCodec::GetInstance().EncodeMessage(message); } std::unique_ptr> @@ -71,7 +62,7 @@ JsonMethodCodec::EncodeSuccessEnvelopeInternal(const void *result) const { envelope.append(result == nullptr ? Json::Value() : *static_cast(result)); - return EncodeJsonObject(envelope); + return JsonMessageCodec::GetInstance().EncodeMessage(envelope); } std::unique_ptr> @@ -84,16 +75,7 @@ JsonMethodCodec::EncodeErrorEnvelopeInternal(const std::string &error_code, envelope.append(error_details == nullptr ? Json::Value() : *static_cast(error_details)); - return EncodeJsonObject(envelope); -} - -std::unique_ptr> JsonMethodCodec::EncodeJsonObject( - const Json::Value &json) const { - Json::StreamWriterBuilder writer_builder; - std::string serialization = Json::writeString(writer_builder, json); - - return std::make_unique>(serialization.begin(), - serialization.end()); + return JsonMessageCodec::GetInstance().EncodeMessage(envelope); } } // namespace flutter_desktop_embedding