|
|
@ -5,74 +5,140 @@ import GRDB
|
|
|
|
import SessionUtil
|
|
|
|
import SessionUtil
|
|
|
|
import SessionUtilitiesKit
|
|
|
|
import SessionUtilitiesKit
|
|
|
|
|
|
|
|
|
|
|
|
/*internal*/public enum SessionUtil { // TODO: Rename this to be cleaner?
|
|
|
|
/*internal*/public enum SessionUtil {
|
|
|
|
|
|
|
|
typealias ConfResult = (needsPush: Bool, needsDump: Bool)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// MARK: - Configs
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static var userProfileConfig: Atomic<UnsafeMutablePointer<config_object>?> = Atomic(nil)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// MARK: - Variables
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public static var needsSync: Bool {
|
|
|
|
|
|
|
|
return ConfigDump.Variant.allCases.contains { variant in
|
|
|
|
|
|
|
|
switch variant {
|
|
|
|
|
|
|
|
case .userProfile:
|
|
|
|
|
|
|
|
return (userProfileConfig.wrappedValue.map { config_needs_push($0) } ?? false)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// MARK: - Loading
|
|
|
|
|
|
|
|
|
|
|
|
/*internal*/public static func loadState() {
|
|
|
|
/*internal*/public static func loadState() {
|
|
|
|
|
|
|
|
SessionUtil.userProfileConfig.mutate { $0 = loadState(for: .userProfile) }
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private static func loadState(for variant: ConfigDump.Variant) -> UnsafeMutablePointer<config_object>? {
|
|
|
|
|
|
|
|
// Load any
|
|
|
|
let storedDump: Data? = Storage.shared
|
|
|
|
let storedDump: Data? = Storage.shared
|
|
|
|
.read { db in try ConfigDump.fetchOne(db, id: .userProfile) }?
|
|
|
|
.read { db in try ConfigDump.fetchOne(db, id: variant) }?
|
|
|
|
.data
|
|
|
|
.data
|
|
|
|
var dump: UnsafePointer<CChar>? = nil // TODO: Load from DB/Disk
|
|
|
|
|
|
|
|
let dumpLen: size_t = 0
|
|
|
|
|
|
|
|
var conf: UnsafeMutablePointer<config_object>? = nil
|
|
|
|
|
|
|
|
// var confSetup: UnsafeMutablePointer<UnsafeMutablePointer<config_object>?>? = nil
|
|
|
|
|
|
|
|
var error: UnsafeMutablePointer<CChar>? = nil
|
|
|
|
|
|
|
|
// TODO: Will need to manually release any unsafe pointers
|
|
|
|
|
|
|
|
let result = user_profile_init(&conf, dump, dumpLen, error)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
guard result == 0 else { return } // TODO: Throw error
|
|
|
|
return try? loadState(for: variant, cachedData: storedDump)
|
|
|
|
|
|
|
|
}
|
|
|
|
// var conf: UnsafeMutablePointer<config_object>? = confSetup?.pointee
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
user_profile_set_name(conf, "TestName") // TODO: Confirm success
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let profileUrl: [CChar] = "http://example.org/omg-pic-123.bmp".bytes.map { CChar(bitPattern: $0) }
|
|
|
|
internal static func loadState(
|
|
|
|
let profileKey: [CChar] = "secretNOTSECRET".bytes.map { CChar(bitPattern: $0) }
|
|
|
|
for variant: ConfigDump.Variant,
|
|
|
|
let profilePic: user_profile_pic = profileUrl.withUnsafeBufferPointer { profileUrlPtr in
|
|
|
|
cachedData: Data? = nil
|
|
|
|
profileKey.withUnsafeBufferPointer { profileKeyPtr in
|
|
|
|
) throws -> UnsafeMutablePointer<config_object>? {
|
|
|
|
user_profile_pic(
|
|
|
|
// Setup initial variables (including getting the memory address for any cached data)
|
|
|
|
url: profileUrlPtr.baseAddress,
|
|
|
|
var conf: UnsafeMutablePointer<config_object>? = nil
|
|
|
|
key: profileKeyPtr.baseAddress,
|
|
|
|
let error: UnsafeMutablePointer<CChar>? = nil
|
|
|
|
keylen: profileKey.count
|
|
|
|
let cachedDump: (data: UnsafePointer<CChar>, length: Int)? = cachedData?.withUnsafeBytes { unsafeBytes in
|
|
|
|
|
|
|
|
return unsafeBytes.baseAddress.map {
|
|
|
|
|
|
|
|
(
|
|
|
|
|
|
|
|
$0.assumingMemoryBound(to: CChar.self),
|
|
|
|
|
|
|
|
unsafeBytes.count
|
|
|
|
)
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
user_profile_set_pic(conf, profilePic) // TODO: Confirm success
|
|
|
|
// No need to deallocate the `cachedDump.data` as it'll automatically be cleaned up by
|
|
|
|
|
|
|
|
// the `cachedData` lifecycle, but need to deallocate the `error` if it gets set
|
|
|
|
if config_needs_push(conf) {
|
|
|
|
defer {
|
|
|
|
print("Needs Push!!!")
|
|
|
|
error?.deallocate()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if config_needs_dump(conf) {
|
|
|
|
// Try to create the object
|
|
|
|
print("Needs Dump!!!")
|
|
|
|
let result: Int32 = {
|
|
|
|
|
|
|
|
switch variant {
|
|
|
|
|
|
|
|
case .userProfile:
|
|
|
|
|
|
|
|
return user_profile_init(&conf, cachedDump?.data, (cachedDump?.length ?? 0), error)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
guard result == 0 else {
|
|
|
|
|
|
|
|
let errorString: String = (error.map { String(cString: $0) } ?? "unknown error")
|
|
|
|
|
|
|
|
SNLog("[SessionUtil Error] Unable to create \(variant.rawValue) config object: \(errorString)")
|
|
|
|
|
|
|
|
throw SessionUtilError.unableToCreateConfigObject
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var toPush: UnsafeMutablePointer<CChar>? = nil
|
|
|
|
return conf
|
|
|
|
var pushLen: Int = 0
|
|
|
|
}
|
|
|
|
let seqNo = config_push(conf, &toPush, &pushLen)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//var remoteAddr: [CChar] = remote.bytes.map { CChar(bitPattern: $0) }
|
|
|
|
internal static func saveState(
|
|
|
|
//config_dump(conf, &dump1, &dump1len);
|
|
|
|
_ db: Database,
|
|
|
|
|
|
|
|
conf: UnsafeMutablePointer<config_object>?,
|
|
|
|
|
|
|
|
for variant: ConfigDump.Variant
|
|
|
|
|
|
|
|
) throws {
|
|
|
|
|
|
|
|
guard conf != nil else { throw SessionUtilError.nilConfigObject }
|
|
|
|
|
|
|
|
|
|
|
|
free(toPush) // TODO: Confirm
|
|
|
|
// If it doesn't need a dump then do nothing
|
|
|
|
|
|
|
|
guard config_needs_dump(conf) else { return }
|
|
|
|
|
|
|
|
|
|
|
|
var dumpResult: UnsafeMutablePointer<CChar>? = nil
|
|
|
|
var dumpResult: UnsafeMutablePointer<CChar>? = nil
|
|
|
|
var dumpResultLen: Int = 0
|
|
|
|
var dumpResultLen: Int = 0
|
|
|
|
|
|
|
|
|
|
|
|
config_dump(conf, &dumpResult, &dumpResultLen)
|
|
|
|
config_dump(conf, &dumpResult, &dumpResultLen)
|
|
|
|
|
|
|
|
|
|
|
|
print("RAWR")
|
|
|
|
guard let dumpResult: UnsafeMutablePointer<CChar> = dumpResult else { return }
|
|
|
|
let str = String(cString: dumpResult!)
|
|
|
|
|
|
|
|
let stryBytes = str.bytes
|
|
|
|
let dumpData: Data = Data(bytes: dumpResult, count: dumpResultLen)
|
|
|
|
let hexStr = stryBytes.toHexString()
|
|
|
|
dumpResult.deallocate()
|
|
|
|
let data = Data(bytes: dumpResult!, count: dumpResultLen)
|
|
|
|
|
|
|
|
// dumpResult.
|
|
|
|
try ConfigDump(
|
|
|
|
// Storage.shared.write { db in
|
|
|
|
variant: variant,
|
|
|
|
// try ConfigDump(variant: .userProfile, data: <#T##Data#>)
|
|
|
|
data: dumpData
|
|
|
|
// .save(db)
|
|
|
|
)
|
|
|
|
// }
|
|
|
|
.save(db)
|
|
|
|
//
|
|
|
|
}
|
|
|
|
print("RAWR2")
|
|
|
|
|
|
|
|
|
|
|
|
// MARK: - UserProfile
|
|
|
|
//String(cString: dumpResult!)
|
|
|
|
|
|
|
|
|
|
|
|
internal static func update(
|
|
|
|
|
|
|
|
conf: UnsafeMutablePointer<config_object>?,
|
|
|
|
|
|
|
|
with profile: Profile
|
|
|
|
|
|
|
|
) throws -> ConfResult {
|
|
|
|
|
|
|
|
guard conf != nil else { throw SessionUtilError.nilConfigObject }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Update the name
|
|
|
|
|
|
|
|
user_profile_set_name(conf, profile.name)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let profilePic: user_profile_pic? = profile.profilePictureUrl?
|
|
|
|
|
|
|
|
.bytes
|
|
|
|
|
|
|
|
.map { CChar(bitPattern: $0) }
|
|
|
|
|
|
|
|
.withUnsafeBufferPointer { profileUrlPtr in
|
|
|
|
|
|
|
|
let profileKey: [CChar]? = profile.profileEncryptionKey?
|
|
|
|
|
|
|
|
.keyData
|
|
|
|
|
|
|
|
.bytes
|
|
|
|
|
|
|
|
.map { CChar(bitPattern: $0) }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return profileKey?.withUnsafeBufferPointer { profileKeyPtr in
|
|
|
|
|
|
|
|
user_profile_pic(
|
|
|
|
|
|
|
|
url: profileUrlPtr.baseAddress,
|
|
|
|
|
|
|
|
key: profileKeyPtr.baseAddress,
|
|
|
|
|
|
|
|
keylen: (profileKey?.count ?? 0)
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if let profilePic: user_profile_pic = profilePic {
|
|
|
|
|
|
|
|
user_profile_set_pic(conf, profilePic)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
|
|
needsPush: config_needs_push(conf),
|
|
|
|
|
|
|
|
needsDump: config_needs_dump(conf)
|
|
|
|
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|