Skip to content

Commit

Permalink
Make compile on Linux
Browse files Browse the repository at this point in the history
Fixes #2
  • Loading branch information
p2 committed Nov 11, 2016
1 parent 48d3e4a commit fae5a34
Show file tree
Hide file tree
Showing 13 changed files with 134 additions and 58 deletions.
6 changes: 5 additions & 1 deletion Sources/Client/FHIRSearch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,11 @@ open class FHIRSearch
}
else {
let jsonres = response as! FHIRServerJSONResponse
let bundle = Bundle(json: jsonres.json)
#if !NO_MODEL_IMPORT
let bundle = Models.Bundle(json: jsonres.json)
#else
let bundle = SwiftFHIR.Bundle(json: jsonres.json)
#endif
bundle._server = server
if let entries = bundle.entry {
for entry in entries {
Expand Down
19 changes: 12 additions & 7 deletions Sources/Client/FHIRServerDataResponse.swift
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ open class FHIRServerDataResponse: FHIRServerResponse {
}

// was there an error?
if let error = error as? NSError, NSURLErrorDomain == error.domain {
if let error = error, NSURLErrorDomain == error._domain {
self.error = FHIRError.requestError(status, error.humanized)
}
else if let error = error as? FHIRError {
Expand All @@ -150,8 +150,8 @@ open class FHIRServerDataResponse: FHIRServerResponse {
public required init(error: Error) {
self.status = 0
self.headers = [String: String]()
if NSURLErrorDomain == (error as NSError).domain {
self.error = FHIRError.requestError(status, (error as NSError).humanized)
if NSURLErrorDomain == error._domain {
self.error = FHIRError.requestError(status, error.humanized)
}
else if let error = error as? FHIRError {
self.error = error
Expand Down Expand Up @@ -278,14 +278,19 @@ open class FHIRServerJSONResponse: FHIRServerDataResponse {

// MARK: -

extension NSError {
extension Error {

/**
Return a human-readable, localized string for error codes of the NSURLErrorDomain (!!).
Return a human-readable, localized string for error codes of the NSURLErrorDomain. Will simply return `localizedDescription` for if the
receiver is not of that domain.

The list of errors that are "humanized" is not necessarily exhaustive. All strings are returned `fhir_localized`.
*/
public var humanized: String {
assert(NSURLErrorDomain == domain, "Can only use this function with errors in the NSURLErrorDomain")
switch code {
guard NSURLErrorDomain == _domain else {
return localizedDescription
}
switch _code {
case NSURLErrorBadURL: return "The URL was malformed".fhir_localized
case NSURLErrorTimedOut: return "The connection timed out".fhir_localized
case NSURLErrorUnsupportedURL: return "The URL scheme is not supported".fhir_localized
Expand Down
4 changes: 2 additions & 2 deletions Sources/Client/Resource+REST.swift
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,8 @@ public extension Resource {
catch let error {
fhir_warn("Error applying response headers after `read` call: \(error)")
}
if nil == resource.id {
resource.id = (path as NSString).lastPathComponent
if nil == resource.id, let lpc = URL(string: path) {
resource.id = lpc.lastPathComponent
}
callback(resource, nil)
}
Expand Down
127 changes: 89 additions & 38 deletions Sources/Models/DateAndTime.swift
Original file line number Diff line number Diff line change
Expand Up @@ -258,12 +258,22 @@ public struct FHIRTime: DateAndTime {
return DateNSDateConverter.sharedConverter.create(fromTime: self)
}

// TODO: this implementation uses a workaround using string coercion instead of format: "%02d:%02d:%@" because %@ with String is not
// supported on Linux (SR-957)
public var description: String {
if let secStr = tookSecondsFromString {
#if os(Linux)
return String(format: "%02d:%02d:", hour, minute) + secStr
#else
return String(format: "%02d:%02d:%@", hour, minute, secStr)
#endif
}
if let s = second {
#if os(Linux)
return String(format: "%02d:%02d:", hour, minute) + ((s < 10) ? "0" : "") + String(format: "%g", s)
#else
return String(format: "%02d:%02d:%@%g", hour, minute, (s < 10) ? "0" : "", s)
#endif
}
return String(format: "%02d:%02d", hour, minute)
}
Expand Down Expand Up @@ -381,7 +391,7 @@ public struct DateTime: DateAndTime {
public var description: String {
if let tm = time {
if let tz = timeZoneString ?? timeZone?.offset() {
return String(format: "%@T%@%@", date.description, tm.description, tz)
return "\(date.description)T\(tm.description)\(tz)"
}
}
return date.description
Expand Down Expand Up @@ -493,7 +503,7 @@ public struct Instant: DateAndTime {

public var description: String {
let tz = timeZoneString ?? timeZone.offset()
return String(format: "%@T%@%@", date.description, time.description, tz)
return "\(date.description)T\(time.description)\(tz)"
}

public static func <(lhs: Instant, rhs: Instant) -> Bool {
Expand Down Expand Up @@ -579,7 +589,7 @@ class DateNSDateConverter {
let comp = calendar.dateComponents(flags, from: inDate)

let date = FHIRDate(year: comp.year!, month: UInt8(comp.month!), day: UInt8(comp.day!))
let zone = (comp as NSDateComponents).timeZone ?? utc
let zone = comp.timeZone ?? utc
let secs = Double(comp.second!) + (Double(comp.nanosecond!) / 1000000000)
let time = FHIRTime(hour: UInt8(comp.hour!), minute: UInt8(comp.minute!), second: secs)

Expand Down Expand Up @@ -658,73 +668,65 @@ class DateAndTimeParser {

// scan date (must have at least the year)
if !isTimeOnly {
var year = 0
if scanner.scanInt(&year) && year < 10000 { // dates above 9999 are considered special cases
var month = 0
if scanner.scanString("-", into: nil) && scanner.scanInt(&month) && month <= 12 {
var day = 0
if scanner.scanString("-", into: nil) && scanner.scanInt(&day) && day <= 31 {
date = FHIRDate(year: year, month: UInt8(month), day: UInt8(day))
if let year = scanner.fhir_scanInt(), year < 10000 { // dates above 9999 are considered special cases
if nil != scanner.fhir_scanString("-"), let month = scanner.fhir_scanInt(), month <= 12 {
if nil != scanner.fhir_scanString("-"), let day = scanner.fhir_scanInt(), day <= 31 {
date = FHIRDate(year: Int(year), month: UInt8(month), day: UInt8(day))
}
else {
date = FHIRDate(year: year, month: UInt8(month), day: nil)
date = FHIRDate(year: Int(year), month: UInt8(month), day: nil)
}
}
else {
date = FHIRDate(year: year, month: nil, day: nil)
date = FHIRDate(year: Int(year), month: nil, day: nil)
}
}
}

// scan time
if isTimeOnly || scanner.scanString("T", into: nil) {
var hour = 0
var minute = 0
if scanner.scanInt(&hour) && hour >= 0 && hour < 24 && scanner.scanString(":", into: nil)
&& scanner.scanInt(&minute) && minute >= 0 && minute < 60 {
if isTimeOnly || nil != scanner.fhir_scanString("T") {
if let hour = scanner.fhir_scanInt(), hour >= 0 && hour < 24 && nil != scanner.fhir_scanString(":"),
let minute = scanner.fhir_scanInt(), minute >= 0 && minute < 60 {

let digitSet = CharacterSet.decimalDigits
var decimalSet = NSMutableCharacterSet.decimalDigits
decimalSet.insert(".")

var secStr: NSString?
if scanner.scanString(":", into: nil) && scanner.scanCharacters(from: decimalSet as CharacterSet, into: &secStr), let secStr = secStr as? String, let second = Double(secStr), second < 60.0 {
if nil != scanner.fhir_scanString(":"), let secStr = scanner.fhir_scanCharacters(from: decimalSet as CharacterSet), let second = Double(secStr), second < 60.0 {
time = FHIRTime(hour: UInt8(hour), minute: UInt8(minute), second: second, secondsFromString: secStr)
}
else {
time = FHIRTime(hour: UInt8(hour), minute: UInt8(minute), second: nil)
}

// scan zone
if !scanner.isAtEnd {
var negStr: NSString?
if scanner.scanString("Z", into: nil) {
if !scanner.fhir_isAtEnd {
if nil != scanner.fhir_scanString("Z") {
tz = TimeZone(abbreviation: "UTC")
tzString = "Z"
}
else if scanner.scanString("-", into: &negStr) || scanner.scanString("+", into: nil) {
tzString = (nil == negStr) ? "+" : "-"
var hourStr: NSString?
if scanner.scanCharacters(from: digitSet, into: &hourStr) {
tzString! += hourStr! as String
else if var tzStr = (scanner.fhir_scanString("-") ?? scanner.fhir_scanString("+")) {
if let hourStr = scanner.fhir_scanCharacters(from: digitSet) {
tzStr += hourStr
var tzhour = 0
var tzmin = 0
if 2 == hourStr?.length {
tzhour = hourStr!.integerValue
if scanner.scanString(":", into: nil) && scanner.scanInt(&tzmin) {
tzString! += (tzmin < 10) ? ":0\(tzmin)" : ":\(tzmin)"
if tzmin >= 60 {
tzmin = 0
if 2 == hourStr.characters.count {
tzhour = Int(hourStr) ?? 0
if nil != scanner.fhir_scanString(":"), let tzm = scanner.fhir_scanInt() {
tzStr += (tzm < 10) ? ":0\(tzm)" : ":\(tzm)"
if tzm < 60 {
tzmin = tzm
}
}
}
else if 4 == hourStr?.length {
tzhour = Int(hourStr!.substring(to: 2))!
tzmin = Int(hourStr!.substring(from: 2))!
else if 4 == hourStr.characters.count {
tzhour = Int(hourStr.substring(to: hourStr.index(hourStr.startIndex, offsetBy: 2)))!
tzmin = Int(hourStr.substring(from: hourStr.index(hourStr.startIndex, offsetBy: 2)))!
}

let offset = tzhour * 3600 + tzmin * 60
tz = TimeZone(secondsFromGMT: nil == negStr ? offset : -1 * offset)
tz = TimeZone(secondsFromGMT: "+" == tzStr ? offset : -1 * offset)
tzString = tzStr
}
}
}
Expand Down Expand Up @@ -786,7 +788,56 @@ extension TimeZone {
let hr = abs((secsFromGMT / 3600) - (secsFromGMT % 3600))
let min = abs((secsFromGMT % 3600) / 60)

return String(format: "%@%02d:%02d", secsFromGMT >= 0 ? "+" : "-", hr, min)
return (secsFromGMT >= 0 ? "+" : "-") + String(format: "%02d:%02d", hr, min)
}
}


/**
Extend Scanner to account for interface differences between macOS and Linux (as of November 2016)
*/
extension Scanner {

public var fhir_isAtEnd: Bool {
#if os(Linux)
return atEnd
#else
return isAtEnd
#endif
}

public func fhir_scanString(_ searchString: String) -> String? {
#if os(Linux)
return scanString(string: searchString)
#else
var str: NSString?
if scanString(searchString, into: &str) {
return str as? String
}
return nil
#endif
}

public func fhir_scanCharacters(from set: CharacterSet) -> String? {
#if os(Linux)
return scanCharactersFromSet(set)
#else
var str: NSString?
if scanCharacters(from: set, into: &str) {
return str as? String
}
return nil
#endif
}

public func fhir_scanInt() -> Int? {
var int = 0
#if os(Linux)
let flag = scanInteger(&int)
#else
let flag = scanInt(&int)
#endif
return flag ? int : nil
}
}

10 changes: 8 additions & 2 deletions Sources/Models/FHIRTypes.swift
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,15 @@ public struct Base64Binary: ExpressibleByStringLiteral, CustomStringConvertible,
extension String {
/**
Convenience getter using `NSLocalizedString()` with no comment.

TODO: On Linux this currently simply returns self
*/
public var fhir_localized: String {
#if os(Linux)
return self
#else
return NSLocalizedString(self, comment: "")
#endif
}
}

Expand All @@ -82,14 +88,14 @@ Execute a `print()`, prepending filename, line and function/method name, if `DEB
*/
public func fhir_logIfDebug(_ message: @autoclosure () -> String, function: String = #function, file: String = #file, line: Int = #line) {
#if DEBUG
print("SwiftFHIR [\((file as NSString).lastPathComponent):\(line)] \(function) \(message())")
print("SwiftFHIR [\(URL(fileURLWithPath: file).lastPathComponent):\(line)] \(function) \(message())")
#endif
}

/**
Execute a `print()`, prepending filename, line and function/method name and "WARNING" prepended.
*/
public func fhir_warn(_ message: @autoclosure () -> String, function: String = #function, file: String = #file, line: Int = #line) {
print("SwiftFHIR [\((file as NSString).lastPathComponent):\(line)] \(function) WARNING: \(message())")
print("SwiftFHIR [\(URL(fileURLWithPath: file).lastPathComponent):\(line)] \(function) WARNING: \(message())")
}

2 changes: 1 addition & 1 deletion Sources/Models/JSON-extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ extension NSDecimalNumber {
*/
public convenience init(json: NSNumber) {
if let _ = json.stringValue.characters.index(of: ".") {
self.init(string: NSString(format: "%.15g", json.doubleValue) as String)
self.init(string: String(format: "%.15g", json.doubleValue))
}
else {
self.init(string: "\(json)")
Expand Down
22 changes: 16 additions & 6 deletions SwiftFHIR.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@
EE545F3B1A66805600E17B0C /* SwiftFHIR.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE684C1E19A789BA00B5A2C0 /* SwiftFHIR.framework */; };
EE684CCF19A7CEF000B5A2C0 /* ExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE684CCE19A7CEF000B5A2C0 /* ExtensionsTest.swift */; };
EE6DA8631A5D4B3A00E00708 /* SwiftFHIR.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EE6DA8571A5D4B1000E00708 /* SwiftFHIR.framework */; };
EE8250411DD631610097A737 /* ResourceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE01F9721C58FC51003AEA7E /* ResourceTests.swift */; };
EE8901231B7E07D700F1EDBF /* Element+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE8901221B7E07D700F1EDBF /* Element+Extensions.swift */; };
EE8901241B7E07D700F1EDBF /* Element+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE8901221B7E07D700F1EDBF /* Element+Extensions.swift */; };
EE9B31F41ACAD93400980AA9 /* Resource+REST.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE9B31F31ACAD93400980AA9 /* Resource+REST.swift */; };
Expand Down Expand Up @@ -839,13 +840,9 @@
isa = PBXGroup;
children = (
EE684C2C19A789BA00B5A2C0 /* Info.plist */,
EE684CCE19A7CEF000B5A2C0 /* ExtensionsTest.swift */,
EEE5DF361A5D862B002AFF53 /* FHIRSearchTests.swift */,
EE1F49D41C0D14F60095BF0F /* ReferenceTests.swift */,
EE01F9721C58FC51003AEA7E /* ResourceTests.swift */,
EE39069E1CD3E4F6008FECEA /* RequestTests.swift */,
EE1F49DE1C0D1BB40095BF0F /* TestResources */,
EE8250401DD62E0B0097A737 /* ClientTests */,
EEEB096E19AD248700C324FC /* ModelTests */,
EE1F49DE1C0D1BB40095BF0F /* TestResources */,
EEEE31191BB278E3008866E2 /* AppKit.framework */,
);
path = Tests;
Expand Down Expand Up @@ -991,6 +988,18 @@
path = Sources/Models;
sourceTree = "<group>";
};
EE8250401DD62E0B0097A737 /* ClientTests */ = {
isa = PBXGroup;
children = (
EE684CCE19A7CEF000B5A2C0 /* ExtensionsTest.swift */,
EEE5DF361A5D862B002AFF53 /* FHIRSearchTests.swift */,
EE1F49D41C0D14F60095BF0F /* ReferenceTests.swift */,
EE01F9721C58FC51003AEA7E /* ResourceTests.swift */,
EE39069E1CD3E4F6008FECEA /* RequestTests.swift */,
);
path = ClientTests;
sourceTree = "<group>";
};
EE9B31F61ACAD94800980AA9 /* Client */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -1734,6 +1743,7 @@
EE02F7E91ACF259B00179969 /* RiskAssessmentTests.swift in Sources */,
EE02F7D51ACF259B00179969 /* PractitionerTests.swift in Sources */,
EE02F7EB1ACF259B00179969 /* ScheduleTests.swift in Sources */,
EE8250411DD631610097A737 /* ResourceTests.swift in Sources */,
EE02F7991ACF259B00179969 /* FamilyMemberHistoryTests.swift in Sources */,
EE02F7AB1ACF259B00179969 /* ImmunizationTests.swift in Sources */,
EE02F76F1ACF259B00179969 /* ContractTests.swift in Sources */,
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion fhir-parser

0 comments on commit fae5a34

Please sign in to comment.