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 <[email protected]> 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 <[email protected]> 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 ([email protected])
>>
>> 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 [email protected]
>
_______________________________________________
Cocoa-dev mailing list ([email protected])
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 [email protected]