mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-23 09:04:13 +00:00
* 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:
parent
3ecbf4a4a0
commit
c415f0628a
3 changed files with 106 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue