Skip to content

Commit e135e3c

Browse files
authored
Add fixed32 support to the proto decoder. (#25)
1 parent 6e32bee commit e135e3c

File tree

5 files changed

+86
-23
lines changed

5 files changed

+86
-23
lines changed

Tests/BinaryCodableTests/XCTestManifests.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ extension LengthEncodedPacketEncoderTests {
6666

6767
extension ProtobufTests {
6868
static let __allTests = [
69+
("testDouble0Decoding", testDouble0Decoding),
70+
("testDoubleValueDecoding", testDoubleValueDecoding),
71+
("testFixed320Decoding", testFixed320Decoding),
72+
("testFixed32ValueDecoding", testFixed32ValueDecoding),
6973
("testFloat0Decoding", testFloat0Decoding),
7074
("testFloatValueDecoding", testFloatValueDecoding),
7175
("testGeneratedMessageDecoding", testGeneratedMessageDecoding),

Tests/BinaryCodableTests/protobufs/Message.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ struct Message: ProtoDecodable {
2121
var value4: Float = 0
2222
var value2: UInt32 = 0
2323
var value3: Int32 = 0
24+
var value5: UInt32 = 0
2425

2526
static func fieldDescriptor(for key: CodingKey) -> Field? {
2627
guard let codingKey = key as? CodingKeys else {
@@ -31,6 +32,7 @@ struct Message: ProtoDecodable {
3132
case .value2: return Field(number: 2, type: .uint32)
3233
case .value3: return Field(number: 3, type: .sint32)
3334
case .value4: return Field(number: 4, type: .float)
35+
case .value5: return Field(number: 5, type: .fixed32)
3436
}
3537
}
3638
}

Tests/BinaryCodableTests/protobufs/ProtoDecoderSupport.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ struct Field {
2222
case uint32
2323
case sint32
2424
case float
25+
case fixed32
2526
}
2627
let type: FieldType
2728
}
@@ -112,7 +113,7 @@ private struct ProtoKeyedDecodingContainer<Key: CodingKey>: KeyedDecodingContain
112113
}
113114
switch (fieldDescriptor.type, message.value) {
114115
case (.float, .fixed32(let value)):
115-
return value
116+
return Float(bitPattern: value)
116117
default:
117118
preconditionFailure("Unimplemented")
118119
}
@@ -168,10 +169,10 @@ private struct ProtoKeyedDecodingContainer<Key: CodingKey>: KeyedDecodingContain
168169
debugDescription: "No value found for \(key) of type \(type)."))
169170
}
170171
switch (fieldDescriptor.type, message.value) {
171-
case (.int32, .varint(let rawValue)), (.uint32, .varint(let rawValue)):
172-
return T.init(clamping: rawValue)
173-
case (.sint32, .varint(let rawValue)):
174-
return T.init(clamping: Int32(rawValue >> 1) ^ -Int32(rawValue & 1))
172+
case (.int32, .varint(let rawValue)),
173+
(.uint32, .varint(let rawValue)): return T.init(clamping: rawValue)
174+
case (.sint32, .varint(let rawValue)): return T.init(clamping: Int32(rawValue >> 1) ^ -Int32(rawValue & 1))
175+
case (.fixed32, .fixed32(let rawValue)): return T.init(clamping: rawValue)
175176
default:
176177
preconditionFailure("Unimplemented")
177178
}

