// The following is copied from Go 1.18 official implementation. // 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. package net import ( "io" "time" ) // Addr represents a network end point address. // // The two methods Network and String conventionally return strings // that can be passed as the arguments to Dial, but the exact form // and meaning of the strings is up to the implementation. type Addr interface { Network() string // name of the network (for example, "tcp", "udp") String() string // string form of address (for example, "192.0.2.1:25", "[2001:db8::1]:80") } // Conn is a generic stream-oriented network connection. // // Multiple goroutines may invoke methods on a Conn simultaneously. type Conn interface { // Read reads data from the connection. // Read can be made to time out and return an error after a fixed // time limit; see SetDeadline and SetReadDeadline. Read(b []byte) (n int, err error) // Write writes data to the connection. // Write can be made to time out and return an error after a fixed // time limit; see SetDeadline and SetWriteDeadline. Write(b []byte) (n int, err error) // Close closes the connection. // Any blocked Read or Write operations will be unblocked and return errors. Close() error // LocalAddr returns the local network address, if known. LocalAddr() Addr // RemoteAddr returns the remote network address, if known. RemoteAddr() Addr // SetDeadline sets the read and write deadlines associated // with the connection. It is equivalent to calling both // SetReadDeadline and SetWriteDeadline. // // A deadline is an absolute time after which I/O operations // fail instead of blocking. The deadline applies to all future // and pending I/O, not just the immediately following call to // Read or Write. After a deadline has been exceeded, the // connection can be refreshed by setting a deadline in the future. // // If the deadline is exceeded a call to Read or Write or to other // I/O methods will return an error that wraps os.ErrDeadlineExceeded. // This can be tested using errors.Is(err, os.ErrDeadlineExceeded). // The error's Timeout method will return true, but note that there // are other possible errors for which the Timeout method will // return true even if the deadline has not been exceeded. // // An idle timeout can be implemented by repeatedly extending // the deadline after successful Read or Write calls. // // A zero value for t means I/O operations will not time out. SetDeadline(t time.Time) error // SetReadDeadline sets the deadline for future Read calls // and any currently-blocked Read call. // A zero value for t means Read will not time out. SetReadDeadline(t time.Time) error // SetWriteDeadline sets the deadline for future Write calls // and any currently-blocked Write call. // Even if write times out, it may return n > 0, indicating that // some of the data was successfully written. // A zero value for t means Write will not time out. SetWriteDeadline(t time.Time) error } type conn struct { // } // A Listener is a generic network listener for stream-oriented protocols. // // Multiple goroutines may invoke methods on a Listener simultaneously. type Listener interface { // Accept waits for and returns the next connection to the listener. Accept() (Conn, error) // Close closes the listener. // Any blocked Accept operations will be unblocked and return errors. Close() error // Addr returns the listener's network address. Addr() Addr } // An Error represents a network error. type Error interface { error Timeout() bool // Is the error a timeout? // Deprecated: Temporary errors are not well-defined. // Most "temporary" errors are timeouts, and the few exceptions are surprising. // Do not use this method. Temporary() bool } // OpError is the error type usually returned by functions in the net // package. It describes the operation, network type, and address of // an error. type OpError struct { // Op is the operation which caused the error, such as // "read" or "write". Op string // Net is the network type on which this error occurred, // such as "tcp" or "udp6". Net string // For operations involving a remote network connection, like // Dial, Read, or Write, Source is the corresponding local // network address. Source Addr // Addr is the network address for which this error occurred. // For local operations, like Listen or SetDeadline, Addr is // the address of the local endpoint being manipulated. // For operations involving a remote network connection, like // Dial, Read, or Write, Addr is the remote address of that // connection. Addr Addr // Err is the error that occurred during the operation. // The Error method panics if the error is nil. Err error } func (e *OpError) Unwrap() error { return e.Err } func (e *OpError) Error() string { if e == nil { return "" } s := e.Op if e.Net != "" { s += " " + e.Net } if e.Source != nil { s += " " + e.Source.String() } if e.Addr != nil { if e.Source != nil { s += "->" } else { s += " " } s += e.Addr.String() } s += ": " + e.Err.Error() return s } // A ParseError is the error type of literal network address parsers. type ParseError struct { // Type is the type of string that was expected, such as // "IP address", "CIDR address". Type string // Text is the malformed text string. Text string } func (e *ParseError) Error() string { return "invalid " + e.Type + ": " + e.Text } type AddrError struct { Err string Addr string } func (e *AddrError) Error() string { if e == nil { return "" } s := e.Err if e.Addr != "" { s = "address " + e.Addr + ": " + s } return s } func (e *AddrError) Timeout() bool { return false } func (e *AddrError) Temporary() bool { return false } // ErrClosed is the error returned by an I/O call on a network // connection that has already been closed, or that is closed by // another goroutine before the I/O is completed. This may be wrapped // in another error, and should normally be tested using // errors.Is(err, net.ErrClosed). var ErrClosed = errClosed // buffersWriter is the interface implemented by Conns that support a // "writev"-like batch write optimization. // writeBuffers should fully consume and write all chunks from the // provided Buffers, else it should report a non-nil error. type buffersWriter interface { writeBuffers(*Buffers) (int64, error) } // Buffers contains zero or more runs of bytes to write. // // On certain machines, for certain types of connections, this is // optimized into an OS-specific batch write operation (such as // "writev"). type Buffers [][]byte var ( _ io.WriterTo = (*Buffers)(nil) _ io.Reader = (*Buffers)(nil) ) // WriteTo writes contents of the buffers to w. // // WriteTo implements io.WriterTo for Buffers. // // WriteTo modifies the slice v as well as v[i] for 0 <= i < len(v), // but does not modify v[i][j] for any i, j. func (v *Buffers) WriteTo(w io.Writer) (n int64, err error) { if wv, ok := w.(buffersWriter); ok { return wv.writeBuffers(v) } for _, b := range *v { nb, err := w.Write(b) n += int64(nb) if err != nil { v.consume(n) return n, err } } v.consume(n) return n, nil } // Read from the buffers. // // Read implements io.Reader for Buffers. // // Read modifies the slice v as well as v[i] for 0 <= i < len(v), // but does not modify v[i][j] for any i, j. func (v *Buffers) Read(p []byte) (n int, err error) { for len(p) > 0 && len(*v) > 0 { n0 := copy(p, (*v)[0]) v.consume(int64(n0)) p = p[n0:] n += n0 } if len(*v) == 0 { err = io.EOF } return } func (v *Buffers) consume(n int64) { for len(*v) > 0 { ln0 := int64(len((*v)[0])) if ln0 > n { (*v)[0] = (*v)[0][n:] return } n -= ln0 (*v)[0] = nil *v = (*v)[1:] } }