<commit_before>package controllers

import (
	"log"
	"net/http"

	"github.com/UniversityRadioYork/2016-site/models"
	"github.com/UniversityRadioYork/2016-site/structs"
	"github.com/UniversityRadioYork/2016-site/utils"
	"github.com/UniversityRadioYork/myradio-go"
)

// IndexController is the controller for the index page.
type IndexController struct {
	Controller
}

type RenderData struct {
	CurrentAndNext *myradio.CurrentAndNext
	Banners        []myradio.Banner
	Teams          []myradio.Team
	MsgBoxError    bool
}

// NewIndexController returns a new IndexController with the MyRadio session s
// and configuration context c.
func NewIndexController(s *myradio.Session, c *structs.Config) *IndexController {
	return &IndexController{Controller{session: s, config: c}}
}

// Get handles the HTTP GET request r for the index page, writing to w.
func (ic *IndexController) Get(w http.ResponseWriter, r *http.Request) {
	// This is where any form params would be parsed
	model := models.NewIndexModel(ic.session)

	currentAndNext, banners, teams, err := model.Get()

	if err != nil {
		log.Println(err)
		return
	}

	data := RenderData{
		CurrentAndNext: currentAndNext,
		Banners:        banners,
		Teams:          teams,
		MsgBoxError:    false,
	}

	ic.render(w, data)
}

// Post handles the HTTP POST request r to the index page that sends a message. Writes to w.
func (ic *IndexController) Post(w http.ResponseWriter, r *http.Request) {
	// Parse message from request
	r.ParseForm()
	msg := r.Form.Get("message")

	// Get all the data for the webpage
	model := models.NewIndexModel(ic.session)

	currentAndNext, banners, teams, err := model.Get()

	if err != nil {
		log.Println(err)
		return
	}

	data := RenderData{
		CurrentAndNext: currentAndNext,
		Banners:        banners,
		Teams:          teams,
	}

	// Create the message model and send the message
	msgmodel := models.NewMessageModel(ic.session)
	err = msgmodel.Put(msg)
	if err != nil {
		// Set prompt if send fails
		data.MsgBoxError = true
		log.Println(err)
	}

	ic.render(w, data)

}

func (ic *IndexController) render(w http.ResponseWriter, data RenderData) {
	// Render page
	err := utils.RenderTemplate(w, ic.config.PageContext, data, "index.tmpl", "elements/current_and_next.tmpl", "elements/banner.tmpl", "elements/message_box.tmpl")
	if err != nil {
		log.Println(err)
		return
	}
}
<commit_msg>Initialize msgboxerror to false<commit_after>package controllers

import (
	"log"
	"net/http"

	"github.com/UniversityRadioYork/2016-site/models"
	"github.com/UniversityRadioYork/2016-site/structs"
	"github.com/UniversityRadioYork/2016-site/utils"
	"github.com/UniversityRadioYork/myradio-go"
)

// IndexController is the controller for the index page.
type IndexController struct {
	Controller
}

type RenderData struct {
	CurrentAndNext *myradio.CurrentAndNext
	Banners        []myradio.Banner
	Teams          []myradio.Team
	MsgBoxError    bool
}

// NewIndexController returns a new IndexController with the MyRadio session s
// and configuration context c.
func NewIndexController(s *myradio.Session, c *structs.Config) *IndexController {
	return &IndexController{Controller{session: s, config: c}}
}

// Get handles the HTTP GET request r for the index page, writing to w.
func (ic *IndexController) Get(w http.ResponseWriter, r *http.Request) {
	// This is where any form params would be parsed
	model := models.NewIndexModel(ic.session)

	currentAndNext, banners, teams, err := model.Get()

	if err != nil {
		log.Println(err)
		return
	}

	data := RenderData{
		CurrentAndNext: currentAndNext,
		Banners:        banners,
		Teams:          teams,
		MsgBoxError:    false,
	}

	ic.render(w, data)
}

// Post handles the HTTP POST request r to the index page that sends a message. Writes to w.
func (ic *IndexController) Post(w http.ResponseWriter, r *http.Request) {
	// Parse message from request
	r.ParseForm()
	msg := r.Form.Get("message")

	// Get all the data for the webpage
	model := models.NewIndexModel(ic.session)

	currentAndNext, banners, teams, err := model.Get()

	if err != nil {
		log.Println(err)
		return
	}

	data := RenderData{
		CurrentAndNext: currentAndNext,
		Banners:        banners,
		Teams:          teams,
		MsgBoxError:    false,
	}

	// Create the message model and send the message
	msgmodel := models.NewMessageModel(ic.session)
	err = msgmodel.Put(msg)
	if err != nil {
		// Set prompt if send fails
		data.MsgBoxError = true
		log.Println(err)
	}

	ic.render(w, data)

}

func (ic *IndexController) render(w http.ResponseWriter, data RenderData) {
	// Render page
	err := utils.RenderTemplate(w, ic.config.PageCotext, data, "index.tmpl", "elements/current_and_next.tmpl", "elements/banner.tmpl", "elements/message_box.tmpl")
	if err != nil {
		log.Println(err)
		return
	}
}
<|endoftext|>


<commit_before>package hashtable

import (
	"github.com/rasaford/algorithms/datastructures/list"
)

type Table interface {
	Insert(string, interface{})
	Search(string) interface{}
	Delete(string)
}

type chaining struct {
	values  []*list.List
	len     int
	maxLoad float64
}

type pair struct {
	key   string
	value interface{}
}

func NewChaining() Table {
	return &chaining{
		values:  make([]*list.List, 8),
		len:     0,
		maxLoad: 3,
	}
}

func (t *chaining) Insert(key string, val interface{}) {
	if t.loadFactor() > t.maxLoad {
		t.tableDouble()
	}
	hash := t.hash(key)
	if t.values[hash] == nil {
		t.values[hash] = list.New()
	}
	t.values[hash].Insert(&pair{key, val})
	t.len++
}

func (t *chaining) Search(key string) interface{} {
	hash := t.hash(key)
	list := t.values[hash]
	if list == nil || list.Len == 0 {
		return nil
	}
	head := list.Start().Prev
	for head != list.End() {
		head = head.Next
		pair := head.Value.(*pair)
		if pair.key == key {
			return pair.value
		}
	}
	return nil
}

func (t *chaining) Delete(key string) {
	hash := t.hash(key)
	list := t.values[hash]
	if list == nil {
		return
	}
	first := list.Start().Prev
	for first != list.End() {
		first = first.Next
		pair := first.Value.(*pair)
		if pair.key == key {
			list.Delete(first)
			t.len--
			return
		}
	}
}

func (t *chaining) loadFactor() float64 {
	return float64(t.len) / float64(len(t.values))
}

func (t *chaining) tableDouble() {
	oldVal := t.values
	size := len(oldVal)
	t.values = make([]*list.List, size*2)
	for i := 0; i < size; i++ {
		list := oldVal[i]
		if list == nil {
			continue
		}
		first := list.Start().Prev
		for first != list.End() {
			first = first.Next
			pair := first.Value.(*pair)
			k, v := pair.key, pair.value
			t.Insert(k, v)
		}
	}
}

func (t *chaining) hash(key string) uint32 {
	return HashMultiply32(stringToInt(key), uint32(len(t.values)-1))
}

func stringToInt(s string) uint32 {
	res, j := uint32(0), uint32(0)
	for i := uint32(0); i < uint32(len(s)); i++ {
		j = i % 32
		res += uint32(s[i]) << j
	}
	return res
}

type openAddressing struct {
	values []*deletablePair
	len    int
}
type deletablePair struct {
	pair
	deleted bool
}

func NewOpenAddressing() Table {
	return &openAddressing{
		values: make([]*deletablePair, 8),
		len:    0,
	}
}

func (t *openAddressing) Insert(key string, value interface{}) {
	if t.loadFactor() > 0.5 {
		t.tableDouble()
	}
	round := 0
	for round != len(t.values) {
		hash := t.hash(key, round)
		if t.values[hash] == nil || t.values[hash].deleted {
			t.values[hash] = &deletablePair{
				pair:    pair{key, value},
				deleted: false,
			}
			t.len++
			return
		}
		round++
	}
}

func (t *openAddressing) Search(key string) interface{} {
	round := 0
	for round != len(t.values) {
		hash := t.hash(key, round)
		slot := t.values[hash]
		if slot != nil && !slot.deleted && slot.key == key {
			return slot.value
		}
		round++
	}
	return nil
}

func (t *openAddressing) Delete(key string) {
	round := 0
	for round != len(t.values) {
		hash := t.hash(key, round)
		slot := t.values[hash]
		if slot != nil && slot.key == key {
			t.values[hash].deleted = true
			t.len--
			return
		}
		round++
	}
}

func (t *openAddressing) hash(key string, round int) uint32 {
	num := uint(stringToInt(key))
	max := uint(len(t.values) - 1)
	return uint32((hashDivision(num, max) + uint(round)*hashDivision2(num, max)) % max)
}

func (t *openAddressing) loadFactor() float64 {
	return float64(t.len) / float64(len(t.values))
}

func (t *openAddressing) tableDouble() {
	oldVal := t.values
	size := len(oldVal)
	t.values = make([]*deletablePair, size*2)
	for i := 0; i < size; i++ {
		list := oldVal[i]
		if list == nil || list.deleted {
			continue
		}
		t.Insert(list.key, list.value)
	}
}
<commit_msg>add hahstable documentation<commit_after>package hashtable

import (
	"github.com/rasaford/algorithms/datastructures/list"
)

// Table is a common interface for all the Hashtable implementations it supports:
// Insert, Search and Delete.
type Table interface {
	Insert(string, interface{})
	Search(string) interface{}
	Delete(string)
}

type chaining struct {
	values  []*list.List
	len     int
	maxLoad float64
}

type pair struct {
	key   string
	value interface{}
}

// NewChaining returns a new HashTable that uses chaining to deal with hash collisions.
// If the average length of the chains is >= 3 items, the table gets doubled in size.
func NewChaining() Table {
	return &chaining{
		values:  make([]*list.List, 8),
		len:     0,
		maxLoad: 3,
	}
}

// Insert inserts the given value at the hash location of the key.
// If the current loadfactor is > than the specified maximum, the underlying table
// gets doubled in size.
//
// It runs in O(1) expected time. Wort case is O(n) with n := len(table)
func (t *chaining) Insert(key string, val interface{}) {
	if t.loadFactor() > t.maxLoad {
		t.tableDouble()
	}
	hash := t.hash(key)
	if t.values[hash] == nil {
		t.values[hash] = list.New()
	}
	t.values[hash].Insert(&pair{key, val})
	t.len++
}

// Search seaches for the given key in the table and retuns an items if
// one is found. Otherwise nil is returned.
//
// It runs in O(1) time.
func (t *chaining) Search(key string) interface{} {
	hash := t.hash(key)
	list := t.values[hash]
	if list == nil || list.Len == 0 {
		return nil
	}
	head := list.Start().Prev
	for head != list.End() {
		head = head.Next
		pair := head.Value.(*pair)
		if pair.key == key {
			return pair.value
		}
	}
	return nil
}

// Delete deletes the value at the given key from the table.
//
// It runs in O(1) time.
func (t *chaining) Delete(key string) {
	hash := t.hash(key)
	list := t.values[hash]
	if list == nil {
		return
	}
	first := list.Start().Prev
	for first != list.End() {
		first = first.Next
		pair := first.Value.(*pair)
		if pair.key == key {
			list.Delete(first)
			t.len--
			return
		}
	}
}

func (t *chaining) loadFactor() float64 {
	return float64(t.len) / float64(len(t.values))
}

// tableDouble copies all keys / values from the current table into a newone, twice the size.
// All keys are rehashed to retain the properties of the hashtable.
func (t *chaining) tableDouble() {
	oldVal := t.values
	size := len(oldVal)
	t.values = make([]*list.List, size*2)
	for i := 0; i < size; i++ {
		list := oldVal[i]
		if list == nil {
			continue
		}
		first := list.Start().Prev
		for first != list.End() {
			first = first.Next
			pair := first.Value.(*pair)
			k, v := pair.key, pair.value
			t.Insert(k, v)
		}
	}
}

func (t *chaining) hash(key string) uint32 {
	return HashMultiply32(stringToInt(key), uint32(len(t.values)-1))
}

func stringToInt(s string) uint32 {
	res, j := uint32(0), uint32(0)
	for i := uint32(0); i < uint32(len(s)); i++ {
		j = i % 32
		res += uint32(s[i]) << j
	}
	return res
}

type openAddressing struct {
	values []*deletablePair
	len    int
}
type deletablePair struct {
	pair
	deleted bool
}

// NewOpenAddressing returns a Hashtable which uses only a single array to store the values
// and deals with hash collisions by rehashing the current key to a different slot until
// a non empty one is found.
func NewOpenAddressing() Table {
	return &openAddressing{
		values: make([]*deletablePair, 8),
		len:    0,
	}
}

// Insert inserts the given value at the hash location of the key.
// If the current loadfactor is > than the specified maximum, the underlying table
// gets doubled in size.
//
// It runs in O(1) expected time. Wort case is O(n) with n := len(table)
func (t *openAddressing) Insert(key string, value interface{}) {
	if t.loadFactor() > 0.5 {
		t.tableDouble()
	}
	round := 0
	for round != len(t.values) {
		hash := t.hash(key, round)
		if t.values[hash] == nil || t.values[hash].deleted {
			t.values[hash] = &deletablePair{
				pair:    pair{key, value},
				deleted: false,
			}
			t.len++
			return
		}
		round++
	}
}

// Search seaches for the given key in the table and retuns an items if
// one is found. Otherwise nil is returned.
//
// It runs in O(1) time.
func (t *openAddressing) Search(key string) interface{} {
	round := 0
	for round != len(t.values) {
		hash := t.hash(key, round)
		slot := t.values[hash]
		if slot != nil && !slot.deleted && slot.key == key {
			return slot.value
		}
		round++
	}
	return nil
}

// Delete deletes the value at the given key from the table.
//
// It runs in O(1) time.
func (t *openAddressing) Delete(key string) {
	round := 0
	for round != len(t.values) {
		hash := t.hash(key, round)
		slot := t.values[hash]
		if slot != nil && slot.key == key {
			t.values[hash].deleted = true
			t.len--
			return
		}
		round++
	}
}

// hash on an openAddressing table uses the double hashing scheme to deal with hash collisions.
func (t *openAddressing) hash(key string, round int) uint32 {
	num := uint(stringToInt(key))
	max := uint(len(t.values) - 1)
	return uint32((hashDivision(num, max) + uint(round)*hashDivision2(num, max)) % max)
}

func (t *openAddressing) loadFactor() float64 {
	return float64(t.len) / float64(len(t.values))
}

// tableDouble copies all keys / values from the current table into a newone, twice the size.
// All keys are rehashed to retain the properties of the hashtable.
func (t *openAddressing) tableDouble() {
	oldVal := t.values
	size := len(oldVal)
	t.values = make([]*deletablePair, size*2)
	for i := 0; i < size; i++ {
		list := oldVal[i]
		if list == nil || list.deleted {
			continue
		}
		t.Insert(list.key, list.value)
	}
}
<|endoftext|>


<commit_before>// Copyright (c) 2017 Cisco and/or its affiliates.
//
// 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 msg

import (
	"encoding/json"

	"github.com/golang/protobuf/proto"
	log "github.com/ligato/cn-infra/logging/logrus"
)

// NewChangeWatchResp is a constructor
func NewChangeWatchResp(message *DataChangeRequest, callback func(error)) *ChangeWatchResp {
	return &ChangeWatchResp{message: message, callback: callback}
}

// ChangeWatchResp adapts Datamessage to interface datasync.ChangeEvent
type ChangeWatchResp struct {
	message  *DataChangeRequest
	callback func(error)
}

// GetChangeType - see the comment in implemented interface datasync.ChangeEvent
func (ev *ChangeWatchResp) GetChangeType() datasync.PutDel {
	if ev.message.OperationType == PutDel_DEL {
		return datasync.Delete
	}

	return datasync.Put
}

// GetKey returns the key associated with the change
func (ev *ChangeWatchResp) GetKey() string {
	return ev.message.Key
}

// GetRevision //TODO
func (ev *ChangeWatchResp) GetRevision() int64 {
	return 0
}

// GetValue - see the comments in the interface datasync.ChangeEvent
func (ev *ChangeWatchResp) GetValue(val proto.Message) error {
	return json.Unmarshal(ev.message.Content, val) //TODO use contentType...
}

// GetPrevValue returns the value before change
func (ev *ChangeWatchResp) GetPrevValue(prevVal proto.Message) (prevExists bool, err error) {
	if ev.message.OperationType == PutDel_DEL {
		return false, err
	}

	return false, err //TODO prev value
}

// Done does nothing yet
func (ev *ChangeWatchResp) Done(err error) {
	//TODO publish response to the topic
	if err != nil {
		log.Error(err)
	}
}
<commit_msg> ODPM-361 FIX import<commit_after>// Copyright (c) 2017 Cisco and/or its affiliates.
//
// 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 msg

import (
	"encoding/json"

	"github.com/golang/protobuf/proto"
	"github.com/ligato/cn-infra/datasync"
	log "github.com/ligato/cn-infra/logging/logrus"
)

// NewChangeWatchResp is a constructor
func NewChangeWatchResp(message *DataChangeRequest, callback func(error)) *ChangeWatchResp {
	return &ChangeWatchResp{message: message, callback: callback}
}

// ChangeWatchResp adapts Datamessage to interface datasync.ChangeEvent
type ChangeWatchResp struct {
	message  *DataChangeRequest
	callback func(error)
}

// GetChangeType - see the comment in implemented interface datasync.ChangeEvent
func (ev *ChangeWatchResp) GetChangeType() datasync.PutDel {
	if ev.message.OperationType == PutDel_DEL {
		return datasync.Delete
	}

	return datasync.Put
}

// GetKey returns the key associated with the change
func (ev *ChangeWatchResp) GetKey() string {
	return ev.message.Key
}

// GetRevision //TODO
func (ev *ChangeWatchResp) GetRevision() int64 {
	return 0
}

// GetValue - see the comments in the interface datasync.ChangeEvent
func (ev *ChangeWatchResp) GetValue(val proto.Message) error {
	return json.Unmarshal(ev.message.Content, val) //TODO use contentType...
}

// GetPrevValue returns the value before change
func (ev *ChangeWatchResp) GetPrevValue(prevVal proto.Message) (prevExists bool, err error) {
	if ev.message.OperationType == PutDel_DEL {
		return false, err
	}

	return false, err //TODO prev value
}

// Done does nothing yet
func (ev *ChangeWatchResp) Done(err error) {
	//TODO publish response to the topic
	if err != nil {
		log.Error(err)
	}
}
<|endoftext|>


<commit_before>package php

import (
	"github.com/stephens2424/php/ast"
	"github.com/stephens2424/php/token"
)

func (p *Parser) parseIf() *ast.IfStmt {
	p.expect(token.OpenParen)
	n := &ast.IfStmt{}
	n.Condition = p.parseNextExpression()
	p.expect(token.CloseParen)

	p.next()
	n.TrueBranch = p.parseControlBlock(token.EndIf, token.ElseIf, token.Else)
	n.FalseBranch = ast.Block{}

	blockStyle := false
	switch p.current.typ {
	case token.ElseIf, token.Else, token.EndIf:
	default:
		p.next()
		blockStyle = true
	}

	switch p.current.typ {
	case token.ElseIf:
		n.FalseBranch = p.parseIf()
	case token.Else:
		p.next()
		if p.current.typ == token.If {
			n.FalseBranch = p.parseIf()
		} else {
			n.FalseBranch = p.parseControlBlock(token.EndIf)
		}
	default:
		if blockStyle {
			p.backup()
		}
	}

	return n
}

func (p *Parser) parseWhile() ast.Statement {
	p.expect(token.OpenParen)
	term := p.parseNextExpression()
	p.expect(token.CloseParen)
	p.next()
	block := p.parseControlBlock(token.EndWhile)
	return &ast.WhileStmt{
		Termination: term,
		LoopBlock:   block,
	}
}

func (p *Parser) parseForeach() ast.Statement {
	stmt := &ast.ForeachStmt{}
	p.expect(token.OpenParen)
	stmt.Source = p.parseNextExpression()
	p.expect(token.AsOperator)
	if p.peek().typ == token.AmpersandOperator {
		p.expect(token.AmpersandOperator)
	}
	p.expect(token.VariableOperator)
	p.next()
	first := ast.NewVariable(p.current.val)
	if p.peek().typ == token.ArrayKeyOperator {
		stmt.Key = first
		p.expect(token.ArrayKeyOperator)
		if p.peek().typ == token.AmpersandOperator {
			p.expect(token.AmpersandOperator)
		}
		p.expect(token.VariableOperator)
		p.next()
		stmt.Value = ast.NewVariable(p.current.val)
	} else {
		stmt.Value = first
	}
	p.expect(token.CloseParen)
	p.next()
	stmt.LoopBlock = p.parseControlBlock(token.EndForeach)
	return stmt
}

func (p *Parser) parseControlBlock(end ...token.Token) ast.Statement {
	// try to parse this in bash style, but it requires an end token
	if len(end) > 0 && p.current.typ == token.TernaryOperator2 {
		return p.parseStatementsUntil(end...)
	}
	return p.parseStmt()
}

func (p *Parser) parseFor() ast.Statement {
	stmt := &ast.ForStmt{}
	p.expect(token.OpenParen)
	stmt.Initialization = p.parseExpressionsUntil(token.Comma, token.StatementEnd)
	stmt.Termination = p.parseExpressionsUntil(token.Comma, token.StatementEnd)
	stmt.Iteration = p.parseExpressionsUntil(token.Comma, token.CloseParen)
	p.expectCurrent(token.CloseParen)
	p.next()
	stmt.LoopBlock = p.parseControlBlock(token.EndFor)
	return stmt
}

func (p *Parser) parseDo() ast.Statement {
	block := p.parseBlock()
	p.expect(token.While)
	p.expect(token.OpenParen)
	term := p.parseNextExpression()
	p.expect(token.CloseParen)
	p.expectStmtEnd()
	return &ast.DoWhileStmt{
		Termination: term,
		LoopBlock:   block,
	}
}

func (p *Parser) parseSwitch() ast.Statement {
	stmt := ast.SwitchStmt{}
	p.expect(token.OpenParen)
	stmt.Expression = p.parseExpression()
	p.expectCurrent(token.CloseParen)
	p.expect(token.BlockBegin, token.TernaryOperator2)
	p.next()
	for {
		switch p.current.typ {
		case token.Case:
			expr := p.parseNextExpression()
			p.expect(token.TernaryOperator2, token.StatementEnd)
			p.next()
			stmt.Cases = append(stmt.Cases, &ast.SwitchCase{
				Expression: expr,
				Block:      *(p.parseSwitchBlock()),
			})
		case token.Default:
			p.expect(token.TernaryOperator2, token.StatementEnd)
			p.next()
			stmt.DefaultCase = p.parseSwitchBlock()
		case token.BlockEnd, token.EndSwitch:
			return stmt
		default:
			p.errorf("Unexpected token. in switch statement:", p.current)
			return nil
		}
	}
}

func (p *Parser) parseSwitchBlock() *ast.Block {
	needBlockEnd := false
	if p.current.typ == token.BlockBegin {
		needBlockEnd = true
		p.next()
	}
	block := &ast.Block{
		Statements: make([]ast.Statement, 0),
	}
stmtLoop:
	for {
		switch p.current.typ {
		case token.BlockEnd:
			if needBlockEnd {
				needBlockEnd = false
				p.next()
			}
			fallthrough
		case token.Case, token.Default, token.EndSwitch:
			break stmtLoop
		default:
			stmt := p.parseStmt()
			if stmt == nil {
				p.errorf("Invalid statement in switch block", p.current)
				break stmtLoop
			}
			block.Statements = append(block.Statements, stmt)
			p.next()
		}
	}
	if needBlockEnd {
		p.errorf("switch case needs block end")
	}
	return block
}

func (p *Parser) parseDeclareBlock() *ast.DeclareBlock {
	declare := &ast.DeclareBlock{Declarations: make([]string, 0)}

	p.expectCurrent(token.Declare)
	p.expect(token.OpenParen)

	declare.Declarations = append(declare.Declarations, p.parseDeclareElement())

	p.next()
	for p.current.typ == token.Comma {
		declare.Declarations = append(declare.Declarations, p.parseDeclareElement())
		p.next()
	}

	p.expectCurrent(token.CloseParen)

	declare.Statements = p.parseBlock()
	return declare
}

func (p *Parser) parseDeclareElement() string {
	element := ""
	p.expect(token.Identifier)
	element += p.current.val

	p.expect(token.AssignmentOperator)
	element += p.current.val

	p.parseNextExpression()
	element += p.current.val
	return element
}
<commit_msg>Allowing declare statements without blocks<commit_after>package php

import (
	"github.com/stephens2424/php/ast"
	"github.com/stephens2424/php/token"
)

func (p *Parser) parseIf() *ast.IfStmt {
	p.expect(token.OpenParen)
	n := &ast.IfStmt{}
	n.Condition = p.parseNextExpression()
	p.expect(token.CloseParen)

	p.next()
	n.TrueBranch = p.parseControlBlock(token.EndIf, token.ElseIf, token.Else)
	n.FalseBranch = ast.Block{}

	blockStyle := false
	switch p.current.typ {
	case token.ElseIf, token.Else, token.EndIf:
	default:
		p.next()
		blockStyle = true
	}

	switch p.current.typ {
	case token.ElseIf:
		n.FalseBranch = p.parseIf()
	case token.Else:
		p.next()
		if p.current.typ == token.If {
			n.FalseBranch = p.parseIf()
		} else {
			n.FalseBranch = p.parseControlBlock(token.EndIf)
		}
	default:
		if blockStyle {
			p.backup()
		}
	}

	return n
}

func (p *Parser) parseWhile() ast.Statement {
	p.expect(token.OpenParen)
	term := p.parseNextExpression()
	p.expect(token.CloseParen)
	p.next()
	block := p.parseControlBlock(token.EndWhile)
	return &ast.WhileStmt{
		Termination: term,
		LoopBlock:   block,
	}
}

func (p *Parser) parseForeach() ast.Statement {
	stmt := &ast.ForeachStmt{}
	p.expect(token.OpenParen)
	stmt.Source = p.parseNextExpression()
	p.expect(token.AsOperator)
	if p.peek().typ == token.AmpersandOperator {
		p.expect(token.AmpersandOperator)
	}
	p.expect(token.VariableOperator)
	p.next()
	first := ast.NewVariable(p.current.val)
	if p.peek().typ == token.ArrayKeyOperator {
		stmt.Key = first
		p.expect(token.ArrayKeyOperator)
		if p.peek().typ == token.AmpersandOperator {
			p.expect(token.AmpersandOperator)
		}
		p.expect(token.VariableOperator)
		p.next()
		stmt.Value = ast.NewVariable(p.current.val)
	} else {
		stmt.Value = first
	}
	p.expect(token.CloseParen)
	p.next()
	stmt.LoopBlock = p.parseControlBlock(token.EndForeach)
	return stmt
}

func (p *Parser) parseControlBlock(end ...token.Token) ast.Statement {
	// try to parse this in bash style, but it requires an end token
	if len(end) > 0 && p.current.typ == token.TernaryOperator2 {
		return p.parseStatementsUntil(end...)
	}
	return p.parseStmt()
}

func (p *Parser) parseFor() ast.Statement {
	stmt := &ast.ForStmt{}
	p.expect(token.OpenParen)
	stmt.Initialization = p.parseExpressionsUntil(token.Comma, token.StatementEnd)
	stmt.Termination = p.parseExpressionsUntil(token.Comma, token.StatementEnd)
	stmt.Iteration = p.parseExpressionsUntil(token.Comma, token.CloseParen)
	p.expectCurrent(token.CloseParen)
	p.next()
	stmt.LoopBlock = p.parseControlBlock(token.EndFor)
	return stmt
}

func (p *Parser) parseDo() ast.Statement {
	block := p.parseBlock()
	p.expect(token.While)
	p.expect(token.OpenParen)
	term := p.parseNextExpression()
	p.expect(token.CloseParen)
	p.expectStmtEnd()
	return &ast.DoWhileStmt{
		Termination: term,
		LoopBlock:   block,
	}
}

func (p *Parser) parseSwitch() ast.Statement {
	stmt := ast.SwitchStmt{}
	p.expect(token.OpenParen)
	stmt.Expression = p.parseExpression()
	p.expectCurrent(token.CloseParen)
	p.expect(token.BlockBegin, token.TernaryOperator2)
	p.next()
	for {
		switch p.current.typ {
		case token.Case:
			expr := p.parseNextExpression()
			p.expect(token.TernaryOperator2, token.StatementEnd)
			p.next()
			stmt.Cases = append(stmt.Cases, &ast.SwitchCase{
				Expression: expr,
				Block:      *(p.parseSwitchBlock()),
			})
		case token.Default:
			p.expect(token.TernaryOperator2, token.StatementEnd)
			p.next()
			stmt.DefaultCase = p.parseSwitchBlock()
		case token.BlockEnd, token.EndSwitch:
			return stmt
		default:
			p.errorf("Unexpected token. in switch statement:", p.current)
			return nil
		}
	}
}

func (p *Parser) parseSwitchBlock() *ast.Block {
	needBlockEnd := false
	if p.current.typ == token.BlockBegin {
		needBlockEnd = true
		p.next()
	}
	block := &ast.Block{
		Statements: make([]ast.Statement, 0),
	}
stmtLoop:
	for {
		switch p.current.typ {
		case token.BlockEnd:
			if needBlockEnd {
				needBlockEnd = false
				p.next()
			}
			fallthrough
		case token.Case, token.Default, token.EndSwitch:
			break stmtLoop
		default:
			stmt := p.parseStmt()
			if stmt == nil {
				p.errorf("Invalid statement in switch block", p.current)
				break stmtLoop
			}
			block.Statements = append(block.Statements, stmt)
			p.next()
		}
	}
	if needBlockEnd {
		p.errorf("switch case needs block end")
	}
	return block
}

func (p *Parser) parseDeclareBlock() *ast.DeclareBlock {
	declare := &ast.DeclareBlock{Declarations: make([]string, 0)}

	p.expectCurrent(token.Declare)
	p.expect(token.OpenParen)

	declare.Declarations = append(declare.Declarations, p.parseDeclareElement())

	p.next()
	for p.current.typ == token.Comma {
		declare.Declarations = append(declare.Declarations, p.parseDeclareElement())
		p.next()
	}

	p.expectCurrent(token.CloseParen)

	if p.peek().typ == token.BlockBegin {
		declare.Statements = p.parseBlock()
	} else {
		p.expect(token.StatementEnd)
	}
	return declare
}

func (p *Parser) parseDeclareElement() string {
	element := ""
	p.expect(token.Identifier)
	element += p.current.val

	p.expect(token.AssignmentOperator)
	element += p.current.val

	p.parseNextExpression()
	element += p.current.val
	return element
}
<|endoftext|>


<commit_before>// Tabix queries for go
package bix

import (
	"bufio"
	"compress/gzip"
	"io"
	"log"
	"os"
	"strconv"
	"strings"

	"github.com/biogo/hts/bgzf"
	"github.com/biogo/hts/bgzf/index"
	"github.com/biogo/hts/tabix"
	"github.com/brentp/irelate/interfaces"
	"github.com/brentp/irelate/parsers"
	"github.com/brentp/vcfgo"
)

const (
	VCF = iota
	BED
	GENERIC
)

type location struct {
	chrom string
	start int
	end   int
}

func (s location) RefName() string {
	return s.chrom
}
func (s location) Start() int {
	return s.start
}
func (s location) End() int {
	return s.end
}

// Bix provides read access to tabix files.
type Bix struct {
	*tabix.Index
	bgzf   *bgzf.Reader
	path   string
	Header string

	vReader *vcfgo.Reader
}

// New returns a &Bix
func New(path string, workers ...int) (*Bix, error) {
	f, err := os.Open(path + ".tbi")
	if err != nil {
		return nil, err
	}
	defer f.Close()

	gz, err := gzip.NewReader(f)
	if err != nil {
		return nil, err
	}
	defer gz.Close()

	idx, err := tabix.ReadTabix(gz)
	if err != nil {
		return nil, err
	}
	n := 1
	if len(workers) > 0 {
		n = workers[0]
	}

	b, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	bgz, err := bgzf.NewReader(b, n)
	bgz.Blocked = false
	if err != nil {
		return nil, err
	}

	/*
		c := cache.NewFIFO(4)
		bgz.SetCache(c)
	*/

	buf := bufio.NewReaderSize(bgz, 16384/2)
	h := make([]string, 0)
	tbx := &Bix{bgzf: bgz, path: path}

	l, err := buf.ReadString('\n')
	if err != nil {
		return tbx, err
	}

	for i := 0; i < int(idx.Skip) || rune(l[0]) == idx.MetaChar; i++ {
		h = append(h, l)
		l, err = buf.ReadString('\n')
		if err != nil {
			return tbx, err
		}
	}
	tbx.Header = strings.Join(h, "")

	if len(h) > 0 && strings.HasSuffix(tbx.path, ".vcf.gz") {
		rdr := strings.NewReader(tbx.Header)
		var err error
		tbx.vReader, err = vcfgo.NewReader(rdr, true)
		if err != nil {
			return nil, err
		}
	}

	tbx.Index = idx
	return tbx, nil
}

// bixReader is return from Bix.Query() it meets the io.Reader interface
type bixReader struct {
	startCol int
	endCol   int
	maxCol   int
	add      int

	start int
	end   int

	rdr   *bufio.Reader
	isVCF bool

	buf []byte
}

func newReader(tbx *Bix, cr *index.ChunkReader, start, end int) (io.Reader, error) {
	r := &bixReader{}
	r.startCol = int(tbx.BeginColumn - 1)
	r.endCol = int(tbx.EndColumn - 1)
	r.maxCol = r.endCol
	if r.startCol > r.endCol {
		r.maxCol = r.startCol
	}
	r.start = start
	r.end = end
	r.maxCol += 1
	if !tbx.ZeroBased {
		r.add = -1
	}
	r.rdr = bufio.NewReader(cr)
	r.buf = make([]byte, 0)
	r.isVCF = strings.HasSuffix(tbx.path, ".vcf.gz")
	if r.isVCF {
		r.maxCol = 9
	}

	return r, nil
}

func (r *bixReader) inBounds(line string) (bool, error, []string) {

	var readErr error
	toks := strings.SplitN(line, "\t", r.maxCol+1)

	s, err := strconv.Atoi(toks[r.startCol])
	if err != nil {
		return false, err, toks
	}

	pos := s + r.add
	if pos >= r.end {
		return false, io.EOF, toks
	}

	if r.endCol != -1 {
		e, err := strconv.Atoi(toks[r.endCol])
		if err != nil {
			return false, err, toks
		}
		if e < r.start {
			return false, readErr, toks
		}
	} else if r.isVCF {
		alt := strings.Split(toks[4], ",")
		lref := len(toks[3])
		//log.Println(maxEnd, r.start, lref, toks[3], toks[4])
		if r.start >= pos+lref {
			for _, a := range alt {
				if a[0] != '<' {
					e := pos + lref
					if e > r.start {
						//log.Println("true")
						return true, readErr, toks
					}
				} else if strings.HasPrefix(a, "<DEL") || strings.HasPrefix(a, "<DUP") || strings.HasPrefix(a, "<INV") || strings.HasPrefix(a, "<CN") {
					info := toks[7]
					if idx := strings.Index(info, ";END="); idx != -1 {
						v := info[idx+5 : idx+5+strings.Index(info[idx+5:], ";")]
						e, err := strconv.Atoi(v)
						if err != nil {
							return false, err, toks
						}
						if e > r.start {
							return true, readErr, toks
						}
					} else {
						log.Println("no end")
					}
				}
			}
		} else {
			return true, readErr, toks
		}
		return false, readErr, toks
	}
	return false, readErr, toks

}

func (tbx *Bix) Get(q interfaces.IPosition) []interfaces.IPosition {
	overlaps := make([]interfaces.IPosition, 0)
	chunkReader, err := tbx.chunkedReader(location{q.Chrom(), int(q.Start()), int(q.End())})
	if err != nil {
		return overlaps
	}
	br := chunkReader.(*bixReader)
	isVCF := tbx.vReader != nil
	isBED := tbx.Index.NameColumn == 1 && tbx.Index.BeginColumn == 2 && tbx.Index.EndColumn == 3
	for {
		line, err := br.rdr.ReadString('\n')

		if err != nil && err != io.EOF {
			log.Println(err)
			break
		}
		if len(line) == 0 || (err == io.EOF && line[len(line)-1] != '\n') {
			break
		}
		if err != nil {
			log.Println(err)
		}
		in, rerr, toks := br.inBounds(line)
		if !in {
			if rerr == io.EOF {
				break
			}
			continue
		}

		if isVCF {
			v := tbx.vReader.Parse(toks)
			if v != nil {
				overlaps = append(overlaps, v)
			}
		} else if isBED {
			v, e := parsers.IntervalFromBedLine(line)
			if e != nil {
				overlaps = append(overlaps, v)
			}
		} else {

			g, e := newgeneric(toks, int(tbx.Index.NameColumn-1), br.startCol, br.endCol, tbx.Index.ZeroBased)
			if e != nil {
				overlaps = append(overlaps, g)
			}

		}
		if err == io.EOF || rerr == io.EOF {
			break
		}
	}
	return overlaps

}

// return an interval using the info from the tabix index
func newgeneric(fields []string, chromCol int, startCol int, endCol int, zeroBased bool) (*parsers.Interval, error) {
	s, err := strconv.Atoi(fields[startCol])
	if err != nil {
		return nil, err
	}
	if !zeroBased {
		s -= 1
	}
	e, err := strconv.Atoi(fields[endCol])
	if err != nil {
		return nil, err
	}

	return parsers.NewInterval(fields[chromCol], uint32(s), uint32(e), fields, uint32(0), nil), nil
}

// Read from a BixReader (will contain only overlapping intervals).
func (r *bixReader) Read(p []byte) (int, error) {
	var readErr error
	var line string

	for len(r.buf) < len(p) {
		line, readErr = r.rdr.ReadString('\n')
		if readErr == io.EOF {
			if len(line) == 0 {
				break
			}
		} else if readErr != nil {
			log.Println(readErr)
			break
		}
		var in bool
		var err error
		if in, err, _ = r.inBounds(line); in {
			r.buf = append(r.buf, line...)
		}
		if err == io.EOF {
			readErr = err
			break
		} else if err != nil {
			log.Println(err)
		}
	}
	if len(r.buf) >= len(p) {
		copy(p, r.buf[:len(p)])
		r.buf = r.buf[len(p):]
		if len(r.buf) > 0 && readErr == io.EOF {
			readErr = nil
		}
		return len(p), readErr
	}
	copy(p, r.buf)
	l := len(r.buf)
	r.buf = r.buf[:0]
	return l, readErr
}

func (tbx *Bix) chunkedReader(l location) (io.Reader, error) {
	chunks, err := tbx.Chunks(l)
	if err != nil {
		return nil, err
	}

	chunkReader, err := index.NewChunkReader(tbx.bgzf, chunks)
	if err != nil {
		return nil, err
	}
	rdr, err := newReader(tbx, chunkReader, l.start, l.end)
	if err != nil {
		return nil, err
	}
	return rdr, nil
}

// Query a Bix struct with genomic coordinates. Returns an io.Reader.
func (tbx *Bix) Query(chrom string, start int, end int, printHeader bool) (io.Reader, error) {

	rdr, err := tbx.chunkedReader(location{chrom: chrom, start: start, end: end})
	if err != nil {
		return nil, err
	}
	if printHeader {
		rdr.(*bixReader).buf = []byte(tbx.Header)
	}
	return rdr, err
}

// Close closes the files associate with a Bix struct.
func (tbx *Bix) Close() {
	tbx.bgzf.Close()
}

func (tbx *Bix) AddInfoToHeader(id, number, vtype, desc string) {
	if tbx.vReader == nil {
		return
	}
	tbx.vReader.AddInfoToHeader(id, number, vtype, desc)
}
<commit_msg>add caching so we don't parse intervals multiple times.<commit_after>// Tabix queries for go
package bix

import (
	"bufio"
	"compress/gzip"
	"io"
	"log"
	"os"
	"strconv"
	"strings"

	"github.com/biogo/hts/bgzf"
	"github.com/biogo/hts/bgzf/index"
	"github.com/biogo/hts/tabix"
	"github.com/brentp/irelate/interfaces"
	"github.com/brentp/irelate/parsers"
	"github.com/brentp/vcfgo"
)

const (
	VCF = iota
	BED
	GENERIC
)

type location struct {
	chrom string
	start int
	end   int
}

func (s location) RefName() string {
	return s.chrom
}
func (s location) Start() int {
	return s.start
}
func (s location) End() int {
	return s.end
}

// Bix provides read access to tabix files.
type Bix struct {
	*tabix.Index
	bgzf   *bgzf.Reader
	path   string
	Header string

	vReader   *vcfgo.Reader
	lastChunk *bgzf.Chunk
	cache     []interfaces.IPosition

	UseCache bool
}

// New returns a &Bix
func New(path string, workers ...int) (*Bix, error) {
	f, err := os.Open(path + ".tbi")
	if err != nil {
		return nil, err
	}
	defer f.Close()

	gz, err := gzip.NewReader(f)
	if err != nil {
		return nil, err
	}
	defer gz.Close()

	idx, err := tabix.ReadTabix(gz)
	if err != nil {
		return nil, err
	}
	n := 1
	if len(workers) > 0 {
		n = workers[0]
	}

	b, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	bgz, err := bgzf.NewReader(b, n)
	bgz.Blocked = false
	if err != nil {
		return nil, err
	}

	/*
		c := cache.NewFIFO(4)
		bgz.SetCache(c)
	*/

	buf := bufio.NewReaderSize(bgz, 16384/2)
	h := make([]string, 0)
	tbx := &Bix{bgzf: bgz, path: path, cache: make([]interfaces.IPosition, 0, 4000),
		UseCache: false}

	l, err := buf.ReadString('\n')
	if err != nil {
		return tbx, err
	}

	for i := 0; i < int(idx.Skip) || rune(l[0]) == idx.MetaChar; i++ {
		h = append(h, l)
		l, err = buf.ReadString('\n')
		if err != nil {
			return tbx, err
		}
	}
	tbx.Header = strings.Join(h, "")

	if len(h) > 0 && strings.HasSuffix(tbx.path, ".vcf.gz") {
		rdr := strings.NewReader(tbx.Header)
		var err error
		tbx.vReader, err = vcfgo.NewReader(rdr, true)
		if err != nil {
			return nil, err
		}
	}

	tbx.Index = idx
	return tbx, nil
}

// bixReader is return from Bix.Query() it meets the io.Reader interface
type bixReader struct {
	startCol int
	endCol   int
	maxCol   int
	add      int

	start int
	end   int

	rdr   *bufio.Reader
	isVCF bool

	buf []byte
}

func newReader(tbx *Bix, cr *index.ChunkReader, start, end int) (io.Reader, error) {
	r := &bixReader{}
	r.startCol = int(tbx.BeginColumn - 1)
	r.endCol = int(tbx.EndColumn - 1)
	r.maxCol = r.endCol
	if r.startCol > r.endCol {
		r.maxCol = r.startCol
	}
	r.start = start
	r.end = end
	r.maxCol += 1
	if !tbx.ZeroBased {
		r.add = -1
	}
	r.rdr = bufio.NewReader(cr)
	r.buf = make([]byte, 0)
	r.isVCF = strings.HasSuffix(tbx.path, ".vcf.gz")
	if r.isVCF {
		r.maxCol = 9
	}

	return r, nil
}

func (r *bixReader) inBounds(line string) (bool, error, []string) {

	var readErr error
	toks := strings.SplitN(line, "\t", r.maxCol+1)

	s, err := strconv.Atoi(toks[r.startCol])
	if err != nil {
		return false, err, toks
	}

	pos := s + r.add
	if pos >= r.end {
		return false, io.EOF, toks
	}

	if r.endCol != -1 {
		e, err := strconv.Atoi(toks[r.endCol])
		if err != nil {
			return false, err, toks
		}
		if e < r.start {
			return false, readErr, toks
		}
	} else if r.isVCF {
		alt := strings.Split(toks[4], ",")
		lref := len(toks[3])
		//log.Println(maxEnd, r.start, lref, toks[3], toks[4])
		if r.start >= pos+lref {
			for _, a := range alt {
				if a[0] != '<' {
					e := pos + lref
					if e > r.start {
						return true, readErr, toks
					}
				} else if strings.HasPrefix(a, "<DEL") || strings.HasPrefix(a, "<DUP") || strings.HasPrefix(a, "<INV") || strings.HasPrefix(a, "<CN") {
					info := toks[7]
					if idx := strings.Index(info, ";END="); idx != -1 {
						v := info[idx+5 : idx+5+strings.Index(info[idx+5:], ";")]
						e, err := strconv.Atoi(v)
						if err != nil {
							return false, err, toks
						}
						if e > r.start {
							return true, readErr, toks
						}
					} else {
						log.Println("no end")
					}
				}
			}
		} else {
			return true, readErr, toks
		}
		return false, readErr, toks
	}
	return false, readErr, toks

}

func (tbx *Bix) fillCache(br *bixReader) {
	if len(tbx.cache) != 0 {
		return
	}
	for {
		line, err := br.rdr.ReadString('\n')
		if err != nil && err != io.EOF {
			log.Println(err)
			return
		}
		if len(line) == 0 || (err == io.EOF && line[len(line)-1] != '\n') {
			return
		}
		toks := strings.SplitN(line, "\t", br.maxCol)
		ip := tbx.toPosition(toks)
		tbx.cache = append(tbx.cache, ip)
	}

}

func (tbx *Bix) Get(q interfaces.IPosition) []interfaces.IPosition {
	overlaps := make([]interfaces.IPosition, 0)
	chunkReader, err := tbx.chunkedReader(location{q.Chrom(), int(q.Start()), int(q.End())})
	if err != nil {
		return overlaps
	}
	br := chunkReader.(*bixReader)

	var k, skip, hit int
	for {
		if tbx.UseCache {
			if len(tbx.cache) == 0 {
				tbx.fillCache(br)
			}
			if k >= len(tbx.cache) {
				break
			}
			v := tbx.cache[k]
			if v != nil {
				//log.Printf("hitting cache: %s:%d-%d %s:%d-%d", q.Chrom(), q.Start(), q.End(), v.Chrom(), v.Start(), v.End())
				if interfaces.OverlapsPosition(v, q) {
					overlaps = append(overlaps, v)
				} else if v.Start() >= q.End() {
					break
				}
			}
			k += 1
		} else {
			line, err := br.rdr.ReadString('\n')

			if err != nil && err != io.EOF {
				log.Println(err)
				break
			}
			if len(line) == 0 || (err == io.EOF && line[len(line)-1] != '\n') {
				break
			}
			k += 1
			if err != nil {
				log.Println(err)
			}
			in, rerr, toks := br.inBounds(line)

			if !in {
				if rerr == io.EOF {
					break
				}
				continue
			}
			ip := tbx.toPosition(toks)
			if ip != nil {
				overlaps = append(overlaps, ip)
			}
			if err == io.EOF || rerr == io.EOF {
				break
			}
		}
	}
	//log.Println(fmt.Sprintf("total: %d, hits: %d, misses: %d", k, hit, skip))
	_ = skip
	_ = hit
	return overlaps

}

func (tbx *Bix) toPosition(toks []string) interfaces.IPosition {
	isVCF := tbx.vReader != nil

	if isVCF {
		v := tbx.vReader.Parse(toks)
		return v
	} else {

		g, _ := newgeneric(toks, int(tbx.Index.NameColumn-1), int(tbx.Index.BeginColumn-1),
			int(tbx.Index.EndColumn-1), tbx.Index.ZeroBased)
		return g
	}
}

// return an interval using the info from the tabix index
func newgeneric(fields []string, chromCol int, startCol int, endCol int, zeroBased bool) (*parsers.Interval, error) {
	s, err := strconv.Atoi(fields[startCol])
	if err != nil {
		return nil, err
	}
	if !zeroBased {
		s -= 1
	}
	e, err := strconv.Atoi(fields[endCol])
	if err != nil {
		return nil, err
	}

	return parsers.NewInterval(fields[chromCol], uint32(s), uint32(e), fields, uint32(0), nil), nil
}

// Read from a BixReader (will contain only overlapping intervals).
func (r *bixReader) Read(p []byte) (int, error) {
	var readErr error
	var line string

	for len(r.buf) < len(p) {
		line, readErr = r.rdr.ReadString('\n')
		if readErr == io.EOF {
			if len(line) == 0 {
				break
			}
		} else if readErr != nil {
			log.Println(readErr)
			break
		}
		var in bool
		var err error
		if in, err, _ = r.inBounds(line); in {
			r.buf = append(r.buf, line...)
		}
		if err == io.EOF {
			readErr = err
			break
		} else if err != nil {
			log.Println(err)
		}
	}
	if len(r.buf) >= len(p) {
		copy(p, r.buf[:len(p)])
		r.buf = r.buf[len(p):]
		if len(r.buf) > 0 && readErr == io.EOF {
			readErr = nil
		}
		return len(p), readErr
	}
	copy(p, r.buf)
	l := len(r.buf)
	r.buf = r.buf[:0]
	return l, readErr
}

func (tbx *Bix) chunkedReader(l location) (io.Reader, error) {
	chunks, err := tbx.Chunks(l)
	if err != nil {
		return nil, err
	}
	if tbx.UseCache && len(chunks) > 0 && (tbx.lastChunk == nil || (len(chunks) > 0 && (tbx.lastChunk.Begin.File != chunks[0].Begin.File || tbx.lastChunk.Begin.Block != chunks[0].Begin.Block))) {
		(*tbx).lastChunk = &chunks[0]
		tbx.cache = tbx.cache[:0]
	}

	chunkReader, err := index.NewChunkReader(tbx.bgzf, chunks)
	if err != nil {
		return nil, err
	}
	rdr, err := newReader(tbx, chunkReader, l.start, l.end)
	if err != nil {
		return nil, err
	}
	return rdr, nil
}

// Query a Bix struct with genomic coordinates. Returns an io.Reader.
func (tbx *Bix) Query(chrom string, start int, end int, printHeader bool) (io.Reader, error) {

	rdr, err := (*tbx).chunkedReader(location{chrom: chrom, start: start, end: end})
	if err != nil {
		return nil, err
	}
	if printHeader {
		rdr.(*bixReader).buf = []byte(tbx.Header)
	}
	return rdr, err
}

// Close closes the files associate with a Bix struct.
func (tbx *Bix) Close() {
	tbx.bgzf.Close()
}

func (tbx *Bix) AddInfoToHeader(id, number, vtype, desc string) {
	if tbx.vReader == nil {
		return
	}
	tbx.vReader.AddInfoToHeader(id, number, vtype, desc)
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"fmt"
	"log"
	"math/rand"
	"net"
	"net/textproto"
	"strings"
	"time"
)

func (bot *Bot) reduceJoins() {
	bot.joins--
}

// Bot struct for main config
type Bot struct {
	server          string
	groupserver     string
	port            string
	groupport       string
	oauth           string
	nick            string
	inconn          net.Conn
	mainconn        net.Conn
	connlist        []Connection
	connactive      bool
	groupconn       net.Conn
	groupconnactive bool
	joins           int
	toJoin          []string
}

// NewBot main config
func NewBot() *Bot {
	return &Bot{
		server:          "irc.chat.twitch.tv",
		groupserver:     "group.tmi.twitch.tv",
		port:            "80",
		groupport:       "443",
		oauth:           "",
		nick:            "",
		inconn:          nil,
		mainconn:        nil,
		connlist:        make([]Connection, 0),
		connactive:      false,
		groupconn:       nil,
		groupconnactive: false,
		joins:           0,
	}
}

func (bot *Bot) join(channel string) {
	for !bot.connactive {
		log.Printf("chat connection not active yet")
		time.Sleep(time.Second)
	}

	if bot.joins < 45 {
		fmt.Fprintf(bot.mainconn, "JOIN %s\r\n", channel)
		log.Printf("[chat] joined %s", channel)
		bot.joins++
		time.AfterFunc(10*time.Second, bot.reduceJoins)
	} else {
		log.Printf("[chat] in queue to join %s", channel)
		time.Sleep(time.Second)
		bot.join(channel)
	}
}

// ListenToConnection listen
func (bot *Bot) ListenToConnection(conn net.Conn) {
	reader := bufio.NewReader(conn)
	tp := textproto.NewReader(reader)
	for {
		line, err := tp.ReadLine()
		if err != nil {
			log.Printf("Error reading from chat connection: %s", err)
			bot.CreateConnection()
			break // break loop on errors
		}
		if strings.Contains(line, "tmi.twitch.tv 001") {
			bot.connactive = true
		}
		if strings.Contains(line, "PING ") {
			fmt.Fprintf(conn, "PONG tmi.twitch.tv\r\n")
		}
		bot.inconn.Write([]byte(line))
	}
}

// ListenToGroupConnection validate connection is running and listen to it
func (bot *Bot) ListenToGroupConnection(conn net.Conn) {
	reader := bufio.NewReader(conn)
	tp := textproto.NewReader(reader)
	for {
		line, err := tp.ReadLine()
		if err != nil {
			log.Printf("Error reading from group connection: %s", err)
			bot.CreateGroupConnection()
			break
		}
		if strings.Contains(line, "tmi.twitch.tv 001") {
			bot.groupconnactive = true
		}
		if strings.Contains(line, "PING ") {
			fmt.Fprintf(conn, "PONG tmi.twitch.tv\r\n")
		}
		bot.inconn.Write([]byte(line + "\r\n"))
	}
}

// CreateConnection Add a new connection
func (bot *Bot) CreateConnection() {
	conn, err := net.Dial("tcp", bot.server+":"+bot.port)
	if err != nil {
		log.Println("unable to connect to chat IRC server ", err)
		bot.CreateConnection()
		return
	}
	fmt.Fprintf(conn, "PASS %s\r\n", bot.oauth)
	fmt.Fprintf(conn, "USER %s\r\n", bot.nick)
	fmt.Fprintf(conn, "NICK %s\r\n", bot.nick)
	fmt.Fprintf(conn, "CAP REQ :twitch.tv/tags\r\n")     // enable ircv3 tags
	fmt.Fprintf(conn, "CAP REQ :twitch.tv/commands\r\n") // enable roomstate and such
	log.Printf("new connection to chat IRC server %s (%s)\n", bot.server, conn.RemoteAddr())

	connnection := NewConnection(conn)
	bot.connlist = append(bot.connlist, connnection)

	if len(bot.connlist) == 1 {
		bot.mainconn = conn
	}

	go bot.ListenToConnection(conn)

}

// CreateGroupConnection creates connection to recevie and send whispers
func (bot *Bot) CreateGroupConnection() {
	conn, err := net.Dial("tcp", bot.groupserver+":"+bot.groupport)
	if err != nil {
		log.Println("unable to connect to group IRC server ", err)
		bot.CreateGroupConnection()
		return
	}
	fmt.Fprintf(conn, "PASS %s\r\n", bot.oauth)
	fmt.Fprintf(conn, "USER %s\r\n", bot.nick)
	fmt.Fprintf(conn, "NICK %s\r\n", bot.nick)
	fmt.Fprintf(conn, "CAP REQ :twitch.tv/tags\r\n")     // enable ircv3 tags
	fmt.Fprintf(conn, "CAP REQ :twitch.tv/commands\r\n") // enable roomstate and such
	log.Printf("new connection to group IRC server %s (%s)\n", bot.groupserver, conn.RemoteAddr())

	bot.groupconn = conn

	go bot.ListenToGroupConnection(conn)
}

// shuffle simple array shuffle functino
func shuffle(a []Connection) {
	for i := range a {
		j := rand.Intn(i + 1)
		a[i], a[j] = a[j], a[i]
	}
}

// Message to send a message
func (bot *Bot) Message(message string) {
	message = strings.TrimSpace(message)
	for !bot.connactive {
		// wait for connection to become active
	}
	shuffle(bot.connlist)
	for i := 0; i < len(bot.connlist); i++ {
		if bot.connlist[i].messages < 90 {
			bot.connlist[i].Message(message)
			return
		}
	}
	// open new connection when others too full
	log.Printf("opened new connection, total: %d", len(bot.connlist))
	bot.CreateConnection()
	bot.Message(message)
}

// Whisper to send whispers
func (bot *Bot) Whisper(message string) {
	for !bot.groupconnactive {
		// wait for connection to become active
	}
	fmt.Fprintf(bot.groupconn, "PRIVMSG #jtv :"+message+"\r\n")
	log.Printf(message)
}
<commit_msg>using fmt package to send messages over connections and readded line endings<commit_after>package main

import (
	"bufio"
	"fmt"
	"log"
	"math/rand"
	"net"
	"net/textproto"
	"strings"
	"time"
)

func (bot *Bot) reduceJoins() {
	bot.joins--
}

// Bot struct for main config
type Bot struct {
	server          string
	groupserver     string
	port            string
	groupport       string
	oauth           string
	nick            string
	inconn          net.Conn
	mainconn        net.Conn
	connlist        []Connection
	connactive      bool
	groupconn       net.Conn
	groupconnactive bool
	joins           int
	toJoin          []string
}

// NewBot main config
func NewBot() *Bot {
	return &Bot{
		server:          "irc.chat.twitch.tv",
		groupserver:     "group.tmi.twitch.tv",
		port:            "80",
		groupport:       "443",
		oauth:           "",
		nick:            "",
		inconn:          nil,
		mainconn:        nil,
		connlist:        make([]Connection, 0),
		connactive:      false,
		groupconn:       nil,
		groupconnactive: false,
		joins:           0,
	}
}

func (bot *Bot) join(channel string) {
	for !bot.connactive {
		log.Printf("chat connection not active yet")
		time.Sleep(time.Second)
	}

	if bot.joins < 45 {
		fmt.Fprintf(bot.mainconn, "JOIN %s\r\n", channel)
		log.Printf("[chat] joined %s", channel)
		bot.joins++
		time.AfterFunc(10*time.Second, bot.reduceJoins)
	} else {
		log.Printf("[chat] in queue to join %s", channel)
		time.Sleep(time.Second)
		bot.join(channel)
	}
}

// ListenToConnection listen
func (bot *Bot) ListenToConnection(conn net.Conn) {
	reader := bufio.NewReader(conn)
	tp := textproto.NewReader(reader)
	for {
		line, err := tp.ReadLine()
		if err != nil {
			log.Printf("Error reading from chat connection: %s", err)
			bot.CreateConnection()
			break // break loop on errors
		}
		if strings.Contains(line, "tmi.twitch.tv 001") {
			bot.connactive = true
		}
		if strings.Contains(line, "PING ") {
			fmt.Fprintf(conn, "PONG tmi.twitch.tv\r\n")
		}
		fmt.Fprintf(bot.inconn, line+"\r\n")
	}
}

// ListenToGroupConnection validate connection is running and listen to it
func (bot *Bot) ListenToGroupConnection(conn net.Conn) {
	reader := bufio.NewReader(conn)
	tp := textproto.NewReader(reader)
	for {
		line, err := tp.ReadLine()
		if err != nil {
			log.Printf("Error reading from group connection: %s", err)
			bot.CreateGroupConnection()
			break
		}
		if strings.Contains(line, "tmi.twitch.tv 001") {
			bot.groupconnactive = true
		}
		if strings.Contains(line, "PING ") {
			fmt.Fprintf(conn, "PONG tmi.twitch.tv\r\n")
		}
		fmt.Fprintf(bot.inconn, line+"\r\n")
	}
}

// CreateConnection Add a new connection
func (bot *Bot) CreateConnection() {
	conn, err := net.Dial("tcp", bot.server+":"+bot.port)
	if err != nil {
		log.Println("unable to connect to chat IRC server ", err)
		bot.CreateConnection()
		return
	}
	fmt.Fprintf(conn, "PASS %s\r\n", bot.oauth)
	fmt.Fprintf(conn, "USER %s\r\n", bot.nick)
	fmt.Fprintf(conn, "NICK %s\r\n", bot.nick)
	fmt.Fprintf(conn, "CAP REQ :twitch.tv/tags\r\n")     // enable ircv3 tags
	fmt.Fprintf(conn, "CAP REQ :twitch.tv/commands\r\n") // enable roomstate and such
	log.Printf("new connection to chat IRC server %s (%s)\n", bot.server, conn.RemoteAddr())

	connnection := NewConnection(conn)
	bot.connlist = append(bot.connlist, connnection)

	if len(bot.connlist) == 1 {
		bot.mainconn = conn
	}

	go bot.ListenToConnection(conn)

}

// CreateGroupConnection creates connection to recevie and send whispers
func (bot *Bot) CreateGroupConnection() {
	conn, err := net.Dial("tcp", bot.groupserver+":"+bot.groupport)
	if err != nil {
		log.Println("unable to connect to group IRC server ", err)
		bot.CreateGroupConnection()
		return
	}
	fmt.Fprintf(conn, "PASS %s\r\n", bot.oauth)
	fmt.Fprintf(conn, "USER %s\r\n", bot.nick)
	fmt.Fprintf(conn, "NICK %s\r\n", bot.nick)
	fmt.Fprintf(conn, "CAP REQ :twitch.tv/tags\r\n")     // enable ircv3 tags
	fmt.Fprintf(conn, "CAP REQ :twitch.tv/commands\r\n") // enable roomstate and such
	log.Printf("new connection to group IRC server %s (%s)\n", bot.groupserver, conn.RemoteAddr())

	bot.groupconn = conn

	go bot.ListenToGroupConnection(conn)
}

// shuffle simple array shuffle functino
func shuffle(a []Connection) {
	for i := range a {
		j := rand.Intn(i + 1)
		a[i], a[j] = a[j], a[i]
	}
}

// Message to send a message
func (bot *Bot) Message(message string) {
	message = strings.TrimSpace(message)
	for !bot.connactive {
		// wait for connection to become active
	}
	shuffle(bot.connlist)
	for i := 0; i < len(bot.connlist); i++ {
		if bot.connlist[i].messages < 90 {
			bot.connlist[i].Message(message)
			return
		}
	}
	// open new connection when others too full
	log.Printf("opened new connection, total: %d", len(bot.connlist))
	bot.CreateConnection()
	bot.Message(message)
}

// Whisper to send whispers
func (bot *Bot) Whisper(message string) {
	for !bot.groupconnactive {
		// wait for connection to become active
	}
	fmt.Fprintf(bot.groupconn, "PRIVMSG #jtv :"+message+"\r\n")
	log.Printf(message)
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/golang/protobuf/proto"
	"flag"
	"github.com/thoj/go-ircevent"
	"io/ioutil"
	"log"
	"net/http"
)

func logErrors(c chan error) {
	var err error

	for err = range c {
		log.Print("IRC error: ", err)
	}
}

func launchhttpserver(bindto string) {
	var err error
	err = http.ListenAndServe(bindto, nil)
	if err != nil {
		log.Fatal("Error starting http server: ", err)
	}
}

func main() {
	var myircbot *irc.Connection
	var channelname string
	var err error
	var extractor *URLTitleExtractor
	var github *GitHubAdapter
	var configpath string // path of config file
	var configdata []byte
	var config IRCBotConfig
	var msgbuffer *MessageBuffer

	flag.StringVar(&configpath, "config", "", "Specify the path to the configuration file.")
	flag.Parse()

	configdata, err = ioutil.ReadFile(configpath)
	if err != nil {
		log.Fatal("Error reading config file: ", err)
	}

	err = proto.Unmarshal(configdata, &config)
	if err != nil {
		err = proto.UnmarshalText(string(configdata), &config)
	}
	if err != nil {
		log.Fatal("Error parsing config: ", err)
	}

	myircbot = irc.IRC(config.GetBotName(), config.GetBotName())
	if myircbot == nil {
                log.Fatal("Error calling IRC(nick, user string) *Connection. Nick or User empty.")
        }
	go logErrors(myircbot.ErrorChan()) // collect irc errors and log

        // 1: RPL_WELCOME "Welcome to the Internet Relay Network
        // <nick>!<user>@<host>"
        myircbot.AddCallback("001", func(e *irc.Event) {
                //Join all channels.
                for _, channelname = range config.GetIrcChannel() {
                        myircbot.Join(channelname)
                }
        })

	if err = myircbot.Connect(config.GetServerAddress()); err != nil {
		log.Fatal("Error connecting to server: ", err)
	}
	msgbuffer = NewMessageBuffer(myircbot, config.GetSendQueueLength())

	extractor = &URLTitleExtractor{
		msgbuffer: msgbuffer,
	}
	github = NewGitHubAdapter(msgbuffer, config.GetGithub())

	//Event handling
	myircbot.AddCallback("PRIVMSG", logprivmsgs)
	myircbot.AddCallback("PRIVMSG", extractor.WriteURLTitle)

	// Write GitHub status messages to the specified channels
	http.Handle("/github", github)

	// Start http server in a new thread
	go launchhttpserver(config.GetHttpServerAddress())

	myircbot.Loop()
}
<commit_msg>Allow passing the entire config as --config instead of a file path.<commit_after>package main

import (
	"github.com/golang/protobuf/proto"
	"flag"
	"github.com/thoj/go-ircevent"
	"io/ioutil"
	"log"
	"net/http"
)

func logErrors(c chan error) {
	var err error

	for err = range c {
		log.Print("IRC error: ", err)
	}
}

func launchhttpserver(bindto string) {
	var err error
	err = http.ListenAndServe(bindto, nil)
	if err != nil {
		log.Fatal("Error starting http server: ", err)
	}
}

func main() {
	var myircbot *irc.Connection
	var channelname string
	var err error
	var extractor *URLTitleExtractor
	var github *GitHubAdapter
	var configpath string // path of config file
	var configdata []byte
	var config IRCBotConfig
	var msgbuffer *MessageBuffer

	flag.StringVar(&configpath, "config", "", "Specify the path to the configuration file.")
	flag.Parse()

	configdata, err = ioutil.ReadFile(configpath)
	if err == nil {
		err = proto.Unmarshal(configdata, &config)
		if err != nil {
			err = proto.UnmarshalText(string(configdata), &config)
		}
		if err != nil {
			log.Fatal("Error parsing config: ", err)
		}
	} else {
		var nerr = proto.UnmarshalText(configpath, &config)
		if nerr != nil {
			log.Print("Error parsing config: ", nerr)
			log.Fatal("Error reading config file: ", err)
		}
	}

	myircbot = irc.IRC(config.GetBotName(), config.GetBotName())
	if myircbot == nil {
                log.Fatal("Error calling IRC(nick, user string) *Connection. Nick or User empty.")
        }
	go logErrors(myircbot.ErrorChan()) // collect irc errors and log

        // 1: RPL_WELCOME "Welcome to the Internet Relay Network
        // <nick>!<user>@<host>"
        myircbot.AddCallback("001", func(e *irc.Event) {
                //Join all channels.
                for _, channelname = range config.GetIrcChannel() {
                        myircbot.Join(channelname)
                }
        })

	if err = myircbot.Connect(config.GetServerAddress()); err != nil {
		log.Fatal("Error connecting to server: ", err)
	}
	msgbuffer = NewMessageBuffer(myircbot, config.GetSendQueueLength())

	extractor = &URLTitleExtractor{
		msgbuffer: msgbuffer,
	}
	github = NewGitHubAdapter(msgbuffer, config.GetGithub())

	//Event handling
	myircbot.AddCallback("PRIVMSG", logprivmsgs)
	myircbot.AddCallback("PRIVMSG", extractor.WriteURLTitle)

	// Write GitHub status messages to the specified channels
	http.Handle("/github", github)

	// Start http server in a new thread
	go launchhttpserver(config.GetHttpServerAddress())

	myircbot.Loop()
}
<|endoftext|>


<commit_before>// Copyright (C) 2017 Google Inc.
//
// 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 main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"path/filepath"

	"github.com/google/gapid/core/app"
	"github.com/google/gapid/core/app/flags"
	"github.com/google/gapid/core/event/task"
	"github.com/google/gapid/core/log"
	"github.com/google/gapid/gapis/client"
	"github.com/google/gapid/gapis/service"
	"github.com/google/gapid/gapis/service/path"
)

type stateVerb struct{ StateFlags }

func init() {
	verb := &stateVerb{
		StateFlags{
			At:     flags.U64Slice{},
			Depth:  -1,
			Filter: flags.StringSlice{},
		},
	}

	app.AddVerb(&app.Verb{
		Name:      "state",
		ShortHelp: "Prints the state tree for a point in a .gfxtrace file",
		Action:    verb,
	})
}

func (verb *stateVerb) Run(ctx context.Context, flags flag.FlagSet) error {
	if flags.NArg() != 1 {
		app.Usage(ctx, "Exactly one gfx trace file expected, got %d", flags.NArg())
		return nil
	}

	client, err := getGapis(ctx, verb.Gapis, verb.Gapir)
	if err != nil {
		return log.Err(ctx, err, "Failed to connect to the GAPIS server")
	}
	defer client.Close()

	filepath, err := filepath.Abs(flags.Arg(0))
	ctx = log.V{"filepath": filepath}.Bind(ctx)
	if err != nil {
		return log.Err(ctx, err, "Could not find capture file")
	}

	c, err := client.LoadCapture(ctx, filepath)
	if err != nil {
		return log.Err(ctx, err, "Failed to load the capture file")
	}

	if len(verb.At) == 0 {
		boxedCapture, err := client.Get(ctx, c.Path())
		if err != nil {
			return log.Err(ctx, err, "Failed to load the capture")
		}
		verb.At = []uint64{uint64(boxedCapture.(*service.Capture).NumCommands) - 1}
	}

	boxedTree, err := client.Get(ctx, c.Command(uint64(verb.At[0]), verb.At[1:]...).StateAfter().Tree().Path())
	if err != nil {
		return log.Err(ctx, err, "Failed to load the command tree")
	}

	tree := boxedTree.(*service.StateTree)

	return traverseStateTree(ctx, client, tree.Root, verb.Depth, verb.Filter, func(n *service.StateTreeNode, prefix string) error {
		name := n.Name + ":"
		if n.Preview != nil {
			v := n.Preview.Get()
			if n.Constants != nil {
				constants, err := getConstantSet(ctx, client, n.Constants)
				if err != nil {
					return log.Err(ctx, err, "Couldn't fetch constant set")
				}
				v = constants.Sprint(v)
			}
			fmt.Fprintln(os.Stdout, prefix, name, v)
		} else {
			fmt.Fprintln(os.Stdout, prefix, name)
		}
		return nil
	}, "", true)
}

func traverseStateTree(
	ctx context.Context,
	c client.Client,
	p *path.StateTreeNode,
	depth int,
	filter flags.StringSlice,
	f func(n *service.StateTreeNode, prefix string) error,
	prefix string,
	last bool) error {

	if task.Stopped(ctx) {
		return task.StopReason(ctx)
	}

	boxedNode, err := c.Get(ctx, p.Path())
	if err != nil {
		return log.Errf(ctx, err, "Failed to load the node at: %v", p)
	}

	n := boxedNode.(*service.StateTreeNode)

	curPrefix := prefix
	if len(p.Indices) > 0 {
		if last {
			curPrefix += "└──"
		} else {
			curPrefix += "├──"
		}
	}

	nextFilter := filter
	if len(filter) != 0 && filter[0] != n.Name {
		return nil
	}
	if len(filter) != 0 {
		nextFilter = filter[1:]
	}

	if err := f(n, curPrefix); err != nil {
		return err
	}

	if last {
		prefix += "    "
	} else {
		prefix += "│   "
	}
	if depth != 0 {
		for i := uint64(0); i < n.NumChildren; i++ {
			err := traverseStateTree(ctx, c, p.Index(i), depth-1, nextFilter, f, prefix, i == n.NumChildren-1)
			if err != nil {
				return err
			}
		}
	}

	return nil
}
<commit_msg>Allow wildcards in gapit state filter.<commit_after>// Copyright (C) 2017 Google Inc.
//
// 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 main

import (
	"context"
	"flag"
	"fmt"
	"os"
	"path/filepath"

	"github.com/google/gapid/core/app"
	"github.com/google/gapid/core/app/flags"
	"github.com/google/gapid/core/event/task"
	"github.com/google/gapid/core/log"
	"github.com/google/gapid/gapis/client"
	"github.com/google/gapid/gapis/service"
	"github.com/google/gapid/gapis/service/path"
)

type stateVerb struct{ StateFlags }

func init() {
	verb := &stateVerb{
		StateFlags{
			At:     flags.U64Slice{},
			Depth:  -1,
			Filter: flags.StringSlice{},
		},
	}

	app.AddVerb(&app.Verb{
		Name:      "state",
		ShortHelp: "Prints the state tree for a point in a .gfxtrace file",
		Action:    verb,
	})
}

func (verb *stateVerb) Run(ctx context.Context, flags flag.FlagSet) error {
	if flags.NArg() != 1 {
		app.Usage(ctx, "Exactly one gfx trace file expected, got %d", flags.NArg())
		return nil
	}

	client, err := getGapis(ctx, verb.Gapis, verb.Gapir)
	if err != nil {
		return log.Err(ctx, err, "Failed to connect to the GAPIS server")
	}
	defer client.Close()

	filepath, err := filepath.Abs(flags.Arg(0))
	ctx = log.V{"filepath": filepath}.Bind(ctx)
	if err != nil {
		return log.Err(ctx, err, "Could not find capture file")
	}

	c, err := client.LoadCapture(ctx, filepath)
	if err != nil {
		return log.Err(ctx, err, "Failed to load the capture file")
	}

	if len(verb.At) == 0 {
		boxedCapture, err := client.Get(ctx, c.Path())
		if err != nil {
			return log.Err(ctx, err, "Failed to load the capture")
		}
		verb.At = []uint64{uint64(boxedCapture.(*service.Capture).NumCommands) - 1}
	}

	boxedTree, err := client.Get(ctx, c.Command(uint64(verb.At[0]), verb.At[1:]...).StateAfter().Tree().Path())
	if err != nil {
		return log.Err(ctx, err, "Failed to load the command tree")
	}

	tree := boxedTree.(*service.StateTree)

	return traverseStateTree(ctx, client, tree.Root, verb.Depth, verb.Filter, func(n *service.StateTreeNode, prefix string) error {
		name := n.Name + ":"
		if n.Preview != nil {
			v := n.Preview.Get()
			if n.Constants != nil {
				constants, err := getConstantSet(ctx, client, n.Constants)
				if err != nil {
					return log.Err(ctx, err, "Couldn't fetch constant set")
				}
				v = constants.Sprint(v)
			}
			fmt.Fprintln(os.Stdout, prefix, name, v)
		} else {
			fmt.Fprintln(os.Stdout, prefix, name)
		}
		return nil
	}, "", true)
}

func traverseStateTree(
	ctx context.Context,
	c client.Client,
	p *path.StateTreeNode,
	depth int,
	filter flags.StringSlice,
	f func(n *service.StateTreeNode, prefix string) error,
	prefix string,
	last bool) error {

	if task.Stopped(ctx) {
		return task.StopReason(ctx)
	}

	boxedNode, err := c.Get(ctx, p.Path())
	if err != nil {
		return log.Errf(ctx, err, "Failed to load the node at: %v", p)
	}

	n := boxedNode.(*service.StateTreeNode)

	curPrefix := prefix
	if len(p.Indices) > 0 {
		if last {
			curPrefix += "└──"
		} else {
			curPrefix += "├──"
		}
	}

	nextFilter := filter
	if len(filter) != 0 &&
			(filter[0] != n.Name && filter[0] != "*") {
		return nil
	}
	if len(filter) != 0 {
		nextFilter = filter[1:]
	}

	if err := f(n, curPrefix); err != nil {
		return err
	}

	if last {
		prefix += "    "
	} else {
		prefix += "│   "
	}
	if depth != 0 {
		for i := uint64(0); i < n.NumChildren; i++ {
			err := traverseStateTree(ctx, c, p.Index(i), depth-1, nextFilter, f, prefix, i == n.NumChildren-1)
			if err != nil {
				return err
			}
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"os"

	"github.com/loadimpact/k6/stats/cloud"
	"github.com/loadimpact/k6/ui"
	"github.com/pkg/errors"
	"github.com/spf13/cobra"
)

// loginCloudCommand represents the 'login cloud' command
var loginCloudCommand = &cobra.Command{
	Use:   "cloud",
	Short: "Authenticate with Load Impact",
	Long: `Authenticate with Load Impact.

This will set the default token used when just "k6 run -o cloud" is passed.`,

	Example: `
  # Show the stored token.
  k6 login cloud -s

  # Set up the token.
  k6 login cloud -t YOUR_TOKEN

  # Ask for your Load Impact user email and password to automatically set up the token.
  k6 login cloud`[1:],

	Args: cobra.NoArgs,
	RunE: func(cmd *cobra.Command, args []string) error {

		printToken := func(conf cloud.Config) {
			fmt.Fprintf(stdout, "  token: %s\n", ui.ValueColor.Sprint(conf.Token))
		}

		config, cdir, err := readDiskConfig()
		if err != nil {
			return err
		}

		token := getNullString(cmd.Flags(), "token")
		show := getNullBool(cmd.Flags(), "show")

		conf := config.Collectors.Cloud

		if !show.Valid {
			if token.Valid {
				conf.Token = token.String
			} else {
				printToken(conf)

				form := ui.Form{
					Fields: []ui.Field{
						ui.StringField{
							Key:   "Email",
							Label: "Email",
						},
						ui.StringField{
							Key:   "Password",
							Label: "Password",
						},
					},
				}

				vals, err := form.Run(os.Stdin, stdout)
				if err != nil {
					return err
				}

				email := vals["Email"].(string)
				password := vals["Password"].(string)
				client := cloud.NewClient("", conf.Host, Version)
				response, err := client.Login(email, password)
				if err != nil {
					return err
				}

				if response.APIToken == "" {
					return errors.New("Your account has no API token, please generate one: `https://app.loadimpact.com/account/token`.")
				}

				conf.Token = response.APIToken
			}

			config.Collectors.Cloud = conf
			if err := writeDiskConfig(cdir, config); err != nil {
				return err
			}
		}

		printToken(conf)
		return nil

	},
}

func init() {
	loginCmd.AddCommand(loginCloudCommand)
	loginCloudCommand.Flags().StringP("token", "t", "", "specify `token` to use")
	loginCloudCommand.Flags().BoolP("show", "s", false, "display saved token and exit")
}
<commit_msg>Refactor using a `switch`<commit_after>package cmd

import (
	"fmt"
	"os"

	"github.com/loadimpact/k6/stats/cloud"
	"github.com/loadimpact/k6/ui"
	"github.com/pkg/errors"
	"github.com/spf13/cobra"
)

const (
        actionSetToken = iota
        actionShowToken
        actionLogin
)

// loginCloudCommand represents the 'login cloud' command
var loginCloudCommand = &cobra.Command{
	Use:   "cloud",
	Short: "Authenticate with Load Impact",
	Long: `Authenticate with Load Impact.

This will set the default token used when just "k6 run -o cloud" is passed.`,

	Example: `
  # Show the stored token.
  k6 login cloud -s

  # Set up the token.
  k6 login cloud -t YOUR_TOKEN

  # Ask for your Load Impact user email and password to automatically set up the token.
  k6 login cloud`[1:],

	Args: cobra.NoArgs,
	RunE: func(cmd *cobra.Command, args []string) error {

		printToken := func(conf cloud.Config) {
			fmt.Fprintf(stdout, "  token: %s\n", ui.ValueColor.Sprint(conf.Token))
		}

		config, cdir, err := readDiskConfig()
		if err != nil {
			return err
		}

		token := getNullString(cmd.Flags(), "token")
		show := getNullBool(cmd.Flags(), "show")

                cmdName := actionLogin
                if show.Valid {
                        cmdName = actionShowToken
                } else if token.Valid {
                        cmdName = actionSetToken
                }

		conf := config.Collectors.Cloud

                switch cmdName {
                case actionSetToken:
                        conf.Token = token.String
                case actionLogin:
                        printToken(conf)

                        form := ui.Form{
                                Fields: []ui.Field{
                                        ui.StringField{
                                                Key:   "Email",
                                                Label: "Email",
					},
                                        ui.StringField{
                                                Key:   "Password",
                                                Label: "Password",
                                        },
                                },
                        }

                        vals, err := form.Run(os.Stdin, stdout)
                        if err != nil {
                                return err
			}

                        email := vals["Email"].(string)
                        password := vals["Password"].(string)
                        client := cloud.NewClient("", conf.Host, Version)
                        response, err := client.Login(email, password)
                        if err != nil {
                                return err
                        }

                        if response.APIToken == "" {
                                return errors.New("Your account has no API token, please generate one: `https://app.loadimpact.com/account/token`.")
                        }

                        conf.Token = response.APIToken
                }

                if cmdName != actionShowToken {
			config.Collectors.Cloud = conf
			if err := writeDiskConfig(cdir, config); err != nil {
				return err
			}
		}

		printToken(conf)
		return nil
	},
}

func init() {
	loginCmd.AddCommand(loginCloudCommand)
	loginCloudCommand.Flags().StringP("token", "t", "", "specify `token` to use")
	loginCloudCommand.Flags().BoolP("show", "s", false, "display saved token and exit")
}
<|endoftext|>


<commit_before>// record some audio and save it as a WAV file
package main

import (
	"encoding/binary"
	"flag"
	"fmt"
	"os"

	"github.com/go-audio/audio"
	"github.com/go-audio/wav"
	"github.com/yobert/alsa"
)

var (
	rate     = 44100
	channels = 2
)

func main() {
	var duration = 5
	var file = "out.wav"

	flag.IntVar(&rate, "rate", 44100, "Frame rate (Hz)")
	flag.IntVar(&duration, "duration", 5, "Recording duration (s)")
	flag.StringVar(&file, "file", "out.wave", "Output file")
	flag.Parse()

	cards, err := alsa.OpenCards()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer alsa.CloseCards(cards)

	// use the first recording device we find
	var recordDevice *alsa.Device

	for _, card := range cards {
		devices, err := card.Devices()
		if err != nil {
			fmt.Println(err)
			return
		}
		for _, device := range devices {
			if device.Type != alsa.PCM {
				continue
			}
			if device.Record && recordDevice == nil {
				recordDevice = device
			}
		}
	}

	if recordDevice == nil {
		fmt.Println("No recording device found")
		return
	}
	fmt.Printf("Recording device: %v\n", recordDevice)

	recording, err := record(recordDevice, duration)
	if err != nil {
		fmt.Println(err)
		return
	}

	err = save(recording, file)
	if err != nil {
		fmt.Println(err)
		return
	}
}

// record audio for duration seconds
func record(rec *alsa.Device, duration int) (alsa.Buffer, error) {
	var err error

	if err = rec.Open(); err != nil {
		return alsa.Buffer{}, err
	}
	defer rec.Close()

	_, err = rec.NegotiateChannels(channels)
	if err != nil {
		return alsa.Buffer{}, err
	}

	_, err = rec.NegotiateRate(rate)
	if err != nil {
		return alsa.Buffer{}, err
	}

	_, err = rec.NegotiateFormat(alsa.S16_LE, alsa.S32_LE)
	if err != nil {
		return alsa.Buffer{}, err
	}

	bufferSize, err := rec.NegotiateBufferSize(8192, 16384)
	if err != nil {
		return alsa.Buffer{}, err
	}

	if err = rec.Prepare(); err != nil {
		return alsa.Buffer{}, err
	}

	buf := rec.NewBufferSeconds(duration)

	fmt.Printf("Negotiated parameters: %v, %d frame buffer, %d bytes/frame\n",
		buf.Format, bufferSize, rec.BytesPerFrame())

	fmt.Printf("Recording for %d seconds (%d frames, %d bytes)...\n", duration, len(buf.Data)/rec.BytesPerFrame(), len(buf.Data))
	err = rec.Read(buf.Data)
	if err != nil {
		return alsa.Buffer{}, err
	}
	fmt.Println("Recording stopped.")
	return buf, nil
}

// save recording to a WAV file
func save(recording alsa.Buffer, file string) error {
	of, err := os.Create(file)
	if err != nil {
		return err
	}
	defer of.Close()

	var sampleBytes int
	switch recording.Format.SampleFormat {
	case alsa.S32_LE:
		sampleBytes = 4
	case alsa.S16_LE:
		sampleBytes = 2
	default:
		return fmt.Errorf("Unhandled ALSA format %v", recording.Format.SampleFormat)
	}

	// normal uncompressed WAV format (I think)
	// https://web.archive.org/web/20080113195252/http://www.borg.com/~jglatt/tech/wave.htm
	wavformat := 1

	enc := wav.NewEncoder(of, recording.Format.Rate, sampleBytes*8, recording.Format.Channels, wavformat)

	sampleCount := len(recording.Data) / sampleBytes
	data := make([]int, sampleCount)

	format := &audio.Format{
		NumChannels: recording.Format.Channels,
		SampleRate:  recording.Format.Rate,
	}

	// Convert into the format go-audio/wav wants
	var off int
	switch recording.Format.SampleFormat {
	case alsa.S32_LE:
		inc := binary.Size(uint32(0))
		for i := 0; i < sampleCount; i++ {
			data[i] = int(binary.LittleEndian.Uint32(recording.Data[off:]))
			off += inc
		}
	case alsa.S16_LE:
		inc := binary.Size(uint16(0))
		for i := 0; i < sampleCount; i++ {
			data[i] = int(binary.LittleEndian.Uint16(recording.Data[off:]))
			off += inc
		}
	default:
		return fmt.Errorf("Unhandled ALSA format %v", recording.Format.SampleFormat)
	}

	intBuf := &audio.IntBuffer{Data: data, Format: format, SourceBitDepth: sampleBytes * 8}

	if err := enc.Write(intBuf); err != nil {
		return err
	}

	if err := enc.Close(); err != nil {
		return err
	}
	fmt.Printf("Saved recording to %s\n", file)
	return nil
}
<commit_msg>cmd/record: Support 1 or 2 channels<commit_after>// record some audio and save it as a WAV file
package main

import (
	"encoding/binary"
	"flag"
	"fmt"
	"os"

	"github.com/go-audio/audio"
	"github.com/go-audio/wav"
	"github.com/yobert/alsa"
)

var (
	rate     = 44100
)

func main() {
	var duration = 5
	var file = "out.wav"

	flag.IntVar(&rate, "rate", 44100, "Frame rate (Hz)")
	flag.IntVar(&duration, "duration", 5, "Recording duration (s)")
	flag.StringVar(&file, "file", "out.wave", "Output file")
	flag.Parse()

	cards, err := alsa.OpenCards()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer alsa.CloseCards(cards)

	// use the first recording device we find
	var recordDevice *alsa.Device

	for _, card := range cards {
		devices, err := card.Devices()
		if err != nil {
			fmt.Println(err)
			return
		}
		for _, device := range devices {
			if device.Type != alsa.PCM {
				continue
			}
			if device.Record && recordDevice == nil {
				recordDevice = device
			}
		}
	}

	if recordDevice == nil {
		fmt.Println("No recording device found")
		return
	}
	fmt.Printf("Recording device: %v\n", recordDevice)

	recording, err := record(recordDevice, duration)
	if err != nil {
		fmt.Println(err)
		return
	}

	err = save(recording, file)
	if err != nil {
		fmt.Println(err)
		return
	}
}

// record audio for duration seconds
func record(rec *alsa.Device, duration int) (alsa.Buffer, error) {
	var err error

	if err = rec.Open(); err != nil {
		return alsa.Buffer{}, err
	}
	defer rec.Close()

	_, err = rec.NegotiateChannels(1, 2)
	if err != nil {
		return alsa.Buffer{}, err
	}

	_, err = rec.NegotiateRate(rate)
	if err != nil {
		return alsa.Buffer{}, err
	}

	_, err = rec.NegotiateFormat(alsa.S16_LE, alsa.S32_LE)
	if err != nil {
		return alsa.Buffer{}, err
	}

	bufferSize, err := rec.NegotiateBufferSize(8192, 16384)
	if err != nil {
		return alsa.Buffer{}, err
	}

	if err = rec.Prepare(); err != nil {
		return alsa.Buffer{}, err
	}

	buf := rec.NewBufferSeconds(duration)

	fmt.Printf("Negotiated parameters: %v, %d frame buffer, %d bytes/frame\n",
		buf.Format, bufferSize, rec.BytesPerFrame())

	fmt.Printf("Recording for %d seconds (%d frames, %d bytes)...\n", duration, len(buf.Data)/rec.BytesPerFrame(), len(buf.Data))
	err = rec.Read(buf.Data)
	if err != nil {
		return alsa.Buffer{}, err
	}
	fmt.Println("Recording stopped.")
	return buf, nil
}

// save recording to a WAV file
func save(recording alsa.Buffer, file string) error {
	of, err := os.Create(file)
	if err != nil {
		return err
	}
	defer of.Close()

	var sampleBytes int
	switch recording.Format.SampleFormat {
	case alsa.S32_LE:
		sampleBytes = 4
	case alsa.S16_LE:
		sampleBytes = 2
	default:
		return fmt.Errorf("Unhandled ALSA format %v", recording.Format.SampleFormat)
	}

	// normal uncompressed WAV format (I think)
	// https://web.archive.org/web/20080113195252/http://www.borg.com/~jglatt/tech/wave.htm
	wavformat := 1

	enc := wav.NewEncoder(of, recording.Format.Rate, sampleBytes*8, recording.Format.Channels, wavformat)

	sampleCount := len(recording.Data) / sampleBytes
	data := make([]int, sampleCount)

	format := &audio.Format{
		NumChannels: recording.Format.Channels,
		SampleRate:  recording.Format.Rate,
	}

	// Convert into the format go-audio/wav wants
	var off int
	switch recording.Format.SampleFormat {
	case alsa.S32_LE:
		inc := binary.Size(uint32(0))
		for i := 0; i < sampleCount; i++ {
			data[i] = int(binary.LittleEndian.Uint32(recording.Data[off:]))
			off += inc
		}
	case alsa.S16_LE:
		inc := binary.Size(uint16(0))
		for i := 0; i < sampleCount; i++ {
			data[i] = int(binary.LittleEndian.Uint16(recording.Data[off:]))
			off += inc
		}
	default:
		return fmt.Errorf("Unhandled ALSA format %v", recording.Format.SampleFormat)
	}

	intBuf := &audio.IntBuffer{Data: data, Format: format, SourceBitDepth: sampleBytes * 8}

	if err := enc.Write(intBuf); err != nil {
		return err
	}

	if err := enc.Close(); err != nil {
		return err
	}
	fmt.Printf("Saved recording to %s\n", file)
	return nil
}
<|endoftext|>


<commit_before>// +build !appengine

// main.go holds bits needed when not serving hkjnweb on appengine.
package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"

	"hkjn.me/hkjnweb"
)

// registerStatic registers handler for static files.
func registerStatic(dir string) {
	if dir == "" {
		dir = "static"
	}
	path := fmt.Sprintf("/%s/", dir)
	h := http.StripPrefix(
		path,
		http.FileServer(http.Dir(dir)))
	http.Handle(path, h)
}

func main() {
	flag.Parse()

	hkjnweb.Register()
	hkjnweb.IsProd = os.Getenv("IN_PROD") != ""
	//	hkjnweb.Logger = autosite.Glogger{}
	registerStatic(os.Getenv("STATIC_DIR"))

	addr := os.Getenv("BIND_ADDR")
	if addr == "" {
		addr = ":12345"
	}
	if os.Getenv("SERVE_HTTP") != "" {
		log.Printf("webserver serving HTTP on %s..\n", addr)
		err := http.ListenAndServe(addr, nil)
		if err != nil {
			log.Fatalf("FATAL: http server exited: %v\n", err)
		}
	} else {
		log.Println("Since SERVE_HTTP isn't set, we should serve https")
		certFile := os.Getenv("HTTPS_CERT_FILE")
		keyFile := os.Getenv("HTTPS_KEY_FILE")
		if certFile == "" || keyFile == "" {
			log.Fatalln("FATAL: No HTTPS_CERT_FILE or HTTPS_KEY_FILE specified.")
		}
		log.Printf("webserver serving HTTPS on %s..\n", addr)
		err := http.ListenAndServeTLS(addr, certFile, keyFile, nil)
		if err != nil {
			log.Fatalf("FATAL: https server exited: %v\n", err)
		}
	}
}
<commit_msg>Rename IN_PROD -> PROD<commit_after>// +build !appengine

// main.go holds bits needed when not serving hkjnweb on appengine.
package main

import (
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"

	"hkjn.me/hkjnweb"
)

// registerStatic registers handler for static files.
func registerStatic(dir string) {
	if dir == "" {
		dir = "static"
	}
	path := fmt.Sprintf("/%s/", dir)
	h := http.StripPrefix(
		path,
		http.FileServer(http.Dir(dir)))
	http.Handle(path, h)
}

func main() {
	flag.Parse()

	hkjnweb.Register()
	hkjnweb.IsProd = os.Getenv("PROD") != ""
	if hkjnweb.IsProd {
		log.Println("Since PROD is set, we're serving the prod site")
	}
	//	hkjnweb.Logger = autosite.Glogger{}
	registerStatic(os.Getenv("STATIC_DIR"))

	addr := os.Getenv("BIND_ADDR")
	if addr == "" {
		addr = ":12345"
	}
	if os.Getenv("SERVE_HTTP") != "" {
		log.Printf("webserver serving HTTP on %s..\n", addr)
		err := http.ListenAndServe(addr, nil)
		if err != nil {
			log.Fatalf("FATAL: http server exited: %v\n", err)
		}
	} else {
		log.Println("Since SERVE_HTTP isn't set, we should serve https")
		certFile := os.Getenv("HTTPS_CERT_FILE")
		keyFile := os.Getenv("HTTPS_KEY_FILE")
		if certFile == "" || keyFile == "" {
			log.Fatalln("FATAL: No HTTPS_CERT_FILE or HTTPS_KEY_FILE specified.")
		}
		log.Printf("webserver serving HTTPS on %s..\n", addr)
		err := http.ListenAndServeTLS(addr, certFile, keyFile, nil)
		if err != nil {
			log.Fatalf("FATAL: https server exited: %v\n", err)
		}
	}
}
<|endoftext|>


<commit_before><commit_msg>finished 1.8<commit_after>// “Exercise 1.8: Modify fetch to add the prefix http:// to each argument
// URL if it is missing. You might want to use strings.HasPrefix.”

// Excerpt From: Brian W. Kernighan. “The Go Programming Language
// (Addison-Wesley Professional Computing Series).” iBooks.

// Copyright © 2016 Alan A. A. Donovan & Brian W. Kernighan.
// License: https://creativecommons.org/licenses/by-nc-sa/4.0/

// See page 16.
//!+

// Fetch prints the content found at each specified URL.
package main

import (
	"fmt"
	"io"
	"net/http"
	"os"
	"strings"
)

func main() {
	for _, url := range os.Args[1:] {
		url = "http://" + url
		fmt.Println(url)
		if prefix := strings.HasPrefix(url, "http://"); !prefix {
			url = "http://" + url
		}
		resp, err := http.Get(url)
		if err != nil {
			fmt.Fprintf(os.Stderr, "fetch: %v\n", err)
			os.Exit(1)
		}
		_, err = io.Copy(os.Stdout, resp.Body)
		resp.Body.Close()
		if err != nil {
			fmt.Fprintf(os.Stderr, "fetch: reading %s: %v\n", url, err)
			os.Exit(1)
		}
	}
}

//!-
<|endoftext|>


<commit_before>/*
Copyright IBM Corp 2016 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 main

import (
	"errors"
	"fmt"
	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

// ============================================================================================================================
// Main
// ============================================================================================================================
func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

// Init resets all the things
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}

	return nil, nil
}

// Invoke is our entry point to invoke a chaincode function
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("invoke is running " + function)

	// Handle different functions
	if function == "init" {													//initialize the chaincode state, used as reset
		return t.Init(stub, "init", args)
	}
	fmt.Println("invoke did not find func: " + function)					//error

	return nil, errors.New("Received unknown function invocation: " + function)
}

// Query is our entry point for queries
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("query is running " + function)

	// Handle different functions
	if function == "dummy_query" {											//read a variable
		fmt.Println("hi there " + function)						//error
		return nil, nil;
	}
	fmt.Println("query did not find func: " + function)						//error

	return nil, errors.New("Received unknown function query: " + function)
}<commit_msg>Back to original interfaces with full code<commit_after>/*
Copyright IBM Corp 2016 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 main

import (
	"errors"
	"fmt"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

// Init resets all the things
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}

	err := stub.PutState("hello_world", []byte(args[0]))
	if err != nil {
		return nil, err
	}

	return nil, nil
}

// Invoke isur entry point to invoke a chaincode function
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("invoke is running " + function)

	// Handle different functions
	if function == "init" {
		return t.Init(stub, "init", args)
	} else if function == "write" {
		return t.write(stub, args)
	}
	fmt.Println("invoke did not find func: " + function)

	return nil, errors.New("Received unknown function invocation: " + function)
}

// Query is our entry point for queries
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("query is running " + function)

	// Handle different functions
	if function == "read" { //read a variable
		return t.read(stub, args)
	}
	fmt.Println("query did not find func: " + function)

	return nil, errors.New("Received unknown function query: " + function)
}

// write - invoke function to write key/value pair
func (t *SimpleChaincode) write(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	var key, value string
	var err error
	fmt.Println("running write()")

	if len(args) != 2 {
		return nil, errors.New("Incorrect number of arguments. Expecting 2. name of the key and value to set")
	}

	key = args[0] //rename for funsies
	value = args[1]
	err = stub.PutState(key, []byte(value)) //write the variable into the chaincode state
	if err != nil {
		return nil, err
	}
	return nil, nil
}

// read - query function to read key/value pair
func (t *SimpleChaincode) read(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	var key, jsonResp string
	var err error

	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting name of the key to query")
	}

	key = args[0]
	valAsbytes, err := stub.GetState(key)
	if err != nil {
		jsonResp = "{\"Error\":\"Failed to get state for " + key + "\"}"
		return nil, errors.New(jsonResp)
	}

	return valAsbytes, nil
}<|endoftext|>


<commit_before>package models

import (
	"github.com/Luncher/go-rest/db"
	"github.com/Luncher/go-rest/forms"
	"gopkg.in/mgo.v2/bson"
)

type Movie struct {
	ID     bson.ObjectId
	Name   string
	Rating float32
	Desc   string
}

type MovieModel struct{}

var dbConnect = db.NewConnection("localhost")

func (m *MovieModel) Create(data forms.CreateMovieCommand) error {
	collection := dbConnect.Use("test-mgo", "movies")
	err := collection.Insert(&Movie{data.Name, data.Rating, data.Desc})
	return err
}

func (m *MovieModel) Get(id string) (movie Movie, err error) {
	collection := dbConnect.Use("test-mgo", "movies")
	err = collection.FindId(id).One(&movie)
	return movie, err
}

func (m *MovieModel) Find() (list []Movie, err error) {
	collection := dbConnect.Use("test-mgo", "movies")
	err = collection.Find(bson.M{}).All(&list)
	return list, err
}

func (m *MovieModel) Update(id string, data forms.UpdateMovieCommand) (err error) {
	collection := dbConnect.Use("test-mgo", "movies")
	err = collection.UpdateId(id, data)

	return err
}

func (m *MovieModel) Delete(id string) (err error) {
	collection := dbConnect.Use("test-mgo", "movies")
	err = collection.RemoveId(id)

	return err
}
<commit_msg>sync latest code<commit_after>package models

import (
	"github.com/Luncher/go-rest/db"
	"github.com/Luncher/go-rest/forms"
	"gopkg.in/mgo.v2/bson"
)

type Movie struct {
	ID     bson.ObjectId
	Name   string
	Rating float32
	Desc   string
}

type MovieModel struct{}

var dbConnect = db.NewConnection("localhost")

func (m *MovieModel) Create(data forms.CreateMovieCommand) error {
	collection := dbConnect.Use("test-mgo", "movies")
	err := collection.Insert(&Movie{Name: data.Name, Rating: data.Rating, Desc: data.Desc})
	return err
}

func (m *MovieModel) Get(id string) (movie Movie, err error) {
	collection := dbConnect.Use("test-mgo", "movies")
	err = collection.FindId(id).One(&movie)
	return movie, err
}

func (m *MovieModel) Find() (list []Movie, err error) {
	collection := dbConnect.Use("test-mgo", "movies")
	err = collection.Find(bson.M{}).All(&list)
	return list, err
}

func (m *MovieModel) Update(id string, data forms.UpdateMovieCommand) (err error) {
	collection := dbConnect.Use("test-mgo", "movies")
	err = collection.UpdateId(id, data)

	return err
}

func (m *MovieModel) Delete(id string) (err error) {
	collection := dbConnect.Use("test-mgo", "movies")
	err = collection.RemoveId(id)

	return err
}
<|endoftext|>