diff --git a/SWCompression.xcodeproj/project.pbxproj b/SWCompression.xcodeproj/project.pbxproj index d2e1175a..e5dff5ad 100644 --- a/SWCompression.xcodeproj/project.pbxproj +++ b/SWCompression.xcodeproj/project.pbxproj @@ -59,6 +59,7 @@ 06E63DB41DC3B8BD00D3A7C8 /* secondtest.txt in Resources */ = {isa = PBXBuildFile; fileRef = 06E63DB21DC3B8BD00D3A7C8 /* secondtest.txt */; }; 06E63DB51DC3B8BD00D3A7C8 /* secondtest.txt.gz in Resources */ = {isa = PBXBuildFile; fileRef = 06E63DB31DC3B8BD00D3A7C8 /* secondtest.txt.gz */; }; 06E961CA1DBD5FA1008C47F2 /* HuffmanTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06E961C91DBD5FA1008C47F2 /* HuffmanTable.swift */; }; + 06F27A6D1DCD1F8800A98168 /* DataWithPointerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F27A6C1DCD1F8800A98168 /* DataWithPointerTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -106,6 +107,7 @@ 06E63DB21DC3B8BD00D3A7C8 /* secondtest.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = secondtest.txt; sourceTree = ""; }; 06E63DB31DC3B8BD00D3A7C8 /* secondtest.txt.gz */ = {isa = PBXFileReference; lastKnownFileType = archive.gzip; path = secondtest.txt.gz; sourceTree = ""; }; 06E961C91DBD5FA1008C47F2 /* HuffmanTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HuffmanTable.swift; sourceTree = ""; }; + 06F27A6C1DCD1F8800A98168 /* DataWithPointerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataWithPointerTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -196,9 +198,9 @@ 064492581DC606D400F10981 /* ZlibArchive.swift */, 061FCE251DBCC4BE0052F7BE /* Deflate.swift */, 0661F0721DC92F98006C3D35 /* DataWithPointer.swift */, + 061FCE301DBCC8BF0052F7BE /* Extensions.swift */, 06E961C91DBD5FA1008C47F2 /* HuffmanTable.swift */, 06AC9B0C1DC1027900A5066B /* HuffmanLength.swift */, - 061FCE301DBCC8BF0052F7BE /* Extensions.swift */, 06BE1ACC1DB410F100EE0F59 /* Info.plist */, 065569611DC65B1B00A47E66 /* Info-iOS.plist */, 065569621DC65B1B00A47E66 /* Info-tvOS.plist */, @@ -213,6 +215,7 @@ children = ( 061FCE271DBCC6070052F7BE /* Test Files */, 06BE1AD61DB410F100EE0F59 /* SWCompressionTests.swift */, + 06F27A6C1DCD1F8800A98168 /* DataWithPointerTests.swift */, 0661F06E1DC92391006C3D35 /* PerformanceTests.swift */, 061FCE2C1DBCC6A30052F7BE /* Constants.swift */, 06BE1AD81DB410F100EE0F59 /* Info.plist */, @@ -525,6 +528,7 @@ 06BE1AD71DB410F100EE0F59 /* SWCompressionTests.swift in Sources */, 061FCE2D1DBCC6A30052F7BE /* Constants.swift in Sources */, 0661F06F1DC92391006C3D35 /* PerformanceTests.swift in Sources */, + 06F27A6D1DCD1F8800A98168 /* DataWithPointerTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Sources/DataWithPointer.swift b/Sources/DataWithPointer.swift new file mode 100644 index 00000000..9ff6ed3c --- /dev/null +++ b/Sources/DataWithPointer.swift @@ -0,0 +1,55 @@ +// +// DataWithPointer.swift +// SWCompression +// +// Created by Timofey Solomko on 01.11.16. +// Copyright © 2016 Timofey Solomko. All rights reserved. +// + +import Foundation +import CoreFoundation + +class DataWithPointer { + + /// Only needed for creation of bitVector in initData() + let data: Data + + private(set) var bitVector: CFBitVector? + private(set) var index: Int + private(set) var bitShift: Int + + init(data: Data) { + self.data = data + self.index = 0 + self.bitShift = 0 + self.bitVector = nil + initData() + } + + private func initData() { + data.withUnsafeBytes { (bytes: UnsafePointer) in + self.bitVector = CFBitVectorCreate(kCFAllocatorDefault, bytes, data.count * 8) + } + } + + func bits(count: Int) -> [UInt8] { + guard count > 0 else { return [] } + + /// Start point of bits to return + let startIndex = self.index * 8 + self.bitShift + /// Range of bits to return in bitVector + let range = CFRangeMake(startIndex, count) + + var array: [UInt8] = Array(repeating: 0, count: count) + CFBitVectorGetBits(self.bitVector!, range, &array) + + // Update index and bitShift + let amountOfBytes = (count - self.bitShift) / 8 + self.index += amountOfBytes + self.bitShift += count - 8 * amountOfBytes + + + return array + } + +} diff --git a/Tests/DataWithPointerTests.swift b/Tests/DataWithPointerTests.swift new file mode 100644 index 00000000..bf70ee91 --- /dev/null +++ b/Tests/DataWithPointerTests.swift @@ -0,0 +1,39 @@ +// +// DataWithPointerTests.swift +// SWCompression +// +// Created by Timofey Solomko on 04.11.16. +// Copyright © 2016 tsolomko. All rights reserved. +// + +import XCTest +@testable import SWCompression + +class DataWithPointerTests: XCTestCase { + + func testDataWithPointer() { + self.measure { + let testData = try? Data(contentsOf: Constants.relativelyBigFilePath) + XCTAssertNotNil(testData, "Failed to load test archive") + let testDataWithPointer = DataWithPointer(data: testData!) + for _ in 0..