transform.mx raw

   1  // Copyright 2013 The Go Authors. All rights reserved.
   2  // Use of this source code is governed by a BSD-style
   3  // license that can be found in the LICENSE file.
   4  
   5  // Package transform provides reader and writer wrappers that transform the
   6  // bytes passing through as well as various transformations. Example
   7  // transformations provided by other packages include normalization and
   8  // conversion between character sets.
   9  package transform // import "golang.org/x/text/transform"
  10  
  11  import (
  12  	"bytes"
  13  	"errors"
  14  	"io"
  15  	"unicode/utf8"
  16  )
  17  
  18  var (
  19  	// ErrShortDst means that the destination buffer was too short to
  20  	// receive all of the transformed bytes.
  21  	ErrShortDst = errors.New("transform: short destination buffer")
  22  
  23  	// ErrShortSrc means that the source buffer has insufficient data to
  24  	// complete the transformation.
  25  	ErrShortSrc = errors.New("transform: short source buffer")
  26  
  27  	// ErrEndOfSpan means that the input and output (the transformed input)
  28  	// are not identical.
  29  	ErrEndOfSpan = errors.New("transform: input and output are not identical")
  30  
  31  	// errInconsistentByteCount means that Transform returned success (nil
  32  	// error) but also returned nSrc inconsistent with the src argument.
  33  	errInconsistentByteCount = errors.New("transform: inconsistent byte count returned")
  34  
  35  	// errShortInternal means that an internal buffer is not large enough
  36  	// to make progress and the Transform operation must be aborted.
  37  	errShortInternal = errors.New("transform: short internal buffer")
  38  )
  39  
  40  // Transformer transforms bytes.
  41  type Transformer interface {
  42  	// Transform writes to dst the transformed bytes read from src, and
  43  	// returns the number of dst bytes written and src bytes read. The
  44  	// atEOF argument tells whether src represents the last bytes of the
  45  	// input.
  46  	//
  47  	// Callers should always process the nDst bytes produced and account
  48  	// for the nSrc bytes consumed before considering the error err.
  49  	//
  50  	// A nil error means that all of the transformed bytes (whether freshly
  51  	// transformed from src or left over from previous Transform calls)
  52  	// were written to dst. A nil error can be returned regardless of
  53  	// whether atEOF is true. If err is nil then nSrc must equal len(src);
  54  	// the converse is not necessarily true.
  55  	//
  56  	// ErrShortDst means that dst was too short to receive all of the
  57  	// transformed bytes. ErrShortSrc means that src had insufficient data
  58  	// to complete the transformation. If both conditions apply, then
  59  	// either error may be returned. Other than the error conditions listed
  60  	// here, implementations are free to report other errors that arise.
  61  	Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error)
  62  
  63  	// Reset resets the state and allows a Transformer to be reused.
  64  	Reset()
  65  }
  66  
  67  // SpanningTransformer extends the Transformer interface with a Span method
  68  // that determines how much of the input already conforms to the Transformer.
  69  type SpanningTransformer interface {
  70  	Transformer
  71  
  72  	// Span returns a position in src such that transforming src[:n] results in
  73  	// identical output src[:n] for these bytes. It does not necessarily return
  74  	// the largest such n. The atEOF argument tells whether src represents the
  75  	// last bytes of the input.
  76  	//
  77  	// Callers should always account for the n bytes consumed before
  78  	// considering the error err.
  79  	//
  80  	// A nil error means that all input bytes are known to be identical to the
  81  	// output produced by the Transformer. A nil error can be returned
  82  	// regardless of whether atEOF is true. If err is nil, then n must
  83  	// equal len(src); the converse is not necessarily true.
  84  	//
  85  	// ErrEndOfSpan means that the Transformer output may differ from the
  86  	// input after n bytes. Note that n may be len(src), meaning that the output
  87  	// would contain additional bytes after otherwise identical output.
  88  	// ErrShortSrc means that src had insufficient data to determine whether the
  89  	// remaining bytes would change. Other than the error conditions listed
  90  	// here, implementations are free to report other errors that arise.
  91  	//
  92  	// Calling Span can modify the Transformer state as a side effect. In
  93  	// effect, it does the transformation just as calling Transform would, only
  94  	// without copying to a destination buffer and only up to a point it can
  95  	// determine the input and output bytes are the same. This is obviously more
  96  	// limited than calling Transform, but can be more efficient in terms of
  97  	// copying and allocating buffers. Calls to Span and Transform may be
  98  	// interleaved.
  99  	Span(src []byte, atEOF bool) (n int, err error)
 100  }
 101  
 102  // NopResetter can be embedded by implementations of Transformer to add a nop
 103  // Reset method.
 104  type NopResetter struct{}
 105  
 106  // Reset implements the Reset method of the Transformer interface.
 107  func (NopResetter) Reset() {}
 108  
 109  // Reader wraps another io.Reader by transforming the bytes read.
 110  type Reader struct {
 111  	r   io.Reader
 112  	t   Transformer
 113  	err error
 114  
 115  	// dst[dst0:dst1] contains bytes that have been transformed by t but
 116  	// not yet copied out via Read.
 117  	dst        []byte
 118  	dst0, dst1 int
 119  
 120  	// src[src0:src1] contains bytes that have been read from r but not
 121  	// yet transformed through t.
 122  	src        []byte
 123  	src0, src1 int
 124  
 125  	// transformComplete is whether the transformation is complete,
 126  	// regardless of whether or not it was successful.
 127  	transformComplete bool
 128  }
 129  
 130  const defaultBufSize = 4096
 131  
 132  // NewReader returns a new Reader that wraps r by transforming the bytes read
 133  // via t. It calls Reset on t.
 134  func NewReader(r io.Reader, t Transformer) *Reader {
 135  	t.Reset()
 136  	return &Reader{
 137  		r:   r,
 138  		t:   t,
 139  		dst: []byte{:defaultBufSize},
 140  		src: []byte{:defaultBufSize},
 141  	}
 142  }
 143  
 144  // Read implements the io.Reader interface.
 145  func (r *Reader) Read(p []byte) (int, error) {
 146  	n, err := 0, error(nil)
 147  	for {
 148  		// Copy out any transformed bytes and return the final error if we are done.
 149  		if r.dst0 != r.dst1 {
 150  			n = copy(p, r.dst[r.dst0:r.dst1])
 151  			r.dst0 += n
 152  			if r.dst0 == r.dst1 && r.transformComplete {
 153  				return n, r.err
 154  			}
 155  			return n, nil
 156  		} else if r.transformComplete {
 157  			return 0, r.err
 158  		}
 159  
 160  		// Try to transform some source bytes, or to flush the transformer if we
 161  		// are out of source bytes. We do this even if r.r.Read returned an error.
 162  		// As the io.Reader documentation says, "process the n > 0 bytes returned
 163  		// before considering the error".
 164  		if r.src0 != r.src1 || r.err != nil {
 165  			r.dst0 = 0
 166  			r.dst1, n, err = r.t.Transform(r.dst, r.src[r.src0:r.src1], r.err == io.EOF)
 167  			r.src0 += n
 168  
 169  			switch {
 170  			case err == nil:
 171  				if r.src0 != r.src1 {
 172  					r.err = errInconsistentByteCount
 173  				}
 174  				// The Transform call was successful; we are complete if we
 175  				// cannot read more bytes into src.
 176  				r.transformComplete = r.err != nil
 177  				continue
 178  			case err == ErrShortDst && (r.dst1 != 0 || n != 0):
 179  				// Make room in dst by copying out, and try again.
 180  				continue
 181  			case err == ErrShortSrc && r.src1-r.src0 != len(r.src) && r.err == nil:
 182  				// Read more bytes into src via the code below, and try again.
 183  			default:
 184  				r.transformComplete = true
 185  				// The reader error (r.err) takes precedence over the
 186  				// transformer error (err) unless r.err is nil or io.EOF.
 187  				if r.err == nil || r.err == io.EOF {
 188  					r.err = err
 189  				}
 190  				continue
 191  			}
 192  		}
 193  
 194  		// Move any untransformed source bytes to the start of the buffer
 195  		// and read more bytes.
 196  		if r.src0 != 0 {
 197  			r.src0, r.src1 = 0, copy(r.src, r.src[r.src0:r.src1])
 198  		}
 199  		n, r.err = r.r.Read(r.src[r.src1:])
 200  		r.src1 += n
 201  	}
 202  }
 203  
 204  // TODO: implement ReadByte (and ReadRune??).
 205  
 206  // Writer wraps another io.Writer by transforming the bytes read.
 207  // The user needs to call Close to flush unwritten bytes that may
 208  // be buffered.
 209  type Writer struct {
 210  	w   io.Writer
 211  	t   Transformer
 212  	dst []byte
 213  
 214  	// src[:n] contains bytes that have not yet passed through t.
 215  	src []byte
 216  	n   int
 217  }
 218  
 219  // NewWriter returns a new Writer that wraps w by transforming the bytes written
 220  // via t. It calls Reset on t.
 221  func NewWriter(w io.Writer, t Transformer) *Writer {
 222  	t.Reset()
 223  	return &Writer{
 224  		w:   w,
 225  		t:   t,
 226  		dst: []byte{:defaultBufSize},
 227  		src: []byte{:defaultBufSize},
 228  	}
 229  }
 230  
 231  // Write implements the io.Writer interface. If there are not enough
 232  // bytes available to complete a Transform, the bytes will be buffered
 233  // for the next write. Call Close to convert the remaining bytes.
 234  func (w *Writer) Write(data []byte) (n int, err error) {
 235  	src := data
 236  	if w.n > 0 {
 237  		// Append bytes from data to the last remainder.
 238  		// TODO: limit the amount copied on first try.
 239  		n = copy(w.src[w.n:], data)
 240  		w.n += n
 241  		src = w.src[:w.n]
 242  	}
 243  	for {
 244  		nDst, nSrc, err := w.t.Transform(w.dst, src, false)
 245  		if _, werr := w.w.Write(w.dst[:nDst]); werr != nil {
 246  			return n, werr
 247  		}
 248  		src = src[nSrc:]
 249  		if w.n == 0 {
 250  			n += nSrc
 251  		} else if len(src) <= n {
 252  			// Enough bytes from w.src have been consumed. We make src point
 253  			// to data instead to reduce the copying.
 254  			w.n = 0
 255  			n -= len(src)
 256  			src = data[n:]
 257  			if n < len(data) && (err == nil || err == ErrShortSrc) {
 258  				continue
 259  			}
 260  		}
 261  		switch err {
 262  		case ErrShortDst:
 263  			// This error is okay as long as we are making progress.
 264  			if nDst > 0 || nSrc > 0 {
 265  				continue
 266  			}
 267  		case ErrShortSrc:
 268  			if len(src) < len(w.src) {
 269  				m := copy(w.src, src)
 270  				// If w.n > 0, bytes from data were already copied to w.src and n
 271  				// was already set to the number of bytes consumed.
 272  				if w.n == 0 {
 273  					n += m
 274  				}
 275  				w.n = m
 276  				err = nil
 277  			} else if nDst > 0 || nSrc > 0 {
 278  				// Not enough buffer to store the remainder. Keep processing as
 279  				// long as there is progress. Without this case, transforms that
 280  				// require a lookahead larger than the buffer may result in an
 281  				// error. This is not something one may expect to be common in
 282  				// practice, but it may occur when buffers are set to small
 283  				// sizes during testing.
 284  				continue
 285  			}
 286  		case nil:
 287  			if w.n > 0 {
 288  				err = errInconsistentByteCount
 289  			}
 290  		}
 291  		return n, err
 292  	}
 293  }
 294  
 295  // Close implements the io.Closer interface.
 296  func (w *Writer) Close() error {
 297  	src := w.src[:w.n]
 298  	for {
 299  		nDst, nSrc, err := w.t.Transform(w.dst, src, true)
 300  		if _, werr := w.w.Write(w.dst[:nDst]); werr != nil {
 301  			return werr
 302  		}
 303  		if err != ErrShortDst {
 304  			return err
 305  		}
 306  		src = src[nSrc:]
 307  	}
 308  }
 309  
 310  type nop struct{ NopResetter }
 311  
 312  func (nop) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
 313  	n := copy(dst, src)
 314  	if n < len(src) {
 315  		err = ErrShortDst
 316  	}
 317  	return n, n, err
 318  }
 319  
 320  func (nop) Span(src []byte, atEOF bool) (n int, err error) {
 321  	return len(src), nil
 322  }
 323  
 324  type discard struct{ NopResetter }
 325  
 326  func (discard) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
 327  	return 0, len(src), nil
 328  }
 329  
 330  var (
 331  	// Discard is a Transformer for which all Transform calls succeed
 332  	// by consuming all bytes and writing nothing.
 333  	Discard Transformer = discard{}
 334  
 335  	// Nop is a SpanningTransformer that copies src to dst.
 336  	Nop SpanningTransformer = nop{}
 337  )
 338  
 339  // chain is a sequence of links. A chain with N Transformers has N+1 links and
 340  // N+1 buffers. Of those N+1 buffers, the first and last are the src and dst
 341  // buffers given to chain.Transform and the middle N-1 buffers are intermediate
 342  // buffers owned by the chain. The i'th link transforms bytes from the i'th
 343  // buffer chain.link[i].b at read offset chain.link[i].p to the i+1'th buffer
 344  // chain.link[i+1].b at write offset chain.link[i+1].n, for i in [0, N).
 345  type chain struct {
 346  	link []link
 347  	err  error
 348  	// errStart is the index at which the error occurred plus 1. Processing
 349  	// errStart at this level at the next call to Transform. As long as
 350  	// errStart > 0, chain will not consume any more source bytes.
 351  	errStart int
 352  }
 353  
 354  func (c *chain) fatalError(errIndex int, err error) {
 355  	if i := errIndex + 1; i > c.errStart {
 356  		c.errStart = i
 357  		c.err = err
 358  	}
 359  }
 360  
 361  type link struct {
 362  	t Transformer
 363  	// b[p:n] holds the bytes to be transformed by t.
 364  	b []byte
 365  	p int
 366  	n int
 367  }
 368  
 369  func (l *link) src() []byte {
 370  	return l.b[l.p:l.n]
 371  }
 372  
 373  func (l *link) dst() []byte {
 374  	return l.b[l.n:]
 375  }
 376  
 377  // Chain returns a Transformer that applies t in sequence.
 378  func Chain(t ...Transformer) Transformer {
 379  	if len(t) == 0 {
 380  		return nop{}
 381  	}
 382  	c := &chain{link: []link{:len(t)+1}}
 383  	for i, tt := range t {
 384  		c.link[i].t = tt
 385  	}
 386  	// Allocate intermediate buffers.
 387  	b := [][defaultBufSize]byte{:len(t)-1}
 388  	for i := range b {
 389  		c.link[i+1].b = b[i][:]
 390  	}
 391  	return c
 392  }
 393  
 394  // Reset resets the state of Chain. It calls Reset on all the Transformers.
 395  func (c *chain) Reset() {
 396  	for i, l := range c.link {
 397  		if l.t != nil {
 398  			l.t.Reset()
 399  		}
 400  		c.link[i].p, c.link[i].n = 0, 0
 401  	}
 402  }
 403  
 404  // TODO: make chain use Span (is going to be fun to implement!)
 405  
 406  // Transform applies the transformers of c in sequence.
 407  func (c *chain) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
 408  	// Set up src and dst in the chain.
 409  	srcL := &c.link[0]
 410  	dstL := &c.link[len(c.link)-1]
 411  	srcL.b, srcL.p, srcL.n = src, 0, len(src)
 412  	dstL.b, dstL.n = dst, 0
 413  	var lastFull, needProgress bool // for detecting progress
 414  
 415  	// i is the index of the next Transformer to apply, for i in [low, high].
 416  	// low is the lowest index for which c.link[low] may still produce bytes.
 417  	// high is the highest index for which c.link[high] has a Transformer.
 418  	// The error returned by Transform determines whether to increase or
 419  	// decrease i. We try to completely fill a buffer before converting it.
 420  	for low, i, high := c.errStart, c.errStart, len(c.link)-2; low <= i && i <= high; {
 421  		in, out := &c.link[i], &c.link[i+1]
 422  		nDst, nSrc, err0 := in.t.Transform(out.dst(), in.src(), atEOF && low == i)
 423  		out.n += nDst
 424  		in.p += nSrc
 425  		if i > 0 && in.p == in.n {
 426  			in.p, in.n = 0, 0
 427  		}
 428  		needProgress, lastFull = lastFull, false
 429  		switch err0 {
 430  		case ErrShortDst:
 431  			// Process the destination buffer next. Return if we are already
 432  			// at the high index.
 433  			if i == high {
 434  				return dstL.n, srcL.p, ErrShortDst
 435  			}
 436  			if out.n != 0 {
 437  				i++
 438  				// If the Transformer at the next index is not able to process any
 439  				// source bytes there is nothing that can be done to make progress
 440  				// and the bytes will remain unprocessed. lastFull is used to
 441  				// detect this and break out of the loop with a fatal error.
 442  				lastFull = true
 443  				continue
 444  			}
 445  			// The destination buffer was too small, but is completely empty.
 446  			// Return a fatal error as this transformation can never complete.
 447  			c.fatalError(i, errShortInternal)
 448  		case ErrShortSrc:
 449  			if i == 0 {
 450  				// Save ErrShortSrc in err. All other errors take precedence.
 451  				err = ErrShortSrc
 452  				break
 453  			}
 454  			// Source bytes were depleted before filling up the destination buffer.
 455  			// Verify we made some progress, move the remaining bytes to the errStart
 456  			// and try to get more source bytes.
 457  			if needProgress && nSrc == 0 || in.n-in.p == len(in.b) {
 458  				// There were not enough source bytes to proceed while the source
 459  				// buffer cannot hold any more bytes. Return a fatal error as this
 460  				// transformation can never complete.
 461  				c.fatalError(i, errShortInternal)
 462  				break
 463  			}
 464  			// in.b is an internal buffer and we can make progress.
 465  			in.p, in.n = 0, copy(in.b, in.src())
 466  			// Inlined from nil case (fallthrough not allowed in moxie).
 467  			if i > low {
 468  				i--
 469  				continue
 470  			}
 471  		case nil:
 472  			// if i == low, we have depleted the bytes at index i or any lower levels.
 473  			// In that case we increase low and i. In all other cases we decrease i to
 474  			// fetch more bytes before proceeding to the next index.
 475  			if i > low {
 476  				i--
 477  				continue
 478  			}
 479  		default:
 480  			c.fatalError(i, err0)
 481  		}
 482  		// Exhausted level low or fatal error: increase low and continue
 483  		// to process the bytes accepted so far.
 484  		i++
 485  		low = i
 486  	}
 487  
 488  	// If c.errStart > 0, this means we found a fatal error.  We will clear
 489  	// all upstream buffers. At this point, no more progress can be made
 490  	// downstream, as Transform would have bailed while handling ErrShortDst.
 491  	if c.errStart > 0 {
 492  		for i := 1; i < c.errStart; i++ {
 493  			c.link[i].p, c.link[i].n = 0, 0
 494  		}
 495  		err, c.errStart, c.err = c.err, 0, nil
 496  	}
 497  	return dstL.n, srcL.p, err
 498  }
 499  
 500  // Deprecated: Use runes.Remove instead.
 501  func RemoveFunc(f func(r rune) bool) Transformer {
 502  	return removeF(f)
 503  }
 504  
 505  type removeF func(r rune) bool
 506  
 507  func (removeF) Reset() {}
 508  
 509  // Transform implements the Transformer interface.
 510  func (t removeF) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
 511  	for r, sz := rune(0), 0; len(src) > 0; src = src[sz:] {
 512  
 513  		if r = rune(src[0]); r < utf8.RuneSelf {
 514  			sz = 1
 515  		} else {
 516  			r, sz = utf8.DecodeRune(src)
 517  
 518  			if sz == 1 {
 519  				// Invalid rune.
 520  				if !atEOF && !utf8.FullRune(src) {
 521  					err = ErrShortSrc
 522  					break
 523  				}
 524  				// We replace illegal bytes with RuneError. Not doing so might
 525  				// otherwise turn a sequence of invalid UTF-8 into valid UTF-8.
 526  				// The resulting byte sequence may subsequently contain runes
 527  				// for which t(r) is true that were passed unnoticed.
 528  				if !t(r) {
 529  					if nDst+3 > len(dst) {
 530  						err = ErrShortDst
 531  						break
 532  					}
 533  					nDst += copy(dst[nDst:], "\uFFFD")
 534  				}
 535  				nSrc++
 536  				continue
 537  			}
 538  		}
 539  
 540  		if !t(r) {
 541  			if nDst+sz > len(dst) {
 542  				err = ErrShortDst
 543  				break
 544  			}
 545  			nDst += copy(dst[nDst:], src[:sz])
 546  		}
 547  		nSrc += sz
 548  	}
 549  	return
 550  }
 551  
 552  // grow returns a new []byte that is longer than b, and copies the first n bytes
 553  // of b to the start of the new slice.
 554  func grow(b []byte, n int) []byte {
 555  	m := len(b)
 556  	if m <= 32 {
 557  		m = 64
 558  	} else if m <= 256 {
 559  		m *= 2
 560  	} else {
 561  		m += m >> 1
 562  	}
 563  	buf := []byte{:m}
 564  	copy(buf, b[:n])
 565  	return buf
 566  }
 567  
 568  const initialBufSize = 128
 569  
 570  // String returns a string with the result of converting s[:n] using t, where
 571  // n <= len(s). If err == nil, n will be len(s). It calls Reset on t.
 572  func String(t Transformer, s string) (result string, n int, err error) {
 573  	t.Reset()
 574  	if s == "" {
 575  		// Fast path for the common case for empty input. Results in about a
 576  		// 86% reduction of running time for BenchmarkStringLowerEmpty.
 577  		if _, _, err := t.Transform(nil, nil, true); err == nil {
 578  			return "", 0, nil
 579  		}
 580  	}
 581  
 582  	// Allocate only once. Note that both dst and src escape when passed to
 583  	// Transform.
 584  	buf := [2 * initialBufSize]byte{}
 585  	dst := buf[:initialBufSize:initialBufSize]
 586  	src := buf[initialBufSize : 2*initialBufSize]
 587  
 588  	// The input string s is transformed in multiple chunks (starting with a
 589  	// chunk size of initialBufSize). nDst and nSrc are per-chunk (or
 590  	// per-Transform-call) indexes, pDst and pSrc are overall indexes.
 591  	nDst, nSrc := 0, 0
 592  	pDst, pSrc := 0, 0
 593  
 594  	// pPrefix is the length of a common prefix: the first pPrefix bytes of the
 595  	// result will equal the first pPrefix bytes of s. It is not guaranteed to
 596  	// be the largest such value, but if pPrefix, len(result) and len(s) are
 597  	// all equal after the final transform (i.e. calling Transform with atEOF
 598  	// being true returned nil error) then we don't need to allocate a new
 599  	// result string.
 600  	pPrefix := 0
 601  	for {
 602  		// Invariant: pDst == pPrefix && pSrc == pPrefix.
 603  
 604  		n := copy(src, s[pSrc:])
 605  		nDst, nSrc, err = t.Transform(dst, src[:n], pSrc+n == len(s))
 606  		pDst += nDst
 607  		pSrc += nSrc
 608  
 609  		// TODO:  let transformers implement an optional Spanner interface, akin
 610  		// to norm's QuickSpan. This would even allow us to avoid any allocation.
 611  		if !bytes.Equal(dst[:nDst], src[:nSrc]) {
 612  			break
 613  		}
 614  		pPrefix = pSrc
 615  		if err == ErrShortDst {
 616  			// A buffer can only be short if a transformer modifies its input.
 617  			break
 618  		} else if err == ErrShortSrc {
 619  			if nSrc == 0 {
 620  				// No progress was made.
 621  				break
 622  			}
 623  			// Equal so far and !atEOF, so continue checking.
 624  		} else if err != nil || pPrefix == len(s) {
 625  			return string(s[:pPrefix]), pPrefix, err
 626  		}
 627  	}
 628  	// Post-condition: pDst == pPrefix + nDst && pSrc == pPrefix + nSrc.
 629  
 630  	// We have transformed the first pSrc bytes of the input s to become pDst
 631  	// transformed bytes. Those transformed bytes are discontiguous: the first
 632  	// pPrefix of them equal s[:pPrefix] and the last nDst of them equal
 633  	// dst[:nDst]. We copy them around, into a new dst buffer if necessary, so
 634  	// that they become one contiguous slice: dst[:pDst].
 635  	if pPrefix != 0 {
 636  		newDst := dst
 637  		if pDst > len(newDst) {
 638  			newDst = []byte{:len(s)+nDst-nSrc}
 639  		}
 640  		copy(newDst[pPrefix:pDst], dst[:nDst])
 641  		copy(newDst[:pPrefix], s[:pPrefix])
 642  		dst = newDst
 643  	}
 644  
 645  	// Prevent duplicate Transform calls with atEOF being true at the end of
 646  	// the input. Also return if we have an unrecoverable error.
 647  	if (err == nil && pSrc == len(s)) ||
 648  		(err != nil && err != ErrShortDst && err != ErrShortSrc) {
 649  		return string(dst[:pDst]), pSrc, err
 650  	}
 651  
 652  	// Transform the remaining input, growing dst and src buffers as necessary.
 653  	for {
 654  		n := copy(src, s[pSrc:])
 655  		atEOF := pSrc+n == len(s)
 656  		nDst, nSrc, err := t.Transform(dst[pDst:], src[:n], atEOF)
 657  		pDst += nDst
 658  		pSrc += nSrc
 659  
 660  		// If we got ErrShortDst or ErrShortSrc, do not grow as long as we can
 661  		// make progress. This may avoid excessive allocations.
 662  		if err == ErrShortDst {
 663  			if nDst == 0 {
 664  				dst = grow(dst, pDst)
 665  			}
 666  		} else if err == ErrShortSrc {
 667  			if atEOF {
 668  				return string(dst[:pDst]), pSrc, err
 669  			}
 670  			if nSrc == 0 {
 671  				src = grow(src, 0)
 672  			}
 673  		} else if err != nil || pSrc == len(s) {
 674  			return string(dst[:pDst]), pSrc, err
 675  		}
 676  	}
 677  }
 678  
 679  // Bytes returns a new byte slice with the result of converting b[:n] using t,
 680  // where n <= len(b). If err == nil, n will be len(b). It calls Reset on t.
 681  func Bytes(t Transformer, b []byte) (result []byte, n int, err error) {
 682  	return doAppend(t, 0, []byte{:len(b)}, b)
 683  }
 684  
 685  // Append appends the result of converting src[:n] using t to dst, where
 686  // n <= len(src), If err == nil, n will be len(src). It calls Reset on t.
 687  func Append(t Transformer, dst, src []byte) (result []byte, n int, err error) {
 688  	if len(dst) == cap(dst) {
 689  		n := len(src) + len(dst) // It is okay for this to be 0.
 690  		b := []byte{:n}
 691  		dst = b[:copy(b, dst)]
 692  	}
 693  	return doAppend(t, len(dst), dst[:cap(dst)], src)
 694  }
 695  
 696  func doAppend(t Transformer, pDst int, dst, src []byte) (result []byte, n int, err error) {
 697  	t.Reset()
 698  	pSrc := 0
 699  	for {
 700  		nDst, nSrc, err := t.Transform(dst[pDst:], src[pSrc:], true)
 701  		pDst += nDst
 702  		pSrc += nSrc
 703  		if err != ErrShortDst {
 704  			return dst[:pDst], pSrc, err
 705  		}
 706  
 707  		// Grow the destination buffer, but do not grow as long as we can make
 708  		// progress. This may avoid excessive allocations.
 709  		if nDst == 0 {
 710  			dst = grow(dst, pDst)
 711  		}
 712  	}
 713  }
 714