Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
FlutterStandardCodecHelper.cc
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#include "flutter/shell/platform/darwin/common/framework/Source/FlutterStandardCodecHelper.h"
6#include <stdint.h>
7
8#include <vector>
9
10#include "flutter/fml/logging.h"
11
12// The google-runtime-int lint suggests uint64_t in place of unsigned long,
13// however these functions are frequently used with NSUInteger, which is
14// defined as an unsigned long.
15//
16// NOLINTBEGIN(google-runtime-int)
17
18void FlutterStandardCodecHelperReadAlignment(unsigned long* location,
19 uint8_t alignment) {
20 uint8_t mod = *location % alignment;
21 if (mod) {
22 *location += (alignment - mod);
23 }
24}
25
26static uint8_t PeekByte(unsigned long location, CFDataRef data) {
27 uint8_t result;
28 CFRange range = CFRangeMake(location, 1);
29 CFDataGetBytes(data, range, &result);
30 return result;
31}
32
33void FlutterStandardCodecHelperReadBytes(unsigned long* location,
34 unsigned long length,
35 void* destination,
36 CFDataRef data) {
37 CFRange range = CFRangeMake(*location, length);
38 CFDataGetBytes(data, range, static_cast<UInt8*>(destination));
39 *location += length;
40}
41
42uint8_t FlutterStandardCodecHelperReadByte(unsigned long* location,
43 CFDataRef data) {
44 uint8_t value;
45 FlutterStandardCodecHelperReadBytes(location, 1, &value, data);
46 return value;
47}
48
49uint32_t FlutterStandardCodecHelperReadSize(unsigned long* location,
50 CFDataRef data) {
51 uint8_t byte = FlutterStandardCodecHelperReadByte(location, data);
52 if (byte < 254) {
53 return (uint32_t)byte;
54 } else if (byte == 254) {
55 UInt16 value;
56 FlutterStandardCodecHelperReadBytes(location, 2, &value, data);
57 return value;
58 } else {
59 UInt32 value;
60 FlutterStandardCodecHelperReadBytes(location, 4, &value, data);
61 return value;
62 }
63}
64
65static CFDataRef ReadDataNoCopy(unsigned long* location,
66 unsigned long length,
67 CFDataRef data) {
68 CFDataRef result = CFDataCreateWithBytesNoCopy(
69 kCFAllocatorDefault, CFDataGetBytePtr(data) + *location, length,
70 kCFAllocatorNull);
71 *location += length;
72 return static_cast<CFDataRef>(CFAutorelease(result));
73}
74
75CFStringRef FlutterStandardCodecHelperReadUTF8(unsigned long* location,
76 CFDataRef data) {
77 uint32_t size = FlutterStandardCodecHelperReadSize(location, data);
78 CFDataRef bytes = ReadDataNoCopy(location, size, data);
79 CFStringRef result = CFStringCreateFromExternalRepresentation(
80 kCFAllocatorDefault, bytes, kCFStringEncodingUTF8);
81 return static_cast<CFStringRef>(CFAutorelease(result));
82}
83
84// Peeks ahead to see if we are reading a standard type. If so, recurse
85// directly to FlutterStandardCodecHelperReadValueOfType, otherwise recurse to
86// objc.
87static inline CFTypeRef FastReadValue(
88 unsigned long* location,
89 CFDataRef data,
90 CFTypeRef (*ReadValue)(CFTypeRef),
91 CFTypeRef (*ReadTypedDataOfType)(FlutterStandardField, CFTypeRef),
92 CFTypeRef user_data) {
93 uint8_t type = PeekByte(*location, data);
95 *location += 1;
97 location, data, type, ReadValue, ReadTypedDataOfType, user_data);
98 } else {
99 return ReadValue(user_data);
100 }
101}
102
104 unsigned long* location,
105 CFDataRef data,
106 uint8_t type,
107 CFTypeRef (*ReadValue)(CFTypeRef),
108 CFTypeRef (*ReadTypedDataOfType)(FlutterStandardField, CFTypeRef),
109 CFTypeRef user_data) {
111 switch (field) {
113 return nil;
115 return kCFBooleanTrue;
117 return kCFBooleanFalse;
119 int32_t value;
120 FlutterStandardCodecHelperReadBytes(location, 4, &value, data);
121 return CFAutorelease(
122 CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &value));
123 }
125 int64_t value;
126 FlutterStandardCodecHelperReadBytes(location, 8, &value, data);
127 return CFAutorelease(
128 CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &value));
129 }
131 Float64 value;
133 FlutterStandardCodecHelperReadBytes(location, 8, &value, data);
134 return CFAutorelease(
135 CFNumberCreate(kCFAllocatorDefault, kCFNumberDoubleType, &value));
136 }
139 return FlutterStandardCodecHelperReadUTF8(location, data);
145 return ReadTypedDataOfType(field, user_data);
147 UInt32 length = FlutterStandardCodecHelperReadSize(location, data);
148 CFMutableArrayRef array = CFArrayCreateMutable(
149 kCFAllocatorDefault, length, &kCFTypeArrayCallBacks);
150 for (UInt32 i = 0; i < length; i++) {
151 CFTypeRef value = FastReadValue(location, data, ReadValue,
152 ReadTypedDataOfType, user_data);
153 CFArrayAppendValue(array, (value == nil ? kCFNull : value));
154 }
155 return CFAutorelease(array);
156 }
158 UInt32 size = FlutterStandardCodecHelperReadSize(location, data);
159 CFMutableDictionaryRef dict = CFDictionaryCreateMutable(
160 kCFAllocatorDefault, size, &kCFTypeDictionaryKeyCallBacks,
161 &kCFTypeDictionaryValueCallBacks);
162 for (UInt32 i = 0; i < size; i++) {
163 CFTypeRef key = FastReadValue(location, data, ReadValue,
164 ReadTypedDataOfType, user_data);
165 CFTypeRef val = FastReadValue(location, data, ReadValue,
166 ReadTypedDataOfType, user_data);
167 CFDictionaryAddValue(dict, (key == nil ? kCFNull : key),
168 (val == nil ? kCFNull : val));
169 }
170 return CFAutorelease(dict);
171 }
172 default:
173 // Malformed message.
174 FML_DCHECK(false);
175 }
176}
177
178void FlutterStandardCodecHelperWriteByte(CFMutableDataRef data, uint8_t value) {
179 CFDataAppendBytes(data, &value, 1);
180}
181
182void FlutterStandardCodecHelperWriteBytes(CFMutableDataRef data,
183 const void* bytes,
184 unsigned long length) {
185 CFDataAppendBytes(data, static_cast<const UInt8*>(bytes), length);
186}
187
188void FlutterStandardCodecHelperWriteSize(CFMutableDataRef data, uint32_t size) {
189 if (size < 254) {
191 } else if (size <= 0xffff) {
193 UInt16 value = (UInt16)size;
195 } else {
198 }
199}
200
202 uint8_t alignment) {
203 uint8_t mod = CFDataGetLength(data) % alignment;
204 if (mod) {
205 for (int i = 0; i < (alignment - mod); i++) {
207 }
208 }
209}
210
211void FlutterStandardCodecHelperWriteUTF8(CFMutableDataRef data,
212 CFStringRef value) {
213 const char* utf8 = CFStringGetCStringPtr(value, kCFStringEncodingUTF8);
214 if (utf8) {
215 size_t length = strlen(utf8);
218 } else {
219 CFIndex length = CFStringGetLength(value);
220 CFIndex used_length = 0;
221 // UTF16 length times 3 will fit all UTF8.
222 CFIndex buffer_length = length * 3;
223 std::vector<UInt8> buffer;
224 buffer.resize(buffer_length);
225 CFStringGetBytes(value, CFRangeMake(0, length), kCFStringEncodingUTF8, 0,
226 false, buffer.data(), buffer_length, &used_length);
227 FlutterStandardCodecHelperWriteSize(data, used_length);
228 FlutterStandardCodecHelperWriteBytes(data, buffer.data(), used_length);
229 }
230}
231
232void FlutterStandardCodecHelperWriteData(CFMutableDataRef data,
233 CFDataRef value) {
234 const UInt8* bytes = CFDataGetBytePtr(value);
235 CFIndex length = CFDataGetLength(value);
237}
238
239bool FlutterStandardCodecHelperWriteNumber(CFMutableDataRef data,
240 CFNumberRef number) {
241 bool success = false;
242 if (CFGetTypeID(number) == CFBooleanGetTypeID()) {
243 bool b = CFBooleanGetValue((CFBooleanRef)number);
246 success = true;
247 } else if (CFNumberIsFloatType(number)) {
248 Float64 f;
249 success = CFNumberGetValue(number, kCFNumberFloat64Type, &f);
250 if (success) {
254 }
255 } else if (CFNumberGetByteSize(number) <= 4) {
256 SInt32 n;
257 success = CFNumberGetValue(number, kCFNumberSInt32Type, &n);
258 if (success) {
261 }
262 } else if (CFNumberGetByteSize(number) <= 8) {
263 SInt64 n;
264 success = CFNumberGetValue(number, kCFNumberSInt64Type, &n);
265 if (success) {
268 }
269 }
270 return success;
271}
272
273// NOLINTEND(google-runtime-int)
static uint8_t PeekByte(unsigned long location, CFDataRef data)
CFTypeRef FlutterStandardCodecHelperReadValueOfType(unsigned long *location, CFDataRef data, uint8_t type, CFTypeRef(*ReadValue)(CFTypeRef), CFTypeRef(*ReadTypedDataOfType)(FlutterStandardField, CFTypeRef), CFTypeRef user_data)
bool FlutterStandardCodecHelperWriteNumber(CFMutableDataRef data, CFNumberRef number)
void FlutterStandardCodecHelperWriteData(CFMutableDataRef data, CFDataRef value)
uint8_t FlutterStandardCodecHelperReadByte(unsigned long *location, CFDataRef data)
void FlutterStandardCodecHelperWriteSize(CFMutableDataRef data, uint32_t size)
CFStringRef FlutterStandardCodecHelperReadUTF8(unsigned long *location, CFDataRef data)
void FlutterStandardCodecHelperWriteBytes(CFMutableDataRef data, const void *bytes, unsigned long length)
void FlutterStandardCodecHelperWriteUTF8(CFMutableDataRef data, CFStringRef value)
void FlutterStandardCodecHelperWriteByte(CFMutableDataRef data, uint8_t value)
uint32_t FlutterStandardCodecHelperReadSize(unsigned long *location, CFDataRef data)
void FlutterStandardCodecHelperReadAlignment(unsigned long *location, uint8_t alignment)
static CFTypeRef FastReadValue(unsigned long *location, CFDataRef data, CFTypeRef(*ReadValue)(CFTypeRef), CFTypeRef(*ReadTypedDataOfType)(FlutterStandardField, CFTypeRef), CFTypeRef user_data)
void FlutterStandardCodecHelperWriteAlignment(CFMutableDataRef data, uint8_t alignment)
static CFDataRef ReadDataNoCopy(unsigned long *location, unsigned long length, CFDataRef data)
void FlutterStandardCodecHelperReadBytes(unsigned long *location, unsigned long length, void *destination, CFDataRef data)
@ FlutterStandardFieldUInt8Data
@ FlutterStandardFieldFloat64
@ FlutterStandardFieldFloat32Data
@ FlutterStandardFieldIntHex
@ FlutterStandardFieldMap
@ FlutterStandardFieldInt64Data
@ FlutterStandardFieldList
@ FlutterStandardFieldInt32
@ FlutterStandardFieldNil
@ FlutterStandardFieldTrue
@ FlutterStandardFieldString
@ FlutterStandardFieldFalse
@ FlutterStandardFieldInt32Data
@ FlutterStandardFieldInt64
@ FlutterStandardFieldFloat64Data
static bool FlutterStandardFieldIsStandardType(uint8_t field)
static bool b
static const uint8_t buffer[]
uint8_t value
GAsyncResult * result
#define FML_DCHECK(condition)
Definition logging.h:103
size_t length