Re: Two Questions on NSStrings <-> bytes
Re: Two Questions on NSStrings <-> bytes
- Subject: Re: Two Questions on NSStrings <-> bytes
- From: Alastair Houghton <email@hidden>
- Date: Tue, 23 Oct 2007 10:48:18 +0100
On 22 Oct 2007, at 18:13, Jaime Magiera wrote:
What do you want here?
Here is the spec. The items I'm working on are URLLength and URL
class TextHyperTextBox() extends TextSampleModifierBox (‘href’) {
unsigned int(16) startcharoffset;
unsigned int(16) endcharoffset;
unsigned int(8) URLLength;
unsigned int(8) URL[URLLength];
unsigned int(8) altLength;
unsigned int(8) altstring[altLength];
}
In a test file created by GarageBand, the binary output looks like
so using xxd...
002facd: 00085072 6f664361 73740000 00256872 ..ProfCast...%hr
002fadd: 65660000 00081768 7474703a 2f2f7777 ef.....http://ww
002faed: 772e7072 6f666361 73742e63 6f6d00 w.profcast.com.
So, I need to convert an NSString value of something like "http:///
www.apple.com", to a straight c-string and write that out. I've
tried a lot of different ways, but I keep ending up with lots of
binary 0's. I think there is something fundamental about bytes/
characters/etc. that I don't get.
Well the first thing you need to find out is what character encoding
should be used for that string. It should say somewhere in the spec
what you should be using (or there will be a field somewhere that
specifies the character encoding explicitly).
At the risk of doing rather too much for you (and because questions
about bytes and characters keep popping up so perhaps others will
find this post and find what they need here)...
I think the format you quote comes from the 3GPP "Timed text format"
specifications, which starts by explaining the encoding in section 5
(specifically, they say that you should use UTF-8 unless you start
with a UTF-16 BOM, in which case you can use UTF-16; also, they say
that text should be fully composed).
It also (section 5.17.1.5) says specifically that the URL is in UTF-8.
Assuming that you are building this structure up in an NSMutableData
called "boxData", and that you have already encoded startCharOffset
and endCharOffset, you might do something like:
NSData *utf8Data = [[string precomposedStringWithCanonicalMapping]
dataUsingEncoding:NSUTF8StringEncoding];
int len = [utf8Data length];
NSAssert (len < 256, @"Chapter URL is too long (you might want to
handle this differently)");
uint8_t utf8URLLen = len;
[boxData appendBytes:&utf8URLLen length:1];
[boxData appendData:utf8Data];
(You could equally use UTF8String and strlen(), though I'd prefer the
-dataUsingEncoding: method for this particular application I think.)
I'll also note that it's likely that you'll keep wanting to encode
strings if you're working with a spec like this, and that they will
often be in the same format (i.e. a length byte, followed by that
many bytes of data). You might consider adding a category on
NSMutableData, containing the following method (or something similar):
- (void)append3GPPString:(NSString *)string
{
NSData *utf8Data = [[string precomposedStringWithCanonicalMapping]
dataUsingEncoding:NSUTF8StringEncoding];
int len = [utf8Data length];
NSAssert (len < 256, @"String too long");
uint8_t utf8Len = [utf8Data length];
[self appendBytes:&utf8Len length:1];
[self appendData:utf8Data];
}
then you could just write
[boxData append3GPPString:chapterURL];
every time you want to encode a <length, string> pair like that.
Hopefully you should be able to compare that with what you have now
and see where you were going wrong. (You might also consider
improving the error handling in the above code; you probably don't
want it to just assert if the string is too long to fit... maybe
truncating it somehow [careful; it's UTF-8 encoded <http://
en.wikipedia.org/wiki/UTF-8>] or reporting an error to the user is
what you want.)
Kind regards,
Alastair.
--
http://alastairs-place.net
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden