示例#1
0
func (t *Transformer) advance(s []byte) (n int, ok bool) {
	var e bidi.Properties
	var sz int
	for n < len(s) {
		if s[n] < utf8.RuneSelf {
			e, sz = asciiTable[s[n]], 1
		} else {
			e, sz = bidi.Lookup(s[n:])
			if sz <= 1 {
				if sz == 1 {
					// We always consider invalid UTF-8 to be invalid, even if
					// the string has not yet been determined to be RTL.
					// TODO: is this correct?
					return n, false
				}
				return n, true // incomplete UTF-8 encoding
			}
		}
		// TODO: using CompactClass would result in noticeable speedup.
		// See unicode/bidi/prop.go:Properties.CompactClass.
		c := uint16(1 << e.Class())
		t.seen |= c
		if t.seen&exclusiveRTL == exclusiveRTL {
			t.state = ruleInvalid
			return n, false
		}
		switch tr := transitions[t.state]; {
		case tr[0].mask&c != 0:
			t.state = tr[0].next
		case tr[1].mask&c != 0:
			t.state = tr[1].next
		default:
			t.state = ruleInvalid
			if t.isRTL() {
				return n, false
			}
		}
		n += sz
	}
	return n, true
}
示例#2
0
func (t *Transformer) advanceString(s string) (n int, ok bool) {
	var e bidi.Properties
	var sz int
	for n < len(s) {
		if s[n] < utf8.RuneSelf {
			e, sz = asciiTable[s[n]], 1
		} else {
			e, sz = bidi.LookupString(s[n:])
			if sz <= 1 {
				if sz == 1 {
					return n, false // invalid UTF-8
				}
				return n, true // incomplete UTF-8 encoding
			}
		}
		// TODO: using CompactClass results in noticeable speedup.
		// See unicode/bidi/prop.go:Properties.CompactClass.
		c := uint16(1 << e.Class())
		t.seen |= c
		if t.seen&exclusiveRTL == exclusiveRTL {
			t.state = ruleInvalid
			return n, false
		}
		switch tr := transitions[t.state]; {
		case tr[0].mask&c != 0:
			t.state = tr[0].next
		case tr[1].mask&c != 0:
			t.state = tr[1].next
		default:
			t.state = ruleInvalid
			if t.isRTL() {
				return n, false
			}
		}
		n += sz
	}
	return n, true
}