1 /** Interface for NSArchiver for GNUStep
2    Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.
3 
4    Written by:  Andrew Kachites McCallum <mccallum@gnu.ai.mit.edu>
5    Rewrite by:  Richard Frith-Macdonald <rfm@gnu.org>
6    Date: March 1995
7 
8    This file is part of the GNUstep Base Library.
9 
10    This library is free software; you can redistribute it and/or
11    modify it under the terms of the GNU Lesser General Public
12    License as published by the Free Software Foundation; either
13    version 2 of the License, or (at your option) any later version.
14 
15    This library is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    Lesser General Public License for more details.
19 
20    You should have received a copy of the GNU Lesser General Public
21    License along with this library; if not, write to the Free
22    Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
23    Boston, MA 02110 USA.
24 
25    AutogsdocSource:NSUnarchiver.m
26    AutogsdocSource:NSArchiver.m
27 */
28 
29 #ifndef __NSArchiver_h_GNUSTEP_BASE_INCLUDE
30 #define __NSArchiver_h_GNUSTEP_BASE_INCLUDE
31 #import	<GNUstepBase/GSVersionMacros.h>
32 
33 #import	<Foundation/NSCoder.h>
34 
35 #if	defined(__cplusplus)
36 extern "C" {
37 #endif
38 
39 @class NSMutableArray, NSMutableDictionary, NSMutableData, NSData, NSString;
40 
41 #if	OS_API_VERSION(GS_API_OSSPEC,GS_API_LATEST)
42 
43 @interface NSArchiver : NSCoder
44 {
45 #if	GS_EXPOSE(NSArchiver)
46 @private
47   NSMutableData	*_data;		/* Data to write into.		*/
48   id		_dst;		/* Serialization destination.	*/
49   IMP		_serImp;	/* Method to serialize with.	*/
50   IMP		_tagImp;	/* Serialize a type tag.	*/
51   IMP		_xRefImp;	/* Serialize a crossref.	*/
52   IMP		_eObjImp;	/* Method to encode an id.	*/
53   IMP		_eValImp;	/* Method to encode others.	*/
54 #ifndef	_IN_NSARCHIVER_M
55 #define	GSIMapTable	void*
56 #endif
57   GSIMapTable	_clsMap;	/* Class cross references.	*/
58   GSIMapTable	_cIdMap;	/* Conditionally coded.		*/
59   GSIMapTable	_uIdMap;	/* Unconditionally coded.	*/
60   GSIMapTable	_ptrMap;	/* Constant pointers.		*/
61   GSIMapTable	_namMap;	/* Mappings for class names.	*/
62   GSIMapTable	_repMap;	/* Mappings for objects.	*/
63 #ifndef	_IN_NSARCHIVER_M
64 #undef	GSIMapTable
65 #endif
66   unsigned	_xRefC;		/* Counter for cross-reference.	*/
67   unsigned	_xRefO;		/* Counter for cross-reference.	*/
68   unsigned	_xRefP;		/* Counter for cross-reference.	*/
69   unsigned	_startPos;	/* Where in data we started.	*/
70   BOOL		_encodingRoot;
71   BOOL		_initialPass;
72 #endif
73 #if     GS_NONFRAGILE
74 #else
75   /* Pointer to private additional data used to avoid breaking ABI
76    * when we don't have the non-fragile ABI available.
77    * Use this mechanism rather than changing the instance variable
78    * layout (see Source/GSInternal.h for details).
79    */
80   @private id _internal GS_UNUSED_IVAR;
81 #endif
82 }
83 
84 /* Initializing an archiver */
85 - (id) initForWritingWithMutableData: (NSMutableData*)mdata;
86 
87 /* Archiving Data */
88 + (NSData*) archivedDataWithRootObject: (id)rootObject;
89 + (BOOL) archiveRootObject: (id)rootObject toFile: (NSString*)path;
90 
91 /* Getting data from the archiver */
92 - (NSMutableData*) archiverData;
93 
94 /* Substituting Classes */
95 - (NSString*) classNameEncodedForTrueClassName: (NSString*) trueName;
96 - (void) encodeClassName: (NSString*)trueName
97            intoClassName: (NSString*)inArchiveName;
98 
99 #if	OS_API_VERSION(GS_API_MACOSX,GS_API_LATEST)
100 /* Substituting Objects */
101 - (void) replaceObject: (id)object
102 	    withObject: (id)newObject;
103 #endif
104 @end
105 
106 #if	GS_API_VERSION(GS_API_NONE,011700)
107 @interface	NSArchiver (GNUstep)
108 
109 /*
110  *	Re-using the archiver - the 'resetArchiver' method resets the internal
111  *	state of the archiver so that you can re-use it rather than having to
112  *	destroy it and create a new one.
113  *	NB. you would normally want to issue a 'setLength:0' message to the
114  *	mutable data object used by the archiver as well, othewrwise the next
115  *	root object encoded will be appended to data.
116  */
117 - (void) resetArchiver;
118 
119 /*
120  *	Subclassing with different output format.
121  *	NSArchiver normally writes directly to an NSMutableData object using
122  *	the methods -
123  *		[-serializeTypeTag:]
124  *		    to encode type tags for data items, the tag is the
125  *		    first byte of the character encoding string for the
126  *		    data type (as provided by '@encode(xxx)'), possibly
127  *		    with the top bit set to indicate that what follows is
128  *		    a crossreference to an item already encoded.
129  *		[-serializeCrossRef:],
130  *		    to encode a crossreference number either to identify the
131  *		    following item, or to refer to a previously encoded item.
132  *		    Objects, Classes, Selectors, CStrings and Pointer items
133  *		    have crossreference encoding, other types do not.
134  *		[-serializeData:ofObjCType:context:]
135  *		    to encode all other information.
136  *
137  *	And uses other NSMutableData methods to write the archive header
138  *	information from within the method:
139  *		[-serializeHeaderAt:version:classes:objects:pointers:]
140  *		    to write a fixed size header including archiver version
141  *		    (obtained by [self systemVersion]) and crossreference
142  *		    table sizes.  The archiver will do this twice, once with
143  *		    dummy values at initialisation time and once with the real
144  *		    values.
145  *
146  *	To subclass NSArchiver, you must implement your own versions of the
147  *	four methods above, and override the 'directDataAccess' method to
148  *	return NO so that the archiver knows to use your serialization
149  *	methods rather than those in the NSMutableData object.
150  */
151 - (BOOL) directDataAccess;
152 - (void) serializeHeaderAt: (unsigned)positionInData
153 		   version: (unsigned)systemVersion
154 		   classes: (unsigned)classCount
155 		   objects: (unsigned)objectCount
156 		  pointers: (unsigned)pointerCount;
157 @end
158 #endif
159 
160 
161 
162 @interface NSUnarchiver : NSCoder
163 {
164 #if	GS_EXPOSE(NSUnarchiver)
165 @private
166   NSData		*data;		/* Data to write into.		*/
167   Class			dataClass;	/* What sort of data is it?	*/
168   id			src;		/* Deserialization source.	*/
169   IMP			desImp;		/* Method to deserialize with.	*/
170   void			(*tagImp)(id, SEL, unsigned char*, unsigned*,unsigned*);
171   IMP			dValImp;	/* Method to decode data with.	*/
172 #ifndef	_IN_NSUNARCHIVER_M
173 #define	GSIArray	void*
174 #endif
175   GSIArray		clsMap;		/* Class crossreference map.	*/
176   GSIArray		objMap;		/* Object crossreference map.	*/
177   GSIArray		ptrMap;		/* Pointer crossreference map.	*/
178 #ifndef	_IN_NSUNARCHIVER_M
179 #undef	GSIArray
180 #endif
181   unsigned		cursor;		/* Position in data buffer.	*/
182   unsigned		version;	/* Version of archiver used.	*/
183   NSZone		*zone;		/* Zone for allocating objs.	*/
184   NSMutableDictionary	*objDict;	/* Class information store.	*/
185   NSMutableArray	*objSave;
186 #endif
187 #if     GS_NONFRAGILE
188 #else
189   /* Pointer to private additional data used to avoid breaking ABI
190    * when we don't have the non-fragile ABI available.
191    * Use this mechanism rather than changing the instance variable
192    * layout (see Source/GSInternal.h for details).
193    */
194   @private id _internal GS_UNUSED_IVAR;
195 #endif
196 }
197 
198 /* Initializing an unarchiver */
199 - (id) initForReadingWithData: (NSData*)anObject;
200 
201 /* Decoding objects */
202 + (id) unarchiveObjectWithData: (NSData*)anObject;
203 + (id) unarchiveObjectWithFile: (NSString*)path;
204 
205 /* Managing */
206 - (BOOL) isAtEnd;
207 - (NSZone*) objectZone;
208 - (void) setObjectZone: (NSZone*)aZone;
209 - (unsigned int) systemVersion;
210 
211 /* Substituting Classes */
212 + (NSString*) classNameDecodedForArchiveClassName: (NSString*)nameInArchive;
213 + (void) decodeClassName: (NSString*)nameInArchive
214 	     asClassName: (NSString*)trueName;
215 - (NSString*) classNameDecodedForArchiveClassName: (NSString*)nameInArchive;
216 - (void) decodeClassName: (NSString*)nameInArchive
217 	     asClassName: (NSString*)trueName;
218 
219 #if	OS_API_VERSION(GS_API_MACOSX,GS_API_LATEST)
220 /* Substituting objects */
221 - (void) replaceObject: (id)anObject withObject: (id)replacement;
222 #endif
223 @end
224 
225 #if OS_API_VERSION(GS_API_NONE,GS_API_NONE) && GS_API_VERSION(1,GS_API_LATEST)
226 @interface	NSUnarchiver (GNUstep)
227 
228 - (unsigned) cursor;
229 - (void) resetUnarchiverWithData: (NSData*)anObject
230 			 atIndex: (unsigned)pos;
231 
232 - (BOOL) directDataAccess;
233 - (void) deserializeHeaderAt: (unsigned*)pos
234 		     version: (unsigned*)v
235 		     classes: (unsigned*)c
236 		     objects: (unsigned*)o
237 		    pointers: (unsigned*)p;
238 @end
239 #endif
240 
241 
242 /* Exceptions */
243 
244 /**
245  *  Specified in OpenStep to be raised by [NSArchiver] or subclasses if there
246  *  are problems initializing or encoding.  <em>Not currently used.
247  *  NSInternalInconsistencyException usually raised instead.</em>
248  */
249 GS_EXPORT NSString * const NSInconsistentArchiveException;
250 
251 #endif	/* OS_API_VERSION */
252 
253 #if	defined(__cplusplus)
254 }
255 #endif
256 
257 #endif	/* __NSArchiver_h_GNUSTEP_BASE_INCLUDE */
258