@@ -211,114 +211,144 @@ - (instancetype)initWithData:(NSMutableData*)data {
211
211
}
212
212
213
213
- (void )writeByte : (UInt8 )value {
214
- [ _data appendBytes: & value length: 1 ] ;
214
+ FlutterStandardCodecHelperWriteByte ((__bridge CFMutableDataRef ) _data, value) ;
215
215
}
216
216
217
217
- (void )writeBytes : (const void *)bytes length : (NSUInteger )length {
218
- [ _data appendBytes: bytes length: length] ;
218
+ FlutterStandardCodecHelperWriteBytes ((__bridge CFMutableDataRef ) _data, bytes, length) ;
219
219
}
220
220
221
221
- (void )writeData : (NSData *)data {
222
- [ _data appendData: data] ;
222
+ FlutterStandardCodecHelperWriteData ((__bridge CFMutableDataRef ) _data, (__bridge CFDataRef ) data) ;
223
223
}
224
224
225
225
- (void )writeSize : (UInt32 )size {
226
- if (size < 254 ) {
227
- [self writeByte: (UInt8 )size];
228
- } else if (size <= 0xffff ) {
229
- [self writeByte: 254 ];
230
- UInt16 value = (UInt16 )size;
231
- [self writeBytes: &value length: 2 ];
232
- } else {
233
- [self writeByte: 255 ];
234
- [self writeBytes: &size length: 4 ];
235
- }
226
+ FlutterStandardCodecHelperWriteSize ((__bridge CFMutableDataRef )_data, size);
236
227
}
237
228
238
229
- (void )writeAlignment : (UInt8 )alignment {
239
- UInt8 mod = _data.length % alignment;
240
- if (mod) {
241
- for (int i = 0 ; i < (alignment - mod); i++) {
242
- [self writeByte: 0 ];
243
- }
244
- }
230
+ FlutterStandardCodecHelperWriteAlignment ((__bridge CFMutableDataRef )_data, alignment);
245
231
}
246
232
247
233
- (void )writeUTF8 : (NSString *)value {
248
- UInt32 length = [value lengthOfBytesUsingEncoding: NSUTF8StringEncoding];
249
- [self writeSize: length];
250
- [self writeBytes: value.UTF8String length: length];
234
+ FlutterStandardCodecHelperWriteUTF8 ((__bridge CFMutableDataRef )_data,
235
+ (__bridge CFStringRef )value);
251
236
}
252
237
253
- - ( void ) writeValue : ( id ) value {
254
- if (value == nil || value == [ NSNull null ] ) {
255
- [ self writeByte: FlutterStandardFieldNil] ;
238
+ static FlutterStandardCodecObjcType GetWriteType ( id value) {
239
+ if (value == nil || (__bridge CFNullRef ) value == kCFNull ) {
240
+ return FlutterStandardCodecObjcTypeNil ;
256
241
} else if ([value isKindOfClass: [NSNumber class ]]) {
257
- CFNumberRef number = (__bridge CFNumberRef )value;
258
- BOOL success = NO ;
259
- if (CFGetTypeID (number) == CFBooleanGetTypeID ()) {
260
- BOOL b = CFBooleanGetValue ((CFBooleanRef )number);
261
- [self writeByte: (b ? FlutterStandardFieldTrue : FlutterStandardFieldFalse)];
262
- success = YES ;
263
- } else if (CFNumberIsFloatType (number)) {
264
- Float64 f;
265
- success = CFNumberGetValue (number, kCFNumberFloat64Type , &f);
266
- if (success) {
267
- [self writeByte: FlutterStandardFieldFloat64];
268
- [self writeAlignment: 8 ];
269
- [self writeBytes: (UInt8 *)&f length: 8 ];
270
- }
271
- } else if (CFNumberGetByteSize (number) <= 4 ) {
272
- SInt32 n;
273
- success = CFNumberGetValue (number, kCFNumberSInt32Type , &n);
274
- if (success) {
275
- [self writeByte: FlutterStandardFieldInt32];
276
- [self writeBytes: (UInt8 *)&n length: 4 ];
277
- }
278
- } else if (CFNumberGetByteSize (number) <= 8 ) {
279
- SInt64 n;
280
- success = CFNumberGetValue (number, kCFNumberSInt64Type , &n);
281
- if (success) {
282
- [self writeByte: FlutterStandardFieldInt64];
283
- [self writeBytes: (UInt8 *)&n length: 8 ];
284
- }
285
- }
286
- if (!success) {
287
- NSLog (@" Unsupported value: %@ of number type %ld " , value, CFNumberGetType(number));
288
- NSAssert (NO , @" Unsupported value for standard codec" );
289
- }
242
+ return FlutterStandardCodecObjcTypeNSNumber;
290
243
} else if ([value isKindOfClass: [NSString class ]]) {
291
- NSString * string = value;
292
- [self writeByte: FlutterStandardFieldString];
293
- [self writeUTF8: string];
244
+ return FlutterStandardCodecObjcTypeNSString;
294
245
} else if ([value isKindOfClass: [FlutterStandardTypedData class ]]) {
295
- FlutterStandardTypedData* typedData = value;
296
- [self writeByte: FlutterStandardFieldForDataType (typedData.type)];
297
- [self writeSize: typedData.elementCount];
298
- [self writeAlignment: typedData.elementSize];
299
- [self writeData: typedData.data];
246
+ return FlutterStandardCodecObjcTypeFlutterStandardTypedData;
300
247
} else if ([value isKindOfClass: [NSData class ]]) {
301
- [ self writeValue: [FlutterStandardTypedData typedDataWithBytes: value]] ;
248
+ return FlutterStandardCodecObjcTypeNSData ;
302
249
} else if ([value isKindOfClass: [NSArray class ]]) {
303
- NSArray * array = value;
304
- [self writeByte: FlutterStandardFieldList];
305
- [self writeSize: array.count];
306
- for (id object in array) {
307
- [self writeValue: object];
308
- }
250
+ return FlutterStandardCodecObjcTypeNSArray;
309
251
} else if ([value isKindOfClass: [NSDictionary class ]]) {
310
- NSDictionary * dict = value;
311
- [self writeByte: FlutterStandardFieldMap];
312
- [self writeSize: dict.count];
313
- for (id key in dict) {
314
- [self writeValue: key];
315
- [self writeValue: [dict objectForKey: key]];
316
- }
252
+ return FlutterStandardCodecObjcTypeNSDictionary;
317
253
} else {
318
- NSLog (@" Unsupported value: %@ of type %@ " , value, [value class ]);
319
- NSAssert (NO , @" Unsupported value for standard codec" );
254
+ return FlutterStandardCodecObjcTypeUnknown;
320
255
}
321
256
}
257
+
258
+ struct WriteKeyValuesInfo {
259
+ CFTypeRef writer;
260
+ CFMutableDataRef data;
261
+ };
262
+
263
+ static void WriteKeyValues (CFTypeRef key, CFTypeRef value, void * context) {
264
+ WriteKeyValuesInfo* info = (WriteKeyValuesInfo*)context;
265
+ FastWriteValueOfType (info->writer , info->data , key);
266
+ FastWriteValueOfType (info->writer , info->data , value);
267
+ }
268
+
269
+ // Recurses into WriteValueOfType directly if it is writing a known type,
270
+ // otherwise recurses with objc_msgSend.
271
+ static void FastWriteValueOfType (CFTypeRef writer, CFMutableDataRef data, CFTypeRef value) {
272
+ FlutterStandardCodecObjcType type = GetWriteType ((__bridge id )value);
273
+ if (type != FlutterStandardCodecObjcTypeUnknown) {
274
+ WriteValueOfType (writer, data, type, value);
275
+ } else {
276
+ [(__bridge FlutterStandardWriter*)writer writeValue: (__bridge id )value];
277
+ }
278
+ }
279
+
280
+ static void WriteValueOfType (CFTypeRef writer,
281
+ CFMutableDataRef data,
282
+ FlutterStandardCodecObjcType type,
283
+ CFTypeRef value) {
284
+ switch (type) {
285
+ case FlutterStandardCodecObjcTypeNil:
286
+ FlutterStandardCodecHelperWriteByte (data, FlutterStandardFieldNil);
287
+ break ;
288
+ case FlutterStandardCodecObjcTypeNSNumber: {
289
+ CFNumberRef number = (CFNumberRef )value;
290
+ BOOL success = FlutterStandardCodecHelperWriteNumber (data, number);
291
+ if (!success) {
292
+ NSLog (@" Unsupported value: %@ of number type %ld " , value, CFNumberGetType(number));
293
+ NSCAssert (NO , @" Unsupported value for standard codec" );
294
+ }
295
+ break ;
296
+ }
297
+ case FlutterStandardCodecObjcTypeNSString: {
298
+ CFStringRef string = (CFStringRef )value;
299
+ FlutterStandardCodecHelperWriteByte (data, FlutterStandardFieldString);
300
+ FlutterStandardCodecHelperWriteUTF8 (data, string);
301
+ break ;
302
+ }
303
+ case FlutterStandardCodecObjcTypeFlutterStandardTypedData: {
304
+ FlutterStandardTypedData* typedData = (__bridge FlutterStandardTypedData*)value;
305
+ FlutterStandardCodecHelperWriteByte (data, FlutterStandardFieldForDataType (typedData.type ));
306
+ FlutterStandardCodecHelperWriteSize (data, typedData.elementCount );
307
+ FlutterStandardCodecHelperWriteAlignment (data, typedData.elementSize );
308
+ FlutterStandardCodecHelperWriteData (data, (__bridge CFDataRef )typedData.data );
309
+ break ;
310
+ }
311
+ case FlutterStandardCodecObjcTypeNSData:
312
+ WriteValueOfType (writer, data, FlutterStandardCodecObjcTypeFlutterStandardTypedData,
313
+ (__bridge CFTypeRef )
314
+ [FlutterStandardTypedData typedDataWithBytes: (__bridge NSData *)value]);
315
+ break ;
316
+ case FlutterStandardCodecObjcTypeNSArray: {
317
+ CFArrayRef array = (CFArrayRef )value;
318
+ FlutterStandardCodecHelperWriteByte (data, FlutterStandardFieldList);
319
+ CFIndex count = CFArrayGetCount (array);
320
+ FlutterStandardCodecHelperWriteSize (data, count);
321
+ for (CFIndex i = 0 ; i < count; ++i) {
322
+ FastWriteValueOfType (writer, data, CFArrayGetValueAtIndex (array, i));
323
+ }
324
+ break ;
325
+ }
326
+ case FlutterStandardCodecObjcTypeNSDictionary: {
327
+ CFDictionaryRef dict = (CFDictionaryRef )value;
328
+ FlutterStandardCodecHelperWriteByte (data, FlutterStandardFieldMap);
329
+ CFIndex count = CFDictionaryGetCount (dict);
330
+ FlutterStandardCodecHelperWriteSize (data, count);
331
+ WriteKeyValuesInfo info = {
332
+ .writer = writer,
333
+ .data = data,
334
+ };
335
+ CFDictionaryApplyFunction (dict, WriteKeyValues, (void *)&info);
336
+ break ;
337
+ }
338
+ case FlutterStandardCodecObjcTypeUnknown: {
339
+ id objc_value = (__bridge id )value;
340
+ NSLog (@" Unsupported value: %@ of type %@ " , objc_value, [objc_value class ]);
341
+ NSCAssert (NO , @" Unsupported value for standard codec" );
342
+ break ;
343
+ }
344
+ }
345
+ }
346
+
347
+ - (void )writeValue : (id )value {
348
+ FlutterStandardCodecObjcType type = GetWriteType (value);
349
+ WriteValueOfType ((__bridge CFTypeRef )self, (__bridge CFMutableDataRef )self->_data , type,
350
+ (__bridge CFTypeRef )value);
351
+ }
322
352
@end
323
353
324
354
@implementation FlutterStandardReader {
0 commit comments