<commit_before>// Copyright 2012 Google, Inc. All rights reserved.
// Copyright 2009-2011 Andreas Krennmair. All rights reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree.

package layers

import (
	"fmt"
	"github.com/google/gopacket"
)

// Checksum computation for TCP/UDP.
type tcpipchecksum struct {
	pseudoheader tcpipPseudoHeader
}

type tcpipPseudoHeader interface {
	pseudoheaderChecksum() uint32
}

func (ip *IPv4) pseudoheaderChecksum() (csum uint32) {
	csum += (uint32(ip.SrcIP[0]) + uint32(ip.SrcIP[2])) << 8
	csum += uint32(ip.SrcIP[1]) + uint32(ip.SrcIP[3])
	csum += (uint32(ip.DstIP[0]) + uint32(ip.DstIP[2])) << 8
	csum += uint32(ip.DstIP[1]) + uint32(ip.DstIP[3])
	return
}

func (ip *IPv6) pseudoheaderChecksum() (csum uint32) {
	for i := 0; i < 16; i += 2 {
		csum += uint32(ip.SrcIP[i]) << 8
		csum += uint32(ip.SrcIP[i+1])
		csum += uint32(ip.DstIP[i]) << 8
		csum += uint32(ip.DstIP[i+1])
	}
	return
}

// Calculate the TCP/IP checksum defined in rfc1071.  The passed-in csum is any
// initial checksum data that's already been computed.
func tcpipChecksum(data []byte, csum uint32) uint16 {
	// to handle odd lengths, we loop to length - 1, incrementing by 2, then
	// handle the last byte specifically by checking against the original
	// length.
	length := len(data) - 1
	for i := 0; i < length; i += 2 {
		// For our test packet, doing this manually is about 25% faster
		// (740 ns vs. 1000ns) than doing it by calling binary.BigEndian.Uint16.
		csum += uint32(data[i]) << 8
		csum += uint32(data[i+1])
	}
	if len(data)%2 == 1 {
		csum += uint32(data[length]) << 8
	}
	for csum > 0xffff {
		csum = (csum >> 16) + (csum & 0xffff)
	}
	return ^uint16(csum + (csum >> 16))
}

// computeChecksum computes a TCP or UDP checksum.  headerAndPayload is the
// serialized TCP or UDP header plus its payload, with the checksum zero'd
// out. headerProtocol is the IP protocol number of the upper-layer header.
func (c *tcpipchecksum) computeChecksum(headerAndPayload []byte, headerProtocol IPProtocol) (uint16, error) {
	if c.pseudoheader == nil {
		return 0, fmt.Errorf("TCP/IP layer 4 checksum cannot be computed without network layer... call SetNetworkLayerForChecksum to set which layer to use")
	}
	length := uint32(len(headerAndPayload))
	csum := c.pseudoheader.pseudoheaderChecksum()
	csum += uint32(headerProtocol)
	csum += length & 0xffff
	csum += length >> 16
	return tcpipChecksum(headerAndPayload, csum), nil
}

// SetNetworkLayerForChecksum tells this layer which network layer is wrapping it.
// This is needed for computing the checksum when serializing, since TCP/IP transport
// layer checksums depends on fields in the IPv4 or IPv6 layer that contains it.
// The passed in layer must be an *IPv4 or *IPv6.
func (i *tcpipchecksum) SetNetworkLayerForChecksum(l gopacket.NetworkLayer) error {
	switch v := l.(type) {
	case *IPv4:
		i.pseudoheader = v
	case *IPv6:
		i.pseudoheader = v
	default:
		return fmt.Errorf("cannot use layer type %v for tcp checksum network layer", l.LayerType())
	}
	return nil
}
<commit_msg>Fix out of range error in pseudo-header checksum for invalid addresses<commit_after>// Copyright 2012 Google, Inc. All rights reserved.
// Copyright 2009-2011 Andreas Krennmair. All rights reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree.

package layers

import (
	"fmt"
	"github.com/google/gopacket"
)

// Checksum computation for TCP/UDP.
type tcpipchecksum struct {
	pseudoheader tcpipPseudoHeader
}

type tcpipPseudoHeader interface {
	pseudoheaderChecksum() (uint32, error)
}

func (ip *IPv4) pseudoheaderChecksum() (csum uint32, err error) {
	if len(ip.SrcIP) != 4 {
		return 0, fmt.Errorf("invalid src IP %v", ip.SrcIP)
	}
	if len(ip.DstIP) != 4 {
		return 0, fmt.Errorf("invalid dst IP %v", ip.DstIP)
	}
	csum += (uint32(ip.SrcIP[0]) + uint32(ip.SrcIP[2])) << 8
	csum += uint32(ip.SrcIP[1]) + uint32(ip.SrcIP[3])
	csum += (uint32(ip.DstIP[0]) + uint32(ip.DstIP[2])) << 8
	csum += uint32(ip.DstIP[1]) + uint32(ip.DstIP[3])
	return csum, nil
}

func (ip *IPv6) pseudoheaderChecksum() (csum uint32, err error) {
	if len(ip.SrcIP) != 16 {
		return 0, fmt.Errorf("invalid src IP %v", ip.SrcIP)
	}
	if len(ip.DstIP) != 16 {
		return 0, fmt.Errorf("invalid dst IP %v", ip.DstIP)
	}
	for i := 0; i < 16; i += 2 {
		csum += uint32(ip.SrcIP[i]) << 8
		csum += uint32(ip.SrcIP[i+1])
		csum += uint32(ip.DstIP[i]) << 8
		csum += uint32(ip.DstIP[i+1])
	}
	return csum, nil
}

// Calculate the TCP/IP checksum defined in rfc1071.  The passed-in csum is any
// initial checksum data that's already been computed.
func tcpipChecksum(data []byte, csum uint32) uint16 {
	// to handle odd lengths, we loop to length - 1, incrementing by 2, then
	// handle the last byte specifically by checking against the original
	// length.
	length := len(data) - 1
	for i := 0; i < length; i += 2 {
		// For our test packet, doing this manually is about 25% faster
		// (740 ns vs. 1000ns) than doing it by calling binary.BigEndian.Uint16.
		csum += uint32(data[i]) << 8
		csum += uint32(data[i+1])
	}
	if len(data)%2 == 1 {
		csum += uint32(data[length]) << 8
	}
	for csum > 0xffff {
		csum = (csum >> 16) + (csum & 0xffff)
	}
	return ^uint16(csum + (csum >> 16))
}

// computeChecksum computes a TCP or UDP checksum.  headerAndPayload is the
// serialized TCP or UDP header plus its payload, with the checksum zero'd
// out. headerProtocol is the IP protocol number of the upper-layer header.
func (c *tcpipchecksum) computeChecksum(headerAndPayload []byte, headerProtocol IPProtocol) (uint16, error) {
	if c.pseudoheader == nil {
		return 0, fmt.Errorf("TCP/IP layer 4 checksum cannot be computed without network layer... call SetNetworkLayerForChecksum to set which layer to use")
	}
	length := uint32(len(headerAndPayload))
	csum, err := c.pseudoheader.pseudoheaderChecksum()
	if err != nil {
		return 0, err
	}
	csum += uint32(headerProtocol)
	csum += length & 0xffff
	csum += length >> 16
	return tcpipChecksum(headerAndPayload, csum), nil
}

// SetNetworkLayerForChecksum tells this layer which network layer is wrapping it.
// This is needed for computing the checksum when serializing, since TCP/IP transport
// layer checksums depends on fields in the IPv4 or IPv6 layer that contains it.
// The passed in layer must be an *IPv4 or *IPv6.
func (i *tcpipchecksum) SetNetworkLayerForChecksum(l gopacket.NetworkLayer) error {
	switch v := l.(type) {
	case *IPv4:
		i.pseudoheader = v
	case *IPv6:
		i.pseudoheader = v
	default:
		return fmt.Errorf("cannot use layer type %v for tcp checksum network layer", l.LayerType())
	}
	return nil
}
<|endoftext|>


<commit_before>// Copyright 2013 Matthew Baird
// 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 elastigo

import (
	"encoding/json"
	"fmt"
)

// MGet allows the caller to get multiple documents based on an index, type (optional) and id (and possibly routing).
// The response includes a docs array with all the fetched documents, each element similar in structure to a document
// provided by the get API.
// see http://www.elasticsearch.org/guide/reference/api/multi-get.html
func (c *Conn) MGet(index string, _type string, mgetRequest MGetRequestContainer, args map[string]interface{}) (MGetResponseContainer, error) {
	var url string
	var retval MGetResponseContainer
	if len(index) <= 0 {
		url = fmt.Sprintf("/_mget")
	}
	if len(_type) > 0 && len(index) > 0 {
		url = fmt.Sprintf("/%s/%s/_mget", index, _type)
	} else if len(index) > 0 {
		url = fmt.Sprintf("/%s/_mget", index)
	}
	body, err := c.DoCommand("GET", url, args, mgetRequest)
	if err != nil {
		return retval, err
	}
	if err == nil {
		// marshall into json
		jsonErr := json.Unmarshal(body, &retval)
		if jsonErr != nil {
			return retval, jsonErr
		}
	}
	return retval, err
}

type MGetRequestContainer struct {
	Docs []MGetRequest `json:"docs"`
}

type MGetRequest struct {
	Index  string   `json:"_index"`
	Type   string   `json:"_type"`
	ID     string   `json:"_id"`
	IDS    []string `json:"_ids,omitempty"`
	Fields []string `json:"fields,omitempty"`
}

type MGetResponseContainer struct {
	Docs []BaseResponse `json:"docs"`
}
<commit_msg>Add method for mget with only ids and updated doc<commit_after>// Copyright 2013 Matthew Baird
// 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 elastigo

import (
	"encoding/json"
	"fmt"
)

// MGet allows the caller to get multiple documents based on an index, type (optional) and id (and possibly routing).
// The response includes a docs array with all the fetched documents, each element similar in structure to a document
// provided by the get API.
// see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-multi-get.html
/*
{
  "docs" : [
    {
      "_type" : "type",
      "_id" : "1"
    },
    {
      "_type" : "type",
      "_id" : "2"
    }
  ]
}
*/
func (c *Conn) MGet(index string, _type string, mgetRequest MGetRequestContainer, args map[string]interface{}) (MGetResponseContainer, error) {
	body, err := c.DoCommand("GET", mGetUrl(index, _type), args, mgetRequest)
	return mGetHandleResponse(body, err)
}

// MGetShort allows to get multiple documents based on an index, type (optional) and id (and possibly routing).
// The response includes a docs array with all the fetched documents, each element similar in structure to a document
// provided by the get API.
// see https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-multi-get.html
/*
{
	"ids": ["1", "2", "3"]
}
*/

func (c *Conn) MGetShort(index string, _type string, mgetRequestShort MGetRequestShort, args map[string]interface{}) (MGetResponseContainer, error) {
	body, err := c.DoCommand("GET", mGetUrl(index, _type), args, mgetRequestShort)
	return mGetHandleResponse(body, err)
}

func mGetHandleResponse (responseBody []byte, err error) (MGetResponseContainer, error) {
	var retval MGetResponseContainer
	if err != nil {
		return retval, err
	}
	if err == nil {
		// marshall into json
		jsonErr := json.Unmarshal(responseBody, &retval)
		if jsonErr != nil {
			return retval, jsonErr
		}
	}
	return retval, err
}

func mGetUrl(index string, _type string) string {
	var url string
	if len(index) <= 0 {
		url = fmt.Sprintf("/_mget")
	}
	if len(_type) > 0 && len(index) > 0 {
		url = fmt.Sprintf("/%s/%s/_mget", index, _type)
	} else if len(index) > 0 {
		url = fmt.Sprintf("/%s/_mget", index)
	}
	return url
}

type MGetRequestContainer struct {
	Docs []MGetRequest `json:"docs"`
}

type MGetRequest struct {
	Index  string   `json:"_index,omitempty"`
	Type   string   `json:"_type,omitempty"`
	ID     string   `json:"_id"`
	Fields []string `json:"fields,omitempty"`
}

type MGetRequestShort struct {
	IDS    []string `json:"ids"`
}

type MGetResponseContainer struct {
	Docs []BaseResponse `json:"docs"`
}
<|endoftext|>


<commit_before>// package shell implements a remote API interface for a running ipfs daemon
package shell

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"

	cmds "github.com/ipfs/go-ipfs/commands"
	files "github.com/ipfs/go-ipfs/commands/files"
	http "github.com/ipfs/go-ipfs/commands/http"
	cc "github.com/ipfs/go-ipfs/core/commands"
)

type Shell struct {
	client http.Client
}

func NewShell(url string) *Shell {
	return &Shell{http.NewClient(url)}
}

// Cat the content at the given path
func (s *Shell) Cat(path string) (io.Reader, error) {
	ropts, err := cc.Root.GetOptions([]string{"cat"})
	if err != nil {
		return nil, err
	}

	req, err := cmds.NewRequest([]string{"cat", path}, nil, nil, nil, cc.CatCmd, ropts)
	if err != nil {
		return nil, err
	}

	resp, err := s.client.Send(req)
	if err != nil {
		return nil, err
	}

	return resp.Reader()
}

// Add a file to ipfs from the given reader, returns the hash of the added file
func (s *Shell) Add(r io.Reader) (string, error) {
	ropts, err := cc.Root.GetOptions([]string{"add"})
	if err != nil {
		return "", err
	}

	slf := files.NewSliceFile("", []files.File{files.NewReaderFile("", ioutil.NopCloser(r), nil)})

	req, err := cmds.NewRequest([]string{"add"}, nil, nil, slf, cc.AddCmd, ropts)
	if err != nil {
		return "", err
	}

	resp, err := s.client.Send(req)
	if err != nil {
		return "", err
	}
	if resp.Error() != nil {
		return "", resp.Error()
	}

	read, err := resp.Reader()
	if err != nil {
		return "", err
	}

	dec := json.NewDecoder(read)
	out := struct{ Hash string }{}
	err = dec.Decode(&out)
	if err != nil {
		return "", err
	}

	return out.Hash, nil
}

// List entries at the given path
func (s *Shell) List(path string) ([]cc.Link, error) {
	ropts, err := cc.Root.GetOptions([]string{"ls"})
	if err != nil {
		return nil, err
	}

	req, err := cmds.NewRequest([]string{"ls", path}, nil, nil, nil, cc.LsCmd, ropts)
	if err != nil {
		return nil, err
	}

	resp, err := s.client.Send(req)
	if err != nil {
		return nil, err
	}

	if resp.Error() != nil {
		return nil, resp.Error()
	}

	read, err := resp.Reader()
	if err != nil {
		return nil, err
	}

	dec := json.NewDecoder(read)
	out := struct{ Objects []cc.Object }{}
	err = dec.Decode(&out)
	if err != nil {
		return nil, err
	}

	return out.Objects[0].Links, nil
}

// Pin the given path
func (s *Shell) Pin(path string) error {
	ropts, err := cc.Root.GetOptions([]string{"pin", "add"})
	if err != nil {
		return err
	}
	pinadd := cc.PinCmd.Subcommands["add"]

	req, err := cmds.NewRequest([]string{"pin", "add", path}, nil, nil, nil, pinadd, ropts)
	if err != nil {
		return err
	}
	req.SetOption("r", true)

	resp, err := s.client.Send(req)
	if err != nil {
		return err
	}
	if resp.Error() != nil {
		return resp.Error()
	}

	read, err := resp.Reader()
	if err != nil {
		return err
	}

	out, err := ioutil.ReadAll(read)
	if err != nil {
		return err
	}

	fmt.Println(string(out))
	return nil
}

func (s *Shell) FindPeer(peer string) error {
	ropts, err := cc.Root.GetOptions([]string{"dht", "findpeer"})
	if err != nil {
		return err
	}
	fpeer := cc.DhtCmd.Subcommands["findpeer"]

	req, err := cmds.NewRequest([]string{"dht", "findpeer", peer}, nil, nil, nil, fpeer, ropts)
	if err != nil {
		return err
	}

	resp, err := s.client.Send(req)
	if err != nil {
		return err
	}
	if resp.Error() != nil {
		return resp.Error()
	}

	read, err := resp.Reader()
	if err != nil {
		return err
	}

	out, err := ioutil.ReadAll(read)
	if err != nil {
		return err
	}

	fmt.Println(string(out))
	return nil
}
<commit_msg>fix find peer<commit_after>// package shell implements a remote API interface for a running ipfs daemon
package shell

import (
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"

	cmds "github.com/ipfs/go-ipfs/commands"
	files "github.com/ipfs/go-ipfs/commands/files"
	http "github.com/ipfs/go-ipfs/commands/http"
	cc "github.com/ipfs/go-ipfs/core/commands"
)

type Shell struct {
	client http.Client
}

func NewShell(url string) *Shell {
	return &Shell{http.NewClient(url)}
}

// Cat the content at the given path
func (s *Shell) Cat(path string) (io.Reader, error) {
	ropts, err := cc.Root.GetOptions([]string{"cat"})
	if err != nil {
		return nil, err
	}

	req, err := cmds.NewRequest([]string{"cat", path}, nil, nil, nil, cc.CatCmd, ropts)
	if err != nil {
		return nil, err
	}

	resp, err := s.client.Send(req)
	if err != nil {
		return nil, err
	}

	return resp.Reader()
}

// Add a file to ipfs from the given reader, returns the hash of the added file
func (s *Shell) Add(r io.Reader) (string, error) {
	ropts, err := cc.Root.GetOptions([]string{"add"})
	if err != nil {
		return "", err
	}

	slf := files.NewSliceFile("", []files.File{files.NewReaderFile("", ioutil.NopCloser(r), nil)})

	req, err := cmds.NewRequest([]string{"add"}, nil, nil, slf, cc.AddCmd, ropts)
	if err != nil {
		return "", err
	}

	resp, err := s.client.Send(req)
	if err != nil {
		return "", err
	}
	if resp.Error() != nil {
		return "", resp.Error()
	}

	read, err := resp.Reader()
	if err != nil {
		return "", err
	}

	dec := json.NewDecoder(read)
	out := struct{ Hash string }{}
	err = dec.Decode(&out)
	if err != nil {
		return "", err
	}

	return out.Hash, nil
}

// List entries at the given path
func (s *Shell) List(path string) ([]cc.Link, error) {
	ropts, err := cc.Root.GetOptions([]string{"ls"})
	if err != nil {
		return nil, err
	}

	req, err := cmds.NewRequest([]string{"ls", path}, nil, nil, nil, cc.LsCmd, ropts)
	if err != nil {
		return nil, err
	}

	resp, err := s.client.Send(req)
	if err != nil {
		return nil, err
	}

	if resp.Error() != nil {
		return nil, resp.Error()
	}

	read, err := resp.Reader()
	if err != nil {
		return nil, err
	}

	dec := json.NewDecoder(read)
	out := struct{ Objects []cc.Object }{}
	err = dec.Decode(&out)
	if err != nil {
		return nil, err
	}

	return out.Objects[0].Links, nil
}

// Pin the given path
func (s *Shell) Pin(path string) error {
	ropts, err := cc.Root.GetOptions([]string{"pin", "add"})
	if err != nil {
		return err
	}
	pinadd := cc.PinCmd.Subcommands["add"]

	req, err := cmds.NewRequest([]string{"pin", "add", path}, nil, nil, nil, pinadd, ropts)
	if err != nil {
		return err
	}
	req.SetOption("r", true)

	resp, err := s.client.Send(req)
	if err != nil {
		return err
	}
	if resp.Error() != nil {
		return resp.Error()
	}

	read, err := resp.Reader()
	if err != nil {
		return err
	}

	out, err := ioutil.ReadAll(read)
	if err != nil {
		return err
	}

	fmt.Println(string(out))
	return nil
}

type PeerInfo struct {
	Addrs []string
	ID    string
}

func (s *Shell) FindPeer(peer string) (*PeerInfo, error) {
	ropts, err := cc.Root.GetOptions([]string{"dht", "findpeer"})
	if err != nil {
		return nil, err
	}
	fpeer := cc.DhtCmd.Subcommands["findpeer"]

	req, err := cmds.NewRequest([]string{"dht", "findpeer", peer}, nil, nil, nil, fpeer, ropts)
	if err != nil {
		return nil, err
	}

	resp, err := s.client.Send(req)
	if err != nil {
		return nil, err
	}
	if resp.Error() != nil {
		return nil, resp.Error()
	}

	read, err := resp.Reader()
	if err != nil {
		return nil, err
	}

	str := struct {
		Responses []PeerInfo
	}{}
	err = json.NewDecoder(read).Decode(&str)
	if err != nil {
		return nil, err
	}

	return &str.Responses[0], nil
}
<|endoftext|>


<commit_before>// Copyright 2014 Arne Roomann-Kurrik
//
// 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 twodee

import (
	"fmt"
	"github.com/kurrik/Go-SDL/mixer"
	"github.com/kurrik/Go-SDL/sdl"
)

func initSound() error {
	if code := sdl.Init(sdl.INIT_AUDIO); code == -1 {
		return fmt.Errorf("Could not init audio: %v", sdl.GetError())
	}
	var (
		freq     int    = mixer.DEFAULT_FREQUENCY
		format   uint16 = mixer.DEFAULT_FORMAT
		channels int    = mixer.DEFAULT_CHANNELS
	)
	if mixer.OpenAudio(freq, format, channels, 4096) != 0 {
		return fmt.Errorf("Could not init mixer: %v", sdl.GetError())
	}
	return nil
}

func cleanupSound() {
	mixer.CloseAudio()
	sdl.QuitSubSystem(sdl.INIT_AUDIO)
}

type Audio struct {
	music *mixer.Music
}

func NewAudio(path string) (a *Audio, err error) {
	a = &Audio{
		music: mixer.LoadMUS(path),
	}
	if a.music == nil {
		err = fmt.Errorf("Could not load audio: %v", sdl.GetError())
	}
	return
}

func (a *Audio) Delete() {
	a.music.Free()
}

func (a *Audio) Play(times int) {
	a.music.PlayMusic(times)
}
<commit_msg>Added pause and resume functions for music<commit_after>// Copyright 2014 Arne Roomann-Kurrik
//
// 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 twodee

import (
	"fmt"
	"github.com/kurrik/Go-SDL/mixer"
	"github.com/kurrik/Go-SDL/sdl"
)

func initSound() error {
	if code := sdl.Init(sdl.INIT_AUDIO); code == -1 {
		return fmt.Errorf("Could not init audio: %v", sdl.GetError())
	}
	var (
		freq     int    = mixer.DEFAULT_FREQUENCY
		format   uint16 = mixer.DEFAULT_FORMAT
		channels int    = mixer.DEFAULT_CHANNELS
	)
	if mixer.OpenAudio(freq, format, channels, 4096) != 0 {
		return fmt.Errorf("Could not init mixer: %v", sdl.GetError())
	}
	return nil
}

func cleanupSound() {
	mixer.CloseAudio()
	sdl.QuitSubSystem(sdl.INIT_AUDIO)
}

func Pause() {
	mixer.PauseMusic()
}

func Resume() {
	mixer.ResumeMusic()
}

type Audio struct {
	music *mixer.Music
}

func NewAudio(path string) (a *Audio, err error) {
	a = &Audio{
		music: mixer.LoadMUS(path),
	}
	if a.music == nil {
		err = fmt.Errorf("Could not load audio: %v", sdl.GetError())
	}
	return
}

func (a *Audio) Delete() {
	a.music.Free()
}

func (a *Audio) Play(times int) {
	a.music.PlayMusic(times)
}

<|endoftext|>


<commit_before>package cp

// #cgo CFLAGS: -DNDEBUG
// #define CP_USE_CGTYPES 0
// #include "chipmunk/chipmunk.h"
import "C"

type Space struct {
	ptr *C.cpSpace
}

func NewSpace() *Space {
	space := new(Space)
	space.ptr = C.cpSpaceNew()
	return space
}

func (s *Space) GetGravity() (float64, float64) {
	vect := C.cpSpaceGetGravity(s.ptr)
	return float64(vect.x), float64(vect.y)
}

func (s *Space) SetGravity(x float64, y float64) {
	C.cpSpaceSetGravity(s.ptr, C.cpVect{C.cpFloat(x), C.cpFloat(y)})
}
<commit_msg>use -std=gnu99 for linux support<commit_after>package cp

// #cgo CFLAGS: -DNDEBUG -std=gnu99
// #define CP_USE_CGTYPES 0
// #include "chipmunk/chipmunk.h"
import "C"

type Space struct {
	ptr *C.cpSpace
}

func NewSpace() *Space {
	space := new(Space)
	space.ptr = C.cpSpaceNew()
	return space
}

func (s *Space) GetGravity() (float64, float64) {
	vect := C.cpSpaceGetGravity(s.ptr)
	return float64(vect.x), float64(vect.y)
}

func (s *Space) SetGravity(x float64, y float64) {
	C.cpSpaceSetGravity(s.ptr, C.cpVect{C.cpFloat(x), C.cpFloat(y)})
}
<|endoftext|>


<commit_before>package main

type stack struct {
	data []int
}

func (s stack) hasAtLeast1() bool {
	return len(s.data) >= 1
}

func (s stack) hasAtLeast2() bool {
	return len(s.data) >= 2
}

func (s *stack) push(n int) {
	s.data = append(s.data, n)
}

func (s *stack) pop() (n int) {
	if s.hasAtLeast1() {
		n, s.data = s.data[len(s.data)-1], s.data[0:len(s.data)-1]
	}
	return
}

func (s *stack) add() {
	if s.hasAtLeast2() {
		x, y := s.pop(), s.pop()
		s.push(x + y)
	}
}

func (s *stack) subtract() {
	if s.hasAtLeast2() {
		top, second := s.pop(), s.pop()
		s.push(second - top)
	}
}

func (s *stack) multiply() {
	if s.hasAtLeast2() {
		x, y := s.pop(), s.pop()
		s.push(x * y)
	}
}

func (s *stack) divide() {
	if !s.hasAtLeast2() {
		return
	}
	top, second := s.pop(), s.pop()
	if top == 0 {
		// Put them back so this becomes a no-op.
		s.push(second)
		s.push(top)
	} else {
		s.push(second / top)
	}
}

func (s *stack) mod() {
	if !s.hasAtLeast2() {
		return
	}
	top, second := s.pop(), s.pop()
	if top != 0 {
		// Put them back so this becomes a no-op.
		s.push(second)
		s.push(top)
	}
	s.push(second % top)
}

func (s *stack) not() {
	if s.hasAtLeast1() {
		top := s.pop()
		if top == 0 {
			s.push(1)
		} else {
			s.push(0)
		}
	}
}

func (s *stack) greater() {
	if s.hasAtLeast2() {
		top, second := s.pop(), s.pop()
		if second > top {
			s.push(1)
		} else {
			s.push(0)
		}
	}
}

func (s *stack) duplicate() {
	if s.hasAtLeast1() {
		top := s.data[len(s.data)-1]
		s.data = append(s.data, top)
	}
}

func (s *stack) roll() {
	numRolls, depth := s.pop(), s.pop()
	_, _ = numRolls, depth
	panic("Not implemented")
}
<commit_msg>implement roll()<commit_after>package main

type stack struct {
	data []int
}

func (s stack) hasAtLeast1() bool {
	return len(s.data) >= 1
}

func (s stack) hasAtLeast2() bool {
	return len(s.data) >= 2
}

func (s *stack) push(n int) {
	s.data = append(s.data, n)
}

func (s *stack) pop() (n int) {
	if s.hasAtLeast1() {
		n, s.data = s.data[len(s.data)-1], s.data[0:len(s.data)-1]
	}
	return
}

func (s *stack) add() {
	if s.hasAtLeast2() {
		x, y := s.pop(), s.pop()
		s.push(x + y)
	}
}

func (s *stack) subtract() {
	if s.hasAtLeast2() {
		top, second := s.pop(), s.pop()
		s.push(second - top)
	}
}

func (s *stack) multiply() {
	if s.hasAtLeast2() {
		x, y := s.pop(), s.pop()
		s.push(x * y)
	}
}

func (s *stack) divide() {
	if !s.hasAtLeast2() {
		return
	}
	top, second := s.pop(), s.pop()
	if top == 0 {
		// Put them back so this becomes a no-op.
		s.push(second)
		s.push(top)
	} else {
		s.push(second / top)
	}
}

func (s *stack) mod() {
	if !s.hasAtLeast2() {
		return
	}
	top, second := s.pop(), s.pop()
	if top != 0 {
		// Put them back so this becomes a no-op.
		s.push(second)
		s.push(top)
	}
	s.push(second % top)
}

func (s *stack) not() {
	if s.hasAtLeast1() {
		top := s.pop()
		if top == 0 {
			s.push(1)
		} else {
			s.push(0)
		}
	}
}

func (s *stack) greater() {
	if s.hasAtLeast2() {
		top, second := s.pop(), s.pop()
		if second > top {
			s.push(1)
		} else {
			s.push(0)
		}
	}
}

func (s *stack) duplicate() {
	if s.hasAtLeast1() {
		top := s.data[len(s.data)-1]
		s.data = append(s.data, top)
	}
}

func (s *stack) roll() {
	if !s.hasAtLeast2() {
		return
	}

	numRolls, depth := s.pop(), s.pop()
	if depth < 0 || depth > len(s.data) {
		// Undo.
		s.push(depth)
		s.push(numRolls)
		return
	}

	for i := 0; i < numRolls; i++ {
		index := len(s.data) - depth
		val := s.pop()
		s1, s2 := s.data[0:index], s.data[index:]
		s.data = append(append(s1, val), s2...)
	}
}
<|endoftext|>


<commit_before>// Discordgo - Discord bindings for Go
// Available at https://github.com/bwmarrin/discordgo

// Copyright 2015-2016 Bruce Marriner <bruce@sqls.net>.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file contains code related to state tracking.  If enabled, state
// tracking will capture the initial READY packet and many other websocket
// events and maintain an in-memory state of of guilds, channels, users, and
// so forth.  This information can be accessed through the Session.State struct.

package discordgo

import (
	"errors"
	"fmt"
)

// ErrNilState is returned when the state is nil.
var ErrNilState = errors.New("State not instantiated, please use discordgo.New() or assign Session.State.")

// NewState creates an empty state.
func NewState() *State {
	return &State{
		Ready: Ready{
			PrivateChannels: []*Channel{},
			Guilds:          []*Guild{},
		},
	}
}

// OnReady takes a Ready event and updates all internal state.
func (s *State) OnReady(r *Ready) error {
	if s == nil {
		return ErrNilState
	}

	s.Lock()
	defer s.Unlock()

	s.Ready = *r
	return nil
}

// GuildAdd adds a guild to the current world state, or
// updates it if it already exists.
func (s *State) GuildAdd(guild *Guild) error {
	if s == nil {
		return ErrNilState
	}

	s.Lock()
	defer s.Unlock()

	// If the guild exists, replace it.
	for i, g := range s.Guilds {
		if g.ID == guild.ID {
			// Don't stomp on properties that don't come in updates.
			guild.Members = g.Members
			guild.Presences = g.Presences
			guild.Channels = g.Channels
			guild.VoiceStates = g.VoiceStates
			s.Guilds[i] = guild
			return nil
		}
	}

	s.Guilds = append(s.Guilds, guild)
	return nil
}

// GuildRemove removes a guild from current world state.
func (s *State) GuildRemove(guild *Guild) error {
	if s == nil {
		return ErrNilState
	}

	s.Lock()
	defer s.Unlock()

	for i, g := range s.Guilds {
		if g.ID == guild.ID {
			s.Guilds = append(s.Guilds[:i], s.Guilds[i+1:]...)
			return nil
		}
	}

	return errors.New("Guild not found.")
}

// Guild gets a guild by ID.
// Useful for querying if @me is in a guild:
//     _, err := discordgo.Session.State.Guild(guildID)
//     isInGuild := err == nil
func (s *State) Guild(guildID string) (*Guild, error) {
	if s == nil {
		return nil, ErrNilState
	}

	s.RLock()
	defer s.RUnlock()

	for _, g := range s.Guilds {
		if g.ID == guildID {
			return g, nil
		}
	}

	return nil, errors.New("Guild not found.")
}

// TODO: Consider moving Guild state update methods onto *Guild.

// MemberAdd adds a member to the current world state, or
// updates it if it already exists.
func (s *State) MemberAdd(member *Member) error {
	if s == nil {
		return ErrNilState
	}

	guild, err := s.Guild(member.GuildID)
	if err != nil {
		return err
	}

	s.Lock()
	defer s.Unlock()

	for i, m := range guild.Members {
		if m.User.ID == member.User.ID {
			guild.Members[i] = member
			return nil
		}
	}

	guild.Members = append(guild.Members, member)
	return nil
}

// MemberRemove removes a member from current world state.
func (s *State) MemberRemove(member *Member) error {
	if s == nil {
		return ErrNilState
	}

	guild, err := s.Guild(member.GuildID)
	if err != nil {
		return err
	}

	s.Lock()
	defer s.Unlock()

	for i, m := range guild.Members {
		if m.User.ID == member.User.ID {
			guild.Members = append(guild.Members[:i], guild.Members[i+1:]...)
			return nil
		}
	}

	return errors.New("Member not found.")
}

// Member gets a member by ID from a guild.
func (s *State) Member(guildID, userID string) (*Member, error) {
	if s == nil {
		return nil, ErrNilState
	}

	guild, err := s.Guild(guildID)
	if err != nil {
		return nil, err
	}

	s.RLock()
	defer s.RUnlock()

	for _, m := range guild.Members {
		if m.User.ID == userID {
			return m, nil
		}
	}

	return nil, errors.New("Member not found.")
}

// ChannelAdd adds a guild to the current world state, or
// updates it if it already exists.
// Channels may exist either as PrivateChannels or inside
// a guild.
func (s *State) ChannelAdd(channel *Channel) error {
	if s == nil {
		return ErrNilState
	}

	if channel.IsPrivate {
		s.Lock()
		defer s.Unlock()

		// If the channel exists, replace it.
		for i, c := range s.PrivateChannels {
			if c.ID == channel.ID {
				// Don't stomp on messages.
				channel.Messages = c.Messages
				s.PrivateChannels[i] = channel
				return nil
			}
		}

		s.PrivateChannels = append(s.PrivateChannels, channel)
	} else {
		guild, err := s.Guild(channel.GuildID)
		if err != nil {
			return err
		}

		s.Lock()
		defer s.Unlock()

		// If the channel exists, replace it.
		for i, c := range guild.Channels {
			if c.ID == channel.ID {
				// Don't stomp on messages.
				channel.Messages = c.Messages
				guild.Channels[i] = channel
				return nil
			}
		}

		guild.Channels = append(guild.Channels, channel)
	}

	return nil
}

// ChannelRemove removes a channel from current world state.
func (s *State) ChannelRemove(channel *Channel) error {
	if s == nil {
		return ErrNilState
	}

	if channel.IsPrivate {
		s.Lock()
		defer s.Unlock()

		for i, c := range s.PrivateChannels {
			if c.ID == channel.ID {
				s.PrivateChannels = append(s.PrivateChannels[:i], s.PrivateChannels[i+1:]...)
				return nil
			}
		}
	} else {
		guild, err := s.Guild(channel.GuildID)
		if err != nil {
			return err
		}

		s.Lock()
		defer s.Unlock()

		for i, c := range guild.Channels {
			if c.ID == channel.ID {
				guild.Channels = append(guild.Channels[:i], guild.Channels[i+1:]...)
				return nil
			}
		}
	}

	return errors.New("Channel not found.")
}

// GuildChannel gets a channel by ID from a guild.
func (s *State) GuildChannel(guildID, channelID string) (*Channel, error) {
	if s == nil {
		return nil, ErrNilState
	}

	guild, err := s.Guild(guildID)
	if err != nil {
		return nil, err
	}

	s.RLock()
	defer s.RUnlock()

	for _, c := range guild.Channels {
		if c.ID == channelID {
			return c, nil
		}
	}

	return nil, errors.New("Channel not found.")
}

// PrivateChannel gets a private channel by ID.
func (s *State) PrivateChannel(channelID string) (*Channel, error) {
	if s == nil {
		return nil, ErrNilState
	}

	s.RLock()
	defer s.RUnlock()

	for _, c := range s.PrivateChannels {
		if c.ID == channelID {
			return c, nil
		}
	}

	return nil, errors.New("Channel not found.")
}

// Channel gets a channel by ID, it will look in all guilds an private channels.
func (s *State) Channel(channelID string) (*Channel, error) {
	if s == nil {
		return nil, ErrNilState
	}

	c, err := s.PrivateChannel(channelID)
	if err == nil {
		return c, nil
	}

	for _, g := range s.Guilds {
		c, err := s.GuildChannel(g.ID, channelID)
		if err == nil {
			return c, nil
		}
	}

	return nil, errors.New("Channel not found.")
}

// Emoji returns an emoji for a guild and emoji id.
func (s *State) Emoji(guildID, emojiID string) (*Emoji, error) {
	if s == nil {
		return nil, ErrNilState
	}

	guild, err := s.Guild(guildID)
	if err != nil {
		return nil, err
	}

	s.RLock()
	defer s.RUnlock()

	for _, e := range guild.Emojis {
		if e.ID == emojiID {
			return e, nil
		}
	}

	return nil, errors.New("Emoji not found.")
}

// EmojiAdd adds an emoji to the current world state.
func (s *State) EmojiAdd(guildID string, emoji *Emoji) error {
	if s == nil {
		return ErrNilState
	}

	guild, err := s.Guild(guildID)
	if err != nil {
		return err
	}

	s.Lock()
	defer s.Unlock()

	for i, e := range guild.Emojis {
		if e.ID == emoji.ID {
			guild.Emojis[i] = emoji
			return nil
		}
	}

	guild.Emojis = append(guild.Emojis, emoji)
	return nil
}

// EmojisAdd adds multiple emojis to the world state.
func (s *State) EmojisAdd(guildID string, emojis []*Emoji) error {
	for _, e := range emojis {
		if err := s.EmojiAdd(guildID, e); err != nil {
			return err
		}
	}
	return nil
}

// MessageAdd adds a message to the current world state, or updates it if it exists.
// If the channel cannot be found, the message is discarded.
// Messages are kept in state up to s.MaxMessageCount
func (s *State) MessageAdd(message *Message) error {
	if s == nil {
		return ErrNilState
	}

	c, err := s.Channel(message.ChannelID)
	if err != nil {
		return err
	}

	s.Lock()
	defer s.Unlock()

	// If the message exists, replace it.
	for i, m := range c.Messages {
		if m.ID == message.ID {
			c.Messages[i] = message
			return nil
		}
	}

	c.Messages = append(c.Messages, message)

	if len(c.Messages) > s.MaxMessageCount {
		s.Unlock()
		for len(c.Messages) > s.MaxMessageCount {
			err := s.MessageRemove(c.Messages[0])
			if err != nil {
				fmt.Println("message remove error: ", err)
			}
		}
		s.Lock()
	}
	return nil
}

// MessageRemove removes a message from the world state.
func (s *State) MessageRemove(message *Message) error {
	if s == nil {
		return ErrNilState
	}

	c, err := s.Channel(message.ChannelID)
	if err != nil {
		return err
	}

	s.Lock()
	defer s.Unlock()

	for i, m := range c.Messages {
		if m.ID == message.ID {
			c.Messages = append(c.Messages[:i], c.Messages[i+1:]...)
			return nil
		}
	}

	return errors.New("Message not found.")
}

// Message gets a message by channel and message ID.
func (s *State) Message(channelID, messageID string) (*Message, error) {
	if s == nil {
		return nil, ErrNilState
	}

	c, err := s.Channel(channelID)
	if err != nil {
		return nil, err
	}

	s.RLock()
	defer s.RUnlock()

	for _, m := range c.Messages {
		if m.ID == messageID {
			return m, nil
		}
	}

	return nil, errors.New("Message not found.")
}

// onInterface handles all events related to states.
func (s *State) onInterface(se *Session, i interface{}) {
	if s == nil || !se.StateEnabled {
		return
	}

	switch t := i.(type) {
	case *Ready:
		s.OnReady(t)
	case *GuildCreate:
		s.GuildAdd(t.Guild)
	case *GuildUpdate:
		s.GuildAdd(t.Guild)
	case *GuildDelete:
		s.GuildRemove(t.Guild)
	case *GuildMemberAdd:
		s.MemberAdd(t.Member)
	case *GuildMemberUpdate:
		s.MemberAdd(t.Member)
	case *GuildMemberRemove:
		s.MemberRemove(t.Member)
	case *GuildEmojisUpdate:
		s.EmojisAdd(t.GuildID, t.Emojis)
	case *ChannelCreate:
		s.ChannelAdd(t.Channel)
	case *ChannelUpdate:
		s.ChannelAdd(t.Channel)
	case *ChannelDelete:
		s.ChannelRemove(t.Channel)
	case *MessageCreate:
		s.MessageAdd(t.Message)
	case *MessageUpdate:
		s.MessageAdd(t.Message)
	case *MessageDelete:
		s.MessageRemove(t.Message)
	}
}
<commit_msg>Return state errors. Because we're good citizens.<commit_after>// Discordgo - Discord bindings for Go
// Available at https://github.com/bwmarrin/discordgo

// Copyright 2015-2016 Bruce Marriner <bruce@sqls.net>.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file contains code related to state tracking.  If enabled, state
// tracking will capture the initial READY packet and many other websocket
// events and maintain an in-memory state of of guilds, channels, users, and
// so forth.  This information can be accessed through the Session.State struct.

package discordgo

import (
	"errors"
	"fmt"
)

// ErrNilState is returned when the state is nil.
var ErrNilState = errors.New("State not instantiated, please use discordgo.New() or assign Session.State.")

// NewState creates an empty state.
func NewState() *State {
	return &State{
		Ready: Ready{
			PrivateChannels: []*Channel{},
			Guilds:          []*Guild{},
		},
	}
}

// OnReady takes a Ready event and updates all internal state.
func (s *State) OnReady(r *Ready) error {
	if s == nil {
		return ErrNilState
	}

	s.Lock()
	defer s.Unlock()

	s.Ready = *r
	return nil
}

// GuildAdd adds a guild to the current world state, or
// updates it if it already exists.
func (s *State) GuildAdd(guild *Guild) error {
	if s == nil {
		return ErrNilState
	}

	s.Lock()
	defer s.Unlock()

	// If the guild exists, replace it.
	for i, g := range s.Guilds {
		if g.ID == guild.ID {
			// Don't stomp on properties that don't come in updates.
			guild.Members = g.Members
			guild.Presences = g.Presences
			guild.Channels = g.Channels
			guild.VoiceStates = g.VoiceStates
			s.Guilds[i] = guild
			return nil
		}
	}

	s.Guilds = append(s.Guilds, guild)
	return nil
}

// GuildRemove removes a guild from current world state.
func (s *State) GuildRemove(guild *Guild) error {
	if s == nil {
		return ErrNilState
	}

	s.Lock()
	defer s.Unlock()

	for i, g := range s.Guilds {
		if g.ID == guild.ID {
			s.Guilds = append(s.Guilds[:i], s.Guilds[i+1:]...)
			return nil
		}
	}

	return errors.New("Guild not found.")
}

// Guild gets a guild by ID.
// Useful for querying if @me is in a guild:
//     _, err := discordgo.Session.State.Guild(guildID)
//     isInGuild := err == nil
func (s *State) Guild(guildID string) (*Guild, error) {
	if s == nil {
		return nil, ErrNilState
	}

	s.RLock()
	defer s.RUnlock()

	for _, g := range s.Guilds {
		if g.ID == guildID {
			return g, nil
		}
	}

	return nil, errors.New("Guild not found.")
}

// TODO: Consider moving Guild state update methods onto *Guild.

// MemberAdd adds a member to the current world state, or
// updates it if it already exists.
func (s *State) MemberAdd(member *Member) error {
	if s == nil {
		return ErrNilState
	}

	guild, err := s.Guild(member.GuildID)
	if err != nil {
		return err
	}

	s.Lock()
	defer s.Unlock()

	for i, m := range guild.Members {
		if m.User.ID == member.User.ID {
			guild.Members[i] = member
			return nil
		}
	}

	guild.Members = append(guild.Members, member)
	return nil
}

// MemberRemove removes a member from current world state.
func (s *State) MemberRemove(member *Member) error {
	if s == nil {
		return ErrNilState
	}

	guild, err := s.Guild(member.GuildID)
	if err != nil {
		return err
	}

	s.Lock()
	defer s.Unlock()

	for i, m := range guild.Members {
		if m.User.ID == member.User.ID {
			guild.Members = append(guild.Members[:i], guild.Members[i+1:]...)
			return nil
		}
	}

	return errors.New("Member not found.")
}

// Member gets a member by ID from a guild.
func (s *State) Member(guildID, userID string) (*Member, error) {
	if s == nil {
		return nil, ErrNilState
	}

	guild, err := s.Guild(guildID)
	if err != nil {
		return nil, err
	}

	s.RLock()
	defer s.RUnlock()

	for _, m := range guild.Members {
		if m.User.ID == userID {
			return m, nil
		}
	}

	return nil, errors.New("Member not found.")
}

// ChannelAdd adds a guild to the current world state, or
// updates it if it already exists.
// Channels may exist either as PrivateChannels or inside
// a guild.
func (s *State) ChannelAdd(channel *Channel) error {
	if s == nil {
		return ErrNilState
	}

	if channel.IsPrivate {
		s.Lock()
		defer s.Unlock()

		// If the channel exists, replace it.
		for i, c := range s.PrivateChannels {
			if c.ID == channel.ID {
				// Don't stomp on messages.
				channel.Messages = c.Messages
				s.PrivateChannels[i] = channel
				return nil
			}
		}

		s.PrivateChannels = append(s.PrivateChannels, channel)
	} else {
		guild, err := s.Guild(channel.GuildID)
		if err != nil {
			return err
		}

		s.Lock()
		defer s.Unlock()

		// If the channel exists, replace it.
		for i, c := range guild.Channels {
			if c.ID == channel.ID {
				// Don't stomp on messages.
				channel.Messages = c.Messages
				guild.Channels[i] = channel
				return nil
			}
		}

		guild.Channels = append(guild.Channels, channel)
	}

	return nil
}

// ChannelRemove removes a channel from current world state.
func (s *State) ChannelRemove(channel *Channel) error {
	if s == nil {
		return ErrNilState
	}

	if channel.IsPrivate {
		s.Lock()
		defer s.Unlock()

		for i, c := range s.PrivateChannels {
			if c.ID == channel.ID {
				s.PrivateChannels = append(s.PrivateChannels[:i], s.PrivateChannels[i+1:]...)
				return nil
			}
		}
	} else {
		guild, err := s.Guild(channel.GuildID)
		if err != nil {
			return err
		}

		s.Lock()
		defer s.Unlock()

		for i, c := range guild.Channels {
			if c.ID == channel.ID {
				guild.Channels = append(guild.Channels[:i], guild.Channels[i+1:]...)
				return nil
			}
		}
	}

	return errors.New("Channel not found.")
}

// GuildChannel gets a channel by ID from a guild.
func (s *State) GuildChannel(guildID, channelID string) (*Channel, error) {
	if s == nil {
		return nil, ErrNilState
	}

	guild, err := s.Guild(guildID)
	if err != nil {
		return nil, err
	}

	s.RLock()
	defer s.RUnlock()

	for _, c := range guild.Channels {
		if c.ID == channelID {
			return c, nil
		}
	}

	return nil, errors.New("Channel not found.")
}

// PrivateChannel gets a private channel by ID.
func (s *State) PrivateChannel(channelID string) (*Channel, error) {
	if s == nil {
		return nil, ErrNilState
	}

	s.RLock()
	defer s.RUnlock()

	for _, c := range s.PrivateChannels {
		if c.ID == channelID {
			return c, nil
		}
	}

	return nil, errors.New("Channel not found.")
}

// Channel gets a channel by ID, it will look in all guilds an private channels.
func (s *State) Channel(channelID string) (*Channel, error) {
	if s == nil {
		return nil, ErrNilState
	}

	c, err := s.PrivateChannel(channelID)
	if err == nil {
		return c, nil
	}

	for _, g := range s.Guilds {
		c, err := s.GuildChannel(g.ID, channelID)
		if err == nil {
			return c, nil
		}
	}

	return nil, errors.New("Channel not found.")
}

// Emoji returns an emoji for a guild and emoji id.
func (s *State) Emoji(guildID, emojiID string) (*Emoji, error) {
	if s == nil {
		return nil, ErrNilState
	}

	guild, err := s.Guild(guildID)
	if err != nil {
		return nil, err
	}

	s.RLock()
	defer s.RUnlock()

	for _, e := range guild.Emojis {
		if e.ID == emojiID {
			return e, nil
		}
	}

	return nil, errors.New("Emoji not found.")
}

// EmojiAdd adds an emoji to the current world state.
func (s *State) EmojiAdd(guildID string, emoji *Emoji) error {
	if s == nil {
		return ErrNilState
	}

	guild, err := s.Guild(guildID)
	if err != nil {
		return err
	}

	s.Lock()
	defer s.Unlock()

	for i, e := range guild.Emojis {
		if e.ID == emoji.ID {
			guild.Emojis[i] = emoji
			return nil
		}
	}

	guild.Emojis = append(guild.Emojis, emoji)
	return nil
}

// EmojisAdd adds multiple emojis to the world state.
func (s *State) EmojisAdd(guildID string, emojis []*Emoji) error {
	for _, e := range emojis {
		if err := s.EmojiAdd(guildID, e); err != nil {
			return err
		}
	}
	return nil
}

// MessageAdd adds a message to the current world state, or updates it if it exists.
// If the channel cannot be found, the message is discarded.
// Messages are kept in state up to s.MaxMessageCount
func (s *State) MessageAdd(message *Message) error {
	if s == nil {
		return ErrNilState
	}

	c, err := s.Channel(message.ChannelID)
	if err != nil {
		return err
	}

	s.Lock()
	defer s.Unlock()

	// If the message exists, replace it.
	for i, m := range c.Messages {
		if m.ID == message.ID {
			c.Messages[i] = message
			return nil
		}
	}

	c.Messages = append(c.Messages, message)

	if len(c.Messages) > s.MaxMessageCount {
		s.Unlock()
		for len(c.Messages) > s.MaxMessageCount {
			err := s.MessageRemove(c.Messages[0])
			if err != nil {
				fmt.Println("message remove error: ", err)
			}
		}
		s.Lock()
	}
	return nil
}

// MessageRemove removes a message from the world state.
func (s *State) MessageRemove(message *Message) error {
	if s == nil {
		return ErrNilState
	}

	c, err := s.Channel(message.ChannelID)
	if err != nil {
		return err
	}

	s.Lock()
	defer s.Unlock()

	for i, m := range c.Messages {
		if m.ID == message.ID {
			c.Messages = append(c.Messages[:i], c.Messages[i+1:]...)
			return nil
		}
	}

	return errors.New("Message not found.")
}

// Message gets a message by channel and message ID.
func (s *State) Message(channelID, messageID string) (*Message, error) {
	if s == nil {
		return nil, ErrNilState
	}

	c, err := s.Channel(channelID)
	if err != nil {
		return nil, err
	}

	s.RLock()
	defer s.RUnlock()

	for _, m := range c.Messages {
		if m.ID == messageID {
			return m, nil
		}
	}

	return nil, errors.New("Message not found.")
}

// onInterface handles all events related to states.
func (s *State) onInterface(se *Session, i interface{}) (err error) {
	if s == nil {
		return ErrNilState
	}
	if !se.StateEnabled {
		return nil
	}

	switch t := i.(type) {
	case *Ready:
		err = s.OnReady(t)
	case *GuildCreate:
		err = s.GuildAdd(t.Guild)
	case *GuildUpdate:
		err = s.GuildAdd(t.Guild)
	case *GuildDelete:
		err = s.GuildRemove(t.Guild)
	case *GuildMemberAdd:
		err = s.MemberAdd(t.Member)
	case *GuildMemberUpdate:
		err = s.MemberAdd(t.Member)
	case *GuildMemberRemove:
		err = s.MemberRemove(t.Member)
	case *GuildEmojisUpdate:
		err = s.EmojisAdd(t.GuildID, t.Emojis)
	case *ChannelCreate:
		err = s.ChannelAdd(t.Channel)
	case *ChannelUpdate:
		err = s.ChannelAdd(t.Channel)
	case *ChannelDelete:
		err = s.ChannelRemove(t.Channel)
	case *MessageCreate:
		err = s.MessageAdd(t.Message)
	case *MessageUpdate:
		err = s.MessageAdd(t.Message)
	case *MessageDelete:
		err = s.MessageRemove(t.Message)
	}

	return
}
<|endoftext|>


<commit_before>package main

import (
	"sort"
)

type ExchangeInfo struct {
	Exchange string
	Currency string
	Price float64
	Volume float64
}

var ExchInfo []ExchangeInfo

type ByPrice []ExchangeInfo

func (this ByPrice) Len() int {
	return len(this)
}

func (this ByPrice) Less(i, j int) bool {
	return this[i].Price < this[j].Price
}

func (this ByPrice) Swap(i, j int) {
	this[i], this[j] = this[j], this[i]
}

type ByVolume []ExchangeInfo

func (this ByVolume) Len() int {
	return len(this)
}

func (this ByVolume) Less(i, j int) bool {
	return this[i].Volume < this[j].Volume
}

func (this ByVolume) Swap(i, j int) {
	this[i], this[j] = this[j], this[i]
}

func AddExchangeInfo(exchange, currency string, price, volume float64) {
	exch := ExchangeInfo{}
	exch.Exchange = exchange
	exch.Currency = currency
	exch.Price = price
	exch.Volume = volume
	ExchInfo = append(ExchInfo, exch)
}

func SortExchangesByVolume(currency string) []ExchangeInfo {
	info := []ExchangeInfo{}

	for _, x := range ExchInfo {
		if x.Currency == currency {
			info = append(info, x)
		}
	}

	sort.Sort(ByVolume(info))
	return info
}

func SortExchangesByPrice(currency string) []ExchangeInfo {
	info := []ExchangeInfo{}

	for _, x := range ExchInfo {
		if x.Currency == currency {
			info = append(info, x)
		}
	}

	sort.Sort(ByPrice(info))
	return info
}

