Source File
writer.go
Belonging Package
mime/quotedprintable
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package quotedprintable
import
const lineMaxLen = 76
// A Writer is a quoted-printable writer that implements [io.WriteCloser].
type Writer struct {
// Binary mode treats the writer's input as pure binary and processes end of
// line bytes as binary data.
Binary bool
w io.Writer
i int
line [78]byte
cr bool
}
// NewWriter returns a new [Writer] that writes to w.
func ( io.Writer) *Writer {
return &Writer{w: }
}
// Write encodes p using quoted-printable encoding and writes it to the
// underlying [io.Writer]. It limits line length to 76 characters. The encoded
// bytes are not necessarily flushed until the [Writer] is closed.
func ( *Writer) ( []byte) ( int, error) {
for , := range {
switch {
// Simple writes are done in batch.
case >= '!' && <= '~' && != '=':
continue
case isWhitespace() || !.Binary && ( == '\n' || == '\r'):
continue
}
if > {
if := .write([:]); != nil {
return ,
}
=
}
if := .encode(); != nil {
return ,
}
++
}
if == len() {
return , nil
}
if := .write([:]); != nil {
return ,
}
return len(), nil
}
// Close closes the [Writer], flushing any unwritten data to the underlying
// [io.Writer], but does not close the underlying io.Writer.
func ( *Writer) () error {
if := .checkLastByte(); != nil {
return
}
return .flush()
}
// write limits text encoded in quoted-printable to 76 characters per line.
func ( *Writer) ( []byte) error {
for , := range {
if == '\n' || == '\r' {
// If the previous byte was \r, the CRLF has already been inserted.
if .cr && == '\n' {
.cr = false
continue
}
if == '\r' {
.cr = true
}
if := .checkLastByte(); != nil {
return
}
if := .insertCRLF(); != nil {
return
}
continue
}
if .i == lineMaxLen-1 {
if := .insertSoftLineBreak(); != nil {
return
}
}
.line[.i] =
.i++
.cr = false
}
return nil
}
func ( *Writer) ( byte) error {
if lineMaxLen-1-.i < 3 {
if := .insertSoftLineBreak(); != nil {
return
}
}
.line[.i] = '='
.line[.i+1] = upperhex[>>4]
.line[.i+2] = upperhex[&0x0f]
.i += 3
return nil
}
const upperhex = "0123456789ABCDEF"
// checkLastByte encodes the last buffered byte if it is a space or a tab.
func ( *Writer) () error {
if .i == 0 {
return nil
}
:= .line[.i-1]
if isWhitespace() {
.i--
if := .encode(); != nil {
return
}
}
return nil
}
func ( *Writer) () error {
.line[.i] = '='
.i++
return .insertCRLF()
}
func ( *Writer) () error {
.line[.i] = '\r'
.line[.i+1] = '\n'
.i += 2
return .flush()
}
func ( *Writer) () error {
if , := .w.Write(.line[:.i]); != nil {
return
}
.i = 0
return nil
}
func isWhitespace( byte) bool {
return == ' ' || == '\t'
}
The pages are generated with Golds v0.7.0-preview. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |