// Copyright 2016 The Go Authors. All rights reserved.// Use of this source code is governed by a BSD-style// license that can be found in the LICENSE file.package bidiimport// Properties provides access to BiDi properties of runes.typePropertiesstruct { entry uint8 last uint8}var trie = newBidiTrie(0)// TODO: using this for bidirule reduces the running time by about 5%. Consider// if this is worth exposing or if we can find a way to speed up the Class// method.//// // CompactClass is like Class, but maps all of the BiDi control classes// // (LRO, RLO, LRE, RLE, PDF, LRI, RLI, FSI, PDI) to the class Control.// func (p Properties) CompactClass() Class {// return Class(p.entry & 0x0F)// }// Class returns the Bidi class for p.func ( Properties) () Class { := Class(.entry & 0x0F)if == Control { = controlByteToClass[.last&0xF] }return}// IsBracket reports whether the rune is a bracket.func ( Properties) () bool { return .entry&0xF0 != 0 }// IsOpeningBracket reports whether the rune is an opening bracket.// IsBracket must return true.func ( Properties) () bool { return .entry&openMask != 0 }// TODO: find a better API and expose.func ( Properties) ( rune) rune {returnxorMasks[.entry>>xorMaskShift] ^ }var controlByteToClass = [16]Class{0xD: LRO, // U+202D LeftToRightOverride,0xE: RLO, // U+202E RightToLeftOverride,0xA: LRE, // U+202A LeftToRightEmbedding,0xB: RLE, // U+202B RightToLeftEmbedding,0xC: PDF, // U+202C PopDirectionalFormat,0x6: LRI, // U+2066 LeftToRightIsolate,0x7: RLI, // U+2067 RightToLeftIsolate,0x8: FSI, // U+2068 FirstStrongIsolate,0x9: PDI, // U+2069 PopDirectionalIsolate,}// LookupRune returns properties for r.func ( rune) ( Properties, int) {var [4]byte := utf8.EncodeRune([:], )returnLookup([:])}// TODO: these lookup methods are based on the generated trie code. The returned// sizes have slightly different semantics from the generated code, in that it// always returns size==1 for an illegal UTF-8 byte (instead of the length// of the maximum invalid subsequence). Most Transformers, like unicode/norm,// leave invalid UTF-8 untouched, in which case it has performance benefits to// do so (without changing the semantics). Bidi requires the semantics used here// for the bidirule implementation to be compatible with the Go semantics.// They ultimately should perhaps be adopted by all trie implementations, for// convenience sake.// This unrolled code also boosts performance of the secure/bidirule package by// about 30%.// So, to remove this code:// - add option to trie generator to define return type.// - always return 1 byte size for ill-formed UTF-8 runes.// Lookup returns properties for the first rune in s and the width in bytes of// its encoding. The size will be 0 if s does not hold enough bytes to complete// the encoding.func ( []byte) ( Properties, int) { := [0]switch {case < 0x80: // is ASCIIreturnProperties{entry: bidiValues[]}, 1case < 0xC2:returnProperties{}, 1case < 0xE0: // 2-byte UTF-8iflen() < 2 {returnProperties{}, 0 } := bidiIndex[] := [1]if < 0x80 || 0xC0 <= {returnProperties{}, 1 }returnProperties{entry: trie.lookupValue(uint32(), )}, 2case < 0xF0: // 3-byte UTF-8iflen() < 3 {returnProperties{}, 0 } := bidiIndex[] := [1]if < 0x80 || 0xC0 <= {returnProperties{}, 1 } := uint32()<<6 + uint32() = bidiIndex[] := [2]if < 0x80 || 0xC0 <= {returnProperties{}, 1 }returnProperties{entry: trie.lookupValue(uint32(), ), last: }, 3case < 0xF8: // 4-byte UTF-8iflen() < 4 {returnProperties{}, 0 } := bidiIndex[] := [1]if < 0x80 || 0xC0 <= {returnProperties{}, 1 } := uint32()<<6 + uint32() = bidiIndex[] := [2]if < 0x80 || 0xC0 <= {returnProperties{}, 1 } = uint32()<<6 + uint32() = bidiIndex[] := [3]if < 0x80 || 0xC0 <= {returnProperties{}, 1 }returnProperties{entry: trie.lookupValue(uint32(), )}, 4 }// Illegal runereturnProperties{}, 1}// LookupString returns properties for the first rune in s and the width in// bytes of its encoding. The size will be 0 if s does not hold enough bytes to// complete the encoding.func ( string) ( Properties, int) { := [0]switch {case < 0x80: // is ASCIIreturnProperties{entry: bidiValues[]}, 1case < 0xC2:returnProperties{}, 1case < 0xE0: // 2-byte UTF-8iflen() < 2 {returnProperties{}, 0 } := bidiIndex[] := [1]if < 0x80 || 0xC0 <= {returnProperties{}, 1 }returnProperties{entry: trie.lookupValue(uint32(), )}, 2case < 0xF0: // 3-byte UTF-8iflen() < 3 {returnProperties{}, 0 } := bidiIndex[] := [1]if < 0x80 || 0xC0 <= {returnProperties{}, 1 } := uint32()<<6 + uint32() = bidiIndex[] := [2]if < 0x80 || 0xC0 <= {returnProperties{}, 1 }returnProperties{entry: trie.lookupValue(uint32(), ), last: }, 3case < 0xF8: // 4-byte UTF-8iflen() < 4 {returnProperties{}, 0 } := bidiIndex[] := [1]if < 0x80 || 0xC0 <= {returnProperties{}, 1 } := uint32()<<6 + uint32() = bidiIndex[] := [2]if < 0x80 || 0xC0 <= {returnProperties{}, 1 } = uint32()<<6 + uint32() = bidiIndex[] := [3]if < 0x80 || 0xC0 <= {returnProperties{}, 1 }returnProperties{entry: trie.lookupValue(uint32(), )}, 4 }// Illegal runereturnProperties{}, 1}
The pages are generated with Goldsv0.6.9-preview. (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu.
PR and bug reports are welcome and can be submitted to the issue list.
Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds.