<commit_before>package pushtx

import (
	"errors"
	"fmt"
	"sync"
	"time"

	"github.com/btcsuite/btcd/chaincfg/chainhash"
	"github.com/btcsuite/btcd/wire"
	"github.com/btcsuite/btcwallet/wtxmgr"
	"github.com/lightninglabs/neutrino/blockntfns"
)

var (
	// ErrBroadcastStopped is an error returned when we attempt to process a
	// request to broadcast a transaction but the Broadcaster has already
	// been stopped.
	ErrBroadcasterStopped = errors.New("broadcaster has been stopped")
)

const (
	// DefaultRebroadcastInterval is the default period that we'll wait
	// between blocks to attempt another rebroadcast.
	DefaultRebroadcastInterval = time.Minute
)

// broadcastReq is an internal message the Broadcaster will use to process
// transaction broadcast requests.
type broadcastReq struct {
	tx      *wire.MsgTx
	errChan chan error
}

// Config contains all of the external dependencies required for the Broadcaster
// to properly carry out its duties.
type Config struct {
	// Broadcast broadcasts a transaction to the network. We expect certain
	// BroadcastError's to be returned to handle special cases, namely
	// errors with the codes Mempool and Confirmed.
	Broadcast func(*wire.MsgTx) error

	// SubscribeBlocks returns a block subscription that delivers block
	// notifications in order. This will be used to rebroadcast all
	// transactions once a new block arrives.
	SubscribeBlocks func() (*blockntfns.Subscription, error)

	// RebroadcastInterval is the interval that we'll continually try to
	// re-broadcast transactions in-between new block arrival.
	RebroadcastInterval time.Duration
}

// Broadcaster is a subsystem responsible for reliably broadcasting transactions
// to the network. Each transaction will be rebroadcast upon every new block
// being connected/disconnected to/from the chain.
type Broadcaster struct {
	start sync.Once
	stop  sync.Once

	cfg Config

	// broadcastReqs is a channel through which new transaction broadcast
	// requests from external callers will be streamed through.
	broadcastReqs chan *broadcastReq

	quit chan struct{}
	wg   sync.WaitGroup
}

// NewBroadcaster creates a new Broadcaster backed by the given config.
func NewBroadcaster(cfg *Config) *Broadcaster {
	b := &Broadcaster{
		cfg:           *cfg,
		broadcastReqs: make(chan *broadcastReq),
		quit:          make(chan struct{}),
	}

	return b
}

// Start starts all of the necessary steps for the Broadcaster to begin properly
// carrying out its duties.
func (b *Broadcaster) Start() error {
	var err error
	b.start.Do(func() {
		sub, err := b.cfg.SubscribeBlocks()
		if err != nil {
			err = fmt.Errorf("unable to subscribe for block "+
				"notifications: %v", err)
			return
		}

		b.wg.Add(1)
		go b.broadcastHandler(sub)
	})
	return err
}

// Stop halts the Broadcaster from rebroadcasting pending transactions.
func (b *Broadcaster) Stop() {
	b.stop.Do(func() {
		close(b.quit)
		b.wg.Wait()
	})
}

// broadcastHandler is the main event handler of the Broadcaster responsible for
// handling new broadcast requests, rebroadcasting transactions upon every new
// block, etc.
//
// NOTE: This must be run as a goroutine.
func (b *Broadcaster) broadcastHandler(sub *blockntfns.Subscription) {
	defer b.wg.Done()
	defer sub.Cancel()

	log.Infof("Broadcaster now active")

	// transactions is the set of transactions we have broadcast so far,
	// and are still not confirmed.
	transactions := make(map[chainhash.Hash]*wire.MsgTx)

	// confChan is a channel used to notify the broadcast handler about
	// confirmed transactions.
	confChan := make(chan chainhash.Hash)

	// The rebroadcast semaphore is used to ensure we have only one
	// rebroadcast running at a time.
	rebroadcastSem := make(chan struct{}, 1)
	rebroadcastSem <- struct{}{}

	// triggerRebroadcast is a helper method that checks whether the
	// rebroadcast semaphore is available, and if it is spawns a goroutine
	// to rebroadcast all pending transactions.
	triggerRebroadcast := func() {
		select {
		// If the rebroadcast semaphore is available, start a
		// new goroutine to exectue a rebroadcast.
		case <-rebroadcastSem:
		default:
			log.Debugf("Existing rebroadcast still in " +
				"progress")
			return
		}

		// Make a copy of the current set of transactions to hand to
		// the goroutine.
		txs := make(map[chainhash.Hash]*wire.MsgTx)
		for k, v := range transactions {
			txs[k] = v.Copy()
		}

		b.wg.Add(1)
		go func() {
			defer b.wg.Done()

			b.rebroadcast(txs, confChan)
			rebroadcastSem <- struct{}{}
		}()

	}

	reBroadcastTicker := time.NewTicker(b.cfg.RebroadcastInterval)
	defer reBroadcastTicker.Stop()

	for {
		select {
		// A new broadcast request was submitted by an external caller.
		case req := <-b.broadcastReqs:
			err := b.cfg.Broadcast(req.tx)
			if err != nil && !IsBroadcastError(err, Mempool) {
				log.Errorf("Broadcast attempt failed: %v", err)
				req.errChan <- err
				continue
			}

			transactions[req.tx.TxHash()] = req.tx
			req.errChan <- nil

		// A tx was confirmed, and we can remove it from our set of
		// transactions.
		case txHash := <-confChan:
			delete(transactions, txHash)

		// A new block notification has arrived, so we'll rebroadcast
		// all of our pending transactions.
		case _, ok := <-sub.Notifications:
			if !ok {
				log.Warn("Unable to rebroadcast transactions: " +
					"block subscription was canceled")
				continue
			}
			triggerRebroadcast()

		// Between blocks, we'll also try to attempt additional
		// re-broadcasts to ensure a timely confirmation.
		case <-reBroadcastTicker.C:
			triggerRebroadcast()

		case <-b.quit:
			return
		}
	}
}

// rebroadcast rebroadcasts all of the currently pending transactions. Care has
// been taken to ensure that the transactions are sorted in their dependency
// order to prevent peers from deeming our transactions as invalid due to
// broadcasting them before their pending dependencies.
func (b *Broadcaster) rebroadcast(txs map[chainhash.Hash]*wire.MsgTx,
	confChan chan<- chainhash.Hash) {

	// Return immediately if there are no transactions to re-broadcast.
	if len(txs) == 0 {
		return
	}

	log.Debugf("Re-broadcasting %d transactions", len(txs))

	sortedTxs := wtxmgr.DependencySort(txs)
	for _, tx := range sortedTxs {
		// Before attempting to broadcast this transaction, we check
		// whether we are shutting down.
		select {
		case <-b.quit:
			return
		default:
		}

		err := b.cfg.Broadcast(tx)
		switch {
		// If the transaction has already confirmed on-chain, we can
		// stop broadcasting it further.
		//
		// TODO(wilmer); This should ideally be implemented by checking
		// the chain ourselves rather than trusting our peers.
		case IsBroadcastError(err, Confirmed):
			log.Debugf("Re-broadcast of txid=%v, now confirmed!",
				tx.TxHash())

			select {
			case confChan <- tx.TxHash():
			case <-b.quit:
				return
			}
			continue

		// If the transaction already exists within our peers' mempool,
		// we'll continue to rebroadcast it to ensure it actually
		// propagates throughout the network.
		//
		// TODO(wilmer): Rate limit peers that have already accepted our
		// transaction into their mempool to prevent resending to them
		// every time.
		case IsBroadcastError(err, Mempool):
			log.Debugf("Re-broadcast of txid=%v, still "+
				"pending...", tx.TxHash())

			continue

		case err != nil:
			log.Errorf("Unable to rebroadcast transaction %v: %v",
				tx.TxHash(), err)
			continue
		}
	}
}

// Broadcast submits a request to the Broadcaster to reliably broadcast the
// given transaction. An error won't be returned if the transaction already
// exists within the mempool. Any transaction broadcast through this method will
// be rebroadcast upon every change of the tip of the chain.
func (b *Broadcaster) Broadcast(tx *wire.MsgTx) error {
	errChan := make(chan error, 1)

	select {
	case b.broadcastReqs <- &broadcastReq{
		tx:      tx,
		errChan: errChan,
	}:
	case <-b.quit:
		return ErrBroadcasterStopped
	}

	select {
	case err := <-errChan:
		return err
	case <-b.quit:
		return ErrBroadcasterStopped
	}
}
<commit_msg>pushtx: demote existing rebroadcast log to trace<commit_after>package pushtx

import (
	"errors"
	"fmt"
	"sync"
	"time"

	"github.com/btcsuite/btcd/chaincfg/chainhash"
	"github.com/btcsuite/btcd/wire"
	"github.com/btcsuite/btcwallet/wtxmgr"
	"github.com/lightninglabs/neutrino/blockntfns"
)

var (
	// ErrBroadcastStopped is an error returned when we attempt to process a
	// request to broadcast a transaction but the Broadcaster has already
	// been stopped.
	ErrBroadcasterStopped = errors.New("broadcaster has been stopped")
)

const (
	// DefaultRebroadcastInterval is the default period that we'll wait
	// between blocks to attempt another rebroadcast.
	DefaultRebroadcastInterval = time.Minute
)

// broadcastReq is an internal message the Broadcaster will use to process
// transaction broadcast requests.
type broadcastReq struct {
	tx      *wire.MsgTx
	errChan chan error
}

// Config contains all of the external dependencies required for the Broadcaster
// to properly carry out its duties.
type Config struct {
	// Broadcast broadcasts a transaction to the network. We expect certain
	// BroadcastError's to be returned to handle special cases, namely
	// errors with the codes Mempool and Confirmed.
	Broadcast func(*wire.MsgTx) error

	// SubscribeBlocks returns a block subscription that delivers block
	// notifications in order. This will be used to rebroadcast all
	// transactions once a new block arrives.
	SubscribeBlocks func() (*blockntfns.Subscription, error)

	// RebroadcastInterval is the interval that we'll continually try to
	// re-broadcast transactions in-between new block arrival.
	RebroadcastInterval time.Duration
}

// Broadcaster is a subsystem responsible for reliably broadcasting transactions
// to the network. Each transaction will be rebroadcast upon every new block
// being connected/disconnected to/from the chain.
type Broadcaster struct {
	start sync.Once
	stop  sync.Once

	cfg Config

	// broadcastReqs is a channel through which new transaction broadcast
	// requests from external callers will be streamed through.
	broadcastReqs chan *broadcastReq

	quit chan struct{}
	wg   sync.WaitGroup
}

// NewBroadcaster creates a new Broadcaster backed by the given config.
func NewBroadcaster(cfg *Config) *Broadcaster {
	b := &Broadcaster{
		cfg:           *cfg,
		broadcastReqs: make(chan *broadcastReq),
		quit:          make(chan struct{}),
	}

	return b
}

// Start starts all of the necessary steps for the Broadcaster to begin properly
// carrying out its duties.
func (b *Broadcaster) Start() error {
	var err error
	b.start.Do(func() {
		sub, err := b.cfg.SubscribeBlocks()
		if err != nil {
			err = fmt.Errorf("unable to subscribe for block "+
				"notifications: %v", err)
			return
		}

		b.wg.Add(1)
		go b.broadcastHandler(sub)
	})
	return err
}

// Stop halts the Broadcaster from rebroadcasting pending transactions.
func (b *Broadcaster) Stop() {
	b.stop.Do(func() {
		close(b.quit)
		b.wg.Wait()
	})
}

// broadcastHandler is the main event handler of the Broadcaster responsible for
// handling new broadcast requests, rebroadcasting transactions upon every new
// block, etc.
//
// NOTE: This must be run as a goroutine.
func (b *Broadcaster) broadcastHandler(sub *blockntfns.Subscription) {
	defer b.wg.Done()
	defer sub.Cancel()

	log.Infof("Broadcaster now active")

	// transactions is the set of transactions we have broadcast so far,
	// and are still not confirmed.
	transactions := make(map[chainhash.Hash]*wire.MsgTx)

	// confChan is a channel used to notify the broadcast handler about
	// confirmed transactions.
	confChan := make(chan chainhash.Hash)

	// The rebroadcast semaphore is used to ensure we have only one
	// rebroadcast running at a time.
	rebroadcastSem := make(chan struct{}, 1)
	rebroadcastSem <- struct{}{}

	// triggerRebroadcast is a helper method that checks whether the
	// rebroadcast semaphore is available, and if it is spawns a goroutine
	// to rebroadcast all pending transactions.
	triggerRebroadcast := func() {
		select {
		// If the rebroadcast semaphore is available, start a
		// new goroutine to exectue a rebroadcast.
		case <-rebroadcastSem:
		default:
			log.Tracef("Existing rebroadcast still in " +
				"progress")
			return
		}

		// Make a copy of the current set of transactions to hand to
		// the goroutine.
		txs := make(map[chainhash.Hash]*wire.MsgTx)
		for k, v := range transactions {
			txs[k] = v.Copy()
		}

		b.wg.Add(1)
		go func() {
			defer b.wg.Done()

			b.rebroadcast(txs, confChan)
			rebroadcastSem <- struct{}{}
		}()

	}

	reBroadcastTicker := time.NewTicker(b.cfg.RebroadcastInterval)
	defer reBroadcastTicker.Stop()

	for {
		select {
		// A new broadcast request was submitted by an external caller.
		case req := <-b.broadcastReqs:
			err := b.cfg.Broadcast(req.tx)
			if err != nil && !IsBroadcastError(err, Mempool) {
				log.Errorf("Broadcast attempt failed: %v", err)
				req.errChan <- err
				continue
			}

			transactions[req.tx.TxHash()] = req.tx
			req.errChan <- nil

		// A tx was confirmed, and we can remove it from our set of
		// transactions.
		case txHash := <-confChan:
			delete(transactions, txHash)

		// A new block notification has arrived, so we'll rebroadcast
		// all of our pending transactions.
		case _, ok := <-sub.Notifications:
			if !ok {
				log.Warn("Unable to rebroadcast transactions: " +
					"block subscription was canceled")
				continue
			}
			triggerRebroadcast()

		// Between blocks, we'll also try to attempt additional
		// re-broadcasts to ensure a timely confirmation.
		case <-reBroadcastTicker.C:
			triggerRebroadcast()

		case <-b.quit:
			return
		}
	}
}

// rebroadcast rebroadcasts all of the currently pending transactions. Care has
// been taken to ensure that the transactions are sorted in their dependency
// order to prevent peers from deeming our transactions as invalid due to
// broadcasting them before their pending dependencies.
func (b *Broadcaster) rebroadcast(txs map[chainhash.Hash]*wire.MsgTx,
	confChan chan<- chainhash.Hash) {

	// Return immediately if there are no transactions to re-broadcast.
	if len(txs) == 0 {
		return
	}

	log.Debugf("Re-broadcasting %d transactions", len(txs))

	sortedTxs := wtxmgr.DependencySort(txs)
	for _, tx := range sortedTxs {
		// Before attempting to broadcast this transaction, we check
		// whether we are shutting down.
		select {
		case <-b.quit:
			return
		default:
		}

		err := b.cfg.Broadcast(tx)
		switch {
		// If the transaction has already confirmed on-chain, we can
		// stop broadcasting it further.
		//
		// TODO(wilmer); This should ideally be implemented by checking
		// the chain ourselves rather than trusting our peers.
		case IsBroadcastError(err, Confirmed):
			log.Debugf("Re-broadcast of txid=%v, now confirmed!",
				tx.TxHash())

			select {
			case confChan <- tx.TxHash():
			case <-b.quit:
				return
			}
			continue

		// If the transaction already exists within our peers' mempool,
		// we'll continue to rebroadcast it to ensure it actually
		// propagates throughout the network.
		//
		// TODO(wilmer): Rate limit peers that have already accepted our
		// transaction into their mempool to prevent resending to them
		// every time.
		case IsBroadcastError(err, Mempool):
			log.Debugf("Re-broadcast of txid=%v, still "+
				"pending...", tx.TxHash())

			continue

		case err != nil:
			log.Errorf("Unable to rebroadcast transaction %v: %v",
				tx.TxHash(), err)
			continue
		}
	}
}

// Broadcast submits a request to the Broadcaster to reliably broadcast the
// given transaction. An error won't be returned if the transaction already
// exists within the mempool. Any transaction broadcast through this method will
// be rebroadcast upon every change of the tip of the chain.
func (b *Broadcaster) Broadcast(tx *wire.MsgTx) error {
	errChan := make(chan error, 1)

	select {
	case b.broadcastReqs <- &broadcastReq{
		tx:      tx,
		errChan: errChan,
	}:
	case <-b.quit:
		return ErrBroadcasterStopped
	}

	select {
	case err := <-errChan:
		return err
	case <-b.quit:
		return ErrBroadcasterStopped
	}
}
<|endoftext|>


<commit_before>/*
 * json.go, part of gochem.
 *
 *
 * Copyright 2012 Raul Mera <rmera{at}chemDOThelsinkiDOTfi>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this program.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 *
 * Gochem is developed at the laboratory for instruction in Swedish, Department of Chemistry,
 * University of Helsinki, Finland.
 *
 *
 */
/***Dedicated to the long life of the Ven. Khenpo Phuntzok Tenzin Rinpoche***/

package chem

import (
	"bufio"
	"encoding/json"
	"strings"
	"fmt"
	"os"
)

type JSONAtom struct {
	A      *Atom
	Coords []float64
	Bfac   float64
}

type JSONCoords struct {
	Coords []float64
}

//An easily JSON-serializable error type,
type JSONError struct {
	IsError      bool //If this is false (no error) all the other fields will be at their zero-values.
	InOptions    bool //If error, was it in parsing the options?
	InSelections bool //Was it in parsing selections?
	InProcess    bool
	InPostProcess bool //was it in preparing the output?
	Selection    string //Which selection?
	State        int    //Which state of it?
	Atom         int
	Function     string //which go function gave the error
	Message      string //the error itself
}
//implements the error interface
func (J *JSONError) Error () string{
	return  J.Message
}

//Serializes the error. Panics on failure.
func (J *JSONError) Marshal() []byte{
	ret, err2 := json.Marshal(J)
	if err2 != nil {
		panic(strings.Join([]string{J.Error(), err2.Error()}, " - ")) //well, shit.
	}
	return ret
}

//Information to be passed back to the calling program.
type JSONInfo struct {
	Molecules int
	Bfactors  bool
	SS        bool
	FramesPerMolecule []int
	AtomsPerMolecule  []int
	FloatInfo  [][]float64
	StringInfo [][]string
	IntInfo    [][]int
}
func (J *JSONInfo) Marshal() ([]byte,*JSONError){
	ret,err:=json.Marshal(J)
	if err!=nil{
		return nil, MakeJSONError("postprocess","JSONInfo.Marshal",err)
	}
	return ret, nil
}

//Options passed from the calling external program
type JSONOptions struct {
	SelNames      []string
	AtomsPerSel   []int //Knowing in advance makes memory allocation more efficient
	StatesPerSel  []int //How many snapshots a traj has?
	StringOptions [][]string
	IntOptions    [][]int
	BoolOptions   [][]bool
	FloatOptions  [][]float64
}

//Takes an error and some additional info to create a JSON error
func MakeJSONError(where, function string, err error) *JSONError {
	jerr := new(JSONError)
	jerr.IsError = true
	switch where {
	case "options":
		jerr.InOptions = true
	case "selection":
		jerr.InSelections = true
	case "postprocess":
		jerr.InPostProcess = true
	default:
		jerr.InProcess = true
	}
	jerr.Function = function
	jerr.Message = err.Error()
	return jerr
}

func DecodeJSONOptions(stdin *bufio.Reader) (*JSONOptions, *JSONError) {
	line, err := stdin.ReadBytes('\n')
	if err != nil {
		return nil, MakeJSONError("options","DecodeJSONOptions",err)
	}
	ret := new(JSONOptions)
	err = json.Unmarshal(line, ret)
	if err != nil {
		return nil, MakeJSONError("options","DecodeJSONOptions",err)
	}
	return ret, nil
}

//Decodes a JSON molecule into a gochem molecule. Can handle several frames (all of which need to have the same amount of atoms). It does
//not collect the b-factors.
func DecodeJSONMolecule(stream *bufio.Reader, atomnumber, frames int) (*Topology, []*CoordMatrix, *JSONError) {
	atoms := make([]*Atom, 0, atomnumber)
	coordset := make([]*CoordMatrix, 0, frames)
	rawcoords := make([]float64, 0, 3*atomnumber)
	for i := 0; i < atomnumber; i++ {
		line, err := stream.ReadBytes('\n') //Using this function allocates a lot without need. There is no function that takes a []bytes AND a limit. I might write one at some point.
		if err != nil {
			break
		}
		at := new(Atom)
		err = json.Unmarshal(line, at)
		if err != nil {
			return nil, nil, MakeJSONError("selection","DecodeJSONMolecule",err)
		}
		atoms = append(atoms, at)
		line, err = stream.ReadBytes('\n') //See previous comment.
		if err != nil {
			break
		}
		ctemp := new(JSONCoords)
		if err = json.Unmarshal(line, ctemp); err != nil {
			return nil, nil, MakeJSONError("selection","DecodeJSONMolecule",err)
		}
		rawcoords = append(rawcoords, ctemp.Coords...)
	}
	mol, _ := MakeTopology(atoms, 0, 0) //no idea of the charge or multiplicity
	coords := NewCoords(rawcoords)
	coordset = append(coordset, coords)
	if frames == 1 {
		return mol, coordset, nil
	}
	for i:=0;i<(frames-1);i++{
		coords,err:=DecodeJSONCoords(stream,atomnumber)
		if err!=nil{
			return mol, coordset, MakeJSONError("selection","DecodeJSONMolecule",fmt.Errorf("Error reading the %d th frame: %s",i+2,err.Error()))
			}
		coordset=append(coordset,coords)
	}
	return mol, coordset, nil

}

func DecodeJSONCoords(stream *bufio.Reader, atomnumber int) (*CoordMatrix, *JSONError) {
	rawcoords := make([]float64, 0, 3*atomnumber)
	for i := 0; i < atomnumber; i++ {
		line, err := stream.ReadBytes('\n') //Using this function allocates a lot without need. There is no function that takes a []bytes AND a limit. I might write one at some point.
		if err != nil {
			break
		}
		ctemp := new(JSONCoords)
		if err = json.Unmarshal(line, ctemp); err != nil {
			return nil, MakeJSONError("selection","DecodeJSONCoords",err)
		}
		rawcoords = append(rawcoords, ctemp.Coords...)
	}
	coords := NewCoords(rawcoords)
	return coords, nil
}

func TransmitMoleculeJSON(mol Atomer, coordset, bfactors []*CoordMatrix, ss [][]string, out *os.File) *JSONError{
	jmol,err:=EncodeAtoms2JSON(mol)
	if err!=nil{
		return err
	}
	for _,i:=range(jmol){
		fmt.Fprint(out,i)
		fmt.Fprint(out,"\n")
	}
	for _,coords:=range(coordset){
		jcoords,err:=EncodeCoords2JSON(coords)
		if err!=nil{
			return err
		}
		for _,i:=range(jcoords){
			fmt.Fprint(out,i)
			fmt.Fprint(out,"\n")
		}
	}
	if bfactors!=nil{
		jb:=new(jSONbfac)
		for _,b:=range(bfactors){
			jb.Bfactors=b.Col(nil,0)
			jjb,err2:=json.Marshal(jb)
			if err2!=nil{
				return MakeJSONError("postprocess","TransmitMoleculeJson(bfactors)",err2)
			}
			fmt.Fprint(out,jjb)
			fmt.Fprint(out,"\n")
		}
	}
	if ss!=nil{
		jss:=new(jSONss)
		for _,s:=range(ss){
			jss.SS=s
			jjss,err2:=json.Marshal(jss)
			if err2!=nil{
				return MakeJSONError("postprocess","TransmitMoleculeJson(ss)",err2)
			}
			fmt.Fprint(out,jjss)
			fmt.Fprint(out,"\n")
		}
	}
	return nil
}

type jSONbfac struct {
	Bfactors []float64
}

type jSONss struct {
	SS []string
}

type jSONCoords struct{
	coords []float64
}

func EncodeAtoms2JSON(mol Atomer) ([][]byte, *JSONError){
	ret:=make([][]byte,0,mol.Len())
	for i:=0;i<mol.Len();i++{
		b,err:=json.Marshal(mol.Atom(i))
		if err!=nil{
			return  nil, MakeJSONError("postprocess","EncodeAtoms2JSON",err)
		}
		ret=append(ret,b)
	}
	return ret, nil
}

func EncodeCoords2JSON(coords *CoordMatrix)  ([][]byte, *JSONError){
	c:=new(jSONCoords)
	t:=make([]float64,3,3)
	ret:=make([][]byte,0,coords.NumVec())
	for i:=0;i<coords.NumVec();i++{
		c.coords=coords.Row(t,i)
		b,err:=json.Marshal(c)
		if err!=nil{
			return  nil, MakeJSONError("postprocess","EncodeCoords2JSON",err)
		}
		ret=append(ret,b)
	}
	return ret, nil
}

<commit_msg>transition commit, json transmitting back to python is not working, the issue seems to be here. There are several bug-hunting print statements in json.go that need to go after this is fixed<commit_after>/*
 * json.go, part of gochem.
 *
 *
 * Copyright 2012 Raul Mera <rmera{at}chemDOThelsinkiDOTfi>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of the
 * License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this program.  If not, see
 * <http://www.gnu.org/licenses/>.
 *
 *
 * Gochem is developed at the laboratory for instruction in Swedish, Department of Chemistry,
 * University of Helsinki, Finland.
 *
 *
 */
/***Dedicated to the long life of the Ven. Khenpo Phuntzok Tenzin Rinpoche***/

package chem

import (
	"bufio"
	"encoding/json"
	"strings"
	"fmt"
	"os"
	"io"
)

type JSONAtom struct {
	A      *Atom
	Coords []float64
	Bfac   float64
}

type JSONCoords struct {
	Coords []float64
}

//An easily JSON-serializable error type,
type JSONError struct {
	IsError      bool //If this is false (no error) all the other fields will be at their zero-values.
	InOptions    bool //If error, was it in parsing the options?
	InSelections bool //Was it in parsing selections?
	InProcess    bool
	InPostProcess bool //was it in preparing the output?
	Selection    string //Which selection?
	State        int    //Which state of it?
	Atom         int
	Function     string //which go function gave the error
	Message      string //the error itself
}
//implements the error interface
func (J *JSONError) Error () string{
	return  J.Message
}

//Serializes the error. Panics on failure.
func (J *JSONError) Marshal() []byte{
	ret, err2 := json.Marshal(J)
	if err2 != nil {
		panic(strings.Join([]string{J.Error(), err2.Error()}, " - ")) //well, shit.
	}
	return ret
}

//Information to be passed back to the calling program.
type JSONInfo struct {
	Molecules int
	Bfactors  bool
	SS        bool
	FramesPerMolecule []int
	AtomsPerMolecule  []int
	FloatInfo  [][]float64
	StringInfo [][]string
	IntInfo    [][]int
}
func (J *JSONInfo) Send(out io.Writer) (*JSONError){
	enc:=json.NewEncoder(out)
	if err:=enc.Encode(J);err!=nil{
		return MakeJSONError("postprocess","JSONInfo.Marshal",err)
	}
	return nil
}

//Options passed from the calling external program
type JSONOptions struct {
	SelNames      []string
	AtomsPerSel   []int //Knowing in advance makes memory allocation more efficient
	StatesPerSel  []int //How many snapshots a traj has?
	StringOptions [][]string
	IntOptions    [][]int
	BoolOptions   [][]bool
	FloatOptions  [][]float64
}

//Takes an error and some additional info to create a JSON error
func MakeJSONError(where, function string, err error) *JSONError {
	jerr := new(JSONError)
	jerr.IsError = true
	switch where {
	case "options":
		jerr.InOptions = true
	case "selection":
		jerr.InSelections = true
	case "postprocess":
		jerr.InPostProcess = true
	default:
		jerr.InProcess = true
	}
	jerr.Function = function
	jerr.Message = err.Error()
	return jerr
}

func DecodeJSONOptions(stdin *bufio.Reader) (*JSONOptions, *JSONError) {
	line, err := stdin.ReadBytes('\n')
	if err != nil {
		return nil, MakeJSONError("options","DecodeJSONOptions",err)
	}
	ret := new(JSONOptions)
	err = json.Unmarshal(line, ret)
	if err != nil {
		return nil, MakeJSONError("options","DecodeJSONOptions",err)
	}
	return ret, nil
}

//Decodes a JSON molecule into a gochem molecule. Can handle several frames (all of which need to have the same amount of atoms). It does
//not collect the b-factors.
func DecodeJSONMolecule(stream *bufio.Reader, atomnumber, frames int) (*Topology, []*CoordMatrix, *JSONError) {
	atoms := make([]*Atom, 0, atomnumber)
	coordset := make([]*CoordMatrix, 0, frames)
	rawcoords := make([]float64, 0, 3*atomnumber)
	for i := 0; i < atomnumber; i++ {
		line, err := stream.ReadBytes('\n') //Using this function allocates a lot without need. There is no function that takes a []bytes AND a limit. I might write one at some point.
		if err != nil {
			break
		}
		at := new(Atom)
		err = json.Unmarshal(line, at)
		if err != nil {
			return nil, nil, MakeJSONError("selection","DecodeJSONMolecule",err)
		}
		atoms = append(atoms, at)
		line, err = stream.ReadBytes('\n') //See previous comment.
		if err != nil {
			break
		}
		ctemp := new(JSONCoords)
		if err = json.Unmarshal(line, ctemp); err != nil {
			return nil, nil, MakeJSONError("selection","DecodeJSONMolecule",err)
		}
		rawcoords = append(rawcoords, ctemp.Coords...)
	}
	mol, _ := MakeTopology(atoms, 0, 0) //no idea of the charge or multiplicity
	coords := NewCoords(rawcoords)
	coordset = append(coordset, coords)
	if frames == 1 {
		return mol, coordset, nil
	}
	for i:=0;i<(frames-1);i++{
		coords,err:=DecodeJSONCoords(stream,atomnumber)
		if err!=nil{
			return mol, coordset, MakeJSONError("selection","DecodeJSONMolecule",fmt.Errorf("Error reading the %d th frame: %s",i+2,err.Error()))
			}
		coordset=append(coordset,coords)
	}
	return mol, coordset, nil

}

func DecodeJSONCoords(stream *bufio.Reader, atomnumber int) (*CoordMatrix, *JSONError) {
	rawcoords := make([]float64, 0, 3*atomnumber)
	for i := 0; i < atomnumber; i++ {
		line, err := stream.ReadBytes('\n') //Using this function allocates a lot without need. There is no function that takes a []bytes AND a limit. I might write one at some point.
		if err != nil {
			break
		}
		ctemp := new(JSONCoords)
		if err = json.Unmarshal(line, ctemp); err != nil {
			return nil, MakeJSONError("selection","DecodeJSONCoords",err)
		}
		rawcoords = append(rawcoords, ctemp.Coords...)
	}
	coords := NewCoords(rawcoords)
	return coords, nil
}

func TransmitMoleculeJSON(mol Atomer, coordset, bfactors []*CoordMatrix, ss [][]string, out io.Writer) *JSONError{
	fmt.Fprintln(os.Stderr, "JOVEN")
	enc:=json.NewEncoder(out)
	fmt.Fprintln(os.Stderr, "VIEJA")
	if err:=EncodeAtoms2JSON(mol,enc); err!=nil{
		return err
	}
	fmt.Fprintln(os.Stderr, "VIeeeeeeEJA")
	for _,coords:=range(coordset){
		if err:=EncodeCoords2JSON(coords,enc); err!=nil{
			return err
		}
	}

	fmt.Fprintln(os.Stderr, "VIEJaaaaaaaaaaaaaaaaaaaA")
	if bfactors!=nil{
		jb:=new(jSONbfac)
		for _,b:=range(bfactors){
			jb.Bfactors=b.Col(nil,0)
			if err:=enc.Encode(jb);err!=nil{
				return MakeJSONError("postprocess","TransmitMoleculeJson(bfactors)",err)
			}
		}
	}
	if ss!=nil{
		jss:=new(jSONss)
		for _,s:=range(ss){
			jss.SS=s
			if err:=enc.Encode(jss); err!=nil{
				return MakeJSONError("postprocess","TransmitMoleculeJson(ss)",err)
			}
		}
	}
	return nil
}

type jSONbfac struct {
	Bfactors []float64
}

type jSONss struct {
	SS []string
}

type jSONCoords struct{
	Coords []float64
}

func EncodeAtoms2JSON(mol Atomer, enc *json.Encoder) (*JSONError){
	for i:=0;i<mol.Len();i++{
		fmt.Fprintln(os.Stderr, "IIII", i)
		if err:=enc.Encode(mol.Atom(i));err!=nil{
			return  MakeJSONError("postprocess","EncodeAtoms2JSON",err)
		}
	//	out.Write([]byte{'\n'})
	}
	return nil
}

func EncodeCoords2JSON(coords *CoordMatrix, enc *json.Encoder)  (*JSONError){
	c:=new(jSONCoords)
	t:=make([]float64,3,3)
	for i:=0;i<coords.NumVec();i++{
		c.Coords=coords.Row(t,i)
		if err:=enc.Encode(c); err!=nil{
			return MakeJSONError("postprocess","EncodeCoords2JSON",err)
		}
	}
	return nil
}

<|endoftext|>


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

package gabi

import (
	"crypto/rand"
	"encoding/xml"
	"io"
	"io/ioutil"
	"math/big"
	"os"
	"strconv"
	"time"

	"github.com/credentials/safeprime"
)

const (
	//XMLHeader can be a used as the XML header when writing keys in XML format.
	XMLHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
	// DefaultEpochLength is the default epoch length for public keys.
	DefaultEpochLength = 432000
)

// PrivateKey represents an issuer's private key.
type PrivateKey struct {
	XMLName    xml.Name `xml:"http://www.zurich.ibm.com/security/idemix IssuerPrivateKey"`
	Counter    uint     `xml:"Counter"`
	ExpiryDate int64    `xml:"ExpiryDate"`
	P          *big.Int `xml:"Elements>p"`
	Q          *big.Int `xml:"Elements>q"`
	PPrime     *big.Int `xml:"Elements>pPrime"`
	QPrime     *big.Int `xml:"Elements>qPrime"`
}

// NewPrivateKey creates a new issuer private key using the provided parameters.
func NewPrivateKey(p, q *big.Int, counter uint, expiryDate time.Time) *PrivateKey {
	sk := PrivateKey{P: p, Q: q, PPrime: new(big.Int), QPrime: new(big.Int), Counter: counter, ExpiryDate: expiryDate.Unix()}

	sk.PPrime.Sub(p, bigONE)
	sk.PPrime.Rsh(sk.PPrime, 1)

	sk.QPrime.Sub(q, bigONE)
	sk.QPrime.Rsh(sk.QPrime, 1)

	return &sk
}

// NewPrivateKeyFromXML creates a new issuer private key using the xml data
// provided.
func NewPrivateKeyFromXML(xmlInput string) (*PrivateKey, error) {
	privk := &PrivateKey{}
	err := xml.Unmarshal([]byte(xmlInput), privk)
	if err != nil {
		return nil, err
	}
	return privk, nil
}

// NewPrivateKeyFromFile create a new issuer private key from an xml file.
func NewPrivateKeyFromFile(filename string) (*PrivateKey, error) {
	f, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	privk := &PrivateKey{}

	b, err := ioutil.ReadAll(f)
	if err != nil {
		return nil, err
	}

	err = xml.Unmarshal(b, privk)
	if err != nil {
		return nil, err
	}
	return privk, nil
}

// Print prints the key to stdout.
func (privk *PrivateKey) Print() error {
	_, err := privk.WriteTo(os.Stdout)
	return err
}

// WriteTo writes the XML-serialized public key to the given writer.
func (privk *PrivateKey) WriteTo(writer io.Writer) (int64, error) {
	// Write the standard XML header
	numHeaderBytes, err := writer.Write([]byte(XMLHeader))
	if err != nil {
		return 0, err
	}

	// And the actual xml body (with indentation)
	b, err := xml.MarshalIndent(privk, "", "   ")
	if err != nil {
		return int64(numHeaderBytes), err
	}
	numBodyBytes, err := writer.Write(b)
	return int64(numHeaderBytes + numBodyBytes), err
}

// WriteToFile writes the private key to an xml file. If any existing file with
// the same filename should be overwritten, set forceOverwrite to true.
func (privk *PrivateKey) WriteToFile(filename string, forceOverwrite bool) (int64, error) {
	var f *os.File
	var err error
	if forceOverwrite {
		f, err = os.Create(filename)
	} else {
		// This should return an error if the file already exists
		f, err = os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
	}
	if err != nil {
		return 0, err
	}
	defer f.Close()

	return privk.WriteTo(f)
}

// xmlBases is an auxiliary struct to encode/decode the odd way bases are
// represented in the xml representation of public keys
type xmlBases struct {
	Num   int        `xml:"num,attr"`
	Bases []*xmlBase `xml:",any"`
}

type xmlBase struct {
	XMLName xml.Name
	Bigint  string `xml:",innerxml"` // Has to be a string for ",innerxml" to work
}

// xmlFeatures is an auxiliary struct to make the XML encoding/decoding a bit
// easier while keeping the struct for PublicKey somewhat simple.
type xmlFeatures struct {
	Epoch struct {
		Length int `xml:"length,attr"`
	}
}

// Bases is a type that is introduced to simplify the encoding/decoding of
// a PublicKey whilst using the xml support of Go's standard library.
type Bases []*big.Int

// UnmarshalXML is an internal function to simplify decoding a PublicKey from
// XML.
func (bl *Bases) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	var t xmlBases

	if err := d.DecodeElement(&t, &start); err != nil {
		return err
	}

	arr := make([]*big.Int, t.Num)
	for i := range arr {
		arr[i], _ = new(big.Int).SetString(t.Bases[i].Bigint, 10)
	}

	*bl = Bases(arr)
	return nil
}

// MarshalXML is an internal function to simplify encoding a PublicKey to XML.
func (bl *Bases) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	l := len(*bl)
	bases := make([]*xmlBase, l)

	for i := range bases {
		bases[i] = &xmlBase{
			XMLName: xml.Name{Local: "Base_" + strconv.Itoa(i)},
			Bigint:  (*bl)[i].String(),
		}
	}

	t := xmlBases{
		Num:   l,
		Bases: bases,
	}
	return e.EncodeElement(t, start)
}

// EpochLength is a type that is introduced to simplify the encoding/decoding of
// a PublicKey whilst using the xml support of Go's standard library.
type EpochLength int

// UnmarshalXML is an internal function to simplify decoding a PublicKey from
// XML.
func (el *EpochLength) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	var t xmlFeatures

	if err := d.DecodeElement(&t, &start); err != nil {
		return err
	}
	*el = EpochLength(t.Epoch.Length)
	return nil
}

// MarshalXML is an internal function to simplify encoding a PublicKey to XML.
func (el *EpochLength) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	var t xmlFeatures
	t.Epoch.Length = int(*el)
	return e.EncodeElement(t, start)
}

// PublicKey represents an issuer's public key.
type PublicKey struct {
	XMLName     xml.Name          `xml:"http://www.zurich.ibm.com/security/idemix IssuerPublicKey"`
	Counter     uint              `xml:"Counter"`
	ExpiryDate  int64             `xml:"ExpiryDate"`
	N           *big.Int          `xml:"Elements>n"` // Modulus n
	Z           *big.Int          `xml:"Elements>Z"` // Generator Z
	S           *big.Int          `xml:"Elements>S"` // Generator S
	R           Bases             `xml:"Elements>Bases"`
	EpochLength EpochLength       `xml:"Features"`
	Params      *SystemParameters `xml:"-"`
}

// NewPublicKey creates and returns a new public key based on the provided parameters.
func NewPublicKey(N, Z, S *big.Int, R []*big.Int, counter uint, expiryDate time.Time) *PublicKey {
	// TODO: make keylength a parameter
	return &PublicKey{
		Counter:     counter,
		ExpiryDate:  expiryDate.Unix(),
		N:           N,
		Z:           Z,
		S:           S,
		R:           R,
		EpochLength: DefaultEpochLength,
		Params:      DefaultSystemParameters[1024],
	}
}

// NewPublicKeyFromXML creates a new issuer public key using the xml data
// provided.
func NewPublicKeyFromXML(xmlInput string) (*PublicKey, error) {
	// TODO: this might fail in the future. The DefaultSystemParameters and the
	// public key might not match!
	// TODO: Also: the 1024 should be derived from the XML file.
	pubk := &PublicKey{Params: DefaultSystemParameters[1024]}
	err := xml.Unmarshal([]byte(xmlInput), pubk)
	if err != nil {
		return nil, err
	}
	return pubk, nil
}

// NewPublicKeyFromFile create a new issuer public key from an xml file.
func NewPublicKeyFromFile(filename string) (*PublicKey, error) {
	f, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	pubk := &PublicKey{}

	b, err := ioutil.ReadAll(f)
	if err != nil {
		return nil, err
	}

	err = xml.Unmarshal(b, pubk)
	if err != nil {
		return nil, err
	}
	return pubk, nil
}

// Print prints the key to stdout.
func (pubk *PublicKey) Print() error {
	_, err := pubk.WriteTo(os.Stdout)
	return err
}

// WriteTo writes the XML-serialized public key to the given writer.
func (pubk *PublicKey) WriteTo(writer io.Writer) (int64, error) {
	// Write the standard XML header
	numHeaderBytes, err := writer.Write([]byte(XMLHeader))
	if err != nil {
		return 0, err
	}

	// And the actual xml body (with indentation)
	b, err := xml.MarshalIndent(pubk, "", "   ")
	if err != nil {
		return int64(numHeaderBytes), err
	}
	numBodyBytes, err := writer.Write(b)
	return int64(numHeaderBytes + numBodyBytes), err
}

// WriteToFile writes the public key to an xml file. If any existing file with
// the same filename should be overwritten, set forceOverwrite to true.
func (pubk *PublicKey) WriteToFile(filename string, forceOverwrite bool) (int64, error) {
	var f *os.File
	var err error
	if forceOverwrite {
		f, err = os.Create(filename)
	} else {
		// This should return an error if the file already exists
		f, err = os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
	}
	if err != nil {
		return 0, err
	}
	defer f.Close()

	return pubk.WriteTo(f)
}

// randomSafePrime produces a safe prime of the requested number of bits
func randomSafePrime(bits int) (*big.Int, error) {
	p2 := new(big.Int)
	for {
		p, err := rand.Prime(rand.Reader, bits)
		if err != nil {
			return nil, err
		}
		p2.Rsh(p, 1) // p2 = (p - 1)/2
		if p2.ProbablyPrime(20) {
			return p, nil
		}
	}
}

// GenerateKeyPair generates a private/public keypair for an Issuer
func GenerateKeyPair(param *SystemParameters, attrsAmount int, counter uint, expiryDate time.Time) (*PrivateKey, *PublicKey, error) {
	primeSize := param.Ln / 2

	// p and q need to be safe primes
	p, err := safeprime.Generate(int(primeSize))
	if err != nil {
		return nil, nil, err
	}

	q, err := safeprime.Generate(int(primeSize))
	if err != nil {
		return nil, nil, err
	}

	priv := &PrivateKey{P: p, Q: q, PPrime: new(big.Int), QPrime: new(big.Int), Counter: counter, ExpiryDate: expiryDate.Unix()}

	// compute p' and q'
	priv.PPrime.Sub(priv.P, bigONE)
	priv.PPrime.Rsh(priv.PPrime, 1)

	priv.QPrime.Sub(priv.Q, bigONE)
	priv.QPrime.Rsh(priv.QPrime, 1)

	// compute n
	pubk := &PublicKey{Params: param, EpochLength: DefaultEpochLength, Counter: counter, ExpiryDate: expiryDate.Unix()}
	pubk.N = new(big.Int).Mul(priv.P, priv.Q)

	// Find an acceptable value for S; we follow lead of the Silvia code here:
	// Pick a random l_n value and check whether it is a quadratic residue modulo n

	var s *big.Int
	for {
		s, err = randomBigInt(param.Ln)
		if err != nil {
			return nil, nil, err
		}
		// check if S \elem Z_n
		if s.Cmp(pubk.N) > 0 {
			continue
		}
		if legendreSymbol(s, priv.P) == 1 && legendreSymbol(s, priv.Q) == 1 {
			break
		}
	}

	pubk.S = s

	// Derive Z from S
	var x *big.Int
	for {
		x, _ = randomBigInt(primeSize)
		if x.Cmp(bigTWO) > 0 && x.Cmp(pubk.N) < 0 {
			break
		}
	}

	// Compute Z = S^x mod n
	pubk.Z = new(big.Int).Exp(pubk.S, x, pubk.N)

	// Derive R_i for i = 0...attrsAmount from S
	pubk.R = make([]*big.Int, attrsAmount)
	for i := 0; i < attrsAmount; i++ {
		pubk.R[i] = new(big.Int)

		var x *big.Int
		for {
			x, _ = randomBigInt(primeSize)
			if x.Cmp(bigTWO) > 0 && x.Cmp(pubk.N) < 0 {
				break
			}
		}
		// Compute R_i = S^x mod n
		pubk.R[i].Exp(pubk.S, x, pubk.N)
	}

	return priv, pubk, nil
}
<commit_msg>Automatically select system parameters based on N's bitlength.<commit_after>// Copyright 2016 Maarten Everts. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gabi

import (
	"crypto/rand"
	"encoding/xml"
	"io"
	"io/ioutil"
	"math/big"
	"os"
	"strconv"
	"time"

	"errors"
	"github.com/credentials/safeprime"
)

const (
	//XMLHeader can be a used as the XML header when writing keys in XML format.
	XMLHeader = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
	// DefaultEpochLength is the default epoch length for public keys.
	DefaultEpochLength = 432000
)

// PrivateKey represents an issuer's private key.
type PrivateKey struct {
	XMLName    xml.Name `xml:"http://www.zurich.ibm.com/security/idemix IssuerPrivateKey"`
	Counter    uint     `xml:"Counter"`
	ExpiryDate int64    `xml:"ExpiryDate"`
	P          *big.Int `xml:"Elements>p"`
	Q          *big.Int `xml:"Elements>q"`
	PPrime     *big.Int `xml:"Elements>pPrime"`
	QPrime     *big.Int `xml:"Elements>qPrime"`
}

// NewPrivateKey creates a new issuer private key using the provided parameters.
func NewPrivateKey(p, q *big.Int, counter uint, expiryDate time.Time) *PrivateKey {
	sk := PrivateKey{P: p, Q: q, PPrime: new(big.Int), QPrime: new(big.Int), Counter: counter, ExpiryDate: expiryDate.Unix()}

	sk.PPrime.Sub(p, bigONE)
	sk.PPrime.Rsh(sk.PPrime, 1)

	sk.QPrime.Sub(q, bigONE)
	sk.QPrime.Rsh(sk.QPrime, 1)

	return &sk
}

// NewPrivateKeyFromXML creates a new issuer private key using the xml data
// provided.
func NewPrivateKeyFromXML(xmlInput string) (*PrivateKey, error) {
	privk := &PrivateKey{}
	err := xml.Unmarshal([]byte(xmlInput), privk)
	if err != nil {
		return nil, err
	}
	return privk, nil
}

// NewPrivateKeyFromFile create a new issuer private key from an xml file.
func NewPrivateKeyFromFile(filename string) (*PrivateKey, error) {
	f, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	privk := &PrivateKey{}

	b, err := ioutil.ReadAll(f)
	if err != nil {
		return nil, err
	}

	err = xml.Unmarshal(b, privk)
	if err != nil {
		return nil, err
	}
	return privk, nil
}

// Print prints the key to stdout.
func (privk *PrivateKey) Print() error {
	_, err := privk.WriteTo(os.Stdout)
	return err
}

// WriteTo writes the XML-serialized public key to the given writer.
func (privk *PrivateKey) WriteTo(writer io.Writer) (int64, error) {
	// Write the standard XML header
	numHeaderBytes, err := writer.Write([]byte(XMLHeader))
	if err != nil {
		return 0, err
	}

	// And the actual xml body (with indentation)
	b, err := xml.MarshalIndent(privk, "", "   ")
	if err != nil {
		return int64(numHeaderBytes), err
	}
	numBodyBytes, err := writer.Write(b)
	return int64(numHeaderBytes + numBodyBytes), err
}

// WriteToFile writes the private key to an xml file. If any existing file with
// the same filename should be overwritten, set forceOverwrite to true.
func (privk *PrivateKey) WriteToFile(filename string, forceOverwrite bool) (int64, error) {
	var f *os.File
	var err error
	if forceOverwrite {
		f, err = os.Create(filename)
	} else {
		// This should return an error if the file already exists
		f, err = os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
	}
	if err != nil {
		return 0, err
	}
	defer f.Close()

	return privk.WriteTo(f)
}

// xmlBases is an auxiliary struct to encode/decode the odd way bases are
// represented in the xml representation of public keys
type xmlBases struct {
	Num   int        `xml:"num,attr"`
	Bases []*xmlBase `xml:",any"`
}

type xmlBase struct {
	XMLName xml.Name
	Bigint  string `xml:",innerxml"` // Has to be a string for ",innerxml" to work
}

// xmlFeatures is an auxiliary struct to make the XML encoding/decoding a bit
// easier while keeping the struct for PublicKey somewhat simple.
type xmlFeatures struct {
	Epoch struct {
		Length int `xml:"length,attr"`
	}
}

// Bases is a type that is introduced to simplify the encoding/decoding of
// a PublicKey whilst using the xml support of Go's standard library.
type Bases []*big.Int

// UnmarshalXML is an internal function to simplify decoding a PublicKey from
// XML.
func (bl *Bases) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	var t xmlBases

	if err := d.DecodeElement(&t, &start); err != nil {
		return err
	}

	arr := make([]*big.Int, t.Num)
	for i := range arr {
		arr[i], _ = new(big.Int).SetString(t.Bases[i].Bigint, 10)
	}

	*bl = Bases(arr)
	return nil
}

// MarshalXML is an internal function to simplify encoding a PublicKey to XML.
func (bl *Bases) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	l := len(*bl)
	bases := make([]*xmlBase, l)

	for i := range bases {
		bases[i] = &xmlBase{
			XMLName: xml.Name{Local: "Base_" + strconv.Itoa(i)},
			Bigint:  (*bl)[i].String(),
		}
	}

	t := xmlBases{
		Num:   l,
		Bases: bases,
	}
	return e.EncodeElement(t, start)
}

// EpochLength is a type that is introduced to simplify the encoding/decoding of
// a PublicKey whilst using the xml support of Go's standard library.
type EpochLength int

// UnmarshalXML is an internal function to simplify decoding a PublicKey from
// XML.
func (el *EpochLength) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	var t xmlFeatures

	if err := d.DecodeElement(&t, &start); err != nil {
		return err
	}
	*el = EpochLength(t.Epoch.Length)
	return nil
}

// MarshalXML is an internal function to simplify encoding a PublicKey to XML.
func (el *EpochLength) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	var t xmlFeatures
	t.Epoch.Length = int(*el)
	return e.EncodeElement(t, start)
}

// PublicKey represents an issuer's public key.
type PublicKey struct {
	XMLName     xml.Name          `xml:"http://www.zurich.ibm.com/security/idemix IssuerPublicKey"`
	Counter     uint              `xml:"Counter"`
	ExpiryDate  int64             `xml:"ExpiryDate"`
	N           *big.Int          `xml:"Elements>n"` // Modulus n
	Z           *big.Int          `xml:"Elements>Z"` // Generator Z
	S           *big.Int          `xml:"Elements>S"` // Generator S
	R           Bases             `xml:"Elements>Bases"`
	EpochLength EpochLength       `xml:"Features"`
	Params      *SystemParameters `xml:"-"`
}

// NewPublicKey creates and returns a new public key based on the provided parameters.
func NewPublicKey(N, Z, S *big.Int, R []*big.Int, counter uint, expiryDate time.Time) *PublicKey {
	return &PublicKey{
		Counter:     counter,
		ExpiryDate:  expiryDate.Unix(),
		N:           N,
		Z:           Z,
		S:           S,
		R:           R,
		EpochLength: DefaultEpochLength,
		Params:      DefaultSystemParameters[N.BitLen()],
	}
}

// NewPublicKeyFromXML creates a new issuer public key using the xml data
// provided.
func NewPublicKeyFromXML(xmlInput string) (*PublicKey, error) {
	// TODO: this might fail in the future. The DefaultSystemParameters and the
	// public key might not match!
	pubk := &PublicKey{}
	err := xml.Unmarshal([]byte(xmlInput), pubk)
	if err != nil {
		return nil, err
	}
	keylength := pubk.N.BitLen()
	if sysparam, ok := DefaultSystemParameters[keylength]; ok {
		pubk.Params = sysparam
	} else {
		return nil, errors.New("Unknown keylength")
	}
	return pubk, nil
}

// NewPublicKeyFromFile create a new issuer public key from an xml file.
func NewPublicKeyFromFile(filename string) (*PublicKey, error) {
	f, err := os.Open(filename)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	pubk := &PublicKey{}

	b, err := ioutil.ReadAll(f)
	if err != nil {
		return nil, err
	}

	err = xml.Unmarshal(b, pubk)
	if err != nil {
		return nil, err
	}
	return pubk, nil
}

// Print prints the key to stdout.
func (pubk *PublicKey) Print() error {
	_, err := pubk.WriteTo(os.Stdout)
	return err
}

// WriteTo writes the XML-serialized public key to the given writer.
func (pubk *PublicKey) WriteTo(writer io.Writer) (int64, error) {
	// Write the standard XML header
	numHeaderBytes, err := writer.Write([]byte(XMLHeader))
	if err != nil {
		return 0, err
	}

	// And the actual xml body (with indentation)
	b, err := xml.MarshalIndent(pubk, "", "   ")
	if err != nil {
		return int64(numHeaderBytes), err
	}
	numBodyBytes, err := writer.Write(b)
	return int64(numHeaderBytes + numBodyBytes), err
}

// WriteToFile writes the public key to an xml file. If any existing file with
// the same filename should be overwritten, set forceOverwrite to true.
func (pubk *PublicKey) WriteToFile(filename string, forceOverwrite bool) (int64, error) {
	var f *os.File
	var err error
	if forceOverwrite {
		f, err = os.Create(filename)
	} else {
		// This should return an error if the file already exists
		f, err = os.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_EXCL, 0666)
	}
	if err != nil {
		return 0, err
	}
	defer f.Close()

	return pubk.WriteTo(f)
}

// randomSafePrime produces a safe prime of the requested number of bits
func randomSafePrime(bits int) (*big.Int, error) {
	p2 := new(big.Int)
	for {
		p, err := rand.Prime(rand.Reader, bits)
		if err != nil {
			return nil, err
		}
		p2.Rsh(p, 1) // p2 = (p - 1)/2
		if p2.ProbablyPrime(20) {
			return p, nil
		}
	}
}

// GenerateKeyPair generates a private/public keypair for an Issuer
func GenerateKeyPair(param *SystemParameters, attrsAmount int, counter uint, expiryDate time.Time) (*PrivateKey, *PublicKey, error) {
	primeSize := param.Ln / 2

	// p and q need to be safe primes
	p, err := safeprime.Generate(int(primeSize))
	if err != nil {
		return nil, nil, err
	}

	q, err := safeprime.Generate(int(primeSize))
	if err != nil {
		return nil, nil, err
	}

	priv := &PrivateKey{P: p, Q: q, PPrime: new(big.Int), QPrime: new(big.Int), Counter: counter, ExpiryDate: expiryDate.Unix()}

	// compute p' and q'
	priv.PPrime.Sub(priv.P, bigONE)
	priv.PPrime.Rsh(priv.PPrime, 1)

	priv.QPrime.Sub(priv.Q, bigONE)
	priv.QPrime.Rsh(priv.QPrime, 1)

	// compute n
	pubk := &PublicKey{Params: param, EpochLength: DefaultEpochLength, Counter: counter, ExpiryDate: expiryDate.Unix()}
	pubk.N = new(big.Int).Mul(priv.P, priv.Q)

	// Find an acceptable value for S; we follow lead of the Silvia code here:
	// Pick a random l_n value and check whether it is a quadratic residue modulo n

	var s *big.Int
	for {
		s, err = randomBigInt(param.Ln)
		if err != nil {
			return nil, nil, err
		}
		// check if S \elem Z_n
		if s.Cmp(pubk.N) > 0 {
			continue
		}
		if legendreSymbol(s, priv.P) == 1 && legendreSymbol(s, priv.Q) == 1 {
			break
		}
	}

	pubk.S = s

	// Derive Z from S
	var x *big.Int
	for {
		x, _ = randomBigInt(primeSize)
		if x.Cmp(bigTWO) > 0 && x.Cmp(pubk.N) < 0 {
			break
		}
	}

	// Compute Z = S^x mod n
	pubk.Z = new(big.Int).Exp(pubk.S, x, pubk.N)

	// Derive R_i for i = 0...attrsAmount from S
	pubk.R = make([]*big.Int, attrsAmount)
	for i := 0; i < attrsAmount; i++ {
		pubk.R[i] = new(big.Int)

		var x *big.Int
		for {
			x, _ = randomBigInt(primeSize)
			if x.Cmp(bigTWO) > 0 && x.Cmp(pubk.N) < 0 {
				break
			}
		}
		// Compute R_i = S^x mod n
		pubk.R[i].Exp(pubk.S, x, pubk.N)
	}

	return priv, pubk, nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io"
	"log"
	"os"
	"syscall"
	"unsafe"
)

/*** defines ***/

const KILO_VERSION = "0.0.1"

/*** data ***/

type Termios struct {
	Iflag  uint32
	Oflag  uint32
	Cflag  uint32
	Lflag  uint32
	Cc     [20]byte
	Ispeed uint32
	Ospeed uint32
}

type editorConfig struct {
	cx          int
	cy          int
	screenRows  int
	screenCols  int
	origTermios *Termios
}

type WinSize struct {
	Row    uint16
	Col    uint16
	Xpixel uint16
	Ypixel uint16
}

var E editorConfig

/*** terminal ***/

func die(err error) {
	disableRawMode()
	io.WriteString(os.Stdout, "\x1b[2J")
	io.WriteString(os.Stdout, "\x1b[H")
	log.Fatal(err)
}

func TcSetAttr(fd uintptr, termios *Termios) error {
	// TCSETS+1 == TCSETSW, because TCSAFLUSH doesn't exist
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TCSETS+1), uintptr(unsafe.Pointer(termios))); err != 0 {
		return err
	}
	return nil
}

func TcGetAttr(fd uintptr) *Termios {
	var termios = &Termios{}
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, syscall.TCGETS, uintptr(unsafe.Pointer(termios))); err != 0 {
		log.Fatalf("Problem getting terminal attributes: %s\n", err)
	}
	return termios
}

func enableRawMode() {
	E.origTermios = TcGetAttr(os.Stdin.Fd())
	var raw Termios
	raw = *E.origTermios
	raw.Iflag &^= syscall.BRKINT | syscall.ICRNL | syscall.INPCK | syscall.ISTRIP | syscall.IXON
	raw.Oflag &^= syscall.OPOST
	raw.Cflag |= syscall.CS8
	raw.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.IEXTEN | syscall.ISIG
	raw.Cc[syscall.VMIN+1] = 0
	raw.Cc[syscall.VTIME+1] = 1
	if e := TcSetAttr(os.Stdin.Fd(), &raw); e != nil {
		log.Fatalf("Problem enabling raw mode: %s\n", e)
	}
}

func disableRawMode() {
	if e := TcSetAttr(os.Stdin.Fd(), E.origTermios); e != nil {
		log.Fatalf("Problem disabling raw mode: %s\n", e)
	}
}

func editorReadKey() byte {
	var buffer [1]byte
	var cc int
	var err error
	for cc, err = os.Stdin.Read(buffer[:]); cc != 1; cc, err = os.Stdin.Read(buffer[:]) {
	}
	if err != nil {
		die(err)
	}
	return buffer[0]
}

func getCursorPosition(rows *int, cols *int) int {
	io.WriteString(os.Stdout, "\x1b[6n")
	var buffer [1]byte
	var buf []byte
	var cc int
	for cc, _ = os.Stdin.Read(buffer[:]); cc == 1; cc, _ = os.Stdin.Read(buffer[:]) {
		if buffer[0] == 'R' {
			break
		}
		buf = append(buf, buffer[0])
	}
	if string(buf[0:2]) != "\x1b[" {
		log.Printf("Failed to read rows;cols from tty\n")
		return -1
	}
	if n, e := fmt.Sscanf(string(buf[2:]), "%d;%d", rows, cols); n != 2 || e != nil {
		if e != nil {
			log.Printf("getCursorPosition: fmt.Sscanf() failed: %s\n", e)
		}
		if n != 2 {
			log.Printf("getCursorPosition: got %d items, wanted 2\n", n)
		}
		return -1
	}
	return 0
}

func getWindowSize(rows *int, cols *int) int {
	var w WinSize
	_, _, err := syscall.Syscall(syscall.SYS_IOCTL,
		os.Stdout.Fd(),
		syscall.TIOCGWINSZ,
		uintptr(unsafe.Pointer(&w)),
	)
	if err != 0 { // type syscall.Errno
		io.WriteString(os.Stdout, "\x1b[999C\x1b[999B")
		return getCursorPosition(rows, cols)
	} else {
		*rows = int(w.Row)
		*cols = int(w.Col)
		return 0
	}
	return -1
}

/*** input ***/

func editorMoveCursor(key byte) {
	switch key {
	case 'a':
		E.cx--
	case 'd':
		E.cx++
	case 'w':
		E.cy--
	case 's':
		E.cy++
	}
}

func editorProcessKeypress() {
	c := editorReadKey()
	switch c {
	case ('q' & 0x1f):
		io.WriteString(os.Stdout, "\x1b[2J")
		io.WriteString(os.Stdout, "\x1b[H")
		disableRawMode()
		os.Exit(0)
	case 'w', 'a', 's', 'd':
		editorMoveCursor(c)
	}
}

/*** append buffer ***/

type abuf struct {
	buf []byte
}

func (p abuf) String() string {
	return string(p.buf)
}

func (p *abuf) abAppend(s string) {
	p.buf = append(p.buf, []byte(s)...)
}

/*** output ***/

func editorRefreshScreen() {
	var ab abuf
	ab.abAppend("\x1b[25l")
	ab.abAppend("\x1b[H")
	editorDrawRows(&ab)
	ab.abAppend(fmt.Sprintf("\x1b[%d;%dH", E.cy+1, E.cx+1))
	ab.abAppend("\x1b[25h")
	io.WriteString(os.Stdout, ab.String())
}

func editorDrawRows(ab *abuf) {
	for y := 0; y < E.screenRows-1; y++ {
		if y == E.screenRows/3 {
			w := fmt.Sprintf("Kilo editor -- version %s", KILO_VERSION)
			if len(w) > E.screenCols {
				w = w[0:E.screenCols]
			}
			pad := "~ "
			for padding := (E.screenCols - len(w)) / 2; padding > 0; padding-- {
				ab.abAppend(pad)
				pad = " "
			}
			ab.abAppend(w)
		} else {
			ab.abAppend("~")
		}
		ab.abAppend("\x1b[K")
		if y < E.screenRows-1 {
			ab.abAppend("\r\n")
		}
	}
}

/*** init ***/

func initEditor() {
	if getWindowSize(&E.screenRows, &E.screenCols) == -1 {
		die(fmt.Errorf("couldn't get screen size"))
	}
}

func main() {
	enableRawMode()
	defer disableRawMode()
	initEditor()

	for {
		editorRefreshScreen()
		editorProcessKeypress()
	}
}
<commit_msg>Step 46 - arrow keys<commit_after>package main

import (
	"fmt"
	"io"
	"log"
	"os"
	"syscall"
	"unsafe"
)

/*** defines ***/

const KILO_VERSION = "0.0.1"

/*** data ***/

type Termios struct {
	Iflag  uint32
	Oflag  uint32
	Cflag  uint32
	Lflag  uint32
	Cc     [20]byte
	Ispeed uint32
	Ospeed uint32
}

type editorConfig struct {
	cx          int
	cy          int
	screenRows  int
	screenCols  int
	origTermios *Termios
}

type WinSize struct {
	Row    uint16
	Col    uint16
	Xpixel uint16
	Ypixel uint16
}

var E editorConfig

/*** terminal ***/

func die(err error) {
	disableRawMode()
	io.WriteString(os.Stdout, "\x1b[2J")
	io.WriteString(os.Stdout, "\x1b[H")
	log.Fatal(err)
}

func TcSetAttr(fd uintptr, termios *Termios) error {
	// TCSETS+1 == TCSETSW, because TCSAFLUSH doesn't exist
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TCSETS+1), uintptr(unsafe.Pointer(termios))); err != 0 {
		return err
	}
	return nil
}

func TcGetAttr(fd uintptr) *Termios {
	var termios = &Termios{}
	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, syscall.TCGETS, uintptr(unsafe.Pointer(termios))); err != 0 {
		log.Fatalf("Problem getting terminal attributes: %s\n", err)
	}
	return termios
}

func enableRawMode() {
	E.origTermios = TcGetAttr(os.Stdin.Fd())
	var raw Termios
	raw = *E.origTermios
	raw.Iflag &^= syscall.BRKINT | syscall.ICRNL | syscall.INPCK | syscall.ISTRIP | syscall.IXON
	raw.Oflag &^= syscall.OPOST
	raw.Cflag |= syscall.CS8
	raw.Lflag &^= syscall.ECHO | syscall.ICANON | syscall.IEXTEN | syscall.ISIG
	raw.Cc[syscall.VMIN+1] = 0
	raw.Cc[syscall.VTIME+1] = 1
	if e := TcSetAttr(os.Stdin.Fd(), &raw); e != nil {
		log.Fatalf("Problem enabling raw mode: %s\n", e)
	}
}

func disableRawMode() {
	if e := TcSetAttr(os.Stdin.Fd(), E.origTermios); e != nil {
		log.Fatalf("Problem disabling raw mode: %s\n", e)
	}
}

func editorReadKey() byte {
	var buffer [1]byte
	var cc int
	var err error
	for cc, err = os.Stdin.Read(buffer[:]); cc != 1; cc, err = os.Stdin.Read(buffer[:]) {
	}
	if err != nil {
		die(err)
	}
	if buffer[0] == '\x1b' {
		var seq [2]byte
		cc, _ = os.Stdin.Read(seq[:])
		if cc != 2 {
			return '\x1b'
		}

		if seq[0] == '[' {
			switch seq[1] {
			case 'A':
				return 'w'
			case 'B':
				return 's'
			case 'C':
				return 'd'
			case 'D':
				return 'a'
			}
		}

		return '\x1b'
	}
	return buffer[0]
}

func getCursorPosition(rows *int, cols *int) int {
	io.WriteString(os.Stdout, "\x1b[6n")
	var buffer [1]byte
	var buf []byte
	var cc int
	for cc, _ = os.Stdin.Read(buffer[:]); cc == 1; cc, _ = os.Stdin.Read(buffer[:]) {
		if buffer[0] == 'R' {
			break
		}
		buf = append(buf, buffer[0])
	}
	if string(buf[0:2]) != "\x1b[" {
		log.Printf("Failed to read rows;cols from tty\n")
		return -1
	}
	if n, e := fmt.Sscanf(string(buf[2:]), "%d;%d", rows, cols); n != 2 || e != nil {
		if e != nil {
			log.Printf("getCursorPosition: fmt.Sscanf() failed: %s\n", e)
		}
		if n != 2 {
			log.Printf("getCursorPosition: got %d items, wanted 2\n", n)
		}
		return -1
	}
	return 0
}

func getWindowSize(rows *int, cols *int) int {
	var w WinSize
	_, _, err := syscall.Syscall(syscall.SYS_IOCTL,
		os.Stdout.Fd(),
		syscall.TIOCGWINSZ,
		uintptr(unsafe.Pointer(&w)),
	)
	if err != 0 { // type syscall.Errno
		io.WriteString(os.Stdout, "\x1b[999C\x1b[999B")
		return getCursorPosition(rows, cols)
	} else {
		*rows = int(w.Row)
		*cols = int(w.Col)
		return 0
	}
	return -1
}

/*** input ***/

func editorMoveCursor(key byte) {
	switch key {
	case 'a':
		E.cx--
	case 'd':
		E.cx++
	case 'w':
		E.cy--
	case 's':
		E.cy++
	}
}

func editorProcessKeypress() {
	c := editorReadKey()
	switch c {
	case ('q' & 0x1f):
		io.WriteString(os.Stdout, "\x1b[2J")
		io.WriteString(os.Stdout, "\x1b[H")
		disableRawMode()
		os.Exit(0)
	case 'w', 'a', 's', 'd':
		editorMoveCursor(c)
	}
}

/*** append buffer ***/

type abuf struct {
	buf []byte
}

func (p abuf) String() string {
	return string(p.buf)
}

func (p *abuf) abAppend(s string) {
	p.buf = append(p.buf, []byte(s)...)
}

/*** output ***/

func editorRefreshScreen() {
	var ab abuf
	ab.abAppend("\x1b[25l")
	ab.abAppend("\x1b[H")
	editorDrawRows(&ab)
	ab.abAppend(fmt.Sprintf("\x1b[%d;%dH", E.cy+1, E.cx+1))
	ab.abAppend("\x1b[25h")
	io.WriteString(os.Stdout, ab.String())
}

func editorDrawRows(ab *abuf) {
	for y := 0; y < E.screenRows-1; y++ {
		if y == E.screenRows/3 {
			w := fmt.Sprintf("Kilo editor -- version %s", KILO_VERSION)
			if len(w) > E.screenCols {
				w = w[0:E.screenCols]
			}
			pad := "~ "
			for padding := (E.screenCols - len(w)) / 2; padding > 0; padding-- {
				ab.abAppend(pad)
				pad = " "
			}
			ab.abAppend(w)
		} else {
			ab.abAppend("~")
		}
		ab.abAppend("\x1b[K")
		if y < E.screenRows-1 {
			ab.abAppend("\r\n")
		}
	}
}

/*** init ***/

func initEditor() {
	if getWindowSize(&E.screenRows, &E.screenCols) == -1 {
		die(fmt.Errorf("couldn't get screen size"))
	}
}

func main() {
	enableRawMode()
	defer disableRawMode()
	initEditor()

	for {
		editorRefreshScreen()
		editorProcessKeypress()
	}
}
<|endoftext|>


<commit_before>package btrfs

import (
	"bytes"
	"io/ioutil"
	"os"
	"strings"
	"testing"

	"github.com/pachyderm/pachyderm/src/pfs"
	"github.com/pachyderm/pachyderm/src/pkg/require"
)

var (
	counter int32
)

func TestSimple(t *testing.T) {
	driver1, err := NewDriver(getBtrfsRootDir(t), "drive.TestSimple")
	require.NoError(t, err)
	shards := make(map[uint64]bool)
	shards[0] = true
	repo := &pfs.Repo{Name: "repo1"}
	require.NoError(t, driver1.CreateRepo(repo))
	commit1 := &pfs.Commit{
		Repo: repo,
		Id:   "commit1",
	}
	require.NoError(t, driver1.StartCommit(nil, commit1, shards))
	file1 := &pfs.File{
		Commit: commit1,
		Path:   "foo",
	}
	require.NoError(t, driver1.PutFile(file1, 0, 0, strings.NewReader("foo")))
	require.NoError(t, driver1.FinishCommit(commit1, shards))
	reader, err := driver1.GetFile(file1, 0)
	require.NoError(t, err)
	contents, err := ioutil.ReadAll(reader)
	require.NoError(t, err)
	require.Equal(t, string(contents), "foo")
	commit2 := &pfs.Commit{
		Repo: repo,
		Id:   "commit2",
	}
	require.NoError(t, driver1.StartCommit(commit1, commit2, shards))
	file2 := &pfs.File{
		Commit: commit2,
		Path:   "bar",
	}
	require.NoError(t, driver1.PutFile(file2, 0, 0, strings.NewReader("bar")))
	require.NoError(t, driver1.FinishCommit(commit2, shards))
	changes, err := driver1.ListChange(file2, commit1, 0)
	require.NoError(t, err)
	require.Equal(t, len(changes), 1)
	require.Equal(t, changes[0].File, file2)
	require.Equal(t, changes[0].OffsetBytes, uint64(0))
	require.Equal(t, changes[0].SizeBytes, uint64(3))
	//Replicate repo
	driver2, err := NewDriver(getBtrfsRootDir(t), "drive.TestSimpleReplica")
	require.NoError(t, err)
	require.NoError(t, driver2.CreateRepo(repo))
	var buffer bytes.Buffer
	require.NoError(t, driver1.PullDiff(commit1, 0, &buffer))
	require.NoError(t, driver2.PushDiff(commit1, 0, &buffer))
	buffer = bytes.Buffer{}
	require.NoError(t, driver1.PullDiff(commit2, 0, &buffer))
	require.NoError(t, driver2.PushDiff(commit2, 0, &buffer))
	reader, err = driver2.GetFile(file1, 0)
	require.NoError(t, err)
	contents, err = ioutil.ReadAll(reader)
	require.NoError(t, err)
	require.Equal(t, string(contents), "foo")
	changes, err = driver2.ListChange(file2, commit1, 0)
	require.NoError(t, err)
	require.Equal(t, len(changes), 1)
	require.Equal(t, changes[0].File, file2)
	require.Equal(t, changes[0].OffsetBytes, uint64(0))
	require.Equal(t, changes[0].SizeBytes, uint64(3))
}

func getBtrfsRootDir(tb testing.TB) string {
	// TODO
	rootDir := os.Getenv("PFS_DRIVER_ROOT")
	if rootDir == "" {
		tb.Fatal("PFS_DRIVER_ROOT not set")
	}
	return rootDir
}
<commit_msg>Adds a test for reordered commits.<commit_after>package btrfs

import (
	"bytes"
	"io/ioutil"
	"os"
	"strings"
	"testing"

	"github.com/pachyderm/pachyderm/src/pfs"
	"github.com/pachyderm/pachyderm/src/pkg/require"
)

var (
	counter int32
)

func TestSimple(t *testing.T) {
	driver1, err := NewDriver(getBtrfsRootDir(t), "drive.TestSimple")
	require.NoError(t, err)
	shards := make(map[uint64]bool)
	shards[0] = true
	repo := &pfs.Repo{Name: "repo1"}
	require.NoError(t, driver1.CreateRepo(repo))
	commit1 := &pfs.Commit{
		Repo: repo,
		Id:   "commit1",
	}
	require.NoError(t, driver1.StartCommit(nil, commit1, shards))
	file1 := &pfs.File{
		Commit: commit1,
		Path:   "foo",
	}
	require.NoError(t, driver1.PutFile(file1, 0, 0, strings.NewReader("foo")))
	require.NoError(t, driver1.FinishCommit(commit1, shards))
	reader, err := driver1.GetFile(file1, 0)
	require.NoError(t, err)
	contents, err := ioutil.ReadAll(reader)
	require.NoError(t, err)
	require.Equal(t, string(contents), "foo")
	commit2 := &pfs.Commit{
		Repo: repo,
		Id:   "commit2",
	}
	require.NoError(t, driver1.StartCommit(commit1, commit2, shards))
	file2 := &pfs.File{
		Commit: commit2,
		Path:   "bar",
	}
	require.NoError(t, driver1.PutFile(file2, 0, 0, strings.NewReader("bar")))
	require.NoError(t, driver1.FinishCommit(commit2, shards))
	changes, err := driver1.ListChange(file2, commit1, 0)
	require.NoError(t, err)
	require.Equal(t, len(changes), 1)
	require.Equal(t, changes[0].File, file2)
	require.Equal(t, changes[0].OffsetBytes, uint64(0))
	require.Equal(t, changes[0].SizeBytes, uint64(3))
	//Replicate repo
	driver2, err := NewDriver(getBtrfsRootDir(t), "drive.TestSimpleReplica")
	require.NoError(t, err)
	require.NoError(t, driver2.CreateRepo(repo))
	var buffer bytes.Buffer
	require.NoError(t, driver1.PullDiff(commit1, 0, &buffer))
	require.NoError(t, driver2.PushDiff(commit1, 0, &buffer))
	buffer = bytes.Buffer{}
	require.NoError(t, driver1.PullDiff(commit2, 0, &buffer))
	require.NoError(t, driver2.PushDiff(commit2, 0, &buffer))
	reader, err = driver2.GetFile(file1, 0)
	require.NoError(t, err)
	contents, err = ioutil.ReadAll(reader)
	require.NoError(t, err)
	require.Equal(t, string(contents), "foo")
	changes, err = driver2.ListChange(file2, commit1, 0)
	require.NoError(t, err)
	require.Equal(t, len(changes), 1)
	require.Equal(t, changes[0].File, file2)
	require.Equal(t, changes[0].OffsetBytes, uint64(0))
	require.Equal(t, changes[0].SizeBytes, uint64(3))
}

func TestCommitReordering(t *testing.T) {
	driver1, err := NewDriver(getBtrfsRootDir(t), "drive.TestCommitReordering")
	require.NoError(t, err)
	shards := make(map[uint64]bool)
	shards[0] = true
	repo := &pfs.Repo{Name: "repo1"}
	require.NoError(t, driver1.CreateRepo(repo))
	commit1 := &pfs.Commit{
		Repo: repo,
		Id:   "commit1",
	}
	require.NoError(t, driver1.StartCommit(nil, commit1, shards))
	require.NoError(t, driver1.FinishCommit(commit1, shards))
	commit2 := &pfs.Commit{
		Repo: repo,
		Id:   "commit2",
	}
	require.NoError(t, driver1.StartCommit(commit1, commit2, shards))
	commit3 := &pfs.Commit{
		Repo: repo,
		Id:   "commit3",
	}
	require.NoError(t, driver1.StartCommit(commit1, commit3, shards))
	require.NoError(t, driver1.FinishCommit(commit3, shards))
	require.NoError(t, driver1.FinishCommit(commit2, shards))

	commitInfos, err := driver1.ListCommit(repo, nil, shards)
	require.NoError(t, err)
	require.Equal(t, 3, len(commitInfos))
	require.Equal(t, commitInfos[0].Commit.Id, "commit3")
	require.Equal(t, commitInfos[1].Commit.Id, "commit2")
	require.Equal(t, commitInfos[2].Commit.Id, "commit1")
	//Replicate repo
	driver2, err := NewDriver(getBtrfsRootDir(t), "drive.TestCommitReorderingReplica")
	require.NoError(t, err)
	require.NoError(t, driver2.CreateRepo(repo))
	var buffer bytes.Buffer
	require.NoError(t, driver1.PullDiff(commit1, 0, &buffer))
	require.NoError(t, driver2.PushDiff(commit1, 0, &buffer))
	buffer = bytes.Buffer{}
	require.NoError(t, driver1.PullDiff(commit3, 0, &buffer))
	require.NoError(t, driver2.PushDiff(commit3, 0, &buffer))
	buffer = bytes.Buffer{}
	require.NoError(t, driver1.PullDiff(commit2, 0, &buffer))
	require.NoError(t, driver2.PushDiff(commit2, 0, &buffer))
	commitInfos, err = driver2.ListCommit(repo, nil, shards)
	require.NoError(t, err)
	require.Equal(t, 3, len(commitInfos))
	require.Equal(t, commitInfos[0].Commit.Id, "commit2")
	require.Equal(t, commitInfos[1].Commit.Id, "commit3")
	require.Equal(t, commitInfos[2].Commit.Id, "commit1")
}

func getBtrfsRootDir(tb testing.TB) string {
	// TODO
	rootDir := os.Getenv("PFS_DRIVER_ROOT")
	if rootDir == "" {
		tb.Fatal("PFS_DRIVER_ROOT not set")
	}
	return rootDir
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/codegangsta/cli"
	"github.com/evoL/gif/image"
	"github.com/evoL/gif/store"
	"os"
)

func ListCommand(c *cli.Context) {
	store, err := store.Default()
	if err != nil {
		fmt.Println("Cannot create store: " + err.Error())
		os.Exit(1)
	}
	defer store.Close()

	images, err := store.List()
	if err != nil {
		fmt.Println("Error while fetching: " + err.Error())
		os.Exit(1)
	}

	image.PrintAll(images)
}
<commit_msg>Added image count to the list command.<commit_after>package main

import (
	"fmt"
	"github.com/codegangsta/cli"
	"github.com/evoL/gif/image"
	"github.com/evoL/gif/store"
	"os"
)

func ListCommand(c *cli.Context) {
	store, err := store.Default()
	if err != nil {
		fmt.Println("Cannot create store: " + err.Error())
		os.Exit(1)
	}
	defer store.Close()

	images, err := store.List()
	if err != nil {
		fmt.Println("Error while fetching: " + err.Error())
		os.Exit(1)
	}

	fmt.Printf("%v images\n", len(images))

	image.PrintAll(images)
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"strings"
)

type fileListing struct {
	Files map[string]interface{} `json:"files"`
	Dirs  map[string]interface{} `json:"dirs"`
	Path  string                 `json:"path"`
}

func toStringJoin(in []interface{}, sep string) string {
	s := []string{}
	for _, a := range in {
		s = append(s, a.(string))
	}
	return strings.Join(s, sep)
}

func listFiles(path string, includeMeta bool,
	depth int) (fileListing, error) {

	emptyObject := &(json.RawMessage{'{', '}'})
	viewRes := struct {
		Rows []struct {
			Key   []interface{}
			Value struct {
				Count, Sum, Min, Max int64
			}
		}
	}{}

	// use the requested path to build our view query parameters
	startKey := []interface{}{}
	if path != "" {
		for _, k := range strings.Split(path, "/") {
			startKey = append(startKey, k)
		}
	}
	endKey := make([]interface{}, len(startKey)+1, len(startKey)+1)
	copy(endKey, startKey)
	endKey[len(startKey)] = emptyObject
	groupLevel := len(startKey) + depth

	// query the view
	err := couchbase.ViewCustom("cbfs", "file_browse",
		map[string]interface{}{
			"group_level": groupLevel,
			"start_key":   startKey,
			"end_key":     endKey,
		}, &viewRes)
	if err != nil {
		return fileListing{}, err
	}

	// use the view result to build a list of keys
	keys := make([]string, len(viewRes.Rows), len(viewRes.Rows))
	for i, r := range viewRes.Rows {
		keys[i] = shortName(toStringJoin(r.Key, "/"))
	}

	// do a multi-get on the all the keys returned
	bulkResult := couchbase.GetBulk(keys)

	// divide items up into files and directories
	files := map[string]interface{}{}
	dirs := map[string]interface{}{}
	for _, r := range viewRes.Rows {
		key := shortName(toStringJoin(r.Key, "/"))
		subkey := r.Key
		if len(r.Key) > depth {
			subkey = r.Key[len(r.Key)-depth:]
		}
		name := toStringJoin(subkey, "/")
		res, ok := bulkResult[key]
		if ok == true {
			// this means we have a file
			if includeMeta {
				rm := json.RawMessage(res.Body)
				files[name] = &rm
			} else {
				files[name] = emptyObject
			}
		} else {
			// no record in the multi-get means this is a directory
			dirs[name] = struct {
				Count int64 `json:"descendants"`
				Sum   int64 `json:"size"`
				Min   int64 `json:"smallest"`
				Max   int64 `json:"largest"`
			}{r.Value.Count, r.Value.Sum, r.Value.Min, r.Value.Max}
		}
	}

	rv := fileListing{
		Path:  "/" + path,
		Dirs:  dirs,
		Files: files,
	}

	return rv, nil
}
<commit_msg>More straightforward query params for listing.<commit_after>package main

import (
	"encoding/json"
	"strings"
)

type fileListing struct {
	Files map[string]interface{} `json:"files"`
	Dirs  map[string]interface{} `json:"dirs"`
	Path  string                 `json:"path"`
}

func toStringJoin(in []interface{}, sep string) string {
	s := []string{}
	for _, a := range in {
		s = append(s, a.(string))
	}
	return strings.Join(s, sep)
}

func listFiles(path string, includeMeta bool,
	depth int) (fileListing, error) {

	emptyObject := &(json.RawMessage{'{', '}'})
	viewRes := struct {
		Rows []struct {
			Key   []interface{}
			Value struct {
				Count, Sum, Min, Max int64
			}
		}
	}{}

	// use the requested path to build our view query parameters
	endKey := []interface{}{}
	if path != "" {
		for _, k := range strings.Split(path, "/") {
			endKey = append(endKey, k)
		}
	}
	endKey = append(endKey, emptyObject)
	startKey := endKey[:len(endKey)-1]
	groupLevel := len(startKey) + depth

	// query the view
	err := couchbase.ViewCustom("cbfs", "file_browse",
		map[string]interface{}{
			"group_level": groupLevel,
			"start_key":   startKey,
			"end_key":     endKey,
		}, &viewRes)
	if err != nil {
		return fileListing{}, err
	}

	// use the view result to build a list of keys
	keys := make([]string, len(viewRes.Rows), len(viewRes.Rows))
	for i, r := range viewRes.Rows {
		keys[i] = shortName(toStringJoin(r.Key, "/"))
	}

	// do a multi-get on the all the keys returned
	bulkResult := couchbase.GetBulk(keys)

	// divide items up into files and directories
	files := map[string]interface{}{}
	dirs := map[string]interface{}{}
	for _, r := range viewRes.Rows {
		key := shortName(toStringJoin(r.Key, "/"))
		subkey := r.Key
		if len(r.Key) > depth {
			subkey = r.Key[len(r.Key)-depth:]
		}
		name := toStringJoin(subkey, "/")
		res, ok := bulkResult[key]
		if ok == true {
			// this means we have a file
			if includeMeta {
				rm := json.RawMessage(res.Body)
				files[name] = &rm
			} else {
				files[name] = emptyObject
			}
		} else {
			// no record in the multi-get means this is a directory
			dirs[name] = struct {
				Count int64 `json:"descendants"`
				Sum   int64 `json:"size"`
				Min   int64 `json:"smallest"`
				Max   int64 `json:"largest"`
			}{r.Value.Count, r.Value.Sum, r.Value.Min, r.Value.Max}
		}
	}

	rv := fileListing{
		Path:  "/" + path,
		Dirs:  dirs,
		Files: files,
	}

	return rv, nil
}
<|endoftext|>


<commit_before>package irc

import (
	"fmt"
	"strings"
	"time"
)

type Identifier interface {
	Id() string
}

type Reply interface {
	String(client *Client) string
}

type BasicReply struct {
	source  Identifier
	code    string
	message string
}

func NewBasicReply(source Identifier, code string, message string) *BasicReply {
	fullMessage := fmt.Sprintf(":%s %s %s\r\n", source.Id(), code, message)
	return &BasicReply{source, code, fullMessage}
}

func (reply *BasicReply) String(client *Client) string {
	return reply.message
}

type NumericReply struct {
	*BasicReply
}

func NewNumericReply(source Identifier, code string, message string) *NumericReply {
	return &NumericReply{&BasicReply{source, code, message}}
}

func (reply *NumericReply) String(client *Client) string {
	return fmt.Sprintf(":%s %s %s %s\r\n", reply.source.Id(), reply.code, client.Nick(),
		reply.message)
}

// messaging replies

func RplPrivMsg(source *Client, target *Client, message string) Reply {
	return NewBasicReply(source, RPL_PRIVMSG, fmt.Sprintf("%s :%s", target, message))
}

func RplNick(client *Client, newNick string) Reply {
	return NewBasicReply(client, RPL_NICK, newNick)
}

func RplPrivMsgChannel(channel *Channel, source *Client, message string) Reply {
	return NewBasicReply(source, RPL_PRIVMSG, fmt.Sprintf("%s :%s", channel.name, message))
}

func RplJoin(channel *Channel, client *Client) Reply {
	return NewBasicReply(client, RPL_JOIN, channel.name)
}

func RplPart(channel *Channel, client *Client, message string) Reply {
	return NewBasicReply(client, RPL_PART, fmt.Sprintf("%s :%s", channel.name, message))
}

func RplPong(server *Server) Reply {
	return NewBasicReply(server, RPL_PONG, server.Id())
}

func RplQuit(client *Client, message string) Reply {
	return NewBasicReply(client, RPL_QUIT, ":"+message)
}

func RplInviteMsg(channel *Channel, inviter *Client) Reply {
	return NewBasicReply(inviter, RPL_INVITE, channel.name)
}

// numeric replies

func RplWelcome(source Identifier, client *Client) Reply {
	return NewNumericReply(source, RPL_WELCOME,
		"Welcome to the Internet Relay Network "+client.Id())
}

func RplYourHost(server *Server, target *Client) Reply {
	return NewNumericReply(server, RPL_YOURHOST,
		fmt.Sprintf("Your host is %s, running version %s", server.hostname, VERSION))
}

func RplCreated(server *Server) Reply {
	return NewNumericReply(server, RPL_CREATED,
		"This server was created "+server.ctime.Format(time.RFC1123))
}

func RplMyInfo(server *Server) Reply {
	return NewNumericReply(server, RPL_MYINFO,
		fmt.Sprintf("%s %s w kn", server.name, VERSION))
}

func RplUModeIs(server *Server, client *Client) Reply {
	return NewNumericReply(server, RPL_UMODEIS, client.UModeString())
}

func RplNoTopic(channel *Channel) Reply {
	return NewNumericReply(channel.server, RPL_NOTOPIC, channel.name+" :No topic is set")
}

func RplTopic(channel *Channel) Reply {
	return NewNumericReply(channel.server, RPL_TOPIC, fmt.Sprintf("%s :%s", channel.name, channel.topic))
}

func RplInvitingMsg(channel *Channel, invitee *Client) Reply {
	return NewNumericReply(channel.server, RPL_INVITING,
		fmt.Sprintf("%s %s", channel.name, invitee.Nick()))
}

func RplNamReply(channel *Channel) Reply {
	// TODO multiple names and splitting based on message size
	return NewNumericReply(channel.server, RPL_NAMREPLY,
		fmt.Sprintf("= %s :%s", channel.name, strings.Join(channel.Nicks(), " ")))
}

func RplEndOfNames(source Identifier) Reply {
	return NewNumericReply(source, RPL_ENDOFNAMES, ":End of NAMES list")
}

func RplYoureOper(server *Server) Reply {
	return NewNumericReply(server, RPL_YOUREOPER, ":You are now an IRC operator")
}

// errors (also numeric)

func ErrAlreadyRegistered(source Identifier) Reply {
	return NewNumericReply(source, ERR_ALREADYREGISTRED, ":You may not reregister")
}

func ErrNickNameInUse(source Identifier, nick string) Reply {
	return NewNumericReply(source, ERR_NICKNAMEINUSE,
		nick+" :Nickname is already in use")
}

func ErrUnknownCommand(source Identifier, command string) Reply {
	return NewNumericReply(source, ERR_UNKNOWNCOMMAND,
		command+" :Unknown command")
}

func ErrUsersDontMatch(source Identifier) Reply {
	return NewNumericReply(source, ERR_USERSDONTMATCH,
		":Cannot change mode for other users")
}

func ErrNeedMoreParams(source Identifier, command string) Reply {
	return NewNumericReply(source, ERR_NEEDMOREPARAMS,
		command+"%s :Not enough parameters")
}

func ErrNoSuchChannel(source Identifier, channel string) Reply {
	return NewNumericReply(source, ERR_NOSUCHCHANNEL,
		channel+" :No such channel")
}

func ErrUserOnChannel(channel *Channel, member *Client) Reply {
	return NewNumericReply(channel.server, ERR_USERONCHANNEL,
		fmt.Sprintf("%s %s :is already on channel", member.nick, channel.name))
}

func ErrNotOnChannel(channel *Channel) Reply {
	return NewNumericReply(channel.server, ERR_NOTONCHANNEL,
		channel.name+" :You're not on that channel")
}

func ErrInviteOnlyChannel(channel *Channel) Reply {
	return NewNumericReply(channel.server, ERR_INVITEONLYCHAN,
		channel.name+" :Cannot join channel (+i)")
}

func ErrBadChannelKey(channel *Channel) Reply {
	return NewNumericReply(channel.server, ERR_BADCHANNELKEY,
		channel.name+" :Cannot join channel (+k)")
}

func ErrNoSuchNick(source Identifier, nick string) Reply {
	return NewNumericReply(source, ERR_NOSUCHNICK,
		nick+" :No such nick/channel")
}

func ErrPasswdMismatch(server *Server) Reply {
	return NewNumericReply(server, ERR_PASSWDMISMATCH, ":Password incorrect")
}

func ErrNoChanModes(channel *Channel) Reply {
	return NewNumericReply(channel.server, ERR_NOCHANMODES,
		channel.name+" :Channel doesn't support modes")
}
<commit_msg>formatting<commit_after>package irc

import (
	"fmt"
	"strings"
	"time"
)

type Identifier interface {
	Id() string
}

type Reply interface {
	String(client *Client) string
}

type BasicReply struct {
	source  Identifier
	code    string
	message string
}

func NewBasicReply(source Identifier, code string, message string) *BasicReply {
	fullMessage := fmt.Sprintf(":%s %s %s\r\n", source.Id(), code, message)
	return &BasicReply{source, code, fullMessage}
}

func (reply *BasicReply) String(client *Client) string {
	return reply.message
}

type NumericReply struct {
	*BasicReply
}

func NewNumericReply(source Identifier, code string, message string) *NumericReply {
	return &NumericReply{&BasicReply{source, code, message}}
}

func (reply *NumericReply) String(client *Client) string {
	return fmt.Sprintf(":%s %s %s %s\r\n", reply.source.Id(), reply.code, client.Nick(),
		reply.message)
}

// messaging replies

func RplPrivMsg(source *Client, target *Client, message string) Reply {
	return NewBasicReply(source, RPL_PRIVMSG, fmt.Sprintf("%s :%s", target, message))
}

func RplNick(client *Client, newNick string) Reply {
	return NewBasicReply(client, RPL_NICK, newNick)
}

func RplPrivMsgChannel(channel *Channel, source *Client, message string) Reply {
	return NewBasicReply(source, RPL_PRIVMSG, fmt.Sprintf("%s :%s", channel.name, message))
}

func RplJoin(channel *Channel, client *Client) Reply {
	return NewBasicReply(client, RPL_JOIN, channel.name)
}

