mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Tidyup Fast stuff
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@4063 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
6e786ee19f
commit
c76319e5b6
16 changed files with 1363 additions and 243 deletions
19
ChangeLog
19
ChangeLog
|
@ -1,5 +1,22 @@
|
|||
Sun Apr 11 18:22:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
Mon Apr 12 13:15:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* Source/NSCountedSet.m: Make copying behavior be same as OPENSTEP
|
||||
* Source/NSSet.m: Fix memory scribbling bug in ([-initWithSet:])
|
||||
* Source/NSGSet.m: Tidied types in fast map.
|
||||
* Source/NSGArray.m: Minor optimisationin copy etc.
|
||||
* Source/NSGDictionary.m: Tidied types in fast map.
|
||||
* Source/NSSerializer.m: Tidied types in fast map and array.
|
||||
* Source/NSArchiver.m: Tidied types in fast map and array.
|
||||
* Source/NSUnarchiver.m: Tidied types in fast map and array.
|
||||
* Source/FastArray.x: Tidied, fixed init bug, movied to include
|
||||
* Source/FastMap.x: Tidied, moved to include
|
||||
* Source/NSZone.m: Dummy zone for use with GC.
|
||||
* Source/include/NSZone.h: Dummy zone for use with GC.
|
||||
* Source/include/GSUnion.h: Unions for use with Fast...
|
||||
* Source/include/FastArray.x: New from Source
|
||||
* Source/include/FastMap.x: New from Source
|
||||
* Source/GNUmakefile: Added FastArray.x, FastMap.x, GSUnion.h
|
||||
* Source/Makefile.postamble: Added FastArray.x FastMap.x GSUnion.h.
|
||||
* NSCharacterSets/GNUmakefile: List all new character set names.
|
||||
|
||||
Fri Apr 9 22:04:00 1999 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
|
245
Headers/gnustep/base/FastArray.x
Normal file
245
Headers/gnustep/base/FastArray.x
Normal file
|
@ -0,0 +1,245 @@
|
|||
/* A fast inline array table implementation without objc method overhead.
|
||||
* Copyright (C) 1998,1999 Free Software Foundation, Inc.
|
||||
*
|
||||
* Author: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
* Created: Nov 1998
|
||||
*
|
||||
* This file is part of the GNUstep Base Library.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <config.h>
|
||||
#include <Foundation/NSObject.h>
|
||||
#include <Foundation/NSZone.h>
|
||||
|
||||
/* To easily un-inline functions for debugging */
|
||||
#ifndef INLINE
|
||||
#define INLINE inline
|
||||
#endif
|
||||
|
||||
/* To turn assertions on, comment out the following four lines */
|
||||
#ifndef NS_BLOCK_ASSERTIONS
|
||||
#define NS_BLOCK_ASSERTIONS 1
|
||||
#define FAST_ARRAY_BLOCKED_ASSERTIONS 1
|
||||
#endif
|
||||
|
||||
#define FAST_ARRAY_CHECK NSCAssert(array->count <= array->cap && array->old <= array->cap && array->old >= 1, NSInternalInconsistencyException)
|
||||
|
||||
/*
|
||||
* This file should be INCLUDED in files wanting to use the FastArray
|
||||
* functions - these are all declared inline for maximum performance.
|
||||
*
|
||||
* The file including this one may predefine some macros to alter
|
||||
* the behaviour (default macros assume the items are NSObjects
|
||||
* that are to be retained in the array) ...
|
||||
*
|
||||
* FAST_ARRAY_RETAIN()
|
||||
* Macro to retain an array item
|
||||
*
|
||||
* FAST_ARRAY_RELEASE()
|
||||
* Macro to release the item.
|
||||
*
|
||||
* The next two values can be defined in order to let us optimise
|
||||
* even further when either retain or release operations are not needed.
|
||||
*
|
||||
* FAST_ARRAY_NO_RELEASE
|
||||
* Defined if no release operation is needed for an item
|
||||
* FAST_ARRAY_NO_RETAIN
|
||||
* Defined if no retain operation is needed for a an item
|
||||
|
||||
#ifndef FAST_ARRAY_RETAIN
|
||||
#define FAST_ARRAY_RETAIN(X) [(X).obj retain]
|
||||
#endif
|
||||
|
||||
#ifndef FAST_ARRAY_RELEASE
|
||||
#define FAST_ARRAY_RELEASE(X) [(X).obj release]
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If there is no bitmask defined to supply the types that
|
||||
* may be stored in the array, default to permitting all types.
|
||||
*/
|
||||
#ifndef FAST_ARRAY_TYPES
|
||||
#define FAST_ARRAY_TYPES GSUNION_ALL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up the name of the union to store array elements.
|
||||
*/
|
||||
#ifdef GSUNION
|
||||
#undef GSUNION
|
||||
#endif
|
||||
#define GSUNION FastArrayItem
|
||||
|
||||
/*
|
||||
* Set up the types that will be storable in the union.
|
||||
* See 'GSUnion.h' for details.
|
||||
*/
|
||||
#ifdef GSUNION_TYPES
|
||||
#undef GSUNION_TYPES
|
||||
#endif
|
||||
#define GSUNION_TYPES FAST_ARRAY_TYPES
|
||||
#ifdef GSUNION_EXTRA
|
||||
#undef GSUNION_EXTRA
|
||||
#endif
|
||||
#ifdef FAST_ARRAY_EXTRA
|
||||
#define GSUNION_EXTRA FAST_ARRAY_EXTRA
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Generate the union typedef
|
||||
*/
|
||||
#include <base/GSUnion.h>
|
||||
|
||||
|
||||
struct _FastArray {
|
||||
FastArrayItem *ptr;
|
||||
unsigned count;
|
||||
unsigned cap;
|
||||
unsigned old;
|
||||
NSZone *zone;
|
||||
};
|
||||
typedef struct _FastArray FastArray_t;
|
||||
typedef struct _FastArray *FastArray;
|
||||
|
||||
|
||||
static INLINE void
|
||||
FastArrayAddItem(FastArray array, FastArrayItem item)
|
||||
{
|
||||
FAST_ARRAY_RETAIN(item);
|
||||
FAST_ARRAY_CHECK;
|
||||
if (array->count == array->cap)
|
||||
{
|
||||
unsigned next;
|
||||
unsigned size;
|
||||
FastArrayItem *tmp;
|
||||
|
||||
next = array->cap + array->old;
|
||||
size = next*sizeof(FastArrayItem);
|
||||
#if GS_WITH_GC
|
||||
tmp = (FastArrayItem*)GC_REALLOC(size);
|
||||
#else
|
||||
tmp = NSZoneRealloc(array->zone, array->ptr, size);
|
||||
#endif
|
||||
|
||||
if (tmp == 0)
|
||||
{
|
||||
[NSException raise: NSMallocException
|
||||
format: @"failed to grow FastArray"];
|
||||
}
|
||||
array->ptr = tmp;
|
||||
array->old = array->cap;
|
||||
array->cap = next;
|
||||
}
|
||||
array->ptr[array->count++] = item;
|
||||
FAST_ARRAY_CHECK;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastArrayRemoveItemAtIndex(FastArray array, unsigned index)
|
||||
{
|
||||
FastArrayItem tmp;
|
||||
NSCAssert(index < array->count, NSInvalidArgumentException);
|
||||
tmp = array->ptr[index];
|
||||
while (++index < array->count)
|
||||
array->ptr[index-1] = array->ptr[index];
|
||||
array->count--;
|
||||
FAST_ARRAY_RELEASE(tmp);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastArraySetItemAtIndex(FastArray array, FastArrayItem item, unsigned index)
|
||||
{
|
||||
FastArrayItem tmp;
|
||||
NSCAssert(index < array->count, NSInvalidArgumentException);
|
||||
tmp = array->ptr[index];
|
||||
FAST_ARRAY_RETAIN(item);
|
||||
array->ptr[index] = item;
|
||||
FAST_ARRAY_RELEASE(tmp);
|
||||
}
|
||||
|
||||
static INLINE FastArrayItem
|
||||
FastArrayItemAtIndex(FastArray array, unsigned index)
|
||||
{
|
||||
NSCAssert(index < array->count, NSInvalidArgumentException);
|
||||
return array->ptr[index];
|
||||
}
|
||||
|
||||
static INLINE unsigned
|
||||
FastArrayCount(FastArray array)
|
||||
{
|
||||
return array->count;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastArrayClear(FastArray array)
|
||||
{
|
||||
if (array->ptr)
|
||||
{
|
||||
#if GS_WITH_GC
|
||||
GC_FREE((void*)array->ptr);
|
||||
#else
|
||||
NSZoneFree(array->zone, (void*)array->ptr);
|
||||
#endif
|
||||
array->ptr = 0;
|
||||
array->cap = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastArrayEmpty(FastArray array)
|
||||
{
|
||||
#ifdef FAST_ARRAY_NO_RELEASE
|
||||
array->count = 0;
|
||||
#else
|
||||
while (array->count--)
|
||||
{
|
||||
FAST_ARRAY_RELEASE(array->ptr[array->count]);
|
||||
}
|
||||
#endif
|
||||
FastArrayClear(array);
|
||||
}
|
||||
|
||||
static INLINE FastArray
|
||||
FastArrayInitWithZoneAndCapacity(FastArray array, NSZone *zone, size_t capacity)
|
||||
{
|
||||
unsigned size;
|
||||
|
||||
array->zone = zone;
|
||||
array->count = 0;
|
||||
if (capacity < 2)
|
||||
capacity = 2;
|
||||
array->cap = capacity;
|
||||
array->old = capacity/2;
|
||||
size = capacity*sizeof(FastArrayItem);
|
||||
#if GS_WITH_GC
|
||||
/*
|
||||
* If we use a nil zone, objects we point to are subject to GC
|
||||
*/
|
||||
if (zone == 0)
|
||||
array->ptr = (FastArrayItem*)GC_MALLOC_ATOMIC(size);
|
||||
else
|
||||
array->ptr = (FastArrayitem)GC_MALLOC(zone, size);
|
||||
#else
|
||||
array->ptr = (FastArrayItem*)NSZoneMalloc(zone, size);
|
||||
#endif
|
||||
return array;
|
||||
}
|
||||
|
||||
#ifdef FAST_ARRAY_BLOCKED_ASSERTIONS
|
||||
#undef NS_BLOCK_ASSERTIONS
|
||||
#undef FAST_ARRAY_BLOCKED_ASSERTIONS
|
||||
#endif
|
||||
|
745
Headers/gnustep/base/FastMap.x
Normal file
745
Headers/gnustep/base/FastMap.x
Normal file
|
@ -0,0 +1,745 @@
|
|||
/* A fast map/hash table implementation for NSObjects
|
||||
* Copyright (C) 1998,1999 Free Software Foundation, Inc.
|
||||
*
|
||||
* Author: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
* Created: Thu Oct 1 09:30:00 GMT 1998
|
||||
*
|
||||
* Based on original o_map code by Albin L. Jones <Albin.L.Jones@Dartmouth.EDU>
|
||||
*
|
||||
* This file is part of the GNUstep Base Library.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
#include <config.h>
|
||||
#include <Foundation/NSObject.h>
|
||||
#include <Foundation/NSZone.h>
|
||||
|
||||
/* To easily un-inline functions for debugging */
|
||||
#ifndef INLINE
|
||||
#define INLINE inline
|
||||
#endif
|
||||
|
||||
/* To turn assertions on, comment out the following four lines */
|
||||
#ifndef NS_BLOCK_ASSERTIONS
|
||||
#define NS_BLOCK_ASSERTIONS 1
|
||||
#define FAST_MAP_BLOCKED_ASSERTIONS 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This file should be INCLUDED in files wanting to use the FastMap
|
||||
* functions - these are all declared inline for maximum performance.
|
||||
*
|
||||
* The file including this one may predefine some macros to alter
|
||||
* the behaviour
|
||||
*
|
||||
* FAST_MAP_HAS_VALUE
|
||||
* If defined as 0, then this becomes a hash table rather than
|
||||
* a map table.
|
||||
*
|
||||
* FAST_MAP_RETAIN_KEY()
|
||||
* Macro to retain the key item in a map or hash table.
|
||||
*
|
||||
* FAST_MAP_RETAIN_VAL()
|
||||
* Macro to retain the value item in a map table.
|
||||
*
|
||||
* FAST_MAP_RELEASE_KEY()
|
||||
* Macro to release the key item in a map or hash table.
|
||||
*
|
||||
* FAST_MAP_RELEASE_VAL()
|
||||
* Macro to release the value item in a map table.
|
||||
*
|
||||
* FAST_MAP_HASH()
|
||||
* Macro to get the hash of a key item.
|
||||
*
|
||||
* FAST_MAP_EQUAL()
|
||||
* Macro to compare two key items for equality - produces zero
|
||||
* if the items are not equal.
|
||||
*
|
||||
* FAST_MAP_EXTRA
|
||||
* If this value is defined, there is an 'extra' field in each
|
||||
* map table which is a pointer to void. This field can be used
|
||||
* to store additional information for the map.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FAST_MAP_HAS_VALUE
|
||||
#define FAST_MAP_HAS_VALUE 1
|
||||
#endif
|
||||
|
||||
#ifndef FAST_MAP_RETAIN_KEY
|
||||
#define FAST_MAP_RETAIN_KEY(X) [(X).obj retain]
|
||||
#endif
|
||||
|
||||
#ifndef FAST_MAP_RELEASE_KEY
|
||||
#define FAST_MAP_RELEASE_KEY(X) [(X).obj release]
|
||||
#endif
|
||||
|
||||
#ifndef FAST_MAP_RETAIN_VAL
|
||||
#define FAST_MAP_RETAIN_VAL(X) [(X).obj retain]
|
||||
#endif
|
||||
|
||||
#ifndef FAST_MAP_RELEASE_VAL
|
||||
#define FAST_MAP_RELEASE_VAL(X) [(X).obj release]
|
||||
#endif
|
||||
|
||||
#ifndef FAST_MAP_HASH
|
||||
#define FAST_MAP_HASH(X) [(X).obj hash]
|
||||
#endif
|
||||
|
||||
#ifndef FAST_MAP_EQUAL
|
||||
#define FAST_MAP_EQUAL(X,Y) [(X).obj isEqual: (Y).obj]
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* If there is no bitmask defined to supply the types that
|
||||
* may be used as keys in the map, default to permitting all types.
|
||||
*/
|
||||
#ifndef FAST_MAP_KTYPES
|
||||
#define FAST_MAP_KTYPES GSUNION_ALL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up the name of the union to store keys.
|
||||
*/
|
||||
#ifdef GSUNION
|
||||
#undef GSUNION
|
||||
#endif
|
||||
#define GSUNION FastMapKey
|
||||
|
||||
/*
|
||||
* Set up the types that will be storable in the union.
|
||||
* See 'GSUnion.h' for further information.
|
||||
*/
|
||||
#ifdef GSUNION_TYPES
|
||||
#undef GSUNION_TYPES
|
||||
#endif
|
||||
#define GSUNION_TYPES FAST_MAP_KTYPES
|
||||
#ifdef GSUNION_EXTRA
|
||||
#undef GSUNION_EXTRA
|
||||
#endif
|
||||
#ifdef FAST_MAP_KEXTRA
|
||||
#define GSUNION_EXTRA FAST_MAP_KEXTRA
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Generate the union typedef
|
||||
*/
|
||||
#include <base/GSUnion.h>
|
||||
|
||||
/*
|
||||
* If there is no bitmask defined to supply the types that
|
||||
* may be used as values in the map, default to permitting all types.
|
||||
*/
|
||||
#ifndef FAST_MAP_VTYPES
|
||||
#define FAST_MAP_VTYPES GSUNION_ALL
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up the name of the union to store map values.
|
||||
*/
|
||||
#ifdef GSUNION
|
||||
#undef GSUNION
|
||||
#endif
|
||||
#define GSUNION FastMapVal
|
||||
|
||||
/*
|
||||
* Set up the types that will be storable in the union.
|
||||
* See 'GSUnion.h' for further information.
|
||||
*/
|
||||
#ifdef GSUNION_TYPES
|
||||
#undef GSUNION_TYPES
|
||||
#endif
|
||||
#define GSUNION_TYPES FAST_MAP_VTYPES
|
||||
#ifdef GSUNION_EXTRA
|
||||
#undef GSUNION_EXTRA
|
||||
#endif
|
||||
#ifdef FAST_MAP_VEXTRA
|
||||
#define GSUNION_EXTRA FAST_MAP_VEXTRA
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Generate the union typedef
|
||||
*/
|
||||
#include <base/GSUnion.h>
|
||||
|
||||
|
||||
typedef struct _FastMapTable FastMapTable_t;
|
||||
typedef struct _FastMapBucket FastMapBucket_t;
|
||||
typedef struct _FastMapNode FastMapNode_t;
|
||||
typedef struct _FastMapEnumerator FastMapEnumerator_t;
|
||||
|
||||
typedef FastMapTable_t *FastMapTable;
|
||||
typedef FastMapBucket_t *FastMapBucket;
|
||||
typedef FastMapNode_t *FastMapNode;
|
||||
typedef FastMapEnumerator_t *FastMapEnumerator;
|
||||
|
||||
struct _FastMapNode {
|
||||
FastMapNode nextInBucket; /* Linked list of bucket. */
|
||||
FastMapNode nextInMap; /* For enumerating. */
|
||||
FastMapKey key;
|
||||
#if FAST_MAP_HAS_VALUE
|
||||
FastMapVal value;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _FastMapBucket {
|
||||
size_t nodeCount; /* Number of nodes in bucket. */
|
||||
FastMapNode firstNode; /* The linked list of nodes. */
|
||||
};
|
||||
|
||||
struct _FastMapTable {
|
||||
NSZone *zone;
|
||||
size_t nodeCount; /* Number of nodes in map. */
|
||||
FastMapNode firstNode; /* List for enumerating. */
|
||||
size_t bucketCount; /* Number of buckets in map. */
|
||||
FastMapBucket buckets; /* Array of buckets. */
|
||||
FastMapNode freeNodes; /* List of unused nodes. */
|
||||
size_t chunkCount; /* Number of chunks in array. */
|
||||
FastMapNode *nodeChunks; /* Chunks of allocated memory. */
|
||||
#ifdef FAST_MAP_EXTRA
|
||||
void *extra;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct _FastMapEnumerator {
|
||||
FastMapTable map; /* the map being enumerated. */
|
||||
FastMapNode node; /* The next node to use. */
|
||||
};
|
||||
|
||||
static INLINE FastMapBucket
|
||||
FastMapPickBucket(FastMapKey key, FastMapBucket buckets, size_t bucketCount)
|
||||
{
|
||||
return buckets + FAST_MAP_HASH(key) % bucketCount;
|
||||
}
|
||||
|
||||
static INLINE FastMapBucket
|
||||
FastMapBucketForKey(FastMapTable map, FastMapKey key)
|
||||
{
|
||||
return FastMapPickBucket(key, map->buckets, map->bucketCount);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastMapLinkNodeIntoBucket(FastMapBucket bucket, FastMapNode node)
|
||||
{
|
||||
node->nextInBucket = bucket->firstNode;
|
||||
bucket->firstNode = node;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastMapUnlinkNodeFromBucket(FastMapBucket bucket, FastMapNode node)
|
||||
{
|
||||
if (node == bucket->firstNode)
|
||||
{
|
||||
bucket->firstNode = node->nextInBucket;
|
||||
}
|
||||
else
|
||||
{
|
||||
FastMapNode tmp = bucket->firstNode;
|
||||
|
||||
while (tmp->nextInBucket != node)
|
||||
{
|
||||
tmp = tmp->nextInBucket;
|
||||
}
|
||||
tmp->nextInBucket = node->nextInBucket;
|
||||
}
|
||||
node->nextInBucket = 0;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastMapLinkNodeIntoMap(FastMapTable map, FastMapNode node)
|
||||
{
|
||||
node->nextInMap = map->firstNode;
|
||||
map->firstNode = node;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastMapUnlinkNodeFromMap(FastMapTable map, FastMapNode node)
|
||||
{
|
||||
if (node == map->firstNode)
|
||||
{
|
||||
map->firstNode = node->nextInMap;
|
||||
}
|
||||
else
|
||||
{
|
||||
FastMapNode tmp = map->firstNode;
|
||||
|
||||
while (tmp->nextInMap != node)
|
||||
{
|
||||
tmp = tmp->nextInMap;
|
||||
}
|
||||
tmp->nextInMap = node->nextInMap;
|
||||
}
|
||||
node->nextInMap = 0;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastMapAddNodeToBucket(FastMapBucket bucket, FastMapNode node)
|
||||
{
|
||||
FastMapLinkNodeIntoBucket(bucket, node);
|
||||
bucket->nodeCount += 1;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastMapAddNodeToMap(FastMapTable map, FastMapNode node)
|
||||
{
|
||||
FastMapBucket bucket;
|
||||
|
||||
bucket = FastMapBucketForKey(map, node->key);
|
||||
FastMapAddNodeToBucket(bucket, node);
|
||||
FastMapLinkNodeIntoMap(map, node);
|
||||
map->nodeCount++;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastMapRemoveNodeFromBucket(FastMapBucket bucket, FastMapNode node)
|
||||
{
|
||||
bucket->nodeCount--;
|
||||
FastMapUnlinkNodeFromBucket(bucket, node);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastMapRemoveNodeFromMap(FastMapTable map, FastMapBucket bkt, FastMapNode node)
|
||||
{
|
||||
map->nodeCount--;
|
||||
FastMapUnlinkNodeFromMap(map, node);
|
||||
FastMapRemoveNodeFromBucket(bkt, node);
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastMapRemangleBuckets(FastMapTable map,
|
||||
FastMapBucket old_buckets,
|
||||
size_t old_bucketCount,
|
||||
FastMapBucket new_buckets,
|
||||
size_t new_bucketCount)
|
||||
{
|
||||
while (old_bucketCount-- > 0)
|
||||
{
|
||||
FastMapNode node;
|
||||
|
||||
while ((node = old_buckets->firstNode) != 0)
|
||||
{
|
||||
FastMapBucket bkt;
|
||||
|
||||
FastMapRemoveNodeFromBucket(old_buckets, node);
|
||||
bkt = FastMapPickBucket(node->key, new_buckets, new_bucketCount);
|
||||
FastMapAddNodeToBucket(bkt, node);
|
||||
}
|
||||
old_buckets++;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastMapMoreNodes(FastMapTable map)
|
||||
{
|
||||
FastMapNode *newArray;
|
||||
size_t arraySize = (map->chunkCount+1)*sizeof(FastMapNode);
|
||||
|
||||
newArray = (FastMapNode*)NSZoneMalloc(map->zone, arraySize);
|
||||
if (newArray)
|
||||
{
|
||||
FastMapNode newNodes;
|
||||
size_t chunkCount;
|
||||
size_t chunkSize;
|
||||
|
||||
memcpy(newArray,map->nodeChunks,(map->chunkCount)*sizeof(FastMapNode));
|
||||
if (map->nodeChunks != 0)
|
||||
{
|
||||
NSZoneFree(map->zone, map->nodeChunks);
|
||||
}
|
||||
map->nodeChunks = newArray;
|
||||
|
||||
if (map->chunkCount == 0)
|
||||
{
|
||||
chunkCount = map->bucketCount > 1 ? map->bucketCount : 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
chunkCount = ((map->nodeCount>>2)+1)<<1;
|
||||
}
|
||||
chunkSize = chunkCount * sizeof(FastMapNode_t);
|
||||
#if GS_WITH_GC
|
||||
/*
|
||||
* If we use a nil zone, objects we point to are subject to GC
|
||||
*/
|
||||
if (map->zone == 0)
|
||||
newNodes = (FastMapNode*)GC_MALLOC_ATOMIC(chunkSize);
|
||||
else
|
||||
newNodes = (FastMapNode*)GC_MALLOC(chunkSize);
|
||||
#else
|
||||
newNodes = (FastMapNode)NSZoneMalloc(map->zone, chunkSize);
|
||||
#endif
|
||||
if (newNodes)
|
||||
{
|
||||
map->nodeChunks[map->chunkCount++] = newNodes;
|
||||
newNodes[--chunkCount].nextInMap = map->freeNodes;
|
||||
while (chunkCount--)
|
||||
{
|
||||
newNodes[chunkCount].nextInMap = &newNodes[chunkCount+1];
|
||||
}
|
||||
map->freeNodes = newNodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if FAST_MAP_HAS_VALUE
|
||||
static INLINE FastMapNode
|
||||
FastMapNewNode(FastMapTable map, FastMapKey key, FastMapVal value)
|
||||
{
|
||||
FastMapNode node = map->freeNodes;
|
||||
|
||||
if (node == 0)
|
||||
{
|
||||
FastMapMoreNodes(map);
|
||||
node = map->freeNodes;
|
||||
if (node == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
map->freeNodes = node->nextInMap;
|
||||
node->key = key;
|
||||
node->value = value;
|
||||
node->nextInBucket = 0;
|
||||
node->nextInMap = 0;
|
||||
|
||||
return node;
|
||||
}
|
||||
#else
|
||||
static INLINE FastMapNode
|
||||
FastMapNewNode(FastMapTable map, FastMapKey key)
|
||||
{
|
||||
FastMapNode node = map->freeNodes;
|
||||
|
||||
if (node == 0)
|
||||
{
|
||||
FastMapMoreNodes(map);
|
||||
node = map->freeNodes;
|
||||
if (node == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
map->freeNodes = node->nextInMap;
|
||||
node->key = key;
|
||||
node->nextInBucket = 0;
|
||||
node->nextInMap = 0;
|
||||
return node;
|
||||
}
|
||||
#endif
|
||||
|
||||
static INLINE void
|
||||
FastMapFreeNode(FastMapTable map, FastMapNode node)
|
||||
{
|
||||
FAST_MAP_RELEASE_KEY(node->key);
|
||||
#if FAST_MAP_HAS_VALUE
|
||||
FAST_MAP_RELEASE_VAL(node->value);
|
||||
#endif
|
||||
node->nextInMap = map->freeNodes;
|
||||
map->freeNodes = node;
|
||||
}
|
||||
|
||||
static INLINE FastMapNode
|
||||
FastMapNodeForKeyInBucket(FastMapBucket bucket, FastMapKey key)
|
||||
{
|
||||
FastMapNode node = bucket->firstNode;
|
||||
|
||||
while ((node != 0) && FAST_MAP_EQUAL(node->key, key) == NO)
|
||||
{
|
||||
node = node->nextInBucket;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
static INLINE FastMapNode
|
||||
FastMapNodeForKey(FastMapTable map, FastMapKey key)
|
||||
{
|
||||
FastMapBucket bucket;
|
||||
FastMapNode node;
|
||||
|
||||
if (map->nodeCount == 0)
|
||||
return 0;
|
||||
bucket = FastMapBucketForKey(map, key);
|
||||
node = FastMapNodeForKeyInBucket(bucket, key);
|
||||
return node;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastMapResize(FastMapTable map, size_t new_capacity)
|
||||
{
|
||||
FastMapBucket new_buckets;
|
||||
size_t size = 1;
|
||||
size_t old = 1;
|
||||
|
||||
/*
|
||||
* Find next size up in the fibonacci series
|
||||
*/
|
||||
while (size < new_capacity)
|
||||
{
|
||||
size_t tmp = old;
|
||||
old = size;
|
||||
size += tmp;
|
||||
}
|
||||
/*
|
||||
* Avoid 8 - since hash functions frequently generate uneven distributions
|
||||
* around powers of two - we don't want lots of keys falling into a single
|
||||
* bucket.
|
||||
*/
|
||||
if (size == 8) size++;
|
||||
|
||||
/*
|
||||
* Make a new set of buckets for this map
|
||||
*/
|
||||
new_buckets = (FastMapBucket)NSZoneCalloc(map->zone, size,
|
||||
sizeof(FastMapBucket_t));
|
||||
if (new_buckets != 0)
|
||||
{
|
||||
FastMapRemangleBuckets(map,
|
||||
map->buckets,
|
||||
map->bucketCount,
|
||||
new_buckets,
|
||||
size);
|
||||
|
||||
if (map->buckets != 0)
|
||||
{
|
||||
NSZoneFree(map->zone, map->buckets);
|
||||
}
|
||||
map->buckets = new_buckets;
|
||||
map->bucketCount = size;
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastMapRightSizeMap(FastMapTable map, size_t capacity)
|
||||
{
|
||||
/* FIXME: Now, this is a guess, based solely on my intuition. If anyone
|
||||
* knows of a better ratio (or other test, for that matter) and can
|
||||
* provide evidence of its goodness, please get in touch with me, Albin
|
||||
* L. Jones <Albin.L.Jones@Dartmouth.EDU>. */
|
||||
|
||||
if (3 * capacity >= 4 * map->bucketCount)
|
||||
{
|
||||
FastMapResize(map, (3 * capacity)/4 + 1);
|
||||
}
|
||||
}
|
||||
|
||||
/** Enumerating **/
|
||||
|
||||
/* WARNING: You should not alter a map while an enumeration is
|
||||
* in progress. The results of doing so are reasonably unpremapable.
|
||||
* With that in mind, read the following warnings carefully. But
|
||||
* remember, DON'T MESS WITH A MAP WHILE YOU'RE ENUMERATING IT. */
|
||||
|
||||
/* IMPORTANT WARNING: Map enumerators, as I have map them up, have a
|
||||
* wonderous property. Namely, that, while enumerating, one may add
|
||||
* new elements (i.e., new nodes) to the map while an enumeration is
|
||||
* in progress (i.e., after `o_map_enumerator_for_map()' has been
|
||||
* called), and the enumeration remains the same. */
|
||||
|
||||
/* WARNING: The above warning should not, in any way, be taken as
|
||||
* assurance that this property of map enumerators will be preserved
|
||||
* in future editions of the library. I'm still thinking about
|
||||
* this. */
|
||||
|
||||
/* IMPORTANT WARNING: Enumerators have yet another wonderous property.
|
||||
* Once a node has been returned by `FastMapEnumeratorNextNode()', it may be
|
||||
* removed from the map without effecting the rest of the current
|
||||
* enumeration. */
|
||||
|
||||
/* EXTREMELY IMPORTANT WARNING: The purpose of this warning is point
|
||||
* out that, at this time, various (i.e., many) functions depend on
|
||||
* the behaviours outlined above. So be prepared for some serious
|
||||
* breakage when you go fudging around with these things. */
|
||||
|
||||
static INLINE FastMapEnumerator_t
|
||||
FastMapEnumeratorForMap(FastMapTable map)
|
||||
{
|
||||
FastMapEnumerator_t enumerator;
|
||||
|
||||
enumerator.map = map;
|
||||
enumerator.node = map->firstNode;
|
||||
|
||||
return enumerator;
|
||||
}
|
||||
|
||||
static INLINE FastMapNode
|
||||
FastMapEnumeratorNextNode(FastMapEnumerator enumerator)
|
||||
{
|
||||
FastMapNode node;
|
||||
|
||||
node = enumerator->node;
|
||||
|
||||
if (node != 0)
|
||||
enumerator->node = node->nextInMap;
|
||||
|
||||
/* Send back NODE. */
|
||||
return node;
|
||||
}
|
||||
|
||||
#if FAST_MAP_HAS_VALUE
|
||||
static INLINE FastMapNode
|
||||
FastMapAddPairNoRetain(FastMapTable map, FastMapKey key, FastMapVal value)
|
||||
{
|
||||
FastMapNode node;
|
||||
|
||||
node = FastMapNewNode(map, key, value);
|
||||
|
||||
if (node != 0)
|
||||
{
|
||||
FastMapRightSizeMap(map, map->nodeCount);
|
||||
FastMapAddNodeToMap(map, node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
static INLINE FastMapNode
|
||||
FastMapAddPair(FastMapTable map, FastMapKey key, FastMapVal value)
|
||||
{
|
||||
FastMapNode node;
|
||||
|
||||
FAST_MAP_RETAIN_KEY(key);
|
||||
FAST_MAP_RETAIN_VAL(value);
|
||||
node = FastMapNewNode(map, key, value);
|
||||
|
||||
if (node != 0)
|
||||
{
|
||||
FastMapRightSizeMap(map, map->nodeCount);
|
||||
FastMapAddNodeToMap(map, node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
#else
|
||||
static INLINE FastMapNode
|
||||
FastMapAddKeyNoRetain(FastMapTable map, FastMapKey key)
|
||||
{
|
||||
FastMapNode node;
|
||||
|
||||
node = FastMapNewNode(map, key);
|
||||
|
||||
if (node != 0)
|
||||
{
|
||||
FastMapRightSizeMap(map, map->nodeCount);
|
||||
FastMapAddNodeToMap(map, node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
static INLINE FastMapNode
|
||||
FastMapAddKey(FastMapTable map, FastMapKey key)
|
||||
{
|
||||
FastMapNode node;
|
||||
|
||||
FAST_MAP_RETAIN_KEY(key);
|
||||
node = FastMapNewNode(map, key);
|
||||
|
||||
if (node != 0)
|
||||
{
|
||||
FastMapRightSizeMap(map, map->nodeCount);
|
||||
FastMapAddNodeToMap(map, node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
#endif
|
||||
|
||||
static INLINE void
|
||||
FastMapRemoveKey(FastMapTable map, FastMapKey key)
|
||||
{
|
||||
FastMapBucket bucket = FastMapBucketForKey(map, key);
|
||||
|
||||
if (bucket != 0)
|
||||
{
|
||||
FastMapNode node = FastMapNodeForKeyInBucket(bucket, key);
|
||||
|
||||
if (node != 0)
|
||||
{
|
||||
FastMapRemoveNodeFromMap(map, bucket, node);
|
||||
FastMapFreeNode(map, node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastMapCleanMap(FastMapTable map)
|
||||
{
|
||||
FastMapBucket bucket = map->buckets;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < map->bucketCount; i++)
|
||||
{
|
||||
while (bucket->nodeCount != 0)
|
||||
{
|
||||
FastMapNode node = bucket->firstNode;
|
||||
|
||||
FastMapRemoveNodeFromBucket(bucket, node);
|
||||
FastMapFreeNode(map, node);
|
||||
}
|
||||
bucket++;
|
||||
}
|
||||
map->firstNode = 0;
|
||||
map->nodeCount = 0;
|
||||
}
|
||||
|
||||
static INLINE void
|
||||
FastMapEmptyMap(FastMapTable map)
|
||||
{
|
||||
int i;
|
||||
|
||||
FastMapCleanMap(map);
|
||||
if (map->buckets != 0)
|
||||
{
|
||||
NSZoneFree(map->zone, map->buckets);
|
||||
map->buckets = 0;
|
||||
map->bucketCount = 0;
|
||||
}
|
||||
if (map->nodeChunks != 0)
|
||||
{
|
||||
for (i = 0; i < map->chunkCount; i++)
|
||||
{
|
||||
#if GS_WITH_GC
|
||||
GC_FREE(map->nodeChunks[i]);
|
||||
#else
|
||||
NSZoneFree(map->zone, map->nodeChunks[i]);
|
||||
#endif
|
||||
}
|
||||
map->chunkCount = 0;
|
||||
NSZoneFree(map->zone, map->nodeChunks);
|
||||
map->nodeChunks = 0;
|
||||
}
|
||||
map->freeNodes = 0;
|
||||
map->zone = 0;
|
||||
}
|
||||
|
||||
static INLINE FastMapTable
|
||||
FastMapInitWithZoneAndCapacity(FastMapTable map, NSZone *zone, size_t capacity)
|
||||
{
|
||||
map->zone = zone;
|
||||
map->nodeCount = 0;
|
||||
map->bucketCount = 0;
|
||||
map->firstNode = 0;
|
||||
map->buckets = 0;
|
||||
map->nodeChunks = 0;
|
||||
map->freeNodes = 0;
|
||||
map->chunkCount = 0;
|
||||
FastMapRightSizeMap(map, capacity);
|
||||
FastMapMoreNodes(map);
|
||||
}
|
||||
|
||||
#ifdef FAST_MAP_BLOCKED_ASSERTIONS
|
||||
#undef NS_BLOCK_ASSERTIONS
|
||||
#undef FAST_MAP_BLOCKED_ASSERTIONS
|
||||
#endif
|
||||
|
114
Headers/gnustep/base/GSUnion.h
Normal file
114
Headers/gnustep/base/GSUnion.h
Normal file
|
@ -0,0 +1,114 @@
|
|||
/*
|
||||
* GSUnion.h
|
||||
* File to set up a typedef for a union capable of containing various types.
|
||||
* Copyright (C) 1999 Free Software Foundation, Inc.
|
||||
*
|
||||
* Author: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
* Created: Apr 1999
|
||||
*
|
||||
* This file is part of the GNUstep Base Library.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/*
|
||||
* Definitions for bitmap mask of types of element in union.
|
||||
*/
|
||||
#ifndef GSUNION_OBJ
|
||||
|
||||
#define GSUNION_OBJ 0x0001
|
||||
#define GSUNION_CLS 0x0002
|
||||
#define GSUNION_SEL 0x0004
|
||||
#define GSUNION_CHAR 0x0008
|
||||
#define GSUNION_SHORT 0x0010
|
||||
#define GSUNION_INT 0x0020
|
||||
#define GSUNION_LONG 0x0040
|
||||
#define GSUNION_PTR 0x0080
|
||||
#define GSUNION_8B 0x0100
|
||||
#define GSUNION_16B 0x0200
|
||||
#define GSUNION_32B 0x0400
|
||||
#define GSUNION_64B 0x0800
|
||||
|
||||
#define GSUNION_ALL 0x0fff
|
||||
|
||||
#endif /* GSUNION_OBJ */
|
||||
|
||||
|
||||
/*
|
||||
* Produce a typedef for a union with name 'GSUNION' containing elements
|
||||
* specified in the GSUNION_TYPES mask, and optionally with an extra
|
||||
* element 'ext' of the type specified in GSUNION_EXTRA
|
||||
*
|
||||
* You can include this file more than once in order to produce different
|
||||
* typedefs as long as you redefine 'GSUNION' before each inclusion.
|
||||
*/
|
||||
|
||||
#if defined(GSUNION) && defined(GSUNION_TYPES)
|
||||
|
||||
typedef union {
|
||||
#if (GSUNION_TYPES & GSUNION_OBJ)
|
||||
id obj;
|
||||
NSObject *nso;
|
||||
#endif
|
||||
#if (GSUNION_TYPES & GSUNION_CLS)
|
||||
Class cls;
|
||||
#endif
|
||||
#if (GSUNION_TYPES & GSUNION_SEL)
|
||||
SEL sel;
|
||||
#endif
|
||||
#if (GSUNION_TYPES & GSUNION_CHAR)
|
||||
char schr;
|
||||
unsigned char uchr;
|
||||
#endif
|
||||
#if (GSUNION_TYPES & GSUNION_SHORT)
|
||||
short ssht;
|
||||
unsigned short usht;
|
||||
#endif
|
||||
#if (GSUNION_TYPES & GSUNION_INT)
|
||||
int sint;
|
||||
unsigned uint;
|
||||
#endif
|
||||
#if (GSUNION_TYPES & GSUNION_LONG)
|
||||
long slng;
|
||||
unsigned long ulng;
|
||||
#endif
|
||||
#if (GSUNION_TYPES & GSUNION_PTR)
|
||||
void *ptr;
|
||||
const void *cptr;
|
||||
char *str;
|
||||
const char *cstr;
|
||||
#endif
|
||||
#if (GSUNION_TYPES & GSUNION_8B)
|
||||
gss8 s8;
|
||||
gsu8 u8;
|
||||
#endif
|
||||
#if (GSUNION_TYPES & GSUNION_16B)
|
||||
gss16 s16;
|
||||
gsu16 u16;
|
||||
#endif
|
||||
#if (GSUNION_TYPES & GSUNION_32B)
|
||||
gss32 s32;
|
||||
gsu32 u32;
|
||||
#endif
|
||||
#if (GSUNION_TYPES & GSUNION_64B)
|
||||
gss64 s64;
|
||||
gsu64 u64;
|
||||
#endif
|
||||
#if defined(GSUNION_EXTRA)
|
||||
GSUNION_EXTRA ext;
|
||||
#endif
|
||||
} GSUNION;
|
||||
|
||||
#endif
|
||||
|
|
@ -58,6 +58,10 @@ struct _NSZone
|
|||
|
||||
void *GSOutOfMemory(size_t size, BOOL retry);
|
||||
|
||||
/* Default zone. Name is hopelessly long so that no one will ever
|
||||
want to use it. ;) Private variable. */
|
||||
extern NSZone* __nszone_private_hidden_default_zone;
|
||||
|
||||
#ifndef GS_WITH_GC
|
||||
#define GS_WITH_GC 0
|
||||
#endif
|
||||
|
@ -65,14 +69,15 @@ void *GSOutOfMemory(size_t size, BOOL retry);
|
|||
|
||||
#include <gc.h>
|
||||
|
||||
#define
|
||||
extern inline NSZone* NSCreateZone (size_t start, size_t gran, BOOL canFree)
|
||||
{ return 0; }
|
||||
{ return __nszone_private_hidden_default_zone; }
|
||||
|
||||
extern inline NSZone* NSDefaultMallocZone (void)
|
||||
{ return 0; }
|
||||
{ return __nszone_private_hidden_default_zone; }
|
||||
|
||||
extern inline NSZone* NSZoneFromPointer (void *ptr)
|
||||
{ return 0; }
|
||||
{ return __nszone_private_hidden_default_zone; }
|
||||
|
||||
extern inline void* NSZoneMalloc (NSZone *zone, size_t size)
|
||||
{
|
||||
|
@ -134,10 +139,6 @@ extern inline struct NSZoneStats NSZoneStats (NSZone *zone)
|
|||
|
||||
#else /* GS_WITH_GC */
|
||||
|
||||
/* Default zone. Name is hopelessly long so that no one will ever
|
||||
want to use it. ;) Private variable. */
|
||||
extern NSZone* __nszone_private_hidden_default_zone;
|
||||
|
||||
extern NSZone* NSCreateZone (size_t start, size_t gran, BOOL canFree);
|
||||
|
||||
extern inline NSZone* NSDefaultMallocZone (void)
|
||||
|
|
|
@ -160,6 +160,9 @@ libgnustep-base.def
|
|||
|
||||
GNU_HEADERS = \
|
||||
fast.x \
|
||||
GSUnion.h \
|
||||
FastArray.x \
|
||||
FastMap.x \
|
||||
Archiver.h \
|
||||
Array.h \
|
||||
ArrayPrivate.h \
|
||||
|
|
|
@ -216,7 +216,7 @@ $(GNUSTEP_OBJ_DIR)/NSUnarchiver.o \
|
|||
#
|
||||
$(GNUSTEP_OBJ_DIR)/NSSerializer.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSUnarchiver.o \
|
||||
: FastArray.x
|
||||
: include/FastArray.x include/GSUnion.h
|
||||
|
||||
#
|
||||
# Files that include FastMap.x will need a rebuild if it is changed.
|
||||
|
@ -226,7 +226,7 @@ $(GNUSTEP_OBJ_DIR)/NSGCountedSet.o \
|
|||
$(GNUSTEP_OBJ_DIR)/NSGDictionary.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSGSet.o \
|
||||
$(GNUSTEP_OBJ_DIR)/NSSerializer.o \
|
||||
: FastMap.x
|
||||
: include/FastMap.x include/GSUnion.h
|
||||
|
||||
#
|
||||
# Files that include fast.x will need a rebuild if it is changed.
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/* Implementation of NSArchiver for GNUstep
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
Copyright (C) 1998,1999 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Richard frith-Macdonald <richard@brainstorm.co.Ik>
|
||||
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
Created: October 1998
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
@ -30,10 +30,10 @@
|
|||
#define FAST_MAP_RELEASE_KEY(X)
|
||||
#define FAST_MAP_RETAIN_VAL(X) X
|
||||
#define FAST_MAP_RELEASE_VAL(X)
|
||||
#define FAST_MAP_HASH(X) ((X).I)
|
||||
#define FAST_MAP_EQUAL(X,Y) ((X).I == (Y).I)
|
||||
#define FAST_MAP_HASH(X) ((X).uint)
|
||||
#define FAST_MAP_EQUAL(X,Y) ((X).uint == (Y).uint)
|
||||
|
||||
#include "FastMap.x"
|
||||
#include <base/FastMap.x>
|
||||
|
||||
#define _IN_NSARCHIVER_M
|
||||
#include <Foundation/NSArchiver.h>
|
||||
|
@ -317,7 +317,7 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
{
|
||||
FastMapNode node;
|
||||
|
||||
node = FastMapNodeForKey(ptrMap, (FastMapItem)*(void**)buf);
|
||||
node = FastMapNodeForKey(ptrMap, (FastMapKey)*(void**)buf);
|
||||
if (isInPreparatoryPass == YES)
|
||||
{
|
||||
/*
|
||||
|
@ -327,13 +327,13 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
if (node == 0)
|
||||
{
|
||||
FastMapAddPair(ptrMap,
|
||||
(FastMapItem)*(void**)buf, (FastMapItem)0);
|
||||
(FastMapKey)*(void**)buf, (FastMapVal)0);
|
||||
type++;
|
||||
buf = *(char**)buf;
|
||||
(*eValImp)(self, eValSel, type, buf);
|
||||
}
|
||||
}
|
||||
else if (node == 0 || node->value.I == 0)
|
||||
else if (node == 0 || node->value.uint == 0)
|
||||
{
|
||||
/*
|
||||
* Second pass, unwritten pointer - write it.
|
||||
|
@ -341,13 +341,13 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
if (node == 0)
|
||||
{
|
||||
node = FastMapAddPair(ptrMap,
|
||||
(FastMapItem)*(void**)buf, (FastMapItem)++xRefP);
|
||||
(FastMapKey)*(void**)buf, (FastMapVal)++xRefP);
|
||||
}
|
||||
else
|
||||
{
|
||||
node->value.I = ++xRefP;
|
||||
node->value.uint = ++xRefP;
|
||||
}
|
||||
(*xRefImp)(dst, xRefSel, _GSC_PTR, node->value.I);
|
||||
(*xRefImp)(dst, xRefSel, _GSC_PTR, node->value.uint);
|
||||
type++;
|
||||
buf = *(char**)buf;
|
||||
(*eValImp)(self, eValSel, type, buf);
|
||||
|
@ -357,7 +357,7 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
/*
|
||||
* Second pass, write a cross-reference number.
|
||||
*/
|
||||
(*xRefImp)(dst, xRefSel, _GSC_PTR | _GSC_XREF, node->value.I);
|
||||
(*xRefImp)(dst, xRefSel, _GSC_PTR|_GSC_XREF, node->value.uint);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -386,11 +386,12 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
FastMapNode node;
|
||||
BOOL done = NO;
|
||||
|
||||
node = FastMapNodeForKey(clsMap, (FastMapItem)(void*)c);
|
||||
node = FastMapNodeForKey(clsMap, (FastMapKey)(void*)c);
|
||||
|
||||
if (node != 0)
|
||||
{
|
||||
(*xRefImp)(dst, xRefSel, _GSC_CLASS | _GSC_XREF, node->value.I);
|
||||
(*xRefImp)(dst, xRefSel, _GSC_CLASS | _GSC_XREF,
|
||||
node->value.uint);
|
||||
return;
|
||||
}
|
||||
while (done == NO)
|
||||
|
@ -405,11 +406,11 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
format: @"negative class version"];
|
||||
}
|
||||
node = FastMapAddPair(clsMap,
|
||||
(FastMapItem)(void*)c, (FastMapItem)++xRefC);
|
||||
(FastMapKey)(void*)c, (FastMapVal)++xRefC);
|
||||
/*
|
||||
* Encode tag and crossref number.
|
||||
*/
|
||||
(*xRefImp)(dst, xRefSel, _GSC_CLASS, node->value.I);
|
||||
(*xRefImp)(dst, xRefSel, _GSC_CLASS, node->value.uint);
|
||||
/*
|
||||
* Encode class, and version.
|
||||
*/
|
||||
|
@ -423,7 +424,7 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
* [super initWithCoder:ccc]
|
||||
*/
|
||||
if (s == c || s == 0 ||
|
||||
FastMapNodeForKey(clsMap, (FastMapItem)(void*)s) != 0)
|
||||
FastMapNodeForKey(clsMap, (FastMapKey)(void*)s) != 0)
|
||||
{
|
||||
done = YES;
|
||||
}
|
||||
|
@ -450,13 +451,13 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
else
|
||||
{
|
||||
SEL s = *(SEL*)buf;
|
||||
FastMapNode node = FastMapNodeForKey(ptrMap, (FastMapItem)(void*)s);
|
||||
FastMapNode node = FastMapNodeForKey(ptrMap, (FastMapKey)(void*)s);
|
||||
|
||||
if (node == 0)
|
||||
{
|
||||
node = FastMapAddPair(ptrMap,
|
||||
(FastMapItem)(void*)s, (FastMapItem)++xRefP);
|
||||
(*xRefImp)(dst, xRefSel, _GSC_SEL, node->value.I);
|
||||
(FastMapKey)(void*)s, (FastMapVal)++xRefP);
|
||||
(*xRefImp)(dst, xRefSel, _GSC_SEL, node->value.uint);
|
||||
/*
|
||||
* Encode selector.
|
||||
*/
|
||||
|
@ -464,7 +465,7 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
}
|
||||
else
|
||||
{
|
||||
(*xRefImp)(dst, xRefSel, _GSC_SEL | _GSC_XREF, node->value.I);
|
||||
(*xRefImp)(dst, xRefSel, _GSC_SEL|_GSC_XREF, node->value.uint);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -481,17 +482,18 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
{
|
||||
FastMapNode node;
|
||||
|
||||
node = FastMapNodeForKey(ptrMap, (FastMapItem)*(char**)buf);
|
||||
node = FastMapNodeForKey(ptrMap, (FastMapKey)*(char**)buf);
|
||||
if (node == 0)
|
||||
{
|
||||
node = FastMapAddPair(ptrMap,
|
||||
(FastMapItem)*(char**)buf, (FastMapItem)++xRefP);
|
||||
(*xRefImp)(dst, xRefSel, _GSC_CHARPTR, node->value.I);
|
||||
(FastMapKey)*(char**)buf, (FastMapVal)++xRefP);
|
||||
(*xRefImp)(dst, xRefSel, _GSC_CHARPTR, node->value.uint);
|
||||
(*serImp)(dst, serSel, buf, type, nil);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*xRefImp)(dst, xRefSel, _GSC_CHARPTR|_GSC_XREF, node->value.I);
|
||||
(*xRefImp)(dst, xRefSel, _GSC_CHARPTR|_GSC_XREF,
|
||||
node->value.uint);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
@ -627,7 +629,7 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
* If we have already conditionally encoded this object, we can
|
||||
* ignore it this time.
|
||||
*/
|
||||
node = FastMapNodeForKey(cIdMap, (FastMapItem)anObject);
|
||||
node = FastMapNodeForKey(cIdMap, (FastMapKey)anObject);
|
||||
if (node != 0)
|
||||
{
|
||||
return;
|
||||
|
@ -637,13 +639,13 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
* If we have unconditionally encoded this object, we can ignore
|
||||
* it now.
|
||||
*/
|
||||
node = FastMapNodeForKey(uIdMap, (FastMapItem)anObject);
|
||||
node = FastMapNodeForKey(uIdMap, (FastMapKey)anObject);
|
||||
if (node != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
FastMapAddPair(cIdMap, (FastMapItem)anObject, (FastMapItem)0);
|
||||
FastMapAddPair(cIdMap, (FastMapKey)anObject, (FastMapVal)0);
|
||||
}
|
||||
else if (anObject == nil)
|
||||
{
|
||||
|
@ -655,14 +657,14 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
|
||||
if (repMap->nodeCount)
|
||||
{
|
||||
node = FastMapNodeForKey(repMap, (FastMapItem)anObject);
|
||||
node = FastMapNodeForKey(repMap, (FastMapKey)anObject);
|
||||
if (node)
|
||||
{
|
||||
anObject = (id)node->value.p;
|
||||
anObject = (id)node->value.ptr;
|
||||
}
|
||||
}
|
||||
|
||||
node = FastMapNodeForKey(cIdMap, (FastMapItem)anObject);
|
||||
node = FastMapNodeForKey(cIdMap, (FastMapKey)anObject);
|
||||
if (node != 0)
|
||||
{
|
||||
(*eObjImp)(self, eObjSel, nil);
|
||||
|
@ -723,16 +725,16 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
/*
|
||||
* Substitute replacement object if required.
|
||||
*/
|
||||
node = FastMapNodeForKey(repMap, (FastMapItem)anObject);
|
||||
node = FastMapNodeForKey(repMap, (FastMapKey)anObject);
|
||||
if (node)
|
||||
{
|
||||
anObject = (id)node->value.p;
|
||||
anObject = (id)node->value.ptr;
|
||||
}
|
||||
|
||||
/*
|
||||
* See if the object has already been encoded.
|
||||
*/
|
||||
node = FastMapNodeForKey(uIdMap, (FastMapItem)anObject);
|
||||
node = FastMapNodeForKey(uIdMap, (FastMapKey)anObject);
|
||||
|
||||
if (isInPreparatoryPass)
|
||||
{
|
||||
|
@ -742,14 +744,14 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
* Remove object from map of conditionally encoded objects
|
||||
* and add it to the map of unconditionay encoded ones.
|
||||
*/
|
||||
FastMapRemoveKey(cIdMap, (FastMapItem)anObject);
|
||||
FastMapAddPair(uIdMap, (FastMapItem)anObject, (FastMapItem)0);
|
||||
FastMapRemoveKey(cIdMap, (FastMapKey)anObject);
|
||||
FastMapAddPair(uIdMap, (FastMapKey)anObject, (FastMapVal)0);
|
||||
[anObject encodeWithCoder: self];
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (node == 0 || node->value.I == 0)
|
||||
if (node == 0 || node->value.uint == 0)
|
||||
{
|
||||
Class cls;
|
||||
id obj;
|
||||
|
@ -757,26 +759,26 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
if (node == 0)
|
||||
{
|
||||
node = FastMapAddPair(uIdMap,
|
||||
(FastMapItem)anObject, (FastMapItem)++xRefO);
|
||||
(FastMapKey)anObject, (FastMapVal)++xRefO);
|
||||
}
|
||||
else
|
||||
{
|
||||
node->value.I = ++xRefO;
|
||||
node->value.uint = ++xRefO;
|
||||
}
|
||||
|
||||
obj = [anObject replacementObjectForArchiver: self];
|
||||
cls = [anObject classForArchiver];
|
||||
|
||||
(*xRefImp)(dst, xRefSel, _GSC_ID, node->value.I);
|
||||
(*xRefImp)(dst, xRefSel, _GSC_ID, node->value.uint);
|
||||
if (namMap->nodeCount)
|
||||
{
|
||||
FastMapNode node;
|
||||
|
||||
node = FastMapNodeForKey(namMap, (FastMapItem)cls);
|
||||
node = FastMapNodeForKey(namMap, (FastMapKey)cls);
|
||||
|
||||
if (node)
|
||||
{
|
||||
cls = (Class)node->value.p;
|
||||
cls = (Class)node->value.ptr;
|
||||
}
|
||||
}
|
||||
(*eValImp)(self, eValSel, @encode(Class), &cls);
|
||||
|
@ -784,7 +786,7 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
}
|
||||
else if(!isInPreparatoryPass)
|
||||
{
|
||||
(*xRefImp)(dst, xRefSel, _GSC_ID | _GSC_XREF, node->value.I);
|
||||
(*xRefImp)(dst, xRefSel, _GSC_ID | _GSC_XREF, node->value.uint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -802,10 +804,10 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
Class c;
|
||||
|
||||
c = objc_get_class([trueName cString]);
|
||||
node = FastMapNodeForKey(namMap, (FastMapItem)c);
|
||||
node = FastMapNodeForKey(namMap, (FastMapKey)c);
|
||||
if (node)
|
||||
{
|
||||
c = (Class)node->value.p;
|
||||
c = (Class)node->value.ptr;
|
||||
return [NSString stringWithCString: fastClassName(c)];
|
||||
}
|
||||
}
|
||||
|
@ -831,14 +833,14 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"Can't find class '%@'.", inArchiveName];
|
||||
}
|
||||
node = FastMapNodeForKey(namMap, (FastMapItem)tc);
|
||||
node = FastMapNodeForKey(namMap, (FastMapKey)tc);
|
||||
if (node == 0)
|
||||
{
|
||||
FastMapAddPair(namMap, (FastMapItem)(void*)tc, (FastMapItem)(void*)ic);
|
||||
FastMapAddPair(namMap, (FastMapKey)(void*)tc, (FastMapVal)(void*)ic);
|
||||
}
|
||||
else
|
||||
{
|
||||
node->value.p = (void*)ic;
|
||||
node->value.ptr = (void*)ic;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -857,14 +859,14 @@ static SEL eValSel = @selector(encodeValueOfObjCType:at:);
|
|||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"attempt to remap object to nil"];
|
||||
}
|
||||
node = FastMapNodeForKey(namMap, (FastMapItem)object);
|
||||
node = FastMapNodeForKey(namMap, (FastMapKey)object);
|
||||
if (node == 0)
|
||||
{
|
||||
FastMapAddPair(namMap, (FastMapItem)object, (FastMapItem)newObject);
|
||||
FastMapAddPair(namMap, (FastMapKey)object, (FastMapVal)newObject);
|
||||
}
|
||||
else
|
||||
{
|
||||
node->value.p = (void*)newObject;
|
||||
node->value.ptr = (void*)newObject;
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
|
|
@ -62,75 +62,50 @@ static Class NSCountedSet_concrete_class;
|
|||
|
||||
- (unsigned int) countForObject: anObject
|
||||
{
|
||||
[self subclassResponsibility:_cmd];
|
||||
[self subclassResponsibility: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- copyWithZone: (NSZone*)z
|
||||
{
|
||||
NSSet *newSet;
|
||||
int count = [self count];
|
||||
id objects[count];
|
||||
id enumerator = [self objectEnumerator];
|
||||
id o;
|
||||
int i;
|
||||
|
||||
for (i = 0; (o = [enumerator nextObject]); i++)
|
||||
objects[i] = [o copyWithZone:z];
|
||||
|
||||
newSet = [[[self class] allocWithZone: z] initWithObjects: objects
|
||||
count: count];
|
||||
|
||||
for (i = 0; (o = [enumerator nextObject]); i++) {
|
||||
unsigned extra;
|
||||
|
||||
extra = [self countForObject: o];
|
||||
|
||||
if (extra > 1) {
|
||||
while (--extra) {
|
||||
[newSet addObject: o];
|
||||
}
|
||||
}
|
||||
[o release];
|
||||
}
|
||||
|
||||
return newSet;
|
||||
return [[[self class] allocWithZone: z] initWithSet: self copyItems: YES];
|
||||
}
|
||||
|
||||
- mutableCopyWithZone: (NSZone*)z
|
||||
{
|
||||
return [self copyWithZone: z];
|
||||
return [[[self class] allocWithZone: z] initWithSet: self copyItems: NO];
|
||||
}
|
||||
|
||||
- initWithCoder: aCoder
|
||||
{
|
||||
[self subclassResponsibility:_cmd];
|
||||
[self subclassResponsibility: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void) encodeWithCoder: aCoder
|
||||
{
|
||||
[self subclassResponsibility:_cmd];
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- initWithSet: (NSSet*)other copyItems: (BOOL)flag
|
||||
{
|
||||
int c = [other count];
|
||||
id os[c], o, e = [other objectEnumerator];
|
||||
int i = 0;
|
||||
unsigned c = [other count];
|
||||
id os[c], o, e = [other objectEnumerator];
|
||||
unsigned i = 0;
|
||||
NSZone *z = [self zone];
|
||||
|
||||
while ((o = [e nextObject]))
|
||||
{
|
||||
if (flag)
|
||||
os[i] = [o copy];
|
||||
os[i] = [o copyWithZone: z];
|
||||
else
|
||||
os[i] = o;
|
||||
i++;
|
||||
}
|
||||
self = [self initWithObjects:os count:c];
|
||||
self = [self initWithObjects: os count: c];
|
||||
if ([other isKindOfClass: [NSCountedSet class]])
|
||||
{
|
||||
int j;
|
||||
unsigned j;
|
||||
|
||||
for (j = 0; j < i; j++)
|
||||
{
|
||||
|
@ -142,7 +117,7 @@ static Class NSCountedSet_concrete_class;
|
|||
}
|
||||
}
|
||||
if (flag)
|
||||
while (--i)
|
||||
while (i--)
|
||||
[os[i] release];
|
||||
return self;
|
||||
}
|
||||
|
|
|
@ -157,17 +157,16 @@
|
|||
|
||||
- (unsigned) indexOfObject: anObject
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
if (anObject == nil)
|
||||
return NSNotFound;
|
||||
/*
|
||||
* For large arrays, speed things up a little by caching the method.
|
||||
*/
|
||||
if (_count > 8)
|
||||
if (_count > 1)
|
||||
{
|
||||
SEL sel = @selector(isEqual:);
|
||||
BOOL (*imp)(id,SEL,id);
|
||||
static SEL sel = @selector(isEqual:);
|
||||
BOOL (*imp)(id,SEL,id);
|
||||
unsigned i;
|
||||
|
||||
imp = (BOOL (*)(id,SEL,id))[anObject methodForSelector: sel];
|
||||
|
||||
|
@ -179,15 +178,9 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (_count == 1 && [anObject isEqual: _contents_array[0]])
|
||||
{
|
||||
for (i = 0; i < _count; i++)
|
||||
{
|
||||
if ([anObject isEqual: _contents_array[i]])
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return NSNotFound;
|
||||
}
|
||||
|
@ -442,21 +435,22 @@
|
|||
|
||||
- (void) replaceObjectAtIndex: (unsigned)index withObject: (id)anObject
|
||||
{
|
||||
id obj;
|
||||
id obj;
|
||||
|
||||
if (index >= _count) {
|
||||
[NSException raise: NSRangeException format:
|
||||
if (index >= _count)
|
||||
{
|
||||
[NSException raise: NSRangeException format:
|
||||
@"in replaceObjectAtIndex:withObject:, index %d is out of range",
|
||||
index];
|
||||
}
|
||||
/*
|
||||
* Swap objects in order so that there is always a valid object in the
|
||||
* array in case a retain or release causes an exception.
|
||||
*/
|
||||
obj = _contents_array[index];
|
||||
[anObject retain];
|
||||
_contents_array[index] = anObject;
|
||||
[obj release];
|
||||
}
|
||||
/*
|
||||
* Swap objects in order so that there is always a valid object in the
|
||||
* array in case a retain or release causes an exception.
|
||||
*/
|
||||
obj = _contents_array[index];
|
||||
[anObject retain];
|
||||
_contents_array[index] = anObject;
|
||||
[obj release];
|
||||
}
|
||||
|
||||
- (void) sortUsingFunction: (int(*)(id,id,void*))compare
|
||||
|
|
|
@ -100,12 +100,14 @@ myEqual(id self, id other)
|
|||
* The 'Fastmap' stuff provides an inline implementation of a mapping
|
||||
* table - for maximum performance.
|
||||
*/
|
||||
#define FAST_MAP_HASH(X) myHash(X.o)
|
||||
#define FAST_MAP_EQUAL(X,Y) myEqual(X.o,Y.o)
|
||||
#define FAST_MAP_RETAIN_KEY(X) ((id)(X).o) = \
|
||||
[((id)(X).o) copyWithZone: map->zone]
|
||||
#define FAST_MAP_KTYPES GSUNION_OBJ
|
||||
#define FAST_MAP_VTYPES GSUNION_OBJ
|
||||
#define FAST_MAP_HASH(X) myHash(X.obj)
|
||||
#define FAST_MAP_EQUAL(X,Y) myEqual(X.obj,Y.obj)
|
||||
#define FAST_MAP_RETAIN_KEY(X) ((id)(X).obj) = \
|
||||
[((id)(X).obj) copyWithZone: map->zone]
|
||||
|
||||
#include "FastMap.x"
|
||||
#include <base/FastMap.x>
|
||||
|
||||
@class NSDictionaryNonCore;
|
||||
@class NSMutableDictionaryNonCore;
|
||||
|
@ -165,8 +167,8 @@ myEqual(id self, id other)
|
|||
[aCoder encodeValueOfObjCType: @encode(unsigned) at: &count];
|
||||
while (node != 0)
|
||||
{
|
||||
(*imp)(aCoder, sel, node->key.o);
|
||||
(*imp)(aCoder, sel, node->value.o);
|
||||
(*imp)(aCoder, sel, node->key.obj);
|
||||
(*imp)(aCoder, sel, node->value.obj);
|
||||
node = node->nextInMap;
|
||||
}
|
||||
}
|
||||
|
@ -193,7 +195,7 @@ myEqual(id self, id other)
|
|||
{
|
||||
(*imp)(aCoder, sel, type, &key);
|
||||
(*imp)(aCoder, sel, type, &value);
|
||||
FastMapAddPairNoRetain(&map, (FastMapItem)key, (FastMapItem)value);
|
||||
FastMapAddPairNoRetain(&map, (FastMapKey)key, (FastMapVal)value);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
@ -221,16 +223,16 @@ myEqual(id self, id other)
|
|||
format: @"Tried to init dictionary with nil value"];
|
||||
}
|
||||
|
||||
node = FastMapNodeForKey(&map, (FastMapItem)keys[i]);
|
||||
node = FastMapNodeForKey(&map, (FastMapKey)keys[i]);
|
||||
if (node)
|
||||
{
|
||||
[objs[i] retain];
|
||||
[node->value.o release];
|
||||
node->value.o = objs[i];
|
||||
[node->value.obj release];
|
||||
node->value.obj = objs[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
FastMapAddPair(&map, (FastMapItem)keys[i], (FastMapItem)objs[i]);
|
||||
FastMapAddPair(&map, (FastMapKey)keys[i], (FastMapVal)objs[i]);
|
||||
}
|
||||
}
|
||||
return self;
|
||||
|
@ -276,15 +278,15 @@ myEqual(id self, id other)
|
|||
format: @"Tried to init dictionary with nil value"];
|
||||
}
|
||||
|
||||
node = FastMapNodeForKey(&map, (FastMapItem)k);
|
||||
node = FastMapNodeForKey(&map, (FastMapKey)k);
|
||||
if (node)
|
||||
{
|
||||
[node->value.o release];
|
||||
node->value.o = o;
|
||||
[node->value.obj release];
|
||||
node->value.obj = o;
|
||||
}
|
||||
else
|
||||
{
|
||||
FastMapAddPairNoRetain(&map, (FastMapItem)k, (FastMapItem)o);
|
||||
FastMapAddPairNoRetain(&map, (FastMapKey)k, (FastMapVal)o);
|
||||
}
|
||||
}
|
||||
return self;
|
||||
|
@ -306,11 +308,11 @@ myEqual(id self, id other)
|
|||
{
|
||||
if (aKey != nil)
|
||||
{
|
||||
FastMapNode node = FastMapNodeForKey(&map, (FastMapItem)aKey);
|
||||
FastMapNode node = FastMapNodeForKey(&map, (FastMapKey)aKey);
|
||||
|
||||
if (node)
|
||||
{
|
||||
return node->value.o;
|
||||
return node->value.obj;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
|
@ -350,16 +352,16 @@ myEqual(id self, id other)
|
|||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Tried to add nil value to dictionary"];
|
||||
}
|
||||
node = FastMapNodeForKey(&map, (FastMapItem)aKey);
|
||||
node = FastMapNodeForKey(&map, (FastMapKey)aKey);
|
||||
if (node)
|
||||
{
|
||||
[anObject retain];
|
||||
[node->value.o release];
|
||||
node->value.o = anObject;
|
||||
[node->value.obj release];
|
||||
node->value.obj = anObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
FastMapAddPair(&map, (FastMapItem)aKey, (FastMapItem)anObject);
|
||||
FastMapAddPair(&map, (FastMapKey)aKey, (FastMapVal)anObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -372,7 +374,7 @@ myEqual(id self, id other)
|
|||
{
|
||||
if (aKey)
|
||||
{
|
||||
FastMapRemoveKey(&map, (FastMapItem)aKey);
|
||||
FastMapRemoveKey(&map, (FastMapKey)aKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -397,7 +399,7 @@ myEqual(id self, id other)
|
|||
return nil;
|
||||
}
|
||||
node = node->nextInMap;
|
||||
return old->key.o;
|
||||
return old->key.obj;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
|
@ -419,7 +421,7 @@ myEqual(id self, id other)
|
|||
return nil;
|
||||
}
|
||||
node = node->nextInMap;
|
||||
return old->value.o;
|
||||
return old->value.obj;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -32,8 +32,9 @@
|
|||
#include <Foundation/NSPortCoder.h>
|
||||
|
||||
#define FAST_MAP_HAS_VALUE 0
|
||||
#define FAST_MAP_KTYPES GSUNION_OBJ
|
||||
|
||||
#include "FastMap.x"
|
||||
#include <base/FastMap.x>
|
||||
|
||||
@class NSSetNonCore;
|
||||
@class NSMutableSetNonCore;
|
||||
|
@ -78,7 +79,7 @@
|
|||
return nil;
|
||||
}
|
||||
node = node->nextInMap;
|
||||
return old->key.o;
|
||||
return old->key.obj;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
|
@ -121,7 +122,7 @@
|
|||
[aCoder encodeValueOfObjCType: @encode(unsigned) at: &count];
|
||||
while (node != 0)
|
||||
{
|
||||
(*imp)(aCoder, sel, node->key.o);
|
||||
(*imp)(aCoder, sel, node->key.obj);
|
||||
node = node->nextInMap;
|
||||
}
|
||||
}
|
||||
|
@ -145,7 +146,7 @@
|
|||
while (count-- > 0)
|
||||
{
|
||||
(*imp)(aCoder, sel, type, &value);
|
||||
FastMapAddKeyNoRetain(&map, (FastMapItem)value);
|
||||
FastMapAddKeyNoRetain(&map, (FastMapKey)value);
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -167,10 +168,10 @@
|
|||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Tried to init set with nil value"];
|
||||
}
|
||||
node = FastMapNodeForKey(&map, (FastMapItem)objs[i]);
|
||||
node = FastMapNodeForKey(&map, (FastMapKey)objs[i]);
|
||||
if (node == 0)
|
||||
{
|
||||
FastMapAddKey(&map, (FastMapItem)objs[i]);
|
||||
FastMapAddKey(&map, (FastMapKey)objs[i]);
|
||||
}
|
||||
}
|
||||
return self;
|
||||
|
@ -180,11 +181,11 @@
|
|||
{
|
||||
if (anObject)
|
||||
{
|
||||
FastMapNode node = FastMapNodeForKey(&map, (FastMapItem)anObject);
|
||||
FastMapNode node = FastMapNodeForKey(&map, (FastMapKey)anObject);
|
||||
|
||||
if (node)
|
||||
{
|
||||
return node->key.o;
|
||||
return node->key.obj;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
|
@ -224,10 +225,10 @@
|
|||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"Tried to add nil to set"];
|
||||
}
|
||||
node = FastMapNodeForKey(&map, (FastMapItem)anObject);
|
||||
node = FastMapNodeForKey(&map, (FastMapKey)anObject);
|
||||
if (node == 0)
|
||||
{
|
||||
FastMapAddKey(&map, (FastMapItem)anObject);
|
||||
FastMapAddKey(&map, (FastMapKey)anObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,7 +236,7 @@
|
|||
{
|
||||
if (anObject)
|
||||
{
|
||||
FastMapRemoveKey(&map, (FastMapItem)anObject);
|
||||
FastMapRemoveKey(&map, (FastMapKey)anObject);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -47,18 +47,19 @@
|
|||
#define FAST_MAP_RELEASE_KEY(X)
|
||||
#define FAST_MAP_RETAIN_VAL(X) X
|
||||
#define FAST_MAP_RELEASE_VAL(X)
|
||||
#define FAST_MAP_HASH(X) [(X).o hash]
|
||||
#define FAST_MAP_EQUAL(X,Y) [(X).o isEqualToString: (Y).o]
|
||||
#define FAST_MAP_HASH(X) [(X).obj hash]
|
||||
#define FAST_MAP_EQUAL(X,Y) [(X).obj isEqualToString: (Y).obj]
|
||||
|
||||
#include "FastMap.x"
|
||||
#include <base/FastMap.x>
|
||||
|
||||
/*
|
||||
* Setup for inline operation of string arrays.
|
||||
*/
|
||||
#define FAST_ARRAY_RETAIN(X) X
|
||||
#define FAST_ARRAY_RELEASE(X)
|
||||
#define FAST_ARRAY_TYPES GSUNION_OBJ
|
||||
|
||||
#include "FastArray.x"
|
||||
#include <base/FastArray.x>
|
||||
|
||||
/*
|
||||
* Define constants for data types and variables to hold them.
|
||||
|
@ -154,7 +155,7 @@ serializeToInfo(id object, _NSSerializerInfo* info)
|
|||
FastMapNode node;
|
||||
|
||||
if (info->shouldUnique)
|
||||
node = FastMapNodeForKey(&info->map, (FastMapItem)object);
|
||||
node = FastMapNodeForKey(&info->map, (FastMapKey)object);
|
||||
else
|
||||
node = 0;
|
||||
if (node == 0)
|
||||
|
@ -170,12 +171,12 @@ serializeToInfo(id object, _NSSerializerInfo* info)
|
|||
[object getCString: (*info->datImp)(info->data, datSel) + dlen];
|
||||
if (info->shouldUnique)
|
||||
FastMapAddPair(&info->map,
|
||||
(FastMapItem)object, (FastMapItem)info->count++);
|
||||
(FastMapKey)object, (FastMapVal)info->count++);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*info->appImp)(info->data, appSel, &st_xref, 1);
|
||||
(*info->serImp)(info->data, serSel, node->value.I);
|
||||
(*info->serImp)(info->data, serSel, node->value.uint);
|
||||
}
|
||||
}
|
||||
else if (fastClassIsKindOfClass(c, _fastCls._NSString))
|
||||
|
@ -183,7 +184,7 @@ serializeToInfo(id object, _NSSerializerInfo* info)
|
|||
FastMapNode node;
|
||||
|
||||
if (info->shouldUnique)
|
||||
node = FastMapNodeForKey(&info->map, (FastMapItem)object);
|
||||
node = FastMapNodeForKey(&info->map, (FastMapKey)object);
|
||||
else
|
||||
node = 0;
|
||||
if (node == 0)
|
||||
|
@ -199,12 +200,12 @@ serializeToInfo(id object, _NSSerializerInfo* info)
|
|||
[object getCharacters: (*info->datImp)(info->data, datSel) + dlen];
|
||||
if (info->shouldUnique)
|
||||
FastMapAddPair(&info->map,
|
||||
(FastMapItem)object, (FastMapItem)info->count++);
|
||||
(FastMapKey)object, (FastMapVal)info->count++);
|
||||
}
|
||||
else
|
||||
{
|
||||
(*info->appImp)(info->data, appSel, &st_xref, 1);
|
||||
(*info->serImp)(info->data, serSel, node->value.I);
|
||||
(*info->serImp)(info->data, serSel, node->value.uint);
|
||||
}
|
||||
}
|
||||
else if (fastClassIsKindOfClass(c, ArrayClass))
|
||||
|
@ -390,7 +391,7 @@ deserializeFromInfo(_NSDeserializerInfo* info)
|
|||
{
|
||||
case ST_XREF:
|
||||
{
|
||||
return [FastArrayItemAtIndex(&info->array, size).o retain];
|
||||
return [FastArrayItemAtIndex(&info->array, size).obj retain];
|
||||
}
|
||||
|
||||
case ST_CSTRING:
|
||||
|
|
130
Source/NSSet.m
130
Source/NSSet.m
|
@ -42,10 +42,11 @@ static Class NSMutableSet_concrete_class;
|
|||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSSet class]) {
|
||||
NSSet_concrete_class = [NSGSet class];
|
||||
NSMutableSet_concrete_class = [NSGMutableSet class];
|
||||
behavior_class_add_class(self, [NSSetNonCore class]);
|
||||
if (self == [NSSet class])
|
||||
{
|
||||
NSSet_concrete_class = [NSGSet class];
|
||||
NSMutableSet_concrete_class = [NSGMutableSet class];
|
||||
behavior_class_add_class(self, [NSSetNonCore class]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,29 +72,23 @@ static Class NSMutableSet_concrete_class;
|
|||
|
||||
+ set
|
||||
{
|
||||
return [[[self alloc] init]
|
||||
autorelease];
|
||||
return [[[self alloc] init] autorelease];
|
||||
}
|
||||
|
||||
+ setWithObjects: (id*)objects
|
||||
count: (unsigned)count
|
||||
{
|
||||
return [[[self alloc] initWithObjects: objects
|
||||
count: count]
|
||||
autorelease];
|
||||
return [[[self alloc] initWithObjects: objects count: count] autorelease];
|
||||
}
|
||||
|
||||
+ setWithArray: (NSArray*)objects
|
||||
{
|
||||
return [[[self alloc] initWithArray: objects]
|
||||
autorelease];
|
||||
return [[[self alloc] initWithArray: objects] autorelease];
|
||||
}
|
||||
|
||||
+ setWithObject: anObject
|
||||
{
|
||||
return [[[self alloc] initWithObjects: &anObject
|
||||
count: 1]
|
||||
autorelease];
|
||||
return [[[self alloc] initWithObjects: &anObject count: 1] autorelease];
|
||||
}
|
||||
|
||||
+ setWithObjects: firstObject, ...
|
||||
|
@ -107,8 +102,7 @@ static Class NSMutableSet_concrete_class;
|
|||
|
||||
+ setWithSet: (NSSet*)aSet
|
||||
{
|
||||
return [[[self alloc] initWithSet: aSet]
|
||||
autorelease];
|
||||
return [[[self alloc] initWithSet: aSet] autorelease];
|
||||
}
|
||||
|
||||
+ allocWithZone: (NSZone*)z
|
||||
|
@ -152,12 +146,12 @@ static Class NSMutableSet_concrete_class;
|
|||
return [self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- copyWithZone: (NSZone*)z
|
||||
- (id) copyWithZone: (NSZone*)z
|
||||
{
|
||||
return [self retain];
|
||||
}
|
||||
|
||||
- mutableCopyWithZone: (NSZone*)z
|
||||
- (id) mutableCopyWithZone: (NSZone*)z
|
||||
{
|
||||
return [[[[self class] _mutableConcreteClass] allocWithZone: z]
|
||||
initWithSet: self];
|
||||
|
@ -232,24 +226,26 @@ static Class NSMutableSet_concrete_class;
|
|||
|
||||
- initWithArray: (NSArray*)other
|
||||
{
|
||||
unsigned count = [other count];
|
||||
unsigned count = [other count];
|
||||
|
||||
if (count == 0) {
|
||||
return [self init];
|
||||
if (count == 0)
|
||||
{
|
||||
return [self init];
|
||||
}
|
||||
else {
|
||||
id objs[count];
|
||||
else
|
||||
{
|
||||
id objs[count];
|
||||
|
||||
[other getObjects: objs];
|
||||
return [self initWithObjects: objs count: count];
|
||||
[other getObjects: objs];
|
||||
return [self initWithObjects: objs count: count];
|
||||
}
|
||||
}
|
||||
|
||||
- initWithSet: (NSSet*)other copyItems: (BOOL)flag
|
||||
- (id) initWithSet: (NSSet*)other copyItems: (BOOL)flag
|
||||
{
|
||||
int c = [other count];
|
||||
id os[c], o, e = [other objectEnumerator];
|
||||
int i = 0;
|
||||
unsigned c = [other count];
|
||||
id os[c], o, e = [other objectEnumerator];
|
||||
unsigned i = 0;
|
||||
|
||||
while ((o = [e nextObject]))
|
||||
{
|
||||
|
@ -261,31 +257,30 @@ static Class NSMutableSet_concrete_class;
|
|||
}
|
||||
self = [self initWithObjects: os count: c];
|
||||
if (flag)
|
||||
while (--i)
|
||||
while (i--)
|
||||
[os[i] release];
|
||||
return self;
|
||||
}
|
||||
|
||||
- initWithSet: (NSSet*)other
|
||||
- (id) initWithSet: (NSSet*)other
|
||||
{
|
||||
return [self initWithSet: other copyItems: NO];
|
||||
}
|
||||
|
||||
- (NSArray*) allObjects
|
||||
{
|
||||
id e = [self objectEnumerator];
|
||||
int i, c = [self count];
|
||||
id k[c];
|
||||
id e = [self objectEnumerator];
|
||||
unsigned i, c = [self count];
|
||||
id k[c];
|
||||
|
||||
for (i = 0; i < c; i++)
|
||||
{
|
||||
k[i] = [e nextObject];
|
||||
}
|
||||
return [[[NSArray alloc] initWithObjects: k count: c]
|
||||
autorelease];
|
||||
return [[[NSArray alloc] initWithObjects: k count: c] autorelease];
|
||||
}
|
||||
|
||||
- anyObject
|
||||
- (id) anyObject
|
||||
{
|
||||
if ([self count] == 0)
|
||||
return nil;
|
||||
|
@ -303,50 +298,55 @@ static Class NSMutableSet_concrete_class;
|
|||
|
||||
- (unsigned) hash
|
||||
{
|
||||
return [self count];
|
||||
return [self count];
|
||||
}
|
||||
|
||||
- (void) makeObjectsPerform: (SEL)aSelector
|
||||
{
|
||||
id o, e = [self objectEnumerator];
|
||||
id o, e = [self objectEnumerator];
|
||||
|
||||
while ((o = [e nextObject]))
|
||||
[o performSelector: aSelector];
|
||||
}
|
||||
|
||||
- (void) makeObjectsPerformSelector: (SEL)aSelector
|
||||
{
|
||||
id o, e = [self objectEnumerator];
|
||||
id o, e = [self objectEnumerator];
|
||||
|
||||
while ((o = [e nextObject]))
|
||||
[o performSelector: aSelector];
|
||||
}
|
||||
|
||||
- (void) makeObjectsPerformSelector: (SEL)aSelector withObject: argument
|
||||
{
|
||||
id o, e = [self objectEnumerator];
|
||||
id o, e = [self objectEnumerator];
|
||||
|
||||
while ((o = [e nextObject]))
|
||||
[o performSelector: aSelector withObject: argument];
|
||||
}
|
||||
|
||||
- (void) makeObjectsPerform: (SEL)aSelector withObject: argument
|
||||
{
|
||||
id o, e = [self objectEnumerator];
|
||||
id o, e = [self objectEnumerator];
|
||||
|
||||
while ((o = [e nextObject]))
|
||||
[o performSelector: aSelector withObject: argument];
|
||||
}
|
||||
|
||||
- (BOOL) intersectsSet: (NSSet*) otherSet
|
||||
{
|
||||
id o = nil, e = nil;
|
||||
id o = nil, e = nil;
|
||||
|
||||
// -1. If this set is empty, this method should return NO.
|
||||
if ([self count] == 0) return NO;
|
||||
if ([self count] == 0)
|
||||
return NO;
|
||||
|
||||
// 0. Loop for all members in otherSet
|
||||
e = [otherSet objectEnumerator];
|
||||
while ((o = [e nextObject])) // 1. pick a member from otherSet.
|
||||
{
|
||||
if ([self member: o]) // 2. check the member is in this set(self).
|
||||
return YES;
|
||||
return YES;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
@ -356,7 +356,8 @@ static Class NSMutableSet_concrete_class;
|
|||
id o = nil, e = nil;
|
||||
|
||||
// -1. members of this set(self) <= that of otherSet
|
||||
if ([self count] > [otherSet count]) return NO;
|
||||
if ([self count] > [otherSet count])
|
||||
return NO;
|
||||
|
||||
// 0. Loop for all members in this set(self).
|
||||
e = [self objectEnumerator];
|
||||
|
@ -389,12 +390,14 @@ static Class NSMutableSet_concrete_class;
|
|||
{
|
||||
if ([self count] != [other count])
|
||||
return NO;
|
||||
{
|
||||
id o, e = [self objectEnumerator];
|
||||
while ((o = [e nextObject]))
|
||||
if (![other member: o])
|
||||
return NO;
|
||||
}
|
||||
else
|
||||
{
|
||||
id o, e = [self objectEnumerator];
|
||||
|
||||
while ((o = [e nextObject]))
|
||||
if (![other member: o])
|
||||
return NO;
|
||||
}
|
||||
/* xxx Recheck this. */
|
||||
return YES;
|
||||
}
|
||||
|
@ -415,31 +418,30 @@ static Class NSMutableSet_concrete_class;
|
|||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (self == [NSMutableSet class]) {
|
||||
behavior_class_add_class(self, [NSMutableSetNonCore class]);
|
||||
behavior_class_add_class(self, [NSSetNonCore class]);
|
||||
if (self == [NSMutableSet class])
|
||||
{
|
||||
behavior_class_add_class(self, [NSMutableSetNonCore class]);
|
||||
behavior_class_add_class(self, [NSSetNonCore class]);
|
||||
}
|
||||
}
|
||||
|
||||
+ setWithCapacity: (unsigned)numItems
|
||||
+ (id) setWithCapacity: (unsigned)numItems
|
||||
{
|
||||
return [[[self alloc] initWithCapacity: numItems]
|
||||
autorelease];
|
||||
return [[[self alloc] initWithCapacity: numItems] autorelease];
|
||||
}
|
||||
|
||||
+ allocWithZone: (NSZone*)z
|
||||
+ (id) allocWithZone: (NSZone*)z
|
||||
{
|
||||
return NSAllocateObject([self _mutableConcreteClass], 0, z);
|
||||
}
|
||||
|
||||
- copyWithZone: (NSZone*)z
|
||||
- (id) copyWithZone: (NSZone*)z
|
||||
{
|
||||
return [[[[self class] _concreteClass] allocWithZone: z]
|
||||
initWithSet: self];
|
||||
return [[[[self class] _concreteClass] allocWithZone: z] initWithSet: self];
|
||||
}
|
||||
|
||||
/* This is the designated initializer */
|
||||
- initWithCapacity: (unsigned)numItems
|
||||
- (id) initWithCapacity: (unsigned)numItems
|
||||
{
|
||||
return [self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
@ -470,7 +472,7 @@ static Class NSMutableSet_concrete_class;
|
|||
|
||||
- (void) addObjectsFromArray: (NSArray*)array
|
||||
{
|
||||
int i, c = [array count];
|
||||
unsigned i, c = [array count];
|
||||
|
||||
for (i = 0; i < c; i++)
|
||||
[self addObject: [array objectAtIndex: i]];
|
||||
|
|
|
@ -32,8 +32,9 @@
|
|||
*/
|
||||
#define FAST_ARRAY_RETAIN(X) X
|
||||
#define FAST_ARRAY_RELEASE(X)
|
||||
#define FAST_ARRAY__TYPES GSUNION_OBJ
|
||||
|
||||
#include "FastArray.x"
|
||||
#include <base/FastArray.x>
|
||||
|
||||
#define _IN_NSUNARCHIVER_M
|
||||
#include <Foundation/NSArchiver.h>
|
||||
|
@ -507,7 +508,7 @@ mapClassName(NSUnarchiverObjectInfo *info)
|
|||
format: @"object crossref missing - %d",
|
||||
xref];
|
||||
}
|
||||
obj = FastArrayItemAtIndex(objMap, xref).o;
|
||||
obj = FastArrayItemAtIndex(objMap, xref).obj;
|
||||
/*
|
||||
* If it's a cross-reference, we need to retain it in
|
||||
* order to give the appearance that it's actually a
|
||||
|
@ -572,7 +573,7 @@ mapClassName(NSUnarchiverObjectInfo *info)
|
|||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"class crossref missing - %d", xref];
|
||||
}
|
||||
classInfo = (NSUnarchiverObjectInfo*)FastArrayItemAtIndex(clsMap, xref).o;
|
||||
classInfo = (NSUnarchiverObjectInfo*)FastArrayItemAtIndex(clsMap, xref).obj;
|
||||
*(Class*)address = mapClassObject(classInfo);
|
||||
return;
|
||||
}
|
||||
|
@ -640,7 +641,7 @@ mapClassName(NSUnarchiverObjectInfo *info)
|
|||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"sel crossref missing - %d", xref];
|
||||
}
|
||||
sel = FastArrayItemAtIndex(ptrMap, xref).C;
|
||||
sel = FastArrayItemAtIndex(ptrMap, xref).sel;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -717,7 +718,7 @@ mapClassName(NSUnarchiverObjectInfo *info)
|
|||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"ptr crossref missing - %d", xref];
|
||||
}
|
||||
*(void**)address = FastArrayItemAtIndex(ptrMap, xref).p;
|
||||
*(void**)address = FastArrayItemAtIndex(ptrMap, xref).ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -766,7 +767,7 @@ mapClassName(NSUnarchiverObjectInfo *info)
|
|||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"string crossref missing - %d", xref];
|
||||
}
|
||||
*(char**)address = FastArrayItemAtIndex(ptrMap, xref).s;
|
||||
*(char**)address = FastArrayItemAtIndex(ptrMap, xref).str;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1013,7 +1014,7 @@ mapClassName(NSUnarchiverObjectInfo *info)
|
|||
format: @"object crossref missing - %d",
|
||||
xref];
|
||||
}
|
||||
obj = FastArrayItemAtIndex(objMap, xref).o;
|
||||
obj = FastArrayItemAtIndex(objMap, xref).obj;
|
||||
/*
|
||||
* If it's a cross-reference, we don't need to autorelease it
|
||||
* since we don't own it.
|
||||
|
@ -1155,9 +1156,11 @@ mapClassName(NSUnarchiverObjectInfo *info)
|
|||
{
|
||||
unsigned i;
|
||||
|
||||
if (replacement == anObject)
|
||||
return;
|
||||
for (i = FastArrayCount(objMap) - 1; i > 0; i--)
|
||||
{
|
||||
if (FastArrayItemAtIndex(objMap, i).o == anObject)
|
||||
if (FastArrayItemAtIndex(objMap, i).obj == anObject)
|
||||
{
|
||||
FastArraySetItemAtIndex(objMap, (FastArrayItem)replacement, i);
|
||||
return;
|
||||
|
|
|
@ -1757,5 +1757,20 @@ NSZoneStats (NSZone *zone)
|
|||
return (zone->stats)(zone);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/*
|
||||
* Dummy zone used with garbage collection.
|
||||
* In some places we make a distinction between the nul zone and the dummy
|
||||
* zone - items pointed to by memory in the nul zone can be deallocated by
|
||||
* the gc mechanism, while those pointed to from memory in the dummy zone
|
||||
* can't.
|
||||
*/
|
||||
static NSZone default_zone =
|
||||
{
|
||||
0, 0, 0, 0, 0, 0, 0, 0, @"default", 0
|
||||
};
|
||||
NSZone* __nszone_private_hidden_default_zone = &default_zone;
|
||||
|
||||
#endif /* GS_WITH_GC */
|
||||
|
||||
|
|
Loading…
Reference in a new issue