<commit_before>//GstQuery — Provide functions to create queries, and to set and parse values in them.
package gst

/*
#include <gst/gst.h>
*/
import "C"

import (
	"github.com/lidouf/glib"
	"time"
)

type QueryTypeFlags C.GstQueryTypeFlags

const (
	QUERY_TYPE_UPSTREAM = 1 << iota
	QUERY_TYPE_DOWNSTREAM
	QUERY_TYPE_SERIALIZED
)

//type Query C.GstQuery
type Query struct {
	glib.Object
}

func (q *Query) g() *C.GstQuery {
	return (*C.GstQuery)(q.GetPtr())
}

func (q *Query) AsQuery() *Query {
	return q
}

func (q *Query) ParseSeeking(format *Format) (bool, time.Duration, time.Duration) {
	var seekable C.gboolean
	var start, end C.gint64
	if format == nil {
		C.gst_query_parse_seeking(q.g(), nil, &seekable, &start, &end)
	} else {
		C.gst_query_parse_seeking(q.g(), format.g(), &seekable, &start, &end)
	}

	return seekable == 1, (time.Duration)(start), (time.Duration)(end)
}

func (q *Query) Unref() {
	C.gst_query_unref(q.g())
}

func NewQuerySeeking(format Format) *Query {
	seeking := C.gst_query_new_seeking(*(format.g()))
	if seeking == nil {
		return nil
	}
	q := new(Query)
	q.SetPtr(glib.Pointer(seeking))
	return q
}
<commit_msg>add some implementations for query<commit_after>//GstQuery — Provide functions to create queries, and to set and parse values in them.
package gst

/*
#include <gst/gst.h>
*/
import "C"

import (
	"github.com/lidouf/glib"
	"time"
)

type QueryTypeFlags C.GstQueryTypeFlags

const (
	QUERY_TYPE_UPSTREAM = 1 << iota
	QUERY_TYPE_DOWNSTREAM
	QUERY_TYPE_SERIALIZED
)

//type Query C.GstQuery
type Query struct {
	glib.Object
}

func (q *Query) g() *C.GstQuery {
	return (*C.GstQuery)(q.GetPtr())
}

func (q *Query) AsQuery() *Query {
	return q
}

func (q *Query) ParseSeeking(format *Format) (bool, time.Duration, time.Duration) {
	var seekable C.gboolean
	var start, end C.gint64
	if format == nil {
		C.gst_query_parse_seeking(q.g(), nil, &seekable, &start, &end)
	} else {
		C.gst_query_parse_seeking(q.g(), format.g(), &seekable, &start, &end)
	}

	return seekable == 1, (time.Duration)(start), (time.Duration)(end)
}

func (q *Query) GetNBufferingRanges() int {
	return int(C.gst_query_get_n_buffering_ranges(q.g()))
}

func (q *Query) ParseNthBufferingRange(r uint) (int64, int64) {
	var start, stop C.gint64
	C.gst_query_parse_nth_buffering_range(q.g(), C.guint(r), &start, &stop)
	return int64(start), int64(stop)
}

func (q *Query) Unref() {
	C.gst_query_unref(q.g())
}

func NewQuerySeeking(format Format) *Query {
	seeking := C.gst_query_new_seeking(*(format.g()))
	if seeking == nil {
		return nil
	}
	q := new(Query)
	q.SetPtr(glib.Pointer(seeking))
	return q
}

func NewQueryBuffering(format Format) *Query {
	buffering := C.gst_query_new_buffering(*(format.g()))
	if buffering == nil {
		return nil
	}
	q := new(Query)
	q.SetPtr(glib.Pointer(buffering))
	return q
}
<|endoftext|>


<commit_before>// Package radix is a simple redis driver. This top-level package is a wrapper
// for its sub-packages and doesn't actually contain an code. You likely want to
// look at the redis sub-package for a straightforward redis client
package radix
<commit_msg>fixed typo<commit_after>// Package radix is a simple redis driver. This top-level package is a wrapper
// for its sub-packages and doesn't actually contain any code. You likely want
// to look at the redis sub-package for a straightforward redis client
package radix
<|endoftext|>


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

package main

import (
	"bytes"
	"errors"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"time"

	"go/build"
)

var (
	do_tests = flag.Bool("test", false, "Run tests (before running program)")
	do_build = flag.Bool("build", false, "Build program")
)

func buildpathDir(buildpath string) (string, error) {
	pkg, err := build.Import(buildpath, "", 0)

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

	if pkg.Goroot {
		return "", err
	}

	return pkg.Dir, nil
}

type scanCallback func(path string)

func scanChanges(path string, cb scanCallback) {
	last := time.Now()

	for {
		filepath.Walk(path, func(p string, info os.FileInfo, err error) error {
			if info.ModTime().After(last) {
				cb(path)
				last = time.Now()
			}
			return nil
		})

		time.Sleep(500 * time.Millisecond)
	}
}

func log(format string, args ...interface{}) {
	fmt.Printf("[rerun] %s", fmt.Sprintf(format+"\n", args...))
}

func gobuild(buildpath string) (bool, error) {
	cmd := exec.Command("go", "build", "-v", buildpath)

	buf := bytes.NewBuffer([]byte{})
	cmd.Stdout = buf
	cmd.Stderr = buf

	if err := cmd.Run(); err != nil {
		log("build failed")
		fmt.Println(buf.String())
		return false, err
	}

	log("build succeeded")
	return true, nil
}

func goinstall(buildpath string) (bool, error) {
	cmd := exec.Command("go", "get", buildpath)

	buf := bytes.NewBuffer([]byte{})
	cmd.Stdout = buf
	cmd.Stderr = buf

	if err := cmd.Run(); err != nil {
		log("install failed")
		fmt.Println(buf.String())
		return false, err
	}

	log("install succeeded")
	return true, nil
}

func gotest(buildpath string) (bool, error) {
	cmd := exec.Command("go", "test", "-v", buildpath)

	buf := bytes.NewBuffer([]byte{})
	cmd.Stdout = buf
	cmd.Stderr = buf

	if err := cmd.Run(); err != nil {
		log("tests failed")
		fmt.Println(buf.String())
		return false, err
	}

	log("tests passed")
	return true, nil
}

func run(ch chan bool, bin string, args []string) {
	go func() {
		var proc *os.Process

		for relaunch := range ch {
			if proc != nil {
				if err := proc.Signal(os.Interrupt); err != nil {
					log("error on sending signal to process: '%s', will now hard-kill the process", err)
					proc.Kill()
				}
				proc.Wait()
			}

			if !relaunch {
				continue
			}

			cmd := exec.Command(bin, args...)
			cmd.Stdout = os.Stdout
			cmd.Stderr = os.Stderr

			if err := cmd.Start(); err != nil {
				log("error: %s", err)
			}

			proc = cmd.Process
		}
	}()
	return
}

func refresh(buildpath string, ch chan bool) {
	if *do_tests {
		if ok, _ := gotest(buildpath); !ok {
			ch <- false
			return
		}
	}

	if *do_build {
		if ok, _ := gobuild(buildpath); !ok {
			ch <- false
			return
		}
	}

	// if ok, _ := goinstall(buildpath); !ok {
	//   ch <- false
	//   return
	// }

	ch <- true
	return
}

func rerun(buildpath string, args []string) (err error) {
	pkg, err := build.Import(buildpath, "", 0)
	if err != nil {
		return
	}

	if pkg.Name != "main" {
		err = errors.New(fmt.Sprintf("expected package %q, got %q", "main", pkg.Name))
		return
	}

	_, name := path.Split(buildpath)
	bin := filepath.Join(pkg.BinDir, name)

	ch := make(chan bool)
	go run(ch, bin, args)

	refresh(buildpath, ch)

	dir, err := buildpathDir(buildpath)
	if err != nil {
		return
	}

	scanChanges(dir, func(path string) {
		refresh(buildpath, ch)
	})

	return
}

func main() {
	flag.Parse()

	if len(flag.Args()) < 1 {
		fmt.Println("Usage: rerun [--test] [--no-run] [--build] [--race] <import path> [arg]*")
		os.Exit(1)
	}

	buildpath := flag.Args()[0]
	args := flag.Args()[1:]

	if err := rerun(buildpath, args); err != nil {
		log("error: %s", err)
	}
}
<commit_msg>install<commit_after>// Copyright 2013 The rerun AUTHORS. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"bytes"
	"errors"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"time"

	"go/build"
)

var (
	do_tests = flag.Bool("test", false, "Run tests (before running program)")
	do_build = flag.Bool("build", false, "Build program")
)

func buildpathDir(buildpath string) (string, error) {
	pkg, err := build.Import(buildpath, "", 0)

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

	if pkg.Goroot {
		return "", err
	}

	return pkg.Dir, nil
}

type scanCallback func(path string)

func scanChanges(path string, cb scanCallback) {
	last := time.Now()

	for {
		filepath.Walk(path, func(p string, info os.FileInfo, err error) error {
			if info.ModTime().After(last) {
				cb(path)
				last = time.Now()
			}
			return nil
		})

		time.Sleep(500 * time.Millisecond)
	}
}

func log(format string, args ...interface{}) {
	fmt.Printf("[rerun] %s", fmt.Sprintf(format+"\n", args...))
}

func gobuild(buildpath string) (bool, error) {
	cmd := exec.Command("go", "build", "-v", buildpath)

	buf := bytes.NewBuffer([]byte{})
	cmd.Stdout = buf
	cmd.Stderr = buf

	if err := cmd.Run(); err != nil {
		log("build failed")
		fmt.Println(buf.String())
		return false, err
	}

	log("build succeeded")
	return true, nil
}

func goinstall(buildpath string) (bool, error) {
	cmd := exec.Command("go", "get", buildpath)

	buf := bytes.NewBuffer([]byte{})
	cmd.Stdout = buf
	cmd.Stderr = buf

	if err := cmd.Run(); err != nil {
		log("install failed")
		fmt.Println(buf.String())
		return false, err
	}

	log("install succeeded")
	return true, nil
}

func gotest(buildpath string) (bool, error) {
	cmd := exec.Command("go", "test", "-v", buildpath)

	buf := bytes.NewBuffer([]byte{})
	cmd.Stdout = buf
	cmd.Stderr = buf

	if err := cmd.Run(); err != nil {
		log("tests failed")
		fmt.Println(buf.String())
		return false, err
	}

	log("tests passed")
	return true, nil
}

func run(ch chan bool, bin string, args []string) {
	go func() {
		var proc *os.Process

		for relaunch := range ch {
			if proc != nil {
				if err := proc.Signal(os.Interrupt); err != nil {
					log("error on sending signal to process: '%s', will now hard-kill the process", err)
					proc.Kill()
				}
				proc.Wait()
			}

			if !relaunch {
				continue
			}

			cmd := exec.Command(bin, args...)
			cmd.Stdout = os.Stdout
			cmd.Stderr = os.Stderr

			if err := cmd.Start(); err != nil {
				log("error: %s", err)
			}

			proc = cmd.Process
		}
	}()
	return
}

func refresh(buildpath string, ch chan bool) {
	if *do_tests {
		if ok, _ := gotest(buildpath); !ok {
			ch <- false
			return
		}
	}

	if *do_build {
		if ok, _ := gobuild(buildpath); !ok {
			ch <- false
			return
		}
	}

	if ok, _ := goinstall(buildpath); !ok {
		ch <- false
		return
	}

	ch <- true
	return
}

func rerun(buildpath string, args []string) (err error) {
	pkg, err := build.Import(buildpath, "", 0)
	if err != nil {
		return
	}

	if pkg.Name != "main" {
		err = errors.New(fmt.Sprintf("expected package %q, got %q", "main", pkg.Name))
		return
	}

	_, name := path.Split(buildpath)
	bin := filepath.Join(pkg.BinDir, name)

	ch := make(chan bool)
	go run(ch, bin, args)

	refresh(buildpath, ch)

	dir, err := buildpathDir(buildpath)
	if err != nil {
		return
	}

	scanChanges(dir, func(path string) {
		refresh(buildpath, ch)
	})

	return
}

func main() {
	flag.Parse()

	if len(flag.Args()) < 1 {
		fmt.Println("Usage: rerun [--test] [--no-run] [--build] [--race] <import path> [arg]*")
		os.Exit(1)
	}

	buildpath := flag.Args()[0]
	args := flag.Args()[1:]

	if err := rerun(buildpath, args); err != nil {
		log("error: %s", err)
	}
}
<|endoftext|>


<commit_before>package netlink

import (
	"fmt"
	"net"
	"syscall"
)

// Scope is an enum representing a route scope.
type Scope uint8

const (
	SCOPE_UNIVERSE Scope = syscall.RT_SCOPE_UNIVERSE
	SCOPE_SITE     Scope = syscall.RT_SCOPE_SITE
	SCOPE_LINK     Scope = syscall.RT_SCOPE_LINK
	SCOPE_HOST     Scope = syscall.RT_SCOPE_HOST
	SCOPE_NOWHERE  Scope = syscall.RT_SCOPE_NOWHERE
)

type NextHopFlag int

const (
	FLAG_ONLINK    NextHopFlag = syscall.RTNH_F_ONLINK
	FLAG_PERVASIVE NextHopFlag = syscall.RTNH_F_PERVASIVE
)

// Route represents a netlink route.
type Route struct {
	LinkIndex  int
	ILinkIndex int
	Scope      Scope
	Dst        *net.IPNet
	Src        net.IP
	Gw         net.IP
	Protocol   int
	Priority   int
	Table      int
	Type       int
	Tos        int
	Flags      int
}

func (r Route) String() string {
	return fmt.Sprintf("{Ifindex: %d Dst: %s Src: %s Gw: %s Flags: %s}", r.LinkIndex, r.Dst,
		r.Src, r.Gw, r.ListFlags())
}

func (r *Route) SetFlag(flag NextHopFlag) {
	r.Flags |= int(flag)
}

func (r *Route) ClearFlag(flag NextHopFlag) {
	r.Flags &^= int(flag)
}

type flagString struct {
	f NextHopFlag
	s string
}

var testFlags = []flagString{
	{f: FLAG_ONLINK, s: "onlink"},
	{f: FLAG_PERVASIVE, s: "pervasive"},
}

func (r *Route) ListFlags() []string {
	var flags []string
	for _, tf := range testFlags {
		if r.Flags&int(tf.f) != 0 {
			flags = append(flags, tf.s)
		}
	}
	return flags
}

// RouteUpdate is sent when a route changes - type is RTM_NEWROUTE or RTM_DELROUTE
type RouteUpdate struct {
	Type uint16
	Route
}
<commit_msg>Add route table number as significant info about route object (#103)<commit_after>package netlink

import (
	"fmt"
	"net"
	"syscall"
)

// Scope is an enum representing a route scope.
type Scope uint8

const (
	SCOPE_UNIVERSE Scope = syscall.RT_SCOPE_UNIVERSE
	SCOPE_SITE     Scope = syscall.RT_SCOPE_SITE
	SCOPE_LINK     Scope = syscall.RT_SCOPE_LINK
	SCOPE_HOST     Scope = syscall.RT_SCOPE_HOST
	SCOPE_NOWHERE  Scope = syscall.RT_SCOPE_NOWHERE
)

type NextHopFlag int

const (
	FLAG_ONLINK    NextHopFlag = syscall.RTNH_F_ONLINK
	FLAG_PERVASIVE NextHopFlag = syscall.RTNH_F_PERVASIVE
)

// Route represents a netlink route.
type Route struct {
	LinkIndex  int
	ILinkIndex int
	Scope      Scope
	Dst        *net.IPNet
	Src        net.IP
	Gw         net.IP
	Protocol   int
	Priority   int
	Table      int
	Type       int
	Tos        int
	Flags      int
}

func (r Route) String() string {
	return fmt.Sprintf("{Ifindex: %d Dst: %s Src: %s Gw: %s Flags: %s Table: %d}", r.LinkIndex, r.Dst,
		r.Src, r.Gw, r.ListFlags(), r.Table)
}

func (r *Route) SetFlag(flag NextHopFlag) {
	r.Flags |= int(flag)
}

func (r *Route) ClearFlag(flag NextHopFlag) {
	r.Flags &^= int(flag)
}

type flagString struct {
	f NextHopFlag
	s string
}

var testFlags = []flagString{
	{f: FLAG_ONLINK, s: "onlink"},
	{f: FLAG_PERVASIVE, s: "pervasive"},
}

func (r *Route) ListFlags() []string {
	var flags []string
	for _, tf := range testFlags {
		if r.Flags&int(tf.f) != 0 {
			flags = append(flags, tf.s)
		}
	}
	return flags
}

// RouteUpdate is sent when a route changes - type is RTM_NEWROUTE or RTM_DELROUTE
type RouteUpdate struct {
	Type uint16
	Route
}
<|endoftext|>


<commit_before>// The RS232 package lets you access old serial junk from go
package rs232

/*
#include <stdlib.h>
#include <fcntl.h>
#include <termios.h>
*/
import "C"

import (
	"os"
	"syscall"
)

// This is your serial port handle.
type SerialPort struct {
	port *os.File
}

func baudConversion(rate int) (flag _Ctype_speed_t) {
	if C.B9600 != 9600 {
		panic("Baud rates may not map directly.")
	}
	return _Ctype_speed_t(rate)
}

// SerConf represents the basic serial configuration to provide to OpenPort.
type SerConf int

const (
	S_8N1 = iota
	S_7E1
	S_7O1
)

// Opens and returns a non-blocking serial port.
// The device, baud rate, and SerConf is specified.
//
// Example:  rs232.OpenPort("/dev/ttyS0", 115200, rs232.S_8N1)
func OpenPort(port string, baudRate int, serconf SerConf) (rv SerialPort, err error) {
	f, open_err := os.OpenFile(port,
		syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NDELAY,
		0666)
	if open_err != nil {
		err = open_err
		return
	}
	rv.port = f

	fd := rv.port.Fd()

	var options C.struct_termios
	if C.tcgetattr(C.int(fd), &options) < 0 {
		panic("tcgetattr failed")
	}

	if C.cfsetispeed(&options, baudConversion(baudRate)) < 0 {
		panic("cfsetispeed failed")
	}
	if C.cfsetospeed(&options, baudConversion(baudRate)) < 0 {
		panic("cfsetospeed failed")
	}
	switch serconf {
	case S_8N1:
		{
			options.c_cflag &^= C.PARENB
			options.c_cflag &^= C.CSTOPB
			options.c_cflag &^= C.CSIZE
			options.c_cflag |= C.CS8
		}
	case S_7E1:
		{
			options.c_cflag |= C.PARENB
			options.c_cflag &^= C.PARODD
			options.c_cflag &^= C.CSTOPB
			options.c_cflag &^= C.CSIZE
			options.c_cflag |= C.CS7
		}
	case S_7O1:
		{
			options.c_cflag |= C.PARENB
			options.c_cflag |= C.PARODD
			options.c_cflag &^= C.CSTOPB
			options.c_cflag &^= C.CSIZE
			options.c_cflag |= C.CS7
		}
	}
	// Local
	options.c_cflag |= (C.CLOCAL | C.CREAD)
	// no hardware flow control
	options.c_cflag &^= C.CRTSCTS

	if C.tcsetattr(C.int(fd), C.TCSANOW, &options) < 0 {
		panic("tcsetattr failed")
	}

	if syscall.SetNonblock(int(fd), false) != nil {
		panic("Error disabling blocking")
	}

	return
}

// Read from the port.
func (port *SerialPort) Read(p []byte) (n int, err error) {
	return port.port.Read(p)
}

// Write to the port.
func (port *SerialPort) Write(p []byte) (n int, err error) {
	return port.port.Write(p)
}

// Close the port.
func (port *SerialPort) Close() error {
	return port.port.Close()
}
<commit_msg>Found a platform that didn't map baud rates sanely.<commit_after>// The RS232 package lets you access old serial junk from go
package rs232

/*
#include <stdlib.h>
#include <fcntl.h>
#include <termios.h>
*/
import "C"

import (
	"os"
	"syscall"
)

var baudConversionMap = map[int]_Ctype_speed_t{}

// This is your serial port handle.
type SerialPort struct {
	port *os.File
}

func init() {
	baudConversionMap[0] = C.B0
	baudConversionMap[50] = C.B50
	baudConversionMap[75] = C.B75
	baudConversionMap[110] = C.B110
	baudConversionMap[134] = C.B134
	baudConversionMap[150] = C.B150
	baudConversionMap[200] = C.B200
	baudConversionMap[300] = C.B300
	baudConversionMap[600] = C.B600
	baudConversionMap[1200] = C.B1200
	baudConversionMap[1800] = C.B1800
	baudConversionMap[2400] = C.B2400
	baudConversionMap[4800] = C.B4800
	baudConversionMap[9600] = C.B9600
	baudConversionMap[19200] = C.B19200
	baudConversionMap[38400] = C.B38400
	// baudConversionMap[7200] = C.B7200
	// baudConversionMap[14400] = C.B14400
	// baudConversionMap[28800] = C.B28800
	baudConversionMap[57600] = C.B57600
	// baudConversionMap[76800] = C.B76800
	baudConversionMap[115200] = C.B115200
	baudConversionMap[230400] = C.B230400
}

func baudConversion(rate int) (flag _Ctype_speed_t) {
	return baudConversionMap[rate]
}

// SerConf represents the basic serial configuration to provide to OpenPort.
type SerConf int

const (
	S_8N1 = iota
	S_7E1
	S_7O1
)

// Opens and returns a non-blocking serial port.
// The device, baud rate, and SerConf is specified.
//
// Example:  rs232.OpenPort("/dev/ttyS0", 115200, rs232.S_8N1)
func OpenPort(port string, baudRate int, serconf SerConf) (rv SerialPort, err error) {
	f, open_err := os.OpenFile(port,
		syscall.O_RDWR|syscall.O_NOCTTY|syscall.O_NDELAY,
		0666)
	if open_err != nil {
		err = open_err
		return
	}
	rv.port = f

	fd := rv.port.Fd()

	var options C.struct_termios
	if C.tcgetattr(C.int(fd), &options) < 0 {
		panic("tcgetattr failed")
	}

	if C.cfsetispeed(&options, baudConversion(baudRate)) < 0 {
		panic("cfsetispeed failed")
	}
	if C.cfsetospeed(&options, baudConversion(baudRate)) < 0 {
		panic("cfsetospeed failed")
	}
	switch serconf {
	case S_8N1:
		{
			options.c_cflag &^= C.PARENB
			options.c_cflag &^= C.CSTOPB
			options.c_cflag &^= C.CSIZE
			options.c_cflag |= C.CS8
		}
	case S_7E1:
		{
			options.c_cflag |= C.PARENB
			options.c_cflag &^= C.PARODD
			options.c_cflag &^= C.CSTOPB
			options.c_cflag &^= C.CSIZE
			options.c_cflag |= C.CS7
		}
	case S_7O1:
		{
			options.c_cflag |= C.PARENB
			options.c_cflag |= C.PARODD
			options.c_cflag &^= C.CSTOPB
			options.c_cflag &^= C.CSIZE
			options.c_cflag |= C.CS7
		}
	}
	// Local
	options.c_cflag |= (C.CLOCAL | C.CREAD)
	// no hardware flow control
	options.c_cflag &^= C.CRTSCTS

	if C.tcsetattr(C.int(fd), C.TCSANOW, &options) < 0 {
		panic("tcsetattr failed")
	}

	if syscall.SetNonblock(int(fd), false) != nil {
		panic("Error disabling blocking")
	}

	return
}

// Read from the port.
func (port *SerialPort) Read(p []byte) (n int, err error) {
	return port.port.Read(p)
}

// Write to the port.
func (port *SerialPort) Write(p []byte) (n int, err error) {
	return port.port.Write(p)
}

// Close the port.
func (port *SerialPort) Close() error {
	return port.port.Close()
}
<|endoftext|>


<commit_before>package s3

import (
	"net/http"

	"bytes"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/aws/aws-sdk-go/service/s3/s3manager"
	"github.com/eyecuelab/kit/log"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"io"
	"mime/multipart"
)

var uploder *s3manager.Uploader

func UploadFromForm(fileHeader *multipart.FileHeader, key string) (*s3manager.UploadOutput, error) {
	file, err := fileHeader.Open()
	if err != nil {
		return nil, err
	}

	var buffer bytes.Buffer
	io.Copy(&buffer, file)

	return Upload(buffer.Bytes(), key)
}

func Upload(b []byte, key string) (*s3manager.UploadOutput, error) {

	fileBytes := bytes.NewReader(b)
	fileType := http.DetectContentType(b)

	params := &s3manager.UploadInput{
		Bucket:      aws.String("lub-assets-test"),
		Key:         aws.String(key),
		Body:        fileBytes,
		ContentType: aws.String(fileType),
	}

	return uploder.Upload(params)
}

func newS3Client() *s3.S3 {
	awsAccessKey := viper.GetString("aws_access_key")
	awsSecret := viper.GetString("aws_secret")
	creds := credentials.NewStaticCredentials(awsAccessKey, awsSecret, "")
	_, err := creds.Get()
	log.Check(err)

	session, err := session.NewSession()
	log.Check(err)

	cfg := aws.NewConfig().WithRegion("us-west-1").WithCredentials(creds)
	return s3.New(session, cfg)
}

func setUploader() {
	uploder = s3manager.NewUploaderWithClient(newS3Client())
}

func init() {
	cobra.OnInitialize(setUploader)
}
<commit_msg>use s3 bucket from env<commit_after>package s3

import (
	"net/http"

	"bytes"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/credentials"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/aws/aws-sdk-go/service/s3/s3manager"
	"github.com/eyecuelab/kit/log"
	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"io"
	"mime/multipart"
)

var uploder *s3manager.Uploader

func UploadFromForm(fileHeader *multipart.FileHeader, key string) (*s3manager.UploadOutput, error) {
	file, err := fileHeader.Open()
	if err != nil {
		return nil, err
	}

	var buffer bytes.Buffer
	io.Copy(&buffer, file)

	return Upload(buffer.Bytes(), key)
}

func Upload(b []byte, key string) (*s3manager.UploadOutput, error) {

	fileBytes := bytes.NewReader(b)
	fileType := http.DetectContentType(b)

	params := &s3manager.UploadInput{
		Bucket:      aws.String(viper.GetString("aws_bucket")),
		Key:         aws.String(key),
		Body:        fileBytes,
		ContentType: aws.String(fileType),
	}

	return uploder.Upload(params)
}

func newS3Client() *s3.S3 {
	awsAccessKey := viper.GetString("aws_access_key")
	awsSecret := viper.GetString("aws_secret")
	creds := credentials.NewStaticCredentials(awsAccessKey, awsSecret, "")
	_, err := creds.Get()
	log.Check(err)

	session, err := session.NewSession()
	log.Check(err)

	cfg := aws.NewConfig().WithRegion("us-west-1").WithCredentials(creds)
	return s3.New(session, cfg)
}

func setUploader() {
	uploder = s3manager.NewUploaderWithClient(newS3Client())
}

func init() {
	cobra.OnInitialize(setUploader)
}
<|endoftext|>


<commit_before>// These will all be very flaky because they are dependent on actual
// filesystems.
package main

import (
	"crypto/rand"
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"
	"time"
)

const waitForMsg = 2 * time.Second

// Slow in the success case
func TestNoWatchingCreation(t *testing.T) {
	fs := newFS(t)
	fs.Create("foobar")
	ch := make(chan time.Time, 10)
	cleanUp := watchTest(fs, []string{fs.Abs("foobar")}, []string{}, ch)
	defer cleanUp()
	fs.Create("baz")
	seeNothing(fs, ch, "creation of baz")
}

// Slow in the success case
func TestSimpleWatch(t *testing.T) {
	fs := newFS(t)
	fs.Create("foobar")
	ch := make(chan time.Time, 10)
	cleanUp := watchTest(fs, []string{fs.Abs("foobar")}, []string{fs.Abs("baz")}, ch)
	defer cleanUp()
	fs.ChangeContents("foobar")
	seeChangeContents(fs, ch, "foobar")
	fs.Create("baz")
	seeNothing(fs, ch, "creation of baz")
}

func TestSimpleDirWatch(t *testing.T) {
	fs := newFS(t)
	fs.MkdirAll("simpleDir1")
	ch := make(chan time.Time, 10)
	cleanUp := watchTest(fs, []string{fs.Abs("simpleDir1")}, []string{}, ch)
	defer cleanUp()

	fs.Create("simpleDir1/foobar")
	seeCreation(fs, ch, "simpleDir1/foobar")
}

func TestCurrentDirWorks(t *testing.T) {
	fs := newFS(t)
	fs.Create("foobar")
	ch := make(chan time.Time, 10)
	cleanUp := watchTest(fs, []string{fs.Abs(".")}, nil, ch)
	defer cleanUp()
	fs.ChangeContents("foobar")
	seeChangeContents(fs, ch, "foobar")
	fs.Create("baz")
	seeCreation(fs, ch, "baz")
}

// Slow in the success case
func TestIgnoredDir(t *testing.T) {
	fs := newFS(t)
	fs.Create("foobar")
	fs.MkdirAll("existdir/quuxdir")
	ch := make(chan time.Time, 10)
	cleanUp := watchTest(fs, []string{fs.Abs(".")},
		[]string{
			fs.Abs("bardir"),
			fs.Abs("existdir"),
		},
		ch)
	defer cleanUp()

	fs.MkdirAll("bardir")
	fs.Create("bardir/barfile")
	fs.RemoveAll("bardir")
	fs.Create("existdir/level1")
	fs.Create("existdir/quuxdir/level2")
	fs.ChangeContents("existdir/level1")
	fs.ChangeContents("existdir/quuxdir/level2")
	seeNothing(fs, ch, "some ignored operations")
}

// Slow in the success case
func TestIgnoredDirOverlap(t *testing.T) {
	fs := newFS(t)
	fs.Create("foobar")
	fs.MkdirAll("existdir/quuxdir")
	ch := make(chan time.Time, 10)
	// The existdir and existdir/quuxdir cases seem silly but can
	// happen accidentally in shell globbing. Better to be consistent
	// about it.
	cleanUp := watchTest(fs,
		[]string{
			fs.Abs("."),
			fs.Abs("bardir"),
			fs.Abs("existdir/quuxdir"),
		},
		[]string{
			fs.Abs("bardir"),
			fs.Abs("existdir/quuxdir"),
		},
		ch)
	defer cleanUp()

	fs.MkdirAll("bardir")
	fs.Create("bardir/barfile")
	fs.Create("existdir/level1")
	fs.Create("existdir/quuxdir/level2")
	fs.ChangeContents("existdir/level1")
	fs.ChangeContents("existdir/quuxdir/level2")

	seeNothing(fs, ch, "some ignored operations")
}

func TestNoSubdirRecursionWithoutGlobs(t *testing.T) {
	fs := newFS(t)
	fs.MkdirAll("some_dir")
	ch := make(chan time.Time, 10)
	cleanUp := watchTest(fs, []string{fs.Abs(".")}, nil, ch)
	defer cleanUp()

	fs.Create("some_dir/level1")
	seeNothing(fs, ch, "creation in level1")
}

func TestRenameFile(t *testing.T) {
	fs := newFS(t)

	fs.Create("foobar")
	ch := make(chan time.Time, 10)

	cleanUp := watchTest(fs, []string{fs.Abs("foobar")}, []string{}, ch)
	defer cleanUp()
	renameTest(fs, ch, "foobar", "baz")
	renameTest(fs, ch, "baz", "foobar")
}

func TestRenameDir(t *testing.T) {
	fs := newFS(t)

	fs.MkdirAll("foodir")
	fs.Create("foodir/foobar")
	ch := make(chan time.Time, 10)

	cleanUp := watchTest(fs, []string{fs.Abs("foodir/foobar")}, []string{}, ch)
	defer cleanUp()
	renameTest(fs, ch, "foodir/foobar", "baz")
	renameTest(fs, ch, "baz", "foodir/foobar")
	renameTest(fs, ch, "foodir", "bardir")
	// TODO(jmhodges): this requires a better rename system than
	// fsnotify provides or watching every dang directory in the
	// entiry absolute path.
	// renameTest(fs, ch, "bardir", "foodir")
}

func TestHiddenFilesHiddenByDefault(t *testing.T) {
	fs := newFS(t)
	fs.MkdirAll("hDir1")
	fs.Create("hDir1/.hidden")
	fs.MkdirAll("hDir2")
	fs.MkdirAll("hDir3")
	fs.Create("hDir3/.hiddenAndIgnored")
	ch := make(chan time.Time, 10)
	cleanUp := watchTest(fs,
		[]string{fs.Abs("hDir1/.hidden"), fs.Abs("hDir2")},
		[]string{fs.Abs("hDir3/.hiddenAndIgnored")},
		ch)
	defer cleanUp()

	fs.ChangeContents("hDir1/.hidden")
	seeChangeContents(fs, ch, "hDir1/.hidden")
	fs.Create("hDir2/.hidden")
	seeNothing(fs, ch, "no hidden file creation")
	fs.ChangeContents("hDir3/.hiddenAndIgnored")
	seeNothing(fs, ch, "no event for changes to hDir3/.hiddenAndIgnored")
}

func renameTest(fs *fileSystem, ch <-chan time.Time, oldpath, newpath string) {
	fs.Rename(oldpath, newpath)
	seeRename(fs, ch, oldpath, newpath)
}

func seeRename(fs *fileSystem, ch <-chan time.Time, oldpath, newpath string) {
	select {
	case <-ch:
		fs.t.Logf("successful catch of rename ('%s' -> '%s')", oldpath, newpath)
	case <-time.After(waitForMsg):
		fs.t.Errorf("did not see rename ('%s' -> '%s')", oldpath, newpath)
	}
}

func seeNothing(fs *fileSystem, ch <-chan time.Time, msg string) {
	select {
	case <-ch:
		fs.t.Errorf("should not have seen anything but saw: %s", msg)
	case <-time.After(waitForMsg):
		fs.t.Logf("successfully saw nothing for '%s'", msg)
	}
}

func seeCreation(fs *fileSystem, ch <-chan time.Time, path string) {
	select {
	case <-ch:
		fs.t.Logf("successful catch of creation of '%s'", path)

	case <-time.After(waitForMsg):
		fs.t.Errorf("did not see creation of '%s'", path)

	}
}

func seeChangeContents(fs *fileSystem, ch <-chan time.Time, path string) {
	select {
	case <-ch:
		fs.t.Logf("successful catch of first event (MODIFY|ATTRIB) for changing contents of '%s'", path)
	case <-time.After(waitForMsg):
		fs.t.Errorf("did not see content change of '%s'", path)
	}
	select {
	case <-ch:
		fs.t.Logf("successful catch of second event (MODIFY) for changing contents of '%s'", path)
	case <-time.After(waitForMsg):
		fs.t.Errorf("did not see content change of '%s'", path)
	}
}

func watchTest(fs *fileSystem, inputPaths, ignoredPaths []string, cmdCh chan<- time.Time) func() {
	w, err := watch(inputPaths, ignoredPaths, cmdCh)
	if err != nil {
		fs.t.Fatalf("unable to run watch: %#v", err)
		return func() {}
	}
	return func() {
		w.Close()
		fs.Close()
	}
}

func newFS(t *testing.T) *fileSystem {
	name, err := ioutil.TempDir("", "justrun_tests_")
	subdir := filepath.Join(name, "subdir_for_fds")
	os.MkdirAll(subdir, 0700)
	if err != nil {
		t.Fatalf("unable to create temporary directory")
	}
	return &fileSystem{name: subdir, t: t}
}

type fileSystem struct {
	name string
	t    *testing.T
}

func (fs *fileSystem) Create(path string) {
	fullName := filepath.Join(fs.name, path)
	// O_SYNC is important
	f, err := os.OpenFile(fullName, os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_SYNC, 0666)
	if err != nil {
		fs.t.Fatalf("unable to create '%s' in '%s': %#v", path, fs.name, err)
	}
	f.Close()
}

func (fs *fileSystem) MkdirAll(path string) {
	fullName := filepath.Join(fs.name, path)
	err := os.MkdirAll(fullName, 0700)
	if err != nil {
		fs.t.Fatalf("unable to create directory '%s' in '%s': %#v", path, fs.name, err)
	}
}

func (fs *fileSystem) Rename(oldpath, newpath string) {
	err := os.Rename(filepath.Join(fs.name, oldpath), filepath.Join(fs.name, newpath))
	if err != nil {
		fs.t.Fatalf("unable to rename '%s' to '%s' in '%s'", oldpath, newpath, fs.name)
	}
}

func (fs *fileSystem) Abs(path string) string {
	return filepath.Join(fs.name, path)
}

func (fs *fileSystem) RemoveAll(path string) {
	if err := os.RemoveAll(path); err != nil {
		fs.t.Fatalf("unable to delete '%s': %s", path, err)
	}
}

func (fs *fileSystem) ChangeContents(path string) {
	fullName := filepath.Join(fs.name, path)
	b := make([]byte, 16)
	_, err := rand.Read(b)
	if err != nil {
		fs.t.Fatalf("unable to get random data to change the contents of '%s': %s", path, err)
	}

	f, err := os.OpenFile(fullName, os.O_WRONLY|os.O_SYNC|os.O_TRUNC, 0666)
	if err != nil {
		fs.t.Fatalf("unable to open '%s' to change its contents: %s", path, err)
	}
	defer f.Close()
	n, err := f.Write(b)
	if err != nil {
		fs.t.Fatalf("unable to write new contents to '%s': %s", path, err)
	}
	if n < len(b) {
		fs.t.Fatalf("unable to write all contents to '%s'", path)
	}
}

func (fs *fileSystem) Close() {
	err := os.RemoveAll(fs.name)
	if err != nil {
		fs.t.Fatalf("unable to delete directory '%s'", fs.name)
	}
}
<commit_msg>correct error handling of tempdir in tests<commit_after>// These will all be very flaky because they are dependent on actual
// filesystems.
package main

import (
	"crypto/rand"
	"io/ioutil"
	"os"
	"path/filepath"
	"testing"
	"time"
)

const waitForMsg = 2 * time.Second

// Slow in the success case
func TestNoWatchingCreation(t *testing.T) {
	fs := newFS(t)
	fs.Create("foobar")
	ch := make(chan time.Time, 10)
	cleanUp := watchTest(fs, []string{fs.Abs("foobar")}, []string{}, ch)
	defer cleanUp()
	fs.Create("baz")
	seeNothing(fs, ch, "creation of baz")
}

// Slow in the success case
func TestSimpleWatch(t *testing.T) {
	fs := newFS(t)
	fs.Create("foobar")
	ch := make(chan time.Time, 10)
	cleanUp := watchTest(fs, []string{fs.Abs("foobar")}, []string{fs.Abs("baz")}, ch)
	defer cleanUp()
	fs.ChangeContents("foobar")
	seeChangeContents(fs, ch, "foobar")
	fs.Create("baz")
	seeNothing(fs, ch, "creation of baz")
}

func TestSimpleDirWatch(t *testing.T) {
	fs := newFS(t)
	fs.MkdirAll("simpleDir1")
	ch := make(chan time.Time, 10)
	cleanUp := watchTest(fs, []string{fs.Abs("simpleDir1")}, []string{}, ch)
	defer cleanUp()

	fs.Create("simpleDir1/foobar")
	seeCreation(fs, ch, "simpleDir1/foobar")
}

func TestCurrentDirWorks(t *testing.T) {
	fs := newFS(t)
	fs.Create("foobar")
	ch := make(chan time.Time, 10)
	cleanUp := watchTest(fs, []string{fs.Abs(".")}, nil, ch)
	defer cleanUp()
	fs.ChangeContents("foobar")
	seeChangeContents(fs, ch, "foobar")
	fs.Create("baz")
	seeCreation(fs, ch, "baz")
}

// Slow in the success case
func TestIgnoredDir(t *testing.T) {
	fs := newFS(t)
	fs.Create("foobar")
	fs.MkdirAll("existdir/quuxdir")
	ch := make(chan time.Time, 10)
	cleanUp := watchTest(fs, []string{fs.Abs(".")},
		[]string{
			fs.Abs("bardir"),
			fs.Abs("existdir"),
		},
		ch)
	defer cleanUp()

	fs.MkdirAll("bardir")
	fs.Create("bardir/barfile")
	fs.RemoveAll("bardir")
	fs.Create("existdir/level1")
	fs.Create("existdir/quuxdir/level2")
	fs.ChangeContents("existdir/level1")
	fs.ChangeContents("existdir/quuxdir/level2")
	seeNothing(fs, ch, "some ignored operations")
}

// Slow in the success case
func TestIgnoredDirOverlap(t *testing.T) {
	fs := newFS(t)
	fs.Create("foobar")
	fs.MkdirAll("existdir/quuxdir")
	ch := make(chan time.Time, 10)
	// The existdir and existdir/quuxdir cases seem silly but can
	// happen accidentally in shell globbing. Better to be consistent
	// about it.
	cleanUp := watchTest(fs,
		[]string{
			fs.Abs("."),
			fs.Abs("bardir"),
			fs.Abs("existdir/quuxdir"),
		},
		[]string{
			fs.Abs("bardir"),
			fs.Abs("existdir/quuxdir"),
		},
		ch)
	defer cleanUp()

	fs.MkdirAll("bardir")
	fs.Create("bardir/barfile")
	fs.Create("existdir/level1")
	fs.Create("existdir/quuxdir/level2")
	fs.ChangeContents("existdir/level1")
	fs.ChangeContents("existdir/quuxdir/level2")

	seeNothing(fs, ch, "some ignored operations")
}

func TestNoSubdirRecursionWithoutGlobs(t *testing.T) {
	fs := newFS(t)
	fs.MkdirAll("some_dir")
	ch := make(chan time.Time, 10)
	cleanUp := watchTest(fs, []string{fs.Abs(".")}, nil, ch)
	defer cleanUp()

	fs.Create("some_dir/level1")
	seeNothing(fs, ch, "creation in level1")
}

func TestRenameFile(t *testing.T) {
	fs := newFS(t)

	fs.Create("foobar")
	ch := make(chan time.Time, 10)

	cleanUp := watchTest(fs, []string{fs.Abs("foobar")}, []string{}, ch)
	defer cleanUp()
	renameTest(fs, ch, "foobar", "baz")
	renameTest(fs, ch, "baz", "foobar")
}

func TestRenameDir(t *testing.T) {
	fs := newFS(t)

	fs.MkdirAll("foodir")
	fs.Create("foodir/foobar")
	ch := make(chan time.Time, 10)

	cleanUp := watchTest(fs, []string{fs.Abs("foodir/foobar")}, []string{}, ch)
	defer cleanUp()
	renameTest(fs, ch, "foodir/foobar", "baz")
	renameTest(fs, ch, "baz", "foodir/foobar")
	renameTest(fs, ch, "foodir", "bardir")
	// TODO(jmhodges): this requires a better rename system than
	// fsnotify provides or watching every dang directory in the
	// entiry absolute path.
	// renameTest(fs, ch, "bardir", "foodir")
}

func TestHiddenFilesHiddenByDefault(t *testing.T) {
	fs := newFS(t)
	fs.MkdirAll("hDir1")
	fs.Create("hDir1/.hidden")
	fs.MkdirAll("hDir2")
	fs.MkdirAll("hDir3")
	fs.Create("hDir3/.hiddenAndIgnored")
	ch := make(chan time.Time, 10)
	cleanUp := watchTest(fs,
		[]string{fs.Abs("hDir1/.hidden"), fs.Abs("hDir2")},
		[]string{fs.Abs("hDir3/.hiddenAndIgnored")},
		ch)
	defer cleanUp()

	fs.ChangeContents("hDir1/.hidden")
	seeChangeContents(fs, ch, "hDir1/.hidden")
	fs.Create("hDir2/.hidden")
	seeNothing(fs, ch, "no hidden file creation")
	fs.ChangeContents("hDir3/.hiddenAndIgnored")
	seeNothing(fs, ch, "no event for changes to hDir3/.hiddenAndIgnored")
}

func renameTest(fs *fileSystem, ch <-chan time.Time, oldpath, newpath string) {
	fs.Rename(oldpath, newpath)
	seeRename(fs, ch, oldpath, newpath)
}

func seeRename(fs *fileSystem, ch <-chan time.Time, oldpath, newpath string) {
	select {
	case <-ch:
		fs.t.Logf("successful catch of rename ('%s' -> '%s')", oldpath, newpath)
	case <-time.After(waitForMsg):
		fs.t.Errorf("did not see rename ('%s' -> '%s')", oldpath, newpath)
	}
}

func seeNothing(fs *fileSystem, ch <-chan time.Time, msg string) {
	select {
	case <-ch:
		fs.t.Errorf("should not have seen anything but saw: %s", msg)
	case <-time.After(waitForMsg):
		fs.t.Logf("successfully saw nothing for '%s'", msg)
	}
}

func seeCreation(fs *fileSystem, ch <-chan time.Time, path string) {
	select {
	case <-ch:
		fs.t.Logf("successful catch of creation of '%s'", path)

	case <-time.After(waitForMsg):
		fs.t.Errorf("did not see creation of '%s'", path)

	}
}

func seeChangeContents(fs *fileSystem, ch <-chan time.Time, path string) {
	select {
	case <-ch:
		fs.t.Logf("successful catch of first event (MODIFY|ATTRIB) for changing contents of '%s'", path)
	case <-time.After(waitForMsg):
		fs.t.Errorf("did not see content change of '%s'", path)
	}
	select {
	case <-ch:
		fs.t.Logf("successful catch of second event (MODIFY) for changing contents of '%s'", path)
	case <-time.After(waitForMsg):
		fs.t.Errorf("did not see content change of '%s'", path)
	}
}

func watchTest(fs *fileSystem, inputPaths, ignoredPaths []string, cmdCh chan<- time.Time) func() {
	w, err := watch(inputPaths, ignoredPaths, cmdCh)
	if err != nil {
		fs.t.Fatalf("unable to run watch: %#v", err)
		return func() {}
	}
	return func() {
		w.Close()
		fs.Close()
	}
}

func newFS(t *testing.T) *fileSystem {
	name, err := ioutil.TempDir("", "justrun_tests_")
	if err != nil {
		t.Fatalf("unable to create temporary directory")
	}
	subdir := filepath.Join(name, "subdir_for_fds")
	err = os.MkdirAll(subdir, 0700)
	if err != nil {
		t.Fatalf("unable to create temporary directory's subdirectory")
	}
	return &fileSystem{name: subdir, t: t}
}

type fileSystem struct {
	name string
	t    *testing.T
}

func (fs *fileSystem) Create(path string) {
	fullName := filepath.Join(fs.name, path)
	// O_SYNC is important
	f, err := os.OpenFile(fullName, os.O_RDWR|os.O_CREATE|os.O_TRUNC|os.O_SYNC, 0666)
	if err != nil {
		fs.t.Fatalf("unable to create '%s' in '%s': %#v", path, fs.name, err)
	}
	f.Close()
}

func (fs *fileSystem) MkdirAll(path string) {
	fullName := filepath.Join(fs.name, path)
	err := os.MkdirAll(fullName, 0700)
	if err != nil {
		fs.t.Fatalf("unable to create directory '%s' in '%s': %#v", path, fs.name, err)
	}
}

func (fs *fileSystem) Rename(oldpath, newpath string) {
	err := os.Rename(filepath.Join(fs.name, oldpath), filepath.Join(fs.name, newpath))
	if err != nil {
		fs.t.Fatalf("unable to rename '%s' to '%s' in '%s'", oldpath, newpath, fs.name)
	}
}

func (fs *fileSystem) Abs(path string) string {
	return filepath.Join(fs.name, path)
}

func (fs *fileSystem) RemoveAll(path string) {
	if err := os.RemoveAll(path); err != nil {
		fs.t.Fatalf("unable to delete '%s': %s", path, err)
	}
}

func (fs *fileSystem) ChangeContents(path string) {
	fullName := filepath.Join(fs.name, path)
	b := make([]byte, 16)
	_, err := rand.Read(b)
	if err != nil {
		fs.t.Fatalf("unable to get random data to change the contents of '%s': %s", path, err)
	}

	f, err := os.OpenFile(fullName, os.O_WRONLY|os.O_SYNC|os.O_TRUNC, 0666)
	if err != nil {
		fs.t.Fatalf("unable to open '%s' to change its contents: %s", path, err)
	}
	defer f.Close()
	n, err := f.Write(b)
	if err != nil {
		fs.t.Fatalf("unable to write new contents to '%s': %s", path, err)
	}
	if n < len(b) {
		fs.t.Fatalf("unable to write all contents to '%s'", path)
	}
}

func (fs *fileSystem) Close() {
	err := os.RemoveAll(fs.name)
	if err != nil {
		fs.t.Fatalf("unable to delete directory '%s'", fs.name)
	}
}
<|endoftext|>


<commit_before>package dlog

import (
	"bufio"
	"bytes"
	"fmt"
	"os"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"time"
)

var (
	_ FullLogger = &logger{}
)

type logger struct {
	bytPool     sync.Pool
	debugLevel  Level
	debugFilter string
	writer      *bufio.Writer
}

// NewLogger returns an instance of the default logger with no filter,
// no file, and level set to ERROR
func NewLogger() Logger {
	return &logger{
		bytPool: sync.Pool{
			New: func() interface{} {
				return new(bytes.Buffer)
			},
		},
		debugLevel: ERROR,
	}
}

// GetLogLevel returns the current log level, i.e WARN or INFO...
func (l *logger) GetLogLevel() Level {
	return l.debugLevel
}

// dLog, the primary function of the package,
// prints out and writes to file a string
// containing the logged data separated by spaces,
// prepended with file and line information.
// It only includes logs which pass the current filters.
// Todo: use io.Multiwriter to simplify the writing to
// both logfiles and stdout
func (l *logger) dLog(console, override bool, in ...interface{}) {
	//(pc uintptr, file string, line int, ok bool)
	_, f, line, ok := runtime.Caller(2)
	if strings.Contains(f, "dlog") {
		_, f, line, ok = runtime.Caller(3)
	}
	if ok {
		f = truncateFileName(f)
		if !l.checkFilter(f, in) && !override {
			return
		}

		buffer := l.bytPool.Get().(*bytes.Buffer)
		// Note on errors: these functions all return
		// errors, but they are always nil.
		buffer.WriteRune('[')
		buffer.WriteString(f)
		buffer.WriteRune(':')
		buffer.WriteString(strconv.Itoa(line))
		buffer.WriteString("]  ")
		buffer.WriteString(logLevels[l.GetLogLevel()])
		buffer.WriteRune(':')
		for _, elem := range in {
			buffer.WriteString(fmt.Sprintf("%v ", elem))
		}
		buffer.WriteRune('\n')

		if console {
			fmt.Print(buffer.String())
		}

		if l.writer != nil {
			l.writer.WriteString(buffer.String())
			l.writer.Flush()
		}

		buffer.Reset()
		l.bytPool.Put(buffer)
	}
}

// FileWrite runs dLog, but JUST writes to file instead
// of also to stdout.
func (l *logger) FileWrite(in ...interface{}) {
	l.dLog(false, true, in...)
}

func truncateFileName(f string) string {
	index := strings.LastIndex(f, "/")
	lIndex := strings.LastIndex(f, ".")
	return f[index+1 : lIndex]
}

func (l *logger) checkFilter(f string, in ...interface{}) bool {
	for _, elem := range in {
		if strings.Contains(fmt.Sprintf("%s", elem), l.debugFilter) {
			return true
		}
	}
	return strings.Contains(f, l.debugFilter)
}

// SetDebugFilter sets the string which determines
// what debug messages get printed. Only messages
// which contain the filer as a pseudo-regex
func (l *logger) SetDebugFilter(filter string) {
	l.debugFilter = filter
}

// SetDebugLevel sets what message levels of debug
// will be printed.
func (l *logger) SetDebugLevel(dL Level) {
	if dL < NONE || dL > VERBOSE {
		Warn("Unknown debug level: ", dL)
		l.debugLevel = NONE
	} else {
		l.debugLevel = dL
	}
}

// CreateLogFile creates a file in the 'logs' directory
// of the starting point of this program to write logs to
func (l *logger) CreateLogFile() {
	fHandle, err := os.Create("logs/dlog" + time.Now().Format("_Jan_2_15-04-05_2006") + ".txt")
	if err != nil {
		fmt.Println("[oak]-------- No logs directory found. No logs will be written to file.")
		return
	}
	l.writer = bufio.NewWriter(fHandle)
}

// Error will write a dlog if the debug level is not NONE
func (l *logger) Error(in ...interface{}) {
	if l.debugLevel > NONE {
		l.dLog(true, true, in...)
	}
}

// Warn will write a dLog if the debug level is higher than ERROR
func (l *logger) Warn(in ...interface{}) {
	if l.debugLevel > ERROR {
		l.dLog(true, true, in...)
	}
}

// Info will write a dLog if the debug level is higher than WARN
func (l *logger) Info(in ...interface{}) {
	if l.debugLevel > WARN {
		l.dLog(true, false, in...)
	}
}

// Verb will write a dLog if the debug level is higher than INFO
func (l *logger) Verb(in ...interface{}) {
	if l.debugLevel > INFO {
		l.dLog(true, false, in...)
	}
}
<commit_msg>Dlog should log the level that was asked, instead of the logger's setting, probably<commit_after>package dlog

import (
	"bufio"
	"bytes"
	"fmt"
	"os"
	"runtime"
	"strconv"
	"strings"
	"sync"
	"time"
)

var (
	_ FullLogger = &logger{}
)

type logger struct {
	bytPool     sync.Pool
	debugLevel  Level
	debugFilter string
	writer      *bufio.Writer
}

// NewLogger returns an instance of the default logger with no filter,
// no file, and level set to ERROR
func NewLogger() Logger {
	return &logger{
		bytPool: sync.Pool{
			New: func() interface{} {
				return new(bytes.Buffer)
			},
		},
		debugLevel: ERROR,
	}
}

// GetLogLevel returns the current log level, i.e WARN or INFO...
func (l *logger) GetLogLevel() Level {
	return l.debugLevel
}

// dLog, the primary function of the package,
// prints out and writes to file a string
// containing the logged data separated by spaces,
// prepended with file and line information.
// It only includes logs which pass the current filters.
// Todo: use io.Multiwriter to simplify the writing to
// both logfiles and stdout
func (l *logger) dLog(level Level, console, override bool, in ...interface{}) {
	//(pc uintptr, file string, line int, ok bool)
	_, f, line, ok := runtime.Caller(2)
	if strings.Contains(f, "dlog") {
		_, f, line, ok = runtime.Caller(3)
	}
	if ok {
		f = truncateFileName(f)
		if !l.checkFilter(f, in) && !override {
			return
		}

		buffer := l.bytPool.Get().(*bytes.Buffer)
		// Note on errors: these functions all return
		// errors, but they are always nil.
		buffer.WriteRune('[')
		buffer.WriteString(f)
		buffer.WriteRune(':')
		buffer.WriteString(strconv.Itoa(line))
		buffer.WriteString("]  ")
		buffer.WriteString(logLevels[level])
		buffer.WriteRune(':')
		for _, elem := range in {
			buffer.WriteString(fmt.Sprintf("%v ", elem))
		}
		buffer.WriteRune('\n')

		if console {
			fmt.Print(buffer.String())
		}

		if l.writer != nil {
			l.writer.WriteString(buffer.String())
			l.writer.Flush()
		}

		buffer.Reset()
		l.bytPool.Put(buffer)
	}
}

// FileWrite runs dLog, but JUST writes to file instead
// of also to stdout.
func (l *logger) FileWrite(in ...interface{}) {
	l.dLog(INFO, false, true, in...)
}

func truncateFileName(f string) string {
	index := strings.LastIndex(f, "/")
	lIndex := strings.LastIndex(f, ".")
	return f[index+1 : lIndex]
}

func (l *logger) checkFilter(f string, in ...interface{}) bool {
	for _, elem := range in {
		if strings.Contains(fmt.Sprintf("%s", elem), l.debugFilter) {
			return true
		}
	}
	return strings.Contains(f, l.debugFilter)
}

// SetDebugFilter sets the string which determines
// what debug messages get printed. Only messages
// which contain the filer as a pseudo-regex
func (l *logger) SetDebugFilter(filter string) {
	l.debugFilter = filter
}

// SetDebugLevel sets what message levels of debug
// will be printed.
func (l *logger) SetDebugLevel(dL Level) {
	if dL < NONE || dL > VERBOSE {
		Warn("Unknown debug level: ", dL)
		l.debugLevel = NONE
	} else {
		l.debugLevel = dL
	}
}

// CreateLogFile creates a file in the 'logs' directory
// of the starting point of this program to write logs to
func (l *logger) CreateLogFile() {
	fHandle, err := os.Create("logs/dlog" + time.Now().Format("_Jan_2_15-04-05_2006") + ".txt")
	if err != nil {
		fmt.Println("[oak]-------- No logs directory found. No logs will be written to file.")
		return
	}
	l.writer = bufio.NewWriter(fHandle)
}

// Error will write a dlog if the debug level is not NONE
func (l *logger) Error(in ...interface{}) {
	if l.debugLevel > NONE {
		l.dLog(ERROR, true, true, in...)
	}
}

// Warn will write a dLog if the debug level is higher than ERROR
func (l *logger) Warn(in ...interface{}) {
	if l.debugLevel > ERROR {
		l.dLog(WARN, true, true, in...)
	}
}

// Info will write a dLog if the debug level is higher than WARN
func (l *logger) Info(in ...interface{}) {
	if l.debugLevel > WARN {
		l.dLog(INFO, true, false, in...)
	}
}

// Verb will write a dLog if the debug level is higher than INFO
func (l *logger) Verb(in ...interface{}) {
	if l.debugLevel > INFO {
		l.dLog(VERBOSE, true, false, in...)
	}
}
<|endoftext|>


<commit_before>package wrapper_test

import (
	"errors"
	"net/http"

	"code.cloudfoundry.org/cli/api/cloudcontroller"
	"code.cloudfoundry.org/cli/api/cloudcontroller/cloudcontrollerfakes"
	. "code.cloudfoundry.org/cli/api/cloudcontroller/wrapper"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Retry", func() {
	var (
		fakeConnection *cloudcontrollerfakes.FakeConnection
		connectionErr  error

		wrapper cloudcontroller.Connection

		request  *http.Request
		response *cloudcontroller.Response
		err      error
	)

	BeforeEach(func() {
		fakeConnection = new(cloudcontrollerfakes.FakeConnection)

		wrapper = NewRetryRequest(2).Wrap(fakeConnection)

		var err error
		request, err = http.NewRequest(http.MethodGet, "https://foo.bar.com/banana", nil)
		Expect(err).NotTo(HaveOccurred())

		response = &cloudcontroller.Response{
			HTTPResponse: &http.Response{},
		}
	})

	JustBeforeEach(func() {
		fakeConnection.MakeReturns(connectionErr)
		err = wrapper.Make(request, response)
	})

	Describe("Make", func() {
		Context("when no error occurs", func() {
			It("does not retry", func() {
				Expect(err).ToNot(HaveOccurred())
				Expect(fakeConnection.MakeCallCount()).To(Equal(1))
			})
		})

		Context("when an error occurs and there's no HTTP Response (aka protocol level error)", func() {
			BeforeEach(func() {
				connectionErr = errors.New("ZOMG WAAT")
				response.HTTPResponse = nil
			})

			It("does not retry", func() {
				Expect(err).To(Equal(connectionErr))
				Expect(fakeConnection.MakeCallCount()).To(Equal(1))
			})
		})

		Context("when the request recieves a 4XX status code", func() {
			BeforeEach(func() {
				connectionErr = cloudcontroller.RawHTTPStatusError{
					StatusCode: 400,
				}
				response.HTTPResponse.StatusCode = 400
			})

			It("does not retry", func() {
				Expect(err).To(Equal(connectionErr))
				Expect(fakeConnection.MakeCallCount()).To(Equal(1))
			})
		})

		Context("when the request recieves a 5XX status code", func() {
			BeforeEach(func() {
				connectionErr = cloudcontroller.RawHTTPStatusError{
					StatusCode: 500,
				}
				response.HTTPResponse.StatusCode = 500
			})

			It("retries maxRetries times", func() {
				Expect(err).To(Equal(connectionErr))
				Expect(fakeConnection.MakeCallCount()).To(Equal(3))
			})
		})
	})
})
<commit_msg>test pollution :{<commit_after>package wrapper_test

import (
	"errors"
	"net/http"

	"code.cloudfoundry.org/cli/api/cloudcontroller"
	"code.cloudfoundry.org/cli/api/cloudcontroller/cloudcontrollerfakes"
	. "code.cloudfoundry.org/cli/api/cloudcontroller/wrapper"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Retry", func() {
	var (
		fakeConnection *cloudcontrollerfakes.FakeConnection
		connectionErr  error

		wrapper cloudcontroller.Connection

		request  *http.Request
		response *cloudcontroller.Response
		err      error
	)

	BeforeEach(func() {
		fakeConnection = new(cloudcontrollerfakes.FakeConnection)

		wrapper = NewRetryRequest(2).Wrap(fakeConnection)

		var err error
		request, err = http.NewRequest(http.MethodGet, "https://foo.bar.com/banana", nil)
		Expect(err).NotTo(HaveOccurred())

		response = &cloudcontroller.Response{
			HTTPResponse: &http.Response{},
		}
	})

	JustBeforeEach(func() {
		fakeConnection.MakeReturns(connectionErr)
		err = wrapper.Make(request, response)
	})

	Describe("Make", func() {
		Context("when no error occurs", func() {
			BeforeEach(func() {
				connectionErr = nil
			})

			It("does not retry", func() {
				Expect(err).ToNot(HaveOccurred())
				Expect(fakeConnection.MakeCallCount()).To(Equal(1))
			})
		})

		Context("when an error occurs and there's no HTTP Response (aka protocol level error)", func() {
			BeforeEach(func() {
				connectionErr = errors.New("ZOMG WAAT")
				response.HTTPResponse = nil
			})

			It("does not retry", func() {
				Expect(err).To(Equal(connectionErr))
				Expect(fakeConnection.MakeCallCount()).To(Equal(1))
			})
		})

		Context("when the request recieves a 4XX status code", func() {
			BeforeEach(func() {
				connectionErr = cloudcontroller.RawHTTPStatusError{
					StatusCode: 400,
				}
				response.HTTPResponse.StatusCode = 400
			})

			It("does not retry", func() {
				Expect(err).To(Equal(connectionErr))
				Expect(fakeConnection.MakeCallCount()).To(Equal(1))
			})
		})

		Context("when the request recieves a 5XX status code", func() {
			BeforeEach(func() {
				connectionErr = cloudcontroller.RawHTTPStatusError{
					StatusCode: 500,
				}
				response.HTTPResponse.StatusCode = 500
			})

			It("retries maxRetries times", func() {
				Expect(err).To(Equal(connectionErr))
				Expect(fakeConnection.MakeCallCount()).To(Equal(3))
			})
		})
	})
})
<|endoftext|>


<commit_before>package api

import (
	"io/ioutil"
	"testing"
	"time"

	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/types"
)

// TestIntegrationMinerGET checks the GET call to the /miner endpoint.
func TestIntegrationMinerGET(t *testing.T) {
	if testing.Short() {
		t.SkipNow()
	}
	st, err := createServerTester("TestIntegrationMinerGET")
	if err != nil {
		t.Fatal(err)
	}

	// TODO: Mine some stale blocks.

	// Get the api returned fields of the miner.
	var mg MinerGET
	err = st.getAPI("/miner", &mg)
	if err != nil {
		t.Fatal(err)
	}

	// Verify the correctness of the results.
	blocksMined, staleBlocksMined := st.server.miner.BlocksMined()
	if mg.BlocksMined != blocksMined {
		t.Error("blocks mined did not succeed")
	}
	if mg.StaleBlocksMined != staleBlocksMined {
		t.Error("stale blocks mined is incorrect")
	}
	if mg.CPUHashrate != st.server.miner.CPUHashrate() {
		t.Error("mismatched cpu hashrate")
	}
	if mg.CPUMining != st.server.miner.CPUMining() {
		t.Error("mismatched cpu miner status")
	}
}

// TestIntegrationMinerStartStop checks that the miner start and miner stop api endpoints
// toggle the cpu miner.
func TestIntegrationMinerStartStop(t *testing.T) {
	if testing.Short() {
		t.SkipNow()
	}
	st, err := createServerTester("TestIntegrationMinerStartStop")
	if err != nil {
		t.Fatal(err)
	}

	// Start the cpu miner, give time for the first hashrate readings to
	// appear.
	err = st.stdGetAPI("/miner/start")
	if err != nil {
		t.Fatal(err)
	}
	time.Sleep(100 * time.Millisecond)
	if !st.server.miner.CPUMining() {
		t.Error("cpu miner is reporting that it is not on")
	}

	// Check the numbers through the status api call.
	var mg MinerGET
	err = st.getAPI("/miner", &mg)
	if err != nil {
		t.Fatal(err)
	}
	if !mg.CPUMining {
		t.Error("cpu is not reporting through the api that it is mining.")
	}

	// Stop the cpu miner and wait for the stop call to go through.
	err = st.stdGetAPI("/miner/stop")
	if err != nil {
		t.Fatal(err)
	}
	time.Sleep(100 * time.Millisecond)
	if st.server.miner.CPUMining() {
		t.Error("cpu miner is reporting that it is not on")
	}

	// Check the numbers through the status api call.
	err = st.getAPI("/miner", &mg)
	if err != nil {
		t.Fatal(err)
	}
	if mg.CPUMining {
		t.Error("cpu is not reporting through the api that it is mining.")
	}
}

// TestIntegrationMinerHeader checks that the header GET and POST calls are
// useful tools for mining blocks.
func TestIntegrationMinerHeader(t *testing.T) {
	if testing.Short() {
		t.SkipNow()
	}
	st, err := createServerTester("TestIntegrationMinerHeader")
	if err != nil {
		t.Fatal(err)
	}
	startingHeight := st.cs.Height()

	// Get a header that can be used for mining.
	resp, err := HttpGET("http://" + st.server.listener.Addr().String() + "/miner/header")
	if err != nil {
		t.Fatal(err)
	}
	defer resp.Body.Close()
	targetAndHeader, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatal(err)
	}

	// Twiddle the header bits until a block has been found.
	//
	// Note: this test treats the target as hardcoded, if the testing target is
	// changed, this test will also need to be changed.
	if types.RootTarget[0] != 128 {
		t.Fatal("test will fail because the testing constants have been unexpectedly changed")
	}
	var header [80]byte
	copy(header[:], targetAndHeader[32:])
	headerHash := crypto.HashObject(header)
	for headerHash[0] >= types.RootTarget[0] {
		header[35]++
		headerHash = crypto.HashObject(header)
	}

	// Submit the solved header through the api and check that the height of
	// the blockchain increases.
	resp, err = HttpPOST("http://"+st.server.listener.Addr().String()+"/miner/header", string(header[:]))
	if err != nil {
		t.Fatal(err)
	}
	defer resp.Body.Close()
	time.Sleep(500 * time.Millisecond)
	if st.cs.Height() != startingHeight+1 {
		println(st.cs.Height())
		println(startingHeight + 1)
		t.Error("block height did not increase after trying to mine a block through the api")
	}
}
<commit_msg>better test failure reporting<commit_after>package api

