mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-25 01:31:08 +00:00
Inital commit of partial implementation of MacOS-X compatible keyed archiving.
Experimental ... archiving is implemented aand tested for xml format output. Unarchiving is not yet implemented. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@18450 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
b410ed6e5d
commit
f88e119c36
12 changed files with 3927 additions and 30 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
2004-01-19 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Headers/Foundation/NSPropertyList.h: serialisation/deserialisation.
|
||||
* Source/NSPropertyList.m: serialisation/deserialisation code partly
|
||||
implemented.
|
||||
* Headers/Foundation/NSCoder.h: Add keyed coding methods.
|
||||
* Source/NSCoder.m: ditto
|
||||
* Headers/Foundation/NSKeyedArchiver.h: new keyed archiver/unarchiver.
|
||||
* Source/NSKeyedArchiver.m: New MacOS-X compatible class implementation.
|
||||
* Source/NSKeyedUnarchiver.m: Stub for new class implementation.
|
||||
* Source/GNUmakefile: build new keyed archiving stuff.
|
||||
* Source/GSCompatibility.m: fix indentation error in xml output.
|
||||
improve output of numeric values in xml format.
|
||||
* Source/Additions/GSMime.m: ([-setContentType:) make argument more
|
||||
strongly typed. ([-encodeBase64:])tweak buffer size.
|
||||
|
||||
2004-01-18 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Source/NSDistantObject.m: All code conditional on USE_FFCALL should
|
||||
|
|
|
@ -77,6 +77,137 @@
|
|||
- (unsigned int) systemVersion;
|
||||
- (unsigned int) versionForClassName: (NSString*)className;
|
||||
|
||||
#ifndef STRICT_OPENSTEP
|
||||
/*
|
||||
* MacOS-X adds some typedefs that GNUstep already has by another name.
|
||||
*/
|
||||
#include <GSConfig.h>
|
||||
#define uint8_t gsu8
|
||||
#define int32_t gss32
|
||||
#define int64_t gss64
|
||||
|
||||
|
||||
/** <override-subclass />
|
||||
* Returns a flag indicating whether the receiver supported keyed coding.
|
||||
* the default implementation returns NO. Subclasses supporting keyed
|
||||
* coding must override this to return YES.
|
||||
*/
|
||||
- (BOOL) allowsKeyedCoding;
|
||||
|
||||
/** <override-subclass />
|
||||
* Returns a class indicating whether an encoded value corresponding
|
||||
* to aKey exists.
|
||||
*/
|
||||
- (BOOL) containsValueForKey: (NSString*)aKey;
|
||||
|
||||
/** <override-subclass />
|
||||
* Returns a boolean value associated with aKey. This value must previously
|
||||
* have been encoded using -encodeBool:forKey:
|
||||
*/
|
||||
- (BOOL) decodeBoolForKey: (NSString*)aKey;
|
||||
|
||||
/** <override-subclass />
|
||||
* Returns a pointer to a byte array associated with aKey.<br />
|
||||
* Returns the length of the data in aLength.<br />
|
||||
* This value must previously have been encoded using
|
||||
* -encodeBytes:length:forKey:
|
||||
*/
|
||||
- (const uint8_t*) decodeBytesForKey: (NSString*)aKey
|
||||
returnedLength: (unsigned*)alength;
|
||||
|
||||
/** <override-subclass />
|
||||
* Returns a double value associated with aKey. This value must previously
|
||||
* have been encoded using -encodeDouble:forKey: or -encodeFloat:forKey:
|
||||
*/
|
||||
- (double) decodeDoubleForKey: (NSString*)aKey;
|
||||
|
||||
/** <override-subclass />
|
||||
* Returns a float value associated with aKey. This value must previously
|
||||
* have been encoded using -encodeFloat:forKey: or -encodeDouble:forKey:<br />
|
||||
* Precision may be lost (or an exception raised if the value will not fit
|
||||
* in a float) if the value was encoded using -encodeDouble:forKey:,
|
||||
*/
|
||||
- (float) decodeFloatForKey: (NSString*)aKey;
|
||||
|
||||
/** <override-subclass />
|
||||
* Returns an integer value associated with aKey. This value must previously
|
||||
* have been encoded using -encodeInt:forKey:, -encodeInt32:forKey:, or
|
||||
* -encodeInt64:forKey:.<br />
|
||||
* An exception will be raised if the value does not fit in an integer.
|
||||
*/
|
||||
- (int) decodeIntForKey: (NSString*)aKey;
|
||||
|
||||
/** <override-subclass />
|
||||
* Returns a 32-bit integer value associated with aKey. This value must
|
||||
* previously have been encoded using -encodeInt:forKey:,
|
||||
* -encodeInt32:forKey:, or -encodeInt64:forKey:.<br />
|
||||
* An exception will be raised if the value does not fit in a 32-bit integer.
|
||||
*/
|
||||
- (int32_t) decodeInt32ForKey: (NSString*)aKey;
|
||||
|
||||
/** <override-subclass />
|
||||
* Returns a 64-bit integer value associated with aKey. This value must
|
||||
* previously have been encoded using -encodeInt:forKey:,
|
||||
* -encodeInt32:forKey:, or -encodeInt64:forKey:.
|
||||
*/
|
||||
- (int64_t) decodeInt64ForKey: (NSString*)aKey;
|
||||
|
||||
/** <override-subclass />
|
||||
* Returns an object value associated with aKey. This value must
|
||||
* previously have been encoded using -encodeObject:forKey: or
|
||||
* -encodeConditionalObject:forKey:
|
||||
*/
|
||||
- (id) decodeObjectForKey: (NSString*)aKey;
|
||||
|
||||
/** <override-subclass />
|
||||
* Encodes aBool and associates the encoded value with aKey.
|
||||
*/
|
||||
- (void) encodeBool: (BOOL) aBool forKey: (NSString*)aKey;
|
||||
|
||||
/** <override-subclass />
|
||||
* Encodes the data of the specified length and pointed to by aPointeraBool,
|
||||
* and associates the encoded value with aKey.
|
||||
*/
|
||||
- (void) encodeBytes: (const uint8_t*)aPointer
|
||||
length: (unsigned)length
|
||||
forKey: (NSString*)aKey;
|
||||
|
||||
/** <override-subclass />
|
||||
* Encodes anObject and associates the encoded value with aKey, but only
|
||||
* if anObject has already been encoded using -encodeObject:forKey:
|
||||
*/
|
||||
- (void) encodeConditionalObject: (id)anObject forKey: (NSString*)aKey;
|
||||
|
||||
/** <override-subclass />
|
||||
* Encodes aDouble and associates the encoded value with aKey.
|
||||
*/
|
||||
- (void) encodeDouble: (double)aDouble forKey: (NSString*)aKey;
|
||||
|
||||
/** <override-subclass />
|
||||
* Encodes aFloat and associates the encoded value with aKey.
|
||||
*/
|
||||
- (void) encodeFloat: (float)aFloat forKey: (NSString*)aKey;
|
||||
|
||||
/** <override-subclass />
|
||||
* Encodes anInteger and associates the encoded value with aKey.
|
||||
*/
|
||||
- (void) encodeInt: (int)anInteger forKey: (NSString*)aKey;
|
||||
|
||||
/** <override-subclass />
|
||||
* Encodes anInteger and associates the encoded value with aKey.
|
||||
*/
|
||||
- (void) encodeInt32: (int32_t)anInteger forKey: (NSString*)aKey;
|
||||
|
||||
/** <override-subclass />
|
||||
* Encodes anInteger and associates the encoded value with aKey.
|
||||
*/
|
||||
- (void) encodeInt64: (int64_t)anInteger forKey: (NSString*)aKey;
|
||||
|
||||
/** <override-subclass />
|
||||
* Encodes anObject and associates the encoded value with aKey.
|
||||
*/
|
||||
- (void) encodeObject: (id)anObject forKey: (NSString*)aKey;
|
||||
#endif
|
||||
@end
|
||||
|
||||
#ifndef NO_GNUSTEP
|
||||
|
|
353
Headers/Foundation/NSKeyedArchiver.h
Normal file
353
Headers/Foundation/NSKeyedArchiver.h
Normal file
|
@ -0,0 +1,353 @@
|
|||
/** Interface for NSKeyedArchiver for GNUStep
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Richard Frith-Macdonald <rfm@gnu.org>
|
||||
Date: January 2004
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
||||
|
||||
AutogsdocSource: NSKeyedArchiver.m
|
||||
AutogsdocSource: NSKeyedUnarchiver.m
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __NSKeyedArchiver_h_GNUSTEP_BASE_INCLUDE
|
||||
#define __NSKeyedArchiver_h_GNUSTEP_BASE_INCLUDE
|
||||
|
||||
#ifndef STRICT_OPENSTEP
|
||||
|
||||
#include <Foundation/NSCoder.h>
|
||||
#include <Foundation/NSMapTable.h>
|
||||
#include <Foundation/NSPropertyList.h>
|
||||
|
||||
@class NSMutableDictionary, NSMutableData, NSData, NSString;
|
||||
|
||||
/**
|
||||
* Keyed archiving class, <strong>NOT YET IMPLEMENTED</strong>
|
||||
*/
|
||||
@interface NSKeyedArchiver : NSCoder
|
||||
{
|
||||
@private
|
||||
NSMutableData *_data; /* Data to write into. */
|
||||
id _delegate; /* Delegate controls operation. */
|
||||
NSMapTable *_clsMap; /* Map classes to names. */
|
||||
#ifndef _IN_NSKEYEDARCHIVER_M
|
||||
#define GSIMapTable void*
|
||||
#endif
|
||||
GSIMapTable _cIdMap; /* Conditionally coded. */
|
||||
GSIMapTable _uIdMap; /* Unconditionally coded. */
|
||||
GSIMapTable _repMap; /* Mappings for objects. */
|
||||
#ifndef _IN_NSKEYEDARCHIVER_M
|
||||
#undef GSIMapTable
|
||||
#endif
|
||||
unsigned _keyNum; /* Counter for keys in object. */
|
||||
NSMutableDictionary *_enc; /* Object being encoded. */
|
||||
NSMutableArray *_obj; /* Array of objects. */
|
||||
NSPropertyListFormat _format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes anObject and returns the resulting data object.
|
||||
*/
|
||||
+ (NSData*) archivedDataWithRootObject: (id)anObject;
|
||||
|
||||
/**
|
||||
* Encodes anObject and writes the resulting data ti aPath.
|
||||
*/
|
||||
+ (BOOL) archiveRootObject: (id)anObject toFile: (NSString*)aPath;
|
||||
|
||||
/**
|
||||
* Returns the class name with which the NSKeyedArchiver class will encode
|
||||
* instances of aClass, or nil if no name mapping has been set using the
|
||||
* +setClassName:forClass: method.
|
||||
*/
|
||||
+ (NSString*) classNameForClass: (Class)aClass;
|
||||
|
||||
/**
|
||||
* Sets the class name with which the NSKeyedArchiver class will encode
|
||||
* instances of aClass. This mapping is used only if no class name
|
||||
* mapping has been set for the individual instance of NSKeyedArchiver
|
||||
* being used.<br />
|
||||
* The value of aString must be the name of an existing class.<br />
|
||||
* If the value of aString is nil, any mapping for aClass is removed.
|
||||
*/
|
||||
+ (void) setClassName: (NSString*)aString forClass: (Class)aClass;
|
||||
|
||||
/**
|
||||
* Returns any mapping for the name of aClass which was previously set
|
||||
* for the receiver using the -setClassName:forClass: method.<br />
|
||||
* Returns nil if no such mapping exists, even if one has been set
|
||||
* using the class method +setClassName:forClass:
|
||||
*/
|
||||
- (NSString*) classNameForClass: (Class)aClass;
|
||||
|
||||
/**
|
||||
* Returns the delegate set for the receiver, or nil of none is set.
|
||||
*/
|
||||
- (id) delegate;
|
||||
|
||||
- (void) encodeBool: (BOOL)aBool forKey: (NSString*)aKey;
|
||||
- (void) encodeBytes: (const uint8_t*)aPointer length: (unsigned)length forKey: (NSString*)aKey;
|
||||
- (void) encodeConditionalObject: (id)anObject forKey: (NSString*)aKey;
|
||||
- (void) encodeDouble: (double)aDouble forKey: (NSString*)aKey;
|
||||
- (void) encodeFloat: (float)aFloat forKey: (NSString*)aKey;
|
||||
- (void) encodeInt: (int)anInteger forKey: (NSString*)aKey;
|
||||
- (void) encodeInt32: (int32_t)anInteger forKey: (NSString*)aKey;
|
||||
- (void) encodeInt64: (int64_t)anInteger forKey: (NSString*)aKey;
|
||||
- (void) encodeObject: (id)anObject forKey: (NSString*)aKey;
|
||||
|
||||
/**
|
||||
* Ends the encoding process and causes the encoded archive to be placed
|
||||
* in the mutable data object supplied when the receiver was initialised.<br />
|
||||
* This method must be called at the end of encoding, and nothing may be
|
||||
* encoded after this method is called.
|
||||
*/
|
||||
- (void) finishEncoding;
|
||||
|
||||
/**
|
||||
* Initialise the receiver to encode an archive into the supplied
|
||||
* data object.
|
||||
*/
|
||||
- (id) initForWritingWithMutableData: (NSMutableData*)data;
|
||||
|
||||
/**
|
||||
* Returns the output format of the archived data ... this should default
|
||||
* to the MacOS-X binary format, but we don't support that yet, so the
|
||||
* -setOutputFormat: method should be used to set a supported format.
|
||||
*/
|
||||
- (NSPropertyListFormat) outputFormat;
|
||||
|
||||
/**
|
||||
* Sets the name with which instances of aClass are encoded.<br />
|
||||
* The value of aString must be the anme of an existing clas.
|
||||
*/
|
||||
- (void) setClassName: (NSString*)aString forClass: (Class)aClass;
|
||||
|
||||
/**
|
||||
* Sets the receivers delegate. The delegate should conform to the
|
||||
* NSObject(NSKeyedArchiverDelegate) informal protocol.<br />
|
||||
* NB. the delegate is not retained, so you must ensure that it is not
|
||||
* deallocated before the archiver has finished with it.
|
||||
*/
|
||||
- (void) setDelegate: (id)anObject;
|
||||
|
||||
/**
|
||||
* Specifies the output format of the archived data ... this should default
|
||||
* to the MacOS-X binary format, but we don't support that yet, so the
|
||||
* -setOutputFormat: method should be used to set a supported format.
|
||||
*/
|
||||
- (void) setOutputFormat: (NSPropertyListFormat)format;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Keyed unarchiving class, <strong>NOT YET IMPLEMENTED</strong>
|
||||
*/
|
||||
@interface NSKeyedUnarchiver : NSCoder
|
||||
{
|
||||
@private
|
||||
id _delegate;
|
||||
#ifndef _IN_NSKEYEDUNARCHIVER_M
|
||||
#define GSIArray void*
|
||||
#endif
|
||||
GSIArray clsMap; /* Class crossreference map. */
|
||||
GSIArray objMap; /* Object crossreference map. */
|
||||
GSIArray ptrMap; /* Pointer crossreference map. */
|
||||
#ifndef _IN_NSKEYEDUNARCHIVER_M
|
||||
#undef GSUnarchiverArray
|
||||
#endif
|
||||
unsigned cursor; /* Position in data buffer. */
|
||||
NSZone *zone; /* Zone for allocating objs. */
|
||||
NSMutableDictionary *objDict; /* Class information store. */
|
||||
}
|
||||
|
||||
+ (Class) classForClassName: (NSString*)aString;
|
||||
+ (void) setClass: (Class)aClass forClassName: (NSString*)aString;
|
||||
+ (id) unarchiveObjectWithData: (NSData*)data;
|
||||
+ (id) unarchiveObjectWithFile: (NSString*)aPath;
|
||||
|
||||
- (Class) classForClassName: (NSString*)aString;
|
||||
- (BOOL) containsValueForKey: (NSString*)aKey;
|
||||
- (BOOL) decodeBoolForKey: (NSString*)aKey;
|
||||
- (const uint8_t*) decodeBytesForKey: (NSString*)aKey
|
||||
returnedLength: (unsigned*)length;
|
||||
- (double) decodeDoubleForKey: (NSString*)aKey;
|
||||
- (float) decodeFloatForKey: (NSString*)aKey;
|
||||
- (int) decodeIntForKey: (NSString*)aKey;
|
||||
- (int32_t) decodeInt32ForKey: (NSString*)aKey;
|
||||
- (int64_t) decodeInt64ForKey: (NSString*)aKey;
|
||||
- (id) decodeObjectForKey: (NSString*)aKey;
|
||||
/**
|
||||
* returns the delegate of the unarchiver.
|
||||
*/
|
||||
- (id) delegate;
|
||||
- (void) finishDecoding;
|
||||
- (id) initForReadingWithData: (NSData*)data;
|
||||
- (void) setClass: (Class)aClass forClassName: (NSString*)aString;
|
||||
/**
|
||||
* Sets the receivers delegate. The delegate should conform to the
|
||||
* NSObject(NSKeyedUnarchiverDelegate) informal protocol.<br />
|
||||
* NB. the delegate is not retained, so you must ensure that it is not
|
||||
* deallocated before the unarchiver has finished with it.
|
||||
*/
|
||||
- (void) setDelegate: (id)delegate;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
/* Exceptions */
|
||||
GS_EXPORT NSString * const NSInvalidArchiveOperationException;
|
||||
GS_EXPORT NSString * const NSInvalidUnarchiveOperationException;
|
||||
|
||||
|
||||
/**
|
||||
* Informal protocol implemented by delegates of [NSKeyedArchiver]
|
||||
*/
|
||||
@interface NSObject (NSKeyedArchiverDelegate)
|
||||
|
||||
/**
|
||||
* Sent when encoding of anObject has completed <em>except</em> in the case
|
||||
* of conditional encoding.
|
||||
*/
|
||||
- (void) archiver: (NSKeyedArchiver*)anArchiver didEncodeObject: (id)anObject;
|
||||
|
||||
/**
|
||||
* Sent when anObject is about to be encoded (or conditionally encoded)
|
||||
* and provides the receiver with an opportunity to change the actual
|
||||
* object stored into the archive by returning a different value (otherwise
|
||||
* it should return anObject).<br />
|
||||
* The method is not called for encoding of nil or for encoding of any
|
||||
* object for which has already been called.<br />
|
||||
* The method is called <em>after</em> the -replacementObjectForKeyedArchiver:
|
||||
* method.
|
||||
*/
|
||||
- (id) archiver: (NSKeyedArchiver*)anArchiver willEncodeObject: (id)anObject;
|
||||
|
||||
/**
|
||||
* Sent when the encoding process is complete.
|
||||
*/
|
||||
- (void) archiverDidFinish: (NSKeyedArchiver*)anArchiver;
|
||||
|
||||
/**
|
||||
* Sent when the encoding process is about to finish.
|
||||
*/
|
||||
- (void) archiverWillFinish: (NSKeyedArchiver*)anArchiver;
|
||||
|
||||
/**
|
||||
* Sent whenever object replacement occurs during encoding, either by the
|
||||
* -replacementObjectForKeyedArchiver: method or because the delegate has
|
||||
* returned a changed value using the -archiver:willEncodeObject: method.
|
||||
*/
|
||||
- (void) archiver: (NSKeyedArchiver*)anArchiver
|
||||
willReplaceObject: (id)anObject
|
||||
withObject: (id)newObject;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Informal protocol implemented by delegates of [NSKeyedUnarchiver]
|
||||
*/
|
||||
@interface NSObject (NSKeyedUnarchiverDelegate)
|
||||
|
||||
/**
|
||||
* Sent if the named class is not available during decoding.<br />
|
||||
* The value of aName is the class name being decoded (after any name mapping
|
||||
* has been applied).<br />
|
||||
* The classNames arraay contains the original name of the class encoded
|
||||
* in the archive, and is followed by eqach of its superclasses in turn.<br />
|
||||
* The delegate may either return a class object for the unarchiver to use
|
||||
* to continue decoding, or may return nil to abort the decoding process.
|
||||
*/
|
||||
- (Class) unarchiver: (NSKeyedUnarchiver*)anUnarchiver
|
||||
cannotDecodeObjectOfClassName: (NSString*)aName
|
||||
originalClasses: (NSArray*)classNames;
|
||||
|
||||
/**
|
||||
* Sent when anObject is decoded. The receiver may return either anObject
|
||||
* or some other object (including nil). If a value other than anObject is
|
||||
* returned, it is used to replace anObject.
|
||||
*/
|
||||
- (id) unarchiver: (NSKeyedUnarchiver*)anUnarchiver
|
||||
didDecodeObject: (id)anObject;
|
||||
|
||||
/**
|
||||
* Sent when unarchiving is about to complete.
|
||||
*/
|
||||
- (void) unarchiverDidFinish: (NSKeyedUnarchiver*)anUnarchiver;
|
||||
|
||||
/**
|
||||
* Sent when unarchiving has been completed.
|
||||
*/
|
||||
- (void) unarchiverWillFinish: (NSKeyedUnarchiver*)anUnarchiver;
|
||||
|
||||
/**
|
||||
* Sent whenever object replacement occurs during decoding, eg by the
|
||||
* -replacementObjectForKeyedArchiver: method.
|
||||
*/
|
||||
- (void) unarchiver: (NSKeyedUnarchiver*)anUnarchiver
|
||||
willReplaceObject: (id)anObject
|
||||
withObject: (id)newObject;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Methods by which a class may control its archiving by the NSKeyedArchiver
|
||||
*/
|
||||
@interface NSObject (NSKeyedArchiverObjectSubstitution)
|
||||
|
||||
/**
|
||||
* This message is sent to objects being encoded, to allow them to choose
|
||||
* to be encoded a different class. If this returns nil it is treated as
|
||||
* if it returned the class of the object.<br />
|
||||
* After this method is applied, any class name mapping set in the archiver
|
||||
* is applied to its result.<br />
|
||||
* The default implementation returns the result of the -classForArchiver
|
||||
* method.
|
||||
*/
|
||||
- (Class) classForKeyedArchiver;
|
||||
|
||||
/**
|
||||
* This message is sent to objects being encoded, to allow them to choose
|
||||
* to be encoded a different object by returning the alternative object.<br />
|
||||
* The default implementation returns the result of calling
|
||||
* the -replacementObjectForArchiver: method with a nil argument.<br />
|
||||
* This is called only if no mapping has been set up in the archiver already.
|
||||
*/
|
||||
- (id) replacementObjectForKeyedArchiver: (NSKeyedArchiver*)archiver;
|
||||
|
||||
@end
|
||||
|
||||
@interface NSObject (NSKeyedUnarchiverObjectSubstitution)
|
||||
|
||||
/**
|
||||
* Sent during unarchiving to permit classes to substitute a different
|
||||
* class for decoded instances of themselves.<br />
|
||||
* Default implementation returns the receiver.<br />
|
||||
* Overrides the mappings set up within the receiver.
|
||||
*/
|
||||
+ (Class) classForKeyedUnarchiver;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* STRICT_OPENSTEP */
|
||||
#endif /* __NSKeyedArchiver_h_GNUSTEP_BASE_INCLUDE*/
|
125
Headers/Foundation/NSPropertyList.h
Normal file
125
Headers/Foundation/NSPropertyList.h
Normal file
|
@ -0,0 +1,125 @@
|
|||
/** Interface for NSPropertyList for GNUStep
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Richard Frith-Macdonald <rfm@gnu.org>
|
||||
Date: January 2004
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
||||
|
||||
AutogsdocSource: NSPropertyList.m
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __NSPropertyList_h_GNUSTEP_BASE_INCLUDE
|
||||
#define __NSPropertyList_h_GNUSTEP_BASE_INCLUDE
|
||||
|
||||
#ifndef STRICT_OPENSTEP
|
||||
|
||||
#include <Foundation/NSObject.h>
|
||||
|
||||
@class NSData, NSString;
|
||||
|
||||
/**
|
||||
* Describes the mutability to use when generating objects during
|
||||
* deserialisation of a property list.
|
||||
*/
|
||||
typedef enum {
|
||||
NSPropertyListImmutable,
|
||||
/** <strong>NSPropertyListImmutable</strong>
|
||||
* all objects in created list are immutable
|
||||
*/
|
||||
NSPropertyListMutableContainers,
|
||||
/** <strong>NSPropertyListMutableContainers</strong>
|
||||
* dictionaries and arrays are mutable
|
||||
*/
|
||||
NSPropertyListMutableContainersAndLeaves
|
||||
/** <strong>NSPropertyListMutableContainersAndLeaves</strong>
|
||||
* dictionaries, arrays, strings and data objects are mutable
|
||||
*/
|
||||
} NSPropertyListMutabilityOptions;
|
||||
|
||||
/**
|
||||
* Specifies the serialisation format for a serialised property list.
|
||||
*/
|
||||
typedef enum {
|
||||
NSPropertyListGNUStepFormat,
|
||||
/** <strong>NSPropertyListGNUStepFormat</strong>
|
||||
* extension of OpenStep format */
|
||||
NSPropertyListGNUstepBinaryFormat,
|
||||
/** <strong>NSPropertyListGNUstepBinaryFormat</strong>
|
||||
* efficient, hardware independent */
|
||||
NSPropertyListOpenStepFormat,
|
||||
/** <strong>NSPropertyListOpenStepFormat</strong>
|
||||
* the most human-readable format */
|
||||
NSPropertyListXMLFormat_v1_0,
|
||||
/** <strong>NSPropertyListXMLFormat_v1_0</strong>
|
||||
* portable and readable */
|
||||
NSPropertyListBinaryFormat_v1_0,
|
||||
/** <strong>NSPropertyListBinaryFormat_v1_0</strong>
|
||||
* not yet supported */
|
||||
} NSPropertyListFormat;
|
||||
|
||||
/**
|
||||
* <p>The NSPropertyListSerialization class provides facilities for
|
||||
* serialising and deserializing property list data in a number of
|
||||
* formats.
|
||||
* </p>
|
||||
* <p>You do not work with instances of this class, instead you use a
|
||||
* small number of claass methods to serialized and deserialize
|
||||
* property lists.
|
||||
* </p>
|
||||
*/
|
||||
@interface NSPropertyListSerialization : NSObject
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and returns a data object containing a serialized representation
|
||||
* of plist. The argument aFormat is used to determine the way in which the
|
||||
* data is serialised, and the anErrorString argument is a pointer in which
|
||||
* an error message is returned on failure (nil is returned on success).
|
||||
*/
|
||||
+ (NSData*) dataFromPropertyList: (id)aPropertyList
|
||||
format: (NSPropertyListFormat)aFormat
|
||||
errorDescription: (NSString**)anErrorString;
|
||||
|
||||
/**
|
||||
* Returns a flag indicating whether it is possible to serialize aPropertyList
|
||||
* in the format aFormat.
|
||||
*/
|
||||
+ (BOOL) propertyList: (id)aPropertyList
|
||||
isValidForFormat: (NSPropertyListFormat)aFormat;
|
||||
|
||||
/**
|
||||
* Deserialises dataItem and returns the resulting property list
|
||||
* (or nil if the data does not contain a property list serialised
|
||||
* in a supported format).<br />
|
||||
* The argument anOption is ised to control whether the objects making
|
||||
* up the deserialized property list are mutable or not.<br />
|
||||
* The argument aFormat is either null or a pointer to a location
|
||||
* in which the format of the serialized property list will be returned.<br />
|
||||
* Either nil or an error message will be returned in anErrorString.
|
||||
*/
|
||||
+ (id) propertyListFromData: (NSData*)data
|
||||
mutabilityOption: (NSPropertyListMutabilityOptions)anOption
|
||||
format: (NSPropertyListFormat*)aFormat
|
||||
errorDescription: (NSString**)anErrorString;
|
||||
|
||||
@end
|
||||
|
||||
#endif /* STRICT_OPENSTEP */
|
||||
#endif /* __NSPropertyList_h_GNUSTEP_BASE_INCLUDE*/
|
|
@ -108,7 +108,6 @@ encodebase64(char *dst, const unsigned char *src, int length)
|
|||
dst[dIndex - 1] = '=';
|
||||
dst[dIndex - 2] = '=';
|
||||
}
|
||||
dst[dIndex] = '\0';
|
||||
return dIndex;
|
||||
}
|
||||
|
||||
|
@ -3155,10 +3154,9 @@ static NSCharacterSet *tokenSet = nil;
|
|||
{
|
||||
return [NSData data];
|
||||
}
|
||||
destlen = 4 * ((length - 1) / 3) + 5;
|
||||
destlen = 4 * ((length + 2) / 3);
|
||||
sBuf = (unsigned char*)[source bytes];
|
||||
dBuf = NSZoneMalloc(NSDefaultMallocZone(), destlen);
|
||||
dBuf[destlen - 1] = '\0';
|
||||
|
||||
destlen = encodebase64(dBuf, sBuf, length);
|
||||
|
||||
|
@ -4539,7 +4537,7 @@ static NSCharacterSet *tokenSet = nil;
|
|||
* and parameters as found after the colon in a mime Content-Type header.
|
||||
* </p>
|
||||
*/
|
||||
- (void) setContentType: (id)newType
|
||||
- (void) setContentType: (NSString *)newType
|
||||
{
|
||||
CREATE_AUTORELEASE_POOL(arp);
|
||||
GSMimeHeader *hdr = nil;
|
||||
|
|
|
@ -64,6 +64,7 @@ NSGeometry.h \
|
|||
NSHashTable.h \
|
||||
NSHost.h \
|
||||
NSInvocation.h \
|
||||
NSKeyedArchiver.h \
|
||||
NSKeyValueCoding.h \
|
||||
NSLock.h \
|
||||
NSMapTable.h \
|
||||
|
@ -79,6 +80,7 @@ NSPort.h \
|
|||
NSPortCoder.h \
|
||||
NSPortMessage.h \
|
||||
NSPortNameServer.h \
|
||||
NSPropertyList.h \
|
||||
NSProcessInfo.h \
|
||||
NSProtocolChecker.h \
|
||||
NSProxy.h \
|
||||
|
|
|
@ -178,6 +178,8 @@ NSGeometry.m \
|
|||
NSHashTable.m \
|
||||
NSHost.m \
|
||||
NSInvocation.m \
|
||||
NSKeyedArchiver.m \
|
||||
NSKeyedUnarchiver.m \
|
||||
NSKeyValueCoding.m \
|
||||
NSLock.m \
|
||||
NSLog.m \
|
||||
|
@ -198,6 +200,7 @@ NSPortCoder.m \
|
|||
NSPortMessage.m \
|
||||
NSPortNameServer.m \
|
||||
NSProcessInfo.m \
|
||||
NSPropertyList.m \
|
||||
NSProtocolChecker.m \
|
||||
NSProxy.m \
|
||||
NSRange.m \
|
||||
|
@ -291,6 +294,7 @@ NSGeometry.h \
|
|||
NSHashTable.h \
|
||||
NSHost.h \
|
||||
NSInvocation.h \
|
||||
NSKeyedArchiver.h \
|
||||
NSKeyValueCoding.h \
|
||||
NSLock.h \
|
||||
NSMapTable.h \
|
||||
|
@ -307,6 +311,7 @@ NSPortCoder.h \
|
|||
NSPortMessage.h \
|
||||
NSPortNameServer.h \
|
||||
NSProcessInfo.h \
|
||||
NSPropertyList.h \
|
||||
NSProtocolChecker.h \
|
||||
NSProxy.h \
|
||||
NSRange.h \
|
||||
|
|
|
@ -436,39 +436,44 @@ OAppend(id obj, NSDictionary *loc, unsigned lev, unsigned step,
|
|||
}
|
||||
else if ([obj isKindOfClass: [NSNumber class]])
|
||||
{
|
||||
double val = [obj doubleValue];
|
||||
const char *t = [obj objCType];
|
||||
|
||||
if (val == 1.0)
|
||||
if (*t == 'c' || *t == 'C')
|
||||
{
|
||||
if (x == PLXML)
|
||||
BOOL val = [obj boolValue];
|
||||
|
||||
if (val == YES)
|
||||
{
|
||||
Append(@"<true/>\n", dest);
|
||||
}
|
||||
else if (x == PLNEW)
|
||||
{
|
||||
Append(@"<*BY>", dest);
|
||||
if (x == PLXML)
|
||||
{
|
||||
Append(@"<true/>\n", dest);
|
||||
}
|
||||
else if (x == PLNEW)
|
||||
{
|
||||
Append(@"<*BY>", dest);
|
||||
}
|
||||
else
|
||||
{
|
||||
PString([obj description], dest);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PString([obj description], dest);
|
||||
if (x == PLXML)
|
||||
{
|
||||
Append(@"<false/>\n", dest);
|
||||
}
|
||||
else if (x == PLNEW)
|
||||
{
|
||||
Append(@"<*BN>", dest);
|
||||
}
|
||||
else
|
||||
{
|
||||
PString([obj description], dest);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (val == 0.0)
|
||||
{
|
||||
if (x == PLXML)
|
||||
{
|
||||
Append(@"<false/>\n", dest);
|
||||
}
|
||||
else if (x == PLNEW)
|
||||
{
|
||||
Append(@"<*BN>", dest);
|
||||
}
|
||||
else
|
||||
{
|
||||
PString([obj description], dest);
|
||||
}
|
||||
}
|
||||
else if (rint(val) == val)
|
||||
else if (strchr("sSiIlLqQ", *t) != 0)
|
||||
{
|
||||
if (x == PLXML)
|
||||
{
|
||||
|
@ -601,7 +606,7 @@ OAppend(id obj, NSDictionary *loc, unsigned lev, unsigned step,
|
|||
{
|
||||
NSEnumerator *e;
|
||||
|
||||
Append(@"<array>", dest);
|
||||
Append(@"<array>\n", dest);
|
||||
e = [obj objectEnumerator];
|
||||
while ((obj = [e nextObject]))
|
||||
{
|
||||
|
@ -700,6 +705,7 @@ OAppend(id obj, NSDictionary *loc, unsigned lev, unsigned step,
|
|||
Append(@"<key>", dest);
|
||||
XString(key, dest);
|
||||
Append(@"</key>\n", dest);
|
||||
Append(iSizeString, dest);
|
||||
OAppend(val, loc, level, step, x, dest);
|
||||
}
|
||||
Append(iBaseString, dest);
|
||||
|
|
112
Source/NSCoder.m
112
Source/NSCoder.m
|
@ -294,6 +294,116 @@
|
|||
+ GNUSTEP_BASE_MINOR_VERSION) * 100) + GNUSTEP_BASE_SUBMINOR_VERSION;
|
||||
}
|
||||
|
||||
|
||||
// Keyed archiving extensions
|
||||
|
||||
- (BOOL) allowsKeyedCoding
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) containsValueForKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) decodeBoolForKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (const uint8_t*) decodeBytesForKey: (NSString*)aKey
|
||||
returnedLength: (unsigned*)alength
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (double) decodeDoubleForKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
- (float) decodeFloatForKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
- (int) decodeIntForKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (int32_t) decodeInt32ForKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (int64_t) decodeInt64ForKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (id) decodeObjectForKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void) encodeBool: (BOOL) aBool forKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (void) encodeBytes: (const uint8_t*)aPointer
|
||||
length: (unsigned)length
|
||||
forKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (void) encodeConditionalObject: (id)anObject forKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (void) encodeDouble: (double)aDouble forKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (void) encodeFloat: (float)aFloat forKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (void) encodeInt: (int)anInteger forKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (void) encodeInt32: (int32_t)anInteger forKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (void) encodeInt64: (int64_t)anInteger forKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
- (void) encodeObject: (id)anObject forKey: (NSString*)aKey
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSCoder (GNUstep)
|
||||
|
@ -378,4 +488,6 @@
|
|||
{
|
||||
[self encodeValueOfObjCType: @encode(id) at: anObject withName: name];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
|
|
741
Source/NSKeyedArchiver.m
Normal file
741
Source/NSKeyedArchiver.m
Normal file
|
@ -0,0 +1,741 @@
|
|||
/** Implementation for NSKeyedArchiver for GNUStep
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Richard Frith-Macdonald <rfm@gnu.org>
|
||||
Date: January 2004
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
||||
|
||||
*/
|
||||
|
||||
#include <Foundation/NSAutoreleasePool.h>
|
||||
#include <Foundation/NSObject.h>
|
||||
#include <Foundation/NSData.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSValue.h>
|
||||
|
||||
/*
|
||||
* Setup for inline operation of pointer map tables.
|
||||
*/
|
||||
#define GSI_MAP_RETAIN_KEY(M, X)
|
||||
#define GSI_MAP_RELEASE_KEY(M, X)
|
||||
#define GSI_MAP_RETAIN_VAL(M, X)
|
||||
#define GSI_MAP_RELEASE_VAL(M, X)
|
||||
#define GSI_MAP_HASH(M, X) ((X).uint)
|
||||
#define GSI_MAP_EQUAL(M, X,Y) ((X).uint == (Y).uint)
|
||||
#define GSI_MAP_NOCLEAN 1
|
||||
|
||||
#include <GNUstepBase/GSIMap.h>
|
||||
|
||||
|
||||
#define _IN_NSKEYEDARCHIVER_M 1
|
||||
#include <Foundation/NSKeyedArchiver.h>
|
||||
#undef _IN_NSKEYEDARCHIVER_M
|
||||
|
||||
/* Exceptions */
|
||||
NSString * const NSInvalidArchiveOperationException
|
||||
= @"NSInvalidArchiveOperationException";
|
||||
|
||||
static NSMapTable *globalClassMap = 0;
|
||||
|
||||
#define CHECKKEY \
|
||||
if ([aKey isKindOfClass: [NSString class]] == NO) \
|
||||
{ \
|
||||
[NSException raise: NSInvalidArgumentException \
|
||||
format: @"%@, bad key '%@' in %@", \
|
||||
NSStringFromClass([self class]), aKey, NSStringFromSelector(_cmd)]; \
|
||||
} \
|
||||
if ([aKey hasPrefix: @"$"] == YES) \
|
||||
{ \
|
||||
aKey = [@"$" stringByAppendingString: aKey]; \
|
||||
} \
|
||||
if ([_enc objectForKey: aKey] != nil) \
|
||||
{ \
|
||||
[NSException raise: NSInvalidArgumentException \
|
||||
format: @"%@, duplicate key '%@' in %@", \
|
||||
NSStringFromClass([self class]), aKey, NSStringFromSelector(_cmd)]; \
|
||||
}
|
||||
|
||||
@interface NSKeyedArchiver (Private)
|
||||
- (NSDictionary*) _buildObjectReference: (id)anObject;
|
||||
- (void) _encodeObject: (id)anObject
|
||||
forKey: (NSString*)aKey
|
||||
conditional: (BOOL)conditional;
|
||||
@end
|
||||
|
||||
@implementation NSKeyedArchiver (Private)
|
||||
/*
|
||||
* Add an object to the table off all encoded objects, and return a reference.
|
||||
*/
|
||||
- (NSDictionary*) _buildObjectReference: (id)anObject
|
||||
{
|
||||
unsigned ref = 0;
|
||||
|
||||
if (anObject != nil)
|
||||
{
|
||||
ref = [_obj count];
|
||||
[_obj addObject: anObject];
|
||||
}
|
||||
return [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: ref]
|
||||
forKey: @"CF$UID"];
|
||||
}
|
||||
|
||||
/*
|
||||
* The real workhorse of the archiving process ... this deals with all
|
||||
* archiving of objects.
|
||||
*/
|
||||
- (void) _encodeObject: (id)anObject
|
||||
forKey: (NSString*)aKey
|
||||
conditional: (BOOL)conditional
|
||||
{
|
||||
id original = anObject;
|
||||
GSIMapNode node;
|
||||
id objectInfo = nil; // Encoded object
|
||||
NSMutableDictionary *m = nil;
|
||||
NSNumber *refNum;
|
||||
NSDictionary *keyDict;
|
||||
unsigned ref = 0;
|
||||
|
||||
if (anObject != nil)
|
||||
{
|
||||
/*
|
||||
* Obtain replacement object for the value being encoded.
|
||||
* Notify delegate of progress and set up new mapping if necessary.
|
||||
*/
|
||||
node = GSIMapNodeForKey(_repMap, (GSIMapKey)anObject);
|
||||
if (node == 0)
|
||||
{
|
||||
anObject = [original replacementObjectForKeyedArchiver: self];
|
||||
if (_delegate != nil)
|
||||
{
|
||||
if (anObject != nil)
|
||||
{
|
||||
anObject = [_delegate archiver: self
|
||||
willEncodeObject: anObject];
|
||||
}
|
||||
if (original != anObject)
|
||||
{
|
||||
[_delegate archiver: self
|
||||
willReplaceObject: original
|
||||
withObject: anObject];
|
||||
}
|
||||
}
|
||||
GSIMapAddPair(_repMap, (GSIMapKey)original, (GSIMapVal)anObject);
|
||||
}
|
||||
}
|
||||
|
||||
if (anObject != nil)
|
||||
{
|
||||
node = GSIMapNodeForKey(_uIdMap, (GSIMapKey)anObject);
|
||||
if (node == 0)
|
||||
{
|
||||
if (conditional == YES)
|
||||
{
|
||||
node = GSIMapNodeForKey(_cIdMap, (GSIMapKey)anObject);
|
||||
if (node == 0)
|
||||
{
|
||||
ref = [_obj count];
|
||||
GSIMapAddPair(_cIdMap, (GSIMapKey)anObject, (GSIMapVal)ref);
|
||||
/*
|
||||
* Use the null object as a placeholder for a conditionally
|
||||
* encoded object.
|
||||
*/
|
||||
[_obj addObject: [_obj objectAtIndex: 0]];
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* This object has already been conditionally encoded.
|
||||
*/
|
||||
ref = node->value.uint;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// FIXME ... exactly what classes are stored directly???
|
||||
if ([anObject isKindOfClass: [NSString class]] == YES)
|
||||
{
|
||||
// We will store the string object directly.
|
||||
objectInfo = anObject;
|
||||
}
|
||||
else
|
||||
{
|
||||
// We store a dictionary describing the object.
|
||||
m = [NSMutableDictionary new];
|
||||
objectInfo = m;
|
||||
}
|
||||
|
||||
node = GSIMapNodeForKey(_cIdMap, (GSIMapKey)anObject);
|
||||
if (node == 0)
|
||||
{
|
||||
/*
|
||||
* Not encoded ... create dictionary for it.
|
||||
*/
|
||||
ref = [_obj count];
|
||||
GSIMapAddPair(_uIdMap, (GSIMapKey)anObject, (GSIMapVal)ref);
|
||||
[_obj addObject: objectInfo];
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* Conditionally encoded ... replace with actual value.
|
||||
*/
|
||||
ref = node->value.uint;
|
||||
GSIMapAddPair(_uIdMap, (GSIMapKey)anObject, (GSIMapVal)ref);
|
||||
GSIMapRemoveKey(_cIdMap, (GSIMapKey)anObject);
|
||||
[_obj replaceObjectAtIndex: ref withObject: objectInfo];
|
||||
}
|
||||
RELEASE(m);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ref = node->value.uint;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Store the mapping from aKey to the appropriate entry in _obj
|
||||
*/
|
||||
refNum = [[NSNumber alloc] initWithInt: ref];
|
||||
keyDict = [NSDictionary dictionaryWithObject: refNum forKey: @"CF$UID"];
|
||||
[_enc setObject: keyDict forKey: aKey];
|
||||
RELEASE(refNum);
|
||||
|
||||
/*
|
||||
* objectInfo is a dictionary describing the object.
|
||||
*/
|
||||
if (objectInfo != nil && m == objectInfo)
|
||||
{
|
||||
NSMutableDictionary *savedEnc = _enc;
|
||||
unsigned savedKeyNum = _keyNum;
|
||||
Class c = [anObject class];
|
||||
NSString *classname;
|
||||
Class mapped;
|
||||
|
||||
/*
|
||||
* Map the class of the object to the actual class it is encoded as.
|
||||
* First ask the object, then apply any name mappings to that value.
|
||||
*/
|
||||
mapped = [anObject classForKeyedArchiver];
|
||||
if (mapped != nil)
|
||||
{
|
||||
c = mapped;
|
||||
}
|
||||
|
||||
classname = [self classNameForClass: c];
|
||||
if (classname == nil)
|
||||
{
|
||||
classname = [[self class] classNameForClass: c];
|
||||
}
|
||||
if (classname == nil)
|
||||
{
|
||||
classname = NSStringFromClass(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
c = NSClassFromString(classname);
|
||||
}
|
||||
|
||||
/*
|
||||
* At last, get the object to encode itsself. Save and restore the
|
||||
* current object scope of course.
|
||||
*/
|
||||
_enc = m;
|
||||
_keyNum = 0;
|
||||
[anObject encodeWithCoder: self];
|
||||
_keyNum = savedKeyNum;
|
||||
_enc = savedEnc;
|
||||
|
||||
/*
|
||||
* This is ugly, but it seems to be the way MacOS-X does it ...
|
||||
* We create class information by storing it directly into the
|
||||
* table of all objects, and making a reference so we can look
|
||||
* up the table entry by class pointer.
|
||||
* A much cleaner way to do it would be by encoding the class
|
||||
* normally, but we are trying to be compatible.
|
||||
*
|
||||
* Also ... we encode the class *after* encoding the instance,
|
||||
* simply because that seems to be the way MacOS-X does it and
|
||||
* we want to maximise compatibility (perhaps they had good reason?)
|
||||
*/
|
||||
node = GSIMapNodeForKey(_uIdMap, (GSIMapKey)c);
|
||||
if (node == 0)
|
||||
{
|
||||
NSMutableDictionary *cDict;
|
||||
NSMutableArray *hierarchy;
|
||||
|
||||
ref = [_obj count];
|
||||
GSIMapAddPair(_uIdMap, (GSIMapKey)c, (GSIMapVal)ref);
|
||||
cDict = [[NSMutableDictionary alloc] initWithCapacity: 2];
|
||||
|
||||
/*
|
||||
* record class name
|
||||
*/
|
||||
[cDict setObject: classname forKey: @"$classname"];
|
||||
|
||||
/*
|
||||
* Record the class hierarchy for this object.
|
||||
*/
|
||||
hierarchy = [NSMutableArray new];
|
||||
while (c != 0)
|
||||
{
|
||||
Class next = [c superClass];
|
||||
|
||||
[hierarchy addObject: NSStringFromClass(c)];
|
||||
if (next == c)
|
||||
{
|
||||
break;
|
||||
}
|
||||
c = next;
|
||||
}
|
||||
[cDict setObject: hierarchy forKey: @"$classes"];
|
||||
RELEASE(hierarchy);
|
||||
[_obj addObject: cDict];
|
||||
RELEASE(cDict);
|
||||
}
|
||||
else
|
||||
{
|
||||
ref = node->value.uint;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now create a reference to the class information and store it
|
||||
* in the object description dictionary for the object we just encoded.
|
||||
*/
|
||||
refNum = [[NSNumber alloc] initWithInt: ref];
|
||||
keyDict = [NSDictionary dictionaryWithObject: refNum forKey: @"CF$UID"];
|
||||
[m setObject: keyDict forKey: @"$class"];
|
||||
RELEASE(refNum);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have encoded the object information, tell the delegaate.
|
||||
*/
|
||||
if (objectInfo != nil && _delegate != nil)
|
||||
{
|
||||
[_delegate archiver: self didEncodeObject: anObject];
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSKeyedArchiver
|
||||
|
||||
/*
|
||||
* When I tried this on MacOS 10.3 it encoded the object with the key 'root',
|
||||
* so this implementation does the same.
|
||||
*/
|
||||
+ (NSData*) archivedDataWithRootObject: (id)anObject
|
||||
{
|
||||
NSMutableData *m = nil;
|
||||
NSKeyedArchiver *a = nil;
|
||||
NSData *d = nil;
|
||||
|
||||
NS_DURING
|
||||
{
|
||||
m = [[NSMutableData alloc] initWithCapacity: 10240];
|
||||
a = [[NSKeyedArchiver alloc] initForWritingWithMutableData: m];
|
||||
[a encodeObject: anObject forKey: @"root"];
|
||||
[a finishEncoding];
|
||||
d = [m copy];
|
||||
DESTROY(m);
|
||||
DESTROY(a);
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
DESTROY(m);
|
||||
DESTROY(a);
|
||||
[localException raise];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
return AUTORELEASE(d);
|
||||
}
|
||||
|
||||
+ (BOOL) archiveRootObject: (id)anObject toFile: (NSString*)aPath
|
||||
{
|
||||
CREATE_AUTORELEASE_POOL(pool);
|
||||
NSData *d;
|
||||
BOOL result;
|
||||
|
||||
d = [self archivedDataWithRootObject: anObject];
|
||||
result = [d writeToFile: aPath atomically: YES];
|
||||
RELEASE(pool);
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (NSString*) classNameForClass: (Class)aClass
|
||||
{
|
||||
return (NSString*)NSMapGet(globalClassMap, (void*)aClass);
|
||||
}
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (globalClassMap == 0)
|
||||
{
|
||||
globalClassMap =
|
||||
NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 0);
|
||||
}
|
||||
}
|
||||
|
||||
+ (void) setClassName: (NSString*)aString forClass: (Class)aClass
|
||||
{
|
||||
if (aString == nil)
|
||||
{
|
||||
NSMapRemove(globalClassMap, (void*)aClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSMapInsert(globalClassMap, (void*)aClass, aString);
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString*) classNameForClass: (Class)aClass
|
||||
{
|
||||
return (NSString*)NSMapGet(_clsMap, (void*)aClass);
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(_enc);
|
||||
RELEASE(_obj);
|
||||
RELEASE(_data);
|
||||
if (_clsMap != 0)
|
||||
{
|
||||
NSFreeMapTable(_clsMap);
|
||||
_clsMap = 0;
|
||||
}
|
||||
if (_cIdMap)
|
||||
{
|
||||
GSIMapEmptyMap(_cIdMap);
|
||||
if (_uIdMap)
|
||||
{
|
||||
GSIMapEmptyMap(_uIdMap);
|
||||
}
|
||||
if (_repMap)
|
||||
{
|
||||
GSIMapEmptyMap(_repMap);
|
||||
}
|
||||
NSZoneFree(_cIdMap->zone, (void*)_cIdMap);
|
||||
}
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (id) delegate
|
||||
{
|
||||
return _delegate;
|
||||
}
|
||||
|
||||
- (void) encodeBool: (BOOL)aBool forKey: (NSString*)aKey
|
||||
{
|
||||
CHECKKEY
|
||||
|
||||
[_enc setObject: [NSNumber numberWithBool: aBool] forKey: aKey];
|
||||
}
|
||||
|
||||
- (void) encodeBytes: (const uint8_t*)aPointer length: (unsigned)length forKey: (NSString*)aKey
|
||||
{
|
||||
CHECKKEY
|
||||
|
||||
[_enc setObject: [NSData dataWithBytes: aPointer length: length]
|
||||
forKey: aKey];
|
||||
}
|
||||
|
||||
- (void) encodeConditionalObject: (id)anObject
|
||||
{
|
||||
[self _encodeObject: anObject
|
||||
forKey: [NSString stringWithFormat: @"$%u", _keyNum++]
|
||||
conditional: YES];
|
||||
}
|
||||
|
||||
- (void) encodeConditionalObject: (id)anObject forKey: (NSString*)aKey
|
||||
{
|
||||
CHECKKEY
|
||||
|
||||
[self _encodeObject: anObject forKey: aKey conditional: YES];
|
||||
}
|
||||
|
||||
- (void) encodeDouble: (double)aDouble forKey: (NSString*)aKey
|
||||
{
|
||||
CHECKKEY
|
||||
|
||||
[_enc setObject: [NSNumber numberWithDouble: aDouble] forKey: aKey];
|
||||
}
|
||||
|
||||
- (void) encodeFloat: (float)aFloat forKey: (NSString*)aKey
|
||||
{
|
||||
CHECKKEY
|
||||
|
||||
[_enc setObject: [NSNumber numberWithFloat: aFloat] forKey: aKey];
|
||||
}
|
||||
|
||||
- (void) encodeInt: (int)anInteger forKey: (NSString*)aKey
|
||||
{
|
||||
CHECKKEY
|
||||
|
||||
[_enc setObject: [NSNumber numberWithInt: anInteger] forKey: aKey];
|
||||
}
|
||||
|
||||
- (void) encodeInt32: (int32_t)anInteger forKey: (NSString*)aKey
|
||||
{
|
||||
CHECKKEY
|
||||
|
||||
[_enc setObject: [NSNumber numberWithLong: anInteger] forKey: aKey];
|
||||
}
|
||||
|
||||
- (void) encodeInt64: (int64_t)anInteger forKey: (NSString*)aKey
|
||||
{
|
||||
CHECKKEY
|
||||
|
||||
[_enc setObject: [NSNumber numberWithLongLong: anInteger] forKey: aKey];
|
||||
}
|
||||
|
||||
- (void) encodeObject: (id)anObject
|
||||
{
|
||||
[self _encodeObject: anObject
|
||||
forKey: [NSString stringWithFormat: @"$%u", _keyNum++]
|
||||
conditional: NO];
|
||||
}
|
||||
|
||||
- (void) encodeObject: (id)anObject forKey: (NSString*)aKey
|
||||
{
|
||||
CHECKKEY
|
||||
|
||||
[self _encodeObject: anObject forKey: aKey conditional: NO];
|
||||
}
|
||||
|
||||
- (void) encodeValueOfObjCType: (const char*)type
|
||||
at: (const void*)address
|
||||
{
|
||||
NSString *aKey;
|
||||
id o;
|
||||
|
||||
if (*type == _C_ID || *type == _C_CLASS)
|
||||
{
|
||||
[self encodeObject: *(id*)address];
|
||||
return;
|
||||
}
|
||||
|
||||
aKey = [NSString stringWithFormat: @"$%u", _keyNum++];
|
||||
switch (*type)
|
||||
{
|
||||
case _C_SEL:
|
||||
{
|
||||
// Selectors are encoded by name as strings.
|
||||
o = NSStringFromSelector(*(SEL*)address);
|
||||
[self encodeObject: o];
|
||||
}
|
||||
return;
|
||||
|
||||
case _C_CHARPTR:
|
||||
{
|
||||
/*
|
||||
* Bizzarely MacOS-X seems to encode char* values by creating
|
||||
* string objects and encoding those objects!
|
||||
*/
|
||||
o = [NSString stringWithCString: (char*)address];
|
||||
[self encodeObject: o];
|
||||
}
|
||||
return;
|
||||
|
||||
case _C_CHR:
|
||||
o = [NSNumber numberWithInt: (int)*(char*)address];
|
||||
[_enc setObject: o forKey: aKey];
|
||||
return;
|
||||
|
||||
case _C_UCHR:
|
||||
o = [NSNumber numberWithInt: (int)*(unsigned char*)address];
|
||||
[_enc setObject: o forKey: aKey];
|
||||
return;
|
||||
|
||||
case _C_SHT:
|
||||
o = [NSNumber numberWithInt: (int)*(short*)address];
|
||||
[_enc setObject: o forKey: aKey];
|
||||
return;
|
||||
|
||||
case _C_USHT:
|
||||
o = [NSNumber numberWithLong: (long)*(unsigned short*)address];
|
||||
[_enc setObject: o forKey: aKey];
|
||||
return;
|
||||
|
||||
case _C_INT:
|
||||
o = [NSNumber numberWithInt: *(int*)address];
|
||||
[_enc setObject: o forKey: aKey];
|
||||
return;
|
||||
|
||||
case _C_UINT:
|
||||
o = [NSNumber numberWithUnsignedInt: *(unsigned int*)address];
|
||||
[_enc setObject: o forKey: aKey];
|
||||
return;
|
||||
|
||||
case _C_LNG:
|
||||
o = [NSNumber numberWithLong: *(long*)address];
|
||||
[_enc setObject: o forKey: aKey];
|
||||
return;
|
||||
|
||||
case _C_ULNG:
|
||||
o = [NSNumber numberWithUnsignedLong: *(unsigned long*)address];
|
||||
[_enc setObject: o forKey: aKey];
|
||||
return;
|
||||
|
||||
case _C_LNG_LNG:
|
||||
o = [NSNumber numberWithLongLong: *(long long*)address];
|
||||
[_enc setObject: o forKey: aKey];
|
||||
return;
|
||||
|
||||
case _C_ULNG_LNG:
|
||||
o = [NSNumber numberWithUnsignedLongLong:
|
||||
*(unsigned long long*)address];
|
||||
[_enc setObject: o forKey: aKey];
|
||||
return;
|
||||
|
||||
case _C_FLT:
|
||||
o = [NSNumber numberWithFloat: *(float*)address];
|
||||
[_enc setObject: o forKey: aKey];
|
||||
return;
|
||||
|
||||
case _C_DBL:
|
||||
o = [NSNumber numberWithDouble: *(double*)address];
|
||||
[_enc setObject: o forKey: aKey];
|
||||
return;
|
||||
|
||||
case _C_STRUCT_B:
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"-[%@ %@]: this archiver cannote encode structs",
|
||||
NSStringFromClass([self class]), NSStringFromSelector(_cmd)];
|
||||
return;
|
||||
|
||||
default: /* Types that can be ignored in first pass. */
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"-[%@ %@]: unknown type encoding ('%c')",
|
||||
NSStringFromClass([self class]), NSStringFromSelector(_cmd), *type];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) finishEncoding
|
||||
{
|
||||
NSMutableDictionary *final;
|
||||
NSData *data;
|
||||
NSString *error;
|
||||
|
||||
[_delegate archiverWillFinish: self];
|
||||
|
||||
final = [NSMutableDictionary new];
|
||||
[final setObject: NSStringFromClass([self class]) forKey: @"$archiver"];
|
||||
[final setObject: @"100000" forKey: @"$version"];
|
||||
[final setObject: _enc forKey: @"$top"];
|
||||
[final setObject: _obj forKey: @"$objects"];
|
||||
data = [NSPropertyListSerialization dataFromPropertyList: final
|
||||
format: _format
|
||||
errorDescription: &error];
|
||||
RELEASE(final);
|
||||
[_data setData: data];
|
||||
[_delegate archiverDidFinish: self];
|
||||
}
|
||||
|
||||
- (id) initForWritingWithMutableData: (NSMutableData*)data
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
NSZone *zone = [self zone];
|
||||
|
||||
_keyNum = 0;
|
||||
_data = RETAIN(data);
|
||||
|
||||
_clsMap = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks,
|
||||
NSObjectMapValueCallBacks, 0);
|
||||
/*
|
||||
* Set up map tables.
|
||||
*/
|
||||
_cIdMap = (GSIMapTable)NSZoneMalloc(zone, sizeof(GSIMapTable_t)*5);
|
||||
_uIdMap = &_cIdMap[1];
|
||||
_repMap = &_cIdMap[2];
|
||||
GSIMapInitWithZoneAndCapacity(_cIdMap, zone, 10);
|
||||
GSIMapInitWithZoneAndCapacity(_uIdMap, zone, 200);
|
||||
GSIMapInitWithZoneAndCapacity(_repMap, zone, 1);
|
||||
|
||||
_enc = [NSMutableDictionary new]; // Top level mapping dict
|
||||
_obj = [NSMutableArray new]; // Array of objects.
|
||||
[_obj addObject: @"$null"]; // Placeholder.
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSPropertyListFormat) outputFormat
|
||||
{
|
||||
return _format;
|
||||
}
|
||||
|
||||
- (void) setClassName: (NSString*)aString forClass: (Class)aClass
|
||||
{
|
||||
if (aString == nil)
|
||||
{
|
||||
NSMapRemove(_clsMap, (void*)aClass);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSMapInsert(_clsMap, (void*)aClass, aString);
|
||||
}
|
||||
}
|
||||
|
||||
- (void) setDelegate: (id)anObject
|
||||
{
|
||||
_delegate = anObject; // Not retained.
|
||||
}
|
||||
|
||||
- (void) setOutputFormat: (NSPropertyListFormat)format
|
||||
{
|
||||
_format = format;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSObject (NSKeyedArchiverDelegate)
|
||||
- (void) archiver: (NSKeyedArchiver*)anArchiver didEncodeObject: (id)anObject
|
||||
{
|
||||
}
|
||||
- (id) archiver: (NSKeyedArchiver*)anArchiver willEncodeObject: (id)anObject
|
||||
{
|
||||
return anObject;
|
||||
}
|
||||
- (void) archiverDidFinish: (NSKeyedArchiver*)anArchiver
|
||||
{
|
||||
}
|
||||
- (void) archiverWillFinish: (NSKeyedArchiver*)anArchiver
|
||||
{
|
||||
}
|
||||
- (void) archiver: (NSKeyedArchiver*)anArchiver
|
||||
willReplaceObject: (id)anObject
|
||||
withObject: (id)newObject
|
||||
{
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSObject (NSKeyedArchiverObjectSubstitution)
|
||||
- (Class) classForKeyedArchiver
|
||||
{
|
||||
return [self classForArchiver];
|
||||
}
|
||||
- (id) replacementObjectForKeyedArchiver: (NSKeyedArchiver*)archiver
|
||||
{
|
||||
return [self replacementObjectForArchiver: nil];
|
||||
}
|
||||
@end
|
||||
|
230
Source/NSKeyedUnarchiver.m
Normal file
230
Source/NSKeyedUnarchiver.m
Normal file
|
@ -0,0 +1,230 @@
|
|||
/** Implementation for NSKeyedUnarchiver for GNUStep
|
||||
Copyright (C) 2004 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Richard Frith-Macdonald <rfm@gnu.org>
|
||||
Date: January 2004
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
||||
|
||||
*/
|
||||
|
||||
#include <Foundation/NSAutoreleasePool.h>
|
||||
#include <Foundation/NSData.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSMapTable.h>
|
||||
|
||||
#include <GNUstepBase/GSIArray.h>
|
||||
#include <GNUstepBase/GSIMap.h>
|
||||
|
||||
#define _IN_NSKEYEDUNARCHIVER_M 1
|
||||
#include <Foundation/NSKeyedArchiver.h>
|
||||
#undef _IN_NSKEYEDUNARCHIVER_M
|
||||
|
||||
static NSMapTable globalClassMap = 0;
|
||||
|
||||
NSString * const NSInvalidUnarchiveOperationException
|
||||
= @"NSInvalidUnarchiveOperationException";
|
||||
|
||||
@implementation NSKeyedUnarchiver
|
||||
|
||||
+ (Class) classForClassName: (NSString*)aString
|
||||
{
|
||||
return (Class)NSMapGet(globalClassMap, (void*)aString);
|
||||
}
|
||||
|
||||
+ (void) initialize
|
||||
{
|
||||
if (globalClassMap == 0)
|
||||
{
|
||||
globalClassMap =
|
||||
NSCreateMapTable(NSObjectMapKeyCallBacks,
|
||||
NSNonOwnedPointerMapValueCallBacks, 0);
|
||||
}
|
||||
}
|
||||
|
||||
+ (void) setClass: (Class)aClass forClassName: (NSString*)aString
|
||||
{
|
||||
if (aClass == nil)
|
||||
{
|
||||
NSMapRemove(globalClassMap, (void*)aString);
|
||||
}
|
||||
else
|
||||
{
|
||||
NSMapInsert(globalClassMap, (void*)aString, aClass);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* When I tried this on MacOS 10.3 it encoded the object with the key 'root',
|
||||
* so this implementation does the same.
|
||||
*/
|
||||
+ (id) unarchiveObjectWithData: (NSData*)data
|
||||
{
|
||||
NSKeyedUnarchiver *u = nil;
|
||||
id o = nil;
|
||||
|
||||
NS_DURING
|
||||
{
|
||||
u = [[NSKeyedUnarchiver alloc] initForReadingWithData: data];
|
||||
o = RETAIN([u decodeObjectForKey: @"root"]);
|
||||
[u finishDecoding];
|
||||
DESTROY(u);
|
||||
}
|
||||
NS_HANDLER
|
||||
{
|
||||
DESTROY(u);
|
||||
[localException raise];
|
||||
}
|
||||
NS_ENDHANDLER
|
||||
return AUTORELEASE(o);
|
||||
}
|
||||
|
||||
+ (id) unarchiveObjectWithFile: (NSString*)aPath
|
||||
{
|
||||
CREATE_AUTORELEASE_POOL(pool);
|
||||
NSData *d;
|
||||
id o;
|
||||
|
||||
d = [NSData dataWithContentsOfFile: aPath];
|
||||
o = [self unarchiveObjectWithData: d];
|
||||
RETAIN(o);
|
||||
RELEASE(pool);
|
||||
return AUTORELEASE(o);
|
||||
}
|
||||
|
||||
- (Class) classForClassName: (NSString*)aString
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL) containsValueForKey: (NSString*)aKey
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL) decodeBoolForKey: (NSString*)aKey
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (const uint8_t*) decodeBytesForKey: (NSString*)aKey
|
||||
returnedLength: (unsigned*)length
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
*length = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (double) decodeDoubleForKey: (NSString*)aKey
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
- (float) decodeFloatForKey: (NSString*)aKey
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
- (int) decodeIntForKey: (NSString*)aKey
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (int32_t) decodeInt32ForKey: (NSString*)aKey
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (int64_t) decodeInt64ForKey: (NSString*)aKey
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (id) decodeObjectForKey: (NSString*)aKey
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (id) delegate
|
||||
{
|
||||
return _delegate;
|
||||
}
|
||||
|
||||
- (void) finishDecoding
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
}
|
||||
|
||||
- (id) initForReadingWithData: (NSData*)data
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void) setClass: (Class)aClass forClassName: (NSString*)aString
|
||||
{
|
||||
[self notImplemented: _cmd];
|
||||
}
|
||||
|
||||
- (void) setDelegate: (id)delegate
|
||||
{
|
||||
_delegate = delegate; // Not retained.
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSObject (NSKeyedUnarchiverDelegate)
|
||||
- (Class) unarchiver: (NSKeyedUnarchiver*)anUnarchiver
|
||||
cannotDecodeObjectOfClassName: (NSString*)aName
|
||||
originalClasses: (NSArray*)classNames
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
- (id) unarchiver: (NSKeyedUnarchiver*)anUnarchiver
|
||||
didDecodeObject: (id)anObject
|
||||
{
|
||||
return anObject;
|
||||
}
|
||||
- (void) unarchiverDidFinish: (NSKeyedUnarchiver*)anUnarchiver
|
||||
{
|
||||
}
|
||||
- (void) unarchiverWillFinish: (NSKeyedUnarchiver*)anUnarchiver
|
||||
{
|
||||
}
|
||||
- (void) unarchiver: (NSKeyedUnarchiver*)anUnarchiver
|
||||
willReplaceObject: (id)anObject
|
||||
withObject: (id)newObject
|
||||
{
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSObject (NSKeyedUnarchiverObjectSubstitution)
|
||||
+ (Class) classForKeyedUnarchiver
|
||||
{
|
||||
return self;
|
||||
}
|
||||
@end
|
||||
|
2178
Source/NSPropertyList.m
Normal file
2178
Source/NSPropertyList.m
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue