Skip to content

[4.2][String] Define _copyContents for UTF8View #16313

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions stdlib/public/core/StringUTF8.swift
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,11 @@ extension String.UTF8View.Iterator : IteratorProtocol {
self._endOffset = utf8._guts.count
}

internal mutating func _clear() {
self._nextOffset = self._endOffset
self._buffer = _OutputBuffer()
}

@inlinable // FIXME(sil-serialize-all)
public mutating func next() -> Unicode.UTF8.CodeUnit? {
if _slowPath(_nextOffset == _endOffset) {
Expand Down Expand Up @@ -731,3 +736,42 @@ extension String.UTF8View {
return self[bounds.relative(to: self)]
}
}

extension String.UTF8View {
/// Copies `self` into the supplied buffer.
///
/// - Precondition: The memory in `self` is uninitialized. The buffer must
/// contain sufficient uninitialized memory to accommodate `source.underestimatedCount`.
///
/// - Postcondition: The `Pointee`s at `buffer[startIndex..<returned index]` are
/// initialized.
public func _copyContents(
initializing buffer: UnsafeMutableBufferPointer<Iterator.Element>
) -> (Iterator,UnsafeMutableBufferPointer<Iterator.Element>.Index) {
guard var ptr = buffer.baseAddress else {
_preconditionFailure(
"Attempt to copy string contents into nil buffer pointer")
}
var it = self.makeIterator()

if _guts.isASCII {
defer { _fixLifetime(_guts) }
let asciiView = _guts._unmanagedASCIIView
_precondition(asciiView.count <= buffer.count,
"Insufficient space allocated to copy string contents")
ptr.initialize(from: asciiView.start, count: asciiView.count)
it._clear()
return (it, buffer.index(buffer.startIndex, offsetBy: asciiView.count))
}
else {
for idx in buffer.startIndex..<buffer.count {
guard let x = it.next() else {
return (it, idx)
}
ptr.initialize(to: x)
ptr += 1
}
return (it,buffer.endIndex)
}
}
}