├── .swift-version ├── .travis.yml ├── BinarySwift.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist ├── xcshareddata │ └── xcschemes │ │ ├── BinarySwiftTests_OSX.xcscheme │ │ ├── BinarySwiftTests_iOS.xcscheme │ │ ├── BinarySwift_OSX.xcscheme │ │ └── BinarySwift_iOS.xcscheme └── project.pbxproj ├── Package.swift ├── Sources └── BinarySwift │ ├── Common.swift │ ├── BinaryDataErrors.swift │ ├── IntegerType.swift │ ├── Tuple.swift │ ├── BinaryDataReader.swift │ └── BinaryData.swift ├── BinarySwift ├── BinarySwift_OSX.h └── Info.plist ├── BinarySwift_iOS ├── BinarySwift_iOS.h └── Info.plist ├── BinarySwiftTests_OSX └── Info.plist ├── BinarySwiftTests_iOS └── Info.plist ├── LICENSE ├── BinarySwift.podspec ├── .gitignore ├── README.md └── Tests └── BinarySwiftTests ├── BinaryDataReaderTests.swift └── BinaryDataTests.swift /.swift-version: -------------------------------------------------------------------------------- 1 | 3.1 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode9.2 3 | 4 | script: 5 | - xcodebuild clean build -project BinarySwift.xcodeproj -scheme BinarySwift_OSX 6 | - xcodebuild test -project BinarySwift.xcodeproj -scheme BinarySwiftTests_OSX 7 | -------------------------------------------------------------------------------- /BinarySwift.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BinarySwift.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.1 2 | import PackageDescription 3 | 4 | let package = Package( 5 | name: "BinarySwift", 6 | platforms: [ 7 | .macOS("10.9"), 8 | .iOS("8.0"), 9 | ], 10 | products: [ 11 | .library(name: "BinarySwift", targets: ["BinarySwift"]), 12 | ], 13 | targets: [ 14 | .target(name: "BinarySwift", dependencies: []), 15 | .testTarget(name: "BinarySwiftTests", dependencies: ["BinarySwift"]), 16 | ] 17 | ) 18 | -------------------------------------------------------------------------------- /Sources/BinarySwift/Common.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Common.swift 3 | // BinaryData 4 | // 5 | // Created by Łukasz Kwoska on 09.12.2015. 6 | // Copyright © 2015 Macoscope Sp. z o.o. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | func unsafeConversion(_ from: FROM) -> TO { 12 | func ptr(_ fromPtr: UnsafePointer) -> UnsafePointer { 13 | return fromPtr.withMemoryRebound(to: TO.self, capacity: 1, { return $0 }) 14 | } 15 | 16 | var fromVar = from 17 | return ptr(&fromVar).pointee 18 | } 19 | -------------------------------------------------------------------------------- /Sources/BinarySwift/BinaryDataErrors.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BinaryDataErrors.swift 3 | // BinaryData 4 | // 5 | // Created by Łukasz Kwoska on 09.12.2015. 6 | // Copyright © 2015 Macoscope Sp. z o.o. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | Errors thrown by `BinaryData` i `BinaryDataReader` 13 | */ 14 | public enum BinaryDataErrors : Error { 15 | ///There wasn't enough data to read in current `BinaryData` struct 16 | case notEnoughData 17 | ///Data was supposed to be UTF8, but there was an error parsing it 18 | case failedToConvertToString 19 | } 20 | -------------------------------------------------------------------------------- /BinarySwift/BinarySwift_OSX.h: -------------------------------------------------------------------------------- 1 | // 2 | // BinarySwift.h 3 | // BinarySwift 4 | // 5 | // Created by Łukasz Kwoska on 09/04/16. 6 | // Copyright © 2016 Spinal Development.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for BinarySwift. 12 | FOUNDATION_EXPORT double BinarySwiftVersionNumber; 13 | 14 | //! Project version string for BinarySwift. 15 | FOUNDATION_EXPORT const unsigned char BinarySwiftVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /BinarySwift_iOS/BinarySwift_iOS.h: -------------------------------------------------------------------------------- 1 | // 2 | // BinarySwift_iOS.h 3 | // BinarySwift_iOS 4 | // 5 | // Created by Łukasz Kwoska on 09/04/16. 6 | // Copyright © 2016 Spinal Development.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for BinarySwift_iOS. 12 | FOUNDATION_EXPORT double BinarySwift_iOSVersionNumber; 13 | 14 | //! Project version string for BinarySwift_iOS. 15 | FOUNDATION_EXPORT const unsigned char BinarySwift_iOSVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /BinarySwiftTests_OSX/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 | -------------------------------------------------------------------------------- /BinarySwiftTests_iOS/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 | -------------------------------------------------------------------------------- /BinarySwift_iOS/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 | BinarySwift 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /BinarySwift/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 | BinarySwift 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSHumanReadableCopyright 24 | Copyright © 2016 Spinal Development.com. All rights reserved. 25 | NSPrincipalClass 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, 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, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Sources/BinarySwift/IntegerType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // IntegerType.swift 3 | // BinaryData 4 | // 5 | // Created by Łukasz Kwoska on 09.12.2015. 6 | // Copyright © 2015 Macoscope Sp. z o.o. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension UInt16 { 12 | static func join(_ parts: (UInt8, UInt8), bigEndian: Bool) -> UInt16 { 13 | let tuple = toUInt16(applyOrder(parts, bigEndian)) 14 | return (UInt16(tuple.1) << 8) | UInt16(tuple.0) 15 | 16 | } 17 | } 18 | 19 | extension UInt32 { 20 | static func join(_ parts:(UInt8, UInt8, UInt8, UInt8), bigEndian: Bool) -> UInt32 { 21 | let tuple = toUInt32(applyOrder(parts, bigEndian)) 22 | let tuple24 = UInt32(tuple.3) << 24 23 | let tuple16 = UInt32(tuple.2) << 16 24 | let tuple8 = UInt32(tuple.1) << 8 25 | let tuple0 = UInt32(tuple.0) 26 | return tuple24 | tuple16 | tuple8 | tuple0 27 | } 28 | } 29 | 30 | extension UInt64 { 31 | static func join(_ parts:(UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8), bigEndian: Bool) -> UInt64{ 32 | let tuple = toUInt64(applyOrder(parts, bigEndian)) 33 | return (tuple.7 << 56) | (tuple.6 << 48) | (tuple.5 << 40) | (tuple.4 << 32) 34 | | (tuple.3 << 24) | (tuple.2 << 16) | (tuple.1 << 8) | tuple.0 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /BinarySwift.podspec: -------------------------------------------------------------------------------- 1 | 2 | Pod::Spec.new do |s| 3 | s.name = "BinarySwift" 4 | s.version = "0.9.5" 5 | s.summary = "BinarySwift is a pure-swift library for parsing binary data." 6 | 7 | s.description = <<-DESC 8 | BinarySwift is a pure-swift library for parsing binary data. It contains 9 | two components - BinaryReader which can be used to parse 10 | binary data in non-mutating environment, 11 | and BinaryDataReader which keeps index of last read byte and 12 | automatically updates it. 13 | 14 | Using this library you can read: 15 | - UInt(8/16/32/64) 16 | - Int(8/16/32/64) 17 | - Float(32,64) 18 | - Null-terminated UTF8 string 19 | - UTF8 String of known size 20 | DESC 21 | 22 | s.homepage = "https://github.com/Szaq/BinarySwift.git" 23 | 24 | s.license = { :type => 'BSD', :file => "LICENSE"} 25 | 26 | s.author = "Łukasz Kwoska" 27 | 28 | s.ios.deployment_target = "8.0" 29 | s.osx.deployment_target = "10.9" 30 | 31 | s.source = { :git => "https://github.com/Szaq/BinarySwift.git", :tag => "v0.9.5" } 32 | s.source_files = "Sources/BinarySwift/*.swift" 33 | 34 | end 35 | -------------------------------------------------------------------------------- /Sources/BinarySwift/Tuple.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Tupple.swift 3 | // BinaryData 4 | // 5 | // Created by Łukasz Kwoska on 11.12.2015. 6 | // Copyright © 2015 Macoscope Sp. z o.o. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | func applyOrder(_ tuple: (T, T), _ bigEndian: Bool) -> (T, T) { 12 | return bigEndian ? (tuple.1, tuple.0) : tuple 13 | } 14 | 15 | func applyOrder(_ tuple: (T, T, T, T), _ bigEndian: Bool) -> (T, T, T, T) { 16 | return bigEndian ? (tuple.3, tuple.2, tuple.1, tuple.0) : tuple 17 | } 18 | 19 | func applyOrder(_ tuple: (T, T, T, T, T, T, T, T), _ bigEndian: Bool) -> (T, T, T, T, T, T, T, T) { 20 | return bigEndian ? (tuple.7, tuple.6, tuple.5, tuple.4, tuple.3, tuple.2, tuple.1, tuple.0) : tuple 21 | } 22 | 23 | func toUInt16(_ tuple: (UInt8, UInt8)) -> (UInt16, UInt16) { 24 | return (UInt16(tuple.0), UInt16(tuple.1)) 25 | } 26 | 27 | func toUInt32(_ tuple: (UInt8, UInt8, UInt8, UInt8)) -> (UInt32, UInt32, UInt32, UInt32) { 28 | return (UInt32(tuple.0), UInt32(tuple.1), UInt32(tuple.2), UInt32(tuple.3)) 29 | } 30 | 31 | func toUInt64(_ tuple: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8)) -> (UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64, UInt64) { 32 | return (UInt64(tuple.0), UInt64(tuple.1), UInt64(tuple.2), UInt64(tuple.3), UInt64(tuple.4), UInt64(tuple.5), UInt64(tuple.6), UInt64(tuple.7)) 33 | } 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata 19 | 20 | ## Other 21 | *.xccheckout 22 | *.moved-aside 23 | *.xcuserstate 24 | *.xcscmblueprint 25 | 26 | ## Obj-C/Swift specific 27 | *.hmap 28 | *.ipa 29 | 30 | ## Playgrounds 31 | timeline.xctimeline 32 | playground.xcworkspace 33 | 34 | # Swift Package Manager 35 | # 36 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 37 | # Packages/ 38 | .build/ 39 | 40 | # CocoaPods 41 | # 42 | # We recommend against adding the Pods directory to your .gitignore. However 43 | # you should judge for yourself, the pros and cons are mentioned at: 44 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 45 | # 46 | # Pods/ 47 | 48 | # Carthage 49 | # 50 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 51 | # Carthage/Checkouts 52 | 53 | Carthage/Build 54 | 55 | # fastlane 56 | # 57 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 58 | # screenshots whenever they are needed. 59 | # For more information about the recommended setup visit: 60 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md 61 | 62 | fastlane/report.xml 63 | fastlane/screenshots 64 | -------------------------------------------------------------------------------- /BinarySwift.xcodeproj/xcshareddata/xcschemes/BinarySwiftTests_OSX.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 16 | 18 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 41 | 42 | 43 | 44 | 50 | 51 | 53 | 54 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /BinarySwift.xcodeproj/xcshareddata/xcschemes/BinarySwiftTests_iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 16 | 18 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 41 | 42 | 43 | 44 | 50 | 51 | 53 | 54 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /BinarySwift.xcodeproj/xcshareddata/xcschemes/BinarySwift_OSX.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 35 | 36 | 47 | 48 | 54 | 55 | 56 | 57 | 58 | 59 | 65 | 66 | 72 | 73 | 74 | 75 | 77 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /BinarySwift.xcodeproj/xcshareddata/xcschemes/BinarySwift_iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 57 | 63 | 64 | 65 | 66 | 67 | 68 | 74 | 75 | 77 | 78 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) ![platforms](https://img.shields.io/badge/platforms-iOS%20%7C%20OSX-333333.svg) ![pod](https://img.shields.io/cocoapods/v/BinarySwift.svg) [![Build Status](https://travis-ci.org/Szaq/BinarySwift.svg?branch=master)](https://travis-ci.org/Szaq/BinarySwift) 2 | # BinarySwift 3 | 4 | BinarySwift is a pure-swift library for parsing binary data. It contains two components - BinaryReader which can be used to parse 5 | binary data in non-mutating environment, 6 | and BinaryDataReader which keeps index of last read byte and 7 | automatically updates it. 8 | 9 | Using this library you can read: 10 | - UInt(8/16/32/64) 11 | - Int(8/16/32/64) 12 | - Float(32,64) 13 | - Null-terminated UTF8 string 14 | - UTF8 String of known size 15 | 16 | # How to use 17 | 18 | There are various initializers of `BinaryData`. Most notably `public init(data: [UInt8], bigEndian: Bool = default)` and `public init(data: NSData, bigEndian: Bool = default)`. 19 | 20 | BinaryData is a non-mutating struct, so can safely be created using `let`. 21 | 22 | Parsing IP frame header with `BinaryReader` is very simple: 23 | 24 | ```swift 25 | 26 | struct IPHeader { 27 | let version: UInt8 28 | let headerLength: UInt8 29 | let typeOfService: UInt8 30 | let length: UInt16 31 | let id: UInt16 32 | let offset: UInt16 33 | let timeToLive: UInt8 34 | let proto:UInt8 35 | let checksum: UInt16 36 | let source: in_addr 37 | let destination: in_addr 38 | } 39 | 40 | let nsData = ... 41 | let data = BinaryData(data: nsData) 42 | 43 | let header = IPHeader(version: try data.get(0), 44 | headerLength: try data.get(1), 45 | typeOfService: try data.get(2), 46 | length: try data.get(3), 47 | id: try data.get(5), 48 | offset: try data.get(7), 49 | timeToLive: try data.get(8), 50 | proto: try data.get(9), 51 | checksum: try data.get(10), 52 | source: in_addr(s_addr: try data.get(12)), 53 | destination: in_addr(s_addr: try data.get(16))) 54 | 55 | ``` 56 | 57 | If mutating reference types are not a problem for you then with BinaryDataReader it is even simpler: 58 | ```swift 59 | 60 | struct IPHeader { 61 | let version: UInt8 62 | let headerLength: UInt8 63 | let typeOfService: UInt8 64 | let length: UInt16 65 | let id: UInt16 66 | let offset: UInt16 67 | let timeToLive: UInt8 68 | let proto:UInt8 69 | let checksum: UInt16 70 | let source: in_addr 71 | let destination: in_addr 72 | } 73 | 74 | let nsData = ... 75 | let data = BinaryData(data: nsData) 76 | let reader = BinaryDataReader(data) 77 | 78 | let header = IPHeader(version: try reader.read(), 79 | headerLength: try reader.read(), 80 | typeOfService: try reader.read(), 81 | length: try reader.read(), 82 | id: try reader.read(), 83 | offset: try reader.read(), 84 | timeToLive: try reader.read(), 85 | proto: try reader.read(), 86 | checksum: try reader.read(), 87 | source: in_addr(s_addr: try reader.read()), 88 | destination: in_addr(s_addr: try reader.read())) 89 | 90 | ``` 91 | You can even pass `reader` down to other functions, because it is a `class` and reference semantics applies. 92 | 93 | This library is perfect compromise. Neither magic nor too verbose. 94 | 95 | # Contributions 96 | Contributions are more than welcome. Please send your PRs / Issues / Whatever comes to your mind. 97 | -------------------------------------------------------------------------------- /Tests/BinarySwiftTests/BinaryDataReaderTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BinaryDataReaderTests.swift 3 | // BinarySwift 4 | // 5 | // Created by Łukasz Kwoska on 12/04/16. 6 | // Copyright © 2016 Spinal Development.com. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import BinarySwift 11 | 12 | 13 | class BinaryDataReaderTests: XCTestCase { 14 | func testReadUInt8() { 15 | let reader = BinaryDataReader(BinaryData(data:[0xff, 0x05])) 16 | XCTAssertEqual(try? reader.read() as UInt8, 255) 17 | XCTAssertEqual(try? reader.read() as UInt8, 5) 18 | XCTAssertNil(try? reader.read() as UInt8?) 19 | } 20 | 21 | func testReadInt8() { 22 | let reader = BinaryDataReader(BinaryData(data:[0xff, 0x05])) 23 | XCTAssertEqual(try? reader.read() as Int8, -1) 24 | XCTAssertEqual(try? reader.read() as Int8, 5) 25 | XCTAssertNil(try? reader.read() as Int8?) 26 | } 27 | 28 | func testReadUInt16() { 29 | let reader = BinaryDataReader(BinaryData(data:[0xff, 0x00, 0xcc, 0x00, 0x00])) 30 | XCTAssertEqual(try? reader.read() as UInt16, 0xff00) 31 | XCTAssertEqual(try? reader.read() as UInt16, 0xcc00) 32 | XCTAssertNil(try? reader.read() as UInt16?) 33 | } 34 | 35 | func testReadInt16() { 36 | let reader = BinaryDataReader(BinaryData(data:[0xff, 0x00, 0xcc, 0x00, 0x00])) 37 | XCTAssertEqual(try? reader.read() as Int16, -256) 38 | XCTAssertEqual(try? reader.read() as Int16, -13312) 39 | XCTAssertNil(try? reader.read() as Int16?) 40 | } 41 | 42 | func testReadUInt32() { 43 | let reader = BinaryDataReader(BinaryData(data:[0xff, 0x00, 0xcc, 0x11, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00])) 44 | XCTAssertEqual(try? reader.read() as UInt32, 0xff00cc11) 45 | XCTAssertEqual(try? reader.read() as UInt32, 5) 46 | XCTAssertNil(try? reader.read() as UInt32?) 47 | } 48 | 49 | func testReadInt32() { 50 | let reader = BinaryDataReader(BinaryData(data:[0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00])) 51 | XCTAssertEqual(try? reader.read() as Int32, -16777216) 52 | XCTAssertEqual(try? reader.read() as Int32, 255) 53 | XCTAssertNil(try? reader.read() as Int32?) 54 | } 55 | 56 | func testReadUInt64() { 57 | let reader = BinaryDataReader(BinaryData(data:[0xff, 0x00, 0xcc, 0x11, 0x00, 0x00, 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00])) 58 | XCTAssertEqual(try? reader.read() as UInt64, 0xff00cc11000000ab) 59 | XCTAssertNil(try? reader.read() as UInt64?) 60 | } 61 | 62 | func testReadInt64() { 63 | let reader = BinaryDataReader(BinaryData(data:[0xff, 0x00, 0xcc, 0x11, 0x00, 0x00, 0x00, 0xab, 0x00, 0x00, 0x00, 0x00, 0x00])) 64 | XCTAssertEqual(try? reader.read() as Int64, -71833220651417429) 65 | XCTAssertNil(try? reader.read() as Int64?) 66 | 67 | } 68 | 69 | func testReadFloat32() { 70 | let reader = BinaryDataReader(BinaryData(data:[0x40, 0x20, 0x00, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00])) 71 | XCTAssertEqual(try? reader.read() as Float32, 2.5) 72 | XCTAssertEqual(try? reader.read() as Float32, 2.75) 73 | XCTAssertNil(try? reader.read() as Float32?) 74 | 75 | } 76 | 77 | func testReadFloat64() { 78 | let reader = BinaryDataReader(BinaryData(data:[0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])) 79 | XCTAssertEqual(try? reader.read() as Float64, 8.0) 80 | XCTAssertEqual(try? reader.read() as Float64, 16.0) 81 | XCTAssertNil(try? reader.read() as Float64?) 82 | } 83 | 84 | func testReadNullTerminatedString() { 85 | let string = "Test string" 86 | let bytes = Array(string.utf8CString).map {UInt8($0)} 87 | let reader = BinaryDataReader(BinaryData(data: bytes + bytes + [0x0, 0x12])) 88 | 89 | XCTAssertEqual(try? reader.readNullTerminatedUTF8(), string) 90 | XCTAssertEqual(try? reader.readNullTerminatedUTF8(), string) 91 | XCTAssertEqual(try? reader.readNullTerminatedUTF8(), "") 92 | XCTAssertNil(try? reader.readNullTerminatedUTF8()) 93 | } 94 | 95 | func testReadString() { 96 | let string = "Test string" 97 | let bytes = Array(string.utf8) 98 | let reader = BinaryDataReader(BinaryData(data: bytes + bytes + [0x0, 0x12])) 99 | 100 | XCTAssertEqual(try? reader.readUTF8(11), string) 101 | XCTAssertEqual(try? reader.readUTF8(11), string) 102 | XCTAssertEqual(try? reader.readUTF8(0), "") 103 | XCTAssertNil(try? reader.readUTF8(11)) 104 | } 105 | 106 | func testReadSubData() { 107 | let reader = BinaryDataReader(BinaryData(data:[0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00])) 108 | let subdata1 = try? reader.read(8) as BinaryData 109 | let subdata2 = try? reader.read(8) as BinaryData 110 | XCTAssertEqual(subdata1?.data ?? [], [0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) 111 | XCTAssertEqual(subdata2?.data ?? [], [0x40, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /Sources/BinarySwift/BinaryDataReader.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BinaryDataReader.swift 3 | // BinaryData 4 | // 5 | // Created by Łukasz Kwoska on 09.12.2015. 6 | // Copyright © 2015 Macoscope Sp. z o.o. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | ///Wrapper on `BinaryReader` which is reference type and keeps current offset. 12 | open class BinaryDataReader { 13 | public private(set) var readIndex: Int 14 | let data: BinaryData 15 | 16 | /** 17 | Initialize `BinaryDataReader` 18 | - parameter data: Underlying `BinaryData` 19 | - parameter readIndex: Starting index. If ommited than 0 is used. 20 | 21 | - returns: Initialized object 22 | */ 23 | public init(_ data: BinaryData, readIndex: Int = 0) { 24 | self.data = data 25 | self.readIndex = readIndex 26 | } 27 | 28 | // MARK: - Parsing out simple types 29 | 30 | /** 31 | Parse `UInt8` from underlying data at current offset and increase offset. 32 | 33 | - returns: `UInt8` representation of byte at offset. 34 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 35 | */ 36 | open func read(_ bigEndian: Bool? = nil) throws -> UInt8 { 37 | let value: UInt8 = try data.get(readIndex, bigEndian: bigEndian) 38 | readIndex = readIndex + 1 39 | return value 40 | } 41 | 42 | /** 43 | Parse `Int8` from underlying data at current offset and increase offset. 44 | 45 | - returns: `Int8` representation of byte at offset. 46 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 47 | */ 48 | open func read(_ bigEndian: Bool? = nil) throws -> Int8 { 49 | let value: Int8 = try data.get(readIndex, bigEndian: bigEndian) 50 | readIndex = readIndex + 1 51 | return value 52 | } 53 | 54 | /** 55 | Parse `UInt16` from underlying data at current offset and increase offset. 56 | 57 | - returns: `UInt16` representation of bytes at offset. 58 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 59 | */ 60 | open func read(_ bigEndian: Bool? = nil) throws -> UInt16 { 61 | let value: UInt16 = try data.get(readIndex, bigEndian: bigEndian) 62 | readIndex = readIndex + 2 63 | return value 64 | } 65 | 66 | /** 67 | Parse `Int16` from underlying data at current offset and increase offset. 68 | 69 | - returns: `Int16` representation of bytes at offset. 70 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 71 | */ 72 | open func read(_ bigEndian: Bool? = nil) throws -> Int16 { 73 | let value: Int16 = try data.get(readIndex, bigEndian: bigEndian) 74 | readIndex = readIndex + 2 75 | return value 76 | } 77 | 78 | /** 79 | Parse `UInt32` from underlying data at current offset and increase offset. 80 | 81 | - returns: `UInt32` representation of bytes at offset. 82 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 83 | */ 84 | open func read(_ bigEndian: Bool? = nil) throws -> UInt32 { 85 | let value: UInt32 = try data.get(readIndex, bigEndian: bigEndian) 86 | readIndex = readIndex + 4 87 | return value 88 | } 89 | 90 | /** 91 | Parse `Int32` from underlying data at current offset and increase offset. 92 | 93 | - returns: `Int32` representation of bytes at offset. 94 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 95 | */ 96 | open func read(_ bigEndian: Bool? = nil) throws -> Int32 { 97 | let value: Int32 = try data.get(readIndex, bigEndian: bigEndian) 98 | readIndex = readIndex + 4 99 | return value 100 | } 101 | 102 | /** 103 | Parse `UInt64` from underlying data at current offset and increase offset. 104 | 105 | - returns: `UInt64` representation of bytes at offset. 106 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 107 | */ 108 | open func read(_ bigEndian: Bool? = nil) throws -> UInt64 { 109 | let value: UInt64 = try data.get(readIndex, bigEndian: bigEndian) 110 | readIndex = readIndex + 8 111 | return value 112 | } 113 | 114 | /** 115 | Parse `Int64` from underlying data at current offset and increase offset. 116 | 117 | - returns: `Int64` representation of bytes at offset. 118 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 119 | */ 120 | open func read(_ bigEndian: Bool? = nil) throws -> Int64 { 121 | let value: Int64 = try data.get(readIndex, bigEndian: bigEndian) 122 | readIndex = readIndex + 8 123 | return value 124 | } 125 | 126 | /** 127 | Parse `Float32` from underlying data at current offset and increase offset. 128 | 129 | - returns: `Float32` representation of bytes at offset. 130 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 131 | */ 132 | open func read() throws -> Float32 { 133 | let value: Float32 = try data.get(readIndex) 134 | readIndex = readIndex + 4 135 | return value 136 | } 137 | 138 | /** 139 | Parse `Float64` from underlying data at current offset and increase offset. 140 | 141 | - returns: `Float64` representation of bytes at offset. 142 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 143 | */ 144 | open func read() throws -> Float64 { 145 | let value: Float64 = try data.get(readIndex) 146 | readIndex = readIndex + 8 147 | return value 148 | } 149 | 150 | /** 151 | Parse null-terminated UTF8 `String` from underlying data at current offset and increase offset. 152 | 153 | - returns: `String` representation of null-terminated UTF8 bytes at offset. 154 | 155 | - throws: 156 | - `BinaryDataErrors.NotEnoughData` if there is not enough data. 157 | - `BinaryDataErrors.FailedToConvertToString` if there was an error converting byte stream to String. 158 | */ 159 | open func readNullTerminatedUTF8() throws -> String { 160 | let string = try data.getNullTerminatedUTF8(readIndex) 161 | readIndex += string.utf8.count + 1//Account for \0 162 | return string 163 | } 164 | 165 | /** 166 | Parse UTF8 `String` of known size from underlying data at current offset and increase offset. 167 | 168 | - parameter length: String length in bytes. 169 | 170 | - returns: `String` representation of null-terminated UTF8 bytes at offset. 171 | - throws: 172 | - `BinaryDataErrors.NotEnoughData` if there is not enough data. 173 | - `BinaryDataErrors.FailedToConvertToString` if there was an error converting byte stream to String. 174 | */ 175 | open func readUTF8(_ length: Int) throws -> String { 176 | let string = try data.getUTF8(readIndex, length: length) 177 | readIndex += length 178 | return string 179 | } 180 | 181 | /** 182 | Get subdata at current offset and increase offset. 183 | 184 | - parameter length: String length in bytes. 185 | 186 | - returns: `BinaryData` subdata starting at `offset` with given `length`. 187 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 188 | */ 189 | open func read(_ length: Int) throws -> BinaryData { 190 | let subdata = try data.subData(readIndex, length) 191 | readIndex += length 192 | return subdata 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /Tests/BinarySwiftTests/BinaryDataTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BinaryDataTests.swift 3 | // BinarySwift 4 | // 5 | // Created by Łukasz Kwoska on 11/04/16. 6 | // Copyright © 2016 Spinal Development.com. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | import BinarySwift 11 | 12 | class BinaryDataTests: XCTestCase { 13 | 14 | let intData = BinaryData(data: [0xff, 0x11, 0x00, 0xef, 0x76, 0x12, 0x98, 0xff]) 15 | let floatData = BinaryData(data:[0x40, 0x20, 0x00, 0x00]) 16 | let doubleData = BinaryData(data:[0x40, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) 17 | 18 | func doManyTimes(_ block: () -> Void) { 19 | for _ in 0 ..< 10000 { 20 | block() 21 | } 22 | } 23 | 24 | //MARK: - Initialization 25 | 26 | func testArrayLiteralInit() { 27 | let data:BinaryData = [0xf, 0x00, 0x1, 0xa] 28 | XCTAssertEqual(data.data, [0xf, 0x00, 0x1, 0xa]) 29 | XCTAssertTrue(data.bigEndian) 30 | } 31 | 32 | func testArrayInit() { 33 | let data = BinaryData(data: [0xf, 0x00, 0x1, 0xa]) 34 | XCTAssertEqual(data.data, [0xf, 0x00, 0x1, 0xa]) 35 | XCTAssertTrue(data.bigEndian) 36 | 37 | let dataExplicitBigEndianTrue = BinaryData(data: [0xf, 0x00, 0x1, 0xa], bigEndian: true) 38 | XCTAssertEqual(dataExplicitBigEndianTrue.data, [0xf, 0x00, 0x1, 0xa]) 39 | XCTAssertTrue(dataExplicitBigEndianTrue.bigEndian) 40 | 41 | let dataExplicitBigEndianFalse = BinaryData(data: [0xf, 0x00, 0x1, 0xa], bigEndian: false) 42 | XCTAssertEqual(dataExplicitBigEndianFalse.data, [0xf, 0x00, 0x1, 0xa]) 43 | XCTAssertFalse(dataExplicitBigEndianFalse.bigEndian) 44 | } 45 | 46 | func testNSDataInit() { 47 | guard let nsData = Data(base64Encoded: "MTIzNA==", options: Data.Base64DecodingOptions()) 48 | else { XCTFail("Failed to decode test Base64 string"); return} 49 | 50 | let data = BinaryData(data: nsData) 51 | XCTAssertEqual(data.data, [49, 50, 51, 52]) 52 | XCTAssertTrue(data.bigEndian) 53 | 54 | let dataExplicitBigEndianTrue = BinaryData(data: nsData, bigEndian: true) 55 | XCTAssertEqual(dataExplicitBigEndianTrue.data, [49, 50, 51, 52]) 56 | XCTAssertTrue(dataExplicitBigEndianTrue.bigEndian) 57 | 58 | let dataExplicitBigEndianFalse = BinaryData(data: nsData, bigEndian: false) 59 | XCTAssertEqual(dataExplicitBigEndianFalse.data, [49, 50, 51, 52]) 60 | XCTAssertFalse(dataExplicitBigEndianFalse.bigEndian) 61 | } 62 | 63 | 64 | 65 | //MARK: - Reading One - byte values 66 | 67 | func testGetUInt8() { 68 | let value: UInt8? = try? intData.get(0) 69 | XCTAssertEqual(value, 255) 70 | } 71 | 72 | func testPerformanceGetUInt8() { 73 | self.measure { 74 | self.doManyTimes { 75 | let _: UInt8? = try? self.intData.get(0) 76 | } 77 | } 78 | } 79 | 80 | func testGetInt8() { 81 | let value: Int8? = try? intData.get(0) 82 | XCTAssertEqual(value, -1) 83 | } 84 | 85 | func testPerformanceGetInt8() { 86 | self.measure { 87 | self.doManyTimes { 88 | let _: Int8? = try? self.intData.get(0) 89 | } 90 | } 91 | } 92 | 93 | 94 | //MARK: - Reading Two - byte values 95 | 96 | func testGetUInt16() { 97 | let value: UInt16? = try? intData.get(0) 98 | XCTAssertEqual(value, 65297) 99 | } 100 | 101 | func testPerformanceGetUInt16() { 102 | self.measure { 103 | self.doManyTimes { 104 | let _: UInt16? = try? self.intData.get(0) 105 | } 106 | } 107 | } 108 | 109 | func testGetInt16() { 110 | let value: Int16? = try? intData.get(0) 111 | XCTAssertEqual(value, -239) 112 | } 113 | 114 | func testPerformanceGetInt16() { 115 | self.measure { 116 | self.doManyTimes { 117 | let _: Int16? = try? self.intData.get(0) 118 | } 119 | } 120 | } 121 | 122 | func testGetUInt16LittleEndian() { 123 | let value: UInt16? = try? intData.get(0, bigEndian:false) 124 | XCTAssertEqual(value, 4607) 125 | } 126 | 127 | func testPerformanceGetUInt16LittleEndian() { 128 | self.measure { 129 | self.doManyTimes { 130 | let _: UInt16? = try? self.intData.get(0, bigEndian:false) 131 | } 132 | } 133 | } 134 | 135 | func testGetInt16LittleEndian() { 136 | let value: Int16? = try? intData.get(0, bigEndian:false) 137 | XCTAssertEqual(value, 4607) 138 | } 139 | 140 | func testPerformanceGetInt16LittleEndian() { 141 | self.measure { 142 | self.doManyTimes { 143 | let _: Int16? = try? self.intData.get(0, bigEndian:false) 144 | } 145 | } 146 | } 147 | 148 | //MARK: - Reading Four - byte values 149 | 150 | func testGetUInt32() { 151 | let value: UInt32? = try? intData.get(0) 152 | XCTAssertEqual(value, 4279304431) 153 | } 154 | 155 | func testPerformanceGetUInt32() { 156 | self.measure { 157 | self.doManyTimes { 158 | let _: UInt32? = try? self.intData.get(0) 159 | } 160 | } 161 | } 162 | 163 | func testGetInt32() { 164 | let value: Int32? = try? intData.get(0) 165 | XCTAssertEqual(value, -15662865) 166 | } 167 | 168 | func testPerformanceGetInt32() { 169 | self.measure { 170 | self.doManyTimes { 171 | let _: Int32? = try? self.intData.get(0) 172 | } 173 | } 174 | } 175 | 176 | func testGetUInt32LittleEndian() { 177 | let value: UInt32? = try? intData.get(0, bigEndian:false) 178 | XCTAssertEqual(value, 4009759231) 179 | } 180 | 181 | func testPerformanceGetUInt32LittleEndian() { 182 | self.measure { 183 | self.doManyTimes { 184 | let _: UInt32? = try? self.intData.get(0, bigEndian:false) 185 | } 186 | } 187 | } 188 | 189 | func testGetInt32LittleEndian() { 190 | let value: Int32? = try? intData.get(0, bigEndian:false) 191 | XCTAssertEqual(value, -285208065) 192 | } 193 | 194 | func testPerformanceGetInt32LittleEndian() { 195 | self.measure { 196 | self.doManyTimes { 197 | let _: Int32? = try? self.intData.get(0, bigEndian:false) 198 | } 199 | } 200 | } 201 | 202 | //MARK: - Reading Eight - byte values 203 | 204 | func testGetUInt64() { 205 | let value: UInt64? = try? intData.get(0) 206 | XCTAssertEqual(value, 18379472582753818879) 207 | } 208 | 209 | func testPerformanceGetUInt64() { 210 | self.measure { 211 | self.doManyTimes { 212 | let _: UInt64? = try? self.intData.get(0) 213 | } 214 | } 215 | } 216 | 217 | func testGetInt64() { 218 | let value: Int64? = try? intData.get(0) 219 | XCTAssertEqual(value, -67271490955732737) 220 | } 221 | 222 | func testPerformanceGetInt64() { 223 | self.measure { 224 | self.doManyTimes { 225 | let _: Int64? = try? self.intData.get(0) 226 | } 227 | } 228 | } 229 | 230 | func testGetUInt64LittleEndian() { 231 | let value: UInt64? = try? intData.get(0, bigEndian:false) 232 | XCTAssertEqual(value, 18417490978156843519) 233 | } 234 | 235 | func testPerformanceGetUInt64LittleEndian() { 236 | self.measure { 237 | self.doManyTimes { 238 | let _: UInt64? = try? self.intData.get(0, bigEndian:false) 239 | } 240 | } 241 | } 242 | 243 | func testGetInt64LittleEndian() { 244 | let value: Int64? = try? intData.get(0, bigEndian:false) 245 | XCTAssertEqual(value, -29253095552708097) 246 | } 247 | 248 | func testPerformanceGetInt64LittleEndian() { 249 | self.measure { 250 | self.doManyTimes { 251 | let _: Int64? = try? self.intData.get(0, bigEndian:false) 252 | } 253 | } 254 | } 255 | 256 | //MARK: - Reading Floats 257 | 258 | func testGetFloat32() { 259 | let value: Float32? = try? floatData.get(0) 260 | XCTAssertEqual(value, 2.5) 261 | } 262 | 263 | func testPerformanceGetFloat32() { 264 | self.measure { 265 | self.doManyTimes { 266 | let _: Float32? = try? self.floatData.get(0) 267 | } 268 | } 269 | } 270 | 271 | func testGetFloat64() { 272 | let value: Float64? = try? doubleData.get(0) 273 | XCTAssertEqual(value, 8.0) 274 | } 275 | 276 | func testPerformanceGetFloat64() { 277 | self.measure { 278 | self.doManyTimes { 279 | let _: Float64? = try? self.doubleData.get(0) 280 | } 281 | } 282 | } 283 | 284 | //MARK: - Test reading String 285 | func testGetNullTerminatedString() { 286 | let testString = "TestData" 287 | let bytes = Array(testString.utf8CString).map {UInt8($0)} 288 | let data = BinaryData(data: bytes + bytes) 289 | print (bytes) 290 | XCTAssertEqual(try? data.getNullTerminatedUTF8(0), testString) 291 | } 292 | 293 | func testPerformanceGetNullTerminatedString() { 294 | self.measure { 295 | self.doManyTimes { 296 | let testString = "TestData" 297 | let data = BinaryData(data: Array(testString.utf8CString).map {UInt8($0)}) 298 | let _ = try? data.getNullTerminatedUTF8(0) 299 | } 300 | } 301 | } 302 | 303 | func testGetString() { 304 | let testString = "Test" 305 | let data = BinaryData(data: Array(testString.utf8CString).map {UInt8($0)}) 306 | XCTAssertEqual(try? data.getUTF8(0, length: 4), testString) 307 | } 308 | 309 | func testPerformanceGetString() { 310 | self.measure { 311 | self.doManyTimes { 312 | let testString = "Test" 313 | let data = BinaryData(data: Array(testString.utf8CString).map {UInt8($0)}) 314 | let _ = try? data.getUTF8(0, length: 4) 315 | } 316 | } 317 | } 318 | 319 | //MARK: - Test reading subdata 320 | 321 | func testGetSubData() { 322 | XCTAssertEqual((try? intData.subData(1, 2).data) ?? [], [0x11, 0x00]) 323 | } 324 | 325 | func testPerformanceGetSubData() { 326 | self.measure { 327 | self.doManyTimes { 328 | let _ = try? self.intData.subData(1, 2) 329 | } 330 | } 331 | } 332 | 333 | func testTail() { 334 | XCTAssertEqual((try? intData.tail(1).data) ?? [], [0x11, 0x00, 0xef, 0x76, 0x12, 0x98, 0xff]) 335 | } 336 | 337 | func testPerformanceTail() { 338 | self.measure { 339 | self.doManyTimes { 340 | let _ = try? self.intData.tail(1) 341 | } 342 | } 343 | } 344 | 345 | } 346 | -------------------------------------------------------------------------------- /Sources/BinarySwift/BinaryData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BinaryData.swift 3 | // BinaryData 4 | // 5 | // Created by Łukasz Kwoska on 08.12.2015. 6 | // Copyright © 2015 Macoscope Sp. z o.o. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /** 12 | Structure for fast/immutable parsing of binary file. 13 | */ 14 | public struct BinaryData : ExpressibleByArrayLiteral { 15 | public typealias Element = UInt8 16 | ///Underlying data for this object. 17 | public let data: [UInt8] 18 | ///Is data in big-endian byte order? 19 | public let bigEndian: Bool 20 | 21 | // MARK: - Initializers 22 | 23 | /** 24 | Initialize with array literal 25 | 26 | You may initialize `BinaryData` with array literal like so: 27 | ``` 28 | let data:BinaryData = [0xf, 0x00, 0x1, 0xa] 29 | ``` 30 | 31 | - parameter data: `NSData` to parse 32 | - parameter bigEndian: Is data in big-endian or little-endian order? 33 | 34 | - returns: Initialized object 35 | 36 | - remark: Data is copied. 37 | */ 38 | public init(arrayLiteral elements: Element...) { 39 | data = elements 40 | bigEndian = true 41 | } 42 | 43 | /** 44 | Initialize with array 45 | 46 | - parameter data: `Array` containing data to parse 47 | - parameter bigEndian: Is data in big-endian or little-endian order? 48 | 49 | - returns: Initialized object 50 | 51 | - remark: Data is copied. 52 | */ 53 | 54 | public init(data: [UInt8], bigEndian: Bool = true) { 55 | self.data = data 56 | self.bigEndian = bigEndian 57 | } 58 | 59 | /** 60 | Initialize with `NSData` 61 | 62 | - parameter data: `NSData` to parse 63 | - parameter bigEndian: Is data in big-endian or little-endian order? 64 | 65 | - returns: Initialized object 66 | 67 | - remark: Data is copied. 68 | */ 69 | public init(data:Data, bigEndian: Bool = true) { 70 | 71 | self.bigEndian = bigEndian 72 | 73 | var mutableData = [UInt8](repeating: 0, count: data.count) 74 | if data.count > 0 { 75 | (data as NSData).getBytes(&mutableData, length: data.count) 76 | } 77 | self.data = mutableData 78 | } 79 | 80 | // MARK: - Simple data types 81 | 82 | /** 83 | Parse `UInt8` from underlying data. 84 | 85 | - parameter offset: Offset in bytes from this value should be read 86 | - parameter bigEndian: Is data in big-endian or little-endian order? If this parameter may is ommited, than `BinaryData` 87 | setting is used. 88 | 89 | - returns: `UInt8` representation of byte at offset. 90 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 91 | */ 92 | public func get(_ offset: Int, bigEndian: Bool? = nil) throws -> UInt8 { 93 | guard offset < data.count else { throw BinaryDataErrors.notEnoughData } 94 | return data[offset] 95 | } 96 | 97 | /** 98 | Parse `UInt16` from underlying data. 99 | 100 | - parameter offset: Offset in bytes from this value should be read 101 | - parameter bigEndian: Is data in big-endian or little-endian order? If this parameter may is ommited, than `BinaryData` 102 | setting is used. 103 | 104 | - returns: `UInt16` representation of byte at offset. 105 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 106 | */ 107 | public func get(_ offset: Int, bigEndian: Bool? = nil) throws -> UInt16 { 108 | guard offset + 1 < data.count else { throw BinaryDataErrors.notEnoughData } 109 | return UInt16.join((data[offset], data[offset + 1]), 110 | bigEndian: bigEndian ?? self.bigEndian) 111 | } 112 | 113 | /** 114 | Parse `UInt32` from underlying data. 115 | 116 | - parameter offset: Offset in bytes from this value should be read 117 | - parameter bigEndian: Is data in big-endian or little-endian order? If this parameter may is ommited, than `BinaryData` 118 | setting is used. 119 | 120 | - returns: `UInt32` representation of byte at offset. 121 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 122 | */ 123 | public func get(_ offset: Int, bigEndian: Bool? = nil) throws -> UInt32 { 124 | guard offset + 3 < data.count else { throw BinaryDataErrors.notEnoughData } 125 | return UInt32.join((data[offset], data[offset + 1], data[offset + 2], data[offset + 3]), 126 | bigEndian: bigEndian ?? self.bigEndian) 127 | } 128 | 129 | /** 130 | Parse `UInt64` from underlying data. 131 | 132 | - parameter offset: Offset in bytes from this value should be read 133 | - parameter bigEndian: Is data in big-endian or little-endian order? If this parameter may is ommited, than `BinaryData` 134 | setting is used. 135 | 136 | - returns: `UInt64` representation of byte at offset. 137 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 138 | */ 139 | public func get(_ offset: Int, bigEndian: Bool? = nil) throws -> UInt64 { 140 | guard offset + 7 < data.count else { throw BinaryDataErrors.notEnoughData } 141 | return UInt64.join((data[offset], data[offset + 1], data[offset + 2], data[offset + 3], 142 | data[offset + 4], data[offset + 5], data[offset + 6], data[offset + 7]), 143 | bigEndian: bigEndian ?? self.bigEndian) } 144 | 145 | /** 146 | Parse `Int8` from underlying data. 147 | 148 | - parameter offset: Offset in bytes from this value should be read 149 | - parameter bigEndian: Is data in big-endian or little-endian order? If this parameter may is ommited, than `BinaryData` 150 | setting is used. 151 | 152 | - returns: `Int8` representation of byte at offset. 153 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 154 | */ 155 | public func get(_ offset: Int, bigEndian: Bool? = nil) throws -> Int8 { 156 | let uint: UInt8 = try get(offset, bigEndian: bigEndian ?? self.bigEndian) 157 | return Int8(bitPattern: uint) 158 | } 159 | 160 | /** 161 | Parse `Int16` from underlying data. 162 | 163 | - parameter offset: Offset in bytes from this value should be read 164 | - parameter bigEndian: Is data in big-endian or little-endian order? If this parameter may is ommited, than `BinaryData` 165 | setting is used. 166 | 167 | - returns: `Int16` representation of byte at offset. 168 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 169 | */ 170 | public func get(_ offset: Int, bigEndian: Bool? = nil) throws -> Int16 { 171 | let uint:UInt16 = try get(offset, bigEndian: bigEndian ?? self.bigEndian) 172 | return Int16(bitPattern: uint) 173 | } 174 | 175 | /** 176 | Parse `Int32` from underlying data. 177 | 178 | - parameter offset: Offset in bytes from this value should be read 179 | - parameter bigEndian: Is data in big-endian or little-endian order? If this parameter may is ommited, than `BinaryData` 180 | setting is used. 181 | 182 | - returns: `Int32` representation of byte at offset. 183 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 184 | */ 185 | public func get(_ offset: Int, bigEndian: Bool? = nil) throws -> Int32 { 186 | let uint:UInt32 = try get(offset, bigEndian: bigEndian ?? self.bigEndian) 187 | return Int32(bitPattern: uint) 188 | } 189 | 190 | /** 191 | Parse `Int64` from underlying data. 192 | 193 | - parameter offset: Offset in bytes from this value should be read 194 | - parameter bigEndian: Is data in big-endian or little-endian order? If this parameter may is ommited, than `BinaryData` 195 | setting is used. 196 | 197 | - returns: `Int64` representation of byte at offset. 198 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 199 | */ 200 | public func get(_ offset: Int, bigEndian: Bool? = nil) throws -> Int64 { 201 | let uint:UInt64 = try get(offset, bigEndian: bigEndian ?? self.bigEndian) 202 | return Int64(bitPattern: uint) 203 | } 204 | 205 | /** 206 | Parse `Float32` from underlying data. 207 | 208 | - parameter offset: Offset in bytes from this value should be read 209 | - parameter bigEndian: Is data in big-endian or little-endian order? If this parameter may is ommited, than `BinaryData` 210 | setting is used. 211 | 212 | - returns: `Float32` representation of byte at offset. 213 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 214 | */ 215 | public func get(_ offset: Int) throws -> Float32 { 216 | let uint:UInt32 = try get(offset) 217 | return unsafeConversion(uint) 218 | } 219 | 220 | /** 221 | Parse `Float64` from underlying data. 222 | 223 | - parameter offset: Offset in bytes from this value should be read 224 | - parameter bigEndian: Is data in big-endian or little-endian order? If this parameter may is ommited, than `BinaryData` 225 | setting is used. 226 | 227 | - returns: `Float64` representation of byte at offset. 228 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 229 | */ 230 | public func get(_ offset: Int) throws -> Float64 { 231 | let uint:UInt64 = try get(offset) 232 | return unsafeConversion(uint) 233 | } 234 | 235 | // MARK: - Strings 236 | 237 | /** 238 | Parse null-terminated UTF8 `String` from underlying data. 239 | 240 | - parameter offset: Offset in bytes from this value should be read 241 | 242 | - returns: Read `String` 243 | - throws: 244 | - `BinaryDataErrors.NotEnoughData` if there is not enough data. 245 | - `BinaryDataErrors.FailedToConvertToString` if there was an error converting byte stream to String. 246 | */ 247 | public func getNullTerminatedUTF8(_ offset: Int) throws -> String { 248 | var utf8 = UTF8() 249 | var string = "" 250 | var generator = try subData(offset, data.count - offset).data.makeIterator() 251 | 252 | while true { 253 | switch utf8.decode(&generator) { 254 | case .scalarValue(let unicodeScalar) where unicodeScalar.value > 0: 255 | string.append(String(unicodeScalar)) 256 | case .scalarValue(_)://\0 means end of string 257 | return string 258 | case .emptyInput: 259 | throw BinaryDataErrors.failedToConvertToString 260 | case .error: 261 | throw BinaryDataErrors.failedToConvertToString 262 | } 263 | } 264 | } 265 | 266 | /** 267 | Parse UTF8 `String` of known size from underlying data. 268 | 269 | - parameter offset: Offset in bytes from this value should be read 270 | - parameter length: Length in bytes to read 271 | 272 | - returns: Read `String` 273 | - throws: 274 | - `BinaryDataErrors.NotEnoughData` if there is not enough data. 275 | - `BinaryDataErrors.FailedToConvertToString` if there was an error converting byte stream to String. 276 | */ 277 | public func getUTF8(_ offset: Int, length: Int) throws -> String { 278 | var utf8 = UTF8() 279 | var string = "" 280 | var generator = try subData(offset, length).data.makeIterator() 281 | 282 | while true { 283 | switch utf8.decode(&generator) { 284 | case .scalarValue(let unicodeScalar): 285 | string.append(String(unicodeScalar)) 286 | case .emptyInput: 287 | return string 288 | case .error: 289 | throw BinaryDataErrors.failedToConvertToString 290 | } 291 | } 292 | } 293 | 294 | // MARK: - Data manipulation 295 | 296 | /** 297 | Get subdata in range (offset, self.data.length) 298 | 299 | - parameter offset: Offset to start of subdata 300 | 301 | - returns: Subdata 302 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 303 | */ 304 | public func tail(_ offset: Int) throws -> BinaryData { 305 | if offset > data.count { 306 | throw BinaryDataErrors.notEnoughData 307 | } 308 | 309 | return try subData(offset, data.count - offset) 310 | } 311 | 312 | /** 313 | Get subdata in range (offset, length) 314 | 315 | - parameter offset: Offset to start of subdata 316 | - parameter length: Length of subdata 317 | 318 | - returns: Subdata 319 | - throws: `BinaryDataErrors.NotEnoughData` if there is not enough data. 320 | */ 321 | public func subData(_ offset: Int, _ length: Int) throws -> BinaryData { 322 | if offset >= 0 && offset <= data.count && length >= 0 && (offset + length) <= data.count { 323 | return BinaryData(data: Array(data[offset..<(offset + length)])) 324 | } else { 325 | throw BinaryDataErrors.notEnoughData 326 | } 327 | } 328 | } 329 | -------------------------------------------------------------------------------- /BinarySwift.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 2009DE481CBBC98200A4BC50 /* BinarySwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3980FC6D1CB92F2C0091D322 /* BinarySwift.framework */; }; 11 | 2009DE521CBBCA1800A4BC50 /* BinaryDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2009DE511CBBCA1800A4BC50 /* BinaryDataTests.swift */; }; 12 | 2009DE561CBD2ED000A4BC50 /* BinaryDataReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2009DE551CBD2ED000A4BC50 /* BinaryDataReaderTests.swift */; }; 13 | 2009DE571CBD2ED000A4BC50 /* BinaryDataReaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2009DE551CBD2ED000A4BC50 /* BinaryDataReaderTests.swift */; }; 14 | 3980FC711CB92F2C0091D322 /* BinarySwift_OSX.h in Headers */ = {isa = PBXBuildFile; fileRef = 3980FC701CB92F2C0091D322 /* BinarySwift_OSX.h */; settings = {ATTRIBUTES = (Public, ); }; }; 15 | 3980FC7F1CB92F620091D322 /* BinaryData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3980FC791CB92F620091D322 /* BinaryData.swift */; }; 16 | 3980FC801CB92F620091D322 /* BinaryDataErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3980FC7A1CB92F620091D322 /* BinaryDataErrors.swift */; }; 17 | 3980FC811CB92F620091D322 /* BinaryDataReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3980FC7B1CB92F620091D322 /* BinaryDataReader.swift */; }; 18 | 3980FC821CB92F620091D322 /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3980FC7C1CB92F620091D322 /* Common.swift */; }; 19 | 3980FC831CB92F620091D322 /* IntegerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3980FC7D1CB92F620091D322 /* IntegerType.swift */; }; 20 | 3980FC841CB92F620091D322 /* Tuple.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3980FC7E1CB92F620091D322 /* Tuple.swift */; }; 21 | 3980FC8D1CB92F840091D322 /* BinarySwift_iOS.h in Headers */ = {isa = PBXBuildFile; fileRef = 3980FC8C1CB92F840091D322 /* BinarySwift_iOS.h */; settings = {ATTRIBUTES = (Public, ); }; }; 22 | 3980FC921CB92F920091D322 /* BinaryData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3980FC791CB92F620091D322 /* BinaryData.swift */; }; 23 | 3980FC931CB92F920091D322 /* BinaryDataErrors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3980FC7A1CB92F620091D322 /* BinaryDataErrors.swift */; }; 24 | 3980FC941CB92F920091D322 /* BinaryDataReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3980FC7B1CB92F620091D322 /* BinaryDataReader.swift */; }; 25 | 3980FC951CB92F920091D322 /* Common.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3980FC7C1CB92F620091D322 /* Common.swift */; }; 26 | 3980FC961CB92F920091D322 /* IntegerType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3980FC7D1CB92F620091D322 /* IntegerType.swift */; }; 27 | 3980FC971CB92F920091D322 /* Tuple.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3980FC7E1CB92F620091D322 /* Tuple.swift */; }; 28 | 39EE44531CBC542700C947A9 /* BinarySwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3980FC8A1CB92F840091D322 /* BinarySwift.framework */; }; 29 | 39EE44591CBC553B00C947A9 /* BinaryDataTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2009DE511CBBCA1800A4BC50 /* BinaryDataTests.swift */; }; 30 | /* End PBXBuildFile section */ 31 | 32 | /* Begin PBXContainerItemProxy section */ 33 | 2009DE491CBBC98200A4BC50 /* PBXContainerItemProxy */ = { 34 | isa = PBXContainerItemProxy; 35 | containerPortal = 3980FC641CB92F2C0091D322 /* Project object */; 36 | proxyType = 1; 37 | remoteGlobalIDString = 3980FC6C1CB92F2C0091D322; 38 | remoteInfo = BinarySwift_OSX; 39 | }; 40 | 39EE44541CBC542700C947A9 /* PBXContainerItemProxy */ = { 41 | isa = PBXContainerItemProxy; 42 | containerPortal = 3980FC641CB92F2C0091D322 /* Project object */; 43 | proxyType = 1; 44 | remoteGlobalIDString = 3980FC891CB92F840091D322; 45 | remoteInfo = BinarySwift_iOS; 46 | }; 47 | /* End PBXContainerItemProxy section */ 48 | 49 | /* Begin PBXFileReference section */ 50 | 2009DE431CBBC98200A4BC50 /* BinarySwiftTests_OSX.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BinarySwiftTests_OSX.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | 2009DE471CBBC98200A4BC50 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | 2009DE511CBBCA1800A4BC50 /* BinaryDataTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BinaryDataTests.swift; path = Tests/BinarySwiftTests/BinaryDataTests.swift; sourceTree = SOURCE_ROOT; }; 53 | 2009DE551CBD2ED000A4BC50 /* BinaryDataReaderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BinaryDataReaderTests.swift; path = Tests/BinarySwiftTests/BinaryDataReaderTests.swift; sourceTree = SOURCE_ROOT; }; 54 | 3980FC6D1CB92F2C0091D322 /* BinarySwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BinarySwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 55 | 3980FC701CB92F2C0091D322 /* BinarySwift_OSX.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BinarySwift_OSX.h; sourceTree = ""; }; 56 | 3980FC721CB92F2C0091D322 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | 3980FC791CB92F620091D322 /* BinaryData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BinaryData.swift; path = Sources/BinarySwift/BinaryData.swift; sourceTree = SOURCE_ROOT; }; 58 | 3980FC7A1CB92F620091D322 /* BinaryDataErrors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BinaryDataErrors.swift; path = Sources/BinarySwift/BinaryDataErrors.swift; sourceTree = SOURCE_ROOT; }; 59 | 3980FC7B1CB92F620091D322 /* BinaryDataReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BinaryDataReader.swift; path = Sources/BinarySwift/BinaryDataReader.swift; sourceTree = SOURCE_ROOT; }; 60 | 3980FC7C1CB92F620091D322 /* Common.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Common.swift; path = Sources/BinarySwift/Common.swift; sourceTree = SOURCE_ROOT; }; 61 | 3980FC7D1CB92F620091D322 /* IntegerType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = IntegerType.swift; path = Sources/BinarySwift/IntegerType.swift; sourceTree = SOURCE_ROOT; }; 62 | 3980FC7E1CB92F620091D322 /* Tuple.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Tuple.swift; path = Sources/BinarySwift/Tuple.swift; sourceTree = SOURCE_ROOT; }; 63 | 3980FC8A1CB92F840091D322 /* BinarySwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = BinarySwift.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 64 | 3980FC8C1CB92F840091D322 /* BinarySwift_iOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BinarySwift_iOS.h; sourceTree = ""; }; 65 | 3980FC8E1CB92F840091D322 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 66 | 39EE444E1CBC542600C947A9 /* BinarySwiftTests_iOS.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BinarySwiftTests_iOS.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 67 | 39EE44521CBC542700C947A9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 68 | /* End PBXFileReference section */ 69 | 70 | /* Begin PBXFrameworksBuildPhase section */ 71 | 2009DE401CBBC98200A4BC50 /* Frameworks */ = { 72 | isa = PBXFrameworksBuildPhase; 73 | buildActionMask = 2147483647; 74 | files = ( 75 | 2009DE481CBBC98200A4BC50 /* BinarySwift.framework in Frameworks */, 76 | ); 77 | runOnlyForDeploymentPostprocessing = 0; 78 | }; 79 | 3980FC691CB92F2C0091D322 /* Frameworks */ = { 80 | isa = PBXFrameworksBuildPhase; 81 | buildActionMask = 2147483647; 82 | files = ( 83 | ); 84 | runOnlyForDeploymentPostprocessing = 0; 85 | }; 86 | 3980FC861CB92F840091D322 /* Frameworks */ = { 87 | isa = PBXFrameworksBuildPhase; 88 | buildActionMask = 2147483647; 89 | files = ( 90 | ); 91 | runOnlyForDeploymentPostprocessing = 0; 92 | }; 93 | 39EE444B1CBC542600C947A9 /* Frameworks */ = { 94 | isa = PBXFrameworksBuildPhase; 95 | buildActionMask = 2147483647; 96 | files = ( 97 | 39EE44531CBC542700C947A9 /* BinarySwift.framework in Frameworks */, 98 | ); 99 | runOnlyForDeploymentPostprocessing = 0; 100 | }; 101 | /* End PBXFrameworksBuildPhase section */ 102 | 103 | /* Begin PBXGroup section */ 104 | 2009DE441CBBC98200A4BC50 /* BinarySwiftTests_OSX */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 2009DE471CBBC98200A4BC50 /* Info.plist */, 108 | ); 109 | path = BinarySwiftTests_OSX; 110 | sourceTree = ""; 111 | }; 112 | 2009DE4E1CBBC99300A4BC50 /* Test Source */ = { 113 | isa = PBXGroup; 114 | children = ( 115 | 2009DE511CBBCA1800A4BC50 /* BinaryDataTests.swift */, 116 | 2009DE551CBD2ED000A4BC50 /* BinaryDataReaderTests.swift */, 117 | ); 118 | name = "Test Source"; 119 | sourceTree = ""; 120 | }; 121 | 3980FC631CB92F2C0091D322 = { 122 | isa = PBXGroup; 123 | children = ( 124 | 3980FC781CB92F520091D322 /* Source */, 125 | 2009DE4E1CBBC99300A4BC50 /* Test Source */, 126 | 3980FC6F1CB92F2C0091D322 /* BinarySwift_OSX */, 127 | 3980FC8B1CB92F840091D322 /* BinarySwift_iOS */, 128 | 2009DE441CBBC98200A4BC50 /* BinarySwiftTests_OSX */, 129 | 39EE444F1CBC542700C947A9 /* BinarySwiftTests_iOS */, 130 | 3980FC6E1CB92F2C0091D322 /* Products */, 131 | ); 132 | indentWidth = 2; 133 | sourceTree = ""; 134 | tabWidth = 2; 135 | }; 136 | 3980FC6E1CB92F2C0091D322 /* Products */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | 3980FC6D1CB92F2C0091D322 /* BinarySwift.framework */, 140 | 3980FC8A1CB92F840091D322 /* BinarySwift.framework */, 141 | 2009DE431CBBC98200A4BC50 /* BinarySwiftTests_OSX.xctest */, 142 | 39EE444E1CBC542600C947A9 /* BinarySwiftTests_iOS.xctest */, 143 | ); 144 | name = Products; 145 | sourceTree = ""; 146 | }; 147 | 3980FC6F1CB92F2C0091D322 /* BinarySwift_OSX */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 3980FC701CB92F2C0091D322 /* BinarySwift_OSX.h */, 151 | 3980FC721CB92F2C0091D322 /* Info.plist */, 152 | ); 153 | name = BinarySwift_OSX; 154 | path = BinarySwift; 155 | sourceTree = ""; 156 | }; 157 | 3980FC781CB92F520091D322 /* Source */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | 3980FC791CB92F620091D322 /* BinaryData.swift */, 161 | 3980FC7A1CB92F620091D322 /* BinaryDataErrors.swift */, 162 | 3980FC7B1CB92F620091D322 /* BinaryDataReader.swift */, 163 | 3980FC7C1CB92F620091D322 /* Common.swift */, 164 | 3980FC7D1CB92F620091D322 /* IntegerType.swift */, 165 | 3980FC7E1CB92F620091D322 /* Tuple.swift */, 166 | ); 167 | name = Source; 168 | sourceTree = ""; 169 | }; 170 | 3980FC8B1CB92F840091D322 /* BinarySwift_iOS */ = { 171 | isa = PBXGroup; 172 | children = ( 173 | 3980FC8C1CB92F840091D322 /* BinarySwift_iOS.h */, 174 | 3980FC8E1CB92F840091D322 /* Info.plist */, 175 | ); 176 | path = BinarySwift_iOS; 177 | sourceTree = ""; 178 | }; 179 | 39EE444F1CBC542700C947A9 /* BinarySwiftTests_iOS */ = { 180 | isa = PBXGroup; 181 | children = ( 182 | 39EE44521CBC542700C947A9 /* Info.plist */, 183 | ); 184 | path = BinarySwiftTests_iOS; 185 | sourceTree = ""; 186 | }; 187 | /* End PBXGroup section */ 188 | 189 | /* Begin PBXHeadersBuildPhase section */ 190 | 3980FC6A1CB92F2C0091D322 /* Headers */ = { 191 | isa = PBXHeadersBuildPhase; 192 | buildActionMask = 2147483647; 193 | files = ( 194 | 3980FC711CB92F2C0091D322 /* BinarySwift_OSX.h in Headers */, 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | }; 198 | 3980FC871CB92F840091D322 /* Headers */ = { 199 | isa = PBXHeadersBuildPhase; 200 | buildActionMask = 2147483647; 201 | files = ( 202 | 3980FC8D1CB92F840091D322 /* BinarySwift_iOS.h in Headers */, 203 | ); 204 | runOnlyForDeploymentPostprocessing = 0; 205 | }; 206 | /* End PBXHeadersBuildPhase section */ 207 | 208 | /* Begin PBXNativeTarget section */ 209 | 2009DE421CBBC98200A4BC50 /* BinarySwiftTests_OSX */ = { 210 | isa = PBXNativeTarget; 211 | buildConfigurationList = 2009DE4D1CBBC98200A4BC50 /* Build configuration list for PBXNativeTarget "BinarySwiftTests_OSX" */; 212 | buildPhases = ( 213 | 2009DE3F1CBBC98200A4BC50 /* Sources */, 214 | 2009DE401CBBC98200A4BC50 /* Frameworks */, 215 | 2009DE411CBBC98200A4BC50 /* Resources */, 216 | ); 217 | buildRules = ( 218 | ); 219 | dependencies = ( 220 | 2009DE4A1CBBC98200A4BC50 /* PBXTargetDependency */, 221 | ); 222 | name = BinarySwiftTests_OSX; 223 | productName = BinarySwiftTests_OSX; 224 | productReference = 2009DE431CBBC98200A4BC50 /* BinarySwiftTests_OSX.xctest */; 225 | productType = "com.apple.product-type.bundle.unit-test"; 226 | }; 227 | 3980FC6C1CB92F2C0091D322 /* BinarySwift_OSX */ = { 228 | isa = PBXNativeTarget; 229 | buildConfigurationList = 3980FC751CB92F2C0091D322 /* Build configuration list for PBXNativeTarget "BinarySwift_OSX" */; 230 | buildPhases = ( 231 | 3980FC681CB92F2C0091D322 /* Sources */, 232 | 3980FC691CB92F2C0091D322 /* Frameworks */, 233 | 3980FC6A1CB92F2C0091D322 /* Headers */, 234 | 3980FC6B1CB92F2C0091D322 /* Resources */, 235 | ); 236 | buildRules = ( 237 | ); 238 | dependencies = ( 239 | ); 240 | name = BinarySwift_OSX; 241 | productName = BinarySwift; 242 | productReference = 3980FC6D1CB92F2C0091D322 /* BinarySwift.framework */; 243 | productType = "com.apple.product-type.framework"; 244 | }; 245 | 3980FC891CB92F840091D322 /* BinarySwift_iOS */ = { 246 | isa = PBXNativeTarget; 247 | buildConfigurationList = 3980FC8F1CB92F840091D322 /* Build configuration list for PBXNativeTarget "BinarySwift_iOS" */; 248 | buildPhases = ( 249 | 3980FC851CB92F840091D322 /* Sources */, 250 | 3980FC861CB92F840091D322 /* Frameworks */, 251 | 3980FC871CB92F840091D322 /* Headers */, 252 | 3980FC881CB92F840091D322 /* Resources */, 253 | ); 254 | buildRules = ( 255 | ); 256 | dependencies = ( 257 | ); 258 | name = BinarySwift_iOS; 259 | productName = BinarySwift_iOS; 260 | productReference = 3980FC8A1CB92F840091D322 /* BinarySwift.framework */; 261 | productType = "com.apple.product-type.framework"; 262 | }; 263 | 39EE444D1CBC542600C947A9 /* BinarySwiftTests_iOS */ = { 264 | isa = PBXNativeTarget; 265 | buildConfigurationList = 39EE44561CBC542700C947A9 /* Build configuration list for PBXNativeTarget "BinarySwiftTests_iOS" */; 266 | buildPhases = ( 267 | 39EE444A1CBC542600C947A9 /* Sources */, 268 | 39EE444B1CBC542600C947A9 /* Frameworks */, 269 | 39EE444C1CBC542600C947A9 /* Resources */, 270 | ); 271 | buildRules = ( 272 | ); 273 | dependencies = ( 274 | 39EE44551CBC542700C947A9 /* PBXTargetDependency */, 275 | ); 276 | name = BinarySwiftTests_iOS; 277 | productName = BinarySwiftTests_iOS; 278 | productReference = 39EE444E1CBC542600C947A9 /* BinarySwiftTests_iOS.xctest */; 279 | productType = "com.apple.product-type.bundle.unit-test"; 280 | }; 281 | /* End PBXNativeTarget section */ 282 | 283 | /* Begin PBXProject section */ 284 | 3980FC641CB92F2C0091D322 /* Project object */ = { 285 | isa = PBXProject; 286 | attributes = { 287 | LastSwiftUpdateCheck = 0730; 288 | LastUpgradeCheck = 0920; 289 | ORGANIZATIONNAME = "Spinal Development.com"; 290 | TargetAttributes = { 291 | 2009DE421CBBC98200A4BC50 = { 292 | CreatedOnToolsVersion = 7.3; 293 | LastSwiftMigration = 0830; 294 | }; 295 | 3980FC6C1CB92F2C0091D322 = { 296 | CreatedOnToolsVersion = 7.3; 297 | LastSwiftMigration = 0830; 298 | }; 299 | 3980FC891CB92F840091D322 = { 300 | CreatedOnToolsVersion = 7.3; 301 | LastSwiftMigration = 1130; 302 | }; 303 | 39EE444D1CBC542600C947A9 = { 304 | CreatedOnToolsVersion = 7.3; 305 | LastSwiftMigration = 0830; 306 | }; 307 | }; 308 | }; 309 | buildConfigurationList = 3980FC671CB92F2C0091D322 /* Build configuration list for PBXProject "BinarySwift" */; 310 | compatibilityVersion = "Xcode 3.2"; 311 | developmentRegion = English; 312 | hasScannedForEncodings = 0; 313 | knownRegions = ( 314 | English, 315 | en, 316 | ); 317 | mainGroup = 3980FC631CB92F2C0091D322; 318 | productRefGroup = 3980FC6E1CB92F2C0091D322 /* Products */; 319 | projectDirPath = ""; 320 | projectRoot = ""; 321 | targets = ( 322 | 3980FC6C1CB92F2C0091D322 /* BinarySwift_OSX */, 323 | 3980FC891CB92F840091D322 /* BinarySwift_iOS */, 324 | 2009DE421CBBC98200A4BC50 /* BinarySwiftTests_OSX */, 325 | 39EE444D1CBC542600C947A9 /* BinarySwiftTests_iOS */, 326 | ); 327 | }; 328 | /* End PBXProject section */ 329 | 330 | /* Begin PBXResourcesBuildPhase section */ 331 | 2009DE411CBBC98200A4BC50 /* Resources */ = { 332 | isa = PBXResourcesBuildPhase; 333 | buildActionMask = 2147483647; 334 | files = ( 335 | ); 336 | runOnlyForDeploymentPostprocessing = 0; 337 | }; 338 | 3980FC6B1CB92F2C0091D322 /* Resources */ = { 339 | isa = PBXResourcesBuildPhase; 340 | buildActionMask = 2147483647; 341 | files = ( 342 | ); 343 | runOnlyForDeploymentPostprocessing = 0; 344 | }; 345 | 3980FC881CB92F840091D322 /* Resources */ = { 346 | isa = PBXResourcesBuildPhase; 347 | buildActionMask = 2147483647; 348 | files = ( 349 | ); 350 | runOnlyForDeploymentPostprocessing = 0; 351 | }; 352 | 39EE444C1CBC542600C947A9 /* Resources */ = { 353 | isa = PBXResourcesBuildPhase; 354 | buildActionMask = 2147483647; 355 | files = ( 356 | ); 357 | runOnlyForDeploymentPostprocessing = 0; 358 | }; 359 | /* End PBXResourcesBuildPhase section */ 360 | 361 | /* Begin PBXSourcesBuildPhase section */ 362 | 2009DE3F1CBBC98200A4BC50 /* Sources */ = { 363 | isa = PBXSourcesBuildPhase; 364 | buildActionMask = 2147483647; 365 | files = ( 366 | 2009DE521CBBCA1800A4BC50 /* BinaryDataTests.swift in Sources */, 367 | 2009DE561CBD2ED000A4BC50 /* BinaryDataReaderTests.swift in Sources */, 368 | ); 369 | runOnlyForDeploymentPostprocessing = 0; 370 | }; 371 | 3980FC681CB92F2C0091D322 /* Sources */ = { 372 | isa = PBXSourcesBuildPhase; 373 | buildActionMask = 2147483647; 374 | files = ( 375 | 3980FC821CB92F620091D322 /* Common.swift in Sources */, 376 | 3980FC811CB92F620091D322 /* BinaryDataReader.swift in Sources */, 377 | 3980FC7F1CB92F620091D322 /* BinaryData.swift in Sources */, 378 | 3980FC801CB92F620091D322 /* BinaryDataErrors.swift in Sources */, 379 | 3980FC841CB92F620091D322 /* Tuple.swift in Sources */, 380 | 3980FC831CB92F620091D322 /* IntegerType.swift in Sources */, 381 | ); 382 | runOnlyForDeploymentPostprocessing = 0; 383 | }; 384 | 3980FC851CB92F840091D322 /* Sources */ = { 385 | isa = PBXSourcesBuildPhase; 386 | buildActionMask = 2147483647; 387 | files = ( 388 | 3980FC921CB92F920091D322 /* BinaryData.swift in Sources */, 389 | 3980FC931CB92F920091D322 /* BinaryDataErrors.swift in Sources */, 390 | 3980FC941CB92F920091D322 /* BinaryDataReader.swift in Sources */, 391 | 3980FC951CB92F920091D322 /* Common.swift in Sources */, 392 | 3980FC961CB92F920091D322 /* IntegerType.swift in Sources */, 393 | 3980FC971CB92F920091D322 /* Tuple.swift in Sources */, 394 | ); 395 | runOnlyForDeploymentPostprocessing = 0; 396 | }; 397 | 39EE444A1CBC542600C947A9 /* Sources */ = { 398 | isa = PBXSourcesBuildPhase; 399 | buildActionMask = 2147483647; 400 | files = ( 401 | 39EE44591CBC553B00C947A9 /* BinaryDataTests.swift in Sources */, 402 | 2009DE571CBD2ED000A4BC50 /* BinaryDataReaderTests.swift in Sources */, 403 | ); 404 | runOnlyForDeploymentPostprocessing = 0; 405 | }; 406 | /* End PBXSourcesBuildPhase section */ 407 | 408 | /* Begin PBXTargetDependency section */ 409 | 2009DE4A1CBBC98200A4BC50 /* PBXTargetDependency */ = { 410 | isa = PBXTargetDependency; 411 | target = 3980FC6C1CB92F2C0091D322 /* BinarySwift_OSX */; 412 | targetProxy = 2009DE491CBBC98200A4BC50 /* PBXContainerItemProxy */; 413 | }; 414 | 39EE44551CBC542700C947A9 /* PBXTargetDependency */ = { 415 | isa = PBXTargetDependency; 416 | target = 3980FC891CB92F840091D322 /* BinarySwift_iOS */; 417 | targetProxy = 39EE44541CBC542700C947A9 /* PBXContainerItemProxy */; 418 | }; 419 | /* End PBXTargetDependency section */ 420 | 421 | /* Begin XCBuildConfiguration section */ 422 | 2009DE4B1CBBC98200A4BC50 /* Debug */ = { 423 | isa = XCBuildConfiguration; 424 | buildSettings = { 425 | COMBINE_HIDPI_IMAGES = YES; 426 | INFOPLIST_FILE = BinarySwiftTests_OSX/Info.plist; 427 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 428 | PRODUCT_BUNDLE_IDENTIFIER = "com.macoscope.BinarySwiftTests-OSX"; 429 | PRODUCT_NAME = "$(TARGET_NAME)"; 430 | SWIFT_VERSION = 3.0; 431 | }; 432 | name = Debug; 433 | }; 434 | 2009DE4C1CBBC98200A4BC50 /* Release */ = { 435 | isa = XCBuildConfiguration; 436 | buildSettings = { 437 | COMBINE_HIDPI_IMAGES = YES; 438 | INFOPLIST_FILE = BinarySwiftTests_OSX/Info.plist; 439 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/../Frameworks"; 440 | PRODUCT_BUNDLE_IDENTIFIER = "com.macoscope.BinarySwiftTests-OSX"; 441 | PRODUCT_NAME = "$(TARGET_NAME)"; 442 | SWIFT_VERSION = 3.0; 443 | }; 444 | name = Release; 445 | }; 446 | 3980FC731CB92F2C0091D322 /* Debug */ = { 447 | isa = XCBuildConfiguration; 448 | buildSettings = { 449 | ALWAYS_SEARCH_USER_PATHS = NO; 450 | CLANG_ANALYZER_NONNULL = YES; 451 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 452 | CLANG_CXX_LIBRARY = "libc++"; 453 | CLANG_ENABLE_MODULES = YES; 454 | CLANG_ENABLE_OBJC_ARC = YES; 455 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 456 | CLANG_WARN_BOOL_CONVERSION = YES; 457 | CLANG_WARN_COMMA = YES; 458 | CLANG_WARN_CONSTANT_CONVERSION = YES; 459 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 460 | CLANG_WARN_EMPTY_BODY = YES; 461 | CLANG_WARN_ENUM_CONVERSION = YES; 462 | CLANG_WARN_INFINITE_RECURSION = YES; 463 | CLANG_WARN_INT_CONVERSION = YES; 464 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 465 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 466 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 467 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 468 | CLANG_WARN_STRICT_PROTOTYPES = YES; 469 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 470 | CLANG_WARN_UNREACHABLE_CODE = YES; 471 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 472 | CODE_SIGN_IDENTITY = "-"; 473 | COPY_PHASE_STRIP = NO; 474 | CURRENT_PROJECT_VERSION = 1; 475 | DEBUG_INFORMATION_FORMAT = dwarf; 476 | ENABLE_STRICT_OBJC_MSGSEND = YES; 477 | ENABLE_TESTABILITY = YES; 478 | GCC_C_LANGUAGE_STANDARD = gnu99; 479 | GCC_DYNAMIC_NO_PIC = NO; 480 | GCC_NO_COMMON_BLOCKS = YES; 481 | GCC_OPTIMIZATION_LEVEL = 0; 482 | GCC_PREPROCESSOR_DEFINITIONS = ( 483 | "DEBUG=1", 484 | "$(inherited)", 485 | ); 486 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 487 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 488 | GCC_WARN_UNDECLARED_SELECTOR = YES; 489 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 490 | GCC_WARN_UNUSED_FUNCTION = YES; 491 | GCC_WARN_UNUSED_VARIABLE = YES; 492 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 493 | MACOSX_DEPLOYMENT_TARGET = 10.9; 494 | MTL_ENABLE_DEBUG_INFO = YES; 495 | ONLY_ACTIVE_ARCH = YES; 496 | SDKROOT = macosx; 497 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 498 | VERSIONING_SYSTEM = "apple-generic"; 499 | VERSION_INFO_PREFIX = ""; 500 | }; 501 | name = Debug; 502 | }; 503 | 3980FC741CB92F2C0091D322 /* Release */ = { 504 | isa = XCBuildConfiguration; 505 | buildSettings = { 506 | ALWAYS_SEARCH_USER_PATHS = NO; 507 | CLANG_ANALYZER_NONNULL = YES; 508 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 509 | CLANG_CXX_LIBRARY = "libc++"; 510 | CLANG_ENABLE_MODULES = YES; 511 | CLANG_ENABLE_OBJC_ARC = YES; 512 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 513 | CLANG_WARN_BOOL_CONVERSION = YES; 514 | CLANG_WARN_COMMA = YES; 515 | CLANG_WARN_CONSTANT_CONVERSION = YES; 516 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 517 | CLANG_WARN_EMPTY_BODY = YES; 518 | CLANG_WARN_ENUM_CONVERSION = YES; 519 | CLANG_WARN_INFINITE_RECURSION = YES; 520 | CLANG_WARN_INT_CONVERSION = YES; 521 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 522 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 523 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 524 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 525 | CLANG_WARN_STRICT_PROTOTYPES = YES; 526 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 527 | CLANG_WARN_UNREACHABLE_CODE = YES; 528 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 529 | CODE_SIGN_IDENTITY = "-"; 530 | COPY_PHASE_STRIP = NO; 531 | CURRENT_PROJECT_VERSION = 1; 532 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 533 | ENABLE_NS_ASSERTIONS = NO; 534 | ENABLE_STRICT_OBJC_MSGSEND = YES; 535 | GCC_C_LANGUAGE_STANDARD = gnu99; 536 | GCC_NO_COMMON_BLOCKS = YES; 537 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 538 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 539 | GCC_WARN_UNDECLARED_SELECTOR = YES; 540 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 541 | GCC_WARN_UNUSED_FUNCTION = YES; 542 | GCC_WARN_UNUSED_VARIABLE = YES; 543 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 544 | MACOSX_DEPLOYMENT_TARGET = 10.9; 545 | MTL_ENABLE_DEBUG_INFO = NO; 546 | SDKROOT = macosx; 547 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 548 | VERSIONING_SYSTEM = "apple-generic"; 549 | VERSION_INFO_PREFIX = ""; 550 | }; 551 | name = Release; 552 | }; 553 | 3980FC761CB92F2C0091D322 /* Debug */ = { 554 | isa = XCBuildConfiguration; 555 | buildSettings = { 556 | CLANG_ENABLE_MODULES = YES; 557 | COMBINE_HIDPI_IMAGES = YES; 558 | DEFINES_MODULE = YES; 559 | DYLIB_COMPATIBILITY_VERSION = 1; 560 | DYLIB_CURRENT_VERSION = 1; 561 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 562 | FRAMEWORK_VERSION = A; 563 | INFOPLIST_FILE = BinarySwift/Info.plist; 564 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 565 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 566 | PRODUCT_BUNDLE_IDENTIFIER = com.spinaldevelopment.BinarySwift; 567 | PRODUCT_NAME = BinarySwift; 568 | SKIP_INSTALL = YES; 569 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 570 | SWIFT_VERSION = 4.0; 571 | }; 572 | name = Debug; 573 | }; 574 | 3980FC771CB92F2C0091D322 /* Release */ = { 575 | isa = XCBuildConfiguration; 576 | buildSettings = { 577 | CLANG_ENABLE_MODULES = YES; 578 | COMBINE_HIDPI_IMAGES = YES; 579 | DEFINES_MODULE = YES; 580 | DYLIB_COMPATIBILITY_VERSION = 1; 581 | DYLIB_CURRENT_VERSION = 1; 582 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 583 | FRAMEWORK_VERSION = A; 584 | GCC_OPTIMIZATION_LEVEL = fast; 585 | INFOPLIST_FILE = BinarySwift/Info.plist; 586 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 587 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; 588 | PRODUCT_BUNDLE_IDENTIFIER = com.spinaldevelopment.BinarySwift; 589 | PRODUCT_NAME = BinarySwift; 590 | SKIP_INSTALL = YES; 591 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 592 | SWIFT_VERSION = 4.0; 593 | }; 594 | name = Release; 595 | }; 596 | 3980FC901CB92F840091D322 /* Debug */ = { 597 | isa = XCBuildConfiguration; 598 | buildSettings = { 599 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 600 | DEFINES_MODULE = YES; 601 | DYLIB_COMPATIBILITY_VERSION = 1; 602 | DYLIB_CURRENT_VERSION = 1; 603 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 604 | INFOPLIST_FILE = BinarySwift_iOS/Info.plist; 605 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 606 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 607 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 608 | PRODUCT_BUNDLE_IDENTIFIER = "com.spinaldevelopment.BinarySwift-iOS"; 609 | PRODUCT_NAME = BinarySwift; 610 | SDKROOT = iphoneos; 611 | SKIP_INSTALL = YES; 612 | SWIFT_VERSION = 5.0; 613 | TARGETED_DEVICE_FAMILY = "1,2"; 614 | }; 615 | name = Debug; 616 | }; 617 | 3980FC911CB92F840091D322 /* Release */ = { 618 | isa = XCBuildConfiguration; 619 | buildSettings = { 620 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 621 | DEFINES_MODULE = YES; 622 | DYLIB_COMPATIBILITY_VERSION = 1; 623 | DYLIB_CURRENT_VERSION = 1; 624 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 625 | GCC_OPTIMIZATION_LEVEL = fast; 626 | INFOPLIST_FILE = BinarySwift_iOS/Info.plist; 627 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 628 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 629 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 630 | PRODUCT_BUNDLE_IDENTIFIER = "com.spinaldevelopment.BinarySwift-iOS"; 631 | PRODUCT_NAME = BinarySwift; 632 | SDKROOT = iphoneos; 633 | SKIP_INSTALL = YES; 634 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 635 | SWIFT_VERSION = 5.0; 636 | TARGETED_DEVICE_FAMILY = "1,2"; 637 | VALIDATE_PRODUCT = YES; 638 | }; 639 | name = Release; 640 | }; 641 | 39EE44571CBC542700C947A9 /* Debug */ = { 642 | isa = XCBuildConfiguration; 643 | buildSettings = { 644 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 645 | INFOPLIST_FILE = BinarySwiftTests_iOS/Info.plist; 646 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 647 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 648 | PRODUCT_BUNDLE_IDENTIFIER = "com.spinaldevelopment.BinarySwiftTests-iOS"; 649 | PRODUCT_NAME = "$(TARGET_NAME)"; 650 | SDKROOT = iphoneos; 651 | SWIFT_VERSION = 3.0; 652 | }; 653 | name = Debug; 654 | }; 655 | 39EE44581CBC542700C947A9 /* Release */ = { 656 | isa = XCBuildConfiguration; 657 | buildSettings = { 658 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 659 | INFOPLIST_FILE = BinarySwiftTests_iOS/Info.plist; 660 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 661 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 662 | PRODUCT_BUNDLE_IDENTIFIER = "com.spinaldevelopment.BinarySwiftTests-iOS"; 663 | PRODUCT_NAME = "$(TARGET_NAME)"; 664 | SDKROOT = iphoneos; 665 | SWIFT_VERSION = 3.0; 666 | VALIDATE_PRODUCT = YES; 667 | }; 668 | name = Release; 669 | }; 670 | /* End XCBuildConfiguration section */ 671 | 672 | /* Begin XCConfigurationList section */ 673 | 2009DE4D1CBBC98200A4BC50 /* Build configuration list for PBXNativeTarget "BinarySwiftTests_OSX" */ = { 674 | isa = XCConfigurationList; 675 | buildConfigurations = ( 676 | 2009DE4B1CBBC98200A4BC50 /* Debug */, 677 | 2009DE4C1CBBC98200A4BC50 /* Release */, 678 | ); 679 | defaultConfigurationIsVisible = 0; 680 | defaultConfigurationName = Release; 681 | }; 682 | 3980FC671CB92F2C0091D322 /* Build configuration list for PBXProject "BinarySwift" */ = { 683 | isa = XCConfigurationList; 684 | buildConfigurations = ( 685 | 3980FC731CB92F2C0091D322 /* Debug */, 686 | 3980FC741CB92F2C0091D322 /* Release */, 687 | ); 688 | defaultConfigurationIsVisible = 0; 689 | defaultConfigurationName = Release; 690 | }; 691 | 3980FC751CB92F2C0091D322 /* Build configuration list for PBXNativeTarget "BinarySwift_OSX" */ = { 692 | isa = XCConfigurationList; 693 | buildConfigurations = ( 694 | 3980FC761CB92F2C0091D322 /* Debug */, 695 | 3980FC771CB92F2C0091D322 /* Release */, 696 | ); 697 | defaultConfigurationIsVisible = 0; 698 | defaultConfigurationName = Release; 699 | }; 700 | 3980FC8F1CB92F840091D322 /* Build configuration list for PBXNativeTarget "BinarySwift_iOS" */ = { 701 | isa = XCConfigurationList; 702 | buildConfigurations = ( 703 | 3980FC901CB92F840091D322 /* Debug */, 704 | 3980FC911CB92F840091D322 /* Release */, 705 | ); 706 | defaultConfigurationIsVisible = 0; 707 | defaultConfigurationName = Release; 708 | }; 709 | 39EE44561CBC542700C947A9 /* Build configuration list for PBXNativeTarget "BinarySwiftTests_iOS" */ = { 710 | isa = XCConfigurationList; 711 | buildConfigurations = ( 712 | 39EE44571CBC542700C947A9 /* Debug */, 713 | 39EE44581CBC542700C947A9 /* Release */, 714 | ); 715 | defaultConfigurationIsVisible = 0; 716 | defaultConfigurationName = Release; 717 | }; 718 | /* End XCConfigurationList section */ 719 | }; 720 | rootObject = 3980FC641CB92F2C0091D322 /* Project object */; 721 | } 722 | --------------------------------------------------------------------------------