Thanks for the suggestion, Kevin!

I went ahead and created a really crude subclass of NSMutableData. It seems to 
work for my situation.
Attached is the code, for posterity. (I am sure I won't be the only one working 
around this.)

Any suggestions to make this a bit more "Proper" are welcome.

bob.

//
//  GT_NSMutableData.h
//
//  Created by Robert Monaghan on 12/13/12.
//  Copyright (c) 2012 Glue Tools LLC. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface GT_NSMutableData : NSMutableData
{
        void *_gt_buffer;
        NSUInteger _gt_length;
        BOOL _gt_freeWhenDone;
}
@property (readwrite) NSUInteger length;
@end

//
//  GT_NSMutableData.m
//
//  Created by Robert Monaghan on 12/13/12.
//  Copyright (c) 2012 Glue Tools LLC. All rights reserved.
//

#import "GT_NSMutableData.h"

@implementation GT_NSMutableData
+ (id)dataWithBytesNoCopy:(void *)bytes length:(NSUInteger)length 
freeWhenDone:(BOOL)b
{
        return [[[GT_NSMutableData alloc] initWithBytesNoCopy:bytes 
length:length freeWhenDone:b] autorelease];
}

- (id)initWithBytesNoCopy:(void *)bytes length:(NSUInteger)length 
freeWhenDone:(BOOL)b
{
    self = [super init];
    if (self) {
        _gt_buffer = bytes;
        _gt_length = length;
        _gt_freeWhenDone = b;
    }
    return self;
}

- (void)dealloc
{
    if (_gt_freeWhenDone)
                free(_gt_buffer);
        
    [super dealloc];
}

- (void)increaseLengthBy:(NSUInteger)extraLength
{
}

- (void)setLength:(NSUInteger)length
{
}

- (NSUInteger) length
{
        return _gt_length;
}

- (const void *)bytes
{
        return _gt_buffer;
}

- (void *)mutableBytes
{
        return _gt_buffer;
}

- (void)replaceBytesInRange:(NSRange)range withBytes:(const void *)bytes
{
}

- (void)replaceBytesInRange:(NSRange)range withBytes:(const void 
*)replacementBytes length:(NSUInteger)replacementLength
{
}

- (void)resetBytesInRange:(NSRange)range
{
}

- (void)setData:(NSData *)data
{
        _gt_buffer = (void *)[data bytes];
}

@end


On Dec 13, 2012, at 3:22 PM, Kevin Perry <kpe...@apple.com> wrote:

> NSMutableData currently ignores (and always has, to my knowledge) the no-copy 
> "hint" and always copies the bytes into an internal buffer in case something 
> tries to change the length of the NSMutableData.
> 
> It would not be too difficult to make a subclass of NSMutableData that 
> doesn't copy and throws an exception when something tries to change the 
> length. That would violate the Liskov substitution principle though, so at 
> the very least, you want to prevent any code that doesn't understand the 
> fixed-length restriction from getting ahold of one of these objects.
> 
> [kevin perry];
> 
> On Dec 13, 2012, at 2:28 PM, Robert Monaghan <b...@gluetools.com> wrote:
> 
>> Hi Everyone,
>> 
>> I have just run head long into an issue with NSMutableData and existing 
>> buffers.
>> I have the following code:
>> 
>> 
>>                      UInt8 *sourcebytes = [clImgEngine srcBuffer];
>>                      [self setData:[NSMutableData 
>> dataWithBytesNoCopy:sourcebytes length:[clImgEngine inRangeByteCount] 
>> freeWhenDone:NO]];
>>                      UInt8 *resultBytes = [[self data] mutableBytes];
>> 
>> The source is a pinned memory buffer from OpenCL. What I want to do, is to 
>> pass this buffer inside a NSMutableData wrapper and have another object for 
>> some work.
>> Seems simple enough, except that NSMutableData changes the memory buffer in 
>> the background.
>> 
>> "sourcebytes" starts with an address such as: 0x000000012361b000
>> and "resultBytes" returns 0x0000000136fe2000
>> 
>> Naturally, my work object doesn't see any data from "sourcebytes", as 
>> NSMutableData has moved the buffer.
>> I thought that freeWhenDone:NO prevented ownership of the buffer..
>> 
>> Can anyone suggest a way to prevent this from happening? I need the buffer 
>> to stay "pinned".
>> 
>> Thanks in advance!
>> 
>> bob.
>> 
>> _______________________________________________
>> 
>> Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)
>> 
>> 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:
>> https://lists.apple.com/mailman/options/cocoa-dev/kperry%40apple.com
>> 
>> This email sent to kpe...@apple.com
> 

_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

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:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to