import (
	"io/ioutil"
	"testing"
	"time"

	"github.com/NebulousLabs/Sia/crypto"
	"github.com/NebulousLabs/Sia/types"
)

// TestIntegrationMinerGET checks the GET call to the /miner endpoint.
func TestIntegrationMinerGET(t *testing.T) {
	if testing.Short() {
		t.SkipNow()
	}
	st, err := createServerTester("TestIntegrationMinerGET")
	if err != nil {
		t.Fatal(err)
	}

	// TODO: Mine some stale blocks.

	// Get the api returned fields of the miner.
	var mg MinerGET
	err = st.getAPI("/miner", &mg)
	if err != nil {
		t.Fatal(err)
	}

	// Verify the correctness of the results.
	blocksMined, staleBlocksMined := st.server.miner.BlocksMined()
	if mg.BlocksMined != blocksMined {
		t.Error("blocks mined did not succeed")
	}
	if mg.StaleBlocksMined != staleBlocksMined {
		t.Error("stale blocks mined is incorrect")
	}
	if mg.CPUHashrate != st.server.miner.CPUHashrate() {
		t.Error("mismatched cpu hashrate")
	}
	if mg.CPUMining != st.server.miner.CPUMining() {
		t.Error("mismatched cpu miner status")
	}
}

// TestIntegrationMinerStartStop checks that the miner start and miner stop api endpoints
// toggle the cpu miner.
func TestIntegrationMinerStartStop(t *testing.T) {
	if testing.Short() {
		t.SkipNow()
	}
	st, err := createServerTester("TestIntegrationMinerStartStop")
	if err != nil {
		t.Fatal(err)
	}

	// Start the cpu miner, give time for the first hashrate readings to
	// appear.
	err = st.stdGetAPI("/miner/start")
	if err != nil {
		t.Fatal(err)
	}
	time.Sleep(100 * time.Millisecond)
	if !st.server.miner.CPUMining() {
		t.Error("cpu miner is reporting that it is not on")
	}

	// Check the numbers through the status api call.
	var mg MinerGET
	err = st.getAPI("/miner", &mg)
	if err != nil {
		t.Fatal(err)
	}
	if !mg.CPUMining {
		t.Error("cpu is not reporting through the api that it is mining.")
	}

	// Stop the cpu miner and wait for the stop call to go through.
	err = st.stdGetAPI("/miner/stop")
	if err != nil {
		t.Fatal(err)
	}
	time.Sleep(100 * time.Millisecond)
	if st.server.miner.CPUMining() {
		t.Error("cpu miner is reporting that it is not on")
	}

	// Check the numbers through the status api call.
	err = st.getAPI("/miner", &mg)
	if err != nil {
		t.Fatal(err)
	}
	if mg.CPUMining {
		t.Error("cpu is not reporting through the api that it is mining.")
	}
}

// TestIntegrationMinerHeader checks that the header GET and POST calls are
// useful tools for mining blocks.
func TestIntegrationMinerHeader(t *testing.T) {
	if testing.Short() {
		t.SkipNow()
	}
	st, err := createServerTester("TestIntegrationMinerHeader")
	if err != nil {
		t.Fatal(err)
	}
	startingHeight := st.cs.Height()

	// Get a header that can be used for mining.
	resp, err := HttpGET("http://" + st.server.listener.Addr().String() + "/miner/header")
	if err != nil {
		t.Fatal(err)
	}
	defer resp.Body.Close()
	targetAndHeader, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatal(err)
	}

	// Twiddle the header bits until a block has been found.
	//
	// Note: this test treats the target as hardcoded, if the testing target is
	// changed, this test will also need to be changed.
	if types.RootTarget[0] != 128 {
		t.Fatal("test will fail because the testing constants have been unexpectedly changed")
	}
	var header [80]byte
	copy(header[:], targetAndHeader[32:])
	headerHash := crypto.HashObject(header)
	for headerHash[0] >= types.RootTarget[0] {
		header[35]++
		headerHash = crypto.HashObject(header)
	}

	// Submit the solved header through the api and check that the height of
	// the blockchain increases.
	resp, err = HttpPOST("http://"+st.server.listener.Addr().String()+"/miner/header", string(header[:]))
	if err != nil {
		t.Fatal(err)
	}
	defer resp.Body.Close()
	time.Sleep(500 * time.Millisecond)
	if st.cs.Height() != startingHeight+1 {
		t.Errorf("block height did not increase after trying to mine a block through the api, started at %v and ended at %v", startingHeight, st.cs.Height())
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"log"
	"os"

	"github.com/smartystreets/smartystreets-go-sdk/us-street-api"
	"github.com/smartystreets/smartystreets-go-sdk/wireup"
)

func main() {
	log.SetFlags(log.Ltime | log.Llongfile)

	// You don't have to store your keys in environment variables, but we recommend it.
	client := wireup.BuildUSStreetAPIClient(
		wireup.SecretKeyCredential(os.Getenv("SMARTY_AUTH_ID"), os.Getenv("SMARTY_AUTH_TOKEN")),
		//wireup.ViaProxy("https://my-proxy.my-company.com"), // uncomment this line to point to the specified proxy.
		//wireup.DebugHTTPOutput(), // uncomment this line to see detailed HTTP request/response information.
	)

	lookup1 := &street.Lookup{
		Street:        "1 Rosedale",
		City:          "Baltimore",
		State:         "MD",
		MaxCandidates: 10, // This input produces more than one candidate!
	}
	lookup2 := &street.Lookup{
		Street: "1600 Pennsylvania Avenue",
		City:   "Washington",
		State:  "DC",
	}
	lookup3 := &street.Lookup{
		Street: "1600 Amphitheatre Parkway Mountain View, CA 94043",
	}

	batch := street.NewBatch()
	batch.Append(lookup1)
	batch.Append(lookup2)
	batch.Append(lookup3)

	if err := client.SendBatch(batch); err != nil {
		log.Fatal("Error sending batch:", err)
	}

	for i, input := range batch.Records() {
		fmt.Println("Results for input:", i)
		fmt.Println()
		for j, candidate := range input.Results {
			fmt.Println("  Candidate:", j)
			fmt.Println(" ", candidate.DeliveryLine1)
			fmt.Println(" ", candidate.LastLine)
			fmt.Println()
		}
	}

	log.Println("OK")
}
<commit_msg>Added match=invalid field in example code.<commit_after>package main

import (
	"fmt"
	"log"
	"os"

	"github.com/smartystreets/smartystreets-go-sdk/us-street-api"
	"github.com/smartystreets/smartystreets-go-sdk/wireup"
)

func main() {
	log.SetFlags(log.Ltime | log.Llongfile)

	// You don't have to store your keys in environment variables, but we recommend it.
	client := wireup.BuildUSStreetAPIClient(
		wireup.SecretKeyCredential(os.Getenv("SMARTY_AUTH_ID"), os.Getenv("SMARTY_AUTH_TOKEN")),
		//wireup.ViaProxy("https://my-proxy.my-company.com"), // uncomment this line to point to the specified proxy.
		//wireup.DebugHTTPOutput(), // uncomment this line to see detailed HTTP request/response information.
	)

	lookup1 := &street.Lookup{
		Street:        "1 Rosedale",
		City:          "Baltimore",
		State:         "MD",
		MaxCandidates: 10, // This input produces more than one candidate!
		MatchStrategy: street.MatchInvalid,
	}
	lookup2 := &street.Lookup{
		Street: "1600 Pennsylvania Avenue",
		City:   "Washington",
		State:  "DC",
	}
	lookup3 := &street.Lookup{
		Street: "1600 Amphitheatre Parkway Mountain View, CA 94043",
	}

	batch := street.NewBatch()
	batch.Append(lookup1)
	batch.Append(lookup2)
	batch.Append(lookup3)

	if err := client.SendBatch(batch); err != nil {
		log.Fatal("Error sending batch:", err)
	}

	for i, input := range batch.Records() {
		fmt.Println("Results for input:", i)
		fmt.Println()
		for j, candidate := range input.Results {
			fmt.Println("  Candidate:", j)
			fmt.Println(" ", candidate.DeliveryLine1)
			fmt.Println(" ", candidate.LastLine)
			fmt.Println()
		}
	}

	log.Println("OK")
}
<|endoftext|>


<commit_before>// SenML encoder and decoder to pare Sensor Markup Language
package senml

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"errors"
	"fmt"
	"github.com/ugorji/go/codec"
	"strconv"
	"strings"
	"time"
)

type Format int

const (
	JSON Format = 1 + iota
	XML
	CBOR
	CSV
	MPACK
	LINEP
	JSONLINE
)

type OutputOptions struct {
	PrettyPrint bool
	Topic       string
}

type SenMLRecord struct {
	XMLName *bool `json:"_,omitempty" xml:"senml"`

	BaseName    string  `json:"bn,omitempty"  xml:"bn,attr,omitempty"`
	BaseTime    float64 `json:"bt,omitempty"  xml:"bt,attr,omitempty"`
	BaseUnit    string  `json:"bu,omitempty"  xml:"bu,attr,omitempty"`
	BaseVersion int     `json:"bver,omitempty"  xml:"bver,attr,omitempty"`

	Link string `json:"l,omitempty"  xml:"l,attr,omitempty"`

	Name       string  `json:"n,omitempty"  xml:"n,attr,omitempty"`
	Unit       string  `json:"u,omitempty"  xml:"u,attr,omitempty"`
	Time       float64 `json:"t,omitempty"  xml:"t,attr,omitempty"`
	UpdateTime float64 `json:"ut,omitempty"  xml:"ut,attr,omitempty"`

	Value       *float64 `json:"v,omitempty"  xml:"v,attr,omitempty"`
	StringValue string   `json:"vs,omitempty"  xml:"vs,attr,omitempty"`
	DataValue   string   `json:"vd,omitempty"  xml:"vd,attr,omitempty"`
	BoolValue   *bool    `json:"vb,omitempty"  xml:"vb,attr,omitempty"`

	Sum *float64 `json:"s,omitempty"  xml:"sum,,attr,omitempty"`
}

type SenML struct {
	XMLName *bool  `json:"_,omitempty" xml:"sensml"`
	Xmlns   string `json:"_,omitempty" xml:"xmlns,attr"`

	Records []SenMLRecord ` xml:"senml"`
}

// Decode takes a SenML message in the given format and parses it and decodes it
// into the returned SenML record.
func Decode(msg []byte, format Format) (SenML, error) {
	var s SenML
	var err error

	s.XMLName = nil
	s.Xmlns = "urn:ietf:params:xml:ns:senml"

	switch {
	case format == JSON:
		// parse the input JSON stream
		err = json.Unmarshal(msg, &s.Records)
		if err != nil {
			//fmt.Println("error parsing JSON SenML Stream: ", err)
			//fmt.Println("msg=", msg)
			return s, err
		}

	case format == JSONLINE:
		// parse the input JSON line
		lines := strings.Split(string(msg), "\n")
		for _, line := range lines {
			r := new(SenMLRecord)
			if len(line) > 5 {
				err = json.Unmarshal([]byte(line), r)
				if err != nil {
					//fmt.Println("error parsing JSON SenML Line: ", err)
					return s, err
				}
				s.Records = append(s.Records, *r)
			}
		}

	case format == XML:
		// parse the input XML
		err = xml.Unmarshal(msg, &s)
		if err != nil {
			//fmt.Println("error parsing XML SenML", err)
			return s, err
		}

	case format == CBOR:
		// parse the input CBOR
		var cborHandle codec.Handle = new(codec.CborHandle)
		var decoder *codec.Decoder = codec.NewDecoderBytes(msg, cborHandle)
		err = decoder.Decode(&s.Records)
		if err != nil {
			//fmt.Println("error parsing CBOR SenML", err)
			return s, err
		}

	case format == MPACK:
		// parse the input MPACK
		// spec for MessagePack is at https://github.com/msgpack/msgpack/
		var mpackHandle codec.Handle = new(codec.MsgpackHandle)
		var decoder *codec.Decoder = codec.NewDecoderBytes(msg, mpackHandle)
		err = decoder.Decode(&s.Records)
		if err != nil {
			//fmt.Println("error parsing MPACK SenML", err)
			return s, err
		}

	}

	if !IsValid(s) {
		return s, errors.New("SenML record not valid")
	}

	return s, nil
}

// Encode takes a SenML record, and encodes it using the given format.
func Encode(s SenML, format Format, options OutputOptions) ([]byte, error) {
	var data []byte
	var err error

	if options.Topic == "" {
		options.Topic = "senml"
	}

	s.Xmlns = "urn:ietf:params:xml:ns:senml"

	switch {

	case format == JSON:
		// ouput JSON version
		if options.PrettyPrint {
			// data, err = json.MarshalIndent(s.Records, "", "  ")
			var lines string
			lines += fmt.Sprintf("[\n  ")
			for i, r := range s.Records {
				if i != 0 {
					lines += ",\n  "
				}
				recData, err := json.Marshal(r)
				if err != nil {
					//fmt.Println("error encoding JSON SenML", err)
					return nil, err
				}
				lines += fmt.Sprintf("%s", recData)
			}
			lines += fmt.Sprintf("\n]\n")
			data = []byte(lines)
		} else {
			data, err = json.Marshal(s.Records)
		}
		if err != nil {
			//fmt.Println("error encoding JSON SenML", err)
			return nil, err
		}

	case format == XML:
		// output a XML version
		if options.PrettyPrint {
			data, err = xml.MarshalIndent(s, "", "  ")
		} else {
			data, err = xml.Marshal(s)
		}
		if err != nil {
			//fmt.Println("error encoding XML SenML", err)
			return nil, err
		}

	case format == CSV:
		// output a CSV version
		var lines string
		for _, r := range s.Records {
			if r.Value != nil {
				// TODO - replace sprintf with bytes.Buffer
				lines += fmt.Sprintf("%s,", r.Name)
				// excell time in days since 1900, unix seconds since 1970
				// ( 1970 is 25569 days after 1900 )
				lines += fmt.Sprintf("%f,", (r.Time/(24.0*3600.0))+25569.0)
				lines += fmt.Sprintf("%f", *r.Value)
				if len(r.Unit) > 0 {
					lines += fmt.Sprintf(",%s", r.Unit)
				}
				lines += fmt.Sprintf("\r\n")
			}
		}
		data = []byte(lines)
		if err != nil {
			//fmt.Println("error encoding CSV SenML", err)
			return nil, err
		}

	case format == CBOR:
		// output a CBOR version
		var cborHandle codec.Handle = new(codec.CborHandle)
		var encoder *codec.Encoder = codec.NewEncoderBytes(&data, cborHandle)
		err = encoder.Encode(s.Records)
		if err != nil {
			//fmt.Println("error encoding CBOR SenML", err)
			return nil, err
		}

	case format == MPACK:
		// output a MPACK version
		var mpackHandle codec.Handle = new(codec.MsgpackHandle)
		var encoder *codec.Encoder = codec.NewEncoderBytes(&data, mpackHandle)
		err = encoder.Encode(s.Records)
		if err != nil {
			//fmt.Println("error encoding MPACK SenML", err)
			return nil, err
		}

	case format == LINEP:
		// ouput Line Protocol
		var buf bytes.Buffer
		for _, r := range s.Records {
			if r.Value != nil {
				buf.WriteString(options.Topic)
				buf.WriteString(",n=")
				buf.WriteString(r.Name)
				buf.WriteString(",u=")
				buf.WriteString(r.Unit)
				buf.WriteString(" v=")
				buf.WriteString(strconv.FormatFloat(*r.Value, 'f', -1, 64))
				buf.WriteString(" ")
				buf.WriteString(strconv.FormatInt(int64(r.Time*1.0e9), 10))
				buf.WriteString("\n")
			}
		}
		data = buf.Bytes()

	case format == JSONLINE:
		// ouput Line Protocol
		var buf bytes.Buffer
		for _, r := range s.Records {
			if r.Value != nil {
				data, err = json.Marshal(r)
				if err != nil {
					//fmt.Println("error encoding JSONLINE SenML", err)
					return nil, err
				}
				buf.Write(data)
				buf.WriteString("\n")
			}
		}
		data = buf.Bytes()
	}

	return data, nil
}

// Removes all the base items and expands records to have items that include
// what previosly in base iterms. Convets relative times to absoltue times.
func Normalize(senml SenML) SenML {
	var bname string = ""
	var btime float64 = 0
	var bunit string = ""
	var ver = 5
	var ret SenML

	var totalRecords int = 0
	for _, r := range senml.Records {
		if (r.Value != nil) || (len(r.StringValue) > 0) || (r.BoolValue != nil) {
			totalRecords += 1
		}
	}

	ret.XMLName = senml.XMLName
	ret.Xmlns = senml.Xmlns
	ret.Records = make([]SenMLRecord, totalRecords)
	var numRecords = 0

	for _, r := range senml.Records {
		if r.BaseTime != 0 {
			btime = r.BaseTime
		}
		if r.BaseVersion != 0 {
			ver = r.BaseVersion
		}
		if len(r.BaseUnit) > 0 {
			bunit = r.BaseUnit
		}
		if len(r.BaseName) > 0 {
			bname = r.BaseName
		}
		r.BaseTime = 0
		r.BaseUnit = ""
		r.BaseName = ""
		r.Name = bname + r.Name
		r.Time = btime + r.Time
		if len(r.Unit) == 0 {
			r.Unit = bunit
		}
		r.BaseVersion = ver

		if r.Time <= 0 {
			// convert to absolute time
			var now int64 = time.Now().UnixNano()
			var t int64 = now / 1000000000.0
			r.Time = float64(t) + r.Time
		}

		if (r.Value != nil) || (len(r.StringValue) > 0) || (r.BoolValue != nil) {
			ret.Records[numRecords] = r
			numRecords += 1
		}
	}

	return ret
}

// Test if SenML is valid
func IsValid(senml SenML) bool {
	var bname string = ""
	var bver = -1

	//fmt.Println("In Validate")

	for _, r := range senml.Records {

		// Check version is same for all records
		if bver == -1 {
			// set the bver the first time it is seen
			if r.BaseVersion != 0 {
				bver = r.BaseVersion
			}
		} else {
			if r.BaseVersion != 0 {
				// next time a version in seen, check it has not changed
				if r.BaseVersion != bver {
					//fmt.Println("unallowed version change ")
					return false
				}
			}
		}

		// Check name
		if len(r.BaseName) > 0 {
			bname = r.BaseName
		}
		name := bname + r.Name
		if len(name) == 0 {
			//fmt.Println("empty name")

			return false
		}
		if (name[0] == '-') || (name[0] == ':') || (name[0] == '.') || (name[0] == '/') || (name[0] == '_') {
			//fmt.Println("Bad first char in name")
			return false
		}
		for _, l := range name {
			if (l < 'a' || l > 'z') && (l < 'A' || l > 'Z') && (l < '0' || l > '9') && (l != '-') && (l != ':') && (l != '.') && (l != '/') && (l != '_') {
				//fmt.Println("Bad char in name")
				return false
			}
		}

		valueCount := 0
		if r.Value != nil {
			valueCount = valueCount + 1
		}
		if r.BoolValue != nil {
			valueCount = valueCount + 1
		}
		if len(r.DataValue) > 0 {
			valueCount = valueCount + 1
		}
		if len(r.StringValue) > 0 {
			valueCount = valueCount + 1
		}
		if valueCount > 1 {
			//fmt.Println("Too many values ")
			return false
		}
		if r.Sum != nil {
			valueCount = valueCount + 1
		}
		if valueCount < 1 {
			//fmt.Println("No value or sum")
			return false
		}

		// Check if name is known Mandatory To Understand
		//for k :=  r {
		// 	fmt.Println( "key=" , k  )
		//         if k[ len(k)-1 ] == '_' {
		//         	fmt.Println("unknown MTU in record")
		//		return false
		//        }
		// }
	}

	return true
}
<commit_msg>fix#19 xml encoding of sum<commit_after>// SenML encoder and decoder to pare Sensor Markup Language
package senml

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"errors"
	"fmt"
	"github.com/ugorji/go/codec"
	"strconv"
	"strings"
	"time"
)

