<commit_before>package readline

import (
	"io"
	"net"
	"os"
)

type Conn struct {
	Conn     net.Conn
	Terminal *Terminal
	runChan  chan error
}

func NewConn(conn net.Conn, t *Terminal) (*Conn, error) {
	return &Conn{
		Conn:     conn,
		Terminal: t,
		runChan:  make(chan error),
	}, nil
}

func (c *Conn) Run() error {
	c.Terminal.EnterRawMode()
	go func() {
		_, err := io.Copy(c.Conn, os.Stdin)
		c.runChan <- err
	}()
	go func() {
		_, err := io.Copy(os.Stdout, c.Conn)
		c.runChan <- err
	}()
	err := <-c.runChan
	c.Terminal.ExitRawMode()
	return err
}

func Dial(network string, address string) (*Remote, error) {
	conn, err := net.Dial(network, address)
	if err != nil {
		return nil, err
	}
	var cfg Config
	t, err := NewTerminal(&cfg)
	if err != nil {
		return nil, err
	}
	return NewRemote(conn, t)
}
<commit_msg>fix typo<commit_after>package readline

import (
	"io"
	"net"
	"os"
)

type Conn struct {
	Conn     net.Conn
	Terminal *Terminal
	runChan  chan error
}

func NewConn(conn net.Conn, t *Terminal) (*Conn, error) {
	return &Conn{
		Conn:     conn,
		Terminal: t,
		runChan:  make(chan error),
	}, nil
}

func (c *Conn) Run() error {
	c.Terminal.EnterRawMode()
	go func() {
		_, err := io.Copy(c.Conn, os.Stdin)
		c.runChan <- err
	}()
	go func() {
		_, err := io.Copy(os.Stdout, c.Conn)
		c.runChan <- err
	}()
	err := <-c.runChan
	c.Terminal.ExitRawMode()
	return err
}

func Dial(network string, address string) (*Conn, error) {
	conn, err := net.Dial(network, address)
	if err != nil {
		return nil, err
	}
	var cfg Config
	t, err := NewTerminal(&cfg)
	if err != nil {
		return nil, err
	}
	return NewConn(conn, t)
}
<|endoftext|>


<commit_before>package render

import (
	"net/http"
	"path"

	"github.com/flosch/pongo2"
	"github.com/gin-gonic/gin/render"
)

type (
	PongoProduction struct {
		Templates map[string]*pongo2.Template
		Path      string
	}

	PongoDebug struct {
		Path string
	}

	Pongo struct {
		Template *pongo2.Template
		Name     string
		Data     interface{}
	}

	Context pongo2.Context
)

func NewProduction(path string) *PongoProduction {
	return &PongoProduction{map[string]*pongo2.Template{}, path}
}

func NewDebug(path string) *PongoDebug {
	return &PongoDebug{path}
}

func (p PongoProduction) Instance(name string, data interface{}) render.Render {
	var t *pongo2.Template
	if tmpl, ok := p.Templates[name]; ok {
		t = tmpl
	} else {
		tmpl := pongo2.Must(pongo2.FromFile(path.Join(p.Path, name)))
		p.Templates[name] = tmpl
		t = tmpl
	}
	return Pongo{
		Template: t,
		Name:     name,
		Data:     data,
	}
}

func (p PongoDebug) Instance(name string, data interface{}) render.Render {
	t := pongo2.Must(pongo2.FromFile(path.Join(p.Path, name)))
	return Pongo{
		Template: t,
		Name:     name,
		Data:     data,
	}
}

func (p Pongo) Write(w http.ResponseWriter) error {
	ctx := pongo2.Context(p.Data.(Context))
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	return p.Template.ExecuteWriter(ctx, w)
}
<commit_msg>Updated for Gin 1.0<commit_after>package render

import (
	"net/http"
	"path"

	"github.com/flosch/pongo2"
	"github.com/gin-gonic/gin/render"
)

type (
	PongoProduction struct {
		Templates map[string]*pongo2.Template
		Path      string
	}

	PongoDebug struct {
		Path string
	}

	Pongo struct {
		Template *pongo2.Template
		Name     string
		Data     interface{}
	}

	Context pongo2.Context
)

func NewProduction(path string) *PongoProduction {
	return &PongoProduction{map[string]*pongo2.Template{}, path}
}

func NewDebug(path string) *PongoDebug {
	return &PongoDebug{path}
}

func (p PongoProduction) Instance(name string, data interface{}) render.Render {
	var t *pongo2.Template
	if tmpl, ok := p.Templates[name]; ok {
		t = tmpl
	} else {
		tmpl := pongo2.Must(pongo2.FromFile(path.Join(p.Path, name)))
		p.Templates[name] = tmpl
		t = tmpl
	}
	return Pongo{
		Template: t,
		Name:     name,
		Data:     data,
	}
}

func (p PongoDebug) Instance(name string, data interface{}) render.Render {
	t := pongo2.Must(pongo2.FromFile(path.Join(p.Path, name)))
	return Pongo{
		Template: t,
		Name:     name,
		Data:     data,
	}
}

func (p Pongo) Render(w http.ResponseWriter) error {
	ctx := pongo2.Context(p.Data.(Context))
	w.Header().Set("Content-Type", "text/html; charset=utf-8")
	return p.Template.ExecuteWriter(ctx, w)
}
<|endoftext|>


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

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"text/template"
	"sort"

	"github.com/russross/blackfriday"
)

// RenderPost runs the input source through the blackfriday library.
func RenderPost(post *Post, input []byte) []byte {
	tpl, err := getTemplate("post")
	if err != nil {
		return nil
	}

	content := blackfriday.Markdown(
		input,
		blackfriday.HtmlRenderer(
			blackfriday.HTML_USE_SMARTYPANTS|
				blackfriday.HTML_USE_XHTML|
				blackfriday.HTML_SMARTYPANTS_LATEX_DASHES,
			"",
			""),
		0)

	buf := bytes.NewBuffer([]byte{})
	tpl.Execute(buf, map[string]interface{}{
		"Post":    post,
		"Content": string(content),
	})

	result, err := wrapPage(buf.Bytes(), map[string]string{
		"Title":    post.Title,
		"RootPath": getRootPath(post.CreateURL()),
	})
	return result
}

func makeParentDirIfNecessary(dir string) error {
	parent, _ := path.Split(dir)
	return os.MkdirAll(parent, 0755)
}

// CreateIndex takes the sorted list of posts and generates HTML output listing
// each one.
func CreateIndex(posts PostList) ([]byte, error) {
	tpl, err := getTemplate("index")
	if err != nil {
		return nil, err
	}

	sort.Sort(posts)

	buf := bytes.NewBuffer([]byte{})
	err = tpl.Execute(buf, struct{Posts PostList}{posts})
	if err != nil {
		return nil, err
	}

	content, err := wrapPage(buf.Bytes(), map[string]string{
		"Title":    "Posts",
		"RootPath": "",
	})
	return content, nil
}

func wrapPage(content []byte, vars interface{}) ([]byte, error) {
	buf := bytes.NewBuffer([]byte{})

	header, err := getTemplate("header")
	if err != nil {
		return nil, err
	}

	footer, err := getTemplate("footer")
	if err != nil {
		return nil, err
	}

	header.Execute(buf, vars)
	buf.Write(content)
	footer.Execute(buf, vars)

	return buf.Bytes(), nil
}

func getTemplate(name string) (*template.Template, error) {
	name = path.Join(*flagTemplates, name+".html")
	file, err := ioutil.ReadFile(name)
	if err != nil {
		return nil, err
	}

	tpl := template.New(name)
	_, err = tpl.Parse(string(file))
	if err != nil {
		return nil, err
	}

	return tpl, nil
}

func generateRedirect(url string) string {
	return fmt.Sprintf(`<html><head><meta http-equiv="refresh" content="0;url=%s"></head></html>`, url)
}
<commit_msg>Switch to using defined structs for the index page.<commit_after>//
// Blackblog
// Copyright 2012 Google Inc. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

package main

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"path"
	"sort"
	"text/template"

	"github.com/russross/blackfriday"
)

// RenderPost runs the input source through the blackfriday library.
func RenderPost(post *Post, input []byte) []byte {
	tpl, err := getTemplate("post")
	if err != nil {
		return nil
	}

	content := blackfriday.Markdown(
		input,
		blackfriday.HtmlRenderer(
			blackfriday.HTML_USE_SMARTYPANTS|
				blackfriday.HTML_USE_XHTML|
				blackfriday.HTML_SMARTYPANTS_LATEX_DASHES,
			"",
			""),
		0)

	buf := bytes.NewBuffer([]byte{})
	tpl.Execute(buf, map[string]interface{}{
		"Post":    post,
		"Content": string(content),
	})

	result, err := wrapPage(buf.Bytes(), PageParams{
		Title:    post.Title,
		RootPath: getRootPath(post.CreateURL()),
	})
	return result
}

func makeParentDirIfNecessary(dir string) error {
	parent, _ := path.Split(dir)
	return os.MkdirAll(parent, 0755)
}

// CreateIndex takes the sorted list of posts and generates HTML output listing
// each one.
func CreateIndex(posts PostList) ([]byte, error) {
	tpl, err := getTemplate("index")
	if err != nil {
		return nil, err
	}

	sort.Sort(posts)

	params := IndexPageParams{
		Posts:      posts,
		PageParams: PageParams{Title: "Posts"},
	}

	buf := bytes.NewBuffer([]byte{})
	err = tpl.Execute(buf, params)
	if err != nil {
		return nil, err
	}

	content, err := wrapPage(buf.Bytes(), params.PageParams)
	return content, nil
}

// PageParams contains the varaibles passed to the basic header/footer
// page templates.
type PageParams struct {
	// The title of the blog post.
	Title string

	// Relative path linking up to the root of the blog.
	RootPath string
}

// IndexPageParams is used to render out the blog post list page.
type IndexPageParams struct {
	PageParams
	Posts PostList
}

func wrapPage(content []byte, vars PageParams) ([]byte, error) {
	buf := bytes.NewBuffer([]byte{})

	header, err := getTemplate("header")
	if err != nil {
		return nil, err
	}

	footer, err := getTemplate("footer")
	if err != nil {
		return nil, err
	}

	header.Execute(buf, vars)
	buf.Write(content)
	footer.Execute(buf, vars)

	return buf.Bytes(), nil
}

func getTemplate(name string) (*template.Template, error) {
	name = path.Join(*flagTemplates, name+".html")
	file, err := ioutil.ReadFile(name)
	if err != nil {
		return nil, err
	}

	tpl := template.New(name)
	_, err = tpl.Parse(string(file))
	if err != nil {
		return nil, err
	}

	return tpl, nil
}

func generateRedirect(url string) string {
	return fmt.Sprintf(`<html><head><meta http-equiv="refresh" content="0;url=%s"></head></html>`, url)
}
<|endoftext|>


<commit_before>// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 oglemock

import (
	"errors"
	"fmt"
	"math"
	"reflect"
)

var intType = reflect.TypeOf(int(0))
var float64Type = reflect.TypeOf(float64(0))
var complex128Type = reflect.TypeOf(complex128(0))

// Return creates an Action that returns the values passed to Return as
// arguments, after suitable legal type conversions. The following rules apply.
// Given an argument x to Return and a corresponding type T in the method's
// signature, at least one of the following must hold:
//
//  *  x is assignable to T. (See "Assignability" in the language spec.) Note
//     that this in particular applies that x may be a type that implements an
//     interface T. It also implies that the nil literal can be used if T is a
//     pointer, function, interface, slice, channel, or map type.
//
//  *  T is any numeric type, and x is an int that is in-range for that type.
//     This facilities using raw integer constants: Return(17).
//
//  *  T is a floating-point or complex number type, and x is a float64.  This
//     facilities using raw floating-point constants: Return(17.5).
//
//  *  T is a complex number type, and x is a complex128. This facilities using
//     raw complex constants: Return(17+2i).
//
func Return(vals ...interface{}) Action {
	return &returnAction{vals, nil}
}

type returnAction struct {
	returnVals []interface{}
	signature reflect.Type
}

func (a *returnAction) Invoke(vals []interface{}) []interface{} {
	res, err := a.buildInvokeResult(a.signature)
	if err != nil {
		panic(err)
	}

	return res
}

func (a *returnAction) SetSignature(signature reflect.Type) error {
	if _, err := a.buildInvokeResult(signature); err != nil {
		return err
	}

	a.signature = signature
	return nil
}

// A version of Invoke that does error checking, used by both public methods.
func (a *returnAction) buildInvokeResult(
	sig reflect.Type) (res []interface{}, err error) {
	// Check the length of the return value.
	numOut := sig.NumOut()
	numVals := len(a.returnVals)

	if numOut != numVals {
		err = errors.New(
			fmt.Sprintf("Return given %d vals; expected %d.", numVals, numOut))
		return
	}

	// Attempt to coerce each return value.
	res = make([]interface{}, numOut)

	for i, val := range a.returnVals {
		resType := sig.Out(i)
		res[i], err = a.coerce(val, resType)

		if err != nil {
			res = nil
			err = errors.New(fmt.Sprintf("Return: arg %d: %v", i, err))
			return
		}
	}

	return
}

func (a *returnAction) coerce(x interface{}, t reflect.Type) (interface{}, error) {
	xv := reflect.ValueOf(x)
	rv := reflect.New(t).Elem()

	// Special case: the language spec says that the predeclared identifier nil
	// is assignable to pointers, functions, interface, slices, channels, and map
	// types. However, reflect.ValueOf(nil) returns an invalid value that will
	// not cooperate below. So handle invalid values here, assuming that they
	// resulted from Return(nil).
	if !xv.IsValid() {
		switch t.Kind() {
		case reflect.Ptr, reflect.Func, reflect.Interface, reflect.Chan, reflect.Slice, reflect.Map:
			return rv.Interface(), nil
		}

		return nil, errors.New(fmt.Sprintf("expected %v, given <nil>", t))
	}

	// If x is assignable to type t, let the reflect package do the heavy
	// lifting.
	if reflect.TypeOf(x).AssignableTo(t) {
		rv.Set(xv)
		return rv.Interface(), nil
	}

	// Handle numeric types as described in the documentation on Return.
	switch {
	case xv.Type() == intType && a.isNumeric(t):
		return a.coerceInt(xv.Int(), t)

	case xv.Type() == float64Type && (a.isFloatingPoint(t) || a.isComplex(t)):
		return a.coerceFloat(xv.Float(), t)

	case xv.Type() == complex128Type && a.isComplex(t):
		return a.coerceComplex(xv.Complex(), t)
	}

	// The value wasn't of a legal type.
	return nil, errors.New(fmt.Sprintf("expected %v, given %v", t, xv.Type()))
}

func (a *returnAction) isNumeric(t reflect.Type) bool {
	return (t.Kind() >= reflect.Int && t.Kind() <= reflect.Uint64) ||
		a.isFloatingPoint(t) ||
		a.isComplex(t)
}

func (a *returnAction) isFloatingPoint(t reflect.Type) bool {
	return t.Kind() == reflect.Float32 || t.Kind() == reflect.Float64
}

func (a *returnAction) isComplex(t reflect.Type) bool {
	return t.Kind() == reflect.Complex64 || t.Kind() == reflect.Complex128
}

func (a *returnAction) coerceInt(x int64, t reflect.Type) (interface{}, error) {
	k := t.Kind()

	// Floating point and complex numbers: promote appropriately.
	if a.isFloatingPoint(t) || a.isComplex(t) {
		return a.coerceFloat(float64(x), t)
	}

	// Integers: range check.
	min := int64(math.MinInt64)
	max := int64(math.MaxInt64)
	unsigned := false

	switch k {
	case reflect.Int8:
		min = math.MinInt8
		max = math.MaxInt8

	case reflect.Int16:
		min = math.MinInt16
		max = math.MaxInt16

	case reflect.Int32:
		min = math.MinInt32
		max = math.MaxInt32

	case reflect.Uint8:
		unsigned = true
		min = 0
		max = math.MaxUint8

	case reflect.Uint16:
		unsigned = true
		min = 0
		max = math.MaxUint16

	case reflect.Uint32:
		unsigned = true
		min = 0
		max = math.MaxUint32

	case reflect.Uint64:
		unsigned = true
		min = 0
		max = math.MaxInt64

	default:
		panic(fmt.Sprintf("Unexpected type: %v", t))
	}

	if x < min || x > max {
		return nil, errors.New("int value out of range")
	}

	rv := reflect.New(t).Elem()
	if unsigned {
		rv.SetUint(uint64(x))
	} else {
		rv.SetInt(x)
	}

	return rv.Interface(), nil
}

func (a *returnAction) coerceFloat(x float64, t reflect.Type) (interface{}, error) {
	// Promote complex numbers.
	if a.isComplex(t) {
		return a.coerceComplex(complex(x, 0), t)
	}

	rv := reflect.New(t).Elem()
	rv.SetFloat(x)
	return rv.Interface(), nil
}

func (a *returnAction) coerceComplex(x complex128, t reflect.Type) (interface{}, error) {
	return nil, errors.New("TODO")
}
<commit_msg>Implemented coerceComplex.<commit_after>// Copyright 2011 Aaron Jacobs. All Rights Reserved.
// Author: aaronjjacobs@gmail.com (Aaron Jacobs)
//
// 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 oglemock

import (
	"errors"
	"fmt"
	"math"
	"reflect"
)

var intType = reflect.TypeOf(int(0))
var float64Type = reflect.TypeOf(float64(0))
var complex128Type = reflect.TypeOf(complex128(0))

// Return creates an Action that returns the values passed to Return as
// arguments, after suitable legal type conversions. The following rules apply.
// Given an argument x to Return and a corresponding type T in the method's
// signature, at least one of the following must hold:
//
//  *  x is assignable to T. (See "Assignability" in the language spec.) Note
//     that this in particular applies that x may be a type that implements an
//     interface T. It also implies that the nil literal can be used if T is a
//     pointer, function, interface, slice, channel, or map type.
//
//  *  T is any numeric type, and x is an int that is in-range for that type.
//     This facilities using raw integer constants: Return(17).
//
//  *  T is a floating-point or complex number type, and x is a float64.  This
//     facilities using raw floating-point constants: Return(17.5).
//
//  *  T is a complex number type, and x is a complex128. This facilities using
//     raw complex constants: Return(17+2i).
//
func Return(vals ...interface{}) Action {
	return &returnAction{vals, nil}
}

type returnAction struct {
	returnVals []interface{}
	signature reflect.Type
}

func (a *returnAction) Invoke(vals []interface{}) []interface{} {
	res, err := a.buildInvokeResult(a.signature)
	if err != nil {
		panic(err)
	}

	return res
}

func (a *returnAction) SetSignature(signature reflect.Type) error {
	if _, err := a.buildInvokeResult(signature); err != nil {
		return err
	}

	a.signature = signature
	return nil
}

// A version of Invoke that does error checking, used by both public methods.
func (a *returnAction) buildInvokeResult(
	sig reflect.Type) (res []interface{}, err error) {
	// Check the length of the return value.
	numOut := sig.NumOut()
	numVals := len(a.returnVals)

	if numOut != numVals {
		err = errors.New(
			fmt.Sprintf("Return given %d vals; expected %d.", numVals, numOut))
		return
	}

	// Attempt to coerce each return value.
	res = make([]interface{}, numOut)

	for i, val := range a.returnVals {
		resType := sig.Out(i)
		res[i], err = a.coerce(val, resType)

		if err != nil {
			res = nil
			err = errors.New(fmt.Sprintf("Return: arg %d: %v", i, err))
			return
		}
	}

	return
}

func (a *returnAction) coerce(x interface{}, t reflect.Type) (interface{}, error) {
	xv := reflect.ValueOf(x)
	rv := reflect.New(t).Elem()

	// Special case: the language spec says that the predeclared identifier nil
	// is assignable to pointers, functions, interface, slices, channels, and map
	// types. However, reflect.ValueOf(nil) returns an invalid value that will
	// not cooperate below. So handle invalid values here, assuming that they
	// resulted from Return(nil).
	if !xv.IsValid() {
		switch t.Kind() {
		case reflect.Ptr, reflect.Func, reflect.Interface, reflect.Chan, reflect.Slice, reflect.Map:
			return rv.Interface(), nil
		}

		return nil, errors.New(fmt.Sprintf("expected %v, given <nil>", t))
	}

	// If x is assignable to type t, let the reflect package do the heavy
	// lifting.
	if reflect.TypeOf(x).AssignableTo(t) {
		rv.Set(xv)
		return rv.Interface(), nil
	}

	// Handle numeric types as described in the documentation on Return.
	switch {
	case xv.Type() == intType && a.isNumeric(t):
		return a.coerceInt(xv.Int(), t)

	case xv.Type() == float64Type && (a.isFloatingPoint(t) || a.isComplex(t)):
		return a.coerceFloat(xv.Float(), t)

	case xv.Type() == complex128Type && a.isComplex(t):
		return a.coerceComplex(xv.Complex(), t)
	}

	// The value wasn't of a legal type.
	return nil, errors.New(fmt.Sprintf("expected %v, given %v", t, xv.Type()))
}

func (a *returnAction) isNumeric(t reflect.Type) bool {
	return (t.Kind() >= reflect.Int && t.Kind() <= reflect.Uint64) ||
		a.isFloatingPoint(t) ||
		a.isComplex(t)
}

func (a *returnAction) isFloatingPoint(t reflect.Type) bool {
	return t.Kind() == reflect.Float32 || t.Kind() == reflect.Float64
}

func (a *returnAction) isComplex(t reflect.Type) bool {
	return t.Kind() == reflect.Complex64 || t.Kind() == reflect.Complex128
}

func (a *returnAction) coerceInt(x int64, t reflect.Type) (interface{}, error) {
	k := t.Kind()

	// Floating point and complex numbers: promote appropriately.
	if a.isFloatingPoint(t) || a.isComplex(t) {
		return a.coerceFloat(float64(x), t)
	}

	// Integers: range check.
	min := int64(math.MinInt64)
	max := int64(math.MaxInt64)
	unsigned := false

	switch k {
	case reflect.Int8:
		min = math.MinInt8
		max = math.MaxInt8

	case reflect.Int16:
		min = math.MinInt16
		max = math.MaxInt16

	case reflect.Int32:
		min = math.MinInt32
		max = math.MaxInt32

	case reflect.Uint8:
		unsigned = true
		min = 0
		max = math.MaxUint8

	case reflect.Uint16:
		unsigned = true
		min = 0
		max = math.MaxUint16

	case reflect.Uint32:
		unsigned = true
		min = 0
		max = math.MaxUint32

	case reflect.Uint64:
		unsigned = true
		min = 0
		max = math.MaxInt64

	default:
		panic(fmt.Sprintf("Unexpected type: %v", t))
	}

	if x < min || x > max {
		return nil, errors.New("int value out of range")
	}

	rv := reflect.New(t).Elem()
	if unsigned {
		rv.SetUint(uint64(x))
	} else {
		rv.SetInt(x)
	}

	return rv.Interface(), nil
}

func (a *returnAction) coerceFloat(x float64, t reflect.Type) (interface{}, error) {
	// Promote complex numbers.
	if a.isComplex(t) {
		return a.coerceComplex(complex(x, 0), t)
	}

	rv := reflect.New(t).Elem()
	rv.SetFloat(x)
	return rv.Interface(), nil
}

func (a *returnAction) coerceComplex(x complex128, t reflect.Type) (interface{}, error) {
	rv := reflect.New(t).Elem()
	rv.SetComplex(x)
	return rv.Interface(), nil
}
<|endoftext|>


<commit_before>package helm

import (
	"errors"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"strings"
	"time"
)

const (
	get     = "GET"
	head    = "HEAD"
	post    = "POST"
	put     = "PUT"
	patch   = "PATCH"
	deleteh = "DELETE"
)

// Handle is just like "net/http" Handlers, only takes params.
type Handle func(http.ResponseWriter, *http.Request, url.Values)

// Middleware is just like the Handle type, but has a boolean return. True
// means to keep processing the rest of the middleware chain, false means end.
// If you return false to end the request-response cycle you MUST
// write something back to the client, otherwise it will be left hanging.
type Middleware func(http.ResponseWriter, *http.Request, url.Values) bool

// Router name says it all.
type Router struct {
	tree           *node
	rootHandler    Handle
	middleware     []Middleware
	l              *log.Logger
	LoggingEnabled bool
	URIVersion     string
}

type Param struct {
	Name     string
	Required bool
}

// New creates a new router. Take the root/fall through route
// like how the default mux works. Only difference is in this case,
// you have to specific one.
func New(rootHandler Handle) *Router {
	node := node{component: "/", isNamedParam: false, methods: make(map[string]*route)}
	return &Router{tree: &node, rootHandler: rootHandler, URIVersion: ""}
}

// EnableLogging sets logging to supplied writer.
func (r *Router) EnableLogging(w io.Writer) {
	r.l = log.New(w, "[helm] ", 0)
	r.LoggingEnabled = true
}

// Handle takes an http handler, method and pattern for a route.
func (r *Router) Handle(method, path string, handler Handle, middleware ...Middleware) {
	if path[0] != '/' {
		panic("Path has to start with a /.")
	}
	r.tree.addNode(method, r.URIVersion+path, handler, middleware...)
}

// GET same as Handle only the method is already implied.
func (r *Router) GET(path string, handler Handle, middleware ...Middleware) {
	r.Handle(get, path, handler, middleware...)
}

// HEAD same as Handle only the method is already implied.
func (r *Router) HEAD(path string, handler Handle, middleware ...Middleware) {
	r.Handle(head, path, handler, middleware...)
}

// POST same as Handle only the method is already implied.
func (r *Router) POST(path string, handler Handle, middleware ...Middleware) {
	r.Handle(post, path, handler, middleware...)
}

// PUT same as Handle only the method is already implied.
func (r *Router) PUT(path string, handler Handle, middleware ...Middleware) {
	r.Handle(put, path, handler, middleware...)
}

// PATCH same as Handle only the method is already implied.
func (r *Router) PATCH(path string, handler Handle, middleware ...Middleware) { // might make this and put one.
	r.Handle(patch, path, handler, middleware...)
}

// DELETE same as Handle only the method is already implied.
func (r *Router) DELETE(path string, handler Handle, middleware ...Middleware) {
	r.Handle(deleteh, path, handler, middleware...)
}

// Use adds middleware to all of the routes.
func (r *Router) Use(middleware ...Middleware) {
	r.middleware = append(r.middleware, middleware...)
}

// Run is a simple wrapper around http.ListenAndServe.
func (r *Router) Run(address string) {
	if r.LoggingEnabled {
		r.l.Println("Running on", address)
	}
	http.ListenAndServe(address, r)
}

// runMiddleware loops over the slice of middleware and call to each of the middleware handlers.
func runMiddleware(w http.ResponseWriter, req *http.Request, params url.Values, middleware ...Middleware) bool {
	for _, m := range middleware {
		if !m(w, req, params) {
			return false // the middleware returned false, so end processing the chain.
		}
	}
	return true
}

// Needed by "net/http" to handle http requests and be a mux to http.ListenAndServe.
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	defer clear(req)
	cw := w
	if r.LoggingEnabled {
		r.l.Printf("Started %s %s", req.Method, req.URL.Path)
		cw = &responseWriter{w, 200}
		start := time.Now()
		defer func(time.Time) {
			status := cw.(*responseWriter).status
			r.l.Printf("Completed %d %s in %v", status, http.StatusText(status), time.Since(start))
		}(start)
	}

	req.ParseMultipartForm(10 * 1024 * 1024) // 10MB. Should probably make this configurable...
	params := req.Form
	if !runMiddleware(cw, req, params, r.middleware...) {
		return // end the chain.
	}
	node, _ := r.tree.traverse(strings.Split(req.URL.Path, "/")[1:], params)
	if handler := node.methods[req.Method]; handler != nil {
		if !runMiddleware(cw, req, params, handler.middleware...) {
			return
		}
		handler.handler(cw, req, params)
	} else {
		r.rootHandler(cw, req, params)
	}
}

// ValidateParams is used for validating and sanizating params. Since HTTP params can have
// same name for multiple params, if this happens it will just use the first one.
func ValidateParams(params url.Values, desiredParams []Param) (map[string]string, error) {
	paramValues := make(map[string]string)
	for _, param := range desiredParams {
		p, ok := params[param.Name]
		if !ok || p[0] == "" && param.Required {
			return nil, errors.New(fmt.Sprintf("Required parameter (%s) not valid", param.Name))
		} else if ok && p[0] != "" {
			paramValues[param.Name] = p[0]
		}
	}
	return paramValues, nil
}
<commit_msg>Correcting logic for ValidateParams<commit_after>package helm

import (
	"errors"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/url"
	"strings"
	"time"
)

const (
	get     = "GET"
	head    = "HEAD"
	post    = "POST"
	put     = "PUT"
	patch   = "PATCH"
	deleteh = "DELETE"
)

// Handle is just like "net/http" Handlers, only takes params.
type Handle func(http.ResponseWriter, *http.Request, url.Values)

// Middleware is just like the Handle type, but has a boolean return. True
// means to keep processing the rest of the middleware chain, false means end.
// If you return false to end the request-response cycle you MUST
// write something back to the client, otherwise it will be left hanging.
type Middleware func(http.ResponseWriter, *http.Request, url.Values) bool

// Router name says it all.
type Router struct {
	tree           *node
	rootHandler    Handle
	middleware     []Middleware
	l              *log.Logger
	LoggingEnabled bool
	URIVersion     string
}

type Param struct {
	Name     string
	Required bool
}

// New creates a new router. Take the root/fall through route
// like how the default mux works. Only difference is in this case,
// you have to specific one.
func New(rootHandler Handle) *Router {
	node := node{component: "/", isNamedParam: false, methods: make(map[string]*route)}
	return &Router{tree: &node, rootHandler: rootHandler, URIVersion: ""}
}

// EnableLogging sets logging to supplied writer.
func (r *Router) EnableLogging(w io.Writer) {
	r.l = log.New(w, "[helm] ", 0)
	r.LoggingEnabled = true
}

// Handle takes an http handler, method and pattern for a route.
func (r *Router) Handle(method, path string, handler Handle, middleware ...Middleware) {
	if path[0] != '/' {
		panic("Path has to start with a /.")
	}
	r.tree.addNode(method, r.URIVersion+path, handler, middleware...)
}

// GET same as Handle only the method is already implied.
func (r *Router) GET(path string, handler Handle, middleware ...Middleware) {
	r.Handle(get, path, handler, middleware...)
}

// HEAD same as Handle only the method is already implied.
func (r *Router) HEAD(path string, handler Handle, middleware ...Middleware) {
	r.Handle(head, path, handler, middleware...)
}

// POST same as Handle only the method is already implied.
func (r *Router) POST(path string, handler Handle, middleware ...Middleware) {
	r.Handle(post, path, handler, middleware...)
}

// PUT same as Handle only the method is already implied.
func (r *Router) PUT(path string, handler Handle, middleware ...Middleware) {
	r.Handle(put, path, handler, middleware...)
}

// PATCH same as Handle only the method is already implied.
func (r *Router) PATCH(path string, handler Handle, middleware ...Middleware) { // might make this and put one.
	r.Handle(patch, path, handler, middleware...)
}

// DELETE same as Handle only the method is already implied.
func (r *Router) DELETE(path string, handler Handle, middleware ...Middleware) {
	r.Handle(deleteh, path, handler, middleware...)
}

// Use adds middleware to all of the routes.
func (r *Router) Use(middleware ...Middleware) {
	r.middleware = append(r.middleware, middleware...)
}

// Run is a simple wrapper around http.ListenAndServe.
func (r *Router) Run(address string) {
	if r.LoggingEnabled {
		r.l.Println("Running on", address)
	}
	http.ListenAndServe(address, r)
}

// runMiddleware loops over the slice of middleware and call to each of the middleware handlers.
func runMiddleware(w http.ResponseWriter, req *http.Request, params url.Values, middleware ...Middleware) bool {
	for _, m := range middleware {
		if !m(w, req, params) {
			return false // the middleware returned false, so end processing the chain.
		}
	}
	return true
}

// Needed by "net/http" to handle http requests and be a mux to http.ListenAndServe.
func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	defer clear(req)
	cw := w
	if r.LoggingEnabled {
		r.l.Printf("Started %s %s", req.Method, req.URL.Path)
		cw = &responseWriter{w, 200}
		start := time.Now()
		defer func(time.Time) {
			status := cw.(*responseWriter).status
			r.l.Printf("Completed %d %s in %v", status, http.StatusText(status), time.Since(start))
		}(start)
	}

	req.ParseMultipartForm(10 * 1024 * 1024) // 10MB. Should probably make this configurable...
	params := req.Form
	if !runMiddleware(cw, req, params, r.middleware...) {
		return // end the chain.
	}
	node, _ := r.tree.traverse(strings.Split(req.URL.Path, "/")[1:], params)
	if handler := node.methods[req.Method]; handler != nil {
		if !runMiddleware(cw, req, params, handler.middleware...) {
			return
		}
		handler.handler(cw, req, params)
	} else {
		r.rootHandler(cw, req, params)
	}
}

// ValidateParams is used for validating and sanizating params. Since HTTP params can have
// same name for multiple params, if this happens it will just use the first one.
func ValidateParams(params url.Values, desiredParams []Param) (map[string]string, error) {
	paramValues := make(map[string]string)
	for _, param := range desiredParams {
		p, ok := params[param.Name]
		if param.Required && ok && p[0] != "" {
			paramValues[param.Name] = p[0]
		} else if ok && p[0] != "" {
			paramValues[param.Name] = p[0]
		} else if param.Required {
			return nil, errors.New(fmt.Sprintf("Required parameter (%s) not valid", param.Name))
		}
	}
	return paramValues, nil
}

<|endoftext|>


<commit_before>package napnap

import "strings"

type Router struct {
	tree *tree
}

type tree struct {
	rootNode *node
}

type kind uint8

type node struct {
	parent    *node
	children  []*node
	kind      kind
	name      string
	pNames    []string
	params    []string
	sortOrder int
	handler   *methodHandler
}

type methodHandler struct {
	connect HandlerFunc
	delete  HandlerFunc
	get     HandlerFunc
	head    HandlerFunc
	options HandlerFunc
	patch   HandlerFunc
	post    HandlerFunc
	put     HandlerFunc
	trace   HandlerFunc
}

const (
	// CONNECT HTTP method
	CONNECT = "CONNECT"
	// DELETE HTTP method
	DELETE = "DELETE"
	// GET HTTP method
	GET = "GET"
	// HEAD HTTP method
	HEAD = "HEAD"
	// OPTIONS HTTP method
	OPTIONS = "OPTIONS"
	// PATCH HTTP method
	PATCH = "PATCH"
	// POST HTTP method
	POST = "POST"
	// PUT HTTP method
	PUT = "PUT"
	// TRACE HTTP method
	TRACE = "TRACE"
)

var (
	notFoundHandler = func(c *Context) {
		_logger.debug("NotFound")
	}
)

const (
	skind kind = iota
	pkind
)

// NewRouter function will create a new router instance
func NewRouter() *Router {
	return &Router{
		tree: &tree{
			rootNode: &node{
				parent:    nil,
				children:  []*node{},
				kind:      0,
				name:      "/",
				sortOrder: 0,
				handler:   &methodHandler{},
			},
		},
	}
}

// Invoke function is a middleware entry
func (r *Router) Invoke(c *Context, next HandlerFunc) {
	h := r.Find(c.Request.Method, c.Request.URL.Path, c)

	if h == nil {
		next(c)
	} else {
		h(c)
	}
}

// All is a shortcut for adding all methods
func (r *Router) All(path string, handler HandlerFunc) {
	r.Add(GET, path, handler)
	r.Add(POST, path, handler)
	r.Add(PUT, path, handler)
	r.Add(DELETE, path, handler)
	r.Add(PATCH, path, handler)
	r.Add(OPTIONS, path, handler)
	r.Add(HEAD, path, handler)
}

// Get is a shortcut for router.Add("GET", path, handle)
func (r *Router) Get(path string, handler HandlerFunc) {
	r.Add(GET, path, handler)
}

// Post is a shortcut for router.Add("POST", path, handle)
func (r *Router) Post(path string, handler HandlerFunc) {
	r.Add(POST, path, handler)
}

// Put is a shortcut for router.Add("PUT", path, handle)
func (r *Router) Put(path string, handler HandlerFunc) {
	r.Add(PUT, path, handler)
}

// Delete is a shortcut for router.Add("DELETE", path, handle)
func (r *Router) Delete(path string, handler HandlerFunc) {
	r.Add(DELETE, path, handler)
}

// Patch is a shortcut for router.Add("PATCH", path, handle)
func (r *Router) Patch(path string, handler HandlerFunc) {
	r.Add(PATCH, path, handler)
}

// Options is a shortcut for router.Add("OPTIONS", path, handle)
func (r *Router) Options(path string, handler HandlerFunc) {
	r.Add(OPTIONS, path, handler)
}

// Head is a shortcut for router.Add("HEAD", path, handle)
func (r *Router) Head(path string, handler HandlerFunc) {
	r.Add(HEAD, path, handler)
}

// Add function which adding path and handler to router
func (r *Router) Add(method string, path string, handler HandlerFunc) {
	_logger.debug("===Add")
	if len(path) == 0 {
		panic("router: path couldn't be empty")
	}

	if path[0:1] == "/" {
		path = path[1:]
	} else {
		panic("router: path was invalid")
	}

	_logger.debug("path:" + path)

	pathArray := strings.Split(path, "/")
	count := len(pathArray)

	currentNode := r.tree.rootNode
	pathParams := []string{}

	for index, element := range pathArray {
		if len(element) == 0 {
			continue
		}

		var childNode *node
		if element[0:1] == ":" {
			// that is parameter node
			pName := element[1:]
			_logger.debug("parameterName:" + pName)
			childNode = currentNode.findChildByKind(pkind)
			if childNode == nil {
				childNode = newNode(pName, pkind)
				currentNode.addChild(childNode)
			}

			isFound := false
			for _, p := range childNode.pNames {
				if p == pName {
					isFound = true
				}
			}

			if isFound == false {
				childNode.pNames = append(childNode.pNames, pName)
				_logger.debug("added_parameter_name:" + pName)
			}

			pathParams = append(pathParams, pName)

		} else {
			// that is static node
			childNode = currentNode.findChildByName(element)
			if childNode == nil {
				childNode = newNode(element, skind)
				currentNode.addChild(childNode)
			}
		}

		// last node in the path
		if count == index+1 {
			childNode.params = pathParams
			_logger.debug("lastNode_param:")
			_logger.debug("method:" + method)
			childNode.addHandler(method, handler)
		}

		currentNode = childNode
	}

	//test
	/*
		testNode := r.tree.rootNode.children[0].children[0]
		println("test_node_name: " + testNode.name)
		if method == POST {
			testNode.handler.post()
		}*/

}

// Find returns http handler for specific path
func (r *Router) Find(method string, path string, c *Context) HandlerFunc {
	_logger.debug("===Find")
	_logger.debug("method:" + method)
	_logger.debug("path:" + path)
	if path[0:1] == "/" {
		path = path[1:]
	}

	pathArray := strings.Split(path, "/")
	count := len(pathArray)

	currentNode := r.tree.rootNode

	pathParams := make(map[int][]Param)
	var paramsNum int

	for index, element := range pathArray {
		childNode := currentNode.findChildByName(element)

		if childNode == nil {
			// static node was not found and is looking for parameter node
			childNode = currentNode.findChildByKind(pkind)

			if childNode != nil {
				var newParams []Param
				for _, pName := range childNode.pNames {
					param := Param{Key: pName, Value: element}
					newParams = append(newParams, param)
				}
				pathParams[paramsNum] = newParams
				paramsNum++
			}
		}

		if childNode == nil {
			//return notFoundHandler
			return nil
		}

		// last node in the path
		if count == index+1 {
			myHandler := childNode.findHandler(method)
			if myHandler == nil {
				//return notFoundHandler
				_logger.debug("handler was not found")
				return nil
			}

			var newParams []Param
			for _, pName := range childNode.pNames {
				param := Param{Key: pName, Value: element}
				newParams = append(newParams, param)
			}
			pathParams[paramsNum] = newParams
			paramsNum++

			paramsNum = 0
			//println("params_count:", len(pathParams))
			_logger.debug("lastNode_params_count:", len(childNode.params))
			for _, el := range childNode.params {
				println(el)
			}
			for _, validParam := range childNode.params {
				for _, p := range pathParams[paramsNum] {
					//println("p_value:", index, p.Key+"&"+p.Value)
					if validParam == p.Key {
						_logger.debug("matched: " + validParam + "," + p.Value)
						c.params = append(c.params, p)
					}
				}
				paramsNum++
			}

			return myHandler
		}

		currentNode = childNode
	}
	//return notFoundHandler
	return nil
}

func newNode(name string, t kind) *node {
	return &node{
		kind:      t,
		name:      name,
		sortOrder: 0,
		handler:   &methodHandler{},
	}
}

func (n *node) addChild(node *node) {
	node.parent = n
	n.children = append(n.children, node)
}

func (n *node) findChildByName(name string) *node {
	var result *node
	for _, element := range n.children {
		if element.name == name && element.kind == skind {
			result = element
			break
		}
	}
	return result
}

func (n *node) findChildByKind(t kind) *node {
	for _, c := range n.children {
		if c.kind == t {
			return c
		}
	}
	return nil
}

func (n *node) addHandler(method string, h HandlerFunc) {
	switch method {
	case GET:
		n.handler.get = h
	case POST:
		n.handler.post = h
	case PUT:
		n.handler.put = h
	case DELETE:
		n.handler.delete = h
	case PATCH:
		n.handler.patch = h
	case OPTIONS:
		n.handler.options = h
	case HEAD:
		n.handler.head = h
	case CONNECT:
		n.handler.connect = h
	case TRACE:
		n.handler.trace = h
	default:
		panic("method is not invalid or supported.")
	}
}

func (n *node) findHandler(method string) HandlerFunc {
	switch method {
	case GET:
		return n.handler.get
	case POST:
		return n.handler.post
	case PUT:
		return n.handler.put
	case DELETE:
		return n.handler.delete
	case PATCH:
		return n.handler.patch
	case OPTIONS:
		return n.handler.options
	case HEAD:
		return n.handler.head
	case CONNECT:
		return n.handler.connect
	case TRACE:
		return n.handler.trace
	default:
		panic("method is not invalid or supported.")
	}
}

/*
// SetHTTPErrorHandler registers a custom Echo.HTTPErrorHandler.
func (nap *NapNap) SetHTTPErrorHandler(h HTTPErrorHandler) {
	//nap.httpErrorHandler = h
}

type (
	//MiddlewareFunc func(c *Context, next HandlerFunc)
	// HTTPErrorHandler is a centralized HTTP error handler.
	HTTPErrorHandler func(error)
)

// Conforms to the http.Handler interface.
func (nap *NapNap) ServeHTTP(w http.ResponseWriter, req *http.Request) {

	c := NewContext(req, w)

		for _, m := range nap.middlewares {
			m(c)
			if c.goNext == false {
				break
			}
		}

	// Execute chain
	h := nap.Router.Find(req.Method, req.URL.Path, c)

	if err := h(c); err != nil {
		//nap.httpErrorHandler(err)
	}
}
*/
<commit_msg>remove debug message<commit_after>package napnap

import "strings"

type Router struct {
	tree *tree
}

type tree struct {
	rootNode *node
}

type kind uint8

type node struct {
	parent    *node
	children  []*node
	kind      kind
	name      string
	pNames    []string
	params    []string
	sortOrder int
	handler   *methodHandler
}

type methodHandler struct {
	connect HandlerFunc
	delete  HandlerFunc
	get     HandlerFunc
	head    HandlerFunc
	options HandlerFunc
	patch   HandlerFunc
	post    HandlerFunc
	put     HandlerFunc
	trace   HandlerFunc
}

const (
	// CONNECT HTTP method
	CONNECT = "CONNECT"
	// DELETE HTTP method
	DELETE = "DELETE"
	// GET HTTP method
	GET = "GET"
	// HEAD HTTP method
	HEAD = "HEAD"
	// OPTIONS HTTP method
	OPTIONS = "OPTIONS"
	// PATCH HTTP method
	PATCH = "PATCH"
	// POST HTTP method
	POST = "POST"
	// PUT HTTP method
	PUT = "PUT"
	// TRACE HTTP method
	TRACE = "TRACE"
)

var (
	notFoundHandler = func(c *Context) {
		_logger.debug("NotFound")
	}
)

const (
	skind kind = iota
	pkind
)

// NewRouter function will create a new router instance
func NewRouter() *Router {
	return &Router{
		tree: &tree{
			rootNode: &node{
				parent:    nil,
				children:  []*node{},
				kind:      0,
				name:      "/",
				sortOrder: 0,
				handler:   &methodHandler{},
			},
		},
	}
}

// Invoke function is a middleware entry
func (r *Router) Invoke(c *Context, next HandlerFunc) {
	h := r.Find(c.Request.Method, c.Request.URL.Path, c)

	if h == nil {
		next(c)
	} else {
		h(c)
	}
}

// All is a shortcut for adding all methods
func (r *Router) All(path string, handler HandlerFunc) {
	r.Add(GET, path, handler)
	r.Add(POST, path, handler)
	r.Add(PUT, path, handler)
	r.Add(DELETE, path, handler)
	r.Add(PATCH, path, handler)
	r.Add(OPTIONS, path, handler)
	r.Add(HEAD, path, handler)
}

// Get is a shortcut for router.Add("GET", path, handle)
func (r *Router) Get(path string, handler HandlerFunc) {
	r.Add(GET, path, handler)
}

// Post is a shortcut for router.Add("POST", path, handle)
func (r *Router) Post(path string, handler HandlerFunc) {
	r.Add(POST, path, handler)
}

// Put is a shortcut for router.Add("PUT", path, handle)
func (r *Router) Put(path string, handler HandlerFunc) {
	r.Add(PUT, path, handler)
}

// Delete is a shortcut for router.Add("DELETE", path, handle)
func (r *Router) Delete(path string, handler HandlerFunc) {
	r.Add(DELETE, path, handler)
}

// Patch is a shortcut for router.Add("PATCH", path, handle)
func (r *Router) Patch(path string, handler HandlerFunc) {
	r.Add(PATCH, path, handler)
}

// Options is a shortcut for router.Add("OPTIONS", path, handle)
func (r *Router) Options(path string, handler HandlerFunc) {
	r.Add(OPTIONS, path, handler)
}

// Head is a shortcut for router.Add("HEAD", path, handle)
func (r *Router) Head(path string, handler HandlerFunc) {
	r.Add(HEAD, path, handler)
}

// Add function which adding path and handler to router
func (r *Router) Add(method string, path string, handler HandlerFunc) {
	_logger.debug("===Add")
	if len(path) == 0 {
		panic("router: path couldn't be empty")
	}

	if path[0:1] == "/" {
		path = path[1:]
	} else {
		panic("router: path was invalid")
	}

	_logger.debug("path:" + path)

	pathArray := strings.Split(path, "/")
	count := len(pathArray)

	currentNode := r.tree.rootNode
	pathParams := []string{}

	for index, element := range pathArray {
		if len(element) == 0 {
			continue
		}

		var childNode *node
		if element[0:1] == ":" {
			// that is parameter node
			pName := element[1:]
			_logger.debug("parameterName:" + pName)
			childNode = currentNode.findChildByKind(pkind)
			if childNode == nil {
				childNode = newNode(pName, pkind)
				currentNode.addChild(childNode)
			}

			isFound := false
			for _, p := range childNode.pNames {
				if p == pName {
					isFound = true
				}
			}

			if isFound == false {
				childNode.pNames = append(childNode.pNames, pName)
				_logger.debug("added_parameter_name:" + pName)
			}

			pathParams = append(pathParams, pName)

		} else {
			// that is static node
			childNode = currentNode.findChildByName(element)
			if childNode == nil {
				childNode = newNode(element, skind)
				currentNode.addChild(childNode)
			}
		}

		// last node in the path
		if count == index+1 {
			childNode.params = pathParams
			_logger.debug("lastNode_param:")
			_logger.debug("method:" + method)
			childNode.addHandler(method, handler)
		}

		currentNode = childNode
	}

	//test
	/*
		testNode := r.tree.rootNode.children[0].children[0]
		println("test_node_name: " + testNode.name)
		if method == POST {
			testNode.handler.post()
		}*/

}

// Find returns http handler for specific path
func (r *Router) Find(method string, path string, c *Context) HandlerFunc {
	_logger.debug("===Find")
	_logger.debug("method:" + method)
	_logger.debug("path:" + path)
	if path[0:1] == "/" {
		path = path[1:]
	}

	pathArray := strings.Split(path, "/")
	count := len(pathArray)

	currentNode := r.tree.rootNode

	pathParams := make(map[int][]Param)
	var paramsNum int

	for index, element := range pathArray {
		childNode := currentNode.findChildByName(element)

		if childNode == nil {
			// static node was not found and is looking for parameter node
			childNode = currentNode.findChildByKind(pkind)

			if childNode != nil {
				var newParams []Param
				for _, pName := range childNode.pNames {
					param := Param{Key: pName, Value: element}
					newParams = append(newParams, param)
				}
				pathParams[paramsNum] = newParams
				paramsNum++
			}
		}

		if childNode == nil {
			//return notFoundHandler
			return nil
		}

		// last node in the path
		if count == index+1 {
			myHandler := childNode.findHandler(method)
			if myHandler == nil {
				//return notFoundHandler
				_logger.debug("handler was not found")
				return nil
			}

			var newParams []Param
			for _, pName := range childNode.pNames {
				param := Param{Key: pName, Value: element}
				newParams = append(newParams, param)
			}
			pathParams[paramsNum] = newParams
			paramsNum++

			paramsNum = 0
			//println("params_count:", len(pathParams))
			_logger.debug("lastNode_params_count:", len(childNode.params))
			for _, validParam := range childNode.params {
				for _, p := range pathParams[paramsNum] {
					//println("p_value:", index, p.Key+"&"+p.Value)
					if validParam == p.Key {
						_logger.debug("matched: " + validParam + "," + p.Value)
						c.params = append(c.params, p)
					}
				}
				paramsNum++
			}

			return myHandler
		}

		currentNode = childNode
	}
	//return notFoundHandler
	return nil
}

