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.