<commit_before>package types

import (
	"bytes"
	"compress/gzip"
	"database/sql/driver"
	"encoding/json"
	"errors"

	"io/ioutil"
)

// GzippedText is a []byte which transparently gzips data being submitted to
// a database and ungzips data being Scanned from a database.
type GzippedText []byte

// Value implements the driver.Valuer interface, gzipping the raw value of
// this GzippedText.
func (g GzippedText) Value() (driver.Value, error) {
	b := make([]byte, 0, len(g))
	buf := bytes.NewBuffer(b)
	w := gzip.NewWriter(buf)
	w.Write(g)
	w.Close()
	return buf.Bytes(), nil

}

// Scan implements the sql.Scanner interface, ungzipping the value coming off
// the wire and storing the raw result in the GzippedText.
func (g *GzippedText) Scan(src interface{}) error {
	var source []byte
	switch src.(type) {
	case string:
		source = []byte(src.(string))
	case []byte:
		source = src.([]byte)
	default:
		return errors.New("Incompatible type for GzippedText")
	}
	reader, err := gzip.NewReader(bytes.NewReader(source))
	if err != nil {
		return err
	}
	defer reader.Close()
	b, err := ioutil.ReadAll(reader)
	if err != nil {
		return err
	}
	*g = GzippedText(b)
	return nil
}

// JSONText is a json.RawMessage, which is a []byte underneath.
// Value() validates the json format in the source, and returns an error if
// the json is not valid.  Scan does no validation.  JSONText additionally
// implements `Unmarshal`, which unmarshals the json within to an interface{}
type JSONText json.RawMessage

// MarshalJSON returns j as the JSON encoding of j.
func (j JSONText) MarshalJSON() ([]byte, error) {
	return j, nil
}

// UnmarshalJSON sets *j to a copy of data
func (j *JSONText) UnmarshalJSON(data []byte) error {
	if j == nil {
		return errors.New("JSONText: UnmarshalJSON on nil pointer")
	}
	*j = append((*j)[0:0], data...)
	return nil

}

// Value returns j as a value.  This does a validating unmarshal into another
// RawMessage.  If j is invalid json, it returns an error.
func (j JSONText) Value() (driver.Value, error) {
	var m json.RawMessage
	var err = j.Unmarshal(&m)
	if err != nil {
		return []byte{}, err
	}
	return []byte(j), nil
}

// Scan stores the src in *j.  No validation is done.
func (j *JSONText) Scan(src interface{}) error {
	var source []byte
	switch src.(type) {
	case string:
		source = []byte(src.(string))
	case []byte:
		source = src.([]byte)
	default:
		return errors.New("Incompatible type for JSONText")
	}
	*j = JSONText(append((*j)[0:0], source...))
	return nil
}

// Unmarshal unmarshal's the json in j to v, as in json.Unmarshal.
func (j *JSONText) Unmarshal(v interface{}) error {
	return json.Unmarshal([]byte(*j), v)
}

// Pretty printing for JSONText types
func (j JSONText) String() string {
	return string(j)
}

// BitBool is an implementation of a bool for the MySQL type BIT(1).
// This type allows you to avoid wasting an entire byte for MySQL's boolean type TINYINT.
type BitBool bool

// Value implements the driver.Valuer interface,
// and turns the BitBool into a bitfield (BIT(1)) for MySQL storage.
func (b BitBool) Value() (driver.Value, error) {
	if b {
		return []byte{1}, nil
	} else {
		return []byte{0}, nil
	}
}

// Scan implements the sql.Scanner interface,
// and turns the bitfield incoming from MySQL into a BitBool
func (b *BitBool) Scan(src interface{}) error {
	v, ok := src.([]byte)
	if !ok {
		return errors.New("bad []byte type assertion")
	}
	*b = v[0] == 1
	return nil
}
<commit_msg>remove dangling else from #254<commit_after>package types

import (
	"bytes"
	"compress/gzip"
	"database/sql/driver"
	"encoding/json"
	"errors"

	"io/ioutil"
)

// GzippedText is a []byte which transparently gzips data being submitted to
// a database and ungzips data being Scanned from a database.
type GzippedText []byte

// Value implements the driver.Valuer interface, gzipping the raw value of
// this GzippedText.
func (g GzippedText) Value() (driver.Value, error) {
	b := make([]byte, 0, len(g))
	buf := bytes.NewBuffer(b)
	w := gzip.NewWriter(buf)
	w.Write(g)
	w.Close()
	return buf.Bytes(), nil

}

// Scan implements the sql.Scanner interface, ungzipping the value coming off
// the wire and storing the raw result in the GzippedText.
func (g *GzippedText) Scan(src interface{}) error {
	var source []byte
	switch src.(type) {
	case string:
		source = []byte(src.(string))
	case []byte:
		source = src.([]byte)
	default:
		return errors.New("Incompatible type for GzippedText")
	}
	reader, err := gzip.NewReader(bytes.NewReader(source))
	if err != nil {
		return err
	}
	defer reader.Close()
	b, err := ioutil.ReadAll(reader)
	if err != nil {
		return err
	}
	*g = GzippedText(b)
	return nil
}

// JSONText is a json.RawMessage, which is a []byte underneath.
// Value() validates the json format in the source, and returns an error if
// the json is not valid.  Scan does no validation.  JSONText additionally
// implements `Unmarshal`, which unmarshals the json within to an interface{}
type JSONText json.RawMessage

// MarshalJSON returns j as the JSON encoding of j.
func (j JSONText) MarshalJSON() ([]byte, error) {
	return j, nil
}

// UnmarshalJSON sets *j to a copy of data
func (j *JSONText) UnmarshalJSON(data []byte) error {
	if j == nil {
		return errors.New("JSONText: UnmarshalJSON on nil pointer")
	}
	*j = append((*j)[0:0], data...)
	return nil

}

// Value returns j as a value.  This does a validating unmarshal into another
// RawMessage.  If j is invalid json, it returns an error.
func (j JSONText) Value() (driver.Value, error) {
	var m json.RawMessage
	var err = j.Unmarshal(&m)
	if err != nil {
		return []byte{}, err
	}
	return []byte(j), nil
}

// Scan stores the src in *j.  No validation is done.
func (j *JSONText) Scan(src interface{}) error {
	var source []byte
	switch src.(type) {
	case string:
		source = []byte(src.(string))
	case []byte:
		source = src.([]byte)
	default:
		return errors.New("Incompatible type for JSONText")
	}
	*j = JSONText(append((*j)[0:0], source...))
	return nil
}

// Unmarshal unmarshal's the json in j to v, as in json.Unmarshal.
func (j *JSONText) Unmarshal(v interface{}) error {
	return json.Unmarshal([]byte(*j), v)
}

// Pretty printing for JSONText types
func (j JSONText) String() string {
	return string(j)
}

// BitBool is an implementation of a bool for the MySQL type BIT(1).
// This type allows you to avoid wasting an entire byte for MySQL's boolean type TINYINT.
type BitBool bool

// Value implements the driver.Valuer interface,
// and turns the BitBool into a bitfield (BIT(1)) for MySQL storage.
func (b BitBool) Value() (driver.Value, error) {
	if b {
		return []byte{1}, nil
	}
	return []byte{0}, nil
}

// Scan implements the sql.Scanner interface,
// and turns the bitfield incoming from MySQL into a BitBool
func (b *BitBool) Scan(src interface{}) error {
	v, ok := src.([]byte)
	if !ok {
		return errors.New("bad []byte type assertion")
	}
	*b = v[0] == 1
	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	udt "github.com/fffw/go-udtwrapper"
	"io"
	"io/ioutil"
	"net"
	"os"
	"os/signal"
	"syscall"
	"time"
)

var verbose = false

// Usage prints out the usage of this module.
// Assumes flags use go stdlib flag pacakage.
var Usage = func() {
	text := `benchmark - UDT/TCP benchmark tool

Usage:

  server: %s -s<udt address> <tcp address>
  benchmarker:   %s [udt | tcp] <remote address>

Address format is Go's: [host]:port
`

	fmt.Fprintf(os.Stderr, text, os.Args[0], os.Args[0])
	flag.PrintDefaults()
}

type args struct {
	verbose bool
	listen  bool
	bs      int64

	udtAddr string
	tcpAddr string

	dialUdt    bool
	dialTcp    bool
	remoteAddr string
}

func parseArgs() args {
	var a args

	// setup + parse flags
	flag.BoolVar(&a.listen, "server", false, "listen for connections")
	flag.BoolVar(&a.listen, "s", false, "listen for connections (short)")
	flag.BoolVar(&a.dialUdt, "udt", false, "use udt client")
	flag.BoolVar(&a.dialTcp, "tcp", false, "use tcp client")
	flag.BoolVar(&a.verbose, "v", false, "verbose debugging")
	flag.Int64Var(&a.bs, "bs", 65536, "block size to send and receive")
	flag.Usage = Usage
	flag.Parse()
	osArgs := flag.Args()

	if a.listen {
		if len(osArgs) < 2 {
			Usage()
			exit("")
		}
		a.udtAddr = osArgs[0]
		a.tcpAddr = osArgs[1]
	} else {
		if len(osArgs) < 1 {
			Usage()
			exit("")
		}
		a.remoteAddr = osArgs[0]
	}

	return a
}

func main() {
	args := parseArgs()
	verbose = args.verbose

	go func() {
		// wait until we exit.
		sigc := make(chan os.Signal, 1)
		signal.Notify(sigc, syscall.SIGABRT)
		<-sigc
		panic("ABORT! ABORT! ABORT!")
	}()

	var err error
	if args.listen {
		err = Listen(args.udtAddr, args.tcpAddr, args.bs)
	} else {
		var c net.Conn
		if args.dialUdt {
			c, err = Dial("udt", args.remoteAddr)
		} else {
			c, err = Dial("tcp", args.remoteAddr)
		}
		if err != nil {
			exit("%s", err)
		}
		err = benchmark(c, args.bs)
	}

	if err != nil {
		exit("%s", err)
	}
}

func exit(format string, vals ...interface{}) {
	if format != "" {
		fmt.Fprintf(os.Stderr, "benchmark error: "+format+"\n", vals...)
	}
	os.Exit(1)
}

func log(format string, vals ...interface{}) {
	if verbose {
		fmt.Fprintf(os.Stderr, "benchmark log: "+format+"\n", vals...)
	}
}

// Listen listens and accepts one incoming UDT connection on a given port,
// and pipes all incoming data to os.Stdout.
func Listen(udtAddr string, tcpAddr string, bs int64) error {
	udt, err := udt.Listen("udt", udtAddr)
	if err != nil {
		return err
	}
	log("udt listening at %s", udt.Addr())

	tcp, err := net.Listen("tcp", tcpAddr)
	if err != nil {
		return err
	}
	log("tcp listening at %s", tcp.Addr())

	done := make(chan interface{}, 2)
	run := func(l net.Listener) (err error) {
		for {
			var c net.Conn
			c, err = l.Accept()
			if err != nil {
				return
			}
			log("accepted connection from %s", c.RemoteAddr())

			go func() {
				var n int64
				for {
					select {
					case <-done:
						return
					default:
						n, err = io.CopyN(c, c, bs)
						if err != nil {
							return
						}
						log("Copied back %d bytes", n)
					}
				}
				c.Close()

				return
			}()
		}
	}

	go run(udt)
	go run(tcp)
	// wait until we exit.
	sigc := make(chan os.Signal, 1)
	signal.Notify(sigc, syscall.SIGHUP, syscall.SIGINT,
		syscall.SIGTERM, syscall.SIGQUIT)
	<-sigc
	done <- nil
	return nil
}

// Dial connects to a remote address and pipes all os.Stdin to the remote end.
// If localAddr is set, uses it to Dial from.
func Dial(network, remoteAddr string) (c net.Conn, err error) {
	log("%s dialing %s", network, remoteAddr)
	if network == "udt" {
		c, err = udt.Dial("udt", remoteAddr)
	} else {
		c, err = net.Dial("tcp", remoteAddr)
	}
	if err != nil {
		return
	}
	log("connected to %s", c.RemoteAddr())
	return

}

func benchmark(c net.Conn, bs int64) (err error) {
	defer c.Close()
	rand, err := os.Open("/dev/zero")
	if err != nil {
		return
	}
	log("piping random to connection")

	done := make(chan interface{}, 2)
	var sent, recved int64
	startTime := time.Now()

	reportStat := func(prefix string, bytes int64) {
		timeSpent := time.Now().Sub(startTime) / time.Second
		fmt.Printf("%s %d bytes in %d sec, %d Bps\n", prefix, bytes, timeSpent, bytes/int64(timeSpent))
	}
	go func() {
		ticker := time.Tick(time.Second)
		for {
			select {
			case <-ticker:
				reportStat("Sent", sent)
			case <-done:
				return
			default:
				n, _ := io.CopyN(c, rand, bs)
				sent = sent + n
			}
		}
	}()
	go func() {
		ticker := time.Tick(time.Second)
		for {
			select {
			case <-ticker:
				reportStat("Recv", recved)
			case <-done:
				return
			default:
				n, _ := io.CopyN(ioutil.Discard, c, bs)
				recved = recved + n
			}
		}
	}()

	// wait until we exit.
	sigc := make(chan os.Signal, 1)
	signal.Notify(sigc, syscall.SIGHUP, syscall.SIGINT,
		syscall.SIGTERM, syscall.SIGQUIT)
	<-sigc
	done <- nil
	reportStat("Sent", sent)
	reportStat("Recv", recved)
	c.Close()
	return
}
<commit_msg>close server socket when EOF<commit_after>package main

import (
	"flag"
	"fmt"
	udt "github.com/fffw/go-udtwrapper"
	"io"
	"io/ioutil"
	"net"
	"os"
	"os/signal"
	"syscall"
	"time"
)

var verbose = false

// Usage prints out the usage of this module.
// Assumes flags use go stdlib flag pacakage.
var Usage = func() {
	text := `benchmark - UDT/TCP benchmark tool

Usage:

  server: %s -s<udt address> <tcp address>
  benchmarker:   %s [udt | tcp] <remote address>

Address format is Go's: [host]:port
`

	fmt.Fprintf(os.Stderr, text, os.Args[0], os.Args[0])
	flag.PrintDefaults()
}

type args struct {
	verbose bool
	listen  bool
	bs      int64

	udtAddr string
	tcpAddr string

	dialUdt    bool
	dialTcp    bool
	remoteAddr string
}

func parseArgs() args {
	var a args

	// setup + parse flags
	flag.BoolVar(&a.listen, "server", false, "listen for connections")
	flag.BoolVar(&a.listen, "s", false, "listen for connections (short)")
	flag.BoolVar(&a.dialUdt, "udt", false, "use udt client")
	flag.BoolVar(&a.dialTcp, "tcp", false, "use tcp client")
	flag.BoolVar(&a.verbose, "v", false, "verbose debugging")
	flag.Int64Var(&a.bs, "bs", 65536, "block size to send and receive")
	flag.Usage = Usage
	flag.Parse()
	osArgs := flag.Args()

	if a.listen {
		if len(osArgs) < 2 {
			Usage()
			exit("")
		}
		a.udtAddr = osArgs[0]
		a.tcpAddr = osArgs[1]
	} else {
		if len(osArgs) < 1 {
			Usage()
			exit("")
		}
		a.remoteAddr = osArgs[0]
	}

	return a
}

func main() {
	args := parseArgs()
	verbose = args.verbose

	go func() {
		// wait until we exit.
		sigc := make(chan os.Signal, 1)
		signal.Notify(sigc, syscall.SIGABRT)
		<-sigc
		panic("ABORT! ABORT! ABORT!")
	}()

	var err error
	if args.listen {
		err = Listen(args.udtAddr, args.tcpAddr, args.bs)
	} else {
		var c net.Conn
		if args.dialUdt {
			c, err = Dial("udt", args.remoteAddr)
		} else {
			c, err = Dial("tcp", args.remoteAddr)
		}
		if err != nil {
			exit("%s", err)
		}
		err = benchmark(c, args.bs)
	}

	if err != nil {
		exit("%s", err)
	}
}

func exit(format string, vals ...interface{}) {
	if format != "" {
		fmt.Fprintf(os.Stderr, "benchmark error: "+format+"\n", vals...)
	}
	os.Exit(1)
}

func log(format string, vals ...interface{}) {
	if verbose {
		fmt.Fprintf(os.Stderr, "benchmark log: "+format+"\n", vals...)
	}
}

// Listen listens and accepts one incoming UDT connection on a given port,
// and pipes all incoming data to os.Stdout.
func Listen(udtAddr string, tcpAddr string, bs int64) error {
	udt, err := udt.Listen("udt", udtAddr)
	if err != nil {
		return err
	}
	log("udt listening at %s", udt.Addr())

	tcp, err := net.Listen("tcp", tcpAddr)
	if err != nil {
		return err
	}
	log("tcp listening at %s", tcp.Addr())

	done := make(chan interface{}, 2)
	run := func(l net.Listener) (err error) {
		for {
			var c net.Conn
			c, err = l.Accept()
			if err != nil {
				return
			}
			log("accepted connection from %s", c.RemoteAddr())

			go func() {
				for {
					select {
					case <-done:
						c.Close()
						return
					default:
						n, e := io.CopyN(c, c, bs)
						if e == io.EOF {
							c.Close()
							return
						}
						log("Copied back %d bytes", n)
					}
				}

				return
			}()
		}
	}

	go run(udt)
	go run(tcp)
	// wait until we exit.
	sigc := make(chan os.Signal, 1)
	signal.Notify(sigc, syscall.SIGHUP, syscall.SIGINT,
		syscall.SIGTERM, syscall.SIGQUIT)
	<-sigc
	fmt.Println("Quit now")
	done <- nil
	return nil
}

// Dial connects to a remote address and pipes all os.Stdin to the remote end.
// If localAddr is set, uses it to Dial from.
func Dial(network, remoteAddr string) (c net.Conn, err error) {
	log("%s dialing %s", network, remoteAddr)
	if network == "udt" {
		c, err = udt.Dial("udt", remoteAddr)
	} else {
		c, err = net.Dial("tcp", remoteAddr)
	}
	if err != nil {
		return
	}
	log("connected to %s", c.RemoteAddr())
	return

}

func benchmark(c net.Conn, bs int64) (err error) {
	defer c.Close()
	rand, err := os.Open("/dev/zero")
	if err != nil {
		return
	}
	log("piping random to connection")

	done := make(chan interface{}, 2)
	var sent, recved int64
	startTime := time.Now()

	reportStat := func(prefix string, bytes int64) {
		timeSpent := time.Now().Sub(startTime) / time.Second
		fmt.Printf("%s %d bytes in %d sec, %d Bps\n", prefix, bytes, timeSpent, bytes/int64(timeSpent))
	}
	go func() {
		ticker := time.Tick(time.Second)
		for {
			select {
			case <-ticker:
				reportStat("Sent", sent)
			case <-done:
				return
			default:
				n, _ := io.CopyN(c, rand, bs)
				sent = sent + n
			}
		}
	}()
	go func() {
		ticker := time.Tick(time.Second)
		for {
			select {
			case <-ticker:
				reportStat("Recv", recved)
			case <-done:
				return
			default:
				n, _ := io.CopyN(ioutil.Discard, c, bs)
				recved = recved + n
			}
		}
	}()

	// wait until we exit.
	sigc := make(chan os.Signal, 1)
	signal.Notify(sigc, syscall.SIGHUP, syscall.SIGINT,
		syscall.SIGTERM, syscall.SIGQUIT)
	<-sigc
	fmt.Println("Quit now, final result:")
	done <- nil
	done <- nil
	reportStat("Sent", sent)
	reportStat("Recv", recved)
	c.Close()
	return
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"go/token"
	"go/types"
	"log"
	"os"
	"sort"
	"strings"

	"github.com/kisielk/gotool"
	"golang.org/x/tools/go/loader"
)

var exitCode int

var (
	fConstants bool
	fFunctions bool
	fTypes     bool
	fVariables bool
)

func init() {
	flag.BoolVar(&fConstants, "c", true, "Report unused constants")
	flag.BoolVar(&fFunctions, "f", true, "Report unused functions and methods")
	flag.BoolVar(&fTypes, "t", true, "Report unused types")
	flag.BoolVar(&fVariables, "v", true, "Report unused variables")
}

func main() {
	flag.Parse()
	// FIXME check flag.NArgs
	paths := gotool.ImportPaths([]string{flag.Arg(0)})
	conf := loader.Config{AllowErrors: true}
	for _, path := range paths {
		conf.ImportWithTests(path)
	}
	lprog, err := conf.Load()
	if err != nil {
		log.Fatal(err)
	}

	defs := map[types.Object]bool{}
	for _, path := range paths {
		pkg := lprog.Package(path)
		if pkg == nil {
			log.Println("Couldn't load package", path)
			continue
		}
		for _, obj := range pkg.Defs {
			if obj == nil {
				continue
			}
			if isVariable(obj) && !isPkgScope(obj) && !isField(obj) {
				// Skip variables that aren't package variables or struct fields
				continue
			}
			defs[obj] = false
		}
		for _, obj := range pkg.Uses {
			defs[obj] = true
		}
	}
	var reports Reports
	for obj, used := range defs {
		if obj.Pkg() == nil {
			continue
		}
		// TODO methods that satisfy an interface are used
		// TODO methods + reflection
		if !checkFlags(obj) {
			continue
		}
		if used {
			continue
		}
		if obj.Name() == "_" {
			continue
		}
		if obj.Exported() && (isPkgScope(obj) || isMethod(obj) || isField(obj)) {
			f := lprog.Fset.Position(obj.Pos()).Filename
			if !strings.HasSuffix(f, "_test.go") || strings.HasPrefix(obj.Name(), "Test") || strings.HasPrefix(obj.Name(), "Benchmark") {
				continue
			}
		}
		if isMain(obj) {
			continue
		}
		if isFunction(obj) && !isMethod(obj) && obj.Name() == "init" {
			continue
		}
		reports = append(reports, Report{obj.Pos(), obj.Name()})
	}
	sort.Sort(reports)
	for _, report := range reports {
		fmt.Printf("%s: %s is unused\n", lprog.Fset.Position(report.pos), report.name)
	}

	os.Exit(exitCode)
}

func isPkgScope(obj types.Object) bool {
	return obj.Parent() == obj.Pkg().Scope()
}

func isMain(obj types.Object) bool {
	if obj.Pkg().Name() != "main" {
		return false
	}
	if obj.Name() != "main" {
		return false
	}
	if !isPkgScope(obj) {
		return false
	}
	if !isFunction(obj) {
		return false
	}
	if isMethod(obj) {
		return false
	}
	return true
}

func isFunction(obj types.Object) bool {
	_, ok := obj.(*types.Func)
	return ok
}

func isMethod(obj types.Object) bool {
	if !isFunction(obj) {
		return false
	}
	return obj.(*types.Func).Type().(*types.Signature).Recv() != nil
}

func isVariable(obj types.Object) bool {
	_, ok := obj.(*types.Var)
	return ok
}

func isConstant(obj types.Object) bool {
	_, ok := obj.(*types.Const)
	return ok
}

func isType(obj types.Object) bool {
	_, ok := obj.(*types.TypeName)
	return ok
}

func isField(obj types.Object) bool {
	if obj, ok := obj.(*types.Var); ok && obj.IsField() {
		return true
	}
	return false
}

func checkFlags(obj types.Object) bool {
	if isFunction(obj) && !fFunctions {
		return false
	}
	if isVariable(obj) && !fVariables {
		return false
	}
	if isConstant(obj) && !fConstants {
		return false
	}
	if isType(obj) && !fTypes {
		return false
	}
	return true
}

type Report struct {
	pos  token.Pos
	name string
}
type Reports []Report

func (l Reports) Len() int           { return len(l) }
func (l Reports) Less(i, j int) bool { return l[i].pos < l[j].pos }
func (l Reports) Swap(i, j int)      { l[i], l[j] = l[j], l[i] }
<commit_msg>Disable support for tests for now<commit_after>package main

import (
	"flag"
	"fmt"
	"go/token"
	"go/types"
	"log"
	"os"
	"sort"
	"strings"

	"github.com/kisielk/gotool"
	"golang.org/x/tools/go/loader"
)

var exitCode int

var (
	fConstants bool
	fFunctions bool
	fTypes     bool
	fVariables bool
)

func init() {
	flag.BoolVar(&fConstants, "c", true, "Report unused constants")
	flag.BoolVar(&fFunctions, "f", true, "Report unused functions and methods")
	flag.BoolVar(&fTypes, "t", true, "Report unused types")
	flag.BoolVar(&fVariables, "v", true, "Report unused variables")
}

func main() {
	flag.Parse()
	// FIXME check flag.NArgs
	paths := gotool.ImportPaths([]string{flag.Arg(0)})
	conf := loader.Config{AllowErrors: true}
	for _, path := range paths {
		conf.Import(path)
	}
	lprog, err := conf.Load()
	if err != nil {
		log.Fatal(err)
	}

	defs := map[types.Object]bool{}
	for _, path := range paths {
		pkg := lprog.Package(path)
		if pkg == nil {
			log.Println("Couldn't load package", path)
			continue
		}
		for _, obj := range pkg.Defs {
			if obj == nil {
				continue
			}
			if isVariable(obj) && !isPkgScope(obj) && !isField(obj) {
				// Skip variables that aren't package variables or struct fields
				continue
			}
			defs[obj] = false
		}
		for _, obj := range pkg.Uses {
			defs[obj] = true
		}
	}
	var reports Reports
	for obj, used := range defs {
		if obj.Pkg() == nil {
			continue
		}
		// TODO methods that satisfy an interface are used
		// TODO methods + reflection
		if !checkFlags(obj) {
			continue
		}
		if used {
			continue
		}
		if obj.Name() == "_" {
			continue
		}
		if obj.Exported() && (isPkgScope(obj) || isMethod(obj) || isField(obj)) {
			f := lprog.Fset.Position(obj.Pos()).Filename
			if !strings.HasSuffix(f, "_test.go") || strings.HasPrefix(obj.Name(), "Test") || strings.HasPrefix(obj.Name(), "Benchmark") {
				continue
			}
		}
		if isMain(obj) {
			continue
		}
		if isFunction(obj) && !isMethod(obj) && obj.Name() == "init" {
			continue
		}
		reports = append(reports, Report{obj.Pos(), obj.Name()})
	}
	sort.Sort(reports)
	for _, report := range reports {
		fmt.Printf("%s: %s is unused\n", lprog.Fset.Position(report.pos), report.name)
	}

	os.Exit(exitCode)
}

func isPkgScope(obj types.Object) bool {
	return obj.Parent() == obj.Pkg().Scope()
}

func isMain(obj types.Object) bool {
	if obj.Pkg().Name() != "main" {
		return false
	}
	if obj.Name() != "main" {
		return false
	}
	if !isPkgScope(obj) {
		return false
	}
	if !isFunction(obj) {
		return false
	}
	if isMethod(obj) {
		return false
	}
	return true
}

func isFunction(obj types.Object) bool {
	_, ok := obj.(*types.Func)
	return ok
}

func isMethod(obj types.Object) bool {
	if !isFunction(obj) {
		return false
	}
	return obj.(*types.Func).Type().(*types.Signature).Recv() != nil
}

func isVariable(obj types.Object) bool {
	_, ok := obj.(*types.Var)
	return ok
}

func isConstant(obj types.Object) bool {
	_, ok := obj.(*types.Const)
	return ok
}

func isType(obj types.Object) bool {
	_, ok := obj.(*types.TypeName)
	return ok
}

func isField(obj types.Object) bool {
	if obj, ok := obj.(*types.Var); ok && obj.IsField() {
		return true
	}
	return false
}

func checkFlags(obj types.Object) bool {
	if isFunction(obj) && !fFunctions {
		return false
	}
	if isVariable(obj) && !fVariables {
		return false
	}
	if isConstant(obj) && !fConstants {
		return false
	}
	if isType(obj) && !fTypes {
		return false
	}
	return true
}

type Report struct {
	pos  token.Pos
	name string
}
type Reports []Report

func (l Reports) Len() int           { return len(l) }
func (l Reports) Less(i, j int) bool { return l[i].pos < l[j].pos }
func (l Reports) Swap(i, j int)      { l[i], l[j] = l[j], l[i] }
<|endoftext|>


<commit_before>package flickr

import (
	"bytes"
	"io/ioutil"
	"os"
	"strings"
	"testing"

	flickErr "github.com/masci/flickr/error"
)

func TestNewUploadParams(t *testing.T) {
	params := NewUploadParams()
	Expect(t, params.Title, "")
	Expect(t, params.Description, "")
	Expect(t, len(params.Tags), 0)
	Expect(t, params.IsPublic, false)
	Expect(t, params.IsFamily, false)
	Expect(t, params.IsFriend, false)
	Expect(t, params.ContentType, 1)
	Expect(t, params.Hidden, 2)
	Expect(t, params.SafetyLevel, 1)
}

func TestFillArgsWithParams(t *testing.T) {
	client := GetTestClient()
	params := NewUploadParams()
	fillArgsWithParams(client, params)

	Expect(t, client.Args.Get("title"), "")
	Expect(t, client.Args.Get("description"), "")
	Expect(t, client.Args.Get("tags"), "")
	Expect(t, client.Args.Get("is_public"), "0")
	Expect(t, client.Args.Get("is_friend"), "0")
	Expect(t, client.Args.Get("is_family"), "0")
	Expect(t, client.Args.Get("content_type"), "1")
	Expect(t, client.Args.Get("hidden"), "2")
	Expect(t, client.Args.Get("safety_level"), "1")

	params.Title = "foo"
	params.Description = "a long description"
	params.Tags = []string{"a", "b", "c"}
	params.IsPublic = true
	params.IsFamily = true
	params.IsFriend = true
	params.ContentType = 100
	params.Hidden = 100
	params.SafetyLevel = 100
	client.ClearArgs()
	fillArgsWithParams(client, params)
	Expect(t, client.Args.Get("title"), "foo")
	Expect(t, client.Args.Get("description"), "a long description")
	Expect(t, client.Args.Get("tags"), "a b c")
	Expect(t, client.Args.Get("is_public"), "1")
	Expect(t, client.Args.Get("is_friend"), "1")
	Expect(t, client.Args.Get("is_family"), "1")
	Expect(t, client.Args.Get("content_type"), "")
	Expect(t, client.Args.Get("hidden"), "")
	Expect(t, client.Args.Get("safety_level"), "")
}

func TestGetUploadBody(t *testing.T) {
	client := GetTestClient()
	photo := bytes.NewBufferString("foo")
	body, ctype, err := getUploadBody(client, photo, "fnam")

	Expect(t, err, nil)
	Expect(t, strings.Contains(ctype, "multipart/form-data; boundary="), true)
	Expect(t, strings.Contains(body.String(), "foo"), true)
}

func TestUploadFile(t *testing.T) {
	fclient := GetTestClient()
	server, client := FlickrMock(200, `<?xml version="1.0" encoding="utf-8" ?><rsp stat="ok"></rsp>`, "")
	defer server.Close()
	fclient.HTTPClient = client
	params := NewUploadParams()

	resp, err := UploadFile(fclient, "", params)
	Expect(t, resp == nil, true) // comparing nil interfaces would fail
	_, ok := err.(*os.PathError)
	Expect(t, ok, true)

	fooFile, err := ioutil.TempFile("", "flickr.go")
	defer fooFile.Close()
	Expect(t, err, nil)
	resp, err = UploadFile(fclient, fooFile.Name(), params)
	Expect(t, resp.HasErrors(), false)
}

func TestUploadFileKo(t *testing.T) {
	fclient := GetTestClient()
	server, client := FlickrMock(200, `<?xml version="1.0" encoding="utf-8" ?><rsp stat="fail"></rsp>`, "")
	defer server.Close()
	fclient.HTTPClient = client

	fooFile, err := ioutil.TempFile("", "flickr.go")
	defer fooFile.Close()
	resp, err := UploadFile(fclient, fooFile.Name(), nil)
	_, ok := err.(*flickErr.Error)
	Expect(t, ok, true)
	Expect(t, resp.HasErrors(), true)
}
<commit_msg>fixed tests<commit_after>package flickr

import (
	"io/ioutil"
	"os"
	"testing"

	flickErr "github.com/masci/flickr/error"
)

func TestNewUploadParams(t *testing.T) {
	params := NewUploadParams()
	Expect(t, params.Title, "")
	Expect(t, params.Description, "")
	Expect(t, len(params.Tags), 0)
	Expect(t, params.IsPublic, false)
	Expect(t, params.IsFamily, false)
	Expect(t, params.IsFriend, false)
	Expect(t, params.ContentType, 1)
	Expect(t, params.Hidden, 2)
	Expect(t, params.SafetyLevel, 1)
}

func TestFillArgsWithParams(t *testing.T) {
	client := GetTestClient()
	params := NewUploadParams()
	fillArgsWithParams(client, params)

	Expect(t, client.Args.Get("title"), "")
	Expect(t, client.Args.Get("description"), "")
	Expect(t, client.Args.Get("tags"), "")
	Expect(t, client.Args.Get("is_public"), "0")
	Expect(t, client.Args.Get("is_friend"), "0")
	Expect(t, client.Args.Get("is_family"), "0")
	Expect(t, client.Args.Get("content_type"), "1")
	Expect(t, client.Args.Get("hidden"), "2")
	Expect(t, client.Args.Get("safety_level"), "1")

	params.Title = "foo"
	params.Description = "a long description"
	params.Tags = []string{"a", "b", "c"}
	params.IsPublic = true
	params.IsFamily = true
	params.IsFriend = true
	params.ContentType = 100
	params.Hidden = 100
	params.SafetyLevel = 100
	client.ClearArgs()
	fillArgsWithParams(client, params)
	Expect(t, client.Args.Get("title"), "foo")
	Expect(t, client.Args.Get("description"), "a long description")
	Expect(t, client.Args.Get("tags"), "a b c")
	Expect(t, client.Args.Get("is_public"), "1")
	Expect(t, client.Args.Get("is_friend"), "1")
	Expect(t, client.Args.Get("is_family"), "1")
	Expect(t, client.Args.Get("content_type"), "")
	Expect(t, client.Args.Get("hidden"), "")
	Expect(t, client.Args.Get("safety_level"), "")
}

func TestUploadFile(t *testing.T) {
	fclient := GetTestClient()
	server, client := FlickrMock(200, `<?xml version="1.0" encoding="utf-8" ?><rsp stat="ok"></rsp>`, "")
	defer server.Close()
	fclient.HTTPClient = client
	params := NewUploadParams()

	resp, err := UploadFile(fclient, "", params)
	Expect(t, resp == nil, true) // comparing nil interfaces would fail
	_, ok := err.(*os.PathError)
	Expect(t, ok, true)
}

func TestUploadFileKo(t *testing.T) {
	fclient := GetTestClient()
	server, client := FlickrMock(200, `<?xml version="1.0" encoding="utf-8" ?><rsp stat="fail"></rsp>`, "")
	defer server.Close()
	fclient.HTTPClient = client

	fooFile, err := ioutil.TempFile("", "flickr.go")
	defer fooFile.Close()
	resp, err := UploadFile(fclient, fooFile.Name(), nil)
	_, ok := err.(*flickErr.Error)
	Expect(t, ok, true)
	Expect(t, resp.HasErrors(), true)
}
<|endoftext|>


<commit_before>package picarus
import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"bytes"
	"mime/multipart"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
	"time"
)

type Conn struct {
	Email string
	ApiKey string
	LoginKey string
	Server string
}

func (conn *Conn) call(method string, path []string, params url.Values, files map[string][]byte, key string) ([]byte, error) {
	var err error
	var req *http.Request
	serverPrefix := conn.Server + "/" + strings.Join(path, "/")
	if method == "GET" {
		req, err = http.NewRequest(method, serverPrefix + "?" + params.Encode(), nil)
	} else {
		buf := new(bytes.Buffer)
		w := multipart.NewWriter(buf)
		for fileName, fileData := range files {
			_, err = w.CreateFormFile(fileName, fileName) // fw
			if err != nil {
				return nil, err
			}
			buf.Write([]byte(fileData))
		}
		for name, values := range params {
			for _, value := range values {
				err = w.WriteField(name, value)
				if err != nil {
					return nil, err
				}
			}
		}
		w.Close()
		req, err = http.NewRequest(method, serverPrefix, buf)
		if err != nil {
			return nil, err
		}
		req.Header.Set("Content-Type", w.FormDataContentType())
	}
	if err != nil {
		return nil, err
	}
	req.SetBasicAuth(conn.Email, key)
	response, err := http.DefaultClient.Do(req) // res
	if err != nil {
		return nil, err
	}
	if response.StatusCode != 200 {
		body := ioutil.ReadAll(response.Body)
		return nil, errors.New(fmt.Sprintf("Bad status[%d][%s]", response.StatusCode, body))
	}
	defer response.Body.Close()
	return ioutil.ReadAll(response.Body)
}

func decodeLod(values []map[string]string) ([]map[string]string, error) {
	out := []map[string]string{}
	for _, value := range values {
		curOut, err := decodeDict(value)
		if err != nil {
			return nil, err
		}
		out = append(out, curOut)
	}
	return out, nil
}

func decodeDict(value map[string]string) (map[string]string, error) {
	out := map[string]string{}
	for k, v := range value {
		// TODO: Use a checked version of b64dec
		if k == "row" {
			out[k] = B64Dec(v)
		} else {
			out[B64Dec(k)] = B64Dec(v)
		}
	}
	return out, nil
}

func decodeValues(value map[string]string) (map[string]string, error) {
	out := map[string]string{}
	for k, v := range value {
		// TODO: Use a checked version of b64dec
		out[k] = B64Dec(v)
	}
	return out, nil
}

func encodeDict(value map[string]string) map[string]string {
	out := map[string]string{}
	for k, v := range value {
		out[B64Enc(k)] = B64Enc(v)
	}
	return out
}

func encodeValues(value map[string]string) map[string]string {
	out := map[string]string{}
	for k, v := range value {
		out[k] = B64Enc(v)
	}
	return out
}

func encodeFiles(files map[string][]byte) map[string][]byte {
	out := map[string][]byte{}
	for k, v := range files {
		out[B64Enc(k)] = v
	}
	return out
}

func (conn *Conn) GetRow(table string, row string, columns []string) (map[string]string, error) {
	params := url.Values{}
	if len(columns) > 0 {
		params.Set("columns", encodeColumns(columns))
	}
	data, err := conn.call("GET", []string{"v0", "data", table, UB64Enc(row)}, params, map[string][]byte{}, conn.ApiKey)
	if err != nil {
		return nil, err
	}
	dataParsed := map[string]string{}
	json.Unmarshal(data, &dataParsed)
	return decodeDict(dataParsed)
}

func (conn *Conn) GetTable(table string, columns []string) ([]map[string]string, error) {
	params := url.Values{}
	if len(columns) > 0 {
		params.Set("columns", encodeColumns(columns))
	}
	data, err := conn.call("GET", []string{"v0", "data", table}, params, map[string][]byte{}, conn.ApiKey)
	if err != nil {
		return nil, err
	}
	dataParsed := []map[string]string{}
	json.Unmarshal(data, &dataParsed)
	return decodeLod(dataParsed)
}

func encodeColumns(columns []string) string {
	columnsB64 := []string{}
	for _, c := range columns {
		columnsB64 = append(columnsB64, B64Enc(c))
	}
	return strings.Join(columnsB64, ",")
}

func (conn *Conn) GetSlice(table string, startRow string, stopRow string, columns []string) ([]map[string]string, error) {
	params := url.Values{}
	if len(columns) > 0 {
		params.Set("columns", encodeColumns(columns))
	}
	data, err := conn.call("GET", []string{"v0", "slice", table, UB64Enc(startRow), UB64Enc(stopRow)}, params, map[string][]byte{}, conn.ApiKey)
	if err != nil {
		return nil, err
	}
	dataParsed := []map[string]string{}
	json.Unmarshal(data, &dataParsed)
	return decodeLod(dataParsed)
}

func mapToUrlValues(data map[string]string) url.Values {
	out := url.Values{}
	for k, v := range data {
		out.Set(k, v)
	}
	return out
}

func (conn *Conn) PostSlice(table string, startRow string, stopRow string, params map[string]string) (map[string]string, error) {
	data, err := conn.call("POST", []string{"v0", "slice", table, UB64Enc(startRow), UB64Enc(stopRow)}, mapToUrlValues(encodeValues(params)), map[string][]byte{}, conn.ApiKey)
	if err != nil {
		return nil, err
	}
	dataParsed := map[string]string{}
	json.Unmarshal(data, &dataParsed)
	return decodeDict(dataParsed)
}

type Slice struct {
    StartRow, StopRow string
}

func encodeSlices(slices []Slice) string {
	out := []string{}
	for _, v := range slices {
		out = append(out, B64Enc(v.StartRow) + "," + B64Enc(v.StopRow))
	}
	return strings.Join(out, ";")
}

func (conn *Conn) PostTable(table string, params map[string]string, files map[string][]byte, slices []Slice) (map[string]string, error) {
	if len(slices) > 0 {
		params["slices"] = encodeSlices(slices)
	}
	data, err := conn.call("POST", []string{"v0", "data", table}, mapToUrlValues(encodeDict(params)), encodeFiles(files), conn.ApiKey)
	if err != nil {
		return nil, err
	}
	dataParsed := map[string]string{}
	json.Unmarshal(data, &dataParsed)
	return decodeValues(dataParsed)
}

func (conn *Conn) PostRow(table string, row string, params map[string]string) (map[string]string, error) {
	data, err := conn.call("POST", []string{"v0", "data", table, UB64Enc(row)}, mapToUrlValues(encodeValues(params)), map[string][]byte{}, conn.ApiKey)
	if err != nil {
		return nil, err
	}
	dataParsed := map[string]string{}
	json.Unmarshal(data, &dataParsed)
	return decodeDict(dataParsed)
}

func (conn *Conn) PatchRow(table string, row string, params map[string]string, files map[string][]byte) (map[string]string, error) {
	data, err := conn.call("PATCH", []string{"v0", "data", table, UB64Enc(row)}, mapToUrlValues(encodeDict(params)), encodeFiles(files), conn.ApiKey)
	if err != nil {
		return nil, err
	}
	dataParsed := map[string]string{}
	json.Unmarshal(data, &dataParsed)
	return decodeDict(dataParsed)
}

func UB64Dec(s string) string {
	decoded, err := base64.URLEncoding.DecodeString(s)
	if err != nil {
		panic(err)
	}
	return string(decoded)
}

func B64Dec(s string) string {
	decoded, err := base64.StdEncoding.DecodeString(s)
	if err != nil {
		fmt.Println(s)
		panic(err)
	}
	return string(decoded)
}

func B64DecBytes(s string) []byte {
	decoded, err := base64.StdEncoding.DecodeString(s)
	if err != nil {
		fmt.Println(s)
		panic(err)
	}
	return decoded
}

func UB64Enc(s string) string {
	return base64.URLEncoding.EncodeToString([]byte(s))
}

func B64Enc(s string) string {
	return base64.StdEncoding.EncodeToString([]byte(s))
}

func (conn *Conn) WatchJob(row string) (map[string]string, error) {
	for {
		data, err := conn.GetRow("jobs", row, []string{})
		if err != nil {
			return nil, err
		}
		fmt.Println(data)
		if data["status"] == "completed" {
			return data, nil
		}
		time.Sleep(1000 * time.Millisecond)
	}
}<commit_msg>Cleaned up error reporting<commit_after>package picarus
import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"bytes"
	"mime/multipart"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"
	"time"
)

type Conn struct {
	Email string
	ApiKey string
	LoginKey string
	Server string
}

func (conn *Conn) call(method string, path []string, params url.Values, files map[string][]byte, key string) ([]byte, error) {
	var err error
	var req *http.Request
	serverPrefix := conn.Server + "/" + strings.Join(path, "/")
	if method == "GET" {
		req, err = http.NewRequest(method, serverPrefix + "?" + params.Encode(), nil)
	} else {
		buf := new(bytes.Buffer)
		w := multipart.NewWriter(buf)
		for fileName, fileData := range files {
			_, err = w.CreateFormFile(fileName, fileName) // fw
			if err != nil {
				return nil, err
			}
			buf.Write([]byte(fileData))
		}
		for name, values := range params {
			for _, value := range values {
				err = w.WriteField(name, value)
				if err != nil {
					return nil, err
				}
			}
		}
		w.Close()
		req, err = http.NewRequest(method, serverPrefix, buf)
		if err != nil {
			return nil, err
		}
		req.Header.Set("Content-Type", w.FormDataContentType())
	}
	if err != nil {
		return nil, err
	}
	req.SetBasicAuth(conn.Email, key)
	response, err := http.DefaultClient.Do(req) // res
	if err != nil {
		return nil, err
	}
	body, err := ioutil.ReadAll(response.Body)
	defer response.Body.Close()
	if err != nil {
		return nil, err
	}
	if response.StatusCode != 200 {
		return nil, errors.New(fmt.Sprintf("Bad status[%d][%s]", response.StatusCode, body))
	}
	return body, nil
}

func decodeLod(values []map[string]string) ([]map[string]string, error) {
	out := []map[string]string{}
	for _, value := range values {
		curOut, err := decodeDict(value)
		if err != nil {
			return nil, err
		}
		out = append(out, curOut)
	}
	return out, nil
}

func decodeDict(value map[string]string) (map[string]string, error) {
	out := map[string]string{}
	for k, v := range value {
		// TODO: Use a checked version of b64dec
		if k == "row" {
			out[k] = B64Dec(v)
		} else {
			out[B64Dec(k)] = B64Dec(v)
		}
	}
	return out, nil
}

func decodeValues(value map[string]string) (map[string]string, error) {
	out := map[string]string{}
	for k, v := range value {
		// TODO: Use a checked version of b64dec
		out[k] = B64Dec(v)
	}
	return out, nil
}

func encodeDict(value map[string]string) map[string]string {
	out := map[string]string{}
	for k, v := range value {
		out[B64Enc(k)] = B64Enc(v)
	}
	return out
}

func encodeValues(value map[string]string) map[string]string {
	out := map[string]string{}
	for k, v := range value {
		out[k] = B64Enc(v)
	}
	return out
}

func encodeFiles(files map[string][]byte) map[string][]byte {
	out := map[string][]byte{}
	for k, v := range files {
		out[B64Enc(k)] = v
	}
	return out
}

func (conn *Conn) GetRow(table string, row string, columns []string) (map[string]string, error) {
	params := url.Values{}
	if len(columns) > 0 {
		params.Set("columns", encodeColumns(columns))
	}
	data, err := conn.call("GET", []string{"v0", "data", table, UB64Enc(row)}, params, map[string][]byte{}, conn.ApiKey)
	if err != nil {
		return nil, err
	}
	dataParsed := map[string]string{}
	json.Unmarshal(data, &dataParsed)
	return decodeDict(dataParsed)
}

func (conn *Conn) GetTable(table string, columns []string) ([]map[string]string, error) {
	params := url.Values{}
	if len(columns) > 0 {
		params.Set("columns", encodeColumns(columns))
	}
	data, err := conn.call("GET", []string{"v0", "data", table}, params, map[string][]byte{}, conn.ApiKey)
	if err != nil {
		return nil, err
	}
	dataParsed := []map[string]string{}
	json.Unmarshal(data, &dataParsed)
	return decodeLod(dataParsed)
}

func encodeColumns(columns []string) string {
	columnsB64 := []string{}
	for _, c := range columns {
		columnsB64 = append(columnsB64, B64Enc(c))
	}
	return strings.Join(columnsB64, ",")
}

func (conn *Conn) GetSlice(table string, startRow string, stopRow string, columns []string) ([]map[string]string, error) {
	params := url.Values{}
	if len(columns) > 0 {
		params.Set("columns", encodeColumns(columns))
	}
	data, err := conn.call("GET", []string{"v0", "slice", table, UB64Enc(startRow), UB64Enc(stopRow)}, params, map[string][]byte{}, conn.ApiKey)
	if err != nil {
		return nil, err
	}
	dataParsed := []map[string]string{}
	json.Unmarshal(data, &dataParsed)
	return decodeLod(dataParsed)
}

func mapToUrlValues(data map[string]string) url.Values {
	out := url.Values{}
	for k, v := range data {
		out.Set(k, v)
	}
	return out
}

func (conn *Conn) PostSlice(table string, startRow string, stopRow string, params map[string]string) (map[string]string, error) {
	data, err := conn.call("POST", []string{"v0", "slice", table, UB64Enc(startRow), UB64Enc(stopRow)}, mapToUrlValues(encodeValues(params)), map[string][]byte{}, conn.ApiKey)
	if err != nil {
		return nil, err
	}
	dataParsed := map[string]string{}
	json.Unmarshal(data, &dataParsed)
	return decodeDict(dataParsed)
}

type Slice struct {
    StartRow, StopRow string
}

func encodeSlices(slices []Slice) string {
	out := []string{}
	for _, v := range slices {
		out = append(out, B64Enc(v.StartRow) + "," + B64Enc(v.StopRow))
	}
	return strings.Join(out, ";")
}

func (conn *Conn) PostTable(table string, params map[string]string, files map[string][]byte, slices []Slice) (map[string]string, error) {
	if len(slices) > 0 {
		params["slices"] = encodeSlices(slices)
	}
	data, err := conn.call("POST", []string{"v0", "data", table}, mapToUrlValues(encodeDict(params)), encodeFiles(files), conn.ApiKey)
	if err != nil {
		return nil, err
	}
	dataParsed := map[string]string{}
	json.Unmarshal(data, &dataParsed)
	return decodeValues(dataParsed)
}

func (conn *Conn) PostRow(table string, row string, params map[string]string) (map[string]string, error) {
	data, err := conn.call("POST", []string{"v0", "data", table, UB64Enc(row)}, mapToUrlValues(encodeValues(params)), map[string][]byte{}, conn.ApiKey)
	if err != nil {
		return nil, err
	}
	dataParsed := map[string]string{}
	json.Unmarshal(data, &dataParsed)
	return decodeDict(dataParsed)
}

func (conn *Conn) PatchRow(table string, row string, params map[string]string, files map[string][]byte) (map[string]string, error) {
	data, err := conn.call("PATCH", []string{"v0", "data", table, UB64Enc(row)}, mapToUrlValues(encodeDict(params)), encodeFiles(files), conn.ApiKey)
	if err != nil {
		return nil, err
	}
	dataParsed := map[string]string{}
	json.Unmarshal(data, &dataParsed)
	return decodeDict(dataParsed)
}

func UB64Dec(s string) string {
	decoded, err := base64.URLEncoding.DecodeString(s)
	if err != nil {
		panic(err)
	}
	return string(decoded)
}

func B64Dec(s string) string {
	decoded, err := base64.StdEncoding.DecodeString(s)
	if err != nil {
		fmt.Println(s)
		panic(err)
	}
	return string(decoded)
}

func B64DecBytes(s string) []byte {
	decoded, err := base64.StdEncoding.DecodeString(s)
	if err != nil {
		fmt.Println(s)
		panic(err)
	}
	return decoded
}

func UB64Enc(s string) string {
	return base64.URLEncoding.EncodeToString([]byte(s))
}

func B64Enc(s string) string {
	return base64.StdEncoding.EncodeToString([]byte(s))
}

func (conn *Conn) WatchJob(row string) (map[string]string, error) {
	for {
		data, err := conn.GetRow("jobs", row, []string{})
		if err != nil {
			return nil, err
		}
		fmt.Println(data)
		if data["status"] == "completed" {
			return data, nil
		}
		time.Sleep(1000 * time.Millisecond)
	}
}<|endoftext|>


<commit_before>package main

import (
	//"flag"
	"encoding/json"
	"fmt"
	compilerapi "github.com/ant0ine/go-closure-compilerapi"
	. "github.com/sebkl/gotojs"
	. "github.com/sebkl/gotojs/client"
	"io/ioutil"
	"os"
	"regexp"
	"strings"
)

const (
	fflag                = os.FileMode(0644)
	dflag                = os.FileMode(0755)
	DefaultServerEnvName = "GOTOJS_HOST"
)

func printUsage() {
	cmd := os.Args[0]
	fmt.Printf(`
Usage:
	%s <command> <mandatory_arguments> [optional_arguments]

The Commands are:
	example <path_to_app_root>		Create a sample app.
	create 	<path_to_app_root>		Create a sample directory structure.
	export 	<path_to_template_dir>		Exports internally used templates.
	compile <path_to_js_file> [output]	Compile javascript file.
	<interface_name>.<method_name> [args]   Invoke call of remote gotojs instance. The
						configuration is taken from the "%s"
						environment variable. Default is:
						"http://localhost:8080/gotojs"

Examples:
	GOTOJS_HOST="http://somehost.com/gotojs" %s Trace.Echo
	%s create /var/www/helloworld
`, cmd, DefaultServerEnvName, cmd, cmd)
}

func check(e error) {
	if e != nil {
		printUsage()
		panic(e)
	}
}

func exportTemplates(path string) {
	fflag := os.FileMode(0644)

	temp := DefaultTemplates()

	for p, t := range temp {
		err := ioutil.WriteFile(path+"/"+p+"/"+HTTPTemplate, []byte(t.HTTP), fflag)
		check(err)
		err = ioutil.WriteFile(path+"/"+p+"/"+BindingTemplate, []byte(t.Binding), fflag)
		check(err)
		err = ioutil.WriteFile(path+"/"+p+"/"+InterfaceTemplate, []byte(t.Interface), fflag)
		check(err)
		err = ioutil.WriteFile(path+"/"+p+"/"+MethodTemplate, []byte(t.Method), fflag)
		check(err)
	}
}

func createBaseDirs(path string) {
	err := os.MkdirAll(path, dflag)
	check(err)
	err = os.MkdirAll(path+"/"+DefaultFileServerDir, dflag)
	check(err)
	err = os.MkdirAll(path+"/"+RelativeTemplatePath, dflag)
	check(err)
	for _, p := range Platforms {
		err = os.MkdirAll(path+"/"+RelativeTemplatePath+"/"+p, dflag)
		check(err)
		err = os.MkdirAll(path+"/"+RelativeTemplatePath+"/"+p+"/"+RelativeTemplateLibPath, dflag)
		check(err)
	}
}

func createSampleFiles(path string) {
	createBaseDirs(path)
	err := ioutil.WriteFile(path+"/"+DefaultFileServerDir+"/index.html", []byte(`
<!DOCTYPE HTML>

  <title>gotojs example</title>
  <link type="text/css" href="css/main.css" rel="Stylesheet"/>

Hello World !

 `), fflag)
	check(err)
	err = os.MkdirAll(path+"/"+DefaultFileServerDir+"/css", dflag)
	check(err)
	err = os.MkdirAll(path+"/"+DefaultFileServerDir+"/js", dflag)
	check(err)
	err = ioutil.WriteFile(path+"/"+DefaultFileServerDir+"/css/main.css", []byte(`
h1{ font-family: sans-serif; color: #AAAAAA; }
`), fflag)
	check(err)

	err = ioutil.WriteFile(path+"/app.go", []byte(`
package main

import (
	"log"
	"fmt"
	"strings"
	. "github.com/sebkl/gotojs"
)

// Declare Service to be exposed.
type Service struct {}

// Methods of Service that will be exposed.
func (s *Service) UpperCase(mes string) string {
    return fmt.Sprintf("%s",strings.ToUpper(mes))
}

// Function that takes the HTTPContext as injection.
func AppendURL(context *HTTPContext, source string) string{
	return fmt.Sprintf("%s (%s)",source,context.Request.URL.String())
}

func main() {
	// Initialize the frontend.
	frontend := NewFrontend()

	// Setup the service object.
	service := Service{}

        // Declare some js code that is doing the calls. Usually this is done by a flat file in the public directory,
        // but in this case we would like to show how to use HandleStatic.
        myjs := "$(document).ready(function() {"
        myjs += "       var text = $('h1').html();"
        myjs += "       text = GOTOJS.Service.UpperCase(text);" // Make the title uppcase by the server side implementation
        myjs += "       text = GOTOJS.Service.AppendURL(text);" // Append the URL by the server side  implementation
        myjs += "       $('h1').html(text);"
        myjs += "});"

	// Expose the interface and setup the request routing.
	frontend.ExposeInterface(&service,"Service")
	frontend.ExposeFunction(AppendURL,"Service","AppendURL") // Name the function and expose it to existing interface.
	frontend.EnableFileServer("public","p")
	frontend.Redirect("/","/p/")
	frontend.HandleStatic("/my.js",myjs,"application/javascript")
	log.Fatal(frontend.Start(":8080","/gotojs"))
}
`), fflag)
	check(err)
}

func main() {
	al := len(os.Args)
	if al < 2 {
		printUsage()
		return
	}

	cmd := os.Args[1]
	args := os.Args[2:]

	switch cmd {
	case "example":
		createSampleFiles(args[0])
		exportTemplates(args[0] + "/" + RelativeTemplatePath)
	case "create":
		createBaseDirs(args[0])
		exportTemplates(args[0] + "/" + RelativeTemplatePath)
	case "export":
		exportTemplates(args[0])
	case "compile":
		client := &compilerapi.Client{Language: "ECMASCRIPT5", CompilationLevel: "SIMPLE_OPTIMIZATIONS"}
		bs, err := ioutil.ReadFile(args[0])
		check(err)
		o := client.Compile(bs)

		if al > 3 {
			out := os.Args[3]
			ioutil.WriteFile(out, []byte(o.CompiledCode), fflag)
		} else {
			fmt.Println(o.CompiledCode)
		}

		//Log Errors and Warnings last.
		for _, v := range o.Warnings {
			fmt.Println(v.AsLogline())
		}

		for _, v := range o.Errors {
			fmt.Println(v.AsLogline())
		}
	default:
		r := regexp.MustCompile(`^(.*)\.(.*)$`)
		if r.MatchString(cmd) {
			sa := r.FindStringSubmatch(cmd)
			iname := sa[1]
			mname := sa[2]
			server := os.Getenv(DefaultServerEnvName)
			c := NewClient(server)
			fmt.Printf("> %s.%s(%s) @ %s\n\n", iname, mname, strings.Join(args, ","), server)
			ret, err := c.Invoke(iname, mname, SAToIA(args...)...)

			if err != nil {
				fmt.Printf("FAILED: %s", err)
				os.Exit(1)
			} else {
				by, _ := json.MarshalIndent(ret, "", "  ")
				fmt.Printf("%s", string(by))
			}
		} else {
			fmt.Printf("Unknown command: %s\n\n", cmd)
			printUsage()
		}
	}

}
<commit_msg>Updated to falgconf.<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	compilerapi "github.com/ant0ine/go-closure-compilerapi"
	"github.com/sebkl/flagconf"
	. "github.com/sebkl/gotojs"
	. "github.com/sebkl/gotojs/client"
	"io/ioutil"
	"os"
	"regexp"
	"strings"
)

const (
	fflag = os.FileMode(0644)
	dflag = os.FileMode(0755)
)

func printUsage() {
	cmd := os.Args[0]
	fmt.Printf(`
Usage:
	%s <command> <mandatory_arguments> [optional_arguments]

The Commands are:
	example <path_to_app_root>		Create a sample app.
	create 	<path_to_app_root>		Create a sample directory structure.
	export 	<path_to_template_dir>		Exports internally used templates.
	compile <path_to_js_file> [output]	Compile javascript file.
	<interface_name>.<method_name> [args]   Invoke call of remote gotojs instance. The
						configuration is taken from the "GJHOST"
						environment variable. Default is:
						"http://localhost:8080/gotojs"

Examples:
	GJSHOST="http://somehost.com/gotojs" %s Trace.Echo
	%s --HOST="http://somehost.com/gotojs" Trace.Echo
	%s create /var/www/helloworld

`, cmd, cmd, cmd, cmd)
	flag.PrintDefaults()
}

var gotojsHost string

func init() {
	flag.StringVar(&gotojsHost, "HOST", "http://localhost:8080/gotojs", "GOTOJS endpoint to use.")
}

func check(e error) {
	if e != nil {
		printUsage()
		panic(e)
	}
}

func exportTemplates(path string) {
	fflag := os.FileMode(0644)

	temp := DefaultTemplates()

	for p, t := range temp {
		err := ioutil.WriteFile(path+"/"+p+"/"+HTTPTemplate, []byte(t.HTTP), fflag)
		check(err)
		err = ioutil.WriteFile(path+"/"+p+"/"+BindingTemplate, []byte(t.Binding), fflag)
		check(err)
		err = ioutil.WriteFile(path+"/"+p+"/"+InterfaceTemplate, []byte(t.Interface), fflag)
		check(err)
		err = ioutil.WriteFile(path+"/"+p+"/"+MethodTemplate, []byte(t.Method), fflag)
		check(err)
	}
}

func createBaseDirs(path string) {
	err := os.MkdirAll(path, dflag)
	check(err)
	err = os.MkdirAll(path+"/"+DefaultFileServerDir, dflag)
	check(err)
	err = os.MkdirAll(path+"/"+RelativeTemplatePath, dflag)
	check(err)
	for _, p := range Platforms {
		err = os.MkdirAll(path+"/"+RelativeTemplatePath+"/"+p, dflag)
		check(err)
		err = os.MkdirAll(path+"/"+RelativeTemplatePath+"/"+p+"/"+RelativeTemplateLibPath, dflag)
		check(err)
	}
}

func createSampleFiles(path string) {
	createBaseDirs(path)
	err := ioutil.WriteFile(path+"/"+DefaultFileServerDir+"/index.html", []byte(`
<!DOCTYPE HTML>

  <title>gotojs example</title>
  <link type="text/css" href="css/main.css" rel="Stylesheet"/>

Hello World !

 `), fflag)
	check(err)
	err = os.MkdirAll(path+"/"+DefaultFileServerDir+"/css", dflag)
	check(err)
	err = os.MkdirAll(path+"/"+DefaultFileServerDir+"/js", dflag)
	check(err)
	err = ioutil.WriteFile(path+"/"+DefaultFileServerDir+"/css/main.css", []byte(`
h1{ font-family: sans-serif; color: #AAAAAA; }
`), fflag)
	check(err)

	err = ioutil.WriteFile(path+"/app.go", []byte(`
package main

import (
	"log"
	"fmt"
	"strings"
	. "github.com/sebkl/gotojs"
)

// Declare Service to be exposed.
type Service struct {}

// Methods of Service that will be exposed.
func (s *Service) UpperCase(mes string) string {
    return fmt.Sprintf("%s",strings.ToUpper(mes))
}

// Function that takes the HTTPContext as injection.
func AppendURL(context *HTTPContext, source string) string{
	return fmt.Sprintf("%s (%s)",source,context.Request.URL.String())
}

func main() {
	// Initialize the frontend.
	frontend := NewContainer()

	// Setup the service object.
	service := Service{}

        // Declare some js code that is doing the calls. Usually this is done by a flat file in the public directory,
        // but in this case we would like to show how to use HandleStatic.
        myjs := "$(document).ready(function() {"
        myjs += "       var text = $('h1').html();"
        myjs += "       text = GOTOJS.Service.UpperCase(text);" // Make the title uppcase by the server side implementation
        myjs += "       text = GOTOJS.Service.AppendURL(text);" // Append the URL by the server side  implementation
        myjs += "       $('h1').html(text);"
        myjs += "});"

	// Expose the interface and setup the request routing.
	frontend.ExposeInterface(&service,"Service")
	frontend.ExposeFunction(AppendURL,"Service","AppendURL") // Name the function and expose it to existing interface.
	frontend.EnableFileServer("public","p")
	frontend.Redirect("/","/p/")
	frontend.HandleStatic("/my.js",myjs,"application/javascript")
	log.Fatal(frontend.Start(":8080","/gotojs"))
}
`), fflag)
	check(err)
}

func main() {
	flagconf.Parse("GJS")
	al := len(os.Args)
	if al < 2 {
		printUsage()
		return
	}

	cmd := os.Args[1]
	args := os.Args[2:]

	switch cmd {
	case "example":
		createSampleFiles(args[0])
		exportTemplates(args[0] + "/" + RelativeTemplatePath)
	case "create":
		createBaseDirs(args[0])
		exportTemplates(args[0] + "/" + RelativeTemplatePath)
	case "export":
		exportTemplates(args[0])
	case "compile":
		client := &compilerapi.Client{Language: "ECMASCRIPT5", CompilationLevel: "SIMPLE_OPTIMIZATIONS"}
		bs, err := ioutil.ReadFile(args[0])
		check(err)
		o := client.Compile(bs)

		if al > 3 {
			out := os.Args[3]
			ioutil.WriteFile(out, []byte(o.CompiledCode), fflag)
		} else {
			fmt.Println(o.CompiledCode)
		}

		//Log Errors and Warnings last.
		for _, v := range o.Warnings {
			fmt.Println(v.AsLogline())
		}

		for _, v := range o.Errors {
			fmt.Println(v.AsLogline())
		}
	default:
		r := regexp.MustCompile(`^(.*)\.(.*)$`)
		if r.MatchString(cmd) {
			sa := r.FindStringSubmatch(cmd)
			iname := sa[1]
			mname := sa[2]
			fmt.Printf("> %s.%s(%s) @ %s\n\n", iname, mname, strings.Join(args, ","), gotojsHost)
			c := NewClient(gotojsHost)
			ret, err := c.Invoke(iname, mname, SAToIA(args...)...)

			if err != nil {
				fmt.Printf("FAILED: %s", err)
				os.Exit(1)
			} else {
				by, _ := json.MarshalIndent(ret, "", "  ")
				fmt.Printf("%s", string(by))
			}
		} else {
			fmt.Printf("Unknown command: %s\n\n", cmd)
			printUsage()
		}
	}

}
<|endoftext|>


<commit_before>package util

import (
	"bufio"
	"errors"
	"fmt"
	"image"
	"io"
	"math"
	"os/exec"
	"runtime"
	"strings"
	"time"

	"github.com/ninjasphere/go-ninja/config"
	"github.com/tarm/serial"
)

var ledPath = config.String("/dev/tty.ledmatrix", "led.tty")

var cmdWriteBuffer byte = 1
var cmdSwapBuffers byte = 2

// Attempts this first, then falls back to half.
const baudRate = 230400

// From https://diarmuid.ie/blog/post/pwm-exponential-led-fading-on-arduino-or-other-platforms
var R = (255 * math.Log10(2)) / (math.Log10(255))
var ledAdjust = make(map[uint8]uint8)

func init() {
	for i := 0; i < 256; i++ {
		ledAdjust[uint8(i)] = uint8(math.Pow(2, (float64(i)/R)) - 1)
	}
}

func GetLEDConnectionAtRate(baudRate int) (io.ReadWriteCloser, error) {

	log.Infof("Connecting to LED using baud rate: %d", baudRate)

	c := &serial.Config{Name: ledPath, Baud: baudRate}
	s, err := serial.OpenPort(c)
	if err != nil {
		return nil, err
	}

	init := make(chan string)
	failed := make(chan error)
	go func() {
		reader := bufio.NewReader(s)
		str, err := reader.ReadString('\n')
		if err != nil {
			failed <- err
		} else {
			init <- str
		}
	}()

	select {
	case err := <-failed:
		log.Infof("Failed reading init string from LED matrix: %s", err)
		return nil, err
	case initStr := <-init:
		log.Infof("Read init string from LED matrix: %s", initStr)

		if !strings.Contains(initStr, "LED") {
			return nil, fmt.Errorf("Bad init string... '%s'", initStr)
		}

		return s, nil
	case <-time.After(time.Second * 3):
		log.Warningf("Timeout waiting for LED matrix init string.")
		s.Close()
		return nil, fmt.Errorf("Bad init string..")
	}

}

func GetLEDConnection() (io.ReadWriteCloser, error) {

	if runtime.GOOS == "linux" {
		return getLEDConnectionLinux()
	}

	return newMockMatrix(), nil
}

func getLEDConnectionLinux() (io.ReadWriteCloser, error) {

	resetLedMatrix, resetErr := exec.LookPath("reset-led-matrix")
	if resetErr != nil {
		log.Errorf("Could not find reset led matrix command: %s", resetErr)
	}

	for _, d := range []int{1, 2, 4} {
		for _, baud := range []int{baudRate, baudRate / 2} {

			if resetErr == nil {
				cmd := exec.Command(resetLedMatrix)
				_, _ = cmd.Output()
			}

			s, err := GetLEDConnectionAtRate(baud)
			if err == nil {
				return s, nil
			}

			log.Warningf("Connection to LED matrix failed at %d. Sleeping for %d seconds.", baud, d)

			time.Sleep(time.Second * time.Duration(d))
		}
	}

	return nil, errors.New("failed to connect to LED matrix - falling back to mock a matrix connection.")
}

func ConvertImage(image *image.RGBA) []byte {

	var frame [768]byte

	for inPos, outPos := 0, 0; inPos < len(image.Pix); inPos = inPos + 4 {

		outPos = inPos / 4 * 3

		frame[outPos] = ledAdjust[image.Pix[inPos]]
		frame[outPos+1] = ledAdjust[image.Pix[inPos+1]]
		frame[outPos+2] = ledAdjust[image.Pix[inPos+2]]
	}

	rows := split(frame[:], 16*3)

	var orderedRows [][]byte
	for i := 0; i < 8; i++ {
		orderedRows = append(orderedRows, rows[i+8])
		orderedRows = append(orderedRows, rows[i])
	}

	var finalFrame []byte

	for _, line := range orderedRows {
		for i, j := 0, len(line)-1; i < j; i, j = i+1, j-1 {
			line[i], line[j] = line[j], line[i]
		}

		finalFrame = append(finalFrame, line...)
	}

	return finalFrame
}

// Write an image into the led matrix
func WriteLEDMatrix(image *image.RGBA, s io.ReadWriteCloser) {

	//spew.Dump("writing image", image)

	finalFrame := ConvertImage(image)

	_, err := s.Write([]byte{cmdWriteBuffer})
	if err != nil {
		log.Fatalf("Failed writing write buffer command: %s", err)
	}

	_, err = s.Write(finalFrame[:])
	if err != nil {
		log.Fatalf("Failed writing frame: %s", err)
	}

	_, err = s.Write([]byte{cmdSwapBuffers})
	if err != nil {
		log.Fatalf("Failed writing swap buffer command: %s", err)
	}

	//log.Println("Wrote frame", n)
	buf := make([]byte, 1)
	_, err = s.Read(buf)
	if err != nil {
		log.Infof("Failed to read char after sending frame : %s", err)
	}
	if buf[0] != byte('F') {
		log.Infof("Expected an 'F', got '%q'", buf[0])
	}
}

func split(a []byte, size int) [][]byte {
	var out [][]byte
	var i = 0
	for i < len(a) {
		out = append(out, a[i:i+size])
		i += size
	}

	return out
}

// Simple RLE on zero values....
/*
func compress(frame []byte) []byte {
	compressed := make([]byte, 0)
	for i := 0; i < len(frame); i++ {

		val := frame[i]
		if val == 0 {

			count := 0
			for j := i + 1; j < len(frame) && frame[j] == val; j++ {
				count++
			}

			compressed = append(compressed, val, byte(count))
			i += count
		} else {
			compressed = append(compressed, val)
		}
	}
	//spew.Dump("from", frame, compressed)
	return compressed
}*/
<commit_msg>Revert "Switch to tarm"<commit_after>package util

import (
	"bufio"
	"errors"
	"fmt"
	"image"
	"io"
	"math"
	"os/exec"
	"runtime"
	"strings"
	"time"

	"github.com/ninjasphere/go-ninja/config"
	"github.com/ninjasphere/goserial"
)

var ledPath = config.String("/dev/tty.ledmatrix", "led.tty")

var cmdWriteBuffer byte = 1
var cmdSwapBuffers byte = 2

// Attempts this first, then falls back to half.
const baudRate = 230400

// From https://diarmuid.ie/blog/post/pwm-exponential-led-fading-on-arduino-or-other-platforms
var R = (255 * math.Log10(2)) / (math.Log10(255))
var ledAdjust = make(map[uint8]uint8)

func init() {
	for i := 0; i < 256; i++ {
		ledAdjust[uint8(i)] = uint8(math.Pow(2, (float64(i)/R)) - 1)
	}
}

func GetLEDConnectionAtRate(baudRate int) (io.ReadWriteCloser, error) {

	log.Infof("Connecting to LED using baud rate: %d", baudRate)

	c := &serial.Config{Name: ledPath, Baud: baudRate}
	s, err := serial.OpenPort(c)
	if err != nil {
		return nil, err
	}

	init := make(chan string)
	failed := make(chan error)
	go func() {
		reader := bufio.NewReader(s)
		str, err := reader.ReadString('\n')
		if err != nil {
			failed <- err
		} else {
			init <- str
		}
	}()

	select {
	case err := <-failed:
		log.Infof("Failed reading init string from LED matrix: %s", err)
		return nil, err
	case initStr := <-init:
		log.Infof("Read init string from LED matrix: %s", initStr)

		if !strings.Contains(initStr, "LED") {
			return nil, fmt.Errorf("Bad init string... '%s'", initStr)
		}

		return s, nil
	case <-time.After(time.Second * 3):
		log.Warningf("Timeout waiting for LED matrix init string.")
		s.Close()
		return nil, fmt.Errorf("Bad init string..")
	}

}

func GetLEDConnection() (io.ReadWriteCloser, error) {

	if runtime.GOOS == "linux" {
		return getLEDConnectionLinux()
	}

	return newMockMatrix(), nil
}

func getLEDConnectionLinux() (io.ReadWriteCloser, error) {

	resetLedMatrix, resetErr := exec.LookPath("reset-led-matrix")
	if resetErr != nil {
		log.Errorf("Could not find reset led matrix command: %s", resetErr)
	}

	for _, d := range []int{1, 2, 4} {
		for _, baud := range []int{baudRate, baudRate / 2} {

			if resetErr == nil {
				cmd := exec.Command(resetLedMatrix)
				_, _ = cmd.Output()
			}

			s, err := GetLEDConnectionAtRate(baud)
			if err == nil {
				return s, nil
			}

			log.Warningf("Connection to LED matrix failed at %d. Sleeping for %d seconds.", baud, d)

			time.Sleep(time.Second * time.Duration(d))
		}
	}

	return nil, errors.New("failed to connect to LED matrix - falling back to mock a matrix connection.")
}

func ConvertImage(image *image.RGBA) []byte {

	var frame [768]byte

	for inPos, outPos := 0, 0; inPos < len(image.Pix); inPos = inPos + 4 {

		outPos = inPos / 4 * 3

		frame[outPos] = ledAdjust[image.Pix[inPos]]
		frame[outPos+1] = ledAdjust[image.Pix[inPos+1]]
		frame[outPos+2] = ledAdjust[image.Pix[inPos+2]]
	}

	rows := split(frame[:], 16*3)

	var orderedRows [][]byte
	for i := 0; i < 8; i++ {
		orderedRows = append(orderedRows, rows[i+8])
		orderedRows = append(orderedRows, rows[i])
	}

	var finalFrame []byte

	for _, line := range orderedRows {
		for i, j := 0, len(line)-1; i < j; i, j = i+1, j-1 {
			line[i], line[j] = line[j], line[i]
		}

		finalFrame = append(finalFrame, line...)
	}

	return finalFrame
}

// Write an image into the led matrix
func WriteLEDMatrix(image *image.RGBA, s io.ReadWriteCloser) {

	//spew.Dump("writing image", image)

	finalFrame := ConvertImage(image)

	_, err := s.Write([]byte{cmdWriteBuffer})
	if err != nil {
		log.Fatalf("Failed writing write buffer command: %s", err)
	}

	_, err = s.Write(finalFrame[:])
	if err != nil {
		log.Fatalf("Failed writing frame: %s", err)
	}

	_, err = s.Write([]byte{cmdSwapBuffers})
	if err != nil {
		log.Fatalf("Failed writing swap buffer command: %s", err)
	}

	//log.Println("Wrote frame", n)
	buf := make([]byte, 1)
	_, err = s.Read(buf)
	if err != nil {
		log.Infof("Failed to read char after sending frame : %s", err)
	}
	if buf[0] != byte('F') {
		log.Infof("Expected an 'F', got '%q'", buf[0])
	}
}

func split(a []byte, size int) [][]byte {
	var out [][]byte
	var i = 0
	for i < len(a) {
		out = append(out, a[i:i+size])
		i += size
	}

	return out
}

// Simple RLE on zero values....
/*
func compress(frame []byte) []byte {
	compressed := make([]byte, 0)
	for i := 0; i < len(frame); i++ {

		val := frame[i]
		if val == 0 {

			count := 0
			for j := i + 1; j < len(frame) && frame[j] == val; j++ {
				count++
			}

			compressed = append(compressed, val, byte(count))
			i += count
		} else {
			compressed = append(compressed, val)
		}
	}
	//spew.Dump("from", frame, compressed)
	return compressed
}*/
<|endoftext|>


<commit_before>package util

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"syscall"

	"github.com/go-fsnotify/fsnotify"

	"github.com/pagodabox/nanobox-cli/config"
)

var watcher *fsnotify.Watcher
var ignoreDirs = []string{}

//
func Watch(path string, fn func(e *fsnotify.Event, err error)) error {
	setFileLimit()
	// get a list of directories that should not be watched; this is done because
	// there is a limit to how many files can be watched at a time, so folders like
	// node_modules, bower_components, vendor, etc...
	if err := getIgnoreDirs(); err != nil {
		return err
	}

	// create a new file watcher
	w, err := fsnotify.NewWatcher()
	if err != nil {
		return err
	}

	// this is dumb
	watcher = w

	// recursivly walk directories, beginning at 'root' (path), adding watchers
	if err := filepath.Walk(path, watchDir); err != nil {
		return err
	}

	// watch for file events (blocking)
	for {
		select {

		// handle any file events by calling the handler function
		case event := <-watcher.Events:

			// the watcher needs to watch itself to see if any directories are added to then
			// add them to the list of watched files;
			if event.Op == fsnotify.Create {
				fi, err := os.Stat(event.Name)
				if err := watchDir(event.Name, fi, err); err != nil {
					fn(&event, err)
				}
			}

			// call the handler for each even fired
			fn(&event, nil)

			// handle any errors by calling the handler function
		case err := <-watcher.Errors:
			fn(nil, err)
		}
	}

}

// watchDir gets run as a walk func, searching for directories to add watchers to
func watchDir(path string, fi os.FileInfo, err error) error {

	// since fsnotify can watch all the files in a directory, watchers only need
	// to be added to each nested directory
	if fi.Mode().IsDir() && !isIgnoreDir(fi.Name()) {
		if err = watcher.Add(path); err != nil {
			return err
		}
	}

	return nil
}

// isIgnoreDir
func isIgnoreDir(name string) bool {
	for _, dir := range ignoreDirs {
		if dir == name {
			return true
		}
	}
	return false
}

// getIgnoreDirs
func getIgnoreDirs() error {
	res, err := http.Get(fmt.Sprintf("http://%s/libdirs", config.ServerURI))
	if err != nil {
		return err
	}
	defer res.Body.Close()

	//
	b, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return err
	}

	return json.Unmarshal(b, &ignoreDirs)
}

func setFileLimit() {
	rlm := &syscall.Rlimit{}
	syscall.Getrlimit(syscall.RLIMIT_NOFILE, rlm)
	rlm.Cur = rlm.Max
	syscall.Setrlimit(syscall.RLIMIT_NOFILE, rlm)
}
<commit_msg>add comment<commit_after>package util

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"path/filepath"
	"syscall"

	"github.com/go-fsnotify/fsnotify"

	"github.com/pagodabox/nanobox-cli/config"
)

var watcher *fsnotify.Watcher
var ignoreDirs = []string{}

//
func Watch(path string, fn func(e *fsnotify.Event, err error)) error {
	setFileLimit()
	// get a list of directories that should not be watched; this is done because
	// there is a limit to how many files can be watched at a time, so folders like
	// node_modules, bower_components, vendor, etc...
	if err := getIgnoreDirs(); err != nil {
		return err
	}

	// create a new file watcher
	w, err := fsnotify.NewWatcher()
	if err != nil {
		return err
	}

	// this is dumb
	watcher = w

	// recursivly walk directories, beginning at 'root' (path), adding watchers
	if err := filepath.Walk(path, watchDir); err != nil {
		return err
	}

	// watch for file events (blocking)
	for {
		select {

		// handle any file events by calling the handler function
		case event := <-watcher.Events:

			// the watcher needs to watch itself to see if any directories are added to then
			// add them to the list of watched files;
			if event.Op == fsnotify.Create {
				fi, err := os.Stat(event.Name)
				if err := watchDir(event.Name, fi, err); err != nil {
					fn(&event, err)
				}
			}

			// call the handler for each even fired
			fn(&event, nil)

			// handle any errors by calling the handler function
		case err := <-watcher.Errors:
			fn(nil, err)
		}
	}

}

// watchDir gets run as a walk func, searching for directories to add watchers to
func watchDir(path string, fi os.FileInfo, err error) error {

	// since fsnotify can watch all the files in a directory, watchers only need
	// to be added to each nested directory
	if fi.Mode().IsDir() && !isIgnoreDir(fi.Name()) {
		if err = watcher.Add(path); err != nil {
			return err
		}
	}

	return nil
}

// isIgnoreDir
func isIgnoreDir(name string) bool {
	for _, dir := range ignoreDirs {
		if dir == name {
			return true
		}
	}
	return false
}

// getIgnoreDirs
func getIgnoreDirs() error {
	res, err := http.Get(fmt.Sprintf("http://%s/libdirs", config.ServerURI))
	if err != nil {
		return err
	}
	defer res.Body.Close()

	//
	b, err := ioutil.ReadAll(res.Body)
	if err != nil {
		return err
	}

	return json.Unmarshal(b, &ignoreDirs)
}

// set my rlimit to the maximum rlimit
func setFileLimit() {
	rlm := &syscall.Rlimit{}
	syscall.Getrlimit(syscall.RLIMIT_NOFILE, rlm)
	rlm.Cur = rlm.Max
	syscall.Setrlimit(syscall.RLIMIT_NOFILE, rlm)
}
<|endoftext|>


<commit_before>package gosideways

import (
	"bufio"
	"errors"
	"fmt"
	"log"
	"net"
	"strconv"
	"strings"
	"time"
)

type Node struct {
	Addr     string
	Port     int
	Data     map[string]Data
	Siblings map[string]*Node

	save chan Data
	repl chan Data
}

type Data struct {
	Key     string
	Text    string
	Date    time.Time
	Expires time.Time
}

func (n *Node) AddSibling(addr string, port int) error {
	key := addr + ":" + fmt.Sprint(port)
	if _, exists := n.Siblings[key]; exists {
		return errors.New("Sibling " + key + " already registered")
	}

	n.Siblings[key] = newNode(addr, port)

	return nil
}

func Listen(port int) *Node {
	node := newNode("127.0.0.1", port)
	go node.clean()
	go node.Run()

	go func() {
		for d := range node.save {
			node.Data[d.Key] = d
		}
	}()

	go func() {
		for d := range node.repl {
			node.replicate(d)
		}
	}()

	return node
}

func (n *Node) Run() {
	listener, err := net.Listen("tcp", fmt.Sprintf(":%d", n.Port))
	if err != nil {
		log.Println(err.Error())
		return
	}
	defer listener.Close()

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Println(err.Error())
			continue
		}

		go n.handleConnection(conn)
	}
}

func (n *Node) Get(key string) *Data {
	return n.get(key)
}

func (n *Node) Set(key string, data string, valid time.Duration) {
	d := n.newData(key, data, valid)

	n.save <- d
	n.repl <- d
}

func (n *Node) newData(key string, data string, valid time.Duration) Data {
	return Data{
		Key:     key,
		Text:    data,
		Date:    time.Now(),
		Expires: time.Now().Add(valid),
	}
}

func (n *Node) replicate(d Data) {
	for _, s := range n.Siblings {
		if s.Addr == n.Addr && s.Port == n.Port {
			continue
		}

		addr := fmt.Sprintf("%s:%d", s.Addr, s.Port)
		conn, err := net.Dial("tcp", addr)
		if err != nil {
			log.Println(err.Error())
			continue
		}

		exp := int(d.Expires.Sub(time.Now()).Seconds() + .5)

		fmt.Fprintf(conn, "REPLICATE %s %d %d %s", d.Key, exp, len(d.Text), d.Text)
		conn.Close()
	}
}

func (n *Node) get(key string) *Data {
	var data *Data

	if aux, ok := n.Data[key]; ok {
		if aux.Expires.Before(time.Now()) {
			n.del(key)
		} else {
			data = &aux
		}
	}

	return data
}

func (n *Node) del(key string) {
	if _, ok := n.Data[key]; ok {
		delete(n.Data, key)
	}
}

func (n *Node) clean() {
	for {
		now := time.Now()
		for key, data := range n.Data {
			if data.Expires.Before(now) {
				n.del(key)
			}
		}

		time.Sleep(time.Second)
	}
}

func newNode(addr string, port int) *Node {
	return &Node{
		Addr:     addr,
		Port:     port,
		Data:     make(map[string]Data),
		Siblings: make(map[string]*Node),

		save: make(chan Data, 1024),
		repl: make(chan Data, 1024),
	}
}

func (n *Node) handleConnection(c net.Conn) {
	defer c.Close()

	scanner := bufio.NewScanner(c)
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if line == "" {
			continue
		}

		command := strings.SplitN(line, " ", 3)
		if len(command) < 2 {
			continue
		}

		command[0] = strings.ToUpper(command[0])
		for i := 1; i < len(command); i++ {
			command[i] = strings.TrimSpace(command[i])
		}

		switch command[0] {
		case "GET":
			data := n.get(command[1])
			if data != nil {
				fmt.Fprintln(c, data.Text)
			}
			break
		case "SET", "REPLICATE":
			if len(command) < 3 {
				continue
			}

			aux := strings.SplitN(command[2], " ", 3)
			if len(aux) < 3 {
				continue
			}

			seconds, _ := strconv.Atoi(aux[0])
			if seconds <= 0 {
				continue
			}

			length, _ := strconv.Atoi(aux[1])
			if length <= 0 {
				continue
			}

			d := n.newData(command[1], aux[2], time.Duration(seconds)*time.Second)

			for len(d.Text) < length {
				scanner.Scan()
				d.Text += "\n" + scanner.Text()
			}

			n.save <- d

			if command[0] == "SET" {
				n.repl <- d
			}
			break
		case "DELETE":
			n.del(command[1])
			break
		}
	}
}
<commit_msg>Making node.run() private, there's no need for it to be public<commit_after>package gosideways

import (
	"bufio"
	"errors"
	"fmt"
	"log"
	"net"
	"strconv"
	"strings"
	"time"
)

type Node struct {
	Addr     string
	Port     int
	Data     map[string]Data
	Siblings map[string]*Node

	save chan Data
	repl chan Data
}

type Data struct {
	Key     string
	Text    string
	Date    time.Time
	Expires time.Time
}

func (n *Node) AddSibling(addr string, port int) error {
	key := addr + ":" + fmt.Sprint(port)
	if _, exists := n.Siblings[key]; exists {
		return errors.New("Sibling " + key + " already registered")
	}

	n.Siblings[key] = newNode(addr, port)

	return nil
}

func Listen(port int) *Node {
	node := newNode("127.0.0.1", port)
	go node.clean()
	go node.run()

	go func() {
		for d := range node.save {
			node.Data[d.Key] = d
		}
	}()

	go func() {
		for d := range node.repl {
			node.replicate(d)
		}
	}()

	return node
}

func (n *Node) run() {
	listener, err := net.Listen("tcp", fmt.Sprintf(":%d", n.Port))
	if err != nil {
		log.Println(err.Error())
		return
	}
	defer listener.Close()

	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Println(err.Error())
			continue
		}

		go n.handleConnection(conn)
	}
}

func (n *Node) Get(key string) *Data {
	return n.get(key)
}

func (n *Node) Set(key string, data string, valid time.Duration) {
	d := n.newData(key, data, valid)

	n.save <- d
	n.repl <- d
}

func (n *Node) newData(key string, data string, valid time.Duration) Data {
	return Data{
		Key:     key,
		Text:    data,
		Date:    time.Now(),
		Expires: time.Now().Add(valid),
	}
}

func (n *Node) replicate(d Data) {
	for _, s := range n.Siblings {
		if s.Addr == n.Addr && s.Port == n.Port {
			continue
		}

		addr := fmt.Sprintf("%s:%d", s.Addr, s.Port)
		conn, err := net.Dial("tcp", addr)
		if err != nil {
			log.Println(err.Error())
			continue
		}

		exp := int(d.Expires.Sub(time.Now()).Seconds() + .5)

		fmt.Fprintf(conn, "REPLICATE %s %d %d %s", d.Key, exp, len(d.Text), d.Text)
		conn.Close()
	}
}

func (n *Node) get(key string) *Data {
	var data *Data

	if aux, ok := n.Data[key]; ok {
		if aux.Expires.Before(time.Now()) {
			n.del(key)
		} else {
			data = &aux
		}
	}

	return data
}

func (n *Node) del(key string) {
	if _, ok := n.Data[key]; ok {
		delete(n.Data, key)
	}
}

func (n *Node) clean() {
	for {
		now := time.Now()
		for key, data := range n.Data {
			if data.Expires.Before(now) {
				n.del(key)
			}
		}

		time.Sleep(time.Second)
	}
}

func newNode(addr string, port int) *Node {
	return &Node{
		Addr:     addr,
		Port:     port,
		Data:     make(map[string]Data),
		Siblings: make(map[string]*Node),

		save: make(chan Data, 1024),
		repl: make(chan Data, 1024),
	}
}

func (n *Node) handleConnection(c net.Conn) {
	defer c.Close()

	scanner := bufio.NewScanner(c)
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if line == "" {
			continue
		}

		command := strings.SplitN(line, " ", 3)
		if len(command) < 2 {
			continue
		}

		command[0] = strings.ToUpper(command[0])
		for i := 1; i < len(command); i++ {
			command[i] = strings.TrimSpace(command[i])
		}

		switch command[0] {
		case "GET":
			data := n.get(command[1])
			if data != nil {
				fmt.Fprintln(c, data.Text)
			}
			break
		case "SET", "REPLICATE":
			if len(command) < 3 {
				continue
			}

			aux := strings.SplitN(command[2], " ", 3)
			if len(aux) < 3 {
				continue
			}

			seconds, _ := strconv.Atoi(aux[0])
			if seconds <= 0 {
				continue
			}

			length, _ := strconv.Atoi(aux[1])
			if length <= 0 {
				continue
			}

			d := n.newData(command[1], aux[2], time.Duration(seconds)*time.Second)

			for len(d.Text) < length {
				scanner.Scan()
				d.Text += "\n" + scanner.Text()
			}

			n.save <- d

			if command[0] == "SET" {
				n.repl <- d
			}
			break
		case "DELETE":
			n.del(command[1])
			break
		}
	}
}
<|endoftext|>


<commit_before>package xlsx

import (
	"fmt"
	"math"
	"strconv"
)

type CellType int

const (
	CellTypeString CellType = iota
	CellTypeFormula
	CellTypeNumeric
	CellTypeBool
	CellTypeInline
	CellTypeError
)

// Cell is a high level structure intended to provide user access to
// the contents of Cell within an xlsx.Row.
type Cell struct {
	Row      *Row
	Value    string
	formula  string
	style    *Style
	numFmt   string
	date1904 bool
	Hidden   bool
	cellType CellType
}

// CellInterface defines the public API of the Cell.
type CellInterface interface {
	String() string
	FormattedValue() string
}

func NewCell(r *Row) *Cell {
	return &Cell{style: NewStyle(), Row: r}
}

func (c *Cell) Type() CellType {
	return c.cellType
}

// Set string
func (c *Cell) SetString(s string) {
	c.Value = s
	c.formula = ""
	c.cellType = CellTypeString
}

// String returns the value of a Cell as a string.
func (c *Cell) String() string {
	return c.FormattedValue()
}

// Set float
func (c *Cell) SetFloat(n float64) {
	c.SetFloatWithFormat(n, "0.00e+00")
}

/*
	Set float with format. The followings are samples of format samples.

	* "0.00e+00"
	* "0", "#,##0"
	* "0.00", "#,##0.00", "@"
	* "#,##0 ;(#,##0)", "#,##0 ;[red](#,##0)"
	* "#,##0.00;(#,##0.00)", "#,##0.00;[red](#,##0.00)"
	* "0%", "0.00%"
	* "0.00e+00", "##0.0e+0"
*/
func (c *Cell) SetFloatWithFormat(n float64, format string) {
	// tmp value. final value is formatted by FormattedValue() method
	c.Value = fmt.Sprintf("%e", n)
	c.numFmt = format
	c.Value = c.FormattedValue()
	c.formula = ""
	c.cellType = CellTypeNumeric
}

// Returns the value of cell as a number
func (c *Cell) Float() (float64, error) {
	f, err := strconv.ParseFloat(c.Value, 64)
	if err != nil {
		return math.NaN(), err
	}
	return f, nil
}

// Set a 64-bit integer
func (c *Cell) SetInt64(n int64) {
	c.Value = fmt.Sprintf("%d", n)
	c.numFmt = "0"
	c.formula = ""
	c.cellType = CellTypeNumeric
}

// Returns the value of cell as 64-bit integer
func (c *Cell) Int64() (int64, error) {
	f, err := strconv.ParseInt(c.Value, 10, 64)
	if err != nil {
		return -1, err
	}
	return f, nil
}

// Set integer
func (c *Cell) SetInt(n int) {
	c.Value = fmt.Sprintf("%d", n)
	c.numFmt = "0"
	c.formula = ""
	c.cellType = CellTypeNumeric
}

// Returns the value of cell as integer
// Has max 53 bits of precision
// See: float64(int64(math.MaxInt))
func (c *Cell) Int() (int, error) {
	f, err := strconv.ParseFloat(c.Value, 64)
	if err != nil {
		return -1, err
	}
	return int(f), nil
}

// Set boolean
func (c *Cell) SetBool(b bool) {
	if b {
		c.Value = "1"
	} else {
		c.Value = "0"
	}
	c.cellType = CellTypeBool
}

// Get boolean
func (c *Cell) Bool() bool {
	return c.Value == "1"
}

// Set formula
func (c *Cell) SetFormula(formula string) {
	c.formula = formula
	c.cellType = CellTypeFormula
}

// Returns formula
func (c *Cell) Formula() string {
	return c.formula
}

// GetStyle returns the Style associated with a Cell
func (c *Cell) GetStyle() *Style {
	return c.style
}

// SetStyle sets the style of a cell.
func (c *Cell) SetStyle(style *Style) {
	c.style = style
}

// The number format string is returnable from a cell.
func (c *Cell) GetNumberFormat() string {
	return c.numFmt
}

func (c *Cell) formatToTime(format string) string {
	f, err := strconv.ParseFloat(c.Value, 64)
	if err != nil {
		return err.Error()
	}
	return TimeFromExcelTime(f, c.date1904).Format(format)
}