func newNode(name string, t kind) *node {
	return &node{
		kind:      t,
		name:      name,
		sortOrder: 0,
		handler:   &methodHandler{},
	}
}

func (n *node) addChild(node *node) {
	node.parent = n
	n.children = append(n.children, node)
}

func (n *node) findChildByName(name string) *node {
	var result *node
	for _, element := range n.children {
		if element.name == name && element.kind == skind {
			result = element
			break
		}
	}
	return result
}

func (n *node) findChildByKind(t kind) *node {
	for _, c := range n.children {
		if c.kind == t {
			return c
		}
	}
	return nil
}

func (n *node) addHandler(method string, h HandlerFunc) {
	switch method {
	case GET:
		n.handler.get = h
	case POST:
		n.handler.post = h
	case PUT:
		n.handler.put = h
	case DELETE:
		n.handler.delete = h
	case PATCH:
		n.handler.patch = h
	case OPTIONS:
		n.handler.options = h
	case HEAD:
		n.handler.head = h
	case CONNECT:
		n.handler.connect = h
	case TRACE:
		n.handler.trace = h
	default:
		panic("method is not invalid or supported.")
	}
}

func (n *node) findHandler(method string) HandlerFunc {
	switch method {
	case GET:
		return n.handler.get
	case POST:
		return n.handler.post
	case PUT:
		return n.handler.put
	case DELETE:
		return n.handler.delete
	case PATCH:
		return n.handler.patch
	case OPTIONS:
		return n.handler.options
	case HEAD:
		return n.handler.head
	case CONNECT:
		return n.handler.connect
	case TRACE:
		return n.handler.trace
	default:
		panic("method is not invalid or supported.")
	}
}

/*
// SetHTTPErrorHandler registers a custom Echo.HTTPErrorHandler.
func (nap *NapNap) SetHTTPErrorHandler(h HTTPErrorHandler) {
	//nap.httpErrorHandler = h
}

type (
	//MiddlewareFunc func(c *Context, next HandlerFunc)
	// HTTPErrorHandler is a centralized HTTP error handler.
	HTTPErrorHandler func(error)
)

// Conforms to the http.Handler interface.
func (nap *NapNap) ServeHTTP(w http.ResponseWriter, req *http.Request) {

	c := NewContext(req, w)

		for _, m := range nap.middlewares {
			m(c)
			if c.goNext == false {
				break
			}
		}

	// Execute chain
	h := nap.Router.Find(req.Method, req.URL.Path, c)

	if err := h(c); err != nil {
		//nap.httpErrorHandler(err)
	}
}
*/
<|endoftext|>


<commit_before>package relay

import (
	"fmt"
	"net/http"
	"path"
	"regexp"
	"strings"
	"sync"

	"github.com/influx6/flux"
	"github.com/influx6/reggy"
)

// RHandler provides a custom route handler for http request with params
type RHandler func(http.ResponseWriter, *http.Request, Collector)

//WrapRouteHandlerFunc wraps http handler into a router RHandler
func WrapRouteHandlerFunc(r http.HandlerFunc) RHandler {
	return func(res http.ResponseWriter, req *http.Request, _ Collector) {
		r(res, req)
	}
}

//WrapRouteHandler wraps http handler into a router RHandler
func WrapRouteHandler(r http.Handler) RHandler {
	return func(res http.ResponseWriter, req *http.Request, _ Collector) {
		r.ServeHTTP(res, req)
	}
}

// Routable provides an interface for handling structs that accept routing
type Routable interface {
	Handle(http.ResponseWriter, *http.Request, Collector)
}

//Route define a specific route with its handler
type Route struct {
	*reggy.ClassicMatchMux
	handler  RHandler
	method   map[string]bool
	nomethod bool
}

// PanicHandler provides a panic function type for requests
type PanicHandler func(http.ResponseWriter, *http.Request, interface{})

//Routes is the base struct for defining interlinking routes
type Routes struct {
	namespace    string
	added        map[string]int
	routes       []*Route
	FailHandler  http.HandlerFunc
	PanicHandler PanicHandler
	ro           sync.RWMutex
}

//NewRoutes returns a new Routes instance
func NewRoutes(ns string) *Routes {
	return BuildRoutes(ns, nil, nil)
}

//BuildRoutes returns a new Routes instance
func BuildRoutes(ns string, failed http.HandlerFunc, panic PanicHandler) *Routes {
	ns = reggy.TrimSlashes(ns)
	rs := Routes{
		namespace:    ns,
		added:        make(map[string]int),
		FailHandler:  failed,
		PanicHandler: panic,
	}
	return &rs
}

// Namespace returns the path of the route with a added '/*' to endicate allowance of all paths,this is used by other routes to bind to a parent router
func (r *Routes) Namespace() string {
	if r.namespace == "" {
		return r.namespace
	}
	return reggy.CleanPath(fmt.Sprintf("/%s/*", r.namespace))
}

// Bind routes bind a router using the router namespace,except if the router namespace is an empty string
func (r *Routes) Bind(rx *Routes) error {
	if rx.Namespace() == "" {
		return NewCustomError("Router:Namespace.Error", "namespace is aqn empty string and not allowed")
	}

	r.Add("", rx.Namespace(), rx.Handle)
	return nil
}

//Handle provides a router handler for handling routes incoming from other routers
func (r *Routes) Handle(res http.ResponseWriter, req *http.Request, _ Collector) {
	r.ServeHTTP(res, req)
}

//ServeHTTP handles the a request cycle
func (r *Routes) ServeHTTP(res http.ResponseWriter, req *http.Request) {
	flux.RecoveryHandler("Route:ServeHTTP", func() error {
		r.ro.RLock()
		defer r.ro.RUnlock()
		mod := strings.ToLower(req.Method)
		for _, no := range r.routes {

			if no.method[mod] || no.nomethod {
				var ro string

				// check if namespace is not empty then combine the namespace else just use url path

				// if r.namespace != "" {
				// 	ro = fmt.Sprintf("%s/%s", r.namespace, req.URL.Path)
				// } else {
				ro = req.URL.Path
				// }

				// state, params := no.Validate(req.URL.Path)
				state, params := no.Validate(ro)
				if !state {
					continue
				}
				r.wrap(no, res, req, Collector(params))
				// break
				return nil

			}
		}
		r.doFail(res, req, nil)
		return nil
	})
}

// RouteOPTIONS sets the handler to only requests of this method
func (r *Routes) RouteOPTIONS(pattern string, h Routable) {
	r.Add("options", pattern, h.Handle)
}

// RoutePOST sets the handler to only requests of this method
func (r *Routes) RoutePOST(pattern string, h Routable) {
	r.Add("post", pattern, h.Handle)
}

// RoutePATCH sets the handler to only requests of this method
func (r *Routes) RoutePATCH(pattern string, h Routable) {
	r.Add("patch", pattern, h.Handle)
}

// RouteDELETE sets the handler to only requests of this method
func (r *Routes) RouteDELETE(pattern string, h Routable) {
	r.Add("delete", pattern, h.Handle)
}

// RoutePUT sets the handler to only requests of this method
func (r *Routes) RoutePUT(pattern string, h Routable) {
	r.Add("put", pattern, h.Handle)
}

// RouteHEAD sets the handler to only requests of this method
func (r *Routes) RouteHEAD(pattern string, h Routable) {
	r.Add("head", pattern, h.Handle)
}

// RouteGET sets the handler to only requests of this method
func (r *Routes) RouteGET(pattern string, h Routable) {
	r.Add("get", pattern, h.Handle)
}

// OPTIONS sets the handler to only requests of this method
func (r *Routes) OPTIONS(pattern string, h RHandler) {
	r.Add("options", pattern, h)
}

// POST sets the handler to only requests of this method
func (r *Routes) POST(pattern string, h RHandler) {
	r.Add("post", pattern, h)
}

// PATCH sets the handler to only requests of this method
func (r *Routes) PATCH(pattern string, h RHandler) {
	r.Add("patch", pattern, h)
}

// DELETE sets the handler to only requests of this method
func (r *Routes) DELETE(pattern string, h RHandler) {
	r.Add("delete", pattern, h)
}

// PUT sets the handler to only requests of this method
func (r *Routes) PUT(pattern string, h RHandler) {
	r.Add("put", pattern, h)
}

// HEAD sets the handler to only requests of this method
func (r *Routes) HEAD(pattern string, h RHandler) {
	r.Add("head", pattern, h)
}

// GET sets the handler to only requests of this method
func (r *Routes) GET(pattern string, h RHandler) {
	r.Add("get", pattern, h)
}

// ServeDir serves up a directory to the request
func (r *Routes) ServeDir(pattern, dir, strip string) {
	r.Add("get head", pattern+"/*", func(res http.ResponseWriter, req *http.Request, c Collector) {
		requested := reggy.CleanPath(req.URL.Path)
		file := strings.TrimPrefix(requested, strip)

		if err := ServeFile("index.html", dir, file, res, req); err != nil {
			r.doFail(res, req, c)
		}
	})
}

// ServeDirIndex serves up a directory to the request
func (r *Routes) ServeDirIndex(pattern, indexFile, dir, strip string) {
	r.Add("get head", pattern+"/*", func(res http.ResponseWriter, req *http.Request, c Collector) {
		requested := reggy.CleanPath(req.URL.Path)
		file := strings.TrimPrefix(requested, strip)

		if err := ServeFile(indexFile, dir, file, res, req); err != nil {
			r.doFail(res, req, c)
		}
	})
}

//ServeFile adds a only route for handling file requests
func (r *Routes) ServeFile(pattern, file string) {
	r.Add("get head", pattern, func(res http.ResponseWriter, req *http.Request, c Collector) {

		dir, file := path.Split(file)
		if err := ServeFile("", dir, file, res, req); err != nil {
			r.doFail(res, req, c)
		}
	})
}

var multispaces = regexp.MustCompile(`\s+`)

// Add adds a route into the sets of routes, method can be "" to allow all methods to be handled or a stringed range eg "get head put" to allow this range of methods(get,head,put) only for the handler
func (r *Routes) Add(mo, pattern string, h RHandler) {
	r.ro.Lock()
	defer r.ro.Unlock()

	var fatt string

	if r.namespace != "" {
		fatt = reggy.CleanPath(fmt.Sprintf("/%s/%s", r.namespace, pattern))
	} else {
		fatt = pattern
	}

	var mod = make(map[string]bool)

	if mo != "" {
		cln := multispaces.ReplaceAllString(mo, " ")

		amod := multispaces.Split(cln, -1)

		for _, ro := range amod {
			mod[ro] = true
		}
	}

	if _, ok := r.added[pattern]; !ok {
		r.added[pattern] = len(r.routes)
		r.routes = append(r.routes, &Route{
			ClassicMatchMux: reggy.CreateClassic(fatt),
			handler:         h,
			method:          mod,
			nomethod:        len(mod) == 0,
		})
	}
}

// HasRoute returns true/false if the pattern exists
func (r *Routes) HasRoute(pattern string) bool {
	_, ok := r.added[pattern]
	return ok
}

// FindRoute returns the route that matches the pattern
func (r *Routes) FindRoute(pattern string) (*Route, error) {
	if !r.HasRoute(pattern) {
		return nil, ErrorNotFind
	}
	return r.routes[r.added[pattern]], nil
}

func (r *Routes) recover(res http.ResponseWriter, req *http.Request) {
	if r.PanicHandler == nil {
		return
	}
	if err := recover(); err != nil {
		r.PanicHandler(res, req, err)
	}
}

func (r *Routes) doFail(res http.ResponseWriter, req *http.Request, ps Collector) {
	defer r.recover(res, req)
	if r.FailHandler == nil {
		http.NotFound(res, req)
	} else {
		r.FailHandler(res, req)
	}
}

func (r *Routes) wrap(rw *Route, res http.ResponseWriter, req *http.Request, ps Collector) {
	defer r.recover(res, req)
	rw.handler(res, req, ps)
}
<commit_msg>adding routing interface<commit_after>package relay

import (
	"fmt"
	"net/http"
	"path"
	"regexp"
	"strings"
	"sync"

	"github.com/influx6/flux"
	"github.com/influx6/reggy"
)

// RHandler provides a custom route handler for http request with params
type RHandler func(http.ResponseWriter, *http.Request, Collector)

//WrapRouteHandlerFunc wraps http handler into a router RHandler
func WrapRouteHandlerFunc(r http.HandlerFunc) RHandler {
	return func(res http.ResponseWriter, req *http.Request, _ Collector) {
		r(res, req)
	}
}

//WrapRouteHandler wraps http handler into a router RHandler
func WrapRouteHandler(r http.Handler) RHandler {
	return func(res http.ResponseWriter, req *http.Request, _ Collector) {
		r.ServeHTTP(res, req)
	}
}

// Routable provides an interface for handling structs that accept routing
type Routable interface {
	Handle(http.ResponseWriter, *http.Request, Collector)
}

// Routing provide a basic route interface
type Routing interface {
	Handle(http.ResponseWriter, *http.Request, Collector)
	Namespace() string
}

//Route define a specific route with its handler
type Route struct {
	*reggy.ClassicMatchMux
	handler  RHandler
	method   map[string]bool
	nomethod bool
}

// PanicHandler provides a panic function type for requests
type PanicHandler func(http.ResponseWriter, *http.Request, interface{})

//Routes is the base struct for defining interlinking routes
type Routes struct {
	namespace    string
	added        map[string]int
	routes       []*Route
	FailHandler  http.HandlerFunc
	PanicHandler PanicHandler
	ro           sync.RWMutex
}

//NewRoutes returns a new Routes instance
func NewRoutes(ns string) *Routes {
	return BuildRoutes(ns, nil, nil)
}

//BuildRoutes returns a new Routes instance
func BuildRoutes(ns string, failed http.HandlerFunc, panic PanicHandler) *Routes {
	ns = reggy.TrimSlashes(ns)
	rs := Routes{
		namespace:    ns,
		added:        make(map[string]int),
		FailHandler:  failed,
		PanicHandler: panic,
	}
	return &rs
}

// Namespace returns the path of the route with a added '/*' to endicate allowance of all paths,this is used by other routes to bind to a parent router
func (r *Routes) Namespace() string {
	if r.namespace == "" {
		return r.namespace
	}
	return reggy.CleanPath(fmt.Sprintf("/%s/*", r.namespace))
}

// Bind routes bind a router using the router namespace,except if the router namespace is an empty string
func (r *Routes) Bind(rx Routing) error {
	if rx.Namespace() == "" {
		return NewCustomError("Router:Namespace.Error", "namespace is aqn empty string and not allowed")
	}

	r.Add("", rx.Namespace(), rx.Handle)
	return nil
}

//Handle provides a router handler for handling routes incoming from other routers
func (r *Routes) Handle(res http.ResponseWriter, req *http.Request, _ Collector) {
	r.ServeHTTP(res, req)
}

//ServeHTTP handles the a request cycle
func (r *Routes) ServeHTTP(res http.ResponseWriter, req *http.Request) {
	flux.RecoveryHandler("Route:ServeHTTP", func() error {
		r.ro.RLock()
		defer r.ro.RUnlock()
		mod := strings.ToLower(req.Method)
		for _, no := range r.routes {

			if no.method[mod] || no.nomethod {
				var ro string

				// check if namespace is not empty then combine the namespace else just use url path

				// if r.namespace != "" {
				// 	ro = fmt.Sprintf("%s/%s", r.namespace, req.URL.Path)
				// } else {
				ro = req.URL.Path
				// }

				// state, params := no.Validate(req.URL.Path)
				state, params := no.Validate(ro)
				if !state {
					continue
				}
				r.wrap(no, res, req, Collector(params))
				// break
				return nil

			}
		}
		r.doFail(res, req, nil)
		return nil
	})
}

// RouteOPTIONS sets the handler to only requests of this method
func (r *Routes) RouteOPTIONS(pattern string, h Routable) {
	r.Add("options", pattern, h.Handle)
}

// RoutePOST sets the handler to only requests of this method
func (r *Routes) RoutePOST(pattern string, h Routable) {
	r.Add("post", pattern, h.Handle)
}

// RoutePATCH sets the handler to only requests of this method
func (r *Routes) RoutePATCH(pattern string, h Routable) {
	r.Add("patch", pattern, h.Handle)
}

// RouteDELETE sets the handler to only requests of this method
func (r *Routes) RouteDELETE(pattern string, h Routable) {
	r.Add("delete", pattern, h.Handle)
}

// RoutePUT sets the handler to only requests of this method
func (r *Routes) RoutePUT(pattern string, h Routable) {
	r.Add("put", pattern, h.Handle)
}

// RouteHEAD sets the handler to only requests of this method
func (r *Routes) RouteHEAD(pattern string, h Routable) {
	r.Add("head", pattern, h.Handle)
}

// RouteGET sets the handler to only requests of this method
func (r *Routes) RouteGET(pattern string, h Routable) {
	r.Add("get", pattern, h.Handle)
}

// OPTIONS sets the handler to only requests of this method
func (r *Routes) OPTIONS(pattern string, h RHandler) {
	r.Add("options", pattern, h)
}

// POST sets the handler to only requests of this method
func (r *Routes) POST(pattern string, h RHandler) {
	r.Add("post", pattern, h)
}

// PATCH sets the handler to only requests of this method
func (r *Routes) PATCH(pattern string, h RHandler) {
	r.Add("patch", pattern, h)
}

// DELETE sets the handler to only requests of this method
func (r *Routes) DELETE(pattern string, h RHandler) {
	r.Add("delete", pattern, h)
}

// PUT sets the handler to only requests of this method
func (r *Routes) PUT(pattern string, h RHandler) {
	r.Add("put", pattern, h)
}

// HEAD sets the handler to only requests of this method
func (r *Routes) HEAD(pattern string, h RHandler) {
	r.Add("head", pattern, h)
}

// GET sets the handler to only requests of this method
func (r *Routes) GET(pattern string, h RHandler) {
	r.Add("get", pattern, h)
}

// ServeDir serves up a directory to the request
func (r *Routes) ServeDir(pattern, dir, strip string) {
	r.Add("get head", pattern+"/*", func(res http.ResponseWriter, req *http.Request, c Collector) {
		requested := reggy.CleanPath(req.URL.Path)
		file := strings.TrimPrefix(requested, strip)

		if err := ServeFile("index.html", dir, file, res, req); err != nil {
			r.doFail(res, req, c)
		}
	})
}

// ServeDirIndex serves up a directory to the request
func (r *Routes) ServeDirIndex(pattern, indexFile, dir, strip string) {
	r.Add("get head", pattern+"/*", func(res http.ResponseWriter, req *http.Request, c Collector) {
		requested := reggy.CleanPath(req.URL.Path)
		file := strings.TrimPrefix(requested, strip)

		if err := ServeFile(indexFile, dir, file, res, req); err != nil {
			r.doFail(res, req, c)
		}
	})
}

//ServeFile adds a only route for handling file requests
func (r *Routes) ServeFile(pattern, file string) {
	r.Add("get head", pattern, func(res http.ResponseWriter, req *http.Request, c Collector) {

		dir, file := path.Split(file)
		if err := ServeFile("", dir, file, res, req); err != nil {
			r.doFail(res, req, c)
		}
	})
}

var multispaces = regexp.MustCompile(`\s+`)

// Add adds a route into the sets of routes, method can be "" to allow all methods to be handled or a stringed range eg "get head put" to allow this range of methods(get,head,put) only for the handler
func (r *Routes) Add(mo, pattern string, h RHandler) {
	r.ro.Lock()
	defer r.ro.Unlock()

	var fatt string

	if r.namespace != "" {
		fatt = reggy.CleanPath(fmt.Sprintf("/%s/%s", r.namespace, pattern))
	} else {
		fatt = pattern
	}

	var mod = make(map[string]bool)

	if mo != "" {
		cln := multispaces.ReplaceAllString(mo, " ")

		amod := multispaces.Split(cln, -1)

		for _, ro := range amod {
			mod[ro] = true
		}
	}

	if _, ok := r.added[pattern]; !ok {
		r.added[pattern] = len(r.routes)
		r.routes = append(r.routes, &Route{
			ClassicMatchMux: reggy.CreateClassic(fatt),
			handler:         h,
			method:          mod,
			nomethod:        len(mod) == 0,
		})
	}
}

// HasRoute returns true/false if the pattern exists
func (r *Routes) HasRoute(pattern string) bool {
	_, ok := r.added[pattern]
	return ok
}

// FindRoute returns the route that matches the pattern
func (r *Routes) FindRoute(pattern string) (*Route, error) {
	if !r.HasRoute(pattern) {
		return nil, ErrorNotFind
	}
	return r.routes[r.added[pattern]], nil
}

func (r *Routes) recover(res http.ResponseWriter, req *http.Request) {
	if r.PanicHandler == nil {
		return
	}
	if err := recover(); err != nil {
		r.PanicHandler(res, req, err)
	}
}

func (r *Routes) doFail(res http.ResponseWriter, req *http.Request, ps Collector) {
	defer r.recover(res, req)
	if r.FailHandler == nil {
		http.NotFound(res, req)
	} else {
		r.FailHandler(res, req)
	}
}

func (r *Routes) wrap(rw *Route, res http.ResponseWriter, req *http.Request, ps Collector) {
	defer r.recover(res, req)
	rw.handler(res, req, ps)
}
<|endoftext|>


<commit_before>// Copyright (C) 2016, 2017 Nicolas Lamirault <nicolas.lamirault@gmail.com>

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"bytes"
	"fmt"
	"log"
	"strings"

	"github.com/go-telegram-bot-api/telegram-bot-api"

	"github.com/zeiot/jarvis-bot/k8s"
	"github.com/zeiot/jarvis-bot/version"
)

var (
	botName = "Jarvis"

	messages = map[string]string{
		"Help": `You can use the following commands:
/releases : Display last release of components
/help     : Display help message
/about    : About this bot
/version  : Show bot version
	`,
	}
)

func route(bot *tgbotapi.BotAPI, update tgbotapi.Update, k8sclient *k8s.Client) {
	tokens := strings.Fields(update.Message.Text)
	command := tokens[0]
	switch command {
	case "/help":
		msg := tgbotapi.NewMessage(update.Message.Chat.ID, messages["Help"])
		bot.Send(msg)
	case "/help@" + botName:
		msg := tgbotapi.NewMessage(update.Message.Chat.ID, messages["Help"])
		bot.Send(msg)
	case "/about":
		msg := getAboutMessage()
		bot.Send(msg)
	case "/releases":
		text := getReleases()
		msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
		bot.Send(msg)
	case "/k8s-services":
		text := getKubernetesServices(k8sclient)
		msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
		bot.Send(msg)
	case "/version":
		msg := tgbotapi.NewMessage(update.Message.Chat.ID, fmt.Sprintf("v%s", version.Version))
		bot.Send(msg)
	}
}

func getKubernetesServices(k8sclient *k8s.Client) string {
	var buffer bytes.Buffer
	buffer.WriteString("Kubernetes Services:\n")
	services, err := k8sclient.GetServices()
	if err != nil {
		log.Printf("[ERROR] Kubernetes services: %s", err.Error())
		buffer.WriteString("Can't retrieve Kubernetes services")
		return buffer.String()
	}
	for _, service := range services.Items {
		buffer.WriteString(fmt.Sprintf("- %s\n", service.Name))
	}
	text := buffer.String()
	log.Printf("[INFO] Kubernetes services: %s", text)
	return text
}

func getAboutMessage() string {
	var buffer bytes.Buffer
	buffer.WriteString("Telegram bot for Jarvis platform.\n")
	buffer.WriteString("Homepage: https://github.com/zeiot/jarvis-bot\n")
	buffer.WriteString("Releases: https://github.com/zeiot/jarvis-bot/releases\n")
	buffer.WriteString("Issues: https://github.com/zeiot/jarvis-bot/issues\n")
	text := buffer.String()
	return text
}
<commit_msg>Fix About command<commit_after>// Copyright (C) 2016, 2017 Nicolas Lamirault <nicolas.lamirault@gmail.com>

// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at

//     http://www.apache.org/licenses/LICENSE-2.0

// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
	"bytes"
	"fmt"
	"log"
	"strings"

	"github.com/go-telegram-bot-api/telegram-bot-api"

	"github.com/zeiot/jarvis-bot/k8s"
	"github.com/zeiot/jarvis-bot/version"
)

var (
	botName = "Jarvis"

	messages = map[string]string{
		"Help": `You can use the following commands:
/releases : Display last release of components
/help     : Display help message
/about    : About this bot
/version  : Show bot version
	`,
	}
)

