Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 09638ac

Browse files
committed
faster codec
1 parent 3430bf9 commit 09638ac

File tree

1 file changed

+92
-56
lines changed

1 file changed

+92
-56
lines changed

shell/platform/darwin/common/framework/Source/FlutterStandardCodec.mm

Lines changed: 92 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,15 @@
66

77
#pragma mark - Codec for basic message channel
88

9+
static const UInt8 s_zeroBuffer[8] = {0, 0, 0, 0, 0, 0, 0, 0};
10+
static const Class s_nsNumber = [NSNumber class];
11+
static const id s_nsNull = [NSNull null];
12+
static const Class s_nsString = [NSString class];
13+
static const Class s_nsData = [NSData class];
14+
static const Class s_nsArray = [NSArray class];
15+
static const Class s_nsDictionary = [NSDictionary class];
16+
static const Class s_flutterStandardTypedData = [FlutterStandardTypedData class];
17+
918
@implementation FlutterStandardMessageCodec {
1019
FlutterStandardReaderWriter* _readerWriter;
1120
}
@@ -221,115 +230,142 @@ - (void)dealloc {
221230
[super dealloc];
222231
}
223232

224-
- (void)writeByte:(UInt8)value {
225-
[_data appendBytes:&value length:1];
233+
static void WriteByte(CFMutableDataRef data, UInt8 value) {
234+
CFDataAppendBytes(data, &value, 1);
226235
}
227236

228-
- (void)writeBytes:(const void*)bytes length:(NSUInteger)length {
229-
[_data appendBytes:bytes length:length];
237+
static void WriteBytes(CFMutableDataRef data, const void* bytes, NSUInteger length) {
238+
CFDataAppendBytes(data, (const UInt8*)bytes, length);
230239
}
231240

232-
- (void)writeData:(NSData*)data {
233-
[_data appendData:data];
241+
static void WriteData(CFMutableDataRef destination, NSData* source) {
242+
CFDataAppendBytes(destination, (const UInt8*)source.bytes, source.length);
234243
}
235244

236-
- (void)writeSize:(UInt32)size {
245+
static void WriteSize(CFMutableDataRef data, UInt32 size) {
237246
if (size < 254) {
238-
[self writeByte:(UInt8)size];
247+
WriteByte(data, (UInt8)size);
239248
} else if (size <= 0xffff) {
240-
[self writeByte:254];
249+
WriteByte(data, 254);
241250
UInt16 value = (UInt16)size;
242-
[self writeBytes:&value length:2];
251+
WriteBytes(data, &value, 2);
243252
} else {
244-
[self writeByte:255];
245-
[self writeBytes:&size length:4];
253+
WriteByte(data, 255);
254+
WriteBytes(data, &size, 4);
246255
}
247256
}
248257

249-
- (void)writeAlignment:(UInt8)alignment {
250-
UInt8 mod = _data.length % alignment;
258+
static void WriteAlignment(CFMutableDataRef data, UInt8 alignment) {
259+
assert(alignment <= 8);
260+
UInt8 mod = CFDataGetLength(data) % alignment;
251261
if (mod) {
252-
for (int i = 0; i < (alignment - mod); i++) {
253-
[self writeByte:0];
254-
}
262+
WriteBytes(data, s_zeroBuffer, alignment - mod);
255263
}
256264
}
257265

258-
- (void)writeUTF8:(NSString*)value {
266+
static void WriteUTF8(CFMutableDataRef data, NSString* value) {
259267
UInt32 length = [value lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
260-
[self writeSize:length];
261-
[self writeBytes:value.UTF8String length:length];
268+
WriteSize(data, length);
269+
WriteBytes(data, value.UTF8String, length);
262270
}
263271

264-
- (void)writeValue:(id)value {
265-
if (value == nil || value == [NSNull null]) {
266-
[self writeByte:FlutterStandardFieldNil];
267-
} else if ([value isKindOfClass:[NSNumber class]]) {
272+
static void WriteValue(CFMutableDataRef data, id value) {
273+
if (value == nil || value == s_nsNull) {
274+
WriteByte(data, FlutterStandardFieldNil);
275+
} else if ([value isKindOfClass:s_nsNumber]) {
268276
CFNumberRef number = (CFNumberRef)value;
269277
BOOL success = NO;
270278
if (CFGetTypeID(number) == CFBooleanGetTypeID()) {
271279
BOOL b = CFBooleanGetValue((CFBooleanRef)number);
272-
[self writeByte:(b ? FlutterStandardFieldTrue : FlutterStandardFieldFalse)];
280+
WriteByte(data, (b ? FlutterStandardFieldTrue : FlutterStandardFieldFalse));
273281
success = YES;
274282
} else if (CFNumberIsFloatType(number)) {
275283
Float64 f;
276284
success = CFNumberGetValue(number, kCFNumberFloat64Type, &f);
277285
if (success) {
278-
[self writeByte:FlutterStandardFieldFloat64];
279-
[self writeAlignment:8];
280-
[self writeBytes:(UInt8*)&f length:8];
286+
WriteByte(data, FlutterStandardFieldFloat64);
287+
WriteAlignment(data, 8);
288+
WriteBytes(data, (UInt8*)&f, 8);
281289
}
282290
} else if (CFNumberGetByteSize(number) <= 4) {
283291
SInt32 n;
284292
success = CFNumberGetValue(number, kCFNumberSInt32Type, &n);
285293
if (success) {
286-
[self writeByte:FlutterStandardFieldInt32];
287-
[self writeBytes:(UInt8*)&n length:4];
294+
WriteByte(data, FlutterStandardFieldInt32);
295+
WriteBytes(data, (UInt8*)&n, 4);
288296
}
289297
} else if (CFNumberGetByteSize(number) <= 8) {
290298
SInt64 n;
291299
success = CFNumberGetValue(number, kCFNumberSInt64Type, &n);
292300
if (success) {
293-
[self writeByte:FlutterStandardFieldInt64];
294-
[self writeBytes:(UInt8*)&n length:8];
301+
WriteByte(data, FlutterStandardFieldInt64);
302+
WriteBytes(data, (UInt8*)&n, 8);
295303
}
296304
}
297305
if (!success) {
298306
NSLog(@"Unsupported value: %@ of number type %ld", value, CFNumberGetType(number));
299-
NSAssert(NO, @"Unsupported value for standard codec");
307+
assert(NO); // Unsupported value for standard codec.
300308
}
301-
} else if ([value isKindOfClass:[NSString class]]) {
309+
} else if ([value isKindOfClass:s_nsString]) {
302310
NSString* string = value;
303-
[self writeByte:FlutterStandardFieldString];
304-
[self writeUTF8:string];
305-
} else if ([value isKindOfClass:[FlutterStandardTypedData class]]) {
311+
WriteByte(data, FlutterStandardFieldString);
312+
WriteUTF8(data, string);
313+
} else if ([value isKindOfClass:s_flutterStandardTypedData]) {
306314
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]]) {
315+
WriteByte(data, FlutterStandardFieldForDataType(typedData.type));
316+
WriteSize(data, typedData.elementCount);
317+
WriteAlignment(data, typedData.elementSize);
318+
WriteData(data, typedData.data);
319+
} else if ([value isKindOfClass:s_nsData]) {
320+
WriteValue(data, [FlutterStandardTypedData typedDataWithBytes:value]);
321+
} else if ([value isKindOfClass:s_nsArray]) {
314322
NSArray* array = value;
315-
[self writeByte:FlutterStandardFieldList];
316-
[self writeSize:array.count];
323+
WriteByte(data, FlutterStandardFieldList);
324+
WriteSize(data, array.count);
317325
for (id object in array) {
318-
[self writeValue:object];
326+
WriteValue(data, object);
319327
}
320-
} else if ([value isKindOfClass:[NSDictionary class]]) {
328+
} else if ([value isKindOfClass:s_nsDictionary]) {
321329
NSDictionary* dict = value;
322-
[self writeByte:FlutterStandardFieldMap];
323-
[self writeSize:dict.count];
330+
WriteByte(data, FlutterStandardFieldMap);
331+
WriteSize(data, dict.count);
324332
for (id key in dict) {
325-
[self writeValue:key];
326-
[self writeValue:[dict objectForKey:key]];
333+
WriteValue(data, key);
334+
WriteValue(data, [dict objectForKey:key]);
327335
}
328336
} else {
329337
NSLog(@"Unsupported value: %@ of type %@", value, [value class]);
330-
NSAssert(NO, @"Unsupported value for standard codec");
338+
assert(NO); // Unsupported value for standard codec.
331339
}
332340
}
341+
342+
- (void)writeByte:(UInt8)value {
343+
WriteByte((CFMutableDataRef)_data, value);
344+
}
345+
346+
- (void)writeBytes:(const void*)bytes length:(NSUInteger)length {
347+
WriteBytes((CFMutableDataRef)_data, bytes, length);
348+
}
349+
350+
- (void)writeData:(NSData*)data {
351+
WriteData((CFMutableDataRef)_data, data);
352+
}
353+
354+
- (void)writeSize:(UInt32)size {
355+
WriteSize((CFMutableDataRef)_data, size);
356+
}
357+
358+
- (void)writeAlignment:(UInt8)alignment {
359+
WriteAlignment((CFMutableDataRef)_data, alignment);
360+
}
361+
362+
- (void)writeUTF8:(NSString*)value {
363+
WriteUTF8((CFMutableDataRef)_data, value);
364+
}
365+
366+
- (void)writeValue:(id)value {
367+
WriteValue((CFMutableDataRef)_data, value);
368+
}
333369
@end
334370

335371
@implementation FlutterStandardReader {
@@ -450,7 +486,7 @@ - (nullable id)readValueOfType:(UInt8)type {
450486
NSMutableArray* array = [NSMutableArray arrayWithCapacity:length];
451487
for (UInt32 i = 0; i < length; i++) {
452488
id value = [self readValue];
453-
[array addObject:(value == nil ? [NSNull null] : value)];
489+
[array addObject:(value == nil ? s_nsNull : value)];
454490
}
455491
return array;
456492
}
@@ -460,8 +496,8 @@ - (nullable id)readValueOfType:(UInt8)type {
460496
for (UInt32 i = 0; i < size; i++) {
461497
id key = [self readValue];
462498
id val = [self readValue];
463-
[dict setObject:(val == nil ? [NSNull null] : val)
464-
forKey:(key == nil ? [NSNull null] : key)];
499+
[dict setObject:(val == nil ? s_nsNull : val)
500+
forKey:(key == nil ? s_nsNull : key)];
465501
}
466502
return dict;
467503
}

0 commit comments

Comments
 (0)