| // This source file is part of the Swift.org open source project |
| // |
| // Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors |
| // Licensed under Apache License v2.0 with Runtime Library Exception |
| // |
| // See http://swift.org/LICENSE.txt for license information |
| // See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors |
| // |
| |
| extension NSCoder { |
| |
| /// Describes the action an `NSCoder` should take when it encounters decode |
| /// failures (e.g. corrupt data) for non-TopLevel decodes. Darwin platfrom |
| /// supports exceptions here, and there may be other approaches supported |
| /// in the future, so its included for completeness. |
| public enum DecodingFailurePolicy : Int { |
| case setErrorAndReturn |
| } |
| } |
| |
| |
| /// The `NSCoding` protocol declares the two methods that a class must implement |
| /// so that instances of that class can be encoded and decoded. This capability |
| /// provides the basis for archiving (where objects and other structures are |
| /// stored on disk) and distribution (where objects are copied to different |
| /// address spaces). |
| /// |
| /// In keeping with object-oriented design principles, an object being encoded |
| /// or decoded is responsible for encoding and decoding its instance variables. |
| /// A coder instructs the object to do so by invoking `encode(with:)` or |
| /// `init(coder:)`. `encode(with:)` instructs the object to encode its instance |
| /// variables to the coder provided; this method can be invoked any number of |
| /// times. `init(coder:)` instructs the object to initialize itself from data |
| /// in the coder provided. |
| /// Any object class that should be codable must adopt the NSCoding protocol and |
| /// implement its methods. |
| public protocol NSCoding { |
| |
| /// Encodes an instance of a conforming class using a given archiver. |
| /// |
| /// - Parameter aCoder: An archiver object. |
| func encode(with aCoder: NSCoder) |
| |
| /// Initializes an object from data in a given unarchiver. |
| /// |
| /// - Parameter aDecoder: An unarchiver object. |
| init?(coder aDecoder: NSCoder) |
| } |
| |
| /// Conforming to the `NSSecureCoding` protocol indicates that an object handles |
| /// encoding and decoding instances of itself in a manner that is robust against |
| /// object substitution attacks. |
| /// |
| /// Historically, many classes decoded instances of themselves like this: |
| /// ```swift |
| /// if let object = decoder.decodeObject(forKey: "myKey") as? MyClass { |
| /// ...succeeds... |
| /// } else { |
| /// ...fail... |
| /// } |
| /// ``` |
| /// This technique is potentially unsafe because by the time you can verify |
| /// the class type, the object has already been constructed, and if this is part |
| /// of a collection class, potentially inserted into an object graph. |
| /// |
| /// In order to conform to `NSSecureCoding`: |
| /// - An object that does not override `init(coder:)` can conform to |
| /// `NSSecureCoding` without any changes (assuming that it is a subclass |
| /// of another class that conforms). |
| /// - An object that does override `init(coder:)` must decode any enclosed |
| /// objects using the `decodeObject(of:forKey:)` method. For example: |
| /// ```swift |
| /// let obj = decoder.decodeObject(of: MyClass.self, forKey: "myKey") |
| /// ``` |
| /// In addition, the class must override its `NSSecureCoding` method to return |
| /// `true`. |
| public protocol NSSecureCoding : NSCoding { |
| |
| static var supportsSecureCoding: Bool { get } |
| } |
| |
| /// The `NSCoder` abstract class declares the interface used by concrete |
| /// subclasses to transfer objects and other values between memory and some |
| /// other format. This capability provides the basis for archiving (where |
| /// objects and data items are stored on disk) and distribution (where objects |
| /// and data items are copied between different processes or threads). The |
| /// concrete subclasses provided by Foundation for these purposes are |
| /// `NSKeyedArchiver` and `NSKeyedUnarchiver`. Concrete subclasses of `NSCoder` |
| /// are referred to in general as coder classes, and instances of these classes |
| /// as coder objects (or simply coders). A coder object that can only encode |
| /// values is referred to as an encoder object, and one that can only decode |
| /// values as a decoder object. |
| /// |
| /// `NSCoder` operates on objects, scalars, C arrays, structures, and strings, |
| /// and on pointers to these types. It does not handle types whose |
| /// implementation varies across platforms, such as `UnsafeRawPointer`, |
| /// closures, and long chains of pointers. A coder object stores object type |
| /// information along with the data, so an object decoded from a stream of bytes |
| /// is normally of the same class as the object that was originally encoded into |
| /// the stream. An object can change its class when encoded, however; this is |
| /// described in Archives and Serializations Programming Guide. |
| open class NSCoder : NSObject { |
| internal var _pendingBuffers = Array<(UnsafeMutableRawPointer, Int)>() |
| |
| deinit { |
| for buffer in _pendingBuffers { |
| // Cannot deinitialize a pointer to unknown type. |
| buffer.0.deallocate(bytes: buffer.1, alignedTo: MemoryLayout<Int>.alignment) |
| } |
| } |
| |
| /// Must be overridden by subclasses to encode a single value residing at |
| /// `addr`, whose Objective-C type is given by `type`. |
| /// |
| /// `type` must contain exactly one type code. |
| /// |
| /// This method must be matched by a subsequent |
| /// `decodeValue(ofObjCType:at:)` call. |
| /// |
| /// - Parameters: |
| /// - type: A type code. |
| /// - addr: The address of the object to endcode. |
| open func encodeValue(ofObjCType type: UnsafePointer<Int8>, at addr: UnsafeRawPointer) { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Encodes a given `Data` object. |
| /// |
| /// Subclasses must override this method. |
| /// |
| /// This method must be matched by a subsequent `decodeData()` call. |
| /// |
| /// - Parameter data: The data to encode. |
| open func encode(_ data: Data) { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Decodes a single value, whose Objective-C type is given by `type`. |
| /// |
| /// `type` must contain exactly one type code, and the buffer specified by |
| /// `data` must be large enough to hold the value corresponding to that type |
| /// code. |
| /// |
| /// Subclasses must override this method and provide an implementation to |
| /// decode the value. In your overriding implementation, decode the value |
| /// into the buffer beginning at `data`. |
| /// |
| /// This method matches an `encodeValue(ofObjCType:at:)` call used during |
| /// encoding. |
| /// |
| /// - Parameters: |
| /// - type: A type code. |
| /// - data: The buffer to put the decoded value into. |
| open func decodeValue(ofObjCType type: UnsafePointer<Int8>, at data: UnsafeMutableRawPointer) { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Decodes and returns a `Data` object that was previously encoded with |
| /// `encode(_:)`. Subclasses must override this method. |
| /// |
| /// The implementation of your overriding method must match the |
| /// implementation of your `encode(_:)` method. For example, a typical |
| /// `encode(_:)` method encodes the number of bytes of data followed by |
| /// the bytes themselves. Your override of this method must read the number |
| /// of bytes, create a `Data` object of the appropriate size, and decode the |
| /// bytes into the new `Data` object. |
| /// |
| /// - Returns: The decoded data. |
| open func decodeData() -> Data? { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// This method is present for historical reasons and is not used with |
| /// keyed archivers. |
| /// |
| /// The version number does apply not to |
| /// `NSKeyedArchiver`/`NSKeyedUnarchiver`. A keyed archiver does not encode |
| /// class version numbers. |
| /// |
| /// - Parameter className: The class name. |
| /// - Returns: The version in effect for the class named `className` or |
| /// `NSNotFound` if no class named `className` exists. |
| open func version(forClassName className: String) -> Int { |
| NSRequiresConcreteImplementation() |
| } |
| |
| open func decodeObject<DecodedObjectType: NSCoding>(of cls: DecodedObjectType.Type, forKey key: String) -> DecodedObjectType? where DecodedObjectType: NSObject { |
| NSUnimplemented() |
| } |
| |
| /// Decodes an object for the key, restricted to the specified `classes`. |
| /// |
| /// This function signature differs from Darwin Foundation in that `classes` |
| /// is an array of classes, not a set. This is because `AnyClass` cannot |
| /// be casted to `NSObject`, nor is it `Hashable`. |
| /// |
| /// - Parameters: |
| /// - classes: An array of the expected classes. |
| /// - key: The code key. |
| /// - Returns: The decoded object. |
| open func decodeObject(of classes: [AnyClass]?, forKey key: String) -> Any? { |
| NSUnimplemented() |
| } |
| |
| open func decodeTopLevelObject() throws -> Any? { |
| NSUnimplemented() |
| } |
| |
| open func decodeTopLevelObject(forKey key: String) throws -> Any? { |
| NSUnimplemented() |
| } |
| |
| open func decodeTopLevelObject<DecodedObjectType: NSCoding>(of cls: DecodedObjectType.Type, forKey key: String) throws -> DecodedObjectType? where DecodedObjectType: NSObject { |
| NSUnimplemented() |
| } |
| |
| /// Decodes an top-level object for the key, restricted to the specified |
| /// `classes`. |
| /// |
| /// This function signature differs from Darwin Foundation in that `classes` |
| /// is an array of classes, not a set. This is because `AnyClass` cannot |
| /// be casted to `NSObject`, nor is it `Hashable`. |
| /// |
| /// - Parameters: |
| /// - classes: An array of the expected classes. |
| /// - key: The code key. |
| /// - Returns: The decoded object. |
| open func decodeTopLevelObject(of classes: [AnyClass], forKey key: String) throws -> Any? { |
| NSUnimplemented() |
| } |
| |
| /// Encodes `object`. |
| /// |
| /// `NSCoder`’s implementation simply invokes `encodeValue(ofObjCType:at:)` |
| /// to encode object. Subclasses can override this method to encode |
| /// a reference to object instead of object itself. |
| /// |
| /// This method must be matched by a subsequent `decodeObject()` call. |
| /// |
| /// - Parameter object: The object to encode. |
| open func encode(_ object: Any?) { |
| var object = object |
| withUnsafePointer(to: &object) { (ptr: UnsafePointer<Any?>) -> Void in |
| encodeValue(ofObjCType: "@", at: UnsafeRawPointer(ptr)) |
| } |
| } |
| |
| /// Can be overridden by subclasses to encode an interconnected group of |
| /// Objective-C objects, starting with `rootObject`. |
| /// |
| /// `NSCoder`’s implementation simply invokes `encode(_:)`. |
| /// |
| /// This method must be matched by a subsequent `decodeObject()` call. |
| /// |
| /// - Parameter rootObject: The root object of the group to encode. |
| open func encodeRootObject(_ rootObject: Any) { |
| encode(rootObject) |
| } |
| |
| /// Can be overridden by subclasses to encode `anObject` so that a copy, |
| /// rather than a proxy, is created upon decoding. |
| /// |
| /// `NSCoder`’s implementation simply invokes `encode(_:)`. |
| /// |
| /// This method must be matched by a corresponding `decodeObject()` call. |
| /// |
| /// - Parameter anObject: The object to encode. |
| open func encodeBycopyObject(_ anObject: Any?) { |
| encode(anObject) |
| } |
| |
| /// Can be overridden by subclasses to encode `anObject` so that a proxy, |
| /// rather than a copy, is created upon decoding. |
| /// |
| /// `NSCoder`’s implementation simply invokes `encode(_:)`. |
| /// |
| /// This method must be matched by a corresponding `decodeObject()` call. |
| /// |
| /// - Parameter anObject: The object to encode. |
| open func encodeByrefObject(_ anObject: Any?) { |
| encode(anObject) |
| } |
| |
| /// Can be overridden by subclasses to conditionally encode `object`, |
| /// preserving common references to that object. |
| /// |
| /// In the overriding method, `object` should be encoded only if it’s |
| /// unconditionally encoded elsewhere (with any other `encode...Object` |
| /// method). |
| /// |
| /// This method must be matched by a subsequent `decodeObject()` call. Upon |
| /// decoding, if `object` was never encoded unconditionally, |
| /// `decodeObject()` returns `nil` in place of `object`. However, if |
| /// `object` was encoded unconditionally, all references to `object` must be |
| /// resolved. |
| /// |
| /// `NSCoder’s` implementation simply invokes `encode(_:)`. |
| /// |
| /// - Parameter object: The object to conditionally encode. |
| open func encodeConditionalObject(_ object: Any?) { |
| encode(object) |
| } |
| |
| /// Encodes an array of `count` items, whose Objective-C type is given by |
| /// `type`. |
| /// |
| /// The values are encoded from the buffer beginning at `array`. `type` must |
| /// contain exactly one type code. `NSCoder`’s implementation invokes |
| /// `encodeValue(ofObjCType:at:)` to encode the entire array of items. |
| /// Subclasses that implement the `encodeValue(ofObjCType:at:)` method do |
| /// not need to override this method. |
| /// |
| /// This method must be matched by a subsequent |
| /// `decodeArray(ofObjCType:count:at:)` call. |
| /// |
| /// - note: You should not use this method to encode C arrays of Objective-C |
| /// objects. See `decodeArray(ofObjCType:count:at:)` for more |
| /// details. |
| /// |
| /// - Parameters: |
| /// - type: A type code. |
| /// - count: The number of items in `array`. |
| /// - array: The buffer of items. |
| open func encodeArray(ofObjCType type: UnsafePointer<Int8>, count: Int, at array: UnsafeRawPointer) { |
| encodeValue(ofObjCType: "[\(count)\(String(cString: type))]", at: array) |
| } |
| |
| /// Encodes a buffer of data whose types are unspecified. |
| /// |
| /// The buffer to be encoded begins at `byteaddr`, and its length in bytes |
| /// is given by `length`. |
| /// |
| /// This method must be matched by a corresponding |
| /// `decodeBytes(withReturnedLength:)` call. |
| /// |
| /// - Parameters: |
| /// - byteaddr: The address of the buffer to encode. |
| /// - length: The length of the buffer. |
| open func encodeBytes(_ byteaddr: UnsafeRawPointer?, length: Int) { |
| var newLength = UInt32(length) |
| withUnsafePointer(to: &newLength) { (ptr: UnsafePointer<UInt32>) -> Void in |
| encodeValue(ofObjCType: "I", at: ptr) |
| } |
| var empty: [Int8] = [] |
| withUnsafePointer(to: &empty) { |
| encodeArray(ofObjCType: "c", count: length, at: byteaddr ?? UnsafeRawPointer($0)) |
| } |
| } |
| |
| /// Decodes an Objective-C object that was previously encoded with any of |
| /// the `encode...Object` methods. |
| /// |
| /// `NSCoder`’s implementation invokes `decodeValue(ofObjCType:at:)` to |
| /// decode the object data. |
| /// |
| /// Subclasses may need to override this method if they override any of the |
| /// corresponding `encode...Object` methods. For example, if an object was |
| /// encoded conditionally using the `encodeConditionalObject(_:)` method, |
| /// this method needs to check whether the object had actually been encoded. |
| /// |
| /// - Returns: The decoded object. |
| open func decodeObject() -> Any? { |
| if self.error != nil { |
| return nil |
| } |
| |
| var obj: Any? = nil |
| withUnsafeMutablePointer(to: &obj) { (ptr: UnsafeMutablePointer<Any?>) -> Void in |
| decodeValue(ofObjCType: "@", at: UnsafeMutableRawPointer(ptr)) |
| } |
| return obj |
| } |
| |
| open func decodeArray(ofObjCType itemType: UnsafePointer<Int8>, count: Int, at array: UnsafeMutableRawPointer) { |
| decodeValue(ofObjCType: "[\(count)\(String(cString: itemType))]", at: array) |
| } |
| |
| /* |
| // TODO: This is disabled, as functions which return unsafe interior pointers are inherently unsafe when we have no autorelease pool. |
| open func decodeBytes(withReturnedLength lengthp: UnsafeMutablePointer<Int>) -> UnsafeMutableRawPointer? { |
| var length: UInt32 = 0 |
| withUnsafeMutablePointer(to: &length) { (ptr: UnsafeMutablePointer<UInt32>) -> Void in |
| decodeValue(ofObjCType: "I", at: unsafeBitCast(ptr, to: UnsafeMutableRawPointer.self)) |
| } |
| // we cannot autorelease here so instead the pending buffers will manage the lifespan of the returned data... this is wasteful but good enough... |
| let result = UnsafeMutableRawPointer.allocate(bytes: Int(length), alignedTo: MemoryLayout<Int>.alignment) |
| decodeValue(ofObjCType: "c", at: result) |
| lengthp.pointee = Int(length) |
| _pendingBuffers.append((result, Int(length))) |
| return result |
| } |
| */ |
| |
| /// Encodes the property list `aPropertyList`. |
| /// |
| /// `NSCoder`’s implementation invokes `encodeValue(ofObjCType:at:)` |
| /// to encode `aPropertyList`. |
| /// |
| /// This method must be matched by a subsequent `decodePropertyList()` call. |
| /// |
| /// - Parameter aPropertyList: The property list to encode. |
| open func encodePropertyList(_ aPropertyList: Any) { |
| NSUnimplemented() |
| } |
| |
| /// Decodes a property list that was previously encoded with |
| /// `encodePropertyList(_:)`. |
| /// |
| /// - Returns: The decoded property list. |
| open func decodePropertyList() -> Any? { |
| NSUnimplemented() |
| } |
| |
| /// The system version in effect for the archive. |
| /// |
| /// During encoding, the current version. During decoding, the version that |
| /// was in effect when the data was encoded. |
| /// |
| /// Subclasses that implement decoding must override this property to return |
| /// the system version of the data being decoded. |
| open var systemVersion: UInt32 { |
| return 1000 |
| } |
| |
| /// A Boolean value that indicates whether the receiver supports keyed |
| /// coding of objects. |
| /// |
| /// `false` by default. Concrete subclasses that support keyed coding, |
| /// such as `NSKeyedArchiver`, need to override this property to return |
| /// `true`. |
| open var allowsKeyedCoding: Bool { |
| return false |
| } |
| |
| /// Encodes the object `objv` and associates it with the string `key`. |
| /// |
| /// Subclasses must override this method to identify multiple encodings |
| /// of `objv` and encode a reference to `objv` instead. For example, |
| /// `NSKeyedArchiver` detects duplicate objects and encodes a reference to |
| /// the original object rather than encode the same object twice. |
| /// |
| /// - Parameters: |
| /// - objv: The object to encode. |
| /// - key: The key to associate the object with. |
| open func encode(_ objv: Any?, forKey key: String) { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Conditionally encodes a reference to `objv` and associates it with |
| /// the string `key` only if `objv` has been unconditionally encoded with |
| /// `encode(_:forKey:)`. |
| /// |
| /// Subclasses must override this method if they support keyed coding. |
| /// |
| /// The encoded object is decoded with the `decodeObject(forKey:)` method. |
| /// If `objv` was never encoded unconditionally, `decodeObject(forKey:)` |
| /// returns `nil` in place of `objv`. |
| /// |
| /// - Parameters: |
| /// - objv: The object to conditionally encode. |
| /// - key: The key to associate the object with. |
| open func encodeConditionalObject(_ objv: Any?, forKey key: String) { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Encodes `boolv` and associates it with the string `key`. |
| /// |
| /// Subclasses must override this method if they perform keyed coding. |
| /// |
| /// - Parameters: |
| /// - boolv: The value to encode. |
| /// - key: The key to associate the value with. |
| open func encode(_ boolv: Bool, forKey key: String) { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Encodes the 32-bit integer `intv` and associates it with the string |
| /// `key`. |
| /// |
| /// Subclasses must override this method if they perform keyed coding. |
| /// |
| /// - Parameters: |
| /// - intv: The value to encode. |
| /// - key: The key to associate the value with. |
| open func encode(_ intv: Int32, forKey key: String) { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Encodes the 64-bit integer `intv` and associates it with the string |
| /// `key`. |
| /// |
| /// Subclasses must override this method if they perform keyed coding. |
| /// |
| /// - Parameters: |
| /// - intv: The value to encode. |
| /// - key: The key to associate the value with. |
| open func encode(_ intv: Int64, forKey key: String) { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Encodes `realv` and associates it with the string |
| /// `key`. |
| /// |
| /// Subclasses must override this method if they perform keyed coding. |
| /// |
| /// - Parameters: |
| /// - intv: The value to encode. |
| /// - key: The key to associate the value with. |
| open func encode(_ realv: Float, forKey key: String) { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Encodes `realv` and associates it with the string |
| /// `key`. |
| /// |
| /// Subclasses must override this method if they perform keyed coding. |
| /// |
| /// - Parameters: |
| /// - intv: The value to encode. |
| /// - key: The key to associate the value with. |
| open func encode(_ realv: Double, forKey key: String) { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Encodes a buffer of data, `bytesp`, whose length is specified by `lenv`, |
| /// and associates it with the string `key`. |
| /// |
| /// Subclasses must override this method if they perform keyed coding. |
| /// |
| /// - Parameters: |
| /// - bytesp: The buffer of data to encode. |
| /// - lenv: The length of the buffer. |
| /// - key: The key to associate the data with. |
| open func encodeBytes(_ bytesp: UnsafePointer<UInt8>?, length lenv: Int, forKey key: String) { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Returns a Boolean value that indicates whether an encoded value is |
| /// available for a string. |
| /// |
| /// Subclasses must override this method if they perform keyed coding. |
| /// |
| /// The string is passed as `key`. |
| /// |
| /// - Parameter key: The key to test. |
| /// - Returns: `true` if an encoded value is available for provided |
| /// `key`, otherwise `false`. |
| open func containsValue(forKey key: String) -> Bool { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Decodes and returns an Objective-C object that was previously encoded |
| /// with `encode(_:forKey:)` or `encodeConditionalObject(_:forKey:)` and |
| /// associated with the string `key`. |
| /// |
| /// - Parameter key: The key the object to be decoded is associated with. |
| /// - Returns: The decoded object. |
| open func decodeObject(forKey key: String) -> Any? { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Decodes and returns a Boolean value that was previously encoded with |
| /// `encode(_:forKey:)` and associated with the string `key`. |
| /// |
| /// Subclasses must override this method if they perform keyed coding. |
| /// |
| /// - Parameter key: The key the value to be decoded is associated with. |
| /// - Returns: The decoded value. |
| open func decodeBool(forKey key: String) -> Bool { |
| NSRequiresConcreteImplementation() |
| } |
| |
| // NOTE: this equivalent to the decodeIntForKey: in Objective-C implementation |
| |
| /// Decodes and returns an int value that was previously encoded with |
| /// `encodeCInt(_:forKey:)` or `encode(_:forKey:)` and associated with |
| /// the string `key`. |
| /// |
| /// Subclasses must override this method if they perform keyed coding. |
| /// |
| /// - Parameter key: The key the value to be decoded is associated with. |
| /// - Returns: The decoded value. |
| open func decodeCInt(forKey key: String) -> Int32 { |
| |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Decodes and returns a 32-bit integer value that was previously encoded |
| /// with `encodeCInt(_:forKey:)` or `encode(_:forKey:)` and associated with |
| /// the string `key`. |
| /// |
| /// Subclasses must override this method if they perform keyed coding. |
| /// |
| /// - Parameter key: The key the value to be decoded is associated with. |
| /// - Returns: The decoded value. |
| open func decodeInt32(forKey key: String) -> Int32 { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Decodes and returns a 64-bit integer value that was previously encoded |
| /// with `encodeCInt(_:forKey:)` or `encode(_:forKey:)` and associated with |
| /// the string `key`. |
| /// |
| /// Subclasses must override this method if they perform keyed coding. |
| /// |
| /// - Parameter key: The key the value to be decoded is associated with. |
| /// - Returns: The decoded value. |
| open func decodeInt64(forKey key: String) -> Int64 { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Decodes and returns a float value that was previously encoded |
| /// with `encodeCInt(_:forKey:)` or `encode(_:forKey:)` and associated with |
| /// the string `key`. |
| /// |
| /// Subclasses must override this method if they perform keyed coding. |
| /// |
| /// - Parameter key: The key the value to be decoded is associated with. |
| /// - Returns: The decoded value. |
| open func decodeFloat(forKey key: String) -> Float { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Decodes and returns a double value that was previously encoded |
| /// with `encodeCInt(_:forKey:)` or `encode(_:forKey:)` and associated with |
| /// the string `key`. |
| /// |
| /// Subclasses must override this method if they perform keyed coding. |
| /// |
| /// - Parameter key: The key the value to be decoded is associated with. |
| /// - Returns: The decoded value. |
| open func decodeDouble(forKey key: String) -> Double { |
| NSRequiresConcreteImplementation() |
| } |
| |
| // TODO: This is disabled, as functions which return unsafe interior pointers are inherently unsafe when we have no autorelease pool. |
| /* |
| open func decodeBytes(forKey key: String, returnedLength lengthp: UnsafeMutablePointer<Int>?) -> UnsafePointer<UInt8>? { // returned bytes immutable! |
| NSRequiresConcreteImplementation() |
| } |
| */ |
| |
| /// - Experiment: This method does not exist in the Darwin Foundation. |
| open func withDecodedUnsafeBufferPointer<ResultType>(forKey key: String, body: (UnsafeBufferPointer<UInt8>?) throws -> ResultType) rethrows -> ResultType { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Encodes a given integer number and associates it with a given key. |
| /// |
| /// Subclasses must override this method if they perform keyed coding. |
| /// |
| /// - Parameters: |
| /// - intv: The value to encode. |
| /// - key: The key to associate the value with. |
| open func encode(_ intv: Int, forKey key: String) { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Decodes and returns an integer value that was previously encoded |
| /// with `encodeCInt(_:forKey:)` or `encode(_:forKey:)` and associated with |
| /// the string `key`. |
| /// |
| /// Subclasses must override this method if they perform keyed coding. |
| /// |
| /// - Parameter key: The key the value to be decoded is associated with. |
| /// - Returns: The decoded value. |
| open func decodeInteger(forKey key: String) -> Int { |
| NSRequiresConcreteImplementation() |
| } |
| |
| /// Boolean value that indicates whether the coder requires secure coding. |
| /// |
| /// `true` if this coder requires secure coding; `false` otherwise. |
| /// |
| /// Secure coders check a set of allowed classes before decoding objects, |
| /// and all objects must implement the `NSSecureCoding` protocol. |
| open var requiresSecureCoding: Bool { |
| return false |
| } |
| |
| /// Returns a decoded property list for the specified key. |
| /// |
| /// - Parameter key: The coder key. |
| /// - Returns: A decoded object containing a property list. |
| open func decodePropertyList(forKey key: String) -> Any? { |
| NSUnimplemented() |
| } |
| |
| /// The array of coded classes allowed for secure coding. |
| /// |
| /// This property type differs from Darwin Foundation in that `classes` is |
| /// an array of classes, not a set. This is because `AnyClass` is not |
| /// `Hashable`. |
| /// |
| /// - Experiment: This is a draft API currently under consideration for |
| /// official import into Foundation. |
| open var allowedClasses: [AnyClass]? { |
| NSUnimplemented() |
| } |
| |
| open func failWithError(_ error: Error) { |
| NSUnimplemented() |
| // NOTE: disabled for now due to bridging uncertainty |
| // if let debugDescription = error.userInfo["NSDebugDescription"] { |
| // NSLog("*** NSKeyedUnarchiver.init: \(debugDescription)") |
| // } else { |
| // NSLog("*** NSKeyedUnarchiver.init: decoding error") |
| // } |
| } |
| |
| open var decodingFailurePolicy: NSCoder.DecodingFailurePolicy { |
| return .setErrorAndReturn |
| } |
| |
| open var error: Error? { |
| NSRequiresConcreteImplementation() |
| } |
| |
| internal func _decodeArrayOfObjectsForKey(_ key: String) -> [Any] { |
| NSRequiresConcreteImplementation() |
| } |
| |
| internal func _decodePropertyListForKey(_ key: String) -> Any? { |
| NSRequiresConcreteImplementation() |
| } |
| } |