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 }
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 }
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 }