func PopulateExchangeInfo() {
	if bot.exchange.bitfinex.IsEnabled() {
		BitfinexBTC := bot.exchange.bitfinex.GetTicker("BTCUSD")
		BitfinexLTC := bot.exchange.bitfinex.GetTicker("LTCUSD")
		AddExchangeInfo(bot.exchange.bitfinex.GetName(), "BTC", BitfinexBTC.Last, BitfinexBTC.Volume)
		AddExchangeInfo(bot.exchange.bitfinex.GetName(), "LTC", BitfinexLTC.Last, BitfinexLTC.Volume)
	}
	if bot.exchange.bitstamp.IsEnabled() {
		BitstampBTC := bot.exchange.bitstamp.GetTicker()
		AddExchangeInfo(bot.exchange.bitstamp.GetName(), "BTC", BitstampBTC.Last, BitstampBTC.Volume)
	}
	if bot.exchange.btcchina.IsEnabled() {
		BTCChinaBTC := bot.exchange.btcchina.GetTicker("btccny")
		BTCChinaLTC := bot.exchange.btcchina.GetTicker("ltccny")
		BTCChinaBTCLastUSD, _ := ConvertCurrency(BTCChinaBTC.Last, "CNY", "USD")
		BTCChinaLTCLastUSD, _ := ConvertCurrency(BTCChinaLTC.Last, "CNY", "USD")
		AddExchangeInfo(bot.exchange.btcchina.GetName(), "BTC", BTCChinaBTCLastUSD, BTCChinaBTC.Vol)
		AddExchangeInfo(bot.exchange.btcchina.GetName(), "LTC", BTCChinaLTCLastUSD, BTCChinaLTC.Vol)
	}
	if bot.exchange.btce.IsEnabled() {
		BTCEBTC := bot.exchange.btce.GetTicker("btc_usd")
		BTCELTC := bot.exchange.btce.GetTicker("ltc_usd")
		AddExchangeInfo(bot.exchange.btce.GetName(), "BTC", BTCEBTC.Last, BTCEBTC.Vol_cur)
		AddExchangeInfo(bot.exchange.btce.GetName(), "LTC", BTCELTC.Last, BTCELTC.Vol_cur)
	}
	if bot.exchange.btcmarkets.IsEnabled() {
		BTCMarketsBTC := bot.exchange.btcmarkets.GetTicker("BTC")
		BTCMarketsLTC := bot.exchange.btcmarkets.GetTicker("LTC")
		BTCMarketsBTCUSD, _ := ConvertCurrency(BTCMarketsBTC.LastPrice, "AUD", "USD")
		BTCMarketsLTCUSD, _ := ConvertCurrency(BTCMarketsLTC.LastPrice, "AUD", "USD")
		AddExchangeInfo(bot.exchange.btcmarkets.GetName(), "BTC", BTCMarketsBTCUSD, 0)
		AddExchangeInfo(bot.exchange.btcmarkets.GetName(), "LTC", BTCMarketsLTCUSD, 0)
	}
	if bot.exchange.coinbase.IsEnabled() {
		CoinbaseBTC := bot.exchange.coinbase.GetTicker("BTC-USD")
		CoinbaseStats := bot.exchange.coinbase.GetStats("BTC-USD")
		AddExchangeInfo(bot.exchange.coinbase.GetName(), "BTC",  CoinbaseBTC.Price, CoinbaseStats.Volume)
	}
	if bot.exchange.huobi.IsEnabled() {
		HuobiBTC := bot.exchange.huobi.GetTicker("btc")
		HuobiLTC := bot.exchange.huobi.GetTicker("ltc")
		HuobiBTCLastUSD, _ := ConvertCurrency(HuobiBTC.Last,  "CNY", "USD")
		HuobiLTCLastUSD, _ := ConvertCurrency(HuobiLTC.Last,  "CNY", "USD")
		AddExchangeInfo(bot.exchange.huobi.GetName(), "BTC", HuobiBTCLastUSD, HuobiBTC.Vol)
		AddExchangeInfo(bot.exchange.huobi.GetName(), "LTC", HuobiLTCLastUSD, HuobiLTC.Vol)
	}
	if bot.exchange.itbit.IsEnabled() {
		itbitBTC := bot.exchange.itbit.GetTicker("XBTUSD")
		AddExchangeInfo(bot.exchange.itbit.GetName(), "BTC", itbitBTC.LastPrice, itbitBTC.Volume24h)
	}
	if bot.exchange.okcoinIntl.IsEnabled() {
		okcoinIntlBTC := bot.exchange.okcoinIntl.GetTicker("btc_usd")
		okcoinIntlLTC := bot.exchange.okcoinIntl.GetTicker("ltc_usd")
		AddExchangeInfo(bot.exchange.okcoinIntl.GetName(), "BTC", okcoinIntlBTC.Last, okcoinIntlBTC.Vol)
		AddExchangeInfo(bot.exchange.okcoinIntl.GetName(), "LTC", okcoinIntlLTC.Last, okcoinIntlLTC.Vol)
	}
	if bot.exchange.okcoinChina.IsEnabled() {
		okcoinChinaBTC := bot.exchange.okcoinChina.GetTicker("btc_cny")
		okcoinChinaLTC := bot.exchange.okcoinChina.GetTicker("ltc_cny")
		okcoinChinaBTCLast, _ := ConvertCurrency(okcoinChinaBTC.Last, "CNY", "USD")
		okcoinChinaLTCLast, _ := ConvertCurrency(okcoinChinaLTC.Last, "CNY", "USD")
		AddExchangeInfo(bot.exchange.okcoinChina.GetName(), "BTC", okcoinChinaBTCLast, okcoinChinaBTC.Vol)
		AddExchangeInfo(bot.exchange.okcoinChina.GetName(), "LTC", okcoinChinaLTCLast, okcoinChinaLTC.Vol)
	}
	if bot.exchange.lakebtc.IsEnabled() {
		LakeBTC := bot.exchange.lakebtc.GetTicker()
		AddExchangeInfo(bot.exchange.lakebtc.GetName(), "BTC", LakeBTC.USD.Last, LakeBTC.USD.Volume)
	}
}
<commit_msg>Added ability to reverse sort.<commit_after>package main

import (
	"sort"
)

type ExchangeInfo struct {
	Exchange string
	Currency string
	Price float64
	Volume float64
}

var ExchInfo []ExchangeInfo

type ByPrice []ExchangeInfo

func (this ByPrice) Len() int {
	return len(this)
}

func (this ByPrice) Less(i, j int) bool {
	return this[i].Price < this[j].Price
}

func (this ByPrice) Swap(i, j int) {
	this[i], this[j] = this[j], this[i]
}

type ByVolume []ExchangeInfo

func (this ByVolume) Len() int {
	return len(this)
}

func (this ByVolume) Less(i, j int) bool {
	return this[i].Volume < this[j].Volume
}

func (this ByVolume) Swap(i, j int) {
	this[i], this[j] = this[j], this[i]
}

func AddExchangeInfo(exchange, currency string, price, volume float64) {
	exch := ExchangeInfo{}
	exch.Exchange = exchange
	exch.Currency = currency
	exch.Price = price
	exch.Volume = volume
	ExchInfo = append(ExchInfo, exch)
}

func SortExchangesByVolume(currency string, reverse bool) []ExchangeInfo {
	info := []ExchangeInfo{}

	for _, x := range ExchInfo {
		if x.Currency == currency {
			info = append(info, x)
		}
	}

	if reverse {
		sort.Sort(sort.Reverse(ByVolume(info)))
	} else {
		sort.Sort(ByVolume(info))
	}
	return info
}

func SortExchangesByPrice(currency string, reverse bool) []ExchangeInfo {
	info := []ExchangeInfo{}

	for _, x := range ExchInfo {
		if x.Currency == currency {
			info = append(info, x)
		}
	}

	if reverse {
		sort.Sort(sort.Reverse(ByPrice(info)))
	} else {
		sort.Sort(ByPrice(info))
	}
	return info
}

func PopulateExchangeInfo() {
	if bot.exchange.bitfinex.IsEnabled() {
		BitfinexBTC := bot.exchange.bitfinex.GetTicker("BTCUSD")
		BitfinexLTC := bot.exchange.bitfinex.GetTicker("LTCUSD")
		AddExchangeInfo(bot.exchange.bitfinex.GetName(), "BTC", BitfinexBTC.Last, BitfinexBTC.Volume)
		AddExchangeInfo(bot.exchange.bitfinex.GetName(), "LTC", BitfinexLTC.Last, BitfinexLTC.Volume)
	}
	if bot.exchange.bitstamp.IsEnabled() {
		BitstampBTC := bot.exchange.bitstamp.GetTicker()
		AddExchangeInfo(bot.exchange.bitstamp.GetName(), "BTC", BitstampBTC.Last, BitstampBTC.Volume)
	}
	if bot.exchange.btcchina.IsEnabled() {
		BTCChinaBTC := bot.exchange.btcchina.GetTicker("btccny")
		BTCChinaLTC := bot.exchange.btcchina.GetTicker("ltccny")
		BTCChinaBTCLastUSD, _ := ConvertCurrency(BTCChinaBTC.Last, "CNY", "USD")
		BTCChinaLTCLastUSD, _ := ConvertCurrency(BTCChinaLTC.Last, "CNY", "USD")
		AddExchangeInfo(bot.exchange.btcchina.GetName(), "BTC", BTCChinaBTCLastUSD, BTCChinaBTC.Vol)
		AddExchangeInfo(bot.exchange.btcchina.GetName(), "LTC", BTCChinaLTCLastUSD, BTCChinaLTC.Vol)
	}
	if bot.exchange.btce.IsEnabled() {
		BTCEBTC := bot.exchange.btce.GetTicker("btc_usd")
		BTCELTC := bot.exchange.btce.GetTicker("ltc_usd")
		AddExchangeInfo(bot.exchange.btce.GetName(), "BTC", BTCEBTC.Last, BTCEBTC.Vol_cur)
		AddExchangeInfo(bot.exchange.btce.GetName(), "LTC", BTCELTC.Last, BTCELTC.Vol_cur)
	}
	if bot.exchange.btcmarkets.IsEnabled() {
		BTCMarketsBTC := bot.exchange.btcmarkets.GetTicker("BTC")
		BTCMarketsLTC := bot.exchange.btcmarkets.GetTicker("LTC")
		BTCMarketsBTCUSD, _ := ConvertCurrency(BTCMarketsBTC.LastPrice, "AUD", "USD")
		BTCMarketsLTCUSD, _ := ConvertCurrency(BTCMarketsLTC.LastPrice, "AUD", "USD")
		AddExchangeInfo(bot.exchange.btcmarkets.GetName(), "BTC", BTCMarketsBTCUSD, 0)
		AddExchangeInfo(bot.exchange.btcmarkets.GetName(), "LTC", BTCMarketsLTCUSD, 0)
	}
	if bot.exchange.coinbase.IsEnabled() {
		CoinbaseBTC := bot.exchange.coinbase.GetTicker("BTC-USD")
		CoinbaseStats := bot.exchange.coinbase.GetStats("BTC-USD")
		AddExchangeInfo(bot.exchange.coinbase.GetName(), "BTC",  CoinbaseBTC.Price, CoinbaseStats.Volume)
	}
	if bot.exchange.huobi.IsEnabled() {
		HuobiBTC := bot.exchange.huobi.GetTicker("btc")
		HuobiLTC := bot.exchange.huobi.GetTicker("ltc")
		HuobiBTCLastUSD, _ := ConvertCurrency(HuobiBTC.Last,  "CNY", "USD")
		HuobiLTCLastUSD, _ := ConvertCurrency(HuobiLTC.Last,  "CNY", "USD")
		AddExchangeInfo(bot.exchange.huobi.GetName(), "BTC", HuobiBTCLastUSD, HuobiBTC.Vol)
		AddExchangeInfo(bot.exchange.huobi.GetName(), "LTC", HuobiLTCLastUSD, HuobiLTC.Vol)
	}
	if bot.exchange.itbit.IsEnabled() {
		itbitBTC := bot.exchange.itbit.GetTicker("XBTUSD")
		AddExchangeInfo(bot.exchange.itbit.GetName(), "BTC", itbitBTC.LastPrice, itbitBTC.Volume24h)
	}
	if bot.exchange.okcoinIntl.IsEnabled() {
		okcoinIntlBTC := bot.exchange.okcoinIntl.GetTicker("btc_usd")
		okcoinIntlLTC := bot.exchange.okcoinIntl.GetTicker("ltc_usd")
		AddExchangeInfo(bot.exchange.okcoinIntl.GetName(), "BTC", okcoinIntlBTC.Last, okcoinIntlBTC.Vol)
		AddExchangeInfo(bot.exchange.okcoinIntl.GetName(), "LTC", okcoinIntlLTC.Last, okcoinIntlLTC.Vol)
	}
	if bot.exchange.okcoinChina.IsEnabled() {
		okcoinChinaBTC := bot.exchange.okcoinChina.GetTicker("btc_cny")
		okcoinChinaLTC := bot.exchange.okcoinChina.GetTicker("ltc_cny")
		okcoinChinaBTCLast, _ := ConvertCurrency(okcoinChinaBTC.Last, "CNY", "USD")
		okcoinChinaLTCLast, _ := ConvertCurrency(okcoinChinaLTC.Last, "CNY", "USD")
		AddExchangeInfo(bot.exchange.okcoinChina.GetName(), "BTC", okcoinChinaBTCLast, okcoinChinaBTC.Vol)
		AddExchangeInfo(bot.exchange.okcoinChina.GetName(), "LTC", okcoinChinaLTCLast, okcoinChinaLTC.Vol)
	}
	if bot.exchange.lakebtc.IsEnabled() {
		LakeBTC := bot.exchange.lakebtc.GetTicker()
		AddExchangeInfo(bot.exchange.lakebtc.GetName(), "BTC", LakeBTC.USD.Last, LakeBTC.USD.Volume)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"sync/atomic"
)

type ProxyStats struct {
	clientsServed uint64
	bytesServed   uint64
}

func (ps *ProxyStats) AddServed() {
	atomic.AddUint64(&ps.clientsServed, 1)
}

func (ps *ProxyStats) AddBytes(bc int64) {
	if bc <= 0 {
		return
	}
	atomic.AddUint64(&ps.bytesServed, uint64(bc))
}

func (ps *ProxyStats) GetStats() (b uint64, c uint64) {
	b = atomic.LoadUint64(&ps.clientsServed)
	c = atomic.LoadUint64(&ps.bytesServed)
	return b, c
}
<commit_msg>cleanup stats a bit<commit_after>package main

import (
	"sync"
)

type ProxyStats struct {
	sync.RWMutex
	clients uint64
	bytes   uint64
}

func (ps *ProxyStats) AddServed() {
	ps.Lock()
	ps.clients += 1
	ps.Unlock()
}

func (ps *ProxyStats) AddBytes(bc int64) {
	if bc <= 0 {
		return
	}
	ps.Lock()
	ps.bytes += uint64(bc)
	ps.Unlock()
}

func (ps *ProxyStats) GetStats() (uint64, uint64) {
	ps.RLock()
	defer ps.RUnlock()
	return ps.bytes, ps.clients
}
<|endoftext|>


<commit_before>package cruncy

import (
	"errors"
	"fmt"
	"sync"
	"time"

	bolt "go.etcd.io/bbolt"
)

// Store is db abstarction on top of bolt db
type Store struct {
	db    *bolt.DB
	mutex sync.Mutex
}

var (
	// ErrNotFound error key not found
	ErrNotFound = errors.New("store: key not found")
	// ErrBadValue error bad value
	ErrBadValue = errors.New("store: bad value")
)

// Open a database file
func Open(path string) (*Store, error) {
	opts := &bolt.Options{
		Timeout: 50 * time.Millisecond,
	}
	db, err := bolt.Open(path, 0640, opts)

	if err != nil {
		return nil, err
	}

	return &Store{db: db}, nil
}

// CreateBucket creates a buck
func (store *Store) CreateBucket(bucket string) error {
	return store.db.Update(func(tx *bolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists([]byte(bucket))
		return err
	})
}

// Close the database
func (store *Store) Close() error {
	return store.db.Close()
}

// Put a key/value into a given bucket
func (store *Store) Put(bucket string, key string, value string) error {
	store.mutex.Lock()
	defer store.mutex.Unlock()

	return store.db.Update(func(tx *bolt.Tx) error {
		return tx.Bucket([]byte(bucket)).Put([]byte(key), ([]byte(value)))
	})
}

// Get a key/value from a given bucket
func (store *Store) Get(bucket, key string, value *string) error {
	if value == nil {
		return fmt.Errorf("store.Get requires pointer to a string. Param must be given")
	}

	store.mutex.Lock()
	defer store.mutex.Unlock()

	return store.db.View(func(tx *bolt.Tx) error {

		c := tx.Bucket([]byte(bucket)).Cursor()
		k, v := c.Seek([]byte(key))
		if k == nil || string(k) != key {
			return ErrNotFound
		}
		*value = string(v[:])
		return nil

	})
}

// Delete the entry with the given key. If no such key is present in the store,
// it returns ErrNotFound.
//
//	store.Delete("key42")
func (store *Store) Delete(bucket string, key string) error {
	store.mutex.Lock()
	defer store.mutex.Unlock()

	return store.db.Update(func(tx *bolt.Tx) error {
		c := tx.Bucket([]byte(bucket)).Cursor()
		if k, _ := c.Seek([]byte(key)); k == nil || string(k) != key {
			return ErrNotFound
		}
		return c.Delete()

	})
}

// ListBuckets lists all buckets
func (store *Store) ListBuckets() ([]string, error) {
	rc := []string{}

	store.mutex.Lock()
	defer store.mutex.Unlock()

	err := store.db.View(func(tx *bolt.Tx) error {
		return tx.ForEach(func(name []byte, _ *bolt.Bucket) error {
			rc = append(rc, string(name))
			return nil
		})
	})

	return rc, err
}

// ListBucket lists all buckets
func (store *Store) ListBucket(bucket string, filter func(k, v string) (bool, error)) ([]string, error) {
	rc := []string{}

	store.mutex.Lock()
	defer store.mutex.Unlock()

	err := store.db.View(func(tx *bolt.Tx) error {

		b := tx.Bucket([]byte(bucket))

		c := b.Cursor()

		for k, v := c.First(); k != nil; k, v = c.Next() {
			add := true
			var err error
			if filter != nil {
				add, err = filter(string(k), string(v))
				if err != nil {
					return err
				}
			}
			if add {
				rc = append(rc, string(k))
			}
		}
		return nil
	})

	return rc, err
}

// ForEach iterates over every key and value in a bucket
func (store *Store) ForEach(bucket string, filter func(k, v []byte) error) error {
	return store.db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(bucket))
		return b.ForEach(filter)
	})
}

