Files
SwiftCBOR/Sources/Encoder/SingleValueEncodingContainer.swift
T

170 lines
5.1 KiB
Swift

import Foundation
extension _CBOREncoder {
final class SingleValueContainer {
private var storage: Data = Data()
fileprivate var canEncodeNewValue = true
fileprivate func checkCanEncode(value: Any?) throws {
guard self.canEncodeNewValue else {
let context = EncodingError.Context(codingPath: self.codingPath, debugDescription: "Attempt to encode value through single value container when previously value already encoded.")
throw EncodingError.invalidValue(value as Any, context)
}
}
var codingPath: [CodingKey]
var userInfo: [CodingUserInfoKey: Any]
let options: CodableCBOREncoder._Options
init(codingPath: [CodingKey], userInfo: [CodingUserInfoKey : Any], options: CodableCBOREncoder._Options) {
self.codingPath = codingPath
self.userInfo = userInfo
self.options = options
}
}
}
extension _CBOREncoder.SingleValueContainer: SingleValueEncodingContainer {
func encodeNil() throws {
try checkCanEncode(value: nil)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encodeNull())
}
func encode(_ value: Bool) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encodeBool(value))
}
func encode(_ value: String) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encodeString(value, options: self.options.toCBOROptions()))
}
func encode(_ value: Double) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encodeDouble(value))
}
func encode(_ value: Float) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encodeFloat(value))
}
func encode(_ value: Int) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encode(value))
}
func encode(_ value: Int8) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encode(Int(value)))
}
func encode(_ value: Int16) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encode(Int(value)))
}
func encode(_ value: Int32) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encode(Int(value)))
}
func encode(_ value: Int64) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encode(Int(value)))
}
func encode(_ value: UInt) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encode(value))
}
func encode(_ value: UInt8) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encode(value))
}
func encode(_ value: UInt16) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encode(value))
}
func encode(_ value: UInt32) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encode(value))
}
func encode(_ value: UInt64) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encode(value))
}
func encodeDate(_ value: Date) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encodeDate(value, options: self.options.toCBOROptions()))
}
func encodeData(_ value: Data) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
self.storage.append(contentsOf: CBOR.encodeData(value, options: self.options.toCBOROptions()))
}
func encode<T: Encodable>(_ value: T) throws {
try checkCanEncode(value: value)
defer { self.canEncodeNewValue = false }
switch value {
case let data as Data:
try self.encodeData(data)
case let date as Date:
try self.encodeDate(date)
default:
let encoder = _CBOREncoder(options: self.options)
try value.encode(to: encoder)
self.storage.append(encoder.data)
}
}
}
extension _CBOREncoder.SingleValueContainer: CBOREncodingContainer {
var data: Data {
return storage
}
}