• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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