<commit_before>// Copyright 2017 Hajime Hoshi
//
// 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 oto offers io.Writer to play sound on multiple platforms.
package oto

import (
	"time"
)

// Player is a PCM (pulse-code modulation) audio player. It implements io.Writer, use Write method
// to play samples.
type Player struct {
	player         *player
	sampleRate     int
	channelNum     int
	bytesPerSample int
	bufferSize     int
}

// NewPlayer creates a new, ready-to-use Player.
//
// The sampleRate argument specifies the number of samples that should be played during one second.
// Usual numbers are 44100 or 48000.
//
// The channelNum argument specifies the number of channels. One channel is mono playback. Two
// channels are stereo playback. No other values are supported.
//
// The bytesPerSample argument specifies the number of bytes per sample per channel. The usual value
// is 2. Only values 1 and 2 are supported.
//
// The bufferSizeInBytes argument specifies the size of the buffer of the Player. This means, how
// many bytes can Player remember before actually playing them. Bigger buffer can reduce the number
// of Write calls, thus reducing CPU time. Smaller buffer enables more precise timing. The longest
// delay between when samples were written and when they started playing is equal to the size of the
// buffer.
func NewPlayer(sampleRate, channelNum, bytesPerSample, bufferSizeInBytes int) (*Player, error) {
	p, err := newPlayer(sampleRate, channelNum, bytesPerSample, bufferSizeInBytes)
	if err != nil {
		return nil, err
	}
	return &Player{
		player:         p,
		sampleRate:     sampleRate,
		channelNum:     channelNum,
		bytesPerSample: bytesPerSample,
		bufferSize:     bufferSizeInBytes,
	}, nil
}

func (p *Player) bytesPerSec() int {
	return p.sampleRate * p.channelNum * p.bytesPerSample
}

// SetUnderrunCallback sets a function which will be called whenever an underrun occurs. This is
// mostly for debugging and optimization purposes.
//
// Underrun occurs when not enough samples is written to the player in a certain amount of time and
// thus there's nothing to play. This usually happens when there's too much audio data processing,
// or the audio data processing code gets stuck for a while, or the player's buffer is too small.
//
// Example:
//
//   player.SetUnderrunCallback(func() {
//       log.Println("UNDERRUN, YOUR CODE IS SLOW")
//   })
//
// Supported platforms: Linux.
func (p *Player) SetUnderrunCallback(f func()) {
	p.player.SetUnderrunCallback(f)
}

// Write writes PCM samples to the Player.
//
// The format is as follows:
//   [data]      = [sample 1] [sample 2] [sample 3] ...
//   [sample *]  = [channel 1] ...
//   [channel *] = [byte 1] [byte 2] ...
// Byte ordering is little endian.
//
// The data is first put into the Player's buffer. Once the buffer is full, Player starts playing
// the data and empties the buffer.
//
// If the supplied data doesn't fit into the Player's buffer, Write block until a sufficient amount
// of data has been played (or at least started playing) and the remaining unplayed data fits into
// the buffer.
//
// Note, that the Player won't start playing anything until the buffer is full.
func (p *Player) Write(data []byte) (int, error) {
	written := 0
	total := len(data)
	for written < total {
		n, err := p.player.Write(data)
		written += n
		if err != nil {
			return written, err
		}
		data = data[n:]
		// When not all data is written, the underlying buffer is full.
		// Mitigate the busy loop by sleeping (#10).
		if len(data) > 0 {
			t := time.Second * time.Duration(p.bufferSize) / time.Duration(p.bytesPerSec()) / 4
			time.Sleep(t)
		}
	}
	return written, nil
}

// Close closes the Player and frees any resources associated with it. The Player is no longer
// usable after calling Close.
func (p *Player) Close() error {
	return p.player.Close()
}

func max(a, b int) int {
	if a < b {
		return b
	}
	return a
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}
<commit_msg>Refactoring<commit_after>// Copyright 2017 Hajime Hoshi
//
// 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 oto offers io.Writer to play sound on multiple platforms.
package oto

import (
	"time"
)

// Player is a PCM (pulse-code modulation) audio player. It implements io.Writer, use Write method
// to play samples.
type Player struct {
	player         *player
	sampleRate     int
	channelNum     int
	bytesPerSample int
	bufferSize     int
}

// NewPlayer creates a new, ready-to-use Player.
//
// The sampleRate argument specifies the number of samples that should be played during one second.
// Usual numbers are 44100 or 48000.
//
// The channelNum argument specifies the number of channels. One channel is mono playback. Two
// channels are stereo playback. No other values are supported.
//
// The bytesPerSample argument specifies the number of bytes per sample per channel. The usual value
// is 2. Only values 1 and 2 are supported.
//
// The bufferSizeInBytes argument specifies the size of the buffer of the Player. This means, how
// many bytes can Player remember before actually playing them. Bigger buffer can reduce the number
// of Write calls, thus reducing CPU time. Smaller buffer enables more precise timing. The longest
// delay between when samples were written and when they started playing is equal to the size of the
// buffer.
func NewPlayer(sampleRate, channelNum, bytesPerSample, bufferSizeInBytes int) (*Player, error) {
	p, err := newPlayer(sampleRate, channelNum, bytesPerSample, bufferSizeInBytes)
	if err != nil {
		return nil, err
	}
	return &Player{
		player:         p,
		sampleRate:     sampleRate,
		channelNum:     channelNum,
		bytesPerSample: bytesPerSample,
		bufferSize:     bufferSizeInBytes,
	}, nil
}

func (p *Player) bytesPerSec() int {
	return p.sampleRate * p.channelNum * p.bytesPerSample
}

// SetUnderrunCallback sets a function which will be called whenever an underrun occurs. This is
// mostly for debugging and optimization purposes.
//
// Underrun occurs when not enough samples is written to the player in a certain amount of time and
// thus there's nothing to play. This usually happens when there's too much audio data processing,
// or the audio data processing code gets stuck for a while, or the player's buffer is too small.
//
// Example:
//
//   player.SetUnderrunCallback(func() {
//       log.Println("UNDERRUN, YOUR CODE IS SLOW")
//   })
//
// Supported platforms: Linux.
func (p *Player) SetUnderrunCallback(f func()) {
	p.player.SetUnderrunCallback(f)
}

// Write writes PCM samples to the Player.
//
// The format is as follows:
//   [data]      = [sample 1] [sample 2] [sample 3] ...
//   [sample *]  = [channel 1] ...
//   [channel *] = [byte 1] [byte 2] ...
// Byte ordering is little endian.
//
// The data is first put into the Player's buffer. Once the buffer is full, Player starts playing
// the data and empties the buffer.
//
// If the supplied data doesn't fit into the Player's buffer, Write block until a sufficient amount
// of data has been played (or at least started playing) and the remaining unplayed data fits into
// the buffer.
//
// Note, that the Player won't start playing anything until the buffer is full.
func (p *Player) Write(data []byte) (int, error) {
	written := 0
	for len(data) > 0 {
		n, err := p.player.Write(data)
		written += n
		if err != nil {
			return written, err
		}
		data = data[n:]
		// When not all data is written, the underlying buffer is full.
		// Mitigate the busy loop by sleeping (#10).
		if len(data) > 0 {
			t := time.Second * time.Duration(p.bufferSize) / time.Duration(p.bytesPerSec()) / 4
			time.Sleep(t)
		}
	}
	return written, nil
}

// Close closes the Player and frees any resources associated with it. The Player is no longer
// usable after calling Close.
func (p *Player) Close() error {
	return p.player.Close()
}

func max(a, b int) int {
	if a < b {
		return b
	}
	return a
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}
<|endoftext|>


<commit_before>// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build darwin freebsd linux netbsd openbsd

package test

// functional test harness for unix.

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"testing"
	"text/template"

	"code.google.com/p/go.crypto/ssh"
	"code.google.com/p/go.crypto/ssh/testdata"
)

const sshd_config = `
Protocol 2
HostKey {{.Dir}}/id_rsa
HostKey {{.Dir}}/id_dsa
HostKey {{.Dir}}/id_ecdsa
Pidfile {{.Dir}}/sshd.pid
#UsePrivilegeSeparation no
KeyRegenerationInterval 3600
ServerKeyBits 768
SyslogFacility AUTH
LogLevel DEBUG2
LoginGraceTime 120
PermitRootLogin no
StrictModes no
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile	{{.Dir}}/id_user.pub
TrustedUserCAKeys {{.Dir}}/id_ecdsa.pub
IgnoreRhosts yes
RhostsRSAAuthentication no
HostbasedAuthentication no
`

var configTmpl = template.Must(template.New("").Parse(sshd_config))

type server struct {
	t          *testing.T
	cleanup    func() // executed during Shutdown
	configfile string
	cmd        *exec.Cmd
	output     bytes.Buffer // holds stderr from sshd process

	// Client half of the network connection.
	clientConn net.Conn
}

func username() string {
	var username string
	if user, err := user.Current(); err == nil {
		username = user.Username
	} else {
		// user.Current() currently requires cgo. If an error is
		// returned attempt to get the username from the environment.
		log.Printf("user.Current: %v; falling back on $USER", err)
		username = os.Getenv("USER")
	}
	if username == "" {
		panic("Unable to get username")
	}
	return username
}

type storedHostKey struct {
	// keys map from an algorithm string to binary key data.
	keys map[string][]byte

	// checkCount counts the Check calls. Used for testing
	// rekeying.
	checkCount int
}

func (k *storedHostKey) Add(key ssh.PublicKey) {
	if k.keys == nil {
		k.keys = map[string][]byte{}
	}
	k.keys[key.Type()] = key.Marshal()
}

func (k *storedHostKey) Check(addr string, remote net.Addr, key ssh.PublicKey) error {
	k.checkCount++
	algo := key.Type()

	if k.keys == nil || bytes.Compare(key.Marshal(), k.keys[algo]) != 0 {
		return fmt.Errorf("host key mismatch. Got %q, want %q", key, k.keys[algo])
	}
	return nil
}

func hostKeyDB() *storedHostKey {
	keyChecker := &storedHostKey{}
	keyChecker.Add(testPublicKeys["ecdsa"])
	keyChecker.Add(testPublicKeys["rsa"])
	keyChecker.Add(testPublicKeys["dsa"])
	return keyChecker
}

func clientConfig() *ssh.ClientConfig {
	config := &ssh.ClientConfig{
		User: username(),
		Auth: []ssh.AuthMethod{
			ssh.PublicKeys(testSigners["user"]),
		},
		HostKeyCallback: hostKeyDB().Check,
	}
	return config
}

// unixConnection creates two halves of a connected net.UnixConn.  It
// is used for connecting the Go SSH client with sshd without opening
// ports.
func unixConnection() (*net.UnixConn, *net.UnixConn, error) {
	dir, err := ioutil.TempDir("", "unixConnection")
	if err != nil {
		return nil, nil, err
	}
	defer os.Remove(dir)

	addr := filepath.Join(dir, "ssh")
	listener, err := net.Listen("unix", addr)
	if err != nil {
		return nil, nil, err
	}
	defer listener.Close()
	c1, err := net.Dial("unix", addr)
	if err != nil {
		return nil, nil, err
	}

	c2, err := listener.Accept()
	if err != nil {
		c1.Close()
		return nil, nil, err
	}

	return c1.(*net.UnixConn), c2.(*net.UnixConn), nil
}

func (s *server) TryDial(config *ssh.ClientConfig) (*ssh.Client, error) {
	sshd, err := exec.LookPath("sshd")
	if err != nil {
		s.t.Skipf("skipping test: %v", err)
	}

	c1, c2, err := unixConnection()
	if err != nil {
		s.t.Fatalf("unixConnection: %v", err)
	}

	s.cmd = exec.Command(sshd, "-f", s.configfile, "-i", "-e")
	f, err := c2.File()
	if err != nil {
		s.t.Fatalf("UnixConn.File: %v", err)
	}
	defer f.Close()
	s.cmd.Stdin = f
	s.cmd.Stdout = f
	s.cmd.Stderr = &s.output
	if err := s.cmd.Start(); err != nil {
		s.t.Fail()
		s.Shutdown()
		s.t.Fatalf("s.cmd.Start: %v", err)
	}
	s.clientConn = c1
	conn, chans, reqs, err := ssh.NewClientConn(c1, "", config)
	if err != nil {
		return nil, err
	}
	return ssh.NewClient(conn, chans, reqs), nil
}

