//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2014 - 2015 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 // //===----------------------------------------------------------------------===// // // MessagePack-based serialization and deserialization. // //===----------------------------------------------------------------------===// public struct MsgPackSerializer { public static func serialize< T : SerializableFixedDictionaryType >(var value: T) -> [UInt8] { // FIXME(performance): we could serialize directly into a byte stream // without creating an intermediate data structure if our MsgPack // serializer could accept arrays and dictionaries of unknown length and // then back-patch the length into the byte stream when it becomes known. var serializerImpl = _MsgPackSerializerImpl() value.serializeDeserialize(&serializerImpl) return serializerImpl._value!.serialize() } } internal struct _MsgPackSerializerImpl { internal var _value: MsgPackVariant? = nil } extension _MsgPackSerializerImpl : ScalarSerializerType { internal mutating func add(inout value: Int64) { _precondition(_value == nil, "value has been set already") _value = .Int64(value) } internal mutating func add(inout value: UInt64) { _precondition(_value == nil, "value has been set already") _value = .UInt64(value) } internal mutating func add(inout value: Float) { _precondition(_value == nil, "value has been set already") _value = .Float32(value) } internal mutating func add(inout value: Double) { _precondition(_value == nil, "value has been set already") _value = .Float64(value) } internal mutating func add(inout value: Bool) { _precondition(_value == nil, "value has been set already") _value = .Bool(value) } internal mutating func add(inout value: String) { _precondition(_value == nil, "value has been set already") _value = .String(value) } } % for value_kind in [ 'Scalar', 'Array', 'Dictionary', 'FixedDictionary' ]: internal func _toMsgPackVariant< Value : RangeReplaceableCollectionType where Value.Generator.Element : Serializable${value_kind}Type >(inout value: Value) -> MsgPackVariant { % if value_kind == 'Scalar': if let byteBlob = value as? [UInt8] { return .Binary(byteBlob) } % end return .Array(MsgPackVariantArray(map(value) { (var element) -> MsgPackVariant in var serializerImpl = _MsgPackSerializerImpl() element.serializeDeserialize(&serializerImpl) return serializerImpl._value! })) } % end extension _MsgPackSerializerImpl : ArraySerializerType { % for value_kind in [ 'Scalar', 'Array', 'Dictionary', 'FixedDictionary' ]: internal mutating func add< Value : RangeReplaceableCollectionType where Value.Generator.Element : Serializable${value_kind}Type >(inout value: Value) { _precondition(_value == nil, "value has been set already") _value = _toMsgPackVariant(&value) } % end } % for value_kind in [ 'Scalar', 'Array', 'Dictionary', 'FixedDictionary' ]: internal func _toMsgPackVariant< Value : Serializable${value_kind}Type >(inout value: [String : Value]) -> MsgPackVariant { var variantDictionary: [String : MsgPackVariant] = [:] for (dictKey, dictValue) in value { var mutableValue = dictValue var serializerImpl = _MsgPackSerializerImpl() mutableValue.serializeDeserialize(&serializerImpl) variantDictionary[dictKey] = serializerImpl._value! } return .Map(MsgPackVariantMap(variantDictionary)) } % end extension _MsgPackSerializerImpl : DictionarySerializerType { % for value_kind in [ 'Scalar', 'Array', 'Dictionary', 'FixedDictionary' ]: internal mutating func add< Value : Serializable${value_kind}Type >(inout value: [String : Value]) { _precondition(_value == nil, "value has been set already") _value = _toMsgPackVariant(&value) } % end } extension _MsgPackSerializerImpl : FixedDictionarySerializerType { % for value_kind in [ 'Scalar', 'Array', 'Dictionary', 'FixedDictionary' ]: internal mutating func addKey< Value : Serializable${value_kind}Type >(key: String, inout value: Value) { var serializerImpl = _MsgPackSerializerImpl() value.serializeDeserialize(&serializerImpl) _addKeyImpl(key, value: serializerImpl._value!) } % end internal mutating func addKey< Value : SerializableScalarType >(key: String, inout value: [Value]) { _addKeyImpl(key, value: _toMsgPackVariant(&value)) } internal mutating func addKey< Value : SerializableScalarType >(key: String, inout value: [String : Value]) { _addKeyImpl(key, value: _toMsgPackVariant(&value)) } internal mutating func _addKeyImpl(key: String, value: MsgPackVariant) { if let existingValue = _value { switch existingValue { case .Map(var map): _value = nil map._append(key: .String(key), value: value) _value = .Map(map) default: _preconditionFailure("impossible") } } else { _value = .Map(MsgPackVariantMap([key: value])) } } } public struct MsgPackDeserializer { public static func deserialize< T : SerializableFixedDictionaryType >(bytes: [UInt8]) -> T { var value = T(forDeserialization: ()) var deserializerImpl = _MsgPackDeserializerImpl(MsgPackVariant(bytes: bytes)!) value.serializeDeserialize(&deserializerImpl) return value } } internal struct _MsgPackDeserializerImpl { internal var _value: MsgPackVariant internal init(_ value: MsgPackVariant) { _value = value } } extension _MsgPackDeserializerImpl : ScalarSerializerType { internal mutating func add(inout value: Int64) { switch _value { case .Int64(let i): value = i default: _preconditionFailure("bad data") } } internal mutating func add(inout value: UInt64) { switch _value { case .UInt64(let i): value = i default: _preconditionFailure("bad data") } } internal mutating func add(inout value: Float) { switch _value { case .Float32(let f): value = f default: _preconditionFailure("bad data") } } internal mutating func add(inout value: Double) { switch _value { case .Float64(let f): value = f default: _preconditionFailure("bad data") } } internal mutating func add(inout value: Bool) { switch _value { case .Bool(let b): value = b default: _preconditionFailure("bad data") } } internal mutating func add(inout value: String) { switch _value { case .String(let s): value = s default: _preconditionFailure("bad data") } } } % for value_kind in [ 'Scalar', 'Array', 'Dictionary', 'FixedDictionary' ]: internal func _fromMsgPackVariant< Value : RangeReplaceableCollectionType where Value.Generator.Element : Serializable${value_kind}Type >(msgPackVariant: MsgPackVariant, inout _ value: Value) { switch msgPackVariant { % if value_kind == 'Scalar': case .Binary(let byteBlob): value = byteBlob as! Value % end case .Array(let a): var elements: [Value.Generator.Element] = [] elements.reserveCapacity(a.count()) for e in a { var element = Value.Generator.Element(forDeserialization: ()) var deserializerImpl = _MsgPackDeserializerImpl(e) element.serializeDeserialize(&deserializerImpl) elements.append(element) } value.replaceRange(value.startIndex..(inout value: Value) { _fromMsgPackVariant(_value, &value) } % end } % for value_kind in [ 'Scalar', 'Array', 'Dictionary', 'FixedDictionary' ]: internal func _fromMsgPackVariant< Value : Serializable${value_kind}Type >(msgPackVariant: MsgPackVariant, inout _ value: [String : Value]) { switch msgPackVariant { case .Map(let m): value.removeAll() for (k, v) in m { switch k { case .String(let s): var element = Value(forDeserialization: ()) var deserializerImpl = _MsgPackDeserializerImpl(v) element.serializeDeserialize(&deserializerImpl) value[s] = element default: _preconditionFailure("bad data") } } default: _preconditionFailure("bad data") } } % end extension _MsgPackDeserializerImpl : DictionarySerializerType { % for value_kind in [ 'Scalar', 'Array', 'Dictionary', 'FixedDictionary' ]: internal mutating func add< Value : Serializable${value_kind}Type >(inout value: [String : Value]) { _fromMsgPackVariant(_value, &value) } % end } extension _MsgPackDeserializerImpl : FixedDictionarySerializerType { % for value_kind in [ 'Scalar', 'Array', 'Dictionary', 'FixedDictionary' ]: internal mutating func addKey< Value : Serializable${value_kind}Type>( key: String, inout value: Value) { var deserializerImpl = _MsgPackDeserializerImpl(_findValueForKey(key)) value.serializeDeserialize(&deserializerImpl) } % end internal mutating func addKey< Value : SerializableScalarType >(key: String, inout value: [Value]) { _fromMsgPackVariant(_findValueForKey(key), &value) } internal mutating func addKey< Value : SerializableScalarType >(key: String, inout value: [String : Value]) { _fromMsgPackVariant(_findValueForKey(key), &value) } internal func _findValueForKey(key: String) -> MsgPackVariant { switch _value { case .Map(let map): for (k, v) in map { switch k { case .String(let s): if key == s { return v } default: () } } _preconditionFailure("key not found") default: _preconditionFailure("bad data") } } }