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 d54866a commit 5dd2f1e
Show file tree
Hide file tree
Showing 14 changed files with 134 additions and 58 deletions.
4 changes: 4 additions & 0 deletions Sources/Client/FHIRSearch.swift
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,11 @@ open class FHIRSearch
else {
let jsonres = response as! FHIRServerJSONResponse
do {
#if !NO_MODEL_IMPORT
let bundle = try Models.Bundle(json: jsonres.json ?? FHIRJSON())
#else
let bundle = try SwiftFHIR.Bundle(json: jsonres.json ?? FHIRJSON())
#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 @@ -276,14 +276,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 @@ -525,6 +525,7 @@
EE723FF21DC14AD300C398BA /* RelatedArtifact.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE723F6D1DC148C200C398BA /* RelatedArtifact.swift */; };
EE723FF31DC14AD300C398BA /* ServiceDefinition.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE723F6E1DC148C200C398BA /* ServiceDefinition.swift */; };
EE723FF41DC14AD300C398BA /* TestReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE723F6F1DC148C200C398BA /* TestReport.swift */; };
EE82503F1DD61DE20097A737 /* 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 */; };
EE9ABA2B1D803D8400BA8B54 /* Patient+SMART.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE9ABA2A1D803D8400BA8B54 /* Patient+SMART.swift */; };
Expand Down Expand Up @@ -971,12 +972,7 @@
isa = PBXGroup;
children = (
EE684C2C19A789BA00B5A2C0 /* Info.plist */,
EE684CCE19A7CEF000B5A2C0 /* ExtensionsTest.swift */,
EEE5DF361A5D862B002AFF53 /* FHIRSearchTests.swift */,
EE1F49D41C0D14F60095BF0F /* ReferenceTests.swift */,
EE01F9721C58FC51003AEA7E /* ResourceTests.swift */,
EE39069E1CD3E4F6008FECEA /* RequestTests.swift */,
EEA97F921DCA19C300C3F016 /* ValidationTests.swift */,
EE8250321DD61DBD0097A737 /* ClientTests */,
EEEB096E19AD248700C324FC /* ModelTests */,
EE1F49DE1C0D1BB40095BF0F /* TestResources */,
);
Expand Down Expand Up @@ -1152,6 +1148,19 @@
path = Sources/Models;
sourceTree = "<group>";
};
EE8250321DD61DBD0097A737 /* ClientTests */ = {
isa = PBXGroup;
children = (
EE684CCE19A7CEF000B5A2C0 /* ExtensionsTest.swift */,
EEE5DF361A5D862B002AFF53 /* FHIRSearchTests.swift */,
EE1F49D41C0D14F60095BF0F /* ReferenceTests.swift */,
EE01F9721C58FC51003AEA7E /* ResourceTests.swift */,
EE39069E1CD3E4F6008FECEA /* RequestTests.swift */,
EEA97F921DCA19C300C3F016 /* ValidationTests.swift */,
);
path = ClientTests;
sourceTree = "<group>";
};
EE9B31F61ACAD94800980AA9 /* Client */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2013,6 +2022,7 @@
EE02F7591ACF259B00179969 /* BundleTests.swift in Sources */,
EEA97F971DCA1C3C00C3F016 /* RequestGroupTests.swift in Sources */,
EE02F7731ACF259B00179969 /* CoverageTests.swift in Sources */,
EE82503F1DD61DE20097A737 /* ResourceTests.swift in Sources */,
EE1F49D61C0D14F60095BF0F /* ReferenceTests.swift in Sources */,
EE02F7BB1ACF259B00179969 /* MessageHeaderTests.swift in Sources */,
EE31DC521D64AC3600B04BEA /* ActivityDefinitionTests.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.
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class ValidationTests: XCTestCase {
XCTAssertNil(error)
}

let element3 = QuestionnaireItemOption(value: FHIRDate(string: "2016-03-30"))
let element3 = QuestionnaireItemOption(value: FHIRDate(string: "2016-03-30")!)
XCTAssertEqual(2016, element3.valueDate?.year)
do {
let js = try element3.asJSON()
Expand Down
2 changes: 1 addition & 1 deletion fhir-parser

0 comments on commit 5dd2f1e

Please sign in to comment.