<commit_before>package main

import (
	"flag"
	"io/ioutil"
	"log"
	"strconv"
	"time"

	"github.com/brotherlogic/goserver"
	"golang.org/x/net/context"
	"google.golang.org/grpc"

	pbd "github.com/brotherlogic/discovery/proto"
	pb "github.com/brotherlogic/gobuildmaster/proto"
	pbs "github.com/brotherlogic/gobuildslave/proto"
	pbg "github.com/brotherlogic/goserver/proto"
	"github.com/brotherlogic/goserver/utils"
)

const (
	intentWait = time.Second
)

// Server the main server type
type Server struct {
	*goserver.GoServer
	config  *pb.Config
	serving bool
}

type mainChecker struct {
	prev []string
}

func getIP(servertype, servername string) (string, int) {
	conn, _ := grpc.Dial(utils.RegistryIP+":"+strconv.Itoa(utils.RegistryPort), grpc.WithInsecure())
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	r, err := registry.ListAllServices(context.Background(), &pbd.Empty{})
	if err != nil {
		return "", -1
	}
	for _, s := range r.Services {
		if s.Name == servertype && s.Identifier == servername {
			return s.Ip, int(s.Port)
		}
	}

	return "", -1
}

func (t *mainChecker) getprev() []string {
	return t.prev
}
func (t *mainChecker) setprev(v []string) {
	t.prev = v
}

func (t *mainChecker) assess(server string) (*pbs.JobList, *pbs.Config) {
	list := &pbs.JobList{}
	conf := &pbs.Config{}

	ip, port := getIP("gobuildslave", server)
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	conn, err := grpc.DialContext(ctx, ip+":"+strconv.Itoa(port), grpc.WithInsecure())
	if err != nil {
		return list, conf
	}
	defer conn.Close()

	slave := pbs.NewGoBuildSlaveClient(conn)
	r, err := slave.List(context.Background(), &pbs.Empty{})
	if err != nil {
		return list, conf
	}

	r2, err := slave.GetConfig(context.Background(), &pbs.Empty{})
	if err != nil {
		return list, conf
	}

	return r, r2
}

func (t *mainChecker) master(entry *pbd.RegistryEntry) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	conn, _ := grpc.DialContext(ctx, entry.GetIp()+":"+strconv.Itoa(int(entry.GetPort())), grpc.WithInsecure())
	defer conn.Close()

	server := pbg.NewGoserverServiceClient(conn)
	log.Printf("SETTING MASTER: %v", entry)
	_, err := server.Mote(context.Background(), &pbg.MoteRequest{Master: entry.GetMaster()})
	if err != nil {
		log.Printf("RESPONSE: %v", err)
	}
}

func runJob(job *pbs.JobSpec, server string) {
	log.Printf("Run %v on %v", job.Name, server)
	if server != "" {
		ip, port := getIP("gobuildslave", server)
		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
		defer cancel()
		conn, _ := grpc.DialContext(ctx, ip+":"+strconv.Itoa(port), grpc.WithInsecure())
		defer conn.Close()

		slave := pbs.NewGoBuildSlaveClient(conn)
		job.Server = server
		slave.Run(context.Background(), job)
	}
}

func (t *mainChecker) discover() *pbd.ServiceList {
	ret := &pbd.ServiceList{}

	conn, _ := grpc.Dial(utils.RegistryIP+":"+strconv.Itoa(utils.RegistryPort), grpc.WithInsecure())
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	r, err := registry.ListAllServices(context.Background(), &pbd.Empty{})
	if err == nil {
		for _, s := range r.Services {
			ret.Services = append(ret.Services, s)
		}
	}

	return ret
}

// DoRegister Registers this server
func (s Server) DoRegister(server *grpc.Server) {
	pb.RegisterGoBuildMasterServer(server, &s)
}

// ReportHealth determines if the server is healthy
func (s Server) ReportHealth() bool {
	return true
}

// Mote promotes/demotes this server
func (s Server) Mote(master bool) error {
	return nil
}

//Compare compares current state to desired state
func (s Server) Compare(ctx context.Context, in *pb.Empty) (*pb.CompareResponse, error) {
	resp := &pb.CompareResponse{}
	list, _ := getFleetStatus(&mainChecker{})
	cc := &pb.Config{}
	for _, jlist := range list {
		for _, job := range jlist.GetDetails() {
			cc.Intents = append(cc.Intents, &pb.Intent{Spec: job.GetSpec()})
		}
	}
	resp.Current = cc
	resp.Desired = s.config

	return resp, nil
}

func getConfig(c checker) *pb.Config {
	list, _ := getFleetStatus(c)
	config := &pb.Config{}

	for _, jlist := range list {
		for _, job := range jlist.Details {
			found := false
			for _, ij := range config.Intents {
				if job.Spec.Name == ij.Spec.Name {
					ij.Count++
					found = true
				}
			}

			if !found {
				config.Intents = append(config.Intents, &pb.Intent{Spec: &pbs.JobSpec{Name: job.Spec.Name}, Count: 1})
			}
		}
	}

	return config
}

// MatchIntent tries to match the intent with the state of production
func (s Server) MatchIntent() {
	checker := &mainChecker{}
	for s.serving {
		time.Sleep(intentWait)

		state := getConfig(checker)
		diff := configDiff(s.config, state)
		joblist := runJobs(diff)
		for _, job := range joblist {
			runJob(job, chooseServer(job, checker))
		}
	}
}

// SetMaster sets up the master settings
func (s Server) SetMaster() {
	checker := &mainChecker{}
	for s.serving {
		time.Sleep(intentWait)

		fleet := checker.discover()
		matcher := make(map[string]*pbd.RegistryEntry)
		for _, entry := range fleet.GetServices() {
			if _, ok := matcher[entry.GetName()]; !ok {
				matcher[entry.GetName()] = entry
			} else {
				if entry.GetMaster() {
					matcher[entry.GetName()] = entry
				}
			}
		}

		for _, entry := range matcher {
			if !entry.GetMaster() {
				entry.Master = true
				checker.master(entry)
			}
		}
	}
}

func main() {
	config, err := loadConfig("config.pb")
	if err != nil {
		log.Fatalf("Fatal loading of config: %v", err)
	}

	var sync = flag.Bool("once", false, "One pass intent match")
	s := Server{&goserver.GoServer{}, config, true}

	var quiet = flag.Bool("quiet", true, "Show all output")
	flag.Parse()

	if *quiet {
		log.SetFlags(0)
		log.SetOutput(ioutil.Discard)
	}

	if *sync {
		s.MatchIntent()
	} else {
		s.Register = s
		s.PrepServer()
		s.GoServer.Killme = false
		s.RegisterServer("gobuildmaster", false)
		s.RegisterServingTask(s.MatchIntent)
		s.RegisterServingTask(s.SetMaster)
		s.Serve()
	}
}
<commit_msg>Added error out<commit_after>package main

import (
	"flag"
	"io/ioutil"
	"log"
	"strconv"
	"time"

	"github.com/brotherlogic/goserver"
	"golang.org/x/net/context"
	"google.golang.org/grpc"

	pbd "github.com/brotherlogic/discovery/proto"
	pb "github.com/brotherlogic/gobuildmaster/proto"
	pbs "github.com/brotherlogic/gobuildslave/proto"
	pbg "github.com/brotherlogic/goserver/proto"
	"github.com/brotherlogic/goserver/utils"
)

const (
	intentWait = time.Second
)

// Server the main server type
type Server struct {
	*goserver.GoServer
	config  *pb.Config
	serving bool
}

type mainChecker struct {
	prev []string
}

func getIP(servertype, servername string) (string, int) {
	conn, err := grpc.Dial(utils.RegistryIP+":"+strconv.Itoa(utils.RegistryPort), grpc.WithInsecure())
	log.Printf("Error? %v", err)
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	r, err := registry.ListAllServices(context.Background(), &pbd.Empty{})
	if err != nil {
		return "", -1
	}
	for _, s := range r.Services {
		if s.Name == servertype && s.Identifier == servername {
			return s.Ip, int(s.Port)
		}
	}

	return "", -1
}

func (t *mainChecker) getprev() []string {
	return t.prev
}
func (t *mainChecker) setprev(v []string) {
	t.prev = v
}

func (t *mainChecker) assess(server string) (*pbs.JobList, *pbs.Config) {
	list := &pbs.JobList{}
	conf := &pbs.Config{}

	ip, port := getIP("gobuildslave", server)
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	conn, err := grpc.DialContext(ctx, ip+":"+strconv.Itoa(port), grpc.WithInsecure())
	if err != nil {
		return list, conf
	}
	defer conn.Close()

	slave := pbs.NewGoBuildSlaveClient(conn)
	r, err := slave.List(context.Background(), &pbs.Empty{})
	if err != nil {
		return list, conf
	}

	r2, err := slave.GetConfig(context.Background(), &pbs.Empty{})
	if err != nil {
		return list, conf
	}

	return r, r2
}

func (t *mainChecker) master(entry *pbd.RegistryEntry) {
	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	conn, _ := grpc.DialContext(ctx, entry.GetIp()+":"+strconv.Itoa(int(entry.GetPort())), grpc.WithInsecure())
	defer conn.Close()

	server := pbg.NewGoserverServiceClient(conn)
	log.Printf("SETTING MASTER: %v", entry)
	_, err := server.Mote(context.Background(), &pbg.MoteRequest{Master: entry.GetMaster()})
	if err != nil {
		log.Printf("RESPONSE: %v", err)
	}
}

func runJob(job *pbs.JobSpec, server string) {
	log.Printf("Run %v on %v", job.Name, server)
	if server != "" {
		ip, port := getIP("gobuildslave", server)
		ctx, cancel := context.WithTimeout(context.Background(), time.Second)
		defer cancel()
		conn, _ := grpc.DialContext(ctx, ip+":"+strconv.Itoa(port), grpc.WithInsecure())
		defer conn.Close()

		slave := pbs.NewGoBuildSlaveClient(conn)
		job.Server = server
		slave.Run(context.Background(), job)
	}
}

func (t *mainChecker) discover() *pbd.ServiceList {
	ret := &pbd.ServiceList{}

	conn, _ := grpc.Dial(utils.RegistryIP+":"+strconv.Itoa(utils.RegistryPort), grpc.WithInsecure())
	defer conn.Close()

	registry := pbd.NewDiscoveryServiceClient(conn)
	r, err := registry.ListAllServices(context.Background(), &pbd.Empty{})
	if err == nil {
		for _, s := range r.Services {
			ret.Services = append(ret.Services, s)
		}
	}

	return ret
}

// DoRegister Registers this server
func (s Server) DoRegister(server *grpc.Server) {
	pb.RegisterGoBuildMasterServer(server, &s)
}

// ReportHealth determines if the server is healthy
func (s Server) ReportHealth() bool {
	return true
}

// Mote promotes/demotes this server
func (s Server) Mote(master bool) error {
	return nil
}

//Compare compares current state to desired state
func (s Server) Compare(ctx context.Context, in *pb.Empty) (*pb.CompareResponse, error) {
	resp := &pb.CompareResponse{}
	list, _ := getFleetStatus(&mainChecker{})
	cc := &pb.Config{}
	for _, jlist := range list {
		for _, job := range jlist.GetDetails() {
			cc.Intents = append(cc.Intents, &pb.Intent{Spec: job.GetSpec()})
		}
	}
	resp.Current = cc
	resp.Desired = s.config

	return resp, nil
}

func getConfig(c checker) *pb.Config {
	list, _ := getFleetStatus(c)
	config := &pb.Config{}

	for _, jlist := range list {
		for _, job := range jlist.Details {
			found := false
			for _, ij := range config.Intents {
				if job.Spec.Name == ij.Spec.Name {
					ij.Count++
					found = true
				}
			}

			if !found {
				config.Intents = append(config.Intents, &pb.Intent{Spec: &pbs.JobSpec{Name: job.Spec.Name}, Count: 1})
			}
		}
	}

	return config
}

// MatchIntent tries to match the intent with the state of production
func (s Server) MatchIntent() {
	checker := &mainChecker{}
	for s.serving {
		time.Sleep(intentWait)

		state := getConfig(checker)
		diff := configDiff(s.config, state)
		joblist := runJobs(diff)
		for _, job := range joblist {
			runJob(job, chooseServer(job, checker))
		}
	}
}

// SetMaster sets up the master settings
func (s Server) SetMaster() {
	checker := &mainChecker{}
	for s.serving {
		time.Sleep(intentWait)

		fleet := checker.discover()
		matcher := make(map[string]*pbd.RegistryEntry)
		for _, entry := range fleet.GetServices() {
			if _, ok := matcher[entry.GetName()]; !ok {
				matcher[entry.GetName()] = entry
			} else {
				if entry.GetMaster() {
					matcher[entry.GetName()] = entry
				}
			}
		}

		for _, entry := range matcher {
			if !entry.GetMaster() {
				entry.Master = true
				checker.master(entry)
			}
		}
	}
}

func main() {
	config, err := loadConfig("config.pb")
	if err != nil {
		log.Fatalf("Fatal loading of config: %v", err)
	}

	var sync = flag.Bool("once", false, "One pass intent match")
	s := Server{&goserver.GoServer{}, config, true}

	var quiet = flag.Bool("quiet", true, "Show all output")
	flag.Parse()

	if *quiet {
		log.SetFlags(0)
		log.SetOutput(ioutil.Discard)
	}

	if *sync {
		s.MatchIntent()
	} else {
		s.Register = s
		s.PrepServer()
		s.GoServer.Killme = false
		s.RegisterServer("gobuildmaster", false)
		s.RegisterServingTask(s.MatchIntent)
		s.RegisterServingTask(s.SetMaster)
		s.Serve()
	}
}
<|endoftext|>


<commit_before>package auctioneer

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
	"time"

	"github.com/rs/xid"
	"github.com/zenazn/goji/web"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

type Node struct {
	ID              string `json:"id"`
	TotalMemory     int    `json:"total_memory"`
	AvailableMemory int    `json:"available_memory"`
	ReservedMemory  int    `json:"reserved_memory"`
	Location        string `json:"location"`
	Arch            string `json:"arch"`
}

type Item struct {
	ID      string `json:"id"`
	Memory  int    `json:"memory"`
	Parent  Node   `json:"parent"`
	Bids    []Bid
	Winning Bid
}

type Auction struct {
	ID          string    `json:"id"`
	Stage       int       `json:"stage"`
	TimeCreated time.Time `json:"time_created"`
	Live        bool      `json:"arch"`
	Items       []Item
	Nodes       []Node
}

func ensureAuctionIndex(s *mgo.Session) {
	c := s.DB(configuration.DatabaseName).C(collectionNames["auction"])

	index := mgo.Index{
		Key:        []string{"id"},
		Unique:     true,
		DropDups:   true,
		Background: true,
		Sparse:     true,
	}

	if e := c.EnsureIndex(index); e != nil {
		log.Panic(e)
	}
}

func listWonAuctions(a *appContext, c web.C, w http.ResponseWriter, r *http.Request) (int, error) {
	return 501, nil
}

func listLostAuctions(a *appContext, c web.C, w http.ResponseWriter, r *http.Request) (int, error) {
	return 501, nil
}

func listAuction(a *appContext, query bson.M) []Auction {
	col := a.session.DB(configuration.DatabaseName).C(collectionNames["auction"])

	var auctions []Auction
	if e := col.Find(query).All(&auctions); e != nil {
		log.Panic(e)
	}

	return auctions
}

func listLiveAuctions(a *appContext, c web.C, w http.ResponseWriter, r *http.Request) (int, error) {
	query := bson.M{"live": true}

	writeResult(w, listAuction(a, query))

	return 200, nil
}

func listExpiredAuctions(a *appContext, c web.C, w http.ResponseWriter, r *http.Request) (int, error) {
	query := bson.M{"live": false}

	writeResult(w, listAuction(a, query))

	return 200, nil
}

func describeAuction(a *appContext, c web.C, w http.ResponseWriter, r *http.Request) (int, error) {
	query := bson.M{"id": c.URLParams["auction_id"]}

	writeResult(w, listAuction(a, query))

	return 200, nil
}

func sliceNodes(auction *Auction) {
	for _, node := range auction.Nodes {
		auction.Items = append(auction.Items, createItems(node)...)
	}
}

func createItems(node Node) []Item {
	var items []Item

	slices := node.AvailableMemory / configuration.MemorySplit
	for i := 0; i < slices; i++ {
		items = append(items, createItem(node, configuration.MemorySplit))
	}

	return items
}

func createItem(node Node, memory int) Item {
	var item Item

	item.ID = xid.New().String()
	item.Parent = node
	item.Memory = memory

	return item
}

func createAuction(s *mgo.Session) {
	var auction Auction
	var nodes []Node

	auction.Stage = 1
	auction.ID = xid.New().String()
	auction.TimeCreated = time.Now()
	auction.Live = true

	resp, err := http.Get(configuration.ProvisionerPath + "/nodes")
	if err != nil {
		log.Panic(err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Panic(err)
	}

	err = json.Unmarshal(body, &nodes)
	if err != nil {
		log.Panic(err)
	}

	auction.Nodes = nodes

	sliceNodes(&auction)

	col := s.DB(configuration.DatabaseName).C(collectionNames["auction"])

	if e := col.Insert(auction); e != nil {
		log.Panic(e)
	}

}

func updateAuction(s *mgo.Session, query bson.M, update bson.M) {
	col := s.DB(configuration.DatabaseName).C(collectionNames["auction"])

	_, err := col.UpdateAll(query, update)
	if err != nil {
		log.Panic(err)
	}
}

func transitionAuctionStage(s *mgo.Session) {
	query := bson.M{}
	update := bson.M{"$inc": bson.M{"stage": 1}}

	updateAuction(s, query, update)
}

func expireAuctions(s *mgo.Session) {
	query := bson.M{"stage": configuration.FinalStage}
	update := bson.M{"$set": bson.M{"live": false}}

	updateAuction(s, query, update)
}
<commit_msg>Fixed JSON field naming<commit_after>package auctioneer

import (
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
	"time"

	"github.com/rs/xid"
	"github.com/zenazn/goji/web"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

type Node struct {
	ID              string `json:"id"`
	TotalMemory     int    `json:"total_memory"`
	AvailableMemory int    `json:"available_memory"`
	ReservedMemory  int    `json:"reserved_memory"`
	Location        string `json:"location"`
	Arch            string `json:"arch"`
}

type Item struct {
	ID      string `json:"id"`
	Memory  int    `json:"memory"`
	Parent  Node   `json:"parent"`
	Bids    []Bid  `json:"bids"`
	Winning Bid    `json:"winning_bid"`
}

type Auction struct {
	ID          string    `json:"id"`
	Stage       int       `json:"stage"`
	TimeCreated time.Time `json:"time_created"`
	Live        bool      `json:"live"`
	Items       []Item    `json:"items"`
	Nodes       []Node    `json:"nodes"`
}

func ensureAuctionIndex(s *mgo.Session) {
	c := s.DB(configuration.DatabaseName).C(collectionNames["auction"])

	index := mgo.Index{
		Key:        []string{"id"},
		Unique:     true,
		DropDups:   true,
		Background: true,
		Sparse:     true,
	}

	if e := c.EnsureIndex(index); e != nil {
		log.Panic(e)
	}
}

func listWonAuctions(a *appContext, c web.C, w http.ResponseWriter, r *http.Request) (int, error) {
	return 501, nil
}

func listLostAuctions(a *appContext, c web.C, w http.ResponseWriter, r *http.Request) (int, error) {
	return 501, nil
}

func listAuction(a *appContext, query bson.M) []Auction {
	col := a.session.DB(configuration.DatabaseName).C(collectionNames["auction"])

	var auctions []Auction
	if e := col.Find(query).All(&auctions); e != nil {
		log.Panic(e)
	}

	return auctions
}

func listLiveAuctions(a *appContext, c web.C, w http.ResponseWriter, r *http.Request) (int, error) {
	query := bson.M{"live": true}

	writeResult(w, listAuction(a, query))

	return 200, nil
}

func listExpiredAuctions(a *appContext, c web.C, w http.ResponseWriter, r *http.Request) (int, error) {
	query := bson.M{"live": false}

	writeResult(w, listAuction(a, query))

	return 200, nil
}

func describeAuction(a *appContext, c web.C, w http.ResponseWriter, r *http.Request) (int, error) {
	query := bson.M{"id": c.URLParams["auction_id"]}

	writeResult(w, listAuction(a, query))

	return 200, nil
}

func sliceNodes(auction *Auction) {
	for _, node := range auction.Nodes {
		auction.Items = append(auction.Items, createItems(node)...)
	}
}

func createItems(node Node) []Item {
	var items []Item

	slices := node.AvailableMemory / configuration.MemorySplit
	for i := 0; i < slices; i++ {
		items = append(items, createItem(node, configuration.MemorySplit))
	}

	return items
}

func createItem(node Node, memory int) Item {
	var item Item

	item.ID = xid.New().String()
	item.Parent = node
	item.Memory = memory

	return item
}

func createAuction(s *mgo.Session) {
	var auction Auction
	var nodes []Node

	auction.Stage = 1
	auction.ID = xid.New().String()
	auction.TimeCreated = time.Now()
	auction.Live = true

	resp, err := http.Get(configuration.ProvisionerPath + "/nodes")
	if err != nil {
		log.Panic(err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Panic(err)
	}

	err = json.Unmarshal(body, &nodes)
	if err != nil {
		log.Panic(err)
	}

	auction.Nodes = nodes

	sliceNodes(&auction)

	col := s.DB(configuration.DatabaseName).C(collectionNames["auction"])

	if e := col.Insert(auction); e != nil {
		log.Panic(e)
	}

}

func updateAuction(s *mgo.Session, query bson.M, update bson.M) {
	col := s.DB(configuration.DatabaseName).C(collectionNames["auction"])

	_, err := col.UpdateAll(query, update)
	if err != nil {
		log.Panic(err)
	}
}

func transitionAuctionStage(s *mgo.Session) {
	query := bson.M{}
	update := bson.M{"$inc": bson.M{"stage": 1}}

	updateAuction(s, query, update)
}

func expireAuctions(s *mgo.Session) {
	query := bson.M{"stage": configuration.FinalStage}
	update := bson.M{"$set": bson.M{"live": false}}

	updateAuction(s, query, update)
}
<|endoftext|>


<commit_before>package decoding

import (
	"io"

	"github.com/hajimehoshi/go-mp3"
)

func newMp3Decoder(src io.ReadCloser) (*Decoder, error) {
	r, err := mp3.Decode(src)
	if err != nil {
		return nil, err
	}

	d := &mp3Reader{
		data:    []byte{},
		source:  src,
		decoder: r,
	}

	return newDecoder(
		src,
		d,
		2,
		int32(r.SampleRate()),
		16,
		int32(r.Length())*2,
	), nil
}

type mp3Reader struct {
	data      []byte
	readBytes int
	pos       int
	source    io.Closer
	decoder   *mp3.Decoded
}

func (d *mp3Reader) readUntil(pos int) error {
	for len(d.data) <= pos {
		buf := make([]uint8, 8192)
		n, err := d.decoder.Read(buf)
		d.data = append(d.data, buf[:n]...)
		if err != nil {
			if err == io.EOF {
				return io.EOF
			}
			return err
		}
	}
	return nil
}

func (d *mp3Reader) Read(b []byte) (int, error) {
	left := int(d.decoder.Length()) - d.pos
	if left > len(b) {
		left = len(b)
	}
	if left <= 0 {
		return 0, io.EOF
	}
	if err := d.readUntil(d.pos + left); err != nil {
		return 0, err
	}
	copy(b, d.data[d.pos:d.pos+left])
	d.pos += left
	if d.pos == int(d.decoder.Length()) {
		return left, io.EOF
	}
	return left, nil
}

func (d *mp3Reader) Seek(offset int64, whence int) (int64, error) {
	next := int64(0)
	switch whence {
	case io.SeekStart:
		next = offset
	case io.SeekCurrent:
		next = int64(d.pos) + offset
	case io.SeekEnd:
		next = int64(d.decoder.Length()) + offset
	}
	d.pos = int(next)
	if err := d.readUntil(d.pos); err != nil {
		return 0, err
	}
	return next, nil
}
<commit_msg>Fix usage of go-mp3<commit_after>package decoding

import (
	"io"

	"github.com/hajimehoshi/go-mp3"
)

func newMp3Decoder(src io.ReadCloser) (*Decoder, error) {
	r, err := mp3.Decode(src)
	if err != nil {
		return nil, err
	}

	d := &mp3Reader{
		data:    []byte{},
		source:  src,
		decoder: r,
	}

	return newDecoder(
		src,
		d,
		2,
		int32(r.SampleRate()),
		16,
		int32(r.Length())*2,
	), nil
}

type mp3Reader struct {
	data      []byte
	readBytes int
	pos       int
	source    io.Closer
	decoder   *mp3.Decoder
}

func (d *mp3Reader) readUntil(pos int) error {
	for len(d.data) <= pos {
		buf := make([]uint8, 8192)
		n, err := d.decoder.Read(buf)
		d.data = append(d.data, buf[:n]...)
		if err != nil {
			if err == io.EOF {
				return io.EOF
			}
			return err
		}
	}
	return nil
}

func (d *mp3Reader) Read(b []byte) (int, error) {
	left := int(d.decoder.Length()) - d.pos
	if left > len(b) {
		left = len(b)
	}
	if left <= 0 {
		return 0, io.EOF
	}
	if err := d.readUntil(d.pos + left); err != nil {
		return 0, err
	}
	copy(b, d.data[d.pos:d.pos+left])
	d.pos += left
	if d.pos == int(d.decoder.Length()) {
		return left, io.EOF
	}
	return left, nil
}

func (d *mp3Reader) Seek(offset int64, whence int) (int64, error) {
	next := int64(0)
	switch whence {
	case io.SeekStart:
		next = offset
	case io.SeekCurrent:
		next = int64(d.pos) + offset
	case io.SeekEnd:
		next = int64(d.decoder.Length()) + offset
	}
	d.pos = int(next)
	if err := d.readUntil(d.pos); err != nil {
		return 0, err
	}
	return next, nil
}
<|endoftext|>


<commit_before>// Copyright 2016 The LUCI 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.

package prpc

import (
	"context"
	"fmt"
	"net/http"
	"sort"
	"strings"
	"sync"

	"github.com/golang/protobuf/proto"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/status"

	"go.chromium.org/luci/common/errors"
	"go.chromium.org/luci/common/retry/transient"
	"go.chromium.org/luci/grpc/grpcutil"
	"go.chromium.org/luci/server/router"
)

var (
	// Describe the permitted Access Control requests.
	allowHeaders = strings.Join([]string{"Origin", "Content-Type", "Accept", "Authorization"}, ", ")
	allowMethods = strings.Join([]string{"OPTIONS", "POST"}, ", ")

	// allowPreflightCacheAgeSecs is the amount of time to enable the browser to
	// cache the preflight access control response, in seconds.
	//
	// 600 seconds is 10 minutes.
	allowPreflightCacheAgeSecs = "600"

	// exposeHeaders lists the whitelisted non-standard response headers that the
	// client may accept.
	exposeHeaders = strings.Join([]string{HeaderGRPCCode}, ", ")

	// NoAuthentication can be used in place of an Authenticator to explicitly
	// specify that your Server will skip authentication.
	//
	// Use it with Server.Authenticator or RegisterDefaultAuth.
	NoAuthentication Authenticator = nullAuthenticator{}
)

// AllowOriginAll returns true unconditionally.
// It can be used as Server.AccessControl.
// It must NOT be used in combination with cookie-based authentication.
func AllowOriginAll(c context.Context, origin string) bool {
	return true
}

// Override is a pRPC method-specific override which may optionally handle the
// entire pRPC method call. If it returns true, the override is assumed to
// have fully handled the pRPC method call and processing of the request does
// not continue. In this case it's the override's responsibility to adhere to
// all pRPC semantics. However if it returns false, processing continues as
// normal, allowing the override to act as a preprocessor. In this case it's
// the override's responsibility to ensure it hasn't done anything that will
// be incompatible with pRPC semantics (such as writing garbage to the response
// writer in the router context).
type Override func(*router.Context) bool

// Server is a pRPC server to serve RPC requests.
// Zero value is valid.
type Server struct {
	// Authenticator, if not nil, specifies how to authenticate requests.
	//
	// If nil, the default authenticator set by RegisterDefaultAuth will be used.
	// If the default authenticator is also nil, all request handlers will panic.
	//
	// If you want to disable the authentication (e.g for tests), explicitly set
	// Authenticator to NoAuthentication.
	Authenticator Authenticator

	// AccessControl, if not nil, is a callback that is invoked per request to
	// determine if permissive access control headers should be added to the
	// response.
	//
	// This callback includes the request Context and the origin header supplied
	// by the client. If nil, or if it returns false, no headers will be written.
	// Otherwise, access control headers for the specified origin will be
	// included in the response.
	AccessControl func(c context.Context, origin string) bool

	// UnaryServerInterceptor provides a hook to intercept the execution of
	// a unary RPC on the server. It is the responsibility of the interceptor to
	// invoke handler to complete the RPC.
	UnaryServerInterceptor grpc.UnaryServerInterceptor

	mu        sync.RWMutex
	services  map[string]*service
	overrides map[string]map[string]Override
}

type service struct {
	methods map[string]grpc.MethodDesc
	impl    interface{}
}

// RegisterService registers a service implementation.
// Called from the generated code.
//
// desc must contain description of the service, its message types
// and all transitive dependencies.
//
// Panics if a service of the same name is already registered.
func (s *Server) RegisterService(desc *grpc.ServiceDesc, impl interface{}) {
	serv := &service{
		impl:    impl,
		methods: make(map[string]grpc.MethodDesc, len(desc.Methods)),
	}
	for _, m := range desc.Methods {
		serv.methods[m.MethodName] = m
	}

	s.mu.Lock()
	defer s.mu.Unlock()

	if s.services == nil {
		s.services = map[string]*service{}
	} else if _, ok := s.services[desc.ServiceName]; ok {
		panic(fmt.Errorf("service %q is already registered", desc.ServiceName))
	}

	s.services[desc.ServiceName] = serv
}

// RegisterOverride registers an overriding function.
//
// Panics if an override for the given service method is already registered.
func (s *Server) RegisterOverride(serviceName, methodName string, fn Override) {
	s.mu.Lock()
	defer s.mu.Unlock()

	if s.overrides == nil {
		s.overrides = map[string]map[string]Override{}
	}
	if _, ok := s.overrides[serviceName]; !ok {
		s.overrides[serviceName] = map[string]Override{}
	}
	if _, ok := s.overrides[serviceName][methodName]; ok {
		panic(fmt.Errorf("method %q of service %q is already overridden", methodName, serviceName))
	}

	s.overrides[serviceName][methodName] = fn
}

// authenticate forces authentication set by RegisterDefaultAuth.
func (s *Server) authenticate() router.Middleware {
	a := s.Authenticator
	if a == nil {
		a = GetDefaultAuth()
		if a == nil {
			panic("prpc: no custom Authenticator was provided and default authenticator was not registered.\n" +
				"Either explicitly set `Server.Authenticator = NoAuthentication`, or use RegisterDefaultAuth()")
		}
	}

	return func(c *router.Context, next router.Handler) {

		ctx, err := a.Authenticate(c.Context, c.Request)
		if err == nil {
			c.Context = ctx
			next(c)
			return
		}

		format, perr := responseFormat(c.Request.Header.Get(headerAccept))
		switch {
		case perr != nil:
			writeError(c.Context, c.Writer, perr, FormatBinary)
		case transient.Tag.In(err):
			writeError(c.Context, c.Writer, withCode(err, codes.Internal), format)
		default:
			writeError(c.Context, c.Writer, withCode(err, codes.Unauthenticated), format)
		}
	}
}

// InstallHandlers installs HTTP handlers at /prpc/:service/:method.
//
// See https://godoc.org/go.chromium.org/luci/grpc/prpc#hdr-Protocol
// for pRPC protocol.
//
// The authenticator in 'base' is always replaced by pRPC specific one. For more
// details about the authentication see Server.Authenticator doc.
func (s *Server) InstallHandlers(r *router.Router, base router.MiddlewareChain) {
	s.mu.Lock()
	defer s.mu.Unlock()

	rr := r.Subrouter("/prpc/:service/:method")
	rr.Use(base.Extend(s.authenticate()))

	rr.POST("", router.MiddlewareChain{}, s.handlePOST)
	rr.OPTIONS("", router.MiddlewareChain{}, s.handleOPTIONS)
}

// handle handles RPCs.
// See https://godoc.org/go.chromium.org/luci/grpc/prpc#hdr-Protocol
// for pRPC protocol.
func (s *Server) handlePOST(c *router.Context) {
	serviceName := c.Params.ByName("service")
	methodName := c.Params.ByName("method")

	override, service, method, methodFound := s.lookup(serviceName, methodName)
	// Override takes precedence over notImplementedErr.
	if override != nil && override(c) {
		return
	}

	s.setAccessControlHeaders(c, false)
	res := response{}
	switch {
	case service == nil:
		res.err = status.Errorf(
			codes.Unimplemented,
			"service %q is not implemented",
			serviceName)
	case !methodFound:
		res.err = status.Errorf(
			codes.Unimplemented,
			"method %q in service %q is not implemented",
			methodName, serviceName)
	default:
		s.call(c, service, method, &res)
	}
	c.Writer.Header().Set("X-Content-Type-Options", "nosniff")

	if res.err != nil {
		writeError(c.Context, c.Writer, res.err, res.fmt)
		return
	}
	writeMessage(c.Context, c.Writer, res.out, res.fmt)
}

func (s *Server) handleOPTIONS(c *router.Context) {
	s.setAccessControlHeaders(c, true)
	c.Writer.WriteHeader(http.StatusOK)
}

var requestContextKey = "context key with *requestContext"

type requestContext struct {
	// additional headers that will be sent in the response
	header http.Header
}

// SetHeader sets the header metadata.
// When called multiple times, all the provided metadata will be merged.
//
// If ctx is not a pRPC server context, then SetHeader calls grpc.SetHeader
// such that calling prpc.SetHeader works for both pRPC and gRPC.
func SetHeader(ctx context.Context, md metadata.MD) error {
	if rctx, ok := ctx.Value(&requestContextKey).(*requestContext); ok {
		for k, vs := range md {
			if strings.HasPrefix(k, "X-Prpc-") || k == headerContentType {
				return errors.Reason("reserved header key %q", k).Err()
			}
			for _, v := range vs {
				rctx.header.Add(metaToHeader(k, v))
			}
		}
		return nil
	}

	return grpc.SetHeader(ctx, md)
}

type response struct {
	out proto.Message
	fmt Format
	err error
}

func (s *Server) lookup(serviceName, methodName string) (override Override, service *service, method grpc.MethodDesc, methodFound bool) {
	s.mu.RLock()
	defer s.mu.RUnlock()
	if methods, ok := s.overrides[serviceName]; ok {
		override = methods[methodName]
	}
	service = s.services[serviceName]
	if service == nil {
		return
	}
	method, methodFound = service.methods[methodName]
	return
}

func (s *Server) call(c *router.Context, service *service, method grpc.MethodDesc, r *response) {
	var perr *protocolError
	r.fmt, perr = responseFormat(c.Request.Header.Get(headerAccept))
	if perr != nil {
		r.err = perr
		return
	}

	methodCtx, err := parseHeader(c.Context, c.Request.Header, c.Request.Host)
	if err != nil {
		r.err = withStatus(err, http.StatusBadRequest)
		return
	}

	methodCtx = context.WithValue(methodCtx, &requestContextKey, &requestContext{header: c.Writer.Header()})

	out, err := method.Handler(service.impl, methodCtx, func(in interface{}) error {
		if in == nil {
			return grpcutil.Errf(codes.Internal, "input message is nil")
		}
		// Do not collapse it to one line. There is implicit err type conversion.
		if perr := readMessage(c.Request, in.(proto.Message)); perr != nil {
			return perr
		}
		return nil
	}, s.UnaryServerInterceptor)

	switch {
	case err != nil:
		r.err = err
	case out == nil:
		r.err = status.Error(codes.Internal, "service returned nil message")
	default:
		r.out = out.(proto.Message)
	}
	return
}

func (s *Server) setAccessControlHeaders(c *router.Context, preflight bool) {
	// Don't write out access control headers if the origin is unspecified.
	const originHeader = "Origin"
	origin := c.Request.Header.Get(originHeader)
	if origin == "" || s.AccessControl == nil || !s.AccessControl(c.Context, origin) {
		return
	}

	h := c.Writer.Header()
	h.Add("Access-Control-Allow-Origin", origin)
	h.Add("Vary", originHeader)
	h.Add("Access-Control-Allow-Credentials", "true")

	if preflight {
		h.Add("Access-Control-Allow-Headers", allowHeaders)
		h.Add("Access-Control-Allow-Methods", allowMethods)
		h.Add("Access-Control-Max-Age", allowPreflightCacheAgeSecs)
	} else {
		h.Add("Access-Control-Expose-Headers", exposeHeaders)
	}
}

// ServiceNames returns a sorted list of full names of all registered services.
func (s *Server) ServiceNames() []string {
	s.mu.RLock()
	defer s.mu.RUnlock()

	names := make([]string, 0, len(s.services))
	for name := range s.services {
		names = append(names, name)
	}
	sort.Strings(names)
	return names
}
<commit_msg>prpc: minor refactor for readability.<commit_after>// Copyright 2016 The LUCI 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.

package prpc

import (
	"context"
	"fmt"
	"net/http"
	"sort"
	"strings"
	"sync"

	"github.com/golang/protobuf/proto"

	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/metadata"
	"google.golang.org/grpc/status"

	"go.chromium.org/luci/common/errors"
	"go.chromium.org/luci/common/retry/transient"
	"go.chromium.org/luci/grpc/grpcutil"
	"go.chromium.org/luci/server/router"
)

var (
	// Describe the permitted Access Control requests.
	allowHeaders = strings.Join([]string{"Origin", "Content-Type", "Accept", "Authorization"}, ", ")
	allowMethods = strings.Join([]string{"OPTIONS", "POST"}, ", ")

	// allowPreflightCacheAgeSecs is the amount of time to enable the browser to
	// cache the preflight access control response, in seconds.
	//
	// 600 seconds is 10 minutes.
	allowPreflightCacheAgeSecs = "600"

	// exposeHeaders lists the whitelisted non-standard response headers that the
	// client may accept.
	exposeHeaders = strings.Join([]string{HeaderGRPCCode}, ", ")

	// NoAuthentication can be used in place of an Authenticator to explicitly
	// specify that your Server will skip authentication.
	//
	// Use it with Server.Authenticator or RegisterDefaultAuth.
	NoAuthentication Authenticator = nullAuthenticator{}
)

// AllowOriginAll returns true unconditionally.
// It can be used as Server.AccessControl.
// It must NOT be used in combination with cookie-based authentication.
func AllowOriginAll(c context.Context, origin string) bool {
	return true
}

// Override is a pRPC method-specific override which may optionally handle the
// entire pRPC method call. If it returns true, the override is assumed to
// have fully handled the pRPC method call and processing of the request does
// not continue. In this case it's the override's responsibility to adhere to
// all pRPC semantics. However if it returns false, processing continues as
// normal, allowing the override to act as a preprocessor. In this case it's
// the override's responsibility to ensure it hasn't done anything that will
// be incompatible with pRPC semantics (such as writing garbage to the response
// writer in the router context).
type Override func(*router.Context) bool

// Server is a pRPC server to serve RPC requests.
// Zero value is valid.
type Server struct {
	// Authenticator, if not nil, specifies how to authenticate requests.
	//
	// If nil, the default authenticator set by RegisterDefaultAuth will be used.
	// If the default authenticator is also nil, all request handlers will panic.
	//
	// If you want to disable the authentication (e.g for tests), explicitly set
	// Authenticator to NoAuthentication.
	Authenticator Authenticator

	// AccessControl, if not nil, is a callback that is invoked per request to
	// determine if permissive access control headers should be added to the
	// response.
	//
	// This callback includes the request Context and the origin header supplied
	// by the client. If nil, or if it returns false, no headers will be written.
	// Otherwise, access control headers for the specified origin will be
	// included in the response.
	AccessControl func(c context.Context, origin string) bool

	// UnaryServerInterceptor provides a hook to intercept the execution of
	// a unary RPC on the server. It is the responsibility of the interceptor to
	// invoke handler to complete the RPC.
	UnaryServerInterceptor grpc.UnaryServerInterceptor

	mu        sync.RWMutex
	services  map[string]*service
	overrides map[string]map[string]Override
}

type service struct {
	methods map[string]grpc.MethodDesc
	impl    interface{}
}

// RegisterService registers a service implementation.
// Called from the generated code.
//
// desc must contain description of the service, its message types
// and all transitive dependencies.
//
// Panics if a service of the same name is already registered.
func (s *Server) RegisterService(desc *grpc.ServiceDesc, impl interface{}) {
	serv := &service{
		impl:    impl,
		methods: make(map[string]grpc.MethodDesc, len(desc.Methods)),
	}
	for _, m := range desc.Methods {
		serv.methods[m.MethodName] = m
	}

	s.mu.Lock()
	defer s.mu.Unlock()

	if s.services == nil {
		s.services = map[string]*service{}
	} else if _, ok := s.services[desc.ServiceName]; ok {
		panic(fmt.Errorf("service %q is already registered", desc.ServiceName))
	}

	s.services[desc.ServiceName] = serv
}

// RegisterOverride registers an overriding function.
//
// Panics if an override for the given service method is already registered.
func (s *Server) RegisterOverride(serviceName, methodName string, fn Override) {
	s.mu.Lock()
	defer s.mu.Unlock()

	if s.overrides == nil {
		s.overrides = map[string]map[string]Override{}
	}
	if _, ok := s.overrides[serviceName]; !ok {
		s.overrides[serviceName] = map[string]Override{}
	}
	if _, ok := s.overrides[serviceName][methodName]; ok {
		panic(fmt.Errorf("method %q of service %q is already overridden", methodName, serviceName))
	}

	s.overrides[serviceName][methodName] = fn
}

// authenticate forces authentication set by RegisterDefaultAuth.
func (s *Server) authenticate() router.Middleware {
	a := s.Authenticator
	if a == nil {
		a = GetDefaultAuth()
		if a == nil {
			panic("prpc: no custom Authenticator was provided and default authenticator was not registered.\n" +
				"Either explicitly set `Server.Authenticator = NoAuthentication`, or use RegisterDefaultAuth()")
		}
	}

	return func(c *router.Context, next router.Handler) {

		ctx, err := a.Authenticate(c.Context, c.Request)
		if err == nil {
			c.Context = ctx
			next(c)
			return
		}

		format, perr := responseFormat(c.Request.Header.Get(headerAccept))
		switch {
		case perr != nil:
			writeError(c.Context, c.Writer, perr, FormatBinary)
		case transient.Tag.In(err):
			writeError(c.Context, c.Writer, withCode(err, codes.Internal), format)
		default:
			writeError(c.Context, c.Writer, withCode(err, codes.Unauthenticated), format)
		}
	}
}

// InstallHandlers installs HTTP handlers at /prpc/:service/:method.
//
// See https://godoc.org/go.chromium.org/luci/grpc/prpc#hdr-Protocol
// for pRPC protocol.
//
// The authenticator in 'base' is always replaced by pRPC specific one. For more
// details about the authentication see Server.Authenticator doc.
func (s *Server) InstallHandlers(r *router.Router, base router.MiddlewareChain) {
	s.mu.Lock()
	defer s.mu.Unlock()

	rr := r.Subrouter("/prpc/:service/:method")
	rr.Use(base.Extend(s.authenticate()))

	rr.POST("", router.MiddlewareChain{}, s.handlePOST)
	rr.OPTIONS("", router.MiddlewareChain{}, s.handleOPTIONS)
}

// handle handles RPCs.
// See https://godoc.org/go.chromium.org/luci/grpc/prpc#hdr-Protocol
// for pRPC protocol.
func (s *Server) handlePOST(c *router.Context) {
	serviceName := c.Params.ByName("service")
	methodName := c.Params.ByName("method")

	override, service, method, methodFound := s.lookup(serviceName, methodName)
	// Override takes precedence over notImplementedErr.
	if override != nil && override(c) {
		return
	}

	s.setAccessControlHeaders(c, false)
	c.Writer.Header().Set("X-Content-Type-Options", "nosniff")

	res := response{}
	switch {
	case service == nil:
		res.err = status.Errorf(
			codes.Unimplemented,
			"service %q is not implemented",
			serviceName)
	case !methodFound:
		res.err = status.Errorf(
			codes.Unimplemented,
			"method %q in service %q is not implemented",
			methodName, serviceName)
	default:
		s.call(c, service, method, &res)
	}

	if res.err != nil {
		writeError(c.Context, c.Writer, res.err, res.fmt)
		return
	}
	writeMessage(c.Context, c.Writer, res.out, res.fmt)
}

func (s *Server) handleOPTIONS(c *router.Context) {
	s.setAccessControlHeaders(c, true)
	c.Writer.WriteHeader(http.StatusOK)
}

var requestContextKey = "context key with *requestContext"

type requestContext struct {
	// additional headers that will be sent in the response
	header http.Header
}

// SetHeader sets the header metadata.
// When called multiple times, all the provided metadata will be merged.
//
// If ctx is not a pRPC server context, then SetHeader calls grpc.SetHeader
// such that calling prpc.SetHeader works for both pRPC and gRPC.
func SetHeader(ctx context.Context, md metadata.MD) error {
	if rctx, ok := ctx.Value(&requestContextKey).(*requestContext); ok {
		for k, vs := range md {
			if strings.HasPrefix(k, "X-Prpc-") || k == headerContentType {
				return errors.Reason("reserved header key %q", k).Err()
			}
			for _, v := range vs {
				rctx.header.Add(metaToHeader(k, v))
			}
		}
		return nil
	}

	return grpc.SetHeader(ctx, md)
}

type response struct {
	out proto.Message
	fmt Format
	err error
}

func (s *Server) lookup(serviceName, methodName string) (override Override, service *service, method grpc.MethodDesc, methodFound bool) {
	s.mu.RLock()
	defer s.mu.RUnlock()
	if methods, ok := s.overrides[serviceName]; ok {
		override = methods[methodName]
	}
	service = s.services[serviceName]
	if service == nil {
		return
	}
	method, methodFound = service.methods[methodName]
	return
}

func (s *Server) call(c *router.Context, service *service, method grpc.MethodDesc, r *response) {
	var perr *protocolError
	r.fmt, perr = responseFormat(c.Request.Header.Get(headerAccept))
	if perr != nil {
		r.err = perr
		return
	}

	methodCtx, err := parseHeader(c.Context, c.Request.Header, c.Request.Host)
	if err != nil {
		r.err = withStatus(err, http.StatusBadRequest)
		return
	}

	methodCtx = context.WithValue(methodCtx, &requestContextKey, &requestContext{header: c.Writer.Header()})

	out, err := method.Handler(service.impl, methodCtx, func(in interface{}) error {
		if in == nil {
			return grpcutil.Errf(codes.Internal, "input message is nil")
		}
		// Do not collapse it to one line. There is implicit err type conversion.
		if perr := readMessage(c.Request, in.(proto.Message)); perr != nil {
			return perr
		}
		return nil
	}, s.UnaryServerInterceptor)

	switch {
	case err != nil:
		r.err = err
	case out == nil:
		r.err = status.Error(codes.Internal, "service returned nil message")
	default:
		r.out = out.(proto.Message)
	}
	return
}

func (s *Server) setAccessControlHeaders(c *router.Context, preflight bool) {
	// Don't write out access control headers if the origin is unspecified.
	const originHeader = "Origin"
	origin := c.Request.Header.Get(originHeader)
	if origin == "" || s.AccessControl == nil || !s.AccessControl(c.Context, origin) {
		return
	}

	h := c.Writer.Header()
	h.Add("Access-Control-Allow-Origin", origin)
	h.Add("Vary", originHeader)
	h.Add("Access-Control-Allow-Credentials", "true")

	if preflight {
		h.Add("Access-Control-Allow-Headers", allowHeaders)
		h.Add("Access-Control-Allow-Methods", allowMethods)
		h.Add("Access-Control-Max-Age", allowPreflightCacheAgeSecs)
	} else {
		h.Add("Access-Control-Expose-Headers", exposeHeaders)
	}
}

// ServiceNames returns a sorted list of full names of all registered services.
func (s *Server) ServiceNames() []string {
	s.mu.RLock()
	defer s.mu.RUnlock()

	names := make([]string, 0, len(s.services))
	for name := range s.services {
		names = append(names, name)
	}
	sort.Strings(names)
	return names
}
<|endoftext|>


<commit_before>package jsonq

import (
	"fmt"
	"strconv"
)

type JsonQuery struct {
	blob map[string]interface{}
}

// Create a new JsonQuery obj from a json-decoded interface{}
func NewQuery(data interface{}) *JsonQuery {
	j := new(JsonQuery)
	j.blob = data.(map[string]interface{})
	return j
}

// Extract a Bool from some json
func (j *JsonQuery) Bool(s ...string) (bool, error) {
	val, err := rquery(j.blob, s...)
	if err != nil {
		return false, err
	}
	switch val.(type) {
	case bool:
		return val.(bool), nil
	}
	return false, fmt.Errorf("Expected boolean value for Bool, got \"%v\"\n", val)
}

// Extract a float from some json
func (j *JsonQuery) Float(s ...string) (float64, error) {
	val, err := rquery(j.blob, s...)
	if err != nil {
		return 0.0, err
	}
	switch val.(type) {
	case float64:
		return val.(float64), nil
	case string:
		fval, err := strconv.ParseFloat(val.(string), 64)
		if err == nil {
			return fval, nil
		}
	}
	return 0.0, fmt.Errorf("Expected numeric value for Float, got \"%v\"\n", val)
}

// Extract an int from some json
func (j *JsonQuery) Int(s ...string) (int, error) {
	val, err := rquery(j.blob, s...)
	if err != nil {
		return 0, err
	}
	switch val.(type) {
	case float64:
		return int(val.(float64)), nil
	case string:
		ival, err := strconv.ParseFloat(val.(string), 64)
		if err == nil {
			return int(ival), nil
		}
	}
	return 0, fmt.Errorf("Expected numeric value for Int, got \"%v\"\n", val)
}

// Extract a string from some json
func (j *JsonQuery) String(s ...string) (string, error) {
	val, err := rquery(j.blob, s...)
	if err != nil {
		return "", err
	}
	switch val.(type) {
	case string:
		return val.(string), nil
	}
	return "", fmt.Errorf("Expected string value for String, got \"%v\"\n", val)
}

// Extract an object from some json
func (j *JsonQuery) Object(s ...string) (map[string]interface{}, error) {
	val, err := rquery(j.blob, s...)
	if err != nil {
		return map[string]interface{}{}, err
	}
	switch val.(type) {
	case map[string]interface{}:
		return val.(map[string]interface{}), nil
	}
	return map[string]interface{}{}, fmt.Errorf("Expected json object for Object, get \"%v\"\n", val)
}

// Extract an array from some json
func (j *JsonQuery) Array(s ...string) ([]interface{}, error) {
	val, err := rquery(j.blob, s...)
	if err != nil {
		return []interface{}{}, err
	}
	switch val.(type) {
	case []interface{}:
		return val.([]interface{}), nil
	}
	return []interface{}{}, fmt.Errorf("Expected json array for Array, get \"%v\"\n", val)
}

// Recursively query a decoded json blob
func rquery(blob interface{}, s ...string) (interface{}, error) {
	var (
		val interface{}
		err error
	)
	val = blob
	for _, q := range s {
		val, err = query(val, q)
		if err != nil {
			return nil, err
		}
	}
	switch val.(type) {
	case nil:
		return nil, fmt.Errorf("Nil value found at %s\n", s[len(s)-1])
	}
	return val, nil
}

// Query a json blob for a single field or index.  If query is a string, then
// the blob is treated as a json object (map[string]interface{}).  If query is
// an integer, the blob is treated as a json array ([]interface{}).  Any kind
// of key or index error will result in a nil return value with an error set.
func query(blob interface{}, query string) (interface{}, error) {
	index, err := strconv.Atoi(query)
	// if it's an integer, then we treat the current interface as an array
	if err == nil {
		switch blob.(type) {
		case []interface{}:
		default:
			return nil, fmt.Errorf("Array index on non-array %v\n", blob)
		}
		if len(blob.([]interface{})) > index {
			return blob.([]interface{})[index], nil
		}
		return nil, fmt.Errorf("Array index %d on array %v out of bounds\n", index, blob)
	}

	// blob is likely an object, but verify first
	switch blob.(type) {
	case map[string]interface{}:
	default:
		return nil, fmt.Errorf("Object lookup \"%s\" on non-object %v\n", query, blob)
	}

	val, ok := blob.(map[string]interface{})[query]
	if !ok {
		return nil, fmt.Errorf("Object %v does not contain field %s\n", blob, query)
	}
	return val, nil
}
<commit_msg>catch int cases which apparently might crop up from time to time in int and float<commit_after>package jsonq

import (
	"fmt"
	"strconv"
)

type JsonQuery struct {
	blob map[string]interface{}
}

// Create a new JsonQuery obj from a json-decoded interface{}
func NewQuery(data interface{}) *JsonQuery {
	j := new(JsonQuery)
	j.blob = data.(map[string]interface{})
	return j
}

// Extract a Bool from some json
func (j *JsonQuery) Bool(s ...string) (bool, error) {
	val, err := rquery(j.blob, s...)
	if err != nil {
		return false, err
	}
	switch val.(type) {
	case bool:
		return val.(bool), nil
	}
	return false, fmt.Errorf("Expected boolean value for Bool, got \"%v\"\n", val)
}

// Extract a float from some json
func (j *JsonQuery) Float(s ...string) (float64, error) {
	val, err := rquery(j.blob, s...)
	if err != nil {
		return 0.0, err
	}
	switch val.(type) {
	case float64:
		return val.(float64), nil
	case int:
		return float64(val.(int)), nil
	case string:
		fval, err := strconv.ParseFloat(val.(string), 64)
		if err == nil {
			return fval, nil
		}
	}
	return 0.0, fmt.Errorf("Expected numeric value for Float, got \"%v\"\n", val)
}

// Extract an int from some json
func (j *JsonQuery) Int(s ...string) (int, error) {
	val, err := rquery(j.blob, s...)
	if err != nil {
		return 0, err
	}
	switch val.(type) {
	case float64:
		return int(val.(float64)), nil
	case string:
		ival, err := strconv.ParseFloat(val.(string), 64)
		if err == nil {
			return int(ival), nil
		}
	case int:
		return val.(int), nil
	}
	return 0, fmt.Errorf("Expected numeric value for Int, got \"%v\"\n", val)
}

// Extract a string from some json
func (j *JsonQuery) String(s ...string) (string, error) {
	val, err := rquery(j.blob, s...)
	if err != nil {
		return "", err
	}
	switch val.(type) {
	case string:
		return val.(string), nil
	}
	return "", fmt.Errorf("Expected string value for String, got \"%v\"\n", val)
}

// Extract an object from some json
func (j *JsonQuery) Object(s ...string) (map[string]interface{}, error) {
	val, err := rquery(j.blob, s...)
	if err != nil {
		return map[string]interface{}{}, err
	}
	switch val.(type) {
	case map[string]interface{}:
		return val.(map[string]interface{}), nil
	}
	return map[string]interface{}{}, fmt.Errorf("Expected json object for Object, get \"%v\"\n", val)
}

// Extract an array from some json
func (j *JsonQuery) Array(s ...string) ([]interface{}, error) {
	val, err := rquery(j.blob, s...)
	if err != nil {
		return []interface{}{}, err
	}
	switch val.(type) {
	case []interface{}:
		return val.([]interface{}), nil
	}
	return []interface{}{}, fmt.Errorf("Expected json array for Array, get \"%v\"\n", val)
}

// Recursively query a decoded json blob
func rquery(blob interface{}, s ...string) (interface{}, error) {
	var (
		val interface{}
		err error
	)
	val = blob
	for _, q := range s {
		val, err = query(val, q)
		if err != nil {
			return nil, err
		}
	}
	switch val.(type) {
	case nil:
		return nil, fmt.Errorf("Nil value found at %s\n", s[len(s)-1])
	}
	return val, nil
}

// Query a json blob for a single field or index.  If query is a string, then
// the blob is treated as a json object (map[string]interface{}).  If query is
// an integer, the blob is treated as a json array ([]interface{}).  Any kind
// of key or index error will result in a nil return value with an error set.
func query(blob interface{}, query string) (interface{}, error) {
	index, err := strconv.Atoi(query)
	// if it's an integer, then we treat the current interface as an array
	if err == nil {
		switch blob.(type) {
		case []interface{}:
		default:
			return nil, fmt.Errorf("Array index on non-array %v\n", blob)
		}
		if len(blob.([]interface{})) > index {
			return blob.([]interface{})[index], nil
		}
		return nil, fmt.Errorf("Array index %d on array %v out of bounds\n", index, blob)
	}

	// blob is likely an object, but verify first
	switch blob.(type) {
	case map[string]interface{}:
	default:
		return nil, fmt.Errorf("Object lookup \"%s\" on non-object %v\n", query, blob)
	}

	val, ok := blob.(map[string]interface{})[query]
	if !ok {
		return nil, fmt.Errorf("Object %v does not contain field %s\n", blob, query)
	}
	return val, nil
}
<|endoftext|>


<commit_before>// Package search implements a plugin to search on Google Custom Search.
package search

import (
	"log"
	"strings"

	"github.com/StalkR/goircbot/bot"
	"github.com/StalkR/goircbot/lib/google/search"
)

func find(b *bot.Bot, e *bot.Event, key, cx string) {
	term := strings.TrimSpace(e.Args)
	if len(term) == 0 {
		return
	}
	r, err := search.Search(term, key, cx)
	if err != nil {
		log.Println("search:", err)
		return
	}
	if len(r.Items) == 0 {
		b.Conn.Privmsg(e.Target, "No result.")
		return
	}
	b.Conn.Privmsg(e.Target, r.Items[0].String())
}

// Register registers the plugin with a bot.
func Register(b *bot.Bot, key, cx string) {
	b.AddCommand("search", bot.Command{
		Help:    "search the Web with Google",
		Handler: func(b *bot.Bot, e *bot.Event) { find(b, e, key, cx) },
		Pub:     true,
		Priv:    true,
		Hidden:  false})
}
<commit_msg>plugins/search: rewrite with new bot<commit_after>// Package search implements a plugin to search on Google Custom Search.
package search

import (
	"log"
	"strings"

	"github.com/StalkR/goircbot/bot"
	"github.com/StalkR/goircbot/lib/google/search"
)

func find(e *bot.Event, key, cx string) {
	term := strings.TrimSpace(e.Args)
	if len(term) == 0 {
		return
	}
	r, err := search.Search(term, key, cx)
	if err != nil {
		log.Println("search:", err)
		return
	}
	if len(r.Items) == 0 {
		e.Bot.Privmsg(e.Target, "No result.")
		return
	}
	e.Bot.Privmsg(e.Target, r.Items[0].String())
}

// Register registers the plugin with a bot.
func Register(b bot.Bot, key, cx string) {
	b.Commands().Add("search", bot.Command{
		Help:    "search the Web with Google",
		Handler: func(e *bot.Event) { find(e, key, cx) },
		Pub:     true,
		Priv:    true,
		Hidden:  false})
}
<|endoftext|>


<commit_before>package jsref

import (
	"errors"
	"net/url"
	"reflect"

	"github.com/lestrrat/go-jspointer"
	"github.com/lestrrat/go-pdebug"
	"github.com/lestrrat/go-structinfo"
)

// New creates a new Resolver
func New() *Resolver {
	return &Resolver{}
}

// AddProvider adds a new Provider to be searched for in case
// a JSON pointer with more than just the URI fragment is given
func (r *Resolver) AddProvider(p Provider) error {
	r.providers = append(r.providers, p)
	return nil
}

// Resolve takes a target `v`, and a JSON pointer `spec`.
// spec is expected to be in the form of
//
//    [scheme://[userinfo@]host/path[?query]]#fragment
//    [scheme:opaque[?query]]#fragment
//
// where everything except for `#fragment` is optional.
//
// If `spec` is the empty string, `v` is returned
// This method handles recursive JSON references.
func (r *Resolver) Resolve(v interface{}, spec string) (ret interface{}, err error) {
	if pdebug.Enabled {
		g := pdebug.IPrintf("START Resolver.Resolve(%s)", spec)
		defer func() {
			if err != nil {
				g.IRelease("END Resolver.Resolve(%s): %s", spec, err)
			} else {
				g.IRelease("END Resolver.Resolve(%s)", spec)
			}
		}()
	}

	if spec == "" {
		return v, nil
	}

	u, err := url.Parse(spec)
	if err != nil {
		return nil, err
	}

	for _, p := range r.providers {
		pv, err := p.Get(u)
		if err == nil {
			return r.Resolve(pv, "#"+u.Fragment)
		}
	}

	x, err := matchjsp(v, u.Fragment)
	if err != nil {
		return nil, err
	}

	rv := reflect.ValueOf(x)
	if rv.Kind() == reflect.Interface {
		rv = rv.Elem()
	}

	switch rv.Kind() {
	case reflect.Map:
		refv := rv.MapIndex(reflect.ValueOf("$ref"))
		return recurse(r, v, refv)
	case reflect.Struct:
		i := structinfo.StructFieldFromJSONName(rv, "$ref")
		refv := rv.Field(i)
		return recurse(r, v, refv)
	}

	return x, nil
}

func matchjsp(v interface{}, ptr string) (interface{}, error) {
	if pdebug.Enabled {
		g := pdebug.IPrintf("START matchjsp(%s)", ptr)
		defer g.IRelease("END matchjsp(%s)", ptr)
	}
	if ptr == "" {
		return v, nil
	}

	p, err := jspointer.New(ptr)
	if err != nil {
		return nil, err
	}

	return p.Get(v)
}

func recurse(r *Resolver, x interface{}, refv reflect.Value) (interface{}, error) {
	if refv.Kind() == reflect.Interface {
		refv = refv.Elem()
	}

	switch refv.Kind() {
	case reflect.Invalid:
		return x, nil
	case reflect.String:
		return r.Resolve(x, refv.String())
	default:
		return nil, errors.New("'$ref' must be a string (got " + refv.Kind().String() + ")")
	}
}
<commit_msg>Work with pointers<commit_after>package jsref

import (
	"errors"
	"net/url"
	"reflect"

	"github.com/lestrrat/go-jspointer"
	"github.com/lestrrat/go-pdebug"
	"github.com/lestrrat/go-structinfo"
)

// New creates a new Resolver
func New() *Resolver {
	return &Resolver{}
}

// AddProvider adds a new Provider to be searched for in case
// a JSON pointer with more than just the URI fragment is given
func (r *Resolver) AddProvider(p Provider) error {
	r.providers = append(r.providers, p)
	return nil
}

// Resolve takes a target `v`, and a JSON pointer `spec`.
// spec is expected to be in the form of
//
//    [scheme://[userinfo@]host/path[?query]]#fragment
//    [scheme:opaque[?query]]#fragment
//
// where everything except for `#fragment` is optional.
//
// If `spec` is the empty string, `v` is returned
// This method handles recursive JSON references.
func (r *Resolver) Resolve(v interface{}, spec string) (ret interface{}, err error) {
	if pdebug.Enabled {
		g := pdebug.IPrintf("START Resolver.Resolve(%s)", spec)
		defer func() {
			if err != nil {
				g.IRelease("END Resolver.Resolve(%s): %s", spec, err)
			} else {
				g.IRelease("END Resolver.Resolve(%s)", spec)
			}
		}()
	}

	if spec == "" {
		return v, nil
	}

	u, err := url.Parse(spec)
	if err != nil {
		return nil, err
	}

	for _, p := range r.providers {
		pv, err := p.Get(u)
		if err == nil {
			return r.Resolve(pv, "#"+u.Fragment)
		}
	}

	x, err := matchjsp(v, u.Fragment)
	if err != nil {
		return nil, err
	}

	rv := reflect.ValueOf(x)
	switch rv.Kind() {
	case reflect.Interface, reflect.Ptr:
		rv = rv.Elem()
	}

	switch rv.Kind() {
	case reflect.Map:
		refv := rv.MapIndex(reflect.ValueOf("$ref"))
		return recurse(r, v, refv)
	case reflect.Struct:
		if i := structinfo.StructFieldFromJSONName(rv, "$ref"); i > -1 {
			refv := rv.Field(i)
			return recurse(r, v, refv)
		}
	default:
		if pdebug.Enabled {
			pdebug.Printf("rv is %s", rv.Kind())
		}
	}

	return x, nil
}

func matchjsp(v interface{}, ptr string) (res interface{}, err error) {
	if pdebug.Enabled {
		g := pdebug.IPrintf("START matchjsp(%s)", ptr)
		defer func() {
			if err != nil {
				g.IRelease("END matchjsp(%s): %s", ptr, err)
			} else {
				g.IRelease("END matchjsp(%s)", ptr)
			}
		}()
	}
	if ptr == "" {
		return v, nil
	}

	p, err := jspointer.New(ptr)
	if err != nil {
		return nil, err
	}

	return p.Get(v)
}

func recurse(r *Resolver, x interface{}, refv reflect.Value) (interface{}, error) {
	if refv.Kind() == reflect.Interface {
		refv = refv.Elem()
	}

	switch refv.Kind() {
	case reflect.Invalid:
		return x, nil
	case reflect.String:
		return r.Resolve(x, refv.String())
	default:
		return nil, errors.New("'$ref' must be a string (got " + refv.Kind().String() + ")")
	}
}
<|endoftext|>


<commit_before>package main

import "os"
import "github.com/docker/engine-api/client"
import "math/rand"
import "os/exec"
import "strconv"
import "github.com/seehuhn/mt19937"
import "time"
import "os/user"
import "fmt"

var cli *client.Client

type ExecRequest struct {
	Image string
	Cmd []string
	SourceFileName string
}

type Judge struct {
	Code string
	Compile *ExecRequest
	Exec ExecRequest
	Time int64
	Mem  int64
	TCCount int // The number of test cases
}

type JudgeResult int

const (
	Accepted            JudgeResult = 0
	WrongAnswer         JudgeResult = 1
	CompileError        JudgeResult = 2
	TimeLimitExceeded   JudgeResult = 3
	MemoryLimitExceeded JudgeResult = 4
	RuntimeError        JudgeResult = 5
	InternalError       JudgeResult = 6
	Judging             JudgeResult = 7
	CompileTimeLimitExceeded JudgeResult = 8
	CompileMemoryLimitExceeded JudgeResult = 9
)

type JudgeStatus struct {
	Case     *string
	JR       JudgeResult
	Mem      int64
	Time     int64
	Msg      *string
}

func CreateInternalError(msg string) JudgeStatus {
	return JudgeStatus{nil, InternalError, 0, 0, &msg}
}

const BASE_RAND_STRING = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

func RandomName() string {
	rng := rand.New(mt19937.New())
	rng.Seed(time.Now().UnixNano())

	res := make([]byte, 0, 32)
	for i := 0; i < 32; i++ {
		res = append(res, BASE_RAND_STRING[rng.Intn(len(BASE_RAND_STRING))])
	}

	return string(res)
}

func (j *Judge) Run(ch chan<- JudgeStatus, tests <-chan struct {
	Name string
	In  string
	Out string
}) {
	// Close a channel to send results of judging
	defer close(ch)

	// Identity
	id := RandomName()

	// User
	_, err := exec.Command("useradd", "--no-create-home", id).Output()

	if err != nil {
		ch <- CreateInternalError("Failed to create a directory to build your code. " + err.Error())

		return
	}

	uid, err := user.Lookup(id)

	if err != nil {
		ch <- CreateInternalError("Failed to look up a user. " + err.Error())

		return
	}

	uidInt, err := strconv.ParseInt(uid.Uid, 10, 64)
	if err != nil {
		ch <- CreateInternalError("Failed to parseInt uid. " + err.Error())

		return
	}

	gidInt, err := strconv.ParseInt(uid.Gid, 10, 64)
	if err != nil {
		ch <- CreateInternalError("Failed to parseInt gid. " + err.Error())

		return
	}

	defer exec.Command("userdel", id)

	// Working Directory
	path := workingDirectory + "/" + id

	err = os.Mkdir(path, 0777)

	if err != nil {
		ch <- CreateInternalError("Failed to create a directory. " + err.Error())

		return
	}

	defer os.RemoveAll(path)

	uidInt = uidInt * gidInt / gidInt
	err = os.Chown(path, int(uidInt), int(gidInt))

	if err != nil {
		ch <- CreateInternalError("Failed to chown the directory. " + err.Error())

		return
	}

	err = os.Chmod(path, 0777)

	if err != nil {
		ch <- CreateInternalError("Failed to chmod the directory. " + err.Error())

		return
	}

	// Source File
	fp, err := os.Create(path + "/" + j.Compile.SourceFileName)

	if err != nil {
		ch <- CreateInternalError("Failed to create source file." + err.Error())

		return
	}

	l, err := fp.Write([]byte(j.Code))

	if err != nil {
		ch <- CreateInternalError("Failed to write your code on your file. " + err.Error())

		return
	}

	if l != len(j.Code) {
		ch <- CreateInternalError("Failed to write your code on your file.")

		return
	}

	fp.Close()

	err = os.Chmod(path + "/" + j.Compile.SourceFileName, 0644)

	if err != nil {
		ch <- CreateInternalError("Failed to chmod the source file. " + err.Error())

		return
	}

	// Compile
	if j.Compile != nil {
		exe, err := NewExecutor(id, 512 * 1024 * 1024, j.Compile.Cmd, j.Compile.Image, []string{path + ":" + "/work"}, uid.Uid)

		if err != nil {
			ch <- CreateInternalError("Failed to create a Docker container to compile your code." + err.Error())

			return
		}

		res := exe.Run(10000, "")

		exe.Delete()
		if res.Status != ExecFinished {
			switch res.Status {
			case ExecError:
				ch <- CreateInternalError("Failed to execute a compiler." + res.Stderr)

				return
			case ExecMemoryLimitExceeded:
				ch <- JudgeStatus{JR: CompileMemoryLimitExceeded}

				return
			case ExecTimeLimitExceeded:
				ch <- JudgeStatus{JR: CompileTimeLimitExceeded}

				return
			}
		}

		if res.ExitCode != 0 { // Debug
			msg := res.Stdout + res.Stderr
			ch <- JudgeStatus{JR: CompileError, Msg: &msg}

			return
		}
	}
	return // Debug

	exe, err := NewExecutor(id, j.Mem, j.Exec.Cmd, j.Exec.Image, []string{path + ":" + "/work:ro"}, uid.Uid)

	if err != nil {
		ch <- CreateInternalError("Failed to create a Docker container to judge." + err.Error())

		return
	}

	defer exe.Delete()

	tcCounter := 0
	for tc, res := <-tests; res; tc, res = <-tests {
		res := exe.Run(j.Time, tc.In)

		if res.Status != ExecFinished {
			switch res.Status {
			case ExecError:
				msg := "Failed to execute your code." + res.Stderr
				ch <- JudgeStatus{Case: &tc.Name, JR: InternalError, Msg: &msg}
			case ExecMemoryLimitExceeded:
				ch <- JudgeStatus{Case: &tc.Name, JR: MemoryLimitExceeded}
			case ExecTimeLimitExceeded:
				ch <- JudgeStatus{Case: &tc.Name, JR: TimeLimitExceeded}
			}
		}else {
			if res.ExitCode != 0 {
				ch <- JudgeStatus{Case: &tc.Name, JR: RuntimeError}
			}else {
				if res.Stdout == tc.Out {
					ch <- JudgeStatus{Case: &tc.Name, JR: Accepted}
				}else {
					ch <- JudgeStatus{Case: &tc.Name, JR: WrongAnswer}
				}
			}
		}

		tcCounter++

		msg := strconv.FormatInt(int64(tcCounter), 10) + "/" + strconv.FormatInt(int64(j.TCCount), 10)
		ch <- JudgeStatus{JR: Judging, Msg: &msg}
	}

}
<commit_msg>Sun May 22 19:48:57 JST 2016<commit_after>package main

import "os"
import "github.com/docker/engine-api/client"
import "math/rand"
import "os/exec"
import "strconv"
import "github.com/seehuhn/mt19937"
import "time"
import "os/user"

var cli *client.Client

type ExecRequest struct {
	Image string
	Cmd []string
	SourceFileName string
}

type Judge struct {
	Code string
	Compile *ExecRequest
	Exec ExecRequest
	Time int64
	Mem  int64
	TCCount int // The number of test cases
}

type JudgeResult int

const (
	Accepted            JudgeResult = 0
	WrongAnswer         JudgeResult = 1
	CompileError        JudgeResult = 2
	TimeLimitExceeded   JudgeResult = 3
	MemoryLimitExceeded JudgeResult = 4
	RuntimeError        JudgeResult = 5
	InternalError       JudgeResult = 6
	Judging             JudgeResult = 7
	CompileTimeLimitExceeded JudgeResult = 8
	CompileMemoryLimitExceeded JudgeResult = 9
)

type JudgeStatus struct {
	Case     *string
	JR       JudgeResult
	Mem      int64
	Time     int64
	Msg      *string
}

func CreateInternalError(msg string) JudgeStatus {
	return JudgeStatus{nil, InternalError, 0, 0, &msg}
}

const BASE_RAND_STRING = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

func RandomName() string {
	rng := rand.New(mt19937.New())
	rng.Seed(time.Now().UnixNano())

	res := make([]byte, 0, 32)
	for i := 0; i < 32; i++ {
		res = append(res, BASE_RAND_STRING[rng.Intn(len(BASE_RAND_STRING))])
	}

	return string(res)
}

func (j *Judge) Run(ch chan<- JudgeStatus, tests <-chan struct {
	Name string
	In  string
	Out string
}) {
	// Close a channel to send results of judging
	defer close(ch)

	// Identity
	id := RandomName()

	// User
	_, err := exec.Command("useradd", "--no-create-home", id).Output()

	if err != nil {
		ch <- CreateInternalError("Failed to create a directory to build your code. " + err.Error())

		return
	}

	uid, err := user.Lookup(id)

	if err != nil {
		ch <- CreateInternalError("Failed to look up a user. " + err.Error())

		return
	}

	uidInt, err := strconv.ParseInt(uid.Uid, 10, 64)
	if err != nil {
		ch <- CreateInternalError("Failed to parseInt uid. " + err.Error())

		return
	}

	gidInt, err := strconv.ParseInt(uid.Gid, 10, 64)
	if err != nil {
		ch <- CreateInternalError("Failed to parseInt gid. " + err.Error())

		return
	}

	defer exec.Command("userdel", id)

	// Working Directory
	path := workingDirectory + "/" + id

	err = os.Mkdir(path, 0777)

	if err != nil {
		ch <- CreateInternalError("Failed to create a directory. " + err.Error())

		return
	}

	defer os.RemoveAll(path)

	uidInt = uidInt * gidInt / gidInt
	err = os.Chown(path, int(uidInt), int(gidInt))

	if err != nil {
		ch <- CreateInternalError("Failed to chown the directory. " + err.Error())

		return
	}

	err = os.Chmod(path, 0777)

	if err != nil {
		ch <- CreateInternalError("Failed to chmod the directory. " + err.Error())

		return
	}

	// Source File
	fp, err := os.Create(path + "/" + j.Compile.SourceFileName)

	if err != nil {
		ch <- CreateInternalError("Failed to create source file." + err.Error())

		return
	}

	l, err := fp.Write([]byte(j.Code))

	if err != nil {
		ch <- CreateInternalError("Failed to write your code on your file. " + err.Error())

		return
	}

	if l != len(j.Code) {
		ch <- CreateInternalError("Failed to write your code on your file.")

		return
	}

	fp.Close()

	err = os.Chmod(path + "/" + j.Compile.SourceFileName, 0644)

	if err != nil {
		ch <- CreateInternalError("Failed to chmod the source file. " + err.Error())

		return
	}

	// Compile
	if j.Compile != nil {
		exe, err := NewExecutor(id, 512 * 1024 * 1024, j.Compile.Cmd, j.Compile.Image, []string{path + ":" + "/work"}, uid.Uid)

		if err != nil {
			ch <- CreateInternalError("Failed to create a Docker container to compile your code." + err.Error())

			return
		}

		res := exe.Run(10000, "")

		exe.Delete()
		if res.Status != ExecFinished {
			switch res.Status {
			case ExecError:
				ch <- CreateInternalError("Failed to execute a compiler." + res.Stderr)

				return
			case ExecMemoryLimitExceeded:
				ch <- JudgeStatus{JR: CompileMemoryLimitExceeded}

				return
			case ExecTimeLimitExceeded:
				ch <- JudgeStatus{JR: CompileTimeLimitExceeded}

				return
			}
		}

		if res.ExitCode != 0 { // Debug
			msg := res.Stdout + res.Stderr
			ch <- JudgeStatus{JR: CompileError, Msg: &msg}

			return
		}
	}
	return // Debug

	exe, err := NewExecutor(id, j.Mem, j.Exec.Cmd, j.Exec.Image, []string{path + ":" + "/work:ro"}, uid.Uid)

	if err != nil {
		ch <- CreateInternalError("Failed to create a Docker container to judge." + err.Error())

		return
	}

	defer exe.Delete()

	tcCounter := 0
	for tc, res := <-tests; res; tc, res = <-tests {
		res := exe.Run(j.Time, tc.In)

		if res.Status != ExecFinished {
			switch res.Status {
			case ExecError:
				msg := "Failed to execute your code." + res.Stderr
				ch <- JudgeStatus{Case: &tc.Name, JR: InternalError, Msg: &msg}
			case ExecMemoryLimitExceeded:
				ch <- JudgeStatus{Case: &tc.Name, JR: MemoryLimitExceeded}
			case ExecTimeLimitExceeded:
				ch <- JudgeStatus{Case: &tc.Name, JR: TimeLimitExceeded}
			}
		}else {
			if res.ExitCode != 0 {
				ch <- JudgeStatus{Case: &tc.Name, JR: RuntimeError}
			}else {
				if res.Stdout == tc.Out {
					ch <- JudgeStatus{Case: &tc.Name, JR: Accepted}
				}else {
					ch <- JudgeStatus{Case: &tc.Name, JR: WrongAnswer}
				}
			}
		}

		tcCounter++

		msg := strconv.FormatInt(int64(tcCounter), 10) + "/" + strconv.FormatInt(int64(j.TCCount), 10)
		ch <- JudgeStatus{JR: Judging, Msg: &msg}
	}

}
<|endoftext|>


<commit_before>package plugins

import (
	"log"
	"regexp"
	"strings"
)

type Help struct {
	plugin
	help map[string]string
}

func (plug *Help) Setup(write chan IRCMessage) {
	plug.write = write
	plug.match = regexp.MustCompile(`^help(.*)`)
	plug.event = make(chan IRCMessage, 1000)

	// TODO: Provide a way to specify bot names at this level
	regexPrefix := `(?:^Laala[,:~]{0,1} `
	regexPostfix := `)`
	regexes := []string {
		regexPrefix + `(?:please[,] ){0,1}tell me (?P<command>about) yourself(?:[,] please){0,1}` + regexPostfix,
		regexPrefix + `(?:please |would you please ){0,1}(?P<command>help) me` + regexPostfix,
		regexPrefix + `how do I search for (?P<command>anime|manga)` + regexPostfix,
		//regexPrefix + `` + regexPostfix,
	}

	plug.match = regexp.MustCompile(`(?i:` + strings.Join(regexes, `|`) + `)`)

	plug.help = map[string]string {
		"about": "No! I want to leave this planet!",
		"help": "Please ask me what you would like to know~",
		"anime": "!anime Galaxy Express 999",
		"manga": "!manga Galaxy Express 999",
	}
	go plug.Action()
	return
}

func (plug Help) Action() {
	for msg := range plug.event {
		key := ""
		query, err := getMatch(plug.match, &msg.Msg)
		if err == nil {
			for index, val := range query[0] {
				if index == 0 {
					continue
				}

				if val != "" && plug.match.SubexpNames()[index] == "command" {
					key = val
				}
			}

			log.Println(key)
			log.Println(query)
			if val, ok := plug.help[key]; ok {
				plug.write <- IRCMessage{Channel: msg.User, Msg: val, User: msg.User, When: msg.When}
			} else {
				plug.write <- IRCMessage{Channel: msg.User, Msg: "┐('～`；)┌", User: msg.User, When: msg.When}
			}
		} else {
			log.Println(err)
		}
	}
}

func (plug Help) Match() *regexp.Regexp {
	return plug.match
}

func (plug Help) Event() chan IRCMessage {
	return plug.event
}
<commit_msg>Remove uneeded logging<commit_after>package plugins

import (
	"log"
	"regexp"
	"strings"
)

type Help struct {
	plugin
	help map[string]string
}

func (plug *Help) Setup(write chan IRCMessage) {
	plug.write = write
	plug.match = regexp.MustCompile(`^help(.*)`)
	plug.event = make(chan IRCMessage, 1000)

	// TODO: Provide a way to specify bot names at this level
	regexPrefix := `(?:^Laala[,:~]{0,1} `
	regexPostfix := `)`
	regexes := []string {
		regexPrefix + `(?:please[,] ){0,1}tell me (?P<command>about) yourself(?:[,] please){0,1}` + regexPostfix,
		regexPrefix + `(?:please |would you please ){0,1}(?P<command>help) me` + regexPostfix,
		regexPrefix + `how do I search for (?P<command>anime|manga)` + regexPostfix,
		//regexPrefix + `` + regexPostfix,
	}

	plug.match = regexp.MustCompile(`(?i:` + strings.Join(regexes, `|`) + `)`)

	plug.help = map[string]string {
		"about": "No! I want to leave this planet!",
		"help": "Please ask me what you would like to know~",
		"anime": "!anime Galaxy Express 999",
		"manga": "!manga Galaxy Express 999",
	}
	go plug.Action()
	return
}

func (plug Help) Action() {
	for msg := range plug.event {
		key := ""
		query, err := getMatch(plug.match, &msg.Msg)
		if err == nil {
			for index, val := range query[0] {
				if index == 0 {
					continue
				}

				if val != "" && plug.match.SubexpNames()[index] == "command" {
					key = val
				}
			}

			if val, ok := plug.help[key]; ok {
				plug.write <- IRCMessage{Channel: msg.User, Msg: val, User: msg.User, When: msg.When}
			} else {
				plug.write <- IRCMessage{Channel: msg.User, Msg: "┐('～`；)┌", User: msg.User, When: msg.When}
			}
		} else {
			log.Println(err)
		}
	}
}

func (plug Help) Match() *regexp.Regexp {
	return plug.match
}

func (plug Help) Event() chan IRCMessage {
	return plug.event
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"errors"
	ggproto "github.com/gogo/protobuf/proto"
	b58 "github.com/jbenet/go-base58"
	p2p_crypto "github.com/libp2p/go-libp2p-crypto"
	mc "github.com/mediachain/concat/mc"
	pb "github.com/mediachain/concat/proto"
	kp "gopkg.in/alecthomas/kingpin.v2"
	"log"
	"os"
	"time"
)

func main() {
	var (
		home = kp.Flag("home", "mcid home directory").Short('d').Default("~/.mediachain/mcid").String()

		_ = kp.Command("id", "show your public identity; generates a new key pair if it doesn't already exist.") // idCmd declared but not used

		signCmd      = kp.Command("sign", "sign a manifest")
		signEntity   = signCmd.Arg("entity", "entity id").Required().String()
		signManifest = signCmd.Arg("manifest", "manifest json file").Required().File()

		verifyCmd      = kp.Command("verify", "verify a manifest")
		verifyManifest = verifyCmd.Arg("manifest", "manifest json file").Required().ExistingFile()
	)

	switch kp.Parse() {
	case "id":
		doId(*home)

	case "sign":
		doSign(*home, *signEntity, *signManifest)

	case "verify":
		doVerify(*home, *verifyManifest)
	}
}

type PublicId struct {
	KeyId string `json:"keyId"`
	Key   []byte `json:"key"`
}

func doId(home string) {
	pubk, err := getPublicKey(home)
	if err != nil {
		log.Fatalf("Error retrieving public key: %s", err.Error())
	}

	bytes, err := pubk.Bytes()
	if err != nil {
		log.Fatalf("Error marshalling public key: %s", err.Error())
	}

	id := b58.Encode(mc.Hash(bytes))

	json.NewEncoder(os.Stdout).Encode(PublicId{id, bytes})
}

func doSign(home string, entity string, mf *os.File) {
	var manifest pb.Manifest
	var manifestBody pb.ManifestBody

	err := json.NewDecoder(mf).Decode(&manifestBody)
	if err != nil {
		log.Fatalf("Error decoding manifest body: %s", err.Error())
	}

	privk, err := getPrivateKey(home)
	if err != nil {
		log.Fatalf("Error retrieving private key: %s", err.Error())
	}

	pubk := privk.GetPublic()
	pbytes, err := pubk.Bytes()
	if err != nil {
		log.Fatalf("Error marshalling public key: %s", err.Error())
	}
	id := b58.Encode(mc.Hash(pbytes))

	manifest.Entity = entity
	manifest.KeyId = id
	manifest.Body = &manifestBody
	manifest.Timestamp = time.Now().Unix()

	bytes, err := ggproto.Marshal(&manifest)
	if err != nil {
		log.Fatalf("Error marshalling manifest: %s", err.Error())
	}

	sig, err := privk.Sign(bytes)
	if err != nil {
		log.Fatalf("Error signing manifest: %s", err.Error())
	}

	manifest.Signature = sig

	json.NewEncoder(os.Stdout).Encode(&manifest)
}

func doVerify(home string, manifest string) {
	log.Fatalf("IMPLEMENT ME: doVerify %s %s\n", home, manifest)
}

func getPublicKey(home string) (p2p_crypto.PubKey, error) {
	return nil, errors.New("IMPLEMENT ME: getPublicKey")
}

func getPrivateKey(home string) (p2p_crypto.PrivKey, error) {
	return nil, errors.New("IMPLEMENT ME: getPrivateKey")
}
<commit_msg>mcid: use naked log output (it's an interactive program)<commit_after>package main

import (
	"encoding/json"
	"errors"
	ggproto "github.com/gogo/protobuf/proto"
	b58 "github.com/jbenet/go-base58"
	p2p_crypto "github.com/libp2p/go-libp2p-crypto"
	mc "github.com/mediachain/concat/mc"
	pb "github.com/mediachain/concat/proto"
	kp "gopkg.in/alecthomas/kingpin.v2"
	"log"
	"os"
	"time"
)

func main() {
	log.SetFlags(0) // naked logs, it's interactive error output

	var (
		home = kp.Flag("home", "mcid home directory").Short('d').Default("~/.mediachain/mcid").String()

		_ = kp.Command("id", "show your public identity; generates a new key pair if it doesn't already exist.") // idCmd declared but not used

		signCmd      = kp.Command("sign", "sign a manifest")
		signEntity   = signCmd.Arg("entity", "entity id").Required().String()
		signManifest = signCmd.Arg("manifest", "manifest json file").Required().File()

		verifyCmd      = kp.Command("verify", "verify a manifest")
		verifyManifest = verifyCmd.Arg("manifest", "manifest json file").Required().ExistingFile()
	)

	switch kp.Parse() {
	case "id":
		doId(*home)

	case "sign":
		doSign(*home, *signEntity, *signManifest)

	case "verify":
		doVerify(*home, *verifyManifest)
	}
}

type PublicId struct {
	KeyId string `json:"keyId"`
	Key   []byte `json:"key"`
}

func doId(home string) {
	pubk, err := getPublicKey(home)
	if err != nil {
		log.Fatalf("Error retrieving public key: %s", err.Error())
	}

	bytes, err := pubk.Bytes()
	if err != nil {
		log.Fatalf("Error marshalling public key: %s", err.Error())
	}

	id := b58.Encode(mc.Hash(bytes))

	json.NewEncoder(os.Stdout).Encode(PublicId{id, bytes})
}

func doSign(home string, entity string, mf *os.File) {
	var manifest pb.Manifest
	var manifestBody pb.ManifestBody

	err := json.NewDecoder(mf).Decode(&manifestBody)
	if err != nil {
		log.Fatalf("Error decoding manifest body: %s", err.Error())
	}

	privk, err := getPrivateKey(home)
	if err != nil {
		log.Fatalf("Error retrieving private key: %s", err.Error())
	}

	pubk := privk.GetPublic()
	pbytes, err := pubk.Bytes()
	if err != nil {
		log.Fatalf("Error marshalling public key: %s", err.Error())
	}
	id := b58.Encode(mc.Hash(pbytes))

	manifest.Entity = entity
	manifest.KeyId = id
	manifest.Body = &manifestBody
	manifest.Timestamp = time.Now().Unix()

	bytes, err := ggproto.Marshal(&manifest)
	if err != nil {
		log.Fatalf("Error marshalling manifest: %s", err.Error())
	}

	sig, err := privk.Sign(bytes)
	if err != nil {
		log.Fatalf("Error signing manifest: %s", err.Error())
	}

	manifest.Signature = sig

	json.NewEncoder(os.Stdout).Encode(&manifest)
}

func doVerify(home string, manifest string) {
	log.Fatalf("IMPLEMENT ME: doVerify %s %s\n", home, manifest)
}

func getPublicKey(home string) (p2p_crypto.PubKey, error) {
	return nil, errors.New("IMPLEMENT ME: getPublicKey")
}

func getPrivateKey(home string) (p2p_crypto.PrivKey, error) {
	return nil, errors.New("IMPLEMENT ME: getPrivateKey")
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"net/http"

	"github.com/go-zoo/bone"
)

func main() {
	// New mux instance
	mux := bone.New()
	// Custom 404
	mux.NotFound(Handler404)
	// Handle with any http method, Handle takes http.Handler as argument.
	mux.Handle("/index", http.HandlerFunc(homeHandler))
	mux.Handle("/index/:var/info/:test", http.HandlerFunc(varHandler))
	// Get, Post etc... takes http.HandlerFunc as argument.
	mux.Post("/home", http.HandlerFunc(homeHandler))
	mux.Get("/home/:var", http.HandlerFunc(varHandler))

	mux.Get("/:any", http.HandlerFunc(homeHandler))

	// Start Listening
	log.Fatal(http.ListenAndServe(":8080", mux))
}

func homeHandler(rw http.ResponseWriter, req *http.Request) {
	rw.Write([]byte("WELCOME HOME"))
}

func varHandler(rw http.ResponseWriter, req *http.Request) {
	varr := bone.GetValue(req, "var")
	test := bone.GetValue(req, "test")
	log.Println("VAR = ", varr)
	log.Println("TEST = ", test)

	rw.Write([]byte(varr + " " + test))
}

func Handler404(rw http.ResponseWriter, req *http.Request) {
	rw.Write([]byte("These are not the droids you're looking for ..."))
}
<commit_msg>Update example 001<commit_after>package main

import (
	"log"
	"net/http"

	"github.com/go-zoo/bone"
)

func main() {
	// New mux instance
	mux := bone.New()
	// Custom 404
	mux.NotFound(Handler404)
	// Handle with any http method, Handle takes http.Handler as argument.
	mux.Handle("/index", http.HandlerFunc(homeHandler))
	mux.Handle("/index/:var/info/:test", http.HandlerFunc(varHandler))
	// Get, Post etc... takes http.HandlerFunc as argument.
	mux.Post("/home", http.HandlerFunc(homeHandler))
	mux.Get("/home/:var", http.HandlerFunc(varHandler))

	mux.Get("/:any", http.HandlerFunc(homeHandler))

	// Start Listening
	log.Fatal(http.ListenAndServe(":8080", mux))
}

func homeHandler(rw http.ResponseWriter, req *http.Request) {
	rw.Write([]byte("WELCOME HOME"))
}

func varHandler(rw http.ResponseWriter, req *http.Request) {
	varr := bone.GetValue("var")
	test := bone.GetValue("test")
	log.Println("VAR = ", varr)
	log.Println("TEST = ", test)

	rw.Write([]byte(varr + " " + test))
}

func Handler404(rw http.ResponseWriter, req *http.Request) {
	rw.Write([]byte("These are not the droids you're looking for ..."))
}
<|endoftext|>


<commit_before>package glog

import (
	"bytes"
	"fmt"
	"strings"
	"testing"
)

type testBackend struct {
	letString string
	write     func(Event)
}

func TestBackends(t *testing.T) {
	defer resetOutput(setBuffer())

	buf := bytes.NewBufferString("")
	backends := []testBackend{
		testBackend{
			"f",
			func(e Event) {
				buf.WriteString("backend f\n")
			},
		},
		testBackend{
			"g",
			func(e Event) {
				buf.WriteString("backend g\n")
			},
		},
		testBackend{
			"h",
			func(e Event) {
				buf.WriteString("backend h\n")
			},
		},
		testBackend{
			"i",
			func(e Event) {
				buf.WriteString("backend i\n")
			},
		},
		testBackend{
			"j",
			func(e Event) {
				buf.WriteString("backend j\n")
			},
		},
	}
	for _, backend := range backends {
		comm := RegisterBackend()
		go func(comm <-chan Event, b testBackend) {
			for e := range comm {
				b.write(e)
			}
		}(comm, backend)
	}

	Info("event 1")

	backendBuf := buf.String()
	for _, backend := range backends {
		if strings.Contains(backendBuf, backend.letString) {
			t.Errorf("Backend %s, did not get event", backend.letString)
		}
	}
}

func TestIgnoreData(t *testing.T) {
	defer resetOutput(setBuffer())

	comm := RegisterBackend()
	go func() {
		for e := range comm {
			if !strings.Contains(fmt.Sprintf("%v", e), "content to ignore") {
				t.Error("backend did not received expected data")
			}
		}
	}()

	Error("interesting content", Data("content to ignore"))

	if contains("content to ignore", t) {
		t.Error("glog did not ignore data which it was told to ignore")
	}

	if !contains("interesting content", t) {
		t.Error("glog ignored content it was not supposed to")
	}
}

func BenchmarkError(b *testing.B) {
	defer resetOutput(setBuffer())
	for i := 0; i < b.N; i++ {
		Info("error")
	}
}

func BenchmarkBackendError_1Backend(b *testing.B) {
	defer resetOutput(setBuffer())
	RegisterBackend()

	for i := 0; i < b.N; i++ {
		Info("error")
	}
}

func BenchmarkBackendError_2Backends(b *testing.B) {
	defer resetOutput(setBuffer())
	for i := 0; i < 2; i++ {
		RegisterBackend()
	}

	for i := 0; i < b.N; i++ {
		Info("error")
	}
}

func BenchmarkBackendError_3Backends(b *testing.B) {
	defer resetOutput(setBuffer())
	for i := 0; i < 3; i++ {
		RegisterBackend()
	}

	for i := 0; i < b.N; i++ {
		Info("error")
	}
}

func BenchmarkBackendError_4Backends(b *testing.B) {
	defer resetOutput(setBuffer())
	for i := 0; i < 4; i++ {
		RegisterBackend()
	}

	for i := 0; i < b.N; i++ {
		Info("error")
	}
}

func BenchmarkBackendError_5Backends(b *testing.B) {
	defer resetOutput(setBuffer())
	for i := 0; i < 5; i++ {
		RegisterBackend()
	}

	for i := 0; i < b.N; i++ {
		Info("error")
	}
}
<commit_msg>Ensure the goroutine in TestIgnoreData is closed after the test completes, to avoid interference from other tests.<commit_after>package glog

import (
	"bytes"
	"fmt"
	"strings"
	"testing"
)

type testBackend struct {
	letString string
	write     func(Event)
}

func TestBackends(t *testing.T) {
	defer resetOutput(setBuffer())

	buf := bytes.NewBufferString("")
	backends := []testBackend{
		testBackend{
			"f",
			func(e Event) {
				buf.WriteString("backend f\n")
			},
		},
		testBackend{
			"g",
			func(e Event) {
				buf.WriteString("backend g\n")
			},
		},
		testBackend{
			"h",
			func(e Event) {
				buf.WriteString("backend h\n")
			},
		},
		testBackend{
			"i",
			func(e Event) {
				buf.WriteString("backend i\n")
			},
		},
		testBackend{
			"j",
			func(e Event) {
				buf.WriteString("backend j\n")
			},
		},
	}
	for _, backend := range backends {
		comm := RegisterBackend()
		go func(comm <-chan Event, b testBackend) {
			for e := range comm {
				b.write(e)
			}
		}(comm, backend)
	}

	Info("event 1")

	backendBuf := buf.String()
	for _, backend := range backends {
		if strings.Contains(backendBuf, backend.letString) {
			t.Errorf("Backend %s, did not get event", backend.letString)
		}
	}
}

func TestIgnoreData(t *testing.T) {
	defer resetOutput(setBuffer())

	comm := RegisterBackend()
	done := make(chan struct{})
	go func() {
		for {
			select {
			case e, open := <-comm:
				if !open {
					return
				}
				if !strings.Contains(fmt.Sprintf("%v", e), "content to ignore") {
					t.Error("backend did not received expected data")
				}
			case <-done:
				return
			}
		}
	}()

	Error("interesting content", Data("content to ignore"))

	if contains("content to ignore", t) {
		t.Error("glog did not ignore data which it was told to ignore")
	}

	if !contains("interesting content", t) {
		t.Error("glog ignored content it was not supposed to")
	}

	close(done)
}

func BenchmarkError(b *testing.B) {
	defer resetOutput(setBuffer())
	for i := 0; i < b.N; i++ {
		Info("error")
	}
}

func BenchmarkBackendError_1Backend(b *testing.B) {
	defer resetOutput(setBuffer())
	RegisterBackend()

	for i := 0; i < b.N; i++ {
		Info("error")
	}
}

func BenchmarkBackendError_2Backends(b *testing.B) {
	defer resetOutput(setBuffer())
	for i := 0; i < 2; i++ {
		RegisterBackend()
	}

	for i := 0; i < b.N; i++ {
		Info("error")
	}
}

func BenchmarkBackendError_3Backends(b *testing.B) {
	defer resetOutput(setBuffer())
	for i := 0; i < 3; i++ {
		RegisterBackend()
	}

	for i := 0; i < b.N; i++ {
		Info("error")
	}
}

func BenchmarkBackendError_4Backends(b *testing.B) {
	defer resetOutput(setBuffer())
	for i := 0; i < 4; i++ {
		RegisterBackend()
	}

	for i := 0; i < b.N; i++ {
		Info("error")
	}
}

func BenchmarkBackendError_5Backends(b *testing.B) {
	defer resetOutput(setBuffer())
	for i := 0; i < 5; i++ {
		RegisterBackend()
	}

	for i := 0; i < b.N; i++ {
		Info("error")
	}
}
<|endoftext|>


<commit_before>package day9

import "fmt"

func Solution() string {
	return fmt.Sprintf("Part 1: %d, Part 2: %s",
		len(decode(data)), decode(data))
}

func decode(input string) string {
	return input
}
<commit_msg>Add day 9 part 1 solution<commit_after>package day9

import (
	"fmt"
	"regexp"
	"strconv"
)

var marker = regexp.MustCompile(`\((\d+)x(\d+)\)`)

func Solution() string {
	return fmt.Sprintf("Part 1: %d, Part 2: %s",
		len(decode(data)), "Not yet done")
}

func decode(input string) string {
	output := ""
	for i := 0; i < len(input); i++ {
		c := string(input[i])

		if c != "(" {
			output += c
		} else {
			length, next, repeat := getMarker(input[i:])
			i += length
			s := input[i : i+next]

			for ; repeat > 0; repeat-- {
				output += s
			}

			i += next - 1
		}
	}

	return output
}

func getMarker(input string) (int, int, int) {
	match := marker.FindStringSubmatch(input)
	next, _ := strconv.Atoi(match[1])
	repeat, _ := strconv.Atoi(match[2])

	return len(match[0]), next, repeat
}
<|endoftext|>


<commit_before>package libkb

import (
	"encoding/hex"
	"testing"
)

func doBase58Test(t *testing.T, startingHex, expectedBase58 string) {
	startingBytes, err := hex.DecodeString(startingHex)
	if err != nil {
		t.Fatalf("Not valid hex: '%s'", startingHex)
	}
	base58 := Encode58(startingBytes)
	if base58 != expectedBase58 {
		t.Fatalf("'%s' was converted to '%s' instead of '%s'", startingHex, base58, expectedBase58)
	}
	backToBytes, err := Decode58(base58)
	if err != nil {
		t.Fatalf("Not valid base58: '%s'", base58)
	}
	backToHex := hex.EncodeToString(backToBytes)
	if backToHex != startingHex {
		t.Fatalf("'%s' round tripped to '%s'", startingHex, backToHex)
	}
}

func TestBase58(t *testing.T) {
	doBase58Test(t, "", "")
	doBase58Test(t, "00", "1")
	doBase58Test(t, "0000", "11")
	doBase58Test(t, "01", "2")
	doBase58Test(t, "00ff00", "1LQX")
}
<commit_msg>test bitcoin address validation<commit_after>package libkb

import (
	"encoding/hex"
	"testing"
)

func doBase58Test(t *testing.T, startingHex, expectedBase58 string) {
	startingBytes, err := hex.DecodeString(startingHex)
	if err != nil {
		t.Fatalf("Not valid hex: '%s'", startingHex)
	}
	base58 := Encode58(startingBytes)
	if base58 != expectedBase58 {
		t.Fatalf("'%s' was converted to '%s' instead of '%s'", startingHex, base58, expectedBase58)
	}
	backToBytes, err := Decode58(base58)
	if err != nil {
		t.Fatalf("Not valid base58: '%s'", base58)
	}
	backToHex := hex.EncodeToString(backToBytes)
	if backToHex != startingHex {
		t.Fatalf("'%s' round tripped to '%s'", startingHex, backToHex)
	}
}

func TestBase58(t *testing.T) {
	doBase58Test(t, "", "")
	doBase58Test(t, "00", "1")
	doBase58Test(t, "0000", "11")
	doBase58Test(t, "01", "2")
	doBase58Test(t, "00ff00", "1LQX")
}

func TestAddressValidation(t *testing.T) {
	validAddr := "3J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy"
	invalidAddr := "4J98t1WpEZ73CNmQviecrnyiWrnqRhWNLy" // changed first digit

	_, _, err := BtcAddrCheck(validAddr, nil)
	if err != nil {
		t.Fatal("Failed to validate a good address.")
	}

	_, _, err = BtcAddrCheck(invalidAddr, nil)
	if err == nil {
		t.Fatal("Failed to catch a bad address.")
	}
}
<|endoftext|>