coding fixes

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@8569 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2001-01-12 16:48:33 +00:00
parent 559db76abd
commit ead63e6999
4 changed files with 220 additions and 21 deletions

View file

@ -6,10 +6,12 @@
* Source/GNUmakefile: Rename value files to GS prefix and remove
concrete value header.
* Source/Makefile.postamble: Build GS value files. rather than NS
* Source/NSValue.m: Added range meethods and updated for change to
naming conventions.
* Source/NSValue.m: Added range methods and updated for change to
naming conventions. Added abstract placeholder class. Fixed encoding
to store the abstract class in the archive.
* Testing/values.m: Added range check
* Source/GSTemplateValue.m: Renamed for consistency.
Adapted encoding/decoding for storing abstract class in archive.
* Source/GSValue.m: ditto
* Headers/gnustep/base/NSConcreteValue.h: private info removed
* Source/NSCTemplateValue.m: Renamed for consistency

View file

@ -252,6 +252,10 @@
[NSException raise: NSInternalInconsistencyException
format: @"Attempt to encode a pointer to void object"];
#else
const char *objctype = @encode(TYPE_NAME);
unsigned size = strlen(objctype)+1;
[coder encodeValueOfObjCType: @encode(unsigned) at: &size];
[coder encodeArrayOfObjCType: @encode(char) count: size at: objctype];
[coder encodeValueOfObjCType: @encode(TYPE_NAME) at: &data];
#endif
}

View file

