William Kurkian | ea86948 | 2019-04-09 15:16:11 -0400 | [diff] [blame] | 1 | // Copyright 2015 The Go Authors. All rights reserved. |
| 2 | // Use of this source code is governed by a BSD-style |
| 3 | // license that can be found in the LICENSE file. |
| 4 | |
| 5 | // Package rangetable provides utilities for creating and inspecting |
| 6 | // unicode.RangeTables. |
| 7 | package rangetable |
| 8 | |
| 9 | import ( |
| 10 | "sort" |
| 11 | "unicode" |
| 12 | ) |
| 13 | |
| 14 | // New creates a RangeTable from the given runes, which may contain duplicates. |
| 15 | func New(r ...rune) *unicode.RangeTable { |
| 16 | if len(r) == 0 { |
| 17 | return &unicode.RangeTable{} |
| 18 | } |
| 19 | |
| 20 | sort.Sort(byRune(r)) |
| 21 | |
| 22 | // Remove duplicates. |
| 23 | k := 1 |
| 24 | for i := 1; i < len(r); i++ { |
| 25 | if r[k-1] != r[i] { |
| 26 | r[k] = r[i] |
| 27 | k++ |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | var rt unicode.RangeTable |
| 32 | for _, r := range r[:k] { |
| 33 | if r <= 0xFFFF { |
| 34 | rt.R16 = append(rt.R16, unicode.Range16{Lo: uint16(r), Hi: uint16(r), Stride: 1}) |
| 35 | } else { |
| 36 | rt.R32 = append(rt.R32, unicode.Range32{Lo: uint32(r), Hi: uint32(r), Stride: 1}) |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | // Optimize RangeTable. |
| 41 | return Merge(&rt) |
| 42 | } |
| 43 | |
| 44 | type byRune []rune |
| 45 | |
| 46 | func (r byRune) Len() int { return len(r) } |
| 47 | func (r byRune) Swap(i, j int) { r[i], r[j] = r[j], r[i] } |
| 48 | func (r byRune) Less(i, j int) bool { return r[i] < r[j] } |
| 49 | |
| 50 | // Visit visits all runes in the given RangeTable in order, calling fn for each. |
| 51 | func Visit(rt *unicode.RangeTable, fn func(rune)) { |
| 52 | for _, r16 := range rt.R16 { |
| 53 | for r := rune(r16.Lo); r <= rune(r16.Hi); r += rune(r16.Stride) { |
| 54 | fn(r) |
| 55 | } |
| 56 | } |
| 57 | for _, r32 := range rt.R32 { |
| 58 | for r := rune(r32.Lo); r <= rune(r32.Hi); r += rune(r32.Stride) { |
| 59 | fn(r) |
| 60 | } |
| 61 | } |
| 62 | } |
| 63 | |
| 64 | // Assigned returns a RangeTable with all assigned code points for a given |
| 65 | // Unicode version. This includes graphic, format, control, and private-use |
| 66 | // characters. It returns nil if the data for the given version is not |
| 67 | // available. |
| 68 | func Assigned(version string) *unicode.RangeTable { |
| 69 | return assigned[version] |
| 70 | } |