<commit_before>package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"math"
	"os"
	"time"
	"unsafe"
	//"github.com/edsrzf/mmap-go"
	"github.com/yobert/alsa/pcm"
)

// _, _, errnop := syscall.Syscall(syscall.SYS_IOCTL, uintptr(file.Fd()), uintptr(TUNSETIFF), uintptr(unsafe.Pointer(&ifr)))
//errno := int(errno)

//func ioctl(fd int, request, argp uintptr) error {
//	_, _, errorp := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), request, argp)
//	return os.NewSyscallError("ioctl", int(errorp))
//}

func main() {
	if err := list_the_things(); err != nil {
		fmt.Println(err)
	}

	if err := boop("/dev/snd/pcmC0D0p"); err != nil {
		//if err := boop("/dev/snd/pcmC2D0p"); err != nil {
		fmt.Println(err)
	}

}

func boop(path string) error {
	fh, err := os.OpenFile(path, os.O_RDWR, 0755)
	if err != nil {
		return err
	}
	defer fh.Close()

	var pv PVersion
	err = ioctl(fh.Fd(), ioctl_encode(CmdRead, 4, CmdPCMVersion), &pv)
	if err != nil {
		return err
	}

	ttstamp := uint32(PCMTimestampTypeGettimeofday)
	err = ioctl(fh.Fd(), ioctl_encode(CmdWrite, 4, CmdPCMTimestampType), &ttstamp)
	if err != nil {
		return err
	}

	params := &Params{}
	last := &Params{}

	for i := range params.Masks {
		for ii := 0; ii < 2; ii++ {
			params.Masks[i].Bits[ii] = 0xffffffff
		}
	}
	for i := range params.Intervals {
		params.Intervals[i].Max = 0xffffffff
	}
	params.Rmask = 0xffffffff

	if err := refine(fh.Fd(), params, last); err != nil {
		return err
	}

	if !params.IntervalInRange(ParamChannels, 2) {
		return fmt.Errorf("Stereo not available")
	}

	params.Cmask = 0
	params.Rmask = 0xffffffff
	params.SetInterval(ParamChannels, 2, 2, Integer)

	if err := refine(fh.Fd(), params, last); err != nil {
		return err
	}

	rate := uint32(44100)

	if !params.IntervalInRange(ParamRate, rate) {
		return fmt.Errorf("%d Khz not available", rate)
	}

	params.Cmask = 0
	params.Rmask = 0xffffffff
	params.SetInterval(ParamRate, rate, rate, Integer)

	if err := refine(fh.Fd(), params, last); err != nil {
		return err
	}

	params.Cmask = 0
	params.Rmask = 0xffffffff
	params.SetAccess(RWInterleaved)
	params.SetFormat(U24_BE)
	//params.SetFormat(U8)

	if err := refine(fh.Fd(), params, last); err != nil {
		return err
	}

	//	params.Cmask = 0
	//	params.Rmask = 0xffffffff
	//	params.SetIntervalToMin(ParamBufferTime)
	//	if err := refine(fh.Fd(), params, last); err != nil {
	//		return err
	//	}

	if err := hw_params(fh.Fd(), params, last); err != nil {
		return err
	}

	swparams := &SwParams{}
	swlast := &SwParams{}

	swparams.PeriodStep = 1
	swparams.AvailMin = 1024
	swparams.XferAlign = 1
	swparams.StartThreshold = 1
	swparams.StopThreshold = 16384
	swparams.Proto = pv
	swparams.TstampType = 1

	if err := sw_params(fh.Fd(), swparams, swlast); err != nil {
		return err
	}

	if err := get_status(fh.Fd()); err != nil {
		return err
	}
	if err := ioctl(fh.Fd(), ioctl_encode(0, 0, CmdPCMPrepare), nil); err != nil {
		return err
	}
	if err := get_status(fh.Fd()); err != nil {
		return err
	}

	/*	if err := ioctl(fh.Fd(), ioctl_encode(0, 0, CmdPCMStart), nil); err != nil {
			return err
		}
		if err := get_status(fh.Fd()); err != nil {
			return err
		}*/

	buf_size := int(params.Intervals[ParamBufferSize-ParamFirstInterval].Max)

	buf_bytes := int(params.Intervals[ParamBufferBytes-ParamFirstInterval].Max)
	buf := bytes.NewBuffer(make([]byte, 0, buf_bytes))

	fmt.Println("buf", buf_bytes, "/", buf_size, "frames")
	fmt.Println("rate", rate)

	t := 0.0

	xfer := pcm.XferI{}

	for i := 0; i < buf_size; i++ {

		v := math.Sin(t * 2 * math.Pi * 440)
		//v += math.Sin(t * 2 * math.Pi * 261.63)
		//v += math.Sin(t * 2 * math.Pi * 349.23)
		v *= 0.1

		//buf[i] = uint8((v*0.5+0.5)*255)
		sample := uint32((v*0.5 + 0.5) * 16777215)

		binary.Write(buf, binary.BigEndian, sample)
		binary.Write(buf, binary.BigEndian, sample)

		t += 1.0 / float64(rate)

		xfer.Frames++
	}

	xfer.Buf = uintptr(unsafe.Pointer(&buf.Bytes()[0]))

	if err := get_status(fh.Fd()); err != nil {
		return err
	}
	err = ioctl(fh.Fd(), ioctl_encode(CmdWrite, pcm.XferISize, CmdPCMWriteIFrames), &xfer)
	if err != nil {
		return err
	}
	fmt.Println("xfer complete")
	for i := 0; i < 10; i++ {
		if err := get_status(fh.Fd()); err != nil {
			return err
		}
		time.Sleep(time.Millisecond * 100)
	}

	return nil
}

func list_the_things() error {
	for i := 0; i < 10; i++ {
		path := fmt.Sprintf("/dev/snd/controlC%d", i)
		_, err := os.Stat(path)
		if err != nil {
			continue
		}
		fh, err := os.Open(path)
		if err != nil {
			return err
		}
		defer fh.Close()

		var pv PVersion
		err = ioctl(fh.Fd(), ioctl_encode(CmdRead, 4, CmdControlVersion), &pv)
		if err != nil {
			return err
		}

		var ci CardInfo
		err = ioctl(fh.Fd(), ioctl_encode(CmdRead, 376, CmdControlCardInfo), &ci)
		if err != nil {
			return err
		}

		fmt.Println(ci, pv)

		var next int32 = -1

		for {
			err = ioctl(fh.Fd(), ioctl_encode(CmdRead, 4, CmdControlPCMNextDevice), &next)
			if err != nil {
				return err
			}

			if next == -1 {
				break
			}

			for stream := int32(0); stream < 2; stream++ {
				var pi PCMInfo
				pi.Device = uint32(next)
				pi.Subdevice = 0
				pi.Stream = stream
				err = ioctl(fh.Fd(), ioctl_encode(CmdRead|CmdWrite, 288, CmdControlPCMInfo), &pi)
				if err != nil {
					//return err
					//fmt.Println(err)
				} else {
					fmt.Println(pi)
				}
			}
		}

		fmt.Println("")
	}
	return nil
}
<commit_msg>WIP closer!<commit_after>package main

import (
	"bytes"
	"encoding/binary"
	"fmt"
	"math"
	"os"
	"time"
	"unsafe"
	//"github.com/edsrzf/mmap-go"
	"github.com/yobert/alsa/misc"
	"github.com/yobert/alsa/pcm"
)

// _, _, errnop := syscall.Syscall(syscall.SYS_IOCTL, uintptr(file.Fd()), uintptr(TUNSETIFF), uintptr(unsafe.Pointer(&ifr)))
//errno := int(errno)

//func ioctl(fd int, request, argp uintptr) error {
//	_, _, errorp := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), request, argp)
//	return os.NewSyscallError("ioctl", int(errorp))
//}

func main() {
	if err := list_the_things(); err != nil {
		fmt.Println(err)
	}

	if err := boop("/dev/snd/pcmC0D0p"); err != nil {
		//if err := boop("/dev/snd/pcmC2D0p"); err != nil {
		fmt.Println(err)
	}

}

func boop(path string) error {
	fh, err := os.OpenFile(path, os.O_RDWR, 0755)
	if err != nil {
		return err
	}
	defer fh.Close()

	var pv PVersion
	err = ioctl(fh.Fd(), ioctl_encode(CmdRead, 4, CmdPCMVersion), &pv)
	if err != nil {
		return err
	}

	ttstamp := uint32(PCMTimestampTypeGettimeofday)
	err = ioctl(fh.Fd(), ioctl_encode(CmdWrite, 4, CmdPCMTimestampType), &ttstamp)
	if err != nil {
		return err
	}

	params := &Params{}
	last := &Params{}

	for i := range params.Masks {
		for ii := 0; ii < 2; ii++ {
			params.Masks[i].Bits[ii] = 0xffffffff
		}
	}
	for i := range params.Intervals {
		params.Intervals[i].Max = 0xffffffff
	}
	params.Rmask = 0xffffffff

	if err := refine(fh.Fd(), params, last); err != nil {
		return err
	}

	if !params.IntervalInRange(ParamChannels, 2) {
		return fmt.Errorf("Stereo not available")
	}

	params.Cmask = 0
	params.Rmask = 0xffffffff
	params.SetInterval(ParamChannels, 2, 2, Integer)

	if err := refine(fh.Fd(), params, last); err != nil {
		return err
	}

	rate := uint32(44100)

	if !params.IntervalInRange(ParamRate, rate) {
		return fmt.Errorf("%d hz not available", rate)
	}

	params.Cmask = 0
	params.Rmask = 0xffffffff
	params.SetInterval(ParamRate, rate, rate, Integer)

	if err := refine(fh.Fd(), params, last); err != nil {
		return err
	}

	// buffer time?
	max_buf_time := uint32(params.Intervals[ParamBufferTime-ParamFirstInterval].Max)
	min_buf_time := uint32(1000 * 1000)
	if min_buf_time > max_buf_time {
		min_buf_time = max_buf_time / 2
	}
	params.Cmask = 0
	params.Rmask = 0xffffffff
	params.SetInterval(ParamBufferTime, min_buf_time, max_buf_time, OpenMin|OpenMax)

	if err := refine(fh.Fd(), params, last); err != nil {
		return err
	}

	params.Cmask = 0
	params.Rmask = 0xffffffff
	params.SetAccess(RWInterleaved)
	//params.SetFormat(U24_BE)
	params.SetFormat(U8)

	if err := refine(fh.Fd(), params, last); err != nil {
		return err
	}

	//	params.Cmask = 0
	//	params.Rmask = 0xffffffff
	//	params.SetIntervalToMin(ParamBufferTime)
	//	if err := refine(fh.Fd(), params, last); err != nil {
	//		return err
	//	}

	if err := hw_params(fh.Fd(), params, last); err != nil {
		return err
	}

	swparams := &SwParams{}
	swlast := &SwParams{}

	swparams.PeriodStep = 1
	swparams.AvailMin = 1024
	swparams.XferAlign = 1
	//swparams.StartThreshold = 1024
	swparams.StartThreshold = 100
	swparams.StopThreshold = 16384
	swparams.Proto = pv
	swparams.TstampType = 1

	if err := sw_params(fh.Fd(), swparams, swlast); err != nil {
		return err
	}

	if err := get_status(fh.Fd()); err != nil {
		return err
	}
	if err := ioctl(fh.Fd(), ioctl_encode(0, 0, CmdPCMPrepare), nil); err != nil {
		return err
	}
	if err := get_status(fh.Fd()); err != nil {
		return err
	}

	/*	if err := ioctl(fh.Fd(), ioctl_encode(0, 0, CmdPCMStart), nil); err != nil {
			return err
		}
		if err := get_status(fh.Fd()); err != nil {
			return err
		}*/

	buf_size := int(params.Intervals[ParamBufferSize-ParamFirstInterval].Max)

	buf_bytes := int(params.Intervals[ParamBufferBytes-ParamFirstInterval].Max)

	fmt.Println("buf", buf_bytes, "/", buf_size, "frames")
	fmt.Println("rate", rate)

	/*	go func() {
		for {
			if err := get_status(fh.Fd()); err != nil {
				fmt.Println(err)
				return
			}
			time.Sleep(time.Second)
		}
	}()*/

	t := 0.0

	for {

		amt := int(buf_size)
		buf := bytes.NewBuffer(nil)

		for i := 0; i < amt; i++ {

			v := math.Sin(t * 2 * math.Pi * 440)
			//v += math.Sin(t * 2 * math.Pi * 261.63)
			//v += math.Sin(t * 2 * math.Pi * 349.23)
			v *= 0.1

			sample := uint8((v*0.5 + 0.5) * 255)

			// U24_BE is lower 3 bytes of a 4 byte word
			// 16777215 is max value of a 24 bit uint
			//sample := uint32((v*0.5 + 0.5) * 16777215)

			binary.Write(buf, binary.BigEndian, sample)
			binary.Write(buf, binary.BigEndian, sample)
			//binary.Write(buf, binary.BigEndian, sample)
			//binary.Write(buf, binary.BigEndian, sample)
			//binary.Write(buf, binary.BigEndian, sample)

			t += (1.0 / float64(rate))

		}

		err = ioctl(fh.Fd(), ioctl_encode(CmdWrite, pcm.XferISize, CmdPCMWriteIFrames), &pcm.XferI{
			Buf:    uintptr(unsafe.Pointer(&buf.Bytes()[0])),
			Frames: misc.Uframes(amt),
		})
		if err != nil {
			return err
		}
		fmt.Println("xfer")
		//fmt.Println("xfer", xfer.Frames, xfer.Result)
		//time.Sleep(time.Millisecond * 10)
		_ = time.Sleep
	}

	return nil
}

func list_the_things() error {
	for i := 0; i < 10; i++ {
		path := fmt.Sprintf("/dev/snd/controlC%d", i)
		_, err := os.Stat(path)
		if err != nil {
			continue
		}
		fh, err := os.Open(path)
		if err != nil {
			return err
		}
		defer fh.Close()

		var pv PVersion
		err = ioctl(fh.Fd(), ioctl_encode(CmdRead, 4, CmdControlVersion), &pv)
		if err != nil {
			return err
		}

		var ci CardInfo
		err = ioctl(fh.Fd(), ioctl_encode(CmdRead, 376, CmdControlCardInfo), &ci)
		if err != nil {
			return err
		}

		fmt.Println(ci, pv)

		var next int32 = -1

		for {
			err = ioctl(fh.Fd(), ioctl_encode(CmdRead, 4, CmdControlPCMNextDevice), &next)
			if err != nil {
				return err
			}

			if next == -1 {
				break
			}

			for stream := int32(0); stream < 2; stream++ {
				var pi PCMInfo
				pi.Device = uint32(next)
				pi.Subdevice = 0
				pi.Stream = stream
				err = ioctl(fh.Fd(), ioctl_encode(CmdRead|CmdWrite, 288, CmdControlPCMInfo), &pi)
				if err != nil {
					//return err
					//fmt.Println(err)
				} else {
					fmt.Println(pi)
				}
			}
		}

		fmt.Println("")
	}
	return nil
}
<|endoftext|>


<commit_before>package xmpp

import (
	"encoding/xml"
)

// TimeReply is XEP-0202 reply stanza
type TimeReply struct {
	XMLName xml.Name `xml:"urn:xmpp:time time"`
	TZO     string   `xml:"tzo"`
	UTC     string   `xml:"utc"`
}

// TimeReplyOld is XEP-0090 stanza
type TimeReplyOld struct {
	XMLName xml.Name `xml:"jabber:iq:time query"`
	UTC     string   `xml:"utc"`
	TZ      string   `xml:"tz"`
	Display string   `xml:"display"`
}
<commit_msg>String() and Format() methods for TimeReply stanza<commit_after>package xmpp

import (
	"encoding/xml"
	"time"
)

const (
	TimeTZ  = "2006-01-02T15:04:05Z"
	TimeOld = "20060102T15:04:05"
)

// TimeReply is XEP-0202 reply stanza
type TimeReply struct {
	XMLName xml.Name `xml:"urn:xmpp:time time"`
	TZO     string   `xml:"tzo"`
	UTC     string   `xml:"utc"`
}

// TimeReplyOld is XEP-0090 stanza
type TimeReplyOld struct {
	XMLName xml.Name `xml:"jabber:iq:time query"`
	UTC     string   `xml:"utc"`
	TZ      string   `xml:"tz"`
	Display string   `xml:"display"`
}

// TimeRequest is XEP-0202: Time Entity query
type TimeQuery struct {
	XMLName xml.Name `xml:"urn:xmpp:time time"`
}

// String is pretty printer.
func (r *TimeReply) String() string {
	return r.Format(time.RubyDate)
}

// Format formating TimeReply with specified layout.
// see: `godoc time` for Format examples.
func (r *TimeReply) Format(layout string) string {
	t, err := time.Parse(TimeTZ, r.UTC)
	if err != nil {
		return err.Error()
	}
	tl, err := time.Parse("-07:00", r.TZO)
	if err != nil {
		return err.Error()
	}
	return t.In(tl.Location()).Format(layout)
}
<|endoftext|>


<commit_before>package main

import (
	"strconv"
	"time"
)

func ParseTimestamp(ts string) int64 {
	tsInt, err := strconv.ParseInt(ts, 10, 64)
	if err == nil {
		switch {
		case tsInt > 1e18: // nanosecond timestamps
			return time.Unix(tsInt/1e9, tsInt%1e9).UnixNano()
		case tsInt > 1e15: // microseconds timestamps
			return time.Unix(tsInt/1e6, (tsInt*1e3)%1e9).UnixNano()
		case tsInt > 1e12: // millisecond timestamps
			return time.Unix(tsInt/1e3, (tsInt*1e6)%1e9).UnixNano()
		case tsInt > 1e9: // second timestamps
			return time.Unix(tsInt, 0).UnixNano()
		}
	}
	return time.Now().UnixNano()
}
<commit_msg>Use current time if wrong timestamp provided<commit_after>package main

import (
	"strconv"
	"time"
)

func ParseTimestamp(ts string) int64 {
	if tsInt, err := strconv.ParseInt(ts, 10, 64); err == nil {
		switch {
		case tsInt > 1e18: // nanosecond timestamps
			return time.Unix(tsInt/1e9, tsInt%1e9).UnixNano()
		case tsInt > 1e15: // microseconds timestamps
			return time.Unix(tsInt/1e6, (tsInt*1e3)%1e9).UnixNano()
		case tsInt > 1e12: // millisecond timestamps
			return time.Unix(tsInt/1e3, (tsInt*1e6)%1e9).UnixNano()
		case tsInt > 1e9: // second timestamps
			return time.Unix(tsInt, 0).UnixNano()
		}
	} else {
		Logger.Warningf("Invalid timestamp, using current time instead.")
		return time.Now().UnixNano()
	}
	panic("Unreachable")
}
<|endoftext|>


<commit_before>package main

import (
	"code.google.com/p/go.tools/go/exact"
	"code.google.com/p/go.tools/go/types"
	"flag"
	"fmt"
	"github.com/neelance/gopherjs/translator"
	"go/ast"
	"go/build"
	"go/parser"
	"go/scanner"
	"go/token"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"strings"
	"syscall"
	"time"
)

type Package struct {
	*build.Package
	SrcModTime     time.Time
	JavaScriptCode []byte
}

var BuildContext = &build.Context{
	GOROOT:        build.Default.GOROOT,
	GOPATH:        build.Default.GOPATH,
	GOOS:          build.Default.GOOS,
	GOARCH:        build.Default.GOARCH,
	Compiler:      "gc",
	InstallSuffix: "js",
}
var TypesConfig = &types.Config{
	Packages: make(map[string]*types.Package),
}
var FileSet = token.NewFileSet()
var Packages = make(map[string]*Package)
var InstallMode = false

func main() {
	flag.Parse()

	cmd := flag.Arg(0)
	switch cmd {
	case "build":
		buildFlags := flag.NewFlagSet("build", flag.ContinueOnError)
		var pkgObj string
		buildFlags.StringVar(&pkgObj, "o", "", "")
		buildFlags.Parse(flag.Args()[1:])

		if pkgObj == "" {
			basename := path.Base(buildFlags.Arg(0))
			pkgObj = basename[:len(basename)-3] + ".js"
		}
		err := Build(buildFlags.Args(), pkgObj)
		HandleError(err)
		os.Exit(0)

	case "install":
		for _, pkgPath := range flag.Args()[1:] {
			err := Install(pkgPath)
			HandleError(err)
		}
		os.Exit(0)

	case "run":
		lastSourceArg := 1
		for {
			if !strings.HasSuffix(flag.Arg(lastSourceArg), ".go") {
				break
			}
			lastSourceArg += 1
		}
		if lastSourceArg == 1 {
			fmt.Fprintln(os.Stderr, "gopherjs run: no go files listed")
			os.Exit(1)
		}

		tempfile, err := ioutil.TempFile("", path.Base(flag.Arg(1))+".")
		HandleError(err)
		defer func() {
			tempfile.Close()
			os.Remove(tempfile.Name())
		}()

		err = Build(flag.Args()[1:lastSourceArg], tempfile.Name())
		HandleError(err)

		node := exec.Command("node", append([]string{tempfile.Name()}, flag.Args()[lastSourceArg:]...)...)
		node.Stdin = os.Stdin
		node.Stdout = os.Stdout
		node.Stderr = os.Stderr
		if err = node.Run(); err != nil {
			if e, isExitError := err.(*exec.ExitError); isExitError {
				os.Exit(e.Sys().(syscall.WaitStatus).ExitStatus())
			}
			HandleError(err)
		}
		os.Exit(0)

	case "tool":
		tool := flag.Arg(1)
		toolFlags := flag.NewFlagSet("tool", flag.ContinueOnError)
		toolFlags.Bool("e", false, "")
		toolFlags.Bool("l", false, "")
		toolFlags.Bool("m", false, "")
		toolFlags.String("o", "", "")
		toolFlags.String("D", "", "")
		toolFlags.String("I", "", "")
		toolFlags.Parse(flag.Args()[2:])

		if len(tool) == 2 {
			switch tool[1] {
			case 'g':
				basename := path.Base(toolFlags.Arg(0))
				err := Build([]string{toolFlags.Arg(0)}, basename[:len(basename)-3]+".js")
				HandleError(err)
				os.Exit(0)
			}
		}
		fmt.Fprintln(os.Stderr, "Tool not supported: "+tool)
		os.Exit(1)

	case "help", "":
		os.Stderr.WriteString(`GopherJS is a tool for compiling Go source code to JavaScript.

Usage:

    gopherjs command [arguments]

The commands are:

    build       compile packages and dependencies
    install     compile and install packages and dependencies
    run         compile and run Go program

`)
		os.Exit(0)

	default:
		fmt.Fprintf(os.Stderr, "gopherjs: unknown subcommand \"%s\"\nRun 'gopherjs help' for usage.\n", cmd)
		os.Exit(1)
	}
}

func HandleError(err error) {
	if err == nil {
		return
	}
	if list, isList := err.(translator.ErrorList); isList {
		for _, entry := range list {
			fmt.Fprintln(os.Stderr, entry)
		}
		os.Exit(1)
	}
	fmt.Fprintln(os.Stderr, err.Error())
	os.Exit(1)
}

func Build(filenames []string, pkgObj string) error {
	wd, err := os.Getwd()
	if err != nil {
		return err
	}
	pkg := &Package{
		Package: &build.Package{
			Name:       "main",
			ImportPath: "main",
			Dir:        wd,
			GoFiles:    filenames,
			PkgObj:     pkgObj,
		},
	}
	return BuildPackage(pkg)
}

func Install(pkgPath string) error {
	buildPkg, err := BuildContext.Import(pkgPath, "", 0)
	if err != nil {
		return err
	}
	pkg := &Package{Package: buildPkg}
	if pkg.IsCommand() {
		pkg.PkgObj = pkg.BinDir + "/" + path.Base(pkg.ImportPath) + ".js"
	}
	InstallMode = true
	return BuildPackage(pkg)
}

func BuildPackage(pkg *Package) error {
	if pkg.ImportPath == "unsafe" {
		TypesConfig.Packages["unsafe"] = types.Unsafe
		return nil
	}

	TypesConfig.Import = func(imports map[string]*types.Package, path string) (*types.Package, error) {
		if _, found := Packages[path]; found {
			return imports[path], nil
		}

		otherPkg, err := BuildContext.Import(path, pkg.Dir, build.AllowBinary)
		if err != nil {
			return nil, err
		}
		pkg := &Package{Package: otherPkg}
		Packages[path] = pkg
		if err := BuildPackage(pkg); err != nil {
			return nil, err
		}

		return imports[path], nil
	}

	if InstallMode {
		if fileInfo, err := os.Stat(os.Args[0]); err == nil { // gopherjs itself
			pkg.SrcModTime = fileInfo.ModTime()
		}

		for _, importedPkgPath := range pkg.Imports {
			_, err := TypesConfig.Import(TypesConfig.Packages, importedPkgPath)
			if err != nil {
				return err
			}
			impModeTime := Packages[importedPkgPath].SrcModTime
			if impModeTime.After(pkg.SrcModTime) {
				pkg.SrcModTime = impModeTime
			}
		}

		for _, name := range pkg.GoFiles {
			fileInfo, err := os.Stat(pkg.Dir + "/" + name)
			if err != nil {
				return err
			}
			if fileInfo.ModTime().After(pkg.SrcModTime) {
				pkg.SrcModTime = fileInfo.ModTime()
			}
		}

		pkgObjFileInfo, err := os.Stat(pkg.PkgObj)
		if err == nil && !pkg.SrcModTime.After(pkgObjFileInfo.ModTime()) {
			// package object is up to date, load from disk if library
			if pkg.IsCommand() {
				return nil
			}

			objFile, err := os.Open(pkg.PkgObj)
			if err != nil {
				return err
			}
			defer objFile.Close()

			pkg.JavaScriptCode, _, err = translator.ReadArchive(TypesConfig.Packages, pkg.PkgObj, pkg.ImportPath, objFile)
			if err != nil {
				return err
			}

			return nil
		}
	}

	files := make([]*ast.File, 0)
	var errList translator.ErrorList
	for _, name := range pkg.GoFiles {
		if !path.IsAbs(name) {
			name = path.Join(pkg.Dir, name)
		}
		r, err := os.Open(name)
		if err != nil {
			return err
		}
		file, err := parser.ParseFile(FileSet, name, r, 0)
		r.Close()
		if err != nil {
			if list, isList := err.(scanner.ErrorList); isList {
				for _, entry := range list {
					errList = append(errList, entry)
				}
				continue
			}
			errList = append(errList, err)
			continue
		}
		files = append(files, file)
	}
	if errList != nil {
		return errList
	}

	var err error
	pkg.JavaScriptCode, err = translator.TranslatePackage(pkg.ImportPath, files, FileSet, TypesConfig)
	if err != nil {
		return err
	}

	if !pkg.IsCommand() {
		if InstallMode {
			if err := os.MkdirAll(path.Dir(pkg.PkgObj), 0777); err != nil {
				return err
			}
			file, err := os.Create(pkg.PkgObj)
			if err != nil {
				return err
			}
			defer file.Close()
			translator.WriteArchive(pkg.JavaScriptCode, TypesConfig.Packages[pkg.ImportPath], file)
		}
		return nil
	}

	webMode := false
	webModeConst := TypesConfig.Packages[pkg.ImportPath].Scope().Lookup("gopherjsWebMode")
	if webModeConst != nil {
		webMode = exact.BoolVal(webModeConst.(*types.Const).Val())
	}

	if err := os.MkdirAll(path.Dir(pkg.PkgObj), 0777); err != nil {
		return err
	}
	var perm os.FileMode = 0666
	if !webMode {
		perm = 0777
	}
	file, err := os.OpenFile(pkg.PkgObj, os.O_RDWR|os.O_CREATE|os.O_TRUNC, perm)
	if err != nil {
		return err
	}
	defer file.Close()

	if !webMode {
		fmt.Fprintln(file, "#!/usr/bin/env node")
	}
	fmt.Fprintln(file, `"use strict";`)
	fmt.Fprintf(file, "var Go$webMode = %t;\n", webMode)
	file.WriteString(strings.TrimSpace(translator.Prelude))
	file.WriteString("\n")

	Packages[pkg.ImportPath] = pkg
	dependencies, err := translator.GetAllDependencies(pkg.ImportPath, TypesConfig)
	if err != nil {
		return err
	}

	for _, dep := range dependencies {
		file.WriteString("Go$packages[\"" + dep.Path() + "\"] = (function() {\n")
		file.Write(Packages[dep.Path()].JavaScriptCode)
		file.WriteString("})();\n")
	}

	translator.WriteInterfaces(dependencies, file, false)

	for _, dep := range dependencies {
		file.WriteString("Go$packages[\"" + dep.Path() + "\"].init();\n")
	}
	file.WriteString("Go$packages[\"" + pkg.ImportPath + "\"].main();\n")

	return nil
}
<commit_msg>Improved "gopherjs build" command.<commit_after>package main

import (
	"code.google.com/p/go.tools/go/exact"
	"code.google.com/p/go.tools/go/types"
	"flag"
	"fmt"
	"github.com/neelance/gopherjs/translator"
	"go/ast"
	"go/build"
	"go/parser"
	"go/scanner"
	"go/token"
	"io/ioutil"
	"os"
	"os/exec"
	"path"
	"strings"
	"syscall"
	"time"
)

type Package struct {
	*build.Package
	SrcModTime     time.Time
	JavaScriptCode []byte
}

var BuildContext = &build.Context{
	GOROOT:        build.Default.GOROOT,
	GOPATH:        build.Default.GOPATH,
	GOOS:          build.Default.GOOS,
	GOARCH:        build.Default.GOARCH,
	Compiler:      "gc",
	InstallSuffix: "js",
}
var TypesConfig = &types.Config{
	Packages: make(map[string]*types.Package),
}
var FileSet = token.NewFileSet()
var Packages = make(map[string]*Package)
var InstallMode = false

func main() {
	flag.Parse()

	cmd := flag.Arg(0)
	switch cmd {
	case "build":
		buildFlags := flag.NewFlagSet("build", flag.ContinueOnError)
		var pkgObj string
		buildFlags.StringVar(&pkgObj, "o", "", "")
		buildFlags.Parse(flag.Args()[1:])

		if buildFlags.NArg() == 0 {
			wd, err := os.Getwd()
			HandleError(err)
			buildPkg, err := BuildContext.ImportDir(wd, 0)
			HandleError(err)
			pkg := &Package{Package: buildPkg}
			pkg.ImportPath = wd
			if pkgObj == "" {
				pkgObj = path.Base(wd) + ".js"
			}
			pkg.PkgObj = pkgObj
			err = BuildPackage(pkg)
			HandleError(err)
			os.Exit(0)
		}

		if strings.HasSuffix(buildFlags.Arg(0), ".go") {
			for _, arg := range buildFlags.Args() {
				if !strings.HasSuffix(arg, ".go") {
					fmt.Fprintln(os.Stderr, "named files must be .go files")
					os.Exit(1)
				}
			}
			if pkgObj == "" {
				basename := path.Base(buildFlags.Arg(0))
				pkgObj = basename[:len(basename)-3] + ".js"
			}
			err := Build(buildFlags.Args(), pkgObj)
			HandleError(err)
			os.Exit(0)
		}

		for _, pkgPath := range buildFlags.Args() {
			buildPkg, err := BuildContext.Import(pkgPath, "", 0)
			HandleError(err)
			pkg := &Package{Package: buildPkg}
			if pkgObj == "" {
				pkgObj = path.Base(buildFlags.Arg(0)) + ".js"
			}
			pkg.PkgObj = pkgObj
			err = BuildPackage(pkg)
			HandleError(err)
		}

	case "install":
		InstallMode = true
		for _, pkgPath := range flag.Args()[1:] {
			buildPkg, err := BuildContext.Import(pkgPath, "", 0)
			HandleError(err)
			pkg := &Package{Package: buildPkg}
			if pkg.IsCommand() {
				pkg.PkgObj = pkg.BinDir + "/" + path.Base(pkg.ImportPath) + ".js"
			}
			err = BuildPackage(pkg)
			HandleError(err)
		}
		os.Exit(0)

	case "run":
		lastSourceArg := 1
		for {
			if !strings.HasSuffix(flag.Arg(lastSourceArg), ".go") {
				break
			}
			lastSourceArg += 1
		}
		if lastSourceArg == 1 {
			fmt.Fprintln(os.Stderr, "gopherjs run: no go files listed")
			os.Exit(1)
		}

		tempfile, err := ioutil.TempFile("", path.Base(flag.Arg(1))+".")
		HandleError(err)
		defer func() {
			tempfile.Close()
			os.Remove(tempfile.Name())
		}()

		err = Build(flag.Args()[1:lastSourceArg], tempfile.Name())
		HandleError(err)

		node := exec.Command("node", append([]string{tempfile.Name()}, flag.Args()[lastSourceArg:]...)...)
		node.Stdin = os.Stdin
		node.Stdout = os.Stdout
		node.Stderr = os.Stderr
		if err = node.Run(); err != nil {
			if e, isExitError := err.(*exec.ExitError); isExitError {
				os.Exit(e.Sys().(syscall.WaitStatus).ExitStatus())
			}
			HandleError(err)
		}
		os.Exit(0)

	case "tool":
		tool := flag.Arg(1)
		toolFlags := flag.NewFlagSet("tool", flag.ContinueOnError)
		toolFlags.Bool("e", false, "")
		toolFlags.Bool("l", false, "")
		toolFlags.Bool("m", false, "")
		toolFlags.String("o", "", "")
		toolFlags.String("D", "", "")
		toolFlags.String("I", "", "")
		toolFlags.Parse(flag.Args()[2:])

		if len(tool) == 2 {
			switch tool[1] {
			case 'g':
				basename := path.Base(toolFlags.Arg(0))
				err := Build([]string{toolFlags.Arg(0)}, basename[:len(basename)-3]+".js")
				HandleError(err)
				os.Exit(0)
			}
		}
		fmt.Fprintln(os.Stderr, "Tool not supported: "+tool)
		os.Exit(1)

	case "help", "":
		os.Stderr.WriteString(`GopherJS is a tool for compiling Go source code to JavaScript.

Usage:

    gopherjs command [arguments]

The commands are:

    build       compile packages and dependencies
    install     compile and install packages and dependencies
    run         compile and run Go program

`)
		os.Exit(0)

	default:
		fmt.Fprintf(os.Stderr, "gopherjs: unknown subcommand \"%s\"\nRun 'gopherjs help' for usage.\n", cmd)
		os.Exit(1)
	}
}

func HandleError(err error) {
	if err == nil {
		return
	}
	if list, isList := err.(translator.ErrorList); isList {
		for _, entry := range list {
			fmt.Fprintln(os.Stderr, entry)
		}
		os.Exit(1)
	}
	fmt.Fprintln(os.Stderr, err.Error())
	os.Exit(1)
}

func Build(filenames []string, pkgObj string) error {
	wd, err := os.Getwd()
	if err != nil {
		return err
	}
	pkg := &Package{
		Package: &build.Package{
			Name:       "main",
			ImportPath: "main",
			Dir:        wd,
			GoFiles:    filenames,
			PkgObj:     pkgObj,
		},
	}
	return BuildPackage(pkg)
}

func BuildPackage(pkg *Package) error {
	if pkg.ImportPath == "unsafe" {
		TypesConfig.Packages["unsafe"] = types.Unsafe
		return nil
	}

	TypesConfig.Import = func(imports map[string]*types.Package, path string) (*types.Package, error) {
		if _, found := Packages[path]; found {
			return imports[path], nil
		}

		otherPkg, err := BuildContext.Import(path, pkg.Dir, build.AllowBinary)
		if err != nil {
			return nil, err
		}
		pkg := &Package{Package: otherPkg}
		Packages[path] = pkg
		if err := BuildPackage(pkg); err != nil {
			return nil, err
		}

		return imports[path], nil
	}

	if InstallMode {
		if fileInfo, err := os.Stat(os.Args[0]); err == nil { // gopherjs itself
			pkg.SrcModTime = fileInfo.ModTime()
		}

		for _, importedPkgPath := range pkg.Imports {
			_, err := TypesConfig.Import(TypesConfig.Packages, importedPkgPath)
			if err != nil {
				return err
			}
			impModeTime := Packages[importedPkgPath].SrcModTime
			if impModeTime.After(pkg.SrcModTime) {
				pkg.SrcModTime = impModeTime
			}
		}

		for _, name := range pkg.GoFiles {
			fileInfo, err := os.Stat(pkg.Dir + "/" + name)
			if err != nil {
				return err
			}
			if fileInfo.ModTime().After(pkg.SrcModTime) {
				pkg.SrcModTime = fileInfo.ModTime()
			}
		}

		pkgObjFileInfo, err := os.Stat(pkg.PkgObj)
		if err == nil && !pkg.SrcModTime.After(pkgObjFileInfo.ModTime()) {
			// package object is up to date, load from disk if library
			if pkg.IsCommand() {
				return nil
			}

			objFile, err := os.Open(pkg.PkgObj)
			if err != nil {
				return err
			}
			defer objFile.Close()

			pkg.JavaScriptCode, _, err = translator.ReadArchive(TypesConfig.Packages, pkg.PkgObj, pkg.ImportPath, objFile)
			if err != nil {
				return err
			}

			return nil
		}
	}

	files := make([]*ast.File, 0)
	var errList translator.ErrorList
	for _, name := range pkg.GoFiles {
		if !path.IsAbs(name) {
			name = path.Join(pkg.Dir, name)
		}
		r, err := os.Open(name)
		if err != nil {
			return err
		}
		file, err := parser.ParseFile(FileSet, name, r, 0)
		r.Close()
		if err != nil {
			if list, isList := err.(scanner.ErrorList); isList {
				for _, entry := range list {
					errList = append(errList, entry)
				}
				continue
			}
			errList = append(errList, err)
			continue
		}
		files = append(files, file)
	}
	if errList != nil {
		return errList
	}

	var err error
	pkg.JavaScriptCode, err = translator.TranslatePackage(pkg.ImportPath, files, FileSet, TypesConfig)
	if err != nil {
		return err
	}

	if !pkg.IsCommand() {
		if InstallMode {
			if err := os.MkdirAll(path.Dir(pkg.PkgObj), 0777); err != nil {
				return err
			}
			file, err := os.Create(pkg.PkgObj)
			if err != nil {
				return err
			}
			defer file.Close()
			translator.WriteArchive(pkg.JavaScriptCode, TypesConfig.Packages[pkg.ImportPath], file)
		}
		return nil
	}

	webMode := false
	webModeConst := TypesConfig.Packages[pkg.ImportPath].Scope().Lookup("gopherjsWebMode")
	if webModeConst != nil {
		webMode = exact.BoolVal(webModeConst.(*types.Const).Val())
	}

	if err := os.MkdirAll(path.Dir(pkg.PkgObj), 0777); err != nil {
		return err
	}
	var perm os.FileMode = 0666
	if !webMode {
		perm = 0777
	}
	file, err := os.OpenFile(pkg.PkgObj, os.O_RDWR|os.O_CREATE|os.O_TRUNC, perm)
	if err != nil {
		return err
	}
	defer file.Close()

	if !webMode {
		fmt.Fprintln(file, "#!/usr/bin/env node")
	}
	fmt.Fprintln(file, `"use strict";`)
	fmt.Fprintf(file, "var Go$webMode = %t;\n", webMode)
	file.WriteString(strings.TrimSpace(translator.Prelude))
	file.WriteString("\n")

	Packages[pkg.ImportPath] = pkg
	dependencies, err := translator.GetAllDependencies(pkg.ImportPath, TypesConfig)
	if err != nil {
		return err
	}

	for _, dep := range dependencies {
		file.WriteString("Go$packages[\"" + dep.Path() + "\"] = (function() {\n")
		file.Write(Packages[dep.Path()].JavaScriptCode)
		file.WriteString("})();\n")
	}

	translator.WriteInterfaces(dependencies, file, false)

	for _, dep := range dependencies {
		file.WriteString("Go$packages[\"" + dep.Path() + "\"].init();\n")
	}
	file.WriteString("Go$packages[\"" + pkg.ImportPath + "\"].main();\n")

	return nil
}
<|endoftext|>


<commit_before>package sms

import (
	"bytes"
	"io"
	"time"
)

var (
	msgRef byte
	// Indent for String() output for each TPDU
	Indent = " | "
)

func init() {
	msgRef = byte(time.Now().Nanosecond())
}

// TPDU represents a SMS PDU
type TPDU interface {
	Encode() []byte
	Decode([]byte) error
	String() string
}

// DecodeAsSC parse byte data to TPDU as SC.
func DecodeAsSC(b []byte) (t TPDU, e error) {
	return decode(b, true)
}

// DecodeAsMS parse byte data to TPDU as MS.
func DecodeAsMS(b []byte) (t TPDU, e error) {
	return decode(b, false)
}

func decode(b []byte, sc bool) (t TPDU, e error) {
	if len(b) == 0 {
		e = io.EOF
	} else if sc {
		switch b[0] & 0x03 {
		case 0x00:
			t = &DeliverReport{}
		case 0x01:
			t = &Submit{}
		case 0x02:
			// t = &Command{}
		case 0x03:
			e = &InvalidDataError{
				Name:  "reserved TPDU type",
				Bytes: b}
		}
	} else {
		switch b[0] & 0x03 {
		case 0x00:
			t = &Deliver{}
		case 0x01:
			t = &SubmitReport{}
		case 0x02:
			t = &StatusReport{}
		case 0x03:
			e = &InvalidDataError{
				Name:  "reserved TPDU type",
				Bytes: b}
		}
	}

	if e == nil {
		e = t.Decode(b)
	}
	return
}

func read7Bytes(r *bytes.Reader) ([7]byte, error) {
	if r.Len() < 7 {
		return [7]byte{}, io.EOF
	}
	b := make([]byte, 7)
	r.Read(b)
	return [7]byte{
		b[0], b[1], b[2], b[3], b[4], b[5], b[6]}, nil
}

func readUD(r *bytes.Reader, d dcs, h bool) ([]byte, []udh, error) {
	p, e := r.ReadByte()
	if e != nil {
		return nil, nil, e
	}
	l := d.unitSize()
	l *= int(p)
	if l%8 != 0 {
		l += 8 - l%8
	}

	ud := make([]byte, l/8)
	if r.Len() < len(ud) {
		return nil, nil, io.EOF
	}
	r.Read(ud)

	if h {
		return ud[ud[0]+1:], decodeUDH(ud[0 : ud[0]+1]), nil
	}
	return ud, nil, nil
}

func writeUD(w *bytes.Buffer, ud []byte, h []udh, d dcs) {
	udh := encodeUDH(h)

	u := d.unitSize()
	l := len(udh) + len(ud)
	l = ((l * 8) - (l * 8 % u)) / u

	w.WriteByte(byte(l))
	w.Write(udh)
	w.Write(ud)
}

func encodeSCTimeStamp(t time.Time) (r []byte) {
	r = make([]byte, 7)
	r[0] = int2SemiOctet(t.Year())
	r[1] = int2SemiOctet(int(t.Month()))
	r[2] = int2SemiOctet(t.Day())
	r[3] = int2SemiOctet(t.Hour())
	r[4] = int2SemiOctet(t.Minute())
	r[5] = int2SemiOctet(t.Second())

	_, z := t.Zone()
	z /= 900
	r[6] = byte((z % 10) & 0x0f)
	r[6] = (r[6] << 4) | byte(((z/10)%10)&0x0f)
	if z < 0 {
		r[6] = r[6] | 0x08
	}
	return
}

func decodeSCTimeStamp(t [7]byte) time.Time {
	d := [6]int{}
	for i := range d {
		d[i] = semiOctet2Int(t[i])
	}
	l := semiOctet2Int(t[6] & 0x7f)
	if t[6]&0x80 == 0x80 {
		l = -l
	}
	return time.Date(2000+d[0],
		time.Month(d[1]), d[2], d[3], d[4], d[5], 0,
		time.FixedZone("unknown", l*15*60))
}

func int2SemiOctet(i int) (b byte) {
	b = byte(i % 10)
	b = (b << 4) | byte((i/10)%10)
	return
}

func semiOctet2Int(b byte) (i int) {
	i = int(b & 0x0f)
	i = (i * 10) + int((b&0xf0)>>4)
	return
}
<commit_msg>modify<commit_after>package sms

import (
	"bytes"
	"io"
	"time"
)

var (
	msgRef chan byte
	// Indent for String() output for each TPDU
	Indent = " | "
)

func init() {
	msgRef = make(chan byte, 1)
	msgRef <- byte(time.Now().Nanosecond())
}

// NextMsgReference make Message Reference ID
func NextMsgReference() byte {
	ret := <-msgRef
	msgRef <- ret + 1
	return ret
}

// TPDU represents a SMS PDU
type TPDU interface {
	Encode() []byte
	Decode([]byte) error
	String() string
}

// DecodeAsSC parse byte data to TPDU as SC.
func DecodeAsSC(b []byte) (t TPDU, e error) {
	return decode(b, true)
}

// DecodeAsMS parse byte data to TPDU as MS.
func DecodeAsMS(b []byte) (t TPDU, e error) {
	return decode(b, false)
}

func decode(b []byte, sc bool) (t TPDU, e error) {
	if len(b) == 0 {
		e = io.EOF
	} else if sc {
		switch b[0] & 0x03 {
		case 0x00:
			t = &DeliverReport{}
		case 0x01:
			t = &Submit{}
		case 0x02:
			// t = &Command{}
		case 0x03:
			e = &InvalidDataError{
				Name:  "reserved TPDU type",
				Bytes: b}
		}
	} else {
		switch b[0] & 0x03 {
		case 0x00:
			t = &Deliver{}
		case 0x01:
			t = &SubmitReport{}
		case 0x02:
			t = &StatusReport{}
		case 0x03:
			e = &InvalidDataError{
				Name:  "reserved TPDU type",
				Bytes: b}
		}
	}

	if e == nil {
		e = t.Decode(b)
	}
	return
}

func read7Bytes(r *bytes.Reader) ([7]byte, error) {
	if r.Len() < 7 {
		return [7]byte{}, io.EOF
	}
	b := make([]byte, 7)
	r.Read(b)
	return [7]byte{
		b[0], b[1], b[2], b[3], b[4], b[5], b[6]}, nil
}

func readUD(r *bytes.Reader, d dcs, h bool) ([]byte, []udh, error) {
	p, e := r.ReadByte()
	if e != nil {
		return nil, nil, e
	}
	l := d.unitSize()
	l *= int(p)
	if l%8 != 0 {
		l += 8 - l%8
	}

	ud := make([]byte, l/8)
	if r.Len() < len(ud) {
		return nil, nil, io.EOF
	}
	r.Read(ud)

	if h {
		return ud[ud[0]+1:], decodeUDH(ud[0 : ud[0]+1]), nil
	}
	return ud, nil, nil
}

func writeUD(w *bytes.Buffer, ud []byte, h []udh, d dcs) {
	udh := encodeUDH(h)

	u := d.unitSize()
	l := len(udh) + len(ud)
	l = ((l * 8) - (l * 8 % u)) / u

	w.WriteByte(byte(l))
	w.Write(udh)
	w.Write(ud)
}

func encodeSCTimeStamp(t time.Time) (r []byte) {
	r = make([]byte, 7)
	r[0] = int2SemiOctet(t.Year())
	r[1] = int2SemiOctet(int(t.Month()))
	r[2] = int2SemiOctet(t.Day())
	r[3] = int2SemiOctet(t.Hour())
	r[4] = int2SemiOctet(t.Minute())
	r[5] = int2SemiOctet(t.Second())

	_, z := t.Zone()
	z /= 900
	r[6] = byte((z % 10) & 0x0f)
	r[6] = (r[6] << 4) | byte(((z/10)%10)&0x0f)
	if z < 0 {
		r[6] = r[6] | 0x08
	}
	return
}

func decodeSCTimeStamp(t [7]byte) time.Time {
	d := [6]int{}
	for i := range d {
		d[i] = semiOctet2Int(t[i])
	}
	l := semiOctet2Int(t[6] & 0x7f)
	if t[6]&0x80 == 0x80 {
		l = -l
	}
	return time.Date(2000+d[0],
		time.Month(d[1]), d[2], d[3], d[4], d[5], 0,
		time.FixedZone("unknown", l*15*60))
}

func int2SemiOctet(i int) (b byte) {
	b = byte(i % 10)
	b = (b << 4) | byte((i/10)%10)
	return
}

func semiOctet2Int(b byte) (i int) {
	i = int(b & 0x0f)
	i = (i * 10) + int((b&0xf0)>>4)
	return
}
<|endoftext|>


<commit_before>package hush

import (
	"crypto/sha256"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"sort"
	"strings"

	"golang.org/x/crypto/pbkdf2"

	"github.com/pkg/errors"

	yaml "gopkg.in/yaml.v2"
)

type Tree struct {
	tree map[Path]*Value

	encryptionKey []byte
}

const safePerm = 0600 // rw- --- ---

func LoadTree() (*Tree, error) {
	hushPath, err := hushPath()
	if err != nil {
		return nil, err
	}

	stat, err := os.Stat(hushPath)
	if os.IsNotExist(err) {
		warn("hush file does not exist. assuming an empty one")
		return &Tree{}, nil
	}
	if err != nil {
		return nil, errors.Wrap(err, "can't stat hush file")
	}
	if (stat.Mode() & os.ModePerm) != safePerm {
		warn("hush file has loose permissions. fixing.")
		err := os.Chmod(hushPath, safePerm)
		if err != nil {
			die("couldn't fix permissions on hush file")
		}
	}

	file, err := os.Open(hushPath)
	if err != nil {
		return nil, errors.Wrap(err, "opening hush file")
	}
	hushData, err := ioutil.ReadAll(file)
	if err != nil {
		return nil, errors.Wrap(err, "can't read hush file")
	}

	keys := make(yaml.MapSlice, 0)
	err = yaml.Unmarshal(hushData, &keys)
	if err != nil {
		return nil, errors.Wrap(err, "can't parse hush file")
	}
	tree := newT(keys)
	return tree, nil
}

func newT(items yaml.MapSlice) *Tree {
	t := &Tree{
		tree: make(map[Path]*Value, 3*len(items)),
	}
	newT_(items, []string{}, t)
	return t
}

func newT_(items yaml.MapSlice, crumbs []string, t *Tree) {
	n := len(crumbs)
	for _, item := range items {
		key := item.Key.(string)
		crumbs = append(crumbs, key)

		switch val := item.Value.(type) {
		case string:
			p := NewPath(strings.Join(crumbs, "/"))
			privacy := Private
			if p.IsPublic() {
				privacy = Public
			}
			t.tree[p] = NewEncoded(val, privacy)
		case yaml.MapSlice:
			newT_(val, crumbs, t)
		default:
			panic(fmt.Sprintf("unexpected type: %#v", val))
		}
		crumbs = crumbs[:n] // remove final crumb
	}
}

func (t *Tree) mapSlice() yaml.MapSlice {
	// sort by key
	kvs := make([][]string, 0, len(t.tree))
	for p, val := range t.tree {
		kvs = append(kvs, []string{string(p), val.String()})
	}
	sort.SliceStable(kvs, func(i, j int) bool {
		return kvs[i][0] < kvs[j][0]
	})

	var slice yaml.MapSlice
	for _, kv := range kvs {
		path := strings.Split(kv[0], "\t")
		slice = mapSlice_(slice, path, kv[1])
	}
	return slice
}

func mapSlice_(slice yaml.MapSlice, path []string, value string) yaml.MapSlice {
	if len(path) == 0 {
		panic("path should never have 0 length")
	}
	if len(path) == 1 {
		return append(slice, yaml.MapItem{
			Key:   path[0],
			Value: value,
		})
	}

	var inner yaml.MapSlice
	if len(slice) == 0 {
		slice = append(slice, yaml.MapItem{Key: path[0]})
	} else {
		final := slice[len(slice)-1]
		if final.Key.(string) == path[0] {
			inner = final.Value.(yaml.MapSlice)
		} else {
			slice = append(slice, yaml.MapItem{Key: path[0]})
		}
	}
	slice[len(slice)-1].Value = mapSlice_(inner, path[1:], value)
	return slice
}

func (t *Tree) filter(pattern string) *Tree {
	keep := t.Empty()
	for p, val := range t.tree {
		if matches(p, pattern) {
			keep.tree[p] = val
		}
	}
	return keep
}

func isLowercase(s string) bool {
	return s == strings.ToLower(s)
}

func matches(p Path, pattern string) bool {
	ps := strings.Split(string(p), "\t")
	patterns := strings.Split(pattern, "/")
	if len(patterns) > len(ps) {
		return false
	}

	ignoreCase := isLowercase(pattern)
	for i, pattern := range patterns {
		haystack := ps[i]
		if ignoreCase {
			haystack = strings.ToLower(haystack)
		}
		if !strings.Contains(haystack, pattern) {
			return false
		}
	}
	return true
}

func (t *Tree) get(p Path) (*Value, bool) {
	val, ok := t.tree[p]
	return val, ok
}

func (t *Tree) set(p Path, val *Value) {
	t.tree[p] = val
}

// Encrypt returns a copy of this tree with all leaves encrypted.
func (tree *Tree) Encrypt() *Tree {
	t := tree.Empty()
	for p, v := range tree.tree {
		if p.IsPublic() { // don't encrypt public data
			t.tree[p] = v
			continue
		}
		if p.IsEncryptionKey() { // value uses different encryption key
			t.tree[p] = v
			continue
		}
		t.tree[p] = v.Ciphertext(t.encryptionKey)
	}
	return t
}

// Encode returns a copy of this tree with all leaves encoded into base64.
func (tree *Tree) Encode() *Tree {
	t := tree.Empty()
	for p, v := range tree.tree {
		t.tree[p] = v.Encode()
	}
	return t
}

// Empty returns a copy of this tree with all the keys and values
// removed.  It retains any other data associated with this tree.
func (t *Tree) Empty() *Tree {
	tree := &Tree{
		tree:          make(map[Path]*Value, len(t.tree)),
		encryptionKey: t.encryptionKey,
	}
	return tree
}

// SetPassphrase sets the password that's used for performing
// encryption and decryption.
func (t *Tree) SetPassphrase(password []byte) error {
	p := NewPath("hush-configuration/salt")
	v, ok := t.get(p)
	if !ok {
		return errors.New("hush file missing salt")
	}
	v, err := v.Decode()
	if err != nil {
		return err
	}
	salt := v.plaintext
	pwKey := stretchPassword(password, salt)

	p = NewPath("hush-configuration/encryption-key")
	v, ok = t.get(p)
	if !ok {
		return errors.New("hush file missing encryption key")
	}
	v = v.Plaintext(pwKey)

	t.encryptionKey = v.plaintext
	return nil
}

// Decrypt returns a copy of this tree with all leaves decrypted.
func (tree *Tree) Decrypt() *Tree {
	t := tree.Empty()
	for p, v := range tree.tree {
		if p.IsPublic() { // don't decrypt public data
			t.tree[p] = v
			continue
		}
		if p.IsEncryptionKey() { // value uses different encryption key
			t.tree[p] = v
			continue
		}
		t.tree[p] = v.Plaintext(tree.encryptionKey)
	}
	return t
}

// Print displays a tree for human consumption.
func (tree *Tree) Print(w io.Writer) error {
	tree = tree.Decrypt()
	slice := tree.mapSlice()
	data, err := yaml.Marshal(slice)
	if err != nil {
		return errors.Wrap(err, "printing tree")
	}

	_, err = w.Write(data)
	return err
}

// Save stores a tree to disk for permanent, private archival.
func (tree *Tree) Save() error {
	tree = tree.Encrypt().Encode()
	slice := tree.mapSlice()

	data, err := yaml.Marshal(slice)
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}

	// save to temporary file
	file, err := ioutil.TempFile("", "hush-")
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}
	err = os.Chmod(file.Name(), safePerm)
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}
	_, err = file.Write(data)
	file.Close()
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}

	// move temporary file over top of permanent file
	hushPath, err := hushPath()
	if os.IsNotExist(err) {
		err = nil // we can create the file
	}
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}
	err = os.Rename(file.Name(), hushPath)
	return errors.Wrap(err, "saving tree")
}

// stretchPassword converts a password and a salt into a
// cryptographically secure key.
func stretchPassword(password, salt []byte) []byte {
	pwKey := pbkdf2.Key(
		password, salt,
		2<<15, // iteration count (about 80ms on modern server)
		32,    // desired key size in bytes
		sha256.New,
	)
	return pwKey
}
<commit_msg>Better error message for corrupted salt<commit_after>package hush

import (
	"crypto/sha256"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"sort"
	"strings"

	"golang.org/x/crypto/pbkdf2"

	"github.com/pkg/errors"

	yaml "gopkg.in/yaml.v2"
)

type Tree struct {
	tree map[Path]*Value

	encryptionKey []byte
}

const safePerm = 0600 // rw- --- ---

func LoadTree() (*Tree, error) {
	hushPath, err := hushPath()
	if err != nil {
		return nil, err
	}

	stat, err := os.Stat(hushPath)
	if os.IsNotExist(err) {
		warn("hush file does not exist. assuming an empty one")
		return &Tree{}, nil
	}
	if err != nil {
		return nil, errors.Wrap(err, "can't stat hush file")
	}
	if (stat.Mode() & os.ModePerm) != safePerm {
		warn("hush file has loose permissions. fixing.")
		err := os.Chmod(hushPath, safePerm)
		if err != nil {
			die("couldn't fix permissions on hush file")
		}
	}

	file, err := os.Open(hushPath)
	if err != nil {
		return nil, errors.Wrap(err, "opening hush file")
	}
	hushData, err := ioutil.ReadAll(file)
	if err != nil {
		return nil, errors.Wrap(err, "can't read hush file")
	}

	keys := make(yaml.MapSlice, 0)
	err = yaml.Unmarshal(hushData, &keys)
	if err != nil {
		return nil, errors.Wrap(err, "can't parse hush file")
	}
	tree := newT(keys)
	return tree, nil
}

func newT(items yaml.MapSlice) *Tree {
	t := &Tree{
		tree: make(map[Path]*Value, 3*len(items)),
	}
	newT_(items, []string{}, t)
	return t
}

func newT_(items yaml.MapSlice, crumbs []string, t *Tree) {
	n := len(crumbs)
	for _, item := range items {
		key := item.Key.(string)
		crumbs = append(crumbs, key)

		switch val := item.Value.(type) {
		case string:
			p := NewPath(strings.Join(crumbs, "/"))
			privacy := Private
			if p.IsPublic() {
				privacy = Public
			}
			t.tree[p] = NewEncoded(val, privacy)
		case yaml.MapSlice:
			newT_(val, crumbs, t)
		default:
			panic(fmt.Sprintf("unexpected type: %#v", val))
		}
		crumbs = crumbs[:n] // remove final crumb
	}
}

func (t *Tree) mapSlice() yaml.MapSlice {
	// sort by key
	kvs := make([][]string, 0, len(t.tree))
	for p, val := range t.tree {
		kvs = append(kvs, []string{string(p), val.String()})
	}
	sort.SliceStable(kvs, func(i, j int) bool {
		return kvs[i][0] < kvs[j][0]
	})

	var slice yaml.MapSlice
	for _, kv := range kvs {
		path := strings.Split(kv[0], "\t")
		slice = mapSlice_(slice, path, kv[1])
	}
	return slice
}

func mapSlice_(slice yaml.MapSlice, path []string, value string) yaml.MapSlice {
	if len(path) == 0 {
		panic("path should never have 0 length")
	}
	if len(path) == 1 {
		return append(slice, yaml.MapItem{
			Key:   path[0],
			Value: value,
		})
	}

	var inner yaml.MapSlice
	if len(slice) == 0 {
		slice = append(slice, yaml.MapItem{Key: path[0]})
	} else {
		final := slice[len(slice)-1]
		if final.Key.(string) == path[0] {
			inner = final.Value.(yaml.MapSlice)
		} else {
			slice = append(slice, yaml.MapItem{Key: path[0]})
		}
	}
	slice[len(slice)-1].Value = mapSlice_(inner, path[1:], value)
	return slice
}

func (t *Tree) filter(pattern string) *Tree {
	keep := t.Empty()
	for p, val := range t.tree {
		if matches(p, pattern) {
			keep.tree[p] = val
		}
	}
	return keep
}

func isLowercase(s string) bool {
	return s == strings.ToLower(s)
}

func matches(p Path, pattern string) bool {
	ps := strings.Split(string(p), "\t")
	patterns := strings.Split(pattern, "/")
	if len(patterns) > len(ps) {
		return false
	}

	ignoreCase := isLowercase(pattern)
	for i, pattern := range patterns {
		haystack := ps[i]
		if ignoreCase {
			haystack = strings.ToLower(haystack)
		}
		if !strings.Contains(haystack, pattern) {
			return false
		}
	}
	return true
}

func (t *Tree) get(p Path) (*Value, bool) {
	val, ok := t.tree[p]
	return val, ok
}

func (t *Tree) set(p Path, val *Value) {
	t.tree[p] = val
}

// Encrypt returns a copy of this tree with all leaves encrypted.
func (tree *Tree) Encrypt() *Tree {
	t := tree.Empty()
	for p, v := range tree.tree {
		if p.IsPublic() { // don't encrypt public data
			t.tree[p] = v
			continue
		}
		if p.IsEncryptionKey() { // value uses different encryption key
			t.tree[p] = v
			continue
		}
		t.tree[p] = v.Ciphertext(t.encryptionKey)
	}
	return t
}

// Encode returns a copy of this tree with all leaves encoded into base64.
func (tree *Tree) Encode() *Tree {
	t := tree.Empty()
	for p, v := range tree.tree {
		t.tree[p] = v.Encode()
	}
	return t
}

// Empty returns a copy of this tree with all the keys and values
// removed.  It retains any other data associated with this tree.
func (t *Tree) Empty() *Tree {
	tree := &Tree{
		tree:          make(map[Path]*Value, len(t.tree)),
		encryptionKey: t.encryptionKey,
	}
	return tree
}

// SetPassphrase sets the password that's used for performing
// encryption and decryption.
func (t *Tree) SetPassphrase(password []byte) error {
	p := NewPath("hush-configuration/salt")
	v, ok := t.get(p)
	if !ok {
		return errors.New("hush file missing salt")
	}
	v, err := v.Decode()
	if err != nil {
		return errors.Wrap(err, "decoding salt")
	}
	salt := v.plaintext
	pwKey := stretchPassword(password, salt)

	p = NewPath("hush-configuration/encryption-key")
	v, ok = t.get(p)
	if !ok {
		return errors.New("hush file missing encryption key")
	}
	v = v.Plaintext(pwKey)

	t.encryptionKey = v.plaintext
	return nil
}

// Decrypt returns a copy of this tree with all leaves decrypted.
func (tree *Tree) Decrypt() *Tree {
	t := tree.Empty()
	for p, v := range tree.tree {
		if p.IsPublic() { // don't decrypt public data
			t.tree[p] = v
			continue
		}
		if p.IsEncryptionKey() { // value uses different encryption key
			t.tree[p] = v
			continue
		}
		t.tree[p] = v.Plaintext(tree.encryptionKey)
	}
	return t
}

// Print displays a tree for human consumption.
func (tree *Tree) Print(w io.Writer) error {
	tree = tree.Decrypt()
	slice := tree.mapSlice()
	data, err := yaml.Marshal(slice)
	if err != nil {
		return errors.Wrap(err, "printing tree")
	}

	_, err = w.Write(data)
	return err
}

// Save stores a tree to disk for permanent, private archival.
func (tree *Tree) Save() error {
	tree = tree.Encrypt().Encode()
	slice := tree.mapSlice()

	data, err := yaml.Marshal(slice)
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}

	// save to temporary file
	file, err := ioutil.TempFile("", "hush-")
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}
	err = os.Chmod(file.Name(), safePerm)
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}
	_, err = file.Write(data)
	file.Close()
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}

	// move temporary file over top of permanent file
	hushPath, err := hushPath()
	if os.IsNotExist(err) {
		err = nil // we can create the file
	}
	if err != nil {
		return errors.Wrap(err, "saving tree")
	}
	err = os.Rename(file.Name(), hushPath)
	return errors.Wrap(err, "saving tree")
}

// stretchPassword converts a password and a salt into a
// cryptographically secure key.
func stretchPassword(password, salt []byte) []byte {
	pwKey := pbkdf2.Key(
		password, salt,
		2<<15, // iteration count (about 80ms on modern server)
		32,    // desired key size in bytes
		sha256.New,
	)
	return pwKey
}
<|endoftext|>


<commit_before>package aero

import (
	"strings"
)

// controlFlow tells the main loop what it should do next.
type controlFlow int

// controlFlow values.
const (
	controlStop  controlFlow = 0
	controlBegin controlFlow = 1
	controlNext  controlFlow = 2
)

// dataType specifies which type of data we are going to save for each node.
type dataType = Handler

// tree represents a radix tree.
type tree struct {
	root        treeNode
	static      map[string]dataType
	canBeStatic [2048]bool
}

// add adds a new element to the tree.
func (tree *tree) add(path string, data dataType) {
	if !strings.Contains(path, ":") && !strings.Contains(path, "*") {
		if tree.static == nil {
			tree.static = map[string]dataType{}
		}

		tree.static[path] = data
		tree.canBeStatic[len(path)] = true
		return
	}

	// Search tree for equal parts until we can no longer proceed
	i := 0
	offset := 0
	node := &tree.root

	for {
	begin:
		switch node.kind {
		case parameter:
			// This only occurs when the same parameter based route is added twice.
			// node: /post/:id|
			// path: /post/:id|
			if i == len(path) {
				node.data = data
				return
			}

			// When we hit a separator, we'll search for a fitting child.
			if path[i] == separator {
				var control controlFlow
				node, offset, control = node.end(path, data, i, offset)

				switch control {
				case controlStop:
					return
				case controlBegin:
					goto begin
				case controlNext:
					goto next
				}
			}

		default:
			if i == len(path) {
				// The path already exists.
				// node: /blog|
				// path: /blog|
				if i-offset == len(node.prefix) {
					node.data = data
					return
				}

				// The path ended but the node prefix is longer.
				// node: /blog|feed
				// path: /blog|
				node.split(i-offset, "", data)
				return
			}

			// The node we just checked is entirely included in our path.
			// node: /|
			// path: /|blog
			if i-offset == len(node.prefix) {
				var control controlFlow
				node, offset, control = node.end(path, data, i, offset)

				switch control {
				case controlStop:
					return
				case controlBegin:
					goto begin
				case controlNext:
					goto next
				}
			}

			// We got a conflict.
			// node: /b|ag
			// path: /b|riefcase
			if path[i] != node.prefix[i-offset] {
				node.split(i-offset, path[i:], data)
				return
			}
		}

	next:
		i++
	}
}

// find finds the data for the given path and assigns it to ctx.handler, if available.
func (tree *tree) find(path string, ctx *context) {
	if tree.canBeStatic[len(path)] {
		handler, found := tree.static[path]

		if found {
			ctx.handler = handler
			return
		}
	}

	var (
		i                  uint
		offset             uint
		lastWildcardOffset uint
		lastWildcard       *treeNode
		node               = &tree.root
	)

	// Search tree for equal parts until we can no longer proceed
begin:
	for {
		// We reached the end.
		if i == uint(len(path)) {
			// node: /blog|
			// path: /blog|
			if i-offset == uint(len(node.prefix)) {
				ctx.handler = node.data
				return
			}

			// node: /blog|feed
			// path: /blog|
			ctx.handler = nil
			return
		}

		// The node we just checked is entirely included in our path.
		// node: /|
		// path: /|blog
		if i-offset == uint(len(node.prefix)) {
			if node.wildcard != nil {
				lastWildcard = node.wildcard
				lastWildcardOffset = i
			}

			char := path[i]

			if char >= node.startIndex && char < node.endIndex {
				index := node.indices[char-node.startIndex]

				if index != 0 {
					node = node.children[index]
					offset = i
					i++
					continue
				}
			}

			// node: /|:id
			// path: /|blog
			if node.parameter != nil {
				node = node.parameter
				offset = i
				i++

				for {
					// We reached the end.
					if i == uint(len(path)) {
						ctx.addParameter(node.prefix, path[offset:i])
						ctx.handler = node.data
						return
					}

					// node: /:id|/posts
					// path: /123|/posts
					if path[i] == separator {
						ctx.addParameter(node.prefix, path[offset:i])
						index := node.indices[separator-node.startIndex]
						node = node.children[index]
						offset = i
						i++
						goto begin
					}

					i++
				}
			}

			// node: /|*any
			// path: /|image.png
			if node.wildcard != nil {
				ctx.addParameter(node.wildcard.prefix, path[i:])
				ctx.handler = node.wildcard.data
				return
			}

			ctx.handler = nil
			return
		}

		// We got a conflict.
		// node: /b|ag
		// path: /b|riefcase
		if path[i] != node.prefix[i-offset] {
			if lastWildcard != nil {
				ctx.addParameter(lastWildcard.prefix, path[lastWildcardOffset:])
				ctx.handler = lastWildcard.data
				return
			}

			ctx.handler = nil
			return
		}

		i++
	}
}

// bind binds all handlers to a new one provided by the callback.
func (tree *tree) bind(transform func(Handler) Handler) {
	tree.root.each(func(node *treeNode) {
		if node.data != nil {
			node.data = transform(node.data)
		}
	})

	for key, value := range tree.static {
		tree.static[key] = transform(value)
	}
}
<commit_msg>Better comment placement<commit_after>package aero

import (
	"strings"
)

// controlFlow tells the main loop what it should do next.
type controlFlow int

// controlFlow values.
const (
	controlStop  controlFlow = 0
	controlBegin controlFlow = 1
	controlNext  controlFlow = 2
)

// dataType specifies which type of data we are going to save for each node.
type dataType = Handler

// tree represents a radix tree.
type tree struct {
	root        treeNode
	static      map[string]dataType
	canBeStatic [2048]bool
}

// add adds a new element to the tree.
func (tree *tree) add(path string, data dataType) {
	if !strings.Contains(path, ":") && !strings.Contains(path, "*") {
		if tree.static == nil {
			tree.static = map[string]dataType{}
		}

		tree.static[path] = data
		tree.canBeStatic[len(path)] = true
		return
	}

	// Search tree for equal parts until we can no longer proceed
	i := 0
	offset := 0
	node := &tree.root

	for {
	begin:
		switch node.kind {
		case parameter:
			// This only occurs when the same parameter based route is added twice.
			// node: /post/:id|
			// path: /post/:id|
			if i == len(path) {
				node.data = data
				return
			}

			// When we hit a separator, we'll search for a fitting child.
			if path[i] == separator {
				var control controlFlow
				node, offset, control = node.end(path, data, i, offset)

				switch control {
				case controlStop:
					return
				case controlBegin:
					goto begin
				case controlNext:
					goto next
				}
			}

		default:
			if i == len(path) {
				// The path already exists.
				// node: /blog|
				// path: /blog|
				if i-offset == len(node.prefix) {
					node.data = data
					return
				}

				// The path ended but the node prefix is longer.
				// node: /blog|feed
				// path: /blog|
				node.split(i-offset, "", data)
				return
			}

			// The node we just checked is entirely included in our path.
			// node: /|
			// path: /|blog
			if i-offset == len(node.prefix) {
				var control controlFlow
				node, offset, control = node.end(path, data, i, offset)

				switch control {
				case controlStop:
					return
				case controlBegin:
					goto begin
				case controlNext:
					goto next
				}
			}

			// We got a conflict.
			// node: /b|ag
			// path: /b|riefcase
			if path[i] != node.prefix[i-offset] {
				node.split(i-offset, path[i:], data)
				return
			}
		}

	next:
		i++
	}
}

// find finds the data for the given path and assigns it to ctx.handler, if available.
func (tree *tree) find(path string, ctx *context) {
	if tree.canBeStatic[len(path)] {
		handler, found := tree.static[path]

		if found {
			ctx.handler = handler
			return
		}
	}

	var (
		i                  uint
		offset             uint
		lastWildcardOffset uint
		lastWildcard       *treeNode
		node               = &tree.root
	)

begin:
	// Search tree for equal parts until we can no longer proceed
	for {
		// We reached the end.
		if i == uint(len(path)) {
			// node: /blog|
			// path: /blog|
			if i-offset == uint(len(node.prefix)) {
				ctx.handler = node.data
				return
			}

			// node: /blog|feed
			// path: /blog|
			ctx.handler = nil
			return
		}

		// The node we just checked is entirely included in our path.
		// node: /|
		// path: /|blog
		if i-offset == uint(len(node.prefix)) {
			if node.wildcard != nil {
				lastWildcard = node.wildcard
				lastWildcardOffset = i
			}

			char := path[i]

			if char >= node.startIndex && char < node.endIndex {
				index := node.indices[char-node.startIndex]

				if index != 0 {
					node = node.children[index]
					offset = i
					i++
					continue
				}
			}

			// node: /|:id
			// path: /|blog
			if node.parameter != nil {
				node = node.parameter
				offset = i
				i++

				for {
					// We reached the end.
					if i == uint(len(path)) {
						ctx.addParameter(node.prefix, path[offset:i])
						ctx.handler = node.data
						return
					}

					// node: /:id|/posts
					// path: /123|/posts
					if path[i] == separator {
						ctx.addParameter(node.prefix, path[offset:i])
						index := node.indices[separator-node.startIndex]
						node = node.children[index]
						offset = i
						i++
						goto begin
					}

					i++
				}
			}

			// node: /|*any
			// path: /|image.png
			if node.wildcard != nil {
				ctx.addParameter(node.wildcard.prefix, path[i:])
				ctx.handler = node.wildcard.data
				return
			}

			ctx.handler = nil
			return
		}

		// We got a conflict.
		// node: /b|ag
		// path: /b|riefcase
		if path[i] != node.prefix[i-offset] {
			if lastWildcard != nil {
				ctx.addParameter(lastWildcard.prefix, path[lastWildcardOffset:])
				ctx.handler = lastWildcard.data
				return
			}

			ctx.handler = nil
			return
		}

		i++
	}
}

// bind binds all handlers to a new one provided by the callback.
func (tree *tree) bind(transform func(Handler) Handler) {
	tree.root.each(func(node *treeNode) {
		if node.data != nil {
			node.data = transform(node.data)
		}
	})

	for key, value := range tree.static {
		tree.static[key] = transform(value)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"time"

	"github.com/bgentry/go-netrc/netrc"
	"github.com/bgentry/heroku-go"
	"github.com/mgutz/ansi"
)

var nrc *netrc.Netrc

// user.Current() requires cgo and thus doesn't work with cross-compiling.
// The following is an alternative that matches how the Heroku Toolbelt
// works, though per @fdr it may not be correct for all cases (when users have
// modified their home dir).
//
// homePath() is defined in the platform-specific source files unix.go and
// windows.go.
//
// http://stackoverflow.com/questions/7922270/obtain-users-home-directory
func hkHome() string {
	return filepath.Join(homePath(), ".hk")
}

func netrcPath() string {
	if s := os.Getenv("NETRC_PATH"); s != "" {
		return s
	}

	return filepath.Join(homePath(), netrcFilename)
}

func loadNetrc() {
	if nrc == nil {
		var err error
		if nrc, err = netrc.ParseFile(netrcPath()); err != nil {
			if os.IsNotExist(err) {
				return
			}
			printError("loading netrc: " + err.Error())
		}
	}
}

func getCreds(u string) (user, pass string) {
	loadNetrc()
	if nrc == nil {
		return "", ""
	}

	apiURL, err := url.Parse(u)
	if err != nil {
		printError("invalid API URL: %s", err)
	}
	if apiURL.Host == "" {
		printError("missing API host: %s", u)
	}
	if apiURL.User != nil {
		pw, _ := apiURL.User.Password()
		return apiURL.User.Username(), pw
	}

	m := nrc.FindMachine(apiURL.Host)
	if m == nil {
		return "", ""
	}
	return m.Login, m.Password
}

func saveCreds(host, user, pass string) error {
	loadNetrc()
	m := nrc.FindMachine(host)
	if m == nil || m.IsDefault() {
		m = nrc.NewMachine(host, user, pass, "")
	}
	m.UpdateLogin(user)
	m.UpdatePassword(pass)

	body, err := nrc.MarshalText()
	if err != nil {
		return err
	}
	return ioutil.WriteFile(netrcPath(), body, 0600)
}

func removeCreds(host string) error {
	loadNetrc()
	nrc.RemoveMachine(host)

	body, err := nrc.MarshalText()
	if err != nil {
		return err
	}
	return ioutil.WriteFile(netrcPath(), body, 0600)
}

// exists returns whether the given file or directory exists or not
func fileExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

func must(err error) {
	if err != nil {
		if herror, ok := err.(heroku.Error); ok {
			if herror.Id == "unauthorized" {
				printError(err.Error() + " Log in with `hk login`.")
			}
		}
		printError(err.Error())
	}
}

func printError(message string, args ...interface{}) {
	log.Fatal(colorizeMessage("red", "error:", message, args...))
}

func printWarning(message string, args ...interface{}) {
	log.Fatal(colorizeMessage("yellow", "warning:", message, args...))
}

func colorizeMessage(color, prefix, message string, args ...interface{}) string {
	prefResult := ""
	if prefix != "" {
		prefResult = ansi.Color(prefix, color+"+b") + " " + ansi.ColorCode("reset")
	}
	return prefResult + ansi.Color(fmt.Sprintf(message, args...), color) + ansi.ColorCode("reset")
}

func listRec(w io.Writer, a ...interface{}) {
	for i, x := range a {
		fmt.Fprint(w, x)
		if i+1 < len(a) {
			w.Write([]byte{'\t'})
		} else {
			w.Write([]byte{'\n'})
		}
	}
}

type prettyTime struct {
	time.Time
}

func (s prettyTime) String() string {
	if time.Now().Sub(s.Time) < 12*30*24*time.Hour {
		return s.Local().Format("Jan _2 15:04")
	}
	return s.Local().Format("Jan _2  2006")
}

type prettyDuration struct {
	time.Duration
}

func (a prettyDuration) String() string {
	switch d := a.Duration; {
	case d > 2*24*time.Hour:
		return a.Unit(24*time.Hour, "d")
	case d > 2*time.Hour:
		return a.Unit(time.Hour, "h")
	case d > 2*time.Minute:
		return a.Unit(time.Minute, "m")
	}
	return a.Unit(time.Second, "s")
}

func (a prettyDuration) Unit(u time.Duration, s string) string {
	return fmt.Sprintf("%2d", roundDur(a.Duration, u)) + s
}

func roundDur(d, k time.Duration) int {
	return int((d + k/2 - 1) / k)
}

func abbrev(s string, n int) string {
	if len(s) > n {
		return s[:n-1] + "…"
	}
	return s
}

func ensurePrefix(val, prefix string) string {
	if !strings.HasPrefix(val, prefix) {
		return prefix + val
	}
	return val
}

func openURL(url string) error {
	var command string
	var args []string
	switch runtime.GOOS {
	case "darwin":
		command = "open"
		args = []string{command, url}
	case "windows":
		command = "cmd"
		args = []string{"/c", "start " + strings.Replace(url, "&", "^&", -1)}
	default:
		if _, err := exec.LookPath("xdg-open"); err != nil {
			log.Println("xdg-open is required to open web pages on " + runtime.GOOS)
			os.Exit(2)
		}
		command = "xdg-open"
		args = []string{command, url}
	}
	return runCommand(command, args, os.Environ())
}

func runCommand(command string, args, env []string) error {
	if runtime.GOOS != "windows" {
		p, err := exec.LookPath(command)
		if err != nil {
			log.Printf("Error finding path to %q: %s\n", command, err)
			os.Exit(2)
		}
		command = p
	}
	return sysExec(command, args, env)
}
<commit_msg>no idea why that was Fatal instead of Println<commit_after>package main

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/url"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"time"

	"github.com/bgentry/go-netrc/netrc"
	"github.com/bgentry/heroku-go"
	"github.com/mgutz/ansi"
)

var nrc *netrc.Netrc

// user.Current() requires cgo and thus doesn't work with cross-compiling.
// The following is an alternative that matches how the Heroku Toolbelt
// works, though per @fdr it may not be correct for all cases (when users have
// modified their home dir).
//
// homePath() is defined in the platform-specific source files unix.go and
// windows.go.
//
// http://stackoverflow.com/questions/7922270/obtain-users-home-directory
func hkHome() string {
	return filepath.Join(homePath(), ".hk")
}

func netrcPath() string {
	if s := os.Getenv("NETRC_PATH"); s != "" {
		return s
	}

	return filepath.Join(homePath(), netrcFilename)
}

func loadNetrc() {
	if nrc == nil {
		var err error
		if nrc, err = netrc.ParseFile(netrcPath()); err != nil {
			if os.IsNotExist(err) {
				return
			}
			printError("loading netrc: " + err.Error())
		}
	}
}

func getCreds(u string) (user, pass string) {
	loadNetrc()
	if nrc == nil {
		return "", ""
	}

	apiURL, err := url.Parse(u)
	if err != nil {
		printError("invalid API URL: %s", err)
	}
	if apiURL.Host == "" {
		printError("missing API host: %s", u)
	}
	if apiURL.User != nil {
		pw, _ := apiURL.User.Password()
		return apiURL.User.Username(), pw
	}

	m := nrc.FindMachine(apiURL.Host)
	if m == nil {
		return "", ""
	}
	return m.Login, m.Password
}

func saveCreds(host, user, pass string) error {
	loadNetrc()
	m := nrc.FindMachine(host)
	if m == nil || m.IsDefault() {
		m = nrc.NewMachine(host, user, pass, "")
	}
	m.UpdateLogin(user)
	m.UpdatePassword(pass)

	body, err := nrc.MarshalText()
	if err != nil {
		return err
	}
	return ioutil.WriteFile(netrcPath(), body, 0600)
}

func removeCreds(host string) error {
	loadNetrc()
	nrc.RemoveMachine(host)

	body, err := nrc.MarshalText()
	if err != nil {
		return err
	}
	return ioutil.WriteFile(netrcPath(), body, 0600)
}

// exists returns whether the given file or directory exists or not
func fileExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

func must(err error) {
	if err != nil {
		if herror, ok := err.(heroku.Error); ok {
			if herror.Id == "unauthorized" {
				printError(err.Error() + " Log in with `hk login`.")
			}
		}
		printError(err.Error())
	}
}

func printError(message string, args ...interface{}) {
	log.Fatal(colorizeMessage("red", "error:", message, args...))
}

func printWarning(message string, args ...interface{}) {
	log.Println(colorizeMessage("yellow", "warning:", message, args...))
}

func colorizeMessage(color, prefix, message string, args ...interface{}) string {
	prefResult := ""
	if prefix != "" {
		prefResult = ansi.Color(prefix, color+"+b") + " " + ansi.ColorCode("reset")
	}
	return prefResult + ansi.Color(fmt.Sprintf(message, args...), color) + ansi.ColorCode("reset")
}

func listRec(w io.Writer, a ...interface{}) {
	for i, x := range a {
		fmt.Fprint(w, x)
		if i+1 < len(a) {
			w.Write([]byte{'\t'})
		} else {
			w.Write([]byte{'\n'})
		}
	}
}

type prettyTime struct {
	time.Time
}

func (s prettyTime) String() string {
	if time.Now().Sub(s.Time) < 12*30*24*time.Hour {
		return s.Local().Format("Jan _2 15:04")
	}
	return s.Local().Format("Jan _2  2006")
}

type prettyDuration struct {
	time.Duration
}

func (a prettyDuration) String() string {
	switch d := a.Duration; {
	case d > 2*24*time.Hour:
		return a.Unit(24*time.Hour, "d")
	case d > 2*time.Hour:
		return a.Unit(time.Hour, "h")
	case d > 2*time.Minute:
		return a.Unit(time.Minute, "m")
	}
	return a.Unit(time.Second, "s")
}

func (a prettyDuration) Unit(u time.Duration, s string) string {
	return fmt.Sprintf("%2d", roundDur(a.Duration, u)) + s
}

func roundDur(d, k time.Duration) int {
	return int((d + k/2 - 1) / k)
}

func abbrev(s string, n int) string {
	if len(s) > n {
		return s[:n-1] + "…"
	}
	return s
}

func ensurePrefix(val, prefix string) string {
	if !strings.HasPrefix(val, prefix) {
		return prefix + val
	}
	return val
}

func openURL(url string) error {
	var command string
	var args []string
	switch runtime.GOOS {
	case "darwin":
		command = "open"
		args = []string{command, url}
	case "windows":
		command = "cmd"
		args = []string{"/c", "start " + strings.Replace(url, "&", "^&", -1)}
	default:
		if _, err := exec.LookPath("xdg-open"); err != nil {
			log.Println("xdg-open is required to open web pages on " + runtime.GOOS)
			os.Exit(2)
		}
		command = "xdg-open"
		args = []string{command, url}
	}
	return runCommand(command, args, os.Environ())
}

func runCommand(command string, args, env []string) error {
	if runtime.GOOS != "windows" {
		p, err := exec.LookPath(command)
		if err != nil {
			log.Printf("Error finding path to %q: %s\n", command, err)
			os.Exit(2)
		}
		command = p
	}
	return sysExec(command, args, env)
}
<|endoftext|>


<commit_before>package pyraconv

import (
	"bytes"
	"encoding/gob"
	"fmt"
	"math"
	"strconv"
	"time"

	// "code.google.com/p/go.text/encoding"
	// "code.google.com/p/go.text/encoding/charmap"
	// "code.google.com/p/go.text/encoding/japanese"
	// "code.google.com/p/go.text/encoding/korean"
	// "code.google.com/p/go.text/encoding/simplifiedchinese"
	// "code.google.com/p/go.text/encoding/traditionalchinese"
)

// ToInterfaceArray converts interface{} to []interface{} and never returns nil
func ToInterfaceArray(i1 interface{}) []interface{} {
	if i1 == nil {
		return []interface{}{}
	}
	switch i2 := i1.(type) {
	default:
		return []interface{}{}
	case []interface{}:
		return i2
	}
	return []interface{}{}
}

// ToInterfaceMap converts interface{} to map[string]interface{} and never returns nil
func ToInterfaceMap(i1 interface{}) map[string]interface{} {
	if i1 == nil {
		return map[string]interface{}{}
	}
	switch i2 := i1.(type) {
	case map[string]interface{}:
		return i2
	default:
		return map[string]interface{}{}
	}
	return map[string]interface{}{}
}

// ToStringArray converts interface{} to []string and never returns nil
func ToStringArray(i1 interface{}) []string {
	if i1 == nil {
		return []string{}
	}
	switch i2 := i1.(type) {
	default:
		return []string{fmt.Sprint(i2)}
	case []string:
		return i2
	case []interface{}:
		var ss []string
		for _, i3 := range i2 {
			ss = append(ss, ToString(i3))
		}
		return ss
	}
	return []string{}
}

// ToStringMap converts interface{} to map[string]string and never returns nil
func ToStringMap(i1 interface{}) map[string]string {
	if i1 == nil {
		return map[string]string{}
	}
	switch i2 := i1.(type) {
	case map[string]interface{}:
		m1 := map[string]string{}
		for k, v := range m1 {
			m1[k] = ToString(v)
		}
		return m1
	case map[string]string:
		return i2

	default:
		return map[string]string{}
	}
	return map[string]string{}
}

// ToString converts interface{} to string
func ToString(i1 interface{}) string {
	if i1 == nil {
		return ""
	}
	switch i2 := i1.(type) {
	default:
		return fmt.Sprint(i2)
	case bool:
		if i2 {
			return "true"
		} else {
			return "false"
		}
	case string:
		return i2
	case *bool:
		if i2 == nil {
			return ""
		}
		if *i2 {
			return "true"
		} else {
			return "false"
		}
	case *string:
		if i2 == nil {
			return ""
		}
		return *i2
	}
	return ""
}

// ToInt64 converts interface{} to int64
func ToInt64(i1 interface{}) int64 {
	if i1 == nil {
		return 0
	}
	switch i2 := i1.(type) {
	default:
		i3, _ := strconv.ParseInt(ToString(i2), 10, 64)
		return i3
	case int64:
		return i2
	case float64:
		return int64(i2)
	case float32:
		return int64(i2)
	case uint64:
		return int64(i2)
	case int:
		return int64(i2)
	case uint:
		return int64(i2)
	case bool:
		if i2 {
			return 1
		} else {
			return 0
		}
	case *bool:
		if i2 == nil {
			return 0
		}
		if *i2 {
			return 1
		} else {
			return 0
		}
	}
	return 0
}

// ToBool converts interface{} to bool
func ToBool(i1 interface{}) bool {
	if i1 == nil {
		return false
	}
	switch i2 := i1.(type) {
	default:
		return false
	case bool:
		return i2
	case string:
		return i2 == "true"
	case int:
		return i2 != 0
	case *bool:
		if i2 == nil {
			return false
		}
		return *i2
	case *string:
		if i2 == nil {
			return false
		}
		return *i2 == "true"
	case *int:
		if i2 == nil {
			return false
		}
		return *i2 != 0
	}
	return false
}

// CloneObject creates copy of object using GOB.
func CloneObject(a, b interface{}) {
	buff := new(bytes.Buffer)
	enc := gob.NewEncoder(buff)
	dec := gob.NewDecoder(buff)
	enc.Encode(a)
	dec.Decode(b)
}

// func ShoterRunes(s1 string, n int) string {
// 	r1 := []rune(s1)
// 	if len(r1) > n {
// 		r1 = r1[0:n]
// 	}
// 	s2 := string(r1)
// 	return s2
// }

// func SecureWebId(s1 string) (string, bool) {
// 	for _, c := range s1 {
// 		if !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) {
// 			return "", false
// 		}
// 	}
// 	return s1, true
// }
// func DebugObject(id string, o1 interface{}) {
// 	b, _ := json.Marshal(o1)
// 	log.Println(id, string(b))
// }

// func CharsetGetEncding(charset string) encoding.Encoding {
// 	if charset == "" {
// 		return nil
// 	}
// 	charset = strings.ToLower(charset)
// 	charset = strings.Replace(charset, "-", "", -1)
// 	if charset == "utf8" {
// 		return nil
// 	}
// 	if charset == "koi8" {
// 		return charmap.KOI8R
// 	}
// 	if charset == "koi8r" {
// 		return charmap.KOI8R
// 	}
// 	if charset == "koi8u" {
// 		return charmap.KOI8U
// 	}

// 	if charset == "iso88591" {
// 		return charmap.Windows1252
// 	}

// 	if charset == "iso88592" {
// 		return charmap.ISO8859_2
// 	}
// 	if charset == "iso88593" {
// 		return charmap.ISO8859_3
// 	}
// 	if charset == "iso88594" {
// 		return charmap.ISO8859_4
// 	}
// 	if charset == "iso88595" {
// 		return charmap.ISO8859_5
// 	}
// 	if charset == "iso88596" {
// 		return charmap.ISO8859_6
// 	}
// 	if charset == "iso88597" {
// 		return charmap.ISO8859_7
// 	}
// 	if charset == "iso88598" {
// 		return charmap.ISO8859_8
// 	}
// 	// if charset == "iso88599" {return charmap.ISO8859_9}
// 	if charset == "iso885910" {
// 		return charmap.ISO8859_10
// 	}
// 	// if charset == "iso885911" {return charmap.ISO8859_11}
// 	// if charset == "iso885912" {return charmap.ISO8859_12}
// 	if charset == "iso885913" {
// 		return charmap.ISO8859_13
// 	}
// 	if charset == "iso885914" {
// 		return charmap.ISO8859_14
// 	}
// 	if charset == "iso885915" {
// 		return charmap.ISO8859_15
// 	}
// 	if charset == "iso885916" {
// 		return charmap.ISO8859_16
// 	}

// 	if charset == "windows1250" {
// 		return charmap.Windows1250
// 	}
// 	if charset == "windows1251" {
// 		return charmap.Windows1251
// 	}
// 	if charset == "windows1252" {
// 		return charmap.Windows1252
// 	}
// 	if charset == "windows1253" {
// 		return charmap.Windows1253
// 	}
// 	if charset == "windows1254" {
// 		return charmap.Windows1254
// 	}
// 	if charset == "windows1255" {
// 		return charmap.Windows1255
// 	}
// 	if charset == "windows1256" {
// 		return charmap.Windows1256
// 	}
// 	if charset == "windows1257" {
// 		return charmap.Windows1257
// 	}
// 	if charset == "windows1258" {
// 		return charmap.Windows1258
// 	}
// 	if charset == "windows874" {
// 		return charmap.Windows874
// 	}

// 	if charset == "eucjp" {
// 		return japanese.EUCJP
// 	}
// 	if charset == "iso2022jp" {
// 		return japanese.ISO2022JP
// 	}
// 	if charset == "shiftjis" {
// 		return japanese.ShiftJIS
// 	}

// 	if charset == "euckr" {
// 		return korean.EUCKR
// 	}

// 	if charset == "gb18030" {
// 		return simplifiedchinese.GB18030
// 	}
// 	if charset == "gbk" {
// 		return simplifiedchinese.GBK
// 	}
// 	if charset == "hzgb2312" {
// 		return simplifiedchinese.HZGB2312
// 	}

// 	if charset == "big5" {
// 		return traditionalchinese.Big5
// 	}

// 	return nil

// }
func TimeSince(t1 time.Time) (since string) {
	now := time.Now()
	d1 := time.Since(t1)
	if d1.Hours() > 24.0 {
		if t1.Year() == now.Year() {
			if t1.Month() == now.Month() {
				if t1.Day() == now.Day() {
					since = t1.Format("15:04")
				} else {
					since = t1.Format("02-Jan")
				}
			} else {
				since = t1.Format("02-Jan")
			}
		} else {
			since = t1.Format("02-Jan-2006")
		}
	} else {
		// since = d1.String()
		hours := int(d1.Hours())
		minutes := int(d1.Minutes() - float64(60.0*hours))
		since = fmt.Sprintf("%02d:%02d", hours, minutes)
	}
	return since
}

func MovingExpAvg(value float64, oldValue float64, ftime float64, time float64) float64 {
	alpha := 1. - math.Exp(-ftime/time)
	r := alpha*value + (1.-alpha)*oldValue
	return r
}
<commit_msg>added json.Number support<commit_after>package pyraconv

import (
	"bytes"
	"encoding/gob"
	"encoding/json"
	"fmt"
	"math"
	"strconv"
	"time"

	// "code.google.com/p/go.text/encoding"
	// "code.google.com/p/go.text/encoding/charmap"
	// "code.google.com/p/go.text/encoding/japanese"
	// "code.google.com/p/go.text/encoding/korean"
	// "code.google.com/p/go.text/encoding/simplifiedchinese"
	// "code.google.com/p/go.text/encoding/traditionalchinese"
)

// ToInterfaceArray converts interface{} to []interface{} and never returns nil
func ToInterfaceArray(i1 interface{}) []interface{} {
	if i1 == nil {
		return []interface{}{}
	}
	switch i2 := i1.(type) {
	default:
		return []interface{}{}
	case []interface{}:
		return i2
	}
	return []interface{}{}
}

// ToInterfaceMap converts interface{} to map[string]interface{} and never returns nil
func ToInterfaceMap(i1 interface{}) map[string]interface{} {
	if i1 == nil {
		return map[string]interface{}{}
	}
	switch i2 := i1.(type) {
	case map[string]interface{}:
		return i2
	default:
		return map[string]interface{}{}
	}
	return map[string]interface{}{}
}

// ToStringArray converts interface{} to []string and never returns nil
func ToStringArray(i1 interface{}) []string {
	if i1 == nil {
		return []string{}
	}
	switch i2 := i1.(type) {
	default:
		return []string{fmt.Sprint(i2)}
	case []string:
		return i2
	case []interface{}:
		var ss []string
		for _, i3 := range i2 {
			ss = append(ss, ToString(i3))
		}
		return ss
	}
	return []string{}
}

