Files
SWCompression/README.md
T

5.5 KiB

SWCompression

GitHub license Carthage compatible Build Status codecov

A framework which contains native (written in Swift) implementations of some compression algorithms.

Why have you made compression framework?

There are a couple of reasons for this.

The main reason is that it is very educational and somewhat fun.

Secondly, if you are a Swift developer and you want to compress/decompress something in your project you have to use either wrapper around system libraries (which is probably written in Objective-C) or you have to use built-in Compression framework. You might think that last option is what you need, but, frankly that framework has a bit complicated API and somewhat questionable choice of supported compression algorithms. And yes, it is also in Objective-C.

And here comes SWCompression: no Objective-C, pure Swift.

Features

  • (De)compression algorithms:
    • Deflate
    • BZip2
  • Archives:
    • GZip
    • Zlib
  • Platform independent.
  • Swift only

By the way, it seems like GZip and Deflate decompressor implementations are specification compliant.

Installation

SWCompression can be integrated into your project either using CocoaPods, Carthage or Swift Package Manager.

CocoaPods

Add to your Podfile pod 'SWCompression'.

Since 1.1.0 version of SWCompression there are several sub-podspecs if you need only parts of functionality of SWCompression. There are pod 'SWCompression/GZip', pod 'SWCompression/Zlib', pod 'SWCompression/Deflate' and pod 'SWCompression/BZip2' subspecs. You can add some or all of them instead of pod 'SWCompression'

Also, do not forget to have use_frameworks! line in the Podfile.

To complete installation, run pod install.

Note: Actually, there is one more subspec (SWCompression/Common) but it does not contain any end-user functions. This subspec is included in other subspecs such as SWCompression/GZip and should not be specified directly in Podfile.

Carthage

Add to your Cartfile github "tsolomko/SWCompression".

Then run carthage update.

Finally, drag and drop SWCompression.framework from Carthage/Build folder into the "Embedded Binaries" section on your targets' "General" tab.

Swift Package Manager

Add to you package dependecies .Package(url: "https://github.com/tsolomko/SWCompression.git"), for example like this:

import PackageDescription

let package = Package(
    name: "PackageName",
    dependencies: [
        .Package(url: "https://github.com/tsolomko/SWCompression.git", majorVersion: 1)
    ]
)

More info you may find at Swift Package Manager's Documentation.

Usage

If you'd like to decompress "deflated" data just use:

let data = try! Data(contentsOf: URL(fileURLWithPath: "path/to/file"),
                     options: .mappedIfSafe)
let decompressedData = try? Deflate.decompress(compressedData: data)

Note: It is highly recommended to specify Data.ReadingOptions.mappedIfSafe, especially if you are working with large files, so you don't run out of system memory.

However, it is unlikely that you will encounter deflated data outside of any archive. So, in case of GZip archive you should use:

let decompressedData = try? GzipArchive.unarchive(archiveData: data)

And, finally, for zlib the corresponding code is:

let decompressedData = try? ZlibArchive.unarchive(archiveData: data)

One final note: every unarchive/decompress function can throw an error and you are responsible for handling them.

Why is it so slow?

Is it?

Firstly, the problem is that if SWCompression is built with 'Debug' configuration for some reason the performance is really bad. However, if you use 'Release' configuration varoius optimizations start to take effect and decompression speed will be much better.

Secondly, slow performance might have a fundamental cause. A recent investigation showed that the most time consuming operations are memory copying operations. And there are a lot of them. So to achieve higher speed of decoding the amount of such operations should be significantly reduced. This might require reimplementation of some things (such as DataWithPointer), thus it is currently considered as a long-term project.

To sum up, it is highly recommended to build SWCompression with 'Release' configuration and, hopefully, some day SWCompression will become fast.

Future plans

  • LZMA decompression.
  • XZ decompression.
  • Performance improvement.
  • Tar unarchiving.
  • Deflate compression.
  • BZip2 compression.
  • Something else...

References

The main source of information was pyflate — python implementation of GZip and BZip2.

There are also several specifications which were also very useful: