git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@8220 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2000-11-28 09:29:21 +00:00
parent fe09500665
commit e23b85fd1a
3 changed files with 64 additions and 108 deletions

View file

@ -71,7 +71,14 @@ GS_EXPORT void NSLogv (NSString* format, va_list args);
#define FOUNDATION_STATIC_INLINE static inline
#ifndef NO_GNUSTEP
/*
* Functions for accessing instance variables directly -
* We can copy an ivar into arbitrary data,
* Get the type encoding for a named ivar,
* and copy a value into an ivar.
*/
GS_EXPORT BOOL GSGetInstanceVariable(id obj, NSString *name, void* data);
GS_EXPORT const char *GSInstanceVariableType(id obj, NSString *name);
GS_EXPORT BOOL GSSetInstanceVariable(id obj, NSString *name, const void* data);
/*

View file

@ -74,20 +74,20 @@ NSGetSizeAndAlignment(const char *typePtr, unsigned *sizep, unsigned *alignp)
BOOL
GSGetInstanceVariable(id obj, NSString *iVarName, void *data)
{
const char *name = [iVarName cString];
Class class;
const char *name = [iVarName cString];
Class class;
struct objc_ivar_list *ivars;
struct objc_ivar *ivar = 0;
int offset;
const char *type;
unsigned int size;
int offset;
const char *type;
unsigned int size;
class = [obj class];
while (class != nil && ivar == 0)
{
ivars = class->ivars;
class = class->super_class;
if (ivars)
if (ivars != 0)
{
int i;
@ -103,7 +103,6 @@ GSGetInstanceVariable(id obj, NSString *iVarName, void *data)
}
if (ivar == 0)
{
NSLog(@"Attempt to get non-existent ivar '%s'", name);
return NO;
}
@ -114,23 +113,58 @@ GSGetInstanceVariable(id obj, NSString *iVarName, void *data)
return YES;
}
BOOL
GSSetInstanceVariable(id obj, NSString *iVarName, const void *data)
const char*
GSInstanceVariableType(id obj, NSString *iVarName)
{
const char *name = [iVarName cString];
Class class;
const char *name = [iVarName cString];
Class class;
struct objc_ivar_list *ivars;
struct objc_ivar *ivar = 0;
int offset;
const char *type;
unsigned int size;
class = [obj class];
while (class != nil && ivar == 0)
{
ivars = class->ivars;
class = class->super_class;
if (ivars)
if (ivars != 0)
{
int i;
for (i = 0; i < ivars->ivar_count; i++)
{
if (strcmp(ivars->ivar_list[i].ivar_name, name) == 0)
{
ivar = &ivars->ivar_list[i];
break;
}
}
}
}
if (ivar == 0)
{
return 0;
}
return ivar->ivar_type;
}
BOOL
GSSetInstanceVariable(id obj, NSString *iVarName, const void *data)
{
const char *name = [iVarName cString];
Class class;
struct objc_ivar_list *ivars;
struct objc_ivar *ivar = 0;
int offset;
const char *type;
unsigned int size;
class = [obj class];
while (class != nil && ivar == 0)
{
ivars = class->ivars;
class = class->super_class;
if (ivars != 0)
{
int i;
@ -146,7 +180,6 @@ GSSetInstanceVariable(id obj, NSString *iVarName, const void *data)
}
if (ivar == 0)
{
NSLog(@"Attempt to set non-existent ivar '%s'", name);
return NO;
}

View file

@ -1281,90 +1281,6 @@ static BOOL deallocNotifications = NO;
#include <Foundation/NSNull.h>
static BOOL
GSGetValue(id obj, NSString *iVarName, id *data)
{
const char *name = [iVarName cString];
Class class;
struct objc_ivar_list *ivars;
struct objc_ivar *ivar = 0;
int offset;
const char *type;
unsigned int size;
class = [obj class];
while (class != nil && ivar == 0)
{
ivars = class->ivars;
class = class->super_class;
if (ivars != 0)
{
int i;
for (i = 0; i < ivars->ivar_count; i++)
{
if (strcmp(ivars->ivar_list[i].ivar_name, name) == 0)
{
ivar = &ivars->ivar_list[i];
break;
}
}
}
}
if (ivar == 0)
{
return NO;
}
offset = ivar->ivar_offset;
type = ivar->ivar_type;
size = objc_sizeof_type(type);
memcpy(data, ((void*)obj) + offset, size);
return YES;
}
static BOOL
GSSetValue(id obj, NSString *iVarName, id *data)
{
const char *name = [iVarName cString];
Class class;
struct objc_ivar_list *ivars;
struct objc_ivar *ivar = 0;
int offset;
const char *type;
unsigned int size;
class = [obj class];
while (class != nil && ivar == 0)
{
ivars = class->ivars;
class = class->super_class;
if (ivars != 0)
{
int i;
for (i = 0; i < ivars->ivar_count; i++)
{
if (strcmp(ivars->ivar_list[i].ivar_name, name) == 0)
{
ivar = &ivars->ivar_list[i];
break;
}
}
}
}
if (ivar == 0)
{
return NO;
}
offset = ivar->ivar_offset;
type = ivar->ivar_type;
size = objc_sizeof_type(type);
memcpy(((void*)obj) + offset, data, size);
return YES;
}
@implementation NSObject (KeyValueCoding)
+ (BOOL) accessInstanceVariablesDirectly
@ -1413,12 +1329,12 @@ GSSetValue(id obj, NSString *iVarName, id *data)
{
id v;
if (GSGetValue(self, [NSString stringWithFormat: @"_%@", aKey],
if (GSGetInstanceVariable(self, [NSString stringWithFormat: @"_%@", aKey],
(void*)&v) == YES)
{
return v;
}
if (GSGetValue(self, aKey, (void*)&v) == YES)
if (GSGetInstanceVariable(self, aKey, (void*)&v) == YES)
{
return v;
}
@ -1460,12 +1376,12 @@ GSSetValue(id obj, NSString *iVarName, id *data)
if ([[self class] accessInstanceVariablesDirectly] == YES)
{
if (GSSetValue(self, [NSString stringWithFormat: @"_%@", aKey],
if (GSSetInstanceVariable(self, [NSString stringWithFormat: @"_%@", aKey],
(void*)&anObject) == YES)
{
return;
}
if (GSSetValue(self, aKey, (void*)&anObject) == YES)
if (GSSetInstanceVariable(self, aKey, (void*)&anObject) == YES)
{
return;
}
@ -1504,12 +1420,12 @@ GSSetValue(id obj, NSString *iVarName, id *data)
if ([[self class] accessInstanceVariablesDirectly] == YES)
{
if (GSSetValue(self, [NSString stringWithFormat: @"_%@", aKey],
if (GSSetInstanceVariable(self, [NSString stringWithFormat: @"_%@", aKey],
(void*)&anObject) == YES)
{
return;
}
if (GSSetValue(self, aKey, (void*)&anObject) == YES)
if (GSSetInstanceVariable(self, aKey, (void*)&anObject) == YES)
{
return;
}
@ -1591,12 +1507,12 @@ GSSetValue(id obj, NSString *iVarName, id *data)
{
id v;
if (GSGetValue(self, [NSString stringWithFormat: @"_%@", aKey],
if (GSGetInstanceVariable(self, [NSString stringWithFormat: @"_%@", aKey],
(void*)&v) == YES)
{
return v;
}
if (GSGetValue(self, aKey, (void*)&v) == YES)
if (GSGetInstanceVariable(self, aKey, (void*)&v) == YES)
{
return v;
}