func (s *server) Dial(config *ssh.ClientConfig) *ssh.Client {
	conn, err := s.TryDial(config)
	if err != nil {
		s.t.Fail()
		s.Shutdown()
		s.t.Fatalf("ssh.Client: %v", err)
	}
	return conn
}

func (s *server) Shutdown() {
	if s.cmd != nil && s.cmd.Process != nil {
		// Don't check for errors; if it fails it's most
		// likely "os: process already finished", and we don't
		// care about that. Use os.Interrupt, so child
		// processes are killed too.
		s.cmd.Process.Signal(os.Interrupt)
		s.cmd.Wait()
	}
	if s.t.Failed() {
		// log any output from sshd process
		s.t.Logf("sshd: %s", s.output.String())
	}
	s.cleanup()
}

func writeFile(path string, contents []byte) {
	f, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0600)
	if err != nil {
		panic(err)
	}
	defer f.Close()
	if _, err := f.Write(contents); err != nil {
		panic(err)
	}
}

// newServer returns a new mock ssh server.
func newServer(t *testing.T) *server {
	dir, err := ioutil.TempDir("", "sshtest")
	if err != nil {
		t.Fatal(err)
	}
	f, err := os.Create(filepath.Join(dir, "sshd_config"))
	if err != nil {
		t.Fatal(err)
	}
	err = configTmpl.Execute(f, map[string]string{
		"Dir": dir,
	})
	if err != nil {
		t.Fatal(err)
	}
	f.Close()

	for k, v := range testdata.PEMBytes {
		filename := "id_" + k
		writeFile(filepath.Join(dir, filename), v)
		writeFile(filepath.Join(dir, filename+".pub"), ssh.MarshalAuthorizedKey(testPublicKeys[k]))
	}

	return &server{
		t:          t,
		configfile: f.Name(),
		cleanup: func() {
			if err := os.RemoveAll(dir); err != nil {
				t.Error(err)
			}
		},
	}
}
<commit_msg>go.crypto/ssh: build test_unix_test on Plan 9<commit_after>// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build darwin freebsd linux netbsd openbsd plan9

package test

// functional test harness for unix.

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"net"
	"os"
	"os/exec"
	"os/user"
	"path/filepath"
	"testing"
	"text/template"

	"code.google.com/p/go.crypto/ssh"
	"code.google.com/p/go.crypto/ssh/testdata"
)

const sshd_config = `
Protocol 2
HostKey {{.Dir}}/id_rsa
HostKey {{.Dir}}/id_dsa
HostKey {{.Dir}}/id_ecdsa
Pidfile {{.Dir}}/sshd.pid
#UsePrivilegeSeparation no
KeyRegenerationInterval 3600
ServerKeyBits 768
SyslogFacility AUTH
LogLevel DEBUG2
LoginGraceTime 120
PermitRootLogin no
StrictModes no
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile	{{.Dir}}/id_user.pub
TrustedUserCAKeys {{.Dir}}/id_ecdsa.pub
IgnoreRhosts yes
RhostsRSAAuthentication no
HostbasedAuthentication no
`

var configTmpl = template.Must(template.New("").Parse(sshd_config))

type server struct {
	t          *testing.T
	cleanup    func() // executed during Shutdown
	configfile string
	cmd        *exec.Cmd
	output     bytes.Buffer // holds stderr from sshd process

	// Client half of the network connection.
	clientConn net.Conn
}

func username() string {
	var username string
	if user, err := user.Current(); err == nil {
		username = user.Username
	} else {
		// user.Current() currently requires cgo. If an error is
		// returned attempt to get the username from the environment.
		log.Printf("user.Current: %v; falling back on $USER", err)
		username = os.Getenv("USER")
	}
	if username == "" {
		panic("Unable to get username")
	}
	return username
}

type storedHostKey struct {
	// keys map from an algorithm string to binary key data.
	keys map[string][]byte

	// checkCount counts the Check calls. Used for testing
	// rekeying.
	checkCount int
}

func (k *storedHostKey) Add(key ssh.PublicKey) {
	if k.keys == nil {
		k.keys = map[string][]byte{}
	}
	k.keys[key.Type()] = key.Marshal()
}

func (k *storedHostKey) Check(addr string, remote net.Addr, key ssh.PublicKey) error {
	k.checkCount++
	algo := key.Type()

	if k.keys == nil || bytes.Compare(key.Marshal(), k.keys[algo]) != 0 {
		return fmt.Errorf("host key mismatch. Got %q, want %q", key, k.keys[algo])
	}
	return nil
}

func hostKeyDB() *storedHostKey {
	keyChecker := &storedHostKey{}
	keyChecker.Add(testPublicKeys["ecdsa"])
	keyChecker.Add(testPublicKeys["rsa"])
	keyChecker.Add(testPublicKeys["dsa"])
	return keyChecker
}

func clientConfig() *ssh.ClientConfig {
	config := &ssh.ClientConfig{
		User: username(),
		Auth: []ssh.AuthMethod{
			ssh.PublicKeys(testSigners["user"]),
		},
		HostKeyCallback: hostKeyDB().Check,
	}
	return config
}

// unixConnection creates two halves of a connected net.UnixConn.  It
// is used for connecting the Go SSH client with sshd without opening
// ports.
func unixConnection() (*net.UnixConn, *net.UnixConn, error) {
	dir, err := ioutil.TempDir("", "unixConnection")
	if err != nil {
		return nil, nil, err
	}
	defer os.Remove(dir)

	addr := filepath.Join(dir, "ssh")
	listener, err := net.Listen("unix", addr)
	if err != nil {
		return nil, nil, err
	}
	defer listener.Close()
	c1, err := net.Dial("unix", addr)
	if err != nil {
		return nil, nil, err
	}

	c2, err := listener.Accept()
	if err != nil {
		c1.Close()
		return nil, nil, err
	}

	return c1.(*net.UnixConn), c2.(*net.UnixConn), nil
}

func (s *server) TryDial(config *ssh.ClientConfig) (*ssh.Client, error) {
	sshd, err := exec.LookPath("sshd")
	if err != nil {
		s.t.Skipf("skipping test: %v", err)
	}

	c1, c2, err := unixConnection()
	if err != nil {
		s.t.Fatalf("unixConnection: %v", err)
	}

	s.cmd = exec.Command(sshd, "-f", s.configfile, "-i", "-e")
	f, err := c2.File()
	if err != nil {
		s.t.Fatalf("UnixConn.File: %v", err)
	}
	defer f.Close()
	s.cmd.Stdin = f
	s.cmd.Stdout = f
	s.cmd.Stderr = &s.output
	if err := s.cmd.Start(); err != nil {
		s.t.Fail()
		s.Shutdown()
		s.t.Fatalf("s.cmd.Start: %v", err)
	}
	s.clientConn = c1
	conn, chans, reqs, err := ssh.NewClientConn(c1, "", config)
	if err != nil {
		return nil, err
	}
	return ssh.NewClient(conn, chans, reqs), nil
}

func (s *server) Dial(config *ssh.ClientConfig) *ssh.Client {
	conn, err := s.TryDial(config)
	if err != nil {
		s.t.Fail()
		s.Shutdown()
		s.t.Fatalf("ssh.Client: %v", err)
	}
	return conn
}

func (s *server) Shutdown() {
	if s.cmd != nil && s.cmd.Process != nil {
		// Don't check for errors; if it fails it's most
		// likely "os: process already finished", and we don't
		// care about that. Use os.Interrupt, so child
		// processes are killed too.
		s.cmd.Process.Signal(os.Interrupt)
		s.cmd.Wait()
	}
	if s.t.Failed() {
		// log any output from sshd process
		s.t.Logf("sshd: %s", s.output.String())
	}
	s.cleanup()
}

func writeFile(path string, contents []byte) {
	f, err := os.OpenFile(path, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, 0600)
	if err != nil {
		panic(err)
	}
	defer f.Close()
	if _, err := f.Write(contents); err != nil {
		panic(err)
	}
}

// newServer returns a new mock ssh server.
func newServer(t *testing.T) *server {
	dir, err := ioutil.TempDir("", "sshtest")
	if err != nil {
		t.Fatal(err)
	}
	f, err := os.Create(filepath.Join(dir, "sshd_config"))
	if err != nil {
		t.Fatal(err)
	}
	err = configTmpl.Execute(f, map[string]string{
		"Dir": dir,
	})
	if err != nil {
		t.Fatal(err)
	}
	f.Close()

	for k, v := range testdata.PEMBytes {
		filename := "id_" + k
		writeFile(filepath.Join(dir, filename), v)
		writeFile(filepath.Join(dir, filename+".pub"), ssh.MarshalAuthorizedKey(testPublicKeys[k]))
	}

	return &server{
		t:          t,
		configfile: f.Name(),
		cleanup: func() {
			if err := os.RemoveAll(dir); err != nil {
				t.Error(err)
			}
		},
	}
}
<|endoftext|>


<commit_before>package lib

import (
	"strconv"

	"github.com/BytemarkHosting/bytemark-client/lib/brain"
)

type UpdateHead struct {
	UsageStrategy   *string
	OvercommitRatio *int
	Label           *string
}

type UpdateTail struct {
	UsageStrategy   *string
	OvercommitRatio *int
	Label           *string
}

type UpdateStoragePool struct {
	UsageStrategy   *string
	OvercommitRatio *int
	Label           *string
}

func (c *bytemarkClient) GetVLANs() (vlans []*brain.VLAN, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/vlans")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &vlans)
	return
}

func (c *bytemarkClient) GetVLAN(num int) (vlan *brain.VLAN, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/vlans/%s", strconv.Itoa(num))
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &vlan)
	return
}

func (c *bytemarkClient) GetIPRanges() (ipRanges []*brain.IPRange, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/ip_ranges")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &ipRanges)
	return
}

func (c *bytemarkClient) GetIPRange(id int) (ipRange *brain.IPRange, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/ip_ranges/%s", strconv.Itoa(id))
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &ipRange)
	return
}

func (c *bytemarkClient) GetHeads() (heads []*brain.Head, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/heads")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &heads)
	return
}

func (c *bytemarkClient) GetHead(idOrLabel string) (head *brain.Head, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/heads/%s", idOrLabel)
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &head)
	return
}

func (c *bytemarkClient) GetTails() (tails []*brain.Tail, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/tails")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &tails)
	return
}

func (c *bytemarkClient) GetTail(idOrLabel string) (tail *brain.Tail, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/tails/%s", idOrLabel)
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &tail)
	return
}

func (c *bytemarkClient) GetStoragePools() (storagePools []*brain.StoragePool, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/storage_pools")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &storagePools)
	return
}

func (c *bytemarkClient) GetStoragePool(idOrLabel string) (storagePool *brain.StoragePool, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/storage_pools/%s", idOrLabel)
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &storagePool)
	return
}

func (c *bytemarkClient) GetMigratingVMs() (vms []*brain.VirtualMachine, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/migrating_vms")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &vms)
	return
}

func (c *bytemarkClient) GetStoppedEligibleVMs() (vms []*brain.VirtualMachine, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/stopped_eligible_vms")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &vms)
	return
}

func (c *bytemarkClient) GetRecentVMs() (vms []*brain.VirtualMachine, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/recent_vms")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &vms)
	return
}

func (c *bytemarkClient) MigrateDisc(disc int, newStoragePool string) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/discs/%s/migrate", strconv.Itoa(disc))
	if err != nil {
		return
	}

	params := map[string]string{}
	if newStoragePool != "" {
		params["new_pool_spec"] = newStoragePool
	}

	_, _, err = r.MarshalAndRun(params, nil)
	return
}

func (c *bytemarkClient) MigrateVirtualMachine(vmName *VirtualMachineName, newHead string) (err error) {
	vm, err := c.GetVirtualMachine(vmName)
	if err != nil {
		return err
	}

	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/vms/%s/migrate", strconv.Itoa(vm.ID))
	if err != nil {
		return
	}

	params := map[string]string{}
	if newHead != "" {
		params["new_head_spec"] = newHead
	}

	_, _, err = r.MarshalAndRun(params, nil)
	return
}

func (c *bytemarkClient) ReapVMs() (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/reap_vms")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, nil)
	return
}

func (c *bytemarkClient) DeleteVLAN(id int) (err error) {
	r, err := c.BuildRequest("DELETE", BrainEndpoint, "/admin/vlans/%s", strconv.Itoa(id))
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, nil)
	return
}

func (c *bytemarkClient) AdminCreateGroup(name *GroupName, vlanNum int) (err error) {
	err = c.validateGroupName(name)
	if err != nil {
		return
	}

	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/groups")
	if err != nil {
		return
	}

	obj := map[string]interface{}{
		"account_spec": name.Account,
		"group_name":   name.Group,
	}

	if vlanNum != 0 {
		obj["vlan_num"] = vlanNum
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) CreateIPRange(ipRange string, vlanNum int) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/ip_ranges")
	if err != nil {
		return
	}

	obj := map[string]interface{}{
		"ip_range": ipRange,
		"vlan_num": vlanNum,
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) CancelDiscMigration(id int) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/discs/%s/cancel_migration", strconv.Itoa(id))
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, nil)
	return
}

func (c *bytemarkClient) CancelVMMigration(id int) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/vms/%s/cancel_migration", strconv.Itoa(id))
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, nil)
	return
}

func (c *bytemarkClient) EmptyStoragePool(idOrLabel string) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/storage_pools/%s/empty", idOrLabel)
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, nil)
	return
}

func (c *bytemarkClient) EmptyHead(idOrLabel string) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/heads/%s/empty", idOrLabel)
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, nil)
	return
}

func (c *bytemarkClient) ReifyDisc(id int) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/discs/%s/reify", strconv.Itoa(id))
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, nil)
	return
}

func (c *bytemarkClient) ApproveVM(name *VirtualMachineName, powerOn bool) (err error) {
	vm, err := c.GetVirtualMachine(name)
	if err != nil {
		return err
	}

	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/vms/%s/approve", strconv.Itoa(vm.ID))
	if err != nil {
		return
	}

	obj := map[string]bool{}
	if powerOn {
		obj["power_on"] = powerOn
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) RejectVM(name *VirtualMachineName, reason string) (err error) {
	vm, err := c.GetVirtualMachine(name)
	if err != nil {
		return err
	}

	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/vms/%s/reject", strconv.Itoa(vm.ID))
	if err != nil {
		return
	}

	obj := map[string]string{
		"reason": reason,
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) RegradeDisc(disc int, newGrade string) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/discs/%s/regrade", strconv.Itoa(disc))
	if err != nil {
		return
	}

	obj := map[string]string{
		"new_grade": newGrade,
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) UpdateVMMigration(name *VirtualMachineName, speed *int64, downtime *int) (err error) {
	vm, err := c.GetVirtualMachine(name)
	if err != nil {
		return err
	}

	r, err := c.BuildRequest("PUT", BrainEndpoint, "/admin/vms/%s/migrate", strconv.Itoa(vm.ID))
	if err != nil {
		return
	}

	obj := map[string]interface{}{}
	if speed != nil {
		obj["migration_speed"] = *speed
	}
	if downtime != nil {
		obj["migration_downtime"] = *downtime
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) CreateUser(username string, privilege string) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/users")
	if err != nil {
		return
	}

	obj := map[string]string{
		"username":  username,
		"priv_spec": privilege,
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) UpdateHead(idOrLabel string, options *UpdateHead) (err error) {
	r, err := c.BuildRequest("PUT", BrainEndpoint, "/admin/heads/%s", idOrLabel)
	if err != nil {
		return
	}

	obj := map[string]interface{}{}

	if options.OvercommitRatio != nil {
		obj["overcommit_ratio"] = *options.OvercommitRatio
	}
	if options.Label != nil {
		obj["label"] = *options.Label
	}
	if options.UsageStrategy != nil {
		// It is set, but we need to translate an empty string to nil
		if *options.UsageStrategy == "" {
			obj["usage_strategy"] = nil
		} else {
			obj["usage_strategy"] = *options.UsageStrategy
		}
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) UpdateTail(idOrLabel string, options *UpdateTail) (err error) {
	r, err := c.BuildRequest("PUT", BrainEndpoint, "/admin/tails/%s", idOrLabel)
	if err != nil {
		return
	}

	obj := map[string]interface{}{}

	if options.OvercommitRatio != nil {
		obj["overcommit_ratio"] = *options.OvercommitRatio
	}
	if options.Label != nil {
		obj["label"] = *options.Label
	}
	if options.UsageStrategy != nil {
		// It is set, but we need to translate an empty string to nil
		if *options.UsageStrategy == "" {
			obj["usage_strategy"] = nil
		} else {
			obj["usage_strategy"] = *options.UsageStrategy
		}
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) UpdateStoragePool(idOrLabel string, options *UpdateStoragePool) (err error) {
	r, err := c.BuildRequest("PUT", BrainEndpoint, "/admin/storage_pools/%s", idOrLabel)
	if err != nil {
		return
	}

	obj := map[string]interface{}{}

	if options.OvercommitRatio != nil {
		obj["overcommit_ratio"] = *options.OvercommitRatio
	}
	if options.Label != nil {
		obj["label"] = *options.Label
	}
	if options.UsageStrategy != nil {
		// It is set, but we need to translate an empty string to nil
		if *options.UsageStrategy == "" {
			obj["usage_strategy"] = nil
		} else {
			obj["usage_strategy"] = *options.UsageStrategy
		}
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}
<commit_msg>Comments to satisfy the linter<commit_after>package lib

import (
	"strconv"

	"github.com/BytemarkHosting/bytemark-client/lib/brain"
)

// UpdateHead is a struct with all the possible settings that can be updated on a head
type UpdateHead struct {
	UsageStrategy   *string
	OvercommitRatio *int
	Label           *string
}

// UpdateTail is a struct with all the possible settings that can be updated on a tail
type UpdateTail struct {
	UsageStrategy   *string
	OvercommitRatio *int
	Label           *string
}

// UpdateStoragePool is a struct with all the possible settings that can be updated on a storage pool
type UpdateStoragePool struct {
	UsageStrategy   *string
	OvercommitRatio *int
	Label           *string
}

func (c *bytemarkClient) GetVLANs() (vlans []*brain.VLAN, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/vlans")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &vlans)
	return
}

func (c *bytemarkClient) GetVLAN(num int) (vlan *brain.VLAN, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/vlans/%s", strconv.Itoa(num))
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &vlan)
	return
}

func (c *bytemarkClient) GetIPRanges() (ipRanges []*brain.IPRange, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/ip_ranges")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &ipRanges)
	return
}

func (c *bytemarkClient) GetIPRange(id int) (ipRange *brain.IPRange, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/ip_ranges/%s", strconv.Itoa(id))
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &ipRange)
	return
}

func (c *bytemarkClient) GetHeads() (heads []*brain.Head, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/heads")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &heads)
	return
}

func (c *bytemarkClient) GetHead(idOrLabel string) (head *brain.Head, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/heads/%s", idOrLabel)
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &head)
	return
}

func (c *bytemarkClient) GetTails() (tails []*brain.Tail, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/tails")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &tails)
	return
}

func (c *bytemarkClient) GetTail(idOrLabel string) (tail *brain.Tail, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/tails/%s", idOrLabel)
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &tail)
	return
}

func (c *bytemarkClient) GetStoragePools() (storagePools []*brain.StoragePool, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/storage_pools")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &storagePools)
	return
}

func (c *bytemarkClient) GetStoragePool(idOrLabel string) (storagePool *brain.StoragePool, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/storage_pools/%s", idOrLabel)
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &storagePool)
	return
}

func (c *bytemarkClient) GetMigratingVMs() (vms []*brain.VirtualMachine, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/migrating_vms")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &vms)
	return
}

func (c *bytemarkClient) GetStoppedEligibleVMs() (vms []*brain.VirtualMachine, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/stopped_eligible_vms")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &vms)
	return
}

func (c *bytemarkClient) GetRecentVMs() (vms []*brain.VirtualMachine, err error) {
	r, err := c.BuildRequest("GET", BrainEndpoint, "/admin/recent_vms")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, &vms)
	return
}

func (c *bytemarkClient) MigrateDisc(disc int, newStoragePool string) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/discs/%s/migrate", strconv.Itoa(disc))
	if err != nil {
		return
	}

	params := map[string]string{}
	if newStoragePool != "" {
		params["new_pool_spec"] = newStoragePool
	}

	_, _, err = r.MarshalAndRun(params, nil)
	return
}

func (c *bytemarkClient) MigrateVirtualMachine(vmName *VirtualMachineName, newHead string) (err error) {
	vm, err := c.GetVirtualMachine(vmName)
	if err != nil {
		return err
	}

	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/vms/%s/migrate", strconv.Itoa(vm.ID))
	if err != nil {
		return
	}

	params := map[string]string{}
	if newHead != "" {
		params["new_head_spec"] = newHead
	}

	_, _, err = r.MarshalAndRun(params, nil)
	return
}

func (c *bytemarkClient) ReapVMs() (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/reap_vms")
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, nil)
	return
}

func (c *bytemarkClient) DeleteVLAN(id int) (err error) {
	r, err := c.BuildRequest("DELETE", BrainEndpoint, "/admin/vlans/%s", strconv.Itoa(id))
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, nil)
	return
}

func (c *bytemarkClient) AdminCreateGroup(name *GroupName, vlanNum int) (err error) {
	err = c.validateGroupName(name)
	if err != nil {
		return
	}

	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/groups")
	if err != nil {
		return
	}

	obj := map[string]interface{}{
		"account_spec": name.Account,
		"group_name":   name.Group,
	}

	if vlanNum != 0 {
		obj["vlan_num"] = vlanNum
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) CreateIPRange(ipRange string, vlanNum int) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/ip_ranges")
	if err != nil {
		return
	}

	obj := map[string]interface{}{
		"ip_range": ipRange,
		"vlan_num": vlanNum,
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) CancelDiscMigration(id int) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/discs/%s/cancel_migration", strconv.Itoa(id))
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, nil)
	return
}

func (c *bytemarkClient) CancelVMMigration(id int) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/vms/%s/cancel_migration", strconv.Itoa(id))
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, nil)
	return
}

func (c *bytemarkClient) EmptyStoragePool(idOrLabel string) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/storage_pools/%s/empty", idOrLabel)
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, nil)
	return
}

func (c *bytemarkClient) EmptyHead(idOrLabel string) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/heads/%s/empty", idOrLabel)
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, nil)
	return
}

func (c *bytemarkClient) ReifyDisc(id int) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/discs/%s/reify", strconv.Itoa(id))
	if err != nil {
		return
	}

	_, _, err = r.Run(nil, nil)
	return
}

