<commit_before>package migration

import (
	"database/sql"
	"errors"
	"fmt"
	"os"
	"sort"
	"time"

	"code.cloudfoundry.org/bbs/db"
	"code.cloudfoundry.org/bbs/db/etcd"
	"code.cloudfoundry.org/bbs/encryption"
	"code.cloudfoundry.org/bbs/models"
	"code.cloudfoundry.org/clock"
	loggingclient "code.cloudfoundry.org/diego-logging-client"
	"code.cloudfoundry.org/lager"
)

const (
	migrationDuration = "MigrationDuration"
)

type Manager struct {
	logger         lager.Logger
	etcdDB         db.DB
	storeClient    etcd.StoreClient
	sqlDB          db.DB
	rawSQLDB       *sql.DB
	cryptor        encryption.Cryptor
	migrations     []Migration
	migrationsDone chan<- struct{}
	clock          clock.Clock
	databaseDriver string
	metronClient   loggingclient.IngressClient
}

func NewManager(
	logger lager.Logger,
	etcdDB db.DB,
	etcdStoreClient etcd.StoreClient,
	sqlDB db.DB,
	rawSQLDB *sql.DB,
	cryptor encryption.Cryptor,
	migrations Migrations,
	migrationsDone chan<- struct{},
	clock clock.Clock,
	databaseDriver string,
	metronClient loggingclient.IngressClient,
) Manager {
	sort.Sort(migrations)

	return Manager{
		logger:         logger,
		etcdDB:         etcdDB,
		storeClient:    etcdStoreClient,
		sqlDB:          sqlDB,
		rawSQLDB:       rawSQLDB,
		cryptor:        cryptor,
		migrations:     migrations,
		migrationsDone: migrationsDone,
		clock:          clock,
		databaseDriver: databaseDriver,
		metronClient:   metronClient,
	}
}

func (m Manager) Run(signals <-chan os.Signal, ready chan<- struct{}) error {
	logger := m.logger.Session("migration-manager")
	logger.Info("starting")

	lastETCDMigrationVersion := m.lastETCDMigrationVersion()

	var maxMigrationVersion int64
	if len(m.migrations) > 0 {
		maxMigrationVersion = m.migrations[len(m.migrations)-1].Version()
	}

	version, err := m.resolveStoredVersion(logger)
	if err != nil {
		return err
	}

	if !m.hasSQLConfigured() {
		logger.Info("no-sql-configuration")
		maxMigrationVersion = lastETCDMigrationVersion
	}

	if version == nil {
		if m.hasETCDConfigured() && !m.hasSQLConfigured() {
			logger.Info("fresh-etcd-skipping-migrations")
			err = m.writeVersion(lastETCDMigrationVersion, lastETCDMigrationVersion, lastETCDMigrationVersion)
			if err != nil {
				return err
			}

			m.finish(logger, ready)

			select {
			case <-signals:
				logger.Info("migration-interrupt")
				return nil
			}
		} else if m.hasSQLConfigured() {
			logger.Info("sql-is-configured")
			version = &models.Version{
				CurrentVersion: lastETCDMigrationVersion,
				TargetVersion:  maxMigrationVersion,
			}
			err = m.writeVersion(lastETCDMigrationVersion, maxMigrationVersion, lastETCDMigrationVersion)
			if err != nil {
				return err
			}
		} else {
			err := errors.New("no database configured")
			logger.Error("no-database-configured", err)
			return err
		}
	}

	if version.TargetVersion < version.CurrentVersion {
		return fmt.Errorf(
			"Existing DB target version (%d) exceeds current version (%d)",
			version.TargetVersion,
			version.CurrentVersion,
		)
	}

	if version.CurrentVersion > maxMigrationVersion {
		return fmt.Errorf(
			"Existing DB version (%d) exceeds bbs version (%d)",
			version.CurrentVersion,
			maxMigrationVersion,
		)
	}

	if version.TargetVersion != maxMigrationVersion {
		if version.TargetVersion > maxMigrationVersion {
			version.TargetVersion = maxMigrationVersion
		}

		logger.Info("running-migrations", lager.Data{
			"from_version": version.CurrentVersion,
			"to_version":   maxMigrationVersion,
		})

		m.writeVersion(version.CurrentVersion, maxMigrationVersion, lastETCDMigrationVersion)
	}

	errorChan := make(chan error)
	go m.performMigration(logger, version, maxMigrationVersion, lastETCDMigrationVersion, errorChan, ready)
	defer logger.Info("exited")

	select {
	case err := <-errorChan:
		logger.Error("migration-failed", err)
		return err
	case <-signals:
		logger.Info("migration-interrupt")
		return nil
	}
}

func (m *Manager) performMigration(
	logger lager.Logger,
	version *models.Version,
	maxMigrationVersion int64,
	lastETCDMigrationVersion int64,
	errorChan chan error,
	readyChan chan<- struct{},
) {
	migrateStart := m.clock.Now()
	if version.CurrentVersion != maxMigrationVersion {
		lastVersion := version.CurrentVersion
		nextVersion := version.CurrentVersion

		for _, currentMigration := range m.migrations {
			if maxMigrationVersion < currentMigration.Version() {
				break
			}

			if lastVersion < currentMigration.Version() {
				if nextVersion > currentMigration.Version() {
					errorChan <- fmt.Errorf(
						"Existing DB target version (%d) exceeds pending migration version (%d)",
						nextVersion,
						currentMigration.Version(),
					)
				}

				nextVersion = currentMigration.Version()
				logger.Info("running-migration", lager.Data{
					"current_version":   lastVersion,
					"migration_version": nextVersion,
				})

				currentMigration.SetCryptor(m.cryptor)
				if lastVersion <= lastETCDMigrationVersion {
					currentMigration.SetStoreClient(m.storeClient)
				}
				currentMigration.SetRawSQLDB(m.rawSQLDB)
				currentMigration.SetClock(m.clock)
				currentMigration.SetDBFlavor(m.databaseDriver)

				err := currentMigration.Up(m.logger.Session("migration"))
				if err != nil {
					errorChan <- err
					return
				}

				lastVersion = nextVersion
				err = m.writeVersion(lastVersion, maxMigrationVersion, lastETCDMigrationVersion)
				if err != nil {
					errorChan <- err
					return
				}
				logger.Info("completed-migration", lager.Data{
					"current_version": lastVersion,
					"target_version":  maxMigrationVersion,
				})
			}
		}
	}

	logger.Debug("migrations-finished")

	err := m.metronClient.SendDuration(migrationDuration, time.Since(migrateStart))
	if err != nil {
		logger.Error("failed-to-send-migration-duration-metric", err)
	}

	m.finish(logger, readyChan)
}

func (m *Manager) finish(logger lager.Logger, ready chan<- struct{}) {
	close(ready)
	close(m.migrationsDone)
	logger.Info("finished-migrations")
}

func (m *Manager) findMaxTargetVersion() (int, int64) {
	if len(m.migrations) > 0 {
		if m.rawSQLDB == nil {
			for i, migration := range m.migrations {
				if migration.RequiresSQL() {
					return i, m.migrations[i-1].Version()
				}
			}
		}
		return len(m.migrations), m.migrations[len(m.migrations)-1].Version()
	}
	return 0, 0
}

func (m *Manager) lastETCDMigrationVersion() int64 {
	if len(m.migrations) > 0 {
		for i, migration := range m.migrations {
			if migration.RequiresSQL() {
				if i == 0 {
					return 0
				}
				return m.migrations[i-1].Version()
			}
		}
		return m.migrations[len(m.migrations)-1].Version()
	}
	return 0
}

// returns nil, nil if no version is found
func (m *Manager) resolveStoredVersion(logger lager.Logger) (*models.Version, error) {
	var (
		version *models.Version
		err     error
	)

	if m.hasSQLConfigured() {
		version, err = m.sqlDB.Version(logger)
		if err == nil {
			return version, nil
		} else if models.ConvertError(err) != models.ErrResourceNotFound {
			return nil, err
		}
	}

	if m.hasETCDConfigured() {
		version, err = m.etcdDB.Version(logger)
		if err != nil {
			if models.ConvertError(err) == models.ErrResourceNotFound {
				return nil, nil // totally fresh deploy
			}
			return nil, err
		}
		return version, nil
	}
	return nil, nil
}

func (m *Manager) writeVersion(currentVersion, targetVersion, lastETCDMigrationVersion int64) error {
	if m.hasSQLConfigured() {
		err := m.sqlDB.SetVersion(m.logger, &models.Version{
			CurrentVersion: currentVersion,
			TargetVersion:  targetVersion,
		})

		if err != nil {
			return err
		}
	}

	if m.hasETCDConfigured() {
		if currentVersion > lastETCDMigrationVersion {
			// make it lastETCDMigration plus 1 to indicate it's past ETCD to SQL
			currentVersion = lastETCDMigrationVersion + 1
		}
		err := m.etcdDB.SetVersion(m.logger, &models.Version{
			CurrentVersion: currentVersion,
			TargetVersion:  targetVersion,
		})
		if err != nil {
			return err
		}
	}

	return nil
}

func (m *Manager) hasETCDConfigured() bool {
	return m.storeClient != nil
}

func (m *Manager) hasSQLConfigured() bool {
	return m.rawSQLDB != nil
}

type Migrations []Migration

func (m Migrations) Len() int           { return len(m) }
func (m Migrations) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }
func (m Migrations) Less(i, j int) bool { return m[i].Version() < m[j].Version() }
<commit_msg>simplify migration manager<commit_after>package migration

import (
	"database/sql"
	"errors"
	"fmt"
	"os"
	"sort"
	"time"

	"code.cloudfoundry.org/bbs/db"
	"code.cloudfoundry.org/bbs/db/etcd"
	"code.cloudfoundry.org/bbs/encryption"
	"code.cloudfoundry.org/bbs/models"
	"code.cloudfoundry.org/clock"
	loggingclient "code.cloudfoundry.org/diego-logging-client"
	"code.cloudfoundry.org/lager"
)

const (
	migrationDuration = "MigrationDuration"
)

type Manager struct {
	logger         lager.Logger
	etcdDB         db.DB
	storeClient    etcd.StoreClient
	sqlDB          db.DB
	rawSQLDB       *sql.DB
	cryptor        encryption.Cryptor
	migrations     []Migration
	migrationsDone chan<- struct{}
	clock          clock.Clock
	databaseDriver string
	metronClient   loggingclient.IngressClient
}

func NewManager(
	logger lager.Logger,
	etcdDB db.DB,
	etcdStoreClient etcd.StoreClient,
	sqlDB db.DB,
	rawSQLDB *sql.DB,
	cryptor encryption.Cryptor,
	migrations Migrations,
	migrationsDone chan<- struct{},
	clock clock.Clock,
	databaseDriver string,
	metronClient loggingclient.IngressClient,
) Manager {
	sort.Sort(migrations)

	return Manager{
		logger:         logger,
		etcdDB:         etcdDB,
		storeClient:    etcdStoreClient,
		sqlDB:          sqlDB,
		rawSQLDB:       rawSQLDB,
		cryptor:        cryptor,
		migrations:     migrations,
		migrationsDone: migrationsDone,
		clock:          clock,
		databaseDriver: databaseDriver,
		metronClient:   metronClient,
	}
}

func (m Manager) Run(signals <-chan os.Signal, ready chan<- struct{}) error {
	logger := m.logger.Session("migration-manager")
	logger.Info("starting")

	lastETCDMigrationVersion := m.lastETCDMigrationVersion()

	var maxMigrationVersion int64
	if len(m.migrations) > 0 {
		maxMigrationVersion = m.migrations[len(m.migrations)-1].Version()
	}

	version, err := m.resolveStoredVersion(logger)
	if err != nil {
		return err
	}

	if !m.hasSQLConfigured() {
		logger.Info("no-sql-configuration")
		maxMigrationVersion = lastETCDMigrationVersion
	}

	if version == nil {
		if m.hasETCDConfigured() && !m.hasSQLConfigured() {
			logger.Info("fresh-etcd-skipping-migrations")
			err = m.writeVersion(lastETCDMigrationVersion, lastETCDMigrationVersion, lastETCDMigrationVersion)
			if err != nil {
				return err
			}

			m.finish(logger, ready)

			select {
			case <-signals:
				logger.Info("migration-interrupt")
				return nil
			}
		} else if m.hasSQLConfigured() {
			logger.Info("sql-is-configured")
			version = &models.Version{
				CurrentVersion: lastETCDMigrationVersion,
				TargetVersion:  maxMigrationVersion,
			}
			err = m.writeVersion(lastETCDMigrationVersion, maxMigrationVersion, lastETCDMigrationVersion)
			if err != nil {
				return err
			}
		} else {
			err := errors.New("no database configured")
			logger.Error("no-database-configured", err)
			return err
		}
	}

	if version.CurrentVersion > maxMigrationVersion {
		return fmt.Errorf(
			"Existing DB version (%d) exceeds bbs version (%d)",
			version.CurrentVersion,
			maxMigrationVersion,
		)
	}

	if version.TargetVersion != maxMigrationVersion {
		if version.TargetVersion > maxMigrationVersion {
			version.TargetVersion = maxMigrationVersion
		}

		logger.Info("running-migrations", lager.Data{
			"from_version": version.CurrentVersion,
			"to_version":   maxMigrationVersion,
		})

		m.writeVersion(version.CurrentVersion, maxMigrationVersion, lastETCDMigrationVersion)
	}

	errorChan := make(chan error)
	go m.performMigration(logger, version, maxMigrationVersion, lastETCDMigrationVersion, errorChan, ready)
	defer logger.Info("exited")

	select {
	case err := <-errorChan:
		logger.Error("migration-failed", err)
		return err
	case <-signals:
		logger.Info("migration-interrupt")
		return nil
	}
}

func (m *Manager) performMigration(
	logger lager.Logger,
	version *models.Version,
	maxMigrationVersion int64,
	lastETCDMigrationVersion int64,
	errorChan chan error,
	readyChan chan<- struct{},
) {
	migrateStart := m.clock.Now()
	if version.CurrentVersion != maxMigrationVersion {
		lastVersion := version.CurrentVersion

		for _, currentMigration := range m.migrations {
			if maxMigrationVersion < currentMigration.Version() {
				break
			}

			if lastVersion < currentMigration.Version() {
				if nextVersion > currentMigration.Version() {
					errorChan <- fmt.Errorf(
						"Existing DB target version (%d) exceeds pending migration version (%d)",
						nextVersion,
						currentMigration.Version(),
					)
				}

				nextVersion = currentMigration.Version()
				logger.Info("running-migration", lager.Data{
					"current_version":   lastVersion,
					"migration_version": nextVersion,
				})

				currentMigration.SetCryptor(m.cryptor)
				if lastVersion <= lastETCDMigrationVersion {
					currentMigration.SetStoreClient(m.storeClient)
				}
				currentMigration.SetRawSQLDB(m.rawSQLDB)
				currentMigration.SetClock(m.clock)
				currentMigration.SetDBFlavor(m.databaseDriver)

				err := currentMigration.Up(m.logger.Session("migration"))
				if err != nil {
					errorChan <- err
					return
				}

				lastVersion = nextVersion
				err = m.writeVersion(lastVersion, maxMigrationVersion, lastETCDMigrationVersion)
				if err != nil {
					errorChan <- err
					return
				}
				logger.Info("completed-migration", lager.Data{
					"current_version": lastVersion,
					"target_version":  maxMigrationVersion,
				})
			}
		}
	}

	logger.Debug("migrations-finished")

	err := m.metronClient.SendDuration(migrationDuration, time.Since(migrateStart))
	if err != nil {
		logger.Error("failed-to-send-migration-duration-metric", err)
	}

	m.finish(logger, readyChan)
}

func (m *Manager) finish(logger lager.Logger, ready chan<- struct{}) {
	close(ready)
	close(m.migrationsDone)
	logger.Info("finished-migrations")
}

func (m *Manager) findMaxTargetVersion() (int, int64) {
	if len(m.migrations) > 0 {
		if m.rawSQLDB == nil {
			for i, migration := range m.migrations {
				if migration.RequiresSQL() {
					return i, m.migrations[i-1].Version()
				}
			}
		}
		return len(m.migrations), m.migrations[len(m.migrations)-1].Version()
	}
	return 0, 0
}

func (m *Manager) lastETCDMigrationVersion() int64 {
	if len(m.migrations) > 0 {
		for i, migration := range m.migrations {
			if migration.RequiresSQL() {
				if i == 0 {
					return 0
				}
				return m.migrations[i-1].Version()
			}
		}
		return m.migrations[len(m.migrations)-1].Version()
	}
	return 0
}

// returns nil, nil if no version is found
func (m *Manager) resolveStoredVersion(logger lager.Logger) (*models.Version, error) {
	var (
		version *models.Version
		err     error
	)

	if m.hasSQLConfigured() {
		version, err = m.sqlDB.Version(logger)
		if err == nil {
			return version, nil
		} else if models.ConvertError(err) != models.ErrResourceNotFound {
			return nil, err
		}
	}

	if m.hasETCDConfigured() {
		version, err = m.etcdDB.Version(logger)
		if err != nil {
			if models.ConvertError(err) == models.ErrResourceNotFound {
				return nil, nil // totally fresh deploy
			}
			return nil, err
		}
		return version, nil
	}
	return nil, nil
}

func (m *Manager) writeVersion(currentVersion, targetVersion, lastETCDMigrationVersion int64) error {
	if m.hasSQLConfigured() {
		err := m.sqlDB.SetVersion(m.logger, &models.Version{
			CurrentVersion: currentVersion,
			TargetVersion:  targetVersion,
		})

		if err != nil {
			return err
		}
	}

	if m.hasETCDConfigured() {
		if currentVersion > lastETCDMigrationVersion {
			// make it lastETCDMigration plus 1 to indicate it's past ETCD to SQL
			currentVersion = lastETCDMigrationVersion + 1
		}
		err := m.etcdDB.SetVersion(m.logger, &models.Version{
			CurrentVersion: currentVersion,
			TargetVersion:  targetVersion,
		})
		if err != nil {
			return err
		}
	}

	return nil
}

func (m *Manager) hasETCDConfigured() bool {
	return m.storeClient != nil
}

func (m *Manager) hasSQLConfigured() bool {
	return m.rawSQLDB != nil
}

type Migrations []Migration

func (m Migrations) Len() int           { return len(m) }
func (m Migrations) Swap(i, j int)      { m[i], m[j] = m[j], m[i] }
func (m Migrations) Less(i, j int) bool { return m[i].Version() < m[j].Version() }
<|endoftext|>


<commit_before>package cloudflare

import (
	"context"
	"errors"
	"fmt"
	"net/http"
)

var (
	ErrMissingIP  = errors.New("ip is required when using 'ipv4' or 'ipv6' indicator type and is missing")
	ErrMissingURL = errors.New("url is required when using 'domain' or 'url' indicator type and is missing")
)

// MisCategorizationParameters represents the parameters for a miscategorization request.
type MisCategorizationParameters struct {
	AccountID       string
	IndicatorType   string `json:"indicator_type,omitempty"`
	IP              string `json:"ip,omitempty"`
	URL             string `json:"url,omitempty"`
	ContentAdds     []int  `json:"content_adds,omitempty"`
	ContentRemoves  []int  `json:"content_removes,omitempty"`
	SecurityAdds    []int  `json:"security_adds,omitempty"`
	SecurityRemoves []int  `json:"security_removes,omitempty"`
}

func (api *API) CreateMiscategorization(ctx context.Context, params MisCategorizationParameters) error {
	if params.AccountID == "" {
		return ErrMissingAccountID
	}
	if (params.IndicatorType == "ipv6" || params.IndicatorType == "ipv4") && params.IP == "" {
		return ErrMissingIP
	}
	if (params.IndicatorType == "domain" || params.IndicatorType == "url") && params.URL == "" {
		return ErrMissingURL
	}

	uri := fmt.Sprintf("/accounts/%s/intel/miscategorization", params.AccountID)
	_, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>Better documentation<commit_after>package cloudflare

import (
	"context"
	"errors"
	"fmt"
	"net/http"
)

var (
	// ErrMissingIP is for when ipv4 or ipv6 indicator was given but ip is missing.
	ErrMissingIP = errors.New("ip is required when using 'ipv4' or 'ipv6' indicator type and is missing")
	// ErrMissingURL is for when url or domain indicator was given but url is missing.
	ErrMissingURL = errors.New("url is required when using 'domain' or 'url' indicator type and is missing")
)

// MisCategorizationParameters represents the parameters for a miscategorization request.
type MisCategorizationParameters struct {
	AccountID       string
	IndicatorType   string `json:"indicator_type,omitempty"`
	IP              string `json:"ip,omitempty"`
	URL             string `json:"url,omitempty"`
	ContentAdds     []int  `json:"content_adds,omitempty"`
	ContentRemoves  []int  `json:"content_removes,omitempty"`
	SecurityAdds    []int  `json:"security_adds,omitempty"`
	SecurityRemoves []int  `json:"security_removes,omitempty"`
}

// CreateMiscategorization creates a miscatergorization.
//
// API Reference: https://api.cloudflare.com/#miscategorization-create-miscategorization
func (api *API) CreateMiscategorization(ctx context.Context, params MisCategorizationParameters) error {
	if params.AccountID == "" {
		return ErrMissingAccountID
	}
	if (params.IndicatorType == "ipv6" || params.IndicatorType == "ipv4") && params.IP == "" {
		return ErrMissingIP
	}
	if (params.IndicatorType == "domain" || params.IndicatorType == "url") && params.URL == "" {
		return ErrMissingURL
	}

	uri := fmt.Sprintf("/accounts/%s/intel/miscategorization", params.AccountID)
	_, err := api.makeRequestContext(ctx, http.MethodPost, uri, params)
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package validation

import (
	"DNA/core/ledger"
	tx "DNA/core/transaction"
	"errors"
	"math"
	"DNA/core/transaction/payload"
	"DNA/common"
)

//Verfiy the transcation for following points
//- Well format
//- No duplicated inputs
//- inputs/outputs balance
//- Transcation contracts pass
func VerifyTransaction(Tx *tx.Transaction, ledger *ledger.Ledger, TxPool []*tx.Transaction) error {

	err := CheckDuplicateInput(Tx)
	if(err != nil){return err}

	err = IsDoubleSpend(Tx,ledger)
	if(err != nil){return err}

	if TxPool != nil{
		err = CheckMemPool(Tx,TxPool)
		if(err != nil){return err}
	}

	err = CheckAssetPrecision(Tx)
	if(err != nil){return err}

	err = CheckTransactionBalance(Tx)
	if(err != nil){return err}

	err = CheckAttributeProgram(Tx)
	if(err != nil){return err}

	err = CheckTransactionContracts(Tx)
	if(err != nil){return err}

	if Tx.TxType == tx.IssueAsset{
		results, err := Tx.GetTransactionResults()
		if err != nil {
			return errors.New("[VerifyTransaction], GetTransactionResults failed.")
		}

		for _, v := range results {
			//Get the Asset amount when RegisterAsseted.
			trx,err := tx.TxStore.GetTransaction(v.AssetId)
			if err != nil {
				return errors.New("[VerifyTransaction], AssetId does exist.")
			}
			if trx.TxType != tx.RegisterAsset{
				return errors.New("[VerifyTransaction], TxType is illegal.")
			}
			AssetReg := trx.Payload.(*payload.RegisterAsset)

			//Get the amount has been issued of this assetID
			var quantity_issued *common.Fixed64
			if AssetReg.Amount < common.Fixed64(0){
				continue
			}else{
				quantity_issued,err = tx.TxStore.GetQuantityIssued(v.AssetId)
				if err != nil {
					return errors.New("[VerifyTransaction], GetQuantityIssued failed.")
				}
			}

			//calc the amounts in txPool
			var txPoolAmounts common.Fixed64
			if TxPool != nil{
				for _, t := range TxPool {
					for _, outputs := range t.Outputs {
						if outputs.AssetID == v.AssetId{
							txPoolAmounts = txPoolAmounts + v.Amount
						}
					}
				}
			}

			//calc weather out off the amount when Registed.
			//AssetReg.Amount : amount when RegisterAsset of this assedID
			//quantity_issued : amount has been issued of this assedID
			//txPoolAmounts   : amount in transactionPool of this assedID
			if AssetReg.Amount - *quantity_issued < - txPoolAmounts{
				return errors.New("[VerifyTransaction], Amount check error.")
			}

		}
	}

	return nil
}

func CheckMemPool(tx *tx.Transaction, TxPool []*tx.Transaction) error {

	for _, poolTx := range TxPool {
		for _, poolInput := range poolTx.UTXOInputs {
			for _, txInput := range tx.UTXOInputs {
				if poolInput.Equals(txInput) {
					return errors.New("There is duplicated Tx Input with Tx Pool.")
				}
			}
		}
	}
	return nil
}

func CheckDuplicateInput(tx *tx.Transaction) error {
	for i, utxoin := range tx.UTXOInputs {
		for j := 0; j < i; j++ {
			if utxoin.ReferTxID == tx.UTXOInputs[j].ReferTxID && utxoin.ReferTxOutputIndex == tx.UTXOInputs[j].ReferTxOutputIndex {
				return errors.New("invalid transaction")
			}
		}
	}
	return nil
}

func IsDoubleSpend(tx *tx.Transaction, ledger *ledger.Ledger) error {
	return ledger.IsDoubleSpend(tx)
}

func CheckAssetPrecision(Tx *tx.Transaction) error {
	for k, outputs := range Tx.AssetOutputs {
		asset,err:= ledger.DefaultLedger.GetAsset(k)
		if err!= nil{
			return errors.New("The asset not exist in local blockchain.")
		}
		precision := asset.Precision
		for _, output := range outputs {
			if output.Value.GetData()%int64(math.Pow(10, 8-float64(precision))) != 0 {
				return errors.New("The precision of asset is incorrect.")
			}
		}
	}
	return nil
}

func CheckTransactionBalance(Tx *tx.Transaction) error {
	if (len(Tx.AssetInputAmount) != len(Tx.AssetOutputAmount)){
		return  errors.New("The number of asset is not same between inputs and outputs.")
	}

	for k, v := range Tx.AssetInputAmount{
		if(v != Tx.AssetOutputAmount[k]){
			return  errors.New("The amount of asset is not same between inputs and outputs.")
		}
	}
	return nil
}

func CheckAttributeProgram(Tx *tx.Transaction) error {
	//TODO: implement CheckAttributeProgram
	return nil
}

func CheckTransactionContracts(Tx *tx.Transaction) error {
	flag,err := VerifySignableData(Tx)
	if ( flag && err == nil ) {
		return nil
	} else {
		return err
	}
}
<commit_msg>With no UTXOInputs could return it immediately. otherwise, it will run len([]*tx.Transaction) times.<commit_after>package validation

import (
	"DNA/common"
	"DNA/core/ledger"
	tx "DNA/core/transaction"
	"DNA/core/transaction/payload"
	"errors"
	"math"
)

//Verfiy the transcation for following points
//- Well format
//- No duplicated inputs
//- inputs/outputs balance
//- Transcation contracts pass
func VerifyTransaction(Tx *tx.Transaction, ledger *ledger.Ledger, TxPool []*tx.Transaction) error {

	err := CheckDuplicateInput(Tx)
	if err != nil {
		return err
	}

	err = IsDoubleSpend(Tx, ledger)
	if err != nil {
		return err
	}

	if TxPool != nil {
		err = CheckMemPool(Tx, TxPool)
		if err != nil {
			return err
		}
	}

	err = CheckAssetPrecision(Tx)
	if err != nil {
		return err
	}

	err = CheckTransactionBalance(Tx)
	if err != nil {
		return err
	}

	err = CheckAttributeProgram(Tx)
	if err != nil {
		return err
	}

	err = CheckTransactionContracts(Tx)
	if err != nil {
		return err
	}

	if Tx.TxType == tx.IssueAsset {
		results, err := Tx.GetTransactionResults()
		if err != nil {
			return errors.New("[VerifyTransaction], GetTransactionResults failed.")
		}

		for _, v := range results {
			//Get the Asset amount when RegisterAsseted.
			trx, err := tx.TxStore.GetTransaction(v.AssetId)
			if err != nil {
				return errors.New("[VerifyTransaction], AssetId does exist.")
			}
			if trx.TxType != tx.RegisterAsset {
				return errors.New("[VerifyTransaction], TxType is illegal.")
			}
			AssetReg := trx.Payload.(*payload.RegisterAsset)

			//Get the amount has been issued of this assetID
			var quantity_issued *common.Fixed64
			if AssetReg.Amount < common.Fixed64(0) {
				continue
			} else {
				quantity_issued, err = tx.TxStore.GetQuantityIssued(v.AssetId)
				if err != nil {
					return errors.New("[VerifyTransaction], GetQuantityIssued failed.")
				}
			}

			//calc the amounts in txPool
			var txPoolAmounts common.Fixed64
			if TxPool != nil {
				for _, t := range TxPool {
					for _, outputs := range t.Outputs {
						if outputs.AssetID == v.AssetId {
							txPoolAmounts = txPoolAmounts + v.Amount
						}
					}
				}
			}

			//calc weather out off the amount when Registed.
			//AssetReg.Amount : amount when RegisterAsset of this assedID
			//quantity_issued : amount has been issued of this assedID
			//txPoolAmounts   : amount in transactionPool of this assedID
			if AssetReg.Amount-*quantity_issued < -txPoolAmounts {
				return errors.New("[VerifyTransaction], Amount check error.")
			}

		}
	}

	return nil
}

func CheckMemPool(tx *tx.Transaction, TxPool []*tx.Transaction) error {
	if len(tx.UTXOInputs) == 0 {
		return nil
	}
	for _, poolTx := range TxPool {
		for _, poolInput := range poolTx.UTXOInputs {
			for _, txInput := range tx.UTXOInputs {
				if poolInput.Equals(txInput) {
					return errors.New("There is duplicated Tx Input with Tx Pool.")
				}
			}
		}
	}
	return nil
}

func CheckDuplicateInput(tx *tx.Transaction) error {
	if len(tx.UTXOInputs) == 0 {
		return nil
	}
	for i, utxoin := range tx.UTXOInputs {
		for j := 0; j < i; j++ {
			if utxoin.ReferTxID == tx.UTXOInputs[j].ReferTxID && utxoin.ReferTxOutputIndex == tx.UTXOInputs[j].ReferTxOutputIndex {
				return errors.New("invalid transaction")
			}
		}
	}
	return nil
}

func IsDoubleSpend(tx *tx.Transaction, ledger *ledger.Ledger) error {
	return ledger.IsDoubleSpend(tx)
}

func CheckAssetPrecision(Tx *tx.Transaction) error {
	for k, outputs := range Tx.AssetOutputs {
		asset, err := ledger.DefaultLedger.GetAsset(k)
		if err != nil {
			return errors.New("The asset not exist in local blockchain.")
		}
		precision := asset.Precision
		for _, output := range outputs {
			if output.Value.GetData()%int64(math.Pow(10, 8-float64(precision))) != 0 {
				return errors.New("The precision of asset is incorrect.")
			}
		}
	}
	return nil
}

func CheckTransactionBalance(Tx *tx.Transaction) error {
	if len(Tx.AssetInputAmount) != len(Tx.AssetOutputAmount) {
		return errors.New("The number of asset is not same between inputs and outputs.")
	}

	for k, v := range Tx.AssetInputAmount {
		if v != Tx.AssetOutputAmount[k] {
			return errors.New("The amount of asset is not same between inputs and outputs.")
		}
	}
	return nil
}

func CheckAttributeProgram(Tx *tx.Transaction) error {
	//TODO: implement CheckAttributeProgram
	return nil
}

func CheckTransactionContracts(Tx *tx.Transaction) error {
	flag, err := VerifySignableData(Tx)
	if flag && err == nil {
		return nil
	} else {
		return err
	}
}
<|endoftext|>


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

package web

import (
	"html/template"
	"log"
)

// Top provides the standard templates in parsed form
var Top = template.New("top").Funcs(Funcmap)

// TemplateText contains the text of the standard templates.
var TemplateText = map[string]string{

	"didyoumean": `

  <title>Error</title>

{{.Message}}. Did you mean {{.Suggestion}} ?

`,

	"head": `

<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

  `,

	"jsdep": `

`,

	// the template for the search box.
	"searchbox": `
<form action="search">

      <input class="form-control" placeholder="Search for some code..." autofocus
              {{if .Query}}
              value={{.Query}}
              {{end}}
              id="searchbox" type="text" name="q">

        <button class="btn btn-primary">Search</button>

</form>
`,

	"navbar": `

      Zoekt
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false">
        Toggle navigation

      </button>

      <form class="navbar-form navbar-left" action="search">

          <input class="form-control"
                placeholder="Search for some code..." role="search"
                id="navsearchbox" type="text" name="q" autofocus
                {{if .Query}}
                value={{.Query}}
                {{end}}>

Max Results

            <input class="form-control" type="number" id="maxhits" name="num" value="{{.Num}}">

          <button class="btn btn-primary">Search</button>

      </form>

`,
	// search box for the entry page.
	"search": `

{{template "head"}}
<title>Zoekt, en gij zult spinazie eten</title>

      {{template "searchbox" .Last}}

Search examples:

needle

search for "needle"

thread or needle

search for either "thread" or "needle"

class needle

search for files containing both "class" and "needle"

class Needle

search for files containing both "class" (case insensitive) and "Needle" (case sensitive)

class Needle case:yes

search for files containing "class" and "Needle", both case sensitively

"class Needle"

search for files with the phrase "class Needle"

needle -hay

search for files with the word "needle" but not the word "hay"

path file:java

search for the word "path" in files whose name contains "java"

needle lang:python

search for "needle" in Python source code

f:\.c$

search for files whose name ends with ".c"

path -file:java

search for the word "path" excluding files whose name contains "java"

foo.*bar

search for the regular expression "foo.*bar"

-(Path File) Stream

search "Stream", but exclude files containing both "Path" and "File"

-Path\ file Stream

search "Stream", but exclude files containing "Path File"

sym:data

search for symbol definitions containing "data"

phone r:droid

search for "phone" in repositories whose name contains "droid"

phone b:master

for Git repos, find "phone" in files in branches whose name contains "master".

phone b:HEAD

for Git repos, find "phone" in the default ('HEAD') branch.

To list repositories, try:

r:droid

list repositories whose name contains "droid".

r:go -r:google

list repositories whose name contains "go" but not "google".

      About

        Used {{HumanUnit .Stats.IndexBytes}} mem for
        {{.Stats.Documents}} documents ({{HumanUnit .Stats.ContentBytes}})
        from {{.Stats.Repos}} repositories.

`,

	"results": `

{{template "head"}}
<title>Results for {{.QueryStr}}</title>

  {{template "navbar" .Last}}

      {{if .Stats.Crashes}}
{{.Stats.Crashes}} shards crashed
{{end}}
      {{ $fileCount := len .FileMatches }}
      Found {{.Stats.MatchCount}} results in {{.Stats.FileCount}} files{{if or (lt $fileCount .Stats.FileCount) (or (gt .Stats.ShardsSkipped 0) (gt .Stats.FilesSkipped 0)) }},
        showing top {{ $fileCount }} files (show more).
      {{else}}.{{end}}

    {{range .FileMatches}}

            {{if .URL}}{{else}}{{end}}

              {{.Repo}}:{{.FileName}}:
              [ {{if .Branches}}{{range .Branches}}{{.}},{{end}}{{end}} ]
              {{if .Language}}{{.Language}}{{end}}
              {{if .DuplicateID}}Duplicate result{{end}}

      {{if not .DuplicateID}}

        {{range .Matches}}

{{if .URL}}{{end}}{{.LineNum}}{{if .URL}}{{end}}: {{range .Fragments}}{{.Pre}}{{.Match}}{{.Post}}{{end}}

        {{end}}

      {{end}}

    {{end}}

      Took {{.Stats.Duration}}{{if .Stats.Wait}}(queued: {{.Stats.Wait}}){{end}} for
      {{HumanUnit .Stats.IndexBytesLoaded}}B index data,
      {{.Stats.NgramMatches}} ngram matches,
      {{.Stats.FilesConsidered}} docs considered,
      {{.Stats.FilesLoaded}} docs ({{HumanUnit .Stats.ContentBytesLoaded}}B)
      loaded{{if or .Stats.FilesSkipped .Stats.ShardsSkipped}},
      {{.Stats.FilesSkipped}} docs and {{.Stats.ShardsSkipped}} shards skipped{{else}}.{{end}}

  {{ template "jsdep"}}

`,

	"repolist": `

{{template "head"}}

    {{template "navbar" .Last}}

        Found {{.Stats.Repos}} repositories ({{.Stats.Documents}} files, {{HumanUnit .Stats.ContentBytes}}b content)
        Last updated
        Branches
        Size

      {{range .Repos}}

        {{if .URL}}{{end}}{{.Name}}{{if .URL}}{{end}}
        {{.IndexTime.Format "Jan 02, 2006 15:04"}}

          {{range .Branches}}
          {{if .URL}}<tt>{{end}}{{.Name}}{{if .URL}} </tt>{{end}}
          {{end}}

        {{HumanUnit .Files}} files ({{HumanUnit .Size}})

      {{end}}

  {{ template "jsdep"}}

`,

	"print": `

    <title>{{.Repo}}:{{.Name}}</title>

{{template "searchbox" .Last}}

  <tt>{{.Repo}} : {{.Name}}</tt>

{{ range $index, $ln := .Lines}}

{{Inc $index}}: {{$ln}}

{{end}}

`,

	"about": `

  <title>About zoekt</title>

  This is zoekt (IPA: /zukt/),
  an open-source full text search engine. It's pronounced roughly as you would
  pronounce "zooked" in English.

Used {{HumanUnit .Stats.IndexBytes}} memory for
{{.Stats.Documents}} documents ({{HumanUnit .Stats.ContentBytes}})
from {{.Stats.Repos}} repositories.

{{if .Version}}Zoekt version {{.Version}}, uptime{{else}}Uptime{{end}} {{.Uptime}}

`,
}

func init() {
	for k, v := range TemplateText {
		_, err := Top.New(k).Parse(v)
		if err != nil {
			log.Panicf("parse(%s): %v:", k, err)
		}
	}
}
<commit_msg>web: make the "show more" link "nofollow"<commit_after>// Copyright 2016 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package web

import (
	"html/template"
	"log"
)

// Top provides the standard templates in parsed form
var Top = template.New("top").Funcs(Funcmap)

// TemplateText contains the text of the standard templates.
var TemplateText = map[string]string{

	"didyoumean": `

  <title>Error</title>

{{.Message}}. Did you mean {{.Suggestion}} ?

`,

	"head": `

<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

  `,

	"jsdep": `

`,

	// the template for the search box.
	"searchbox": `
<form action="search">

      <input class="form-control" placeholder="Search for some code..." autofocus
              {{if .Query}}
              value={{.Query}}
              {{end}}
              id="searchbox" type="text" name="q">

        <button class="btn btn-primary">Search</button>

</form>
`,

	"navbar": `

      Zoekt
      <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar-collapse" aria-expanded="false">
        Toggle navigation

      </button>

      <form class="navbar-form navbar-left" action="search">

          <input class="form-control"
                placeholder="Search for some code..." role="search"
                id="navsearchbox" type="text" name="q" autofocus
                {{if .Query}}
                value={{.Query}}
                {{end}}>

Max Results

            <input class="form-control" type="number" id="maxhits" name="num" value="{{.Num}}">

          <button class="btn btn-primary">Search</button>

      </form>

`,
	// search box for the entry page.
	"search": `

{{template "head"}}
<title>Zoekt, en gij zult spinazie eten</title>

      {{template "searchbox" .Last}}

Search examples:

needle

search for "needle"

thread or needle

search for either "thread" or "needle"

class needle

search for files containing both "class" and "needle"

class Needle

search for files containing both "class" (case insensitive) and "Needle" (case sensitive)

class Needle case:yes

search for files containing "class" and "Needle", both case sensitively

"class Needle"

search for files with the phrase "class Needle"

needle -hay

search for files with the word "needle" but not the word "hay"

path file:java

search for the word "path" in files whose name contains "java"

needle lang:python

search for "needle" in Python source code

f:\.c$

search for files whose name ends with ".c"

path -file:java

search for the word "path" excluding files whose name contains "java"

foo.*bar

search for the regular expression "foo.*bar"

-(Path File) Stream

search "Stream", but exclude files containing both "Path" and "File"

-Path\ file Stream

search "Stream", but exclude files containing "Path File"

sym:data

search for symbol definitions containing "data"

phone r:droid

search for "phone" in repositories whose name contains "droid"

phone b:master

for Git repos, find "phone" in files in branches whose name contains "master".

phone b:HEAD

for Git repos, find "phone" in the default ('HEAD') branch.

To list repositories, try:

r:droid

list repositories whose name contains "droid".

r:go -r:google

list repositories whose name contains "go" but not "google".

      About

        Used {{HumanUnit .Stats.IndexBytes}} mem for
        {{.Stats.Documents}} documents ({{HumanUnit .Stats.ContentBytes}})
        from {{.Stats.Repos}} repositories.

`,

	"results": `

{{template "head"}}
<title>Results for {{.QueryStr}}</title>

  {{template "navbar" .Last}}

      {{if .Stats.Crashes}}
{{.Stats.Crashes}} shards crashed
{{end}}
      {{ $fileCount := len .FileMatches }}
      Found {{.Stats.MatchCount}} results in {{.Stats.FileCount}} files{{if or (lt $fileCount .Stats.FileCount) (or (gt .Stats.ShardsSkipped 0) (gt .Stats.FilesSkipped 0)) }},
        showing top {{ $fileCount }} files (show more).
      {{else}}.{{end}}

    {{range .FileMatches}}

            {{if .URL}}{{else}}{{end}}

              {{.Repo}}:{{.FileName}}:
              [ {{if .Branches}}{{range .Branches}}{{.}},{{end}}{{end}} ]
              {{if .Language}}{{.Language}}{{end}}
              {{if .DuplicateID}}Duplicate result{{end}}

      {{if not .DuplicateID}}

        {{range .Matches}}

{{if .URL}}{{end}}{{.LineNum}}{{if .URL}}{{end}}: {{range .Fragments}}{{.Pre}}{{.Match}}{{.Post}}{{end}}

        {{end}}

      {{end}}

    {{end}}

      Took {{.Stats.Duration}}{{if .Stats.Wait}}(queued: {{.Stats.Wait}}){{end}} for
      {{HumanUnit .Stats.IndexBytesLoaded}}B index data,
      {{.Stats.NgramMatches}} ngram matches,
      {{.Stats.FilesConsidered}} docs considered,
      {{.Stats.FilesLoaded}} docs ({{HumanUnit .Stats.ContentBytesLoaded}}B)
      loaded{{if or .Stats.FilesSkipped .Stats.ShardsSkipped}},
      {{.Stats.FilesSkipped}} docs and {{.Stats.ShardsSkipped}} shards skipped{{else}}.{{end}}

  {{ template "jsdep"}}

`,

	"repolist": `

{{template "head"}}

    {{template "navbar" .Last}}

        Found {{.Stats.Repos}} repositories ({{.Stats.Documents}} files, {{HumanUnit .Stats.ContentBytes}}b content)
        Last updated
        Branches
        Size

      {{range .Repos}}

        {{if .URL}}{{end}}{{.Name}}{{if .URL}}{{end}}
        {{.IndexTime.Format "Jan 02, 2006 15:04"}}

          {{range .Branches}}
          {{if .URL}}<tt>{{end}}{{.Name}}{{if .URL}} </tt>{{end}}
          {{end}}

        {{HumanUnit .Files}} files ({{HumanUnit .Size}})

      {{end}}

  {{ template "jsdep"}}

`,

	"print": `

    <title>{{.Repo}}:{{.Name}}</title>

{{template "searchbox" .Last}}

  <tt>{{.Repo}} : {{.Name}}</tt>

{{ range $index, $ln := .Lines}}

{{Inc $index}}: {{$ln}}

{{end}}

`,

	"about": `

  <title>About zoekt</title>

  This is zoekt (IPA: /zukt/),
  an open-source full text search engine. It's pronounced roughly as you would
  pronounce "zooked" in English.

Used {{HumanUnit .Stats.IndexBytes}} memory for
{{.Stats.Documents}} documents ({{HumanUnit .Stats.ContentBytes}})
from {{.Stats.Repos}} repositories.

{{if .Version}}Zoekt version {{.Version}}, uptime{{else}}Uptime{{end}} {{.Uptime}}

`,
}

func init() {
	for k, v := range TemplateText {
		_, err := Top.New(k).Parse(v)
		if err != nil {
			log.Panicf("parse(%s): %v:", k, err)
		}
	}
}
<|endoftext|>


<commit_before>package nrsc

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"testing"
	"time"
)

const (
	root = "/tmp/nrsc-test"
	port = 9888
)

func TestMask(t *testing.T) {
	resp := getResp(t, "/static/i.gif")
	if resp.StatusCode != http.StatusUnauthorized {
		t.Fatalf("got masked resource - %d\n", resp.StatusCode)
	}
}

func TestText(t *testing.T) {
	expected := map[string]string{
		"Content-Size": "12",
		"Content-Type": "text/plain",
	}
	checkPath(t, "ht.txt", expected)
}

func TestSub(t *testing.T) {
	expected := map[string]string{
		"Content-Size": "1150",
		"Content-Type": "image/",
	}
	checkPath(t, "sub/favicon.ico", expected)
}

// / serves a template
func TestTempalte(t *testing.T) {
	server := startServer(t)
	if server == nil {
		t.Fatalf("can't start server")
	}
	defer server.Process.Kill()

	url := fmt.Sprintf("http://localhost:%d", port)
	resp, err := http.Get(url)
	if err != nil {
		t.Fatalf("can't GET / - %s", err)
	}

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatalf("can't read body - %s", err)
	}

	if string(data) != "The number is 7\n" {
		t.Fatalf("bad template reply - %s", string(data))
	}
}

func createMain() error {
	filename := fmt.Sprintf("%s/main.go", root)
	file, err := os.Create(filename)
	if err != nil {
		return err
	}
	defer file.Close()

	fmt.Fprintf(file, code, port)
	return nil
}

func initDir() error {
	// Ignore error value, since it might not be there
	os.RemoveAll(root)

	err := os.Mkdir(root, 0777)
	if err != nil {
		return err
	}

	return createMain()
}

func get(path string) (*http.Response, error) {
	url := fmt.Sprintf("http://localhost:%d/static/%s", port, path)
	return http.Get(url)
}

func startServer(t *testing.T) *exec.Cmd {
	cmd := exec.Command(fmt.Sprintf("%s/nrsc-test", root))
	// Ignore errors, test will fail anyway if server not running
	cmd.Start()

	// Wait for server
	url := fmt.Sprintf("http://localhost:%d", port)
	start := time.Now()
	for time.Since(start) < time.Duration(2*time.Second) {
		_, err := http.Get(url)
		if err == nil {
			return cmd
		}
		time.Sleep(time.Second / 10)
	}

	if cmd.Process != nil {
		cmd.Process.Kill()
	}
	t.Fatalf("can't connect to server")
	return nil
}

func fixGOPATH(cwd string) {
	os.Setenv("GOPATH", fmt.Sprintf("%s/../..", cwd))
}

func init() {
	if err := initDir(); err != nil {
		panic(err)
	}

	cwd, _ := os.Getwd()
	path := func(name string) string {
		return fmt.Sprintf("%s/%s", cwd, name)
	}
	fixGOPATH(cwd)

	os.Chdir(root)
	defer os.Chdir(cwd)

	cmd := exec.Command("go", "install", "nrsc")
	if err := cmd.Run(); err != nil {
		fmt.Printf("error installing: %s\n", err)
		panic(err)
	}

	cmd = exec.Command("go", "build")
	if err := cmd.Run(); err != nil {
		fmt.Printf("error building: %s\n", err)
		panic(err)
	}

	cmd = exec.Command(path("nrsc"), "nrsc-test", path("test-resources"))
	if err := cmd.Run(); err != nil {
		fmt.Printf("error packing: %s\n", err)
		panic(err)
	}
}

func checkHeaders(t *testing.T, expected map[string]string, headers http.Header) {
	for key := range expected {
		v1 := expected[key]
		v2 := headers.Get(key)
		if !strings.HasPrefix(v2, v1) {
			t.Fatalf("bad header %s: %s <-> %s", key, v1, v2)
		}
	}

	key := "Last-Modified"
	value := headers.Get(key)
	if value == "" {
		t.Fatalf("no %s header", key)
	}
}

func getResp(t *testing.T, path string) *http.Response {
	server := startServer(t)
	if server == nil {
		return nil
	}
	defer server.Process.Kill()

	resp, err := get(path)
	if err != nil {
		t.Fatalf("%s\n", err)
		return nil
	}

	return resp
}

func checkPath(t *testing.T, path string, expected map[string]string) {
	resp := getResp(t, path)
	if resp.StatusCode != http.StatusOK {
		t.Fatalf("bad reply - %s", resp.Status)
	}

	checkHeaders(t, expected, resp.Header)
}

const code = `
package main

import (
	"fmt"
	"net/http"
	"os"
	"regexp"

	"nrsc"
)

type params struct {
	Number  int
}

func indexHandler(w http.ResponseWriter, req *http.Request) {
	t, err := nrsc.LoadTemplates(nil, "t.html")
	if err != nil {
		http.NotFound(w, req)
	}
	if err = t.Execute(w, params{7}); err != nil {
		http.NotFound(w, req)
	}
}

func main() {
	nrsc.Handle("/static/")
	nrsc.Mask(regexp.MustCompile(".gif$"))
	http.HandleFunc("/", indexHandler)
	if err := http.ListenAndServe(":%d", nil); err != nil {
		fmt.Fprintf(os.Stderr, "error: %%s\n", err)
		os.Exit(1)
	}
}
`
<commit_msg>user & host in test dir<commit_after>package nrsc

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"strings"
	"testing"
	"time"
)

const (
	port = 9888
)

var root string

func init() {
	root = testDir()
}

func testDir() string {
	host, err := os.Hostname()
	if err != nil {
		host = "localhost"
	}
	return fmt.Sprintf("%s/nrsc-test-%s-%s", os.TempDir(), os.Getenv("USER"), host)
}

func TestMask(t *testing.T) {
	resp := getResp(t, "/static/i.gif")
	if resp.StatusCode != http.StatusUnauthorized {
		t.Fatalf("got masked resource - %d\n", resp.StatusCode)
	}
}

func TestText(t *testing.T) {
	expected := map[string]string{
		"Content-Size": "12",
		"Content-Type": "text/plain",
	}
	checkPath(t, "ht.txt", expected)
}

func TestSub(t *testing.T) {
	expected := map[string]string{
		"Content-Size": "1150",
		"Content-Type": "image/",
	}
	checkPath(t, "sub/favicon.ico", expected)
}

// / serves a template
func TestTempalte(t *testing.T) {
	server := startServer(t)
	if server == nil {
		t.Fatalf("can't start server")
	}
	defer server.Process.Kill()

	url := fmt.Sprintf("http://localhost:%d", port)
	resp, err := http.Get(url)
	if err != nil {
		t.Fatalf("can't GET / - %s", err)
	}

	data, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		t.Fatalf("can't read body - %s", err)
	}

	if string(data) != "The number is 7\n" {
		t.Fatalf("bad template reply - %s", string(data))
	}
}

func createMain() error {
	filename := fmt.Sprintf("%s/main.go", root)
	file, err := os.Create(filename)
	if err != nil {
		return err
	}
	defer file.Close()

	fmt.Fprintf(file, code, port)
	return nil
}

func initDir() error {
	// Ignore error value, since it might not be there
	os.RemoveAll(root)

	err := os.Mkdir(root, 0777)
	if err != nil {
		return err
	}

	return createMain()
}

func get(path string) (*http.Response, error) {
	url := fmt.Sprintf("http://localhost:%d/static/%s", port, path)
	return http.Get(url)
}

func startServer(t *testing.T) *exec.Cmd {
	cmd := exec.Command(fmt.Sprintf("%s/nrsc-test", root))
	// Ignore errors, test will fail anyway if server not running
	cmd.Start()

	// Wait for server
	url := fmt.Sprintf("http://localhost:%d", port)
	start := time.Now()
	for time.Since(start) < time.Duration(2*time.Second) {
		_, err := http.Get(url)
		if err == nil {
			return cmd
		}
		time.Sleep(time.Second / 10)
	}

	if cmd.Process != nil {
		cmd.Process.Kill()
	}
	t.Fatalf("can't connect to server")
	return nil
}

func fixGOPATH(cwd string) {
	os.Setenv("GOPATH", fmt.Sprintf("%s/../..", cwd))
}

func init() {
	if err := initDir(); err != nil {
		panic(err)
	}

	cwd, _ := os.Getwd()
	path := func(name string) string {
		return fmt.Sprintf("%s/%s", cwd, name)
	}
	fixGOPATH(cwd)

	os.Chdir(root)
	defer os.Chdir(cwd)

	cmd := exec.Command("go", "install", "nrsc")
	if err := cmd.Run(); err != nil {
		fmt.Printf("error installing: %s\n", err)
		panic(err)
	}

	cmd = exec.Command("go", "build")
	if err := cmd.Run(); err != nil {
		fmt.Printf("error building: %s\n", err)
		panic(err)
	}

	cmd = exec.Command(path("nrsc"), "nrsc-test", path("test-resources"))
	if err := cmd.Run(); err != nil {
		fmt.Printf("error packing: %s\n", err)
		panic(err)
	}
}

func checkHeaders(t *testing.T, expected map[string]string, headers http.Header) {
	for key := range expected {
		v1 := expected[key]
		v2 := headers.Get(key)
		if !strings.HasPrefix(v2, v1) {
			t.Fatalf("bad header %s: %s <-> %s", key, v1, v2)
		}
	}

	key := "Last-Modified"
	value := headers.Get(key)
	if value == "" {
		t.Fatalf("no %s header", key)
	}
}

func getResp(t *testing.T, path string) *http.Response {
	server := startServer(t)
	if server == nil {
		return nil
	}
	defer server.Process.Kill()

	resp, err := get(path)
	if err != nil {
		t.Fatalf("%s\n", err)
		return nil
	}

	return resp
}

func checkPath(t *testing.T, path string, expected map[string]string) {
	resp := getResp(t, path)
	if resp.StatusCode != http.StatusOK {
		t.Fatalf("bad reply - %s", resp.Status)
	}

	checkHeaders(t, expected, resp.Header)
}

const code = `
package main

import (
	"fmt"
	"net/http"
	"os"
	"regexp"

	"nrsc"
)

type params struct {
	Number  int
}

func indexHandler(w http.ResponseWriter, req *http.Request) {
	t, err := nrsc.LoadTemplates(nil, "t.html")
	if err != nil {
		http.NotFound(w, req)
	}
	if err = t.Execute(w, params{7}); err != nil {
		http.NotFound(w, req)
	}
}

func main() {
	nrsc.Handle("/static/")
	nrsc.Mask(regexp.MustCompile(".gif$"))
	http.HandleFunc("/", indexHandler)
	if err := http.ListenAndServe(":%d", nil); err != nil {
		fmt.Fprintf(os.Stderr, "error: %%s\n", err)
		os.Exit(1)
	}
}
`
<|endoftext|>


<commit_before>package nsqd

// the core algorithm here was borrowed from:
// Blake Mizerany's `noeqd` https://github.com/bmizerany/noeqd
// and indirectly:
// Twitter's `snowflake` https://github.com/twitter/snowflake

// only minor cleanup and changes to introduce a type, combine the concept
// of workerID + datacenterId into a single identifier, and modify the
// behavior when sequences rollover for our specific implementation needs

import (
	"encoding/hex"
	"errors"
	"time"
)

const (
	workerIDBits   = uint64(10)
	sequenceBits   = uint64(12)
	workerIDShift  = sequenceBits
	timestampShift = sequenceBits + workerIDBits
	sequenceMask   = int64(-1) ^ (int64(-1) << sequenceBits)

	// Tue, 21 Mar 2006 20:50:14.000 GMT
	twepoch = int64(1288834974657)
)

var ErrTimeBackwards = errors.New("time has gone backwards")
var ErrSequenceExpired = errors.New("sequence expired")
var ErrIDBackwards = errors.New("ID went backward")

type guid int64

type guidFactory struct {
	sequence      int64
	lastTimestamp int64
	lastID        guid
}

func (f *guidFactory) NewGUID(workerID int64) (guid, error) {
	ts := time.Now().UnixNano() / 1e6

	if ts < f.lastTimestamp {
		return 0, ErrTimeBackwards
	}

	if f.lastTimestamp == ts {
		f.sequence = (f.sequence + 1) & sequenceMask
		if f.sequence == 0 {
			return 0, ErrSequenceExpired
		}
	} else {
		f.sequence = 0
	}

	f.lastTimestamp = ts

	id := guid(((ts - twepoch) << timestampShift) |
		(workerID << workerIDShift) |
		f.sequence)

	if id <= f.lastID {
		return 0, ErrIDBackwards
	}

	f.lastID = id

	return id, nil
}

func (g guid) Hex() MessageID {
	var h MessageID
	var b [8]byte

	b[0] = byte(g >> 56)
	b[1] = byte(g >> 48)
	b[2] = byte(g >> 40)
	b[3] = byte(g >> 32)
	b[4] = byte(g >> 24)
	b[5] = byte(g >> 16)
	b[6] = byte(g >> 8)
	b[7] = byte(g)

	hex.Encode(h[:], b[:])
	return h
}
<commit_msg>fix twepoch comment. fix #635<commit_after>package nsqd

// the core algorithm here was borrowed from:
// Blake Mizerany's `noeqd` https://github.com/bmizerany/noeqd
// and indirectly:
// Twitter's `snowflake` https://github.com/twitter/snowflake

// only minor cleanup and changes to introduce a type, combine the concept
// of workerID + datacenterId into a single identifier, and modify the
// behavior when sequences rollover for our specific implementation needs

import (
	"encoding/hex"
	"errors"
	"time"
)

const (
	workerIDBits   = uint64(10)
	sequenceBits   = uint64(12)
	workerIDShift  = sequenceBits
	timestampShift = sequenceBits + workerIDBits
	sequenceMask   = int64(-1) ^ (int64(-1) << sequenceBits)

	// Thu Nov  4 01:42:54 UTC 2010
	twepoch = int64(1288834974657)
)

var ErrTimeBackwards = errors.New("time has gone backwards")
var ErrSequenceExpired = errors.New("sequence expired")
var ErrIDBackwards = errors.New("ID went backward")

type guid int64

type guidFactory struct {
	sequence      int64
	lastTimestamp int64
	lastID        guid
}

func (f *guidFactory) NewGUID(workerID int64) (guid, error) {
	ts := time.Now().UnixNano() / 1e6

	if ts < f.lastTimestamp {
		return 0, ErrTimeBackwards
	}

	if f.lastTimestamp == ts {
		f.sequence = (f.sequence + 1) & sequenceMask
		if f.sequence == 0 {
			return 0, ErrSequenceExpired
		}
	} else {
		f.sequence = 0
	}

	f.lastTimestamp = ts

	id := guid(((ts - twepoch) << timestampShift) |
		(workerID << workerIDShift) |
		f.sequence)

	if id <= f.lastID {
		return 0, ErrIDBackwards
	}

	f.lastID = id

	return id, nil
}

func (g guid) Hex() MessageID {
	var h MessageID
	var b [8]byte

	b[0] = byte(g >> 56)
	b[1] = byte(g >> 48)
	b[2] = byte(g >> 40)
	b[3] = byte(g >> 32)
	b[4] = byte(g >> 24)
	b[5] = byte(g >> 16)
	b[6] = byte(g >> 8)
	b[7] = byte(g)

	hex.Encode(h[:], b[:])
	return h
}
<|endoftext|>


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

package num

import "math"

type Cb_fx func(x float64) float64

// DerivCen5 approximates the derivative of f w.r.t x using central differences with 5 points.
func DerivCen5(f Cb_fx, x, h float64) (res, abserr float64) {

	res, round, trunc := centralDeriv5(f, x, h)
	err := round + trunc

	if round < trunc && (round > 0 && trunc > 0) {

		/* Compute an optimised stepsize to minimize the total error, using the scaling of the truncation
		   error (O(h^2)) and rounding error (O(1/h)). */

		h_opt := h * math.Pow(round/(2.0*trunc), 1.0/3.0)
		r_opt, round_opt, trunc_opt := centralDeriv5(f, x, h_opt)
		error_opt := round_opt + trunc_opt

		/* Check that the new error is smaller, and that the new derivative
		   is consistent with the error bounds of the original estimate. */

		if error_opt < err && math.Abs(r_opt-res) < 4.0*err {
			res = r_opt
			err = error_opt
		}
	}

	abserr = err
	return
}

// DerivFwd4 approximates the derivative of f w.r.t x using forward differences with 4 points.
func DerivFwd4(f Cb_fx, x, h float64) (res, abserr float64) {

	res, round, trunc := forwardDeriv4(f, x, h)
	err := round + trunc

	if round < trunc && (round > 0 && trunc > 0) {

		/* Compute an optimised stepsize to minimize the total error, using the scaling of the estimated
		   truncation error (O(h)) and rounding error (O(1/h)). */

		h_opt := h * math.Pow(round/(trunc), 1.0/2.0)
		r_opt, round_opt, trunc_opt := forwardDeriv4(f, x, h_opt)
		error_opt := round_opt + trunc_opt

		/* Check that the new error is smaller, and that the new derivative
		   is consistent with the error bounds of the original estimate. */

		if error_opt < err && math.Abs(r_opt-res) < 4.0*err {
			res = r_opt
			err = error_opt
		}
	}

	abserr = err
	return
}

