8
8
9
9
import Foundation
10
10
11
+ /// An object that decodes instances of a data type from protobuf objects.
11
12
package struct ProtobufDecoder {
13
+ /// An error that can occur during `ProtobufDecoder` decoding.
12
14
package enum DecodingError : Error {
13
15
case failed
14
16
}
15
17
18
+ /// A type representing a field in a protobuf encoding.
16
19
package typealias Field = ProtobufFormat . Field
20
+
21
+ /// A type representing the wire type of a protobuf encoding.
17
22
package typealias WireType = ProtobufFormat . WireType
18
23
24
+ /// The data being decoded.
19
25
var data : NSData
26
+
27
+ /// A pointer to the current position in the data.
20
28
var ptr : UnsafeRawPointer
29
+
30
+ /// A pointer to the end of the data.
21
31
var end : UnsafeRawPointer
32
+
33
+ /// The current packed field.
22
34
var packedField : Field = Field ( rawValue: 0 )
35
+
36
+ /// A pointer to the end of the packed field.
23
37
var packedEnd : UnsafeRawPointer
38
+
39
+ /// A stack of pointers for nested messages.
24
40
var stack : [ UnsafeRawPointer ] = [ ]
41
+
42
+ /// User-defined information.
25
43
package var userInfo : [ CodingUserInfoKey : Any ] = [ : ]
26
44
45
+ /// Creates an instance with a data buffer.
27
46
package init ( _ data: Data ) {
28
47
let nsData = data as NSData
29
48
self . data = nsData
@@ -35,6 +54,7 @@ package struct ProtobufDecoder {
35
54
}
36
55
37
56
extension ProtobufDecoder {
57
+ /// Decodes the next field in the data.
38
58
package mutating func nextField( ) throws -> ProtobufDecoder . Field ? {
39
59
guard ptr < end else {
40
60
packedField = Field ( rawValue: 0 )
@@ -55,6 +75,7 @@ extension ProtobufDecoder {
55
75
return field
56
76
}
57
77
78
+ /// Skips the next field in the data.
58
79
package mutating func skipField( _ field: ProtobufDecoder . Field ) throws {
59
80
switch field. wireType {
60
81
case . varint:
@@ -78,6 +99,10 @@ extension ProtobufDecoder {
78
99
}
79
100
}
80
101
102
+ /// Decodes a boolean(Bool) value field from the data.
103
+ ///
104
+ /// - Parameter field: The field to decode.
105
+ /// - Returns: A boolean(Bool) value.
81
106
package mutating func boolField( _ field: ProtobufDecoder . Field ) throws -> Bool {
82
107
switch field. wireType {
83
108
case . varint:
@@ -96,6 +121,10 @@ extension ProtobufDecoder {
96
121
return try decodeVariant ( ) != 0
97
122
}
98
123
124
+ /// Decodes an unsigned integer(UInt) value field from the data.
125
+ ///
126
+ /// - Parameter field: The field to decode.
127
+ /// - Returns: An unsigned integer(UInt) value.
99
128
package mutating func uintField( _ field: ProtobufDecoder . Field ) throws -> UInt {
100
129
switch field. wireType {
101
130
case . varint:
@@ -114,31 +143,59 @@ extension ProtobufDecoder {
114
143
return try decodeVariant ( )
115
144
}
116
145
146
+ /// Decodes an enum field from the data.
147
+ ///
148
+ /// - Parameter field: The field to decode.
149
+ /// - Returns: A ProtobufEnum value.
117
150
package mutating func enumField< T> ( _ field: ProtobufDecoder . Field ) throws -> T ? where T: ProtobufEnum {
118
151
try T ( protobufValue: uintField ( field) )
119
152
}
120
153
154
+ /// Decodes an unsigned 8-bit integer(UInt8) value field from the data.
155
+ ///
156
+ /// - Parameter field: The field to decode.
157
+ /// - Returns: An unsigned 8-bit integer(UInt8) value.
121
158
package mutating func uint8Field( _ field: ProtobufDecoder . Field ) throws -> UInt8 {
122
159
try UInt8 ( uintField ( field) )
123
160
}
124
161
162
+ /// Decodes an unsigned 16-bit integer(UInt16) value field from the data.
163
+ ///
164
+ /// - Parameter field: The field to decode.
165
+ /// - Returns: An unsigned 16-bit integer(UInt16) value.
125
166
package mutating func uint16Field( _ field: ProtobufDecoder . Field ) throws -> UInt16 {
126
167
try UInt16 ( uintField ( field) )
127
168
}
128
169
170
+ /// Decodes an unsigned 32-bit integer(UInt32) value field from the data.
171
+ ///
172
+ /// - Parameter field: The field to decode.
173
+ /// - Returns: An unsigned 32-bit integer(UInt32) value.
129
174
package mutating func uint32Field( _ field: ProtobufDecoder . Field ) throws -> UInt32 {
130
175
try UInt32 ( uintField ( field) )
131
176
}
132
177
178
+ /// Decodes an unsigned 64-bit integer(UInt64) value field from the data.
179
+ ///
180
+ /// - Parameter field: The field to decode.
181
+ /// - Returns: An unsigned 64-bit integer(UInt64) value.
133
182
package mutating func uint64Field( _ field: ProtobufDecoder . Field ) throws -> UInt64 {
134
183
try UInt64 ( uintField ( field) )
135
184
}
136
185
186
+ /// Decodes a signed integer(Int) value field from the data.
187
+ ///
188
+ /// - Parameter field: The field to decode.
189
+ /// - Returns: A signed integer(Int) value.
137
190
package mutating func intField( _ field: ProtobufDecoder . Field ) throws -> Int {
138
191
let value = Int ( bitPattern: try uintField ( field) )
139
192
return Int ( bitPattern: UInt ( bitPattern: ( value >> 1 ) ) ^ UInt ( bitPattern: - ( value & 1 ) ) )
140
193
}
141
194
195
+ /// Decodes a fixed 32-bit integer(UInt32) value field from the data.
196
+ ///
197
+ /// - Parameter field: The field to decode.
198
+ /// - Returns: A fixed 32-bit integer(UInt32) value.
142
199
package mutating func fixed32Field( _ field: ProtobufDecoder . Field ) throws -> UInt32 {
143
200
switch field. wireType {
144
201
case . lengthDelimited:
@@ -163,6 +220,10 @@ extension ProtobufDecoder {
163
220
return value
164
221
}
165
222
223
+ /// Decodes a fixed 64-bit integer(UInt64) value field from the data.
224
+ ///
225
+ /// - Parameter field: The field to decode.
226
+ /// - Returns: A fixed 64-bit integer(UInt64) value.
166
227
package mutating func fixed64Field( _ field: ProtobufDecoder . Field ) throws -> UInt64 {
167
228
switch field. wireType {
168
229
case . lengthDelimited:
@@ -187,6 +248,10 @@ extension ProtobufDecoder {
187
248
return value
188
249
}
189
250
251
+ /// Decodes a float(Float) value field from the data.
252
+ ///
253
+ /// - Parameter field: The field to decode.
254
+ /// - Returns: A float(Float) value.
190
255
package mutating func floatField( _ field: ProtobufDecoder . Field ) throws -> Float {
191
256
switch field. wireType {
192
257
case . lengthDelimited:
@@ -211,6 +276,10 @@ extension ProtobufDecoder {
211
276
return Float ( bitPattern: value)
212
277
}
213
278
279
+ /// Decodes a double(Double) value field from the data.
280
+ ///
281
+ /// - Parameter field: The field to decode.
282
+ /// - Returns: A double(Double) value.
214
283
package mutating func doubleField( _ field: ProtobufDecoder . Field ) throws -> Double {
215
284
switch field. wireType {
216
285
case . fixed64:
@@ -243,11 +312,19 @@ extension ProtobufDecoder {
243
312
return Double ( bitPattern: value)
244
313
}
245
314
315
+ /// Decodes a CGFloat value field from the data.
316
+ ///
317
+ /// - Parameter field: The field to decode.
318
+ /// - Returns: A CGFloat value.
246
319
@inline ( __always)
247
320
package mutating func cgFloatField( _ field: ProtobufDecoder . Field ) throws -> CGFloat {
248
321
try doubleField ( field)
249
322
}
250
323
324
+ /// Decodes a data buffer value field from the data.
325
+ ///
326
+ /// - Parameter field: The field to decode.
327
+ /// - Returns: A data buffer value.
251
328
package mutating func dataBufferField( _ field: ProtobufDecoder . Field ) throws -> UnsafeRawBufferPointer {
252
329
switch field. wireType {
253
330
case . lengthDelimited:
@@ -257,6 +334,10 @@ extension ProtobufDecoder {
257
334
}
258
335
}
259
336
337
+ /// Decodes a data value field from the data.
338
+ ///
339
+ /// - Parameter field: The field to decode.
340
+ /// - Returns: A data value.
260
341
package mutating func dataField( _ field: ProtobufDecoder . Field ) throws -> Data {
261
342
switch field. wireType {
262
343
case . lengthDelimited:
@@ -272,20 +353,34 @@ extension ProtobufDecoder {
272
353
}
273
354
}
274
355
356
+ /// Decodes a message value field from the data.
357
+ ///
358
+ /// - Parameter field: The field to decode.
359
+ /// - Returns: A ProtobufDecodableMessage value.
275
360
package mutating func messageField< T> ( _ field: ProtobufDecoder . Field ) throws -> T where T: ProtobufDecodableMessage {
276
361
guard field. wireType == . lengthDelimited else {
277
362
throw DecodingError . failed
278
363
}
279
364
return try decodeMessage ( )
280
365
}
281
366
367
+ /// Decodes a message value field from the data.
368
+ ///
369
+ /// - Parameters:
370
+ /// - field: The field to decode.
371
+ /// - body: A closure that decodes the message.
372
+ /// - Returns: A value decoded from the message.
282
373
package mutating func messageField< T> ( _ field: ProtobufDecoder . Field , _ body: ( inout ProtobufDecoder ) throws -> T ) throws -> T {
283
374
guard field. wireType == . lengthDelimited else {
284
375
throw DecodingError . failed
285
376
}
286
377
return try decodeMessage ( body)
287
378
}
288
379
380
+ /// Decodes a string value field from the data.
381
+ ///
382
+ /// - Parameter field: The field to decode.
383
+ /// - Returns: A string value.
289
384
package mutating func stringField( _ field: ProtobufDecoder . Field ) throws -> String {
290
385
let data = try dataField ( field)
291
386
guard let result = String ( data: data, encoding: . utf8) else {
@@ -294,13 +389,18 @@ extension ProtobufDecoder {
294
389
return result
295
390
}
296
391
392
+ /// Decodes a codable value field from the data.
393
+ ///
394
+ /// - Parameter field: The field to decode.
395
+ /// - Returns: A codable value.
297
396
package mutating func codableField< T> ( _ field: ProtobufDecoder . Field ) throws -> T where T: Decodable {
298
397
let data = try dataField ( field)
299
398
return try value ( fromBinaryPlist: data)
300
399
}
301
400
}
302
401
303
402
extension ProtobufDecoder {
403
+ /// Decodes a variant from the data.
304
404
private mutating func decodeVariant( ) throws -> UInt {
305
405
var value : UInt = 0
306
406
var shift : UInt = 0
@@ -318,6 +418,7 @@ extension ProtobufDecoder {
318
418
return value
319
419
}
320
420
421
+ /// Decodes a data buffer from the data.
321
422
private mutating func decodeDataBuffer( ) throws -> UnsafeRawBufferPointer {
322
423
let count = try Int ( decodeVariant ( ) )
323
424
let oldPtr = ptr
@@ -329,6 +430,7 @@ extension ProtobufDecoder {
329
430
return UnsafeRawBufferPointer ( start: oldPtr, count: count)
330
431
}
331
432
433
+ /// Begins decoding a message.
332
434
private mutating func beginMessage( ) throws {
333
435
stack. append ( end)
334
436
let count = try Int ( decodeVariant ( ) )
@@ -339,18 +441,34 @@ extension ProtobufDecoder {
339
441
end = newPtr
340
442
}
341
443
444
+ /// Decodes a message from the data.
445
+ ///
446
+ /// - Parameters:
447
+ /// - body: A closure that decodes the message.
448
+ /// - Returns: The value decoded from the message.
342
449
private mutating func decodeMessage< T> ( _ body: ( inout ProtobufDecoder ) throws -> T ) throws -> T {
343
450
try beginMessage ( )
344
451
defer { end = stack. removeLast ( ) }
345
452
return try body ( & self )
346
453
}
347
454
455
+ /// Decodes a message from the data.
456
+ ///
457
+ /// - Returns: A ProtobufDecodableMessage value.
348
458
private mutating func decodeMessage< T> ( ) throws -> T where T: ProtobufDecodableMessage {
349
459
try beginMessage ( )
350
460
defer { end = stack. removeLast ( ) }
351
461
return try T ( from: & self )
352
462
}
353
463
464
+ /// Decodes a value from a binary plist.
465
+ ///
466
+ /// NOTE: This is only available on non-WASI platforms.
467
+ ///
468
+ /// - Parameters:
469
+ /// - data: The plist data.
470
+ /// - type: The type to decode.
471
+ /// - Returns: The decodable value resulting from the plist data.
354
472
func value< T> ( fromBinaryPlist data: Data , type: T . Type = T . self) throws -> T where T: Decodable {
355
473
#if os(WASI)
356
474
fatalError ( " PropertyListDecoder is not avaiable on WASI " )
0 commit comments