[stdlib] Fixed bugs with string views

Fixes rdar://problem/18435682
Fixes rdar://problem/19238102

Swift SVN r24117
This commit is contained in:
Maxwell Swadling
2014-12-23 20:02:38 +00:00
parent 1486238412
commit 02808373d8
5 changed files with 94 additions and 10 deletions

View File

@@ -12,7 +12,7 @@
extension String {
/// A collection of UTF-16 code units that encodes a `String` value.
public struct UTF16View : Sliceable, Reflectable {
public struct UTF16View : Sliceable, Reflectable, Printable, DebugPrintable {
public struct Index {
// Foundation needs access to these fields so it can expose
// random access
@@ -144,6 +144,16 @@ extension String {
return _UTF16ViewMirror(self)
}
public var description: String {
let start = _toInternalIndex(0)
let end = _toInternalIndex(_length)
return String(_core[start..<end])
}
public var debugDescription: String {
return "StringUTF16(\(self.description.debugDescription))"
}
var _offset: Int
var _length: Int
let _core: _StringCore

View File

@@ -83,11 +83,28 @@ extension _StringCore {
extension String {
/// A collection of UTF-8 code units that encodes a `String` value.
public struct UTF8View : CollectionType, Reflectable {
public struct UTF8View : CollectionType, Reflectable, Printable,
DebugPrintable {
internal let _core: _StringCore
// These are optional as a work around for a compiler segfault.
internal let _startIndex: Index!
internal let _endIndex: Index!
init(_ _core: _StringCore) {
self._core = _core
self._endIndex = Index(_core, _core.endIndex, Index._emptyBuffer)
if _fastPath(_core.count != 0) {
let (_, buffer) = _core._encodeSomeUTF8(0)
self._startIndex = Index(_core, 0, buffer)
} else {
self._startIndex = self._endIndex
}
}
init(_ _core: _StringCore, _ s: Index, _ e: Index) {
self._core = _core
self._startIndex = s
self._endIndex = e
}
/// A position in a `String.UTF8View`
@@ -179,11 +196,7 @@ extension String {
/// The position of the first code unit if the `String` is
/// non-empty; identical to `endIndex` otherwise.
public var startIndex: Index {
if _fastPath(_core.count != 0) {
let (_, buffer) = _core._encodeSomeUTF8(0)
return Index(_core, 0, buffer)
}
return endIndex
return self._startIndex
}
/// The "past the end" position.
@@ -192,7 +205,7 @@ extension String {
/// reachable from `startIndex` by zero or more applications of
/// `successor()`.
public var endIndex: Index {
return Index(_core, _core.endIndex, Index._emptyBuffer)
return self._endIndex
}
/// Access the element at `position`.
@@ -205,6 +218,15 @@ extension String {
return result
}
/// Access the elements delimited by the given half-open range of
/// indices.
///
/// Complexity: O(1) unless bridging from Objective-C requires an
/// O(N) conversion.
public subscript(subRange: Range<Index>) -> UTF8View {
return UTF8View(_core, subRange.startIndex, subRange.endIndex)
}
/// Return a *generator* over the code points that comprise this
/// *sequence*.
///
@@ -217,6 +239,14 @@ extension String {
public func getMirror() -> MirrorType {
return _UTF8ViewMirror(self)
}
public var description: String {
return String._fromCodeUnitSequenceWithRepair(UTF8.self, input: self).0
}
public var debugDescription: String {
return "UTF8View(\(self.description.debugDescription))"
}
}
/// A UTF-8 encoding of `self`.

View File

@@ -32,7 +32,7 @@ extension String {
return ("[\(i)]", reflect(_value[advance(_value.startIndex, i)]))
}
var summary: String { return String(_value._core) }
var summary: String { return _value.description }
var quickLookObject: QuickLookObject? { return .Some(.Text(summary)) }
}

View File

@@ -28,7 +28,8 @@ extension String {
/// A collection of `Unicode scalar values
/// <http://www.unicode.org/glossary/#unicode_scalar_value>`_ that
/// encode a `String` .
public struct UnicodeScalarView : Sliceable, SequenceType, Reflectable {
public struct UnicodeScalarView : Sliceable, SequenceType, Reflectable,
Printable, DebugPrintable {
init(_ _core: _StringCore) {
self._core = _core
}
@@ -210,6 +211,14 @@ extension String {
return _UnicodeScalarViewMirror(self)
}
public var description: String {
return String(_core[self.startIndex._position..<self.endIndex._position])
}
public var debugDescription: String {
return "StringUnicodeScalarView(\(self.description.debugDescription))"
}
var _core: _StringCore
}

View File

@@ -964,5 +964,40 @@ StringTests.test("uppercaseString") {
expectEqual("\u{0046}\u{0049}", "\u{fb01}".uppercaseString)
}
StringTests.test("unicodeViews") {
// Check the UTF views work with slicing
// U+FFFD REPLACEMENT CHARACTER
// U+1F3C2 SNOWBOARDER
// U+2603 SNOWMAN
let winter = "\u{1F3C2}\u{2603}"
// slices
// It is 4 bytes long, so it should return a replacement character.
expectEqual("\u{FFFD}", toString(winter.utf8[winter.utf8.startIndex ..<
winter.utf8.startIndex.successor().successor()]))
expectEqual("\u{1F3C2}", toString(winter.utf8[winter.utf8.startIndex ..<
advance(winter.utf8.startIndex, 4)]))
expectEqual("\u{1F3C2}", toString(winter.utf16[winter.utf16.startIndex ..<
advance(winter.utf16.startIndex, 2)]))
expectEqual("\u{1F3C2}", toString(winter.unicodeScalars[
winter.unicodeScalars.startIndex ..<
winter.unicodeScalars.startIndex.successor()]))
// views
expectEqual(winter, toString(winter.utf8[winter.utf8.startIndex ..<
advance(winter.utf8.startIndex, 7)]))
expectEqual(winter, toString(winter.utf16[winter.utf16.startIndex ..<
advance(winter.utf16.startIndex, 3)]))
expectEqual(winter, toString(
winter.unicodeScalars[winter.unicodeScalars.startIndex ..<
advance(winter.unicodeScalars.startIndex, 2)]))
let ga = "\u{304b}\u{3099}"
expectEqual(ga, toString(ga.utf8[ga.utf8.startIndex ..<
advance(ga.utf8.startIndex, 6)]))
}
runAllTests()