<commit_before>package version

import (
	"bytes"
	"fmt"
)

// The git commit that was compiled. This will be filled in by the compiler.
var GitCommit string

// The main version number that is being run at the moment.
const Version = "1.5.1"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
const VersionPrerelease = ""

func FormattedVersion() string {
	var versionString bytes.Buffer
	fmt.Fprintf(&versionString, "%s", Version)
	if VersionPrerelease != "" {
		fmt.Fprintf(&versionString, "-%s", VersionPrerelease)

		if GitCommit != "" {
			fmt.Fprintf(&versionString, " (%s)", GitCommit)
		}
	}

	return versionString.String()
}
<commit_msg>update to 1.5.2-dev<commit_after>package version

import (
	"bytes"
	"fmt"
)

// The git commit that was compiled. This will be filled in by the compiler.
var GitCommit string

// The main version number that is being run at the moment.
const Version = "1.5.2"

// A pre-release marker for the version. If this is "" (empty string)
// then it means that it is a final release. Otherwise, this is a pre-release
// such as "dev" (in development), "beta", "rc1", etc.
const VersionPrerelease = "dev"

func FormattedVersion() string {
	var versionString bytes.Buffer
	fmt.Fprintf(&versionString, "%s", Version)
	if VersionPrerelease != "" {
		fmt.Fprintf(&versionString, "-%s", VersionPrerelease)

		if GitCommit != "" {
			fmt.Fprintf(&versionString, " (%s)", GitCommit)
		}
	}

	return versionString.String()
}
<|endoftext|>


<commit_before>package version

// Version is the version of the build.
const Version = "1.10.0-dev"
<commit_msg>version: v1.11.0-dev<commit_after>package version

// Version is the version of the build.
const Version = "1.11.0-dev"
<|endoftext|>


<commit_before>// Copyright 2015 CoreOS, Inc.
//
// 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 version

const (
	Version = "0.2.3+git"
)
<commit_msg>locksmith: bump to 0.3.0<commit_after>// Copyright 2015 CoreOS, Inc.
//
// 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 version

const (
	Version = "0.3.0"
)
<|endoftext|>


<commit_before>package version

// VERSION ...
const VERSION = "0.0.3"
<commit_msg>v0.0.4<commit_after>package version

// VERSION ...
const VERSION = "0.0.4"
<|endoftext|>


<commit_before>package version

// VERSION ...
const VERSION = "1.1.46"
<commit_msg>v1.1.47<commit_after>package version

// VERSION ...
const VERSION = "1.1.47"
<|endoftext|>


<commit_before>package version

const (
	APP_VERSION = "1.3.1"
)

var ( // from Makefile
	KERNEL_VERSION string
	GIT_COMMIT     string
)
<commit_msg>Bump version to v1.3.2<commit_after>package version

const (
	APP_VERSION = "1.3.2"
)

var ( // from Makefile
	KERNEL_VERSION string
	GIT_COMMIT     string
)
<|endoftext|>


<commit_before>/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package govmomi

import (
	"github.com/vmware/govmomi/vim25/methods"
	"github.com/vmware/govmomi/vim25/types"
)

type VirtualMachine struct {
	types.ManagedObjectReference

	c *Client
}

func NewVirtualMachine(c *Client, ref types.ManagedObjectReference) *VirtualMachine {
	return &VirtualMachine{
		ManagedObjectReference: ref,
		c: c,
	}
}

func (v VirtualMachine) Reference() types.ManagedObjectReference {
	return v.ManagedObjectReference
}

func (v VirtualMachine) PowerOn() (*Task, error) {
	req := types.PowerOnVM_Task{
		This: v.Reference(),
	}

	res, err := methods.PowerOnVM_Task(v.c, &req)
	if err != nil {
		return nil, err
	}

	return NewTask(v.c, res.Returnval), nil
}

func (v VirtualMachine) PowerOff() (*Task, error) {
	req := types.PowerOffVM_Task{
		This: v.Reference(),
	}

	res, err := methods.PowerOffVM_Task(v.c, &req)
	if err != nil {
		return nil, err
	}

	return NewTask(v.c, res.Returnval), nil
}

func (v VirtualMachine) Reset() (*Task, error) {
	req := types.ResetVM_Task{
		This: v.Reference(),
	}

	res, err := methods.ResetVM_Task(v.c, &req)
	if err != nil {
		return nil, err
	}

	return NewTask(v.c, res.Returnval), nil
}

func (v VirtualMachine) Destroy() (*Task, error) {
	req := types.Destroy_Task{
		This: v.Reference(),
	}

	res, err := methods.Destroy_Task(v.c, &req)
	if err != nil {
		return nil, err
	}

	return NewTask(v.c, res.Returnval), nil
}

func (v VirtualMachine) Clone(folder *Folder, name string, config types.VirtualMachineCloneSpec) (*Task, error) {
	req := types.CloneVM_Task{
		This:   v.Reference(),
		Folder: folder.Reference(),
		Name:   name,
		Spec:   config,
	}

	res, err := methods.CloneVM_Task(v.c, &req)
	if err != nil {
		return nil, err
	}

	return NewTask(v.c, res.Returnval), nil
}

func (v VirtualMachine) Reconfigure(config types.VirtualMachineConfigSpec) (*Task, error) {
	req := types.ReconfigVM_Task{
		This: v.Reference(),
		Spec: config,
	}

	res, err := methods.ReconfigVM_Task(v.c, &req)
	if err != nil {
		return nil, err
	}

	return NewTask(v.c, res.Returnval), nil
}

