func NewDecoder(r io.Reader) io.Reader {
	return &qpReader{br: bufio.NewReader(r)}
}
NewDecoder returns a new quoted-printable stream decoder.
package quotedprintable
import (
	"bufio"
	"bytes"
	"fmt"
	"io"
)
func Encode(dst, src []byte) (n int) {
	for i := 0; i < len(src); i++ {
		switch c := src[i]; {
		case c != '=' && (isVchar(c) || isNewline(c)):
			dst[n] = c
			n++
		case isWSP(c):
			if isLastChar(i, src) {
				encodeByte(dst[n:], c)
				n += 3
			} else {
				dst[n] = c
				n++
			}
		default:
			encodeByte(dst[n:], c)
			n += 3
		}
	}
	return n
}
func isLastChar(i int, src []byte) bool {
	if i == len(src)-1 ||
		(i < len(src)-1 && src[i+1] == '\n') ||
		(i < len(src)-2 && src[i+1] == '\r' && src[i+2] == '\n') {
		return true
	}
	return false
}
func encodeByte(dst []byte, b byte) {
	dst[0] = '='
	dst[1] = hextable[b>>4]
	dst[2] = hextable[b&0x0f]
}
const hextable = "0123456789ABCDEF"
func EncodeToString(src []byte) string {
	dbuf := make([]byte, MaxEncodedLen(len(src)))
	n := Encode(dbuf, src)
	return string(dbuf[:n])
}
func MaxEncodedLen(n int) int { return 3 * n }
func NewEncoder(w io.Writer) io.Writer {
	return &encoder{w}
}
type encoder struct {
	w io.Writer
}
func (e *encoder) Write(p []byte) (int, error) {
	dbuf := make([]byte, MaxEncodedLen(len(p)))
	n := Encode(dbuf, p)
	n, err := e.w.Write(dbuf[:n])
	if err != nil {
		nn := 0
		for i := 0; i < n; i++ {
			if dbuf[i] == '=' {
				if i+2 >= n {
					break
				}
				i += 2
			}
			nn++
		}
		return nn, err
	}
	return len(p), nil
}
func Decode(dst, src []byte) (n int, err error) {
	var eol, trimLen, eolLen int
	for i := 0; i < len(src); i++ {
		if i == eol {
			eol = bytes.IndexByte(src[i:], '\n') + i + 1
			if eol == i {
				eol = len(src)
				eolLen = 0
			} else if eol-2 >= i && src[eol-2] == '\r' {
				eolLen = 2
			} else {
				eolLen = 1
			}
			trimLen = 0
			for {
				if trimLen == eol-eolLen-i {
					break
				}
				switch src[eol-eolLen-trimLen-1] {
				case '\n', '\r', ' ', '\t':
					trimLen++
					continue
				case '=':
					if trimLen > 0 {
						trimLen += eolLen + 1
						eolLen = 0
						err = fmt.Errorf("quotedprintable: invalid bytes after =: %q", src[eol-trimLen+1:eol])
					} else {
						trimLen = eolLen + 1
						eolLen = 0
					}
				}
				break
			}
		}
		if trimLen > 0 && i == eol-trimLen-eolLen {
			if err != nil {
				return n, err
			}
			i += trimLen - 1
			continue
		}
		switch c := src[i]; {
		case c == '=':
			if i+2 >= len(src) {
				return n, io.ErrUnexpectedEOF
			}
			b, convErr := readHexByte(src[i+1:])
			if convErr != nil {
				return n, convErr
			}
			dst[n] = b
			n++
			i += 2
		case (c >= ' ' && c <= '~') || c == '\n' || c == '\r' || c == '\t':
			dst[n] = c
			n++
		default:
			return n, fmt.Errorf("quotedprintable: invalid unescaped byte 0x%02x in quoted-printable body", c)
		}
	}
	return n, nil
}
func MaxDecodedLen(n int) int { return n }
func DecodeString(s string) ([]byte, error) {
	dbuf := make([]byte, MaxDecodedLen(len(s)))
	n, err := Decode(dbuf, []byte(s))
	return dbuf[:n], err
}