github.com/primecitizens/pcz/std@v0.2.1/text/unicode/utf8/runtime.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright 2023 The Prime Citizens 3 // 4 // Copyright 2009 The Go Authors. All rights reserved. 5 // Use of this source code is governed by a BSD-style 6 // license that can be found in the LICENSE file. 7 8 package utf8 9 10 import ( 11 . "github.com/primecitizens/pcz/std/text/unicode/common" 12 ) 13 14 // functions used by the runtime 15 16 // IterRune returns the rune at the start of p[pos:] and the index 17 // after the rune in p. 18 // 19 // If the string appears to be incomplete or decoding problems are 20 // encountered (RuneError, pos+1) is returned to ensure 21 // progress when IterRune is used to iterate over a string. 22 func IterRune(p string, pos int) (r rune, next int) { 23 n := len(p) - pos 24 if n < 1 { 25 return RuneError, pos + 1 26 } 27 28 p = p[pos:] 29 30 p0 := p[0] 31 x := first[p0] 32 if x >= as { 33 // The following code simulates an additional check for x == xx and 34 // handling the ASCII and invalid cases accordingly. This mask-and-or 35 // approach prevents an additional branch. 36 mask := rune(x) << 31 >> 31 // Create 0x0000 or 0xFFFF. 37 return rune(p0)&^mask | RuneError&mask, pos + 1 38 } 39 40 sz := int(x & 7) 41 if n < sz { 42 return RuneError, pos + 1 43 } 44 45 b1 := p[1] 46 accept := acceptRanges[x>>4] 47 if b1 < accept.lo || accept.hi < b1 { 48 return RuneError, pos + 1 49 } 50 51 if sz <= 2 { // <= instead of == to help the compiler eliminate some bounds checks 52 return rune(p0&mask2)<<6 | rune(b1&maskx), pos + 2 53 } 54 55 b2 := p[2] 56 if b2 < locb || hicb < b2 { 57 return RuneError, pos + 1 58 } 59 60 if sz <= 3 { 61 return rune(p0&mask3)<<12 | rune(b1&maskx)<<6 | rune(b2&maskx), pos + 3 62 } 63 64 b3 := p[3] 65 if b3 < locb || hicb < b3 { 66 return RuneError, pos + 1 67 } 68 69 return rune(p0&mask4)<<18 | rune(b1&maskx)<<12 | rune(b2&maskx)<<6 | rune(b3&maskx), pos + 4 70 }