func (c *bytemarkClient) ApproveVM(name *VirtualMachineName, powerOn bool) (err error) {
	vm, err := c.GetVirtualMachine(name)
	if err != nil {
		return err
	}

	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/vms/%s/approve", strconv.Itoa(vm.ID))
	if err != nil {
		return
	}

	obj := map[string]bool{}
	if powerOn {
		obj["power_on"] = powerOn
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) RejectVM(name *VirtualMachineName, reason string) (err error) {
	vm, err := c.GetVirtualMachine(name)
	if err != nil {
		return err
	}

	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/vms/%s/reject", strconv.Itoa(vm.ID))
	if err != nil {
		return
	}

	obj := map[string]string{
		"reason": reason,
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) RegradeDisc(disc int, newGrade string) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/discs/%s/regrade", strconv.Itoa(disc))
	if err != nil {
		return
	}

	obj := map[string]string{
		"new_grade": newGrade,
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) UpdateVMMigration(name *VirtualMachineName, speed *int64, downtime *int) (err error) {
	vm, err := c.GetVirtualMachine(name)
	if err != nil {
		return err
	}

	r, err := c.BuildRequest("PUT", BrainEndpoint, "/admin/vms/%s/migrate", strconv.Itoa(vm.ID))
	if err != nil {
		return
	}

	obj := map[string]interface{}{}
	if speed != nil {
		obj["migration_speed"] = *speed
	}
	if downtime != nil {
		obj["migration_downtime"] = *downtime
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) CreateUser(username string, privilege string) (err error) {
	r, err := c.BuildRequest("POST", BrainEndpoint, "/admin/users")
	if err != nil {
		return
	}

	obj := map[string]string{
		"username":  username,
		"priv_spec": privilege,
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) UpdateHead(idOrLabel string, options *UpdateHead) (err error) {
	r, err := c.BuildRequest("PUT", BrainEndpoint, "/admin/heads/%s", idOrLabel)
	if err != nil {
		return
	}

	obj := map[string]interface{}{}

	if options.OvercommitRatio != nil {
		obj["overcommit_ratio"] = *options.OvercommitRatio
	}
	if options.Label != nil {
		obj["label"] = *options.Label
	}
	if options.UsageStrategy != nil {
		// It is set, but we need to translate an empty string to nil
		if *options.UsageStrategy == "" {
			obj["usage_strategy"] = nil
		} else {
			obj["usage_strategy"] = *options.UsageStrategy
		}
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) UpdateTail(idOrLabel string, options *UpdateTail) (err error) {
	r, err := c.BuildRequest("PUT", BrainEndpoint, "/admin/tails/%s", idOrLabel)
	if err != nil {
		return
	}

	obj := map[string]interface{}{}

	if options.OvercommitRatio != nil {
		obj["overcommit_ratio"] = *options.OvercommitRatio
	}
	if options.Label != nil {
		obj["label"] = *options.Label
	}
	if options.UsageStrategy != nil {
		// It is set, but we need to translate an empty string to nil
		if *options.UsageStrategy == "" {
			obj["usage_strategy"] = nil
		} else {
			obj["usage_strategy"] = *options.UsageStrategy
		}
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}

func (c *bytemarkClient) UpdateStoragePool(idOrLabel string, options *UpdateStoragePool) (err error) {
	r, err := c.BuildRequest("PUT", BrainEndpoint, "/admin/storage_pools/%s", idOrLabel)
	if err != nil {
		return
	}

	obj := map[string]interface{}{}

	if options.OvercommitRatio != nil {
		obj["overcommit_ratio"] = *options.OvercommitRatio
	}
	if options.Label != nil {
		obj["label"] = *options.Label
	}
	if options.UsageStrategy != nil {
		// It is set, but we need to translate an empty string to nil
		if *options.UsageStrategy == "" {
			obj["usage_strategy"] = nil
		} else {
			obj["usage_strategy"] = *options.UsageStrategy
		}
	}

	_, _, err = r.MarshalAndRun(obj, nil)
	return
}
<|endoftext|>


<commit_before>// Copyright 2015 Mark Pundman
// Copyright 2015 Luke Shumaker
// Copyright 2015 Davis Webb

package cfg

import (
	"io"
	"io/ioutil"
	"locale"
	"maildir"
	"net/http"
	"os"
	"periwinkle"
	"periwinkle/domain_handlers"
	"postfixpipe"

	_ "github.com/go-sql-driver/mysql"
	"github.com/jinzhu/gorm"
	_ "github.com/mattn/go-sqlite3"
	yaml "gopkg.in/yaml.v2"
)

func gotoError(err locale.Error) {
	panic(err)
}

func Parse(in io.Reader) (cfgptr *periwinkle.Cfg, e locale.Error) {
	defer func() {
		if r := recover(); r != nil {
			cfgptr = nil
			switch err := r.(type) {
			case locale.Error:
				e = err
			default:
				panic(r)
			}
		}
	}()

	// these are the defaults
	cfg := periwinkle.Cfg{
		Mailstore:            "./Maildir",
		WebUIDir:             "./www",
		Debug:                true,
		TrustForwarded:       true,
		TwilioAccountID:      os.Getenv("TWILIO_ACCOUNTID"),
		TwilioAuthToken:      os.Getenv("TWILIO_TOKEN"),
		GroupDomain:          "localhost",
		WebRoot:              "locahost:8080",
		DB:                   nil, // the default DB is set later
		DefaultDomainHandler: bounceNoHost,
	}

	datstr, err := ioutil.ReadAll(in)
	if err != nil {
		gotoError(locale.UntranslatedError(err))
	}

	var datint interface{}
	err = yaml.Unmarshal(datstr, &datint)
	if err != nil {
		gotoError(locale.UntranslatedError(err))
	}

	datmap, ok := datint.(map[interface{}]interface{})
	if !ok {
		gotoError(locale.UntranslatedError(err))
	}

	for key, val := range datmap {
		switch key {
		case "Mailstore":
			cfg.Mailstore = maildir.Maildir(getString(key.(string), val))
		case "WebUIDir":
			cfg.WebUIDir = http.Dir(getString(key.(string), val))
		case "Debug":
			cfg.Debug = getBool(key.(string), val)
		case "TrustForwarded":
			cfg.TrustForwarded = getBool(key.(string), val)
		case "TwilioAccountID":
			cfg.TwilioAccountID = getString(key.(string), val)
		case "TwilioAuthToken":
			cfg.TwilioAuthToken = getString(key.(string), val)
		case "GroupDomain":
			cfg.GroupDomain = getString(key.(string), val)
		case "WebRoot":
			cfg.WebRoot = getString(key.(string), val)
		case "DB":
			m, ok := val.(map[interface{}]interface{})
			if !ok {
				gotoError(locale.Errorf("value for %q is not a map", key.(string)))
			}
			var driver string
			var source string
			for key, val := range m {
				switch key {
				case "driver":
					driver = getString("DB."+key.(string), val)
				case "source":
					source = getString("DB."+key.(string), val)
				default:
					gotoError(locale.Errorf("unknown field: %v", "DB."+key.(string)))
				}
			}
			db, err := openDB(driver, source)
			if err != nil {
				gotoError(err)
			}
			cfg.DB = db
		default:
			gotoError(locale.Errorf("unknown field: %v", key))
		}
	}

	// Set the default database
	if cfg.DB == nil {
		periwinkle.Logf("DB not configured, trying MySQL periwinkle:periwinkle@localhost/periwinkle")
		db, err := openDB("mysql", "periwinkle:periwinkle@/periwinkle?charset=utf8&parseTime=True")
		if err != nil {
			periwinkle.LogErr(locale.UntranslatedError(err))
			periwinkle.Logf("Failed to connect to MySQL, trying SQLite3 file:periwinkle.sqlite")
			db, err = openDB("sqlite3", "file:periwinkle.sqlite?mode=rwc&_txlock=exclusive")
			if err != nil {
				gotoError(locale.UntranslatedError(err))
			}
		}
		cfg.DB = db
	}

	cfg.DB.LogMode(cfg.Debug)

	domain_handlers.GetHandlers(&cfg)

	return &cfg, nil
}

func getString(key string, val interface{}) string {
	str, ok := val.(string)
	if !ok {
		gotoError(locale.Errorf("value for %q is not a string", key))
	}
	return str
}

func getBool(key string, val interface{}) bool {
	b, ok := val.(bool)
	if !ok {
		gotoError(locale.Errorf("value for %q is not a Boolean", key))
	}
	return b
}

func openDB(driver, source string) (*gorm.DB, locale.Error) {
	db, err := gorm.Open(driver, source)
	if err != nil && driver == "sqlite3" {
		err = db.Exec("PRAGMA foreign_keys = ON").Error
		db.DB().SetMaxOpenConns(1)
	}
	return &db, locale.UntranslatedError(err)
}

func bounceNoHost(io.Reader, string, *gorm.DB, *periwinkle.Cfg) postfixpipe.ExitStatus {
	return postfixpipe.EX_NOHOST
}
<commit_msg>periwinkle/cfg/parse.go: Fix calling gotoError(nil)<commit_after>// Copyright 2015 Mark Pundman
// Copyright 2015 Luke Shumaker
// Copyright 2015 Davis Webb

package cfg

import (
	"io"
	"io/ioutil"
	"locale"
	"maildir"
	"net/http"
	"os"
	"periwinkle"
	"periwinkle/domain_handlers"
	"postfixpipe"

	_ "github.com/go-sql-driver/mysql"
	"github.com/jinzhu/gorm"
	_ "github.com/mattn/go-sqlite3"
	yaml "gopkg.in/yaml.v2"
)

func gotoError(err locale.Error) {
	panic(err)
}

func Parse(in io.Reader) (cfgptr *periwinkle.Cfg, e locale.Error) {
	defer func() {
		if r := recover(); r != nil {
			cfgptr = nil
			switch err := r.(type) {
			case locale.Error:
				e = err
			default:
				panic(r)
			}
		}
	}()

	// these are the defaults
	cfg := periwinkle.Cfg{
		Mailstore:            "./Maildir",
		WebUIDir:             "./www",
		Debug:                true,
		TrustForwarded:       true,
		TwilioAccountID:      os.Getenv("TWILIO_ACCOUNTID"),
		TwilioAuthToken:      os.Getenv("TWILIO_TOKEN"),
		GroupDomain:          "localhost",
		WebRoot:              "locahost:8080",
		DB:                   nil, // the default DB is set later
		DefaultDomainHandler: bounceNoHost,
	}

	datstr, err := ioutil.ReadAll(in)
	if err != nil {
		gotoError(locale.UntranslatedError(err))
	}

	var datint interface{}
	err = yaml.Unmarshal(datstr, &datint)
	if err != nil {
		gotoError(locale.UntranslatedError(err))
	}

	datmap, ok := datint.(map[interface{}]interface{})
	if !ok {
		gotoError(locale.Errorf("root element is not a map"))
	}

	for key, val := range datmap {
		switch key {
		case "Mailstore":
			cfg.Mailstore = maildir.Maildir(getString(key.(string), val))
		case "WebUIDir":
			cfg.WebUIDir = http.Dir(getString(key.(string), val))
		case "Debug":
			cfg.Debug = getBool(key.(string), val)
		case "TrustForwarded":
			cfg.TrustForwarded = getBool(key.(string), val)
		case "TwilioAccountID":
			cfg.TwilioAccountID = getString(key.(string), val)
		case "TwilioAuthToken":
			cfg.TwilioAuthToken = getString(key.(string), val)
		case "GroupDomain":
			cfg.GroupDomain = getString(key.(string), val)
		case "WebRoot":
			cfg.WebRoot = getString(key.(string), val)
		case "DB":
			m, ok := val.(map[interface{}]interface{})
			if !ok {
				gotoError(locale.Errorf("value for %q is not a map", key.(string)))
			}
			var driver string
			var source string
			for key, val := range m {
				switch key {
				case "driver":
					driver = getString("DB."+key.(string), val)
				case "source":
					source = getString("DB."+key.(string), val)
				default:
					gotoError(locale.Errorf("unknown field: %v", "DB."+key.(string)))
				}
			}
			db, err := openDB(driver, source)
			if err != nil {
				gotoError(err)
			}
			cfg.DB = db
		default:
			gotoError(locale.Errorf("unknown field: %v", key))
		}
	}

	// Set the default database
	if cfg.DB == nil {
		periwinkle.Logf("DB not configured, trying MySQL periwinkle:periwinkle@localhost/periwinkle")
		db, err := openDB("mysql", "periwinkle:periwinkle@/periwinkle?charset=utf8&parseTime=True")
		if err != nil {
			periwinkle.LogErr(locale.UntranslatedError(err))
			periwinkle.Logf("Failed to connect to MySQL, trying SQLite3 file:periwinkle.sqlite")
			db, err = openDB("sqlite3", "file:periwinkle.sqlite?mode=rwc&_txlock=exclusive")
			if err != nil {
				gotoError(locale.UntranslatedError(err))
			}
		}
		cfg.DB = db
	}

	cfg.DB.LogMode(cfg.Debug)

	domain_handlers.GetHandlers(&cfg)

	return &cfg, nil
}

func getString(key string, val interface{}) string {
	str, ok := val.(string)
	if !ok {
		gotoError(locale.Errorf("value for %q is not a string", key))
	}
	return str
}

func getBool(key string, val interface{}) bool {
	b, ok := val.(bool)
	if !ok {
		gotoError(locale.Errorf("value for %q is not a Boolean", key))
	}
	return b
}

func openDB(driver, source string) (*gorm.DB, locale.Error) {
	db, err := gorm.Open(driver, source)
	if err != nil && driver == "sqlite3" {
		err = db.Exec("PRAGMA foreign_keys = ON").Error
		db.DB().SetMaxOpenConns(1)
	}
	return &db, locale.UntranslatedError(err)
}

func bounceNoHost(io.Reader, string, *gorm.DB, *periwinkle.Cfg) postfixpipe.ExitStatus {
	return postfixpipe.EX_NOHOST
}
<|endoftext|>


<commit_before>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package net

import (
	"fmt"
	"runtime"
	"testing"
	"time"
)

func testTimeout(t *testing.T, net, addr string, readFrom bool) {
	c, err := Dial(net, addr)
	if err != nil {
		t.Errorf("Dial(%q, %q) failed: %v", net, addr, err)
		return
	}
	defer c.Close()
	what := "Read"
	if readFrom {
		what = "ReadFrom"
	}

	errc := make(chan error, 1)
	go func() {
		t0 := time.Now()
		c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
		var b [100]byte
		var n int
		var err error
		if readFrom {
			n, _, err = c.(PacketConn).ReadFrom(b[0:])
		} else {
			n, err = c.Read(b[0:])
		}
		t1 := time.Now()
		if n != 0 || err == nil || !err.(Error).Timeout() {
			errc <- fmt.Errorf("%s(%q, %q) did not return 0, timeout: %v, %v", what, net, addr, n, err)
			return
		}
		if dt := t1.Sub(t0); dt < 50*time.Millisecond || !testing.Short() && dt > 250*time.Millisecond {
			errc <- fmt.Errorf("%s(%q, %q) took %s, expected 0.1s", what, net, addr, dt)
			return
		}
		errc <- nil
	}()
	select {
	case err := <-errc:
		if err != nil {
			t.Error(err)
		}
	case <-time.After(1 * time.Second):
		t.Errorf("%s(%q, %q) took over 1 second, expected 0.1s", what, net, addr)
	}
}

func TestTimeoutUDP(t *testing.T) {
	switch runtime.GOOS {
	case "plan9":
		t.Logf("skipping test on %q", runtime.GOOS)
		return
	}

	// set up a listener that won't talk back
	listening := make(chan string)
	done := make(chan int)
	go runDatagramPacketConnServer(t, "udp", "127.0.0.1:0", listening, done)
	addr := <-listening

	testTimeout(t, "udp", addr, false)
	testTimeout(t, "udp", addr, true)
	<-done
}

func TestTimeoutTCP(t *testing.T) {
	switch runtime.GOOS {
	case "plan9":
		t.Logf("skipping test on %q", runtime.GOOS)
		return
	}

	// set up a listener that won't talk back
	listening := make(chan string)
	done := make(chan int)
	go runStreamConnServer(t, "tcp", "127.0.0.1:0", listening, done)
	addr := <-listening

	testTimeout(t, "tcp", addr, false)
	<-done
}

func TestDeadlineReset(t *testing.T) {
	switch runtime.GOOS {
	case "plan9":
		t.Logf("skipping test on %q", runtime.GOOS)
		return
	}
	ln, err := Listen("tcp", "127.0.0.1:0")
	if err != nil {
		t.Fatal(err)
	}
	defer ln.Close()
	tl := ln.(*TCPListener)
	tl.SetDeadline(time.Now().Add(1 * time.Minute))
	tl.SetDeadline(time.Time{}) // reset it
	errc := make(chan error, 1)
	go func() {
		_, err := ln.Accept()
		errc <- err
	}()
	select {
	case <-time.After(50 * time.Millisecond):
		// Pass.
	case err := <-errc:
		// Accept should never return; we never
		// connected to it.
		t.Errorf("unexpected return from Accept; err=%v", err)
	}
}

func TestTimeoutAccept(t *testing.T) {
	switch runtime.GOOS {
	case "plan9":
		t.Logf("skipping test on %q", runtime.GOOS)
		return
	}
	ln, err := Listen("tcp", "127.0.0.1:0")
	if err != nil {
		t.Fatal(err)
	}
	defer ln.Close()
	tl := ln.(*TCPListener)
	tl.SetDeadline(time.Now().Add(100 * time.Millisecond))
	errc := make(chan error, 1)
	go func() {
		_, err := ln.Accept()
		errc <- err
	}()
	select {
	case <-time.After(1 * time.Second):
		// Accept shouldn't block indefinitely
		t.Errorf("Accept didn't return in an expected time")
	case <-errc:
		// Pass.
	}
}

func TestReadWriteDeadline(t *testing.T) {
	if !canCancelIO {
		t.Logf("skipping test on this system")
		return
	}
	const (
		readTimeout  = 100 * time.Millisecond
		writeTimeout = 200 * time.Millisecond
		delta        = 40 * time.Millisecond
	)
	checkTimeout := func(command string, start time.Time, should time.Duration) {
		is := time.Now().Sub(start)
		d := should - is
		if d < -delta || delta < d {
			t.Errorf("%s timeout test failed: is=%v should=%v\n", command, is, should)
		}
	}

	ln, err := Listen("tcp", "127.0.0.1:0")
	if err != nil {
		t.Fatalf("ListenTCP on :0: %v", err)
	}

	lnquit := make(chan bool)

	go func() {
		c, err := ln.Accept()
		if err != nil {
			t.Fatalf("Accept: %v", err)
		}
		defer c.Close()
		lnquit <- true
	}()

	c, err := Dial("tcp", ln.Addr().String())
	if err != nil {
		t.Fatalf("Dial: %v", err)
	}
	defer c.Close()

	start := time.Now()
	err = c.SetReadDeadline(start.Add(readTimeout))
	if err != nil {
		t.Fatalf("SetReadDeadline: %v", err)
	}
	err = c.SetWriteDeadline(start.Add(writeTimeout))
	if err != nil {
		t.Fatalf("SetWriteDeadline: %v", err)
	}

	quit := make(chan bool)

	go func() {
		var buf [10]byte
		_, err = c.Read(buf[:])
		if err == nil {
			t.Errorf("Read should not succeed")
		}
		checkTimeout("Read", start, readTimeout)
		quit <- true
	}()

	go func() {
		var buf [10000]byte
		for {
			_, err = c.Write(buf[:])
			if err != nil {
				break
			}
		}
		checkTimeout("Write", start, writeTimeout)
		quit <- true
	}()

	<-quit
	<-quit
	<-lnquit
}
<commit_msg>net: fix race in TestReadWriteDeadline.<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package net

import (
	"fmt"
	"runtime"
	"testing"
	"time"
)

func testTimeout(t *testing.T, net, addr string, readFrom bool) {
	c, err := Dial(net, addr)
	if err != nil {
		t.Errorf("Dial(%q, %q) failed: %v", net, addr, err)
		return
	}
	defer c.Close()
	what := "Read"
	if readFrom {
		what = "ReadFrom"
	}

	errc := make(chan error, 1)
	go func() {
		t0 := time.Now()
		c.SetReadDeadline(time.Now().Add(100 * time.Millisecond))
		var b [100]byte
		var n int
		var err error
		if readFrom {
			n, _, err = c.(PacketConn).ReadFrom(b[0:])
		} else {
			n, err = c.Read(b[0:])
		}
		t1 := time.Now()
		if n != 0 || err == nil || !err.(Error).Timeout() {
			errc <- fmt.Errorf("%s(%q, %q) did not return 0, timeout: %v, %v", what, net, addr, n, err)
			return
		}
		if dt := t1.Sub(t0); dt < 50*time.Millisecond || !testing.Short() && dt > 250*time.Millisecond {
			errc <- fmt.Errorf("%s(%q, %q) took %s, expected 0.1s", what, net, addr, dt)
			return
		}
		errc <- nil
	}()
	select {
	case err := <-errc:
		if err != nil {
			t.Error(err)
		}
	case <-time.After(1 * time.Second):
		t.Errorf("%s(%q, %q) took over 1 second, expected 0.1s", what, net, addr)
	}
}

func TestTimeoutUDP(t *testing.T) {
	switch runtime.GOOS {
	case "plan9":
		t.Logf("skipping test on %q", runtime.GOOS)
		return
	}

	// set up a listener that won't talk back
	listening := make(chan string)
	done := make(chan int)
	go runDatagramPacketConnServer(t, "udp", "127.0.0.1:0", listening, done)
	addr := <-listening

	testTimeout(t, "udp", addr, false)
	testTimeout(t, "udp", addr, true)
	<-done
}

func TestTimeoutTCP(t *testing.T) {
	switch runtime.GOOS {
	case "plan9":
		t.Logf("skipping test on %q", runtime.GOOS)
		return
	}

	// set up a listener that won't talk back
	listening := make(chan string)
	done := make(chan int)
	go runStreamConnServer(t, "tcp", "127.0.0.1:0", listening, done)
	addr := <-listening

	testTimeout(t, "tcp", addr, false)
	<-done
}

func TestDeadlineReset(t *testing.T) {
	switch runtime.GOOS {
	case "plan9":
		t.Logf("skipping test on %q", runtime.GOOS)
		return
	}
	ln, err := Listen("tcp", "127.0.0.1:0")
	if err != nil {
		t.Fatal(err)
	}
	defer ln.Close()
	tl := ln.(*TCPListener)
	tl.SetDeadline(time.Now().Add(1 * time.Minute))
	tl.SetDeadline(time.Time{}) // reset it
	errc := make(chan error, 1)
	go func() {
		_, err := ln.Accept()
		errc <- err
	}()
	select {
	case <-time.After(50 * time.Millisecond):
		// Pass.
	case err := <-errc:
		// Accept should never return; we never
		// connected to it.
		t.Errorf("unexpected return from Accept; err=%v", err)
	}
}

func TestTimeoutAccept(t *testing.T) {
	switch runtime.GOOS {
	case "plan9":
		t.Logf("skipping test on %q", runtime.GOOS)
		return
	}
	ln, err := Listen("tcp", "127.0.0.1:0")
	if err != nil {
		t.Fatal(err)
	}
	defer ln.Close()
	tl := ln.(*TCPListener)
	tl.SetDeadline(time.Now().Add(100 * time.Millisecond))
	errc := make(chan error, 1)
	go func() {
		_, err := ln.Accept()
		errc <- err
	}()
	select {
	case <-time.After(1 * time.Second):
		// Accept shouldn't block indefinitely
		t.Errorf("Accept didn't return in an expected time")
	case <-errc:
		// Pass.
	}
}

func TestReadWriteDeadline(t *testing.T) {
	if !canCancelIO {
		t.Logf("skipping test on this system")
		return
	}
	const (
		readTimeout  = 100 * time.Millisecond
		writeTimeout = 200 * time.Millisecond
		delta        = 40 * time.Millisecond
	)
	checkTimeout := func(command string, start time.Time, should time.Duration) {
		is := time.Now().Sub(start)
		d := should - is
		if d < -delta || delta < d {
			t.Errorf("%s timeout test failed: is=%v should=%v\n", command, is, should)
		}
	}

	ln, err := Listen("tcp", "127.0.0.1:0")
	if err != nil {
		t.Fatalf("ListenTCP on :0: %v", err)
	}

	lnquit := make(chan bool)

	go func() {
		c, err := ln.Accept()
		if err != nil {
			t.Fatalf("Accept: %v", err)
		}
		defer c.Close()
		lnquit <- true
	}()

	c, err := Dial("tcp", ln.Addr().String())
	if err != nil {
		t.Fatalf("Dial: %v", err)
	}
	defer c.Close()

	start := time.Now()
	err = c.SetReadDeadline(start.Add(readTimeout))
	if err != nil {
		t.Fatalf("SetReadDeadline: %v", err)
	}
	err = c.SetWriteDeadline(start.Add(writeTimeout))
	if err != nil {
		t.Fatalf("SetWriteDeadline: %v", err)
	}

	quit := make(chan bool)

	go func() {
		var buf [10]byte
		_, err := c.Read(buf[:])
		if err == nil {
			t.Errorf("Read should not succeed")
		}
		checkTimeout("Read", start, readTimeout)
		quit <- true
	}()

	go func() {
		var buf [10000]byte
		for {
			_, err := c.Write(buf[:])
			if err != nil {
				break
			}
		}
		checkTimeout("Write", start, writeTimeout)
		quit <- true
	}()

	<-quit
	<-quit
	<-lnquit
}
<|endoftext|>


<commit_before>// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build race

package atomic

import (
	"runtime"
	"unsafe"
)

// We use runtime.RaceRead() inside of atomic operations to catch races
// between atomic and non-atomic operations.  It will also catch races
// between Mutex.Lock() and mutex overwrite (mu = Mutex{}).  Since we use
// only RaceRead() we won't catch races with non-atomic loads.
// Otherwise (if we use RaceWrite()) we will report races
// between atomic operations (false positives).

var mtx uint32 = 1 // same for all

func CompareAndSwapInt32(val *int32, old, new int32) bool {
	return CompareAndSwapUint32((*uint32)(unsafe.Pointer(val)), uint32(old), uint32(new))
}

func CompareAndSwapUint32(val *uint32, old, new uint32) (swapped bool) {
	swapped = false
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	runtime.RaceAcquire(unsafe.Pointer(val))
	if *val == old {
		*val = new
		swapped = true
		runtime.RaceReleaseMerge(unsafe.Pointer(val))
	}
	runtime.RaceSemrelease(&mtx)
	return
}

func CompareAndSwapInt64(val *int64, old, new int64) bool {
	return CompareAndSwapUint64((*uint64)(unsafe.Pointer(val)), uint64(old), uint64(new))
}

func CompareAndSwapUint64(val *uint64, old, new uint64) (swapped bool) {
	swapped = false
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	runtime.RaceAcquire(unsafe.Pointer(val))
	if *val == old {
		*val = new
		swapped = true
		runtime.RaceReleaseMerge(unsafe.Pointer(val))
	}
	runtime.RaceSemrelease(&mtx)
	return
}

func CompareAndSwapPointer(val *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool) {
	swapped = false
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	runtime.RaceAcquire(unsafe.Pointer(val))
	if *val == old {
		*val = new
		swapped = true
		runtime.RaceReleaseMerge(unsafe.Pointer(val))
	}
	runtime.RaceSemrelease(&mtx)
	return
}

func CompareAndSwapUintptr(val *uintptr, old, new uintptr) (swapped bool) {
	swapped = false
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	runtime.RaceAcquire(unsafe.Pointer(val))
	if *val == old {
		*val = new
		swapped = true
		runtime.RaceReleaseMerge(unsafe.Pointer(val))
	}
	runtime.RaceSemrelease(&mtx)
	return
}

func AddInt32(val *int32, delta int32) int32 {
	return int32(AddUint32((*uint32)(unsafe.Pointer(val)), uint32(delta)))
}

func AddUint32(val *uint32, delta uint32) (new uint32) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	runtime.RaceAcquire(unsafe.Pointer(val))
	*val = *val + delta
	new = *val
	runtime.RaceReleaseMerge(unsafe.Pointer(val))
	runtime.RaceSemrelease(&mtx)

	return
}

func AddInt64(val *int64, delta int64) int64 {
	return int64(AddUint64((*uint64)(unsafe.Pointer(val)), uint64(delta)))
}

func AddUint64(val *uint64, delta uint64) (new uint64) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	runtime.RaceAcquire(unsafe.Pointer(val))
	*val = *val + delta
	new = *val
	runtime.RaceReleaseMerge(unsafe.Pointer(val))
	runtime.RaceSemrelease(&mtx)

	return
}

func AddUintptr(val *uintptr, delta uintptr) (new uintptr) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	runtime.RaceAcquire(unsafe.Pointer(val))
	*val = *val + delta
	new = *val
	runtime.RaceReleaseMerge(unsafe.Pointer(val))
	runtime.RaceSemrelease(&mtx)

	return
}

func LoadInt32(addr *int32) int32 {
	return int32(LoadUint32((*uint32)(unsafe.Pointer(addr))))
}

func LoadUint32(addr *uint32) (val uint32) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(addr))
	runtime.RaceAcquire(unsafe.Pointer(addr))
	val = *addr
	runtime.RaceSemrelease(&mtx)
	return
}

func LoadInt64(addr *int64) int64 {
	return int64(LoadUint64((*uint64)(unsafe.Pointer(addr))))
}

func LoadUint64(addr *uint64) (val uint64) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(addr))
	runtime.RaceAcquire(unsafe.Pointer(addr))
	val = *addr
	runtime.RaceSemrelease(&mtx)
	return
}

func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(addr))
	runtime.RaceAcquire(unsafe.Pointer(addr))
	val = *addr
	runtime.RaceSemrelease(&mtx)
	return
}

func LoadUintptr(addr *uintptr) (val uintptr) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	runtime.RaceAcquire(unsafe.Pointer(addr))
	val = *addr
	runtime.RaceSemrelease(&mtx)
	return
}

func StoreInt32(addr *int32, val int32) {
	StoreUint32((*uint32)(unsafe.Pointer(addr)), uint32(val))
}

func StoreUint32(addr *uint32, val uint32) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(addr))
	*addr = val
	runtime.RaceRelease(unsafe.Pointer(addr))
	runtime.RaceSemrelease(&mtx)
}

func StoreInt64(addr *int64, val int64) {
	StoreUint64((*uint64)(unsafe.Pointer(addr)), uint64(val))
}

func StoreUint64(addr *uint64, val uint64) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(addr))
	*addr = val
	runtime.RaceRelease(unsafe.Pointer(addr))
	runtime.RaceSemrelease(&mtx)
}

func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	*addr = val
	runtime.RaceRelease(unsafe.Pointer(addr))
	runtime.RaceSemrelease(&mtx)
}

func StoreUintptr(addr *uintptr, val uintptr) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	*addr = val
	runtime.RaceRelease(unsafe.Pointer(addr))
	runtime.RaceSemrelease(&mtx)
}
<commit_msg>sync/atomic: fix race instrumentation<commit_after>// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build race

package atomic

import (
	"runtime"
	"unsafe"
)

// We use runtime.RaceRead() inside of atomic operations to catch races
// between atomic and non-atomic operations.  It will also catch races
// between Mutex.Lock() and mutex overwrite (mu = Mutex{}).  Since we use
// only RaceRead() we won't catch races with non-atomic loads.
// Otherwise (if we use RaceWrite()) we will report races
// between atomic operations (false positives).

var mtx uint32 = 1 // same for all

func CompareAndSwapInt32(val *int32, old, new int32) bool {
	return CompareAndSwapUint32((*uint32)(unsafe.Pointer(val)), uint32(old), uint32(new))
}

func CompareAndSwapUint32(val *uint32, old, new uint32) (swapped bool) {
	swapped = false
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	runtime.RaceAcquire(unsafe.Pointer(val))
	if *val == old {
		*val = new
		swapped = true
		runtime.RaceReleaseMerge(unsafe.Pointer(val))
	}
	runtime.RaceSemrelease(&mtx)
	return
}

func CompareAndSwapInt64(val *int64, old, new int64) bool {
	return CompareAndSwapUint64((*uint64)(unsafe.Pointer(val)), uint64(old), uint64(new))
}

func CompareAndSwapUint64(val *uint64, old, new uint64) (swapped bool) {
	swapped = false
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	runtime.RaceAcquire(unsafe.Pointer(val))
	if *val == old {
		*val = new
		swapped = true
		runtime.RaceReleaseMerge(unsafe.Pointer(val))
	}
	runtime.RaceSemrelease(&mtx)
	return
}

func CompareAndSwapPointer(val *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool) {
	swapped = false
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	runtime.RaceAcquire(unsafe.Pointer(val))
	if *val == old {
		*val = new
		swapped = true
		runtime.RaceReleaseMerge(unsafe.Pointer(val))
	}
	runtime.RaceSemrelease(&mtx)
	return
}

func CompareAndSwapUintptr(val *uintptr, old, new uintptr) (swapped bool) {
	swapped = false
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	runtime.RaceAcquire(unsafe.Pointer(val))
	if *val == old {
		*val = new
		swapped = true
		runtime.RaceReleaseMerge(unsafe.Pointer(val))
	}
	runtime.RaceSemrelease(&mtx)
	return
}

func AddInt32(val *int32, delta int32) int32 {
	return int32(AddUint32((*uint32)(unsafe.Pointer(val)), uint32(delta)))
}

func AddUint32(val *uint32, delta uint32) (new uint32) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	runtime.RaceAcquire(unsafe.Pointer(val))
	*val = *val + delta
	new = *val
	runtime.RaceReleaseMerge(unsafe.Pointer(val))
	runtime.RaceSemrelease(&mtx)

	return
}

func AddInt64(val *int64, delta int64) int64 {
	return int64(AddUint64((*uint64)(unsafe.Pointer(val)), uint64(delta)))
}

func AddUint64(val *uint64, delta uint64) (new uint64) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	runtime.RaceAcquire(unsafe.Pointer(val))
	*val = *val + delta
	new = *val
	runtime.RaceReleaseMerge(unsafe.Pointer(val))
	runtime.RaceSemrelease(&mtx)

	return
}

func AddUintptr(val *uintptr, delta uintptr) (new uintptr) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(val))
	runtime.RaceAcquire(unsafe.Pointer(val))
	*val = *val + delta
	new = *val
	runtime.RaceReleaseMerge(unsafe.Pointer(val))
	runtime.RaceSemrelease(&mtx)

	return
}

func LoadInt32(addr *int32) int32 {
	return int32(LoadUint32((*uint32)(unsafe.Pointer(addr))))
}

func LoadUint32(addr *uint32) (val uint32) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(addr))
	runtime.RaceAcquire(unsafe.Pointer(addr))
	val = *addr
	runtime.RaceSemrelease(&mtx)
	return
}

func LoadInt64(addr *int64) int64 {
	return int64(LoadUint64((*uint64)(unsafe.Pointer(addr))))
}

func LoadUint64(addr *uint64) (val uint64) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(addr))
	runtime.RaceAcquire(unsafe.Pointer(addr))
	val = *addr
	runtime.RaceSemrelease(&mtx)
	return
}

func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(addr))
	runtime.RaceAcquire(unsafe.Pointer(addr))
	val = *addr
	runtime.RaceSemrelease(&mtx)
	return
}

func LoadUintptr(addr *uintptr) (val uintptr) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(addr))
	runtime.RaceAcquire(unsafe.Pointer(addr))
	val = *addr
	runtime.RaceSemrelease(&mtx)
	return
}

func StoreInt32(addr *int32, val int32) {
	StoreUint32((*uint32)(unsafe.Pointer(addr)), uint32(val))
}

func StoreUint32(addr *uint32, val uint32) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(addr))
	*addr = val
	runtime.RaceRelease(unsafe.Pointer(addr))
	runtime.RaceSemrelease(&mtx)
}

func StoreInt64(addr *int64, val int64) {
	StoreUint64((*uint64)(unsafe.Pointer(addr)), uint64(val))
}

func StoreUint64(addr *uint64, val uint64) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(addr))
	*addr = val
	runtime.RaceRelease(unsafe.Pointer(addr))
	runtime.RaceSemrelease(&mtx)
}

func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(addr))
	*addr = val
	runtime.RaceRelease(unsafe.Pointer(addr))
	runtime.RaceSemrelease(&mtx)
}

func StoreUintptr(addr *uintptr, val uintptr) {
	runtime.RaceSemacquire(&mtx)
	runtime.RaceRead(unsafe.Pointer(addr))
	*addr = val
	runtime.RaceRelease(unsafe.Pointer(addr))
	runtime.RaceSemrelease(&mtx)
}
<|endoftext|>


<commit_before>package boltqueue

import (
	"encoding/binary"
	"errors"
	"fmt"

	"github.com/boltdb/bolt"
)

// TODO: Interfacification of messages

// Message represents a message in the priority queue
type Message struct {
	Priority int // Message priority in the range of 0-255
	key      []byte
	value    []byte
}

var foundItem = errors.New("item found")

// NewMessage generates a new priority queue message with a priority range of
// 0-255
func NewMessage(priority int, value string) *Message {
	if priority < 0 || priority > 255 {
		priority = 255
	}
	return &Message{Priority: priority, value: []byte(value)}
}

// ToString outputs the string representation of the message's value
func (m *Message) ToString() string {
	return string(m.value)
}

// PQueue is a priority queue backed by a Bolt database on disk
type PQueue struct {
	conn *bolt.DB
}

// NewPQueue loads or creates a new PQueue with the given filename
func NewPQueue(filename string) (*PQueue, error) {
	db, err := bolt.Open(filename, 0600, nil)
	if err != nil {
		return nil, err
	}
	return &PQueue{db}, nil
}

