可变字节编码方法在Swift中不起作用



我正在尝试读取这里详细介绍的mapsfage.map文件,但我似乎无法使可变字节编码部分正常工作。只要没有第二个字节(所以数字很小(,我的实现就可以工作,但当数字被编码为2个或更多字节时,我的函数无法正确解码。我想知道是否有人能帮我解决我做错了什么。

类实现:

final class MapFileInputSerializer {
private let _0x7full: UInt64 = 0x7f
private let _0x3full: UInt64 = 0x3f
private let _0x3fll: Int64 = 0x3f
private let _0xffl: Int32 = 0xff

private var fileHandle: FileHandle
init(fileUrl: URL) throws {
let fh = try! FileHandle(forReadingFrom: fileUrl)
fileHandle = fh
}
[...]

当我知道这个数字是一个无符号整数时:

func readVarUInt64() throws -> UInt64 {
var value: UInt64 = 0
var shift: UInt = 0
while true {
guard let byteData = try? fileHandle.read(upToCount: 1) else { fatalError() }
let byteValue = UInt8(bigEndian: byteData.withUnsafeBytes { $0.load(as: UInt8.self) })
value |= (UInt64(byteValue) & _0x7full) << shift
shift += 7
if byteValue & 0x80 == 0 { break }
if shift > 63 { throw Error.tooLongUInt64 }
}
return value
}

这是我的有符号整数函数:

func readVarInt64() -> Int64 {
var value: Int64 = 0
var shift: UInt = 0
var byteValue: UInt8 = UInt8()
while true {
guard let byteData = try? fileHandle.read(upToCount: 1) else { fatalError() }
byteValue = UInt8(bigEndian: byteData.withUnsafeBytes { $0.load(as: UInt8.self) })
if byteValue & 0x80 == 0 { break } //0 at 128 means this is the last byte
value |= Int64((UInt64(byteValue) & _0x7full) << shift)
shift += 7
}
if byteValue & 0x40 != 0 { //0 at 64 means the number is positive, otherwise negative
value = -(value | Int64(((UInt64(byteValue) & _0x3full) << shift)))
} else {
value |= Int64((UInt64(byteValue) & _0x3full) << shift)
}
return value
}

我真的无法确定错误在哪里,因为我正在解码一个巨大的文件,我只是注意到当我试图将UInt64转换为Int64时,突然出现了溢出错误。调试建议也有帮助。:(

事实证明我的功能很好。我的代码中有一个错误。由于StackOverflow上没有其他关于如何在Swift中进行可变字节编码的问题,我不会删除这个问题——可能会对以后的人有所帮助。

最新更新