Remove old source

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@12356 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
fedor 2002-02-01 04:00:57 +00:00
parent 3cd3290404
commit babf23255c
125 changed files with 7 additions and 28856 deletions

View file

@ -1,3 +1,8 @@
2002-01-31 Adam Fedor <fedor@gnu.org>
* Old/*: Removed (now at
ftp://ftp.gnustep.org/pub/gnustep/old/gnustep-obsolete.tar.gz).
2002-01-31 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSMapTable.m:

View file

@ -14,8 +14,7 @@ The GNUstep Base Library is a library of general-purpose, non-graphical
Objective C objects. For example, it includes classes for strings,
object collections, byte streams, typed coders, invocations,
notifications, notification dispatchers, moments in time, network ports,
remote object messaging support (distributed objects), event loops, and
random number generators.
remote object messaging support (distributed objects), and event loops.
It provides functionality that aims to implement the non-graphical
portion of the OpenStep standard (the Foundation library).

View file

@ -7,8 +7,7 @@ The GNUstep Base Library is a library of general-purpose, non-graphical
Objective C objects. For example, it includes classes for strings,
object collections, byte streams, typed coders, invocations,
notifications, notification dispatchers, moments in time, network ports,
remote object messaging support (distributed objects), event loops, and
random number generators.
remote object messaging support (distributed objects), and event loops.
It provides functionality that aims to implement the non-graphical
portion of the OpenStep standard (the Foundation library).

View file

@ -1,41 +0,0 @@
/* Interface for GNU Objective-C Archiver object for use serializing
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: January 1996
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Archiver_h_GNUSTEP_BASE_INCLUDE
#define __Archiver_h_GNUSTEP_BASE_INCLUDE
#include <base/Coder.h>
/* Eventually some functionality may be moved out of Coder and
into these objects.
These class should be used as concrete classes, not the Coder class. */
@interface Archiver : Encoder
@end
@interface Unarchiver : Decoder
@end
#endif /* __Archiver_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,38 +0,0 @@
/* Implementation of GNU Objective-C class for writing objects to files
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: January 1996
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/preface.h>
#include <base/Archiver.h>
/* Eventually some functionality may be moved out of Encoder and
Decoder and into these objects.
These class should be used as concrete classes, not the Coder,
Encoder or Decoder classes. */
@implementation Archiver
@end
@implementation Unarchiver
@end

View file

@ -1,72 +0,0 @@
/* Interface for Objective-C Array collection object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Array_h_GNUSTEP_BASE_INCLUDE
#define __Array_h_GNUSTEP_BASE_INCLUDE
#include <base/IndexedCollection.h>
#include <base/OrderedCollecting.h>
@interface ConstantArray : ConstantIndexedCollection
{
@public
id *_contents_array;
unsigned int _count;
}
@end
@interface Array : ConstantArray
{
@public
unsigned int _capacity;
int _grow_factor;
}
+ (unsigned) defaultCapacity;
+ (int) defaultGrowFactor;
- initWithCapacity: (unsigned) aCapacity;
- (void) setCapacity: (unsigned)newCapacity;
- (int) growFactor;
- (void) setGrowFactor: (int)aNum;
@end
/* Put this on category instead of class to avoid bogus complaint from gcc */
@interface Array (Ordering) <OrderedCollecting>
@end
#define FOR_ARRAY(ARRAY, ELEMENT_VAR) \
{ \
unsigned _FOR_ARRAY_i; \
for (_FOR_ARRAY_i = 0; \
_FOR_ARRAY_i < ((Array*)ARRAY)->_count; \
_FOR_ARRAY_i++) \
{ \
ELEMENT_VAR = \
(((Array*)ARRAY)->_contents_array[_FOR_ARRAY_i]);
#define END_FOR_ARRAY(ARRAY) }}
#endif /* __Array_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,263 +0,0 @@
/* Implementation for Objective-C Array collection object
Copyright (C) 1993,1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/Array.h>
#include <base/ArrayPrivate.h>
#include <base/NSString.h>
#include <base/OrderedCollection.h>
#include <base/behavior.h>
@implementation ConstantArray
/* This is the designated initializer of this class */
- initWithObjects: (id*)objs count: (unsigned)c
{
_count = c;
OBJC_MALLOC(_contents_array, id, _count);
while (c--)
_contents_array[c] = objs[c];
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
Array *copy = [super emptyCopy];
copy->_count = 0;
OBJC_MALLOC(copy->_contents_array, id, copy->_capacity);
return copy;
}
- (void) _collectionDealloc
{
OBJC_FREE(_contents_array);
[super _collectionDealloc];
}
// GETTING ELEMENTS BY INDEX;
- objectAtIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count);
return _contents_array[index];
}
// TESTING;
- (unsigned) count
{
return _count;
}
@end
@implementation Array
+ (void) initialize
{
if (self == [Array class])
class_add_behavior (self, [OrderedCollection class]);
}
// MANAGING CAPACITY;
/* Eventually we will want to have better capacity management,
potentially keep default capacity as a class variable. */
+ (unsigned) defaultCapacity
{
return DEFAULT_ARRAY_CAPACITY;
}
+ (int) defaultGrowFactor
{
return DEFAULT_ARRAY_GROW_FACTOR;
}
/* This is the designated initializer for this class */
- initWithCapacity: (unsigned)aCapacity
{
_grow_factor = [[self class] defaultGrowFactor];
_count = 0;
_capacity = (aCapacity < 1) ? 1 : aCapacity;
OBJC_MALLOC(_contents_array, id, _capacity);
return self;
}
/* Archiving must mimic the above designated initializer */
- (void) _encodeCollectionWithCoder: (id <Encoding>)coder
{
[super _encodeCollectionWithCoder:coder];
[coder encodeValueOfCType:@encode(unsigned)
at:&_grow_factor
withName:@"Array Grow Factor"];
[coder encodeValueOfCType:@encode(unsigned)
at:&_capacity
withName:@"Array Capacity"];
}
- _initCollectionWithCoder: (id <Decoding>)coder
{
[super _initCollectionWithCoder:coder];
[coder decodeValueOfCType:@encode(unsigned)
at:&_grow_factor
withName:NULL];
_count = 0;
[coder decodeValueOfCType:@encode(unsigned)
at:&_capacity
withName:NULL];
return self;
}
/* Override superclass' designated initializer to call ours */
- initWithObjects: (id*)objs count: (unsigned)c
{
int i;
[self initWithCapacity: c];
for (i = 0; i < c; i++)
[self insertObject: objs[i] atIndex: i]; // xxx this most efficient method?
return self;
}
/* This must work without sending any messages to content objects */
- (void) empty
{
int i;
for (i = 0; i < _count; i++)
[_contents_array[i] release];
_count = 0;
/* Note this may not work for subclassers. Beware. */
}
// MANAGING CAPACITY;
/* This is the only method that changes the value of the instance
variable _capacity, except for "-initDescription:capacity:" */
- (void) setCapacity: (unsigned)newCapacity
{
if (newCapacity > _count) {
_capacity = newCapacity;
OBJC_REALLOC(_contents_array, id, _capacity);
}
}
- (int) growFactor
{
return _grow_factor;
}
- (void) setGrowFactor: (int)aNum;
{
_grow_factor = aNum;
}
// ADDING;
- (void) appendObject: newObject
{
/* Check to make sure that anObject is not nil, first. */
if (newObject == nil)
{
[NSException raise: NSInvalidArgumentException
format: @"Array: object to add is nil"
];
}
/* Now we can add it. */
incrementCount(self);
[newObject retain];
_contents_array[_count-1] = newObject;
}
- (void) prependObject: newObject
{
incrementCount(self);
[newObject retain];
makeHoleAt(self, 0);
_contents_array[0] = newObject;
}
- (void) insertObject: newObject atIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count+1);
/* Check to make sure that anObject is not nil, first. */
if (newObject == nil)
{
[NSException raise: NSInvalidArgumentException
format: @"Array: object to insert is nil"
];
}
incrementCount(self);
[newObject retain];
makeHoleAt(self, index);
_contents_array[index] = newObject;
}
// REMOVING, REPLACING AND SWAPPING;
- (void) removeObjectAtIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count);
[_contents_array[index] release];
fillHoleAt(self, index);
decrementCount(self);
}
/* We could be more efficient if we override these also.
- removeFirstObject
- removeLastObject;
If you do, remember, you will have to implement this methods
in GapArray also! */
- (void) replaceObjectAtIndex: (unsigned)index withObject: newObject
{
CHECK_INDEX_RANGE_ERROR(index, _count);
[newObject retain];
[_contents_array[index] release];
_contents_array[index] = newObject;
}
- (void) swapAtIndeces: (unsigned)index1 : (unsigned)index2
{
id tmp;
CHECK_INDEX_RANGE_ERROR(index1, _count);
CHECK_INDEX_RANGE_ERROR(index2, _count);
tmp = _contents_array[index1];
_contents_array[index1] = _contents_array[index2];
_contents_array[index2] = tmp;
}
@end

View file

@ -1,87 +0,0 @@
/* Array definitions for the use of subclass implementations only
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __ArrayPrivate_h_GNUSTEP_BASE_INCLUDE
#define __ArrayPrivate_h_GNUSTEP_BASE_INCLUDE
#include <base/IndexedCollectionPrivate.h>
#define DEFAULT_ARRAY_CAPACITY 2
#define DEFAULT_ARRAY_GROW_FACTOR 2
/* Routines that help with inserting and removing elements */
/* Assumes that _count has already been incremented to make room
for the hole. The data at _contents_array[_count-1] is not part
of the collection). */
static inline void
makeHoleAt(Array *self, unsigned index)
{
int i;
for (i = (self->_count)-1; i > index; i--)
self->_contents_array[i] = self->_contents_array[i-1];
}
/* Assumes that _count has not yet been decremented. The data at
_contents_array[_count-1] is part of the collection. */
static inline void
fillHoleAt(Array *self, unsigned index)
{
int i;
for (i = index; i < (self->_count)-1; i++)
self->_contents_array[i] = self->_contents_array[i+1];
}
/* These are the only two routines that change the value of the instance
variable _count, except for "-initWithType:capacity:" and "-empty" */
/* Should these be methods instead of functions? Doing so would make
them slower. */
/* Do this before adding an element */
static inline void
incrementCount(Array *self)
{
(self->_count)++;
if (self->_count == self->_capacity)
{
[self setCapacity:(self->_capacity) * ABS(self->_grow_factor)];
}
}
/* Do this after removing an element */
static inline void
decrementCount(Array *self)
{
(self->_count)--;
if (self->_grow_factor > 0
&& self->_count < (self->_capacity / self->_grow_factor))
{
[self setCapacity:(self->_capacity) / self->_grow_factor];
}
}
#endif /* __ArrayPrivate_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,50 +0,0 @@
/* Interface for Objective-C Bag collection object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Bag_h_GNUSTEP_BASE_INCLUDE
#define __Bag_h_GNUSTEP_BASE_INCLUDE
#include <base/Collection.h>
#include <Foundation/NSMapTable.h>
@interface Bag : Collection
{
NSMapTable *_contents_map;
unsigned int _count; // the number of elements;
}
// INITIALIZING AND FREEING;
- initWithCapacity: (unsigned)aCapacity;
// ADDING;
- (void) addObject: newObject withOccurrences: (unsigned)count;
// REMOVING AND REPLACING;
- (void) removeObject: oldObject occurrences: (unsigned)count;
// TESTING;
- (unsigned) uniqueCount;
@end
#endif /* __Bag_h_GNUSTEP_BASE_INCLUDE */

211
Old/Bag.m
View file

@ -1,211 +0,0 @@
/* Implementation for Objective-C Bag collection object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/Bag.h>
#include <base/CollectionPrivate.h>
#define DEFAULT_BAG_CAPACITY 32
@implementation Bag
// MANAGING CAPACITY;
/* Eventually we will want to have better capacity management,
potentially keep default capacity as a class variable. */
+ (unsigned) defaultCapacity
{
return DEFAULT_BAG_CAPACITY;
}
// INITIALIZING AND FREEING;
/* This is the designated initializer of this class */
/* Override designated initializer of superclass */
- initWithCapacity: (unsigned)cap
{
_contents_map = NSCreateMapTable (NSObjectMapKeyCallBacks,
NSIntMapValueCallBacks,
cap);
_count = 0;
return self;
}
/* Override Collection's designated initializer */
- initWithObjects: (id*)objs count: (unsigned)count
{
[self initWithCapacity: count];
while (count--)
[self addObject: objs[count]];
return self;
}
/* Archiving must mimic the above designated initializer */
/* Archiving must mimic the above designated initializer */
- (void) encodeWithCoder: anEncoder
{
[self notImplemented:_cmd];
}
- initWithCoder: aDecoder
{
[self notImplemented:_cmd];
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
Bag *copy = [super emptyCopy];
copy->_contents_map = NSCreateMapTable (NSObjectMapKeyCallBacks,
NSIntMapValueCallBacks,
0);
copy->_count = 0;
return copy;
}
- (void) dealloc
{
NSFreeMapTable (_contents_map);
[super _collectionDealloc];
}
/* This must work without sending any messages to content objects */
- (void) _collectionEmpty
{
NSResetMapTable (_contents_map);
_count = 0;
}
// ADDING;
- (void) addObject: newObject withOccurrences: (unsigned)count
{
unsigned new_count = (unsigned) NSMapGet (_contents_map, newObject);
new_count += count;
NSMapInsert (_contents_map, newObject, (void*)new_count);
_count += count;
}
- (void) addObject: newObject
{
[self addObject: newObject withOccurrences: 1];
}
// REMOVING AND REPLACING;
- (void) removeObject: oldObject occurrences: (unsigned)count
{
unsigned c = (unsigned) NSMapGet (_contents_map, oldObject);
if (c)
{
if (c <= count)
{
NSMapRemove (_contents_map, oldObject);
_count -= c;
}
else
{
NSMapInsert (_contents_map, oldObject, (void*)(c - count));
_count -= count;
}
}
}
- (void) removeObject: oldObject
{
[self removeObject: oldObject occurrences:1];
}
- (void) uniqueContents
{
[self notImplemented: _cmd];
}
// TESTING;
- (unsigned) count
{
return _count;
}
- (unsigned) uniqueCount
{
return NSCountMapTable (_contents_map);
}
- (unsigned) occurrencesOfObject: anObject
{
return (unsigned) NSMapGet (_contents_map, anObject);
}
// ENUMERATING;
struct BagEnumState
{
NSMapEnumerator me;
id object;
unsigned count;
};
#define ES ((struct BagEnumState *) *enumState)
- nextObjectWithEnumState: (void**)enumState
{
if (!(ES->count))
if (!NSNextMapEnumeratorPair (&(ES->me),
(void**) &(ES->object),
(void**) &(ES->count)))
return NO_OBJECT;
ES->count--;
return ES->object;
}
- (void*) newEnumState
{
/* init for start of enumeration. */
void *vp;
void **enumState = &vp;
OBJC_MALLOC(*enumState, struct BagEnumState, 1);
ES->me = NSEnumerateMapTable (_contents_map);
ES->object = nil;
ES->count = 0;
return vp;
}
- (void) freeEnumState: (void**)enumState
{
if (*enumState)
OBJC_FREE(*enumState);
}
@end

View file

@ -1,42 +0,0 @@
/* Interface for GNU Objective-C binary stream object for use serializing
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Written: Jan 1996
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __BinaryCStream_h_GNUSTEP_BASE_INCLUDE
#define __BinaryCStream_h_GNUSTEP_BASE_INCLUDE
#include <base/Stream.h>
#include <base/CStream.h>
@interface BinaryCStream : CStream
{
unsigned char _sizeof_long;
unsigned char _sizeof_int;
unsigned char _sizeof_short;
unsigned char _sizeof_char;
}
+ setDebugging: (BOOL)f;
@end
#endif /* __BinaryCStream_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,646 +0,0 @@
/* Implementation of GNU Objective-C binary stream object for use serializing
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Written: Jan 1996
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/preface.h>
#include <base/BinaryCStream.h>
#include <base/NSString.h>
#include <base/StdioStream.h>
#include <base/TextCStream.h>
#include <Foundation/NSData.h>
#include <Foundation/NSException.h>
#include <Foundation/NSByteOrder.h>
#include <math.h>
#if HAVE_VALUES_H
#include <values.h> // This gets BITSPERBYTE on Solaris
#endif
#define PRE_SIZEOF_PREFIX_FORMAT_VERSION 0
#define CURRENT_FORMAT_VERSION ((((GNUSTEP_BASE_MAJOR_VERSION * 100) + \
GNUSTEP_BASE_MINOR_VERSION) * 100) + GNUSTEP_BASE_SUBMINOR_VERSION)
#define DEFAULT_FORMAT_VERSION CURRENT_FORMAT_VERSION
#define ROUND(V, A) \
({ typeof(V) __v=(V); typeof(A) __a=(A); \
__a*((__v+__a-1)/__a); })
/* The number of bytes used to encode the length of a _C_CHARPTR
string that is encoded. */
#define NUM_BYTES_STRING_LENGTH 4
/* The value by which we multiply a float or double in order to bring
mantissa digits to the left-hand-side of the decimal point, so that
we can extract them by assigning the float or double to an int. */
#if !defined(BITSPERBYTE) && defined(NeXT)
#include <mach/vm_param.h>
#define BITSPERBYTE BYTE_SIZE
#elif !defined(BITSPERBYTE)
#define BITSPERBYTE 8 /* a safe guess? */
#endif
#define FLOAT_FACTOR ((double)(1 << ((sizeof(int)*BITSPERBYTE)-2)))
@implementation BinaryCStream
+ (void) initialize
{
if (self == [BinaryCStream class])
/* Make sure that we don't overrun memory when reading _C_CHARPTR. */
NSAssert (sizeof(unsigned) >= NUM_BYTES_STRING_LENGTH,
@"_C_CHARPTR overruns memory");
}
/* For debugging */
static int debug_binary_coder = 0;
+ setDebugging: (BOOL)f
{
debug_binary_coder = f;
return self;
}
+ debugStderrCoder
{
static id c = nil;
if (!c)
c = [[TextCStream alloc]
initForWritingToStream: [StdioStream standardError]];
return c;
}
/* This is the designated initializer for reading. */
- _initForReadingFromPostSignatureStream: (id <Streaming>)s
withFormatVersion: (int)version
{
[super _initForReadingFromPostSignatureStream: s
withFormatVersion: version];
if (version > PRE_SIZEOF_PREFIX_FORMAT_VERSION)
{
/* Read the C-type sizes to expect. */
[s readByte: &_sizeof_long];
[s readByte: &_sizeof_int];
[s readByte: &_sizeof_short];
[s readByte: &_sizeof_char];
}
return self;
}
/* This is a designated initializer for writing. */
- initForWritingToStream: (id <Streaming>) s
withFormatVersion: (int)version
{
[super initForWritingToStream: s
withFormatVersion: version];
if (version > PRE_SIZEOF_PREFIX_FORMAT_VERSION)
{
[s writeByte: sizeof (long)];
[s writeByte: sizeof (int)];
[s writeByte: sizeof (short)];
[s writeByte: sizeof (char)];
}
return self;
}
/* Encoding/decoding C values */
- (void) encodeValueOfCType: (const char*)type
at: (const void*)d
withName: (NSString*) name
{
if (!type)
[NSException raise:NSInvalidArgumentException format:@"type is NULL"];
/* Make sure we're not being asked to encode an "ObjC" type. */
NSAssert(*type != '@', @"tried to encode an \"ObjC\" type");
NSAssert(*type != '^', @"tried to encode an \"ObjC\" type");
NSAssert(*type != ':', @"tried to encode an \"ObjC\" type");
if (debug_binary_coder)
{
[[[self class] debugStderrCoder]
encodeValueOfCType: type
at: d
withName: name];
}
[stream writeByte: *type];
#define WRITE_SIGNED_TYPE0(_PTR, _TYPE, _CONV_FUNC) \
{ \
_TYPE tmp; \
char buffer[1+sizeof(_TYPE)]; \
buffer[0] = sizeof (_TYPE); \
if (*(_TYPE*)_PTR < 0) \
{ \
buffer[0] |= 0x80; \
tmp = _CONV_FUNC (- *(_TYPE*)_PTR); \
memcpy (buffer+1, &tmp, sizeof(_TYPE)); \
} \
else \
{ \
tmp = _CONV_FUNC (*(_TYPE*)_PTR); \
memcpy (buffer+1, &tmp, sizeof(_TYPE)); \
} \
[stream writeBytes: buffer length: 1+sizeof(_TYPE)]; \
}
#define WRITE_SIGNED_TYPE1(_PTR, _TYPE, _CONV_FUNC) \
{ \
_TYPE tmp; \
char buffer[sizeof(_TYPE)]; \
if (*(_TYPE*)_PTR < 0) \
{ \
tmp = _CONV_FUNC (- *(_TYPE*)_PTR); \
memcpy (buffer, &tmp, sizeof(_TYPE)); \
NSAssert(!(buffer[0] & 0x80), @"high bit set"); \
buffer[0] |= 0x80; \
} \
else \
{ \
tmp = _CONV_FUNC (*(_TYPE*)_PTR); \
memcpy (buffer, &tmp, sizeof(_TYPE)); \
} \
[stream writeBytes: buffer length: sizeof(_TYPE)]; \
}
#define WRITE_SIGNED_TYPE(_PTR, _TYPE, _CONV_FUNC) \
{ \
if (format_version == PRE_SIZEOF_PREFIX_FORMAT_VERSION) \
WRITE_SIGNED_TYPE0 (_PTR, _TYPE, _CONV_FUNC) \
else \
WRITE_SIGNED_TYPE1 (_PTR, _TYPE, _CONV_FUNC) \
}
#define READ_SIGNED_TYPE0(_PTR, _TYPE, _CONV_FUNC) \
{ \
char sign, size; \
[stream readByte: &size]; \
sign = size & 0x80; \
size &= ~0x80; \
{ \
char buffer[size]; \
int read_size; \
read_size = [stream readBytes: buffer length: size]; \
NSAssert (read_size == size, @"expected more input"); \
NSAssert (size == sizeof(_TYPE), @"inconsistent size");\
*(unsigned _TYPE*)_PTR = \
_CONV_FUNC (*(unsigned _TYPE*)buffer); \
if (sign) \
*(_TYPE*)_PTR = - *(_TYPE*)_PTR; \
} \
}
#define READ_SIGNED_TYPE1(_PTR, _TYPE, _CONV_FUNC) \
{ \
int size = _sizeof_ ## _TYPE; \
char buffer[size]; \
int read_size; \
int sign; \
read_size = [stream readBytes: buffer length: size]; \
NSAssert (read_size == size, @"expected more input"); \
/* xxx Remove this next requirement eventually */ \
NSAssert (size == sizeof(_TYPE), @"inconsistent size"); \
sign = buffer[0] & 0x80; \
buffer[0] &= ~0x80; \
*(unsigned _TYPE*)_PTR = \
_CONV_FUNC (*(unsigned _TYPE*)buffer); \
if (sign) \
*(_TYPE*)_PTR = - *(_TYPE*)_PTR; \
}
#define READ_SIGNED_TYPE(_PTR, _TYPE, _CONV_FUNC) \
{ \
if (format_version == PRE_SIZEOF_PREFIX_FORMAT_VERSION) \
READ_SIGNED_TYPE0 (_PTR, _TYPE, _CONV_FUNC) \
else \
READ_SIGNED_TYPE1 (_PTR, _TYPE, _CONV_FUNC) \
}
/* Reading and writing unsigned scalar types. */
#define WRITE_UNSIGNED_TYPE0(_PTR, _TYPE, _CONV_FUNC) \
{ \
_TYPE tmp; \
char buffer[1+sizeof(_TYPE)]; \
buffer[0] = sizeof (_TYPE); \
tmp = _CONV_FUNC (*(_TYPE*)_PTR); \
memcpy (buffer+1, &tmp, sizeof(_TYPE)); \
[stream writeBytes: buffer length: (1+sizeof(_TYPE))]; \
}
#define WRITE_UNSIGNED_TYPE1(_PTR, _TYPE, _CONV_FUNC) \
{ \
unsigned _TYPE tmp; \
char buffer[sizeof(unsigned _TYPE)]; \
tmp = _CONV_FUNC (*(unsigned _TYPE*)_PTR); \
memcpy (buffer, &tmp, sizeof(unsigned _TYPE)); \
[stream writeBytes: buffer length: (sizeof(unsigned _TYPE))]; \
}
#define WRITE_UNSIGNED_TYPE(_PTR, _TYPE, _CONV_FUNC) \
{ \
if (format_version == PRE_SIZEOF_PREFIX_FORMAT_VERSION) \
WRITE_UNSIGNED_TYPE0 (_PTR, _TYPE, _CONV_FUNC) \
else \
WRITE_UNSIGNED_TYPE1 (_PTR, _TYPE, _CONV_FUNC) \
}
#define READ_UNSIGNED_TYPE0(_PTR, _TYPE, _CONV_FUNC) \
{ \
char size; \
[stream readByte: &size]; \
{ \
char buffer[size]; \
int read_size; \
read_size = [stream readBytes: buffer length: size]; \
NSAssert (read_size == size, @"expected more input"); \
NSAssert (size == sizeof(_TYPE), @"inconsistent size");\
*(_TYPE*)_PTR = \
_CONV_FUNC (*(_TYPE*)buffer); \
} \
}
#define READ_UNSIGNED_TYPE1(_PTR, _TYPE, _CONV_FUNC) \
{ \
int size = _sizeof_ ## _TYPE; \
char buffer[size]; \
int read_size; \
read_size = [stream readBytes: buffer length: size]; \
NSAssert (read_size == size, @"expected more input"); \
/* xxx Remove this next requirement eventually */ \
NSAssert (size == sizeof(_TYPE), @"inconsistent size"); \
*(unsigned _TYPE*)_PTR = \
_CONV_FUNC (*(unsigned _TYPE*)buffer); \
}
#define READ_UNSIGNED_TYPE(_PTR, _TYPE, _CONV_FUNC) \
{ \
if (format_version == PRE_SIZEOF_PREFIX_FORMAT_VERSION) \
READ_UNSIGNED_TYPE0 (_PTR, _TYPE, _CONV_FUNC) \
else \
READ_UNSIGNED_TYPE1 (_PTR, _TYPE, _CONV_FUNC) \
}
switch (*type)
{
case _C_CHARPTR:
{
unsigned length = strlen (*(char**)d);
unsigned nlength;
nlength = NSSwapHostIntToBig (length);
[stream writeBytes: &nlength
length: NUM_BYTES_STRING_LENGTH];
[stream writeBytes: *(char**)d
length: length];
break;
}
case _C_CHR:
case _C_UCHR:
[stream writeByte: *(unsigned char*)d];
break;
/* Reading and writing signed scalar types. */
case _C_SHT:
WRITE_SIGNED_TYPE (d, short, NSSwapHostShortToBig);
break;
case _C_USHT:
WRITE_UNSIGNED_TYPE (d, short, NSSwapHostShortToBig);
break;
case _C_INT:
WRITE_SIGNED_TYPE (d, int, NSSwapHostIntToBig);
break;
case _C_UINT:
WRITE_UNSIGNED_TYPE (d, int, NSSwapHostIntToBig);
break;
case _C_LNG:
WRITE_SIGNED_TYPE (d, long, NSSwapHostLongToBig);
break;
case _C_ULNG:
WRITE_UNSIGNED_TYPE (d, long, NSSwapHostLongToBig);
break;
/* xxx The handling of floats and doubles could be improved.
e.g. I should account for varying sizeof(int) vs sizeof(double). */
case _C_FLT:
{
float fvalue;
double value;
int exponent, mantissa;
short exponent_encoded;
memcpy (&fvalue, d, sizeof (float));
value = fvalue;
/* Get the exponent */
value = frexp (value, &exponent);
exponent_encoded = exponent;
NSParameterAssert (exponent_encoded == exponent);
/* Get the mantissa. */
value *= FLOAT_FACTOR;
mantissa = value;
NSAssert (value - mantissa == 0,
@"mantissa and value should be the same");
/* Encode the value as its two integer components. */
WRITE_SIGNED_TYPE (&exponent_encoded, short, NSSwapHostShortToBig);
WRITE_SIGNED_TYPE (&mantissa, int, NSSwapHostIntToBig);
break;
}
case _C_DBL:
{
double value;
int exponent, mantissa1, mantissa2;
short exponent_encoded;
memcpy (&value, d, sizeof (double));
/* Get the exponent */
value = frexp (value, &exponent);
exponent_encoded = exponent;
NSParameterAssert (exponent_encoded == exponent);
/* Get the first part of the mantissa. */
value *= FLOAT_FACTOR;
mantissa1 = value;
value -= mantissa1;
value *= FLOAT_FACTOR;
mantissa2 = value;
NSAssert (value - mantissa2 == 0,
@"mantissa2 and value should be the same");
/* Encode the value as its three integer components. */
WRITE_SIGNED_TYPE (&exponent_encoded, short, NSSwapHostShortToBig);
WRITE_SIGNED_TYPE (&mantissa1, int, NSSwapHostIntToBig);
WRITE_SIGNED_TYPE (&mantissa2, int, NSSwapHostIntToBig);
break;
}
case _C_ARY_B:
{
int len = atoi (type+1); /* xxx why +1 ? */
int offset;
while (isdigit(*++type));
offset = objc_sizeof_type(type);
[self encodeName:name];
[self encodeIndent];
while (len-- > 0)
{
/* Change this so we don't re-write type info every time. */
/* xxx We should be able to encode arrays "ObjC" types also! */
[self encodeValueOfCType:type
at:d
withName:@"array component"];
((char*)d) += offset;
}
[self encodeUnindent];
break;
}
case _C_STRUCT_B:
{
int acc_size = 0;
int align;
while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */
[self encodeName:name];
[self encodeIndent];
while (*type != _C_STRUCT_E)
{
align = objc_alignof_type (type); /* pad to alignment */
acc_size = ROUND (acc_size, align);
/* xxx We should be able to encode structs "ObjC" types also! */
[self encodeValueOfCType:type
at:((char*)d)+acc_size
withName:@"structure component"];
acc_size += objc_sizeof_type (type); /* add component size */
type = objc_skip_typespec (type); /* skip component */
}
[self encodeUnindent];
break;
}
default:
[NSException raise: NSGenericException
format: @"Unrecognized type %s", type];
}
}
- (void) decodeValueOfCType: (const char*)type
at: (void*)d
withName: (NSString* *)namePtr
{
char encoded_type;
if (!type)
[NSException raise:NSInvalidArgumentException format:@"type is NULL"];
NSAssert(*type != '@', @"tried to decode an \"ObjC\" type");
NSAssert(*type != '^', @"tried to decode an \"ObjC\" type");
NSAssert(*type != ':', @"tried to decode an \"ObjC\" type");
[stream readByte: &encoded_type];
if (encoded_type != *type
&& !((encoded_type=='c' || encoded_type=='C')
&& (*type=='c' || *type=='C')))
[NSException raise: NSGenericException
format: @"Expected type \"%c\", got type \"%c\"",
*type, encoded_type];
switch (encoded_type)
{
case _C_CHARPTR:
{
unsigned length;
unsigned read_count;
read_count = [stream readBytes: &length
length: NUM_BYTES_STRING_LENGTH];
NSAssert2 (read_count == NUM_BYTES_STRING_LENGTH,
@"expected %d bytes of input, got %d",
NUM_BYTES_STRING_LENGTH,read_count);
length = NSSwapBigIntToHost (length);
OBJC_MALLOC (*(char**)d, char, length+1);
read_count = [stream readBytes: *(char**)d
length: length];
NSAssert2 (read_count == length,
@"expected %d bytes of input, got %d",length,read_count);
(*(char**)d)[length] = '\0';
/* Autorelease the newly malloc'ed pointer? Grep for (*objc_free)
to see the places the may have to be changed
[NSData dataWithBytesNoCopy: *(void**)d length: length+1]; */
break;
}
case _C_CHR:
case _C_UCHR:
[stream readByte: (unsigned char*)d];
break;
case _C_SHT:
READ_SIGNED_TYPE (d, short, NSSwapBigShortToHost);
break;
case _C_USHT:
READ_UNSIGNED_TYPE (d, short, NSSwapBigShortToHost);
break;
case _C_INT:
READ_SIGNED_TYPE (d, int, NSSwapBigIntToHost);
break;
case _C_UINT:
READ_UNSIGNED_TYPE (d, int, NSSwapBigIntToHost);
break;
case _C_LNG:
READ_SIGNED_TYPE (d, long, NSSwapBigLongToHost);
break;
case _C_ULNG:
READ_UNSIGNED_TYPE (d, long, NSSwapBigLongToHost);
break;
case _C_FLT:
{
short exponent;
int mantissa;
double value;
float fvalue;
/* Decode the exponent and mantissa. */
READ_SIGNED_TYPE (&exponent, short, NSSwapBigShortToHost);
READ_SIGNED_TYPE (&mantissa, int, NSSwapBigIntToHost);
/* Assemble them into a double */
value = mantissa / FLOAT_FACTOR;
value = ldexp (value, exponent);
/* Put the double into the requested memory location as a float */
fvalue = value;
memcpy (d, &fvalue, sizeof (float));
break;
}
case _C_DBL:
{
short exponent;
int mantissa1, mantissa2;
double value;
/* Decode the exponent and the two pieces of the mantissa. */
READ_SIGNED_TYPE (&exponent, short, NSSwapBigShortToHost);
READ_SIGNED_TYPE (&mantissa1, int, NSSwapBigIntToHost);
READ_SIGNED_TYPE (&mantissa2, int, NSSwapBigIntToHost);
/* Assemble them into a double */
value = ((mantissa2 / FLOAT_FACTOR) + mantissa1) / FLOAT_FACTOR;
value = ldexp (value, exponent);
/* Put the double into the requested memory location. */
memcpy (d, &value, sizeof (double));
break;
}
case _C_ARY_B:
{
/* xxx Do we need to allocate space, just like _C_CHARPTR ? */
int len = atoi(type+1);
int offset;
[self decodeName:namePtr];
[self decodeIndent];
while (isdigit(*++type));
offset = objc_sizeof_type(type);
while (len-- > 0)
{
[self decodeValueOfCType:type
at:d
withName:namePtr];
((char*)d) += offset;
}
[self decodeUnindent];
break;
}
case _C_STRUCT_B:
{
/* xxx Do we need to allocate space just like char* ? No. */
int acc_size = 0;
int align;
const char *save_type = type;
while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */
[self decodeName:namePtr];
[self decodeIndent]; /* xxx insert [self decodeName:] */
while (*type != _C_STRUCT_E)
{
align = objc_alignof_type (type); /* pad to alignment */
acc_size = ROUND (acc_size, align);
[self decodeValueOfCType:type
at:((char*)d)+acc_size
withName:namePtr];
acc_size += objc_sizeof_type (type); /* add component size */
type = objc_skip_typespec (type); /* skip component */
}
type = save_type;
[self decodeUnindent];
break;
}
default:
[NSException raise: NSGenericException
format: @"Unrecognized Type %s", type];
}
if (debug_binary_coder)
{
[[[self class] debugStderrCoder]
encodeValueOfCType:type
at:d
withName:@"decoding unnamed"];
}
}
/* Returning default format version. */
+ (int) defaultFormatVersion
{
return DEFAULT_FORMAT_VERSION;
}
/* Encoding and decoding names. */
- (void) encodeName: (NSString*) name
{
if (debug_binary_coder)
[[[self class] debugStderrCoder]
encodeName:name];
}
- (void) decodeName: (NSString* *)n
{
#if 1
if (n)
*n = nil;
#else
if (n)
*n = [[[NSString alloc] init] autorelease];
#endif
}
@end

View file

@ -1,76 +0,0 @@
/* Interface for Objective-C BinaryTree collection object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/*
Binary Tree.
Base class for smarter binary trees.
*/
#ifndef __BinaryTree_h_GNUSTEP_BASE_INCLUDE
#define __BinaryTree_h_GNUSTEP_BASE_INCLUDE
#include <base/IndexedCollection.h>
/* The <BinaryTreeComprising> protocol defines the interface to an object
that may be an element in a BinaryTree.
*/
@protocol BinaryTreeComprising <NSObject>
- leftNode;
- rightNode;
- parentNode;
- (void) setLeftNode: (id <BinaryTreeComprising>)aNode;
- (void) setRightNode: (id <BinaryTreeComprising>)aNode;
- (void) setParentNode: (id <BinaryTreeComprising>)aNode;
- binaryTree;
- (void) setBinaryTree: anObject;
@end
#define NODE_IS_RIGHTCHILD(NODE) (NODE == [[NODE parentNode] rightNode])
#define NODE_IS_LEFTCHILD(NODE) (NODE == [[NODE parentNode] leftNode])
@interface BinaryTree : IndexedCollection
{
unsigned int _count;
id _contents_root;
}
- nilNode;
- rootNode;
- leftmostNodeFromNode: aNode;
- rightmostNodeFromNode: aNode;
- (unsigned) depthOfNode: aNode;
- (unsigned) heightOfNode: aNode;
- (unsigned) nodeCountUnderNode: aNode;
- leftRotateAroundNode: aNode;
- rightRotateAroundNode: aNode;
- binaryTreePrintForDebugger;
@end
#endif /* __BinaryTree_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,607 +0,0 @@
/* Implementation for Objective-C BinaryTree collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/BinaryTree.h>
#include <base/IndexedCollectionPrivate.h>
#include <base/BinaryTreeNode.h>
#include <base/NSString.h>
/* the sentinal */
static id nilBinaryTreeNode;
@implementation BinaryTree
+ (void) initialize
{
if (self == [BinaryTree class])
{
nilBinaryTreeNode = [[BinaryTreeNode alloc] init];
}
}
/* This is the designated initializer of this class */
- init
{
_count = 0;
_contents_root = [self nilNode];
return self;
}
/* Archiving must mimic the above designated initializer */
/* xxx See Collection _decodeContentsWithCoder:.
We shouldn't do an -addElement. finishEncodingInterconnectedObjects
should take care of all that. */
- _initCollectionWithCoder: aCoder
{
[self notImplemented:_cmd];
[super _initCollectionWithCoder:aCoder];
_count = 0;
_contents_root = [self nilNode];
return self;
}
- (void) _encodeContentsWithCoder: (id <Encoding>)aCoder
{
[aCoder startEncodingInterconnectedObjects];
[super _encodeContentsWithCoder:aCoder];
[aCoder finishEncodingInterconnectedObjects];
}
- (void) _decodeContentsWithCoder: (id <Decoding>)aCoder
{
[aCoder startDecodingInterconnectedObjects];
[super _decodeContentsWithCoder:aCoder];
[aCoder finishDecodingInterconnectedObjects];
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
BinaryTree *copy = [super emptyCopy];
copy->_count = 0;
copy->_contents_root = [self nilNode];
return copy;
}
/* This must work without sending any messages to content objects */
- (void) _empty
{
_count = 0;
_contents_root = [self nilNode];
}
- nilNode
{
return nilBinaryTreeNode;
}
- rootNode
{
return _contents_root;
}
- leftmostNodeFromNode: aNode
{
id left;
if (aNode && aNode != [self nilNode])
{
while ((left = [aNode leftNode]) != [self nilNode])
aNode = left;
}
return aNode;
}
- rightmostNodeFromNode: aNode
{
id right;
if (aNode && aNode != [self nilNode])
while ((right = [aNode rightNode]) != [self nilNode])
{
aNode = right;
}
return aNode;
}
- firstObject
{
return [self leftmostNodeFromNode: _contents_root];
}
- lastObject
{
return [self rightmostNodeFromNode: _contents_root];
}
/* This is correct only if the tree is sorted. How to deal with this? */
- maxObject
{
return [self rightmostNodeFromNode: _contents_root];
}
/* This is correct only is the tree is sorted. How to deal with this? */
- minObject
{
return [self leftmostNodeFromNode: _contents_root];
}
- successorOfObject: anObject
{
id tmp;
/* Make sure we actually own the anObject. */
NSAssert([anObject binaryTree] == self, NSInternalInconsistencyException);
// here tmp is the right node;
if ((tmp = [anObject rightNode]) != [self nilNode])
return [self leftmostNodeFromNode: tmp];
// here tmp is the parent;
tmp = [anObject parentNode];
while (tmp != [self nilNode] && anObject == [tmp rightNode])
{
anObject = tmp;
tmp = [tmp parentNode];
}
if (tmp == [self nilNode])
return NO_OBJECT;
return tmp;
}
// I should make sure that [_contents_root parentNode] == [self nilNode];
// Perhaps I should make [_contents_root parentNode] == binaryTreeObj ??;
- predecessorObject: anObject
{
id tmp;
/* Make sure we actually own the anObject. */
NSAssert([anObject binaryTree] == self, NSInternalInconsistencyException);
// here tmp is the left node;
if ((tmp = [anObject leftNode]) != [self nilNode])
return [self rightmostNodeFromNode:tmp];
// here tmp is the parent;
tmp = [anObject parentNode];
while (tmp != [self nilNode] && anObject == [tmp leftNode])
{
anObject = tmp;
tmp = [tmp parentNode];
}
if (tmp == [self nilNode])
return NO_OBJECT;
return tmp;
}
/* This relies on [_contents_root parentNode] == [self nilNode] */
- rootFromNode: aNode
{
id parentNode;
/* Make sure we actually own the aNode. */
NSAssert([aNode binaryTree] == self, NSInternalInconsistencyException);
while ((parentNode = [aNode parentNode]) != [self nilNode])
aNode = parentNode;
return aNode;
}
/* This relies on [_contents_root parentNode] == [self nilNode] */
- (unsigned) depthOfNode: aNode
{
unsigned count = 0;
/* Make sure we actually own the aNode. */
NSAssert([aNode binaryTree] == self, NSInternalInconsistencyException);
if (aNode == nil || aNode == [self nilNode])
[self error:"in %s, Can't find depth of nil node", sel_get_name(_cmd)];
do
{
aNode = [aNode parentNode];
count++;
}
while (aNode != [self nilNode]);
return count;
}
- (unsigned) heightOfNode: aNode
{
unsigned leftHeight, rightHeight;
id tmpNode;
/* Make sure we actually own the aNode. */
NSAssert([aNode binaryTree] == self, NSInternalInconsistencyException);
if (aNode == nil || aNode == [self nilNode])
{
[self error:"in %s, Can't find height of nil node", sel_get_name(_cmd)];
return 0;
}
else
{
leftHeight = ((tmpNode = [aNode leftNode])
?
(1 + [self heightOfNode:tmpNode])
:
0);
rightHeight = ((tmpNode = [aNode rightNode])
?
(1 + [self heightOfNode:tmpNode])
:
0);
return MAX(leftHeight, rightHeight);
}
}
- (unsigned) nodeCountUnderNode: aNode
{
unsigned count = 0;
/* Make sure we actually own the aNode. */
NSAssert([aNode binaryTree] == self, NSInternalInconsistencyException);
if ([aNode leftNode] != [self nilNode])
count += 1 + [self nodeCountUnderNode:[aNode leftNode]];
if ([aNode rightNode] != [self nilNode])
count += 1 + [self nodeCountUnderNode:[aNode rightNode]];
return count;
}
- leftRotateAroundNode: aNode
{
id y;
/* Make sure we actually own the aNode. */
NSAssert([aNode binaryTree] == self, NSInternalInconsistencyException);
y = [aNode rightNode];
if (y == [self nilNode])
return self;
[aNode setRightNode:[y leftNode]];
if ([y leftNode] != [self nilNode])
[[y leftNode] setParentNode:aNode];
[y setParentNode:[aNode parentNode]];
if ([aNode parentNode] == [self nilNode])
_contents_root = y;
else
{
if (NODE_IS_LEFTCHILD(aNode))
[[aNode parentNode] setLeftNode:y];
else
[[aNode parentNode] setRightNode:y];
}
[y setLeftNode:aNode];
[aNode setParentNode:y];
return self;
}
- rightRotateAroundNode: aNode
{
id y;
/* Make sure we actually own the aNode. */
NSAssert([aNode binaryTree] == self, NSInternalInconsistencyException);
y = [aNode leftNode];
if (y == [self nilNode])
return self;
[aNode setLeftNode:[y rightNode]];
if ([y rightNode] != [self nilNode])
[[y rightNode] setParentNode:aNode];
[y setParentNode:[aNode parentNode]];
if ([aNode parentNode] == [self nilNode])
_contents_root = y;
else
{
if (NODE_IS_RIGHTCHILD(aNode))
[[aNode parentNode] setRightNode:y];
else
[[aNode parentNode] setLeftNode:y];
}
[y setRightNode:aNode];
[aNode setParentNode:y];
return self;
}
- objectAtIndex: (unsigned)index
{
id ret;
CHECK_INDEX_RANGE_ERROR(index, _count);
ret = [self firstObject];
// Not very efficient; Should be rewritten;
while (index--)
ret = [self successorOfObject: ret];
return ret;
}
- (void) sortAddObject: newObject
{
id theParent, tmpChild;
/* Make sure no one else already owns the newObject. */
NSAssert([newObject binaryTree] == NO_OBJECT, NSInternalInconsistencyException);
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setBinaryTree: self];
[newObject setLeftNode:[self nilNode]];
[newObject setRightNode:[self nilNode]];
theParent = [self nilNode];
tmpChild = _contents_root;
while (tmpChild != [self nilNode])
{
theParent = tmpChild;
if ([newObject compare: theParent] < 0)
tmpChild = [tmpChild leftNode];
else
tmpChild = [tmpChild rightNode];
}
[newObject setParentNode:theParent];
if (theParent == [self nilNode])
_contents_root = newObject;
else
{
if ([newObject compare: theParent] < 0)
[theParent setLeftNode:newObject];
else
[theParent setRightNode:newObject];
}
_count++;
}
- (void) addObject: newObject
{
// By default insert in sorted order.
[self sortAddObject: newObject];
}
- (void) removeObject: oldObject
{
id x, y;
/* Make sure we actually own the aNode. */
NSAssert([oldObject binaryTree] == self, NSInternalInconsistencyException);
/* Extract the oldObject and sew up the cut. */
if ([oldObject leftNode] == [self nilNode]
|| [oldObject rightNode] == [self nilNode])
y = oldObject;
else
y = [self successorOfObject: oldObject];
if ([y leftNode] != [self nilNode])
x = [y leftNode];
else
x = [y rightNode];
if (x != [self nilNode])
[x setParentNode: [y parentNode]];
if ([y parentNode] == [self nilNode])
_contents_root = x;
else
{
if (y == [[y parentNode] leftNode])
[[y parentNode] setLeftNode: x];
else
[[y parentNode] setRightNode: x];
}
if (y != oldObject)
{
/* put y in the place of oldObject */
[y setParentNode: [oldObject parentNode]];
[y setLeftNode: [oldObject leftNode]];
[y setRightNode: [oldObject rightNode]];
if (oldObject == [[oldObject parentNode] leftNode])
[[oldObject parentNode] setLeftNode: y];
else
[[oldObject parentNode] setRightNode: y];
[[oldObject leftNode] setParentNode: y];
[[oldObject rightNode] setParentNode: y];
}
_count--;
/* Release ownership of the object. */
#if 0
[oldObject setRightNode: [self nilNode]];
[oldObject setLeftNode: [self nilNode]];
[oldObject setParentNode: [self nilNode]];
#else
[oldObject setLeftNode: NO_OBJECT];
[oldObject setRightNode: NO_OBJECT];
[oldObject setParentNode: NO_OBJECT];
#endif
[oldObject setBinaryTree: NO_OBJECT];
[oldObject release];
}
// ENUMERATING;
- nextObjectWithEnumState: (void**)enumState
{
if (!(*enumState))
*enumState = [self leftmostNodeFromNode:_contents_root];
else
*enumState = [self successorOfObject:*enumState];
return (id) *enumState;
}
- prevObjectWithEnumState: (void**)enumState
{
if (!(*enumState))
*enumState = [self rightmostNodeFromNode:_contents_root];
else
*enumState = [self predecessorObject:*enumState];
return (id) *enumState;
}
- (unsigned) count
{
return _count;
}
/* replace this with something better eventually */
- _tmpPrintFromNode: aNode indent: (int)count
{
printf("%-*s", count, "");
printf("%s\n", [[aNode description] cString]);
printf("%-*s.", count, "");
if ([aNode leftNode] != [self nilNode])
[self _tmpPrintFromNode:[aNode leftNode] indent:count+2];
else
printf("\n");
printf("%-*s.", count, "");
if ([aNode rightNode] != [self nilNode])
[self _tmpPrintFromNode:[aNode rightNode] indent:count+2];
else
printf("\n");
return self;
}
- binaryTreePrintForDebugger
{
[self _tmpPrintFromNode:_contents_root indent:0];
return self;
}
@end
/* These methods removed because they belong to an
OrderedCollection implementation, not an IndexedCollection
implementation. */
#if 0
// NOTE: This gives you the power to put elements in unsorted order;
- insertObject: newObject before: oldObject
{
id tmp;
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setBinaryTree: self];
[newObject setRightNode:[self nilNode]];
[newObject setLeftNode:[self nilNode]];
if ((tmp = [oldObject leftNode]) != [self nilNode])
{
[(tmp = [self rightmostNodeFromNode:tmp]) setRightNode:newObject];
[newObject setParentNode:tmp];
}
else if (newObject != [self nilNode])
{
[oldObject setLeftNode:newObject];
[newObject setParentNode:oldObject];
}
else
{
_contents_root = newObject;
[newObject setParentNode:[self nilNode]];
}
_count++;
RETAIN_ELT(newObject);
return self;
}
// NOTE: This gives you the power to put elements in unsorted order;
- insertObject: newObject after: oldObject
{
id tmp;
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setBinaryTree: self];
[newObject setRightNode:[self nilNode]];
[newObject setLeftNode:[self nilNode]];
if ((tmp = [oldObject rightNode]) != [self nilNode])
{
[(tmp = [self leftmostNodeFromNode:tmp]) setLeftNode:newObject];
[newObject setParentNode:tmp];
}
else if (newObject != [self nilNode])
{
[oldObject setRightNode:newObject];
[newObject setParentNode:oldObject];
}
else
{
_contents_root = newObject;
[newObject setParentNode:[self nilNode]];
}
_count++;
RETAIN_ELT(newObject);
return self;
}
// NOTE: This gives you the power to put elements in unsorted order;
- insertObject: newObject atIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count+1);
if (index == _count)
[self appendObject:newObject];
else
[self insertObject:newObject before:[self ObjectAtIndex:index]];
return self;
}
// NOTE: This gives you the power to put elements in unsorted order;
- appendObject: newObject
{
if (_count == 0)
{
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setBinaryTree: self];
_contents_root = newObject;
_count = 1;
[newObject setLeftNode:[self nilNode]];
[newObject setRightNode:[self nilNode]];
[newObject setParentNode:[self nilNode]];
}
else
[self insertObject:newObject after:[self lastObject]];
return self;
}
#endif

View file

@ -1,40 +0,0 @@
/* Interface for Objective-C BinaryTreeNode object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __BinaryTreeNode_h_GNUSTEP_BASE_INCLUDE
#define __BinaryTreeNode_h_GNUSTEP_BASE_INCLUDE
#include <base/BinaryTree.h>
#include <base/Coding.h>
@interface BinaryTreeNode : NSObject <BinaryTreeComprising>
{
id _left;
id _right;
id _parent;
id _binary_tree;
}
@end
#endif /* __BinaryTreeNode_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,104 +0,0 @@
/* Implementation for Objective-C BinaryTreeNode object
Copyright (C) 1993,1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/BinaryTreeNode.h>
#include <base/NSString.h>
@implementation BinaryTreeNode
+ (void) initialize
{
if (self == [BinaryTreeNode class])
[self setVersion:0]; /* beta release */
}
- init
{
[super init];
_left = _right = _parent = nil;
return self;
}
- (void) encodeWithCoder: aCoder
{
[super encodeWithCoder:(id)aCoder];
[aCoder encodeObjectReference:_right withName:@"Right BinaryTree Node"];
[aCoder encodeObjectReference:_left withName:@"Left BinaryTree Node"];
[aCoder encodeObjectReference:_parent withName:@"Parent BinaryTree Node"];
[aCoder encodeObjectReference:_binary_tree
withName:@"BinaryTree"];
}
- initWithCoder: aCoder
{
[super initWithCoder:aCoder];
[aCoder decodeObjectAt:&_right withName:NULL];
[aCoder decodeObjectAt:&_left withName:NULL];
[aCoder decodeObjectAt:&_parent withName:NULL];
[aCoder decodeObjectAt:&_binary_tree withName:NULL];
return self;
}
- leftNode
{
return _left;
}
- rightNode
{
return _right;
}
- parentNode
{
return _parent;
}
- (void) setLeftNode: aNode
{
_left = aNode;
}
- (void) setRightNode: aNode
{
_right = aNode;
}
- (void) setParentNode: aNode
{
_parent = aNode;
}
- binaryTree
{
return _binary_tree;
}
- (void) setBinaryTree: anObject
{
_binary_tree = anObject;
}
@end

View file

@ -1,62 +0,0 @@
/* Interface for GNU Objective-C stream object for use in archiving
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Written: Jan 1996
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __CStream_h_GNUSTEP_BASE_INCLUDE
#define __CStream_h_GNUSTEP_BASE_INCLUDE
#include <base/Stream.h>
#include <base/CStreaming.h>
@interface CStream : Stream <CStreaming>
{
Stream *stream;
int format_version;
int indentation;
}
/* These are the standard ways to create a new CStream from a Stream
that is open for reading.
It reads the CStream signature at the beginning of the file, and
automatically creates the appropriate subclass of CStream with
the correct format version. */
+ cStreamReadingFromFile: (NSString*) filename;
+ cStreamReadingFromStream: (id <Streaming>) stream;
/* These are standard ways to create a new CStream with a Stream
that is open for writing. */
- initForWritingToFile: (NSString*) filename;
- initForWritingToStream: (id <Streaming>) stream;
- initForWritingToStream: (id <Streaming>) s
withFormatVersion: (int)version;
+ cStreamWritingToStream: (id <Streaming>) stream;
+ cStreamWritingToFile: (NSString*) filename;
/* This is the designated initializer for reading. Don't call it yourself. */
- _initForReadingFromPostSignatureStream: (id <Streaming>)s
withFormatVersion: (int)version;
@end
#endif /* __CStream_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,287 +0,0 @@
/* Implementation of GNU Objective-C class for streaming C types and indentatn
Copyright (C) 1994, 1995, 1996, 1997 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/preface.h>
#include <base/CStream.h>
#include <base/NSString.h>
#include <base/StdioStream.h>
#include <base/CoderPrivate.h> /* for SIGNATURE_FORMAT_STRING */
#include <Foundation/NSException.h>
id CStreamSignatureMalformedException = @"CStreamSignatureMalformedException";
id CStreamSignatureMismatchException = @"CStreamSignatureMismatchException";
@implementation CStream
/* Encoding/decoding C values */
- (void) encodeValueOfCType: (const char*) type
at: (const void*) d
withName: (NSString*) name;
{
[self subclassResponsibility:_cmd];
}
- (void) decodeValueOfCType: (const char*) type
at: (void*) d
withName: (NSString* *) namePtr;
{
[self subclassResponsibility:_cmd];
}
/* Signature methods. */
- (void) writeSignature
{
/* Careful: the string should not contain newlines. */
[stream writeFormat: SIGNATURE_FORMAT_STRING,
STRINGIFY(GNUSTEP_BASE_PACKAGE_NAME),
GNUSTEP_BASE_MAJOR_VERSION,
GNUSTEP_BASE_MINOR_VERSION,
GNUSTEP_BASE_SUBMINOR_VERSION,
object_get_class_name(self),
format_version];
}
+ (void) readSignatureFromStream: s
getClassname: (char *) name
formatVersion: (int*) version
{
int got;
char package_name[64];
int major_version;
int minor_version;
int subminor_version;
got = [s readFormat: SIGNATURE_FORMAT_STRING,
&(package_name[0]),
&major_version,
&minor_version,
&subminor_version,
name,
version];
if (got != 6)
[NSException raise:CStreamSignatureMalformedException
format: @"CStream found a malformed signature"];
}
/* Initialization methods */
/* This is the hidden designated initializer. Do not call it yourself. */
- _initWithStream: (id <Streaming>) s
formatVersion: (int)version
{
[super init];
[s retain];
stream = s;
format_version = version;
indentation = 0;
return self;
}
/* This is the designated initializer for reading. */
- _initForReadingFromPostSignatureStream: (id <Streaming>)s
withFormatVersion: (int)version
{
[self _initWithStream: s
formatVersion: version];
return self;
}
- initForReadingFromStream: (id <Streaming>) s
withFormatVersion: (int)version
{
[self notImplemented: _cmd];
/* xxx Why this condition? -mccallum */
if ([stream streamPosition] != 0)
{
char name[128]; /* max class name length. */
int version;
[[self class] readSignatureFromStream: stream
getClassname: name
formatVersion: &version];
if (!strcmp(name, object_get_class_name(self))
|| version != format_version)
{
[NSException raise: CStreamSignatureMismatchException
format: @"CStream found a mismatched signature"];
}
[self _initForReadingFromPostSignatureStream: s
withFormatVersion: version];
}
return self;
}
+ cStreamReadingFromStream: (id <Streaming>) s
{
char name[128]; /* Maximum class name length. */
int version;
id new_cstream;
[self readSignatureFromStream: s
getClassname: name
formatVersion: &version];
new_cstream = [[objc_lookup_class(name) alloc]
_initForReadingFromPostSignatureStream: s
withFormatVersion: version];
return [new_cstream autorelease];
}
+ cStreamReadingFromFile: (NSString*) filename
{
return [self cStreamReadingFromStream:
[StdioStream streamWithFilename: filename fmode: "r"]];
}
/* This is a designated initializer for writing. */
- initForWritingToStream: (id <Streaming>) s
withFormatVersion: (int)version
{
[self _initWithStream: s
formatVersion: version];
[self writeSignature];
return self;
}
- initForWritingToStream: (id <Streaming>) s
{
return [self initForWritingToStream: s
withFormatVersion: [[self class] defaultFormatVersion]];
}
- initForWritingToFile: (NSString*) file
{
return [self initForWritingToStream:
[StdioStream streamWithFilename: file fmode: "w"]];
}
+ cStreamWritingToStream: (id <Streaming>) s
{
return [[[self alloc] initForWritingToStream: s]
autorelease];
}
+ cStreamWritingToFile: (NSString*) filename;
{
return [[[self alloc] initForWritingToFile: filename]
autorelease];
}
/* Encoding/decoding indentation */
- (void) encodeWithName: (NSString*) name
valuesOfCTypes: (const char *) types, ...
{
va_list ap;
[self encodeName: name];
va_start (ap, types);
while (*types)
{
[self encodeValueOfCType: types
at: va_arg(ap, void*)
withName: NULL];
types = objc_skip_typespec (types);
}
va_end (ap);
}
- (void) decodeWithName: (NSString* *)name
valuesOfCTypes: (const char *)types, ...
{
va_list ap;
[self decodeName: name];
va_start (ap, types);
while (*types)
{
[self decodeValueOfCType: types
at: va_arg (ap, void*)
withName: NULL];
types = objc_skip_typespec (types);
}
va_end (ap);
}
- (void) encodeIndent
{
/* Do nothing */
}
- (void) encodeUnindent
{
/* Do nothing */
}
- (void) decodeIndent
{
/* Do nothing */
}
- (void) decodeUnindent
{
/* Do nothing */
}
- (void) encodeName: (NSString*) n
{
/* Do nothing */
}
- (void) decodeName: (NSString* *) name
{
/* Do nothing */
}
/* Access to the underlying stream. */
- (id <Streaming>) stream
{
return stream;
}
/* Deallocation. */
- (void) dealloc
{
[stream release];
[super dealloc];
}
/* Returning default format version. */
+ (int) defaultFormatVersion
{
[self subclassResponsibility:_cmd];
return 0;
}
@end

View file

@ -1,59 +0,0 @@
/* Protocol for GNU Objective C byte streams that can code C types and indentn
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: April 1995
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __CStreaming_h__GNUSTEP_BASE_INCLUDE
#define __CStreaming_h__GNUSTEP_BASE_INCLUDE
#include <base/Streaming.h>
@protocol CStreaming <Streaming>
- (void) encodeValueOfCType: (const char*) type
at: (const void*) d
withName: (NSString*) name;
- (void) decodeValueOfCType: (const char*) type
at: (void*) d
withName: (NSString* *) namePtr;
- (void) encodeWithName: (NSString*) name
valuesOfCTypes: (const char *) types, ...;
- (void) decodeWithName: (NSString* *)name
valuesOfCTypes: (const char *)types, ...;
- (void) encodeName: (NSString*) name;
- (void) decodeName: (NSString* *) name;
- (void) encodeIndent;
- (void) decodeIndent;
- (void) encodeUnindent;
- (void) decodeUnindent;
- (id <Streaming>) stream;
+ (int) defaultFormatVersion;
@end
#endif /* __CStreaming_h__GNUSTEP_BASE_INCLUDE */

View file

@ -1,37 +0,0 @@
/* Interface for Objective-C CircularArray collection object
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __CircularArray_h_GNUSTEP_BASE_INCLUDE
#define __CircularArray_h_GNUSTEP_BASE_INCLUDE
#include <base/Array.h>
@interface CircularArray : Array
{
@public
unsigned int _start_index;
}
@end
#endif /* __CircularArray_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,197 +0,0 @@
/* Implementation for Objective-C CircularArray collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/CircularArray.h>
#include <base/CircularArrayPrivate.h>
@implementation CircularArray
/* This is the designated initializer of this class */
- initWithCapacity: (unsigned)aCapacity
{
[super initWithCapacity:aCapacity];
_start_index = 0;
return self;
}
/* Archiving must mimic the above designated initializer */
- _initCollectionWithCoder: coder
{
[super _initCollectionWithCoder:coder];
_start_index = 0;
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
CircularArray *copy = [super emptyCopy];
copy->_start_index = 0;
return copy;
}
- (void) empty
{
[super empty];
_start_index = 0;
}
/* This is the only method that changes the value of the instance
variable _capacity, except for "-initWithCapacity:" */
- (void) setCapacity: (unsigned)newCapacity
{
id *new_contents;
int i;
if (newCapacity > _count) {
/* This could be more efficient */
OBJC_MALLOC(new_contents, id, newCapacity);
for (i = 0; i < _count; i++)
new_contents[i] = _contents_array[CIRCULAR_TO_BASIC(i)];
OBJC_FREE(_contents_array);
_contents_array = new_contents;
_start_index = 0;
_capacity = newCapacity;
}
}
- (void) removeObjectAtIndex: (unsigned)index
{
unsigned basicIndex;
CHECK_INDEX_RANGE_ERROR(index, _count);
basicIndex = CIRCULAR_TO_BASIC(index);
[_contents_array[basicIndex] release];
circularFillHoleAt(self, basicIndex);
decrementCount(self);
}
- (void) removeFirstObject
{
if (!_count)
return;
[_contents_array[_start_index] release];
_start_index = (_start_index + 1) % _capacity;
decrementCount(self);
}
- (void) removeLastObject
{
if (!_count)
return;
[_contents_array[CIRCULAR_TO_BASIC(_count-1)] release];
decrementCount(self);
}
- objectAtIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count);
return _contents_array[CIRCULAR_TO_BASIC(index)];
}
- (void) appendObject: newObject
{
incrementCount(self);
[newObject retain];
_contents_array[CIRCULAR_TO_BASIC(_count-1)] = newObject;
}
- (void) prependElement: newObject
{
incrementCount(self);
[newObject retain];
_start_index = (_capacity + _start_index - 1) % _capacity;
_contents_array[_start_index] = newObject;
}
- (void) insertElement: newObject atIndex: (unsigned)index
{
unsigned basicIndex;
CHECK_INDEX_RANGE_ERROR(index, _count+1);
incrementCount(self);
[newObject retain];
basicIndex = CIRCULAR_TO_BASIC(index);
circularMakeHoleAt(self, basicIndex);
_contents_array[basicIndex] = newObject;
}
- (void) replaceObjectAtIndex: (unsigned)index withObject: newObject
{
unsigned basicIndex;
CHECK_INDEX_RANGE_ERROR(index, _count);
[newObject retain];
basicIndex = CIRCULAR_TO_BASIC(index);
[_contents_array[basicIndex] release];
_contents_array[basicIndex] = newObject;
}
- (void) swapAtIndeces: (unsigned)index1 : (unsigned)index2
{
id tmp;
CHECK_INDEX_RANGE_ERROR(index1, _count);
CHECK_INDEX_RANGE_ERROR(index2, _count);
index1 = CIRCULAR_TO_BASIC(index1);
index2 = CIRCULAR_TO_BASIC(index2);
tmp = _contents_array[index1];
_contents_array[index1] = _contents_array[index2];
_contents_array[index2] = tmp;
}
#if 0
/* just temporary for debugging */
- circularArrayPrintForDebugger
{
int i;
printf("_start_index=%d, _count=%d, _capacity=%d\n",
_start_index, _count, _capacity);
for (i = 0; i < _capacity; i++)
{
printf("%3d ", i);
}
printf("\n");
for (i = 0; i < _capacity; i++)
{
printf("%3d ", _contents_array[i].int_t);
}
printf("\n");
for (i = 0; i < _capacity; i++)
{
printf("%3d ", _contents_array[CIRCULAR_TO_BASIC(i)].int_t);
}
printf("\n");
return self;
}
#endif
@end

View file

@ -1,74 +0,0 @@
/* CircularArray definitions for the use of subclass implementations
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __CircularArrayPrivate_h_GNUSTEP_BASE_INCLUDE
#define __CircularArrayPrivate_h_GNUSTEP_BASE_INCLUDE
#include <base/ArrayPrivate.h>
#define CIRCULAR_TO_BASIC(INDEX) \
((INDEX + self->_start_index) % self->_capacity)
#define BASIC_TO_CIRCULAR(INDEX) \
((INDEX + self->_capacity - self->_start_index) % self->_capacity)
#define NEXT_CIRCULAR_INDEX(INDEX) \
((INDEX + 1) % self->_capacity)
#define PREV_CIRCULAR_INDEX(INDEX) \
((INDEX + self->_capacity - 1) % self->_capacity)
static inline void
circularMakeHoleAt(CircularArray *self, unsigned basicIndex)
{
int i;
if (self->_start_index && basicIndex > self->_start_index)
{
for (i = self->_start_index; i < basicIndex; i++)
self->_contents_array[i-1] = self->_contents_array[i];
}
else
{
for (i = CIRCULAR_TO_BASIC(self->_count-1); i >= basicIndex; i--)
self->_contents_array[i+1] = self->_contents_array[i];
}
/* This is never called with _count == 0 */
}
static inline void
circularFillHoleAt(CircularArray *self, unsigned basicIndex)
{
int i;
if (basicIndex > self->_start_index)
{
for (i = basicIndex; i > self->_start_index; i--)
self->_contents_array[i] = self->_contents_array[i-1];
}
else
{
for (i = basicIndex; i < CIRCULAR_TO_BASIC(self->_count-1); i++)
self->_contents_array[i] = self->_contents_array[i+1];
}
}
#endif /* __CircularArrayPrivate_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,141 +0,0 @@
/* Interface for GNU Objective-C coder object for use serializing
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Coder_h_GNUSTEP_BASE_INCLUDE
#define __Coder_h_GNUSTEP_BASE_INCLUDE
#include <base/Coding.h>
#include <base/Streaming.h>
#include <Foundation/NSHashTable.h>
#include <Foundation/NSMapTable.h>
@class CStream;
/* The root abstract class for archiving */
@interface Coder : NSObject
{
@public
int format_version;
CStream *cstream;
NSMapTable *classname_2_classname; /* for changing class names on r/w */
int interconnect_stack_height; /* number of nested root objects */
}
+ setDebugging: (BOOL)f;
@end
/* An abstract class for writing an archive */
@interface Encoder : Coder
{
@public
/* xxx in_progress_table should actually be an NSHashTable,
but we are working around a bug right now. */
NSMapTable *in_progress_table; /* objects begun writing, but !finished */
NSMapTable *object_2_xref; /* objects already written */
NSMapTable *object_2_fref; /* table of forward references */
NSMapTable *const_ptr_2_xref; /* const pointers already written */
unsigned fref_counter; /* Keep track of unused fref numbers */
}
- initForWritingToFile: (NSString*) filename;
- initForWritingToFile: (NSString*) filename
withCStreamClass: (Class) cStreamClass;
- initForWritingToFile: (NSString*) filename
withFormatVersion: (int) version
cStreamClass: (Class)scc
cStreamFormatVersion: (int) cStreamFormatVersion;
- initForWritingToStream: (id <Streaming>) s;
- initForWritingToStream: (id <Streaming>) s
withCStreamClass: (Class) cStreamClass;
- initForWritingToStream: (id <Streaming>) s
withFormatVersion: (int) version
cStreamClass: (Class) cStreamClass
cStreamFormatVersion: (int) cStreamFormatVersion;
+ (BOOL) encodeRootObject: anObject
withName: (NSString*) name
toFile: (NSString*) filename;
+ (BOOL) encodeRootObject: anObject
withName: (NSString*) name
toStream: (id <Streaming>)stream;
/* Defaults */
+ (void) setDefaultStreamClass: sc;
+ defaultStreamClass;
+ (void) setDefaultCStreamClass: sc;
+ defaultCStreamClass;
+ (void) setDefaultFormatVersion: (int)fv;
+ (int) defaultFormatVersion;
@end
@interface Encoder (Encoding) <Encoding>
@end
/* An abstract class for reading an archive. */
@interface Decoder : Coder
{
NSZone *zone; /* zone in which to create objects */
id xref_2_object; /* objects already read */
id xref_2_object_root; /* objs read since last -startDecodoingI.. */
NSMapTable *xref_2_const_ptr; /* const pointers already written */
NSMapTable *fref_2_object; /* table of forward references */
NSMapTable *address_2_fref; /* table of forward references */
}
/* These are class methods (and not instance methods) because the
header of the file or stream determines which subclass of Decoder
is created. */
+ newReadingFromFile: (NSString*) filename;
+ newReadingFromStream: (id <Streaming>)stream;
+ decodeObjectWithName: (NSString* *) name
fromFile: (NSString*) filename;
+ decodeObjectWithName: (NSString* *) name
fromStream: (id <Streaming>)stream;
@end
@interface Decoder (Decoding) <Decoding>
@end
/* Extensions to NSObject for encoding and decoding. */
@interface NSObject (OptionalNewWithCoder)
+ newWithCoder: (Coder*)aDecoder;
@end
GS_EXPORT id CoderSignatureMalformedException;
#endif /* __Coder_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,310 +0,0 @@
/* Implementation of GNU Objective-C coder object for use serializing
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/preface.h>
#include <base/behavior.h>
#include <base/Coder.h>
#include <base/CoderPrivate.h>
#include <base/MemoryStream.h>
#include <base/Coding.h>
#include <base/Streaming.h>
#include <base/Stream.h>
#include <base/CStreaming.h>
#include <base/CStream.h>
#include <base/TextCStream.h>
#include <base/BinaryCStream.h>
#include <base/StdioStream.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSString.h>
#include <Foundation/NSException.h>
#include <Foundation/NSGeometry.h>
#include <Foundation/NSData.h>
#include <Foundation/NSArchiver.h>
#include <Foundation/NSMapTable.h>
#include <Foundation/NSHashTable.h>
#include <Foundation/NSCoder.h>
#include <Foundation/NSAutoreleasePool.h>
/* Exception strings */
id CoderSignatureMalformedException = @"CoderSignatureMalformedException";
#define DEFAULT_FORMAT_VERSION 0
#define ROUND(V, A) \
({ typeof(V) __v=(V); typeof(A) __a=(A); \
__a*((__v+__a-1)/__a); })
#define DOING_ROOT_OBJECT (interconnect_stack_height != 0)
static BOOL debug_coder = NO;
@implementation Coder
+ (void) initialize
{
if (self == [Coder class])
behavior_class_add_class (self, [NSCoderNonCore class]);
}
+ setDebugging: (BOOL)f
{
debug_coder = f;
return self;
}
/* Initialization. */
/* This is the designated initializer. But, don't call it yourself;
override it and call [super...] in subclasses. */
- _initWithCStream: (id <CStreaming>) cs
formatVersion: (int) version
{
format_version = version;
cstream = [cs retain];
classname_2_classname = NULL;
interconnect_stack_height = 0;
return self;
}
- init
{
if ([self class] == [Coder class])
{
[self shouldNotImplement:_cmd];
return nil;
}
else
return [super init];
}
/* We must separate the idea of "closing" a coder and "deallocating"
a coder because of delays in deallocation due to -autorelease. */
- (void) close
{
[[cstream stream] close];
}
- (BOOL) isClosed
{
return [[cstream stream] isClosed];
}
- (void) dealloc
{
/* xxx No. [self _finishDecodeRootObject]; */
[cstream release];
[super dealloc];
}
/* Access to instance variables. */
- cStream
{
return cstream;
}
- (int) formatVersion
{
return format_version;
}
- (void) resetCoder
{
/* xxx Finish this */
[self notImplemented:_cmd];
}
@end
/* To fool ourselves into thinking we can call all these
Encoding and Decoding methods. */
@interface Coder (Coding) <Encoding, Decoding>
@end
@implementation Coder (NSCoderCompatibility)
/* The core methods */
- (void) encodeValueOfObjCType: (const char*)type
at: (const void*)address;
{
[self encodeValueOfObjCType: type at: address withName: NULL];
}
- (void) decodeValueOfObjCType: (const char*)type
at: (void*)address
{
[self decodeValueOfObjCType: type at: address withName: NULL];
}
- (void) encodeDataObject: (NSData*)data
{
[self notImplemented:_cmd];
}
- (NSData*) decodeDataObject
{
[self notImplemented:_cmd];
return nil;
}
- (unsigned int) versionForClassName: (NSString*)className
{
[self notImplemented:_cmd];
return 0;
}
/* Override some methods in NSCoderNonCore */
- (void) encodeObject: (id)anObject
{
[self encodeObject: anObject withName: NULL];
}
- (void) encodeBycopyObject: (id)anObject
{
[self encodeBycopyObject: anObject withName: NULL];
}
- (void) encodeByrefObject: (id)anObject
{
[self encodeByrefObject: anObject withName: NULL];
}
- (void) encodeConditionalObject: (id)anObject
{
/* NeXT's implementation handles *forward* references by running
through the entire encoding process twice! GNU Coding can handle
forward references with only one pass. Therefore, however, GNU
Coding cannot return a *forward* reference from -decodeObject, so
here, assuming this call to -encodeConditionalObject: is mirrored
by a -decodeObject, we don't try to encode *forward*
references.
Note that this means objects that use -encodeConditionalObject:
that are encoded in the GNU style might decode a nil where
NeXT-style encoded would not. I don't see this a huge problem;
at least not as bad as NeXT coding mechanism that actually causes
crashes in situations where GNU's does fine. Still, if we wanted
to fix this, we might be able to build a kludgy fix based on
detecting when this would happen, rewinding the stream to the
"conditional" point, and encoding again. Yuck. */
if ([self _coderReferenceForObject: anObject])
[self encodeObject: anObject];
else
[self encodeObject: nil];
}
- (void) encodeRootObject: (id)rootObject
{
[self encodeRootObject: rootObject withName: NULL];
}
- (id) decodeObject
{
/* This won't work for decoding GNU-style forward references because
once the GNU decoder finds the object later in the decoding, it
will back-patch by storing the id in &o... &o will point to some
weird location on the stack! This is why we make the GNU
implementation of -encodeConditionalObject: not encode forward
references. */
id o;
[self decodeObjectAt: &o withName: NULL];
return [o autorelease];
}
- (unsigned int) systemVersion
{
return format_version; /* xxx Is this right? */
}
@end /* of (NSCoderCompatibility) */
@implementation Coder (NSArchiverCompatibility)
/* Initializing an archiver */
- (id) initForWritingWithMutableData: (NSMutableData*)mdata
{
[(id)self initForWritingToStream: [MemoryStream streamWithData: mdata]];
return self;
}
- (id) initForReadingWithData: (NSData*)data
{
id ret = [[self class] newReadingFromStream:
[MemoryStream streamWithData:data]];
[self release];
return ret;
}
/* Archiving Data */
+ (NSData*) archivedDataWithRootObject: (id)rootObject
{
id d = [[NSMutableData alloc] init];
id a = [[NSArchiver alloc] initForWritingWithMutableData:d];
[a encodeRootObject:rootObject];
return [d autorelease];
}
+ (BOOL) archiveRootObject: (id)rootObject toFile: (NSString*)path
{
/* xxx fix this return value */
id d = [self archivedDataWithRootObject:rootObject];
[d writeToFile:path atomically:NO];
return YES;
}
/* Getting data from the archiver */
+ unarchiveObjectWithData: (NSData*) data
{
return [self decodeObjectWithName: NULL
fromStream: [MemoryStream streamWithData:data]];
}
+ unarchiveObjectWithFile: (NSString*) path
{
return [self decodeObjectWithName: NULL fromFile: path];
}
- (NSMutableData*) archiverData
{
[self notImplemented:_cmd];
return nil;
}
@end

View file

@ -1,66 +0,0 @@
/* Private interface for GNU Objective-C coder object for use serializing
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: February 1996
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __CoderPrivate_h_GNUSTEP_BASE_INCLUDE
#define __CoderPrivate_h_GNUSTEP_BASE_INCLUDE
#include <base/Coder.h>
#include <base/CStreaming.h>
enum {
CODER_OBJECT_NIL = 0,
CODER_OBJECT,
CODER_OBJECT_ROOT,
CODER_OBJECT_REPEATED,
CODER_OBJECT_FORWARD_REFERENCE,
CODER_OBJECT_CLASS,
CODER_CLASS_NIL,
CODER_CLASS,
CODER_CLASS_REPEATED,
CODER_CONST_PTR_NULL,
CODER_CONST_PTR,
CODER_CONST_PTR_REPEATED
};
#define DOING_ROOT_OBJECT (interconnect_stack_height != 0)
@interface Coder (Private)
- _initWithCStream: (id <CStreaming>) cs formatVersion: (int) version;
- (unsigned) _coderReferenceForObject: anObject;
@end
#define SIGNATURE_FORMAT_STRING \
@"GNU Objective C (%s %d.%d.%d) [%s %d]\n"
#define WRITE_SIGNATURE_FORMAT_ARGS \
STRINGIFY(GNUSTEP_BASE_PACKAGE_NAME), \
GNUSTEP_BASE_MAJOR_VERSION, \
GNUSTEP_BASE_MINOR_VERSION, \
GNUSTEP_BASE_SUBMINOR_VERSION, \
[self defaultDecoderClassname], \
format_version
#define NO_SEL_TYPES "none"
#endif /* __CoderPrivate_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,165 +0,0 @@
/* Protocol for GNU Objective-C objects that can write/read to a coder
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Coding_h_GNUSTEP_BASE_INCLUDE
#define __Coding_h_GNUSTEP_BASE_INCLUDE
#include <Foundation/NSObject.h>
/* #include <base/String.h>
xxx Think about trying to get <String> back in types,
but now there is a circular dependancy in the include files. */
@protocol CommonCoding
- (BOOL) isDecoding;
- (void) close;
- (BOOL) isClosed;
+ (int) defaultFormatVersion;
- cStream;
@end
@protocol Encoding <CommonCoding>
- (void) encodeValueOfObjCType: (const char*)type
at: (const void*)d
withName: (id /*<String>*/)name;
- (void) encodeValueOfCType: (const char*)type
at: (const void*)d
withName: (id /*<String>*/)name;
- (void) encodeWithName: (id /*<String>*/)name
valuesOfObjCTypes: (const char *)types, ...;
- (void) encodeArrayOfObjCType: (const char *)type
count: (unsigned)c
at: (const void *)d
withName: (id /*<String>*/)name;
- (void) encodeObject: anObj
withName: (id /*<String>*/)name;
- (void) encodeBycopyObject: anObj
withName: (id /*<String>*/)name;
- (void) encodeByrefObject: anObj
withName: (id /*<String>*/)name;
- (void) encodeRootObject: anObj
withName: (id /*<String>*/)name;
- (void) encodeObjectReference: anObj
withName: (id /*<String>*/)name;
- (void) startEncodingInterconnectedObjects;
- (void) finishEncodingInterconnectedObjects;
- (void) encodeAtomicString: (const char*)sp
withName: (id /*<String>*/)name;
- (void) encodeClass: aClass;
/* For inserting a name into a TextCoder stream */
- (void) encodeName: (id /*<String>*/) n;
/* For classes that want to keep track of recursion */
- (void) encodeIndent;
- (void) encodeUnindent;
- (void) encodeBytes: (const void *)b
count: (unsigned)c
withName: (id /*<String>*/)name;
@end
@protocol Decoding <CommonCoding>
- (void) decodeValueOfObjCType: (const char*)type
at: (void*)d
withName: (id /*<String>*/ *) namePtr;
- (void) decodeValueOfCType: (const char*)type
at: (void*)d
withName: (id /*<String>*/ *) namePtr;
- (void) decodeWithName: (id /*<String>*/*)name
valuesOfObjCTypes: (const char *) types, ...;
- (void) decodeArrayOfObjCType: (const char *)type
count: (unsigned)c
at: (void *)d
withName: (id /*<String>*/*)name;
- (void) decodeObjectAt: (id*)anObjPtr
withName: (id /*<String>*/*)name;
- (void) startDecodingInterconnectedObjects;
- (void) finishDecodingInterconnectedObjects;
- (const char *) decodeAtomicStringWithName: (id /*<String>*/*) name;
- decodeClass;
/* For inserting a name into a TextCoder stream */
- (void) decodeName: (id /*<String>*/ *)n;
/* For classes that want to keep track of recursion */
- (void) decodeIndent;
- (void) decodeUnindent;
- (void) decodeBytes: (void *)b
count: (unsigned)c
withName: (id /*<String>*/ *) name;
@end
@interface NSObject (SelfCoding)
- (void) encodeWithCoder: (id <Encoding>)anEncoder;
- (id) initWithCoder: (id <Decoding>)aDecoder;
+ (id) newWithCoder: (id <Decoding>)aDecoder;
/* NOTE:
If the class responds to +newWithCoder Coder will send it for
decoding, otherwise Coder will allocate the object itself and send
initWithCoder instead.
+newWithCoder is useful because many classes keep track of their
instances and only allow one instance of each configuration. For
example, see the designated initializers of SocketPort, Connection,
and Proxy.
Using +new.. instead of -init.. prevents us from having to waste
the effort of allocating space for an object to be decoded, then
immediately deallocating that space because we're just returning a
pre-existing object.
The newWithCoder and initWithCoder methods must return the decoded
object.
This is not a Protocol, because objects are not required to
implement newWithCoder or initWithCoder. They probably want to
implement one of them, though.
-mccallum */
@end
#endif /* __Coding_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,129 +0,0 @@
/* Protocol for Objective-C objects that hold collections of elements.
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/* The <Collecting> protocol is root of the collection protocol heirarchy.
The <Collecting> protocol defines the most general interface to a
collection of elements. Elements can be added, removed, and replaced.
The contents can be tested, enumerated, and enumerated through various
filters. Elements may be objects, or any C type included in the
"elt" union given in elt.h, but all elements of a collection must be of
the same C type.
*/
#ifndef __Collecting_h_GNUSTEP_BASE_INCLUDE
#define __Collecting_h_GNUSTEP_BASE_INCLUDE
#include <base/Coding.h>
#include <base/Invoking.h>
#include <base/Enumerating.h>
@protocol ConstantCollecting <NSObject>
// INITIALIZING;
- init;
- initWithObjects: (id*)objc count: (unsigned)c;
- initWithObjects: firstObject, ...;
- initWithObjects: firstObject rest: (va_list)ap;
- initWithContentsOf: (id <ConstantCollecting>)aCollection;
// QUERYING COUNTS;
- (BOOL) isEmpty;
- (unsigned) count;
- (BOOL) containsObject: anObject;
- (unsigned) occurrencesOfObject: anObject;
// COMPARISON WITH OTHER COLLECTIONS;
- (BOOL) isSubsetOf: (id <ConstantCollecting>)aCollection;
- (BOOL) isDisjointFrom: (id <ConstantCollecting>)aCollection;
- (BOOL) isEqual: anObject;
- (int) compare: anObject;
- (BOOL) contentsEqual: (id <ConstantCollecting>)aCollection;
// PROPERTIES OF CONTENTS;
- (BOOL) trueForAllObjectsByInvoking: (id <Invoking>)anInvocation;
- (BOOL) trueForAnyObjectsByInvoking: (id <Invoking>)anInvocation;
- detectObjectByInvoking: (id <Invoking>)anInvocation;
- maxObject;
- minObject;
// ENUMERATING
- (id <Enumerating>) objectEnumerator;
- (void) withObjectsInvoke: (id <Invoking>)anInvocation;
- (void) withObjectsInvoke: (id <Invoking>)anInvocation whileTrue:(BOOL *)flag;
- (void) makeObjectsPerform: (SEL)aSel;
- (void) makeObjectsPerform: (SEL)aSel withObject: argObject;
// FILTERED ENUMERATING;
- (void) withObjectsTrueByInvoking: (id <Invoking>)testInvocation
invoke: (id <Invoking>)anInvocation;
- (void) withObjectsFalseByInvoking: (id <Invoking>)testInvocation
invoke: (id <Invoking>)anInvocation;
- (void) withObjectsTransformedByInvoking: (id <Invoking>)transInvocation
invoke: (id <Invoking>)anInvocation;
// LOW-LEVEL ENUMERATING;
- (void*) newEnumState;
- nextObjectWithEnumState: (void**)enumState;
- (void) freeEnumState: (void**)enumState;
// COPYING;
- allocCopy;
- emptyCopy;
- emptyCopyAs: (Class)aCollectionClass;
- shallowCopy;
- shallowCopyAs: (Class)aCollectionClass;
- copyAs: (Class)aCollectionClass;
- species;
@end
@protocol Collecting <ConstantCollecting>
// ADDING;
- (void) addObject: newObject;
- (void) addObjectIfAbsent: newObject;
- (void) addContentsOf: (id <ConstantCollecting>)aCollection;
- (void) addContentsIfAbsentOf: (id <ConstantCollecting>)aCollection;
- (void) addWithObjects: (id*)objc count: (unsigned)c;
- (void) addObjects: firstObject, ...;
- (void) addObjects: firstObject rest: (va_list)ap;
// REMOVING;
- (void) removeObject: oldObject;
- (void) removeAllOccurrencesOfObject: oldObject;
- (void) removeContentsIn: (id <ConstantCollecting>)aCollection;
- (void) removeContentsNotIn: (id <ConstantCollecting>)aCollection;
- (void) uniqueContents;
- (void) empty;
// REPLACING;
- (void) replaceObject: oldObject withObject: newObject;
- (void) replaceAllOccurrencesOfObject: oldObject withObject: newObject;
@end
#define NO_OBJECT nil
#endif /* __Collecting_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,102 +0,0 @@
/* Interface for Objective-C Collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/* This is the abstract superclass that satisfies the Collecting
protocol, without using any instance variables.
*/
#ifndef __Collection_h_GNUSTEP_BASE_INCLUDE
#define __Collection_h_GNUSTEP_BASE_INCLUDE
#include <Foundation/NSObject.h>
#include <base/Collecting.h>
#include <base/preface.h>
#include <base/Coding.h>
@interface ConstantCollection : NSObject <ConstantCollecting>
- printForDebugger; /* This method will disappear later. */
@end
@interface Collection : ConstantCollection <Collecting>
@end
@interface Enumerator : NSObject <Enumerating>
{
id collection;
void *enum_state;
}
@end
#define FOR_COLLECTION(ACOLL, ELT) \
{ \
void *_es = [ACOLL newEnumState]; \
while ((ELT = [ACOLL nextObjectWithEnumState: &_es])) \
{
#define END_FOR_COLLECTION(ACOLL) \
} \
[ACOLL freeEnumState: &_es]; \
}
#define FOR_COLLECTION_WHILE_TRUE(ACOLL, ELT, FLAG) \
{ \
void *_es = [ACOLL newEnumState]; \
while (FLAG && (ELT = [ACOLL nextObjectWithEnumState: &_es])) \
{
#define END_FOR_COLLECTION_WHILE_TRUE(ACOLL) \
} \
[ACOLL freeEnumState: &_es]; \
}
/* The only subclassResponsibilities in Collection are:
addElement:
removeElement:
getNextElement:withEnumState:
empty
But subclasses may need to override the following for correctness:
contentType
comparisonFunction
but subclasses will want to override others as well in order to
increase efficiency, especially:
count
and perhaps:
includesElement:
occurrencesOfElement:
uniqueContents
withElementsCall:whileTrue:
withElementsCall:
isEmpty
releaseObjects
*/
#endif /* __Collection_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,839 +0,0 @@
/* Implementation for Objective-C Collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/Collection.h>
#include <base/CollectionPrivate.h>
#include <stdarg.h>
#include <base/Bag.h> /* for -contentsEqual: */
#include <base/Array.h> /* for -safeWithElementsCall: */
#include <base/Coder.h>
#include <base/NSString.h>
@implementation Enumerator
- initWithCollection: coll
{
self = [super init];
if (self)
{
collection = [coll retain];
enum_state = [coll newEnumState];
}
return self;
}
- nextObject
{
return [collection nextObjectWithEnumState: &enum_state];
}
- (void) dealloc
{
[collection freeEnumState: &enum_state];
[collection release];
[super dealloc];
}
@end
@implementation ConstantCollection
// INITIALIZING AND RELEASING;
- init
{
return [self initWithObjects: NULL count: 0];
}
// This is the designated initializer of this class;
- initWithObjects: (id*)objc count: (unsigned)c
{
[self subclassResponsibility: _cmd];
return self;
}
- initWithObjects: firstObject, ...
{
va_list ap;
va_start(ap, firstObject);
self = [self initWithObjects:firstObject rest:ap];
va_end(ap);
return self;
}
#define INITIAL_OBJECTS_SIZE 10
- initWithObjects: firstObject rest: (va_list)ap
{
id *objects;
int i = 0;
int s = INITIAL_OBJECTS_SIZE;
OBJC_MALLOC(objects, id, s);
if (firstObject != nil)
{
objects[i++] = firstObject;
while ((objects[i++] = va_arg(ap, id)))
{
if (i >= s)
{
s *= 2;
OBJC_REALLOC(objects, id, s);
}
}
}
self = [self initWithObjects:objects count:i-1];
OBJC_FREE(objects);
return self;
}
/* Subclasses can override this for efficiency. For example, Array can
init itself with enough capacity to hold aCollection. */
- initWithContentsOf: (id <Collecting>)aCollection
{
int count = [aCollection count];
id contents_array[count];
id o;
int i = 0;
FOR_COLLECTION(aCollection, o)
{
contents_array[i++] = o;
}
END_FOR_COLLECTION(aCollection);
return [self initWithObjects: contents_array count: count];
}
- (void) dealloc
{
/* xxx Get rid of this since Set, Bag, Dictionary, and String
subclasses don't want to use it? */
[self _collectionReleaseContents];
[self _collectionDealloc];
[super dealloc];
}
// QUERYING COUNTS;
- (BOOL) isEmpty
{
return ([self count] == 0);
}
// Inefficient, so should be overridden in subclasses;
- (unsigned) count
{
unsigned n = 0;
id o;
FOR_COLLECTION(self, o)
{
n++;
}
END_FOR_COLLECTION(self);
return n;
}
// Potentially inefficient, may be overridden in subclasses;
- (BOOL) containsObject: anObject
{
id o;
FOR_COLLECTION (self, o)
{
if ([anObject isEqual: o])
return YES;
}
END_FOR_COLLECTION(self);
return NO;
}
- (unsigned) occurrencesOfObject: anObject
{
unsigned count = 0;
id o;
FOR_COLLECTION(self, o)
{
if ([anObject isEqual: o])
count++;
}
END_FOR_COLLECTION(self);
return count;
}
// COMPARISON WITH OTHER COLLECTIONS;
- (BOOL) isSubsetOf: (id <Collecting>)aCollection
{
id o;
FOR_COLLECTION (self, o)
{
if (![aCollection containsObject: o])
return NO;
}
END_FOR_COLLECTION (self);
return YES;
}
- (BOOL) isDisjointFrom: (id <Collecting>)aCollection
{
// Use objc_msg_lookup here also;
BOOL flag = YES;
id o;
FOR_COLLECTION_WHILE_TRUE(self, o, flag)
{
if (![aCollection containsObject: o])
flag = NO;
}
END_FOR_COLLECTION_WHILE_TRUE(self);
return !flag;
}
// xxx How do we want to compare unordered contents?? ;
- (int) compareContentsOf: (id <Collecting>)aCollection
{
if ([self contentsEqual:aCollection])
return 0;
if (self > aCollection)
return 1;
return -1;
}
- (BOOL) isEqual: anObject
{
if (self == anObject)
return YES;
if ( [self contentsEqual: anObject] )
return YES;
else
return NO;
}
// Deal with this in IndexedCollection also ;
// How do we want to compare collections? ;
- (int) compare: anObject
{
if ([self isEqual:anObject])
return 0;
if (self > anObject)
return 1;
return -1;
}
- (BOOL) contentsEqual: (id <Collecting>)aCollection
{
id bag, o;
BOOL flag;
if ([self count] != [aCollection count])
return NO;
bag = [[Bag alloc] initWithContentsOf:aCollection];
flag = YES;
FOR_COLLECTION_WHILE_TRUE (self, o, flag)
{
if ([bag containsObject: o])
[bag removeObject: o];
else
flag = NO;
}
END_FOR_COLLECTION_WHILE_TRUE(self);
if ((!flag) || [bag count])
flag = NO;
else
flag = YES;
[bag release];
return flag;
}
// PROPERTIES OF CONTENTS;
- (BOOL) trueForAllObjectsByInvoking: (id <Invoking>)anInvocation
{
BOOL flag = YES;
id o;
FOR_COLLECTION_WHILE_TRUE(self, o, flag)
{
[anInvocation invokeWithObject: o];
if (![anInvocation returnValueIsTrue])
flag = NO;
}
END_FOR_COLLECTION_WHILE_TRUE(self);
return flag;
}
- (BOOL) trueForAnyObjectsByInvoking: (id <Invoking>)anInvocation;
{
BOOL flag = YES;
id o;
FOR_COLLECTION_WHILE_TRUE(self, o, flag)
{
[anInvocation invokeWithObject: o];
if ([anInvocation returnValueIsTrue])
flag = NO;
}
END_FOR_COLLECTION_WHILE_TRUE(self);
return !flag;
}
- detectObjectByInvoking: (id <Invoking>)anInvocation;
{
BOOL flag = YES;
id detectedObject = nil;
id o;
FOR_COLLECTION_WHILE_TRUE(self, o, flag)
{
[anInvocation invokeWithObject: o];
if ([anInvocation returnValueIsTrue])
{
flag = NO;
detectedObject = o;
}
}
END_FOR_COLLECTION_WHILE_TRUE(self);
if (flag)
return NO_OBJECT;
else
return detectedObject;
}
- maxObject
{
id o, max = nil;
BOOL firstTime = YES;
FOR_COLLECTION(self, o)
{
if (firstTime)
{
firstTime = NO;
max = o;
}
else
{
if ([o compare: max] > 0)
max = o;
}
}
END_FOR_COLLECTION(self);
return max;
}
- minObject
{
id o, min = nil;
BOOL firstTime = YES;
FOR_COLLECTION(self, o)
{
if (firstTime)
{
firstTime = NO;
min = o;
}
else
{
if ([o compare: min] < 0)
min = o;
}
}
END_FOR_COLLECTION(self);
return min;
}
/* Consider adding:
- maxObjectByInvoking: (id <Invoking>)anInvocation;
- minObjectByInvoking: (id <Invoking>)anInvocation;
*/
// ENUMERATING;
- (id <Enumerating>) objectEnumerator
{
return [[[Enumerator alloc] initWithCollection: self]
autorelease];
}
- (void) withObjectsInvoke: (id <Invoking>)anInvocation
{
id o;
FOR_COLLECTION(self, o)
{
[anInvocation invokeWithObject: o];
}
END_FOR_COLLECTION(self);
}
- (void) withObjectsInvoke: (id <Invoking>)anInvocation whileTrue:(BOOL *)flag;
{
id o;
FOR_COLLECTION_WHILE_TRUE(self, o, *flag)
{
[anInvocation invokeWithObject: o];
}
END_FOR_COLLECTION_WHILE_TRUE(self);
}
- (void) makeObjectsPerform: (SEL)aSel
{
id o;
FOR_COLLECTION(self, o)
{
[o performSelector: aSel];
}
END_FOR_COLLECTION(self);
}
- (void) makeObjectsPerform: (SEL)aSel withObject: argObject
{
id o;
FOR_COLLECTION(self, o)
{
[o performSelector: aSel withObject: argObject];
}
END_FOR_COLLECTION(self);
}
// FILTERED ENUMERATING;
- (void) withObjectsTrueByInvoking: (id <Invoking>)testInvocation
invoke: (id <Invoking>)anInvocation
{
id o;
FOR_COLLECTION(self, o)
{
[testInvocation invokeWithObject: o];
if ([testInvocation returnValueIsTrue])
[anInvocation invokeWithObject: o];
}
END_FOR_COLLECTION(self);
}
- (void) withObjectsFalseByInvoking: (id <Invoking>)testInvocation
invoke: (id <Invoking>)anInvocation
{
id o;
FOR_COLLECTION(self, o)
{
[testInvocation invokeWithObject: o];
if (![testInvocation returnValueIsTrue])
[anInvocation invokeWithObject: o];
}
END_FOR_COLLECTION(self);
}
- (void) withObjectsTransformedByInvoking: (id <Invoking>)transInvocation
invoke: (id <Invoking>)anInvocation
{
id o;
FOR_COLLECTION(self, o)
{
[transInvocation invokeWithObject: o];
[anInvocation invokeWithObject: [transInvocation objectReturnValue]];
}
END_FOR_COLLECTION(self);
}
// LOW-LEVEL ENUMERATING;
- (void*) newEnumState
{
return (void*)0;
}
- nextObjectWithEnumState: (void**)enumState;
{
[self subclassResponsibility: _cmd];
return NO;
}
- (void) freeEnumState: (void**)enumState
{
*enumState = (void*)0;
}
// COPYING;
- allocCopy
{
return NSCopyObject (self, 0, [self zone]);
}
// the copy to be filled by -shallowCopyAs: etc... ;
- emptyCopy
{
// This will copy all instance vars;
// Subclasses will have to change instance vars like Array's _contents_array;
return [self allocCopy];
}
// the copy to be filled by -shallowCopyAs: etc... ;
- emptyCopyAs: (Class)aCollectionClass
{
if (aCollectionClass == [self species])
return [self emptyCopy];
else
return [[(id)aCollectionClass alloc] init];
}
- shallowCopy
{
return [self shallowCopyAs:[self species]];
}
- shallowCopyAs: (Class)aCollectionClass
{
id newColl = [self emptyCopyAs:aCollectionClass];
//#warning fix this addContentsOf for ConstantCollection
[newColl addContentsOf:self];
return newColl;
}
/* We can avoid the ugly [self safeWithElementsCall:doIt];
in -deepen with something like this instead.
This fits with a scheme in which we get rid of the -deepen method, an
idea that I like since calling deepen on an object that has not just
been -shallowCopy'ed can cause major memory leakage. */
- copyAs: (id <Collecting>)aCollectionClass
{
id newColl = [self emptyCopyAs: (Class)aCollectionClass];
id o;
FOR_COLLECTION(self, o)
{
//#warning fix this addObject for ConstantCollection
id n = [o copy];
[newColl addObject:n];
[n release];
}
END_FOR_COLLECTION(self);
return newColl;
}
- species
{
return [self class];
}
// EXTRAS;
- (const char *) libobjectsLicense
{
const char *licenseString =
"Copyright (C) 1993,1994,1995,1996 Free Software Foundation, Inc.\n"
"\n"
"Chief Maintainer: Andrew McCallum <mccallum@gnu.ai.mit.edu>\n"
"\n"
"This object is part of the GNUstep Base Library.\n"
"\n"
"This library is free software; you can redistribute it and/or\n"
"modify it under the terms of the GNU Library General Public\n"
"License as published by the Free Software Foundation; either\n"
"version 2 of the License, or (at your option) any later version.\n"
"\n"
"This library is distributed in the hope that it will be useful,\n"
"but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n"
"Library General Public License for more details.\n"
"\n"
"You should have received a copy of the GNU Library General Public\n"
"License along with this library; if not, write to the Free\n"
"Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.\n";
return licenseString;
}
- printForDebugger
{
id o;
FOR_COLLECTION(self, o)
{
printf("%s ", [[o description] cString]);
}
END_FOR_COLLECTION(self);
printf(": %s\n", object_get_class_name (self));
return self;
}
- (void) encodeWithCoder: aCoder
{
[self _encodeCollectionWithCoder:aCoder];
[self _encodeContentsWithCoder:aCoder];
}
- initWithCoder: aCoder
{
[self _initCollectionWithCoder:aCoder];
[self _decodeContentsWithCoder:aCoder];
return self;
}
@end
@implementation ConstantCollection (ArchivingHelpers)
- (void) _encodeCollectionWithCoder: aCoder
{
[super encodeWithCoder:aCoder];
// there are no instance vars;
return;
}
- _initCollectionWithCoder: aCoder
{
// there are no instance vars;
return [super initWithCoder:aCoder];
}
- (void) _encodeContentsWithCoder: (id <Encoding>)aCoder
{
unsigned int count = [self count];
id o;
[aCoder encodeValueOfCType: @encode(unsigned)
at: &count
withName: @"Collection content count"];
FOR_COLLECTION(self, o)
{
[aCoder encodeObject: o
withName:@"Collection element"];
}
END_FOR_COLLECTION(self);
}
- (void) _decodeContentsWithCoder: (id <Decoding>)aCoder
{
id *content_array;
unsigned int count, i;
[aCoder decodeValueOfCType:@encode(unsigned)
at:&count
withName:NULL];
content_array = alloca (sizeof (id) * count);
for (i = 0; i < count; i++)
[aCoder decodeObjectAt: &(content_array[i])
withName:NULL];
[self initWithObjects: content_array count: count];
for (i = 0; i < count; i++)
[content_array[i] release];
}
@end
@implementation ConstantCollection (DeallocationHelpers)
/* This must work without sending any messages to content objects.
Content objects already may be dealloc'd when this is executed. */
- (void) _collectionEmpty
{
[self subclassResponsibility:_cmd];
}
- (void) _collectionReleaseContents
{
int c = [self count];
if (c)
{
id *array = (id*) alloca (c * sizeof(id));
int i = 0;
void *es = [self newEnumState];
id o;
while ((o = [self nextObjectWithEnumState:&es]))
{
array[i++] = o;
}
[self freeEnumState: &es];
for (i = 0; i < c; i++)
[array[i] release];
}
}
- (void) _collectionDealloc
{
return;
}
@end
@implementation Collection
// ADDING;
- (void) addObject: anObject
{
[self subclassResponsibility:_cmd];
}
- (void) addObjectIfAbsent: newObject;
{
if (![self containsObject: newObject])
[self addObject: newObject];
}
- (void) addContentsOf: (id <Collecting>)aCollection
{
id o;
FOR_COLLECTION(aCollection, o)
{
[self addObject: o];
}
END_FOR_COLLECTION(aCollection);
}
- (void) addContentsIfAbsentOf: (id <Collecting>)aCollection
{
id o;
FOR_COLLECTION(aCollection, o)
{
if (![self containsObject:o])
[self addObject: o];
}
END_FOR_COLLECTION(aCollection);
}
- (void) addWithObjects: (id*)objc count: (unsigned)c
{
[self notImplemented: _cmd];
}
- (void) addObjects: firstObject, ...
{
[self notImplemented: _cmd];
}
- (void) addObjects: firstObject rest: (va_list)ap
{
[self notImplemented: _cmd];
}
// REMOVING AND REPLACING;
- (void) removeObject: oldObject
{
[self subclassResponsibility: _cmd];
}
- (void) removeAllOccurrencesOfObject: oldObject
{
while ([self containsObject: oldObject])
[self removeObject: oldObject];
}
- (void) removeContentsIn: (id <ConstantCollecting>)aCollection
{
id o;
FOR_COLLECTION(aCollection, o)
{
[self removeObject: o];
}
END_FOR_COLLECTION(aCollection);
}
- (void) removeContentsNotIn: (id <ConstantCollecting>)aCollection
{
id o;
FOR_COLLECTION(self, o)
{
if (![aCollection containsObject: o])
[self removeObject: o];
}
END_FOR_COLLECTION(self);
}
- (void) uniqueContents
{
id cp = [self shallowCopy];
int count;
id o;
FOR_COLLECTION(cp, o)
{
count = [self occurrencesOfObject: o];
if (!count)
continue;
while (count--)
[self removeObject: o];
}
END_FOR_COLLECTION(cp);
}
/* May be inefficient. Could be overridden; */
- (void) empty
{
if ([self isEmpty])
return;
[self _collectionReleaseContents];
[self _collectionEmpty];
}
// REPLACING;
- (void) replaceObject: oldObject withObject: newObject
{
if ([newObject isEqual: newObject])
return;
[oldObject retain];
[self removeObject: oldObject];
[self addObject: newObject];
[oldObject release];
}
- (void) replaceAllOccurrencesOfObject: oldObject withObject: newObject
{
if ([oldObject isEqual: newObject])
return;
while ([self containsObject: oldObject])
[self replaceObject: oldObject withObject: newObject];
}
@end

View file

@ -1,50 +0,0 @@
/* Collection definitions for the use of subclass implementations only
Copyright (C) 1993,1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __CollectionPrivate_h_GNUSTEP_BASE_INCLUDE
#define __CollectionPrivate_h_GNUSTEP_BASE_INCLUDE
@interface ConstantCollection (ArchivingHelpers)
/* These methods should never be called except in order, and inside
-encodeWithCoder: and -decodeWithCoder: */
- (void) _encodeCollectionWithCoder: (id <Encoding>)aCoder;
- _initCollectionWithCoder: (id <Decoding>)aCoder;
- (void) _encodeContentsWithCoder: (id <Encoding>)aCoder;
- (void) _decodeContentsWithCoder: (id <Decoding>)aCoder;
@end
@interface ConstantCollection (DeallocationHelpers)
/* Empty the internals of a collection after the contents have
already been released. */
- (void) _collectionEmpty;
- (void) _collectionReleaseContents;
/* Deallocate the internals of a collection after the contents
have already been released. */
- (void) _collectionDealloc;
@end
#endif /* __CollectionPrivate_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,878 +0,0 @@
/* Abstract class for reading objects from a stream
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: February 1996, with core from Coder, created 1994.
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/preface.h>
#include <base/Coder.h>
#include <base/CoderPrivate.h>
#include <base/CStream.h>
#include <base/Stream.h>
#include <base/StdioStream.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSException.h>
extern BOOL sel_types_match(const char* t1, const char* t2);
static int debug_coder = 0;
@implementation Decoder
static id dummyObject;
+ (void)initialize
{
BOOL beenHere = NO;
if (beenHere == NO)
{
beenHere = YES;
dummyObject = [NSObject new];
}
}
/* Signature Handling. */
+ (void) readSignatureFromCStream: (id <CStreaming>) cs
getClassname: (char *) name
formatVersion: (int*) version
{
int got;
char package_name[64];
int major_version;
int minor_version;
int subminor_version;
/* SIGNATURE_FORMAT_STRING is defined in gnustep/base/CoderPrivate.h */
got = [[cs stream] readFormat: SIGNATURE_FORMAT_STRING,
&package_name,
&major_version,
&minor_version,
&subminor_version,
name, version];
if (got != 6)
[NSException raise: CoderSignatureMalformedException
format: @"Decoder found a malformed signature"];
}
/* This is the designated initializer. */
+ newReadingFromStream: (id <Streaming>) stream
{
id cs = [CStream cStreamReadingFromStream: stream];
char name[128]; /* Max classname length. */
int version;
Decoder *new_coder;
[self readSignatureFromCStream: cs
getClassname: name
formatVersion: &version];
new_coder = [[objc_lookup_class(name) alloc]
_initWithCStream: cs
formatVersion: version];
new_coder->xref_2_object = NULL;
new_coder->xref_2_object_root = NULL;
new_coder->fref_2_object = NULL;
new_coder->address_2_fref = NULL;
new_coder->zone = NSDefaultMallocZone();
return new_coder;
}
+ newReadingFromFile: (NSString*) filename
{
return [self newReadingFromStream:
[StdioStream streamWithFilename: filename
fmode: "r"]];
}
+ decodeObjectWithName: (NSString* *) name
fromStream: (id <Streaming>)stream;
{
id c, o;
c = [self newReadingFromStream:stream];
[c decodeObjectAt: &o withName: name];
[c release];
return [o autorelease];
}
+ decodeObjectWithName: (NSString* *) name
fromFile: (NSString*) filename;
{
return [self decodeObjectWithName: name
fromStream:
[StdioStream streamWithFilename:filename fmode: "r"]];
}
/* Functions and methods for keeping cross-references
so objects that were already read can be referred to again. */
/* These _coder... methods may be overriden by subclasses so that
cross-references can be kept differently. */
- (unsigned) _coderCreateReferenceForObject: anObj
{
if (!xref_2_object)
{
xref_2_object = [NSMutableArray new];
/* Append an object so our xref numbers are in sync with the
Encoders, which start at 1. */
[xref_2_object addObject: dummyObject];
}
if (debug_coder)
fprintf (stderr, "Decoder registering object xref %u\n",
[xref_2_object count] - 1);
[xref_2_object addObject: anObj]; // xxx but this will retain anObj. NO.
/* This return value should be the same as the index of anObj
in xref_2_object. */
return ([xref_2_object count] - 1);
}
- (void) _coderSubstituteObject: anObj atReference: (unsigned)xref
{
[xref_2_object replaceObjectAtIndex: xref withObject: anObj];
}
- _coderObjectAtReference: (unsigned)xref
{
NSParameterAssert (xref_2_object);
return [xref_2_object objectAtIndex: xref];
}
/* The methods for the root object table. The *root* object table
(XREF_2_OBJECT_ROOT) isn't really used for much right now, but it
may be in the future. For now, most of the work is don't by
XREF_2_OBJECT. */
- (void) _coderPushRootObjectTable
{
if (!xref_2_object_root)
xref_2_object_root = [NSMutableArray new];
}
- (void) _coderPopRootObjectTable
{
NSParameterAssert (xref_2_object_root);
if (!interconnect_stack_height)
{
[xref_2_object_root release];
xref_2_object_root = NULL;
}
}
- (unsigned) _coderCreateReferenceForInterconnectedObject: anObj
{
if (!xref_2_object_root)
{
xref_2_object_root = [NSMutableArray new];
/* Append an object so our xref numbers are in sync with the
Encoders, which start at 1. */
[xref_2_object_root addObject: dummyObject];
}
[xref_2_object_root addObject: anObj];
/* This return value should be the same as the index of anObj
in xref_2_object_root. */
return ([xref_2_object_root count] - 1);
}
- _coderTopRootObjectTable
{
NSParameterAssert (xref_2_object_root);
return xref_2_object_root;
}
/* Using the next three methods, subclasses can change the way that
const pointers (like SEL, Class, Atomic strings, etc) are
archived. */
- (unsigned) _coderCreateReferenceForConstPtr: (const void*)ptr
{
unsigned xref;
if (!xref_2_const_ptr)
{
xref_2_const_ptr = NSCreateMapTable (NSIntMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks,
0);
/* Append an object so our xref numbers are in sync with the
Encoders, which start at 1. */
NSMapInsert (xref_2_const_ptr, (void*)0, (void*)1);
}
xref = NSCountMapTable (xref_2_const_ptr);
NSMapInsert (xref_2_const_ptr, (void*)xref, ptr);
return xref;
}
- (const void*) _coderConstPtrAtReference: (unsigned)xref;
{
NSParameterAssert (xref_2_const_ptr);
return NSMapGet (xref_2_const_ptr, (void*)xref);
}
/* Here are the methods for forward object references. */
- (void) _coderPushForwardObjectTable
{
#if 0
if (!fref_stack)
fref_stack = o_list_of_void_p ();
o_list_append_element (fref_stack, NSCreateMap (...));
#endif
if (!address_2_fref)
address_2_fref = NSCreateMapTable (NSNonOwnedPointerMapKeyCallBacks,
NSIntMapValueCallBacks, 0);
}
- (void) _coderPopForwardObjectTable
{
NSParameterAssert (address_2_fref);
if (!interconnect_stack_height)
{
NSFreeMapTable (address_2_fref);
address_2_fref = NULL;
}
}
- (void) _coderSatisfyForwardReference: (unsigned)fref withObject: anObj
{
NSParameterAssert (address_2_fref);
if (!fref_2_object)
/* xxx Or should this be NSObjectMapValueCallBacks, so we make
sure the object doesn't get released before we can resolve
references with it? */
fref_2_object = NSCreateMapTable (NSIntMapKeyCallBacks,
NSNonOwnedPointerMapValueCallBacks, 0);
/* There should only be one object for each fref. */
NSAssert (!NSMapGet (fref_2_object, (void*)fref),
@"Should have only been one object for each fref");
NSMapInsert (fref_2_object, (void*)fref, anObj);
}
- (void) _coderAssociateForwardReference: (unsigned)fref
withObjectAddress: (void*)addr
{
/* Register ADDR as associated with FREF; later we will put id
associated with FREF at ADDR. */
NSParameterAssert (address_2_fref);
/* There should not be duplicate addresses */
NSAssert (!NSMapGet (address_2_fref, addr), @"Duplicate addresses");
NSMapInsert (address_2_fref, addr, (void*)fref);
}
- (void) _coderResolveTopForwardReferences
{
/* Enumerate the forward references and put them at the proper addresses. */
NSMapEnumerator me;
void *fref;
void *addr;
if (!address_2_fref)
return;
/* Go through all the addresses that are needing to be filled
in with forward references, and put the correct object there.
If fref_2_object does not contain an object for fref, (i.e. there
was no satisfier for the forward reference), put nil there. */
me = NSEnumerateMapTable (address_2_fref);
while (NSNextMapEnumeratorPair (&me, &addr, &fref))
*(id*)addr = (id) NSMapGet (fref_2_object, fref);
}
/* This is the Coder's interface to the over-ridable
"_coderCreateReferenceForObject" method. Do not override it. It
handles the xref_2_object_root. */
- (unsigned) _coderInternalCreateReferenceForObject: anObj
{
unsigned xref = [self _coderCreateReferenceForObject: anObj];
if (DOING_ROOT_OBJECT)
[self _coderCreateReferenceForInterconnectedObject: anObj];
return xref;
}
- (void) _coderInternalSubstituteObject: anObj atReference: (unsigned)xref
{
[self _coderSubstituteObject: anObj atReference: xref];
/* xxx If we ever use the root object table, do something with it also. */
}
/* Method for decoding things. */
- (void) decodeValueOfCType: (const char*)type
at: (void*)d
withName: (NSString* *)namePtr
{
[cstream decodeValueOfCType:type
at:d
withName:namePtr];
}
- (void) decodeBytes: (void *)b
count: (unsigned)c
withName: (NSString* *) name
{
int actual_count;
/* xxx Is this what we want?
It won't be cleanly readable in TextCStream's. */
[cstream decodeName: name];
actual_count = [[cstream stream] readBytes: b length: c];
NSAssert2 (actual_count == c,
@"expected to read %d bytes, read %d bytes",c,actual_count);
}
- (unsigned char) decodeTag
{
if ([cstream respondsToSelector: @selector(decodeTag)])
return [(id)cstream decodeTag];
{
unsigned char t;
[self decodeValueOfCType:@encode(unsigned char)
at:&t
withName:NULL];
return t;
}
}
- decodeClass
{
unsigned char tag;
char *class_name;
int class_version;
id ret = Nil;
[self decodeIndent];
tag = [self decodeTag];
switch (tag)
{
case CODER_CLASS_NIL:
break;
case CODER_CLASS_REPEATED:
{
unsigned xref;
[self decodeValueOfCType: @encode(unsigned)
at: &xref
withName: NULL];
ret = (id) [self _coderConstPtrAtReference: xref];
if (!ret)
[NSException
raise: NSGenericException
format: @"repeated class cross-reference number %u not found",
xref];
break;
}
case CODER_CLASS:
{
[self decodeValueOfCType: @encode(char*)
at: &class_name
withName: NULL];
[self decodeValueOfCType: @encode(int)
at: &class_version
withName: NULL];
/* xxx should do classname substitution,
ala decodeClassName:intoClassName: here. */
ret = objc_lookup_class (class_name);
/* Ensure that the [+initialize] method has been called for the
class by calling one of it's methods */
if (ret != Nil)
ret = [ret class];
if (ret == Nil)
[NSException raise: NSGenericException
format: @"Couldn't find class `%s'", class_name];
if (class_get_version(ret) != class_version)
[NSException
raise: NSGenericException
format: @"Class version mismatch, executable %d != encoded %d",
class_get_version(ret), class_version];
{
unsigned xref;
xref = [self _coderCreateReferenceForConstPtr: ret];
if (debug_coder)
fprintf(stderr,
"Decoder decoding registered class xref %u\n", xref);
}
objc_free (class_name);
break;
}
default:
[NSException raise: NSGenericException
format: @"unrecognized class tag = %d", (int)tag];
}
[self decodeUnindent];
return ret;
}
- (const char *) decodeAtomicStringWithName: (NSString* *) name
{
char *s;
/* xxx Add repeat-string-ptr checking here */
[self notImplemented:_cmd];
[self decodeValueOfCType:@encode(char*) at:&s withName:name];
return s;
}
- (SEL) decodeSelectorWithName: (NSString* *) name
{
char tag;
SEL ret = NULL;
[self decodeName:name];
[self decodeIndent];
tag = [self decodeTag];
switch (tag)
{
case CODER_CONST_PTR_NULL:
break;
case CODER_CONST_PTR_REPEATED:
{
unsigned xref;
[self decodeValueOfCType: @encode(unsigned)
at: &xref
withName: NULL];
ret = (SEL) [self _coderConstPtrAtReference: xref];
if (!ret)
[NSException
raise: NSGenericException
format: @"repeated selector cross-reference number %u not found",
xref];
break;
}
case CODER_CONST_PTR:
{
char *sel_name;
char *sel_types;
[self decodeValueOfCType:@encode(char *)
at:&sel_name
withName:NULL];
[self decodeValueOfCType:@encode(char *)
at:&sel_types
withName:NULL];
#if NeXT_runtime
ret = sel_getUid(sel_name);
#else
if (!strcmp(sel_types, NO_SEL_TYPES))
ret = sel_get_any_uid(sel_name);
else
ret = sel_get_typed_uid(sel_name, sel_types);
#endif
if (!ret)
[NSException raise: NSGenericException
format: @"Could not find selector (%s) with types [%s]",
sel_name, sel_types];
#if ! NeXT_runtime
if (strcmp(sel_types, NO_SEL_TYPES)
&& !(sel_types_match(sel_types, ret->sel_types)))
[NSException
raise: NSGenericException
format: @"ObjC runtime didn't provide SEL with matching type"];
#endif
{
unsigned xref;
xref = [self _coderCreateReferenceForConstPtr: ret];
if (debug_coder)
fprintf(stderr,
"Decoder decoding registered sel xref %u\n", xref);
}
objc_free(sel_name);
objc_free(sel_types);
break;
}
default:
[NSException raise: NSGenericException
format: @"unrecognized selector tag = %d", (int)tag];
}
[self decodeUnindent];
return ret;
}
- (void) startDecodingInterconnectedObjects
{
interconnect_stack_height++;
[self _coderPushRootObjectTable];
[self _coderPushForwardObjectTable];
}
- (void) finishDecodingInterconnectedObjects
{
NSParameterAssert (interconnect_stack_height);
/* xxx This might not be the right thing to do; perhaps we should do
this finishing up work at the end of each nested call, not just
at the end of all nested calls.
However, then we might miss some forward references that we could
have resolved otherwise. */
if (--interconnect_stack_height)
return;
/* xxx fix the use of _coderPopForwardObjectTable and
_coderPopRootObjectTable. */
#if 0 /* Actually, we do this below in -decodeObjectAt:withName: */
/* Send "-awakeAfterUsingCoder:" to all the objects that were read */
{
SEL awake_sel = sel_get_any_uid("awakeAfterUsingCoder:");
if (awake_sel)
{
int i;
id table = [self _coderTopRootObjectTable];
/* Loop through all objects that we decoded by this Decoder */
for (i = [table count]-1; i >= 0; i--)
{
id o = [table objectAtIndex: i];
if (__objc_responds_to(o, awake_sel))
{
replacement_obj =
(*objc_msg_lookup(e.id_u,awake_sel))(o, awake_sel, self);
/* xxx Make the replacement in the decoder's object tables. */
}
}
}
}
#endif
/* resolve object forward references */
[self _coderResolveTopForwardReferences];
[self _coderPopForwardObjectTable];
[self _coderPopRootObjectTable];
}
- (void) _decodeRootObjectAt: (id*)ret withName: (NSString* *) name
{
[self startDecodingInterconnectedObjects];
[self decodeObjectAt:ret withName:name];
[self finishDecodingInterconnectedObjects];
}
- (void) decodeValueOfObjCType: (const char*)type
at: (void*)d
withName: (NSString* *)namePtr
{
switch (*type)
{
case _C_CLASS:
{
[self decodeName:namePtr];
*(id*)d = [self decodeClass];
break;
}
case _C_ATOM:
*(const char**)d = [self decodeAtomicStringWithName:namePtr];
break;
case _C_SEL:
*(SEL*)d = [self decodeSelectorWithName:namePtr];
break;
case _C_ID:
[self decodeObjectAt:d withName:namePtr];
break;
default:
[self decodeValueOfCType:type at:d withName:namePtr];
}
/* xxx We need to catch unions and make a sensible error message */
}
- (BOOL) _createReferenceBeforeInit
{
return NO;
}
/* This is the designated (and one-and-only) object decoder */
- (void) decodeObjectAt: (id*) anObjPtr withName: (NSString* *) name
{
unsigned char tag;
unsigned fref = 0;
id dummy_object;
/* Sometimes the user wants to decode an object, but doesn't care to
have a pointer to it, (LinkedList elements, for example). In
this case, the user can pass in NULL for anObjPtr, and all will
be safe. */
if (!anObjPtr)
anObjPtr = &dummy_object;
[self decodeName:name];
[self decodeIndent];
tag = [self decodeTag];
switch (tag)
{
case CODER_OBJECT_NIL:
*anObjPtr = nil;
break;
case CODER_OBJECT_CLASS:
*anObjPtr = [self decodeClass];
break;
case CODER_OBJECT_FORWARD_REFERENCE:
{
if (!DOING_ROOT_OBJECT)
[NSException
raise: NSGenericException
format: @"can't decode forward reference when not decoding "
@"a root object"];
[self decodeValueOfCType: @encode(unsigned)
at: &fref
withName: NULL];
/* The user doesn't need the object pointer anyway, don't record
it in the table. */
if (anObjPtr == &dummy_object)
break;
[self _coderAssociateForwardReference: fref
withObjectAddress: anObjPtr];
break;
}
case CODER_OBJECT:
{
Class object_class;
SEL new_sel = sel_get_any_uid ("newWithCoder:");
Method* new_method;
BOOL create_ref_before_init = [self _createReferenceBeforeInit];
/* Initialize this to <0 so we can tell below if it's been set */
int xref = -1;
[self decodeIndent];
object_class = [self decodeClass];
/* xxx Should change the runtime.
class_get_class_method should take the class as its first
argument, not the metaclass! */
new_method = class_get_class_method(class_get_meta_class(object_class),
new_sel);
if (new_method && !create_ref_before_init)
*anObjPtr = (*(new_method->method_imp))(object_class, new_sel, self);
else
{
SEL init_sel = sel_get_any_uid ("initWithCoder:");
Method *init_method =
class_get_instance_method (object_class, init_sel);
/* xxx Or should I send +alloc? */
*anObjPtr = (id) NSAllocateObject (object_class, 0, zone);
if (create_ref_before_init)
xref = [self _coderInternalCreateReferenceForObject: *anObjPtr];
if (init_method)
*anObjPtr =
(*(init_method->method_imp))(*anObjPtr, init_sel, self);
/* xxx else what, error? */
}
/* Send -awakeAfterUsingCoder: */
/* xxx Unknown whether -awakeAfterUsingCoder: should be sent here, or
when Decoder is deallocated, or after a root object is finished
decoding. */
/* NOTE: Use of this with the NeXT archiving methods is
tricky, because if [*anObj initWithCoder:] creates any
objects that references *anObj, and if [*anObj
awakeAfterUsingCoder:] replaces itself, then the
subobject's references will not be to the replacement.
There is no way to magically fix this circular dependancy;
users must be aware. We should just make sure we require
the same cautions as NeXT's implementation. Note that, with
the GNU archiving methods, this problem doesn't occur because
we don't register the object until after it has been fully
initialized and awakened. */
{
SEL awake_sel = sel_get_any_uid ("awakeAfterUsingCoder:");
IMP awake_imp = objc_msg_lookup (*anObjPtr, awake_sel);
id replacement;
if (awake_imp)
{
replacement = (*awake_imp) (*anObjPtr, awake_sel, self);
if (replacement != *anObjPtr)
{
if (xref > 0)
[self _coderInternalSubstituteObject: replacement
atReference: xref];
*anObjPtr = replacement;
}
}
}
[self decodeUnindent];
/* If this was a CODER_OBJECT_FORWARD_SATISFIER, then remember it. */
[self decodeValueOfCType: @encode(unsigned)
at: &fref
withName: NULL];
if (fref)
{
NSAssert (!create_ref_before_init,
@"You are trying to decode an object with the non-GNU\n"
@"OpenStep-style forward references, but the object's\n"
@"decoding mechanism wants to use GNU features.");
[self _coderSatisfyForwardReference: fref withObject: *anObjPtr];
}
/* Would get error here with Connection-wide object references
because addProxy gets called in +newRemote:connection: */
if (!create_ref_before_init)
{
unsigned xref =
[self _coderInternalCreateReferenceForObject: *anObjPtr];
if (debug_coder)
fprintf(stderr,
"Decoder decoding registered class xref %u\n", xref);
}
break;
}
case CODER_OBJECT_ROOT:
{
[self _decodeRootObjectAt: anObjPtr withName: name];
break;
}
case CODER_OBJECT_REPEATED:
{
unsigned xref;
[self decodeValueOfCType: @encode(unsigned)
at: &xref
withName: NULL];
*anObjPtr = [[self _coderObjectAtReference: xref] retain];
if (!*anObjPtr)
[NSException
raise: NSGenericException
format: @"repeated object cross-reference number %u not found",
xref];
break;
}
default:
[NSException raise: NSGenericException
format: @"unrecognized object tag = %d", (int)tag];
}
[self decodeUnindent];
}
- (void) decodeWithName: (NSString* *)name
valuesOfObjCTypes: (const char *)types, ...
{
va_list ap;
[self decodeName:name];
va_start(ap, types);
while (*types)
{
[self decodeValueOfObjCType:types
at:va_arg(ap, void*)
withName:NULL];
types = objc_skip_typespec(types);
}
va_end(ap);
}
- (void) decodeValueOfObjCTypes: (const char *)types
at: (void *)d
withName: (NSString* *)name
{
[self decodeName:name];
while (*types)
{
[self decodeValueOfObjCType:types
at:d
withName:NULL];
types = objc_skip_typespec(types);
}
}
- (void) decodeArrayOfObjCType: (const char *)type
count: (unsigned)c
at: (void *)d
withName: (NSString* *) name
{
int i;
int offset = objc_sizeof_type(type);
char *where = d;
[self decodeName:name];
for (i = 0; i < c; i++)
{
[self decodeValueOfObjCType:type
at:where
withName:NULL];
where += offset;
}
}
- (void) decodeIndent
{
[cstream decodeIndent];
}
- (void) decodeUnindent
{
[cstream decodeUnindent];
}
- (void) decodeName: (NSString* *)n
{
[cstream decodeName: n];
}
+ (NSString*) classNameDecodedForArchiveClassName: (NSString*) inArchiveName
{
[self notImplemented:_cmd];
return nil;
}
+ (void) decodeClassName: (NSString*) inArchiveName
asClassName:(NSString *)trueName
{
[self notImplemented:_cmd];
}
/* Managing Zones */
- (NSZone*) objectZone
{
return zone;
}
- (void) setObjectZone: (NSZone*)z
{
zone = z;
}
- (void) dealloc
{
if (xref_2_object) [xref_2_object release];
if (xref_2_object_root) [xref_2_object_root release];
if (xref_2_const_ptr) NSFreeMapTable (xref_2_const_ptr);
if (fref_2_object) NSFreeMapTable (fref_2_object);
if (address_2_fref) NSFreeMapTable (address_2_fref);
[super dealloc];
}
@end

View file

@ -1,74 +0,0 @@
/* Interface for Objective-C "collection of delegates" object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/* Using this object, a delegator can have an arbitrary number of
delegates. Send a message to this object and the message will get
forwarded to the delegates on the list. */
#ifndef __DelegatePool_h_GNUSTEP_BASE_INCLUDE
#define __DelegatePool_h_GNUSTEP_BASE_INCLUDE
#include <base/Array.h>
/* Available sending behaviors */
enum DelegatePoolSendBehavior {SEND_TO_ALL = 0,
SEND_TO_FIRST_RESPONDER,
SEND_UNTIL_YES,
SEND_UNTIL_NO};
@interface DelegatePool
{
struct objc_class *isa;
@public
unsigned char _send_behavior;
Array *_list;
BOOL _last_message_had_receivers;
}
// CREATING AND FREEING;
+ alloc;
+ new;
- init;
- (void) dealloc;
// MANIPULATING COLLECTION OF DELEGATES;
- (void) delegatePoolAddObject: anObject;
- (void) delegatePoolAddObjectIfAbsent: anObject;
- (void) delegatePoolRemoveObject: anObject;
- (BOOL) delegatePoolIncludesObject: anObject;
- delegatePoolCollection;
- (unsigned char) delegatePoolSendBehavior;
- (void) delegatePoolSetSendBehavior: (unsigned char)b;
// FOR PASSING ALL OTHER MESSAGES TO DELEGATES;
// RETURNS 0 IF NO OBJECTS RESPOND;
- forward:(SEL)aSel :(arglist_t)argFrame;
// FOR FINDING OUT IF ANY OBJECTS IN THE POOL RESPONDED TO THE LAST MSG;
/* This method is bad because it won't be thread-safe---it may
go away in the future. */
- (BOOL) delegatePoolLastMessageHadReceivers;
@end
#endif /* __DelegatePool_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,210 +0,0 @@
/* Implementation of Objective-C "collection of delegates" object
Copyright (C) 1993,1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
This file is part of the GNU Objective-C Collection 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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/DelegatePool.h>
#include <base/NSString.h>
@implementation DelegatePool
+ (void) initialize
{
return;
}
+ alloc
{
return (id)class_create_instance(self);
}
+ new
{
return [[self alloc] init];
}
/* This is the designated initializer for this class. */
- init
{
_list = [[Array alloc] init];
_send_behavior = SEND_TO_ALL;
_last_message_had_receivers = NO;
return self;
}
/* Archiving must mimic the above designated initializer */
- (void) encodeWithCoder: anEncoder
{
[anEncoder encodeValueOfCType:@encode(unsigned char)
at:&_send_behavior
withName:@"DelegatePool Send Behavior"];
[anEncoder encodeObject:_list
withName:@"DelegatePool Collection of Delegates"];
}
+ newWithCoder: aDecoder
{
/* xxx Should be:
DelegatePool *n = NSAllocateObject(self, 0, [aDecoder objectZone]); */
DelegatePool *n = (id) NSAllocateObject(self, 0, NSDefaultMallocZone());
[aDecoder decodeValueOfCType:@encode(unsigned char)
at:&(n->_send_behavior)
withName:NULL];
[aDecoder decodeObjectAt:&(n->_list)
withName:NULL];
return n;
}
- write: (TypedStream*)aStream
{
objc_write_type(aStream, @encode(unsigned char), &_send_behavior);
objc_write_object(aStream, _list);
return self;
}
- read: (TypedStream*)aStream
{
objc_write_type(aStream, @encode(unsigned char), &_send_behavior);
objc_read_object(aStream, &_list);
return self;
}
- (void) dealloc
{
[_list release];
#if NeXT_runtime
object_dispose((Object*)self);
#else
NSDeallocateObject((NSObject*)self);
#endif
}
// MANIPULATING COLLECTION OF DELEGATES;
- (void) delegatePoolAddObject: anObject
{
[_list addObject: anObject];
}
- (void) delegatePoolAddObjectIfAbsent: anObject
{
[_list addObjectIfAbsent: anObject];
}
- (void) delegatePoolRemoveObject: anObject
{
[_list removeObject:anObject];
}
- (BOOL) delegatePoolIncludesObject: anObject
{
return [_list containsObject:anObject];
}
- delegatePoolCollection
{
return _list;
}
- (unsigned char) delegatePoolSendBehavior
{
return _send_behavior;
}
- (void) delegatePoolSetSendBehavior: (unsigned char)b
{
_send_behavior = b;
}
- (BOOL) delegatePoolLastMessageHadReceivers
{
return _last_message_had_receivers;
}
// FOR PASSING ALL OTHER MESSAGES TO DELEGATES;
- forward: (SEL)aSel :(arglist_t)argFrame
{
void *ret = 0;
id delegate;
_last_message_had_receivers = NO;
switch (_send_behavior)
{
case SEND_TO_ALL:
FOR_ARRAY(_list, delegate)
{
if ([delegate respondsTo:aSel])
{
ret = [delegate performv:aSel :argFrame];
_last_message_had_receivers = YES;
}
}
END_FOR_ARRAY (_list);
break;
case SEND_TO_FIRST_RESPONDER:
FOR_ARRAY(_list, delegate)
{
if ([delegate respondsTo:aSel])
{
_last_message_had_receivers = YES;
return [delegate performv:aSel :argFrame];
}
}
END_FOR_ARRAY (_list);
break;
case SEND_UNTIL_YES:
FOR_ARRAY(_list, delegate)
{
if ([delegate respondsTo:aSel])
{
_last_message_had_receivers = YES;
if ((ret = [delegate performv:aSel :argFrame]))
return ret;
}
}
END_FOR_ARRAY (_list);
break;
case SEND_UNTIL_NO:
FOR_ARRAY(_list, delegate)
{
if ([delegate respondsTo:aSel])
{
_last_message_had_receivers = YES;
if (!(ret = [delegate performv:aSel :argFrame]))
return ret;
}
}
END_FOR_ARRAY (_list);
break;
}
return ret;
}
@end

View file

@ -1,40 +0,0 @@
/* Interface for Objective-C Dictionary collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Dictionary_h_GNUSTEP_BASE_INCLUDE
#define __Dictionary_h_GNUSTEP_BASE_INCLUDE
#include <base/KeyedCollection.h>
#include <Foundation/NSMapTable.h>
@interface Dictionary : KeyedCollection
{
NSMapTable *_contents_hash;
}
- initWithCapacity: (unsigned)aCapacity;
@end
#endif /* __Dictionary_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,209 +0,0 @@
/* Implementation for Objective-C Dictionary collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/Dictionary.h>
#include <base/CollectionPrivate.h>
#include <Foundation/NSCharacterSet.h>
#define DEFAULT_DICTIONARY_CAPACITY 32
@implementation Dictionary
// MANAGING CAPACITY;
/* Eventually we will want to have better capacity management,
potentially keep default capacity as a class variable. */
+ (unsigned) defaultCapacity
{
return DEFAULT_DICTIONARY_CAPACITY;
}
// INITIALIZING;
/* This is the designated initializer of this class */
- initWithCapacity: (unsigned)cap
{
_contents_hash = NSCreateMapTable (NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks,
cap);
return self;
}
/* Override the KeyedCollection designated initializer */
- initWithObjects: (id*)objects forKeys: (id*)keys count: (unsigned)c
{
[self initWithCapacity: c];
while (c--)
[self putObject: objects[c] atKey: keys[c]];
return self;
}
- init
{
return [self initWithCapacity: DEFAULT_DICTIONARY_CAPACITY];
}
/* Archiving must mimic the above designated initializer */
- _initCollectionWithCoder: (id <Decoding>)coder
{
_contents_hash = NSCreateMapTable (NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks,
0);
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
Dictionary *copy = [super emptyCopy];
copy->_contents_hash = NSCreateMapTable (NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks,
0);
return copy;
}
- (void) _collectionReleaseContents
{
if (_contents_hash) {
NSFreeMapTable (_contents_hash);
_contents_hash = 0;
}
}
- (void) dealloc
{
[self _collectionReleaseContents];
[super dealloc];
}
/* This must work without sending any messages to content objects */
- (void) _collectionEmpty
{
NSResetMapTable (_contents_hash);
}
// ADDING OR REPLACING;
- (void) addObject: newObject
{
[self shouldNotImplement: _cmd];
/* or should I make up some default behavior here?
Base it on object conforming to <Associating> protocol, perhaps */
}
- (void) putObject: newObject atKey: aKey
{
NSMapInsert (_contents_hash, aKey, newObject);
}
// REMOVING;
- (void) removeObjectAtKey: aKey
{
NSMapRemove (_contents_hash, aKey);
}
- (void) removeObject: oldObject
{
/* xxx Could be more efficient! */
int count = [self count];
id keys_to_remove[count];
int num_keys_to_remove = 0;
id o, k;
NSMapEnumerator me = NSEnumerateMapTable (_contents_hash);
/* Find all the keys with corresponding objects that equal oldObject. */
while (NSNextMapEnumeratorPair (&me, (void**)&k, (void**)&o))
if ([oldObject isEqual: o])
keys_to_remove[num_keys_to_remove++] = k;
/* Remove them. */
while (num_keys_to_remove--)
[self removeObjectAtKey: keys_to_remove[num_keys_to_remove]];
}
// GETTING ELEMENTS;
- (NSArray*) allKeys
{
return NSAllMapTableKeys(_contents_hash);
}
- (NSArray*) allValues
{
return NSAllMapTableValues(_contents_hash);
}
- objectAtKey: aKey
{
return NSMapGet (_contents_hash, aKey);
}
// TESTING;
- (BOOL) containsKey: aKey
{
if (NSMapGet (_contents_hash, aKey))
return YES;
else
return NO;
}
- (unsigned) count
{
return NSCountMapTable (_contents_hash);
}
// ENUMERATIONS;
- nextObjectAndKey: (id*)aKeyPtr withEnumState: (void**)enumState
{
id o;
if (!NSNextMapEnumeratorPair (*enumState, (void**)aKeyPtr, (void**)&o))
return NO_OBJECT;
return o;
}
- (void*) newEnumState
{
void *me;
OBJC_MALLOC (me, NSMapEnumerator, 1);
*((NSMapEnumerator*)me) = NSEnumerateMapTable (_contents_hash);
return me;
}
- (void) freeEnumState: (void**)enumState
{
OBJC_FREE (*enumState);
}
@end

View file

@ -1,883 +0,0 @@
/* Abstract class for writing objects to a stream
Copyright (C) 1996, 1997 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: February 1996, with core from Coder, created 1994.
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/preface.h>
#include <base/Coder.h>
#include <base/CoderPrivate.h>
#include <base/MemoryStream.h>
#include <base/StdioStream.h>
#include <base/BinaryCStream.h>
#include <Foundation/NSArchiver.h>
#include <Foundation/NSException.h>
static int default_format_version;
static id default_stream_class;
static id default_cstream_class;
#define DEFAULT_DEFAULT_FORMAT_VERSION 0
static int debug_coder = 0;
/* xxx For experimentation. The function in objc-api.h doesn't always
work for objects; it sometimes returns YES for an instance. */
/* But, metaclasses return YES too? */
static BOOL
my_object_is_class(id object)
{
if (object != nil
#if NeXT_runtime
&& CLS_ISMETA(((Class)object)->isa)
&& ((Class)object)->isa != ((Class)object)->isa)
#else
&& CLS_ISMETA(((Class)object)->class_pointer)
&& ((Class)object)->class_pointer != ((Class)object)->class_pointer)
#endif
return YES;
else
return NO;
}
@implementation Encoder
+ (void) initialize
{
if (self == [Encoder class])
{
/* This code has not yet been ported to machines for which
a pointer is not the same size as an int. */
NSAssert(sizeof(void*) == sizeof(unsigned),
@"Pointer and int are different sizes");
/* Initialize some defaults. */
default_stream_class = [MemoryStream class];
default_cstream_class = [BinaryCStream class];
default_format_version = DEFAULT_DEFAULT_FORMAT_VERSION;
}
}
/* Default format version, Stream and CStream class handling. */
+ (int) defaultFormatVersion
{
return default_format_version;
}
+ (void) setDefaultFormatVersion: (int)f
{
default_format_version = f;
}
+ (void) setDefaultCStreamClass: sc
{
default_cstream_class = sc;
}
+ defaultCStreamClass
{
return default_cstream_class;
}
+ (void) setDefaultStreamClass: sc
{
default_stream_class = sc;
}
+ defaultStreamClass
{
return default_stream_class;
}
/* xxx This method interface may change in the future. */
- (const char *) defaultDecoderClassname
{
return "Unarchiver";
}
/* Signature Handling. */
- (void) writeSignature
{
/* Careful: the string should not contain newlines. */
[[cstream stream] writeFormat: SIGNATURE_FORMAT_STRING,
WRITE_SIGNATURE_FORMAT_ARGS];
}
/* This is the designated initializer for this class. */
- initForWritingToStream: (id <Streaming>) s
withFormatVersion: (int) version
cStreamClass: (Class) cStreamClass
cStreamFormatVersion: (int) cStreamFormatVersion
{
[super _initWithCStream: [[cStreamClass alloc]
initForWritingToStream: s
withFormatVersion: cStreamFormatVersion]
formatVersion: version];
[cstream release];
in_progress_table = NULL;
object_2_xref = NULL;
object_2_fref = NULL;
const_ptr_2_xref = NULL;
fref_counter = 0;
[self writeSignature];
return self;
}
/* ..Writing... methods */
- initForWritingToStream: (id <Streaming>) s
withCStreamClass: (Class) cStreamClass
{
return [self initForWritingToStream: s
withFormatVersion: DEFAULT_DEFAULT_FORMAT_VERSION
cStreamClass: cStreamClass
cStreamFormatVersion: [cStreamClass defaultFormatVersion]];
}
- initForWritingToStream: (id <Streaming>) s
{
return [self initForWritingToStream: s
withCStreamClass: [[self class] defaultCStreamClass]];
}
- initForWritingToFile: (NSString*) filename
withFormatVersion: (int) version
cStreamClass: (Class) cStreamClass
cStreamFormatVersion: (int) cStreamFormatVersion
{
return [self initForWritingToStream: [StdioStream
streamWithFilename: filename
fmode: "w"]
withFormatVersion: version
cStreamClass: cStreamClass
cStreamFormatVersion: cStreamFormatVersion];
}
- initForWritingToFile: (NSString*) filename
withCStreamClass: (Class) cStreamClass
{
return [self initForWritingToStream: [StdioStream
streamWithFilename: filename
fmode: "w"]
withCStreamClass: cStreamClass];
}
- initForWritingToFile: (NSString*) filename
{
return [self initForWritingToStream:
[StdioStream streamWithFilename: filename
fmode: "w"]];
}
+ newWritingToStream: (id <Streaming>)s
{
return [[self alloc] initForWritingToStream: s];
}
+ newWritingToFile: (NSString*)filename
{
return [self newWritingToStream:
[StdioStream streamWithFilename: filename
fmode: "w"]];
}
+ (BOOL) encodeRootObject: anObject
withName: (NSString*) name
toStream: (id <Streaming>)stream
{
id c = [[self alloc] initForWritingToStream: stream];
[c encodeRootObject: anObject withName: name];
[c close];
[c release];
return YES;
}
+ (BOOL) encodeRootObject: anObject
withName: (NSString*) name
toFile: (NSString*) filename
{
return [self encodeRootObject: anObject
withName: name
toStream: [StdioStream streamWithFilename: filename
fmode: "w"]];
}
/* Functions and methods for keeping cross-references
so objects aren't written/read twice. */
/* These _coder... methods may be overriden by subclasses so that
cross-references can be kept differently.
over again.
*/
- (unsigned) _coderCreateReferenceForObject: anObj
{
unsigned xref;
if (!object_2_xref)
{
object_2_xref =
NSCreateMapTable (NSNonOwnedPointerOrNullMapKeyCallBacks,
NSIntMapValueCallBacks, 0);
}
xref = NSCountMapTable (object_2_xref) + 1;
NSMapInsert (object_2_xref, anObj, (void*)xref);
return xref;
}
- (unsigned) _coderReferenceForObject: anObject
{
if (object_2_xref)
return (unsigned) NSMapGet (object_2_xref, anObject);
else
return 0;
}
/* Methods for handling constant pointers */
/* By overriding the next three methods, subclasses can change the way
that const pointers (like SEL, Class, Atomic strings, etc) are
archived. */
- (unsigned) _coderCreateReferenceForConstPtr: (const void*)ptr
{
unsigned xref;
if (!const_ptr_2_xref)
const_ptr_2_xref =
NSCreateMapTable (NSNonOwnedPointerOrNullMapKeyCallBacks,
NSIntMapValueCallBacks, 0);
xref = NSCountMapTable (const_ptr_2_xref) + 1;
NSAssert (! NSMapGet (const_ptr_2_xref, (void*)xref), @"xref already in Map");
NSMapInsert (const_ptr_2_xref, ptr, (void*)xref);
return xref;
}
- (unsigned) _coderReferenceForConstPtr: (const void*)ptr
{
if (const_ptr_2_xref)
return (unsigned) NSMapGet (const_ptr_2_xref, ptr);
else
return 0;
}
/* Methods for forward references */
- (unsigned) _coderCreateForwardReferenceForObject: anObject
{
unsigned fref;
if (!object_2_fref)
object_2_fref =
NSCreateMapTable (NSNonOwnedPointerOrNullMapKeyCallBacks,
NSIntMapValueCallBacks, 0);
fref = ++fref_counter;
NSAssert ( ! NSMapGet (object_2_fref, anObject), @"anObject already in Map");
NSMapInsert (object_2_fref, anObject, (void*)fref);
return fref;
}
- (unsigned) _coderForwardReferenceForObject: anObject
{
/* This method must return 0 if it's not there. */
if (!object_2_fref)
return 0;
return (unsigned) NSMapGet (object_2_fref, anObject);
}
- (void) _coderRemoveForwardReferenceForObject: anObject
{
NSMapRemove (object_2_fref, anObject);
}
/* This is the Coder's interface to the over-ridable
"_coderPutObject:atReference" method. Do not override it. It
handles the root_object_table. */
- (void) _coderInternalCreateReferenceForObject: anObj
{
[self _coderCreateReferenceForObject: anObj];
}
/* Handling the in_progress_table. These are called before and after
the actual object (not a forward or backward reference) is encoded.
One of these objects should also call
-_coderInternalCreateReferenceForObject:. GNU archiving calls it
in the first, in order to force forward references to objects that
are in progress; this allows for -initWithCoder: methods that
deallocate self, and return another object. OpenStep-style coding
calls it in the second, meaning that we never create forward
references to objects that are in progress; we encode a backward
reference to the in progress object, and assume that it will not
change location. */
- (void) _objectWillBeInProgress: anObj
{
if (!in_progress_table)
in_progress_table =
/* This is "NonOwnedPointer", and not "Object", because
with "Object" we would get an infinite loop with distributed
objects when we try to put a Proxy in in the table, and
send the proxy the -hash method. */
NSCreateMapTable (NSNonOwnedPointerMapKeyCallBacks,
NSIntMapValueCallBacks, 0);
NSMapInsert (in_progress_table, anObj, (void*)1);
}
- (void) _objectNoLongerInProgress: anObj
{
NSMapRemove (in_progress_table, anObj);
/* Register that we have encoded it so that future encoding can
do backward references properly. */
[self _coderInternalCreateReferenceForObject: anObj];
}
/* Method for encoding things. */
- (void) encodeValueOfCType: (const char*)type
at: (const void*)d
withName: (NSString*)name
{
[cstream encodeValueOfCType:type
at:d
withName:name];
}
- (void) encodeBytes: (const void *)b
count: (unsigned)c
withName: (NSString*)name
{
/* xxx Is this what we want?
It won't be cleanly readable in TextCStream's. */
[cstream encodeName: name];
[[cstream stream] writeBytes: b length: c];
}
- (void) encodeTag: (unsigned char)t
{
if ([cstream respondsToSelector: @selector(encodeTag:)])
[(id)cstream encodeTag:t];
else
[self encodeValueOfCType:@encode(unsigned char)
at:&t
withName:@"Coder tag"];
}
- (void) encodeClass: aClass
{
[self encodeIndent];
if (aClass == Nil)
{
[self encodeTag: CODER_CLASS_NIL];
}
else
{
/* xxx Perhaps I should do classname substitution here. */
const char *class_name = class_get_class_name (aClass);
unsigned xref;
/* Do classname substitution, ala encodeClassName:intoClassName */
if (classname_2_classname)
{
char *subst_class_name = NSMapGet (classname_2_classname,
class_name);
if (subst_class_name)
{
class_name = subst_class_name;
aClass = objc_lookup_class (class_name);
}
}
xref = [self _coderReferenceForConstPtr: aClass];
if (xref)
{
/* It's already been encoded, so just encode the x-reference */
[self encodeTag: CODER_CLASS_REPEATED];
[self encodeValueOfCType: @encode(unsigned)
at: &xref
withName: @"Class cross-reference number"];
}
else
{
/* It hasn't been encoded before; encode it. */
int class_version = class_get_version (aClass);
NSAssert (class_name, @"Class doesn't have a name");
NSAssert (*class_name, @"Class name is empty");
[self encodeTag: CODER_CLASS];
[self encodeValueOfCType: @encode(char*)
at: &class_name
withName: @"Class name"];
[self encodeValueOfCType: @encode(int)
at: &class_version
withName: @"Class version"];
[self _coderCreateReferenceForConstPtr: aClass];
}
}
[self encodeUnindent];
return;
}
- (void) encodeAtomicString: (const char*) sp
withName: (NSString*) name
{
/* xxx Add repeat-string-ptr checking here. */
[self notImplemented:_cmd];
[self encodeValueOfCType:@encode(char*) at:&sp withName:name];
}
- (void) encodeSelector: (SEL)sel withName: (NSString*) name
{
[self encodeName:name];
[self encodeIndent];
if (sel == 0)
{
[self encodeTag: CODER_CONST_PTR_NULL];
}
else
{
unsigned xref = [self _coderReferenceForConstPtr: sel];
if (xref)
{
/* It's already been encoded, so just encode the x-reference */
[self encodeTag: CODER_CONST_PTR_REPEATED];
[self encodeValueOfCType: @encode(unsigned)
at: &xref
withName: @"SEL cross-reference number"];
}
else
{
const char *sel_name;
const char *sel_types;
[self encodeTag: CODER_CONST_PTR];
/* Get the selector name and type. */
sel_name = sel_get_name(sel);
#if NeXT_runtime
sel_types = NO_SEL_TYPES;
#else
sel_types = sel_get_type(sel);
#endif
#if 1 /* xxx Yipes,... careful... */
/* xxx Think about something like this. */
if (!sel_types)
sel_types =
sel_get_type (sel_get_any_typed_uid (sel_get_name (sel)));
#endif
if (!sel_name || !*sel_name)
[NSException raise: NSGenericException
format: @"ObjC runtime didn't provide SEL name"];
if (!sel_types || !*sel_types)
sel_types = NO_SEL_TYPES;
[self _coderCreateReferenceForConstPtr: sel];
[self encodeValueOfCType: @encode(char*)
at: &sel_name
withName: @"SEL name"];
[self encodeValueOfCType: @encode(char*)
at: &sel_types
withName: @"SEL types"];
if (debug_coder)
fprintf(stderr, "Coder encoding registered sel xref %u\n", xref);
}
}
[self encodeUnindent];
return;
}
- (void) encodeValueOfObjCType: (const char*) type
at: (const void*) d
withName: (NSString*) name
{
switch (*type)
{
case _C_CLASS:
[self encodeName: name];
[self encodeClass: *(id*)d];
break;
case _C_ATOM:
[self encodeAtomicString: *(char**)d withName: name];
break;
case _C_SEL:
{
[self encodeSelector: *(SEL*)d withName: name];
break;
}
case _C_ID:
[self encodeObject: *(id*)d withName: name];
break;
default:
[self encodeValueOfCType:type at:d withName:name];
}
}
/* Methods for handling interconnected objects */
- (void) startEncodingInterconnectedObjects
{
interconnect_stack_height++;
}
- (void) finishEncodingInterconnectedObjects
{
/* xxx Perhaps we should look at the forward references and
encode here any forward-referenced objects that haven't been
encoded yet. No---the current behavior implements NeXT's
-encodeConditionalObject: */
NSParameterAssert (interconnect_stack_height);
interconnect_stack_height--;
}
/* NOTE: Unlike NeXT's, this *can* be called recursively */
- (void) encodeRootObject: anObj
withName: (NSString*)name
{
[self encodeName: @"Root Object"];
[self encodeIndent];
[self encodeTag: CODER_OBJECT_ROOT];
[self startEncodingInterconnectedObjects];
[self encodeObject: anObj withName: name];
[self finishEncodingInterconnectedObjects];
[self encodeUnindent];
}
/* These next three methods are the designated coder methods called when
we've determined that the object has not already been
encoded---we're not simply going to encode a cross-reference number
to the object, we're actually going to encode an object (either a
proxy to the object or the object itself).
NSPortCoder overrides _doEncodeObject: in order to implement
the encoding of proxies. */
- (void) _doEncodeBycopyObject: anObj
{
id encoded_object, encoded_class;
/* Give the user the opportunity to substitute the class and object */
/* xxx Is this the right place for this substitution? */
if ([[self class] isKindOf: [NSCoder class]]
&& ! [[self class] isKindOf: [NSArchiver class]])
/* Make sure we don't do this for the Coder class, because
by default Coder should behave like NSArchiver. */
{
encoded_object = [anObj replacementObjectForCoder: (NSCoder*)self];
encoded_class = [encoded_object classForCoder];
}
else
{
encoded_object = [anObj replacementObjectForArchiver: (NSArchiver*)self];
encoded_class = [encoded_object classForArchiver];
}
[self encodeClass: encoded_class];
/* xxx We should make sure it responds to this selector! */
[encoded_object encodeWithCoder: (id)self];
}
/* This method overridden by NSPortCoder */
- (void) _doEncodeObject: anObj
{
[self _doEncodeBycopyObject:anObj];
}
/* This method overridden by NSPortCoder */
- (void) _doEncodeByrefObject: anObj
{
[self _doEncodeObject: anObj];
}
/* This is the designated object encoder */
- (void) _encodeObject: anObj
withName: (NSString*) name
isBycopy: (BOOL) bycopy_flag
isByref: (BOOL) byref_flag
isForwardReference: (BOOL) forward_ref_flag
{
[self encodeName:name];
[self encodeIndent];
if (!anObj)
{
[self encodeTag:CODER_OBJECT_NIL];
}
else if (my_object_is_class(anObj))
{
[self encodeTag: CODER_OBJECT_CLASS];
[self encodeClass:anObj];
}
else
{
unsigned xref = [self _coderReferenceForObject: anObj];
if (xref)
{
/* It's already been encoded, so just encode the x-reference */
[self encodeTag: CODER_OBJECT_REPEATED];
[self encodeValueOfCType: @encode(unsigned)
at: &xref
withName: @"Object cross-reference number"];
}
else if (forward_ref_flag
|| (in_progress_table
&& NSMapGet (in_progress_table, anObj)))
{
unsigned fref;
/* We are going to encode a forward reference, either because
(1) our caller asked for it, or (2) we are in the middle
of encoding this object, and haven't finished encoding it yet. */
/* Find out if it already has a forward reference number. */
fref = [self _coderForwardReferenceForObject: anObj];
if (!fref)
/* It doesn't, so create one. */
fref = [self _coderCreateForwardReferenceForObject: anObj];
[self encodeTag: CODER_OBJECT_FORWARD_REFERENCE];
[self encodeValueOfCType: @encode(unsigned)
at: &fref
withName: @"Object forward cross-reference number"];
}
else
{
/* No backward or forward references, we are going to encode
the object. */
unsigned fref;
/* Register the object as being in progress of encoding. In
OpenStep-style archiving, this method also calls
-_coderInternalCreateReferenceForObject:. */
[self _objectWillBeInProgress: anObj];
/* Encode the object. */
[self encodeTag: CODER_OBJECT];
[self encodeIndent];
if (bycopy_flag)
[self _doEncodeBycopyObject:anObj];
else if (byref_flag)
[self _doEncodeByrefObject:anObj];
else
[self _doEncodeObject:anObj];
[self encodeUnindent];
/* Find out if this object satisfies any forward references,
and encode either the forward reference number, or a
zero. NOTE: This test is here, and not before the
_doEncode.., because the encoding of this object may,
itself, generate a "forward reference" to this object,
(ala the in_progress_table). That is, we cannot know
whether this object satisfies a forward reference until
after it has been encoded. */
fref = [self _coderForwardReferenceForObject: anObj];
if (fref)
{
/* It does satisfy a forward reference; write the forward
reference number, so the decoder can know. */
[self encodeValueOfCType: @encode(unsigned)
at: &fref
withName: @"Object forward cross-reference number"];
/* Remove it from the forward reference table, since we'll never
have another forward reference for this object. */
[self _coderRemoveForwardReferenceForObject: anObj];
}
else
{
/* It does not satisfy any forward references. Let the
decoder know this by encoding NULL. Note: in future
encoding we may have backward references to this
object, but we will never need forward references to
this object. */
unsigned null_fref = 0;
[self encodeValueOfCType: @encode(unsigned)
at: &null_fref
withName: @"Object forward cross-reference number"];
}
/* We're done encoding the object, it's no longer in progress.
In GNU-style archiving, this method also calls
-_coderInternalCreateReferenceForObject:. */
[self _objectNoLongerInProgress: anObj];
}
}
[self encodeUnindent];
}
- (void) encodeObject: anObj
withName: (NSString*)name
{
[self _encodeObject:anObj
withName:name
isBycopy:NO
isByref:NO
isForwardReference:NO];
}
- (void) encodeBycopyObject: anObj
withName: (NSString*)name
{
[self _encodeObject:anObj
withName:name
isBycopy:YES
isByref:NO
isForwardReference:NO];
}
- (void) encodeByrefObject: anObj
withName: (NSString*)name
{
[self _encodeObject:anObj
withName:name
isBycopy:NO
isByref:YES
isForwardReference:NO];
}
- (void) encodeObjectReference: anObj
withName: (NSString*)name
{
[self _encodeObject:anObj
withName:name
isBycopy:NO
isByref:NO
isForwardReference:YES];
}
- (void) encodeWithName: (NSString*)name
valuesOfObjCTypes: (const char *)types, ...
{
va_list ap;
[self encodeName:name];
va_start(ap, types);
while (*types)
{
[self encodeValueOfObjCType:types
at:va_arg(ap, void*)
withName:@"Encoded Types Component"];
types = objc_skip_typespec(types);
}
va_end(ap);
}
- (void) encodeValueOfObjCTypes: (const char *)types
at: (const void *)d
withName: (NSString*)name
{
[self encodeName:name];
while (*types)
{
[self encodeValueOfObjCType:types
at:d
withName:@"Encoded Types Component"];
types = objc_skip_typespec(types);
}
}
- (void) encodeArrayOfObjCType: (const char *)type
count: (unsigned)c
at: (const void *)d
withName: (NSString*)name
{
int i;
int offset = objc_sizeof_type(type);
const char *where = d;
[self encodeName:name];
for (i = 0; i < c; i++)
{
[self encodeValueOfObjCType:type
at:where
withName:@"Encoded Array Component"];
where += offset;
}
}
- (void) encodeIndent
{
[cstream encodeIndent];
}
- (void) encodeUnindent
{
[cstream encodeUnindent];
}
- (void) encodeName: (NSString*)n
{
[cstream encodeName: n];
}
/* Substituting Classes */
- (NSString*) classNameEncodedForTrueClassName: (NSString*) trueName
{
[self notImplemented: _cmd];
return nil;
#if 0
if (classname_2_classname)
return NSMapGet (classname_2_classname, [trueName cString]);
return trueName;
#endif
}
- (void) encodeClassName: (NSString*) trueName
intoClassName: (NSString*) inArchiveName
{
[self notImplemented: _cmd];
#if 0
/* The table should hold char*'s, not id's. */
if (!classname_2_classname)
classname_2_classname =
NSCreateMapTable (NSObjectsMapKeyCallBacks,
NSObjectsMapValueCallBacks, 0);
NSMapInsert (classname_2_classname, trueName, inArchiveName);
#endif
}
- (void) dealloc
{
if (in_progress_table) NSFreeMapTable (in_progress_table);
if (object_2_xref) NSFreeMapTable (object_2_xref);
if (object_2_fref) NSFreeMapTable (object_2_fref);
if (const_ptr_2_xref) NSFreeMapTable (const_ptr_2_xref);
if (classname_2_classname) NSFreeMapTable (classname_2_classname);
[super dealloc];
}
@end

View file

@ -1,36 +0,0 @@
/* Protocol for GNU Objective C invocations
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: February 1996
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Enumerating_h__GNUSTEP_BASE_INCLUDE
#define __Enumerating_h__GNUSTEP_BASE_INCLUDE
#include <Foundation/NSObject.h>
@protocol Enumerating <NSObject>
- initWithCollection: aCollection;
- nextObject;
@end
#endif /* __Enumerating_h__GNUSTEP_BASE_INCLUDE */

View file

@ -1,38 +0,0 @@
/* Interface for Objective-C GapArray collection object
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Written by: Kresten Krab Thorup <krab@iesd.auc.dk>
Dept. of Mathematics and Computer Science, Aalborg U., Denmark
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __GapArray_h_GNUSTEP_BASE_INCLUDE
#define __GapArray_h_GNUSTEP_BASE_INCLUDE
#include <base/Array.h>
@interface GapArray : Array
{
@public
unsigned _gap_start; /* start of gap */
unsigned _gap_size; /* size of gap */
}
@end
#endif /* __GapArray_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,144 +0,0 @@
/* Implementation for Objective-C GapArray collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Kresten Krab Thorup <krab@iesd.auc.dk>
Dept. of Mathematics and Computer Science, Aalborg U., Denmark
Overhauled by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/GapArray.h>
#include <base/GapArrayPrivate.h>
@implementation GapArray
/* This is the designated initializer of this class */
/* Override designated initializer of superclass */
- initWithCapacity: (unsigned)aCapacity
{
[super initWithCapacity: aCapacity];
_gap_start = 0;
_gap_size = aCapacity;
return self;
}
/* Archiving must mimic the above designated initializer */
- (void) encodeWithCoder: anEncoder
{
[self notImplemented:_cmd];
}
+ newWithCoder: aDecoder
{
[self notImplemented:_cmd];
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
GapArray *copy = [super emptyCopy];
copy->_gap_start = 0;
copy->_gap_size = copy->_capacity;
return copy;
}
- (void) empty
{
[super empty];
_gap_start = 0;
_gap_size = _capacity;
}
- (void) setCapacity: (unsigned)newCapacity
{
if (newCapacity > _count)
{
gapMoveGapTo (self, _capacity-_gap_size); /* move gap to end */
[super setCapacity: newCapacity]; /* resize */
_gap_size = _capacity - _gap_start;
}
}
- (void) removeObjectAtIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count);
[_contents_array[GAP_TO_BASIC (index)] release];
gapFillHoleAt (self, index);
decrementCount(self);
}
- objectAtIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count);
return _contents_array[GAP_TO_BASIC(index)];
}
- (void) appendObject: newObject
{
incrementCount(self);
[newObject retain];
gapMakeHoleAt (self, _count-1);
_contents_array[_count-1] = newObject;
}
- (void) prependObject: newObject
{
incrementCount(self);
[newObject retain];
gapMakeHoleAt (self, 0);
_contents_array[0] = newObject;
}
- (void) insertObject: newObject atIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count+1);
incrementCount(self);
[newObject retain];
gapMakeHoleAt (self, index);
_contents_array[index] = newObject;
}
- (void) replaceObjectAtIndex: (unsigned)index withObject: newObject
{
CHECK_INDEX_RANGE_ERROR(index, _count);
[newObject retain];
[_contents_array[GAP_TO_BASIC(index)] release];
_contents_array[GAP_TO_BASIC(index)] = newObject;
}
- (void) swapAtIndeces: (unsigned)index1 : (unsigned)index2
{
id tmp;
CHECK_INDEX_RANGE_ERROR(index1, _count);
CHECK_INDEX_RANGE_ERROR(index2, _count);
index1 = GAP_TO_BASIC(index1);
index2 = GAP_TO_BASIC(index2);
tmp = _contents_array[index1];
_contents_array[index1] = _contents_array[index2];
_contents_array[index2] = tmp;
}
@end

View file

@ -1,88 +0,0 @@
/* GapArray definitions for the use of subclass implementations
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
Copyright (C) 1993,1994 Kresten Krab Thorup <krab@iesd.auc.dk>
Dept. of Mathematics and Computer Science, Aalborg U., Denmark
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __GapArrayPrivate_h_GNUSTEP_BASE_INCLUDE
#define __GapArrayPrivate_h_GNUSTEP_BASE_INCLUDE
#include <base/ArrayPrivate.h>
#include <assert.h>
#define GAP_TO_BASIC(INDEX) \
({ unsigned int __idx = (INDEX); \
__idx >= self->_gap_start \
? __idx+self->_gap_size : __idx; })
#define BASIC_TO_GAP(INDEX) \
({ unsigned int __idx = (INDEX); \
__idx < self->_gap_start \
? __idx : __idx-self->_gap_size; })
static inline void
gapMoveGapTo (GapArray* self, unsigned index)
{
int i;
assert (index <= self->_capacity);
if (index < self->_gap_start)
{
#ifndef STABLE_MEMCPY
int b = index + self->_gap_size;
for (i = self->_gap_start + self->_gap_size - 1; i >= b; i--)
self->_contents_array[i] = self->_contents_array[i - self->_gap_size];
#else
memcpy (self->_contents_array + index + self->_gap_size,
self->_contents_array + index,
self->_gap_start - index)
#endif
}
else
{
#ifndef STABLE_MEMCPY
for(i = self->_gap_start; i != index; i++)
self->_contents_array[i] = self->_contents_array[i + self->_gap_size];
#else
memcpy (self->_contents_array + self->_gap_start,
self->_contents_array + self->_gap_start + self->_gap_size,
index - self->_gap_start);
#endif
}
self->_gap_start = index;
}
static inline void
gapMakeHoleAt(GapArray *self, unsigned index)
{
gapMoveGapTo (self, index);
self->_gap_start += 1;
self->_gap_size -= 1;
}
static inline void
gapFillHoleAt(GapArray *self, unsigned index)
{
gapMoveGapTo (self, index);
self->_gap_size += 1;
}
#endif /* __GapArrayPrivate_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,36 +0,0 @@
/* Interface for Objective-C Heap collection object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Heap_h_GNUSTEP_BASE_INCLUDE
#define __Heap_h_GNUSTEP_BASE_INCLUDE
#include <base/Array.h>
@interface Heap : Array
- (void) heapifyFromIndex: (unsigned)index;
- (void) heapify;
@end
#endif /* __Heap_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,102 +0,0 @@
/* Implementation for Objective-C Heap object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/* This class could be improved by somehow making is a subclass of
IndexedCollection, but not OrderedCollection. */
#include <config.h>
#include <base/Heap.h>
#include <base/ArrayPrivate.h>
#define HEAP_PARENT(i) (i/2)
#define HEAP_LEFT(i) (2 * i)
#define HEAP_RIGHT(i) ((2 * i) + 1)
@implementation Heap
/* We could take out the recursive call to make it a little more efficient */
- (void) heapifyFromIndex: (unsigned)index
{
unsigned right, left, largest;
id tmp;
right = HEAP_RIGHT(index);
left = HEAP_LEFT(index);
if (left < _count
&& [_contents_array[index] compare: _contents_array[left]] > 0)
largest = left;
else
largest = index;
if (right < _count
&& [_contents_array[largest] compare: _contents_array[right]] > 0)
largest = right;
if (largest != index)
{
tmp = _contents_array[index];
_contents_array[index] = _contents_array[largest];
_contents_array[largest] = tmp;
[self heapifyFromIndex:largest];
}
}
- (void) heapify
{
int i;
// could use objc_msg_lookup here;
for (i = _count / 2; i >= 1; i--)
[self heapifyFromIndex:i];
}
- (void) removeFirstObject
{
if (_count == 0)
return;
[_contents_array[0] release];
_contents_array[0] = _contents_array[_count-1];
decrementCount(self);
[self heapifyFromIndex:0];
}
- (void) addObject: newObject
{
int i;
incrementCount(self);
[newObject retain];
for (i = _count-1;
i > 0
&& [newObject compare: _contents_array[HEAP_PARENT(i)]] < 0;
i = HEAP_PARENT(i))
{
_contents_array[i] = _contents_array[HEAP_PARENT(i)];
}
_contents_array[i] = newObject;
}
- (id) minObject
{
return [self firstObject];
}
@end

View file

@ -1,132 +0,0 @@
/* Protocol for Objective-C objects that hold elements accessible by index
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/* The <IndexedCollecting> protocol inherits from the
<KeyedCollecting> protocol.
The <IndexedCollecting> protocol defines the interface to a
collection of elements that are accessible by a key that is an index,
where the indeces in a collection are a contiguous series of unsigned
integers beginning at 0. This is the root of the protocol heirarchy
for all collections that hold their elements in some order. Elements
may be accessed, inserted, replaced and removed by their index.
*/
#ifndef __IndexedCollecting_h_GNUSTEP_BASE_INCLUDE
#define __IndexedCollecting_h_GNUSTEP_BASE_INCLUDE
#include <base/Collecting.h>
#include <Foundation/NSRange.h>
#define IndexRange NSRange
#define IndexRangeInside(RANGE1,RANGE2) \
({IndexRange __a=(RANGE1), __b=(RANGE2); \
__a.start<=__b.start && __a.end>=__b.end;})
@protocol ConstantIndexedCollecting <ConstantCollecting>
// GETTING MEMBERS BY INDEX;
- objectAtIndex: (unsigned)index;
- firstObject;
- lastObject;
// GETTING MEMBERS BY NEIGHBOR;
- successorOfObject: anObject;
- predecessorOfObject: anObject;
// GETTING INDICES BY MEMBER;
- (unsigned) indexOfObject: anObject;
- (unsigned) indexOfObject: anObject inRange: (IndexRange)aRange;
// TESTING;
- (BOOL) contentsEqualInOrder: (id <ConstantIndexedCollecting>)aColl;
- (int) compareInOrderContentsOf: (id <Collecting>)aCollection;
- (unsigned) indexOfFirstDifference: (id <ConstantIndexedCollecting>)aColl;
- (unsigned) indexOfFirstIn: (id <ConstantCollecting>)aColl;
- (unsigned) indexOfFirstNotIn: (id <ConstantCollecting>)aColl;
// ENUMERATING;
- (id <Enumerating>) reverseObjectEnumerator;
- (void) withObjectsInRange: (IndexRange)aRange
invoke: (id <Invoking>)anInvocation;
- (void) withObjectsInReverseInvoke: (id <Invoking>)anInvocation;
- (void) withObjectsInReverseInvoke: (id <Invoking>)anInvocation
whileTrue:(BOOL *)flag;
- (void) makeObjectsPerformInReverse: (SEL)aSel;
- (void) makeObjectsPerformInReverse: (SEL)aSel withObject: argObject;
// LOW-LEVEL ENUMERATING;
- prevObjectWithEnumState: (void**)enumState;
@end
@protocol IndexedCollecting <ConstantIndexedCollecting, Collecting>
// REPLACING;
- (void) replaceObjectAtIndex: (unsigned)index with: newObject;
// REMOVING;
- (void) removeObjectAtIndex: (unsigned)index;
- (void) removeFirstObject;
- (void) removeLastObject;
- (void) removeRange: (IndexRange)aRange;
// SORTING;
- (void) sortContents;
- (void) sortAddObject: newObject;
@end
#define NO_INDEX NSNotFound
/* xxx Fix this comment: */
/* Most methods in the KeyedCollecting protocol that mention a key are
duplicated in the IndexedCollecting protocol, with their names
modified to reflect that the "key" now must be an unsigned integer,
(an "index"). The programmer should be able to use either of the
corresponding method names to the same effect.
The new methods are provided in the IndexedCollecting protocol for:
1) Better type checking for when an unsigned int is required.
2) More intuitive method names.
IndexedCollecting KeyedCollecting
----------------------------------------------------------------------
insertObject:atIndex insertObject:atKey:
replaceObjectAtIndex:with: replaceObjectAtKey:with:
removeObjectAtIndex: removeObjectAtKey:
objectAtIndex: objectAtKey:
includesIndex: includesKey:
insertElement:atIndex insertElement:atKey:
replaceElementAtIndex:with: replaceElementAtKey:with:
removeElementAtIndex: removeElementAtKey:
elementAtIndex: elementAtKey:
*/
#endif /* __IndexedCollecting_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,110 +0,0 @@
/* Interface for Objective-C Sequential Collection object.
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __IndexedCollection_h_GNUSTEP_BASE_INCLUDE
#define __IndexedCollection_h_GNUSTEP_BASE_INCLUDE
#include <base/KeyedCollection.h>
#include <base/IndexedCollecting.h>
@interface ConstantIndexedCollection : ConstantCollection
@end
@interface IndexedCollection : ConstantIndexedCollection
@end
@interface ReverseEnumerator : Enumerator
@end
/* Put this on category instead of class to avoid bogus complaint from gcc */
@interface ConstantIndexedCollection (Protocol) <ConstantIndexedCollecting>
@end
@interface IndexedCollection (Protocol) <IndexedCollecting>
@end
#define FOR_INDEXED_COLLECTION(ACOLL, ELT) \
{ \
void *_es = [ACOLL newEnumState]; \
while ((ELT = [ACOLL nextObjectWithEnumState: &_es])) \
{
#define END_FOR_INDEXED_COLLECTION(ACOLL) \
} \
[ACOLL freeEnumState: &_es]; \
}
#define FOR_INDEXED_COLLECTION_REVERSE(ACOLL, ELT) \
{ \
void *_es = [ACOLL newEnumState]; \
while ((ELT = [ACOLL prevObjectWithEnumState: &_es])) \
{
#define END_FOR_INDEXED_COLLECTION_REVERSE(ACOLL) \
} \
[ACOLL freeEnumState: &_es]; \
}
#define FOR_INDEXED_COLLECTION_WHILE_TRUE(ACOLL, ELT, FLAG) \
{ \
void *_es = [ACOLL newEnumState]; \
while (FLAG && (ELT = [ACOLL nextObjectWithEnumState: &_es])) \
{
#define END_FOR_INDEXED_COLLECTION_WHILE_TRUE(ACOLL) \
} \
[ACOLL freeEnumState: &_es]; \
}
/* The only subclassResponsibilities in IndexedCollection are:
insertElement:atIndex:
removeElementAtIndex:
elementAtIndex:
but subclass will want to override others as well in order to
increase efficiency. The following are especially important if
the subclass's implementation of "elementAtIndex:" is not efficient:
replaceElementAtIndex:with:
swapAtIndeces::
shallowCopyReplaceFrom:to:with:
sortAddElement:byCalling:
removeElement:
firstElement
lastElement
shallowCopyFrom:to:
withElementsCall:whileTrue:
withElementsInReverseCall:whileTrue:
and perhaps:
appendElement:
prependElement:
indexOfElement:
withElementsInReverseCall:
*/
#endif /* __IndexedCollection_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,466 +0,0 @@
/* Implementation for Objective-C IndexedCollection object
Copyright (C) 1993,1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/IndexedCollection.h>
#include <base/IndexedCollectionPrivate.h>
#include <stdio.h>
#include <base/Array.h>
#include <base/NSString.h>
#include <base/behavior.h>
@implementation ReverseEnumerator
- nextObject
{
return [collection prevObjectWithEnumState: &enum_state];
}
@end
@implementation ConstantIndexedCollection
// GETTING MEMBERS BY INDEX;
- objectAtIndex: (unsigned)index
{
[self subclassResponsibility: _cmd];
return nil;
}
- firstObject
{
if ([self isEmpty])
return nil;
return [self objectAtIndex: 0];
}
- lastObject
{
if ([self isEmpty])
return nil;
return [self objectAtIndex: [self count]-1];
}
// GETTING MEMBERS BY NEIGHBOR;
/* Should be overriden by linked-list-type classes */
- successorOfObject: anObject
{
int last = [self count] - 1;
int index = [self indexOfObject: anObject];
if (index == last)
return nil;
return [self objectAtIndex: index+1];
}
/* Should be overriden by linked-list-type classes */
- predecessorOfObject: anObject
{
int index = [self indexOfObject: anObject];
if (index == 0)
return nil;
return [self objectAtIndex: index-1];
}
// GETTING INDICES BY MEMBER;
- (unsigned) indexOfObject: anObject
{
int i, count = [self count];
for (i = 0; i < count; i++)
if ([anObject isEqual: [self objectAtIndex:i]])
return i;
return NO_INDEX;
}
- (unsigned) indexOfObject: anObject inRange: (IndexRange)aRange
{
int i;
/* xxx check that aRange is within count */
for (i = aRange.location; i < aRange.location+aRange.length; i++)
if ([anObject isEqual: [self objectAtIndex:i]])
return i - aRange.location;
return NO_INDEX;
}
// TESTING;
- (BOOL) contentsEqualInOrder: (id <ConstantIndexedCollecting>)aColl
{
id o1, o2;
void *s1, *s2;
if ([self count] != [aColl count])
return NO;
s1 = [self newEnumState];
s2 = [aColl newEnumState];
while ((o1 = [self nextObjectWithEnumState:&s1])
&& (o2 = [aColl nextObjectWithEnumState:&s2]))
{
if (![o1 isEqual: o2])
{
[self freeEnumState:&s1];
[aColl freeEnumState:&s2];
return NO;
}
}
[self freeEnumState:&s1];
[aColl freeEnumState:&s2];
return YES;
}
- (int) compareInOrderContentsOf: (id <Collecting>)aCollection
{
void *es1 = [self newEnumState];
void *es2 = [aCollection newEnumState];
id o1, o2;
int comparison;
while ((o1 = [self nextObjectWithEnumState:&es1])
&& (o2 = [aCollection nextObjectWithEnumState:&es2]))
{
if ((comparison = [o1 compare: o2]))
{
[self freeEnumState:&es1];
[aCollection freeEnumState:&es2];
return comparison;
}
}
if ((comparison = ([self count] - [aCollection count])))
return comparison;
return 0;
}
- (unsigned) indexOfFirstDifference: (id <ConstantIndexedCollecting>)aColl
{
unsigned i = 0;
BOOL flag = YES;
void *enumState = [self newEnumState];
id o1, o2;
FOR_INDEXED_COLLECTION_WHILE_TRUE(self, o1, flag)
{
if ((!(o2 = [self nextObjectWithEnumState: &enumState]))
|| [o1 isEqual: o2])
flag = NO;
else
i++;
}
END_FOR_INDEXED_COLLECTION_WHILE_TRUE(self);
[self freeEnumState: &enumState];
return i;
}
/* Could be more efficient */
- (unsigned) indexOfFirstIn: (id <ConstantCollecting>)aCollection
{
unsigned index = 0;
BOOL flag = YES;
id o;
FOR_INDEXED_COLLECTION_WHILE_TRUE(self, o, flag)
{
if ([aCollection containsObject: o])
flag = NO;
else
index++;
}
END_FOR_INDEXED_COLLECTION(self);
return index;
}
/* Could be more efficient */
- (unsigned) indexOfFirstNotIn: (id <ConstantCollecting>)aCollection
{
unsigned index = 0;
BOOL flag = YES;
id o;
FOR_INDEXED_COLLECTION_WHILE_TRUE(self, o, flag)
{
if (![aCollection containsObject: o])
flag = NO;
else
index++;
}
END_FOR_INDEXED_COLLECTION(self);
return index;
}
// ENUMERATING;
- (id <Enumerating>) reverseObjectEnumerator
{
return [[[ReverseEnumerator alloc] initWithCollection: self]
autorelease];
}
- (void) withObjectsInRange: (IndexRange)aRange
invoke: (id <Invoking>)anInvocation
{
int i;
for (i = aRange.location; i < aRange.location + aRange.length; i++)
[anInvocation invokeWithObject: [self objectAtIndex: i]];
}
- (void) withObjectsInReverseInvoke: (id <Invoking>)anInvocation
{
int i, count = [self count];
for (i = count-1; i >= 0; i--)
[anInvocation invokeWithObject: [self objectAtIndex: i]];
}
- (void) withObjectsInReverseInvoke: (id <Invoking>)anInvocation
whileTrue:(BOOL *)flag
{
int i, count = [self count];
for (i = count-1; *flag && i >= 0; i--)
[anInvocation invokeWithObject: [self objectAtIndex: i]];
}
- (void) makeObjectsPerformInReverse: (SEL)aSel
{
id o;
FOR_INDEXED_COLLECTION_REVERSE(self, o)
{
[o performSelector: aSel];
}
END_FOR_INDEXED_COLLECTION_REVERSE(self);
}
- (void) makeObjectsPerformInReverse: (SEL)aSel withObject: argObject
{
id o;
FOR_INDEXED_COLLECTION_REVERSE(self, o)
{
[o performSelector: aSel withObject: argObject];
}
END_FOR_INDEXED_COLLECTION_REVERSE(self);
}
// LOW-LEVEL ENUMERATING;
- prevObjectWithEnumState: (void**)enumState
{
/* *(int*)enumState is the index of the element that was returned
last time -prevObjectWithEnumState: or -nextObjectWithEnumState
was called. In -newEnumState, *(int*)enumState is initialized to
-2; The implementation of -newEnumState can be found below. */
/* If there are not objects in this collection, or we are being
asked for the object before the first object, return nil. */
if ([self isEmpty] || ((*(int*)enumState) == 0)
|| ((*(int*)enumState) == -1))
{
(*(int*)enumState) = -1;
return NO_OBJECT;
}
if (*(int*)enumState == -2)
/* enumState was just initialized by -newEnumState, start
at the end of the sequence. */
*(int*)enumState = [self count]-1;
else
/* ...otherwise go the previous index. */
(*(int*)enumState)--;
return [self objectAtIndex:(*(unsigned*)enumState)];
}
// COPYING;
- shallowCopyRange: (IndexRange)aRange
{
[self notImplemented: _cmd];
return nil;
}
- shallowCopyInReverse
{
[self notImplemented: _cmd];
return nil;
}
- shallowCopyInReverseRange: (IndexRange)aRange
{
[self notImplemented: _cmd];
return nil;
}
// OVERRIDE SOME COLLECTION METHODS;
- (void*) newEnumState
{
return (void*) -2;
}
- nextObjectWithEnumState: (void**)enumState
{
/* *(int*)enumState is the index of the element that was returned
last time -prevObjectWithEnumState: or -nextObjectWithEnumState
was called. In -newEnumState, *(int*)enumState is initialized to
-2. */
/* If there are not objects in this collection, or we are being
asked for the object after the last object, return nil. */
if ([self isEmpty] || ((*(int*)enumState) >= (int)([self count]-1)))
{
(*(int*)enumState) = [self count];
return NO_OBJECT;
}
if (*(int*)enumState == -2)
/* enumState was just initialized by -newEnumState, start
at the beginning of the sequence. */
*(int*)enumState = 0;
else
/* ...otherwise go the next index. */
(*(int*)enumState)++;
return [self objectAtIndex:(*(unsigned*)enumState)];
}
/* is this what we want? */
- (BOOL) isEqual: anObject
{
if (self == anObject)
return YES;
if ([anObject class] == [self class]
&& [self count] != [anObject count]
&& [self contentsEqualInOrder: anObject] )
return YES;
else
return NO;
}
@end
@implementation IndexedCollection
+ (void) initialize
{
if (self == [IndexedCollection class])
class_add_behavior(self, [Collection class]);
}
// REPLACING;
- (void) replaceObjectAtIndex: (unsigned)index withObject: newObject
{
[self subclassResponsibility: _cmd];
}
// REMOVING;
- (void) removeObjectAtIndex: (unsigned)index
{
[self subclassResponsibility: _cmd];
}
- (void) removeFirstObject
{
[self removeObjectAtIndex: 0];
}
- (void) removeLastObject
{
[self removeObjectAtIndex: [self count]-1];
}
- (void) removeRange: (IndexRange)aRange
{
int count = aRange.length;
CHECK_INDEX_RANGE_ERROR(aRange.location, [self count]);
CHECK_INDEX_RANGE_ERROR(aRange.location+aRange.length-1, [self count]);
while (count--)
[self removeObjectAtIndex: aRange.location];
}
// SORTING;
- (void) sortContents
{
[self notImplemented: _cmd];
}
- (void) sortAddObject: newObject
{
[self notImplemented: _cmd];
}
// OVERRIDE SOME COLLECTION METHODS;
- (void) removeObject: anObject
{
unsigned index;
/* Retain the object. Yuck, but necessary in case the array holds
the last reference to anObject. */
/* xxx Is there an alternative to this expensive retain/release? */
[anObject retain];
for (index = [self indexOfObject: anObject];
index != NO_INDEX;
index = [self indexOfObject: anObject])
[self removeObjectAtIndex: index];
[anObject release];
}
- (void) replaceObject: oldObject withObject: newObject
{
unsigned index;
/* Retain the object. Yuck, but necessary in case the array holds
the last reference to anObject. */
/* xxx Is there an alternative to this expensive retain/release? */
[oldObject retain];
for (index = [self indexOfObject: oldObject];
index != NO_INDEX;
index = [self indexOfObject: oldObject])
[self replaceObjectAtIndex: index withObject: newObject];
[oldObject release];
}
@end

View file

@ -1,40 +0,0 @@
/* IndexedCollection definitions for the use of subclass implementations only
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __IndexedCollectionPrivate_h_GNUSTEP_BASE_INCLUDE
#define __IndexedCollectionPrivate_h_GNUSTEP_BASE_INCLUDE
#include <base/CollectionPrivate.h>
#include <Foundation/NSException.h>
#include <Foundation/NSString.h>
/* To be used inside a method for making sure that index
is not above range.
*/
#define CHECK_INDEX_RANGE_ERROR(INDEX, OVER) \
if (INDEX >= OVER) \
[NSException raise: NSRangeException \
format: @"in %s, index %d is out of range", \
sel_get_name (_cmd), INDEX]
#endif /* __IndexedCollectionPrivate_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,38 +0,0 @@
/* Protocol for GNU Objective-C objects that understand an invalidation msg
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __InvalidationListening_h_GNUSTEP_BASE_INCLUDE
#define __InvalidationListening_h_GNUSTEP_BASE_INCLUDE
#include <Foundation/NSObject.h>
/* This protocol is just temporary. It will disappear when GNU writes
a more general notification system.
It is not recommended that you use it in your code. */
@protocol InvalidationListening
- senderIsInvalid: sender;
@end
#endif /* __InvalidationListening_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,98 +0,0 @@
#ifndef __Invocation_h_GNUSTEP_BASE_INCLUDE
#define __Invocation_h_GNUSTEP_BASE_INCLUDE
/*
Use these for notifications!
Don't forget to make these archivable / transportable.
WARNING: All the (char*) type arguments and return values may
extraneous stuff after the first type.
*/
#include <base/Collection.h>
#include <base/Invoking.h>
@interface Invocation : NSObject <Invoking>
{
char *return_type; /* may actually contain full argframe type */
unsigned return_size;
void *return_value;
}
- initWithReturnType: (const char *)encoding;
- (const char *) returnType;
- (unsigned) returnSize;
- (void) getReturnValue: (void*) addr;
@end
@interface ArgframeInvocation : Invocation
{
arglist_t argframe;
BOOL args_retained;
/* Use return_type to hold full argframe type. */
}
- initWithArgframe: (arglist_t)frame type: (const char *)e;
- initWithType: (const char *)e;
- (void) retainArguments;
- (BOOL) argumentsRetained;
- (const char *) argumentTypeAtIndex: (unsigned)i;
- (unsigned) argumentSizeAtIndex: (unsigned)i;
- (void) getArgument: (void*)addr atIndex: (unsigned)i;
- (void) setArgumentAtIndex: (unsigned)i
toValueAt: (const void*)addr;
@end
@interface MethodInvocation : ArgframeInvocation
{
id *target_pointer;
SEL *sel_pointer;
}
- initWithArgframe: (arglist_t)frame selector: (SEL)s;
- initWithSelector: (SEL)s;
- initWithTarget: target selector: (SEL)s, ...;
- (void) invokeWithTarget: t;
- (SEL) selector;
- (void) setSelector: (SEL)s;
- target;
- (void) setTarget: t;
@end
/* Same as MethodInvocation, except that when sent
[ -invokeWithObject: anObj], anObj does not become the target
for the invocation's selector, it becomes the first object
argument of the selector. */
@interface ObjectMethodInvocation : MethodInvocation
{
id *arg_object_pointer;
}
@end
@interface VoidFunctionInvocation : Invocation
{
void (*function)();
}
- initWithVoidFunction: (void(*)())f;
@end
@interface ObjectFunctionInvocation : Invocation
{
id (*function)(id);
}
- initWithObjectFunction: (id(*)(id))f;
@end
#if 0
@interface FunctionInvocation : ArgframeInvocation
{
void (*function)();
}
- initWithFunction: (void(*)())f
argframe: (arglist_t)frame type: (const char *)e;
- initWithFunction: (void(*)())f;
@end
#endif
#endif /* __Invocation_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,861 +0,0 @@
/* Implementation for Objective-C Invocation object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <mframe.h>
#include <base/preface.h>
#include <base/Invocation.h>
#include <Foundation/DistributedObjects.h>
#include <Foundation/NSValue.h>
#include <Foundation/NSString.h>
#include <Foundation/NSConnection.h>
#include <Foundation/NSException.h>
extern BOOL sel_types_match(const char* t1, const char* t2);
/* xxx We are currently retaining the return value.
We shouldn't always do this. Make is an option. */
/* Deal with strrchr: */
#if STDC_HEADERS || HAVE_STRING_H
#include <string.h>
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
#if !STDC_HEADERS && HAVE_MEMORY_H
#include <memory.h>
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
#define rindex strrchr
#define bcopy(s, d, n) memcpy ((d), (s), (n))
#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
#define bzero(s, n) memset ((s), 0, (n))
#else /* not STDC_HEADERS and not HAVE_STRING_H */
#include <strings.h>
/* memory.h and strings.h conflict on some systems. */
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
/* xxx Perhaps make this an ivar. */
#define return_retained 0
@implementation Invocation
- initWithReturnType: (const char *)enc
{
int l = strlen(enc);
OBJC_MALLOC(return_type, char, l + 1);
memcpy(return_type, enc, l);
return_type[l] = '\0';
enc = objc_skip_type_qualifiers (return_type);
if (*enc != 'v')
{
/* Work around bug in objc_sizeof_type; it doesn't handle void type */
return_size = objc_sizeof_type (enc);
return_value = objc_calloc (1, return_size);
}
else
{
return_size = 0;
return_value = NULL;
}
return self;
}
- (void) encodeWithCoder: (id <Encoding>)coder
{
[super encodeWithCoder: coder];
[coder encodeValueOfCType: @encode(char*)
at: &return_type
withName: @"Invocation return type"];
[coder encodeValueOfCType: @encode(unsigned)
at: &return_size
withName: @"Invocation return size"];
if (return_size)
[coder encodeValueOfObjCType: return_type
at: return_value
withName: @"Invocation return value"];
}
- initWithCoder: (id <Decoding>)coder
{
self = [super initWithCoder: coder];
[coder decodeValueOfCType: @encode(char*)
at: &return_type
withName: NULL];
[coder decodeValueOfCType: @encode(unsigned)
at: &return_size
withName: NULL];
if (return_size)
{
return_value = objc_malloc (return_size);
[coder decodeValueOfObjCType: return_type
at: return_value
withName: NULL];
}
else
return_value = 0;
return self;
}
- (Class) classForConnectedCoder: coder
{
/* Make sure that Connection's always send us bycopy,
i.e. as our own class, not a Proxy class. */
return [self class];
}
/* Next two methods for OPENSTEP */
- (Class) classForPortCoder
{
return [self class];
}
- replacementObjectForPortCoder: coder
{
return self;
}
- (void) invoke
{
[self subclassResponsibility:_cmd];
}
- (void) invokeWithObject: anObj
{
[self subclassResponsibility:_cmd];
}
- (const char *) returnType
{
return return_type;
}
- (unsigned) returnSize
{
return return_size;
}
- (void) getReturnValue: (void *)addr
{
if (return_value)
memcpy (addr, return_value, return_size);
/* xxx what if it hasn't been invoked yet, and there isn't
a return value yet. */
}
- (void) setReturnValue: (void*)addr
{
if (return_value)
{
if (return_retained && *return_type == _C_ID)
{
[*(id*)return_value release];
*(id*)return_value = *(id*)addr;
[*(id*)return_value retain];
}
else
memcpy (return_value, addr, return_size);
}
}
- objectReturnValue
{
switch (*return_type)
{
#define CASE_RETURN(C,T,S) \
case C: return [NSNumber numberWith ## S: *(T*)return_value]
CASE_RETURN (_C_LNG, long, Long);
CASE_RETURN (_C_ULNG, unsigned long, UnsignedLong);
CASE_RETURN (_C_INT, int, Int);
CASE_RETURN (_C_UINT, unsigned int, UnsignedInt);
CASE_RETURN (_C_SHT, short, Short);
CASE_RETURN (_C_USHT, unsigned short, UnsignedShort);
CASE_RETURN (_C_CHR, char, Char);
CASE_RETURN (_C_UCHR, unsigned char, UnsignedChar);
CASE_RETURN (_C_FLT, float, Float);
CASE_RETURN (_C_DBL, double, Double);
#undef CASE_RETURN
case _C_PTR:
return [NSNumber numberWithUnsignedLong: (long) *(void**)return_value];
case _C_CHARPTR:
return [NSString stringWithCString: *(char**)return_value];
case _C_ID:
return *(id*)return_value;
case 'v':
return nil;
default:
[self notImplemented: _cmd];
}
return 0;
[self notImplemented: _cmd];
return nil;
}
- (int) intReturnValue
{
switch (*return_type)
{
#define CASE_RETURN(_C,_T) case _C: return (int) *(_T*)return_value
CASE_RETURN (_C_LNG, long);
CASE_RETURN (_C_ULNG, unsigned long);
CASE_RETURN (_C_INT, int);
CASE_RETURN (_C_UINT, unsigned int);
CASE_RETURN (_C_SHT, short);
CASE_RETURN (_C_USHT, unsigned short);
CASE_RETURN (_C_CHR, char);
CASE_RETURN (_C_UCHR, unsigned char);
CASE_RETURN (_C_CHARPTR, char*);
CASE_RETURN (_C_FLT, float);
CASE_RETURN (_C_DBL, double);
CASE_RETURN (_C_PTR, void*);
#undef CASE_RETURN
case _C_ID:
return [*(id*)return_value intValue];
case 'v':
return 0;
default:
[self notImplemented: _cmd];
}
return 0;
}
- (BOOL) returnValueIsTrue
{
switch (return_size)
{
case sizeof(char):
return (*(char*)return_value != 0);
case sizeof(short):
return (*(short*)return_value != 0);
case sizeof(int):
return (*(int*)return_value != 0);
}
{
int i;
for (i = 0; i < return_size; i++)
if (*((char*)return_value + i) != 0)
return YES;
return NO;
}
}
- (void) dealloc
{
if (return_retained && *return_type == _C_ID)
[*(id*)return_value release];
OBJC_FREE(return_type);
[super dealloc];
}
@end
static int
types_get_size_of_stack_arguments(const char *types)
{
const char* type = objc_skip_typespec (types);
return atoi(type);
}
static int
types_get_size_of_register_arguments(const char *types)
{
const char* type = strrchr(types, '+');
if (type)
return atoi(++type) + sizeof(void*);
else
return 0;
}
/* To fix temporary bug in method_get_next_argument() on m68k */
static char*
my_method_get_next_argument (arglist_t argframe,
const char **type)
{
const char *t = objc_skip_argspec (*type);
if (*t == '\0')
return 0;
*type = t;
t = objc_skip_typespec (t);
if (*t == '+')
return argframe->arg_regs + atoi(++t);
else
/* xxx What's going on here? This -8 needed on my 68k NeXT box. */
#if m68k
return argframe->arg_ptr + (atoi(t) - 8);
#else
return argframe->arg_ptr + atoi(t);
#endif
}
@implementation ArgframeInvocation
- (void) _retainArguments
{
const char *tmptype;
void *datum;
tmptype = return_type;
while ((datum = my_method_get_next_argument (argframe, &tmptype)))
{
tmptype = objc_skip_type_qualifiers (tmptype);
if (*tmptype == _C_ID)
[*(id*)datum retain];
}
}
- (void) _initArgframeFrom: (arglist_t)frame
withType: (const char*)type
retainArgs: (BOOL)f
{
int stack_argsize, reg_argsize;
/* allocate the argframe */
stack_argsize = types_get_size_of_stack_arguments (type);
reg_argsize = types_get_size_of_register_arguments(type);
argframe = (arglist_t) objc_calloc (1 ,sizeof(char*) + reg_argsize);
if (stack_argsize)
argframe->arg_ptr = objc_calloc (1, stack_argsize);
else
argframe->arg_ptr = 0;
/* copy the frame into the argframe */
if (frame)
{
memcpy((char*)argframe + sizeof(char*),
(char*)frame + sizeof(char*),
reg_argsize);
memcpy(argframe->arg_ptr, frame->arg_ptr, stack_argsize);
if (f)
{
[self _retainArguments];
args_retained = YES;
}
}
}
/* This is the designated initializer. */
- initWithArgframe: (arglist_t)frame type: (const char *)type
{
/* xxx we are just using the return part. Does this matter? */
[super initWithReturnType: type];
[self _initArgframeFrom: frame withType: type retainArgs: NO];
return self;
}
- (void) encodeWithCoder: (id <Encoding>)coder
{
const char *tmptype;
void *datum;
[super encodeWithCoder: coder];
tmptype = return_type;
while ((datum = my_method_get_next_argument(argframe, &tmptype)))
{
[coder encodeValueOfObjCType: tmptype
at: datum
withName: @"Invocation Argframe argument"];
}
}
- initWithCoder: (id <Decoding>)coder
{
const char *tmptype;
void *datum;
self = [super initWithCoder: coder];
[self _initArgframeFrom: NULL withType: return_type retainArgs: NO];
tmptype = return_type;
while ((datum = my_method_get_next_argument(argframe, &tmptype)))
{
[coder decodeValueOfObjCType: tmptype
at: datum
withName: NULL];
}
return self;
}
- initWithType: (const char *)e
{
[self initWithArgframe:NULL type:e];
return self;
}
- (void) retainArguments
{
if (!args_retained)
{
if (argframe)
[self _retainArguments];
args_retained = YES;
}
}
- (BOOL) argumentsRetained
{
return args_retained;
}
- (const char *) argumentTypeAtIndex: (unsigned)i
{
const char *tmptype = return_type;
do
{
tmptype = objc_skip_argspec (tmptype);
}
while (i--);
return tmptype;
}
- (unsigned) argumentSizeAtIndex: (unsigned)i
{
return objc_sizeof_type ([self argumentTypeAtIndex:i]);
}
- (void) getArgument: (void*)addr atIndex: (unsigned)i
{
const char *tmptype = return_type;
void *datum;
do
datum = my_method_get_next_argument(argframe, &tmptype);
while (i-- && datum);
/* xxx Give error msg for null datum */
memcpy (addr, datum, objc_sizeof_type(tmptype));
}
- (void) setArgument:(const void *)addr atIndex: (unsigned)i
{
const char *tmptype = return_type;
void *datum;
do
datum = my_method_get_next_argument(argframe, &tmptype);
while (i--);
memcpy (datum, addr, objc_sizeof_type(tmptype));
}
- (void) setArgumentAtIndex: (unsigned)i
toValueAt: (const void*)addr
{
[self setArgument: addr atIndex: i];
}
- (void) _deallocArgframe
{
if (argframe)
{
if (argframe->arg_ptr)
objc_free (argframe->arg_ptr);
objc_free (argframe);
}
}
- (void) dealloc
{
void *datum;
const char *tmptype = return_type;
while ((datum = my_method_get_next_argument(argframe, &tmptype)))
{
tmptype = objc_skip_type_qualifiers (tmptype);
if (args_retained && *tmptype == _C_ID)
[*(id*)datum release];
}
[self _deallocArgframe];
[super dealloc];
}
#if 0
- resetArgframeWithReturnType: (const char*)encoding
{
[self _deallocArgframe];
[self _allocArgframe];
}
#endif
@end
@implementation MethodInvocation
- (void) _initTargetAndSelPointers
{
const char *tmptype = return_type;
target_pointer = (id*) my_method_get_next_argument (argframe, &tmptype);
sel_pointer = (SEL*) my_method_get_next_argument (argframe, &tmptype);
}
/* This is the designated initializer */
- initWithArgframe: (arglist_t)frame type: (const char*)t
{
[super initWithArgframe: frame type: t];
[self _initTargetAndSelPointers];
return self;
}
- initWithArgframe: (arglist_t)frame selector: (SEL)sel
{
const char *sel_type;
if (! (sel_type = sel_get_type (sel)) )
sel_type = sel_get_type ( sel_get_any_typed_uid (sel_get_name (sel)));
/* xxx Try harder to get this type by looking up the method in the target.
Hopefully the target can be found in the FRAME. */
if (!sel_type)
[NSException raise: @"SelectorWithoutType"
format: @"Couldn't find encoding type for selector %s.",
sel_get_name (sel)];
[self initWithArgframe: frame type: sel_type];
if (!frame)
*sel_pointer = sel;
return self;
}
- initWithCoder: (id <Decoding>)coder
{
self = [super initWithCoder: coder];
[self _initTargetAndSelPointers];
return self;
}
- initWithSelector: (SEL)s
{
[self initWithArgframe: NULL selector: s];
*sel_pointer = s;
return self;
}
- initWithTarget: target selector: (SEL)s, ...
{
const char *tmptype;
void *datum;
va_list ap;
[self initWithArgframe: NULL selector: s];
tmptype = return_type;
datum = my_method_get_next_argument(argframe, &tmptype);
if (args_retained)
[target retain];
*((id*)datum) = target;
datum = my_method_get_next_argument(argframe, &tmptype);
*((SEL*)datum) = s;
datum = my_method_get_next_argument(argframe, &tmptype);
va_start (ap, s);
while (datum)
{
#define CASE_TYPE(_C,_T) case _C: *(_T*)datum = va_arg (ap, _T); break
switch (*tmptype)
{
case _C_ID:
*(id*)datum = va_arg (ap, id);
if (args_retained)
[*(id*)datum retain];
break;
CASE_TYPE(_C_CLASS, Class);
CASE_TYPE(_C_SEL, SEL);
CASE_TYPE(_C_LNG, long);
CASE_TYPE(_C_ULNG, unsigned long);
CASE_TYPE(_C_INT, int);
CASE_TYPE(_C_UINT, unsigned int);
case _C_SHT:
*(short*)datum = (short)va_arg(ap, int);
break;
case _C_USHT:
*(unsigned short*)datum = (unsigned short)va_arg(ap, int);
break;
CASE_TYPE(_C_CHR, int);
case _C_UCHR:
*(unsigned char*)datum = (unsigned char)va_arg(ap, int);
break;
case _C_FLT:
*(float*)datum = (float)va_arg(ap, int);
break;
CASE_TYPE(_C_DBL, double);
CASE_TYPE(_C_CHARPTR, char*);
CASE_TYPE(_C_PTR, void*);
default:
{
int copysize;
copysize = objc_sizeof_type(tmptype);
memcpy(datum, (char *)va_arg(ap, int), copysize);
} /* default */
}
datum = my_method_get_next_argument (argframe, &tmptype);
}
return self;
}
- (void) invoke
{
void *ret;
IMP imp;
id target;
id cl;
SEL sel;
/* xxx This could be more efficient by using my_method_get_next_argument
instead of -target and -selector. Or, even better, caching the
memory offsets of the target and selector in the argframe. */
target = *target_pointer;
if (target == nil)
return;
cl = object_get_class (target);
sel = *sel_pointer;
/* xxx Perhaps we could speed things up by making this an ivar,
and caching it. */
imp = get_imp (cl, sel);
NSAssert(imp, NSInternalInconsistencyException);
ret = __builtin_apply((void(*)(void))imp,
argframe,
types_get_size_of_stack_arguments(return_type));
if (return_size)
{
if (*return_type == _C_ID)
{
id old = *(id*)return_value;
mframe_decode_return(return_type, return_value, ret);
if (return_retained && (*(id*)return_value != old))
{
[old release];
[*(id*)return_value retain];
}
}
else
{
mframe_decode_return(return_type, return_value, ret);
}
}
}
- (void) invokeWithTarget: t
{
[self setTarget: t];
[self invoke];
}
- (void) invokeWithObject: anObj
{
[self invokeWithTarget: anObj];
}
- (SEL) selector
{
return *sel_pointer;
}
- (void) setSelector: (SEL)s
{
SEL mysel = [self selector];
if (mysel == (SEL)0)
/* XXX Type check is needed! (masata-y@is.aist-nara.ac.jp) */
*sel_pointer = sel_get_any_typed_uid (sel_get_name (s));
else if (sel_types_match(sel_get_type(mysel), sel_get_type(s)))
*sel_pointer = s;
else
{
/* We need to reallocate the argframe */
[self notImplemented:_cmd];
}
}
- target
{
return *target_pointer;
}
- (void) setTarget: t
{
if (*target_pointer != t)
{
if (args_retained)
{
[*target_pointer release];
[t retain];
}
*target_pointer = t;
}
}
@end
@implementation ObjectMethodInvocation
- (void) _initArgObjectPointer
{
const char *tmptype;
void *datum;
tmptype = return_type;
my_method_get_next_argument (argframe, &tmptype);
my_method_get_next_argument (argframe, &tmptype);
do
{
datum = my_method_get_next_argument (argframe, &tmptype);
tmptype = objc_skip_type_qualifiers (tmptype);
}
while (datum && tmptype && *tmptype != _C_ID);
if (*tmptype != _C_ID)
[self error: "This method does not have an object argument."];
arg_object_pointer = (id*) datum;
}
- initWithArgframe: (arglist_t)frame selector: (SEL)sel
{
[super initWithArgframe: frame selector: sel];
[self _initArgObjectPointer];
return self;
}
- initWithCoder: (id <Decoding>)coder
{
self = [super initWithCoder: coder];
[self _initArgObjectPointer];
return self;
}
- (void) invokeWithObject: anObject
{
if (*arg_object_pointer != anObject)
{
if (args_retained)
{
[*arg_object_pointer release];
[anObject retain];
}
*arg_object_pointer = anObject;
}
[self invoke];
}
@end
@implementation VoidFunctionInvocation
#if 0
- initWithFunction: (void(*)())f
argframe: (arglist_t)frame type: (const char *)e
{
[super initWithArgframe: frame type: e];
function = f;
return self;
}
#endif
- initWithVoidFunction: (void(*)())f
{
[super initWithReturnType: "v"];
function = f;
return self;
}
/* Encode ourself as a proxies across Connection's; we can't encode
a function across the wire. */
- classForPortCoder
{
return [NSDistantObject class];
}
- (void) encodeWithCoder: (id <Encoding>)coder
{
[self shouldNotImplement: _cmd];
}
- (void) invoke
{
(*function) ();
}
- (void) invokeWithObject
{
[self shouldNotImplement: _cmd];
}
@end
@implementation ObjectFunctionInvocation
- initWithObjectFunction: (id(*)(id))f
{
[super initWithReturnType: "@"];
function = f;
return self;
}
/* Encode ourself as a proxies across Connection's; we can't encode
a function across the wire. */
- classForPortCoder
{
return [NSDistantObject class];
}
- (void) encodeWithCoder: (id <Encoding>)coder
{
[self shouldNotImplement: _cmd];
}
- (void) invoke
{
[self invokeWithObject: nil];
}
- (void) invokeWithObject: anObject
{
id r;
r = (*function) (anObject);
if (*(id*)return_value != r)
{
if (return_retained)
{
[*(id*)return_value release];
[r retain];
}
*(id*)return_value = r;
}
}
@end
/* Many other kinds of Invocations are possible:
SchemeInvocation, TclInvocation */
#if 0
@implementation CurriedInvocation
@end
What is this nonsense?
@interface StreamInvocation
@interface LogInvocation
@interface PrintingInvocation
{
Stream *stream;
char *format_string;
}
@end
#endif

View file

@ -1,42 +0,0 @@
/* Protocol for GNU Objective C invocations
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: February 1996
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Invoking_h__GNUSTEP_BASE_INCLUDE
#define __Invoking_h__GNUSTEP_BASE_INCLUDE
#include <Foundation/NSObject.h>
@protocol Invoking <NSObject>
- (void) invoke;
- (void) invokeWithObject: anObject;
- objectReturnValue;
- (int) intReturnValue;
- (BOOL) returnValueIsTrue;
@end
#endif /* __Invoking_h__GNUSTEP_BASE_INCLUDE */

View file

@ -1,81 +0,0 @@
/* Protocol for Objective-C objects holding (keyElement,contentElement) pairs.
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/* The <KeyedCollecting> protocol inherits from the <Collecting> protocol.
The <KeyedCollecting> protocol defines the interface to a
collection of elements that are accessible by a key, where the key is
some unique element. Pairs of (key element, content element) may be
added, removed and replaced. The keys and contents may be tested,
enumerated and copied.
*/
#ifndef __KeyedCollecting_h_GNUSTEP_BASE_INCLUDE
#define __KeyedCollecting_h_GNUSTEP_BASE_INCLUDE
#include <base/Collecting.h>
@protocol ConstantKeyedCollecting <ConstantCollecting>
// INITIALIZING;
- initWithObjects: (id*)objects forKeys: (id*)keys count: (unsigned)c;
// GETTING ELEMENTS AND KEYS;
- objectAtKey: aKey;
- keyOfObject: aContentObject;
// TESTING;
- (BOOL) containsKey: aKey;
// ENUMERATIONS;
- (id <Enumerating>) keyEnumerator;
- withKeyObjectsInvoke: (id <Invoking>)anInvocation;
- withKeyObjectsInvoke: (id <Invoking>)anInvocation
whileTrue: (BOOL *)flag;
// LOW-LEVEL ENUMERATING;
- nextObjectAndKey: (id*)keyPtr withEnumState: (void**)enumState;
// COPYING;
- shallowCopyValuesAs: (Class)aCollectingClass;
- shallowCopyKeysAs: (Class)aCollectingClass;
- copyValuesAs: (Class)aCollectingClass;
- copyKeysAs: (Class)aCollectingClass;
@end
@protocol KeyedCollecting <ConstantKeyedCollecting, Collecting>
// ADDING;
- (void) putObject: newContentObject atKey: aKey;
// REPLACING AND SWAPPING;
- (void) replaceObjectAtKey: aKey with: newContentObject;
- (void) swapObjectsAtKeys: key1 : key2;
// REMOVING;
- (void) removeObjectAtKey: aKey;
@end
#endif /* __KeyedCollecting_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,79 +0,0 @@
/* Interface for Objective-C KeyedCollection collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __KeyedCollection_h_GNUSTEP_BASE_INCLUDE
#define __KeyedCollection_h_GNUSTEP_BASE_INCLUDE
#include <base/Collection.h>
#include <base/KeyedCollecting.h>
@interface ConstantKeyedCollection : Collection
@end
@interface KeyedCollection : ConstantKeyedCollection
@end
/* Put this on category instead of class to avoid bogus complaint from gcc */
@interface ConstantKeyedCollection (Protocol) <ConstantKeyedCollecting>
@end
@interface KeyedCollection (Protocol) <KeyedCollecting>
@end
@interface KeyEnumerator : Enumerator
@end
#define FOR_KEYED_COLLECTION(ACOLL, ELT, KEY) \
{ \
void *_es = [ACOLL newEnumState]; \
while ((ELT = [ACOLL nextObjectAndKey: &(KEY) withEnumState: &_es])) \
{
#define END_FOR_KEYED_COLLECTION(ACOLL) \
} \
[ACOLL freeEnumState: &_es]; \
}
#define FOR_KEYED_COLLECTION_WHILE_TRUE(ACOLL, ELT, KEY, FLAG) \
{ \
void *_es = [ACOLL newEnumState]; \
while (FLAG && (ELT = [ACOLL nextObjectAndKey: &(KEY) \
withEnumState: &_es])) \
{
#define END_FOR_KEYED_COLLECTION_WHILE_TRUE(ACOLL) \
} \
[ACOLL freeEnumState: &_es]; \
}
/* The only subclassResponsibilities in IndexedCollection are:
keyDescription
insertElement:atKey:
removeElementAtKey:
elementAtKey:
includesKey:
getNextKey:content:withEnumState:
*/
#endif /* __KeyedCollection_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,280 +0,0 @@
/* Implementation for Objective-C KeyedCollection collection object
Copyright (C) 1993,1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/KeyedCollection.h>
#include <base/CollectionPrivate.h>
#include <stdio.h>
#include <base/Array.h>
#include <base/NSString.h>
#include <base/behavior.h>
@implementation KeyEnumerator
- nextObject
{
id k;
[collection nextObjectAndKey: &k withEnumState: &enum_state];
return k;
}
@end
@implementation ConstantKeyedCollection
// INITIALIZING;
/* This is the designated initializer */
- initWithObjects: (id*)objects forKeys: (id*)keys count: (unsigned)c
{
[self subclassResponsibility: _cmd];
return nil;
}
// GETTING ELEMENTS AND KEYS;
- objectAtKey: aKey
{
[self subclassResponsibility: _cmd];
return nil;
}
- keyOfObject: aContentObject
{
[self subclassResponsibility: _cmd];
return nil;
}
// TESTING;
- (BOOL) containsKey: aKey
{
if ([self objectAtKey: aKey] == NO_OBJECT)
return NO;
return YES;
}
// ENUMERATIONS;
- (id <Enumerating>) keyEnumerator
{
return [[[KeyEnumerator alloc] initWithCollection: self]
autorelease];
}
- (void) withKeysInvoke: (id <Invoking>)anInvocation
{
id o, k;
FOR_KEYED_COLLECTION(self, o, k)
{
[anInvocation invokeWithObject: k];
}
END_FOR_KEYED_COLLECTION(self);
}
- (void) withKeysInvoke: (id <Invoking>)anInvocation
whileTrue: (BOOL *)flag
{
id o, k;
FOR_KEYED_COLLECTION_WHILE_TRUE(self, o, k, *flag)
{
[anInvocation invokeWithObject: k];
}
END_FOR_KEYED_COLLECTION(self);
}
/* Override this Collection method */
- nextObjectWithEnumState: (void**)enumState
{
id k;
return [self nextObjectAndKey: &k withEnumState: enumState];
}
// LOW-LEVEL ENUMERATING;
- nextObjectAndKey: (id*)keyPtr withEnumState: (void**)enumState
{
[self subclassResponsibility: _cmd];
return nil;
}
// COPYING;
- shallowCopyValuesAs: (Class)aConstantCollectingClass
{
int count = [self count];
id contents[count];
id k;
int i = 0;
id o;
FOR_KEYED_COLLECTION(self, o, k)
{
contents[i++] = o;
}
END_FOR_KEYED_COLLECTION(self);
return [[aConstantCollectingClass alloc]
initWithObjects: contents count: count];
}
- shallowCopyKeysAs: (Class)aCollectingClass;
{
int count = [self count];
id contents[count];
id k;
int i = 0;
id o;
FOR_KEYED_COLLECTION(self, o, k)
{
contents[i++] = k;
}
END_FOR_KEYED_COLLECTION(self);
return [[aCollectingClass alloc]
initWithObjects: contents count: count];
}
- copyValuesAs: (Class)aCollectingClass
{
[self notImplemented: _cmd];
return nil;
}
- copyKeysAs: (Class)aCollectingClass;
{
[self notImplemented: _cmd];
return nil;
}
// ARCHIVING
- (void) _encodeContentsWithCoder: (id <Encoding>)aCoder
{
unsigned int count = [self count];
id o, k;
[aCoder encodeValueOfCType: @encode(unsigned)
at: &count
withName: @"Collection content count"];
FOR_KEYED_COLLECTION(self, o, k)
{
[aCoder encodeObject: k
withName: @"KeyedCollection key"];
[aCoder encodeObject: o
withName:@"KeyedCollection content"];
}
END_FOR_KEYED_COLLECTION(self);
}
- (void) _decodeContentsWithCoder: (id <Decoding>)aCoder
{
unsigned int count, i;
id *objs, *keys;
[aCoder decodeValueOfCType:@encode(unsigned)
at:&count
withName:NULL];
OBJC_MALLOC(objs, id, count);
OBJC_MALLOC(keys, id, count);
for (i = 0; i < count; i++)
{
[aCoder decodeObjectAt: &(keys[i])
withName: NULL];
[aCoder decodeObjectAt: &(objs[i])
withName: NULL];
}
[self initWithObjects: objs forKeys: keys count: count];
for (i = 0; i < count; i++)
{
[keys[i] release];
[objs[i] release];
}
OBJC_FREE(objs);
OBJC_FREE(keys);
}
- (NSString*) description
{
id s = [NSMutableString new];
id o, k;
FOR_KEYED_COLLECTION(self, o, k)
{
[s appendFormat: @"(%@,%@) ", [k description], [o description]];
}
END_FOR_KEYED_COLLECTION(self);
[s appendFormat: @" :%s\n", object_get_class_name (self)];
return [s autorelease];
}
@end
@implementation KeyedCollection
+ (void) initialize
{
if (self == [KeyedCollection class])
class_add_behavior(self, [Collection class]);
}
// ADDING;
- (void) putObject: newContentObject atKey: aKey
{
[self subclassResponsibility: _cmd];
}
// REPLACING AND SWAPPING;
- (void) replaceObjectAtKey: aKey with: newContentObject
{
[self subclassResponsibility: _cmd];
}
- (void) swapObjectsAtKeys: key1 : key2
{
[self subclassResponsibility: _cmd];
}
// REMOVING;
- (void) removeObjectAtKey: aKey
{
[self subclassResponsibility: _cmd];
}
@end

View file

@ -1,50 +0,0 @@
/* Interface for Objective-C LinkedList collection object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __LinkedList_h_GNUSTEP_BASE_INCLUDE
#define __LinkedList_h_GNUSTEP_BASE_INCLUDE
#include <base/OrderedCollection.h>
/* The <LinkedListComprising> protocol defines the interface to an object
that may be an element in a LinkedList.
*/
@protocol LinkedListComprising
- nextLink;
- prevLink;
- (void) setNextLink: (id <LinkedListComprising>)aLink;
- (void) setPrevLink: (id <LinkedListComprising>)aLink;
- linkedList;
- (void) setLinkedList: aLinkedList;
@end
@interface LinkedList : OrderedCollection
{
id _first_link;
id _last_link;
unsigned int _count;
}
@end
#endif /* __LinkedList_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,408 +0,0 @@
/* Implementation for Objective-C LinkedList collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/LinkedList.h>
#include <base/IndexedCollectionPrivate.h>
#include <base/Coder.h>
@implementation LinkedList
/* This is the designated initializer of this class */
- init
{
_count = 0;
_first_link = nil;
_last_link = nil;
return self;
}
- initWithObjects: (id*)objs count: (unsigned)c
{
[self init];
while (c--)
[self prependObject: objs[c]];
return self;
}
/* Archiving must mimic the above designated initializer */
- (void) encodeWithCoder: coder
{
id l;
[super encodeWithCoder: coder];
[coder encodeValueOfCType: @encode (typeof (_count))
at: &_count
withName: @"LinkedList count"];
FOR_COLLECTION (self, l)
{
[coder encodeObject: l
withName: @"LinkedList element"];
}
END_FOR_COLLECTION (self);
[coder encodeObjectReference: _first_link
withName: @"LinkedList first link"];
[coder encodeObjectReference: _last_link
withName: @"LinkedList last link"];
}
- initWithCoder: coder
{
int i;
// id link;
self = [super initWithCoder: coder];
[coder decodeValueOfCType: @encode (typeof (_count))
at: &_count
withName: NULL];
/* We don't really care about storing the elements decoded, because
we access them through their own link pointers. */
for (i = 0; i < _count; i++)
[coder decodeObjectAt: NULL
withName: NULL];
[coder decodeObjectAt: &_first_link
withName: NULL];
[coder decodeObjectAt: &_last_link
withName: NULL];
#if 0
/* xxx Not necessary, since the links encode this?
But should we rely on the links encoding this?
BUT! Look out: the next link pointers may not be set until
the last finishDecoding... method is run... */
FOR_COLLECTION (self, link)
{
[link setLinkedList: self];
}
END_FOR_COLLECTION (self);
#endif
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
LinkedList *copy = [super emptyCopy];
copy->_first_link = nil;
copy->_last_link = nil;
copy->_count = 0;
return copy;
}
/* This must work without sending any messages to content objects */
- (void) _empty
{
_count = 0;
_first_link = nil;
_last_link = nil;
}
/* These next four methods are the only ones that change the values of
the instance variables _count, _first_link, except for
"-init". */
- (void) removeObject: oldObject
{
NSAssert([oldObject linkedList] == self, NSInternalInconsistencyException);
if (_first_link == oldObject)
{
if (_count > 1)
_first_link = [oldObject nextLink];
else
_first_link = nil;
}
else
[[oldObject prevLink] setNextLink:[oldObject nextLink]];
if (_last_link == oldObject)
{
if (_count > 1)
_last_link = [oldObject prevLink];
else
_first_link = nil;
}
else
[[oldObject nextLink] setPrevLink:[oldObject prevLink]];
_count--;
[oldObject setNextLink: NO_OBJECT];
[oldObject setPrevLink: NO_OBJECT];
[oldObject setLinkedList: NO_OBJECT];
[oldObject release];
}
- (void) insertObject: newObject after: oldObject
{
/* Make sure we actually own the oldObject. */
NSAssert([oldObject linkedList] == self, NSInternalInconsistencyException);
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setLinkedList: self];
/* Insert it. */
if (_count == 0)
{
_first_link = newObject;
_last_link = newObject;
_count = 1;
[newObject setNextLink: NO_OBJECT];
[newObject setPrevLink: NO_OBJECT];
}
else
{
if (oldObject == _last_link)
_last_link = newObject;
[newObject setNextLink: [oldObject nextLink]];
[newObject setPrevLink: oldObject];
[[oldObject nextLink] setPrevLink: newObject];
[oldObject setNextLink: newObject];
}
_count++;
}
- (void) insertObject: newObject before: oldObject
{
/* Make sure we actually own the oldObject. */
NSAssert([oldObject linkedList] == self, NSInternalInconsistencyException);
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setLinkedList: self];
/* Insert it. */
if (_count == 0)
{
_first_link = newObject;
_last_link = newObject;
_count = 1;
[newObject setNextLink: NO_OBJECT];
[newObject setPrevLink: NO_OBJECT];
}
else
{
if (oldObject == _first_link)
_first_link = newObject;
[newObject setPrevLink: [oldObject prevLink]];
[newObject setNextLink: oldObject];
[[oldObject prevLink] setNextLink: newObject];
[oldObject setPrevLink: newObject];
}
_count++;
}
- (void) replaceObject: oldObject with: newObject
{
/* Make sure we actually own the oldObject. */
NSAssert([oldObject linkedList] == self, NSInternalInconsistencyException);
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setLinkedList: self];
/* Do the replacement. */
if (oldObject == _first_link)
_first_link = newObject;
[newObject setNextLink:[oldObject nextLink]];
[newObject setPrevLink:[oldObject prevLink]];
[[oldObject prevLink] setNextLink:newObject];
[[oldObject nextLink] setPrevLink:newObject];
/* Release ownership of the oldObject. */
[oldObject setNextLink: NO_OBJECT];
[oldObject setPrevLink: NO_OBJECT];
[oldObject setLinkedList: NO_OBJECT];
[oldObject release];
}
/* End of methods that change the instance variables. */
- (void) appendObject: newObject
{
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Insert it. */
if (_count == 0)
{
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setLinkedList: self];
/* Put it in as the only node. */
_first_link = newObject;
_last_link = newObject;
_count = 1;
[newObject setNextLink: NO_OBJECT];
[newObject setPrevLink: NO_OBJECT];
}
else
[self insertObject: newObject after: _last_link];
}
- (void) prependObject: newObject
{
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Insert it. */
if (_count == 0)
{
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setLinkedList: self];
/* Put it in as the only node. */
_first_link = newObject;
_last_link = newObject;
_count = 1;
[newObject setNextLink: NO_OBJECT];
[newObject setPrevLink: NO_OBJECT];
}
else
[self insertObject: newObject before: _first_link];
}
- (void) insertObject: newObject atIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, (_count+1));
/* Make sure no one else already owns the newObject. */
NSAssert([newObject linkedList] == NO_OBJECT, NSInternalInconsistencyException);
/* Insert it. */
if (_count == 0)
{
/* Claim ownership of the newObject. */
[newObject retain];
[newObject setLinkedList: self];
/* Put it in as the only node. */
_first_link = newObject;
_last_link = newObject;
_count = 1;
[newObject setNextLink: NO_OBJECT];
[newObject setPrevLink: NO_OBJECT];
}
else if (index == _count)
[self insertObject: newObject after: _last_link];
else
[self insertObject:newObject before: [self objectAtIndex: index]];
}
- (void) removeObjectAtIndex: (unsigned)index
{
CHECK_INDEX_RANGE_ERROR(index, _count);
[self removeObject: [self objectAtIndex: index]];
}
- objectAtIndex: (unsigned)index
{
id <LinkedListComprising> link;
CHECK_INDEX_RANGE_ERROR(index, _count);
if (index < _count / 2)
for (link = _first_link;
index;
link = [link nextLink], index--)
;
else
for (link = _last_link, index = _count - index - 1;
index;
link = [link prevLink], index--)
;
return link;
}
- firstObject
{
return _first_link;
}
- lastObject
{
return _last_link;
}
- successorOfObject: oldObject
{
/* Make sure we actually own the oldObject. */
NSAssert([oldObject linkedList] == self, NSInternalInconsistencyException);
return [oldObject nextLink];
}
- predecessorOfObject: oldObject
{
/* Make sure we actually own the oldObject. */
NSAssert([oldObject linkedList] == self, NSInternalInconsistencyException);
return [oldObject prevLink];
}
- (void*) newEnumState
{
return _first_link;
}
- nextObjectWithEnumState: (void**)enumState
{
id ret;
if (!*enumState)
return nil;
ret = *enumState;
*enumState = [(id)(*enumState) nextLink];
/* *enumState points to the next object to be returned. */
return ret;
}
- prevObjectWithEnumState: (void**)enumState
{
/* *enumState points to the object returned last time. */
if (!*enumState)
return nil;
if (*enumState == _first_link)
/* enumState was just initialized from -newEnumState. */
return *enumState = _last_link;
return (id) *enumState = [(id)(*enumState) prevLink];
}
- (unsigned) count
{
return _count;
}
@end

View file

@ -1,38 +0,0 @@
/* Interface for Objective-C LinkedListNode object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __LinkedListNode_h_GNUSTEP_BASE_INCLUDE
#define __LinkedListNode_h_GNUSTEP_BASE_INCLUDE
#include <base/LinkedList.h>
#include <base/Coding.h>
@interface LinkedListNode : NSObject <LinkedListComprising>
{
id <LinkedListComprising> _next;
id <LinkedListComprising> _prev;
id _linked_list;
}
@end
#endif /* __LinkedListNode_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,84 +0,0 @@
/* Implementation for Objective-C LinkedListNode object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/LinkedListNode.h>
#include <base/Coder.h>
@implementation LinkedListNode
- init
{
[super init];
_next = _prev = _linked_list = nil;
return self;
}
- (void) encodeWithCoder: aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeObjectReference:_next withName:@"Next LinkedList Node"];
[aCoder encodeObjectReference:_prev withName:@"Prev LinkedList Node"];
[aCoder encodeObjectReference:_linked_list withName:@"LinkedList"];
}
- initWithCoder: aCoder
{
[super initWithCoder:aCoder];
[aCoder decodeObjectAt:&_next withName:NULL];
[aCoder decodeObjectAt:&_prev withName:NULL];
[aCoder decodeObjectAt:&_linked_list withName:NULL];
return self;
}
- (id <LinkedListComprising>) nextLink
{
return _next;
}
- (id <LinkedListComprising>) prevLink
{
return _prev;
}
- (void) setNextLink: (id <LinkedListComprising>)aLink
{
_next = aLink;
}
- (void) setPrevLink: (id <LinkedListComprising>)aLink
{
_prev = aLink;
}
- linkedList
{
return _linked_list;
}
- (void) setLinkedList: anObject;
{
_linked_list = anObject;
}
@end

View file

@ -1,34 +0,0 @@
/* Protocol for GNU Objective-C mutex locks
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Locking_h_GNUSTEP_BASE_INCLUDE
#define __Locking_h_GNUSTEP_BASE_INCLUDE
#include <objc/Protocol.h>
@protocol Locking
- (void) lock;
- (void) unlock;
@end
#endif /* __Locking_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,39 +0,0 @@
/* Interface for Mach-port based object for use with Connection
Copyright (C) 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: July 1994
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __MachPort_h_GNUSTEP_BASE_INCLUDE
#define __MachPort_h_GNUSTEP_BASE_INCLUDE
#if __mach__
#include <base/Port.h>
@interface MachInPort : InPort
@end
@interface MachOutPort : OutPort
@end
#endif /* __mach__ */
#endif /* __MachPort_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,196 +0,0 @@
/* Implementation of Machport-based port object for use with Connection
Copyright (C) 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: September 1994
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/* This old code really needs work; it does not currently compile. */
#if __mach__
#include <config.h>
#include <base/MachPort.h>
#include <Foundation/NSLock.h>
#include <Foundation/NSException.h>
#include <base/Set.h>
#include <mach/cthreads.h>
#include <mach/notify.h>
static Dictionary *portDictionary;
static NSLock *portDictionaryGate;
@implementation MachPort
+ initialize
{
portDictionaryGate = [NSLock new];
NSAssert(sizeof(int) == sizeof(port_t), NSInternalInconsistencyException);
portDictionary = [[Dictionary alloc]
initWithType:@encode(id)
keyType:@encode(int)];
return self;
}
/* This not tested */
static int
listen_for_invalidation (any_t arg)
{
kern_return_t r;
notification_t m;
m.notify_header.msg_size = sizeof(notification_t);
m.notify_header.msg_local_port = task_notify();
for (;;)
{
r = msg_receive((msg_header_t*)&m, MSG_OPTION_NONE, 0);
switch (r)
{
case RCV_SUCCESS:
fprintf(stderr, "notification id %d\n", (int)m.notify_header.msg_id);
break;
case RCV_TIMED_OUT:
fprintf(stderr, "notification msg_receive timed out\n");
exit(-1);
default:
mach_error("notification", r);
exit(-1);
}
switch (m.notify_header.msg_id)
{
case NOTIFY_PORT_DELETED:
[[MachPort newFromMachPort:m.notify_port] invalidate];
break;
case NOTIFY_MSG_ACCEPTED:
break;
case NOTIFY_PORT_DESTROYED:
[[MachPort newFromMachPort:m.notify_port] invalidate];
break;
default:
mach_error("notification", r);
exit(-1);
}
/* Where do we free the object? */
}
return 0;
}
/* This not tested */
+ listenForPortInvalidation
{
MachPort *listenPort = [MachPort new];
task_set_special_port(task_self(), TASK_NOTIFY_PORT, [listenPort mach_port]);
cthread_detach(cthread_fork((any_t)listen_for_invalidation, (any_t)0));
return self;
}
/* designated initializer */
+ newFromMachPort: (port_t)p dealloc: (BOOL)f
{
MachPort *aPort;
[portDictionaryGate lock];
if ((aPort = [portDictionary elementAtKey:(int)p]))
{
[portDictionaryGate unlock];
[aPort addReference];
return aPort;
}
aPort = [[self alloc] init];
aPort->mach_port = p;
aPort->deallocate = f;
[portDictionary addElement:aPort atKey:(int)p];
[portDictionaryGate unlock];
return aPort;
}
+ newFromMachPort: (port_t)p
{
return [self newFromMachPort:p dealloc:NO];
}
+ new
{
kern_return_t error;
port_t p;
if ((error=port_allocate(task_self(), &p)) != KERN_SUCCESS) {
mach_error("port_allocate failed", error);
exit(1);
}
return [self newFromMachPort:p];
}
- (void) encodeWithCoder: aCoder
{
[aCoder encodeValueOfCType: @encode(BOOL)
at: &deallocate
withName: @""];
[aCoder encodeMachPort: mach_port];
}
+ newWithCoder: aCoder
{
BOOL f;
port_t mp;
MachPort *p;
[aCoder decodeValueOfCType: @encode(BOOL)
at: &f
withName: NULL];
[aCoder decodeMachPort: &mp];
p = [MachPort newFromMachPort:mp dealloc:f];
return p;
}
- (unsigned) hash
{
/* What should this be? */
return (unsigned)self;
}
- (void) dealloc
{
if (refcount-1 == 0)
{
[portDictionaryGate lock];
[portDictionaryGate removeElementAtKey:(int)machPort];
[portDictionaryGate unlock];
if (deallocate)
{
kern_return_t error;
error = port_deallocate(task_self(), machPort);
if (error != KERN_SUCCESS) {
mach_error("port_deallocate failed", error);
exit(1);
}
}
}
[super dealloc];
return self;
}
- (mach_port_t) machPort
{
return mach_port;
}
@end
#endif /* __mach__ */

View file

@ -1,33 +0,0 @@
/* Interface for Objective-C Magnitude object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Magnitude_h_GNUSTEP_BASE_INCLUDE
#define __Magnitude_h_GNUSTEP_BASE_INCLUDE
#include <base/Ordering.h>
@interface Magnitude : NSObject <Ordering>
@end
#endif /* __Magnitude_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,99 +0,0 @@
/* Implementation for Objective-C Magnitude object
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/preface.h>
#include <base/Magnitude.h>
/* These methods accesses no instance variables. It is exactly the kind
of thing that should be a "behavior" associated with a protocol.
i.e. #3 on Steve Naroff's wish list. */
@implementation Magnitude
- (int) compare: anObject
{
return [super compare:anObject];
}
- (BOOL) greaterThan: anObject
{
if ([self compare:anObject] > 0)
return YES;
else
return NO;
}
- (BOOL) greaterThanOrEqual: anObject
{
if ([self compare:anObject] >= 0)
return YES;
else
return NO;
}
- (BOOL) lessThan: anObject
{
if ([self compare:anObject] < 0)
return YES;
else
return NO;
}
- (BOOL) lessThanOrEqual: anObject
{
if ([self compare:anObject] <= 0)
return YES;
else
return NO;
}
- (BOOL) between: firstObject and: secondObject
{
if ([self compare:firstObject] >= 0
&& [self compare:secondObject] <= 0)
return YES;
else
return NO;
}
- maximum: anObject
{
if ([self compare:anObject] >= 0)
return self;
else
return anObject;
}
- minimum: anObject
{
if ([self compare:anObject] <= 0)
return self;
else
return anObject;
}
@end

View file

@ -1,40 +0,0 @@
/* Interface for Objective-C MappedCollector collection object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __MappedCollector_h_GNUSTEP_BASE_INCLUDE
#define __MappedCollector_h_GNUSTEP_BASE_INCLUDE
#include <base/KeyedCollection.h>
@interface MappedCollector : KeyedCollection
{
id <KeyedCollecting> _map;
id <KeyedCollecting> _domain;
}
- initWithCollection: (id <KeyedCollecting>)aDomain
map: (id <KeyedCollecting>)aMap;
@end
#endif /* __MappedCollector_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,138 +0,0 @@
/* Implementation for Objective-C MappedCollector collection object
Copyright (C) 1993, 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/MappedCollector.h>
#include <base/Dictionary.h>
#include <base/CollectionPrivate.h>
@implementation MappedCollector
/* This is the designated initializer for this class */
- initWithCollection: (id <KeyedCollecting>)aDomain
map: (id <KeyedCollecting>)aMap
{
_map = aMap;
_domain = aDomain;
return self;
}
/* Archiving must mimic the above designated initializer */
- (void) encodeWithCoder: anEncoder
{
[self notImplemented:_cmd];
}
+ newWithCoder: aDecoder
{
[self notImplemented:_cmd];
return self;
}
/* Override our superclass' designated initializer */
- initWithObjects: (id*)objects forKeys: (id*)keys count: (unsigned)c
{
[self notImplemented: _cmd];
return nil;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
MappedCollector *copy = [super emptyCopy];
copy->_map = [_map emptyCopy];
copy->_domain = [_domain emptyCopy];
return copy;
}
/* This must work without sending any messages to content objects */
- (void) empty
{
[_domain empty];
}
- objectAtKey: aKey
{
return [_domain objectAtKey: [_map objectAtKey: aKey]];
}
- keyOfObject: aContentObject
{
[self notImplemented: _cmd];
return self;
}
- (void) replaceObjectAtKey: aKey with: newObject
{
return [_domain replaceObjectAtKey: [_map objectAtKey: aKey]
with: newObject];
}
- (void) putObject: newObject atKey: aKey
{
return [_domain putObject: newObject
atKey: [_map objectAtKey:aKey]];
}
- (void) removeObjectAtKey: aKey
{
return [_domain removeObjectAtKey: [_map objectAtKey: aKey]];
}
- (BOOL) containsKey: aKey
{
return [_domain containsKey: [_map objectAtKey:aKey]];
}
- (void*) newEnumState
{
return [_domain newEnumState];
}
- (void) freeEnumState: (void**)enumState
{
return [_domain freeEnumState: enumState];
}
- nextObjectAndKey: (id*)keyPtr withEnumState: (void**)enumState
{
id mapContent;
id domainKey;
/* xxx This needs debugging; see checks/test02.m */
while ((mapContent = [_map nextObjectAndKey:keyPtr withEnumState:enumState])
&&
(![_domain containsKey: (domainKey = [_map objectAtKey:*keyPtr])]))
;
if (mapContent == NO_OBJECT)
return NO_OBJECT;
return [_domain objectAtKey: domainKey];
}
- species
{
return [Dictionary class];
}
@end

View file

@ -1,90 +0,0 @@
/* Interface for GNU Objective C memory stream
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/*
Modified by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
Date: September 1997
Modifications to use NSData and NSMutable data objects to hold data.
*/
#ifndef __MemoryStream_h_GNUSTEP_BASE_INCLUDE
#define __MemoryStream_h_GNUSTEP_BASE_INCLUDE
#include <base/Stream.h>
#include <base/Streaming.h>
/* This protocol is preliminary and may change.
This also may get pulled out into a separate .h file. */
@protocol MemoryStreaming <Streaming>
- initWithCapacity: (unsigned)capacity;
- (void) setStreamBufferCapacity: (unsigned)s;
- (char*) streamBuffer;
- (unsigned) streamBufferCapacity;
- (unsigned) streamEofPosition;
@end
@interface MemoryStream : Stream <MemoryStreaming>
{
id data;
int prefix;
int position;
int eof_position;
BOOL isMutable;
}
+ (MemoryStream*)streamWithData: (id)anObject;
- initWithCapacity: (unsigned)capacity
prefix: (unsigned)prefix;
- initWithData: (id)anObject;
#if 0
- initWithSize: (unsigned)s; /* For backwards compatibility, depricated */
#endif
- (id) data;
- (id) mutableData;
- (unsigned) streamBufferPrefix;
- (unsigned) streamBufferLength; /* prefix + eofPosition */
/* xxx This interface will change */
- _initOnMallocBuffer: (char*)b
size: (unsigned)s /* size of malloc'ed buffer */
eofPosition: (unsigned)l /* length of buffer with data for reading */
prefix: (unsigned)p /* reset for this position */
position: (unsigned)i; /* current position for reading/writing */
- _initOnMallocBuffer: (char*)b
freeWhenDone: (BOOL)f
size: (unsigned)s /* size of malloc'ed buffer */
eofPosition: (unsigned)l /* length of buffer with data for reading */
prefix: (unsigned)p /* reset for this position */
position: (unsigned)i; /* current position for reading/writing */
@end
#endif /* __MemoryStream_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,435 +0,0 @@
/* Implementation of GNU Objective C memory stream
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/preface.h>
#include <base/MemoryStream.h>
#include <base/Coder.h>
#include <Foundation/NSData.h>
#include <Foundation/NSException.h>
#include <stdarg.h>
/* Deal with memchr: */
#if STDC_HEADERS || HAVE_STRING_H
#include <string.h>
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
#if !STDC_HEADERS && HAVE_MEMORY_H
#include <memory.h>
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
#define rindex strrchr
#define bcopy(s, d, n) memcpy ((d), (s), (n))
#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
#define bzero(s, n) memset ((s), 0, (n))
#else /* not STDC_HEADERS and not HAVE_STRING_H */
#include <strings.h>
/* memory.h and strings.h conflict on some systems. */
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
#define DEFAULT_MEMORY_STREAM_SIZE 64
extern int
o_vscanf (void *stream,
int (*inchar_func)(void*),
void (*unchar_func)(void*,int),
const char *format, va_list argptr);
static BOOL debug_memory_stream = NO;
/* A pretty stupid implementation based on realloc(), but it works for now. */
@implementation MemoryStream
+ (MemoryStream*)streamWithData: (id)anObject
{
return [[[MemoryStream alloc] initWithData:anObject] autorelease];
}
- (id) data
{
return data;
}
/* xxx This interface will change */
- _initOnMallocBuffer: (char*)b
freeWhenDone: (BOOL)f
size: (unsigned)s /* size of malloc'ed buffer */
eofPosition: (unsigned)l /* length of buffer with data for reading */
prefix: (unsigned)p /* never read/write before this position */
position: (unsigned)i /* current position for reading/writing */
{
self = [super init];
if (self)
{
if (b)
if (f)
data = [[NSMutableData alloc] initWithBytesNoCopy: b length: s];
else
data = [[NSMutableData alloc] initWithBytes: b length: s];
else
{
data = [[NSMutableData alloc] initWithCapacity: s];
if (data)
[data setLength: s];
}
if (data)
{
prefix = p;
position = i;
eof_position = l;
isMutable = YES;
if ([data length] < prefix + MAX(position, eof_position))
[data setLength: prefix + MAX(position, eof_position)];
}
else
{
[self release];
self = nil;
}
}
return self;
}
- _initOnMallocBuffer: (char*)b
size: (unsigned)s /* size of malloc'ed buffer */
eofPosition: (unsigned)l /* length of buffer with data for reading */
prefix: (unsigned)p /* never read/write before this position */
position: (unsigned)i /* current position for reading/writing */
{
return [self _initOnMallocBuffer: b
freeWhenDone: YES
size: s
eofPosition: l
prefix: p
position: i];
}
/* xxx This method will disappear. */
#if 0
- initWithSize: (unsigned)s
prefix: (unsigned)p
position: (unsigned)i
{
return [self _initOnMallocBuffer: 0
freeWhenDone: YES
size: s
eofPosition: i
prefix: p
position: i];
}
#endif
- initWithCapacity: (unsigned)capacity
prefix: (unsigned)p
{
return [self _initOnMallocBuffer: 0
freeWhenDone: YES
size: capacity
eofPosition: 0
prefix: p
position: 0];
}
- initWithCapacity: (unsigned)capacity
{
return [self _initOnMallocBuffer: 0
freeWhenDone: YES
size: capacity
eofPosition: 0
prefix: 0
position: 0];
}
- initWithData: (id)anObject
{
self = [super init];
if (self)
{
if (anObject && [anObject isKindOfClass:[NSData class]])
{
data = [anObject retain];
if ([data isKindOfClass:[NSMutableData class]])
isMutable = YES;
eof_position = [data length];
position = 0;
prefix = 0;
}
else
{
[self dealloc];
self = nil;
}
}
return self;
}
#if 0
- initWithSize: (unsigned)s
{
return [self initWithCapacity:s];
}
#endif
- init
{
return [self initWithCapacity: DEFAULT_MEMORY_STREAM_SIZE];
}
- (BOOL) isWritable
{
return isMutable;
}
- (void) encodeWithCoder: anEncoder
{
[self notImplemented:_cmd];
}
+ newWithCoder: aDecoder
{
[self notImplemented:_cmd];
return self;
}
- (id) mutableData
{
if (isMutable)
return data;
return nil;
}
- (int) writeBytes: (const void*)b length: (int)l
{
unsigned size;
if (isMutable)
{
size = [data capacity];
if (prefix+position+l > size)
{
size = MAX(prefix+position+l, size*2);
[data setCapacity: size];
}
if (position+prefix+l > [data length])
[data setLength: position+prefix+l];
memcpy([data mutableBytes]+prefix+position, b, l);
position += l;
if (position > eof_position)
eof_position = position;
return l;
}
return 0;
}
- (int) readBytes: (void*)b length: (int)l
{
if (position+l > eof_position)
l = eof_position-position;
memcpy(b, [data bytes]+prefix+position, l);
position += l;
return l;
}
- (NSString*) readLine
{
char *nl = memchr([data bytes]+prefix+position, '\n', eof_position-position);
char *ret = NULL;
if (nl)
{
int len = nl-((char*)[data bytes])-prefix-position;
ret = objc_malloc (len+1);
strncpy(ret, ((char*)[data bytes])+prefix+position, len);
ret[len] = '\0';
position += len+1;
}
return [[[NSString alloc] initWithCStringNoCopy: ret
length: strlen (ret)
freeWhenDone: YES]
autorelease];
}
/* Making these nested functions (which is what I'd like to do) is
crashing the va_arg stuff in vscanf(). Why? */
#define MS ((MemoryStream*)s)
int outchar_func(void *s, int c)
{
if (MS->isMutable)
{
if (MS->prefix + MS->position >= [MS->data capacity])
return EOF;
((char*)[MS->data mutableBytes])[MS->prefix + MS->position++] = (char)c;
return 1;
}
return EOF;
}
int inchar_func(void *s)
{
if (MS->prefix + MS->position >= [MS->data length])
return EOF;
return (int) ((char*)[MS->data bytes])[MS->prefix + MS->position++];
}
void unchar_func(void *s, int c)
{
if (MS->position > 0)
MS->position--;
if (MS->isMutable)
((char*)[MS->data mutableBytes])[MS->prefix + MS->position] = (char)c;
}
#if HAVE_VSPRINTF
- (int) writeFormat: (NSString*)format
arguments: (va_list)arg
{
unsigned size;
int ret;
if (!isMutable)
return 0;
/* xxx Using this ugliness we at least let ourselves safely print
formatted strings up to 128 bytes long.
It's digusting, though, and we need to fix it.
Using GNU stdio streams would do the trick.
*/
size = [data capacity];
if (size - (prefix + position) < 128)
size = MAX(size+128, size*2);
[data setLength: size];
ret = VSPRINTF_LENGTH (vsprintf([data mutableBytes]+prefix+position,
[format cString], arg));
position += ret;
/* xxx Make sure we didn't overrun our buffer.
As per above kludge, this would happen if we happen to have more than
128 bytes left in the buffer and we try to write a string longer than
the num bytes left in the buffer. */
NSAssert(prefix + position <= [data capacity], @"buffer overrun");
if (position > eof_position)
eof_position = position;
[data setLength:eof_position + prefix];
if (debug_memory_stream)
{
*(char*)([data mutableBytes]+prefix+position) = '\0';
fprintf(stderr, "%s\n", (char*)[data mutableBytes]+prefix);
}
return ret;
}
#endif
- (int) readFormat: (NSString*)format, ...
{
int ret;
va_list ap;
va_start(ap, format);
ret = o_vscanf(self, inchar_func, unchar_func,
[format cString], ap);
va_end(ap);
return ret;
}
- (void) setStreamPosition: (unsigned)i seekMode: (seek_mode_t)mode
{
switch (mode)
{
case STREAM_SEEK_FROM_START:
position = i;
break;
case STREAM_SEEK_FROM_CURRENT:
position += i;
break;
case STREAM_SEEK_FROM_END:
position = eof_position + i;
break;
}
}
- (unsigned) streamPosition
{
return position;
}
- (void) close
{
[self flushStream];
}
- (void) dealloc
{
[data release];
[super dealloc];
}
- (BOOL) streamEof
{
if (position == eof_position)
return YES;
else
return NO;
}
- (unsigned) streamBufferCapacity
{
if (isMutable)
return [data capacity];
return [data length];
}
- (char*) streamBuffer
{
if (isMutable)
return (char*)[data mutableBytes];
return 0;
}
- (void) setStreamBufferCapacity: (unsigned)s
{
if (isMutable)
if (s > prefix + eof_position)
[data setCapacity:s];
}
- (unsigned) streamEofPosition
{
return eof_position;
}
- (void) setStreamEofPosition: (unsigned)i
{
if (i < [data length] - prefix)
eof_position = i;
}
- (unsigned) streamBufferPrefix
{
return prefix;
}
- (unsigned) streamBufferLength
{
return prefix + eof_position;
}
@end

View file

@ -1,221 +0,0 @@
/* Interface to object for broadcasting Notification objects
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: March 1996
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __NotificationDispatcher_h_GNUSTEP_BASE_INCLUDE
#define __NotificationDispatcher_h_GNUSTEP_BASE_INCLUDE
/* A class for posting notifications to observer objects that request
them.
This implementation has several advantages over OpenStep's
NSNotificationCenter:
(1) Heavy use of hash tables and the use of LinkedList's make it
faster. Removing from the middle of LinkedList's is much more
efficient than removing from the middle of Array's.
(2) The way in which notifications are dispatched can be specified as
invocation objects instead of just selectors. Invocation objects
are more flexible than selectors in that they can hold more context
and, if desired, can call C functions instead of sending a message
to an object; (this way you may be able to avoid creating a new
class just to handle certain notifications).
(3) Instead of sending +defaultCenter, you can simply send +add...,
+remove... and +post... messages directly to the class object.
The class uses a static variable directly, instead of taking
the time for the extra +defaultCenter method call. It's both
easier for the user and more time efficient.
(4) You can call -addObserver:... with both name and object being
nil. This request will receive postings of *all* notifications.
Wow.
Although it offers extra features, the implementation has an
OpenStep-style interface also.
*/
#include <base/LinkedList.h>
#include <base/Array.h>
#include <Foundation/NSMapTable.h>
#include <Foundation/NSString.h>
#include <Foundation/NSLock.h>
@interface NotificationDispatcher : NSObject
{
/* `nr' stands for Notification Request Object; the interface for
this class is defined in the .m file. One of these is created
for each -add... call. */
/* For those observer requests with NAME=nil and OBJECT=nil. */
LinkedList *_anonymous_nr_list;
/* For those observer requests with NAME=nil and OBJECT!=nil. */
NSMapTable *_object_2_nr_list;
/* For those observer requests with NAME!=nil, OBJECT may or may not =nil .*/
NSMapTable *_name_2_nr_list;
/* The keys are observers; the values are Array's containing all
NotificationInvocation objects associated with the observer key. */
NSMapTable *_observer_2_nr_array;
/* A mutex lock for making the ivars thread-safe. */
NSRecursiveLock *_lock;
}
/* Adding new observers. */
/* Register INVOCATION to receive future notifictions that match NAME
and OBJECT. A nil passed as either NAME or OBJECT acts as a
wild-card. If NAME is nil, the NotificationDispatcher will send to
the observer all notification pertaining to OBJECT. If OBJECT is
nil, the NotificationDispatcher will send to the observer all
notification pertaining to NAME. If both OBJECT and NAME are nil,
send to the observer all notifications.
The notification will be posted by sending -invokeWithObject: to
INVOCATION argument. The argument of -invokeWithObject: will be a
Notification object. This use of Invocation objects is more
flexible than using a selector, since Invocation's can be set up
with more arguments, hold more context, and can be C functions.
OBJECT is not retained; this is done so these objects can tell when
there are no outstanding non-notification references remaining. If
an object may have added itself as an observer, it should call
+removeObserver: in its -dealloc method.
INVOCATION and NAME, however, are retained. */
- (void) addInvocation: (id <Invoking>)invocation
name: (NSString*)name
object: object;
/* Register OBSERVER to receive future notifications that match NAME
and OBJECT. A nil passed as either NAME or OBJECT acts as a
wild-card. If NAME is nil, the NotificationDispatcher will send to
the observer all notification pertaining to OBJECT. If OBJECT is
nil, the NotificationDispatcher will send to the observer all
notification pertaining to NAME. If both OBJECT and NAME are nil,
send to the observer all notifications.
The notification will be posted by sending -perform:withObject:
to the observer, with SEL and a Notification object as arguments.
Neither OBSERVER nor OBJECT are retained; this is done so these
objects can tell when there are no outstanding non-notification
references remaining. If an object may have added itself as an
observer, it should call +removeObserver: in its -dealloc method.
INVOCATION and NAME, however, are retained. */
- (void) addObserver: observer
selector: (SEL)sel
name: (NSString*)name
object: object;
/* Class versions of the above two methods that send these messages
to the default NotificationDispatcher for the class. */
+ (void) addInvocation: (id <Invoking>)invocation
name: (NSString*)name
object: object;
+ (void) addObserver: observer
selector: (SEL)sel
name: (NSString*)name
object: object;
/* Removing observers. */
/* Remove all notification requests that would be sent to INVOCATION. */
- (void) removeInvocation: invocation;
/* Remove the notification requests matching NAME and OBJECT that
would be sent to INVOCATION. As with adding an observation
request, nil NAME or OBJECT act as wildcards. */
- (void) removeInvocation: invocation
name: (NSString*)name
object: object;
/* Remove all records pertaining to OBSERVER. For instance, this
should be called before the OBSERVER is -dealloc'ed. */
- (void) removeObserver: observer;
/* Remove the notification requests for the given NAME and OBJECT
parameters. As with adding an observation request, nil NAME or
OBJECT act as wildcards. */
- (void) removeObserver: observer
name: (NSString*)name
object: object;
/* Class versions of the above four methods that send these messages
to the default NotificationDispatcher for the class. */
+ (void) removeInvocation: invocation;
+ (void) removeInvocation: invocation
name: (NSString*)name
object: object;
+ (void) removeObserver: observer;
+ (void) removeObserver: observer
name: (NSString*)name
object: object;
/* Post NOTIFICATION to all the observers that match its NAME and OBJECT.
The INFO arguent does not have to be a Dictionary. If there is a single
object that should be associated with the notification, you can simply
pass that single object instead of a Dictionary containing the object. */
- (void) postNotification: notification;
- (void) postNotificationName: (NSString*)name
object: object;
- (void) postNotificationName: (NSString*)name
object: object
userInfo: info;
/* Class versions of the above three methods that send these messages
to the default NotificationDispatcher for the class. */
+ (void) postNotification: notification;
+ (void) postNotificationName: (NSString*)name
object: object;
+ (void) postNotificationName: (NSString*)name
object: object
userInfo: info;
+ defaultInstance;
@end
@interface NotificationDispatcher (OpenStepCompat)
+ defaultCenter;
@end
#endif /* __NotificationDispatcher_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,750 +0,0 @@
/* Implementation of object for broadcasting Notification objects
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: March 1996
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/* The implementation for NotificationDispatcher. */
/* NeXT says you can only have one NotificationCenter per task;
I don't think GNU needs this restriction with its corresponding
NotificationDistributor class. */
#include <config.h>
#include <base/NotificationDispatcher.h>
#include <base/LinkedListNode.h>
#include <base/Array.h>
#include <base/Invocation.h>
#include <Foundation/NSNotification.h>
#include <Foundation/NSException.h>
/* NotificationRequest class - One of these objects is created for
each -addObserver... request. It holds the requested invocation,
name and object. Each object is placed
(1) in one LinkedList, as keyed by the NAME/OBJECT parameters (accessible
through one of the ivars: anonymous_nr_list, object_2_nr_list,
name_2_nr_list), and
(2) in the Array, as keyed by the OBSERVER (as accessible through
the ivar observer_2_nr_array.
To post a notification in satisfaction of this request,
send -postNotification:. */
@interface NotificationRequest : LinkedListNode
{
int _retain_count;
id _name;
id _object;
}
- initWithName: n object: o;
- (NSString*) notificationName;
- notificationObject;
- (void) postNotification: n;
@end
@implementation NotificationRequest
- initWithName: n object: o
{
[super init];
_retain_count = 0;
_name = [n retain];
_object = o;
/* Note that OBJECT is not retained. See the comment for
-addObserver... in NotificationDispatcher.h. */
return self;
}
/* Implement these retain/release methods here for efficiency, since
NotificationRequest's get retained and released by all their
holders. Doing this is a judgement call; I'm choosing speed over
space. */
- retain
{
_retain_count++;
return self;
}
- (oneway void) release
{
if (_retain_count-- == 0)
[self dealloc];
}
- (unsigned) retainCount
{
return _retain_count + 1;
}
- (void) dealloc
{
[_name release];
[super dealloc];
}
- (BOOL)isEqual:other
{
if ([self class] != [other class])
return NO;
if (_object != [other notificationObject])
return NO;
if (_name != [other notificationName] &&
![_name isEqual: [other notificationName]])
return NO;
return YES;
}
- (NSString*) notificationName
{
return _name;
}
- notificationObject
{
return _object;
}
- (void) postNotification: n
{
[self subclassResponsibility: _cmd];
}
@end
@interface NotificationInvocation : NotificationRequest
{
id _invocation;
}
- initWithInvocation: i name: n object: o;
@end
@implementation NotificationInvocation
- initWithInvocation: i name: n object: o
{
[super initWithName: n object: o];
_invocation = [i retain];
return self;
}
- (void) dealloc
{
[_invocation release];
[super dealloc];
}
- (void) postNotification: n
{
[_invocation invokeWithObject: n];
}
@end
@interface NotificationPerformer : NotificationRequest
{
id _target;
SEL _selector;
}
- initWithTarget: t selector: (SEL)s name: n object: o;
@end
@implementation NotificationPerformer
- initWithTarget: t selector: (SEL)s name: n object: o
{
[super initWithName: n object: o];
/* Note that TARGET is not retained. See the comment for
-addObserver... in NotificationDispatcher.h. */
_target = t;
_selector = s;
return self;
}
- (void) postNotification: n
{
[_target performSelector: _selector withObject: n];
}
@end
@implementation NotificationDispatcher
/* The default instance, most often the only one created.
It is accessed by the class methods at the end of this file.
There is no need to mutex locking of this variable. */
static NotificationDispatcher *default_notification_dispatcher = nil;
+ (void) initialize
{
if (self == [NotificationDispatcher class])
default_notification_dispatcher = [self new];
}
/* Initializing. */
- init
{
[super init];
_anonymous_nr_list = [LinkedList new];
/* Use NSNonOwnedPointerOrNullMapKeyCallBacks so we won't retain
the object. We will, however, retain the values, which are
LinkedList's. */
_object_2_nr_list =
NSCreateMapTable (NSNonOwnedPointerOrNullMapKeyCallBacks,
NSObjectMapValueCallBacks, 0);
/* Use NSObjectMapKeyCallBacks so we retain the NAME. We also retain
the values, which are LinkedList's. */
_name_2_nr_list =
NSCreateMapTable (NSObjectMapKeyCallBacks,
NSObjectMapValueCallBacks, 0);
/* Use NSNonOwnedPointerOrNullMapKeyCallBacks so we won't retain
the observer. We will, however, retain the values, which are Array's. */
_observer_2_nr_array =
NSCreateMapTable (NSNonOwnedPointerOrNullMapKeyCallBacks,
NSObjectMapValueCallBacks, 0);
_lock = [NSRecursiveLock new];
return self;
}
- (void) dealloc
{
[_anonymous_nr_list release];
NSFreeMapTable( _object_2_nr_list);
NSFreeMapTable (_name_2_nr_list);
NSFreeMapTable (_observer_2_nr_array);
[_lock release];
[super dealloc];
}
/* Adding new observers. */
/* This is the (private) designated method for adding observers. If we
came from -addInvocation... then OBSERVER is actually an Invocation. */
- (void) _addObserver: observer
notificationRequest: nr
name: (NSString*)name
object: object
{
/* If observer is nil, there is nothing to do; return. */
if (!observer)
return;
[_lock lock];
/* Record the notification request in an array keyed by OBSERVER. */
{
/* Find the array of all the requests by OBSERVER. */
Array *nr_array = NSMapGet (_observer_2_nr_array, observer);
if (!nr_array)
{
nr_array = [Array new];
/* nr_array is retained; observer is not. */
NSMapInsert (_observer_2_nr_array, observer, nr_array);
/* Now that nr_array is retained by the map table, release it;
this way the array will be completely released when the
map table is done with it. */
[nr_array release];
}
/* If the observer is already watching this request, do nothing. */
if ([nr_array containsObject:nr])
{
[_lock unlock];
return;
}
[nr_array appendObject: nr];
}
/* Record the NotificationRequest in one of three MapTable->LinkedLists. */
/* Record the request in one, and only one, LinkedList. The LinkedList
is stored in a hash table accessed by a key. Which key is used
depends on what combination of NAME and OBJECT are non-nil. */
if (!name)
{
if (!object)
{
/* This NotificationRequest will get posted notifications
for all NAME and OBJECT combinations. */
[_anonymous_nr_list appendObject: nr];
}
else
{
LinkedList *nr_list = NSMapGet (_object_2_nr_list, object);
if (!nr_list)
{
nr_list = [LinkedList new];
/* nr_list is retained; object is not retained. */
NSMapInsert (_object_2_nr_list, object, nr_list);
/* Now that nr_list is retained by the map table, release it;
this way the list will be completely released when the
map table is done with it. */
[nr_list release];
}
[nr_list appendObject: nr];
}
}
else
{
LinkedList *nr_list = NSMapGet (_name_2_nr_list, name);
if (!nr_list)
{
nr_list = [LinkedList new];
/* nr_list is retained; object is not retained. */
NSMapInsert (_name_2_nr_list, name, nr_list);
/* Now that nr_list is retained by the map table, release it;
this way the list will be completely released when the
map table is done with it. */
[nr_list release];
}
[nr_list appendObject: nr];
}
[_lock unlock];
}
- (void) addInvocation: (id <Invoking>)invocation
name: (NSString*)name
object: object
{
id nr;
/* Create the NotificationRequest object that will hold this
observation request. This will retain INVOCATION and NAME. */
nr = [[NotificationInvocation alloc]
initWithInvocation: invocation
name: name
object: object];
/* Record it in all the right places. */
[self _addObserver: invocation
notificationRequest: nr
name: name
object: object];
/* Since nr was retained when it was added to the Array and
LinkedList above, we can release it now. */
[nr release];
}
/* For those that want to specify a selector instead of an invocation
as a way to contact the observer. */
- (void) addObserver: observer
selector: (SEL)sel
name: (NSString*)name
object: object
{
id nr;
/* Create the NotificationRequest object that will hold this
observation request. This will retain INVOCATION and NAME. */
nr = [[NotificationPerformer alloc]
initWithTarget: observer
selector: sel
name: name
object: object];
/* Record it in all the right places. */
[self _addObserver: observer
notificationRequest: nr
name: name
object: object];
/* Since nr was retained when it was added to the Array and
LinkedList above, we can release it now. */
[nr release];
}
/* Removing objects. */
/* A private method.
Remove the NR object from its one LinkedList; if this is the last
element of that LinkedList, and the LinkedList is map-accessible,
also release the LinkedList. */
- (void) _removeFromLinkedListNotificationRequest: nr
{
id nr_list = [nr linkedList];
/* See if, instead of removing the NR from its LinkedList, we can
actually release the entire list. */
if ([nr_list count] == 1
&& nr_list != _anonymous_nr_list)
{
id nr_name;
id nr_object;
LinkedList *mapped_nr_list;
NSAssert([nr_list firstObject] == nr, NSInternalInconsistencyException);
if ((nr_name = [nr notificationName]))
{
mapped_nr_list = NSMapGet (_name_2_nr_list, nr_name);
NSAssert(mapped_nr_list == nr_list, NSInternalInconsistencyException);
NSMapRemove (_name_2_nr_list, nr_name);
}
else
{
nr_object = [nr notificationObject];
NSAssert(nr_object, NSInternalInconsistencyException);
mapped_nr_list = NSMapGet (_object_2_nr_list, nr_object);
NSAssert(mapped_nr_list == nr_list, NSInternalInconsistencyException);
NSMapRemove (_object_2_nr_list, nr_object);
}
}
else
[nr_list removeObject: nr];
}
/* Removing notification requests. */
/* Remove all notification requests that would be sent to INVOCATION. */
- (void) removeInvocation: invocation
{
[self removeObserver: invocation];
}
/* Remove the notification requests matching NAME and OBJECT that
would be sent to INVOCATION. As with adding an observation
request, nil NAME or OBJECT act as wildcards. */
- (void) removeInvocation: invocation
name: (NSString*)name
object: object
{
[self removeObserver: invocation
name: name
object: object];
}
/* Remove all records pertaining to OBSERVER. For instance, this
should be called before the OBSERVER is -dealloc'ed. */
- (void) removeObserver: observer
{
Array *observer_nr_array;
NotificationRequest *nr;
/* If OBSERVER is nil, do nothing; just return. NOTE: This *does not*
remove all requests with a nil OBSERVER; it would be too easy to
unintentionally remove other's requests that way. If you need to
remove a request with a nil OBSERVER, use -removeObserver:name:object: */
if (!observer)
return;
[_lock lock];
/* Get the array of NotificationRequest's associated with OBSERVER. */
observer_nr_array = NSMapGet (_observer_2_nr_array, observer);
if (!observer_nr_array)
/* OBSERVER was never registered for any notification requests with us.
Nothing to do. */
return;
/* Remove each of these from it's LinkedList. */
FOR_ARRAY (observer_nr_array, nr)
{
[self _removeFromLinkedListNotificationRequest: nr];
}
END_FOR_ARRAY (observer_nr_array);
/* Remove from the MapTable the list of NotificationRequest's
associated with OBSERVER. This also releases the observer_nr_array,
and its contents. */
NSMapRemove (_observer_2_nr_array, observer);
[_lock unlock];
}
/* Remove the notification requests for the given parameters. As with
adding an observation request, nil NAME or OBJECT act as wildcards. */
- (void) removeObserver: observer
name: (NSString*)name
object: object
{
Array *observer_nr_array;
/* If both NAME and OBJECT are nil, this call is the same as
-removeObserver:, so just call it. */
if (!name && !object)
[self removeObserver: observer];
/* We are now guaranteed that at least one of NAME and OBJECT is non-nil. */
[_lock lock];
/* Get the list of NotificationRequest's associated with OBSERVER. */
observer_nr_array = NSMapGet (_observer_2_nr_array, observer);
if (!observer_nr_array)
/* OBSERVER was never registered for any notification requests with us.
Nothing to do. */
return;
/* Find those NotificationRequest's from the array that
match NAME and OBJECT, and remove them from the array and
their linked list. */
/* xxx If we thought the LinkedList from the map table keyed on NAME
would be shorter, we could use that instead. */
{
NotificationRequest *nr;
int count = [observer_nr_array count];
int i;
for (i = count-1; i >= 0; i--)
{
nr = [observer_nr_array objectAtIndex: i];
if ((!name || [name isEqual: [nr notificationName]])
&& (!object || [object isEqual: [nr notificationObject]]))
{
/* We can remove from the array, even though we are "enumerating"
over it, because we are enumerating from back-to-front,
and the indices of yet-to-come objects don't change when
high-indexed objects are removed. */
[observer_nr_array removeObjectAtIndex: i];
[self _removeFromLinkedListNotificationRequest: nr];
}
}
/* xxx If there are some LinkedList's that are empty, I should
remove them from the map table's. */
}
[_lock unlock];
}
/* Post NOTIFICATION to all the observers that match its NAME and OBJECT. */
- (void) postNotification: notification
{
id notification_name = [(NSNotification *)notification name];
id notification_object = [notification object];
id nr;
LinkedList *nr_list;
NSMutableArray* array;
/* Make sure the notification has a name. */
if (!notification_name)
[NSException raise: NSInvalidArgumentException
format: @"Tried to post a notification with no name."];
[_lock lock];
array = [[NSMutableArray arrayWithCapacity:10] retain];
/* Post the notification to all the observers that specified neither
NAME or OBJECT. */
if ([_anonymous_nr_list count])
{
FOR_COLLECTION (_anonymous_nr_list, nr)
{
[array addObject:nr];
}
END_FOR_COLLECTION (_anonymous_nr_list);
while ([array count] > 0)
{
nr = [array objectAtIndex:0];
if ([nr linkedList] != NO_OBJECT) /* Has request been removed? */
[nr postNotification:notification];
[array removeObjectAtIndex:0];
}
}
/* Post the notification to all the observers that specified OBJECT,
but didn't specify NAME. */
if (notification_object)
{
nr_list = NSMapGet (_object_2_nr_list, notification_object);
if (nr_list)
{
FOR_COLLECTION (nr_list, nr)
{
[array addObject:nr];
}
END_FOR_COLLECTION (nr_list);
while ([array count] > 0)
{
nr = [array objectAtIndex:0];
if ([nr linkedList] != NO_OBJECT) /* Has request been removed? */
[nr postNotification:notification];
[array removeObjectAtIndex:0];
}
}
}
/* Post the notification to all the observers of NAME; (and if the
observer's OBJECT is non-nil, don't send unless the observer's OBJECT
matches the notification's OBJECT). */
nr_list = NSMapGet (_name_2_nr_list, notification_name);
if (nr_list)
{
FOR_COLLECTION (nr_list, nr)
{
id nr_object = [nr notificationObject];
if (!nr_object || nr_object == notification_object)
[array addObject:nr];
}
END_FOR_COLLECTION (nr_list);
while ([array count] > 0)
{
nr = [array objectAtIndex:0];
if ([nr linkedList] != NO_OBJECT) /* Has request been removed? */
[nr postNotification:notification];
[array removeObjectAtIndex:0];
}
}
[array release];
[_lock unlock];
}
- (void) postNotificationName: (NSString*)name
object: object
{
[self postNotification: [NSNotification notificationWithName: name
object: object]];
}
- (void) postNotificationName: (NSString*)name
object: object
userInfo: info
{
[self postNotification: [NSNotification notificationWithName: name
object: object
userInfo: info]];
}
/* Class methods. */
+ defaultInstance
{
return default_notification_dispatcher;
}
+ (void) addInvocation: (id <Invoking>)invocation
name: (NSString*)name
object: object
{
[default_notification_dispatcher addInvocation: invocation
name: name
object: object];
}
+ (void) addObserver: observer
selector: (SEL)sel
name: (NSString*)name
object: object
{
[default_notification_dispatcher addObserver: observer
selector: sel
name: name
object: object];
}
+ (void) removeInvocation: invocation
{
[default_notification_dispatcher removeInvocation: invocation];
}
+ (void) removeInvocation: invocation
name: (NSString*)name
object: object
{
[default_notification_dispatcher removeInvocation: invocation
name: name
object: object];
}
+ (void) removeObserver: observer
{
[default_notification_dispatcher removeObserver: observer];
}
+ (void) removeObserver: observer
name: (NSString*)name
object: object
{
[default_notification_dispatcher removeObserver: observer
name: name
object: object];
}
+ (void) postNotification: notification
{
[default_notification_dispatcher postNotification: notification];
}
+ (void) postNotificationName: (NSString*)name
object: object
{
[default_notification_dispatcher postNotificationName: name
object: object];
}
+ (void) postNotificationName: (NSString*)name
object: object
userInfo: info
{
[default_notification_dispatcher postNotificationName: name
object: object
userInfo: info];
}
@end
@implementation NotificationDispatcher (OpenStepCompat)
/* For OpenStep compatibility. */
+ defaultCenter
{
return default_notification_dispatcher;
}
@end

View file

@ -1,558 +0,0 @@
#if NEW_DO
/* Interface for GNU Objective-C version of NSConnection
Copyright (C) 1997,2000 Free Software Foundation, Inc.
Original by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Version for OPENSTEP by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
Created: August 1997, updated June 2000
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __NSConnection_h_GNUSTEP_BASE_INCLUDE
#define __NSConnection_h_GNUSTEP_BASE_INCLUDE
#include <Foundation/NSObject.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSString.h>
#include <Foundation/NSTimer.h>
#include <Foundation/NSRunLoop.h>
#include <Foundation/NSMapTable.h>
@class NSDistantObject;
@class NSPort;
@class NSPortNameServer;
@class NSData;
/*
* Keys for the NSDictionary returned by [NSConnection -statistics]
*/
/* These in OPENSTEP 4.2 */
GS_EXPORT NSString *NSConnectionRepliesReceived;
GS_EXPORT NSString *NSConnectionRepliesSent;
GS_EXPORT NSString *NSConnectionRequestsReceived;
GS_EXPORT NSString *NSConnectionRequestsSent;
/* These Are GNUstep extras */
GS_EXPORT NSString *NSConnectionLocalCount; /* Objects sent out */
GS_EXPORT NSString *NSConnectionProxyCount; /* Objects received */
/*
* NSConnection class interface.
*
* A few methods are in the specification but not yet implemented.
*/
@interface NSConnection : NSObject
{
@private
BOOL _isValid;
BOOL _independentQueueing;
BOOL _authenticateIn;
BOOL _authenticateOut;
BOOL _multipleThreads;
NSPort *_receivePort;
NSPort *_sendPort;
unsigned _requestDepth;
unsigned _messageCount;
unsigned _reqOutCount;
unsigned _reqInCount;
unsigned _repOutCount;
unsigned _repInCount;
#ifndef _IN_CONNECTION_M
#define GSIMapTable void*
#endif
GSIMapTable _localObjects;
GSIMapTable _localTargets;
GSIMapTable _remoteProxies;
GSIMapTable _replyMap;
#ifndef _IN_CONNECTION_M
#undef GSIMapTable
#endif
NSTimeInterval _replyTimeout;
NSTimeInterval _requestTimeout;
NSMutableArray *_requestModes;
NSMutableArray *_runLoops;
NSMutableArray *_requestQueue;
id _delegate;
NSRecursiveLock *_refGate;
NSMutableArray *_cachedDecoders;
NSMutableArray *_cachedEncoders;
NSString *_registeredName;
NSPortNameServer *_nameServer;
}
+ (NSArray*) allConnections;
+ (NSConnection*) connectionWithReceivePort: (NSPort*)r
sendPort: (NSPort*)s;
+ (NSConnection*) connectionWithRegisteredName: (NSString*)n
host: (NSString*)h;
+ (NSConnection*) connectionWithRegisteredName: (NSString*)n
host: (NSString*)h
usingNameServer: (NSPortNameServer*)s;
+ (id) currentConversation;
+ (NSConnection*) defaultConnection;
+ (NSDistantObject*) rootProxyForConnectionWithRegisteredName: (NSString*)name
host: (NSString*)host;
+ (NSDistantObject*) rootProxyForConnectionWithRegisteredName: (NSString*)name
host: (NSString*)host usingNameServer: (NSPortNameServer*)s;
- (void) addRequestMode: (NSString*)mode;
- (void) addRunLoop: (NSRunLoop*)runloop;
- (id) delegate;
- (void) enableMultipleThreads;
- (BOOL) independentConversationQueueing;
- (id) initWithReceivePort: (NSPort*)r
sendPort: (NSPort*)s;
- (void) invalidate;
- (BOOL) isValid;
- (NSArray*)localObjects;
- (BOOL) multipleThreadsEnabled;
- (NSPort*) receivePort;
- (BOOL) registerName: (NSString*)name;
- (BOOL) registerName: (NSString*)name withNameServer: (NSPortNameServer*)svr;
- (NSArray*) remoteObjects;
- (void) removeRequestMode: (NSString*)mode;
- (void) removeRunLoop: (NSRunLoop *)runloop;
- (NSTimeInterval) replyTimeout;
- (NSArray*) requestModes;
- (NSTimeInterval) requestTimeout;
- (id) rootObject;
- (NSDistantObject*) rootProxy;
- (void) runInNewThread;
- (NSPort*) sendPort;
- (void) setDelegate: anObj;
- (void) setIndependentConversationQueueing: (BOOL)flag;
- (void) setReplyTimeout: (NSTimeInterval)seconds;
- (void) setRequestMode: (NSString*)mode;
- (void) setRequestTimeout: (NSTimeInterval)seconds;
- (void) setRootObject: anObj;
- (NSDictionary*) statistics;
@end
/*
* This catagory contains legacy methods from the original GNU 'Connection'
* class, and useful extensions to NSConnection.
*/
@interface NSConnection (GNUstepExtensions) <GCFinalization>
+ (NSConnection*) newRegisteringAtName: (NSString*)n
withRootObject: (id)anObject;
- (void) gcFinalize;
- (retval_t) forwardForProxy: (NSDistantObject*)object
selector: (SEL)sel
argFrame: (arglist_t)frame;
- (const char *) typeForSelector: (SEL)sel remoteTarget: (unsigned)target;
@end
GS_EXPORT NSString *ConnectionBecameInvalidNotification;
@interface Object (NSConnectionDelegate)
/*
* This method may be used to ask a delegates permission to create
* a new connection from the old one.
* This method should be implemented in preference to the
* [makeNewConnection:sender:] which is obsolete.
*/
- (BOOL) connection: (NSConnection*)parent
shouldMakeNewConnection: (NSConnection*)newConnection;
/*
* This is the old way of doing the same thing as
* [connection:shouldMakeNewConnection:]
* It is obsolete - don't use it.
*/
- (BOOL) makeNewConnection: (NSConnection*)newConnection
sender: (NSConnection*)parent;
/*
* If the delegate responds to this method, it will be used to ask the
* delegate's permission to establish a new connection from the old one.
* Often this is used so that the delegate can register for invalidation
* notification on new child connections.
* This is a GNUstep extension
* Normally return newConn.
*/
- (NSConnection*) connection: (NSConnection*)ancestorConn
didConnect: (NSConnection*)newConn;
/*
* These are like the MacOS-X delegate methods, except that we provide the
* components in mutable arrays, so that the delegate can alter the data
* items in the array. Of course, you must do that WITH CARE.
*/
- (BOOL) authenticateComponents: (NSMutableArray*)components
withData: (NSData*)authenticationData;
- (NSData*) authenticationDataForComponents: (NSMutableArray*)components;
@end
@interface Object (NSPortCoder)
- (Class) classForPortCoder;
/*
* Must return the class that will be created on the remote side
* of the connection. If the class to be created is not the same
* as that of the object returned by replacementObjectForPortCoder:
* then the class must be capable of recognising the object it
* actually gets in its initWithCoder: method.
* The default operation is to return NSDistantObject unless the
* object is being sent bycopy, in which case the objects actual
* class is returned. To force bycopy operation the object should
* return its own class.
*/
- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder;
/*
* This message is sent to an object about to be encoded for sending
* over the wire. The default action is to return an NSDistantObject
* which is a local proxy for the object unless the object is being
* sent bycopy, in which case the actual object is returned.
* To force bycopy, an object should return itsself.
*/
@end
#define CONNECTION_DEFAULT_TIMEOUT 15.0 /* in seconds */
/*
* NSRunLoop mode, NSNotification name and NSException strings.
*/
GS_EXPORT NSString *NSConnectionReplyMode;
GS_EXPORT NSString *NSConnectionDidDieNotification;
GS_EXPORT NSString *NSConnectionDidInitializeNotification; /* OPENSTEP */
GS_EXPORT NSString *NSFailedAuthenticationException; /* MacOS-X */
#endif /* __NSConnection_h_GNUSTEP_BASE_INCLUDE */
#else
/* Interface for GNU Objective-C version of NSConnection
Copyright (C) 1997 Free Software Foundation, Inc.
Original by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Version for OPENSTEP by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
Created: August 1997
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __NSConnection_h_GNUSTEP_BASE_INCLUDE
#define __NSConnection_h_GNUSTEP_BASE_INCLUDE
#include <Foundation/NSObject.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSString.h>
#include <Foundation/NSTimer.h>
#include <Foundation/NSRunLoop.h>
#include <Foundation/NSMapTable.h>
@class NSDistantObject;
@class NSPort;
@class NSData;
/*
* Keys for the NSDictionary returned by [NSConnection -statistics]
*/
/* These in OPENSTEP 4.2 */
GS_EXPORT NSString *NSConnectionRepliesReceived;
GS_EXPORT NSString *NSConnectionRepliesSent;
GS_EXPORT NSString *NSConnectionRequestsReceived;
GS_EXPORT NSString *NSConnectionRequestsSent;
/* These Are GNUstep extras */
GS_EXPORT NSString *NSConnectionLocalCount; /* Objects sent out */
GS_EXPORT NSString *NSConnectionProxyCount; /* Objects received */
/*
* NSConnection class interface.
*
* A few methods are in the specification but not yet implemented.
*/
@interface NSConnection : NSObject
{
@private
BOOL is_valid;
BOOL independent_queueing;
unsigned request_depth;
NSPort *receive_port;
NSPort *send_port;
unsigned message_count;
unsigned req_out_count;
unsigned req_in_count;
unsigned rep_out_count;
unsigned rep_in_count;
NSMapTable *local_objects;
NSMapTable *local_targets;
NSMapTable *remote_proxies;
NSTimeInterval reply_timeout;
NSTimeInterval request_timeout;
Class receive_port_class;
Class send_port_class;
Class encoding_class;
id delegate;
NSMutableArray *request_modes;
}
+ (NSArray*) allConnections;
+ (NSConnection*) connectionWithRegisteredName: (NSString*)n
host: (NSString*)h;
+ (id)currentConversation;
+ (NSConnection*) defaultConnection;
+ (NSDistantObject*) rootProxyForConnectionWithRegisteredName: (NSString*)name
host: (NSString*)host;
- (void) addRequestMode: (NSString*)mode;
- (void) addRunLoop: (NSRunLoop *)runloop;
- (id) delegate;
- (void) enableMultipleThreads;
- (BOOL) multipleThreadsEnabled;
- (BOOL) independentConversationQueueing;
- (void) invalidate;
- (BOOL) isValid;
- (BOOL) registerName: (NSString*)name;
- (NSArray *) remoteObjects;
- (void) removeRequestMode: (NSString*)mode;
- (void) removeRunLoop: (NSRunLoop *)runloop;
- (NSTimeInterval) replyTimeout;
- (NSArray*) requestModes;
- (NSTimeInterval) requestTimeout;
- (id) rootObject;
- (NSDistantObject*) rootProxy;
- (void) setDelegate: anObj;
- (void) setIndependentConversationQueueing: (BOOL)flag;
- (void) setReplyTimeout: (NSTimeInterval)seconds;
- (void) setRequestMode: (NSString*)mode;
- (void) setRequestTimeout: (NSTimeInterval)seconds;
- (void) setRootObject: anObj;
- (NSDictionary*) statistics;
@end
/*
* This catagory contains methods which were not in the original
* OpenStep specification, but which are in OPENSTEP.
* Some methods are not yet implemented.
*/
@interface NSConnection (OPENSTEP)
+ (NSConnection*) connectionWithReceivePort: (NSPort*)r
sendPort: (NSPort*)s;
- initWithReceivePort: (NSPort*)r
sendPort: (NSPort*)s;
- (NSPort*) receivePort;
- (void) runInNewThread;
- (NSPort*) sendPort;
@end
/*
* This catagory contains legacy methods from the original GNU 'Connection'
* class, and useful extensions to NSConnection.
*/
@interface NSConnection (GNUstepExtensions) <GCFinalization>
- (void) gcFinalize;
/* Setting and getting class configuration */
+ (Class) defaultReceivePortClass;
+ (void) setDefaultReceivePortClass: (Class) aPortClass;
+ (Class) defaultSendPortClass;
+ (void) setDefaultSendPortClass: (Class) aPortClass;
+ (Class) defaultProxyClass;
+ (void) setDefaultProxyClass: (Class) aClass;
+ (int) defaultOutTimeout;
+ (void) setDefaultOutTimeout: (int)to;
+ (int) defaultInTimeout;
+ (void) setDefaultInTimeout: (int)to;
/* Querying the state of all the connections */
+ (int) messagesReceived;
+ (unsigned) connectionsCount;
+ (unsigned) connectionsCountWithInPort: (NSPort*)aPort;
/* Registering your server object on the network.
These methods create a new connection object that must be "run" in order
to start handling requests from clients.
These method names may change when we get the capability to register
ports with names after the ports have been created. */
/* I want the second method name to clearly indicate that we're not
connecting to a pre-existing registration name, we're registering a
new name, and this method will fail if that name has already been
registered. This is why I don't like "newWithRegisteredName:" ---
it's unclear if we're connecting to another NSConnection that already
registered with that name. */
+ (NSConnection*) newWithRootObject: anObj;
+ (NSConnection*) newRegisteringAtName: (NSString*)n
withRootObject: anObj;
+ (NSConnection*) newRegisteringAtName: (NSString*)n
atPort: (int)portn
withRootObject: anObj;
+ (NSConnection*) connectionByOutPort: (NSPort*)aPort;
/* Get a proxy to a remote server object.
A new connection is created if necessary. */
+ (NSDistantObject*) rootProxyAtName: (NSString*)name onHost: (NSString*)host;
+ (NSDistantObject*) rootProxyAtName: (NSString*)name;
+ (NSDistantObject*) rootProxyAtPort: (NSPort*)anOutPort;
+ (NSDistantObject*) rootProxyAtPort: (NSPort*)anOutPort withInPort: (NSPort*)anInPort;
/* This is the designated initializer for the NSConnection class.
You don't need to call it yourself. */
+ (NSConnection*) newForInPort: (NSPort*)anInPort outPort: (NSPort*)anOutPort
ancestorConnection: (NSConnection*)ancestor;
/* Make a connection object start listening for incoming requests. After
after DATE. */
- (void) runConnectionUntilDate: date;
/* Same as above, but never time out. */
- (void) runConnection;
/* When you get an invalidation notification from a connection, use
this method in order to find out if any of the proxy objects you're
using are going away. */
- (id) proxies;
/* For getting the root object of a connection or port */
+ rootObjectForInPort: (NSPort*)aPort;
/* Used for setting the root object of a connection that we
created without one, or changing the root object of a connection
that already has one. */
+ (void) setRootObject: anObj forInPort: (NSPort*)aPort;
/* Querying and setting some instance variables */
- (Class) receivePortClass;
- (Class) sendPortClass;
- (void) setReceivePortClass: (Class)aPortClass;
- (void) setSendPortClass: (Class)aPortClass;
- (Class) proxyClass;
- (Class) encodingClass;
- (Class) decodingClass;
/* Only subclassers and power-users need worry about these */
- (void) addProxy: (NSDistantObject*)aProxy;
- (id) includesProxyForTarget: (gsu32)target;
- (void) removeProxy: (NSDistantObject*)aProxy;
// It seems to be a non pure-OPENSTEP definition...
//
// new def :
- (NSArray*)localObjects;
- (void) addLocalObject: anObj;
- (id) includesLocalObject: anObj;
- (void) removeLocalObject: anObj;
- (retval_t) forwardForProxy: (NSDistantObject*)object
selector: (SEL)sel
argFrame: (arglist_t)frame;
- (const char *) typeForSelector: (SEL)sel remoteTarget: (unsigned)target;
@end
GS_EXPORT NSString *ConnectionBecameInvalidNotification;
@interface Object (NSConnectionDelegate)
- (BOOL) connection: (NSConnection*)parent
shouldMakeNewConnection: (NSConnection*)newConnection;
/*
* This method may be used to ask a delegates permission to create
* a new connection from the old one.
* This method should be implemented in preference to the
* [makeNewConnection:sender:] which is obsolete.
*/
- (BOOL) makeNewConnection: (NSConnection*)newConnection
sender: (NSConnection*)parent;
/*
* This is the old way of doing the same thing as
* [connection:shouldMakeNewConnection:]
* It is obsolete - don't use it.
*/
- (NSConnection*) connection: ancestorConn didConnect: newConn;
/*
* If the delegate responds to this method, it will be used to ask the
* delegate's permission to establish a new connection from the old one.
* Often this is used so that the delegate can register for invalidation
* notification on new child connections.
* This is a GNUstep extension
* Normally return newConn.
*/
@end
@interface Object (NSPortCoder)
- (Class) classForPortCoder;
/*
* Must return the class that will be created on the remote side
* of the connection. If the class to be created is not the same
* as that of the object returned by replacementObjectForPortCoder:
* then the class must be capable of recognising the object it
* actually gets in its initWithCoder: method.
* The default operation is to return NSDistantObject unless the
* object is being sent bycopy, in which case the objects actual
* class is returned. To force bycopy operation the object should
* return its own class.
*/
- (id) replacementObjectForPortCoder: (NSPortCoder*)aCoder;
/*
* This message is sent to an object about to be encoded for sending
* over the wire. The default action is to return an NSDistantObject
* which is a local proxy for the object unless the object is being
* sent bycopy, in which case the actual object is returned.
* To force bycopy, an object should return itsself.
*/
- (BOOL)authenticateComponents: (NSArray *)components
withData: (NSData *)authenticationData;
- (NSData *)authenticationDataForComponents: (NSArray *)components;
@end
#define CONNECTION_DEFAULT_TIMEOUT 15.0 /* in seconds */
/*
* NSRunLoop mode, NSNotification name and NSException strings.
*/
GS_EXPORT NSString *NSConnectionReplyMode;
GS_EXPORT NSString *NSConnectionDidDieNotification;
GS_EXPORT NSString *NSConnectionDidInitializeNotification; /* OPENSTEP */
/*
* For compatibility with old GNU DO code -
*/
#define RunLoopConnectionReplyMode NSConnectionReplyMode
#define ConnectionBecameInvalidNotification NSConnectionDidDieNotification
#define ConnectionWasCreatedNotification NSConnectionDidInitializeNotification
#endif /* __NSConnection_h_GNUSTEP_BASE_INCLUDE */
#endif

File diff suppressed because it is too large Load diff

View file

@ -1,147 +0,0 @@
/* Interface for NSPortCoder object for distributed objects
Copyright (C) 2000 Free Software Foundation, Inc.
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
Date: June 2000
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __NSPortCoder_h
#define __NSPortCoder_h
#include <Foundation/NSCoder.h>
@class NSMutableArray;
@class NSMutableDictionary;
@class NSConnection;
@class NSPort;
@interface NSPortCoder : NSCoder
{
@private
NSMutableArray *_comp;
NSConnection *_conn;
BOOL _is_by_copy;
BOOL _is_by_ref;
// Encoding
BOOL _encodingRoot;
BOOL _initialPass;
id _dst; /* Serialization destination. */
IMP _eObjImp; /* Method to encode an id. */
IMP _eValImp; /* Method to encode others. */
#ifndef _IN_PORT_CODER_M
#define GSIMapTable void*
#endif
GSIMapTable _clsMap; /* Class cross references. */
GSIMapTable _cIdMap; /* Conditionally coded. */
GSIMapTable _uIdMap; /* Unconditionally coded. */
GSIMapTable _ptrMap; /* Constant pointers. */
#ifndef _IN_PORT_CODER_M
#undef GSIMapTable
#endif
unsigned _xRefC; /* Counter for cross-reference. */
unsigned _xRefO; /* Counter for cross-reference. */
unsigned _xRefP; /* Counter for cross-reference. */
// Decoding
id _src; /* Deserialization source. */
IMP _dDesImp; /* Method to deserialize with. */
void (*_dTagImp)(id,SEL,unsigned char*,unsigned*,unsigned*);
IMP _dValImp; /* Method to decode data with. */
#ifndef _IN_PORT_CODER_M
#define GSIArray void*
#endif
GSIArray _clsAry; /* Class crossreference map. */
GSIArray _objAry; /* Object crossreference map. */
GSIArray _ptrAry; /* Pointer crossreference map. */
#ifndef _IN_PORT_CODER_M
#undef GSIArray
#endif
NSMutableDictionary *_cInfo; /* Class version information. */
unsigned _cursor; /* Position in data buffer. */
unsigned _version; /* Version of archiver used. */
NSZone *_zone; /* Zone for allocating objs. */
}
+ (NSPortCoder*) portCoderWithReceivePort: (NSPort*)recv
sendPort: (NSPort*)send
components: (NSArray*)comp;
- (id) initWithReceivePort: (NSPort*)recv
sendPort: (NSPort*)send
components: (NSArray*)comp;
- (NSConnection*) connection;
- (NSPort*) decodePortObject;
- (void) dispatch;
- (void) encodePortObject: (NSPort*)aPort;
- (BOOL) isBycopy;
- (BOOL) isByref;
@end
@interface NSPortCoder (Private)
- (NSMutableArray*) _components;
@end
#endif /* __NSPortCoder_h */
#else
/* Interface for NSPortCoder object for distributed objects
Copyright (C) 1997 Free Software Foundation, Inc.
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
Date: August 1997
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __NSPortCoder_h
#define __NSPortCoder_h
#include <Foundation/NSCoder.h>
@class NSConnection;
@class NSPort;
@interface NSPortCoder : NSCoder
{
}
- (NSConnection*) connection;
- (NSPort*) decodePortObject;
- (void) encodePortObject: (NSPort*)aPort;
- (BOOL) isBycopy;
- (BOOL) isByref;
@end
#endif /* __NSPortCoder_h */

File diff suppressed because it is too large Load diff

View file

@ -1,65 +0,0 @@
/* Protocol for Objective-C objects that hold elements, user gets to set order
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: Feb 1996
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/* The <OrderedCollecting> protocol inherits from the
<KeyedCollecting> protocol.
The <OrderedCollecting> protocol defines the interface to a
collection of elements that are accessible by a key that is an index,
where the indeces in a collection are a contiguous series of unsigned
integers beginning at 0. This is the root of the protocol heirarchy
for all collections that hold their elements in some order. Elements
may be accessed, inserted, replaced and removed by their index.
*/
#ifndef __OrderedCollecting_h_GNUSTEP_BASE_INCLUDE
#define __OrderedCollecting_h_GNUSTEP_BASE_INCLUDE
#include <base/IndexedCollecting.h>
@protocol OrderedCollecting <IndexedCollecting>
// ADDING;
- (void) insertObject: newObject atIndex: (unsigned)index;
- (void) insertObject: newObject before: oldObject;
- (void) insertObject: newObject after: oldObject;
- (void) insertContentsOf: (id <ConstantCollecting>)aCollection
atIndex: (unsigned)index;
- (void) appendObject: newObject;
- (void) prependObject: newObject;
- (void) appendContentsOf: (id <ConstantCollecting>)aCollection;
- (void) prependContentsOf: (id <ConstantCollecting>)aCollection;
// SWAPPING AND SORTING
- (void) swapAtIndeces: (unsigned)index1 : (unsigned)index2;
- (void) sortContents;
// REPLACING;
- (void) replaceRange: (IndexRange)aRange
with: (id <ConstantCollecting>)aCollection;
- replaceRange: (IndexRange)aRange
using: (id <ConstantCollecting>)aCollection;
@end
#endif /* __OrderedCollecting_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,38 +0,0 @@
/* Interface for Objective-C Ordered Collection object.
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: February 1996
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __OrderedCollection_h_GNUSTEP_BASE_INCLUDE
#define __OrderedCollection_h_GNUSTEP_BASE_INCLUDE
#include <base/IndexedCollection.h>
#include <base/OrderedCollecting.h>
@interface OrderedCollection : IndexedCollection
@end
/* Put this on category instead of class to avoid bogus complaint from gcc */
@interface OrderedCollection (Protocol) <OrderedCollecting>
@end
#endif /* __OrderedCollection_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,265 +0,0 @@
/* Implementation for Objective-C OrderedCollection object
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: Feb 1996
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/OrderedCollection.h>
#include <stdio.h>
#include <base/Array.h>
#include <base/NSString.h>
#include <Foundation/NSException.h>
@implementation OrderedCollection
// ADDING;
- (void) insertObject: newObject atIndex: (unsigned)index
{
[self subclassResponsibility: _cmd];
}
- (void) insertObject: newObject before: oldObject
{
int i = [self indexOfObject: oldObject];
[self insertObject: newObject atIndex: i];
}
- (void) insertObject: newObject after: oldObject
{
int i = [self indexOfObject: oldObject];
[self insertObject: newObject atIndex: i+1];
}
- (void) insertContentsOf: (id <ConstantCollecting>) aCollection
atIndex: (unsigned)index
{
[self notImplemented: _cmd];
#if 0
void doIt(elt e)
{
[self insertElement: e atIndex: index];
}
if (aCollection == self)
[self safeWithElementsInReverseCall:doIt];
else
{
if ([(id)aCollection respondsToSelector:
@selector(withElemetnsInReverseCall:)])
[(id)aCollection withElementsInReverseCall:doIt];
else
[aCollection withElementsCall:doIt];
}
#endif
}
- (void) appendObject: newObject
{
[self insertObject: newObject atIndex: [self count]];
}
- (void) prependObject: newObject
{
[self insertObject: newObject atIndex: 0];
}
- (void) appendContentsOf: (id <ConstantCollecting>) aCollection
{
id o;
NSAssert(aCollection != self, NSInvalidArgumentException);
/* xxx Could be more efficient. */
FOR_COLLECTION(aCollection, o)
{
[self appendObject: o];
}
END_FOR_COLLECTION(aCollection);
}
- (void) prependContentsOf: (id <ConstantCollecting>)aCollection
{
id o;
NSAssert(aCollection != self, NSInvalidArgumentException);
if ([(id)aCollection conformsTo: @protocol(IndexedCollecting)])
{
FOR_INDEXED_COLLECTION_REVERSE(self, o)
{
[self prependObject: o];
}
END_FOR_INDEXED_COLLECTION_REVERSE(self);
}
else
{
FOR_COLLECTION(self, o)
{
[self prependObject: o];
}
END_FOR_COLLECTION(self);
}
}
// SWAPPING AND SORTING;
- (void) swapAtIndeces: (unsigned)index1 : (unsigned)index2
{
id tmp = [self objectAtIndex:index1];
[self replaceObjectAtIndex: index1 with: [self objectAtIndex: index2]];
[self replaceObjectAtIndex: index2 with: tmp];
}
/* This could be hacked a bit to make it more efficient */
- (void) quickSortContentsFromIndex: (unsigned)p
toIndex: (unsigned)r
{
unsigned i ,j;
id x;
if (p < r)
{
/* Partition */
x = [self objectAtIndex:p];
i = p - 1;
j = r + 1;
for (;;)
{
do
j = j - 1;
while ([[self objectAtIndex: j] compare: x] > 0);
do
i = i + 1;
while ([[self objectAtIndex: i] compare: x] < 0);
if (i < j)
[self swapAtIndeces: i : j];
else
break;
}
/* Sort partitions */
[self quickSortContentsFromIndex: p toIndex: j];
[self quickSortContentsFromIndex: j+1 toIndex: r];
}
}
- (void) sortContents
{
[self quickSortContentsFromIndex: 0 toIndex: [self count]-1];
}
// REPLACING;
- (void) replaceRange: (IndexRange)aRange
withCollection: (id <ConstantCollecting>)aCollection
{
[self notImplemented: _cmd];
}
- (void) replaceRange: (IndexRange)aRange
usingCollection: (id <ConstantCollecting>)aCollection
{
[self notImplemented: _cmd];
}
#if 0
- replaceRange: (IndexRange)aRange
with: (id <Collecting>)aCollection
{
CHECK_INDEX_RANGE_ERROR(aRange.location, [self count]);
CHECK_INDEX_RANGE_ERROR(aRange.location+aRange.length-1, [self count]);
[self removeRange:aRange];
[self insertContentsOf:aCollection atIndex:aRange.location];
return self;
}
- replaceRange: (IndexRange)aRange
using: (id <Collecting>)aCollection
{
int i;
void *state = [aCollection newEnumState];
elt e;
CHECK_INDEX_RANGE_ERROR(aRange.location, [self count]);
CHECK_INDEX_RANGE_ERROR(aRange.location+aRange.length-1, [self count]);
for (i = aRange.location;
i < aRange.location + aRange.length
&& [aCollection getNextElement:&e withEnumState:&state];
i++)
{
[self replaceElementAtIndex:i with:e];
}
[aCollection freeEnumState:&state];
return self;
}
#endif
// OVERRIDE SOME COLLECTION METHODS;
- (void) addObject: newObject
{
[self appendObject: newObject];
}
- (void) addContentsOf: (id <Collecting>)aCollection
{
[self appendContentsOf: aCollection];
}
#if 0
// OVERRIDE SOME KEYED COLLECTION METHODS;
/* Semantics: You can "put" an element only at index "count" or less */
- (void) putObject: newObject atIndex: (unsigned)index
{
unsigned c = [self count];
if (index < c)
[self replaceObjectAtIndex: index withObject: newObject];
else if (index == c)
[self appendObject: newObject];
else
[NSException
raise: NSRangeException
format: @"in %s, can't put an element at index beyond [self count]"];
}
- putObject: newObject atKey: index
{
return [self putObject: newObject atIndex: [index unsignedIntValue]];
}
#endif
// OVERRIDE SOME INDEXED COLLECTION METHODS;
/* Should be more efficiently overriden by some subclasses. */
- (void) replaceObjectAtIndex: (unsigned)index withObject: newObject
{
[self removeObjectAtIndex: index];
[self insertObject: newObject atIndex: index];
}
@end

View file

@ -1,47 +0,0 @@
/* Protocol for Objective-C objects that can be ordered.
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Ordering_h_GNUSTEP_BASE_INCLUDE
#define __Ordering_h_GNUSTEP_BASE_INCLUDE
#include <objc/objc.h>
#include <Foundation/NSObject.h>
@protocol Ordering
- (int) compare: anObject;
- (BOOL) greaterThan: anObject;
- (BOOL) greaterThanOrEqual: anObject;
- (BOOL) lessThan: anObject;
- (BOOL) lessThanOrEqual: anObject;
- (BOOL) between: firstObject and: secondObject;
- maximum: anObject;
- minimum: anObject;
@end
#endif /* __Ordering_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,119 +0,0 @@
/* Interface for abstract superclass port for use with Connection
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: July 1994
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Port_h_GNUSTEP_BASE_INCLUDE
#define __Port_h_GNUSTEP_BASE_INCLUDE
#include <base/Coding.h>
#include <base/MemoryStream.h>
#include <Foundation/NSPort.h>
#include <Foundation/NSDate.h>
#include <Foundation/NSString.h>
/* xxx Use something like this? */
@protocol PacketSending
@end
@interface Port : NSPort
{
}
- (void) close;
+ (Class) outPacketClass;
- (Class) outPacketClass;
@end
@interface InPort : Port
{
id _packet_invocation;
}
+ newForReceiving;
+ newForReceivingFromRegisteredName: (NSString*)name;
+ newForReceivingFromRegisteredName: (NSString*)name fromPort: (int)port;
/* Register/Unregister this port for input handling through RunLoop
RUN_LOOP in mode MODE. */
- (void) addToRunLoop: run_loop forMode: (NSString*)mode;
- (void) removeFromRunLoop: run_loop forMode: (NSString*)mode;
/* When a RunLoop is handling this InPort, and a new incoming
packet arrives, INVOCATION will be invoked with the new packet
as an argument. The INVOCATION is responsible for releasing
the packet. */
- (void) setReceivedPacketInvocation: (id)invocation;
/* An alternative to the above way for receiving packets from this port.
Get a packet from the net and return it. If no packet is received
within MILLISECONDS, then return nil. The caller is responsible
for releasing the packet. */
- receivePacketWithTimeout: (int)milliseconds;
@end
@interface OutPort : Port
+ newForSendingToRegisteredName: (NSString*)name
onHost: (NSString*)hostname;
- (BOOL) sendPacket: packet timeout: (NSTimeInterval)t;
@end
/* Objects for holding incoming/outgoing data to/from ports. */
@interface InPacket : MemoryStream
{
id _receiving_in_port;
id _reply_out_port;
}
- replyOutPort;
- receivingInPort;
/* Do not call this method yourself; it is to be called by subclassers.
InPackets are created for you by the InPort object, and are
made available as the argument to the received packet invocation. */
- initForReceivingWithCapacity: (unsigned)s
receivingInPort: ip
replyOutPort: op;
@end
@interface OutPacket : MemoryStream
{
id _reply_in_port;
}
- initForSendingWithCapacity: (unsigned)c
replyInPort: p;
- replyInPort;
+ (unsigned) prefixSize;
@end
#endif /* __Port_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,210 +0,0 @@
/* Implementation of abstract superclass port for use with Connection
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: July 1994
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/Port.h>
#include <base/Coder.h> /* for Coding protocol in Object category */
#include <Foundation/NSNotification.h>
#include <Foundation/NSException.h>
@implementation Port
/* This is the designated initializer. */
- init
{
[super init];
_is_valid = YES;
return self;
}
- (void) close
{
[self invalidate];
}
+ (Class) outPacketClass
{
[self subclassResponsibility: _cmd];
return nil;
}
- (Class) outPacketClass
{
[self subclassResponsibility: _cmd];
return nil;
}
- (Class) classForPortCoder
{
/* Make sure that Connection's always send us bycopy,
i.e. as our own class, not a Proxy class. */
return [self class];
}
- replacementObjectForPortCoder: aRmc
{
return self;
}
- (void) encodeWithCoder: (id <Encoding>)anEncoder
{
[super encodeWithCoder: anEncoder];
/* xxx What else? */
}
- initWithCoder: (id <Decoding>)coder
{
self = [super initWithCoder: coder];
/* xxx What else? */
return self;
}
@end
@implementation InPort
- init
{
[super init];
_packet_invocation = nil;
return self;
}
+ newForReceivingFromRegisteredName: (NSString*)name fromPort: (int)port
{
[self subclassResponsibility:_cmd];
return nil;
}
+ newForReceivingFromRegisteredName: (NSString*)name
{
[self subclassResponsibility:_cmd];
return nil;
}
+ newForReceiving
{
return [self newForReceivingFromRegisteredName: nil];
}
- receivePacketWithTimeout: (int)milliseconds
{
[self subclassResponsibility:_cmd];
return nil;
}
- (void) setReceivedPacketInvocation: (id)invocation
{
NSAssert(!_packet_invocation, NSInternalInconsistencyException);
_packet_invocation = invocation;
}
- (void) addToRunLoop: run_loop forMode: (NSString*)mode
{
[self subclassResponsibility:_cmd];
}
- (void) removeFromRunLoop: run_loop forMode: (NSString*)mode
{
[self subclassResponsibility:_cmd];
}
@end
@implementation OutPort
+ newForSendingToRegisteredName: (NSString*)name
onHost: (NSString*)hostname
{
[self subclassResponsibility:_cmd];
return nil;
}
- (BOOL) sendPacket: packet timeout: (NSTimeInterval)t
{
[self subclassResponsibility:_cmd];
return NO;
}
@end
@implementation InPacket
/* The designated initializer. */
- initForReceivingWithCapacity: (unsigned)c
receivingInPort: ip
replyOutPort: op
{
self = [super initWithCapacity: c prefix: 0];
if (self)
{
NSAssert([op isValid], NSInternalInconsistencyException);
NSAssert(!ip || [ip isValid], NSInternalInconsistencyException);
_reply_out_port = op;
_receiving_in_port = ip;
}
return self;
}
- replyOutPort
{
return _reply_out_port;
}
- receivingInPort
{
return _receiving_in_port;
}
@end
@implementation OutPacket
/* The designated initializer. */
- initForSendingWithCapacity: (unsigned)c
replyInPort: ip
{
self = [super initWithCapacity: c prefix: [[self class] prefixSize]];
if (self)
{
NSAssert([ip isValid], NSInternalInconsistencyException);
_reply_in_port = ip;
}
return self;
}
+ (unsigned) prefixSize
{
return 0;
}
- replyInPort
{
return _reply_in_port;
}
@end

View file

@ -1,36 +0,0 @@
/* Interface for Objective-C Queue object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Queue_h_GNUSTEP_BASE_INCLUDE
#define __Queue_h_GNUSTEP_BASE_INCLUDE
#include <base/CircularArray.h>
@interface Queue : CircularArray
- (void) enqueueObject: newObject;
- dequeueObject;
@end
#endif /* __Queue_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,48 +0,0 @@
/* Implementation for Objective-C Queue object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/Queue.h>
#include <base/ArrayPrivate.h>
@implementation Queue
- (void) enqueueObject: newObject
{
[self prependObject: newObject];
}
- dequeueObject
{
id ret = [[self lastObject] retain];
[self removeLastObject];
return [ret autorelease];
}
/* Overriding */
- (void) addObject: newObject
{
[self enqueueObject: newObject];
}
@end

View file

@ -1,39 +0,0 @@
/* Interface for Objective-C Red-Black Tree collection object
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __RBTree_h_GNUSTEP_BASE_INCLUDE
#define __RBTree_h_GNUSTEP_BASE_INCLUDE
#include <base/BinaryTree.h>
@protocol RBTreeComprising <BinaryTreeComprising>
- (BOOL) isRed;
- setRed;
- setBlack;
@end
@interface RBTree : BinaryTree
@end
#endif /* __RBTree_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,250 +0,0 @@
/* Implementation for Objective-C Red-Black Tree collection object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/RBTree.h>
#include <base/IndexedCollectionPrivate.h>
#include <base/RBTreeNode.h>
#define NODE_IS_RED(NODE) ([NODE isRed])
#define NODE_IS_BLACK(NODE) (![NODE isRed])
/* sentinal */
static id nilRBNode;
@implementation RBTree
+ (void) initialize
{
if (self == [RBTree class])
{
nilRBNode = [[RBTreeNode alloc] init];
[nilRBNode setBlack];
}
}
- nilNode
{
return nilRBNode;
}
- (void) sortAddObject: newObject
{
id y;
[super sortAddObject: newObject];
[newObject setRed];
while (newObject != _contents_root
&& [[newObject parentNode] isRed])
{
if ([newObject parentNode] ==
[[[newObject parentNode] parentNode] leftNode])
{
y = [[[newObject parentNode] parentNode] leftNode];
if ([y isRed])
{
[[newObject parentNode] setBlack];
[y setBlack];
[[[newObject parentNode] parentNode] setRed];
newObject = [[newObject parentNode] parentNode];
}
else
{
if (newObject == [[newObject parentNode] rightNode])
{
newObject = [newObject parentNode];
[self leftRotateAroundNode:newObject];
}
[[newObject parentNode] setBlack];
[[[newObject parentNode] parentNode] setRed];
[self rightRotateAroundNode:
[[newObject parentNode] parentNode]];
}
}
else
{
y = [[[newObject parentNode] parentNode] rightNode];
if ([y isRed])
{
[[newObject parentNode] setBlack];
[y setBlack];
[[[newObject parentNode] parentNode] setRed];
newObject = [[newObject parentNode] parentNode];
}
else
{
if (newObject == [[newObject parentNode] leftNode])
{
newObject = [newObject parentNode];
[self rightRotateAroundNode:newObject];
}
[[newObject parentNode] setBlack];
[[[newObject parentNode] parentNode] setRed];
[self leftRotateAroundNode:
[[newObject parentNode] parentNode]];
}
}
}
[_contents_root setBlack];
}
- (void) _RBTreeDeleteFixup: x
{
id w;
while (x != _contents_root && NODE_IS_BLACK(x))
{
if (NODE_IS_LEFTCHILD(x))
{
w = [[x parentNode] rightNode];
if (NODE_IS_RED(w))
{
[w setBlack];
[[x parentNode] setRed];
[self leftRotateAroundNode:[x parentNode]];
w = [[x parentNode] rightNode];
}
if (NODE_IS_BLACK([w leftNode]) && NODE_IS_BLACK([w rightNode]))
{
[w setRed];
x = [x parentNode];
}
else
{
if (NODE_IS_BLACK([w rightNode]))
{
[[w leftNode] setBlack];
[w setRed];
[self rightRotateAroundNode:w];
w = [[x parentNode] rightNode];
}
if (NODE_IS_BLACK([x parentNode]))
[w setBlack];
else
[w setRed];
[[x parentNode] setBlack];
[[w rightNode] setBlack];
[self leftRotateAroundNode:[x parentNode]];
x = _contents_root;
}
}
else
{
w = [[x parentNode] leftNode];
if (NODE_IS_RED(w))
{
[w setBlack];
[[x parentNode] setRed];
[self rightRotateAroundNode:[x parentNode]];
w = [[x parentNode] leftNode];
}
if (NODE_IS_BLACK([w rightNode]) && NODE_IS_BLACK([w leftNode]))
{
[w setRed];
x = [x parentNode];
}
else
{
if (NODE_IS_BLACK([w leftNode]))
{
[[w rightNode] setBlack];
[w setRed];
[self leftRotateAroundNode:w];
w = [[x parentNode] leftNode];
}
if (NODE_IS_BLACK([x parentNode]))
[w setBlack];
else
[w setRed];
[[x parentNode] setBlack];
[[w leftNode] setBlack];
[self rightRotateAroundNode:[x parentNode]];
x = _contents_root;
}
}
}
[x setBlack];
}
- (void) removeObject: oldObject
{
id x, y;
if ([oldObject leftNode] == [self nilNode]
|| [oldObject rightNode] == [self nilNode])
y = oldObject;
else
y = [self successorOfObject: oldObject];
if ([y leftNode] != [self nilNode])
x = [y leftNode];
else
x = [y rightNode];
[x setParentNode:[y parentNode]];
if ([y parentNode] == [self nilNode])
_contents_root = x;
else
{
if (y == [[y parentNode] leftNode])
[[y parentNode] setLeftNode:x];
else
[[y parentNode] setRightNode:x];
}
if (y != oldObject)
{
/* put y in the place of oldObject */
[y setParentNode:[oldObject parentNode]];
[y setLeftNode:[oldObject leftNode]];
[y setRightNode:[oldObject rightNode]];
if (oldObject == [[oldObject parentNode] leftNode])
[[oldObject parentNode] setLeftNode:y];
else
[[oldObject parentNode] setRightNode:oldObject];
[[oldObject leftNode] setParentNode:y];
[[oldObject rightNode] setParentNode:y];
}
if (NODE_IS_BLACK(y))
[self _RBTreeDeleteFixup:x];
_count--;
/* Release ownership of the object. */
#if 0
[oldObject setRightNode: [self nilNode]];
[oldObject setLeftNode: [self nilNode]];
[oldObject setParentNode: [self nilNode]];
#else
[oldObject setLeftNode: NO_OBJECT];
[oldObject setRightNode: NO_OBJECT];
[oldObject setParentNode: NO_OBJECT];
#endif
[oldObject setBinaryTree: NO_OBJECT];
[oldObject release];
}
@end

View file

@ -1,36 +0,0 @@
/* Interface for Objective-C RBTreeNode object
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __RBTreeNode_h_GNUSTEP_BASE_INCLUDE
#define __RBTreeNode_h_GNUSTEP_BASE_INCLUDE
#include <base/BinaryTreeNode.h>
#include <base/RBTree.h>
@interface RBTreeNode : BinaryTreeNode <RBTreeComprising>
{
BOOL _red;
}
@end
#endif /* __RBTreeNode_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,87 +0,0 @@
/* Implementation for Objective-C RBTreeNode objects
Copyright (C) 1993,1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/RBTreeNode.h>
#include <base/NSString.h>
@implementation RBTreeNode
+ (void) initialize
{
if (self == [RBTreeNode class])
[self setVersion:0]; /* beta release */
}
- init
{
[super init];
_red = YES;
return self;
}
- (void) encodeWithCoder: aCoder
{
[super encodeWithCoder:aCoder];
[aCoder encodeValueOfObjCType:@encode(BOOL) at:&_red withName:@"RBTreeNode isRed"];
}
- initWithCoder: aCoder
{
[self initWithCoder:aCoder];
[aCoder decodeValueOfObjCType:@encode(BOOL) at:&_red withName:NULL];
return self;
}
- write: (TypedStream*)aStream
{
[super write:aStream];
objc_write_type(aStream, @encode(BOOL), &_red);
return self;
}
- read: (TypedStream*)aStream
{
[super read:aStream];
objc_read_type(aStream, @encode(BOOL), &_red);
return self;
}
- (BOOL) isRed
{
return _red;
}
- setRed
{
_red = YES;
return self;
}
- setBlack
{
_red = NO;
return self;
}
@end

View file

@ -1,16 +0,0 @@
* WARNING *
This directory contains code that does not (and is not intended to) build.
* WARNING *
The source code here is obsolete - mostly from the original libObjects library
that was used as a basis for GNUstep-base. The GNUstep base library has been
almost entirely rewritten since this code was used!
The files have been preserved in case we want to use them at some point,
as the basis/inspiration for an additional library.
They are NOT part of GNUstep-base proper and are not supported in any way,
they are also unlikely to be preserved indefinately, and will probably be
removed from the CVS repository at some point.

View file

@ -1,43 +0,0 @@
/* Interface for additive congruential pseudo-random num generating
Copyright (C) 1994 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/* Additive Congruential Method,
from Robert Sedgewick, "Algorithms" */
#ifndef __RNGAdditiveCongruential_h_GNUSTEP_BASE_INCLUDE
#define __RNGAdditiveCongruential_h_GNUSTEP_BASE_INCLUDE
#include <base/RandomGenerating.h>
@interface RNGAdditiveCongruential : NSObject <RandomGenerating>
{
long *table;
int table_size;
int tap1;
int tap2;
int index;
}
@end
#endif /* __RNGAdditiveCongruential_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,112 +0,0 @@
/* Implementation additive congruential pseudo-random num generating
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/RNGAdditiveCongruential.h>
#include <base/Coder.h>
#include <limits.h>
/* Additive Congruential Method,
from Robert Sedgewick, "Algorithms" */
/* The Chi^2 test results for this RNG is bad.
xxx Find the bug. */
@implementation RNGAdditiveCongruential
- initWithTableSize: (int)s tapsAtOffsets: (int)t1 :(int)t2
{
[super init];
table_size = s;
tap1 = t1;
tap2 = t2;
OBJC_MALLOC(table, long, table_size);
[self setRandomSeed:0];
return self;
}
- (void) encodeWithCoder: anEncoder
{
[self notImplemented:_cmd];
}
- initWithCoder: aDecoder
{
[self notImplemented:_cmd];
return self;
}
- (void) dealloc
{
OBJC_FREE(table);
[super dealloc];
}
- init
{
[self initWithTableSize:55 tapsAtOffsets:31 :55];
return self;
}
#define BITS_PER_CHAR 8
#define HIGH_BYTE(X) ((X) / (1 << (sizeof(X)-1) * BITS_PER_CHAR))
- (long) nextRandom
{
int i;
long result = 0;
/* Grab only the high bytes---they are the most random */
for (i = 0; i < sizeof(long); i++)
{
index = (index + 1) % table_size;
table[index] = (table[(index + table_size - tap1) % table_size]
+
table[(index + table_size - tap2) % table_size]);
result = (result << BITS_PER_CHAR) + HIGH_BYTE(table[index]);
}
return result;
}
- (void) setRandomSeed: (long)s
{
/* Fill the table with the linear congruential method,
from Robert Sedgewick, "Algorithms" */
/* b must be x21, with x even, one less number of digits than ULONG_MAX */
unsigned long b = ((ULONG_MAX / 1000) * 200) + 21;
unsigned char *byte_table = (unsigned char*) table;
int byte_table_size = table_size * sizeof(*table);
int i;
for (i = 0; i < byte_table_size; i++)
{
s = s * b + 1;
byte_table[i] = HIGH_BYTE(s);
}
/* Reset index to beginning */
index = 0;
return;
}
@end

View file

@ -1,73 +0,0 @@
/* Interface for Berkeley random()-compatible generation for Objective-C
Reworked by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __RNGBerkeley_h_GNUSTEP_BASE_INCLUDE
#define __RNGBerkeley_h_GNUSTEP_BASE_INCLUDE
/*
* Copyright (c) 1983 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
* This is derived from the Berkeley source:
* @(#)random.c 5.5 (Berkeley) 7/6/88
* It was reworked for the GNU C Library by Roland McGrath.
* It was reworked for the GNU Objective-C Library by Andrew Kachites McCallum
*/
#include <base/RandomGenerating.h>
@interface RNGBerkeley : NSObject <RandomGenerating>
{
int foo[2];
long int randtbl[32]; /* Size must match DEG_3 + 1 from RNGBerkeley.m */
long int *fptr;
long int *rptr;
long int *state;
int rand_type;
int rand_deg;
int rand_sep;
long int *end_ptr;
}
- (void) _srandom: (unsigned int)x;
- (void*) _initstateSeed: (unsigned int)seed
state: (void*)arg_state
size: (size_t)n;
- (void*) _setstate: (void*)arg_state;
@end
#endif /* __RNGBerkeley_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,443 +0,0 @@
/* Implementation of Berkeley random()-compatible generation for Objective-C
Reworked by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/*
* Copyright (c) 1983, 1995 Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
* This is derived from the Berkeley source:
* @(#)random.c 5.5 (Berkeley) 7/6/88
* It was reworked for the GNU C Library by Roland McGrath.
* It was reworked for the GNU Objective-C Library by Andrew Kachites McCallum
*/
#include <config.h>
#include <base/RNGBerkeley.h>
#include <base/Coder.h>
#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <stdlib.h>
//#include <sys/time.h>
/* Deal with bcopy: */
#if STDC_HEADERS || HAVE_STRING_H
#include <string.h>
/* An ANSI string.h and pre-ANSI memory.h might conflict. */
#if !STDC_HEADERS && HAVE_MEMORY_H
#include <memory.h>
#endif /* not STDC_HEADERS and HAVE_MEMORY_H */
#define index strchr
#define rindex strrchr
#define bcopy(s, d, n) memcpy ((d), (s), (n))
#define bcmp(s1, s2, n) memcmp ((s1), (s2), (n))
#define bzero(s, n) memset ((s), 0, (n))
#else /* not STDC_HEADERS and not HAVE_STRING_H */
#include <strings.h>
/* memory.h and strings.h conflict on some systems. */
#endif /* not STDC_HEADERS and not HAVE_STRING_H */
/* An improved random number generation package. In addition to the standard
rand()/srand() like interface, this package also has a special state info
interface. The initstate() routine is called with a seed, an array of
bytes, and a count of how many bytes are being passed in; this array is
then initialized to contain information for random number generation with
that much state information. Good sizes for the amount of state
information are 32, 64, 128, and 256 bytes. The state can be switched by
calling the setstate() function with the same array as was initiallized
with initstate(). By default, the package runs with 128 bytes of state
information and generates far better random numbers than a linear
congruential generator. If the amount of state information is less than
32 bytes, a simple linear congruential R.N.G. is used. Internally, the
state information is treated as an array of longs; the zeroeth element of
the array is the type of R.N.G. being used (small integer); the remainder
of the array is the state information for the R.N.G. Thus, 32 bytes of
state information will give 7 longs worth of state information, which will
allow a degree seven polynomial. (Note: The zeroeth word of state
information also has some other information stored in it; see setstate
for details). The random number generation technique is a linear feedback
shift register approach, employing trinomials (since there are fewer terms
to sum up that way). In this approach, the least significant bit of all
the numbers in the state table will act as a linear feedback shift register,
and will have period 2^deg - 1 (where deg is the degree of the polynomial
being used, assuming that the polynomial is irreducible and primitive).
The higher order bits will have longer periods, since their values are
also influenced by pseudo-random carries out of the lower bits. The
total period of the generator is approximately deg*(2**deg - 1); thus
doubling the amount of state information has a vast influence on the
period of the generator. Note: The deg*(2**deg - 1) is an approximation
only good for large deg, when the period of the shift register is the
dominant factor. With deg equal to seven, the period is actually much
longer than the 7*(2**7 - 1) predicted by this formula. */
/* For each of the currently supported random number generators, we have a
break value on the amount of state information (you need at least thi
bytes of state info to support this random number generator), a degree for
the polynomial (actually a trinomial) that the R.N.G. is based on, and
separation between the two lower order coefficients of the trinomial. */
/* Linear congruential. */
#define TYPE_0 0
#define BREAK_0 8
#define DEG_0 0
#define SEP_0 0
/* x**7 + x**3 + 1. */
#define TYPE_1 1
#define BREAK_1 32
#define DEG_1 7
#define SEP_1 3
/* x**15 + x + 1. */
#define TYPE_2 2
#define BREAK_2 64
#define DEG_2 15
#define SEP_2 1
/* x**31 + x**3 + 1. */
#define TYPE_3 3
#define BREAK_3 128
#define DEG_3 31
#define SEP_3 3
/* x**63 + x + 1. */
#define TYPE_4 4
#define BREAK_4 256
#define DEG_4 63
#define SEP_4 1
/* Array versions of the above information to make code run faster.
Relies on fact that TYPE_i == i. */
#define MAX_TYPES 5 /* Max number of types above. */
static int degrees[MAX_TYPES] = { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 };
static int seps[MAX_TYPES] = { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 };
/* Initially, everything is set up as if from:
initstate(1, randtbl, 128);
Note that this initialization takes advantage of the fact that srandom
advances the front and rear pointers 10*rand_deg times, and hence the
rear pointer which starts at 0 will also end up at zero; thus the zeroeth
element of the state information, which contains info about the current
position of the rear pointer is just
(MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3. */
#if 0 /* moved to RNGBerkeley.h -am */
static long int randtbl[DEG_3 + 1] =
{
TYPE_3,
-851904987, -43806228, -2029755270, 1390239686, -1912102820,
-485608943, 1969813258, -1590463333, -1944053249, 455935928, 508023712,
-1714531963, 1800685987, -2015299881, 654595283, -1149023258,
-1470005550, -1143256056, -1325577603, -1568001885, 1275120390,
-607508183, -205999574, -1696891592, 1492211999, -1528267240,
-952028296, -189082757, 362343714, 1424981831, 2039449641,
};
#endif /* moved to RNGBerkeley.h -am */
/* FPTR and RPTR are two pointers into the state info, a front and a rear
pointer. These two pointers are always rand_sep places aparts, as they
cycle through the state information. (Yes, this does mean we could get
away with just one pointer, but the code for random is more efficient
this way). The pointers are left positioned as they would be from the call:
initstate(1, randtbl, 128);
(The position of the rear pointer, rptr, is really 0 (as explained above
in the initialization of randtbl) because the state table pointer is set
to point to randtbl[1] (as explained below).) */
#if 0 /* moved to RNGBerkeley.h -am */
static long int *fptr = &randtbl[SEP_3 + 1];
static long int *rptr = &randtbl[1];
#endif /* moved to RNGBerkeley.h -am */
/* The following things are the pointer to the state information table,
the type of the current generator, the degree of the current polynomial
being used, and the separation between the two pointers.
Note that for efficiency of random, we remember the first location of
the state information, not the zeroeth. Hence it is valid to access
state[-1], which is used to store the type of the R.N.G.
Also, we remember the last location, since this is more efficient than
indexing every time to find the address of the last element to see if
the front and rear pointers have wrapped. */
#if 0 /* moved to RNGBerkeley.h -am */
static long int *state = &randtbl[1];
static int rand_type = TYPE_3;
static int rand_deg = DEG_3;
static int rand_sep = SEP_3;
static long int *end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])];
#endif /* moved to RNGBerkeley.h -am */
@implementation RNGBerkeley
- init
{
static long int static_randtbl[DEG_3 + 1] =
{
TYPE_3,
-851904987, -43806228, -2029755270, 1390239686, -1912102820,
-485608943, 1969813258, -1590463333, -1944053249, 455935928, 508023712,
-1714531963, 1800685987, -2015299881, 654595283, -1149023258,
-1470005550, -1143256056, -1325577603, -1568001885, 1275120390,
-607508183, -205999574, -1696891592, 1492211999, -1528267240,
-952028296, -189082757, 362343714, 1424981831, 2039449641,
};
[super init];
bcopy(static_randtbl, randtbl, sizeof(randtbl));
fptr = &randtbl[SEP_3 + 1];
rptr = &randtbl[1];
state = &randtbl[1];
rand_type = TYPE_3;
rand_deg = DEG_3;
rand_sep = SEP_3;
end_ptr = &randtbl[sizeof(randtbl) / sizeof(randtbl[0])];
return self;
}
/* Initialize the random number generator based on the given seed. If the
type is the trivial no-state-information type, just remember the seed.
Otherwise, initializes state[] based on the given "seed" via a linear
congruential generator. Then, the pointers are set to known locations
that are exactly rand_sep places apart. Lastly, it cycles the state
information a given number of times to get rid of any initial dependencies
introduced by the L.C.R.N.G. Note that the initialization of randtbl[]
for default usage relies on values produced by this routine. */
- (void) _srandom: (unsigned int)x
{
state[0] = x;
if (rand_type != TYPE_0)
{
register long int i;
for (i = 1; i < rand_deg; ++i)
state[i] = (1103515145 * state[i - 1]) + 12345;
fptr = &state[rand_sep];
rptr = &state[0];
for (i = 0; i < 10 * rand_deg; ++i)
[self nextRandom]; /* (void) __random(); */
}
}
- (void) setRandomSeed: (long)aSeed
{
[self _srandom:aSeed];
return;
}
/* Initialize the state information in the given array of N bytes for
future random number generation. Based on the number of bytes we
are given, and the break values for the different R.N.G.'s, we choose
the best (largest) one we can and set things up for it. srandom is
then called to initialize the state information. Note that on return
from srandom, we set state[-1] to be the type multiplexed with the current
value of the rear pointer; this is so successive calls to initstate won't
lose this information and will be able to restart with setstate.
Note: The first thing we do is save the current state, if any, just like
setstate so that it doesn't matter when initstate is called.
Returns a pointer to the old state. */
- (void*) _initstateSeed: (unsigned int)seed
state: (void*)arg_state
size: (size_t)n
{
void* ostate = (void*) &state[-1];
if (rand_type == TYPE_0)
state[-1] = rand_type;
else
state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
if (n < BREAK_1)
{
if (n < BREAK_0)
{
errno = EINVAL;
return NULL;
}
rand_type = TYPE_0;
rand_deg = DEG_0;
rand_sep = SEP_0;
}
else if (n < BREAK_2)
{
rand_type = TYPE_1;
rand_deg = DEG_1;
rand_sep = SEP_1;
}
else if (n < BREAK_3)
{
rand_type = TYPE_2;
rand_deg = DEG_2;
rand_sep = SEP_2;
}
else if (n < BREAK_4)
{
rand_type = TYPE_3;
rand_deg = DEG_3;
rand_sep = SEP_3;
}
else
{
rand_type = TYPE_4;
rand_deg = DEG_4;
rand_sep = SEP_4;
}
state = &((long int *) arg_state)[1]; /* First location. */
/* Must set END_PTR before srandom. */
end_ptr = &state[rand_deg];
[self _srandom:seed]; /*__srandom(seed); */
if (rand_type == TYPE_0)
state[-1] = rand_type;
else
state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
return ostate;
}
/* Restore the state from the given state array.
Note: It is important that we also remember the locations of the pointers
in the current state information, and restore the locations of the pointers
from the old state information. This is done by multiplexing the pointer
location into the zeroeth word of the state information. Note that due
to the order in which things are done, it is OK to call setstate with the
same state as the current state
Returns a pointer to the old state information. */
- (void*) _setstate: (void*)arg_state
{
register long int *new_state = (long int *) arg_state;
register int type = new_state[0] % MAX_TYPES;
register int rear = new_state[0] / MAX_TYPES;
void* ostate = (void*) &state[-1];
if (rand_type == TYPE_0)
state[-1] = rand_type;
else
state[-1] = (MAX_TYPES * (rptr - state)) + rand_type;
switch (type)
{
case TYPE_0:
case TYPE_1:
case TYPE_2:
case TYPE_3:
case TYPE_4:
rand_type = type;
rand_deg = degrees[type];
rand_sep = seps[type];
break;
default:
/* State info munged. */
errno = EINVAL;
return NULL;
}
state = &new_state[1];
if (rand_type != TYPE_0)
{
rptr = &state[rear];
fptr = &state[(rear + rand_sep) % rand_deg];
}
/* Set end_ptr too. */
end_ptr = &state[rand_deg];
return ostate;
}
/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
congruential bit. Otherwise, we do our fancy trinomial stuff, which is the
same in all ther other cases due to all the global variables that have been
set up. The basic operation is to add the number at the rear pointer into
the one at the front pointer. Then both pointers are advanced to the next
location cyclically in the table. The value returned is the sum generated,
reduced to 31 bits by throwing away the "least random" low bit.
Note: The code takes advantage of the fact that both the front and
rear pointers can't wrap on the same call by not testing the rear
pointer if the front one has wrapped. Returns a 31-bit random number. */
- (long) nextRandom
{
if (rand_type == TYPE_0)
{
state[0] = ((state[0] * 1103515245) + 12345) & LONG_MAX;
return state[0];
}
else
{
long int i;
*fptr += *rptr;
/* Chucking least random bit. */
i = (*fptr >> 1) & LONG_MAX;
++fptr;
if (fptr >= end_ptr)
{
fptr = state;
++rptr;
}
else
{
++rptr;
if (rptr >= end_ptr)
rptr = state;
}
return i;
}
}
- (void) encodeWithCoder: anEncoder
{
[self notImplemented:_cmd];
}
- initWithCoder: aDecoder
{
[self notImplemented:_cmd];
return self;
}
@end

View file

@ -1,68 +0,0 @@
/* Interface for Objective-C object providing randoms in uniform distribution
Copyright (C) 1994 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Random_h_GNUSTEP_BASE_INCLUDE
#define __Random_h_GNUSTEP_BASE_INCLUDE
#include <base/RandomGenerating.h>
@interface Random : NSObject
{
id <RandomGenerating> rng;
}
+ initialize;
+ (id <RandomGenerating>) defaultRandomGeneratorClass;
+ setDefaultRandomGeneratorClass: (id <RandomGenerating>)aRNG;
+ (float) chiSquareOfRandomGenerator: (id <RandomGenerating>)aRNG
iterations: (int)n
range: (long)r;
+ (float) chiSquareOfRandomGenerator: (id <RandomGenerating>)aRNG;
- init;
- setRandomSeedFromClock;
- setRandomSeed: (long)seed;
- (long) randomInt;
- (long) randomIntBetween: (long)lowBound and: (long)highBound;
- (long) randomDie: (long)numSides; /* between 0 and numSides-1 */
- (BOOL) randomCoin;
- (BOOL) randomCoinWithProbability: (double)p;
- (float) randomFloat;
- (float) randomFloatBetween: (float)lowBound and: (float)highBound;
- (float) randomFloatProbability;
- (double) randomDouble;
- (double) randomDoubleBetween: (double)lowBound and: (double)highBound;
- (double) randomDoubleProbability;
- read: (TypedStream*)aStream;
- write: (TypedStream*)aStream;
@end
#endif /* __Random_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,306 +0,0 @@
/* Implementation Objective-C object providing randoms in uniform distribution
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/* TODO:
RNGBerkeley nextRandom returns only positive numbers
RNGAdditiveCongruential nextRandom returns positive and negative numbers
*/
#include <config.h>
#include <base/Random.h>
#include <base/RNGBerkeley.h>
#include <base/Time.h>
#include <base/Coder.h>
#include <Foundation/NSException.h>
#include <limits.h>
typedef union {
float f;
unsigned long u;
} float_and_long_u;
typedef union {
double d;
unsigned long u[2];
} double_and_long_u;
static float_and_long_u singleMantissa;
static double_and_long_u doubleMantissa;
static id defaultRNG = nil;
@class RNGBerkeley;
@implementation Random
+ initialize
{
if (self == [Random class])
{
defaultRNG = [RNGBerkeley class];
NSAssert(sizeof(double) == 2 * sizeof(long), NSInternalInconsistencyException);
NSAssert(sizeof(float) == sizeof(long), NSInternalInconsistencyException);
/* Following taken from libg++ */
/*
The following is a hack that I attribute to
Andres Nowatzyk at CMU. The intent of the loop
is to form the smallest number 0 <= x < 1.0,
which is then used as a mask for two longwords.
this gives us a fast way way to produce double
precision numbers from longwords.
I know that this works for IEEE and VAX floating
point representations.
A further complication is that gnu C will blow
the following loop, unless compiled with -ffloat-store,
because it uses extended representations for some of
of the comparisons. Thus, we have the following hack.
If we could specify #pragma optimize, we wouldn't need this.
*/
{
double_and_long_u t;
float_and_long_u s;
#if _IEEE == 1
t.d = 1.5;
if ( t.u[1] == 0 ) { // sun word order?
t.u[0] = 0x3fffffff;
t.u[1] = 0xffffffff;
}
else {
t.u[0] = 0xffffffff; // encore word order?
t.u[1] = 0x3fffffff;
}
s.u = 0x3fffffff;
#else
volatile double x = 1.0; /* volatile needed when fp hardware used,
and has greater precision than memory
doubles */
double y = 0.5;
volatile float xx = 1.0; /* volatile needed when fp hardware used,
and has greater precision than memory
floats */
float yy = 0.5;
do { /* find largest fp-number < 2.0 */
t.d = x;
x += y;
y *= 0.5;
} while (x != t.d && x < 2.0);
do { /*find largest fp-number < 2.0 */
s.f = xx;
xx += yy;
yy *= 0.5;
} while (xx != s.f && xx < 2.0);
#endif
// set doubleMantissa to 1 for each doubleMantissa bit;
doubleMantissa.d = 1.0;
doubleMantissa.u[0] ^= t.u[0];
doubleMantissa.u[1] ^= t.u[1];
// set singleMantissa to 1 for each singleMantissa bit;
singleMantissa.f = 1.0;
singleMantissa.u ^= s.u;
}
}
return self;
}
+ setDefaultRandomGeneratorClass: (id <RandomGenerating>)aRNG
{
defaultRNG = aRNG;
return self;
}
+ (id <RandomGenerating>) defaultRandomGeneratorClass
{
return defaultRNG;
}
/* For testing randomness of a random generator,
the closer to r the returned value is, the better the randomness. */
+ (float) chiSquareOfRandomGenerator: (id <RandomGenerating>)aRNG
iterations: (int)n
range: (long)r
{
long table[r];
int i, j;
for (i = 0; i < r; i++)
table[i] = 0;
for (i = 0; i < n; i++)
{
j = ABS([aRNG nextRandom]) % r;
table[j]++;
}
j = 0;
for (i = 0; i < r; i++)
j += table[i] * table[i];
return ((((float)r * j) / n) - n);
}
/* For testing randomness of a random generator,
the closer to 1.0 the returned value is, the better the randomness. */
+ (float) chiSquareOfRandomGenerator: (id <RandomGenerating>)aRNG
{
return [self chiSquareOfRandomGenerator:aRNG
iterations:1000
range:100] / 100.0;
}
- initWithRandomGenerator: (id <RandomGenerating>)aRNG
{
[super init];
rng = aRNG;
return self;
}
- init
{
/* Without the (id) we get:
Random.m: In function `_i_Random__init':
Random.m:172: warning: method `alloc' not implemented by protocol.
This is a bug in gcc.
*/
return [self initWithRandomGenerator:
[[(id)[[self class] defaultRandomGeneratorClass] alloc] init]];
}
- setRandomSeedFromClock
{
[self setRandomSeed:[Time secondClockValue]];
return self;
}
- setRandomSeed: (long)seed
{
[rng setRandomSeed:seed];
return self;
}
- (long) randomInt
{
return [rng nextRandom];
}
- (long) randomIntBetween: (long)lowBound and: (long)highBound
{
return ([rng nextRandom] % (highBound - lowBound + 1) + lowBound);
}
/* return between 0 and numSides-1 */
- (long) randomDie: (long)numSides
{
return ([rng nextRandom] % numSides);
}
- (BOOL) randomCoin
{
return ([rng nextRandom] % 2);
}
- (BOOL) randomCoinWithProbability: (double)p
{
return (p >= [self randomDoubleProbability]);
}
/* Returns 0.0 <= r < 1.0. Is this what people want?
I'd like it to return 1.0 also. */
- (float) randomFloat
{
union {long i; float f;} result;
result.f = 1.0;
result.i |= ([rng nextRandom] & singleMantissa.u);
result.f -= 1.0;
NSAssert(result.f < 1.0 && result.f >= 0, NSInternalInconsistencyException);
return result.f;
}
- (float) randomFloatBetween: (float)lowBound and: (float)highBound
{
return ([self randomFloat] * (highBound - lowBound) + lowBound);
}
- (float) randomFloatProbability
{
return [self randomFloat];
}
/* Returns 0.0 <= r < 1.0. Is this what people want?
I'd like it to return 1.0 also. */
- (double) randomDouble
{
union {unsigned long u[2]; double d;} result;
result.d = 1.0;
result.u[0] |= ([rng nextRandom] & doubleMantissa.u[0]);
result.u[1] |= ([rng nextRandom] & doubleMantissa.u[1]);
result.d -= 1.0;
NSAssert(result.d < 1.0 && result.d >= 0, NSInternalInconsistencyException);
return result.d;
}
- (double) randomDoubleBetween: (double)lowBound and: (double)highBound
{
return [self randomDouble] * (highBound - lowBound);
}
- (double) randomDoubleProbability
{
return [self randomDouble];
}
- (void) encodeWithCoder: anEncoder
{
[self notImplemented:_cmd];
}
- initWithCoder: aDecoder
{
[self notImplemented:_cmd];
return self;
}
- write: (TypedStream*)aStream
{
[super write:aStream];
// [rng read:aStream];
[self notImplemented:_cmd];
return self;
}
- read: (TypedStream*)aStream
{
[super read:aStream];
// [rng read:aStream];
[self notImplemented:_cmd];
return self;
}
@end

View file

@ -1,36 +0,0 @@
/* Protocol for Objective-C objects that generate random bits
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Created: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __RandomGenerating_h_GNUSTEP_BASE_INCLUDE
#define __RandomGenerating_h_GNUSTEP_BASE_INCLUDE
#include <Foundation/NSObject.h>
@protocol RandomGenerating <NSObject, NSCoding>
- (void) setRandomSeed: (long)seed;
- (long) nextRandom;
@end
#endif /* __RandomGenerating_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,36 +0,0 @@
/* Interface for GNU Objective-C raw stream object for archiving
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Written: Jan 1996
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __RawCStream_h_GNUSTEP_BASE_INCLUDE
#define __RawCStream_h_GNUSTEP_BASE_INCLUDE
#include <base/Stream.h>
#include <base/CStream.h>
@interface RawCStream : CStream
+ setDebugging: (BOOL)f;
@end
#endif /* __RawCStream_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,296 +0,0 @@
/* Implementation of GNU Objective-C raw-binary stream for archiving
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Written: Jan 1996
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/* Use this CStream subclass when you are encoding/decoding on the
same architecture, and you care about time and space.
WARNING: This encoding is *not* machine-independent. */
#include <config.h>
#include <base/preface.h>
#include <base/RawCStream.h>
#include <base/NSString.h>
#include <base/StdioStream.h>
#include <base/TextCStream.h>
#include <base/NSException.h>
#define DEFAULT_FORMAT_VERSION 0
#define ROUND(V, A) \
({ typeof(V) __v=(V); typeof(A) __a=(A); \
__a*((__v+__a-1)/__a); })
@implementation RawCStream
/* For debugging */
static BOOL debug_binary_coder;
+ setDebugging: (BOOL)f
{
debug_binary_coder = f;
return self;
}
+ debugStderrCoder
{
static id c = nil;
if (!c)
c = [[TextCStream alloc]
initForWritingToStream: [StdioStream standardError]];
return c;
}
- (void) encodeName: (NSString*) name
{
if (debug_binary_coder)
[[[self class] debugStderrCoder]
encodeName:name];
}
/* Encoding/decoding C values */
- (void) encodeValueOfCType: (const char*)type
at: (const void*)d
withName: (NSString*) name
{
if (debug_binary_coder)
{
[[[self class] debugStderrCoder]
encodeValueOfCType:type
at:d
withName:name];
}
if (!type)
[NSException raise:NSInvalidArgumentException format:@"type is NULL"];
NSAssert(*type != '@', @"tried to encode an \"ObjC\" type");
NSAssert(*type != '^', @"tried to encode an \"ObjC\" type");
NSAssert(*type != ':', @"tried to encode an \"ObjC\" type");
switch (*type)
{
case _C_CHARPTR:
{
int length = strlen(*(char**)d);
[self encodeValueOfCType:@encode(int)
at:&length withName:@"BinaryCStream char* length"];
[stream writeBytes:*(char**)d length:length];
break;
}
case _C_CHR:
case _C_UCHR:
[stream writeByte:*(unsigned char*)d];
break;
case _C_SHT:
case _C_USHT:
[stream writeBytes:d length:sizeof(short)];
break;
case _C_INT:
case _C_UINT:
[stream writeBytes:d length:sizeof(int)];
break;
case _C_LNG:
case _C_ULNG:
[stream writeBytes:d length:sizeof(long)];
break;
case _C_FLT:
[stream writeBytes:d length:sizeof(float)];
break;
case _C_DBL:
[stream writeBytes:d length:sizeof(double)];
break;
case _C_ARY_B:
{
int len = atoi (type+1); /* xxx why +1 ? */
int offset;
while (isdigit(*++type));
offset = objc_sizeof_type(type);
while (len-- > 0)
{
/* Change this so we don't re-write type info every time. */
[self encodeValueOfCType: type
at: d
withName: NULL];
((char*)d) += offset;
}
break;
}
case _C_STRUCT_B:
{
int acc_size = 0;
int align;
while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */
while (*type != _C_STRUCT_E)
{
align = objc_alignof_type (type); /* pad to alignment */
acc_size = ROUND (acc_size, align);
[self encodeValueOfCType: type
at: ((char*)d)+acc_size
withName: NULL];
acc_size += objc_sizeof_type (type); /* add component size */
type = objc_skip_typespec (type); /* skip component */
}
break;
}
default:
[self error:"Unrecognized Type %s", type];
}
}
- (void) decodeValueOfCType: (const char*)type
at: (void*)d
withName: (NSString* *)namePtr
{
if (!type)
[NSException raise:NSInvalidArgumentException format:@"type is NULL"];
NSAssert(*type != '@', @"tried to decode an \"ObjC\" type");
NSAssert(*type != '^', @"tried to decode an \"ObjC\" type");
NSAssert(*type != ':', @"tried to decode an \"ObjC\" type");
switch (*type)
{
case _C_CHARPTR:
{
int length;
[self decodeValueOfCType:@encode(int)
at:&length withName:NULL];
OBJC_MALLOC(*(char**)d, char, length+1);
[stream readBytes:*(char**)d length:length];
(*(char**)d)[length] = '\0';
break;
}
case _C_CHR:
case _C_UCHR:
[stream readByte:d];
break;
case _C_SHT:
case _C_USHT:
[stream readBytes:d length:sizeof(short)];
break;
case _C_INT:
case _C_UINT:
[stream readBytes:d length:sizeof(int)];
break;
case _C_LNG:
case _C_ULNG:
[stream readBytes:d length:sizeof(long)];
break;
case _C_FLT:
[stream readBytes:d length:sizeof(float)];
break;
case _C_DBL:
[stream readBytes:d length:sizeof(double)];
break;
case _C_ARY_B:
{
/* xxx Do we need to allocate space, just like _C_CHARPTR ? */
int len = atoi(type+1);
int offset;
while (isdigit(*++type));
offset = objc_sizeof_type(type);
while (len-- > 0)
{
[self decodeValueOfCType:type
at:d
withName:namePtr];
((char*)d) += offset;
}
break;
}
case _C_STRUCT_B:
{
/* xxx Do we need to allocate space just like char* ? No. */
int acc_size = 0;
int align;
const char *save_type = type;
while (*type != _C_STRUCT_E && *type++ != '='); /* skip "<name>=" */
while (*type != _C_STRUCT_E)
{
align = objc_alignof_type (type); /* pad to alignment */
acc_size = ROUND (acc_size, align);
[self decodeValueOfCType:type
at:((char*)d)+acc_size
withName:namePtr];
acc_size += objc_sizeof_type (type); /* add component size */
type = objc_skip_typespec (type); /* skip component */
}
type = save_type;
break;
}
default:
[self error:"Unrecognized Type %s", type];
}
if (debug_binary_coder)
{
[[[self class] debugStderrCoder]
encodeValueOfCType:type
at:d
withName:@"decoding unnamed"];
}
}
/* Returning default format version. */
+ (int) defaultFormatVersion
{
return DEFAULT_FORMAT_VERSION;
}
- (void) decodeName: (NSString* *)n
{
#if 1
if (n)
*n = nil;
#else
if (n)
*n = [[[NSString alloc] init] autorelease];
#endif
}
@end

View file

@ -1,100 +0,0 @@
/* Protocol for GNU Objective-C objects that can keep a retain count.
Copyright (C) 1993,1994 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: July 1994
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Retaining_h_GNUSTEP_BASE_INCLUDE
#define __Retaining_h_GNUSTEP_BASE_INCLUDE
#include <Foundation/NSObject.h>
@protocol Retaining
- retain;
/* Use this message when the sender did not allocate the receiving
object, but the sender wants to keep a reference to the receiving
object. It increments a reference count for the object. The
object will not be deallocated until after a matching release
message is sent to this object.
IMPORTANT PROGRAMMING CONVENTION: There is no need to send this
message to objects that the sender allocated---allocating an object
already implies that the object will not be deallocated until the
sender releases it. Just as "retain" and "release" messages cancel
each other, one "release" message is needed to cancel the original
allocation. */
- (oneway void) release;
/* Use this message when the sender is done with the receiving object.
If the sender had the last reference to the object, the object will
be deallocated by sending "dealloc" to it.
IMPORTANT PROGRAMMING CONVENTION: The sender should only send this
to objects that it has allocated or has retain'ed. */
- (void) dealloc;
/* This method deallocates the memory for this object. You should not
send this message yourself; it is sent for you by the release
method, which properly manages retain counts. Do, however,
override this method to deallocate any memory allocated by this
object during initialization; the overriding method should call
[super dealloc] at the end. */
- (unsigned) retainCount;
/* This method returns the retain count to this object. It does
not, however, include the decrements due to stackRelease's. Note
that the returned number is not quite a "reference count" in the
traditional sense; it is less by one in that it is actually a count
of the number of unreleased retain messages sent. A retainCount of
zero implies that there is still one more release necessary to
deallocate the receiver. For example, after an object is created,
its retainCount is zero, but another "release" message is still
required before the object will be deallocated. */
- autorelease;
/* Use this message when the sender is done with this object, but the
sender doesn't want the object to be deallocated immediately
because the function that sends this message will use this object
as its return value. The object will be queued to receive the
actual "release" message later.
Due to this delayed release, the function that receives the object
as a return value will have the opportunity to retain the object
before the "release" instigated by the "autorelease" actually
takes place.
For the object to be autoreleased, you must have previously created
a AutoreleasePool or an AutoreleaseStack. If you don't, however,
your program won't crash, the release corresponding to the
autorelease will just never happen. */
@end
#endif /* __Retaining_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,9 +0,0 @@
#ifndef __RunLoop_h_GNUSTEP_BASE_INCLUDE
#define __RunLoop_h_GNUSTEP_BASE_INCLUDE
#include <Foundation/NSRunLoop.h>
#define RunLoop NSRunLoop
#define RunLoopDefaultMode NSDefaultRunLoopMode
#endif /* __RunLoop_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,52 +0,0 @@
/* Interface for Objective-C Set collection object
Copyright (C) 1993,1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#ifndef __Set_h_GNUSTEP_BASE_INCLUDE
#define __Set_h_GNUSTEP_BASE_INCLUDE
#include <base/Collection.h>
#include <Foundation/NSHashTable.h>
@interface Set : Collection
{
NSHashTable *_contents_hash; // a hashtable to hold the contents;
}
// MANAGING CAPACITY;
+ (unsigned) defaultCapacity;
// INITIALIZING AND FREEING;
- initWithCapacity: (unsigned)aCapacity;
// SET OPERATIONS;
- (void) intersectWithCollection: (id <Collecting>)aCollection;
- (void) unionWithCollection: (id <Collecting>)aCollection;
- (void) differenceWithCollection: (id <Collecting>)aCollection;
- shallowCopyIntersectWithCollection: (id <Collecting>)aCollection;
- shallowCopyUnionWithCollection: (id <Collecting>)aCollection;
- shallowCopyDifferenceWithCollection: (id <Collecting>)aCollection;
@end
#endif /* __Set_h_GNUSTEP_BASE_INCLUDE */

229
Old/Set.m
View file

@ -1,229 +0,0 @@
/* Implementation for Objective-C Set collection object
Copyright (C) 1993,1994, 1995, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/Set.h>
#include <base/CollectionPrivate.h>
#include <base/Coder.h>
#include <Foundation/NSHashTable.h>
#define DEFAULT_SET_CAPACITY 32
@implementation Set
// MANAGING CAPACITY;
/* Eventually we will want to have better capacity management,
potentially keep default capacity as a class variable. */
+ (unsigned) defaultCapacity
{
return DEFAULT_SET_CAPACITY;
}
// INITIALIZING AND FREEING;
/* This is the designated initializer of this class */
- initWithCapacity: (unsigned)cap
{
_contents_hash = NSCreateHashTable(NSObjectHashCallBacks, cap);
return self;
}
/* Override Collection's designated initializer */
- initWithObjects: (id*)objs count: (unsigned)count
{
[self initWithCapacity: count];
while (count--)
[self addObject: objs[count]];
return self;
}
/* Archiving must mimic the above designated initializer */
- _initCollectionWithCoder: aCoder
{
[super _initCollectionWithCoder:aCoder];
_contents_hash = NSCreateHashTable(NSObjectHashCallBacks,
DEFAULT_SET_CAPACITY);
return self;
}
/* Empty copy must empty an allocCopy'ed version of self */
- emptyCopy
{
Set *copy = [super emptyCopy];
copy->_contents_hash =
NSCreateHashTable (NSObjectHashCallBacks, 0);
return copy;
}
- (void) dealloc
{
if (_contents_hash)
{
NSFreeHashTable (_contents_hash);
_contents_hash = 0;
}
[super dealloc];
}
// SET OPERATIONS;
- (void) intersectWithCollection: (id <Collecting>)aCollection
{
[self removeContentsNotIn: aCollection];
}
- (void) unionWithCollection: (id <Collecting>)aCollection
{
[self addContentsIfAbsentOf: aCollection];
}
- (void) differenceWithCollection: (id <Collecting>)aCollection
{
[self removeContentsIn: aCollection];
}
- shallowCopyIntersectWithCollection: (id <Collecting>)aCollection
{
[self notImplemented: _cmd];
return nil;
#if 0
id newColl = [self emptyCopyAs:[self species]];
void doIt(elt e)
{
if ([aCollection includesElement:e])
[newColl addElement:e];
}
[self withElementsCall:doIt];
return newColl;
#endif
}
- shallowCopyUnionWithCollection: (id <Collecting>)aCollection
{
[self notImplemented: _cmd];
return nil;
#if 0
id newColl = [self shallowCopy];
[newColl addContentsOf:aCollection];
return newColl;
#endif
}
- shallowCopyDifferenceWithCollection: (id <Collecting>)aCollection
{
[self notImplemented: _cmd];
return nil;
#if 0
id newColl = [self emptyCopyAs:[self species]];
void doIt(elt e)
{
if (![aCollection includesElement:e])
[newColl addElement:e];
}
[self withElementsCall:doIt];
return newColl;
#endif
}
// ADDING;
- (void) addObject: newObject
{
NSHashInsert (_contents_hash, newObject);
}
// REMOVING AND REPLACING;
- (void) removeObject: oldObject
{
NSHashRemove (_contents_hash, oldObject);
}
/* This must work without sending any messages to content objects */
- (void) _collectionEmpty
{
NSResetHashTable (_contents_hash);
}
- (void) uniqueContents
{
return;
}
// TESTING;
- (BOOL) containsObject: anObject
{
return (NSHashGet (_contents_hash, anObject) ? 1 : 0);
}
- (unsigned) count
{
if (!_contents_hash)
return 0;
return NSCountHashTable (_contents_hash);
}
- (unsigned) occurrencesOfObject: anObject
{
if ([self containsObject: anObject])
return 1;
else
return 0;
}
- member: anObject
{
return NSHashGet(_contents_hash, anObject);
}
// ENUMERATING;
- nextObjectWithEnumState: (void**)enumState
{
return NSNextHashEnumeratorItem ((*(NSHashEnumerator**)enumState));
}
- (void*) newEnumState
{
void *es;
OBJC_MALLOC (es, NSMapEnumerator, 1);
*((NSHashEnumerator*)es) = NSEnumerateHashTable (_contents_hash);
return es;
}
- (void) freeEnumState: (void**)enumState
{
OBJC_FREE (*enumState);
}
@end

View file

@ -1,47 +0,0 @@
/* Interface for Objective-C SplayTree collection object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
/*
Splay Tree.
Sleator and Tarjan. "Self-adjusting binary search trees."
Journal of the ACM, 32(3):652-686, 1985.
includesObject:, minObject, maxObject, nextObject:, sortAddObject,
and removeObject: operations can all be done in O(lg n) amortized time.
*/
#ifndef __SplayTree_h_GNUSTEP_BASE_INCLUDE
#define __SplayTree_h_GNUSTEP_BASE_INCLUDE
#include <base/BinaryTree.h>
@interface SplayTree : BinaryTree
{
}
- (void) splayNode: aNode;
@end
#endif /* __SplayTree_h_GNUSTEP_BASE_INCLUDE */

View file

@ -1,102 +0,0 @@
/* Implementation for Objective-C SplayTree collection object
Copyright (C) 1993, 1994, 1996 Free Software Foundation, Inc.
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
Date: May 1993
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., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include <config.h>
#include <base/SplayTree.h>
#include <base/IndexedCollectionPrivate.h>
@implementation SplayTree
/* Make this a function ? */
- (void) _doSplayOperationOnNode: aNode
{
id parent = [aNode parentNode];
id parentRightChild =
((parent == [self nilNode]) ? [self nilNode] : [parent rightNode]);
if (aNode == _contents_root || aNode == [self nilNode])
{
return;
}
else if (aNode == parentRightChild)
{
if (parent == _contents_root)
{
[self leftRotateAroundNode:parent];
}
else if (NODE_IS_RIGHTCHILD(parent))
{
[self leftRotateAroundNode:[parent parentNode]];
[self leftRotateAroundNode:parent];
}
else
/* NODE_IS_LEFTCHILD(parent) */
{
[self leftRotateAroundNode:parent];
[self rightRotateAroundNode:[aNode parentNode]];
}
}
else
/* aNode == parentLeftChild */
{
if (parent == _contents_root)
{
[self rightRotateAroundNode:parent];
}
else if (NODE_IS_LEFTCHILD(parent))
{
[self rightRotateAroundNode:[parent parentNode]];
[self rightRotateAroundNode:parent];
}
else
/* NODE_IS_RIGHTCHILD(parent) */
{
[self rightRotateAroundNode:parent];
[self leftRotateAroundNode:[aNode parentNode]];
}
}
}
- (void) splayNode: aNode
{
while (aNode != _contents_root)
[self _doSplayOperationOnNode:aNode];
}
/* We could make this a little more efficient by doing the splay as
we search down the tree for the correct insertion point. */
- (void) sortAddObject: newObject
{
[super sortAddObject: newObject];
[self splayNode: newObject];
}
- (void) removeObject: anObject
{
id parent = [anObject parentNode];
[super removeObject: anObject];
if (parent && parent != [self nilNode])
[self splayNode:parent];
}
@end

Some files were not shown because too many files have changed in this diff Show more