<commit_before>// Package sskg provides a Go implementation of Seekable Sequential Key
// Generators (SSKGs).
//
// An SSKG generates a sequence of forward-secure keys (e.g., for use as
// time-bounded authentication keys), while also providing a fast-forward
// functionality. This package provides an HMAC-based implementation of a binary
// tree-based SSKG as described by Marson and Poettering:
// https://eprint.iacr.org/2014/479.pdf.
//
// The canonical example of SSKG usage is cryptographically protected local
// logs. In this scenario, we have logs on a computer which are secured via
// MACs. If the MAC key is constant, an attacker can extract the key and forge
// or modify log entries in the past. The traditional solution to this is to use
// a foward-secure solution like a hash chain (e.g., K1 = H(K0); K2 =
// H(K1)). This ensures that an attacker who compromises the state of the logger
// cannot establish the state of the logger at an arbitrary point in time in the
// past (and therefore cannot forge log entries in the past).
//
// The use of hash chains presents a large computational expense to the
// auditors, however. In order to verify the MAC using the Nth key, the auditor
// must calculate (N-1) hashes, which may be cumbersome. An SSKG, in contrast,
// allows quickly seeking forward to arbitrary points of time (specifically,
// Marson and Poettering's tree-based SSKG can perform O(log N) seeks).
package sskg

import "math"

// A Seq is a sequence of forward-secure keys.
type Seq struct {
	nodes []node
	key   []byte
	size  int
}

// New creates a new Seq with the given key, seed, maximum number of keys, and
// key size.
func New(key, seed []byte, maxKeys, keySize uint) Seq {
	return Seq{
		nodes: []node{
			node{
				s: prf12(int(keySize), []byte("seed"), key, seed),
				h: uint(math.Ceil(math.Log2(float64(maxKeys) + 1))),
			},
		},
		key:  key,
		size: int(keySize),
	}
}

// Key returns the Seq's current key.
func (t Seq) Key() []byte {
	return prf12(t.size, []byte("key"), t.key, t.nodes[len(t.nodes)-1].s)
}

// Next advances the Seq's current key to the next in the sequence.
//
// (In the literature, this function is called Evolve.)
func (t *Seq) Next() {
	s, h := t.pop()

	if h > 1 {
		t.push(prf12(t.size, right, t.key, s), h-1)
		t.push(prf12(t.size, left, t.key, s), h-1)
	}
}

// Seek moves the Seq to the k-th key without having to calculate all of the
// intermediary keys. It is equivalent to, but faster than, k invocations of
// Next().
func (t *Seq) Seek(k int) {
	delta := k
	s, h := t.pop()

	for delta > 0 {
		h--
		if h <= 0 {
			panic("keyspace exhausted")
		}

		pow := 1 << h
		if delta < pow {
			t.push(prf12(t.size, right, t.key, s), h)
			s = prf12(t.size, left, t.key, s)
			delta--
		} else {
			s = prf12(t.size, right, t.key, s)
			delta -= pow
		}
	}

	t.push(s, h)
}

func (t *Seq) pop() ([]byte, uint) {
	node := t.nodes[len(t.nodes)-1]
	t.nodes = t.nodes[:len(t.nodes)-1]
	return node.s, node.h
}

func (t *Seq) push(s []byte, h uint) {
	t.nodes = append(t.nodes, node{s: s, h: h})
}

type node struct {
	s []byte
	h uint
}

var (
	right = []byte("right")
	left  = []byte("left")
)
<commit_msg>Clean up Seek a little.<commit_after>// Package sskg provides a Go implementation of Seekable Sequential Key
// Generators (SSKGs).
//
// An SSKG generates a sequence of forward-secure keys (e.g., for use as
// time-bounded authentication keys), while also providing a fast-forward
// functionality. This package provides an HMAC-based implementation of a binary
// tree-based SSKG as described by Marson and Poettering:
// https://eprint.iacr.org/2014/479.pdf.
//
// The canonical example of SSKG usage is cryptographically protected local
// logs. In this scenario, we have logs on a computer which are secured via
// MACs. If the MAC key is constant, an attacker can extract the key and forge
// or modify log entries in the past. The traditional solution to this is to use
// a foward-secure solution like a hash chain (e.g., K1 = H(K0); K2 =
// H(K1)). This ensures that an attacker who compromises the state of the logger
// cannot establish the state of the logger at an arbitrary point in time in the
// past (and therefore cannot forge log entries in the past).
//
// The use of hash chains presents a large computational expense to the
// auditors, however. In order to verify the MAC using the Nth key, the auditor
// must calculate (N-1) hashes, which may be cumbersome. An SSKG, in contrast,
// allows quickly seeking forward to arbitrary points of time (specifically,
// Marson and Poettering's tree-based SSKG can perform O(log N) seeks).
package sskg

import "math"

// A Seq is a sequence of forward-secure keys.
type Seq struct {
	nodes []node
	key   []byte
	size  int
}

// New creates a new Seq with the given key, seed, maximum number of keys, and
// key size.
func New(key, seed []byte, maxKeys, keySize uint) Seq {
	return Seq{
		nodes: []node{
			node{
				s: prf12(int(keySize), []byte("seed"), key, seed),
				h: uint(math.Ceil(math.Log2(float64(maxKeys) + 1))),
			},
		},
		key:  key,
		size: int(keySize),
	}
}

// Key returns the Seq's current key.
func (t Seq) Key() []byte {
	return prf12(t.size, []byte("key"), t.key, t.nodes[len(t.nodes)-1].s)
}

// Next advances the Seq's current key to the next in the sequence.
//
// (In the literature, this function is called Evolve.)
func (t *Seq) Next() {
	s, h := t.pop()

	if h > 1 {
		t.push(prf12(t.size, right, t.key, s), h-1)
		t.push(prf12(t.size, left, t.key, s), h-1)
	}
}

// Seek moves the Seq to the k-th key without having to calculate all of the
// intermediary keys. It is equivalent to, but faster than, k invocations of
// Next().
func (t *Seq) Seek(k int) {
	s, h := t.pop()

	for k > 0 {
		h--

		if h <= 0 {
			panic("keyspace exhausted")
		}

		pow := 1 << h
		if k < pow {
			t.push(prf12(t.size, right, t.key, s), h)
			s = prf12(t.size, left, t.key, s)
			k--
		} else {
			s = prf12(t.size, right, t.key, s)
			k -= pow
		}
	}

	t.push(s, h)
}

func (t *Seq) pop() ([]byte, uint) {
	node := t.nodes[len(t.nodes)-1]
	t.nodes = t.nodes[:len(t.nodes)-1]
	return node.s, node.h
}

func (t *Seq) push(s []byte, h uint) {
	t.nodes = append(t.nodes, node{s: s, h: h})
}

type node struct {
	s []byte
	h uint
}

var (
	right = []byte("right")
	left  = []byte("left")
)
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Michael Wendland
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *   Michael Wendland <michael@michiwend.com>
 */

package goefa

import (
	"errors"
	"net/url"
	"time"
)

type EFAStop struct {
	Id             int     `xml:"id,attr"`
	Name           string  `xml:"objectName,attr"`
	Locality       string  `xml:"locality,attr"`
	Lat            float64 `xml:"x,attr"`
	Lng            float64 `xml:"y,attr"`
	IsTransferStop bool    `xml:"isTransferStop,attr"`

	Provider *EFAProvider
}

// Departures is just a helper method and calls the Departures() method of
// EFAProvider.
func (stop *EFAStop) Departures(due time.Time, results int) ([]*EFADeparture, error) {
	return stop.Provider.Departures(stop.Id, due, results)
}

type stopFinderResult struct {
	EFAResponse
	Odv struct {
		OdvPlace struct {
		}
		OdvName struct {
			State string     `xml:"state,attr"`
			Stops []*EFAStop `xml:"odvNameElem"`
		} `xml:"itdOdvName"`
	} `xml:"itdStopFinderRequest>itdOdv"`
}

func (s *stopFinderResult) endpoint() string {
	return "XML_STOPFINDER_REQUEST"
}

// FindStop queries the EFA StopFinder API of the corresponding provider and
// returns whether the stop was identified/unique (bool), an array of matched
// stops (or only the identified one) or an error in case somthing went wrong.
func (efa *EFAProvider) FindStop(name string) (bool, []*EFAStop, error) {

	// To get a more detailed response from the StopFinder request we can use
	// EFAs LocationServer (locationServerActive=1, type_sf=any). To limit the
	// results to a specific type we can use anyObjFilter_sf=<bitmask> as
	// following:
	//	0 any type
	//	1 locations
	//	2 stations
	//	4 streets
	//	8 addresses
	//	16 crossroads
	//	32 POIs
	//	64 postal codes
	// "stations and streets" results in 2 + 4 = 6
	params := url.Values{
		"type_sf":              {"any"},
		"name_sf":              {name},
		"outputFormat":         {"XML"},
		"stateless":            {"1"},
		"locationServerActive": {"1"},
		"anyObjFilter_sf":      {"2"},
		"coordOutputFormat":    {"WGS84[DD.ddddd]"},
	}

	var result stopFinderResult

	if err := efa.postRequest(&result, params); err != nil {
		return false, nil, err
	}

	for _, stop := range result.Odv.OdvName.Stops {
		stop.Provider = efa
	}

	switch result.Odv.OdvName.State {
	case "identified":
		return true, result.Odv.OdvName.Stops, nil
	case "list":
		return false, result.Odv.OdvName.Stops, nil
	default:
		return false, nil, errors.New("no matched stops")
	}

}
<commit_msg>Added Stop(id) function and cleaned up API<commit_after>/*
 * Copyright (C) 2014      Michael Wendland
 *               2014-2018 Christian Muehlhaeuser
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authors:
 *   Michael Wendland <michael@michiwend.com>
 *   Christian Muehlhaeuser <muesli@gmail.com>
 */

package goefa

import (
	"errors"
	"net/url"
	"strconv"
	"time"
)

// Stop represents a public transportation stop
type Stop struct {
	ID             int
	Name           string
	Locality       string
	Lat            float64
	Lng            float64
	IsTransferStop bool

	Provider *Provider
}

type stopResult struct {
	ID             int     `xml:"id,attr"`
	Name           string  `xml:"objectName,attr"`
	ValueName      string  `xml:",chardata"`
	Locality       string  `xml:"locality,attr"`
	Lat            float64 `xml:"x,attr"`
	Lng            float64 `xml:"y,attr"`
	IsTransferStop bool    `xml:"isTransferStop,attr"`
}

type stopFinderResult struct {
	Response
	Odv struct {
		OdvPlace struct {
		}
		OdvName struct {
			State string        `xml:"state,attr"`
			Stops []*stopResult `xml:"odvNameElem"`
		} `xml:"itdOdvName"`
	} `xml:"itdStopFinderRequest>itdOdv"`
}

func (s *stopFinderResult) endpoint() string {
	return "XML_STOPFINDER_REQUEST"
}

// FindStop queries the EFA StopFinder API of the corresponding provider and
// returns an array of matched stops (or only the identified one) or an error
// in case somthing went wrong.
func (efa *Provider) FindStop(name string) ([]*Stop, error) {
	// To get a more detailed response from the StopFinder request we can use
	// EFAs LocationServer (locationServerActive=1, type_sf=any). To limit the
	// results to a specific type we can use anyObjFilter_sf=<bitmask> as
	// following:
	//	0 any type
	//	1 locations
	//	2 stations
	//	4 streets
	//	8 addresses
	//	16 crossroads
	//	32 POIs
	//	64 postal codes
	// "stations and streets" results in 2 + 4 = 6
	params := url.Values{
		"type_sf":              {"any"},
		"name_sf":              {name},
		"outputFormat":         {"XML"},
		"stateless":            {"1"},
		"locationServerActive": {"1"},
		"anyObjFilter_sf":      {"2"},
		"coordOutputFormat":    {"WGS84[DD.ddddd]"},
	}

	var result stopFinderResult
	if err := efa.postRequest(&result, params); err != nil {
		return nil, err
	}

	stops := []*Stop{}
	for _, stop := range result.Odv.OdvName.Stops {
		stops = append(stops, &Stop{
			ID:             stop.ID,
			Name:           stop.Name,
			Locality:       stop.Locality,
			Lat:            stop.Lat,
			Lng:            stop.Lng,
			IsTransferStop: stop.IsTransferStop,
			Provider:       efa,
		})
	}

	switch result.Odv.OdvName.State {
	case "identified":
		fallthrough
	case "list":
		return stops, nil
	default:
		return nil, errors.New("no matched stops")
	}
}

