blob: 4f8ba4df9e4cb519b0a359574bb96c7cdaecfa0e [file] [log] [blame]
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 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
}
}
public protocol NSCoding {
func encode(with aCoder: NSCoder)
init?(coder aDecoder: NSCoder)
}
public protocol NSSecureCoding : NSCoding {
static var supportsSecureCoding: Bool { get }
}
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)
}
}
open func encodeValue(ofObjCType type: UnsafePointer<Int8>, at addr: UnsafeRawPointer) {
NSRequiresConcreteImplementation()
}
open func encode(_ data: Data) {
NSRequiresConcreteImplementation()
}
open func decodeValue(ofObjCType type: UnsafePointer<Int8>, at data: UnsafeMutableRawPointer) {
NSRequiresConcreteImplementation()
}
open func decodeData() -> Data? {
NSRequiresConcreteImplementation()
}
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()
}
/*!
@method decodeObjectOfClasses:forKey:
@abstract Decodes an object for the key, restricted to the specified classes.
@param classes An array of the expected classes.
@param key The code key.
@return The decoded object.
@discussion This function signature differs from Foundation OS X in that
classes is an array of Classes, not a NSSet. This is because AnyClass cannot
be casted to NSObject, nor is it Hashable.
*/
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()
}
/*!
@method decodeTopLevelObjectOfClasses:
@abstract Decodes an top-level object for the key, restricted to the specified classes.
@param classes An array of the expected classes.
@param key The code key.
@return The decoded object.
@discussion This function signature differs from Foundation OS X in that
classes is an array of Classes, not a NSSet. This is because AnyClass cannot
be casted to NSObject, nor is it Hashable.
*/
open func decodeTopLevelObject(of classes: [AnyClass], forKey key: String) throws -> Any? {
NSUnimplemented()
}
open func encode(_ object: Any?) {
var object = object
withUnsafePointer(to: &object) { (ptr: UnsafePointer<Any?>) -> Void in
encodeValue(ofObjCType: "@", at: unsafeBitCast(ptr, to: UnsafeRawPointer.self))
}
}
open func encodeRootObject(_ rootObject: Any) {
encode(rootObject)
}
open func encodeBycopyObject(_ anObject: Any?) {
encode(anObject)
}
open func encodeByrefObject(_ anObject: Any?) {
encode(anObject)
}
open func encodeConditionalObject(_ object: Any?) {
encode(object)
}
open func encodeArray(ofObjCType type: UnsafePointer<Int8>, count: Int, at array: UnsafeRawPointer) {
encodeValue(ofObjCType: "[\(count)\(String(cString: type))]", at: array)
}
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))
}
}
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: unsafeBitCast(ptr, to: UnsafeMutableRawPointer.self))
}
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
}
*/
open func encodePropertyList(_ aPropertyList: Any) {
NSUnimplemented()
}
open func decodePropertyList() -> Any? {
NSUnimplemented()
}
open var systemVersion: UInt32 {
return 1000
}
open var allowsKeyedCoding: Bool {
return false
}
open func encode(_ objv: Any?, forKey key: String) {
NSRequiresConcreteImplementation()
}
open func encodeConditionalObject(_ objv: Any?, forKey key: String) {
NSRequiresConcreteImplementation()
}
open func encode(_ boolv: Bool, forKey key: String) {
NSRequiresConcreteImplementation()
}
open func encode(_ intv: Int32, forKey key: String) {
NSRequiresConcreteImplementation()
}
open func encode(_ intv: Int64, forKey key: String) {
NSRequiresConcreteImplementation()
}
open func encode(_ realv: Float, forKey key: String) {
NSRequiresConcreteImplementation()
}
open func encode(_ realv: Double, forKey key: String) {
NSRequiresConcreteImplementation()
}
open func encodeBytes(_ bytesp: UnsafePointer<UInt8>?, length lenv: Int, forKey key: String) {
NSRequiresConcreteImplementation()
}
open func containsValue(forKey key: String) -> Bool {
NSRequiresConcreteImplementation()
}
open func decodeObject(forKey key: String) -> Any? {
NSRequiresConcreteImplementation()
}
open func decodeBool(forKey key: String) -> Bool {
NSRequiresConcreteImplementation()
}
// NOTE: this equivalent to the decodeIntForKey: in Objective-C implementation
open func decodeCInt(forKey key: String) -> Int32 {
NSRequiresConcreteImplementation()
}
open func decodeInt32(forKey key: String) -> Int32 {
NSRequiresConcreteImplementation()
}
open func decodeInt64(forKey key: String) -> Int64 {
NSRequiresConcreteImplementation()
}
open func decodeFloat(forKey key: String) -> Float {
NSRequiresConcreteImplementation()
}
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()
}
*/
/// - experimental: This method does not exist in the Darwin Foundation.
open func withDecodedUnsafeBufferPointer<ResultType>(forKey key: String, body: (UnsafeBufferPointer<UInt8>?) throws -> ResultType) rethrows -> ResultType {
NSRequiresConcreteImplementation()
}
open func encode(_ intv: Int, forKey key: String) {
NSRequiresConcreteImplementation()
}
open func decodeInteger(forKey key: String) -> Int {
NSRequiresConcreteImplementation()
}
open var requiresSecureCoding: Bool {
return false
}
open func decodePropertyListForKey(_ key: String) -> Any? {
NSUnimplemented()
}
/*!
@property allowedClasses
@abstract The set of coded classes allowed for secure coding. (read-only)
@discussion This property type differs from Foundation OS X 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()
}
}