1 // Copyright 2013 The Flutter Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package io.flutter.plugin.common; 6 7 import java.nio.ByteBuffer; 8 import org.json.JSONException; 9 import org.json.JSONObject; 10 import org.json.JSONTokener; 11 12 /** 13 * A {@link MessageCodec} using UTF-8 encoded JSON messages. 14 * 15 * <p>This codec is guaranteed to be compatible with the corresponding 16 * <a href="https://docs.flutter.io/flutter/services/JSONMessageCodec-class.html">JSONMessageCodec</a> 17 * on the Dart side. These parts of the Flutter SDK are evolved synchronously.</p> 18 * 19 * <p>Supports the same Java values as {@link JSONObject#wrap(Object)}.</p> 20 * 21 * <p>On the Dart side, JSON messages are handled by the JSON facilities of the 22 * <a href="https://api.dartlang.org/stable/dart-convert/JSON-constant.html">dart:convert</a> 23 * package.</p> 24 */ 25 public final class JSONMessageCodec implements MessageCodec<Object> { 26 // This codec must match the Dart codec of the same name in package flutter/services. 27 public static final JSONMessageCodec INSTANCE = new JSONMessageCodec(); 28 JSONMessageCodec()29 private JSONMessageCodec() { 30 } 31 32 @Override encodeMessage(Object message)33 public ByteBuffer encodeMessage(Object message) { 34 if (message == null) { 35 return null; 36 } 37 final Object wrapped = JSONUtil.wrap(message); 38 if (wrapped instanceof String) { 39 return StringCodec.INSTANCE.encodeMessage(JSONObject.quote((String) wrapped)); 40 } else { 41 return StringCodec.INSTANCE.encodeMessage(wrapped.toString()); 42 } 43 } 44 45 @Override decodeMessage(ByteBuffer message)46 public Object decodeMessage(ByteBuffer message) { 47 if (message == null) { 48 return null; 49 } 50 try { 51 final String json = StringCodec.INSTANCE.decodeMessage(message); 52 final JSONTokener tokener = new JSONTokener(json); 53 final Object value = tokener.nextValue(); 54 if (tokener.more()) { 55 throw new IllegalArgumentException("Invalid JSON"); 56 } 57 return value; 58 } catch (JSONException e) { 59 throw new IllegalArgumentException("Invalid JSON", e); 60 } 61 } 62 } 63