CryptoPassphrase  Diff

Differences From Artifact [0a36bee6de]:

To Artifact [0072dc8d4f]:


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

49
50



51
52
53
54
55
56
57
58
59
60
61

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91


92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131


132
133
134
135
 * POSSIBILITY OF SUCH DAMAGE.
 */

import ObjFW
import ObjFWBridge

class SiteStorage: OFObject {
    private typealias Storage =
        OFMutableDictionary<OFString, OFDictionary<OFNumber, AnyObject>>

    private static let lengthField = OFNumber(uInt8: 0)
    private static let legacyField = OFNumber(uInt8: 1)
    private static let keyFileField = OFNumber(uInt8: 2)

    private var path: OFString
    private var storage: Storage
    private var sites: OFArray<OFString>

    override init() {
        let fileManager = OFFileManager.default
        let userDataPath = OFSystemInfo.userDataPath!

        if !fileManager.directoryExists(atPath: userDataPath) {
            fileManager.createDirectory(atPath: userDataPath)
        }

        let path = userDataPath.appendingPathComponent(
            OFString(utf8String: "sites.msgpack"))
        var storage: Storage? = nil

        OFException.try({
            storage = OFData(contentsOfFile: path).messagePackValue as? Storage



        }, catch: { (OFException) in
            storage = OFMutableDictionary()
        })

        self.path = path
        self.storage = storage!
        self.sites = self.storage.allKeys.sorted
    }

    func sites(withFilter filter: OFString?) -> OFArray<OFString> {
        // FIXME: We need case folding here, but there is no method for it yet.

        let filter = filter?.lowercase

        return storage.allKeys.sorted.filteredArray({
            (name: Any, index: size_t) -> Bool in
            if filter == nil {
                return true
            }

            let name = name as! OFString
            return name.lowercase.contains(filter!)
        })
    }

    func hasSite(_ name: OFString) -> Bool {
        return (storage[name] != nil)
    }

    func length(forSite name: OFString) -> size_t {
        guard let site = storage[name] else {
            OFInvalidArgumentException().throw()
        }

        return (site[SiteStorage.lengthField] as! OFNumber).sizeValue
    }

    func isLegacy(site name: OFString) -> Bool {
        guard let site = storage[name] else {
            OFInvalidArgumentException().throw()
        }



        return (site[SiteStorage.legacyField] as! OFNumber).boolValue
    }

    func keyFile(forSite name: OFString) -> OFString? {
        guard let site = storage[name] else {
            OFInvalidArgumentException().throw()
        }

        let keyFile = site[SiteStorage.keyFileField]
        if keyFile is OFNull {
            return nil
        }

        return keyFile as? OFString
    }

    func setSite(_ name: OFString, length: size_t, legacy: Bool,
                 keyFile: OFString?) {
        let siteDictionary = OFMutableDictionary<OFNumber, AnyObject>()

        siteDictionary.setObject(OFNumber(size: length),
                                 forKey: SiteStorage.lengthField)
        siteDictionary.setObject(OFNumber(bool: legacy),
                                 forKey: SiteStorage.legacyField)
        if keyFile != nil {
            siteDictionary.setObject(keyFile!, forKey: SiteStorage.keyFileField)
        }

        siteDictionary.makeImmutable()
        storage.setObject(siteDictionary, forKey: name)


        self.update()
    }

    func removeSite(_ name: OFString) {
        self.storage.removeObject(forKey: name)
        self.update()
    }

    private func update() {


        storage.messagePackRepresentation.write(toFile: path)
        sites = storage.allKeys.sorted
    }
}







<
<
<
|
|
|


|
|











|
>

|
>
>
>

|




|


|
<
>
|
|
<
<
<
<
<
|
<
|



|



|




|

<
<
<
<
<

>
>
|


|
|
<
|
<
|
|



|


|
|
<
<
|
|
<
|
<
<
<
|
|
<

>



|
|




>
>
|
|


20
21
22
23
24
25
26



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61

62
63
64





65

66
67
68
69
70
71
72
73
74
75
76
77
78
79
80





81
82
83
84
85
86
87
88

89

90
91
92
93
94
95
96
97
98
99


100
101

102



103
104

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
 * POSSIBILITY OF SUCH DAMAGE.
 */

import ObjFW
import ObjFWBridge

class SiteStorage: OFObject {



    private static let lengthField = NSNumber(value: 0)
    private static let legacyField = NSNumber(value: 1)
    private static let keyFileField = NSNumber(value: 2)

    private var path: OFString
    private var storage: [String: [NSNumber: AnyObject]]
    private var sites: [String]

    override init() {
        let fileManager = OFFileManager.default
        let userDataPath = OFSystemInfo.userDataPath!

        if !fileManager.directoryExists(atPath: userDataPath) {
            fileManager.createDirectory(atPath: userDataPath)
        }

        let path = userDataPath.appendingPathComponent(
            OFString(utf8String: "sites.msgpack"))

        var storage: [String: [NSNumber: AnyObject]]? = nil
        OFException.try({
            let decoded = (OFData(contentsOfFile: path).messagePackValue)
                as? OFDictionary<OFString, OFDictionary<OFNumber, AnyObject>>
            storage =
                (decoded?.nsObject as? [String: [NSNumber: AnyObject]]) ?? [:]
        }, catch: { (OFException) in
            storage = [:]
        })

        self.path = path
        self.storage = storage!
        self.sites = self.storage.keys.sorted()
    }

    func sites(withFilter filter: String?) -> [String] {

        return storage.keys.sorted().filter({ (name) in
            if let filter = filter {
                return name.localizedCaseInsensitiveContains(filter)





            }

            return true
        })
    }

    func hasSite(_ name: String) -> Bool {
        return (storage[name] != nil)
    }

    func length(forSite name: String) -> UInt {
        guard let site = storage[name] else {
            OFInvalidArgumentException().throw()
        }

        return (site[SiteStorage.lengthField] as! NSNumber).uintValue
    }






    func isLegacy(site name: String) -> Bool {
        guard let site = storage[name] else { return false }
        return (site[SiteStorage.legacyField] as! NSNumber).boolValue
    }

    func keyFile(forSite name: String) -> String? {
        guard let site = storage[name] else { return nil }



        guard let keyFile = site[SiteStorage.keyFileField], !(keyFile is NSNull)
        else {
            return nil
        }

        return keyFile as? String
    }

    func setSite(_ name: String, length: UInt, isLegacy: Bool,
                 keyFile: String?) {


        var siteDictionary: [NSNumber: AnyObject] = [
            SiteStorage.lengthField: NSNumber(value: length),

            SiteStorage.legacyField: NSNumber(value: isLegacy),



        ]
        siteDictionary[SiteStorage.keyFileField] = keyFile as AnyObject?


        storage[name] = siteDictionary
        self.update()
    }

    func removeSite(_ name: String) {
        storage[name] = nil
        self.update()
    }

    private func update() {
        let ofStorage = (storage as NSDictionary).ofObject

        ofStorage.messagePackRepresentation.write(toFile: path)
        sites = storage.keys.sorted()
    }
}