Skip to content

Commit 175963e

Browse files
committed
Add new supported scanner API.
1 parent 3c41fb2 commit 175963e

File tree

6 files changed

+784
-133
lines changed

6 files changed

+784
-133
lines changed

Foundation.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
03B6F5841F15F339004F25AF /* TestURLProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03B6F5831F15F339004F25AF /* TestURLProtocol.swift */; };
1212
1513A8432044893F00539722 /* FileManager_XDG.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1513A8422044893F00539722 /* FileManager_XDG.swift */; };
1313
1520469B1D8AEABE00D02E36 /* HTTPServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1520469A1D8AEABE00D02E36 /* HTTPServer.swift */; };
14+
153CC8332214C3D100BFE8F3 /* ScannerAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 153CC8322214C3D100BFE8F3 /* ScannerAPI.swift */; };
1415
153E951120111DC500F250BE /* CFKnownLocations.h in Headers */ = {isa = PBXBuildFile; fileRef = 153E950F20111DC500F250BE /* CFKnownLocations.h */; settings = {ATTRIBUTES = (Private, ); }; };
1516
153E951220111DC500F250BE /* CFKnownLocations.c in Sources */ = {isa = PBXBuildFile; fileRef = 153E951020111DC500F250BE /* CFKnownLocations.c */; };
1617
15496CF1212CAEBA00450F5A /* CFAttributedStringPriv.h in Headers */ = {isa = PBXBuildFile; fileRef = 15496CF0212CAEBA00450F5A /* CFAttributedStringPriv.h */; };
@@ -546,6 +547,7 @@
546547
03B6F5831F15F339004F25AF /* TestURLProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestURLProtocol.swift; sourceTree = "<group>"; };
547548
1513A8422044893F00539722 /* FileManager_XDG.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileManager_XDG.swift; sourceTree = "<group>"; };
548549
1520469A1D8AEABE00D02E36 /* HTTPServer.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPServer.swift; sourceTree = "<group>"; };
550+
153CC8322214C3D100BFE8F3 /* ScannerAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScannerAPI.swift; sourceTree = "<group>"; };
549551
153E950F20111DC500F250BE /* CFKnownLocations.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CFKnownLocations.h; sourceTree = "<group>"; };
550552
153E951020111DC500F250BE /* CFKnownLocations.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = CFKnownLocations.c; sourceTree = "<group>"; };
551553
15496CF0212CAEBA00450F5A /* CFAttributedStringPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CFAttributedStringPriv.h; sourceTree = "<group>"; };
@@ -1851,6 +1853,7 @@
18511853
children = (
18521854
EADE0B751BD15DFF00C49C64 /* NSRegularExpression.swift */,
18531855
EADE0B771BD15DFF00C49C64 /* Scanner.swift */,
1856+
153CC8322214C3D100BFE8F3 /* ScannerAPI.swift */,
18541857
EADE0B7B1BD15DFF00C49C64 /* NSTextCheckingResult.swift */,
18551858
EADE0B4F1BD09E3100C49C64 /* NSAttributedString.swift */,
18561859
5BDC3F311BCC5DCB00ED97BB /* NSCharacterSet.swift */,
@@ -2366,6 +2369,7 @@
23662369
5B23AB871CE62D17000DB898 /* Boxing.swift in Sources */,
23672370
5BF7AEA41BCD51F9008F214A /* Bundle.swift in Sources */,
23682371
5B23AB891CE62D4D000DB898 /* ReferenceConvertible.swift in Sources */,
2372+
153CC8332214C3D100BFE8F3 /* ScannerAPI.swift in Sources */,
23692373
D3E8D6D11C367AB600295652 /* NSSpecialValue.swift in Sources */,
23702374
EAB57B721BD1C7A5004AC5C5 /* PortMessage.swift in Sources */,
23712375
5BD31D201D5CE8C400563814 /* Bridging.swift in Sources */,

