mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-03 21:31:00 +00:00
(debug_coder): Make it a static var instead of a #define.
([Decoder -_coderCreateReferenceForObject:]): Add a debugging message. ([Decoder -_coderCreateReferenceForInterconnectedObject:]): Autorelease the placeholder object. ([Decoder -_createReferenceBeforeInit]): New method. By default return NO, for the GNU-style forward references. ([Decoder -decodeObjectAt:anObjPtr:name]): [CODER_OBJECT]: Use new method; if it returns true, then we are using non-GNU, OpenStep-style forward references. In this case: (1) don't try to decode the object by sending +newWithCoder:, in fact, raise an error if the object wanted to be decoded that way; (2) call _coderInternalCreateReferenceForObject before sending -initWithCoder, not after; unfortunately this means that -initWithCoder methods cannot substitute another object for self. If it returns false, use the more robust GNU style forward references. The NSGUnarchiver overrides this method to use the OpenStep style. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@1480 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
e16a142cde
commit
1e171d13a7
1 changed files with 33 additions and 13 deletions
|
@ -30,7 +30,7 @@
|
||||||
#include <gnustep/base/Array.h>
|
#include <gnustep/base/Array.h>
|
||||||
#include <Foundation/NSException.h>
|
#include <Foundation/NSException.h>
|
||||||
|
|
||||||
#define debug_coder 0
|
static int debug_coder = 0;
|
||||||
|
|
||||||
@implementation Decoder
|
@implementation Decoder
|
||||||
|
|
||||||
|
@ -109,7 +109,7 @@
|
||||||
|
|
||||||
|
|
||||||
/* Functions and methods for keeping cross-references
|
/* Functions and methods for keeping cross-references
|
||||||
so objects that were already read can be refered to again. */
|
so objects that were already read can be referred to again. */
|
||||||
|
|
||||||
/* These _coder... methods may be overriden by subclasses so that
|
/* These _coder... methods may be overriden by subclasses so that
|
||||||
cross-references can be kept differently. */
|
cross-references can be kept differently. */
|
||||||
|
@ -123,6 +123,9 @@
|
||||||
Encoders, which start at 1. */
|
Encoders, which start at 1. */
|
||||||
[xref_2_object appendObject: [NSObject new]];
|
[xref_2_object appendObject: [NSObject new]];
|
||||||
}
|
}
|
||||||
|
if (debug_coder)
|
||||||
|
fprintf (stderr, "Decoder registering object xref %u\n",
|
||||||
|
[xref_2_object count] - 1);
|
||||||
[xref_2_object appendObject: anObj]; // xxx but this will retain anObj. NO.
|
[xref_2_object appendObject: anObj]; // xxx but this will retain anObj. NO.
|
||||||
/* This return value should be the same as the index of anObj
|
/* This return value should be the same as the index of anObj
|
||||||
in xref_2_object. */
|
in xref_2_object. */
|
||||||
|
@ -161,7 +164,7 @@
|
||||||
xref_2_object_root = [Array new];
|
xref_2_object_root = [Array new];
|
||||||
/* Append an object so our xref numbers are in sync with the
|
/* Append an object so our xref numbers are in sync with the
|
||||||
Encoders, which start at 1. */
|
Encoders, which start at 1. */
|
||||||
[xref_2_object_root appendObject: [NSObject new]];
|
[xref_2_object_root appendObject: [[NSObject new] autorelease]];
|
||||||
}
|
}
|
||||||
[xref_2_object_root appendObject: anObj];
|
[xref_2_object_root appendObject: anObj];
|
||||||
/* This return value should be the same as the index of anObj
|
/* This return value should be the same as the index of anObj
|
||||||
|
@ -276,7 +279,7 @@
|
||||||
|
|
||||||
|
|
||||||
/* This is the Coder's interface to the over-ridable
|
/* This is the Coder's interface to the over-ridable
|
||||||
"_coderPutObject:atReference" method. Do not override it. It
|
"_coderCreateReferenceForObject" method. Do not override it. It
|
||||||
handles the xref_2_object_root. */
|
handles the xref_2_object_root. */
|
||||||
|
|
||||||
- (unsigned) _coderInternalCreateReferenceForObject: anObj
|
- (unsigned) _coderInternalCreateReferenceForObject: anObj
|
||||||
|
@ -378,7 +381,8 @@
|
||||||
unsigned xref;
|
unsigned xref;
|
||||||
xref = [self _coderCreateReferenceForConstPtr: ret];
|
xref = [self _coderCreateReferenceForConstPtr: ret];
|
||||||
if (debug_coder)
|
if (debug_coder)
|
||||||
fprintf(stderr, "Coder decoding registered class xref %u\n", xref);
|
fprintf(stderr,
|
||||||
|
"Decoder decoding registered class xref %u\n", xref);
|
||||||
}
|
}
|
||||||
(*objc_free) (class_name);
|
(*objc_free) (class_name);
|
||||||
break;
|
break;
|
||||||
|
@ -460,7 +464,8 @@
|
||||||
unsigned xref;
|
unsigned xref;
|
||||||
xref = [self _coderCreateReferenceForConstPtr: ret];
|
xref = [self _coderCreateReferenceForConstPtr: ret];
|
||||||
if (debug_coder)
|
if (debug_coder)
|
||||||
fprintf(stderr, "Coder decoding registered sel xref %u\n", xref);
|
fprintf(stderr,
|
||||||
|
"Decoder decoding registered sel xref %u\n", xref);
|
||||||
}
|
}
|
||||||
(*objc_free)(sel_name);
|
(*objc_free)(sel_name);
|
||||||
(*objc_free)(sel_types);
|
(*objc_free)(sel_types);
|
||||||
|
@ -558,6 +563,11 @@
|
||||||
/* xxx We need to catch unions and make a sensible error message */
|
/* 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 */
|
/* This is the designated (and one-and-only) object decoder */
|
||||||
- (void) decodeObjectAt: (id*) anObjPtr withName: (id <String> *) name
|
- (void) decodeObjectAt: (id*) anObjPtr withName: (id <String> *) name
|
||||||
{
|
{
|
||||||
|
@ -606,6 +616,7 @@
|
||||||
Class object_class;
|
Class object_class;
|
||||||
SEL new_sel = sel_get_any_uid ("newWithCoder:");
|
SEL new_sel = sel_get_any_uid ("newWithCoder:");
|
||||||
Method* new_method;
|
Method* new_method;
|
||||||
|
BOOL create_ref_before_init = [self _createReferenceBeforeInit];
|
||||||
|
|
||||||
[self decodeIndent];
|
[self decodeIndent];
|
||||||
object_class = [self decodeClass];
|
object_class = [self decodeClass];
|
||||||
|
@ -614,15 +625,22 @@
|
||||||
argument, not the metaclass! */
|
argument, not the metaclass! */
|
||||||
new_method = class_get_class_method(class_get_meta_class(object_class),
|
new_method = class_get_class_method(class_get_meta_class(object_class),
|
||||||
new_sel);
|
new_sel);
|
||||||
if (new_method)
|
if (new_method && !create_ref_before_init)
|
||||||
*anObjPtr = (*(new_method->method_imp))(object_class, new_sel, self);
|
*anObjPtr = (*(new_method->method_imp))(object_class, new_sel, self);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SEL init_sel = sel_get_any_uid("initWithCoder:");
|
SEL init_sel = sel_get_any_uid("initWithCoder:");
|
||||||
Method *init_method =
|
Method *init_method =
|
||||||
class_get_instance_method(object_class, init_sel);
|
class_get_instance_method(object_class, init_sel);
|
||||||
|
|
||||||
|
NSAssert (!create_ref_before_init,
|
||||||
|
@"You are trying to decode an object with the non-GNU"
|
||||||
|
@"OpenStep-style of forward references, but the object's"
|
||||||
|
@"decoding mechanism wants to use GNU features.");
|
||||||
/* xxx Or should I send +alloc? */
|
/* xxx Or should I send +alloc? */
|
||||||
*anObjPtr = (id) NSAllocateObject (object_class, 0, zone);
|
*anObjPtr = (id) NSAllocateObject (object_class, 0, zone);
|
||||||
|
if (create_ref_before_init)
|
||||||
|
[self _coderInternalCreateReferenceForObject: *anObjPtr];
|
||||||
if (init_method)
|
if (init_method)
|
||||||
*anObjPtr =
|
*anObjPtr =
|
||||||
(*(init_method->method_imp))(*anObjPtr, init_sel, self);
|
(*(init_method->method_imp))(*anObjPtr, init_sel, self);
|
||||||
|
@ -640,12 +658,14 @@
|
||||||
|
|
||||||
/* Would get error here with Connection-wide object references
|
/* Would get error here with Connection-wide object references
|
||||||
because addProxy gets called in +newRemote:connection: */
|
because addProxy gets called in +newRemote:connection: */
|
||||||
{
|
if (!create_ref_before_init)
|
||||||
unsigned xref =
|
{
|
||||||
[self _coderInternalCreateReferenceForObject: *anObjPtr];
|
unsigned xref =
|
||||||
if (debug_coder)
|
[self _coderInternalCreateReferenceForObject: *anObjPtr];
|
||||||
fprintf(stderr, "Coder decoding registered class xref %u\n", xref);
|
if (debug_coder)
|
||||||
}
|
fprintf(stderr,
|
||||||
|
"Decoder decoding registered class xref %u\n", xref);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CODER_OBJECT_ROOT:
|
case CODER_OBJECT_ROOT:
|
||||||
|
|
Loading…
Reference in a new issue