all repos

rss-tools @ a5ac527

get rss feed from sources that(i need and) dont provide one

rss-tools/vendor/golang.org/x/text/transform/transform.go (view raw)

Oleksandr Smirnov Oleksandr Smirnov
olexsmir@gmail.com
we're vendoring now, 7 days ago
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: 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
		atEOF := pSrc+n == len(s)
652
		nDst, nSrc, err := t.Transform(dst[pDst:], src[:n], atEOF)
653
		pDst += nDst
654
		pSrc += nSrc
655
656
		// If we got ErrShortDst or ErrShortSrc, do not grow as long as we can
657
		// make progress. This may avoid excessive allocations.
658
		if err == ErrShortDst {
659
			if nDst == 0 {
660
				dst = grow(dst, pDst)
661
			}
662
		} else if err == ErrShortSrc {
663
			if atEOF {
664
				return string(dst[:pDst]), pSrc, err
665
			}
666
			if nSrc == 0 {
667
				src = grow(src, 0)
668
			}
669
		} else if err != nil || pSrc == len(s) {
670
			return string(dst[:pDst]), pSrc, err
671
		}
672
	}
673
}
674
675
// Bytes returns a new byte slice with the result of converting b[:n] using t,
676
// where n <= len(b). If err == nil, n will be len(b). It calls Reset on t.
677
func Bytes(t Transformer, b []byte) (result []byte, n int, err error) {
678
	return doAppend(t, 0, make([]byte, len(b)), b)
679
}
680
681
// Append appends the result of converting src[:n] using t to dst, where
682
// n <= len(src), If err == nil, n will be len(src). It calls Reset on t.
683
func Append(t Transformer, dst, src []byte) (result []byte, n int, err error) {
684
	if len(dst) == cap(dst) {
685
		n := len(src) + len(dst) // It is okay for this to be 0.
686
		b := make([]byte, n)
687
		dst = b[:copy(b, dst)]
688
	}
689
	return doAppend(t, len(dst), dst[:cap(dst)], src)
690
}
691
692
func doAppend(t Transformer, pDst int, dst, src []byte) (result []byte, n int, err error) {
693
	t.Reset()
694
	pSrc := 0
695
	for {
696
		nDst, nSrc, err := t.Transform(dst[pDst:], src[pSrc:], true)
697
		pDst += nDst
698
		pSrc += nSrc
699
		if err != ErrShortDst {
700
			return dst[:pDst], pSrc, err
701
		}
702
703
		// Grow the destination buffer, but do not grow as long as we can make
704
		// progress. This may avoid excessive allocations.
705
		if nDst == 0 {
706
			dst = grow(dst, pDst)
707
		}
708
	}
709
}