Saturday, June 1, 2013

NSData initWithBytesNoCopy example in Objective C (iOS).


NSData initWithBytesNoCopy

Returns a data object initialized by adding to it a given number of bytes of data from a given buffer.

- (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)length

Parameters of [NSData initWithBytesNoCopy]
bytes
A buffer containing data for the new object. bytes must point to a memory block allocated with malloc.
length
The number of bytes to hold from bytes. This value must not exceed the length of bytes.

Return Value
A data object initialized by adding to it length bytes of data from the buffer bytes. The returned object might be different than the original receiver.

Discussion of [NSData initWithBytesNoCopy]
The returned object takes ownership of the bytes pointer and frees it on deallocation. Therefore, bytes must point to a memory block allocated with malloc.

NSData initWithBytesNoCopy example.
int offset = 10;
NSRange dataRange;
dataRange.length = [data length] - offset;
dataRange.location = offset;

void *buffer = malloc(dataRange.length);
[data getBytes:buffer range:dataRange];
self.bodyData = [[NSData alloc] initWithBytesNoCopy:buffer length:dataRange.length];
free(buffer); //Make sure your property has either retain attribute (or strong if using ARC)

Example of [NSData initWithBytesNoCopy].
if (flags == nil) {
   flagPtr *flgH = &flags;
   NSData *flgsDatum =
      [[NSData alloc] initWithBytesNoCopy:flgH length:sizeof(flgH)
freeWhenDone:NO];
   [[NSNotificationCenter defaultCenter] postNotificationName:@"fetchFlags"
object:flgsDatum];
   *flags = (WORKING | (*flags & LOGFILE));
}

NSData initWithBytesNoCopy example.
- (NSString *)hashWithDigest:(AUMessageDigest)digest data:(NSData **)data
{
    u_byte *(*CC_XXX)(const void *, CC_LONG, u_byte *);
    CC_LONG CC_XXX_DIGEST_LEN;
    u_byte *md = NULL;
    NSInteger i = 0;
    NSString *result;
    NSMutableString *buffer;
   
    switch (digest) {
        case AUDigestSHA1:
            CC_XXX = CC_SHA1;
            CC_XXX_DIGEST_LEN = CC_SHA1_DIGEST_LENGTH;
        break;
        case AUDigestSHA256:
            CC_XXX = CC_SHA256;
            CC_XXX_DIGEST_LEN = CC_SHA256_DIGEST_LENGTH;
        break;
        case AUDigestSHA512:
            CC_XXX = CC_SHA512;
            CC_XXX_DIGEST_LEN = CC_SHA512_DIGEST_LENGTH;
        break;
        case AUDigestMD5:
            CC_XXX = CC_MD5;
            CC_XXX_DIGEST_LEN = CC_MD5_DIGEST_LENGTH;
        break;
        default:
            return nil;
    }
   
    result = nil;
    if((md = malloc(CC_XXX_DIGEST_LEN * sizeof(u_byte) + 1))) {
        memset(md, 0, CC_XXX_DIGEST_LEN + 1);
        CC_XXX([self bytes], [self length], md);
        buffer = [NSMutableString string];
        for (i = 0; i< CC_XXX_DIGEST_LEN; i++) {
            [buffer appendFormat:@"%02x", (CC_LONG)(md[i])];
        }
        if (data != nil) {
            *data = [[NSData alloc] initWithBytesNoCopy:md length:CC_XXX_DIGEST_LEN freeWhenDone:YES];
        } else {
            free(md);
        }
        result = [NSString stringWithString:buffer];
    }
    return result;
}

End of NSData initWithBytesNoCopy example article.