cford32.gno

18.84 Kb ยท 704 lines
  1// Modified from the Go Source code for encoding/base32.
  2// Copyright 2009 The Go Authors. All rights reserved.
  3// Use of this source code is governed by a BSD-style
  4// license that can be found in the LICENSE file.
  5
  6// Package cford32 implements a base32-like encoding/decoding package, with the
  7// encoding scheme [specified by Douglas Crockford].
  8//
  9// From the website, the requirements of said encoding scheme are to:
 10//
 11//   - Be human readable and machine readable.
 12//   - Be compact. Humans have difficulty in manipulating long strings of arbitrary symbols.
 13//   - Be error resistant. Entering the symbols must not require keyboarding gymnastics.
 14//   - Be pronounceable. Humans should be able to accurately transmit the symbols to other humans using a telephone.
 15//
 16// This is slightly different from a simple difference in encoding table from
 17// the Go's stdlib `encoding/base32`, as when decoding the characters i I l L are
 18// parsed as 1, and o O is parsed as 0.
 19//
 20// This package additionally provides ways to encode uint64's efficiently,
 21// as well as efficient encoding to a lowercase variation of the encoding.
 22// The encodings never use paddings.
 23//
 24// # Uint64 Encoding
 25//
 26// Aside from lower/uppercase encoding, there is a compact encoding, allowing
 27// to encode all values in [0,2^34), and the full encoding, allowing all
 28// values in [0,2^64). The compact encoding uses 7 characters, and the full
 29// encoding uses 13 characters. Both are parsed unambiguously by the Uint64
 30// decoder.
 31//
 32// The compact encodings have the first character between ['0','f'], while the
 33// full encoding's first character ranges between ['g','z']. Practically, in
 34// your usage of the package, you should consider which one to use and stick
 35// with it, while considering that the compact encoding, once it reaches 2^34,
 36// automatically switches to the full encoding. The properties of the generated
 37// strings are still maintained: for instance, any two encoded uint64s x,y
 38// consistently generated with the compact encoding, if the numeric value is
 39// x < y, will also be x < y in lexical ordering. However, values [0,2^34) have a
 40// "double encoding", which if mixed together lose the lexical ordering property.
 41//
 42// The Uint64 encoding is most useful for generating string versions of Uint64
 43// IDs. Practically, it allows you to retain sleek and compact IDs for your
 44// application for the first 2^34 (>17 billion) entities, while seamlessly
 45// rolling over to the full encoding should you exceed that. You are encouraged
 46// to use it unless you have a requirement or preferences for IDs consistently
 47// being always the same size.
 48//
 49// To use the cford32 encoding for IDs, you may want to consider using package
 50// [gno.land/p/demo/seqid].
 51//
 52// [specified by Douglas Crockford]: https://www.crockford.com/base32.html
 53package cford32
 54
 55import (
 56	"io"
 57	"strconv"
 58)
 59
 60const (
 61	encTable      = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"
 62	encTableLower = "0123456789abcdefghjkmnpqrstvwxyz"
 63
 64	// each line is 16 bytes
 65	decTable = "" +
 66		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + // 00-0f
 67		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + // 10-1f
 68		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + // 20-2f
 69		"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\xff\xff\xff\xff\xff\xff" + // 30-3f
 70		"\xff\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x01\x12\x13\x01\x14\x15\x00" + // 40-4f
 71		"\x16\x17\x18\x19\x1a\xff\x1b\x1c\x1d\x1e\x1f\xff\xff\xff\xff\xff" + // 50-5f
 72		"\xff\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x01\x12\x13\x01\x14\x15\x00" + // 60-6f
 73		"\x16\x17\x18\x19\x1a\xff\x1b\x1c\x1d\x1e\x1f\xff\xff\xff\xff\xff" + // 70-7f
 74		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + // 80-ff (not ASCII)
 75		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
 76		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
 77		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
 78		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
 79		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
 80		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +
 81		"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
 82)
 83
 84// CorruptInputError is returned by parsing functions when an invalid character
 85// in the input is found. The integer value represents the byte index where
 86// the error occurred.
 87//
 88// This is typically because the given character does not exist in the encoding.
 89type CorruptInputError int64
 90
 91func (e CorruptInputError) Error() string {
 92	return "illegal cford32 data at input byte " + strconv.FormatInt(int64(e), 10)
 93}
 94
 95// Uint64 parses a cford32-encoded byte slice into a uint64.
 96//
 97//   - The parser requires all provided character to be valid cford32 characters.
 98//   - The parser disregards case.
 99//   - If the first character is '0' <= c <= 'f', then the passed value is assumed
100//     encoded in the compact encoding, and must be 7 characters long.
101//   - If the first character is 'g' <= c <= 'z',  then the passed value is
102//     assumed encoded in the full encoding, and must be 13 characters long.
103//
104// If any of these requirements fail, a CorruptInputError will be returned.
105func Uint64(b []byte) (uint64, error) {
106	if len(b) == 0 {
107		return 0, CorruptInputError(0)
108	}
109	b0 := decTable[b[0]]
110	switch {
111	default:
112		return 0, CorruptInputError(0)
113	case len(b) == 7 && b0 < 16:
114		decVals := [7]byte{
115			decTable[b[0]],
116			decTable[b[1]],
117			decTable[b[2]],
118			decTable[b[3]],
119			decTable[b[4]],
120			decTable[b[5]],
121			decTable[b[6]],
122		}
123		for idx, v := range decVals {
124			if v >= 32 {
125				return 0, CorruptInputError(idx)
126			}
127		}
128
129		return 0 +
130			uint64(decVals[0])<<30 |
131			uint64(decVals[1])<<25 |
132			uint64(decVals[2])<<20 |
133			uint64(decVals[3])<<15 |
134			uint64(decVals[4])<<10 |
135			uint64(decVals[5])<<5 |
136			uint64(decVals[6]), nil
137	case len(b) == 13 && b0 >= 16 && b0 < 32:
138		decVals := [13]byte{
139			decTable[b[0]] & 0x0F, // disregard high bit
140			decTable[b[1]],
141			decTable[b[2]],
142			decTable[b[3]],
143			decTable[b[4]],
144			decTable[b[5]],
145			decTable[b[6]],
146			decTable[b[7]],
147			decTable[b[8]],
148			decTable[b[9]],
149			decTable[b[10]],
150			decTable[b[11]],
151			decTable[b[12]],
152		}
153		for idx, v := range decVals {
154			if v >= 32 {
155				return 0, CorruptInputError(idx)
156			}
157		}
158
159		return 0 +
160			uint64(decVals[0])<<60 |
161			uint64(decVals[1])<<55 |
162			uint64(decVals[2])<<50 |
163			uint64(decVals[3])<<45 |
164			uint64(decVals[4])<<40 |
165			uint64(decVals[5])<<35 |
166			uint64(decVals[6])<<30 |
167			uint64(decVals[7])<<25 |
168			uint64(decVals[8])<<20 |
169			uint64(decVals[9])<<15 |
170			uint64(decVals[10])<<10 |
171			uint64(decVals[11])<<5 |
172			uint64(decVals[12]), nil
173	}
174}
175
176const mask = 31
177
178// PutUint64 returns a cford32-encoded byte slice.
179func PutUint64(id uint64) [13]byte {
180	return [13]byte{
181		encTable[id>>60&mask|0x10], // specify full encoding
182		encTable[id>>55&mask],
183		encTable[id>>50&mask],
184		encTable[id>>45&mask],
185		encTable[id>>40&mask],
186		encTable[id>>35&mask],
187		encTable[id>>30&mask],
188		encTable[id>>25&mask],
189		encTable[id>>20&mask],
190		encTable[id>>15&mask],
191		encTable[id>>10&mask],
192		encTable[id>>5&mask],
193		encTable[id&mask],
194	}
195}
196
197// PutUint64Lower returns a cford32-encoded byte array, swapping uppercase
198// letters with lowercase.
199//
200// For more information on how the value is encoded, see [Uint64].
201func PutUint64Lower(id uint64) [13]byte {
202	return [13]byte{
203		encTableLower[id>>60&mask|0x10],
204		encTableLower[id>>55&mask],
205		encTableLower[id>>50&mask],
206		encTableLower[id>>45&mask],
207		encTableLower[id>>40&mask],
208		encTableLower[id>>35&mask],
209		encTableLower[id>>30&mask],
210		encTableLower[id>>25&mask],
211		encTableLower[id>>20&mask],
212		encTableLower[id>>15&mask],
213		encTableLower[id>>10&mask],
214		encTableLower[id>>5&mask],
215		encTableLower[id&mask],
216	}
217}
218
219// PutCompact returns a cford32-encoded byte slice, using the compact
220// representation of cford32 described in the package documentation where
221// possible (all values of id < 1<<34). The lowercase encoding is used.
222//
223// The resulting byte slice will be 7 bytes long for all compact values,
224// and 13 bytes long for
225func PutCompact(id uint64) []byte {
226	return AppendCompact(id, nil)
227}
228
229// AppendCompact works like [PutCompact] but appends to the given byte slice
230// instead of allocating one anew.
231func AppendCompact(id uint64, b []byte) []byte {
232	const maxCompact = 1 << 34
233	if id < maxCompact {
234		return append(b,
235			encTableLower[id>>30&mask],
236			encTableLower[id>>25&mask],
237			encTableLower[id>>20&mask],
238			encTableLower[id>>15&mask],
239			encTableLower[id>>10&mask],
240			encTableLower[id>>5&mask],
241			encTableLower[id&mask],
242		)
243	}
244	return append(b,
245		encTableLower[id>>60&mask|0x10],
246		encTableLower[id>>55&mask],
247		encTableLower[id>>50&mask],
248		encTableLower[id>>45&mask],
249		encTableLower[id>>40&mask],
250		encTableLower[id>>35&mask],
251		encTableLower[id>>30&mask],
252		encTableLower[id>>25&mask],
253		encTableLower[id>>20&mask],
254		encTableLower[id>>15&mask],
255		encTableLower[id>>10&mask],
256		encTableLower[id>>5&mask],
257		encTableLower[id&mask],
258	)
259}
260
261func DecodedLen(n int) int {
262	return n/8*5 + n%8*5/8
263}
264
265func EncodedLen(n int) int {
266	return n/5*8 + (n%5*8+4)/5
267}
268
269// Encode encodes src using the encoding enc,
270// writing [EncodedLen](len(src)) bytes to dst.
271//
272// The encoding does not contain any padding, unlike Go's base32.
273func Encode(dst, src []byte) {
274	// Copied from encoding/base32/base32.go (go1.22)
275	if len(src) == 0 {
276		return
277	}
278
279	di, si := 0, 0
280	n := (len(src) / 5) * 5
281	for si < n {
282		// Combining two 32 bit loads allows the same code to be used
283		// for 32 and 64 bit platforms.
284		hi := uint32(src[si+0])<<24 | uint32(src[si+1])<<16 | uint32(src[si+2])<<8 | uint32(src[si+3])
285		lo := hi<<8 | uint32(src[si+4])
286
287		dst[di+0] = encTable[(hi>>27)&0x1F]
288		dst[di+1] = encTable[(hi>>22)&0x1F]
289		dst[di+2] = encTable[(hi>>17)&0x1F]
290		dst[di+3] = encTable[(hi>>12)&0x1F]
291		dst[di+4] = encTable[(hi>>7)&0x1F]
292		dst[di+5] = encTable[(hi>>2)&0x1F]
293		dst[di+6] = encTable[(lo>>5)&0x1F]
294		dst[di+7] = encTable[(lo)&0x1F]
295
296		si += 5
297		di += 8
298	}
299
300	// Add the remaining small block
301	remain := len(src) - si
302	if remain == 0 {
303		return
304	}
305
306	// Encode the remaining bytes in reverse order.
307	val := uint32(0)
308	switch remain {
309	case 4:
310		val |= uint32(src[si+3])
311		dst[di+6] = encTable[val<<3&0x1F]
312		dst[di+5] = encTable[val>>2&0x1F]
313		fallthrough
314	case 3:
315		val |= uint32(src[si+2]) << 8
316		dst[di+4] = encTable[val>>7&0x1F]
317		fallthrough
318	case 2:
319		val |= uint32(src[si+1]) << 16
320		dst[di+3] = encTable[val>>12&0x1F]
321		dst[di+2] = encTable[val>>17&0x1F]
322		fallthrough
323	case 1:
324		val |= uint32(src[si+0]) << 24
325		dst[di+1] = encTable[val>>22&0x1F]
326		dst[di+0] = encTable[val>>27&0x1F]
327	}
328}
329
330// EncodeLower is like [Encode], but uses the lowercase
331func EncodeLower(dst, src []byte) {
332	// Copied from encoding/base32/base32.go (go1.22)
333	if len(src) == 0 {
334		return
335	}
336
337	di, si := 0, 0
338	n := (len(src) / 5) * 5
339	for si < n {
340		// Combining two 32 bit loads allows the same code to be used
341		// for 32 and 64 bit platforms.
342		hi := uint32(src[si+0])<<24 | uint32(src[si+1])<<16 | uint32(src[si+2])<<8 | uint32(src[si+3])
343		lo := hi<<8 | uint32(src[si+4])
344
345		dst[di+0] = encTableLower[(hi>>27)&0x1F]
346		dst[di+1] = encTableLower[(hi>>22)&0x1F]
347		dst[di+2] = encTableLower[(hi>>17)&0x1F]
348		dst[di+3] = encTableLower[(hi>>12)&0x1F]
349		dst[di+4] = encTableLower[(hi>>7)&0x1F]
350		dst[di+5] = encTableLower[(hi>>2)&0x1F]
351		dst[di+6] = encTableLower[(lo>>5)&0x1F]
352		dst[di+7] = encTableLower[(lo)&0x1F]
353
354		si += 5
355		di += 8
356	}
357
358	// Add the remaining small block
359	remain := len(src) - si
360	if remain == 0 {
361		return
362	}
363
364	// Encode the remaining bytes in reverse order.
365	val := uint32(0)
366	switch remain {
367	case 4:
368		val |= uint32(src[si+3])
369		dst[di+6] = encTableLower[val<<3&0x1F]
370		dst[di+5] = encTableLower[val>>2&0x1F]
371		fallthrough
372	case 3:
373		val |= uint32(src[si+2]) << 8
374		dst[di+4] = encTableLower[val>>7&0x1F]
375		fallthrough
376	case 2:
377		val |= uint32(src[si+1]) << 16
378		dst[di+3] = encTableLower[val>>12&0x1F]
379		dst[di+2] = encTableLower[val>>17&0x1F]
380		fallthrough
381	case 1:
382		val |= uint32(src[si+0]) << 24
383		dst[di+1] = encTableLower[val>>22&0x1F]
384		dst[di+0] = encTableLower[val>>27&0x1F]
385	}
386}
387
388// AppendEncode appends the cford32 encoded src to dst
389// and returns the extended buffer.
390func AppendEncode(dst, src []byte) []byte {
391	n := EncodedLen(len(src))
392	dst = grow(dst, n)
393	Encode(dst[len(dst):][:n], src)
394	return dst[:len(dst)+n]
395}
396
397// AppendEncodeLower appends the lowercase cford32 encoded src to dst
398// and returns the extended buffer.
399func AppendEncodeLower(dst, src []byte) []byte {
400	n := EncodedLen(len(src))
401	dst = grow(dst, n)
402	EncodeLower(dst[len(dst):][:n], src)
403	return dst[:len(dst)+n]
404}
405
406func grow(s []byte, n int) []byte {
407	// slices.Grow
408	if n -= cap(s) - len(s); n > 0 {
409		news := make([]byte, cap(s)+n)
410		copy(news[:cap(s)], s[:cap(s)])
411		return news[:len(s)]
412	}
413	return s
414}
415
416// EncodeToString returns the cford32 encoding of src.
417func EncodeToString(src []byte) string {
418	buf := make([]byte, EncodedLen(len(src)))
419	Encode(buf, src)
420	return string(buf)
421}
422
423// EncodeToStringLower returns the cford32 lowercase encoding of src.
424func EncodeToStringLower(src []byte) string {
425	buf := make([]byte, EncodedLen(len(src)))
426	EncodeLower(buf, src)
427	return string(buf)
428}
429
430func decode(dst, src []byte) (n int, err error) {
431	dsti := 0
432	olen := len(src)
433
434	for len(src) > 0 {
435		// Decode quantum using the base32 alphabet
436		var dbuf [8]byte
437		dlen := 8
438
439		for j := 0; j < 8; {
440			if len(src) == 0 {
441				// We have reached the end and are not expecting any padding
442				dlen = j
443				break
444			}
445			in := src[0]
446			src = src[1:]
447			dbuf[j] = decTable[in]
448			if dbuf[j] == 0xFF {
449				return n, CorruptInputError(olen - len(src) - 1)
450			}
451			j++
452		}
453
454		// Pack 8x 5-bit source blocks into 5 byte destination
455		// quantum
456		switch dlen {
457		case 8:
458			dst[dsti+4] = dbuf[6]<<5 | dbuf[7]
459			n++
460			fallthrough
461		case 7:
462			dst[dsti+3] = dbuf[4]<<7 | dbuf[5]<<2 | dbuf[6]>>3
463			n++
464			fallthrough
465		case 5:
466			dst[dsti+2] = dbuf[3]<<4 | dbuf[4]>>1
467			n++
468			fallthrough
469		case 4:
470			dst[dsti+1] = dbuf[1]<<6 | dbuf[2]<<1 | dbuf[3]>>4
471			n++
472			fallthrough
473		case 2:
474			dst[dsti+0] = dbuf[0]<<3 | dbuf[1]>>2
475			n++
476		}
477		dsti += 5
478	}
479	return n, nil
480}
481
482type encoder struct {
483	err  error
484	w    io.Writer
485	enc  func(dst, src []byte)
486	buf  [5]byte    // buffered data waiting to be encoded
487	nbuf int        // number of bytes in buf
488	out  [1024]byte // output buffer
489}
490
491func NewEncoder(w io.Writer) io.WriteCloser {
492	return &encoder{w: w, enc: Encode}
493}
494
495func NewEncoderLower(w io.Writer) io.WriteCloser {
496	return &encoder{w: w, enc: EncodeLower}
497}
498
499func (e *encoder) Write(p []byte) (n int, err error) {
500	if e.err != nil {
501		return 0, e.err
502	}
503
504	// Leading fringe.
505	if e.nbuf > 0 {
506		var i int
507		for i = 0; i < len(p) && e.nbuf < 5; i++ {
508			e.buf[e.nbuf] = p[i]
509			e.nbuf++
510		}
511		n += i
512		p = p[i:]
513		if e.nbuf < 5 {
514			return
515		}
516		e.enc(e.out[0:], e.buf[0:])
517		if _, e.err = e.w.Write(e.out[0:8]); e.err != nil {
518			return n, e.err
519		}
520		e.nbuf = 0
521	}
522
523	// Large interior chunks.
524	for len(p) >= 5 {
525		nn := len(e.out) / 8 * 5
526		if nn > len(p) {
527			nn = len(p)
528			nn -= nn % 5
529		}
530		e.enc(e.out[0:], p[0:nn])
531		if _, e.err = e.w.Write(e.out[0 : nn/5*8]); e.err != nil {
532			return n, e.err
533		}
534		n += nn
535		p = p[nn:]
536	}
537
538	// Trailing fringe.
539	copy(e.buf[:], p)
540	e.nbuf = len(p)
541	n += len(p)
542	return
543}
544
545// Close flushes any pending output from the encoder.
546// It is an error to call Write after calling Close.
547func (e *encoder) Close() error {
548	// If there's anything left in the buffer, flush it out
549	if e.err == nil && e.nbuf > 0 {
550		e.enc(e.out[0:], e.buf[0:e.nbuf])
551		encodedLen := EncodedLen(e.nbuf)
552		e.nbuf = 0
553		_, e.err = e.w.Write(e.out[0:encodedLen])
554	}
555	return e.err
556}
557
558// Decode decodes src using cford32. It writes at most
559// [DecodedLen](len(src)) bytes to dst and returns the number of bytes
560// written. If src contains invalid cford32 data, it will return the
561// number of bytes successfully written and [CorruptInputError].
562// Newline characters (\r and \n) are ignored.
563func Decode(dst, src []byte) (n int, err error) {
564	buf := make([]byte, len(src))
565	l := stripNewlines(buf, src)
566	return decode(dst, buf[:l])
567}
568
569// AppendDecode appends the cford32 decoded src to dst
570// and returns the extended buffer.
571// If the input is malformed, it returns the partially decoded src and an error.
572func AppendDecode(dst, src []byte) ([]byte, error) {
573	n := DecodedLen(len(src))
574
575	dst = grow(dst, n)
576	dstsl := dst[len(dst) : len(dst)+n]
577	n, err := Decode(dstsl, src)
578	return dst[:len(dst)+n], err
579}
580
581// DecodeString returns the bytes represented by the cford32 string s.
582func DecodeString(s string) ([]byte, error) {
583	buf := []byte(s)
584	l := stripNewlines(buf, buf)
585	n, err := decode(buf, buf[:l])
586	return buf[:n], err
587}
588
589// stripNewlines removes newline characters and returns the number
590// of non-newline characters copied to dst.
591func stripNewlines(dst, src []byte) int {
592	offset := 0
593	for _, b := range src {
594		if b == '\r' || b == '\n' {
595			continue
596		}
597		dst[offset] = b
598		offset++
599	}
600	return offset
601}
602
603type decoder struct {
604	err    error
605	r      io.Reader
606	buf    [1024]byte // leftover input
607	nbuf   int
608	out    []byte // leftover decoded output
609	outbuf [1024 / 8 * 5]byte
610}
611
612// NewDecoder constructs a new base32 stream decoder.
613func NewDecoder(r io.Reader) io.Reader {
614	return &decoder{r: &newlineFilteringReader{r}}
615}
616
617func readEncodedData(r io.Reader, buf []byte) (n int, err error) {
618	for n < 1 && err == nil {
619		var nn int
620		nn, err = r.Read(buf[n:])
621		n += nn
622	}
623	return
624}
625
626func (d *decoder) Read(p []byte) (n int, err error) {
627	// Use leftover decoded output from last read.
628	if len(d.out) > 0 {
629		n = copy(p, d.out)
630		d.out = d.out[n:]
631		if len(d.out) == 0 {
632			return n, d.err
633		}
634		return n, nil
635	}
636
637	if d.err != nil {
638		return 0, d.err
639	}
640
641	// Read nn bytes from input, bounded [8,len(d.buf)]
642	nn := (len(p)/5 + 1) * 8
643	if nn > len(d.buf) {
644		nn = len(d.buf)
645	}
646
647	nn, d.err = readEncodedData(d.r, d.buf[d.nbuf:nn])
648	d.nbuf += nn
649	if d.nbuf < 1 {
650		return 0, d.err
651	}
652
653	// Decode chunk into p, or d.out and then p if p is too small.
654	nr := d.nbuf
655	if d.err != io.EOF && nr%8 != 0 {
656		nr -= nr % 8
657	}
658	nw := DecodedLen(d.nbuf)
659
660	if nw > len(p) {
661		nw, err = decode(d.outbuf[0:], d.buf[0:nr])
662		d.out = d.outbuf[0:nw]
663		n = copy(p, d.out)
664		d.out = d.out[n:]
665	} else {
666		n, err = decode(p, d.buf[0:nr])
667	}
668	d.nbuf -= nr
669	for i := 0; i < d.nbuf; i++ {
670		d.buf[i] = d.buf[i+nr]
671	}
672
673	if err != nil && (d.err == nil || d.err == io.EOF) {
674		d.err = err
675	}
676
677	if len(d.out) > 0 {
678		// We cannot return all the decoded bytes to the caller in this
679		// invocation of Read, so we return a nil error to ensure that Read
680		// will be called again.  The error stored in d.err, if any, will be
681		// returned with the last set of decoded bytes.
682		return n, nil
683	}
684
685	return n, d.err
686}
687
688type newlineFilteringReader struct {
689	wrapped io.Reader
690}
691
692func (r *newlineFilteringReader) Read(p []byte) (int, error) {
693	n, err := r.wrapped.Read(p)
694	for n > 0 {
695		s := p[0:n]
696		offset := stripNewlines(s, s)
697		if err != nil || offset > 0 {
698			return offset, err
699		}
700		// Previous buffer entirely whitespace, read again
701		n, err = r.wrapped.Read(p)
702	}
703	return n, err
704}