-
Notifications
You must be signed in to change notification settings - Fork 61
/
MessagePackParser.m
82 lines (77 loc) · 2.9 KB
/
MessagePackParser.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
//
// MessagePackParser.m
// Fetch TV Remote
//
// Created by Chris Hulbert on 23/06/11.
// Copyright 2011 Digital Five. All rights reserved.
//
#import "MessagePackParser.h"
@implementation MessagePackParser
// This function returns a parsed object that you have the responsibility to release/autorelease (see 'create rule' in apple docs)
+(id) createUnpackedObject:(msgpack_object)obj {
switch (obj.type) {
case MSGPACK_OBJECT_BOOLEAN:
return [[NSNumber alloc] initWithBool:obj.via.boolean];
break;
case MSGPACK_OBJECT_POSITIVE_INTEGER:
return [[NSNumber alloc] initWithUnsignedLongLong:obj.via.u64];
break;
case MSGPACK_OBJECT_NEGATIVE_INTEGER:
return [[NSNumber alloc] initWithLongLong:obj.via.i64];
break;
case MSGPACK_OBJECT_DOUBLE:
return [[NSNumber alloc] initWithDouble:obj.via.dec];
break;
case MSGPACK_OBJECT_RAW:
return [[NSString alloc] initWithBytes:obj.via.raw.ptr length:obj.via.raw.size encoding:NSUTF8StringEncoding];
break;
case MSGPACK_OBJECT_ARRAY:
{
NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:obj.via.array.size];
msgpack_object* const pend = obj.via.array.ptr + obj.via.array.size;
for(msgpack_object *p= obj.via.array.ptr;p < pend;p++){
id newArrayItem = [self createUnpackedObject:*p];
[arr addObject:newArrayItem];
#if !__has_feature(objc_arc)
[newArrayItem release];
#endif
}
return arr;
}
break;
case MSGPACK_OBJECT_MAP:
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc] initWithCapacity:obj.via.map.size];
msgpack_object_kv* const pend = obj.via.map.ptr + obj.via.map.size;
for(msgpack_object_kv* p = obj.via.map.ptr; p < pend; p++){
id key = [self createUnpackedObject:p->key];
id val = [self createUnpackedObject:p->val];
[dict setValue:val forKey:key];
#if !__has_feature(objc_arc)
[key release];
[val release];
#endif
}
return dict;
}
break;
case MSGPACK_OBJECT_NIL:
default:
return [NSNull null]; // Since nsnull is a system singleton, we don't have to worry about ownership of it
break;
}
}
// Parse the given messagepack data into a NSDictionary or NSArray typically
+ (id)parseData:(NSData*)data {
msgpack_unpacked msg;
msgpack_unpacked_init(&msg);
bool success = msgpack_unpack_next(&msg, data.bytes, data.length, NULL); // Parse it into C-land
id results = success ? [self createUnpackedObject:msg.data] : nil; // Convert from C-land to Obj-c-land
msgpack_unpacked_destroy(&msg); // Free the parser
#if !__has_feature(objc_arc)
return [results autorelease];
#else
return results;
#endif
}
@end