swift/ref: Implement decodeId in CGO layer
Instead of replicating the Go logic in Swift (and Java), wrap the
existing util.DecodeId in a CGO-accessible method.
Also renames Id.swift to Identifier.swift.
Closes vanadium/issues#1400
MultiPart: 2/2
Change-Id: I497f4161fcdd53a2421f3c5c8d27ff2ff8416ade
diff --git a/Syncbase/Source/Id.swift b/Syncbase/Source/Identifier.swift
similarity index 66%
rename from Syncbase/Source/Id.swift
rename to Syncbase/Source/Identifier.swift
index 9a19864..a052f5b 100644
--- a/Syncbase/Source/Id.swift
+++ b/Syncbase/Source/Identifier.swift
@@ -21,23 +21,13 @@
}
public func encode() throws -> String {
- var cStr = v23_syncbase_String()
- let id = try v23_syncbase_Id(toCore())
- v23_syncbase_EncodeId(id, &cStr)
- // If there was a UTF-8 problem, it would have been thrown when UTF-8 encoding the id above.
- // Therefore, we can be confident in unwrapping the conditional here.
- return cStr.toString()!
+ // If there was a UTF-8 problem, it would have been thrown when UTF-8 encoding core's call
+ // to CGO. Therefore, we can be confident in unwrapping the conditional here.
+ return try toCore().encode().toString()!
}
- // TODO(zinman): Replace decode method implementations with call to Cgo.
- static let separator = ","
public static func decode(encodedId: String) throws -> Identifier {
- let parts = encodedId.componentsSeparatedByString(separator)
- if parts.count != 2 {
- throw SyncbaseError.IllegalArgument(detail: "Invalid encoded id: \(encodedId)")
- }
- let (blessing, name) = (parts[0], parts[1])
- return Identifier(name: name, blessing: blessing)
+ return Identifier(coreId: try SyncbaseCore.Identifier.decode(encodedId))
}
public var hashValue: Int {
diff --git a/Syncbase/Syncbase.xcodeproj/project.pbxproj b/Syncbase/Syncbase.xcodeproj/project.pbxproj
index 24528bb..28b494a 100644
--- a/Syncbase/Syncbase.xcodeproj/project.pbxproj
+++ b/Syncbase/Syncbase.xcodeproj/project.pbxproj
@@ -14,7 +14,7 @@
9374F6AF1D01081D004ECE59 /* Collection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9374F6A41D01081D004ECE59 /* Collection.swift */; };
9374F6B01D01081D004ECE59 /* Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9374F6A51D01081D004ECE59 /* Database.swift */; };
9374F6B11D01081D004ECE59 /* DatabaseHandle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9374F6A61D01081D004ECE59 /* DatabaseHandle.swift */; };
- 9374F6B21D01081D004ECE59 /* Id.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9374F6A71D01081D004ECE59 /* Id.swift */; };
+ 9374F6B21D01081D004ECE59 /* Identifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9374F6A71D01081D004ECE59 /* Identifier.swift */; };
9374F6B31D01081D004ECE59 /* Syncbase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9374F6A81D01081D004ECE59 /* Syncbase.swift */; };
9374F6B41D01081D004ECE59 /* Syncgroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9374F6A91D01081D004ECE59 /* Syncgroup.swift */; };
9374F6B51D01081D004ECE59 /* SyncgroupInvite.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9374F6AA1D01081D004ECE59 /* SyncgroupInvite.swift */; };
@@ -64,7 +64,7 @@
9374F6A41D01081D004ECE59 /* Collection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Collection.swift; sourceTree = "<group>"; };
9374F6A51D01081D004ECE59 /* Database.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Database.swift; sourceTree = "<group>"; };
9374F6A61D01081D004ECE59 /* DatabaseHandle.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DatabaseHandle.swift; sourceTree = "<group>"; };
- 9374F6A71D01081D004ECE59 /* Id.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Id.swift; sourceTree = "<group>"; };
+ 9374F6A71D01081D004ECE59 /* Identifier.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Identifier.swift; sourceTree = "<group>"; };
9374F6A81D01081D004ECE59 /* Syncbase.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Syncbase.swift; sourceTree = "<group>"; };
9374F6A91D01081D004ECE59 /* Syncgroup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Syncgroup.swift; sourceTree = "<group>"; };
9374F6AA1D01081D004ECE59 /* SyncgroupInvite.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SyncgroupInvite.swift; sourceTree = "<group>"; };
@@ -128,7 +128,7 @@
9374F6A51D01081D004ECE59 /* Database.swift */,
9374F6A61D01081D004ECE59 /* DatabaseHandle.swift */,
93D90C4C1D080E18004A8E72 /* Error.swift */,
- 9374F6A71D01081D004ECE59 /* Id.swift */,
+ 9374F6A71D01081D004ECE59 /* Identifier.swift */,
9374F68F1D01074B004ECE59 /* Info.plist */,
938DEA9E1D12257E003C9734 /* OAuth.swift */,
9374F6901D01074B004ECE59 /* Syncbase.h */,
@@ -296,7 +296,7 @@
938DEA9F1D12257E003C9734 /* OAuth.swift in Sources */,
9374F6AF1D01081D004ECE59 /* Collection.swift in Sources */,
9374F6B11D01081D004ECE59 /* DatabaseHandle.swift in Sources */,
- 9374F6B21D01081D004ECE59 /* Id.swift in Sources */,
+ 9374F6B21D01081D004ECE59 /* Identifier.swift in Sources */,
93D90C4D1D080E18004A8E72 /* Error.swift in Sources */,
938DEA861D0BAE57003C9734 /* Blessing.swift in Sources */,
9374F6B51D01081D004ECE59 /* SyncgroupInvite.swift in Sources */,
diff --git a/Syncbase/Tests/BasicDatabaseTests.swift b/Syncbase/Tests/BasicDatabaseTests.swift
index ed35a32..3ce4e8d 100644
--- a/Syncbase/Tests/BasicDatabaseTests.swift
+++ b/Syncbase/Tests/BasicDatabaseTests.swift
@@ -107,16 +107,6 @@
}
}
-class SyncgroupTest: XCTestCase {
- override class func setUp() {
- configureDb(disableUserdataSyncgroup: false, disableSyncgroupPublishing: true)
- }
-
- override class func tearDown() {
- Syncbase.shutdown()
- }
-}
-
class UserdataTest: SyncgroupTest {
func testUserdata() {
withDb { db in
diff --git a/Syncbase/Tests/TestHelpers.swift b/Syncbase/Tests/TestHelpers.swift
index 6bb1226..edc524e 100644
--- a/Syncbase/Tests/TestHelpers.swift
+++ b/Syncbase/Tests/TestHelpers.swift
@@ -77,3 +77,14 @@
}
}
}
+
+// This class serves as a base class to inherit -- it doesn't have any tests itself.
+class SyncgroupTest: XCTestCase {
+ override class func setUp() {
+ configureDb(disableUserdataSyncgroup: false, disableSyncgroupPublishing: true)
+ }
+
+ override class func tearDown() {
+ Syncbase.shutdown()
+ }
+}
diff --git a/SyncbaseCore/Source/Collection.swift b/SyncbaseCore/Source/Collection.swift
index 1ce591b..b942746 100644
--- a/SyncbaseCore/Source/Collection.swift
+++ b/SyncbaseCore/Source/Collection.swift
@@ -352,7 +352,7 @@
private static func encodedName(databaseId: Identifier, collectionId: Identifier) throws -> String {
var cStr = v23_syncbase_String()
v23_syncbase_NamingJoin(
- v23_syncbase_Strings([try databaseId.encodeId(), try collectionId.encodeId()]),
+ v23_syncbase_Strings([try databaseId.encode(), try collectionId.encode()]),
&cStr)
return cStr.toString()!
}
diff --git a/SyncbaseCore/Source/Database.swift b/SyncbaseCore/Source/Database.swift
index 0d50592..d6ef9aa 100644
--- a/SyncbaseCore/Source/Database.swift
+++ b/SyncbaseCore/Source/Database.swift
@@ -45,7 +45,7 @@
init(databaseId: Identifier, batchHandle: String?) throws {
self.databaseId = databaseId
self.batchHandle = batchHandle
- self.encodedDatabaseName = try databaseId.encodeId().toString()!
+ self.encodedDatabaseName = try databaseId.encode().toString()!
}
/// Create creates this Database.
diff --git a/SyncbaseCore/Source/Identifier.swift b/SyncbaseCore/Source/Identifier.swift
index d34ea16..a1fba1a 100644
--- a/SyncbaseCore/Source/Identifier.swift
+++ b/SyncbaseCore/Source/Identifier.swift
@@ -4,7 +4,7 @@
import Foundation
-public struct Identifier {
+public struct Identifier: Equatable {
public let name: String
public let blessing: String
@@ -13,12 +13,22 @@
self.blessing = blessing
}
- func encodeId() throws -> v23_syncbase_String {
+ /// ***Advanced users only*** encodes this identifier as needed for low-level Syncbase APIs.
+ public func encode() throws -> v23_syncbase_String {
var cStr = v23_syncbase_String()
let id = try v23_syncbase_Id(self)
v23_syncbase_EncodeId(id, &cStr)
return cStr
}
+
+ /// ***Advanced users only*** decodes an identifier as returned from low-level Syncbase APIs.
+ public static func decode(encodedId: String) throws -> Identifier {
+ var cId = v23_syncbase_Id()
+ try VError.maybeThrow { errPtr in
+ v23_syncbase_DecodeId(try v23_syncbase_String(encodedId), &cId, errPtr)
+ }
+ return cId.toIdentifier()!
+ }
}
public func == (d1: Identifier, d2: Identifier) -> Bool {
diff --git a/SyncbaseCore/SyncbaseCore.xcodeproj/project.pbxproj b/SyncbaseCore/SyncbaseCore.xcodeproj/project.pbxproj
index 3475776..1a89b5e 100644
--- a/SyncbaseCore/SyncbaseCore.xcodeproj/project.pbxproj
+++ b/SyncbaseCore/SyncbaseCore.xcodeproj/project.pbxproj
@@ -37,6 +37,7 @@
930DFCE21CEE46DE00738DB8 /* OAuth.swift in Sources */ = {isa = PBXBuildFile; fileRef = 930DFCE11CEE46DE00738DB8 /* OAuth.swift */; };
9351A4941CE46DB9009CC4F4 /* sbcore_amd64.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 9351A4931CE46DB9009CC4F4 /* sbcore_amd64.a */; };
9374F6681D00FFE5004ECE59 /* TestHelpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9374F6661D00FF68004ECE59 /* TestHelpers.swift */; };
+ 93B3C8391D41D7B5005B20C8 /* BridgeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93B3C8381D41D7B5005B20C8 /* BridgeTests.swift */; };
93C462791D29D7BD00394BAB /* Neighborhood.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93C462781D29D7BD00394BAB /* Neighborhood.swift */; };
93D3AD5C1CE4392A00A80CDA /* libleveldb_amd64.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 93D3AD581CE4392A00A80CDA /* libleveldb_amd64.a */; };
93D3AD5D1CE4392A00A80CDA /* libleveldb_arm64.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 93D3AD591CE4392A00A80CDA /* libleveldb_arm64.a */; };
@@ -88,6 +89,7 @@
930DFCE11CEE46DE00738DB8 /* OAuth.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OAuth.swift; sourceTree = "<group>"; };
9351A4931CE46DB9009CC4F4 /* sbcore_amd64.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = sbcore_amd64.a; sourceTree = "<group>"; };
9374F6661D00FF68004ECE59 /* TestHelpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestHelpers.swift; sourceTree = "<group>"; };
+ 93B3C8381D41D7B5005B20C8 /* BridgeTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BridgeTests.swift; sourceTree = "<group>"; };
93C462781D29D7BD00394BAB /* Neighborhood.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Neighborhood.swift; sourceTree = "<group>"; };
93D3AD581CE4392A00A80CDA /* libleveldb_amd64.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libleveldb_amd64.a; sourceTree = "<group>"; };
93D3AD591CE4392A00A80CDA /* libleveldb_arm64.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libleveldb_arm64.a; sourceTree = "<group>"; };
@@ -171,8 +173,9 @@
30AD2E461CDD508D00A28A0C /* Tests */ = {
isa = PBXGroup;
children = (
- 30AD2E481CDD508D00A28A0C /* Info.plist */,
30A1F52D1CE68465008FC205 /* BasicDatabaseTests.swift */,
+ 93B3C8381D41D7B5005B20C8 /* BridgeTests.swift */,
+ 30AD2E481CDD508D00A28A0C /* Info.plist */,
9374F6661D00FF68004ECE59 /* TestHelpers.swift */,
);
path = Tests;
@@ -353,6 +356,7 @@
buildActionMask = 2147483647;
files = (
30A1F52E1CE68465008FC205 /* BasicDatabaseTests.swift in Sources */,
+ 93B3C8391D41D7B5005B20C8 /* BridgeTests.swift in Sources */,
9374F6681D00FFE5004ECE59 /* TestHelpers.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
diff --git a/SyncbaseCore/Tests/BridgeTests.swift b/SyncbaseCore/Tests/BridgeTests.swift
new file mode 100644
index 0000000..493c751
--- /dev/null
+++ b/SyncbaseCore/Tests/BridgeTests.swift
@@ -0,0 +1,24 @@
+// Copyright 2016 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+import Foundation
+@testable import SyncbaseCore
+import XCTest
+
+class IdentifierTest: XCTestCase {
+ func testEncodeDecodeEquality() {
+ do {
+ for id in [
+ Identifier(name: "cx_0EA0EA98AA9B4636AA058EA88C25DB2A", blessing: "root:o:app:user"),
+ Identifier(name: "_%/-,,hi", blessing: "root:o:app:user"),
+ Identifier(name: "", blessing: "root:o:app:user"),
+ Identifier(name: "something", blessing: "")] {
+ let mirror = try Identifier.decode(try id.encode().toString()!)
+ XCTAssertEqual(id, mirror)
+ }
+ } catch {
+ XCTFail("Unexpected error: \(error)")
+ }
+ }
+}
\ No newline at end of file