@@ -212,6 +212,42 @@ extension String {
212
212
return String . _fromCodeUnits (
213
213
codeUnits, encoding: encoding, repair: isRepairing)
214
214
}
215
+
216
+ @_specialize ( where Encoding == Unicode. UTF8 )
217
+ @_specialize ( where Encoding == Unicode. UTF16 )
218
+ @inlinable // Fold away specializations
219
+ @_alwaysEmitIntoClient
220
+ public static func decodeCString< Encoding: _UnicodeEncoding > (
221
+ _ cString: [ Encoding . CodeUnit ] ,
222
+ as encoding: Encoding . Type ,
223
+ repairingInvalidCodeUnits isRepairing: Bool = true
224
+ ) -> ( result: String , repairsMade: Bool ) ? {
225
+ guard let length = cString. firstIndex ( of: 0 ) else {
226
+ _preconditionFailure (
227
+ " input of decodeCString(_:as:repairingInvalidCodeUnits:) must be null-terminated "
228
+ )
229
+ }
230
+
231
+ if _fastPath ( encoding == Unicode . UTF8. self) {
232
+ return cString. prefix ( length) . withUnsafeBytes {
233
+ buf -> ( result: String , repairsMade: Bool ) ? in
234
+ let codeUnits = buf. assumingMemoryBound ( to: UInt8 . self)
235
+ if isRepairing {
236
+ return String . _fromUTF8Repairing ( codeUnits)
237
+ }
238
+ else if let str = String . _tryFromUTF8 ( codeUnits) {
239
+ return ( str, false )
240
+ }
241
+ return nil
242
+ }
243
+ }
244
+
245
+ return cString. prefix ( length) . withUnsafeBufferPointer {
246
+ buf -> ( result: String , repairsMade: Bool ) ? in
247
+ String . _fromCodeUnits ( buf, encoding: encoding, repair: isRepairing)
248
+ }
249
+ }
250
+
215
251
/// Creates a string from the null-terminated sequence of bytes at the given
216
252
/// pointer.
217
253
///
@@ -230,6 +266,17 @@ extension String {
230
266
) {
231
267
self = String . decodeCString ( nullTerminatedCodeUnits, as: sourceEncoding) !. 0
232
268
}
269
+
270
+ @_specialize ( where Encoding == Unicode. UTF8 )
271
+ @_specialize ( where Encoding == Unicode. UTF16 )
272
+ @inlinable // Fold away specializations
273
+ @_alwaysEmitIntoClient
274
+ public init < Encoding: Unicode . Encoding > (
275
+ decodingCString nullTerminatedCodeUnits: [ Encoding . CodeUnit ] ,
276
+ as sourceEncoding: Encoding . Type
277
+ ) {
278
+ self = String . decodeCString ( nullTerminatedCodeUnits, as: sourceEncoding) !. 0
279
+ }
233
280
}
234
281
235
282
extension UnsafePointer where Pointee == UInt8 {
0 commit comments