mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-30 16:30:41 +00:00
Archiver update.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3109 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
ef32816527
commit
e6d36d8e5c
5 changed files with 2338 additions and 167 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
||||||
|
Sat Oct 24 11:30:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
|
src/NSArchiver.m: New implementation
|
||||||
|
src/NSArchiver.m: New file
|
||||||
|
src/GNUmakefile: Added NSUnarchiver.m
|
||||||
|
src/include/NSArchiver.h: New version
|
||||||
|
New Archiver/unarchiver - OPENSTEP complient (I think).
|
||||||
|
Basic functionality tested fairly thoroughly, some of the more
|
||||||
|
unusual bits untested so far. Mechanisms for adding other backends
|
||||||
|
in place, but untested. Performance may be around four times that
|
||||||
|
of the old version though there is still a little (very little)
|
||||||
|
room for improvement.
|
||||||
|
|
||||||
Thu Oct 22 21:45:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
Thu Oct 22 21:45:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
src/NSData.m: Added support for serialisation of Class and SEL types
|
src/NSData.m: Added support for serialisation of Class and SEL types
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Interface for NSArchiver for GNUStep
|
/* Interface for NSArchiver for GNUStep
|
||||||
Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
|
Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
|
||||||
|
|
||||||
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
Written by: Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
|
||||||
Date: March 1995
|
Date: March 1995
|
||||||
|
@ -26,9 +26,40 @@
|
||||||
|
|
||||||
#include <Foundation/NSCoder.h>
|
#include <Foundation/NSCoder.h>
|
||||||
|
|
||||||
@class NSMutableData, NSData, NSString;
|
@class NSMutableDictionary, NSMutableData, NSData, NSString;
|
||||||
|
|
||||||
|
#define _C_NONE 0x00 /* No type information. */
|
||||||
|
#define _C_MASK 0x7f /* Basic type info. */
|
||||||
|
#define _C_XREF 0x80 /* Cross reference to an item. */
|
||||||
|
|
||||||
@interface NSArchiver : NSCoder
|
@interface NSArchiver : NSCoder
|
||||||
|
{
|
||||||
|
NSMutableData *data; /* Data to write into. */
|
||||||
|
id dst; /* Serialization destination. */
|
||||||
|
IMP serImp; /* Method to serialize with. */
|
||||||
|
IMP tagImp; /* Serialize a type tag. */
|
||||||
|
IMP xRefImp; /* Serialize a crossref. */
|
||||||
|
IMP eObjImp; /* Method to encode an id. */
|
||||||
|
IMP eValImp; /* Method to encode others. */
|
||||||
|
#ifndef _IN_NSARCHIVER_M
|
||||||
|
#define FastMapTable void*
|
||||||
|
#endif
|
||||||
|
FastMapTable clsMap; /* Class cross references. */
|
||||||
|
FastMapTable cIdMap; /* Conditionally coded. */
|
||||||
|
FastMapTable uIdMap; /* Unconditionally coded. */
|
||||||
|
FastMapTable ptrMap; /* Constant pointers. */
|
||||||
|
FastMapTable namMap; /* Mappings for class names. */
|
||||||
|
FastMapTable repMap; /* Mappings for objects. */
|
||||||
|
#ifndef _IN_NSARCHIVER_M
|
||||||
|
#undef FastMapTable
|
||||||
|
#endif
|
||||||
|
unsigned xRefC; /* Counter for cross-reference. */
|
||||||
|
unsigned xRefO; /* Counter for cross-reference. */
|
||||||
|
unsigned xRefP; /* Counter for cross-reference. */
|
||||||
|
unsigned startPos; /* Where in data we started. */
|
||||||
|
BOOL isEncodingRootObject;
|
||||||
|
BOOL isInPreparatoryPass;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initializing an archiver */
|
/* Initializing an archiver */
|
||||||
- (id) initForWritingWithMutableData: (NSMutableData*)mdata;
|
- (id) initForWritingWithMutableData: (NSMutableData*)mdata;
|
||||||
|
@ -38,19 +69,110 @@
|
||||||
+ (BOOL) archiveRootObject: (id)rootObject toFile: (NSString*)path;
|
+ (BOOL) archiveRootObject: (id)rootObject toFile: (NSString*)path;
|
||||||
|
|
||||||
/* Getting data from the archiver */
|
/* Getting data from the archiver */
|
||||||
+ unarchiveObjectWithData: (NSData*) data;
|
|
||||||
+ unarchiveObjectWithFile: (NSString*) path;
|
|
||||||
- (NSMutableData*) archiverData;
|
- (NSMutableData*) archiverData;
|
||||||
|
|
||||||
/* Substituting Classes */
|
/* Substituting Classes */
|
||||||
+ (NSString*) classNameEncodedForTrueClassName: (NSString*) trueName;
|
- (NSString*) classNameEncodedForTrueClassName: (NSString*) trueName;
|
||||||
- (void) encodeClassName: (NSString*)trueName
|
- (void) encodeClassName: (NSString*)trueName
|
||||||
intoClassName: (NSString*)inArchiveName;
|
intoClassName: (NSString*)inArchiveName;
|
||||||
|
|
||||||
|
/* Substituting Objects */
|
||||||
|
- (void) replaceObject: (id)object
|
||||||
|
withObject: (id)newObject;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface NSArchiver (GNUstep)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Re-using the archiver - the 'resetArchiver' method resets the internal
|
||||||
|
* state of the archiver so that you can re-use it rather than having to
|
||||||
|
* destroy it and create a new one.
|
||||||
|
* NB. you would normally want to issue a 'setLength:0' message to the
|
||||||
|
* mutable data object used by the archiver as well, othewrwise the next
|
||||||
|
* root object encoded will be appended to data.
|
||||||
|
*/
|
||||||
|
- (void) resetArchiver;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Subclassing with different output format.
|
||||||
|
* NSArchiver normally writes directly to an NSMutableData object using
|
||||||
|
* the methods -
|
||||||
|
* [-serializeTypeTag:]
|
||||||
|
* to encode type tags for data items, the tag is the
|
||||||
|
* first byte of the character encoding string for the
|
||||||
|
* data type (as provided by '@encode(xxx)'), possibly
|
||||||
|
* with the top bit set to indicate that what follows is
|
||||||
|
* a crossreference to an item already encoded.
|
||||||
|
* [-serializeCrossRef:],
|
||||||
|
* to encode a crossreference number either to identify the
|
||||||
|
* following item, or to refer to a previously encoded item.
|
||||||
|
* Objects, Classes, Selectors, CStrings and Pointer items
|
||||||
|
* have crossreference encoding, other types do not.
|
||||||
|
* [-serializeData:ofObjCType:context:]
|
||||||
|
* to encode all other information.
|
||||||
|
*
|
||||||
|
* And uses other NSMutableData methods to write the archive header
|
||||||
|
* information from within the method:
|
||||||
|
* [-serializeHeaderAt:version:classes:objects:pointers:]
|
||||||
|
* to write a fixed size header including archiver version
|
||||||
|
* (obtained by [self systemVersion]) and crossreference
|
||||||
|
* table sizes. The archiver will do this twice, once with
|
||||||
|
* dummy values at initialisation time and once with the real
|
||||||
|
* values.
|
||||||
|
*
|
||||||
|
* To subclass NSArchiver, you must implement your own versions of the
|
||||||
|
* four methods above, and override the 'directDataAccess' method to
|
||||||
|
* return NO so that the archiver knows to use your serialization
|
||||||
|
* methods rather than those in the NSMutableData object.
|
||||||
|
*/
|
||||||
|
- (BOOL) directDataAccess;
|
||||||
|
- (void) serializeHeaderAt: (unsigned)positionInData
|
||||||
|
version: (unsigned)systemVersion
|
||||||
|
classes: (unsigned)classCount
|
||||||
|
objects: (unsigned)objectCount
|
||||||
|
pointers: (unsigned)pointerCount;
|
||||||
|
|
||||||
|
/* libObjects compatibility */
|
||||||
|
- (void) encodeArrayOfObjCType: (const char*) type
|
||||||
|
count: (unsigned)count
|
||||||
|
at: (const void*)buf
|
||||||
|
withName: (id)name;
|
||||||
|
- (void) encodeIndent;
|
||||||
|
- (void) encodeValueOfCType: (const char*) type
|
||||||
|
at: (const void*)buf
|
||||||
|
withName: (id)name;
|
||||||
|
- (void) encodeValueOfObjCType: (const char*) type
|
||||||
|
at: (const void*)buf
|
||||||
|
withName: (id)name;
|
||||||
|
- (void) encodeObject: (id)anObject
|
||||||
|
withName: (id)name;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@interface NSUnarchiver : NSCoder
|
@interface NSUnarchiver : NSCoder
|
||||||
|
{
|
||||||
|
NSData *data; /* Data to write into. */
|
||||||
|
Class dataClass; /* What sort of data is it? */
|
||||||
|
id src; /* Deserialization source. */
|
||||||
|
IMP desImp; /* Method to deserialize with. */
|
||||||
|
unsigned char (*tagImp)(id, SEL, unsigned*);
|
||||||
|
unsigned (*xRefImp)(id, SEL, unsigned*);
|
||||||
|
IMP dValImp; /* Method to decode data with. */
|
||||||
|
#ifndef _IN_NSUNARCHIVER_M
|
||||||
|
#define GSUnarchiverArray void*
|
||||||
|
#endif
|
||||||
|
GSUnarchiverArray clsMap; /* Class crossreference map. */
|
||||||
|
GSUnarchiverArray objMap; /* Object crossreference map. */
|
||||||
|
GSUnarchiverArray ptrMap; /* Pointer crossreference map. */
|
||||||
|
#ifndef _IN_NSUNARCHIVER_M
|
||||||
|
#undef GSUnarchiverArray
|
||||||
|
#endif
|
||||||
|
unsigned cursor; /* Position in data buffer. */
|
||||||
|
unsigned version; /* Version of archiver used. */
|
||||||
|
NSZone *zone; /* Zone for allocating objs. */
|
||||||
|
NSMutableDictionary *objDict; /* Class information store. */
|
||||||
|
}
|
||||||
|
|
||||||
/* Initializing an unarchiver */
|
/* Initializing an unarchiver */
|
||||||
- (id) initForReadingWithData: (NSData*)data;
|
- (id) initForReadingWithData: (NSData*)data;
|
||||||
|
@ -73,17 +195,79 @@
|
||||||
- (void) decodeClassName: (NSString*)nameInArchive
|
- (void) decodeClassName: (NSString*)nameInArchive
|
||||||
asClassName: (NSString*)trueName;
|
asClassName: (NSString*)trueName;
|
||||||
|
|
||||||
|
/* Substituting objects */
|
||||||
|
- (void) replaceObject: (id)anObject withObject: (id)replacement;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface NSUnarchiver (GNUstep)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Re-using the unarchiver - the 'resetUnarchiverWithdata:atIndex:'
|
||||||
|
* method lets you re-use the archive to decode a new data object
|
||||||
|
* or, in conjunction with the 'cursor' method (which reports the
|
||||||
|
* current decoding position in the archive), decode a second
|
||||||
|
* archive that exists in the data object after the first one.
|
||||||
|
*/
|
||||||
|
- (unsigned) cursor;
|
||||||
|
- (void) resetUnarchiverWithData: (NSData*)data
|
||||||
|
atIndex: (unsigned)pos;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Subclassing with different input format.
|
||||||
|
* NSUnarchiver normally reads directly from an NSData object using
|
||||||
|
* the methods -
|
||||||
|
* [-deserializeTypeTagAtCursor:]
|
||||||
|
* to decode type tags for data items, the tag is the
|
||||||
|
* first byte of the character encoding string for the
|
||||||
|
* data type (as provided by '@encode(xxx)'), possibly
|
||||||
|
* with the top bit set to indicate that what follows is
|
||||||
|
* a crossreference to an item already encoded.
|
||||||
|
* [-deserializeCrossRefAtCursor:],
|
||||||
|
* to decode a crossreference number either to identify the
|
||||||
|
* following item, or to refer to a previously encoded item.
|
||||||
|
* Objects, Classes, Selectors, CStrings and Pointer items
|
||||||
|
* have crossreference encoding, other types do not.
|
||||||
|
* [-deserializeData:ofObjCType:atCursor:context:]
|
||||||
|
* to decode all other information.
|
||||||
|
*
|
||||||
|
* And uses other NSData methods to read the archive header information
|
||||||
|
* from within the method:
|
||||||
|
* [-deserializeHeaderAt:version:classes:objects:pointers:]
|
||||||
|
* to read a fixed size header including archiver version
|
||||||
|
* (obtained by [self systemVersion]) and crossreference
|
||||||
|
* table sizes.
|
||||||
|
*
|
||||||
|
* To subclass NSUnarchiver, you must implement your own versions of the
|
||||||
|
* four methods above, and override the 'directDataAccess' method to
|
||||||
|
* return NO so that the archiver knows to use your serialization
|
||||||
|
* methods rather than those in the NSData object.
|
||||||
|
*/
|
||||||
|
- (BOOL) directDataAccess;
|
||||||
|
- (void) deserializeHeaderAt: (unsigned*)cursor
|
||||||
|
version: (unsigned*)systemVersion
|
||||||
|
classes: (unsigned*)classCount
|
||||||
|
objects: (unsigned*)objectCount
|
||||||
|
pointers: (unsigned*)pointerCount;
|
||||||
|
|
||||||
|
/* Compatibility with libObjects */
|
||||||
|
- (void) decodeArrayOfObjCType: (const char*) type
|
||||||
|
count: (unsigned)count
|
||||||
|
at: (void*)buf
|
||||||
|
withName: (id*)name;
|
||||||
|
- (void) decodeIndent;
|
||||||
|
- (void) decodeValueOfCType: (const char*) type
|
||||||
|
at: (void*)buf
|
||||||
|
withName: (id*)name;
|
||||||
|
- (void) decodeValueOfObjCType: (const char*) type
|
||||||
|
at: (void*)buf
|
||||||
|
withName: (id*)name;
|
||||||
|
- (void) decodeObjectAt: (id*)anObject
|
||||||
|
withName: (id*)name;
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Exceptions */
|
/* Exceptions */
|
||||||
extern NSString *NSInconsistentArchiveException;
|
extern NSString *NSInconsistentArchiveException;
|
||||||
|
|
||||||
|
|
||||||
/* NSObject extensions for archiving */
|
|
||||||
@interface NSObject (NSArchiver)
|
|
||||||
- (Class) classForArchiver;
|
|
||||||
- replacementObjectForArchiver: (NSArchiver*) archiver;
|
|
||||||
@end
|
|
||||||
|
|
||||||
#endif /* __NSArchiver_h_GNUSTEP_BASE_INCLUDE */
|
#endif /* __NSArchiver_h_GNUSTEP_BASE_INCLUDE */
|
||||||
|
|
|
@ -353,6 +353,7 @@ NSTask.m \
|
||||||
NSThread.m \
|
NSThread.m \
|
||||||
NSTimer.m \
|
NSTimer.m \
|
||||||
NSTimeZone.m \
|
NSTimeZone.m \
|
||||||
|
NSUnarchiver.m \
|
||||||
NSUndoManager.m \
|
NSUndoManager.m \
|
||||||
NSUser.m \
|
NSUser.m \
|
||||||
NSUserDefaults.m \
|
NSUserDefaults.m \
|
||||||
|
|
1057
Source/NSArchiver.m
1057
Source/NSArchiver.m
File diff suppressed because it is too large
Load diff
1226
Source/NSUnarchiver.m
Normal file
1226
Source/NSUnarchiver.m
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue