<commit_before>// Copyright (c) 2012-2019 Eli Janssen
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

package htrie

import (
	"fmt"
)

const globChar uint32 = 1

// A globPathNode represents a path checker that supports globbing comparisons
type globPathNode struct {
	// go maps are optimized for only certain int types:
	//  -- results as of go 1.13 on my slow laptop --
	//  BenchmarkInt        297391227    3.99 ns/op
	//  BenchmarkInt8        68107761    17.9 ns/op
	//  BenchmarkInt16       65628482    18.3 ns/op
	//  BenchmarkInt32      292725417    4.08 ns/op
	//  BenchmarkInt64      293602374    4.11 ns/op
	//  BenchmarkUInt       298711089    3.99 ns/op
	//  BenchmarkUInt8       68173198    17.8 ns/op
	//  BenchmarkUInt16      67566312    18.1 ns/op
	//  BenchmarkUInt32      298597942   3.99 ns/op
	//  BenchmarkUInt64      300239860   4.02 ns/op
	//
	// Since we would /want/ to use uint8 here, use uint32 instead
	// Ugly and wasteful, but quite a bit faster for now...
	subtrees map[uint32]*globPathNode
	// used to avoid map lookup when there is only one subtree candidate
	oneShot *globPathNode
	// is this path component a glob
	isGlob bool
	// determines whether a node can be a match even if it isn't a leaf node;
	// this becomes necessary due to the possibility of longer and shorter
	// paths overlapping
	canMatch bool
	// optimization to avoid an extra map lookup on every char
	hasGlobChild bool
	// char for this node
	nodeChar uint32
	// is this a case insensitive comparison tree?
	icase bool
}

func (gpn *globPathNode) addPath(s string) error {
	if gpn.subtrees == nil {
		return fmt.Errorf("got nil <gpn>.subtrees in receiver")
	}

	curnode := gpn
	prevnode := curnode
	mlen := len(s)
	//for _, part := range s {
	for i := 0; i < mlen; i++ {
		part := uint32(s[i])

		// if icase, use lowercase letters for comparisons
		// 'A' == 65; 'Z' == 90
		if gpn.icase && 65 <= part && part <= 90 {
			part = part + 32
		}

		var c uint32
		// '*' == 42
		if part == 42 {
			c = globChar
		} else {
			c = part
		}

		subt := curnode.subtrees
		if subt[c] == nil {
			subt[c] = newGlobPathNode(gpn.icase)
		}

		subt[c].nodeChar = part

		// setup oneshot as an optimizaiton if there is only one subcandidate...
		if len(subt) == 1 {
			curnode.oneShot = subt[c]
		} else {
			curnode.oneShot = nil
		}

		prevnode = curnode
		curnode = subt[c]
		if part == '*' {
			prevnode.hasGlobChild = true
			curnode.isGlob = true
		}
	}

	// this is the end of the path, so this node can be a match, even if future
	// urls add children to it (a longer url).
	curnode.canMatch = true
	return nil
}

func (gpn *globPathNode) globConsume(s string, index, mlen int) bool {
	// we have a glob and no follow-on chars, so we can consume
	// till the end and then match. early return
	if gpn.canMatch {
		return true
	}

	oneShotLookahead := false
	oneShotStep := false
	// optimize common single char after * globbing
	// eg. .../*/...
	if gpn.oneShot != nil {
		oneShotLookahead = true
		oneShotStep = true
	}

	// otherwise we have some work to do...
	curnode := gpn
	// don't need to iter runes since we have ascii
	for i := index; i < mlen; i++ {
		part := uint32(s[i])

		// if icase, use lowercase letters for comparisons
		// 'A' == 65; 'Z' == 90
		if gpn.icase && 65 <= part && part <= 90 {
			part = part + 32
		}

		// we know the glob has one one subcandidate (next char), so consume until
		// we hit one of those
		if oneShotStep {
			if part != curnode.oneShot.nodeChar {
				continue
			}
			// got the oneshot expected char finally, so unset oneshot
			// stepping, and proceed
			oneShotStep = false
		}

		if v, ok := curnode.subtrees[part]; ok {
			// found a candidate. follow it with normal branch logic.
			// if it matches, we're done!
			// increment index value for checkPath because we consumed a char
			// by following oneShot
			if v.checkPath(s, i+1, mlen) {
				return true
			}
		}

		// was this the last char in path?
		if i == mlen-1 {
			// reached the end without a match, and the glob wasn't at the end
			// of the line...
			if !curnode.canMatch {
				return false
			}
			// this should be covered by the test in the start of the function,
			// but add it here in case the code changes in the future.
			return true
		}

		// if we walked the branch, and got no match, we may just need to consume
		// some more... reset oneshot stepping and continue onwards
		if oneShotLookahead {
			oneShotStep = true
		}
	}

	// exhausted the string, but never found a match
	return false
}

func (gpn *globPathNode) checkPath(s string, index, mlen int) bool {
	curnode := gpn
	// don't need to iter runes since we have ascii
	for i := index; i < mlen; i++ {
		part := uint32(s[i])

		// if icase, use lowercase letters for comparisons
		// 'A' == 65; 'Z' == 90
		if gpn.icase && 65 <= part && part <= 90 {
			part = part + 32
		}

		// node may have a glob child candidate (consumes), check that first
		if curnode.hasGlobChild {
			// get glob node, and call globconsume.
			// don't advance string pointer here though, as a glob is a match
			// node and not a standard char node (it can also match zero characters)
			if v, ok := curnode.subtrees[globChar]; ok && v.globConsume(s, i, mlen) {
				return true
			}
		}

		// oneshot means we only have one child candidate -- an optimization (fastpath)
		// to avoid the slow path map fallback
		if curnode.oneShot != nil {
			// only one candidate, and it _was_ the glob we tried.
			// we're done!
			if curnode.oneShot.nodeChar == globChar {
				return false
			}

			// if oneshot matches, use it
			if curnode.oneShot.nodeChar == part {
				curnode = curnode.oneShot
				continue
			}

			// we had once chance, and it wasn't a glob or a match
			// work is done on this branch
			return false
		}

		// more than one candidate, so fallback to map lookup, since we don't
		// know anything else
		v, ok := curnode.subtrees[part]
		if !ok {
			return false
		}
		curnode = v
	}

	// reached the end of the string.. check if curnode is a leaf or globby
	// note: unlikely we would end up with a globby here, but maybe possible.
	if curnode.canMatch || curnode.isGlob {
		return true
	}

	// didn't hit a leaf, and didn't find a match
	return false
}

func newGlobPathNode(icase bool) *globPathNode {
	// refs for valid tree chars
	// https://www.w3.org/TR/2011/WD-html5-20110525/urls.html (refers to RFC 3986)
	// https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Generic_syntax
	// http://www.asciitable.com
	//
	// omit: less than or equal to 0x0020 or greater than or equal to 0x007F
	// omit: 0x0022, 0x003C, 0x003E, 0x005B, 0x005E, 0x0060, and 0x007B to 0x007D
	// ... so set is:
	//   0x0021             33
	//   0x0023...0x003B    35-59
	//   0x003D             61
	//   0x003F...0x005A    63-90
	//   0x005C             92
	//   0x005D             93
	//   0x005F             94
	//   0x0061...0x007A    97-122
	//   0x007E             126
	// so a total possible of 85 chars, but spread out over 94 slots
	// since there are quite a few possible slots, let's use a map for now...
	// web searches say a map is faster in go above a certain size. benchmark later...

	// for now, since realloc cost is paid at creation, and we want to RSS size
	// and since we only /really/ care about lookup costs, just start with 0 initial
	// map size and let it grow as needed
	return &globPathNode{
		subtrees: make(map[uint32]*globPathNode, 0),
		icase:    icase,
	}
}
<commit_msg>make package clearer<commit_after>// Copyright (c) 2012-2019 Eli Janssen
// Use of this source code is governed by an MIT-style
// license that can be found in the LICENSE file.

package htrie

import (
	"fmt"
)

const globChar uint32 = 1

// A globPathNode represents a path checker that supports globbing comparisons
type globPathNode struct {
	// go maps are optimized for only certain int types:
	//  -- results as of go 1.13 on my slow laptop --
	//  BenchmarkInt        297391227    3.99 ns/op
	//  BenchmarkInt8        68107761   17.90 ns/op
	//  BenchmarkInt16       65628482   18.30 ns/op
	//  BenchmarkInt32      292725417    4.08 ns/op
	//  BenchmarkInt64      293602374    4.11 ns/op
	//  BenchmarkUInt       298711089    3.99 ns/op
	//  BenchmarkUInt8       68173198   17.80 ns/op
	//  BenchmarkUInt16      67566312   18.10 ns/op
	//  BenchmarkUInt32      298597942   3.99 ns/op
	//  BenchmarkUInt64      300239860   4.02 ns/op
	//
	// Since we would /want/ to use uint8 here, use uint32 instead
	// Ugly and wasteful, but quite a bit faster for now...
	subtrees map[uint32]*globPathNode
	// used to avoid map lookup when there is only one subtree candidate
	oneShot *globPathNode
	// is this path component a glob
	isGlob bool
	// determines whether a node can be a match even if it isn't a leaf node;
	// this becomes necessary due to the possibility of longer and shorter
	// paths overlapping
	canMatch bool
	// optimization to avoid an extra map lookup on every char
	hasGlobChild bool
	// char for this node
	nodeChar uint32
	// is this a case insensitive comparison tree?
	icase bool
}

func (gpn *globPathNode) addPath(s string) error {
	if gpn.subtrees == nil {
		return fmt.Errorf("got nil <gpn>.subtrees in receiver")
	}

	curnode := gpn
	prevnode := curnode
	mlen := len(s)
	//for _, part := range s {
	for i := 0; i < mlen; i++ {
		part := uint32(s[i])

		// if icase, use lowercase letters for comparisons
		// 'A' == 65; 'Z' == 90
		if gpn.icase && 65 <= part && part <= 90 {
			part = part + 32
		}

		var c uint32
		// '*' == 42
		if part == 42 {
			c = globChar
		} else {
			c = part
		}

		subt := curnode.subtrees
		if subt[c] == nil {
			subt[c] = newGlobPathNode(gpn.icase)
		}

		subt[c].nodeChar = part

		// setup oneshot as an optimizaiton if there is only one subcandidate...
		if len(subt) == 1 {
			curnode.oneShot = subt[c]
		} else {
			curnode.oneShot = nil
		}

		prevnode = curnode
		curnode = subt[c]
		if part == '*' {
			prevnode.hasGlobChild = true
			curnode.isGlob = true
		}
	}

	// this is the end of the path, so this node can be a match, even if future
	// urls add children to it (a longer url).
	curnode.canMatch = true
	return nil
}

func (gpn *globPathNode) globConsume(s string, index, mlen int) bool {
	// we have a glob and no follow-on chars, so we can consume
	// till the end and then match. early return
	if gpn.canMatch {
		return true
	}

	oneShotLookahead := false
	oneShotStep := false
	// optimize common single char after * globbing
	// eg. .../*/...
	if gpn.oneShot != nil {
		oneShotLookahead = true
		oneShotStep = true
	}

	// otherwise we have some work to do...
	curnode := gpn
	// don't need to iter runes since we have ascii
	for i := index; i < mlen; i++ {
		part := uint32(s[i])

		// if icase, use lowercase letters for comparisons
		// 'A' == 65; 'Z' == 90
		if gpn.icase && 65 <= part && part <= 90 {
			part = part + 32
		}

		// we know the glob has one one subcandidate (next char), so consume until
		// we hit one of those
		if oneShotStep {
			if part != curnode.oneShot.nodeChar {
				continue
			}
			// got the oneshot expected char finally, so unset oneshot
			// stepping, and proceed
			oneShotStep = false
		}

		if v, ok := curnode.subtrees[part]; ok {
			// found a candidate. follow it with normal branch logic.
			// if it matches, we're done!
			// increment index value for checkPath because we consumed a char
			// by following oneShot
			if v.checkPath(s, i+1, mlen) {
				return true
			}
		}

		// was this the last char in path?
		if i == mlen-1 {
			// reached the end without a match, and the glob wasn't at the end
			// of the line...
			if !curnode.canMatch {
				return false
			}
			// this should be covered by the test in the start of the function,
			// but add it here in case the code changes in the future.
			return true
		}

		// if we walked the branch, and got no match, we may just need to consume
		// some more... reset oneshot stepping and continue onwards
		if oneShotLookahead {
			oneShotStep = true
		}
	}

	// exhausted the string, but never found a match
	return false
}

func (gpn *globPathNode) checkPath(s string, index, mlen int) bool {
	curnode := gpn
	// don't need to iter runes since we have ascii
	for i := index; i < mlen; i++ {
		part := uint32(s[i])

		// if icase, use lowercase letters for comparisons
		// 'A' == 65; 'Z' == 90
		if gpn.icase && 65 <= part && part <= 90 {
			part = part + 32
		}

		// node may have a glob child candidate (consumes), check that first
		if curnode.hasGlobChild {
			// get glob node, and call globconsume.
			// don't advance string pointer here though, as a glob is a match
			// node and not a standard char node (it can also match zero characters)
			if v, ok := curnode.subtrees[globChar]; ok && v.globConsume(s, i, mlen) {
				return true
			}
		}

		// oneshot means we only have one child candidate -- an optimization (fastpath)
		// to avoid the slow path map fallback
		if curnode.oneShot != nil {
			// only one candidate, and it _was_ the glob we tried.
			// we're done!
			if curnode.oneShot.nodeChar == globChar {
				return false
			}

			// if oneshot matches, use it
			if curnode.oneShot.nodeChar == part {
				curnode = curnode.oneShot
				continue
			}

			// we had once chance, and it wasn't a glob or a match
			// work is done on this branch
			return false
		}

		// more than one candidate, so fallback to map lookup, since we don't
		// know anything else
		v, ok := curnode.subtrees[part]
		if !ok {
			return false
		}
		curnode = v
	}

	// reached the end of the string.. check if curnode is a leaf or globby
	// note: unlikely we would end up with a globby here, but maybe possible.
	if curnode.canMatch || curnode.isGlob {
		return true
	}

	// didn't hit a leaf, and didn't find a match
	return false
}

func newGlobPathNode(icase bool) *globPathNode {
	// refs for valid tree chars
	// https://www.w3.org/TR/2011/WD-html5-20110525/urls.html (refers to RFC 3986)
	// https://en.wikipedia.org/wiki/Uniform_Resource_Identifier#Generic_syntax
	// http://www.asciitable.com
	//
	// omit: less than or equal to 0x0020 or greater than or equal to 0x007F
	// omit: 0x0022, 0x003C, 0x003E, 0x005B, 0x005E, 0x0060, and 0x007B to 0x007D
	// ... so set is:
	//   0x0021             33
	//   0x0023...0x003B    35-59
	//   0x003D             61
	//   0x003F...0x005A    63-90
	//   0x005C             92
	//   0x005D             93
	//   0x005F             94
	//   0x0061...0x007A    97-122
	//   0x007E             126
	// so a total possible of 85 chars, but spread out over 94 slots
	// since there are quite a few possible slots, let's use a map for now...
	// web searches say a map is faster in go above a certain size. benchmark later...

	// for now, since realloc cost is paid at creation, and we want to RSS size
	// and since we only /really/ care about lookup costs, just start with 0 initial
	// map size and let it grow as needed
	return &globPathNode{
		subtrees: make(map[uint32]*globPathNode, 0),
		icase:    icase,
	}
}
<|endoftext|>


<commit_before>// Package api provides a framework for creating HTTP servers in Go
// (http://golang.org/) to handle API requests capable of replying in xml,
// json, or any other valid content type.

package api

import (
	"crypto/hmac"
	"crypto/sha1"
	"fmt"
	"log"
	"net/http"
	"os"
	"time"
)

type Server struct {
	mux    *http.ServeMux
	s      *http.Server
	Logger *log.Logger
}

var (
	Srv                      *Server
	DefaultServerReadTimeout = 30 // in seconds
)

// DigestMatches is an optional hmac check that can be applied to any or
// all api queries. DigestMatches takes three strings: a private key,
// a query term, and a sha1 digest of the query term string using the
// shared private key known only by authorized api clients and this server
// (see http://en.wikipedia.org/wiki/Hmac for more details on how it
// works). DigestMatches returns a boolean if the hmac digest is correct
// or not.
func DigestMatches(privateKey string, queryTerm string, queryTermDigest string) bool {
	h := hmac.New(sha1.New, []byte(privateKey))
	h.Write([]byte(queryTerm))
	hashed := fmt.Sprintf("%x", h.Sum(nil))
	return (hashed == queryTermDigest)
}

// Respond accepts an HTTP media type, charset, and a response function
// which returns a string. Respond wraps the server reply in the correct
// Content-type, charset, and Content-length, returning an http.HandlerFunc
// invoked by the HTTP multiplexer in reponse to the particular url pattern
// associated with this response function.
func Respond(mediaType string, charset string, fn func(w http.ResponseWriter, r *http.Request) string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", fmt.Sprintf("%s; charset=%s", mediaType, charset))
		data := fn(w, r)
		w.Header().Set("Content-Length", fmt.Sprintf("%d", len(data)))
		fmt.Fprintf(w, data)
	}
}

// NewServer takes a host or ip address string, a port number, read timeout
// (in secords), along with a map defining url string patterns, and their
// corresponding response functions. NewServer sets each map entry into
// the HTTP multiplexer, then starts the HTTP server on the given host/ip
// address and port. The api.Server struct also provides a Logger for each
// response function to use, to log warnings, errors, and other information.
func NewServer(host string, port int, timeout int, handlers map[string]func(http.ResponseWriter, *http.Request)) {

	mux := http.NewServeMux()
	for pattern, handler := range handlers {
		mux.Handle(pattern, http.HandlerFunc(handler))
	}

	s := &http.Server{
		Addr:        fmt.Sprintf("%s:%d", host, port),
		Handler:     mux,
		ReadTimeout: time.Duration(timeout) * time.Second, // to prevent abuse of "keep-alive" requests by clients
	}

	Srv = &Server{
		mux:    mux,
		s:      s,
		Logger: log.New(os.Stdout, "", log.Ldate|log.Ltime),
	}
	Srv.s.ListenAndServe()
}

// NewLocalServer takes a port number, read timeout (in secords), along with
// a map defining url string patterns, and their corresponding response
// functions. This function is a simpler alternative to NewServer, used
// when the api server will be running on the localhost.
func NewLocalServer(port int, timeout int, handlers map[string]func(http.ResponseWriter, *http.Request)) {
	NewServer("", port, timeout, handlers)
}

<commit_msg>Added option to run the server under FastCGI<commit_after>// Package api provides a framework for creating HTTP servers in Go
// (http://golang.org/) to handle API requests capable of replying in xml,
// json, or any other valid content type.

package api

import (
	"crypto/hmac"
	"crypto/sha1"
	"fmt"
	"log"
	"net"
	"net/http"
	"net/http/fcgi"
	"os"
	"time"
)

type Server struct {
	mux       *http.ServeMux
	s         *http.Server
	Logger    *log.Logger
	Transport string
}

var (
	Srv                      *Server
	DefaultServerReadTimeout = 30 // in seconds
	DefaultServerTransport   = "tcp"
)

// DigestMatches is an optional hmac check that can be applied to any or
// all api queries. DigestMatches takes three strings: a private key,
// a query term, and a sha1 digest of the query term string using the
// shared private key known only by authorized api clients and this server
// (see http://en.wikipedia.org/wiki/Hmac for more details on how it
// works). DigestMatches returns a boolean if the hmac digest is correct
// or not.
func DigestMatches(privateKey string, queryTerm string, queryTermDigest string) bool {
	h := hmac.New(sha1.New, []byte(privateKey))
	h.Write([]byte(queryTerm))
	hashed := fmt.Sprintf("%x", h.Sum(nil))
	return (hashed == queryTermDigest)
}

// Respond accepts an HTTP media type, charset, and a response function
// which returns a string. Respond wraps the server reply in the correct
// Content-type, charset, and Content-length, returning an http.HandlerFunc
// invoked by the HTTP multiplexer in reponse to the particular url pattern
// associated with this response function.
func Respond(mediaType string, charset string, fn func(w http.ResponseWriter, r *http.Request) string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", fmt.Sprintf("%s; charset=%s", mediaType, charset))
		data := fn(w, r)
		w.Header().Set("Content-Length", fmt.Sprintf("%d", len(data)))
		fmt.Fprintf(w, data)
	}
}

// NewServer takes a host or ip address string, a port number, read timeout
// (in secords), along with a map defining url string patterns, and their
// corresponding response functions. NewServer sets each map entry into
// the HTTP multiplexer, then starts the HTTP server on the given host/ip
// address and port. The api.Server struct also provides a Logger for each
// response function to use, to log warnings, errors, and other information.
func NewServer(host, transport string, port, timeout int, useFcgi bool, handlers map[string]func(http.ResponseWriter, *http.Request)) {

	mux := http.NewServeMux()
	for pattern, handler := range handlers {
		mux.Handle(pattern, http.HandlerFunc(handler))
	}

	s := &http.Server{
		Addr:        fmt.Sprintf("%s:%d", host, port),
		Handler:     mux,
		ReadTimeout: time.Duration(timeout) * time.Second, // to prevent abuse of "keep-alive" requests by clients
	}

	Srv = &Server{
		mux:       mux,
		s:         s,
		Logger:    log.New(os.Stdout, "", log.Ldate|log.Ltime),
		Transport: transport,
	}

	if useFcgi {
		// create a listener for the incoming FastCGI requests
		listener, err := net.Listen(Srv.Transport, Srv.s.Addr)
		if err != nil {
			Srv.Logger.Fatal(err)
		}
		fcgi.Serve(listener, Srv.mux)
	} else {
		// serve requests using the default http.Server
		Srv.s.ListenAndServe()
	}
}

// NewLocalServer takes a port number, read timeout (in secords), along with
// a map defining url string patterns, and their corresponding response
// functions. This function is a simpler alternative to NewServer, used
// when the api server will be running on the localhost.
func NewLocalServer(transport string, port, timeout int, useFcgi bool, handlers map[string]func(http.ResponseWriter, *http.Request)) {
	NewServer("", transport, port, timeout, useFcgi, handlers)
}
<|endoftext|>


<commit_before>package http

import (
	"encoding/json"
	"errors"
	"log"
	"net/http"
	"strings"

	cmodel "github.com/Cepave/common/model"
	"github.com/Cepave/query/graph"
	"github.com/Cepave/query/proc"
	"regexp"
)

type GraphHistoryParam struct {
	Start            int                     `json:"start"`
	End              int                     `json:"end"`
	CF               string                  `json:"cf"`
	EndpointCounters []cmodel.GraphInfoParam `json:"endpoint_counters"`
}

func graphQueryOne(ec cmodel.GraphInfoParam, body GraphHistoryParam, endpoint string, counter string) *cmodel.GraphQueryResponse {
	if endpoint == "" {
		endpoint = ec.Endpoint
	}
	if counter == "" {
		counter = ec.Counter
	}
	request := cmodel.GraphQueryParam{
		Start:     int64(body.Start),
		End:       int64(body.End),
		ConsolFun: body.CF,
		Endpoint:  endpoint,
		Counter:   counter,
	}
	result, err := graph.QueryOne(request)
	if err != nil {
		log.Printf("graph.queryOne fail, %v, (endpoint, counter) = (%s, %s)", err, endpoint, counter)
	}
	return result
}

func makeOneFakeResult(body GraphHistoryParam) *cmodel.GraphQueryResponse {
	for _, ec := range body.EndpointCounters {
		if !strings.Contains(ec.Counter,"packet-loss-rate") && !strings.Contains(ec.Counter,"average") {
			fakeResult := graphQueryOne(ec, body,"" , "")
			for i := range fakeResult.Values {
				fakeResult.Values[i].Value = cmodel.JsonFloat(0.0)
			}
			return fakeResult
		}
	}
	return nil
}

func detectCounter(counter string, body GraphHistoryParam) bool {
	for _, ec := range body.EndpointCounters {
		if strings.Contains(ec.Counter, counter) {
			return true
		}
	}
	return false
}

func nqmData(body GraphHistoryParam, nqmDataCounter string, rawDataCounter string) []*cmodel.GraphQueryResponse {

	result := makeOneFakeResult(body)
	if result == nil {
		return nil
	}
	data := []*cmodel.GraphQueryResponse{}
	packetSentCount := make([]cmodel.JsonFloat, len(result.Values))
	for i := range result.Values {
		packetSentCount[i] = cmodel.JsonFloat(0.0)
	}
	for _, ec := range body.EndpointCounters {
		if !strings.Contains(ec.Counter, rawDataCounter) {
			continue
		}

		resultRaw := graphQueryOne(ec, body, "", "")
		if resultRaw == nil {
			continue
		}
		data = append(data, resultRaw)

		if rawDataCounter == "packets-sent" {
			counter := strings.Replace(ec.Counter, "packets-sent", "packets-received", 1)
			if resultAdditional := graphQueryOne(ec, body, "", counter); resultAdditional != nil {
				data = append(data, resultAdditional)
				for i := range resultRaw.Values {
					packetLossCount := (resultRaw.Values[i].Value - resultAdditional.Values[i].Value)
					result.Values[i].Value += packetLossCount
					packetSentCount[i] += resultRaw.Values[i].Value
				}
			}
		} else if rawDataCounter == "transmission-time" {
			counter := strings.Replace(ec.Counter, "transmission-time", "packets-sent", 1)
			if resultAdditional := graphQueryOne(ec, body, "", counter); resultAdditional != nil {
				data = append(data, resultAdditional)
				for i := range resultAdditional.Values {
					result.Values[i].Value += resultAdditional.Values[i].Value * resultRaw.Values[i].Value
					packetSentCount[i] += resultAdditional.Values[i].Value
				}
			}
		}
	}
	for i := range result.Values {
		result.Values[i].Value = result.Values[i].Value / packetSentCount[i]
	}
	result.Endpoint = "all-endpoints"
	result.Counter = nqmDataCounter
	data = append(data, result)
	return data
}

func configGraphRoutes() {

	// method:post
	http.HandleFunc("/graph/history", func(w http.ResponseWriter, r *http.Request) {
		// statistics
		proc.HistoryRequestCnt.Incr()

		var body GraphHistoryParam
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&body)
		if err != nil {
			StdRender(w, "", err)
			return
		}

		if len(body.EndpointCounters) == 0 {
			StdRender(w, "", errors.New("empty_payload"))
			return
		}

		data := []*cmodel.GraphQueryResponse{}

		isPacketLossRate := detectCounter("packet-loss-rate", body)
		isAverage := detectCounter("average", body)

		if isPacketLossRate || isAverage {
			// NQM Case
			if isPacketLossRate {
				data = append(data, nqmData(body, "packet-loss-rate", "packets-sent")... )
			} else if isAverage {
				data = append(data, nqmData(body, "average", "transmission-time")... )
			}
		} else {
			for _, ec := range body.EndpointCounters {
				regx, _ := regexp.Compile("(\\.\\$\\s*|\\s*)$")
				endpoint := regx.ReplaceAllString(ec.Endpoint, "")
				counter := regx.ReplaceAllString(ec.Counter, "")
				result := graphQueryOne(ec, body, endpoint, counter)
				if result == nil {
					continue
				}
				data = append(data, result)
			}
		}
		log.Println("got length of data: ", len(data))

		// statistics
		proc.HistoryResponseCounterCnt.IncrBy(int64(len(data)))
		for _, item := range data {
			proc.HistoryResponseItemCnt.IncrBy(int64(len(item.Values)))
		}

		StdRender(w, data, nil)
	})

	// post, info
	http.HandleFunc("/graph/info", func(w http.ResponseWriter, r *http.Request) {
		// statistics
		proc.InfoRequestCnt.Incr()

		var body []*cmodel.GraphInfoParam
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&body)
		if err != nil {
			StdRender(w, "", err)
			return
		}

		if len(body) == 0 {
			StdRender(w, "", errors.New("empty"))
			return
		}

		data := []*cmodel.GraphFullyInfo{}
		for _, param := range body {
			if param == nil {
				continue
			}
			info, err := graph.Info(*param)
			if err != nil {
				log.Printf("graph.info fail, resp: %v, err: %v", info, err)
			}
			if info == nil {
				continue
			}
			data = append(data, info)
		}

		StdRender(w, data, nil)
	})

	// post, last
	http.HandleFunc("/graph/last", func(w http.ResponseWriter, r *http.Request) {
		// statistics
		proc.LastRequestCnt.Incr()

		var body []*cmodel.GraphLastParam
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&body)
		if err != nil {
			StdRender(w, "", err)
			return
		}

		if len(body) == 0 {
			StdRender(w, "", errors.New("empty"))
			return
		}

		data := []*cmodel.GraphLastResp{}
		for _, param := range body {
			if param == nil {
				continue
			}
			last, err := graph.Last(*param)
			if err != nil {
				log.Printf("graph.last fail, resp: %v, err: %v", last, err)
			}
			if last == nil {
				continue
			}
			data = append(data, last)
		}

		// statistics
		proc.LastRequestItemCnt.IncrBy(int64(len(data)))

		StdRender(w, data, nil)
	})

	// post, last/raw
	http.HandleFunc("/graph/last/raw", func(w http.ResponseWriter, r *http.Request) {
		// statistics
		proc.LastRawRequestCnt.Incr()

		var body []*cmodel.GraphLastParam
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&body)
		if err != nil {
			StdRender(w, "", err)
			return
		}

		if len(body) == 0 {
			StdRender(w, "", errors.New("empty"))
			return
		}

		data := []*cmodel.GraphLastResp{}
		for _, param := range body {
			if param == nil {
				continue
			}
			last, err := graph.LastRaw(*param)
			if err != nil {
				log.Printf("graph.last.raw fail, resp: %v, err: %v", last, err)
			}
			if last == nil {
				continue
			}
			data = append(data, last)
		}
		// statistics
		proc.LastRawRequestItemCnt.IncrBy(int64(len(data)))
		StdRender(w, data, nil)
	})

}
<commit_msg>go format<commit_after>package http

import (
	"encoding/json"
	"errors"
	"log"
	"net/http"
	"strings"

	"regexp"

	cmodel "github.com/Cepave/common/model"
	"github.com/Cepave/query/graph"
	"github.com/Cepave/query/proc"
)

type GraphHistoryParam struct {
	Start            int                     `json:"start"`
	End              int                     `json:"end"`
	CF               string                  `json:"cf"`
	EndpointCounters []cmodel.GraphInfoParam `json:"endpoint_counters"`
}

func graphQueryOne(ec cmodel.GraphInfoParam, body GraphHistoryParam, endpoint string, counter string) *cmodel.GraphQueryResponse {
	if endpoint == "" {
		endpoint = ec.Endpoint
	}
	if counter == "" {
		counter = ec.Counter
	}
	request := cmodel.GraphQueryParam{
		Start:     int64(body.Start),
		End:       int64(body.End),
		ConsolFun: body.CF,
		Endpoint:  endpoint,
		Counter:   counter,
	}
	result, err := graph.QueryOne(request)
	if err != nil {
		log.Printf("graph.queryOne fail, %v, (endpoint, counter) = (%s, %s)", err, endpoint, counter)
	}
	return result
}

func makeOneFakeResult(body GraphHistoryParam) *cmodel.GraphQueryResponse {
	for _, ec := range body.EndpointCounters {
		if !strings.Contains(ec.Counter, "packet-loss-rate") && !strings.Contains(ec.Counter, "average") {
			fakeResult := graphQueryOne(ec, body, "", "")
			for i := range fakeResult.Values {
				fakeResult.Values[i].Value = cmodel.JsonFloat(0.0)
			}
			return fakeResult
		}
	}
	return nil
}

func detectCounter(counter string, body GraphHistoryParam) bool {
	for _, ec := range body.EndpointCounters {
		if strings.Contains(ec.Counter, counter) {
			return true
		}
	}
	return false
}

func nqmData(body GraphHistoryParam, nqmDataCounter string, rawDataCounter string) []*cmodel.GraphQueryResponse {

	result := makeOneFakeResult(body)
	if result == nil {
		return nil
	}
	data := []*cmodel.GraphQueryResponse{}
	packetSentCount := make([]cmodel.JsonFloat, len(result.Values))
	for i := range result.Values {
		packetSentCount[i] = cmodel.JsonFloat(0.0)
	}
	for _, ec := range body.EndpointCounters {
		if !strings.Contains(ec.Counter, rawDataCounter) {
			continue
		}

		resultRaw := graphQueryOne(ec, body, "", "")
		if resultRaw == nil {
			continue
		}
		data = append(data, resultRaw)

		if rawDataCounter == "packets-sent" {
			counter := strings.Replace(ec.Counter, "packets-sent", "packets-received", 1)
			if resultAdditional := graphQueryOne(ec, body, "", counter); resultAdditional != nil {
				data = append(data, resultAdditional)
				for i := range resultRaw.Values {
					packetLossCount := (resultRaw.Values[i].Value - resultAdditional.Values[i].Value)
					result.Values[i].Value += packetLossCount
					packetSentCount[i] += resultRaw.Values[i].Value
				}
			}
		} else if rawDataCounter == "transmission-time" {
			counter := strings.Replace(ec.Counter, "transmission-time", "packets-sent", 1)
			if resultAdditional := graphQueryOne(ec, body, "", counter); resultAdditional != nil {
				data = append(data, resultAdditional)
				for i := range resultAdditional.Values {
					result.Values[i].Value += resultAdditional.Values[i].Value * resultRaw.Values[i].Value
					packetSentCount[i] += resultAdditional.Values[i].Value
				}
			}
		}
	}
	for i := range result.Values {
		result.Values[i].Value = result.Values[i].Value / packetSentCount[i]
	}
	result.Endpoint = "all-endpoints"
	result.Counter = nqmDataCounter
	data = append(data, result)
	return data
}

func configGraphRoutes() {

	// method:post
	http.HandleFunc("/graph/history", func(w http.ResponseWriter, r *http.Request) {
		// statistics
		proc.HistoryRequestCnt.Incr()

		var body GraphHistoryParam
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&body)
		if err != nil {
			StdRender(w, "", err)
			return
		}

		if len(body.EndpointCounters) == 0 {
			StdRender(w, "", errors.New("empty_payload"))
			return
		}

		data := []*cmodel.GraphQueryResponse{}

		isPacketLossRate := detectCounter("packet-loss-rate", body)
		isAverage := detectCounter("average", body)

		if isPacketLossRate || isAverage {
			// NQM Case
			if isPacketLossRate {
				data = append(data, nqmData(body, "packet-loss-rate", "packets-sent")...)
			} else if isAverage {
				data = append(data, nqmData(body, "average", "transmission-time")...)
			}
		} else {
			for _, ec := range body.EndpointCounters {
				regx, _ := regexp.Compile("(\\.\\$\\s*|\\s*)$")
				endpoint := regx.ReplaceAllString(ec.Endpoint, "")
				counter := regx.ReplaceAllString(ec.Counter, "")
				result := graphQueryOne(ec, body, endpoint, counter)
				if result == nil {
					continue
				}
				data = append(data, result)
			}
		}
		log.Println("got length of data: ", len(data))

		// statistics
		proc.HistoryResponseCounterCnt.IncrBy(int64(len(data)))
		for _, item := range data {
			proc.HistoryResponseItemCnt.IncrBy(int64(len(item.Values)))
		}

		StdRender(w, data, nil)
	})

	// post, info
	http.HandleFunc("/graph/info", func(w http.ResponseWriter, r *http.Request) {
		// statistics
		proc.InfoRequestCnt.Incr()

		var body []*cmodel.GraphInfoParam
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&body)
		if err != nil {
			StdRender(w, "", err)
			return
		}

		if len(body) == 0 {
			StdRender(w, "", errors.New("empty"))
			return
		}

		data := []*cmodel.GraphFullyInfo{}
		for _, param := range body {
			if param == nil {
				continue
			}
			info, err := graph.Info(*param)
			if err != nil {
				log.Printf("graph.info fail, resp: %v, err: %v", info, err)
			}
			if info == nil {
				continue
			}
			data = append(data, info)
		}

		StdRender(w, data, nil)
	})

	// post, last
	http.HandleFunc("/graph/last", func(w http.ResponseWriter, r *http.Request) {
		// statistics
		proc.LastRequestCnt.Incr()

		var body []*cmodel.GraphLastParam
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&body)
		if err != nil {
			StdRender(w, "", err)
			return
		}

		if len(body) == 0 {
			StdRender(w, "", errors.New("empty"))
			return
		}

		data := []*cmodel.GraphLastResp{}
		for _, param := range body {
			if param == nil {
				continue
			}
			last, err := graph.Last(*param)
			if err != nil {
				log.Printf("graph.last fail, resp: %v, err: %v", last, err)
			}
			if last == nil {
				continue
			}
			data = append(data, last)
		}

		// statistics
		proc.LastRequestItemCnt.IncrBy(int64(len(data)))

		StdRender(w, data, nil)
	})

	// post, last/raw
	http.HandleFunc("/graph/last/raw", func(w http.ResponseWriter, r *http.Request) {
		// statistics
		proc.LastRawRequestCnt.Incr()

		var body []*cmodel.GraphLastParam
		decoder := json.NewDecoder(r.Body)
		err := decoder.Decode(&body)
		if err != nil {
			StdRender(w, "", err)
			return
		}

		if len(body) == 0 {
			StdRender(w, "", errors.New("empty"))
			return
		}

		data := []*cmodel.GraphLastResp{}
		for _, param := range body {
			if param == nil {
				continue
			}
			last, err := graph.LastRaw(*param)
			if err != nil {
				log.Printf("graph.last.raw fail, resp: %v, err: %v", last, err)
			}
			if last == nil {
				continue
			}
			data = append(data, last)
		}
		// statistics
		proc.LastRawRequestItemCnt.IncrBy(int64(len(data)))
		StdRender(w, data, nil)
	})

}
<|endoftext|>


<commit_before>// Copyright (c) 2013-2017 The btcsuite developers
// Copyright (c) 2015-2021 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package txscript

import (
	"github.com/decred/dcrd/dcrec"
)

const (
	// MaxDataCarrierSize is the maximum number of bytes allowed in pushed
	// data to be considered a nulldata transaction.
	MaxDataCarrierSize = 256
)

// ScriptClass is an enumeration for the list of standard types of script.
type ScriptClass byte

// Classes of script payment known about in the blockchain.
const (
	NonStandardTy     ScriptClass = iota // None of the recognized forms.
	PubKeyTy                             // Pay pubkey.
	PubKeyHashTy                         // Pay pubkey hash.
	ScriptHashTy                         // Pay to script hash.
	MultiSigTy                           // Multi signature.
	NullDataTy                           // Empty data-only (provably prunable).
	StakeSubmissionTy                    // Stake submission.
	StakeGenTy                           // Stake generation
	StakeRevocationTy                    // Stake revocation.
	StakeSubChangeTy                     // Change for stake submission tx.
	PubkeyAltTy                          // Alternative signature pubkey.
	PubkeyHashAltTy                      // Alternative signature pubkey hash.
	TreasuryAddTy                        // Add value to treasury
	TreasuryGenTy                        // Generate utxos from treasury account
)

// scriptClassToName houses the human-readable strings which describe each
// script class.
var scriptClassToName = []string{
	NonStandardTy:     "nonstandard",
	PubKeyTy:          "pubkey",
	PubkeyAltTy:       "pubkeyalt",
	PubKeyHashTy:      "pubkeyhash",
	PubkeyHashAltTy:   "pubkeyhashalt",
	ScriptHashTy:      "scripthash",
	MultiSigTy:        "multisig",
	NullDataTy:        "nulldata",
	StakeSubmissionTy: "stakesubmission",
	StakeGenTy:        "stakegen",
	StakeRevocationTy: "stakerevoke",
	StakeSubChangeTy:  "sstxchange",
	TreasuryAddTy:     "treasuryadd",
	TreasuryGenTy:     "treasurygen",
}

// String implements the Stringer interface by returning the name of
// the enum script class. If the enum is invalid then "Invalid" will be
// returned.
func (t ScriptClass) String() string {
	if int(t) > len(scriptClassToName) || int(t) < 0 {
		return "Invalid"
	}
	return scriptClassToName[t]
}

// extractCompressedPubKey extracts a compressed public key from the passed
// script if it is a standard pay-to-compressed-secp256k1-pubkey script.  It
// will return nil otherwise.
func extractCompressedPubKey(script []byte) []byte {
	// A pay-to-compressed-pubkey script is of the form:
	//  OP_DATA_33 <33-byte compressed pubkey> OP_CHECKSIG

	// All compressed secp256k1 public keys must start with 0x02 or 0x03.
	if len(script) == 35 &&
		script[34] == OP_CHECKSIG &&
		script[0] == OP_DATA_33 &&
		(script[1] == 0x02 || script[1] == 0x03) {

		return script[1:34]
	}
	return nil
}

// extractUncompressedPubKey extracts an uncompressed public key from the
// passed script if it is a standard pay-to-uncompressed-secp256k1-pubkey
// script.  It will return nil otherwise.
func extractUncompressedPubKey(script []byte) []byte {
	// A pay-to-uncompressed-pubkey script is of the form:
	//  OP_DATA_65 <65-byte uncompressed pubkey> OP_CHECKSIG

	// All non-hybrid uncompressed secp256k1 public keys must start with 0x04.
	if len(script) == 67 &&
		script[66] == OP_CHECKSIG &&
		script[0] == OP_DATA_65 &&
		script[1] == 0x04 {

		return script[1:66]
	}
	return nil
}

// extractPubKey extracts either a compressed or uncompressed public key from the
// passed script if it is either a standard pay-to-compressed-secp256k1-pubkey
// or pay-to-uncompressed-secp256k1-pubkey script, respectively.  It will return
// nil otherwise.
func extractPubKey(script []byte) []byte {
	if pubKey := extractCompressedPubKey(script); pubKey != nil {
		return pubKey
	}
	return extractUncompressedPubKey(script)
}

// isPubKeyScript returns whether or not the passed script is either a standard
// pay-to-compressed-secp256k1-pubkey or pay-to-uncompressed-secp256k1-pubkey
// script.
func isPubKeyScript(script []byte) bool {
	return extractPubKey(script) != nil
}

// extractPubKeyAltDetails extracts the public key and signature type from the
// passed script if it is a standard pay-to-alt-pubkey script.  It will return
// nil otherwise.
func extractPubKeyAltDetails(script []byte) ([]byte, dcrec.SignatureType) {
	// A pay-to-alt-pubkey script is of the form:
	//  PUBKEY SIGTYPE OP_CHECKSIGALT
	//
	// The only two currently supported alternative signature types are ed25519
	// and schnorr + secp256k1 (with a compressed pubkey).
	//
	//  OP_DATA_32 <32-byte pubkey> <1-byte ed25519 sigtype> OP_CHECKSIGALT
	//  OP_DATA_33 <33-byte pubkey> <1-byte schnorr+secp sigtype> OP_CHECKSIGALT

	// The script can't possibly be a pay-to-alt-pubkey script if it doesn't
	// end with OP_CHECKSIGALT or have at least two small integer pushes
	// preceding it (although any reasonable pubkey will certainly be larger).
	// Fail fast to avoid more work below.
	if len(script) < 3 || script[len(script)-1] != OP_CHECKSIGALT {
		return nil, 0
	}

	if len(script) == 35 && script[0] == OP_DATA_32 &&
		IsSmallInt(script[33]) && AsSmallInt(script[33]) == dcrec.STEd25519 {

		return script[1:33], dcrec.STEd25519
	}

	if len(script) == 36 && script[0] == OP_DATA_33 &&
		IsSmallInt(script[34]) &&
		AsSmallInt(script[34]) == dcrec.STSchnorrSecp256k1 &&
		isStrictPubKeyEncoding(script[1:34]) {

		return script[1:34], dcrec.STSchnorrSecp256k1
	}

	return nil, 0
}

// isPubKeyAltScript returns whether or not the passed script is a standard
// pay-to-alt-pubkey script.
func isPubKeyAltScript(script []byte) bool {
	pk, _ := extractPubKeyAltDetails(script)
	return pk != nil
}

// extractPubKeyHash extracts the public key hash from the passed script if it
// is a standard pay-to-pubkey-hash script.  It will return nil otherwise.
func extractPubKeyHash(script []byte) []byte {
	// A pay-to-pubkey-hash script is of the form:
	//  OP_DUP OP_HASH160 <20-byte hash> OP_EQUALVERIFY OP_CHECKSIG
	if len(script) == 25 &&
		script[0] == OP_DUP &&
		script[1] == OP_HASH160 &&
		script[2] == OP_DATA_20 &&
		script[23] == OP_EQUALVERIFY &&
		script[24] == OP_CHECKSIG {

		return script[3:23]
	}

	return nil
}

// isStandardAltSignatureType returns whether or not the provided opcode
// represents a push of a standard alt signature type.
func isStandardAltSignatureType(op byte) bool {
	if !IsSmallInt(op) {
		return false
	}

	sigType := AsSmallInt(op)
	return sigType == dcrec.STEd25519 || sigType == dcrec.STSchnorrSecp256k1
}

// extractPubKeyHashAltDetails extracts the public key hash and signature type
// from the passed script if it is a standard pay-to-alt-pubkey-hash script.  It
// will return nil otherwise.
func extractPubKeyHashAltDetails(script []byte) ([]byte, dcrec.SignatureType) {
	// A pay-to-alt-pubkey-hash script is of the form:
	//  DUP HASH160 <20-byte hash> EQUALVERIFY SIGTYPE CHECKSIG
	//
	// The only two currently supported alternative signature types are ed25519
	// and schnorr + secp256k1 (with a compressed pubkey).
	//
	//  DUP HASH160 <20-byte hash> EQUALVERIFY <1-byte ed25519 sigtype> CHECKSIG
	//  DUP HASH160 <20-byte hash> EQUALVERIFY <1-byte schnorr+secp sigtype> CHECKSIG
	//
	//  Notice that OP_0 is not specified since signature type 0 disabled.

	if len(script) == 26 &&
		script[0] == OP_DUP &&
		script[1] == OP_HASH160 &&
		script[2] == OP_DATA_20 &&
		script[23] == OP_EQUALVERIFY &&
		isStandardAltSignatureType(script[24]) &&
		script[25] == OP_CHECKSIGALT {

		return script[3:23], dcrec.SignatureType(AsSmallInt(script[24]))
	}

	return nil, 0
}

// isPubKeyHashAltScript returns whether or not the passed script is a standard
// pay-to-alt-pubkey-hash script.
func isPubKeyHashAltScript(script []byte) bool {
	pk, _ := extractPubKeyHashAltDetails(script)
	return pk != nil
}
<commit_msg>txscript: Remove unused extractPubKeyHash.<commit_after>// Copyright (c) 2013-2017 The btcsuite developers
// Copyright (c) 2015-2021 The Decred developers
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package txscript

import (
	"github.com/decred/dcrd/dcrec"
)

const (
	// MaxDataCarrierSize is the maximum number of bytes allowed in pushed
	// data to be considered a nulldata transaction.
	MaxDataCarrierSize = 256
)

// ScriptClass is an enumeration for the list of standard types of script.
type ScriptClass byte

// Classes of script payment known about in the blockchain.
const (
	NonStandardTy     ScriptClass = iota // None of the recognized forms.
	PubKeyTy                             // Pay pubkey.
	PubKeyHashTy                         // Pay pubkey hash.
	ScriptHashTy                         // Pay to script hash.
	MultiSigTy                           // Multi signature.
	NullDataTy                           // Empty data-only (provably prunable).
	StakeSubmissionTy                    // Stake submission.
	StakeGenTy                           // Stake generation
	StakeRevocationTy                    // Stake revocation.
	StakeSubChangeTy                     // Change for stake submission tx.
	PubkeyAltTy                          // Alternative signature pubkey.
	PubkeyHashAltTy                      // Alternative signature pubkey hash.
	TreasuryAddTy                        // Add value to treasury
	TreasuryGenTy                        // Generate utxos from treasury account
)

// scriptClassToName houses the human-readable strings which describe each
// script class.
var scriptClassToName = []string{
	NonStandardTy:     "nonstandard",
	PubKeyTy:          "pubkey",
	PubkeyAltTy:       "pubkeyalt",
	PubKeyHashTy:      "pubkeyhash",
	PubkeyHashAltTy:   "pubkeyhashalt",
	ScriptHashTy:      "scripthash",
	MultiSigTy:        "multisig",
	NullDataTy:        "nulldata",
	StakeSubmissionTy: "stakesubmission",
	StakeGenTy:        "stakegen",
	StakeRevocationTy: "stakerevoke",
	StakeSubChangeTy:  "sstxchange",
	TreasuryAddTy:     "treasuryadd",
	TreasuryGenTy:     "treasurygen",
}

// String implements the Stringer interface by returning the name of
// the enum script class. If the enum is invalid then "Invalid" will be
// returned.
func (t ScriptClass) String() string {
	if int(t) > len(scriptClassToName) || int(t) < 0 {
		return "Invalid"
	}
	return scriptClassToName[t]
}

// extractCompressedPubKey extracts a compressed public key from the passed
// script if it is a standard pay-to-compressed-secp256k1-pubkey script.  It
// will return nil otherwise.
func extractCompressedPubKey(script []byte) []byte {
	// A pay-to-compressed-pubkey script is of the form:
	//  OP_DATA_33 <33-byte compressed pubkey> OP_CHECKSIG

	// All compressed secp256k1 public keys must start with 0x02 or 0x03.
	if len(script) == 35 &&
		script[34] == OP_CHECKSIG &&
		script[0] == OP_DATA_33 &&
		(script[1] == 0x02 || script[1] == 0x03) {

		return script[1:34]
	}
	return nil
}

// extractUncompressedPubKey extracts an uncompressed public key from the
// passed script if it is a standard pay-to-uncompressed-secp256k1-pubkey
// script.  It will return nil otherwise.
func extractUncompressedPubKey(script []byte) []byte {
	// A pay-to-uncompressed-pubkey script is of the form:
	//  OP_DATA_65 <65-byte uncompressed pubkey> OP_CHECKSIG

	// All non-hybrid uncompressed secp256k1 public keys must start with 0x04.
	if len(script) == 67 &&
		script[66] == OP_CHECKSIG &&
		script[0] == OP_DATA_65 &&
		script[1] == 0x04 {

		return script[1:66]
	}
	return nil
}

// extractPubKey extracts either a compressed or uncompressed public key from the
// passed script if it is either a standard pay-to-compressed-secp256k1-pubkey
// or pay-to-uncompressed-secp256k1-pubkey script, respectively.  It will return
// nil otherwise.
func extractPubKey(script []byte) []byte {
	if pubKey := extractCompressedPubKey(script); pubKey != nil {
		return pubKey
	}
	return extractUncompressedPubKey(script)
}

// isPubKeyScript returns whether or not the passed script is either a standard
// pay-to-compressed-secp256k1-pubkey or pay-to-uncompressed-secp256k1-pubkey
// script.
func isPubKeyScript(script []byte) bool {
	return extractPubKey(script) != nil
}

// extractPubKeyAltDetails extracts the public key and signature type from the
// passed script if it is a standard pay-to-alt-pubkey script.  It will return
// nil otherwise.
func extractPubKeyAltDetails(script []byte) ([]byte, dcrec.SignatureType) {
	// A pay-to-alt-pubkey script is of the form:
	//  PUBKEY SIGTYPE OP_CHECKSIGALT
	//
	// The only two currently supported alternative signature types are ed25519
	// and schnorr + secp256k1 (with a compressed pubkey).
	//
	//  OP_DATA_32 <32-byte pubkey> <1-byte ed25519 sigtype> OP_CHECKSIGALT
	//  OP_DATA_33 <33-byte pubkey> <1-byte schnorr+secp sigtype> OP_CHECKSIGALT

	// The script can't possibly be a pay-to-alt-pubkey script if it doesn't
	// end with OP_CHECKSIGALT or have at least two small integer pushes
	// preceding it (although any reasonable pubkey will certainly be larger).
	// Fail fast to avoid more work below.
	if len(script) < 3 || script[len(script)-1] != OP_CHECKSIGALT {
		return nil, 0
	}

	if len(script) == 35 && script[0] == OP_DATA_32 &&
		IsSmallInt(script[33]) && AsSmallInt(script[33]) == dcrec.STEd25519 {

		return script[1:33], dcrec.STEd25519
	}

	if len(script) == 36 && script[0] == OP_DATA_33 &&
		IsSmallInt(script[34]) &&
		AsSmallInt(script[34]) == dcrec.STSchnorrSecp256k1 &&
		isStrictPubKeyEncoding(script[1:34]) {

		return script[1:34], dcrec.STSchnorrSecp256k1
	}

	return nil, 0
}

// isPubKeyAltScript returns whether or not the passed script is a standard
// pay-to-alt-pubkey script.
func isPubKeyAltScript(script []byte) bool {
	pk, _ := extractPubKeyAltDetails(script)
	return pk != nil
}

// isStandardAltSignatureType returns whether or not the provided opcode
// represents a push of a standard alt signature type.
func isStandardAltSignatureType(op byte) bool {
	if !IsSmallInt(op) {
		return false
	}

	sigType := AsSmallInt(op)
	return sigType == dcrec.STEd25519 || sigType == dcrec.STSchnorrSecp256k1
}

// extractPubKeyHashAltDetails extracts the public key hash and signature type
// from the passed script if it is a standard pay-to-alt-pubkey-hash script.  It
// will return nil otherwise.
func extractPubKeyHashAltDetails(script []byte) ([]byte, dcrec.SignatureType) {
	// A pay-to-alt-pubkey-hash script is of the form:
	//  DUP HASH160 <20-byte hash> EQUALVERIFY SIGTYPE CHECKSIG
	//
	// The only two currently supported alternative signature types are ed25519
	// and schnorr + secp256k1 (with a compressed pubkey).
	//
	//  DUP HASH160 <20-byte hash> EQUALVERIFY <1-byte ed25519 sigtype> CHECKSIG
	//  DUP HASH160 <20-byte hash> EQUALVERIFY <1-byte schnorr+secp sigtype> CHECKSIG
	//
	//  Notice that OP_0 is not specified since signature type 0 disabled.

	if len(script) == 26 &&
		script[0] == OP_DUP &&
		script[1] == OP_HASH160 &&
		script[2] == OP_DATA_20 &&
		script[23] == OP_EQUALVERIFY &&
		isStandardAltSignatureType(script[24]) &&
		script[25] == OP_CHECKSIGALT {

		return script[3:23], dcrec.SignatureType(AsSmallInt(script[24]))
	}

	return nil, 0
}

// isPubKeyHashAltScript returns whether or not the passed script is a standard
// pay-to-alt-pubkey-hash script.
func isPubKeyHashAltScript(script []byte) bool {
	pk, _ := extractPubKeyHashAltDetails(script)
	return pk != nil
}
<|endoftext|>


<commit_before>package audit

import (
	"reflect"
	"strings"

	"github.com/hashicorp/vault/helper/salt"
	"github.com/hashicorp/vault/logical"
	"github.com/mitchellh/copystructure"
	"github.com/mitchellh/reflectwalk"
)

// HashString hashes the given opaque string and returns it
func HashString(salter *salt.Salt, data string) string {
	return salter.GetIdentifiedHMAC(data)
}

// Hash will hash the given type. This has built-in support for auth,
// requests, and responses. If it is a type that isn't recognized, then
// it will be passed through.
//
// The structure is modified in-place.
func Hash(salter *salt.Salt, raw interface{}) error {
	fn := salter.GetIdentifiedHMAC

	switch s := raw.(type) {
	case *logical.Auth:
		if s == nil {
			return nil
		}
		if s.ClientToken != "" {
			token := fn(s.ClientToken)
			s.ClientToken = token
		}

	case *logical.Request:
		if s == nil {
			return nil
		}
		if s.Auth != nil {
			if err := Hash(salter, s.Auth); err != nil {
				return err
			}
		}

		if s.ClientToken != "" {
			token := fn(s.ClientToken)
			s.ClientToken = token
		}

		data, err := HashStructure(s.Data, fn)
		if err != nil {
			return err
		}

		s.Data = data.(map[string]interface{})

	case *logical.Response:
		if s == nil {
			return nil
		}

		if s.Auth != nil {
			if err := Hash(salter, s.Auth); err != nil {
				return err
			}
		}

		data, err := HashStructure(s.Data, fn)
		if err != nil {
			return err
		}

		s.Data = data.(map[string]interface{})
	}

	return nil
}

// HashStructure takes an interface and hashes all the values within
// the structure. Only _values_ are hashed: keys of objects are not.
//
// For the HashCallback, see the built-in HashCallbacks below.
func HashStructure(s interface{}, cb HashCallback) (interface{}, error) {
	s, err := copystructure.Copy(s)
	if err != nil {
		return nil, err
	}

	walker := &hashWalker{Callback: cb}
	if err := reflectwalk.Walk(s, walker); err != nil {
		return nil, err
	}

	return s, nil
}

// HashCallback is the callback called for HashStructure to hash
// a value.
type HashCallback func(string) string

// hashWalker implements interfaces for the reflectwalk package
// (github.com/mitchellh/reflectwalk) that can be used to automatically
// replace primitives with a hashed value.
type hashWalker struct {
	// Callback is the function to call with the primitive that is
	// to be hashed. If there is an error, walking will be halted
	// immediately and the error returned.
	Callback HashCallback

	key         []string
	lastValue   reflect.Value
	loc         reflectwalk.Location
	cs          []reflect.Value
	csKey       []reflect.Value
	csData      interface{}
	sliceIndex  int
	unknownKeys []string
}

func (w *hashWalker) Enter(loc reflectwalk.Location) error {
	w.loc = loc
	return nil
}

func (w *hashWalker) Exit(loc reflectwalk.Location) error {
	w.loc = reflectwalk.None

	switch loc {
	case reflectwalk.Map:
		w.cs = w.cs[:len(w.cs)-1]
	case reflectwalk.MapValue:
		w.key = w.key[:len(w.key)-1]
		w.csKey = w.csKey[:len(w.csKey)-1]
	case reflectwalk.Slice:
		w.cs = w.cs[:len(w.cs)-1]
	case reflectwalk.SliceElem:
		w.csKey = w.csKey[:len(w.csKey)-1]
	}

	return nil
}

func (w *hashWalker) Map(m reflect.Value) error {
	w.cs = append(w.cs, m)
	return nil
}

func (w *hashWalker) MapElem(m, k, v reflect.Value) error {
	w.csData = k
	w.csKey = append(w.csKey, k)
	w.key = append(w.key, k.String())
	w.lastValue = v
	return nil
}

func (w *hashWalker) Slice(s reflect.Value) error {
	w.cs = append(w.cs, s)
	return nil
}

func (w *hashWalker) SliceElem(i int, elem reflect.Value) error {
	w.csKey = append(w.csKey, reflect.ValueOf(i))
	w.sliceIndex = i
	return nil
}

func (w *hashWalker) Primitive(v reflect.Value) error {
	if w.Callback == nil {
		return nil
	}

	// We don't touch map keys
	if w.loc == reflectwalk.MapKey {
		return nil
	}

	setV := v

	// We only care about strings
	if v.Kind() == reflect.Interface {
		setV = v
		v = v.Elem()
	}
	if v.Kind() != reflect.String {
		return nil
	}

	replaceVal := w.Callback(v.Interface().(string))

	resultVal := reflect.ValueOf(replaceVal)
	switch w.loc {
	case reflectwalk.MapKey:
		m := w.cs[len(w.cs)-1]

		// Delete the old value
		var zero reflect.Value
		m.SetMapIndex(w.csData.(reflect.Value), zero)

		// Set the new key with the existing value
		m.SetMapIndex(resultVal, w.lastValue)

		// Set the key to be the new key
		w.csData = resultVal
	case reflectwalk.MapValue:
		// If we're in a map, then the only way to set a map value is
		// to set it directly.
		m := w.cs[len(w.cs)-1]
		mk := w.csData.(reflect.Value)
		m.SetMapIndex(mk, resultVal)
	default:
		// Otherwise, we should be addressable
		setV.Set(resultVal)
	}

	return nil
}

func (w *hashWalker) removeCurrent() {
	// Append the key to the unknown keys
	w.unknownKeys = append(w.unknownKeys, strings.Join(w.key, "."))

	for i := 1; i <= len(w.cs); i++ {
		c := w.cs[len(w.cs)-i]
		switch c.Kind() {
		case reflect.Map:
			// Zero value so that we delete the map key
			var val reflect.Value

			// Get the key and delete it
			k := w.csData.(reflect.Value)
			c.SetMapIndex(k, val)
			return
		}
	}

	panic("No container found for removeCurrent")
}

func (w *hashWalker) replaceCurrent(v reflect.Value) {
	c := w.cs[len(w.cs)-2]
	switch c.Kind() {
	case reflect.Map:
		// Get the key and delete it
		k := w.csKey[len(w.csKey)-1]
		c.SetMapIndex(k, v)
	}
}
<commit_msg>Use reflect.Value.String() rather than a type assertion.<commit_after>package audit

import (
	"reflect"
	"strings"

	"github.com/hashicorp/vault/helper/salt"
	"github.com/hashicorp/vault/logical"
	"github.com/mitchellh/copystructure"
	"github.com/mitchellh/reflectwalk"
)

// HashString hashes the given opaque string and returns it
func HashString(salter *salt.Salt, data string) string {
	return salter.GetIdentifiedHMAC(data)
}

// Hash will hash the given type. This has built-in support for auth,
// requests, and responses. If it is a type that isn't recognized, then
// it will be passed through.
//
// The structure is modified in-place.
func Hash(salter *salt.Salt, raw interface{}) error {
	fn := salter.GetIdentifiedHMAC

	switch s := raw.(type) {
	case *logical.Auth:
		if s == nil {
			return nil
		}
		if s.ClientToken != "" {
			token := fn(s.ClientToken)
			s.ClientToken = token
		}

	case *logical.Request:
		if s == nil {
			return nil
		}
		if s.Auth != nil {
			if err := Hash(salter, s.Auth); err != nil {
				return err
			}
		}

		if s.ClientToken != "" {
			token := fn(s.ClientToken)
			s.ClientToken = token
		}

		data, err := HashStructure(s.Data, fn)
		if err != nil {
			return err
		}

		s.Data = data.(map[string]interface{})

	case *logical.Response:
		if s == nil {
			return nil
		}

		if s.Auth != nil {
			if err := Hash(salter, s.Auth); err != nil {
				return err
			}
		}

		data, err := HashStructure(s.Data, fn)
		if err != nil {
			return err
		}

		s.Data = data.(map[string]interface{})
	}

	return nil
}

// HashStructure takes an interface and hashes all the values within
// the structure. Only _values_ are hashed: keys of objects are not.
//
// For the HashCallback, see the built-in HashCallbacks below.
func HashStructure(s interface{}, cb HashCallback) (interface{}, error) {
	s, err := copystructure.Copy(s)
	if err != nil {
		return nil, err
	}

	walker := &hashWalker{Callback: cb}
	if err := reflectwalk.Walk(s, walker); err != nil {
		return nil, err
	}

	return s, nil
}

// HashCallback is the callback called for HashStructure to hash
// a value.
type HashCallback func(string) string

// hashWalker implements interfaces for the reflectwalk package
// (github.com/mitchellh/reflectwalk) that can be used to automatically
// replace primitives with a hashed value.
type hashWalker struct {
	// Callback is the function to call with the primitive that is
	// to be hashed. If there is an error, walking will be halted
	// immediately and the error returned.
	Callback HashCallback

	key         []string
	lastValue   reflect.Value
	loc         reflectwalk.Location
	cs          []reflect.Value
	csKey       []reflect.Value
	csData      interface{}
	sliceIndex  int
	unknownKeys []string
}

func (w *hashWalker) Enter(loc reflectwalk.Location) error {
	w.loc = loc
	return nil
}

func (w *hashWalker) Exit(loc reflectwalk.Location) error {
	w.loc = reflectwalk.None

	switch loc {
	case reflectwalk.Map:
		w.cs = w.cs[:len(w.cs)-1]
	case reflectwalk.MapValue:
		w.key = w.key[:len(w.key)-1]
		w.csKey = w.csKey[:len(w.csKey)-1]
	case reflectwalk.Slice:
		w.cs = w.cs[:len(w.cs)-1]
	case reflectwalk.SliceElem:
		w.csKey = w.csKey[:len(w.csKey)-1]
	}

	return nil
}

func (w *hashWalker) Map(m reflect.Value) error {
	w.cs = append(w.cs, m)
	return nil
}

func (w *hashWalker) MapElem(m, k, v reflect.Value) error {
	w.csData = k
	w.csKey = append(w.csKey, k)
	w.key = append(w.key, k.String())
	w.lastValue = v
	return nil
}

func (w *hashWalker) Slice(s reflect.Value) error {
	w.cs = append(w.cs, s)
	return nil
}

func (w *hashWalker) SliceElem(i int, elem reflect.Value) error {
	w.csKey = append(w.csKey, reflect.ValueOf(i))
	w.sliceIndex = i
	return nil
}

func (w *hashWalker) Primitive(v reflect.Value) error {
	if w.Callback == nil {
		return nil
	}

	// We don't touch map keys
	if w.loc == reflectwalk.MapKey {
		return nil
	}

	setV := v

	// We only care about strings
	if v.Kind() == reflect.Interface {
		setV = v
		v = v.Elem()
	}
	if v.Kind() != reflect.String {
		return nil
	}

	replaceVal := w.Callback(v.String())

	resultVal := reflect.ValueOf(replaceVal)
	switch w.loc {
	case reflectwalk.MapKey:
		m := w.cs[len(w.cs)-1]

		// Delete the old value
		var zero reflect.Value
		m.SetMapIndex(w.csData.(reflect.Value), zero)

		// Set the new key with the existing value
		m.SetMapIndex(resultVal, w.lastValue)

		// Set the key to be the new key
		w.csData = resultVal
	case reflectwalk.MapValue:
		// If we're in a map, then the only way to set a map value is
		// to set it directly.
		m := w.cs[len(w.cs)-1]
		mk := w.csData.(reflect.Value)
		m.SetMapIndex(mk, resultVal)
	default:
		// Otherwise, we should be addressable
		setV.Set(resultVal)
	}

	return nil
}

func (w *hashWalker) removeCurrent() {
	// Append the key to the unknown keys
	w.unknownKeys = append(w.unknownKeys, strings.Join(w.key, "."))

	for i := 1; i <= len(w.cs); i++ {
		c := w.cs[len(w.cs)-i]
		switch c.Kind() {
		case reflect.Map:
			// Zero value so that we delete the map key
			var val reflect.Value

			// Get the key and delete it
			k := w.csData.(reflect.Value)
			c.SetMapIndex(k, val)
			return
		}
	}

	panic("No container found for removeCurrent")
}

func (w *hashWalker) replaceCurrent(v reflect.Value) {
	c := w.cs[len(w.cs)-2]
	switch c.Kind() {
	case reflect.Map:
		// Get the key and delete it
		k := w.csKey[len(w.csKey)-1]
		c.SetMapIndex(k, v)
	}
}
<|endoftext|>


<commit_before>package microsoft

import "github.com/st3v/translator"

type api struct {
	router              Router
	languageCatalog     LanguageCatalog
	translationProvider TranslationProvider
}

// NewTranslator returns a struct that implements the Translator
// interface by exposing a Translate and a Languages function that
// are backed by Microsoft's translation API.
// The function takes the clientID and clientSecret for an existing
// app registered in Microsoft's Azure DataMarket.
func NewTranslator(clientID, clientSecret string) translator.Translator {
	authenticator := newAuthenticator(clientID, clientSecret)
	return &api{
		languageCatalog:     newLanguageCatalog(newLanguageProvider(authenticator)),
		translationProvider: newTranslationProvider(authenticator),
	}
}

func (a *api) Translate(text, from, to string) (string, error) {
	return a.translationProvider.Translate(text, from, to)
}

func (a *api) Languages() ([]translator.Language, error) {
	return a.languageCatalog.Languages()
}
<commit_msg>Refactor Api<commit_after>package microsoft

import (
	"github.com/st3v/translator"
	"github.com/st3v/translator/microsoft/auth"
)

type api struct {
	languageCatalog     LanguageCatalog
	translationProvider TranslationProvider
}

// NewTranslator returns a struct that implements the Translator
// interface by exposing a Translate and a Languages function that
// are backed by Microsoft's translation API.
// The function takes the clientID and clientSecret for an existing
// app registered in Microsoft's Azure DataMarket.
func NewTranslator(clientID, clientSecret string) translator.Translator {
	scope := "http://api.microsofttranslator.com"
	router := newRouter()
	authenticator := auth.NewAuthenticator(clientID, clientSecret, scope, router.AuthURL())
	return &api{
		languageCatalog:     newLanguageCatalog(newLanguageProvider(authenticator, router)),
		translationProvider: newTranslationProvider(authenticator, router),
	}
}

func (a *api) Translate(text, from, to string) (string, error) {
	return a.translationProvider.Translate(text, from, to)
}

func (a *api) Languages() ([]translator.Language, error) {
	return a.languageCatalog.Languages()
}
<|endoftext|>


<commit_before>package hwaflib

func (ctx *Context) Version() string {
	version := "20130930"
	return version
}

func (ctx *Context) Revision() string {
	revision := "dac0f9e"
	return revision
}

// EOF

<commit_msg>version: 20131002<commit_after>package hwaflib

func (ctx *Context) Version() string {
	version := "20131002"
	return version
}

func (ctx *Context) Revision() string {
	revision := "ae0fcdb"
	return revision
}

// EOF

<|endoftext|>


<commit_before>package docker

//TODO monitor event and update data
import (
	"sort"
	"strings"

	docker "github.com/fsouza/go-dockerclient"
	"github.com/sapk/sca/pkg"
	log "github.com/sirupsen/logrus"
)

const id = "Docker"

//Module retrieve information form executing sca
type Module struct {
	Endpoint string
	Client   *docker.Client
}

//Response describe docker informations
type Response struct {
	Info       *docker.DockerInfo     `json:"Info,omitempty"`
	Containers []docker.APIContainers `json:"Containers,omitempty"`
	Images     []docker.APIImages     `json:"Images,omitempty"`
	Volumes    []docker.Volume        `json:"Volumes,omitempty"`
	Networks   []docker.Network       `json:"Networks,omitempty"`
}

//New constructor for Module
func New(options map[string]string) *Module {
	log.WithFields(log.Fields{
		"id":      id,
		"options": options,
	}).Debug("Creating new Module")

	client, err := docker.NewClient(options["docker.endpoint"])
	if err != nil {
		log.WithFields(log.Fields{
			"client": client,
			"err":    err,
		}).Warn("Failed to create docker client")
		//return nil
	}
	return &Module{Endpoint: options["docker.endpoint"], Client: client}
}

//ID //TODO
func (d *Module) ID() string {
	return id
}

//GetData //TODO
func (d *Module) GetData() interface{} {

	return Response{
		Info:       d.getInfo(),
		Containers: d.getContainers(),
		Networks:   d.getNetworks(),
		Volumes:    d.getVolumes(),
		Images:     d.getImages(),
	}
}
func (d *Module) getInfo() *docker.DockerInfo {
	//Get server info
	info, err := d.Client.Info()
	if err != nil {
		log.WithFields(log.Fields{
			"err":    err,
			"info":   info,
			"client": d.Client,
		}).Warn("Failed to get docker host info")
		return nil
	}
	//Clean of . in key info.RegistryConfig.IndexConfigs
	tmp := make(map[string]*docker.IndexInfo, len(info.RegistryConfig.IndexConfigs))
	for id, conf := range info.RegistryConfig.IndexConfigs {
		tmp[strings.Replace(id, ".", "-", -1)] = conf
	}
	info.RegistryConfig.IndexConfigs = tmp

	//Sort Docker/Info/Swarm/RemoteManagers/X to ease optimisation on sync
	sort.Sort(pkg.ByPeer(info.Swarm.RemoteManagers))
	return info
}

func (d *Module) getImages() []docker.APIImages {
	//Get images
	imgs, err := d.Client.ListImages(docker.ListImagesOptions{All: true})
	if err != nil {
		panic(err)
	}
	for id, i := range imgs {
		if len(i.Labels) > 0 { //Reconstruct map without . in key
			tmp := make(map[string]string, len(i.Labels))
			for iid, val := range i.Labels {
				tmp[strings.Replace(iid, ".", "-", -1)] = val
			}
			imgs[id].Labels = tmp
		}
	}
	sort.Sort(pkg.ByIID(imgs))
	return imgs
}

func (d *Module) getNetworks() []docker.Network {
	//Get networks
	nets, err := d.Client.ListNetworks()
	if err != nil {
		log.WithFields(log.Fields{
			"err":    err,
			"nets":   nets,
			"client": d.Client,
		}).Warn("Failed to get docker network list")
		return nil
	}
	//Clean . in key of options
	for id, n := range nets {
		if len(n.Options) > 0 { //Reconstruct map without . in key
			tmp := make(map[string]string, len(n.Options))
			for oid, opt := range n.Options {
				tmp[strings.Replace(oid, ".", "-", -1)] = opt
			}
			nets[id].Options = tmp
		}
		if len(n.Labels) > 0 { //Reconstruct map without . in key
			tmp := make(map[string]string, len(n.Labels))
			for lid, val := range n.Labels {
				tmp[strings.Replace(lid, ".", "-", -1)] = val
			}
			nets[id].Labels = tmp
		}
	}
	sort.Sort(pkg.ByNID(nets))
	return nets
}

func (d *Module) getContainers() []docker.APIContainers {
	//Get container
	cnts, err := d.Client.ListContainers(docker.ListContainersOptions{All: true})
	if err != nil {
		log.WithFields(log.Fields{
			"err":    err,
			"cnts":   cnts,
			"client": d.Client,
		}).Warn("Failed to get docker container list")
		return nil
	}
	for id, c := range cnts {
		if len(c.Labels) > 0 { //Reconstruct map without . in key
			tmp := make(map[string]string, len(c.Labels))
			for vid, val := range c.Labels {
				tmp[strings.Replace(vid, ".", "-", -1)] = val
			}
			cnts[id].Labels = tmp
		}
		//Sort Docker/Containers/X/Mounts/X to ease optimisation on sync
		sort.Sort(pkg.ByMount(c.Mounts))
		//Sort Docker/Containers/X/Ports/X to ease optimisation on sync
		sort.Sort(pkg.ByPort(c.Ports))
	}
	sort.Sort(pkg.ByCID(cnts))
	return cnts
}

func (d *Module) getVolumes() []docker.Volume {
	//Get volumes
	vols, err := d.Client.ListVolumes(docker.ListVolumesOptions{})
	if err != nil {
		log.WithFields(log.Fields{
			"err":    err,
			"vols":   vols,
			"client": d.Client,
		}).Warn("Failed to get docker volume list")
		return nil
	}
	sort.Sort(pkg.ByVName(vols))
	return vols
}
<commit_msg>Apply sort to simplify sync opti<commit_after>package docker

//TODO monitor event and update data
import (
	"sort"
	"strings"

	docker "github.com/fsouza/go-dockerclient"
	"github.com/sapk/sca/pkg"
	log "github.com/sirupsen/logrus"
)

const id = "Docker"

//Module retrieve information form executing sca
type Module struct {
	Endpoint string
	Client   *docker.Client
}

//Response describe docker informations
type Response struct {
	Info       *docker.DockerInfo     `json:"Info,omitempty"`
	Containers []docker.APIContainers `json:"Containers,omitempty"`
	Images     []docker.APIImages     `json:"Images,omitempty"`
	Volumes    []docker.Volume        `json:"Volumes,omitempty"`
	Networks   []docker.Network       `json:"Networks,omitempty"`
}

//New constructor for Module
func New(options map[string]string) *Module {
	log.WithFields(log.Fields{
		"id":      id,
		"options": options,
	}).Debug("Creating new Module")

	client, err := docker.NewClient(options["docker.endpoint"])
	if err != nil {
		log.WithFields(log.Fields{
			"client": client,
			"err":    err,
		}).Warn("Failed to create docker client")
		//return nil
	}
	return &Module{Endpoint: options["docker.endpoint"], Client: client}
}

//ID //TODO
func (d *Module) ID() string {
	return id
}

//GetData //TODO
func (d *Module) GetData() interface{} {

	return Response{
		Info:       d.getInfo(),
		Containers: d.getContainers(),
		Networks:   d.getNetworks(),
		Volumes:    d.getVolumes(),
		Images:     d.getImages(),
	}
}
func (d *Module) getInfo() *docker.DockerInfo {
	//Get server info
	info, err := d.Client.Info()
	if err != nil {
		log.WithFields(log.Fields{
			"err":    err,
			"info":   info,
			"client": d.Client,
		}).Warn("Failed to get docker host info")
		return nil
	}
	//Clean of . in key info.RegistryConfig.IndexConfigs
	tmp := make(map[string]*docker.IndexInfo, len(info.RegistryConfig.IndexConfigs))
	for id, conf := range info.RegistryConfig.IndexConfigs {
		tmp[strings.Replace(id, ".", "-", -1)] = conf
	}
	info.RegistryConfig.IndexConfigs = tmp

	//Sort Docker/Info/Swarm/RemoteManagers/X to ease optimisation on sync
	sort.Sort(pkg.ByPeer(info.Swarm.RemoteManagers))
	sort.Strings(info.Plugins.Network)
	sort.Strings(info.Plugins.Volume)
	return info
}

func (d *Module) getImages() []docker.APIImages {
	//Get images
	imgs, err := d.Client.ListImages(docker.ListImagesOptions{All: true})
	if err != nil {
		panic(err)
	}
	for id, i := range imgs {
		if len(i.Labels) > 0 { //Reconstruct map without . in key
			tmp := make(map[string]string, len(i.Labels))
			for iid, val := range i.Labels {
				tmp[strings.Replace(iid, ".", "-", -1)] = val
			}
			imgs[id].Labels = tmp
		}
	}
	sort.Sort(pkg.ByIID(imgs))
	return imgs
}

func (d *Module) getNetworks() []docker.Network {
	//Get networks
	nets, err := d.Client.ListNetworks()
	if err != nil {
		log.WithFields(log.Fields{
			"err":    err,
			"nets":   nets,
			"client": d.Client,
		}).Warn("Failed to get docker network list")
		return nil
	}
	//Clean . in key of options
	for id, n := range nets {
		if len(n.Options) > 0 { //Reconstruct map without . in key
			tmp := make(map[string]string, len(n.Options))
			for oid, opt := range n.Options {
				tmp[strings.Replace(oid, ".", "-", -1)] = opt
			}
			nets[id].Options = tmp
		}
		if len(n.Labels) > 0 { //Reconstruct map without . in key
			tmp := make(map[string]string, len(n.Labels))
			for lid, val := range n.Labels {
				tmp[strings.Replace(lid, ".", "-", -1)] = val
			}
			nets[id].Labels = tmp
		}
	}
	sort.Sort(pkg.ByNID(nets))
	return nets
}

func (d *Module) getContainers() []docker.APIContainers {
	//Get container
	cnts, err := d.Client.ListContainers(docker.ListContainersOptions{All: true})
	if err != nil {
		log.WithFields(log.Fields{
			"err":    err,
			"cnts":   cnts,
			"client": d.Client,
		}).Warn("Failed to get docker container list")
		return nil
	}
	for id, c := range cnts {
		if len(c.Labels) > 0 { //Reconstruct map without . in key
			tmp := make(map[string]string, len(c.Labels))
			for vid, val := range c.Labels {
				tmp[strings.Replace(vid, ".", "-", -1)] = val
			}
			cnts[id].Labels = tmp
		}
		//Sort Docker/Containers/X/Mounts/X to ease optimisation on sync
		sort.Sort(pkg.ByMount(c.Mounts))
		//Sort Docker/Containers/X/Ports/X to ease optimisation on sync
		sort.Sort(pkg.ByPort(c.Ports))
	}
	sort.Sort(pkg.ByCID(cnts))
	return cnts
}

func (d *Module) getVolumes() []docker.Volume {
	//Get volumes
	vols, err := d.Client.ListVolumes(docker.ListVolumesOptions{})
	if err != nil {
		log.WithFields(log.Fields{
			"err":    err,
			"vols":   vols,
			"client": d.Client,
		}).Warn("Failed to get docker volume list")
		return nil
	}
	sort.Sort(pkg.ByVName(vols))
	return vols
}
<|endoftext|>


<commit_before>// Copyright 2022 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build lockdep
// +build lockdep

package locking

import (
	"fmt"
	"reflect"
	"strings"

	"gvisor.dev/gvisor/pkg/goid"
	"gvisor.dev/gvisor/pkg/log"
)

var classMap classAtomicPtrMap

// NewMutexClass allocates a new mutex class.
func NewMutexClass(t reflect.Type) *MutexClass {
	c := &MutexClass{}
	classMap.Store(c, &t)
	return c
}

// MutexClass describes dependencies of a specific class.
type MutexClass struct {
	// ancestors are locks that are locked before the current class.
	ancestors ancestorsAtomicPtrMap
	// subclasses is the list of sub-classes that are used to handle nested locks.
	subclasses subclassAtomicPtrMap
}

type goroutineLocks map[*MutexClass]bool

var routineLocks goroutineLocksAtomicPtrMap

// checkLock checks that class isn't in ancestors of prevClass.
func checkLock(class *MutexClass, prevClass *MutexClass, chain []*MutexClass) {
	chain = append(chain, prevClass)
	if c := prevClass.ancestors.Load(class); c != nil {
		var b strings.Builder
		fmt.Fprintf(&b, "WARNING: circular locking detected: %s -> %s:\n%s\n",
			*classMap.Load(chain[0]), *classMap.Load(class), log.Stacks(false))

		fmt.Fprintf(&b, "known lock chain: ")
		c := class
		for i := len(chain) - 1; i >= 0; i-- {
			fmt.Fprintf(&b, "%s -> ", *classMap.Load(c))
			c = chain[i]
		}
		fmt.Fprintf(&b, "%s\n", *classMap.Load(chain[0]))
		c = class
		for i := len(chain) - 1; i >= 0; i-- {
			fmt.Fprintf(&b, "\n====== %s -> %s =====\n%s",
				*classMap.Load(c), *classMap.Load(chain[i]), *chain[i].ancestors.Load(c))
			c = chain[i]
		}
		panic(b.String())
	}
	prevClass.ancestors.Range(func(parentClass *MutexClass, stacks *string) bool {
		// The recursion is fine here. If it fails, you need to reduce
		// a number of nested locks.
		checkLock(class, parentClass, chain)
		return true
	})
}

// AddGLock records a lock to the current goroutine and updates dependences.
func AddGLock(class *MutexClass, subclass uint32) {
	gid := goid.Get()

	if subclass != 0 {
		var c *MutexClass
		if c = class.subclasses.Load(subclass); c == nil {
			t := classMap.Load(class)
			c = NewMutexClass(*t)
			class.subclasses.Store(subclass, c)
		}
		class = c
	}
	currentLocks := routineLocks.Load(gid)
	if currentLocks == nil {
		locks := goroutineLocks(make(map[*MutexClass]bool))
		locks[class] = true
		routineLocks.Store(gid, &locks)
		return
	}

	// Check dependencies and add locked mutexes to the ancestors list.
	for prevClass := range *currentLocks {
		if prevClass == class {
			panic(fmt.Sprintf("nested locking: %s:\n%s", *classMap.Load(class), log.Stacks(false)))
		}
		checkLock(class, prevClass, nil)

		if c := class.ancestors.Load(prevClass); c == nil {
			stacks := string(log.Stacks(false))
			class.ancestors.Store(prevClass, &stacks)
		}
	}
	(*currentLocks)[class] = true

}

// DelGLock deletes a lock from the current goroutine.
func DelGLock(class *MutexClass, subclass uint32) {
	if subclass != 0 {
		class = class.subclasses.Load(subclass)
	}
	gid := goid.Get()
	currentLocks := routineLocks.Load(gid)
	if currentLocks == nil {
		panic("the current goroutine doesn't have locks")
	}
	if _, ok := (*currentLocks)[class]; !ok {
		panic("unlock of an unknow lock")
	}

	delete(*currentLocks, class)
	if len(*currentLocks) == 0 {
		routineLocks.Store(gid, nil)
	}
}
<commit_msg>sync/lockdep: use RangeRepeatable instead of Range<commit_after>// Copyright 2022 The gVisor Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//go:build lockdep
// +build lockdep

package locking

import (
	"fmt"
	"reflect"
	"strings"

	"gvisor.dev/gvisor/pkg/goid"
	"gvisor.dev/gvisor/pkg/log"
)

var classMap classAtomicPtrMap

// NewMutexClass allocates a new mutex class.
func NewMutexClass(t reflect.Type) *MutexClass {
	c := &MutexClass{}
	classMap.Store(c, &t)
	return c
}

// MutexClass describes dependencies of a specific class.
type MutexClass struct {
	// ancestors are locks that are locked before the current class.
	ancestors ancestorsAtomicPtrMap
	// subclasses is the list of sub-classes that are used to handle nested locks.
	subclasses subclassAtomicPtrMap
}

type goroutineLocks map[*MutexClass]bool

var routineLocks goroutineLocksAtomicPtrMap

// checkLock checks that class isn't in ancestors of prevClass.
func checkLock(class *MutexClass, prevClass *MutexClass, chain []*MutexClass) {
	chain = append(chain, prevClass)
	if c := prevClass.ancestors.Load(class); c != nil {
		var b strings.Builder
		fmt.Fprintf(&b, "WARNING: circular locking detected: %s -> %s:\n%s\n",
			*classMap.Load(chain[0]), *classMap.Load(class), log.Stacks(false))

		fmt.Fprintf(&b, "known lock chain: ")
		c := class
		for i := len(chain) - 1; i >= 0; i-- {
			fmt.Fprintf(&b, "%s -> ", *classMap.Load(c))
			c = chain[i]
		}
		fmt.Fprintf(&b, "%s\n", *classMap.Load(chain[0]))
		c = class
		for i := len(chain) - 1; i >= 0; i-- {
			fmt.Fprintf(&b, "\n====== %s -> %s =====\n%s",
				*classMap.Load(c), *classMap.Load(chain[i]), *chain[i].ancestors.Load(c))
			c = chain[i]
		}
		panic(b.String())
	}
	prevClass.ancestors.RangeRepeatable(func(parentClass *MutexClass, stacks *string) bool {
		// The recursion is fine here. If it fails, you need to reduce
		// a number of nested locks.
		checkLock(class, parentClass, chain)
		return true
	})
}

// AddGLock records a lock to the current goroutine and updates dependences.
func AddGLock(class *MutexClass, subclass uint32) {
	gid := goid.Get()

	if subclass != 0 {
		var c *MutexClass
		if c = class.subclasses.Load(subclass); c == nil {
			t := classMap.Load(class)
			c = NewMutexClass(*t)
			class.subclasses.Store(subclass, c)
		}
		class = c
	}
	currentLocks := routineLocks.Load(gid)
	if currentLocks == nil {
		locks := goroutineLocks(make(map[*MutexClass]bool))
		locks[class] = true
		routineLocks.Store(gid, &locks)
		return
	}

	// Check dependencies and add locked mutexes to the ancestors list.
	for prevClass := range *currentLocks {
		if prevClass == class {
			panic(fmt.Sprintf("nested locking: %s:\n%s", *classMap.Load(class), log.Stacks(false)))
		}
		checkLock(class, prevClass, nil)

		if c := class.ancestors.Load(prevClass); c == nil {
			stacks := string(log.Stacks(false))
			class.ancestors.Store(prevClass, &stacks)
		}
	}
	(*currentLocks)[class] = true

}

// DelGLock deletes a lock from the current goroutine.
func DelGLock(class *MutexClass, subclass uint32) {
	if subclass != 0 {
		class = class.subclasses.Load(subclass)
	}
	gid := goid.Get()
	currentLocks := routineLocks.Load(gid)
	if currentLocks == nil {
		panic("the current goroutine doesn't have locks")
	}
	if _, ok := (*currentLocks)[class]; !ok {
		panic("unlock of an unknow lock")
	}

	delete(*currentLocks, class)
	if len(*currentLocks) == 0 {
		routineLocks.Store(gid, nil)
	}
}
<|endoftext|>


<commit_before>package middleware

import (
	"github.com/drone/drone/model"

	"github.com/gin-gonic/gin"
	"github.com/urfave/cli"
)

const configKey = "config"

// Config is a middleware function that initializes the Configuration and
// attaches to the context of every http.Request.
func Config(cli *cli.Context) gin.HandlerFunc {
	v := setupConfig(cli)
	return func(c *gin.Context) {
		c.Set(configKey, v)
	}
}

// helper function to create the configuration from the CLI context.
func setupConfig(c *cli.Context) *model.Settings {
	return &model.Settings{
		Open:   c.Bool("open"),
		Secret: c.String("agent-secret"),
		Admins: sliceToMap2(c.StringSlice("admin")),
		Orgs:   sliceToMap2(c.StringSlice("orgs")),
	}
}

// helper function to convert a string slice to a map.
func sliceToMap2(s []string) map[string]bool {
	v := map[string]bool{}
	for _, ss := range s {
		v[ss] = true
	}
	return v
}
<commit_msg>ignore empty orgs value<commit_after>package middleware

import (
	"github.com/drone/drone/model"

	"github.com/gin-gonic/gin"
	"github.com/urfave/cli"
)

const configKey = "config"

// Config is a middleware function that initializes the Configuration and
// attaches to the context of every http.Request.
func Config(cli *cli.Context) gin.HandlerFunc {
	v := setupConfig(cli)
	return func(c *gin.Context) {
		c.Set(configKey, v)
	}
}

// helper function to create the configuration from the CLI context.
func setupConfig(c *cli.Context) *model.Settings {
	return &model.Settings{
		Open:   c.Bool("open"),
		Secret: c.String("agent-secret"),
		Admins: sliceToMap2(c.StringSlice("admin")),
		Orgs:   sliceToMap2(c.StringSlice("orgs")),
	}
}

// helper function to convert a string slice to a map.
func sliceToMap2(s []string) map[string]bool {
	v := map[string]bool{}
	for _, ss := range s {
		if ss == "" {
			continue
		}
		v[ss] = true
	}
	return v
}
<|endoftext|>


<commit_before>package unit

import (
	"github.com/WindomZ/go-macro/json"
	"testing"
)

func TestNewCurrency(t *testing.T) {
	SetCurrencyMappingPair("$", "USD")
	SetCurrencyMappingPair("RMB", "CNY")
	SetCurrencyMapping("rmb", "CNY")
	SetCurrencyUnMapping("FRC", "frc")
}

func TestSetCurrencyMappingFunc(t *testing.T) {
	SetCurrencyMappingFunc(func(s string) string {
		switch s {
		case "AAA":
			return "bbb"
		}
		return s
	})
	SetCurrencyUnMappingFunc(func(s string) string {
		switch s {
		case "bbb":
			return "AAA"
		}
		return s
	})
	if CurrencyMapping("AAA") != "bbb" {
		t.Fatal("Error SetCurrencyMappingFunc")
	} else if CurrencyUnMapping("bbb") != "AAA" {
		t.Fatal("Error SetCurrencyUnMappingFunc")
	}
}

func TestCurrencyMapping(t *testing.T) {
	if CurrencyMapping("$") != "USD" {
		t.Fatal("Error CurrencyMapping")
	} else if CurrencyMapping("RMB") != "CNY" {
		t.Fatal("Error CurrencyMapping")
	}
}

func TestCurrencyUnMapping(t *testing.T) {
	if CurrencyUnMapping("USD") != "$" {
		t.Fatal("Error CurrencyUnMapping")
	} else if CurrencyUnMapping("CNY") != "RMB" {
		t.Fatal("Error CurrencyUnMapping")
	}
}

type testCurrency struct {
	C1 Currency `json:"c1"`
	C2 Currency `json:"c2"`
	C3 Currency `json:"c3"`
	C4 Currency `json:"c4"`
	C5 Currency `json:"c5"`
}

func TestCurrencyJSON(t *testing.T) {
	c := &testCurrency{
		C1: NewCurrency("rmb"),
		C2: NewCurrency("RMB"),
		C3: NewCurrency("$"),
		C4: NewCurrency("USD"),
		C5: NewCurrency("FRC"),
	}
	data, err := gojson.Marshal(c)
	if err != nil {
		t.Fatal(err)
	}
	c = new(testCurrency)
	if err := gojson.Unmarshal(data, &c); err != nil {
		t.Fatal(err)
	}
	if c.C1.String() != "CNY" {
		t.Fatal("Error C1:", c.C1.String())
	} else if c.C2.String() != "CNY" {
		t.Fatal("Error C2:", c.C2.String())
	} else if c.C3.String() != "USD" {
		t.Fatal("Error C3:", c.C3.String())
	} else if c.C4.String() != "USD" {
		t.Fatal("Error C4:", c.C4.String())
	} else if c.C5.String() != "frc" {
		t.Fatal("Error C5:", c.C5.String())
	}
	var m map[string]string
	if err := gojson.Unmarshal(data, &m); err != nil {
		t.Fatal(err)
	}
	for _, v := range m {
		switch v {
		case "rmb":
		case "RMB":
		case "$":
		case "frc":
		default:
			t.Fatal("Error Map:", v)
		}
	}
}
<commit_msg>test: unit currency<commit_after>package unit

import (
	"github.com/WindomZ/go-macro/json"
	"testing"
)

func TestNewCurrency(t *testing.T) {
	SetCurrencyMappingPair("$", "USD")
	SetCurrencyMappingPair("RMB", "CNY")
	SetCurrencyMapping("rmb", "CNY")
	SetCurrencyUnMapping("FRC", "frc")
}

func TestSetCurrencyMappingFunc(t *testing.T) {
	SetCurrencyMappingFunc(func(s string) string {
		switch s {
		case "AAA":
			return "bbb"
		}
		return s
	})
	SetCurrencyUnMappingFunc(func(s string) string {
		switch s {
		case "bbb":
			return "AAA"
		}
		return s
	})
	if CurrencyMapping("AAA") != "bbb" {
		t.Fatal("Error SetCurrencyMappingFunc")
	} else if CurrencyUnMapping("bbb") != "AAA" {
		t.Fatal("Error SetCurrencyUnMappingFunc")
	}
}

func TestCurrencyMapping(t *testing.T) {
	if CurrencyMapping("$") != "USD" {
		t.Fatal("Error CurrencyMapping")
	} else if CurrencyMapping("RMB") != "CNY" {
		t.Fatal("Error CurrencyMapping")
	}
}

func TestCurrencyUnMapping(t *testing.T) {
	if CurrencyUnMapping("USD") != "$" {
		t.Fatal("Error CurrencyUnMapping")
	} else if CurrencyUnMapping("CNY") != "RMB" {
		t.Fatal("Error CurrencyUnMapping")
	}
}

type testCurrency struct {
	C1   Currency              `json:"c1"`
	C2   Currency              `json:"c2"`
	C3   Currency              `json:"c3"`
	C4   Currency              `json:"c4"`
	C5   Currency              `json:"c5"`
	CMAP map[Currency]Currency `json:"cmap"`
	CARR []Currency            `json:"carr"`
}

func TestCurrencyJSON(t *testing.T) {
	c := &testCurrency{
		C1:   NewCurrency("rmb"),
		C2:   NewCurrency("RMB"),
		C3:   NewCurrency("$"),
		C4:   NewCurrency("USD"),
		C5:   NewCurrency("FRC"),
		CMAP: make(map[Currency]Currency),
		CARR: make([]Currency, 3),
	}
	c.CMAP[c.C1] = c.C1
	c.CMAP[c.C3] = c.C3
	c.CMAP[c.C5] = c.C5
	c.CARR[0] = c.C1
	c.CARR[1] = c.C2
	c.CARR[2] = c.C3
	data, err := gojson.Marshal(c)
	if err != nil {
		t.Fatal(err)
	}
	//t.Log(string(data))
	c = new(testCurrency)
	if err := gojson.Unmarshal(data, &c); err != nil {
		t.Fatal(err)
	}
	if c.C1.String() != "CNY" {
		t.Fatal("Error C1:", c.C1.String())
	} else if c.C2.String() != "CNY" {
		t.Fatal("Error C2:", c.C2.String())
	} else if c.C3.String() != "USD" {
		t.Fatal("Error C3:", c.C3.String())
	} else if c.C4.String() != "USD" {
		t.Fatal("Error C4:", c.C4.String())
	} else if c.C5.String() != "frc" {
		t.Fatal("Error C5:", c.C5.String())
	}
	for k, v := range c.CMAP {
		if !k.Equal(v) {
			t.Fatal("Error CMAP:", k, v)
		}
	}
	var m map[string]interface{}
	if err := gojson.Unmarshal(data, &m); err != nil {
		t.Fatal(err)
	}
	for k, v := range m {
		if k == "cmap" || k == "carr" {
			continue
		}
		switch v {
		case "rmb":
		case "RMB":
		case "$":
		case "frc":
		default:
			t.Fatal("Error:", v)
		}
	}
}
<|endoftext|>


<commit_before>package main

<commit_msg>Some preliminaries.<commit_after>package main

import (
	"fmt"
	"strings"
)

const (
	width  = 20
	height = 10
)

type direction int

const (
	up direction = iota + 1
	down
	left
	right
)

type Board struct {
	Cells [height][width]bool
}

type Piece interface {
	Initialize(*Board) bool
	Move(*Board, direction) bool
	Rotate(*Board, direction) bool
}

func (board *Board) Draw() {
	fmt.Println("+" + strings.Repeat("-", width) + "+")
	for _, row := range board.Cells {
		fmt.Printf("|")
		for _, cell := range row {
			if cell {
				fmt.Printf("#")
			} else {
				fmt.Printf(" ")
			}
		}
		fmt.Println("|")
	}
	fmt.Println("+" + strings.Repeat("-", width) + "+")
}

func main() {
	board := new(Board)
	board.Draw()
}
<|endoftext|>


<commit_before>// Package types is where exportable API structures go. This is so we can share
// the XML marshalling and unmarshalling with the services.
package types

import (
	"encoding/xml"
	"time"
)

type Version struct {
	XMLName xml.Name `xml:"version"`
	App     *App     `xml:"app"`
	Package *Package `xml:"package"`
}

type App struct {
	XMLName xml.Name  `xml:"app"`
	Id      string    `xml:"id,attr"`
	Version string    `xml:"version,attr"`
	Track   string    `xml:"track,attr"`
	Date    time.Time `xml:"-"`
}

type Package struct {
	XMLName              xml.Name `xml:"package"`
	Name                 string   `xml:"name,attr"`      // Package filename
	Size                 string   `xml:"size,attr"`      // Size of the file (in bytes)
	Path                 string   `xml:"path,attr"`      // Path from the root to the file
	Sha1Sum              string   `xml:"sha1sum,attr"`   // SHA-1 hash of the file
	Sha256Sum            string   `xml:"sha256sum,attr"` // Sha-256 hash of the file (extension)
	Required             bool     `xml:"required,attr"`
	MetadataSignatureRsa string   `xml:"MetadataSignatureRsa,attr,omitempty" json:"metadata_signature_rsa"`
	MetadataSize         string   `xml:"MetadataSize,attr,omitempty" json:"metadata_size"`
}
<commit_msg>feat(update/types): add IsActive to App<commit_after>// Package types is where exportable API structures go. This is so we can share
// the XML marshalling and unmarshalling with the services.
package types

import (
	"encoding/xml"
	"time"
)

type Version struct {
	XMLName xml.Name `xml:"version"`
	App     *App     `xml:"app"`
	Package *Package `xml:"package"`
}

type App struct {
	XMLName  xml.Name  `xml:"app"`
	Id       string    `xml:"id,attr"`
	Version  string    `xml:"version,attr"`
	Track    string    `xml:"track,attr"`
	Date     time.Time `xml:"-"`
	IsActive time.Time `xml:"-"`
}

type Package struct {
	XMLName              xml.Name `xml:"package"`
	Name                 string   `xml:"name,attr"`      // Package filename
	Size                 string   `xml:"size,attr"`      // Size of the file (in bytes)
	Path                 string   `xml:"path,attr"`      // Path from the root to the file
	Sha1Sum              string   `xml:"sha1sum,attr"`   // SHA-1 hash of the file
	Sha256Sum            string   `xml:"sha256sum,attr"` // Sha-256 hash of the file (extension)
	Required             bool     `xml:"required,attr"`
	MetadataSignatureRsa string   `xml:"MetadataSignatureRsa,attr,omitempty" json:"metadata_signature_rsa"`
	MetadataSize         string   `xml:"MetadataSize,attr,omitempty" json:"metadata_size"`
}
<|endoftext|>


<commit_before>package fi

import (
	"encoding/json"
	"fmt"
	"reflect"
)

func StringValue(s *string) string {
	if s == nil {
		return ""
	}
	return *s
}

func String(s string) *string {
	return &s
}

func Bool(v bool) *bool {
	return &v
}

func BoolValue(v *bool) bool {
	if v == nil {
		return false
	}
	return *v
}

func Int(v int) *int {
	return &v
}

func Int64(v int64) *int64 {
	return &v
}

func DebugPrint(o interface{}) string {
	if o == nil {
		return "<nil>"
	}
	if rh, ok := o.(*ResourceHolder); ok {
		if rh.Resource == nil {
			return fmt.Sprintf("unknown resource %q", rh.Name)
		}
	}
	if resource, ok := o.(Resource); ok {
		s, err := ResourceAsString(resource)
		if err != nil {
			return fmt.Sprintf("error converting resource to string: %v", err)
		}
		if len(s) >= 256 {
			s = s[:256] + "... (truncated)"
		}
		return s
	}

	v := reflect.ValueOf(o)
	if v.Kind() == reflect.Ptr {
		if v.IsNil() {
			return "<nil>"
		}
		v = v.Elem()
	}
	if !v.IsValid() {
		return "<?>"
	}
	o = v.Interface()
	if stringer, ok := o.(fmt.Stringer); ok {
		return stringer.String()
	}

	return fmt.Sprint(o)
}

func DebugAsJsonString(v interface{}) string {
	data, err := json.Marshal(v)
	if err != nil {
		return fmt.Sprintf("error marshalling: %v", err)
	}
	return string(data)
}

func DebugAsJsonStringIndent(v interface{}) string {
	data, err := json.MarshalIndent(v, "", "  ")
	if err != nil {
		return fmt.Sprintf("error marshalling: %v", err)
	}
	return string(data)
}
<commit_msg>Avoid segfault on nil ResourceHolder<commit_after>package fi

import (
	"encoding/json"
	"fmt"
	"reflect"
)

func StringValue(s *string) string {
	if s == nil {
		return ""
	}
	return *s
}

func String(s string) *string {
	return &s
}

func Bool(v bool) *bool {
	return &v
}

func BoolValue(v *bool) bool {
	if v == nil {
		return false
	}
	return *v
}

func Int(v int) *int {
	return &v
}

func Int64(v int64) *int64 {
	return &v
}

func DebugPrint(o interface{}) string {
	if o == nil {
		return "<nil>"
	}
	if rh, ok := o.(*ResourceHolder); ok {
		if rh == nil || rh.Resource == nil {
			return fmt.Sprintf("unknown resource %q", rh.Name)
		}
	}
	if resource, ok := o.(Resource); ok {
		s, err := ResourceAsString(resource)
		if err != nil {
			return fmt.Sprintf("error converting resource to string: %v", err)
		}
		if len(s) >= 256 {
			s = s[:256] + "... (truncated)"
		}
		return s
	}

	v := reflect.ValueOf(o)
	if v.Kind() == reflect.Ptr {
		if v.IsNil() {
			return "<nil>"
		}
		v = v.Elem()
	}
	if !v.IsValid() {
		return "<?>"
	}
	o = v.Interface()
	if stringer, ok := o.(fmt.Stringer); ok {
		return stringer.String()
	}

	return fmt.Sprint(o)
}

func DebugAsJsonString(v interface{}) string {
	data, err := json.Marshal(v)
	if err != nil {
		return fmt.Sprintf("error marshalling: %v", err)
	}
	return string(data)
}

func DebugAsJsonStringIndent(v interface{}) string {
	data, err := json.MarshalIndent(v, "", "  ")
	if err != nil {
		return fmt.Sprintf("error marshalling: %v", err)
	}
	return string(data)
}
<|endoftext|>