// Copyright 2013 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 norm

import (
	

	
)

// Reset implements the Reset method of the transform.Transformer interface.
func (Form) () {}

// Transform implements the Transform method of the transform.Transformer
// interface. It may need to write segments of up to MaxSegmentSize at once.
// Users should either catch ErrShortDst and allow dst to grow or have dst be at
// least of size MaxTransformChunkSize to be guaranteed of progress.
func ( Form) (,  []byte,  bool) (,  int,  error) {
	// Cap the maximum number of src bytes to check.
	 := 
	 := 
	if  := len();  < len() {
		 = transform.ErrShortDst
		 = false
		 = [:]
	}
	,  := formTable[].quickSpan(inputBytes(), 0, len(), )
	 := copy(, [:])
	if ! {
		, ,  = .transform([:], [:], )
		return  + ,  + , 
	}

	if  == nil &&  < len() && ! {
		 = transform.ErrShortSrc
	}
	return , , 
}

func flushTransform( *reorderBuffer) bool {
	// Write out (must fully fit in dst, or else it is an ErrShortDst).
	if len(.out) < .nrune*utf8.UTFMax {
		return false
	}
	.out = .out[.flushCopy(.out):]
	return true
}

var errs = []error{nil, transform.ErrShortDst, transform.ErrShortSrc}

// transform implements the transform.Transformer interface. It is only called
// when quickSpan does not pass for a given string.
func ( Form) (,  []byte,  bool) (,  int,  error) {
	// TODO: get rid of reorderBuffer. See CL 23460044.
	 := reorderBuffer{}
	.init(, )
	for {
		// Load segment into reorder buffer.
		.setFlusher([:], flushTransform)
		 := decomposeSegment(&, , )
		if  < 0 {
			return , , errs[-]
		}
		 = len() - len(.out)
		 = 

		// Next quickSpan.
		 = .nsrc
		 := 
		if  :=  + len() - ;  <  {
			 = transform.ErrShortDst
			 = 
			 = false
		}
		,  := .f.quickSpan(.src, , , )
		 := copy([:], .src.bytes[:])
		 += 
		 += 
		if  {
			if  == nil &&  < .nsrc && ! {
				 = transform.ErrShortSrc
			}
			return , , 
		}
	}
}