This is MiscMutableData.m in view mode; [Download] [Up]
/* MiscMutableData.m created by giddings on Tue 04-Feb-1997 */
//Written By Michael Giddings, 1996 and 1997
//giddings@barbarian.com
//giddings@whitewater.chem.wisc.edu
//MiscMutableData
//The purpose of this "subclass" of MiscMutableData is to handle some
//byte order swapping when using and NSMutableData to store arrays of
//Floats, Doubles, and Ints.
//The primary thing to remember about using this class is that you must
//tell it what type to use when you create it, otherwise it can't really
//know how to change byte order when appropriate. You set this by sending
//it a -setType message, with a single character type code of i (int),
//d (double-float), f (float), l (long int)
//This class may also be useful because it demonstrates (somewhat) how
//to effectively subclass an abstract class cluster, which is something
//I had difficulty getting to work at first. That is the one downside
//of class clusters. Anyway, for someone wishing to create their own
//subclass of NSMutableData, this gets you a substantial way there.
#import "MiscMutableData.h"
@implementation MiscMutableData
+ (id)allocWithZone:(NSZone *)zone
{
return [super allocWithZone:zone];
}
+ (MiscMutableData *)data
{
return [[[self alloc] init] autorelease];
}
+ (MiscMutableData *)dataWithBytes:(const void *)bytes length:(unsigned int)length
{
return [[[self alloc] initWithBytes:bytes length:length] autorelease];
}
+ (MiscMutableData *)dataWithBytesNoCopy:(void *)bytes length:(unsigned int)length
{
return [[[self alloc] initWithBytesNoCopy:bytes length:length] autorelease];
}
+ (MiscMutableData *)dataWithContentsOfFile:(NSString *)path
{
return [[[MiscMutableData alloc] initWithContentsOfFile:path] autorelease];
}
+ (MiscMutableData *)dataWithContentsOfMappedFile:(NSString *)path
{
return [[[MiscMutableData alloc] initWithContentsOfMappedFile:path] autorelease];
}
+ (MiscMutableData *)dataWithData:(NSMutableData *)aData
{
MiscMutableData *temp = [MiscMutableData alloc];
return ([[temp initWithData:aData] autorelease]);
}
+ (MiscMutableData *)dataWithCapacity:(unsigned int)aNumItems
{
return [[[MiscMutableData alloc] initWithCapacity:aNumItems] autorelease];
}
+ (MiscMutableData *)dataWithLength:(unsigned int)length;
{
return [[[MiscMutableData alloc] initWithLength:length] autorelease];
}
- (MiscMutableData *)init
{
type = 0;
[super init];
data = [[NSMutableData allocWithZone:[self zone]] init];
byteOrder = [self hostOrder];
return self;
}
- (MiscMutableData *)initWithCapacity:(unsigned int)capacity
{
[super init];
byteOrder = [self hostOrder];
data = [[NSMutableData allocWithZone:[self zone]] initWithCapacity:capacity];
return self;
}
- (MiscMutableData *)initWithLength:(unsigned int)length{
[super init];
byteOrder = [self hostOrder];
data = [[NSMutableData allocWithZone:[self zone]] initWithLength:length];
return self;
}
- (id)initWithBytes:(const void *)bytes length:(unsigned int)length
{
type = 0;
[super init];
data = [[NSMutableData allocWithZone:[self zone]] initWithBytes:bytes length:length];
byteOrder = [self hostOrder];
return self;
}
- (id)initWithBytesNoCopy:(void *)bytes length:(unsigned int)length{
type = 0;
[super init];
data = [[NSMutableData allocWithZone:[self zone]] initWithBytesNoCopy:bytes length:length];
byteOrder = [self hostOrder];
return self;
}
- (id)initWithContentsOfFile:(NSString *)path
{
type = 0;
[super init];
data = [[NSMutableData allocWithZone:[self zone]] initWithContentsOfFile:path];
byteOrder = [self hostOrder];
return self;
}
- (id)initWithContentsOfMappedFile:(NSString *)path
{
type = 0;
[super init];
data = [[NSMutableData allocWithZone:[self zone]] initWithContentsOfMappedFile:path];
byteOrder = [self hostOrder];
return self;
}
- (MiscMutableData *)initWithData:(NSMutableData *)thedata
{
type = 0;
[super init];
data = [thedata mutableCopy];
//[NSMutableData allocWithZone:[self zone]] initWithData:thedata];
byteOrder = [self hostOrder];
return self;
}
- (id)copyWithZone:(NSZone *)zone
{
return [self retain];
}
- (id)mutableCopyWithZone:(NSZone *)zone
{
MiscMutableData *copy = [MiscMutableData allocWithZone:zone];
[copy initWithData:data];
[copy setByteOrder:[self byteOrder]];
[copy setType:[self type]];
return copy;
}
- (id)setType:(unsigned char)thetype
{
if ((thetype == 'i') || (thetype == 'l') || (thetype == 'd') || (thetype == 'f'))
type = thetype;
return self;
}
-(unsigned char)type
{
return type;
}
- replacementObjectForPortCoder:(NSPortCoder *)encoder
{
if ([encoder isBycopy])
return self;
else
return [super replacementObjectForPortCoder:encoder];
}
- (void)setByteOrder:(char unsigned)order
{
byteOrder=order;
}
-(NSMutableData *)data
{
return data;
}
- (unsigned char)byteOrder
{
return byteOrder;
}
- (void)dealloc
{
fprintf(stderr, "Freeing myself (MiscMutableData)\n");
if (data != NULL)
[data release];
[super dealloc];
}
- (unsigned char)hostOrder
{
#ifdef __BIG_ENDIAN__
return MISC_BIGENDIAN;
#else
return MISC_LITTLEENDIAN;
#endif
}
- (BOOL)respondsToSelector:(SEL)aSelector
{
if ( [super respondsToSelector:aSelector] )
return YES;
else if ([data respondsToSelector:aSelector])
return YES;
else
return NO;
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel
{
NSMethodSignature *result = [super methodSignatureForSelector:sel];
if (nil == result)
result = [data methodSignatureForSelector:sel];
return result;
}
- (void)forwardInvocation:(NSInvocation *)invocation
{
if ([data respondsToSelector:[invocation selector]])
[invocation invokeWithTarget:data];
else
{
[self doesNotRecognizeSelector:[invocation selector]];
fprintf(stderr, "Cannot forward message, selector not recognized.\n");
}
}
- (unsigned int)length
{
return [data length];
}
- (const void *)bytes
{
return [data bytes];
}
- (void *)mutableBytes
{
return [data mutableBytes];
}
- (void)setLength:(unsigned int)length
{
[data setLength:length];
}
- (void)swapDoubleToHost
{
unsigned char curHostOrder = [self hostOrder];
if (byteOrder != curHostOrder) {
NSSwappedDouble *temp1 = (NSSwappedDouble *)[data bytes];
double *temp = (double *)[data mutableBytes];
unsigned i, count = ([data length] / sizeof(double));
if (byteOrder == MISC_BIGENDIAN) {
for (i = 0; i < count; i++)
temp[i] = NSSwapBigDoubleToHost(temp1[i]);
[self setByteOrder:MISC_LITTLEENDIAN];
}
else
{
for (i = 0; i < count; i++)
temp[i] = NSSwapLittleDoubleToHost(temp1[i]);
[self setByteOrder:MISC_LITTLEENDIAN];
}
}
}
- (void)swapFloatToHost
{
unsigned char curHostOrder = [self hostOrder];
if (byteOrder != curHostOrder) {
NSSwappedFloat *temp1 = (NSSwappedFloat *)[data bytes];
float *temp = (float *)[data mutableBytes];
unsigned i, count = ([data length] / sizeof(float));
if (byteOrder == MISC_BIGENDIAN) {
for (i = 0; i < count; i++)
temp[i] = NSSwapBigFloatToHost(temp1[i]);
[self setByteOrder:MISC_LITTLEENDIAN];
}
else
{
for (i = 0; i < count; i++)
temp[i] = NSSwapLittleFloatToHost(temp1[i]);
[self setByteOrder:MISC_LITTLEENDIAN];
}
}
}
- (void)swapLongToHost
{
unsigned char curHostOrder = [self hostOrder];
if (byteOrder != curHostOrder) {
long *temp = (long *)[data mutableBytes];
unsigned i, count = ([data length] / sizeof(long));
if (byteOrder == MISC_BIGENDIAN) {
for (i = 0; i < count; i++)
temp[i] = NSSwapBigLongToHost(temp[i]);
[self setByteOrder:MISC_LITTLEENDIAN];
}
else
{
for (i = 0; i < count; i++)
temp[i] = NSSwapLittleLongToHost(temp[i]);
[self setByteOrder:MISC_LITTLEENDIAN];
}
}
}
- (void)swapIntToHost
{
unsigned char curHostOrder = [self hostOrder];
if (byteOrder != curHostOrder) {
int *temp = (int *)[data mutableBytes];
unsigned i, count = ([data length] / sizeof(int));
if (byteOrder == MISC_BIGENDIAN) {
for (i = 0; i < count; i++)
temp[i] = NSSwapBigIntToHost(temp[i]);
[self setByteOrder:MISC_LITTLEENDIAN];
}
else
{
for (i = 0; i < count; i++)
temp[i] = NSSwapLittleIntToHost(temp[i]);
[self setByteOrder:MISC_LITTLEENDIAN];
}
}
}
- (void)swapShortToHost
{
unsigned char curHostOrder = [self hostOrder];
if (byteOrder != curHostOrder) {
short *temp = (short *)[data mutableBytes];
unsigned i, count = ([data length] / sizeof(short));
if (byteOrder == MISC_BIGENDIAN) {
for (i = 0; i < count; i++)
temp[i] = NSSwapBigShortToHost(temp[i]);
[self setByteOrder:MISC_LITTLEENDIAN];
}
else
{
for (i = 0; i < count; i++)
temp[i] = NSSwapLittleShortToHost(temp[i]);
[self setByteOrder:MISC_LITTLEENDIAN];
}
}
}
- (void)swapToHost{
if (type) {
switch (type) {
case 'i' : [self swapIntToHost];
break;
case 'l' : [self swapLongToHost];
break;
case 's' : [self swapShortToHost];
break;
case 'f' : [self swapFloatToHost];
break;
case 'd' : [self swapDoubleToHost];
break;
}
}
}
- (void)encodeWithCoder:(NSCoder *)coder
{
[coder encodeValueOfObjCType:@encode(unsigned char) at:&byteOrder];
[coder encodeValueOfObjCType:@encode(unsigned char) at:&type];
[coder encodeDataObject:data];
}
- (id)initWithCoder:(NSCoder *)coder
{
[coder decodeValueOfObjCType:@encode(unsigned char) at:&byteOrder];
[coder decodeValueOfObjCType:@encode(unsigned char) at:&type];
data = [[NSMutableData dataWithData:[coder decodeDataObject]] retain];
[self swapToHost];
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.