feat(dir2config): defaults
This commit is contained in:
122
vendor/gopkg.in/src-d/go-git.v4/plumbing/format/pktline/encoder.go
generated
vendored
Normal file
122
vendor/gopkg.in/src-d/go-git.v4/plumbing/format/pktline/encoder.go
generated
vendored
Normal file
@ -0,0 +1,122 @@
|
||||
// Package pktline implements reading payloads form pkt-lines and encoding
|
||||
// pkt-lines from payloads.
|
||||
package pktline
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// An Encoder writes pkt-lines to an output stream.
|
||||
type Encoder struct {
|
||||
w io.Writer
|
||||
}
|
||||
|
||||
const (
|
||||
// MaxPayloadSize is the maximum payload size of a pkt-line in bytes.
|
||||
MaxPayloadSize = 65516
|
||||
|
||||
// For compatibility with canonical Git implementation, accept longer pkt-lines
|
||||
OversizePayloadMax = 65520
|
||||
)
|
||||
|
||||
var (
|
||||
// FlushPkt are the contents of a flush-pkt pkt-line.
|
||||
FlushPkt = []byte{'0', '0', '0', '0'}
|
||||
// Flush is the payload to use with the Encode method to encode a flush-pkt.
|
||||
Flush = []byte{}
|
||||
// FlushString is the payload to use with the EncodeString method to encode a flush-pkt.
|
||||
FlushString = ""
|
||||
// ErrPayloadTooLong is returned by the Encode methods when any of the
|
||||
// provided payloads is bigger than MaxPayloadSize.
|
||||
ErrPayloadTooLong = errors.New("payload is too long")
|
||||
)
|
||||
|
||||
// NewEncoder returns a new encoder that writes to w.
|
||||
func NewEncoder(w io.Writer) *Encoder {
|
||||
return &Encoder{
|
||||
w: w,
|
||||
}
|
||||
}
|
||||
|
||||
// Flush encodes a flush-pkt to the output stream.
|
||||
func (e *Encoder) Flush() error {
|
||||
_, err := e.w.Write(FlushPkt)
|
||||
return err
|
||||
}
|
||||
|
||||
// Encode encodes a pkt-line with the payload specified and write it to
|
||||
// the output stream. If several payloads are specified, each of them
|
||||
// will get streamed in their own pkt-lines.
|
||||
func (e *Encoder) Encode(payloads ...[]byte) error {
|
||||
for _, p := range payloads {
|
||||
if err := e.encodeLine(p); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *Encoder) encodeLine(p []byte) error {
|
||||
if len(p) > MaxPayloadSize {
|
||||
return ErrPayloadTooLong
|
||||
}
|
||||
|
||||
if bytes.Equal(p, Flush) {
|
||||
return e.Flush()
|
||||
}
|
||||
|
||||
n := len(p) + 4
|
||||
if _, err := e.w.Write(asciiHex16(n)); err != nil {
|
||||
return err
|
||||
}
|
||||
_, err := e.w.Write(p)
|
||||
return err
|
||||
}
|
||||
|
||||
// Returns the hexadecimal ascii representation of the 16 less
|
||||
// significant bits of n. The length of the returned slice will always
|
||||
// be 4. Example: if n is 1234 (0x4d2), the return value will be
|
||||
// []byte{'0', '4', 'd', '2'}.
|
||||
func asciiHex16(n int) []byte {
|
||||
var ret [4]byte
|
||||
ret[0] = byteToASCIIHex(byte(n & 0xf000 >> 12))
|
||||
ret[1] = byteToASCIIHex(byte(n & 0x0f00 >> 8))
|
||||
ret[2] = byteToASCIIHex(byte(n & 0x00f0 >> 4))
|
||||
ret[3] = byteToASCIIHex(byte(n & 0x000f))
|
||||
|
||||
return ret[:]
|
||||
}
|
||||
|
||||
// turns a byte into its hexadecimal ascii representation. Example:
|
||||
// from 11 (0xb) to 'b'.
|
||||
func byteToASCIIHex(n byte) byte {
|
||||
if n < 10 {
|
||||
return '0' + n
|
||||
}
|
||||
|
||||
return 'a' - 10 + n
|
||||
}
|
||||
|
||||
// EncodeString works similarly as Encode but payloads are specified as strings.
|
||||
func (e *Encoder) EncodeString(payloads ...string) error {
|
||||
for _, p := range payloads {
|
||||
if err := e.Encode([]byte(p)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Encodef encodes a single pkt-line with the payload formatted as
|
||||
// the format specifier. The rest of the arguments will be used in
|
||||
// the format string.
|
||||
func (e *Encoder) Encodef(format string, a ...interface{}) error {
|
||||
return e.EncodeString(
|
||||
fmt.Sprintf(format, a...),
|
||||
)
|
||||
}
|
134
vendor/gopkg.in/src-d/go-git.v4/plumbing/format/pktline/scanner.go
generated
vendored
Normal file
134
vendor/gopkg.in/src-d/go-git.v4/plumbing/format/pktline/scanner.go
generated
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
package pktline
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
)
|
||||
|
||||
const (
|
||||
lenSize = 4
|
||||
)
|
||||
|
||||
// ErrInvalidPktLen is returned by Err() when an invalid pkt-len is found.
|
||||
var ErrInvalidPktLen = errors.New("invalid pkt-len found")
|
||||
|
||||
// Scanner provides a convenient interface for reading the payloads of a
|
||||
// series of pkt-lines. It takes an io.Reader providing the source,
|
||||
// which then can be tokenized through repeated calls to the Scan
|
||||
// method.
|
||||
//
|
||||
// After each Scan call, the Bytes method will return the payload of the
|
||||
// corresponding pkt-line on a shared buffer, which will be 65516 bytes
|
||||
// or smaller. Flush pkt-lines are represented by empty byte slices.
|
||||
//
|
||||
// Scanning stops at EOF or the first I/O error.
|
||||
type Scanner struct {
|
||||
r io.Reader // The reader provided by the client
|
||||
err error // Sticky error
|
||||
payload []byte // Last pkt-payload
|
||||
len [lenSize]byte // Last pkt-len
|
||||
}
|
||||
|
||||
// NewScanner returns a new Scanner to read from r.
|
||||
func NewScanner(r io.Reader) *Scanner {
|
||||
return &Scanner{
|
||||
r: r,
|
||||
}
|
||||
}
|
||||
|
||||
// Err returns the first error encountered by the Scanner.
|
||||
func (s *Scanner) Err() error {
|
||||
return s.err
|
||||
}
|
||||
|
||||
// Scan advances the Scanner to the next pkt-line, whose payload will
|
||||
// then be available through the Bytes method. Scanning stops at EOF
|
||||
// or the first I/O error. After Scan returns false, the Err method
|
||||
// will return any error that occurred during scanning, except that if
|
||||
// it was io.EOF, Err will return nil.
|
||||
func (s *Scanner) Scan() bool {
|
||||
var l int
|
||||
l, s.err = s.readPayloadLen()
|
||||
if s.err == io.EOF {
|
||||
s.err = nil
|
||||
return false
|
||||
}
|
||||
if s.err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if cap(s.payload) < l {
|
||||
s.payload = make([]byte, 0, l)
|
||||
}
|
||||
|
||||
if _, s.err = io.ReadFull(s.r, s.payload[:l]); s.err != nil {
|
||||
return false
|
||||
}
|
||||
s.payload = s.payload[:l]
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// Bytes returns the most recent payload generated by a call to Scan.
|
||||
// The underlying array may point to data that will be overwritten by a
|
||||
// subsequent call to Scan. It does no allocation.
|
||||
func (s *Scanner) Bytes() []byte {
|
||||
return s.payload
|
||||
}
|
||||
|
||||
// Method readPayloadLen returns the payload length by reading the
|
||||
// pkt-len and subtracting the pkt-len size.
|
||||
func (s *Scanner) readPayloadLen() (int, error) {
|
||||
if _, err := io.ReadFull(s.r, s.len[:]); err != nil {
|
||||
if err == io.ErrUnexpectedEOF {
|
||||
return 0, ErrInvalidPktLen
|
||||
}
|
||||
|
||||
return 0, err
|
||||
}
|
||||
|
||||
n, err := hexDecode(s.len)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
switch {
|
||||
case n == 0:
|
||||
return 0, nil
|
||||
case n <= lenSize:
|
||||
return 0, ErrInvalidPktLen
|
||||
case n > OversizePayloadMax+lenSize:
|
||||
return 0, ErrInvalidPktLen
|
||||
default:
|
||||
return n - lenSize, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Turns the hexadecimal representation of a number in a byte slice into
|
||||
// a number. This function substitute strconv.ParseUint(string(buf), 16,
|
||||
// 16) and/or hex.Decode, to avoid generating new strings, thus helping the
|
||||
// GC.
|
||||
func hexDecode(buf [lenSize]byte) (int, error) {
|
||||
var ret int
|
||||
for i := 0; i < lenSize; i++ {
|
||||
n, err := asciiHexToByte(buf[i])
|
||||
if err != nil {
|
||||
return 0, ErrInvalidPktLen
|
||||
}
|
||||
ret = 16*ret + int(n)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// turns the hexadecimal ascii representation of a byte into its
|
||||
// numerical value. Example: from 'b' to 11 (0xb).
|
||||
func asciiHexToByte(b byte) (byte, error) {
|
||||
switch {
|
||||
case b >= '0' && b <= '9':
|
||||
return b - '0', nil
|
||||
case b >= 'a' && b <= 'f':
|
||||
return b - 'a' + 10, nil
|
||||
default:
|
||||
return 0, ErrInvalidPktLen
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user