<commit_before>// Copyright 2010 The Go 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 sqlite

import (
	"database/sql"
	"database/sql/driver"
	"errors"
	"io"
	"log"
	"os"
)

func init() {
	sql.Register("sqlite3", &Driver{})
	if os.Getenv("SQLITE_LOG") != "" {
		ConfigLog(func(d interface{}, err error, msg string) {
			log.Printf("%s: %s, %s\n", d, err, msg)
		}, "SQLITE")
	}
}

// Adapter to database/sql/driver
type Driver struct {
}
type connImpl struct {
	c *Conn
}
type stmtImpl struct {
	s            *Stmt
	rowsRef      bool // true if there is a rowsImpl associated to this statement that has not been closed.
	pendingClose bool
}
type rowsImpl struct {
	s           *stmtImpl
	columnNames []string // cache
}

// Open opens a new database connection.
// ":memory:" for memory db,
// "" for temp file db
// TODO How to specify open flags?
func (d *Driver) Open(name string) (driver.Conn, error) {
	c, err := Open(name)
	if err != nil {
		return nil, err
	}
	c.BusyTimeout(500)
	return &connImpl{c}, nil
}

// PRAGMA schema_version may be used to detect when the database schema is altered

func (c *connImpl) Exec(query string, args []driver.Value) (driver.Result, error) {
	// http://code.google.com/p/go-wiki/wiki/InterfaceSlice
	tmp := make([]interface{}, len(args))
	for i, arg := range args {
		tmp[i] = arg
	}
	if err := c.c.Exec(query, tmp...); err != nil {
		return nil, err
	}
	return c, nil // FIXME RowAffected/noRows
}

// TODO How to know that the last Stmt has done an INSERT? An authorizer?
func (c *connImpl) LastInsertId() (int64, error) {
	return c.c.LastInsertRowid(), nil
}

// TODO How to know that the last Stmt has done a DELETE/INSERT/UPDATE? An authorizer?
func (c *connImpl) RowsAffected() (int64, error) {
	return int64(c.c.Changes()), nil
}

func (c *connImpl) Prepare(query string) (driver.Stmt, error) {
	s, err := c.c.Prepare(query)
	if err != nil {
		return nil, err
	}
	return &stmtImpl{s: s}, nil
}

func (c *connImpl) Close() error {
	return c.c.Close()
}

func (c *connImpl) Begin() (driver.Tx, error) {
	if err := c.c.Begin(); err != nil {
		return nil, err
	}
	return c, nil
}

func (c *connImpl) Commit() error {
	return c.c.Commit()
}
func (c *connImpl) Rollback() error {
	return c.c.Rollback()
}

func (s *stmtImpl) Close() error {
	if s.rowsRef { // Currently, it never happens because the sql.Stmt doesn't call driver.Stmt in this case
		s.pendingClose = true
		return nil
	}
	return s.s.Finalize()
}

func (s *stmtImpl) NumInput() int {
	return s.s.BindParameterCount()
}

func (s *stmtImpl) Exec(args []driver.Value) (driver.Result, error) {
	if err := s.bind(args); err != nil {
		return nil, err
	}
	if err := s.s.exec(); err != nil {
		return nil, err
	}
	return s, nil // FIXME RowAffected/noRows
}

// TODO How to know that this Stmt has done an INSERT? An authorizer?
func (s *stmtImpl) LastInsertId() (int64, error) {
	return s.s.c.LastInsertRowid(), nil
}

// TODO How to know that this Stmt has done a DELETE/INSERT/UPDATE? An authorizer?
func (s *stmtImpl) RowsAffected() (int64, error) {
	return int64(s.s.c.Changes()), nil
}

func (s *stmtImpl) Query(args []driver.Value) (driver.Rows, error) {
	if s.rowsRef {
		return nil, errors.New("Previously returned Rows still not closed")
	}
	if err := s.bind(args); err != nil {
		return nil, err
	}
	s.rowsRef = true
	return &rowsImpl{s, nil}, nil
}

func (s *stmtImpl) bind(args []driver.Value) error {
	for i, v := range args {
		if err := s.s.BindByIndex(i+1, v); err != nil {
			return err
		}
	}
	return nil
}

func (r *rowsImpl) Columns() []string {
	if r.columnNames == nil {
		r.columnNames = r.s.s.ColumnNames()
	}
	return r.columnNames
}

func (r *rowsImpl) Next(dest []driver.Value) error {
	ok, err := r.s.s.Next()
	if err != nil {
		return err
	}
	if !ok {
		return io.EOF
	}
	for i := range dest {
		value := r.s.s.ScanValue(i)
		switch value := value.(type) {
		case string: // "All string values must be converted to []byte."
			dest[i] = []byte(value)
		default:
			dest[i] = value
		}
	}
	return nil
}

func (r *rowsImpl) Close() error {
	r.s.rowsRef = false
	if r.s.pendingClose {
		return r.s.Close()
	}
	return r.s.s.Reset()
}
<commit_msg>Sets multi-thread mode for driver by default.<commit_after>// Copyright 2010 The Go 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 sqlite

import (
	"database/sql"
	"database/sql/driver"
	"errors"
	"io"
	"log"
	"os"
)

func init() {
	sql.Register("sqlite3", &Driver{})
	if os.Getenv("SQLITE_LOG") != "" {
		ConfigLog(func(d interface{}, err error, msg string) {
			log.Printf("%s: %s, %s\n", d, err, msg)
		}, "SQLITE")
	}
	ConfigThreadingMode(MultiThread)
	ConfigMemStatus(false)
}

// Adapter to database/sql/driver
type Driver struct {
}
type connImpl struct {
	c *Conn
}
type stmtImpl struct {
	s            *Stmt
	rowsRef      bool // true if there is a rowsImpl associated to this statement that has not been closed.
	pendingClose bool
}
type rowsImpl struct {
	s           *stmtImpl
	columnNames []string // cache
}

// Open opens a new database connection.
// ":memory:" for memory db,
// "" for temp file db
// TODO How to specify open flags? SQLITE_OPEN_NOMUTEX
func (d *Driver) Open(name string) (driver.Conn, error) {
	c, err := Open(name)
	if err != nil {
		return nil, err
	}
	c.BusyTimeout(10000)
	return &connImpl{c}, nil
}

// PRAGMA schema_version may be used to detect when the database schema is altered

func (c *connImpl) Exec(query string, args []driver.Value) (driver.Result, error) {
	// http://code.google.com/p/go-wiki/wiki/InterfaceSlice
	tmp := make([]interface{}, len(args))
	for i, arg := range args {
		tmp[i] = arg
	}
	if err := c.c.Exec(query, tmp...); err != nil {
		return nil, err
	}
	return c, nil // FIXME RowAffected/noRows
}

// TODO How to know that the last Stmt has done an INSERT? An authorizer?
func (c *connImpl) LastInsertId() (int64, error) {
	return c.c.LastInsertRowid(), nil
}

// TODO How to know that the last Stmt has done a DELETE/INSERT/UPDATE? An authorizer?
func (c *connImpl) RowsAffected() (int64, error) {
	return int64(c.c.Changes()), nil
}

func (c *connImpl) Prepare(query string) (driver.Stmt, error) {
	s, err := c.c.Prepare(query)
	if err != nil {
		return nil, err
	}
	return &stmtImpl{s: s}, nil
}

func (c *connImpl) Close() error {
	return c.c.Close()
}

func (c *connImpl) Begin() (driver.Tx, error) {
	if err := c.c.Begin(); err != nil {
		return nil, err
	}
	return c, nil
}

func (c *connImpl) Commit() error {
	return c.c.Commit()
}
func (c *connImpl) Rollback() error {
	return c.c.Rollback()
}

func (s *stmtImpl) Close() error {
	if s.rowsRef { // Currently, it never happens because the sql.Stmt doesn't call driver.Stmt in this case
		s.pendingClose = true
		return nil
	}
	return s.s.Finalize()
}

func (s *stmtImpl) NumInput() int {
	return s.s.BindParameterCount()
}

func (s *stmtImpl) Exec(args []driver.Value) (driver.Result, error) {
	if err := s.bind(args); err != nil {
		return nil, err
	}
	if err := s.s.exec(); err != nil {
		return nil, err
	}
	return s, nil // FIXME RowAffected/noRows
}

// TODO How to know that this Stmt has done an INSERT? An authorizer?
func (s *stmtImpl) LastInsertId() (int64, error) {
	return s.s.c.LastInsertRowid(), nil
}

// TODO How to know that this Stmt has done a DELETE/INSERT/UPDATE? An authorizer?
func (s *stmtImpl) RowsAffected() (int64, error) {
	return int64(s.s.c.Changes()), nil
}

func (s *stmtImpl) Query(args []driver.Value) (driver.Rows, error) {
	if s.rowsRef {
		return nil, errors.New("Previously returned Rows still not closed")
	}
	if err := s.bind(args); err != nil {
		return nil, err
	}
	s.rowsRef = true
	return &rowsImpl{s, nil}, nil
}

func (s *stmtImpl) bind(args []driver.Value) error {
	for i, v := range args {
		if err := s.s.BindByIndex(i+1, v); err != nil {
			return err
		}
	}
	return nil
}

func (r *rowsImpl) Columns() []string {
	if r.columnNames == nil {
		r.columnNames = r.s.s.ColumnNames()
	}
	return r.columnNames
}

func (r *rowsImpl) Next(dest []driver.Value) error {
	ok, err := r.s.s.Next()
	if err != nil {
		return err
	}
	if !ok {
		return io.EOF
	}
	for i := range dest {
		value := r.s.s.ScanValue(i)
		switch value := value.(type) {
		case string: // "All string values must be converted to []byte."
			dest[i] = []byte(value)
		default:
			dest[i] = value
		}
	}
	return nil
}

func (r *rowsImpl) Close() error {
	r.s.rowsRef = false
	if r.s.pendingClose {
		return r.s.Close()
	}
	return r.s.s.Reset()
}
<|endoftext|>


<commit_before>package buf

import (
	"io"

	"v2ray.com/core/common"
	"v2ray.com/core/common/errors"
)

func readOneUDP(r io.Reader) (*Buffer, error) {
	b := New()
	for i := 0; i < 64; i++ {
		_, err := b.ReadFrom(r)
		if !b.IsEmpty() {
			return b, nil
		}
		if err != nil {
			b.Release()
			return nil, err
		}
	}

	b.Release()
	return nil, newError("Reader returns too many empty payloads.")
}

// ReadBuffer reads a Buffer from the given reader, without allocating large buffer in advance.
func ReadBuffer(r io.Reader) (*Buffer, error) {
	// Use an one-byte buffer to wait for incoming payload.
	var firstByte [1]byte
	nBytes, err := r.Read(firstByte[:])
	if err != nil {
		return nil, err
	}

	b := New()
	if nBytes > 0 {
		common.Must(b.WriteByte(firstByte[0]))
	}
	b.ReadFrom(r)
	return b, nil
}

// BufferedReader is a Reader that keeps its internal buffer.
type BufferedReader struct {
	// Reader is the underlying reader to be read from
	Reader Reader
	// Buffer is the internal buffer to be read from first
	Buffer MultiBuffer
	// Spliter is a function to read bytes from MultiBuffer
	Spliter func(MultiBuffer, []byte) (MultiBuffer, int)
}

// BufferedBytes returns the number of bytes that is cached in this reader.
func (r *BufferedReader) BufferedBytes() int32 {
	return r.Buffer.Len()
}

// ReadByte implements io.ByteReader.
func (r *BufferedReader) ReadByte() (byte, error) {
	var b [1]byte
	_, err := r.Read(b[:])
	return b[0], err
}

// Read implements io.Reader. It reads from internal buffer first (if available) and then reads from the underlying reader.
func (r *BufferedReader) Read(b []byte) (int, error) {
	spliter := r.Spliter
	if spliter == nil {
		spliter = SplitBytes
	}

	if !r.Buffer.IsEmpty() {
		buffer, nBytes := spliter(r.Buffer, b)
		r.Buffer = buffer
		if r.Buffer.IsEmpty() {
			r.Buffer = nil
		}
		return nBytes, nil
	}

	mb, err := r.Reader.ReadMultiBuffer()
	if err != nil {
		return 0, err
	}

	mb, nBytes := spliter(mb, b)
	if !mb.IsEmpty() {
		r.Buffer = mb
	}
	return nBytes, nil
}

// ReadMultiBuffer implements Reader.
func (r *BufferedReader) ReadMultiBuffer() (MultiBuffer, error) {
	if !r.Buffer.IsEmpty() {
		mb := r.Buffer
		r.Buffer = nil
		return mb, nil
	}

	return r.Reader.ReadMultiBuffer()
}

// ReadAtMost returns a MultiBuffer with at most size.
func (r *BufferedReader) ReadAtMost(size int32) (MultiBuffer, error) {
	if r.Buffer.IsEmpty() {
		mb, err := r.Reader.ReadMultiBuffer()
		if mb.IsEmpty() && err != nil {
			return nil, err
		}
		r.Buffer = mb
	}

	rb, mb := SplitSize(r.Buffer, size)
	r.Buffer = rb
	if r.Buffer.IsEmpty() {
		r.Buffer = nil
	}
	return mb, nil
}

func (r *BufferedReader) writeToInternal(writer io.Writer) (int64, error) {
	mbWriter := NewWriter(writer)
	var sc SizeCounter
	if r.Buffer != nil {
		sc.Size = int64(r.Buffer.Len())
		if err := mbWriter.WriteMultiBuffer(r.Buffer); err != nil {
			return 0, err
		}
		r.Buffer = nil
	}

	err := Copy(r.Reader, mbWriter, CountSize(&sc))
	return sc.Size, err
}

// WriteTo implements io.WriterTo.
func (r *BufferedReader) WriteTo(writer io.Writer) (int64, error) {
	nBytes, err := r.writeToInternal(writer)
	if errors.Cause(err) == io.EOF {
		return nBytes, nil
	}
	return nBytes, err
}

// Interrupt implements common.Interruptible.
func (r *BufferedReader) Interrupt() {
	common.Interrupt(r.Reader)
}

// Close implements io.Closer.
func (r *BufferedReader) Close() error {
	return common.Close(r.Reader)
}

// SingleReader is a Reader that read one Buffer every time.
type SingleReader struct {
	io.Reader
}

// ReadMultiBuffer implements Reader.
func (r *SingleReader) ReadMultiBuffer() (MultiBuffer, error) {
	b, err := ReadBuffer(r.Reader)
	if err != nil {
		return nil, err
	}
	return MultiBuffer{b}, nil
}

// PacketReader is a Reader that read one Buffer every time.
type PacketReader struct {
	io.Reader
}

// ReadMultiBuffer implements Reader.
func (r *PacketReader) ReadMultiBuffer() (MultiBuffer, error) {
	b, err := readOneUDP(r.Reader)
	if err != nil {
		return nil, err
	}
	return MultiBuffer{b}, nil
}
<commit_msg>fix ReadBuffer()<commit_after>package buf

import (
	"io"

	"v2ray.com/core/common"
	"v2ray.com/core/common/errors"
)

func readOneUDP(r io.Reader) (*Buffer, error) {
	b := New()
	for i := 0; i < 64; i++ {
		_, err := b.ReadFrom(r)
		if !b.IsEmpty() {
			return b, nil
		}
		if err != nil {
			b.Release()
			return nil, err
		}
	}

	b.Release()
	return nil, newError("Reader returns too many empty payloads.")
}

// ReadBuffer reads a Buffer from the given reader.
func ReadBuffer(r io.Reader) (*Buffer, error) {
	b := New()
	_, err := b.ReadFrom(r)
	if err != nil {
		b.Release()
		return nil, err
	}
	return b, nil
}

// BufferedReader is a Reader that keeps its internal buffer.
type BufferedReader struct {
	// Reader is the underlying reader to be read from
	Reader Reader
	// Buffer is the internal buffer to be read from first
	Buffer MultiBuffer
	// Spliter is a function to read bytes from MultiBuffer
	Spliter func(MultiBuffer, []byte) (MultiBuffer, int)
}

// BufferedBytes returns the number of bytes that is cached in this reader.
func (r *BufferedReader) BufferedBytes() int32 {
	return r.Buffer.Len()
}

// ReadByte implements io.ByteReader.
func (r *BufferedReader) ReadByte() (byte, error) {
	var b [1]byte
	_, err := r.Read(b[:])
	return b[0], err
}

// Read implements io.Reader. It reads from internal buffer first (if available) and then reads from the underlying reader.
func (r *BufferedReader) Read(b []byte) (int, error) {
	spliter := r.Spliter
	if spliter == nil {
		spliter = SplitBytes
	}

	if !r.Buffer.IsEmpty() {
		buffer, nBytes := spliter(r.Buffer, b)
		r.Buffer = buffer
		if r.Buffer.IsEmpty() {
			r.Buffer = nil
		}
		return nBytes, nil
	}

	mb, err := r.Reader.ReadMultiBuffer()
	if err != nil {
		return 0, err
	}

	mb, nBytes := spliter(mb, b)
	if !mb.IsEmpty() {
		r.Buffer = mb
	}
	return nBytes, nil
}

// ReadMultiBuffer implements Reader.
func (r *BufferedReader) ReadMultiBuffer() (MultiBuffer, error) {
	if !r.Buffer.IsEmpty() {
		mb := r.Buffer
		r.Buffer = nil
		return mb, nil
	}

	return r.Reader.ReadMultiBuffer()
}

// ReadAtMost returns a MultiBuffer with at most size.
func (r *BufferedReader) ReadAtMost(size int32) (MultiBuffer, error) {
	if r.Buffer.IsEmpty() {
		mb, err := r.Reader.ReadMultiBuffer()
		if mb.IsEmpty() && err != nil {
			return nil, err
		}
		r.Buffer = mb
	}

	rb, mb := SplitSize(r.Buffer, size)
	r.Buffer = rb
	if r.Buffer.IsEmpty() {
		r.Buffer = nil
	}
	return mb, nil
}

func (r *BufferedReader) writeToInternal(writer io.Writer) (int64, error) {
	mbWriter := NewWriter(writer)
	var sc SizeCounter
	if r.Buffer != nil {
		sc.Size = int64(r.Buffer.Len())
		if err := mbWriter.WriteMultiBuffer(r.Buffer); err != nil {
			return 0, err
		}
		r.Buffer = nil
	}

	err := Copy(r.Reader, mbWriter, CountSize(&sc))
	return sc.Size, err
}

// WriteTo implements io.WriterTo.
func (r *BufferedReader) WriteTo(writer io.Writer) (int64, error) {
	nBytes, err := r.writeToInternal(writer)
	if errors.Cause(err) == io.EOF {
		return nBytes, nil
	}
	return nBytes, err
}

// Interrupt implements common.Interruptible.
func (r *BufferedReader) Interrupt() {
	common.Interrupt(r.Reader)
}

// Close implements io.Closer.
func (r *BufferedReader) Close() error {
	return common.Close(r.Reader)
}

// SingleReader is a Reader that read one Buffer every time.
type SingleReader struct {
	io.Reader
}

// ReadMultiBuffer implements Reader.
func (r *SingleReader) ReadMultiBuffer() (MultiBuffer, error) {
	b, err := ReadBuffer(r.Reader)
	if err != nil {
		return nil, err
	}
	return MultiBuffer{b}, nil
}

// PacketReader is a Reader that read one Buffer every time.
type PacketReader struct {
	io.Reader
}

// ReadMultiBuffer implements Reader.
func (r *PacketReader) ReadMultiBuffer() (MultiBuffer, error) {
	b, err := readOneUDP(r.Reader)
	if err != nil {
		return nil, err
	}
	return MultiBuffer{b}, nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"log"
	"os"

	"github.com/haskelladdict/mbdr/libmbd"
	"github.com/haskelladdict/mbdr/parser"
)

const mbdrMajorVersion = 3
const mbdrMinorVersion = 0

// command line flags
var (
	infoFlag      bool
	listFlag      bool
	addTimesFlag  bool
	writeFileFlag bool
	extractFlag   bool
	extractID     uint64
	extractString string
	extractRegex  string
)

func init() {
	flag.BoolVar(&infoFlag, "i", false, "show general info")
	flag.BoolVar(&listFlag, "l", false, "list available data blocks")
	flag.BoolVar(&extractFlag, "e", false, "extract dataset")
	flag.BoolVar(&addTimesFlag, "t", false, "add output times column")
	flag.BoolVar(&writeFileFlag, "w", false, "write output to file")
	flag.Uint64Var(&extractID, "I", 0, "id of dataset to extract")
	flag.StringVar(&extractString, "N", "", "name of dataset to extract")
	flag.StringVar(&extractRegex, "R", "", "regular expression of dataset(s) to extract")
}

// main function entry point
func main() {
	flag.Parse()
	if len(flag.Args()) == 0 {
		usage()
		return
	}

	filename := flag.Args()[0]
	var data *libmbd.MCellData
	var err error
	if infoFlag || listFlag {
		if data, err = parser.ReadHeader(filename); err != nil {
			log.Fatal(err)
		}
	} else if extractFlag {
		if data, err = parser.Read(filename); err != nil {
			log.Fatal(err)
		}
	} else {
		fmt.Println("\nError: Please specify at least one of -i, -l, or -e!")
		usage()
		return
	}

	switch {
	case infoFlag:
		showInfo(data)

	case listFlag:
		showAvailableData(data)

	case extractFlag:
		if err := extractData(data); err != nil {
			log.Fatal(err)
		}
	}
}

// usage prints a brief usage information to stdout
func usage() {
	fmt.Println("usage: mbdr [options] <binary mcell filename>")
	fmt.Println("\noptions:")
	flag.PrintDefaults()
}

// showInfo provides general info regarding the nature and amount of data
// contained in the binary mcell file
func showInfo(d *libmbd.MCellData) {
	fmt.Printf("This is mbdr version %d.%d        (C) 2014 M. Dittrich\n",
		mbdrMajorVersion, mbdrMinorVersion)
	fmt.Println("------------------------------------------------------------------")
	fmt.Printf("mbdr> output was generated using %s\n", d.API)
	fmt.Printf("mbdr> found %d output data blocks with %d output iterations each\n",
		d.NumDataBlocks(), d.BlockLen())
	switch d.OutputType() {
	case libmbd.Step:
		fmt.Printf("mbdr> output generated via STEP size of %g s\n", d.OutputStepLen())

	case libmbd.TimeListType:
		fmt.Printf("mbdr> output generated via TIME_LIST\n")

	case libmbd.IterationListType:
		fmt.Printf("mbdr> output generated via ITERATION_LIST\n")

	default:
		fmt.Printf("mbdr> encountered UNKNOWN output type")
	}
}

// showAvailableData shows the available data sets contained in the
// binary output file
func showAvailableData(d *libmbd.MCellData) {
	for i, n := range d.DataNames() {
		fmt.Printf("[%d] %s\n", i, n)
	}
}

// extractData extracts the content of a data set or data sets either at the
// requested ID, the provided name, or the regular expression and writes it to
// stdout or files if requested.
// NOTE: This routine doesn't bother with converting to integer column data
// (as determined by DataTypes) and simply prints everything as double
func extractData(data *libmbd.MCellData) error {

	outputData := make(map[string]*libmbd.CountData)
	var countData *libmbd.CountData
	var err error

	if extractString != "" {
		// if match string was supplied we'll use it
		if countData, err = data.BlockDataByName(extractString); err != nil {
			return err
		}
		outputData[extractString] = countData
	} else if extractRegex != "" {
		if outputData, err = data.BlockDataByRegex(extractRegex); err != nil {
			return err
		}
	} else {
		// otherwise we pick the supplied data set ID to extract (0 by default)
		if countData, err = data.BlockDataByID(extractID); err != nil {
			return err
		}
		var name string
		if name, err = data.IDtoBlockName(extractID); err != nil {
			return err
		}
		outputData[name] = countData
	}

	for name, col := range outputData {
		if err = writeData(data, name, col); err != nil {
			return err
		}
	}

	return nil
}

// writeData writes the supplied count data corresponding to the named data set
// to stdout or a file
func writeData(d *libmbd.MCellData, name string, data *libmbd.CountData) error {

	var outputTimes []float64
	if addTimesFlag {
		outputTimes = d.OutputTimes()
	}

	output := os.Stdout
	var err error
	if writeFileFlag {
		if output, err = os.Create(name); err != nil {
			return err
		}
	}

	numCols := len(data.Col)
	numRows := len(data.Col[0])
	for r := 0; r < numRows; r++ {
		for c := 0; c < numCols; c++ {
			if addTimesFlag {
				fmt.Fprintf(output, "%8.5e %g", outputTimes[r], data.Col[c][r])
			} else {
				fmt.Fprintf(output, "%g", data.Col[c][r])
			}
		}
		fmt.Fprintf(output, "\n")
	}
	return nil
}
<commit_msg>Allow mbdr to act on all supplied files on commandline.<commit_after>package main

import (
	"flag"
	"fmt"
	"log"
	"os"

	"github.com/haskelladdict/mbdr/libmbd"
	"github.com/haskelladdict/mbdr/parser"
)

const mbdrMajorVersion = 3
const mbdrMinorVersion = 0

// command line flags
var (
	infoFlag      bool
	listFlag      bool
	addTimesFlag  bool
	writeFileFlag bool
	extractFlag   bool
	extractID     uint64
	extractString string
	extractRegex  string
)

func init() {
	flag.BoolVar(&infoFlag, "i", false, "show general info")
	flag.BoolVar(&listFlag, "l", false, "list available data blocks")
	flag.BoolVar(&extractFlag, "e", false, "extract dataset")
	flag.BoolVar(&addTimesFlag, "t", false, "add output times column")
	flag.BoolVar(&writeFileFlag, "w", false, "write output to file")
	flag.Uint64Var(&extractID, "I", 0, "id of dataset to extract")
	flag.StringVar(&extractString, "N", "", "name of dataset to extract")
	flag.StringVar(&extractRegex, "R", "", "regular expression of dataset(s) to extract")
}

// main function entry point
func main() {
	flag.Parse()
	if len(flag.Args()) == 0 {
		usage()
		return
	}

	for _, filename := range flag.Args() {
		var data *libmbd.MCellData
		var err error
		if infoFlag || listFlag {
			if data, err = parser.ReadHeader(filename); err != nil {
				log.Fatal(err)
			}
		} else if extractFlag {
			if data, err = parser.Read(filename); err != nil {
				log.Fatal(err)
			}
		} else {
			fmt.Println("\nError: Please specify at least one of -i, -l, or -e!")
			usage()
			return
		}

		switch {
		case infoFlag:
			showInfo(data)

		case listFlag:
			showAvailableData(data)

		case extractFlag:
			if err := extractData(data); err != nil {
				log.Fatal(err)
			}
		}
	}
}

// usage prints a brief usage information to stdout
func usage() {
	fmt.Println("usage: mbdr [options] <binary mcell filename>")
	fmt.Println("\noptions:")
	flag.PrintDefaults()
}

// showInfo provides general info regarding the nature and amount of data
// contained in the binary mcell file
func showInfo(d *libmbd.MCellData) {
	fmt.Printf("This is mbdr version %d.%d        (C) 2014 M. Dittrich\n",
		mbdrMajorVersion, mbdrMinorVersion)
	fmt.Println("------------------------------------------------------------------")
	fmt.Printf("mbdr> output was generated using %s\n", d.API)
	fmt.Printf("mbdr> found %d output data blocks with %d output iterations each\n",
		d.NumDataBlocks(), d.BlockLen())
	switch d.OutputType() {
	case libmbd.Step:
		fmt.Printf("mbdr> output generated via STEP size of %g s\n", d.OutputStepLen())

	case libmbd.TimeListType:
		fmt.Printf("mbdr> output generated via TIME_LIST\n")

	case libmbd.IterationListType:
		fmt.Printf("mbdr> output generated via ITERATION_LIST\n")

	default:
		fmt.Printf("mbdr> encountered UNKNOWN output type")
	}
}

// showAvailableData shows the available data sets contained in the
// binary output file
func showAvailableData(d *libmbd.MCellData) {
	for i, n := range d.DataNames() {
		fmt.Printf("[%d] %s\n", i, n)
	}
}

// extractData extracts the content of a data set or data sets either at the
// requested ID, the provided name, or the regular expression and writes it to
// stdout or files if requested.
// NOTE: This routine doesn't bother with converting to integer column data
// (as determined by DataTypes) and simply prints everything as double
func extractData(data *libmbd.MCellData) error {

	outputData := make(map[string]*libmbd.CountData)
	var countData *libmbd.CountData
	var err error

	if extractString != "" {
		// if match string was supplied we'll use it
		if countData, err = data.BlockDataByName(extractString); err != nil {
			return err
		}
		outputData[extractString] = countData
	} else if extractRegex != "" {
		if outputData, err = data.BlockDataByRegex(extractRegex); err != nil {
			return err
		}
	} else {
		// otherwise we pick the supplied data set ID to extract (0 by default)
		if countData, err = data.BlockDataByID(extractID); err != nil {
			return err
		}
		var name string
		if name, err = data.IDtoBlockName(extractID); err != nil {
			return err
		}
		outputData[name] = countData
	}

	for name, col := range outputData {
		if err = writeData(data, name, col); err != nil {
			return err
		}
	}

	return nil
}

// writeData writes the supplied count data corresponding to the named data set
// to stdout or a file
func writeData(d *libmbd.MCellData, name string, data *libmbd.CountData) error {

	var outputTimes []float64
	if addTimesFlag {
		outputTimes = d.OutputTimes()
	}

	output := os.Stdout
	var err error
	if writeFileFlag {
		if output, err = os.Create(name); err != nil {
			return err
		}
	}

	numCols := len(data.Col)
	numRows := len(data.Col[0])
	for r := 0; r < numRows; r++ {
		for c := 0; c < numCols; c++ {
			if addTimesFlag {
				fmt.Fprintf(output, "%8.5e %g", outputTimes[r], data.Col[c][r])
			} else {
				fmt.Fprintf(output, "%g", data.Col[c][r])
			}
		}
		fmt.Fprintf(output, "\n")
	}
	return nil
}
<|endoftext|>


<commit_before>package bowling

import (
	"fmt"
	"log"
)

type Game struct {
	frames []*Frame
	rolls  []int
}

func NewGame() *Game {
	return &Game{}
}

func (g *Game) Roll(pins int) error {
	if pins < 0 {
		return fmt.Errorf("negative roll is invalid")
	}
	if pins > 10 {
		return fmt.Errorf("roll can not hit more than 10 pins")
	}
	g.rolls = append(g.rolls, pins)
	return nil
}

func (g *Game) parseFrames() {
	g.frames = []*Frame{}
	for _, roll := range g.rolls {
		if len(g.frames) == 0 {
			isComplete := roll == 10
			g.frames = append(g.frames, &Frame{roll, 0, isComplete})
		} else if !g.lastFrame().isComplete {
			g.lastFrame().rollTwo = roll
			g.lastFrame().isComplete = true
		} else {
			isComplete := roll == 10
			g.frames = append(g.frames, &Frame{roll, 0, isComplete})
		}
	}
}

func (g *Game) Score() (total int, err error) {
	g.parseFrames()
	fmt.Printf("rolls: %v\nframes: %v\n", g.rolls, g.frames)
	if len(g.frames) < 10 {
		return 0, fmt.Errorf("not enough frames %v", g.frames)
	}
	for i, frame := range g.frames[0:10] {
		score := frame.score(g.frames[i+1:])
		fmt.Printf("frame: %v score %v\n", frame, score)
		total += score
	}
	return total, nil
}

func (g *Game) lastFrame() *Frame {
	return g.frames[len(g.frames)-1]
}

type Frame struct {
	rollOne    int
	rollTwo    int
	isComplete bool
}

func (f *Frame) String() string {
	return fmt.Sprintf("[%d, %d]", f.rollOne, f.rollTwo)
}

func (f *Frame) score(nextFrames []*Frame) int {
	if f.isOpenFrame() {
		return f.rollOne + f.rollTwo
	}
	nextRoll, nextNextRoll := nextRolls(nextFrames)
	if f.isSpare() {
		return 10 + nextRoll
	}
	if f.isStrike() {
		return 10 + nextRoll + nextNextRoll
	}
	log.Fatalf("frame %v is not an open frame, spare, or strike", f)
	return 0
}

func (f *Frame) isStrike() bool {
	return isStrike(f.rollOne)
}

func (f *Frame) isSpare() bool {
	return !f.isStrike() && f.rollOne+f.rollTwo == 10
}

func (f *Frame) isOpenFrame() bool {
	return !f.isStrike() && !f.isSpare()
}

func isStrike(roll int) bool {
	return roll == 10
}

func nextRolls(nextFrames []*Frame) (nextRoll int, nextNextRoll int) {
	if len(nextFrames) == 0 {
		return 0, 0
	}
	rolls := []int{}
	for _, frame := range nextFrames {
		if frame.isStrike() {
			rolls = append(rolls, frame.rollOne)
		} else {
			rolls = append(rolls, frame.rollOne)
			rolls = append(rolls, frame.rollTwo)
		}
	}

	if len(rolls) >= 2 {
		return rolls[0], rolls[1]
	} else if len(rolls) == 1 {
		return rolls[0], 0
	} else {
		log.Fatalf("rolls %v is empty", rolls)
		return 0, 0
	}
}
<commit_msg>Handle pin count exceeds pins on the lane<commit_after>package bowling

import (
	"fmt"
	"log"
)

type Game struct {
	frames []*Frame
	rolls  []int
}

func NewGame() *Game {
	return &Game{}
}

func (g *Game) Roll(pins int) error {
	if pins < 0 {
		return fmt.Errorf("negative roll is invalid")
	}
	if pins > 10 {
		return fmt.Errorf("roll can not hit more than 10 pins")
	}
	g.rolls = append(g.rolls, pins)
	return g.parseFrames()
}

func (g *Game) parseFrames() error {
	g.frames = []*Frame{}
	for _, roll := range g.rolls {
		isComplete := roll == 10

		if len(g.frames) == 0 {
			g.frames = append(g.frames, &Frame{roll, 0, isComplete})
		} else if !g.lastFrame().isComplete {
			if g.lastFrame().rollOne+roll > 10 {
				return fmt.Errorf("second roll hit more than number of pins on the lane")
			}
			g.lastFrame().rollTwo = roll
			g.lastFrame().isComplete = true
		} else {
			g.frames = append(g.frames, &Frame{roll, 0, isComplete})
		}
	}
	return nil
}

func (g *Game) Score() (total int, err error) {
	g.parseFrames()
	fmt.Printf("rolls: %v\nframes: %v\n", g.rolls, g.frames)
	if len(g.frames) < 10 {
		return 0, fmt.Errorf("not enough frames %v", g.frames)
	}
	for i, frame := range g.frames[0:10] {
		score := frame.score(g.frames[i+1:])
		fmt.Printf("frame: %v score %v\n", frame, score)
		total += score
	}
	return total, nil
}

func (g *Game) lastFrame() *Frame {
	return g.frames[len(g.frames)-1]
}

type Frame struct {
	rollOne    int
	rollTwo    int
	isComplete bool
}

func (f *Frame) String() string {
	return fmt.Sprintf("[%d, %d]", f.rollOne, f.rollTwo)
}

func (f *Frame) score(nextFrames []*Frame) int {
	if f.isOpenFrame() {
		return f.rollOne + f.rollTwo
	}
	nextRoll, nextNextRoll := nextRolls(nextFrames)
	if f.isSpare() {
		return 10 + nextRoll
	}
	if f.isStrike() {
		return 10 + nextRoll + nextNextRoll
	}
	log.Fatalf("frame %v is not an open frame, spare, or strike", f)
	return 0
}

func (f *Frame) isStrike() bool {
	return isStrike(f.rollOne)
}

func (f *Frame) isSpare() bool {
	return !f.isStrike() && f.rollOne+f.rollTwo == 10
}

func (f *Frame) isOpenFrame() bool {
	return !f.isStrike() && !f.isSpare()
}

func isStrike(roll int) bool {
	return roll == 10
}

func nextRolls(nextFrames []*Frame) (nextRoll int, nextNextRoll int) {
	if len(nextFrames) == 0 {
		return 0, 0
	}
	rolls := []int{}
	for _, frame := range nextFrames {
		if frame.isStrike() {
			rolls = append(rolls, frame.rollOne)
		} else {
			rolls = append(rolls, frame.rollOne)
			rolls = append(rolls, frame.rollTwo)
		}
	}

	if len(rolls) >= 2 {
		return rolls[0], rolls[1]
	} else if len(rolls) == 1 {
		return rolls[0], 0
	} else {
		log.Fatalf("rolls %v is empty", rolls)
		return 0, 0
	}
}
<|endoftext|>


<commit_before>package render

import (
	"errors"
	"fmt"
	"github.com/extrame/goblet/error"
	"html/template"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"reflect"
	"strconv"
	"strings"
)

type HtmlRender struct {
	root     *template.Template
	dir      string
	models   map[string]*template.Template
	suffix   string
	saveTemp bool
}

func (h *HtmlRender) PrepareInstance(ctx RenderContext) (instance RenderInstance, err error) {
	var layout, yield *template.Template

	err = errors.New("")

	var root *template.Template

	if !h.saveTemp {
		root, _ = h.root.Clone()
		h.initGlobalTemplate(root)
	} else {
		root = h.root
	}

	if ctx.StatusCode() >= 300 {
		layout, err = h.getTemplate(root, "layout/"+"error"+h.suffix, filepath.Join("layout", "error"+h.suffix))
		if err != nil {
			layout, err = h.getTemplate(root, "layout/"+ctx.Layout()+h.suffix, filepath.Join("layout", ctx.Layout()+h.suffix))
		}
		yield, err = h.getTemplate(root, strconv.Itoa(ctx.StatusCode())+h.suffix, filepath.Join(strconv.Itoa(ctx.StatusCode())+h.suffix))
		if err != nil {
			log.Println("Find Err Code Fail, ", err)
		}
	}
	if err != nil {
		h.initModelTemplate(root, ctx.TemplatePath())
		switch ctx.BlockOptionType() {

		case "Html":
			layout, err = h.getTemplate(root, "layout/"+ctx.Layout()+h.suffix, filepath.Join("layout", ctx.Layout()+h.suffix))
			if err == nil {
				yield, err = h.getTemplate(root, ctx.Method()+h.suffix)
			}
		case "Rest":
			if layout, err = h.getTemplate(root, "module_layout/"+ctx.Layout()+h.suffix, filepath.Join(ctx.TemplatePath(), "layout", ctx.Layout()+h.suffix)); err != nil {
				layout, err = h.getTemplate(root, "layout/"+ctx.Layout()+h.suffix, filepath.Join("layout", ctx.Layout()+h.suffix))
			}
			if err == nil {
				yield, err = h.getTemplate(root, ctx.TemplatePath()+"/"+ctx.Method()+h.suffix)
			}
		case "Group":
			if layout, err = h.getTemplate(root, "module_layout/"+ctx.Layout()+h.suffix, filepath.Join(ctx.TemplatePath(), "layout", ctx.Layout()+h.suffix)); err != nil {
				layout, err = h.getTemplate(root, "layout/"+ctx.Layout()+h.suffix, filepath.Join("layout", ctx.Layout()+h.suffix))
			}
			if err == nil {
				yield, err = h.getTemplate(root, ctx.TemplatePath()+"/"+ctx.Method()+h.suffix)
			}
		case "Static":
			if layout, err = h.getTemplate(root, "module_layout/"+ctx.Layout()+h.suffix, filepath.Join(ctx.TemplatePath(), "layout", ctx.Layout()+h.suffix)); err != nil {
				layout, err = h.getTemplate(root, "layout/"+ctx.Layout()+h.suffix, filepath.Join("layout", ctx.Layout()+h.suffix))
			}
			if err == nil {
				yield, err = h.getTemplate(root, ctx.TemplatePath()+"/"+ctx.Method()+h.suffix)
			}
		}
	}
	if err == nil {
		return &HttpRenderInstance{layout, yield, "/css/" + ctx.TemplatePath() + "/" + ctx.Method() + ".css", "/js/" + ctx.TemplatePath() + "/" + ctx.Method() + ".js"}, nil
	}

	return
}

func (h *HtmlRender) Init(s RenderServer, funcs template.FuncMap) {
	h.root = template.New("REST_HTTP_ROOT")
	origin_funcs := template.FuncMap{"js": RawHtml, "css": RawHtml, "raw": RawHtml, "yield": RawHtml, "status": RawHtml, "slice": Slice, "mask": RawHtml, "repeat": Repeat}
	for k, v := range funcs {
		origin_funcs[k] = v
	}
	h.root.Funcs(origin_funcs)
	h.dir = s.WwwRoot()
	h.suffix = ".html"
	h.models = make(map[string]*template.Template)
	h.saveTemp = (s.Env() == "production")
	if h.saveTemp {
		h.initGlobalTemplate(h.root)
	}
}

func (h *HtmlRender) initTemplate(parent *template.Template, dir string, typ string) {
	parent.New("")
	if !h.saveTemp { //for debug
		log.Println("init template in ", h.dir, dir, "helper")
	}
	//scan for the helpers
	filepath.Walk(filepath.Join(h.dir, dir, "helper"), func(path string, info os.FileInfo, err error) error {
		if err == nil && (!info.IsDir()) && strings.HasSuffix(info.Name(), h.suffix) {
			name := strings.TrimSuffix(info.Name(), h.suffix)
			log.Printf("Parse helper:%s(%s)", typ+"/"+name, path)
			e := parseFileWithName(parent, typ+"/"+name, path)
			if e != nil {
				fmt.Printf("ERROR template.ParseFile: %v", e)
			}
		}
		return nil
	})
}

func (h *HtmlRender) initGlobalTemplate(parent *template.Template) {
	h.initTemplate(parent, ".", "global")
}

func (h *HtmlRender) initModelTemplate(parent *template.Template, dir string) {
	if dir != "" || dir != "." {
		h.initTemplate(parent, dir, "model")
	}
}

func (h *HtmlRender) getTemplate(root *template.Template, args ...string) (*template.Template, error) {
	var name, file string
	if len(args) == 1 {
		name = args[0]
		file = args[0]
	} else {
		name = args[1]
		file = args[1]
	}
	if !h.saveTemp { //for debug
		log.Println("get template of ", name, file)
	}
	file = filepath.FromSlash(file)
	t := h.models[name]

	if t == nil {
		cloned_rest_model, err := root.Clone()

		if err == nil {

			err = parseFileWithName(cloned_rest_model, name, filepath.Join(h.dir, file))
			if err == nil {
				t = cloned_rest_model.Lookup(name)
				if h.saveTemp {
					h.models[name] = t
				}
			} else {
				if os.IsNotExist(err) {
					return nil, ge.NOSUCHROUTER
				} else {
					return nil, err
				}
			}
		}
	}
	return t, nil
}

type HttpRenderInstance struct {
	layout   *template.Template
	yield    *template.Template
	css_file string
	js_file  string
}

func (h *HttpRenderInstance) Render(wr http.ResponseWriter, data interface{}, status int, funcs template.FuncMap) error {
	var mask_map = make(map[string]bool)

	funcMap := template.FuncMap{
		"yield": func() (template.HTML, error) {
			err := h.yield.Execute(wr, data)
			if err != nil {
				log.Printf("%v%T", err, err)
			}
			// return safe html here since we are rendering our own template
			return template.HTML(""), err
		},
		"status": func() int {
			return status
		},
		"mask": func(tag string) string {
			if _, ok := mask_map[tag]; ok {
				return "true"
			} else {
				mask_map[tag] = true
			}
			return ""
		},
		"css": func() template.HTML {
			return template.HTML(`<link rel="stylesheet" type="text/css" href="` + h.css_file + `"></link>`)
		},
		"js": func() template.HTML {
			return template.HTML(`<script src="` + h.js_file + `"></script>`)
		},
	}
	for k, v := range funcs {
		funcMap[k] = v
	}
	h.layout.Funcs(funcMap)
	h.yield.Funcs(funcMap)

	if h.layout != nil {
		return h.layout.Execute(wr, data)
	} else if h.yield != nil {
		return h.yield.Execute(wr, data)
	}
	return nil
}

func parseFileWithName(parent *template.Template, name string, filepath string) error {
	b, err := ioutil.ReadFile(filepath)
	if err != nil {
		return err
	}
	s := string(b)
	// First template becomes return value if not already defined,
	// and we use that one for subsequent New calls to associate
	// all the templates together. Also, if this file has the same name
	// as t, this file becomes the contents of t, so
	//  t, err := New(name).Funcs(xxx).ParseFiles(name)
	// works. Otherwise we create a new template associated with t.
	var tmpl *template.Template
	if name == parent.Name() || name == "" {
		tmpl = parent
	} else {
		tmpl = parent.New(name)
	}
	_, err = tmpl.Parse(s)
	if err != nil {
		return err
	}
	return nil
}

func RawHtml(text string) template.HTML { return template.HTML(text) }

func Slice(obj interface{}, leng int) interface{} {
	slice := reflect.ValueOf(obj)
	new_leng := slice.Len() / leng

	if slice.Len()%leng != 0 {
		new_leng++
	}
	new_array := reflect.MakeSlice(reflect.SliceOf(slice.Type()), new_leng, new_leng)
	for i := 0; i < new_leng; i++ {
		end := (i + 1) * leng
		if end > slice.Len() {
			end = slice.Len()
		}
		item_array_in_new_array := slice.Slice(i*leng, end)
		new_array.Index(i).Set(item_array_in_new_array)
	}
	return new_array.Interface()
}

func Repeat(count int) []int {
	res := make([]int, count)
	for i := 0; i < count; i++ {
		res[i] = i
	}
	return res
}
<commit_msg>fix js function for other types<commit_after>package render

import (
	"errors"
	"fmt"
	"github.com/extrame/goblet/error"
	"html/template"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"reflect"
	"strconv"
	"strings"
)

type HtmlRender struct {
	root     *template.Template
	dir      string
	models   map[string]*template.Template
	suffix   string
	saveTemp bool
}

func (h *HtmlRender) PrepareInstance(ctx RenderContext) (instance RenderInstance, err error) {
	var layout, yield *template.Template

	err = errors.New("")

	var root *template.Template

	if !h.saveTemp {
		root, _ = h.root.Clone()
		h.initGlobalTemplate(root)
	} else {
		root = h.root
	}

	if ctx.StatusCode() >= 300 {
		layout, err = h.getTemplate(root, "layout/"+"error"+h.suffix, filepath.Join("layout", "error"+h.suffix))
		if err != nil {
			layout, err = h.getTemplate(root, "layout/"+ctx.Layout()+h.suffix, filepath.Join("layout", ctx.Layout()+h.suffix))
		}
		yield, err = h.getTemplate(root, strconv.Itoa(ctx.StatusCode())+h.suffix, filepath.Join(strconv.Itoa(ctx.StatusCode())+h.suffix))
		if err != nil {
			log.Println("Find Err Code Fail, ", err)
		}
	}
	path := ctx.TemplatePath() + "/" + ctx.Method()
	if err != nil {
		h.initModelTemplate(root, ctx.TemplatePath())
		switch ctx.BlockOptionType() {

		case "Html":
			layout, err = h.getTemplate(root, "layout/"+ctx.Layout()+h.suffix, filepath.Join("layout", ctx.Layout()+h.suffix))
			path = ctx.Method()
			if err == nil {
				yield, err = h.getTemplate(root, path+h.suffix)
			}
		case "Rest":
			if layout, err = h.getTemplate(root, "module_layout/"+ctx.Layout()+h.suffix, filepath.Join(ctx.TemplatePath(), "layout", ctx.Layout()+h.suffix)); err != nil {
				layout, err = h.getTemplate(root, "layout/"+ctx.Layout()+h.suffix, filepath.Join("layout", ctx.Layout()+h.suffix))
			}
			if err == nil {
				yield, err = h.getTemplate(root, path+h.suffix)
			}
		case "Group":
			if layout, err = h.getTemplate(root, "module_layout/"+ctx.Layout()+h.suffix, filepath.Join(ctx.TemplatePath(), "layout", ctx.Layout()+h.suffix)); err != nil {
				layout, err = h.getTemplate(root, "layout/"+ctx.Layout()+h.suffix, filepath.Join("layout", ctx.Layout()+h.suffix))
			}
			if err == nil {
				yield, err = h.getTemplate(root, path+h.suffix)
			}
		case "Static":
			if layout, err = h.getTemplate(root, "module_layout/"+ctx.Layout()+h.suffix, filepath.Join(ctx.TemplatePath(), "layout", ctx.Layout()+h.suffix)); err != nil {
				layout, err = h.getTemplate(root, "layout/"+ctx.Layout()+h.suffix, filepath.Join("layout", ctx.Layout()+h.suffix))
			}
			if err == nil {
				yield, err = h.getTemplate(root, path+h.suffix)
			}
		}
	}
	if err == nil {
		return &HttpRenderInstance{layout, yield, "/css/" + path + ".css", "/js/" + path + ".js"}, nil
	}

	return
}

func (h *HtmlRender) Init(s RenderServer, funcs template.FuncMap) {
	h.root = template.New("REST_HTTP_ROOT")
	origin_funcs := template.FuncMap{"js": RawHtml, "css": RawHtml, "raw": RawHtml, "yield": RawHtml, "status": RawHtml, "slice": Slice, "mask": RawHtml, "repeat": Repeat}
	for k, v := range funcs {
		origin_funcs[k] = v
	}
	h.root.Funcs(origin_funcs)
	h.dir = s.WwwRoot()
	h.suffix = ".html"
	h.models = make(map[string]*template.Template)
	h.saveTemp = (s.Env() == "production")
	if h.saveTemp {
		h.initGlobalTemplate(h.root)
	}
}

func (h *HtmlRender) initTemplate(parent *template.Template, dir string, typ string) {
	parent.New("")
	if !h.saveTemp { //for debug
		log.Println("init template in ", h.dir, dir, "helper")
	}
	//scan for the helpers
	filepath.Walk(filepath.Join(h.dir, dir, "helper"), func(path string, info os.FileInfo, err error) error {
		if err == nil && (!info.IsDir()) && strings.HasSuffix(info.Name(), h.suffix) {
			name := strings.TrimSuffix(info.Name(), h.suffix)
			log.Printf("Parse helper:%s(%s)", typ+"/"+name, path)
			e := parseFileWithName(parent, typ+"/"+name, path)
			if e != nil {
				fmt.Printf("ERROR template.ParseFile: %v", e)
			}
		}
		return nil
	})
}

func (h *HtmlRender) initGlobalTemplate(parent *template.Template) {
	h.initTemplate(parent, ".", "global")
}

func (h *HtmlRender) initModelTemplate(parent *template.Template, dir string) {
	if dir != "" || dir != "." {
		h.initTemplate(parent, dir, "model")
	}
}

func (h *HtmlRender) getTemplate(root *template.Template, args ...string) (*template.Template, error) {
	var name, file string
	if len(args) == 1 {
		name = args[0]
		file = args[0]
	} else {
		name = args[1]
		file = args[1]
	}
	if !h.saveTemp { //for debug
		log.Println("get template of ", name, file)
	}
	file = filepath.FromSlash(file)
	t := h.models[name]

	if t == nil {
		cloned_rest_model, err := root.Clone()

		if err == nil {

			err = parseFileWithName(cloned_rest_model, name, filepath.Join(h.dir, file))
			if err == nil {
				t = cloned_rest_model.Lookup(name)
				if h.saveTemp {
					h.models[name] = t
				}
			} else {
				if os.IsNotExist(err) {
					return nil, ge.NOSUCHROUTER
				} else {
					return nil, err
				}
			}
		}
	}
	return t, nil
}

type HttpRenderInstance struct {
	layout   *template.Template
	yield    *template.Template
	css_file string
	js_file  string
}

func (h *HttpRenderInstance) Render(wr http.ResponseWriter, data interface{}, status int, funcs template.FuncMap) error {
	var mask_map = make(map[string]bool)

	funcMap := template.FuncMap{
		"yield": func() (template.HTML, error) {
			err := h.yield.Execute(wr, data)
			if err != nil {
				log.Printf("%v%T", err, err)
			}
			// return safe html here since we are rendering our own template
			return template.HTML(""), err
		},
		"status": func() int {
			return status
		},
		"mask": func(tag string) string {
			if _, ok := mask_map[tag]; ok {
				return "true"
			} else {
				mask_map[tag] = true
			}
			return ""
		},
		"css": func() template.HTML {
			return template.HTML(`<link rel="stylesheet" type="text/css" href="` + h.css_file + `"></link>`)
		},
		"js": func() template.HTML {
			return template.HTML(`<script src="` + h.js_file + `"></script>`)
		},
	}
	for k, v := range funcs {
		funcMap[k] = v
	}
	h.layout.Funcs(funcMap)
	h.yield.Funcs(funcMap)

	if h.layout != nil {
		return h.layout.Execute(wr, data)
	} else if h.yield != nil {
		return h.yield.Execute(wr, data)
	}
	return nil
}

func parseFileWithName(parent *template.Template, name string, filepath string) error {
	b, err := ioutil.ReadFile(filepath)
	if err != nil {
		return err
	}
	s := string(b)
	// First template becomes return value if not already defined,
	// and we use that one for subsequent New calls to associate
	// all the templates together. Also, if this file has the same name
	// as t, this file becomes the contents of t, so
	//  t, err := New(name).Funcs(xxx).ParseFiles(name)
	// works. Otherwise we create a new template associated with t.
	var tmpl *template.Template
	if name == parent.Name() || name == "" {
		tmpl = parent
	} else {
		tmpl = parent.New(name)
	}
	_, err = tmpl.Parse(s)
	if err != nil {
		return err
	}
	return nil
}

func RawHtml(text string) template.HTML { return template.HTML(text) }

func Slice(obj interface{}, leng int) interface{} {
	slice := reflect.ValueOf(obj)
	new_leng := slice.Len() / leng

	if slice.Len()%leng != 0 {
		new_leng++
	}
	new_array := reflect.MakeSlice(reflect.SliceOf(slice.Type()), new_leng, new_leng)
	for i := 0; i < new_leng; i++ {
		end := (i + 1) * leng
		if end > slice.Len() {
			end = slice.Len()
		}
		item_array_in_new_array := slice.Slice(i*leng, end)
		new_array.Index(i).Set(item_array_in_new_array)
	}
	return new_array.Interface()
}

func Repeat(count int) []int {
	res := make([]int, count)
	for i := 0; i < count; i++ {
		res[i] = i
	}
	return res
}
<|endoftext|>


<commit_before>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package service

import (
	"errors"

	"golang.org/x/net/context"

	"github.com/keybase/client/go/libkb"
	keybase1 "github.com/keybase/client/go/protocol"
	rpc "github.com/keybase/go-framed-msgpack-rpc"
)

var ErrNoSession = errors.New("no current session")

// SessionHandler is the RPC handler for the session interface.
type SessionHandler struct {
	libkb.Contextified
	*BaseHandler
}

// NewSessionHandler creates a SessionHandler for the xp transport.
func NewSessionHandler(xp rpc.Transporter, g *libkb.GlobalContext) *SessionHandler {
	return &SessionHandler{
		BaseHandler:  NewBaseHandler(xp),
		Contextified: libkb.NewContextified(g),
	}
}

// CurrentSession uses the global session to find the session.  If
// the user isn't logged in, it returns ErrNoSession.
func (h *SessionHandler) CurrentSession(_ context.Context, sessionID int) (keybase1.Session, error) {
	var s keybase1.Session
	var token string
	var username libkb.NormalizedUsername
	var uid keybase1.UID
	var deviceSubkey, deviceSibkey libkb.GenericKey
	var err error

	aerr := h.G().LoginState().Account(func(a *libkb.Account) {
		uid, username, token, deviceSubkey, deviceSibkey, err = a.UserInfo()
	}, "Service - SessionHandler - UserInfo")
	if aerr != nil {
		return s, aerr
	}
	if err != nil {
		if _, ok := err.(libkb.LoginRequiredError); ok {
			return s, ErrNoSession
		}
		return s, err
	}

	s.Uid = uid
	s.Username = username.String()
	s.Token = token
	s.DeviceSubkeyKid = deviceSubkey.GetKID()
	s.DeviceSibkeyKid = deviceSibkey.GetKID()

	return s, nil
}
<commit_msg>Call LoggedInProvisionedLoad before UserInfo<commit_after>// Copyright 2015 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package service

import (
	"errors"

	"golang.org/x/net/context"

	"github.com/keybase/client/go/libkb"
	keybase1 "github.com/keybase/client/go/protocol"
	rpc "github.com/keybase/go-framed-msgpack-rpc"
)

var ErrNoSession = errors.New("no current session")

// SessionHandler is the RPC handler for the session interface.
type SessionHandler struct {
	libkb.Contextified
	*BaseHandler
}

// NewSessionHandler creates a SessionHandler for the xp transport.
func NewSessionHandler(xp rpc.Transporter, g *libkb.GlobalContext) *SessionHandler {
	return &SessionHandler{
		BaseHandler:  NewBaseHandler(xp),
		Contextified: libkb.NewContextified(g),
	}
}

// CurrentSession uses the global session to find the session.  If
// the user isn't logged in, it returns ErrNoSession.
func (h *SessionHandler) CurrentSession(_ context.Context, sessionID int) (keybase1.Session, error) {
	var s keybase1.Session
	var token string
	var username libkb.NormalizedUsername
	var uid keybase1.UID
	var deviceSubkey, deviceSibkey libkb.GenericKey
	var err error

	aerr := h.G().LoginState().Account(func(a *libkb.Account) {
		_, err = a.LoggedInProvisionedLoad()
		if err != nil {
			return
		}
		uid, username, token, deviceSubkey, deviceSibkey, err = a.UserInfo()
	}, "Service - SessionHandler - UserInfo")
	if aerr != nil {
		return s, aerr
	}
	if err != nil {
		if _, ok := err.(libkb.LoginRequiredError); ok {
			return s, ErrNoSession
		}
		return s, err
	}

	s.Uid = uid
	s.Username = username.String()
	s.Token = token
	s.DeviceSubkeyKid = deviceSubkey.GetKID()
	s.DeviceSibkeyKid = deviceSibkey.GetKID()

	return s, nil
}
<|endoftext|>


<commit_before>package main

import (
	"database/sql"
	"encoding/json"
	_ "github.com/go-sql-driver/mysql"
	"html/template"
	"log"
	"math/rand"
	"net/http"
	"runtime"
	"sort"
	"strconv"
	"sync"
)

type MessageStruct struct {
	Message string
}

type World struct {
	Id           uint16 `json:"id"`
	RandomNumber uint16 `json:"randomNumber"`
}

type Fortune struct {
	Id      uint16 `json:"id"`
	Message string `json:"message"`
}

const (
	ConnectionString   = "benchmarkdbuser:benchmarkdbpass@tcp(localhost:3306)/hello_world"
	WorldSelect        = "SELECT id, randomNumber FROM World where id = ?"
	FortuneSelect      = "SELECT id, message FROM Fortune;"
	WorldRowCount      = 10000
	MaxConnectionCount = 100
)

var (
	tmpl = template.Must(template.ParseFiles("templates/layout.html", "templates/fortune.html"))

	worldStatement    *sql.Stmt
	fourtuneStatement *sql.Stmt
)

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	db, err := sql.Open("mysql", ConnectionString)
	if err != nil {
		log.Fatalf("Error opening database: %v", err)
	}
	db.SetMaxIdleConns(MaxConnectionCount)
	worldStatement, err = db.Prepare(WorldSelect)
	if err != nil {
		log.Fatal(err)
	}
	fourtuneStatement, err = db.Prepare(FortuneSelect)
	if err != nil {
		log.Fatal(err)
	}

	http.HandleFunc("/db", worldHandler)
	http.HandleFunc("/json", jsonHandler)
	http.HandleFunc("/fortune", fortuneHandler)
	http.ListenAndServe(":8080", nil)
}

func jsonHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/javascript")
	j, _ := json.Marshal(&MessageStruct{"Hello, world"})
	w.Header().Set("Content-Length", strconv.Itoa(len(j)))
	w.Write(j)
}

func worldHandler(w http.ResponseWriter, r *http.Request) {
	n := 1
	if nStr := r.URL.Query().Get("queries"); len(nStr) != 0 {
		n, _ = strconv.Atoi(nStr)
	}
	ww := make([]World, n)
	if n == 1 {
		worldStatement.QueryRow(rand.Intn(WorldRowCount)+1).Scan(&ww[0].Id, &ww[0].RandomNumber)
	} else {
		var wg sync.WaitGroup
		wg.Add(n)
		for i := 0; i < n; i++ {
			go func(i int) {
				err := worldStatement.QueryRow(rand.Intn(WorldRowCount)+1).Scan(&ww[i].Id, &ww[i].RandomNumber)
				if err != nil {
					log.Fatalf("Error scanning world row: %v", err)
				}
				wg.Done()
			}(i)
		}
		wg.Wait()
	}
	j, _ := json.Marshal(ww)
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Content-Length", strconv.Itoa(len(j)))
	w.Write(j)
}

func fortuneHandler(w http.ResponseWriter, r *http.Request) {
	fortunes := make([]*Fortune, 0, 16)

	//Execute the query
	rows, err := fourtuneStatement.Query()
	if err != nil {
		log.Fatalf("Error preparing statement: %v", err)
	}

	i := 0
	var fortune *Fortune
	for rows.Next() { //Fetch rows
		fortune = new(Fortune)
		if err = rows.Scan(&fortune.Id, &fortune.Message); err != nil {
			log.Fatalf("Error scanning fortune row: %v", err)
		}
		fortunes = append(fortunes, fortune)
		i++
	}
	fortunes = append(fortunes, &Fortune{Message: "Additional fortune added at request time."})

	sort.Sort(ByMessage{fortunes})
	w.Header().Set("Content-Type", "text/html")
	if err := tmpl.Execute(w, map[string]interface{}{"fortunes": fortunes}); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

type Fortunes []*Fortune

func (s Fortunes) Len() int      { return len(s) }
func (s Fortunes) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

type ByMessage struct{ Fortunes }

func (s ByMessage) Less(i, j int) bool { return s.Fortunes[i].Message < s.Fortunes[j].Message }
<commit_msg>Added charset=utf8 to DSN for the fortune test<commit_after>package main

import (
	"database/sql"
	"encoding/json"
	_ "github.com/go-sql-driver/mysql"
	"html/template"
	"log"
	"math/rand"
	"net/http"
	"runtime"
	"sort"
	"strconv"
	"sync"
)

type MessageStruct struct {
	Message string
}

type World struct {
	Id           uint16 `json:"id"`
	RandomNumber uint16 `json:"randomNumber"`
}

type Fortune struct {
	Id      uint16 `json:"id"`
	Message string `json:"message"`
}

const (
	ConnectionString   = "benchmarkdbuser:benchmarkdbpass@tcp(localhost:3306)/hello_world?charset=utf8"
	WorldSelect        = "SELECT id, randomNumber FROM World where id = ?"
	FortuneSelect      = "SELECT id, message FROM Fortune;"
	WorldRowCount      = 10000
	MaxConnectionCount = 100
)

var (
	tmpl = template.Must(template.ParseFiles("templates/layout.html", "templates/fortune.html"))

	worldStatement    *sql.Stmt
	fortuneStatement *sql.Stmt
)

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())

	db, err := sql.Open("mysql", ConnectionString)
	if err != nil {
		log.Fatalf("Error opening database: %v", err)
	}
	db.SetMaxIdleConns(MaxConnectionCount)
	worldStatement, err = db.Prepare(WorldSelect)
	if err != nil {
		log.Fatal(err)
	}
	fortuneStatement, err = db.Prepare(FortuneSelect)
	if err != nil {
		log.Fatal(err)
	}

	http.HandleFunc("/db", worldHandler)
	http.HandleFunc("/json", jsonHandler)
	http.HandleFunc("/fortune", fortuneHandler)
	http.ListenAndServe(":8080", nil)
}

func jsonHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/javascript")
	j, _ := json.Marshal(&MessageStruct{"Hello, world"})
	w.Header().Set("Content-Length", strconv.Itoa(len(j)))
	w.Write(j)
}

func worldHandler(w http.ResponseWriter, r *http.Request) {
	n := 1
	if nStr := r.URL.Query().Get("queries"); len(nStr) != 0 {
		n, _ = strconv.Atoi(nStr)
	}
	ww := make([]World, n)
	if n == 1 {
		worldStatement.QueryRow(rand.Intn(WorldRowCount)+1).Scan(&ww[0].Id, &ww[0].RandomNumber)
	} else {
		var wg sync.WaitGroup
		wg.Add(n)
		for i := 0; i < n; i++ {
			go func(i int) {
				err := worldStatement.QueryRow(rand.Intn(WorldRowCount)+1).Scan(&ww[i].Id, &ww[i].RandomNumber)
				if err != nil {
					log.Fatalf("Error scanning world row: %v", err)
				}
				wg.Done()
			}(i)
		}
		wg.Wait()
	}
	j, _ := json.Marshal(ww)
	w.Header().Set("Content-Type", "application/json")
	w.Header().Set("Content-Length", strconv.Itoa(len(j)))
	w.Write(j)
}

func fortuneHandler(w http.ResponseWriter, r *http.Request) {
	fortunes := make([]*Fortune, 0, 16)

	//Execute the query
	rows, err := fortuneStatement.Query()
	if err != nil {
		log.Fatalf("Error preparing statement: %v", err)
	}

	i := 0
	var fortune *Fortune
	for rows.Next() { //Fetch rows
		fortune = new(Fortune)
		if err = rows.Scan(&fortune.Id, &fortune.Message); err != nil {
			log.Fatalf("Error scanning fortune row: %v", err)
		}
		fortunes = append(fortunes, fortune)
		i++
	}
	fortunes = append(fortunes, &Fortune{Message: "Additional fortune added at request time."})

	sort.Sort(ByMessage{fortunes})
	w.Header().Set("Content-Type", "text/html")
	if err := tmpl.Execute(w, map[string]interface{}{"fortunes": fortunes}); err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

type Fortunes []*Fortune

func (s Fortunes) Len() int      { return len(s) }
func (s Fortunes) Swap(i, j int) { s[i], s[j] = s[j], s[i] }

type ByMessage struct{ Fortunes }

func (s ByMessage) Less(i, j int) bool { return s.Fortunes[i].Message < s.Fortunes[j].Message }
<|endoftext|>


<commit_before>package rest

import (
	"errors"
	"net/url"
	"testing"

	"github.com/rs/rest-layer/resource"
	"github.com/rs/rest-layer/schema"
	"github.com/stretchr/testify/assert"
	"golang.org/x/net/context"
)

// mockHandler is a read-only storage handler which always return what is stored in items
// with no support for filtering/sorting or error if err is set
type mockHandler struct {
	items   []*resource.Item
	err     error
	queries []schema.Query
}

func (m *mockHandler) Insert(ctx context.Context, items []*resource.Item) error {
	return ErrNotImplemented
}
func (m *mockHandler) Update(ctx context.Context, item *resource.Item, original *resource.Item) error {
	return ErrNotImplemented
}
func (m *mockHandler) Delete(ctx context.Context, item *resource.Item) error {
	return ErrNotImplemented
}
func (m *mockHandler) Clear(ctx context.Context, lookup *resource.Lookup) (int, error) {
	return 0, ErrNotImplemented
}
func (m *mockHandler) Find(ctx context.Context, lookup *resource.Lookup, page, perPage int) (*resource.ItemList, error) {
	if m.err != nil {
		return nil, m.err
	}
	m.queries = append(m.queries, lookup.Filter())
	return &resource.ItemList{len(m.items), page, m.items}, nil
}

func newRoute(method string) *RouteMatch {
	return &RouteMatch{
		Method:       method,
		ResourcePath: ResourcePath{},
		Params:       url.Values{},
	}
}

func TestFindRoute(t *testing.T) {
	var route *RouteMatch
	var err *Error
	index := resource.NewIndex()
	i, _ := resource.NewItem(map[string]interface{}{"id": "1234"})
	h := &mockHandler{[]*resource.Item{i}, nil, []schema.Query{}}
	foo := index.Bind("foo", resource.New(schema.Schema{}, h, resource.DefaultConf))
	bar := foo.Bind("bar", "f", resource.New(schema.Schema{"f": schema.Field{}}, h, resource.DefaultConf))
	barbar := bar.Bind("bar", "b", resource.New(schema.Schema{"b": schema.Field{}}, h, resource.DefaultConf))
	bar.Alias("baz", url.Values{"sort": []string{"foo"}})

	route = newRoute("GET")
	err = findRoute("/foo", index, route)
	if assert.Nil(t, err) {
		assert.Equal(t, foo, route.Resource())
		assert.Equal(t, url.Values{}, route.Params)
		assert.Nil(t, route.ResourceID())
		rp := route.ResourcePath
		if assert.Len(t, rp, 1) {
			assert.Equal(t, "foo", rp[0].Name)
			assert.Equal(t, "", rp[0].Field)
			assert.Nil(t, rp[0].Value)
		}
	}

	route = newRoute("GET")
	err = findRoute("/foo/1234", index, route)
	if assert.Nil(t, err) {
		assert.Equal(t, foo, route.Resource())
		assert.Equal(t, url.Values{}, route.Params)
		assert.Equal(t, "1234", route.ResourceID())
		rp := route.ResourcePath
		if assert.Len(t, rp, 1) {
			assert.Equal(t, "foo", rp[0].Name)
			assert.Equal(t, "id", rp[0].Field)
			assert.Equal(t, "1234", rp[0].Value)
		}
	}

	route = newRoute("GET")
	err = findRoute("/foo/1234/bar", index, route)
	if assert.Nil(t, err) {
		assert.Equal(t, bar, route.Resource())
		assert.Nil(t, route.ResourceID())
		assert.Equal(t, url.Values{}, route.Params)
		rp := route.ResourcePath
		if assert.Len(t, rp, 2) {
			assert.Equal(t, "foo", rp[0].Name)
			assert.Equal(t, "f", rp[0].Field)
			assert.Equal(t, "1234", rp[0].Value)
			assert.Equal(t, "bar", rp[1].Name)
			assert.Equal(t, "", rp[1].Field)
			assert.Nil(t, rp[1].Value)
		}
	}

	route = newRoute("GET")
	err = findRoute("/foo/1234/bar/1234", index, route)
	if assert.Nil(t, err) {
		assert.Equal(t, bar, route.Resource())
		assert.Equal(t, "1234", route.ResourceID())
		assert.Equal(t, url.Values{}, route.Params)
		rp := route.ResourcePath
		if assert.Len(t, rp, 2) {
			assert.Equal(t, "foo", rp[0].Name)
			assert.Equal(t, "f", rp[0].Field)
			assert.Equal(t, "1234", rp[0].Value)
			assert.Equal(t, "bar", rp[1].Name)
			assert.Equal(t, "id", rp[1].Field)
			assert.Equal(t, "1234", rp[1].Value)
		}
	}

	route = newRoute("GET")
	err = findRoute("/foo/1234/bar/1234/bar", index, route)
	if assert.Nil(t, err) {
		assert.Equal(t, barbar, route.Resource())
		assert.Nil(t, route.ResourceID())
		assert.Equal(t, url.Values{}, route.Params)
		rp := route.ResourcePath
		if assert.Len(t, rp, 3) {
			assert.Equal(t, "foo", rp[0].Name)
			assert.Equal(t, "f", rp[0].Field)
			assert.Equal(t, "1234", rp[0].Value)
			assert.Equal(t, "bar", rp[1].Name)
			assert.Equal(t, "b", rp[1].Field)
			assert.Equal(t, "1234", rp[1].Value)
			assert.Equal(t, "bar", rp[2].Name)
			assert.Equal(t, "", rp[2].Field)
			assert.Nil(t, rp[2].Value)
		}
	}

	route = newRoute("GET")
	err = findRoute("/foo/1234/bar/1234/bar/1234", index, route)
	if assert.Nil(t, err) {
		assert.Equal(t, barbar, route.Resource())
		assert.Equal(t, "1234", route.ResourceID())
		assert.Equal(t, url.Values{}, route.Params)
		rp := route.ResourcePath
		if assert.Len(t, rp, 3) {
			assert.Equal(t, "foo", rp[0].Name)
			assert.Equal(t, "f", rp[0].Field)
			assert.Equal(t, "1234", rp[0].Value)
			assert.Equal(t, "bar", rp[1].Name)
			assert.Equal(t, "b", rp[1].Field)
			assert.Equal(t, "1234", rp[1].Value)
			assert.Equal(t, "bar", rp[2].Name)
			assert.Equal(t, "id", rp[2].Field)
			assert.Equal(t, "1234", rp[2].Value)
		}
	}

	route = newRoute("GET")
	err = findRoute("/foo/1234/bar/baz", index, route)
	if assert.Nil(t, err) {
		assert.Equal(t, bar, route.Resource())
		assert.Equal(t, url.Values{"sort": []string{"foo"}}, route.Params)
		assert.Nil(t, route.ResourceID())
		rp := route.ResourcePath
		if assert.Len(t, rp, 2) {
			assert.Equal(t, "foo", rp[0].Name)
			assert.Equal(t, "f", rp[0].Field)
			assert.Equal(t, "1234", rp[0].Value)
			assert.Equal(t, "bar", rp[1].Name)
			assert.Equal(t, "", rp[1].Field)
			assert.Nil(t, rp[1].Value)
		}
	}

	route = newRoute("GET")
	err = findRoute("/foo/1234/bar/baz/baz", index, route)
	assert.Equal(t, &Error{404, "Resource Not Found", nil}, err)
	assert.Nil(t, route.Resource())
	assert.Nil(t, route.ResourceID())
}

func TestRoutePathParentsExists(t *testing.T) {
	var route *RouteMatch
	var err error
	index := resource.NewIndex()
	i, _ := resource.NewItem(map[string]interface{}{"id": "1234"})
	h := &mockHandler{[]*resource.Item{i}, nil, []schema.Query{}}
	foo := index.Bind("foo", resource.New(schema.Schema{}, h, resource.DefaultConf))
	bar := foo.Bind("bar", "f", resource.New(schema.Schema{"f": schema.Field{}}, h, resource.DefaultConf))
	bar.Bind("baz", "b", resource.New(schema.Schema{"f": schema.Field{}, "b": schema.Field{}}, h, resource.DefaultConf))
	ctx := context.Background()

	route = newRoute("GET")
	err = findRoute("/foo/1234/bar/5678/baz/9000", index, route)
	if assert.NoError(t, err) {
		err = route.ResourcePath.ParentsExist(ctx)
		assert.NoError(t, err)
		// There's 3 components in the path but only 2 are parents
		assert.Len(t, h.queries, 2)
		// query on /foo/1234
		assert.Contains(t, h.queries, schema.Query{schema.Equal{Field: "id", Value: "1234"}})
		// query on /bar/5678 with foo/1234 context
		assert.Contains(t, h.queries, schema.Query{schema.Equal{Field: "f", Value: "1234"}, schema.Equal{Field: "id", Value: "5678"}})
	}

	route = newRoute("GET")
	// empty the storage handler
	h.items = []*resource.Item{}
	err = findRoute("/foo/1234/bar", index, route)
	if assert.NoError(t, err) {
		err = route.ResourcePath.ParentsExist(ctx)
		assert.Equal(t, &Error{404, "Parent Resource Not Found", nil}, err)
	}

	route = newRoute("GET")
	// for error
	h.err = errors.New("test")
	err = findRoute("/foo/1234/bar", index, route)
	if assert.NoError(t, err) {
		err = route.ResourcePath.ParentsExist(ctx)
		assert.EqualError(t, err, "test")
	}
}

func TestRoutePathParentsNotExists(t *testing.T) {
	index := resource.NewIndex()
	i, _ := resource.NewItem(map[string]interface{}{"id": "1234"})
	h := &mockHandler{[]*resource.Item{i}, nil, []schema.Query{}}
	empty := &mockHandler{[]*resource.Item{}, nil, []schema.Query{}}
	foo := index.Bind("foo", resource.New(schema.Schema{}, empty, resource.DefaultConf))
	foo.Bind("bar", "f", resource.New(schema.Schema{"f": schema.Field{}}, h, resource.DefaultConf))
	ctx := context.Background()

	route := newRoute("GET")
	// non existing foo
	err := findRoute("/foo/4321/bar/1234", index, route)
	if assert.NoError(t, err) {
		err := route.ResourcePath.ParentsExist(ctx)
		assert.Equal(t, &Error{404, "Parent Resource Not Found", nil}, err)
	}
}
<commit_msg>routing_test.go: fix race condition<commit_after>package rest

import (
	"errors"
	"net/url"
	"sync"
	"testing"

	"github.com/rs/rest-layer/resource"
	"github.com/rs/rest-layer/schema"
	"github.com/stretchr/testify/assert"
	"golang.org/x/net/context"
)

// mockHandler is a read-only storage handler which always return what is stored in items
// with no support for filtering/sorting or error if err is set
type mockHandler struct {
	items   []*resource.Item
	err     error
	queries []schema.Query
	lock    sync.Mutex
}

func (m *mockHandler) Insert(ctx context.Context, items []*resource.Item) error {
	return ErrNotImplemented
}
func (m *mockHandler) Update(ctx context.Context, item *resource.Item, original *resource.Item) error {
	return ErrNotImplemented
}
func (m *mockHandler) Delete(ctx context.Context, item *resource.Item) error {
	return ErrNotImplemented
}
func (m *mockHandler) Clear(ctx context.Context, lookup *resource.Lookup) (int, error) {
	return 0, ErrNotImplemented
}
func (m *mockHandler) Find(ctx context.Context, lookup *resource.Lookup, page, perPage int) (*resource.ItemList, error) {
	if m.err != nil {
		return nil, m.err
	}
	m.lock.Lock()
	defer m.lock.Unlock()
	m.queries = append(m.queries, lookup.Filter())
	return &resource.ItemList{Total: len(m.items), Page: page, Items: m.items}, nil
}

func newRoute(method string) *RouteMatch {
	return &RouteMatch{
		Method:       method,
		ResourcePath: ResourcePath{},
		Params:       url.Values{},
	}
}

func TestFindRoute(t *testing.T) {
	var route *RouteMatch
	var err *Error
	index := resource.NewIndex()
	i, _ := resource.NewItem(map[string]interface{}{"id": "1234"})
	h := &mockHandler{[]*resource.Item{i}, nil, []schema.Query{}, sync.Mutex{}}
	foo := index.Bind("foo", resource.New(schema.Schema{}, h, resource.DefaultConf))
	bar := foo.Bind("bar", "f", resource.New(schema.Schema{"f": schema.Field{}}, h, resource.DefaultConf))
	barbar := bar.Bind("bar", "b", resource.New(schema.Schema{"b": schema.Field{}}, h, resource.DefaultConf))
	bar.Alias("baz", url.Values{"sort": []string{"foo"}})

	route = newRoute("GET")
	err = findRoute("/foo", index, route)
	if assert.Nil(t, err) {
		assert.Equal(t, foo, route.Resource())
		assert.Equal(t, url.Values{}, route.Params)
		assert.Nil(t, route.ResourceID())
		rp := route.ResourcePath
		if assert.Len(t, rp, 1) {
			assert.Equal(t, "foo", rp[0].Name)
			assert.Equal(t, "", rp[0].Field)
			assert.Nil(t, rp[0].Value)
		}
	}

	route = newRoute("GET")
	err = findRoute("/foo/1234", index, route)
	if assert.Nil(t, err) {
		assert.Equal(t, foo, route.Resource())
		assert.Equal(t, url.Values{}, route.Params)
		assert.Equal(t, "1234", route.ResourceID())
		rp := route.ResourcePath
		if assert.Len(t, rp, 1) {
			assert.Equal(t, "foo", rp[0].Name)
			assert.Equal(t, "id", rp[0].Field)
			assert.Equal(t, "1234", rp[0].Value)
		}
	}

	route = newRoute("GET")
	err = findRoute("/foo/1234/bar", index, route)
	if assert.Nil(t, err) {
		assert.Equal(t, bar, route.Resource())
		assert.Nil(t, route.ResourceID())
		assert.Equal(t, url.Values{}, route.Params)
		rp := route.ResourcePath
		if assert.Len(t, rp, 2) {
			assert.Equal(t, "foo", rp[0].Name)
			assert.Equal(t, "f", rp[0].Field)
			assert.Equal(t, "1234", rp[0].Value)
			assert.Equal(t, "bar", rp[1].Name)
			assert.Equal(t, "", rp[1].Field)
			assert.Nil(t, rp[1].Value)
		}
	}

	route = newRoute("GET")
	err = findRoute("/foo/1234/bar/1234", index, route)
	if assert.Nil(t, err) {
		assert.Equal(t, bar, route.Resource())
		assert.Equal(t, "1234", route.ResourceID())
		assert.Equal(t, url.Values{}, route.Params)
		rp := route.ResourcePath
		if assert.Len(t, rp, 2) {
			assert.Equal(t, "foo", rp[0].Name)
			assert.Equal(t, "f", rp[0].Field)
			assert.Equal(t, "1234", rp[0].Value)
			assert.Equal(t, "bar", rp[1].Name)
			assert.Equal(t, "id", rp[1].Field)
			assert.Equal(t, "1234", rp[1].Value)
		}
	}

	route = newRoute("GET")
	err = findRoute("/foo/1234/bar/1234/bar", index, route)
	if assert.Nil(t, err) {
		assert.Equal(t, barbar, route.Resource())
		assert.Nil(t, route.ResourceID())
		assert.Equal(t, url.Values{}, route.Params)
		rp := route.ResourcePath
		if assert.Len(t, rp, 3) {
			assert.Equal(t, "foo", rp[0].Name)
			assert.Equal(t, "f", rp[0].Field)
			assert.Equal(t, "1234", rp[0].Value)
			assert.Equal(t, "bar", rp[1].Name)
			assert.Equal(t, "b", rp[1].Field)
			assert.Equal(t, "1234", rp[1].Value)
			assert.Equal(t, "bar", rp[2].Name)
			assert.Equal(t, "", rp[2].Field)
			assert.Nil(t, rp[2].Value)
		}
	}

	route = newRoute("GET")
	err = findRoute("/foo/1234/bar/1234/bar/1234", index, route)
	if assert.Nil(t, err) {
		assert.Equal(t, barbar, route.Resource())
		assert.Equal(t, "1234", route.ResourceID())
		assert.Equal(t, url.Values{}, route.Params)
		rp := route.ResourcePath
		if assert.Len(t, rp, 3) {
			assert.Equal(t, "foo", rp[0].Name)
			assert.Equal(t, "f", rp[0].Field)
			assert.Equal(t, "1234", rp[0].Value)
			assert.Equal(t, "bar", rp[1].Name)
			assert.Equal(t, "b", rp[1].Field)
			assert.Equal(t, "1234", rp[1].Value)
			assert.Equal(t, "bar", rp[2].Name)
			assert.Equal(t, "id", rp[2].Field)
			assert.Equal(t, "1234", rp[2].Value)
		}
	}

	route = newRoute("GET")
	err = findRoute("/foo/1234/bar/baz", index, route)
	if assert.Nil(t, err) {
		assert.Equal(t, bar, route.Resource())
		assert.Equal(t, url.Values{"sort": []string{"foo"}}, route.Params)
		assert.Nil(t, route.ResourceID())
		rp := route.ResourcePath
		if assert.Len(t, rp, 2) {
			assert.Equal(t, "foo", rp[0].Name)
			assert.Equal(t, "f", rp[0].Field)
			assert.Equal(t, "1234", rp[0].Value)
			assert.Equal(t, "bar", rp[1].Name)
			assert.Equal(t, "", rp[1].Field)
			assert.Nil(t, rp[1].Value)
		}
	}

	route = newRoute("GET")
	err = findRoute("/foo/1234/bar/baz/baz", index, route)
	assert.Equal(t, &Error{404, "Resource Not Found", nil}, err)
	assert.Nil(t, route.Resource())
	assert.Nil(t, route.ResourceID())
}

func TestRoutePathParentsExists(t *testing.T) {
	var route *RouteMatch
	var err error
	index := resource.NewIndex()
	i, _ := resource.NewItem(map[string]interface{}{"id": "1234"})
	h := &mockHandler{[]*resource.Item{i}, nil, []schema.Query{}, sync.Mutex{}}
	foo := index.Bind("foo", resource.New(schema.Schema{}, h, resource.DefaultConf))
	bar := foo.Bind("bar", "f", resource.New(schema.Schema{"f": schema.Field{}}, h, resource.DefaultConf))
	bar.Bind("baz", "b", resource.New(schema.Schema{"f": schema.Field{}, "b": schema.Field{}}, h, resource.DefaultConf))
	ctx := context.Background()

	route = newRoute("GET")
	err = findRoute("/foo/1234/bar/5678/baz/9000", index, route)
	if assert.NoError(t, err) {
		err = route.ResourcePath.ParentsExist(ctx)
		assert.NoError(t, err)
		// There's 3 components in the path but only 2 are parents
		assert.Len(t, h.queries, 2)
		// query on /foo/1234
		assert.Contains(t, h.queries, schema.Query{schema.Equal{Field: "id", Value: "1234"}})
		// query on /bar/5678 with foo/1234 context
		assert.Contains(t, h.queries, schema.Query{schema.Equal{Field: "f", Value: "1234"}, schema.Equal{Field: "id", Value: "5678"}})
	}

	route = newRoute("GET")
	// empty the storage handler
	h.items = []*resource.Item{}
	err = findRoute("/foo/1234/bar", index, route)
	if assert.NoError(t, err) {
		err = route.ResourcePath.ParentsExist(ctx)
		assert.Equal(t, &Error{404, "Parent Resource Not Found", nil}, err)
	}

	route = newRoute("GET")
	// for error
	h.err = errors.New("test")
	err = findRoute("/foo/1234/bar", index, route)
	if assert.NoError(t, err) {
		err = route.ResourcePath.ParentsExist(ctx)
		assert.EqualError(t, err, "test")
	}
}

func TestRoutePathParentsNotExists(t *testing.T) {
	index := resource.NewIndex()
	i, _ := resource.NewItem(map[string]interface{}{"id": "1234"})
	h := &mockHandler{[]*resource.Item{i}, nil, []schema.Query{}, sync.Mutex{}}
	empty := &mockHandler{[]*resource.Item{}, nil, []schema.Query{}, sync.Mutex{}}
	foo := index.Bind("foo", resource.New(schema.Schema{}, empty, resource.DefaultConf))
	foo.Bind("bar", "f", resource.New(schema.Schema{"f": schema.Field{}}, h, resource.DefaultConf))
	ctx := context.Background()

	route := newRoute("GET")
	// non existing foo
	err := findRoute("/foo/4321/bar/1234", index, route)
	if assert.NoError(t, err) {
		err := route.ResourcePath.ParentsExist(ctx)
		assert.Equal(t, &Error{404, "Parent Resource Not Found", nil}, err)
	}
}
<|endoftext|>


<commit_before>// Copyright 2013 The Go 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 ssa_test

// This file runs the SSA builder in sanity-checking mode on all
// packages beneath $GOROOT and prints some summary information.
//
// Run test with GOMAXPROCS=8.

import (
	"go/token"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
	"time"

	"code.google.com/p/go.tools/go/loader"
	"code.google.com/p/go.tools/go/ssa"
	"code.google.com/p/go.tools/go/ssa/ssautil"
)

func allPackages() []string {
	var pkgs []string
	root := filepath.Join(runtime.GOROOT(), "src/pkg") + string(os.PathSeparator)
	filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		// Prune the search if we encounter any of these names:
		switch filepath.Base(path) {
		case "testdata", ".hg":
			return filepath.SkipDir
		}
		if info.IsDir() {
			pkg := strings.TrimPrefix(path, root)
			switch pkg {
			case "builtin", "pkg", "code.google.com":
				return filepath.SkipDir // skip these subtrees
			case "":
				return nil // ignore root of tree
			}
			pkgs = append(pkgs, pkg)
		}

		return nil
	})
	return pkgs
}

func TestStdlib(t *testing.T) {
	// Load, parse and type-check the program.
	t0 := time.Now()

	var conf loader.Config
	conf.SourceImports = true
	if _, err := conf.FromArgs(allPackages(), true); err != nil {
		t.Errorf("FromArgs failed: %v", err)
		return
	}

	iprog, err := conf.Load()
	if err != nil {
		t.Fatalf("Load failed: %v", err)
	}

	t1 := time.Now()

	runtime.GC()
	var memstats runtime.MemStats
	runtime.ReadMemStats(&memstats)
	alloc := memstats.Alloc

	// Create SSA packages.
	var mode ssa.BuilderMode
	// Comment out these lines during benchmarking.  Approx SSA build costs are noted.
	mode |= ssa.SanityCheckFunctions // + 2% space, + 4% time
	mode |= ssa.GlobalDebug          // +30% space, +18% time
	prog := ssa.Create(iprog, mode)

	t2 := time.Now()

	// Build SSA.
	prog.BuildAll()

	t3 := time.Now()

	runtime.GC()
	runtime.ReadMemStats(&memstats)

	numPkgs := len(prog.AllPackages())
	if want := 140; numPkgs < want {
		t.Errorf("Loaded only %d packages, want at least %d", numPkgs, want)
	}

	// Dump some statistics.
	allFuncs := ssautil.AllFunctions(prog)
	var numInstrs int
	for fn := range allFuncs {
		for _, b := range fn.Blocks {
			numInstrs += len(b.Instrs)
		}
	}

	// determine line count
	var lineCount int
	prog.Fset.Iterate(func(f *token.File) bool {
		lineCount += f.LineCount()
		return true
	})

	// NB: when benchmarking, don't forget to clear the debug +
	// sanity builder flags for better performance.

	t.Log("GOMAXPROCS:           ", runtime.GOMAXPROCS(0))
	t.Log("#Source lines:        ", lineCount)
	t.Log("Load/parse/typecheck: ", t1.Sub(t0))
	t.Log("SSA create:           ", t2.Sub(t1))
	t.Log("SSA build:            ", t3.Sub(t2))

	// SSA stats:
	t.Log("#Packages:            ", numPkgs)
	t.Log("#Functions:           ", len(allFuncs))
	t.Log("#Instructions:        ", numInstrs)
	t.Log("#MB:                  ", int64(memstats.Alloc-alloc)/1000000)
}
<commit_msg>go/loader: convert directory separators to slash when enumerating packages.<commit_after>// Copyright 2013 The Go 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 ssa_test

// This file runs the SSA builder in sanity-checking mode on all
// packages beneath $GOROOT and prints some summary information.
//
// Run test with GOMAXPROCS=8.

import (
	"go/token"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"testing"
	"time"

	"code.google.com/p/go.tools/go/loader"
	"code.google.com/p/go.tools/go/ssa"
	"code.google.com/p/go.tools/go/ssa/ssautil"
)

func allPackages() []string {
	var pkgs []string
	root := filepath.Join(runtime.GOROOT(), "src/pkg") + string(os.PathSeparator)
	filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		// Prune the search if we encounter any of these names:
		switch filepath.Base(path) {
		case "testdata", ".hg":
			return filepath.SkipDir
		}
		if info.IsDir() {
			pkg := filepath.ToSlash(strings.TrimPrefix(path, root))
			switch pkg {
			case "builtin", "pkg":
				return filepath.SkipDir // skip these subtrees
			case "":
				return nil // ignore root of tree
			}
			pkgs = append(pkgs, pkg)
		}

		return nil
	})
	return pkgs
}

func TestStdlib(t *testing.T) {
	// Load, parse and type-check the program.
	t0 := time.Now()

	var conf loader.Config
	conf.SourceImports = true
	if _, err := conf.FromArgs(allPackages(), true); err != nil {
		t.Errorf("FromArgs failed: %v", err)
		return
	}

	iprog, err := conf.Load()
	if err != nil {
		t.Fatalf("Load failed: %v", err)
	}

	t1 := time.Now()

	runtime.GC()
	var memstats runtime.MemStats
	runtime.ReadMemStats(&memstats)
	alloc := memstats.Alloc

	// Create SSA packages.
	var mode ssa.BuilderMode
	// Comment out these lines during benchmarking.  Approx SSA build costs are noted.
	mode |= ssa.SanityCheckFunctions // + 2% space, + 4% time
	mode |= ssa.GlobalDebug          // +30% space, +18% time
	prog := ssa.Create(iprog, mode)

	t2 := time.Now()

	// Build SSA.
	prog.BuildAll()

	t3 := time.Now()

	runtime.GC()
	runtime.ReadMemStats(&memstats)

	numPkgs := len(prog.AllPackages())
	if want := 140; numPkgs < want {
		t.Errorf("Loaded only %d packages, want at least %d", numPkgs, want)
	}

	// Dump some statistics.
	allFuncs := ssautil.AllFunctions(prog)
	var numInstrs int
	for fn := range allFuncs {
		for _, b := range fn.Blocks {
			numInstrs += len(b.Instrs)
		}
	}

	// determine line count
	var lineCount int
	prog.Fset.Iterate(func(f *token.File) bool {
		lineCount += f.LineCount()
		return true
	})

	// NB: when benchmarking, don't forget to clear the debug +
	// sanity builder flags for better performance.

	t.Log("GOMAXPROCS:           ", runtime.GOMAXPROCS(0))
	t.Log("#Source lines:        ", lineCount)
	t.Log("Load/parse/typecheck: ", t1.Sub(t0))
	t.Log("SSA create:           ", t2.Sub(t1))
	t.Log("SSA build:            ", t3.Sub(t2))

	// SSA stats:
	t.Log("#Packages:            ", numPkgs)
	t.Log("#Functions:           ", len(allFuncs))
	t.Log("#Instructions:        ", numInstrs)
	t.Log("#MB:                  ", int64(memstats.Alloc-alloc)/1000000)
}
<|endoftext|>