serde-generate/runtime/swift/Sources/Serde/BinaryDeserializer.swift (135 lines of code) (raw):
// Copyright (c) Facebook, Inc. and its affiliates.
import Foundation
public class BinaryDeserializer: Deserializer {
let input: [UInt8]
private var location: Int
private var containerDepthBudget: Int
init(input: [UInt8], maxContainerDepth: Int) {
self.input = input
location = 0
containerDepthBudget = maxContainerDepth
}
private func readBytes(count: Int) throws -> [UInt8] {
let newLocation = location + count
if newLocation > input.count {
throw DeserializationError.invalidInput(issue: "Input is too small")
}
let bytes = input[location ..< newLocation]
location = newLocation
return Array(bytes)
}
public func deserialize_len() throws -> Int {
assertionFailure("Not implemented")
return 0
}
public func deserialize_variant_index() throws -> UInt32 {
assertionFailure("Not implemented")
return 0
}
public func deserialize_char() throws -> Character {
throw DeserializationError.invalidInput(issue: "Not implemented: char deserialization")
}
public func deserialize_f32() throws -> Float {
throw DeserializationError.invalidInput(issue: "Not implemented: f32 deserialization")
}
public func deserialize_f64() throws -> Double {
throw DeserializationError.invalidInput(issue: "Not implemented: f64 deserialization")
}
public func increase_container_depth() throws {
if containerDepthBudget == 0 {
throw DeserializationError.invalidInput(issue: "Exceeded maximum container depth")
}
containerDepthBudget -= 1
}
public func decrease_container_depth() {
containerDepthBudget += 1
}
public func deserialize_str() throws -> String {
let bytes = try deserialize_bytes()
guard let value = String(bytes: bytes, encoding: .utf8) else {
throw DeserializationError.invalidInput(issue: "Incorrect UTF8 string")
}
return value
}
public func deserialize_bytes() throws -> [UInt8] {
let len = try deserialize_len()
let content = try readBytes(count: len)
return content
}
public func deserialize_bool() throws -> Bool {
let value = try deserialize_u8()
switch value {
case 0: return false
case 1: return true
default: throw DeserializationError.invalidInput(issue: "Incorrect value for boolean: \(value)")
}
}
public func deserialize_unit() throws -> Unit {
return Unit()
}
public func deserialize_u8() throws -> UInt8 {
let bytes = try readBytes(count: 1)
return bytes[0]
}
public func deserialize_u16() throws -> UInt16 {
let bytes = try readBytes(count: 2)
var x = UInt16(bytes[0])
x += UInt16(bytes[1]) << 8
return x
}
public func deserialize_u32() throws -> UInt32 {
let bytes = try readBytes(count: 4)
var x = UInt32(bytes[0])
x += UInt32(bytes[1]) << 8
x += UInt32(bytes[2]) << 16
x += UInt32(bytes[3]) << 24
return x
}
public func deserialize_u64() throws -> UInt64 {
let bytes = try readBytes(count: 8)
var x = UInt64(bytes[0])
x += UInt64(bytes[1]) << 8
x += UInt64(bytes[2]) << 16
x += UInt64(bytes[3]) << 24
x += UInt64(bytes[4]) << 32
x += UInt64(bytes[5]) << 40
x += UInt64(bytes[6]) << 48
x += UInt64(bytes[7]) << 56
return x
}
public func deserialize_u128() throws -> UInt128 {
let low = try deserialize_u64()
let high = try deserialize_u64()
return UInt128(high: high, low: low)
}
public func deserialize_i8() throws -> Int8 {
return Int8(bitPattern: try deserialize_u8())
}
public func deserialize_i16() throws -> Int16 {
return Int16(bitPattern: try deserialize_u16())
}
public func deserialize_i32() throws -> Int32 {
return Int32(bitPattern: try deserialize_u32())
}
public func deserialize_i64() throws -> Int64 {
return Int64(bitPattern: try deserialize_u64())
}
public func deserialize_i128() throws -> Int128 {
let low = try deserialize_u64()
let high = try deserialize_i64()
return Int128(high: high, low: low)
}
public func deserialize_option_tag() throws -> Bool {
let value = try deserialize_u8()
switch value {
case 0: return false
case 1: return true
default: throw DeserializationError.invalidInput(issue: "Incorrect value for option tag: \(value)")
}
}
public func get_buffer_offset() -> Int {
return location
}
public func check_that_key_slices_are_increasing(key1 _: Slice, key2 _: Slice) throws {
assertionFailure("Not implemented")
}
}