func DerivBackward(f Cb_fx, x, h float64) (res, abserr float64) {
	return DerivFwd4(f, x, -h)
}

// lower level functions //////////////////////////////////////////////////////////////////////////

func centralDeriv5(f Cb_fx, x float64, h float64) (res, absErrRound, absErrTrunc float64) {

	/* Compute the derivative using the 5-point rule (x-h, x-h/2, x, x+h/2, x+h).
	   Note that the central point is not used.
	   Compute the error using the difference between the 5-point and the 3-point rule (x-h,x,x+h).
	   Again the central point is not used.
	*/

	fm1 := f(x - h)
	fp1 := f(x + h)
	fmh := f(x - h/2)
	fph := f(x + h/2)
	r3 := 0.5 * (fp1 - fm1)
	r5 := (4.0/3.0)*(fph-fmh) - (1.0/3.0)*r3
	e3 := (math.Abs(fp1) + math.Abs(fm1)) * DBL_EPSILON
	e5 := 2.0*(math.Abs(fph)+math.Abs(fmh))*DBL_EPSILON + e3

	/* The next term is due to finite precision in x+h = O (eps * x) */

	dy := max(math.Abs(r3/h), math.Abs(r5/h)) * (math.Abs(x) / h) * DBL_EPSILON

	/* The truncation error in the r5 approximation itself is O(h^4).
	   However, for safety, we estimate the error from r5-r3, which is O(h^2).
	   By scaling h we will minimise this estimated error, not the actual truncation error in r5. */

	res = r5 / h
	absErrTrunc = math.Abs((r5 - r3) / h) // Estimated truncation error O(h^2)
	absErrRound = math.Abs(e5/h) + dy     // Rounding error (cancellations)

	return
}

func forwardDeriv4(f Cb_fx, x, h float64) (res, absErrRound, absErrTrunc float64) {

	/* Compute the derivative using the 4-point rule (x+h/4, x+h/2, x+3h/4, x+h).
	   Compute the error using the difference between the 4-point and the 2-point rule (x+h/2,x+h). */

	f1 := f(x + h/4.0)
	f2 := f(x + h/2.0)
	f3 := f(x + (3.0/4.0)*h)
	f4 := f(x + h)
	r2 := 2.0 * (f4 - f2)
	r4 := (22.0/3.0)*(f4-f3) - (62.0/3.0)*(f3-f2) + (52.0/3.0)*(f2-f1)

	/* Estimate the rounding error for r4 */

	e4 := 2 * 20.67 * (math.Abs(f4) + math.Abs(f3) + math.Abs(f2) + math.Abs(f1)) * DBL_EPSILON

	/* The next term is due to finite precision in x+h = O (eps * x) */

	dy := max(math.Abs(r2/h), math.Abs(r4/h)) * math.Abs(x/h) * DBL_EPSILON

	/* The truncation error in the r4 approximation itself is O(h^3). However, for safety, we estimate the
	   error from r4-r2, which is O(h). By scaling h we will minimise this estimated error, not
	   the actual truncation error in r4. */

	res = r4 / h
	absErrTrunc = math.Abs((r4 - r2) / h) // Estimated truncation error O(h)
	absErrRound = math.Abs(e4/h) + dy
	return
}
<commit_msg>Organise comments in num.deriv<commit_after>// Copyright 2016 The Gosl Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package num

import "math"

type Cb_fx func(x float64) float64

// DerivCen5 approximates the derivative of f w.r.t x using central differences with 5 points.
func DerivCen5(f Cb_fx, x, h float64) (res, abserr float64) {

	// first estimate
	res, round, trunc := centralDeriv5(f, x, h)
	err := round + trunc

	// second estimate
	if round < trunc && (round > 0 && trunc > 0) {

		// Compute an optimised stepsize to minimize the total error,
		// using the scaling of the truncation error (O(h^2)) and rounding error (O(1/h)).
		h_opt := h * math.Pow(round/(2.0*trunc), 1.0/3.0)
		r_opt, round_opt, trunc_opt := centralDeriv5(f, x, h_opt)
		error_opt := round_opt + trunc_opt

		// Check that the new error is smaller, and that the new derivative
		// is consistent with the error bounds of the original estimate.
		if error_opt < err && math.Abs(r_opt-res) < 4.0*err {
			res = r_opt
			err = error_opt
		}
	}

	abserr = err
	return
}

// DerivFwd4 approximates the derivative of f w.r.t x using forward differences with 4 points.
func DerivFwd4(f Cb_fx, x, h float64) (res, abserr float64) {

	// first estimate
	res, round, trunc := forwardDeriv4(f, x, h)
	err := round + trunc

	// second estimate
	if round < trunc && (round > 0 && trunc > 0) {

		// Compute an optimised stepsize to minimize the total error,
		// using the scaling of the estimated truncation error (O(h)) and rounding error (O(1/h)).
		h_opt := h * math.Pow(round/(trunc), 1.0/2.0)
		r_opt, round_opt, trunc_opt := forwardDeriv4(f, x, h_opt)
		error_opt := round_opt + trunc_opt

		// Check that the new error is smaller, and that the new derivative
		// is consistent with the error bounds of the original estimate.
		if error_opt < err && math.Abs(r_opt-res) < 4.0*err {
			res = r_opt
			err = error_opt
		}
	}

	abserr = err
	return
}

// DerivBwd4 approximates the derivative of f w.r.t x using backward differences with 4 points.
func DerivBwd4(f Cb_fx, x, h float64) (res, abserr float64) {
	return DerivFwd4(f, x, -h)
}

// lower level functions //////////////////////////////////////////////////////////////////////////

// centralDeriv5 computes the derivative using the 5-point rule (x-h, x-h/2, x, x+h/2, x+h).
func centralDeriv5(f Cb_fx, x float64, h float64) (res, absErrRound, absErrTrunc float64) {

	// Compute the derivative using the 5-point rule (x-h, x-h/2, x, x+h/2, x+h).
	// Note that the central point is not used.
	// Compute the error using the difference between the 5-point and the 3-point rule (x-h,x,x+h).
	// Again the central point is not used.
	fm1 := f(x - h)
	fp1 := f(x + h)
	fmh := f(x - h/2)
	fph := f(x + h/2)
	r3 := 0.5 * (fp1 - fm1)
	r5 := (4.0/3.0)*(fph-fmh) - (1.0/3.0)*r3
	e3 := (math.Abs(fp1) + math.Abs(fm1)) * DBL_EPSILON
	e5 := 2.0*(math.Abs(fph)+math.Abs(fmh))*DBL_EPSILON + e3

	// The next term is due to finite precision in x+h = O (eps * x)
	dy := max(math.Abs(r3/h), math.Abs(r5/h)) * (math.Abs(x) / h) * DBL_EPSILON

	// The truncation error in the r5 approximation itself is O(h^4).
	// However, for safety, we estimate the error from r5-r3, which is O(h^2).
	// By scaling h we will minimise this estimated error, not the actual truncation error in r5.
	res = r5 / h
	absErrTrunc = math.Abs((r5 - r3) / h) // Estimated truncation error O(h^2)
	absErrRound = math.Abs(e5/h) + dy     // Rounding error (cancellations)
	return
}

// forwardDeriv4 compute the derivative using the 4-point rule (x+h/4, x+h/2, x+3h/4, x+h).
func forwardDeriv4(f Cb_fx, x, h float64) (res, absErrRound, absErrTrunc float64) {

	// Compute the derivative using the 4-point rule (x+h/4, x+h/2, x+3h/4, x+h).
	// Compute the error using the difference between the 4-point and the 2-point rule (x+h/2,x+h).
	f1 := f(x + h/4.0)
	f2 := f(x + h/2.0)
	f3 := f(x + (3.0/4.0)*h)
	f4 := f(x + h)
	r2 := 2.0 * (f4 - f2)
	r4 := (22.0/3.0)*(f4-f3) - (62.0/3.0)*(f3-f2) + (52.0/3.0)*(f2-f1)

	// Estimate the rounding error for r4
	e4 := 2 * 20.67 * (math.Abs(f4) + math.Abs(f3) + math.Abs(f2) + math.Abs(f1)) * DBL_EPSILON

	// The next term is due to finite precision in x+h = O (eps * x)
	dy := max(math.Abs(r2/h), math.Abs(r4/h)) * math.Abs(x/h) * DBL_EPSILON

	// The truncation error in the r4 approximation itself is O(h^3).
	// However, for safety, we estimate the error from r4-r2, which is O(h).
	// By scaling h we will minimise this estimated error, not the actual truncation error in r4.
	res = r4 / h
	absErrTrunc = math.Abs((r4 - r2) / h) // Estimated truncation error O(h)
	absErrRound = math.Abs(e4/h) + dy
	return
}
<|endoftext|>


<commit_before>package nv

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"reflect"
	"sort"

	xdr "github.com/davecgh/go-xdr/xdr2"
)

var (
	types = map[reflect.Kind]dataType{
		reflect.Bool:    _BOOLEAN_VALUE,
		reflect.Float32: _DOUBLE,
		reflect.Float64: _DOUBLE,
		reflect.Int16:   _INT16,
		reflect.Int32:   _INT32,
		reflect.Int64:   _INT64,
		reflect.Int8:    _INT8,
		reflect.Int:     _INT32,
		reflect.Map:     _NVLIST,
		reflect.String:  _STRING,
		reflect.Struct:  _NVLIST,
		reflect.Uint16:  _UINT16,
		reflect.Uint32:  _UINT32,
		reflect.Uint64:  _UINT64,
		reflect.Uint8:   _UINT8,
		reflect.Uint:    _UINT32,
	}

	sliceTypes = map[reflect.Kind]dataType{
		reflect.Bool:   _BOOLEAN_ARRAY,
		reflect.Int16:  _INT16_ARRAY,
		reflect.Int32:  _INT32_ARRAY,
		reflect.Int64:  _INT64_ARRAY,
		reflect.Int8:   _INT8_ARRAY,
		reflect.Int:    _INT32_ARRAY,
		reflect.Map:    _NVLIST_ARRAY,
		reflect.String: _STRING_ARRAY,
		reflect.Struct: _NVLIST_ARRAY,
		reflect.Uint16: _UINT16_ARRAY,
		reflect.Uint32: _UINT32_ARRAY,
		reflect.Uint64: _UINT64_ARRAY,
		reflect.Uint8:  _UINT8_ARRAY,
		reflect.Uint:   _UINT32_ARRAY,
	}
)

func Encode(i interface{}) ([]byte, error) {
	if i == nil {
		return nil, errors.New("can not encode a nil pointer")
	}

	v := reflect.ValueOf(i)
	if !v.IsValid() {
		return nil, fmt.Errorf("type '%s' is invalid", v.Kind().String())
	}

	var err error
	buff := bytes.NewBuffer(nil)
	if err = binary.Write(buff, binary.BigEndian, encoding{Encoding: 1, Endianess: 1}); err != nil {
		return nil, err
	}

	if err = encodeList(buff, v); err != nil {
		return nil, err
	}

	return buff.Bytes(), nil
}

func encodeList(w io.Writer, v reflect.Value) error {
	if err := binary.Write(w, binary.BigEndian, header{Flag: _UNIQUE_NAME}); err != nil {
		return err
	}

	v = deref(v)
	switch v.Kind() {
	case reflect.Struct:
		if err := encodeStruct(v, w); err != nil {
			return err
		}
	case reflect.Map:
		keys := make([]string, len(v.MapKeys()))
		for i, k := range v.MapKeys() {
			keys[i] = k.Interface().(string)
		}
		sort.Strings(keys)

		for _, name := range keys {
			v := v.MapIndex(reflect.ValueOf(name))
			if err := encodeItem(w, name, nil, v); err != nil {
				return err
			}
		}
	default:
		return fmt.Errorf("invalid type '%s', must be a struct", v.Kind().String())
	}

	return binary.Write(w, binary.BigEndian, uint64(0))
}

func encodeStruct(v reflect.Value, w io.Writer) error {
	var err error

	forEachField(v, func(i int, field reflect.Value) bool {
		// Skip fields that can't be set (e.g. unexported)
		if !field.CanSet() {
			return true
		}
		name := v.Type().Field(i).Name
		tags := getTags(i, v)
		if len(tags) > 0 && tags[0] != "" {
			name = tags[0]
		}

		if err = encodeItem(w, name, tags, field); err != nil {
			return false
		}
		return true
	})

	return err
}

func encodeItem(w io.Writer, name string, tags []string, field reflect.Value) error {
	var tagType dataType
	if len(tags) > 1 {
		if tags[1] == "byte" {
			tagType = _BYTE
		} else if tags[1] == "uint8" {
			tagType = _UINT8
		}
	}

	field = deref(field)

	p := pair{
		Name:      name,
		NElements: 1,
	}
	var ok bool
	p.Type, ok = types[field.Kind()]

	switch field.Kind() {
	case reflect.Bool:
		if field.Type().Name() == "Boolean" {
			p.Type = _BOOLEAN
		}
	case reflect.Interface:
		return encodeItem(w, name, tags, reflect.ValueOf(field.Interface()))
	case reflect.Slice, reflect.Array:
		p.Type, ok = sliceTypes[field.Type().Elem().Kind()]
		switch tagType {
		case _BYTE:
			p.Type = _BYTE_ARRAY
		case _UINT8:
			p.Type = _UINT8_ARRAY
		}
	case reflect.Int64:
		if field.Type().String() == "time.Duration" {
			p.Type = _HRTIME
		}
	case reflect.Uint8:
		switch tagType {
		case _BYTE:
			p.Type = _BYTE
		case _UINT8:
			p.Type = _UINT8
		}
	}

	if !ok {
		return fmt.Errorf("unknown type: %v", field.Kind())
	}

	p.data = field.Interface()
	value := p.data
	vbuf := &bytes.Buffer{}
	switch p.Type {
	case _BOOLEAN:
		p.NElements = 0
	case _BYTE:
		value = int8(value.(uint8))
	case _UINT8:
		value = int(int8(value.(uint8)))
	case _BYTE_ARRAY:
		p.NElements = uint32(len(value.([]byte)))
		n := int(p.NElements)
		arrType := reflect.ArrayOf(n, reflect.TypeOf(byte(0)))
		arr := reflect.New(arrType).Elem()
		for i, b := range value.([]byte) {
			arr.Index(i).SetUint(uint64(b))
		}
		value = arr.Interface()
	case _BOOLEAN_ARRAY:
		p.NElements = uint32(len(value.([]bool)))
	case _INT8_ARRAY:
		p.NElements = uint32(len(value.([]int8)))
	case _INT16_ARRAY:
		p.NElements = uint32(len(value.([]int16)))
	case _INT32_ARRAY:
		p.NElements = uint32(len(value.([]int32)))
	case _INT64_ARRAY:
		p.NElements = uint32(len(value.([]int64)))
	case _UINT8_ARRAY:
		// this one is weird since UINT8s are encoded as char
		// aka int32s... :(
		p.NElements = uint32(len(value.([]uint8)))
		n := int(p.NElements)
		sliceType := reflect.SliceOf(reflect.TypeOf(int32(0)))
		slice := reflect.MakeSlice(sliceType, n, n)
		for i, b := range value.([]uint8) {
			slice.Index(i).SetInt(int64(int8(b)))
		}
		value = slice.Interface()
	case _UINT16_ARRAY:
		p.NElements = uint32(len(value.([]uint16)))
	case _UINT32_ARRAY:
		p.NElements = uint32(len(value.([]uint32)))
	case _UINT64_ARRAY:
		p.NElements = uint32(len(value.([]uint64)))
	case _STRING_ARRAY:
		p.NElements = uint32(len(value.([]string)))
		arrType := reflect.ArrayOf(int(p.NElements), reflect.TypeOf(""))
		arr := reflect.New(arrType).Elem()
		for i, b := range value.([]string) {
			arr.Index(i).SetString(b)
		}
		value = arr.Interface()
	case _NVLIST:
		if err := encodeList(vbuf, reflect.ValueOf(value)); err != nil {
			return err
		}
		p.data = vbuf.Bytes()
	case _NVLIST_ARRAY:
		p.NElements = uint32(len(value.([]map[string]interface{})))
		for _, l := range value.([]map[string]interface{}) {
			if err := encodeList(vbuf, reflect.ValueOf(l)); err != nil {
				return err
			}
		}
		p.data = vbuf.Bytes()
	}

	if vbuf.Len() == 0 && p.Type != _BOOLEAN {
		_, err := xdr.NewEncoder(vbuf).Encode(value)
		if err != nil {
			return err
		}
	}

	p.EncodedSize = uint32(p.encodedSize())
	p.DecodedSize = uint32(p.decodedSize())

	pbuf := &bytes.Buffer{}
	_, err := xdr.NewEncoder(pbuf).Encode(p)
	if err != nil {
		return err
	}

	_, err = pbuf.WriteTo(w)
	if err != nil {
		return err
	}
	_, err = vbuf.WriteTo(w)
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>move pair instantiation closer to actual use<commit_after>package nv

import (
	"bytes"
	"encoding/binary"
	"errors"
	"fmt"
	"io"
	"reflect"
	"sort"

	xdr "github.com/davecgh/go-xdr/xdr2"
)

var (
	types = map[reflect.Kind]dataType{
		reflect.Bool:    _BOOLEAN_VALUE,
		reflect.Float32: _DOUBLE,
		reflect.Float64: _DOUBLE,
		reflect.Int16:   _INT16,
		reflect.Int32:   _INT32,
		reflect.Int64:   _INT64,
		reflect.Int8:    _INT8,
		reflect.Int:     _INT32,
		reflect.Map:     _NVLIST,
		reflect.String:  _STRING,
		reflect.Struct:  _NVLIST,
		reflect.Uint16:  _UINT16,
		reflect.Uint32:  _UINT32,
		reflect.Uint64:  _UINT64,
		reflect.Uint8:   _UINT8,
		reflect.Uint:    _UINT32,
	}

	sliceTypes = map[reflect.Kind]dataType{
		reflect.Bool:   _BOOLEAN_ARRAY,
		reflect.Int16:  _INT16_ARRAY,
		reflect.Int32:  _INT32_ARRAY,
		reflect.Int64:  _INT64_ARRAY,
		reflect.Int8:   _INT8_ARRAY,
		reflect.Int:    _INT32_ARRAY,
		reflect.Map:    _NVLIST_ARRAY,
		reflect.String: _STRING_ARRAY,
		reflect.Struct: _NVLIST_ARRAY,
		reflect.Uint16: _UINT16_ARRAY,
		reflect.Uint32: _UINT32_ARRAY,
		reflect.Uint64: _UINT64_ARRAY,
		reflect.Uint8:  _UINT8_ARRAY,
		reflect.Uint:   _UINT32_ARRAY,
	}
)

func Encode(i interface{}) ([]byte, error) {
	if i == nil {
		return nil, errors.New("can not encode a nil pointer")
	}

	v := reflect.ValueOf(i)
	if !v.IsValid() {
		return nil, fmt.Errorf("type '%s' is invalid", v.Kind().String())
	}

	var err error
	buff := bytes.NewBuffer(nil)
	if err = binary.Write(buff, binary.BigEndian, encoding{Encoding: 1, Endianess: 1}); err != nil {
		return nil, err
	}

	if err = encodeList(buff, v); err != nil {
		return nil, err
	}

	return buff.Bytes(), nil
}

func encodeList(w io.Writer, v reflect.Value) error {
	if err := binary.Write(w, binary.BigEndian, header{Flag: _UNIQUE_NAME}); err != nil {
		return err
	}

	v = deref(v)
	switch v.Kind() {
	case reflect.Struct:
		if err := encodeStruct(v, w); err != nil {
			return err
		}
	case reflect.Map:
		keys := make([]string, len(v.MapKeys()))
		for i, k := range v.MapKeys() {
			keys[i] = k.Interface().(string)
		}
		sort.Strings(keys)

		for _, name := range keys {
			v := v.MapIndex(reflect.ValueOf(name))
			if err := encodeItem(w, name, nil, v); err != nil {
				return err
			}
		}
	default:
		return fmt.Errorf("invalid type '%s', must be a struct", v.Kind().String())
	}

	return binary.Write(w, binary.BigEndian, uint64(0))
}

func encodeStruct(v reflect.Value, w io.Writer) error {
	var err error

	forEachField(v, func(i int, field reflect.Value) bool {
		// Skip fields that can't be set (e.g. unexported)
		if !field.CanSet() {
			return true
		}
		name := v.Type().Field(i).Name
		tags := getTags(i, v)
		if len(tags) > 0 && tags[0] != "" {
			name = tags[0]
		}

		if err = encodeItem(w, name, tags, field); err != nil {
			return false
		}
		return true
	})

	return err
}

func encodeItem(w io.Writer, name string, tags []string, field reflect.Value) error {
	var tagType dataType
	if len(tags) > 1 {
		if tags[1] == "byte" {
			tagType = _BYTE
		} else if tags[1] == "uint8" {
			tagType = _UINT8
		}
	}

	field = deref(field)
	dtype, ok := types[field.Kind()]

	switch field.Kind() {
	case reflect.Bool:
		if field.Type().Name() == "Boolean" {
			dtype = _BOOLEAN
		}
	case reflect.Interface:
		return encodeItem(w, name, tags, reflect.ValueOf(field.Interface()))
	case reflect.Slice, reflect.Array:
		dtype, ok = sliceTypes[field.Type().Elem().Kind()]
		switch tagType {
		case _BYTE:
			dtype = _BYTE_ARRAY
		case _UINT8:
			dtype = _UINT8_ARRAY
		}
	case reflect.Int64:
		if field.Type().String() == "time.Duration" {
			dtype = _HRTIME
		}
	case reflect.Uint8:
		switch tagType {
		case _BYTE:
			dtype = _BYTE
		case _UINT8:
			dtype = _UINT8
		}
	}

	if !ok {
		return fmt.Errorf("unknown type: %v", field.Kind())
	}

	p := pair{
		Name:      name,
		NElements: 1,
		Type:      dtype,
		data:      field.Interface(),
	}

	value := p.data
	vbuf := &bytes.Buffer{}
	switch p.Type {
	case _BOOLEAN:
		p.NElements = 0
	case _BYTE:
		value = int8(value.(uint8))
	case _UINT8:
		value = int(int8(value.(uint8)))
	case _BYTE_ARRAY:
		p.NElements = uint32(len(value.([]byte)))
		n := int(p.NElements)
		arrType := reflect.ArrayOf(n, reflect.TypeOf(byte(0)))
		arr := reflect.New(arrType).Elem()
		for i, b := range value.([]byte) {
			arr.Index(i).SetUint(uint64(b))
		}
		value = arr.Interface()
	case _BOOLEAN_ARRAY:
		p.NElements = uint32(len(value.([]bool)))
	case _INT8_ARRAY:
		p.NElements = uint32(len(value.([]int8)))
	case _INT16_ARRAY:
		p.NElements = uint32(len(value.([]int16)))
	case _INT32_ARRAY:
		p.NElements = uint32(len(value.([]int32)))
	case _INT64_ARRAY:
		p.NElements = uint32(len(value.([]int64)))
	case _UINT8_ARRAY:
		// this one is weird since UINT8s are encoded as char
		// aka int32s... :(
		p.NElements = uint32(len(value.([]uint8)))
		n := int(p.NElements)
		sliceType := reflect.SliceOf(reflect.TypeOf(int32(0)))
		slice := reflect.MakeSlice(sliceType, n, n)
		for i, b := range value.([]uint8) {
			slice.Index(i).SetInt(int64(int8(b)))
		}
		value = slice.Interface()
	case _UINT16_ARRAY:
		p.NElements = uint32(len(value.([]uint16)))
	case _UINT32_ARRAY:
		p.NElements = uint32(len(value.([]uint32)))
	case _UINT64_ARRAY:
		p.NElements = uint32(len(value.([]uint64)))
	case _STRING_ARRAY:
		p.NElements = uint32(len(value.([]string)))
		arrType := reflect.ArrayOf(int(p.NElements), reflect.TypeOf(""))
		arr := reflect.New(arrType).Elem()
		for i, b := range value.([]string) {
			arr.Index(i).SetString(b)
		}
		value = arr.Interface()
	case _NVLIST:
		if err := encodeList(vbuf, reflect.ValueOf(value)); err != nil {
			return err
		}
		p.data = vbuf.Bytes()
	case _NVLIST_ARRAY:
		p.NElements = uint32(len(value.([]map[string]interface{})))
		for _, l := range value.([]map[string]interface{}) {
			if err := encodeList(vbuf, reflect.ValueOf(l)); err != nil {
				return err
			}
		}
		p.data = vbuf.Bytes()
	}

	if vbuf.Len() == 0 && p.Type != _BOOLEAN {
		_, err := xdr.NewEncoder(vbuf).Encode(value)
		if err != nil {
			return err
		}
	}

	p.EncodedSize = uint32(p.encodedSize())
	p.DecodedSize = uint32(p.decodedSize())

	pbuf := &bytes.Buffer{}
	_, err := xdr.NewEncoder(pbuf).Encode(p)
	if err != nil {
		return err
	}

	_, err = pbuf.WriteTo(w)
	if err != nil {
		return err
	}
	_, err = vbuf.WriteTo(w)
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>// Code generated by go-bindata.
// sources:
// dist/index.html
// DO NOT EDIT!

package webui

import (
	"bytes"
	"compress/gzip"
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"
)

func bindataRead(data []byte, name string) ([]byte, error) {
	gz, err := gzip.NewReader(bytes.NewBuffer(data))
	if err != nil {
		return nil, fmt.Errorf("Read %q: %v", name, err)
	}

	var buf bytes.Buffer
	_, err = io.Copy(&buf, gz)
	clErr := gz.Close()

	if err != nil {
		return nil, fmt.Errorf("Read %q: %v", name, err)
	}
	if clErr != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

type asset struct {
	bytes []byte
	info  os.FileInfo
}

type bindataFileInfo struct {
	name    string
	size    int64
	mode    os.FileMode
	modTime time.Time
}

func (fi bindataFileInfo) Name() string {
	return fi.name
}
func (fi bindataFileInfo) Size() int64 {
	return fi.size
}
func (fi bindataFileInfo) Mode() os.FileMode {
	return fi.mode
}
func (fi bindataFileInfo) ModTime() time.Time {
	return fi.modTime
}
func (fi bindataFileInfo) IsDir() bool {
	return false
}
func (fi bindataFileInfo) Sys() interface{} {
	return nil
}

var _distIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xf2\x2f\x49\x2c\x2a\x55\x28\x4f\x2c\x56\x48\x2a\xcd\xcc\x49\x51\x28\xcf\x2c\xc9\xc8\x2f\x2d\x51\x08\x4f\x4d\x0a\xf5\xd4\xe3\x02\x04\x00\x00\xff\xff\xac\x6d\xee\x5e\x1f\x00\x00\x00")

func distIndexHtmlBytes() ([]byte, error) {
	return bindataRead(
		_distIndexHtml,
		"dist/index.html",
	)
}

func distIndexHtml() (*asset, error) {
	bytes, err := distIndexHtmlBytes()
	if err != nil {
		return nil, err
	}

	info := bindataFileInfo{name: "dist/index.html", size: 31, mode: os.FileMode(420), modTime: time.Unix(1451264166, 0)}
	a := &asset{bytes: bytes, info: info}
	return a, nil
}

// Asset loads and returns the asset for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
	cannonicalName := strings.Replace(name, "\\", "/", -1)
	if f, ok := _bindata[cannonicalName]; ok {
		a, err := f()
		if err != nil {
			return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
		}
		return a.bytes, nil
	}
	return nil, fmt.Errorf("Asset %s not found", name)
}

// MustAsset is like Asset but panics when Asset would return an error.
// It simplifies safe initialization of global variables.
func MustAsset(name string) []byte {
	a, err := Asset(name)
	if err != nil {
		panic("asset: Asset(" + name + "): " + err.Error())
	}

	return a
}

// AssetInfo loads and returns the asset info for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func AssetInfo(name string) (os.FileInfo, error) {
	cannonicalName := strings.Replace(name, "\\", "/", -1)
	if f, ok := _bindata[cannonicalName]; ok {
		a, err := f()
		if err != nil {
			return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
		}
		return a.info, nil
	}
	return nil, fmt.Errorf("AssetInfo %s not found", name)
}

// AssetNames returns the names of the assets.
func AssetNames() []string {
	names := make([]string, 0, len(_bindata))
	for name := range _bindata {
		names = append(names, name)
	}
	return names
}

// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
	"dist/index.html": distIndexHtml,
}

// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
//     data/
//       foo.txt
//       img/
//         a.png
//         b.png
// then AssetDir("data") would return []string{"foo.txt", "img"}
// AssetDir("data/img") would return []string{"a.png", "b.png"}
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
// AssetDir("") will return []string{"data"}.
func AssetDir(name string) ([]string, error) {
	node := _bintree
	if len(name) != 0 {
		cannonicalName := strings.Replace(name, "\\", "/", -1)
		pathList := strings.Split(cannonicalName, "/")
		for _, p := range pathList {
			node = node.Children[p]
			if node == nil {
				return nil, fmt.Errorf("Asset %s not found", name)
			}
		}
	}
	if node.Func != nil {
		return nil, fmt.Errorf("Asset %s not found", name)
	}
	rv := make([]string, 0, len(node.Children))
	for childName := range node.Children {
		rv = append(rv, childName)
	}
	return rv, nil
}

type bintree struct {
	Func     func() (*asset, error)
	Children map[string]*bintree
}

var _bintree = &bintree{nil, map[string]*bintree{
	"dist": &bintree{nil, map[string]*bintree{
		"index.html": &bintree{distIndexHtml, map[string]*bintree{}},
	}},
}}

// RestoreAsset restores an asset under the given directory
func RestoreAsset(dir, name string) error {
	data, err := Asset(name)
	if err != nil {
		return err
	}
	info, err := AssetInfo(name)
	if err != nil {
		return err
	}
	err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
	if err != nil {
		return err
	}
	err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
	if err != nil {
		return err
	}
	return nil
}

// RestoreAssets restores an asset under the given directory recursively
func RestoreAssets(dir, name string) error {
	children, err := AssetDir(name)
	// File
	if err != nil {
		return RestoreAsset(dir, name)
	}
	// Dir
	for _, child := range children {
		err = RestoreAssets(dir, filepath.Join(name, child))
		if err != nil {
			return err
		}
	}
	return nil
}

func _filePath(dir, name string) string {
	cannonicalName := strings.Replace(name, "\\", "/", -1)
	return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}
<commit_msg>revert stub bindata.go<commit_after>// Code generated by go-bindata.
// sources:
// dist/index.html
// DO NOT EDIT!

package webui

import (
	"bytes"
	"compress/gzip"
	"fmt"
	"io"
	"strings"
	"os"
	"time"
	"io/ioutil"
	"path/filepath"
)

func bindataRead(data []byte, name string) ([]byte, error) {
	gz, err := gzip.NewReader(bytes.NewBuffer(data))
	if err != nil {
		return nil, fmt.Errorf("Read %q: %v", name, err)
	}

	var buf bytes.Buffer
	_, err = io.Copy(&buf, gz)
	clErr := gz.Close()

	if err != nil {
		return nil, fmt.Errorf("Read %q: %v", name, err)
	}
	if clErr != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

type asset struct {
	bytes []byte
	info  os.FileInfo
}

type bindataFileInfo struct {
	name string
	size int64
	mode os.FileMode
	modTime time.Time
}

func (fi bindataFileInfo) Name() string {
	return fi.name
}
func (fi bindataFileInfo) Size() int64 {
	return fi.size
}
func (fi bindataFileInfo) Mode() os.FileMode {
	return fi.mode
}
func (fi bindataFileInfo) ModTime() time.Time {
	return fi.modTime
}
func (fi bindataFileInfo) IsDir() bool {
	return false
}
func (fi bindataFileInfo) Sys() interface{} {
	return nil
}

var _distIndexHtml = []byte("\x1f\x8b\x08\x00\x00\x09\x6e\x88\x00\xff\xf2\x2f\x49\x2c\x2a\x55\x28\x4f\x2c\x56\x48\x2a\xcd\xcc\x49\x51\x28\xcf\x2c\xc9\xc8\x2f\x2d\x51\x08\x4f\x4d\x0a\xf5\xd4\xe3\x02\x04\x00\x00\xff\xff\xac\x6d\xee\x5e\x1f\x00\x00\x00")

func distIndexHtmlBytes() ([]byte, error) {
	return bindataRead(
		_distIndexHtml,
		"dist/index.html",
	)
}

func distIndexHtml() (*asset, error) {
	bytes, err := distIndexHtmlBytes()
	if err != nil {
		return nil, err
	}

	info := bindataFileInfo{name: "dist/index.html", size: 31, mode: os.FileMode(420), modTime: time.Unix(1451264166, 0)}
	a := &asset{bytes: bytes, info:  info}
	return a, nil
}

// Asset loads and returns the asset for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func Asset(name string) ([]byte, error) {
	cannonicalName := strings.Replace(name, "\\", "/", -1)
	if f, ok := _bindata[cannonicalName]; ok {
		a, err := f()
		if err != nil {
			return nil, fmt.Errorf("Asset %s can't read by error: %v", name, err)
		}
		return a.bytes, nil
	}
	return nil, fmt.Errorf("Asset %s not found", name)
}

// MustAsset is like Asset but panics when Asset would return an error.
// It simplifies safe initialization of global variables.
func MustAsset(name string) []byte {
	a, err := Asset(name)
	if (err != nil) {
		panic("asset: Asset(" + name + "): " + err.Error())
	}

	return a
}

// AssetInfo loads and returns the asset info for the given name.
// It returns an error if the asset could not be found or
// could not be loaded.
func AssetInfo(name string) (os.FileInfo, error) {
	cannonicalName := strings.Replace(name, "\\", "/", -1)
	if f, ok := _bindata[cannonicalName]; ok {
		a, err := f()
		if err != nil {
			return nil, fmt.Errorf("AssetInfo %s can't read by error: %v", name, err)
		}
		return a.info, nil
	}
	return nil, fmt.Errorf("AssetInfo %s not found", name)
}

// AssetNames returns the names of the assets.
func AssetNames() []string {
	names := make([]string, 0, len(_bindata))
	for name := range _bindata {
		names = append(names, name)
	}
	return names
}

// _bindata is a table, holding each asset generator, mapped to its name.
var _bindata = map[string]func() (*asset, error){
	"dist/index.html": distIndexHtml,
}

// AssetDir returns the file names below a certain
// directory embedded in the file by go-bindata.
// For example if you run go-bindata on data/... and data contains the
// following hierarchy:
//     data/
//       foo.txt
//       img/
//         a.png
//         b.png
// then AssetDir("data") would return []string{"foo.txt", "img"}
// AssetDir("data/img") would return []string{"a.png", "b.png"}
// AssetDir("foo.txt") and AssetDir("notexist") would return an error
// AssetDir("") will return []string{"data"}.
func AssetDir(name string) ([]string, error) {
	node := _bintree
	if len(name) != 0 {
		cannonicalName := strings.Replace(name, "\\", "/", -1)
		pathList := strings.Split(cannonicalName, "/")
		for _, p := range pathList {
			node = node.Children[p]
			if node == nil {
				return nil, fmt.Errorf("Asset %s not found", name)
			}
		}
	}
	if node.Func != nil {
		return nil, fmt.Errorf("Asset %s not found", name)
	}
	rv := make([]string, 0, len(node.Children))
	for childName := range node.Children {
		rv = append(rv, childName)
	}
	return rv, nil
}

type bintree struct {
	Func func() (*asset, error)
	Children map[string]*bintree
}
var _bintree = &bintree{nil, map[string]*bintree{
	"dist": &bintree{nil, map[string]*bintree{
		"index.html": &bintree{distIndexHtml, map[string]*bintree{
		}},
	}},
}}

// RestoreAsset restores an asset under the given directory
func RestoreAsset(dir, name string) error {
        data, err := Asset(name)
        if err != nil {
                return err
        }
        info, err := AssetInfo(name)
        if err != nil {
                return err
        }
        err = os.MkdirAll(_filePath(dir, filepath.Dir(name)), os.FileMode(0755))
        if err != nil {
                return err
        }
        err = ioutil.WriteFile(_filePath(dir, name), data, info.Mode())
        if err != nil {
                return err
        }
        err = os.Chtimes(_filePath(dir, name), info.ModTime(), info.ModTime())
        if err != nil {
                return err
        }
        return nil
}

// RestoreAssets restores an asset under the given directory recursively
func RestoreAssets(dir, name string) error {
        children, err := AssetDir(name)
        // File
        if err != nil {
                return RestoreAsset(dir, name)
        }
        // Dir
        for _, child := range children {
                err = RestoreAssets(dir, filepath.Join(name, child))
                if err != nil {
                        return err
                }
        }
        return nil
}

func _filePath(dir, name string) string {
        cannonicalName := strings.Replace(name, "\\", "/", -1)
        return filepath.Join(append([]string{dir}, strings.Split(cannonicalName, "/")...)...)
}

<|endoftext|>