简体   繁体   中英

NSString into NSMutableData without conversion to NSData

my problem is the following. I would like to encapsulate a NSString in a NSMutableData object. But I would like to do it together with other items and without first encapsulating it into a NSData. It's only bytes after all isn't it?

My final NSMutableData object would look something like

[header | stringLength | NSString]

where header is a char and stringLength is an unsigned short. I build my packet like this

unsigned short stringLength = myString.length;
NSMutableData* nData = [NSMutableData dataWithBytes:(const void*)&header length:sizeof(char)];
[nData appendBytes:(const void*)&dataLength length:sizeof(unsigned short)];
[nData appendBytes:(const void*)myString length:stringLength];

I would then send this over a gkSession and at the other end I would extract the sting lenght and then the string itself:

NSString* temp = [NSString alloc];
[data getBytes:(void*)&temp range:NSMakeRange(sizeof(char)+sizeof(unsigned short), stringLenght)];

For some reasons this is giving me bad memory access. I suspect that myString.length is not doing exactly what I would expect. Do you have any hints? Thanks in advance.

This line is incorrect:

[nData appendBytes:(const void*)myString length:stringLength];

This is encoding the first part of the underlying NSString structure (which is larger than stringLength ).

What you mean is:

[nData appendBytes:[myString UTF8String] 
            length:[myString lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];

length is the number of characters. This can be substantially smaller than the number of bytes for multibyte characters.

Just as a side note: if you can shorten your length to 1 byte (0-255), then that encoding is called a Pascal String, and CFString can handle that encoding natively (see CFStringGetPascalString() ). Not something you generally want to do, but interesting. It's particularly nice with CFStringCreateWithPascalStringNoCopy() , since you can avoid the memory copy operation entirely. This is mostly for legacy support, and I wouldn't jump through any hoops to use it, but sometimes it's handy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM