Copyright 2009 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.
Pipe adapter to connect code expecting an io.Reader with code expecting an io.Writer.

package io

import (
	
	
)
onceError is an object that will only store an error once.
type onceError struct {
	sync.Mutex // guards following
	err        error
}

func ( *onceError) ( error) {
	.Lock()
	defer .Unlock()
	if .err != nil {
		return
	}
	.err = 
}
func ( *onceError) () error {
	.Lock()
	defer .Unlock()
	return .err
}
ErrClosedPipe is the error used for read or write operations on a closed pipe.
var ErrClosedPipe = errors.New("io: read/write on closed pipe")
A pipe is the shared pipe structure underlying PipeReader and PipeWriter.
type pipe struct {
	wrMu sync.Mutex // Serializes Write operations
	wrCh chan []byte
	rdCh chan int

	once sync.Once // Protects closing done
	done chan struct{}
	rerr onceError
	werr onceError
}

func ( *pipe) ( []byte) ( int,  error) {
	select {
	case <-.done:
		return 0, .readCloseError()
	default:
	}

	select {
	case  := <-.wrCh:
		 := copy(, )
		.rdCh <- 
		return , nil
	case <-.done:
		return 0, .readCloseError()
	}
}

func ( *pipe) () error {
	 := .rerr.Load()
	if  := .werr.Load();  == nil &&  != nil {
		return 
	}
	return ErrClosedPipe
}

func ( *pipe) ( error) error {
	if  == nil {
		 = ErrClosedPipe
	}
	.rerr.Store()
	.once.Do(func() { close(.done) })
	return nil
}

func ( *pipe) ( []byte) ( int,  error) {
	select {
	case <-.done:
		return 0, .writeCloseError()
	default:
		.wrMu.Lock()
		defer .wrMu.Unlock()
	}

	for  := true;  || len() > 0;  = false {
		select {
		case .wrCh <- :
			 := <-.rdCh
			 = [:]
			 += 
		case <-.done:
			return , .writeCloseError()
		}
	}
	return , nil
}

func ( *pipe) () error {
	 := .werr.Load()
	if  := .rerr.Load();  == nil &&  != nil {
		return 
	}
	return ErrClosedPipe
}

func ( *pipe) ( error) error {
	if  == nil {
		 = EOF
	}
	.werr.Store()
	.once.Do(func() { close(.done) })
	return nil
}
A PipeReader is the read half of a pipe.
type PipeReader struct {
	p *pipe
}
Read implements the standard Read interface: it reads data from the pipe, blocking until a writer arrives or the write end is closed. If the write end is closed with an error, that error is returned as err; otherwise err is EOF.
func ( *PipeReader) ( []byte) ( int,  error) {
	return .p.Read()
}
Close closes the reader; subsequent writes to the write half of the pipe will return the error ErrClosedPipe.
func ( *PipeReader) () error {
	return .CloseWithError(nil)
}
CloseWithError closes the reader; subsequent writes to the write half of the pipe will return the error err. CloseWithError never overwrites the previous error if it exists and always returns nil.
func ( *PipeReader) ( error) error {
	return .p.CloseRead()
}
A PipeWriter is the write half of a pipe.
type PipeWriter struct {
	p *pipe
}
Write implements the standard Write interface: it writes data to the pipe, blocking until one or more readers have consumed all the data or the read end is closed. If the read end is closed with an error, that err is returned as err; otherwise err is ErrClosedPipe.
func ( *PipeWriter) ( []byte) ( int,  error) {
	return .p.Write()
}
Close closes the writer; subsequent reads from the read half of the pipe will return no bytes and EOF.
func ( *PipeWriter) () error {
	return .CloseWithError(nil)
}
CloseWithError closes the writer; subsequent reads from the read half of the pipe will return no bytes and the error err, or EOF if err is nil. CloseWithError never overwrites the previous error if it exists and always returns nil.
func ( *PipeWriter) ( error) error {
	return .p.CloseWrite()
}
Pipe creates a synchronous in-memory pipe. It can be used to connect code expecting an io.Reader with code expecting an io.Writer. Reads and Writes on the pipe are matched one to one except when multiple Reads are needed to consume a single Write. That is, each Write to the PipeWriter blocks until it has satisfied one or more Reads from the PipeReader that fully consume the written data. The data is copied directly from the Write to the corresponding Read (or Reads); there is no internal buffering. It is safe to call Read and Write in parallel with each other or with Close. Parallel calls to Read and parallel calls to Write are also safe: the individual calls will be gated sequentially.
func () (*PipeReader, *PipeWriter) {
	 := &pipe{
		wrCh: make(chan []byte),
		rdCh: make(chan int),
		done: make(chan struct{}),
	}
	return &PipeReader{}, &PipeWriter{}