// GetDB returns pointer to underlaying DB.
func (store *Store) GetDB() *bolt.DB {
	return store.db
}
<commit_msg>Store fix<commit_after>package cruncy

import (
	"errors"
	"fmt"
	"sync"
	"time"

	bolt "go.etcd.io/bbolt"
)

// Store is db abstarction on top of bolt db
type Store struct {
	db    *bolt.DB
	mutex sync.Mutex
}

var (
	// ErrNotFound error key not found
	ErrNotFound = errors.New("store: key not found")
	// ErrBadValue error bad value
	ErrBadValue = errors.New("store: bad value")
)

// Open a database file
func Open(path string) (*Store, error) {
	opts := &bolt.Options{
		Timeout: 50 * time.Millisecond,
	}
	db, err := bolt.Open(path, 0640, opts)

	if err != nil {
		return nil, err
	}

	return &Store{db: db}, nil
}

// CreateBucket creates a buck
func (store *Store) CreateBucket(bucket string) error {
	return store.db.Update(func(tx *bolt.Tx) error {
		_, err := tx.CreateBucketIfNotExists([]byte(bucket))
		return err
	})
}

// Close the database
func (store *Store) Close() error {
	return store.db.Close()
}

// Put a key/value into a given bucket
func (store *Store) Put(bucket string, key string, value string) error {
	store.mutex.Lock()
	defer store.mutex.Unlock()

	return store.db.Update(func(tx *bolt.Tx) error {
		return tx.Bucket([]byte(bucket)).Put([]byte(key), ([]byte(value)))
	})
}

// Get a key/value from a given bucket
func (store *Store) Get(bucket, key string, value *string) error {
	if value == nil {
		return fmt.Errorf("store.Get requires pointer to a string. Param must be given")
	}

	store.mutex.Lock()
	defer store.mutex.Unlock()

	return store.db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(bucket))
		if b == nil {
			return ErrNotFound
		}
		c := b.Cursor()
		k, v := c.Seek([]byte(key))
		if k == nil || string(k) != key {
			return ErrNotFound
		}
		*value = string(v[:])
		return nil

	})
}

// Delete the entry with the given key. If no such key is present in the store,
// it returns ErrNotFound.
//
//	store.Delete("key42")
func (store *Store) Delete(bucket string, key string) error {
	store.mutex.Lock()
	defer store.mutex.Unlock()

	return store.db.Update(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(bucket))
		if b == nil {
			return ErrNotFound
		}
		c := b.Cursor()
		if k, _ := c.Seek([]byte(key)); k == nil || string(k) != key {
			return ErrNotFound
		}
		return c.Delete()

	})
}

// ListBuckets lists all buckets
func (store *Store) ListBuckets() ([]string, error) {
	rc := []string{}

	store.mutex.Lock()
	defer store.mutex.Unlock()

	err := store.db.View(func(tx *bolt.Tx) error {
		return tx.ForEach(func(name []byte, _ *bolt.Bucket) error {
			rc = append(rc, string(name))
			return nil
		})
	})

	return rc, err
}

// ListBucket lists all buckets
func (store *Store) ListBucket(bucket string, filter func(k, v string) (bool, error)) ([]string, error) {
	rc := []string{}

	store.mutex.Lock()
	defer store.mutex.Unlock()

	err := store.db.View(func(tx *bolt.Tx) error {

		b := tx.Bucket([]byte(bucket))
		if b == nil {
			return ErrNotFound
		}

		c := b.Cursor()

		for k, v := c.First(); k != nil; k, v = c.Next() {
			add := true
			var err error
			if filter != nil {
				add, err = filter(string(k), string(v))
				if err != nil {
					return err
				}
			}
			if add {
				rc = append(rc, string(k))
			}
		}
		return nil
	})

	return rc, err
}

// ForEach iterates over every key and value in a bucket
func (store *Store) ForEach(bucket string, filter func(k, v []byte) error) error {
	return store.db.View(func(tx *bolt.Tx) error {
		b := tx.Bucket([]byte(bucket))
		return b.ForEach(filter)
	})
}

// GetDB returns pointer to underlaying DB.
func (store *Store) GetDB() *bolt.DB {
	return store.db
}
<|endoftext|>


<commit_before>package qb

import (
	"fmt"
	"strings"
)

// NewTable generates a new table pointer given table name, column and table constraints
func NewTable(name string, columns []Column, constraints []Constraint) *Table {
	return &Table{
		name:        name,
		columns:     columns,
		constraints: constraints,
		builder:     NewBuilder(),
		primaryCols: []string{},
		refs:        []ref{},
	}
}

// Table is the base abstraction for any sql table
type Table struct {
	name        string
	columns     []Column
	constraints []Constraint
	builder     *Builder
	primaryCols []string
	refs        []ref
}

// SQL generates create table syntax of table
func (t *Table) SQL() string {

	cols := []string{}
	for _, v := range t.columns {
		cols = append(cols, v.SQL())
	}

	constraints := []string{}

	// build primary key constraints using primaryCols
	if len(t.primaryCols) > 0 {
		constraints = append(constraints, fmt.Sprintf("PRIMARY KEY(%s)", strings.Join(t.primaryCols, ", ")))
	}

	// build foreign key constraints using refCols
	for _, ref := range t.refs {
		constraints = append(constraints, fmt.Sprintf("FOREIGN KEY(%s) REFERENCES %s(%s)", strings.Join(ref.cols, ", "), ref.refTable, strings.Join(ref.refCols, ", ")))
	}

	for _, v := range t.constraints {
		constraints = append(constraints, v.Name)
	}

	query, _ := t.builder.CreateTable(t.name, cols, constraints).Build()

	return query.SQL()
}

// AddColumn appends a new column to current table
func (t *Table) AddColumn(column Column) {
	t.columns = append(t.columns, column)
}

// AddConstraint appends a new constraint to current table
func (t *Table) AddConstraint(c Constraint) {
	t.constraints = append(t.constraints, c)
}

// AddPrimary appends a primary column that will be lazily built as a primary key constraint
func (t *Table) AddPrimary(col string) {
	t.primaryCols = append(t.primaryCols, col)
}

type ref struct {
	cols     []string
	refTable string
	refCols  []string
}

// AddRef appends a new reference struct that will be lazily built as a foreign key constraint
func (t *Table) AddRef(col string, refTable string, refCol string) {

	if len(t.refs) > 0 {
		for k, ref := range t.refs {
			if refTable == ref.refTable {
				t.refs[k].cols = append(t.refs[k].cols, fmt.Sprintf("`%s`", col))
				t.refs[k].refCols = append(t.refs[k].refCols, fmt.Sprintf("`%s`", refCol))
				return
			}
		}
	}

	r := ref{[]string{}, refTable, []string{}}
	r.cols = append(r.cols, col)
	r.refCols = append(r.refCols, refCol)
	t.refs = append(t.refs, r)
}

// Constraints returns the constraint slice of current table
func (t *Table) Constraints() []Constraint {
	return t.constraints
}

func (t *Table) Insert(kv map[string]interface{}) (*Query, error) {

	keys := make([]string, len(kv))
	vals := make([]interface{}, len(kv))

	for k, v := range kv {
		keys = append(keys, k)
		vals = append(vals, v)
	}

	return t.builder.Insert(t.name, keys...).Values(vals...).Build()
}<commit_msg>fix invalid keys, values array length in Insert()<commit_after>package qb

import (
	"fmt"
	"strings"
)

// NewTable generates a new table pointer given table name, column and table constraints
func NewTable(name string, columns []Column, constraints []Constraint) *Table {
	return &Table{
		name:        name,
		columns:     columns,
		constraints: constraints,
		builder:     NewBuilder(),
		primaryCols: []string{},
		refs:        []ref{},
	}
}

// Table is the base abstraction for any sql table
type Table struct {
	name        string
	columns     []Column
	constraints []Constraint
	builder     *Builder
	primaryCols []string
	refs        []ref
}

// SQL generates create table syntax of table
func (t *Table) SQL() string {

	cols := []string{}
	for _, v := range t.columns {
		cols = append(cols, v.SQL())
	}

	constraints := []string{}

	// build primary key constraints using primaryCols
	if len(t.primaryCols) > 0 {
		constraints = append(constraints, fmt.Sprintf("PRIMARY KEY(%s)", strings.Join(t.primaryCols, ", ")))
	}

	// build foreign key constraints using refCols
	for _, ref := range t.refs {
		constraints = append(constraints, fmt.Sprintf("FOREIGN KEY(%s) REFERENCES %s(%s)", strings.Join(ref.cols, ", "), ref.refTable, strings.Join(ref.refCols, ", ")))
	}

	for _, v := range t.constraints {
		constraints = append(constraints, v.Name)
	}

	query, _ := t.builder.CreateTable(t.name, cols, constraints).Build()

	return query.SQL()
}

// AddColumn appends a new column to current table
func (t *Table) AddColumn(column Column) {
	t.columns = append(t.columns, column)
}

// AddConstraint appends a new constraint to current table
func (t *Table) AddConstraint(c Constraint) {
	t.constraints = append(t.constraints, c)
}

// AddPrimary appends a primary column that will be lazily built as a primary key constraint
func (t *Table) AddPrimary(col string) {
	t.primaryCols = append(t.primaryCols, col)
}

type ref struct {
	cols     []string
	refTable string
	refCols  []string
}

// AddRef appends a new reference struct that will be lazily built as a foreign key constraint
func (t *Table) AddRef(col string, refTable string, refCol string) {

	if len(t.refs) > 0 {
		for k, ref := range t.refs {
			if refTable == ref.refTable {
				t.refs[k].cols = append(t.refs[k].cols, fmt.Sprintf("`%s`", col))
				t.refs[k].refCols = append(t.refs[k].refCols, fmt.Sprintf("`%s`", refCol))
				return
			}
		}
	}

	r := ref{[]string{}, refTable, []string{}}
	r.cols = append(r.cols, col)
	r.refCols = append(r.refCols, refCol)
	t.refs = append(t.refs, r)
}

// Constraints returns the constraint slice of current table
func (t *Table) Constraints() []Constraint {
	return t.constraints
}

func (t *Table) Insert(kv map[string]interface{}) (*Query, error) {

	keys := []string{}
	values := []interface{}{}

	for k, v := range kv {
		keys = append(keys, k)
		values = append(values, v)
	}

	return t.builder.Insert(t.name, keys...).Values(values...).Build()
}
<|endoftext|>


<commit_before>// Package ninow implements a magical sql database ORM.
package ninow

import (
	"database/sql"
	"reflect"
	"strconv"
	"strings"
)

type Table struct {
	db    *sql.DB
	rtype reflect.Type

	name    string
	columns []string
	fields  []string
}

func TableFor(row interface{}, db *sql.DB) *Table {
	rtype := reflect.TypeOf(row)
	name := strings.ToLower(rtype.Name()) + "s"

	columns := []string{}
	fields := []string{}
	for i := 0; i < rtype.NumField(); i++ {
		fieldValue := rtype.Field(i)
		//TODO fix this piece
		columns = append(columns, fieldNameToColumnName(fieldValue.Name))
		fields = append(fields, fieldValue.Name)
	}

	return &Table{db, rtype, name, columns, fields}
}

func (t *Table) Select(id int) (interface{}, error) {
	row := t.db.QueryRow("SELECT "+csv(t.columns)+" FROM "+t.name+" WHERE id=?", id)
	value := reflect.New(t.rtype)
	err := row.Scan(fieldPointers(t.fields, value)...)

	return value.Interface(), err
}

func (t *Table) SelectAllBy(column, value string) (interface{}, error) {
	query := "SELECT " + csv(t.columns) + " FROM " + t.name

	if column != "" && value != "" {
		// TODO Make sure this line is safe
		query += " WHERE " + column + "=" + value
	}

	rows, err := t.db.Query(query)
	if err != nil {
		return nil, err
	}

	sliceOfValue := reflect.MakeSlice(reflect.SliceOf(reflect.PtrTo(t.rtype)), 0, 10)

	for rows.Next() {
		value := reflect.New(t.rtype)
		err := rows.Scan(fieldPointers(t.fields, value)...)
		if err != nil {
			return nil, err
		}

		sliceOfValue = reflect.Append(sliceOfValue, value)
	}

	return sliceOfValue.Interface(), nil
}

func (t *Table) Insert(row interface{}) (int, error) {
	query := "INSERT INTO " + t.name
	query += " (" + csv(t.columns[1:]) + ") "
	query += " values (" + csQ(len(t.columns)-1) + ")"

	res, err := t.db.Exec(query, fieldValues(t.fields[1:], reflect.ValueOf(row))...)
	if err != nil {
		return 0, err
	}

	id, err := res.LastInsertId()
	if err != nil {
		return 0, err
	}

	return int(id), nil
}

func (t *Table) Update(row interface{}) error {
	values := fieldValues(t.fields, reflect.ValueOf(row))

	query := "UPDATE " + t.name
	query += " SET " + cscv(t.columns[1:], values[1:])
	query += " WHERE id=" + strconv.Itoa(values[0].(int))

	println(query)
	_, err := t.db.Exec(query, values[1:]...)
	return err
}

func (t *Table) Delete(id int) error {
	query := "DELETE FROM " + t.name + " WHERE id =? "

	_, err := t.db.Exec(query, id)
	return err
}
<commit_msg>Remove println() from Table.Update()<commit_after>// Package ninow implements a magical sql database ORM.
package ninow

import (
	"database/sql"
	"reflect"
	"strconv"
	"strings"
)

type Table struct {
	db    *sql.DB
	rtype reflect.Type

	name    string
	columns []string
	fields  []string
}

func TableFor(row interface{}, db *sql.DB) *Table {
	rtype := reflect.TypeOf(row)
	name := strings.ToLower(rtype.Name()) + "s"

	columns := []string{}
	fields := []string{}
	for i := 0; i < rtype.NumField(); i++ {
		fieldValue := rtype.Field(i)
		//TODO fix this piece
		columns = append(columns, fieldNameToColumnName(fieldValue.Name))
		fields = append(fields, fieldValue.Name)
	}

	return &Table{db, rtype, name, columns, fields}
}

func (t *Table) Select(id int) (interface{}, error) {
	row := t.db.QueryRow("SELECT "+csv(t.columns)+" FROM "+t.name+" WHERE id=?", id)
	value := reflect.New(t.rtype)
	err := row.Scan(fieldPointers(t.fields, value)...)

	return value.Interface(), err
}

func (t *Table) SelectAllBy(column, value string) (interface{}, error) {
	query := "SELECT " + csv(t.columns) + " FROM " + t.name

	if column != "" && value != "" {
		// TODO Make sure this line is safe
		query += " WHERE " + column + "=" + value
	}

	rows, err := t.db.Query(query)
	if err != nil {
		return nil, err
	}

	sliceOfValue := reflect.MakeSlice(reflect.SliceOf(reflect.PtrTo(t.rtype)), 0, 10)

	for rows.Next() {
		value := reflect.New(t.rtype)
		err := rows.Scan(fieldPointers(t.fields, value)...)
		if err != nil {
			return nil, err
		}

		sliceOfValue = reflect.Append(sliceOfValue, value)
	}

	return sliceOfValue.Interface(), nil
}

func (t *Table) Insert(row interface{}) (int, error) {
	query := "INSERT INTO " + t.name
	query += " (" + csv(t.columns[1:]) + ") "
	query += " values (" + csQ(len(t.columns)-1) + ")"

	res, err := t.db.Exec(query, fieldValues(t.fields[1:], reflect.ValueOf(row))...)
	if err != nil {
		return 0, err
	}

	id, err := res.LastInsertId()
	if err != nil {
		return 0, err
	}

	return int(id), nil
}

func (t *Table) Update(row interface{}) error {
	values := fieldValues(t.fields, reflect.ValueOf(row))

	query := "UPDATE " + t.name
	query += " SET " + cscv(t.columns[1:], values[1:])
	query += " WHERE id=" + strconv.Itoa(values[0].(int))

	_, err := t.db.Exec(query, values[1:]...)
	return err
}

func (t *Table) Delete(id int) error {
	query := "DELETE FROM " + t.name + " WHERE id =? "

	_, err := t.db.Exec(query, id)
	return err
}
<|endoftext|>


<commit_before>package lists

import (
	"encoding/csv"
	"io"
	"net/http"
	"net/url"
	"strings"
	"sync"

	"github.com/Sirupsen/logrus"
	"github.com/sprungknoedl/reputile/model"
	"golang.org/x/net/context"
)

var Lists []List

type Iterator interface {
	Run(context.Context) chan *model.Entry
}

type IteratorFunc func(ctx context.Context) chan *model.Entry

func (fn IteratorFunc) Run(ctx context.Context) chan *model.Entry {
	return fn(ctx)
}

type List struct {
	Key         string
	Name        string
	URL         string
	Description string
	Iterator    Iterator
}

// Run runs the iterator defined for this List. It also sets
// list shared attributes to each entry
func (l List) Run(ctx context.Context) chan *model.Entry {
	c := l.Iterator.Run(ctx)
	out := make(chan *model.Entry)

	go func() {
		for entry := range c {
			entry.Source = l.Key
			out <- entry
		}
	}()

	return out
}

func Combine(its ...Iterator) Iterator {
	return IteratorFunc(func(ctx context.Context) chan *model.Entry {
		wg := sync.WaitGroup{}
		out := make(chan *model.Entry)

		// Start an output goroutine for each input channel in generators. output
		// copies values from c to out until c is closed, then calls wg.Done.
		output := func(c chan *model.Entry) {
			for entry := range c {
				out <- entry
			}
			wg.Done()
		}

		wg.Add(len(its))
		for _, it := range its {
			go output(it.Run(ctx))
		}

		// Start a goroutine to close out once all the output goroutines are
		// done.  This must start after the wg.Add call.
		go func() {
			wg.Wait()
			close(out)
		}()

		return out
	})
}

type Translator func(row []string) *model.Entry

func CSV(url string, fn Translator) Iterator {
	ctor := func(r io.Reader) *csv.Reader {
		reader := csv.NewReader(r)
		reader.Comment = '#'
		reader.TrimLeadingSpace = true
		reader.FieldsPerRecord = -1
		return reader
	}
	return GenericCSV(url, fn, ctor)
}

func SSV(url string, fn Translator) Iterator {
	ctor := func(r io.Reader) *csv.Reader {
		reader := csv.NewReader(r)
		reader.Comma = ' '
		reader.Comment = '#'
		reader.TrimLeadingSpace = true
		reader.FieldsPerRecord = -1
		return reader
	}
	return GenericCSV(url, fn, ctor)
}

func TSV(url string, fn Translator) Iterator {
	ctor := func(r io.Reader) *csv.Reader {
		reader := csv.NewReader(r)
		reader.Comma = '\t'
		reader.Comment = '#'
		reader.TrimLeadingSpace = true
		reader.FieldsPerRecord = -1
		return reader
	}
	return GenericCSV(url, fn, ctor)
}

func CStyleCSV(url string, fn Translator) Iterator {
	ctor := func(r io.Reader) *csv.Reader {
		reader := csv.NewReader(r)
		reader.Comment = '/'
		reader.TrimLeadingSpace = true
		reader.FieldsPerRecord = -1
		return reader
	}
	return GenericCSV(url, fn, ctor)
}

func CStyleSSV(url string, fn Translator) Iterator {
	ctor := func(r io.Reader) *csv.Reader {
		reader := csv.NewReader(r)
		reader.Comma = ' '
		reader.Comment = '/'
		reader.TrimLeadingSpace = true
		reader.FieldsPerRecord = -1
		return reader
	}
	return GenericCSV(url, fn, ctor)
}

func GenericCSV(url string, fn Translator, ctor func(io.Reader) *csv.Reader) Iterator {
	return IteratorFunc(func(ctx context.Context) chan *model.Entry {
		out := make(chan *model.Entry)

		go func() {
			defer close(out)

			resp, err := http.Get(url)
			if err != nil {
				out <- model.SendError(err)
				return
			}

			defer resp.Body.Close()
			reader := ctor(resp.Body)

			for {
				row, err := reader.Read()
				if err == io.EOF {
					break
				}

				if err != nil {
					out <- model.SendError(err)
					break
				}

				e := fn(row)
				if e == nil || (e.Domain == "" && e.IP == nil) {
					continue
				}

				select {
				case out <- e:
				case <-ctx.Done():
					out <- model.SendError(ctx.Err())
					break
				}
			}

			logrus.Printf("update of %q finished", url)
		}()

		return out
	})
}

func ExtractHost(s string) string {
	if s == "" || s == "-" {
		return ""
	}

	if !(strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://")) {
		s = "http://" + s
	}

	u, err := url.Parse(s)
	if err != nil {
		//logrus.Printf("failed to parse %q: %v", s, err)
		return ""
	}

	return u.Host
}
<commit_msg>close List channel, log invalid entries<commit_after>package lists

import (
	"encoding/csv"
	"io"
	"net"
	"net/http"
	"net/url"
	"strings"
	"sync"

	"github.com/Sirupsen/logrus"
	"github.com/sprungknoedl/reputile/model"
	"golang.org/x/net/context"
)

var Lists []List

type Iterator interface {
	Run(context.Context) chan *model.Entry
}

type IteratorFunc func(ctx context.Context) chan *model.Entry

func (fn IteratorFunc) Run(ctx context.Context) chan *model.Entry {
	return fn(ctx)
}

type List struct {
	Key         string
	Name        string
	URL         string
	Description string
	Iterator    Iterator
}

// Run runs the iterator defined for this List. It also sets
// list shared attributes to each entry
func (l List) Run(ctx context.Context) chan *model.Entry {
	c := l.Iterator.Run(ctx)
	out := make(chan *model.Entry)

	go func() {
		defer close(out)
		for entry := range c {
			entry.Source = l.Key
			if entry.Domain == "" && entry.IP == nil {
				logrus.Warnf("skipping invalid entry: %+v", entry)
				continue
			}

			out <- entry
		}
	}()

	return out
}

func Combine(its ...Iterator) Iterator {
	return IteratorFunc(func(ctx context.Context) chan *model.Entry {
		wg := sync.WaitGroup{}
		out := make(chan *model.Entry)

		// Start an output goroutine for each input channel in generators. output
		// copies values from c to out until c is closed, then calls wg.Done.
		output := func(c chan *model.Entry) {
			for entry := range c {
				out <- entry
			}
			wg.Done()
		}

		wg.Add(len(its))
		for _, it := range its {
			go output(it.Run(ctx))
		}

		// Start a goroutine to close out once all the output goroutines are
		// done.  This must start after the wg.Add call.
		go func() {
			wg.Wait()
			close(out)
		}()

		return out
	})
}

type Translator func(row []string) *model.Entry

func CSV(url string, fn Translator) Iterator {
	ctor := func(r io.Reader) *csv.Reader {
		reader := csv.NewReader(r)
		reader.Comment = '#'
		reader.TrimLeadingSpace = true
		reader.FieldsPerRecord = -1
		return reader
	}
	return GenericCSV(url, fn, ctor)
}