// Enqueue adds a message to the queue
func (b *PQueue) Enqueue(m *Message) error {
	if m.Priority < 0 || m.Priority > 255 {
		return fmt.Errorf("Invalid priority %d on Enqueue()", m.Priority)
	}
	p := make([]byte, 1)
	p[0] = byte(uint8(m.Priority))
	return b.conn.Update(func(tx *bolt.Tx) error {
		// Get bucket for this priority level
		pb, err := tx.CreateBucketIfNotExists(p)
		if err != nil {
			return err
		}
		// Add the message
		var key []byte
		if m.key == nil {
			key = make([]byte, 8)
			nextKey, err := pb.NextSequence()
			if err != nil {
				return err
			}
			binary.BigEndian.PutUint64(key, nextKey)
		} else {
			key = m.key
		}
		err = pb.Put(key, m.value)
		if err != nil {
			return err
		}
		return nil
	})
}

// Dequeue removes the oldest, highest priority message from the queue and
// returns it
func (b *PQueue) Dequeue() (*Message, error) {
	var m *Message
	err := b.conn.Update(func(tx *bolt.Tx) error {
		err := tx.ForEach(func(bname []byte, bucket *bolt.Bucket) error {
			if bucket.Stats().KeyN == 0 { //empty bucket
				return nil
			}
			cur := bucket.Cursor()
			k, v := cur.First() //Should not be empty by definition
			priority, _ := binary.Uvarint(bname)
			m = &Message{int(priority), cloneBytes(k), cloneBytes(v)}

			// Remove message
			if err := cur.Delete(); err != nil {
				return err
			}
			return foundItem //to stop the iteration
		})
		if err != nil && err != foundItem {
			return err
		}
		return nil
	})
	if err != nil {
		return nil, err
	}
	return m, nil
}

// Size returns the number of entries of a given priority from 1 to 5
func (b *PQueue) Size(priority int) (int, error) {
	if priority < 0 || priority > 255 {
		return 0, fmt.Errorf("Invalid priority %d for Size()", priority)
	}
	tx, err := b.conn.Begin(false)
	if err != nil {
		return 0, err
	}
	bucket := tx.Bucket([]byte{byte(uint8(priority))})
	if bucket == nil {
		return 0, nil
	}
	count := bucket.Stats().KeyN
	tx.Rollback()
	return count, nil
}

// Close closes the queue and releases all resources
func (b *PQueue) Close() error {
	err := b.conn.Close()
	if err != nil {
		return err
	}
	return nil
}

// taken from boltDB. Avoids corruption when re-queueing
func cloneBytes(v []byte) []byte {
	var clone = make([]byte, len(v))
	copy(clone, v)
	return clone
}
<commit_msg>Revert "use bucket auto-incrementer instead of time.Now.UnixNano()"<commit_after>package boltqueue

import (
	"encoding/binary"
	"errors"
	"fmt"
	"time"

	"github.com/boltdb/bolt"
)

// TODO: Interfacification of messages

// Message represents a message in the priority queue
type Message struct {
	Priority int // Message priority in the range of 0-255
	key      []byte
	value    []byte
}

var foundItem = errors.New("item found")
var lastTime int64 //keep track of the last UnixNano in case there's somehow a dup

// NewMessage generates a new priority queue message with a priority range of
// 0-255
func NewMessage(priority int, value string) *Message {
	if priority < 0 || priority > 255 {
		priority = 255
	}
	t := time.Now().UnixNano()
	if t <= lastTime {
		t = lastTime + 1
	}
	lastTime = t
	k := make([]byte, 8)
	binary.BigEndian.PutUint64(k, uint64(t))
	return &Message{priority, k, []byte(value)}
}

// ToString outputs the string representation of the message's value
func (m *Message) ToString() string {
	return string(m.value)
}

// PQueue is a priority queue backed by a Bolt database on disk
type PQueue struct {
	conn *bolt.DB
}

// NewPQueue loads or creates a new PQueue with the given filename
func NewPQueue(filename string) (*PQueue, error) {
	db, err := bolt.Open(filename, 0600, nil)
	if err != nil {
		return nil, err
	}
	return &PQueue{db}, nil
}

// Enqueue adds a message to the queue
func (b *PQueue) Enqueue(m *Message) error {
	if m.Priority < 0 || m.Priority > 255 {
		return fmt.Errorf("Invalid priority %d on Enqueue()", m.Priority)
	}
	p := make([]byte, 1)
	p[0] = byte(uint8(m.Priority))
	return b.conn.Update(func(tx *bolt.Tx) error {
		// Get bucket for this priority level
		pb, err := tx.CreateBucketIfNotExists(p)
		if err != nil {
			return err
		}
		// Add the message
		err = pb.Put(m.key, m.value)
		if err != nil {
			return err
		}
		return nil
	})
}

// Dequeue removes the oldest, highest priority message from the queue and
// returns it
func (b *PQueue) Dequeue() (*Message, error) {
	var m *Message
	err := b.conn.Update(func(tx *bolt.Tx) error {
		err := tx.ForEach(func(bname []byte, bucket *bolt.Bucket) error {
			if bucket.Stats().KeyN == 0 { //empty bucket
				return nil
			}
			cur := bucket.Cursor()
			k, v := cur.First() //Should not be empty by definition
			priority, _ := binary.Uvarint(bname)
			m = &Message{int(priority), cloneBytes(k), cloneBytes(v)}

			// Remove message
			if err := cur.Delete(); err != nil {
				return err
			}
			return foundItem //to stop the iteration
		})
		if err != nil && err != foundItem {
			return err
		}
		return nil
	})
	if err != nil {
		return nil, err
	}
	return m, nil
}

// Size returns the number of entries of a given priority from 1 to 5
func (b *PQueue) Size(priority int) (int, error) {
	if priority < 0 || priority > 255 {
		return 0, fmt.Errorf("Invalid priority %d for Size()", priority)
	}
	tx, err := b.conn.Begin(false)
	if err != nil {
		return 0, err
	}
	bucket := tx.Bucket([]byte{byte(uint8(priority))})
	if bucket == nil {
		return 0, nil
	}
	count := bucket.Stats().KeyN
	tx.Rollback()
	return count, nil
}

// Close closes the queue and releases all resources
func (b *PQueue) Close() error {
	err := b.conn.Close()
	if err != nil {
		return err
	}
	return nil
}

// taken from boltDB. Avoids corruption when re-queueing
func cloneBytes(v []byte) []byte {
	var clone = make([]byte, len(v))
	copy(clone, v)
	return clone
}
<|endoftext|>


<commit_before>// Copyright 2013 Mikio Hara. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE.

// Package ipaddr provides basic functions for the manipulation of IP
// address prefixes and subsequent addresses as described in RFC 4632
// and RFC 4291.
package ipaddr

import (
	"errors"
	"math/big"
	"net"
	"sort"
)

var errInvalidArgument = errors.New("invalid arugument")

// A Prefix represents an IP address prefix.
type Prefix interface {
	// Contains reports whether the prefix includes the given ip.
	Contains(ip net.IP) bool

	// Overlaps reports whether the prefix overlaps with the given
	// prefix.
	Overlaps(prefix Prefix) bool

	// Equal reports whether the prefix and the given prefix are
	// equal.
	Equal(prefix Prefix) bool

	// String returns the string form of the prefix.
	String() string

	// Len returns the length of the prefix in bits.
	Len() int

	// NumAddr returns the number of addresses possible in the
	// prefix.
	NumAddr() *big.Int

	// Bits returns the nbits bit sequence extracted from the
	// prefix at position pos.
	Bits(pos, nbits int) uint32

	// Addr returns the address of the prefix.
	Addr() net.IP

	// LastAddr returns the last address in the address range of
	// the prefix. It returns the address of the prefix when the
	// prefix contains only one address.
	LastAddr() net.IP

	// Hostmask returns the host mask, the inverse mask of the
	// prefix's network mask.
	Hostmask() net.IPMask

	// Netmask returns the network mask of the prefix.
	Netmask() net.IPMask

	// Hosts returns the list of addresses that are assignable to
	// hosts, nodes that are not routers or other intermediate
	// systems, beginning with the given address begin for the
	// prefix neither 0.0.0.0/0 nor ::/0.
	//
	// Note that it will take a bit long time when the prefix is a
	// shorter one, and it also does not distinguish any multicast
	// addresses correctly for now.
	Hosts(begin net.IP) []net.IP

	// HostIter generates and returns the iterator that iterates
	// over the list of addresses that are assignable to hosts,
	// beginning with the given address's next address.
	//
	// Note that it does not identify host-assignable addresses
	// when the prefix is 0.0.0.0/0 or ::/0, and it also does not
	// distinguish any multicast addresses correctly for now.
	HostIter(first net.IP) <-chan net.IP

	// Subnets returns the list of prefixes that are splitted from
	// the prefix, into small address blocks by nbits which
	// represents a number of subnetworks in power of 2 notation.
	Subnets(nbits int) []Prefix

	// SubnetIter generates and returns the iterator that iterates
	// over the list of prefixes that are splitted from the
	// prefix, into small address blocks by nbits which represents
	// a number of subnetworks in power of 2 notation.
	SubnetIter(nbits int) <-chan Prefix

	// Exclude returns the list of prefixes that do not contain
	// the given prefix.
	Exclude(prefix Prefix) []Prefix

	// Set replaces the existing address and prefix length of the
	// prefix with ip and nbits.
	Set(ip net.IP, nbits int) error

	// MarshalBinary returns the BGP NLRI binary form of the
	// prefix.
	MarshalBinary() ([]byte, error)

	// UnmarshalBinary replaces the existing address and prefix
	// length of the prefix with data.
	UnmarshalBinary(data []byte) error

	// MarshalText returns the UTF-8-encoded text form of the
	// prefix.
	MarshalText() ([]byte, error)

	// UnmarshalText replaces the existing address and prefix
	// length of the prefix with text.
	UnmarshalText(text []byte) error
}

// NewPrefix returns a new Prefix.
func NewPrefix(ip net.IP, nbits int) (Prefix, error) {
	if ipv4 := ip.To4(); ipv4 != nil && 0 <= nbits && nbits <= IPv4PrefixLen {
		return newIPv4(ipToIPv4Int(ipv4), nbits), nil
	} else if ipv6 := ip.To16(); ipv6 != nil && ipv6.To4() == nil && 0 <= nbits && nbits <= IPv6PrefixLen {
		return newIPv6(ipToIPv6Int(ipv6), nbits), nil
	}
	return nil, errInvalidArgument
}

// Compare returns an integer comparing two prefixes. The result will
// be 0 if a == b, -1 if a < b, and +1 if a > b.
func Compare(a, b Prefix) int {
	switch a := a.(type) {
	case *IPv4:
		b, ok := b.(*IPv4)
		if !ok {
			return -1
		}
		return a.compare(b)
	case *IPv6:
		b, ok := b.(*IPv6)
		if !ok {
			return -1
		}
		return a.compare(b)
	default:
		return -1
	}
}

// Supernet finds out a shortest common address prefix for the given
// prefixes. It returns nil when no suitable prefix is found.
func Supernet(prefixes []Prefix) Prefix {
	if len(prefixes) == 0 {
		return nil
	}
	switch prefixes[0].(type) {
	case *IPv4:
		subs := byAddrFamily(prefixes).ipv4Only()
		if l := len(subs); l == 0 {
			return nil
		} else if l == 1 {
			return subs[0]
		}
		return supernetIPv4(subs)
	case *IPv6:
		subs := byAddrFamily(prefixes).ipv6Only()
		if l := len(subs); l == 0 {
			return nil
		} else if l == 1 {
			return subs[0]
		}
		return supernetIPv6(subs)
	default:
		return nil
	}
}

// Aggregate aggregates the given prefixes and returns a list of
// aggregated address prefixes.
func Aggregate(prefixes []Prefix) []Prefix {
	if len(prefixes) == 0 {
		return nil
	}
	switch prefixes[0].(type) {
	case *IPv4:
		subs := sortAndDedup(prefixes)
		if l := len(subs); l == 0 {
			return nil
		} else if l == 1 {
			return subs
		}
		return aggregateIPv4(subs)
	case *IPv6:
		subs := sortAndDedup(prefixes)
		if l := len(subs); l == 0 {
			return nil
		} else if l == 1 {
			return subs
		}
		return aggregateIPv6(subs)
	default:
		return nil
	}
}

