Sheamus
Sheamus

Reputation: 6606

Determine if UTF-8 encoded NSData contains a null-terminated string

I have the NSData-to-NSString conversion in an NSData Category, because I'm always using the NSString method: initWithData:encoding:. But, according to this answer, https://stackoverflow.com/a/2467856/1231948, it is not that simple.

So far, I have this method in my NSData Category, in an effort to keep consistent with methods in other data objects that return a string from a method with the same name:

- (NSString *) stringValue
{
    return [[NSString alloc] initWithData:self encoding:NSUTF8StringEncoding];
}

So far it is successful, but I would like to determine if a string is null-terminated, to decide whether I should use this method instead, also from the answer link:

NSString* str = [NSString stringWithUTF8String:[data bytes]];

How do I determine if UTF-8 encoded NSData contains a null-terminated string?


After getting the answer below, I wrote more thorough implementation for my NSData Category method, stringValue:

- (NSString *) stringValue
{
    //Determine if string is null-terminated
    char lastByte;
    [self getBytes:&lastByte range:NSMakeRange([self length]-1, 1)];

    NSString *str;

    if (lastByte == 0x0) {
        //string is null-terminated
        str = [NSString stringWithUTF8String:[self bytes]];
    } else {
        //string is not null-terminated
        str = [[NSString alloc] initWithData:self encoding:NSUTF8StringEncoding];
    }

    return str;
}

Upvotes: 5

Views: 3130

Answers (2)

Tom Harrington
Tom Harrington

Reputation: 70966

Null termination literally means that the last byte has a value of zero. It's easy to check for:

char lastByte;
[myNSData getBytes:&lastByte range:NSMakeRange([myNSData length]-1, 1)];
if (lastByte == 0x0) {
    // string is null terminated
} else {
    // string is not null terminated
}

Upvotes: 10

CRD
CRD

Reputation: 53010

So you wish to determine whether the last byte of your NSData is a null, you know how to get a pointer to all the bytes (bytes) and how many there are (length).

In C a "pointer to all the bytes" can be used as an array and indexed, so you can get the last byte using:

Byte *theBytes = data.bytes;
Byte lastByte = theBytes[bytes.length - 1];

If you need to support the null-terminated string being shorter then the full buffer you'll have to scan for it, remembering to stop at the end (so don't use something like strlen).

In checking for the null you will get both a pointer to the bytes and the length, given that you might want to use initWithBytes:length:encoding: to construct the NSString rather than either of the two methods in the question.

HTH

Upvotes: 0

Related Questions