1997-01-05 22:41:44 +00:00
|
|
|
|
/* Test use of -awakeAfterUsingCoder:
|
|
|
|
|
This is a rather complicated, strenuous test, borrowing elements
|
|
|
|
|
from the fref.m test. */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Beginning of some parameters to vary. */
|
2005-02-22 11:22:44 +00:00
|
|
|
|
/* 0 and 0 works.
|
1997-01-05 22:41:44 +00:00
|
|
|
|
1 and 0 works for the first test, but has no way of getting the
|
|
|
|
|
super_foo in second test right, because we haven't resolved the
|
|
|
|
|
forward reference when -awakeAfterUsingCoder is called; this is
|
|
|
|
|
an inherent problem of decoding.
|
|
|
|
|
0 and 1 crashes, as does NeXT's (for reasons related to forward
|
|
|
|
|
references, having nothing to do with awakeAfterUsingCoder). */
|
|
|
|
|
|
|
|
|
|
/* Use GNU Archiving features, if they are available. */
|
|
|
|
|
#define TRY_GNU_ARCHIVING 0
|
|
|
|
|
|
|
|
|
|
/* In the forward self-reference test, -initWithCoder substitutes
|
|
|
|
|
another object for self. */
|
|
|
|
|
#define SELF_REF_INITWITHCODER_SUBSTITUTES 0
|
|
|
|
|
|
|
|
|
|
/* End of some parameters to vary. */
|
|
|
|
|
|
|
|
|
|
#ifdef NX_CURRENT_COMPILER_RELEASE
|
|
|
|
|
#include <foundation/NSArchiver.h>
|
|
|
|
|
#include <foundation/NSArray.h>
|
|
|
|
|
#include <foundation/NSAutoreleasePool.h>
|
|
|
|
|
#else
|
|
|
|
|
#include <Foundation/NSArchiver.h>
|
|
|
|
|
#include <Foundation/NSArray.h>
|
|
|
|
|
#include <Foundation/NSAutoreleasePool.h>
|
|
|
|
|
#endif
|
1998-10-20 14:44:00 +00:00
|
|
|
|
#include <Foundation/NSDebug.h>
|
1997-01-05 22:41:44 +00:00
|
|
|
|
|
|
|
|
|
#define GNU_ARCHIVING \
|
|
|
|
|
(TRY_GNU_ARCHIVING && defined(GNUSTEP_BASE_MAJOR_VERSION))
|
|
|
|
|
|
|
|
|
|
#if GNU_ARCHIVING
|
2003-07-31 23:49:32 +00:00
|
|
|
|
#include <GNUstepBase/Archiver.h>
|
1997-01-05 22:41:44 +00:00
|
|
|
|
#endif /* GNU_ARCHIVING */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* The -initWithCoder methods substitutes another object for self. */
|
|
|
|
|
int initWithCoder_substitutes;
|
|
|
|
|
int Foo_awakeAfterUsingCoder_substitutes = 0;
|
|
|
|
|
int SubFoo_awakeAfterUsingCoder_substitutes = 1;
|
|
|
|
|
|
|
|
|
|
/* This object encodes an -encodeConditionalObject: reference to a Foo. */
|
|
|
|
|
@interface SubFoo : NSObject
|
|
|
|
|
{
|
|
|
|
|
id super_foo;
|
|
|
|
|
int label;
|
|
|
|
|
}
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
/* This object encodes an -encodeObject: reference to a SubFoo */
|
|
|
|
|
/* Object may offer a replacement of itself using -awakeAfterUsingCoder: */
|
|
|
|
|
@interface Foo : NSObject
|
|
|
|
|
{
|
|
|
|
|
id sub_foo;
|
|
|
|
|
int label;
|
|
|
|
|
}
|
|
|
|
|
- (int) label;
|
|
|
|
|
- (void) setLabel: (int)l;
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Object may offer a replacement of itself using -awakeAfterUsingCoder: */
|
|
|
|
|
@implementation SubFoo
|
|
|
|
|
|
|
|
|
|
- initWithSuperFoo: o label: (int)l
|
|
|
|
|
{
|
|
|
|
|
[super init];
|
|
|
|
|
super_foo = o;
|
|
|
|
|
label = l;
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- awakeAfterUsingCoder: coder
|
|
|
|
|
{
|
|
|
|
|
if (SubFoo_awakeAfterUsingCoder_substitutes)
|
|
|
|
|
{
|
|
|
|
|
SubFoo *replacement = [[[self class] alloc]
|
|
|
|
|
initWithSuperFoo: super_foo
|
|
|
|
|
label: label + 100];
|
|
|
|
|
/* NOTE: We can't use the ivar SUPER_FOO here because it won't have
|
|
|
|
|
been resolved by the Decoder yet. */
|
|
|
|
|
[self release];
|
|
|
|
|
return replacement;
|
|
|
|
|
}
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- superFoo
|
|
|
|
|
{
|
|
|
|
|
return super_foo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) encodeWithCoder: coder
|
|
|
|
|
{
|
|
|
|
|
printf ("In [SubFoo encodeWithCoder:]\n");
|
|
|
|
|
#if GNU_ARCHIVING
|
|
|
|
|
[coder encodeObjectReference: super_foo
|
|
|
|
|
withName: @"super foo"];
|
|
|
|
|
#else
|
|
|
|
|
[coder encodeConditionalObject: super_foo];
|
|
|
|
|
#endif
|
|
|
|
|
[coder encodeValueOfObjCType: @encode(int)
|
|
|
|
|
at: &label];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- initWithCoder: coder
|
|
|
|
|
{
|
|
|
|
|
if (initWithCoder_substitutes)
|
|
|
|
|
{
|
|
|
|
|
id o = self;
|
|
|
|
|
self = [[[self class] alloc] init];
|
|
|
|
|
[o release];
|
|
|
|
|
}
|
|
|
|
|
#if GNU_ARCHIVING
|
|
|
|
|
[coder decodeObjectAt: &super_foo
|
|
|
|
|
withName: NULL];
|
|
|
|
|
#else
|
|
|
|
|
super_foo = [coder decodeObject];
|
|
|
|
|
#endif
|
|
|
|
|
[coder decodeValueOfObjCType: @encode(int)
|
|
|
|
|
at: &label];
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) print
|
|
|
|
|
{
|
|
|
|
|
printf ("SubFoo label = %d, super label = %d\n",
|
|
|
|
|
label, [super_foo label]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
2005-02-22 11:22:44 +00:00
|
|
|
|
@implementation Foo
|
1997-01-05 22:41:44 +00:00
|
|
|
|
|
|
|
|
|
- init
|
|
|
|
|
{
|
|
|
|
|
[super init];
|
|
|
|
|
sub_foo = nil;
|
|
|
|
|
label = 0;
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- awakeAfterUsingCoder: coder
|
|
|
|
|
{
|
|
|
|
|
if (Foo_awakeAfterUsingCoder_substitutes)
|
|
|
|
|
{
|
|
|
|
|
Foo *replacement = [[[self class] alloc] init];
|
|
|
|
|
[replacement setLabel: label + 100];
|
|
|
|
|
/* NOTE: We can't use the ivar SUPER_FOO here because it won't have
|
|
|
|
|
been resolved by the Decoder yet. */
|
|
|
|
|
[self release];
|
|
|
|
|
return replacement;
|
|
|
|
|
}
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) setSubFoo: o
|
|
|
|
|
{
|
|
|
|
|
sub_foo = o;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- subFoo
|
|
|
|
|
{
|
|
|
|
|
return sub_foo;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) encodeWithCoder: coder
|
|
|
|
|
{
|
|
|
|
|
printf ("In [Foo encodeWithCoder:]\n");
|
|
|
|
|
[coder encodeObject: sub_foo];
|
|
|
|
|
[coder encodeValueOfObjCType: @encode(int)
|
|
|
|
|
at: &label];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- initWithCoder: coder
|
|
|
|
|
{
|
|
|
|
|
if (initWithCoder_substitutes)
|
|
|
|
|
{
|
|
|
|
|
id o = self;
|
|
|
|
|
self = [[[self class] alloc] init];
|
|
|
|
|
[o release];
|
|
|
|
|
}
|
|
|
|
|
sub_foo = [coder decodeObject];
|
|
|
|
|
[coder decodeValueOfObjCType: @encode(int)
|
|
|
|
|
at: &label];
|
|
|
|
|
return self;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (int) label
|
|
|
|
|
{
|
|
|
|
|
return label;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) setLabel: (int)l
|
|
|
|
|
{
|
|
|
|
|
label = l;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
- (void) print
|
|
|
|
|
{
|
|
|
|
|
printf (" Foo label = %d, sub label = %d\n",
|
|
|
|
|
label, [sub_foo label]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
2005-02-22 11:22:44 +00:00
|
|
|
|
/* Test the use of -encodeConditional to encode a forward reference
|
1997-01-05 22:41:44 +00:00
|
|
|
|
to an object. */
|
|
|
|
|
void
|
|
|
|
|
test_fref ()
|
|
|
|
|
{
|
|
|
|
|
id array;
|
|
|
|
|
id foo, sub_foo;
|
|
|
|
|
printf ("\nTest awakeAfterUsingCoder substitution of objects that will\n"
|
|
|
|
|
" satisfy backward references\n");
|
|
|
|
|
initWithCoder_substitutes = 0;
|
|
|
|
|
|
|
|
|
|
array = [[NSMutableArray alloc] init];
|
|
|
|
|
foo = [[Foo alloc] init];
|
|
|
|
|
[foo setLabel: 4];
|
|
|
|
|
sub_foo = [[SubFoo alloc] initWithSuperFoo: nil label: 3];
|
|
|
|
|
[array addObject: foo];
|
|
|
|
|
[array addObject: sub_foo];
|
|
|
|
|
|
|
|
|
|
#if GNU_ARCHIVING
|
|
|
|
|
[Archiver archiveRootObject: array toFile: @"fref.dat"];
|
|
|
|
|
#else
|
|
|
|
|
[NSArchiver archiveRootObject: array toFile: @"fref.dat"];
|
|
|
|
|
#endif
|
|
|
|
|
printf ("Encoded: ");
|
|
|
|
|
[sub_foo print];
|
|
|
|
|
[foo release];
|
|
|
|
|
[sub_foo release];
|
|
|
|
|
[array release];
|
|
|
|
|
|
|
|
|
|
array = [NSUnarchiver unarchiveObjectWithFile: @"fref.dat"];
|
|
|
|
|
foo = [array objectAtIndex: 0];
|
|
|
|
|
sub_foo = [array objectAtIndex: 1];
|
|
|
|
|
printf ("Decoded: ");
|
|
|
|
|
[sub_foo print];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Test awakeAfterUsingCoder of a self-referential forward reference. */
|
|
|
|
|
void
|
|
|
|
|
test_self_fref ()
|
|
|
|
|
{
|
|
|
|
|
id foo, sub_foo;
|
|
|
|
|
printf ("\nTest awakeAfterUsingCoder substitution of objects that\n"
|
|
|
|
|
" will satisfy self-referential forward references\n");
|
|
|
|
|
initWithCoder_substitutes = SELF_REF_INITWITHCODER_SUBSTITUTES;
|
|
|
|
|
|
|
|
|
|
foo = [[Foo alloc] init];
|
|
|
|
|
[foo setLabel: 4];
|
|
|
|
|
sub_foo = [[SubFoo alloc] initWithSuperFoo: foo label: 3];
|
|
|
|
|
[foo setSubFoo: sub_foo];
|
|
|
|
|
|
|
|
|
|
#if GNU_ARCHIVING
|
|
|
|
|
[Archiver archiveRootObject: foo toFile: @"fref.dat"];
|
|
|
|
|
#else
|
|
|
|
|
[NSArchiver archiveRootObject: foo toFile: @"fref.dat"];
|
|
|
|
|
#endif
|
|
|
|
|
printf ("Encoded: ");
|
|
|
|
|
[sub_foo print];
|
|
|
|
|
[foo release];
|
|
|
|
|
[sub_foo release];
|
|
|
|
|
|
|
|
|
|
foo = [NSUnarchiver unarchiveObjectWithFile: @"fref.dat"];
|
|
|
|
|
sub_foo = [foo subFoo];
|
|
|
|
|
printf ("Decoded: ");
|
|
|
|
|
[sub_foo print];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int
|
|
|
|
|
main ()
|
|
|
|
|
{
|
1998-10-20 14:44:00 +00:00
|
|
|
|
id arp;
|
|
|
|
|
|
|
|
|
|
arp = [NSAutoreleasePool new];
|
|
|
|
|
[NSAutoreleasePool enableDoubleReleaseCheck:YES];
|
|
|
|
|
GSDebugAllocationActive(YES);
|
1997-01-05 22:41:44 +00:00
|
|
|
|
|
|
|
|
|
#if TEXTCSTREAM
|
|
|
|
|
[Archiver setDefaultCStreamClass: [TextCStream class]];
|
|
|
|
|
#endif
|
|
|
|
|
|
1998-10-20 14:44:00 +00:00
|
|
|
|
[arp release];
|
|
|
|
|
arp = [NSAutoreleasePool new];
|
1997-01-05 22:41:44 +00:00
|
|
|
|
printf ("Decoded SubFoo label's should be 100 more than Encoded.\n");
|
|
|
|
|
test_fref ();
|
1998-10-20 14:44:00 +00:00
|
|
|
|
[arp release];
|
|
|
|
|
arp = [NSAutoreleasePool new];
|
1997-01-05 22:41:44 +00:00
|
|
|
|
test_self_fref ();
|
|
|
|
|
[arp release];
|
1998-10-20 14:44:00 +00:00
|
|
|
|
printf("Object allocation info -\n%s\n", GSDebugAllocationList(0));
|
1997-01-05 22:41:44 +00:00
|
|
|
|
exit (0);
|
|
|
|
|
}
|