// Summarize summarizes the given address range and returns a list of
// address prefixes.
func Summarize(first, last net.IP) []Prefix {
	if first == nil || last == nil {
		return nil
	}
	if firstip := first.To4(); firstip != nil {
		lastip := last.To4()
		if lastip == nil {
			return nil
		}
		return summarizeIPv4(firstip, lastip)
	} else if firstip := first.To16(); firstip != nil {
		lastip := last.To16()
		if lastip == nil || last.To4() != nil {
			return nil
		}
		return summarizeIPv6(firstip, lastip)
	} else {
		return nil
	}
}

func sortAndDedup(ps []Prefix) []Prefix {
	switch ps[0].(type) {
	case *IPv4:
		ps = byAddrFamily(ps).ipv4Only()
		sort.Sort(byAddrAndLen(ps))
	case *IPv6:
		ps = byAddrFamily(ps).ipv6Only()
		sort.Sort(byAddrAndLen(ps))
	default:
		return nil
	}
	nps := ps[:0]
	var prev Prefix
	for _, p := range ps {
		if prev == nil {
			nps = append(nps, p)
		} else if !prev.Equal(p) {
			nps = append(nps, p)
		}
		prev = p
	}
	return nps
}

type byAddrFamily []Prefix

func (ps byAddrFamily) ipv4Only() []Prefix {
	nps := ps[:0]
	for _, p := range ps {
		if p, ok := p.(*IPv4); ok {
			nps = append(nps, p)
		}
	}
	return nps
}

func (ps byAddrFamily) ipv6Only() []Prefix {
	nps := ps[:0]
	for _, p := range ps {
		if p, ok := p.(*IPv6); ok {
			nps = append(nps, p)
		}
	}
	return nps
}

type byAddrAndLen []Prefix

func (ps byAddrAndLen) Len() int {
	return len(ps)
}

func (ps byAddrAndLen) Less(i, j int) bool {
	if ncmp := Compare(ps[i], ps[j]); ncmp < 0 {
		return true
	} else if ncmp > 0 {
		return false
	}
	if ps[i].Len() < ps[j].Len() {
		return true
	} else if ps[i].Len() > ps[j].Len() {
		return false
	}
	return false
}

func (ps byAddrAndLen) Swap(i, j int) {
	ps[i], ps[j] = ps[j], ps[i]
}
<commit_msg>ipaddr: fix argument check in Summarize<commit_after>// Copyright 2013 Mikio Hara. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE.

// Package ipaddr provides basic functions for the manipulation of IP
// address prefixes and subsequent addresses as described in RFC 4632
// and RFC 4291.
package ipaddr

import (
	"errors"
	"math/big"
	"net"
	"sort"
)

var errInvalidArgument = errors.New("invalid arugument")

// A Prefix represents an IP address prefix.
type Prefix interface {
	// Contains reports whether the prefix includes the given ip.
	Contains(ip net.IP) bool

	// Overlaps reports whether the prefix overlaps with the given
	// prefix.
	Overlaps(prefix Prefix) bool

	// Equal reports whether the prefix and the given prefix are
	// equal.
	Equal(prefix Prefix) bool

	// String returns the string form of the prefix.
	String() string

	// Len returns the length of the prefix in bits.
	Len() int

	// NumAddr returns the number of addresses possible in the
	// prefix.
	NumAddr() *big.Int

	// Bits returns the nbits bit sequence extracted from the
	// prefix at position pos.
	Bits(pos, nbits int) uint32

	// Addr returns the address of the prefix.
	Addr() net.IP

	// LastAddr returns the last address in the address range of
	// the prefix. It returns the address of the prefix when the
	// prefix contains only one address.
	LastAddr() net.IP

	// Hostmask returns the host mask, the inverse mask of the
	// prefix's network mask.
	Hostmask() net.IPMask

	// Netmask returns the network mask of the prefix.
	Netmask() net.IPMask

	// Hosts returns the list of addresses that are assignable to
	// hosts, nodes that are not routers or other intermediate
	// systems, beginning with the given address begin for the
	// prefix neither 0.0.0.0/0 nor ::/0.
	//
	// Note that it will take a bit long time when the prefix is a
	// shorter one, and it also does not distinguish any multicast
	// addresses correctly for now.
	Hosts(begin net.IP) []net.IP

	// HostIter generates and returns the iterator that iterates
	// over the list of addresses that are assignable to hosts,
	// beginning with the given address's next address.
	//
	// Note that it does not identify host-assignable addresses
	// when the prefix is 0.0.0.0/0 or ::/0, and it also does not
	// distinguish any multicast addresses correctly for now.
	HostIter(first net.IP) <-chan net.IP

	// Subnets returns the list of prefixes that are splitted from
	// the prefix, into small address blocks by nbits which
	// represents a number of subnetworks in power of 2 notation.
	Subnets(nbits int) []Prefix

	// SubnetIter generates and returns the iterator that iterates
	// over the list of prefixes that are splitted from the
	// prefix, into small address blocks by nbits which represents
	// a number of subnetworks in power of 2 notation.
	SubnetIter(nbits int) <-chan Prefix

	// Exclude returns the list of prefixes that do not contain
	// the given prefix.
	Exclude(prefix Prefix) []Prefix

	// Set replaces the existing address and prefix length of the
	// prefix with ip and nbits.
	Set(ip net.IP, nbits int) error

	// MarshalBinary returns the BGP NLRI binary form of the
	// prefix.
	MarshalBinary() ([]byte, error)

	// UnmarshalBinary replaces the existing address and prefix
	// length of the prefix with data.
	UnmarshalBinary(data []byte) error

	// MarshalText returns the UTF-8-encoded text form of the
	// prefix.
	MarshalText() ([]byte, error)

	// UnmarshalText replaces the existing address and prefix
	// length of the prefix with text.
	UnmarshalText(text []byte) error
}

// NewPrefix returns a new Prefix.
func NewPrefix(ip net.IP, nbits int) (Prefix, error) {
	if ipv4 := ip.To4(); ipv4 != nil && 0 <= nbits && nbits <= IPv4PrefixLen {
		return newIPv4(ipToIPv4Int(ipv4), nbits), nil
	} else if ipv6 := ip.To16(); ipv6 != nil && ipv6.To4() == nil && 0 <= nbits && nbits <= IPv6PrefixLen {
		return newIPv6(ipToIPv6Int(ipv6), nbits), nil
	}
	return nil, errInvalidArgument
}

// Compare returns an integer comparing two prefixes. The result will
// be 0 if a == b, -1 if a < b, and +1 if a > b.
func Compare(a, b Prefix) int {
	switch a := a.(type) {
	case *IPv4:
		b, ok := b.(*IPv4)
		if !ok {
			return -1
		}
		return a.compare(b)
	case *IPv6:
		b, ok := b.(*IPv6)
		if !ok {
			return -1
		}
		return a.compare(b)
	default:
		return -1
	}
}

// Supernet finds out a shortest common address prefix for the given
// prefixes. It returns nil when no suitable prefix is found.
func Supernet(prefixes []Prefix) Prefix {
	if len(prefixes) == 0 {
		return nil
	}
	switch prefixes[0].(type) {
	case *IPv4:
		subs := byAddrFamily(prefixes).ipv4Only()
		if l := len(subs); l == 0 {
			return nil
		} else if l == 1 {
			return subs[0]
		}
		return supernetIPv4(subs)
	case *IPv6:
		subs := byAddrFamily(prefixes).ipv6Only()
		if l := len(subs); l == 0 {
			return nil
		} else if l == 1 {
			return subs[0]
		}
		return supernetIPv6(subs)
	default:
		return nil
	}
}

// Aggregate aggregates the given prefixes and returns a list of
// aggregated address prefixes.
func Aggregate(prefixes []Prefix) []Prefix {
	if len(prefixes) == 0 {
		return nil
	}
	switch prefixes[0].(type) {
	case *IPv4:
		subs := sortAndDedup(prefixes)
		if l := len(subs); l == 0 {
			return nil
		} else if l == 1 {
			return subs
		}
		return aggregateIPv4(subs)
	case *IPv6:
		subs := sortAndDedup(prefixes)
		if l := len(subs); l == 0 {
			return nil
		} else if l == 1 {
			return subs
		}
		return aggregateIPv6(subs)
	default:
		return nil
	}
}

// Summarize summarizes the given address range and returns a list of
// address prefixes.
func Summarize(first, last net.IP) []Prefix {
	if first == nil || last == nil {
		return nil
	}
	if firstip := first.To4(); firstip != nil {
		lastip := last.To4()
		if lastip == nil {
			return nil
		}
		return summarizeIPv4(firstip, lastip)
	} else if firstip := first.To16(); firstip != nil && firstip.To4() == nil {
		lastip := last.To16()
		if lastip == nil || last.To4() != nil {
			return nil
		}
		return summarizeIPv6(firstip, lastip)
	} else {
		return nil
	}
}

func sortAndDedup(ps []Prefix) []Prefix {
	switch ps[0].(type) {
	case *IPv4:
		ps = byAddrFamily(ps).ipv4Only()
		sort.Sort(byAddrAndLen(ps))
	case *IPv6:
		ps = byAddrFamily(ps).ipv6Only()
		sort.Sort(byAddrAndLen(ps))
	default:
		return nil
	}
	nps := ps[:0]
	var prev Prefix
	for _, p := range ps {
		if prev == nil {
			nps = append(nps, p)
		} else if !prev.Equal(p) {
			nps = append(nps, p)
		}
		prev = p
	}
	return nps
}

type byAddrFamily []Prefix

func (ps byAddrFamily) ipv4Only() []Prefix {
	nps := ps[:0]
	for _, p := range ps {
		if p, ok := p.(*IPv4); ok {
			nps = append(nps, p)
		}
	}
	return nps
}

func (ps byAddrFamily) ipv6Only() []Prefix {
	nps := ps[:0]
	for _, p := range ps {
		if p, ok := p.(*IPv6); ok {
			nps = append(nps, p)
		}
	}
	return nps
}

type byAddrAndLen []Prefix

func (ps byAddrAndLen) Len() int {
	return len(ps)
}

func (ps byAddrAndLen) Less(i, j int) bool {
	if ncmp := Compare(ps[i], ps[j]); ncmp < 0 {
		return true
	} else if ncmp > 0 {
		return false
	}
	if ps[i].Len() < ps[j].Len() {
		return true
	} else if ps[i].Len() > ps[j].Len() {
		return false
	}
	return false
}

func (ps byAddrAndLen) Swap(i, j int) {
	ps[i], ps[j] = ps[j], ps[i]
}
<|endoftext|>


<commit_before>package expint

import (
	"testing"

	"github.com/go-math/support/assert"
	"github.com/go-math/prob/dist/uniform"
)

func TestComputeTransient(t *testing.T) {
	s, _ := Load(findFixture("002.json"))

	cc := uint32(2)
	sc := uint32(len(fixtureP)) / cc

	Q := make([]float64, cc*sc)
	s.ComputeTransient(fixtureP, Q, nil, sc)

	assert.AlmostEqual(Q, fixtureQ, t)
}

func BenchmarkComputeTransient(b *testing.B) {
	s, _ := Load(findFixture("032.json"))

	cc := uint32(32)
	sc := uint32(1000)
	nc := s.Nodes

	P := uniform.New(0, 1).Sample(cc*sc)
	Q := make([]float64, cc*sc)
	S := make([]float64, nc*sc)

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		s.ComputeTransient(P, Q, S, sc)
	}
}
<commit_msg>Updated the usage of prob<commit_after>package expint

import (
	"testing"

	"github.com/go-math/prob"
	"github.com/go-math/prob/uniform"
	"github.com/go-math/support/assert"
)

func TestComputeTransient(t *testing.T) {
	s, _ := Load(findFixture("002.json"))

	cc := uint32(2)
	sc := uint32(len(fixtureP)) / cc

	Q := make([]float64, cc*sc)
	s.ComputeTransient(fixtureP, Q, nil, sc)

	assert.AlmostEqual(Q, fixtureQ, t)
}

func BenchmarkComputeTransient(b *testing.B) {
	s, _ := Load(findFixture("032.json"))

	cc := uint32(32)
	sc := uint32(1000)
	nc := s.Nodes

	P := prob.Sample(uniform.New(0, 1), cc*sc)
	Q := make([]float64, cc*sc)
	S := make([]float64, nc*sc)

	b.ResetTimer()

	for i := 0; i < b.N; i++ {
		s.ComputeTransient(P, Q, S, sc)
	}
}
<|endoftext|>