func RplPart(channel *Channel, client *Client, message string) Reply {
	return NewBasicReply(client, RPL_PART, fmt.Sprintf("%s :%s", channel.name, message))
}

func RplPong(server *Server) Reply {
	return NewBasicReply(server, RPL_PONG, server.Id())
}

func RplQuit(client *Client, message string) Reply {
	return NewBasicReply(client, RPL_QUIT, ":"+message)
}

func RplInviteMsg(channel *Channel, inviter *Client) Reply {
	return NewBasicReply(inviter, RPL_INVITE, channel.name)
}

// numeric replies

func RplWelcome(source Identifier, client *Client) Reply {
	return NewNumericReply(source, RPL_WELCOME,
		"Welcome to the Internet Relay Network "+client.Id())
}

func RplYourHost(server *Server, target *Client) Reply {
	return NewNumericReply(server, RPL_YOURHOST,
		fmt.Sprintf("Your host is %s, running version %s", server.hostname, VERSION))
}

func RplCreated(server *Server) Reply {
	return NewNumericReply(server, RPL_CREATED,
		"This server was created "+server.ctime.Format(time.RFC1123))
}

func RplMyInfo(server *Server) Reply {
	return NewNumericReply(server, RPL_MYINFO,
		fmt.Sprintf("%s %s w kn", server.name, VERSION))
}

func RplUModeIs(server *Server, client *Client) Reply {
	return NewNumericReply(server, RPL_UMODEIS, client.UModeString())
}

func RplNoTopic(channel *Channel) Reply {
	return NewNumericReply(channel.server, RPL_NOTOPIC, channel.name+" :No topic is set")
}

func RplTopic(channel *Channel) Reply {
	return NewNumericReply(channel.server, RPL_TOPIC,
		fmt.Sprintf("%s :%s", channel.name, channel.topic))
}

func RplInvitingMsg(channel *Channel, invitee *Client) Reply {
	return NewNumericReply(channel.server, RPL_INVITING,
		fmt.Sprintf("%s %s", channel.name, invitee.Nick()))
}

func RplNamReply(channel *Channel) Reply {
	// TODO multiple names and splitting based on message size
	return NewNumericReply(channel.server, RPL_NAMREPLY,
		fmt.Sprintf("= %s :%s", channel.name, strings.Join(channel.Nicks(), " ")))
}

func RplEndOfNames(source Identifier) Reply {
	return NewNumericReply(source, RPL_ENDOFNAMES, ":End of NAMES list")
}

func RplYoureOper(server *Server) Reply {
	return NewNumericReply(server, RPL_YOUREOPER, ":You are now an IRC operator")
}

// errors (also numeric)

func ErrAlreadyRegistered(source Identifier) Reply {
	return NewNumericReply(source, ERR_ALREADYREGISTRED, ":You may not reregister")
}

func ErrNickNameInUse(source Identifier, nick string) Reply {
	return NewNumericReply(source, ERR_NICKNAMEINUSE,
		nick+" :Nickname is already in use")
}

func ErrUnknownCommand(source Identifier, command string) Reply {
	return NewNumericReply(source, ERR_UNKNOWNCOMMAND,
		command+" :Unknown command")
}

func ErrUsersDontMatch(source Identifier) Reply {
	return NewNumericReply(source, ERR_USERSDONTMATCH,
		":Cannot change mode for other users")
}

func ErrNeedMoreParams(source Identifier, command string) Reply {
	return NewNumericReply(source, ERR_NEEDMOREPARAMS,
		command+"%s :Not enough parameters")
}

func ErrNoSuchChannel(source Identifier, channel string) Reply {
	return NewNumericReply(source, ERR_NOSUCHCHANNEL,
		channel+" :No such channel")
}

func ErrUserOnChannel(channel *Channel, member *Client) Reply {
	return NewNumericReply(channel.server, ERR_USERONCHANNEL,
		fmt.Sprintf("%s %s :is already on channel", member.nick, channel.name))
}

func ErrNotOnChannel(channel *Channel) Reply {
	return NewNumericReply(channel.server, ERR_NOTONCHANNEL,
		channel.name+" :You're not on that channel")
}

func ErrInviteOnlyChannel(channel *Channel) Reply {
	return NewNumericReply(channel.server, ERR_INVITEONLYCHAN,
		channel.name+" :Cannot join channel (+i)")
}

func ErrBadChannelKey(channel *Channel) Reply {
	return NewNumericReply(channel.server, ERR_BADCHANNELKEY,
		channel.name+" :Cannot join channel (+k)")
}

func ErrNoSuchNick(source Identifier, nick string) Reply {
	return NewNumericReply(source, ERR_NOSUCHNICK,
		nick+" :No such nick/channel")
}

func ErrPasswdMismatch(server *Server) Reply {
	return NewNumericReply(server, ERR_PASSWDMISMATCH, ":Password incorrect")
}

func ErrNoChanModes(channel *Channel) Reply {
	return NewNumericReply(channel.server, ERR_NOCHANMODES,
		channel.name+" :Channel doesn't support modes")
}
<|endoftext|>


<commit_before>package main

// #cgo LDFLAGS: -lm
// #include "tclled.h"
import "C"
import "fmt"
import "time"
import "errors"

//////////////////
// STRAND CODE
//////////////////

type Strand struct {
	device   C.int
	buffer   *_Ctype_tcl_buffer
	ledCount int
}

func (s *Strand) Connect(ledCount int) error {
	s.ledCount = ledCount
	s.device = C.open_device()

	if s.device <= 0 {
		return errors.New("Device init failed")
	}

	C.set_gamma(2.2, 2.2, 2.2)
	spiStatus := C.spi_init(s.device)
	if spiStatus != 0 {
		return errors.New("SPI init failed")
	}

	s.buffer = &C.tcl_buffer{}
	tclStatus := C.tcl_init(s.buffer, C.int(s.ledCount))
	if tclStatus != 0 {
		return errors.New("TCL init failed")
	}

	for i := 0; i < ledCount; i++ {
		s.SetColor(i, 0, 0, 0)
	}
	s.Save()

	return nil
}

func (s *Strand) Free() error {
	C.tcl_free(s.buffer)
	C.close_device(s.device)
	fmt.Println("closed!")

	return nil
}

func (s *Strand) SetColor(ledNumber int, r int, g int, b int) {
	C.write_gamma_color_to_buffer(s.buffer, C.int(ledNumber), C.uint8_t(r), C.uint8_t(g), C.uint8_t(b))
}

func (s *Strand) Save() {
	C.send_buffer(s.device, s.buffer)
}

//////////////////
// BOARD CODE
//////////////////

type Board struct {
	strand  *Strand
	pixelW  int
	pixelH  int
	squareW int
	squareH int
}

func (brd *Board) Connect(pixelW int, pixelH int, squareW int, squareH int) error {
	brd.pixelW = pixelW
	brd.pixelH = pixelH
	brd.squareW = squareW
	brd.squareH = squareH
	brd.strand = &Strand{}
	return brd.strand.Connect(pixelW * pixelH)
}

func (brd *Board) Free() {
	brd.strand.Free()
}

func (brd *Board) Save() {
	brd.strand.Save()
}

func getPixelNum(x int, y int) int {
	xSq := x / 5
	ySq := y / 5
	var boardNum, pixelNum int

	// NOTE: this is hardcoded for a 4 x 5 board with 25px/square
	if ySq%2 == 0 {
		boardNum = ySq*4 + xSq
	} else {
		boardNum = ySq*4 + 3 - xSq
	}

	xPixelInSq := x % 5
	yPixelInSq := y % 5

	if yPixelInSq%2 == 0 {
		pixelNum = yPixelInSq*5 + xPixelInSq
	} else {
		pixelNum = yPixelInSq*5 + 4 - xPixelInSq
	}

	return boardNum*25 + pixelNum
}

func (brd *Board) DrawPixel(x int, y int, r int, g int, b int) {
	pixelNum := getPixelNum(x, y)
	// fmt.Println("Pixel Drawn at: (", x, y, ") ->", pixelNum)
	brd.strand.SetColor(pixelNum, r, g, b)
}

func (brd *Board) SetColor(x int, r int, g int, b int) {
	// fmt.Println("(", r, g, b, ") Pixel Drawn ->", x)
	// fmt.Println("Double Checking: () ->", x)
	brd.strand.SetColor(x, r, g, b)
}

func main() {
	fmt.Println("foo3")
	board := Board{}

	w := 20
	h := 25
	err := board.Connect(w, h, 4, 5)
	defer board.Free()

	// if err != nil {
	// 	fmt.Print("Error: ")
	// 	fmt.Println(err)
	// 	return
	// }
	// for {
	// 	x := 0
	// 	r := 0
	// 	g := 0
	// 	b := 0

	// 	fmt.Scan(&x, &r, &g, &b)
	// 	board.SetColor(x, r, g, b)
	// 	board.Save()
	// }

	// board := Strand{}
	// c := 500
	// err := board.Connect(c)

	if err != nil {
		fmt.Print("Error: ")
		fmt.Println(err)
		return
	}
	// for {
	// 	r := 0
	// 	g := 0
	// 	b := 0
	// 	x := 0
	// 	fmt.Scan(&x, &r, &g, &b)
	// 	board.SetColor(x, r, g, b)
	// 	board.Save()
	// }

	fmt.Println("foo2")
	xPix := 0
	yPix := 0
	for {
		xPix++
		if xPix > w {
			xPix = 0
			yPix++
		}
		if yPix > h {
			xPix = 0
			yPix = 0
		}
		fmt.Println("foo")
		fmt.Println(xPix, yPix)

		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				if x == xPix && y == yPix {
					board.DrawPixel(x, y, 100, 100, 100)
				} else {
					board.DrawPixel(x, y, 0, 0, 0)
				}
			}
		}
		board.Save()
		time.Sleep(20 * time.Millisecond)
	}
}
<commit_msg>Remove comments and test prints<commit_after>package main

// #cgo LDFLAGS: -lm
// #include "tclled.h"
import "C"
import "fmt"
import "time"
import "errors"

//////////////////
// STRAND CODE
//////////////////

type Strand struct {
	device   C.int
	buffer   *_Ctype_tcl_buffer
	ledCount int
}

func (s *Strand) Connect(ledCount int) error {
	s.ledCount = ledCount
	s.device = C.open_device()

	if s.device <= 0 {
		return errors.New("Device init failed")
	}

	C.set_gamma(2.2, 2.2, 2.2)
	spiStatus := C.spi_init(s.device)
	if spiStatus != 0 {
		return errors.New("SPI init failed")
	}

	s.buffer = &C.tcl_buffer{}
	tclStatus := C.tcl_init(s.buffer, C.int(s.ledCount))
	if tclStatus != 0 {
		return errors.New("TCL init failed")
	}

	for i := 0; i < ledCount; i++ {
		s.SetColor(i, 0, 0, 0)
	}
	s.Save()

	return nil
}

func (s *Strand) Free() error {
	C.tcl_free(s.buffer)
	C.close_device(s.device)
	fmt.Println("closed!")

	return nil
}

func (s *Strand) SetColor(ledNumber int, r int, g int, b int) {
	C.write_gamma_color_to_buffer(s.buffer, C.int(ledNumber), C.uint8_t(r), C.uint8_t(g), C.uint8_t(b))
}

func (s *Strand) Save() {
	C.send_buffer(s.device, s.buffer)
}

//////////////////
// BOARD CODE
//////////////////

type Board struct {
	strand  *Strand
	pixelW  int
	pixelH  int
	squareW int
	squareH int
}

func (brd *Board) Connect(pixelW int, pixelH int, squareW int, squareH int) error {
	brd.pixelW = pixelW
	brd.pixelH = pixelH
	brd.squareW = squareW
	brd.squareH = squareH
	brd.strand = &Strand{}
	return brd.strand.Connect(pixelW * pixelH)
}

func (brd *Board) Free() {
	brd.strand.Free()
}

func (brd *Board) Save() {
	brd.strand.Save()
}

func getPixelNum(x int, y int) int {
	xSq := x / 5
	ySq := y / 5
	var boardNum, pixelNum int

	// NOTE: this is hardcoded for a 4 x 5 board with 25px/square
	if ySq%2 == 0 {
		boardNum = ySq*4 + xSq
	} else {
		boardNum = ySq*4 + 3 - xSq
	}

	xPixelInSq := x % 5
	yPixelInSq := y % 5

	if yPixelInSq%2 == 0 {
		pixelNum = yPixelInSq*5 + xPixelInSq
	} else {
		pixelNum = yPixelInSq*5 + 4 - xPixelInSq
	}

	return boardNum*25 + pixelNum
}

func (brd *Board) DrawPixel(x int, y int, r int, g int, b int) {
	pixelNum := getPixelNum(x, y)
	brd.strand.SetColor(pixelNum, r, g, b)
}

func (brd *Board) SetColor(x int, r int, g int, b int) {
	brd.strand.SetColor(x, r, g, b)
}

func main() {
	board := Board{}

	w := 20
	h := 25
	err := board.Connect(w, h, 4, 5)
	defer board.Free()

	if err != nil {
		fmt.Print("Error: ")
		fmt.Println(err)
		return
	}
	xPix := 0
	yPix := 0
	for {
		xPix++
		if xPix > w {
			xPix = 0
			yPix++
		}
		if yPix > h {
			xPix = 0
			yPix = 0
		}

		for x := 0; x < w; x++ {
			for y := 0; y < h; y++ {
				if x == xPix && y == yPix {
					board.DrawPixel(x, y, 100, 100, 100)
				} else {
					board.DrawPixel(x, y, 0, 0, 0)
				}
			}
		}
		board.Save()
		time.Sleep(20 * time.Millisecond)
	}
}
<|endoftext|>