OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [net/] [textproto/] [writer.go] - Rev 848

Go to most recent revision | Compare with Previous | Blame | View Log

// 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 textproto

import (
        "bufio"
        "fmt"
        "io"
)

// A Writer implements convenience methods for writing
// requests or responses to a text protocol network connection.
type Writer struct {
        W   *bufio.Writer
        dot *dotWriter
}

// NewWriter returns a new Writer writing to w.
func NewWriter(w *bufio.Writer) *Writer {
        return &Writer{W: w}
}

var crnl = []byte{'\r', '\n'}
var dotcrnl = []byte{'.', '\r', '\n'}

// PrintfLine writes the formatted output followed by \r\n.
func (w *Writer) PrintfLine(format string, args ...interface{}) error {
        w.closeDot()
        fmt.Fprintf(w.W, format, args...)
        w.W.Write(crnl)
        return w.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 (w *Writer) DotWriter() io.WriteCloser {
        w.closeDot()
        w.dot = &dotWriter{w: w}
        return w.dot
}

func (w *Writer) closeDot() {
        if w.dot != nil {
                w.dot.Close() // sets w.dot = nil
        }
}

type dotWriter struct {
        w     *Writer
        state int
}

const (
        wstateBeginLine = iota // beginning of line; initial state; must be zero
        wstateCR               // wrote \r (possibly at end of line)
        wstateData             // writing data in middle of line
)

func (d *dotWriter) Write(b []byte) (n int, err error) {
        bw := d.w.W
        for n < len(b) {
                c := b[n]
                switch d.state {
                case wstateBeginLine:
                        d.state = wstateData
                        if c == '.' {
                                // escape leading dot
                                bw.WriteByte('.')
                        }
                        fallthrough

                case wstateData:
                        if c == '\r' {
                                d.state = wstateCR
                        }
                        if c == '\n' {
                                bw.WriteByte('\r')
                                d.state = wstateBeginLine
                        }

                case wstateCR:
                        d.state = wstateData
                        if c == '\n' {
                                d.state = wstateBeginLine
                        }
                }
                if err = bw.WriteByte(c); err != nil {
                        break
                }
                n++
        }
        return
}

func (d *dotWriter) Close() error {
        if d.w.dot == d {
                d.w.dot = nil
        }
        bw := d.w.W
        switch d.state {
        default:
                bw.WriteByte('\r')
                fallthrough
        case wstateCR:
                bw.WriteByte('\n')
                fallthrough
        case wstateBeginLine:
                bw.Write(dotcrnl)
        }
        return bw.Flush()
}

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.