func SSV(url string, fn Translator) Iterator {
	ctor := func(r io.Reader) *csv.Reader {
		reader := csv.NewReader(r)
		reader.Comma = ' '
		reader.Comment = '#'
		reader.TrimLeadingSpace = true
		reader.FieldsPerRecord = -1
		return reader
	}
	return GenericCSV(url, fn, ctor)
}

func TSV(url string, fn Translator) Iterator {
	ctor := func(r io.Reader) *csv.Reader {
		reader := csv.NewReader(r)
		reader.Comma = '\t'
		reader.Comment = '#'
		reader.TrimLeadingSpace = true
		reader.FieldsPerRecord = -1
		return reader
	}
	return GenericCSV(url, fn, ctor)
}

func CStyleCSV(url string, fn Translator) Iterator {
	ctor := func(r io.Reader) *csv.Reader {
		reader := csv.NewReader(r)
		reader.Comment = '/'
		reader.TrimLeadingSpace = true
		reader.FieldsPerRecord = -1
		return reader
	}
	return GenericCSV(url, fn, ctor)
}

func CStyleSSV(url string, fn Translator) Iterator {
	ctor := func(r io.Reader) *csv.Reader {
		reader := csv.NewReader(r)
		reader.Comma = ' '
		reader.Comment = '/'
		reader.TrimLeadingSpace = true
		reader.FieldsPerRecord = -1
		return reader
	}
	return GenericCSV(url, fn, ctor)
}

func GenericCSV(url string, fn Translator, ctor func(io.Reader) *csv.Reader) Iterator {
	return IteratorFunc(func(ctx context.Context) chan *model.Entry {
		out := make(chan *model.Entry)

		go func() {
			defer close(out)

			resp, err := http.Get(url)
			if err != nil {
				out <- model.SendError(err)
				return
			}

			defer resp.Body.Close()
			reader := ctor(resp.Body)

			for {
				row, err := reader.Read()
				if err == io.EOF {
					break
				}

				if err != nil {
					out <- model.SendError(err)
					break
				}

				e := fn(row)
				if e == nil {
					continue
				}

				select {
				case out <- e:
				case <-ctx.Done():
					out <- model.SendError(ctx.Err())
					break
				}
			}

			logrus.Printf("update of %q finished", url)
		}()

		return out
	})
}

func ExtractHost(s string) string {
	if s == "" || s == "-" {
		return ""
	}

	if !(strings.HasPrefix(s, "http://") || strings.HasPrefix(s, "https://")) {
		s = "http://" + s
	}

	u, err := url.Parse(s)
	if err != nil {
		logrus.Warnf("failed to parse %s: %v", s, err)
		return ""
	}

	host := u.Host
	if strings.ContainsRune(host, ':') {
		host, _, err = net.SplitHostPort(host)
		if err != nil {
			logrus.Warnf("failed to parse %s: %v", u.Host, err)
			return ""
		}
	}

	return host
}
<|endoftext|>


<commit_before>package util

import (
	"fmt"
	"os"
	"strconv"
	"strings"

	log "github.com/lxc/lxd/shared/log15"
	golxc "gopkg.in/lxc/go-lxc.v2"

	"github.com/lxc/lxd/shared/idmap"
	"github.com/lxc/lxd/shared/logger"
	"github.com/lxc/lxd/shared/osarch"
)

// GetArchitectures returns the list of supported architectures.
func GetArchitectures() ([]int, error) {
	architectures := []int{}

	architectureName, err := osarch.ArchitectureGetLocal()
	if err != nil {
		return nil, err
	}

	architecture, err := osarch.ArchitectureId(architectureName)
	if err != nil {
		return nil, err
	}
	architectures = append(architectures, architecture)

	personalities, err := osarch.ArchitecturePersonalities(architecture)
	if err != nil {
		return nil, err
	}
	for _, personality := range personalities {
		architectures = append(architectures, personality)
	}
	return architectures, nil
}

// GetIdmapSet reads the uid/gid allocation.
func GetIdmapSet() *idmap.IdmapSet {
	idmapSet, err := idmap.DefaultIdmapSet("", "")
	if err != nil {
		logger.Warn("Error reading default uid/gid map", log.Ctx{"err": err.Error()})
		logger.Warnf("Only privileged containers will be able to run")
		idmapSet = nil
	} else {
		kernelIdmapSet, err := idmap.CurrentIdmapSet()
		if err == nil {
			logger.Infof("Kernel uid/gid map:")
			for _, lxcmap := range kernelIdmapSet.ToLxcString() {
				logger.Infof(fmt.Sprintf(" - %s", lxcmap))
			}
		}

		if len(idmapSet.Idmap) == 0 {
			logger.Warnf("No available uid/gid map could be found")
			logger.Warnf("Only privileged containers will be able to run")
			idmapSet = nil
		} else {
			logger.Infof("Configured LXD uid/gid map:")
			for _, lxcmap := range idmapSet.Idmap {
				suffix := ""

				if lxcmap.Usable() != nil {
					suffix = " (unusable)"
				}

				for _, lxcEntry := range lxcmap.ToLxcString() {
					logger.Infof(" - %s%s", lxcEntry, suffix)
				}
			}

			err = idmapSet.Usable()
			if err != nil {
				logger.Warnf("One or more uid/gid map entry isn't usable (typically due to nesting)")
				logger.Warnf("Only privileged containers will be able to run")
				idmapSet = nil
			}
		}
	}
	return idmapSet
}

// RuntimeLiblxcVersionAtLeast checks if the system's liblxc matches the
// provided version requirement
func RuntimeLiblxcVersionAtLeast(major int, minor int, micro int) bool {
	version := golxc.Version()
	version = strings.Replace(version, " (devel)", "-devel", 1)
	parts := strings.Split(version, ".")
	partsLen := len(parts)
	if partsLen == 0 {
		return false
	}

	develParts := strings.Split(parts[partsLen-1], "-")
	if len(develParts) == 2 && develParts[1] == "devel" {
		return true
	}

	maj := -1
	min := -1
	mic := -1

	for i, v := range parts {
		if i > 2 {
			break
		}

		num, err := strconv.Atoi(v)
		if err != nil {
			return false
		}

		switch i {
		case 0:
			maj = num
		case 1:
			min = num
		case 2:
			mic = num
		}
	}

	/* Major version is greater. */
	if maj > major {
		return true
	}

	if maj < major {
		return false
	}

	/* Minor number is greater.*/
	if min > minor {
		return true
	}

	if min < minor {
		return false
	}

	/* Patch number is greater. */
	if mic > micro {
		return true
	}

	if mic < micro {
		return false
	}

	return true
}

// GetExecPath returns the path to the current binary
func GetExecPath() string {
	execPath := os.Getenv("LXD_EXEC_PATH")
	if execPath != "" {
		return execPath
	}

	execPath, err := os.Readlink("/proc/self/exe")
	if err != nil {
		execPath = "bad-exec-path"
	}
	return execPath
}
<commit_msg>lxd/util: Restrict sys.go to LXD itself<commit_after>// +build linux,cgo,!agent

package util

import (
	"fmt"
	"os"
	"strconv"
	"strings"

	log "github.com/lxc/lxd/shared/log15"
	golxc "gopkg.in/lxc/go-lxc.v2"

	"github.com/lxc/lxd/shared/idmap"
	"github.com/lxc/lxd/shared/logger"
	"github.com/lxc/lxd/shared/osarch"
)

// GetArchitectures returns the list of supported architectures.
func GetArchitectures() ([]int, error) {
	architectures := []int{}

	architectureName, err := osarch.ArchitectureGetLocal()
	if err != nil {
		return nil, err
	}

	architecture, err := osarch.ArchitectureId(architectureName)
	if err != nil {
		return nil, err
	}
	architectures = append(architectures, architecture)

	personalities, err := osarch.ArchitecturePersonalities(architecture)
	if err != nil {
		return nil, err
	}
	for _, personality := range personalities {
		architectures = append(architectures, personality)
	}
	return architectures, nil
}

// GetIdmapSet reads the uid/gid allocation.
func GetIdmapSet() *idmap.IdmapSet {
	idmapSet, err := idmap.DefaultIdmapSet("", "")
	if err != nil {
		logger.Warn("Error reading default uid/gid map", log.Ctx{"err": err.Error()})
		logger.Warnf("Only privileged containers will be able to run")
		idmapSet = nil
	} else {
		kernelIdmapSet, err := idmap.CurrentIdmapSet()
		if err == nil {
			logger.Infof("Kernel uid/gid map:")
			for _, lxcmap := range kernelIdmapSet.ToLxcString() {
				logger.Infof(fmt.Sprintf(" - %s", lxcmap))
			}
		}

		if len(idmapSet.Idmap) == 0 {
			logger.Warnf("No available uid/gid map could be found")
			logger.Warnf("Only privileged containers will be able to run")
			idmapSet = nil
		} else {
			logger.Infof("Configured LXD uid/gid map:")
			for _, lxcmap := range idmapSet.Idmap {
				suffix := ""

				if lxcmap.Usable() != nil {
					suffix = " (unusable)"
				}

				for _, lxcEntry := range lxcmap.ToLxcString() {
					logger.Infof(" - %s%s", lxcEntry, suffix)
				}
			}

			err = idmapSet.Usable()
			if err != nil {
				logger.Warnf("One or more uid/gid map entry isn't usable (typically due to nesting)")
				logger.Warnf("Only privileged containers will be able to run")
				idmapSet = nil
			}
		}
	}
	return idmapSet
}

// RuntimeLiblxcVersionAtLeast checks if the system's liblxc matches the
// provided version requirement
func RuntimeLiblxcVersionAtLeast(major int, minor int, micro int) bool {
	version := golxc.Version()
	version = strings.Replace(version, " (devel)", "-devel", 1)
	parts := strings.Split(version, ".")
	partsLen := len(parts)
	if partsLen == 0 {
		return false
	}

	develParts := strings.Split(parts[partsLen-1], "-")
	if len(develParts) == 2 && develParts[1] == "devel" {
		return true
	}

	maj := -1
	min := -1
	mic := -1

	for i, v := range parts {
		if i > 2 {
			break
		}

		num, err := strconv.Atoi(v)
		if err != nil {
			return false
		}

		switch i {
		case 0:
			maj = num
		case 1:
			min = num
		case 2:
			mic = num
		}
	}

	/* Major version is greater. */
	if maj > major {
		return true
	}

	if maj < major {
		return false
	}

	/* Minor number is greater.*/
	if min > minor {
		return true
	}

	if min < minor {
		return false
	}

	/* Patch number is greater. */
	if mic > micro {
		return true
	}

	if mic < micro {
		return false
	}

	return true
}

// GetExecPath returns the path to the current binary
func GetExecPath() string {
	execPath := os.Getenv("LXD_EXEC_PATH")
	if execPath != "" {
		return execPath
	}

	execPath, err := os.Readlink("/proc/self/exe")
	if err != nil {
		execPath = "bad-exec-path"
	}
	return execPath
}
<|endoftext|>


<commit_before>package mapper

import (
  "fmt"
  "git.aviuslabs.net/golang/async"
  "testing"
)

func TestMapString(t *testing.T) {
  str := []string{
    "test",
    "test2",
    "test3",
    "test4",
    "test5",
  }

  mapper := func(done async.Done, args ...interface{}) {
    println("Hit string")
    fmt.Printf("Args: %+v\n", args)
    done(nil, args...)
  }

  final := func(err error, results ...interface{}) {
    println("Hit string end")
    fmt.Printf("Results: %+v\n", results)
  }

  Map(str, mapper, final)
}

func TestMapInt(t *testing.T) {
  ints := []int{
    1, 2, 3, 4, 5,
  }

  mapper := func(done async.Done, args ...interface{}) {
    println("Hit bool")
    fmt.Printf("Args: %+v\n", args)
    done(nil, args...)
  }

  final := func(err error, results ...interface{}) {
    println("Hit string end")
    fmt.Printf("Results: %+v\n", results)
  }

  Map(ints, mapper, final)
}

func TestMapBool(t *testing.T) {
  bools := []bool{
    true, false, false, true, false,
  }

  mapper := func(done async.Done, args ...interface{}) {
    println("Hit bool")
    fmt.Printf("Args: %+v\n", args)
    done(nil, args...)
  }

  final := func(err error, results ...interface{}) {
    println("Hit string end")
    fmt.Printf("Results: %+v\n", results)
  }

  Map(bools, mapper, final)
}
<commit_msg>Change some miswording in the map test<commit_after>package mapper

import (
  "fmt"
  "git.aviuslabs.net/golang/async"
  "testing"
)

func TestMapString(t *testing.T) {
  str := []string{
    "test",
    "test2",
    "test3",
    "test4",
    "test5",
  }

  mapper := func(done async.Done, args ...interface{}) {
    println("Hit string")
    fmt.Printf("Args: %+v\n", args)
    done(nil, args...)
  }

  final := func(err error, results ...interface{}) {
    println("Hit string end")
    fmt.Printf("Results: %+v\n", results)
  }

  Map(str, mapper, final)
}

func TestMapInt(t *testing.T) {
  ints := []int{1, 2, 3, 4, 5}

  mapper := func(done async.Done, args ...interface{}) {
    println("Hit int")
    fmt.Printf("Args: %+v\n", args)
    done(nil, args...)
  }

  final := func(err error, results ...interface{}) {
    println("Hit int end")
    fmt.Printf("Results: %+v\n", results)
  }

  Map(ints, mapper, final)
}

func TestMapBool(t *testing.T) {
  bools := []bool{true, false, false, true, false}

  mapper := func(done async.Done, args ...interface{}) {
    println("Hit bool")
    fmt.Printf("Args: %+v\n", args)
    done(nil, args...)
  }

  final := func(err error, results ...interface{}) {
    println("Hit bool end")
    fmt.Printf("Results: %+v\n", results)
  }

  Map(bools, mapper, final)
}
<|endoftext|>