mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 00:11:26 +00:00
(USE_OPENSTEP_STYLE_FORWARD_REFERENCES): New macro.
(NSGArchiverNullCStream): New class, interface and implementation. ([NSGArchiverNullCStream -decodeValueOfCType:at:withName:]): New method. ([NSGArchiverNullCStream -decodeValueOfCType:at:withName:]): New method. ([NSGArchiver -encodeRootObject:withName:]): New method. ([NSGArchiver -encodeConditionalObject:]): New method. ([NSGArchiver -_coderCreateReferenceForObject:]): New method. ([NSGArchiver -_coderCreateForwardReferenceForObject:]): New method. ([NSGArchiver -_coderForwardReferenceForObject:]): New method. ([NSGArchiver -_objectWillBeInProgress:]): New method. ([NSGArchiver -_objectNoLongerInProgress:]): New method. ([NSGArchiver -defaultDecoderClassname]): New method. ([NSGUnarchiver -_createReferenceBeforeInit]): New method. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1483 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
69b93a3648
commit
66356eb508
1 changed files with 161 additions and 2 deletions
|
@ -24,8 +24,41 @@
|
|||
#include <gnustep/base/preface.h>
|
||||
#include <Foundation/NSGArchiver.h>
|
||||
#include <gnustep/base/Archiver.h>
|
||||
#include <gnustep/base/CStream.h>
|
||||
#include <gnustep/base/behavior.h>
|
||||
#include <gnustep/base/CoderPrivate.h>
|
||||
#include <Foundation/NSException.h>
|
||||
|
||||
#define USE_OPENSTEP_STYLE_FORWARD_REFERENCES 1
|
||||
|
||||
#if USE_OPENSTEP_STYLE_FORWARD_REFERENCES
|
||||
|
||||
@interface NSGArchiverNullCStream : CStream
|
||||
@end
|
||||
|
||||
@implementation NSGArchiverNullCStream
|
||||
- (void) encodeValueOfCType: (const char*)type
|
||||
at: (const void*)d
|
||||
withName: (id <String>) name
|
||||
{
|
||||
return;
|
||||
}
|
||||
- (void) decodeValueOfCType: (const char*)type
|
||||
at: (void*)d
|
||||
withName: (id <String> *)namePtr
|
||||
{
|
||||
[self shouldNotImplement: _cmd];
|
||||
}
|
||||
@end
|
||||
|
||||
@interface NSGArchiver (Private)
|
||||
- (void) _coderInternalCreateReferenceForObject: anObj;
|
||||
- (void) encodeTag: (unsigned char)t;
|
||||
@end
|
||||
|
||||
#endif /* USE_OPENSTEP_STYLE_FORWARD_REFERENCES */
|
||||
|
||||
|
||||
@implementation NSGArchiver
|
||||
|
||||
+ (void) initialize
|
||||
|
@ -34,6 +67,125 @@
|
|||
class_add_behavior([NSGArchiver class], [Archiver class]);
|
||||
}
|
||||
|
||||
#if USE_OPENSTEP_STYLE_FORWARD_REFERENCES
|
||||
|
||||
/* Use this if you want to define any other methods... */
|
||||
//#define self ((Archiver*)self)
|
||||
#define cstream (((Archiver*)self)->cstream)
|
||||
#define in_progress_table (((Archiver*)self)->in_progress_table)
|
||||
#define object_2_fref (((Archiver*)self)->object_2_fref)
|
||||
#define object_2_xref (((Archiver*)self)->object_2_xref)
|
||||
#define const_ptr_2_xref (((Archiver*)self)->const_ptr_2_xref)
|
||||
#define fref_counter (((Archiver*)self)->fref_counter)
|
||||
|
||||
/* Unlike the GNU version, this cannot be called recursively. */
|
||||
- (void) encodeRootObject: anObj
|
||||
withName: (id <String>)name
|
||||
{
|
||||
id saved_cstream;
|
||||
|
||||
/* Make sure that we're in a clean state. */
|
||||
NSParameterAssert (!object_2_xref);
|
||||
NSParameterAssert (!object_2_fref);
|
||||
|
||||
object_2_fref =
|
||||
NSCreateMapTable (NSNonOwnedPointerOrNullMapKeyCallBacks,
|
||||
NSIntMapValueCallBacks, 0);
|
||||
|
||||
/* First encode to a null cstream, and record all the objects that
|
||||
will be encoded. They will get recorded in [NSGArchiver
|
||||
-_coderCreateReferenceForObject:] */
|
||||
saved_cstream = cstream;
|
||||
cstream = [[NSGArchiverNullCStream alloc] init];
|
||||
[self startEncodingInterconnectedObjects];
|
||||
[self encodeObject: anObj withName: name];
|
||||
[self finishEncodingInterconnectedObjects];
|
||||
|
||||
[cstream release];
|
||||
cstream = saved_cstream;
|
||||
/* Reset ourselves, except for object_2_fref. */
|
||||
assert (!in_progress_table);
|
||||
NSResetMapTable (object_2_xref);
|
||||
NSResetMapTable (const_ptr_2_xref);
|
||||
assert (fref_counter == 0);
|
||||
|
||||
/* Then encode everything "for real". */
|
||||
[self encodeName: @"Root Object"];
|
||||
[self encodeIndent];
|
||||
[(id)self encodeTag: CODER_OBJECT_ROOT];
|
||||
[self startEncodingInterconnectedObjects];
|
||||
[self encodeObject: anObj withName: name];
|
||||
[self finishEncodingInterconnectedObjects];
|
||||
[self encodeUnindent];
|
||||
}
|
||||
|
||||
- (void) encodeConditionalObject: (id)anObject
|
||||
{
|
||||
if ([cstream class] == [NSGArchiverNullCStream class])
|
||||
/* If we're gathering a list of all the objects that will be
|
||||
encoded (for the first half of a -encodeRootObject:), then do
|
||||
nothing. */
|
||||
return;
|
||||
else
|
||||
{
|
||||
/* Otherwise, we've already gathered a list of all the objects
|
||||
into objects_2_fref; if the object is there, encode it. */
|
||||
if (NSMapGet (object_2_fref, anObject))
|
||||
[self encodeObject: anObject];
|
||||
else
|
||||
[self encodeObject: nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (unsigned) _coderCreateReferenceForObject: anObj
|
||||
{
|
||||
if ([cstream class] == [NSGArchiverNullCStream class])
|
||||
/* If we're just gathering a list of all the objects that will be
|
||||
encoded (for the first half of a -encodeRootObject:), then just
|
||||
put it in object_2_fref. */
|
||||
NSMapInsert (object_2_fref, anObj, (void*)1);
|
||||
|
||||
/* Do the normal thing. */
|
||||
return (unsigned) CALL_METHOD_IN_CLASS ([Archiver class],
|
||||
_coderCreateReferenceForObject:,
|
||||
anObj);
|
||||
}
|
||||
|
||||
- (unsigned) _coderCreateForwardReferenceForObject: anObject
|
||||
{
|
||||
/* We should never get here. */
|
||||
[self shouldNotImplement: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (unsigned) _coderForwardReferenceForObject: anObject
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (void) _objectWillBeInProgress: anObj
|
||||
{
|
||||
/* OpenStep-style coding doesn't keep an in-progress table. */
|
||||
/* Register that we have encoded it so that future encoding can
|
||||
do backward references properly. */
|
||||
[self _coderInternalCreateReferenceForObject: anObj];
|
||||
}
|
||||
|
||||
- (void) _objectNoLongerInProgress: anObj
|
||||
{
|
||||
/* OpenStep-style coding doesn't keep an in-progress table. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* xxx This method interface may change in the future. */
|
||||
- (const char *) defaultDecoderClassname
|
||||
{
|
||||
return "NSGUnarchiver";
|
||||
}
|
||||
|
||||
#undef self
|
||||
#endif /* USE_OPENSTEP_STYLE_FORWARD_REFERENCES */
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSGUnarchiver
|
||||
|
@ -44,7 +196,14 @@
|
|||
class_add_behavior([NSGUnarchiver class], [Unarchiver class]);
|
||||
}
|
||||
|
||||
#if USE_OPENSTEP_STYLE_FORWARD_REFERENCES
|
||||
|
||||
- (BOOL) _createReferenceBeforeInit
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
#endif /* USE_OPENSTEP_STYLE_FORWARD_REFERENCES */
|
||||
|
||||
@end
|
||||
|
||||
/* Use this if you want to define any other methods... */
|
||||
#define self ((Coder*)self)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue