Copyright 2012 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 ssh

import (
	
	
)
buffer provides a linked list buffer for data exchange between producer and consumer. Theoretically the buffer is of unlimited capacity as it does no allocation of its own.
protects concurrent access to head, tail and closed
	*sync.Cond

	head *element // the buffer that will be read first
	tail *element // the buffer that will be read last

	closed bool
}
An element represents a single link in a linked list.
type element struct {
	buf  []byte
	next *element
}
newBuffer returns an empty buffer that is not closed.
func () *buffer {
	 := new(element)
	 := &buffer{
		Cond: newCond(),
		head: ,
		tail: ,
	}
	return 
}
write makes buf available for Read to receive. buf must not be modified after the call to write.
func ( *buffer) ( []byte) {
	.Cond.L.Lock()
	 := &element{buf: }
	.tail.next = 
	.tail = 
	.Cond.Signal()
	.Cond.L.Unlock()
}
eof closes the buffer. Reads from the buffer once all the data has been consumed will receive io.EOF.
func ( *buffer) () {
	.Cond.L.Lock()
	.closed = true
	.Cond.Signal()
	.Cond.L.Unlock()
}
Read reads data from the internal buffer in buf. Reads will block if no data is available, or until the buffer is closed.
func ( *buffer) ( []byte) ( int,  error) {
	.Cond.L.Lock()
	defer .Cond.L.Unlock()

if there is data in b.head, copy it
		if len(.head.buf) > 0 {
			 := copy(, .head.buf)
			, .head.buf = [:], .head.buf[:]
			 += 
			continue
if there is a next buffer, make it the head
		if len(.head.buf) == 0 && .head != .tail {
			.head = .head.next
			continue
		}
if at least one byte has been copied, return
		if  > 0 {
			break
		}
if nothing was read, and there is nothing outstanding check to see if the buffer is closed.
		if .closed {
			 = io.EOF
			break
out of buffers, wait for producer
		.Cond.Wait()
	}
	return