@@ -124,6 +124,40 @@ extension String {
124124 self = " "
125125 }
126126
127+ /// Creates a new string by copying and validating the null-terminated UTF-8
128+ /// data referenced by the given pointer.
129+ ///
130+ /// This initializer does not try to repair ill-formed UTF-8 code unit
131+ /// sequences. If any are found, the result of the initializer is `nil`.
132+ ///
133+ /// The following example calls this initializer with pointers to the
134+ /// contents of two different `CChar` arrays---the first with well-formed
135+ /// UTF-8 code unit sequences and the second with an ill-formed sequence at
136+ /// the end.
137+ ///
138+ /// let validUTF8: [CChar] = [67, 97, 102, -61, -87, 0]
139+ /// validUTF8.withUnsafeBufferPointer { ptr in
140+ /// let s = String(validatingCString: ptr.baseAddress!)
141+ /// print(s)
142+ /// }
143+ /// // Prints "Optional("Café")"
144+ ///
145+ /// let invalidUTF8: [CChar] = [67, 97, 102, -61, 0]
146+ /// invalidUTF8.withUnsafeBufferPointer { ptr in
147+ /// let s = String(validatingCString: ptr.baseAddress!)
148+ /// print(s)
149+ /// }
150+ /// // Prints "nil"
151+ ///
152+ /// - Parameter nullTerminatedUTF8:
153+ /// A pointer to a null-terminated UTF-8 code sequence.
154+ @inlinable
155+ @_alwaysEmitIntoClient
156+ public init ? ( validatingCString nullTerminatedUTF8: UnsafePointer < CChar > ) {
157+ // FIXME: https://github.com/apple/swift/issues/68433 (rdar://115296219)
158+ self . init ( validatingUTF8: nullTerminatedUTF8)
159+ }
160+
127161 /// Creates a new string by copying and validating the null-terminated UTF-8
128162 /// data referenced by the given pointer.
129163 ///
@@ -149,7 +183,11 @@ extension String {
149183 /// }
150184 /// // Prints "nil"
151185 ///
186+ /// Note: This initializer is deprecated. Use
187+ /// `String.init?(validatingCString:)` instead.
188+ ///
152189 /// - Parameter cString: A pointer to a null-terminated UTF-8 code sequence.
190+ @available ( swift, deprecated: 6 , renamed: " String.init(validatingCString:) " )
153191 public init ? ( validatingUTF8 cString: UnsafePointer < CChar > ) {
154192 let len = UTF8 . _nullCodeUnitOffset ( in: cString)
155193 guard let str = cString. withMemoryRebound ( to: UInt8 . self, capacity: len, {
@@ -162,39 +200,59 @@ extension String {
162200
163201 @inlinable
164202 @_alwaysEmitIntoClient
165- public init ? ( validatingUTF8 cString : [ CChar ] ) {
166- guard let length = cString . firstIndex ( of: 0 ) else {
203+ public init ? ( validatingCString nullTerminatedUTF8 : [ CChar ] ) {
204+ guard let length = nullTerminatedUTF8 . firstIndex ( of: 0 ) else {
167205 _preconditionFailure (
168- " input of String.init(validatingUTF8 :) must be null-terminated "
206+ " input of String.init(validatingCString :) must be null-terminated "
169207 )
170208 }
171- guard let string = cString . prefix ( length) . withUnsafeBufferPointer ( {
209+ let string = nullTerminatedUTF8 . prefix ( length) . withUnsafeBufferPointer {
172210 $0. withMemoryRebound ( to: UInt8 . self, String . _tryFromUTF8 ( _: ) )
173- } )
174- else { return nil }
175-
211+ }
212+ guard let string else { return nil }
176213 self = string
177214 }
178215
216+ @inlinable
217+ @_alwaysEmitIntoClient
218+ @available ( * , deprecated, renamed: " String.init(validatingCString:) " )
219+ public init ? ( validatingUTF8 cString: [ CChar ] ) {
220+ self . init ( validatingCString: cString)
221+ }
222+
223+ @inlinable
224+ @_alwaysEmitIntoClient
225+ @available ( * , deprecated, message: " Use a copy of the String argument " )
226+ public init ? ( validatingCString nullTerminatedUTF8: String ) {
227+ self = nullTerminatedUTF8. withCString ( String . init ( cString: ) )
228+ }
229+
179230 @inlinable
180231 @_alwaysEmitIntoClient
181232 @available ( * , deprecated, message: " Use a copy of the String argument " )
182233 public init ? ( validatingUTF8 cString: String ) {
183- self = cString . withCString ( String . init ( cString : ) )
234+ self . init ( validatingCString : cString )
184235 }
185236
186237 @inlinable
187238 @_alwaysEmitIntoClient
188239 @available ( * , deprecated, message: " Use String(_ scalar: Unicode.Scalar) " )
189- public init ? ( validatingUTF8 cString : inout CChar ) {
190- guard cString == 0 else {
240+ public init ? ( validatingCString nullTerminatedUTF8 : inout CChar ) {
241+ guard nullTerminatedUTF8 == 0 else {
191242 _preconditionFailure (
192243 " input of String.init(validatingUTF8:) must be null-terminated "
193244 )
194245 }
195246 self = " "
196247 }
197248
249+ @inlinable
250+ @_alwaysEmitIntoClient
251+ @available ( * , deprecated, message: " Use String(_ scalar: Unicode.Scalar) " )
252+ public init ? ( validatingUTF8 cString: inout CChar ) {
253+ self . init ( validatingCString: & cString)
254+ }
255+
198256 /// Creates a new string by copying the null-terminated data referenced by
199257 /// the given pointer using the specified encoding.
200258 ///
0 commit comments