@@ -212,6 +212,42 @@ extension String {
212212 return String . _fromCodeUnits (
213213 codeUnits, encoding: encoding, repair: isRepairing)
214214 }
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+
215251 /// Creates a string from the null-terminated sequence of bytes at the given
216252 /// pointer.
217253 ///
@@ -230,6 +266,17 @@ extension String {
230266 ) {
231267 self = String . decodeCString ( nullTerminatedCodeUnits, as: sourceEncoding) !. 0
232268 }
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+ }
233280}
234281
235282extension UnsafePointer where Pointee == UInt8 {
0 commit comments