type Format int

const (
	JSON Format = 1 + iota
	XML
	CBOR
	CSV
	MPACK
	LINEP
	JSONLINE
)

type OutputOptions struct {
	PrettyPrint bool
	Topic       string
}

type SenMLRecord struct {
	XMLName *bool `json:"_,omitempty" xml:"senml"`

	BaseName    string  `json:"bn,omitempty"  xml:"bn,attr,omitempty"`
	BaseTime    float64 `json:"bt,omitempty"  xml:"bt,attr,omitempty"`
	BaseUnit    string  `json:"bu,omitempty"  xml:"bu,attr,omitempty"`
	BaseVersion int     `json:"bver,omitempty"  xml:"bver,attr,omitempty"`

	Link string `json:"l,omitempty"  xml:"l,attr,omitempty"`

	Name       string  `json:"n,omitempty"  xml:"n,attr,omitempty"`
	Unit       string  `json:"u,omitempty"  xml:"u,attr,omitempty"`
	Time       float64 `json:"t,omitempty"  xml:"t,attr,omitempty"`
	UpdateTime float64 `json:"ut,omitempty"  xml:"ut,attr,omitempty"`

	Value       *float64 `json:"v,omitempty"  xml:"v,attr,omitempty"`
	StringValue string   `json:"vs,omitempty"  xml:"vs,attr,omitempty"`
	DataValue   string   `json:"vd,omitempty"  xml:"vd,attr,omitempty"`
	BoolValue   *bool    `json:"vb,omitempty"  xml:"vb,attr,omitempty"`

	Sum *float64 `json:"s,omitempty"  xml:"s,attr,omitempty"`
}

type SenML struct {
	XMLName *bool  `json:"_,omitempty" xml:"sensml"`
	Xmlns   string `json:"_,omitempty" xml:"xmlns,attr"`

	Records []SenMLRecord ` xml:"senml"`
}

// Decode takes a SenML message in the given format and parses it and decodes it
// into the returned SenML record.
func Decode(msg []byte, format Format) (SenML, error) {
	var s SenML
	var err error

	s.XMLName = nil
	s.Xmlns = "urn:ietf:params:xml:ns:senml"

	switch {
	case format == JSON:
		// parse the input JSON stream
		err = json.Unmarshal(msg, &s.Records)
		if err != nil {
			//fmt.Println("error parsing JSON SenML Stream: ", err)
			//fmt.Println("msg=", msg)
			return s, err
		}

	case format == JSONLINE:
		// parse the input JSON line
		lines := strings.Split(string(msg), "\n")
		for _, line := range lines {
			r := new(SenMLRecord)
			if len(line) > 5 {
				err = json.Unmarshal([]byte(line), r)
				if err != nil {
					//fmt.Println("error parsing JSON SenML Line: ", err)
					return s, err
				}
				s.Records = append(s.Records, *r)
			}
		}

	case format == XML:
		// parse the input XML
		err = xml.Unmarshal(msg, &s)
		if err != nil {
			//fmt.Println("error parsing XML SenML", err)
			return s, err
		}

	case format == CBOR:
		// parse the input CBOR
		var cborHandle codec.Handle = new(codec.CborHandle)
		var decoder *codec.Decoder = codec.NewDecoderBytes(msg, cborHandle)
		err = decoder.Decode(&s.Records)
		if err != nil {
			//fmt.Println("error parsing CBOR SenML", err)
			return s, err
		}

	case format == MPACK:
		// parse the input MPACK
		// spec for MessagePack is at https://github.com/msgpack/msgpack/
		var mpackHandle codec.Handle = new(codec.MsgpackHandle)
		var decoder *codec.Decoder = codec.NewDecoderBytes(msg, mpackHandle)
		err = decoder.Decode(&s.Records)
		if err != nil {
			//fmt.Println("error parsing MPACK SenML", err)
			return s, err
		}

	}

	if !IsValid(s) {
		return s, errors.New("SenML record not valid")
	}

	return s, nil
}

// Encode takes a SenML record, and encodes it using the given format.
func Encode(s SenML, format Format, options OutputOptions) ([]byte, error) {
	var data []byte
	var err error

	if options.Topic == "" {
		options.Topic = "senml"
	}

	s.Xmlns = "urn:ietf:params:xml:ns:senml"

	switch {

	case format == JSON:
		// ouput JSON version
		if options.PrettyPrint {
			// data, err = json.MarshalIndent(s.Records, "", "  ")
			var lines string
			lines += fmt.Sprintf("[\n  ")
			for i, r := range s.Records {
				if i != 0 {
					lines += ",\n  "
				}
				recData, err := json.Marshal(r)
				if err != nil {
					//fmt.Println("error encoding JSON SenML", err)
					return nil, err
				}
				lines += fmt.Sprintf("%s", recData)
			}
			lines += fmt.Sprintf("\n]\n")
			data = []byte(lines)
		} else {
			data, err = json.Marshal(s.Records)
		}
		if err != nil {
			//fmt.Println("error encoding JSON SenML", err)
			return nil, err
		}

	case format == XML:
		// output a XML version
		if options.PrettyPrint {
			data, err = xml.MarshalIndent(s, "", "  ")
		} else {
			data, err = xml.Marshal(s)
		}
		if err != nil {
			//fmt.Println("error encoding XML SenML", err)
			return nil, err
		}

	case format == CSV:
		// output a CSV version
		var lines string
		for _, r := range s.Records {
			if r.Value != nil {
				// TODO - replace sprintf with bytes.Buffer
				lines += fmt.Sprintf("%s,", r.Name)
				// excell time in days since 1900, unix seconds since 1970
				// ( 1970 is 25569 days after 1900 )
				lines += fmt.Sprintf("%f,", (r.Time/(24.0*3600.0))+25569.0)
				lines += fmt.Sprintf("%f", *r.Value)
				if len(r.Unit) > 0 {
					lines += fmt.Sprintf(",%s", r.Unit)
				}
				lines += fmt.Sprintf("\r\n")
			}
		}
		data = []byte(lines)
		if err != nil {
			//fmt.Println("error encoding CSV SenML", err)
			return nil, err
		}

	case format == CBOR:
		// output a CBOR version
		var cborHandle codec.Handle = new(codec.CborHandle)
		var encoder *codec.Encoder = codec.NewEncoderBytes(&data, cborHandle)
		err = encoder.Encode(s.Records)
		if err != nil {
			//fmt.Println("error encoding CBOR SenML", err)
			return nil, err
		}

	case format == MPACK:
		// output a MPACK version
		var mpackHandle codec.Handle = new(codec.MsgpackHandle)
		var encoder *codec.Encoder = codec.NewEncoderBytes(&data, mpackHandle)
		err = encoder.Encode(s.Records)
		if err != nil {
			//fmt.Println("error encoding MPACK SenML", err)
			return nil, err
		}

	case format == LINEP:
		// ouput Line Protocol
		var buf bytes.Buffer
		for _, r := range s.Records {
			if r.Value != nil {
				buf.WriteString(options.Topic)
				buf.WriteString(",n=")
				buf.WriteString(r.Name)
				buf.WriteString(",u=")
				buf.WriteString(r.Unit)
				buf.WriteString(" v=")
				buf.WriteString(strconv.FormatFloat(*r.Value, 'f', -1, 64))
				buf.WriteString(" ")
				buf.WriteString(strconv.FormatInt(int64(r.Time*1.0e9), 10))
				buf.WriteString("\n")
			}
		}
		data = buf.Bytes()

	case format == JSONLINE:
		// ouput Line Protocol
		var buf bytes.Buffer
		for _, r := range s.Records {
			if r.Value != nil {
				data, err = json.Marshal(r)
				if err != nil {
					//fmt.Println("error encoding JSONLINE SenML", err)
					return nil, err
				}
				buf.Write(data)
				buf.WriteString("\n")
			}
		}
		data = buf.Bytes()
	}

	return data, nil
}

// Removes all the base items and expands records to have items that include
// what previosly in base iterms. Convets relative times to absoltue times.
func Normalize(senml SenML) SenML {
	var bname string = ""
	var btime float64 = 0
	var bunit string = ""
	var ver = 5
	var ret SenML

	var totalRecords int = 0
	for _, r := range senml.Records {
		if (r.Value != nil) || (len(r.StringValue) > 0) || (r.BoolValue != nil) {
			totalRecords += 1
		}
	}

	ret.XMLName = senml.XMLName
	ret.Xmlns = senml.Xmlns
	ret.Records = make([]SenMLRecord, totalRecords)
	var numRecords = 0

	for _, r := range senml.Records {
		if r.BaseTime != 0 {
			btime = r.BaseTime
		}
		if r.BaseVersion != 0 {
			ver = r.BaseVersion
		}
		if len(r.BaseUnit) > 0 {
			bunit = r.BaseUnit
		}
		if len(r.BaseName) > 0 {
			bname = r.BaseName
		}
		r.BaseTime = 0
		r.BaseUnit = ""
		r.BaseName = ""
		r.Name = bname + r.Name
		r.Time = btime + r.Time
		if len(r.Unit) == 0 {
			r.Unit = bunit
		}
		r.BaseVersion = ver

		if r.Time <= 0 {
			// convert to absolute time
			var now int64 = time.Now().UnixNano()
			var t int64 = now / 1000000000.0
			r.Time = float64(t) + r.Time
		}

		if (r.Value != nil) || (len(r.StringValue) > 0) || (r.BoolValue != nil) {
			ret.Records[numRecords] = r
			numRecords += 1
		}
	}

	return ret
}

// Test if SenML is valid
func IsValid(senml SenML) bool {
	var bname string = ""
	var bver = -1

	//fmt.Println("In Validate")

	for _, r := range senml.Records {

		// Check version is same for all records
		if bver == -1 {
			// set the bver the first time it is seen
			if r.BaseVersion != 0 {
				bver = r.BaseVersion
			}
		} else {
			if r.BaseVersion != 0 {
				// next time a version in seen, check it has not changed
				if r.BaseVersion != bver {
					//fmt.Println("unallowed version change ")
					return false
				}
			}
		}

		// Check name
		if len(r.BaseName) > 0 {
			bname = r.BaseName
		}
		name := bname + r.Name
		if len(name) == 0 {
			//fmt.Println("empty name")

			return false
		}
		if (name[0] == '-') || (name[0] == ':') || (name[0] == '.') || (name[0] == '/') || (name[0] == '_') {
			//fmt.Println("Bad first char in name")
			return false
		}
		for _, l := range name {
			if (l < 'a' || l > 'z') && (l < 'A' || l > 'Z') && (l < '0' || l > '9') && (l != '-') && (l != ':') && (l != '.') && (l != '/') && (l != '_') {
				//fmt.Println("Bad char in name")
				return false
			}
		}

		valueCount := 0
		if r.Value != nil {
			valueCount = valueCount + 1
		}
		if r.BoolValue != nil {
			valueCount = valueCount + 1
		}
		if len(r.DataValue) > 0 {
			valueCount = valueCount + 1
		}
		if len(r.StringValue) > 0 {
			valueCount = valueCount + 1
		}
		if valueCount > 1 {
			//fmt.Println("Too many values ")
			return false
		}
		if r.Sum != nil {
			valueCount = valueCount + 1
		}
		if valueCount < 1 {
			//fmt.Println("No value or sum")
			return false
		}

		// Check if name is known Mandatory To Understand
		//for k :=  r {
		// 	fmt.Println( "key=" , k  )
		//         if k[ len(k)-1 ] == '_' {
		//         	fmt.Println("unknown MTU in record")
		//		return false
		//        }
		// }
	}

	return true
}
<|endoftext|>