From 7564a4ebebdbad11532341cd053a2c80d4543731 Mon Sep 17 00:00:00 2001 From: Joe Newton <> Date: Wed, 12 Feb 2020 23:38:59 -0500 Subject: [PATCH] Added support for encoding/decoding Half-Precision floating point numbers --- .gitignore | 4 + .swiftlint.yml | 7 +- .travis.yml | 16 +- CBORCoding.podspec | 4 +- CBORCoding.xcodeproj/project.pbxproj | 156 +++++++++++++++++- .../xcschemes/CBORCoding macOS Tests.xcscheme | 8 +- .../xcschemes/CBORCoding macOS.xcscheme | 27 ++- .../xcschemes/CBORCoding tvOS Tests.xcscheme | 26 ++- .../xcschemes/CBORCoding tvOS.xcscheme | 27 ++- .../xcschemes/CBORCoding watchOS.xcscheme | 4 - .../xcschemes/CBORCoding.xcscheme | 27 ++- .../xcschemes/CBORCodingTests.xcscheme | 8 +- CBORCoding/CBORDecoder.swift | 31 +++- CBORCoding/CBOREncoder.swift | 10 ++ CBORCoding/CBORParser.swift | 44 ++--- CBORCodingTests/CBORDecoderTests.swift | 83 ++++++---- CBORCodingTests/CBOREncoderTests.swift | 23 +-- CBORCodingTests/CBORParserTests.swift | 67 ++++---- Cartfile | 1 + Cartfile.resolved | 1 + Package.swift | 6 +- README.md | 2 + 22 files changed, 392 insertions(+), 190 deletions(-) create mode 100644 Cartfile create mode 100644 Cartfile.resolved diff --git a/.gitignore b/.gitignore index c09916f..550c82f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,8 @@ CBORCoding.xcodeproj/project.xcworkspace CBORCoding.xcodeproj/xcuserdata +CBORCoding.xcworkspace/xcuserdata .build .swiftpm +IDEWorkspaceChecks.plist +Pods +Carthage diff --git a/.swiftlint.yml b/.swiftlint.yml index b9fc5e6..1caab9e 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -1,9 +1,10 @@ -disabled_rules: +disabled_rules: - file_length - line_length - cyclomatic_complexity - type_body_length - type_name + - function_body_length opt_in_rules: - anyobject_protocol @@ -58,6 +59,10 @@ opt_in_rules: - unneeded_parentheses_in_closure_argument - yoda_condition +excluded: + - Pods + - Carthage + reporter: "xcode" identifier_name: diff --git a/.travis.yml b/.travis.yml index 61ea86f..a7817bd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,19 @@ os: osx language: swift -osx_image: xcode10.2 +osx_image: xcode11.3 xcode_project: CBORCoding.xcodeproj +addons: + homebrew: + packages: + carthage script: - - set -o pipefail && travis_retry xcodebuild -scheme "CBORCoding" -destination "platform=iOS Simulator,name=iPhone XS Max" -configuration Debug ONLY_ACTIVE_ARCH=YES -enableCodeCoverage YES test - - set -o pipefail && travis_retry xcodebuild -scheme "CBORCoding tvOS" -destination "platform=tvOS Simulator,name=Apple TV 4K" -configuration Debug ONLY_ACTIVE_ARCH=YES -enableCodeCoverage YES test - - set -o pipefail && travis_retry xcodebuild -scheme "CBORCoding watchOS" -destination "platform=watchOS Simulator,name=Apple Watch Series 4 - 44mm" -configuration Debug ONLY_ACTIVE_ARCH=YES - - set -o pipefail && travis_retry xcodebuild -scheme "CBORCoding macOS" -destination "platform=macOS" -configuration Debug ONLY_ACTIVE_ARCH=YES -enableCodeCoverage YES test + - carthage bootstrap + + - set -o pipefail && travis_retry xcodebuild -scheme "CBORCodingTests" -destination "platform=iOS Simulator,name=iPhone 11 Pro Max" -configuration Debug ONLY_ACTIVE_ARCH=YES -enableCodeCoverage YES test + - set -o pipefail && travis_retry xcodebuild -scheme "CBORCoding macOS Tests" -destination "platform=macOS" -configuration Debug ONLY_ACTIVE_ARCH=YES -enableCodeCoverage YES test + - set -o pipefail && travis_retry xcodebuild -scheme "CBORCoding tvOS Tests" -destination "platform=tvOS Simulator,name=Apple TV 4K" -configuration Debug ONLY_ACTIVE_ARCH=YES -enableCodeCoverage YES test + - set -o pipefail && travis_retry xcodebuild -scheme "CBORCoding watchOS" -destination "platform=watchOS Simulator,name=Apple Watch Series 5 - 44mm" -configuration Debug ONLY_ACTIVE_ARCH=YES after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/CBORCoding.podspec b/CBORCoding.podspec index 2cb9c82..86a3c7a 100644 --- a/CBORCoding.podspec +++ b/CBORCoding.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "CBORCoding" - s.version = "1.0.6" + s.version = "1.1.0" s.summary = "A CBOR Encoder and Decoder" s.description = <<-DESC A lightweight framework containing a coder pair for encoding and decoding `Codable` conforming types to and from CBOR document format for iOS, macOS, tvOS, and watchOS. @@ -21,5 +21,7 @@ Pod::Spec.new do |s| s.frameworks = 'Foundation' s.swift_version = '5.0' s.requires_arc = true + + s.dependency 'Half', '~> 1.0' end diff --git a/CBORCoding.xcodeproj/project.pbxproj b/CBORCoding.xcodeproj/project.pbxproj index 44c4469..a6e0fba 100644 --- a/CBORCoding.xcodeproj/project.pbxproj +++ b/CBORCoding.xcodeproj/project.pbxproj @@ -61,11 +61,22 @@ DD32E378228DDCFB002D9067 /* CBOREncoderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD32E377228DDCFB002D9067 /* CBOREncoderTests.swift */; }; DD32E39B228DE3E2002D9067 /* CBOREncoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD32E39A228DE3E2002D9067 /* CBOREncoder.swift */; }; DD32E39D228E0EBA002D9067 /* CBOR.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD32E39C228E0EBA002D9067 /* CBOR.swift */; }; + DD3E07B923F48F5E00D1BBF8 /* Half.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD3E07B823F48F5E00D1BBF8 /* Half.framework */; }; + DD3E07BA23F48F5E00D1BBF8 /* Half.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DD3E07B823F48F5E00D1BBF8 /* Half.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + DD3E07BC23F48F7C00D1BBF8 /* Half.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD3E07BB23F48F7C00D1BBF8 /* Half.framework */; }; + DD3E07BD23F48F7C00D1BBF8 /* Half.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DD3E07BB23F48F7C00D1BBF8 /* Half.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + DD3E07BF23F48F8200D1BBF8 /* Half.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD3E07BE23F48F8200D1BBF8 /* Half.framework */; }; + DD3E07C023F48F8200D1BBF8 /* Half.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DD3E07BE23F48F8200D1BBF8 /* Half.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + DD3E07C223F48F8800D1BBF8 /* Half.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD3E07C123F48F8800D1BBF8 /* Half.framework */; }; + DD3E07C323F48F8800D1BBF8 /* Half.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = DD3E07C123F48F8800D1BBF8 /* Half.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + DD3E07C423F4920A00D1BBF8 /* Half.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD3E07B823F48F5E00D1BBF8 /* Half.framework */; }; DD957E6A22942D98000127A3 /* CBORTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD957E6922942D98000127A3 /* CBORTests.swift */; }; DD957E6C2296B63E000127A3 /* Containers.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD957E6B2296B63E000127A3 /* Containers.swift */; }; DD957E6E2296B6B7000127A3 /* ContainersTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD957E6D2296B6B7000127A3 /* ContainersTests.swift */; }; DD957E732296D514000127A3 /* CBORDecoderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD957E722296D514000127A3 /* CBORDecoderTests.swift */; }; DD957E9D2299CE1C000127A3 /* CBOR+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD957E9C2299CE1C000127A3 /* CBOR+Codable.swift */; }; + DDA0F92423F4924A00218569 /* Half.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD3E07BB23F48F7C00D1BBF8 /* Half.framework */; }; + DDA0F92523F4924F00218569 /* Half.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DD3E07BE23F48F8200D1BBF8 /* Half.framework */; }; DDA7181C22A017CF008C85B7 /* CBORDecoder.swift in Sources */ = {isa = PBXBuildFile; fileRef = DD32E383228DDD27002D9067 /* CBORDecoder.swift */; }; /* End PBXBuildFile section */ @@ -121,6 +132,53 @@ }; /* End PBXContainerItemProxy section */ +/* Begin PBXCopyFilesBuildPhase section */ + DD7B003323F46F08008AD6A7 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + DD3E07BA23F48F5E00D1BBF8 /* Half.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + DD7B003723F46F18008AD6A7 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + DD3E07BD23F48F7C00D1BBF8 /* Half.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + DD7B003B23F46F24008AD6A7 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + DD3E07C023F48F8200D1BBF8 /* Half.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + DD7B003F23F46F2E008AD6A7 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + DD3E07C323F48F8800D1BBF8 /* Half.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ DD0812F6229CD69B0003E3F6 /* CBORParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBORParser.swift; sourceTree = ""; }; DD0812F9229CE1840003E3F6 /* CBORParserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBORParserTests.swift; sourceTree = ""; }; @@ -143,6 +201,11 @@ DD32E383228DDD27002D9067 /* CBORDecoder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CBORDecoder.swift; sourceTree = ""; }; DD32E39A228DE3E2002D9067 /* CBOREncoder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBOREncoder.swift; sourceTree = ""; }; DD32E39C228E0EBA002D9067 /* CBOR.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBOR.swift; sourceTree = ""; }; + DD3E07B823F48F5E00D1BBF8 /* Half.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Half.framework; path = Carthage/Build/iOS/Half.framework; sourceTree = ""; }; + DD3E07BB23F48F7C00D1BBF8 /* Half.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Half.framework; path = Carthage/Build/Mac/Half.framework; sourceTree = ""; }; + DD3E07BE23F48F8200D1BBF8 /* Half.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Half.framework; path = Carthage/Build/tvOS/Half.framework; sourceTree = ""; }; + DD3E07C123F48F8800D1BBF8 /* Half.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Half.framework; path = Carthage/Build/watchOS/Half.framework; sourceTree = ""; }; + DD7BFFD823F4652B008AD6A7 /* Cartfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Cartfile; sourceTree = SOURCE_ROOT; }; DD957E6922942D98000127A3 /* CBORTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CBORTests.swift; sourceTree = ""; }; DD957E6B2296B63E000127A3 /* Containers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Containers.swift; sourceTree = ""; }; DD957E6D2296B6B7000127A3 /* ContainersTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContainersTests.swift; sourceTree = ""; }; @@ -157,6 +220,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DD3E07BC23F48F7C00D1BBF8 /* Half.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -165,6 +229,7 @@ buildActionMask = 2147483647; files = ( DD1298B122A563BE005CEB9A /* CBORCoding.framework in Frameworks */, + DDA0F92423F4924A00218569 /* Half.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -172,6 +237,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DD3E07BF23F48F8200D1BBF8 /* Half.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -180,6 +246,7 @@ buildActionMask = 2147483647; files = ( DD1298E922A56431005CEB9A /* CBORCoding.framework in Frameworks */, + DDA0F92523F4924F00218569 /* Half.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -187,6 +254,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DD3E07C223F48F8800D1BBF8 /* Half.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -194,6 +262,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + DD3E07B923F48F5E00D1BBF8 /* Half.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -202,6 +271,7 @@ buildActionMask = 2147483647; files = ( DD32E373228DDCFB002D9067 /* CBORCoding.framework in Frameworks */, + DD3E07C423F4920A00D1BBF8 /* Half.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -241,6 +311,7 @@ children = ( DD12989122A487FB005CEB9A /* CBORCoding.podspec */, DDF755AC22A8649F002E11D4 /* Package.swift */, + DD7BFFD823F4652B008AD6A7 /* Cartfile */, DD1298A122A546B4005CEB9A /* .swiftlint.yml */, DDF755AB22A80069002E11D4 /* .travis.yml */, DD12989322A487FB005CEB9A /* README.md */, @@ -257,6 +328,7 @@ DD32E36B228DDCFB002D9067 /* CBORCoding */, DD32E376228DDCFB002D9067 /* CBORCodingTests */, DD32E36A228DDCFB002D9067 /* Products */, + DD3E07B723F48F5E00D1BBF8 /* Frameworks */, ); sourceTree = ""; }; @@ -298,6 +370,17 @@ path = CBORCodingTests; sourceTree = ""; }; + DD3E07B723F48F5E00D1BBF8 /* Frameworks */ = { + isa = PBXGroup; + children = ( + DD3E07B823F48F5E00D1BBF8 /* Half.framework */, + DD3E07C123F48F8800D1BBF8 /* Half.framework */, + DD3E07BE23F48F8200D1BBF8 /* Half.framework */, + DD3E07BB23F48F7C00D1BBF8 /* Half.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -340,6 +423,7 @@ DD1298A422A563BE005CEB9A /* Sources */, DD1298A522A563BE005CEB9A /* Frameworks */, DD1298A622A563BE005CEB9A /* Resources */, + DD7B003723F46F18008AD6A7 /* Embed Frameworks */, ); buildRules = ( ); @@ -377,6 +461,7 @@ DD1298DC22A56430005CEB9A /* Sources */, DD1298DD22A56430005CEB9A /* Frameworks */, DD1298DE22A56430005CEB9A /* Resources */, + DD7B003B23F46F24008AD6A7 /* Embed Frameworks */, ); buildRules = ( ); @@ -414,6 +499,7 @@ DD1298FA22A5644C005CEB9A /* Sources */, DD1298FB22A5644C005CEB9A /* Frameworks */, DD1298FC22A5644C005CEB9A /* Resources */, + DD7B003F23F46F2E008AD6A7 /* Embed Frameworks */, ); buildRules = ( ); @@ -433,6 +519,7 @@ DD32E365228DDCFB002D9067 /* Sources */, DD32E366228DDCFB002D9067 /* Frameworks */, DD32E367228DDCFB002D9067 /* Resources */, + DD7B003323F46F08008AD6A7 /* Embed Frameworks */, ); buildRules = ( ); @@ -505,6 +592,7 @@ hasScannedForEncodings = 0; knownRegions = ( en, + Base, ); mainGroup = DD32E35F228DDCFB002D9067; productRefGroup = DD32E36A228DDCFB002D9067 /* Products */; @@ -758,6 +846,10 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/Mac", + ); FRAMEWORK_VERSION = A; INFOPLIST_FILE = CBORCoding/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -784,6 +876,10 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/Mac", + ); FRAMEWORK_VERSION = A; INFOPLIST_FILE = CBORCoding/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -803,15 +899,19 @@ DD1298BE22A563BE005CEB9A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/Mac", + ); INFOPLIST_FILE = CBORCodingTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", "@loader_path/../Frameworks", + "\"${PROJECT_DIR}/Carthage/Build/Mac\"", ); MACOSX_DEPLOYMENT_TARGET = 10.14; PRODUCT_BUNDLE_IDENTIFIER = com.somerandomiosdev.cborcodingtests; @@ -823,15 +923,19 @@ DD1298C022A563BE005CEB9A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_IDENTITY = "-"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/Mac", + ); INFOPLIST_FILE = CBORCodingTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", "@loader_path/../Frameworks", + "\"${PROJECT_DIR}/Carthage/Build/Mac\"", ); MACOSX_DEPLOYMENT_TARGET = 10.14; PRODUCT_BUNDLE_IDENTIFIER = com.somerandomiosdev.cborcodingtests; @@ -849,6 +953,10 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/tvOS", + ); INFOPLIST_FILE = CBORCoding/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( @@ -874,6 +982,10 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/tvOS", + ); INFOPLIST_FILE = CBORCoding/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( @@ -893,13 +1005,17 @@ DD1298F622A56431005CEB9A /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/tvOS", + ); INFOPLIST_FILE = CBORCodingTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", + "\"${PROJECT_DIR}/Carthage/Build/tvOS\"", ); PRODUCT_BUNDLE_IDENTIFIER = com.somerandomiosdev.cborcodingtests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -912,13 +1028,17 @@ DD1298F822A56431005CEB9A /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/tvOS", + ); INFOPLIST_FILE = CBORCodingTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", + "\"${PROJECT_DIR}/Carthage/Build/tvOS\"", ); PRODUCT_BUNDLE_IDENTIFIER = com.somerandomiosdev.cborcodingtests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -938,6 +1058,10 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/watchOS", + ); INFOPLIST_FILE = CBORCoding/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( @@ -964,6 +1088,10 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/watchOS", + ); INFOPLIST_FILE = CBORCoding/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( @@ -1122,6 +1250,10 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); INFOPLIST_FILE = CBORCoding/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( @@ -1147,6 +1279,10 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); INFOPLIST_FILE = CBORCoding/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( @@ -1164,13 +1300,17 @@ DD32E381228DDCFB002D9067 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); INFOPLIST_FILE = CBORCodingTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", + "\"${PROJECT_DIR}/Carthage/Build/iOS\"", ); PRODUCT_BUNDLE_IDENTIFIER = com.somerandomiosdev.cborcodingtests; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -1180,13 +1320,17 @@ DD32E382228DDCFB002D9067 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/Carthage/Build/iOS", + ); INFOPLIST_FILE = CBORCodingTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", "@loader_path/Frameworks", + "\"${PROJECT_DIR}/Carthage/Build/iOS\"", ); PRODUCT_BUNDLE_IDENTIFIER = com.somerandomiosdev.cborcodingtests; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/CBORCoding.xcodeproj/xcshareddata/xcschemes/CBORCoding macOS Tests.xcscheme b/CBORCoding.xcodeproj/xcshareddata/xcschemes/CBORCoding macOS Tests.xcscheme index 44abd29..0efe05b 100644 --- a/CBORCoding.xcodeproj/xcshareddata/xcschemes/CBORCoding macOS Tests.xcscheme +++ b/CBORCoding.xcodeproj/xcshareddata/xcschemes/CBORCoding macOS Tests.xcscheme @@ -10,9 +10,9 @@ buildConfiguration = "Debug" selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" + shouldUseLaunchSchemeArgsEnv = "YES" codeCoverageEnabled = "YES" - onlyGenerateCoverageForSpecifiedTargets = "YES" - shouldUseLaunchSchemeArgsEnv = "YES"> + onlyGenerateCoverageForSpecifiedTargets = "YES"> - - - - + shouldUseLaunchSchemeArgsEnv = "YES" + onlyGenerateCoverageForSpecifiedTargets = "YES"> + + + + - - - - - - - - + onlyGenerateCoverageForSpecifiedTargets = "YES"> + + + + - - - - - - - - + shouldUseLaunchSchemeArgsEnv = "YES" + onlyGenerateCoverageForSpecifiedTargets = "YES"> + + + + - - - - - - - - - - - - + shouldUseLaunchSchemeArgsEnv = "YES" + onlyGenerateCoverageForSpecifiedTargets = "YES"> + + + + - - - - - - - - + onlyGenerateCoverageForSpecifiedTargets = "YES"> - - - - (_ value: Any, as type: T.Type) throws -> T where T: BinaryFloatingPoint { let floatingPoint: T - if let float = value as? Float { + if let half = value as? Half { + if half.isNaN { + if half.isSignalingNaN { + floatingPoint = .signalingNaN + } else { + floatingPoint = .nan + } + } else { + guard let value = T(exactly: half) else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded CBOR number <\(half)> does not fit in \(type).")) + } + + floatingPoint = value + } + } else if let float = value as? Float { if float.isNaN { - floatingPoint = .nan + if float.isSignalingNaN { + floatingPoint = .signalingNaN + } else { + floatingPoint = .nan + } } else { guard let value = T(exactly: float) else { throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded CBOR number <\(float)> does not fit in \(type).")) @@ -378,7 +399,11 @@ internal class __CBORDecoder: Decoder, SingleValueDecodingContainer { } } else if let double = value as? Double { if double.isNaN { - floatingPoint = .nan + if double.isSignalingNaN { + floatingPoint = .signalingNaN + } else { + floatingPoint = .nan + } } else { guard let value = T(exactly: double) else { throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: codingPath, debugDescription: "Decoded CBOR number <\(double)> does not fit in \(type).")) diff --git a/CBORCoding/CBOREncoder.swift b/CBORCoding/CBOREncoder.swift index 44314bf..be760d9 100644 --- a/CBORCoding/CBOREncoder.swift +++ b/CBORCoding/CBOREncoder.swift @@ -7,6 +7,7 @@ // import Foundation +import Half #if canImport(Combine) import Combine @@ -208,6 +209,13 @@ open class CBOREncoder { return Data(bytes) } + internal static func encode(_ value: Half) -> Data { + var half = value + let data = Data(bytes: &half, count: MemoryLayout.size(ofValue: half)) + + return Data([CBOR.Bits.half.rawValue]) + data.reversed() + } + internal static func encode(_ value: Float) -> Data { var float = value let data = Data(bytes: &float, count: MemoryLayout.size(ofValue: float)) @@ -679,6 +687,8 @@ internal class __CBOREncoder: CBOREncoderProtocol, SingleValueEncodingContainer result = try encode(string) } else if let value = value as? CBOR.NegativeUInt64 { result = CBOREncoder.encode(value) + } else if let value = value as? Half { + result = CBOREncoder.encode(value) } else { let action: () throws -> Any? = { let depth = self.storage.count diff --git a/CBORCoding/CBORParser.swift b/CBORCoding/CBORParser.swift index f5c0424..584b009 100644 --- a/CBORCoding/CBORParser.swift +++ b/CBORCoding/CBORParser.swift @@ -7,6 +7,7 @@ // import Foundation +import Half // MARK: - CBORParser Definition @@ -225,7 +226,13 @@ internal class CBORParser { index += simple.decodedBytes - case 25, 26: // Decode Half-precision as Float + case 25: + let half = try decode(Half.self, from: Data(data[index...])) + try storage.append(half.value) + + index += half.decodedBytes + + case 26: let float = try decode(Float.self, from: Data(data[index...])) try storage.append(float.value) @@ -624,28 +631,19 @@ internal class CBORParser { if header == CBOR.Bits.half.rawValue { // Half if data.count >= 3 { // swiftlint:disable force_unwrapping - let half = data[1 ..< 3].reversed().withUnsafeBytes { $0.bindMemory(to: UInt16.self).baseAddress!.pointee } + let half = data[1 ..< 3].reversed().withUnsafeBytes { $0.bindMemory(to: Half.self).baseAddress!.pointee } // swiftlint:enable force_unwrapping - let sign = (half & 0x8000) != 0 ? FloatingPointSign.minus : .plus - let exponent = T.RawExponent((half & 0x7C00) >> 10) - let significand = T.RawSignificand((half & 0x03FF)) - - if exponent == 0 { - result = (T(sign: sign, - exponentBitPattern: exponent, - significandBitPattern: significand << (T.significandBitCount - 10)), 3) - } else if exponent == 0x1F { - if (half & 0x03FF) == 0 { - result = (sign == .minus ? -.infinity : .infinity, 3) + if half.isNaN { + if half.isSignalingNaN { + result = (.signalingNaN, 3) } else { result = (.nan, 3) } + } else if let value = T(exactly: half) { + result = (value, 3) } else { - let floatingBias = T.RawExponent((1 << (T.exponentBitCount - 1)) - 1) - let halfBias = T.RawExponent((1 << 4) - 1) - - result = (T(sign: sign, exponentBitPattern: exponent + floatingBias - halfBias, significandBitPattern: significand << (T.significandBitCount - 10)), 3) + throw CBOR.DecodingError.dataCorrupted(description: "Decoded number <\(half)> does not fit in \(type).") } } else { throw CBOR.DecodingError.insufficientEncodedBytes(expected: type) @@ -657,7 +655,11 @@ internal class CBORParser { // swiftlint:enable force_unwrapping if float.isNaN { - result = (.nan, 5) + if float.isSignalingNaN { + result = (.signalingNaN, 5) + } else { + result = (.nan, 5) + } } else if let value = T(exactly: float) { result = (value, 5) } else { @@ -673,7 +675,11 @@ internal class CBORParser { // swiftlint:enable force_unwrapping if double.isNaN { - result = (.nan, 9) + if double.isSignalingNaN { + result = (.signalingNaN, 9) + } else { + result = (.nan, 9) + } } else if let value = T(exactly: double) { result = (value, 9) } else { diff --git a/CBORCodingTests/CBORDecoderTests.swift b/CBORCodingTests/CBORDecoderTests.swift index 6f13898..592ec3b 100644 --- a/CBORCodingTests/CBORDecoderTests.swift +++ b/CBORCodingTests/CBORDecoderTests.swift @@ -9,6 +9,7 @@ // swiftlint:disable nesting function_body_length force_cast identifier_name opening_brace comma implicitly_unwrapped_optional number_separator force_unwrapping @testable import CBORCoding +import Half import XCTest // MARK: - CBORDecoderTests Definition @@ -82,23 +83,23 @@ class CBORDecoderTests: XCTestCase { XCTAssertNoThrow(value = try decoder.decode(Int64.self, from: convertFromHexString("0x3B7FFFFFFFFFFFFFFF"))) // NOT part of RFC 7049 examples XCTAssertEqual(value as! Int64, .min) - XCTAssertNoThrow(value = try decoder.decode(Float.self, from: convertFromHexString("0xF90000"))) // Half - XCTAssertEqual(value as! Float, 0.0) + XCTAssertNoThrow(value = try decoder.decode(Half.self, from: convertFromHexString("0xF90000"))) + XCTAssertEqual(value as! Half, 0.0) - XCTAssertNoThrow(value = try decoder.decode(Float.self, from: convertFromHexString("0xF98000"))) // Half - XCTAssertEqual(value as! Float, -0.0) + XCTAssertNoThrow(value = try decoder.decode(Half.self, from: convertFromHexString("0xF98000"))) + XCTAssertEqual(value as! Half, -0.0) - XCTAssertNoThrow(value = try decoder.decode(Float.self, from: convertFromHexString("0xF93C00"))) // Half - XCTAssertEqual(value as! Float, 1.0) + XCTAssertNoThrow(value = try decoder.decode(Half.self, from: convertFromHexString("0xF93C00"))) + XCTAssertEqual(value as! Half, 1.0) XCTAssertNoThrow(value = try decoder.decode(Double.self, from: convertFromHexString("0xFB3FF199999999999A"))) XCTAssertEqual(value as! Double, 1.1) - XCTAssertNoThrow(value = try decoder.decode(Float.self, from: convertFromHexString("0xF93E00"))) // Half - XCTAssertEqual(value as! Float, 1.5) + XCTAssertNoThrow(value = try decoder.decode(Half.self, from: convertFromHexString("0xF93E00"))) + XCTAssertEqual(value as! Half, 1.5) - XCTAssertNoThrow(value = try decoder.decode(Float.self, from: convertFromHexString("0xF97BFF"))) // Half - XCTAssertEqual(value as! Float, 65504.0) + XCTAssertNoThrow(value = try decoder.decode(Half.self, from: convertFromHexString("0xF97BFF"))) + XCTAssertEqual(value as! Half, 65504.0) XCTAssertNoThrow(value = try decoder.decode(Float.self, from: convertFromHexString("0xFA47C35000"))) XCTAssertEqual(value as! Float, 100000.0) @@ -109,42 +110,60 @@ class CBORDecoderTests: XCTestCase { XCTAssertNoThrow(value = try decoder.decode(Double.self, from: convertFromHexString("0xFB7E37E43C8800759C"))) XCTAssertEqual(value as! Double, 1.0e+300) -// XCTAssertNoThrow(value = try decoder.decode(Float.self, from: convertFromHexString("0xF90001"))) // Half -// XCTAssertEqual(value as! Float, 5.960464477539063e-8) + XCTAssertNoThrow(value = try decoder.decode(Half.self, from: convertFromHexString("0xF90001"))) + XCTAssertEqual(value as! Half, 5.960464477539063e-8) - XCTAssertNoThrow(value = try decoder.decode(Float.self, from: convertFromHexString("0xF90400"))) // Half - XCTAssertEqual(value as! Float, 0.00006103515625) + XCTAssertNoThrow(value = try decoder.decode(Half.self, from: convertFromHexString("0xF90400"))) + XCTAssertEqual(value as! Half, 0.00006103515625) - XCTAssertNoThrow(value = try decoder.decode(Float.self, from: convertFromHexString("0xF9C400"))) // Half - XCTAssertEqual(value as! Float, -4.0) + XCTAssertNoThrow(value = try decoder.decode(Half.self, from: convertFromHexString("0xF9C400"))) + XCTAssertEqual(value as! Half, -4.0) XCTAssertNoThrow(value = try decoder.decode(Double.self, from: convertFromHexString("0xFBC010666666666666"))) XCTAssertEqual(value as! Double, -4.1) - XCTAssertNoThrow(value = try decoder.decode(Float.self, from: convertFromHexString("0xF97C00"))) // Half - XCTAssertEqual(value as! Float, .infinity) + // Half, Float, and Double should be able to decode each other's NaN values + for quietNaN in ["0xF97E00", "0xFA7FC00000", "0xFB7FF8000000000000"].map(convertFromHexString) { + XCTAssertNoThrow(value = try decoder.decode(Half.self, from: quietNaN)) + XCTAssertTrue((value as! Half).isNaN) + XCTAssertFalse((value as! Half).isSignalingNaN) - XCTAssertNoThrow(value = try decoder.decode(Float.self, from: convertFromHexString("0xF97E00"))) // Half - XCTAssertTrue((value as! Float).isNaN) + XCTAssertNoThrow(value = try decoder.decode(Float.self, from: quietNaN)) + XCTAssertTrue((value as! Float).isNaN) + XCTAssertFalse((value as! Float).isSignalingNaN) - XCTAssertNoThrow(value = try decoder.decode(Float.self, from: convertFromHexString("0xF9FC00"))) // Half - XCTAssertEqual(value as! Float, -.infinity) + XCTAssertNoThrow(value = try decoder.decode(Double.self, from: quietNaN)) + XCTAssertTrue((value as! Double).isNaN) + XCTAssertFalse((value as! Double).isSignalingNaN) + } + + // NOT part of RFC 7049 examples + for signalingNaN in ["0xF97D00", "0xFA7FA00000", "0xFB7FF4000000000000"].map(convertFromHexString) { + XCTAssertNoThrow(value = try decoder.decode(Half.self, from: signalingNaN)) + XCTAssertTrue((value as! Half).isSignalingNaN) + + XCTAssertNoThrow(value = try decoder.decode(Float.self, from: signalingNaN)) + XCTAssertTrue((value as! Float).isSignalingNaN) + + XCTAssertNoThrow(value = try decoder.decode(Double.self, from: signalingNaN)) + XCTAssertTrue((value as! Double).isSignalingNaN) + } + + XCTAssertNoThrow(value = try decoder.decode(Half.self, from: convertFromHexString("0xF97C00"))) + XCTAssertEqual(value as! Half, .infinity) + + XCTAssertNoThrow(value = try decoder.decode(Half.self, from: convertFromHexString("0xF9FC00"))) + XCTAssertEqual(value as! Half, -.infinity) XCTAssertNoThrow(value = try decoder.decode(Float.self, from: convertFromHexString("0xFA7F800000"))) XCTAssertEqual(value as! Float, .infinity) - XCTAssertNoThrow(value = try decoder.decode(Float.self, from: convertFromHexString("0xFA7FC00000"))) - XCTAssertTrue((value as! Float).isNaN) - XCTAssertNoThrow(value = try decoder.decode(Float.self, from: convertFromHexString("0xFAFF800000"))) XCTAssertEqual(value as! Float, -.infinity) XCTAssertNoThrow(value = try decoder.decode(Double.self, from: convertFromHexString("0xFB7FF0000000000000"))) XCTAssertEqual(value as! Double, .infinity) - XCTAssertNoThrow(value = try decoder.decode(Double.self, from: convertFromHexString("0xFB7FF8000000000000"))) - XCTAssertTrue((value as! Double).isNaN) - XCTAssertNoThrow(value = try decoder.decode(Double.self, from: convertFromHexString("0xFBFFF0000000000000"))) XCTAssertEqual(value as! Double, -.infinity) @@ -695,6 +714,8 @@ class CBORDecoderTests: XCTestCase { TestDecodeSingleValue.decode(from: convertFromHexString("0x3BFFFFFFFFFFFFFFFE")) { try $0.decode(UInt64.self) } // Decode unsigned from large signed TestDecodeSingleValue.decode(from: convertFromHexString("0x01")) { try $0.decode(String.self) } // Decode string from other type TestDecodeSingleValue.decode(from: convertFromHexString("0xFB3FF199999999999A")) { try $0.decode(Float.self) } // Precise Double into Float + TestDecodeSingleValue.decode(from: convertFromHexString("0xFB3FF199999999999A")) { try $0.decode(Float.self) } // Precise Double into Half + TestDecodeSingleValue.decode(from: convertFromHexString("0xFA3F8CCCCD")) { try $0.decode(Half.self) } // Precise Float into Half } func testDecodeStringKeyedValues() { @@ -721,7 +742,7 @@ class CBORDecoderTests: XCTestCase { XCTAssertEqual(try container.decode(UInt16.self, forKey: .l), 25091) XCTAssertEqual(try container.decode(UInt32.self, forKey: .m), 2354019811) XCTAssertEqual(try container.decode(UInt64.self, forKey: .n), .max) - XCTAssertEqual(try container.decode(Float.self, forKey: .o), 1.0) + XCTAssertEqual(try container.decode(Half.self, forKey: .o), 1.0) XCTAssertEqual(try container.decode(Float.self, forKey: .p), 100000.0) XCTAssertEqual(try container.decode(Double.self, forKey: .q), 1.1) XCTAssertEqual(try container.decode(String.self, forKey: .r), "CBOR") @@ -770,7 +791,7 @@ class CBORDecoderTests: XCTestCase { XCTAssertEqual(try container.decode(UInt16.self, forKey: .l), 25091) XCTAssertEqual(try container.decode(UInt32.self, forKey: .m), 2354019811) XCTAssertEqual(try container.decode(UInt64.self, forKey: .n), .max) - XCTAssertEqual(try container.decode(Float.self, forKey: .o), 1.0) + XCTAssertEqual(try container.decode(Half.self, forKey: .o), 1.0) XCTAssertEqual(try container.decode(Float.self, forKey: .p), 100000.0) XCTAssertEqual(try container.decode(Double.self, forKey: .q), 1.1) XCTAssertEqual(try container.decode(String.self, forKey: .r), "CBOR") @@ -857,7 +878,7 @@ class CBORDecoderTests: XCTestCase { XCTAssertEqual(try container.decode(UInt16.self), 25091) XCTAssertEqual(try container.decode(UInt32.self), 2354019811) XCTAssertEqual(try container.decode(UInt64.self), .max) - XCTAssertEqual(try container.decode(Float.self), 1.0) + XCTAssertEqual(try container.decode(Half.self), 1.0) XCTAssertEqual(try container.decode(Float.self), 100000.0) XCTAssertEqual(try container.decode(Double.self), 1.1) XCTAssertEqual(try container.decode(String.self), "CBOR") diff --git a/CBORCodingTests/CBOREncoderTests.swift b/CBORCodingTests/CBOREncoderTests.swift index 68e6a05..c39ccab 100644 --- a/CBORCodingTests/CBOREncoderTests.swift +++ b/CBORCodingTests/CBOREncoderTests.swift @@ -9,6 +9,7 @@ // swiftlint:disable comma nesting function_body_length identifier_name force_try force_cast number_separator force_unwrapping @testable import CBORCoding +import Half import XCTest // MARK: - CBORTests Definition @@ -45,22 +46,22 @@ class CBOREncoderTests: XCTestCase { (try! encoder.encode(Int64(-100)), "0x3863"), (try! encoder.encode(Int64(-1000)), "0x3903E7"), (try! encoder.encode(Int64.min), "0x3B7FFFFFFFFFFFFFFF"), // NOT part of RFC 7049 examples - // Half 0.0 - // Half -0.0 - // Half 1.0 + (try! encoder.encode(Half(0.0)), "0xF90000"), + (try! encoder.encode(Half(-0.0)), "0xF98000"), + (try! encoder.encode(Half(1.0)), "0xF93C00"), (try! encoder.encode(Double(1.1)), "0xFB3FF199999999999A"), - // Half 1.5 - // Half 65504.0 + (try! encoder.encode(Half(1.5)), "0xF93E00"), + (try! encoder.encode(Half(65504.0)), "0xF97BFF"), (try! encoder.encode(Float(100000.0)), "0xFA47C35000"), (try! encoder.encode(Float(3.4028234663852886e+38)), "0xFA7F7FFFFF"), (try! encoder.encode(Double(1.0e+300)), "0xFB7E37E43C8800759C"), - // Half 5.960464477539063e-8 - // Half 0.00006103515625 - // Half -4.0 + (try! encoder.encode(Half(5.960464477539063e-8)), "0xF90001"), + (try! encoder.encode(Half(0.00006103515625)), "0xF90400"), + (try! encoder.encode(Half(-4.0)), "0xF9C400"), (try! encoder.encode(Double(-4.1)), "0xFBC010666666666666"), - // Half .infinity - // Half .nan - // Half -.infinity + (try! encoder.encode(Half.infinity), "0xF97C00"), + (try! encoder.encode(Half.nan), "0xF97E00"), + (try! encoder.encode(-Half.infinity), "0xF9FC00"), (try! encoder.encode(Float.infinity), "0xFA7F800000"), (try! encoder.encode(Float.nan), "0xFA7FC00000"), (try! encoder.encode(-Float.infinity), "0xFAFF800000"), diff --git a/CBORCodingTests/CBORParserTests.swift b/CBORCodingTests/CBORParserTests.swift index 4b0420f..5043561 100644 --- a/CBORCodingTests/CBORParserTests.swift +++ b/CBORCodingTests/CBORParserTests.swift @@ -9,6 +9,7 @@ // swiftlint:disable function_body_length force_cast comma force_try implicitly_unwrapped_optional number_separator force_unwrapping @testable import CBORCoding +import Half import XCTest // MARK: - CBORParserTests Definition @@ -100,29 +101,29 @@ class CBORParserTests: XCTestCase { XCTAssertTrue(value is Int64) XCTAssertEqual(value as! Int64, .min) - XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF90000"))) // Half - XCTAssertTrue(value is Float) - XCTAssertEqual(value as! Float, 0.0) + XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF90000"))) + XCTAssertTrue(value is Half) + XCTAssertEqual(value as! Half, 0.0) - XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF98000"))) // Half - XCTAssertTrue(value is Float) - XCTAssertEqual(value as! Float, -0.0) + XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF98000"))) + XCTAssertTrue(value is Half) + XCTAssertEqual(value as! Half, -0.0) - XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF93C00"))) // Half - XCTAssertTrue(value is Float) - XCTAssertEqual(value as! Float, 1.0) + XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF93C00"))) + XCTAssertTrue(value is Half) + XCTAssertEqual(value as! Half, 1.0) XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xFB3FF199999999999A"))) XCTAssertTrue(value is Double) XCTAssertEqual(value as! Double, 1.1) - XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF93E00"))) // Half - XCTAssertTrue(value is Float) - XCTAssertEqual(value as! Float, 1.5) + XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF93E00"))) + XCTAssertTrue(value is Half) + XCTAssertEqual(value as! Half, 1.5) - XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF97BFF"))) // Half - XCTAssertTrue(value is Float) - XCTAssertEqual(value as! Float, 65504.0) + XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF97BFF"))) + XCTAssertTrue(value is Half) + XCTAssertEqual(value as! Half, 65504.0) XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xFA47C35000"))) XCTAssertTrue(value is Float) @@ -136,33 +137,33 @@ class CBORParserTests: XCTestCase { XCTAssertTrue(value is Double) XCTAssertEqual(value as! Double, 1.0e+300) -// XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF90001"))) // Half -// XCTAssertTrue(value is Float) -// XCTAssertEqual(value as! Float, 5.960464477539063e-8) + XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF90001"))) + XCTAssertTrue(value is Half) + XCTAssertEqual(value as! Half, 5.960464477539063e-8) - XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF90400"))) // Half - XCTAssertTrue(value is Float) - XCTAssertEqual(value as! Float, 0.00006103515625) + XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF90400"))) + XCTAssertTrue(value is Half) + XCTAssertEqual(value as! Half, 0.00006103515625) - XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF9C400"))) // Half - XCTAssertTrue(value is Float) - XCTAssertEqual(value as! Float, -4.0) + XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF9C400"))) + XCTAssertTrue(value is Half) + XCTAssertEqual(value as! Half, -4.0) XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xFBC010666666666666"))) XCTAssertTrue(value is Double) XCTAssertEqual(value as! Double, -4.1) - XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF97C00"))) // Half - XCTAssertTrue(value is Float) - XCTAssertEqual(value as! Float, .infinity) + XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF97C00"))) + XCTAssertTrue(value is Half) + XCTAssertEqual(value as! Half, .infinity) - XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF97E00"))) // Half - XCTAssertTrue(value is Float) - XCTAssertTrue((value as! Float).isNaN) + XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF97E00"))) + XCTAssertTrue(value is Half) + XCTAssertTrue((value as! Half).isNaN) - XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF9FC00"))) // Half - XCTAssertTrue(value is Float) - XCTAssertEqual(value as! Float, -.infinity) + XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xF9FC00"))) + XCTAssertTrue(value is Half) + XCTAssertEqual(value as! Half, -.infinity) XCTAssertNoThrow(value = try CBORParser.parse(convertFromHexString("0xFA7F800000"))) XCTAssertTrue(value is Float) diff --git a/Cartfile b/Cartfile new file mode 100644 index 0000000..2639593 --- /dev/null +++ b/Cartfile @@ -0,0 +1 @@ +github "SomeRandomiOSDev/Half" ~> 1.0 diff --git a/Cartfile.resolved b/Cartfile.resolved new file mode 100644 index 0000000..e250439 --- /dev/null +++ b/Cartfile.resolved @@ -0,0 +1 @@ +github "SomeRandomiOSDev/Half" "1.0.0" diff --git a/Package.swift b/Package.swift index b90aecc..5fe80f6 100644 --- a/Package.swift +++ b/Package.swift @@ -15,8 +15,12 @@ let package = Package( .library(name: "CBORCoding", targets: ["CBORCoding"]) ], + dependencies: [ + .package(url: "https://github.com/SomeRandomiOSDev/Half", from: "1.0.0") + ], + targets: [ - .target(name: "CBORCoding", path: "CBORCoding"), + .target(name: "CBORCoding", dependencies: ["Half"], path: "CBORCoding"), .testTarget(name: "CBORCodingTests", dependencies: ["CBORCoding"], path: "CBORCodingTests") ] ) diff --git a/README.md b/README.md index 550ca78..b56e66b 100644 --- a/README.md +++ b/README.md @@ -94,6 +94,8 @@ Contributing If you have need for a specific feature or you encounter a bug, please open an issue. If you extend the functionality of **CBORCoding** yourself or you feel like fixing a bug yourself, please submit a pull request. +Note: You'll need to run `carthage bootstrap` upon downloading to resolve and build **CBORCoding**'s dependencies before being able to develop locally. Please look [here](https://github.com/Carthage/Carthage) for more info on installing Carthage on your local machine. + Author --------