You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

706 lines
22 KiB

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