Skip to content

Commit 2ce971a

Browse files
authored
Merge pull request #155 from glessard/system-string-api-consistency
SystemString api consistency improvements
2 parents 8078852 + 6609a40 commit 2ce971a

File tree

3 files changed

+26
-19
lines changed

3 files changed

+26
-19
lines changed

Sources/System/FilePath/FilePathComponents.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift System open source project
33

4-
Copyright (c) 2020 Apple Inc. and the Swift System project authors
4+
Copyright (c) 2020 - 2024 Apple Inc. and the Swift System project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -146,7 +146,7 @@ extension _StrSlice {
146146
internal func _withSystemChars<T>(
147147
_ f: (UnsafeBufferPointer<SystemChar>) throws -> T
148148
) rethrows -> T {
149-
try _storage.withSystemChars {
149+
try _storage.withNullTerminatedSystemChars {
150150
try f(UnsafeBufferPointer(rebasing: $0[_range]))
151151
}
152152
}

Sources/System/SystemString.swift

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift System open source project
33

4-
Copyright (c) 2020 Apple Inc. and the Swift System project authors
4+
Copyright (c) 2020 - 2024 Apple Inc. and the Swift System project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -169,24 +169,20 @@ extension SystemString: Hashable, Codable {}
169169

170170
extension SystemString {
171171

172-
// withSystemChars includes the null terminator
173-
internal func withSystemChars<T>(
172+
internal func withNullTerminatedSystemChars<T>(
174173
_ f: (UnsafeBufferPointer<SystemChar>) throws -> T
175174
) rethrows -> T {
176-
try nullTerminatedStorage.withContiguousStorageIfAvailable(f)!
175+
try nullTerminatedStorage.withUnsafeBufferPointer(f)
177176
}
178177

178+
// withCodeUnits does not include the null terminator
179179
internal func withCodeUnits<T>(
180180
_ f: (UnsafeBufferPointer<CInterop.PlatformUnicodeEncoding.CodeUnit>) throws -> T
181181
) rethrows -> T {
182-
try withSystemChars { chars in
183-
let length = chars.count * MemoryLayout<SystemChar>.stride
184-
let count = length / MemoryLayout<CInterop.PlatformUnicodeEncoding.CodeUnit>.stride
185-
return try chars.baseAddress!.withMemoryRebound(
186-
to: CInterop.PlatformUnicodeEncoding.CodeUnit.self,
187-
capacity: count
188-
) { pointer in
189-
try f(UnsafeBufferPointer(start: pointer, count: count))
182+
try withNullTerminatedSystemChars {
183+
try $0.withMemoryRebound(to: CInterop.PlatformUnicodeEncoding.CodeUnit.self) {
184+
assert($0.last == .zero)
185+
return try f(.init(start: $0.baseAddress, count: $0.count&-1))
190186
}
191187
}
192188
}
@@ -202,7 +198,9 @@ extension Slice where Base == SystemString {
202198
}
203199

204200
internal var string: String {
205-
withCodeUnits { String(decoding: $0, as: CInterop.PlatformUnicodeEncoding.self) }
201+
withCodeUnits {
202+
String(decoding: $0, as: CInterop.PlatformUnicodeEncoding.self)
203+
}
206204
}
207205

208206
internal func withPlatformString<T>(
@@ -244,7 +242,11 @@ extension SystemString: ExpressibleByStringLiteral {
244242
}
245243

246244
extension SystemString: CustomStringConvertible, CustomDebugStringConvertible {
247-
internal var string: String { String(decoding: self) }
245+
internal var string: String {
246+
self.withCodeUnits {
247+
String(decoding: $0, as: CInterop.PlatformUnicodeEncoding.self)
248+
}
249+
}
248250

249251
internal var description: String { string }
250252
internal var debugDescription: String { description.debugDescription }
@@ -283,7 +285,7 @@ extension SystemString {
283285
internal func withPlatformString<T>(
284286
_ f: (UnsafePointer<CInterop.PlatformChar>) throws -> T
285287
) rethrows -> T {
286-
try withSystemChars { chars in
288+
try withNullTerminatedSystemChars { chars in
287289
let length = chars.count * MemoryLayout<SystemChar>.stride
288290
return try chars.baseAddress!.withMemoryRebound(
289291
to: CInterop.PlatformChar.self,

Tests/SystemTests/SystemStringTests.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
This source file is part of the Swift System open source project
33

4-
Copyright (c) 2020 Apple Inc. and the Swift System project authors
4+
Copyright (c) 2020 - 2024 Apple Inc. and the Swift System project authors
55
Licensed under Apache License v2.0 with Runtime Library Exception
66

77
See https://swift.org/LICENSE.txt for license information
@@ -101,7 +101,7 @@ struct StringTest: TestCase {
101101
// Test null insertion
102102
let rawChars = raw.lazy.map { SystemChar($0) }
103103
expectEqual(sysRaw, SystemString(rawChars.dropLast()))
104-
sysRaw.withSystemChars { // TODO: assuming we want null in withSysChars
104+
sysRaw.withNullTerminatedSystemChars {
105105
expectEqualSequence(rawChars, $0, "rawChars")
106106
}
107107

@@ -254,6 +254,11 @@ final class SystemStringTest: XCTestCase {
254254
XCTAssert(str == "abcd")
255255
}
256256

257+
func testStringProperty() {
258+
let source: [CInterop.PlatformChar] = [0x61, 0x62, 0, 0x63]
259+
let str = SystemString(platformString: source)
260+
XCTAssertEqual(str.string, str[...].string)
261+
}
257262
}
258263

259264
extension SystemStringTest {

0 commit comments

Comments
 (0)