func route(bot *tgbotapi.BotAPI, update tgbotapi.Update, k8sclient *k8s.Client) {
	tokens := strings.Fields(update.Message.Text)
	command := tokens[0]
	switch command {
	case "/help":
		msg := tgbotapi.NewMessage(update.Message.Chat.ID, messages["Help"])
		bot.Send(msg)
	case "/help@" + botName:
		msg := tgbotapi.NewMessage(update.Message.Chat.ID, messages["Help"])
		bot.Send(msg)
	case "/about":
		text := getAboutMessage()
		tgbotapi.NewMessage(update.Message.Chat.ID, text)
		bot.Send(msg)
	case "/releases":
		text := getReleases()
		msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
		bot.Send(msg)
	case "/k8s-services":
		text := getKubernetesServices(k8sclient)
		msg := tgbotapi.NewMessage(update.Message.Chat.ID, text)
		bot.Send(msg)
	case "/version":
		msg := tgbotapi.NewMessage(update.Message.Chat.ID, fmt.Sprintf("v%s", version.Version))
		bot.Send(msg)
	}
}

func getKubernetesServices(k8sclient *k8s.Client) string {
	var buffer bytes.Buffer
	buffer.WriteString("Kubernetes Services:\n")
	services, err := k8sclient.GetServices()
	if err != nil {
		log.Printf("[ERROR] Kubernetes services: %s", err.Error())
		buffer.WriteString("Can't retrieve Kubernetes services")
		return buffer.String()
	}
	for _, service := range services.Items {
		buffer.WriteString(fmt.Sprintf("- %s\n", service.Name))
	}
	text := buffer.String()
	log.Printf("[INFO] Kubernetes services: %s", text)
	return text
}

func getAboutMessage() string {
	var buffer bytes.Buffer
	buffer.WriteString("Telegram bot for Jarvis platform.\n")
	buffer.WriteString("Homepage: https://github.com/zeiot/jarvis-bot\n")
	buffer.WriteString("Releases: https://github.com/zeiot/jarvis-bot/releases\n")
	buffer.WriteString("Issues: https://github.com/zeiot/jarvis-bot/issues\n")
	text := buffer.String()
	return text
}
<|endoftext|>


<commit_before>package main

import (
	mux "github.com/julienschmidt/httprouter"
)

// Struct of route data
type Route struct {
	Method 	string
	Path	string
	Handle 	mux.Handle
}

// Slice to hold Route structs
type Routes []Route

var routes = Routes{

	Route{
		"GET",
		"/",
		Index,
	},

	Route{
		"GET",
		"/houses",
		HouseIndex,
	},

	Route{
		"GET",
		"/new",
		HouseNew,
	},

    Route{
        "POST",
        "/create",
        HouseCreate,
    }

    /*
	Route{
		"POST",
		"/houses",
		HouseCreate,
	},
    */

	Route{
		"GET",
		"/houses/id/:id",
		HouseById,
	},

	Route{
		"GET",
		"/houses/city/:city",
		HouseByCity,
	},

	Route{
		"GET",
		"/houses/state/:state",
		HouseByState,
	},
}<commit_msg>fix routes.go<commit_after>package main

import (
	mux "github.com/julienschmidt/httprouter"
)

// Struct of route data
type Route struct {
	Method 	string
	Path	string
	Handle 	mux.Handle
}

// Slice to hold Route structs
type Routes []Route

var routes = Routes{

	Route{
		"GET",
		"/",
		Index,
	},

	Route{
		"GET",
		"/houses",
		HouseIndex,
	},

	Route{
		"GET",
		"/new",
		HouseNew,
	},

    	Route{
		"POST",
		"/create",
        	HouseCreate,
    	},

    /*
	Route{
		"POST",
		"/houses",
		HouseCreate,
	},
    */

	Route{
		"GET",
		"/houses/id/:id",
		HouseById,
	},

	Route{
		"GET",
		"/houses/city/:city",
		HouseByCity,
	},

	Route{
		"GET",
		"/houses/state/:state",
		HouseByState,
	},
}<|endoftext|>


<commit_before>package game

import (
	"sync"
	"time"

	"buildblast/lib/coords"
	"buildblast/lib/mapgen"
)

type ChunkGenerator struct {
	// Chunks are sent to this channel as they are generated
	Generated chan ChunkGenerationResult

	chunks    map[coords.Chunk]ChunkStatus
	mutex     sync.Mutex
	generator mapgen.Generator
}

type ChunkGenerationResult struct {
	cc    coords.Chunk
	chunk *mapgen.Chunk
}

type ChunkStatus struct {
	generated bool
	priority  int
}

func NewChunkGenerator(generator mapgen.Generator) *ChunkGenerator {
	cm := new(ChunkGenerator)
	cm.chunks = make(map[coords.Chunk]ChunkStatus, 10)
	cm.Generated = make(chan ChunkGenerationResult, 10)
	cm.generator = generator
	return cm
}

// cm.Lock() MUST BE HELD by the caller, or else calling
// this function is unsafe.
func (cm *ChunkGenerator) queue(cc coords.Chunk, priority int) {
	status := cm.chunks[cc]
	if status.generated {
		return
	}
	status.priority += priority
	cm.chunks[cc] = status
}

func (cm *ChunkGenerator) QueueChunksNearby(wc coords.World) {
	cm.mutex.Lock()
	defer cm.mutex.Unlock()

	queue := func(cc coords.Chunk, priority int) {
		cm.queue(cc, priority)
	}

	EachChunkNearby(wc, queue)
}

func (cm *ChunkGenerator) Top() (cc coords.Chunk, valid bool) {
	cm.mutex.Lock()
	defer cm.mutex.Unlock()

	highest := -1
	for key, val := range cm.chunks {
		if val.priority > highest && !val.generated {
			highest = val.priority
			cc = key
		}
	}
	if highest != -1 {
		return cc, true
	}
	return cc, false
}

func (cm *ChunkGenerator) Run() {
	for {
		cc, valid := cm.Top()
		if !valid {
			<-time.After(time.Second / 10)
			continue
		}

		chunk := cm.generator.Chunk(cc)

		cm.Generated <- ChunkGenerationResult{
			cc:    cc,
			chunk: chunk,
		}

		cm.mutex.Lock()
		status := cm.chunks[cc]
		status.generated = true
		cm.chunks[cc] = status
		cm.mutex.Unlock()
	}
}

func EachChunkNearby(wc coords.World, cb func(cc coords.Chunk, priority int)) {
	occ := func(cc coords.Chunk, x, y, z int) coords.Chunk {
		return coords.Chunk{
			X: cc.X + x,
			Y: cc.Y + y,
			Z: cc.Z + z,
		}
	}

	eachWithin := func(cc coords.Chunk, xdist, ydist, zdist int, cb func(newCC coords.Chunk, dist int)) {
		abs := func(n int) int {
			if n < 0 {
				return -n
			}
			return n
		}
		dist := func(x, y, z int) int {
			return abs(x) + abs(y) + abs(z)
		}

		cb(cc, 0)
		for x := -xdist; x <= xdist; x++ {
			for y := -ydist; y <= ydist; y++ {
				for z := -zdist; z <= zdist; z++ {
					cb(occ(cc, x, y, z), dist(x, y, z))
				}
			}
		}
	}

	cc := wc.Chunk()
	eachWithin(cc, 2, 0, 2, func(newCC coords.Chunk, dist int) {
		// We want to prioritize further away chunks lower, but the
		// priority must be a positive integer.
		cb(newCC, 10-dist)
	})

	oc := wc.Offset()
	if oc.Y <= 4 {
		cb(occ(cc, 0, -1, 0), 1)
	} else if oc.Y >= 28 {
		cb(occ(cc, 0, 1, 0), 1)
	}
}
<commit_msg>Load some chunks on the Y axis.<commit_after>package game

import (
	"sync"
	"time"

	"buildblast/lib/coords"
	"buildblast/lib/mapgen"
)

type ChunkGenerator struct {
	// Chunks are sent to this channel as they are generated
	Generated chan ChunkGenerationResult

	chunks    map[coords.Chunk]ChunkStatus
	mutex     sync.Mutex
	generator mapgen.Generator
}

type ChunkGenerationResult struct {
	cc    coords.Chunk
	chunk *mapgen.Chunk
}

type ChunkStatus struct {
	generated bool
	priority  int
}

func NewChunkGenerator(generator mapgen.Generator) *ChunkGenerator {
	cm := new(ChunkGenerator)
	cm.chunks = make(map[coords.Chunk]ChunkStatus, 10)
	cm.Generated = make(chan ChunkGenerationResult, 10)
	cm.generator = generator
	return cm
}

// cm.Lock() MUST BE HELD by the caller, or else calling
// this function is unsafe.
func (cm *ChunkGenerator) queue(cc coords.Chunk, priority int) {
	status := cm.chunks[cc]
	if status.generated {
		return
	}
	status.priority += priority
	cm.chunks[cc] = status
}

func (cm *ChunkGenerator) QueueChunksNearby(wc coords.World) {
	cm.mutex.Lock()
	defer cm.mutex.Unlock()

	queue := func(cc coords.Chunk, priority int) {
		cm.queue(cc, priority)
	}

	EachChunkNearby(wc, queue)
}

func (cm *ChunkGenerator) Top() (cc coords.Chunk, valid bool) {
	cm.mutex.Lock()
	defer cm.mutex.Unlock()

	highest := -1
	for key, val := range cm.chunks {
		if val.priority > highest && !val.generated {
			highest = val.priority
			cc = key
		}
	}
	if highest != -1 {
		return cc, true
	}
	return cc, false
}

func (cm *ChunkGenerator) Run() {
	for {
		cc, valid := cm.Top()
		if !valid {
			<-time.After(time.Second / 10)
			continue
		}

		chunk := cm.generator.Chunk(cc)

		cm.Generated <- ChunkGenerationResult{
			cc:    cc,
			chunk: chunk,
		}

		cm.mutex.Lock()
		status := cm.chunks[cc]
		status.generated = true
		cm.chunks[cc] = status
		cm.mutex.Unlock()
	}
}

func EachChunkNearby(wc coords.World, cb func(cc coords.Chunk, priority int)) {
	occ := func(cc coords.Chunk, x, y, z int) coords.Chunk {
		return coords.Chunk{
			X: cc.X + x,
			Y: cc.Y + y,
			Z: cc.Z + z,
		}
	}

	eachWithin := func(cc coords.Chunk, xdist, ydist, zdist int, cb func(newCC coords.Chunk, dist int)) {
		abs := func(n int) int {
			if n < 0 {
				return -n
			}
			return n
		}
		dist := func(x, y, z int) int {
			return abs(x) + abs(y) + abs(z)
		}

		cb(cc, 0)
		for x := -xdist; x <= xdist; x++ {
			for y := -ydist; y <= ydist; y++ {
				for z := -zdist; z <= zdist; z++ {
					cb(occ(cc, x, y, z), dist(x, y, z))
				}
			}
		}
	}

	cc := wc.Chunk()
	eachWithin(cc, 2, 1, 2, func(newCC coords.Chunk, dist int) {
		// We want to prioritize further away chunks lower, but the
		// priority must be a positive integer.
		cb(newCC, 10-dist)
	})

	oc := wc.Offset()
	if oc.Y <= 4 {
		cb(occ(cc, 0, -1, 0), 1)
	} else if oc.Y >= 28 {
		cb(occ(cc, 0, 1, 0), 1)
	}
}
<|endoftext|>


<commit_before>package git

import (
	"os/exec"
)

type commandRunner interface {
	BranchCommand(string) ([]byte, error)
	BranchCommand2(string) ([]byte, error)
	ShaCommand(string) ([]byte, error)
	TagCommand(string) ([]byte, error)
	CleanCommand(string) ([]byte, error)
	UpToDateLocal(string) ([]byte, error)
	UpToDateRemote(string) ([]byte, error)
	UpToDateBase(string) ([]byte, error)
	RemoteV(string) ([]byte, error)
}

type realRunner struct{}
type fakeRunner struct {
	branch         string
	branch2        string
	sha            string
	tag            string
	clean          string
	upToDateLocal  string
	upToDateRemote string
	upToDateBase   string
	remoteV        string
}

// branch 1

func (r *realRunner) BranchCommand(top string) ([]byte, error) {
	cmd := exec.Command("git", "rev-parse", "-q", "--abbrev-ref", "HEAD")
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) BranchCommand(top string) ([]byte, error) {
	return []byte(f.branch), nil
}

// branch 2

func (r *realRunner) BranchCommand2(top string) ([]byte, error) {
	cmd := exec.Command("git", "branch", "-ra", "--contains", Sha(top))
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) BranchCommand2(top string) ([]byte, error) {
	return []byte(f.branch2), nil
}

// sha

