New file.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@950 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Andrew McCallum 1996-02-22 15:47:04 +00:00
parent 16636b8a2f
commit 079a267be8
13 changed files with 2257 additions and 0 deletions

View file

@ -0,0 +1,59 @@
/* Private interface for GNU Objective-C coder object for use serializing
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Created: February 1996
This file is part of the GNU Objective C Class Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __CoderPrivate_h_OBJECTS_INCLUDE
#define __CoderPrivate_h_OBJECTS_INCLUDE
#include <objects/stdobjects.h>
#include <objects/Coder.h>
#include <objects/CStreaming.h>
enum {
CODER_OBJECT_NIL = 0,
CODER_OBJECT,
CODER_OBJECT_ROOT,
CODER_OBJECT_REPEATED,
CODER_OBJECT_FORWARD_REFERENCE,
CODER_OBJECT_FORWARD_SATISFIER,
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;
- (BOOL) _coderHasObjectReference: (unsigned)xref;
@end
#define SIGNATURE_FORMAT_STRING \
@"GNU Objective C Class Library %s version %d\n"
#define NO_SEL_TYPES "none"
#endif /* __CoderPrivate_h_OBJECTS_INCLUDE */

View file

@ -0,0 +1,37 @@
/* Protocol for GNU Objective C invocations
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: February 1996
This file is part of the GNU Objective C Class Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __Enumerating_h__OBJECTS_INCLUDE
#define __Enumerating_h__OBJECTS_INCLUDE
#include <objects/stdobjects.h>
@protocol Enumerating <NSObject>
- initWithCollection: aCollection;
- nextObject;
@end
#endif /* __Enumerating_h__OBJECTS_INCLUDE */

View file

@ -0,0 +1,42 @@
/* Protocol for GNU Objective C invocations
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: February 1996
This file is part of the GNU Objective C Class Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __Invoking_h__OBJECTS_INCLUDE
#define __Invoking_h__OBJECTS_INCLUDE
#include <objects/stdobjects.h>
@protocol Invoking <NSObject>
- invoke;
- invokeWithObject: anObject;
- objectReturnValue;
- (int) intReturnValue;
- (BOOL) returnValueIsTrue;
@end
#endif /* __Invoking_h__OBJECTS_INCLUDE */

View file

@ -0,0 +1,66 @@
/* Protocol for Objective-C objects that hold elements, user gets to set order
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: Feb 1996
This file is part of the GNU Objective C Class Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* 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_OBJECTS_INCLUDE
#define __OrderedCollecting_h_OBJECTS_INCLUDE
#include <objects/stdobjects.h>
#include <objects/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_OBJECTS_INCLUDE */

View file

@ -0,0 +1,39 @@
/* Interface for Objective-C Ordered Collection object.
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: February 1996
This file is part of the GNU Objective C Class Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __OrderedCollection_h_INCLUDE_GNU
#define __OrderedCollection_h_INCLUDE_GNU
#include <objects/stdobjects.h>
#include <objects/IndexedCollection.h>
#include <objects/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_INCLUDE_GNU */

737
Source/Decoder.m Normal file
View file

