mirror of
https://github.com/gnustep/libs-gdl2.git
synced 2025-04-25 05:40:55 +00:00
Fixes inEOAttribute.m and EOKeyValueARchiver.m
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gdl2/trunk@21153 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
8bab203b96
commit
9c4a91f7ce
4 changed files with 420 additions and 173 deletions
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
|||
2005-04-20 Manuel Guesdon <mguesdon@orange-concept.com>
|
||||
|
||||
* EOControl/EOPriv.h: added GDL2_allocWithZone()
|
||||
* EOAccess/EOAttribute.m:
|
||||
o fixed -validateValue: rewritten following
|
||||
David Ayers's advices to handle EONull values
|
||||
validation and fix width validation
|
||||
o fixed -newValueForBytes:length: retain problems and
|
||||
wrong invocation target
|
||||
o fixed -newValueForBytes:length:encoding: retain
|
||||
problems and wrong invocation target
|
||||
o added comments and doc
|
||||
o added allowsNull in EOAttribute -description
|
||||
* EOControl/EOKeyValueArchiver.m: fixed int and bool
|
||||
archiving following David Ayers's comments (produce
|
||||
NSNumber instead of NSString)
|
||||
|
||||
2005-04-24 Matt Rice <ratmice@yahoo.com>
|
||||
|
||||
* EOAdaptors/Postgres95/Postgres95Adaptor.m: Removed externalTypeNames
|
||||
|
|
|
@ -441,10 +441,11 @@ RCS_ID("$Id$")
|
|||
[self columnName],
|
||||
[self definition]];
|
||||
|
||||
dscr = [dscr stringByAppendingFormat: @"valueClassName=%@ valueType=%@ externalType=%@ isReadOnly=%s isDerived=%s isFlattened=%s>",
|
||||
dscr = [dscr stringByAppendingFormat: @"valueClassName=%@ valueType=%@ externalType=%@ allowsNull=%s isReadOnly=%s isDerived=%s isFlattened=%s>",
|
||||
[self valueClassName],
|
||||
[self valueType],
|
||||
[self externalType],
|
||||
([self allowsNull] ? "YES" : "NO"),
|
||||
([self isReadOnly] ? "YES" : "NO"),
|
||||
([self isDerived] ? "YES" : "NO"),
|
||||
([self isFlattened] ? "YES" : "NO")];
|
||||
|
@ -1078,17 +1079,18 @@ return nexexp
|
|||
|
||||
|
||||
/**
|
||||
* Returns an NSString or a custom-class value object
|
||||
* Returns an NSData or a custom-class value object
|
||||
* from the supplied set of bytes.
|
||||
* The Adaptor calls this method during value creation
|
||||
* when fetching objects from the database.
|
||||
* For efficiency, the returned value is NOT autoreleased.
|
||||
*
|
||||
* NB: The documentation of the reference implementation
|
||||
* mistakenly claims that it returns an NSString.
|
||||
**/
|
||||
- (id)newValueForBytes: (const void *)bytes
|
||||
length: (int)length
|
||||
{
|
||||
NSMethodSignature *aSignature;
|
||||
NSInvocation *anInvocation;
|
||||
NSData *value = nil;
|
||||
Class valueClass = [self _valueClass];
|
||||
|
||||
|
@ -1097,43 +1099,79 @@ return nexexp
|
|||
switch (_argumentType)
|
||||
{
|
||||
case EOFactoryMethodArgumentIsNSData:
|
||||
{
|
||||
//For efficiency reasons, the returned value is NOT autoreleased !
|
||||
value = [GDL2_alloc(NSData) initWithBytes: bytes length: length];
|
||||
|
||||
// If we have a value factiry method, call it to get the final value
|
||||
if(_valueFactoryMethod != NULL)
|
||||
{
|
||||
//TODO: doc says that the returned value is autoreleased !!
|
||||
NSData* tmp = value;
|
||||
// valueFactoryMethod returns an autoreleased value
|
||||
value = [(id)valueClass performSelector: _valueFactoryMethod
|
||||
withObject: [value autorelease]];
|
||||
withObject: value];
|
||||
if (value != value)
|
||||
{
|
||||
RETAIN(value);
|
||||
RELEASE(tmp);
|
||||
};
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case EOFactoryMethodArgumentIsBytes:
|
||||
//For efficiency reasons, the returned value is NOT autoreleased !
|
||||
value = [valueClass allocWithZone: 0];
|
||||
{
|
||||
NSMethodSignature *aSignature = nil;
|
||||
NSInvocation *anInvocation = nil;
|
||||
|
||||
// TODO: verify with WO
|
||||
NSAssert2(_valueFactoryMethod,
|
||||
@"No _valueFactoryMethod (valueFactoryMethodName=%@) in attribute %@",
|
||||
_valueFactoryMethodName,self);
|
||||
|
||||
// First find signature for method
|
||||
aSignature =
|
||||
[valueClass
|
||||
instanceMethodSignatureForSelector: _valueFactoryMethod];
|
||||
methodSignatureForSelector: _valueFactoryMethod];
|
||||
|
||||
// Create the invocation object
|
||||
anInvocation
|
||||
= [NSInvocation invocationWithMethodSignature: aSignature];
|
||||
|
||||
// Put the selector
|
||||
[anInvocation setSelector: _valueFactoryMethod];
|
||||
[anInvocation setTarget: value];
|
||||
|
||||
// The target is the custom value class
|
||||
[anInvocation setTarget: valueClass];
|
||||
|
||||
// arguments are buffer pointer and length
|
||||
[anInvocation setArgument: &bytes atIndex: 2];
|
||||
[anInvocation setArgument: &length atIndex: 3];
|
||||
[anInvocation invoke];
|
||||
break;
|
||||
|
||||
// Let's invoke the method
|
||||
[anInvocation invoke];
|
||||
|
||||
// Get the returned value
|
||||
[anInvocation getReturnValue: &value];
|
||||
|
||||
//For efficiency reasons, the returned value is NOT autoreleased !
|
||||
// valueFactoryMethod returns an autoreleased value
|
||||
RETAIN(value);
|
||||
|
||||
break;
|
||||
}
|
||||
case EOFactoryMethodArgumentIsNSString:
|
||||
// TODO: verify with WO
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!value)
|
||||
{
|
||||
//For efficiency reasons, the returned value is NOT autoreleased !
|
||||
value = [GDL2_alloc(NSData) initWithBytes: bytes length: length];
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
@ -1149,9 +1187,7 @@ return nexexp
|
|||
length: (int)length
|
||||
encoding: (NSStringEncoding)encoding
|
||||
{
|
||||
NSMethodSignature *aSignature;
|
||||
NSInvocation *anInvocation;
|
||||
id value = nil;
|
||||
NSString* value = nil;
|
||||
Class valueClass = [self _valueClass];
|
||||
|
||||
if (valueClass != Nil && valueClass != GDL2_NSStringClass)
|
||||
|
@ -1160,40 +1196,79 @@ return nexexp
|
|||
{
|
||||
case EOFactoryMethodArgumentIsNSString:
|
||||
{
|
||||
NSData *data;
|
||||
NSString *string;
|
||||
//For efficiency reasons, the returned value is NOT autoreleased !
|
||||
NSData *data = nil;
|
||||
NSString *string = nil;
|
||||
|
||||
data = AUTORELEASE([(GDL2_alloc(NSData)) initWithBytes: bytes
|
||||
length: length]);
|
||||
string = AUTORELEASE([(GDL2_alloc(NSString)) initWithData: data
|
||||
encoding: encoding]);
|
||||
|
||||
string = [(GDL2_alloc(NSString)) initWithData: data
|
||||
encoding: encoding];
|
||||
|
||||
// If we have a value factiry method, call it to get the final value
|
||||
if(_valueFactoryMethod != NULL)
|
||||
{
|
||||
value = [((id)valueClass) performSelector: _valueFactoryMethod
|
||||
withObject: string];
|
||||
if ( value != string)
|
||||
{
|
||||
//For efficiency reasons, the returned value is NOT autoreleased !
|
||||
RETAIN(value);
|
||||
RELEASE(string);
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
//For efficiency reasons, the returned value is NOT autoreleased !
|
||||
value = string;
|
||||
};
|
||||
break;
|
||||
}
|
||||
|
||||
case EOFactoryMethodArgumentIsBytes:
|
||||
{
|
||||
//For efficiency reasons, the returned value is NOT autoreleased !
|
||||
value = [valueClass alloc];
|
||||
NSMethodSignature *aSignature = nil;
|
||||
NSInvocation *anInvocation = nil;
|
||||
|
||||
// TODO: verify with WO
|
||||
NSAssert2(_valueFactoryMethod,
|
||||
@"No _valueFactoryMethod (valueFactoryMethodName=%@) in attribute %@",
|
||||
_valueFactoryMethodName,self);
|
||||
|
||||
// First find signature for method
|
||||
aSignature
|
||||
= [valueClass instanceMethodSignatureForSelector: _valueFactoryMethod];
|
||||
= [valueClass methodSignatureForSelector: _valueFactoryMethod];
|
||||
|
||||
// Create the invocation object
|
||||
anInvocation
|
||||
= [NSInvocation invocationWithMethodSignature: aSignature];
|
||||
|
||||
// Put the selector
|
||||
[anInvocation setSelector: _valueFactoryMethod];
|
||||
[anInvocation setTarget: value];
|
||||
|
||||
// The target is the custom value class
|
||||
[anInvocation setTarget: valueClass];
|
||||
|
||||
// arguments are buffer pointer, length and encoding
|
||||
[anInvocation setArgument: &bytes atIndex: 2];
|
||||
[anInvocation setArgument: &length atIndex: 3];
|
||||
[anInvocation setArgument: &encoding atIndex: 4];
|
||||
|
||||
// Let's invoke the method
|
||||
[anInvocation invoke];
|
||||
|
||||
// Get the returned value
|
||||
[anInvocation getReturnValue: &value];
|
||||
|
||||
//For efficiency reasons, the returned value is NOT autoreleased !
|
||||
// valueFactoryMethod returns an autoreleased value
|
||||
RETAIN(value);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case EOFactoryMethodArgumentIsNSData:
|
||||
// TODO: verify with WO
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1201,9 +1276,10 @@ return nexexp
|
|||
if(!value)
|
||||
{
|
||||
NSData *data;
|
||||
//For efficiency reasons, the returned value is NOT autoreleased !
|
||||
data = AUTORELEASE([(GDL2_alloc(NSData)) initWithBytes: bytes
|
||||
length: length]);
|
||||
|
||||
//For efficiency reasons, the returned value is NOT autoreleased !
|
||||
value = [(GDL2_alloc(NSString)) initWithData: data
|
||||
encoding: encoding];
|
||||
}
|
||||
|
@ -1217,6 +1293,8 @@ return nexexp
|
|||
* The Adaptor calls this method during value creation
|
||||
* when fetching objects from the database.
|
||||
* For efficiency, the returned value is NOT autoreleased.
|
||||
* Milliseconds are dropped since they cannot be easily be stored in
|
||||
* NSCalendarDate.
|
||||
**/
|
||||
- (NSCalendarDate *)newDateForYear: (int)year
|
||||
month: (unsigned)month
|
||||
|
@ -1228,10 +1306,12 @@ return nexexp
|
|||
timezone: (NSTimeZone *)timezone
|
||||
zone: (NSZone *)zone
|
||||
{
|
||||
NSCalendarDate *date;
|
||||
NSCalendarDate *date = nil;
|
||||
|
||||
// FIXME: extend initializer to include Milliseconds
|
||||
|
||||
//For efficiency reasons, the returned value is NOT autoreleased !
|
||||
date = [[GDL2_NSCalendarDateClass allocWithZone: zone]
|
||||
date = [(GDL2_allocWithZone(NSCalendarDate,zone))
|
||||
initWithYear: year
|
||||
month: month
|
||||
day: day
|
||||
|
@ -1240,8 +1320,6 @@ return nexexp
|
|||
second: second
|
||||
timeZone: timezone];
|
||||
|
||||
// TODO milliseconds ??
|
||||
|
||||
return date;
|
||||
}
|
||||
|
||||
|
@ -1410,6 +1488,23 @@ EOAdaptorDateType Date value (attribute valueClass is kind of NSDate)
|
|||
return _adaptorValueType;
|
||||
}
|
||||
|
||||
|
||||
/** Returns the type of argument needed by the factoryMethod.
|
||||
|
||||
Type can be:
|
||||
|
||||
EOFactoryMethodArgumentIsNSData
|
||||
method need one parameter: a NSData
|
||||
|
||||
EOFactoryMethodArgumentIsNSString
|
||||
method need one parameter: a NSString
|
||||
|
||||
EOFactoryMethodArgumentIsBytes
|
||||
method need 2 parameters (for data type valueClass): a raw bytes buffer and its length
|
||||
or 3 parameters (for string type valueClass): a raw bytes buffer, its length and the encoding
|
||||
|
||||
See also: -valueFactoryMethod, -setFactoryMethodArgumentType:
|
||||
**/
|
||||
- (EOFactoryMethodArgumentType)factoryMethodArgumentType
|
||||
{
|
||||
return _argumentType;
|
||||
|
@ -1432,6 +1527,13 @@ See also: -setFactoryMethodArgumentType:
|
|||
_valueFactoryMethod = NSSelectorFromString(_valueFactoryMethodName);
|
||||
}
|
||||
|
||||
/** Set method name to use to convert value of a class
|
||||
different than attribute adaptor value type.
|
||||
|
||||
See also: -adaptorValueByConvertingAttributeValue, -adaptorValueConversionMethod,
|
||||
-adaptorValueConversionMethodName
|
||||
**/
|
||||
|
||||
- (void)setAdaptorValueConversionMethodName: (NSString *)conversionMethodName
|
||||
{
|
||||
[self willChange];
|
||||
|
@ -1440,6 +1542,22 @@ See also: -setFactoryMethodArgumentType:
|
|||
_adaptorValueConversionMethod = NSSelectorFromString(_adaptorValueConversionMethodName);
|
||||
}
|
||||
|
||||
/** Set the type of argument needed by the factoryMethod.
|
||||
|
||||
Type can be:
|
||||
|
||||
EOFactoryMethodArgumentIsNSData
|
||||
method need one parameter: a NSData
|
||||
|
||||
EOFactoryMethodArgumentIsNSString
|
||||
method need one parameter: a NSString
|
||||
|
||||
EOFactoryMethodArgumentIsBytes
|
||||
method need 2 parameters (for data type valueClass): a raw bytes buffer and its length
|
||||
or 3 parameters (for string type valueClass): a raw bytes buffer, its length and the encoding
|
||||
|
||||
See also: -setValueFactoryMethodName:, -factoryMethodArgumentType
|
||||
**/
|
||||
- (void)setFactoryMethodArgumentType: (EOFactoryMethodArgumentType)argumentType
|
||||
{
|
||||
[self willChange];
|
||||
|
@ -1451,34 +1569,90 @@ See also: -setFactoryMethodArgumentType:
|
|||
|
||||
@implementation EOAttribute (EOAttributeValueMapping)
|
||||
|
||||
/** Validates value pointed by valueP, may set changed validated value in
|
||||
valueP and return an validation exception if constraints validation fails.
|
||||
valueP must not be NULL.
|
||||
|
||||
More details:
|
||||
1. raise an exception if [self allowsNull] == NO but *valueP is nil or EONull
|
||||
except if attribute is a primaryKey attribute (reason of this process
|
||||
exception is currently unknown).
|
||||
|
||||
2. if valueClassName isn't set, return nil and leave *valueP unchanged
|
||||
|
||||
3. if it can't find the class by name, log message, return nil and
|
||||
leave *valueP unchanged
|
||||
|
||||
4. do the fancy type conversions as necessary (Pretty much the current
|
||||
handling we have)
|
||||
|
||||
5. THEN if width is not 0 call adaptorValueByConvertingAttributeValue:
|
||||
on the new value and the if returned value is NSString or NSData
|
||||
validate length with width and return a corresponding exception
|
||||
if it's longer than allowed.
|
||||
**/
|
||||
|
||||
- (NSException *)validateValue: (id*)valueP
|
||||
{
|
||||
NSException *exception=nil;
|
||||
|
||||
NSAssert(valueP, @"No value pointer");
|
||||
|
||||
if (*valueP == nil && [self allowsNull] == NO)
|
||||
exception = [NSException validationExceptionWithFormat: @"attribute '%@' cannot be nil", [self name]];
|
||||
else if (*valueP)
|
||||
{
|
||||
//call self valueClassName
|
||||
*valueP = [self adaptorValueByConvertingAttributeValue: *valueP];
|
||||
//call attribute width
|
||||
//end !
|
||||
NSDebugMLog(@"In EOAttribute validateValue: value (class=%@) = %@ attribute = %@",
|
||||
[*valueP class],*valueP,self);
|
||||
|
||||
//TODO: revoir
|
||||
// First check if value is nil or EONull
|
||||
if (_isNilOrEONull(*valueP))
|
||||
{
|
||||
//EOEntity *entity = [self entity];
|
||||
//NSArray *pkAttributes = [entity primaryKeyAttributes];
|
||||
//TODO wowhat
|
||||
// Check if this is not allowed
|
||||
if ([self allowsNull] == NO)
|
||||
{
|
||||
NSArray *pkAttributes = [[self entity] primaryKeyAttributes];
|
||||
|
||||
if (*valueP)
|
||||
// "Primary key attributes are ignored when enforcing allowsNull
|
||||
// property for attributes. The values could be handled later
|
||||
// by automatic PK-generation later
|
||||
if ([pkAttributes indexOfObjectIdenticalTo: self] == NSNotFound)
|
||||
{
|
||||
exception =
|
||||
[NSException
|
||||
validationExceptionWithFormat:
|
||||
@"attribute '%@' of entity '%@' cannot be nil or EONull ",
|
||||
[self name],[[self entity] name]];
|
||||
};
|
||||
}
|
||||
}
|
||||
else // There's a value.
|
||||
{
|
||||
NSString* valueClassName=[self valueClassName];
|
||||
|
||||
// if there's no valueClassName, leave the value unchanged
|
||||
// and don't return an exception
|
||||
|
||||
if (valueClassName)
|
||||
{
|
||||
Class valueClass=[self _valueClass];
|
||||
|
||||
if ([*valueP isKindOfClass: valueClass] == NO)
|
||||
// There's a className but no class !
|
||||
if (!valueClass)
|
||||
{
|
||||
if ([*valueP isKindOfClass: GDL2_NSStringClass])
|
||||
//Log this problem, leave the value unchanged
|
||||
// and don't return an exception
|
||||
NSLog(@"No valueClass for valueClassName '%@' in attribute %@",
|
||||
valueClassName,self);
|
||||
}
|
||||
else
|
||||
{
|
||||
unsigned int width = 0;
|
||||
IMP isKindOfClassIMP=[*valueP methodForSelector:@selector(isKindOfClass:)];
|
||||
|
||||
// If the value has not the good class we'll try to convert it
|
||||
if ((*isKindOfClassIMP)(*valueP,@selector(isKindOfClass:),
|
||||
valueClass) == NO)
|
||||
{
|
||||
// Is it a string ?
|
||||
if ((*isKindOfClassIMP)(*valueP,@selector(isKindOfClass:),
|
||||
GDL2_NSStringClass))
|
||||
{
|
||||
if (valueClass == GDL2_NSNumberClass)
|
||||
{
|
||||
|
@ -1486,89 +1660,139 @@ See also: -setFactoryMethodArgumentType:
|
|||
switch(valueTypeChar)
|
||||
{
|
||||
case 'i':
|
||||
*valueP = [NSNumber numberWithInt:
|
||||
*valueP = [GDL2_alloc(NSNumber)
|
||||
initWithInt:
|
||||
[*valueP intValue]];
|
||||
AUTORELEASE(*valueP);
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
*valueP = [NSNumber numberWithUnsignedInt:
|
||||
*valueP = [GDL2_alloc(NSNumber)
|
||||
initWithUnsignedInt:
|
||||
[*valueP unsignedIntValue]];
|
||||
AUTORELEASE(*valueP);
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
*valueP = [NSNumber numberWithChar:
|
||||
*valueP = [GDL2_alloc(NSNumber)
|
||||
initWithChar:
|
||||
[*valueP intValue]];
|
||||
AUTORELEASE(*valueP);
|
||||
break;
|
||||
|
||||
case 'C':
|
||||
*valueP = [NSNumber numberWithUnsignedChar:
|
||||
*valueP = [GDL2_alloc(NSNumber)
|
||||
initWithUnsignedChar:
|
||||
[*valueP unsignedIntValue]];
|
||||
AUTORELEASE(*valueP);
|
||||
break;
|
||||
|
||||
case 's':
|
||||
*valueP = [NSNumber numberWithShort:
|
||||
*valueP = [GDL2_alloc(NSNumber)
|
||||
initWithShort:
|
||||
[*valueP shortValue]];
|
||||
AUTORELEASE(*valueP);
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
*valueP = [NSNumber numberWithUnsignedShort:
|
||||
*valueP = [GDL2_alloc(NSNumber)
|
||||
initWithUnsignedShort:
|
||||
[*valueP unsignedShortValue]];
|
||||
AUTORELEASE(*valueP);
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
*valueP = [NSNumber numberWithLong:
|
||||
*valueP = [GDL2_alloc(NSNumber)
|
||||
initWithLong:
|
||||
[*valueP longValue]];
|
||||
AUTORELEASE(*valueP);
|
||||
break;
|
||||
|
||||
case 'L':
|
||||
*valueP = [NSNumber numberWithUnsignedLong:
|
||||
*valueP = [GDL2_alloc(NSNumber)
|
||||
initWithUnsignedLong:
|
||||
[*valueP unsignedLongValue]];
|
||||
AUTORELEASE(*valueP);
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
*valueP = [NSNumber numberWithLongLong:
|
||||
*valueP = [GDL2_alloc(NSNumber)
|
||||
initWithLongLong:
|
||||
[*valueP longLongValue]];
|
||||
AUTORELEASE(*valueP);
|
||||
break;
|
||||
|
||||
case 'U':
|
||||
*valueP = [NSNumber numberWithUnsignedLongLong:
|
||||
*valueP = [GDL2_alloc(NSNumber)
|
||||
initWithUnsignedLongLong:
|
||||
[*valueP unsignedLongLongValue]];
|
||||
AUTORELEASE(*valueP);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
*valueP = [NSNumber numberWithFloat:
|
||||
*valueP = [GDL2_alloc(NSNumber)
|
||||
initWithFloat:
|
||||
[*valueP floatValue]];
|
||||
AUTORELEASE(*valueP);
|
||||
break;
|
||||
|
||||
default:
|
||||
*valueP = [NSNumber numberWithDouble:
|
||||
*valueP = [GDL2_alloc(NSNumber)
|
||||
initWithDouble:
|
||||
[*valueP doubleValue]];
|
||||
AUTORELEASE(*valueP);
|
||||
break;
|
||||
};
|
||||
}
|
||||
else if (valueClass == GDL2_NSDecimalNumberClass)
|
||||
*valueP = [NSDecimalNumber
|
||||
decimalNumberWithString: *valueP];
|
||||
|
||||
{
|
||||
*valueP = [GDL2_alloc(NSDecimalNumber)
|
||||
initWithString: *valueP];
|
||||
AUTORELEASE(*valueP);
|
||||
}
|
||||
else if (valueClass == GDL2_NSDataClass)
|
||||
{
|
||||
//TODO Verify here.
|
||||
*valueP = [*valueP
|
||||
dataUsingEncoding: NSASCIIStringEncoding
|
||||
allowLossyConversion: YES];
|
||||
|
||||
dataUsingEncoding:
|
||||
[NSString defaultCStringEncoding]];
|
||||
}
|
||||
else if (valueClass == GDL2_NSCalendarDateClass)
|
||||
{
|
||||
*valueP = AUTORELEASE([(GDL2_alloc(NSCalendarDate))
|
||||
initWithString: *valueP]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ([*valueP isKindOfClass: GDL2_NSStringClass])
|
||||
{
|
||||
unsigned width = [self width];
|
||||
};
|
||||
|
||||
if (width && [*valueP length] > width)
|
||||
{
|
||||
const char *buf;
|
||||
// Now, test width if any
|
||||
width = [self width];
|
||||
|
||||
buf = [*valueP cString];
|
||||
*valueP = [NSString stringWithCString: buf
|
||||
length: width];
|
||||
}
|
||||
}
|
||||
else if ([*valueP isKindOfClass: GDL2_NSNumberClass])
|
||||
if (width>0)
|
||||
{
|
||||
// TODO ??
|
||||
}
|
||||
}
|
||||
// First convert value to adaptor value
|
||||
id testValue = [self adaptorValueByConvertingAttributeValue: *valueP];
|
||||
|
||||
if (testValue)
|
||||
{
|
||||
IMP testIsKindOfClassIMP=[testValue methodForSelector:@selector(isKindOfClass:)];
|
||||
|
||||
// We can test NSString and NSData type only
|
||||
if ((*testIsKindOfClassIMP)(testValue,@selector(isKindOfClass:),
|
||||
GDL2_NSStringClass)
|
||||
|| (*testIsKindOfClassIMP)(testValue,@selector(isKindOfClass:),
|
||||
GDL2_NSDataClass))
|
||||
{
|
||||
unsigned int testValueLength = [testValue length];
|
||||
if (testValueLength > width)
|
||||
{
|
||||
exception = [NSException validationExceptionWithFormat:
|
||||
@"Value %@ for attribute '%@' is too large",
|
||||
testValue,[self name]];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ RCS_ID("$Id$")
|
|||
#include <Foundation/NSDictionary.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSDebug.h>
|
||||
#include <Foundation/NSValue.h>
|
||||
#else
|
||||
#include <Foundation/Foundation.h>
|
||||
#endif
|
||||
|
@ -205,7 +206,7 @@ RCS_ID("$Id$")
|
|||
NSDebugMLLog(@"gsdb", @"key=%@ intValue=%d",key,intValue);
|
||||
NSAssert(key,@"No key");
|
||||
|
||||
[_propertyList setObject:[NSString stringWithFormat:@"%d",intValue]
|
||||
[_propertyList setObject: [NSNumber numberWithInt: intValue]
|
||||
forKey: key];
|
||||
|
||||
NSDebugMLLog(@"gsdb", @"_propertyList=%@",_propertyList);
|
||||
|
@ -222,7 +223,7 @@ RCS_ID("$Id$")
|
|||
NSDebugMLLog(@"gsdb", @"key=%@ yn=%s",key,(yn ? "YES" : "NO"));
|
||||
NSAssert(key,@"No key");
|
||||
|
||||
[_propertyList setObject:(yn ? @"YES" : @"NO")
|
||||
[_propertyList setObject: [NSNumber numberWithBool: yn]
|
||||
forKey: key];
|
||||
|
||||
NSDebugMLLog(@"gsdb", @"_propertyList=%@",_propertyList);
|
||||
|
|
|
@ -119,6 +119,11 @@ _isNilOrEONull(id obj)
|
|||
(*GDL2_##CLASS_NAME##_allocWithZoneIMP) \
|
||||
(GDL2_##CLASS_NAME##Class,@selector(allocWithZone:),NULL)
|
||||
|
||||
// ---- +allocWithZone: ----
|
||||
#define GDL2_allocWithZone(CLASS_NAME,ALLOC_ZONE) \
|
||||
(*GDL2_##CLASS_NAME##_allocWithZoneIMP) \
|
||||
(GDL2_##CLASS_NAME##Class,@selector(allocWithZone:),ALLOC_ZONE)
|
||||
|
||||
// ---- NSMutableString appendString: ----
|
||||
#define GDL2_AppendStringWithImp(string,methodIMP,aString) \
|
||||
(*(methodIMP))((string),@selector(appendString:),(aString))
|
||||
|
|
Loading…
Reference in a new issue