@@ -434,49 +434,29 @@ extension NSString {
434
434
}
435
435
436
436
public func commonPrefix( with str: String , options mask: CompareOptions = [ ] ) -> String {
437
- var currentSubstring : CFMutableString ?
438
- let isLiteral = mask. contains ( . literal)
439
- var lastMatch = NSRange ( )
440
- let selfLen = length
441
- let otherLen = str. length
442
- var low = 0
443
- var high = selfLen
444
- var probe = ( low + high) / 2
445
- if ( probe > otherLen) {
446
- probe = otherLen // A little heuristic to avoid some extra work
447
- }
448
- if selfLen == 0 || otherLen == 0 {
437
+
438
+ let receiver = self as String
439
+ if receiver. isEmpty || str. isEmpty {
449
440
return " "
450
441
}
451
- var numCharsBuffered = 0
452
- var arrayBuffer = [ unichar] ( repeating: 0 , count: 100 )
453
- let other = str. _nsObject
454
- return arrayBuffer. withUnsafeMutablePointerOrAllocation ( selfLen, fastpath: UnsafeMutablePointer < unichar > ( mutating: _fastContents) ) { ( selfChars: UnsafeMutablePointer < unichar > ) -> String in
455
- // Now do the binary search. Note that the probe value determines the length of the substring to check.
456
- while true {
457
- let range = NSRange ( location: 0 , length: isLiteral ? probe + 1 : NSMaxRange ( rangeOfComposedCharacterSequence ( at: probe) ) ) // Extend the end of the composed char sequence
458
- if range. length > numCharsBuffered { // Buffer more characters if needed
459
- getCharacters ( selfChars, range: NSRange ( location: numCharsBuffered, length: range. length - numCharsBuffered) )
460
- numCharsBuffered = range. length
461
- }
462
- if currentSubstring == nil {
463
- currentSubstring = CFStringCreateMutableWithExternalCharactersNoCopy ( kCFAllocatorSystemDefault, selfChars, range. length, range. length, kCFAllocatorNull)
464
- } else {
465
- CFStringSetExternalCharactersNoCopy ( currentSubstring, selfChars, range. length, range. length)
466
- }
467
- if other. range ( of: currentSubstring!. _swiftObject, options: mask. union ( . anchored) , range: NSRange ( location: 0 , length: otherLen) ) . length != 0 { // Match
468
- lastMatch = range
469
- low = probe + 1
470
- } else {
471
- high = probe
472
- }
473
- if low >= high {
474
- break
475
- }
476
- probe = ( low + high) / 2
442
+ let literal = mask. contains ( . literal)
443
+ let caseInsensitive = mask. contains ( . caseInsensitive)
444
+
445
+ var result = " "
446
+ var otherIterator = str. makeIterator ( )
447
+
448
+ for ch in receiver {
449
+ guard let otherCh = otherIterator. next ( ) else { break }
450
+
451
+ if ch != otherCh {
452
+ guard caseInsensitive && String ( ch) . lowercased ( ) == String ( otherCh) . lowercased ( ) else { break }
477
453
}
478
- return lastMatch. length != 0 ? substring ( with: lastMatch) : " "
454
+
455
+ if literal && otherCh. unicodeScalars. count != ch. unicodeScalars. count { break }
456
+ result. append ( ch)
479
457
}
458
+
459
+ return result
480
460
}
481
461
482
462
public func contains( _ str: String ) -> Bool {
0 commit comments