Skip to content

Commit 8582b41

Browse files
authored
Merge pull request #9087 from apple/stateful-unicode-decoding
2 parents 306e9a3 + 4e802e2 commit 8582b41

File tree

1 file changed

+47
-32
lines changed

1 file changed

+47
-32
lines changed

test/Prototypes/UnicodeDecoders.swift

Lines changed: 47 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,8 @@ extension Unicode.DefaultScalarView.Iterator : IteratorProtocol, Sequence {
361361
extension Unicode.DefaultScalarView {
362362
struct Index {
363363
var codeUnitIndex: CodeUnits.Index
364+
var scalar: UnicodeScalar
365+
var stride: UInt8
364366
}
365367
}
366368

@@ -384,44 +386,52 @@ extension Unicode.DefaultScalarView.Index : Comparable {
384386

385387
extension Unicode.DefaultScalarView : Collection {
386388
public var startIndex: Index {
387-
return Index(codeUnitIndex: codeUnits.startIndex)
389+
@inline(__always)
390+
get {
391+
return index(
392+
after: Index(
393+
codeUnitIndex: codeUnits.startIndex,
394+
scalar: UnicodeScalar(_unchecked: 0),
395+
stride: 0)
396+
)
397+
}
388398
}
389399

390400
public var endIndex: Index {
391-
return Index(codeUnitIndex: codeUnits.endIndex)
392-
}
393-
394-
public subscript(i: Index) -> UnicodeScalar {
395401
@inline(__always)
396402
get {
397-
var d = Encoding.ForwardDecoder()
398-
var input = codeUnits[i.codeUnitIndex..<codeUnits.endIndex].makeIterator()
399-
switch d.parseOne(&input) {
400-
case .valid(let scalarContent):
401-
return Encoding.ForwardDecoder.decodeOne(scalarContent)
402-
case .invalid:
403-
return UnicodeScalar(_unchecked: 0xFFFD)
404-
case .emptyInput:
405-
fatalError("subscripting at endIndex")
406-
}
403+
return Index(
404+
codeUnitIndex: codeUnits.endIndex,
405+
scalar: UnicodeScalar(_unchecked: 0),
406+
stride: 0)
407407
}
408408
}
409409

410+
public subscript(i: Index) -> UnicodeScalar {
411+
@inline(__always) get { return i.scalar }
412+
}
413+
410414
@inline(__always)
411415
public func index(after i: Index) -> Index {
416+
let nextPosition = codeUnits.index(
417+
i.codeUnitIndex, offsetBy: numericCast(i.stride))
418+
var i = IndexingIterator(
419+
_elements: codeUnits, _position: nextPosition
420+
)
412421
var d = Encoding.ForwardDecoder()
413-
var input = codeUnits[i.codeUnitIndex..<codeUnits.endIndex].makeIterator()
414-
switch d.parseOne(&input) {
422+
switch d.parseOne(&i) {
415423
case .valid(let scalarContent):
416424
return Index(
417-
codeUnitIndex: codeUnits.index(
418-
i.codeUnitIndex, offsetBy: numericCast(scalarContent.count)))
419-
case .invalid(let l):
425+
codeUnitIndex: nextPosition,
426+
scalar: Encoding.ForwardDecoder.decodeOne(scalarContent),
427+
stride: numericCast(scalarContent.count))
428+
case .invalid(let stride):
420429
return Index(
421-
codeUnitIndex: codeUnits.index(
422-
i.codeUnitIndex, offsetBy: numericCast(l)))
430+
codeUnitIndex: nextPosition,
431+
scalar: UnicodeScalar(_unchecked: 0xfffd),
432+
stride: numericCast(stride))
423433
case .emptyInput:
424-
fatalError("indexing past endIndex")
434+
return endIndex
425435
}
426436
}
427437
}
@@ -461,19 +471,24 @@ extension Unicode.DefaultScalarView : BidirectionalCollection {
461471
@inline(__always)
462472
public func index(before i: Index) -> Index {
463473
var d = Encoding.ReverseDecoder()
464-
var input = ReverseIndexingIterator(
474+
475+
var more = ReverseIndexingIterator(
465476
_elements: codeUnits, _position: i.codeUnitIndex)
466-
switch d.parseOne(&input) {
477+
478+
switch d.parseOne(&more) {
467479
case .valid(let scalarContent):
480+
let d: CodeUnits.IndexDistance = -numericCast(scalarContent.count)
468481
return Index(
469-
codeUnitIndex: codeUnits.index(
470-
i.codeUnitIndex, offsetBy: -numericCast(scalarContent.count)))
471-
case .invalid(let l):
482+
codeUnitIndex: codeUnits.index(i.codeUnitIndex, offsetBy: d),
483+
scalar: Encoding.ReverseDecoder.decodeOne(scalarContent),
484+
stride: numericCast(scalarContent.count))
485+
case .invalid(let stride):
486+
let d: CodeUnits.IndexDistance = -numericCast(stride)
472487
return Index(
473-
codeUnitIndex: codeUnits.index(
474-
i.codeUnitIndex, offsetBy: -numericCast(l)))
475-
case .emptyInput:
476-
fatalError("indexing past startIndex")
488+
codeUnitIndex: codeUnits.index(i.codeUnitIndex, offsetBy: d) ,
489+
scalar: UnicodeScalar(_unchecked: 0xfffd),
490+
stride: numericCast(stride))
491+
case .emptyInput: fatalError("index out of bounds.")
477492
}
478493
}
479494
}

0 commit comments

Comments
 (0)