@ -3,6 +3,8 @@
Written by: Adam Fedor <fedor@boulder.colorado.edu>
Date: Mar 1995
Updated by: Richard frith-Macdonald <rfm@gnu.org>
Date: Jan 2001
This file is part of the GNUstep Base Library.
@ -27,6 +29,13 @@
#include <Foundation/NSCoder.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSZone.h>
#include <Foundation/NSException.h>
#include <Foundation/NSMapTable.h>
#include <Foundation/NSLock.h>
#include <Foundation/NSDebug.h>
@interface GSPlaceholderValue : NSValue
@end
@class GSValue;
@class GSNonretainedObjectValue;
@ -44,7 +53,12 @@ static Class pointerValueClass;
static Class rangeValueClass;
static Class rectValueClass;
static Class sizeValueClass;
static Class GSPlaceholderValueClass;
static GSPlaceholderValue *defaultPlaceholderValue;
static NSMapTable *placeholderMap;
static NSLock *placeholderLock;
@implementation NSValue
@ -60,23 +74,59 @@ static Class sizeValueClass;
rangeValueClass = [GSRangeValue class];
rectValueClass = [GSRectValue class];
sizeValueClass = [GSSizeValue class];
}
}
GSPlaceholderValueClass = [GSPlaceholderValue class];
+ (id) alloc
{
if (self == abstractClass)
return NSAllocateObject(concreteClass, 0, NSDefaultMallocZone());
else
return NSAllocateObject(self, 0, NSDefaultMallocZone());
/*
* Set up infrastructure for placeholder values.
*/
defaultPlaceholderValue = (GSPlaceholderValue*)
NSAllocateObject(GSPlaceholderValueClass, 0, NSDefaultMallocZone());
placeholderMap = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
NSNonRetainedObjectMapValueCallBacks, 0);
placeholderLock = [NSLock new];
}
}
+ (id) allocWithZone: (NSZone*)z
{
if (self == abstractClass)
return NSAllocateObject(concreteClass, 0, z);
{
if (z == NSDefaultMallocZone() || z == 0)
{
/*
* As a special case, we can return a placeholder for a value
* in the default malloc zone extremely efficiently.
*/
return defaultPlaceholderValue;
}
else
{
id obj;
/*
* For anything other than the default zone, we need to
* locate the correct placeholder in the (lock protected)
* table of placeholders.
*/
[placeholderLock lock];
obj = (id)NSMapGet(placeholderMap, (void*)z);
if (obj == nil)
{
/*
* There is no placeholder object for this zone, so we
* create a new one and use that.
*/
obj = (id)NSAllocateObject(GSPlaceholderValueClass, 0, z);
NSMapInsert(placeholderMap, (void*)z, (void*)obj);
}
[placeholderLock unlock];
return obj;
}
}
else
return NSAllocateObject(self, 0, z);
{
return NSAllocateObject(self, 0, z);
}
}
// NSCopying - always a simple retain.
@ -198,10 +248,16 @@ static Class sizeValueClass;
{
NSDictionary *dict = [string propertyList];
if (!dict)
if (dict == nil)
return nil;
if ([dict objectForKey: @"width"] && [dict objectForKey: @"x"])
if ([dict objectForKey: @"location"])
{
NSRange range;
range = NSMakeRange([[dict objectForKey: @"location"] intValue],
[[dict objectForKey: @"length"] intValue]);
}
else if ([dict objectForKey: @"width"] && [dict objectForKey: @"x"])
{
NSRect rect;
rect = NSMakeRect([[dict objectForKey: @"x"] floatValue],
@ -297,18 +353,149 @@ static Class sizeValueClass;
return NSMakePoint(0,0);
}
// NSCoding (done by subclasses)
- (Class) classForCoder
{
return abstractClass;
}
- (void) encodeWithCoder: (NSCoder *)coder
{
[self subclassResponsibility: _cmd];
unsigned size;
char *data;
const char *objctype = [self objCType];
size = strlen(objctype)+1;
[coder encodeValueOfObjCType: @encode(unsigned) at: &size];
[coder encodeArrayOfObjCType: @encode(char) count: size at: objctype];
size = objc_sizeof_type(objctype);
data = (void *)NSZoneMalloc(GSObjCZone(self), size);
[self getValue: (void*)data];
[coder encodeValueOfObjCType: @encode(unsigned) at: &size];
[coder encodeArrayOfObjCType: @encode(unsigned char) count: size at: data];
NSZoneFree(NSDefaultMallocZone(), data);
}
- (id) initWithCoder: (NSCoder *)coder
{
[self subclassResponsibility: _cmd];
const char *objctype;
Class c;
id o;
unsigned size;
[coder decodeValueOfObjCType: @encode(unsigned) at: &size];
objctype = (void*)NSZoneMalloc(NSDefaultMallocZone(), size);
[coder decodeArrayOfObjCType: @encode(char) count: size at: (void*)objctype];
c = [abstractClass valueClassWithObjCType: objctype];
o = [c alloc];
/*
* Special case classes can decode themselves.
*/
if (c == pointValueClass || c == rangeValueClass
|| c == rectValueClass || c == sizeValueClass)
{
o = [o initWithCoder: coder];
}
else
{
char *data;
size = objc_sizeof_type(objctype);
data = (void *)NSZoneMalloc(NSDefaultMallocZone(), size);
[coder decodeArrayOfObjCType: @encode(unsigned char)
count: size
at: data];
o = [o initWithBytes: data objCType: objctype];
NSZoneFree(NSDefaultMallocZone(), data);
}
NSZoneFree(NSDefaultMallocZone(), (void*)objctype);
RELEASE(self);
self = o;
return self;
}
@end
@implementation GSPlaceholderValue
- (id) autorelease
{
NSWarnLog(@"-autorelease sent to uninitialised value");
return self; // placeholders never get released.
}
- (void) dealloc
{
return; // placeholders never get deallocated.
}
- (void) getData: (void*)data
{
[NSException raise: NSInternalInconsistencyException
format: @"attempt to use uninitialised value"];
}
- (id) initWithCoder: (NSCoder *)coder
{
const char *objctype;
Class c;
id o;
unsigned size;
[coder decodeValueOfObjCType: @encode(unsigned) at: &size];
objctype = (void*)NSZoneMalloc(NSDefaultMallocZone(), size);
[coder decodeArrayOfObjCType: @encode(char) count: size at: (void*)objctype];
c = [abstractClass valueClassWithObjCType: objctype];
o = [c alloc];
/*
* Special case classes can decode themselves.
*/
if (c == pointValueClass || c == rangeValueClass
|| c == rectValueClass || c == sizeValueClass)
{
o = [o initWithCoder: coder];
}
else
{
char *data;
size = objc_sizeof_type(objctype);
data = (void *)NSZoneMalloc(NSDefaultMallocZone(), size);
[coder decodeArrayOfObjCType: @encode(unsigned char)
count: size
at: data];
o = [o initWithBytes: data objCType: objctype];
NSZoneFree(NSDefaultMallocZone(), data);
}
NSZoneFree(NSDefaultMallocZone(), (void*)objctype);
self = o;
return self;
}
- (id) initWithBytes: (const void*)data objCType: (const char*)type
{
Class c = [abstractClass valueClassWithObjCType: type];
self = (id)NSAllocateObject(c, 0, GSObjCZone(self));
return [self initWithBytes: data objCType: type];
}
- (const char*) objCType
{
[NSException raise: NSInternalInconsistencyException
format: @"attempt to use uninitialised value"];
return 0;
}
- (void) release
{
return; // placeholders never get released.
}
- (id) retain
{
return self; // placeholders never get retained.
}
@end

View file

@ -7,6 +7,7 @@
#include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSSet.h>
#include <Foundation/NSUtilities.h>
#include <Foundation/NSValue.h>
#include <Foundation/NSDate.h>
int main()
@ -24,14 +25,19 @@ int main()
/* Create a Set of int's */
set = [[NSSet alloc] initWithObjects:
@"apple", @"banana", @"carrot", @"dal", @"escarole", @"fava", nil];
@"apple", @"banana", @"carrot", @"dal", @"escarole", @"fava",
[NSValue valueWithPoint: NSMakePoint(1,1)],
[NSValue valueWithSize: NSMakeSize(11,11)],
[NSValue valueWithRange: NSMakeRange(10,2)],
[NSValue valueWithRect: NSMakeRect(11,11,22,22)],
nil];
/* Display the set */
printf("Writing:\n");
{
id o, e = [set objectEnumerator];
while ((o = [e nextObject]))
printf("%s\n", [o cString]);
printf("%s\n", [[o description] cString]);
}
apl = [[NSAutoreleasePool alloc] init];
@ -73,7 +79,7 @@ printf("%u\n", [arc retainCount]);
{
id o, e = [set objectEnumerator];
while ((o = [e nextObject]))
printf("%s\n", [o cString]);
printf("%s\n", [[o description] cString]);
}
#if 0