diff --git a/Sources/CDRCodable/Encoder/CDREncoder.swift b/Sources/CDRCodable/Encoder/CDREncoder.swift index 4c02fc8..964513e 100644 --- a/Sources/CDRCodable/Encoder/CDREncoder.swift +++ b/Sources/CDRCodable/Encoder/CDREncoder.swift @@ -31,6 +31,7 @@ final public class CDREncoder { } encoder = nil // call deinit and finalize dataBlock changes. + // Final data aligment let aligment = dataBlock.data.count % 4 if aligment != 0 { for _ in 0..<4-aligment { @@ -45,6 +46,8 @@ final public class CDREncoder { protocol _CDREncodingContainer { var dataStore: _CDREncoder.DataStore { get } + var codingPath: [CodingKey] { get set } + func write(count: Int) throws } final class _CDREncoder { @@ -119,3 +122,13 @@ extension _CDREncoder.DataStore { self.data.append(contentsOf: value.bytes) } } + +extension _CDREncodingContainer { + func write(count: Int) throws { + guard let uint32 = UInt32(exactly: count) else { + let context = EncodingError.Context(codingPath: self.codingPath, debugDescription: "Cannot encode data of length \(count).") + throw EncodingError.invalidValue(count, context) + } + dataStore.write(value: uint32) + } +} diff --git a/Sources/CDRCodable/Encoder/KeyedEncodingContainer.swift b/Sources/CDRCodable/Encoder/KeyedEncodingContainer.swift index b173313..bb5be5f 100644 --- a/Sources/CDRCodable/Encoder/KeyedEncodingContainer.swift +++ b/Sources/CDRCodable/Encoder/KeyedEncodingContainer.swift @@ -21,11 +21,7 @@ extension _CDREncoder { extension _CDREncoder.KeyedContainer: KeyedEncodingContainerProtocol { @inline(__always) private func encodeNumericArray(count: Int, size: Int, pointer: UnsafeRawBufferPointer) throws { - guard let uint32 = UInt32(exactly: count) else { - let context = EncodingError.Context(codingPath: self.codingPath, debugDescription: "Cannot encode data of length \(count).") - throw EncodingError.invalidValue(count, context) - } - dataStore.write(value: uint32) + try write(count: count) self.dataStore.data.append(pointer.baseAddress!.assumingMemoryBound(to: UInt8.self), count: count * size) } @@ -48,12 +44,7 @@ extension _CDREncoder.KeyedContainer: KeyedEncodingContainerProtocol { } let length = data.count + 1 - if let uint32 = UInt32(exactly: length) { - dataStore.write(value: uint32) - } else { - let context = EncodingError.Context(codingPath: self.codingPath, debugDescription: "Cannot encode string with length \(length).") - throw EncodingError.invalidValue(value, context) - } + try write(count: length) dataStore.write(data: data) dataStore.writeByte(0) } @@ -85,11 +76,7 @@ extension _CDREncoder.KeyedContainer: KeyedEncodingContainerProtocol { case let value as [Float]: try encodeNumericArray(count: value.count, size: MemoryLayout.size, pointer: value.withUnsafeBytes{ $0 }) case let value as [Double]: try encodeNumericArray(count: value.count, size: MemoryLayout.size, pointer: value.withUnsafeBytes{ $0 }) case let value as Data: - guard let uint32 = UInt32(exactly: value.count) else { - let context = EncodingError.Context(codingPath: self.codingPath, debugDescription: "Cannot encode data of length \(value.count).") - throw EncodingError.invalidValue(value.count, context) - } - dataStore.write(value: uint32) + try write(count: value.count) dataStore.write(data: value) default: let encoder = _CDREncoder(data: self.dataStore) diff --git a/Sources/CDRCodable/Encoder/SingleValueEncodingContainer.swift b/Sources/CDRCodable/Encoder/SingleValueEncodingContainer.swift index ec56701..b5edab2 100644 --- a/Sources/CDRCodable/Encoder/SingleValueEncodingContainer.swift +++ b/Sources/CDRCodable/Encoder/SingleValueEncodingContainer.swift @@ -1,7 +1,7 @@ import Foundation extension _CDREncoder { - final class SingleValueContainer { + final class SingleValueContainer: _CDREncodingContainer { var codingPath: [CodingKey] var userInfo: [CodingUserInfoKey: Any] var dataStore: DataStore @@ -34,12 +34,7 @@ extension _CDREncoder.SingleValueContainer: SingleValueEncodingContainer { } let length = data.count + 1 - if let uint32 = UInt32(exactly: length) { - dataStore.write(value: uint32) - } else { - let context = EncodingError.Context(codingPath: self.codingPath, debugDescription: "Cannot encode string with length \(length).") - throw EncodingError.invalidValue(value, context) - } + try write(count: length) dataStore.write(data: data) dataStore.writeByte(0) } @@ -57,14 +52,8 @@ extension _CDREncoder.SingleValueContainer: SingleValueEncodingContainer { } func encode(_ value: Data) throws { - let length = value.count - if let uint32 = UInt32(exactly: length) { - dataStore.write(value: uint32) - dataStore.write(data: value) - } else { - let context = EncodingError.Context(codingPath: self.codingPath, debugDescription: "Cannot encode data of length \(value.count).") - throw EncodingError.invalidValue(value, context) - } + try write(count: value.count) + dataStore.write(data: value) } func encode(_ value: T) throws where T : Encodable { @@ -77,5 +66,3 @@ extension _CDREncoder.SingleValueContainer: SingleValueEncodingContainer { } } } - -extension _CDREncoder.SingleValueContainer: _CDREncodingContainer {} diff --git a/Sources/CDRCodable/Encoder/UnkeyedEncodingContainer.swift b/Sources/CDRCodable/Encoder/UnkeyedEncodingContainer.swift index 5c47e08..f8d6bc6 100644 --- a/Sources/CDRCodable/Encoder/UnkeyedEncodingContainer.swift +++ b/Sources/CDRCodable/Encoder/UnkeyedEncodingContainer.swift @@ -1,7 +1,7 @@ import Foundation extension _CDREncoder { - final class UnkeyedContainer { + final class UnkeyedContainer: _CDREncodingContainer { var count: Int = 0 private var index: Data.Index var codingPath: [CodingKey] @@ -53,5 +53,3 @@ extension _CDREncoder.UnkeyedContainer: UnkeyedEncodingContainer { fatalError("Unimplemented") } } - -extension _CDREncoder.UnkeyedContainer: _CDREncodingContainer {}