func (c *Cell) formatToFloat(format string) string {
	f, err := strconv.ParseFloat(c.Value, 64)
	if err != nil {
		return err.Error()
	}
	return fmt.Sprintf(format, f)
}

func (c *Cell) formatToInt(format string) string {
	f, err := strconv.ParseFloat(c.Value, 64)
	if err != nil {
		return err.Error()
	}
	return fmt.Sprintf(format, int(f))
}

// Return the formatted version of the value.
func (c *Cell) FormattedValue() string {
	var numberFormat string = c.GetNumberFormat()
	isText := numberFormat == "general" && numberFormat == "@"
	if c.Type() == CellTypeString && isText {
		return c.Value
	}
	switch numberFormat {
	case "general":
		return c.Value
	case "0", "#,##0":
		return c.formatToInt("%d")
	case "0.00", "#,##0.00", "@":
		return c.formatToFloat("%.2f")
	case "#,##0 ;(#,##0)", "#,##0 ;[red](#,##0)":
		f, err := strconv.ParseFloat(c.Value, 64)
		if err != nil {
			return err.Error()
		}
		if f < 0 {
			i := int(math.Abs(f))
			return fmt.Sprintf("(%d)", i)
		}
		i := int(f)
		return fmt.Sprintf("%d", i)
	case "#,##0.00;(#,##0.00)", "#,##0.00;[red](#,##0.00)":
		f, err := strconv.ParseFloat(c.Value, 64)
		if err != nil {
			return err.Error()
		}
		if f < 0 {
			return fmt.Sprintf("(%.2f)", f)
		}
		return fmt.Sprintf("%.2f", f)
	case "0%":
		f, err := strconv.ParseFloat(c.Value, 64)
		if err != nil {
			return err.Error()
		}
		f = f * 100
		return fmt.Sprintf("%d%%", int(f))
	case "0.00%":
		f, err := strconv.ParseFloat(c.Value, 64)
		if err != nil {
			return err.Error()
		}
		f = f * 100
		return fmt.Sprintf("%.2f%%", f)
	case "0.00e+00", "##0.0e+0":
		return c.formatToFloat("%e")
	case "mm-dd-yy":
		return c.formatToTime("01-02-06")
	case "d-mmm-yy":
		return c.formatToTime("2-Jan-06")
	case "d-mmm":
		return c.formatToTime("2-Jan")
	case "mmm-yy":
		return c.formatToTime("Jan-06")
	case "h:mm am/pm":
		return c.formatToTime("3:04 pm")
	case "h:mm:ss am/pm":
		return c.formatToTime("3:04:05 pm")
	case "h:mm":
		return c.formatToTime("15:04")
	case "h:mm:ss":
		return c.formatToTime("15:04:05")
	case "m/d/yy h:mm":
		return c.formatToTime("1/2/06 15:04")
	case "mm:ss":
		return c.formatToTime("04:05")
	case "[h]:mm:ss":
		f, err := strconv.ParseFloat(c.Value, 64)
		if err != nil {
			return err.Error()
		}
		t := TimeFromExcelTime(f, c.date1904)
		if t.Hour() > 0 {
			return t.Format("15:04:05")
		}
		return t.Format("04:05")
	case "mmss.0":
		f, err := strconv.ParseFloat(c.Value, 64)
		if err != nil {
			return err.Error()
		}
		t := TimeFromExcelTime(f, c.date1904)
		return fmt.Sprintf("%0d%0d.%d", t.Minute(), t.Second(), t.Nanosecond()/1000)

	case "yyyy\\-mm\\-dd":
		return c.formatToTime("2006\\-01\\-02")
	case "dd/mm/yy":
		return c.formatToTime("02/01/06")
	case "hh:mm:ss":
		return c.formatToTime("15:04:05")
	case "dd/mm/yy\\ hh:mm":
		return c.formatToTime("02/01/06\\ 15:04")
	case "dd/mm/yyyy hh:mm:ss":
		return c.formatToTime("02/01/2006 15:04:05")
	case "yy-mm-dd":
		return c.formatToTime("06-01-02")
	case "d-mmm-yyyy":
		return c.formatToTime("2-Jan-2006")
	case "m/d/yy":
		return c.formatToTime("1/2/06")
	case "m/d/yyyy":
		return c.formatToTime("1/2/2006")
	case "dd-mmm-yyyy":
		return c.formatToTime("02-Jan-2006")
	case "dd/mm/yyyy":
		return c.formatToTime("02/01/2006")
	case "mm/dd/yy hh:mm am/pm":
		return c.formatToTime("01/02/06 03:04 pm")
	case "mm/dd/yyyy hh:mm:ss":
		return c.formatToTime("01/02/2006 15:04:05")
	case "yyyy-mm-dd hh:mm:ss":
		return c.formatToTime("2006-01-02 15:04:05")
	}
	return c.Value
}
<commit_msg>typo fix<commit_after>package xlsx

import (
	"fmt"
	"math"
	"strconv"
)

type CellType int

const (
	CellTypeString CellType = iota
	CellTypeFormula
	CellTypeNumeric
	CellTypeBool
	CellTypeInline
	CellTypeError
)

// Cell is a high level structure intended to provide user access to
// the contents of Cell within an xlsx.Row.
type Cell struct {
	Row      *Row
	Value    string
	formula  string
	style    *Style
	numFmt   string
	date1904 bool
	Hidden   bool
	cellType CellType
}

// CellInterface defines the public API of the Cell.
type CellInterface interface {
	String() string
	FormattedValue() string
}

func NewCell(r *Row) *Cell {
	return &Cell{style: NewStyle(), Row: r}
}

func (c *Cell) Type() CellType {
	return c.cellType
}

// Set string
func (c *Cell) SetString(s string) {
	c.Value = s
	c.formula = ""
	c.cellType = CellTypeString
}

// String returns the value of a Cell as a string.
func (c *Cell) String() string {
	return c.FormattedValue()
}

// Set float
func (c *Cell) SetFloat(n float64) {
	c.SetFloatWithFormat(n, "0.00e+00")
}

/*
	Set float with format. The followings are samples of format samples.

	* "0.00e+00"
	* "0", "#,##0"
	* "0.00", "#,##0.00", "@"
	* "#,##0 ;(#,##0)", "#,##0 ;[red](#,##0)"
	* "#,##0.00;(#,##0.00)", "#,##0.00;[red](#,##0.00)"
	* "0%", "0.00%"
	* "0.00e+00", "##0.0e+0"
*/
func (c *Cell) SetFloatWithFormat(n float64, format string) {
	// tmp value. final value is formatted by FormattedValue() method
	c.Value = fmt.Sprintf("%e", n)
	c.numFmt = format
	c.Value = c.FormattedValue()
	c.formula = ""
	c.cellType = CellTypeNumeric
}

// Returns the value of cell as a number
func (c *Cell) Float() (float64, error) {
	f, err := strconv.ParseFloat(c.Value, 64)
	if err != nil {
		return math.NaN(), err
	}
	return f, nil
}

// Set a 64-bit integer
func (c *Cell) SetInt64(n int64) {
	c.Value = fmt.Sprintf("%d", n)
	c.numFmt = "0"
	c.formula = ""
	c.cellType = CellTypeNumeric
}

// Returns the value of cell as 64-bit integer
func (c *Cell) Int64() (int64, error) {
	f, err := strconv.ParseInt(c.Value, 10, 64)
	if err != nil {
		return -1, err
	}
	return f, nil
}

// Set integer
func (c *Cell) SetInt(n int) {
	c.Value = fmt.Sprintf("%d", n)
	c.numFmt = "0"
	c.formula = ""
	c.cellType = CellTypeNumeric
}

// Returns the value of cell as integer
// Has max 53 bits of precision
// See: float64(int64(math.MaxInt))
func (c *Cell) Int() (int, error) {
	f, err := strconv.ParseFloat(c.Value, 64)
	if err != nil {
		return -1, err
	}
	return int(f), nil
}

// Set boolean
func (c *Cell) SetBool(b bool) {
	if b {
		c.Value = "1"
	} else {
		c.Value = "0"
	}
	c.cellType = CellTypeBool
}

// Get boolean
func (c *Cell) Bool() bool {
	return c.Value == "1"
}

// Set formula
func (c *Cell) SetFormula(formula string) {
	c.formula = formula
	c.cellType = CellTypeFormula
}

// Returns formula
func (c *Cell) Formula() string {
	return c.formula
}

// GetStyle returns the Style associated with a Cell
func (c *Cell) GetStyle() *Style {
	return c.style
}

// SetStyle sets the style of a cell.
func (c *Cell) SetStyle(style *Style) {
	c.style = style
}

// The number format string is returnable from a cell.
func (c *Cell) GetNumberFormat() string {
	return c.numFmt
}

func (c *Cell) formatToTime(format string) string {
	f, err := strconv.ParseFloat(c.Value, 64)
	if err != nil {
		return err.Error()
	}
	return TimeFromExcelTime(f, c.date1904).Format(format)
}

func (c *Cell) formatToFloat(format string) string {
	f, err := strconv.ParseFloat(c.Value, 64)
	if err != nil {
		return err.Error()
	}
	return fmt.Sprintf(format, f)
}

func (c *Cell) formatToInt(format string) string {
	f, err := strconv.ParseFloat(c.Value, 64)
	if err != nil {
		return err.Error()
	}
	return fmt.Sprintf(format, int(f))
}

// Return the formatted version of the value.
func (c *Cell) FormattedValue() string {
	var numberFormat string = c.GetNumberFormat()
	isText := numberFormat == "general" || numberFormat == "@"
	if (c.Type() == CellTypeString) && isText {
		return c.Value
	}
	switch numberFormat {
	case "general":
		return c.Value
	case "0", "#,##0":
		return c.formatToInt("%d")
	case "0.00", "#,##0.00", "@":
		return c.formatToFloat("%.2f")
	case "#,##0 ;(#,##0)", "#,##0 ;[red](#,##0)":
		f, err := strconv.ParseFloat(c.Value, 64)
		if err != nil {
			return err.Error()
		}
		if f < 0 {
			i := int(math.Abs(f))
			return fmt.Sprintf("(%d)", i)
		}
		i := int(f)
		return fmt.Sprintf("%d", i)
	case "#,##0.00;(#,##0.00)", "#,##0.00;[red](#,##0.00)":
		f, err := strconv.ParseFloat(c.Value, 64)
		if err != nil {
			return err.Error()
		}
		if f < 0 {
			return fmt.Sprintf("(%.2f)", f)
		}
		return fmt.Sprintf("%.2f", f)
	case "0%":
		f, err := strconv.ParseFloat(c.Value, 64)
		if err != nil {
			return err.Error()
		}
		f = f * 100
		return fmt.Sprintf("%d%%", int(f))
	case "0.00%":
		f, err := strconv.ParseFloat(c.Value, 64)
		if err != nil {
			return err.Error()
		}
		f = f * 100
		return fmt.Sprintf("%.2f%%", f)
	case "0.00e+00", "##0.0e+0":
		return c.formatToFloat("%e")
	case "mm-dd-yy":
		return c.formatToTime("01-02-06")
	case "d-mmm-yy":
		return c.formatToTime("2-Jan-06")
	case "d-mmm":
		return c.formatToTime("2-Jan")
	case "mmm-yy":
		return c.formatToTime("Jan-06")
	case "h:mm am/pm":
		return c.formatToTime("3:04 pm")
	case "h:mm:ss am/pm":
		return c.formatToTime("3:04:05 pm")
	case "h:mm":
		return c.formatToTime("15:04")
	case "h:mm:ss":
		return c.formatToTime("15:04:05")
	case "m/d/yy h:mm":
		return c.formatToTime("1/2/06 15:04")
	case "mm:ss":
		return c.formatToTime("04:05")
	case "[h]:mm:ss":
		f, err := strconv.ParseFloat(c.Value, 64)
		if err != nil {
			return err.Error()
		}
		t := TimeFromExcelTime(f, c.date1904)
		if t.Hour() > 0 {
			return t.Format("15:04:05")
		}
		return t.Format("04:05")
	case "mmss.0":
		f, err := strconv.ParseFloat(c.Value, 64)
		if err != nil {
			return err.Error()
		}
		t := TimeFromExcelTime(f, c.date1904)
		return fmt.Sprintf("%0d%0d.%d", t.Minute(), t.Second(), t.Nanosecond()/1000)

	case "yyyy\\-mm\\-dd":
		return c.formatToTime("2006\\-01\\-02")
	case "dd/mm/yy":
		return c.formatToTime("02/01/06")
	case "hh:mm:ss":
		return c.formatToTime("15:04:05")
	case "dd/mm/yy\\ hh:mm":
		return c.formatToTime("02/01/06\\ 15:04")
	case "dd/mm/yyyy hh:mm:ss":
		return c.formatToTime("02/01/2006 15:04:05")
	case "yy-mm-dd":
		return c.formatToTime("06-01-02")
	case "d-mmm-yyyy":
		return c.formatToTime("2-Jan-2006")
	case "m/d/yy":
		return c.formatToTime("1/2/06")
	case "m/d/yyyy":
		return c.formatToTime("1/2/2006")
	case "dd-mmm-yyyy":
		return c.formatToTime("02-Jan-2006")
	case "dd/mm/yyyy":
		return c.formatToTime("02/01/2006")
	case "mm/dd/yy hh:mm am/pm":
		return c.formatToTime("01/02/06 03:04 pm")
	case "mm/dd/yyyy hh:mm:ss":
		return c.formatToTime("01/02/2006 15:04:05")
	case "yyyy-mm-dd hh:mm:ss":
		return c.formatToTime("2006-01-02 15:04:05")
	}
	return c.Value
}
<|endoftext|>