Example #1
0
// Direction reports the direction of the given label as defined by RFC 5893.
// The Bidi Rule does not have to be applied to labels of the category
// LeftToRight.
func Direction(b []byte) bidi.Direction {
	for i := 0; i < len(b); {
		e, sz := bidi.Lookup(b[i:])
		if sz == 0 {
			i++
		}
		c := e.Class()
		if c == bidi.R || c == bidi.AL || c == bidi.AN {
			return bidi.RightToLeft
		}
		i += sz
	}
	return bidi.LeftToRight
}
Example #2
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
}
Example #3
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 {
					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
			return n, false
		}
		n += sz
	}
	return n, true
}