func (r *realRunner) ShaCommand(top string) ([]byte, error) {
	cmd := exec.Command("git", "rev-parse", "-q", "HEAD")
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) ShaCommand(top string) ([]byte, error) {
	return []byte(f.sha), nil
}

// tag

func (r *realRunner) TagCommand(top string) ([]byte, error) {
	cmd := exec.Command("git", "describe", "--always", "--dirty", "--tags")
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) TagCommand(top string) ([]byte, error) {
	return []byte(f.tag), nil
}

// clean

func (r *realRunner) CleanCommand(top string) ([]byte, error) {
	cmd := exec.Command("git", "diff", "--shortstat")
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) CleanCommand(top string) ([]byte, error) {
	return []byte(f.clean), nil
}

// up to date local

func (r *realRunner) UpToDateLocal(top string) ([]byte, error) {
	cmd := exec.Command("git", "rev-parse", "@")
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) UpToDateLocal(top string) ([]byte, error) {
	return []byte(f.upToDateLocal), nil
}

// up to date remote

func (r *realRunner) UpToDateRemote(top string) ([]byte, error) {
	cmd := exec.Command("git", "rev-parse", "@{u}")
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) UpToDateRemote(top string) ([]byte, error) {
	return []byte(f.upToDateRemote), nil
}

// up to date base

func (r *realRunner) UpToDateBase(top string) ([]byte, error) {
	cmd := exec.Command("git", "merge-base", "@", "@{u}")
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) UpToDateBase(top string) ([]byte, error) {
	return []byte(f.upToDateBase), nil
}

// remote

func (r *realRunner) RemoteV(top string) ([]byte, error) {
	cmd := exec.Command("git", "remote", "-v")
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) RemoteV(top string) ([]byte, error) {
	return []byte(f.remoteV), nil
}

func run(cr commandRunner) {
}

func otherFunc() {
	run(&realRunner{})
	run(&fakeRunner{})
}
<commit_msg>Oops, forgot to remove these functions<commit_after>package git

import (
	"os/exec"
)

type commandRunner interface {
	BranchCommand(string) ([]byte, error)
	BranchCommand2(string) ([]byte, error)
	ShaCommand(string) ([]byte, error)
	TagCommand(string) ([]byte, error)
	CleanCommand(string) ([]byte, error)
	UpToDateLocal(string) ([]byte, error)
	UpToDateRemote(string) ([]byte, error)
	UpToDateBase(string) ([]byte, error)
	RemoteV(string) ([]byte, error)
}

type realRunner struct{}
type fakeRunner struct {
	branch         string
	branch2        string
	sha            string
	tag            string
	clean          string
	upToDateLocal  string
	upToDateRemote string
	upToDateBase   string
	remoteV        string
}

// branch 1

func (r *realRunner) BranchCommand(top string) ([]byte, error) {
	cmd := exec.Command("git", "rev-parse", "-q", "--abbrev-ref", "HEAD")
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) BranchCommand(top string) ([]byte, error) {
	return []byte(f.branch), nil
}

// branch 2

func (r *realRunner) BranchCommand2(top string) ([]byte, error) {
	cmd := exec.Command("git", "branch", "-ra", "--contains", Sha(top))
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) BranchCommand2(top string) ([]byte, error) {
	return []byte(f.branch2), nil
}

// sha

func (r *realRunner) ShaCommand(top string) ([]byte, error) {
	cmd := exec.Command("git", "rev-parse", "-q", "HEAD")
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) ShaCommand(top string) ([]byte, error) {
	return []byte(f.sha), nil
}

// tag

func (r *realRunner) TagCommand(top string) ([]byte, error) {
	cmd := exec.Command("git", "describe", "--always", "--dirty", "--tags")
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) TagCommand(top string) ([]byte, error) {
	return []byte(f.tag), nil
}

// clean

func (r *realRunner) CleanCommand(top string) ([]byte, error) {
	cmd := exec.Command("git", "diff", "--shortstat")
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) CleanCommand(top string) ([]byte, error) {
	return []byte(f.clean), nil
}

// up to date local

func (r *realRunner) UpToDateLocal(top string) ([]byte, error) {
	cmd := exec.Command("git", "rev-parse", "@")
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) UpToDateLocal(top string) ([]byte, error) {
	return []byte(f.upToDateLocal), nil
}

// up to date remote

func (r *realRunner) UpToDateRemote(top string) ([]byte, error) {
	cmd := exec.Command("git", "rev-parse", "@{u}")
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) UpToDateRemote(top string) ([]byte, error) {
	return []byte(f.upToDateRemote), nil
}

// up to date base

func (r *realRunner) UpToDateBase(top string) ([]byte, error) {
	cmd := exec.Command("git", "merge-base", "@", "@{u}")
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) UpToDateBase(top string) ([]byte, error) {
	return []byte(f.upToDateBase), nil
}

// remote

func (r *realRunner) RemoteV(top string) ([]byte, error) {
	cmd := exec.Command("git", "remote", "-v")
	cmd.Dir = top
	return cmd.Output()
}

func (f *fakeRunner) RemoteV(top string) ([]byte, error) {
	return []byte(f.remoteV), nil
}
<|endoftext|>


<commit_before>package main
import (
	"./sample"
	"os"
	"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore"
)

func main() {
	// Replace the endpoint info
	endpoint := os.Getenv("TS_TEST_ENDPOINT")
	instanceName := os.Getenv("TS_TEST_INSTANCENAME")
	accessKeyId := os.Getenv("TS_TEST_KEYID")
	accessKeySecret := os.Getenv("TS_TEST_SECRET")
	client := tablestore.NewClient(endpoint, instanceName, accessKeyId, accessKeySecret)

	// Table operation
	sample.CreateTableSample(client, "sampletable")
	sample.CreateTableKeyAutoIncrementSample(client)
	sample.DeleteTableSample(client)
	sample.ListTableSample(client)
	sample.UpdateTableSample(client, "sampletable")
	sample.DescribeTableSample(client, "sampletable")

	// Single row operation
	sample.PutRowSample(client,"sampletable")
	sample.UpdateRowSample(client, "sampletable")
	sample.GetRowSample(client, "sampletable")
	sample.DeleteRowSample(client, "sampletable")
	sample.PutRowWithKeyAutoIncrementSample(client)

	// Multi row operation
	sample.BatchWriteRowSample(client,"sampletable")
	sample.BatchGetRowSample(client, "sampletable")
	sample.GetRangeSample(client, "sampletable")
}<commit_msg>update import<commit_after>package main
import (
	"os"
	"github.com/aliyun/aliyun-tablestore-go-sdk/tablestore"
	"github.com/aliyun/aliyun-tablestore-go-sdk/sample"
)

func main() {
	// Replace the endpoint info
	endpoint := os.Getenv("TS_TEST_ENDPOINT")
	instanceName := os.Getenv("TS_TEST_INSTANCENAME")
	accessKeyId := os.Getenv("TS_TEST_KEYID")
	accessKeySecret := os.Getenv("TS_TEST_SECRET")
	client := tablestore.NewClient(endpoint, instanceName, accessKeyId, accessKeySecret)

	// Table operation
	sample.CreateTableSample(client, "sampletable")
	sample.CreateTableKeyAutoIncrementSample(client)
	sample.DeleteTableSample(client)
	sample.ListTableSample(client)
	sample.UpdateTableSample(client, "sampletable")
	sample.DescribeTableSample(client, "sampletable")

	// Single row operation
	sample.PutRowSample(client,"sampletable")
	sample.UpdateRowSample(client, "sampletable")
	sample.GetRowSample(client, "sampletable")
	sample.DeleteRowSample(client, "sampletable")
	sample.PutRowWithKeyAutoIncrementSample(client)

	// Multi row operation
	sample.BatchWriteRowSample(client,"sampletable")
	sample.BatchGetRowSample(client, "sampletable")
	sample.GetRangeSample(client, "sampletable")
}<|endoftext|>


<commit_before>// +build nacl

package websocket

import (
	"net"
	"net/url"
	"runtime/ppapi"
	"sync"
	"time"
)

// Ppapi instance which must be set before the Dial is called.
var PpapiInstance ppapi.Instance

func WebsocketConn(address string, ws *ppapi.WebsocketConn) net.Conn {
	return &wrappedConn{
		address: address,
		ws:      ws,
	}
}

type wrappedConn struct {
	address    string
	ws         *ppapi.WebsocketConn
	readLock   sync.Mutex
	writeLock  sync.Mutex
	currBuffer []byte
}

func Dial(address string) (net.Conn, error) {
	inst := PpapiInstance
	u, err := url.Parse("ws://" + address)
	if err != nil {
		return nil, err
	}

	ws, err := inst.DialWebsocket(u.String())
	if err != nil {
		return nil, err
	}
	return WebsocketConn(address, ws), nil
}

func (c *wrappedConn) Read(b []byte) (int, error) {
	c.readLock.Lock()
	defer c.readLock.Unlock()

	var err error
	if len(c.currBuffer) == 0 {
		c.currBuffer, err = c.ws.ReceiveMessage()
		if err != nil {
			return 0, nil
		}
	}

	n := copy(b, c.currBuffer)
	c.currBuffer = c.currBuffer[n:]
	return n, nil
}

func (c *wrappedConn) Write(b []byte) (int, error) {
	c.writeLock.Lock()
	defer c.writeLock.Unlock()
	if err := c.ws.SendMessage(b); err != nil {
		return 0, err
	}
	return len(b), nil
}

func (c *wrappedConn) Close() error {
	return c.ws.Close()
}

func (c *wrappedConn) LocalAddr() net.Addr {
	return websocketAddr{s: c.address}
}

func (c *wrappedConn) RemoteAddr() net.Addr {
	return websocketAddr{s: c.address}
}

func (c *wrappedConn) SetDeadline(t time.Time) error {
	panic("SetDeadline not implemented.")
}

func (c *wrappedConn) SetReadDeadline(t time.Time) error {
	panic("SetReadDeadline not implemented.")
}

func (c *wrappedConn) SetWriteDeadline(t time.Time) error {
	panic("SetWriteDeadline not implemented.")
}

type websocketAddr struct {
	s string
}

func (websocketAddr) Network() string {
	return "ws"
}

func (w websocketAddr) String() string {
	return w.s
}
<commit_msg>veyron/lib/websocket: Fix bug in conn_nacl.<commit_after>// +build nacl

package websocket

import (
	"net"
	"net/url"
	"runtime/ppapi"
	"sync"
	"time"
)

// Ppapi instance which must be set before the Dial is called.
var PpapiInstance ppapi.Instance

func WebsocketConn(address string, ws *ppapi.WebsocketConn) net.Conn {
	return &wrappedConn{
		address: address,
		ws:      ws,
	}
}

type wrappedConn struct {
	address    string
	ws         *ppapi.WebsocketConn
	readLock   sync.Mutex
	writeLock  sync.Mutex
	currBuffer []byte
}

func Dial(address string) (net.Conn, error) {
	inst := PpapiInstance
	u, err := url.Parse("ws://" + address)
	if err != nil {
		return nil, err
	}

	ws, err := inst.DialWebsocket(u.String())
	if err != nil {
		return nil, err
	}
	return WebsocketConn(address, ws), nil
}

func (c *wrappedConn) Read(b []byte) (int, error) {
	c.readLock.Lock()
	defer c.readLock.Unlock()

	var err error
	if len(c.currBuffer) == 0 {
		c.currBuffer, err = c.ws.ReceiveMessage()
		if err != nil {
			return 0, err
		}
	}

	n := copy(b, c.currBuffer)
	c.currBuffer = c.currBuffer[n:]
	return n, nil
}

func (c *wrappedConn) Write(b []byte) (int, error) {
	c.writeLock.Lock()
	defer c.writeLock.Unlock()
	if err := c.ws.SendMessage(b); err != nil {
		return 0, err
	}
	return len(b), nil
}

func (c *wrappedConn) Close() error {
	return c.ws.Close()
}

func (c *wrappedConn) LocalAddr() net.Addr {
	return websocketAddr{s: c.address}
}

func (c *wrappedConn) RemoteAddr() net.Addr {
	return websocketAddr{s: c.address}
}

func (c *wrappedConn) SetDeadline(t time.Time) error {
	panic("SetDeadline not implemented.")
}

func (c *wrappedConn) SetReadDeadline(t time.Time) error {
	panic("SetReadDeadline not implemented.")
}

func (c *wrappedConn) SetWriteDeadline(t time.Time) error {
	panic("SetWriteDeadline not implemented.")
}

type websocketAddr struct {
	s string
}

func (websocketAddr) Network() string {
	return "ws"
}

func (w websocketAddr) String() string {
	return w.s
}
<|endoftext|>