From 4673d63e08b894376798a5e94558024ffbd539b1 Mon Sep 17 00:00:00 2001 From: Claudiu Saftoiu Date: Mon, 30 Sep 2013 22:51:27 -0400 Subject: [PATCH 1/6] augmented msgpack to be able to handle raw bytes that aren't utf8 strings. this was necessary in my application. I wasn't sure what the desired behavior should be so I left in some options - see the readme for descriptions. by default, it will return an NSNull on failing to decode a string. i felt this was as close to the original behavior and thus most backwards compatible, but really i'd prefer the default to be an exception. i can change this if need be --- MessagePackPacker.m | 9 ++++-- MessagePackParser+Streaming.h | 1 + MessagePackParser+Streaming.m | 10 ++++-- MessagePackParser.h | 22 +++++++++++++ MessagePackParser.m | 61 ++++++++++++++++++++++++----------- NSData+MessagePack.h | 11 ++++++- NSData+MessagePack.m | 12 +++++-- readme.md | 23 +++++++++++-- 8 files changed, 121 insertions(+), 28 deletions(-) diff --git a/MessagePackPacker.m b/MessagePackPacker.m index 28af09b..af26222 100644 --- a/MessagePackPacker.m +++ b/MessagePackPacker.m @@ -53,7 +53,7 @@ + (void)packNumber:(NSNumber*)num into:(msgpack_packer*)pk { } break; default: - NSLog(@"Could not messagepack number, cannot recognise type: %@", num); + [NSException raise:@"Failed to messagepack number" format:@"Cannot recognize type: %@", num]; } } @@ -75,12 +75,17 @@ + (void)packObject:(id)obj into:(msgpack_packer*)pk { int len = strlen(str); msgpack_pack_raw(pk, len); msgpack_pack_raw_body(pk, str, len); + } else if ([obj isKindOfClass:[NSData class]]) { + const void *bytes = [((NSData *)obj) bytes]; + int len = [((NSData *)obj) length]; + msgpack_pack_raw(pk, len); + msgpack_pack_raw_body(pk, bytes, len); } else if ([obj isKindOfClass:[NSNumber class]]) { [self packNumber:obj into:pk]; } else if (obj==[NSNull null]) { msgpack_pack_nil(pk); } else { - NSLog(@"Could not messagepack object: %@", obj); + [NSException raise:@"Failed to messagepack object" format:@"Object was: %@", obj]; } } diff --git a/MessagePackParser+Streaming.h b/MessagePackParser+Streaming.h index 7d679a0..7388727 100644 --- a/MessagePackParser+Streaming.h +++ b/MessagePackParser+Streaming.h @@ -14,6 +14,7 @@ - (id)init; - (id)initWithBufferSize:(int)bufferSize; - (void)feed:(NSData*)rawData; +- (id)nextWith:(MPRawHandling)rawHandling; - (id)next; @end diff --git a/MessagePackParser+Streaming.m b/MessagePackParser+Streaming.m index 58441ea..400b22c 100644 --- a/MessagePackParser+Streaming.m +++ b/MessagePackParser+Streaming.m @@ -12,7 +12,7 @@ @interface MessagePackParser () // Implemented in MessagePackParser.m -+(id) createUnpackedObject:(msgpack_object)obj; ++(id) createUnpackedObject:(msgpack_object)obj rawHandling:(MPRawHandling)rawHandling; @end @implementation MessagePackParser (Streaming) @@ -36,13 +36,13 @@ - (void)feed:(NSData*)chunk { } // Put next parsed messagepack data. If there is not sufficient data, return nil. -- (id)next { +- (id)nextWith:(MPRawHandling) rawHandling { id unpackedObject; msgpack_unpacked result; msgpack_unpacked_init(&result); if (msgpack_unpacker_next(&unpacker, &result)) { msgpack_object obj = result.data; - unpackedObject = [MessagePackParser createUnpackedObject:obj]; + unpackedObject = [MessagePackParser createUnpackedObject:obj rawHandling:rawHandling]; } msgpack_unpacked_destroy(&result); @@ -53,4 +53,8 @@ - (id)next { #endif } +- (id)next { + return [self nextWith:MPRawsAsNSString_NSNullOnFail]; +} + @end diff --git a/MessagePackParser.h b/MessagePackParser.h index 5aede5c..15b43b4 100644 --- a/MessagePackParser.h +++ b/MessagePackParser.h @@ -9,11 +9,33 @@ #import #include "msgpack_src/msgpack.h" +typedef enum +{ + MPRawsAsNSString_NSNullOnFail, + MPRawsAsNSString_NSDataOnFail, + MPRawsAsNSString_ExceptionOnFail, + MPRawsAsNSData, +} MPRawHandling; + + @interface MessagePackParser : NSObject { // This is only for MessagePackParser+Streaming category. msgpack_unpacker unpacker; } +//parse the data into an NSObject. handle raw bytes as specified: +// - MPRawsAsNSString_NSNullOnFail: try to decode the bytes with utf8. +// if the decoding fails, put an NSNull in that part of the message. +// - MPRawsAsNSString_NSDataOnFail: try to decode the bytes with utf8. +// if the decoding fails, put an NSData in that part of the message. +// - MPRawsAsNSString_ExceptionOnFail: try to decode the bytes with utf8. +// if the decoding fails, raise an exception +// - MPRawsAsNSData: always leave bytes as they are, leaving them as +// NSDatas. + ++ (id)parseData:(NSData*)data rawHandling:(MPRawHandling)rawHandling; + +//parse the data into an NSObject, handling raws with MPRawsAsNSString_NSNullOnFail + (id)parseData:(NSData*)data; @end diff --git a/MessagePackParser.m b/MessagePackParser.m index 61078cc..0b59df0 100644 --- a/MessagePackParser.m +++ b/MessagePackParser.m @@ -11,29 +11,49 @@ @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 { ++(id) createUnpackedObject:(msgpack_object)obj rawHandling:(MPRawHandling)rawHandling { 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; + { + if (rawHandling == MPRawsAsNSData) { + return [[NSData alloc] initWithBytes:obj.via.raw.ptr length:obj.via.raw.size]; + } + + NSString *res = [[NSString alloc] initWithBytes:obj.via.raw.ptr + length:obj.via.raw.size + encoding:NSUTF8StringEncoding]; + if (res) { + return res; + } + + switch (rawHandling) { + case MPRawsAsNSString_NSNullOnFail: + return [NSNull null]; + case MPRawsAsNSString_ExceptionOnFail: + [NSException raise:@"Invalid string encountered" + format:@"Raw bytes did not decode into utf8"]; + return res; + case MPRawsAsNSString_NSDataOnFail: { + return [[NSData alloc] initWithBytes:obj.via.raw.ptr length:obj.via.raw.size]; + case MPRawsAsNSData: //suppress compiler warning + return res; + } + } + } 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]; + id newArrayItem = [self createUnpackedObject:*p rawHandling:rawHandling]; [arr addObject:newArrayItem]; #if !__has_feature(objc_arc) [newArrayItem release]; @@ -41,14 +61,13 @@ +(id) createUnpackedObject:(msgpack_object)obj { } 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]; + id key = [self createUnpackedObject:p->key rawHandling:rawHandling]; + id val = [self createUnpackedObject:p->val rawHandling:rawHandling]; [dict setValue:val forKey:key]; #if !__has_feature(objc_arc) [key release]; @@ -57,26 +76,32 @@ +(id) createUnpackedObject:(msgpack_object)obj { } 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; + default: + [NSException raise:@"Unsupported object type" + format:@"Unrecognized msgpack object type %d", obj.type]; + return [NSNull null]; // suppress compiler warning } } -// Parse the given messagepack data into a NSDictionary or NSArray typically -+ (id)parseData:(NSData*)data { ++ (id)parseData:(NSData*)data rawHandling:(MPRawHandling)rawHandling { 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 + // Convert from C-land to Obj-c-land + id results = success ? [self createUnpackedObject:msg.data rawHandling:rawHandling] : nil; msgpack_unpacked_destroy(&msg); // Free the parser #if !__has_feature(objc_arc) return [results autorelease]; #else return results; -#endif +#endif +} + +// Parse the given messagepack data into a NSDictionary or NSArray typically ++ (id)parseData:(NSData*)data { + return [self parseData:data rawHandling:MPRawsAsNSString_NSNullOnFail]; } @end diff --git a/NSData+MessagePack.h b/NSData+MessagePack.h index 41e2fe5..3aa24df 100644 --- a/NSData+MessagePack.h +++ b/NSData+MessagePack.h @@ -7,11 +7,20 @@ // #import +#import "MessagePackParser.h" // Adds MessagePack parsing to NSData @interface NSData (NSData_MessagePack) -// Parses the receiver's data into a message pack array or dictionary +// **Packs** the receiver's data into message pack data +- (NSData*)messagePack; + +// Parses the receiver's data into a message pack array or dictionary, +// decoding raw bytes into utf8 strings - (id)messagePackParse; +// Parses the receiver's data into a message pack array or dictionary, +// without decoding raw bytes into utf8 strings +- (id)messagePackParseWith:(MPRawHandling)rawHandling; + @end diff --git a/NSData+MessagePack.m b/NSData+MessagePack.m index 2b08ce8..5a19b99 100644 --- a/NSData+MessagePack.m +++ b/NSData+MessagePack.m @@ -7,13 +7,21 @@ // #import "NSData+MessagePack.h" - +#import "MessagePackPacker.h" #import "MessagePackParser.h" @implementation NSData (NSData_MessagePack) +- (NSData*)messagePack { + return [MessagePackPacker pack:self]; +} + -(id)messagePackParse { - return [MessagePackParser parseData:self]; + return [MessagePackParser parseData:self]; +} + +- (id)messagePackParseWith:(MPRawHandling)rawHandling { + return [MessagePackParser parseData:self rawHandling:rawHandling]; } @end diff --git a/readme.md b/readme.md index 29780c4..b47cdd9 100644 --- a/readme.md +++ b/readme.md @@ -2,7 +2,7 @@ MessagePack for Objective-C / iPhone ============ This is a wrapper for the C MessagePack parser, building the bridge to Objective-C. -In a similar way to the JSON framework, this parses MessagePack into NSDictionaries, NSArrays, NSNumbers, NSStrings, and NSNulls. +In a similar way to the JSON framework, this parses MessagePack into NSDictionaries, NSArrays, NSNumbers, NSStrings, NSDatas and NSNulls. This contains a small patch to the C library so that it doesn't segfault with a byte alignment error when running on the iPhone in armv7 mode. Please note that the parser has been extensively tested, however the packer has not been. Please get in touch if it has issues. @@ -12,9 +12,26 @@ Parsing Usage #import "MessagePack.h" ... NSData* myData = ... - NSDictionary* parsed = [myData messagePackParse]; + NSDictionary* parsed = [myData messagePackParse]; //decodes raw bytes into NSStrings using UTF8 NSLog(@"%@", [parsed description]); +Handling Raw Data +----- + + NSData* myData = ... + + //default: try to decode raw bytes into utf8 strings, parse to NSNull on fail + NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_NSNullOnFail]; + + //try to decode, parse to NSData of the original bytes on fail + NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_NSDataOnFail]; + + //try to decode, raise an exception on fail + NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_ExceptionOnFail]; + + //always parse to NSData + NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_ExceptionOnFail]; + Packing Usage ---- @@ -22,6 +39,7 @@ Packing Usage .. NSData* packed = [someArray messagePack]; NSData* packed = [someDictionary messagePack]; + NSData* packed = [someData messagePack]; Authors ------- @@ -29,6 +47,7 @@ Authors * Sugendran Ganess * Chris Hulbert * Bugfixes by Matzo: https://github.com/Matzo +* NSData handling by csaftoiu: https://github.com/csaftoiu License ------- From 555f9f61b1751700149ce73ac0694624b8e91ea9 Mon Sep 17 00:00:00 2001 From: Claudiu Saftoiu Date: Mon, 30 Sep 2013 23:07:12 -0400 Subject: [PATCH 2/6] change default behavior to raise an exception --- MessagePackParser+Streaming.m | 2 +- MessagePackParser.h | 6 +++--- MessagePackParser.m | 2 +- readme.md | 14 +++++++------- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/MessagePackParser+Streaming.m b/MessagePackParser+Streaming.m index 400b22c..086b3e1 100644 --- a/MessagePackParser+Streaming.m +++ b/MessagePackParser+Streaming.m @@ -54,7 +54,7 @@ - (id)nextWith:(MPRawHandling) rawHandling { } - (id)next { - return [self nextWith:MPRawsAsNSString_NSNullOnFail]; + return [self nextWith:MPRawsAsNSString_ExceptionOnFail]; } @end diff --git a/MessagePackParser.h b/MessagePackParser.h index 15b43b4..9d48725 100644 --- a/MessagePackParser.h +++ b/MessagePackParser.h @@ -24,18 +24,18 @@ typedef enum } //parse the data into an NSObject. handle raw bytes as specified: +// - MPRawsAsNSString_ExceptionOnFail: try to decode the bytes with utf8. +// if the decoding fails, raise an exception // - MPRawsAsNSString_NSNullOnFail: try to decode the bytes with utf8. // if the decoding fails, put an NSNull in that part of the message. // - MPRawsAsNSString_NSDataOnFail: try to decode the bytes with utf8. // if the decoding fails, put an NSData in that part of the message. -// - MPRawsAsNSString_ExceptionOnFail: try to decode the bytes with utf8. -// if the decoding fails, raise an exception // - MPRawsAsNSData: always leave bytes as they are, leaving them as // NSDatas. + (id)parseData:(NSData*)data rawHandling:(MPRawHandling)rawHandling; -//parse the data into an NSObject, handling raws with MPRawsAsNSString_NSNullOnFail +//parse the data into an NSObject, handling raws with MPRawsAsNSString_ExceptionOnFail + (id)parseData:(NSData*)data; @end diff --git a/MessagePackParser.m b/MessagePackParser.m index 0b59df0..c73891f 100644 --- a/MessagePackParser.m +++ b/MessagePackParser.m @@ -101,7 +101,7 @@ + (id)parseData:(NSData*)data rawHandling:(MPRawHandling)rawHandling { // Parse the given messagepack data into a NSDictionary or NSArray typically + (id)parseData:(NSData*)data { - return [self parseData:data rawHandling:MPRawsAsNSString_NSNullOnFail]; + return [self parseData:data rawHandling:MPRawsAsNSString_ExceptionOnFail]; } @end diff --git a/readme.md b/readme.md index b47cdd9..414f283 100644 --- a/readme.md +++ b/readme.md @@ -20,18 +20,18 @@ Handling Raw Data NSData* myData = ... - //default: try to decode raw bytes into utf8 strings, parse to NSNull on fail - NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_NSNullOnFail]; - - //try to decode, parse to NSData of the original bytes on fail - NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_NSDataOnFail]; - - //try to decode, raise an exception on fail + //default: try to decode, raise an exception on fail NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_ExceptionOnFail]; //always parse to NSData NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_ExceptionOnFail]; + //try to decode, parse to NSData of the original bytes on fail + NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_NSDataOnFail]; + + //try to decode raw bytes into utf8 strings, parse to NSNull on fail + NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_NSNullOnFail]; + Packing Usage ---- From 2427e6aba827220b5f62cb09dd7f787dcd1fb48b Mon Sep 17 00:00:00 2001 From: Claudiu Saftoiu Date: Mon, 30 Sep 2013 23:20:34 -0400 Subject: [PATCH 3/6] Helper function as NSData category --- NSData+MessagePack.h | 5 +++++ NSData+MessagePack.m | 14 ++++++++++++++ readme.md | 10 +++++++--- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/NSData+MessagePack.h b/NSData+MessagePack.h index 3aa24df..843d507 100644 --- a/NSData+MessagePack.h +++ b/NSData+MessagePack.h @@ -23,4 +23,9 @@ // without decoding raw bytes into utf8 strings - (id)messagePackParseWith:(MPRawHandling)rawHandling; +// If obj is NSData, return obj. If obj is NSString, return +// NSData of the utf8-encoded bytes. Otherwise, raise an exception. +// useful when using MPRawsAsNSString_NSDataOnFail ++ (NSData *)expectData:(id) obj; + @end diff --git a/NSData+MessagePack.m b/NSData+MessagePack.m index 5a19b99..5695830 100644 --- a/NSData+MessagePack.m +++ b/NSData+MessagePack.m @@ -24,4 +24,18 @@ - (id)messagePackParseWith:(MPRawHandling)rawHandling { return [MessagePackParser parseData:self rawHandling:rawHandling]; } ++ (NSData *)expectData:(id) dataOrString { + if ([dataOrString isKindOfClass:[NSData class]]) { + return dataOrString; + } + else if ([dataOrString isKindOfClass:[NSString class]]) { + return [dataOrString dataUsingEncoding:NSUTF8StringEncoding]; + } + else { + [NSException raise:@"Unexpected object in message" + format:@"Expected data or string, not %@", dataOrString]; + return nil; //suppress warning + } +} + @end diff --git a/readme.md b/readme.md index 414f283..3b9feac 100644 --- a/readme.md +++ b/readme.md @@ -23,15 +23,19 @@ Handling Raw Data //default: try to decode, raise an exception on fail NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_ExceptionOnFail]; - //always parse to NSData - NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_ExceptionOnFail]; - //try to decode, parse to NSData of the original bytes on fail NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_NSDataOnFail]; + //always parse to NSData + NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_ExceptionOnFail]; + //try to decode raw bytes into utf8 strings, parse to NSNull on fail NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_NSNullOnFail]; + //if using MPRawsAsNSString_NSDataOnFail, NSData+MessagePack.h provides a useful + //helper function when you expect bytes, just in case they were valid utf8 bytes. + NSData *data = [NSData expectData:[parsed objectForKey:@"bytes"]; + Packing Usage ---- From 25d3875d8d6689f982c01b467fe20fa500ad793b Mon Sep 17 00:00:00 2001 From: Claudiu Saftoiu Date: Mon, 30 Sep 2013 23:21:27 -0400 Subject: [PATCH 4/6] readme typo --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 3b9feac..9ce33cd 100644 --- a/readme.md +++ b/readme.md @@ -34,7 +34,7 @@ Handling Raw Data //if using MPRawsAsNSString_NSDataOnFail, NSData+MessagePack.h provides a useful //helper function when you expect bytes, just in case they were valid utf8 bytes. - NSData *data = [NSData expectData:[parsed objectForKey:@"bytes"]; + NSData *data = [NSData expectData:[parsed objectForKey:@"bytes"]]; Packing Usage ---- From 1cd7aa4686ca4856e73ef482923399f6adfe85bb Mon Sep 17 00:00:00 2001 From: Claudiu Saftoiu Date: Mon, 30 Sep 2013 23:25:02 -0400 Subject: [PATCH 5/6] readme typo --- readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index 9ce33cd..4acfe89 100644 --- a/readme.md +++ b/readme.md @@ -26,12 +26,12 @@ Handling Raw Data //try to decode, parse to NSData of the original bytes on fail NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_NSDataOnFail]; - //always parse to NSData - NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_ExceptionOnFail]; - //try to decode raw bytes into utf8 strings, parse to NSNull on fail NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_NSNullOnFail]; + //always parse to NSData + NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSData]; + //if using MPRawsAsNSString_NSDataOnFail, NSData+MessagePack.h provides a useful //helper function when you expect bytes, just in case they were valid utf8 bytes. NSData *data = [NSData expectData:[parsed objectForKey:@"bytes"]]; From b4c30b9988c91f75dffbcba54677af16c76a575b Mon Sep 17 00:00:00 2001 From: Claudiu Saftoiu Date: Mon, 30 Sep 2013 23:27:28 -0400 Subject: [PATCH 6/6] readme fixup --- readme.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/readme.md b/readme.md index 4acfe89..a4df5c8 100644 --- a/readme.md +++ b/readme.md @@ -12,17 +12,16 @@ Parsing Usage #import "MessagePack.h" ... NSData* myData = ... - NSDictionary* parsed = [myData messagePackParse]; //decodes raw bytes into NSStrings using UTF8 + NSDictionary* parsed = [myData messagePackParse]; NSLog(@"%@", [parsed description]); Handling Raw Data ----- +When using `messagePackParse`, bytes are decoded with utf8 and parsed into `NSString`s, and an exception is raised if that encoding is invalid. This behavior can be changed as follows: + NSData* myData = ... - //default: try to decode, raise an exception on fail - NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_ExceptionOnFail]; - //try to decode, parse to NSData of the original bytes on fail NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_NSDataOnFail]; @@ -32,6 +31,9 @@ Handling Raw Data //always parse to NSData NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSData]; + //(same as `messagePackParse`): try to decode, raise an exception on fail + NSDictionary *parsed = [myData messagePackParseWith:MPRawsAsNSString_ExceptionOnFail]; + //if using MPRawsAsNSString_NSDataOnFail, NSData+MessagePack.h provides a useful //helper function when you expect bytes, just in case they were valid utf8 bytes. NSData *data = [NSData expectData:[parsed objectForKey:@"bytes"]];