* Headers/Additions/GNUstepBase/GSObjCRuntime.h/m:

(GSClassList): New function.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@19264 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
ayers 2004-05-07 16:26:50 +00:00
parent 3ecbf4a4a0
commit c415f0628a
3 changed files with 106 additions and 0 deletions

View file

@ -1,3 +1,8 @@
2004-05-06 David Ayers <d.ayers@inode.at>
* Headers/Additions/GNUstepBase/GSObjCRuntime.h/m:
(GSClassList): New function.
2004-05-07 Richard Frith-Macdonald <rfm@gnu.org>
* configure.ac: don't attempt to find xslt support if xml support

View file

@ -123,6 +123,24 @@ GSObjCSetValue(NSObject *self, NSString *key, id val, SEL sel,
#define GS_STATIC_INLINE static inline
/**
* Fills a nil terminated array of Class objects referenced by buffer
* with max number of classes registered with the objc runtime.
* The provided buffer must be large enough to hold max + 1 Class objects.
* If buffer is nil, the function returns the number of Class
* objects that would be inserted if the buffer is large enough.
* Otherwise returns the number of Class objects that did not fit
* into the provided buffer. This function keeps a cache of the class
* list for future invocations when used with the GNU runtime. If
* clearCache is YES, this cache will be invalidated and rebuild. The
* flag has no effect for the NeXT runtime.
* This function is provided as consistent API to both runtimes.
* In the case of the GNU runtime it is likely more efficient to use
* objc_next_class() to iterate over the classes.
*/
GS_EXPORT unsigned int
GSClassList(Class *buffer, unsigned int max, BOOL clearCache);
/**
* GSObjCClass() return the class of an instance.
* Returns a nul pointer if the argument is nil.

View file

@ -323,6 +323,89 @@ GSObjCSetVariable(id obj, int offset, unsigned int size, const void *data)
memcpy(((void*)obj) + offset, data, size);
}
GS_EXPORT unsigned int
GSClassList(Class *buffer, unsigned int max, BOOL clearCache)
{
#ifdef NeXT_RUNTIME
int num;
if (buffer != NULL)
{
memset(buffer, 0, sizeof(Class) * (max + 1));
}
num = objc_getClassList(buffer, max);
num = (num < 0) ? 0 : num;
#else
static Class *cache = 0;
static unsigned cacheClassCount = 0;
static volatile objc_mutex_t cache_lock = NULL;
unsigned int num;
if (cache_lock == NULL)
{
GSAllocateMutexAt((void*)&cache_lock);
}
objc_mutex_lock(cache_lock);
if (clearCache)
{
if (cache)
{
objc_free(cache);
cache = NULL;
}
cacheClassCount = 0;
}
if (cache == NULL)
{
void *iterator = 0;
Class cls;
unsigned int i;
cacheClassCount = 0;
while ((cls = objc_next_class(&iterator)))
{
cacheClassCount++;
}
cache = objc_malloc(sizeof(Class) * (cacheClassCount + 1));
/* Be extra careful as another thread may be loading classes. */
for (i = 0, iterator = 0, cls = objc_next_class(&iterator);
i < cacheClassCount && cls != NULL;
i++, cls = objc_next_class(&iterator))
{
cache[i] = cls;
}
cache[i] = NULL;
}
if (buffer == NULL)
{
num = cacheClassCount;
}
else
{
size_t cpySize;
unsigned int cpyCnt;
cpyCnt = MIN(max, cacheClassCount);
cpySize = sizeof(Class) * cpyCnt;
memcpy(buffer, cache, cpySize);
buffer[cpyCnt] = NULL;
num = (max > cacheClassCount) ? 0 : (cacheClassCount - max);
}
objc_mutex_unlock(cache_lock);
#endif
return num;
}
/*
* NOTE - OBJC_VERSION needs to be defined to be the version of the
* Objective-C runtime you are using. You can find this in the file