├── .gitignore ├── LICENSE ├── PassHUD.xcodeproj ├── project.pbxproj ├── project.pbxproje ├── project.pbxprojee ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── contents.xcworkspacedatae │ ├── contents.xcworkspacedataee │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── mnussbaum.xcuserdatad │ │ └── IDEFindNavigatorScopes.plist ├── xcshareddata │ └── xcschemes │ │ └── PassHUD.xcscheme └── xcuserdata │ └── mnussbaum.xcuserdatad │ └── xcschemes │ ├── xcschememanagement.plist │ └── xcschememanagement.pliste ├── PassHUD.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── PassHUD ├── AppDelegate.swift ├── Assets.xcassets │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ ├── Icon-128.png │ │ ├── Icon-128@2x.png │ │ ├── Icon-16.png │ │ ├── Icon-16@2x.png │ │ ├── Icon-256.png │ │ ├── Icon-32.png │ │ ├── Icon-32@2x.png │ │ ├── Icon-512.png │ │ ├── Icon-512@2x.png │ │ └── Icon-513.png │ ├── Contents.json │ ├── Icon.xcf │ └── PadLockStatusBarButtonImage.imageset │ │ ├── Contents.json │ │ ├── Icon-16.png │ │ ├── Icon-32.png │ │ └── Icon-32@2x.png ├── Atomic.swift ├── Base.lproj │ ├── Main.storyboard │ └── Main.storyboarde ├── CommandOutputStreamer.swift ├── ConfigParser.swift ├── FaviconLoader.swift ├── HUDIconImageView.swift ├── HUDSearchField.swift ├── HUDTableCellView.swift ├── HUDTableRowView.swift ├── HUDTableView.swift ├── HUDView.swift ├── HUDViewController.swift ├── HUDWindow.swift ├── HotKey.swift ├── HotKeyParser.swift ├── Info.plist ├── LRUCache.swift ├── NSImage.swift ├── NSString.swift └── PassHUD.entitlements ├── PassHUDScreenShot.png ├── PassHUDTests ├── Info.plist └── PassHUDTests.swift ├── PassHUDUITests ├── Info.plist └── PaddHUDUITests.swift ├── Podfile ├── Podfile.lock ├── Pods ├── FavIcon │ ├── LICENSE │ ├── README.md │ └── Sources │ │ ├── FavIcon │ │ ├── ContentTypes.swift │ │ ├── Detection.swift │ │ ├── Download.swift │ │ ├── FavIcon.swift │ │ ├── HTML.swift │ │ ├── Icon.swift │ │ ├── IconType.swift │ │ └── XML.swift │ │ └── Modules │ │ ├── libxml2-favicon.h │ │ └── module.modulemap ├── Manifest.lock ├── Pods.xcodeproj │ ├── project.pbxproj │ └── xcuserdata │ │ └── mnussbaum.xcuserdatad │ │ └── xcschemes │ │ ├── FavIcon.xcscheme │ │ ├── Pods-PassHUD.xcscheme │ │ ├── Pods-PassHUDTests.xcscheme │ │ ├── Pods-PassHUDUITests.xcscheme │ │ ├── SPTPersistentCache.xcscheme │ │ ├── Yams.xcscheme │ │ └── xcschememanagement.plist ├── SPTPersistentCache │ ├── LICENSE │ ├── README.md │ ├── Sources │ │ ├── Categories │ │ │ ├── NSError+SPTPersistentCacheDomainErrors.h │ │ │ └── NSError+SPTPersistentCacheDomainErrors.m │ │ ├── SPTPersistentCache+Private.h │ │ ├── SPTPersistentCache.m │ │ ├── SPTPersistentCacheDebugUtilities.h │ │ ├── SPTPersistentCacheDebugUtilities.m │ │ ├── SPTPersistentCacheFileManager+Private.h │ │ ├── SPTPersistentCacheFileManager.h │ │ ├── SPTPersistentCacheFileManager.m │ │ ├── SPTPersistentCacheGarbageCollector.h │ │ ├── SPTPersistentCacheGarbageCollector.m │ │ ├── SPTPersistentCacheHeader.m │ │ ├── SPTPersistentCacheObjectDescription.h │ │ ├── SPTPersistentCacheObjectDescription.m │ │ ├── SPTPersistentCacheOptions.m │ │ ├── SPTPersistentCachePosixWrapper.h │ │ ├── SPTPersistentCachePosixWrapper.m │ │ ├── SPTPersistentCacheRecord+Private.h │ │ ├── SPTPersistentCacheRecord.m │ │ ├── SPTPersistentCacheResponse+Private.h │ │ ├── SPTPersistentCacheResponse.m │ │ ├── SPTPersistentCacheTypeUtilities.h │ │ ├── SPTPersistentCacheTypeUtilities.m │ │ ├── crc32iso3309.c │ │ └── crc32iso3309.h │ └── include │ │ └── SPTPersistentCache │ │ ├── SPTPersistentCache.h │ │ ├── SPTPersistentCacheHeader.h │ │ ├── SPTPersistentCacheOptions.h │ │ ├── SPTPersistentCacheRecord.h │ │ └── SPTPersistentCacheResponse.h ├── Target Support Files │ ├── FavIcon │ │ ├── FavIcon-Info.plist │ │ ├── FavIcon-dummy.m │ │ ├── FavIcon-prefix.pch │ │ ├── FavIcon-umbrella.h │ │ ├── FavIcon.modulemap │ │ └── FavIcon.xcconfig │ ├── Pods-PassHUD │ │ ├── Pods-PassHUD-Info.plist │ │ ├── Pods-PassHUD-acknowledgements.markdown │ │ ├── Pods-PassHUD-acknowledgements.plist │ │ ├── Pods-PassHUD-dummy.m │ │ ├── Pods-PassHUD-frameworks.sh │ │ ├── Pods-PassHUD-umbrella.h │ │ ├── Pods-PassHUD.debug.xcconfig │ │ ├── Pods-PassHUD.modulemap │ │ └── Pods-PassHUD.release.xcconfig │ ├── Pods-PassHUDTests │ │ ├── Pods-PassHUDTests-Info.plist │ │ ├── Pods-PassHUDTests-acknowledgements.markdown │ │ ├── Pods-PassHUDTests-acknowledgements.plist │ │ ├── Pods-PassHUDTests-dummy.m │ │ ├── Pods-PassHUDTests-umbrella.h │ │ ├── Pods-PassHUDTests.debug.xcconfig │ │ ├── Pods-PassHUDTests.modulemap │ │ └── Pods-PassHUDTests.release.xcconfig │ ├── Pods-PassHUDUITests │ │ ├── Pods-PassHUDUITests-Info.plist │ │ ├── Pods-PassHUDUITests-acknowledgements.markdown │ │ ├── Pods-PassHUDUITests-acknowledgements.plist │ │ ├── Pods-PassHUDUITests-dummy.m │ │ ├── Pods-PassHUDUITests-umbrella.h │ │ ├── Pods-PassHUDUITests.debug.xcconfig │ │ ├── Pods-PassHUDUITests.modulemap │ │ └── Pods-PassHUDUITests.release.xcconfig │ ├── SPTPersistentCache │ │ ├── SPTPersistentCache-Info.plist │ │ ├── SPTPersistentCache-dummy.m │ │ ├── SPTPersistentCache-prefix.pch │ │ ├── SPTPersistentCache-umbrella.h │ │ ├── SPTPersistentCache.modulemap │ │ └── SPTPersistentCache.xcconfig │ └── Yams │ │ ├── Yams-Info.plist │ │ ├── Yams-dummy.m │ │ ├── Yams-prefix.pch │ │ ├── Yams-umbrella.h │ │ ├── Yams.modulemap │ │ └── Yams.xcconfig └── Yams │ ├── LICENSE │ ├── README.md │ └── Sources │ ├── CYaml │ ├── include │ │ ├── CYaml.h │ │ └── yaml.h │ └── src │ │ ├── api.c │ │ ├── emitter.c │ │ ├── parser.c │ │ ├── reader.c │ │ ├── scanner.c │ │ ├── writer.c │ │ └── yaml_private.h │ └── Yams │ ├── Constructor.swift │ ├── Decoder.swift │ ├── Emitter.swift │ ├── Encoder.swift │ ├── Mark.swift │ ├── Node.Mapping.swift │ ├── Node.Scalar.swift │ ├── Node.Sequence.swift │ ├── Node.swift │ ├── Parser.swift │ ├── Representer.swift │ ├── Resolver.swift │ ├── String+Yams.swift │ ├── Tag.swift │ ├── YamlError.swift │ ├── Yams.h │ └── shim.swift └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | PassHUD.xcodeproj/xcuserdata/*.xcuserdatad/xcdebugger/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Michael Nussbaum 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 | -------------------------------------------------------------------------------- /PassHUD.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PassHUD.xcodeproj/project.xcworkspace/contents.xcworkspacedatae: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PassHUD.xcodeproj/project.xcworkspace/contents.xcworkspacedataee: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PassHUD.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /PassHUD.xcodeproj/project.xcworkspace/xcuserdata/mnussbaum.xcuserdatad/IDEFindNavigatorScopes.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /PassHUD.xcodeproj/xcshareddata/xcschemes/PassHUD.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 69 | 70 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /PassHUD.xcodeproj/xcuserdata/mnussbaum.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PassHUD.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 5 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 7B99C42F216F21310025D6ED 16 | 17 | primary 18 | 19 | 20 | 7B99C441216F21340025D6ED 21 | 22 | primary 23 | 24 | 25 | 7B99C44C216F21340025D6ED 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /PassHUD.xcodeproj/xcuserdata/mnussbaum.xcuserdatad/xcschemes/xcschememanagement.pliste: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | PassHUD.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | PassHUD.xcscheme 13 | 14 | orderHint 15 | 0 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | 7B99C42F216F21310025D6ED 21 | 22 | primary 23 | 24 | 25 | 7B99C441216F21340025D6ED 26 | 27 | primary 28 | 29 | 30 | 7B99C44C216F21340025D6ED 31 | 32 | primary 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /PassHUD.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /PassHUD.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /PassHUD/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // PassHUD 4 | // 5 | // Created by Nussbaum, Michael on 10/10/18. 6 | // Copyright © 2018 mnussbaum. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import Carbon 11 | import os 12 | 13 | let logger = OSLog( 14 | subsystem: Bundle.main.bundleIdentifier!, 15 | category: "HUD" 16 | ) 17 | 18 | @NSApplicationMain 19 | class AppDelegate: NSObject, NSApplicationDelegate { 20 | let statusItem = NSStatusBar 21 | .system 22 | .statusItem(withLength: NSStatusItem.squareLength) 23 | let hudWindow = HUDWindow() 24 | var hudViewController: HUDViewController? 25 | 26 | let defaultHotKey = HotKeyConfig(modifiers: ["cmd"], key: "/") 27 | 28 | func applicationDidFinishLaunching(_ aNotification: Notification) { 29 | if let button = statusItem.button { 30 | button.image = NSImage(named:NSImage.Name("PadLockStatusBarButtonImage")) 31 | button.action = #selector(toggleHUD(_:)) 32 | } 33 | self.hudWindow.setAppearance() 34 | 35 | let config = ConfigParser.ParseConfig() 36 | self.hudViewController = HUDViewController.create( 37 | config: config 38 | ) 39 | self.hudWindow.contentViewController = self.hudViewController 40 | 41 | self.registerHotKeys(config) 42 | } 43 | 44 | @objc func toggleHUD(_ sender: Any?) { 45 | self.hudViewController?.toggle(sender) 46 | } 47 | 48 | func registerHotKeys(_ config: Config?) { 49 | for hotKey in config?.hotKeys ?? [defaultHotKey] { 50 | HotKey.register( 51 | HotKeyParser.charToKeyCode(hotKey.key), 52 | modifiers: HotKeyParser.modifiersToModCode(hotKey.modifiers), 53 | block: { 54 | self.toggleHUD(nil) 55 | } 56 | ) 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "16x16", 5 | "idiom" : "mac", 6 | "filename" : "Icon-16.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "16x16", 11 | "idiom" : "mac", 12 | "filename" : "Icon-16@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "32x32", 17 | "idiom" : "mac", 18 | "filename" : "Icon-32.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "32x32", 23 | "idiom" : "mac", 24 | "filename" : "Icon-32@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "128x128", 29 | "idiom" : "mac", 30 | "filename" : "Icon-128.png", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "size" : "128x128", 35 | "idiom" : "mac", 36 | "filename" : "Icon-128@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "256x256", 41 | "idiom" : "mac", 42 | "filename" : "Icon-256.png", 43 | "scale" : "1x" 44 | }, 45 | { 46 | "size" : "256x256", 47 | "idiom" : "mac", 48 | "filename" : "Icon-513.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "512x512", 53 | "idiom" : "mac", 54 | "filename" : "Icon-512.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "512x512", 59 | "idiom" : "mac", 60 | "filename" : "Icon-512@2x.png", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mnussbaum/PassHUD/72a33d55f03090090bf429bbebb85220d26f6702/PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-128.png -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-128@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mnussbaum/PassHUD/72a33d55f03090090bf429bbebb85220d26f6702/PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-128@2x.png -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mnussbaum/PassHUD/72a33d55f03090090bf429bbebb85220d26f6702/PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-16.png -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mnussbaum/PassHUD/72a33d55f03090090bf429bbebb85220d26f6702/PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-16@2x.png -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mnussbaum/PassHUD/72a33d55f03090090bf429bbebb85220d26f6702/PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-256.png -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mnussbaum/PassHUD/72a33d55f03090090bf429bbebb85220d26f6702/PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-32.png -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mnussbaum/PassHUD/72a33d55f03090090bf429bbebb85220d26f6702/PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-32@2x.png -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mnussbaum/PassHUD/72a33d55f03090090bf429bbebb85220d26f6702/PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-512.png -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-512@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mnussbaum/PassHUD/72a33d55f03090090bf429bbebb85220d26f6702/PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-512@2x.png -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-513.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mnussbaum/PassHUD/72a33d55f03090090bf429bbebb85220d26f6702/PassHUD/Assets.xcassets/AppIcon.appiconset/Icon-513.png -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/Icon.xcf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mnussbaum/PassHUD/72a33d55f03090090bf429bbebb85220d26f6702/PassHUD/Assets.xcassets/Icon.xcf -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/PadLockStatusBarButtonImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "Icon-16.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "Icon-32.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "Icon-32@2x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | }, 23 | "properties" : { 24 | "template-rendering-intent" : "template" 25 | } 26 | } -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/PadLockStatusBarButtonImage.imageset/Icon-16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mnussbaum/PassHUD/72a33d55f03090090bf429bbebb85220d26f6702/PassHUD/Assets.xcassets/PadLockStatusBarButtonImage.imageset/Icon-16.png -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/PadLockStatusBarButtonImage.imageset/Icon-32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mnussbaum/PassHUD/72a33d55f03090090bf429bbebb85220d26f6702/PassHUD/Assets.xcassets/PadLockStatusBarButtonImage.imageset/Icon-32.png -------------------------------------------------------------------------------- /PassHUD/Assets.xcassets/PadLockStatusBarButtonImage.imageset/Icon-32@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mnussbaum/PassHUD/72a33d55f03090090bf429bbebb85220d26f6702/PassHUD/Assets.xcassets/PadLockStatusBarButtonImage.imageset/Icon-32@2x.png -------------------------------------------------------------------------------- /PassHUD/Atomic.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Atomic.swift 3 | // PassHUD 4 | // 5 | // Created by Nussbaum, Michael on 10/26/18. 6 | // Source https://stackoverflow.com/a/47345863 7 | // 8 | 9 | import Foundation 10 | 11 | class Atomic { 12 | private let semaphore = DispatchSemaphore(value: 1) 13 | private var _value: T 14 | 15 | var value: T { 16 | get { 17 | wait() 18 | let result = _value 19 | defer { 20 | signal() 21 | } 22 | return result 23 | } 24 | 25 | set (value) { 26 | wait() 27 | _value = value 28 | defer { 29 | signal() 30 | } 31 | } 32 | } 33 | 34 | func set(closure: (_ currentValue: T)->(T)){ 35 | wait() 36 | _value = closure(_value) 37 | signal() 38 | } 39 | 40 | func get(closure: (_ currentValue: T)->()){ 41 | wait() 42 | closure(_value) 43 | signal() 44 | } 45 | 46 | private func wait() { 47 | semaphore.wait() 48 | } 49 | 50 | private func signal() { 51 | semaphore.signal() 52 | } 53 | 54 | init (value: T) { 55 | _value = value 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /PassHUD/CommandOutputStreamer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CommandOutputStreamer.swift 3 | // PassHUD 4 | // 5 | // Created by Nussbaum, Michael on 10/11/18. 6 | // Copyright © 2018 mnussbaum. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | protocol CommandOutputStreamerDelegate { 12 | func handleOutput( 13 | _ output: String, 14 | arguments: [String]?, 15 | commandIndex: Int 16 | ) 17 | } 18 | 19 | class CommandOutputStreamer { 20 | var task: Process 21 | 22 | init( 23 | task: Process, 24 | arguments: [String], 25 | caller: CommandOutputStreamerDelegate, 26 | index: Int 27 | ) { 28 | self.task = task 29 | var pipe: Pipe? = Pipe() 30 | self.task.standardOutput = pipe 31 | 32 | let outputHandle = pipe?.fileHandleForReading 33 | outputHandle?.waitForDataInBackgroundAndNotify() 34 | 35 | // TODO: make queue non-nil so this runs in the background 36 | var dataAvailable : NSObjectProtocol! 37 | dataAvailable = NotificationCenter.default.addObserver( 38 | forName: NSNotification.Name.NSFileHandleDataAvailable, 39 | object: outputHandle, queue: nil 40 | ) { notification -> Void in 41 | guard let strongPipe = pipe else { return } 42 | 43 | let data = strongPipe.fileHandleForReading.availableData 44 | if data.count <= 0 { 45 | NotificationCenter.default.removeObserver(dataAvailable) 46 | pipe = nil 47 | return 48 | } 49 | 50 | if let str = String(data: data, encoding: .utf8) { 51 | caller.handleOutput( 52 | str.substring( 53 | to: str.index(str.endIndex, offsetBy: -1) 54 | ), 55 | arguments: arguments, 56 | commandIndex: index 57 | ) 58 | } 59 | 60 | outputHandle?.waitForDataInBackgroundAndNotify() 61 | } 62 | } 63 | 64 | func launch() { 65 | return self.task.launch() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /PassHUD/ConfigParser.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Config.swift 3 | // PassHUD 4 | // 5 | // Created by Nussbaum, Michael on 12/7/18. 6 | // Copyright © 2018 mnussbaum. All rights reserved. 7 | // 8 | 9 | import os 10 | import Foundation 11 | 12 | import Yams 13 | 14 | struct EnvVarPair: Codable { 15 | var name: String 16 | var value: String 17 | } 18 | 19 | struct PassConfig: Codable { 20 | var commandPath: Optional 21 | var env: Optional> 22 | } 23 | 24 | struct HotKeyConfig: Codable { 25 | var modifiers: Array 26 | var key: String 27 | } 28 | 29 | struct Config: Codable { 30 | var version: Optional 31 | var pass: Optional 32 | var hotKeys: Optional> 33 | } 34 | 35 | let potentialConfigPaths = [ 36 | FileManager 37 | .default 38 | .homeDirectoryForCurrentUser 39 | .appendingPathComponent(".PassHUD"), 40 | FileManager 41 | .default 42 | .homeDirectoryForCurrentUser 43 | .appendingPathComponent(".config", isDirectory: true) 44 | .appendingPathComponent("PassHUD", isDirectory: true) 45 | .appendingPathComponent("config") 46 | ] 47 | 48 | class ConfigParser { 49 | class func ParseConfig() -> Optional { 50 | let (maybeConfigPath, maybeRawConfig) = rawConfig() 51 | 52 | guard let configPath = maybeConfigPath else { 53 | return nil 54 | } 55 | guard let rawConfig = maybeRawConfig else { 56 | return nil 57 | } 58 | 59 | do { 60 | return try YAMLDecoder().decode( 61 | Config.self, 62 | from: rawConfig 63 | ) 64 | } catch { 65 | os_log( 66 | "Error parsing config at %{public}@: %{public}@.", 67 | log: logger, 68 | type: .error, 69 | configPath.description, 70 | "\(error)" 71 | ) 72 | } 73 | 74 | return nil 75 | } 76 | 77 | class func rawConfig() -> (Optional, Optional) { 78 | for configPath in potentialConfigPaths { 79 | do { 80 | return try (configPath, String(contentsOf: configPath)) 81 | } catch { 82 | continue 83 | } 84 | } 85 | 86 | return (nil, nil) 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /PassHUD/FaviconLoader.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FaviconLoader.swift 3 | // PassHUD 4 | // 5 | // Created by Nussbaum, Michael on 10/27/18. 6 | // Copyright © 2018 mnussbaum. All rights reserved. 7 | // 8 | 9 | import os 10 | 11 | import FavIcon 12 | import SPTPersistentCache 13 | 14 | class FaviconLoader { 15 | var cache: SPTPersistentCache 16 | 17 | let systemCachePath = NSSearchPathForDirectoriesInDomains( 18 | .cachesDirectory, 19 | .userDomainMask, 20 | true 21 | ).first! 22 | let cacheIdentifier = "com.passhud.favicon.cache" 23 | var cachePath: String 24 | let cacheQueue = DispatchQueue(label: "com.passhud.favicon.cache") 25 | let cacheOptions = SPTPersistentCacheOptions() 26 | let thirtyDays = 60 * 60 * 24 * 30 27 | 28 | let domainPredicate = NSPredicate( 29 | format:"SELF MATCHES %@", 30 | argumentArray: [ 31 | "^(www\\.)?([-a-z0-9]{1,63}\\.)*?[a-z0-9][-a-z0-9]{0,61}[a-z0-9]\\.[a-z]{2,6}(/[-\\w@\\+\\.~#\\?&/=%]*)?$" 32 | ] 33 | ) 34 | 35 | init() { 36 | self.cachePath = self.systemCachePath.appending( 37 | self.cacheIdentifier 38 | ) 39 | 40 | self.cacheOptions.cachePath = self.cachePath; 41 | self.cacheOptions.cacheIdentifier = self.cacheIdentifier 42 | self.cacheOptions.defaultExpirationPeriod = UInt(self.thirtyDays) 43 | self.cacheOptions.garbageCollectionInterval = UInt(60 * 60) * SPTPersistentCacheDefaultGCIntervalSec 44 | self.cacheOptions.sizeConstraintBytes = 1024 * 1024 * 200; // 200 MiB 45 | 46 | self.cache = SPTPersistentCache(options: self.cacheOptions) 47 | self.cache.scheduleGarbageCollector() 48 | } 49 | 50 | func isDomain(candidate: String) -> Bool { 51 | return self.domainPredicate.evaluate(with: candidate) 52 | } 53 | 54 | func load( 55 | _ domain: String?, 56 | callback: @escaping (NSImage?) -> Void 57 | ) { 58 | guard let domain = domain else { return } 59 | if !isDomain(candidate: domain) { return } 60 | 61 | self.cache.loadData( 62 | forKey: domain, 63 | withCallback: { (cacheResponse) in 64 | if cacheResponse.result == .operationSucceeded { 65 | callback(NSImage(data: cacheResponse.record.data)) 66 | } else { 67 | self.downloadFavicon( 68 | domain, 69 | attempt: 0, 70 | callback: callback 71 | ) 72 | } 73 | }, 74 | on: DispatchQueue.main 75 | ) 76 | 77 | return 78 | } 79 | 80 | func downloadFavicon( 81 | _ domain: String, 82 | attempt: Int, 83 | callback: @escaping (NSImage?) -> Void 84 | ) { 85 | var scheme = "https" 86 | if attempt == 1 { 87 | scheme = "http" 88 | } else if attempt > 1 { 89 | return 90 | } 91 | 92 | try! FavIcon.downloadPreferred(scheme + "://" + domain) { result in 93 | guard case let .success(image) = result else { 94 | self.downloadFavicon( 95 | domain, 96 | attempt: attempt + 1, 97 | callback: callback 98 | ) 99 | return 100 | } 101 | 102 | callback(image) 103 | 104 | if let tiffImage = image.tiffRepresentation { 105 | // Stagger cache expiration to avoid thundering hurds 106 | let ttl = self.cacheOptions.defaultExpirationPeriod + UInt(Int.random(in: 0 ..< self.thirtyDays)) 107 | self.cache.store( 108 | tiffImage, 109 | forKey: domain, 110 | ttl: ttl, 111 | locked: false, 112 | withCallback: { (cacheResponse) in 113 | if cacheResponse.result != .operationSucceeded { 114 | os_log( 115 | "Failed to store favicon for %{public}@ to cache: %{public}@", 116 | log: logger, 117 | type: .error, 118 | domain, 119 | cacheResponse.error.localizedDescription 120 | ) 121 | } 122 | }, 123 | on: self.cacheQueue 124 | ) 125 | } 126 | } 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /PassHUD/HUDIconImageView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HUDIconImageView.swift 3 | // PassHUD 4 | // 5 | // Created by Nussbaum, Michael on 12/19/18. 6 | // Copyright © 2018 mnussbaum. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import os 11 | 12 | class HUDIconImageView: NSImageView { 13 | override func draw(_ dirtyRect: NSRect) { 14 | if let imageLayer = self.layer { 15 | imageLayer.cornerRadius = self.frame.width / 6.0 16 | imageLayer.masksToBounds = true 17 | } else { 18 | os_log( 19 | "Error, missing expected icon image view layer", 20 | log: logger, 21 | type: .error 22 | ) 23 | } 24 | 25 | super.draw(dirtyRect) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /PassHUD/HUDSearchField.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HUDSearchField.swift 3 | // PassHUD 4 | // 5 | // Created by Nussbaum, Michael on 10/12/18. 6 | // Copyright © 2018 mnussbaum. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class HUDSearchField: NSTextField { 12 | override func draw(_ dirtyRect: NSRect) { 13 | super.draw(dirtyRect) 14 | self.focusRingType = .none 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /PassHUD/HUDTableCellView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HUDTableCellView.swift 3 | // PassHUD 4 | // 5 | // Created by Nussbaum, Michael on 10/22/18. 6 | // Copyright © 2018 mnussbaum. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class HUDTableCellView: NSTableCellView { 12 | override func draw(_ dirtyRect: NSRect) { 13 | super.draw(dirtyRect) 14 | } 15 | 16 | override var backgroundStyle: NSView.BackgroundStyle { 17 | set { 18 | if let rowView = self.superview as? NSTableRowView { 19 | rowView.isEmphasized = true 20 | } else { 21 | super.backgroundStyle = newValue 22 | } 23 | } 24 | get { 25 | return super.backgroundStyle; 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /PassHUD/HUDTableRowView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HUDTableRowView.swift 3 | // PassHUD 4 | // 5 | // Created by Nussbaum, Michael on 11/12/18. 6 | // Copyright © 2018 mnussbaum. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | import os 11 | 12 | class HUDTableRowView: NSTableRowView { 13 | weak var parentTableView: NSTableView? 14 | var index: Int? 15 | var trackingArea: NSTrackingArea? 16 | 17 | override func updateTrackingAreas() { 18 | super.updateTrackingAreas() 19 | self.ensureTrackingArea() 20 | if !trackingAreas.contains(self.trackingArea!) { 21 | self.addTrackingArea(self.trackingArea!) 22 | } 23 | } 24 | 25 | func ensureTrackingArea() { 26 | if self.trackingArea != nil { 27 | return 28 | } 29 | 30 | self.trackingArea = NSTrackingArea( 31 | rect: NSZeroRect, 32 | options: [ 33 | .inVisibleRect, 34 | .activeInActiveApp, 35 | .mouseEnteredAndExited 36 | ], 37 | owner: self, 38 | userInfo: nil 39 | ) 40 | } 41 | 42 | override func mouseEntered(with event: NSEvent) { 43 | guard let index = self.index else { 44 | os_log( 45 | "Error, missing row index from HUDTableRowView", 46 | log: logger, 47 | type: .error 48 | ) 49 | return 50 | } 51 | guard let parentTableView = self.parentTableView else { 52 | os_log( 53 | "Error, missing parent table view from HUDTableRowView", 54 | log: logger, 55 | type: .error 56 | ) 57 | return 58 | } 59 | 60 | parentTableView.selectRowIndexes( 61 | IndexSet(integer: index), 62 | byExtendingSelection: false 63 | ) 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /PassHUD/HUDTableView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HUDTableView.swift 3 | // PassHUD 4 | // 5 | // Created by Nussbaum, Michael on 10/12/18. 6 | // Copyright © 2018 mnussbaum. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class HUDTableView: NSTableView { 12 | override func draw(_ dirtyRect: NSRect) { 13 | super.draw(dirtyRect) 14 | self.focusRingType = .none 15 | } 16 | 17 | override func reloadData() { 18 | super.reloadData() 19 | self.selectRowIndexes( 20 | IndexSet(integer: 0), 21 | byExtendingSelection: false 22 | ) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /PassHUD/HUDView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HUDView.swift 3 | // PassHUD 4 | // 5 | // Created by Nussbaum, Michael on 10/12/18. 6 | // Copyright © 2018 mnussbaum. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class HUDView: NSView { 12 | override func draw(_ dirtyRect: NSRect) { 13 | super.draw(dirtyRect) 14 | self.appearance = NSAppearance(named: .vibrantDark) 15 | } 16 | 17 | override var allowsVibrancy: Bool { return true } 18 | } 19 | -------------------------------------------------------------------------------- /PassHUD/HUDWindow.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HUDWindow.swift 3 | // PassHUD 4 | // 5 | // Created by Nussbaum, Michael on 10/12/18. 6 | // Copyright © 2018 mnussbaum. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | class HUDWindow: NSWindow { 12 | func setAppearance() { 13 | self.backgroundColor = .clear 14 | self.collectionBehavior = .moveToActiveSpace 15 | self.hidesOnDeactivate = true 16 | self.isMovableByWindowBackground = true 17 | self.styleMask.remove(.miniaturizable) 18 | self.styleMask.remove(.closable) 19 | self.styleMask.remove(.resizable) 20 | self.styleMask.insert(.fullSizeContentView) 21 | self.titlebarAppearsTransparent = true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /PassHUD/HotKey.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HotKey.swift 3 | // PassHUD 4 | // Source: https://github.com/nathan/hush/blob/master/Hush/HotKey.swift 5 | 6 | import Cocoa 7 | import Carbon 8 | 9 | class HotKey { 10 | init() {} 11 | 12 | static func register( 13 | _ keyCode: UInt32, 14 | modifiers: UInt32, 15 | block: @escaping () -> () 16 | ) { 17 | var hotKey: EventHotKeyRef? = nil 18 | var eventHandler: EventHandlerRef? = nil 19 | let hotKeyID = EventHotKeyID(signature: 1, id: 1) 20 | var eventType = EventTypeSpec( 21 | eventClass: OSType(kEventClassKeyboard), 22 | eventKind: UInt32(kEventHotKeyPressed) 23 | ) 24 | 25 | let ptr = UnsafeMutablePointer<() -> ()>.allocate(capacity: 1) 26 | ptr.initialize(to: block) 27 | 28 | if InstallEventHandler( 29 | GetApplicationEventTarget(), 30 | { (_: EventHandlerCallRef?, _: EventRef?, ptr: UnsafeMutableRawPointer?) -> OSStatus in 31 | ptr.map({$0.assumingMemoryBound(to: (() -> ()).self).pointee()}) 32 | return noErr 33 | }, 34 | 1, 35 | &eventType, 36 | ptr, 37 | &eventHandler 38 | ) == noErr { 39 | if RegisterEventHotKey( 40 | keyCode, 41 | modifiers, 42 | hotKeyID, 43 | GetApplicationEventTarget(), 44 | OptionBits(0), 45 | &hotKey 46 | ) != noErr { 47 | fatalError("Failed to register global hotkey") 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /PassHUD/HotKeyParser.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HotKeyParser.swift 3 | // PassHUD 4 | // Source: https://github.com/marshallbrekka/AutoWin/blob/master/AutoWin/Util/AWKeyCodes.swift 5 | 6 | import Foundation 7 | import Carbon 8 | import Cocoa 9 | 10 | let modifiersToKeyCodes: NSDictionary = [ 11 | "cmd" : cmdKey, 12 | "ctrl" : controlKey, 13 | "opt" : optionKey, 14 | "shift": shiftKey 15 | ] 16 | 17 | let charsToKeyCodes :NSDictionary = [ 18 | "a":kVK_ANSI_A, 19 | "b":kVK_ANSI_B, 20 | "c":kVK_ANSI_C, 21 | "d":kVK_ANSI_D, 22 | "e":kVK_ANSI_E, 23 | "f":kVK_ANSI_F, 24 | "g":kVK_ANSI_G, 25 | "h":kVK_ANSI_H, 26 | "i":kVK_ANSI_I, 27 | "j":kVK_ANSI_J, 28 | "k":kVK_ANSI_K, 29 | "l":kVK_ANSI_L, 30 | "m":kVK_ANSI_M, 31 | "n":kVK_ANSI_N, 32 | "o":kVK_ANSI_O, 33 | "p":kVK_ANSI_P, 34 | "q":kVK_ANSI_Q, 35 | "r":kVK_ANSI_R, 36 | "s":kVK_ANSI_S, 37 | "t":kVK_ANSI_T, 38 | "u":kVK_ANSI_U, 39 | "v":kVK_ANSI_V, 40 | "w":kVK_ANSI_W, 41 | "x":kVK_ANSI_X, 42 | "y":kVK_ANSI_Y, 43 | "z":kVK_ANSI_Z, 44 | "0":kVK_ANSI_0, 45 | "1":kVK_ANSI_1, 46 | "2":kVK_ANSI_2, 47 | "3":kVK_ANSI_3, 48 | "4":kVK_ANSI_4, 49 | "5":kVK_ANSI_5, 50 | "6":kVK_ANSI_6, 51 | "7":kVK_ANSI_7, 52 | "8":kVK_ANSI_8, 53 | "9":kVK_ANSI_9, 54 | "`":kVK_ANSI_Grave, 55 | "=":kVK_ANSI_Equal, 56 | "-":kVK_ANSI_Minus, 57 | "]":kVK_ANSI_RightBracket, 58 | "[":kVK_ANSI_LeftBracket, 59 | "\"":kVK_ANSI_Quote, 60 | ";":kVK_ANSI_Semicolon, 61 | "\\":kVK_ANSI_Backslash, 62 | ",":kVK_ANSI_Comma, 63 | "/":kVK_ANSI_Slash, 64 | ".":kVK_ANSI_Period, 65 | "§":kVK_ISO_Section, 66 | "f1":kVK_F1, 67 | "f2":kVK_F2, 68 | "f3":kVK_F3, 69 | "f4":kVK_F4, 70 | "f5":kVK_F5, 71 | "f6":kVK_F6, 72 | "f7":kVK_F7, 73 | "f8":kVK_F8, 74 | "f9":kVK_F9, 75 | "f10":kVK_F10, 76 | "f11":kVK_F11, 77 | "f12":kVK_F12, 78 | "f13":kVK_F13, 79 | "f14":kVK_F14, 80 | "f15":kVK_F15, 81 | "f16":kVK_F16, 82 | "f17":kVK_F17, 83 | "f18":kVK_F18, 84 | "f19":kVK_F19, 85 | "f20":kVK_F20, 86 | "pad.":kVK_ANSI_KeypadDecimal, 87 | "pad*":kVK_ANSI_KeypadMultiply, 88 | "pad+":kVK_ANSI_KeypadPlus, 89 | "pad/":kVK_ANSI_KeypadDivide, 90 | "pad-":kVK_ANSI_KeypadMinus, 91 | "pad=":kVK_ANSI_KeypadEquals, 92 | "pad0":kVK_ANSI_Keypad0, 93 | "pad1":kVK_ANSI_Keypad1, 94 | "pad2":kVK_ANSI_Keypad2, 95 | "pad3":kVK_ANSI_Keypad3, 96 | "pad4":kVK_ANSI_Keypad4, 97 | "pad5":kVK_ANSI_Keypad5, 98 | "pad6":kVK_ANSI_Keypad6, 99 | "pad7":kVK_ANSI_Keypad7, 100 | "pad8":kVK_ANSI_Keypad8, 101 | "pad9":kVK_ANSI_Keypad9, 102 | "padclear":kVK_ANSI_KeypadClear, 103 | "padenter":kVK_ANSI_KeypadEnter, 104 | "return":kVK_Return, 105 | "tab":kVK_Tab, 106 | "space":kVK_Space, 107 | "delete":kVK_Delete, 108 | "escape":kVK_Escape, 109 | "help":kVK_Help, 110 | "home":kVK_Home, 111 | "pageup":kVK_PageUp, 112 | "forwarddelete":kVK_ForwardDelete, 113 | "end":kVK_End, 114 | "pagedown":kVK_PageDown, 115 | "left":kVK_LeftArrow, 116 | "right":kVK_RightArrow, 117 | "down":kVK_DownArrow, 118 | "up":kVK_UpArrow 119 | ] 120 | 121 | class HotKeyParser { 122 | class func charToKeyCode(_ char: String) -> UInt32 { 123 | return charsToKeyCodes.object(forKey: char) as! UInt32 124 | } 125 | 126 | class func modifiersToModCode(_ modifiers: [String]) -> UInt32 { 127 | var code: UInt32 = 0 128 | for mod in modifiers { 129 | let modCode = modifiersToKeyCodes.object(forKey: mod) as! UInt32 130 | code |= modCode 131 | } 132 | 133 | return code 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /PassHUD/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 0.2.2 21 | CFBundleVersion 22 | 0.2.2 23 | LSApplicationCategoryType 24 | public.app-category.utilities 25 | LSMinimumSystemVersion 26 | $(MACOSX_DEPLOYMENT_TARGET) 27 | LSUIElement 28 | 29 | NSHumanReadableCopyright 30 | Copyright © 2018 mnussbaum. All rights reserved. 31 | NSMainStoryboardFile 32 | Main 33 | NSPrincipalClass 34 | NSApplication 35 | 36 | 37 | -------------------------------------------------------------------------------- /PassHUD/LRUCache.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LRUCache.swift 3 | // PassHUD 4 | // 5 | // Created by Nussbaum, Michael on 10/26/18. 6 | // Written with help from https://dzone.com/articles/how-to-implement-cache-lru-with-swift 7 | // 8 | 9 | import Cocoa 10 | 11 | class LinkedListNode { 12 | var previous: LinkedListNode? 13 | var next: LinkedListNode? 14 | var value: AnyHashable 15 | 16 | init(_ value: AnyHashable) { 17 | self.value = value 18 | } 19 | } 20 | 21 | extension LinkedListNode: CustomStringConvertible { 22 | var description: String { 23 | return self.value.description 24 | } 25 | } 26 | 27 | class DoublyLinkedList { 28 | var head: LinkedListNode? 29 | var tail: LinkedListNode? 30 | 31 | func addHead(_ value: AnyHashable) -> LinkedListNode { 32 | let newNode = LinkedListNode(value) 33 | if let head = self.head { 34 | head.previous = newNode 35 | newNode.next = head 36 | newNode.previous = nil 37 | } else { 38 | self.tail = newNode 39 | } 40 | self.head = newNode 41 | 42 | return newNode 43 | } 44 | 45 | func moveToHead(_ node: LinkedListNode) { 46 | guard node !== self.head else { return } 47 | 48 | let previous = node.previous 49 | let next = node.next 50 | node.previous?.next = next 51 | node.next?.previous = previous 52 | 53 | node.next = self.head 54 | node.previous = nil 55 | 56 | if node === tail { 57 | self.tail = previous 58 | } 59 | self.head?.previous = node 60 | self.head = node 61 | } 62 | 63 | func removeLast() -> LinkedListNode? { 64 | guard let originalTail = self.tail else { 65 | return nil 66 | } 67 | 68 | if self.tail === self.head { 69 | self.head = nil 70 | } 71 | 72 | let previous = self.tail?.previous 73 | previous?.next = nil 74 | self.tail = previous 75 | 76 | return originalTail 77 | } 78 | } 79 | 80 | class LRUCache: Sequence { 81 | let capacity: Int 82 | var members = Dictionary() 83 | var memberList = DoublyLinkedList() 84 | 85 | init(capacity: Int) { 86 | self.capacity = Swift.max(0, capacity) 87 | } 88 | 89 | func addValue(_ value: AnyHashable) { 90 | if let node = self.members[value] { 91 | self.memberList.moveToHead(node) 92 | } else { 93 | let node = self.memberList.addHead(value) 94 | self.members[value] = node 95 | } 96 | 97 | if self.members.count > self.capacity { 98 | if let removedNode = self.memberList.removeLast() { 99 | self.members.removeValue(forKey: removedNode.value) 100 | } 101 | } 102 | } 103 | 104 | func makeIterator() -> LRUCacheIterator { 105 | return LRUCacheIterator(self) 106 | } 107 | 108 | func isEmpty() -> Bool { 109 | return self.members.isEmpty 110 | } 111 | } 112 | 113 | struct LRUCacheIterator: IteratorProtocol { 114 | var nextCacheNode: LinkedListNode? 115 | 116 | init(_ lruCache: LRUCache) { 117 | self.nextCacheNode = lruCache.memberList.head 118 | } 119 | 120 | mutating func next() -> AnyHashable? { 121 | if let cacheNode = self.nextCacheNode { 122 | self.nextCacheNode = cacheNode.next 123 | return cacheNode.value 124 | } 125 | 126 | return nil 127 | } 128 | } 129 | -------------------------------------------------------------------------------- /PassHUD/NSImage.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSImage.swift 3 | // PassHUD 4 | // 5 | // Created by Nussbaum, Michael on 12/18/18. 6 | // Copyright © 2018 mnussbaum. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | // Based off of https://gist.github.com/usagimaru/c0a03ef86b5829fb9976b650ec2f1bf4 12 | 13 | extension NSImage { 14 | func copyWithTint(color: NSColor) -> NSImage { 15 | let image = self.copy() as! NSImage 16 | 17 | image.lockFocus() 18 | color.set() 19 | NSRect( 20 | origin: NSZeroPoint, 21 | size: image.size 22 | ).fill(using: .sourceAtop) 23 | image.isTemplate = false 24 | image.unlockFocus() 25 | 26 | return image 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /PassHUD/NSString.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NSString.swift 3 | // PassHUD 4 | // 5 | // Created by Nussbaum, Michael on 12/18/18. 6 | // Copyright © 2018 mnussbaum. All rights reserved. 7 | // 8 | 9 | import Cocoa 10 | 11 | // Based off of: 12 | // * https://stackoverflow.com/questions/35882103/hash-value-of-string-that-would-be-stable-across-ios-releases 13 | // * https://stackoverflow.com/questions/11120840/hash-string-into-rgb-color 14 | 15 | extension String { 16 | func hashCode() -> UInt64 { 17 | var result = UInt64 (5381) 18 | let buf = [UInt8](self.utf8) 19 | for b in buf { 20 | result = 127 * (result & 0x00FFFFFFFFFFFFFF) + UInt64(b) 21 | } 22 | 23 | return result 24 | } 25 | 26 | func toRGB() -> NSColor { 27 | let hash = self.hashCode() 28 | var red = max(CGFloat((hash & 0xFF0000) >> 16) / 255.0, 0.01) 29 | var green = max(CGFloat((hash & 0x00FF00) >> 8) / 255.0, 0.01) 30 | var blue = max(CGFloat(hash & 0x0000FF) / 255.0, 0.01) 31 | 32 | // Ensure a minimum luminance 33 | // https://en.wikipedia.org/wiki/Relative_luminance 34 | while (0.2126 * red + 0.7152 * green + 0.0722 * blue) <= 0.5 { 35 | blue = min(blue * 2, 1.0) 36 | red = min(red * 2, 1.0) 37 | green = min(green * 2, 1.0) 38 | } 39 | 40 | // Attempt to avoid browns from close color combos, 41 | // without boosting one color too much 42 | while abs(blue - red) < 0.2 { 43 | red = min(red + 0.1, 1.0) 44 | blue = max(blue - 0.1, 0) 45 | } 46 | while abs(green - red) < 0.2 { 47 | green = min(green + 0.1, 1.0) 48 | red = max(red - 0.1, 0) 49 | } 50 | while abs(blue - green) < 0.2 { 51 | blue = min(blue + 0.1, 1.0) 52 | green = max(green - 0.1, 0) 53 | } 54 | 55 | return NSColor( 56 | red: red, 57 | green: green, 58 | blue: blue, 59 | alpha: CGFloat(1.0) 60 | ) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /PassHUD/PassHUD.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.app-sandbox 6 | 7 | com.apple.security.files.user-selected.read-only 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /PassHUDScreenShot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mnussbaum/PassHUD/72a33d55f03090090bf429bbebb85220d26f6702/PassHUDScreenShot.png -------------------------------------------------------------------------------- /PassHUDTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /PassHUDTests/PassHUDTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PassHUDTests.swift 3 | // PassHUDTests 4 | // 5 | // Created by Nussbaum, Michael on 10/10/18. 6 | // Copyright © 2018 mnussbaum. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import PassHUD 11 | 12 | class PassHUDTests: XCTestCase { 13 | 14 | override func setUp() { 15 | // Put setup code here. This method is called before the invocation of each test method in the class. 16 | } 17 | 18 | override func tearDown() { 19 | // Put teardown code here. This method is called after the invocation of each test method in the class. 20 | } 21 | 22 | func testExample() { 23 | // This is an example of a functional test case. 24 | // Use XCTAssert and related functions to verify your tests produce the correct results. 25 | } 26 | 27 | func testPerformanceExample() { 28 | // This is an example of a performance test case. 29 | self.measure { 30 | // Put the code you want to measure the time of here. 31 | } 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /PassHUDUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 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 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /PassHUDUITests/PaddHUDUITests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PassHUDUITests.swift 3 | // PassHUDUITests 4 | // 5 | // Created by Nussbaum, Michael on 10/10/18. 6 | // Copyright © 2018 mnussbaum. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | class PassHUDUITests: XCTestCase { 12 | 13 | override func setUp() { 14 | // Put setup code here. This method is called before the invocation of each test method in the class. 15 | 16 | // In UI tests it is usually best to stop immediately when a failure occurs. 17 | continueAfterFailure = false 18 | 19 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 20 | XCUIApplication().launch() 21 | 22 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 23 | } 24 | 25 | override func tearDown() { 26 | // Put teardown code here. This method is called after the invocation of each test method in the class. 27 | } 28 | 29 | func testExample() { 30 | // Use recording to get started writing UI tests. 31 | // Use XCTAssert and related functions to verify your tests produce the correct results. 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | platform :osx, "10.13" 2 | 3 | target "PassHUD" do 4 | use_frameworks! 5 | 6 | pod "FavIcon", "~> 3.0.4" 7 | pod "SPTPersistentCache", "~> 1.1.0" 8 | pod "Yams", "~> 1.0.1" 9 | 10 | target "PassHUDTests" do 11 | inherit! :search_paths 12 | end 13 | 14 | target "PassHUDUITests" do 15 | inherit! :search_paths 16 | end 17 | 18 | end 19 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FavIcon (3.0.4) 3 | - SPTPersistentCache (1.1.0) 4 | - Yams (1.0.1) 5 | 6 | DEPENDENCIES: 7 | - FavIcon (~> 3.0.4) 8 | - SPTPersistentCache (~> 1.1.0) 9 | - Yams (~> 1.0.1) 10 | 11 | SPEC REPOS: 12 | https://github.com/cocoapods/specs.git: 13 | - FavIcon 14 | - SPTPersistentCache 15 | - Yams 16 | 17 | SPEC CHECKSUMS: 18 | FavIcon: 4eb40c6827e1a040b979d320b6c583409dbd9aba 19 | SPTPersistentCache: df36ea46762d7cf026502bbb86a8b79d0080dff4 20 | Yams: 572f625a8b719b73e0b57fd313c680f3e2161fe9 21 | 22 | PODFILE CHECKSUM: 53e1d37f30e536f1e9a843c04946da0538c9abe2 23 | 24 | COCOAPODS: 1.6.0.beta.2 25 | -------------------------------------------------------------------------------- /Pods/FavIcon/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2018 Leon Breedt 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /Pods/FavIcon/README.md: -------------------------------------------------------------------------------- 1 | # FavIcon [![License](https://img.shields.io/badge/license-Apache%202.0-lightgrey.svg)](https://raw.githubusercontent.com/leonbreedt/FavIcon/master/LICENSE) [![Build Status](https://travis-ci.org/leonbreedt/FavIcon.svg)](https://travis-ci.org/leonbreedt/FavIcon) [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) ![Swift 4.0](https://img.shields.io/badge/Swift-4.0-orange.svg) ![platforms](https://img.shields.io/badge/platforms-iOS%20%7C%20macOS%20-lightgrey.svg) 2 | FavIcon is a tiny Swift library for downloading the favicon representing a website. 3 | 4 | Wait, why is a library needed to do this? Surely it's just a simple HTTP GET of 5 | `/favicon.ico`, right? Right? Well. Go have a read of [this StackOverflow 6 | post](http://stackoverflow.com/questions/19029342/favicons-best-practices), and 7 | see how you feel afterwards. 8 | 9 | ## Quick Start 10 | 11 | ### CocoaPods 12 | 13 | *Note:* CocoaPods (1.4.0 or later) is required. 14 | 15 | Add it to your `Podfile`: 16 | 17 | ```ruby 18 | use_frameworks! 19 | pod 'FavIcon', '~> 3.0.0' 20 | ``` 21 | 22 | ### Carthage 23 | 24 | Add it to your `Cartfile`: 25 | 26 | ```ogdl 27 | github "leonbreedt/FavIcon" ~> 3.0.0 28 | ``` 29 | 30 | ## Features 31 | - Detection of `/favicon.ico` if it exists 32 | - Parsing of the HTML at a URL, and scanning for appropriate `` or 33 | `` tags that refer to icons using Apple, Google or Microsoft 34 | conventions. 35 | - Discovery of and parsing of Web Application manifest JSON files to obtain 36 | lists of icons. 37 | - Discovery of and parsing of Microsoft browser configuration XML files for 38 | obtaining lists of icons. 39 | 40 | Yup. These are all potential ways of indicating that your website has an icon 41 | that can be used in user interfaces. Good work, fellow programmers. 👍 42 | 43 | ## Usage Example 44 | Perhaps you have a location in your user interface where you want to put 45 | the icon of a website the user is currently visiting? 46 | 47 | ```swift 48 | try FavIcon.downloadPreferred("https://apple.com") { result in 49 | if case let .success(image) = result { 50 | // On iOS, this is a UIImage, do something with it here. 51 | // This closure will be executed on the main queue, so it's safe to touch 52 | // the UI here. 53 | } 54 | } 55 | ``` 56 | 57 | This will detect all of the available icons at the URL, and if it is able to 58 | determine their sizes, it will try to find the icon closest in size to your 59 | desired size, otherwise, it will prefer the largest icon. If it has no idea of 60 | the size of any of the icons, it will prefer the first one it found. 61 | 62 | Of course, if this approach is too opaque for you, you can download them all 63 | using `downloadAll(url:completion:)`. 64 | 65 | Or perhaps you’d like to take a stab at downloading them yourself at a later 66 | time, choosing which icon you prefer based on your own criteria, in which case 67 | `scan(url:completion:)` will give you information about the detected icons, which 68 | you can feed to `download(url:completion:)` for downloading at your convenience. 69 | 70 | 71 | ## Example Project 72 | 73 | See the iOS project in `Example/` for a simple example of how to use the library. 74 | 75 | ## License 76 | 77 | Apache 2.0 78 | 79 | -------------------------------------------------------------------------------- /Pods/FavIcon/Sources/FavIcon/ContentTypes.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FavIcon 3 | // Copyright © 2018 Leon Breedt 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | 18 | import Foundation 19 | 20 | func parseHTTPContentType(_ headerValue: String) -> (mimeType: String, encoding: String.Encoding) { 21 | let headerComponents = headerValue 22 | .components(separatedBy: ";") 23 | .map { $0.trimmingCharacters(in: .whitespaces) } 24 | 25 | if headerComponents.count > 1 { 26 | let parameterValues = headerComponents[1..(uniqueKeysWithValues: parameterValues) 32 | 33 | // Default according to RFC is ISO-8859-1, but probably nothing obeys that, so default 34 | // to UTF-8 instead. 35 | var encoding = String.Encoding.utf8 36 | if let charset = parameters["charset"], let parsedEncoding = parseStringEncoding(charset) { 37 | encoding = parsedEncoding 38 | } 39 | 40 | return (mimeType: headerComponents[0], encoding: encoding) 41 | } else { 42 | return (mimeType: headerComponents[0], encoding: .utf8) 43 | } 44 | } 45 | 46 | func parseStringEncoding(_ value: String) -> String.Encoding? { 47 | switch value.lowercased() { 48 | case "iso-8859-1", "latin1": return .isoLatin1 49 | case "iso-8859-2", "latin2": return .isoLatin2 50 | case "iso-2022-jp": return .iso2022JP 51 | case "shift_jis": return .shiftJIS 52 | case "us-ascii": return .ascii 53 | case "utf-8": return .utf8 54 | case "utf-16": return .utf16 55 | case "utf-32": return .utf32 56 | case "utf-32be": return .utf32BigEndian 57 | case "utf-32le": return .utf32LittleEndian 58 | case "windows-1250": return .windowsCP1250 59 | case "windows-1251": return .windowsCP1251 60 | case "windows-1252": return .windowsCP1252 61 | case "windows-1253": return .windowsCP1253 62 | case "windows-1254": return .windowsCP1254 63 | case "x-mac-roman": return .macOSRoman 64 | default: 65 | return nil 66 | } 67 | } 68 | 69 | extension HTTPURLResponse { 70 | func mimeTypeAndEncoding() -> (mimeType: String, encoding: String.Encoding) { 71 | if let contentType = allHeaderFields["Content-Type"] as? String { 72 | return parseHTTPContentType(contentType) 73 | } 74 | return (mimeType: "application/octet-stream", encoding: .utf8) 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Pods/FavIcon/Sources/FavIcon/Download.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FavIcon 3 | // Copyright © 2018 Leon Breedt 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | 18 | import Foundation 19 | 20 | enum DownloadResult { 21 | case text(value: String, mimeType: String, actualURL: URL) 22 | case binary(data: Data, mimeType: String, actualURL: URL) 23 | case exists 24 | case error(Error) 25 | } 26 | 27 | enum DownloadError: Error { 28 | case invalidResponse 29 | case emptyResponse 30 | case invalidTextResponse 31 | case notFound 32 | case serverError(code: Int) 33 | } 34 | 35 | private let downloadSession = URLSession(configuration: .ephemeral) 36 | 37 | func downloadURLs(_ urls: [URL], method: String = "GET", completion: @escaping ([DownloadResult]) -> Void) { 38 | let dispatchGroup = DispatchGroup() 39 | 40 | var results = [(index: Int, result: DownloadResult)]() 41 | let addResult: (Int, DownloadResult) -> Void = { (index: Int, result: DownloadResult) in 42 | DispatchQueue.main.async { 43 | results.append((index: index, result: result)) 44 | } 45 | } 46 | 47 | for (index, url) in urls.enumerated() { 48 | dispatchGroup.enter() 49 | 50 | var request = URLRequest(url: url) 51 | request.httpMethod = method 52 | let task = downloadSession.dataTask(with: request) { data, response, error in 53 | defer { 54 | dispatchGroup.leave() 55 | } 56 | 57 | guard error == nil else { 58 | addResult(index, .error(error!)) 59 | return 60 | } 61 | 62 | guard let response = response else { 63 | addResult(index, .error(DownloadError.invalidResponse)) 64 | return 65 | } 66 | 67 | if let httpResponse = response as? HTTPURLResponse { 68 | if httpResponse.statusCode == 404 { 69 | addResult(index, .error(DownloadError.notFound)) 70 | return 71 | } 72 | 73 | if httpResponse.statusCode < 200 || httpResponse.statusCode > 299 { 74 | addResult(index, .error(DownloadError.serverError(code: httpResponse.statusCode))) 75 | return 76 | } 77 | 78 | if method.lowercased() == "head" { 79 | addResult(index, .exists) 80 | return 81 | } 82 | } 83 | 84 | if let data = data { 85 | let mimeType = response.mimeType ?? "application/octet-stream" 86 | let encoding: String.Encoding = response.textEncodingName != nil 87 | ? parseStringEncoding(response.textEncodingName!) ?? .utf8 88 | : .utf8 89 | if mimeType.starts(with: "text/") || mimeType == "application/json" { 90 | guard let text = String(data: data, encoding: encoding) else { 91 | addResult(index, .error(DownloadError.invalidTextResponse)) 92 | return 93 | } 94 | addResult(index, .text(value: text, mimeType: mimeType, actualURL: response.url!)) 95 | return 96 | } else { 97 | addResult(index, .binary(data: data, mimeType: mimeType, actualURL: response.url!)) 98 | return 99 | } 100 | } else { 101 | addResult(index, .error(DownloadError.emptyResponse)) 102 | return 103 | } 104 | } 105 | 106 | task.resume() 107 | } 108 | 109 | dispatchGroup.notify(queue: .main) { 110 | let sortedResults = 111 | results 112 | .sorted(by: { $0.index < $1.index }) 113 | .map { $0.result } 114 | completion(sortedResults) 115 | } 116 | } 117 | 118 | func downloadURL(_ url: URL, method: String = "GET", completion: @escaping (DownloadResult) -> Void) { 119 | downloadURLs([url], method: method) { results in 120 | completion(results.first!) 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /Pods/FavIcon/Sources/FavIcon/Icon.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FavIcon 3 | // Copyright © 2018 Leon Breedt 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | 18 | import Foundation 19 | 20 | @available(*, deprecated, message: "renamed to Icon") 21 | public typealias DetectedIcon = Icon 22 | 23 | /// Represents a detected icon. 24 | public struct Icon { 25 | /// The absolute URL for the icon file. 26 | public let url: URL 27 | /// The type of the icon. 28 | public let type: IconType 29 | /// The width of the icon, if known, in pixels. 30 | public let width: Int? 31 | /// The height of the icon, if known, in pixels. 32 | public let height: Int? 33 | 34 | init(url: URL, type: IconType, width: Int? = nil, height: Int? = nil) { 35 | self.url = url 36 | self.type = type 37 | self.width = width 38 | self.height = height 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Pods/FavIcon/Sources/FavIcon/IconType.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FavIcon 3 | // Copyright © 2018 Leon Breedt 4 | // 5 | // Licensed under the Apache License, Version 2.0 (the "License"); 6 | // you may not use this file except in compliance with the License. 7 | // You may obtain a copy of the License at 8 | // 9 | // http://www.apache.org/licenses/LICENSE-2.0 10 | // 11 | // Unless required by applicable law or agreed to in writing, software 12 | // distributed under the License is distributed on an "AS IS" BASIS, 13 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | // See the License for the specific language governing permissions and 15 | // limitations under the License. 16 | // 17 | 18 | import Foundation 19 | 20 | @available(*, deprecated, message: "renamed to IconType") 21 | public typealias DetectedIconType = IconType 22 | 23 | /// Enumerates the types of detected icons. 24 | public enum IconType: UInt { 25 | /// A shortcut icon. 26 | case shortcut 27 | /// A classic icon (usually in the range 16x16 to 48x48). 28 | case classic 29 | /// A Google TV icon. 30 | case googleTV 31 | /// An icon used by Chrome/Android. 32 | case googleAndroidChrome 33 | /// An icon used by Safari on OS X for tabs. 34 | case appleOSXSafariTab 35 | /// An icon used iOS for Web Clips on home screen. 36 | case appleIOSWebClip 37 | /// An icon used for a pinned site in Windows. 38 | case microsoftPinnedSite 39 | /// An icon defined in a Web Application Manifest JSON file, mainly Android/Chrome. 40 | case webAppManifest 41 | } 42 | 43 | 44 | -------------------------------------------------------------------------------- /Pods/FavIcon/Sources/Modules/libxml2-favicon.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | #import -------------------------------------------------------------------------------- /Pods/FavIcon/Sources/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | module libxmlFavicon [system] { 2 | link "xml2" 3 | umbrella header "libxml2-favicon.h" 4 | export * 5 | module * { export * } 6 | } -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FavIcon (3.0.4) 3 | - SPTPersistentCache (1.1.0) 4 | - Yams (1.0.1) 5 | 6 | DEPENDENCIES: 7 | - FavIcon (~> 3.0.4) 8 | - SPTPersistentCache (~> 1.1.0) 9 | - Yams (~> 1.0.1) 10 | 11 | SPEC REPOS: 12 | https://github.com/cocoapods/specs.git: 13 | - FavIcon 14 | - SPTPersistentCache 15 | - Yams 16 | 17 | SPEC CHECKSUMS: 18 | FavIcon: 4eb40c6827e1a040b979d320b6c583409dbd9aba 19 | SPTPersistentCache: df36ea46762d7cf026502bbb86a8b79d0080dff4 20 | Yams: 572f625a8b719b73e0b57fd313c680f3e2161fe9 21 | 22 | PODFILE CHECKSUM: 53e1d37f30e536f1e9a843c04946da0538c9abe2 23 | 24 | COCOAPODS: 1.6.0.beta.2 25 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/mnussbaum.xcuserdatad/xcschemes/FavIcon.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/mnussbaum.xcuserdatad/xcschemes/Pods-PassHUD.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/mnussbaum.xcuserdatad/xcschemes/Pods-PassHUDTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/mnussbaum.xcuserdatad/xcschemes/Pods-PassHUDUITests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/mnussbaum.xcuserdatad/xcschemes/SPTPersistentCache.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/mnussbaum.xcuserdatad/xcschemes/Yams.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 66 | 67 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /Pods/Pods.xcodeproj/xcuserdata/mnussbaum.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | FavIcon.xcscheme 8 | 9 | isShown 10 | 11 | 12 | Pods-PassHUD.xcscheme 13 | 14 | isShown 15 | 16 | 17 | Pods-PassHUDTests.xcscheme 18 | 19 | isShown 20 | 21 | 22 | Pods-PassHUDUITests.xcscheme 23 | 24 | isShown 25 | 26 | 27 | SPTPersistentCache.xcscheme 28 | 29 | isShown 30 | 31 | 32 | Yams.xcscheme 33 | 34 | isShown 35 | 36 | 37 | 38 | SuppressBuildableAutocreation 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/Categories/NSError+SPTPersistentCacheDomainErrors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import 22 | 23 | #import 24 | 25 | /** 26 | * Category to instantiate NSError objects with a specific domain for SPTPersistentCache. 27 | */ 28 | @interface NSError (SPTPersistentCacheDomainErrors) 29 | 30 | /** 31 | * Returns a new instance of NSError with a SPTPersistentCache domain and an error code. 32 | * @param persistentDataCacheLoadingError The error code for the NSError object. 33 | */ 34 | + (instancetype)spt_persistentDataCacheErrorWithCode:(SPTPersistentCacheLoadingError)persistentDataCacheLoadingError; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/Categories/NSError+SPTPersistentCacheDomainErrors.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import "NSError+SPTPersistentCacheDomainErrors.h" 22 | 23 | @implementation NSError (SPTPersistentCacheDomainErrors) 24 | 25 | + (instancetype)spt_persistentDataCacheErrorWithCode:(SPTPersistentCacheLoadingError)persistentDataCacheLoadingError 26 | { 27 | return [NSError errorWithDomain:SPTPersistentCacheErrorDomain 28 | code:persistentDataCacheLoadingError 29 | userInfo:nil]; 30 | } 31 | 32 | @end 33 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCache+Private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | 22 | #import 23 | 24 | @class SPTPersistentCacheFileManager; 25 | @class SPTPersistentCacheGarbageCollector; 26 | @class SPTPersistentCachePosixWrapper; 27 | 28 | void SPTPersistentCacheSafeDispatch(_Nullable dispatch_queue_t queue, _Nonnull dispatch_block_t block); 29 | 30 | NS_ASSUME_NONNULL_BEGIN 31 | 32 | /// Private interface exposed for testability. 33 | @interface SPTPersistentCache () 34 | 35 | @property (nonatomic, copy, readonly) SPTPersistentCacheOptions *options; 36 | 37 | @property (nonatomic, copy, readonly, nullable) SPTPersistentCacheDebugCallback debugOutput; 38 | 39 | /// Serial queue used to run all internal stuff 40 | @property (nonatomic, strong, readonly) NSOperationQueue *workQueue; 41 | 42 | @property (nonatomic, strong, readonly) NSFileManager *fileManager; 43 | @property (nonatomic, strong, readonly) SPTPersistentCacheFileManager *dataCacheFileManager; 44 | 45 | @property (nonatomic, strong, readonly) SPTPersistentCacheGarbageCollector *garbageCollector; 46 | 47 | @property (nonatomic, assign, readonly) NSTimeInterval currentDateTimeInterval; 48 | @property (nonatomic, strong, readonly) SPTPersistentCachePosixWrapper *posixWrapper; 49 | 50 | - (void)runRegularGC; 51 | - (BOOL)pruneBySize; 52 | 53 | /** 54 | * forceExpire = YES treat all unlocked files like they expired 55 | * forceLocked = YES ignore lock status 56 | */ 57 | - (void)collectGarbageForceExpire:(BOOL)forceExpire forceLocked:(BOOL)forceLocked; 58 | 59 | - (void)dispatchEmptyResponseWithResult:(SPTPersistentCacheResponseCode)result 60 | callback:(SPTPersistentCacheResponseCallback _Nullable)callback 61 | onQueue:(dispatch_queue_t _Nullable)queue; 62 | 63 | - (void)dispatchError:(NSError *)error 64 | result:(SPTPersistentCacheResponseCode)result 65 | callback:(SPTPersistentCacheResponseCallback _Nullable)callback 66 | onQueue:(dispatch_queue_t _Nullable)queue; 67 | 68 | - (void)doWork:(void (^)(void))block priority:(NSOperationQueuePriority)priority qos:(NSQualityOfService)qos; 69 | 70 | - (void)logTimingForKey:(NSString *)key method:(SPTPersistentCacheDebugMethodType)method type:(SPTPersistentCacheDebugTimingType)type; 71 | 72 | @end 73 | 74 | NS_ASSUME_NONNULL_END 75 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCacheDebugUtilities.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | 22 | #import 23 | #import 24 | 25 | /** 26 | * Executes the debug callback safely avoiding a crash if it is set to nil. 27 | * 28 | * @param debugMessage The debug message. 29 | * @param debugCallback The callback block to execute safely. 30 | */ 31 | void SPTPersistentCacheSafeDebugCallback(NSString *debugMessage, 32 | SPTPersistentCacheDebugCallback debugCallback); 33 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCacheDebugUtilities.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | 22 | #import "SPTPersistentCacheDebugUtilities.h" 23 | 24 | void SPTPersistentCacheSafeDebugCallback(NSString *debugMessage, 25 | SPTPersistentCacheDebugCallback debugCallback) 26 | { 27 | if (debugCallback) { 28 | debugCallback(debugMessage); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCacheFileManager+Private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import "SPTPersistentCacheFileManager.h" 22 | #import 23 | 24 | NS_ASSUME_NONNULL_BEGIN 25 | 26 | /// Private interface exposed for testability. 27 | @interface SPTPersistentCacheFileManager () 28 | 29 | @property (nonatomic, copy, readonly) SPTPersistentCacheOptions *options; 30 | @property (nonatomic, copy, readonly, nullable) SPTPersistentCacheDebugCallback debugOutput; 31 | @property (nonatomic, strong, readonly) NSFileManager *fileManager; 32 | 33 | @end 34 | 35 | NS_ASSUME_NONNULL_END 36 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCacheFileManager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import 22 | 23 | typedef long long SPTPersistentCacheDiskSize; 24 | 25 | extern const NSUInteger SPTPersistentCacheFileManagerSubDirNameLength; 26 | 27 | @class SPTPersistentCacheOptions; 28 | 29 | NS_ASSUME_NONNULL_BEGIN 30 | 31 | /** 32 | * An object that encapsulates file-related operations of SPTPersistentCache. 33 | */ 34 | @interface SPTPersistentCacheFileManager : NSObject 35 | 36 | /// The total amount of bytes used by the cache given the reciever’s options. 37 | @property (nonatomic, readonly) NSUInteger totalUsedSizeInBytes; 38 | 39 | - (instancetype)init NS_UNAVAILABLE; 40 | + (instancetype)new NS_UNAVAILABLE; 41 | 42 | /** 43 | * Initializes a new file manager set with specific options. 44 | * 45 | * @param options Options of the permanent cache. 46 | */ 47 | - (instancetype)initWithOptions:(SPTPersistentCacheOptions *)options NS_DESIGNATED_INITIALIZER; 48 | 49 | /** 50 | * Creates the directory that will be used to persist the cached data. Returns YES if the operation is successful, 51 | * Or NO otherwise. 52 | */ 53 | - (BOOL)createCacheDirectory; 54 | 55 | /** 56 | * Returns the path for the subdirectory containing the data associated to a specific key. 57 | * 58 | * @param key Key of the data you are looking for. 59 | */ 60 | - (NSString *)subDirectoryPathForKey:(NSString *)key; 61 | 62 | /** 63 | * Returns the path for the data associated to a specific key. 64 | * 65 | * @param key Key of the data you are looking for. 66 | */ 67 | - (NSString *)pathForKey:(NSString *)key; 68 | 69 | /** 70 | * Removes all data files in the cache. 71 | */ 72 | - (void)removeAllData; 73 | 74 | /** 75 | * Removes the associated cached file for a key. 76 | * 77 | * @param key Key of the data you are looking for. 78 | */ 79 | - (void)removeDataForKey:(NSString *)key; 80 | 81 | /** 82 | * Based on a specific cache size, return a size optimized for the disk space. 83 | * 84 | * @param currentCacheSize Cache size to be optimized 85 | */ 86 | - (SPTPersistentCacheDiskSize)optimizedDiskSizeForCacheSize:(SPTPersistentCacheDiskSize)currentCacheSize; 87 | 88 | /** 89 | * Returns the size of some data located at a specific path. 90 | * 91 | * @param filePath Path of a specific file. 92 | */ 93 | - (NSUInteger)getFileSizeAtPath:(NSString *)filePath; 94 | 95 | @end 96 | 97 | NS_ASSUME_NONNULL_END 98 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCacheGarbageCollector.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import 22 | 23 | @class SPTPersistentCache; 24 | @class SPTPersistentCacheOptions; 25 | 26 | @interface SPTPersistentCacheGarbageCollector : NSObject 27 | 28 | /** 29 | * Persistent Cache that will be used for garbage collection operations. 30 | */ 31 | @property (nonatomic, weak, readonly) SPTPersistentCache *cache; 32 | 33 | /** 34 | * Dispatch queue where the operations will take place. 35 | */ 36 | @property (nonatomic, strong, readonly) NSOperationQueue *queue; 37 | 38 | /** 39 | * Returns YES if the internal timer of proxy is scheduled to perform garbage collection of the cache. 40 | */ 41 | @property (nonatomic, readonly, getter=isGarbageCollectionScheduled) BOOL garbageCollectionScheduled; 42 | 43 | /** 44 | * Initializes the timer proxy on a specific queue using a specific data cache. 45 | * 46 | * @param cache Persistent Cache that will be used for garbage collection operations. 47 | * @param options Cache options to configure this garbage collector. 48 | * @param queue NSOperation queue where the operations will take place. 49 | */ 50 | - (instancetype)initWithCache:(SPTPersistentCache *)cache 51 | options:(SPTPersistentCacheOptions *)options 52 | queue:(NSOperationQueue *)queue; 53 | 54 | /** 55 | * Schedules the garbage collection operation. 56 | * 57 | * @warning The owner of the reference to this object should call 58 | * unscheduleGarbageCollection on its dealloc method to prevent a retain cycle 59 | * caused by an internal timer. 60 | */ 61 | - (void)schedule; 62 | 63 | /** 64 | * Unschedules the garbage collection operation. 65 | * 66 | * @warning Ensure the garbage collector is unscheduled to break the retain 67 | * cycle that could be caused by the internal timer in this class. 68 | */ 69 | - (void)unschedule; 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCacheGarbageCollector.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import "SPTPersistentCacheGarbageCollector.h" 22 | #import "SPTPersistentCacheDebugUtilities.h" 23 | #import "SPTPersistentCache+Private.h" 24 | 25 | static BOOL SPTPersistentCacheGarbageCollectorSchedulerIsInMainQueue(void); 26 | 27 | static const NSTimeInterval SPTPersistentCacheGarbageCollectorSchedulerTimerTolerance = 300; 28 | 29 | @interface SPTPersistentCacheGarbageCollector () 30 | @property (nonatomic, strong) NSTimer *timer; 31 | @property (nonatomic, copy) SPTPersistentCacheOptions *options; 32 | @end 33 | 34 | 35 | @implementation SPTPersistentCacheGarbageCollector 36 | 37 | #pragma mark - Initializer 38 | 39 | - (instancetype)initWithCache:(SPTPersistentCache *)cache 40 | options:(SPTPersistentCacheOptions *)options 41 | queue:(NSOperationQueue *)queue 42 | { 43 | self = [super init]; 44 | if (self) { 45 | _options = [options copy]; 46 | _cache = cache; 47 | _queue = queue; 48 | } 49 | return self; 50 | } 51 | 52 | - (void)dealloc 53 | { 54 | /** 55 | * Intentionally Left Blank 56 | * 57 | * Our timer should be invalidated by unscheduling this garbage collector 58 | * on the -dealloc method of the object owning the reference. 59 | */ 60 | } 61 | 62 | #pragma mark - 63 | 64 | - (void)enqueueGarbageCollection:(NSTimer *)timer 65 | { 66 | __weak __typeof(self) const weakSelf = self; 67 | NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{ 68 | // We want to shadow `self` in this case. 69 | _Pragma("clang diagnostic push"); 70 | _Pragma("clang diagnostic ignored \"-Wshadow\""); 71 | __typeof(weakSelf) const self = weakSelf; 72 | _Pragma("clang diagnostic pop"); 73 | 74 | SPTPersistentCache * const cache = self.cache; 75 | 76 | [cache runRegularGC]; 77 | [cache pruneBySize]; 78 | }]; 79 | operation.queuePriority = self.options.garbageCollectionPriority; 80 | operation.qualityOfService = self.options.garbageCollectionQualityOfService; 81 | [self.queue addOperation:operation]; 82 | } 83 | 84 | - (void)schedule 85 | { 86 | if (!SPTPersistentCacheGarbageCollectorSchedulerIsInMainQueue()) { 87 | dispatch_async(dispatch_get_main_queue(), ^{ 88 | [self schedule]; 89 | }); 90 | 91 | return; 92 | } 93 | 94 | SPTPersistentCacheSafeDebugCallback([NSString stringWithFormat:@"runGarbageCollector:%@", self.timer], 95 | self.options.debugOutput); 96 | 97 | if (self.isGarbageCollectionScheduled) { 98 | return; 99 | } 100 | 101 | self.timer = [NSTimer timerWithTimeInterval:self.options.garbageCollectionInterval 102 | target:self 103 | selector:@selector(enqueueGarbageCollection:) 104 | userInfo:nil 105 | repeats:YES]; 106 | 107 | self.timer.tolerance = SPTPersistentCacheGarbageCollectorSchedulerTimerTolerance; 108 | 109 | [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSDefaultRunLoopMode]; 110 | } 111 | 112 | - (void)unschedule 113 | { 114 | if (!SPTPersistentCacheGarbageCollectorSchedulerIsInMainQueue()) { 115 | dispatch_async(dispatch_get_main_queue(), ^{ 116 | [self unschedule]; 117 | }); 118 | 119 | return; 120 | } 121 | 122 | SPTPersistentCacheSafeDebugCallback([NSString stringWithFormat:@"stopGarbageCollector:%@", self.timer], 123 | self.options.debugOutput); 124 | 125 | [self.timer invalidate]; 126 | 127 | self.timer = nil; 128 | } 129 | 130 | - (BOOL)isGarbageCollectionScheduled 131 | { 132 | return (self.timer != nil); 133 | } 134 | @end 135 | 136 | static BOOL SPTPersistentCacheGarbageCollectorSchedulerIsInMainQueue(void) 137 | { 138 | NSString *currentQueueLabelString = [NSString stringWithUTF8String:dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)]; 139 | NSString *mainQueueLabelString = [NSString stringWithUTF8String:dispatch_queue_get_label(dispatch_get_main_queue())]; 140 | return [currentQueueLabelString isEqualToString:mainQueueLabelString]; 141 | } 142 | 143 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCacheHeader.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import 22 | 23 | #import "NSError+SPTPersistentCacheDomainErrors.h" 24 | 25 | #include "crc32iso3309.h" 26 | 27 | const SPTPersistentCacheMagicType SPTPersistentCacheMagicValue = 0x46545053; // SPTF 28 | const size_t SPTPersistentCacheRecordHeaderSize = sizeof(SPTPersistentCacheRecordHeader); 29 | 30 | _Static_assert(sizeof(SPTPersistentCacheRecordHeader) == 64, 31 | "Struct SPTPersistentCacheRecordHeader has to be packed without padding"); 32 | _Static_assert(sizeof(SPTPersistentCacheRecordHeader) % 4 == 0, 33 | "Struct size has to be multiple of 4"); 34 | 35 | NS_INLINE BOOL SPTPersistentCachePointerMagicAlignCheck(const void *ptr) 36 | { 37 | const unsigned align = _Alignof(SPTPersistentCacheMagicType); 38 | uint64_t v = (uint64_t)(ptr); 39 | return (v % align == 0); 40 | } 41 | 42 | SPTPersistentCacheRecordHeader SPTPersistentCacheRecordHeaderMake(uint64_t ttl, 43 | uint64_t payloadSize, 44 | uint64_t updateTime, 45 | BOOL isLocked) 46 | 47 | { 48 | SPTPersistentCacheRecordHeader dummy; 49 | memset(&dummy, 0, SPTPersistentCacheRecordHeaderSize); 50 | SPTPersistentCacheRecordHeader *header = &dummy; 51 | 52 | header->magic = SPTPersistentCacheMagicValue; 53 | header->headerSize = (uint32_t)SPTPersistentCacheRecordHeaderSize; 54 | header->refCount = (isLocked ? 1 : 0); 55 | header->ttl = ttl; 56 | header->payloadSizeBytes = payloadSize; 57 | header->updateTimeSec = updateTime; 58 | header->crc = SPTPersistentCacheCalculateHeaderCRC(header); 59 | 60 | return dummy; 61 | } 62 | 63 | SPTPersistentCacheRecordHeader *SPTPersistentCacheGetHeaderFromData(void *data, size_t size) 64 | { 65 | if (size < SPTPersistentCacheRecordHeaderSize) { 66 | return NULL; 67 | } 68 | 69 | return (SPTPersistentCacheRecordHeader *)data; 70 | } 71 | 72 | int /*SPTPersistentCacheLoadingError*/ SPTPersistentCacheValidateHeader(const SPTPersistentCacheRecordHeader *header) 73 | { 74 | if (header == NULL) { 75 | return SPTPersistentCacheLoadingErrorInternalInconsistency; 76 | } 77 | 78 | // Check that header could be read according to alignment 79 | if (!SPTPersistentCachePointerMagicAlignCheck(header)) { 80 | return SPTPersistentCacheLoadingErrorHeaderAlignmentMismatch; 81 | } 82 | 83 | // 1. Check magic 84 | if (header->magic != SPTPersistentCacheMagicValue) { 85 | return SPTPersistentCacheLoadingErrorMagicMismatch; 86 | } 87 | 88 | // 2. Check CRC 89 | uint32_t crc = SPTPersistentCacheCalculateHeaderCRC(header); 90 | if (crc != header->crc) { 91 | return SPTPersistentCacheLoadingErrorInvalidHeaderCRC; 92 | } 93 | 94 | // 3. Check header size 95 | if (header->headerSize != SPTPersistentCacheRecordHeaderSize) { 96 | return SPTPersistentCacheLoadingErrorWrongHeaderSize; 97 | } 98 | 99 | return -1; 100 | } 101 | 102 | NSError * SPTPersistentCacheCheckValidHeader(SPTPersistentCacheRecordHeader *header) 103 | { 104 | int code = SPTPersistentCacheValidateHeader(header); 105 | if (code == -1) { // No error 106 | return nil; 107 | } 108 | 109 | return [NSError spt_persistentDataCacheErrorWithCode:code]; 110 | } 111 | 112 | uint32_t SPTPersistentCacheCalculateHeaderCRC(const SPTPersistentCacheRecordHeader *header) 113 | { 114 | if (header == NULL) { 115 | return 0; 116 | } 117 | 118 | return spt_crc32((const uint8_t *)header, SPTPersistentCacheRecordHeaderSize - sizeof(header->crc)); 119 | } 120 | 121 | 122 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCacheObjectDescription.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import 22 | 23 | /// The termination sentinel that must be used toghether with `SPTPersistentCacheObjectDescription()`. 24 | extern id const SPTPersistentCacheObjectDescriptionTerminationSentinel; 25 | 26 | /** 27 | * Creates a standardized description string for the given _object_ and a variable list of _value_ to _key_ pairs. 28 | * Each value and key must be an object conforming to the `NSObject` protocol. 29 | * 30 | * The function takes a variable list of value and key pairs. Just like the variadic `NSDictionary` initializer. You 31 | * must terminate the list using `SPTPersistentCacheObjectDescriptionTerminationSentinel`. 32 | * 33 | * @note It’s recommended that you use the convenience macro `SPTPersistentCacheObjectDescription` over this function 34 | * directly. As it adds the termination sentinel for you. 35 | * 36 | * @warning The list of variadic arguments **MUST** end with the custom termination sentinel: 37 | * `SPTPersistentCacheObjectDescriptionTerminationSentinel`. We need a custom sentinel as the function supports 38 | * arguments being `nil`. 39 | * 40 | * @return A standardized description string on the format ``. 41 | */ 42 | extern NSString *_SPTPersistentCacheObjectDescription(id object, id firstValue, ...); 43 | 44 | /** 45 | * Creates a standardized description string for the given _object_ and a variable list of _value_ to _key_ pairs. 46 | * 47 | * The function takes a variable list of value and key pairs. Just like the variadic `NSDictionary` initializer. It 48 | * will automatically insert the termination sentinel for you. 49 | * 50 | * @return A standardized description string on the format ``. 51 | */ 52 | #define SPTPersistentCacheObjectDescription(object, firstValue, ...) _SPTPersistentCacheObjectDescription((object), (firstValue), __VA_ARGS__, SPTPersistentCacheObjectDescriptionTerminationSentinel) 53 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCacheObjectDescription.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import "SPTPersistentCacheObjectDescription.h" 22 | 23 | id const SPTPersistentCacheObjectDescriptionTerminationSentinel = @"0xDEADC0DE"; 24 | 25 | NS_INLINE BOOL SPTIsObjectDescriptionTerminationSentinel(id const object) 26 | { 27 | return object == SPTPersistentCacheObjectDescriptionTerminationSentinel; 28 | } 29 | 30 | static void SPTPersistentCacheObjectDescriptionAppendToString(NSMutableString *description, id object, id firstValue, va_list valueKeyPairs) 31 | { 32 | NSCParameterAssert(description); 33 | NSCParameterAssert(object); 34 | 35 | id value = firstValue; 36 | id key = va_arg(valueKeyPairs, id); 37 | 38 | while (!SPTIsObjectDescriptionTerminationSentinel(value) && !SPTIsObjectDescriptionTerminationSentinel(key)) { 39 | if (value != object && key != object) { 40 | [description appendFormat:@"; %@ = \"%@\"", key, value]; 41 | } 42 | 43 | value = va_arg(valueKeyPairs, id); 44 | if (SPTIsObjectDescriptionTerminationSentinel(value)) { 45 | break; 46 | } 47 | 48 | key = va_arg(valueKeyPairs, id); 49 | } 50 | 51 | } 52 | 53 | NSString *_SPTPersistentCacheObjectDescription(id object, id firstValue, ...) 54 | { 55 | if (object == nil) { 56 | return nil; 57 | } 58 | 59 | NSString * const objectClassName = NSStringFromClass(object.class); 60 | NSMutableString * const description = [NSMutableString stringWithFormat:@"<%@: %p", objectClassName, (void *)object]; 61 | 62 | NSString * (^ const closeAndReturnDescriptionBlock)(void) = ^{ 63 | [description appendString:@">"]; 64 | return [description copy]; 65 | }; 66 | 67 | if (SPTIsObjectDescriptionTerminationSentinel(firstValue)) { 68 | return closeAndReturnDescriptionBlock(); 69 | } 70 | 71 | va_list valueKeyPairs; 72 | va_start(valueKeyPairs, firstValue); 73 | SPTPersistentCacheObjectDescriptionAppendToString(description, object, firstValue, valueKeyPairs); 74 | va_end(valueKeyPairs); 75 | 76 | return closeAndReturnDescriptionBlock(); 77 | } 78 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCachePosixWrapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import 22 | 23 | #include 24 | 25 | /** 26 | * An Obj-C wrapper for POSIX functions mainly made for mocking functions during unit tests. 27 | */ 28 | @interface SPTPersistentCachePosixWrapper : NSObject 29 | 30 | /** 31 | * See POSIX "close" 32 | * @param descriptor The file descriptor to close. 33 | */ 34 | - (int)close:(int)descriptor; 35 | /** 36 | * See POSIX "read" 37 | * @param descriptor The file descriptor to read. 38 | * @param buffer The memory to read into. 39 | * @param bufferSize The amount of the file to read into memory. 40 | */ 41 | - (ssize_t)read:(int)descriptor buffer:(void *)buffer bufferSize:(size_t)bufferSize; 42 | /** 43 | * See POSIX "lseek" 44 | * @param descriptor The file descriptor to seek in. 45 | * @param seekType Where in the file to begin seeking. 46 | * @param seekAmount The amount of bytes to seek in the file. 47 | */ 48 | - (off_t)lseek:(int)descriptor seekType:(off_t)seekType seekAmount:(int)seekAmount; 49 | /** 50 | * See POSIX "write" 51 | * @param descriptor The file descriptor to write to. 52 | * @param buffer The memory to write into the file. 53 | * @param bufferSize The size of the memory to write into the file. 54 | */ 55 | - (ssize_t)write:(int)descriptor buffer:(const void *)buffer bufferSize:(size_t)bufferSize; 56 | /** 57 | * See POSIX "fsync" 58 | * @param descriptor The file descriptor to synchronise. 59 | */ 60 | - (int)fsync:(int)descriptor; 61 | /** 62 | * See POSIX "stat" 63 | * @param path The path to file to get the stats for. 64 | * @param statStruct The structure to store the file stats in. 65 | */ 66 | - (int)stat:(const char *)path statStruct:(struct stat *)statStruct; 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCachePosixWrapper.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import "SPTPersistentCachePosixWrapper.h" 22 | 23 | @implementation SPTPersistentCachePosixWrapper 24 | 25 | - (int)close:(int)descriptor 26 | { 27 | return close(descriptor); 28 | } 29 | 30 | - (ssize_t)read:(int)descriptor buffer:(void *)buffer bufferSize:(size_t)bufferSize 31 | { 32 | return read(descriptor, buffer, bufferSize); 33 | } 34 | 35 | - (off_t)lseek:(int)descriptor seekType:(off_t)seekType seekAmount:(int)seekAmount 36 | { 37 | return lseek(descriptor, seekType, seekAmount); 38 | } 39 | 40 | - (ssize_t)write:(int)descriptor buffer:(const void *)buffer bufferSize:(size_t)bufferSize 41 | { 42 | return write(descriptor, buffer, bufferSize); 43 | } 44 | 45 | - (int)fsync:(int)descriptor 46 | { 47 | return fsync(descriptor); 48 | } 49 | 50 | - (int)stat:(const char *)path statStruct:(struct stat *)statStruct 51 | { 52 | return stat(path, statStruct); 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCacheRecord+Private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import "SPTPersistentCacheRecord.h" 22 | 23 | @interface SPTPersistentCacheRecord (Private) 24 | 25 | - (instancetype)initWithData:(NSData *)data 26 | key:(NSString *)key 27 | refCount:(NSUInteger)refCount 28 | ttl:(NSUInteger)ttl; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCacheRecord.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import "SPTPersistentCacheRecord.h" 22 | #import "SPTPersistentCacheObjectDescription.h" 23 | 24 | @implementation SPTPersistentCacheRecord 25 | 26 | #pragma mark SPTPersistentCacheRecord 27 | 28 | - (instancetype)initWithData:(NSData *)data 29 | key:(NSString *)key 30 | refCount:(NSUInteger)refCount 31 | ttl:(NSUInteger)ttl 32 | { 33 | self = [super init]; 34 | if (self) { 35 | _refCount = refCount; 36 | _ttl = ttl; 37 | _key = [key copy]; 38 | _data = data; 39 | } 40 | return self; 41 | } 42 | 43 | #pragma mark Describing Object 44 | 45 | - (NSString *)description 46 | { 47 | return SPTPersistentCacheObjectDescription(self, self.key, @"key"); 48 | } 49 | 50 | - (NSString *)debugDescription 51 | { 52 | return SPTPersistentCacheObjectDescription(self, self.key, @"key", @(self.ttl), @"ttl", @(self.refCount), @"ref-count"); 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCacheResponse+Private.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import 22 | 23 | extern NSString *NSStringFromSPTPersistentCacheResponseCode(SPTPersistentCacheResponseCode code); 24 | 25 | @interface SPTPersistentCacheResponse (Private) 26 | 27 | - (instancetype)initWithResult:(SPTPersistentCacheResponseCode)result 28 | error:(NSError *)error 29 | record:(SPTPersistentCacheRecord *)record; 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCacheResponse.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import 22 | #import 23 | #import "SPTPersistentCacheObjectDescription.h" 24 | #import "SPTPersistentCacheResponse+Private.h" 25 | 26 | @interface SPTPersistentCacheResponse () 27 | 28 | @property (nonatomic, assign, readwrite) SPTPersistentCacheResponseCode result; 29 | @property (nonatomic, strong, readwrite) NSError *error; 30 | @property (nonatomic, strong, readwrite) SPTPersistentCacheRecord *record; 31 | 32 | @end 33 | 34 | @implementation SPTPersistentCacheResponse 35 | 36 | - (instancetype)initWithResult:(SPTPersistentCacheResponseCode)result 37 | error:(NSError *)error 38 | record:(SPTPersistentCacheRecord *)record 39 | { 40 | self = [super init]; 41 | if (self) { 42 | _result = result; 43 | _error = error; 44 | _record = record; 45 | } 46 | return self; 47 | } 48 | 49 | #pragma mark Describing Object 50 | 51 | NSString *NSStringFromSPTPersistentCacheResponseCode(SPTPersistentCacheResponseCode code) 52 | { 53 | switch (code) { 54 | case SPTPersistentCacheResponseCodeNotFound: return @"not-found"; 55 | case SPTPersistentCacheResponseCodeOperationError: return @"operation-error"; 56 | case SPTPersistentCacheResponseCodeOperationSucceeded: return @"operation-success"; 57 | } 58 | } 59 | 60 | - (NSString *)description 61 | { 62 | return SPTPersistentCacheObjectDescription(self, NSStringFromSPTPersistentCacheResponseCode(self.result), @"result"); 63 | } 64 | 65 | - (NSString *)debugDescription 66 | { 67 | return SPTPersistentCacheObjectDescription(self, 68 | NSStringFromSPTPersistentCacheResponseCode(self.result), @"result", 69 | self.record.debugDescription, @"record", 70 | self.error.debugDescription, @"error"); 71 | } 72 | 73 | @end 74 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCacheTypeUtilities.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | 22 | #import 23 | 24 | /** 25 | * Converts the given `double` _value_ to an `uint64_t` value. 26 | * 27 | * @param value The value as a `double`. 28 | * @return The value as an `uint64_t`. 29 | */ 30 | uint64_t spt_uint64rint(double value); 31 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/SPTPersistentCacheTypeUtilities.m: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | 22 | #import "SPTPersistentCacheTypeUtilities.h" 23 | 24 | 25 | uint64_t spt_uint64rint(double value) 26 | { 27 | return (uint64_t)llrint(value); 28 | } 29 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/crc32iso3309.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #include "crc32iso3309.h" 22 | 23 | /** 24 | * Algorithms is taken from RFC-1952. Appendix: Sample CRC Code 25 | */ 26 | 27 | /* Table of CRCs of all 8-bit messages. */ 28 | static const uint32_t crc_table[] = { 29 | 0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 30 | 0x076dc419U, 0x706af48fU, 0xe963a535U, 0x9e6495a3U, 31 | 0x0edb8832U, 0x79dcb8a4U, 0xe0d5e91eU, 0x97d2d988U, 32 | 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U, 0x90bf1d91U, 33 | 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU, 34 | 0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 35 | 0x136c9856U, 0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 36 | 0x14015c4fU, 0x63066cd9U, 0xfa0f3d63U, 0x8d080df5U, 37 | 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U, 0xa2677172U, 38 | 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU, 39 | 0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 40 | 0x32d86ce3U, 0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 41 | 0x26d930acU, 0x51de003aU, 0xc8d75180U, 0xbfd06116U, 42 | 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U, 0xb8bda50fU, 43 | 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U, 44 | 0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 45 | 0x76dc4190U, 0x01db7106U, 0x98d220bcU, 0xefd5102aU, 46 | 0x71b18589U, 0x06b6b51fU, 0x9fbfe4a5U, 0xe8b8d433U, 47 | 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU, 0xe10e9818U, 48 | 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U, 49 | 0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 50 | 0x6c0695edU, 0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 51 | 0x65b0d9c6U, 0x12b7e950U, 0x8bbeb8eaU, 0xfcb9887cU, 52 | 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U, 0xfbd44c65U, 53 | 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U, 54 | 0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 55 | 0x4369e96aU, 0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 56 | 0x44042d73U, 0x33031de5U, 0xaa0a4c5fU, 0xdd0d7cc9U, 57 | 0x5005713cU, 0x270241aaU, 0xbe0b1010U, 0xc90c2086U, 58 | 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU, 59 | 0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 60 | 0x59b33d17U, 0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 61 | 0xedb88320U, 0x9abfb3b6U, 0x03b6e20cU, 0x74b1d29aU, 62 | 0xead54739U, 0x9dd277afU, 0x04db2615U, 0x73dc1683U, 63 | 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U, 64 | 0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 65 | 0xf00f9344U, 0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 66 | 0xf762575dU, 0x806567cbU, 0x196c3671U, 0x6e6b06e7U, 67 | 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU, 0x67dd4accU, 68 | 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U, 69 | 0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 70 | 0xd1bb67f1U, 0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 71 | 0xd80d2bdaU, 0xaf0a1b4cU, 0x36034af6U, 0x41047a60U, 72 | 0xdf60efc3U, 0xa867df55U, 0x316e8eefU, 0x4669be79U, 73 | 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U, 74 | 0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 75 | 0xc5ba3bbeU, 0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 76 | 0xc2d7ffa7U, 0xb5d0cf31U, 0x2cd99e8bU, 0x5bdeae1dU, 77 | 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU, 0x026d930aU, 78 | 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U, 79 | 0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 80 | 0x92d28e9bU, 0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 81 | 0x86d3d2d4U, 0xf1d4e242U, 0x68ddb3f8U, 0x1fda836eU, 82 | 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U, 0x18b74777U, 83 | 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU, 84 | 0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 85 | 0xa00ae278U, 0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 86 | 0xa7672661U, 0xd06016f7U, 0x4969474dU, 0x3e6e77dbU, 87 | 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U, 0x37d83bf0U, 88 | 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U, 89 | 0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 90 | 0xbad03605U, 0xcdd70693U, 0x54de5729U, 0x23d967bfU, 91 | 0xb3667a2eU, 0xc4614ab8U, 0x5d681b02U, 0x2a6f2b94U, 92 | 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU, 0x2d02ef8dU 93 | }; 94 | 95 | /* 96 | Update a running crc with the bytes buf[0..len-1] and return 97 | the updated crc. The crc should be initialized to zero. Pre- and 98 | post-conditioning (one's complement) is performed within this 99 | function so it shouldn't be done by the caller. Usage example: 100 | 101 | uint32_t crc = 0L; 102 | 103 | while (read_buffer(buffer, length) != EOF) { 104 | crc = update_crc(crc, buffer, length); 105 | } 106 | if (crc != original_crc) error(); 107 | */ 108 | static uint32_t update_crc(uint32_t crc, const uint8_t *buf, size_t len) 109 | { 110 | uint32_t c = crc ^ 0xffFFffFFU; 111 | 112 | for (size_t n = 0; n < len; ++n) { 113 | c = crc_table[(c ^ buf[n]) & 0xFF] ^ (c >> 8); 114 | } 115 | return c ^ 0xffFFffFFU; 116 | } 117 | 118 | /* Return the CRC of the bytes buf[0..len-1]. */ 119 | uint32_t spt_crc32(const uint8_t *buf, size_t len) 120 | { 121 | return update_crc(0L, buf, len); 122 | } 123 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/Sources/crc32iso3309.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #ifndef CRC32ISO3309_H 22 | #define CRC32ISO3309_H 23 | 24 | #include 25 | 26 | #ifdef __cplusplus 27 | extern "C" { 28 | #endif 29 | 30 | /* Return the CRC of the bytes buf[0..len-1]. ISO-3309 */ 31 | uint32_t spt_crc32(const uint8_t *buf, size_t len); 32 | 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/include/SPTPersistentCache/SPTPersistentCacheHeader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import 22 | 23 | /** 24 | * The type of integer the magic type is made up of in the header structure 25 | */ 26 | typedef uint32_t SPTPersistentCacheMagicType; 27 | 28 | /** 29 | * Describes different flags for record 30 | */ 31 | typedef NS_ENUM(NSInteger, SPTPersistentCacheRecordHeaderFlags) { 32 | // 0x0 means regular file 33 | /* 34 | * Indicates that record might not be completed last time it was written. 35 | * This is not an error state but more Application logic. 36 | */ 37 | SPTPersistentCacheRecordHeaderFlagsStreamIncomplete = 0x1, 38 | }; 39 | 40 | /** 41 | * The record header making up the front of the file index 42 | */ 43 | typedef struct SPTPersistentCacheRecordHeader { 44 | // Version 1: 45 | SPTPersistentCacheMagicType magic; 46 | uint32_t headerSize; 47 | uint32_t refCount; 48 | uint32_t reserved1; 49 | uint64_t ttl; 50 | // Time of last update i.e. creation or access 51 | uint64_t updateTimeSec; // unix time scale 52 | uint64_t payloadSizeBytes; 53 | uint64_t reserved2; 54 | uint32_t reserved3; 55 | uint32_t reserved4; 56 | uint32_t flags; // See SPTPersistentRecordHeaderFlags 57 | uint32_t crc; 58 | // Version 2: Add fields here if required 59 | } SPTPersistentCacheRecordHeader; 60 | 61 | /** 62 | * The value to use for the magic number (redundancy check). 63 | */ 64 | FOUNDATION_EXPORT const SPTPersistentCacheMagicType SPTPersistentCacheMagicValue; 65 | /** 66 | * The size of the record header in bytes. 67 | */ 68 | FOUNDATION_EXPORT const size_t SPTPersistentCacheRecordHeaderSize; 69 | 70 | // Following functions used internally and could be used for testing purposes also. 71 | 72 | /** 73 | * Creates a record header from a supply of parameters. 74 | */ 75 | FOUNDATION_EXPORT SPTPersistentCacheRecordHeader SPTPersistentCacheRecordHeaderMake(uint64_t ttl, 76 | uint64_t payloadSize, 77 | uint64_t updateTime, 78 | BOOL isLocked); 79 | /** 80 | * Function return pointer to header if there are enough data otherwise NULL. 81 | */ 82 | FOUNDATION_EXPORT SPTPersistentCacheRecordHeader *SPTPersistentCacheGetHeaderFromData(void *data, size_t size); 83 | /** 84 | * Function validates header accoring to predefined rules used in production code. 85 | * @return -1 if everything is ok, otherwise one of codes from SPTPersistentCacheLoadingError. 86 | */ 87 | FOUNDATION_EXPORT int /*SPTPersistentCacheLoadingError*/ SPTPersistentCacheValidateHeader(const SPTPersistentCacheRecordHeader *header); 88 | /** 89 | * Function returns calculated CRC for current header. 90 | */ 91 | FOUNDATION_EXPORT uint32_t SPTPersistentCacheCalculateHeaderCRC(const SPTPersistentCacheRecordHeader *header); 92 | /** 93 | * Checks that a given header is valid. 94 | * @return nil if everything is ok, otherwise will return an instance of NSError. 95 | */ 96 | FOUNDATION_EXPORT NSError * SPTPersistentCacheCheckValidHeader(SPTPersistentCacheRecordHeader *header); 97 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/include/SPTPersistentCache/SPTPersistentCacheRecord.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import 22 | 23 | NS_ASSUME_NONNULL_BEGIN 24 | 25 | /** 26 | * @brief SPTPersistentCacheRecord 27 | * @discussion Class defines one record in cache that is returned in response. 28 | * Each record is represented by single file on disk. 29 | * If file deleted from disk then cache assumes its never existed and return SPTPersistentCacheResponseCodeNotFound for load call. 30 | */ 31 | @interface SPTPersistentCacheRecord : NSObject 32 | 33 | /* 34 | * Defines the number of times external logical references to this cache item. Initially is 0 if locked flag on store is NO. 35 | * Files with refCount > 0 is considered as locked by GC procedure. They also returned on load call regardless of expiration. 36 | */ 37 | @property (nonatomic, assign, readonly) NSUInteger refCount; 38 | /** 39 | * Defines ttl for given record if applicable. 0 means not applicable. 40 | */ 41 | @property (nonatomic, assign, readonly) NSUInteger ttl; 42 | /** 43 | * Key for that record. 44 | */ 45 | @property (nonatomic, copy, readonly) NSString *key; 46 | /* 47 | * Data that was initially passed into storeData:... 48 | */ 49 | @property (nonatomic, strong, readonly) NSData *data; 50 | 51 | @end 52 | 53 | NS_ASSUME_NONNULL_END 54 | -------------------------------------------------------------------------------- /Pods/SPTPersistentCache/include/SPTPersistentCache/SPTPersistentCacheResponse.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2016 Spotify AB. 3 | * 4 | * Licensed to the Apache Software Foundation (ASF) under one 5 | * or more contributor license agreements. See the NOTICE file 6 | * distributed with this work for additional information 7 | * regarding copyright ownership. The ASF licenses this file 8 | * to you under the Apache License, Version 2.0 (the 9 | * "License"); you may not use this file except in compliance 10 | * with the License. You may obtain a copy of the License at 11 | * 12 | * http://www.apache.org/licenses/LICENSE-2.0 13 | * 14 | * Unless required by applicable law or agreed to in writing, 15 | * software distributed under the License is distributed on an 16 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 17 | * KIND, either express or implied. See the License for the 18 | * specific language governing permissions and limitations 19 | * under the License. 20 | */ 21 | #import 22 | 23 | @class SPTPersistentCacheRecord; 24 | 25 | NS_ASSUME_NONNULL_BEGIN 26 | 27 | /** 28 | * The SPTPersistentCacheResponseCode enum defines constants that is used to identify what kind of response would be 29 | * given in callback to loadDataForKey:withCallback: method. 30 | */ 31 | typedef NS_ENUM(NSInteger, SPTPersistentCacheResponseCode) { 32 | /** 33 | * Indicates success of requested operation with data. The record field of SPTPersistentCacheResponse mustn't be nil 34 | * if it was load operation otherwise it could be. The error would be nil. 35 | */ 36 | SPTPersistentCacheResponseCodeOperationSucceeded, 37 | /** 38 | * Indicates that no file found for given key in cache or is expired. The record and error field of 39 | * SPTPersistentCacheResponse is nil in this case. 40 | */ 41 | SPTPersistentCacheResponseCodeNotFound, 42 | /** 43 | * Indicates error occured during requested operation. The record field of SPTPersistentCacheResponse would be nil. 44 | * The error mustn't be nil and specify exact error. 45 | */ 46 | SPTPersistentCacheResponseCodeOperationError 47 | }; 48 | 49 | /** 50 | * @brief SPTPersistentCacheResponse 51 | * @discussion Class defines one response passed in callback to call loadDataForKey: 52 | */ 53 | @interface SPTPersistentCacheResponse : NSObject 54 | 55 | /** 56 | * @see SPTPersistentCacheResponseCode 57 | */ 58 | @property (nonatomic, assign, readonly) SPTPersistentCacheResponseCode result; 59 | /** 60 | * Defines error of response if appliable 61 | */ 62 | @property (nonatomic, strong, readonly) NSError *error; 63 | /** 64 | * @see SPTPersistentCacheRecord 65 | */ 66 | @property (nonatomic, strong, readonly) SPTPersistentCacheRecord *record; 67 | 68 | @end 69 | 70 | NS_ASSUME_NONNULL_END 71 | -------------------------------------------------------------------------------- /Pods/Target Support Files/FavIcon/FavIcon-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 | FMWK 17 | CFBundleShortVersionString 18 | 3.0.4 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/FavIcon/FavIcon-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_FavIcon : NSObject 3 | @end 4 | @implementation PodsDummy_FavIcon 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/FavIcon/FavIcon-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/FavIcon/FavIcon-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double FavIconVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char FavIconVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/FavIcon/FavIcon.modulemap: -------------------------------------------------------------------------------- 1 | framework module FavIcon { 2 | umbrella header "FavIcon-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/FavIcon/FavIcon.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FavIcon 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = /usr/include/libxml2 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/FavIcon 10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 11 | SKIP_INSTALL = YES 12 | SWIFT_INCLUDE_PATHS = $(PODS_TARGET_SRCROOT)/Sources/Modules 13 | SWIFT_VERSION = 4.0 14 | SWIFT_WHOLE_MODULE_OPTIMIZATION = YES 15 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUD/Pods-PassHUD-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 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUD/Pods-PassHUD-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_PassHUD : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_PassHUD 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUD/Pods-PassHUD-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_PassHUDVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_PassHUDVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUD/Pods-PassHUD.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CODE_SIGN_IDENTITY = 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FavIcon" "${PODS_CONFIGURATION_BUILD_DIR}/SPTPersistentCache" "${PODS_CONFIGURATION_BUILD_DIR}/Yams" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FavIcon/FavIcon.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SPTPersistentCache/SPTPersistentCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Yams/Yams.framework/Headers" /usr/include/libxml2 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/Frameworks' 7 | OTHER_LDFLAGS = $(inherited) -l"ObjC" -framework "FavIcon" -framework "SPTPersistentCache" -framework "Yams" 8 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 9 | PODS_BUILD_DIR = ${BUILD_DIR} 10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 12 | PODS_ROOT = ${SRCROOT}/Pods 13 | SWIFT_INCLUDE_PATHS = $(PODS_TARGET_SRCROOT)/Sources/Modules 14 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUD/Pods-PassHUD.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_PassHUD { 2 | umbrella header "Pods-PassHUD-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUD/Pods-PassHUD.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CODE_SIGN_IDENTITY = 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FavIcon" "${PODS_CONFIGURATION_BUILD_DIR}/SPTPersistentCache" "${PODS_CONFIGURATION_BUILD_DIR}/Yams" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FavIcon/FavIcon.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SPTPersistentCache/SPTPersistentCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Yams/Yams.framework/Headers" /usr/include/libxml2 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/Frameworks' 7 | OTHER_LDFLAGS = $(inherited) -l"ObjC" -framework "FavIcon" -framework "SPTPersistentCache" -framework "Yams" 8 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 9 | PODS_BUILD_DIR = ${BUILD_DIR} 10 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 11 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 12 | PODS_ROOT = ${SRCROOT}/Pods 13 | SWIFT_INCLUDE_PATHS = $(PODS_TARGET_SRCROOT)/Sources/Modules 14 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUDTests/Pods-PassHUDTests-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 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUDTests/Pods-PassHUDTests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUDTests/Pods-PassHUDTests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUDTests/Pods-PassHUDTests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_PassHUDTests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_PassHUDTests 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUDTests/Pods-PassHUDTests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_PassHUDTestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_PassHUDTestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUDTests/Pods-PassHUDTests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FavIcon" "${PODS_CONFIGURATION_BUILD_DIR}/SPTPersistentCache" "${PODS_CONFIGURATION_BUILD_DIR}/Yams" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FavIcon/FavIcon.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SPTPersistentCache/SPTPersistentCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Yams/Yams.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/../Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "FavIcon" -framework "SPTPersistentCache" -framework "Yams" 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 10 | PODS_ROOT = ${SRCROOT}/Pods 11 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUDTests/Pods-PassHUDTests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_PassHUDTests { 2 | umbrella header "Pods-PassHUDTests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUDTests/Pods-PassHUDTests.release.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FavIcon" "${PODS_CONFIGURATION_BUILD_DIR}/SPTPersistentCache" "${PODS_CONFIGURATION_BUILD_DIR}/Yams" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FavIcon/FavIcon.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SPTPersistentCache/SPTPersistentCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Yams/Yams.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/../Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "FavIcon" -framework "SPTPersistentCache" -framework "Yams" 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 10 | PODS_ROOT = ${SRCROOT}/Pods 11 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUDUITests/Pods-PassHUDUITests-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 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUDUITests/Pods-PassHUDUITests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUDUITests/Pods-PassHUDUITests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUDUITests/Pods-PassHUDUITests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_PassHUDUITests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_PassHUDUITests 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUDUITests/Pods-PassHUDUITests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_PassHUDUITestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_PassHUDUITestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUDUITests/Pods-PassHUDUITests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FavIcon" "${PODS_CONFIGURATION_BUILD_DIR}/SPTPersistentCache" "${PODS_CONFIGURATION_BUILD_DIR}/Yams" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FavIcon/FavIcon.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SPTPersistentCache/SPTPersistentCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Yams/Yams.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/../Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "FavIcon" -framework "SPTPersistentCache" -framework "Yams" 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 10 | PODS_ROOT = ${SRCROOT}/Pods 11 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUDUITests/Pods-PassHUDUITests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_PassHUDUITests { 2 | umbrella header "Pods-PassHUDUITests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-PassHUDUITests/Pods-PassHUDUITests.release.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FavIcon" "${PODS_CONFIGURATION_BUILD_DIR}/SPTPersistentCache" "${PODS_CONFIGURATION_BUILD_DIR}/Yams" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FavIcon/FavIcon.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SPTPersistentCache/SPTPersistentCache.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Yams/Yams.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/../Frameworks' '@loader_path/../Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "FavIcon" -framework "SPTPersistentCache" -framework "Yams" 7 | PODS_BUILD_DIR = ${BUILD_DIR} 8 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 10 | PODS_ROOT = ${SRCROOT}/Pods 11 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SPTPersistentCache/SPTPersistentCache-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 | FMWK 17 | CFBundleShortVersionString 18 | 1.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SPTPersistentCache/SPTPersistentCache-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_SPTPersistentCache : NSObject 3 | @end 4 | @implementation PodsDummy_SPTPersistentCache 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SPTPersistentCache/SPTPersistentCache-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SPTPersistentCache/SPTPersistentCache-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "SPTPersistentCache.h" 14 | #import "SPTPersistentCacheHeader.h" 15 | #import "SPTPersistentCacheOptions.h" 16 | #import "SPTPersistentCacheRecord.h" 17 | #import "SPTPersistentCacheResponse.h" 18 | 19 | FOUNDATION_EXPORT double SPTPersistentCacheVersionNumber; 20 | FOUNDATION_EXPORT const unsigned char SPTPersistentCacheVersionString[]; 21 | 22 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SPTPersistentCache/SPTPersistentCache.modulemap: -------------------------------------------------------------------------------- 1 | framework module SPTPersistentCache { 2 | umbrella header "SPTPersistentCache-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/SPTPersistentCache/SPTPersistentCache.xcconfig: -------------------------------------------------------------------------------- 1 | CODE_SIGN_IDENTITY = 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SPTPersistentCache 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | OTHER_LDFLAGS = -l"ObjC" 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/SPTPersistentCache 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Yams/Yams-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 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Yams/Yams-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Yams : NSObject 3 | @end 4 | @implementation PodsDummy_Yams 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Yams/Yams-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Yams/Yams-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "CYaml.h" 14 | #import "yaml.h" 15 | #import "yaml_private.h" 16 | #import "Yams.h" 17 | 18 | FOUNDATION_EXPORT double YamsVersionNumber; 19 | FOUNDATION_EXPORT const unsigned char YamsVersionString[]; 20 | 21 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Yams/Yams.modulemap: -------------------------------------------------------------------------------- 1 | framework module Yams { 2 | umbrella header "Yams-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Yams/Yams.xcconfig: -------------------------------------------------------------------------------- 1 | APPLICATION_EXTENSION_API_ONLY = YES 2 | CODE_SIGN_IDENTITY = 3 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Yams 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Yams 10 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 11 | SKIP_INSTALL = YES 12 | -------------------------------------------------------------------------------- /Pods/Yams/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 JP Simard. 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 | -------------------------------------------------------------------------------- /Pods/Yams/README.md: -------------------------------------------------------------------------------- 1 | # Yams 2 | 3 | ![Yams](https://raw.githubusercontent.com/jpsim/Yams/master/yams.jpg) 4 | 5 | A sweet and swifty [YAML](http://yaml.org/) parser built on 6 | [LibYAML](https://github.com/yaml/libyaml). 7 | 8 | [![CircleCI](https://circleci.com/gh/jpsim/Yams.svg?style=svg)](https://circleci.com/gh/jpsim/Yams) 9 | 10 | ## Installation 11 | 12 | Building Yams on macOS requires Xcode 9.x or a Swift 3.2/4.x toolchain with 13 | the Swift Package Manager. 14 | 15 | Building Yams on Linux requires a Swift 4.x compiler and Swift Package Manager 16 | to be installed. 17 | 18 | ### Swift Package Manager 19 | 20 | Add `.package(url: "https://github.com/jpsim/Yams.git", from: "1.0.1")` to your 21 | `Package.swift` file's `dependencies`. 22 | 23 | ### CocoaPods 24 | 25 | Add `pod 'Yams'` to your `Podfile`. 26 | 27 | ### Carthage 28 | 29 | Add `github "jpsim/Yams"` to your `Cartfile`. 30 | 31 | ## Usage 32 | 33 | Yams has three groups of conversion APIs: 34 | one for use with [`Codable` types](#codable-types), 35 | another for [Swift Standard Library types](#swift-standard-library-types), 36 | and a third one for a [Yams-native](#yamsnode) representation. 37 | 38 | #### `Codable` types 39 | 40 | - Codable is an [encoding & decoding strategy introduced in Swift 4][Codable] 41 | enabling easy conversion between YAML and other Encoders like 42 | [JSONEncoder][JSONEncoder] and [PropertyListEncoder][PropertyListEncoder]. 43 | - Lowest computational overhead, equivalent to `Yams.Node`. 44 | - **Encoding: `YAMLEncoder.encode(_:)`** 45 | Produces a YAML `String` from an instance of type conforming to `Encodable`. 46 | - **Decoding: `YAMLDecoder.decode(_:from:)`** 47 | Decodes an instance of type conforming to `Decodable` from YAML `String`. 48 | 49 | ```swift 50 | import Foundation 51 | import Yams 52 | 53 | struct S: Codable { 54 | var p: String 55 | } 56 | 57 | let s = S(p: "test") 58 | let encoder = YAMLEncoder() 59 | let encodedYAML = try encoder.encode(s) 60 | encodedYAML == """ 61 | p: test 62 | 63 | """ 64 | let decoder = YAMLDecoder() 65 | let decoded = try decoder.decode(S.self, from: encodedYAML) 66 | s.p == decoded.p 67 | ``` 68 | 69 | #### Swift Standard Library types 70 | 71 | - The type of Swift Standard Library is inferred from the contents of the 72 | internal `Yams.Node` representation by matching regular expressions. 73 | - This method has the largest computational overhead When decoding YAML, because 74 | the type inference of all objects is done up-front. 75 | - It may be easier to use in such a way as to handle objects created from 76 | `JSONSerialization` or if the input is already standard library types 77 | (`Any`, `Dictionary`, `Array`, etc.). 78 | - **Encoding: `Yams.dump(object:)`** 79 | Produces a YAML `String` from an instance of Swift Standard Library types. 80 | - **Decoding: `Yams.load(yaml:)`** 81 | Produces an instance of Swift Standard Library types as `Any` from YAML 82 | `String`. 83 | 84 | ```swift 85 | // [String: Any] 86 | let dictionary: [String: Any] = ["key": "value"] 87 | let mapYAML: String = try Yams.dump(object: dictionary) 88 | mapYAML == """ 89 | key: value 90 | 91 | """ 92 | let loadedDictionary = try Yams.load(yaml: mapYAML) as? [String: Any] 93 | 94 | // [Any] 95 | let array: [Int] = [1, 2, 3] 96 | let sequenceYAML: String = try Yams.dump(object: array) 97 | sequenceYAML == """ 98 | - 1 99 | - 2 100 | - 3 101 | 102 | """ 103 | let loadedArray: [Int]? = try Yams.load(yaml: sequenceYAML) as? [Int] 104 | 105 | // Any 106 | let string = "string" 107 | let scalarYAML: String = try Yams.dump(object: string) 108 | scalarYAML == """ 109 | string 110 | 111 | """ 112 | let loadedString: String? = try Yams.load(yaml: scalarYAML) as? String 113 | ``` 114 | 115 | #### `Yams.Node` 116 | 117 | - Yams' native model representing [Nodes of YAML][Nodes Spec] which provides all 118 | functions such as detection and customization of the YAML format. 119 | - Depending on how it is used, computational overhead can be minimized. 120 | - **Encoding: `Yams.serialize(node:)`** 121 | Produces a YAML `String` from an instance of `Node`. 122 | - **Decoding `Yams.compose(yaml:)`** 123 | Produces an instance of `Node` from YAML `String`. 124 | 125 | ```swift 126 | var map: Yams.Node = [ 127 | "array": [ 128 | 1, 2, 3 129 | ] 130 | ] 131 | map.mapping?.style = .flow 132 | map["array"]?.sequence?.style = .flow 133 | let yaml = try Yams.serialize(node: map) 134 | yaml == """ 135 | {array: [1, 2, 3]} 136 | 137 | """ 138 | let node = try Yams.compose(yaml: yaml) 139 | map == node 140 | ``` 141 | 142 | ## License 143 | 144 | Both Yams and libYAML are MIT licensed. 145 | 146 | [Codable]: https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types 147 | [JSONEncoder]: https://developer.apple.com/documentation/foundation/jsonencoder 148 | [PropertyListEncoder]: https://developer.apple.com/documentation/foundation/propertylistencoder 149 | [Nodes Spec]: http://www.yaml.org/spec/1.2/spec.html#id2764044 150 | -------------------------------------------------------------------------------- /Pods/Yams/Sources/CYaml/include/CYaml.h: -------------------------------------------------------------------------------- 1 | #include "yaml.h" 2 | -------------------------------------------------------------------------------- /Pods/Yams/Sources/CYaml/src/writer.c: -------------------------------------------------------------------------------- 1 | 2 | #include "yaml_private.h" 3 | 4 | /* 5 | * Declarations. 6 | */ 7 | 8 | static int 9 | yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem); 10 | 11 | YAML_DECLARE(int) 12 | yaml_emitter_flush(yaml_emitter_t *emitter); 13 | 14 | /* 15 | * Set the writer error and return 0. 16 | */ 17 | 18 | static int 19 | yaml_emitter_set_writer_error(yaml_emitter_t *emitter, const char *problem) 20 | { 21 | emitter->error = YAML_WRITER_ERROR; 22 | emitter->problem = problem; 23 | 24 | return 0; 25 | } 26 | 27 | /* 28 | * Flush the output buffer. 29 | */ 30 | 31 | YAML_DECLARE(int) 32 | yaml_emitter_flush(yaml_emitter_t *emitter) 33 | { 34 | int low, high; 35 | 36 | assert(emitter); /* Non-NULL emitter object is expected. */ 37 | assert(emitter->write_handler); /* Write handler must be set. */ 38 | assert(emitter->encoding); /* Output encoding must be set. */ 39 | 40 | emitter->buffer.last = emitter->buffer.pointer; 41 | emitter->buffer.pointer = emitter->buffer.start; 42 | 43 | /* Check if the buffer is empty. */ 44 | 45 | if (emitter->buffer.start == emitter->buffer.last) { 46 | return 1; 47 | } 48 | 49 | /* If the output encoding is UTF-8, we don't need to recode the buffer. */ 50 | 51 | if (emitter->encoding == YAML_UTF8_ENCODING) 52 | { 53 | if (emitter->write_handler(emitter->write_handler_data, 54 | emitter->buffer.start, 55 | emitter->buffer.last - emitter->buffer.start)) { 56 | emitter->buffer.last = emitter->buffer.start; 57 | emitter->buffer.pointer = emitter->buffer.start; 58 | return 1; 59 | } 60 | else { 61 | return yaml_emitter_set_writer_error(emitter, "write error"); 62 | } 63 | } 64 | 65 | /* Recode the buffer into the raw buffer. */ 66 | 67 | low = (emitter->encoding == YAML_UTF16LE_ENCODING ? 0 : 1); 68 | high = (emitter->encoding == YAML_UTF16LE_ENCODING ? 1 : 0); 69 | 70 | while (emitter->buffer.pointer != emitter->buffer.last) 71 | { 72 | unsigned char octet; 73 | unsigned int width; 74 | unsigned int value; 75 | size_t k; 76 | 77 | /* 78 | * See the "reader.c" code for more details on UTF-8 encoding. Note 79 | * that we assume that the buffer contains a valid UTF-8 sequence. 80 | */ 81 | 82 | /* Read the next UTF-8 character. */ 83 | 84 | octet = emitter->buffer.pointer[0]; 85 | 86 | width = (octet & 0x80) == 0x00 ? 1 : 87 | (octet & 0xE0) == 0xC0 ? 2 : 88 | (octet & 0xF0) == 0xE0 ? 3 : 89 | (octet & 0xF8) == 0xF0 ? 4 : 0; 90 | 91 | value = (octet & 0x80) == 0x00 ? octet & 0x7F : 92 | (octet & 0xE0) == 0xC0 ? octet & 0x1F : 93 | (octet & 0xF0) == 0xE0 ? octet & 0x0F : 94 | (octet & 0xF8) == 0xF0 ? octet & 0x07 : 0; 95 | 96 | for (k = 1; k < width; k ++) { 97 | octet = emitter->buffer.pointer[k]; 98 | value = (value << 6) + (octet & 0x3F); 99 | } 100 | 101 | emitter->buffer.pointer += width; 102 | 103 | /* Write the character. */ 104 | 105 | if (value < 0x10000) 106 | { 107 | emitter->raw_buffer.last[high] = value >> 8; 108 | emitter->raw_buffer.last[low] = value & 0xFF; 109 | 110 | emitter->raw_buffer.last += 2; 111 | } 112 | else 113 | { 114 | /* Write the character using a surrogate pair (check "reader.c"). */ 115 | 116 | value -= 0x10000; 117 | emitter->raw_buffer.last[high] = 0xD8 + (value >> 18); 118 | emitter->raw_buffer.last[low] = (value >> 10) & 0xFF; 119 | emitter->raw_buffer.last[high+2] = 0xDC + ((value >> 8) & 0xFF); 120 | emitter->raw_buffer.last[low+2] = value & 0xFF; 121 | 122 | emitter->raw_buffer.last += 4; 123 | } 124 | } 125 | 126 | /* Write the raw buffer. */ 127 | 128 | if (emitter->write_handler(emitter->write_handler_data, 129 | emitter->raw_buffer.start, 130 | emitter->raw_buffer.last - emitter->raw_buffer.start)) { 131 | emitter->buffer.last = emitter->buffer.start; 132 | emitter->buffer.pointer = emitter->buffer.start; 133 | emitter->raw_buffer.last = emitter->raw_buffer.start; 134 | emitter->raw_buffer.pointer = emitter->raw_buffer.start; 135 | return 1; 136 | } 137 | else { 138 | return yaml_emitter_set_writer_error(emitter, "write error"); 139 | } 140 | } 141 | 142 | -------------------------------------------------------------------------------- /Pods/Yams/Sources/Yams/Mark.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Mark.swift 3 | // Yams 4 | // 5 | // Created by Norio Nomura on 4/11/17. 6 | // Copyright (c) 2017 Yams. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// The pointer position. 12 | public struct Mark { 13 | /// Line number starting from 1. 14 | public let line: Int 15 | /// Column number starting from 1. libYAML counts columns in `UnicodeScalar`. 16 | public let column: Int 17 | } 18 | 19 | // MARK: - CustomStringConvertible Conformance 20 | 21 | extension Mark: CustomStringConvertible { 22 | /// A textual representation of this instance. 23 | public var description: String { return "\(line):\(column)" } 24 | } 25 | 26 | // MARK: Snippet 27 | 28 | extension Mark { 29 | /// Returns snippet string pointed by Mark instance from YAML String. 30 | public func snippet(from yaml: String) -> String { 31 | let contents = yaml.substring(at: line - 1) 32 | let columnIndex = contents.unicodeScalars 33 | .index(contents.unicodeScalars.startIndex, 34 | offsetBy: column - 1, 35 | limitedBy: contents.unicodeScalars.endIndex)? 36 | .samePosition(in: contents.utf16) ?? contents.utf16.endIndex 37 | let columnInUTF16 = contents.utf16.distance(from: contents.utf16.startIndex, to: columnIndex) 38 | return contents.endingWithNewLine + 39 | String(repeating: " ", count: columnInUTF16) + "^" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Pods/Yams/Sources/Yams/Node.Scalar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Node.Scalar.swift 3 | // Yams 4 | // 5 | // Created by Norio Nomura on 2/24/17. 6 | // Copyright (c) 2016 Yams. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // MARK: Node+Scalar 12 | 13 | extension Node { 14 | /// Scalar node. 15 | public struct Scalar { 16 | /// This node's string value. 17 | public var string: String { 18 | didSet { 19 | tag = .implicit 20 | } 21 | } 22 | /// This node's tag (its type). 23 | public var tag: Tag 24 | /// The style to be used when emitting this node. 25 | public var style: Style 26 | /// The location for this node. 27 | public var mark: Mark? 28 | 29 | /// The style to use when emitting a `Scalar`. 30 | public enum Style: UInt32 { 31 | /// Let the emitter choose the style. 32 | case any = 0 33 | /// The plain scalar style. 34 | case plain 35 | 36 | /// The single-quoted scalar style. 37 | case singleQuoted 38 | /// The double-quoted scalar style. 39 | case doubleQuoted 40 | 41 | /// The literal scalar style. 42 | case literal 43 | /// The folded scalar style. 44 | case folded 45 | } 46 | 47 | /// Create a `Node.Scalar` using the specified parameters. 48 | /// 49 | /// - parameter string: The string to generate this scalar. 50 | /// - parameter tag: This scalar's `Tag`. 51 | /// - parameter style: The style to use when emitting this `Scalar`. 52 | /// - parameter mark: This scalar's `Mark`. 53 | public init(_ string: String, _ tag: Tag = .implicit, _ style: Style = .any, _ mark: Mark? = nil) { 54 | self.string = string 55 | self.tag = tag 56 | self.style = style 57 | self.mark = mark 58 | } 59 | } 60 | 61 | /// Get or set the `Node.Scalar` value if this node is a `Node.scalar`. 62 | public var scalar: Scalar? { 63 | get { 64 | if case let .scalar(scalar) = self { 65 | return scalar 66 | } 67 | return nil 68 | } 69 | set { 70 | if let newValue = newValue { 71 | self = .scalar(newValue) 72 | } 73 | } 74 | } 75 | } 76 | 77 | extension Node.Scalar: Comparable { 78 | /// :nodoc: 79 | public static func < (lhs: Node.Scalar, rhs: Node.Scalar) -> Bool { 80 | return lhs.string < rhs.string 81 | } 82 | } 83 | 84 | extension Node.Scalar: Equatable { 85 | /// :nodoc: 86 | public static func == (lhs: Node.Scalar, rhs: Node.Scalar) -> Bool { 87 | return lhs.string == rhs.string && lhs.resolvedTag == rhs.resolvedTag 88 | } 89 | } 90 | 91 | #if swift(>=4.1.50) 92 | extension Node.Scalar: Hashable { 93 | /// :nodoc: 94 | public func hash(into hasher: inout Hasher) { 95 | hasher.combine(string) 96 | hasher.combine(resolvedTag) 97 | } 98 | } 99 | #endif 100 | 101 | extension Node.Scalar: TagResolvable { 102 | static let defaultTagName = Tag.Name.str 103 | func resolveTag(using resolver: Resolver) -> Tag.Name { 104 | return tag.name == .implicit ? resolver.resolveTag(from: string) : tag.name 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /Pods/Yams/Sources/Yams/Node.Sequence.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Node.Sequence.swift 3 | // Yams 4 | // 5 | // Created by Norio Nomura on 2/24/17. 6 | // Copyright (c) 2016 Yams. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // MARK: Node+Sequence 12 | 13 | extension Node { 14 | /// Sequence node. 15 | public struct Sequence { 16 | private var nodes: [Node] 17 | /// This node's tag (its type). 18 | public var tag: Tag 19 | /// The style to be used when emitting this node. 20 | public var style: Style 21 | /// The location for this node. 22 | public var mark: Mark? 23 | 24 | /// The style to use when emitting a `Sequence`. 25 | public enum Style: UInt32 { 26 | /// Let the emitter choose the style. 27 | case any 28 | /// The block sequence style. 29 | case block 30 | /// The flow sequence style. 31 | case flow 32 | } 33 | 34 | /// Create a `Node.Sequence` using the specified parameters. 35 | /// 36 | /// - parameter nodes: The array of nodes to generate this sequence. 37 | /// - parameter tag: This sequence's `Tag`. 38 | /// - parameter style: The style to use when emitting this `Sequence`. 39 | /// - parameter mark: This sequence's `Mark`. 40 | public init(_ nodes: [Node], _ tag: Tag = .implicit, _ style: Style = .any, _ mark: Mark? = nil) { 41 | self.nodes = nodes 42 | self.tag = tag 43 | self.style = style 44 | self.mark = mark 45 | } 46 | } 47 | 48 | /// Get or set the `Node.Sequence` value if this node is a `Node.sequence`. 49 | public var sequence: Sequence? { 50 | get { 51 | if case let .sequence(sequence) = self { 52 | return sequence 53 | } 54 | return nil 55 | } 56 | set { 57 | if let newValue = newValue { 58 | self = .sequence(newValue) 59 | } 60 | } 61 | } 62 | } 63 | 64 | // MARK: - Node.Sequence 65 | 66 | extension Node.Sequence: Comparable { 67 | /// :nodoc: 68 | public static func < (lhs: Node.Sequence, rhs: Node.Sequence) -> Bool { 69 | return lhs.nodes < rhs.nodes 70 | } 71 | } 72 | 73 | extension Node.Sequence: Equatable { 74 | /// :nodoc: 75 | public static func == (lhs: Node.Sequence, rhs: Node.Sequence) -> Bool { 76 | return lhs.nodes == rhs.nodes && lhs.resolvedTag == rhs.resolvedTag 77 | } 78 | } 79 | 80 | #if swift(>=4.1.50) 81 | extension Node.Sequence: Hashable { 82 | /// :nodoc: 83 | public func hash(into hasher: inout Hasher) { 84 | hasher.combine(nodes) 85 | hasher.combine(resolvedTag) 86 | } 87 | } 88 | #endif 89 | 90 | extension Node.Sequence: ExpressibleByArrayLiteral { 91 | /// :nodoc: 92 | public init(arrayLiteral elements: Node...) { 93 | self.init(elements) 94 | } 95 | } 96 | 97 | extension Node.Sequence: MutableCollection { 98 | // Sequence 99 | /// :nodoc: 100 | public func makeIterator() -> Array.Iterator { 101 | return nodes.makeIterator() 102 | } 103 | 104 | // Collection 105 | /// :nodoc: 106 | public typealias Index = Array.Index 107 | 108 | /// :nodoc: 109 | public var startIndex: Index { 110 | return nodes.startIndex 111 | } 112 | 113 | /// :nodoc: 114 | public var endIndex: Index { 115 | return nodes.endIndex 116 | } 117 | 118 | /// :nodoc: 119 | public func index(after index: Index) -> Index { 120 | return nodes.index(after: index) 121 | } 122 | 123 | /// :nodoc: 124 | public subscript(index: Index) -> Node { 125 | get { 126 | return nodes[index] 127 | } 128 | // MutableCollection 129 | set { 130 | nodes[index] = newValue 131 | } 132 | } 133 | 134 | /// :nodoc: 135 | public subscript(bounds: Range) -> Array.SubSequence { 136 | get { 137 | return nodes[bounds] 138 | } 139 | // MutableCollection 140 | set { 141 | nodes[bounds] = newValue 142 | } 143 | } 144 | 145 | /// :nodoc: 146 | public var indices: Array.Indices { 147 | return nodes.indices 148 | } 149 | } 150 | 151 | extension Node.Sequence: RandomAccessCollection { 152 | // BidirectionalCollection 153 | /// :nodoc: 154 | public func index(before index: Index) -> Index { 155 | return nodes.index(before: index) 156 | } 157 | 158 | // RandomAccessCollection 159 | /// :nodoc: 160 | public func index(_ index: Index, offsetBy num: Int) -> Index { 161 | return nodes.index(index, offsetBy: num) 162 | } 163 | 164 | /// :nodoc: 165 | public func distance(from start: Index, to end: Int) -> Index { 166 | return nodes.distance(from: start, to: end) 167 | } 168 | } 169 | 170 | extension Node.Sequence: RangeReplaceableCollection { 171 | /// :nodoc: 172 | public init() { 173 | self.init([]) 174 | } 175 | 176 | /// :nodoc: 177 | public mutating func replaceSubrange(_ subrange: Range, with newElements: C) 178 | where C: Collection, C.Iterator.Element == Node { 179 | nodes.replaceSubrange(subrange, with: newElements) 180 | } 181 | } 182 | 183 | extension Node.Sequence: TagResolvable { 184 | static let defaultTagName = Tag.Name.seq 185 | } 186 | -------------------------------------------------------------------------------- /Pods/Yams/Sources/Yams/Resolver.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Resolver.swift 3 | // Yams 4 | // 5 | // Created by Norio Nomura on 12/15/16. 6 | // Copyright (c) 2016 Yams. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Class used to resolve nodes to tags based on customizable rules. 12 | public final class Resolver { 13 | /// Rule describing how to resolve tags from regex patterns. 14 | public struct Rule { 15 | /// The tag name this rule applies to. 16 | public let tag: Tag.Name 17 | internal let regexp: NSRegularExpression 18 | /// The regex pattern used to resolve this rule. 19 | public var pattern: String { return regexp.pattern } 20 | 21 | /// Create a rule with the specified tag name and regex pattern. 22 | /// 23 | /// - parameter tag: The tag name this rule should apply to. 24 | /// - parameter pattern: The regex pattern used to resolve this rule. 25 | /// 26 | /// - throws: Throws an error if the regular expression pattern is invalid. 27 | public init(_ tag: Tag.Name, _ pattern: String) throws { 28 | self.tag = tag 29 | self.regexp = try .init(pattern: pattern, options: []) 30 | } 31 | } 32 | 33 | /// The rules used by this resolver to resolve nodes to tags. 34 | public let rules: [Rule] 35 | 36 | internal init(_ rules: [Rule] = []) { self.rules = rules } 37 | 38 | /// Resolve a tag name from a given node. 39 | /// 40 | /// - parameter node: Node whose tag should be resolved. 41 | /// 42 | /// - returns: The resolved tag name. 43 | public func resolveTag(of node: Node) -> Tag.Name { 44 | switch node { 45 | case let .scalar(scalar): 46 | return resolveTag(of: scalar) 47 | case let .mapping(mapping): 48 | return resolveTag(of: mapping) 49 | case let .sequence(sequence): 50 | return resolveTag(of: sequence) 51 | } 52 | } 53 | 54 | /// Returns a Resolver constructed by appending rule. 55 | public func appending(_ rule: Rule) -> Resolver { 56 | return .init(rules + [rule]) 57 | } 58 | 59 | /// Returns a Resolver constructed by appending pattern for tag. 60 | public func appending(_ tag: Tag.Name, _ pattern: String) throws -> Resolver { 61 | return appending(try Rule(tag, pattern)) 62 | } 63 | 64 | /// Returns a Resolver constructed by replacing rule. 65 | public func replacing(_ rule: Rule) -> Resolver { 66 | return .init(rules.map { $0.tag == rule.tag ? rule : $0 }) 67 | } 68 | 69 | /// Returns a Resolver constructed by replacing pattern for tag. 70 | public func replacing(_ tag: Tag.Name, with pattern: String) throws -> Resolver { 71 | return .init(try rules.map { $0.tag == tag ? try Rule($0.tag, pattern) : $0 }) 72 | } 73 | 74 | /// Returns a Resolver constructed by removing pattern for tag. 75 | public func removing(_ tag: Tag.Name) -> Resolver { 76 | return .init(rules.filter({ $0.tag != tag })) 77 | } 78 | 79 | // MARK: - internal 80 | 81 | func resolveTag(of value: T) -> Tag.Name where T: TagResolvable { 82 | return value.resolveTag(using: self) 83 | } 84 | 85 | func resolveTag(from string: String) -> Tag.Name { 86 | for rule in rules where rule.regexp.matches(in: string) { 87 | return rule.tag 88 | } 89 | return .str 90 | } 91 | } 92 | 93 | // MARK: Defaults 94 | 95 | extension Resolver { 96 | /// Resolver with no rules. 97 | public static let basic = Resolver() 98 | /// Resolver with a default set of rules. 99 | public static let `default` = Resolver([.bool, .int, .float, .merge, .null, .timestamp, .value]) 100 | } 101 | 102 | // MARK: Default Resolver Rules 103 | 104 | extension Resolver.Rule { 105 | // swiftlint:disable force_try 106 | 107 | /// Default bool resolver rule. 108 | public static let bool = try! Resolver.Rule(.bool, """ 109 | ^(?:yes|Yes|YES|no|No|NO\ 110 | |true|True|TRUE|false|False|FALSE\ 111 | |on|On|ON|off|Off|OFF)$ 112 | """) 113 | 114 | /// Default int resolver rule. 115 | public static let int = try! Resolver.Rule(.int, """ 116 | ^(?:[-+]?0b[0-1_]+\ 117 | |[-+]?0o?[0-7_]+\ 118 | |[-+]?(?:0|[1-9][0-9_]*)\ 119 | |[-+]?0x[0-9a-fA-F_]+\ 120 | |[-+]?[1-9][0-9_]*(?::[0-5]?[0-9])+)$ 121 | """) 122 | 123 | /// Default float resolver rule. 124 | public static let float = try! Resolver.Rule(.float, """ 125 | ^(?:[-+]?(?:[0-9][0-9_]*)(?:\\.[0-9_]*)?(?:[eE][-+]?[0-9]+)?\ 126 | |\\.[0-9_]+(?:[eE][-+][0-9]+)?\ 127 | |[-+]?[0-9][0-9_]*(?::[0-5]?[0-9])+\\.[0-9_]*\ 128 | |[-+]?\\.(?:inf|Inf|INF)\ 129 | |\\.(?:nan|NaN|NAN))$ 130 | """) 131 | 132 | /// Default merge resolver rule. 133 | public static let merge = try! Resolver.Rule(.merge, "^(?:<<)$") 134 | 135 | /// Default null resolver rule. 136 | public static let null = try! Resolver.Rule(.null, """ 137 | ^(?:~\ 138 | |null|Null|NULL\ 139 | |)$ 140 | """) 141 | 142 | /// Default timestamp resolver rule. 143 | public static let timestamp = try! Resolver.Rule(.timestamp, """ 144 | ^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]\ 145 | |[0-9][0-9][0-9][0-9]-[0-9][0-9]?-[0-9][0-9]?\ 146 | (?:[Tt]|[ \\t]+)[0-9][0-9]?\ 147 | :[0-9][0-9]:[0-9][0-9](?:\\.[0-9]*)?\ 148 | (?:[ \\t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$ 149 | """) 150 | 151 | /// Default value resolver rule. 152 | public static let value = try! Resolver.Rule(.value, "^(?:=)$") 153 | 154 | // swiftlint:enable force_try 155 | } 156 | 157 | func pattern(_ string: String) -> NSRegularExpression { 158 | do { 159 | return try .init(pattern: string, options: []) 160 | } catch { 161 | fatalError("unreachable") 162 | } 163 | } 164 | 165 | private extension NSRegularExpression { 166 | func matches(in string: String) -> Bool { 167 | let range = NSRange(location: 0, length: string.utf16.count) 168 | if let match = firstMatch(in: string, options: [], range: range) { 169 | return match.range.location != NSNotFound 170 | } 171 | return false 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /Pods/Yams/Sources/Yams/String+Yams.swift: -------------------------------------------------------------------------------- 1 | // 2 | // String+Yams.swift 3 | // Yams 4 | // 5 | // Created by Norio Nomura on 12/7/16. 6 | // Copyright (c) 2016 Yams. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension String { 12 | typealias LineNumberColumnAndContents = (lineNumber: Int, column: Int, contents: String) 13 | 14 | /// line number, column and contents at utf8 offset. 15 | /// 16 | /// - parameter offset: Int 17 | /// 18 | /// - returns: lineNumber: line number start from 0, 19 | /// column: utf16 column start from 0, 20 | /// contents: substring of line 21 | func utf8LineNumberColumnAndContents(at offset: Int) -> LineNumberColumnAndContents? { 22 | guard let index = utf8 23 | .index(utf8.startIndex, offsetBy: offset, limitedBy: utf8.endIndex)? 24 | .samePosition(in: self) else { return nil } 25 | return lineNumberColumnAndContents(at: index) 26 | } 27 | 28 | /// line number, column and contents at utf16 offset. 29 | /// 30 | /// - parameter offset: Int 31 | /// 32 | /// - returns: lineNumber: line number start from 0, 33 | /// column: utf16 column start from 0, 34 | /// contents: substring of line 35 | func utf16LineNumberColumnAndContents(at offset: Int) -> LineNumberColumnAndContents? { 36 | guard let index = utf16 37 | .index(utf16.startIndex, offsetBy: offset, limitedBy: utf16.endIndex)? 38 | .samePosition(in: self) else { return nil } 39 | return lineNumberColumnAndContents(at: index) 40 | } 41 | 42 | /// line number, column and contents at Index. 43 | /// 44 | /// - parameter index: String.Index 45 | /// 46 | /// - returns: lineNumber: line number start from 0, 47 | /// column: utf16 column start from 0, 48 | /// contents: substring of line 49 | func lineNumberColumnAndContents(at index: Index) -> LineNumberColumnAndContents { 50 | assert((startIndex.. String { 76 | var number = 0 77 | var outStartIndex = startIndex, outEndIndex = startIndex, outContentsEndIndex = startIndex 78 | getLineStart(&outStartIndex, end: &outEndIndex, contentsEnd: &outContentsEndIndex, 79 | for: startIndex.. Tag { 54 | return .init(name ?? self.name, resolver ?? self.resolver, constructor ?? self.constructor) 55 | } 56 | 57 | // internal 58 | let constructor: Constructor 59 | var name: Name 60 | 61 | func resolved(with value: T) -> Tag where T: TagResolvable { 62 | if name == .implicit { 63 | name = resolver.resolveTag(of: value) 64 | } else if name == .nonSpecific { 65 | name = T.defaultTagName 66 | } 67 | return self 68 | } 69 | 70 | // private 71 | private let resolver: Resolver 72 | } 73 | 74 | extension Tag: CustomStringConvertible { 75 | /// A textual representation of this tag. 76 | public var description: String { 77 | return name.rawValue 78 | } 79 | } 80 | 81 | extension Tag: Hashable { 82 | #if swift(>=4.1.50) 83 | /// :nodoc: 84 | public func hash(into hasher: inout Hasher) { 85 | hasher.combine(name) 86 | } 87 | #else 88 | /// :nodoc: 89 | public var hashValue: Int { 90 | return name.hashValue 91 | } 92 | #endif 93 | 94 | /// :nodoc: 95 | public static func == (lhs: Tag, rhs: Tag) -> Bool { 96 | return lhs.name == rhs.name 97 | } 98 | } 99 | 100 | extension Tag.Name: ExpressibleByStringLiteral { 101 | /// :nodoc: 102 | public init(stringLiteral value: String) { 103 | self.rawValue = value 104 | } 105 | } 106 | 107 | extension Tag.Name: Hashable { 108 | #if !swift(>=4.1.50) 109 | /// :nodoc: 110 | public var hashValue: Int { 111 | return rawValue.hashValue 112 | } 113 | 114 | /// :nodoc: 115 | public static func == (lhs: Tag.Name, rhs: Tag.Name) -> Bool { 116 | return lhs.rawValue == rhs.rawValue 117 | } 118 | #endif 119 | } 120 | 121 | // http://www.yaml.org/spec/1.2/spec.html#Schema 122 | extension Tag.Name { 123 | // Special 124 | /// Tag should be resolved by value. 125 | public static let implicit: Tag.Name = "" 126 | /// Tag should not be resolved by value, and be resolved as .str, .seq or .map. 127 | public static let nonSpecific: Tag.Name = "!" 128 | 129 | // Failsafe Schema 130 | /// "tag:yaml.org,2002:str" 131 | public static let str: Tag.Name = "tag:yaml.org,2002:str" 132 | /// "tag:yaml.org,2002:seq" 133 | public static let seq: Tag.Name = "tag:yaml.org,2002:seq" 134 | /// "tag:yaml.org,2002:map" 135 | public static let map: Tag.Name = "tag:yaml.org,2002:map" 136 | // JSON Schema 137 | /// "tag:yaml.org,2002:bool" 138 | public static let bool: Tag.Name = "tag:yaml.org,2002:bool" 139 | /// "tag:yaml.org,2002:float" 140 | public static let float: Tag.Name = "tag:yaml.org,2002:float" 141 | /// "tag:yaml.org,2002:null" 142 | public static let null: Tag.Name = "tag:yaml.org,2002:null" 143 | /// "tag:yaml.org,2002:int" 144 | public static let int: Tag.Name = "tag:yaml.org,2002:int" 145 | // http://yaml.org/type/index.html 146 | /// "tag:yaml.org,2002:binary" 147 | public static let binary: Tag.Name = "tag:yaml.org,2002:binary" 148 | /// "tag:yaml.org,2002:merge" 149 | public static let merge: Tag.Name = "tag:yaml.org,2002:merge" 150 | /// "tag:yaml.org,2002:omap" 151 | public static let omap: Tag.Name = "tag:yaml.org,2002:omap" 152 | /// "tag:yaml.org,2002:pairs" 153 | public static let pairs: Tag.Name = "tag:yaml.org,2002:pairs" 154 | /// "tag:yaml.org,2002:set". 155 | public static let set: Tag.Name = "tag:yaml.org,2002:set" 156 | /// "tag:yaml.org,2002:timestamp" 157 | public static let timestamp: Tag.Name = "tag:yaml.org,2002:timestamp" 158 | /// "tag:yaml.org,2002:value" 159 | public static let value: Tag.Name = "tag:yaml.org,2002:value" 160 | /// "tag:yaml.org,2002:yaml" We don't support this. 161 | public static let yaml: Tag.Name = "tag:yaml.org,2002:yaml" 162 | } 163 | 164 | protocol TagResolvable { 165 | var tag: Tag { get } 166 | static var defaultTagName: Tag.Name { get } 167 | func resolveTag(using resolver: Resolver) -> Tag.Name 168 | } 169 | 170 | extension TagResolvable { 171 | var resolvedTag: Tag { 172 | return tag.resolved(with: self) 173 | } 174 | 175 | func resolveTag(using resolver: Resolver) -> Tag.Name { 176 | return tag.name == .implicit ? Self.defaultTagName : tag.name 177 | } 178 | } 179 | -------------------------------------------------------------------------------- /Pods/Yams/Sources/Yams/Yams.h: -------------------------------------------------------------------------------- 1 | // 2 | // Yams.h 3 | // Yams 4 | // 5 | // Created by Norio Nomura on 1/25/17. 6 | // Copyright (c) 2017 Yams. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Yams. 12 | FOUNDATION_EXPORT double YamsVersionNumber; 13 | 14 | //! Project version string for Yams. 15 | FOUNDATION_EXPORT const unsigned char YamsVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | #import 20 | -------------------------------------------------------------------------------- /Pods/Yams/Sources/Yams/shim.swift: -------------------------------------------------------------------------------- 1 | // 2 | // shim.swift 3 | // Yams 4 | // 5 | // Created by Norio Nomura 1/27/18. 6 | // Copyright (c) 2018 Yams. All rights reserved. 7 | // 8 | 9 | #if !swift(>=4.1) 10 | extension Sequence { 11 | func compactMap( 12 | _ transform: (Self.Element 13 | ) throws -> ElementOfResult?) rethrows -> [ElementOfResult] { 14 | return try flatMap(transform) 15 | } 16 | } 17 | #endif 18 | 19 | #if os(Linux) && !swift(>=4.2) 20 | extension Substring { 21 | func hasPrefix(_ prefix: String) -> Bool { 22 | return String(self).hasPrefix(prefix) 23 | } 24 | } 25 | #endif 26 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## PassHUD 2 | 3 | A HUD-style fuzzy-finder interface for [zx2c4's 4 | `pass`](https://www.passwordstore.org) on macOS. Copies passwords to clipboard. 5 | Depends on `pass` being installed and configured. 6 | 7 | ![Screenshot](PassHUDScreenShot.png) 8 | 9 | ### Usage 10 | 11 | Run the PassHUD application, then open PassHUD's window by clicking its lock 12 | menu bar icon, or by using its default keyboard shorcut of `⌘ ` + `/`. 13 | 14 | PassHUD fuzzy-finds passwords as you type. Click passwords to copy them to the 15 | clipboard or just hit `Enter` once the password is highlighted. PassHUD keeps 16 | recently used passwords at the top of the list for easy access. 17 | 18 | Passwords are written to the clipboard directly by `pass` and are never seen by 19 | PassHUD. Default `pass` clipboard clearing behavior applies. 20 | 21 | ### Installation 22 | 23 | Download and install the latest release from a DMG on [the releases 24 | page](https://github.com/mnussbaum/PassHUD/releases/). 25 | 26 | ### Configuration 27 | 28 | PassHUD can be configured with an optional config file that can be created at 29 | one of the following paths: 30 | 31 | * `~/.PassHUD` 32 | * `~/.config/PassHUD/config` 33 | 34 | The config file is YAML and can set environment variables for PassHUD's 35 | execution of `pass`, and an optional path to `pass` itself. If a path isn't 36 | provided `pass` must be on the `$PATH`. All fields in the config are optional. 37 | Here's an exhaustive example config file: 38 | 39 | ```yaml 40 | --- 41 | version: 1 42 | 43 | pass: 44 | commandPath: ~/a/non/default/path/to/pass 45 | env: 46 | - name: PASSWORD_STORE_DIR 47 | value: ~/a/non/default/password/store/path 48 | 49 | # This example registers two arbitrary hot keys. Valid modifiers are: "cmd", 50 | # "ctrl", "opt" and "shift" 51 | hotKeys: 52 | - modifiers: 53 | - cmd 54 | - shift 55 | key: \ 56 | - modifiers: 57 | - cmd 58 | key: / 59 | ``` 60 | --------------------------------------------------------------------------------