<commit_before>package main

import "fmt"
import "io"
import "os"
import "os/exec"
import "strings"
import "unsafe"

import . "./lua"
import "./alias"
import "./conio"
import "./dos"
import "./interpreter"
import "./mbcs"

const nyagos_exec_cmd = "nyagos.exec.cmd"

type LuaFunction struct {
	L            *Lua
	registoryKey string
}

func (this LuaFunction) String() string {
	return "<<Lua-function>>"
}

func (this LuaFunction) Call(cmd *exec.Cmd) (interpreter.NextT, error) {
	this.L.GetField(Registory, this.registoryKey)
	this.L.NewTable()
	for i, arg1 := range cmd.Args {
		this.L.PushInteger(i)
		this.L.PushString(arg1)
		this.L.SetTable(-3)
	}
	this.L.PushLightUserData(unsafe.Pointer(cmd))
	this.L.SetField(Registory, nyagos_exec_cmd)
	err := this.L.Call(1, 0)
	return interpreter.CONTINUE, err
}

func cmdAlias(L *Lua) int {
	name, nameErr := L.ToString(1)
	if nameErr != nil {
		L.PushNil()
		L.PushString(nameErr.Error())
		return 2
	}
	key := strings.ToLower(name)
	switch L.GetType(2) {
	case TSTRING:
		value, err := L.ToString(2)
		if err == nil {
			alias.Table[key] = alias.New(value)
		} else {
			L.PushNil()
			L.PushString(err.Error())
			return 2
		}
	case TFUNCTION:
		regkey := "nyagos.alias." + key
		L.SetField(Registory, regkey)
		alias.Table[key] = LuaFunction{L, regkey}
	}
	L.PushBool(true)
	return 1
}

func cmdSetEnv(L *Lua) int {
	name, nameErr := L.ToString(1)
	if nameErr != nil {
		L.PushNil()
		L.PushString(nameErr.Error())
		return 2
	}
	value, valueErr := L.ToString(2)
	if valueErr != nil {
		L.PushNil()
		L.PushString(valueErr.Error())
		return 2
	}
	os.Setenv(name, value)
	L.PushBool(true)
	return 1
}

func cmdGetEnv(L *Lua) int {
	name, nameErr := L.ToString(1)
	if nameErr != nil {
		L.PushNil()
		return 1
	}
	value := os.Getenv(name)
	if len(value) > 0 {
		L.PushString(value)
	} else {
		L.PushNil()
	}
	return 1
}

func cmdExec(L *Lua) int {
	statement, statementErr := L.ToString(1)
	if statementErr != nil {
		L.PushNil()
		L.PushString(statementErr.Error())
		return 2
	}
	_, err := interpreter.Interpret(statement, nil)

	if err != nil {
		L.PushNil()
		L.PushString(err.Error())
		return 2
	}
	L.PushBool(true)
	return 1
}

func cmdEval(L *Lua) int {
	statement, statementErr := L.ToString(1)
	if statementErr != nil {
		L.PushNil()
		L.PushString(statementErr.Error())
		return 2
	}
	r, w, err := os.Pipe()
	if err != nil {
		L.PushNil()
		L.PushString(err.Error())
		return 2
	}
	go func(statement string, w *os.File) {
		interpreter.Interpret(statement, &interpreter.Stdio{Stdout: w})
		w.Close()
	}(statement, w)

	var result = []byte{}
	for {
		buffer := make([]byte, 256)
		size, err := r.Read(buffer)
		if err != nil || size <= 0 {
			break
		}
		result = append(result, buffer[0:size]...)
	}
	r.Close()
	L.PushAnsiString(result)
	return 1
}

func cmdEcho(L *Lua) int {
	var out io.Writer
	L.GetField(Registory, nyagos_exec_cmd)
	if L.GetType(-1) == TLIGHTUSERDATA {
		cmd := (*exec.Cmd)(L.ToUserData(-1))
		if cmd != nil {
			out = cmd.Stdout
		} else {
			out = os.Stdout
		}
	} else {
		out = os.Stdout
	}
	L.Pop(1)

	n := L.GetTop()
	for i := 1; i <= n; i++ {
		str, err := L.ToString(i)
		if err != nil {
			L.PushNil()
			L.PushString(err.Error())
			return 2
		}
		if i > 1 {
			fmt.Fprint(out, "\t")
		}
		fmt.Fprint(out, str)
	}
	fmt.Fprint(out, "\n")
	L.PushBool(true)
	return 1
}

func cmdGetwd(L *Lua) int {
	wd, err := os.Getwd()
	if err == nil {
		L.PushString(wd)
		return 1
	} else {
		return 0
	}
}

func cmdWhich(L *Lua) int {
	if L.GetType(-1) != TSTRING {
		return 0
	}
	name, nameErr := L.ToString(-1)
	if nameErr != nil {
		L.PushNil()
		L.PushString(nameErr.Error())
		return 2
	}
	path, err := exec.LookPath(name)
	if err == nil {
		L.PushString(path)
		return 1
	} else {
		L.PushNil()
		L.PushString(err.Error())
		return 2
	}
}

func cmdAtoU(L *Lua) int {
	str, err := mbcs.AtoU(L.ToAnsiString(1))
	if err == nil {
		L.PushString(str)
		return 1
	} else {
		return 0
	}
}

func cmdUtoA(L *Lua) int {
	utf8, utf8err := L.ToString(1)
	if utf8err != nil {
		L.PushNil()
		L.PushString(utf8err.Error())
		return 2
	}
	str, err := mbcs.UtoA(utf8)
	if err == nil {
		if len(str) >= 1 {
			L.PushAnsiString(str[:len(str)-1])
		} else {
			L.PushString("")
		}
		L.PushNil()
		return 2
	} else {
		L.PushNil()
		L.PushString(err.Error())
		return 2
	}
}

func cmdGlob(L *Lua) int {
	if !L.IsString(-1) {
		return 0
	}
	wildcard, wildcardErr := L.ToString(-1)
	if wildcardErr != nil {
		L.PushNil()
		L.PushString(wildcardErr.Error())
		return 2
	}
	list, err := dos.Glob(wildcard)
	if err != nil {
		L.PushNil()
		L.PushString(err.Error())
		return 2
	} else {
		L.NewTable()
		for i := 0; i < len(list); i++ {
			L.PushInteger(i + 1)
			L.PushString(list[i])
			L.SetTable(-3)
		}
		return 1
	}
}

func cmdBindKey(L *Lua) int {
	key, keyErr := L.ToString(-2)
	if keyErr != nil {
		L.PushString(keyErr.Error())
		return 1
	}
	val, valErr := L.ToString(-1)
	if valErr != nil {
		L.PushString(valErr.Error())
		return 1
	}
	err := conio.BindKeySymbol(key, val)
	if err != nil {
		L.PushNil()
		L.PushString(err.Error())
		return 2
	} else {
		L.PushBool(true)
		return 1
	}
}

func SetLuaFunctions(this *Lua) {
	stackPos := this.GetTop()
	defer this.SetTop(stackPos)
	this.NewTable()
	this.PushGoFunction(cmdAlias)
	this.SetField(-2, "alias")
	this.PushGoFunction(cmdSetEnv)
	this.SetField(-2, "setenv")
	this.PushGoFunction(cmdGetEnv)
	this.SetField(-2, "getenv")
	this.PushGoFunction(cmdExec)
	this.SetField(-2, "exec")
	this.PushGoFunction(cmdEcho)
	this.SetField(-2, "echo")
	this.PushGoFunction(cmdAtoU)
	this.SetField(-2, "atou")
	this.PushGoFunction(cmdUtoA)
	this.SetField(-2, "utoa")
	this.PushGoFunction(cmdGetwd)
	this.SetField(-2, "getwd")
	this.PushGoFunction(cmdWhich)
	this.SetField(-2, "which")
	this.PushGoFunction(cmdEval)
	this.SetField(-2, "eval")
	this.PushGoFunction(cmdGlob)
	this.SetField(-2, "glob")
	this.PushGoFunction(cmdBindKey)
	this.SetField(-2, "bindkey")
	this.SetGlobal("nyagos")

	// replace io.getenv
	this.GetGlobal("os")
	this.PushGoFunction(cmdGetEnv)
	this.SetField(-2, "getenv")

	var orgArgHook func([]string) []string
	orgArgHook = interpreter.SetArgsHook(func(args []string) []string {
		pos := this.GetTop()
		defer this.SetTop(pos)
		this.GetGlobal("nyagos")
		this.GetField(-1, "argsfilter")
		if !this.IsFunction(-1) {
			return orgArgHook(args)
		}
		this.NewTable()
		for i := 0; i < len(args); i++ {
			this.PushInteger(i)
			this.PushString(args[i])
			this.SetTable(-3)
		}
		if err := this.Call(1, 1); err != nil {
			fmt.Fprintf(os.Stderr, "%s\n", err)
			return orgArgHook(args)
		}
		if this.GetType(-1) != TTABLE {
			return orgArgHook(args)
		}
		newargs := []string{}
		for i := 0; true; i++ {
			this.PushInteger(i)
			this.GetTable(-2)
			if this.GetType(-1) == TNIL {
				break
			}
			arg1, arg1err := this.ToString(-1)
			if arg1err == nil {
				newargs = append(newargs, arg1)
			} else {
				fmt.Fprintln(os.Stderr, arg1err.Error())
			}
			this.Pop(1)
		}
		return orgArgHook(newargs)
	})
}
<commit_msg>Lua変数 nyagos.exe に nyagos.exe のフルパスを格納するようにした。<commit_after>package main

import "fmt"
import "io"
import "os"
import "os/exec"
import "strings"
import "unsafe"

import . "./lua"
import "./alias"
import "./conio"
import "./dos"
import "./interpreter"
import "./mbcs"

const nyagos_exec_cmd = "nyagos.exec.cmd"

type LuaFunction struct {
	L            *Lua
	registoryKey string
}

func (this LuaFunction) String() string {
	return "<<Lua-function>>"
}

func (this LuaFunction) Call(cmd *exec.Cmd) (interpreter.NextT, error) {
	this.L.GetField(Registory, this.registoryKey)
	this.L.NewTable()
	for i, arg1 := range cmd.Args {
		this.L.PushInteger(i)
		this.L.PushString(arg1)
		this.L.SetTable(-3)
	}
	this.L.PushLightUserData(unsafe.Pointer(cmd))
	this.L.SetField(Registory, nyagos_exec_cmd)
	err := this.L.Call(1, 0)
	return interpreter.CONTINUE, err
}

func cmdAlias(L *Lua) int {
	name, nameErr := L.ToString(1)
	if nameErr != nil {
		L.PushNil()
		L.PushString(nameErr.Error())
		return 2
	}
	key := strings.ToLower(name)
	switch L.GetType(2) {
	case TSTRING:
		value, err := L.ToString(2)
		if err == nil {
			alias.Table[key] = alias.New(value)
		} else {
			L.PushNil()
			L.PushString(err.Error())
			return 2
		}
	case TFUNCTION:
		regkey := "nyagos.alias." + key
		L.SetField(Registory, regkey)
		alias.Table[key] = LuaFunction{L, regkey}
	}
	L.PushBool(true)
	return 1
}

func cmdSetEnv(L *Lua) int {
	name, nameErr := L.ToString(1)
	if nameErr != nil {
		L.PushNil()
		L.PushString(nameErr.Error())
		return 2
	}
	value, valueErr := L.ToString(2)
	if valueErr != nil {
		L.PushNil()
		L.PushString(valueErr.Error())
		return 2
	}
	os.Setenv(name, value)
	L.PushBool(true)
	return 1
}

func cmdGetEnv(L *Lua) int {
	name, nameErr := L.ToString(1)
	if nameErr != nil {
		L.PushNil()
		return 1
	}
	value := os.Getenv(name)
	if len(value) > 0 {
		L.PushString(value)
	} else {
		L.PushNil()
	}
	return 1
}

func cmdExec(L *Lua) int {
	statement, statementErr := L.ToString(1)
	if statementErr != nil {
		L.PushNil()
		L.PushString(statementErr.Error())
		return 2
	}
	_, err := interpreter.Interpret(statement, nil)

	if err != nil {
		L.PushNil()
		L.PushString(err.Error())
		return 2
	}
	L.PushBool(true)
	return 1
}

func cmdEval(L *Lua) int {
	statement, statementErr := L.ToString(1)
	if statementErr != nil {
		L.PushNil()
		L.PushString(statementErr.Error())
		return 2
	}
	r, w, err := os.Pipe()
	if err != nil {
		L.PushNil()
		L.PushString(err.Error())
		return 2
	}
	go func(statement string, w *os.File) {
		interpreter.Interpret(statement, &interpreter.Stdio{Stdout: w})
		w.Close()
	}(statement, w)

	var result = []byte{}
	for {
		buffer := make([]byte, 256)
		size, err := r.Read(buffer)
		if err != nil || size <= 0 {
			break
		}
		result = append(result, buffer[0:size]...)
	}
	r.Close()
	L.PushAnsiString(result)
	return 1
}

func cmdEcho(L *Lua) int {
	var out io.Writer
	L.GetField(Registory, nyagos_exec_cmd)
	if L.GetType(-1) == TLIGHTUSERDATA {
		cmd := (*exec.Cmd)(L.ToUserData(-1))
		if cmd != nil {
			out = cmd.Stdout
		} else {
			out = os.Stdout
		}
	} else {
		out = os.Stdout
	}
	L.Pop(1)

	n := L.GetTop()
	for i := 1; i <= n; i++ {
		str, err := L.ToString(i)
		if err != nil {
			L.PushNil()
			L.PushString(err.Error())
			return 2
		}
		if i > 1 {
			fmt.Fprint(out, "\t")
		}
		fmt.Fprint(out, str)
	}
	fmt.Fprint(out, "\n")
	L.PushBool(true)
	return 1
}

func cmdGetwd(L *Lua) int {
	wd, err := os.Getwd()
	if err == nil {
		L.PushString(wd)
		return 1
	} else {
		return 0
	}
}

func cmdWhich(L *Lua) int {
	if L.GetType(-1) != TSTRING {
		return 0
	}
	name, nameErr := L.ToString(-1)
	if nameErr != nil {
		L.PushNil()
		L.PushString(nameErr.Error())
		return 2
	}
	path, err := exec.LookPath(name)
	if err == nil {
		L.PushString(path)
		return 1
	} else {
		L.PushNil()
		L.PushString(err.Error())
		return 2
	}
}

func cmdAtoU(L *Lua) int {
	str, err := mbcs.AtoU(L.ToAnsiString(1))
	if err == nil {
		L.PushString(str)
		return 1
	} else {
		return 0
	}
}

func cmdUtoA(L *Lua) int {
	utf8, utf8err := L.ToString(1)
	if utf8err != nil {
		L.PushNil()
		L.PushString(utf8err.Error())
		return 2
	}
	str, err := mbcs.UtoA(utf8)
	if err == nil {
		if len(str) >= 1 {
			L.PushAnsiString(str[:len(str)-1])
		} else {
			L.PushString("")
		}
		L.PushNil()
		return 2
	} else {
		L.PushNil()
		L.PushString(err.Error())
		return 2
	}
}

func cmdGlob(L *Lua) int {
	if !L.IsString(-1) {
		return 0
	}
	wildcard, wildcardErr := L.ToString(-1)
	if wildcardErr != nil {
		L.PushNil()
		L.PushString(wildcardErr.Error())
		return 2
	}
	list, err := dos.Glob(wildcard)
	if err != nil {
		L.PushNil()
		L.PushString(err.Error())
		return 2
	} else {
		L.NewTable()
		for i := 0; i < len(list); i++ {
			L.PushInteger(i + 1)
			L.PushString(list[i])
			L.SetTable(-3)
		}
		return 1
	}
}

func cmdBindKey(L *Lua) int {
	key, keyErr := L.ToString(-2)
	if keyErr != nil {
		L.PushString(keyErr.Error())
		return 1
	}
	val, valErr := L.ToString(-1)
	if valErr != nil {
		L.PushString(valErr.Error())
		return 1
	}
	err := conio.BindKeySymbol(key, val)
	if err != nil {
		L.PushNil()
		L.PushString(err.Error())
		return 2
	} else {
		L.PushBool(true)
		return 1
	}
}

func SetLuaFunctions(this *Lua) {
	stackPos := this.GetTop()
	defer this.SetTop(stackPos)
	this.NewTable()
	this.PushGoFunction(cmdAlias)
	this.SetField(-2, "alias")
	this.PushGoFunction(cmdSetEnv)
	this.SetField(-2, "setenv")
	this.PushGoFunction(cmdGetEnv)
	this.SetField(-2, "getenv")
	this.PushGoFunction(cmdExec)
	this.SetField(-2, "exec")
	this.PushGoFunction(cmdEcho)
	this.SetField(-2, "echo")
	this.PushGoFunction(cmdAtoU)
	this.SetField(-2, "atou")
	this.PushGoFunction(cmdUtoA)
	this.SetField(-2, "utoa")
	this.PushGoFunction(cmdGetwd)
	this.SetField(-2, "getwd")
	this.PushGoFunction(cmdWhich)
	this.SetField(-2, "which")
	this.PushGoFunction(cmdEval)
	this.SetField(-2, "eval")
	this.PushGoFunction(cmdGlob)
	this.SetField(-2, "glob")
	this.PushGoFunction(cmdBindKey)
	this.SetField(-2, "bindkey")
	exeName, exeNameErr := dos.GetModuleFileName()
	if exeNameErr != nil {
		fmt.Fprintln(os.Stderr, exeNameErr)
	} else {
		this.PushString(exeName)
		this.SetField(-2, "exe")
	}
	this.SetGlobal("nyagos")

	// replace io.getenv
	this.GetGlobal("os")
	this.PushGoFunction(cmdGetEnv)
	this.SetField(-2, "getenv")

	var orgArgHook func([]string) []string
	orgArgHook = interpreter.SetArgsHook(func(args []string) []string {
		pos := this.GetTop()
		defer this.SetTop(pos)
		this.GetGlobal("nyagos")
		this.GetField(-1, "argsfilter")
		if !this.IsFunction(-1) {
			return orgArgHook(args)
		}
		this.NewTable()
		for i := 0; i < len(args); i++ {
			this.PushInteger(i)
			this.PushString(args[i])
			this.SetTable(-3)
		}
		if err := this.Call(1, 1); err != nil {
			fmt.Fprintf(os.Stderr, "%s\n", err)
			return orgArgHook(args)
		}
		if this.GetType(-1) != TTABLE {
			return orgArgHook(args)
		}
		newargs := []string{}
		for i := 0; true; i++ {
			this.PushInteger(i)
			this.GetTable(-2)
			if this.GetType(-1) == TNIL {
				break
			}
			arg1, arg1err := this.ToString(-1)
			if arg1err == nil {
				newargs = append(newargs, arg1)
			} else {
				fmt.Fprintln(os.Stderr, arg1err.Error())
			}
			this.Pop(1)
		}
		return orgArgHook(newargs)
	})
}
<|endoftext|>


<commit_before>// Fully persistent data structures. A persistent data structure is a data
// structure that always preserves the previous version of itself when
// it is modified. Such data structures are effectively immutable,
// as their operations do not update the structure in-place, but instead
// always yield a new structure.
//
// Persistent
// data structures typically share structure among themselves.  This allows
// operations to avoid copying the entire data structure.
package ps

import (
	"bytes"
	"fmt"
)

// A Map associates unique keys (type string) with values (type Any).
type Map interface {
	// IsNil returns true if the Map is empty
	IsNil() bool

	// Set returns a new map in which key and value are associated.
	// If the key didn't exist before, it's created; otherwise, the
	// associated value is changed.
	// This operation is O(log N) in the number of keys.
	Set(key string, value interface{}) Map

	// Delete returns a new map with the association for key, if any, removed.
	// This operation is O(log N) in the number of keys.
	Delete(key string) Map

	// Lookup returns the value associated with a key, if any.  If the key
	// exists, the second return value is true; otherwise, false.
	// This operation is O(log N) in the number of keys.
	Lookup(key string) (interface{}, bool)

	// Size returns the number of key value pairs in the map.
	// This takes O(1) time.
	Size() int

	// ForEach executes a callback on each key value pair in the map.
	ForEach(f func(key string, val interface{}))

	// Keys returns a slice with all keys in this map.
	// This operation is O(N) in the number of keys.
	Keys() []string

	String() string
}

// Immutable (i.e. persistent) associative array
const childCount = 8
const shiftSize = 3

type tree struct {
	count    int
	hash     uint64 // hash of the key (used for tree balancing)
	key      string
	value    interface{}
	children [childCount]*tree
}

var nilMap = &tree{}

// Recursively set nilMap's subtrees to point at itself.
// This eliminates all nil pointers in the map structure.
// All map nodes are created by cloning this structure so
// they avoid the problem too.
func init() {
	for i := range nilMap.children {
		nilMap.children[i] = nilMap
	}
}

// NewMap allocates a new, persistent map from strings to values of
// any type.
// This is currently implemented as a path-copying binary tree.
func NewMap() Map {
	return nilMap
}

func (self *tree) IsNil() bool {
	return self == nilMap
}

// clone returns an exact duplicate of a tree node
func (self *tree) clone() *tree {
	var m tree
	m = *self
	return &m
}

// constants for FNV-1a hash algorithm
const (
	offset64 uint64 = 14695981039346656037
	prime64  uint64 = 1099511628211
)

// hashKey returns a hash code for a given string
func hashKey(key string) uint64 {
	hash := offset64
	for _, codepoint := range key {
		hash ^= uint64(codepoint)
		hash *= prime64
	}
	return hash
}

// Set returns a new map similar to this one but with key and value
// associated.  If the key didn't exist, it's created; otherwise, the
// associated value is changed.
func (self *tree) Set(key string, value interface{}) Map {
	hash := hashKey(key)
	return setLowLevel(self, hash, hash, key, value)
}

func setLowLevel(self *tree, partialHash, hash uint64, key string, value interface{}) *tree {
	if self.IsNil() { // an empty tree is easy
		m := self.clone()
		m.count = 1
		m.hash = hash
		m.key = key
		m.value = value
		return m
	}

	if hash != self.hash {
		m := self.clone()
		i := partialHash % childCount
		m.children[i] = setLowLevel(self.children[i], partialHash>>shiftSize, hash, key, value)
		recalculateCount(m)
		return m
	}

	// did we find a hash collision?
	if key != self.key {
		oops := fmt.Sprintf("Hash collision between: '%s' and '%s'.  Please report to https://github.com/mndrix/ps/issues/new", self.key, key)
		panic(oops)
	}

	// replacing a key's previous value
	m := self.clone()
	m.value = value
	return m
}

// modifies a map by recalculating its key count based on the counts
// of its subtrees
func recalculateCount(m *tree) {
	count := 0
	for _, t := range m.children {
		count += t.Size()
	}
	m.count = count + 1 // add one to count ourself
}

func (m *tree) Delete(key string) Map {
	hash := hashKey(key)
	newMap, _ := deleteLowLevel(m, hash, hash)
	return newMap
}

func deleteLowLevel(self *tree, partialHash, hash uint64) (*tree, bool) {
	// empty trees are easy
	if self.IsNil() {
		return self, false
	}

	if hash != self.hash {
		i := partialHash % childCount
		child, found := deleteLowLevel(self.children[i], partialHash>>shiftSize, hash)
		if !found {
			return self, false
		}
		newMap := self.clone()
		newMap.children[i] = child
		recalculateCount(newMap)
		return newMap, true // ? this wasn't in the original code
	}

	// we must delete our own node
	if self.isLeaf() { // we have no children
		return nilMap, true
	}
	/*
	   if self.subtreeCount() == 1 { // only one subtree
	       for _, t := range self.children {
	           if t != nilMap {
	               return t, true
	           }
	       }
	       panic("Tree with 1 subtree actually had no subtrees")
	   }
	*/

	// find a node to replace us
	i := -1
	size := -1
	for j, t := range self.children {
		if t.Size() > size {
			i = j
			size = t.Size()
		}
	}

	// make chosen leaf smaller
	replacement, child := self.children[i].deleteLeftmost()
	newMap := replacement.clone()
	for j := range self.children {
		if j == i {
			newMap.children[j] = child
		} else {
			newMap.children[j] = self.children[j]
		}
	}
	recalculateCount(newMap)
	return newMap, true
}

// delete the leftmost node in a tree returning the node that
// was deleted and the tree left over after its deletion
func (m *tree) deleteLeftmost() (*tree, *tree) {
	if m.isLeaf() {
		return m, nilMap
	}

	for i, t := range m.children {
		if t != nilMap {
			deleted, child := t.deleteLeftmost()
			newMap := m.clone()
			newMap.children[i] = child
			recalculateCount(newMap)
			return deleted, newMap
		}
	}
	panic("Tree isn't a leaf but also had no children. How does that happen?")
}

// isLeaf returns true if this is a leaf node
func (m *tree) isLeaf() bool {
	return m.Size() == 1
}

// returns the number of child subtrees we have
func (m *tree) subtreeCount() int {
	count := 0
	for _, t := range m.children {
		if t != nilMap {
			count++
		}
	}
	return count
}

func (m *tree) Lookup(key string) (interface{}, bool) {
	hash := hashKey(key)
	return lookupLowLevel(m, hash, hash)
}

func lookupLowLevel(self *tree, partialHash, hash uint64) (interface{}, bool) {
	if self.IsNil() { // an empty tree is easy
		return nil, false
	}

	if hash != self.hash {
		i := partialHash % childCount
		return lookupLowLevel(self.children[i], partialHash>>shiftSize, hash)
	}

	// we found it
	return self.value, true
}

func (m *tree) Size() int {
	return m.count
}

func (m *tree) ForEach(f func(key string, val interface{})) {
	if m.IsNil() {
		return
	}

	// ourself
	f(m.key, m.value)

	// children
	for _, t := range m.children {
		if t != nilMap {
			t.ForEach(f)
		}
	}
}

func (m *tree) Keys() []string {
	keys := make([]string, m.Size())
	i := 0
	m.ForEach(func(k string, v interface{}) {
		keys[i] = k
		i++
	})
	return keys
}

// make it easier to display maps for debugging
func (m *tree) String() string {
	keys := m.Keys()
	buf := bytes.NewBufferString("{")
	for _, key := range keys {
		val, _ := m.Lookup(key)
		fmt.Fprintf(buf, "%s: %s, ", key, val)
	}
	fmt.Fprintf(buf, "}\n")
	return buf.String()
}
<commit_msg>Bring back public Any type<commit_after>// Fully persistent data structures. A persistent data structure is a data
// structure that always preserves the previous version of itself when
// it is modified. Such data structures are effectively immutable,
// as their operations do not update the structure in-place, but instead
// always yield a new structure.
//
// Persistent
// data structures typically share structure among themselves.  This allows
// operations to avoid copying the entire data structure.
package ps

import (
	"bytes"
	"fmt"
)

// Any is a shorthand for Go's verbose interface{} type.
// Usage of this type is deprecated.  It will be removed sometime
// after May 2016.
type Any interface{}

// A Map associates unique keys (type string) with values (type Any).
type Map interface {
	// IsNil returns true if the Map is empty
	IsNil() bool

	// Set returns a new map in which key and value are associated.
	// If the key didn't exist before, it's created; otherwise, the
	// associated value is changed.
	// This operation is O(log N) in the number of keys.
	Set(key string, value interface{}) Map

	// Delete returns a new map with the association for key, if any, removed.
	// This operation is O(log N) in the number of keys.
	Delete(key string) Map

	// Lookup returns the value associated with a key, if any.  If the key
	// exists, the second return value is true; otherwise, false.
	// This operation is O(log N) in the number of keys.
	Lookup(key string) (interface{}, bool)

	// Size returns the number of key value pairs in the map.
	// This takes O(1) time.
	Size() int

	// ForEach executes a callback on each key value pair in the map.
	ForEach(f func(key string, val interface{}))

	// Keys returns a slice with all keys in this map.
	// This operation is O(N) in the number of keys.
	Keys() []string

	String() string
}

// Immutable (i.e. persistent) associative array
const childCount = 8
const shiftSize = 3

type tree struct {
	count    int
	hash     uint64 // hash of the key (used for tree balancing)
	key      string
	value    interface{}
	children [childCount]*tree
}

var nilMap = &tree{}

// Recursively set nilMap's subtrees to point at itself.
// This eliminates all nil pointers in the map structure.
// All map nodes are created by cloning this structure so
// they avoid the problem too.
func init() {
	for i := range nilMap.children {
		nilMap.children[i] = nilMap
	}
}

// NewMap allocates a new, persistent map from strings to values of
// any type.
// This is currently implemented as a path-copying binary tree.
func NewMap() Map {
	return nilMap
}

func (self *tree) IsNil() bool {
	return self == nilMap
}

// clone returns an exact duplicate of a tree node
func (self *tree) clone() *tree {
	var m tree
	m = *self
	return &m
}

// constants for FNV-1a hash algorithm
const (
	offset64 uint64 = 14695981039346656037
	prime64  uint64 = 1099511628211
)

// hashKey returns a hash code for a given string
func hashKey(key string) uint64 {
	hash := offset64
	for _, codepoint := range key {
		hash ^= uint64(codepoint)
		hash *= prime64
	}
	return hash
}

// Set returns a new map similar to this one but with key and value
// associated.  If the key didn't exist, it's created; otherwise, the
// associated value is changed.
func (self *tree) Set(key string, value interface{}) Map {
	hash := hashKey(key)
	return setLowLevel(self, hash, hash, key, value)
}

func setLowLevel(self *tree, partialHash, hash uint64, key string, value interface{}) *tree {
	if self.IsNil() { // an empty tree is easy
		m := self.clone()
		m.count = 1
		m.hash = hash
		m.key = key
		m.value = value
		return m
	}

	if hash != self.hash {
		m := self.clone()
		i := partialHash % childCount
		m.children[i] = setLowLevel(self.children[i], partialHash>>shiftSize, hash, key, value)
		recalculateCount(m)
		return m
	}

	// did we find a hash collision?
	if key != self.key {
		oops := fmt.Sprintf("Hash collision between: '%s' and '%s'.  Please report to https://github.com/mndrix/ps/issues/new", self.key, key)
		panic(oops)
	}

	// replacing a key's previous value
	m := self.clone()
	m.value = value
	return m
}

// modifies a map by recalculating its key count based on the counts
// of its subtrees
func recalculateCount(m *tree) {
	count := 0
	for _, t := range m.children {
		count += t.Size()
	}
	m.count = count + 1 // add one to count ourself
}

func (m *tree) Delete(key string) Map {
	hash := hashKey(key)
	newMap, _ := deleteLowLevel(m, hash, hash)
	return newMap
}

func deleteLowLevel(self *tree, partialHash, hash uint64) (*tree, bool) {
	// empty trees are easy
	if self.IsNil() {
		return self, false
	}

	if hash != self.hash {
		i := partialHash % childCount
		child, found := deleteLowLevel(self.children[i], partialHash>>shiftSize, hash)
		if !found {
			return self, false
		}
		newMap := self.clone()
		newMap.children[i] = child
		recalculateCount(newMap)
		return newMap, true // ? this wasn't in the original code
	}

	// we must delete our own node
	if self.isLeaf() { // we have no children
		return nilMap, true
	}
	/*
	   if self.subtreeCount() == 1 { // only one subtree
	       for _, t := range self.children {
	           if t != nilMap {
	               return t, true
	           }
	       }
	       panic("Tree with 1 subtree actually had no subtrees")
	   }
	*/

	// find a node to replace us
	i := -1
	size := -1
	for j, t := range self.children {
		if t.Size() > size {
			i = j
			size = t.Size()
		}
	}

	// make chosen leaf smaller
	replacement, child := self.children[i].deleteLeftmost()
	newMap := replacement.clone()
	for j := range self.children {
		if j == i {
			newMap.children[j] = child
		} else {
			newMap.children[j] = self.children[j]
		}
	}
	recalculateCount(newMap)
	return newMap, true
}

// delete the leftmost node in a tree returning the node that
// was deleted and the tree left over after its deletion
func (m *tree) deleteLeftmost() (*tree, *tree) {
	if m.isLeaf() {
		return m, nilMap
	}

	for i, t := range m.children {
		if t != nilMap {
			deleted, child := t.deleteLeftmost()
			newMap := m.clone()
			newMap.children[i] = child
			recalculateCount(newMap)
			return deleted, newMap
		}
	}
	panic("Tree isn't a leaf but also had no children. How does that happen?")
}

// isLeaf returns true if this is a leaf node
func (m *tree) isLeaf() bool {
	return m.Size() == 1
}

// returns the number of child subtrees we have
func (m *tree) subtreeCount() int {
	count := 0
	for _, t := range m.children {
		if t != nilMap {
			count++
		}
	}
	return count
}

func (m *tree) Lookup(key string) (interface{}, bool) {
	hash := hashKey(key)
	return lookupLowLevel(m, hash, hash)
}

func lookupLowLevel(self *tree, partialHash, hash uint64) (interface{}, bool) {
	if self.IsNil() { // an empty tree is easy
		return nil, false
	}

	if hash != self.hash {
		i := partialHash % childCount
		return lookupLowLevel(self.children[i], partialHash>>shiftSize, hash)
	}

	// we found it
	return self.value, true
}

func (m *tree) Size() int {
	return m.count
}

func (m *tree) ForEach(f func(key string, val interface{})) {
	if m.IsNil() {
		return
	}

	// ourself
	f(m.key, m.value)

	// children
	for _, t := range m.children {
		if t != nilMap {
			t.ForEach(f)
		}
	}
}

func (m *tree) Keys() []string {
	keys := make([]string, m.Size())
	i := 0
	m.ForEach(func(k string, v interface{}) {
		keys[i] = k
		i++
	})
	return keys
}

// make it easier to display maps for debugging
func (m *tree) String() string {
	keys := m.Keys()
	buf := bytes.NewBufferString("{")
	for _, key := range keys {
		val, _ := m.Lookup(key)
		fmt.Fprintf(buf, "%s: %s, ", key, val)
	}
	fmt.Fprintf(buf, "}\n")
	return buf.String()
}
<|endoftext|>


<commit_before>// Package main provides ...
package main

import (
    "fmt"
)

func main() {
    //define a map
    m := make(map[string]int)
    m["k1"] = 1
    m["k2"] = 2
    fmt.Println("define then assign map: ", m)

    //define and assign a map
    m2 := map[string]int{"k1": 1, "k2": 2}
    fmt.Println("define and assign map: ", m2)

    //judge whether a key is in a map
    _, prs := m["k2"]
    fmt.Println("k2 in map: ", prs)
    _, prs2 := m["k3"]
    fmt.Println("k3 in map: ", prs2)
}
<commit_msg>add map.go<commit_after>// Package main provides ...
package main

import (
    "fmt"
)

func main() {
    //define a map
    m := make(map[string]int)
    m["k1"] = 1
    m["k2"] = 2
    fmt.Println("define then assign map: ", m)

    //define and assign a map
    m2 := map[string]int{"k1": 1, "k2": 2}
    fmt.Println("define and assign map: ", m2)

    //judge whether a key is in a map
    _, prs := m["k2"]
    fmt.Println("k2 in map: ", prs)
    _, prs2 := m["k3"]
    fmt.Println("k3 in map: ", prs2)

    //delete a key
    delete(m, "k3")
    fmt.Println("after delete: ", m)
    //remove key
}
<|endoftext|>


<commit_before>package datagovsg

import (
	"encoding/json"
	"golang.org/x/net/context"
	"net/http"
	"sync"
)

// ClientResult contains the result from the HTTP request from Client
type ClientResult struct {
	Body interface{}
	Err  error
}

// Client is a special HTTP client that batches HTTP requests for the same URL, returning requests through channels
type Client struct {
	APIKey string

	listeners    map[string][]chan ClientResult
	listenerLock sync.RWMutex
}

// NewClient returns a new Client
func NewClient(apiKey string) *Client {
	return &Client{
		APIKey:       apiKey,
		listeners:    map[string][]chan ClientResult{},
		listenerLock: sync.RWMutex{},
	}
}

func GetClientFromContext(ctx context.Context) *Client {
	if c, ok := ctx.Value("client").(*Client); ok {
		return c
	}
	return NewClient("")
}

// broadcastOnce Broadcasts to all listeners and close channel immediately. No new listeners can register at this time.
func (c *Client) broadcastOnce(url string, result ClientResult) {
	c.listenerLock.Lock()
	listeners, _ := c.listeners[url]
	for _, listener := range listeners {
		listener <- result
		close(listener)
	}

	c.listeners[url] = nil
	delete(c.listeners, url)

	c.listenerLock.Unlock()
}

func (c *Client) register(url string) (ch chan ClientResult, alreadyExists bool) {
	ch = make(chan ClientResult)
	c.listenerLock.Lock()
	_, alreadyExists = c.listeners[url]
	if !alreadyExists {
		c.listeners[url] = []chan ClientResult{}
	}
	c.listeners[url] = append(c.listeners[url], ch)
	c.listenerLock.Unlock()
	return ch, alreadyExists
}

func (c *Client) request(method string, url string, target interface{}) chan ClientResult {

	ch, alreadyExists := c.register(url)
	if alreadyExists {
		return ch
	}

	// set up go-routine to make batched request
	go func(url string) {

		// create request
		req, err := http.NewRequest(method, url, nil)
		if err != nil {
			c.broadcastOnce(url, ClientResult{
				Err: err,
			})
			return
		}

		// set API Key
		req.Header.Set("api-key", c.APIKey)

		// make HTTP request
		client := &http.Client{}
		res, err := client.Do(req)
		if err != nil {
			c.broadcastOnce(url, ClientResult{
				Err: err,
			})
			return
		}
		defer res.Body.Close()

		// decode as JSON response
		err = json.NewDecoder(res.Body).Decode(target)

		c.broadcastOnce(url, ClientResult{
			Body: target,
			Err:  err,
		})

	}(url)
	return ch
}

// Get allows user to make a /GET HTTP request, getting it through a channel.
func (c *Client) Get(url string, target interface{}) chan ClientResult {
	return c.request("GET", url, target)
}
<commit_msg>Reduced rw-lock time<commit_after>package datagovsg

import (
	"encoding/json"
	"golang.org/x/net/context"
	"net/http"
	"sync"
)

// ClientResult contains the result from the HTTP request from Client
type ClientResult struct {
	Body interface{}
	Err  error
}

// Client is a special HTTP client that batches HTTP requests for the same URL, returning requests through channels
type Client struct {
	APIKey string

	listeners    map[string][]chan ClientResult
	listenerLock sync.RWMutex
}

// NewClient returns a new Client
func NewClient(apiKey string) *Client {
	return &Client{
		APIKey:       apiKey,
		listeners:    map[string][]chan ClientResult{},
		listenerLock: sync.RWMutex{},
	}
}

func GetClientFromContext(ctx context.Context) *Client {
	if c, ok := ctx.Value("client").(*Client); ok {
		return c
	}
	return NewClient("")
}

// broadcastOnce Broadcasts to all listeners and close channel immediately. No new listeners can register at this time.
func (c *Client) broadcastOnce(url string, result ClientResult) {
	c.listenerLock.Lock()
	listeners, _ := c.listeners[url]
	c.listeners[url] = nil
	delete(c.listeners, url)
	c.listenerLock.Unlock()

	for _, listener := range listeners {
		listener <- result
		close(listener)
	}
}

func (c *Client) register(url string) (ch chan ClientResult, alreadyExists bool) {
	ch = make(chan ClientResult)
	c.listenerLock.Lock()
	_, alreadyExists = c.listeners[url]
	if !alreadyExists {
		c.listeners[url] = []chan ClientResult{}
	}
	c.listeners[url] = append(c.listeners[url], ch)
	c.listenerLock.Unlock()
	return ch, alreadyExists
}

func (c *Client) request(method string, url string, target interface{}) chan ClientResult {

	ch, alreadyExists := c.register(url)
	if alreadyExists {
		return ch
	}

	// set up go-routine to make batched request
	go func(url string) {

		// create request
		req, err := http.NewRequest(method, url, nil)
		if err != nil {
			c.broadcastOnce(url, ClientResult{
				Err: err,
			})
			return
		}

		// set API Key
		req.Header.Set("api-key", c.APIKey)

		// make HTTP request
		client := &http.Client{}
		res, err := client.Do(req)
		if err != nil {
			c.broadcastOnce(url, ClientResult{
				Err: err,
			})
			return
		}
		defer res.Body.Close()

		// decode as JSON response
		err = json.NewDecoder(res.Body).Decode(target)

		c.broadcastOnce(url, ClientResult{
			Body: target,
			Err:  err,
		})

	}(url)
	return ch
}

// Get allows user to make a /GET HTTP request, getting it through a channel.
func (c *Client) Get(url string, target interface{}) chan ClientResult {
	return c.request("GET", url, target)
}
<|endoftext|>


<commit_before>package gonumbers

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestNumberToHuman(t *testing.T) {

	a := assert.New(t)

	//Test with defaults

	a.Equal("1.234 Thousand", NumberToHuman(1234))
	a.Equal("12.3 Thousand", NumberToHuman(12345))
	a.Equal("123.4 Thousand", NumberToHuman(123456))

	a.Equal("1.234 Million", NumberToHuman(1234567))
	a.Equal("12.3 Million", NumberToHuman(12345678))
	a.Equal("123.4 Million", NumberToHuman(123456789))

	a.Equal("123 Million", NumberToHuman(123000000))

	//Custom

	a.Equal("1,234 Thousand", NumberToHuman(1234, "separator:,"))
	a.Equal("1234", NumberToHuman(1234, "precision:4"))
	a.Equal("0.01234", NumberToHuman(1234, "precision:5"))
	a.Equal("0,01234", NumberToHuman(1234, "precision:5", "separator:,"))
	// a.Equal("12.3 Thousand", NumberToHuman(12345))
	// a.Equal("123.4 Thousand", NumberToHuman(123456))

	// a.Equal("1.234 Million", NumberToHuman(1234567))
	// a.Equal("12.3 Million", NumberToHuman(12345678))
	// a.Equal("123.4 Million", NumberToHuman(123456789))

	// a.Equal("123 Million", NumberToHuman(123000000))

}
<commit_msg>remove unused extra tests<commit_after>package gonumbers

import (
	"testing"

	"github.com/stretchr/testify/assert"
)

func TestNumberToHuman(t *testing.T) {

	a := assert.New(t)

	//Test with defaults

	a.Equal("1.234 Thousand", NumberToHuman(1234))
	a.Equal("12.3 Thousand", NumberToHuman(12345))
	a.Equal("123.4 Thousand", NumberToHuman(123456))

	a.Equal("1.234 Million", NumberToHuman(1234567))
	a.Equal("12.3 Million", NumberToHuman(12345678))
	a.Equal("123.4 Million", NumberToHuman(123456789))

	a.Equal("123 Million", NumberToHuman(123000000))

	//Custom

	a.Equal("1,234 Thousand", NumberToHuman(1234, "separator:,"))
	a.Equal("1234", NumberToHuman(1234, "precision:4"))
	a.Equal("0.01234", NumberToHuman(1234, "precision:5"))
	a.Equal("0,01234", NumberToHuman(1234, "precision:5", "separator:,"))

}
<|endoftext|>


<commit_before>package nsf

import (
	"errors"
	"io"
	"io/ioutil"
	"time"

	"github.com/mjibson/mog/codec/nsf/cpu6502"
)

const (
	// 1.79 MHz
	cpuClock   = 236250000 / 11 / 12
	SampleRate = 44100
)

var (
	ErrUnrecognized = errors.New("nsf: unrecognized format")
)

const (
	NSF_HEADER_LEN = 0x80
	NSF_VERSION    = 0x5
	NSF_SONGS      = 0x6
	NSF_START      = 0x7
	NSF_LOAD       = 0x8
	NSF_INIT       = 0xa
	NSF_PLAY       = 0xc
	NSF_SONG       = 0xe
	NSF_ARTIST     = 0x2e
	NSF_COPYRIGHT  = 0x4e
	NSF_SPEED_NTSC = 0x6e
	NSF_BANKSWITCH = 0x70
	NSF_SPEED_PAL  = 0x78
	NSF_PAL_NTSC   = 0x7a
	NSF_EXTRA      = 0x7b
	NSF_ZERO       = 0x7c
)

func ReadNSF(r io.Reader) (n *NSF, err error) {
	n = &NSF{}
	n.b, err = ioutil.ReadAll(r)
	if err != nil {
		return
	}
	if len(n.b) < NSF_HEADER_LEN ||
		string(n.b[0:NSF_VERSION]) != "NESM\u001a" {
		return nil, ErrUnrecognized
	}
	n.Version = n.b[NSF_VERSION]
	n.Songs = n.b[NSF_SONGS]
	n.Start = n.b[NSF_START]
	n.LoadAddr = bLEtoUint16(n.b[NSF_LOAD:])
	n.InitAddr = bLEtoUint16(n.b[NSF_INIT:])
	n.PlayAddr = bLEtoUint16(n.b[NSF_PLAY:])
	n.Song = bToString(n.b[NSF_SONG:])
	n.Artist = bToString(n.b[NSF_ARTIST:])
	n.Copyright = bToString(n.b[NSF_COPYRIGHT:])
	n.SpeedNTSC = bLEtoUint16(n.b[NSF_SPEED_NTSC:])
	copy(n.Bankswitch[:], n.b[NSF_BANKSWITCH:NSF_SPEED_PAL])
	n.SpeedPAL = bLEtoUint16(n.b[NSF_SPEED_PAL:])
	n.PALNTSC = n.b[NSF_PAL_NTSC]
	n.Extra = n.b[NSF_EXTRA]
	n.Data = n.b[NSF_HEADER_LEN:]
	return
}

type NSF struct {
	*Ram
	*cpu6502.Cpu

	b []byte // raw NSF data

	Version byte
	Songs   byte
	Start   byte

	LoadAddr uint16
	InitAddr uint16
	PlayAddr uint16

	Song      string
	Artist    string
	Copyright string

	SpeedNTSC  uint16
	Bankswitch [8]byte
	SpeedPAL   uint16
	PALNTSC    byte
	Extra      byte
	Data       []byte

	totalTicks  int64
	frameTicks  int64
	sampleTicks int64
	playTicks   int64
	samples     []float32
}

func (n *NSF) Tick() {
	n.Ram.A.Step()
	n.totalTicks++
	n.frameTicks++
	if n.frameTicks == cpuClock/240 {
		n.frameTicks = 0
		n.Ram.A.FrameStep()
	}
	n.sampleTicks++
	if n.sampleTicks >= cpuClock/SampleRate {
		n.sampleTicks = 0
		n.samples = append(n.samples, n.Ram.A.Volume())
	}
	n.playTicks++
}

func (n *NSF) Init(song byte) {
	n.Ram = new(Ram)
	n.Cpu = cpu6502.New(n.Ram)
	copy(n.Ram.M[n.LoadAddr:], n.Data)
	n.Ram.A.Init()
	n.Cpu.A = song - 1
	n.Cpu.PC = n.InitAddr
	n.Cpu.T = nil
	n.Cpu.Run()
	n.Cpu.T = n
}

func (n *NSF) Play(d time.Duration) []float32 {
	playDur := time.Duration(n.SpeedNTSC) * time.Nanosecond * 1000
	ticksPerPlay := int64(playDur / (time.Second / cpuClock))
	ticks := int64(d / (time.Second / cpuClock))
	n.samples = make([]float32, 0)
	n.totalTicks = 0
	for n.totalTicks < ticks {
		n.playTicks = 0
		n.Cpu.PC = n.PlayAddr
		n.Cpu.Halt = false
		for !n.Cpu.Halt && n.totalTicks < ticks {
			n.Cpu.Step()
			if !n.Cpu.I() {
				panic("INTERRUPT")
			}
		}
		for i := ticksPerPlay - n.playTicks; i > 0 && n.totalTicks < ticks; i-- {
			n.Tick()
		}
	}
	return n.samples
}

// little-endian [2]byte to uint16 conversion
func bLEtoUint16(b []byte) uint16 {
	return uint16(b[1])<<8 + uint16(b[0])
}

// null-terminated bytes to string
func bToString(b []byte) string {
	i := 0
	for i = range b {
		if b[i] == 0 {
			break
		}
	}
	return string(b[:i])
}

type Ram struct {
	M [0xffff + 1]byte
	A Apu
}

func (r *Ram) Read(v uint16) byte {
	if v == 0x4015 {
		return r.A.Read(v)
	} else {
		return r.M[v]
	}
}

func (r *Ram) Write(v uint16, b byte) {
	r.M[v] = b
	if v&0xf000 == 0x4000 {
		r.A.Write(v, b)
	}
}
<commit_msg>Try out a 4-element sample averager<commit_after>package nsf

import (
	"errors"
	"io"
	"io/ioutil"
	"time"

	"github.com/mjibson/mog/codec/nsf/cpu6502"
)

const (
	// 1.79 MHz
	cpuClock   = 236250000 / 11 / 12
	SampleRate = 44100
)

var (
	ErrUnrecognized = errors.New("nsf: unrecognized format")
)

const (
	NSF_HEADER_LEN = 0x80
	NSF_VERSION    = 0x5
	NSF_SONGS      = 0x6
	NSF_START      = 0x7
	NSF_LOAD       = 0x8
	NSF_INIT       = 0xa
	NSF_PLAY       = 0xc
	NSF_SONG       = 0xe
	NSF_ARTIST     = 0x2e
	NSF_COPYRIGHT  = 0x4e
	NSF_SPEED_NTSC = 0x6e
	NSF_BANKSWITCH = 0x70
	NSF_SPEED_PAL  = 0x78
	NSF_PAL_NTSC   = 0x7a
	NSF_EXTRA      = 0x7b
	NSF_ZERO       = 0x7c
)

func ReadNSF(r io.Reader) (n *NSF, err error) {
	n = &NSF{}
	n.b, err = ioutil.ReadAll(r)
	if err != nil {
		return
	}
	if len(n.b) < NSF_HEADER_LEN ||
		string(n.b[0:NSF_VERSION]) != "NESM\u001a" {
		return nil, ErrUnrecognized
	}
	n.Version = n.b[NSF_VERSION]
	n.Songs = n.b[NSF_SONGS]
	n.Start = n.b[NSF_START]
	n.LoadAddr = bLEtoUint16(n.b[NSF_LOAD:])
	n.InitAddr = bLEtoUint16(n.b[NSF_INIT:])
	n.PlayAddr = bLEtoUint16(n.b[NSF_PLAY:])
	n.Song = bToString(n.b[NSF_SONG:])
	n.Artist = bToString(n.b[NSF_ARTIST:])
	n.Copyright = bToString(n.b[NSF_COPYRIGHT:])
	n.SpeedNTSC = bLEtoUint16(n.b[NSF_SPEED_NTSC:])
	copy(n.Bankswitch[:], n.b[NSF_BANKSWITCH:NSF_SPEED_PAL])
	n.SpeedPAL = bLEtoUint16(n.b[NSF_SPEED_PAL:])
	n.PALNTSC = n.b[NSF_PAL_NTSC]
	n.Extra = n.b[NSF_EXTRA]
	n.Data = n.b[NSF_HEADER_LEN:]
	return
}

type NSF struct {
	*Ram
	*cpu6502.Cpu

	b []byte // raw NSF data

	Version byte
	Songs   byte
	Start   byte

	LoadAddr uint16
	InitAddr uint16
	PlayAddr uint16

	Song      string
	Artist    string
	Copyright string

	SpeedNTSC  uint16
	Bankswitch [8]byte
	SpeedPAL   uint16
	PALNTSC    byte
	Extra      byte
	Data       []byte

	totalTicks  int64
	frameTicks  int64
	sampleTicks int64
	playTicks   int64
	samples     []float32
	prevs       [4]float32
	pi          int // prevs index
}

func (n *NSF) Tick() {
	n.Ram.A.Step()
	n.totalTicks++
	n.frameTicks++
	if n.frameTicks == cpuClock/240 {
		n.frameTicks = 0
		n.Ram.A.FrameStep()
	}
	n.sampleTicks++
	if n.sampleTicks >= cpuClock/SampleRate {
		n.sampleTicks = 0
		n.append(n.Ram.A.Volume())
	}
	n.playTicks++
}

func (n *NSF) append(v float32) {
	n.prevs[n.pi] = v
	n.pi++
	if n.pi >= len(n.prevs) {
		n.pi = 0
	}
	var sum float32
	for _, s := range n.prevs {
		sum += s
	}
	sum /= float32(len(n.prevs))
	n.samples = append(n.samples, sum)
}

func (n *NSF) Init(song byte) {
	n.Ram = new(Ram)
	n.Cpu = cpu6502.New(n.Ram)
	copy(n.Ram.M[n.LoadAddr:], n.Data)
	n.Ram.A.Init()
	n.Cpu.A = song - 1
	n.Cpu.PC = n.InitAddr
	n.Cpu.T = nil
	n.Cpu.Run()
	n.Cpu.T = n
}

func (n *NSF) Play(d time.Duration) []float32 {
	playDur := time.Duration(n.SpeedNTSC) * time.Nanosecond * 1000
	ticksPerPlay := int64(playDur / (time.Second / cpuClock))
	ticks := int64(d / (time.Second / cpuClock))
	n.samples = make([]float32, 0)
	n.totalTicks = 0
	for n.totalTicks < ticks {
		n.playTicks = 0
		n.Cpu.PC = n.PlayAddr
		n.Cpu.Halt = false
		for !n.Cpu.Halt && n.totalTicks < ticks {
			n.Cpu.Step()
			if !n.Cpu.I() {
				panic("INTERRUPT")
			}
		}
		for i := ticksPerPlay - n.playTicks; i > 0 && n.totalTicks < ticks; i-- {
			n.Tick()
		}
	}
	return n.samples
}

// little-endian [2]byte to uint16 conversion
func bLEtoUint16(b []byte) uint16 {
	return uint16(b[1])<<8 + uint16(b[0])
}

// null-terminated bytes to string
func bToString(b []byte) string {
	i := 0
	for i = range b {
		if b[i] == 0 {
			break
		}
	}
	return string(b[:i])
}

type Ram struct {
	M [0xffff + 1]byte
	A Apu
}

func (r *Ram) Read(v uint16) byte {
	if v == 0x4015 {
		return r.A.Read(v)
	} else {
		return r.M[v]
	}
}