// ToStringMap converts interface{} to map[string]string and never returns nil
func ToStringMap(i1 interface{}) map[string]string {
	if i1 == nil {
		return map[string]string{}
	}
	switch i2 := i1.(type) {
	case map[string]interface{}:
		m1 := map[string]string{}
		for k, v := range m1 {
			m1[k] = ToString(v)
		}
		return m1
	case map[string]string:
		return i2

	default:
		return map[string]string{}
	}
	return map[string]string{}
}

// ToString converts interface{} to string
func ToString(i1 interface{}) string {
	if i1 == nil {
		return ""
	}
	switch i2 := i1.(type) {
	default:
		return fmt.Sprint(i2)
	case bool:
		if i2 {
			return "true"
		} else {
			return "false"
		}
	case string:
		return i2
	case *bool:
		if i2 == nil {
			return ""
		}
		if *i2 {
			return "true"
		} else {
			return "false"
		}
	case *string:
		if i2 == nil {
			return ""
		}
		return *i2
	case *json.Number:
		return i2.String()
	case json.Number:
		return i2.String()
	}
	return ""
}

// ToInt64 converts interface{} to int64
func ToInt64(i1 interface{}) int64 {
	if i1 == nil {
		return 0
	}
	switch i2 := i1.(type) {
	default:
		i3, _ := strconv.ParseInt(ToString(i2), 10, 64)
		return i3
	case *json.Number:
		return i2.Int64()
	case json.Number:
		return i2.Int64()
	case int64:
		return i2
	case float64:
		return int64(i2)
	case float32:
		return int64(i2)
	case uint64:
		return int64(i2)
	case int:
		return int64(i2)
	case uint:
		return int64(i2)
	case bool:
		if i2 {
			return 1
		} else {
			return 0
		}
	case *bool:
		if i2 == nil {
			return 0
		}
		if *i2 {
			return 1
		} else {
			return 0
		}
	}
	return 0
}

// ToBool converts interface{} to bool
func ToBool(i1 interface{}) bool {
	if i1 == nil {
		return false
	}
	switch i2 := i1.(type) {
	default:
		return false
	case bool:
		return i2
	case string:
		return i2 == "true"
	case int:
		return i2 != 0
	case *bool:
		if i2 == nil {
			return false
		}
		return *i2
	case *string:
		if i2 == nil {
			return false
		}
		return *i2 == "true"
	case *int:
		if i2 == nil {
			return false
		}
		return *i2 != 0
	}
	return false
}

// CloneObject creates copy of object using GOB.
func CloneObject(a, b interface{}) {
	buff := new(bytes.Buffer)
	enc := gob.NewEncoder(buff)
	dec := gob.NewDecoder(buff)
	enc.Encode(a)
	dec.Decode(b)
}

// func ShoterRunes(s1 string, n int) string {
// 	r1 := []rune(s1)
// 	if len(r1) > n {
// 		r1 = r1[0:n]
// 	}
// 	s2 := string(r1)
// 	return s2
// }

// func SecureWebId(s1 string) (string, bool) {
// 	for _, c := range s1 {
// 		if !((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) {
// 			return "", false
// 		}
// 	}
// 	return s1, true
// }
// func DebugObject(id string, o1 interface{}) {
// 	b, _ := json.Marshal(o1)
// 	log.Println(id, string(b))
// }

// func CharsetGetEncding(charset string) encoding.Encoding {
// 	if charset == "" {
// 		return nil
// 	}
// 	charset = strings.ToLower(charset)
// 	charset = strings.Replace(charset, "-", "", -1)
// 	if charset == "utf8" {
// 		return nil
// 	}
// 	if charset == "koi8" {
// 		return charmap.KOI8R
// 	}
// 	if charset == "koi8r" {
// 		return charmap.KOI8R
// 	}
// 	if charset == "koi8u" {
// 		return charmap.KOI8U
// 	}

// 	if charset == "iso88591" {
// 		return charmap.Windows1252
// 	}

// 	if charset == "iso88592" {
// 		return charmap.ISO8859_2
// 	}
// 	if charset == "iso88593" {
// 		return charmap.ISO8859_3
// 	}
// 	if charset == "iso88594" {
// 		return charmap.ISO8859_4
// 	}
// 	if charset == "iso88595" {
// 		return charmap.ISO8859_5
// 	}
// 	if charset == "iso88596" {
// 		return charmap.ISO8859_6
// 	}
// 	if charset == "iso88597" {
// 		return charmap.ISO8859_7
// 	}
// 	if charset == "iso88598" {
// 		return charmap.ISO8859_8
// 	}
// 	// if charset == "iso88599" {return charmap.ISO8859_9}
// 	if charset == "iso885910" {
// 		return charmap.ISO8859_10
// 	}
// 	// if charset == "iso885911" {return charmap.ISO8859_11}
// 	// if charset == "iso885912" {return charmap.ISO8859_12}
// 	if charset == "iso885913" {
// 		return charmap.ISO8859_13
// 	}
// 	if charset == "iso885914" {
// 		return charmap.ISO8859_14
// 	}
// 	if charset == "iso885915" {
// 		return charmap.ISO8859_15
// 	}
// 	if charset == "iso885916" {
// 		return charmap.ISO8859_16
// 	}

// 	if charset == "windows1250" {
// 		return charmap.Windows1250
// 	}
// 	if charset == "windows1251" {
// 		return charmap.Windows1251
// 	}
// 	if charset == "windows1252" {
// 		return charmap.Windows1252
// 	}
// 	if charset == "windows1253" {
// 		return charmap.Windows1253
// 	}
// 	if charset == "windows1254" {
// 		return charmap.Windows1254
// 	}
// 	if charset == "windows1255" {
// 		return charmap.Windows1255
// 	}
// 	if charset == "windows1256" {
// 		return charmap.Windows1256
// 	}
// 	if charset == "windows1257" {
// 		return charmap.Windows1257
// 	}
// 	if charset == "windows1258" {
// 		return charmap.Windows1258
// 	}
// 	if charset == "windows874" {
// 		return charmap.Windows874
// 	}

// 	if charset == "eucjp" {
// 		return japanese.EUCJP
// 	}
// 	if charset == "iso2022jp" {
// 		return japanese.ISO2022JP
// 	}
// 	if charset == "shiftjis" {
// 		return japanese.ShiftJIS
// 	}

// 	if charset == "euckr" {
// 		return korean.EUCKR
// 	}

// 	if charset == "gb18030" {
// 		return simplifiedchinese.GB18030
// 	}
// 	if charset == "gbk" {
// 		return simplifiedchinese.GBK
// 	}
// 	if charset == "hzgb2312" {
// 		return simplifiedchinese.HZGB2312
// 	}

// 	if charset == "big5" {
// 		return traditionalchinese.Big5
// 	}

// 	return nil

// }
func TimeSince(t1 time.Time) (since string) {
	now := time.Now()
	d1 := time.Since(t1)
	if d1.Hours() > 24.0 {
		if t1.Year() == now.Year() {
			if t1.Month() == now.Month() {
				if t1.Day() == now.Day() {
					since = t1.Format("15:04")
				} else {
					since = t1.Format("02-Jan")
				}
			} else {
				since = t1.Format("02-Jan")
			}
		} else {
			since = t1.Format("02-Jan-2006")
		}
	} else {
		// since = d1.String()
		hours := int(d1.Hours())
		minutes := int(d1.Minutes() - float64(60.0*hours))
		since = fmt.Sprintf("%02d:%02d", hours, minutes)
	}
	return since
}

func MovingExpAvg(value float64, oldValue float64, ftime float64, time float64) float64 {
	alpha := 1. - math.Exp(-ftime/time)
	r := alpha*value + (1.-alpha)*oldValue
	return r
}
<|endoftext|>


<commit_before>package main

import (
	"os/exec"
	"strings"
)

// execute commandLine
func parseCommand(commandLine string) {
	args := strings.Fields(commandLine)
	cmd := exec.Command(args[0])
	cmd.Args = args
	cmd.Run()
}

// compare two []byte
func testEq(a, b []byte) bool {
	if len(a) != len(b) {
		return false
	}

	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}

	return true
}

func insertRule(slice []*RoutingRule, index int, value *RoutingRule) []*RoutingRule {
	newSlice := make([]*RoutingRule, len(slice), cap(slice)+1)
	copy(newSlice, slice)
	slice = newSlice[0 : len(slice)+1]
	copy(slice[index+1:], slice[index:])
	slice[index] = value
	return slice
}
<commit_msg>remove unused functions<commit_after>package main

import (
	"os/exec"
	"strings"
)

// execute commandLine
func parseCommand(commandLine string) {
	args := strings.Fields(commandLine)
	cmd := exec.Command(args[0])
	cmd.Args = args
	cmd.Run()
}
<|endoftext|>


<commit_before>// Copyright 2017 Google 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 model

import (
	"reflect"
	"strings"
	"testing"

	"github.com/google/shenzhen-go/model/parts"
	"github.com/google/shenzhen-go/model/pin"
)

func TestLoadJSON(t *testing.T) {
	json := strings.NewReader(`{
	"nodes": {
		"foo": {
			"part_type": "Code",
			"part": {
				"pins": [
					{
						"name": "output",
						"type": "int",
						"dir": "out"
					}
				]
			},
			"connections": {
				"output": "baz"
			}
		},
		"bar": {
			"part_type": "Code",
			"part": {
				"pins": [
					{
						"name": "input",
						"type": "int",
						"dir": "in"
					}
				]
			},
			"connections": {
				"input": "baz"
			}
		}
	},
	"channels": {
		"baz": {
			"type": "int"
		}
	}
}`)
	got, err := LoadJSON(json, "filePath", "urlPath")
	if err != nil {
		t.Fatalf("LoadJSON() error = %v", err)
	}

	if got, want := got.FilePath, "filePath"; got != want {
		t.Errorf("LoadJSON().FilePath = %q, want %q", got, want)
	}
	if got, want := got.URLPath, "urlPath"; got != want {
		t.Errorf("LoadJSON().URLPath = %q, want %q", got, want)
	}

	wantNodes := map[string]*Node{
		"foo": {
			Name:         "foo",
			Multiplicity: 1,
			Part: parts.NewCode(nil, "", "", "", []pin.Definition{
				{
					Name:      "output",
					Direction: pin.Output,
					Type:      "int",
				},
			}),
			Connections: map[string]string{
				"output": "baz",
			},
		},
		"bar": {
			Name:         "bar",
			Multiplicity: 1,
			Part: parts.NewCode(nil, "", "", "", []pin.Definition{
				{
					Name:      "input",
					Direction: pin.Input,
					Type:      "int",
				},
			}),
			Connections: map[string]string{
				"input": "baz",
			},
		},
	}
	if got, want := got.Nodes, wantNodes; !reflect.DeepEqual(got, want) {
		t.Errorf("LoadJSON().Nodes = %#v, want %#v", got, want)
	}
	wantChans := map[string]*Channel{
		"baz": {
			Name: "baz",
			Type: "int",
		},
	}
	if got, want := got.Channels, wantChans; !reflect.DeepEqual(got, want) {
		t.Errorf("LoadJSON().Channels = %#v, want %#v", got, want)
	}
}
<commit_msg>Improve LoadJSON a little more<commit_after>// Copyright 2017 Google 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 model

import (
	"reflect"
	"strings"
	"testing"

	"github.com/google/shenzhen-go/model/parts"
	"github.com/google/shenzhen-go/model/pin"
)

func TestLoadJSON(t *testing.T) {
	json := strings.NewReader(`{
	"nodes": {
		"foo": {
			"part_type": "Code",
			"part": {
				"pins": [
					{
						"name": "output",
						"type": "int",
						"dir": "out"
					}
				]
			},
			"connections": {
				"output": "baz",
				"ignored": "ignored"
			}
		},
		"bar": {
			"part_type": "Code",
			"part": {
				"pins": [
					{
						"name": "input",
						"type": "int",
						"dir": "in"
					}
				]
			},
			"connections": {
				"input": "baz",
				"ignored": "ignored"
			}
		}
	},
	"channels": {
		"baz": {
			"type": "int"
		}
	}
}`)
	got, err := LoadJSON(json, "filePath", "urlPath")
	if err != nil {
		t.Fatalf("LoadJSON() error = %v", err)
	}

	if got, want := got.FilePath, "filePath"; got != want {
		t.Errorf("LoadJSON().FilePath = %q, want %q", got, want)
	}
	if got, want := got.URLPath, "urlPath"; got != want {
		t.Errorf("LoadJSON().URLPath = %q, want %q", got, want)
	}

	wantNodes := map[string]*Node{
		"foo": {
			Name:         "foo",
			Multiplicity: 1,
			Part: parts.NewCode(nil, "", "", "", []pin.Definition{
				{
					Name:      "output",
					Direction: pin.Output,
					Type:      "int",
				},
			}),
			Connections: map[string]string{
				"output": "baz",
			},
		},
		"bar": {
			Name:         "bar",
			Multiplicity: 1,
			Part: parts.NewCode(nil, "", "", "", []pin.Definition{
				{
					Name:      "input",
					Direction: pin.Input,
					Type:      "int",
				},
			}),
			Connections: map[string]string{
				"input": "baz",
			},
		},
	}
	if got, want := got.Nodes, wantNodes; !reflect.DeepEqual(got, want) {
		t.Errorf("LoadJSON().Nodes = %#v, want %#v", got, want)
	}
	wantChans := map[string]*Channel{
		"baz": {
			Name: "baz",
			Type: "int",
		},
	}
	if got, want := got.Channels, wantChans; !reflect.DeepEqual(got, want) {
		t.Errorf("LoadJSON().Channels = %#v, want %#v", got, want)
	}
}
<|endoftext|>