Source File
writer.go
Belonging Package
net/textproto
// Copyright 2010 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 textprotoimport ()// A Writer implements convenience methods for writing// requests or responses to a text protocol network connection.type Writer struct {W *bufio.Writerdot *dotWriter}// NewWriter returns a new Writer writing to w.func ( *bufio.Writer) *Writer {return &Writer{W: }}var crnl = []byte{'\r', '\n'}var dotcrnl = []byte{'.', '\r', '\n'}// PrintfLine writes the formatted output followed by \r\n.func ( *Writer) ( string, ...interface{}) error {.closeDot()fmt.Fprintf(.W, , ...).W.Write(crnl)return .W.Flush()}// DotWriter returns a writer that can be used to write a dot-encoding to w.// It takes care of inserting leading dots when necessary,// translating line-ending \n into \r\n, and adding the final .\r\n line// when the DotWriter is closed. The caller should close the// DotWriter before the next call to a method on w.//// See the documentation for Reader's DotReader method for details about dot-encoding.func ( *Writer) () io.WriteCloser {.closeDot().dot = &dotWriter{w: }return .dot}func ( *Writer) () {if .dot != nil {.dot.Close() // sets w.dot = nil}}type dotWriter struct {w *Writerstate int}const (wstateBegin = iota // initial state; must be zerowstateBeginLine // beginning of linewstateCR // wrote \r (possibly at end of line)wstateData // writing data in middle of line)func ( *dotWriter) ( []byte) ( int, error) {:= .w.Wfor < len() {:= []switch .state {case wstateBegin, wstateBeginLine:.state = wstateDataif == '.' {// escape leading dot.WriteByte('.')}fallthroughcase wstateData:if == '\r' {.state = wstateCR}if == '\n' {.WriteByte('\r').state = wstateBeginLine}case wstateCR:.state = wstateDataif == '\n' {.state = wstateBeginLine}}if = .WriteByte(); != nil {break}++}return}func ( *dotWriter) () error {if .w.dot == {.w.dot = nil}:= .w.Wswitch .state {default:.WriteByte('\r')fallthroughcase wstateCR:.WriteByte('\n')fallthroughcase wstateBeginLine:.Write(dotcrnl)}return .Flush()}