func (r *Ram) Write(v uint16, b byte) {
	r.M[v] = b
	if v&0xf000 == 0x4000 {
		r.A.Write(v, b)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"go/build"
	"log"
	"os"
	"path/filepath"
)

var (
	ctx = build.Default
)

func init() {
	ctx.UseAllFiles = true
}

func collectAllDeps(wd string, initPkgs ...*build.Package) ([]*build.Package, error) {
	pkgCache := make(map[string]*build.Package)
	var deps []*build.Package
	for _, pkg := range initPkgs {
		pkgCache[pkg.ImportPath] = pkg
		deps = append(deps, pkg)
	}
	for {
		var newDeps []*build.Package
		for _, pkg := range deps {
			if pkg.Goroot {
				continue
			}
			for _, imp := range pkg.Imports {
				if imp == "C" {
					continue
				}
				pkg, err := ctx.Import(imp, wd, build.AllowVendor)
				if pkg.Goroot {
					continue
				}
				if err != nil {
					log.Printf("WARN: unsatisfied dep: %s\n", imp)
					continue
				}
				if _, ok := pkgCache[pkg.ImportPath]; ok {
					continue
				}
				newDeps = append(newDeps, pkg)
			}
			pkgCache[pkg.ImportPath] = pkg
		}
		if len(newDeps) == 0 {
			break
		}
		deps = newDeps
	}
	var pkgs []*build.Package
	for _, pkg := range pkgCache {
		pkgs = append(pkgs, pkg)
	}
	return pkgs, nil
}

func collectPkgs(dir string) ([]*build.Package, error) {
	var pkgs []*build.Package
	err := filepath.Walk(dir, func(path string, i os.FileInfo, err error) error {
		if i == nil {
			return err
		}
		if !i.IsDir() {
			return nil
		}
		// skip vendoring directory itself
		if path == filepath.Join(dir, vendorDir) {
			return filepath.SkipDir
		}
		pkg, err := ctx.ImportDir(path, build.ImportMode(0))
		if err != nil {
			// not a package
			if _, ok := err.(*build.NoGoError); ok {
				return nil
			}
			return err
		}
		pkgs = append(pkgs, pkg)
		return nil
	})
	return pkgs, err
}
<commit_msg>Resolve confusion of names masking<commit_after>package main

import (
	"go/build"
	"log"
	"os"
	"path/filepath"
)

var (
	ctx = build.Default
)

func init() {
	ctx.UseAllFiles = true
}

func collectAllDeps(wd string, initPkgs ...*build.Package) ([]*build.Package, error) {
	pkgCache := make(map[string]*build.Package)
	var deps []*build.Package
	for _, pkg := range initPkgs {
		pkgCache[pkg.ImportPath] = pkg
		deps = append(deps, pkg)
	}
	for {
		var newDeps []*build.Package
		for _, pkg := range deps {
			if pkg.Goroot {
				continue
			}
			for _, imp := range pkg.Imports {
				if imp == "C" {
					continue
				}
				ipkg, err := ctx.Import(imp, wd, build.AllowVendor)
				if ipkg.Goroot {
					continue
				}
				if err != nil {
					log.Printf("WARN: unsatisfied dep: %s for %s\n", imp, pkg.ImportPath)
					continue
				}
				if _, ok := pkgCache[ipkg.ImportPath]; ok {
					continue
				}
				newDeps = append(newDeps, ipkg)
			}
			pkgCache[pkg.ImportPath] = pkg
		}
		if len(newDeps) == 0 {
			break
		}
		deps = newDeps
	}
	var pkgs []*build.Package
	for _, pkg := range pkgCache {
		pkgs = append(pkgs, pkg)
	}
	return pkgs, nil
}

func collectPkgs(dir string) ([]*build.Package, error) {
	var pkgs []*build.Package
	err := filepath.Walk(dir, func(path string, i os.FileInfo, err error) error {
		if i == nil {
			return err
		}
		if !i.IsDir() {
			return nil
		}
		// skip vendoring directory itself
		if path == filepath.Join(dir, vendorDir) {
			return filepath.SkipDir
		}
		pkg, err := ctx.ImportDir(path, build.ImportMode(0))
		if err != nil {
			// not a package
			if _, ok := err.(*build.NoGoError); ok {
				return nil
			}
			return err
		}
		pkgs = append(pkgs, pkg)
		return nil
	})
	return pkgs, err
}
<|endoftext|>


<commit_before>package qpr

import (
    "fmt"
    "io"
    "bytes"
)

const (
    escape string = "="
    maxlinesize int = 76
    emptystring string = ""
    maxchar = "~"
    minchar = " "
)

func NewQPEncoder() (*QPEncoder) {
	qp := new(QPEncoder)
	return qp
}

type QPEncoder struct {
	counter		int
}

func (qp *QPEncoder) quote(b byte, force bool) ([]byte, int) {
	if(force) {
        return []byte(fmt.Sprintf("=%X", b)), len([]byte(fmt.Sprintf("=%X", b)))
	}
	if b < []byte(minchar)[0] || b > []byte(maxchar)[0] {
        return []byte(fmt.Sprintf("=%X", b)), len([]byte(fmt.Sprintf("=%X", b)))
    }
    if b == []byte("=")[0] {
        return []byte(fmt.Sprintf("=%X", b)), len([]byte(fmt.Sprintf("=%X", b)))
    }

    return []byte(string(b)), len([]byte(string(b)))
}

func (qp *QPEncoder) encodeLine(encoded *bytes.Buffer, line *[]byte) {
	*line = bytes.Replace(*line, []byte("\n"), []byte("\r\n"), -1)
	var buf bytes.Buffer
	for index, chr := range *line {
		enc, encLen := qp.quote(chr, false)
		if index == len(*line)-1 && chr == []byte(" ")[0]{
			enc, encLen = qp.quote(chr, true)
		}
		qp.counter += encLen
		if qp.counter > maxlinesize-1 {
			buf.Write([]byte("=\n")) // write newline before enc
			qp.counter = encLen // reset counter after newline
		}
		// set counter to next line's char length
		buf.Write(enc)
	}
    io.Copy(encoded, &buf)

}

func (qp *QPEncoder) Encode(b []byte) ([]byte, error) {
	// split b by newlines
	qp.counter = 0
	var encoded bytes.Buffer
	for _, line := range bytes.Split(b, []byte("\n")) {
		qp.encodeLine(&encoded, &line)
	}

	return encoded.Bytes(), nil
}
<commit_msg>Using CRLF instead of LF<commit_after>package qpr

import (
    "fmt"
    "io"
    "bytes"
)

const (
    escape string = "="
    maxlinesize int = 76
    emptystring string = ""
    maxchar = "~"
    minchar = " "
)

func NewQPEncoder() (*QPEncoder) {
	qp := new(QPEncoder)
	return qp
}

type QPEncoder struct {
	counter		int
}

func (qp *QPEncoder) quote(b byte, force bool) ([]byte, int) {
	if(force) {
        return []byte(fmt.Sprintf("=%X", b)), len([]byte(fmt.Sprintf("=%X", b)))
	}
	if b < []byte(minchar)[0] || b > []byte(maxchar)[0] {
        return []byte(fmt.Sprintf("=%X", b)), len([]byte(fmt.Sprintf("=%X", b)))
    }
    if b == []byte("=")[0] {
        return []byte(fmt.Sprintf("=%X", b)), len([]byte(fmt.Sprintf("=%X", b)))
    }

    return []byte(string(b)), len([]byte(string(b)))
}

func (qp *QPEncoder) encodeLine(encoded *bytes.Buffer, line *[]byte) {
	*line = bytes.Replace(*line, []byte("\n"), []byte("\r\n"), -1)
	var buf bytes.Buffer
	for index, chr := range *line {
		enc, encLen := qp.quote(chr, false)
		if index == len(*line)-1 && chr == []byte(" ")[0]{
			enc, encLen = qp.quote(chr, true)
		}
		qp.counter += encLen
		if qp.counter > maxlinesize-1 {
			buf.Write([]byte("=\r\n")) // write newline before enc
			qp.counter = encLen // reset counter after newline
		}
		// set counter to next line's char length
		buf.Write(enc)
	}
    io.Copy(encoded, &buf)

}

func (qp *QPEncoder) Encode(b []byte) ([]byte, error) {
	// split b by newlines
	qp.counter = 0
	var encoded bytes.Buffer
	for _, line := range bytes.Split(b, []byte("\n")) {
		qp.encodeLine(&encoded, &line)
	}

	return encoded.Bytes(), nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"log"
	"net/http"
	"os"
	"runtime"

	"github.com/garyburd/redigo/redis"
	"github.com/gorilla/mux"
)

type Request struct {
	Urls []string `json:"urls"`
}

type Response struct {
	Recommendations map[string]float32 `json:"recommendations"`
	Err             string             `json:"error"`

	conn redis.Conn
}

func (self *Response) countRecommendations(urls []string) (recommendations map[string]float32, err error) {
	//for url in all urls
	//	for up in user profiles
	//		min(similarity, freq)
	//	max

	return
}

func (self *Response) SetRecommendations(urls []string) (err error) {
	conn, err := redis.Dial("tcp", "127.0.0.1:6379")
	if err != nil {
		return
	}
	defer conn.Close()
	self.conn = conn

	self.Recommendations, err = self.countRecommendations(urls)
	return
}

func recommendHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")

	decoder := json.NewDecoder(r.Body)
	encoder := json.NewEncoder(w)

	req := new(Request)
	resp := &Response{}

	var err error

	defer func() {
		if err != nil {
			log.Println(err)
			resp.Err = err.Error()
		}

		err := encoder.Encode(resp)
		if err != nil {
			log.Println(err)
		}
	}()

	err = decoder.Decode(req)
	if err != nil {
		return
	}

	err = resp.SetRecommendations(req.Urls)
}

func startRecommendationServer() {
	r := mux.NewRouter()
	r.HandleFunc("/recommend", recommendHandler).Methods("POST")
	http.Handle("/", r)

	log.Fatal(http.ListenAndServe(":"+os.Getenv("PORT"), nil))
}

func main() {
	startRecommendationServer()
}

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())
}
<commit_msg>reading profiles from redis<commit_after>package main

import (
	"encoding/json"
	"log"
	"net/http"
	"os"
	"runtime"
	"strconv"
	"strings"

	"github.com/garyburd/redigo/redis"
	"github.com/gorilla/mux"
)

type Request struct {
	Urls []string `json:"urls"`
}

type Response struct {
	Recommendations map[string]float32 `json:"recommendations"`
	Err             string             `json:"error"`

	conn redis.Conn
}

func weightKey(url, profile string) string {
	return strings.Join([]string{url, profile}, "|")
}

func getWeight(conn redis.Conn, url, profile string) (w float64, err error) {
	key := weightKey(url, profile)

	weight, err := redis.String(conn.Do("GET", key))
	if err != nil {
		return
	}

	return strconv.ParseFloat(weight, 64)
}

func setWeight(conn redis.Conn, url, profile string) {
}

func (self *Response) countRecommendations(session []string) (recommendations map[string]float32, err error) {
	urls, err := redis.Strings(self.conn.Do("SMEMBERS", "urls"))
	if err != nil {
		return
	}

	profiles, err := redis.Strings(self.conn.Do("SMEMBERS", "profiles"))
	if err != nil {
		return
	}

	for _, url := range urls {
		for _, profile := range profiles {
			var w float64
			w, err = getWeight(self.conn, url, profile)
			if err != nil {
				return
			}
			log.Println(w)
			//min(similarity, freq)
		}
		//max
	}

	return
}

func (self *Response) SetRecommendations(urls []string) (err error) {
	conn, err := redis.Dial("tcp", "127.0.0.1:6379")
	if err != nil {
		return
	}
	defer conn.Close()
	self.conn = conn

	self.Recommendations, err = self.countRecommendations(urls)
	return
}

func recommendHandler(w http.ResponseWriter, r *http.Request) {
	w.Header().Set("Content-Type", "application/json")

	decoder := json.NewDecoder(r.Body)
	encoder := json.NewEncoder(w)

	req := new(Request)
	resp := &Response{}

	var err error

	defer func() {
		if err != nil {
			log.Println(err)
			resp.Err = err.Error()
		}

		err := encoder.Encode(resp)
		if err != nil {
			log.Println(err)
		}
	}()

	err = decoder.Decode(req)
	if err != nil {
		return
	}

	err = resp.SetRecommendations(req.Urls)
}

func startRecommendationServer() {
	r := mux.NewRouter()
	r.HandleFunc("/recommend", recommendHandler).Methods("POST")
	http.Handle("/", r)

	log.Fatal(http.ListenAndServe(":"+os.Getenv("PORT"), nil))
}

func main() {
	startRecommendationServer()
}

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())
}
<|endoftext|>


<commit_before>package re2

import (
	"io"
	"regexp"
)

type Regexp struct {
	// 元の変数をそのまま使う
	origRe *regexp.Regexp
}

func Match(pattern string, b []byte) (matched bool, err error) {
	return regexp.Match(pattern, b)
}

func MatchReader(pattern string, r io.RuneReader) (matched bool, err error) {
	return regexp.MatchReader(pattern, r)
}

func MatchString(pattern string, s string) (matched bool, err error) {
	return regexp.MatchString(pattern, s)
}

func QuoteMeta(s string) string {
	return regexp.QuoteMeta(s)
}

// test
func Compile(expr string) (*Regexp, error) {
	origRe, err := regexp.Compile(expr)
	re := &Regexp{
		origRe: origRe,
	}
	return re, err
}

// test
func MustCompile(str string) *Regexp {
	re := &Regexp{
		origRe: regexp.MustCompile(str),
	}
	return re
}

// test
func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte {
	return re.origRe.Expand(dst, template, src, match)
}

// test
func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte {
	return re.origRe.ExpandString(dst, template, src, match)
}

// test
func (re *Regexp) Find(b []byte) []byte {
	return re.origRe.Find(b)
}

// test
func (re *Regexp) FindAll(b []byte, n int) [][]byte {
	return re.origRe.FindAll(b, n)
}

func (re *Regexp) FindAllIndex(b []byte, n int) [][]int {
	return re.origRe.FindAllIndex(b, n)
}

func (re *Regexp) FindAllString(s string, n int) []string {
	return re.origRe.FindAllString(s, n)
}

func (re *Regexp) FindAllStringIndex(s string, n int) [][]int {
	return re.origRe.FindAllStringIndex(s, n)
}

func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string {
	return re.origRe.FindAllStringSubmatch(s, n)
}

func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int {
	return re.origRe.FindAllStringSubmatchIndex(s, n)
}

func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte {
	return re.origRe.FindAllSubmatch(b, n)
}

func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int {
	return re.origRe.FindAllSubmatchIndex(b, n)
}

func (re *Regexp) FindIndex(b []byte) (loc []int) {
	return re.origRe.FindIndex(b)
}

func (re *Regexp) FindReaderIndex(r io.RuneReader) (loc []int) {
	return re.origRe.FindReaderIndex(r)
}

func (re *Regexp) FindReaderSubmatchIndex(r io.RuneReader) []int {
	return re.origRe.FindReaderSubmatchIndex(r)
}

func (re *Regexp) FindString(s string) string {
	return re.origRe.FindString(s)
}

func (re *Regexp) FindStringIndex(s string) (loc []int) {
	return re.origRe.FindStringIndex(s)
}

func (re *Regexp) FindStringSubmatch(s string) []string {
	return re.origRe.FindStringSubmatch(s)
}

func (re *Regexp) FindStringSubmatchIndex(s string) []int {
	return re.origRe.FindStringSubmatchIndex(s)
}

func (re *Regexp) FindSubmatch(b []byte) [][]byte {
	return re.origRe.FindSubmatch(b)
}

func (re *Regexp) FindSubmatchIndex(b []byte) []int {
	return re.origRe.FindSubmatchIndex(b)
}

func (re *Regexp) LiteralPrefix() (prefix string, complete bool) {
	return re.origRe.LiteralPrefix()
}

func (re *Regexp) Longest() {
	re.origRe.Longest()
}

func (re *Regexp) Match(b []byte) bool {
	return re.origRe.Match(b)
}

func (re *Regexp) MatchReader(r io.RuneReader) bool {
	return re.origRe.MatchReader(r)
}

func (re *Regexp) MatchString(s string) bool {
	return re.origRe.MatchString(s)
}

func (re *Regexp) NumSubexp() int {
	return re.origRe.NumSubexp()
}

func (re *Regexp) ReplaceAll(src, repl []byte) []byte {
	return re.origRe.ReplaceAll(src, repl)
}

func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte {
	return re.origRe.ReplaceAllFunc(src, repl)
}

func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte {
	return re.origRe.ReplaceAllLiteral(src, repl)
}

func (re *Regexp) ReplaceAllLiteralString(src, repl string) string {
	return re.origRe.ReplaceAllLiteralString(src, repl)
}

func (re *Regexp) ReplaceAllString(src, repl string) string {
	return re.origRe.ReplaceAllString(src, repl)
}

func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string {
	return re.origRe.ReplaceAllStringFunc(src, repl)
}

func (re *Regexp) Split(s string, n int) []string {
	return re.origRe.Split(s, n)
}

func (re *Regexp) String() string {
	return re.origRe.String()
}

func (re *Regexp) SubexpNames() []string {
	return re.origRe.SubexpNames()
}
<commit_msg>ライブラリをcre2ラッパーに置き換え<commit_after>package re2

import (
	"io"
	"regexp"
)

type Regexp struct {
	// 元の変数をそのまま使う
	origRe *regexp.Regexp
}

func Match(pattern string, b []byte) (matched bool, err error) {
	return regexp.Match(pattern, b)
}

func MatchReader(pattern string, r io.RuneReader) (matched bool, err error) {
	return regexp.MatchReader(pattern, r)
}

func MatchString(pattern string, s string) (matched bool, err error) {
	return regexp.MatchString(pattern, s)
}

func QuoteMeta(s string) string {
	return regexp.QuoteMeta(s)
}

func Compile(expr string) (*Regexp, error) {
	origRe, err := regexp.Compile(expr)
	re := &Regexp{
		origRe: origRe,
	}
	return re, err
}

func MustCompile(str string) *Regexp {
	re := &Regexp{
		origRe: regexp.MustCompile(str),
	}
	return re
}

func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte {
	return re.origRe.Expand(dst, template, src, match)
}

func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte {
	return re.origRe.ExpandString(dst, template, src, match)
}

func (re *Regexp) Find(b []byte) []byte {
	return re.origRe.Find(b)
}

func (re *Regexp) FindAll(b []byte, n int) [][]byte {
	return re.origRe.FindAll(b, n)
}

func (re *Regexp) FindAllIndex(b []byte, n int) [][]int {
	return re.origRe.FindAllIndex(b, n)
}

func (re *Regexp) FindAllString(s string, n int) []string {
	return re.origRe.FindAllString(s, n)
}

func (re *Regexp) FindAllStringIndex(s string, n int) [][]int {
	return re.origRe.FindAllStringIndex(s, n)
}

func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string {
	return re.origRe.FindAllStringSubmatch(s, n)
}

func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int {
	return re.origRe.FindAllStringSubmatchIndex(s, n)
}

func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte {
	return re.origRe.FindAllSubmatch(b, n)
}

func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int {
	return re.origRe.FindAllSubmatchIndex(b, n)
}

func (re *Regexp) FindIndex(b []byte) (loc []int) {
	return re.origRe.FindIndex(b)
}

func (re *Regexp) FindReaderIndex(r io.RuneReader) (loc []int) {
	return re.origRe.FindReaderIndex(r)
}

func (re *Regexp) FindReaderSubmatchIndex(r io.RuneReader) []int {
	return re.origRe.FindReaderSubmatchIndex(r)
}

func (re *Regexp) FindString(s string) string {
	return re.origRe.FindString(s)
}

func (re *Regexp) FindStringIndex(s string) (loc []int) {
	return re.origRe.FindStringIndex(s)
}

func (re *Regexp) FindStringSubmatch(s string) []string {
	return re.origRe.FindStringSubmatch(s)
}

func (re *Regexp) FindStringSubmatchIndex(s string) []int {
	return re.origRe.FindStringSubmatchIndex(s)
}

func (re *Regexp) FindSubmatch(b []byte) [][]byte {
	return re.origRe.FindSubmatch(b)
}

func (re *Regexp) FindSubmatchIndex(b []byte) []int {
	return re.origRe.FindSubmatchIndex(b)
}

func (re *Regexp) LiteralPrefix() (prefix string, complete bool) {
	return re.origRe.LiteralPrefix()
}

func (re *Regexp) Longest() {
	re.origRe.Longest()
}

func (re *Regexp) Match(b []byte) bool {
	return re.origRe.Match(b)
}

func (re *Regexp) MatchReader(r io.RuneReader) bool {
	return re.origRe.MatchReader(r)
}

func (re *Regexp) MatchString(s string) bool {
	return re.origRe.MatchString(s)
}

func (re *Regexp) NumSubexp() int {
	return re.origRe.NumSubexp()
}

func (re *Regexp) ReplaceAll(src, repl []byte) []byte {
	return re.origRe.ReplaceAll(src, repl)
}

func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte {
	return re.origRe.ReplaceAllFunc(src, repl)
}

func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte {
	return re.origRe.ReplaceAllLiteral(src, repl)
}

func (re *Regexp) ReplaceAllLiteralString(src, repl string) string {
	return re.origRe.ReplaceAllLiteralString(src, repl)
}

func (re *Regexp) ReplaceAllString(src, repl string) string {
	return re.origRe.ReplaceAllString(src, repl)
}

func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string {
	return re.origRe.ReplaceAllStringFunc(src, repl)
}

func (re *Regexp) Split(s string, n int) []string {
	return re.origRe.Split(s, n)
}

func (re *Regexp) String() string {
	return re.origRe.String()
}

func (re *Regexp) SubexpNames() []string {
	return re.origRe.SubexpNames()
}
<|endoftext|>


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

package curio

import (
	"errors"
	"io"
)

// NewRevByteScanner returns a backward ByteScanner.
func NewRevByteScanner(r io.ReaderAt, offset int64) io.ByteScanner {
	if offset < 0 {
		panic("negative offset is not allowed")
	}
	return &rev{r: r, o: offset + 1, p: -1}
}

const bs = 8 << 10

type rev struct {
	r    io.ReaderAt
	o    int64
	p, q int16
	u    bool
	b    [bs]byte
}

func (r *rev) ReadByte() (c byte, err error) {
	if r.p < 0 {
		if r.o == 0 {
			return 0, io.EOF
		}
		d := int64(bs)
		if r.o < d {
			d = r.o
		}
		r.o -= d
		r.q = int16(d)
		r.p = r.q - 1
		_, err = r.r.ReadAt(r.b[:r.q], r.o)
		if err != nil {
			return
		}
	}
	c = r.b[r.p]
	r.p--
	r.u = true
	return
}

func (r *rev) UnreadByte() error {
	if r.u {
		r.p++
		r.u = false
		return nil
	}
	return errors.New("UnreadByte: previous operation was not a read")
}
<commit_msg>Changed 8k rev buffer to 4k buffer.<commit_after>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package curio

import (
	"errors"
	"io"
)

// NewRevByteScanner returns a backward ByteScanner.
func NewRevByteScanner(r io.ReaderAt, offset int64) io.ByteScanner {
	if offset < 0 {
		panic("negative offset is not allowed")
	}
	return &rev{r: r, o: offset + 1, p: -1}
}

const bs = 4 << 10

type rev struct {
	r    io.ReaderAt
	o    int64
	p, q int16
	u    bool
	b    [bs]byte
}

func (r *rev) ReadByte() (c byte, err error) {
	if r.p < 0 {
		if r.o == 0 {
			return 0, io.EOF
		}
		d := int64(bs)
		if r.o < d {
			d = r.o
		}
		r.o -= d
		r.q = int16(d)
		r.p = r.q - 1
		_, err = r.r.ReadAt(r.b[:r.q], r.o)
		if err != nil {
			return
		}
	}
	c = r.b[r.p]
	r.p--
	r.u = true
	return
}

func (r *rev) UnreadByte() error {
	if r.u {
		r.p++
		r.u = false
		return nil
	}
	return errors.New("UnreadByte: previous operation was not a read")
}
<|endoftext|>


<commit_before>package rin

import (
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/crowdmob/goamz/aws"
	"github.com/crowdmob/goamz/sqs"
)

var SQS *sqs.SQS
var config *Config
var Debug bool
var Runnable bool
var shutdownBeforeExpiration = 3600 * time.Second

var TrapSignals = []os.Signal{
	syscall.SIGHUP,
	syscall.SIGINT,
	syscall.SIGTERM,
	syscall.SIGQUIT,
}

type NoMessageError struct {
	s string
}

func (e NoMessageError) Error() string {
	return e.s
}

type AuthExpiration struct {
	s string
}

func (e AuthExpiration) Error() string {
	return e.s
}

func (e AuthExpiration) String() string {
	return e.s
}

func (e AuthExpiration) Signal() {
}

func getAuth(config *Config) (*aws.Auth, error) {
	if config.Credentials.AWS_ACCESS_KEY_ID != "" && config.Credentials.AWS_SECRET_ACCESS_KEY != "" {
		return &aws.Auth{
			AccessKey: config.Credentials.AWS_ACCESS_KEY_ID,
			SecretKey: config.Credentials.AWS_SECRET_ACCESS_KEY,
		}, nil
	}
	// Otherwise, use IAM Role
	log.Println("[info] Get instance credentials...")
	cred, err := aws.GetInstanceCredentials()
	if err != nil {
		return nil, err
	}
	exptdate, err := time.Parse("2006-01-02T15:04:05Z", cred.Expiration)
	if err != nil {
		return nil, err
	}
	auth := aws.NewAuth(
		cred.AccessKeyId,
		cred.SecretAccessKey,
		cred.Token,
		exptdate,
	)
	return auth, nil
}

func Run(configFile string, batchMode bool) error {
	Runnable = true
	var err error
	log.Println("[info] Loading config:", configFile)
	config, err = LoadConfig(configFile)
	if err != nil {
		return err
	}
	for _, target := range config.Targets {
		log.Println("[info] Define target", target.String())
	}

	auth, err := getAuth(config)
	if err != nil {
		return err
	}
	log.Println("[info] access_key_id:", auth.AccessKey)
	region := aws.GetRegion(config.Credentials.AWS_REGION)
	SQS = sqs.New(*auth, region)

	shutdownCh := make(chan interface{})
	exitCh := make(chan int)
	signalCh := make(chan os.Signal, 1)
	signal.Notify(signalCh, TrapSignals...)

	if !auth.Expiration().IsZero() {
		log.Println("[info] Auth will be expired on", auth.Expiration())
		e := auth.Expiration().Add(-shutdownBeforeExpiration)
		d := e.Sub(time.Now())
		time.AfterFunc(d, func() {
			msg := fmt.Sprintf("Auth will be expired in %s", shutdownBeforeExpiration)
			signalCh <- AuthExpiration{msg}
		})
	}

	// run worker
	if batchMode {
		go func() {
			err := sqsBatch(shutdownCh)
			if err != nil {
				log.Println("[error]", err)
				exitCh <- 1
			}
			exitCh <- 0
		}()
	} else {
		go func() {
			sqsWorker(shutdownCh)
			exitCh <- 0
		}()
	}

	// wait for signal
	var exitCode = 0
	var exitErr error
	select {
	case s := <-signalCh:
		switch sig := s.(type) {
		case syscall.Signal:
			log.Printf("[info] Got signal: %s(%d)", sig, sig)
		case AuthExpiration:
			log.Printf("[info] %s", sig)
			exitErr = sig
		}
		log.Println("[info] Shutting down worker...")
		close(shutdownCh)   // notify shutdown to worker
		exitCode = <-exitCh // wait for shutdown worker
	case exitCode = <-exitCh:
	}

	log.Println("[info] Shutdown.")
	if exitCode != 0 {
		os.Exit(exitCode)
	}
	return exitErr
}

func waitForRetry() {
	log.Println("[warn] Retry after 10 sec.")
	time.Sleep(10 * time.Second)
}

func runnable(ch chan interface{}) bool {
	if !Runnable {
		return false
	}
	select {
	case <-ch:
		// ch closed == shutdown
		Runnable = false
		return false
	default:
	}
	return true
}

func sqsBatch(ch chan interface{}) error {
	log.Printf("[info] Starting up SQS Batch")
	defer log.Println("[info] Shutdown SQS Batch")

	log.Println("[info] Connect to SQS:", config.QueueName)
	queue, err := SQS.GetQueue(config.QueueName)
	if err != nil {
		return err
	}
	for runnable(ch) {
		err := handleMessage(queue)
		if err != nil {
			if _, ok := err.(NoMessageError); ok {
				break
			} else {
				return err
			}
		}
	}
	return nil
}

func sqsWorker(ch chan interface{}) {
	log.Printf("[info] Starting up SQS Worker")
	defer log.Println("[info] Shutdown SQS Worker")

	for runnable(ch) {
		log.Println("[info] Connect to SQS:", config.QueueName)
		queue, err := SQS.GetQueue(config.QueueName)
		if err != nil {
			log.Println("[error] Can't get queue:", err)
			waitForRetry()
			continue
		}
		quit, err := handleQueue(queue, ch)
		if err != nil {
			log.Println("[error] Processing failed:", err)
			waitForRetry()
			continue
		}
		if quit {
			break
		}
	}
}

func handleQueue(queue *sqs.Queue, ch chan interface{}) (bool, error) {
	for runnable(ch) {
		err := handleMessage(queue)
		if err != nil {
			if _, ok := err.(NoMessageError); ok {
				continue
			} else {
				return false, err
			}
		}
	}
	return true, nil
}

func handleMessage(queue *sqs.Queue) error {
	var completed = false
	res, err := queue.ReceiveMessage(1)
	if err != nil {
		return err
	}
	if len(res.Messages) == 0 {
		return NoMessageError{"No messages"}
	}
	msg := res.Messages[0]
	log.Printf("[info] [%s] Starting process message.", msg.MessageId)
	if Debug {
		log.Printf("[degug] [%s] handle: %s", msg.MessageId, msg.ReceiptHandle)
		log.Printf("[debug] [%s] body: %s", msg.MessageId, msg.Body)
	}
	defer func() {
		if !completed {
			log.Printf("[info] [%s] Aborted message.", msg.MessageId)
		}
	}()

	event, err := ParseEvent([]byte(msg.Body))
	if err != nil {
		log.Printf("[error] [%s] Can't parse event from Body.", msg.MessageId, err)
		return err
	}
	log.Printf("[info] [%s] Importing event: %s", msg.MessageId, event)
	n, err := Import(event)
	if err != nil {
		log.Printf("[error] [%s] Import failed. %s", msg.MessageId, err)
		return err
	}
	if n == 0 {
		log.Printf("[warn] [%s] All events were not matched for any targets. Ignored.", msg.MessageId)
	} else {
		log.Printf("[info] [%s] %d import action completed.", msg.MessageId, n)
	}
	_, err = queue.DeleteMessage(&msg)
	if err != nil {
		log.Printf("[error] [%s] Can't delete message. %s", msg.MessageId, err)
	}
	completed = true
	log.Printf("[info] [%s] Completed message.", msg.MessageId)
	return nil
}
<commit_msg>switch from crowdmob/goamz to AdRoll/goamz<commit_after>package rin

import (
	"fmt"
	"log"
	"os"
	"os/signal"
	"syscall"
	"time"

	"github.com/AdRoll/goamz/aws"
	"github.com/AdRoll/goamz/sqs"
)

var SQS *sqs.SQS
var config *Config
var Debug bool
var Runnable bool
var shutdownBeforeExpiration = 3600 * time.Second

var TrapSignals = []os.Signal{
	syscall.SIGHUP,
	syscall.SIGINT,
	syscall.SIGTERM,
	syscall.SIGQUIT,
}

type NoMessageError struct {
	s string
}

func (e NoMessageError) Error() string {
	return e.s
}

type AuthExpiration struct {
	s string
}

func (e AuthExpiration) Error() string {
	return e.s
}

func (e AuthExpiration) String() string {
	return e.s
}

func (e AuthExpiration) Signal() {
}

func getAuth(config *Config) (*aws.Auth, error) {
	if config.Credentials.AWS_ACCESS_KEY_ID != "" && config.Credentials.AWS_SECRET_ACCESS_KEY != "" {
		return &aws.Auth{
			AccessKey: config.Credentials.AWS_ACCESS_KEY_ID,
			SecretKey: config.Credentials.AWS_SECRET_ACCESS_KEY,
		}, nil
	}
	// Otherwise, use IAM Role
	log.Println("[info] Get instance credentials...")
	cred, err := aws.GetInstanceCredentials()
	if err != nil {
		return nil, err
	}
	exptdate, err := time.Parse("2006-01-02T15:04:05Z", cred.Expiration)
	if err != nil {
		return nil, err
	}
	auth := aws.NewAuth(
		cred.AccessKeyId,
		cred.SecretAccessKey,
		cred.Token,
		exptdate,
	)
	return auth, nil
}

func Run(configFile string, batchMode bool) error {
	Runnable = true
	var err error
	log.Println("[info] Loading config:", configFile)
	config, err = LoadConfig(configFile)
	if err != nil {
		return err
	}
	for _, target := range config.Targets {
		log.Println("[info] Define target", target.String())
	}

	auth, err := getAuth(config)
	if err != nil {
		return err
	}
	log.Println("[info] access_key_id:", auth.AccessKey)
	region := aws.GetRegion(config.Credentials.AWS_REGION)
	SQS = sqs.New(*auth, region)

	shutdownCh := make(chan interface{})
	exitCh := make(chan int)
	signalCh := make(chan os.Signal, 1)
	signal.Notify(signalCh, TrapSignals...)

	if !auth.Expiration().IsZero() {
		log.Println("[info] Auth will be expired on", auth.Expiration())
		e := auth.Expiration().Add(-shutdownBeforeExpiration)
		d := e.Sub(time.Now())
		time.AfterFunc(d, func() {
			msg := fmt.Sprintf("Auth will be expired in %s", shutdownBeforeExpiration)
			signalCh <- AuthExpiration{msg}
		})
	}

	// run worker
	if batchMode {
		go func() {
			err := sqsBatch(shutdownCh)
			if err != nil {
				log.Println("[error]", err)
				exitCh <- 1
			}
			exitCh <- 0
		}()
	} else {
		go func() {
			sqsWorker(shutdownCh)
			exitCh <- 0
		}()
	}

	// wait for signal
	var exitCode = 0
	var exitErr error
	select {
	case s := <-signalCh:
		switch sig := s.(type) {
		case syscall.Signal:
			log.Printf("[info] Got signal: %s(%d)", sig, sig)
		case AuthExpiration:
			log.Printf("[info] %s", sig)
			exitErr = sig
		}
		log.Println("[info] Shutting down worker...")
		close(shutdownCh)   // notify shutdown to worker
		exitCode = <-exitCh // wait for shutdown worker
	case exitCode = <-exitCh:
	}

	log.Println("[info] Shutdown.")
	if exitCode != 0 {
		os.Exit(exitCode)
	}
	return exitErr
}

func waitForRetry() {
	log.Println("[warn] Retry after 10 sec.")
	time.Sleep(10 * time.Second)
}

func runnable(ch chan interface{}) bool {
	if !Runnable {
		return false
	}
	select {
	case <-ch:
		// ch closed == shutdown
		Runnable = false
		return false
	default:
	}
	return true
}

func sqsBatch(ch chan interface{}) error {
	log.Printf("[info] Starting up SQS Batch")
	defer log.Println("[info] Shutdown SQS Batch")

	log.Println("[info] Connect to SQS:", config.QueueName)
	queue, err := SQS.GetQueue(config.QueueName)
	if err != nil {
		return err
	}
	for runnable(ch) {
		err := handleMessage(queue)
		if err != nil {
			if _, ok := err.(NoMessageError); ok {
				break
			} else {
				return err
			}
		}
	}
	return nil
}

func sqsWorker(ch chan interface{}) {
	log.Printf("[info] Starting up SQS Worker")
	defer log.Println("[info] Shutdown SQS Worker")

	for runnable(ch) {
		log.Println("[info] Connect to SQS:", config.QueueName)
		queue, err := SQS.GetQueue(config.QueueName)
		if err != nil {
			log.Println("[error] Can't get queue:", err)
			waitForRetry()
			continue
		}
		quit, err := handleQueue(queue, ch)
		if err != nil {
			log.Println("[error] Processing failed:", err)
			waitForRetry()
			continue
		}
		if quit {
			break
		}
	}
}

func handleQueue(queue *sqs.Queue, ch chan interface{}) (bool, error) {
	for runnable(ch) {
		err := handleMessage(queue)
		if err != nil {
			if _, ok := err.(NoMessageError); ok {
				continue
			} else {
				return false, err
			}
		}
	}
	return true, nil
}

func handleMessage(queue *sqs.Queue) error {
	var completed = false
	res, err := queue.ReceiveMessage(1)
	if err != nil {
		return err
	}
	if len(res.Messages) == 0 {
		return NoMessageError{"No messages"}
	}
	msg := res.Messages[0]
	log.Printf("[info] [%s] Starting process message.", msg.MessageId)
	if Debug {
		log.Printf("[degug] [%s] handle: %s", msg.MessageId, msg.ReceiptHandle)
		log.Printf("[debug] [%s] body: %s", msg.MessageId, msg.Body)
	}
	defer func() {
		if !completed {
			log.Printf("[info] [%s] Aborted message.", msg.MessageId)
		}
	}()

	event, err := ParseEvent([]byte(msg.Body))
	if err != nil {
		log.Printf("[error] [%s] Can't parse event from Body.", msg.MessageId, err)
		return err
	}
	log.Printf("[info] [%s] Importing event: %s", msg.MessageId, event)
	n, err := Import(event)
	if err != nil {
		log.Printf("[error] [%s] Import failed. %s", msg.MessageId, err)
		return err
	}
	if n == 0 {
		log.Printf("[warn] [%s] All events were not matched for any targets. Ignored.", msg.MessageId)
	} else {
		log.Printf("[info] [%s] %d import action completed.", msg.MessageId, n)
	}
	_, err = queue.DeleteMessage(&msg)
	if err != nil {
		log.Printf("[error] [%s] Can't delete message. %s", msg.MessageId, err)
	}
	completed = true
	log.Printf("[info] [%s] Completed message.", msg.MessageId)
	return nil
}
<|endoftext|>


<commit_before>package xls

type rowInfo struct {
	Index    uint16
	Fcell    uint16
	Lcell    uint16
	Height   uint16
	Notused  uint16
	Notused2 uint16
	Flags    uint32
}

//Row the data of one row
type Row struct {
	wb   *WorkBook
	info *rowInfo
	cols map[uint16]contentHandler
}

//Col Get the Nth Col from the Row, if has not, return nil.
//Suggest use Has function to test it.
func (r *Row) Col(i int) string {
	serial := uint16(i)
	if ch, ok := r.cols[serial]; ok {
		strs := ch.String(r.wb)
		return strs[0]
	} else {
		for _, v := range r.cols {
			if v.FirstCol() <= serial && v.LastCol() >= serial {
				strs := v.String(r.wb)
				return strs[serial-v.FirstCol()]
			}
		}
	}
	return ""
}

//LastCol Get the number of Last Col of the Row.
func (r *Row) LastCol() int {
	return int(r.info.Lcell)
}

//FirstCol Get the number of First Col of the Row.
func (r *Row) FirstCol() int {
	return int(r.info.Fcell)
}
<commit_msg>5) Row.ColExact(int)(string) when we need not to output duplicates of merged cells<commit_after>package xls

type rowInfo struct {
	Index    uint16
	Fcell    uint16
	Lcell    uint16
	Height   uint16
	Notused  uint16
	Notused2 uint16
	Flags    uint32
}

//Row the data of one row
type Row struct {
	wb   *WorkBook
	info *rowInfo
	cols map[uint16]contentHandler
}

//Col Get the Nth Col from the Row, if has not, return nil.
//Suggest use Has function to test it.
func (r *Row) Col(i int) string {
	serial := uint16(i)
	if ch, ok := r.cols[serial]; ok {
		strs := ch.String(r.wb)
		return strs[0]
	} else {
		for _, v := range r.cols {
			if v.FirstCol() <= serial && v.LastCol() >= serial {
				strs := v.String(r.wb)
				return strs[serial-v.FirstCol()]
			}
		}
	}
	return ""
}

//ColExact Get the Nth Col from the Row, if has not, return nil.
//For merged cells value is returned for first cell only
func (r *Row) ColExact(i int) string {
	serial := uint16(i)
	if ch, ok := r.cols[serial]; ok {
		strs := ch.String(r.wb)
		return strs[0]
	}
	return ""
}

//LastCol Get the number of Last Col of the Row.
func (r *Row) LastCol() int {
	return int(r.info.Lcell)
}

//FirstCol Get the number of First Col of the Row.
func (r *Row) FirstCol() int {
	return int(r.info.Fcell)
}
<|endoftext|>


<commit_before>package junos

// rpcCommand lists the commands that will be called.
var rpcCommand = map[string]string{
	"command":                          "<rpc><command format=\"text\">%s</command></rpc>",
	"command-xml":                      "<rpc><command format=\"xml\">%s</command></rpc>",
	"commit":                           "<rpc><commit-configuration/></rpc>",
	"configure-set":                    "<rpc><load-configuration action=\"set\" format=\"text\"><configuration-set>%s</configuration-set></load-configuration></rpc>",
	"get-rescue-information":           "<rpc><get-rescue-information><format>text</format></get-rescue-information></rpc>",
	"get-rollback-information":         "<rpc><get-rollback-information><rollback>%d</rollback><format>text</format></get-rollback-information></rpc>",
	"get-rollback-information-compare": "<rpc><get-rollback-information><rollback>0</rollback><compare>%d</compare><format>text</format></get-rollback-information></rpc>",
	"lock":            "<rpc><lock><target><candidate/></target></lock></rpc>",
	"rescue-config":   "<rpc><load-configuration rescue=\"rescue\"/></rpc>",
	"rollback-config": "<rpc><load-configuration rollback=\"%d\"/></rpc>",
	"software":        "<rpc><get-software-information/></rpc>",
	"unlock":          "<rpc><unlock><target><candidate/></target></unlock></rpc>",
}
<commit_msg>Added different configuration formats<commit_after>package junos

// rpcCommand lists the commands that will be called.
var rpcCommand = map[string]string{
	"command":                          "<rpc><command format=\"text\">%s</command></rpc>",
	"command-xml":                      "<rpc><command format=\"xml\">%s</command></rpc>",
	"commit":                           "<rpc><commit-configuration/></rpc>",
	"load-config-local-set":            "<rpc><load-configuration action=\"set\" format=\"text\"><configuration-set>%s</configuration-set></load-configuration></rpc>",
	"load-config-local-text":           "<rpc><load-configuration format=\"text\"><configuration-text>%s</configuration-text></load-configuration></rpc>",
	"load-config-local-xml":            "<rpc><load-configuration format=\"xml\"><configuration>%s</configuration></load-configuration></rpc>",
	"load-config-url-set":              "<rpc><load-configuration action=\"set\" format=\"text\" url=\"%s\"/></rpc>",
	"load-config-url-text":             "<rpc><load-configuration format=\"text\" url=\"%s\"/></rpc>",
	"load-config-url-xml":              "<rpc><load-configuration format=\"xml\" url=\"%s\"/></rpc>",
	"get-rescue-information":           "<rpc><get-rescue-information><format>text</format></get-rescue-information></rpc>",
	"get-rollback-information":         "<rpc><get-rollback-information><rollback>%d</rollback><format>text</format></get-rollback-information></rpc>",
	"get-rollback-information-compare": "<rpc><get-rollback-information><rollback>0</rollback><compare>%d</compare><format>text</format></get-rollback-information></rpc>",
	"lock":            "<rpc><lock><target><candidate/></target></lock></rpc>",
	"rescue-config":   "<rpc><load-configuration rescue=\"rescue\"/></rpc>",
	"rollback-config": "<rpc><load-configuration rollback=\"%d\"/></rpc>",
	"software":        "<rpc><get-software-information/></rpc>",
	"unlock":          "<rpc><unlock><target><candidate/></target></unlock></rpc>",
}
<|endoftext|>


<commit_before>// Copyright 2014 Hajime Hoshi
//
// 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 ebiten

import (
	"sync/atomic"

	"github.com/hajimehoshi/ebiten/internal/clock"
	"github.com/hajimehoshi/ebiten/internal/ui"
)

// FPS represents how many times game updating happens in a second (60).
const FPS = clock.FPS

// CurrentFPS returns the current number of frames per second of rendering.
//
// This function is concurrent-safe.
//
// This value represents how many times rendering happens in 1/60 second and
// NOT how many times logical game updating (a passed function to Run) happens.
// Note that logical game updating is assured to happen 60 times in a second
// as long as the screen is active.
func CurrentFPS() float64 {
	return clock.CurrentFPS()
}

var (
	isRunningSlowly = int32(0)
)

func setRunningSlowly(slow bool) {
	v := int32(0)
	if slow {
		v = 1
	}
	atomic.StoreInt32(&isRunningSlowly, v)
}

// IsRunningSlowly returns true if the game is running too slowly to keep 60 FPS of rendering.
// The game screen is not updated when IsRunningSlowly is true.
// It is recommended to skip heavy processing, especially drawing, when IsRunningSlowly is true.
//
// This function is concurrent-safe.
func IsRunningSlowly() bool {
	return atomic.LoadInt32(&isRunningSlowly) != 0
}

var theGraphicsContext atomic.Value

func run(width, height int, scale float64, title string, g *graphicsContext) error {
	if err := ui.Run(width, height, scale, title, &updater{g}); err != nil {
		if _, ok := err.(*ui.RegularTermination); ok {
			return nil
		}
		return err
	}
	return nil
}

type updater struct {
	g *graphicsContext
}

func (u *updater) SetSize(width, height int, scale float64) {
	u.g.SetSize(width, height, scale)
}

func (u *updater) Update() error {
	n := clock.Update()
	if err := u.g.Update(n); err != nil {
		return err
	}
	return nil
}

func (u *updater) Invalidate() {
	u.g.Invalidate()
}

// Run runs the game.
// f is a function which is called at every frame.
// The argument (*Image) is the render target that represents the screen.
//
// Run must be called from the main thread.
// Note that ebiten bounds the main goroutine to the main OS thread by runtime.LockOSThread.
//
// The given function f is guaranteed to be called 60 times a second
// even if a rendering frame is skipped.
// f is not called when the screen is not shown.
//
// The given scale is ignored on fullscreen mode.
//
// Run returns error when 1) OpenGL error happens, or 2) f returns error.
// In the case of 2), Run returns the same error.
//
// The size unit is device-independent pixel.
func Run(f func(*Image) error, width, height int, scale float64, title string) error {
	ch := make(chan error)
	go func() {
		defer close(ch)

		g := newGraphicsContext(f)
		theGraphicsContext.Store(g)
		if err := run(width, height, scale, title, g); err != nil {
			ch <- err
			return
		}
	}()
	// TODO: Use context in Go 1.7?
	if err := ui.RunMainThreadLoop(ch); err != nil {
		return err
	}
	return nil
}

// RunWithoutMainLoop runs the game, but don't call the loop on the main (UI) thread.
// Different from Run, this function returns immediately.
//
// Typically, Ebiten users don't have to call this directly.
// Instead, functions in github.com/hajimehoshi/ebiten/mobile module call this.
//
// The size unit is device-independent pixel.
func RunWithoutMainLoop(f func(*Image) error, width, height int, scale float64, title string) <-chan error {
	ch := make(chan error)
	go func() {
		defer close(ch)

		g := newGraphicsContext(f)
		theGraphicsContext.Store(g)
		if err := run(width, height, scale, title, g); err != nil {
			ch <- err
			return
		}
	}()
	return ch
}

// SetScreenSize changes the (logical) size of the screen.
// This doesn't affect the current scale of the screen.
//
// Unit is device-independent pixel.
//
// This function is concurrent-safe.
func SetScreenSize(width, height int) {
	if width <= 0 || height <= 0 {
		panic("ebiten: width and height must be positive")
	}
	ui.SetScreenSize(width, height)
}

// SetScreenScale changes the scale of the screen.
//
// This function is concurrent-safe.
func SetScreenScale(scale float64) {
	if scale <= 0 {
		panic("ebiten: scale must be positive")
	}
	ui.SetScreenScale(scale)
}

// ScreenScale returns the current screen scale.
//
// If Run is not called, this returns 0.
//
// This function is concurrent-safe.
func ScreenScale() float64 {
	return ui.ScreenScale()
}

// SetCursorVisibility changes the state of cursor visiblity.
//
// This function is concurrent-safe.
func SetCursorVisibility(visible bool) {
	ui.SetCursorVisibility(visible)
}

// IsScreen returns a boolean value indicating whether
// the current mode is fullscreen or not.
//
// This function is concurrent-safe.
func IsFullscreen() bool {
	return ui.IsFullscreen()
}

// SetFullscreen changes the current mode to fullscreen or not.
//
// On fullscreen mode, the game screen is automatically enlarged
// to fit with the monitor. The current scale value is ignored.
//
// On desktops, Ebiten uses 'windowed' fullscreen mode, which doesn't change
// your monitor's resolution.
//
// On browsers, the game screen is resized to fit with the body element (client) size.
// Additionally, the game screen is automatically resized when the body element is resized.
//
// SetFullscreen doesn't work on mobiles.
//
// This function is concurrent-safe.
func SetFullscreen(fullscreen bool) {
	ui.SetFullscreen(fullscreen)
}

// IsRunnableInBackground returns a boolean value indicating whether the game runs even in background.
//
// This function is concurrent-safe.
func IsRunnableInBackground() bool {
	return ui.IsRunnableInBackground()
}

// SetRunnableInBackground sets the state if the game runs even in background.
//
// If the given value is true, the game runs in background e.g. when losing focus.
// The initial state is false.
//
// Known issue: On browsers, even if the state is on, the game doesn't run in background tabs.
// This is because browsers throttles background tabs not to often update.
//
// SetRunnableInBackground doesn't work on mobiles so far.
//
// This function is concurrent-safe.
func SetRunnableInBackground(runnableInBackground bool) {
	ui.SetRunnableInBackground(runnableInBackground)
}
<commit_msg>ui: Fix comments<commit_after>// Copyright 2014 Hajime Hoshi
//
// 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 ebiten

import (
	"sync/atomic"

	"github.com/hajimehoshi/ebiten/internal/clock"
	"github.com/hajimehoshi/ebiten/internal/ui"
)

// FPS represents how many times game updating happens in a second (60).
const FPS = clock.FPS

// CurrentFPS returns the current number of frames per second of rendering.
//
// This function is concurrent-safe.
//
// This value represents how many times rendering happens in 1/60 second and
// NOT how many times logical game updating (a passed function to Run) happens.
// Note that logical game updating is assured to happen 60 times in a second
// as long as the screen is active.
func CurrentFPS() float64 {
	return clock.CurrentFPS()
}

var (
	isRunningSlowly = int32(0)
)

func setRunningSlowly(slow bool) {
	v := int32(0)
	if slow {
		v = 1
	}
	atomic.StoreInt32(&isRunningSlowly, v)
}

// IsRunningSlowly returns true if the game is running too slowly to keep 60 FPS of rendering.
// The game screen is not updated when IsRunningSlowly is true.
// It is recommended to skip heavy processing, especially drawing, when IsRunningSlowly is true.
//
// This function is concurrent-safe.
func IsRunningSlowly() bool {
	return atomic.LoadInt32(&isRunningSlowly) != 0
}

var theGraphicsContext atomic.Value

func run(width, height int, scale float64, title string, g *graphicsContext) error {
	if err := ui.Run(width, height, scale, title, &updater{g}); err != nil {
		if _, ok := err.(*ui.RegularTermination); ok {
			return nil
		}
		return err
	}
	return nil
}

type updater struct {
	g *graphicsContext
}

func (u *updater) SetSize(width, height int, scale float64) {
	u.g.SetSize(width, height, scale)
}

func (u *updater) Update() error {
	n := clock.Update()
	if err := u.g.Update(n); err != nil {
		return err
	}
	return nil
}

func (u *updater) Invalidate() {
	u.g.Invalidate()
}

// Run runs the game.
// f is a function which is called at every frame.
// The argument (*Image) is the render target that represents the screen.
//
// Run must be called from the main thread.
// Note that ebiten bounds the main goroutine to the main OS thread by runtime.LockOSThread.
//
// The given function f is guaranteed to be called 60 times a second
// even if a rendering frame is skipped.
// f is not called when the screen is not shown.
//
// The given scale is ignored on fullscreen mode.
//
// Run returns error when 1) OpenGL error happens, or 2) f returns error.
// In the case of 2), Run returns the same error.
//
// The size unit is device-independent pixel.
func Run(f func(*Image) error, width, height int, scale float64, title string) error {
	ch := make(chan error)
	go func() {
		defer close(ch)

		g := newGraphicsContext(f)
		theGraphicsContext.Store(g)
		if err := run(width, height, scale, title, g); err != nil {
			ch <- err
			return
		}
	}()
	// TODO: Use context in Go 1.7?
	if err := ui.RunMainThreadLoop(ch); err != nil {
		return err
	}
	return nil
}

// RunWithoutMainLoop runs the game, but don't call the loop on the main (UI) thread.
// Different from Run, this function returns immediately.
//
// Typically, Ebiten users don't have to call this directly.
// Instead, functions in github.com/hajimehoshi/ebiten/mobile module call this.
//
// The size unit is device-independent pixel.
func RunWithoutMainLoop(f func(*Image) error, width, height int, scale float64, title string) <-chan error {
	ch := make(chan error)
	go func() {
		defer close(ch)

		g := newGraphicsContext(f)
		theGraphicsContext.Store(g)
		if err := run(width, height, scale, title, g); err != nil {
			ch <- err
			return
		}
	}()
	return ch
}

// SetScreenSize changes the (logical) size of the screen.
// This doesn't affect the current scale of the screen.
//
// Unit is device-independent pixel.
//
// This function is concurrent-safe.
func SetScreenSize(width, height int) {
	if width <= 0 || height <= 0 {
		panic("ebiten: width and height must be positive")
	}
	ui.SetScreenSize(width, height)
}

// SetScreenScale changes the scale of the screen.
//
// This function is concurrent-safe.
func SetScreenScale(scale float64) {
	if scale <= 0 {
		panic("ebiten: scale must be positive")
	}
	ui.SetScreenScale(scale)
}

// ScreenScale returns the current screen scale.
//
// If Run is not called, this returns 0.
//
// This function is concurrent-safe.
func ScreenScale() float64 {
	return ui.ScreenScale()
}

// SetCursorVisibility changes the state of cursor visiblity.
//
// This function is concurrent-safe.
func SetCursorVisibility(visible bool) {
	ui.SetCursorVisibility(visible)
}

// IsFullscreen returns a boolean value indicating whether
// the current mode is fullscreen or not.
//
// This function is concurrent-safe.
func IsFullscreen() bool {
	return ui.IsFullscreen()
}

// SetFullscreen changes the current mode to fullscreen or not.
//
// On fullscreen mode, the game screen is automatically enlarged
// to fit with the monitor. The current scale value is ignored.
//
// On desktops, Ebiten uses 'windowed' fullscreen mode, which doesn't change
// your monitor's resolution.
//
// On browsers, the game screen is resized to fit with the body element (client) size.
// Additionally, the game screen is automatically resized when the body element is resized.
//
// SetFullscreen doesn't work on mobiles.
//
// This function is concurrent-safe.
func SetFullscreen(fullscreen bool) {
	ui.SetFullscreen(fullscreen)
}

// IsRunnableInBackground returns a boolean value indicating whether the game runs even in background.
//
// This function is concurrent-safe.
func IsRunnableInBackground() bool {
	return ui.IsRunnableInBackground()
}

// SetRunnableInBackground sets the state if the game runs even in background.
//
// If the given value is true, the game runs in background e.g. when losing focus.
// The initial state is false.
//
// Known issue: On browsers, even if the state is on, the game doesn't run in background tabs.
// This is because browsers throttles background tabs not to often update.
//
// SetRunnableInBackground doesn't work on mobiles so far.
//
// This function is concurrent-safe.
func SetRunnableInBackground(runnableInBackground bool) {
	ui.SetRunnableInBackground(runnableInBackground)
}
<|endoftext|>