Is there a practical way to compress NSData?

后端 未结 7 1917
感情败类
感情败类 2020-12-14 11:40

I haven\'t seen any documentation on the topic, but that doesn\'t mean it doesn\'t exist.

7条回答
  •  借酒劲吻你
    2020-12-14 12:10

    Starting with iOS 9.0, there is built-in support for a few more compression algorithms. The library is called libcompression and supports LZ4, LZMA, ZLIB and LZFSE.

    Here’s a Swift example of using libcompression to decompress LZMA. It’s verbose, but avoids external dependencies and could be hidden in an extension on NSData.

    import Compression
    
    let streamPtr = UnsafeMutablePointer.alloc(1)
    var stream = streamPtr.memory
    var status: compression_status
    
    status = compression_stream_init(&stream, COMPRESSION_STREAM_DECODE, COMPRESSION_LZMA)
    stream.src_ptr = UnsafePointer(compressedData.bytes)
    stream.src_size = compressedData.length
    
    let dstBufferSize: size_t = 4096
    let dstBufferPtr = UnsafeMutablePointer.alloc(dstBufferSize)
    stream.dst_ptr = dstBufferPtr
    stream.dst_size = dstBufferSize
    
    let decompressedData = NSMutableData()
    
    repeat {
        status = compression_stream_process(&stream, 0)
        switch status {
        case COMPRESSION_STATUS_OK:
            if stream.dst_size == 0 {
                decompressedData.appendBytes(dstBufferPtr, length: dstBufferSize)
                stream.dst_ptr = dstBufferPtr
                stream.dst_size = dstBufferSize
            }
        case COMPRESSION_STATUS_END:
            if stream.dst_ptr > dstBufferPtr {
                decompressedData.appendBytes(dstBufferPtr, length: stream.dst_ptr - dstBufferPtr)
            }
        default:
            break
        }
    }
    while status == COMPRESSION_STATUS_OK
    
    compression_stream_destroy(&stream)
    
    if status == COMPRESSION_STATUS_END {
        // Decompression succeeded, do something with decompressedData
    }
    else {
        // Decompression failed
    }
    

提交回复
热议问题