Skip to content

Commit

Permalink
Add enums for compression, memory level and window bits (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
adam-fowler authored Nov 18, 2024
1 parent 9dedf2c commit 459a803
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 8 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
/*.xcodeproj
xcuserdata/
Package.resolved
/.devcontainer
69 changes: 67 additions & 2 deletions Sources/CompressNIO/zlib/Zlib.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,52 @@ public enum ZlibAlgorithm: Sendable {

/// Zlib library configuration
public struct ZlibConfiguration: Sendable {
/// Compression Level. Lower the value is the faster the compression, higher the value is
/// better the compression
public enum CompressionLevel: Int32 {
case noCompression = 0
case fastestCompression = 1
case compressionLevel2 = 2
case compressionLevel3 = 3
case compressionLevel4 = 4
case compressionLevel5 = 5
case compressionLevel6 = 6
case compressionLevel7 = 7
case compressionLevel8 = 8
case bestCompression = 9
case defaultCompressionLevel = -1
}

/// How much memory is allocated for internal compression state, the smaller the amount
/// of memory the slower compression is. Memory allocated is (1 << (memLevel+9))
public enum MemoryLevel: Int32 {
case memory1k = 1
case memory2K = 2
case memory4K = 3
case memory8K = 4
case memory16K = 5
case memory32K = 6
case memory64K = 7
case memory128K = 8
case memory256K = 9

public static var defaultMemoryLevel: Self { .memory128K }
}

/// How much memory is allocated for the compression/history window. Larger sizes produce
/// better compression. Buffer size is (1 << (windowBits+2))
public enum WindowSize: Int32 {
case window2k = 9
case window4k = 10
case window8k = 11
case window16k = 12
case window32k = 13
case window64k = 14
case window128k = 15

public static var defaultWindowSize: Self { .window128k }
}

/// Compression Strategy
public enum Strategy: Sendable {
/// default compression strategy
Expand Down Expand Up @@ -54,12 +100,13 @@ public struct ZlibConfiguration: Sendable {

/// Initialise ZlibConfiguration
/// - Parameters:
/// - windowSize: Base two logarithm of the window size. eg 9 is 512, 10 is 1024
/// - windowSize: Base two logarithm of the window size. eg 9 is 2048, 10 is 4096
/// - compressionLevel: Level of compression. Value between 0 and 9 where 1 is fastest, 9 is best compression and
/// 0 is no compression
/// - memoryLevel: Amount of memory to use when compressing. Less memory will mean the compression will take longer
/// and compression level will be reduced. Value between 1 - 9 where 1 is least amount of memory.
/// - strategy: Strategy when compressing
@_disfavoredOverload
public init(windowSize: Int32 = 15, compressionLevel: Int32 = Z_DEFAULT_COMPRESSION, memoryLevel: Int32 = 8, strategy: Strategy = .default) {
assert((9...15).contains(windowSize), "Window size must be between the values 9 and 15")
assert((-1...9).contains(compressionLevel), "Compression level must be between the values 0 and 9, or -1 indicating the default value")
Expand All @@ -69,6 +116,24 @@ public struct ZlibConfiguration: Sendable {
self.memoryLevel = memoryLevel
self.strategy = strategy
}

/// Initialise ZlibConfiguration
/// - Parameters:
/// - windowSize: Size of compression/history window
/// - compressionLevel: Level of compression
/// - memoryLevel: Amount of memory used for compression state
/// - strategy: Strategy when compressing
public init(
windowSize: WindowSize = .defaultWindowSize,
compressionLevel: CompressionLevel = .defaultCompressionLevel,
memoryLevel: MemoryLevel = .defaultMemoryLevel,
strategy: Strategy = .default
) {
self.windowSize = windowSize.rawValue
self.compressionLevel = compressionLevel.rawValue
self.memoryLevel = memoryLevel.rawValue
self.strategy = strategy
}
}

/// Compressor using Zlib
Expand Down Expand Up @@ -294,7 +359,7 @@ public final class ZlibDecompressor {
}
}

/// Reset Zlib inflate stream
/// Reset Zlib inflate stream
/// - Throws: ``CompressNIOError`` if reset fails
public func reset() throws {
// inflateReset is a more optimal than calling finish and then start
Expand Down
12 changes: 6 additions & 6 deletions Tests/CompressNIOTests/ZlibCompressTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -282,18 +282,18 @@ class CompressZlibTests: XCTestCase {
}

func testWindowSize() throws {
try self.testCompressionAlgorithm(.gzip, configuration: .init(windowSize: 9))
try self.testCompressionAlgorithm(.deflate, configuration: .init(windowSize: 12))
try self.testCompressionAlgorithm(.gzip, configuration: .init(windowSize: .window2k))
try self.testCompressionAlgorithm(.deflate, configuration: .init(windowSize: .window16k))
}

func testCompressionLevel() throws {
try self.testCompressionAlgorithm(.gzip, configuration: .init(compressionLevel: 4))
try self.testCompressionAlgorithm(.deflate, configuration: .init(compressionLevel: 9))
try self.testCompressionAlgorithm(.gzip, configuration: .init(compressionLevel: .compressionLevel4))
try self.testCompressionAlgorithm(.deflate, configuration: .init(compressionLevel: .bestCompression))
}

func testMemoryLevel() throws {
try self.testCompressionAlgorithm(.gzip, configuration: .init(memoryLevel: 2))
try self.testCompressionAlgorithm(.deflate, configuration: .init(memoryLevel: 9))
try self.testCompressionAlgorithm(.gzip, configuration: .init(memoryLevel: .memory2K))
try self.testCompressionAlgorithm(.deflate, configuration: .init(memoryLevel: .memory256K))
}

func testDecompressWithInputBufferError() throws {
Expand Down

0 comments on commit 459a803

Please sign in to comment.