<commit_before>package main

import (
	"errors"
	"fmt"
	"math"
	"strconv"

	"code.google.com/p/goprotobuf/proto"

	pb "github.com/dgryski/carbonzipper/carbonzipperpb"
)

// expression parser

type exprType int

const (
	etMetric exprType = iota
	etFunc
	etConst
)

type expr struct {
	target    string
	etype     exprType
	val       float64
	args      []*expr
	argString string
}

func (e *expr) metrics() []string {

	switch e.etype {
	case etMetric:
		return []string{e.target}
	case etConst:
		return nil
	case etFunc:
		var r []string
		for _, a := range e.args {
			r = append(r, a.metrics()...)
		}
		return r
	}

	return nil
}

func parseExpr(e string) (*expr, string, error) {

	if '0' <= e[0] && e[0] <= '9' {
		val, e, err := parseConst(e)
		return &expr{val: val, etype: etConst}, e, err
	}

	name, e := parseName(e)

	if e != "" && e[0] == '(' {
		exp := &expr{target: name, etype: etFunc}

		argString, args, e, err := parseArgList(e)
		exp.argString = argString
		exp.args = args

		return exp, e, err
	}

	return &expr{target: name}, e, nil
}

var (
	ErrMissingComma        = errors.New("missing comma")
	ErrUnexpectedCharacter = errors.New("unexpected character")
)

func parseArgList(e string) (string, []*expr, string, error) {

	var args []*expr

	if e[0] != '(' {
		panic("arg list should start with paren")
	}

	argString := e[1:]

	e = e[1:]

	for {
		var arg *expr
		var err error
		arg, e, err = parseExpr(e)
		if err != nil {
			return "", nil, "", err
		}
		args = append(args, arg)

		if e == "" {
			return "", nil, "", ErrMissingComma
		}

		if e[0] == ')' {
			return argString[:len(argString)-len(e)], args, e[1:], nil
		}

		if e[0] != ',' && e[0] != ' ' {
			return "", nil, "", ErrUnexpectedCharacter
		}

		e = e[1:]
	}
}

func isNameChar(r byte) bool {
	return false ||
		'a' <= r && r <= 'z' ||
		'A' <= r && r <= 'Z' ||
		'0' <= r && r <= '9' ||
		r == '.' || r == '_' || r == '-' || r == '*'
}

func isDigit(r byte) bool {
	return '0' <= r && r <= '9'
}

func parseConst(s string) (float64, string, error) {

	var i int
	for i < len(s) && isDigit(s[i]) {
		i++
	}

	v, err := strconv.ParseFloat(s[:i], 64)
	if err != nil {
		return 0, "", err
	}

	return v, s[i:], err
}

func parseName(s string) (string, string) {

	var i int
	for i < len(s) && isNameChar(s[i]) {
		i++
	}

	if i == len(s) {
		return s, ""
	}

	return s[:i], s[i:]
}

func evalExpr(e *expr, values map[string][]*pb.FetchResponse) []*pb.FetchResponse {

	// TODO(dgryski): this should reuse the FetchResponse structs instead of allocating new ones

	switch e.etype {
	case etMetric:
		return values[e.target]
	case etConst:
		p := pb.FetchResponse{Name: proto.String(e.target), Values: []float64{e.val}}
		return []*pb.FetchResponse{&p}
	}

	// evaluate the function
	switch e.target {
	case "keepLastValue":

		arg := evalExpr(e.args[0], values)

		keep := -1

		if len(e.args) > 1 {

			n := evalExpr(e.args[1], values)
			if len(n) != 1 || len(n[0].Values) != 1 {
				// fail
				return nil
			}

			keep = int(n[0].Values[0])

		}

		var results []*pb.FetchResponse

		for _, a := range arg {
			r := pb.FetchResponse{
				Name:      proto.String(fmt.Sprintf("keepLastValue(%s,%d)", e.argString, keep)),
				Values:    make([]float64, len(a.Values)),
				IsAbsent:  make([]bool, len(a.Values)),
				StepTime:  a.StepTime,
				StartTime: a.StartTime,
				StopTime:  a.StopTime,
			}

			prev := math.NaN()
			missing := 0

			for i, v := range a.Values {
				if a.IsAbsent[i] {

					if (keep < 0 || missing < keep) && !math.IsNaN(prev) {
						r.Values[i] = prev
						missing++
					} else {
						r.IsAbsent[i] = true
					}

					continue
				}
				missing = 0
				prev = v
				r.Values[i] = v
			}
			results = append(results, &r)
		}
		return results

	case "movingAverage":
		arg := evalExpr(e.args[0], values)
		n := evalExpr(e.args[1], values)
		if len(n) != 1 || len(n[0].Values) != 1 {
			// fail
			return nil
		}

		windowSize := int(n[0].Values[0])

		var result []*pb.FetchResponse

		for _, a := range arg {
			w := &Windowed{data: make([]float64, windowSize)}
			r := pb.FetchResponse{
				Name:      proto.String(fmt.Sprintf("movingAverage(%s, %d)", *a.Name, windowSize)),
				Values:    make([]float64, len(a.Values)),
				IsAbsent:  make([]bool, len(a.Values)),
				StepTime:  a.StepTime,
				StartTime: a.StartTime,
				StopTime:  a.StopTime,
			}
			for i, v := range a.Values {
				if a.IsAbsent[i] {
					// make sure missing values are ignored
					v = 0
				}
				w.Push(v)
				r.Values[i] = w.Mean()
			}
			result = append(result, &r)
		}
		return result

	case "nonNegativeDerivative":
		arg := evalExpr(e.args[0], values)
		var result []*pb.FetchResponse
		for _, a := range arg {
			r := pb.FetchResponse{
				Name:      proto.String(fmt.Sprintf("nonNegativeDerivative(%s)", *a.Name)),
				Values:    make([]float64, len(a.Values)),
				IsAbsent:  make([]bool, len(a.Values)),
				StepTime:  a.StepTime,
				StartTime: a.StartTime,
				StopTime:  a.StopTime,
			}
			prev := a.Values[0]
			for i, v := range a.Values {
				if i == 0 || a.IsAbsent[i] {
					r.IsAbsent[i] = true
					continue
				}

				r.Values[i] = v - prev
				if r.Values[i] < 0 {
					r.Values[i] = 0
					r.IsAbsent[i] = true
				}
				prev = v
			}
			result = append(result, &r)
		}
		return result

	case "scale":
		arg := evalExpr(e.args[0], values)
		n := evalExpr(e.args[1], values)
		if len(n) != 1 || len(n[0].Values) != 1 {
			// fail
			return nil
		}

		scale := n[0].Values[0]

		var results []*pb.FetchResponse

		for _, a := range arg {
			r := pb.FetchResponse{
				Name:      proto.String(fmt.Sprintf("scale(%s,%g)", e.argString, scale)),
				Values:    make([]float64, len(a.Values)),
				IsAbsent:  make([]bool, len(a.Values)),
				StepTime:  a.StepTime,
				StartTime: a.StartTime,
				StopTime:  a.StopTime,
			}

			for i, v := range a.Values {
				if a.IsAbsent[i] {
					r.Values[i] = 0
					r.IsAbsent[i] = true
					continue
				}
				r.Values[i] = v * scale
			}
			results = append(results, &r)
		}
		return results

	case "scaleToSeconds":
		arg := evalExpr(e.args[0], values)
		n := evalExpr(e.args[1], values)
		if len(n) != 1 || len(n[0].Values) != 1 {
			// fail
			return nil
		}

		seconds := n[0].Values[0]

		var results []*pb.FetchResponse

		for _, a := range arg {
			r := pb.FetchResponse{
				Name:      proto.String(fmt.Sprintf("scale(%s,%g)", e.argString, seconds)),
				Values:    make([]float64, len(a.Values)),
				StepTime:  a.StepTime,
				IsAbsent:  make([]bool, len(a.Values)),
				StartTime: a.StartTime,
				StopTime:  a.StopTime,
			}

			factor := seconds / float64(*a.StepTime)

			for i, v := range a.Values {
				if a.IsAbsent[i] {
					r.Values[i] = 0
					r.IsAbsent[i] = true
					continue
				}
				r.Values[i] = v * factor
			}
			results = append(results, &r)
		}
		return results

	case "sum", "sumSeries":
		// TODO(dgryski): make sure the arrays are all the same 'size'
		var args []*pb.FetchResponse
		for _, arg := range e.args {
			a := evalExpr(arg, values)
			args = append(args, a...)
		}
		r := pb.FetchResponse{
			Name:      proto.String(fmt.Sprintf("sum(%s)", e.argString)),
			Values:    make([]float64, len(args[0].Values)),
			IsAbsent:  make([]bool, len(args[0].Values)),
			StepTime:  args[0].StepTime,
			StartTime: args[0].StartTime,
			StopTime:  args[0].StopTime,
		}
		for _, arg := range args {
			for i, v := range arg.Values {
				if arg.IsAbsent[i] {
					continue
				}
				r.Values[i] += v
			}
		}
		return []*pb.FetchResponse{&r}
	}

	return nil
}

// From github.com/dgryski/go-onlinestats
// Copied here because we don't need the rest of the package, and we only need
// a small part of this type

type Windowed struct {
	data   []float64
	head   int
	length int
	sum    float64
}

func (w *Windowed) Push(n float64) {
	old := w.data[w.head]

	w.length++

	w.data[w.head] = n
	w.head++
	if w.head >= len(w.data) {
		w.head = 0
	}

	w.sum -= old
	w.sum += n
}

func (w *Windowed) Len() int {
	if w.length < len(w.data) {
		return w.length
	}

	return len(w.data)
}

func (w *Windowed) Mean() float64 { return w.sum / float64(w.Len()) }
<commit_msg>match graphite output for sum()<commit_after>package main

import (
	"errors"
	"fmt"
	"math"
	"strconv"

	"code.google.com/p/goprotobuf/proto"

	pb "github.com/dgryski/carbonzipper/carbonzipperpb"
)

// expression parser

type exprType int

const (
	etMetric exprType = iota
	etFunc
	etConst
)

type expr struct {
	target    string
	etype     exprType
	val       float64
	args      []*expr
	argString string
}

func (e *expr) metrics() []string {

	switch e.etype {
	case etMetric:
		return []string{e.target}
	case etConst:
		return nil
	case etFunc:
		var r []string
		for _, a := range e.args {
			r = append(r, a.metrics()...)
		}
		return r
	}

	return nil
}

func parseExpr(e string) (*expr, string, error) {

	if '0' <= e[0] && e[0] <= '9' {
		val, e, err := parseConst(e)
		return &expr{val: val, etype: etConst}, e, err
	}

	name, e := parseName(e)

	if e != "" && e[0] == '(' {
		exp := &expr{target: name, etype: etFunc}

		argString, args, e, err := parseArgList(e)
		exp.argString = argString
		exp.args = args

		return exp, e, err
	}

	return &expr{target: name}, e, nil
}

var (
	ErrMissingComma        = errors.New("missing comma")
	ErrUnexpectedCharacter = errors.New("unexpected character")
)

func parseArgList(e string) (string, []*expr, string, error) {

	var args []*expr

	if e[0] != '(' {
		panic("arg list should start with paren")
	}

	argString := e[1:]

	e = e[1:]

	for {
		var arg *expr
		var err error
		arg, e, err = parseExpr(e)
		if err != nil {
			return "", nil, "", err
		}
		args = append(args, arg)

		if e == "" {
			return "", nil, "", ErrMissingComma
		}

		if e[0] == ')' {
			return argString[:len(argString)-len(e)], args, e[1:], nil
		}

		if e[0] != ',' && e[0] != ' ' {
			return "", nil, "", ErrUnexpectedCharacter
		}

		e = e[1:]
	}
}

func isNameChar(r byte) bool {
	return false ||
		'a' <= r && r <= 'z' ||
		'A' <= r && r <= 'Z' ||
		'0' <= r && r <= '9' ||
		r == '.' || r == '_' || r == '-' || r == '*'
}

func isDigit(r byte) bool {
	return '0' <= r && r <= '9'
}

func parseConst(s string) (float64, string, error) {

	var i int
	for i < len(s) && isDigit(s[i]) {
		i++
	}

	v, err := strconv.ParseFloat(s[:i], 64)
	if err != nil {
		return 0, "", err
	}

	return v, s[i:], err
}

func parseName(s string) (string, string) {

	var i int
	for i < len(s) && isNameChar(s[i]) {
		i++
	}

	if i == len(s) {
		return s, ""
	}

	return s[:i], s[i:]
}

func evalExpr(e *expr, values map[string][]*pb.FetchResponse) []*pb.FetchResponse {

	// TODO(dgryski): this should reuse the FetchResponse structs instead of allocating new ones

	switch e.etype {
	case etMetric:
		return values[e.target]
	case etConst:
		p := pb.FetchResponse{Name: proto.String(e.target), Values: []float64{e.val}}
		return []*pb.FetchResponse{&p}
	}

	// evaluate the function
	switch e.target {
	case "keepLastValue":

		arg := evalExpr(e.args[0], values)

		keep := -1

		if len(e.args) > 1 {

			n := evalExpr(e.args[1], values)
			if len(n) != 1 || len(n[0].Values) != 1 {
				// fail
				return nil
			}

			keep = int(n[0].Values[0])

		}

		var results []*pb.FetchResponse

		for _, a := range arg {
			r := pb.FetchResponse{
				Name:      proto.String(fmt.Sprintf("keepLastValue(%s,%d)", e.argString, keep)),
				Values:    make([]float64, len(a.Values)),
				IsAbsent:  make([]bool, len(a.Values)),
				StepTime:  a.StepTime,
				StartTime: a.StartTime,
				StopTime:  a.StopTime,
			}

			prev := math.NaN()
			missing := 0

			for i, v := range a.Values {
				if a.IsAbsent[i] {

					if (keep < 0 || missing < keep) && !math.IsNaN(prev) {
						r.Values[i] = prev
						missing++
					} else {
						r.IsAbsent[i] = true
					}

					continue
				}
				missing = 0
				prev = v
				r.Values[i] = v
			}
			results = append(results, &r)
		}
		return results

	case "movingAverage":
		arg := evalExpr(e.args[0], values)
		n := evalExpr(e.args[1], values)
		if len(n) != 1 || len(n[0].Values) != 1 {
			// fail
			return nil
		}

		windowSize := int(n[0].Values[0])

		var result []*pb.FetchResponse

		for _, a := range arg {
			w := &Windowed{data: make([]float64, windowSize)}
			r := pb.FetchResponse{
				Name:      proto.String(fmt.Sprintf("movingAverage(%s, %d)", *a.Name, windowSize)),
				Values:    make([]float64, len(a.Values)),
				IsAbsent:  make([]bool, len(a.Values)),
				StepTime:  a.StepTime,
				StartTime: a.StartTime,
				StopTime:  a.StopTime,
			}
			for i, v := range a.Values {
				if a.IsAbsent[i] {
					// make sure missing values are ignored
					v = 0
				}
				w.Push(v)
				r.Values[i] = w.Mean()
			}
			result = append(result, &r)
		}
		return result

	case "nonNegativeDerivative":
		arg := evalExpr(e.args[0], values)
		var result []*pb.FetchResponse
		for _, a := range arg {
			r := pb.FetchResponse{
				Name:      proto.String(fmt.Sprintf("nonNegativeDerivative(%s)", *a.Name)),
				Values:    make([]float64, len(a.Values)),
				IsAbsent:  make([]bool, len(a.Values)),
				StepTime:  a.StepTime,
				StartTime: a.StartTime,
				StopTime:  a.StopTime,
			}
			prev := a.Values[0]
			for i, v := range a.Values {
				if i == 0 || a.IsAbsent[i] {
					r.IsAbsent[i] = true
					continue
				}

				r.Values[i] = v - prev
				if r.Values[i] < 0 {
					r.Values[i] = 0
					r.IsAbsent[i] = true
				}
				prev = v
			}
			result = append(result, &r)
		}
		return result

	case "scale":
		arg := evalExpr(e.args[0], values)
		n := evalExpr(e.args[1], values)
		if len(n) != 1 || len(n[0].Values) != 1 {
			// fail
			return nil
		}

		scale := n[0].Values[0]

		var results []*pb.FetchResponse

		for _, a := range arg {
			r := pb.FetchResponse{
				Name:      proto.String(fmt.Sprintf("scale(%s,%g)", e.argString, scale)),
				Values:    make([]float64, len(a.Values)),
				IsAbsent:  make([]bool, len(a.Values)),
				StepTime:  a.StepTime,
				StartTime: a.StartTime,
				StopTime:  a.StopTime,
			}

			for i, v := range a.Values {
				if a.IsAbsent[i] {
					r.Values[i] = 0
					r.IsAbsent[i] = true
					continue
				}
				r.Values[i] = v * scale
			}
			results = append(results, &r)
		}
		return results

	case "scaleToSeconds":
		arg := evalExpr(e.args[0], values)
		n := evalExpr(e.args[1], values)
		if len(n) != 1 || len(n[0].Values) != 1 {
			// fail
			return nil
		}

		seconds := n[0].Values[0]

		var results []*pb.FetchResponse

		for _, a := range arg {
			r := pb.FetchResponse{
				Name:      proto.String(fmt.Sprintf("scale(%s,%g)", e.argString, seconds)),
				Values:    make([]float64, len(a.Values)),
				StepTime:  a.StepTime,
				IsAbsent:  make([]bool, len(a.Values)),
				StartTime: a.StartTime,
				StopTime:  a.StopTime,
			}

			factor := seconds / float64(*a.StepTime)

			for i, v := range a.Values {
				if a.IsAbsent[i] {
					r.Values[i] = 0
					r.IsAbsent[i] = true
					continue
				}
				r.Values[i] = v * factor
			}
			results = append(results, &r)
		}
		return results

	case "sum", "sumSeries":
		// TODO(dgryski): make sure the arrays are all the same 'size'
		var args []*pb.FetchResponse
		for _, arg := range e.args {
			a := evalExpr(arg, values)
			args = append(args, a...)
		}
		r := pb.FetchResponse{
			Name:      proto.String(fmt.Sprintf("sumSeries(%s)", e.argString)),
			Values:    make([]float64, len(args[0].Values)),
			IsAbsent:  make([]bool, len(args[0].Values)),
			StepTime:  args[0].StepTime,
			StartTime: args[0].StartTime,
			StopTime:  args[0].StopTime,
		}
		for _, arg := range args {
			for i, v := range arg.Values {
				if arg.IsAbsent[i] {
					continue
				}
				r.Values[i] += v
			}
		}
		return []*pb.FetchResponse{&r}
	}

	return nil
}

// From github.com/dgryski/go-onlinestats
// Copied here because we don't need the rest of the package, and we only need
// a small part of this type

type Windowed struct {
	data   []float64
	head   int
	length int
	sum    float64
}

func (w *Windowed) Push(n float64) {
	old := w.data[w.head]

	w.length++

	w.data[w.head] = n
	w.head++
	if w.head >= len(w.data) {
		w.head = 0
	}

	w.sum -= old
	w.sum += n
}

func (w *Windowed) Len() int {
	if w.length < len(w.data) {
		return w.length
	}

	return len(w.data)
}

func (w *Windowed) Mean() float64 { return w.sum / float64(w.Len()) }
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/ActiveState/tail"
	"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/firehose"
	"github.com/foize/go.fifo"
	"os"
	"time"
)

type Configuration struct {
	Api_endpoint, Api_key, Project, Env        string
	Aws_region, Aws_access_key, Aws_secret_key string
	Firehose_stream_name                       string
	Shipping_interval                          int
	Components                                 []Component
}

type Component struct {
	Name, File string
}

type Message struct {
	Project, Env, Component, Text string
	Timestamp                     int64
}

func main() {
	// load the configuration
	file, _ := os.Open("config.json")
	decoder := json.NewDecoder(file)
	configuration := Configuration{}
	err := decoder.Decode(&configuration)
	if err != nil {
		fmt.Println("Error reading config.json:", err)
	}

	// declare our outgoing queue
	outgoing := fifo.NewQueue()

	// initialize aws sdk and credentials from configuration
	svc := firehose.New(session.New(), &aws.Config{Region: aws.String(configuration.Aws_region),
		Credentials: credentials.NewStaticCredentials(configuration.Aws_access_key, configuration.Aws_secret_key, "")})
	fmt.Println("region", configuration.Aws_region)
	fmt.Println(svc)
	streams, err := svc.ListDeliveryStreams(&firehose.ListDeliveryStreamsInput{})
	fmt.Println(streams)
	fmt.Println(err)

	// start Filewatchers for the files
	for _, comp := range configuration.Components {
		fmt.Println("Watching", comp.Name, "at", comp.File)
		go Filewatcher(comp, configuration, outgoing)
	}

	// loop
	for {
		outlen := outgoing.Len()
		if outlen > 0 {
			// create a request body
			var data = bytes.NewBuffer([]byte(``))
			encoder := json.NewEncoder(data)

			// add queue contents as payload
			var items []*Message
			for {
				item := outgoing.Next()
				if item == nil {
					break
				}
				items = append(items, item.(*Message))
			}

			// encode json and send request
			buf, err := json.Marshal(items)
			if err != nil {
				fmt.Println("Encoding error:", error)
				continue
			}

			params := &firehose.PutRecordInput{
				DeliveryStreamName: aws.String(configuration.Firehose_stream_name), // Required
				Record: &firehose.Record{ // Required
					Data: buf, // Required
				},
			}
			resp, err := svc.PutRecord(params)

			if err != nil {
				// Print the error, cast err to awserr.Error to get the Code and
				// Message from an error.
				fmt.Println(err.Error())
				return
			} else {
				fmt.Println(resp)
			}
		}
		time.Sleep(time.Duration(configuration.Shipping_interval) * time.Second)
	}
}

func Filewatcher(comp Component, conf Configuration, outgoing *fifo.Queue) {
	// tail a given file, add appended lines into a Message queue
	t, _ := tail.TailFile(comp.File, tail.Config{Follow: true})
	for line := range t.Lines {
		outgoing.Add(&Message{
			Project:   conf.Project,
			Env:       conf.Env,
			Component: comp.Name,
			Text:      line.Text,
			Timestamp: time.Now().Unix(),
		})
	}
}
<commit_msg>feat(json): Encode JSON as newline delimited records instead of array<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/ActiveState/tail"
	"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/firehose"
	"github.com/foize/go.fifo"
	"os"
	"time"
)

type Configuration struct {
	Api_endpoint, Api_key, Project, Env        string
	Aws_region, Aws_access_key, Aws_secret_key string
	Firehose_stream_name                       string
	Shipping_interval                          int
	Components                                 []Component
}

type Component struct {
	Name, File string
}

type Message struct {
	Project, Env, Component, Text string
	Timestamp                     int64
}

func main() {
	// load the configuration
	file, _ := os.Open("config.json")
	decoder := json.NewDecoder(file)
	configuration := Configuration{}
	err := decoder.Decode(&configuration)
	if err != nil {
		fmt.Println("Error reading config.json:", err)
	}

	// declare our outgoing queue
	outgoing := fifo.NewQueue()

	// initialize aws sdk and credentials from configuration
	svc := firehose.New(session.New(), &aws.Config{Region: aws.String(configuration.Aws_region),
		Credentials: credentials.NewStaticCredentials(configuration.Aws_access_key, configuration.Aws_secret_key, "")})
	fmt.Println("region", configuration.Aws_region)
	fmt.Println(svc)
	streams, err := svc.ListDeliveryStreams(&firehose.ListDeliveryStreamsInput{})
	fmt.Println(streams)
	fmt.Println(err)

	// start Filewatchers for the files
	for _, comp := range configuration.Components {
		fmt.Println("Watching", comp.Name, "at", comp.File)
		go Filewatcher(comp, configuration, outgoing)
	}

	// loop
	for {
		outlen := outgoing.Len()
		if outlen > 0 {
			// create a request body
			var data = bytes.NewBuffer([]byte(``))
			encoder := json.NewEncoder(data)

			// add queue contents as payload
			for {
				item := outgoing.Next()
				if item == nil {
					break
				}

				error := encoder.Encode(item)

				if error != nil {
					fmt.Println("Encoding error: ", error)
				}

			}
			fmt.Println("Buf", data.String())

			params := &firehose.PutRecordInput{
				DeliveryStreamName: aws.String(configuration.Firehose_stream_name), // Required
				Record: &firehose.Record{ // Required
					Data: data.Bytes(), // Required
				},
			}
			resp, err := svc.PutRecord(params)

			if err != nil {
				// Print the error, cast err to awserr.Error to get the Code and
				// Message from an error.
				fmt.Println(err.Error())
				return
			} else {
				fmt.Println(resp)
			}
		}
		time.Sleep(time.Duration(configuration.Shipping_interval) * time.Second)
	}
}

func Filewatcher(comp Component, conf Configuration, outgoing *fifo.Queue) {
	// tail a given file, add appended lines into a Message queue
	t, _ := tail.TailFile(comp.File, tail.Config{Follow: true})
	for line := range t.Lines {
		outgoing.Add(&Message{
			Project:   conf.Project,
			Env:       conf.Env,
			Component: comp.Name,
			Text:      line.Text,
			Timestamp: time.Now().Unix(),
		})
	}
}
<|endoftext|>


<commit_before>// Copyright 2011, Bryan Matsuo. 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

/*
 *  Filename:    file.go
 *  Package:     main
 *  Author:      Bryan Matsuo <bmatsuo@soe.ucsc.edu>
 *  Created:     Sun Jul  3 16:57:42 PDT 2011
 *  Description:
 */
import (
	"fmt"
	"strings"
	"unicode"
)

func TestName(filename string) string {
	var test = filename
	if strings.HasSuffix(test, ".go") {
		test = test[:len(test)-3]
	}
	if strings.HasSuffix(test, "_test") {
		test = test[:len(test)-5]
	}
	return strings.Title(
		strings.Map(
			func(c rune) rune {
				if unicode.IsNumber(c) || unicode.IsLetter(c) {
					return c
				}
				return -1
			},
			test))
}

type FileType uint

const (
	GoFile FileType = iota
	ReadmeFile
	MakeFile
	LicenseFile
	OtherFile
)

//  ProjectFile satisfies the Context interface.
type ProjectFile struct {
	Name      string
	Desc      string
	Type      FileType
	Template  string
	DebugDesc string
	p         Project
}

func (f ProjectFile) Filename() string { return f.Name }

func (f ProjectFile) Package() string {
	if f.p.Type == PkgType {
		return f.p.Target
	}
	return "main"
}

func (f ProjectFile) Imports() []string        { return f.p.ImportLibs }
func (f ProjectFile) Description() string      { return f.Desc }
func (f ProjectFile) DebugDescription() string { return f.DebugDesc }
func (f ProjectFile) Tests() []string {
	return []string{TestName(f.p.Target)}
}
func (f ProjectFile) Project() Project         { return f.p }
func (f ProjectFile) LicenseType() LicenseType { return f.p.License }
func (f ProjectFile) FileType() FileType       { return f.Type }

func (f ProjectFile) Create() (err error) {
	return CreateFile(f, f.Template)
}

type TestFile struct {
	File
	Name    string
	Pkg     string
	License LicenseType
	Repo    RepoType
	Host    RepoHost
}

func (t TestFile) Filename() string  { return t.Name + "_test.go" }
func (t TestFile) Package() string   { return t.Pkg }
func (t TestFile) Imports() []string { return nil }
func (t TestFile) Description() string {
	return fmt.Sprintf("For testing %s", t.File.Filename())
}
func (t TestFile) DebugDescription() string {
	return "test for " + t.File.Filename()
}
func (t TestFile) FileType() FileType       { return GoFile }
func (t TestFile) Tests() []string          { return t.File.Tests() }
func (t TestFile) Project() Project         { return Project{} }
func (t TestFile) LicenseType() LicenseType { return t.License }
func (t TestFile) Create() error {
	return CreateFile(t, "test.t")
}

func (t TestFile) TemplatePath() []string { return []string{"testfiles", "pkg.t"} }

type File struct {
	Name       string
	User       string
	Pkg        string
	ImportLibs []string
	Desc       string
	License    LicenseType
	Repo       RepoType
	Host       RepoHost
}

func (f File) Filename() string         { return f.Name + ".go" }
func (f File) Package() string          { return f.Pkg }
func (f File) Imports() []string        { return f.ImportLibs }
func (f File) Description() string      { return f.Desc }
func (f File) DebugDescription() string { return "library" }
func (f File) FileType() FileType       { return GoFile }
func (f File) Tests() []string          { return []string{TestName(f.Name)} }
func (f File) Project() Project         { return Project{} }
func (f File) LicenseType() LicenseType { return f.License }
func (f File) Create() error {
	return CreateFile(f, "go.lib.t")
}

func (f File) TemplatePath() []string { return []string{"gofiles", "lib.t"} }
func (f File) TestFile() TestFile {
	return TestFile{File: f, Name: f.Name, Pkg: f.Pkg, Repo: f.Repo, Host: f.Host}
}
<commit_msg>Clean up file.go methods.<commit_after>// Copyright 2011, Bryan Matsuo. 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

/*
 *  Filename:    file.go
 *  Package:     main
 *  Author:      Bryan Matsuo <bmatsuo@soe.ucsc.edu>
 *  Created:     Sun Jul  3 16:57:42 PDT 2011
 *  Description:
 */
import (
	"fmt"
	"strings"
	"unicode"
)

func TestName(filename string) string {
	var test = filename
	if strings.HasSuffix(test, ".go") {
		test = test[:len(test)-3]
	}
	if strings.HasSuffix(test, "_test") {
		test = test[:len(test)-5]
	}
	return strings.Title(
		strings.Map(
			func(c rune) rune {
				if unicode.IsNumber(c) || unicode.IsLetter(c) {
					return c
				}
				return -1
			},
			test))
}

type FileType uint

const (
	GoFile FileType = iota
	ReadmeFile
	MakeFile
	LicenseFile
	OtherFile
)

//  ProjectFile satisfies the Context interface.
type ProjectFile struct {
	Name      string
	Desc      string
	Type      FileType
	Template  string
	DebugDesc string
	p         Project
}

func (f ProjectFile) Filename() string { return f.Name }

func (f ProjectFile) Package() string {
	if f.p.Type == PkgType {
		return f.p.Target
	}
	return "main"
}

func (f ProjectFile) Imports() []string        { return f.p.ImportLibs }
func (f ProjectFile) Description() string      { return f.Desc }
func (f ProjectFile) DebugDescription() string { return f.DebugDesc }
func (f ProjectFile) Tests() []string          { return []string{TestName(f.p.Target)} }
func (f ProjectFile) Project() Project         { return f.p }
func (f ProjectFile) LicenseType() LicenseType { return f.p.License }
func (f ProjectFile) FileType() FileType       { return f.Type }
func (f ProjectFile) Create() (err error)      { return CreateFile(f, f.Template) }

type TestFile struct {
	File
	Name    string
	Pkg     string
	License LicenseType
	Repo    RepoType
	Host    RepoHost
}

func (t TestFile) Filename() string         { return t.Name + "_test.go" }
func (t TestFile) Package() string          { return t.Pkg }
func (t TestFile) Imports() []string        { return nil }
func (t TestFile) Description() string      { return fmt.Sprintf("For testing %s", t.File.Filename()) }
func (t TestFile) DebugDescription() string { return "test for " + t.File.Filename() }
func (t TestFile) FileType() FileType       { return GoFile }
func (t TestFile) Tests() []string          { return t.File.Tests() }
func (t TestFile) Project() Project         { return Project{} }
func (t TestFile) LicenseType() LicenseType { return t.License }
func (t TestFile) Create() error            { return CreateFile(t, "test.t") }

func (t TestFile) TemplatePath() []string { return []string{"testfiles", "pkg.t"} }

type File struct {
	Name       string
	User       string
	Pkg        string
	ImportLibs []string
	Desc       string
	License    LicenseType
	Repo       RepoType
	Host       RepoHost
}

func (f File) Filename() string         { return f.Name + ".go" }
func (f File) Package() string          { return f.Pkg }
func (f File) Imports() []string        { return f.ImportLibs }
func (f File) Description() string      { return f.Desc }
func (f File) DebugDescription() string { return "library" }
func (f File) FileType() FileType       { return GoFile }
func (f File) Tests() []string          { return []string{TestName(f.Name)} }
func (f File) Project() Project         { return Project{} }
func (f File) LicenseType() LicenseType { return f.License }
func (f File) Create() error            { return CreateFile(f, "go.lib.t") }

func (f File) TemplatePath() []string { return []string{"gofiles", "lib.t"} }
func (f File) TestFile() TestFile {
	return TestFile{File: f, Name: f.Name, Pkg: f.Pkg, Repo: f.Repo, Host: f.Host}
}
<|endoftext|>


<commit_before>package buffer

import (
	"encoding/gob"
	"io"
	"io/ioutil"
	"os"
)

type File struct {
	file     *os.File
	Filename string
	N        int64
	L        int64
	ROff     int64
	WOff     int64
}

func NewFile(N int64) *File {
	buf := &File{
		N: N,
	}
	return buf
}

func (buf *File) init() (err error) {
	var file *os.File

	if buf.file == nil {

		if buf.Filename != "" {
			if file, err = os.OpenFile(buf.Filename, os.O_CREATE|os.O_RDWR, 0644); err != nil {
				return err
			}
		} else if file, err = ioutil.TempFile("", "buffer"); err != nil {
			return err
		}

		buf.file = file
		buf.Filename = file.Name()
		buf.ROff = 0
		buf.WOff = 0
	}

	return nil
}

func (buf *File) Len() int64 {
	return buf.L
}

func (buf *File) Cap() int64 {
	return buf.N
}

func (buf *File) ReadAt(p []byte, off int64) (n int, err error) {
	if err := buf.init(); err != nil {
		return 0, err
	}

	wrap := NewWrapReader(buf.file, buf.ROff+off, buf.Cap())
	r := io.LimitReader(wrap, buf.Len()-off)
	return r.Read(p)
}

func (buf *File) Read(p []byte) (n int, err error) {
	if err := buf.init(); err != nil {
		return 0, err
	}

	wrap := NewWrapReader(buf.file, buf.ROff, buf.Cap())
	r := io.LimitReader(wrap, buf.Len())

	n, err = r.Read(p)
	buf.L -= int64(n)
	buf.ROff = (buf.ROff + int64(n)) % buf.Cap()

	if Empty(buf) {
		buf.Reset()
	}

	return n, err
}

func (buf *File) Write(p []byte) (n int, err error) {
	if err := buf.init(); err != nil {
		return 0, err
	}

	wrap := NewWrapWriter(buf.file, buf.WOff, buf.Cap())
	w := LimitWriter(wrap, Gap(buf))
	n, err = w.Write(p)
	buf.L += int64(n)
	buf.WOff = (buf.WOff + int64(n)) % buf.Cap()

	return n, err
}

func (buf *File) WriteAt(p []byte, off int64) (n int, err error) {
	if err := buf.init(); err != nil {
		return 0, err
	}

	wrap := NewWrapWriter(buf.file, off, buf.Cap())
	w := LimitWriter(wrap, buf.Cap()-off)
	n, err = w.Write(p)
	if off+int64(n) > buf.Len() {
		buf.L = int64(n) + off
	}
	return n, err
}

func (buf *File) Reset() {
	if buf.file != nil {
		buf.file.Close()
		os.Remove(buf.file.Name())
		buf.file = nil
		buf.Filename = ""
		buf.ROff = 0
		buf.WOff = 0
	}
}

func (buf *File) FFwd(n int64) int64 {
	if int64(n) > buf.Len() {
		n = buf.Len()
	}

	buf.L -= int64(n)
	buf.ROff = (buf.ROff + int64(n)) % buf.Cap()

	return n
}

func init() {
	gob.Register(&File{})
}
<commit_msg>Added custom directory for File-based buffers. Can only be set once, and must be set before any file buffers are used.<commit_after>package buffer

import (
	"encoding/gob"
	"errors"
	"io"
	"io/ioutil"
	"os"
	"sync"
)

var dataDir string
var setDataDir sync.Once

// BUG(Dustin): Path is created even if its not used.
func SetDataDir(path string, perm os.FileMode) (err error) {
	if err = os.MkdirAll(path, perm); err == nil {
		err = errors.New("already set")
		setDataDir.Do(func() {
			dataDir = path
			err = nil
		})
	}
	return err
}

type File struct {
	file     *os.File
	Filename string
	N        int64
	L        int64
	ROff     int64
	WOff     int64
}

func NewFile(N int64) *File {
	buf := &File{
		N: N,
	}
	return buf
}

func (buf *File) init() (err error) {
	var file *os.File

	if buf.file == nil {

		setDataDir.Do(func() {
			dataDir = ""
		})

		if buf.Filename != "" {
			if file, err = os.OpenFile(buf.Filename, os.O_CREATE|os.O_RDWR, 0644); err != nil {
				return err
			}
		} else if file, err = ioutil.TempFile(dataDir, "buffer"); err != nil {
			return err
		}

		buf.file = file
		buf.Filename = file.Name()
		buf.ROff = 0
		buf.WOff = 0
	}

	return nil
}

func (buf *File) Len() int64 {
	return buf.L
}

func (buf *File) Cap() int64 {
	return buf.N
}

func (buf *File) ReadAt(p []byte, off int64) (n int, err error) {
	if err := buf.init(); err != nil {
		return 0, err
	}

	wrap := NewWrapReader(buf.file, buf.ROff+off, buf.Cap())
	r := io.LimitReader(wrap, buf.Len()-off)
	return r.Read(p)
}

func (buf *File) Read(p []byte) (n int, err error) {
	if err := buf.init(); err != nil {
		return 0, err
	}

	wrap := NewWrapReader(buf.file, buf.ROff, buf.Cap())
	r := io.LimitReader(wrap, buf.Len())

	n, err = r.Read(p)
	buf.L -= int64(n)
	buf.ROff = (buf.ROff + int64(n)) % buf.Cap()

	if Empty(buf) {
		buf.Reset()
	}

	return n, err
}

func (buf *File) Write(p []byte) (n int, err error) {
	if err := buf.init(); err != nil {
		return 0, err
	}

	wrap := NewWrapWriter(buf.file, buf.WOff, buf.Cap())
	w := LimitWriter(wrap, Gap(buf))
	n, err = w.Write(p)
	buf.L += int64(n)
	buf.WOff = (buf.WOff + int64(n)) % buf.Cap()

	return n, err
}

func (buf *File) WriteAt(p []byte, off int64) (n int, err error) {
	if err := buf.init(); err != nil {
		return 0, err
	}

	wrap := NewWrapWriter(buf.file, off, buf.Cap())
	w := LimitWriter(wrap, buf.Cap()-off)
	n, err = w.Write(p)
	if off+int64(n) > buf.Len() {
		buf.L = int64(n) + off
	}
	return n, err
}

func (buf *File) Reset() {
	if buf.file != nil {
		buf.file.Close()
		os.Remove(buf.file.Name())
		buf.file = nil
		buf.Filename = ""
		buf.ROff = 0
		buf.WOff = 0
	}
}

func (buf *File) FFwd(n int64) int64 {
	if int64(n) > buf.Len() {
		n = buf.Len()
	}

	buf.L -= int64(n)
	buf.ROff = (buf.ROff + int64(n)) % buf.Cap()

	return n
}

func init() {
	gob.Register(&File{})
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"runtime"
)

func fileExists(path string) (bool, error) {
	var err error
	if runtime.GOOS == "windows" {
		// Windows doesn't seem to like using os.Stat
		_, err = os.Open(path)
	} else {
		_, err = os.Stat(path)
	}
	if err != nil {
		if os.IsNotExist(err) {
			return false, nil
		}
		return false, err
	}
	return true, nil
}
<commit_msg>fixed file exists on windows<commit_after>package main

import "os"

func fileExists(path string) (bool, error) {
	if _, err := os.Stat(path); err != nil {
		if os.IsNotExist(err) {
			return false, nil
		}
		return false, err
	}
	return true, nil
}
<|endoftext|>


<commit_before>package fsql

import (
	"fmt"
	"os"

	"github.com/kshvmdn/fsql/parser"
)

// Run parses the input and executes the resultant query.
func Run(input string) error {
	q, err := parser.Run(input)
	if err != nil {
		return err
	}

	// Find length of the longest name to normalize name output.
	var max = 0
	var results = make([]map[string]interface{}, 0)

	err = q.Execute(
		func(path string, info os.FileInfo, result map[string]interface{}) {
			results = append(results, result)
			if !q.HasAttribute("name") {
				return
			}
			if s, ok := result["name"].(string); ok && len(s) > max {
				max = len(s)
			}
		},
	)
	if err != nil {
		return err
	}

	for _, result := range results {
		for j, attribute := range q.Attributes {
			// If the current attribute is "name", pad the output string by `max`
			// spaces.
			format := "%v"
			if attribute == "name" {
				format = fmt.Sprintf("%%-%ds", max)
			}
			fmt.Printf(format, result[attribute])
			if j != len(q.Attributes)-1 {
				fmt.Print("\t")
			}
		}
		fmt.Print("\n")
	}

	return nil
}
<commit_msg>Buffer each result line before printing<commit_after>package fsql

