├── Data+Compression.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcuserdata │ │ └── lee.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ └── lee.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── Data+Compression.xcscheme │ └── xcschememanagement.plist ├── Data+Compression └── Data+Compression.swift ├── Data+CompressionTests ├── Data+CompressionTests.swift ├── DummyApp │ ├── AppDelegate.swift │ ├── Base.lproj │ │ └── MainMenu.xib │ └── Info.plist └── Info.plist ├── LICENSE.txt ├── README.md └── TestData ├── TestData.lz4 ├── TestData.lzfse ├── TestData.lzma ├── TestData.txt └── TestData.zlib /Data+Compression.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 9B601AF11B5ACE9A008C2BDA /* Data+CompressionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B601AF01B5ACE9A008C2BDA /* Data+CompressionTests.swift */; }; 11 | 9B601AFE1B5ACEBD008C2BDA /* libcompression.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B601AFD1B5ACEBD008C2BDA /* libcompression.tbd */; }; 12 | 9B601B141B5ACF85008C2BDA /* Data+Compression.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B601B131B5ACF85008C2BDA /* Data+Compression.swift */; }; 13 | 9B601B151B5ACF85008C2BDA /* Data+Compression.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B601B131B5ACF85008C2BDA /* Data+Compression.swift */; }; 14 | 9B601B1B1B5ACF92008C2BDA /* TestData.lz4 in Resources */ = {isa = PBXBuildFile; fileRef = 9B601B161B5ACF92008C2BDA /* TestData.lz4 */; }; 15 | 9B601B1C1B5ACF92008C2BDA /* TestData.lz4 in Resources */ = {isa = PBXBuildFile; fileRef = 9B601B161B5ACF92008C2BDA /* TestData.lz4 */; }; 16 | 9B601B1D1B5ACF92008C2BDA /* TestData.lzfse in Resources */ = {isa = PBXBuildFile; fileRef = 9B601B171B5ACF92008C2BDA /* TestData.lzfse */; }; 17 | 9B601B1E1B5ACF92008C2BDA /* TestData.lzfse in Resources */ = {isa = PBXBuildFile; fileRef = 9B601B171B5ACF92008C2BDA /* TestData.lzfse */; }; 18 | 9B601B1F1B5ACF92008C2BDA /* TestData.lzma in Resources */ = {isa = PBXBuildFile; fileRef = 9B601B181B5ACF92008C2BDA /* TestData.lzma */; }; 19 | 9B601B201B5ACF92008C2BDA /* TestData.lzma in Resources */ = {isa = PBXBuildFile; fileRef = 9B601B181B5ACF92008C2BDA /* TestData.lzma */; }; 20 | 9B601B211B5ACF92008C2BDA /* TestData.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B601B191B5ACF92008C2BDA /* TestData.txt */; }; 21 | 9B601B221B5ACF92008C2BDA /* TestData.txt in Resources */ = {isa = PBXBuildFile; fileRef = 9B601B191B5ACF92008C2BDA /* TestData.txt */; }; 22 | 9B601B231B5ACF92008C2BDA /* TestData.zlib in Resources */ = {isa = PBXBuildFile; fileRef = 9B601B1A1B5ACF92008C2BDA /* TestData.zlib */; }; 23 | 9B601B241B5ACF92008C2BDA /* TestData.zlib in Resources */ = {isa = PBXBuildFile; fileRef = 9B601B1A1B5ACF92008C2BDA /* TestData.zlib */; }; 24 | 9B601B271B5AD09A008C2BDA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B601B251B5AD09A008C2BDA /* AppDelegate.swift */; }; 25 | 9B601B281B5AD09A008C2BDA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9B601B251B5AD09A008C2BDA /* AppDelegate.swift */; }; 26 | 9B601B2A1B5AD09A008C2BDA /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 9B601B261B5AD09A008C2BDA /* Info.plist */; }; 27 | 9B601B2D1B5AD0A1008C2BDA /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B601B2B1B5AD0A1008C2BDA /* MainMenu.xib */; }; 28 | 9B601B2E1B5AD0A1008C2BDA /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 9B601B2B1B5AD0A1008C2BDA /* MainMenu.xib */; }; 29 | 9B601B2F1B5AD135008C2BDA /* libcompression.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 9B601AFD1B5ACEBD008C2BDA /* libcompression.tbd */; }; 30 | /* End PBXBuildFile section */ 31 | 32 | /* Begin PBXContainerItemProxy section */ 33 | 9B601AED1B5ACE9A008C2BDA /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = 9B601AD51B5ACE9A008C2BDA /* Project object */; 36 | proxyType = 1; 37 | remoteGlobalIDString = 9B601ADC1B5ACE9A008C2BDA; 38 | remoteInfo = "Data+Compression"; 39 | }; 40 | /* End PBXContainerItemProxy section */ 41 | 42 | /* Begin PBXFileReference section */ 43 | 9B601ADD1B5ACE9A008C2BDA /* Data+Compression.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Data+Compression.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 9B601AEC1B5ACE9A008C2BDA /* Data+CompressionTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Data+CompressionTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 45 | 9B601AF01B5ACE9A008C2BDA /* Data+CompressionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Data+CompressionTests.swift"; sourceTree = ""; }; 46 | 9B601AF21B5ACE9A008C2BDA /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 47 | 9B601AFD1B5ACEBD008C2BDA /* libcompression.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcompression.tbd; path = usr/lib/libcompression.tbd; sourceTree = SDKROOT; }; 48 | 9B601B131B5ACF85008C2BDA /* Data+Compression.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Data+Compression.swift"; sourceTree = ""; }; 49 | 9B601B161B5ACF92008C2BDA /* TestData.lz4 */ = {isa = PBXFileReference; lastKnownFileType = file; name = TestData.lz4; path = TestData/TestData.lz4; sourceTree = ""; }; 50 | 9B601B171B5ACF92008C2BDA /* TestData.lzfse */ = {isa = PBXFileReference; lastKnownFileType = file; name = TestData.lzfse; path = TestData/TestData.lzfse; sourceTree = ""; }; 51 | 9B601B181B5ACF92008C2BDA /* TestData.lzma */ = {isa = PBXFileReference; lastKnownFileType = file; name = TestData.lzma; path = TestData/TestData.lzma; sourceTree = ""; }; 52 | 9B601B191B5ACF92008C2BDA /* TestData.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = TestData.txt; path = TestData/TestData.txt; sourceTree = ""; }; 53 | 9B601B1A1B5ACF92008C2BDA /* TestData.zlib */ = {isa = PBXFileReference; lastKnownFileType = file; name = TestData.zlib; path = TestData/TestData.zlib; sourceTree = ""; }; 54 | 9B601B251B5AD09A008C2BDA /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 55 | 9B601B261B5AD09A008C2BDA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 56 | 9B601B2C1B5AD0A1008C2BDA /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = "Data+CompressionTests/DummyApp/Base.lproj/MainMenu.xib"; sourceTree = SOURCE_ROOT; }; 57 | /* End PBXFileReference section */ 58 | 59 | /* Begin PBXFrameworksBuildPhase section */ 60 | 9B601ADA1B5ACE9A008C2BDA /* Frameworks */ = { 61 | isa = PBXFrameworksBuildPhase; 62 | buildActionMask = 2147483647; 63 | files = ( 64 | 9B601AFE1B5ACEBD008C2BDA /* libcompression.tbd in Frameworks */, 65 | ); 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | 9B601AE91B5ACE9A008C2BDA /* Frameworks */ = { 69 | isa = PBXFrameworksBuildPhase; 70 | buildActionMask = 2147483647; 71 | files = ( 72 | 9B601B2F1B5AD135008C2BDA /* libcompression.tbd in Frameworks */, 73 | ); 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | /* End PBXFrameworksBuildPhase section */ 77 | 78 | /* Begin PBXGroup section */ 79 | 9B601AD41B5ACE9A008C2BDA = { 80 | isa = PBXGroup; 81 | children = ( 82 | 9B601B0E1B5ACEE3008C2BDA /* Data+Compression */, 83 | 9B601AEF1B5ACE9A008C2BDA /* Data+CompressionTests */, 84 | 9B601ADE1B5ACE9A008C2BDA /* Products */, 85 | ); 86 | sourceTree = ""; 87 | }; 88 | 9B601ADE1B5ACE9A008C2BDA /* Products */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 9B601ADD1B5ACE9A008C2BDA /* Data+Compression.app */, 92 | 9B601AEC1B5ACE9A008C2BDA /* Data+CompressionTests.xctest */, 93 | ); 94 | name = Products; 95 | sourceTree = ""; 96 | }; 97 | 9B601ADF1B5ACE9A008C2BDA /* Dummy App */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | 9B601B251B5AD09A008C2BDA /* AppDelegate.swift */, 101 | 9B601B2B1B5AD0A1008C2BDA /* MainMenu.xib */, 102 | 9B601B261B5AD09A008C2BDA /* Info.plist */, 103 | ); 104 | name = "Dummy App"; 105 | path = DummyApp; 106 | sourceTree = ""; 107 | }; 108 | 9B601AEF1B5ACE9A008C2BDA /* Data+CompressionTests */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 9B601AF01B5ACE9A008C2BDA /* Data+CompressionTests.swift */, 112 | 9B601AFB1B5ACEA7008C2BDA /* TestData */, 113 | 9B601B121B5ACF04008C2BDA /* Supporting Files */, 114 | ); 115 | path = "Data+CompressionTests"; 116 | sourceTree = ""; 117 | }; 118 | 9B601AFB1B5ACEA7008C2BDA /* TestData */ = { 119 | isa = PBXGroup; 120 | children = ( 121 | 9B601B191B5ACF92008C2BDA /* TestData.txt */, 122 | 9B601B161B5ACF92008C2BDA /* TestData.lz4 */, 123 | 9B601B1A1B5ACF92008C2BDA /* TestData.zlib */, 124 | 9B601B181B5ACF92008C2BDA /* TestData.lzma */, 125 | 9B601B171B5ACF92008C2BDA /* TestData.lzfse */, 126 | ); 127 | name = TestData; 128 | path = ..; 129 | sourceTree = ""; 130 | }; 131 | 9B601AFC1B5ACEB0008C2BDA /* Frameworks */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 9B601AFD1B5ACEBD008C2BDA /* libcompression.tbd */, 135 | ); 136 | name = Frameworks; 137 | sourceTree = ""; 138 | }; 139 | 9B601B0E1B5ACEE3008C2BDA /* Data+Compression */ = { 140 | isa = PBXGroup; 141 | children = ( 142 | 9B601B131B5ACF85008C2BDA /* Data+Compression.swift */, 143 | 9B601AFC1B5ACEB0008C2BDA /* Frameworks */, 144 | ); 145 | path = "Data+Compression"; 146 | sourceTree = ""; 147 | }; 148 | 9B601B121B5ACF04008C2BDA /* Supporting Files */ = { 149 | isa = PBXGroup; 150 | children = ( 151 | 9B601ADF1B5ACE9A008C2BDA /* Dummy App */, 152 | 9B601AF21B5ACE9A008C2BDA /* Info.plist */, 153 | ); 154 | name = "Supporting Files"; 155 | sourceTree = ""; 156 | }; 157 | /* End PBXGroup section */ 158 | 159 | /* Begin PBXNativeTarget section */ 160 | 9B601ADC1B5ACE9A008C2BDA /* Data+Compression */ = { 161 | isa = PBXNativeTarget; 162 | buildConfigurationList = 9B601AF51B5ACE9A008C2BDA /* Build configuration list for PBXNativeTarget "Data+Compression" */; 163 | buildPhases = ( 164 | 9B601AD91B5ACE9A008C2BDA /* Sources */, 165 | 9B601ADA1B5ACE9A008C2BDA /* Frameworks */, 166 | 9B601ADB1B5ACE9A008C2BDA /* Resources */, 167 | ); 168 | buildRules = ( 169 | ); 170 | dependencies = ( 171 | ); 172 | name = "Data+Compression"; 173 | productName = "Data+Compression"; 174 | productReference = 9B601ADD1B5ACE9A008C2BDA /* Data+Compression.app */; 175 | productType = "com.apple.product-type.application"; 176 | }; 177 | 9B601AEB1B5ACE9A008C2BDA /* Data+CompressionTests */ = { 178 | isa = PBXNativeTarget; 179 | buildConfigurationList = 9B601AF81B5ACE9A008C2BDA /* Build configuration list for PBXNativeTarget "Data+CompressionTests" */; 180 | buildPhases = ( 181 | 9B601AE81B5ACE9A008C2BDA /* Sources */, 182 | 9B601AE91B5ACE9A008C2BDA /* Frameworks */, 183 | 9B601AEA1B5ACE9A008C2BDA /* Resources */, 184 | ); 185 | buildRules = ( 186 | ); 187 | dependencies = ( 188 | 9B601AEE1B5ACE9A008C2BDA /* PBXTargetDependency */, 189 | ); 190 | name = "Data+CompressionTests"; 191 | productName = "Data+CompressionTests"; 192 | productReference = 9B601AEC1B5ACE9A008C2BDA /* Data+CompressionTests.xctest */; 193 | productType = "com.apple.product-type.bundle.unit-test"; 194 | }; 195 | /* End PBXNativeTarget section */ 196 | 197 | /* Begin PBXProject section */ 198 | 9B601AD51B5ACE9A008C2BDA /* Project object */ = { 199 | isa = PBXProject; 200 | attributes = { 201 | LastUpgradeCheck = 0800; 202 | ORGANIZATIONNAME = "Lee Morgan"; 203 | TargetAttributes = { 204 | 9B601ADC1B5ACE9A008C2BDA = { 205 | CreatedOnToolsVersion = 7.0; 206 | LastSwiftMigration = 0800; 207 | }; 208 | 9B601AEB1B5ACE9A008C2BDA = { 209 | CreatedOnToolsVersion = 7.0; 210 | LastSwiftMigration = 0800; 211 | TestTargetID = 9B601ADC1B5ACE9A008C2BDA; 212 | }; 213 | }; 214 | }; 215 | buildConfigurationList = 9B601AD81B5ACE9A008C2BDA /* Build configuration list for PBXProject "Data+Compression" */; 216 | compatibilityVersion = "Xcode 3.2"; 217 | developmentRegion = English; 218 | hasScannedForEncodings = 0; 219 | knownRegions = ( 220 | en, 221 | Base, 222 | ); 223 | mainGroup = 9B601AD41B5ACE9A008C2BDA; 224 | productRefGroup = 9B601ADE1B5ACE9A008C2BDA /* Products */; 225 | projectDirPath = ""; 226 | projectRoot = ""; 227 | targets = ( 228 | 9B601ADC1B5ACE9A008C2BDA /* Data+Compression */, 229 | 9B601AEB1B5ACE9A008C2BDA /* Data+CompressionTests */, 230 | ); 231 | }; 232 | /* End PBXProject section */ 233 | 234 | /* Begin PBXResourcesBuildPhase section */ 235 | 9B601ADB1B5ACE9A008C2BDA /* Resources */ = { 236 | isa = PBXResourcesBuildPhase; 237 | buildActionMask = 2147483647; 238 | files = ( 239 | 9B601B1B1B5ACF92008C2BDA /* TestData.lz4 in Resources */, 240 | 9B601B211B5ACF92008C2BDA /* TestData.txt in Resources */, 241 | 9B601B1F1B5ACF92008C2BDA /* TestData.lzma in Resources */, 242 | 9B601B231B5ACF92008C2BDA /* TestData.zlib in Resources */, 243 | 9B601B1D1B5ACF92008C2BDA /* TestData.lzfse in Resources */, 244 | 9B601B2D1B5AD0A1008C2BDA /* MainMenu.xib in Resources */, 245 | ); 246 | runOnlyForDeploymentPostprocessing = 0; 247 | }; 248 | 9B601AEA1B5ACE9A008C2BDA /* Resources */ = { 249 | isa = PBXResourcesBuildPhase; 250 | buildActionMask = 2147483647; 251 | files = ( 252 | 9B601B221B5ACF92008C2BDA /* TestData.txt in Resources */, 253 | 9B601B1E1B5ACF92008C2BDA /* TestData.lzfse in Resources */, 254 | 9B601B2A1B5AD09A008C2BDA /* Info.plist in Resources */, 255 | 9B601B201B5ACF92008C2BDA /* TestData.lzma in Resources */, 256 | 9B601B241B5ACF92008C2BDA /* TestData.zlib in Resources */, 257 | 9B601B2E1B5AD0A1008C2BDA /* MainMenu.xib in Resources */, 258 | 9B601B1C1B5ACF92008C2BDA /* TestData.lz4 in Resources */, 259 | ); 260 | runOnlyForDeploymentPostprocessing = 0; 261 | }; 262 | /* End PBXResourcesBuildPhase section */ 263 | 264 | /* Begin PBXSourcesBuildPhase section */ 265 | 9B601AD91B5ACE9A008C2BDA /* Sources */ = { 266 | isa = PBXSourcesBuildPhase; 267 | buildActionMask = 2147483647; 268 | files = ( 269 | 9B601B271B5AD09A008C2BDA /* AppDelegate.swift in Sources */, 270 | 9B601B141B5ACF85008C2BDA /* Data+Compression.swift in Sources */, 271 | ); 272 | runOnlyForDeploymentPostprocessing = 0; 273 | }; 274 | 9B601AE81B5ACE9A008C2BDA /* Sources */ = { 275 | isa = PBXSourcesBuildPhase; 276 | buildActionMask = 2147483647; 277 | files = ( 278 | 9B601B281B5AD09A008C2BDA /* AppDelegate.swift in Sources */, 279 | 9B601AF11B5ACE9A008C2BDA /* Data+CompressionTests.swift in Sources */, 280 | 9B601B151B5ACF85008C2BDA /* Data+Compression.swift in Sources */, 281 | ); 282 | runOnlyForDeploymentPostprocessing = 0; 283 | }; 284 | /* End PBXSourcesBuildPhase section */ 285 | 286 | /* Begin PBXTargetDependency section */ 287 | 9B601AEE1B5ACE9A008C2BDA /* PBXTargetDependency */ = { 288 | isa = PBXTargetDependency; 289 | target = 9B601ADC1B5ACE9A008C2BDA /* Data+Compression */; 290 | targetProxy = 9B601AED1B5ACE9A008C2BDA /* PBXContainerItemProxy */; 291 | }; 292 | /* End PBXTargetDependency section */ 293 | 294 | /* Begin PBXVariantGroup section */ 295 | 9B601B2B1B5AD0A1008C2BDA /* MainMenu.xib */ = { 296 | isa = PBXVariantGroup; 297 | children = ( 298 | 9B601B2C1B5AD0A1008C2BDA /* Base */, 299 | ); 300 | name = MainMenu.xib; 301 | sourceTree = ""; 302 | }; 303 | /* End PBXVariantGroup section */ 304 | 305 | /* Begin XCBuildConfiguration section */ 306 | 9B601AF31B5ACE9A008C2BDA /* Debug */ = { 307 | isa = XCBuildConfiguration; 308 | buildSettings = { 309 | ALWAYS_SEARCH_USER_PATHS = NO; 310 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 311 | CLANG_CXX_LIBRARY = "libc++"; 312 | CLANG_ENABLE_MODULES = YES; 313 | CLANG_ENABLE_OBJC_ARC = YES; 314 | CLANG_WARN_BOOL_CONVERSION = YES; 315 | CLANG_WARN_CONSTANT_CONVERSION = YES; 316 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 317 | CLANG_WARN_EMPTY_BODY = YES; 318 | CLANG_WARN_ENUM_CONVERSION = YES; 319 | CLANG_WARN_INFINITE_RECURSION = YES; 320 | CLANG_WARN_INT_CONVERSION = YES; 321 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 322 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 323 | CLANG_WARN_UNREACHABLE_CODE = YES; 324 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 325 | CODE_SIGN_IDENTITY = "-"; 326 | COPY_PHASE_STRIP = NO; 327 | DEBUG_INFORMATION_FORMAT = dwarf; 328 | ENABLE_STRICT_OBJC_MSGSEND = YES; 329 | ENABLE_TESTABILITY = YES; 330 | GCC_C_LANGUAGE_STANDARD = gnu99; 331 | GCC_DYNAMIC_NO_PIC = NO; 332 | GCC_NO_COMMON_BLOCKS = YES; 333 | GCC_OPTIMIZATION_LEVEL = 0; 334 | GCC_PREPROCESSOR_DEFINITIONS = ( 335 | "DEBUG=1", 336 | "$(inherited)", 337 | ); 338 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 339 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 340 | GCC_WARN_UNDECLARED_SELECTOR = YES; 341 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 342 | GCC_WARN_UNUSED_FUNCTION = YES; 343 | GCC_WARN_UNUSED_VARIABLE = YES; 344 | MACOSX_DEPLOYMENT_TARGET = 10.11; 345 | MTL_ENABLE_DEBUG_INFO = YES; 346 | ONLY_ACTIVE_ARCH = YES; 347 | SDKROOT = macosx; 348 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 349 | }; 350 | name = Debug; 351 | }; 352 | 9B601AF41B5ACE9A008C2BDA /* Release */ = { 353 | isa = XCBuildConfiguration; 354 | buildSettings = { 355 | ALWAYS_SEARCH_USER_PATHS = NO; 356 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 357 | CLANG_CXX_LIBRARY = "libc++"; 358 | CLANG_ENABLE_MODULES = YES; 359 | CLANG_ENABLE_OBJC_ARC = YES; 360 | CLANG_WARN_BOOL_CONVERSION = YES; 361 | CLANG_WARN_CONSTANT_CONVERSION = YES; 362 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 363 | CLANG_WARN_EMPTY_BODY = YES; 364 | CLANG_WARN_ENUM_CONVERSION = YES; 365 | CLANG_WARN_INFINITE_RECURSION = YES; 366 | CLANG_WARN_INT_CONVERSION = YES; 367 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 368 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 369 | CLANG_WARN_UNREACHABLE_CODE = YES; 370 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 371 | CODE_SIGN_IDENTITY = "-"; 372 | COPY_PHASE_STRIP = NO; 373 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 374 | ENABLE_NS_ASSERTIONS = NO; 375 | ENABLE_STRICT_OBJC_MSGSEND = YES; 376 | GCC_C_LANGUAGE_STANDARD = gnu99; 377 | GCC_NO_COMMON_BLOCKS = YES; 378 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 379 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 380 | GCC_WARN_UNDECLARED_SELECTOR = YES; 381 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 382 | GCC_WARN_UNUSED_FUNCTION = YES; 383 | GCC_WARN_UNUSED_VARIABLE = YES; 384 | MACOSX_DEPLOYMENT_TARGET = 10.11; 385 | MTL_ENABLE_DEBUG_INFO = NO; 386 | SDKROOT = macosx; 387 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 388 | }; 389 | name = Release; 390 | }; 391 | 9B601AF61B5ACE9A008C2BDA /* Debug */ = { 392 | isa = XCBuildConfiguration; 393 | buildSettings = { 394 | COMBINE_HIDPI_IMAGES = YES; 395 | INFOPLIST_FILE = "Data+CompressionTests/DummyApp/Info.plist"; 396 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 397 | PRODUCT_BUNDLE_IDENTIFIER = "leemorgan.Data-Compression"; 398 | PRODUCT_NAME = "$(TARGET_NAME)"; 399 | SWIFT_INCLUDE_PATHS = ""; 400 | SWIFT_VERSION = 3.0; 401 | }; 402 | name = Debug; 403 | }; 404 | 9B601AF71B5ACE9A008C2BDA /* Release */ = { 405 | isa = XCBuildConfiguration; 406 | buildSettings = { 407 | COMBINE_HIDPI_IMAGES = YES; 408 | INFOPLIST_FILE = "Data+CompressionTests/DummyApp/Info.plist"; 409 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; 410 | PRODUCT_BUNDLE_IDENTIFIER = "leemorgan.Data-Compression"; 411 | PRODUCT_NAME = "$(TARGET_NAME)"; 412 | SWIFT_INCLUDE_PATHS = ""; 413 | SWIFT_VERSION = 3.0; 414 | }; 415 | name = Release; 416 | }; 417 | 9B601AF91B5ACE9A008C2BDA /* Debug */ = { 418 | isa = XCBuildConfiguration; 419 | buildSettings = { 420 | BUNDLE_LOADER = "$(TEST_HOST)"; 421 | COMBINE_HIDPI_IMAGES = YES; 422 | INFOPLIST_FILE = "Data+CompressionTests/Info.plist"; 423 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 424 | PRODUCT_BUNDLE_IDENTIFIER = "leemorgan.Data-CompressionTests"; 425 | PRODUCT_NAME = "$(TARGET_NAME)"; 426 | SWIFT_VERSION = 3.0; 427 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Data+Compression.app/Contents/MacOS/Data+Compression"; 428 | }; 429 | name = Debug; 430 | }; 431 | 9B601AFA1B5ACE9A008C2BDA /* Release */ = { 432 | isa = XCBuildConfiguration; 433 | buildSettings = { 434 | BUNDLE_LOADER = "$(TEST_HOST)"; 435 | COMBINE_HIDPI_IMAGES = YES; 436 | INFOPLIST_FILE = "Data+CompressionTests/Info.plist"; 437 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 438 | PRODUCT_BUNDLE_IDENTIFIER = "leemorgan.Data-CompressionTests"; 439 | PRODUCT_NAME = "$(TARGET_NAME)"; 440 | SWIFT_VERSION = 3.0; 441 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Data+Compression.app/Contents/MacOS/Data+Compression"; 442 | }; 443 | name = Release; 444 | }; 445 | /* End XCBuildConfiguration section */ 446 | 447 | /* Begin XCConfigurationList section */ 448 | 9B601AD81B5ACE9A008C2BDA /* Build configuration list for PBXProject "Data+Compression" */ = { 449 | isa = XCConfigurationList; 450 | buildConfigurations = ( 451 | 9B601AF31B5ACE9A008C2BDA /* Debug */, 452 | 9B601AF41B5ACE9A008C2BDA /* Release */, 453 | ); 454 | defaultConfigurationIsVisible = 0; 455 | defaultConfigurationName = Release; 456 | }; 457 | 9B601AF51B5ACE9A008C2BDA /* Build configuration list for PBXNativeTarget "Data+Compression" */ = { 458 | isa = XCConfigurationList; 459 | buildConfigurations = ( 460 | 9B601AF61B5ACE9A008C2BDA /* Debug */, 461 | 9B601AF71B5ACE9A008C2BDA /* Release */, 462 | ); 463 | defaultConfigurationIsVisible = 0; 464 | defaultConfigurationName = Release; 465 | }; 466 | 9B601AF81B5ACE9A008C2BDA /* Build configuration list for PBXNativeTarget "Data+CompressionTests" */ = { 467 | isa = XCConfigurationList; 468 | buildConfigurations = ( 469 | 9B601AF91B5ACE9A008C2BDA /* Debug */, 470 | 9B601AFA1B5ACE9A008C2BDA /* Release */, 471 | ); 472 | defaultConfigurationIsVisible = 0; 473 | defaultConfigurationName = Release; 474 | }; 475 | /* End XCConfigurationList section */ 476 | }; 477 | rootObject = 9B601AD51B5ACE9A008C2BDA /* Project object */; 478 | } 479 | -------------------------------------------------------------------------------- /Data+Compression.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Data+Compression.xcodeproj/project.xcworkspace/xcuserdata/lee.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leemorgan/NSData-Compression/d01655121be22d8ff9e37feec2476859a7cd2348/Data+Compression.xcodeproj/project.xcworkspace/xcuserdata/lee.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Data+Compression.xcodeproj/xcuserdata/lee.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /Data+Compression.xcodeproj/xcuserdata/lee.xcuserdatad/xcschemes/Data+Compression.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Data+Compression.xcodeproj/xcuserdata/lee.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Data+Compression.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 9B601ADC1B5ACE9A008C2BDA 16 | 17 | primary 18 | 19 | 20 | 9B601AEB1B5ACE9A008C2BDA 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Data+Compression/Data+Compression.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Data+Compression.swift 3 | // Data+Compression 4 | // 5 | // Created by Lee Morgan on 7/17/15. 6 | // Copyright © 2015 Lee Morgan. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Compression 11 | 12 | /** Available Compression Algorithms 13 | 14 | - Compression.lz4 : Fast compression 15 | - Compression.zlib : Balanced between speed and compression 16 | - Compression.lzma : High compression 17 | - Compression.lzfse : Apple-specific high performance compression. Faster and better compression than ZLIB, but slower than LZ4 and does not compress as well as LZMA. 18 | */ 19 | enum Compression { 20 | 21 | /// Fast compression 22 | case lz4 23 | 24 | /// Balanced between speed and compression 25 | case zlib 26 | 27 | /// High compression 28 | case lzma 29 | 30 | /// Apple-specific high performance compression. Faster and better compression than ZLIB, but slower than LZ4 and does not compress as well as LZMA. 31 | case lzfse 32 | } 33 | 34 | extension Data { 35 | 36 | 37 | /// Returns a Data object initialized by decompressing the data from the file specified by `path`. Attempts to determine the appropriate decompression algorithm using the path's extension. 38 | /// 39 | /// This method is equivalent to `Data(contentsOfArchive:usingCompression:)` with `nil compression` 40 | /// 41 | /// let data = Data(contentsOfArchive: absolutePathToFile) 42 | /// 43 | /// - Parameter contentsOfArchive: The absolute path of the file from which to read data 44 | /// - Returns: A Data object initialized by decompressing the data from the file specified by `path`. Returns `nil` if decompression fails. 45 | init?(contentsOfArchive path: String) { 46 | self.init(contentsOfArchive: path, usedCompression: nil) 47 | } 48 | 49 | 50 | /// Returns a Data object initialized by decompressing the data from the file specified by `path` using the given `compression` algorithm. 51 | /// 52 | /// let data = Data(contentsOfArchive: absolutePathToFile, usedCompression: Compression.lzfse) 53 | /// 54 | /// - Parameter contentsOfArchive: The absolute path of the file from which to read data 55 | /// - Parameter usedCompression: Algorithm to use during decompression. If compression is nil, attempts to determine the appropriate decompression algorithm using the path's extension 56 | /// - Returns: A Data object initialized by decompressing the data from the file specified by `path` using the given `compression` algorithm. Returns `nil` if decompression fails. 57 | init?(contentsOfArchive path: String, usedCompression: Compression?) { 58 | let pathURL = URL(fileURLWithPath: path) 59 | 60 | // read in the compressed data from disk 61 | guard let compressedData = try? Data(contentsOf: pathURL) else { 62 | return nil 63 | } 64 | 65 | // if compression is set use it 66 | let compression: Compression 67 | if usedCompression != nil { 68 | compression = usedCompression! 69 | } 70 | else { 71 | // otherwise, attempt to use the file extension to determine the compression algorithm 72 | switch pathURL.pathExtension.lowercased() { 73 | case "lz4" : compression = Compression.lz4 74 | case "zlib" : compression = Compression.zlib 75 | case "lzma" : compression = Compression.lzma 76 | case "lzfse": compression = Compression.lzfse 77 | default: return nil 78 | } 79 | } 80 | 81 | // finally, attempt to uncompress the data and initalize self 82 | if let uncompressedData = compressedData.uncompressed(using: compression) { 83 | self = uncompressedData 84 | } 85 | else { 86 | return nil 87 | } 88 | } 89 | 90 | 91 | /// Returns a Data object created by compressing the receiver using the given compression algorithm. 92 | /// 93 | /// let compressedData = someData.compressed(using: Compression.lzfse) 94 | /// 95 | /// - Parameter using: Algorithm to use during compression 96 | /// - Returns: A Data object created by encoding the receiver's contents using the provided compression algorithm. Returns nil if compression fails or if the receiver's length is 0. 97 | func compressed(using compression: Compression) -> Data? { 98 | return self.data(using: compression, operation: .encode) 99 | } 100 | 101 | /// Returns a Data object by uncompressing the receiver using the given compression algorithm. 102 | /// 103 | /// let uncompressedData = someCompressedData.uncompressed(using: Compression.lzfse) 104 | /// 105 | /// - Parameter using: Algorithm to use during decompression 106 | /// - Returns: A Data object created by decoding the receiver's contents using the provided compression algorithm. Returns nil if decompression fails or if the receiver's length is 0. 107 | func uncompressed(using compression: Compression) -> Data? { 108 | return self.data(using: compression, operation: .decode) 109 | } 110 | 111 | 112 | private enum CompressionOperation { 113 | case encode 114 | case decode 115 | } 116 | 117 | private func data(using compression: Compression, operation: CompressionOperation) -> Data? { 118 | 119 | guard self.count > 0 else { 120 | return nil 121 | } 122 | 123 | let streamPtr = UnsafeMutablePointer.allocate(capacity: 1) 124 | var stream = streamPtr.pointee 125 | var status : compression_status 126 | var op : compression_stream_operation 127 | var flags : Int32 128 | var algorithm : compression_algorithm 129 | 130 | switch compression { 131 | case .lz4: 132 | algorithm = COMPRESSION_LZ4 133 | case .lzfse: 134 | algorithm = COMPRESSION_LZFSE 135 | case .lzma: 136 | algorithm = COMPRESSION_LZMA 137 | case .zlib: 138 | algorithm = COMPRESSION_ZLIB 139 | } 140 | 141 | switch operation { 142 | case .encode: 143 | op = COMPRESSION_STREAM_ENCODE 144 | flags = Int32(COMPRESSION_STREAM_FINALIZE.rawValue) 145 | case .decode: 146 | op = COMPRESSION_STREAM_DECODE 147 | flags = 0 148 | } 149 | 150 | status = compression_stream_init(&stream, op, algorithm) 151 | guard status != COMPRESSION_STATUS_ERROR else { 152 | // an error occurred 153 | return nil 154 | } 155 | 156 | let outputData = withUnsafeBytes { (bytes: UnsafePointer) -> Data? in 157 | // setup the stream's source 158 | stream.src_ptr = bytes 159 | stream.src_size = count 160 | 161 | // setup the stream's output buffer 162 | // we use a temporary buffer to store the data as it's compressed 163 | let dstBufferSize : size_t = 4096 164 | let dstBufferPtr = UnsafeMutablePointer.allocate(capacity: dstBufferSize) 165 | stream.dst_ptr = dstBufferPtr 166 | stream.dst_size = dstBufferSize 167 | // and we store the output in a mutable data object 168 | var outputData = Data() 169 | 170 | 171 | repeat { 172 | status = compression_stream_process(&stream, flags) 173 | 174 | switch status { 175 | case COMPRESSION_STATUS_OK: 176 | // Going to call _process at least once more, so prepare for that 177 | if stream.dst_size == 0 { 178 | // Output buffer full... 179 | 180 | // Write out to outputData 181 | outputData.append(dstBufferPtr, count: dstBufferSize) 182 | 183 | // Re-use dstBuffer 184 | stream.dst_ptr = dstBufferPtr 185 | stream.dst_size = dstBufferSize 186 | } 187 | 188 | case COMPRESSION_STATUS_END: 189 | // We are done, just write out the output buffer if there's anything in it 190 | if stream.dst_ptr > dstBufferPtr { 191 | outputData.append(dstBufferPtr, count: stream.dst_ptr - dstBufferPtr) 192 | } 193 | 194 | case COMPRESSION_STATUS_ERROR: 195 | return nil 196 | 197 | default: 198 | break 199 | } 200 | 201 | } while status == COMPRESSION_STATUS_OK 202 | 203 | return outputData 204 | } 205 | 206 | compression_stream_destroy(&stream) 207 | 208 | return outputData 209 | } 210 | 211 | } 212 | -------------------------------------------------------------------------------- /Data+CompressionTests/Data+CompressionTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Data+CompressionTests.swift 3 | // Data+CompressionTests 4 | // 5 | // Created by Lee Morgan on 7/18/15. 6 | // Copyright © 2015 Lee Morgan. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Data_Compression 11 | 12 | class Data_CompressionTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | 25 | /// init(contentsOfArchive: usedCompression:) tests 26 | func test_initContentsOfArchiveUsedCompression() { 27 | 28 | let verifiedData = testDataOfType("txt") 29 | guard let archivePath = Bundle.main.path(forResource: "TestData", ofType: "lzfse") else { 30 | assertionFailure("FATAL ERROR: Failed to get path to archive Test Data") 31 | exit(EXIT_FAILURE) 32 | } 33 | 34 | 35 | // Test explicit compression Data(contentsOfArchive: usedCompression:) 36 | let explicitData = Data(contentsOfArchive: archivePath, usedCompression: Compression.lzfse) 37 | XCTAssertEqual(explicitData!, verifiedData) 38 | 39 | // Test incorrect explicit compression 40 | let incorrectData = Data(contentsOfArchive: archivePath, usedCompression: Compression.lz4) 41 | XCTAssertNil(incorrectData) 42 | 43 | // Test implicit compression Data(contentsOfArchive:) 44 | let implicitData = Data(contentsOfArchive: archivePath) 45 | XCTAssertEqual(implicitData!, verifiedData) 46 | } 47 | 48 | 49 | /// uncompressedDataUsingCompression tests 50 | func test_uncompressedDataUsingCompression() { 51 | 52 | var compressedData : Data 53 | var uncompressedData : Data? 54 | let verifiedData = testDataOfType("txt") 55 | 56 | 57 | // Test LZ4 58 | compressedData = testDataOfType("lz4") 59 | uncompressedData = compressedData.uncompressed(using: Compression.lz4) 60 | XCTAssertEqual(uncompressedData!, verifiedData) 61 | 62 | // Test ZLIB 63 | compressedData = testDataOfType("zlib") 64 | uncompressedData = compressedData.uncompressed(using: Compression.zlib) 65 | XCTAssertEqual(uncompressedData!, verifiedData) 66 | 67 | // Test LZMA 68 | compressedData = testDataOfType("lzma") 69 | uncompressedData = compressedData.uncompressed(using: Compression.lzma) 70 | XCTAssertEqual(uncompressedData!, verifiedData) 71 | 72 | // Test LZFSE 73 | compressedData = testDataOfType("lzfse") 74 | uncompressedData = compressedData.uncompressed(using: Compression.lzfse) 75 | XCTAssertEqual(uncompressedData!, verifiedData) 76 | } 77 | 78 | 79 | /// compressedDataUsingCompression tests 80 | func test_compressedDataUsingCompression() { 81 | 82 | let uncompressedData = testDataOfType("txt") 83 | var compressedData : Data? 84 | var verifiedData : Data 85 | 86 | // Test LZ4 87 | compressedData = uncompressedData.compressed(using: Compression.lz4) 88 | verifiedData = testDataOfType("lz4") 89 | XCTAssertEqual(compressedData!, verifiedData) 90 | 91 | // Test ZLIB 92 | compressedData = uncompressedData.compressed(using: Compression.zlib) 93 | verifiedData = testDataOfType("zlib") 94 | XCTAssertEqual(compressedData!, verifiedData) 95 | 96 | // Test LZMA 97 | compressedData = uncompressedData.compressed(using: Compression.lzma) 98 | verifiedData = testDataOfType("lzma") 99 | XCTAssertEqual(compressedData!, verifiedData) 100 | 101 | // Test LZFSE 102 | compressedData = uncompressedData.compressed(using: Compression.lzfse) 103 | verifiedData = testDataOfType("lzfse") 104 | XCTAssertEqual(compressedData!, verifiedData) 105 | } 106 | 107 | 108 | /// Basic in memory Compression and Uncompression test 109 | func test_simpleStringCompression() { 110 | 111 | let testString = "Hello World" 112 | 113 | let encoding = String.Encoding.utf8 114 | 115 | guard let testStringData = testString.data(using: encoding) else { 116 | assertionFailure("FATAL ERROR: Failed convert string to data") 117 | exit(EXIT_FAILURE) 118 | } 119 | 120 | let compression = Compression.lzfse 121 | 122 | guard let compressedData = testStringData.compressed(using: compression) else { 123 | assertionFailure("FATAL ERROR: Failed to compress data") 124 | exit(EXIT_FAILURE) 125 | } 126 | 127 | guard let uncompressedData = compressedData.uncompressed(using: compression) else { 128 | assertionFailure("FATAL ERROR: Failed to uncompress data") 129 | exit(EXIT_FAILURE) 130 | } 131 | 132 | guard let uncompressedString = String(data: uncompressedData, encoding: encoding) else { 133 | assertionFailure("FATAL ERROR: Failed to convert to string") 134 | exit(EXIT_FAILURE) 135 | } 136 | 137 | print("\(testString) == \(uncompressedString)") 138 | XCTAssertEqual(uncompressedString, testString) 139 | } 140 | 141 | 142 | 143 | //-------------------------------------------------------- 144 | // Support Methods 145 | //-------------------------------------------------------- 146 | 147 | /// Test Support method 148 | func testDataOfType(_ type : String) -> Data { 149 | 150 | let bundle = Bundle.main 151 | 152 | guard let testDataPath = bundle.path(forResource: "TestData", ofType: type) else { 153 | assertionFailure("FATAL ERROR: Failed to load test data") 154 | exit(EXIT_FAILURE) 155 | } 156 | 157 | guard let testData = try? Data(contentsOf: URL(fileURLWithPath: testDataPath)) else { 158 | assertionFailure("FATAL ERROR: Failed to load test data") 159 | exit(EXIT_FAILURE) 160 | } 161 | 162 | // Verify Test Data isn't empty 163 | guard testData.count > 0 else { 164 | assertionFailure("FATAL ERROR: Test Data is empty") 165 | exit(EXIT_FAILURE) 166 | } 167 | 168 | return testData 169 | } 170 | 171 | } 172 | -------------------------------------------------------------------------------- /Data+CompressionTests/DummyApp/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Data+Compression 4 | // 5 | // Created by Lee Morgan on 7/18/15. 6 | // Copyright © 2015 Lee Morgan. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | @NSApplicationMain 12 | class AppDelegate: NSObject, NSApplicationDelegate { 13 | 14 | @IBOutlet weak var window: NSWindow! 15 | 16 | 17 | func applicationDidFinishLaunching(_ aNotification: Notification) { 18 | // Insert code here to initialize your application 19 | } 20 | 21 | func applicationWillTerminate(_ aNotification: Notification) { 22 | // Insert code here to tear down your application 23 | } 24 | 25 | 26 | } 27 | 28 | -------------------------------------------------------------------------------- /Data+CompressionTests/DummyApp/Base.lproj/MainMenu.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 311 | 312 | 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 325 | 326 | 327 | 328 | 329 | 330 | 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 339 | 340 | 341 | 342 | 343 | 344 | 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | 370 | 371 | 372 | 373 | 374 | 375 | 376 | 377 | 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 386 | 387 | 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 400 | 401 | 402 | 403 | 404 | 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 428 | 429 | 430 | 431 | 432 | 433 | 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 442 | 443 | 444 | 445 | 446 | 447 | 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 456 | 457 | 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | 473 | 474 | 475 | 476 | 477 | 478 | 479 | 480 | 481 | 482 | 483 | 484 | 485 | 486 | 487 | 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 498 | 499 | 500 | 501 | 502 | 503 | 504 | 505 | 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 534 | 535 | 536 | 537 | 538 | 539 | Default 540 | 541 | 542 | 543 | 544 | 545 | 546 | Left to Right 547 | 548 | 549 | 550 | 551 | 552 | 553 | Right to Left 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 563 | 564 | Default 565 | 566 | 567 | 568 | 569 | 570 | 571 | Left to Right 572 | 573 | 574 | 575 | 576 | 577 | 578 | Right to Left 579 | 580 | 581 | 582 | 583 | 584 | 585 | 586 | 587 | 588 | 589 | 590 | 591 | 592 | 593 | 594 | 595 | 596 | 597 | 598 | 599 | 600 | 601 | 602 | 603 | 604 | 605 | 606 | 607 | 608 | 609 | 610 | 611 | 612 | 613 | 614 | 615 | 616 | 617 | 618 | 619 | 620 | 621 | 622 | 623 | 624 | 625 | 626 | 627 | 628 | 629 | 630 | 631 | 632 | 633 | 634 | 635 | 636 | 637 | 638 | 639 | 640 | 641 | 642 | 643 | 644 | 645 | 646 | 647 | 648 | 649 | 650 | 651 | 652 | 653 | 654 | 655 | 656 | 657 | 658 | 659 | 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 668 | 669 | 670 | 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | 680 | 681 | 682 | -------------------------------------------------------------------------------- /Data+CompressionTests/DummyApp/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | NSHumanReadableCopyright 28 | Copyright © 2015 Lee Morgan. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /Data+CompressionTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Lee Morgan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Purpose 2 | ===== 3 | Compression is a set of extensions to Swift's Foundation Data type that provide data compression and decompression functionality by wrapping [libcompression](https://developer.apple.com/library/mac/documentation/Performance/Reference/Compression/), a new library available on OS 10.11 and iOS 9.0 4 | 5 | Compression is written in Swift. For the Objective-C version see [LAMCompression](https://github.com/leemorgan/NSData-LAMCompression). 6 | 7 | Installation 8 | ===== 9 | To use the Compression extensions in an app, include the `Data+Compression.swift` file in your project. 10 | 11 | You will also need to include the `libcompression` library in your project. 12 | 13 | Data Extensions 14 | ===== 15 | 16 | func compressed(using: Compression) -> Data? 17 | Returns a Data object created by compressing the receiver using the given compression algorithm. 18 | 19 |
20 | 21 | func uncompressed(using: Compression) -> Data? 22 | Returns a Data object by uncompressing the receiver using the given compression algorithm. 23 | 24 |
25 | 26 | init?(contentsOfArchive: String, usedCompression: Compression?) 27 | Returns a Data object initialized by decompressing the data from the file specified by `contentsOfArchive` using the given `usedCompression` algorithm. 28 | 29 |
30 | 31 | init?(contentsOfArchive: String) 32 | Returns a Data object initialized by decompressing the data from the file specified by `contentsOfArchive`. Attempts to determine the appropriate decompression algorithm using the path's extension. 33 | 34 | This method is equivalent to `Data(contentsOfArchive:usedCompression:)` with `nil usedCompression` 35 | 36 | Documentation 37 | ===== 38 | The `Data+Compression` extension is documented using standard Xcode doc comments. 39 | 40 | The project has a dummy (skeleton) app which is included to support Unit Testing with Xcode. The app itself doesn't do anything interesting at all. 41 | 42 | 43 | Supported OS & SDK Versions 44 | ===== 45 | Compression relies on CompressionLib which is only available in OS 10.11 and iOS 9.0 and later. 46 | 47 | 48 | Background Information 49 | ===== 50 | 51 | [Tinkering with CompressionLib](http://blog.shiftybit.net/tinkering-with-compressionlib/) 52 | 53 | [Tinkering with CompressionLib (Part 2)](http://blog.shiftybit.net/tinkering-with-compressionlib-part-2) 54 | 55 | [Tinkering with CompressionLib (Part 3)](http://blog.shiftybit.net/tinkering-with-compressionlib-part-3) 56 | 57 | By [Lee Morgan](http://shiftybit.net). If you find this useful please let me know. I'm [@leemorgan](https://twitter.com/leemorgan) on twitter. 58 | 59 | 60 | License 61 | ===== 62 | The license is contained in the "License.txt" file. 63 | 64 | -------------------------------------------------------------------------------- /TestData/TestData.lz4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leemorgan/NSData-Compression/d01655121be22d8ff9e37feec2476859a7cd2348/TestData/TestData.lz4 -------------------------------------------------------------------------------- /TestData/TestData.lzfse: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leemorgan/NSData-Compression/d01655121be22d8ff9e37feec2476859a7cd2348/TestData/TestData.lzfse -------------------------------------------------------------------------------- /TestData/TestData.lzma: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leemorgan/NSData-Compression/d01655121be22d8ff9e37feec2476859a7cd2348/TestData/TestData.lzma -------------------------------------------------------------------------------- /TestData/TestData.txt: -------------------------------------------------------------------------------- 1 | This file is used for Unit Testing. 2 | 3 | Thanks to Eric Bainville, Steve Canon, Luke Chang and the rest of Core OS: Vector and Numerics Group. 4 | 5 | 9$$ 6 | M$$$> 7 | '$$$$& 8 | $$$$$B 9 | $$$$$$$. 10 | :$$$$$$$$k 11 | $$$: X$$$$$$$$$N..:dN 12 | 9$$$$W @$$$$$$$$$$$$$$$> 13 | R$$$$$$W 'W$$$$$$$$$R```"R$$$N> 14 | R$$$$$$$$$b. d$$$$$$$$$$$$> . ^*$$k 15 | R$$$$$$$$$$$$u x$$$$****$$$$$$& 4$$N.'*$$L 16 | 4$$$$$$$$$$$$$$$$" '"*$$B '$$$$K.'R$K 17 | '$$$$$$$$$$$$R :@NW `$$x '#$$$$k `$B 18 | '$$$$$$$$$$~ X$$$$N '$N M$$E ?$N.uebc 19 | '$$$$$$$$> $$$$$$ Rk ' .W$$$$$$$$& 20 | M$$$$$$R '$$$$$$L #N x@$$$$$$$$$$$$> 21 | '$$$$$$~ $$$$L d$$$$$$$$$$$$$$$E 22 | 4$$$$$ 9$$$E W$$$$$$$$$$$$$$$$E 23 | '$$$$$> '#$" :$$$$$$$$$$$$$$$$$$$ 24 | 9$$$$B $$$$$$$$$$$$$$$$$$R 25 | X$$$$$$u d$"M$$$$$$$$$$$$$$$R 26 | "$$$$$$$$u d$# '$$$$$$$$$$$$$$" 27 | X$$$$$$$$$$$e.. ..ud$*" '$$$$$$$$$$$)..uoe@$$$ 28 | X$$$$$$$$$$$$$$$$$**F"~ '$$RF"""""~ 29 | 9$$$$$$$$$$$F`` W$&......x:. 30 | J$$$$$$$$$$" 9$$$****$$$$* 31 | '$$**$$$$$$ W$$ 32 | '$$$$& :$> d$$$$$$: 33 | :xd@$F"`#$$W: ##" d$$$$$$$$$$$$Wu. 34 | :d@$$$"" xW$$$$$$Wx> xuW$$$$$$$$$$$$$$$$$$$$$W> 35 | '$$$*" .d$$*" ""#*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 36 | xe$$*" .uoe$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$> 37 | :W$$*F x@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 38 | '` x@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$k 39 | :@$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$> 40 | $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$& 41 | $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 42 | "R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ : 43 | ?$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$E W$ 44 | '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$F :$$$ 45 | '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$E $$$$ 46 | `*$$R``#R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ :$$$$$ 47 | so$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$N :@$$$$$$ 48 | d$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$Nu. x$$$$$$$$$ 49 | '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 50 | X$$$$$$$$$$$$$"R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ 51 | .WWW@$$$$$$$$$$$$$E )$$$$$$$$$$$$*$$$$$$$$$$$$$$$$$$$$$$ 52 | .W$$$$$$$$$$$$$$$$$$$E $$$$$$$$$$$$$ #$$$$$$$$$$$$$$$$$$$$$ 53 | :$$$$$$$$$$$$$$$$$$$$$$::$$$$$$$$$$$$$k 'R$$$$$$$$$$$$$$$$$$R 54 | :$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$k: `R$$$$$$$$$$$$$$# 55 | "$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$k '"R$$$$$$$R"` 56 | M$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$> 57 | 'R$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$& 58 | `#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$E 59 | `#$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$R 60 | #$$$$$$$$$$$$$$$$$$$$$$$$$$$$$* 61 | "$$$$$$$$$$$$$$$$$$$$$$$" 62 | '`$$$$$$$$$$$$$$$*F"` -------------------------------------------------------------------------------- /TestData/TestData.zlib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leemorgan/NSData-Compression/d01655121be22d8ff9e37feec2476859a7cd2348/TestData/TestData.zlib --------------------------------------------------------------------------------