Consistency and bug fixes in c-type conversations
Replaces remaining init? with init() throws to be consistent
across all type conversions. Also adds swift-to-go init for
v23_syncbase_Ids, and fixes v23_syncbase_Strings.toStrings().
Change-Id: I6294a4ae4df96ad4fd20214a096f0ba45667792f
diff --git a/SyncbaseCore/Source/Identifier.swift b/SyncbaseCore/Source/Identifier.swift
index ff0fad1..d34ea16 100644
--- a/SyncbaseCore/Source/Identifier.swift
+++ b/SyncbaseCore/Source/Identifier.swift
@@ -15,9 +15,7 @@
func encodeId() throws -> v23_syncbase_String {
var cStr = v23_syncbase_String()
- guard let id = v23_syncbase_Id(self) else {
- throw SyncbaseError.InvalidUTF8(invalidUtf8: "\(self)")
- }
+ let id = try v23_syncbase_Id(self)
v23_syncbase_EncodeId(id, &cStr)
return cStr
}
diff --git a/SyncbaseCore/Source/util/Types.swift b/SyncbaseCore/Source/util/Types.swift
index eea44c3..9196623 100644
--- a/SyncbaseCore/Source/util/Types.swift
+++ b/SyncbaseCore/Source/util/Types.swift
@@ -57,14 +57,9 @@
}
extension v23_syncbase_Id {
- init?(_ id: Identifier) {
- do {
- self.name = try id.name.toCgoString()
- self.blessing = try id.blessing.toCgoString()
- } catch (let e) {
- log.warning("Unable to UTF8-encode id: \(e)")
- return nil
- }
+ init(_ id: Identifier) throws {
+ self.name = try id.name.toCgoString()
+ self.blessing = try id.blessing.toCgoString()
}
func toIdentifier() -> Identifier? {
@@ -77,6 +72,28 @@
}
extension v23_syncbase_Ids {
+ init(_ ids: [Identifier]) throws {
+ let arrayBytes = ids.count * sizeof(v23_syncbase_Id)
+ let p = unsafeBitCast(malloc(arrayBytes), UnsafeMutablePointer<v23_syncbase_Id>.self)
+ if p == nil {
+ fatalError("Couldn't allocate \(arrayBytes) bytes")
+ }
+ for i in 0 ..< ids.count {
+ do {
+ p.advancedBy(i).memory = try v23_syncbase_Id(ids[i])
+ } catch (let e) {
+ for j in 0 ..< i {
+ free(p.advancedBy(j).memory.blessing.p)
+ free(p.advancedBy(j).memory.name.p)
+ }
+ free(p)
+ throw e
+ }
+ }
+ self.p = p
+ self.n = Int32(ids.count)
+ }
+
func toIdentifiers() -> [Identifier] {
var ids: [Identifier] = []
for i in 0 ..< n {
@@ -127,10 +144,10 @@
}
extension v23_syncbase_String {
- init?(_ string: String) {
+ init(_ string: String) throws {
// TODO: If possible, make one copy instead of two, e.g. using s.getCString.
guard let data = string.dataUsingEncoding(NSUTF8StringEncoding) else {
- return nil
+ throw SyncbaseError.InvalidUTF8(invalidUtf8: string)
}
let p = malloc(data.length)
if p == nil {
@@ -155,23 +172,22 @@
}
extension v23_syncbase_Strings {
- init?(_ strings: [String]) {
+ init(_ strings: [String]) throws {
let arrayBytes = strings.count * sizeof(v23_syncbase_String)
let p = unsafeBitCast(malloc(arrayBytes), UnsafeMutablePointer<v23_syncbase_String>.self)
if p == nil {
fatalError("Couldn't allocate \(arrayBytes) bytes")
}
- var i = 0
- for string in strings {
- guard let cStr = v23_syncbase_String(string) else {
+ for i in 0 ..< strings.count {
+ do {
+ p.advancedBy(i).memory = try v23_syncbase_String(strings[i])
+ } catch (let e) {
for j in 0 ..< i {
free(p.advancedBy(j).memory.p)
}
free(p)
- return nil
+ throw e
}
- p.advancedBy(i).memory = cStr
- i += 1
}
self.p = p
self.n = Int32(strings.count)
@@ -193,28 +209,26 @@
}
// Return value takes ownership of the memory associated with this object.
- func toString() -> String? {
+ func toStrings() -> [String] {
if p == nil {
- return nil
+ return []
}
- return String(bytesNoCopy: UnsafeMutablePointer<Void>(p),
- length: Int(n),
- encoding: NSUTF8StringEncoding,
- freeWhenDone: true)
+ var ret = [String]()
+ for i in 0 ..< n {
+ ret.append(p.advancedBy(Int(i)).memory.toString() ?? "")
+ }
+ return ret
}
}
extension String {
/// Create a Cgo-passable string struct forceably (will crash if the string cannot be created).
func toCgoString() throws -> v23_syncbase_String {
- guard let cStr = v23_syncbase_String(self) else {
- throw SyncbaseError.InvalidUTF8(invalidUtf8: self)
- }
- return cStr
+ return try v23_syncbase_String(self)
}
}
-// Note, we don't define init?(VError) since we never pass Swift VError objects to Go.
+// Note, we don't define init(VError) since we never pass Swift VError objects to Go.
extension v23_syncbase_VError {
// Return value takes ownership of the memory associated with this object.
func toVError() -> VError? {