import (
	"bytes"
	"fmt"
	"os"

	"github.com/kshvmdn/fsql/parser"
)

// Run parses the input and executes the resultant query.
func Run(input string) error {
	q, err := parser.Run(input)
	if err != nil {
		return err
	}

	// Find length of the longest name to normalize name output.
	var max = 0
	var results = make([]map[string]interface{}, 0)

	err = q.Execute(
		func(path string, info os.FileInfo, result map[string]interface{}) {
			results = append(results, result)
			if !q.HasAttribute("name") {
				return
			}
			if s, ok := result["name"].(string); ok && len(s) > max {
				max = len(s)
			}
		},
	)
	if err != nil {
		return err
	}

	for _, result := range results {
		var buf bytes.Buffer
		for j, attribute := range q.Attributes {
			// If the current attribute is "name", pad the output string by `max`
			// spaces.
			format := "%v"
			if attribute == "name" {
				format = fmt.Sprintf("%%-%ds", max)
			}
			buf.WriteString(fmt.Sprintf(format, result[attribute]))
			if j != len(q.Attributes)-1 {
				buf.WriteString("\t")
			}
		}
		fmt.Printf("%s\n", buf.String())
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import(
	"os"
	"fmt"
	"bufio"
	"io/ioutil"
)

var state [65535]byte
var index = 0

var whileIndex = 0

func main() {
	p, err := ioutil.ReadFile(os.Args[1])
	if err != nil {
		fmt.Println("Did you supply a file?")
		return
	}
	reader := bufio.NewReader(os.Stdin)
	for i := 0; i < len(p); i++ {
		switch a := string(p[i]); a {
		default: fmt.Print()
		case ">": index++
		case "<": if index > 0 { index-- }
		case "+": state[index]++
		case "-": state[index]--

		case ".": fmt.Print(string(state[index]))
		case ",": state[index], _ = reader.ReadByte()

		// TODO: I don't think this works.
		case "[":
			whileIndex, whileState = index, i
			fmt.Println("HEHE")

		case "]":
			fmt.Println(state[whileIndex])
			if state[whileIndex] != 0 {
				index = whileState
			}
		}
	}
}
<commit_msg>Less converting between char and string<commit_after>package main

import(
	"os"
	"fmt"
	"bufio"
	"io/ioutil"
)

var state [65535]byte
var index = 0

var whileIndex = 0

func main() {
	p, err := ioutil.ReadFile(os.Args[1])
	if err != nil {
		fmt.Println("Did you supply a file?")
		return
	}
	reader := bufio.NewReader(os.Stdin)
	for i := 0; i < len(p); i++ {
		switch p[i] {
		default: fmt.Print()
		case '>': index++
		case '<': if index > 0 { index-- }
		case '+': state[index]++
		case '-': state[index]--

		case '.': fmt.Print(string(state[index]))
		case ',': state[index], _ = reader.ReadByte()

		// TODO: I don't think this works.
		case '[':
			whileIndex, whileState = index, i
			fmt.Println("HEHE")

		case ']':
			fmt.Println(state[whileIndex])
			if state[whileIndex] != 0 {
				index = whileState
			}
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/subtle"
	"encoding/hex"
	"fmt"
	"sync"
	"time"
)

type MoveType string

const (
	Hint    MoveType = "hint"
	Play             = "play"
	Discard          = "discard"
)

type Color string

const (
	Red    Color = "red"
	Yellow Color = "yellow"
	Green  Color = "green"
	Blue   Color = "blue"
	Black  Color = "black"
	White  Color = "white"
)

type GameState string

const (
	NotStarted     GameState = "not-started"
	WaitingForTurn GameState = "waiting-for-turn"
	YourTurn       GameState = "your-turn"
	Finished       GameState = "finished"
)

var Colors = [...]Color{Red, Yellow, Green, Blue, White}
var Numbers = [...]int{1, 2, 3, 4, 5}

type Move struct {
	Type MoveType `json:"type"`
	// for Hint:
	ToPlayer string `json:"to_player"`
	Color    Color  `json:"color"`
	Number   int    `json:"number"`
	CardIds  []int  `json:"card_ids"`
	// for Play/Discard:
	CardId int `json:"card_id"`
}

type Card struct {
	Id     int   `json:"id"`
	Color  Color `json:"color"`
	Number int   `json:"number"`
}

// Card implements Cardy
var _ Cardy = (*Card)(nil)

func (f *Card) GetId() int {
	return f.Id
}

func (f *Card) Hide() HiddenCard {
	return HiddenCard{
		Id: f.Id,
	}
}

type HiddenCard struct {
	Id int `json:"id"`
}

// HiddenCard implements Cardy
var _ Cardy = (*HiddenCard)(nil)

func (h *HiddenCard) GetId() int {
	return h.Id
}

type Cardy interface {
	GetId() int
}
type Deck []Card
type Turn struct {
	Id     int    `json:"id"`
	Player string `json:"player"`
	Move   Move   `json:"move"`
	// no NewCard for Hint move
	NewCard Card `json:"new_card"`
}

type GameStateSummary struct {
	State      GameState         `json:"state"`
	Players    []string          `json:"players"`
	Hand       []HiddenCard      `json:"hand"`        // the focused player's hand
	OtherHands map[string][]Card `json:"other_hands"` // the other player's hands
	Board      map[Color]int     `json:"board"`
	Discard    []Card            `json:"discard"`
	Turns      []Turn            `json:"turns"`
	TurnCursor int               `json:"turn_cursor"`
}

// 64-bit hex
type SessionToken string

func RandomSessionToken() (res SessionToken, err error) {
	bs, err := RandBytes(8)
	if err != nil {
		return res, err
	}
	return SessionToken(hex.EncodeToString(bs)), nil
}

// Calling only methods that start with Locking is threadsafe.
type Game struct {
	sync.Mutex

	// Immutable Fields
	Name       string
	NumPlayers int
	cardsById  map[int]Card

	// Mutable, private fields
	players   []string
	sessions  map[string]SessionToken // player -> session token
	turns     []Turn
	deck      Deck
	hands     map[string][]Card
	board     map[Color]int
	discard   []Card
	whoseTurn int // Index into players. Use -1 when game is over
}

// func (g *Game) move(move Move, player string) (GetStateResponse, error) {
// 	lastTurn := len(g.turns)
// 	if player != g.players[g.whoseTurn] {
// 		return MoveResponse{NotYourTurn, g.InfoResponse(player, lastTurn)}
// 	}
// 	//type Move struct {
// 	//Type MoveType `json:"type"`
// 	//// for Hint:
// 	//ToPlayer string `json:"to_player"`
// 	//Color    Color  `json:"color"`
// 	//Number   int    `json:"number"`
// 	//CardIds  []int  `json:"card_ids"`
// 	//for Play/Discard:
// 	//CardId int `json:"card_id"`

// 	//type Turn struct {
// 	//Id     int    `json:"id"`
// 	//Player string `json:"player"`
// 	//Move   Move   `json:"move"`
// 	// no NewCard for Hint move
// 	//NewCard Card `json:"new_card"`
// 	var turn Turn
// 	turn.Id = g.turns[len(g.turns)-1].Id + 1
// 	turn.Player = player
// 	switch move.Type {
// 	case Hint:
// 		// TODO Make sure the hint is legal
// 		//for _, card := range g.hands[move.ToPlayer] {
// 		//}
// 	case Play:
// 		// TODO Bomb or edit board
// 	case Discard:
// 		// TODO Add to Discard
// 	}
// 	return MoveResponse{Ok, g.InfoResponse(player, lastTurn)}
// }

func (g *Game) LockingAddPlayer(playerName string) (session SessionToken, err error) {
	g.Lock()
	defer g.Unlock()

	if len(g.players) >= g.NumPlayers {
		return session, fmt.Errorf("the game is full (%v/%v players)", len(g.players), g.NumPlayers)
	}
	for _, p := range g.players {
		if p == playerName {
			return session, fmt.Errorf("player with that name is already in the game")
		}
	}
	session, err = RandomSessionToken()
	if err != nil {
		return session, fmt.Errorf("error generating session token")
	}
	g.players = append(g.players, playerName)
	g.sessions[playerName] = session
	return session, nil
}

func (g *Game) LockingGetState(playerName string, session SessionToken, wait bool) (res GameStateSummary, err error) {
	err = g.checkPlayerSession(playerName, session)
	if err != nil {
		return res, err
	}
	for {
		res, err = g.lockingGetStateSummary(playerName, 0)
		if err != nil {
			return res, err
		}
		if !wait || res.State == YourTurn {
			return res, err
		}
		// TODO use a channel to make this faster
		<-time.NewTimer(time.Millisecond * 500).C
	}
}

// uses the game lock
func (g *Game) checkPlayerSession(playerName string, session SessionToken) error {
	g.Lock()
	defer g.Unlock()
	if !g.hasPlayer(playerName) {
		return fmt.Errorf("no player '%v'", playerName)
	}
	s2, ok := g.sessions[playerName]
	if !ok {
		// this should never happen
		return fmt.Errorf("missing session for '%v'", playerName)
	}
	if session == "" {
		return fmt.Errorf("session is required")
	}
	if subtle.ConstantTimeCompare([]byte(s2), []byte(session)) != 1 {
		return fmt.Errorf("invalid session for '%v'", playerName)
	}
	return nil
}

func (g *Game) hasPlayer(playerName string) bool {
	for _, p2 := range g.players {
		if playerName == p2 {
			return true
		}
	}
	return false
}

func (g *Game) lockingGetStateSummary(player string, turnCursor int) (GameStateSummary, error) {
	g.Lock()
	defer g.Unlock()
	return g.getStateSummary(player, turnCursor)
}

func (g *Game) getStateSummary(player string, turnCursor int) (GameStateSummary, error) {
	var resp GameStateSummary
	// fill these no matter what
	resp.Players = g.players
	resp.Board = g.board
	resp.Discard = g.discard
	resp.Hand = g.hiddenPlayerHand(player)
	resp.OtherHands = g.otherHands(player)

	if len(g.players) < g.NumPlayers {
		// Game has not started yet
		resp.State = NotStarted
		return resp, nil
	} else if g.whoseTurn == -1 {
		resp.State = Finished
	} else if g.players[g.whoseTurn] == player {
		resp.State = YourTurn
	} else {
		resp.State = WaitingForTurn
	}
	resp.Turns = g.turns[turnCursor:]
	resp.TurnCursor = len(g.turns)
	return resp, nil
}

// The hand of a player, as hidden cards
func (g *Game) hiddenPlayerHand(player string) (res []HiddenCard) {
	hand := g.hands[player]
	for _, card := range hand {
		res = append(res, card.Hide())
	}
	return res
}

// The hands of the players _except_ the specified player.
func (g *Game) otherHands(exceptPlayer string) map[string][]Card {
	res := make(map[string][]Card)
	for p2, hand := range g.hands {
		if p2 == exceptPlayer {
			continue
		}
		res[p2] = hand
	}
	return res
}

// // Take hands and hide the hand of the player.
// func hideCards(hands hands, player string) map[string][]Card {
// 	ret := make(map[string][]Card)
// 	for p, hand := range hands {
// 		if p == player {
// 			// Hide the cards for the player.
// 			ret[p] = nil
// 			for _, card := range hand {
// 				ret[p] = append(ret[p], card.Hide())
// 			}
// 		} else {
// 			// Pass through the other hands unmodified.
// 			ret[p] = hand
// 		}
// 	}
// }
<commit_msg>tweak<commit_after>package main

import (
	"crypto/subtle"
	"encoding/hex"
	"fmt"
	"sync"
	"time"
)

type MoveType string

const (
	Hint    MoveType = "hint"
	Play             = "play"
	Discard          = "discard"
)

type Color string

const (
	Red    Color = "red"
	Yellow Color = "yellow"
	Green  Color = "green"
	Blue   Color = "blue"
	Black  Color = "black"
	White  Color = "white"
)

type GameState string

const (
	NotStarted     GameState = "not-started"
	WaitingForTurn GameState = "waiting-for-turn"
	YourTurn       GameState = "your-turn"
	Finished       GameState = "finished"
)

var Colors = [...]Color{Red, Yellow, Green, Blue, White}
var Numbers = [...]int{1, 2, 3, 4, 5}

type Move struct {
	Type MoveType `json:"type"`
	// for Hint:
	ToPlayer string `json:"to_player"`
	Color    *Color `json:"color,omitempty"`
	Number   *int   `json:"number,omitempty"`
	CardIds  []int  `json:"card_ids,omitempty"`
	// for Play/Discard:
	CardId int `json:"card_id"`
}

type Card struct {
	Id     int   `json:"id"`
	Color  Color `json:"color"`
	Number int   `json:"number"`
}

// Card implements Cardy
var _ Cardy = (*Card)(nil)

func (f *Card) GetId() int {
	return f.Id
}

func (f *Card) Hide() HiddenCard {
	return HiddenCard{
		Id: f.Id,
	}
}

type HiddenCard struct {
	Id int `json:"id"`
}

// HiddenCard implements Cardy
var _ Cardy = (*HiddenCard)(nil)

func (h *HiddenCard) GetId() int {
	return h.Id
}

type Cardy interface {
	GetId() int
}
type Deck []Card
type Turn struct {
	Id     int    `json:"id"`     // turn number starting at 0
	Player string `json:"player"` // player that made the move
	Move   Move   `json:"move"`
	// no NewCard for Hint move
	NewCard Cardy `json:"new_card"`
}

type GameStateSummary struct {
	State      GameState         `json:"state"`
	Players    []string          `json:"players"`
	Hand       []HiddenCard      `json:"hand"`        // the focused player's hand
	OtherHands map[string][]Card `json:"other_hands"` // the other player's hands
	Board      map[Color]int     `json:"board"`
	Discard    []Card            `json:"discard"`
	Turns      []Turn            `json:"turns"`
	TurnCursor int               `json:"turn_cursor"`
}

// 64-bit hex
type SessionToken string

func RandomSessionToken() (res SessionToken, err error) {
	bs, err := RandBytes(8)
	if err != nil {
		return res, err
	}
	return SessionToken(hex.EncodeToString(bs)), nil
}

// Calling only methods that start with Locking is threadsafe.
type Game struct {
	sync.Mutex

	// Immutable Fields
	Name       string
	NumPlayers int
	cardsById  map[int]Card

	// Mutable, private fields
	players   []string
	sessions  map[string]SessionToken // player -> session token
	turns     []Turn
	deck      Deck
	hands     map[string][]Card
	board     map[Color]int
	discard   []Card
	whoseTurn int // Index into players. Use -1 when game is over
}

// func (g *Game) move(move Move, player string) (GetStateResponse, error) {
// 	lastTurn := len(g.turns)
// 	if player != g.players[g.whoseTurn] {
// 		return MoveResponse{NotYourTurn, g.InfoResponse(player, lastTurn)}
// 	}
// 	//type Move struct {
// 	//Type MoveType `json:"type"`
// 	//// for Hint:
// 	//ToPlayer string `json:"to_player"`
// 	//Color    Color  `json:"color"`
// 	//Number   int    `json:"number"`
// 	//CardIds  []int  `json:"card_ids"`
// 	//for Play/Discard:
// 	//CardId int `json:"card_id"`

// 	//type Turn struct {
// 	//Id     int    `json:"id"`
// 	//Player string `json:"player"`
// 	//Move   Move   `json:"move"`
// 	// no NewCard for Hint move
// 	//NewCard Card `json:"new_card"`
// 	var turn Turn
// 	turn.Id = g.turns[len(g.turns)-1].Id + 1
// 	turn.Player = player
// 	switch move.Type {
// 	case Hint:
// 		// TODO Make sure the hint is legal
// 		//for _, card := range g.hands[move.ToPlayer] {
// 		//}
// 	case Play:
// 		// TODO Bomb or edit board
// 	case Discard:
// 		// TODO Add to Discard
// 	}
// 	return MoveResponse{Ok, g.InfoResponse(player, lastTurn)}
// }

func (g *Game) LockingAddPlayer(playerName string) (session SessionToken, err error) {
	g.Lock()
	defer g.Unlock()

	if len(g.players) >= g.NumPlayers {
		return session, fmt.Errorf("the game is full (%v/%v players)", len(g.players), g.NumPlayers)
	}
	for _, p := range g.players {
		if p == playerName {
			return session, fmt.Errorf("player with that name is already in the game")
		}
	}
	session, err = RandomSessionToken()
	if err != nil {
		return session, fmt.Errorf("error generating session token")
	}
	g.players = append(g.players, playerName)
	g.sessions[playerName] = session
	return session, nil
}

func (g *Game) LockingGetState(playerName string, session SessionToken, wait bool) (res GameStateSummary, err error) {
	err = g.checkPlayerSession(playerName, session)
	if err != nil {
		return res, err
	}
	for {
		res, err = g.lockingGetStateSummary(playerName, 0)
		if err != nil {
			return res, err
		}
		if !wait || res.State == YourTurn {
			return res, err
		}
		// TODO use a channel to make this faster
		<-time.NewTimer(time.Millisecond * 500).C
	}
}

// uses the game lock
func (g *Game) checkPlayerSession(playerName string, session SessionToken) error {
	g.Lock()
	defer g.Unlock()
	if !g.hasPlayer(playerName) {
		return fmt.Errorf("no player '%v'", playerName)
	}
	s2, ok := g.sessions[playerName]
	if !ok {
		// this should never happen
		return fmt.Errorf("missing session for '%v'", playerName)
	}
	if session == "" {
		return fmt.Errorf("session is required")
	}
	if subtle.ConstantTimeCompare([]byte(s2), []byte(session)) != 1 {
		return fmt.Errorf("invalid session for '%v'", playerName)
	}
	return nil
}

func (g *Game) hasPlayer(playerName string) bool {
	for _, p2 := range g.players {
		if playerName == p2 {
			return true
		}
	}
	return false
}

func (g *Game) lockingGetStateSummary(player string, turnCursor int) (GameStateSummary, error) {
	g.Lock()
	defer g.Unlock()
	return g.getStateSummary(player, turnCursor)
}

func (g *Game) getStateSummary(player string, turnCursor int) (GameStateSummary, error) {
	var resp GameStateSummary
	// fill these no matter what
	resp.Players = g.players
	resp.Board = g.board
	resp.Discard = g.discard
	resp.Hand = g.hiddenPlayerHand(player)
	resp.OtherHands = g.otherHands(player)

	if len(g.players) < g.NumPlayers {
		// Game has not started yet
		resp.State = NotStarted
		return resp, nil
	} else if g.whoseTurn == -1 {
		resp.State = Finished
	} else if g.players[g.whoseTurn] == player {
		resp.State = YourTurn
	} else {
		resp.State = WaitingForTurn
	}
	resp.Turns = g.turns[turnCursor:]
	resp.TurnCursor = len(g.turns)
	return resp, nil
}

// The hand of a player, as hidden cards
func (g *Game) hiddenPlayerHand(player string) (res []HiddenCard) {
	hand := g.hands[player]
	for _, card := range hand {
		res = append(res, card.Hide())
	}
	return res
}

// The hands of the players _except_ the specified player.
func (g *Game) otherHands(exceptPlayer string) map[string][]Card {
	res := make(map[string][]Card)
	for p2, hand := range g.hands {
		if p2 == exceptPlayer {
			continue
		}
		res[p2] = hand
	}
	return res
}

// // Take hands and hide the hand of the player.
// func hideCards(hands hands, player string) map[string][]Card {
// 	ret := make(map[string][]Card)
// 	for p, hand := range hands {
// 		if p == player {
// 			// Hide the cards for the player.
// 			ret[p] = nil
// 			for _, card := range hand {
// 				ret[p] = append(ret[p], card.Hide())
// 			}
// 		} else {
// 			// Pass through the other hands unmodified.
// 			ret[p] = hand
// 		}
// 	}
// }
<|endoftext|>


<commit_before>package cryptica

import "bytes"

type Solution []Direction

func (solution *Solution) String() string {
	var buffer bytes.Buffer
	for i, dir := range *solution {
		switch {
		case i > 0:
			buffer.WriteRune(' ')
		default:
			buffer.WriteString(dir.String())
		}
	}
	return buffer.String()
}

type Game struct {
	State State
	Goal  Goal
	Steps int
}

type Solver interface {
	solve(game Game, solutions chan Solution)
}

type DepthFirstSolver struct {
}

func (solver DepthFirstSolver) solve(game Game, solutions chan Solution) {
	cache := make(map[uint64]int)
	f := func(state State, solution Solution, k interface{}) {
		n := len(solution)
		if n > game.Steps {
			return
		}
		code := state.Board.Encode(state)
		if m, exists := cache[code]; exists && m <= n {
			return
		}
		cache[code] = n
		if state.Match(game.Goal) {
			solutions <- solution
			return
		}
		f := k.(func(State, Solution, interface{}))
		for i := Up; i <= Right; i++ {
			dir := Direction(i)
			f(state.Move(dir), append(solution, dir), k)
		}
	}
	f(game.State, make(Solution, 0), f)
}

type BreadthFirstSolver struct {
}

func (solver BreadthFirstSolver) solve(game Game, solutions chan Solution) {
	cache := make(map[uint64]Solution)
	var current, next []uint64
	{
		code := game.State.Board.Encode(game.State)
		cache[code] = make(Solution, 0)
		current = []uint64{code}
	}
	for len(current) > 0 {
		next = make([]uint64, 0)
		for _, code := range current {
			solution := cache[code]
			state := game.State.Board.Decode(code)
			if state.Match(game.Goal) {
				solutions <- solution
				continue
			}
			for i := Up; i <= Right; i++ {
				dir := Direction(i)
				newstate := state.Move(dir)
				newcode := game.State.Board.Encode(newstate)
				if _, exists := cache[newcode]; !exists {
					newsolution := make(Solution, len(solution))
					copy(newsolution, solution)
					newsolution = append(newsolution, dir)
					cache[newcode] = newsolution
					next = append(next, newcode)
				}
			}
		}
		current = next
	}
}
<commit_msg>in depth first, make a copy of the solution before returning it<commit_after>package cryptica

import "bytes"

type Solution []Direction

func (solution *Solution) String() string {
	var buffer bytes.Buffer
	for i, dir := range *solution {
		switch {
		case i > 0:
			buffer.WriteRune(' ')
		default:
			buffer.WriteString(dir.String())
		}
	}
	return buffer.String()
}

type Game struct {
	State State
	Goal  Goal
	Steps int
}

type Solver interface {
	solve(game Game, solutions chan Solution)
}

type DepthFirstSolver struct {
}

func (solver DepthFirstSolver) solve(game Game, solutions chan Solution) {
	cache := make(map[uint64]int)
	f := func(state State, solution Solution, k interface{}) {
		n := len(solution)
		if n > game.Steps {
			return
		}
		code := state.Board.Encode(state)
		if m, exists := cache[code]; exists && m <= n {
			return
		}
		cache[code] = n
		if state.Match(game.Goal) {
			newsolution := make(Solution, len(solution))
			copy(newsolution, solution)
			solutions <- newsolution
			return
		}
		f := k.(func(State, Solution, interface{}))
		for i := Up; i <= Right; i++ {
			dir := Direction(i)
			f(state.Move(dir), append(solution, dir), k)
		}
	}
	f(game.State, make(Solution, 0), f)
}

type BreadthFirstSolver struct {
}

func (solver BreadthFirstSolver) solve(game Game, solutions chan Solution) {
	cache := make(map[uint64]Solution)
	var current, next []uint64
	{
		code := game.State.Board.Encode(game.State)
		cache[code] = make(Solution, 0)
		current = []uint64{code}
	}
	for len(current) > 0 {
		next = make([]uint64, 0)
		for _, code := range current {
			solution := cache[code]
			state := game.State.Board.Decode(code)
			if state.Match(game.Goal) {
				solutions <- solution
				continue
			}
			for i := Up; i <= Right; i++ {
				dir := Direction(i)
				newstate := state.Move(dir)
				newcode := game.State.Board.Encode(newstate)
				if _, exists := cache[newcode]; !exists {
					newsolution := make(Solution, len(solution))
					copy(newsolution, solution)
					newsolution = append(newsolution, dir)
					cache[newcode] = newsolution
					next = append(next, newcode)
				}
			}
		}
		current = next
	}
}
<|endoftext|>


<commit_before>package termloop

import (
	"fmt"
	"github.com/nsf/termbox-go"
	"time"
)

// Represents a top-level Termloop application.
type Game struct {
	screen *Screen
	input  *input
	debug  bool
	logs   []string
}

// NewGame creates a new Game, along with a Screen and input handler.
// Returns a pointer to the new Game.
func NewGame() *Game {
	g := Game{
		screen: NewScreen(),
		input:  newInput(),
		logs:   make([]string, 0),
	}
	return &g
}

// Screen returns the current Screen of a Game.
func (g *Game) Screen() *Screen {
	return g.screen
}

// SetScreen sets the current Screen of a Game.
func (g *Game) SetScreen(s *Screen) {
	g.screen = s
}

// DebugOn returns a bool showing whether or not debug mode is on.
func (g *Game) DebugOn() bool {
	return g.debug
}

// SetDebugOn sets debug mode's on status to be debugOn.
func (g *Game) SetDebugOn(debugOn bool) {
	g.debug = debugOn
}

// Log takes a log string and additional parameters, which can be substituted
// into the string using standard fmt.Printf rules.
// The formatted string is added to Game g's logs. If debug mode is on, the log will
// be printed to the terminal when Termloop exits.
func (g *Game) Log(log string, items ...interface{}) {
	toLog := "[" + time.Now().Format(time.StampMilli) + "] " +
		fmt.Sprintf(log, items...)
	g.logs = append(g.logs, toLog)
}

func (g *Game) dumpLogs() {
	if g.debug {
		fmt.Println("=== Logs: ===")
		for _, l := range g.logs {
			fmt.Println(l)
		}
		fmt.Println("=============")
	}
}

// SetEndKey sets the Key used to end the game. Default is KeyCtrlC.
// If you don't want an end key, set it to KeyEsc, as this key
// isn't supported and will do nothing.
// (We recommend always having an end key for development/testing.)
func (g *Game) SetEndKey(key Key) {
	g.input.endKey = termbox.Key(key)
}

// Start starts a Game running. This should be the last thing called in your
// main function. By default, the escape key exits.
func (g *Game) Start() {
	// Init Termbox
	err := termbox.Init()
	termbox.SetOutputMode(termbox.Output256)
	termbox.SetInputMode(termbox.InputAlt | termbox.InputMouse)
	if err != nil {
		panic(err)
	}
	defer g.dumpLogs()
	defer termbox.Close()
	g.screen.resize(termbox.Size())

	// Init input
	g.input.start()
	defer g.input.stop()
	clock := time.Now()

mainloop:
	for {
		update := time.Now()
		g.screen.delta = update.Sub(clock).Seconds()
		clock = update

		select {
		case ev := <-g.input.eventQ:
			if ev.Key == g.input.endKey {
				break mainloop
			} else if EventType(ev.Type) == EventResize {
				g.screen.resize(ev.Width, ev.Height)
			} else if EventType(ev.Type) == EventError {
				g.Log(ev.Err.Error())
			}
			g.screen.Tick(convertEvent(ev))
		default:
			g.screen.Tick(Event{Type: EventNone})
		}

		g.screen.Draw()
		// If g.screen.fps is zero (the default), then 1000.0/g.screen.fps -> +Inf -> time.Duration(+Inf), which
		// is a negative number, and so time.Sleep returns immediately.
		time.Sleep(time.Duration((update.Sub(time.Now()).Seconds()*1000.0)+1000.0/g.screen.fps) * time.Millisecond)
	}
}
<commit_msg>Fix a crash when changing running game screen. (#42)<commit_after>package termloop

import (
	"fmt"
	"github.com/nsf/termbox-go"
	"time"
)

// Represents a top-level Termloop application.
type Game struct {
	screen *Screen
	input  *input
	debug  bool
	logs   []string
}

// NewGame creates a new Game, along with a Screen and input handler.
// Returns a pointer to the new Game.
func NewGame() *Game {
	g := Game{
		screen: NewScreen(),
		input:  newInput(),
		logs:   make([]string, 0),
	}
	return &g
}

// Screen returns the current Screen of a Game.
func (g *Game) Screen() *Screen {
	return g.screen
}

// SetScreen sets the current Screen of a Game.
func (g *Game) SetScreen(s *Screen) {
	g.screen = s
	g.screen.resize(termbox.Size())
}

// DebugOn returns a bool showing whether or not debug mode is on.
func (g *Game) DebugOn() bool {
	return g.debug
}

// SetDebugOn sets debug mode's on status to be debugOn.
func (g *Game) SetDebugOn(debugOn bool) {
	g.debug = debugOn
}

// Log takes a log string and additional parameters, which can be substituted
// into the string using standard fmt.Printf rules.
// The formatted string is added to Game g's logs. If debug mode is on, the log will
// be printed to the terminal when Termloop exits.
func (g *Game) Log(log string, items ...interface{}) {
	toLog := "[" + time.Now().Format(time.StampMilli) + "] " +
		fmt.Sprintf(log, items...)
	g.logs = append(g.logs, toLog)
}

func (g *Game) dumpLogs() {
	if g.debug {
		fmt.Println("=== Logs: ===")
		for _, l := range g.logs {
			fmt.Println(l)
		}
		fmt.Println("=============")
	}
}

// SetEndKey sets the Key used to end the game. Default is KeyCtrlC.
// If you don't want an end key, set it to KeyEsc, as this key
// isn't supported and will do nothing.
// (We recommend always having an end key for development/testing.)
func (g *Game) SetEndKey(key Key) {
	g.input.endKey = termbox.Key(key)
}

// Start starts a Game running. This should be the last thing called in your
// main function. By default, the escape key exits.
func (g *Game) Start() {
	// Init Termbox
	err := termbox.Init()
	termbox.SetOutputMode(termbox.Output256)
	termbox.SetInputMode(termbox.InputAlt | termbox.InputMouse)
	if err != nil {
		panic(err)
	}
	defer g.dumpLogs()
	defer termbox.Close()
	g.screen.resize(termbox.Size())

	// Init input
	g.input.start()
	defer g.input.stop()
	clock := time.Now()

mainloop:
	for {
		update := time.Now()
		g.screen.delta = update.Sub(clock).Seconds()
		clock = update

		select {
		case ev := <-g.input.eventQ:
			if ev.Key == g.input.endKey {
				break mainloop
			} else if EventType(ev.Type) == EventResize {
				g.screen.resize(ev.Width, ev.Height)
			} else if EventType(ev.Type) == EventError {
				g.Log(ev.Err.Error())
			}
			g.screen.Tick(convertEvent(ev))
		default:
			g.screen.Tick(Event{Type: EventNone})
		}

		g.screen.Draw()
		// If g.screen.fps is zero (the default), then 1000.0/g.screen.fps -> +Inf -> time.Duration(+Inf), which
		// is a negative number, and so time.Sleep returns immediately.
		time.Sleep(time.Duration((update.Sub(time.Now()).Seconds()*1000.0)+1000.0/g.screen.fps) * time.Millisecond)
	}
}
<|endoftext|>


<commit_before>package main

import (
  "fmt"
  "net/http"
  "io"
  "github.com/satori/go.uuid"
  "math/rand"
  "os"
  "strconv"
  "time"
  "encoding/json"
  "crypto/md5"
)

// HelloResponse struct
type HelloResponse struct {
  Message string  `json:"message"`
}

// UUIDResponse struct
type UUIDResponse struct {
  UUID string  `json:"uuid"`
}

// AccountResponse struct
type AccountResponse struct {
  Code string `json:"code"`
}

func main () {

  if b, err := ComputeMd5(os.Args[0]); err == nil {
    fmt.Printf("version: %x \n", b)
  }

  port := os.Getenv("PORT")
  if port == "" {
    port = "8080"
  }

  fmt.Printf("Listening on port %s...\n", port)

//  http.HandleFunc ("/", BasePath)
  http.HandleFunc ("/hello", PrintString)
  http.HandleFunc ("/uuid", PrintUUID)
  http.HandleFunc ("/accounts", Accounts)
  http.HandleFunc ("/account", Account)
  http.HandleFunc ("/404", Error404)
  http.HandleFunc ("/500", Error500)
	http.ListenAndServe(":" + port, nil)
}

// PrintString just prints the json Hola: Mundo! string
func PrintString (rw http.ResponseWriter, r *http.Request){
  if RandomizeResponse (rw, r) {

    msg, _ := json.Marshal (&HelloResponse{Message: "Hello World!"})

    rw.Header().Set("Content-Type", "application/json")
    rw.WriteHeader(http.StatusOK)
    io.WriteString (rw, string(msg))
  }
}

// PrintUUID just prints an UUID string in json
func PrintUUID (rw http.ResponseWriter, r *http.Request){
  if RandomizeResponse (rw, r) {

    u1, _ := json.Marshal (&UUIDResponse{UUID: uuid.NewV4().String()})

    rw.Header().Set("Content-Type", "application/json")
    rw.WriteHeader(http.StatusOK)
    io.WriteString (rw, string(u1))
  }
}

// Account just prints an UUID string in json
func Account (rw http.ResponseWriter, r *http.Request){
  if RandomizeResponse (rw, r) {

    msg, _ := json.Marshal (&AccountResponse{Code: "ok"})

    rw.Header().Set("Content-Type", "application/json")
    rw.WriteHeader(http.StatusOK)
    io.WriteString (rw, string (msg))
  }
}

// Accounts serves the accounts.json file
func Accounts(rw http.ResponseWriter, r *http.Request) {
  if RandomizeResponse (rw, r) {
    fp := "accounts.json"

    rw.Header().Set("Content-Type", "application/json")
    http.ServeFile(rw, r, fp)
  }
}

// Error500 serves the accounts.json file
func Error500(rw http.ResponseWriter, r *http.Request) {
  if RandomizeResponse (rw, r) {
    // 500
    http.Error(rw, "500 Interval Server Error", http.StatusInternalServerError)
  }
}

// Error404 serves the accounts.json file
func Error404(rw http.ResponseWriter, r *http.Request) {
  if RandomizeResponse (rw, r) {
    http.NotFound(rw, r)
  }
}

// BasePath tal
//func BasePath (rw http.ResponseWriter, r *http.Request) {
//  http.Redirect (rw, r, "/hello", http.StatusFound)
//}

// RandomizeResponse prints the body, or erros in a random fashion
func RandomizeResponse (rw http.ResponseWriter, r *http.Request) bool {

  // Environment variables:
  // RANDOM404: How many responses are going to be 404
  // RANDOM500: How many responses are going to be 500
  // RANDOMSLEEP: Sleep time in miliseconds
  random404, _ := strconv.Atoi(os.Getenv ("RANDOM404"))
  random500, _ := strconv.Atoi(os.Getenv ("RANDOM500"))
  randomMaxTime, _ := strconv.Atoi(os.Getenv ("RANDOMMAXTIME"))
  randomMinTime, _ := strconv.Atoi(os.Getenv ("RANDOMMINTIME"))

  random500 += random404
  randomResponse := rand.Intn(100)

  if randomMaxTime > 0 {
      time.Sleep(time.Duration (rand.Intn(randomMaxTime - randomMinTime) + randomMinTime) * time.Millisecond)
  }

  result := true
  if (random404 != 0) && randomResponse <= random404 {
    // 404
    http.NotFound(rw, r)
    result = false
  } else if (random500 != 0) && randomResponse <= random500{
    // 500
    http.Error(rw, "500 Interval Server Error", http.StatusInternalServerError)
    result = false
  }

  return result
}

//ComputeMd5 does it
func ComputeMd5(filePath string) ([]byte, error) {
  var result []byte
  file, err := os.Open(filePath)
  if err != nil {
    return result, err
  }
  defer file.Close()

  hash := md5.New()
  if _, err := io.Copy(hash, file); err != nil {
    return result, err
  }

  return hash.Sum(result), nil
}
<commit_msg>echo operation added<commit_after>package main

import (
	"crypto/md5"
	"encoding/json"
	"io"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/satori/go.uuid"
)

// HelloResponse struct
type HelloResponse struct {
	Message string `json:"message"`
}

// UUIDResponse struct
type UUIDResponse struct {
	UUID string `json:"uuid"`
}

// AccountResponse struct
type AccountResponse struct {
	Code string `json:"code"`
}

func main() {

	if b, err := ComputeMd5(os.Args[0]); err == nil {
		log.Printf("version: %x \n", b)
	}

	port := os.Getenv("PORT")
	if port == "" {
		port = "8080"
	}

	log.Printf("Listening on port %s...\n", port)

	http.HandleFunc("/basic/hello", getHelloWorld)
	http.HandleFunc("/basic/uuid", getUUID)
	http.HandleFunc("/basic/accounts", getAccounts)
	http.HandleFunc("/basic/account", postAccount)
	http.HandleFunc("/basic/echo", postEcho)
	http.HandleFunc("/", getDefault)

	err := http.ListenAndServe(":"+port, nil)
	if err != nil {
		log.Println(err)
	}
}

func getHelloWorld(rw http.ResponseWriter, r *http.Request) {
	start := time.Now()

	randomSleepTime()

	msg, _ := json.Marshal(&HelloResponse{Message: "Hello World!"})

	rw.Header().Set("Content-Type", "application/json")
	rw.WriteHeader(http.StatusOK)
	io.WriteString(rw, string(msg))

	elapsed := time.Since(start)
	log.Printf("%s took %s\n", r.URL, elapsed)
}

func getUUID(rw http.ResponseWriter, r *http.Request) {
	start := time.Now()

	randomSleepTime()

	u1, _ := json.Marshal(&UUIDResponse{UUID: uuid.NewV4().String()})

	rw.Header().Set("Content-Type", "application/json")
	rw.WriteHeader(http.StatusOK)
	io.WriteString(rw, string(u1))

	elapsed := time.Since(start)
	log.Printf("%s took %s\n", r.URL, elapsed)
}

func postAccount(rw http.ResponseWriter, r *http.Request) {
	start := time.Now()

	randomSleepTime()

	msg, _ := json.Marshal(&AccountResponse{Code: "ok"})

	rw.Header().Set("Content-Type", "application/json")
	rw.WriteHeader(http.StatusCreated)
	io.WriteString(rw, string(msg))

	elapsed := time.Since(start)
	log.Printf("%s took %s\n", r.URL, elapsed)
}

func getAccounts(rw http.ResponseWriter, r *http.Request) {
	start := time.Now()

	randomSleepTime()

	data, err := ioutil.ReadFile("accounts.json")
	if err != nil {
		log.Println(err)
		http.Error(rw, "Error sent from golang service", http.StatusTeapot)
		return
	}

	u1 := uuid.NewV4().String()
	dataString := strings.Replace(string(data), "XXXXXXXXX", string(u1)[:rand.Intn(31)], -1)
	rw.Header().Set("Content-Type", "application/json")
	io.WriteString(rw, dataString)

	elapsed := time.Since(start)
	log.Printf("%s took %s\n", r.URL, elapsed)
}

func randomSleepTime() {
	randomMaxTime, _ := strconv.Atoi(os.Getenv("RANDOMMAXTIME"))
	randomMinTime, _ := strconv.Atoi(os.Getenv("RANDOMMINTIME"))

	if randomMaxTime > 0 {
		time.Sleep(time.Duration(rand.Intn(randomMaxTime-randomMinTime+1)+randomMinTime) * time.Millisecond)
	}
}

//ComputeMd5 does it to know the version of the service
func ComputeMd5(filePath string) ([]byte, error) {
	var result []byte
	file, err := os.Open(filePath)
	if err != nil {
		return result, err
	}
	defer file.Close()

	hash := md5.New()
	if _, err := io.Copy(hash, file); err != nil {
		return result, err
	}

	return hash.Sum(result), nil
}

func getDefault(rw http.ResponseWriter, r *http.Request) {
	msg := "Sorry, no path registrered in " + r.URL.String() + ". Default Response!	"

	rw.Header().Set("Content-Type", "text/plain")
	rw.WriteHeader(http.StatusNotFound)
	io.WriteString(rw, msg)

	log.Printf("not_found %s. \n", r.URL)
}

func postEcho(rw http.ResponseWriter, r *http.Request) {
	start := time.Now()

	randomSleepTime()

	dataString, _ := ioutil.ReadAll(r.Body)
	rw.Header().Set("Content-Type", "application/json")
	io.WriteString(rw, string(dataString[:]))

	elapsed := time.Since(start)
	log.Printf("%s took %s\n", r.URL, elapsed)

}
<|endoftext|>


<commit_before>package format

import (
	"fmt"
	"io"
	"strings"

	"stephensearles.com/php/ast"
	"stephensearles.com/php/token"
)

func (f *formatWalker) Walk(node ast.Node) error {
	f.printNode(node)
	return nil
}

func (f *formatWalker) printNode(node ast.Node) {
	switch n := node.(type) {
	case ast.ExpressionStmt:
		f.Walk(n.Expression)
		f.printToken(token.StatementEnd)
		f.print("\n")
	case *ast.Variable:
		f.printToken(token.VariableOperator)
		f.Walk(n.Name)
	case ast.Variable:
		f.printToken(token.VariableOperator)
		f.Walk(n.Name)
	case ast.Identifier:
		f.print(n.Value)
	case *ast.Literal:
		f.print(n.Value)
	case ast.Literal:
		f.print(n.Value)
	case ast.EchoStmt:
		f.printEcho(&n)
	case *ast.EchoStmt:
		f.printEcho(n)
	case ast.IfStmt:
		f.printIf(&n)
	case *ast.IfStmt:
		f.printIf(n)
	case *ast.Block:
		for _, stmt := range n.Statements {
			f.Walk(stmt)
		}
	}
}

func (f *formatWalker) printf(fmtString string, i ...interface{}) {
	num := 0
	inPercent := false
	for _, r := range fmtString {
		if inPercent && r == '?' {
			switch n := i[num].(type) {
			case token.Token:
				f.printToken(n)
				num += 1
			case ast.Node:
				f.printNode(n)
				num += 1
			default:
				fmt.Fprint(f.w, n)
			}
		} else if inPercent && r == '%' {
			io.WriteString(f.w, "%")
		} else if inPercent {
			fmt.Fprintf(f.w, "%"+string(byte(r)), i[num])
		} else if r == '%' {
			inPercent = true
			continue
		} else {
			fmt.Fprint(f.w, string(byte(r)))
		}
		inPercent = false
	}
}

func (f *formatWalker) print(s string) {
	io.WriteString(f.w, s)
}

func (f *formatWalker) printToken(t token.Token) {
	if s, ok := tokenMap[t]; ok {
		io.WriteString(f.w, s)
		return
	}
	io.WriteString(f.w, t.String())
}

func (f *formatWalker) printTab() {
	io.WriteString(f.w, strings.Repeat(f.Indent, f.tabLevel))
}

func (f *formatWalker) printTabbedLine() {
	f.println()
	f.printTab()
}

func (f *formatWalker) println() {
	io.WriteString(f.w, "\n")
}
<commit_msg>Added support for notifying about unimplemented ast node formatters<commit_after>package format

import (
	"fmt"
	"io"
	"strings"

	"stephensearles.com/php/ast"
	"stephensearles.com/php/token"
)

func (f *formatWalker) Walk(node ast.Node) error {
	f.printNode(node)
	return nil
}

func (f *formatWalker) printNode(node ast.Node) {
	switch n := node.(type) {
	case ast.ExpressionStmt:
		f.Walk(n.Expression)
		f.printToken(token.StatementEnd)
		f.print("\n")
	case *ast.Variable:
		f.printToken(token.VariableOperator)
		f.Walk(n.Name)
	case ast.Variable:
		f.printToken(token.VariableOperator)
		f.Walk(n.Name)
	case ast.Identifier:
		f.print(n.Value)
	case *ast.Literal:
		f.print(n.Value)
	case ast.Literal:
		f.print(n.Value)
	case ast.EchoStmt:
		f.printEcho(&n)
	case *ast.EchoStmt:
		f.printEcho(n)
	case ast.IfStmt:
		f.printIf(&n)
	case *ast.IfStmt:
		f.printIf(n)
	case *ast.Block:
		for _, stmt := range n.Statements {
			f.Walk(stmt)
		}
	default:
		f.printTabbedLine()
		f.printf("// unimplemented %T\n", n)
		for _, child := range n.Children() {
			f.Walk(child)
		}
	}
}

func (f *formatWalker) printf(fmtString string, i ...interface{}) {
	num := 0
	inPercent := false
	for _, r := range fmtString {
		if inPercent && r == '?' {
			switch n := i[num].(type) {
			case token.Token:
				f.printToken(n)
				num += 1
			case ast.Node:
				f.printNode(n)
				num += 1
			default:
				fmt.Fprint(f.w, n)
			}
		} else if inPercent && r == '%' {
			io.WriteString(f.w, "%")
		} else if inPercent {
			fmt.Fprintf(f.w, "%"+string(byte(r)), i[num])
		} else if r == '%' {
			inPercent = true
			continue
		} else {
			fmt.Fprint(f.w, string(byte(r)))
		}
		inPercent = false
	}
}

func (f *formatWalker) print(s string) {
	io.WriteString(f.w, s)
}

func (f *formatWalker) printToken(t token.Token) {
	if s, ok := tokenMap[t]; ok {
		io.WriteString(f.w, s)
		return
	}
	io.WriteString(f.w, t.String())
}

func (f *formatWalker) printTab() {
	io.WriteString(f.w, strings.Repeat(f.Indent, f.tabLevel))
}

func (f *formatWalker) printTabbedLine() {
	f.println()
	f.printTab()
}

func (f *formatWalker) println() {
	io.WriteString(f.w, "\n")
}
<|endoftext|>


<commit_before>package c

import (
	"go/ast"
	"path"
	"strconv"
)

func packageImports (pkg *ast.Package) map[string]struct{} {
	imprts := make(map[string]struct{})
	for _, file := range pkg.Files {
		for _, impSpec := range file.Imports {
			imprts[newFileImport(impSpec).Path] = struct{}{}
		}
	}
	return imprts
}

type fileImport struct {
	Name string  // local import name
	Path string  // package full path
}

func newFileImport(spec *ast.ImportSpec) *fileImport {
	var err error
	fimp := &fileImport{}
	if fimp.Path, err = strconv.Unquote(spec.Path.Value); err != nil {
		panic(err)
	}
	if spec.Name == nil {
		_, fimp.Name = path.Split(fimp.Path)
	} else {
		fimp.Name = spec.Name.Name
	}
	return fimp
}

// fileImports returns a slice of all packages imported by file
func fileImports(file *ast.File) []*fileImport {
	imprts := make([]*fileImport, len(file.Imports))
	for i, impSpec := range file.Imports {
		imprts[i] = newFileImport(impSpec)
	}
	return imprts
}
<commit_msg>cosmetic<commit_after>package c

import (
	"go/ast"
	"path"
	"strconv"
)

func packageImports(pkg *ast.Package) map[string]struct{} {
	imprts := make(map[string]struct{})
	for _, file := range pkg.Files {
		for _, impSpec := range file.Imports {
			imprts[newFileImport(impSpec).Path] = struct{}{}
		}
	}
	return imprts
}

type fileImport struct {
	Name string  // local import name
	Path string  // package full path
}

func newFileImport(spec *ast.ImportSpec) *fileImport {
	var err error
	fimp := &fileImport{}
	if fimp.Path, err = strconv.Unquote(spec.Path.Value); err != nil {
		panic(err)
	}
	if spec.Name == nil {
		_, fimp.Name = path.Split(fimp.Path)
	} else {
		fimp.Name = spec.Name.Name
	}
	return fimp
}

// fileImports returns a slice of all packages imported by file
func fileImports(file *ast.File) []*fileImport {
	imprts := make([]*fileImport, len(file.Imports))
	for i, impSpec := range file.Imports {
		imprts[i] = newFileImport(impSpec)
	}
	return imprts
}
<|endoftext|>


<commit_before>package pes

const (
	program_stream_map                  uint32 = 0274
	private_stream_1                    uint32 = 0275
	padding_stream                      uint32 = 0277
	private_stream_2                    uint32 = 0277
	ecm_stream                          uint32 = 0360
	emm_stream                          uint32 = 0361
	itu_t_rec_h_222_0                   uint32 = 0362
	dsmcc_stream                        uint32 = 0362
	iso_iec_13522_stream                uint32 = 0363
	itu_t_rec_h_222_1_type_a            uint32 = 0364
	itu_t_rec_h_222_1_type_b            uint32 = 0365
	itu_t_rec_h_222_1_type_c            uint32 = 0366
	itu_t_rec_h_222_1_type_d            uint32 = 0367
	itu_t_rec_h_222_1_type_e            uint32 = 0370
	ancillary_stream                    uint32 = 0371
	iso_iec14496_1_sl_packetized_stream uint32 = 0372
	iso_iec14496_1_flexmux_stream       uint32 = 0373
	program_stream_directory            uint32 = 0377
)

func hasPESHeader(streamID uint32) bool {
	return streamID != program_stream_map &&
		streamID != padding_stream &&
		streamID != private_stream_2 &&
		streamID != ecm_stream &&
		streamID != emm_stream &&
		streamID != program_stream_directory &&
		streamID != dsmcc_stream &&
		streamID != itu_t_rec_h_222_1_type_e
}
<commit_msg>Incorrect padding stream id<commit_after>package pes

const (
	program_stream_map                  uint32 = 0274
	private_stream_1                    uint32 = 0275
	padding_stream                      uint32 = 0276
	private_stream_2                    uint32 = 0277
	ecm_stream                          uint32 = 0360
	emm_stream                          uint32 = 0361
	itu_t_rec_h_222_0                   uint32 = 0362
	dsmcc_stream                        uint32 = 0362
	iso_iec_13522_stream                uint32 = 0363
	itu_t_rec_h_222_1_type_a            uint32 = 0364
	itu_t_rec_h_222_1_type_b            uint32 = 0365
	itu_t_rec_h_222_1_type_c            uint32 = 0366
	itu_t_rec_h_222_1_type_d            uint32 = 0367
	itu_t_rec_h_222_1_type_e            uint32 = 0370
	ancillary_stream                    uint32 = 0371
	iso_iec14496_1_sl_packetized_stream uint32 = 0372
	iso_iec14496_1_flexmux_stream       uint32 = 0373
	program_stream_directory            uint32 = 0377
)

func hasPESHeader(streamID uint32) bool {
	return streamID != program_stream_map &&
		streamID != padding_stream &&
		streamID != private_stream_2 &&
		streamID != ecm_stream &&
		streamID != emm_stream &&
		streamID != program_stream_directory &&
		streamID != dsmcc_stream &&
		streamID != itu_t_rec_h_222_1_type_e
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/json"
	"github.com/darkhelmet/env"
	"github.com/stretchr/testify/assert"
	"github.com/zenazn/goji"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
	"time"
)

func init() {
	log.SetOutput(ioutil.Discard)
	if !strings.HasSuffix(env.String("DATABASE_URL"), "-test") {
		panic("Doesn't look like a test database")
	}
	dataStart()
	webBuild()
}

func clear() {
	_, err := dataConn.Exec("DELETE from dbs")
	must(err)
	_, err = dataConn.Exec("DELETE from pins")
	must(err)
}

func TestStatus(t *testing.T) {
	req, err := http.NewRequest("GET", "https://pgpin.com/status", nil)
	must(err)
	res := httptest.NewRecorder()
	goji.DefaultMux.ServeHTTP(res, req)
	webStatus(res, req)
	assert.Equal(t, 200, res.Code)
	status := &status{}
	must(json.NewDecoder(res.Body).Decode(status))
	assert.Equal(t, "ok", status.Message)
}

func TestAddDb(t *testing.T) {
	defer clear()
	in := `{"name": "pins", "url": "postgres://u:p@h:1234/d"}`
	req, err := http.NewRequest("GET", "http://pgpin.com/status", bytes.NewReader([]byte(in)))
	must(err)
	res := httptest.NewRecorder()
	webDbAdd(res, req)
	assert.Equal(t, 201, res.Code)
	db := &db{}
	must(json.NewDecoder(res.Body).Decode(db))
	assert.Equal(t, "pins", db.Name)
	assert.Equal(t, "postgres://u:p@h:1234/d", db.Url)
	assert.NotEmpty(t, db.Id)
	assert.WithinDuration(t, time.Now(), db.AddedAt, 3*time.Second)
}
<commit_msg>More full stack exercising<commit_after>package main

import (
	"bytes"
	"encoding/json"
	"github.com/darkhelmet/env"
	"github.com/stretchr/testify/assert"
	"github.com/zenazn/goji"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
	"time"
)

func init() {
	log.SetOutput(ioutil.Discard)
	if !strings.HasSuffix(env.String("DATABASE_URL"), "-test") {
		panic("Doesn't look like a test database")
	}
	dataStart()
	webBuild()
}

func clear() {
	_, err := dataConn.Exec("DELETE from dbs")
	must(err)
	_, err = dataConn.Exec("DELETE from pins")
	must(err)
}

func TestStatus(t *testing.T) {
	req, err := http.NewRequest("GET", "https://pgpin.com/status", nil)
	must(err)
	res := httptest.NewRecorder()
	goji.DefaultMux.ServeHTTP(res, req)
	webStatus(res, req)
	assert.Equal(t, 200, res.Code)
	status := &status{}
	must(json.NewDecoder(res.Body).Decode(status))
	assert.Equal(t, "ok", status.Message)
}

func TestAddDb(t *testing.T) {
	defer clear()
	in := `{"name": "pins-1", "url": "postgres://u:p@h:1234/d-1"}`
	req, err := http.NewRequest("POST", "http://pgpin.com/dbs", bytes.NewReader([]byte(in)))
	must(err)
	res := httptest.NewRecorder()
	goji.DefaultMux.ServeHTTP(res, req)
	assert.Equal(t, 201, res.Code)
	db := &db{}
	must(json.NewDecoder(res.Body).Decode(db))
	assert.Equal(t, "pins-1", db.Name)
	assert.Equal(t, "postgres://u:p@h:1234/d-1", db.Url)
	assert.NotEmpty(t, db.Id)
	assert.WithinDuration(t, time.Now(), db.AddedAt, 3*time.Second)
}
<|endoftext|>


<commit_before>package gedis

import (
	"bytes"
	"errors"
	"testing"
)

func TestWriteBulk(t *testing.T) {
	expected := []byte("$4\r\nPING\r\n")
	parsed := WriteBulk("PING")

	if !bytes.Equal(expected, parsed) {
		t.Errorf("writeBulk(%#v)\nG: %v\nE: %v", "PING", parsed, expected)
	}
}

func BenchmarkWriteBulk(b *testing.B) {
	for i := 0; i < b.N; i++ {
		WriteBulk("PING")
	}
}

func TestWriteMultiBulk(t *testing.T) {
	cmd := "*1\r\n$4\r\nPING\r\n"
	expected := []byte(cmd)

	if parsed := WriteMultiBulk("PING"); !bytes.Equal(expected, parsed) {
		t.Errorf("writeMultiBulk(%#v)\nG: %v\nE: %v", cmd, parsed, expected)
	}

	cmd = "*3\r\n$3\r\nSET\r\n$5\r\nlorem\r\n$5\r\n12345\r\n"
	expected = []byte(cmd)

	if parsed := WriteMultiBulk("SET", "lorem", "12345"); !bytes.Equal(expected, parsed) {
		t.Errorf("writeMultiBulk(%#v)\nG: %v\nE: %v", cmd, parsed, expected)
	}
}

func BenchmarkWriteMultiBulk(b *testing.B) {
	for i := 0; i < b.N; i++ {
		WriteMultiBulk("SET", "lorem", "12345")
	}
}

func TestWriteInt(t *testing.T) {
	expected := []byte(":1234\r\n")
	parsed := WriteInt(1234)

	if !bytes.Equal(expected, parsed) {
		t.Errorf("\nexpected %#v\nreturned %#v", expected, parsed)
		t.FailNow()
	}

	expected = []byte(":-1234\r\n")
	parsed = WriteInt(-1234)

	if !bytes.Equal(expected, parsed) {
		t.Errorf("\nexpected %#v\nreturned %#v", expected, parsed)
		t.FailNow()
	}
}

func TestWriteError(t *testing.T) {
	err := errors.New("unknown")
	expected := []byte("-ERR unknown\r\n")
	parsed := WriteError(err)

	if !bytes.Equal(expected, parsed) {
		t.Errorf("\nexpected %q\nreturned %q", expected, parsed)
	}
}

func TestWriteStatus(t *testing.T) {
	expected := []byte("+OK\r\n")
	parsed := WriteStatus("OK")

	if !bytes.Equal(expected, parsed) {
		t.Errorf("\nexpected %q\nreturned %q", expected, parsed)
	}
}

func BenchmarkWriteStatus(b *testing.B) {
	for i := 0; i < b.N; i++ {
		WriteStatus("OK")
	}
}

func TestWrite(t *testing.T) {
	var writer bytes.Buffer

	expected := "*4\r\n$4\r\nPING\r\n:123\r\n$-1\r\n-ERR unknown\r\n"

	Write(&writer, "PING", 123, nil, errors.New("unknown"))

	if res := writer.String(); expected != res {
		t.Errorf("Write()\nexpected %q\nreturned %q", expected, res)
	}
}

func TestWrite_error(t *testing.T) {
	var writer bytes.Buffer

	a := Asserter{t, 1}

	_, err := Write(&writer)
	a.NotNil(err)
	a.StringEq("", writer.String())
}
<commit_msg>Add benchmarks for WriteInt & WriteError<commit_after>package gedis

import (
	"bytes"
	"errors"
	"testing"
)

func TestWriteBulk(t *testing.T) {
	expected := []byte("$4\r\nPING\r\n")
	parsed := WriteBulk("PING")

	if !bytes.Equal(expected, parsed) {
		t.Errorf("writeBulk(%#v)\nG: %v\nE: %v", "PING", parsed, expected)
	}
}

func BenchmarkWriteBulk(b *testing.B) {
	for i := 0; i < b.N; i++ {
		WriteBulk("PING")
	}
}

func TestWriteMultiBulk(t *testing.T) {
	cmd := "*1\r\n$4\r\nPING\r\n"
	expected := []byte(cmd)

	if parsed := WriteMultiBulk("PING"); !bytes.Equal(expected, parsed) {
		t.Errorf("writeMultiBulk(%#v)\nG: %v\nE: %v", cmd, parsed, expected)
	}

	cmd = "*3\r\n$3\r\nSET\r\n$5\r\nlorem\r\n$5\r\n12345\r\n"
	expected = []byte(cmd)

	if parsed := WriteMultiBulk("SET", "lorem", "12345"); !bytes.Equal(expected, parsed) {
		t.Errorf("writeMultiBulk(%#v)\nG: %v\nE: %v", cmd, parsed, expected)
	}
}

func BenchmarkWriteMultiBulk(b *testing.B) {
	for i := 0; i < b.N; i++ {
		WriteMultiBulk("SET", "lorem", "12345")
	}
}

func TestWriteInt(t *testing.T) {
	expected := []byte(":1234\r\n")
	parsed := WriteInt(1234)

	if !bytes.Equal(expected, parsed) {
		t.Errorf("\nexpected %#v\nreturned %#v", expected, parsed)
		t.FailNow()
	}

	expected = []byte(":-1234\r\n")
	parsed = WriteInt(-1234)

	if !bytes.Equal(expected, parsed) {
		t.Errorf("\nexpected %#v\nreturned %#v", expected, parsed)
		t.FailNow()
	}
}

func BenchmarkWriteInt(b *testing.B) {
	for i := 0; i < b.N; i++ {
		WriteInt(1234)
	}
}

func TestWriteError(t *testing.T) {
	err := errors.New("unknown")
	expected := []byte("-ERR unknown\r\n")
	parsed := WriteError(err)

	if !bytes.Equal(expected, parsed) {
		t.Errorf("\nexpected %q\nreturned %q", expected, parsed)
	}
}

func BenchmarkWriteError(b *testing.B) {
	err := errors.New("unknown")

	for i := 0; i < b.N; i++ {
		WriteError(err)
	}
}

func TestWriteStatus(t *testing.T) {
	expected := []byte("+OK\r\n")
	parsed := WriteStatus("OK")

	if !bytes.Equal(expected, parsed) {
		t.Errorf("\nexpected %q\nreturned %q", expected, parsed)
	}
}

func BenchmarkWriteStatus(b *testing.B) {
	for i := 0; i < b.N; i++ {
		WriteStatus("OK")
	}
}

func TestWrite(t *testing.T) {
	var writer bytes.Buffer

	expected := "*4\r\n$4\r\nPING\r\n:123\r\n$-1\r\n-ERR unknown\r\n"

	Write(&writer, "PING", 123, nil, errors.New("unknown"))

	if res := writer.String(); expected != res {
		t.Errorf("Write()\nexpected %q\nreturned %q", expected, res)
	}
}

func TestWrite_error(t *testing.T) {
	var writer bytes.Buffer

	a := Asserter{t, 1}

	_, err := Write(&writer)
	a.NotNil(err)
	a.StringEq("", writer.String())
}
<|endoftext|>


<commit_before>package wake

import (
	"time"
	"unsafe"

	builtins "github.com/kcolford/go-builtins"
)

var (
	createWaitableTimer = kernel32.NewProc("CreateWaitableTimer")
	setWaitableTimer    = kernel32.NewProc("SetWaitableTimer")
	closeHandle         = kernel32.NewProc("CloseHandle")
	waitForSingleObject = kernel32.NewProc("WaitForSingleObject")
)

const (
	waitAbandoned = 0x00000080
	waitObject0   = 0x00000000
	waitTimeout   = 0x00000102
	waitFailed    = 0xFFFFFFFF
)

type winTimerHandle struct {
	hdl uintptr
}

func newWinTimerHandle() (h *winTimerHandle, err error) {
	err = createWaitableTimer.Find()
	if err != nil {
		return
	}

	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682492(v=vs.85).aspx
	hdl, _, err := createWaitableTimer.Call(0, 0, 0)
	if h.hdl != 0 {
		err = nil
	}
	if err != nil {
		return
	}
	h = &winTimerHandle{hdl: hdl}
	return
}

func (h *winTimerHandle) Close() {
	err = closeHandle.Find()
	if err != nil {
		return
	}

	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211(v=vs.85).aspx
	ok, _, err := closeHandle.Call(h.hdl)
	if ok != 0 {
		err = nil
	}
	builtins.Ignore(err)
}

func (h *winTimerHandle) Start(wait, period time.Duration) (err error) {
	err = setWaitableTimer.Find()
	if err != nil {
		return
	}

	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686289(v=vs.85).aspx
	duetime := -int64(wait / time.Nanosecond / 100)
	ok, _, err := setWaitableTimer.Call(h.hdl,
		uintptr(unsafe.Pointer(&duetime)),
		uintptr(period/time.Millisecond), 0, 0, 1)
	if ok != 0 {
		err = nil
	}
	return
}

func (h *winTimerHandle) Wait(timeout time.Duration) (again bool, err error) {
	err = waitForSingleObject.Find()
	if err != nil {
		return
	}

	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx
	res, _, err := waitForSingleObject.Call(h.hdl,
		uintptr(timeout/time.Millisecond))
	if res != waitFailed {
		err = nil
	}
	if err != nil {
		return
	}
	if res == waitTimeout {
		again = true
	}
	return
}

func newTimerHandle() (h timerHandle, err error) {
	return newWinTimerHandle()
}
<commit_msg>fixup! added calls to lazyproc.find to avoid panics<commit_after>package wake

import (
	"time"
	"unsafe"

	builtins "github.com/kcolford/go-builtins"
)

var (
	createWaitableTimer = kernel32.NewProc("CreateWaitableTimer")
	setWaitableTimer    = kernel32.NewProc("SetWaitableTimer")
	closeHandle         = kernel32.NewProc("CloseHandle")
	waitForSingleObject = kernel32.NewProc("WaitForSingleObject")
)

const (
	waitAbandoned = 0x00000080
	waitObject0   = 0x00000000
	waitTimeout   = 0x00000102
	waitFailed    = 0xFFFFFFFF
)

type winTimerHandle struct {
	hdl uintptr
}

func newWinTimerHandle() (h *winTimerHandle, err error) {
	err = createWaitableTimer.Find()
	if err != nil {
		return
	}

	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms682492(v=vs.85).aspx
	hdl, _, err := createWaitableTimer.Call(0, 0, 0)
	if h.hdl != 0 {
		err = nil
	}
	if err != nil {
		return
	}
	h = &winTimerHandle{hdl: hdl}
	return
}

func (h *winTimerHandle) Close() {
	err := closeHandle.Find()
	if err != nil {
		return
	}

	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211(v=vs.85).aspx
	ok, _, err := closeHandle.Call(h.hdl)
	if ok != 0 {
		err = nil
	}
	builtins.Ignore(err)
}

func (h *winTimerHandle) Start(wait, period time.Duration) (err error) {
	err = setWaitableTimer.Find()
	if err != nil {
		return
	}

	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686289(v=vs.85).aspx
	duetime := -int64(wait / time.Nanosecond / 100)
	ok, _, err := setWaitableTimer.Call(h.hdl,
		uintptr(unsafe.Pointer(&duetime)),
		uintptr(period/time.Millisecond), 0, 0, 1)
	if ok != 0 {
		err = nil
	}
	return
}

func (h *winTimerHandle) Wait(timeout time.Duration) (again bool, err error) {
	err = waitForSingleObject.Find()
	if err != nil {
		return
	}

	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx
	res, _, err := waitForSingleObject.Call(h.hdl,
		uintptr(timeout/time.Millisecond))
	if res != waitFailed {
		err = nil
	}
	if err != nil {
		return
	}
	if res == waitTimeout {
		again = true
	}
	return
}

func newTimerHandle() (h timerHandle, err error) {
	return newWinTimerHandle()
}
<|endoftext|>


<commit_before>package handler

import (
	"net/http"
	"time"

	"github.com/yuuki/dynamond/log"
	"github.com/yuuki/dynamond/timeparser"
)

const (
	DAYTIME = time.Duration(24 * 60 * 60) * time.Second
)

func Render(w http.ResponseWriter, r *http.Request) {
	until := time.Now()
	from := until.Add(-DAYTIME)

	if v := r.FormValue("from"); v != "" {
		t, err := timeparser.ParseAtTime(v)
		if err != nil {
			BadRequest(w, err.Error())
			return
		}
		from = t
	}
	if v := r.FormValue("until"); v != "" {
		t, err := timeparser.ParseAtTime(v)
		if err != nil {
			BadRequest(w, err.Error())
			return
		}
		until = t
	}
	log.Debugf("from:%d until:%d", from.Unix(), until.Unix())

	return
}
<commit_msg>Fix to parse 'now+1y' becase FormValue has already unescaped<commit_after>package handler

import (
	"net/http"
	"net/url"
	"time"

	"github.com/yuuki/dynamond/log"
	"github.com/yuuki/dynamond/timeparser"
)

const (
	DAYTIME = time.Duration(24 * 60 * 60) * time.Second
)

func Render(w http.ResponseWriter, r *http.Request) {
	until := time.Now()
	from := until.Add(-DAYTIME)

	if v := r.FormValue("from"); v != "" {
		t, err := timeparser.ParseAtTime(url.QueryEscape(v))
		if err != nil {
			BadRequest(w, err.Error())
			return
		}
		from = t
	}
	if v := r.FormValue("until"); v != "" {
		t, err := timeparser.ParseAtTime(url.QueryEscape(v))
		if err != nil {
			BadRequest(w, err.Error())
			return
		}
		until = t
	}
	log.Debugf("from:%d until:%d", from.Unix(), until.Unix())

	return
}
<|endoftext|>