<commit_before>// 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 bytes

// Simple byte buffer for marshaling data.

import (
	"io"
	"os"
	"utf8"
)

// A Buffer is a variable-sized buffer of bytes with Read and Write methods.
// The zero value for Buffer is an empty buffer ready to use.
type Buffer struct {
	buf       []byte            // contents are the bytes buf[off : len(buf)]
	off       int               // read at &buf[off], write at &buf[len(buf)]
	runeBytes [utf8.UTFMax]byte // avoid allocation of slice on each WriteByte or Rune
	bootstrap [64]byte          // memory to hold first slice; helps small buffers (Printf) avoid allocation.
	lastRead  readOp            // last read operation, so that Unread* can work correctly.
}

// The readOp constants describe the last action performed on
// the buffer, so that UnreadRune and UnreadByte can
// check for invalid usage.
type readOp int

const (
	opInvalid  readOp = iota // Non-read operation.
	opReadRune               // Read rune.
	opRead                   // Any other read operation.
)

// Bytes returns a slice of the contents of the unread portion of the buffer;
// len(b.Bytes()) == b.Len().  If the caller changes the contents of the
// returned slice, the contents of the buffer will change provided there
// are no intervening method calls on the Buffer.
func (b *Buffer) Bytes() []byte { return b.buf[b.off:] }

// String returns the contents of the unread portion of the buffer
// as a string.  If the Buffer is a nil pointer, it returns "<nil>".
func (b *Buffer) String() string {
	if b == nil {
		// Special case, useful in debugging.
		return "<nil>"
	}
	return string(b.buf[b.off:])
}

// Len returns the number of bytes of the unread portion of the buffer;
// b.Len() == len(b.Bytes()).
func (b *Buffer) Len() int { return len(b.buf) - b.off }

// Truncate discards all but the first n unread bytes from the buffer.
// It is an error to call b.Truncate(n) with n > b.Len().
func (b *Buffer) Truncate(n int) {
	b.lastRead = opInvalid
	if n == 0 {
		// Reuse buffer space.
		b.off = 0
	}
	b.buf = b.buf[0 : b.off+n]
}

// Reset resets the buffer so it has no content.
// b.Reset() is the same as b.Truncate(0).
func (b *Buffer) Reset() { b.Truncate(0) }

// Grow buffer to guarantee space for n more bytes.
// Return index where bytes should be written.
func (b *Buffer) grow(n int) int {
	m := b.Len()
	// If buffer is empty, reset to recover space.
	if m == 0 && b.off != 0 {
		b.Truncate(0)
	}
	if len(b.buf)+n > cap(b.buf) {
		var buf []byte
		if b.buf == nil && n <= len(b.bootstrap) {
			buf = b.bootstrap[0:]
		} else {
			// not enough space anywhere
			buf = make([]byte, 2*cap(b.buf)+n)
			copy(buf, b.buf[b.off:])
		}
		b.buf = buf
		b.off = 0
	}
	b.buf = b.buf[0 : b.off+m+n]
	return b.off + m
}

// Write appends the contents of p to the buffer.  The return
// value n is the length of p; err is always nil.
func (b *Buffer) Write(p []byte) (n int, err os.Error) {
	b.lastRead = opInvalid
	m := b.grow(len(p))
	copy(b.buf[m:], p)
	return len(p), nil
}

// WriteString appends the contents of s to the buffer.  The return
// value n is the length of s; err is always nil.
func (b *Buffer) WriteString(s string) (n int, err os.Error) {
	b.lastRead = opInvalid
	m := b.grow(len(s))
	return copy(b.buf[m:], s), nil
}

// MinRead is the minimum slice size passed to a Read call by
// Buffer.ReadFrom.  As long as the Buffer has at least MinRead bytes beyond
// what is required to hold the contents of r, ReadFrom will not grow the
// underlying buffer.
const MinRead = 512

// ReadFrom reads data from r until EOF and appends it to the buffer.
// The return value n is the number of bytes read.
// Any error except os.EOF encountered during the read
// is also returned.
func (b *Buffer) ReadFrom(r io.Reader) (n int64, err os.Error) {
	b.lastRead = opInvalid
	// If buffer is empty, reset to recover space.
	if b.off >= len(b.buf) {
		b.Truncate(0)
	}
	for {
		if cap(b.buf)-len(b.buf) < MinRead {
			var newBuf []byte
			// can we get space without allocation?
			if b.off+cap(b.buf)-len(b.buf) >= MinRead {
				// reuse beginning of buffer
				newBuf = b.buf[0 : len(b.buf)-b.off]
			} else {
				// not enough space at end; put space on end
				newBuf = make([]byte, len(b.buf)-b.off, 2*(cap(b.buf)-b.off)+MinRead)
			}
			copy(newBuf, b.buf[b.off:])
			b.buf = newBuf
			b.off = 0
		}
		m, e := r.Read(b.buf[len(b.buf):cap(b.buf)])
		b.buf = b.buf[0 : len(b.buf)+m]
		n += int64(m)
		if e == os.EOF {
			break
		}
		if e != nil {
			return n, e
		}
	}
	return n, nil // err is EOF, so return nil explicitly
}

// WriteTo writes data to w until the buffer is drained or an error
// occurs. The return value n is the number of bytes written; it always
// fits into an int, but it is int64 to match the io.WriterTo interface.
// Any error encountered during the write is also returned.
func (b *Buffer) WriteTo(w io.Writer) (n int64, err os.Error) {
	b.lastRead = opInvalid
	if b.off < len(b.buf) {
		m, e := w.Write(b.buf[b.off:])
		b.off += m
		n = int64(m)
		if e != nil {
			return n, e
		}
		// otherwise all bytes were written, by definition of
		// Write method in io.Writer
	}
	// Buffer is now empty; reset.
	b.Truncate(0)
	return
}

// WriteByte appends the byte c to the buffer.
// The returned error is always nil, but is included
// to match bufio.Writer's WriteByte.
func (b *Buffer) WriteByte(c byte) os.Error {
	b.lastRead = opInvalid
	m := b.grow(1)
	b.buf[m] = c
	return nil
}

// WriteRune appends the UTF-8 encoding of Unicode
// code point r to the buffer, returning its length and
// an error, which is always nil but is included
// to match bufio.Writer's WriteRune.
func (b *Buffer) WriteRune(r int) (n int, err os.Error) {
	if r < utf8.RuneSelf {
		b.WriteByte(byte(r))
		return 1, nil
	}
	n = utf8.EncodeRune(b.runeBytes[0:], r)
	b.Write(b.runeBytes[0:n])
	return n, nil
}

// Read reads the next len(p) bytes from the buffer or until the buffer
// is drained.  The return value n is the number of bytes read.  If the
// buffer has no data to return, err is os.EOF even if len(p) is zero;
// otherwise it is nil.
func (b *Buffer) Read(p []byte) (n int, err os.Error) {
	b.lastRead = opInvalid
	if b.off >= len(b.buf) {
		// Buffer is empty, reset to recover space.
		b.Truncate(0)
		return 0, os.EOF
	}
	n = copy(p, b.buf[b.off:])
	b.off += n
	if n > 0 {
		b.lastRead = opRead
	}
	return
}

// Next returns a slice containing the next n bytes from the buffer,
// advancing the buffer as if the bytes had been returned by Read.
// If there are fewer than n bytes in the buffer, Next returns the entire buffer.
// The slice is only valid until the next call to a read or write method.
func (b *Buffer) Next(n int) []byte {
	b.lastRead = opInvalid
	m := b.Len()
	if n > m {
		n = m
	}
	data := b.buf[b.off : b.off+n]
	b.off += n
	if n > 0 {
		b.lastRead = opRead
	}
	return data
}

// ReadByte reads and returns the next byte from the buffer.
// If no byte is available, it returns error os.EOF.
func (b *Buffer) ReadByte() (c byte, err os.Error) {
	b.lastRead = opInvalid
	if b.off >= len(b.buf) {
		// Buffer is empty, reset to recover space.
		b.Truncate(0)
		return 0, os.EOF
	}
	c = b.buf[b.off]
	b.off++
	b.lastRead = opRead
	return c, nil
}

// ReadRune reads and returns the next UTF-8-encoded
// Unicode code point from the buffer.
// If no bytes are available, the error returned is os.EOF.
// If the bytes are an erroneous UTF-8 encoding, it
// consumes one byte and returns U+FFFD, 1.
func (b *Buffer) ReadRune() (r int, size int, err os.Error) {
	b.lastRead = opInvalid
	if b.off >= len(b.buf) {
		// Buffer is empty, reset to recover space.
		b.Truncate(0)
		return 0, 0, os.EOF
	}
	b.lastRead = opReadRune
	c := b.buf[b.off]
	if c < utf8.RuneSelf {
		b.off++
		return int(c), 1, nil
	}
	r, n := utf8.DecodeRune(b.buf[b.off:])
	b.off += n
	return r, n, nil
}

// UnreadRune unreads the last rune returned by ReadRune.
// If the most recent read or write operation on the buffer was
// not a ReadRune, UnreadRune returns an error.  (In this regard
// it is stricter than UnreadByte, which will unread the last byte
// from any read operation.)
func (b *Buffer) UnreadRune() os.Error {
	if b.lastRead != opReadRune {
		return os.NewError("bytes.Buffer: UnreadRune: previous operation was not ReadRune")
	}
	b.lastRead = opInvalid
	if b.off > 0 {
		_, n := utf8.DecodeLastRune(b.buf[0:b.off])
		b.off -= n
	}
	return nil
}

// UnreadByte unreads the last byte returned by the most recent
// read operation.  If write has happened since the last read, UnreadByte
// returns an error.
func (b *Buffer) UnreadByte() os.Error {
	if b.lastRead != opReadRune && b.lastRead != opRead {
		return os.NewError("bytes.Buffer: UnreadByte: previous operation was not a read")
	}
	b.lastRead = opInvalid
	if b.off > 0 {
		b.off--
	}
	return nil
}

// ReadBytes reads until the first occurrence of delim in the input,
// returning a slice containing the data up to and including the delimiter.
// If ReadBytes encounters an error before finding a delimiter,
// it returns the data read before the error and the error itself (often os.EOF).
// ReadBytes returns err != nil if and only if the returned data does not end in
// delim.
func (b *Buffer) ReadBytes(delim byte) (line []byte, err os.Error) {
	i := IndexByte(b.buf[b.off:], delim)
	size := i + 1
	if i < 0 {
		size = len(b.buf) - b.off
		err = os.EOF
	}
	line = make([]byte, size)
	copy(line, b.buf[b.off:])
	b.off += size
	return
}

// ReadString reads until the first occurrence of delim in the input,
// returning a string containing the data up to and including the delimiter.
// If ReadString encounters an error before finding a delimiter,
// it returns the data read before the error and the error itself (often os.EOF).
// ReadString returns err != nil if and only if the returned data does not end
// in delim.
func (b *Buffer) ReadString(delim byte) (line string, err os.Error) {
	bytes, err := b.ReadBytes(delim)
	return string(bytes), err
}

// NewBuffer creates and initializes a new Buffer using buf as its initial
// contents.  It is intended to prepare a Buffer to read existing data.  It
// can also be used to size the internal buffer for writing.  To do that,
// buf should have the desired capacity but a length of zero.
func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} }

// NewBufferString creates and initializes a new Buffer using string s as its
// initial contents.  It is intended to prepare a buffer to read an existing
// string.
func NewBufferString(s string) *Buffer {
	return &Buffer{buf: []byte(s)}
}
<commit_msg>bytes.Buffer: clarify that NewBuffer is not for beginners<commit_after>// 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 bytes

// Simple byte buffer for marshaling data.

import (
	"io"
	"os"
	"utf8"
)

// A Buffer is a variable-sized buffer of bytes with Read and Write methods.
// The zero value for Buffer is an empty buffer ready to use.
type Buffer struct {
	buf       []byte            // contents are the bytes buf[off : len(buf)]
	off       int               // read at &buf[off], write at &buf[len(buf)]
	runeBytes [utf8.UTFMax]byte // avoid allocation of slice on each WriteByte or Rune
	bootstrap [64]byte          // memory to hold first slice; helps small buffers (Printf) avoid allocation.
	lastRead  readOp            // last read operation, so that Unread* can work correctly.
}

// The readOp constants describe the last action performed on
// the buffer, so that UnreadRune and UnreadByte can
// check for invalid usage.
type readOp int

const (
	opInvalid  readOp = iota // Non-read operation.
	opReadRune               // Read rune.
	opRead                   // Any other read operation.
)

// Bytes returns a slice of the contents of the unread portion of the buffer;
// len(b.Bytes()) == b.Len().  If the caller changes the contents of the
// returned slice, the contents of the buffer will change provided there
// are no intervening method calls on the Buffer.
func (b *Buffer) Bytes() []byte { return b.buf[b.off:] }

// String returns the contents of the unread portion of the buffer
// as a string.  If the Buffer is a nil pointer, it returns "<nil>".
func (b *Buffer) String() string {
	if b == nil {
		// Special case, useful in debugging.
		return "<nil>"
	}
	return string(b.buf[b.off:])
}

// Len returns the number of bytes of the unread portion of the buffer;
// b.Len() == len(b.Bytes()).
func (b *Buffer) Len() int { return len(b.buf) - b.off }

// Truncate discards all but the first n unread bytes from the buffer.
// It is an error to call b.Truncate(n) with n > b.Len().
func (b *Buffer) Truncate(n int) {
	b.lastRead = opInvalid
	if n == 0 {
		// Reuse buffer space.
		b.off = 0
	}
	b.buf = b.buf[0 : b.off+n]
}

// Reset resets the buffer so it has no content.
// b.Reset() is the same as b.Truncate(0).
func (b *Buffer) Reset() { b.Truncate(0) }

// Grow buffer to guarantee space for n more bytes.
// Return index where bytes should be written.
func (b *Buffer) grow(n int) int {
	m := b.Len()
	// If buffer is empty, reset to recover space.
	if m == 0 && b.off != 0 {
		b.Truncate(0)
	}
	if len(b.buf)+n > cap(b.buf) {
		var buf []byte
		if b.buf == nil && n <= len(b.bootstrap) {
			buf = b.bootstrap[0:]
		} else {
			// not enough space anywhere
			buf = make([]byte, 2*cap(b.buf)+n)
			copy(buf, b.buf[b.off:])
		}
		b.buf = buf
		b.off = 0
	}
	b.buf = b.buf[0 : b.off+m+n]
	return b.off + m
}

// Write appends the contents of p to the buffer.  The return
// value n is the length of p; err is always nil.
func (b *Buffer) Write(p []byte) (n int, err os.Error) {
	b.lastRead = opInvalid
	m := b.grow(len(p))
	copy(b.buf[m:], p)
	return len(p), nil
}

// WriteString appends the contents of s to the buffer.  The return
// value n is the length of s; err is always nil.
func (b *Buffer) WriteString(s string) (n int, err os.Error) {
	b.lastRead = opInvalid
	m := b.grow(len(s))
	return copy(b.buf[m:], s), nil
}

// MinRead is the minimum slice size passed to a Read call by
// Buffer.ReadFrom.  As long as the Buffer has at least MinRead bytes beyond
// what is required to hold the contents of r, ReadFrom will not grow the
// underlying buffer.
const MinRead = 512

// ReadFrom reads data from r until EOF and appends it to the buffer.
// The return value n is the number of bytes read.
// Any error except os.EOF encountered during the read
// is also returned.
func (b *Buffer) ReadFrom(r io.Reader) (n int64, err os.Error) {
	b.lastRead = opInvalid
	// If buffer is empty, reset to recover space.
	if b.off >= len(b.buf) {
		b.Truncate(0)
	}
	for {
		if cap(b.buf)-len(b.buf) < MinRead {
			var newBuf []byte
			// can we get space without allocation?
			if b.off+cap(b.buf)-len(b.buf) >= MinRead {
				// reuse beginning of buffer
				newBuf = b.buf[0 : len(b.buf)-b.off]
			} else {
				// not enough space at end; put space on end
				newBuf = make([]byte, len(b.buf)-b.off, 2*(cap(b.buf)-b.off)+MinRead)
			}
			copy(newBuf, b.buf[b.off:])
			b.buf = newBuf
			b.off = 0
		}
		m, e := r.Read(b.buf[len(b.buf):cap(b.buf)])
		b.buf = b.buf[0 : len(b.buf)+m]
		n += int64(m)
		if e == os.EOF {
			break
		}
		if e != nil {
			return n, e
		}
	}
	return n, nil // err is EOF, so return nil explicitly
}

// WriteTo writes data to w until the buffer is drained or an error
// occurs. The return value n is the number of bytes written; it always
// fits into an int, but it is int64 to match the io.WriterTo interface.
// Any error encountered during the write is also returned.
func (b *Buffer) WriteTo(w io.Writer) (n int64, err os.Error) {
	b.lastRead = opInvalid
	if b.off < len(b.buf) {
		m, e := w.Write(b.buf[b.off:])
		b.off += m
		n = int64(m)
		if e != nil {
			return n, e
		}
		// otherwise all bytes were written, by definition of
		// Write method in io.Writer
	}
	// Buffer is now empty; reset.
	b.Truncate(0)
	return
}

// WriteByte appends the byte c to the buffer.
// The returned error is always nil, but is included
// to match bufio.Writer's WriteByte.
func (b *Buffer) WriteByte(c byte) os.Error {
	b.lastRead = opInvalid
	m := b.grow(1)
	b.buf[m] = c
	return nil
}

// WriteRune appends the UTF-8 encoding of Unicode
// code point r to the buffer, returning its length and
// an error, which is always nil but is included
// to match bufio.Writer's WriteRune.
func (b *Buffer) WriteRune(r int) (n int, err os.Error) {
	if r < utf8.RuneSelf {
		b.WriteByte(byte(r))
		return 1, nil
	}
	n = utf8.EncodeRune(b.runeBytes[0:], r)
	b.Write(b.runeBytes[0:n])
	return n, nil
}

// Read reads the next len(p) bytes from the buffer or until the buffer
// is drained.  The return value n is the number of bytes read.  If the
// buffer has no data to return, err is os.EOF even if len(p) is zero;
// otherwise it is nil.
func (b *Buffer) Read(p []byte) (n int, err os.Error) {
	b.lastRead = opInvalid
	if b.off >= len(b.buf) {
		// Buffer is empty, reset to recover space.
		b.Truncate(0)
		return 0, os.EOF
	}
	n = copy(p, b.buf[b.off:])
	b.off += n
	if n > 0 {
		b.lastRead = opRead
	}
	return
}

// Next returns a slice containing the next n bytes from the buffer,
// advancing the buffer as if the bytes had been returned by Read.
// If there are fewer than n bytes in the buffer, Next returns the entire buffer.
// The slice is only valid until the next call to a read or write method.
func (b *Buffer) Next(n int) []byte {
	b.lastRead = opInvalid
	m := b.Len()
	if n > m {
		n = m
	}
	data := b.buf[b.off : b.off+n]
	b.off += n
	if n > 0 {
		b.lastRead = opRead
	}
	return data
}

// ReadByte reads and returns the next byte from the buffer.
// If no byte is available, it returns error os.EOF.
func (b *Buffer) ReadByte() (c byte, err os.Error) {
	b.lastRead = opInvalid
	if b.off >= len(b.buf) {
		// Buffer is empty, reset to recover space.
		b.Truncate(0)
		return 0, os.EOF
	}
	c = b.buf[b.off]
	b.off++
	b.lastRead = opRead
	return c, nil
}

// ReadRune reads and returns the next UTF-8-encoded
// Unicode code point from the buffer.
// If no bytes are available, the error returned is os.EOF.
// If the bytes are an erroneous UTF-8 encoding, it
// consumes one byte and returns U+FFFD, 1.
func (b *Buffer) ReadRune() (r int, size int, err os.Error) {
	b.lastRead = opInvalid
	if b.off >= len(b.buf) {
		// Buffer is empty, reset to recover space.
		b.Truncate(0)
		return 0, 0, os.EOF
	}
	b.lastRead = opReadRune
	c := b.buf[b.off]
	if c < utf8.RuneSelf {
		b.off++
		return int(c), 1, nil
	}
	r, n := utf8.DecodeRune(b.buf[b.off:])
	b.off += n
	return r, n, nil
}

// UnreadRune unreads the last rune returned by ReadRune.
// If the most recent read or write operation on the buffer was
// not a ReadRune, UnreadRune returns an error.  (In this regard
// it is stricter than UnreadByte, which will unread the last byte
// from any read operation.)
func (b *Buffer) UnreadRune() os.Error {
	if b.lastRead != opReadRune {
		return os.NewError("bytes.Buffer: UnreadRune: previous operation was not ReadRune")
	}
	b.lastRead = opInvalid
	if b.off > 0 {
		_, n := utf8.DecodeLastRune(b.buf[0:b.off])
		b.off -= n
	}
	return nil
}

// UnreadByte unreads the last byte returned by the most recent
// read operation.  If write has happened since the last read, UnreadByte
// returns an error.
func (b *Buffer) UnreadByte() os.Error {
	if b.lastRead != opReadRune && b.lastRead != opRead {
		return os.NewError("bytes.Buffer: UnreadByte: previous operation was not a read")
	}
	b.lastRead = opInvalid
	if b.off > 0 {
		b.off--
	}
	return nil
}

// ReadBytes reads until the first occurrence of delim in the input,
// returning a slice containing the data up to and including the delimiter.
// If ReadBytes encounters an error before finding a delimiter,
// it returns the data read before the error and the error itself (often os.EOF).
// ReadBytes returns err != nil if and only if the returned data does not end in
// delim.
func (b *Buffer) ReadBytes(delim byte) (line []byte, err os.Error) {
	i := IndexByte(b.buf[b.off:], delim)
	size := i + 1
	if i < 0 {
		size = len(b.buf) - b.off
		err = os.EOF
	}
	line = make([]byte, size)
	copy(line, b.buf[b.off:])
	b.off += size
	return
}

// ReadString reads until the first occurrence of delim in the input,
// returning a string containing the data up to and including the delimiter.
// If ReadString encounters an error before finding a delimiter,
// it returns the data read before the error and the error itself (often os.EOF).
// ReadString returns err != nil if and only if the returned data does not end
// in delim.
func (b *Buffer) ReadString(delim byte) (line string, err os.Error) {
	bytes, err := b.ReadBytes(delim)
	return string(bytes), err
}

// NewBuffer creates and initializes a new Buffer using buf as its initial
// contents.  It is intended to prepare a Buffer to read existing data.  It
// can also be used to size the internal buffer for writing. To do that,
// buf should have the desired capacity but a length of zero.
//
// In most cases, new(Buffer) (or just declaring a Buffer variable) is
// preferable to NewBuffer.  In particular, passing a non-empty buf to
// NewBuffer and then writing to the Buffer will overwrite buf, not append to
// it.
func NewBuffer(buf []byte) *Buffer { return &Buffer{buf: buf} }

// NewBufferString creates and initializes a new Buffer using string s as its
// initial contents.  It is intended to prepare a buffer to read an existing
// string.  See the warnings about NewBuffer; similar issues apply here.
func NewBufferString(s string) *Buffer {
	return &Buffer{buf: []byte(s)}
}
<|endoftext|>


<commit_before>// Copyright 2011 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 http provides HTTP client and server implementations.

Get, Head, Post, and PostForm make HTTP requests:

	resp, err := http.Get("http://example.com/")
	...
	resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
	...
	resp, err := http.PostForm("http://example.com/form",
 		url.Values{"key": {"Value"}, "id": {"123"}})

The client must close the response body when finished with it:

	resp, err := http.Get("http://example.com/")
	if err != nil {
		// handle error
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	// ...

For control over HTTP client headers, redirect policy, and other
settings, create a Client:

	client := &http.Client{
		CheckRedirect: redirectPolicyFunc,
	}

	resp, err := client.Get("http://example.com")
	// ...

	req := http.NewRequest("GET", "http://example.com", nil)
	req.Header.Add("If-None-Match", `W/"wyzzy"`)
	resp, err := client.Do(req)
	// ...

For control over proxies, TLS configuration, keep-alives,
compression, and other settings, create a Transport:

	tr := &http.Transport{
		TLSClientConfig:    &tls.Config{RootCAs: pool},
		DisableCompression: true,
	}
	client := &http.Client{Transport: tr}
	resp, err := client.Get("https://example.com")

Clients and Transports are safe for concurrent use by multiple
goroutines and for efficiency should only be created once and re-used.

ListenAndServe starts an HTTP server with a given address and handler.
The handler is usually nil, which means to use DefaultServeMux.
Handle and HandleFunc add handlers to DefaultServeMux:

	http.Handle("/foo", fooHandler)

	http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.RawPath))
	})

	log.Fatal(http.ListenAndServe(":8080", nil))

More control over the server's behavior is available by creating a
custom Server:

	s := &http.Server{
		Addr:           ":8080",
		Handler:        myHandler,
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}
	log.Fatal(s.ListenAndServe())
*/
package http
<commit_msg>net/http: the documentation should call NewRequest with the right signature.<commit_after>// Copyright 2011 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 http provides HTTP client and server implementations.

Get, Head, Post, and PostForm make HTTP requests:

	resp, err := http.Get("http://example.com/")
	...
	resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf)
	...
	resp, err := http.PostForm("http://example.com/form",
 		url.Values{"key": {"Value"}, "id": {"123"}})

The client must close the response body when finished with it:

	resp, err := http.Get("http://example.com/")
	if err != nil {
		// handle error
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	// ...

For control over HTTP client headers, redirect policy, and other
settings, create a Client:

	client := &http.Client{
		CheckRedirect: redirectPolicyFunc,
	}

	resp, err := client.Get("http://example.com")
	// ...

	req, err := http.NewRequest("GET", "http://example.com", nil)
	// ...
	req.Header.Add("If-None-Match", `W/"wyzzy"`)
	resp, err := client.Do(req)
	// ...

For control over proxies, TLS configuration, keep-alives,
compression, and other settings, create a Transport:

	tr := &http.Transport{
		TLSClientConfig:    &tls.Config{RootCAs: pool},
		DisableCompression: true,
	}
	client := &http.Client{Transport: tr}
	resp, err := client.Get("https://example.com")

Clients and Transports are safe for concurrent use by multiple
goroutines and for efficiency should only be created once and re-used.

ListenAndServe starts an HTTP server with a given address and handler.
The handler is usually nil, which means to use DefaultServeMux.
Handle and HandleFunc add handlers to DefaultServeMux:

	http.Handle("/foo", fooHandler)

	http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.RawPath))
	})

	log.Fatal(http.ListenAndServe(":8080", nil))

More control over the server's behavior is available by creating a
custom Server:

	s := &http.Server{
		Addr:           ":8080",
		Handler:        myHandler,
		ReadTimeout:    10 * time.Second,
		WriteTimeout:   10 * time.Second,
		MaxHeaderBytes: 1 << 20,
	}
	log.Fatal(s.ListenAndServe())
*/
package http
<|endoftext|>


<commit_before>// 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 (
	"flag";
	"regexp";
	"testing";
)

var runErrorTest = flag.Bool("run_error_test", false, "let TestDialError check for dns errors")

type DialErrorTest struct {
	Net	string;
	Laddr	string;
	Raddr	string;
	Pattern	string;
}

var dialErrorTests = []DialErrorTest{
	DialErrorTest{
		"datakit", "", "mh/astro/r70",
		"dial datakit mh/astro/r70: unknown network datakit",
	},
	DialErrorTest{
		"tcp", "", "127.0.0.1:☺",
		"dial tcp 127.0.0.1:☺: unknown port tcp/☺",
	},
	DialErrorTest{
		"tcp", "", "no-such-name.google.com.:80",
		"dial tcp no-such-name.google.com.:80: lookup no-such-name.google.com.( on .*)?: no (.*)",
	},
	DialErrorTest{
		"tcp", "", "no-such-name.no-such-top-level-domain.:80",
		"dial tcp no-such-name.no-such-top-level-domain.:80: lookup no-such-name.no-such-top-level-domain.( on .*)?: no (.*)",
	},
	DialErrorTest{
		"tcp", "", "no-such-name:80",
		`dial tcp no-such-name:80: lookup no-such-name\.(.*\.)?( on .*)?: no (.*)`,
	},
	DialErrorTest{
		"tcp", "", "mh/astro/r70:http",
		"dial tcp mh/astro/r70:http: lookup mh/astro/r70: invalid domain name",
	},
	DialErrorTest{
		"unix", "", "/etc/file-not-found",
		"dial unix /etc/file-not-found: no such file or directory",
	},
	DialErrorTest{
		"unix", "", "/etc/",
		"dial unix /etc/: (permission denied|socket operation on non-socket)",
	},
}

func TestDialError(t *testing.T) {
	if !*runErrorTest {
		t.Logf("test disabled; use --run_error_test to enable");
		return;
	}
	for i, tt := range dialErrorTests {
		c, e := Dial(tt.Net, tt.Laddr, tt.Raddr);
		if c != nil {
			c.Close()
		}
		if e == nil {
			t.Errorf("#%d: nil error, want match for %#q", i, tt.Pattern);
			continue;
		}
		s := e.String();
		match, _ := regexp.MatchString(tt.Pattern, s);
		if !match {
			t.Errorf("#%d: %q, want match for %#q", i, s, tt.Pattern)
		}
	}
}
<commit_msg>net: fix error for connect to /etc/ on some systems<commit_after>// 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 (
	"flag";
	"regexp";
	"testing";
)

var runErrorTest = flag.Bool("run_error_test", false, "let TestDialError check for dns errors")

type DialErrorTest struct {
	Net	string;
	Laddr	string;
	Raddr	string;
	Pattern	string;
}

var dialErrorTests = []DialErrorTest{
	DialErrorTest{
		"datakit", "", "mh/astro/r70",
		"dial datakit mh/astro/r70: unknown network datakit",
	},
	DialErrorTest{
		"tcp", "", "127.0.0.1:☺",
		"dial tcp 127.0.0.1:☺: unknown port tcp/☺",
	},
	DialErrorTest{
		"tcp", "", "no-such-name.google.com.:80",
		"dial tcp no-such-name.google.com.:80: lookup no-such-name.google.com.( on .*)?: no (.*)",
	},
	DialErrorTest{
		"tcp", "", "no-such-name.no-such-top-level-domain.:80",
		"dial tcp no-such-name.no-such-top-level-domain.:80: lookup no-such-name.no-such-top-level-domain.( on .*)?: no (.*)",
	},
	DialErrorTest{
		"tcp", "", "no-such-name:80",
		`dial tcp no-such-name:80: lookup no-such-name\.(.*\.)?( on .*)?: no (.*)`,
	},
	DialErrorTest{
		"tcp", "", "mh/astro/r70:http",
		"dial tcp mh/astro/r70:http: lookup mh/astro/r70: invalid domain name",
	},
	DialErrorTest{
		"unix", "", "/etc/file-not-found",
		"dial unix /etc/file-not-found: no such file or directory",
	},
	DialErrorTest{
		"unix", "", "/etc/",
		"dial unix /etc/: (permission denied|socket operation on non-socket|connection refused)",
	},
}

func TestDialError(t *testing.T) {
	if !*runErrorTest {
		t.Logf("test disabled; use --run_error_test to enable");
		return;
	}
	for i, tt := range dialErrorTests {
		c, e := Dial(tt.Net, tt.Laddr, tt.Raddr);
		if c != nil {
			c.Close()
		}
		if e == nil {
			t.Errorf("#%d: nil error, want match for %#q", i, tt.Pattern);
			continue;
		}
		s := e.String();
		match, _ := regexp.MatchString(tt.Pattern, s);
		if !match {
			t.Errorf("#%d: %q, want match for %#q", i, s, tt.Pattern)
		}
	}
}
<|endoftext|>


<commit_before>// 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 os_test

import (
	. "os";
	"testing";
)

func TestMkdirAll(t *testing.T) {
	// Create new dir, in _obj so it will get
	// cleaned up by make if not by us.
	path := "_obj/_TestMkdirAll_/dir/./dir2";
	err := MkdirAll(path, 0777);
	if err != nil {
		t.Fatalf("MkdirAll %q: %s", path, err)
	}

	// Already exists, should succeed.
	err = MkdirAll(path, 0777);
	if err != nil {
		t.Fatalf("MkdirAll %q (second time): %s", path, err)
	}

	// Make file.
	fpath := path + "/file";
	_, err = Open(fpath, O_WRONLY|O_CREAT, 0666);
	if err != nil {
		t.Fatalf("create %q: %s", fpath, err)
	}

	// Can't make directory named after file.
	err = MkdirAll(fpath, 0777);
	if err == nil {
		t.Fatalf("MkdirAll %q: no error")
	}
	perr, ok := err.(*PathError);
	if !ok {
		t.Fatalf("MkdirAll %q returned %T, not *PathError", fpath, err)
	}
	if perr.Path != fpath {
		t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", fpath, perr.Path, fpath)
	}

	// Can't make subdirectory of file.
	ffpath := fpath + "/subdir";
	err = MkdirAll(ffpath, 0777);
	if err == nil {
		t.Fatalf("MkdirAll %q: no error")
	}
	perr, ok = err.(*PathError);
	if !ok {
		t.Fatalf("MkdirAll %q returned %T, not *PathError", ffpath, err)
	}
	if perr.Path != fpath {
		t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", ffpath, perr.Path, fpath)
	}

	RemoveAll("_obj/_TestMkdirAll_");
}

func TestRemoveAll(t *testing.T) {
	// Work directory.
	path := "_obj/_TestRemoveAll_";
	fpath := path + "/file";
	dpath := path + "/dir";

	// Make directory with 1 file and remove.
	if err := MkdirAll(path, 0777); err != nil {
		t.Fatalf("MkdirAll %q: %s", path, err)
	}
	fd, err := Open(fpath, O_WRONLY|O_CREAT, 0666);
	if err != nil {
		t.Fatalf("create %q: %s", fpath, err)
	}
	fd.Close();
	if err = RemoveAll(path); err != nil {
		t.Fatalf("RemoveAll %q (first): %s", path, err)
	}
	if _, err := Lstat(path); err == nil {
		t.Fatalf("Lstat %q succeeded after RemoveAll (first)", path)
	}

	// Make directory with file and subdirectory and remove.
	if err = MkdirAll(dpath, 0777); err != nil {
		t.Fatalf("MkdirAll %q: %s", dpath, err)
	}
	fd, err = Open(fpath, O_WRONLY|O_CREAT, 0666);
	if err != nil {
		t.Fatalf("create %q: %s", fpath, err)
	}
	fd.Close();
	fd, err = Open(dpath+"/file", O_WRONLY|O_CREAT, 0666);
	if err != nil {
		t.Fatalf("create %q: %s", fpath, err)
	}
	fd.Close();
	if err = RemoveAll(path); err != nil {
		t.Fatalf("RemoveAll %q (second): %s", path, err)
	}
	if _, err := Lstat(path); err == nil {
		t.Fatalf("Lstat %q succeeded after RemoveAll (second)", path)
	}

	// Make directory with file and subdirectory and trigger error.
	if err = MkdirAll(dpath, 0777); err != nil {
		t.Fatalf("MkdirAll %q: %s", dpath, err)
	}

	for _, s := range []string{fpath, dpath + "/file1", path + "/zzz"} {
		fd, err = Open(s, O_WRONLY|O_CREAT, 0666);
		if err != nil {
			t.Fatalf("create %q: %s", s, err)
		}
		fd.Close();
	}
	if err = Chmod(dpath, 0); err != nil {
		t.Fatalf("Chmod %q 0: %s", dpath, err)
	}
	if err = RemoveAll(path); err == nil {
		_, err := Lstat(path);
		if err == nil {
			t.Errorf("Can lstat %q after supposed RemoveAll", path)
		}
		t.Fatalf("RemoveAll %q succeeded with chmod 0 subdirectory", path, err);
	}
	perr, ok := err.(*PathError);
	if !ok {
		t.Fatalf("RemoveAll %q returned %T not *PathError", path, err)
	}
	if perr.Path != dpath {
		t.Fatalf("RemoveAll %q failed at %q not %q", path, perr.Path, dpath)
	}
	if err = Chmod(dpath, 0777); err != nil {
		t.Fatalf("Chmod %q 0777: %s", dpath, err)
	}
	for _, s := range []string{fpath, path + "/zzz"} {
		if _, err := Lstat(s); err == nil {
			t.Fatalf("Lstat %q succeeded after partial RemoveAll", s)
		}
	}
	if err = RemoveAll(path); err != nil {
		t.Fatalf("RemoveAll %q after partial RemoveAll: %s", path, err)
	}
	if _, err := Lstat(path); err == nil {
		t.Fatalf("Lstat %q succeeded after RemoveAll (final)", path)
	}
}
<commit_msg>os: do not test error case of TestRemoveAll when root<commit_after>// 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 os_test

import (
	. "os";
	"testing";
)

func TestMkdirAll(t *testing.T) {
	// Create new dir, in _obj so it will get
	// cleaned up by make if not by us.
	path := "_obj/_TestMkdirAll_/dir/./dir2";
	err := MkdirAll(path, 0777);
	if err != nil {
		t.Fatalf("MkdirAll %q: %s", path, err)
	}

	// Already exists, should succeed.
	err = MkdirAll(path, 0777);
	if err != nil {
		t.Fatalf("MkdirAll %q (second time): %s", path, err)
	}

	// Make file.
	fpath := path + "/file";
	_, err = Open(fpath, O_WRONLY|O_CREAT, 0666);
	if err != nil {
		t.Fatalf("create %q: %s", fpath, err)
	}

	// Can't make directory named after file.
	err = MkdirAll(fpath, 0777);
	if err == nil {
		t.Fatalf("MkdirAll %q: no error")
	}
	perr, ok := err.(*PathError);
	if !ok {
		t.Fatalf("MkdirAll %q returned %T, not *PathError", fpath, err)
	}
	if perr.Path != fpath {
		t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", fpath, perr.Path, fpath)
	}

	// Can't make subdirectory of file.
	ffpath := fpath + "/subdir";
	err = MkdirAll(ffpath, 0777);
	if err == nil {
		t.Fatalf("MkdirAll %q: no error")
	}
	perr, ok = err.(*PathError);
	if !ok {
		t.Fatalf("MkdirAll %q returned %T, not *PathError", ffpath, err)
	}
	if perr.Path != fpath {
		t.Fatalf("MkdirAll %q returned wrong error path: %q not %q", ffpath, perr.Path, fpath)
	}

	RemoveAll("_obj/_TestMkdirAll_");
}

func TestRemoveAll(t *testing.T) {
	// Work directory.
	path := "_obj/_TestRemoveAll_";
	fpath := path + "/file";
	dpath := path + "/dir";

	// Make directory with 1 file and remove.
	if err := MkdirAll(path, 0777); err != nil {
		t.Fatalf("MkdirAll %q: %s", path, err)
	}
	fd, err := Open(fpath, O_WRONLY|O_CREAT, 0666);
	if err != nil {
		t.Fatalf("create %q: %s", fpath, err)
	}
	fd.Close();
	if err = RemoveAll(path); err != nil {
		t.Fatalf("RemoveAll %q (first): %s", path, err)
	}
	if _, err := Lstat(path); err == nil {
		t.Fatalf("Lstat %q succeeded after RemoveAll (first)", path)
	}

	// Make directory with file and subdirectory and remove.
	if err = MkdirAll(dpath, 0777); err != nil {
		t.Fatalf("MkdirAll %q: %s", dpath, err)
	}
	fd, err = Open(fpath, O_WRONLY|O_CREAT, 0666);
	if err != nil {
		t.Fatalf("create %q: %s", fpath, err)
	}
	fd.Close();
	fd, err = Open(dpath+"/file", O_WRONLY|O_CREAT, 0666);
	if err != nil {
		t.Fatalf("create %q: %s", fpath, err)
	}
	fd.Close();
	if err = RemoveAll(path); err != nil {
		t.Fatalf("RemoveAll %q (second): %s", path, err)
	}
	if _, err := Lstat(path); err == nil {
		t.Fatalf("Lstat %q succeeded after RemoveAll (second)", path)
	}

	if Getuid() != 0 {	// Test fails as root
		// Make directory with file and subdirectory and trigger error.
		if err = MkdirAll(dpath, 0777); err != nil {
			t.Fatalf("MkdirAll %q: %s", dpath, err)
		}

		for _, s := range []string{fpath, dpath + "/file1", path + "/zzz"} {
			fd, err = Open(s, O_WRONLY|O_CREAT, 0666);
			if err != nil {
				t.Fatalf("create %q: %s", s, err)
			}
			fd.Close();
		}
		if err = Chmod(dpath, 0); err != nil {
			t.Fatalf("Chmod %q 0: %s", dpath, err)
		}
		if err = RemoveAll(path); err == nil {
			_, err := Lstat(path);
			if err == nil {
				t.Errorf("Can lstat %q after supposed RemoveAll", path)
			}
			t.Fatalf("RemoveAll %q succeeded with chmod 0 subdirectory", path, err);
		}
		perr, ok := err.(*PathError);
		if !ok {
			t.Fatalf("RemoveAll %q returned %T not *PathError", path, err)
		}
		if perr.Path != dpath {
			t.Fatalf("RemoveAll %q failed at %q not %q", path, perr.Path, dpath)
		}
	}

	if err = Chmod(dpath, 0777); err != nil {
		t.Fatalf("Chmod %q 0777: %s", dpath, err)
	}
	for _, s := range []string{fpath, path + "/zzz"} {
		if _, err := Lstat(s); err == nil {
			t.Fatalf("Lstat %q succeeded after partial RemoveAll", s)
		}
	}
	if err = RemoveAll(path); err != nil {
		t.Fatalf("RemoveAll %q after partial RemoveAll: %s", path, err)
	}
	if _, err := Lstat(path); err == nil {
		t.Fatalf("Lstat %q succeeded after RemoveAll (final)", path)
	}
}
<|endoftext|>


<commit_before>package slice

import (
	"bufio"
	"encoding/binary"
	"fmt"
	"io"
	"math"
)

type STL struct {
	Layers   []*Layer
	Min, Max Vertex3

	facets []*facet
}

type facet struct {
	normal      Vertex3 //TODO: ignore?
	vertices    [3]Vertex3
	lowZ, highZ float64
}

func (f *facet) String() string {
	return fmt.Sprint(f.vertices)
}

type Vertex3 struct {
	X, Y, Z float64
}

func (v Vertex3) String() string {
	return fmt.Sprintf("(%0.3f,%0.3f,%0.3f)", v.X, v.Y, v.Z)
}

// Parse parses a new STL from an io.Reader.
func Parse(r io.Reader) (*STL, error) {
	// test for ascii stl format
	bufr := bufio.NewReader(r)
	top, err := bufr.Peek(6)
	if err != nil {
		return nil, err
	}
	if string(top) == "solid " {
		return nil, fmt.Errorf("ascii format STL not supported")
	}

	// discard text header
	if _, err := bufr.Discard(80); err != nil {
		return nil, fmt.Errorf("error decoding STL: %v", err)
	}

	var nfacets uint32
	if err := binary.Read(bufr, binary.LittleEndian, &nfacets); err != nil {
		return nil, fmt.Errorf("error decoding STL: %v", err)
	}

	small := -math.MaxFloat64
	big := math.MaxFloat64
	min, max := Vertex3{big, big, big}, Vertex3{small, small, small}
	facets := make([]*facet, nfacets)
	for i := range facets {
		normal, err := getVertex(bufr)
		if err != nil {
			return nil, fmt.Errorf("error decoding STL: %v", err)
		}
		var vertices [3]Vertex3
		for vi := range vertices {
			v, err := getVertex(bufr)
			if err != nil {
				return nil, fmt.Errorf("error decoding STL: %v", err)
			}
			vertices[vi] = v
			min.X = math.Min(min.X, v.X)
			max.X = math.Max(max.X, v.X)
			min.Y = math.Min(min.Y, v.Y)
			max.Y = math.Max(max.Y, v.Y)
			min.Z = math.Min(min.Z, v.Z)
			max.Z = math.Max(max.Z, v.Z)
		}
		facets[i] = &facet{
			normal:   normal,
			vertices: vertices,
			lowZ:     math.Min(math.Min(vertices[0].Z, vertices[1].Z), vertices[2].Z),
			highZ:    math.Max(math.Max(vertices[0].Z, vertices[1].Z), vertices[2].Z),
		}
		if _, err := bufr.Discard(2); err != nil {
			return nil, fmt.Errorf("error decoding STL: %v", err)
		}
	}

	s := STL{
		facets: facets,
		Min:    min,
		Max:    max,
	}
	return &s, nil
}

func getVertex(r io.Reader) (Vertex3, error) {
	var x, z, y float32
	err := binary.Read(r, binary.LittleEndian, &x)
	if err != nil {
		return Vertex3{}, err
	}
	err = binary.Read(r, binary.LittleEndian, &y)
	if err != nil {
		return Vertex3{}, err
	}
	err = binary.Read(r, binary.LittleEndian, &z)
	if err != nil {
		return Vertex3{}, err
	}

	v := Vertex3{X: float64(x), Y: float64(y), Z: float64(z)}
	return v, nil
}
<commit_msg>save some parsing time by discarding facet normals<commit_after>package slice

import (
	"bufio"
	"encoding/binary"
	"fmt"
	"io"
	"math"
)

type STL struct {
	Layers   []*Layer
	Min, Max Vertex3

	facets []*facet
}

type facet struct {
	vertices    [3]Vertex3
	lowZ, highZ float64
}

func (f *facet) String() string {
	return fmt.Sprint(f.vertices)
}

type Vertex3 struct {
	X, Y, Z float64
}

func (v Vertex3) String() string {
	return fmt.Sprintf("(%0.3f,%0.3f,%0.3f)", v.X, v.Y, v.Z)
}

// Parse parses a new STL from an io.Reader.
func Parse(r io.Reader) (*STL, error) {
	// test for ascii stl format
	bufr := bufio.NewReader(r)
	top, err := bufr.Peek(6)
	if err != nil {
		return nil, err
	}
	if string(top) == "solid " {
		return nil, fmt.Errorf("ascii format STL not supported")
	}

	// discard text header
	if _, err := bufr.Discard(80); err != nil {
		return nil, fmt.Errorf("error decoding STL: %v", err)
	}

	var nfacets uint32
	if err := binary.Read(bufr, binary.LittleEndian, &nfacets); err != nil {
		return nil, fmt.Errorf("error decoding STL: %v", err)
	}

	small := -math.MaxFloat64
	big := math.MaxFloat64
	min, max := Vertex3{big, big, big}, Vertex3{small, small, small}
	facets := make([]*facet, nfacets)
	for i := range facets {
		bufr.Discard(12) // discard normal
		var vertices [3]Vertex3
		for vi := range vertices {
			v, err := getVertex(bufr)
			if err != nil {
				return nil, fmt.Errorf("error decoding STL: %v", err)
			}
			vertices[vi] = v
			min.X = math.Min(min.X, v.X)
			max.X = math.Max(max.X, v.X)
			min.Y = math.Min(min.Y, v.Y)
			max.Y = math.Max(max.Y, v.Y)
			min.Z = math.Min(min.Z, v.Z)
			max.Z = math.Max(max.Z, v.Z)
		}
		facets[i] = &facet{
			vertices: vertices,
			lowZ:     math.Min(math.Min(vertices[0].Z, vertices[1].Z), vertices[2].Z),
			highZ:    math.Max(math.Max(vertices[0].Z, vertices[1].Z), vertices[2].Z),
		}
		if _, err := bufr.Discard(2); err != nil {
			return nil, fmt.Errorf("error decoding STL: %v", err)
		}
	}

	s := STL{
		facets: facets,
		Min:    min,
		Max:    max,
	}
	return &s, nil
}

func getVertex(r io.Reader) (Vertex3, error) {
	var x, z, y float32
	err := binary.Read(r, binary.LittleEndian, &x)
	if err != nil {
		return Vertex3{}, err
	}
	err = binary.Read(r, binary.LittleEndian, &y)
	if err != nil {
		return Vertex3{}, err
	}
	err = binary.Read(r, binary.LittleEndian, &z)
	if err != nil {
		return Vertex3{}, err
	}

	v := Vertex3{X: float64(x), Y: float64(y), Z: float64(z)}
	return v, nil
}
<|endoftext|>


<commit_before>package html

import (
	"net"
	"net/url"
	"strings"

	"github.com/dop251/goja"
)

//go:generate go run gen/main.go

var defaultPorts = map[string]string{
	"http":  "80",
	"https": "443",
	"ftp":   "21",
}

const (
	AnchorTagName = "a"
	AreaTagName   = "area"
	BaseTagName   = "base"
	ButtonTagName = "button"
)

type HrefElement struct{ Element }
type AnchorElement struct{ HrefElement }
type AreaElement struct{ HrefElement }

type BaseElement struct{ Element }
type ButtonElement struct{ Element }

func (h HrefElement) hrefURL() *url.URL {
	url, err := url.Parse(h.attrAsString("href"))
	if err != nil {
		url, _ = url.Parse("")
	}

	return url
}

func (h HrefElement) Hash() string {
	return "#" + h.hrefURL().Fragment
}

func (h HrefElement) Host() string {
	url := h.hrefURL()
	hostAndPort := url.Host

	host, port, err := net.SplitHostPort(hostAndPort)
	if err != nil {
		return hostAndPort
	}

	defaultPort := defaultPorts[url.Scheme]
	if defaultPort != "" && port == defaultPort {
		return strings.TrimSuffix(host, ":"+defaultPort)
	}

	return hostAndPort
}

func (h HrefElement) Hostname() string {
	host, _, err := net.SplitHostPort(h.hrefURL().Host)
	if err != nil {
		return h.hrefURL().Host
	}
	return host
}

func (h HrefElement) Port() string {
	_, port, err := net.SplitHostPort(h.hrefURL().Host)
	if err != nil {
		return ""
	}
	return port
}

func (h HrefElement) Username() string {
	user := h.hrefURL().User
	if user == nil {
		return ""
	}
	return user.Username()
}

func (h HrefElement) Password() goja.Value {
	user := h.hrefURL().User
	if user == nil {
		return goja.Undefined()
	}

	pwd, defined := user.Password()
	if !defined {
		return goja.Undefined()
	}

	return h.sel.rt.ToValue(pwd)
}

func (h HrefElement) Origin() string {
	href := h.hrefURL()

	if href.Scheme == "file" {
		return h.Href()
	}

	return href.Scheme + "://" + href.Host
}

func (h HrefElement) Pathname() string {
	return h.hrefURL().Path
}

func (h HrefElement) Protocol() string {
	return h.hrefURL().Scheme
}

func (h HrefElement) RelList() []string {
	rel := h.attrAsString("rel")

	if rel == "" {
		return make([]string, 0)
	}

	return strings.Split(rel, " ")
}

func (h HrefElement) Search() string {
	q := h.hrefURL().RawQuery
	if q == "" {
		return q
	}
	return "?" + q
}

func (h HrefElement) Text() string {
	return h.TextContent()
}

func (b ButtonElement) Form() goja.Value {
	formSel, exists := b.ownerFormSel()
	if !exists {
		return goja.Undefined()
	}
	return selToElement(Selection{b.sel.rt, formSel})
}

// Used by the formAction, formMethod, formTarget and formEnctype methods of Button and Input elements
// Attempts to read attribute "form" + attrName on the current element or attrName on the owning form element
func (e Element) formAttrOrElemOverride(attrName string) string {
	if elemAttr, exists := e.sel.sel.Attr("form" + attrName); exists {
		return elemAttr
	}

	formSel, exists := e.ownerFormSel()
	if !exists {
		return ""
	}

	formAttr, exists := formSel.Attr(attrName)
	if !exists {
		return ""
	}

	return formAttr
}

// Used by the formAction, formMethod, formTarget and formEnctype methods of Button and Input elements
// Attempts to read attribute "form" + attrName on the current element or attrName on the owning form element
func (e Element) formOrElemAttrString(attrName string) string {
	if elemAttr, exists := e.sel.sel.Attr("form" + attrName); exists {
		return elemAttr
	}

	formSel, exists := e.ownerFormSel()
	if !exists {
		return ""
	}

	formAttr, exists := formSel.Attr(attrName)
	if !exists {
		return ""
	}

	return formAttr
}

func (e Element) formOrElemAttrPresent(attrName string) bool {
	if _, exists := e.sel.sel.Attr("form" + attrName); exists {
		return true
	}

	formSel, exists := e.ownerFormSel()
	if !exists {
		return false
	}

	_, exists = formSel.Attr(attrName)
	return exists
}

func (b ButtonElement) FormAction() string {
	return b.formOrElemAttrString("action")
}

func (b ButtonElement) FormEnctype() string {
	return b.formOrElemAttrString("enctype")
}

func (b ButtonElement) FormMethod() string {
	return b.formOrElemAttrString("method")
}

func (b ButtonElement) FormNoValidate() bool {
	return b.formOrElemAttrPresent("novalidate")
}

func (b ButtonElement) FormTarget() string {
	return b.formOrElemAttrString("target")
}

func (e Element) elemLabels() (items []goja.Value) {
	wrapperLbl := e.sel.sel.Closest("label")

	id := e.attrAsString("id")
	if id == "" {
		return elemList(Selection{e.sel.rt, wrapperLbl})
	}

	idLbl := e.sel.sel.Parents().Last().Find("label[for=\"" + id + "\"]")
	if idLbl.Size() == 0 {
		return elemList(Selection{e.sel.rt, wrapperLbl})
	}

	allLbls := wrapperLbl.AddSelection(idLbl)

	return elemList(Selection{e.sel.rt, allLbls})
}

func (b ButtonElement) Labels() (items []goja.Value) {
	return b.elemLabels()
}

// func (b ButtonElement) Name() string {
// 	return b.attrAsString("name")
// }

func (b ButtonElement) Type() string {
	switch b.attrAsString("type") {
	case "button":
		return "button"
	case "menu":
		return "menu"
	case "reset":
		return "reset"
	default:
		return "submit"
	}
}

// func (b ButtonElement) Value() string {
// 	return b.attrAsString("value")
// }
<commit_msg>Move some form related methods from ButtonElement/Element to a FormFieldElement struct so they can be used by InputElement/SelectElement<commit_after>package html

import (
	"net"
	"net/url"
	"strings"

	"github.com/dop251/goja"
)

//go:generate go run gen/main.go

var defaultPorts = map[string]string{
	"http":  "80",
	"https": "443",
	"ftp":   "21",
}

const (
	AnchorTagName = "a"
	AreaTagName   = "area"
	BaseTagName   = "base"
	ButtonTagName = "button"
)

type HrefElement struct{ Element }
type FormFieldElement struct{ Element }

type AnchorElement struct{ HrefElement }
type AreaElement struct{ HrefElement }

type BaseElement struct{ Element }
type ButtonElement struct{ FormFieldElement }

func (h HrefElement) hrefURL() *url.URL {
	url, err := url.Parse(h.attrAsString("href"))
	if err != nil {
		url, _ = url.Parse("")
	}

	return url
}

func (h HrefElement) Hash() string {
	return "#" + h.hrefURL().Fragment
}

func (h HrefElement) Host() string {
	url := h.hrefURL()
	hostAndPort := url.Host

	host, port, err := net.SplitHostPort(hostAndPort)
	if err != nil {
		return hostAndPort
	}

	defaultPort := defaultPorts[url.Scheme]
	if defaultPort != "" && port == defaultPort {
		return strings.TrimSuffix(host, ":"+defaultPort)
	}

	return hostAndPort
}

func (h HrefElement) Hostname() string {
	host, _, err := net.SplitHostPort(h.hrefURL().Host)
	if err != nil {
		return h.hrefURL().Host
	}
	return host
}

func (h HrefElement) Port() string {
	_, port, err := net.SplitHostPort(h.hrefURL().Host)
	if err != nil {
		return ""
	}
	return port
}

func (h HrefElement) Username() string {
	user := h.hrefURL().User
	if user == nil {
		return ""
	}
	return user.Username()
}

func (h HrefElement) Password() goja.Value {
	user := h.hrefURL().User
	if user == nil {
		return goja.Undefined()
	}

	pwd, defined := user.Password()
	if !defined {
		return goja.Undefined()
	}

	return h.sel.rt.ToValue(pwd)
}

func (h HrefElement) Origin() string {
	href := h.hrefURL()

	if href.Scheme == "file" {
		return h.Href()
	}

	return href.Scheme + "://" + href.Host
}

func (h HrefElement) Pathname() string {
	return h.hrefURL().Path
}

func (h HrefElement) Protocol() string {
	return h.hrefURL().Scheme
}

func (h HrefElement) RelList() []string {
	rel := h.attrAsString("rel")

	if rel == "" {
		return make([]string, 0)
	}

	return strings.Split(rel, " ")
}

func (h HrefElement) Search() string {
	q := h.hrefURL().RawQuery
	if q == "" {
		return q
	}
	return "?" + q
}

func (h HrefElement) Text() string {
	return h.TextContent()
}

func (f FormFieldElement) Form() goja.Value {
	formSel, exists := f.ownerFormSel()
	if !exists {
		return goja.Undefined()
	}
	return selToElement(Selection{f.sel.rt, formSel})
}

// Used by the formAction, formMethod, formTarget and formEnctype methods of Button and Input elements
// Attempts to read attribute "form" + attrName on the current element or attrName on the owning form element
func (f FormFieldElement) formAttrOrElemOverride(attrName string) string {
	if elemAttr, exists := f.sel.sel.Attr("form" + attrName); exists {
		return elemAttr
	}

	formSel, exists := f.ownerFormSel()
	if !exists {
		return ""
	}

	formAttr, exists := formSel.Attr(attrName)
	if !exists {
		return ""
	}

	return formAttr
}

// Used by the formAction, formMethod, formTarget and formEnctype methods of Button and Input elements
// Attempts to read attribute "form" + attrName on the current element or attrName on the owning form element
func (f FormFieldElement) formOrElemAttrString(attrName string) string {
	if elemAttr, exists := f.sel.sel.Attr("form" + attrName); exists {
		return elemAttr
	}

	formSel, exists := f.ownerFormSel()
	if !exists {
		return ""
	}

	formAttr, exists := formSel.Attr(attrName)
	if !exists {
		return ""
	}

	return formAttr
}

func (f FormFieldElement) formOrElemAttrPresent(attrName string) bool {
	if _, exists := f.sel.sel.Attr("form" + attrName); exists {
		return true
	}

	formSel, exists := f.ownerFormSel()
	if !exists {
		return false
	}

	_, exists = formSel.Attr(attrName)
	return exists
}

func (f FormFieldElement) FormAction() string {
	return f.formOrElemAttrString("action")
}

func (f FormFieldElement) FormEnctype() string {
	return f.formOrElemAttrString("enctype")
}

func (f FormFieldElement) FormMethod() string {
	return f.formOrElemAttrString("method")
}

func (f FormFieldElement) FormNoValidate() bool {
	return f.formOrElemAttrPresent("novalidate")
}

func (f FormFieldElement) FormTarget() string {
	return f.formOrElemAttrString("target")
}

func (f FormFieldElement) elemLabels() (items []goja.Value) {
	wrapperLbl := f.sel.sel.Closest("label")

	id := f.attrAsString("id")
	if id == "" {
		return elemList(Selection{f.sel.rt, wrapperLbl})
	}

	idLbl := f.sel.sel.Parents().Last().Find("label[for=\"" + id + "\"]")
	if idLbl.Size() == 0 {
		return elemList(Selection{f.sel.rt, wrapperLbl})
	}

	allLbls := wrapperLbl.AddSelection(idLbl)

	return elemList(Selection{f.sel.rt, allLbls})
}

func (f FormFieldElement) Labels() (items []goja.Value) {
	return f.elemLabels()
}

func (b ButtonElement) Type() string {
	switch b.attrAsString("type") {
	case "button":
		return "button"
	case "menu":
		return "menu"
	case "reset":
		return "reset"
	default:
		return "submit"
	}
}
<|endoftext|>


<commit_before>// +build !wasm

package reader

import (
	"context"
	"fmt"
	"time"

	"github.com/Jeffail/benthos/v3/lib/log"
	"github.com/Jeffail/benthos/v3/lib/message"
	"github.com/Jeffail/benthos/v3/lib/message/batch"
	"github.com/Jeffail/benthos/v3/lib/metrics"
	"github.com/Jeffail/benthos/v3/lib/types"
	sess "github.com/Jeffail/benthos/v3/lib/util/aws/session"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/patrobinson/gokini"
)

//------------------------------------------------------------------------------

// KinesisBalancedConfig is configuration values for the input type.
type KinesisBalancedConfig struct {
	sess.Config           `json:",inline" yaml:",inline"`
	Stream                string `json:"stream" yaml:"stream"`
	DynamoDBTable         string `json:"dynamodb_table" yaml:"dynamodb_table"`
	DynamoDBBillingMode   string `json:"dynamodb_billing_mode" yaml:"dynamodb_billing_mode"`
	DynamoDBReadCapacity  int64  `json:"dynamodb_read_provision" yaml:"dynamodb_read_provision"`
	DynamoDBWriteCapacity int64  `json:"dynamodb_write_provision" yaml:"dynamodb_write_provision"`
	// TODO: V4 Remove this.
	MaxBatchCount   int                `json:"max_batch_count" yaml:"max_batch_count"`
	Batching        batch.PolicyConfig `json:"batching" yaml:"batching"`
	StartFromOldest bool               `json:"start_from_oldest" yaml:"start_from_oldest"`
}

// NewKinesisBalancedConfig creates a new Config with default values.
func NewKinesisBalancedConfig() KinesisBalancedConfig {
	batchConf := batch.NewPolicyConfig()
	batchConf.Count = 1
	s := sess.NewConfig()
	return KinesisBalancedConfig{
		Config:                s,
		Stream:                "",
		DynamoDBTable:         "",
		DynamoDBBillingMode:   "",
		DynamoDBReadCapacity:  0,
		DynamoDBWriteCapacity: 0,
		MaxBatchCount:         1,
		Batching:              batchConf,
		StartFromOldest:       true,
	}
}

//------------------------------------------------------------------------------

// KinesisBalanced is a benthos reader.Type implementation that reads messages
// from an Amazon Kinesis stream.
type KinesisBalanced struct {
	conf KinesisBalancedConfig

	session *session.Session

	lastSequence *string
	namespace    string

	log     log.Modular
	stats   metrics.Type
	kc      *gokini.KinesisConsumer
	records chan *gokini.Records
	shardID string
}

// NewKinesisBalanced creates a new Amazon Kinesis stream reader.Type.
func NewKinesisBalanced(
	conf KinesisBalancedConfig,
	log log.Modular,
	stats metrics.Type,
) (*KinesisBalanced, error) {
	consumer := &KinesisBalanced{
		conf:  conf,
		log:   log,
		stats: stats,
	}
	sess, err := conf.GetSession()
	if err != nil {
		return nil, err
	}
	kc := &gokini.KinesisConsumer{
		StreamName:                  conf.Stream,
		ShardIteratorType:           "TRIM_HORIZON",
		RecordConsumer:              consumer,
		TableName:                   conf.DynamoDBTable,
		EmptyRecordBackoffMs:        1000,
		DisableAutomaticCheckpoints: true,
		Session:                     sess,
	}
	if !consumer.conf.StartFromOldest {
		kc.ShardIteratorType = "LATEST"
	}
	if consumer.conf.DynamoDBBillingMode != "" {
		kc.DynamoBillingMode = &consumer.conf.DynamoDBBillingMode
	}
	if consumer.conf.DynamoDBReadCapacity != 0 && consumer.conf.DynamoDBWriteCapacity != 0 {
		kc.DynamoReadCapacityUnits = &consumer.conf.DynamoDBReadCapacity
		kc.DynamoWriteCapacityUnits = &consumer.conf.DynamoDBWriteCapacity
	}

	consumer.kc = kc
	return consumer, nil
}

// Connect attempts to establish a connection to the target Kinesis stream.
func (k *KinesisBalanced) Connect() error {
	return k.ConnectWithContext(context.Background())
}

// ConnectWithContext attempts to establish a connection to the target Kinesis
// stream.
func (k *KinesisBalanced) ConnectWithContext(ctx context.Context) error {
	err := k.kc.StartConsumer()

	k.log.Infof("Receiving Amazon Kinesis messages from stream: %v\n", k.conf.Stream)
	return err
}

func (k *KinesisBalanced) setMetadata(record *gokini.Records, p types.Part) {
	met := p.Metadata()
	met.Set("kinesis_shard", k.shardID)
	met.Set("kinesis_partition_key", record.PartitionKey)
	met.Set("kinesis_sequence_number", record.SequenceNumber)
}

// ReadWithContext attempts to read a new message from the target Kinesis
// stream.
func (k *KinesisBalanced) ReadWithContext(ctx context.Context) (types.Message, AsyncAckFn, error) {
	var record *gokini.Records
	select {
	case record = <-k.records:
	case <-ctx.Done():
		return nil, nil, types.ErrTimeout
	}
	if record == nil {
		return nil, nil, fmt.Errorf("shard '%s' has closed", k.shardID)
	}

	part := message.NewPart(record.Data)
	k.setMetadata(record, part)

	msg := message.New(nil)
	msg.Append(part)

	return msg, func(rctx context.Context, res types.Response) error {
		return k.kc.Checkpoint(k.shardID, record.SequenceNumber)
	}, nil
}

// Read attempts to read a new message from the target Kinesis stream.
func (k *KinesisBalanced) Read() (types.Message, error) {
	msg := message.New(nil)

	record := <-k.records
	if record == nil {
		return nil, fmt.Errorf("shard '%s' has closed", k.shardID)
	}
	k.lastSequence = &record.SequenceNumber
	{
		part := message.NewPart(record.Data)
		k.setMetadata(record, part)
		msg.Append(part)
	}

batchLoop:
	for i := 1; i < k.conf.MaxBatchCount; i++ {
		select {
		case record := <-k.records:
			if record != nil {
				k.lastSequence = &record.SequenceNumber
				part := message.NewPart(record.Data)
				k.setMetadata(record, part)
				msg.Append(part)
			} else {
				break batchLoop
			}
		default:
			// Drained the buffer
			break batchLoop
		}
	}

	return msg, nil
}

// Acknowledge confirms whether or not our unacknowledged messages have been
// successfully propagated or not.
func (k *KinesisBalanced) Acknowledge(err error) error {
	if err == nil && k.lastSequence != nil {
		return k.kc.Checkpoint(k.shardID, *k.lastSequence)
	}
	return nil
}

// CloseAsync begins cleaning up resources used by this reader asynchronously.
func (k *KinesisBalanced) CloseAsync() {
	go k.kc.Shutdown()
}

// WaitForClose will block until either the reader is closed or a specified
// timeout occurs.
func (k *KinesisBalanced) WaitForClose(time.Duration) error {
	return nil
}

// Init is required by the KinesisConsumer interface
func (k *KinesisBalanced) Init(shardID string) error {
	k.shardID = shardID
	return nil
}

// ProcessRecords implements the KinesisConsumer interface
func (k *KinesisBalanced) ProcessRecords(records []*gokini.Records, _ *gokini.KinesisConsumer) {
	for _, record := range records {
		k.records <- record
	}
}

// Shutdown implements the KinesisConsumer interface
func (k *KinesisBalanced) Shutdown() {
	k.log.Infof("Stopping processing of Stream %s Shard %s", k.conf.Stream, k.shardID)
	close(k.records)
}

//------------------------------------------------------------------------------
<commit_msg>Make records chan so ProcessRecords doesn't block on nil chan (#413)<commit_after>// +build !wasm

package reader

import (
	"context"
	"fmt"
	"time"

	"github.com/Jeffail/benthos/v3/lib/log"
	"github.com/Jeffail/benthos/v3/lib/message"
	"github.com/Jeffail/benthos/v3/lib/message/batch"
	"github.com/Jeffail/benthos/v3/lib/metrics"
	"github.com/Jeffail/benthos/v3/lib/types"
	sess "github.com/Jeffail/benthos/v3/lib/util/aws/session"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/patrobinson/gokini"
)

//------------------------------------------------------------------------------

// KinesisBalancedConfig is configuration values for the input type.
type KinesisBalancedConfig struct {
	sess.Config           `json:",inline" yaml:",inline"`
	Stream                string `json:"stream" yaml:"stream"`
	DynamoDBTable         string `json:"dynamodb_table" yaml:"dynamodb_table"`
	DynamoDBBillingMode   string `json:"dynamodb_billing_mode" yaml:"dynamodb_billing_mode"`
	DynamoDBReadCapacity  int64  `json:"dynamodb_read_provision" yaml:"dynamodb_read_provision"`
	DynamoDBWriteCapacity int64  `json:"dynamodb_write_provision" yaml:"dynamodb_write_provision"`
	// TODO: V4 Remove this.
	MaxBatchCount   int                `json:"max_batch_count" yaml:"max_batch_count"`
	Batching        batch.PolicyConfig `json:"batching" yaml:"batching"`
	StartFromOldest bool               `json:"start_from_oldest" yaml:"start_from_oldest"`
}

// NewKinesisBalancedConfig creates a new Config with default values.
func NewKinesisBalancedConfig() KinesisBalancedConfig {
	batchConf := batch.NewPolicyConfig()
	batchConf.Count = 1
	s := sess.NewConfig()
	return KinesisBalancedConfig{
		Config:                s,
		Stream:                "",
		DynamoDBTable:         "",
		DynamoDBBillingMode:   "",
		DynamoDBReadCapacity:  0,
		DynamoDBWriteCapacity: 0,
		MaxBatchCount:         1,
		Batching:              batchConf,
		StartFromOldest:       true,
	}
}

//------------------------------------------------------------------------------

// KinesisBalanced is a benthos reader.Type implementation that reads messages
// from an Amazon Kinesis stream.
type KinesisBalanced struct {
	conf KinesisBalancedConfig

	session *session.Session

	lastSequence *string
	namespace    string

	log     log.Modular
	stats   metrics.Type
	kc      *gokini.KinesisConsumer
	records chan *gokini.Records
	shardID string
}

// NewKinesisBalanced creates a new Amazon Kinesis stream reader.Type.
func NewKinesisBalanced(
	conf KinesisBalancedConfig,
	log log.Modular,
	stats metrics.Type,
) (*KinesisBalanced, error) {
	records := make(chan *gokini.Records)
	consumer := &KinesisBalanced{
		conf:    conf,
		log:     log,
		stats:   stats,
		records: records,
	}
	sess, err := conf.GetSession()
	if err != nil {
		return nil, err
	}
	kc := &gokini.KinesisConsumer{
		StreamName:                  conf.Stream,
		ShardIteratorType:           "TRIM_HORIZON",
		RecordConsumer:              consumer,
		TableName:                   conf.DynamoDBTable,
		EmptyRecordBackoffMs:        1000,
		DisableAutomaticCheckpoints: true,
		Session:                     sess,
	}
	if !consumer.conf.StartFromOldest {
		kc.ShardIteratorType = "LATEST"
	}
	if consumer.conf.DynamoDBBillingMode != "" {
		kc.DynamoBillingMode = &consumer.conf.DynamoDBBillingMode
	}
	if consumer.conf.DynamoDBReadCapacity != 0 && consumer.conf.DynamoDBWriteCapacity != 0 {
		kc.DynamoReadCapacityUnits = &consumer.conf.DynamoDBReadCapacity
		kc.DynamoWriteCapacityUnits = &consumer.conf.DynamoDBWriteCapacity
	}

	consumer.kc = kc
	return consumer, nil
}

// Connect attempts to establish a connection to the target Kinesis stream.
func (k *KinesisBalanced) Connect() error {
	return k.ConnectWithContext(context.Background())
}

// ConnectWithContext attempts to establish a connection to the target Kinesis
// stream.
func (k *KinesisBalanced) ConnectWithContext(ctx context.Context) error {
	err := k.kc.StartConsumer()

	k.log.Infof("Receiving Amazon Kinesis messages from stream: %v\n", k.conf.Stream)
	return err
}

func (k *KinesisBalanced) setMetadata(record *gokini.Records, p types.Part) {
	met := p.Metadata()
	met.Set("kinesis_shard", k.shardID)
	met.Set("kinesis_partition_key", record.PartitionKey)
	met.Set("kinesis_sequence_number", record.SequenceNumber)
}

// ReadWithContext attempts to read a new message from the target Kinesis
// stream.
func (k *KinesisBalanced) ReadWithContext(ctx context.Context) (types.Message, AsyncAckFn, error) {
	var record *gokini.Records
	select {
	case record = <-k.records:
	case <-ctx.Done():
		return nil, nil, types.ErrTimeout
	}
	if record == nil {
		return nil, nil, fmt.Errorf("shard '%s' has closed", k.shardID)
	}

	part := message.NewPart(record.Data)
	k.setMetadata(record, part)

	msg := message.New(nil)
	msg.Append(part)

	return msg, func(rctx context.Context, res types.Response) error {
		return k.kc.Checkpoint(k.shardID, record.SequenceNumber)
	}, nil
}

// Read attempts to read a new message from the target Kinesis stream.
func (k *KinesisBalanced) Read() (types.Message, error) {
	msg := message.New(nil)

	record := <-k.records
	if record == nil {
		return nil, fmt.Errorf("shard '%s' has closed", k.shardID)
	}
	k.lastSequence = &record.SequenceNumber
	{
		part := message.NewPart(record.Data)
		k.setMetadata(record, part)
		msg.Append(part)
	}

batchLoop:
	for i := 1; i < k.conf.MaxBatchCount; i++ {
		select {
		case record := <-k.records:
			if record != nil {
				k.lastSequence = &record.SequenceNumber
				part := message.NewPart(record.Data)
				k.setMetadata(record, part)
				msg.Append(part)
			} else {
				break batchLoop
			}
		default:
			// Drained the buffer
			break batchLoop
		}
	}

	return msg, nil
}

// Acknowledge confirms whether or not our unacknowledged messages have been
// successfully propagated or not.
func (k *KinesisBalanced) Acknowledge(err error) error {
	if err == nil && k.lastSequence != nil {
		return k.kc.Checkpoint(k.shardID, *k.lastSequence)
	}
	return nil
}

// CloseAsync begins cleaning up resources used by this reader asynchronously.
func (k *KinesisBalanced) CloseAsync() {
	go k.kc.Shutdown()
}

// WaitForClose will block until either the reader is closed or a specified
// timeout occurs.
func (k *KinesisBalanced) WaitForClose(time.Duration) error {
	return nil
}

// Init is required by the KinesisConsumer interface
func (k *KinesisBalanced) Init(shardID string) error {
	k.shardID = shardID
	return nil
}

// ProcessRecords implements the KinesisConsumer interface
func (k *KinesisBalanced) ProcessRecords(records []*gokini.Records, _ *gokini.KinesisConsumer) {
	for _, record := range records {
		k.records <- record
	}
}

// Shutdown implements the KinesisConsumer interface
func (k *KinesisBalanced) Shutdown() {
	k.log.Infof("Stopping processing of Stream %s Shard %s", k.conf.Stream, k.shardID)
	close(k.records)
}

//------------------------------------------------------------------------------
<|endoftext|>


<commit_before>package native

import (
	. "github.com/zxh0/jvm.go/jvmgo/any"
	"github.com/zxh0/jvm.go/jvmgo/jvm/rtda"
	rtc "github.com/zxh0/jvm.go/jvmgo/jvm/rtda/class"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/io"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/lang"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/lang/reflect"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/net"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/security"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/util"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/util/concurrent/atomic"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/util/jar"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/util/zip"
	_ "github.com/zxh0/jvm.go/jvmgo/native/sun/management"
	_ "github.com/zxh0/jvm.go/jvmgo/native/sun/misc"
	_ "github.com/zxh0/jvm.go/jvmgo/native/sun/nio/ch"
	_ "github.com/zxh0/jvm.go/jvmgo/native/sun/reflect"
)

// register native methods
func init() {
	rtc.SetRegisterNatives(registerNatives)
}

func registerNatives(frame *rtda.Frame) {
	// todo
}
<commit_msg>fix compile error<commit_after>package native

import (
	. "github.com/zxh0/jvm.go/jvmgo/any"
	"github.com/zxh0/jvm.go/jvmgo/jvm/rtda"
	rtc "github.com/zxh0/jvm.go/jvmgo/jvm/rtda/class"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/io"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/lang"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/lang/reflect"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/net"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/security"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/util"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/util/concurrent/atomic"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/util/jar"
	_ "github.com/zxh0/jvm.go/jvmgo/native/java/util/zip"
	_ "github.com/zxh0/jvm.go/jvmgo/native/sun/management"
	_ "github.com/zxh0/jvm.go/jvmgo/native/sun/misc"
	_ "github.com/zxh0/jvm.go/jvmgo/native/sun/reflect"
)

// register native methods
func init() {
	rtc.SetRegisterNatives(registerNatives)
}

func registerNatives(frame *rtda.Frame) {
	// todo
}
<|endoftext|>


<commit_before>package gomemcached

import (
	"fmt"
	"strings"
)

type TapConnectFlag uint32

const (
	BACKFILL           = TapConnectFlag(0x01)
	DUMP               = TapConnectFlag(0x02)
	LIST_VBUCKETS      = TapConnectFlag(0x04)
	TAKEOVER_VBUCKETS  = TapConnectFlag(0x08)
	SUPPORT_ACK        = TapConnectFlag(0x10)
	REQUEST_KEYS_ONLY  = TapConnectFlag(0x20)
	CHECKPOINT         = TapConnectFlag(0x40)
	REGISTERED_CLIENT  = TapConnectFlag(0x80)
	FIX_FLAG_BYTEORDER = TapConnectFlag(0x100)
)

var TapConnectFlagNames = map[TapConnectFlag]string{
	BACKFILL:           "BACKFILL",
	DUMP:               "DUMP",
	LIST_VBUCKETS:      "LIST_VBUCKETS",
	TAKEOVER_VBUCKETS:  "TAKEOVER_VBUCKETS",
	SUPPORT_ACK:        "SUPPORT_ACK",
	REQUEST_KEYS_ONLY:  "REQUEST_KEYS_ONLY",
	CHECKPOINT:         "CHECKPOINT",
	REGISTERED_CLIENT:  "REGISTERED_CLIENT",
	FIX_FLAG_BYTEORDER: "FIX_FLAG_BYTEORDER",
}

func (f TapConnectFlag) String() string {
	parts := []string{}
	for i := uint32(1); f != 0; i = i << 1 {
		if uint32(f)&i == i {
			p := TapConnectFlagNames[TapConnectFlag(i)]
			if p == "" {
				p = fmt.Sprintf("0x%x", i)
			}
			parts = append(parts, p)
		}
		f = TapConnectFlag(uint32(f) & (^i))
	}
	return strings.Join(parts, "|")
}
<commit_msg>Separate tap flag splitting and stringing.<commit_after>package gomemcached

import (
	"fmt"
	"strings"
)

type TapConnectFlag uint32

const (
	BACKFILL           = TapConnectFlag(0x01)
	DUMP               = TapConnectFlag(0x02)
	LIST_VBUCKETS      = TapConnectFlag(0x04)
	TAKEOVER_VBUCKETS  = TapConnectFlag(0x08)
	SUPPORT_ACK        = TapConnectFlag(0x10)
	REQUEST_KEYS_ONLY  = TapConnectFlag(0x20)
	CHECKPOINT         = TapConnectFlag(0x40)
	REGISTERED_CLIENT  = TapConnectFlag(0x80)
	FIX_FLAG_BYTEORDER = TapConnectFlag(0x100)
)

var TapConnectFlagNames = map[TapConnectFlag]string{
	BACKFILL:           "BACKFILL",
	DUMP:               "DUMP",
	LIST_VBUCKETS:      "LIST_VBUCKETS",
	TAKEOVER_VBUCKETS:  "TAKEOVER_VBUCKETS",
	SUPPORT_ACK:        "SUPPORT_ACK",
	REQUEST_KEYS_ONLY:  "REQUEST_KEYS_ONLY",
	CHECKPOINT:         "CHECKPOINT",
	REGISTERED_CLIENT:  "REGISTERED_CLIENT",
	FIX_FLAG_BYTEORDER: "FIX_FLAG_BYTEORDER",
}

// Split the ORed flags into the individual bit flags.
func (f TapConnectFlag) SplitFlags() []TapConnectFlag {
	rv := []TapConnectFlag{}
	for i := uint32(1); f != 0; i = i << 1 {
		if uint32(f)&i == i {
			rv = append(rv, TapConnectFlag(i))
		}
		f = TapConnectFlag(uint32(f) & (^i))
	}
	return rv
}

func (f TapConnectFlag) String() string {
	parts := []string{}
	for _, x := range f.SplitFlags() {
		p := TapConnectFlagNames[x]
		if p == "" {
			p = fmt.Sprintf("0x%x", int(x))
		}
		parts = append(parts, p)
	}
<|endoftext|>


<commit_before>package qshell

import (
	"bufio"
	"crypto/md5"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/qiniu/api.v6/auth/digest"
	"github.com/qiniu/log"
	"github.com/qiniu/rpc"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"
)

/*
{
	"dest_dir"		:	"/Users/jemy/Backup",
	"bucket"		:	"test-bucket",
	"domain"		:	"<Your bucket domain>",
	"access_key"	:	"<Your AccessKey>",
	"secret_key"	:	"<Your SecretKey>",
	"is_private"	:	false,
	"prefix"		:	"demo/",
	"suffix"		: ".mp4"
}
*/

const (
	MIN_DOWNLOAD_THREAD_COUNT = 1
	MAX_DOWNLOAD_THREAD_COUNT = 100
)

type DownloadConfig struct {
	DestDir   string `json:"dest_dir"`
	Bucket    string `json:"bucket"`
	Domain    string `json:"domain"`
	AccessKey string `json:"access_key"`
	SecretKey string `json:"secret_key"`
	IsPrivate bool   `json:"is_private"`
	Prefix    string `json:"prefix,omitempty"`
	Suffix    string `json:"suffix,omitempty"`
}

func QiniuDownload(threadCount int, downloadConfigFile string) {
	timeStart := time.Now()
	cnfFp, err := os.Open(downloadConfigFile)
	if err != nil {
		log.Error("Open download config file", downloadConfigFile, "failed,", err)
		return
	}
	defer cnfFp.Close()
	cnfData, err := ioutil.ReadAll(cnfFp)
	if err != nil {
		log.Error("Read download config file error", err)
		return
	}
	downConfig := DownloadConfig{}
	cnfErr := json.Unmarshal(cnfData, &downConfig)
	if cnfErr != nil {
		log.Error("Parse download config error", err)
		return
	}
	cnfJson, _ := json.Marshal(&downConfig)
	jobId := fmt.Sprintf("%x", md5.Sum(cnfJson))
	jobListName := fmt.Sprintf("%s.list.txt", jobId)
	acct := Account{
		AccessKey: downConfig.AccessKey,
		SecretKey: downConfig.SecretKey,
	}
	bLister := ListBucket{
		Account: acct,
	}
	log.Debug("List bucket...")
	listErr := bLister.List(downConfig.Bucket, downConfig.Prefix, jobListName)
	if listErr != nil {
		log.Error("List bucket error", listErr)
		return
	}
	listFp, openErr := os.Open(jobListName)
	if openErr != nil {
		log.Error("Open list file error", openErr)
		return
	}
	defer listFp.Close()
	listScanner := bufio.NewScanner(listFp)
	listScanner.Split(bufio.ScanLines)
	downWorkGroup := sync.WaitGroup{}

	totalCount := 0
	existsCount := 0

	var successCount int32 = 0
	var failCount int32 = 0

	threadThreshold := threadCount + 1
	for listScanner.Scan() {
		totalCount += 1
		if totalCount%threadThreshold == 0 {
			downWorkGroup.Wait()
		}
		line := strings.TrimSpace(listScanner.Text())
		items := strings.Split(line, "\t")
		if len(items) > 2 {
			fileKey := items[0]
			//check suffix
			if downConfig.Suffix != "" && !strings.HasSuffix(fileKey, downConfig.Suffix) {
				continue
			}
			fileSize, _ := strconv.ParseInt(items[1], 10, 64)
			//not backup yet
			if !checkLocalDuplicate(downConfig.DestDir, fileKey, fileSize) {
				downWorkGroup.Add(1)
				go func() {
					defer downWorkGroup.Done()
					downErr := downloadFile(downConfig, fileKey)
					if downErr != nil {
						atomic.AddInt32(&failCount, 1)
					} else {
						atomic.AddInt32(&successCount, 1)
					}
				}()
			} else {
				existsCount += 1
			}
		}
	}
	downWorkGroup.Wait()

	log.Info("-------Download Result-------")
	log.Info("Total:\t", totalCount)
	log.Info("Local:\t", existsCount)
	log.Info("Success:\t", successCount)
	log.Info("Failure:\t", failCount)
	log.Info("Duration:\t", time.Since(timeStart))
	log.Info("-----------------------------")
}

func checkLocalDuplicate(destDir string, fileKey string, fileSize int64) bool {
	dup := false
	filePath := filepath.Join(destDir, fileKey)
	fStat, statErr := os.Stat(filePath)
	if statErr == nil {
		//exist, check file size
		localFileSize := fStat.Size()
		if localFileSize == fileSize {
			dup = true
		}
	}
	return dup
}

func downloadFile(downConfig DownloadConfig, fileKey string) (err error) {
	localFilePath := filepath.Join(downConfig.DestDir, fileKey)
	ldx := strings.LastIndex(localFilePath, string(os.PathSeparator))
	if ldx != -1 {
		localFileDir := localFilePath[:ldx]
		mkdirErr := os.MkdirAll(localFileDir, 0775)
		if mkdirErr != nil {
			err = mkdirErr
			log.Error("MkdirAll failed for", localFileDir)
			return
		}
	}
	log.Info("Downloading", fileKey, "=>", localFilePath, "...")
	downUrl := strings.Join([]string{downConfig.Domain, fileKey}, "/")
	if downConfig.IsPrivate {
		now := time.Now().Add(time.Second * 3600 * 24)
		downUrl = fmt.Sprintf("%s?e=%d", downUrl, now.Unix())
		mac := digest.Mac{downConfig.AccessKey, []byte(downConfig.SecretKey)}
		token := digest.Sign(&mac, []byte(downUrl))
		downUrl = fmt.Sprintf("%s&token=%s", downUrl, token)
	}
	resp, respErr := rpc.DefaultClient.Get(nil, downUrl)
	if respErr != nil {
		err = respErr
		log.Error("Download", fileKey, "failed by url", downUrl)
		return
	}
	defer resp.Body.Close()
	if resp.StatusCode == 200 {
		localFp, openErr := os.Create(localFilePath)
		if openErr != nil {
			err = openErr
			log.Error("Open local file", localFilePath, "failed")
			return
		}
		defer localFp.Close()
		_, cpErr := io.Copy(localFp, resp.Body)
		if cpErr != nil {
			err = cpErr
			log.Error("Download", fileKey, "failed", err)
			return
		}
	} else {
		err = errors.New("download failed")
		log.Error("Download", fileKey, "failed by url", downUrl, resp.Status)
		return
	}
	return
}
<commit_msg>output the err if it occurs for debug usage<commit_after>package qshell

import (
	"bufio"
	"crypto/md5"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/qiniu/api.v6/auth/digest"
	"github.com/qiniu/log"
	"github.com/qiniu/rpc"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
	"sync/atomic"
	"time"
)

/*
{
	"dest_dir"		:	"/Users/jemy/Backup",
	"bucket"		:	"test-bucket",
	"domain"		:	"<Your bucket domain>",
	"access_key"	:	"<Your AccessKey>",
	"secret_key"	:	"<Your SecretKey>",
	"is_private"	:	false,
	"prefix"		:	"demo/",
	"suffix"		: ".mp4"
}
*/

const (
	MIN_DOWNLOAD_THREAD_COUNT = 1
	MAX_DOWNLOAD_THREAD_COUNT = 100
)

type DownloadConfig struct {
	DestDir   string `json:"dest_dir"`
	Bucket    string `json:"bucket"`
	Domain    string `json:"domain"`
	AccessKey string `json:"access_key"`
	SecretKey string `json:"secret_key"`
	IsPrivate bool   `json:"is_private"`
	Prefix    string `json:"prefix,omitempty"`
	Suffix    string `json:"suffix,omitempty"`
}

func QiniuDownload(threadCount int, downloadConfigFile string) {
	timeStart := time.Now()
	cnfFp, err := os.Open(downloadConfigFile)
	if err != nil {
		log.Error("Open download config file", downloadConfigFile, "failed,", err)
		return
	}
	defer cnfFp.Close()
	cnfData, err := ioutil.ReadAll(cnfFp)
	if err != nil {
		log.Error("Read download config file error", err)
		return
	}
	downConfig := DownloadConfig{}
	cnfErr := json.Unmarshal(cnfData, &downConfig)
	if cnfErr != nil {
		log.Error("Parse download config error", err)
		return
	}
	cnfJson, _ := json.Marshal(&downConfig)
	jobId := fmt.Sprintf("%x", md5.Sum(cnfJson))
	jobListName := fmt.Sprintf("%s.list.txt", jobId)
	acct := Account{
		AccessKey: downConfig.AccessKey,
		SecretKey: downConfig.SecretKey,
	}
	bLister := ListBucket{
		Account: acct,
	}
	log.Debug("List bucket...")
	listErr := bLister.List(downConfig.Bucket, downConfig.Prefix, jobListName)
	if listErr != nil {
		log.Error("List bucket error", listErr)
		return
	}
	listFp, openErr := os.Open(jobListName)
	if openErr != nil {
		log.Error("Open list file error", openErr)
		return
	}
	defer listFp.Close()
	listScanner := bufio.NewScanner(listFp)
	listScanner.Split(bufio.ScanLines)
	downWorkGroup := sync.WaitGroup{}

	totalCount := 0
	existsCount := 0

	var successCount int32 = 0
	var failCount int32 = 0

	threadThreshold := threadCount + 1
	for listScanner.Scan() {
		totalCount += 1
		if totalCount%threadThreshold == 0 {
			downWorkGroup.Wait()
		}
		line := strings.TrimSpace(listScanner.Text())
		items := strings.Split(line, "\t")
		if len(items) > 2 {
			fileKey := items[0]
			//check suffix
			if downConfig.Suffix != "" && !strings.HasSuffix(fileKey, downConfig.Suffix) {
				continue
			}
			fileSize, _ := strconv.ParseInt(items[1], 10, 64)
			//not backup yet
			if !checkLocalDuplicate(downConfig.DestDir, fileKey, fileSize) {
				downWorkGroup.Add(1)
				go func() {
					defer downWorkGroup.Done()
					downErr := downloadFile(downConfig, fileKey)
					if downErr != nil {
						atomic.AddInt32(&failCount, 1)
					} else {
						atomic.AddInt32(&successCount, 1)
					}
				}()
			} else {
				existsCount += 1
			}
		}
	}
	downWorkGroup.Wait()

	log.Info("-------Download Result-------")
	log.Info("Total:\t", totalCount)
	log.Info("Local:\t", existsCount)
	log.Info("Success:\t", successCount)
	log.Info("Failure:\t", failCount)
	log.Info("Duration:\t", time.Since(timeStart))
	log.Info("-----------------------------")
}

func checkLocalDuplicate(destDir string, fileKey string, fileSize int64) bool {
	dup := false
	filePath := filepath.Join(destDir, fileKey)
	fStat, statErr := os.Stat(filePath)
	if statErr == nil {
		//exist, check file size
		localFileSize := fStat.Size()
		if localFileSize == fileSize {
			dup = true
		}
	}
	return dup
}

func downloadFile(downConfig DownloadConfig, fileKey string) (err error) {
	localFilePath := filepath.Join(downConfig.DestDir, fileKey)
	ldx := strings.LastIndex(localFilePath, string(os.PathSeparator))
	if ldx != -1 {
		localFileDir := localFilePath[:ldx]
		mkdirErr := os.MkdirAll(localFileDir, 0775)
		if mkdirErr != nil {
			err = mkdirErr
			log.Error("MkdirAll failed for", localFileDir, mkdirErr.Error())
			return
		}
	}
	log.Info("Downloading", fileKey, "=>", localFilePath, "...")
	downUrl := strings.Join([]string{downConfig.Domain, fileKey}, "/")
	if downConfig.IsPrivate {
		now := time.Now().Add(time.Second * 3600 * 24)
		downUrl = fmt.Sprintf("%s?e=%d", downUrl, now.Unix())
		mac := digest.Mac{downConfig.AccessKey, []byte(downConfig.SecretKey)}
		token := digest.Sign(&mac, []byte(downUrl))
		downUrl = fmt.Sprintf("%s&token=%s", downUrl, token)
	}
	resp, respErr := rpc.DefaultClient.Get(nil, downUrl)
	if respErr != nil {
		err = respErr
		log.Error("Download", fileKey, "failed by url", downUrl, respErr.Error())
		return
	}
	defer resp.Body.Close()
	if resp.StatusCode == 200 {
		localFp, openErr := os.Create(localFilePath)
		if openErr != nil {
			err = openErr
			log.Error("Open local file", localFilePath, "failed", openErr.Error())
			return
		}
		defer localFp.Close()
		_, cpErr := io.Copy(localFp, resp.Body)
		if cpErr != nil {
			err = cpErr
			log.Error("Download", fileKey, "failed", err)
			return
		}
	} else {
		err = errors.New("download failed")
		log.Error("Download", fileKey, "failed by url", downUrl, resp.Status)
		return
	}
	return
}
<|endoftext|>


<commit_before><commit_msg>Little struct refactor<commit_after><|endoftext|>


<commit_before>package tarantool

import (
	"io"
	"time"
)

const ioTickerInterval = time.Microsecond * 200

var packetPool *packedPacketPool
var ioTicker *time.Ticker

func init() {
	packetPool = newPackedPacketPool()
	ioTicker = time.NewTicker(ioTickerInterval)
}

type Query interface {
	Pack(data *packData, w io.Writer) (uint32, error)
	Unpack(r io.Reader) error
}

type request struct {
	query     Query
	replyChan chan *Result
}

// ReplicaSet is used to store params of the Replica Set.
type ReplicaSet struct {
	UUID      string
	Instances []string // Instances is read-only set of the instances uuid
}

// NewReplicaSet returns empty ReplicaSet.
func NewReplicaSet() ReplicaSet {
	return ReplicaSet{Instances: make([]string, 0, ReplicaSetMaxSize)}
}

// SetInstance uuid in instance set.
func (rs *ReplicaSet) SetInstance(id uint32, uuid string) bool {
	if id >= uint32(cap(rs.Instances)) || len(uuid) != UUIDStrLength {
		return false
	}
	// extend vector by elements needed
	if id >= uint32(len(rs.Instances)) {
		rs.Instances = rs.Instances[:id+1]
	}
	rs.Instances[id] = uuid
	return true
}

// Has ReplicaSet specified instance?
func (rs *ReplicaSet) Has(id uint32) bool {
	return id < uint32(len(rs.Instances))
}

// VectorClock is used to store logical clocks (direct dependency clock implementation).
// Zero index is always reserved for internal use.
// You can get any lsn indexing VectorClock by instance ID directly (without any index offset).
// One can count instances in vector just using built-in len function.
type VectorClock []int64

// NewVectorClockFrom returns VectorClock with clocks equal to the given lsn elements sequentially.
// Empty VectorClock would be returned if no lsn elements is given.
func NewVectorClock(lsns ...int64) VectorClock {
	if len(lsns) == 0 {
		return make([]int64, 0, VClockMax)
	}
	// zero index is reserved
	vc := make([]int64, len(lsns)+1, VClockMax)
	copy(vc[1:], lsns)
	return vc
}

// Follow the clocks.
// Update vector clock with given clock part.
func (vc *VectorClock) Follow(id uint32, lsn int64) bool {
	if id >= uint32(cap(*vc)) || lsn < 0 {
		return false
	}
	// extend vector by elements needed
	if id >= uint32(len(*vc)) {
		*vc = (*vc)[:id+1]
	}
	(*vc)[id] = lsn
	return true
}

// LSN is the sum of the Clocks.
func (vc VectorClock) LSN() int64 {
	result := int64(0)
	for _, lsn := range vc {
		result += lsn
	}
	return result
}

// Has VectorClock specified ID?
func (vc VectorClock) Has(id uint32) bool {
	return id < uint32(len(vc))
}
<commit_msg>Set the I/O ticker rate to 100 microseconds<commit_after>package tarantool

import (
	"io"
	"time"
)

const ioTickerInterval = time.Microsecond * 100

var packetPool *packedPacketPool
var ioTicker *time.Ticker

func init() {
	packetPool = newPackedPacketPool()
	ioTicker = time.NewTicker(ioTickerInterval)
}

type Query interface {
	Pack(data *packData, w io.Writer) (uint32, error)
	Unpack(r io.Reader) error
}

type request struct {
	query     Query
	replyChan chan *Result
}

// ReplicaSet is used to store params of the Replica Set.
type ReplicaSet struct {
	UUID      string
	Instances []string // Instances is read-only set of the instances uuid
}

// NewReplicaSet returns empty ReplicaSet.
func NewReplicaSet() ReplicaSet {
	return ReplicaSet{Instances: make([]string, 0, ReplicaSetMaxSize)}
}

// SetInstance uuid in instance set.
func (rs *ReplicaSet) SetInstance(id uint32, uuid string) bool {
	if id >= uint32(cap(rs.Instances)) || len(uuid) != UUIDStrLength {
		return false
	}
	// extend vector by elements needed
	if id >= uint32(len(rs.Instances)) {
		rs.Instances = rs.Instances[:id+1]
	}
	rs.Instances[id] = uuid
	return true
}

// Has ReplicaSet specified instance?
func (rs *ReplicaSet) Has(id uint32) bool {
	return id < uint32(len(rs.Instances))
}

// VectorClock is used to store logical clocks (direct dependency clock implementation).
// Zero index is always reserved for internal use.
// You can get any lsn indexing VectorClock by instance ID directly (without any index offset).
// One can count instances in vector just using built-in len function.
type VectorClock []int64

// NewVectorClockFrom returns VectorClock with clocks equal to the given lsn elements sequentially.
// Empty VectorClock would be returned if no lsn elements is given.
func NewVectorClock(lsns ...int64) VectorClock {
	if len(lsns) == 0 {
		return make([]int64, 0, VClockMax)
	}
	// zero index is reserved
	vc := make([]int64, len(lsns)+1, VClockMax)
	copy(vc[1:], lsns)
	return vc
}

// Follow the clocks.
// Update vector clock with given clock part.
func (vc *VectorClock) Follow(id uint32, lsn int64) bool {
	if id >= uint32(cap(*vc)) || lsn < 0 {
		return false
	}
	// extend vector by elements needed
	if id >= uint32(len(*vc)) {
		*vc = (*vc)[:id+1]
	}
	(*vc)[id] = lsn
	return true
}

// LSN is the sum of the Clocks.
func (vc VectorClock) LSN() int64 {
	result := int64(0)
	for _, lsn := range vc {
		result += lsn
	}
	return result
}

// Has VectorClock specified ID?
func (vc VectorClock) Has(id uint32) bool {
	return id < uint32(len(vc))
}
<|endoftext|>


<commit_before>/*

blackjack implements a simple blackjack game. This example is interesting
because it has hidden state.

*/
package blackjack

import (
	"errors"
	"fmt"
	"github.com/jkomoros/boardgame"
	"github.com/jkomoros/boardgame/components/playingcards"
	"strings"
)

//go:generate autoreader

const targetScore = 21

const gameDisplayname = "Blackjack"
const gameName = "blackjack"

//computeHandValue is used in our ComputedPropertyConfig.
func computeHandValue(state boardgame.PlayerState) (interface{}, error) {

	playerState := state.(*playerState)

	return playerState.HandValue(), nil

}

type gameDelegate struct {
	boardgame.DefaultGameDelegate
}

func (g *gameDelegate) Name() string {
	return gameName
}

func (g *gameDelegate) DisplayName() string {
	return gameDisplayname
}

func (g *gameDelegate) DefaultNumPlayers() int {
	return 4
}

func (g *gameDelegate) CurrentPhase(state boardgame.State) int {
	game, _ := concreteStates(state)
	return game.Phase.Value()
}

func (g *gameDelegate) PhaseMoveProgression(phase int) []string {
	switch phase {
	case PhaseInitialDeal:
		return []string{
			moveDealInitialCardConfig.Name,
			moveBeginNormalPlayConfig.Name,
		}
	}
	return nil
}

func (g *gameDelegate) CurrentPlayerIndex(state boardgame.State) boardgame.PlayerIndex {
	game, _ := concreteStates(state)
	return game.CurrentPlayer
}

func (g *gameDelegate) ComputedPlayerProperties(player boardgame.PlayerState) boardgame.PropertyCollection {

	p := player.(*playerState)

	return boardgame.PropertyCollection{
		"HandValue": p.HandValue(),
	}
}

func (g *gameDelegate) DistributeComponentToStarterStack(state boardgame.State, c *boardgame.Component) (boardgame.Stack, error) {

	game, _ := concreteStates(state)

	card := c.Values.(*playingcards.Card)

	if card.Rank.Value() == playingcards.RankJoker {
		return game.UnusedCards, nil
	} else {
		return game.DrawStack, nil
	}

	return nil, errors.New("Unexpected control point reached")

}

func (g *gameDelegate) Diagram(state boardgame.State) string {

	game, players := concreteStates(state)

	var result []string

	result = append(result, fmt.Sprintf("Cards left in deck: %d", game.DrawStack.NumComponents()))

	for i, player := range players {

		playerLine := fmt.Sprintf("Player %d", i)

		if boardgame.PlayerIndex(i) == game.CurrentPlayer {
			playerLine += "  *CURRENT*"
		}

		result = append(result, playerLine)

		handValue := player.HandValue()

		statusLine := fmt.Sprintf("\tValue: %d", handValue)

		if player.Busted {
			statusLine += " BUSTED"
		}

		if player.Stood {
			statusLine += " STOOD"
		}

		result = append(result, statusLine)

		result = append(result, "\tCards:")

		for _, card := range playingcards.ValuesToCards(player.HiddenHand.ComponentValues()) {
			result = append(result, "\t\t"+card.String())
		}

		for _, card := range playingcards.ValuesToCards(player.VisibleHand.ComponentValues()) {
			result = append(result, "\t\t"+card.String())
		}

		result = append(result, "")
	}

	return strings.Join(result, "\n")
}

func (g *gameDelegate) CheckGameFinished(state boardgame.State) (finished bool, winners []boardgame.PlayerIndex) {

	_, players := concreteStates(state)

	for _, player := range players {
		if !player.Busted && !player.Stood {
			return false, nil
		}
	}

	//OK, everyone has either busted or Stood. So who won?

	maxScore := 0

	for _, player := range players {
		if player.Busted {
			continue
		}

		handValue := player.HandValue()
		if handValue > maxScore {
			maxScore = handValue
		}
	}

	//OK, now who got the maxScore?

	var result []boardgame.PlayerIndex

	for i, player := range players {
		if player.Busted {
			continue
		}
		handValue := player.HandValue()
		if handValue == maxScore {
			result = append(result, boardgame.PlayerIndex(i))
		}
	}

	return true, result

}

func (g *gameDelegate) LegalNumPlayers(numPlayers int) bool {
	return numPlayers > 0 && numPlayers < 7
}

func (g *gameDelegate) GameStateConstructor() boardgame.ConfigurableSubState {
	return new(gameState)
}

func (g *gameDelegate) PlayerStateConstructor(playerIndex boardgame.PlayerIndex) boardgame.ConfigurablePlayerState {
	return &playerState{
		playerIndex: playerIndex,
	}
}

func (g *gameDelegate) FinishSetUp(state boardgame.MutableState) error {
	game, _ := concreteStates(state)

	game.DrawStack.Shuffle()

	return nil
}

func NewManager(storage boardgame.StorageManager) (*boardgame.GameManager, error) {
	chest := boardgame.NewComponentChest(Enums)

	if err := chest.AddDeck("cards", playingcards.NewDeck(false)); err != nil {
		return nil, errors.New("Couldn't add deck: " + err.Error())
	}

	manager := boardgame.NewGameManager(&gameDelegate{}, chest, storage)

	if manager == nil {
		return nil, errors.New("No manager returned")
	}

	manager.BulkAddMoveTypes([]*boardgame.MoveTypeConfig{
		&moveCurrentPlayerHitConfig,
		&moveCurrentPlayerStandConfig,
		&moveDealInitialCardConfig,
		&moveRevealHiddenCardConfig,
		&moveShuffleDiscardToDrawConfig,
		&moveFinishTurnConfig,
		&moveBeginNormalPlayConfig,
	})

	if err := manager.SetUp(); err != nil {
		return nil, errors.New("Couldn't set up manager: " + err.Error())
	}

	return manager, nil
}

func NewGame(manager *boardgame.GameManager) *boardgame.Game {
	game := manager.NewGame()

	if err := game.SetUp(0, nil, nil); err != nil {
		panic(err)
	}

	return game
}
<commit_msg>Blackjack example uses AddMovesForPhaseProgression. Part of #516.<commit_after>/*

blackjack implements a simple blackjack game. This example is interesting
because it has hidden state.

*/
package blackjack

import (
	"errors"
	"fmt"
	"github.com/jkomoros/boardgame"
	"github.com/jkomoros/boardgame/components/playingcards"
	"strings"
)

//go:generate autoreader

const targetScore = 21

const gameDisplayname = "Blackjack"
const gameName = "blackjack"

//computeHandValue is used in our ComputedPropertyConfig.
func computeHandValue(state boardgame.PlayerState) (interface{}, error) {

	playerState := state.(*playerState)

	return playerState.HandValue(), nil

}

type gameDelegate struct {
	boardgame.DefaultGameDelegate
}

func (g *gameDelegate) Name() string {
	return gameName
}

func (g *gameDelegate) DisplayName() string {
	return gameDisplayname
}

func (g *gameDelegate) DefaultNumPlayers() int {
	return 4
}

func (g *gameDelegate) CurrentPhase(state boardgame.State) int {
	game, _ := concreteStates(state)
	return game.Phase.Value()
}

func (g *gameDelegate) CurrentPlayerIndex(state boardgame.State) boardgame.PlayerIndex {
	game, _ := concreteStates(state)
	return game.CurrentPlayer
}

func (g *gameDelegate) ComputedPlayerProperties(player boardgame.PlayerState) boardgame.PropertyCollection {

	p := player.(*playerState)

	return boardgame.PropertyCollection{
		"HandValue": p.HandValue(),
	}
}

func (g *gameDelegate) DistributeComponentToStarterStack(state boardgame.State, c *boardgame.Component) (boardgame.Stack, error) {

	game, _ := concreteStates(state)

	card := c.Values.(*playingcards.Card)

	if card.Rank.Value() == playingcards.RankJoker {
		return game.UnusedCards, nil
	} else {
		return game.DrawStack, nil
	}

	return nil, errors.New("Unexpected control point reached")

}

func (g *gameDelegate) Diagram(state boardgame.State) string {

	game, players := concreteStates(state)

	var result []string

	result = append(result, fmt.Sprintf("Cards left in deck: %d", game.DrawStack.NumComponents()))

	for i, player := range players {

		playerLine := fmt.Sprintf("Player %d", i)

		if boardgame.PlayerIndex(i) == game.CurrentPlayer {
			playerLine += "  *CURRENT*"
		}

		result = append(result, playerLine)

		handValue := player.HandValue()

		statusLine := fmt.Sprintf("\tValue: %d", handValue)

		if player.Busted {
			statusLine += " BUSTED"
		}

		if player.Stood {
			statusLine += " STOOD"
		}

		result = append(result, statusLine)

		result = append(result, "\tCards:")

		for _, card := range playingcards.ValuesToCards(player.HiddenHand.ComponentValues()) {
			result = append(result, "\t\t"+card.String())
		}

		for _, card := range playingcards.ValuesToCards(player.VisibleHand.ComponentValues()) {
			result = append(result, "\t\t"+card.String())
		}

		result = append(result, "")
	}

	return strings.Join(result, "\n")
}

func (g *gameDelegate) CheckGameFinished(state boardgame.State) (finished bool, winners []boardgame.PlayerIndex) {

	_, players := concreteStates(state)

	for _, player := range players {
		if !player.Busted && !player.Stood {
			return false, nil
		}
	}

	//OK, everyone has either busted or Stood. So who won?

	maxScore := 0

	for _, player := range players {
		if player.Busted {
			continue
		}

		handValue := player.HandValue()
		if handValue > maxScore {
			maxScore = handValue
		}
	}

	//OK, now who got the maxScore?

	var result []boardgame.PlayerIndex

	for i, player := range players {
		if player.Busted {
			continue
		}
		handValue := player.HandValue()
		if handValue == maxScore {
			result = append(result, boardgame.PlayerIndex(i))
		}
	}

	return true, result

}

func (g *gameDelegate) LegalNumPlayers(numPlayers int) bool {
	return numPlayers > 0 && numPlayers < 7
}

func (g *gameDelegate) GameStateConstructor() boardgame.ConfigurableSubState {
	return new(gameState)
}

func (g *gameDelegate) PlayerStateConstructor(playerIndex boardgame.PlayerIndex) boardgame.ConfigurablePlayerState {
	return &playerState{
		playerIndex: playerIndex,
	}
}

func (g *gameDelegate) FinishSetUp(state boardgame.MutableState) error {
	game, _ := concreteStates(state)

	game.DrawStack.Shuffle()

	return nil
}

func NewManager(storage boardgame.StorageManager) (*boardgame.GameManager, error) {
	chest := boardgame.NewComponentChest(Enums)

	if err := chest.AddDeck("cards", playingcards.NewDeck(false)); err != nil {
		return nil, errors.New("Couldn't add deck: " + err.Error())
	}

	delegate := &gameDelegate{}

	manager := boardgame.NewGameManager(delegate, chest, storage)

	if manager == nil {
		return nil, errors.New("No manager returned")
	}

	manager.BulkAddMoveTypes([]*boardgame.MoveTypeConfig{
		&moveCurrentPlayerHitConfig,
		&moveCurrentPlayerStandConfig,
		&moveRevealHiddenCardConfig,
		&moveShuffleDiscardToDrawConfig,
		&moveFinishTurnConfig,
	})

	delegate.AddMovesForPhaseProgression(PhaseInitialDeal, &moveDealInitialCardConfig, &moveBeginNormalPlayConfig)

	if err := manager.SetUp(); err != nil {
		return nil, errors.New("Couldn't set up manager: " + err.Error())
	}

	return manager, nil
}

func NewGame(manager *boardgame.GameManager) *boardgame.Game {
	game := manager.NewGame()

	if err := game.SetUp(0, nil, nil); err != nil {
		panic(err)
	}

	return game
}
<|endoftext|>