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 quotedprintableimportconst 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 boolw io.Writeri intline [78]bytecr 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 >= '!' && <= '~' && != '=':continuecase 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 = falsecontinue}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 += 3return 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 += 2return .flush()}func ( *Writer) () error {if , := .w.Write(.line[:.i]); != nil {return}.i = 0return nil}func ( byte) bool {return == ' ' || == '\t'}