<commit_before>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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 noops

import (
	"fmt"

	"github.com/golang/protobuf/proto"
	"github.com/op/go-logging"

	"github.com/openblockchain/obc-peer/openchain/consensus"
	"github.com/openblockchain/obc-peer/openchain/ledger"
	"github.com/openblockchain/obc-peer/openchain/util"
	pb "github.com/openblockchain/obc-peer/protos"
)

// =============================================================================
// Init
// =============================================================================

var logger *logging.Logger // package-level logger

func init() {
	logger = logging.MustGetLogger("consensus/noops")
}

// =============================================================================
// Structures go here
// =============================================================================

// Noops is a plugin object implementing the consensus.Consenter interface.
type Noops struct {
	cpi consensus.CPI
	txQ *util.Queue
}

var iNoops consensus.Consenter

// =============================================================================
// Constructors go here
// =============================================================================

// NewNoops is a constructor returning a consensus.Consenter object.
func NewNoops(c consensus.CPI) consensus.Consenter {
	logger.Debug("Creating a NOOPS object")
	i := &Noops{}
	i.cpi = c
	i.txQ = util.NewQueue()
	return i
}

// GetNoops returns a singleton of NOOPS
func GetNoops(c consensus.CPI) consensus.Consenter {
	if iNoops == nil {
		iNoops = NewNoops(c)
	}
	return iNoops
}

// RecvMsg is called for OpenchainMessage_CHAIN_TRANSACTION and OpenchainMessage_CONSENSUS messages.
func (i *Noops) RecvMsg(msg *pb.OpenchainMessage) error {
	logger.Debug("Handling OpenchainMessage of type: %s ", msg.Type)

	if msg.Type == pb.OpenchainMessage_CHAIN_TRANSACTION {
		if err := i.broadcastConsensusMsg(msg); nil != err {
			return err
		}
	}
	if msg.Type == pb.OpenchainMessage_CONSENSUS {
		txarr, err := i.getTransactionsFromMsg(msg)
		if nil != err {
			return err
		}
		if i.canProcess(txarr) {
			i.txQ.Push(txarr)
			return i.doTransactions(msg)
		}
		i.queueTransactions(txarr)
	}
	return nil
}

func (i *Noops) broadcastConsensusMsg(msg *pb.OpenchainMessage) error {
	t := &pb.Transaction{}
	if err := proto.Unmarshal(msg.Payload, t); err != nil {
		return fmt.Errorf("Error unmarshalling payload of received OpenchainMessage:%s.", msg.Type)
	}

	// Change the msg type to consensus and broadcast to the network so that
	// other validators may execute the transaction
	msg.Type = pb.OpenchainMessage_CONSENSUS
	logger.Debug("Broadcasting %s", msg.Type)
	txs := &pb.TransactionBlock{Transactions: []*pb.Transaction{t}}
	payload, err := proto.Marshal(txs)
	if err != nil {
		return err
	}
	msg.Payload = payload
	if errs := i.cpi.Broadcast(msg); nil != errs {
		return fmt.Errorf("Failed to broadcast with errors: %v", errs)
	}
	return nil
}

func (i *Noops) getTransactionsFromMsg(msg *pb.OpenchainMessage) ([]*pb.Transaction, error) {
	txs := &pb.TransactionBlock{}
	if err := proto.Unmarshal(msg.Payload, txs); err != nil {
		return nil, err
	}
	return txs.GetTransactions(), nil
}

func (i *Noops) getTransactionsFromQueue() []*pb.Transaction {
	len := i.txQ.Size()
	if len == 1 {
		return i.txQ.Pop().([]*pb.Transaction)
	}
	txarr := make([]*pb.Transaction, len)
	for k := 0; k < len; k++ {
		txs := i.txQ.Pop().([]*pb.Transaction)
		txarr[k] = txs[0]
	}
	return txarr
}

func (i *Noops) canProcess(txarr []*pb.Transaction) bool {
	// For NOOPS, if we have completed the sync since we last connected,
	// we can assume that we are at the current state; otherwise, we need to
	// wait for the sync process to complete before we can exec the transactions

	// TODO: Ask coordinator if we need to start sync

	return true
}

func (i *Noops) doTransactions(msg *pb.OpenchainMessage) error {
	logger.Debug("Executing transactions")
	ledger, err := ledger.GetLedger()
	if err != nil {
		return fmt.Errorf("Fail to get the ledger: %v", err)
	}
	logger.Debug("Starting TX batch with timestamp: %v", msg.Timestamp)
	if err := ledger.BeginTxBatch(msg.Timestamp); err != nil {
		return fmt.Errorf("Fail to begin transaction with the ledger: %v", err)
	}

	// Grab all transactions from the FIFO queue and run them in order
	txarr := i.getTransactionsFromQueue()
	logger.Debug("Executing batch of %d transactions", len(txarr))
	_, errs := i.cpi.ExecTXs(txarr)

	//there are n+1 elements of errors in this array. On complete success
	//they'll all be nil. In particular, the last err will be error in
	//producing the hash, if any. That's the only error we do want to check
	if errs[len(txarr)] != nil {
		logger.Debug("Rolling back TX batch with timestamp: %v", msg.Timestamp)
		ledger.RollbackTxBatch(msg.Timestamp)
		return fmt.Errorf("Fail to execute transactions: %v", errs)
	}

	logger.Debug("Committing TX batch with timestamp: %v", msg.Timestamp)
	if err := ledger.CommitTxBatch(msg.Timestamp, txarr, nil); err != nil {
		logger.Debug("Rolling back TX batch with timestamp: %v", msg.Timestamp)
		ledger.RollbackTxBatch(msg.Timestamp)
		return fmt.Errorf("Fail to commit transaction to the ledger: %v", err)
	}

	return i.notifyBlockAdded(ledger)
}

func (i *Noops) notifyBlockAdded(ledger *ledger.Ledger) error {
	// TODO: Broadcast SYNC_BLOCK_ADDED to connected NVPs
	// VPs already know about this newly added block since they participate
	// in the execution. That is, they can compare their current block with
	// the network block
	// For now, send to everyone until broadcast has better discrimination
	blockHeight := ledger.GetBlockchainSize()
	logger.Debug("Preparing to broadcast with block number %v", blockHeight)
	block, err := ledger.GetBlockByNumber(blockHeight)
	if nil != err {
		return err
	}
	//delta, err := ledger.GetStateDeltaBytes(blockHeight)
	delta, err := ledger.GetStateDelta(blockHeight)
	if nil != err {
		return err
	}

	logger.Debug("Got the delta state of block number %v", blockHeight)
	data, err := proto.Marshal(&pb.BlockState{Block: block, StateDelta: delta.Marshal()})
	if err != nil {
		return fmt.Errorf("Fail to marshall BlockState structure: %v", err)
	}

	logger.Debug("Broadcasting OpenchainMessage_SYNC_BLOCK_ADDED")
	msg := &pb.OpenchainMessage{Type: pb.OpenchainMessage_SYNC_BLOCK_ADDED,
		Payload: data, Timestamp: util.CreateUtcTimestamp()}
	if errs := i.cpi.Broadcast(msg); nil != errs {
		return fmt.Errorf("Failed to broadcast with errors: %v", errs)
	}
	return nil
}

func (i *Noops) queueTransactions(txarr []*pb.Transaction) {
	i.txQ.Push(txarr)
	logger.Debug("Transaction queue size: %d", i.txQ.Size())
}
<commit_msg>fix block height bug in calls to ledger<commit_after>/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you 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 noops

import (
	"fmt"

	"github.com/golang/protobuf/proto"
	"github.com/op/go-logging"

	"github.com/openblockchain/obc-peer/openchain/consensus"
	"github.com/openblockchain/obc-peer/openchain/ledger"
	"github.com/openblockchain/obc-peer/openchain/util"
	pb "github.com/openblockchain/obc-peer/protos"
)

// =============================================================================
// Init
// =============================================================================

var logger *logging.Logger // package-level logger

func init() {
	logger = logging.MustGetLogger("consensus/noops")
}

// =============================================================================
// Structures go here
// =============================================================================

// Noops is a plugin object implementing the consensus.Consenter interface.
type Noops struct {
	cpi consensus.CPI
	txQ *util.Queue
}

var iNoops consensus.Consenter

// =============================================================================
// Constructors go here
// =============================================================================

// NewNoops is a constructor returning a consensus.Consenter object.
func NewNoops(c consensus.CPI) consensus.Consenter {
	logger.Debug("Creating a NOOPS object")
	i := &Noops{}
	i.cpi = c
	i.txQ = util.NewQueue()
	return i
}

// GetNoops returns a singleton of NOOPS
func GetNoops(c consensus.CPI) consensus.Consenter {
	if iNoops == nil {
		iNoops = NewNoops(c)
	}
	return iNoops
}

// RecvMsg is called for OpenchainMessage_CHAIN_TRANSACTION and OpenchainMessage_CONSENSUS messages.
func (i *Noops) RecvMsg(msg *pb.OpenchainMessage) error {
	logger.Debug("Handling OpenchainMessage of type: %s ", msg.Type)

	if msg.Type == pb.OpenchainMessage_CHAIN_TRANSACTION {
		if err := i.broadcastConsensusMsg(msg); nil != err {
			return err
		}
	}
	if msg.Type == pb.OpenchainMessage_CONSENSUS {
		txarr, err := i.getTransactionsFromMsg(msg)
		if nil != err {
			return err
		}
		if i.canProcess(txarr) {
			i.txQ.Push(txarr)
			return i.doTransactions(msg)
		}
		i.queueTransactions(txarr)
	}
	return nil
}

func (i *Noops) broadcastConsensusMsg(msg *pb.OpenchainMessage) error {
	t := &pb.Transaction{}
	if err := proto.Unmarshal(msg.Payload, t); err != nil {
		return fmt.Errorf("Error unmarshalling payload of received OpenchainMessage:%s.", msg.Type)
	}

	// Change the msg type to consensus and broadcast to the network so that
	// other validators may execute the transaction
	msg.Type = pb.OpenchainMessage_CONSENSUS
	logger.Debug("Broadcasting %s", msg.Type)
	txs := &pb.TransactionBlock{Transactions: []*pb.Transaction{t}}
	payload, err := proto.Marshal(txs)
	if err != nil {
		return err
	}
	msg.Payload = payload
	if errs := i.cpi.Broadcast(msg); nil != errs {
		return fmt.Errorf("Failed to broadcast with errors: %v", errs)
	}
	return nil
}

func (i *Noops) getTransactionsFromMsg(msg *pb.OpenchainMessage) ([]*pb.Transaction, error) {
	txs := &pb.TransactionBlock{}
	if err := proto.Unmarshal(msg.Payload, txs); err != nil {
		return nil, err
	}
	return txs.GetTransactions(), nil
}

func (i *Noops) getTransactionsFromQueue() []*pb.Transaction {
	len := i.txQ.Size()
	if len == 1 {
		return i.txQ.Pop().([]*pb.Transaction)
	}
	txarr := make([]*pb.Transaction, len)
	for k := 0; k < len; k++ {
		txs := i.txQ.Pop().([]*pb.Transaction)
		txarr[k] = txs[0]
	}
	return txarr
}

func (i *Noops) canProcess(txarr []*pb.Transaction) bool {
	// For NOOPS, if we have completed the sync since we last connected,
	// we can assume that we are at the current state; otherwise, we need to
	// wait for the sync process to complete before we can exec the transactions

	// TODO: Ask coordinator if we need to start sync

	return true
}

func (i *Noops) doTransactions(msg *pb.OpenchainMessage) error {
	logger.Debug("Executing transactions")
	ledger, err := ledger.GetLedger()
	if err != nil {
		return fmt.Errorf("Fail to get the ledger: %v", err)
	}
	logger.Debug("Starting TX batch with timestamp: %v", msg.Timestamp)
	if err := ledger.BeginTxBatch(msg.Timestamp); err != nil {
		return fmt.Errorf("Fail to begin transaction with the ledger: %v", err)
	}

	// Grab all transactions from the FIFO queue and run them in order
	txarr := i.getTransactionsFromQueue()
	logger.Debug("Executing batch of %d transactions", len(txarr))
	_, errs := i.cpi.ExecTXs(txarr)

	//there are n+1 elements of errors in this array. On complete success
	//they'll all be nil. In particular, the last err will be error in
	//producing the hash, if any. That's the only error we do want to check
	if errs[len(txarr)] != nil {
		logger.Debug("Rolling back TX batch with timestamp: %v", msg.Timestamp)
		ledger.RollbackTxBatch(msg.Timestamp)
		return fmt.Errorf("Fail to execute transactions: %v", errs)
	}

	logger.Debug("Committing TX batch with timestamp: %v", msg.Timestamp)
	if err := ledger.CommitTxBatch(msg.Timestamp, txarr, nil); err != nil {
		logger.Debug("Rolling back TX batch with timestamp: %v", msg.Timestamp)
		ledger.RollbackTxBatch(msg.Timestamp)
		return fmt.Errorf("Fail to commit transaction to the ledger: %v", err)
	}

	return i.notifyBlockAdded(ledger)
}

func (i *Noops) notifyBlockAdded(ledger *ledger.Ledger) error {
	// TODO: Broadcast SYNC_BLOCK_ADDED to connected NVPs
	// VPs already know about this newly added block since they participate
	// in the execution. That is, they can compare their current block with
	// the network block
	// For now, send to everyone until broadcast has better discrimination
	blockHeight := ledger.GetBlockchainSize()
	logger.Debug("Preparing to broadcast with block number %v", blockHeight)
	block, err := ledger.GetBlockByNumber(blockHeight - 1)
	if nil != err {
		return err
	}
	//delta, err := ledger.GetStateDeltaBytes(blockHeight)
	delta, err := ledger.GetStateDelta(blockHeight - 1)
	if nil != err {
		return err
	}

	logger.Debug("Got the delta state of block number %v", blockHeight)
	data, err := proto.Marshal(&pb.BlockState{Block: block, StateDelta: delta.Marshal()})
	if err != nil {
		return fmt.Errorf("Fail to marshall BlockState structure: %v", err)
	}

	logger.Debug("Broadcasting OpenchainMessage_SYNC_BLOCK_ADDED")
	msg := &pb.OpenchainMessage{Type: pb.OpenchainMessage_SYNC_BLOCK_ADDED,
		Payload: data, Timestamp: util.CreateUtcTimestamp()}
	if errs := i.cpi.Broadcast(msg); nil != errs {
		return fmt.Errorf("Failed to broadcast with errors: %v", errs)
	}
	return nil
}

func (i *Noops) queueTransactions(txarr []*pb.Transaction) {
	i.txQ.Push(txarr)
	logger.Debug("Transaction queue size: %d", i.txQ.Size())
}
<|endoftext|>


<commit_before>package tests

import (
	"encoding/json"
	"net/http"
	"net/url"

	"github.com/revel/revel"
)

type AppTest struct {
	revel.TestSuite
}

type PersonaTestUser struct {
	Assertion string `json:"assertion"`
	Audience  string `json:"audience"`
	Email     string `json:"email"`
	Pass      string `json:"pass"`
}

func (t AppTest) TestThatLoginPageWorks() {
	// Make sure empty assertion will cause an error.
	t.PostForm("/login", url.Values{
		"assertion": []string{""},
	})
	t.AssertStatus(400)

	// Ensure that incorrect audience parameter will lead to an error.
	user := t.EmailWithAssertion("https://example.com")
	t.PostForm("/login", url.Values{
		"assertion": []string{user.Assertion},
	})
	t.AssertEqual(user.Audience, "https://example.com")
	t.AssertStatus(400)

	// Check whether authentication works.
	user = t.EmailWithAssertion("http://" + revel.Config.StringDefault("http.host", "localhost"))
	t.PostForm("/login", url.Values{
		"assertion": []string{user.Assertion},
	})
	t.AssertOk()
	t.AssertContains("Login successful")

	// Make sure user is authenticated now.
	t.Get("/")
	t.AssertContains(user.Email)
}

func (t AppTest) TestThatLogoutPageWorks() {
	// Authenticating a user.
	user := t.EmailWithAssertion("http://" + revel.Config.StringDefault("http.host", "localhost"))
	t.PostForm("/login", url.Values{
		"assertion": []string{user.Assertion},
	})
	t.AssertOk()
	t.AssertContains("Login successful")

	// Make sure user is authenticated now.
	t.Get("/")
	t.AssertContains(user.Email)

	// Trying to sign out.
	t.Get("/logout")

	// Make sure user is not logged in.
	t.Get("/")
	t.AssertContains("Signin with your email")
}

// EmailWithAssertion uses personatestuser.org service for getting testing parameters.
// Audience is expected to begin with protocol, for example: "http://".
func (t AppTest) EmailWithAssertion(audience string) *PersonaTestUser {
	// Trying to get data from testing server.
	uri := "/email_with_assertion/" + url.QueryEscape(audience)
	req, err := http.NewRequest("GET", "http://personatestuser.org"+uri, nil)
	t.Assert(err == nil)
	req.URL.Opaque = uri // Use unescaped version of URI for request.
	t.MakeRequest(req)

	// Check whether response status is OK.
	revel.TRACE.Printf("PERSONA TESTING: Response of testing server is %q", t.ResponseBody)
	t.AssertOk()

	// Parsing the response from server.
	var user PersonaTestUser
	err = json.Unmarshal(t.ResponseBody, &user)
	t.Assert(err == nil)

	return &user
}
<commit_msg>Modified persona tests to reflect the latest changes<commit_after>package tests

import (
	"encoding/json"
	"net/url"

	"github.com/revel/revel"
)

type AppTest struct {
	revel.TestSuite
}

type PersonaTestUser struct {
	Assertion string `json:"assertion"`
	Audience  string `json:"audience"`
	Email     string `json:"email"`
	Pass      string `json:"pass"`
}

func (t *AppTest) TestThatLoginPageWorks() {
	// Make sure empty assertion will cause an error.
	t.PostForm("/login", url.Values{
		"assertion": []string{""},
	})
	t.AssertStatus(400)

	// Ensure that incorrect audience parameter will lead to an error.
	user := t.EmailWithAssertion("https://example.com")
	t.PostForm("/login", url.Values{
		"assertion": []string{user.Assertion},
	})
	t.AssertEqual(user.Audience, "https://example.com")
	t.AssertStatus(400)

	// Check whether authentication works.
	user = t.EmailWithAssertion("http://" + revel.Config.StringDefault("http.host", "localhost"))
	t.PostForm("/login", url.Values{
		"assertion": []string{user.Assertion},
	})
	t.AssertOk()
	t.AssertContains("Login successful")

	// Make sure user is authenticated now.
	t.Get("/")
	t.AssertContains(user.Email)
}

func (t *AppTest) TestThatLogoutPageWorks() {
	// Authenticating a user.
	user := t.EmailWithAssertion("http://" + revel.Config.StringDefault("http.host", "localhost"))
	t.PostForm("/login", url.Values{
		"assertion": []string{user.Assertion},
	})
	t.AssertOk()
	t.AssertContains("Login successful")

	// Make sure user is authenticated now.
	t.Get("/")
	t.AssertContains(user.Email)

	// Trying to sign out.
	t.Get("/logout")

	// Make sure user is not logged in.
	t.Get("/")
	t.AssertContains("Signin with your email")
}

// EmailWithAssertion uses personatestuser.org service for getting testing parameters.
// The testing service expects audience to begin with protocol, for example: "http://".
func (t *AppTest) EmailWithAssertion(audience string) *PersonaTestUser {
	// Trying to get data from testing server.
	u := "http://personatestuser.org"
	urn := "/email_with_assertion/" + url.QueryEscape(audience)

	req := t.GetCustom(u + urn)
	req.URL.Opaque = urn // Use unescaped version of URN for the request.
	req.Send()

	// Check whether response status is OK.
	revel.TRACE.Printf("PERSONA TESTING: Response of testing server is %q", t.ResponseBody)
	t.AssertOk()

	// Parsing the response from server.
	var user PersonaTestUser
	err := json.Unmarshal(t.ResponseBody, &user)
	t.Assert(err == nil)

	return &user
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/jessevdk/go-operators/types"
	"fmt"
	"github.com/jessevdk/go-flags"
	"go/ast"
	"go/build"
	"go/format"
	"go/parser"
	"go/token"
	"os"
	"path"
)

func getSources(args []string) (dirname string, files []string) {
	if len(args) == 0 {
		dirname, err := os.Getwd()

		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to obtain current working directory\n")
			os.Exit(1)
		}

		return dirname, nil
	}

	if len(args) == 1 {
		info, err := os.Stat(args[0])

		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to check file `%s': %s\n", args[0], err)
			os.Exit(1)
		}

		if info.IsDir() {
			return args[0], nil
		}
	}

	return "", args
}

func main() {
	var opts struct {
		Output  string `short:"o" long:"output" description:"Output directory (required)" required:"true"`
		Verbose bool   `short:"v" long:"verbose" description:"Enable verbose mode"`
		Package string `short:"p" long:"package" description:"Package name" default:"main"`
	}

	fp := flags.NewParser(&opts, flags.Default)
	fp.Usage = "--output OUTPUT_DIR [OPTIONS] SOURCE_DIR"

	args, err := fp.Parse()

	if err != nil {
		os.Exit(1)
	}

	if err := os.MkdirAll(opts.Output, 0766); err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create output directory: %s\n", err)
		os.Exit(1)
	}

	dirname, files := getSources(args)

	if len(dirname) != 0 {
		p, err := build.ImportDir(dirname, 0)

		if err != nil {
			fmt.Fprintf(os.Stderr, "Error while importing build: %s\n", err)
			os.Exit(1)
		}

		for _, f := range p.GoFiles {
			files = append(files, path.Join(dirname, f))
		}
	}

	fs := token.NewFileSet()
	afs := make([]*ast.File, 0, len(files))

	for _, f := range files {
		af, err := parser.ParseFile(fs, f, nil, 0)

		if err != nil {
			fmt.Fprintf(os.Stderr, "Error while parsing AST: %s\n", err)
			os.Exit(1)
		}

		afs = append(afs, af)
	}

	pkgname := path.Base(dirname)

	if len(pkgname) == 0 {
		pkgname = opts.Package
	}

	pp, err := types.Check(pkgname, fs, afs)

	if err != nil {
		fmt.Fprintf(os.Stderr, "Error while parsing: %s\n", err)
		os.Exit(1)
	}

	overloads := pp.Overloads()

	for i, f := range afs {
		f = replace(func(node ast.Node) ast.Node {
			expr, ok := node.(ast.Expr)

			if !ok {
				return node
			}

			info, ok := overloads[expr]

			if !ok {
				return node
			}

			sel := &ast.SelectorExpr{
				X:   info.Recv,
				Sel: ast.NewIdent(info.Func.Name()),
			}

			args := []ast.Expr{}

			if info.Oper != nil {
				args = append(args, info.Oper)
			}

			// Create function call expression
			call := &ast.CallExpr{
				Fun:  sel,
				Args: args,
			}

			return call
		}, f).(*ast.File)

		fn := path.Join(opts.Output, files[i])
		err := os.MkdirAll(path.Join(opts.Output, path.Dir(files[i])), 0766)

		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to create output directory: %s\n", err)
			os.Exit(1)
		}

		of, err := os.Create(fn)

		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to create output file: %s\n", err)
			os.Exit(1)
		}

		defer of.Close()

		if opts.Verbose {
			fmt.Println(fn)
		}

		format.Node(of, fs, f)
	}
}
<commit_msg>Override package name when using with files<commit_after>package main

import (
	"github.com/jessevdk/go-operators/types"
	"fmt"
	"github.com/jessevdk/go-flags"
	"go/ast"
	"go/build"
	"go/format"
	"go/parser"
	"go/token"
	"os"
	"path"
)

func getSources(args []string) (dirname string, files []string) {
	if len(args) == 0 {
		dirname, err := os.Getwd()

		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to obtain current working directory\n")
			os.Exit(1)
		}

		return dirname, nil
	}

	if len(args) == 1 {
		info, err := os.Stat(args[0])

		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to check file `%s': %s\n", args[0], err)
			os.Exit(1)
		}

		if info.IsDir() {
			return args[0], nil
		}
	}

	return "", args
}

func main() {
	var opts struct {
		Output  string `short:"o" long:"output" description:"Output directory (required)" required:"true"`
		Verbose bool   `short:"v" long:"verbose" description:"Enable verbose mode"`
		Package string `short:"p" long:"package" description:"Package name" default:"main"`
	}

	fp := flags.NewParser(&opts, flags.Default)
	fp.Usage = "--output OUTPUT_DIR [OPTIONS] SOURCE_DIR"

	args, err := fp.Parse()

	if err != nil {
		os.Exit(1)
	}

	if err := os.MkdirAll(opts.Output, 0766); err != nil {
		fmt.Fprintf(os.Stderr, "Failed to create output directory: %s\n", err)
		os.Exit(1)
	}

	dirname, files := getSources(args)

	if len(dirname) != 0 {
		p, err := build.ImportDir(dirname, 0)

		if err != nil {
			fmt.Fprintf(os.Stderr, "Error while importing build: %s\n", err)
			os.Exit(1)
		}

		for _, f := range p.GoFiles {
			files = append(files, path.Join(dirname, f))
		}
	}

	fs := token.NewFileSet()
	afs := make([]*ast.File, 0, len(files))

	for _, f := range files {
		af, err := parser.ParseFile(fs, f, nil, 0)

		if err != nil {
			fmt.Fprintf(os.Stderr, "Error while parsing AST: %s\n", err)
			os.Exit(1)
		}

		afs = append(afs, af)
	}

	pkgname := path.Base(dirname)

	if len(pkgname) == 0 || len(dirname) == 0 {
		pkgname = opts.Package
	}

	pp, err := types.Check(pkgname, fs, afs)

	if err != nil {
		fmt.Fprintf(os.Stderr, "Error while parsing: %s\n", err)
		os.Exit(1)
	}

	overloads := pp.Overloads()

	for i, f := range afs {
		f = replace(func(node ast.Node) ast.Node {
			expr, ok := node.(ast.Expr)

			if !ok {
				return node
			}

			info, ok := overloads[expr]

			if !ok {
				return node
			}

			sel := &ast.SelectorExpr{
				X:   info.Recv,
				Sel: ast.NewIdent(info.Func.Name()),
			}

			args := []ast.Expr{}

			if info.Oper != nil {
				args = append(args, info.Oper)
			}

			// Create function call expression
			call := &ast.CallExpr{
				Fun:  sel,
				Args: args,
			}

			return call
		}, f).(*ast.File)

		fn := path.Join(opts.Output, files[i])
		err := os.MkdirAll(path.Join(opts.Output, path.Dir(files[i])), 0766)

		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to create output directory: %s\n", err)
			os.Exit(1)
		}

		of, err := os.Create(fn)

		if err != nil {
			fmt.Fprintf(os.Stderr, "Failed to create output file: %s\n", err)
			os.Exit(1)
		}

		defer of.Close()

		if opts.Verbose {
			fmt.Println(fn)
		}

		format.Node(of, fs, f)
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 Richard Hawkins
//
// 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 game manages the main game loop.

package game

import (
	"fmt"
	"runtime"

	"github.com/go-gl/gl/v4.1-core/gl"
	"github.com/go-gl/glfw/v3.1/glfw"
	"github.com/hurricanerix/transylvania/display"
	"github.com/hurricanerix/transylvania/events"
	"github.com/hurricanerix/transylvania/sprite"
)

func init() {
	// GLFW event handling must run on the main OS thread
	runtime.LockOSThread()
}

// Context TODO doc
type Context struct {
	Screen *display.Context
}

// New TODO doc
func New(screen *display.Context) (Context, error) {
	return Context{
		Screen: screen,
	}, nil
}

// Main TODO doc
func (c *Context) Main(screen *display.Context) {
	// TODO: figure out why face.png loads, but not player.png
	//player, err := sprite.Load("/Users/hurricanerix/workspace/go/transylvania/examples/basic/face.png")
	player, err := sprite.Load("player.png")
	if err != nil {
		panic(err)
	}

	running := true
	for running {
		gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
		if screen.Window.ShouldClose() {
			running = !screen.Window.ShouldClose()
		}
		for _, event := range events.Get() {
			fmt.Println(event)
			if event.Action == glfw.Press && event.Key == glfw.KeyEscape {
				running = false
				event.Window.SetShouldClose(true)
			}
		}

		screen.Fill(200.0/256.0, 200/256.0, 200/256.0)
		screen.Blit(player, 320, 240)
		screen.Flip()

		glfw.PollEvents()
	}
}
<commit_msg>Fix background trans<commit_after>// Copyright 2016 Richard Hawkins
//
// 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 game manages the main game loop.

package game

import (
	"fmt"
	"runtime"

	"github.com/go-gl/gl/v4.1-core/gl"
	"github.com/go-gl/glfw/v3.1/glfw"
	"github.com/hurricanerix/transylvania/display"
	"github.com/hurricanerix/transylvania/events"
	"github.com/hurricanerix/transylvania/sprite"
)

func init() {
	// GLFW event handling must run on the main OS thread
	runtime.LockOSThread()
}

// Context TODO doc
type Context struct {
	Screen *display.Context
}

// New TODO doc
func New(screen *display.Context) (Context, error) {
	return Context{
		Screen: screen,
	}, nil
}

// Main TODO doc
func (c *Context) Main(screen *display.Context) {
	player, err := sprite.Load("player.png")
	if err != nil {
		panic(err)
	}

	running := true
	for running {
		gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
		if screen.Window.ShouldClose() {
			running = !screen.Window.ShouldClose()
		}
		for _, event := range events.Get() {
			fmt.Println(event)
			if event.Action == glfw.Press && event.Key == glfw.KeyEscape {
				running = false
				event.Window.SetShouldClose(true)
			}
		}

		screen.Fill(200.0/256.0, 200/256.0, 200/256.0)
		screen.Blit(player, 320, 240)
		screen.Flip()

		glfw.PollEvents()
	}
}
<|endoftext|>


<commit_before>package withdraw
<commit_msg>removed empty file<commit_after><|endoftext|>


<commit_before>package opts

import (
	"fmt"
	"net"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/docker/docker/pkg/parsers"
)

// ListOpts type
type ListOpts struct {
	values    []string
	validator ValidatorFctType
}

func NewListOpts(validator ValidatorFctType) ListOpts {
	return ListOpts{
		validator: validator,
	}
}

func (opts *ListOpts) String() string {
	return fmt.Sprintf("%v", []string(opts.values))
}

// Set validates if needed the input value and add it to the
// internal slice.
func (opts *ListOpts) Set(value string) error {
	if opts.validator != nil {
		v, err := opts.validator(value)
		if err != nil {
			return err
		}
		value = v
	}
	opts.values = append(opts.values, value)
	return nil
}

// Delete remove the given element from the slice.
func (opts *ListOpts) Delete(key string) {
	for i, k := range opts.values {
		if k == key {
			opts.values = append(opts.values[:i], opts.values[i+1:]...)
			return
		}
	}
}

// GetMap returns the content of values in a map in order to avoid
// duplicates.
// FIXME: can we remove this?
func (opts *ListOpts) GetMap() map[string]struct{} {
	ret := make(map[string]struct{})
	for _, k := range opts.values {
		ret[k] = struct{}{}
	}
	return ret
}

// GetAll returns the values' slice.
// FIXME: Can we remove this?
func (opts *ListOpts) GetAll() []string {
	return opts.values
}

// Get checks the existence of the given key.
func (opts *ListOpts) Get(key string) bool {
	for _, k := range opts.values {
		if k == key {
			return true
		}
	}
	return false
}

// Len returns the amount of element in the slice.
func (opts *ListOpts) Len() int {
	return len(opts.values)
}

// Validators
type ValidatorFctType func(val string) (string, error)

func ValidateAttach(val string) (string, error) {
	if val != "stdin" && val != "stdout" && val != "stderr" {
		return val, fmt.Errorf("Unsupported stream name: %s", val)
	}
	return val, nil
}

func ValidateLink(val string) (string, error) {
	if _, err := parsers.PartParser("name:alias", val); err != nil {
		return val, err
	}
	return val, nil
}

func ValidatePath(val string) (string, error) {
	var containerPath string

	if strings.Count(val, ":") > 2 {
		return val, fmt.Errorf("bad format for volumes: %s", val)
	}

	splited := strings.SplitN(val, ":", 2)
	if len(splited) == 1 {
		containerPath = splited[0]
		val = filepath.Clean(splited[0])
	} else {
		containerPath = splited[1]
		val = fmt.Sprintf("%s:%s", splited[0], filepath.Clean(splited[1]))
	}

	if !filepath.IsAbs(containerPath) {
		return val, fmt.Errorf("%s is not an absolute path", containerPath)
	}
	return val, nil
}

func ValidateEnv(val string) (string, error) {
	arr := strings.Split(val, "=")
	if len(arr) > 1 {
		return val, nil
	}
	return fmt.Sprintf("%s=%s", val, os.Getenv(val)), nil
}

func ValidateIPAddress(val string) (string, error) {
	var ip = net.ParseIP(strings.TrimSpace(val))
	if ip != nil {
		return ip.String(), nil
	}
	return "", fmt.Errorf("%s is not an ip address", val)
}

// Validates domain for resolvconf search configuration.
// A zero length domain is represented by .
func ValidateDnsSearch(val string) (string, error) {
	if val = strings.Trim(val, " "); val == "." {
		return val, nil
	}
	return validateDomain(val)
}

func validateDomain(val string) (string, error) {
	alpha := regexp.MustCompile(`[a-zA-Z]`)
	if alpha.FindString(val) == "" {
		return "", fmt.Errorf("%s is not a valid domain", val)
	}
	re := regexp.MustCompile(`^(:?(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]))(:?\.(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])))*)\.?\s*$`)
	ns := re.FindSubmatch([]byte(val))
	if len(ns) > 0 {
		return string(ns[1]), nil
	}
	return "", fmt.Errorf("%s is not a valid domain", val)
}
<commit_msg>Make --attach case-insensitive<commit_after>package opts

import (
	"fmt"
	"net"
	"os"
	"path/filepath"
	"regexp"
	"strings"

	"github.com/docker/docker/pkg/parsers"
)

// ListOpts type
type ListOpts struct {
	values    []string
	validator ValidatorFctType
}

func NewListOpts(validator ValidatorFctType) ListOpts {
	return ListOpts{
		validator: validator,
	}
}

func (opts *ListOpts) String() string {
	return fmt.Sprintf("%v", []string(opts.values))
}

// Set validates if needed the input value and add it to the
// internal slice.
func (opts *ListOpts) Set(value string) error {
	if opts.validator != nil {
		v, err := opts.validator(value)
		if err != nil {
			return err
		}
		value = v
	}
	opts.values = append(opts.values, value)
	return nil
}

// Delete remove the given element from the slice.
func (opts *ListOpts) Delete(key string) {
	for i, k := range opts.values {
		if k == key {
			opts.values = append(opts.values[:i], opts.values[i+1:]...)
			return
		}
	}
}

// GetMap returns the content of values in a map in order to avoid
// duplicates.
// FIXME: can we remove this?
func (opts *ListOpts) GetMap() map[string]struct{} {
	ret := make(map[string]struct{})
	for _, k := range opts.values {
		ret[k] = struct{}{}
	}
	return ret
}

// GetAll returns the values' slice.
// FIXME: Can we remove this?
func (opts *ListOpts) GetAll() []string {
	return opts.values
}

// Get checks the existence of the given key.
func (opts *ListOpts) Get(key string) bool {
	for _, k := range opts.values {
		if k == key {
			return true
		}
	}
	return false
}

// Len returns the amount of element in the slice.
func (opts *ListOpts) Len() int {
	return len(opts.values)
}

// Validators
type ValidatorFctType func(val string) (string, error)

func ValidateAttach(val string) (string, error) {
	s := strings.ToLower(val)
	for _, str := range []string{"stdin", "stdout", "stderr"} {
		if s == str {
			return s, nil
		}
	}
	return val, fmt.Errorf("valid streams are STDIN, STDOUT and STDERR.")
}

func ValidateLink(val string) (string, error) {
	if _, err := parsers.PartParser("name:alias", val); err != nil {
		return val, err
	}
	return val, nil
}

func ValidatePath(val string) (string, error) {
	var containerPath string

	if strings.Count(val, ":") > 2 {
		return val, fmt.Errorf("bad format for volumes: %s", val)
	}

	splited := strings.SplitN(val, ":", 2)
	if len(splited) == 1 {
		containerPath = splited[0]
		val = filepath.Clean(splited[0])
	} else {
		containerPath = splited[1]
		val = fmt.Sprintf("%s:%s", splited[0], filepath.Clean(splited[1]))
	}

	if !filepath.IsAbs(containerPath) {
		return val, fmt.Errorf("%s is not an absolute path", containerPath)
	}
	return val, nil
}

func ValidateEnv(val string) (string, error) {
	arr := strings.Split(val, "=")
	if len(arr) > 1 {
		return val, nil
	}
	return fmt.Sprintf("%s=%s", val, os.Getenv(val)), nil
}

func ValidateIPAddress(val string) (string, error) {
	var ip = net.ParseIP(strings.TrimSpace(val))
	if ip != nil {
		return ip.String(), nil
	}
	return "", fmt.Errorf("%s is not an ip address", val)
}

// Validates domain for resolvconf search configuration.
// A zero length domain is represented by .
func ValidateDnsSearch(val string) (string, error) {
	if val = strings.Trim(val, " "); val == "." {
		return val, nil
	}
	return validateDomain(val)
}

func validateDomain(val string) (string, error) {
	alpha := regexp.MustCompile(`[a-zA-Z]`)
	if alpha.FindString(val) == "" {
		return "", fmt.Errorf("%s is not a valid domain", val)
	}
	re := regexp.MustCompile(`^(:?(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9]))(:?\.(:?[a-zA-Z0-9]|(:?[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])))*)\.?\s*$`)
	ns := re.FindSubmatch([]byte(val))
	if len(ns) > 0 {
		return string(ns[1]), nil
	}
	return "", fmt.Errorf("%s is not a valid domain", val)
}
<|endoftext|>


<commit_before>package vlc

// #cgo LDFLAGS: -lvlc
// #include <vlc/vlc.h>
// #include <stdlib.h>
import "C"
import (
	"errors"
)

type ListPlayer struct {
	player *C.libvlc_media_list_player_t
	list   *MediaList
}

// NewPlayer creates an instance of a multi-media player.
func NewListPlayer() (*ListPlayer, error) {
	if instance == nil {
		return nil, errors.New("Module must be initialized first")
	}

	if player := C.libvlc_media_list_player_new(instance); player != nil {
		return &ListPlayer{player: player}, nil
	}

	return nil, getError()
}

// Release destroys the media player instance.
func (lp *ListPlayer) Release() error {
	if lp.player == nil {
		return nil
	}

	C.libvlc_media_list_player_release(lp.player)
	lp.player = nil

	return getError()
}

// Play plays the current media list.
func (lp *ListPlayer) Play() error {
	if lp.player == nil {
		return errors.New("A list player must be initialized first")
	}
	if lp.IsPlaying() {
		return nil
	}

	C.libvlc_media_list_player_play(lp.player)
	return getError()
}

// IsPlaying returns a boolean value specifying if the player is currently
// playing.
func (lp *ListPlayer) IsPlaying() bool {
	if lp.player == nil {
		return false
	}

	return C.libvlc_media_list_player_is_playing(lp.player) != 0
}

// Stop cancels the currently playing media list, if there is one.
func (lp *ListPlayer) Stop() error {
	if lp.player == nil {
		return errors.New("A list player must be initialized first")
	}
	if !lp.IsPlaying() {
		return nil
	}

	C.libvlc_media_list_player_stop(lp.player)
	return getError()
}

// TogglePause pauses/resumes the player.
// Calling this method has no effect if there is no media.
func (lp *ListPlayer) TogglePause() error {
	if lp.player == nil {
		return errors.New("A list player must be initialized first")
	}

	C.libvlc_media_list_player_pause(lp.player)
	return getError()
}

// MediaList returns the current media list of the player, if one exists
func (lp *ListPlayer) MediaList() *MediaList {
	return lp.list
}

// SetMediaList sets the media list to be played.
func (lp *ListPlayer) SetMediaList(ml *MediaList) error {
	if lp.player == nil {
		return errors.New("A list player must be initialized first")
	}
	if ml.list == nil {
		return errors.New("A media list must be initialized first")
	}

	lp.list = ml
	C.libvlc_media_list_player_set_media_list(lp.player, ml.list)

	return getError()
}
<commit_msg>Implement additional list player functions<commit_after>package vlc

// #cgo LDFLAGS: -lvlc
// #include <vlc/vlc.h>
// #include <stdlib.h>
import "C"
import (
	"errors"
)

type ListPlayer struct {
	player *C.libvlc_media_list_player_t
	list   *MediaList
}

// NewPlayer creates an instance of a multi-media player.
func NewListPlayer() (*ListPlayer, error) {
	if instance == nil {
		return nil, errors.New("Module must be initialized first")
	}

	if player := C.libvlc_media_list_player_new(instance); player != nil {
		return &ListPlayer{player: player}, nil
	}

	return nil, getError()
}

// Release destroys the media player instance.
func (lp *ListPlayer) Release() error {
	if lp.player == nil {
		return nil
	}

	C.libvlc_media_list_player_release(lp.player)
	lp.player = nil

	return getError()
}

// Play plays the current media list.
func (lp *ListPlayer) Play() error {
	if lp.player == nil {
		return errors.New("A list player must be initialized first")
	}
	if lp.IsPlaying() {
		return nil
	}

	C.libvlc_media_list_player_play(lp.player)
	return getError()
}

// PlayNext plays the next media in the current media list.
func (lp *ListPlayer) PlayNext() error {
	if lp.player == nil {
		return errors.New("A list player must be initialized first")
	}

	if C.libvlc_media_list_player_next(lp.player) < 0 {
		return getError()
	}

	return nil
}

// PlayPrevious plays the previous media in the current media list.
func (lp *ListPlayer) PlayPrevious() error {
	if lp.player == nil {
		return errors.New("A list player must be initialized first")
	}

	if C.libvlc_media_list_player_previous(lp.player) < 0 {
		return getError()
	}

	return nil
}

// PlayAtIndex plays the media at the specified index from the
// current media list.
func (lp ListPlayer) PlayAtIndex(index uint) error {
	if lp.player == nil {
		return errors.New("A list player must be initialized first")
	}

	idx := C.int(index)
	if C.libvlc_media_list_player_play_item_at_index(lp.player, idx) < 0 {
		return getError()
	}

	return nil
}

// IsPlaying returns a boolean value specifying if the player is currently
// playing.
func (lp *ListPlayer) IsPlaying() bool {
	if lp.player == nil {
		return false
	}

	return C.libvlc_media_list_player_is_playing(lp.player) != 0
}

// Stop cancels the currently playing media list, if there is one.
func (lp *ListPlayer) Stop() error {
	if lp.player == nil {
		return errors.New("A list player must be initialized first")
	}
	if !lp.IsPlaying() {
		return nil
	}

	C.libvlc_media_list_player_stop(lp.player)
	return getError()
}

// TogglePause pauses/resumes the player.
// Calling this method has no effect if there is no media.
func (lp *ListPlayer) TogglePause() error {
	if lp.player == nil {
		return errors.New("A list player must be initialized first")
	}

	C.libvlc_media_list_player_pause(lp.player)
	return getError()
}

// MediaState returns the state of the current media.
func (lp *ListPlayer) MediaState() (MediaState, error) {
	if lp.player == nil {
		return 0, errors.New("A list player must be initialized first")
	}

	state := int(C.libvlc_media_list_player_get_state(lp.player))
	return MediaState(state), getError()
}

// MediaList returns the current media list of the player, if one exists
func (lp *ListPlayer) MediaList() *MediaList {
	return lp.list
}

// SetMediaList sets the media list to be played.
func (lp *ListPlayer) SetMediaList(ml *MediaList) error {
	if lp.player == nil {
		return errors.New("A list player must be initialized first")
	}
	if ml.list == nil {
		return errors.New("A media list must be initialized first")
	}

	lp.list = ml
	C.libvlc_media_list_player_set_media_list(lp.player, ml.list)

	return getError()
}
<|endoftext|>


<commit_before>package cloudflare

import (
	"encoding/json"

	"github.com/pkg/errors"
)

// OriginCA resource
// This is the origin_ca resource definition (as defined here:
// https://api.cloudflare.com/#origin-ca || https://api.cloudflare.com/#cloudflare-ca
type OriginCA struct {
	ID              string   `json:"id"`
	Certificate     string   `json:"certificate"`
	Hostnames       []string `json:"hostnames"`
	ExpiresOn       string   `json:"expires_on"`
	RequestType     string   `json:"request_type"`
	RequestValidity string   `json:"requested_validity"`
	Csr             string   `json:"csr"`
}

// OriginCertificateID is the resource sent back for a revoke action
type OriginCertificateID struct {
	ID string `json:"id"`
}

// OriginCAResponse is the APIv4 response envelop containing the OriginCA result
type OriginCAResponse struct {
	Success  bool     `json:"success"`
	Errors   []string `json:"errors"`
	Messages []string `json:"messages"`
	Result   OriginCA `json:"result"`
}

// OriginCAResponseList is the APIv4 response envelop containing a listof OriginCA result
type OriginCAResponseList struct {
	Success    bool       `json:"success"`
	Errors     []string   `json:"errors"`
	Messages   []string   `json:"messages"`
	Result     []OriginCA `json:"result"`
	ResultInfo ResultInfo `json:"result_info"`
}

// OriginCAResponseRevoke is the APIv4 response envelop containing a revoked cert id
type OriginCAResponseRevoke struct {
	Success  bool                `json:"success"`
	Errors   []string            `json:"errors"`
	Messages []string            `json:"messages"`
	Result   OriginCertificateID `json:"result"`
}

// CreateOriginCertificate will create an origin certificate for a User
// API reference: https://api.cloudflare.com/#origin-ca-create-certificate
func (api *API) CreateOriginCertificate(certificate OriginCA) (*OriginCA, error) {
	uri := "/certificates"
	res, err := api.makeRequest("POST", uri, certificate)

	if err != nil {
		return nil, errors.Wrap(err, errMakeRequestError)
	}

	var originResponse *OriginCAResponse

	err = json.Unmarshal(res, &originResponse)

	if err != nil {
		return nil, errors.Wrap(err, errUnmarshalError)
	}

	if !originResponse.Success {
		return nil, errors.New(errRequestNotSuccessfull)
	}

	createdCert := originResponse.Result

	return &createdCert, nil
}
<commit_msg>Implement list, detail and revoke requests<commit_after>package cloudflare

import (
	"encoding/json"

	"github.com/pkg/errors"
)

// OriginCA resource
// This is the origin_ca resource definition (as defined here:
// https://api.cloudflare.com/#origin-ca || https://api.cloudflare.com/#cloudflare-ca
type OriginCA struct {
	ID              string   `json:"id"`
	Certificate     string   `json:"certificate"`
	Hostnames       []string `json:"hostnames"`
	ExpiresOn       string   `json:"expires_on"`
	RequestType     string   `json:"request_type"`
	RequestValidity string   `json:"requested_validity"`
	Csr             string   `json:"csr"`
}

// OriginCertificateID is the resource sent back for a revoke action
type OriginCertificateID struct {
	ID string `json:"id"`
}

// OriginCAResponse is the APIv4 response envelop containing the OriginCA result
type OriginCAResponse struct {
	Success  bool     `json:"success"`
	Errors   []string `json:"errors"`
	Messages []string `json:"messages"`
	Result   OriginCA `json:"result"`
}

// OriginCAResponseList is the APIv4 response envelop containing a listof OriginCA result
type OriginCAResponseList struct {
	Success    bool       `json:"success"`
	Errors     []string   `json:"errors"`
	Messages   []string   `json:"messages"`
	Result     []OriginCA `json:"result"`
	ResultInfo ResultInfo `json:"result_info"`
}

// OriginCAResponseRevoke is the APIv4 response envelop containing a revoked cert id
type OriginCAResponseRevoke struct {
	Success  bool                `json:"success"`
	Errors   []string            `json:"errors"`
	Messages []string            `json:"messages"`
	Result   OriginCertificateID `json:"result"`
}

// CreateOriginCertificate will create an origin certificate for a User
// API reference: https://api.cloudflare.com/#origin-ca-create-certificate
func (api *API) CreateOriginCertificate(certificate OriginCA) (*OriginCA, error) {
	uri := "/certificates"
	res, err := api.makeRequest("POST", uri, certificate)

	if err != nil {
		return nil, errors.Wrap(err, errMakeRequestError)
	}

	var originResponse *OriginCAResponse

	err = json.Unmarshal(res, &originResponse)

	if err != nil {
		return nil, errors.Wrap(err, errUnmarshalError)
	}

	if !originResponse.Success {
		return nil, errors.New(errRequestNotSuccessfull)
	}

	createdCert := originResponse.Result

	return &createdCert, nil
}

// OriginCertificates will list all certificates owned by the users
// API reference: https://api.cloudflare.com/#origin-ca-list-certificates
func (api *API) OriginCertificates() ([]OriginCA, error) {
	uri := "/certificates"
	res, err := api.makeRequest("GET", uri, nil)

	if err != nil {
		return nil, errors.Wrap(err, errMakeRequestError)
	}

	var originResponse *OriginCAResponseList

	err = json.Unmarshal(res, &originResponse)

	if err != nil {
		return nil, errors.Wrap(err, errUnmarshalError)
	}

	if !originResponse.Success {
		return nil, errors.New(errRequestNotSuccessfull)
	}

	return originResponse.Result, nil
}

// OriginCertificate will get the details for a given certificate
// API reference: https://api.cloudflare.com/#origin-ca-certificate-details
func (api *API) OriginCertificate(certificateID string) (*OriginCA, error) {
	uri := "/certificates/" + certificateID
	res, err := api.makeRequest("GET", uri, nil)

	if err != nil {
		return nil, errors.Wrap(err, errMakeRequestError)
	}

	var originResponse *OriginCAResponse

	err = json.Unmarshal(res, &originResponse)

	if err != nil {
		return nil, errors.Wrap(err, errUnmarshalError)
	}

	if !originResponse.Success {
		return nil, errors.New(errRequestNotSuccessfull)
	}

	return &originResponse.Result, nil
}

// RevokeOriginCertificate will revoke a given certificate
// API reference: https://api.cloudflare.com/#origin-ca-revoke-certificate
func (api *API) RevokeOriginCertificate(certificateID string) (*OriginCertificateID, error) {
	uri := "/certificates/" + certificateID
	res, err := api.makeRequest("DELETE", uri, nil)

	if err != nil {
		return nil, errors.Wrap(err, errMakeRequestError)
	}

	var originResponse *OriginCAResponseRevoke

	err = json.Unmarshal(res, &originResponse)

	if err != nil {
		return nil, errors.Wrap(err, errUnmarshalError)
	}

	if !originResponse.Success {
		return nil, errors.New(errRequestNotSuccessfull)
	}

	return &originResponse.Result, nil

}
<|endoftext|>


<commit_before>package eth

import (
	"crypto/ecdsa"
	"fmt"
	"strings"

	"github.com/ethereum/go-ethereum/core"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethdb"
	"github.com/ethereum/go-ethereum/ethutil"
	"github.com/ethereum/go-ethereum/event"
	ethlogger "github.com/ethereum/go-ethereum/logger"
	"github.com/ethereum/go-ethereum/miner"
	"github.com/ethereum/go-ethereum/p2p"
	"github.com/ethereum/go-ethereum/p2p/discover"
	"github.com/ethereum/go-ethereum/p2p/nat"
	"github.com/ethereum/go-ethereum/pow/ezp"
	"github.com/ethereum/go-ethereum/rpc"
	"github.com/ethereum/go-ethereum/whisper"
)

var (
	logger     = ethlogger.NewLogger("SERV")
	jsonlogger = ethlogger.NewJsonLogger()

	defaultBootNodes = []*discover.Node{
		discover.MustParseNode("enode://6cdd090303f394a1cac34ecc9f7cda18127eafa2a3a06de39f6d920b0e583e062a7362097c7c65ee490a758b442acd5c80c6fce4b148c6a391e946b45131365b@54.169.166.226:30303"),
	}
)

type Config struct {
	Name      string
	KeyStore  string
	DataDir   string
	LogFile   string
	LogLevel  int
	KeyRing   string
	LogFormat string

	MaxPeers int
	Port     string

	// This should be a space-separated list of
	// discovery node URLs.
	BootNodes string

	// This key is used to identify the node on the network.
	// If nil, an ephemeral key is used.
	NodeKey *ecdsa.PrivateKey

	NAT  nat.Interface
	Shh  bool
	Dial bool

	MinerThreads int

	KeyManager *crypto.KeyManager
}

func (cfg *Config) parseBootNodes() []*discover.Node {
	if cfg.BootNodes == "" {
		return defaultBootNodes
	}
	var ns []*discover.Node
	for _, url := range strings.Split(cfg.BootNodes, " ") {
		if url == "" {
			continue
		}
		n, err := discover.ParseNode(url)
		if err != nil {
			logger.Errorf("Bootstrap URL %s: %v\n", url, err)
			continue
		}
		ns = append(ns, n)
	}
	return ns
}

type Ethereum struct {
	// Channel for shutting down the ethereum
	shutdownChan chan bool
	quit         chan bool

	// DB interface
	db        ethutil.Database
	blacklist p2p.Blacklist

	//*** SERVICES ***
	// State manager for processing new blocks and managing the over all states
	blockProcessor *core.BlockProcessor
	txPool         *core.TxPool
	chainManager   *core.ChainManager
	blockPool      *BlockPool
	whisper        *whisper.Whisper

	net      *p2p.Server
	eventMux *event.TypeMux
	txSub    event.Subscription
	blockSub event.Subscription
	miner    *miner.Miner

	RpcServer  rpc.RpcServer
	WsServer   rpc.RpcServer
	keyManager *crypto.KeyManager

	logger ethlogger.LogSystem

	Mining bool
}

func New(config *Config) (*Ethereum, error) {
	// Boostrap database
	logger := ethlogger.New(config.DataDir, config.LogFile, config.LogLevel, config.LogFormat)
	db, err := ethdb.NewLDBDatabase("blockchain")
	if err != nil {
		return nil, err
	}

	// Perform database sanity checks
	d, _ := db.Get([]byte("ProtocolVersion"))
	protov := ethutil.NewValue(d).Uint()
	if protov != ProtocolVersion && protov != 0 {
		return nil, fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, ProtocolVersion, ethutil.Config.ExecPath+"/database")
	}

	// Create new keymanager
	var keyManager *crypto.KeyManager
	switch config.KeyStore {
	case "db":
		keyManager = crypto.NewDBKeyManager(db)
	case "file":
		keyManager = crypto.NewFileKeyManager(config.DataDir)
	default:
		return nil, fmt.Errorf("unknown keystore type: %s", config.KeyStore)
	}
	// Initialise the keyring
	keyManager.Init(config.KeyRing, 0, false)

	saveProtocolVersion(db)
	//ethutil.Config.Db = db

	eth := &Ethereum{
		shutdownChan: make(chan bool),
		quit:         make(chan bool),
		db:           db,
		keyManager:   keyManager,
		blacklist:    p2p.NewBlacklist(),
		eventMux:     &event.TypeMux{},
		logger:       logger,
	}

	eth.chainManager = core.NewChainManager(db, eth.EventMux())
	eth.txPool = core.NewTxPool(eth.EventMux())
	eth.blockProcessor = core.NewBlockProcessor(db, eth.txPool, eth.chainManager, eth.EventMux())
	eth.chainManager.SetProcessor(eth.blockProcessor)
	eth.whisper = whisper.New()
	eth.miner = miner.New(keyManager.Address(), eth, config.MinerThreads)

	hasBlock := eth.chainManager.HasBlock
	insertChain := eth.chainManager.InsertChain
	eth.blockPool = NewBlockPool(hasBlock, insertChain, ezp.Verify)

	ethProto := EthProtocol(eth.txPool, eth.chainManager, eth.blockPool)
	protocols := []p2p.Protocol{ethProto}
	if config.Shh {
		protocols = append(protocols, eth.whisper.Protocol())
	}

	netprv := config.NodeKey
	if netprv == nil {
		if netprv, err = crypto.GenerateKey(); err != nil {
			return nil, fmt.Errorf("could not generate server key: %v", err)
		}
	}
	eth.net = &p2p.Server{
		PrivateKey:     netprv,
		Name:           config.Name,
		MaxPeers:       config.MaxPeers,
		Protocols:      protocols,
		Blacklist:      eth.blacklist,
		NAT:            config.NAT,
		NoDial:         !config.Dial,
		BootstrapNodes: config.parseBootNodes(),
	}
	if len(config.Port) > 0 {
		eth.net.ListenAddr = ":" + config.Port
	}

	return eth, nil
}

