66
77#pragma mark - Codec for basic message channel
88
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+
920@implementation FlutterStandardMessageCodec {
1021 FlutterStandardReaderWriter* _readerWriter;
1122}
@@ -221,115 +232,142 @@ - (void)dealloc {
221232 [super dealloc ];
222233}
223234
224- - ( void ) writeByte : ( UInt8) value {
225- [_data appendBytes: &value length: 1 ] ;
235+ static void WriteByte (CFMutableDataRef data, UInt8 value) {
236+ CFDataAppendBytes (data, &value, 1 ) ;
226237}
227238
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) ;
230241}
231242
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 ) ;
234245}
235246
236- - ( void ) writeSize : ( UInt32) size {
247+ static void WriteSize (CFMutableDataRef data, UInt32 size) {
237248 if (size < 254 ) {
238- [ self writeByte: (UInt8)size] ;
249+ WriteByte (data, (UInt8)size) ;
239250 } else if (size <= 0xffff ) {
240- [ self writeByte: 254 ] ;
251+ WriteByte (data, 254 ) ;
241252 UInt16 value = (UInt16)size;
242- [ self writeBytes: &value length: 2 ] ;
253+ WriteBytes (data, &value, 2 ) ;
243254 } else {
244- [ self writeByte: 255 ] ;
245- [ self writeBytes: &size length: 4 ] ;
255+ WriteByte (data, 255 ) ;
256+ WriteBytes (data, &size, 4 ) ;
246257 }
247258}
248259
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;
251263 if (mod) {
252- for (int i = 0 ; i < (alignment - mod); i++) {
253- [self writeByte: 0 ];
254- }
264+ WriteBytes (data, kZeroBuffer , alignment - mod);
255265 }
256266}
257267
258- - ( void ) writeUTF8 : ( NSString *) value {
268+ static void WriteUTF8 (CFMutableDataRef data, NSString * value) {
259269 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) ;
262272}
263273
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 ]) {
268278 CFNumberRef number = (CFNumberRef)value;
269279 BOOL success = NO ;
270280 if (CFGetTypeID (number) == CFBooleanGetTypeID ()) {
271281 BOOL b = CFBooleanGetValue ((CFBooleanRef)number);
272- [ self writeByte: (b ? FlutterStandardFieldTrue : FlutterStandardFieldFalse)] ;
282+ WriteByte (data, (b ? FlutterStandardFieldTrue : FlutterStandardFieldFalse)) ;
273283 success = YES ;
274284 } else if (CFNumberIsFloatType (number)) {
275285 Float64 f;
276286 success = CFNumberGetValue (number, kCFNumberFloat64Type , &f);
277287 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 ) ;
281291 }
282292 } else if (CFNumberGetByteSize (number) <= 4 ) {
283293 SInt32 n;
284294 success = CFNumberGetValue (number, kCFNumberSInt32Type , &n);
285295 if (success) {
286- [ self writeByte: FlutterStandardFieldInt32] ;
287- [ self writeBytes: (UInt8*)&n length: 4 ] ;
296+ WriteByte (data, FlutterStandardFieldInt32) ;
297+ WriteBytes (data, (UInt8*)&n, 4 ) ;
288298 }
289299 } else if (CFNumberGetByteSize (number) <= 8 ) {
290300 SInt64 n;
291301 success = CFNumberGetValue (number, kCFNumberSInt64Type , &n);
292302 if (success) {
293- [ self writeByte: FlutterStandardFieldInt64] ;
294- [ self writeBytes: (UInt8*)&n length: 8 ] ;
303+ WriteByte (data, FlutterStandardFieldInt64) ;
304+ WriteBytes (data, (UInt8*)&n, 8 ) ;
295305 }
296306 }
297307 if (!success) {
298308 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. " );
300310 }
301- } else if ([value isKindOfClass: [ NSString class ] ]) {
311+ } else if ([value isKindOfClass: kNSStringClass ]) {
302312 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 ]) {
306316 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 ]) {
314324 NSArray * array = value;
315- [ self writeByte: FlutterStandardFieldList] ;
316- [ self writeSize: array.count] ;
325+ WriteByte (data, FlutterStandardFieldList) ;
326+ WriteSize (data, array.count ) ;
317327 for (id object in array) {
318- [ self writeValue: object] ;
328+ WriteValue (data, object) ;
319329 }
320- } else if ([value isKindOfClass: [ NSDictionary class ] ]) {
330+ } else if ([value isKindOfClass: kNSDictionaryClass ]) {
321331 NSDictionary * dict = value;
322- [ self writeByte: FlutterStandardFieldMap] ;
323- [ self writeSize: dict.count] ;
332+ WriteByte (data, FlutterStandardFieldMap) ;
333+ WriteSize (data, dict.count ) ;
324334 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]) ;
327337 }
328338 } else {
329339 NSLog (@" Unsupported value: %@ of type %@ " , value, [value class ]);
330- NSAssert (NO , @" Unsupported value for standard codec" );
340+ NSCAssert (NO , @" Unsupported value for standard codec. " );
331341 }
332342}
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+ }
333371@end
334372
335373@implementation FlutterStandardReader {
@@ -450,7 +488,7 @@ - (nullable id)readValueOfType:(UInt8)type {
450488 NSMutableArray * array = [NSMutableArray arrayWithCapacity: length];
451489 for (UInt32 i = 0 ; i < length; i++) {
452490 id value = [self readValue ];
453- [array addObject: (value == nil ? [ NSNull null ] : value)];
491+ [array addObject: (value == nil ? kNSNull : value)];
454492 }
455493 return array;
456494 }
@@ -460,8 +498,7 @@ - (nullable id)readValueOfType:(UInt8)type {
460498 for (UInt32 i = 0 ; i < size; i++) {
461499 id key = [self readValue ];
462500 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)];
465502 }
466503 return dict;
467504 }
0 commit comments