Skip to content

Commit

Permalink
feat: new compression wrapper using LZFSE
Browse files Browse the repository at this point in the history
  • Loading branch information
adrien-coye committed Jun 5, 2023
1 parent f39617b commit 74b5563
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 0 deletions.
50 changes: 50 additions & 0 deletions Sources/InfomaniakCore/Extensions/Data+Compression.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/*
Infomaniak Core - iOS
Copyright (C) 2023 Infomaniak Network SA
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import Foundation

/// LZFSE Wrapper
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public extension Data {
/// Compressed data using a zstd like algorithm: lzfse
func compressed() -> Self? {
guard let data = try? (self as NSData).compressed(using: .lzfse) as Data else {
return nil
}
return data
}

/// Decompressed data from a lzfse buffer
func decompressed() -> Self? {
guard let data = try? (self as NSData).decompressed(using: .lzfse) as Data else {
return nil
}
return data
}

// MARK: - String helpers

/// Decompressed string from a lzfse buffer
func decompressedString() -> String? {
guard let decompressedData = decompressed() else {
return nil
}
let string = String(decoding: decompressedData, as: UTF8.self)
return string
}
}
35 changes: 35 additions & 0 deletions Sources/InfomaniakCore/Extensions/String+Compression.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
Infomaniak Core - iOS
Copyright (C) 2023 Infomaniak Network SA
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import Foundation

/// LZFSE Wrapper
@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
public extension String {
func compressed() -> Data? {
guard let data = data(using: .utf8),
let compressed = data.compressed() else {
return nil
}
return compressed
}

static func decompressed(from data: Data) -> Self? {
data.decompressedString()
}
}
54 changes: 54 additions & 0 deletions Tests/InfomaniakCoreTests/UTCompression.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
Infomaniak Core - iOS
Copyright (C) 2023 Infomaniak Network SA
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import InfomaniakCore
import XCTest

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
final class UTCompression: XCTestCase {
func testCompression() {
// GIVEN
let lowEntropy = "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
let lowEntropyData = lowEntropy.data(using: .utf8)!

// WHEN
guard let highEntropy = lowEntropy.compressed() else {
XCTFail("Unexpected")
return
}

// THEN
XCTAssertLessThan(highEntropy.count, lowEntropyData.count, "Compressed message should be smaller")
}

func testCompressionDecompression() {
// GIVEN
let lowEntropy = "eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"

// WHEN
guard let highEntropy = lowEntropy.compressed() else {
XCTFail("Unexpected")
return
}

let decompressedString = highEntropy.decompressedString()

// THEN
XCTAssertEqual(lowEntropy, decompressedString)
}
}

0 comments on commit 74b5563

Please sign in to comment.