func (s *Ethereum) KeyManager() *crypto.KeyManager       { return s.keyManager }
func (s *Ethereum) Logger() ethlogger.LogSystem          { return s.logger }
func (s *Ethereum) Name() string                         { return s.net.Name }
func (s *Ethereum) ChainManager() *core.ChainManager     { return s.chainManager }
func (s *Ethereum) BlockProcessor() *core.BlockProcessor { return s.blockProcessor }
func (s *Ethereum) TxPool() *core.TxPool                 { return s.txPool }
func (s *Ethereum) BlockPool() *BlockPool                { return s.blockPool }
func (s *Ethereum) Whisper() *whisper.Whisper            { return s.whisper }
func (s *Ethereum) EventMux() *event.TypeMux             { return s.eventMux }
func (s *Ethereum) Db() ethutil.Database                 { return s.db }
func (s *Ethereum) Miner() *miner.Miner                  { return s.miner }
func (s *Ethereum) IsListening() bool                    { return true } // Always listening
func (s *Ethereum) PeerCount() int                       { return s.net.PeerCount() }
func (s *Ethereum) Peers() []*p2p.Peer                   { return s.net.Peers() }
func (s *Ethereum) MaxPeers() int                        { return s.net.MaxPeers }
func (s *Ethereum) Coinbase() []byte                     { return nil } // TODO

// Start the ethereum
func (s *Ethereum) Start() error {
	jsonlogger.LogJson(&ethlogger.LogStarting{
		ClientString:    s.net.Name,
		ProtocolVersion: ProtocolVersion,
	})

	err := s.net.Start()
	if err != nil {
		return err
	}

	// Start services
	s.txPool.Start()
	s.blockPool.Start()

	if s.whisper != nil {
		s.whisper.Start()
	}

	// broadcast transactions
	s.txSub = s.eventMux.Subscribe(core.TxPreEvent{})
	go s.txBroadcastLoop()

	// broadcast mined blocks
	s.blockSub = s.eventMux.Subscribe(core.NewMinedBlockEvent{})
	go s.blockBroadcastLoop()

	logger.Infoln("Server started")
	return nil
}

func (self *Ethereum) SuggestPeer(nodeURL string) error {
	n, err := discover.ParseNode(nodeURL)
	if err != nil {
		return fmt.Errorf("invalid node URL: %v", err)
	}
	self.net.SuggestPeer(n)
	return nil
}

func (s *Ethereum) Stop() {
	// Close the database
	defer s.db.Close()

	close(s.quit)

	s.txSub.Unsubscribe()    // quits txBroadcastLoop
	s.blockSub.Unsubscribe() // quits blockBroadcastLoop

	if s.RpcServer != nil {
		s.RpcServer.Stop()
	}
	if s.WsServer != nil {
		s.WsServer.Stop()
	}
	s.txPool.Stop()
	s.eventMux.Stop()
	s.blockPool.Stop()
	if s.whisper != nil {
		s.whisper.Stop()
	}

	logger.Infoln("Server stopped")
	close(s.shutdownChan)
}

// This function will wait for a shutdown and resumes main thread execution
func (s *Ethereum) WaitForShutdown() {
	<-s.shutdownChan
}

// now tx broadcasting is taken out of txPool
// handled here via subscription, efficiency?
func (self *Ethereum) txBroadcastLoop() {
	// automatically stops if unsubscribe
	for obj := range self.txSub.Chan() {
		event := obj.(core.TxPreEvent)
		self.net.Broadcast("eth", TxMsg, event.Tx.RlpData())
	}
}

func (self *Ethereum) blockBroadcastLoop() {
	// automatically stops if unsubscribe
	for obj := range self.blockSub.Chan() {
		switch ev := obj.(type) {
		case core.NewMinedBlockEvent:
			self.net.Broadcast("eth", NewBlockMsg, ev.Block.RlpData(), ev.Block.Td)
		}
	}
}

func saveProtocolVersion(db ethutil.Database) {
	d, _ := db.Get([]byte("ProtocolVersion"))
	protocolVersion := ethutil.NewValue(d).Uint()

	if protocolVersion == 0 {
		db.Put([]byte("ProtocolVersion"), ethutil.NewValue(ProtocolVersion).Bytes())
	}
}
<commit_msg>eth: add poc-8.ethdev.com as second default bootstrap node<commit_after>package eth

import (
	"crypto/ecdsa"
	"fmt"
	"strings"

	"github.com/ethereum/go-ethereum/core"
	"github.com/ethereum/go-ethereum/crypto"
	"github.com/ethereum/go-ethereum/ethdb"
	"github.com/ethereum/go-ethereum/ethutil"
	"github.com/ethereum/go-ethereum/event"
	ethlogger "github.com/ethereum/go-ethereum/logger"
	"github.com/ethereum/go-ethereum/miner"
	"github.com/ethereum/go-ethereum/p2p"
	"github.com/ethereum/go-ethereum/p2p/discover"
	"github.com/ethereum/go-ethereum/p2p/nat"
	"github.com/ethereum/go-ethereum/pow/ezp"
	"github.com/ethereum/go-ethereum/rpc"
	"github.com/ethereum/go-ethereum/whisper"
)

var (
	logger     = ethlogger.NewLogger("SERV")
	jsonlogger = ethlogger.NewJsonLogger()

	defaultBootNodes = []*discover.Node{
		// ETH/DEV cmd/bootnode
		discover.MustParseNode("enode://6cdd090303f394a1cac34ecc9f7cda18127eafa2a3a06de39f6d920b0e583e062a7362097c7c65ee490a758b442acd5c80c6fce4b148c6a391e946b45131365b@54.169.166.226:30303"),
		// ETH/DEV cpp-ethereum (poc-8.ethdev.com)
		discover.MustParseNode("enode://4a44599974518ea5b0f14c31c4463692ac0329cb84851f3435e6d1b18ee4eae4aa495f846a0fa1219bd58035671881d44423876e57db2abd57254d0197da0ebe@5.1.83.226:30303"),
	}
)

type Config struct {
	Name      string
	KeyStore  string
	DataDir   string
	LogFile   string
	LogLevel  int
	KeyRing   string
	LogFormat string

	MaxPeers int
	Port     string

	// This should be a space-separated list of
	// discovery node URLs.
	BootNodes string

	// This key is used to identify the node on the network.
	// If nil, an ephemeral key is used.
	NodeKey *ecdsa.PrivateKey

	NAT  nat.Interface
	Shh  bool
	Dial bool

	MinerThreads int

	KeyManager *crypto.KeyManager
}

func (cfg *Config) parseBootNodes() []*discover.Node {
	if cfg.BootNodes == "" {
		return defaultBootNodes
	}
	var ns []*discover.Node
	for _, url := range strings.Split(cfg.BootNodes, " ") {
		if url == "" {
			continue
		}
		n, err := discover.ParseNode(url)
		if err != nil {
			logger.Errorf("Bootstrap URL %s: %v\n", url, err)
			continue
		}
		ns = append(ns, n)
	}
	return ns
}

type Ethereum struct {
	// Channel for shutting down the ethereum
	shutdownChan chan bool
	quit         chan bool

	// DB interface
	db        ethutil.Database
	blacklist p2p.Blacklist

	//*** SERVICES ***
	// State manager for processing new blocks and managing the over all states
	blockProcessor *core.BlockProcessor
	txPool         *core.TxPool
	chainManager   *core.ChainManager
	blockPool      *BlockPool
	whisper        *whisper.Whisper

	net      *p2p.Server
	eventMux *event.TypeMux
	txSub    event.Subscription
	blockSub event.Subscription
	miner    *miner.Miner

	RpcServer  rpc.RpcServer
	WsServer   rpc.RpcServer
	keyManager *crypto.KeyManager

	logger ethlogger.LogSystem

	Mining bool
}

func New(config *Config) (*Ethereum, error) {
	// Boostrap database
	logger := ethlogger.New(config.DataDir, config.LogFile, config.LogLevel, config.LogFormat)
	db, err := ethdb.NewLDBDatabase("blockchain")
	if err != nil {
		return nil, err
	}

	// Perform database sanity checks
	d, _ := db.Get([]byte("ProtocolVersion"))
	protov := ethutil.NewValue(d).Uint()
	if protov != ProtocolVersion && protov != 0 {
		return nil, fmt.Errorf("Database version mismatch. Protocol(%d / %d). `rm -rf %s`", protov, ProtocolVersion, ethutil.Config.ExecPath+"/database")
	}

	// Create new keymanager
	var keyManager *crypto.KeyManager
	switch config.KeyStore {
	case "db":
		keyManager = crypto.NewDBKeyManager(db)
	case "file":
		keyManager = crypto.NewFileKeyManager(config.DataDir)
	default:
		return nil, fmt.Errorf("unknown keystore type: %s", config.KeyStore)
	}
	// Initialise the keyring
	keyManager.Init(config.KeyRing, 0, false)

	saveProtocolVersion(db)
	//ethutil.Config.Db = db

	eth := &Ethereum{
		shutdownChan: make(chan bool),
		quit:         make(chan bool),
		db:           db,
		keyManager:   keyManager,
		blacklist:    p2p.NewBlacklist(),
		eventMux:     &event.TypeMux{},
		logger:       logger,
	}

	eth.chainManager = core.NewChainManager(db, eth.EventMux())
	eth.txPool = core.NewTxPool(eth.EventMux())
	eth.blockProcessor = core.NewBlockProcessor(db, eth.txPool, eth.chainManager, eth.EventMux())
	eth.chainManager.SetProcessor(eth.blockProcessor)
	eth.whisper = whisper.New()
	eth.miner = miner.New(keyManager.Address(), eth, config.MinerThreads)

	hasBlock := eth.chainManager.HasBlock
	insertChain := eth.chainManager.InsertChain
	eth.blockPool = NewBlockPool(hasBlock, insertChain, ezp.Verify)

	ethProto := EthProtocol(eth.txPool, eth.chainManager, eth.blockPool)
	protocols := []p2p.Protocol{ethProto}
	if config.Shh {
		protocols = append(protocols, eth.whisper.Protocol())
	}

	netprv := config.NodeKey
	if netprv == nil {
		if netprv, err = crypto.GenerateKey(); err != nil {
			return nil, fmt.Errorf("could not generate server key: %v", err)
		}
	}
	eth.net = &p2p.Server{
		PrivateKey:     netprv,
		Name:           config.Name,
		MaxPeers:       config.MaxPeers,
		Protocols:      protocols,
		Blacklist:      eth.blacklist,
		NAT:            config.NAT,
		NoDial:         !config.Dial,
		BootstrapNodes: config.parseBootNodes(),
	}
	if len(config.Port) > 0 {
		eth.net.ListenAddr = ":" + config.Port
	}

	return eth, nil
}

func (s *Ethereum) KeyManager() *crypto.KeyManager       { return s.keyManager }
func (s *Ethereum) Logger() ethlogger.LogSystem          { return s.logger }
func (s *Ethereum) Name() string                         { return s.net.Name }
func (s *Ethereum) ChainManager() *core.ChainManager     { return s.chainManager }
func (s *Ethereum) BlockProcessor() *core.BlockProcessor { return s.blockProcessor }
func (s *Ethereum) TxPool() *core.TxPool                 { return s.txPool }
func (s *Ethereum) BlockPool() *BlockPool                { return s.blockPool }
func (s *Ethereum) Whisper() *whisper.Whisper            { return s.whisper }
func (s *Ethereum) EventMux() *event.TypeMux             { return s.eventMux }
func (s *Ethereum) Db() ethutil.Database                 { return s.db }
func (s *Ethereum) Miner() *miner.Miner                  { return s.miner }
func (s *Ethereum) IsListening() bool                    { return true } // Always listening
func (s *Ethereum) PeerCount() int                       { return s.net.PeerCount() }
func (s *Ethereum) Peers() []*p2p.Peer                   { return s.net.Peers() }
func (s *Ethereum) MaxPeers() int                        { return s.net.MaxPeers }
func (s *Ethereum) Coinbase() []byte                     { return nil } // TODO

// Start the ethereum
func (s *Ethereum) Start() error {
	jsonlogger.LogJson(&ethlogger.LogStarting{
		ClientString:    s.net.Name,
		ProtocolVersion: ProtocolVersion,
	})

	err := s.net.Start()
	if err != nil {
		return err
	}

	// Start services
	s.txPool.Start()
	s.blockPool.Start()

	if s.whisper != nil {
		s.whisper.Start()
	}

	// broadcast transactions
	s.txSub = s.eventMux.Subscribe(core.TxPreEvent{})
	go s.txBroadcastLoop()

	// broadcast mined blocks
	s.blockSub = s.eventMux.Subscribe(core.NewMinedBlockEvent{})
	go s.blockBroadcastLoop()

	logger.Infoln("Server started")
	return nil
}

func (self *Ethereum) SuggestPeer(nodeURL string) error {
	n, err := discover.ParseNode(nodeURL)
	if err != nil {
		return fmt.Errorf("invalid node URL: %v", err)
	}
	self.net.SuggestPeer(n)
	return nil
}

func (s *Ethereum) Stop() {
	// Close the database
	defer s.db.Close()

	close(s.quit)

	s.txSub.Unsubscribe()    // quits txBroadcastLoop
	s.blockSub.Unsubscribe() // quits blockBroadcastLoop

	if s.RpcServer != nil {
		s.RpcServer.Stop()
	}
	if s.WsServer != nil {
		s.WsServer.Stop()
	}
	s.txPool.Stop()
	s.eventMux.Stop()
	s.blockPool.Stop()
	if s.whisper != nil {
		s.whisper.Stop()
	}

	logger.Infoln("Server stopped")
	close(s.shutdownChan)
}

// This function will wait for a shutdown and resumes main thread execution
func (s *Ethereum) WaitForShutdown() {
	<-s.shutdownChan
}

// now tx broadcasting is taken out of txPool
// handled here via subscription, efficiency?
func (self *Ethereum) txBroadcastLoop() {
	// automatically stops if unsubscribe
	for obj := range self.txSub.Chan() {
		event := obj.(core.TxPreEvent)
		self.net.Broadcast("eth", TxMsg, event.Tx.RlpData())
	}
}

func (self *Ethereum) blockBroadcastLoop() {
	// automatically stops if unsubscribe
	for obj := range self.blockSub.Chan() {
		switch ev := obj.(type) {
		case core.NewMinedBlockEvent:
			self.net.Broadcast("eth", NewBlockMsg, ev.Block.RlpData(), ev.Block.Td)
		}
	}
}

func saveProtocolVersion(db ethutil.Database) {
	d, _ := db.Get([]byte("ProtocolVersion"))
	protocolVersion := ethutil.NewValue(d).Uint()

	if protocolVersion == 0 {
		db.Put([]byte("ProtocolVersion"), ethutil.NewValue(ProtocolVersion).Bytes())
	}
}
<|endoftext|>


<commit_before>// 24 may 2014
package main

import (
	"fmt"
	"os"
	"strings"
	"go/token"
	"go/ast"
	"go/parser"
)

func main() {
	var pkg *ast.Package

	importpath := os.Args[1]

	fileset := token.NewFileSet()

	filter := func(i os.FileInfo) bool {
		return strings.HasSuffix(i.Name(), "_windows.go")
	}
	pkgs, err := parser.ParseDir(fileset, importpath,
		filter, parser.AllErrors)
	if err != nil {
		panic(err)
	}
	if len(pkgs) != 1 {
		panic("more than one package found")
	}
	for k, _ := range pkgs {		// get the sole key
		pkg = pkgs[k]
	}

	do(pkg)
}

type walker struct {
	desired	func(string) bool
}

func (w *walker) Visit(node ast.Node) ast.Visitor {
	if n, ok := node.(*ast.Ident); ok {
		if w.desired(n.Name) {
			known := "<unknown>"
			if n.Obj != nil {
				known = n.Obj.Kind.String()
			}
			fmt.Println(n.Name + "\t\t" + known)
		}
	}
	return w
}

func do(pkg *ast.Package) {
	desired := func(name string) bool {
		if strings.HasPrefix(name, "_") && len(name) > 1 {
			return !strings.ContainsAny(name,
				"abcdefghijklmnopqrstuvwxyz")
		}
		return false
	}
	for _, f := range pkg.Files {
		for _, d := range f.Decls {
			ast.Walk(&walker{desired}, d)
		}
	}
}
<commit_msg>More work on the constant generation tool. We can almost actually write the generator portion now...<commit_after>// 24 may 2014
package main

import (
//	"fmt"
	"os"
	"strings"
	"go/token"
	"go/ast"
	"go/parser"
)

func main() {
	var pkg *ast.Package

	importpath := os.Args[1]

	fileset := token.NewFileSet()

	filter := func(i os.FileInfo) bool {
		return strings.HasSuffix(i.Name(), "_windows.go")
	}
	pkgs, err := parser.ParseDir(fileset, importpath,
		filter, parser.AllErrors)
	if err != nil {
		panic(err)
	}
	if len(pkgs) != 1 {
		panic("more than one package found")
	}
	for k, _ := range pkgs {		// get the sole key
		pkg = pkgs[k]
	}

	do(pkg)
	if len(unknown) > 0 {
		s := "error: the following are still unknown!"
		for k, _ := range unknown {
			s += "\n" + k
		}
		panic(s)
	}
}

type walker struct {
	desired	func(string) bool
}

var known = map[string]string{}
var unknown = map[string]struct{}{}

func (w *walker) Visit(node ast.Node) ast.Visitor {
	if n, ok := node.(*ast.Ident); ok {
		if w.desired(n.Name) {
			if n.Obj != nil {
				delete(unknown, n.Name)
				kind := n.Obj.Kind.String()
				if known[n.Name] != "" && known[n.Name] != kind {
					panic(n.Name + "(" + kind + ") already known to be a " + known[n.Name])
				}
				known[n.Name] = kind
			} else if _, ok := known[n.Name]; !ok {		// only if not known
				unknown[n.Name] = struct{}{}
			}
		}
	}
	return w
}

func do(pkg *ast.Package) {
	desired := func(name string) bool {
		if strings.HasPrefix(name, "_") && len(name) > 1 {
			return !strings.ContainsAny(name,
				"abcdefghijklmnopqrstuvwxyz")
		}
		return false
	}
	for _, f := range pkg.Files {
		for _, d := range f.Decls {
			ast.Walk(&walker{desired}, d)
		}
	}
}
<|endoftext|>


<commit_before>package eval

import "fmt"

// constants for error types
const (
	_ int = iota
	PREFIXOP
	INFIXOP
	UNKNOWNIDENT
	NOMETHODERROR
	NOINDEXERROR
	KEYERROR
	INDEXERROR
	SLICEERROR
	ARGUMENTERROR
	INPUTERROR
	RTERROR
	CONSTRUCTERR
	ISLOOP
)

var errorType = map[int]string{
	PREFIXOP:      "unsupported operator for prefix expression:'%s' and type: %s",
	INFIXOP:       "unsupported operator for infix expression: '%s' and types %s and %s",
	UNKNOWNIDENT:  "unknown identifier: '%s' is not defined",
	NOMETHODERROR: "undefined method '%s' for object %s",
	NOINDEXERROR:  "index error: type %s is not indexable",
	KEYERROR:      "key error: type %s is not hashable",
	INDEXERROR:    "index error: '%d' out of range",
	SLICEERROR:    "index error: slice '%d:%d' out of range",
	ARGUMENTERROR: "wrong number of arguments. expected=%s, got=%d",
	INPUTERROR:    "unsupported input type '%s' for function or method: %s",
	RTERROR:       "return type should be %s",
	CONSTRUCTERR:  "%s argument for addm should be type %s. got=%s",
	ISLOOP:        "interpolated string cannot interpolate itself",
}

func newError(t int, args ...interface{}) Object {
	return &Error{Message: fmt.Sprintf(errorType[t], args...)}
}

type Error struct{ Message string }

func (e *Error) Inspect() string  { return "Err: " + e.Message }
func (e *Error) Type() ObjectType { return ERROR_OBJ }
func (e *Error) CallMethod(method string, args ...Object) Object {
	return newError(NOMETHODERROR, method, e.Type())
}
<commit_msg>removed unused error<commit_after>package eval

import "fmt"

// constants for error types
const (
	_ int = iota
	PREFIXOP
	INFIXOP
	UNKNOWNIDENT
	NOMETHODERROR
	NOINDEXERROR
	KEYERROR
	INDEXERROR
	SLICEERROR
	ARGUMENTERROR
	INPUTERROR
	RTERROR
	CONSTRUCTERR
	ISLOOP
)

var errorType = map[int]string{
	PREFIXOP:      "unsupported operator for prefix expression:'%s' and type: %s",
	INFIXOP:       "unsupported operator for infix expression: '%s' and types %s and %s",
	UNKNOWNIDENT:  "unknown identifier: '%s' is not defined",
	NOMETHODERROR: "undefined method '%s' for object %s",
	NOINDEXERROR:  "index error: type %s is not indexable",
	KEYERROR:      "key error: type %s is not hashable",
	INDEXERROR:    "index error: '%d' out of range",
	SLICEERROR:    "index error: slice '%d:%d' out of range",
	ARGUMENTERROR: "wrong number of arguments. expected=%s, got=%d",
	INPUTERROR:    "unsupported input type '%s' for function or method: %s",
	RTERROR:       "return type should be %s",
	CONSTRUCTERR:  "%s argument for addm should be type %s. got=%s",
}

func newError(t int, args ...interface{}) Object {
	return &Error{Message: fmt.Sprintf(errorType[t], args...)}
}

type Error struct{ Message string }

func (e *Error) Inspect() string  { return "Err: " + e.Message }
func (e *Error) Type() ObjectType { return ERROR_OBJ }
func (e *Error) CallMethod(method string, args ...Object) Object {
	return newError(NOMETHODERROR, method, e.Type())
}
<|endoftext|>


<commit_before>// Package event handles incremental building of a log event.
package event

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"time"
)

// Event holds a buffer of a log event content.
type Event struct {
	out      io.Writer
	buf      *bytes.Buffer
	wbuf     []byte
	maxLen   int
	exceeded bool
	prefix   []byte
	suffix   []byte
	start    chan (<-chan time.Time) // timer
	stop     chan bool
	close    chan bool
}

var autoFlushCalledHook = func() {}

// New creates an event buffer writing to the out writer on flush.
// When flush, the eol string is appended to the event content.
// When jsonKey is not empty, the output is wrapped into a JSON object
// with jsonKey as message key.
func New(out io.Writer, maxLen int, eol string, jsonKey string) *Event {
	e := &Event{
		out:    out,
		buf:    bytes.NewBuffer(make([]byte, 0, 4096)),
		wbuf:   make([]byte, 0, 2),
		maxLen: maxLen,
		start:  make(chan (<-chan time.Time)),
		stop:   make(chan bool),
		close:  make(chan bool, 1),
	}
	if jsonKey != "" {
		e.prefix = []byte(fmt.Sprintf(`{"%s":"`, jsonKey))
		e.suffix = []byte(fmt.Sprintf(`"}%s`, eol))
	} else {
		e.suffix = []byte(eol)
	}
	go e.autoFlushLoop()
	return e
}

// Empty returns true if the event's buffer is empty.
func (e *Event) Empty() bool {
	return e.buf.Len() == 0
}

// Write appends the contents of p to the buffer. The return value
// n is the length of p; err is always nil.
func (e *Event) Write(p []byte) (n int, err error) {
	if e.exceeded {
		return
	}
	overhead := len(e.prefix) + len(e.suffix)
	if e.maxLen > 0 && e.buf.Len()+overhead > e.maxLen {
		e.exceeded = true
		return
	}
	e.buf.Grow(len(p))
	for _, b := range p {
		e.wbuf = e.wbuf[:0]
		switch b {
		case '"':
			e.wbuf = append(e.wbuf, '\\', b)
		case '\\':
			e.wbuf = append(e.wbuf, `\\`...)
		case '\b':
			e.wbuf = append(e.wbuf, `\b`...)
		case '\f':
			e.wbuf = append(e.wbuf, `\f`...)
		case '\n':
			e.wbuf = append(e.wbuf, `\n`...)
		case '\r':
			e.wbuf = append(e.wbuf, `\r`...)
		case '\t':
			e.wbuf = append(e.wbuf, `\t`...)
		default:
			e.wbuf = append(e.wbuf, b)
		}
		if e.maxLen > 0 && e.buf.Len()+overhead+len(e.wbuf) > e.maxLen {
			e.exceeded = true
			break
		}
		var _n int
		_n, err = e.buf.Write(e.wbuf)
		n += _n
		if err != nil {
			break
		}
	}
	return
}

// Flush appends the eol string to the buffer and copies it to the
// output writer. The buffer is reset after this operation so the
// event can be reused.
//
// If an AutoFlush was in progress, it is stopped by this operation.
func (e *Event) Flush() {
	if e.buf.Len() == 0 {
		return
	}
	e.Stop()
	e.flush()
}

func (e *Event) flush() {
	if e.buf.Len() == 0 {
		return
	}
	if len(e.prefix) > 0 {
		if _, err := e.out.Write(e.prefix); err != nil {
			log.Fatal(err)
		}
	}
	if len(e.suffix) > 0 {
		e.buf.Write(e.suffix)
	}
	if _, err := io.Copy(e.out, e.buf); err != nil {
		log.Fatal(err)
	}
	e.buf.Reset()
	e.exceeded = false
}

// AutoFlush schedule a flush after delay.
func (e *Event) AutoFlush(delay time.Duration) {
	e.start <- time.After(delay)
}

// Stop clears the auto flush timer
func (e *Event) Stop() {
	e.stop <- true
}

// Close stops the flush loop and release release resources.
func (e *Event) Close() error {
	e.close <- true
	return nil
}

func (e *Event) autoFlushLoop() {
	paused := make(<-chan time.Time) // will never fire
	next := paused
	for {
		select {
		case <-next:
			e.flush()
			autoFlushCalledHook()
		case <-e.stop:
			next = paused
		case timer := <-e.start:
			next = timer
		case <-e.close:
			return
		}
	}
}
<commit_msg>Fix typo<commit_after>// Package event handles incremental building of a log event.
package event

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"time"
)

// Event holds a buffer of a log event content.
type Event struct {
	out      io.Writer
	buf      *bytes.Buffer
	wbuf     []byte
	maxLen   int
	exceeded bool
	prefix   []byte
	suffix   []byte
	start    chan (<-chan time.Time) // timer
	stop     chan bool
	close    chan bool
}

var autoFlushCalledHook = func() {}

// New creates an event buffer writing to the out writer on flush.
// When flush, the eol string is appended to the event content.
// When jsonKey is not empty, the output is wrapped into a JSON object
// with jsonKey as message key.
func New(out io.Writer, maxLen int, eol string, jsonKey string) *Event {
	e := &Event{
		out:    out,
		buf:    bytes.NewBuffer(make([]byte, 0, 4096)),
		wbuf:   make([]byte, 0, 2),
		maxLen: maxLen,
		start:  make(chan (<-chan time.Time)),
		stop:   make(chan bool),
		close:  make(chan bool, 1),
	}
	if jsonKey != "" {
		e.prefix = []byte(fmt.Sprintf(`{"%s":"`, jsonKey))
		e.suffix = []byte(fmt.Sprintf(`"}%s`, eol))
	} else {
		e.suffix = []byte(eol)
	}
	go e.autoFlushLoop()
	return e
}

// Empty returns true if the event's buffer is empty.
func (e *Event) Empty() bool {
	return e.buf.Len() == 0
}

// Write appends the contents of p to the buffer. The return value
// n is the length of p; err is always nil.
func (e *Event) Write(p []byte) (n int, err error) {
	if e.exceeded {
		return
	}
	overhead := len(e.prefix) + len(e.suffix)
	if e.maxLen > 0 && e.buf.Len()+overhead > e.maxLen {
		e.exceeded = true
		return
	}
	e.buf.Grow(len(p))
	for _, b := range p {
		e.wbuf = e.wbuf[:0]
		switch b {
		case '"':
			e.wbuf = append(e.wbuf, '\\', b)
		case '\\':
			e.wbuf = append(e.wbuf, `\\`...)
		case '\b':
			e.wbuf = append(e.wbuf, `\b`...)
		case '\f':
			e.wbuf = append(e.wbuf, `\f`...)
		case '\n':
			e.wbuf = append(e.wbuf, `\n`...)
		case '\r':
			e.wbuf = append(e.wbuf, `\r`...)
		case '\t':
			e.wbuf = append(e.wbuf, `\t`...)
		default:
			e.wbuf = append(e.wbuf, b)
		}
		if e.maxLen > 0 && e.buf.Len()+overhead+len(e.wbuf) > e.maxLen {
			e.exceeded = true
			break
		}
		var _n int
		_n, err = e.buf.Write(e.wbuf)
		n += _n
		if err != nil {
			break
		}
	}
	return
}

// Flush appends the eol string to the buffer and copies it to the
// output writer. The buffer is reset after this operation so the
// event can be reused.
//
// If an AutoFlush was in progress, it is stopped by this operation.
func (e *Event) Flush() {
	if e.buf.Len() == 0 {
		return
	}
	e.Stop()
	e.flush()
}

func (e *Event) flush() {
	if e.buf.Len() == 0 {
		return
	}
	if len(e.prefix) > 0 {
		if _, err := e.out.Write(e.prefix); err != nil {
			log.Fatal(err)
		}
	}
	if len(e.suffix) > 0 {
		e.buf.Write(e.suffix)
	}
	if _, err := io.Copy(e.out, e.buf); err != nil {
		log.Fatal(err)
	}
	e.buf.Reset()
	e.exceeded = false
}

// AutoFlush schedule a flush after delay.
func (e *Event) AutoFlush(delay time.Duration) {
	e.start <- time.After(delay)
}

// Stop clears the auto flush timer
func (e *Event) Stop() {
	e.stop <- true
}

// Close stops the flush loop and releases resources.
func (e *Event) Close() error {
	e.close <- true
	return nil
}

func (e *Event) autoFlushLoop() {
	paused := make(<-chan time.Time) // will never fire
	next := paused
	for {
		select {
		case <-next:
			e.flush()
			autoFlushCalledHook()
		case <-e.stop:
			next = paused
		case timer := <-e.start:
			next = timer
		case <-e.close:
			return
		}
	}
}
<|endoftext|>


<commit_before>package event

import (
	"encoding/json"

	"github.com/builderscon/octav/octav/tools"
	"github.com/pkg/errors"
)

func NewCoreAttrs(name string) *CoreAttrs {
	c := &CoreAttrs{}
	c.SetID(tools.UUID())
	c.SetName(name)
	return c
}

func (c CoreAttrs) ID() string {
	return c.id
}

func (c CoreAttrs) Name() string {
	return c.name
}

func (c *CoreAttrs) SetID(id string) {
	c.id = id
}

func (c *CoreAttrs) SetName(name string) {
	c.name = name
}

func (c *CoreAttrs) UnmarshalJSON(buf []byte) error {
	m := struct {
		ID   string `json:"id"`
		Name string `json:"name"`
	}{}

	if err := json.Unmarshal(buf, &m); err != nil {
		return errors.Wrap(err, "failed to unmarshal CoreAttrs")
	}

	c.SetID(m.ID)
	c.SetName(m.Name)
	return nil
}

func (c *CoreAttrs) MarshalJSON() ([]byte, error) {
	m := struct {
		ID   string `json:"id"`
		Name string `json:"name"`
	}{}
	m.ID = c.id
	m.Name = c.name

	buf, err := json.Marshal(&m)
	if err != nil {
		return nil, errors.Wrap(err, "failed to marshal CoreAttrs")
	}

	return buf, nil
}
<commit_msg>implement PropertyLoadServer<commit_after>package event

import (
	"encoding/json"

	"google.golang.org/cloud/datastore"

	"github.com/builderscon/octav/octav/tools"
	"github.com/pkg/errors"
)

func NewCoreAttrs(name string) *CoreAttrs {
	c := &CoreAttrs{}
	c.SetID(tools.UUID())
	c.SetName(name)
	return c
}

func (c CoreAttrs) ID() string {
	return c.id
}

func (c CoreAttrs) Name() string {
	return c.name
}

func (c *CoreAttrs) SetID(id string) {
	c.id = id
}

func (c *CoreAttrs) SetName(name string) {
	c.name = name
}

func (c *CoreAttrs) UnmarshalJSON(buf []byte) error {
	m := struct {
		ID   string `json:"id"`
		Name string `json:"name"`
	}{}

	if err := json.Unmarshal(buf, &m); err != nil {
		return errors.Wrap(err, "failed to unmarshal CoreAttrs")
	}

	c.SetID(m.ID)
	c.SetName(m.Name)
	return nil
}

func (c *CoreAttrs) MarshalJSON() ([]byte, error) {
	m := struct {
		ID   string `json:"id"`
		Name string `json:"name"`
	}{}
	m.ID = c.id
	m.Name = c.name

	buf, err := json.Marshal(&m)
	if err != nil {
		return nil, errors.Wrap(err, "failed to marshal CoreAttrs")
	}

	return buf, nil
}

func (c *CoreAttrs) Save() ([]datastore.Property, error) {
	return []datastore.Property{
		{
			Name:  "ID",
			Value: c.id,
		},
		{
			Name:  "Name",
			Value: c.name,
		},
	}, nil
}

func (c *CoreAttrs) Load(ps []datastore.Property) error {
	for _, p := range ps {
		switch p.Name {
		case "ID":
			c.id = p.Value.(string)
		case "Name":
			c.name = p.Value.(string)
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package postgres

import (
	"database/sql"

	"github.com/anthonynsimon/parrot/errors"
	"github.com/anthonynsimon/parrot/model"
)

func (db *PostgresDB) GetUser(id int) (*model.User, error) {
	u := model.User{}
	row := db.QueryRow("SELECT * FROM users WHERE id = $1", id)

	err := row.Scan(&u.ID, &u.Email, &u.Password, &u.Role)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, errors.ErrNotFound
		}
		return nil, err
	}

	return &u, nil
}

func (db *PostgresDB) GetUserByEmail(email string) (*model.User, error) {
	u := model.User{}
	row := db.QueryRow("SELECT * FROM users WHERE email = $1", email)

	err := row.Scan(&u.ID, &u.Email, &u.Password, &u.Role)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, errors.ErrNotFound
		}
		return nil, err
	}

	return &u, nil
}

func (db *PostgresDB) CreateUser(u *model.User) error {
	row := db.QueryRow("INSERT INTO users (email, password, role) VALUES($1, $2, $3) RETURNING id", u.Email, u.Password, u.Role)
	return row.Scan(&u.ID)
}

func (db *PostgresDB) UpdateUser(u *model.User) error {
	return errors.ErrInternal
}

func (db *PostgresDB) DeleteUser(id int) (int, error) {
	err := db.QueryRow("DELETE FROM users WHERE id = $1 RETURNING id", id).Scan(&id)
	if err == sql.ErrNoRows {
		return -1, errors.ErrNotFound
	}
	return id, err
}
<commit_msg>Change UpdateUser error to not implemented<commit_after>package postgres

import (
	"database/sql"

	"github.com/anthonynsimon/parrot/errors"
	"github.com/anthonynsimon/parrot/model"
)

func (db *PostgresDB) GetUser(id int) (*model.User, error) {
	u := model.User{}
	row := db.QueryRow("SELECT * FROM users WHERE id = $1", id)

	err := row.Scan(&u.ID, &u.Email, &u.Password, &u.Role)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, errors.ErrNotFound
		}
		return nil, err
	}

	return &u, nil
}

func (db *PostgresDB) GetUserByEmail(email string) (*model.User, error) {
	u := model.User{}
	row := db.QueryRow("SELECT * FROM users WHERE email = $1", email)

	err := row.Scan(&u.ID, &u.Email, &u.Password, &u.Role)
	if err != nil {
		if err == sql.ErrNoRows {
			return nil, errors.ErrNotFound
		}
		return nil, err
	}

	return &u, nil
}

func (db *PostgresDB) CreateUser(u *model.User) error {
	row := db.QueryRow("INSERT INTO users (email, password, role) VALUES($1, $2, $3) RETURNING id", u.Email, u.Password, u.Role)
	return row.Scan(&u.ID)
}

func (db *PostgresDB) UpdateUser(u *model.User) error {
	return errors.ErrNotImplemented
}

func (db *PostgresDB) DeleteUser(id int) (int, error) {
	err := db.QueryRow("DELETE FROM users WHERE id = $1 RETURNING id", id).Scan(&id)
	if err == sql.ErrNoRows {
		return -1, errors.ErrNotFound
	}
	return id, err
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"encoding/json"
	"flag"
	"fmt"
	"github.com/julienschmidt/httprouter"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"
)

var (
	config   *Config
	info     *log.Logger
	nucleus  string
	metadata Metadata = Metadata{
		Name:        "cfg",
		Version:     "0.1",
		Description: "./README.md",
		Copyright:   "Copyright 2017 Holmes Group LLC",
		License:     "./LICENSE",
	}
)

type Arc struct {
	Tail       string  `json:"tail"`
	Head       string  `json:"head"`
	Label      string  `json:"label"`
}

type Result struct {
	Truncated  bool    `json:"truncated"`
	Arcs       []*Arc  `json:"arcs"`
}

type Config struct {
	HTTPBinding        string
	MaxNumberOfArcs    int
}

type Metadata struct {
	Name        string
	Version     string
	Description string
	Copyright   string
	License     string
}

func handler_info(f_response http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	fmt.Fprintf(f_response, `
%s - %s

%s

%s

		`,
		metadata.Name,
		metadata.Version,
		metadata.Description,
		metadata.License)
}

// Parse a configuration file into a Config structure.
func load_config(configPath string) (*Config, error) {
	config := &Config{}

	// if no path is supplied look in the current dir
	if configPath == "" {
		configPath, _ = filepath.Abs(filepath.Dir(os.Args[0]))
		configPath += "/service.conf"
	}

	cfile, _ := os.Open(configPath)
	if err := json.NewDecoder(cfile).Decode(&config); err != nil {
		return config, err
	}

	if metadata.Description != "" {
		if data, err := ioutil.ReadFile(string(metadata.Description)); err == nil {
			metadata.Description = strings.Replace(string(data), "\n", "
", -1)
		}
	}

	if metadata.License != "" {
		if data, err := ioutil.ReadFile(string(metadata.License)); err == nil {
			metadata.License = strings.Replace(string(data), "\n", "
", -1)
		}
	}

	return config, nil
}

func check(err error) {
	if err != nil {
		fmt.Println(err)
		return
	}
}

func deleteFile(path string) {
	var err = os.Remove(path)
	check(err)
}

func split(r rune) bool {
	return r == '>' || r == '['
}

func handler_analyze(f_response http.ResponseWriter, request *http.Request, params httprouter.Params) {
	info.Println("Serving request:", request)
	start_time := time.Now()

	obj := request.URL.Query().Get("obj")
	if obj == "" {
		http.Error(f_response, "Missing argument 'obj'", 400)
		return
	}
	sample_path := "/tmp/" + obj
	if _, err := os.Stat(sample_path); os.IsNotExist(err) {
		http.NotFound(f_response, request)
		info.Printf("Error accessing sample (file: %s):", sample_path)
		info.Println(err)
		return
	}

	process := exec.Command(nucleus, "-a x86", "-d linear", "-f", "-p", "-e", sample_path, "-g", sample_path + ".dot")

	// We are not interested in the output of the command, but the written output in the dot files
	// stdout, err := process.StdoutPipe()
	// check(err)

	stdin, err := process.StdinPipe()
	check(err)
	stdin.Close()

	check(process.Start())

	file, err := os.Open(sample_path + ".dot")
	check(err)
	defer file.Close()

	line := bufio.NewScanner(file)

	result := &Result{
		Truncated:   false,
		Arcs:        make([]*Arc, config.MaxNumberOfArcs),
	}

	/* Example file
	digraph G {

	bb_401000 -> bb_40e716 [ label="jmp" ];
	bb_401010 -> bb_40e716 [ label="call" ];
	bb_401010 -> bb_40101e [ label="fallthrough" ];
	bb_40101e -> bb_40102b [ label="jmp/+3" ];
	[...]
	}
	 */

	// Sanity check for the first line
	line.Scan()
	if line.Text() != "digraph G {" {
		http.Error(f_response, "Executing nucleus failed", 500)
		info.Printf("First line failed check: %s", line.Text())
		return
	}

	counter := 0

	for line.Scan() {
		if (line.Text() == "}") || (line.Text() == "") {
			continue
		}

		a := strings.FieldsFunc(line.Text(), split)
		t := strings.TrimSpace(strings.TrimSuffix(a[0], "-"))
		h := strings.TrimSpace(a[1])
		l := strings.TrimSuffix(strings.TrimPrefix(strings.TrimSpace(a[2]), "label=\""), "\" ];")

		result.Arcs[counter] = &Arc{
			Tail:  t,
			Head:  h,
			Label: l,
		}

		counter++

		if counter == config.MaxNumberOfArcs {
			result.Truncated = true
			break
		}
	}

	if result.Truncated {
		// if we reach the max amount of arcs and break, we'll need to throw the rest away
		for line.Text() != "" {
			line.Scan()
		}
	} else {
		// if not, we'll need to throw away the unused array slices
		result.Arcs = result.Arcs[:counter]
	}

	f_response.Header().Set("Content-Type", "text/json; charset=utf-8")
	json2http := json.NewEncoder(f_response)

	if err := json2http.Encode(result); err != nil {
		http.Error(f_response, "Generating JSON failed", 500)
		return
	}

	deleteFile(sample_path + ".dot")

	elapsed_time := time.Since(start_time)
	info.Printf("Elapsed time: %s\n", elapsed_time)
}

func main() {
	var (
		err        error
		configPath string
	)

	// setup logging
	info = log.New(os.Stdout, "", log.Ltime|log.Lshortfile)

	// load config
	flag.StringVar(&configPath, "config", "", "Path to the configuration file")
	flag.Parse()

	config, err = load_config(configPath)
	if err != nil {
		log.Fatalln("Couldn't decode config file without errors!", err.Error())
	}

	// find nucleus binary path
	if binary, err := exec.LookPath("nucleus"); err != nil {
		log.Fatalln("Unable to locate nucleus binary, is nucleus installed?", err)
	} else {
		nucleus = binary
	}

	// setup http handlers
	router := httprouter.New()
	router.GET("/analyze/", handler_analyze)
	router.GET("/", handler_info)

	info.Printf("Binding to %s\n", config.HTTPBinding)
	log.Fatal(http.ListenAndServe(config.HTTPBinding, router))
}
<commit_msg>Update cfg.go<commit_after>package main

import (
	"bufio"
	"encoding/json"
	"flag"
	"fmt"
	"github.com/julienschmidt/httprouter"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
	"time"
)

var (
	config   *Config
	info     *log.Logger
	nucleus  string
	metadata Metadata = Metadata{
		Name:        "cfg",
		Version:     "0.1",
		Description: "./README.md",
		Copyright:   "Copyright 2017 Holmes Group LLC",
		License:     "./LICENSE",
	}
)

type Arc struct {
	Tail       string  `json:"tail"`
	Head       string  `json:"head"`
	Label      string  `json:"label"`
}

type Result struct {
	Truncated  bool    `json:"truncated"`
	Arcs       []*Arc  `json:"arcs"`
}

type Config struct {
	HTTPBinding        string
	MaxNumberOfArcs    int
}

type Metadata struct {
	Name        string
	Version     string
	Description string
	Copyright   string
	License     string
}

func handler_info(f_response http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	fmt.Fprintf(f_response, `
%s - %s

%s

%s

		`,
		metadata.Name,
		metadata.Version,
		metadata.Description,
		metadata.License)
}

// Parse a configuration file into a Config structure.
func load_config(configPath string) (*Config, error) {
	config := &Config{}

	// if no path is supplied look in the current dir
	if configPath == "" {
		configPath, _ = filepath.Abs(filepath.Dir(os.Args[0]))
		configPath += "/service.conf"
	}

	cfile, _ := os.Open(configPath)
	if err := json.NewDecoder(cfile).Decode(&config); err != nil {
		return config, err
	}

	if metadata.Description != "" {
		if data, err := ioutil.ReadFile(string(metadata.Description)); err == nil {
			metadata.Description = strings.Replace(string(data), "\n", "
", -1)
		}
	}

	if metadata.License != "" {
		if data, err := ioutil.ReadFile(string(metadata.License)); err == nil {
			metadata.License = strings.Replace(string(data), "\n", "
", -1)
		}
	}

	return config, nil
}

func check(err error) {
	if err != nil {
		fmt.Println(err)
		return
	}
}

func deleteFile(path string) {
	var err = os.Remove(path)
	check(err)
}

func split(r rune) bool {
	return r == '>' || r == '['
}

func handler_analyze(f_response http.ResponseWriter, request *http.Request, params httprouter.Params) {
	info.Println("Serving request:", request)
	start_time := time.Now()

	obj := request.URL.Query().Get("obj")
	if obj == "" {
		http.Error(f_response, "Missing argument 'obj'", 400)
		return
	}
	sample_path := "/tmp/" + obj
	if _, err := os.Stat(sample_path); os.IsNotExist(err) {
		http.NotFound(f_response, request)
		info.Printf("Error accessing sample (file: %s):", sample_path)
		info.Println(err)
		return
	}

	process := exec.Command(nucleus, "-a x86", "-d linear", "-f", "-p", "-e", sample_path, "-g", sample_path + ".dot")

	// We are not interested in the output of the command, but the written output in the dot files
	// stdout, err := process.StdoutPipe()
	// check(err)

	stdin, err := process.StdinPipe()
	check(err)
	stdin.Close()

	check(process.Start())

	file, err := os.Open(sample_path + ".dot")
	check(err)
	defer file.Close()

	line := bufio.NewScanner(file)

	result := &Result{
		Truncated:   false,
		Arcs:        make([]*Arc, config.MaxNumberOfArcs),
	}

	/* Example file
	digraph G {

	bb_401000 -> bb_40e716 [ label="jmp" ];
	bb_401010 -> bb_40e716 [ label="call" ];
	bb_401010 -> bb_40101e [ label="fallthrough" ];
	bb_40101e -> bb_40102b [ label="jmp/+3" ];
	[...]
	}
	 */

	// Sanity check for the first line
	line.Scan()
	if line.Text() != "digraph G {" {
		http.Error(f_response, "Executing nucleus failed", 500)
		info.Printf("First line failed check: %s", line.Text())
		return
	}

	counter := 0

	for line.Scan() {
		if (line.Text() == "}") || (line.Text() == "") {
			continue
		}

		a := strings.FieldsFunc(line.Text(), split)
		t := strings.TrimSpace(strings.TrimSuffix(a[0], "-"))
		h := strings.TrimSpace(a[1])
		l := strings.TrimSuffix(strings.TrimPrefix(strings.TrimSpace(a[2]), "label=\""), "\" ];")

		result.Arcs[counter] = &Arc{
			Tail:  t,
			Head:  h,
			Label: l,
		}

		counter++

		if counter == config.MaxNumberOfArcs {
			result.Truncated = true
			break
		}
	}

	if result.Truncated {
		// if we reach the max amount of arcs and break, we'll need to throw the rest away
		for line.Text() != "" {
			line.Scan()
		}
	} else {
		// if not, we'll need to throw away the unused array slices
		result.Arcs = result.Arcs[:counter]
	}

	f_response.Header().Set("Content-Type", "text/json; charset=utf-8")
	json2http := json.NewEncoder(f_response)

	if err := json2http.Encode(result); err != nil {
		http.Error(f_response, "Generating JSON failed", 500)
		return
	}

	deleteFile(sample_path + ".dot")

	elapsed_time := time.Since(start_time)
	info.Printf("Elapsed time: %s\n", elapsed_time)
}

func main() {
	var (
		err        error
		configPath string
	)

	// setup logging
	info = log.New(os.Stdout, "", log.Ltime|log.Lshortfile)

	// load config
	flag.StringVar(&configPath, "config", "", "Path to the configuration file")
	flag.Parse()

	config, err = load_config(configPath)
	if err != nil {
		log.Fatalln("Couldn't decode config file without errors!", err.Error())
	}

	// set nucleus binary path
	nucleus = "./nucleus/nucleus"

	// setup http handlers
	router := httprouter.New()
	router.GET("/analyze/", handler_analyze)
	router.GET("/", handler_info)

	info.Printf("Binding to %s\n", config.HTTPBinding)
	log.Fatal(http.ListenAndServe(config.HTTPBinding, router))
}
<|endoftext|>