// Stop queries the EFA StopFinder API of the corresponding provider for a stop
// with a specific ID.
func (efa *Provider) Stop(id int) (*Stop, error) {
	params := url.Values{
		"type_sf":              {"stopID"},
		"name_sf":              {strconv.FormatInt(int64(id), 10)},
		"outputFormat":         {"XML"},
		"stateless":            {"1"},
		"locationServerActive": {"1"},
		"anyObjFilter_sf":      {"2"},
		"coordOutputFormat":    {"WGS84[DD.ddddd]"},
	}

	var result stopFinderResult
	if err := efa.postRequest(&result, params); err != nil {
		return nil, err
	}

	if len(result.Odv.OdvName.Stops) > 0 {
		switch result.Odv.OdvName.State {
		case "identified":
			return &Stop{
				ID:             result.Odv.OdvName.Stops[0].ID,
				Name:           result.Odv.OdvName.Stops[0].ValueName,
				Locality:       result.Odv.OdvName.Stops[0].Locality,
				Lat:            result.Odv.OdvName.Stops[0].Lat,
				Lng:            result.Odv.OdvName.Stops[0].Lng,
				IsTransferStop: result.Odv.OdvName.Stops[0].IsTransferStop,
				Provider:       efa,
			}, nil
		}
	}
	return nil, errors.New("no matched stops")
}

// Departures is just a helper method and calls the Departures() method of the
// Provider.
func (stop *Stop) Departures(due time.Time, results int) ([]*Departure, error) {
	return stop.Provider.Departures(stop.ID, due, results)
}

// Route is just a helper method and calls the Route() method of the Provider.
func (stop *Stop) Route(destination int, due time.Time) ([]*Route, error) {
	return stop.Provider.Route(stop.ID, destination, due)
}
<|endoftext|>


<commit_before>// Package stun implements Session Traversal Utilities for NAT (STUN) RFC 5389.
//
// Definitions
//
// STUN Agent: A STUN agent is an entity that implements the STUN
// protocol. The entity can be either a STUN client or a STUN
// server.
//
// STUN Client: A STUN client is an entity that sends STUN requests and
// receives STUN responses. A STUN client can also send indications.
// In this specification, the terms STUN client and client are
// synonymous.
//
// STUN Server: A STUN server is an entity that receives STUN requests
// and sends STUN responses. A STUN server can also send
// indications. In this specification, the terms STUN server and
// server are synonymous.
//
// Transport Address: The combination of an IP address and port number
// (such as a UDP or TCP port number).
package stun

import (
	"crypto/rand"
	"encoding/binary"
	"encoding/hex"
	"errors"
	"fmt"
	"io"
	"strconv"

	log "github.com/Sirupsen/logrus"
)

const (
	// magicCookie is fixed value that aids in distinguishing STUN packets
	// from packets of other protocols when STUN is multiplexed with those
	// other protocols on the same port.
	//
	// The magic cookie field MUST contain the fixed value 0x2112A442 in
	// network byte order.
	//
	// Defined in "STUN Message Structure", section 6.
	magicCookie = 0x2112A442
)

const transactionIDSize = 12 // 96 bit

// Attributes is list of message attributes.
type Attributes []Attribute

// Get returns first attribute from list which match AttrType. If nothing
// found, it returns blank attribute.
func (a Attributes) Get(t AttrType) Attribute {
	for _, candidate := range a {
		if candidate.Type == t {
			return candidate
		}
	}
	return Attribute{}
}

// Message represents a single STUN packet.
type Message struct {
	Type          MessageType
	Length        uint16                  // TODO: is it needed?
	TransactionID [transactionIDSize]byte // used to uniquely identify STUN transactions.
	Attributes    Attributes
}

func (m Message) String() string {
	return fmt.Sprintf("%s (len=%d) (attr=%d) [%s]",
		m.Type,
		m.Length,
		len(m.Attributes),
		hex.EncodeToString(m.TransactionID[:]),
	)
}

func unexpected(err error) {
	if err != nil {
		panic(err)
	}
}

// NewTransactionID returns new random transaction ID using crypto/rand
// as source.
func NewTransactionID() (b [transactionIDSize]byte) {
	_, err := rand.Read(b[:])
	unexpected(err)
	return b
}

// Put encodes message into buf. If len(buf) is not enough, it panics.
func (m Message) Put(buf []byte) {
	// encoding header
	binary.BigEndian.PutUint16(buf[0:2], m.Type.Value())
	binary.BigEndian.PutUint32(buf[4:8], magicCookie)
	copy(buf[8:messageHeaderSize], m.TransactionID[:])
	offset := messageHeaderSize
	// encoding attributes
	for _, a := range m.Attributes {
		binary.BigEndian.PutUint16(buf[offset:offset+2], a.Type.Value())
		offset += 2
		binary.BigEndian.PutUint16(buf[offset:offset+2], a.Length)
		offset += 2
		copy(buf[offset:offset+len(a.Value)], a.Value[:])
		offset += len(a.Value)
	}
	// writing length as size, in bytes, not including the 20-byte STUN header.
	binary.BigEndian.PutUint16(buf[2:4], uint16(offset-20))
}

// Get decodes message from byte slice and return error if any.
//
// Can return ErrUnexpectedEOF, ErrInvalidMagicCookie, ErrInvalidMessageLength.
// Any error is unrecoverable, but message could be partially decoded.
//
// ErrUnexpectedEOF means that there were not enough bytes to read header or
// value and indicates possible data loss.
func (m *Message) Get(buf []byte) error {
	if len(buf) < messageHeaderSize {
		return io.ErrUnexpectedEOF
	}

	// decoding message header
	m.Type.ReadValue(binary.BigEndian.Uint16(buf[0:2])) // first 2 bytes
	m.Length = binary.BigEndian.Uint16(buf[2:4])        // second 2 bytes
	cookie := binary.BigEndian.Uint32(buf[4:8])
	copy(m.TransactionID[:], buf[8:messageHeaderSize])

	if cookie != magicCookie {
		return ErrInvalidMagicCookie
	}

	offset := messageHeaderSize
	mLength := int(m.Length)
	if (mLength + offset) > len(buf) {
		log.WithFields(log.Fields{
			"len(b)": len(buf),
			"offset": offset,
		}).Debugln("message length", mLength, "is invalid?")
		return ErrInvalidMessageLength
	}

	for (mLength + messageHeaderSize - offset) > 0 {
		b := buf[offset:]
		// checking that we have enough bytes to read header
		if len(b) < attributeHeaderSize {
			return io.ErrUnexpectedEOF
		}
		a := Attribute{}

		// decoding header
		t := binary.BigEndian.Uint16(b[0:2])       // first 2 bytes
		a.Length = binary.BigEndian.Uint16(b[2:4]) // second 2 bytes
		a.Type = AttrType(t)
		l := int(a.Length)

		// reading value
		a.Value = make([]byte, l)   // we could possibly use pool here
		b = b[attributeHeaderSize:] // slicing again to simplify value read
		if len(b) < l {             // checking size
			return io.ErrUnexpectedEOF
		}
		copy(a.Value, b[:l])

		m.Attributes = append(m.Attributes, a)
		offset += l + attributeHeaderSize
	}
	return nil
}

const (
	attributeHeaderSize = 4
	messageHeaderSize   = 20
)

// AttrType is attribute type.
type AttrType uint16

// attributes from comprehension-required range (0x0000-0x7FFF).
const (
	AttrMappedAddress     AttrType = 0x0001 // MAPPED-ADDRESS
	AttrUsername          AttrType = 0x0006 // USERNAME
	AttrErrorCode         AttrType = 0x0009 // ERROR-CODE
	AttrMessageIntegrity  AttrType = 0x0008 // MESSAGE-INTEGRITY
	AttrUnknownAttributes AttrType = 0x000A // UNKNOWN-ATTRIBUTES
	AttrRealm             AttrType = 0x0014 // REALM
	AttrNonce             AttrType = 0x0015 // NONCE
	AttrXORMappedAddress  AttrType = 0x0020 // XOR-MAPPED-ADDRESS
)

// attributes from comprehension-optional range (0x8000-0xFFFF).
const (
	AttrSoftware        AttrType = 0x8022 // SOFTWARE
	AttrAlternateServer AttrType = 0x8023 // ALTERNATE-SERVER
	AttrFingerprint     AttrType = 0x8028 // FINGERPRINT
)

// Value returns uint16 representation of attribute type.
func (t AttrType) Value() uint16 {
	return uint16(t)
}

func (t AttrType) String() string {
	switch t {
	case AttrMappedAddress:
		return "MAPPED-ADDRESS"
	case AttrUsername:
		return "USERNAME"
	case AttrErrorCode:
		return "ERROR-CODE"
	case AttrMessageIntegrity:
		return "MESSAGE-INTEGRITY"
	case AttrUnknownAttributes:
		return "UNKNOWN-ATTRIBUTES"
	case AttrRealm:
		return "REALM"
	case AttrNonce:
		return "NONCE"
	case AttrXORMappedAddress:
		return "XOR-MAPPED-ADDRESS"
	case AttrSoftware:
		return "SOFTWARE"
	case AttrAlternateServer:
		return "ALTERNATE-SERVER"
	case AttrFingerprint:
		return "FINGERPRINT"
	default:
		// just return hex representation of unknown attribute type
		return "0x" + strconv.FormatUint(uint64(t), 16)
	}
}

// Attribute is a Type-Length-Value (TLV) object that
// can be added to a STUN message.  Attributes are divided into two
// types: comprehension-required and comprehension-optional.  STUN
// agents can safely ignore comprehension-optional attributes they
// don't understand, but cannot successfully process a message if it
// contains comprehension-required attributes that are not
// understood.
type Attribute struct {
	Type   AttrType
	Length uint16
	Value  []byte
}

// Equal returns true if a == b.
func (a Attribute) Equal(b Attribute) bool {
	if a.Type != b.Type {
		return false
	}
	if a.Length != b.Length {
		return false
	}
	for i, v := range a.Value {
		if b.Value[i] != v {
			return false
		}
	}
	return true
}

func (a Attribute) String() string {
	return fmt.Sprintf("%s: %x", a.Type, a.Value)
}

// messageClass is 8-bit representation of 2-bit class of STUN Message Type.
type messageClass byte

// possible values for message class in STUN Message Type.
const (
	ClassRequest         = 0x00 // 0b00
	ClassIndication      = 0x01 // 0b01
	ClassSuccessResponse = 0x02 // 0b10
	ClassErrorResponse   = 0x03 // 0b11
)

func (c messageClass) String() string {
	switch c {
	case ClassRequest:
		return "request"
	case ClassIndication:
		return "indication"
	case ClassSuccessResponse:
		return "success response"
	case ClassErrorResponse:
		return "error response"
	default:
		panic("unknown message class")
	}
}

// Method is uint16 representation of 12-bit STUN method.
type Method uint16

// possible methods for STUN Message.
const (
	MethodBinding Method = 0x01 // 0b000000000001
)

func (m Method) String() string {
	switch m {
	case MethodBinding:
		return "binding"
	default:
		return fmt.Sprintf("0x%s", strconv.FormatUint(uint64(m), 16))
	}
}

// MessageType is STUN Message Type Field.
type MessageType struct {
	Class  messageClass
	Method Method
}

const (
	methodABits = 0xf   // 0b0000000000001111
	methodBBits = 0x70  // 0b0000000001110000
	methodDBits = 0xf80 // 0b0000111110000000

	methodBShift = 1
	methodDShift = 2

	firstBit  = 0x1
	secondBit = 0x2

	c0Bit = firstBit
	c1Bit = secondBit

	classC0Shift = 4
	classC1Shift = 7
)

// Value returns bit representation of messageType.
func (t MessageType) Value() uint16 {
	//	 0                 1
	//	 2  3  4 5 6 7 8 9 0 1 2 3 4 5
	//	+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
	//	|M |M |M|M|M|C|M|M|M|C|M|M|M|M|
	//	|11|10|9|8|7|1|6|5|4|0|3|2|1|0|
	//	+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
	// Figure 3: Format of STUN Message Type Field

	// warning: Abandon all hope ye who enter here.
	// splitting M into A(M0-M3), B(M4-M6), D(M7-M11)
	m := uint16(t.Method)
	a := m & methodABits                              // A = M * 0b0000000000001111 (right 4 bits)
	b := m & methodBBits                              // B = M * 0b0000000001110000 (3 bits after A)
	d := m & methodDBits                              // D = M * 0b0000111110000000 (5 bits after B)
	m = a + (b << methodBShift) + (d << methodDShift) // shifting to add "holes" for C0 (at 4 bit) and C1 (8 bit)

	// C0 is zero bit of C, C1 is fist bit.
	// C0 = C * 0b01, C1 = (C * 0b10) >> 1
	// Ct = C0 << 4 + C1 << 8.
	// Optimizations: "((C * 0b10) >> 1) << 8" as "(C * 0b10) << 7"
	// We need C0 shifted by 4, and C1 by 8 to fit "11" and "7" positions (see figure 3).
	c := uint16(t.Class)
	c0 := (c & c0Bit) << classC0Shift
	c1 := (c & c1Bit) << classC1Shift
	class := c0 + c1

	return m + class
}

// ReadValue decodes uint16 into MessageType.
func (t *MessageType) ReadValue(v uint16) {
	// decoding class
	// we are taking first bit from v >> 4 and second from v >> 7.
	c0 := (v >> classC0Shift) & c0Bit
	c1 := (v >> classC1Shift) & c1Bit
	class := c0 + c1
	t.Class = messageClass(class)

	// decoding method
	a := v & methodABits                   // A(M0-M3)
	b := (v >> methodBShift) & methodBBits // B(M4-M6)
	d := (v >> methodDShift) & methodDBits // D(M7-M11)
	m := a + b + d
	t.Method = Method(m)
}

func (t MessageType) String() string {
	return fmt.Sprintf("%s %s", t.Method, t.Class)
}

var (
	// ErrInvalidMagicCookie means that magic cookie field has invalid value.
	ErrInvalidMagicCookie = errors.New("Magic cookie value is invalid")
	// ErrInvalidMessageLength means that actual message size is smaller that length
	// from header field.
	ErrInvalidMessageLength = errors.New("Message size is smaller than length")
)
<commit_msg>fix comments; export class<commit_after>// Package stun implements Session Traversal Utilities for NAT (STUN) RFC 5389.
//
// Definitions
//
// STUN Agent: A STUN agent is an entity that implements the STUN
// protocol. The entity can be either a STUN client or a STUN
// server.
//
// STUN Client: A STUN client is an entity that sends STUN requests and
// receives STUN responses. A STUN client can also send indications.
// In this specification, the terms STUN client and client are
// synonymous.
//
// STUN Server: A STUN server is an entity that receives STUN requests
// and sends STUN responses. A STUN server can also send
// indications. In this specification, the terms STUN server and
// server are synonymous.
//
// Transport Address: The combination of an IP address and port number
// (such as a UDP or TCP port number).
package stun

import (
	"crypto/rand"
	"encoding/binary"
	"encoding/hex"
	"errors"
	"fmt"
	"io"
	"strconv"

	log "github.com/Sirupsen/logrus"
)

const (
	// magicCookie is fixed value that aids in distinguishing STUN packets
	// from packets of other protocols when STUN is multiplexed with those
	// other protocols on the same port.
	//
	// The magic cookie field MUST contain the fixed value 0x2112A442 in
	// network byte order.
	//
	// Defined in "STUN Message Structure", section 6.
	magicCookie = 0x2112A442
)

const transactionIDSize = 12 // 96 bit

// Attributes is list of message attributes.
type Attributes []Attribute

// Get returns first attribute from list which match AttrType. If nothing
// found, it returns blank attribute.
func (a Attributes) Get(t AttrType) Attribute {
	for _, candidate := range a {
		if candidate.Type == t {
			return candidate
		}
	}
	return Attribute{}
}

// Message represents a single STUN packet.
type Message struct {
	Type          MessageType
	Length        uint16                  // TODO: is it needed?
	TransactionID [transactionIDSize]byte // used to uniquely identify STUN transactions.
	Attributes    Attributes
}

func (m Message) String() string {
	return fmt.Sprintf("%s (len=%d) (attr=%d) [%s]",
		m.Type,
		m.Length,
		len(m.Attributes),
		hex.EncodeToString(m.TransactionID[:]),
	)
}

func unexpected(err error) {
	if err != nil {
		panic(err)
	}
}

// NewTransactionID returns new random transaction ID using crypto/rand
// as source.
func NewTransactionID() (b [transactionIDSize]byte) {
	_, err := rand.Read(b[:])
	unexpected(err)
	return b
}

// Put encodes message into buf. If len(buf) is not enough, it panics.
func (m Message) Put(buf []byte) {
	// encoding header
	binary.BigEndian.PutUint16(buf[0:2], m.Type.Value())
	binary.BigEndian.PutUint32(buf[4:8], magicCookie)
	copy(buf[8:messageHeaderSize], m.TransactionID[:])
	offset := messageHeaderSize
	// encoding attributes
	for _, a := range m.Attributes {
		binary.BigEndian.PutUint16(buf[offset:offset+2], a.Type.Value())
		offset += 2
		binary.BigEndian.PutUint16(buf[offset:offset+2], a.Length)
		offset += 2
		copy(buf[offset:offset+len(a.Value)], a.Value[:])
		offset += len(a.Value)
	}
	// writing length as size, in bytes, not including the 20-byte STUN header.
	binary.BigEndian.PutUint16(buf[2:4], uint16(offset-20))
}

// Get decodes message from byte slice and return error if any.
//
// Can return ErrUnexpectedEOF, ErrInvalidMagicCookie, ErrInvalidMessageLength.
// Any error is unrecoverable, but message could be partially decoded.
//
// ErrUnexpectedEOF means that there were not enough bytes to read header or
// value and indicates possible data loss.
func (m *Message) Get(buf []byte) error {
	if len(buf) < messageHeaderSize {
		return io.ErrUnexpectedEOF
	}

	// decoding message header
	m.Type.ReadValue(binary.BigEndian.Uint16(buf[0:2])) // first 2 bytes
	m.Length = binary.BigEndian.Uint16(buf[2:4])        // second 2 bytes
	cookie := binary.BigEndian.Uint32(buf[4:8])
	copy(m.TransactionID[:], buf[8:messageHeaderSize])

	if cookie != magicCookie {
		return ErrInvalidMagicCookie
	}

	offset := messageHeaderSize
	mLength := int(m.Length)
	if (mLength + offset) > len(buf) {
		log.WithFields(log.Fields{
			"len(b)": len(buf),
			"offset": offset,
		}).Debugln("message length", mLength, "is invalid?")
		return ErrInvalidMessageLength
	}

	for (mLength + messageHeaderSize - offset) > 0 {
		b := buf[offset:]
		// checking that we have enough bytes to read header
		if len(b) < attributeHeaderSize {
			return io.ErrUnexpectedEOF
		}
		a := Attribute{}

		// decoding header
		t := binary.BigEndian.Uint16(b[0:2])       // first 2 bytes
		a.Length = binary.BigEndian.Uint16(b[2:4]) // second 2 bytes
		a.Type = AttrType(t)
		l := int(a.Length)

		// reading value
		a.Value = make([]byte, l)   // we could possibly use pool here
		b = b[attributeHeaderSize:] // slicing again to simplify value read
		if len(b) < l {             // checking size
			return io.ErrUnexpectedEOF
		}
		copy(a.Value, b[:l])

		m.Attributes = append(m.Attributes, a)
		offset += l + attributeHeaderSize
	}
	return nil
}

const (
	attributeHeaderSize = 4
	messageHeaderSize   = 20
)

// AttrType is attribute type.
type AttrType uint16

// Attributes from comprehension-required range (0x0000-0x7FFF).
const (
	AttrMappedAddress     AttrType = 0x0001 // MAPPED-ADDRESS
	AttrUsername          AttrType = 0x0006 // USERNAME
	AttrErrorCode         AttrType = 0x0009 // ERROR-CODE
	AttrMessageIntegrity  AttrType = 0x0008 // MESSAGE-INTEGRITY
	AttrUnknownAttributes AttrType = 0x000A // UNKNOWN-ATTRIBUTES
	AttrRealm             AttrType = 0x0014 // REALM
	AttrNonce             AttrType = 0x0015 // NONCE
	AttrXORMappedAddress  AttrType = 0x0020 // XOR-MAPPED-ADDRESS
)

// Attributes from comprehension-optional range (0x8000-0xFFFF).
const (
	AttrSoftware        AttrType = 0x8022 // SOFTWARE
	AttrAlternateServer AttrType = 0x8023 // ALTERNATE-SERVER
	AttrFingerprint     AttrType = 0x8028 // FINGERPRINT
)

// Value returns uint16 representation of attribute type.
func (t AttrType) Value() uint16 {
	return uint16(t)
}

func (t AttrType) String() string {
	switch t {
	case AttrMappedAddress:
		return "MAPPED-ADDRESS"
	case AttrUsername:
		return "USERNAME"
	case AttrErrorCode:
		return "ERROR-CODE"
	case AttrMessageIntegrity:
		return "MESSAGE-INTEGRITY"
	case AttrUnknownAttributes:
		return "UNKNOWN-ATTRIBUTES"
	case AttrRealm:
		return "REALM"
	case AttrNonce:
		return "NONCE"
	case AttrXORMappedAddress:
		return "XOR-MAPPED-ADDRESS"
	case AttrSoftware:
		return "SOFTWARE"
	case AttrAlternateServer:
		return "ALTERNATE-SERVER"
	case AttrFingerprint:
		return "FINGERPRINT"
	default:
		// just return hex representation of unknown attribute type
		return "0x" + strconv.FormatUint(uint64(t), 16)
	}
}

// Attribute is a Type-Length-Value (TLV) object that
// can be added to a STUN message.  Attributes are divided into two
// types: comprehension-required and comprehension-optional.  STUN
// agents can safely ignore comprehension-optional attributes they
// don't understand, but cannot successfully process a message if it
// contains comprehension-required attributes that are not
// understood.
type Attribute struct {
	Type   AttrType
	Length uint16
	Value  []byte
}

// Equal returns true if a == b.
func (a Attribute) Equal(b Attribute) bool {
	if a.Type != b.Type {
		return false
	}
	if a.Length != b.Length {
		return false
	}
	for i, v := range a.Value {
		if b.Value[i] != v {
			return false
		}
	}
	return true
}

func (a Attribute) String() string {
	return fmt.Sprintf("%s: %x", a.Type, a.Value)
}

// MessageClass is 8-bit representation of 2-bit class of STUN Message Class.
type MessageClass byte

// Possible values for message class in STUN Message Type.
const (
	ClassRequest         = 0x00 // 0b00
	ClassIndication      = 0x01 // 0b01
	ClassSuccessResponse = 0x02 // 0b10
	ClassErrorResponse   = 0x03 // 0b11
)

func (c MessageClass) String() string {
	switch c {
	case ClassRequest:
		return "request"
	case ClassIndication:
		return "indication"
	case ClassSuccessResponse:
		return "success response"
	case ClassErrorResponse:
		return "error response"
	default:
		panic("unknown message class")
	}
}

// Method is uint16 representation of 12-bit STUN method.
type Method uint16

// possible methods for STUN Message.
const (
	MethodBinding Method = 0x01 // 0b000000000001
)

func (m Method) String() string {
	switch m {
	case MethodBinding:
		return "binding"
	default:
		return fmt.Sprintf("0x%s", strconv.FormatUint(uint64(m), 16))
	}
}

// MessageType is STUN Message Type Field.
type MessageType struct {
	Class  MessageClass
	Method Method
}

const (
	methodABits = 0xf   // 0b0000000000001111
	methodBBits = 0x70  // 0b0000000001110000
	methodDBits = 0xf80 // 0b0000111110000000

	methodBShift = 1
	methodDShift = 2

	firstBit  = 0x1
	secondBit = 0x2

	c0Bit = firstBit
	c1Bit = secondBit

	classC0Shift = 4
	classC1Shift = 7
)

// Value returns bit representation of messageType.
func (t MessageType) Value() uint16 {
	//	 0                 1
	//	 2  3  4 5 6 7 8 9 0 1 2 3 4 5
	//	+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
	//	|M |M |M|M|M|C|M|M|M|C|M|M|M|M|
	//	|11|10|9|8|7|1|6|5|4|0|3|2|1|0|
	//	+--+--+-+-+-+-+-+-+-+-+-+-+-+-+
	// Figure 3: Format of STUN Message Type Field

	// warning: Abandon all hope ye who enter here.
	// splitting M into A(M0-M3), B(M4-M6), D(M7-M11)
	m := uint16(t.Method)
	a := m & methodABits                              // A = M * 0b0000000000001111 (right 4 bits)
	b := m & methodBBits                              // B = M * 0b0000000001110000 (3 bits after A)
	d := m & methodDBits                              // D = M * 0b0000111110000000 (5 bits after B)
	m = a + (b << methodBShift) + (d << methodDShift) // shifting to add "holes" for C0 (at 4 bit) and C1 (8 bit)

	// C0 is zero bit of C, C1 is fist bit.
	// C0 = C * 0b01, C1 = (C * 0b10) >> 1
	// Ct = C0 << 4 + C1 << 8.
	// Optimizations: "((C * 0b10) >> 1) << 8" as "(C * 0b10) << 7"
	// We need C0 shifted by 4, and C1 by 8 to fit "11" and "7" positions (see figure 3).
	c := uint16(t.Class)
	c0 := (c & c0Bit) << classC0Shift
	c1 := (c & c1Bit) << classC1Shift
	class := c0 + c1

	return m + class
}

// ReadValue decodes uint16 into MessageType.
func (t *MessageType) ReadValue(v uint16) {
	// decoding class
	// we are taking first bit from v >> 4 and second from v >> 7.
	c0 := (v >> classC0Shift) & c0Bit
	c1 := (v >> classC1Shift) & c1Bit
	class := c0 + c1
	t.Class = MessageClass(class)

	// decoding method
	a := v & methodABits                   // A(M0-M3)
	b := (v >> methodBShift) & methodBBits // B(M4-M6)
	d := (v >> methodDShift) & methodDBits // D(M7-M11)
	m := a + b + d
	t.Method = Method(m)
}

func (t MessageType) String() string {
	return fmt.Sprintf("%s %s", t.Method, t.Class)
}

var (
	// ErrInvalidMagicCookie means that magic cookie field has invalid value.
	ErrInvalidMagicCookie = errors.New("Magic cookie value is invalid")
	// ErrInvalidMessageLength means that actual message size is smaller that length
	// from header field.
	ErrInvalidMessageLength = errors.New("Message size is smaller than length")
)
<|endoftext|>


<commit_before>package test

import (
	"bytes"
	"errors"
	"fmt"
	"math"
	"runtime"
	"strings"
	"testing"
)

// ErrPlain is the default error that is returned for functions in this package.
var ErrPlain = errors.New("error")

////////////////////////////////////////////////////////////////

func fileline(i int) string {
	_, file, line, ok := runtime.Caller(i)
	if !ok {
		return ""
	}
	parts := strings.Split(file, "/")
	file = parts[len(parts)-1]
	return fmt.Sprintf("%s:%d", file, line)
}

func trace() string {
	trace2 := fileline(2)
	trace3 := fileline(3)
	return "\r\t" + strings.Repeat(" ", len(fmt.Sprintf("%s:", trace2))) + "\r\t" + trace3
}

func message(msgs ...interface{}) string {
	if len(msgs) == 0 {
		return "\n"
	}
	return ": " + fmt.Sprintln(msgs...)
}

func printable(s string) string {
	s = strings.Replace(s, "\n", `\n`, -1)
	s = strings.Replace(s, "\r", `\r`, -1)
	s = strings.Replace(s, "\t", `\t`, -1)
	return s
}

////////////////////////////////////////////////////////////////

func That(t *testing.T, condition bool, msgs ...interface{}) {
	if !condition {
		t.Errorf("%s%s", trace(), message(msgs...))
	}
}

func Error(t *testing.T, err, expected error, msgs ...interface{}) {
	if err != expected {
		t.Errorf("%s%s   error: %v\nexpected: %v\n", trace(), message(msgs...), err, expected)
	}
}

func Float(t *testing.T, output, expected float64, msgs ...interface{}) {
	if math.Abs(output-expected) > 1e-10 {
		t.Errorf("%s%s  output: %f\nexpected: %f\n", trace(), message(msgs...), output, expected)
	}
}

func String(t *testing.T, output, expected string, msgs ...interface{}) {
	if output != expected {
		t.Errorf("%s%s  output: %s\nexpected: %s\n", trace(), message(msgs...), printable(output), printable(expected))
	}
}

func Bytes(t *testing.T, output, expected []byte, msgs ...interface{}) {
	if !bytes.Equal(output, expected) {
		t.Errorf("%s%s  output: %s\nexpected: %s\n", trace(), message(msgs...), printable(string(output)), printable(string(expected)))
	}
}

func Minify(t *testing.T, input string, err error, output, expected string, msgs ...interface{}) {
	if err != nil {
		t.Errorf("%s%s   given: %s\n   error: %v\n", trace(), message(msgs...), printable(input), err)
	}
	if output != expected {
		t.Errorf("%s%s   given: %s\n  output: %s\nexpected: %s\n", trace(), message(msgs...), printable(input), printable(output), printable(expected))
	}
}
<commit_msg>Add Int<commit_after>package test

import (
	"bytes"
	"errors"
	"fmt"
	"math"
	"runtime"
	"strings"
	"testing"
)

// ErrPlain is the default error that is returned for functions in this package.
var ErrPlain = errors.New("error")

////////////////////////////////////////////////////////////////

func fileline(i int) string {
	_, file, line, ok := runtime.Caller(i)
	if !ok {
		return ""
	}
	parts := strings.Split(file, "/")
	file = parts[len(parts)-1]
	return fmt.Sprintf("%s:%d", file, line)
}

func trace() string {
	trace2 := fileline(2)
	trace3 := fileline(3)
	return "\r\t" + strings.Repeat(" ", len(fmt.Sprintf("%s:", trace2))) + "\r\t" + trace3
}

func message(msgs ...interface{}) string {
	if len(msgs) == 0 {
		return "\n"
	}
	return ": " + fmt.Sprintln(msgs...)
}

func printable(s string) string {
	s = strings.Replace(s, "\n", `\n`, -1)
	s = strings.Replace(s, "\r", `\r`, -1)
	s = strings.Replace(s, "\t", `\t`, -1)
	return s
}

////////////////////////////////////////////////////////////////

func That(t *testing.T, condition bool, msgs ...interface{}) {
	if !condition {
		t.Errorf("%s%s", trace(), message(msgs...))
	}
}

func Error(t *testing.T, err, expected error, msgs ...interface{}) {
	if err != expected {
		t.Errorf("%s%s   error: %v\nexpected: %v\n", trace(), message(msgs...), err, expected)
	}
}

func Int(t *testing.T, output, expected int, msgs ...interface{}) {
	if output != expected {
		t.Errorf("%s%s  output: %d\nexpected: %d\n", trace(), message(msgs...), output, expected)
	}
}

func Float(t *testing.T, output, expected float64, msgs ...interface{}) {
	if math.Abs(output-expected) > 1e-10 {
		t.Errorf("%s%s  output: %f\nexpected: %f\n", trace(), message(msgs...), output, expected)
	}
}

func String(t *testing.T, output, expected string, msgs ...interface{}) {
	if output != expected {
		t.Errorf("%s%s  output: %s\nexpected: %s\n", trace(), message(msgs...), printable(output), printable(expected))
	}
}

func Bytes(t *testing.T, output, expected []byte, msgs ...interface{}) {
	if !bytes.Equal(output, expected) {
		t.Errorf("%s%s  output: %s\nexpected: %s\n", trace(), message(msgs...), printable(string(output)), printable(string(expected)))
	}
}

func Minify(t *testing.T, input string, err error, output, expected string, msgs ...interface{}) {
	if err != nil {
		t.Errorf("%s%s   given: %s\n   error: %v\n", trace(), message(msgs...), printable(input), err)
	}
	if output != expected {
		t.Errorf("%s%s   given: %s\n  output: %s\nexpected: %s\n", trace(), message(msgs...), printable(input), printable(output), printable(expected))
	}
}
<|endoftext|>


<commit_before>// Implementation of an R-Way Trie data structure.
//
// A Trie has a root Node which is the base of the tree.
// Each subsequent Node has a letter and children, which are
// nodes that have letter values associated with them.
package trie

import (
	"sort"
)

type Node struct {
	val      rune
	term     bool
	meta     interface{}
	mask     uint64
	parent   *Node
	children map[rune]*Node
}

type Trie struct {
	root *Node
	size int
}

type ByKeys []string

func (a ByKeys) Len() int           { return len(a) }
func (a ByKeys) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByKeys) Less(i, j int) bool { return len(a[i]) < len(a[j]) }

const nul = 0x0

// Creates a new Trie with an initialized root Node.
func New() *Trie {
	node := newNode(nil, 0, 0, false)
	return &Trie{
		root: node,
		size: 0,
	}
}

// Returns the root node for the Trie.
func (t *Trie) Root() *Node {
	return t.root
}

// Adds the key to the Trie, including meta data. Meta data
// is stored as `interface{}` and must be type cast by
// the caller.
func (t *Trie) Add(key string, meta interface{}) *Node {
	t.size++
	runes := []rune(key)
	node := t.addrune(t.Root(), runes, 0)
	node.meta = meta
	return node
}

// Finds and returns meta data associated
// with `key`.
func (t *Trie) Find(key string) (*Node, bool) {
	node := t.nodeAtPath(key)
	if node == nil {
		return nil, false
	}
	node = node.Children()[nul]

	if !node.term {
		return nil, false
	}

	return node, true
}

// Removes a key from the trie, ensuring that
// all bitmasks up to root are appropriately recalculated.
func (t *Trie) Remove(key string) {
	var (
		i    int
		rs   = []rune(key)
		node = t.nodeAtPath(key)
	)

	t.size--
	for n := node.Parent(); n != nil; n = n.Parent() {
		i++
		if len(n.Children()) > 1 {
			r := rs[len(rs)-i]
			n.RemoveChild(r)
			break
		}
	}
}

// Returns all the keys currently stored in the trie.
func (t *Trie) Keys() []string {
	return t.PrefixSearch("")
}

// Performs a fuzzy search against the keys in the trie.
func (t Trie) FuzzySearch(pre string) []string {
	var (
		keys []string
		pm   []rune
	)

	fuzzycollect(t.Root(), 0, pm, []rune(pre), &keys)
	sort.Sort(ByKeys(keys))

	return keys
}

// Performs a prefix search against the keys in the trie.
func (t Trie) PrefixSearch(pre string) []string {
	var keys []string

	node := t.nodeAtPath(pre)
	if node == nil {
		return keys
	}

	collect(node, []rune(pre), &keys)
	return keys
}

func (t Trie) nodeAtPath(pre string) *Node {
	runes := []rune(pre)
	return findNode(t.Root(), runes)
}

func (t Trie) addrune(node *Node, runes []rune, i int) *Node {
	if len(runes) == 0 {
		return node.NewChild(0, 0, nul, true)
	}

	r := runes[0]
	c := node.Children()

	n, ok := c[r]
	bitmask := maskruneslice(runes)
	if !ok {
		n = node.NewChild(r, bitmask, r, false)
	}
	n.mask |= bitmask

	i++
	return t.addrune(n, runes[1:], i)
}

func newNode(parent *Node, val rune, m uint64, term bool) *Node {
	return &Node{
		val:      val,
		mask:     m,
		term:     term,
		parent:   parent,
		children: make(map[rune]*Node),
	}
}

// Creates and returns a pointer to a new child for the node.
func (n *Node) NewChild(r rune, bitmask uint64, val rune, term bool) *Node {
	node := newNode(n, val, bitmask, term)
	n.children[r] = node
	return node
}

func (n *Node) RemoveChild(r rune) {
	delete(n.children, r)

	n.recalculateMask()
	for parent := n.Parent(); parent != nil; parent = parent.Parent() {
		parent.recalculateMask()
	}
}

func (n *Node) recalculateMask() {
	n.mask = maskrune(n.Val())
	for k, c := range n.Children() {
		n.mask |= (maskrune(k) | c.Mask())
	}
}

// Returns the parent of this node.
func (n Node) Parent() *Node {
	return n.parent
}

// Returns the meta information of this node.
func (n Node) Meta() interface{} {
	return n.meta
}

// Returns the children of this node.
func (n Node) Children() map[rune]*Node {
	return n.children
}

func (n Node) Val() rune {
	return n.val
}

// Returns a uint64 representing the current
// mask of this node.
func (n Node) Mask() uint64 {
	return n.mask
}

func findNode(node *Node, runes []rune) *Node {
	if node == nil {
		return nil
	}

	if len(runes) == 0 {
		return node
	}

	n, ok := node.Children()[runes[0]]
	if !ok {
		return nil
	}

	var nrunes []rune
	if len(runes) > 1 {
		nrunes = runes[1:]
	} else {
		nrunes = runes[0:0]
	}

	return findNode(n, nrunes)
}

func maskruneslice(rs []rune) uint64 {
	var m uint64
	for _, r := range rs {
		m |= maskrune(r)
	}

	return m
}

func maskrune(r rune) uint64 {
	i := uint64(1)
	return i << (uint64(r) - 97)
}

func collect(node *Node, pre []rune, keys *[]string) {
	children := node.Children()
	for r, n := range children {
		if n.term {
			*keys = append(*keys, string(pre))
			continue
		}

		npre := append(pre, r)
		collect(n, npre, keys)
	}
}

func fuzzycollect(node *Node, idx int, partialmatch, partial []rune, keys *[]string) {
	var (
		m          uint64
		partiallen = len(partial)
	)

	if partiallen == idx {
		collect(node, partialmatch, keys)
		return
	}

	children := node.Children()
	m = maskruneslice(partial[idx:])
	for v, n := range children {
		if (n.mask & m) != m {
			continue
		}

		if v == partial[idx] {
			fuzzycollect(n, idx+1, append(partialmatch, v), partial, keys)
			continue
		}

		fuzzycollect(n, idx, append(partialmatch, v), partial, keys)
	}
}
<commit_msg>Remove superfluous function calls<commit_after>// Implementation of an R-Way Trie data structure.
//
// A Trie has a root Node which is the base of the tree.
// Each subsequent Node has a letter and children, which are
// nodes that have letter values associated with them.
package trie

import (
	"sort"
)

type Node struct {
	val      rune
	term     bool
	meta     interface{}
	mask     uint64
	parent   *Node
	children map[rune]*Node
}

type Trie struct {
	root *Node
	size int
}

type ByKeys []string

func (a ByKeys) Len() int           { return len(a) }
func (a ByKeys) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByKeys) Less(i, j int) bool { return len(a[i]) < len(a[j]) }

const nul = 0x0

// Creates a new Trie with an initialized root Node.
func New() *Trie {
	node := newNode(nil, 0, 0, false)
	return &Trie{
		root: node,
		size: 0,
	}
}

// Returns the root node for the Trie.
func (t *Trie) Root() *Node {
	return t.root
}

// Adds the key to the Trie, including meta data. Meta data
// is stored as `interface{}` and must be type cast by
// the caller.
func (t *Trie) Add(key string, meta interface{}) *Node {
	t.size++
	runes := []rune(key)
	node := t.root
	for i := range runes {
		r := runes[i]
		bitmask := maskruneslice(runes[i:])
		n, ok := node.children[r]
		if !ok {
			n = node.NewChild(r, bitmask, r, false)
		}
		node = n
		node.mask |= bitmask
	}
	node = node.NewChild(0, 0, nul, true)
	node.meta = meta
	return node
}

// Finds and returns meta data associated
// with `key`.
func (t *Trie) Find(key string) (*Node, bool) {
	node := t.nodeAtPath(key)
	if node == nil {
		return nil, false
	}
	node = node.Children()[nul]

	if !node.term {
		return nil, false
	}

	return node, true
}

// Removes a key from the trie, ensuring that
// all bitmasks up to root are appropriately recalculated.
func (t *Trie) Remove(key string) {
	var (
		i    int
		rs   = []rune(key)
		node = t.nodeAtPath(key)
	)

	t.size--
	for n := node.Parent(); n != nil; n = n.Parent() {
		i++
		if len(n.Children()) > 1 {
			r := rs[len(rs)-i]
			n.RemoveChild(r)
			break
		}
	}
}

// Returns all the keys currently stored in the trie.
func (t *Trie) Keys() []string {
	return t.PrefixSearch("")
}

// Performs a fuzzy search against the keys in the trie.
func (t Trie) FuzzySearch(pre string) []string {
	var (
		keys []string
		pm   []rune
	)

	fuzzycollect(t.Root(), 0, pm, []rune(pre), &keys)
	sort.Sort(ByKeys(keys))

	return keys
}

// Performs a prefix search against the keys in the trie.
func (t Trie) PrefixSearch(pre string) []string {
	var keys []string

	node := t.nodeAtPath(pre)
	if node == nil {
		return keys
	}

	collect(node, []rune(pre), &keys)
	return keys
}

func (t Trie) nodeAtPath(pre string) *Node {
	runes := []rune(pre)
	return findNode(t.Root(), runes)
}

func newNode(parent *Node, val rune, m uint64, term bool) *Node {
	return &Node{
		val:      val,
		mask:     m,
		term:     term,
		parent:   parent,
		children: make(map[rune]*Node),
	}
}

// Creates and returns a pointer to a new child for the node.
func (n *Node) NewChild(r rune, bitmask uint64, val rune, term bool) *Node {
	node := newNode(n, val, bitmask, term)
	n.children[r] = node
	return node
}

func (n *Node) RemoveChild(r rune) {
	delete(n.children, r)

	n.recalculateMask()
	for parent := n.Parent(); parent != nil; parent = parent.Parent() {
		parent.recalculateMask()
	}
}

func (n *Node) recalculateMask() {
	n.mask = maskrune(n.Val())
	for k, c := range n.Children() {
		n.mask |= (maskrune(k) | c.Mask())
	}
}

// Returns the parent of this node.
func (n Node) Parent() *Node {
	return n.parent
}

// Returns the meta information of this node.
func (n Node) Meta() interface{} {
	return n.meta
}

// Returns the children of this node.
func (n Node) Children() map[rune]*Node {
	return n.children
}

func (n Node) Val() rune {
	return n.val
}

// Returns a uint64 representing the current
// mask of this node.
func (n Node) Mask() uint64 {
	return n.mask
}

func findNode(node *Node, runes []rune) *Node {
	if node == nil {
		return nil
	}

	if len(runes) == 0 {
		return node
	}

	n, ok := node.Children()[runes[0]]
	if !ok {
		return nil
	}

	var nrunes []rune
	if len(runes) > 1 {
		nrunes = runes[1:]
	} else {
		nrunes = runes[0:0]
	}

	return findNode(n, nrunes)
}

func maskruneslice(rs []rune) uint64 {
	var m uint64
	for _, r := range rs {
		m |= maskrune(r)
	}

	return m
}

func maskrune(r rune) uint64 {
	i := uint64(1)
	return i << (uint64(r) - 97)
}

func collect(node *Node, pre []rune, keys *[]string) {
	children := node.Children()
	for r, n := range children {
		if n.term {
			*keys = append(*keys, string(pre))
			continue
		}

		npre := append(pre, r)
		collect(n, npre, keys)
	}
}

func fuzzycollect(node *Node, idx int, partialmatch, partial []rune, keys *[]string) {
	var (
		m          uint64
		partiallen = len(partial)
	)

	if partiallen == idx {
		collect(node, partialmatch, keys)
		return
	}

	children := node.Children()
	m = maskruneslice(partial[idx:])
	for v, n := range children {
		if (n.mask & m) != m {
			continue
		}

		if v == partial[idx] {
			fuzzycollect(n, idx+1, append(partialmatch, v), partial, keys)
			continue
		}

		fuzzycollect(n, idx, append(partialmatch, v), partial, keys)
	}
}
<|endoftext|>


<commit_before>// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package trie implements a byte trie with edge compression.
package trie

import (
	"bytes"
	"fmt"
)

// A trie maintains a sorted collection of values keyed on a string.
///Insertion is O(len(key)). Unlike Go's built-in map there is no
// distinction between a nil and a non-existent value.
// The zero value for Trie is an empty trie ready to use.
type Trie struct {
	suffix   string
	value    interface{}
	children []Trie
	base     byte
}

// Find the largest i such that a[:i] == b[:i]
func commonPrefix(a, b string) int {
	l := len(a)
	if l > len(b) {
		l = len(b)
	}
	for i := 0; i < l; i++ {
		if a[i] != b[i] {
			return i
		}
	}
	return l
}

// Put inserts or replaces a value in the trie.  To remove a value
// insert nil.
func (t *Trie) Put(key string, value interface{}) {
	if t.children == nil && t.value == nil { // empty node
		t.suffix = key
		t.value = value
		return
	}

	s := commonPrefix(t.suffix, key)

	if s < len(t.suffix) {
		// split on s: turn t into a node with suffix[:s]
		// and move the contents to child[suffix[s]-t.base] with suffix[s+1:]
		*t = Trie{t.suffix[:s], nil, []Trie{{t.suffix[s+1:], t.value, t.children, t.base}}, t.suffix[s]}
	}

	if s == len(key) {
		t.value = value
		return
	}

	if len(t.children) == 0 {
		t.children = make([]Trie, 1)
		t.base = key[s]
	} else {
		newbase := t.base
		newlen := len(t.children)
		for key[s] < newbase || int(key[s]) >= int(newbase)+newlen {
			newlen *= 2
			newbase &= ^byte(newlen - 1)
		}
		if newlen != len(t.children) {
			newch := make([]Trie, newlen)
			copy(newch[t.base-newbase:], t.children)
			t.children = newch
			t.base = newbase
		}
	}

	t.children[key[s]-t.base].Put(key[s+1:], value)

	return
}

// Get retrieves an element from the trie if it exists, or nil if it does not.
func (t *Trie) Get(key string) interface{} {
	s := commonPrefix(t.suffix, key)

	if s < len(t.suffix) {
		return nil
	}

	if s == len(key) {
		return t.value
	}

	if key[s] < t.base || int(key[s]) > int(t.base)+len(t.children) {
		return nil
	}

	return t.children[key[s]-t.base].Get(key[s+1:])
}

func (t *Trie) forEach(f func(string, interface{}) bool, buf *bytes.Buffer) bool {
	if t.value == nil && t.children == nil {
		return true
	}

	pfx := buf.Len()
	buf.WriteString(t.suffix)

	if t.value != nil && !f(buf.String(), t.value) {
		return false
	}

	if t.children != nil {
		l := buf.Len()
		buf.WriteByte(t.base)
		for _, v := range t.children {
			if !v.forEach(f, buf) {
				return false
			}
			buf.Bytes()[l]++
		}
	}

	buf.Truncate(pfx)

	return true
}

// ForEach will apply the function f to each key, value pair in the
// Trie in sorted (depth-first pre-)order.  if f returns false, the
// iteration will stop.
func (t *Trie) ForEach(f func(string, interface{}) bool) {
	var buf bytes.Buffer
	t.forEach(f, &buf)
}

// String returns a multiline string representation of the trie
// in the form
//    trie[
//       key1: value1
//       key2: value2
//       ....
//    ]
func (t *Trie) String() string {
	var buf bytes.Buffer
	buf.WriteString("trie{\n")
	t.ForEach(func(key string, val interface{}) bool {
		fmt.Fprintf(&buf, "\t%s:%v\n", key, val)
		return true
	})
	buf.WriteString("}")
	return buf.String()
}

// debug
const spaces = "                                                                                "

func (t *Trie) dump(level int) {
	if level > len(spaces) {
		level = len(spaces)
	}
	fmt.Printf("%s: %v\n", t.suffix, t.value)
	if t.children != nil {
		fmt.Printf("%s<%d>\n", spaces[:4*level], len(t.children))
	}
	c := t.base
	for _, ch := range t.children {
		if ch.value != nil || ch.children != nil {
			if c >= 32 && c < 128 {
				fmt.Printf("%s['%c']", spaces[:4*level], c)
			} else {
				fmt.Printf("%s[%d]", spaces[:4*level], c)
			}
			ch.dump(level + 1)
		}
		c++
	}
}

func (t *Trie) shape() (ln, sz int) {
	if t.value != nil {
		ln++
	}
	sz++
	for _, c := range t.children {
		l, s := c.shape()
		ln += l
		sz += s
	}
	return
}
<commit_msg>gfmted<commit_after>// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package trie implements a byte trie with edge compression.
package trie

import (
	"bytes"
	"fmt"
)

// A trie maintains a sorted collection of values keyed on a string.
///Insertion is O(len(key)). Unlike Go's built-in map there is no
// distinction between a nil and a non-existent value.
// The zero value for Trie is an empty trie ready to use.
type Trie struct {
	suffix   string
	value    interface{}
	children []Trie
	base     byte
}

// Find the largest i such that a[:i] == b[:i]
func commonPrefix(a, b string) int {
	l := len(a)
	if l > len(b) {
		l = len(b)
	}
	for i := 0; i < l; i++ {
		if a[i] != b[i] {
			return i
		}
	}
	return l
}

// Put inserts or replaces a value in the trie.  To remove a value
// insert nil.
func (t *Trie) Put(key string, value interface{}) {
	if t.children == nil && t.value == nil { // empty node
		t.suffix = key
		t.value = value
		return
	}

	s := commonPrefix(t.suffix, key)

	if s < len(t.suffix) {
		// split on s: turn t into a node with suffix[:s]
		// and move the contents to child[suffix[s]-t.base] with suffix[s+1:]
		*t = Trie{t.suffix[:s], nil, []Trie{{t.suffix[s+1:], t.value, t.children, t.base}}, t.suffix[s]}
	}

	if s == len(key) {
		t.value = value
		return
	}

	if len(t.children) == 0 {
		t.children = make([]Trie, 1)
		t.base = key[s]
	} else {
		newbase := t.base
		newlen := len(t.children)
		for key[s] < newbase || int(key[s]) >= int(newbase)+newlen {
			newlen *= 2
			newbase &= ^byte(newlen - 1)
		}
		if newlen != len(t.children) {
			newch := make([]Trie, newlen)
			copy(newch[t.base-newbase:], t.children)
			t.children = newch
			t.base = newbase
		}
	}

	t.children[key[s]-t.base].Put(key[s+1:], value)

	return
}

// Get retrieves an element from the trie if it exists, or nil if it does not.
func (t *Trie) Get(key string) interface{} {
	s := commonPrefix(t.suffix, key)

	if s < len(t.suffix) {
		return nil
	}

	if s == len(key) {
		return t.value
	}

	if key[s] < t.base || int(key[s]) > int(t.base)+len(t.children) {
		return nil
	}

	return t.children[key[s]-t.base].Get(key[s+1:])
}

func (t *Trie) forEach(f func(string, interface{}) bool, buf *bytes.Buffer) bool {
	if t.value == nil && t.children == nil {
		return true
	}

	pfx := buf.Len()
	buf.WriteString(t.suffix)

	if t.value != nil && !f(buf.String(), t.value) {
		return false
	}

	if t.children != nil {
		l := buf.Len()
		buf.WriteByte(t.base)
		for _, v := range t.children {
			if !v.forEach(f, buf) {
				return false
			}
			buf.Bytes()[l]++
		}
	}

	buf.Truncate(pfx)

	return true
}

// ForEach will apply the function f to each key, value pair in the
// Trie in sorted (depth-first pre-)order.  if f returns false, the
// iteration will stop.
func (t *Trie) ForEach(f func(string, interface{}) bool) {
	var buf bytes.Buffer
	t.forEach(f, &buf)
}

// String returns a multiline string representation of the trie
// in the form
//    trie[
//       key1: value1
//       key2: value2
//       ....
//    ]
func (t *Trie) String() string {
	var buf bytes.Buffer
	buf.WriteString("trie{\n")
	t.ForEach(func(key string, val interface{}) bool {
		fmt.Fprintf(&buf, "\t%s:%v\n", key, val)
		return true
	})
	buf.WriteString("}")
	return buf.String()
}

// debug
const spaces = "                                                                                "

func (t *Trie) dump(level int) {
	if level > len(spaces) {
		level = len(spaces)
	}
	fmt.Printf("%s: %v\n", t.suffix, t.value)
	if t.children != nil {
		fmt.Printf("%s<%d>\n", spaces[:4*level], len(t.children))
	}
	c := t.base
	for _, ch := range t.children {
		if ch.value != nil || ch.children != nil {
			if c >= 32 && c < 128 {
				fmt.Printf("%s['%c']", spaces[:4*level], c)
			} else {
				fmt.Printf("%s[%d]", spaces[:4*level], c)
			}
			ch.dump(level + 1)
		}
		c++
	}
}

func (t *Trie) shape() (ln, sz int) {
	if t.value != nil {
		ln++
	}
	sz++
	for _, c := range t.children {
		l, s := c.shape()
		ln += l
		sz += s
	}
	return
}
<|endoftext|>


<commit_before>package degob

// WireType is basically the same as the `encoding/gob` wiretype with a few
// fields added and exported. It is also a `Stringer` so the types can be
// printed for better viewing.
type WireType struct {
	ArrayT  *ArrayType
	SliceT  *SliceType
	StructT *StructType
	MapT    *MapType
}

// ArrayType represents a fixed size array
type ArrayType struct {
	CommonType
	Elem           typeId
	ElemTypeString string
	Len            int
}

// CommonType has information common to all base types
type CommonType struct {
	Name string
	Id   int
}

// SliceType represents a slice
type SliceType struct {
	CommonType
	Elem           typeId
	ElemTypeString string
}
type StructType struct {
	CommonType
	Field []*FieldType
}

// FieldType is the information for a struct field
type FieldType struct {
	Name       string
	TypeString string
	Id         int
}

// MapType is the information for a map
type MapType struct {
	CommonType
	Key            typeId
	KeyTypeString  string
	Elem           typeId
	ElemTypeString string
}

const (
	// builtin types
	_bool_id      typeId = 1
	_int_id       typeId = 2
	_uint_id      typeId = 3
	_float_id     typeId = 4
	_bytes_id     typeId = 5
	_string_id    typeId = 6
	_complex_id   typeId = 7
	_interface_id typeId = 8
	// reserved types
	_reserved1_id typeId = 9
	_reserved2_id typeId = 10
	_reserved3_id typeId = 11
	_reserved4_id typeId = 12
	_reserved5_id typeId = 13
	_reserved6_id typeId = 14
	_reserved7_id typeId = 15
)

// Value is a reprsentation of a Go value. You can test for equality and
// Display them stylized
type Value interface {
	// Equal tests for equality to another value
	Equal(Value) bool
	// Display shows the value accoring to the chosen style
	Display(sty style) string
}

type sliceValue struct {
	elemType string
	values   []Value
}

func (v sliceValue) Equal(o Value) bool {
	ov, ok := o.(*sliceValue)
	if !ok {
		return false
	}
	if len(v.values) != len(ov.values) {
		return false
	}
	for i, v := range v.values {
		if !v.Equal(ov.values[i]) {
			return false
		}
	}
	return true
}

type arrayValue struct {
	elemType string
	length   int
	values   []Value
}

func (v arrayValue) Equal(o Value) bool {
	ov, ok := o.(*arrayValue)
	if !ok {
		return false
	}
	if v.length != ov.length {
		return false
	}
	for i, v := range v.values {
		if !v.Equal(ov.values[i]) {
			return false
		}
	}
	return true
}

type mapValue struct {
	keyType  string
	elemType string
	values   map[Value]Value
}

func (v mapValue) Equal(o Value) bool {
	ov, ok := o.(*mapValue)
	if !ok {
		return false
	}
	if v.keyType != ov.keyType {
		return false
	}
	if v.elemType != ov.elemType {
		return false
	}
	if len(v.values) != len(ov.values) {
		return false
	}
	for k, vtmp := range v.values {
		ovtmp, ok := ov.values[k]
		if !ok {
			// this could be goofy with interfaces so let's be thorough
			// TODO: this is probably pointing to some issue with design
			// in general, but it works for now
			found := false
			for ovk, ovtmp := range ov.values {
				if vtmp.Equal(ovtmp) && k.Equal(ovk) {
					found = true
					break
				}
			}
			if !found {
				return false
			}
		} else if !vtmp.Equal(ovtmp) {
			return false
		}
	}
	return true
}

type structValue struct {
	name   string
	fields map[string]Value
}

func (s *structValue) Equal(o Value) bool {
	v, ok := o.(*structValue)
	if !ok {
		return false
	}

	if s.name != v.name {
		return false
	}
	for k, val := range s.fields {
		ov, ok := v.fields[k]
		if !ok {
			return false
		}
		if !val.Equal(ov) {
			return false
		}
	}
	return true
}

type _bool_type bool

func (v _bool_type) Equal(o Value) bool {
	ov, ok := o.(_bool_type)
	if !ok {
		return false
	}
	return v == ov
}

type _int_type int64

func (v _int_type) Equal(o Value) bool {
	ov, ok := o.(_int_type)
	if !ok {
		return false
	}
	return v == ov
}

type _uint_type uint64

func (v _uint_type) Equal(o Value) bool {
	ov, ok := o.(_uint_type)
	if !ok {
		return false
	}
	return v == ov
}

type _float_type float64

func (v _float_type) Equal(o Value) bool {
	ov, ok := o.(_float_type)
	if !ok {
		return false
	}
	return v == ov
}

type _bytes_type []byte

func (v _bytes_type) Equal(o Value) bool {
	ov, ok := o.(_bytes_type)
	if !ok {
		return false
	}
	if len(v) != len(ov) {
		return false
	}

	for i, b := range v {
		if b != ov[i] {
			return false
		}
	}
	return true
}

type _string_type string

func (v _string_type) Equal(o Value) bool {
	ov, ok := o.(_string_type)
	if !ok {
		return false
	}
	return v == ov
}

type _complex_type complex128

func (v _complex_type) Equal(o Value) bool {
	ov, ok := o.(_complex_type)
	if !ok {
		return false
	}
	return v == ov
}

type _nil_value struct{}

func (v _nil_value) Equal(o Value) bool {
	_, ok := o.(_nil_value)
	return ok
}

type interfaceValue struct {
	name  string
	value Value
}

func (v interfaceValue) Equal(o Value) bool {
	ov, ok := o.(interfaceValue)
	if !ok {
		return false
	}
	if v.name != ov.name {
		return false
	}
	eq := v.value.Equal(ov.value)
	if !eq {
	}
	return eq
}

func valueFor(id typeId) Value {
	switch id {
	case _bool_id:
		var v _bool_type
		return v
	case _int_id:
		var v _int_type
		return v
	case _uint_id:
		var v _uint_type
		return v
	case _float_id:
		var v _float_type
		return v
	case _bytes_id:
		var v _bytes_type
		return v
	case _string_id:
		var v _string_type
		return v
	case _complex_id:
		var v _complex_type
		return v
	case _interface_id:
		var v interfaceValue
		return v
	default:
		panic("unknown id")
	}
}

func isBuiltin(id typeId) bool {
	return (id >= 1) && (id <= 8)
}

func (t typeId) name() string {
	switch t {
	case _bool_id:
		return "bool"
	case _int_id:
		return "int64"
	case _uint_id:
		return "uint64"
	case _float_id:
		return "float64"
	case _bytes_id:
		return "[]byte"
	case _string_id:
		return "string"
	case _complex_id:
		return "complex128"
	case _interface_id:
		return "interface{}"
	default:
		panic("unknown id")
	}
}
<commit_msg>fixed strange code in interfaceValue Equal method<commit_after>package degob

// WireType is basically the same as the `encoding/gob` wiretype with a few
// fields added and exported. It is also a `Stringer` so the types can be
// printed for better viewing.
type WireType struct {
	ArrayT  *ArrayType
	SliceT  *SliceType
	StructT *StructType
	MapT    *MapType
}

// ArrayType represents a fixed size array
type ArrayType struct {
	CommonType
	Elem           typeId
	ElemTypeString string
	Len            int
}

// CommonType has information common to all base types
type CommonType struct {
	Name string
	Id   int
}

// SliceType represents a slice
type SliceType struct {
	CommonType
	Elem           typeId
	ElemTypeString string
}
type StructType struct {
	CommonType
	Field []*FieldType
}

// FieldType is the information for a struct field
type FieldType struct {
	Name       string
	TypeString string
	Id         int
}

// MapType is the information for a map
type MapType struct {
	CommonType
	Key            typeId
	KeyTypeString  string
	Elem           typeId
	ElemTypeString string
}

const (
	// builtin types
	_bool_id      typeId = 1
	_int_id       typeId = 2
	_uint_id      typeId = 3
	_float_id     typeId = 4
	_bytes_id     typeId = 5
	_string_id    typeId = 6
	_complex_id   typeId = 7
	_interface_id typeId = 8
	// reserved types
	_reserved1_id typeId = 9
	_reserved2_id typeId = 10
	_reserved3_id typeId = 11
	_reserved4_id typeId = 12
	_reserved5_id typeId = 13
	_reserved6_id typeId = 14
	_reserved7_id typeId = 15
)

// Value is a reprsentation of a Go value. You can test for equality and
// Display them stylized
type Value interface {
	// Equal tests for equality to another value
	Equal(Value) bool
	// Display shows the value accoring to the chosen style
	Display(sty style) string
}

type sliceValue struct {
	elemType string
	values   []Value
}

func (v sliceValue) Equal(o Value) bool {
	ov, ok := o.(*sliceValue)
	if !ok {
		return false
	}
	if len(v.values) != len(ov.values) {
		return false
	}
	for i, v := range v.values {
		if !v.Equal(ov.values[i]) {
			return false
		}
	}
	return true
}

type arrayValue struct {
	elemType string
	length   int
	values   []Value
}

func (v arrayValue) Equal(o Value) bool {
	ov, ok := o.(*arrayValue)
	if !ok {
		return false
	}
	if v.length != ov.length {
		return false
	}
	for i, v := range v.values {
		if !v.Equal(ov.values[i]) {
			return false
		}
	}
	return true
}

type mapValue struct {
	keyType  string
	elemType string
	values   map[Value]Value
}

func (v mapValue) Equal(o Value) bool {
	ov, ok := o.(*mapValue)
	if !ok {
		return false
	}
	if v.keyType != ov.keyType {
		return false
	}
	if v.elemType != ov.elemType {
		return false
	}
	if len(v.values) != len(ov.values) {
		return false
	}
	for k, vtmp := range v.values {
		ovtmp, ok := ov.values[k]
		if !ok {
			// this could be goofy with interfaces so let's be thorough
			// TODO: this is probably pointing to some issue with design
			// in general, but it works for now
			found := false
			for ovk, ovtmp := range ov.values {
				if vtmp.Equal(ovtmp) && k.Equal(ovk) {
					found = true
					break
				}
			}
			if !found {
				return false
			}
		} else if !vtmp.Equal(ovtmp) {
			return false
		}
	}
	return true
}

type structValue struct {
	name   string
	fields map[string]Value
}

func (s *structValue) Equal(o Value) bool {
	v, ok := o.(*structValue)
	if !ok {
		return false
	}

	if s.name != v.name {
		return false
	}
	for k, val := range s.fields {
		ov, ok := v.fields[k]
		if !ok {
			return false
		}
		if !val.Equal(ov) {
			return false
		}
	}
	return true
}

type _bool_type bool

func (v _bool_type) Equal(o Value) bool {
	ov, ok := o.(_bool_type)
	if !ok {
		return false
	}
	return v == ov
}

type _int_type int64

func (v _int_type) Equal(o Value) bool {
	ov, ok := o.(_int_type)
	if !ok {
		return false
	}
	return v == ov
}

type _uint_type uint64

func (v _uint_type) Equal(o Value) bool {
	ov, ok := o.(_uint_type)
	if !ok {
		return false
	}
	return v == ov
}

type _float_type float64

func (v _float_type) Equal(o Value) bool {
	ov, ok := o.(_float_type)
	if !ok {
		return false
	}
	return v == ov
}

type _bytes_type []byte

func (v _bytes_type) Equal(o Value) bool {
	ov, ok := o.(_bytes_type)
	if !ok {
		return false
	}
	if len(v) != len(ov) {
		return false
	}

	for i, b := range v {
		if b != ov[i] {
			return false
		}
	}
	return true
}

type _string_type string

func (v _string_type) Equal(o Value) bool {
	ov, ok := o.(_string_type)
	if !ok {
		return false
	}
	return v == ov
}

type _complex_type complex128

func (v _complex_type) Equal(o Value) bool {
	ov, ok := o.(_complex_type)
	if !ok {
		return false
	}
	return v == ov
}

type _nil_value struct{}

func (v _nil_value) Equal(o Value) bool {
	_, ok := o.(_nil_value)
	return ok
}

type interfaceValue struct {
	name  string
	value Value
}

func (v interfaceValue) Equal(o Value) bool {
	ov, ok := o.(interfaceValue)
	if !ok {
		return false
	}
	if v.name != ov.name {
		return false
	}
	return v.value.Equal(ov.value)
}

func valueFor(id typeId) Value {
	switch id {
	case _bool_id:
		var v _bool_type
		return v
	case _int_id:
		var v _int_type
		return v
	case _uint_id:
		var v _uint_type
		return v
	case _float_id:
		var v _float_type
		return v
	case _bytes_id:
		var v _bytes_type
		return v
	case _string_id:
		var v _string_type
		return v
	case _complex_id:
		var v _complex_type
		return v
	case _interface_id:
		var v interfaceValue
		return v
	default:
		panic("unknown id")
	}
}

func isBuiltin(id typeId) bool {
	return (id >= 1) && (id <= 8)
}

func (t typeId) name() string {
	switch t {
	case _bool_id:
		return "bool"
	case _int_id:
		return "int64"
	case _uint_id:
		return "uint64"
	case _float_id:
		return "float64"
	case _bytes_id:
		return "[]byte"
	case _string_id:
		return "string"
	case _complex_id:
		return "complex128"
	case _interface_id:
		return "interface{}"
	default:
		panic("unknown id")
	}
}
<|endoftext|>


<commit_before>// Copyright 2014 Rana Ian. All rights reserved.
// Use of this source code is governed by The MIT License
// found in the accompanying LICENSE file.

package ora

/*
#include <oci.h>
#include <stdlib.h>
#include <string.h>
*/
import "C"
import (
	"bytes"
	"container/list"
	"io"
	"io/ioutil"
	"sync"
	"time"
)

// When a parent handle is freed, all child handles associated with it are also
// freed, and can no longer be used. For example, when a statement handle is freed,
// any bind and define handles associated with it are also freed.

// bnd represents an between a Go parameter and a sql statement placeholder and
// contains logic to transfer a Go type to an Oracle OCI type.
type bnd interface {
	// setPtr enables some bind types to set out-bound pointers for some types such as time.Time, etc.
	setPtr() error
	// close releases resources and resets fields.
	close() error
}

// def represents a select-list column definition containing logic to transfer
// an Oracle OCI type to a Go type.
type def interface {
	// value gets a Go value from an Oracle buffer.
	value() (interface{}, error)
	// alloc allocates an OCI descriptor.
	alloc() error
	// free releases an OCI descriptor.
	free()
	// close releases resources and resets fields.
	close() error
}

// Int64 is a nullable int64.
type Int64 struct {
	IsNull bool
	Value  int64
}

// Equals returns true when the receiver and specified Int64 are both null,
// or when the receiver and specified Int64 are both not null and Values are equal.
func (this Int64) Equals(other Int64) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Int32 is a nullable int32.
type Int32 struct {
	IsNull bool
	Value  int32
}

// Equals returns true when the receiver and specified Int32 are both null,
// or when the receiver and specified Int32 are both not null and Values are equal.
func (this Int32) Equals(other Int32) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Int16 is a nullable int16.
type Int16 struct {
	IsNull bool
	Value  int16
}

// Equals returns true when the receiver and specified Int16 are both null,
// or when the receiver and specified Int16 are both not null and Values are equal.
func (this Int16) Equals(other Int16) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Int8 is a nullable int8.
type Int8 struct {
	IsNull bool
	Value  int8
}

// Equals returns true when the receiver and specified Int8 are both null,
// or when the receiver and specified Int8 are both not null and Values are equal.
func (this Int8) Equals(other Int8) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Uint64 is a nullable uint64.
type Uint64 struct {
	IsNull bool
	Value  uint64
}

// Equals returns true when the receiver and specified Uint64 are both null,
// or when the receiver and specified Uint64 are both not null and Values are equal.
func (this Uint64) Equals(other Uint64) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Uint32 is a nullable uint32.
type Uint32 struct {
	IsNull bool
	Value  uint32
}

// Equals returns true when the receiver and specified Uint32 are both null,
// or when the receiver and specified Uint32 are both not null and Values are equal.
func (this Uint32) Equals(other Uint32) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Uint16 is a nullable uint16.
type Uint16 struct {
	IsNull bool
	Value  uint16
}

// Equals returns true when the receiver and specified Uint16 are both null,
// or when the receiver and specified Uint16 are both not null and Values are equal.
func (this Uint16) Equals(other Uint16) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Uint8 is a nullable uint8.
type Uint8 struct {
	IsNull bool
	Value  uint8
}

// Equals returns true when the receiver and specified Uint8 are both null,
// or when the receiver and specified Uint8 are both not null and Values are equal.
func (this Uint8) Equals(other Uint8) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Float64 is a nullable float64.
type Float64 struct {
	IsNull bool
	Value  float64
}

// Equals returns true when the receiver and specified Float64 are both null,
// or when the receiver and specified Float64 are both not null and Values are equal.
func (this Float64) Equals(other Float64) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Float32 is a nullable float32.
type Float32 struct {
	IsNull bool
	Value  float32
}

// Equals returns true when the receiver and specified Float32 are both null,
// or when the receiver and specified Float32 are both not null and Values are equal.
func (this Float32) Equals(other Float32) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Time is a nullable time.Time.
type Time struct {
	IsNull bool
	Value  time.Time
}

// Equals returns true when the receiver and specified Time are both null,
// or when the receiver and specified Time are both not null and Values are equal.
func (this Time) Equals(other Time) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value.Equal(other.Value))
}

// String is a nullable string.
type String struct {
	IsNull bool
	Value  string
}

// Equals returns true when the receiver and specified String are both null,
// or when the receiver and specified String are both not null and Values are equal.
func (this String) Equals(other String) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Bool is a nullable bool.
type Bool struct {
	IsNull bool
	Value  bool
}

// Equals returns true when the receiver and specified Bool are both null,
// or when the receiver and specified Bool are both not null and Values are equal.
func (this Bool) Equals(other Bool) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Raw represents a nullable byte slice for RAW or LONG RAW Oracle values.
type Raw struct {
	IsNull bool
	Value  []byte
}

// Equals returns true when the receiver and specified Raw are both null,
// or when the receiver and specified Raw are both not null and Values are equal.
func (this Raw) Equals(other Raw) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull &&
			bytes.Equal(this.Value, other.Value))
}

// Lob's Reader is sent to the DB on bind, if not nil.
// The Reader can read the LOB if we bind a *Lob, Closer will close the LOB.
type Lob struct {
	io.Reader
	io.Closer
}

func (this Lob) Close() error {
	if this.Closer != nil {
		return this.Closer.Close()
	}
	return nil
}

// Equals returns true when the receiver and specified Lob are both null,
// or when they both not null and share the same Reader.
func (this Lob) Equals(other Lob) bool {
	return this.Reader == other.Reader // this is a quite strict equality...
}

func (this Lob) Bytes() ([]byte, error) {
	if this.Reader == nil {
		return nil, io.EOF
	}
	return ioutil.ReadAll(this.Reader)
}

// Bfile represents a nullable BFILE Oracle value.
type Bfile struct {
	IsNull         bool
	DirectoryAlias string
	Filename       string
}

// Equals returns true when the receiver and specified Bfile are both null,
// or when the receiver and specified Bfile are both not null, DirectoryAlias are equal
// and Filename are equal.
func (this Bfile) Equals(other Bfile) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.DirectoryAlias == other.DirectoryAlias && this.Filename == other.Filename)
}

// IntervalYM represents a nullable INTERVAL YEAR TO MONTH Oracle value.
type IntervalYM struct {
	IsNull bool
	Year   int32
	Month  int32
}

// Equals returns true when the receiver and specified IntervalYM are both null,
// or when the receiver and specified IntervalYM are both not null, Year are equal
// and Month are equal.
func (this IntervalYM) Equals(other IntervalYM) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Year == other.Year && this.Month == other.Month)
}

// ShiftTime returns a new Time with IntervalYM applied.
func (this IntervalYM) ShiftTime(t time.Time) time.Time {
	return t.AddDate(int(this.Year), int(this.Month), 0)
}

// IntervalDS represents a nullable INTERVAL DAY TO SECOND Oracle value.
type IntervalDS struct {
	IsNull     bool
	Day        int32
	Hour       int32
	Minute     int32
	Second     int32
	Nanosecond int32
}

// Equals returns true when the receiver and specified IntervalDS are both null,
// or when the receiver and specified IntervalDS are both not null, and all other
// fields are equal.
func (this IntervalDS) Equals(other IntervalDS) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull &&
			this.Day == other.Day &&
			this.Hour == other.Hour &&
			this.Minute == other.Minute &&
			this.Second == other.Second &&
			this.Nanosecond == other.Nanosecond)
}

// ShiftTime returns a new Time with IntervalDS applied.
func (this IntervalDS) ShiftTime(t time.Time) time.Time {
	year, month, day := t.Date()
	hour, min, sec := t.Clock()
	return time.Date(year, month, day+int(this.Day), hour+int(this.Hour), min+int(this.Minute), sec+int(this.Second), t.Nanosecond()+int(this.Nanosecond), t.Location())
}

