@@ -231,82 +231,74 @@ Base.codeunit(x::StaticString, i::Integer) = x.codeunits[i]
231231
232232Base. codeunit (x:: StaticString{T} ) where {T} = T
233233
234- function Base. isvalid (x:: StaticString{UInt8,N} , i:: Int ) where {N}
235- if i < 1 || i > N
236- return false
237- end
238- cs = x. codeunits
239- c = @inbounds cs[i]
240- if all (iszero, (cs[j] for j = i: N))
241- return false
242- elseif (c & 0x80 ) == 0x00
234+ function utf8_isvalid (x, n:: Int , i:: Int )
235+ 1 ≤ i ≤ n || return false
236+ c = @inbounds codeunit (x, i)
237+ if (c & 0x80 ) == 0x00
243238 return true
244239 elseif (c & 0x40 ) == 0x00
245240 return false
246241 elseif (c & 0x20 ) == 0x00
247- return @inbounds (i ≤ N - 1 ) && ((cs[i + 1 ] & 0xC0 ) == 0x80 )
242+ return @inbounds (i ≤ n - 1 ) && ((codeunit (x, i + 1 ) & 0xC0 ) == 0x80 )
248243 elseif (c & 0x10 ) == 0x00
249- return @inbounds (i ≤ N - 2 ) &&
250- ((cs[i + 1 ] & 0xC0 ) == 0x80 ) &&
251- ((cs[i + 2 ] & 0xC0 ) == 0x80 )
244+ return @inbounds (i ≤ n - 2 ) &&
245+ ((codeunit (x, i + 1 ) & 0xC0 ) == 0x80 ) &&
246+ ((codeunit (x, i + 2 ) & 0xC0 ) == 0x80 )
252247 elseif (c & 0x08 ) == 0x00
253- return @inbounds (i ≤ N - 3 ) &&
254- ((cs[i + 1 ] & 0xC0 ) == 0x80 ) &&
255- ((cs[i + 2 ] & 0xC0 ) == 0x80 ) &&
256- ((cs[i + 3 ] & 0xC0 ) == 0x80 )
248+ return @inbounds (i ≤ n - 3 ) &&
249+ ((codeunit (x, i + 1 ) & 0xC0 ) == 0x80 ) &&
250+ ((codeunit (x, i + 2 ) & 0xC0 ) == 0x80 ) &&
251+ ((codeunit (x, i + 3 ) & 0xC0 ) == 0x80 )
257252 else
258253 return false
259254 end
260- return false
261255end
262256
263- function Base. iterate (x:: StaticString{UInt8,N} , i:: Int = 1 ) where {N}
264- i > N && return
265- cs = x. codeunits
266- c = @inbounds cs[i]
267- if all (iszero, (cs[j] for j = i: N))
268- return
269- elseif (c & 0x80 ) == 0x00
257+ function utf8_iterate (x, n:: Int , i:: Int = 1 )
258+ i > n && return nothing
259+ utf8_isvalid (x, n, i) || throw (StringIndexError (x, i))
260+ c = @inbounds codeunit (x, i)
261+ if (c & 0x80 ) == 0x00
270262 return (reinterpret (Char, UInt32 (c) << 24 ), i + 1 )
271- elseif (c & 0x40 ) == 0x00
272- nothing
273263 elseif (c & 0x20 ) == 0x00
274- if @inbounds (i ≤ N - 1 ) && ((cs[i+ 1 ] & 0xC0 ) == 0x80 )
275- return (
276- reinterpret (Char, (UInt32 (cs[i]) << 24 ) | (UInt32 (cs[i+ 1 ]) << 16 )),
277- i + 2 ,
278- )
279- end
264+ return (
265+ reinterpret (Char, (UInt32 (c) << 24 ) | (UInt32 (codeunit (x, i + 1 )) << 16 )),
266+ i + 2 ,
267+ )
280268 elseif (c & 0x10 ) == 0x00
281- if @inbounds (i ≤ N - 2 ) && ((cs[i+ 1 ] & 0xC0 ) == 0x80 ) && ((cs[i+ 2 ] & 0xC0 ) == 0x80 )
282- return (
283- reinterpret (
284- Char,
285- (UInt32 (cs[i]) << 24 ) |
286- (UInt32 (cs[i+ 1 ]) << 16 ) |
287- (UInt32 (cs[i+ 2 ]) << 8 ),
288- ),
289- i + 3 ,
290- )
291- end
292- elseif (c & 0x08 ) == 0x00
293- if @inbounds (i ≤ N - 3 ) &&
294- ((cs[i+ 1 ] & 0xC0 ) == 0x80 ) &&
295- ((cs[i+ 2 ] & 0xC0 ) == 0x80 ) &&
296- ((cs[i+ 3 ] & 0xC0 ) == 0x80 )
297- return (
298- reinterpret (
299- Char,
300- (UInt32 (cs[i]) << 24 ) |
301- (UInt32 (cs[i+ 1 ]) << 16 ) |
302- (UInt32 (cs[i+ 2 ]) << 8 ) |
303- UInt32 (cs[i+ 3 ]),
304- ),
305- i + 4 ,
306- )
307- end
269+ return (
270+ reinterpret (
271+ Char,
272+ (UInt32 (c) << 24 ) |
273+ (UInt32 (codeunit (x, i + 1 )) << 16 ) |
274+ (UInt32 (codeunit (x, i + 2 )) << 8 ),
275+ ),
276+ i + 3 ,
277+ )
278+ else
279+ return (
280+ reinterpret (
281+ Char,
282+ (UInt32 (c) << 24 ) |
283+ (UInt32 (codeunit (x, i + 1 )) << 16 ) |
284+ (UInt32 (codeunit (x, i + 2 )) << 8 ) |
285+ UInt32 (codeunit (x, i + 3 )),
286+ ),
287+ i + 4 ,
288+ )
308289 end
309- throw (StringIndexError (x, i))
290+ end
291+
292+ function Base. isvalid (x:: StaticString{UInt8,N} , i:: Int ) where {N}
293+ cs = x. codeunits
294+ n = something (findlast (! iszero, cs), 0 )
295+ return utf8_isvalid (x, n, i)
296+ end
297+
298+ function Base. iterate (x:: StaticString{UInt8,N} , i:: Int = 1 ) where {N}
299+ cs = x. codeunits
300+ n = something (findlast (! iszero, cs), 0 )
301+ return utf8_iterate (x, n, i)
310302end
311303
312304function Base. isvalid (x:: StaticString{UInt32,N} , i:: Int ) where {N}
0 commit comments