Sunday, June 2, 2013

NSMutableData mutableBytes example in Objective C (iOS).

NSMutableData mutableBytes

Returns a pointer to the receiver’s data.

- (void *)mutableBytes

Return Value
A pointer to the receiver’s data.

Discussion of [NSMutableData mutableBytes]
If the length of the receiver’s data is not zero, this function is guaranteed to return a pointer to the object's internal bytes. If the length of receiver’s data is zero, this function may or may not return NULL dependent upon many factors related to how the object was created (moreover, in this case the method result might change between different releases).

A sample using this method can be found in Working With Mutable Binary Data.

NSMutableData mutableBytes example.
NSMutableData* mydata = [[NSMutableData alloc] init];
[mydata appendData: [@"hello" dataUsingEncoding:NSUTF8StringEncoding]];
NSLog(@"%p", [mydata mutableBytes]);
NSLog(@"%p", [mydata bytes]);

Example of [NSMutableData mutableBytes].
typedef struct {
    UInt32      riffChunkID; // Always RIFF, in big endian. Integer fields are little-ending.
    UInt32      fileLength;
    UInt32      waveFileID; // 'WAVE' for Wave files.
    UInt32      formatChunkID; // 'fmt '
    UInt32      formatChunkSize;
    SInt16      formatTag; // Wave Format ID: see constants
    SInt16      channels; // Number of Channels: 1=mono, 2=stereo
    SInt32      sampleRate; // Sample Rate: samples per second
    SInt32      bytesPerSec; // sampleRate * blockAlign
    SInt16      blockAlign; // sample frame size = channels * sampleSize / 8
    SInt16      bitsPerSample; // sampleSize (8 or 16), also two's-complement for 16-bit, offset for 8-bit
    UInt32      dataChunkID;  // 'data'
    UInt32      dataChunkSize;
} WaveHeader;

int tfChannels = 1; // mono
int tfSampleRate = 44100;
int tfBitsPerSample = 16;

WaveHeader *header = [maindata mutableBytes];

header->riffChunkID = CFSwapInt32HostToBig ('RIFF');
header->fileLength = CFSwapInt32HostToLittle ([maindata length] - 8);
header->waveFileID = CFSwapInt32HostToBig ('WAVE');

header->formatChunkID = CFSwapInt32HostToBig ('fmt ');
header->formatChunkSize = CFSwapInt32HostToLittle (16);
header->formatTag = CFSwapInt16HostToLittle (1);
header->channels = CFSwapInt16HostToLittle (tfChannels);
header->sampleRate = CFSwapInt32HostToLittle (tfSampleRate);
header->bytesPerSec = CFSwapInt32HostToLittle (tfSampleRate * tfBitsPerSample / 8 * tfChannels);
header->blockAlign = CFSwapInt16HostToLittle (tfBitsPerSample / 8 * tfChannels);
header->bitsPerSample = CFSwapInt16HostToLittle (tfBitsPerSample);
header->dataChunkID = CFSwapInt32HostToBig ('data');
header->dataChunkSize = CFSwapInt32HostToLittle ([maindata length] - 44);

NSMutableData mutableBytes example.
NSMutableData* mutableData = [NSMutableData dataWithLength: someLength];
void* bitmapData = [mutableData mutableBytes];
CGContextRef context = CGBitmapContextCreate(bitmapData,...);
// ...use context

End of NSMutableData mutableBytes example article.