@ -0,0 +1,737 @@
/* Abstract class for reading objects from a stream
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Created: February 1996
This file is part of the GNU Objective C Class Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <objects/stdobjects.h>
#include <objects/Coder.h>
#include <objects/CoderPrivate.h>
#include <objects/CStream.h>
#include <objects/Stream.h>
#include <objects/StdioStream.h>
#include <objects/Array.h>
#include <Foundation/NSException.h>
#define debug_coder 0
@implementation Decoder
/* Signature Handling. */
+ (void) readSignatureFromCStream: (id <CStreaming>) cs
getClassname: (char *) name
formatVersion: (int*) version
{
int got;
got = [[cs stream] readFormat: SIGNATURE_FORMAT_STRING,
name, version];
if (got != 2)
[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: (id <String>) filename
{
return [self newReadingFromStream:
[StdioStream streamWithFilename: filename
fmode: "r"]];
}
+ decodeObjectWithName: (id <String> *) name
fromStream: (id <Streaming>)stream;
{
id c, o;
c = [self newReadingFromStream:stream];
[c decodeObjectAt: &o withName: name];
[c release];
return [o autorelease];
}
+ decodeObjectWithName: (id <String> *) name
fromFile: (id <String>) 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 refered 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 = [Array new];
/* Append an object so our xref numbers are in sync with the
Encoders, which start at 1. */
[xref_2_object appendObject: [NSObject new]];
}
[xref_2_object appendObject: anObj];
/* This return value should be the same as the index of anObj
in xref_2_object. */
return ([xref_2_object count] - 1);
}
- _coderObjectAtReference: (unsigned)xref
{
assert (xref_2_object);
return [xref_2_object objectAtIndex: xref];
}
/* The methods for the root object table */
- (void) _coderPushRootObjectTable
{
if (!xref_2_object_root)
xref_2_object_root = [Array new];
}
- (void) _coderPopRootObjectTable
{
assert (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 = [Array new];
/* Append an object so our xref numbers are in sync with the
Encoders, which start at 1. */
[xref_2_object_root appendObject: [NSObject new]];
}
[xref_2_object_root appendObject: 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
{
assert (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;
{
assert (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 = objects_list_of_void_p ();
objects_list_append_element (fref_stack, NSCreateMap (...));
#endif
if (!address_2_fref)
address_2_fref = NSCreateMapTable (NSNonOwnedPointerMapKeyCallBacks,
NSIntMapValueCallBacks, 0);
}
- (void) _coderPopForwardObjectTable
{
assert (address_2_fref);
if (!interconnect_stack_height)
{
NSFreeMapTable (address_2_fref);
address_2_fref = NULL;
}
}
- (void) _coderSatisfyForwardReference: (unsigned)fref withObject: anObj
{
assert (address_2_fref);
if (!fref_2_object)
fref_2_object = NSCreateMapTable (NSIntMapKeyCallBacks,
NSObjectMapValueCallBacks, 0);
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. */
assert (address_2_fref);
/* There should not be duplicate addresses */
assert (!NSMapGet (address_2_fref, addr));
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
"_coderPutObject:atReference" 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;
}
/* Method for decoding things. */
- (void) decodeValueOfCType: (const char*)type
at: (void*)d
withName: (id <String> *)namePtr
{
[cstream decodeValueOfCType:type
at:d
withName:namePtr];
}
- (void) decodeBytes: (char *)b
count: (unsigned*)c
withName: (id <String> *) name
{
[self notImplemented:_cmd];
}
- (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)
[self error:"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);
if (ret == Nil)
[self error:"Couldn't find class `%s'", class_name];
if (class_get_version(ret) != class_version)
[self error:"Class version mismatch, executable %d != encoded %d",
class_get_version(ret), class_version];
{
unsigned xref;
xref = [self _coderCreateReferenceForConstPtr: ret];
if (debug_coder)
fprintf(stderr, "Coder decoding registered class xref %u\n", xref);
}
(*objc_free) (class_name);
break;
}
default:
[self error:"unrecognized class tag = %d", (int)tag];
}
[self decodeUnindent];
return ret;
}
- (const char *) decodeAtomicStringWithName: (id <String> *) 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: (id <String> *) 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)
[self error:"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)
[self error:"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)))
[self error:"ObjC runtime didn't provide SEL with matching type"];
#endif
{
unsigned xref;
xref = [self _coderCreateReferenceForConstPtr: ret];
if (debug_coder)
fprintf(stderr, "Coder decoding registered sel xref %u\n", xref);
}
(*objc_free)(sel_name);
(*objc_free)(sel_types);
break;
}
default:
[self error:"unrecognized selector tag = %d", (int)tag];
}
[self decodeUnindent];
return ret;
}
- (void) startDecodingInterconnectedObjects
{
interconnect_stack_height++;
[self _coderPushRootObjectTable];
[self _coderPushForwardObjectTable];
}
- (void) finishDecodingInterconnectedObjects
{
SEL awake_sel = sel_get_any_uid("awakeAfterUsingCoder:");
assert (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. */
/* resolve object forward references */
[self _coderResolveTopForwardReferences];
[self _coderPopForwardObjectTable];
#if 0
When should this be done?
/* send "-awakeAfterUsingCoder:" to all the objects that were read */
/* xxx But this doesn't currently handle the return of a different
object than was messaged! */
if (awake_sel)
{
void ask_awake(elt e)
{
if (__objc_responds_to(e.id_u, awake_sel))
(*objc_msg_lookup(e.id_u,awake_sel))(e.id_u, awake_sel, self);
}
[[self _coderTopRootObjectTable] withElementsCall:ask_awake];
}
#endif
[self _coderPopRootObjectTable];
}
- (void) _decodeRootObjectAt: (id*)ret withName: (id <String> *) name
{
[self startDecodingInterconnectedObjects];
[self decodeObjectAt:ret withName:name];
[self finishDecodingInterconnectedObjects];
}
- (void) decodeValueOfObjCType: (const char*)type
at: (void*)d
withName: (id <String> *)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 */
}
/* This is the designated (and one-and-only) object decoder */
- (void) decodeObjectAt: (id*) anObjPtr withName: (id <String> *) name
{
unsigned char tag;
unsigned fref = 0;
[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:
{
unsigned fref;
if (!DOING_ROOT_OBJECT)
[self error:"can't decode forward reference when not decoding "
"a root object"];
[self decodeValueOfCType: @encode(unsigned)
at: &fref
withName: NULL];
[self _coderAssociateForwardReference: fref
withObjectAddress: anObjPtr];
break;
}
case CODER_OBJECT_FORWARD_SATISFIER:
{
[self decodeValueOfCType: @encode(unsigned)
at: &fref
withName: NULL];
/* NOTE: no "break" here; falling through. */
}
case CODER_OBJECT:
{
Class object_class;
SEL new_sel = sel_get_any_uid ("newWithCoder:");
Method* new_method;
[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)
*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 (init_method)
*anObjPtr =
(*(init_method->method_imp))(*anObjPtr, init_sel, self);
/* xxx else what, error? */
}
/* xxx Should I sent -awakeUsingCoder: here instead of above? */
/* If this was a CODER_OBJECT_FORWARD_SATISFIER, then remember it. */
if (fref)
[self _coderSatisfyForwardReference: fref withObject: *anObjPtr];
/* Would get error here with Connection-wide object references
because addProxy gets called in +newRemote:connection: */
{
unsigned xref =
[self _coderInternalCreateReferenceForObject: *anObjPtr];
if (debug_coder)
fprintf(stderr, "Coder decoding registered class xref %u\n", xref);
}
[self decodeUnindent];
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];
if (!*anObjPtr)
[self error: "repeated object cross-reference number %u not found",
xref];
break;
}
default:
[self error:"unrecognized object tag = %d", (int)tag];
}
[self decodeUnindent];
}
- (void) decodeWithName: (id <String> *)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: (id <String> *)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: (id <String> *) 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: (id <String> *)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