// MultiErr holds multiple errors in a single string.
type MultiErr struct {
	str string
}

// Error returns one or more errors.
//
// Error is a member of the 'error' interface.
func (m MultiErr) Error() string {
	return m.str
}

// newMultiErr returns a MultiErr or nil.
// It is valid to pass nil errors to newMultiErr.
// Nil errors will be filtered out. If all errors
// are nil newMultiError will return nil.
func newMultiErr(errs ...error) *MultiErr {
	var buf bytes.Buffer
	for _, err := range errs {
		if err != nil {
			buf.WriteString(err.Error())
			buf.WriteString(", ")
		}
	}
	if buf.Len() > 0 {
		return &MultiErr{str: buf.String()}
	} else {
		return nil
	}
}

// newMultiErrL returns a MultiErr or nil.
// It is valid to pass nil errors to newMultiErr.
// Nil errors will be filtered out. If all errors
// are nil newMultiError will return nil.
func newMultiErrL(errs *list.List) *MultiErr {
	var buf bytes.Buffer
	for e := errs.Front(); e != nil; e = e.Next() {
		if e.Value != nil {
			err := e.Value.(error)
			buf.WriteString(err.Error())
			buf.WriteString(", ")
		}
	}
	if buf.Len() > 0 {
		return &MultiErr{str: buf.String()}
	} else {
		return nil
	}
}

// prefer simple pool instead of sync.Pool to control lifetime of instances
// sync.Pool eliminates instances at its own discretion
// would prefer to maintain instances indefinitely; or, eventually clean on a long timer
type pool struct {
	l       *list.List
	mu      sync.Mutex
	genItem func() interface{}
}

func newPool(genItem func() interface{}) *pool {
	p := &pool{}
	p.l = list.New()
	p.genItem = genItem
	return p
}

func (p *pool) Get() interface{} {
	p.mu.Lock()
	defer p.mu.Unlock()
	if p.l.Len() > 0 {
		return p.l.Remove(p.l.Front())
	} else {
		return p.genItem()
	}
}

func (p *pool) Put(v interface{}) {
	p.mu.Lock()
	defer p.mu.Unlock()
	p.l.PushFront(v)
}
<commit_msg>added Id struct<commit_after>// Copyright 2014 Rana Ian. All rights reserved.
// Use of this source code is governed by The MIT License
// found in the accompanying LICENSE file.

package ora

/*
#include <oci.h>
#include <stdlib.h>
#include <string.h>
*/
import "C"
import (
	"bytes"
	"container/list"
	"io"
	"io/ioutil"
	"math"
	"sync"
	"time"
)

// When a parent handle is freed, all child handles associated with it are also
// freed, and can no longer be used. For example, when a statement handle is freed,
// any bind and define handles associated with it are also freed.

// bnd represents an between a Go parameter and a sql statement placeholder and
// contains logic to transfer a Go type to an Oracle OCI type.
type bnd interface {
	// setPtr enables some bind types to set out-bound pointers for some types such as time.Time, etc.
	setPtr() error
	// close releases resources and resets fields.
	close() error
}

// def represents a select-list column definition containing logic to transfer
// an Oracle OCI type to a Go type.
type def interface {
	// value gets a Go value from an Oracle buffer.
	value() (interface{}, error)
	// alloc allocates an OCI descriptor.
	alloc() error
	// free releases an OCI descriptor.
	free()
	// close releases resources and resets fields.
	close() error
}

// Int64 is a nullable int64.
type Int64 struct {
	IsNull bool
	Value  int64
}

// Equals returns true when the receiver and specified Int64 are both null,
// or when the receiver and specified Int64 are both not null and Values are equal.
func (this Int64) Equals(other Int64) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Int32 is a nullable int32.
type Int32 struct {
	IsNull bool
	Value  int32
}

// Equals returns true when the receiver and specified Int32 are both null,
// or when the receiver and specified Int32 are both not null and Values are equal.
func (this Int32) Equals(other Int32) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Int16 is a nullable int16.
type Int16 struct {
	IsNull bool
	Value  int16
}

// Equals returns true when the receiver and specified Int16 are both null,
// or when the receiver and specified Int16 are both not null and Values are equal.
func (this Int16) Equals(other Int16) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Int8 is a nullable int8.
type Int8 struct {
	IsNull bool
	Value  int8
}

// Equals returns true when the receiver and specified Int8 are both null,
// or when the receiver and specified Int8 are both not null and Values are equal.
func (this Int8) Equals(other Int8) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Uint64 is a nullable uint64.
type Uint64 struct {
	IsNull bool
	Value  uint64
}

// Equals returns true when the receiver and specified Uint64 are both null,
// or when the receiver and specified Uint64 are both not null and Values are equal.
func (this Uint64) Equals(other Uint64) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Uint32 is a nullable uint32.
type Uint32 struct {
	IsNull bool
	Value  uint32
}

// Equals returns true when the receiver and specified Uint32 are both null,
// or when the receiver and specified Uint32 are both not null and Values are equal.
func (this Uint32) Equals(other Uint32) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Uint16 is a nullable uint16.
type Uint16 struct {
	IsNull bool
	Value  uint16
}

// Equals returns true when the receiver and specified Uint16 are both null,
// or when the receiver and specified Uint16 are both not null and Values are equal.
func (this Uint16) Equals(other Uint16) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Uint8 is a nullable uint8.
type Uint8 struct {
	IsNull bool
	Value  uint8
}

// Equals returns true when the receiver and specified Uint8 are both null,
// or when the receiver and specified Uint8 are both not null and Values are equal.
func (this Uint8) Equals(other Uint8) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Float64 is a nullable float64.
type Float64 struct {
	IsNull bool
	Value  float64
}

// Equals returns true when the receiver and specified Float64 are both null,
// or when the receiver and specified Float64 are both not null and Values are equal.
func (this Float64) Equals(other Float64) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Float32 is a nullable float32.
type Float32 struct {
	IsNull bool
	Value  float32
}

// Equals returns true when the receiver and specified Float32 are both null,
// or when the receiver and specified Float32 are both not null and Values are equal.
func (this Float32) Equals(other Float32) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Time is a nullable time.Time.
type Time struct {
	IsNull bool
	Value  time.Time
}

// Equals returns true when the receiver and specified Time are both null,
// or when the receiver and specified Time are both not null and Values are equal.
func (this Time) Equals(other Time) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value.Equal(other.Value))
}

// String is a nullable string.
type String struct {
	IsNull bool
	Value  string
}

// Equals returns true when the receiver and specified String are both null,
// or when the receiver and specified String are both not null and Values are equal.
func (this String) Equals(other String) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Bool is a nullable bool.
type Bool struct {
	IsNull bool
	Value  bool
}

// Equals returns true when the receiver and specified Bool are both null,
// or when the receiver and specified Bool are both not null and Values are equal.
func (this Bool) Equals(other Bool) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Value == other.Value)
}

// Raw represents a nullable byte slice for RAW or LONG RAW Oracle values.
type Raw struct {
	IsNull bool
	Value  []byte
}

// Equals returns true when the receiver and specified Raw are both null,
// or when the receiver and specified Raw are both not null and Values are equal.
func (this Raw) Equals(other Raw) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull &&
			bytes.Equal(this.Value, other.Value))
}

// Lob's Reader is sent to the DB on bind, if not nil.
// The Reader can read the LOB if we bind a *Lob, Closer will close the LOB.
type Lob struct {
	io.Reader
	io.Closer
}

func (this Lob) Close() error {
	if this.Closer != nil {
		return this.Closer.Close()
	}
	return nil
}

// Equals returns true when the receiver and specified Lob are both null,
// or when they both not null and share the same Reader.
func (this Lob) Equals(other Lob) bool {
	return this.Reader == other.Reader // this is a quite strict equality...
}

func (this Lob) Bytes() ([]byte, error) {
	if this.Reader == nil {
		return nil, io.EOF
	}
	return ioutil.ReadAll(this.Reader)
}

// Bfile represents a nullable BFILE Oracle value.
type Bfile struct {
	IsNull         bool
	DirectoryAlias string
	Filename       string
}

// Equals returns true when the receiver and specified Bfile are both null,
// or when the receiver and specified Bfile are both not null, DirectoryAlias are equal
// and Filename are equal.
func (this Bfile) Equals(other Bfile) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.DirectoryAlias == other.DirectoryAlias && this.Filename == other.Filename)
}

// IntervalYM represents a nullable INTERVAL YEAR TO MONTH Oracle value.
type IntervalYM struct {
	IsNull bool
	Year   int32
	Month  int32
}

// Equals returns true when the receiver and specified IntervalYM are both null,
// or when the receiver and specified IntervalYM are both not null, Year are equal
// and Month are equal.
func (this IntervalYM) Equals(other IntervalYM) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull && this.Year == other.Year && this.Month == other.Month)
}

// ShiftTime returns a new Time with IntervalYM applied.
func (this IntervalYM) ShiftTime(t time.Time) time.Time {
	return t.AddDate(int(this.Year), int(this.Month), 0)
}

// IntervalDS represents a nullable INTERVAL DAY TO SECOND Oracle value.
type IntervalDS struct {
	IsNull     bool
	Day        int32
	Hour       int32
	Minute     int32
	Second     int32
	Nanosecond int32
}

// Equals returns true when the receiver and specified IntervalDS are both null,
// or when the receiver and specified IntervalDS are both not null, and all other
// fields are equal.
func (this IntervalDS) Equals(other IntervalDS) bool {
	return (this.IsNull && other.IsNull) ||
		(this.IsNull == other.IsNull &&
			this.Day == other.Day &&
			this.Hour == other.Hour &&
			this.Minute == other.Minute &&
			this.Second == other.Second &&
			this.Nanosecond == other.Nanosecond)
}

// ShiftTime returns a new Time with IntervalDS applied.
func (this IntervalDS) ShiftTime(t time.Time) time.Time {
	year, month, day := t.Date()
	hour, min, sec := t.Clock()
	return time.Date(year, month, day+int(this.Day), hour+int(this.Hour), min+int(this.Minute), sec+int(this.Second), t.Nanosecond()+int(this.Nanosecond), t.Location())
}

// MultiErr holds multiple errors in a single string.
type MultiErr struct {
	str string
}

// Error returns one or more errors.
//
// Error is a member of the 'error' interface.
func (m MultiErr) Error() string {
	return m.str
}

// newMultiErr returns a MultiErr or nil.
// It is valid to pass nil errors to newMultiErr.
// Nil errors will be filtered out. If all errors
// are nil newMultiError will return nil.
func newMultiErr(errs ...error) *MultiErr {
	var buf bytes.Buffer
	for _, err := range errs {
		if err != nil {
			buf.WriteString(err.Error())
			buf.WriteString(", ")
		}
	}
	if buf.Len() > 0 {
		return &MultiErr{str: buf.String()}
	} else {
		return nil
	}
}

// newMultiErrL returns a MultiErr or nil.
// It is valid to pass nil errors to newMultiErr.
// Nil errors will be filtered out. If all errors
// are nil newMultiError will return nil.
func newMultiErrL(errs *list.List) *MultiErr {
	var buf bytes.Buffer
	for e := errs.Front(); e != nil; e = e.Next() {
		if e.Value != nil {
			err := e.Value.(error)
			buf.WriteString(err.Error())
			buf.WriteString(", ")
		}
	}
	if buf.Len() > 0 {
		return &MultiErr{str: buf.String()}
	} else {
		return nil
	}
}

// prefer simple pool instead of sync.Pool to control lifetime of instances
// sync.Pool eliminates instances at its own discretion
// would prefer to maintain instances indefinitely; or, eventually clean on a long timer
type pool struct {
	l       *list.List
	mu      sync.Mutex
	genItem func() interface{}
}

func newPool(genItem func() interface{}) *pool {
	p := &pool{}
	p.l = list.New()
	p.genItem = genItem
	return p
}

func (p *pool) Get() interface{} {
	p.mu.Lock()
	defer p.mu.Unlock()
	if p.l.Len() > 0 {
		return p.l.Remove(p.l.Front())
	} else {
		return p.genItem()
	}
}

func (p *pool) Put(v interface{}) {
	p.mu.Lock()
	defer p.mu.Unlock()
	p.l.PushFront(v)
}

type Id struct {
	val uint64
	mu  sync.Mutex
}

func (id *Id) nextId() (result uint64) {
	id.mu.Lock()
	defer id.mu.Unlock()
	if id.val == math.MaxUint64 {
		id.val = 1
	} else {
		id.val++
	}
	return id.val
}
<|endoftext|>