Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Sources/DBus/BusName.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ internal extension DBusBusName {

static func validate(_ string: String) throws {

let error = DBusError.Reference()
let error = DBusError()
guard Bool(dbus_validate_bus_name(string, &error.internalValue))
else { throw DBusError(error)! }
else { throw error }
}
}

Expand Down
12 changes: 6 additions & 6 deletions Sources/DBus/Connection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ public final class DBusConnection {

self.shared = shared

let error = DBusError.Reference()
let error = DBusError()

if shared {

Expand All @@ -65,7 +65,7 @@ public final class DBusConnection {
}

// check for error
if let error = DBusError(error) {
if error.isSet {

throw error
}
Expand All @@ -80,7 +80,7 @@ public final class DBusConnection {

self.shared = shared

let error = DBusError.Reference()
let error = DBusError()

let internalBusType = CDBus.DBusBusType(rawValue: busType.rawValue)

Expand All @@ -94,7 +94,7 @@ public final class DBusConnection {
}

// check for error
if let error = DBusError(error) {
if error.isSet {

throw error
}
Expand Down Expand Up @@ -172,7 +172,7 @@ public final class DBusConnection {
var serialNumber: dbus_uint32_t = 0

guard Bool(dbus_connection_send(internalPointer, message.internalPointer, &serialNumber))
else { throw DBusError(name: .failed, message: "") }
else { throw try DBusError(name: DBusError.Name.failed, message: "") }

return serialNumber
}
Expand All @@ -190,7 +190,7 @@ public final class DBusConnection {
}

guard Bool(dbus_connection_send_with_reply(internalPointer, message.internalPointer, pendingCallDoublePointer, timeout.rawValue))
else { throw DBusError(name: .failed, message: "No memory") }
else { throw try DBusError(name: DBusError.Name.failed, message: "No memory") }

// if the connection is disconnected or you try to send Unix file descriptors on a connection that does not support them,
// the DBusPendingCall will be set to NULL
Expand Down
253 changes: 88 additions & 165 deletions Sources/DBus/Error.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,192 +9,115 @@
import Foundation
import CDBus

/// DBus type representing an exception.
public struct DBusError: Error, Equatable, Hashable {

/// Error name field
public let name: DBusError.Name

/// Error message field
public let message: String

internal init(name: DBusError.Name, message: String) {

self.name = name
self.message = message
}
// This error is for DBus (swift) runtime failures.
public enum RuntimeError: Error {
case generic(String)
}

// MARK: - Internal Reference

internal extension DBusError {

/// Internal class for working with the C DBus error API
internal final class Reference {

// MARK: - Internal Properties

internal var internalValue: CDBus.DBusError

// MARK: - Initialization

deinit {

dbus_error_free(&internalValue)
}

/// Creates New DBus Error instance.
init() {

var internalValue = CDBus.DBusError()
dbus_error_init(&internalValue)
self.internalValue = internalValue
}

// MARK: - Properties

/// Checks whether an error occurred (the error is set).
///
/// - Returns: `true` if the error is empty or `false` if the error is set.
var isEmpty: Bool {

return Bool(dbus_error_is_set(&internalValue)) == false
}

var name: String {

return String(cString: internalValue.name)
}

var message: String {

return String(cString: internalValue.message)
}

func hasName(_ name: String) -> Bool {

return Bool(dbus_error_has_name(&internalValue, name))
// Given a swift string, make a copy of the C string (const char *) and return a pointer to it.
// This will throw RuntimeError.generic if malloc() fails∫.
func swiftStringToConstCharStar(_ s: String) throws -> UnsafePointer<Int8> {
return try s.withCString { (unsafePointer: UnsafePointer<Int8>) -> UnsafePointer<Int8> in
// We need to copy the string to save a copy. unsafePointer is only valid in this closure
// UnsafeMutableRawPointer
let bufferLen = strlen(unsafePointer) + 1
guard let unsafeMutableRawPointer = malloc(bufferLen) else {
throw RuntimeError.generic("malloc() failed")
}
memcpy(unsafeMutableRawPointer, unsafePointer, bufferLen)
// UnsafeMutablePointer<Int8>
let unsafeMutablePointer = unsafeMutableRawPointer.assumingMemoryBound(to: Int8.self)
// UnsafePointer<Int8>
return UnsafePointer(unsafeMutablePointer)
}
}

internal extension DBusError {

init?(_ reference: DBusError.Reference) {

guard reference.isEmpty == false
else { return nil }

guard let name = DBusError.Name(rawValue: reference.name)
else { fatalError("Invalid error \(reference.name)") }

self.init(name: name,
message: reference.message)
// This is a wrapper of the libdbus DBusError type.
public class DBusError: Error, Equatable, CustomStringConvertible {
internal var internalValue = CDBus.DBusError()

init() {
dbus_error_init(&internalValue);
}
}

// MARK: CustomNSError
// This will throw RuntimeError.generic if the name passed in is not a valid DBus error name,
// or if malloc() fails when we are copying the strings to live in C land.
convenience init(name: String, message: String = "") throws {
self.init()

extension DBusError: CustomNSError {

public enum UserInfoKey: String {

/// DBus error name
case name
let validationError = DBusError()
let isValid = dbus_validate_error_name(name, &validationError.internalValue)
if isValid == false {
throw RuntimeError.generic("\(name) is not a valid DBus Error name.")
}

let cName = try swiftStringToConstCharStar(name)
let cMessage = try swiftStringToConstCharStar(message)
dbus_set_error_const(&internalValue, cName, cMessage)
}

/// The domain of the error.
public static let errorDomain = "org.freedesktop.DBus.Error"

/// The error code within the given domain.
public var errorCode: Int {

return hashValue

deinit {
dbus_error_free(&internalValue)
}

/// The user-info dictionary.
public var errorUserInfo: [String: Any] {

return [
UserInfoKey.name.rawValue: self.name.rawValue,
NSLocalizedDescriptionKey: self.message
]

public var isSet: Bool {
let dbusBool = dbus_error_is_set(&internalValue)
return Bool(dbusBool)
}
}

// MARK: Error Name
public var name: String {
return String(cString: internalValue.name)
}

public extension DBusError {

public struct Name: Equatable, Hashable {

public let rawValue: String

public init?(rawValue: String) {

// validate from C, no parsing
do { try DBusInterface.validate(rawValue) }
catch { return nil }

self.rawValue = rawValue
}
public var message: String {
return String(cString: internalValue.message)
}
}

public extension DBusError.Name {

public init(_ interface: DBusInterface) {

// should be valid
self.rawValue = interface.rawValue
public static func == (lhs: DBusError, rhs: DBusError) -> Bool {
let lhsName = String(cString: lhs.internalValue.name)
let rhsName = String(cString: rhs.internalValue.name)
let lhsMessage = String(cString: lhs.internalValue.message)
let rhsMessage = String(cString: rhs.internalValue.message)
return (lhsName == rhsName &&
lhsMessage == rhsMessage)
}
}

public extension DBusInterface {

init(_ error: DBusError.Name) {

self.init(rawValue: error.rawValue)!
public var description: String {
return "DBusError(name: '\(name)', message: '\(message)') "
}
}

public extension DBusError.Name {

/// A generic error; "something went wrong" - see the error message for more.
///
/// `org.freedesktop.DBus.Error.Failed`
public static let failed = DBusError.Name(rawValue: DBUS_ERROR_FAILED)!

/// No Memory
///
/// `org.freedesktop.DBus.Error.NoMemory`
public static let noMemory = DBusError.Name(rawValue: DBUS_ERROR_NO_MEMORY)!

/// Existing file and the operation you're using does not silently overwrite.
///
/// `org.freedesktop.DBus.Error.FileExists`
public static let fileExists = DBusError.Name(rawValue: DBUS_ERROR_FILE_EXISTS)!

/// Missing file.
///
/// `org.freedesktop.DBus.Error.FileNotFound`
public static let fileNotFound = DBusError.Name(rawValue: DBUS_ERROR_FILE_NOT_FOUND)!

/// Invalid arguments
///
/// `org.freedesktop.DBus.Error.InvalidArgs`
public static let invalidArguments = DBusError.Name(rawValue: DBUS_ERROR_INVALID_ARGS)!

/// Invalid signature
///
/// `org.freedesktop.DBus.Error.InvalidSignature`
public static let invalidSignature = DBusError.Name(rawValue: DBUS_ERROR_INVALID_SIGNATURE)!
}
public extension DBusError {

extension DBusError.Name: CustomStringConvertible {

public var description: String {

return rawValue
public struct Name {
/// A generic error; "something went wrong" - see the error message for more.
///
/// `org.freedesktop.DBus.Error.Failed`
public static let failed = String(DBUS_ERROR_FAILED)

/// No Memory
///
/// `org.freedesktop.DBus.Error.NoMemory`
public static let noMemory = String(DBUS_ERROR_NO_MEMORY)

/// Existing file and the operation you're using does not silently overwrite.
///
/// `org.freedesktop.DBus.Error.FileExists`
public static let fileExists = String(DBUS_ERROR_FILE_EXISTS)

/// Missing file.
///
/// `org.freedesktop.DBus.Error.FileNotFound`
public static let fileNotFound = String(DBUS_ERROR_FILE_NOT_FOUND)

/// Invalid arguments
///
/// `org.freedesktop.DBus.Error.InvalidArgs`
public static let invalidArguments = String(DBUS_ERROR_INVALID_ARGS)

/// Invalid signature
///
/// `org.freedesktop.DBus.Error.InvalidSignature`
public static let invalidSignature = String(DBUS_ERROR_INVALID_SIGNATURE)
}
}
4 changes: 2 additions & 2 deletions Sources/DBus/Interface.swift
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,9 @@ internal extension DBusInterface {

static func validate(_ string: String) throws {

let error = DBusError.Reference()
let error = DBusError()
guard Bool(dbus_validate_interface(string, &error.internalValue))
else { throw DBusError(error)! }
else { throw error }
}
}

Expand Down
4 changes: 2 additions & 2 deletions Sources/DBus/Member.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ internal extension DBusMember {

static func validate(_ string: String) throws {

let error = DBusError.Reference()
let error = DBusError()
guard Bool(dbus_validate_member(string, &error.internalValue))
else { throw DBusError(error)! }
else { throw error }
}
}

Expand Down
Loading