798
Source/Encoder.m Normal file
View file

@ -0,0 +1,798 @@
/* Abstract class for writing objects to a stream
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Created: February 1996
This file is part of the GNU Objective C Class Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <objects/stdobjects.h>
#include <objects/Coder.h>
#include <objects/CoderPrivate.h>
#include <objects/MemoryStream.h>
#include <objects/StdioStream.h>
#include <objects/BinaryCStream.h>
#include <Foundation/NSArchiver.h>
static int default_format_version;
static id default_stream_class;
static id default_cstream_class;
#define debug_coder 0
#define DEFAULT_FORMAT_VERSION 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 == [Coder class])
{
/* This code has not yet been ported to machines for which
a pointer is not the same size as an int. */
assert(sizeof(void*) == sizeof(unsigned));
/* Initialize some defaults. */
default_stream_class = [MemoryStream class];
default_cstream_class = [BinaryCStream class];
default_format_version = 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,
[self defaultDecoderClassname],
format_version];
}
/* 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];
in_progress_table = NULL;
object_2_xref = NULL;
object_2_fref = NULL;
const_ptr_2_xref = NULL;
[self writeSignature];
return self;
}
/* ..Writing... methods */
- initForWritingToStream: (id <Streaming>) s
withCStreamClass: (Class) cStreamClass
{
return [self initForWritingToStream: s
withFormatVersion: DEFAULT_FORMAT_VERSION
cStreamClass: cStreamClass
cStreamFormatVersion: [cStreamClass defaultFormatVersion]];
}
- initForWritingToStream: (id <Streaming>) s
{
return [self initForWritingToStream: s
withCStreamClass: [[self class] defaultCStreamClass]];
}
- initForWritingToFile: (id <String>) 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: (id <String>) filename
withCStreamClass: (Class) cStreamClass
{
return [self initForWritingToStream: [StdioStream
streamWithFilename: filename
fmode: "w"]
withCStreamClass: cStreamClass];
}
- initForWritingToFile: (id <String>) filename
{
return [self initForWritingToStream:
[StdioStream streamWithFilename: filename
fmode: "w"]];
}
+ newWritingToStream: (id <Streaming>)s
{
return [[self alloc] initForWritingToStream: s];
}
+ newWritingToFile: (id <String>)filename
{
return [self newWritingToStream:
[StdioStream streamWithFilename: filename
fmode: "w"]];
}
+ (BOOL) encodeRootObject: anObject
withName: (id <String>) name
toStream: (id <Streaming>)stream
{
id c = [[self alloc] initForWritingToStream: stream];
[c encodeRootObject: anObject withName: name];
[c closeCoding];
[c release];
return YES;
}
+ (BOOL) encodeRootObject: anObject
withName: (id <String>) name
toFile: (id <String>) 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.
For instance, ConnectedCoder keeps cross-references to const
pointers on a per-Connection basis instead of a per-Coder basis.
We avoid encoding/decoding the same classes and selectors over and
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 (const_ptr_2_xref, anObj, (void*)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);
else
assert(! NSMapGet (const_ptr_2_xref, (void*)xref));
xref = NSCountMapTable (const_ptr_2_xref) + 1;
NSMapInsert (const_ptr_2_xref, ptr, (void*)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 = NSCountMapTable (object_2_fref) + 1;
assert ( ! NSMapGet (object_2_fref, anObject));
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];
}
/* Method for encoding things. */
- (void) encodeValueOfCType: (const char*)type
at: (const void*)d
withName: (id <String>)name
{
[cstream encodeValueOfCType:type
at:d
withName:name];
}
- (void) encodeBytes: (const char *)b
count: (unsigned)c
withName: (id <String>)name
{
[self notImplemented:_cmd];
}
- (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);
assert (class_name);
assert (*class_name);
[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: (id <String>) name
{
/* xxx Add repeat-string-ptr checking here. */
[self notImplemented:_cmd];
[self encodeValueOfCType:@encode(char*) at:&sp withName:name];
}
- (void) encodeSelector: (SEL)sel withName: (id <String>) 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_uid (sel_get_name (sel)));
#endif
if (!sel_name) [self error:"ObjC runtime didn't provide SEL name"];
if (!*sel_name) [self error:"ObjC runtime didn't provide SEL name"];
if (!sel_types) [self error:"ObjC runtime didn't provide SEL type"];
if (!*sel_types) [self error:"ObjC runtime didn't provide SEL type"];
[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: (id <String>) 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: */
assert (interconnect_stack_height);
interconnect_stack_height--;
}
/* NOTE: Unlike NeXT's, this *can* be called recursively */
- (void) encodeRootObject: anObj
withName: (id <String>)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 two 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).
ConnectedCoder 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 ConnectedCoder */
- (void) _doEncodeObject: anObj
{
[self _doEncodeBycopyObject:anObj];
}
/* This is the designated object encoder */
- (void) _encodeObject: anObj
withName: (id <String>) name
isBycopy: (BOOL) bycopy_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. */
if (!in_progress_table)
in_progress_table =
NSCreateMapTable (NSObjectMapKeyCallBacks,
NSIntMapValueCallBacks, 0);
NSMapInsert (in_progress_table, anObj, (void*)1);
/* Find out if this object satisfies any previous forward
references. */
fref = [self _coderForwardReferenceForObject: anObj];
if (fref)
{
/* It does satisfy a forward reference; write the forward
reference number, so the decoder can know. */
[self encodeTag: CODER_OBJECT_FORWARD_SATISFIER];
[self encodeValueOfCType: @encode(unsigned)
at: &fref
withName: @"Object forward cross-reference number"];
}
else
{
/* It does not satisfy a forward reference. Note: in future
encoding we may have backward references to this object,
but we will never need forward references to this object. */
[self encodeTag: CODER_OBJECT];
}
/* Encode the object. */
[self encodeIndent];
if (bycopy_flag)
[self _doEncodeBycopyObject:anObj];
else
[self _doEncodeObject:anObj];
[self encodeUnindent];
/* Register that we have encoded it so that future encoding can
do backward references properly. */
[self _coderInternalCreateReferenceForObject: anObj];
/* Remove it from the forward reference table, since we'll never
have another forward reference for this object. */
if (fref)
[self _coderRemoveForwardReferenceForObject: anObj];
/* We're done encoding the object, it's no longer in progress. */
NSMapRemove (in_progress_table, anObj);
}
}
[self encodeUnindent];
}
- (void) encodeObject: anObj
withName: (id <String>)name
{
[self _encodeObject:anObj withName:name isBycopy:NO isForwardReference:NO];
}
- (void) encodeBycopyObject: anObj
withName: (id <String>)name
{
[self _encodeObject:anObj withName:name isBycopy:YES isForwardReference:NO];
}
- (void) encodeObjectReference: anObj
withName: (id <String>)name
{
[self _encodeObject:anObj withName:name isBycopy:NO isForwardReference:YES];
}
- (void) encodeWithName: (id <String>)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: (id <String>)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: (id <String>)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: (id <String>)n
{
[cstream encodeName: n];
}
/* Substituting Classes */
- (id <String>) classNameEncodedForTrueClassName: (id <String>) trueName
{
[self notImplemented: _cmd];
return nil;
#if 0
if (classname_2_classname)
return NSMapGet (classname_2_classname, [trueName cStringNoCopy]);
return trueName;
#endif
}
- (void) encodeClassName: (id <String>) trueName
intoClassName: (id <String>) 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

