OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / text / transform / transform.go
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 be returned
82         // regardless of whether atEOF is true. If err is nil, then 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: make([]byte, defaultBufSize),
140                 src: make([]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: make([]byte, defaultBufSize),
227                 src: make([]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: make([]link, len(t)+1)}
383         for i, tt := range t {
384                 c.link[i].t = tt
385         }
386         // Allocate intermediate buffers.
387         b := make([][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                         fallthrough
467                 case nil:
468                         // if i == low, we have depleted the bytes at index i or any lower levels.
469                         // In that case we increase low and i. In all other cases we decrease i to
470                         // fetch more bytes before proceeding to the next index.
471                         if i > low {
472                                 i--
473                                 continue
474                         }
475                 default:
476                         c.fatalError(i, err0)
477                 }
478                 // Exhausted level low or fatal error: increase low and continue
479                 // to process the bytes accepted so far.
480                 i++
481                 low = i
482         }
483
484         // If c.errStart > 0, this means we found a fatal error.  We will clear
485         // all upstream buffers. At this point, no more progress can be made
486         // downstream, as Transform would have bailed while handling ErrShortDst.
487         if c.errStart > 0 {
488                 for i := 1; i < c.errStart; i++ {
489                         c.link[i].p, c.link[i].n = 0, 0
490                 }
491                 err, c.errStart, c.err = c.err, 0, nil
492         }
493         return dstL.n, srcL.p, err
494 }
495
496 // Deprecated: use runes.Remove instead.
497 func RemoveFunc(f func(r rune) bool) Transformer {
498         return removeF(f)
499 }
500
501 type removeF func(r rune) bool
502
503 func (removeF) Reset() {}
504
505 // Transform implements the Transformer interface.
506 func (t removeF) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
507         for r, sz := rune(0), 0; len(src) > 0; src = src[sz:] {
508
509                 if r = rune(src[0]); r < utf8.RuneSelf {
510                         sz = 1
511                 } else {
512                         r, sz = utf8.DecodeRune(src)
513
514                         if sz == 1 {
515                                 // Invalid rune.
516                                 if !atEOF && !utf8.FullRune(src) {
517                                         err = ErrShortSrc
518                                         break
519                                 }
520                                 // We replace illegal bytes with RuneError. Not doing so might
521                                 // otherwise turn a sequence of invalid UTF-8 into valid UTF-8.
522                                 // The resulting byte sequence may subsequently contain runes
523                                 // for which t(r) is true that were passed unnoticed.
524                                 if !t(r) {
525                                         if nDst+3 > len(dst) {
526                                                 err = ErrShortDst
527                                                 break
528                                         }
529                                         nDst += copy(dst[nDst:], "\uFFFD")
530                                 }
531                                 nSrc++
532                                 continue
533                         }
534                 }
535
536                 if !t(r) {
537                         if nDst+sz > len(dst) {
538                                 err = ErrShortDst
539                                 break
540                         }
541                         nDst += copy(dst[nDst:], src[:sz])
542                 }
543                 nSrc += sz
544         }
545         return
546 }
547
548 // grow returns a new []byte that is longer than b, and copies the first n bytes
549 // of b to the start of the new slice.
550 func grow(b []byte, n int) []byte {
551         m := len(b)
552         if m <= 32 {
553                 m = 64
554         } else if m <= 256 {
555                 m *= 2
556         } else {
557                 m += m >> 1
558         }
559         buf := make([]byte, m)
560         copy(buf, b[:n])
561         return buf
562 }
563
564 const initialBufSize = 128
565
566 // String returns a string with the result of converting s[:n] using t, where
567 // n <= len(s). If err == nil, n will be len(s). It calls Reset on t.
568 func String(t Transformer, s string) (result string, n int, err error) {
569         t.Reset()
570         if s == "" {
571                 // Fast path for the common case for empty input. Results in about a
572                 // 86% reduction of running time for BenchmarkStringLowerEmpty.
573                 if _, _, err := t.Transform(nil, nil, true); err == nil {
574                         return "", 0, nil
575                 }
576         }
577
578         // Allocate only once. Note that both dst and src escape when passed to
579         // Transform.
580         buf := [2 * initialBufSize]byte{}
581         dst := buf[:initialBufSize:initialBufSize]
582         src := buf[initialBufSize : 2*initialBufSize]
583
584         // The input string s is transformed in multiple chunks (starting with a
585         // chunk size of initialBufSize). nDst and nSrc are per-chunk (or
586         // per-Transform-call) indexes, pDst and pSrc are overall indexes.
587         nDst, nSrc := 0, 0
588         pDst, pSrc := 0, 0
589
590         // pPrefix is the length of a common prefix: the first pPrefix bytes of the
591         // result will equal the first pPrefix bytes of s. It is not guaranteed to
592         // be the largest such value, but if pPrefix, len(result) and len(s) are
593         // all equal after the final transform (i.e. calling Transform with atEOF
594         // being true returned nil error) then we don't need to allocate a new
595         // result string.
596         pPrefix := 0
597         for {
598                 // Invariant: pDst == pPrefix && pSrc == pPrefix.
599
600                 n := copy(src, s[pSrc:])
601                 nDst, nSrc, err = t.Transform(dst, src[:n], pSrc+n == len(s))
602                 pDst += nDst
603                 pSrc += nSrc
604
605                 // TODO:  let transformers implement an optional Spanner interface, akin
606                 // to norm's QuickSpan. This would even allow us to avoid any allocation.
607                 if !bytes.Equal(dst[:nDst], src[:nSrc]) {
608                         break
609                 }
610                 pPrefix = pSrc
611                 if err == ErrShortDst {
612                         // A buffer can only be short if a transformer modifies its input.
613                         break
614                 } else if err == ErrShortSrc {
615                         if nSrc == 0 {
616                                 // No progress was made.
617                                 break
618                         }
619                         // Equal so far and !atEOF, so continue checking.
620                 } else if err != nil || pPrefix == len(s) {
621                         return string(s[:pPrefix]), pPrefix, err
622                 }
623         }
624         // Post-condition: pDst == pPrefix + nDst && pSrc == pPrefix + nSrc.
625
626         // We have transformed the first pSrc bytes of the input s to become pDst
627         // transformed bytes. Those transformed bytes are discontiguous: the first
628         // pPrefix of them equal s[:pPrefix] and the last nDst of them equal
629         // dst[:nDst]. We copy them around, into a new dst buffer if necessary, so
630         // that they become one contiguous slice: dst[:pDst].
631         if pPrefix != 0 {
632                 newDst := dst
633                 if pDst > len(newDst) {
634                         newDst = make([]byte, len(s)+nDst-nSrc)
635                 }
636                 copy(newDst[pPrefix:pDst], dst[:nDst])
637                 copy(newDst[:pPrefix], s[:pPrefix])
638                 dst = newDst
639         }
640
641         // Prevent duplicate Transform calls with atEOF being true at the end of
642         // the input. Also return if we have an unrecoverable error.
643         if (err == nil && pSrc == len(s)) ||
644                 (err != nil && err != ErrShortDst && err != ErrShortSrc) {
645                 return string(dst[:pDst]), pSrc, err
646         }
647
648         // Transform the remaining input, growing dst and src buffers as necessary.
649         for {
650                 n := copy(src, s[pSrc:])
651                 nDst, nSrc, err := t.Transform(dst[pDst:], src[:n], pSrc+n == len(s))
652                 pDst += nDst
653                 pSrc += nSrc
654
655                 // If we got ErrShortDst or ErrShortSrc, do not grow as long as we can
656                 // make progress. This may avoid excessive allocations.
657                 if err == ErrShortDst {
658                         if nDst == 0 {
659                                 dst = grow(dst, pDst)
660                         }
661                 } else if err == ErrShortSrc {
662                         if nSrc == 0 {
663                                 src = grow(src, 0)
664                         }
665                 } else if err != nil || pSrc == len(s) {
666                         return string(dst[:pDst]), pSrc, err
667                 }
668         }
669 }
670
671 // Bytes returns a new byte slice with the result of converting b[:n] using t,
672 // where n <= len(b). If err == nil, n will be len(b). It calls Reset on t.
673 func Bytes(t Transformer, b []byte) (result []byte, n int, err error) {
674         return doAppend(t, 0, make([]byte, len(b)), b)
675 }
676
677 // Append appends the result of converting src[:n] using t to dst, where
678 // n <= len(src), If err == nil, n will be len(src). It calls Reset on t.
679 func Append(t Transformer, dst, src []byte) (result []byte, n int, err error) {
680         if len(dst) == cap(dst) {
681                 n := len(src) + len(dst) // It is okay for this to be 0.
682                 b := make([]byte, n)
683                 dst = b[:copy(b, dst)]
684         }
685         return doAppend(t, len(dst), dst[:cap(dst)], src)
686 }
687
688 func doAppend(t Transformer, pDst int, dst, src []byte) (result []byte, n int, err error) {
689         t.Reset()
690         pSrc := 0
691         for {
692                 nDst, nSrc, err := t.Transform(dst[pDst:], src[pSrc:], true)
693                 pDst += nDst
694                 pSrc += nSrc
695                 if err != ErrShortDst {
696                         return dst[:pDst], pSrc, err
697                 }
698
699                 // Grow the destination buffer, but do not grow as long as we can make
700                 // progress. This may avoid excessive allocations.
701                 if nDst == 0 {
702                         dst = grow(dst, pDst)
703                 }
704         }
705 }