Tests/BinaryCodableTests/protobufs/ProtoMessage.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ struct ProtoMessage: BinaryDecodable, Equatable {
2424
let fieldNumber: UInt8
2525
enum Value: Equatable {
2626
case varint(rawValue: UInt64)
27-
case fixed32(rawValue: Float)
28-
case fixed64(rawValue: Double)
27+
case fixed32(rawValue: UInt32)
28+
case fixed64(rawValue: UInt64)
2929
}
3030
let value: Value
3131

@@ -47,8 +47,8 @@ struct ProtoMessage: BinaryDecodable, Equatable {
4747

4848
switch wireType {
4949
case .varint: self.value = try .varint(rawValue: container.decode(VarInt.self).rawValue)
50-
case .fixed32: self.value = try .fixed32(rawValue: container.decode(Float.self))
51-
case .fixed64: self.value = try .fixed64(rawValue: container.decode(Double.self))
50+
case .fixed32: self.value = try .fixed32(rawValue: container.decode(UInt32.self))
51+
case .fixed64: self.value = try .fixed64(rawValue: container.decode(UInt64.self))
5252

5353
default: throw BinaryDecodingError.dataCorrupted(.init(debugDescription: "Unimplemented wire type \(wireType)"))
5454
}

Tests/BinaryCodableTests/protobufs/ProtobufTests.swift

Lines changed: 70 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -397,14 +397,14 @@ class ProtobufTests: XCTestCase {
397397
}
398398
}
399399

400-
// MARK: double
400+
// MARK: fixed32
401401

402-
func testDouble0Decoding() throws {
402+
func testFixed320Decoding() throws {
403403
// Given
404404
do {
405405
let data = try compileProto(definition: """
406406
message value {
407-
double value = 1;
407+
fixed32 value = 1;
408408
}
409409
""", message: "value", content: """
410410
value: 0
@@ -421,19 +421,19 @@ class ProtobufTests: XCTestCase {
421421
}
422422
}
423423

424-
func testDoubleValueDecoding() throws {
424+
func testFixed32ValueDecoding() throws {
425425
// Given
426-
let valuesToTest: [Double] = [
427-
-Double.greatestFiniteMagnitude, -3.14159, -1, 1, 3.14159, Double.greatestFiniteMagnitude,
426+
let valuesToTest: [UInt32] = [
427+
1, UInt32.max
428428
]
429429

430430
for value in valuesToTest {
431431
let data = try compileProto(definition: """
432432
message value {
433-
double value = 1;
433+
fixed32 value = 1;
434434
}
435435
""", message: "value", content: """
436-
value: \(String(format: "%0.20f", value))
436+
value: \(value)
437437
""")
438438
let decoder = BinaryDataDecoder()
439439

@@ -447,9 +447,7 @@ class ProtobufTests: XCTestCase {
447447
continue
448448
}
449449
XCTAssertEqual(message.fieldNumber, 1)
450-
// sint values will be zig-zag encoded.
451-
// https://developers.google.com/protocol-buffers/docs/encoding#signed-integers
452-
XCTAssertEqual(message.value, .fixed64(rawValue: value))
450+
XCTAssertEqual(message.value, .fixed32(rawValue: value))
453451
} catch let error {
454452
XCTFail("Value \(value): \(String(describing: error))")
455453
}
@@ -506,9 +504,65 @@ class ProtobufTests: XCTestCase {
506504
continue
507505
}
508506
XCTAssertEqual(message.fieldNumber, 1)
509-
// sint values will be zig-zag encoded.
510-
// https://developers.google.com/protocol-buffers/docs/encoding#signed-integers
511-
XCTAssertEqual(message.value, .fixed32(rawValue: value))
507+
508+
XCTAssertEqual(message.value, .fixed32(rawValue: value.bitPattern))
509+
} catch let error {
510+
XCTFail("Value \(value): \(String(describing: error))")
511+
}
512+
}
513+
}
514+
515+
// MARK: double
516+
517+
func testDouble0Decoding() throws {
518+
// Given
519+
do {
520+
let data = try compileProto(definition: """
521+
message value {
522+
double value = 1;
523+
}
524+
""", message: "value", content: """
525+
value: 0
526+
""")
527+
let decoder = BinaryDataDecoder()
528+
529+
// When
530+
let messages = try decoder.decode([ProtoMessage].self, from: data)
531+
532+
// Then
533+
XCTAssertEqual(messages.count, 0)
534+
} catch let error {
535+
XCTFail(String(describing: error))
536+
}
537+
}
538+
539+
func testDoubleValueDecoding() throws {
540+
// Given
541+
let valuesToTest: [Double] = [
542+
-Double.greatestFiniteMagnitude, -3.14159, -1, 1, 3.14159, Double.greatestFiniteMagnitude,
543+
]
544+
545+
for value in valuesToTest {
546+
let data = try compileProto(definition: """
547+
message value {
548+
double value = 1;
549+
}
550+
""", message: "value", content: """
551+
value: \(String(format: "%0.20f", value))
552+
""")
553+
let decoder = BinaryDataDecoder()
554+
555+
// When
556+
do {
557+
let messages = try decoder.decode([ProtoMessage].self, from: data)
558+
559+
// Then
560+
XCTAssertEqual(messages.count, 1)
561+
guard let message = messages.first else {
562+
continue
563+
}
564+
XCTAssertEqual(message.fieldNumber, 1)
565+
XCTAssertEqual(message.value, .fixed64(rawValue: value.bitPattern))
512566
} catch let error {
513567
XCTFail("Value \(value): \(String(describing: error))")
514568
}
@@ -526,12 +580,14 @@ class ProtobufTests: XCTestCase {
526580
uint32 second_value = 2;
527581
sint32 third_value = 3;
528582
float fourth_value = 4;
583+
fixed32 fifth_value = 5;
529584
}
530585
""", message: "int_value", content: """
531586
third_value: 268435456
532587
first_value: 1
533588
second_value: \(UInt32.max)
534589
fourth_value: 1.5234
590+
fifth_value: 123
535591
""")
536592
let decoder = ProtoDecoder()
537593

0 commit comments

Comments
 (0)