236
Source/NSCallBacks.m Normal file
View file

@ -0,0 +1,236 @@
/* GNUStep callback functions. Implicitly required by the standard.
* Copyright (C) 1996 Free Software Foundation, Inc.
*
* Author: Albin L. Jones <Albin.L.Jones@Dartmouth.EDU>
* Created: Tue Feb 13 23:10:29 EST 1996
* Updated: Tue Feb 13 23:10:29 EST 1996
* Serial: 96.02.13.01
*
* This file is part of the GNU Objective C Class Library.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
/**** Included Headers *******************************************************/
#include <NSCallBacks.h>
#include <Foundation/NSObject.h>
#include <Foundation/NSString.h>
/**** Type, Constant, and Macro Definitions **********************************/
/**** Function Implementations ***********************************************/
/** For `int's **/
unsigned int
_NS_int_hash (void *table, int i)
{
return (unsigned int) i;
}
BOOL
_NS_int_is_equal (void *table, int i, int j)
{
return (i == j) ? YES : NO;
}
void
_NS_int_retain (void *table, int i)
{
return;
}
void
_NS_int_release (void *table, int i)
{
return;
}
NSString *
_NS_int_describe (void *table, int i)
{
return [NSString stringWithFormat:@"%d", i];
}
/** For owned `void *' **/
unsigned int
_NS_owned_void_p_hash (void *table, void *p)
{
/* P may be aligned, so we need to compensate. */
return ((unsigned int)p)/4;
}
BOOL
_NS_owned_void_p_is_equal (void *table, void *p, void *q)
{
return (p == q) ? YES : NO;
}
void
_NS_owned_void_p_retain (void *table, void *p)
{
return;
}
void
_NS_owned_void_p_release (void *table, void *p)
{
if (p != 0)
free(p);
return;
}
NSString *
_NS_owned_void_p_describe (void *table, void *p)
{
/* This may not be right; I'm doing this off of the top of my head, and
* I'm in a hurry. */
return [NSString stringWithFormat:@"%0x", p];
}
/** For non-retained Objective-C objects **/
unsigned int
_NS_non_retained_id_hash (void *table, id <NSObject> o)
{
return [o hash];
}
BOOL
_NS_non_retained_id_is_equal (void *table, id <NSObject> o, id <NSObject> p)
{
/* Once again I need a nice way to determine whether or not O
* responds to `isEqual:'. */
return [o isEqual:p];
}
void
_NS_non_retained_id_retain (void *table, id <NSObject> o)
{
return;
}
void
_NS_non_retained_id_release (void *table, id <NSObject> o)
{
return;
}
NSString *
_NS_non_retained_id_describe (void *table, id <NSObject> o)
{
/* Once again, I need a nice way to determine whether O responds to
* `describe'. Help. */
return [o description];
}
/** For (retainable) objects **/
unsigned int
_NS_id_hash (void *table, id <NSObject> o)
{
/* See above. */
return [o hash];
}
BOOL
_NS_id_is_equal (void *table, id <NSObject> o, id <NSObject> p)
{
return [o isEqual:p];
}
void
_NS_id_retain (void *table, id <NSObject> o)
{
[o retain];
return;
}
void
_NS_id_release (void *table, id <NSObject> o)
{
[o release];
return;
}
NSString *
_NS_id_describe (void *table, id <NSObject> o)
{
return [o description];
}
/** For (non-owned) `void *' **/
unsigned int
_NS_non_owned_void_p_hash (void *table, void *p)
{
return ((unsigned int)p)/4;
}
BOOL
_NS_non_owned_void_p_is_equal (void *table, void *p, void *q)
{
return (p == q) ? YES : NO;
}
void
_NS_non_owned_void_p_retain (void *table, void *p)
{
return;
}
void
_NS_non_owned_void_p_release (void *table, void *p)
{
return;
}
NSString *
_NS_non_owned_void_p_describe (void *table, void *p)
{
return [NSString stringWithFormat:@"%0x", p];
}
/** For pointers to structures and `int *' **/
unsigned int
_NS_int_p_hash (void *table, int *p)
{
return ((unsigned int)p)/4;
}
BOOL
_NS_int_p_is_equal (void *table, int *p, int *q)
{
return (p == q) ? YES : NO;
}
void
_NS_int_p_retain (void *table, int *p)
{
return;
}
void
_NS_int_p_release (void *table, int *p)
{
return;
}
NSString *
_NS_int_p_describe (void *table, int *p)
{
return [NSString stringWithFormat:@"%d (%0x)", *p, p];
}

