Flutter Engine
The Flutter Engine
FlutterCodecs.mm
Go to the documentation of this file.
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#import "flutter/shell/platform/darwin/common/framework/Headers/FlutterCodecs.h"
6
7#include <cstring>
8
10
11@implementation FlutterBinaryCodec
12+ (instancetype)sharedInstance {
13 static id _sharedInstance = nil;
14 if (!_sharedInstance) {
15 _sharedInstance = [[FlutterBinaryCodec alloc] init];
16 }
17 return _sharedInstance;
18}
19
20- (NSData*)encode:(id)message {
21 NSAssert(!message || [message isKindOfClass:[NSData class]], @"");
22 return message;
23}
24
25- (NSData*)decode:(NSData*)message {
26 return message;
27}
28@end
29
30@implementation FlutterStringCodec
31+ (instancetype)sharedInstance {
32 static id _sharedInstance = nil;
33 if (!_sharedInstance) {
34 _sharedInstance = [[FlutterStringCodec alloc] init];
35 }
36 return _sharedInstance;
37}
38
39- (NSData*)encode:(id)message {
40 if (message == nil) {
41 return nil;
42 }
43 NSAssert([message isKindOfClass:[NSString class]], @"");
44 NSString* stringMessage = message;
45 const char* utf8 = stringMessage.UTF8String;
46 return [NSData dataWithBytes:utf8 length:strlen(utf8)];
47}
48
49- (NSString*)decode:(NSData*)message {
50 if (message == nil) {
51 return nil;
52 }
53 return [[NSString alloc] initWithData:message encoding:NSUTF8StringEncoding];
54}
55@end
56
57@implementation FlutterJSONMessageCodec
58+ (instancetype)sharedInstance {
59 static id _sharedInstance = nil;
60 if (!_sharedInstance) {
61 _sharedInstance = [[FlutterJSONMessageCodec alloc] init];
62 }
63 return _sharedInstance;
64}
65
66- (NSData*)encode:(id)message {
67 if (message == nil) {
68 return nil;
69 }
70 NSData* encoding;
71 NSError* error;
72 if ([message isKindOfClass:[NSArray class]] || [message isKindOfClass:[NSDictionary class]]) {
73 encoding = [NSJSONSerialization dataWithJSONObject:message options:0 error:&error];
74 } else {
75 // NSJSONSerialization does not support top-level simple values.
76 // We encode as singleton array, then extract the relevant bytes.
77 encoding = [NSJSONSerialization dataWithJSONObject:@[ message ] options:0 error:&error];
78 if (encoding) {
79 encoding = [encoding subdataWithRange:NSMakeRange(1, encoding.length - 2)];
80 }
81 }
82 NSAssert(encoding, @"Invalid JSON message, encoding failed: %@", error);
83 return encoding;
84}
85
86- (id)decode:(NSData*)message {
87 if ([message length] == 0) {
88 return nil;
89 }
90 BOOL isSimpleValue = NO;
91 id decoded = nil;
92 NSError* error;
93 if (0 < message.length) {
94 UInt8 first;
95 [message getBytes:&first length:1];
96 isSimpleValue = first != '{' && first != '[';
97 if (isSimpleValue) {
98 // NSJSONSerialization does not support top-level simple values.
99 // We expand encoding to singleton array, then decode that and extract
100 // the single entry.
101 UInt8 begin = '[';
102 UInt8 end = ']';
103 NSMutableData* expandedMessage = [NSMutableData dataWithLength:message.length + 2];
104 [expandedMessage replaceBytesInRange:NSMakeRange(0, 1) withBytes:&begin];
105 [expandedMessage replaceBytesInRange:NSMakeRange(1, message.length) withBytes:message.bytes];
106 [expandedMessage replaceBytesInRange:NSMakeRange(message.length + 1, 1) withBytes:&end];
107 message = expandedMessage;
108 }
109 decoded = [NSJSONSerialization JSONObjectWithData:message options:0 error:&error];
110 }
111 NSAssert(decoded, @"Invalid JSON message, decoding failed: %@", error);
112 return isSimpleValue ? ((NSArray*)decoded)[0] : decoded;
113}
114@end
115
116@implementation FlutterJSONMethodCodec
117+ (instancetype)sharedInstance {
118 static id _sharedInstance = nil;
119 if (!_sharedInstance) {
120 _sharedInstance = [[FlutterJSONMethodCodec alloc] init];
121 }
122 return _sharedInstance;
123}
124
125- (NSData*)encodeMethodCall:(FlutterMethodCall*)call {
126 return [[FlutterJSONMessageCodec sharedInstance] encode:@{
127 @"method" : call.method,
128 @"args" : [self wrapNil:call.arguments],
129 }];
130}
131
132- (NSData*)encodeSuccessEnvelope:(id)result {
133 return [[FlutterJSONMessageCodec sharedInstance] encode:@[ [self wrapNil:result] ]];
134}
135
136- (NSData*)encodeErrorEnvelope:(FlutterError*)error {
137 return [[FlutterJSONMessageCodec sharedInstance] encode:@[
138 error.code,
139 [self wrapNil:error.message],
140 [self wrapNil:error.details],
141 ]];
142}
143
144- (FlutterMethodCall*)decodeMethodCall:(NSData*)message {
145 NSDictionary* dictionary = [[FlutterJSONMessageCodec sharedInstance] decode:message];
146 id method = dictionary[@"method"];
147 id arguments = [self unwrapNil:dictionary[@"args"]];
148 NSAssert([method isKindOfClass:[NSString class]], @"Invalid JSON method call");
149 return [FlutterMethodCall methodCallWithMethodName:method arguments:arguments];
150}
151
152- (id)decodeEnvelope:(NSData*)envelope {
153 NSArray* array = [[FlutterJSONMessageCodec sharedInstance] decode:envelope];
154 if (array.count == 1) {
155 return [self unwrapNil:array[0]];
156 }
157 NSAssert(array.count == 3, @"Invalid JSON envelope");
158 id code = array[0];
159 id message = [self unwrapNil:array[1]];
160 id details = [self unwrapNil:array[2]];
161 NSAssert([code isKindOfClass:[NSString class]], @"Invalid JSON envelope");
162 NSAssert(message == nil || [message isKindOfClass:[NSString class]], @"Invalid JSON envelope");
163 return [FlutterError errorWithCode:code message:message details:details];
164}
165
166- (id)wrapNil:(id)value {
167 return value == nil ? [NSNull null] : value;
168}
169- (id)unwrapNil:(id)value {
170 return value == [NSNull null] ? nil : value;
171}
172@end
static void encode(uint8_t output[16], const uint32_t input[4])
Definition: SkMD5.cpp:240
static const char * begin(const StringSlice &s)
Definition: editor.cpp:252
glong glong end
const uint8_t uint32_t uint32_t GError ** error
uint8_t value
instancetype sharedInstance()
instancetype errorWithCode:message:details:(NSString *code,[message] NSString *_Nullable message,[details] id _Nullable details)
instancetype sharedInstance()
instancetype sharedInstance()
instancetype methodCallWithMethodName:arguments:(NSString *method,[arguments] id _Nullable arguments)
instancetype sharedInstance()
size_t length
Win32Message message
static DecodeResult decode(std::string path)
Definition: png_codec.cpp:124
const uintptr_t id
int BOOL
Definition: windows_types.h:37