Skip to content

Commit

Permalink
Code refactoring: common code for count write
Browse files Browse the repository at this point in the history
  • Loading branch information
DimaRU committed Jan 29, 2024
1 parent 9ca9fca commit 6229168
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 36 deletions.
13 changes: 13 additions & 0 deletions Sources/CDRCodable/Encoder/CDREncoder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -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)
}
}
19 changes: 3 additions & 16 deletions Sources/CDRCodable/Encoder/KeyedEncodingContainer.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand All @@ -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)
}
Expand Down Expand Up @@ -85,11 +76,7 @@ extension _CDREncoder.KeyedContainer: KeyedEncodingContainerProtocol {
case let value as [Float]: try encodeNumericArray(count: value.count, size: MemoryLayout<Float>.size, pointer: value.withUnsafeBytes{ $0 })
case let value as [Double]: try encodeNumericArray(count: value.count, size: MemoryLayout<Double>.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)
Expand Down
21 changes: 4 additions & 17 deletions Sources/CDRCodable/Encoder/SingleValueEncodingContainer.swift
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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)
}
Expand All @@ -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<T>(_ value: T) throws where T : Encodable {
Expand All @@ -77,5 +66,3 @@ extension _CDREncoder.SingleValueContainer: SingleValueEncodingContainer {
}
}
}

extension _CDREncoder.SingleValueContainer: _CDREncodingContainer {}
4 changes: 1 addition & 3 deletions Sources/CDRCodable/Encoder/UnkeyedEncodingContainer.swift
Original file line number Diff line number Diff line change
@@ -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]
Expand Down Expand Up @@ -53,5 +53,3 @@ extension _CDREncoder.UnkeyedContainer: UnkeyedEncodingContainer {
fatalError("Unimplemented")
}
}

extension _CDREncoder.UnkeyedContainer: _CDREncodingContainer {}

0 comments on commit 6229168

Please sign in to comment.