mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[stdlib] Fixed bugs with string views
Fixes rdar://problem/18435682 Fixes rdar://problem/19238102 Swift SVN r24117
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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)) }
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user