Skip to content

Commit 21cee4a

Browse files
committed
Enable String, URL and XML-related types for WASI
fix
1 parent e2219b9 commit 21cee4a

File tree

5 files changed

+83
-3
lines changed

5 files changed

+83
-3
lines changed

Sources/Foundation/NSString.swift

+4
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ func NSLocalizedString(_ key: String,
2525
bundle: Bundle = Bundle.main,
2626
value: String = "",
2727
comment: String) -> String {
28+
#if os(WASI)
29+
return key
30+
#else
2831
return bundle.localizedString(forKey: key, value: value, table: tableName)
32+
#endif
2933
}
3034

3135
internal let kCFStringEncodingMacRoman = CFStringBuiltInEncodings.macRoman.rawValue

Sources/Foundation/NSSwiftRuntime.swift

+9-1
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,15 @@
1616
@_exported import Darwin
1717
#elseif os(Linux) || os(Android) || CYGWIN || os(OpenBSD)
1818
@_exported import Glibc
19+
#elseif os(WASI)
20+
@_exported import WASILibc
1921
#elseif os(Windows)
2022
@_exported import CRT
2123
#endif
2224

25+
#if !os(WASI)
2326
@_exported import Dispatch
27+
#endif
2428

2529
#if os(Windows)
2630
import WinSDK
@@ -257,8 +261,10 @@ internal func __CFInitializeSwift() {
257261
__CFSwiftBridge.NSMutableString.appendString = _CFSwiftStringAppend
258262
__CFSwiftBridge.NSMutableString.appendCharacters = _CFSwiftStringAppendCharacters
259263
__CFSwiftBridge.NSMutableString._cfAppendCString = _CFSwiftStringAppendCString
260-
264+
265+
#if !os(WASI)
261266
__CFSwiftBridge.NSRunLoop._new = _NSRunLoopNew
267+
#endif
262268

263269
__CFSwiftBridge.NSCharacterSet._expandedCFCharacterSet = _CFSwiftCharacterSetExpandedCFCharacterSet
264270
__CFSwiftBridge.NSCharacterSet._retainedBitmapRepresentation = _CFSwiftCharacterSetRetainedBitmapRepresentation
@@ -304,6 +310,7 @@ internal func __CFInitializeSwift() {
304310

305311
// __CFDefaultEightBitStringEncoding = UInt32(kCFStringEncodingUTF8)
306312

313+
#if !os(WASI)
307314
__CFSwiftBridge.NSURL.copyResourcePropertyForKey = _CFSwiftURLCopyResourcePropertyForKey
308315
__CFSwiftBridge.NSURL.copyResourcePropertiesForKeys = _CFSwiftURLCopyResourcePropertiesForKeys
309316
__CFSwiftBridge.NSURL.setResourcePropertyForKey = _CFSwiftURLSetResourcePropertyForKey
@@ -312,6 +319,7 @@ internal func __CFInitializeSwift() {
312319
__CFSwiftBridge.NSURL.clearResourcePropertyCache = _CFSwiftURLClearResourcePropertyCache
313320
__CFSwiftBridge.NSURL.setTemporaryResourceValueForKey = _CFSwiftSetTemporaryResourceValueForKey
314321
__CFSwiftBridge.NSURL.resourceIsReachable = _CFSwiftURLResourceIsReachable
322+
#endif
315323
}
316324

317325
public func === (lhs: AnyClass, rhs: AnyClass) -> Bool {

Sources/Foundation/NSURL.swift

+25-1
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
153153
open func copy(with zone: NSZone? = nil) -> Any {
154154
if isFileURL {
155155
let newURL = CFURLCreateWithString(kCFAllocatorSystemDefault, relativeString._cfObject, self.baseURL?._cfObject)!
156+
156157
if let storage = _resourceStorageIfPresent {
157158
let newStorage = URLResourceValuesStorage(copying: storage)
158159
_CFURLSetResourceInfo(newURL, newStorage)
@@ -206,6 +207,7 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
206207
if validPathSeps.contains(where: { thePath.hasSuffix(String($0)) }) {
207208
isDir = true
208209
} else {
210+
#if !os(WASI)
209211
let absolutePath: String
210212
if let absPath = baseURL?.appendingPathComponent(path).path {
211213
absolutePath = absPath
@@ -214,6 +216,7 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
214216
}
215217

216218
let _ = FileManager.default.fileExists(atPath: absolutePath, isDirectory: &isDir)
219+
#endif
217220
}
218221

219222
self.init(fileURLWithPath: thePath, isDirectory: isDir.boolValue, relativeTo: baseURL)
@@ -230,9 +233,11 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
230233
if validPathSeps.contains(where: { thePath.hasSuffix(String($0)) }) {
231234
isDir = true
232235
} else {
236+
#if !os(WASI)
233237
if !FileManager.default.fileExists(atPath: path, isDirectory: &isDir) {
234238
isDir = false
235239
}
240+
#endif
236241
}
237242
super.init()
238243
_CFURLInitWithFileSystemPathRelativeToBase(_cfObject, thePath._cfObject, kCFURLPlatformPathStyle, isDir.boolValue, nil)
@@ -542,6 +547,9 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
542547
// TODO: should be `checkResourceIsReachableAndReturnError` with autoreleased error parameter.
543548
// Currently Autoreleased pointers is not supported on Linux.
544549
open func checkResourceIsReachable() throws -> Bool {
550+
#if os(WASI)
551+
return false
552+
#else
545553
guard isFileURL,
546554
let path = path else {
547555
throw NSError(domain: NSCocoaErrorDomain,
@@ -557,6 +565,7 @@ open class NSURL : NSObject, NSSecureCoding, NSCopying {
557565
}
558566

559567
return true
568+
#endif
560569
}
561570

562571
/* Returns a file path URL that refers to the same resource as a specified URL. File path URLs use a file system style path. An error will occur if the url parameter is not a file URL. A file reference URL's resource must exist and be reachable to be converted to a file path URL. Symbol is present in iOS 4, but performs no operation.
@@ -841,6 +850,9 @@ extension NSURL {
841850

842851
open func appendingPathComponent(_ pathComponent: String) -> URL? {
843852
var result : URL? = appendingPathComponent(pathComponent, isDirectory: false)
853+
854+
// File URLs can't be handled on WASI without file system access
855+
#if !os(WASI)
844856
// Since we are appending to a URL, path seperators should
845857
// always be '/', even if we're on Windows
846858
if !pathComponent.hasSuffix("/") && isFileURL {
@@ -852,6 +864,7 @@ extension NSURL {
852864
}
853865

854866
}
867+
#endif
855868
return result
856869
}
857870

@@ -878,7 +891,7 @@ extension NSURL {
878891
// In remaining cases it works just like URLByResolvingSymlinksInPath.
879892
return _resolveSymlinksInPath(excludeSystemDirs: true, preserveDirectoryFlag: true)
880893
}
881-
894+
882895
open var resolvingSymlinksInPath: URL? {
883896
return _resolveSymlinksInPath(excludeSystemDirs: true)
884897
}
@@ -896,8 +909,12 @@ extension NSURL {
896909
if selfPath.isAbsolutePath {
897910
absolutePath = selfPath
898911
} else {
912+
#if os(WASI)
913+
return nil
914+
#else
899915
let workingDir = FileManager.default.currentDirectoryPath
900916
absolutePath = workingDir._bridgeToObjectiveC().appendingPathComponent(selfPath)
917+
#endif
901918
}
902919

903920

@@ -918,15 +935,20 @@ extension NSURL {
918935

919936
default:
920937
resolvedPath = resolvedPath._bridgeToObjectiveC().appendingPathComponent(component)
938+
#if !os(WASI)
921939
if let destination = FileManager.default._tryToResolveTrailingSymlinkInPath(resolvedPath) {
922940
resolvedPath = destination
923941
}
942+
#endif
924943
}
925944
}
926945

927946
// It might be a responsibility of NSURL(fileURLWithPath:). Check it.
928947
var isExistingDirectory: ObjCBool = false
948+
949+
#if !os(WASI)
929950
let _ = FileManager.default.fileExists(atPath: resolvedPath, isDirectory: &isExistingDirectory)
951+
#endif
930952

931953
if excludeSystemDirs {
932954
resolvedPath = resolvedPath._tryToRemovePathPrefix("/private") ?? resolvedPath
@@ -1005,6 +1027,7 @@ extension NSURL : _StructTypeBridgeable {
10051027

10061028
// -----
10071029

1030+
#if !os(WASI)
10081031
internal func _CFSwiftURLCopyResourcePropertyForKey(_ url: CFTypeRef, _ key: CFString, _ valuePointer: UnsafeMutablePointer<Unmanaged<CFTypeRef>?>?, _ errorPointer: UnsafeMutablePointer<Unmanaged<CFError>?>?) -> _DarwinCompatibleBoolean {
10091032
do {
10101033
let key = URLResourceKey(rawValue: key._swiftObject)
@@ -1538,6 +1561,7 @@ fileprivate extension URLResourceValuesStorage {
15381561
}
15391562
}
15401563
}
1564+
#endif
15411565

15421566
// -----
15431567

Sources/Foundation/PropertyListSerialization.swift

+2
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ open class PropertyListSerialization : NSObject {
7474
}
7575
}
7676

77+
#if !os(WASI)
7778
internal class func propertyList(with stream: CFReadStream, options opt: ReadOptions, format: UnsafeMutablePointer <PropertyListFormat>?) throws -> Any {
7879
var fmt = kCFPropertyListBinaryFormat_v1_0
7980
var error: Unmanaged<CFError>? = nil
@@ -93,4 +94,5 @@ open class PropertyListSerialization : NSObject {
9394
open class func propertyList(with stream: InputStream, options opt: ReadOptions = [], format: UnsafeMutablePointer<PropertyListFormat>?) throws -> Any {
9495
return try propertyList(with: stream._stream, options: opt, format: format)
9596
}
97+
#endif
9698
}

Sources/FoundationXML/XMLParser.swift

+43-1
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,9 @@ internal func _structuredErrorFunc(_ interface: _CFXMLInterface, error: _CFXMLIn
396396

397397
open class XMLParser : NSObject {
398398
private var _handler: _CFXMLInterfaceSAXHandler
399+
#if !os(WASI)
399400
internal var _stream: InputStream?
401+
#endif
400402
internal var _data: Data?
401403

402404
internal var _chunkSize = Int(4096 * 32) // a suitably large number for a decent chunk size
@@ -410,6 +412,9 @@ open class XMLParser : NSObject {
410412

411413
// initializes the parser with the specified URL.
412414
public convenience init?(contentsOf url: URL) {
415+
#if os(WASI)
416+
return nil
417+
#else
413418
setupXMLParsing()
414419
if url.isFileURL {
415420
if let stream = InputStream(url: url) {
@@ -427,6 +432,7 @@ open class XMLParser : NSObject {
427432
return nil
428433
}
429434
}
435+
#endif
430436
}
431437

432438
// create the parser from data
@@ -442,13 +448,15 @@ open class XMLParser : NSObject {
442448
_CFXMLInterfaceDestroyContext(_parserContext)
443449
}
444450

451+
#if !os(WASI)
445452
//create a parser that incrementally pulls data from the specified stream and parses it.
446453
public init(stream: InputStream) {
447454
setupXMLParsing()
448455
_stream = stream
449456
_handler = _CFXMLInterfaceCreateSAXHandler()
450457
_parserContext = nil
451458
}
459+
#endif
452460

453461
open weak var delegate: XMLParserDelegate?
454462

@@ -460,20 +468,32 @@ open class XMLParser : NSObject {
460468

461469
open var allowedExternalEntityURLs: Set<URL>?
462470

471+
#if os(WASI)
472+
private static var _currentParser: XMLParser?
473+
#endif
474+
463475
internal static func currentParser() -> XMLParser? {
476+
#if os(WASI)
477+
return _currentParser
478+
#else
464479
if let current = Thread.current.threadDictionary["__CurrentNSXMLParser"] {
465480
return current as? XMLParser
466481
} else {
467482
return nil
468483
}
484+
#endif
469485
}
470486

471487
internal static func setCurrentParser(_ parser: XMLParser?) {
488+
#if os(WASI)
489+
_currentParser = parser
490+
#else
472491
if let p = parser {
473492
Thread.current.threadDictionary["__CurrentNSXMLParser"] = p
474493
} else {
475494
Thread.current.threadDictionary.removeObject(forKey: "__CurrentNSXMLParser")
476495
}
496+
#endif
477497
}
478498

479499
internal func _handleParseResult(_ parseResult: Int32) -> Bool {
@@ -547,6 +567,7 @@ open class XMLParser : NSObject {
547567
return result
548568
}
549569

570+
#if !os(WASI)
550571
internal func parseFrom(_ stream : InputStream) -> Bool {
551572
var result = true
552573

@@ -575,9 +596,29 @@ open class XMLParser : NSObject {
575596

576597
return result
577598
}
578-
599+
#else
600+
internal func parse(from data: Data) -> Bool {
601+
var result = true
602+
var chunkStart = 0
603+
var chunkEnd = min(_chunkSize, data.count)
604+
while result {
605+
if chunkStart >= data.count || chunkEnd >= data.count {
606+
break
607+
}
608+
let chunk = data[chunkStart..<chunkEnd]
609+
result = parseData(chunk)
610+
chunkStart = chunkEnd
611+
chunkEnd = min(chunkEnd + _chunkSize, data.count)
612+
}
613+
return result
614+
}
615+
#endif
616+
579617
// called to start the event-driven parse. Returns YES in the event of a successful parse, and NO in case of error.
580618
open func parse() -> Bool {
619+
#if os(WASI)
620+
return _data.map { parse(from: $0) } ?? false
621+
#else
581622
XMLParser.setCurrentParser(self)
582623
defer { XMLParser.setCurrentParser(nil) }
583624

@@ -588,6 +629,7 @@ open class XMLParser : NSObject {
588629
}
589630

590631
return false
632+
#endif
591633
}
592634

593635
// called by the delegate to stop the parse. The delegate will get an error message sent to it.

0 commit comments

Comments
 (0)