Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 变量字节编码方法在Swift中不起作用_Ios_Swift_Macos - Fatal编程技术网

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

Ios 变量字节编码方法在Swift中不起作用,ios,swift,macos,Ios,Swift,Macos,我正在尝试详细地读取mapsforge.map文件,但似乎无法使变量字节编码部分正常工作。只要没有第二个字节(因此数字很小),我的实现就可以工作,但是当数字被编码成2个或更多字节时,我的函数就无法正确解码。我想知道是否有人能帮我解决我做错了什么 类实现: final class MapFileInputSerializer { private let _0x7full: UInt64 = 0x7f private let _0x3full: UInt64 = 0x3f p

我正在尝试详细地读取mapsforge.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 readVarUInt64()抛出->UInt64{
变量值:UInt64=0
变量移位:UInt=0
虽然是真的{
guard let byteData=try?fileHandle.read(upToCount:1)else{fatalError()}
让byteValue=UInt8(bigEndian:byteData.withUnsafeBytes{$0.load(as:UInt8.self)})
值|=(UInt64(字节值)和0x7full)63{throw Error.tooLongUInt64}
}
返回值
}
这是有符号整数的func:

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
}
func readVarInt64()->Int64{
变量值:Int64=0
变量移位:UInt=0
var字节值:UInt8=UInt8()
虽然是真的{
guard let byteData=try?fileHandle.read(upToCount:1)else{fatalError()}
byteValue=UInt8(bigEndian:byteData.withUnsafeBytes{$0.load(as:UInt8.self)})
如果字节值&0x80==0{break}//128处的0表示这是最后一个字节

值|=Int64((UInt64(字节值)和0x7full)结果证明我的函数很好。我的代码中的其他地方有一个bug。由于没有关于如何在Swift中进行变量字节编码的StackOverflow的其他问题,所以我不会删除这个问题-可能会对以后的人有所帮助。

你真的需要逐字节读取吗?每个MapFileInputSerializer的字节数不是恒定的吗您发布的字节序列失败了吗?顺便说一句,如果您只读取一个字节
read(upToCount:1)
为什么需要
byteData.withUnsafeBytes{$0.load(as:UInt8.self)
?为什么不直接获取
数据的第一个字节
呢?
guard let byte=try?fileHandle.read(upToCount:1).first
为什么在单个字节上需要bigEndian初始化器?@LeoDabus我可以读取不同的.map文件。它们有不同的字节数,是的。我需要逐字节读取,因为这种文件格式是逐字节编码的。我需要逐字节解码。如果你查看链接,你可以看到每个字节都以给定的顺序表示某些内容。该文件大小为150MBs。我无法发布所有这些字节。:)但它确实在mapsforge渲染器应用程序中工作,因此不会损坏。关于第二个问题,是的,我可以改进这一行,但有时我需要读取Int64 Int32等。我只是复制了它(我一次读取了8、4等字节)