Exemple #1
0
func (b *buffers) enforce(p *Profile, src []byte) (str []byte, err error) {
	b.src = src

	// These transforms are applied in the order defined in
	// https://tools.ietf.org/html/rfc7564#section-7

	// TODO: allow different width transforms options.
	if p.options.foldWidth {
		// TODO: use Span, once available.
		if err = b.apply(width.Fold); err != nil {
			return nil, err
		}
	}
	for _, f := range p.options.additional {
		if err = b.apply(f()); err != nil {
			return nil, err
		}
	}
	if p.options.cases != nil {
		if err = b.apply(p.options.cases); err != nil {
			return nil, err
		}
	}
	if n := p.norm.QuickSpan(b.src); n < len(b.src) {
		x := b.next & 1
		n = copy(b.buf[x], b.src[:n])
		b.src, _, err = transform.Append(p.norm, b.buf[x][:n], b.src[n:])
		b.buf[x] = b.src
		b.next++
		if err != nil {
			return nil, err
		}
	}
	if p.options.bidiRule {
		if err := b.apply(bidirule.New()); err != nil {
			return nil, err
		}
	}
	c := checker{p: p}
	if _, err := c.span(b.src, true); err != nil {
		return nil, err
	}
	if p.disallow != nil {
		for i := 0; i < len(b.src); {
			r, size := utf8.DecodeRune(b.src[i:])
			if p.disallow.Contains(r) {
				return nil, errDisallowedRune
			}
			i += size
		}
	}

	// TODO: Add the disallow empty rule with a dummy transformer?

	if p.options.disallowEmpty && len(b.src) == 0 {
		return nil, errEmptyString
	}
	return b.src, nil
}
Exemple #2
0
func (b *buffers) apply(t transform.Transformer) (err error) {
	// TODO: use Span, once available.
	x := b.next & 1
	b.src, _, err = transform.Append(t, b.buf[x][:0], b.src)
	b.buf[x] = b.src
	b.next++
	return err
}
Exemple #3
0
func (b *buffers) apply(t transform.SpanningTransformer) (err error) {
	n, err := t.Span(b.src, true)
	if err != transform.ErrEndOfSpan {
		return err
	}
	x := b.next & 1
	if b.buf[x] == nil {
		b.buf[x] = make([]byte, 0, 8+len(b.src)+len(b.src)>>2)
	}
	span := append(b.buf[x][:0], b.src[:n]...)
	b.src, _, err = transform.Append(t, span, b.src[n:])
	b.buf[x] = b.src
	b.next++
	return err
}