View file

@ -0,0 +1,59 @@
/* Private interface for GNU Objective-C coder object for use serializing
Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Created: February 1996
This file is part of the GNU Objective C Class Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __CoderPrivate_h_OBJECTS_INCLUDE
#define __CoderPrivate_h_OBJECTS_INCLUDE
#include <objects/stdobjects.h>
#include <objects/Coder.h>
#include <objects/CStreaming.h>
enum {
CODER_OBJECT_NIL = 0,
CODER_OBJECT,
CODER_OBJECT_ROOT,
CODER_OBJECT_REPEATED,
CODER_OBJECT_FORWARD_REFERENCE,
CODER_OBJECT_FORWARD_SATISFIER,
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;
- (BOOL) _coderHasObjectReference: (unsigned)xref;
@end
#define SIGNATURE_FORMAT_STRING \
@"GNU Objective C Class Library %s version %d\n"
#define NO_SEL_TYPES "none"
#endif /* __CoderPrivate_h_OBJECTS_INCLUDE */

View file

@ -0,0 +1,37 @@
/* Protocol for GNU Objective C invocations
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: February 1996
This file is part of the GNU Objective C Class Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __Enumerating_h__OBJECTS_INCLUDE
#define __Enumerating_h__OBJECTS_INCLUDE
#include <objects/stdobjects.h>
@protocol Enumerating <NSObject>
- initWithCollection: aCollection;
- nextObject;
@end
#endif /* __Enumerating_h__OBJECTS_INCLUDE */

