6
6
7
7
#pragma mark - Codec for basic message channel
8
8
9
+ static const UInt8 kZeroBuffer [8 ] = {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
10
+ // Classes are cached in static variables to avoid the extra method calls in a
11
+ // highly traffic'd recursive function.
12
+ static const Class kNSNumberClass = [NSNumber class ];
13
+ static const id kNSNull = [NSNull null ];
14
+ static const Class kNSStringClass = [NSString class ];
15
+ static const Class kNSDataClass = [NSData class ];
16
+ static const Class kNSArrayClass = [NSArray class ];
17
+ static const Class kNSDictionaryClass = [NSDictionary class ];
18
+ static const Class kFlutterStandardTypedDataClass = [FlutterStandardTypedData class ];
19
+
9
20
@implementation FlutterStandardMessageCodec {
10
21
FlutterStandardReaderWriter* _readerWriter;
11
22
}
@@ -221,115 +232,142 @@ - (void)dealloc {
221
232
[super dealloc ];
222
233
}
223
234
224
- - ( void ) writeByte : ( UInt8) value {
225
- [_data appendBytes: &value length: 1 ] ;
235
+ static void WriteByte (CFMutableDataRef data, UInt8 value) {
236
+ CFDataAppendBytes (data, &value, 1 ) ;
226
237
}
227
238
228
- - ( void ) writeBytes : ( const void *) bytes length : ( NSUInteger ) length {
229
- [_data appendBytes: bytes length: length] ;
239
+ static void WriteBytes (CFMutableDataRef data, const void * bytes, NSUInteger length) {
240
+ CFDataAppendBytes (data, ( const UInt8*) bytes, length) ;
230
241
}
231
242
232
- - ( void ) writeData : ( NSData *) data {
233
- [_data appendData: data] ;
243
+ static void WriteData (CFMutableDataRef destination, NSData * source) {
244
+ CFDataAppendBytes (destination, ( const UInt8*)source. bytes , source. length ) ;
234
245
}
235
246
236
- - ( void ) writeSize : ( UInt32) size {
247
+ static void WriteSize (CFMutableDataRef data, UInt32 size) {
237
248
if (size < 254 ) {
238
- [ self writeByte: (UInt8)size] ;
249
+ WriteByte (data, (UInt8)size) ;
239
250
} else if (size <= 0xffff ) {
240
- [ self writeByte: 254 ] ;
251
+ WriteByte (data, 254 ) ;
241
252
UInt16 value = (UInt16)size;
242
- [ self writeBytes: &value length: 2 ] ;
253
+ WriteBytes (data, &value, 2 ) ;
243
254
} else {
244
- [ self writeByte: 255 ] ;
245
- [ self writeBytes: &size length: 4 ] ;
255
+ WriteByte (data, 255 ) ;
256
+ WriteBytes (data, &size, 4 ) ;
246
257
}
247
258
}
248
259
249
- - (void )writeAlignment : (UInt8)alignment {
250
- UInt8 mod = _data.length % alignment;
260
+ static void WriteAlignment (CFMutableDataRef data, UInt8 alignment) {
261
+ NSCAssert (alignment <= 8 , @" Alignment larger than kZeroBuffer." );
262
+ UInt8 mod = CFDataGetLength (data) % alignment;
251
263
if (mod) {
252
- for (int i = 0 ; i < (alignment - mod); i++) {
253
- [self writeByte: 0 ];
254
- }
264
+ WriteBytes (data, kZeroBuffer , alignment - mod);
255
265
}
256
266
}
257
267
258
- - ( void ) writeUTF8 : ( NSString *) value {
268
+ static void WriteUTF8 (CFMutableDataRef data, NSString * value) {
259
269
UInt32 length = [value lengthOfBytesUsingEncoding: NSUTF8StringEncoding];
260
- [ self writeSize: length] ;
261
- [ self writeBytes: value.UTF8String length: length] ;
270
+ WriteSize (data, length) ;
271
+ WriteBytes (data, value.UTF8String , length) ;
262
272
}
263
273
264
- - ( void ) writeValue : ( id ) value {
265
- if (value == nil || value == [ NSNull null ] ) {
266
- [ self writeByte: FlutterStandardFieldNil] ;
267
- } else if ([value isKindOfClass: [ NSNumber class ] ]) {
274
+ static void WriteValue (CFMutableDataRef data, id value) {
275
+ if (value == nil || value == kNSNull ) {
276
+ WriteByte (data, FlutterStandardFieldNil) ;
277
+ } else if ([value isKindOfClass: kNSNumberClass ]) {
268
278
CFNumberRef number = (CFNumberRef)value;
269
279
BOOL success = NO ;
270
280
if (CFGetTypeID (number) == CFBooleanGetTypeID ()) {
271
281
BOOL b = CFBooleanGetValue ((CFBooleanRef)number);
272
- [ self writeByte: (b ? FlutterStandardFieldTrue : FlutterStandardFieldFalse)] ;
282
+ WriteByte (data, (b ? FlutterStandardFieldTrue : FlutterStandardFieldFalse)) ;
273
283
success = YES ;
274
284
} else if (CFNumberIsFloatType (number)) {
275
285
Float64 f;
276
286
success = CFNumberGetValue (number, kCFNumberFloat64Type , &f);
277
287
if (success) {
278
- [ self writeByte: FlutterStandardFieldFloat64] ;
279
- [ self writeAlignment: 8 ] ;
280
- [ self writeBytes: (UInt8*)&f length: 8 ] ;
288
+ WriteByte (data, FlutterStandardFieldFloat64) ;
289
+ WriteAlignment (data, 8 ) ;
290
+ WriteBytes (data, (UInt8*)&f, 8 ) ;
281
291
}
282
292
} else if (CFNumberGetByteSize (number) <= 4 ) {
283
293
SInt32 n;
284
294
success = CFNumberGetValue (number, kCFNumberSInt32Type , &n);
285
295
if (success) {
286
- [ self writeByte: FlutterStandardFieldInt32] ;
287
- [ self writeBytes: (UInt8*)&n length: 4 ] ;
296
+ WriteByte (data, FlutterStandardFieldInt32) ;
297
+ WriteBytes (data, (UInt8*)&n, 4 ) ;
288
298
}
289
299
} else if (CFNumberGetByteSize (number) <= 8 ) {
290
300
SInt64 n;
291
301
success = CFNumberGetValue (number, kCFNumberSInt64Type , &n);
292
302
if (success) {
293
- [ self writeByte: FlutterStandardFieldInt64] ;
294
- [ self writeBytes: (UInt8*)&n length: 8 ] ;
303
+ WriteByte (data, FlutterStandardFieldInt64) ;
304
+ WriteBytes (data, (UInt8*)&n, 8 ) ;
295
305
}
296
306
}
297
307
if (!success) {
298
308
NSLog (@" Unsupported value: %@ of number type %ld " , value, CFNumberGetType(number));
299
- NSAssert (NO , @" Unsupported value for standard codec" );
309
+ NSCAssert (NO , @" Unsupported value for standard codec. " );
300
310
}
301
- } else if ([value isKindOfClass: [ NSString class ] ]) {
311
+ } else if ([value isKindOfClass: kNSStringClass ]) {
302
312
NSString * string = value;
303
- [ self writeByte: FlutterStandardFieldString] ;
304
- [ self writeUTF8: string] ;
305
- } else if ([value isKindOfClass: [FlutterStandardTypedData class ] ]) {
313
+ WriteByte (data, FlutterStandardFieldString) ;
314
+ WriteUTF8 (data, string) ;
315
+ } else if ([value isKindOfClass: kFlutterStandardTypedDataClass ]) {
306
316
FlutterStandardTypedData* typedData = value;
307
- [ self writeByte: FlutterStandardFieldForDataType (typedData.type)] ;
308
- [ self writeSize: typedData.elementCount] ;
309
- [ self writeAlignment: typedData.elementSize] ;
310
- [ self writeData: typedData.data] ;
311
- } else if ([value isKindOfClass: [ NSData class ] ]) {
312
- [ self writeValue: [FlutterStandardTypedData typedDataWithBytes: value]] ;
313
- } else if ([value isKindOfClass: [ NSArray class ] ]) {
317
+ WriteByte (data, FlutterStandardFieldForDataType (typedData.type )) ;
318
+ WriteSize (data, typedData.elementCount ) ;
319
+ WriteAlignment (data, typedData.elementSize ) ;
320
+ WriteData (data, typedData.data ) ;
321
+ } else if ([value isKindOfClass: kNSDataClass ]) {
322
+ WriteValue (data, [FlutterStandardTypedData typedDataWithBytes: value]) ;
323
+ } else if ([value isKindOfClass: kNSArrayClass ]) {
314
324
NSArray * array = value;
315
- [ self writeByte: FlutterStandardFieldList] ;
316
- [ self writeSize: array.count] ;
325
+ WriteByte (data, FlutterStandardFieldList) ;
326
+ WriteSize (data, array.count ) ;
317
327
for (id object in array) {
318
- [ self writeValue: object] ;
328
+ WriteValue (data, object) ;
319
329
}
320
- } else if ([value isKindOfClass: [ NSDictionary class ] ]) {
330
+ } else if ([value isKindOfClass: kNSDictionaryClass ]) {
321
331
NSDictionary * dict = value;
322
- [ self writeByte: FlutterStandardFieldMap] ;
323
- [ self writeSize: dict.count] ;
332
+ WriteByte (data, FlutterStandardFieldMap) ;
333
+ WriteSize (data, dict.count ) ;
324
334
for (id key in dict) {
325
- [ self writeValue: key] ;
326
- [ self writeValue: [dict objectForKey: key]] ;
335
+ WriteValue (data, key) ;
336
+ WriteValue (data, [dict objectForKey: key]) ;
327
337
}
328
338
} else {
329
339
NSLog (@" Unsupported value: %@ of type %@ " , value, [value class ]);
330
- NSAssert (NO , @" Unsupported value for standard codec" );
340
+ NSCAssert (NO , @" Unsupported value for standard codec. " );
331
341
}
332
342
}
343
+
344
+ - (void )writeByte : (UInt8)value {
345
+ WriteByte ((__bridge CFMutableDataRef)_data, value);
346
+ }
347
+
348
+ - (void )writeBytes : (const void *)bytes length : (NSUInteger )length {
349
+ WriteBytes ((__bridge CFMutableDataRef)_data, bytes, length);
350
+ }
351
+
352
+ - (void )writeData : (NSData *)data {
353
+ WriteData ((__bridge CFMutableDataRef)_data, data);
354
+ }
355
+
356
+ - (void )writeSize : (UInt32)size {
357
+ WriteSize ((__bridge CFMutableDataRef)_data, size);
358
+ }
359
+
360
+ - (void )writeAlignment : (UInt8)alignment {
361
+ WriteAlignment ((__bridge CFMutableDataRef)_data, alignment);
362
+ }
363
+
364
+ - (void )writeUTF8 : (NSString *)value {
365
+ WriteUTF8 ((__bridge CFMutableDataRef)_data, value);
366
+ }
367
+
368
+ - (void )writeValue : (id )value {
369
+ WriteValue ((__bridge CFMutableDataRef)_data, value);
370
+ }
333
371
@end
334
372
335
373
@implementation FlutterStandardReader {
@@ -450,7 +488,7 @@ - (nullable id)readValueOfType:(UInt8)type {
450
488
NSMutableArray * array = [NSMutableArray arrayWithCapacity: length];
451
489
for (UInt32 i = 0 ; i < length; i++) {
452
490
id value = [self readValue ];
453
- [array addObject: (value == nil ? [ NSNull null ] : value)];
491
+ [array addObject: (value == nil ? kNSNull : value)];
454
492
}
455
493
return array;
456
494
}
@@ -460,8 +498,7 @@ - (nullable id)readValueOfType:(UInt8)type {
460
498
for (UInt32 i = 0 ; i < size; i++) {
461
499
id key = [self readValue ];
462
500
id val = [self readValue ];
463
- [dict setObject: (val == nil ? [NSNull null ] : val)
464
- forKey: (key == nil ? [NSNull null ] : key)];
501
+ [dict setObject: (val == nil ? kNSNull : val) forKey: (key == nil ? kNSNull : key)];
465
502
}
466
503
return dict;
467
504
}
0 commit comments