Foundation/Decimal.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2068,6 +2068,7 @@ extension Scanner {
20682068
}
20692069

20702070
}
2071+
20712072
public func scanDecimal() -> Decimal? {
20722073

20732074
var result = Decimal()
@@ -2076,7 +2077,7 @@ extension Scanner {
20762077
let length = string.length
20772078
var buf = _NSStringBuffer(string: string, start: self._scanLocation, end: length)
20782079

2079-
let ds_chars = decimalSep(locale).utf16
2080+
let ds_chars = decimalSep(locale as? Locale).utf16
20802081
let ds = ds_chars[ds_chars.startIndex]
20812082
buf.skip(_skipSet)
20822083
var neg = false

Foundation/Scanner.swift

Lines changed: 98 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ open class Scanner: NSObject, NSCopying {
6363
}
6464

6565
open var caseSensitive: Bool = false
66-
open var locale: Locale?
66+
open var locale: Any?
6767

6868
internal static let defaultSkipSet = CharacterSet.whitespacesAndNewlines
6969

@@ -72,6 +72,89 @@ open class Scanner: NSObject, NSCopying {
7272
_skipSet = Scanner.defaultSkipSet
7373
_scanLocation = 0
7474
}
75+
76+
// On overflow, the below methods will return success and clamp
77+
@discardableResult
78+
open func scanInt32(_ result: UnsafeMutablePointer<Int32>) -> Bool {
79+
return _scanString.scan(_skipSet, locationToScanFrom: &_scanLocation) { (value: Int32) -> Void in
80+
result.pointee = value
81+
}
82+
}
83+
84+
@discardableResult
85+
open func scanInt(_ result: UnsafeMutablePointer<Int>) -> Bool {
86+
return _scanString.scan(_skipSet, locationToScanFrom: &_scanLocation) { (value: Int) -> Void in
87+
result.pointee = value
88+
}
89+
}
90+
91+
@discardableResult
92+
open func scanInt64(_ result: UnsafeMutablePointer<Int64>) -> Bool {
93+
return _scanString.scan(_skipSet, locationToScanFrom: &_scanLocation) { (value: Int64) -> Void in
94+
result.pointee = value
95+
}
96+
}
97+
98+
@discardableResult
99+
open func scanUnsignedLongLong(_ result: UnsafeMutablePointer<UInt64>) -> Bool {
100+
return _scanString.scan(_skipSet, locationToScanFrom: &_scanLocation) { (value: UInt64) -> Void in
101+
result.pointee = value
102+
}
103+
}
104+
105+
@discardableResult
106+
open func scanFloat(_ result: UnsafeMutablePointer<Float>) -> Bool {
107+
return _scanString.scan(_skipSet, locale: locale as? Locale, locationToScanFrom: &_scanLocation) { (value: Float) -> Void in
108+
result.pointee = value
109+
}
110+
}
111+
112+
@discardableResult
113+
open func scanDouble(_ result: UnsafeMutablePointer<Double>) -> Bool {
114+
return _scanString.scan(_skipSet, locale: locale as? Locale, locationToScanFrom: &_scanLocation) { (value: Double) -> Void in
115+
result.pointee = value
116+
}
117+
}
118+
119+
@discardableResult
120+
open func scanHexInt32(_ result: UnsafeMutablePointer<UInt32>) -> Bool {
121+
return _scanString.scanHex(_skipSet, locationToScanFrom: &_scanLocation) { (value: UInt32) -> Void in
122+
result.pointee = value
123+
}
124+
}
125+
126+
@discardableResult
127+
open func scanHexInt64(_ result: UnsafeMutablePointer<UInt64>) -> Bool {
128+
return _scanString.scanHex(_skipSet, locationToScanFrom: &_scanLocation) { (value: UInt64) -> Void in
129+
result.pointee = value
130+
}
131+
}
132+
133+
@discardableResult
134+
open func scanHexFloat(_ result: UnsafeMutablePointer<Float>) -> Bool {
135+
return _scanString.scanHex(_skipSet, locale: locale as? Locale, locationToScanFrom: &_scanLocation) { (value: Float) -> Void in
136+
result.pointee = value
137+
}
138+
}
139+
140+
@discardableResult
141+
open func scanHexDouble(_ result: UnsafeMutablePointer<Double>) -> Bool {
142+
return _scanString.scanHex(_skipSet, locale: locale as? Locale, locationToScanFrom: &_scanLocation) { (value: Double) -> Void in
143+
result.pointee = value
144+
}
145+
}
146+
147+
open var isAtEnd: Bool {
148+
var stringLoc = scanLocation
149+
let stringLen = string.length
150+
if let invSet = invertedSkipSet {
151+
let range = string._nsObject.rangeOfCharacter(from: invSet, options: [], range: NSRange(location: stringLoc, length: stringLen - stringLoc))
152+
stringLoc = range.length > 0 ? range.location : stringLen
153+
}
154+
return stringLoc == stringLen
155+
}
156+
157+
open class func localizedScannerWithString(_ string: String) -> AnyObject { NSUnimplemented() }
75158
}
76159

77160
internal struct _NSStringBuffer {
@@ -416,93 +499,6 @@ extension String {
416499
}
417500
}
418501

419-
extension Scanner {
420-
421-
// On overflow, the below methods will return success and clamp
422-
@discardableResult
423-
public func scanInt32(_ result: UnsafeMutablePointer<Int32>) -> Bool {
424-
return _scanString.scan(_skipSet, locationToScanFrom: &_scanLocation) { (value: Int32) -> Void in
425-
result.pointee = value
426-
}
427-
}
428-
429-
@discardableResult
430-
public func scanInt(_ result: UnsafeMutablePointer<Int>) -> Bool {
431-
return _scanString.scan(_skipSet, locationToScanFrom: &_scanLocation) { (value: Int) -> Void in
432-
result.pointee = value
433-
}
434-
}
435-
436-
@discardableResult
437-
public func scanInt64(_ result: UnsafeMutablePointer<Int64>) -> Bool {
438-
return _scanString.scan(_skipSet, locationToScanFrom: &_scanLocation) { (value: Int64) -> Void in
439-
result.pointee = value
440-
}
441-
}
442-
443-
@discardableResult
444-
public func scanUnsignedLongLong(_ result: UnsafeMutablePointer<UInt64>) -> Bool {
445-
return _scanString.scan(_skipSet, locationToScanFrom: &_scanLocation) { (value: UInt64) -> Void in
446-
result.pointee = value
447-
}
448-
}
449-
450-
@discardableResult
451-
public func scanFloat(_ result: UnsafeMutablePointer<Float>) -> Bool {
452-
return _scanString.scan(_skipSet, locale: locale, locationToScanFrom: &_scanLocation) { (value: Float) -> Void in
453-
result.pointee = value
454-
}
455-
}
456-
457-
@discardableResult
458-
public func scanDouble(_ result: UnsafeMutablePointer<Double>) -> Bool {
459-
return _scanString.scan(_skipSet, locale: locale, locationToScanFrom: &_scanLocation) { (value: Double) -> Void in
460-
result.pointee = value
461-
}
462-
}
463-
464-
@discardableResult
465-
public func scanHexInt32(_ result: UnsafeMutablePointer<UInt32>) -> Bool {
466-
return _scanString.scanHex(_skipSet, locationToScanFrom: &_scanLocation) { (value: UInt32) -> Void in
467-
result.pointee = value
468-
}
469-
}
470-
471-
@discardableResult
472-
public func scanHexInt64(_ result: UnsafeMutablePointer<UInt64>) -> Bool {
473-
return _scanString.scanHex(_skipSet, locationToScanFrom: &_scanLocation) { (value: UInt64) -> Void in
474-
result.pointee = value
475-
}
476-
}
477-
478-
@discardableResult
479-
public func scanHexFloat(_ result: UnsafeMutablePointer<Float>) -> Bool {
480-
return _scanString.scanHex(_skipSet, locale: locale, locationToScanFrom: &_scanLocation) { (value: Float) -> Void in
481-
result.pointee = value
482-
}
483-
}
484-
485-
@discardableResult
486-
public func scanHexDouble(_ result: UnsafeMutablePointer<Double>) -> Bool {
487-
return _scanString.scanHex(_skipSet, locale: locale, locationToScanFrom: &_scanLocation) { (value: Double) -> Void in
488-
result.pointee = value
489-
}
490-
}
491-
492-
public var isAtEnd: Bool {
493-
var stringLoc = scanLocation
494-
let stringLen = string.length
495-
if let invSet = invertedSkipSet {
496-
let range = string._nsObject.rangeOfCharacter(from: invSet, options: [], range: NSRange(location: stringLoc, length: stringLen - stringLoc))
497-
stringLoc = range.length > 0 ? range.location : stringLen
498-
}
499-
return stringLoc == stringLen
500-
}
501-
502-
open class func localizedScannerWithString(_ string: String) -> AnyObject { NSUnimplemented() }
503-
}
504-
505-
506502
/// Revised API for avoiding usage of AutoreleasingUnsafeMutablePointer and better Optional usage.
507503
/// - Experiment: This is a draft API currently under consideration for official import into Foundation as a suitable alternative
508504
/// - Note: Since this API is under consideration it may be either removed or revised in the near future
@@ -619,7 +615,7 @@ extension Scanner {
619615

620616
@discardableResult
621617
public func scanString(_ string:String, into ptr: UnsafeMutablePointer<String?>?) -> Bool {
622-
if let str = scanString(string) {
618+
if let str = _scanStringSplittingGraphemes(string) {
623619
ptr?.pointee = str
624620
return true
625621
}
@@ -628,7 +624,7 @@ extension Scanner {
628624

629625
// These methods avoid calling the private API for _invertedSkipSet and manually re-construct them so that it is only usage of public API usage
630626
// Future implementations on Darwin of these methods will likely be more optimized to take advantage of the cached values.
631-
public func scanString(_ searchString: String) -> String? {
627+
private func _scanStringSplittingGraphemes(_ searchString: String) -> String? {
632628
let str = self.string._bridgeToObjectiveC()
633629
var stringLoc = scanLocation
634630
let stringLen = str.length
@@ -649,6 +645,7 @@ extension Scanner {
649645
return nil
650646
}
651647

648+
@available(swift, deprecated: 5.0, renamed: "scanCharacters(from:)")
652649
public func scanCharactersFromSet(_ set: CharacterSet) -> String? {
653650
let str = self.string._bridgeToObjectiveC()
654651
var stringLoc = scanLocation
@@ -670,7 +667,16 @@ extension Scanner {
670667
return nil
671668
}
672669

673-
public func scanUpToString(_ string: String) -> String? {
670+
@discardableResult
671+
public func scanUpTo(_ string:String, into ptr: UnsafeMutablePointer<String?>?) -> Bool {
672+
if let str = _scanUpToStringSplittingGraphemes(string) {
673+
ptr?.pointee = str
674+
return true
675+
}
676+
return false
677+
}
678+
679+
public func _scanUpToStringSplittingGraphemes(_ string: String) -> String? {
674680
let str = self.string._bridgeToObjectiveC()
675681
var stringLoc = scanLocation
676682
let stringLen = str.length
@@ -700,6 +706,7 @@ extension Scanner {
700706
return false
701707
}
702708

709+
@available(swift, deprecated: 5.0, renamed: "scanUpToCharacters(from:)")
703710
public func scanUpToCharactersFromSet(_ set: CharacterSet) -> String? {
704711
let str = self.string._bridgeToObjectiveC()
705712
var stringLoc = scanLocation

0 commit comments

Comments
 (0)