diff --git a/IOBrowser.xcodeproj/project.pbxproj b/IOBrowser.xcodeproj/project.pbxproj index d45b98b..efc71a0 100644 --- a/IOBrowser.xcodeproj/project.pbxproj +++ b/IOBrowser.xcodeproj/project.pbxproj @@ -17,8 +17,6 @@ 054776F6268A85B6005864F8 /* Icon.icns in Resources */ = {isa = PBXBuildFile; fileRef = 054776F5268A85B6005864F8 /* Icon.icns */; }; 0552FE472948FC7300DAA87A /* PropertyValueTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0552FE462948FC7300DAA87A /* PropertyValueTransformer.swift */; }; 0552FE482948FC7300DAA87A /* PropertyValueTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0552FE462948FC7300DAA87A /* PropertyValueTransformer.swift */; }; - 0552FE4A294907FE00DAA87A /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0552FE49294907FE00DAA87A /* Data.swift */; }; - 0552FE4B294907FE00DAA87A /* Data.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0552FE49294907FE00DAA87A /* Data.swift */; }; 05646BB42685020A00707676 /* ApplicationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05646BAF2685020A00707676 /* ApplicationDelegate.swift */; }; 05646BB52685020A00707676 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 05646BB12685020A00707676 /* MainMenu.xib */; }; 05646BEF2685055F00707676 /* AboutWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 05646BEE2685055F00707676 /* AboutWindowController.swift */; }; @@ -98,7 +96,6 @@ 054776F3268A7BFA005864F8 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/PropertyListFormatViewController.xib; sourceTree = ""; }; 054776F5268A85B6005864F8 /* Icon.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = Icon.icns; sourceTree = ""; }; 0552FE462948FC7300DAA87A /* PropertyValueTransformer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PropertyValueTransformer.swift; sourceTree = ""; }; - 0552FE49294907FE00DAA87A /* Data.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Data.swift; sourceTree = ""; }; 05646B9A268501B300707676 /* IOBrowser.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = IOBrowser.app; sourceTree = BUILT_PRODUCTS_DIR; }; 05646BA4268501B400707676 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 05646BA5268501B400707676 /* IOBrowser.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = IOBrowser.entitlements; sourceTree = ""; }; @@ -232,7 +229,6 @@ 05B886BF2689C64F00E8A413 /* PropertyListNode.swift */, 054776F0268A7BED005864F8 /* PropertyListFormatViewController.swift */, 0552FE462948FC7300DAA87A /* PropertyValueTransformer.swift */, - 0552FE49294907FE00DAA87A /* Data.swift */, 050087D62949CEE400882DD8 /* PasteboardWriter.swift */, 050087DB2949D17E00882DD8 /* Either.swift */, ); @@ -573,7 +569,6 @@ 05646BEF2685055F00707676 /* AboutWindowController.swift in Sources */, 0552FE472948FC7300DAA87A /* PropertyValueTransformer.swift in Sources */, 05B886BB2688F44E00E8A413 /* PropertiesViewController.swift in Sources */, - 0552FE4A294907FE00DAA87A /* Data.swift in Sources */, 05B886B62688BE2E00E8A413 /* Preferences.swift in Sources */, 05646BF72685064C00707676 /* MainWindowController.swift in Sources */, 054776F1268A7BED005864F8 /* PropertyListFormatViewController.swift in Sources */, @@ -595,7 +590,6 @@ 059861D0292B9B7000B20BBD /* AboutWindowController.swift in Sources */, 0552FE482948FC7300DAA87A /* PropertyValueTransformer.swift in Sources */, 059861D1292B9B7000B20BBD /* PropertiesViewController.swift in Sources */, - 0552FE4B294907FE00DAA87A /* Data.swift in Sources */, 059861D2292B9B7000B20BBD /* Preferences.swift in Sources */, 059861D3292B9B7000B20BBD /* MainWindowController.swift in Sources */, 059861D4292B9B7000B20BBD /* PropertyListFormatViewController.swift in Sources */, @@ -674,6 +668,7 @@ DEVELOPMENT_TEAM = 326Y53CJMD; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = IOBrowser/Info.plist; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", @@ -695,6 +690,7 @@ DEVELOPMENT_TEAM = 326Y53CJMD; ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = IOBrowser/Info.plist; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.developer-tools"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/../Frameworks", diff --git a/IOBrowser/Classes/Data.swift b/IOBrowser/Classes/Data.swift deleted file mode 100644 index d051907..0000000 --- a/IOBrowser/Classes/Data.swift +++ /dev/null @@ -1,75 +0,0 @@ -/******************************************************************************* - * The MIT License (MIT) - * - * Copyright (c) 2022, Jean-David Gadina - www.xs-labs.com - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the Software), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - ******************************************************************************/ - -import Foundation - -public extension Data -{ - func hexadecimalString() -> String - { - self.reduce( "0x" ) - { - $0.appending( String( format: "%02X", $1 ) ) - } - } - - func number() -> UInt64? - { - if self.count == 1 - { - return UInt64( self[ 0 ] ) - } - else if self.count == 2 - { - let n1 = UInt64( self[ 0 ] ) << 8 - let n2 = UInt64( self[ 1 ] ) - - return n1 | n2 - } - else if self.count == 4 - { - let n1 = UInt64( self[ 0 ] ) << 24 - let n2 = UInt64( self[ 1 ] ) << 16 - let n3 = UInt64( self[ 2 ] ) << 8 - let n4 = UInt64( self[ 3 ] ) - - return n1 | n2 | n3 | n4 - } - else if self.count == 8 - { - let n1 = UInt64( self[ 0 ] ) << 56 - let n2 = UInt64( self[ 1 ] ) << 48 - let n3 = UInt64( self[ 2 ] ) << 40 - let n4 = UInt64( self[ 3 ] ) << 32 - let n5 = UInt64( self[ 4 ] ) << 24 - let n6 = UInt64( self[ 5 ] ) << 16 - let n7 = UInt64( self[ 6 ] ) << 8 - let n8 = UInt64( self[ 7 ] ) - - return n1 | n2 | n3 | n4 | n5 | n6 | n7 | n8 - } - - return nil - } -} diff --git a/IOBrowser/Classes/Preferences.swift b/IOBrowser/Classes/Preferences.swift index d68d940..6efa5b6 100644 --- a/IOBrowser/Classes/Preferences.swift +++ b/IOBrowser/Classes/Preferences.swift @@ -50,9 +50,9 @@ public class Preferences: NSObject set( value ) { - self.willChangeValue( for: \.lastStart ) + self.willChangeValue( for: \.numberDisplayMode ) UserDefaults.standard.set( value, forKey: "numberDisplayMode" ) - self.didChangeValue( for: \.lastStart ) + self.didChangeValue( for: \.numberDisplayMode ) } } @@ -65,24 +65,24 @@ public class Preferences: NSObject set( value ) { - self.willChangeValue( for: \.lastStart ) + self.willChangeValue( for: \.dataDisplayMode ) UserDefaults.standard.set( value, forKey: "dataDisplayMode" ) - self.didChangeValue( for: \.lastStart ) + self.didChangeValue( for: \.dataDisplayMode ) } } - @objc public dynamic var detectNumbersInData: Bool + @objc public dynamic var detectNumbersInData: Int { get { - UserDefaults.standard.bool( forKey: "detectNumbersInData" ) + UserDefaults.standard.integer( forKey: "detectNumbersInData" ) } set( value ) { - self.willChangeValue( for: \.lastStart ) + self.willChangeValue( for: \.detectNumbersInData ) UserDefaults.standard.set( value, forKey: "detectNumbersInData" ) - self.didChangeValue( for: \.lastStart ) + self.didChangeValue( for: \.detectNumbersInData ) } } diff --git a/IOBrowser/Classes/PropertyValueTransformer.swift b/IOBrowser/Classes/PropertyValueTransformer.swift index f9e5a81..b779405 100644 --- a/IOBrowser/Classes/PropertyValueTransformer.swift +++ b/IOBrowser/Classes/PropertyValueTransformer.swift @@ -42,29 +42,75 @@ public class PropertyValueTransformer: ValueTransformer if let number = value.propertyList as? NSNumber { - if Preferences.shared.numberDisplayMode == 0 + if CFGetTypeID(number) == CFBooleanGetTypeID() + { + return number.boolValue ? "true" : "false" + } + else if Preferences.shared.numberDisplayMode == 0 { return number.description } - else if Preferences.shared.numberDisplayMode == 1 + else { - return String( format: "0x%llX", number.int64Value ) + switch CFNumberGetType(number) + { + case .sInt8Type, .sInt16Type, .sInt32Type, .sInt64Type, .charType, .shortType, .intType, .longType, .longLongType: + return String(format: "0x%0*llX", CFNumberGetByteSize(number) * 2, number.uint64Value) + + case .float32Type, .float64Type, .floatType, .doubleType, .cgFloatType: + return String(format: "0x%a", number.doubleValue) + + default: + return number.description + } } } if let data = value.propertyList as? Data, data.count > 0 { - if Preferences.shared.detectNumbersInData, let number = data.number() + if Preferences.shared.detectNumbersInData != 0, [1, 2, 4, 8].contains(data.count) { - return PropertyValueTransformer().transformedValue( PropertyListNode( key: value.key, propertyList: NSNumber( value: number ) ) ) - } - else if Preferences.shared.dataDisplayMode == 0 - { - return data.base64EncodedString() + var number: UInt64 = 0 + + switch (Preferences.shared.detectNumbersInData) + { + case 1: // big-endian + for byte in data + { + number = (number << 8) | UInt64(byte) + } + case 2: // little-endian + for ( i, byte ) in data.enumerated() + { + number |= UInt64( byte ) << ( i * 8 ) + } + default: + break + } + + if Preferences.shared.numberDisplayMode == 0 + { + return number.description + } + else + { + let width = data.count * 2 + return String(format: "0x%0*llX", width, number) + } } - else if Preferences.shared.dataDisplayMode == 1 + else { - return data.hexadecimalString() + switch Preferences.shared.dataDisplayMode + { + case 1: + return data.base64EncodedString() + case 2: + return "0x" + data.map { String(format: "%02X", $0) }.joined() + case 3: + return String(data: data, encoding: .utf8) ?? "" + default: + return data.description + } } } diff --git a/IOBrowser/Info.plist b/IOBrowser/Info.plist index c2e7397..d52e099 100644 --- a/IOBrowser/Info.plist +++ b/IOBrowser/Info.plist @@ -17,9 +17,9 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.2.1 + 1.2.2 CFBundleVersion - 46 + 54 LSApplicationCategoryType public.app-category.utilities LSMinimumSystemVersion diff --git a/IOBrowser/UI/Base.lproj/PropertiesViewController.xib b/IOBrowser/UI/Base.lproj/PropertiesViewController.xib index ae9edf8..3d11a88 100644 --- a/IOBrowser/UI/Base.lproj/PropertiesViewController.xib +++ b/IOBrowser/UI/Base.lproj/PropertiesViewController.xib @@ -1,8 +1,8 @@ - + - + @@ -21,13 +21,13 @@ - + - + - + @@ -186,13 +186,13 @@ - + - + - + @@ -200,7 +200,7 @@ - + @@ -218,7 +218,7 @@ - + @@ -226,14 +226,16 @@ - + + + @@ -241,35 +243,54 @@ - + - + + + + + + - - + - + @@ -299,7 +320,7 @@ - +