func (v VirtualMachine) WaitForIP() (string, error) {
	var ip string

	err := v.c.WaitForProperties(v.Reference(), []string{"guest.ipAddress"}, func(pc []types.PropertyChange) bool {
		for _, c := range pc {
			if c.Name != "guest.ipAddress" {
				continue
			}
			if c.Op != types.PropertyChangeOpAssign {
				continue
			}
			if c.Val == nil {
				continue
			}

			ip = c.Val.(string)
			return true
		}

		return false
	})

	if err != nil {
		return "", err
	}

	return ip, nil
}
<commit_msg>Add device list related helpers<commit_after>/*
Copyright (c) 2014 VMware, Inc. All Rights Reserved.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package govmomi

import (
	"github.com/vmware/govmomi/vim25/methods"
	"github.com/vmware/govmomi/vim25/mo"
	"github.com/vmware/govmomi/vim25/types"
)

type VirtualMachine struct {
	types.ManagedObjectReference

	c *Client
}

func NewVirtualMachine(c *Client, ref types.ManagedObjectReference) *VirtualMachine {
	return &VirtualMachine{
		ManagedObjectReference: ref,
		c: c,
	}
}

func (v VirtualMachine) Reference() types.ManagedObjectReference {
	return v.ManagedObjectReference
}

func (v VirtualMachine) PowerOn() (*Task, error) {
	req := types.PowerOnVM_Task{
		This: v.Reference(),
	}

	res, err := methods.PowerOnVM_Task(v.c, &req)
	if err != nil {
		return nil, err
	}

	return NewTask(v.c, res.Returnval), nil
}

func (v VirtualMachine) PowerOff() (*Task, error) {
	req := types.PowerOffVM_Task{
		This: v.Reference(),
	}

	res, err := methods.PowerOffVM_Task(v.c, &req)
	if err != nil {
		return nil, err
	}

	return NewTask(v.c, res.Returnval), nil
}

func (v VirtualMachine) Reset() (*Task, error) {
	req := types.ResetVM_Task{
		This: v.Reference(),
	}

	res, err := methods.ResetVM_Task(v.c, &req)
	if err != nil {
		return nil, err
	}

	return NewTask(v.c, res.Returnval), nil
}

func (v VirtualMachine) Destroy() (*Task, error) {
	req := types.Destroy_Task{
		This: v.Reference(),
	}

	res, err := methods.Destroy_Task(v.c, &req)
	if err != nil {
		return nil, err
	}

	return NewTask(v.c, res.Returnval), nil
}

func (v VirtualMachine) Clone(folder *Folder, name string, config types.VirtualMachineCloneSpec) (*Task, error) {
	req := types.CloneVM_Task{
		This:   v.Reference(),
		Folder: folder.Reference(),
		Name:   name,
		Spec:   config,
	}

	res, err := methods.CloneVM_Task(v.c, &req)
	if err != nil {
		return nil, err
	}

	return NewTask(v.c, res.Returnval), nil
}

func (v VirtualMachine) Reconfigure(config types.VirtualMachineConfigSpec) (*Task, error) {
	req := types.ReconfigVM_Task{
		This: v.Reference(),
		Spec: config,
	}

	res, err := methods.ReconfigVM_Task(v.c, &req)
	if err != nil {
		return nil, err
	}

	return NewTask(v.c, res.Returnval), nil
}

func (v VirtualMachine) WaitForIP() (string, error) {
	var ip string

	err := v.c.WaitForProperties(v.Reference(), []string{"guest.ipAddress"}, func(pc []types.PropertyChange) bool {
		for _, c := range pc {
			if c.Name != "guest.ipAddress" {
				continue
			}
			if c.Op != types.PropertyChangeOpAssign {
				continue
			}
			if c.Val == nil {
				continue
			}

			ip = c.Val.(string)
			return true
		}

		return false
	})

	if err != nil {
		return "", err
	}

	return ip, nil
}

// Device returns the VirtualMachine's config.hardware.device property.
func (v VirtualMachine) Device() (VirtualDeviceList, error) {
	var o mo.VirtualMachine

	err := v.c.Properties(v.Reference(), []string{"config.hardware.device"}, &o)
	if err != nil {
		return nil, err
	}

	return VirtualDeviceList(o.Config.Hardware.Device), nil
}

func (v VirtualMachine) configureDevice(op types.VirtualDeviceConfigSpecOperation, devices ...types.BaseVirtualDevice) error {
	spec := types.VirtualMachineConfigSpec{}

	for _, device := range devices {
		config := &types.VirtualDeviceConfigSpec{
			Device:    device,
			Operation: op,
		}

		spec.DeviceChange = append(spec.DeviceChange, config)
	}

	task, err := v.Reconfigure(spec)
	if err != nil {
		return err
	}

	return task.Wait()
}

// AddDevice adds the given devices to the VirtualMachine
func (v VirtualMachine) AddDevice(device ...types.BaseVirtualDevice) error {
	return v.configureDevice(types.VirtualDeviceConfigSpecOperationAdd, device...)
}

// EditDevice edits the given (existing) devices on the VirtualMachine
func (v VirtualMachine) EditDevice(device ...types.BaseVirtualDevice) error {
	return v.configureDevice(types.VirtualDeviceConfigSpecOperationEdit, device...)
}

// RemoveDevice removes the given devices on the VirtualMachine
func (v VirtualMachine) RemoveDevice(device ...types.BaseVirtualDevice) error {
	return v.configureDevice(types.VirtualDeviceConfigSpecOperationRemove, device...)
}
<|endoftext|>


<commit_before>// Package watcher is used for watching files and directories
// for automatic recompilation and restart of app on change
// when in development mode.
package watcher

import (
	"errors"
	"os"
	"path/filepath"
	"sync"

	"github.com/anonx/sunplate/log"

	"gopkg.in/fsnotify.v1"
)

// Type is a watcher type that allows registering new
// pattern - actions pairs.
type Type struct {
	mu       sync.Mutex
	watchers []*fsnotify.Watcher
}

// NewType allocates and returns a new instance of watcher Type.
func NewType() *Type {
	return &Type{}
}

// Listen gets a pattern and a function. The function will be executed
// when files matching the pattern will be modified.
func (t *Type) Listen(pattern string, fn func()) {
	// Create a new watcher.
	w, err := fsnotify.NewWatcher()
	log.AssertNil(err)

	// Replace the unbuffered Event channel with a buffered one.
	// Otherwise multiple change events only come out one at a time.
	w.Events = make(chan fsnotify.Event, 100)
	w.Errors = make(chan error, 10)

	// Find directories matching the pattern.
	ds := glob(pattern)
	if err != nil {
		log.Error.Panicf("Pattern `%s` is malformed. Error: %v.", pattern, err)
	}

	// Add the files to the watcher.
	for i := range ds {
		log.Trace.Printf(`Adding "%s" to the list of watched directories...`, ds[i])
		err := w.Add(ds[i])
		if err != nil {
			log.Warn.Println(err)
		}
	}

	// Add watcher to the list.
	i := len(t.watchers)
	t.watchers = append(t.watchers, w)

	// Start watching process.
	go t.NotifyOnUpdate(i, fn)
}

// NotifyOnUpdate starts the function every time a file change
// event is received. Start it as a goroutine.
func (t *Type) NotifyOnUpdate(watcherIndex int, fn func()) {
	for {
		select {
		case ev := <-t.watchers[watcherIndex].Events:
			if restartRequired(ev) {
				t.mu.Lock()
				fn()
				t.mu.Unlock()
			}
		case err := <-t.watchers[watcherIndex].Errors:
			log.Warn.Println(err)
		}
	}
}

// restartRequired checks whether event indicates a file
// has been modified. If so, it returns true.
func restartRequired(event fsnotify.Event) bool {
	if event.Op&fsnotify.Chmod == fsnotify.Chmod {
		return true
	}
	return false
}

// glob returns names of all directories matching pattern or nil.
// The only supported special character is an asterisk at the end.
// It means that the directory is expected to be scanned recursively.
// There is no way for fsnotify to watch individual files (see #17),
// do we support only directories.
// File system errors such as I/O reading are ignored.
func glob(pattern string) (ds []string) {
	// Check whether recursive scan is expected.
	l := len(pattern)
	if l == 0 || pattern[l-1] != '*' {
		ds = append(ds, pattern)
		return // Return as is.
	}

	// Otherwise, trim the asterisk at the end.
	pattern = pattern[:l-1]

	// Start searching directories recursively.
	filepath.Walk(pattern, func(path string, info os.FileInfo, err error) error {
		// Make sure there are no any errors.
		if err != nil {
			return err
		}

		// Make sure the path represents a directory.
		if info.IsDir() {
			ds = append(ds, path) // Add current path to the list.
			return nil
		}

		// Otherwise, return an error.
		return errors.New("not a directory")
	})
	return
}
<commit_msg>Fixing race condition in watcher<commit_after>// Package watcher is used for watching files and directories
// for automatic recompilation and restart of app on change
// when in development mode.
package watcher

import (
	"errors"
	"os"
	"path/filepath"
	"sync"

	"github.com/anonx/sunplate/log"

	"gopkg.in/fsnotify.v1"
)

// Type is a watcher type that allows registering new
// pattern - actions pairs.
type Type struct {
	mu       sync.Mutex
	watchers []*fsnotify.Watcher
}

// NewType allocates and returns a new instance of watcher Type.
func NewType() *Type {
	return &Type{}
}

// Listen gets a pattern and a function. The function will be executed
// when files matching the pattern will be modified.
func (t *Type) Listen(pattern string, fn func()) {
	// Create a new watcher.
	w, err := fsnotify.NewWatcher()
	log.AssertNil(err)

	// Find directories matching the pattern.
	ds := glob(pattern)
	if err != nil {
		log.Error.Panicf("Pattern `%s` is malformed. Error: %v.", pattern, err)
	}

	// Add the files to the watcher.
	for i := range ds {
		log.Trace.Printf(`Adding "%s" to the list of watched directories...`, ds[i])
		err := w.Add(ds[i])
		if err != nil {
			log.Warn.Println(err)
		}
	}

	// Add watcher to the list.
	i := len(t.watchers)
	t.watchers = append(t.watchers, w)

	// Start watching process.
	go t.NotifyOnUpdate(i, fn)
}

// NotifyOnUpdate starts the function every time a file change
// event is received. Start it as a goroutine.
func (t *Type) NotifyOnUpdate(watcherIndex int, fn func()) {
	for {
		select {
		case ev := <-t.watchers[watcherIndex].Events:
			if restartRequired(ev) {
				t.mu.Lock()
				log.Warn.Println("Cought event...")
				fn()
				t.mu.Unlock()
			}
		case err := <-t.watchers[watcherIndex].Errors:
			log.Warn.Println(err)
		}
	}
}

// restartRequired checks whether event indicates a file
// has been modified. If so, it returns true.
func restartRequired(event fsnotify.Event) bool {
	if event.Op&fsnotify.Chmod == fsnotify.Chmod {
		return true
	}
	return false
}

// glob returns names of all directories matching pattern or nil.
// The only supported special character is an asterisk at the end.
// It means that the directory is expected to be scanned recursively.
// There is no way for fsnotify to watch individual files (see #17),
// do we support only directories.
// File system errors such as I/O reading are ignored.
func glob(pattern string) (ds []string) {
	// Check whether recursive scan is expected.
	l := len(pattern)
	if l == 0 || pattern[l-1] != '*' {
		ds = append(ds, pattern)
		return // Return as is.
	}

	// Otherwise, trim the asterisk at the end.
	pattern = pattern[:l-1]

	// Start searching directories recursively.
	filepath.Walk(pattern, func(path string, info os.FileInfo, err error) error {
		// Make sure there are no any errors.
		if err != nil {
			return err
		}

		// Make sure the path represents a directory.
		if info.IsDir() {
			ds = append(ds, path) // Add current path to the list.
			return nil
		}

		// Otherwise, return an error.
		return errors.New("not a directory")
	})
	return
}
<|endoftext|>


<commit_before>// +build linux
// +build !fsnotify

package notify

import (
	"bytes"
	"errors"
	"fmt"
	"path/filepath"
	"runtime"
	"sync"
	"sync/atomic"
	"syscall"
	"unsafe"
)

// eventBufferSize defines the size of the buffer given to read(2) function. One
// should not depend on this value, since it was arbitrary chosen and may be
// changed in the future.
const eventBufferSize = 64 * (syscall.SizeofInotifyEvent + syscall.PathMax + 1)

// consumersCount defines the number of consumers in producer-consumer based
// implementation. Each consumer is run in a separate goroutine and has read
// access to watched files map.
const consumersCount = 2

const invalidDescriptor = -1

// watched is a pair of file pathname and inotify mask used as a value in
// watched files map.
type watched struct {
	pathname string
	mask     uint32
}

// watcher implements Watcher interface.
type watcher struct {
	sync.RWMutex
	m      map[int32]*watched
	fd     int32
	pipefd []int
	epfd   int
	epes   []syscall.EpollEvent
	buffer [eventBufferSize]byte
	wg     sync.WaitGroup
	c      chan<- EventInfo
}

// NewWatcher creates new non-recursive watcher backed by inotify.
func newWatcher(c chan<- EventInfo) (w *watcher) {
	w = &watcher{
		m:      make(map[int32]*watched),
		fd:     invalidDescriptor,
		pipefd: []int{invalidDescriptor, invalidDescriptor},
		epfd:   invalidDescriptor,
		epes:   make([]syscall.EpollEvent, 0, 2),
		c:      c,
	}
	runtime.SetFinalizer(w, func(w *watcher) {
		w.epollclose()
		if w.fd != invalidDescriptor {
			syscall.Close(int(w.fd))
		}
	})
	return
}

// Watch implements notify.Watcher interface.
func (w *watcher) Watch(pathname string, e Event) error {
	return w.watch(pathname, e)
}

// Rewatch implements notify.Watcher interface.
func (w *watcher) Rewatch(pathname string, _, newevent Event) error {
	return w.watch(pathname, newevent)
}

// TODO : pknap
func (w *watcher) watch(pathname string, e Event) (err error) {
	// Adding new filters with IN_MASK_ADD mask is not supported.
	e &^= Event(syscall.IN_MASK_ADD)
	if e&^(All|IN_ALL_EVENTS) != 0 {
		return errors.New("notify: unknown event")
	}
	if err = w.lazyinit(); err != nil {
		return
	}
	iwd, err := syscall.InotifyAddWatch(int(w.fd), pathname, encode(e))
	if err != nil {
		return
	}
	w.RLock()
	wd := w.m[int32(iwd)]
	w.RUnlock()
	if wd == nil {
		w.Lock()
		if w.m[int32(iwd)] == nil {
			w.m[int32(iwd)] = &watched{pathname: pathname, mask: uint32(e)}
		}
		w.Unlock()
	} else {
		atomic.StoreUint32(&wd.mask, uint32(e))
	}
	return nil
}

// TODO : pknap
func (w *watcher) lazyinit() error {
	if atomic.LoadInt32(&w.fd) == invalidDescriptor {
		w.Lock()
		defer w.Unlock()
		if atomic.LoadInt32(&w.fd) == invalidDescriptor {
			fd, err := syscall.InotifyInit()
			if err != nil {
				return err
			}
			atomic.StoreInt32(&w.fd, int32(fd))
			if err = w.epollinit(); err != nil {
				w.epollclose()
				return err
			}
			esch := make(chan []*event)
			go w.loop(esch)
			w.wg.Add(consumersCount)
			for i := 0; i < consumersCount; i++ {
				go w.send(esch)
			}
		}
	}
	return nil
}

// TODO : pknap
func (w *watcher) epollinit() (err error) {
	if w.epfd, err = syscall.EpollCreate(2); err != nil {
		return
	}
	if err = syscall.Pipe(w.pipefd); err != nil {
		return
	}
	w.epes = []syscall.EpollEvent{
		syscall.EpollEvent{syscall.EPOLLIN, int32(w.fd), 0},
		syscall.EpollEvent{syscall.EPOLLIN, int32(w.pipefd[0]), 0},
	}
	if err = syscall.EpollCtl(
		w.epfd, syscall.EPOLL_CTL_ADD, int(w.fd), &w.epes[0]); err != nil {
		return
	}
	return syscall.EpollCtl(
		w.epfd, syscall.EPOLL_CTL_ADD, w.pipefd[0], &w.epes[1])
}

// TODO : pknap
func (w *watcher) epollclose() (err error) {
	if w.epfd != invalidDescriptor {
		if err = syscall.Close(w.epfd); err == nil {
			w.epfd = invalidDescriptor
		}
	}
	for i, fd := range w.pipefd {
		if fd != invalidDescriptor {
			switch e := syscall.Close(fd); {
			case e != nil && err == nil:
				err = e
			case e == nil:
				w.pipefd[i] = invalidDescriptor
			}
		}
	}
	return
}

// TODO : pknap
func (w *watcher) loop(esch chan<- []*event) {
	epes := make([]syscall.EpollEvent, 1)
	fd := atomic.LoadInt32(&w.fd)
	for {
		if _, err := syscall.EpollWait(w.epfd, epes, -1); err != nil {
			// Panic? error?
		}
		switch epes[0].Fd {
		case fd:
			fmt.Println("Send events")
			esch <- w.read()
		case int32(w.pipefd[0]):
			fmt.Println("break the loop")
			w.Lock()
			defer w.Unlock()
			if err := syscall.Close(int(fd)); err != nil {
				// Panic? error?
			} else {
				atomic.StoreInt32(&w.fd, invalidDescriptor)
			}
			w.epollclose()
			close(esch)
			return
		}
	}
}

// TODO(ppknap) : doc.
func (w *watcher) read() (es []*event) {
	n, err := syscall.Read(int(w.fd), w.buffer[:])
	fmt.Println("read :", n, " err ", err, "   ")
	switch {
	case err != nil || n < 0:
		// TODO(rjeczalik): Panic, error?
		fmt.Println("Error:( ", err)
		return
	case n < syscall.SizeofInotifyEvent:
		return
	}
	var sys *syscall.InotifyEvent
	nmin := n - syscall.SizeofInotifyEvent
	for pos, pathname := 0, ""; pos <= nmin; {
		sys = (*syscall.InotifyEvent)(unsafe.Pointer(&w.buffer[pos]))
		pos += syscall.SizeofInotifyEvent
		if pathname = ""; sys.Len > 0 {
			endpos := pos + int(sys.Len)
			pathname = string(bytes.TrimRight(w.buffer[pos:endpos], "\x00"))
			pos = endpos
		}
		es = append(es, &event{sys: syscall.InotifyEvent{
			Wd:     sys.Wd,
			Mask:   sys.Mask,
			Cookie: sys.Cookie,
		}, impl: watched{pathname: pathname}})
	}
	return
}

// TODO(ppknap) : doc.
func (w *watcher) send(esch <-chan []*event) {
	for es := range esch {
		for _, e := range w.strip(es) {
			if e != nil {
				w.c <- e
			}
		}
	}
	fmt.Println("Done")
	w.wg.Done()
}

// TODO(ppknap) : doc.
func (w *watcher) strip(es []*event) []*event {
	w.RLock()
	for i, e := range es {
		if e.sys.Mask&(syscall.IN_IGNORED|syscall.IN_Q_OVERFLOW) != 0 {
			es[i] = nil
			continue
		}
		wd, ok := w.m[e.sys.Wd]
		if !ok || e.sys.Mask&encode(Event(wd.mask)) == 0 {
			es[i] = nil
			continue
		}
		e.impl.mask = wd.mask
		if e.impl.pathname == "" {
			e.impl.pathname = wd.pathname
		} else {
			e.impl.pathname = filepath.Join(wd.pathname, e.impl.pathname)
		}
	}
	w.RUnlock()
	return es
}

// TODO(ppknap) : doc.
func encode(e Event) uint32 {
	if e&Create != 0 {
		e = (e ^ Create) | IN_CREATE | IN_MOVED_TO
	}
	if e&Delete != 0 {
		e = (e ^ Delete) | IN_DELETE | IN_DELETE_SELF
	}
	if e&Write != 0 {
		e = (e ^ Write) | IN_MODIFY
	}
	if e&Move != 0 {
		e = (e ^ Move) | IN_MOVED_FROM | IN_MOVE_SELF
	}
	return uint32(e)
}

// Unwatch implements notify.Watcher interface.
func (w *watcher) Unwatch(pathname string) (err error) {
	iwd := int32(-1)
	w.RLock()
	for iwdkey, wd := range w.m {
		if wd.pathname == pathname {
			iwd = iwdkey
			break
		}
	}
	w.RUnlock()
	if iwd < 0 {
		return errors.New("notify: file/dir " + pathname + " is unwatched")
	}
	if _, err = syscall.InotifyRmWatch(
		int(atomic.LoadInt32(&w.fd)), uint32(iwd)); err != nil {
		return
	}
	w.Lock()
	delete(w.m, iwd)
	w.Unlock()
	return nil
}

// Dispatch implements notify.Watcher interface.
//
// TODO(rjeczalik): remove
func (w *watcher) Dispatch(c chan<- EventInfo, stop <-chan struct{}) {
	w.c = c
}

func (w *watcher) Close() (err error) {
	w.Lock()
	if fd := atomic.LoadInt32(&w.fd); fd == invalidDescriptor {
		w.Unlock()
		return nil
	}
	for iwdkey, _ := range w.m {
		if _, e := syscall.InotifyRmWatch(
			int(w.fd), uint32(iwdkey)); e != nil && err == nil {
			err = e
		}
		delete(w.m, iwdkey)
	}
	if _, e := syscall.Write(
		w.pipefd[1], []byte{0x00}); e != nil && err == nil {
		err = e
	}
	w.Unlock()
	w.wg.Wait()
	return
}

// TODO(ppknap) : doc.
func decode(mask, syse uint32) Event {
	imask := encode(Event(mask))
	switch {
	case mask&syse != 0:
		return Event(syse)
	case imask&uint32(IN_CREATE|IN_MOVED_TO)&syse != 0:
		return Create
	case imask&uint32(IN_DELETE|IN_DELETE_SELF)&syse != 0:
		return Delete
	case imask&uint32(IN_MODIFY)&syse != 0:
		return Write
	case imask&uint32(IN_MOVED_FROM|IN_MOVE_SELF)&syse != 0:
		return Move
	}
	panic("notify: cannot decode internal mask")
}
<commit_msg>inotify: fix for go vet<commit_after>// +build linux
// +build !fsnotify

package notify

import (
	"bytes"
	"errors"
	"fmt"
	"path/filepath"
	"runtime"
	"sync"
	"sync/atomic"
	"syscall"
	"unsafe"
)

// eventBufferSize defines the size of the buffer given to read(2) function. One
// should not depend on this value, since it was arbitrary chosen and may be
// changed in the future.
const eventBufferSize = 64 * (syscall.SizeofInotifyEvent + syscall.PathMax + 1)

// consumersCount defines the number of consumers in producer-consumer based
// implementation. Each consumer is run in a separate goroutine and has read
// access to watched files map.
const consumersCount = 2

const invalidDescriptor = -1

// watched is a pair of file pathname and inotify mask used as a value in
// watched files map.
type watched struct {
	pathname string
	mask     uint32
}

// watcher implements Watcher interface.
type watcher struct {
	sync.RWMutex
	m      map[int32]*watched
	fd     int32
	pipefd []int
	epfd   int
	epes   []syscall.EpollEvent
	buffer [eventBufferSize]byte
	wg     sync.WaitGroup
	c      chan<- EventInfo
}

// NewWatcher creates new non-recursive watcher backed by inotify.
func newWatcher(c chan<- EventInfo) (w *watcher) {
	w = &watcher{
		m:      make(map[int32]*watched),
		fd:     invalidDescriptor,
		pipefd: []int{invalidDescriptor, invalidDescriptor},
		epfd:   invalidDescriptor,
		epes:   make([]syscall.EpollEvent, 0, 2),
		c:      c,
	}
	runtime.SetFinalizer(w, func(w *watcher) {
		w.epollclose()
		if w.fd != invalidDescriptor {
			syscall.Close(int(w.fd))
		}
	})
	return
}

// Watch implements notify.Watcher interface.
func (w *watcher) Watch(pathname string, e Event) error {
	return w.watch(pathname, e)
}

// Rewatch implements notify.Watcher interface.
func (w *watcher) Rewatch(pathname string, _, newevent Event) error {
	return w.watch(pathname, newevent)
}

// TODO : pknap
func (w *watcher) watch(pathname string, e Event) (err error) {
	// Adding new filters with IN_MASK_ADD mask is not supported.
	e &^= Event(syscall.IN_MASK_ADD)
	if e&^(All|IN_ALL_EVENTS) != 0 {
		return errors.New("notify: unknown event")
	}
	if err = w.lazyinit(); err != nil {
		return
	}
	iwd, err := syscall.InotifyAddWatch(int(w.fd), pathname, encode(e))
	if err != nil {
		return
	}
	w.RLock()
	wd := w.m[int32(iwd)]
	w.RUnlock()
	if wd == nil {
		w.Lock()
		if w.m[int32(iwd)] == nil {
			w.m[int32(iwd)] = &watched{pathname: pathname, mask: uint32(e)}
		}
		w.Unlock()
	} else {
		atomic.StoreUint32(&wd.mask, uint32(e))
	}
	return nil
}

// TODO : pknap
func (w *watcher) lazyinit() error {
	if atomic.LoadInt32(&w.fd) == invalidDescriptor {
		w.Lock()
		defer w.Unlock()
		if atomic.LoadInt32(&w.fd) == invalidDescriptor {
			fd, err := syscall.InotifyInit()
			if err != nil {
				return err
			}
			atomic.StoreInt32(&w.fd, int32(fd))
			if err = w.epollinit(); err != nil {
				w.epollclose()
				return err
			}
			esch := make(chan []*event)
			go w.loop(esch)
			w.wg.Add(consumersCount)
			for i := 0; i < consumersCount; i++ {
				go w.send(esch)
			}
		}
	}
	return nil
}

// TODO : pknap
func (w *watcher) epollinit() (err error) {
	if w.epfd, err = syscall.EpollCreate(2); err != nil {
		return
	}
	if err = syscall.Pipe(w.pipefd); err != nil {
		return
	}
	w.epes = []syscall.EpollEvent{
		syscall.EpollEvent{Events: syscall.EPOLLIN, Fd: int32(w.fd), Pad: 0},
		syscall.EpollEvent{Events: syscall.EPOLLIN, Fd: int32(w.pipefd[0]), Pad: 0},
	}
	if err = syscall.EpollCtl(
		w.epfd, syscall.EPOLL_CTL_ADD, int(w.fd), &w.epes[0]); err != nil {
		return
	}
	return syscall.EpollCtl(
		w.epfd, syscall.EPOLL_CTL_ADD, w.pipefd[0], &w.epes[1])
}

// TODO : pknap
func (w *watcher) epollclose() (err error) {
	if w.epfd != invalidDescriptor {
		if err = syscall.Close(w.epfd); err == nil {
			w.epfd = invalidDescriptor
		}
	}
	for i, fd := range w.pipefd {
		if fd != invalidDescriptor {
			switch e := syscall.Close(fd); {
			case e != nil && err == nil:
				err = e
			case e == nil:
				w.pipefd[i] = invalidDescriptor
			}
		}
	}
	return
}

// TODO : pknap
func (w *watcher) loop(esch chan<- []*event) {
	epes := make([]syscall.EpollEvent, 1)
	fd := atomic.LoadInt32(&w.fd)
	for {
		if _, err := syscall.EpollWait(w.epfd, epes, -1); err != nil {
			// Panic? error?
		}
		switch epes[0].Fd {
		case fd:
			fmt.Println("Send events")
			esch <- w.read()
		case int32(w.pipefd[0]):
			fmt.Println("break the loop")
			w.Lock()
			defer w.Unlock()
			if err := syscall.Close(int(fd)); err != nil {
				// Panic? error?
			} else {
				atomic.StoreInt32(&w.fd, invalidDescriptor)
			}
			w.epollclose()
			close(esch)
			return
		}
	}
}

// TODO(ppknap) : doc.
func (w *watcher) read() (es []*event) {
	n, err := syscall.Read(int(w.fd), w.buffer[:])
	fmt.Println("read :", n, " err ", err, "   ")
	switch {
	case err != nil || n < 0:
		// TODO(rjeczalik): Panic, error?
		fmt.Println("Error:( ", err)
		return
	case n < syscall.SizeofInotifyEvent:
		return
	}
	var sys *syscall.InotifyEvent
	nmin := n - syscall.SizeofInotifyEvent
	for pos, pathname := 0, ""; pos <= nmin; {
		sys = (*syscall.InotifyEvent)(unsafe.Pointer(&w.buffer[pos]))
		pos += syscall.SizeofInotifyEvent
		if pathname = ""; sys.Len > 0 {
			endpos := pos + int(sys.Len)
			pathname = string(bytes.TrimRight(w.buffer[pos:endpos], "\x00"))
			pos = endpos
		}
		es = append(es, &event{sys: syscall.InotifyEvent{
			Wd:     sys.Wd,
			Mask:   sys.Mask,
			Cookie: sys.Cookie,
		}, impl: watched{pathname: pathname}})
	}
	return
}

// TODO(ppknap) : doc.
func (w *watcher) send(esch <-chan []*event) {
	for es := range esch {
		for _, e := range w.strip(es) {
			if e != nil {
				w.c <- e
			}
		}
	}
	fmt.Println("Done")
	w.wg.Done()
}

// TODO(ppknap) : doc.
func (w *watcher) strip(es []*event) []*event {
	w.RLock()
	for i, e := range es {
		if e.sys.Mask&(syscall.IN_IGNORED|syscall.IN_Q_OVERFLOW) != 0 {
			es[i] = nil
			continue
		}
		wd, ok := w.m[e.sys.Wd]
		if !ok || e.sys.Mask&encode(Event(wd.mask)) == 0 {
			es[i] = nil
			continue
		}
		e.impl.mask = wd.mask
		if e.impl.pathname == "" {
			e.impl.pathname = wd.pathname
		} else {
			e.impl.pathname = filepath.Join(wd.pathname, e.impl.pathname)
		}
	}
	w.RUnlock()
	return es
}

// TODO(ppknap) : doc.
func encode(e Event) uint32 {
	if e&Create != 0 {
		e = (e ^ Create) | IN_CREATE | IN_MOVED_TO
	}
	if e&Delete != 0 {
		e = (e ^ Delete) | IN_DELETE | IN_DELETE_SELF
	}
	if e&Write != 0 {
		e = (e ^ Write) | IN_MODIFY
	}
	if e&Move != 0 {
		e = (e ^ Move) | IN_MOVED_FROM | IN_MOVE_SELF
	}
	return uint32(e)
}

// Unwatch implements notify.Watcher interface.
func (w *watcher) Unwatch(pathname string) (err error) {
	iwd := int32(-1)
	w.RLock()
	for iwdkey, wd := range w.m {
		if wd.pathname == pathname {
			iwd = iwdkey
			break
		}
	}
	w.RUnlock()
	if iwd < 0 {
		return errors.New("notify: file/dir " + pathname + " is unwatched")
	}
	if _, err = syscall.InotifyRmWatch(
		int(atomic.LoadInt32(&w.fd)), uint32(iwd)); err != nil {
		return
	}
	w.Lock()
	delete(w.m, iwd)
	w.Unlock()
	return nil
}

// Dispatch implements notify.Watcher interface.
//
// TODO(rjeczalik): remove
func (w *watcher) Dispatch(c chan<- EventInfo, stop <-chan struct{}) {
	w.c = c
}

func (w *watcher) Close() (err error) {
	w.Lock()
	if fd := atomic.LoadInt32(&w.fd); fd == invalidDescriptor {
		w.Unlock()
		return nil
	}
	for iwdkey, _ := range w.m {
		if _, e := syscall.InotifyRmWatch(
			int(w.fd), uint32(iwdkey)); e != nil && err == nil {
			err = e
		}
		delete(w.m, iwdkey)
	}
	if _, e := syscall.Write(
		w.pipefd[1], []byte{0x00}); e != nil && err == nil {
		err = e
	}
	w.Unlock()
	w.wg.Wait()
	return
}

// TODO(ppknap) : doc.
func decode(mask, syse uint32) Event {
	imask := encode(Event(mask))
	switch {
	case mask&syse != 0:
		return Event(syse)
	case imask&uint32(IN_CREATE|IN_MOVED_TO)&syse != 0:
		return Create
	case imask&uint32(IN_DELETE|IN_DELETE_SELF)&syse != 0:
		return Delete
	case imask&uint32(IN_MODIFY)&syse != 0:
		return Write
	case imask&uint32(IN_MOVED_FROM|IN_MOVE_SELF)&syse != 0:
		return Move
	}
	panic("notify: cannot decode internal mask")
}
<|endoftext|>


<commit_before>// Copyright 2013 Prometheus Team
// 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 api

import (
	"github.com/prometheus/prometheus/model"
	"github.com/prometheus/prometheus/retrieval"
	"net/http"
	"time"
)

type TargetGroup struct {
	Endpoints  []string          `json:"endpoints"`
	BaseLabels map[string]string `json:"baseLabels"`
}

func (serv MetricsService) SetTargets(targetGroups []TargetGroup, jobName string) {
	if job := serv.appState.Config.GetJobByName(jobName); job == nil {
		rb := serv.ResponseBuilder()
		rb.SetResponseCode(http.StatusNotFound)
	} else {
		newTargets := []retrieval.Target{}
		for _, targetGroup := range targetGroups {
			// Do mandatory map type conversion due to Go shortcomings.
			baseLabels := model.LabelSet{}
			for label, value := range targetGroup.BaseLabels {
				baseLabels[model.LabelName(label)] = model.LabelValue(value)
			}

			for _, endpoint := range targetGroup.Endpoints {
				newTarget := retrieval.NewTarget(endpoint, time.Second*5, baseLabels)
				newTargets = append(newTargets, newTarget)
			}
		}
		serv.appState.TargetManager.ReplaceTargets(job, newTargets, serv.appState.Config.Global.ScrapeInterval)
	}
}
<commit_msg>Set job label for targets registered through the API<commit_after>// Copyright 2013 Prometheus Team
// 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 api

import (
	"github.com/prometheus/prometheus/model"
	"github.com/prometheus/prometheus/retrieval"
	"net/http"
	"time"
)

type TargetGroup struct {
	Endpoints  []string          `json:"endpoints"`
	BaseLabels map[string]string `json:"baseLabels"`
}

func (serv MetricsService) SetTargets(targetGroups []TargetGroup, jobName string) {
	if job := serv.appState.Config.GetJobByName(jobName); job == nil {
		rb := serv.ResponseBuilder()
		rb.SetResponseCode(http.StatusNotFound)
	} else {
		newTargets := []retrieval.Target{}
		for _, targetGroup := range targetGroups {
			// Do mandatory map type conversion due to Go shortcomings.
			baseLabels := model.LabelSet{
				model.LabelName("job"): model.LabelValue(job.Name),
			}
			for label, value := range targetGroup.BaseLabels {
				baseLabels[model.LabelName(label)] = model.LabelValue(value)
			}

			for _, endpoint := range targetGroup.Endpoints {
				newTarget := retrieval.NewTarget(endpoint, time.Second*5, baseLabels)
				newTargets = append(newTargets, newTarget)
			}
		}
		serv.appState.TargetManager.ReplaceTargets(job, newTargets, serv.appState.Config.Global.ScrapeInterval)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"os/exec"
	"strings"

	"golang.org/x/sys/unix"
)

// WrapperCommand represents components necessary for OAuth2l request
type WrapperCommand struct {
	RequestType string
	Args
	Credential
}

// Args type used for unmarshalled JSON
type Args map[string]interface{}

// Credential type used for storing JSON-formatted credentials
type Credential map[string]interface{}

// Execute will capture output of OAuth2l CLI using command args
func (wc WrapperCommand) Execute() (output string, err error) {
	// combinedArgs used to represent command arguments in an array
	args, err := combinedArgs(wc)

	if err != nil {
		return "", err
	}

	// Check if credential is provided to include in oauth2l command
	if wc.Credential != nil {
		// Symlink path to memory file
		path, err := getCredentialPath(wc.Credential)

		if err != nil {
			return "", err
		}

		args = append(args, "--credentials", path)
	}

	// Execute command and capture output
	command := exec.Command("oauth2l", args...)
	byteBuffer, err := command.Output()

	// Convert byteBuffer to string and remove newline character
	output = strings.TrimSuffix(string(byteBuffer), "\n")

	return output, err
}

func allocateMemFile(credential Credential) (descriptor int, err error) {
	// Init cred with credential body
	cred := credential["credential"]

	byteArray := []byte(cred.(string))

	// Create an anonymous file on the RAM, once all references to descriptor are dropped, file is released
	descriptor, err = unix.MemfdCreate("credential", 0)

	if err != nil {
		return 0, err
	}

	// Truncate file size to match size of our credential body
	err = unix.Ftruncate(descriptor, int64(len(byteArray)))
	if err != nil {
		return 0, err
	}

	// Map file to memory and assign virtual address
	address, err := unix.Mmap(descriptor, 0, len(byteArray), unix.PROT_READ, unix.MAP_SHARED)
	if err != nil {
		return 0, err
	}

	// Copy credential body into allocated memory
	copy(address, byteArray)

	// Delete data memory mapping as body is now written to memory
	err = unix.Munmap(address)
	if err != nil {
		return 0, err
	}

	// Returns file descriptor
	return descriptor, nil
}

func getCredentialPath(credential Credential) (path string, err error) {
	// Gets a file descriptor for a memory allocated credential file
	descriptor, err := allocateMemFile(credential)

	if err != nil {
		return "", err
	}

	path = fmt.Sprintf("/proc/self/fd/%d", descriptor)

	return path, nil
}

// Returns args in flattened array
func combinedArgs(wc WrapperCommand) (combinedArgs []string, err error) {
	combinedArgs = append(combinedArgs, wc.RequestType)

	for flag, value := range wc.Args {
		combinedArgs = append(combinedArgs, flag)

		// Assert args are of accepted types
		switch value := value.(type) {
		case []string:
			combinedArgs = append(combinedArgs, value...)
		case string:
			combinedArgs = append(combinedArgs, value)
		case []interface{}:
			for _, subValue := range value {
				combinedArgs = append(combinedArgs, subValue.(string))
			}
		default:
			return nil, errors.New("invalid type found in args")
		}
	}
	return combinedArgs, nil
}
<commit_msg>Add write permission again and change variable naming to match linux docs<commit_after>package main

import (
	"errors"
	"fmt"
	"os/exec"
	"strings"

	"golang.org/x/sys/unix"
)

// WrapperCommand represents components necessary for OAuth2l request
type WrapperCommand struct {
	RequestType string
	Args
	Credential
}

// Args type used for unmarshalled JSON
type Args map[string]interface{}

// Credential type used for storing JSON-formatted credentials
type Credential map[string]interface{}

// Execute will capture output of OAuth2l CLI using command args
func (wc WrapperCommand) Execute() (output string, err error) {
	// combinedArgs used to represent command arguments in an array
	args, err := combinedArgs(wc)

	if err != nil {
		return "", err
	}

	// Check if credential is provided to include in oauth2l command
	if wc.Credential != nil {
		// Symlink path to memory file
		path, err := getCredentialPath(wc.Credential)

		if err != nil {
			return "", err
		}

		args = append(args, "--credentials", path)
	}

	// Execute command and capture output
	command := exec.Command("oauth2l", args...)
	byteBuffer, err := command.Output()

	// Convert byteBuffer to string and remove newline character
	output = strings.TrimSuffix(string(byteBuffer), "\n")

	return output, err
}

func allocateMemFile(credential Credential) (descriptor int, err error) {
	// Init cred with credential body
	cred := credential["credential"]

	byteArray := []byte(cred.(string))

	// Create an anonymous file on the RAM, once all references to descriptor are dropped, file is released
	descriptor, err = unix.MemfdCreate("credential", 0)

	if err != nil {
		return 0, err
	}

	// Truncate file size to match size of our credential body
	err = unix.Ftruncate(descriptor, int64(len(byteArray)))
	if err != nil {
		return 0, err
	}

	// Map file to memory and assign virtual address
	addr, err := unix.Mmap(descriptor, 0, len(byteArray), unix.PROT_READ|unix.PROT_WRITE, unix.MAP_SHARED)
	if err != nil {
		return 0, err
	}

	// Copy credential body into allocated memory
	copy(addr, byteArray)

	// Delete data memory mapping as body is now written to memory
	err = unix.Munmap(addr)
	if err != nil {
		return 0, err
	}

	// Returns file descriptor
	return descriptor, nil
}

func getCredentialPath(credential Credential) (path string, err error) {
	// Gets a file descriptor for a memory allocated credential file
	descriptor, err := allocateMemFile(credential)

	if err != nil {
		return "", err
	}

	path = fmt.Sprintf("/proc/self/fd/%d", descriptor)

	return path, nil
}

// Returns args in flattened array
func combinedArgs(wc WrapperCommand) (combinedArgs []string, err error) {
	combinedArgs = append(combinedArgs, wc.RequestType)

	for flag, value := range wc.Args {
		combinedArgs = append(combinedArgs, flag)

		// Assert args are of accepted types
		switch value := value.(type) {
		case []string:
			combinedArgs = append(combinedArgs, value...)
		case string:
			combinedArgs = append(combinedArgs, value)
		case []interface{}:
			for _, subValue := range value {
				combinedArgs = append(combinedArgs, subValue.(string))
			}
		default:
			return nil, errors.New("invalid type found in args")
		}
	}
	return combinedArgs, nil
}
<|endoftext|>


<commit_before>// stardew.rocks web server
//
// It contains a few HTTP handlers:
// - a static handler that serves files from /home/stardew/www.
// - a handler that serves the latest complete file save in XML format.
package main

import (
	"net/http"
	"os"
	"path/filepath"
	"strings"

	"github.com/nictuku/stardew-rocks/stardb"

	logging "github.com/op/go-logging"

	hs "github.com/gorilla/handlers"
	"gopkg.in/natefinch/lumberjack.v2"
)

var log = logging.MustGetLogger("stardew.rocks")

func wwwDir() string {
	home := os.Getenv("HOME")
	if home == "" {
		home = string(filepath.Separator)
	}
	return filepath.Clean(filepath.Join(home, "www"))
}

func Index(w http.ResponseWriter, r *http.Request) {
	http.ServeFile(w, r, filepath.Join(wwwDir(), "index.html"))
}

func GetFarms(w http.ResponseWriter, r *http.Request) {
	b, err := stardb.FarmsJSON()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	_, err = w.Write(b)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	return
}

func GetFarm(w http.ResponseWriter, r *http.Request) {
	farmid := strings.TrimPrefix(r.URL.Path, "/api/farm/")

	b, err := stardb.FarmJSON(farmid)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	_, err = w.Write(b)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	return
}

func Root(w http.ResponseWriter, r *http.Request) {
	if strings.HasPrefix(r.URL.Path, "/map") {
		LegacyMap(w, r)
		return
	}
	dir := wwwDir()
	http.FileServer(http.Dir(dir)).ServeHTTP(w, r)
}

// SearchFarms searches for farms or farmers. It looks for a query paramater "q".
func SearchFarms(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()

	q := r.Form.Get("q")
	if len(q) == 0 {
		w.Write([]byte("{}"))
		return
	}
	b, err := stardb.SearchFarmsJSON(q)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	_, err = w.Write(b)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	return
}

func RunHTTPServer() {
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		log.Error("Error starting www server:", err)
		// os.IsPermission doesn't match.
		if strings.Contains(err.Error(), "permission denied") {
			// Only for linux and port 80. Keeping here for future convenience.
			log.Error("Try: sudo setcap 'cap_net_bind_service=+ep' www")
		}
	}
}

func main() {

	serverlog := logging.NewBackendFormatter(logging.NewLogBackend(&lumberjack.Logger{
		Filename:   "/var/log/stardew/server.log",
		MaxSize:    500, // megabytes
		MaxBackups: 3,
		MaxAge:     28, //days
	}, "", 0), logging.GlogFormatter)

	formatted := logging.AddModuleLevel(serverlog)
	formatted.SetLevel(logging.INFO, "")

	stderr := logging.NewBackendFormatter(logging.NewLogBackend(os.Stderr, "", 0), logging.GlogFormatter)

	// Set the backends to be used and the default level.
	logging.SetBackend(stderr, formatted)

	combinedLog := &lumberjack.Logger{
		Filename:   "/var/log/stardew/access.log",
		MaxSize:    500, // megabytes
		MaxBackups: 3,
		MaxAge:     28, //days
	}

	dir := wwwDir()
	log.Infof("Serving files from %v", dir)
	http.Handle("/api/farms", hs.CombinedLoggingHandler(combinedLog, http.HandlerFunc(GetFarms)))
	http.Handle("/api/farm/", hs.CombinedLoggingHandler(combinedLog, http.HandlerFunc(GetFarm)))
	http.Handle("/api/search/farm", hs.CombinedLoggingHandler(combinedLog, http.HandlerFunc(SearchFarms)))

	http.Handle("/screenshot/", hs.CombinedLoggingHandler(combinedLog, http.HandlerFunc(ServeScreenshot)))
	//http.Handle("/saveGames/", logHandler(http.HandlerFunc(ServeGFSFile)))

	// This is served by the web app.
	http.Handle("/farm/", hs.CombinedLoggingHandler(combinedLog, http.HandlerFunc(Index)))

	// This is served from the filesystem, but / goes to index.html which has our web app.
	http.Handle("/", hs.CombinedLoggingHandler(combinedLog, http.HandlerFunc(Root)))
	RunHTTPServer()
}
<commit_msg>Allow URLs such as http://stardew.farm/56f360131700d41646571433<commit_after>// stardew.rocks web server
//
// It contains a few HTTP handlers:
// - a static handler that serves files from /home/stardew/www.
// - a handler that serves the latest complete file save in XML format.
package main

import (
	"fmt"
	"net/http"
	"os"
	"path/filepath"
	"strings"

	"github.com/nictuku/stardew-rocks/stardb"

	logging "github.com/op/go-logging"

	hs "github.com/gorilla/handlers"
	"gopkg.in/natefinch/lumberjack.v2"
)

var log = logging.MustGetLogger("stardew.rocks")

func wwwDir() string {
	home := os.Getenv("HOME")
	if home == "" {
		home = string(filepath.Separator)
	}
	return filepath.Clean(filepath.Join(home, "www"))
}

func Index(w http.ResponseWriter, r *http.Request) {
	http.ServeFile(w, r, filepath.Join(wwwDir(), "index.html"))
}

func GetFarms(w http.ResponseWriter, r *http.Request) {
	b, err := stardb.FarmsJSON()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	_, err = w.Write(b)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	return
}

func GetFarm(w http.ResponseWriter, r *http.Request) {
	farmid := strings.TrimPrefix(r.URL.Path, "/api/farm/")

	b, err := stardb.FarmJSON(farmid)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	_, err = w.Write(b)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	return
}

func Root(w http.ResponseWriter, r *http.Request) {
	if strings.HasPrefix(r.URL.Path, "/map") {
		LegacyMap(w, r)
		return
	}
	// Allow URLs such as http://stardew.farm/56f360131700d41646571433
	fmt.Println(len(r.URL.Path))
	if len(r.URL.Path) == 25 { // len("/56f360131700d41646571433")
		Index(w, r)
		return
	}
	dir := wwwDir()
	http.FileServer(http.Dir(dir)).ServeHTTP(w, r)
}

// SearchFarms searches for farms or farmers. It looks for a query paramater "q".
func SearchFarms(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()

	q := r.Form.Get("q")
	if len(q) == 0 {
		w.Write([]byte("{}"))
		return
	}
	b, err := stardb.SearchFarmsJSON(q)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	_, err = w.Write(b)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	return
}

func RunHTTPServer() {
	err := http.ListenAndServe(":8080", nil)
	if err != nil {
		log.Error("Error starting www server:", err)
		// os.IsPermission doesn't match.
		if strings.Contains(err.Error(), "permission denied") {
			// Only for linux and port 80. Keeping here for future convenience.
			log.Error("Try: sudo setcap 'cap_net_bind_service=+ep' www")
		}
	}
}

func main() {

	serverlog := logging.NewBackendFormatter(logging.NewLogBackend(&lumberjack.Logger{
		Filename:   "/var/log/stardew/server.log",
		MaxSize:    500, // megabytes
		MaxBackups: 3,
		MaxAge:     28, //days
	}, "", 0), logging.GlogFormatter)

	formatted := logging.AddModuleLevel(serverlog)
	formatted.SetLevel(logging.INFO, "")

	stderr := logging.NewBackendFormatter(logging.NewLogBackend(os.Stderr, "", 0), logging.GlogFormatter)

	// Set the backends to be used and the default level.
	logging.SetBackend(stderr, formatted)

	combinedLog := &lumberjack.Logger{
		Filename:   "/var/log/stardew/access.log",
		MaxSize:    500, // megabytes
		MaxBackups: 3,
		MaxAge:     28, //days
	}

	dir := wwwDir()
	log.Infof("Serving files from %v", dir)
	http.Handle("/api/farms", hs.CombinedLoggingHandler(combinedLog, http.HandlerFunc(GetFarms)))
	http.Handle("/api/farm/", hs.CombinedLoggingHandler(combinedLog, http.HandlerFunc(GetFarm)))
	http.Handle("/api/search/farm", hs.CombinedLoggingHandler(combinedLog, http.HandlerFunc(SearchFarms)))

	http.Handle("/screenshot/", hs.CombinedLoggingHandler(combinedLog, http.HandlerFunc(ServeScreenshot)))
	//http.Handle("/saveGames/", logHandler(http.HandlerFunc(ServeGFSFile)))

	// This is served by the web app.
	http.Handle("/farm/", hs.CombinedLoggingHandler(combinedLog, http.HandlerFunc(Index)))

	// This is served from the filesystem, but / goes to index.html which has our web app.
	http.Handle("/", hs.CombinedLoggingHandler(combinedLog, http.HandlerFunc(Root)))
	RunHTTPServer()
}
<|endoftext|>


<commit_before>package main

import "fmt"

func main() {
	const s = 20
	var as, bs int
	var a, b [s]int

	o := getdata(s)

	for i, j := 0, len(o)-1; j >= 0; i, j = i+1, j-1 {
		a[i], b[j] = as+o[i], bs+o[j]
		as, bs = as+o[i], bs+o[j]
	}
	fmt.Println(o)
	fmt.Println(a)
	fmt.Println(b)
}

func getdata(s int) []int {
	o := make([]int, s)
	for i, j := 0, s-1; i <= j; i, j = i+1, j-1 {
		o[i], o[j] = i+1, j+1
	}
	return o
}
<commit_msg>Adding multiple passes.<commit_after>package main

import (
	"fmt"
	"time"
)

func timeTrack(start time.Time, name string) {
	elapsed := time.Since(start)
	fmt.Printf("%s took %s", name, elapsed)
	fmt.Println()
}

func main() {
	defer timeTrack(time.Now(), "main")
	const s = 10
	const n = 1
	var as, bs int
	var a, b [s]int
	var p = false

	for z := 0; z < n; z++ {
		o := getOriginalData(s)

		for i, j := 0, len(o)-1; j >= 0; i, j = i+1, j-1 {
			a[i], b[j] = as+o[i], bs+o[j]
			as, bs = as+o[i], bs+o[j]
		}

		if p {
			fmt.Println(o)
			fmt.Println(a)
			fmt.Println(b)
			fmt.Println()
		}
	}

}

func getOriginalData(s int) []int {
	o := make([]int, s)
	for i, j := 0, s-1; i <= j; i, j = i+1, j-1 {
		o[i], o[j] = i+1, j+1
	}
	return o
}
<|endoftext|>


<commit_before>package binny

import (
	"bufio"
	"bytes"
	"encoding"
	"encoding/binary"
	"encoding/gob"
	"errors"
	"fmt"
	"io"
	"reflect"
	"unsafe"
)

var (
	// ErrNoPointer gets returned if the user passes a non-pointer to Decode
	ErrNoPointer = errors.New("can't decode to a non-pointer")
)

const DefaultDecoderBufferSize = 4096

// Unmarshaler is the interface implemented by objects that can unmarshal a binary representation of themselves.
// Implementing this bypasses reflection and is generally faster.
type Unmarshaler interface {
	UnmarshalBinny(dec *Decoder) error
}

// A Decoder reads binary data from an input stream, it also does a little bit of buffering.
type Decoder struct {
	r *bufio.Reader

	buf [16]byte
}

// NewDecoder is an alias for NewDecoder(r, DefaultDecoderBufferSize)
func NewDecoder(r io.Reader) *Decoder {
	return NewDecoderSize(r, DefaultDecoderBufferSize)
}

// NewDecoder returns a new decoder that reads from r with specific buffer size.
//
// The decoder introduces its own buffering and may
// read data from r beyond the requested values.
func NewDecoderSize(r io.Reader, sz int) *Decoder {
	if sz < 16 {
		sz = 16
	}

	return &Decoder{
		r: bufio.NewReaderSize(r, sz),
	}
}

// Reset discards any buffered data, resets all state, and switches
// the buffered reader to read from r.
func (dec *Decoder) Reset(r io.Reader) {
	dec.r.Reset(r)
}

func (dec *Decoder) readType() (Type, error) {
	b, err := dec.r.ReadByte()
	return Type(b), err
}

func (dec *Decoder) peekType() Type {
	b, _ := dec.r.ReadByte()
	dec.r.UnreadByte()
	return Type(b)
}

func (dec *Decoder) expectType(et Type) error {
	if t, _ := dec.readType(); t != et {
		return DecoderTypeError{et.String(), t}
	}
	return nil
}

// ReadBool returns a bool or an error.
func (dec *Decoder) ReadBool() (bool, error) {
	ft, _ := dec.readType()
	switch ft {
	case BoolTrue:
		return true, nil
	case BoolFalse:
		return false, nil
	}
	return false, DecoderTypeError{"Bool", ft}
}

func (dec *Decoder) ReadInt8() (int8, error) {
	if err := dec.expectType(Int8); err != nil {
		return 0, err
	}
	b, err := dec.r.ReadByte()
	return int8(b), err
}

func (dec *Decoder) ReadInt16() (int16, error) {
	if err := dec.expectType(Int16); err != nil {
		return 0, err
	}
	buf := dec.buf[:2]
	_, err := dec.Read(buf)
	return *(*int16)(unsafe.Pointer(&buf[0])), err
}

func (dec *Decoder) ReadInt32() (int32, error) {
	if err := dec.expectType(Int32); err != nil {
		return 0, err
	}
	buf := dec.buf[:4]
	_, err := dec.Read(buf)
	return *(*int32)(unsafe.Pointer(&buf[0])), err
}

func (dec *Decoder) ReadInt64() (int64, error) {
	if err := dec.expectType(Int64); err != nil {
		return 0, err
	}
	buf := dec.buf[:8]
	_, err := dec.Read(buf)
	return *(*int64)(unsafe.Pointer(&buf[0])), err
}

func (dec *Decoder) ReadVarInt() (int64, error) {
	if err := dec.expectType(VarInt); err != nil {
		return 0, err
	}
	return binary.ReadVarint(dec.r)
}

// ReadInt retruns an int/varint value and the size of it (8, 16, 32, 64) or an error.
func (dec *Decoder) ReadInt() (int64, uint8, error) {
	ft := dec.peekType()
	switch ft {
	case Int8:
		v, err := dec.ReadInt8()
		return int64(v), 8, err
	case Int16:
		v, err := dec.ReadInt16()
		return int64(v), 16, err
	case Int32:
		v, err := dec.ReadInt32()
		return int64(v), 32, err
	case Int64:
		v, err := dec.ReadInt64()
		return v, 64, err
	case VarInt:
		v, err := dec.ReadVarInt()
		return v, 64, err
	}
	return 0, 0, DecoderTypeError{"int", ft}
}

func (dec *Decoder) ReadUint8() (uint8, error) {
	if err := dec.expectType(Uint8); err != nil {
		return 0, err
	}
	return dec.r.ReadByte()
}

func (dec *Decoder) ReadUint16() (uint16, error) {
	if err := dec.expectType(Uint16); err != nil {
		return 0, err
	}
	buf := dec.buf[:2]
	_, err := dec.Read(buf)
	return *(*uint16)(unsafe.Pointer(&buf[0])), err
}

func (dec *Decoder) ReadUint32() (uint32, error) {
	if err := dec.expectType(Uint32); err != nil {
		return 0, err
	}
	buf := dec.buf[:4]
	_, err := dec.Read(buf)
	return *(*uint32)(unsafe.Pointer(&buf[0])), err
}

func (dec *Decoder) ReadUint64() (uint64, error) {
	if err := dec.expectType(Uint64); err != nil {
		return 0, err
	}
	buf := dec.buf[:8]
	_, err := dec.Read(buf)
	return *(*uint64)(unsafe.Pointer(&buf[0])), err
}

func (dec *Decoder) ReadVarUint() (uint64, error) {
	if err := dec.expectType(VarUint); err != nil {
		return 0, err
	}
	return binary.ReadUvarint(dec.r)
}

// ReadUint retruns an uint/varuint value and the size of it (8, 16, 32, 64) or an error.
func (dec *Decoder) ReadUint() (v uint64, sz uint8, err error) {
	ft := dec.peekType()
	switch ft {
	case Uint8:
		v, err := dec.ReadUint8()
		return uint64(v), 8, err
	case Uint16:
		v, err := dec.ReadUint16()
		return uint64(v), 16, err
	case Uint32:
		v, err := dec.ReadUint32()
		return uint64(v), 32, err
	case Uint64:
		v, err := dec.ReadUint64()
		return v, 64, err
	case VarUint:
		v, err := dec.ReadVarUint()
		return v, 64, err
	}
	return 0, 0, DecoderTypeError{"uint", ft}
}

// ReadFloat32 returns a float32 or an error.
func (dec *Decoder) ReadFloat32() (float32, error) {
	if err := dec.expectType(Float32); err != nil {
		return 0, err
	}
	buf := dec.buf[:4]
	_, err := dec.Read(buf)
	return *(*float32)(unsafe.Pointer(&buf[0])), err
}

// ReadFloat64 returns a float64 or an error.
func (dec *Decoder) ReadFloat64() (float64, error) {
	if err := dec.expectType(Float64); err != nil {
		return 0, err
	}
	buf := dec.buf[:8]
	_, err := dec.Read(buf)
	return *(*float64)(unsafe.Pointer(&buf[0])), err
}

// ReadComplex64 returns a complex64 or an error.
func (dec *Decoder) ReadComplex64() (complex64, error) {
	if err := dec.expectType(Complex64); err != nil {
		return 0, err
	}

	buf := dec.buf[:8]
	_, err := dec.Read(buf)
	return *(*complex64)(unsafe.Pointer(&buf[0])), err
}

// ReadComplex128 returns a complex128 or an error.
func (dec *Decoder) ReadComplex128() (complex128, error) {
	if err := dec.expectType(Complex128); err != nil {
		return 0, err
	}
	buf := dec.buf[:16]
	_, err := dec.Read(buf)
	return *(*complex128)(unsafe.Pointer(&buf[0])), err
}

func (dec *Decoder) readBytes(exp Type) ([]byte, error) {
	if err := dec.expectType(exp); err != nil {
		return nil, err
	}

	sz, _, err := dec.ReadUint()
	if err != nil || sz == 0 {
		return nil, err
	}

	buf := make([]byte, sz)
	_, err = io.ReadFull(dec.r, buf)
	return buf, err
}

// ReadBytes returns a byte slice.
func (dec *Decoder) ReadBytes() ([]byte, error) {
	return dec.readBytes(ByteSlice)
}

// ReadBytes returns a string.
func (dec *Decoder) ReadString() (string, error) {
	b, err := dec.readBytes(String)
	return string(b), err
}

// ReadBinary decodes and reads an object that implements the `encoding.BinaryUnmarshaler` interface.
func (dec *Decoder) ReadBinary(v encoding.BinaryUnmarshaler) error {
	b, err := dec.readBytes(Binary)
	if err != nil {
		return err
	}
	return v.UnmarshalBinary(b)
}

// ReadGob decodes and reads an object that implements the `gob.GobDecoder` interface.
func (dec *Decoder) ReadGob(v gob.GobDecoder) error {
	b, err := dec.readBytes(Gob)
	if err != nil {
		return err
	}
	return v.GobDecode(b)
}

// Decode reads the next binny-encoded value from its
// input and stores it in the value pointed to by v.
func (dec *Decoder) Decode(v interface{}) (err error) {
	switch v := v.(type) {
	case Unmarshaler:
		return v.UnmarshalBinny(dec)
	case encoding.BinaryUnmarshaler:
		return dec.ReadBinary(v)
	case gob.GobDecoder:
		return dec.ReadGob(v)
	case *string:
		*v, err = dec.ReadString()
		return
	case *[]byte:
		*v, err = dec.ReadBytes()
		return
	case *int64:
		*v, _, err = dec.ReadInt()
		return
	case *int32:
		var i int64
		i, _, err = dec.ReadInt()
		*v = int32(i)
		return
	case *int16:
		var i int64
		i, _, err = dec.ReadInt()
		*v = int16(i)
		return
	case *int8:
		var i int64
		i, _, err = dec.ReadInt()
		*v = int8(i)
		return
	case *int:
		var i int64
		i, _, err = dec.ReadInt()
		*v = int(i)
		return
	case *uint64:
		*v, _, err = dec.ReadUint()
		return
	case *uint32:
		var i uint64
		i, _, err = dec.ReadUint()
		*v = uint32(i)
		return
	case *uint16:
		var i uint64
		i, _, err = dec.ReadUint()
		*v = uint16(i)
		return
	case *uint8:
		var i uint64
		i, _, err = dec.ReadUint()
		*v = uint8(i)
		return
	case *uint:
		var i uint64
		i, _, err = dec.ReadUint()
		*v = uint(i)
		return
	case *uintptr:
		var i uint64
		i, _, err = dec.ReadUint()
		*v = uintptr(i)
		return
	case *float32:
		*v, err = dec.ReadFloat32()
		return
	case *float64:
		*v, err = dec.ReadFloat64()
		return
	case *complex64:
		*v, err = dec.ReadComplex64()
		return
	case *complex128:
		*v, err = dec.ReadComplex128()
		return
	case *bool:
		*v, err = dec.ReadBool()
		return
	case nil:
		return fmt.Errorf("can't decode a nil value")
	}
	return dec.decodeValue(reflect.ValueOf(v))
}

func (dec *Decoder) decodeValue(v reflect.Value) error {
	if v.Kind() != reflect.Ptr || !v.Elem().CanSet() {
		return ErrNoPointer
	}
	if v.IsNil() {
		return fmt.Errorf("can't decode a nil value: %v", v.Type())
	}
	fn := typeDecoder(v.Type())
	return fn(dec, v)
}

// Read allows the Decoder to be used as an io.Reader, note that internally this calls io.ReadFull().
func (dec *Decoder) Read(p []byte) (int, error) {
	return io.ReadFull(dec.r, p)
}

// Unmarshal is an alias for (sync.Pool'ed) NewDecoder(bytes.NewReader(b)).Decode(v)
func Unmarshal(b []byte, v interface{}) error {
	dec := getDec(bytes.NewReader(b))
	err := dec.Decode(v)
	putDec(dec)
	return err
}
<commit_msg>don't ignore the error from readType  or we will miss io.EOF.<commit_after>package binny

import (
	"bufio"
	"bytes"
	"encoding"
	"encoding/binary"
	"encoding/gob"
	"errors"
	"fmt"
	"io"
	"reflect"
	"unsafe"
)

var (
	// ErrNoPointer gets returned if the user passes a non-pointer to Decode
	ErrNoPointer = errors.New("can't decode to a non-pointer")
)

const DefaultDecoderBufferSize = 4096

// Unmarshaler is the interface implemented by objects that can unmarshal a binary representation of themselves.
// Implementing this bypasses reflection and is generally faster.
type Unmarshaler interface {
	UnmarshalBinny(dec *Decoder) error
}

// A Decoder reads binary data from an input stream, it also does a little bit of buffering.
type Decoder struct {
	r *bufio.Reader

	buf [16]byte
}

// NewDecoder is an alias for NewDecoder(r, DefaultDecoderBufferSize)
func NewDecoder(r io.Reader) *Decoder {
	return NewDecoderSize(r, DefaultDecoderBufferSize)
}

// NewDecoder returns a new decoder that reads from r with specific buffer size.
//
// The decoder introduces its own buffering and may
// read data from r beyond the requested values.
func NewDecoderSize(r io.Reader, sz int) *Decoder {
	if sz < 16 {
		sz = 16
	}

	return &Decoder{
		r: bufio.NewReaderSize(r, sz),
	}
}

// Reset discards any buffered data, resets all state, and switches
// the buffered reader to read from r.
func (dec *Decoder) Reset(r io.Reader) {
	dec.r.Reset(r)
}

func (dec *Decoder) readType() (Type, error) {
	b, err := dec.r.ReadByte()
	return Type(b), err
}

func (dec *Decoder) peekType() Type {
	b, _ := dec.r.ReadByte()
	dec.r.UnreadByte()
	return Type(b)
}

func (dec *Decoder) expectType(et Type) error {
	if t, err := dec.readType(); t != et {
		if err != nil {
			return err
		}
		return DecoderTypeError{et.String(), t}
	}
	return nil
}

// ReadBool returns a bool or an error.
func (dec *Decoder) ReadBool() (bool, error) {
	ft, _ := dec.readType()
	switch ft {
	case BoolTrue:
		return true, nil
	case BoolFalse:
		return false, nil
	}
	return false, DecoderTypeError{"Bool", ft}
}

func (dec *Decoder) ReadInt8() (int8, error) {
	if err := dec.expectType(Int8); err != nil {
		return 0, err
	}
	b, err := dec.r.ReadByte()
	return int8(b), err
}

func (dec *Decoder) ReadInt16() (int16, error) {
	if err := dec.expectType(Int16); err != nil {
		return 0, err
	}
	buf := dec.buf[:2]
	_, err := dec.Read(buf)
	return *(*int16)(unsafe.Pointer(&buf[0])), err
}

func (dec *Decoder) ReadInt32() (int32, error) {
	if err := dec.expectType(Int32); err != nil {
		return 0, err
	}
	buf := dec.buf[:4]
	_, err := dec.Read(buf)
	return *(*int32)(unsafe.Pointer(&buf[0])), err
}

func (dec *Decoder) ReadInt64() (int64, error) {
	if err := dec.expectType(Int64); err != nil {
		return 0, err
	}
	buf := dec.buf[:8]
	_, err := dec.Read(buf)
	return *(*int64)(unsafe.Pointer(&buf[0])), err
}

func (dec *Decoder) ReadVarInt() (int64, error) {
	if err := dec.expectType(VarInt); err != nil {
		return 0, err
	}
	return binary.ReadVarint(dec.r)
}

// ReadInt retruns an int/varint value and the size of it (8, 16, 32, 64) or an error.
func (dec *Decoder) ReadInt() (int64, uint8, error) {
	ft := dec.peekType()
	switch ft {
	case Int8:
		v, err := dec.ReadInt8()
		return int64(v), 8, err
	case Int16:
		v, err := dec.ReadInt16()
		return int64(v), 16, err
	case Int32:
		v, err := dec.ReadInt32()
		return int64(v), 32, err
	case Int64:
		v, err := dec.ReadInt64()
		return v, 64, err
	case VarInt:
		v, err := dec.ReadVarInt()
		return v, 64, err
	}
	return 0, 0, DecoderTypeError{"int", ft}
}

func (dec *Decoder) ReadUint8() (uint8, error) {
	if err := dec.expectType(Uint8); err != nil {
		return 0, err
	}
	return dec.r.ReadByte()
}

func (dec *Decoder) ReadUint16() (uint16, error) {
	if err := dec.expectType(Uint16); err != nil {
		return 0, err
	}
	buf := dec.buf[:2]
	_, err := dec.Read(buf)
	return *(*uint16)(unsafe.Pointer(&buf[0])), err
}

func (dec *Decoder) ReadUint32() (uint32, error) {
	if err := dec.expectType(Uint32); err != nil {
		return 0, err
	}
	buf := dec.buf[:4]
	_, err := dec.Read(buf)
	return *(*uint32)(unsafe.Pointer(&buf[0])), err
}

func (dec *Decoder) ReadUint64() (uint64, error) {
	if err := dec.expectType(Uint64); err != nil {
		return 0, err
	}
	buf := dec.buf[:8]
	_, err := dec.Read(buf)
	return *(*uint64)(unsafe.Pointer(&buf[0])), err
}

func (dec *Decoder) ReadVarUint() (uint64, error) {
	if err := dec.expectType(VarUint); err != nil {
		return 0, err
	}
	return binary.ReadUvarint(dec.r)
}

// ReadUint retruns an uint/varuint value and the size of it (8, 16, 32, 64) or an error.
func (dec *Decoder) ReadUint() (v uint64, sz uint8, err error) {
	ft := dec.peekType()
	switch ft {
	case Uint8:
		v, err := dec.ReadUint8()
		return uint64(v), 8, err
	case Uint16:
		v, err := dec.ReadUint16()
		return uint64(v), 16, err
	case Uint32:
		v, err := dec.ReadUint32()
		return uint64(v), 32, err
	case Uint64:
		v, err := dec.ReadUint64()
		return v, 64, err
	case VarUint:
		v, err := dec.ReadVarUint()
		return v, 64, err
	}
	return 0, 0, DecoderTypeError{"uint", ft}
}

// ReadFloat32 returns a float32 or an error.
func (dec *Decoder) ReadFloat32() (float32, error) {
	if err := dec.expectType(Float32); err != nil {
		return 0, err
	}
	buf := dec.buf[:4]
	_, err := dec.Read(buf)
	return *(*float32)(unsafe.Pointer(&buf[0])), err
}

// ReadFloat64 returns a float64 or an error.
func (dec *Decoder) ReadFloat64() (float64, error) {
	if err := dec.expectType(Float64); err != nil {
		return 0, err
	}
	buf := dec.buf[:8]
	_, err := dec.Read(buf)
	return *(*float64)(unsafe.Pointer(&buf[0])), err
}

// ReadComplex64 returns a complex64 or an error.
func (dec *Decoder) ReadComplex64() (complex64, error) {
	if err := dec.expectType(Complex64); err != nil {
		return 0, err
	}

	buf := dec.buf[:8]
	_, err := dec.Read(buf)
	return *(*complex64)(unsafe.Pointer(&buf[0])), err
}

// ReadComplex128 returns a complex128 or an error.
func (dec *Decoder) ReadComplex128() (complex128, error) {
	if err := dec.expectType(Complex128); err != nil {
		return 0, err
	}
	buf := dec.buf[:16]
	_, err := dec.Read(buf)
	return *(*complex128)(unsafe.Pointer(&buf[0])), err
}

func (dec *Decoder) readBytes(exp Type) ([]byte, error) {
	if err := dec.expectType(exp); err != nil {
		return nil, err
	}

	sz, _, err := dec.ReadUint()
	if err != nil || sz == 0 {
		return nil, err
	}

	buf := make([]byte, sz)
	_, err = io.ReadFull(dec.r, buf)
	return buf, err
}

// ReadBytes returns a byte slice.
func (dec *Decoder) ReadBytes() ([]byte, error) {
	return dec.readBytes(ByteSlice)
}

// ReadBytes returns a string.
func (dec *Decoder) ReadString() (string, error) {
	b, err := dec.readBytes(String)
	return string(b), err
}

// ReadBinary decodes and reads an object that implements the `encoding.BinaryUnmarshaler` interface.
func (dec *Decoder) ReadBinary(v encoding.BinaryUnmarshaler) error {
	b, err := dec.readBytes(Binary)
	if err != nil {
		return err
	}
	return v.UnmarshalBinary(b)
}

// ReadGob decodes and reads an object that implements the `gob.GobDecoder` interface.
func (dec *Decoder) ReadGob(v gob.GobDecoder) error {
	b, err := dec.readBytes(Gob)
	if err != nil {
		return err
	}
	return v.GobDecode(b)
}

// Decode reads the next binny-encoded value from its
// input and stores it in the value pointed to by v.
func (dec *Decoder) Decode(v interface{}) (err error) {
	switch v := v.(type) {
	case Unmarshaler:
		return v.UnmarshalBinny(dec)
	case encoding.BinaryUnmarshaler:
		return dec.ReadBinary(v)
	case gob.GobDecoder:
		return dec.ReadGob(v)
	case *string:
		*v, err = dec.ReadString()
		return
	case *[]byte:
		*v, err = dec.ReadBytes()
		return
	case *int64:
		*v, _, err = dec.ReadInt()
		return
	case *int32:
		var i int64
		i, _, err = dec.ReadInt()
		*v = int32(i)
		return
	case *int16:
		var i int64
		i, _, err = dec.ReadInt()
		*v = int16(i)
		return
	case *int8:
		var i int64
		i, _, err = dec.ReadInt()
		*v = int8(i)
		return
	case *int:
		var i int64
		i, _, err = dec.ReadInt()
		*v = int(i)
		return
	case *uint64:
		*v, _, err = dec.ReadUint()
		return
	case *uint32:
		var i uint64
		i, _, err = dec.ReadUint()
		*v = uint32(i)
		return
	case *uint16:
		var i uint64
		i, _, err = dec.ReadUint()
		*v = uint16(i)
		return
	case *uint8:
		var i uint64
		i, _, err = dec.ReadUint()
		*v = uint8(i)
		return
	case *uint:
		var i uint64
		i, _, err = dec.ReadUint()
		*v = uint(i)
		return
	case *uintptr:
		var i uint64
		i, _, err = dec.ReadUint()
		*v = uintptr(i)
		return
	case *float32:
		*v, err = dec.ReadFloat32()
		return
	case *float64:
		*v, err = dec.ReadFloat64()
		return
	case *complex64:
		*v, err = dec.ReadComplex64()
		return
	case *complex128:
		*v, err = dec.ReadComplex128()
		return
	case *bool:
		*v, err = dec.ReadBool()
		return
	case nil:
		return fmt.Errorf("can't decode a nil value")
	}
	return dec.decodeValue(reflect.ValueOf(v))
}

func (dec *Decoder) decodeValue(v reflect.Value) error {
	if v.Kind() != reflect.Ptr || !v.Elem().CanSet() {
		return ErrNoPointer
	}
	if v.IsNil() {
		return fmt.Errorf("can't decode a nil value: %v", v.Type())
	}
	fn := typeDecoder(v.Type())
	return fn(dec, v)
}

// Read allows the Decoder to be used as an io.Reader, note that internally this calls io.ReadFull().
func (dec *Decoder) Read(p []byte) (int, error) {
	return io.ReadFull(dec.r, p)
}

// Unmarshal is an alias for (sync.Pool'ed) NewDecoder(bytes.NewReader(b)).Decode(v)
func Unmarshal(b []byte, v interface{}) error {
	dec := getDec(bytes.NewReader(b))
	err := dec.Decode(v)
	putDec(dec)
	return err
}
<|endoftext|>


<commit_before>package toolbox

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

//Decoder represents a decoder.
type Decoder interface {
	//Decode  reads and decodes objects from an input stream.
	Decode(v interface{}) error
}

//UnMarshaler represent an struct that can be converted to bytes
type UnMarshaler interface {

	//Unmarshal converts a struct to bytes
	Unmarshal(data []byte) error
}

//DecoderFactory create an decoder for passed in  input stream
type DecoderFactory interface {
	//Create a decoder for passed in io reader
	Create(reader io.Reader) Decoder
}

type jsonDecoderFactory struct{ useNumber bool }

func (d jsonDecoderFactory) Create(reader io.Reader) Decoder {
	decoder := json.NewDecoder(reader)
	if d.useNumber {
		decoder.UseNumber()
	}
	return decoder
}

//NewJSONDecoderFactory create a new JSONDecoderFactory
func NewJSONDecoderFactory() DecoderFactory {
	return &jsonDecoderFactory{}
}

//NewJSONDecoderFactoryWithOption create a new JSONDecoderFactory, it takes useNumber decoder parameter
func NewJSONDecoderFactoryWithOption(useNumber bool) DecoderFactory {
	return &jsonDecoderFactory{useNumber: useNumber}
}

type unMarshalerDecoderFactory struct {
}

func (f *unMarshalerDecoderFactory) Create(reader io.Reader) Decoder {
	return &unMarshalerDecoder{
		reader: reader,
	}
}

type unMarshalerDecoder struct {
	reader   io.Reader
	provider func() UnMarshaler
}

func (d *unMarshalerDecoder) Decode(v interface{}) error {
	bytes, err := ioutil.ReadAll(d.reader)
	if err != nil {
		return fmt.Errorf("Failed to decode %v", err)
	}
	result, casted := v.(UnMarshaler)
	if !casted {
		return fmt.Errorf("Failed to decode - unable cast %T to %s", v, (*UnMarshaler)(nil))
	}
	return result.Unmarshal(bytes)
}

//NewUnMarshalerDecoderFactory returns a decoder factory
func NewUnMarshalerDecoderFactory() DecoderFactory {
	return &unMarshalerDecoderFactory{}
}

//DelimiteredRecord represents a delimitered record
type DelimiteredRecord struct {
	Columns   []string
	Delimiter string
	Record    map[string]interface{}
}

//IsEmpty returns true if all values are empty or null
func (r *DelimiteredRecord) IsEmpty() bool {
	var result = true
	for _, value := range r.Record {
		if value == nil {
			continue
		}
		if AsString(value) == "" {
			continue
		}
		return false
	}
	return result
}

type delimiterDecoder struct {
	reader io.Reader
}

func (d *delimiterDecoder) Decode(target interface{}) error {
	delimiteredRecord, ok := target.(*DelimiteredRecord)
	if !ok {
		return fmt.Errorf("Invalid target type, expected %T but had %T", &DelimiteredRecord{}, target)
	}
	if delimiteredRecord.Record == nil {
		delimiteredRecord.Record = make(map[string]interface{})
	}

	var isInDoubleQuote = false
	var index = 0
	var value = ""
	var delimiter = delimiteredRecord.Delimiter
	payload, err := ioutil.ReadAll(d.reader)
	if err != nil {
		return err
	}
	encoded := string(payload)
	hasColumns := len(delimiteredRecord.Columns) > 0
	if !hasColumns {
		delimiteredRecord.Columns = make([]string, 0)
	}
	for i := 0; i < len(encoded); i++ {
		aChar := string(encoded[i : i+1])
		//escape " only if value is already inside "s
		if isInDoubleQuote && ((aChar == "\\" || aChar == "\"") && i+2 <len(encoded) ) {
			nextChar := encoded[i+1 : i+2]
			if nextChar == "\"" {
				i++
				value = value + nextChar
				continue
			}
		}
		//allow unescaped " be inside text if the whole text is not enclosed in "s
		if aChar == "\"" && (len(value) == 0 || isInDoubleQuote) {
			isInDoubleQuote = !isInDoubleQuote
			continue
		}

		if encoded[i:i+1] == delimiter && !isInDoubleQuote {
			if !hasColumns {
				delimiteredRecord.Columns = append(delimiteredRecord.Columns, strings.TrimSpace(value))
			} else {
				var columnName = delimiteredRecord.Columns[index]
				delimiteredRecord.Record[columnName] = value
			}

			value = ""
			index++
			continue
		}
		value = value + aChar
	}
	if len(value) > 0 {
		if !hasColumns {
			delimiteredRecord.Columns = append(delimiteredRecord.Columns, strings.TrimSpace(value))
		} else {
			var columnName = delimiteredRecord.Columns[index]
			delimiteredRecord.Record[columnName] = value
		}
	}
	return nil
}

type delimiterDecoderFactory struct{}

func (f *delimiterDecoderFactory) Create(reader io.Reader) Decoder {
	return &delimiterDecoder{reader: reader}
}

//NewDelimiterDecoderFactory returns a new delimitered decoder factory.
func NewDelimiterDecoderFactory() DecoderFactory {
	return &delimiterDecoderFactory{}
}
<commit_msg>improved error handlong<commit_after>package toolbox

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

//Decoder represents a decoder.
type Decoder interface {
	//Decode  reads and decodes objects from an input stream.
	Decode(v interface{}) error
}

//UnMarshaler represent an struct that can be converted to bytes
type UnMarshaler interface {

	//Unmarshal converts a struct to bytes
	Unmarshal(data []byte) error
}

//DecoderFactory create an decoder for passed in  input stream
type DecoderFactory interface {
	//Create a decoder for passed in io reader
	Create(reader io.Reader) Decoder
}

type jsonDecoderFactory struct{ useNumber bool }

func (d jsonDecoderFactory) Create(reader io.Reader) Decoder {
	decoder := json.NewDecoder(reader)
	if d.useNumber {
		decoder.UseNumber()
	}
	return decoder
}

//NewJSONDecoderFactory create a new JSONDecoderFactory
func NewJSONDecoderFactory() DecoderFactory {
	return &jsonDecoderFactory{}
}

//NewJSONDecoderFactoryWithOption create a new JSONDecoderFactory, it takes useNumber decoder parameter
func NewJSONDecoderFactoryWithOption(useNumber bool) DecoderFactory {
	return &jsonDecoderFactory{useNumber: useNumber}
}

type unMarshalerDecoderFactory struct {
}

func (f *unMarshalerDecoderFactory) Create(reader io.Reader) Decoder {
	return &unMarshalerDecoder{
		reader: reader,
	}
}

type unMarshalerDecoder struct {
	reader   io.Reader
	provider func() UnMarshaler
}

func (d *unMarshalerDecoder) Decode(v interface{}) error {
	bytes, err := ioutil.ReadAll(d.reader)
	if err != nil {
		return fmt.Errorf("Failed to decode %v", err)
	}
	result, casted := v.(UnMarshaler)
	if !casted {
		return fmt.Errorf("Failed to decode - unable cast %T to %s", v, (*UnMarshaler)(nil))
	}
	return result.Unmarshal(bytes)
}

//NewUnMarshalerDecoderFactory returns a decoder factory
func NewUnMarshalerDecoderFactory() DecoderFactory {
	return &unMarshalerDecoderFactory{}
}

//DelimiteredRecord represents a delimitered record
type DelimiteredRecord struct {
	Columns   []string
	Delimiter string
	Record    map[string]interface{}
}

//IsEmpty returns true if all values are empty or null
func (r *DelimiteredRecord) IsEmpty() bool {
	var result = true
	for _, value := range r.Record {
		if value == nil {
			continue
		}
		if AsString(value) == "" {
			continue
		}
		return false
	}
	return result
}

type delimiterDecoder struct {
	reader io.Reader
}

func (d *delimiterDecoder) Decode(target interface{}) error {
	delimiteredRecord, ok := target.(*DelimiteredRecord)
	if !ok {
		return fmt.Errorf("Invalid target type, expected %T but had %T", &DelimiteredRecord{}, target)
	}
	if delimiteredRecord.Record == nil {
		delimiteredRecord.Record = make(map[string]interface{})
	}

	var isInDoubleQuote = false
	var index = 0
	var value = ""
	var delimiter = delimiteredRecord.Delimiter
	payload, err := ioutil.ReadAll(d.reader)
	if err != nil {
		return err
	}
	encoded := string(payload)
	hasColumns := len(delimiteredRecord.Columns) > 0
	if !hasColumns {
		delimiteredRecord.Columns = make([]string, 0)
	}
	for i := 0; i < len(encoded); i++ {
		aChar := string(encoded[i : i+1])
		//escape " only if value is already inside "s
		if isInDoubleQuote && ((aChar == "\\" || aChar == "\"") && i+2 <len(encoded) ) {
			nextChar := encoded[i+1 : i+2]
			if nextChar == "\"" {
				i++
				value = value + nextChar
				continue
			}
		}
		//allow unescaped " be inside text if the whole text is not enclosed in "s
		if aChar == "\"" && (len(value) == 0 || isInDoubleQuote) {
			isInDoubleQuote = !isInDoubleQuote
			continue
		}

		if encoded[i:i+1] == delimiter && !isInDoubleQuote {
			if !hasColumns {
				delimiteredRecord.Columns = append(delimiteredRecord.Columns, strings.TrimSpace(value))
			} else {
				var columnName = delimiteredRecord.Columns[index]
				delimiteredRecord.Record[columnName] = value
			}

			value = ""
			index++
			continue
		}
		value = value + aChar
	}
	if len(value) > 0 {
		if !hasColumns {
			delimiteredRecord.Columns = append(delimiteredRecord.Columns, strings.TrimSpace(value))
		} else {
			if index >= len(delimiteredRecord.Columns) {
				return fmt.Errorf("Index %v out of bound: columns: %v, values:%v", index, delimiteredRecord.Columns, encoded)
			}
			var columnName = delimiteredRecord.Columns[index]
			delimiteredRecord.Record[columnName] = value
		}
	}
	return nil
}

type delimiterDecoderFactory struct{}

func (f *delimiterDecoderFactory) Create(reader io.Reader) Decoder {
	return &delimiterDecoder{reader: reader}
}

//NewDelimiterDecoderFactory returns a new delimitered decoder factory.
func NewDelimiterDecoderFactory() DecoderFactory {
	return &delimiterDecoderFactory{}
}
<|endoftext|>


<commit_before>package pg

import (
	"encoding/hex"
	"reflect"
	"strconv"
	"time"
)

var (
	timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
)

func Decode(dst interface{}, f []byte) error {
	// NULL.
	if f == nil {
		return nil
	}

	if tm, ok := dst.(*time.Time); ok {
		tm_, err := decodeTime(f)
		if err != nil {
			return err
		}
		*tm = tm_
		return nil
	}

	if unmarshaler, ok := dst.(textUnmarshaler); ok {
		return unmarshaler.UnmarshalText(f)
	}

	switch v := dst.(type) {
	case *bool:
		if len(f) == 1 && f[0] == 't' {
			*v = true
		} else {
			*v = false
		}
		return nil
	case *int8:
		n, err := strconv.ParseInt(string(f), 10, 8)
		if err != nil {
			return err
		}
		*v = int8(n)
		return nil
	case *int16:
		n, err := strconv.ParseInt(string(f), 10, 16)
		if err != nil {
			return err
		}
		*v = int16(n)
		return nil
	case *int32:
		n, err := strconv.ParseInt(string(f), 10, 32)
		if err != nil {
			return err
		}
		*v = int32(n)
		return nil
	case *int64:
		n, err := strconv.ParseInt(string(f), 10, 64)
		if err != nil {
			return err
		}
		*v = n
		return nil
	case *int:
		n, err := strconv.ParseInt(string(f), 10, 64)
		if err != nil {
			return err
		}
		*v = int(n)
		return nil
	case *uint8:
		n, err := strconv.ParseUint(string(f), 10, 8)
		if err != nil {
			return err
		}
		*v = uint8(n)
		return nil
	case *uint16:
		n, err := strconv.ParseUint(string(f), 10, 16)
		if err != nil {
			return err
		}
		*v = uint16(n)
		return nil
	case *uint32:
		n, err := strconv.ParseUint(string(f), 10, 32)
		if err != nil {
			return err
		}
		*v = uint32(n)
		return nil
	case *uint64:
		n, err := strconv.ParseUint(string(f), 10, 64)
		if err != nil {
			return err
		}
		*v = n
		return nil
	case *uint:
		n, err := strconv.ParseInt(string(f), 10, 64)
		if err != nil {
			return err
		}
		*v = uint(n)
		return nil
	case *float32:
		n, err := strconv.ParseFloat(string(f), 32)
		if err != nil {
			return err
		}
		*v = float32(n)
		return nil
	case *float64:
		n, err := strconv.ParseFloat(string(f), 64)
		if err != nil {
			return err
		}
		*v = n
		return nil
	case *string:
		*v = string(f)
		return nil
	case *[]byte:
		b, err := decodeBytes(f)
		if err != nil {
			return err
		}
		*v = b
		return nil
	case *[]string:
		s, err := decodeStringSlice(f)
		if err != nil {
			return err
		}
		*v = s
		return nil
	case *[]int:
		s, err := decodeIntSlice(f)
		if err != nil {
			return err
		}
		*v = s
		return nil
	case *[]int64:
		s, err := decodeInt64Slice(f)
		if err != nil {
			return err
		}
		*v = s
		return nil
	case *map[string]string:
		m, err := decodeStringStringMap(f)
		if err != nil {
			return err
		}
		*v = m
		return nil
	}

	v := reflect.ValueOf(dst)
	if !v.IsValid() {
		return errorf("pg: Decode(%q)", v)
	}
	return DecodeValue(v.Elem(), f)
}

func DecodeValue(dst reflect.Value, f []byte) error {
	// NULL.
	if f == nil {
		return nil
	}

	kind := dst.Kind()
	if kind == reflect.Struct && dst.Type() == timeType {
		tm, err := decodeTime(f)
		if err != nil {
			return err
		}
		dst.Set(reflect.ValueOf(tm))
		return nil
	}

	if dst.CanAddr() {
		addr := dst.Addr()
		if addr.CanInterface() {
			if unmarshaler, ok := addr.Interface().(textUnmarshaler); ok {
				return unmarshaler.UnmarshalText(f)
			}
		}
	}

	switch dst.Kind() {
	case reflect.Ptr:
		if dst.IsNil() {
			dst.Set(reflect.New(dst.Type().Elem()))
		}
		return DecodeValue(dst.Elem(), f)
	case reflect.Bool:
		if len(f) == 1 && f[0] == 't' {
			dst.SetBool(true)
		} else {
			dst.SetBool(false)
		}
		return nil
	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
		n, err := strconv.ParseInt(string(f), 10, 64)
		if err != nil {
			return err
		}
		dst.SetInt(n)
		return nil
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
		n, err := strconv.ParseInt(string(f), 10, 64)
		if err != nil {
			return err
		}
		dst.SetUint(uint64(n))
		return nil
	case reflect.Float32, reflect.Float64:
		n, err := strconv.ParseFloat(string(f), 64)
		if err != nil {
			return err
		}
		dst.SetFloat(n)
		return nil
	case reflect.String:
		dst.SetString(string(f))
		return nil
	case reflect.Slice:
		return decodeSliceValue(dst, f)
	case reflect.Map:
		return decodeMapValue(dst, f)
	case reflect.Interface:
		return DecodeValue(dst.Elem(), f)
	}
	return errorf("pg: unsupported dst: %T", dst.Interface())
}

func decodeSliceValue(dst reflect.Value, f []byte) error {
	elemType := dst.Type().Elem()
	switch elemType.Kind() {
	case reflect.Uint8:
		b, err := decodeBytes(f)
		if err != nil {
			return err
		}
		dst.SetBytes(b)
		return nil
	case reflect.String:
		s, err := decodeStringSlice(f)
		if err != nil {
			return err
		}
		dst.Set(reflect.ValueOf(s))
		return nil
	case reflect.Int:
		s, err := decodeIntSlice(f)
		if err != nil {
			return err
		}
		dst.Set(reflect.ValueOf(s))
		return nil
	case reflect.Int64:
		s, err := decodeInt64Slice(f)
		if err != nil {
			return err
		}
		dst.Set(reflect.ValueOf(s))
		return nil
	}
	return errorf("pg: unsupported dst: %T", dst.Interface())
}

func decodeMapValue(dst reflect.Value, f []byte) error {
	typ := dst.Type()
	if typ.Key().Kind() == reflect.String && typ.Elem().Kind() == reflect.String {
		m, err := decodeStringStringMap(f)
		if err != nil {
			return err
		}
		dst.Set(reflect.ValueOf(m))
		return nil
	}
	return errorf("pg: unsupported dst: %T", dst.Interface())
}

func decodeBytes(f []byte) ([]byte, error) {
	f = f[2:] // Trim off "\\x".
	b := make([]byte, hex.DecodedLen(len(f)))
	_, err := hex.Decode(b, f)
	if err != nil {
		return nil, err
	}
	return b, nil
}

func decodeTime(f []byte) (time.Time, error) {
	switch l := len(f); {
	case l <= len(dateFormat):
		return time.Parse(dateFormat, string(f))
	case l <= len(timeFormat):
		return time.Parse(timeFormat, string(f))
	default:
		if c := f[len(f)-5]; c == '+' || c == '-' {
			return time.Parse(timestampWithTzFormat, string(f))
		}
		if c := f[len(f)-3]; c == '+' || c == '-' {
			return time.Parse(timestampWithTzFormat2, string(f))
		}
		return time.Parse(timestampFormat, string(f))
	}
}

func decodeIntSlice(f []byte) ([]int, error) {
	p := newArrayParser(f[1 : len(f)-1])
	s := make([]int, 0)
	for p.Valid() {
		elem, err := p.NextElem()
		if err != nil {
			return nil, err
		}
		if elem == nil {
			return nil, errorf("pg: unexpected NULL: %q", f)
		}
		n, err := strconv.Atoi(string(elem))
		if err != nil {
			return nil, err
		}
		s = append(s, n)
	}
	return s, nil
}

func decodeInt64Slice(f []byte) ([]int64, error) {
	p := newArrayParser(f[1 : len(f)-1])
	s := make([]int64, 0)
	for p.Valid() {
		elem, err := p.NextElem()
		if err != nil {
			return nil, err
		}
		if elem == nil {
			return nil, errorf("pg: unexpected NULL: %q", f)
		}
		n, err := strconv.ParseInt(string(elem), 10, 64)
		if err != nil {
			return nil, err
		}
		s = append(s, n)
	}
	return s, nil
}

func decodeStringSlice(f []byte) ([]string, error) {
	p := newArrayParser(f[1 : len(f)-1])
	s := make([]string, 0)
	for p.Valid() {
		elem, err := p.NextElem()
		if err != nil {
			return nil, err
		}
		if elem == nil {
			return nil, errorf("pg: unexpected NULL: %q", f)
		}
		s = append(s, string(elem))
	}
	return s, nil
}

func decodeStringStringMap(f []byte) (map[string]string, error) {
	p := newHstoreParser(f)
	m := make(map[string]string)
	for p.Valid() {
		key, err := p.NextKey()
		if err != nil {
			return nil, err
		}
		if key == nil {
			return nil, errorf("pg: unexpected NULL: %q", f)
		}
		value, err := p.NextValue()
		if err != nil {
			return nil, err
		}
		if value == nil {
			return nil, errorf("pg: unexpected NULL: %q", f)
		}
		m[string(key)] = string(value)
	}
	return m, nil
}
<commit_msg>Fix error message on nil values.<commit_after>package pg

import (
	"encoding/hex"
	"reflect"
	"strconv"
	"time"
)

var (
	timeType = reflect.TypeOf((*time.Time)(nil)).Elem()
)

func Decode(dst interface{}, f []byte) error {
	// NULL.
	if f == nil {
		return nil
	}

	if tm, ok := dst.(*time.Time); ok {
		tm_, err := decodeTime(f)
		if err != nil {
			return err
		}
		*tm = tm_
		return nil
	}

	if unmarshaler, ok := dst.(textUnmarshaler); ok {
		return unmarshaler.UnmarshalText(f)
	}

	switch v := dst.(type) {
	case *bool:
		if len(f) == 1 && f[0] == 't' {
			*v = true
		} else {
			*v = false
		}
		return nil
	case *int8:
		n, err := strconv.ParseInt(string(f), 10, 8)
		if err != nil {
			return err
		}
		*v = int8(n)
		return nil
	case *int16:
		n, err := strconv.ParseInt(string(f), 10, 16)
		if err != nil {
			return err
		}
		*v = int16(n)
		return nil
	case *int32:
		n, err := strconv.ParseInt(string(f), 10, 32)
		if err != nil {
			return err
		}
		*v = int32(n)
		return nil
	case *int64:
		n, err := strconv.ParseInt(string(f), 10, 64)
		if err != nil {
			return err
		}
		*v = n
		return nil
	case *int:
		n, err := strconv.ParseInt(string(f), 10, 64)
		if err != nil {
			return err
		}
		*v = int(n)
		return nil
	case *uint8:
		n, err := strconv.ParseUint(string(f), 10, 8)
		if err != nil {
			return err
		}
		*v = uint8(n)
		return nil
	case *uint16:
		n, err := strconv.ParseUint(string(f), 10, 16)
		if err != nil {
			return err
		}
		*v = uint16(n)
		return nil
	case *uint32:
		n, err := strconv.ParseUint(string(f), 10, 32)
		if err != nil {
			return err
		}
		*v = uint32(n)
		return nil
	case *uint64:
		n, err := strconv.ParseUint(string(f), 10, 64)
		if err != nil {
			return err
		}
		*v = n
		return nil
	case *uint:
		n, err := strconv.ParseInt(string(f), 10, 64)
		if err != nil {
			return err
		}
		*v = uint(n)
		return nil
	case *float32:
		n, err := strconv.ParseFloat(string(f), 32)
		if err != nil {
			return err
		}
		*v = float32(n)
		return nil
	case *float64:
		n, err := strconv.ParseFloat(string(f), 64)
		if err != nil {
			return err
		}
		*v = n
		return nil
	case *string:
		*v = string(f)
		return nil
	case *[]byte:
		b, err := decodeBytes(f)
		if err != nil {
			return err
		}
		*v = b
		return nil
	case *[]string:
		s, err := decodeStringSlice(f)
		if err != nil {
			return err
		}
		*v = s
		return nil
	case *[]int:
		s, err := decodeIntSlice(f)
		if err != nil {
			return err
		}
		*v = s
		return nil
	case *[]int64:
		s, err := decodeInt64Slice(f)
		if err != nil {
			return err
		}
		*v = s
		return nil
	case *map[string]string:
		m, err := decodeStringStringMap(f)
		if err != nil {
			return err
		}
		*v = m
		return nil
	}

	v := reflect.ValueOf(dst)
	if !v.IsValid() {
		return errorf("pg: Decode(%s)", v)
	}
	return DecodeValue(v.Elem(), f)
}

func DecodeValue(dst reflect.Value, f []byte) error {
	// NULL.
	if f == nil {
		return nil
	}

	kind := dst.Kind()
	if kind == reflect.Struct && dst.Type() == timeType {
		tm, err := decodeTime(f)
		if err != nil {
			return err
		}
		dst.Set(reflect.ValueOf(tm))
		return nil
	}

	if dst.CanAddr() {
		addr := dst.Addr()
		if addr.CanInterface() {
			if unmarshaler, ok := addr.Interface().(textUnmarshaler); ok {
				return unmarshaler.UnmarshalText(f)
			}
		}
	}

	switch dst.Kind() {
	case reflect.Ptr:
		if dst.IsNil() {
			dst.Set(reflect.New(dst.Type().Elem()))
		}
		return DecodeValue(dst.Elem(), f)
	case reflect.Bool:
		if len(f) == 1 && f[0] == 't' {
			dst.SetBool(true)
		} else {
			dst.SetBool(false)
		}
		return nil
	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
		n, err := strconv.ParseInt(string(f), 10, 64)
		if err != nil {
			return err
		}
		dst.SetInt(n)
		return nil
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
		n, err := strconv.ParseInt(string(f), 10, 64)
		if err != nil {
			return err
		}
		dst.SetUint(uint64(n))
		return nil
	case reflect.Float32, reflect.Float64:
		n, err := strconv.ParseFloat(string(f), 64)
		if err != nil {
			return err
		}
		dst.SetFloat(n)
		return nil
	case reflect.String:
		dst.SetString(string(f))
		return nil
	case reflect.Slice:
		return decodeSliceValue(dst, f)
	case reflect.Map:
		return decodeMapValue(dst, f)
	case reflect.Interface:
		return DecodeValue(dst.Elem(), f)
	}
	return errorf("pg: unsupported dst: %s", dst)
}

func decodeSliceValue(dst reflect.Value, f []byte) error {
	elemType := dst.Type().Elem()
	switch elemType.Kind() {
	case reflect.Uint8:
		b, err := decodeBytes(f)
		if err != nil {
			return err
		}
		dst.SetBytes(b)
		return nil
	case reflect.String:
		s, err := decodeStringSlice(f)
		if err != nil {
			return err
		}
		dst.Set(reflect.ValueOf(s))
		return nil
	case reflect.Int:
		s, err := decodeIntSlice(f)
		if err != nil {
			return err
		}
		dst.Set(reflect.ValueOf(s))
		return nil
	case reflect.Int64:
		s, err := decodeInt64Slice(f)
		if err != nil {
			return err
		}
		dst.Set(reflect.ValueOf(s))
		return nil
	}
	return errorf("pg: unsupported dst: %s", dst)
}

func decodeMapValue(dst reflect.Value, f []byte) error {
	typ := dst.Type()
	if typ.Key().Kind() == reflect.String && typ.Elem().Kind() == reflect.String {
		m, err := decodeStringStringMap(f)
		if err != nil {
			return err
		}
		dst.Set(reflect.ValueOf(m))
		return nil
	}
	return errorf("pg: unsupported dst: %s", dst)
}

func decodeBytes(f []byte) ([]byte, error) {
	f = f[2:] // Trim off "\\x".
	b := make([]byte, hex.DecodedLen(len(f)))
	_, err := hex.Decode(b, f)
	if err != nil {
		return nil, err
	}
	return b, nil
}

func decodeTime(f []byte) (time.Time, error) {
	switch l := len(f); {
	case l <= len(dateFormat):
		return time.Parse(dateFormat, string(f))
	case l <= len(timeFormat):
		return time.Parse(timeFormat, string(f))
	default:
		if c := f[len(f)-5]; c == '+' || c == '-' {
			return time.Parse(timestampWithTzFormat, string(f))
		}
		if c := f[len(f)-3]; c == '+' || c == '-' {
			return time.Parse(timestampWithTzFormat2, string(f))
		}
		return time.Parse(timestampFormat, string(f))
	}
}

func decodeIntSlice(f []byte) ([]int, error) {
	p := newArrayParser(f[1 : len(f)-1])
	s := make([]int, 0)
	for p.Valid() {
		elem, err := p.NextElem()
		if err != nil {
			return nil, err
		}
		if elem == nil {
			return nil, errorf("pg: unexpected NULL: %q", f)
		}
		n, err := strconv.Atoi(string(elem))
		if err != nil {
			return nil, err
		}
		s = append(s, n)
	}
	return s, nil
}

func decodeInt64Slice(f []byte) ([]int64, error) {
	p := newArrayParser(f[1 : len(f)-1])
	s := make([]int64, 0)
	for p.Valid() {
		elem, err := p.NextElem()
		if err != nil {
			return nil, err
		}
		if elem == nil {
			return nil, errorf("pg: unexpected NULL: %q", f)
		}
		n, err := strconv.ParseInt(string(elem), 10, 64)
		if err != nil {
			return nil, err
		}
		s = append(s, n)
	}
	return s, nil
}

func decodeStringSlice(f []byte) ([]string, error) {
	p := newArrayParser(f[1 : len(f)-1])
	s := make([]string, 0)
	for p.Valid() {
		elem, err := p.NextElem()
		if err != nil {
			return nil, err
		}
		if elem == nil {
			return nil, errorf("pg: unexpected NULL: %q", f)
		}
		s = append(s, string(elem))
	}
	return s, nil
}

func decodeStringStringMap(f []byte) (map[string]string, error) {
	p := newHstoreParser(f)
	m := make(map[string]string)
	for p.Valid() {
		key, err := p.NextKey()
		if err != nil {
			return nil, err
		}
		if key == nil {
			return nil, errorf("pg: unexpected NULL: %q", f)
		}
		value, err := p.NextValue()
		if err != nil {
			return nil, err
		}
		if value == nil {
			return nil, errorf("pg: unexpected NULL: %q", f)
		}
		m[string(key)] = string(value)
	}
	return m, nil
}
<|endoftext|>