42
Source/objects/Invoking.h Normal file
View file

@ -0,0 +1,42 @@
/* Protocol for GNU Objective C invocations
Copyright (C) 1995, 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: February 1996
This file is part of the GNU Objective C Class Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __Invoking_h__OBJECTS_INCLUDE
#define __Invoking_h__OBJECTS_INCLUDE
#include <objects/stdobjects.h>
@protocol Invoking <NSObject>
- invoke;
- invokeWithObject: anObject;
- objectReturnValue;
- (int) intReturnValue;
- (BOOL) returnValueIsTrue;
@end
#endif /* __Invoking_h__OBJECTS_INCLUDE */

View file

@ -0,0 +1,66 @@
/* Protocol for Objective-C objects that hold elements, user gets to set order
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: Feb 1996
This file is part of the GNU Objective C Class Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* 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_OBJECTS_INCLUDE
#define __OrderedCollecting_h_OBJECTS_INCLUDE
#include <objects/stdobjects.h>
#include <objects/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_OBJECTS_INCLUDE */

View file

@ -0,0 +1,39 @@
/* Interface for Objective-C Ordered Collection object.
Copyright (C) 1996 Free Software Foundation, Inc.
Written by: R. Andrew McCallum <mccallum@gnu.ai.mit.edu>
Date: February 1996
This file is part of the GNU Objective C Class Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef __OrderedCollection_h_INCLUDE_GNU
#define __OrderedCollection_h_INCLUDE_GNU
#include <objects/stdobjects.h>
#include <objects/IndexedCollection.h>
#include <objects/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_INCLUDE_GNU */