在 Swift2 中使用 iOS9 压缩框架

Using the iOS9 Compression Framework in Swift2

我有一些使用 DEFLATE 压缩协议存储的 NSData

DEFLATE Compression Method DEFLATE is a lossless compressed data format that compresses data using a combination of the LZ77 algorithm and Huffman coding, with efficiency comparable to the best currently available general-purpose compression methods. The data can be produced or consumed, even for an arbitrarily long sequentially presented input data stream, using only a priority-bounded amount of intermediate storage. The format can be implemented readily in a manner not covered by patents. Specifications for DEFLATE can be found in RFC 1951 - DEFLATE Compressed Data Format Specification, May 1996.

如果我在 IOS9 中理解正确,则有一个新的 Compression Framework "might" 可以处理这种情况。该文档列出了以下受支持的算法:LZFSE、LZ4、LZMA 和 ZLIB 级别 5。

我不确定,但我相信 ZLIB 支持 LZ77 Deflate 算法。我的问题是如何实际使用这个框架:

所以我相信我想使用的功能是compression_decode_buffer

@available(iOS 9.0, *)
public func compression_decode_buffer(
    dst_buffer: UnsafeMutablePointer<UInt8>, 
    _ dst_size: Int, 
    _ src_buffer: UnsafePointer<UInt8>, 
    _ src_size: Int, 
    _ scratch_buffer: UnsafeMutablePointer<Void>, 
    _ algorithm: compression_algorithm) -> Int

但我不确定如何使用这个算法。

所以从阅读 header 看来我需要一个输入大小 dst_size: bytes.sizeoutput size 一个 inputBuffer 一个 &outputbuffer 和一个 compression algorithm

dst_buffer: UnsafeMutablePointer, _ dst_size: 整数, _ src_buffer: 不安全指针, _ src_size: 整数, _ scratch_buffer: UnsafeMutablePointer, _ 算法:compression_algorithm) -> Int

假设我有一些示例数据(见下文)

let bytes : [UInt8] = [ .... ]  // see below

compression_decode_buffer(
  <DST_BUFFER>,
  <DST_SIZE>, 
  bytes, 
  bytes.count, 
  <SCRATCH_BUFFER>, 
  COMPRESSION_ZLIB
)

我不知所措的是 , , .

有什么建议吗?

示例数据

let bytes : [UInt8] = [0x7e, 0x07, 0x07, 0xff, 0xff, 0x41, /* <1~....A */
    0x10, 0x33, 0x51, 0x3e, 0x94, 0xb2, 0xa0, 0x27, /* .3Q>...' */
    0x80, 0x00, 0x21, 0x65, 0x26, 0xd8, 0x22, 0x10, /* ..!e&.". */
    0x2c, 0xd5, 0x99, 0x00, 0x00, 0x44, 0xbb, 0xd4, /* ,....D.. */
    0x54, 0x38, 0xf5, 0x01, 0x36, 0xd1, 0x20, 0x2c, /* T8..6. , */
    0xd5, 0x99, 0xbb, 0x1c, 0xaf, 0xc3, 0x2c, 0x60, /* ......,` */
    0xcb, 0x0c, 0x79, 0xcb, 0x76, 0xa0, 0x84, 0xd5, /* ..y.v... */
    0x99, 0x83, 0x1c, 0xaf, 0xc3, 0x2c, 0x60, 0x35, /* .....,`5 */
    0x66, 0x60, 0x49, 0x76, 0x60, 0xc7, 0x5b, 0xf3, /* f`Iv`.[. */
    0xce, 0x05, 0x08, 0x3a, 0x04, 0x13, 0x4a, 0x00, /* ...:..J. */
    0x92, 0x05, 0x08, 0x17, 0x14, 0x68, 0x31, 0xc3, /* .....h1. */
    0x1c, 0xb2, 0xc3, 0x1e, 0x72, 0xdd, 0xe0, 0x00, /* ....r... */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
    0x00, 0x00, 0x00, 0x00, 0x27, 0x00, 0x00, 0x00, /* ....'... */
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, /* .......0 */
    0x8e, 0x7e]

一般compression_decode_buffer()是这样使用的:

import Compression

let bytes : [UInt8] = [ .... ]  // Compressed data
var dst = [UInt8](count: 1000, repeatedValue: 0) // destination buffer
let size = compression_decode_buffer(&dst, dst.count, bytes, bytes.count, nil, COMPRESSION_ZLIB)

目标缓冲区必须足够大以容纳解压缩的数据。 在 return 上,size 是写入的字节数 目标缓冲区(如果解压失败则为零)。

(还有一个"streaming"接口

compression_stream_init()
compression_stream_process()
compression_stream_destroy()

可用于分块处理数据。)

但是,我尝试使用所有可用的方法解压缩您的数据 COMPRESSION_XXX 方法没有成功。

根据我的实验看来 COMPRESSION_ZLIB 对应 到 "raw deflate" 方法,即你用 zlib 得到的 如果设置了 windowBits 参数,则 deflateInit2() 函数 为负值。