<commit_before>package main

import (
	"fmt"
	"time"
)

const defaultTimeout = time.Second * 30

type Step interface {
	Execute(Runtime, TaskReporter) error
	Description() string
}

type StopStep struct {
	services []string
}

func NewStopStep(config StepConfig) Step {
	return &StopStep{
		services: config.Stop,
	}
}

func (s *StopStep) Execute(runtime Runtime, reporter TaskReporter) error {
	return runtime.StopServices(s.services...)
}

func (s *StopStep) Description() string {
	return fmt.Sprintf("<Stop: %v>", s.services)
}

type StartStep struct {
	services []string
}

func NewStartStep(config StepConfig) Step {
	return &StartStep{
		services: config.Start,
	}
}

func (s *StartStep) Execute(runtime Runtime, reporter TaskReporter) error {
	return runtime.StartServices(s.services...)
}

func (s *StartStep) Description() string {
	return fmt.Sprintf("<Start: %v>", s.services)
}

type WaitStep struct {
	task TaskConfig
	env  TaskEnvironment
}

func NewWaitStep(task TaskConfig, env TaskEnvironment) Step {
	return &WaitStep{
		task: task,
		env:  env,
	}
}

func (s *WaitStep) Execute(runtime Runtime, reporter TaskReporter) error {
	timeout := time.After(defaultTimeout)
	for {
		if err := runtime.ExecuteTask(s.task, s.env, reporter); err == nil {
			return nil
		}
		select {
		case <-timeout:
			return fmt.Errorf("Task never completed successfully")
		default:
			if err := runtime.ExecuteTask(s.task, s.env, reporter); err == nil {
				return nil
			}
		}
	}
}

func (s *WaitStep) Description() string {
	return fmt.Sprintf("<Wait: %s>", s.task.Name)
}

type AssertStep struct {
	task TaskConfig
	env  TaskEnvironment
}

func NewAssertStep(task TaskConfig, env TaskEnvironment) Step {
	return &AssertStep{
		task: task,
		env:  env,
	}
}

func (s *AssertStep) Execute(runtime Runtime, reporter TaskReporter) error {
	return runtime.ExecuteTask(s.task, s.env, reporter)
}

func (s *AssertStep) Description() string {
	return fmt.Sprintf("<Assert: %s>", s.task.Name)
}

type FailStep struct {
	task TaskConfig
	env  TaskEnvironment
}

func NewFailStep(task TaskConfig, env TaskEnvironment) Step {
	return &FailStep{
		task: task,
		env:  env,
	}
}

func (s *FailStep) Execute(runtime Runtime, reporter TaskReporter) error {
	if err := runtime.ExecuteTask(s.task, s.env, reporter); err == nil {
		return fmt.Errorf("Expected task to fail!")
	}
	return nil
}

func (s *FailStep) Description() string {
	return fmt.Sprintf("<Fail: %s>", s.task.Name)
}
<commit_msg>Remove redundant lookup<commit_after>package main

import (
	"fmt"
	"time"
)

const defaultTimeout = time.Second * 30

type Step interface {
	Execute(Runtime, TaskReporter) error
	Description() string
}

type StopStep struct {
	services []string
}

func NewStopStep(config StepConfig) Step {
	return &StopStep{
		services: config.Stop,
	}
}

func (s *StopStep) Execute(runtime Runtime, reporter TaskReporter) error {
	return runtime.StopServices(s.services...)
}

func (s *StopStep) Description() string {
	return fmt.Sprintf("<Stop: %v>", s.services)
}

type StartStep struct {
	services []string
}

func NewStartStep(config StepConfig) Step {
	return &StartStep{
		services: config.Start,
	}
}

func (s *StartStep) Execute(runtime Runtime, reporter TaskReporter) error {
	return runtime.StartServices(s.services...)
}

func (s *StartStep) Description() string {
	return fmt.Sprintf("<Start: %v>", s.services)
}

type WaitStep struct {
	task TaskConfig
	env  TaskEnvironment
}

func NewWaitStep(task TaskConfig, env TaskEnvironment) Step {
	return &WaitStep{
		task: task,
		env:  env,
	}
}

func (s *WaitStep) Execute(runtime Runtime, reporter TaskReporter) error {
	timeout := time.After(defaultTimeout)
	for {
		select {
		case <-timeout:
			return fmt.Errorf("Task never completed successfully")
		default:
			if err := runtime.ExecuteTask(s.task, s.env, reporter); err == nil {
				return nil
			}
		}
	}
}

func (s *WaitStep) Description() string {
	return fmt.Sprintf("<Wait: %s>", s.task.Name)
}

type AssertStep struct {
	task TaskConfig
	env  TaskEnvironment
}

func NewAssertStep(task TaskConfig, env TaskEnvironment) Step {
	return &AssertStep{
		task: task,
		env:  env,
	}
}

func (s *AssertStep) Execute(runtime Runtime, reporter TaskReporter) error {
	return runtime.ExecuteTask(s.task, s.env, reporter)
}

func (s *AssertStep) Description() string {
	return fmt.Sprintf("<Assert: %s>", s.task.Name)
}

type FailStep struct {
	task TaskConfig
	env  TaskEnvironment
}

func NewFailStep(task TaskConfig, env TaskEnvironment) Step {
	return &FailStep{
		task: task,
		env:  env,
	}
}

func (s *FailStep) Execute(runtime Runtime, reporter TaskReporter) error {
	if err := runtime.ExecuteTask(s.task, s.env, reporter); err == nil {
		return fmt.Errorf("Expected task to fail!")
	}
	return nil
}

func (s *FailStep) Description() string {
	return fmt.Sprintf("<Fail: %s>", s.task.Name)
}
<|endoftext|>


<commit_before>package gexpect

import (
	"errors"
	"regexp"
)

type Step interface {
	Do(*SubProcess) error
}

type Flow []Step

type ExpectStep struct {
	expects     []*regexp.Regexp
	timeout     int
	matchOK     bool
	before      []byte
	after       []byte
	match       []byte
	WhenMatched Flow
	WhenTimeout Flow
}

func (es *ExpectStep) Do(sp *SubProcess) error {
	es.matchOK, err = sp.Expect(es.timeout, es.expects...)
	return err
}

func (f *Flow) Expect(timeout int, expects ...string) *ExpectStep {
	es := new(ExpectStep)
	es.timeout = timeout
	for _, e := range expects {
		if expregex, err := regexp.Compile(e); err != nil {
			return nil
		} else {
			es.expects = append(es.expects, expregex)
		}
	}
	*f = append(*f, es)
	return es
}

type SendStep struct {
	S string
}

func (f *Flow) SendLine(s string) *SendStep {
	return f.Send(s + "\n")
}

func (f *Flow) Send(s string) *SendStep {
	ss := &SendStep{s}
	*f = append(*f, ss)
	return ss
}

func (ss *SendStep) Do(sp *SubProcess) error {
	return sp.Write(ss.S)
}

type SendArgStep struct {
	Argname string
}

func (sas *SendArgStep) Do(sp *SubProcess) error {
	if v, ok := Args[sas.Argname]; ok {
		return sp.Write(v)
	} else {
		return errors.New("No such argument: " + sas.Argname)
	}
}

func (f *Flow) SendArg(argname string) *SendArgStep {
	sa := &SendArgStep{argname}
	*f = append(*f, sa)
	return sa
}

type SendArgLineStep struct {
    Argname string
}

func (sals *SendArgLineStep) Do(sp *SubProcess) error {
    if v, ok := Args[sals.Argname]; ok {
        return sp.Write(v+"\n")
    } else {
        return errors.New("No such argument: " + sals.Argname)
    }
}

func (f *Flow) SendArgLine(argname string) *SendArgLineStep {
    sal := &SendArgLineStep{argname}
    *f = append(*f, sal)
    return sal
}

type PromptStep struct {
}

type TerminateStep struct{}

func (f *Flow) Terminate() error {
	t := new(TerminateStep)
	*f = append(*f, t)
	return nil
}

func (ts *TerminateStep) Do(sp *SubProcess) error {
	return sp.Close()
}<commit_msg>clean expectstep<commit_after>package gexpect

import (
	"errors"
	"regexp"
	"time"
)

type Step interface {
	Do(*SubProcess) error
}

type Flow []Step

type ExpectStep struct {
	expects     []*regexp.Regexp
	timeout     int
	delay       time.Duration
	matchOK     bool
	WhenMatched Flow
	WhenTimeout Flow
}

func (es *ExpectStep) Do(sp *SubProcess) error {
	es.matchOK, err = sp.Expect(es.timeout, es.expects...)
	return err
}

func (f *Flow) Expect(timeout int, expects ...string) *ExpectStep {
	es := new(ExpectStep)
	es.timeout = timeout
	for _, e := range expects {
		if expregex, err := regexp.Compile(e); err != nil {
			return nil
		} else {
			es.expects = append(es.expects, expregex)
		}
	}
	*f = append(*f, es)
	return es
}

type SendStep struct {
	S string
}

func (f *Flow) SendLine(s string) *SendStep {
	return f.Send(s + "\n")
}

func (f *Flow) Send(s string) *SendStep {
	ss := &SendStep{s}
	*f = append(*f, ss)
	return ss
}

func (ss *SendStep) Do(sp *SubProcess) error {
	return sp.Write(ss.S)
}

type SendArgStep struct {
	Argname string
}

func (sas *SendArgStep) Do(sp *SubProcess) error {
	if v, ok := Args[sas.Argname]; ok {
		return sp.Write(v)
	} else {
		return errors.New("No such argument: " + sas.Argname)
	}
}

func (f *Flow) SendArg(argname string) *SendArgStep {
	sa := &SendArgStep{argname}
	*f = append(*f, sa)
	return sa
}

type SendArgLineStep struct {
    Argname string
}

func (sals *SendArgLineStep) Do(sp *SubProcess) error {
    if v, ok := Args[sals.Argname]; ok {
        return sp.Write(v+"\n")
    } else {
        return errors.New("No such argument: " + sals.Argname)
    }
}

func (f *Flow) SendArgLine(argname string) *SendArgLineStep {
    sal := &SendArgLineStep{argname}
    *f = append(*f, sal)
    return sal
}

type PromptStep struct {
}

type TerminateStep struct{}

func (f *Flow) Terminate() error {
	t := new(TerminateStep)
	*f = append(*f, t)
	return nil
}

func (ts *TerminateStep) Do(sp *SubProcess) error {
	return sp.Close()
}<|endoftext|>


<commit_before>package gocd

import (
	"context"
	"fmt"
	"github.com/stretchr/testify/assert"
	"io/ioutil"
	"net/http"
	"testing"
)

func TestPipelineConfig(t *testing.T) {
	setup()
	defer teardown()
	t.Run("Create", testPipelineConfigCreate)
	t.Run("Update", testPipelineConfigUpdate)
	t.Run("Delete", testPipelineConfigDelete)
}

func testPipelineConfigDelete(t *testing.T) {

	mux.HandleFunc("/api/admin/pipelines/test-pipeline", func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, r.Method, "DELETE", "Unexpected HTTP method")
		assert.Equal(t, r.Header.Get("Accept"), apiV4)

		fmt.Fprint(w, `{
  "message": "Pipeline 'test-pipeline' was deleted successfully."
}`)
	})
	message, resp, err := client.PipelineConfigs.Delete(context.Background(), "test-pipeline")
	if err != nil {
		assert.Error(t, err)
	}
	assert.NotNil(t, resp)
	assert.Equal(t, "Pipeline 'test-pipeline' was deleted successfully.", message)
}

func testPipelineConfigCreate(t *testing.T) {
	mux.HandleFunc("/api/admin/pipelines", func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, r.Method, "POST", "Unexpected HTTP method")
		b, err := ioutil.ReadAll(r.Body)
		if err != nil {
			t.Error(err)
		}
		assert.Equal(
			t,
			"{\n  \"group\": \"test-group\",\n  \"pipeline\": {\n    \"name\": \"\",\n    \"stages\": null\n  }\n}\n",
			string(b))
		j, _ := ioutil.ReadFile("test/resources/pipelineconfig.0.json")
		fmt.Fprint(w, string(j))
	})

	p := Pipeline{}
	pgs, _, err := client.PipelineConfigs.Create(context.Background(), "test-group", &p)
	if err != nil {
		t.Error(t, err)
	}

	assert.NotNil(t, pgs)
}

func testPipelineConfigUpdate(t *testing.T) {
	mux.HandleFunc("/api/admin/pipelines/test-name", func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, "PUT", r.Method, "Unexpected HTTP method")
		b, err := ioutil.ReadAll(r.Body)
		if err != nil {
			t.Error(err)
		}
		assert.Equal(
			t,
			"{\n  \"pipeline\": {\n    \"name\": \"\",\n    \"stages\": null,\n    \"version\": \"test-version\"\n  }\n}\n",
			string(b))
		j, _ := ioutil.ReadFile("test/resources/pipelineconfig.0.json")
		fmt.Fprint(w, string(j))
	})

	p := Pipeline{
		Version: "test-version",
	}
	pcs, _, err := client.PipelineConfigs.Update(context.Background(),
		"test-name", &p)
	if err != nil {
		t.Error(t, err)
	}

	assert.NotNil(t, pcs)
}
<commit_msg>Added pipeline get test<commit_after>package gocd

import (
	"context"
	"fmt"
	"github.com/stretchr/testify/assert"
	"io/ioutil"
	"net/http"
	"testing"
)

func TestPipelineConfig(t *testing.T) {
	setup()
	defer teardown()
	t.Run("Create", testPipelineConfigCreate)
	t.Run("Update", testPipelineConfigUpdate)
	t.Run("Delete", testPipelineConfigDelete)
	t.Run("Get", testPipelineConfigGet)
}

func testPipelineConfigGet(t *testing.T) {
	p, resp, err := client.PipelineConfigs.Get(context.Background(), "mock-pipeline")
	assert.Nil(t, p)
	assert.Nil(t, resp)
	assert.EqualError(t, err, "Not Implemented")
}

func testPipelineConfigDelete(t *testing.T) {

	mux.HandleFunc("/api/admin/pipelines/test-pipeline", func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, r.Method, "DELETE", "Unexpected HTTP method")
		assert.Equal(t, r.Header.Get("Accept"), apiV4)

		fmt.Fprint(w, `{
  "message": "Pipeline 'test-pipeline' was deleted successfully."
}`)
	})
	message, resp, err := client.PipelineConfigs.Delete(context.Background(), "test-pipeline")
	if err != nil {
		assert.Error(t, err)
	}
	assert.NotNil(t, resp)
	assert.Equal(t, "Pipeline 'test-pipeline' was deleted successfully.", message)
}

func testPipelineConfigCreate(t *testing.T) {
	mux.HandleFunc("/api/admin/pipelines", func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, r.Method, "POST", "Unexpected HTTP method")
		b, err := ioutil.ReadAll(r.Body)
		if err != nil {
			t.Error(err)
		}
		assert.Equal(
			t,
			"{\n  \"group\": \"test-group\",\n  \"pipeline\": {\n    \"name\": \"\",\n    \"stages\": null\n  }\n}\n",
			string(b))
		j, _ := ioutil.ReadFile("test/resources/pipelineconfig.0.json")
		fmt.Fprint(w, string(j))
	})

	p := Pipeline{}
	pgs, _, err := client.PipelineConfigs.Create(context.Background(), "test-group", &p)
	if err != nil {
		t.Error(t, err)
	}

	assert.NotNil(t, pgs)
}

func testPipelineConfigUpdate(t *testing.T) {
	mux.HandleFunc("/api/admin/pipelines/test-name", func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, "PUT", r.Method, "Unexpected HTTP method")
		b, err := ioutil.ReadAll(r.Body)
		if err != nil {
			t.Error(err)
		}
		assert.Equal(
			t,
			"{\n  \"pipeline\": {\n    \"name\": \"\",\n    \"stages\": null,\n    \"version\": \"test-version\"\n  }\n}\n",
			string(b))
		j, _ := ioutil.ReadFile("test/resources/pipelineconfig.0.json")
		fmt.Fprint(w, string(j))
	})

	p := Pipeline{
		Version: "test-version",
	}
	pcs, _, err := client.PipelineConfigs.Update(context.Background(),
		"test-name", &p)
	if err != nil {
		t.Error(t, err)
	}

	assert.NotNil(t, pcs)
}
<|endoftext|>


<commit_before>package golhttpclient

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

func UrlRedirectTo(url string) string {
	client := &http.Client{
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
			return nil
		},
	}

	resp, err := client.Get(url)

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

	return resp.Request.URL
}

func LinkExists(url string) bool {
	var netClient = &http.Client{
		Timeout: time.Second * 10,
	}
	response, err := netClient.Get(url)
	if err != nil || response.StatusCode > 399 {
		return false
	}
	return true
}

func getURL(baseURL string, getParams map[string]string) (url *url.URL) {
	var getParamsURI string
	for key, val := range getParams {
		if getParamsURI == "" {
			getParamsURI = fmt.Sprintf("%s=%s", key, val)
		} else {
			getParamsURI = fmt.Sprintf("%s&%s=%s", getParamsURI, key, val)
		}
	}
	request_url := fmt.Sprintf("%s?%s", baseURL, getParamsURI)
	url, err := url.Parse(request_url)

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

func setHttpHeaders(req *http.Request, httpHeaders map[string]string) (err error) {
	basicAuth := strings.Split(httpHeaders["basicAuth"], ":")
	if len(basicAuth) > 1 {
		apiUsername, apiPassword := basicAuth[0], strings.Join(basicAuth[1:], ":")
		req.SetBasicAuth(apiUsername, apiPassword)
	}
	return
}

func httpResponse(httpMethod string, baseURL string, getParams map[string]string, httpHeaders map[string]string) (resp *http.Response, err error) {
	httpClient := &http.Client{
		Transport: &http.Transport{
			Dial: (&net.Dialer{
				Timeout:   30 * time.Second,
				KeepAlive: 30 * time.Second,
			}).Dial,
			TLSHandshakeTimeout:   10 * time.Second,
			ResponseHeaderTimeout: 10 * time.Second,
			ExpectContinueTimeout: 1 * time.Second,
		},
	}

	req, err := http.NewRequest(httpMethod, "", nil)
	if err != nil {
		return
	}
	req.URL = getURL(baseURL, getParams)
	setHttpHeaders(req, httpHeaders)

	resp, err = httpClient.Do(req)
	if err != nil {
		log.Println(err)
		return
	}

	return
}

func httpResponseBody(httpMethod string, baseURL string, getParams map[string]string, httpHeaders map[string]string) (body string, err error) {
	resp, err := httpResponse(httpMethod, baseURL, getParams, httpHeaders)
	bodyText, err := ioutil.ReadAll(resp.Body)
	if err == nil {
		body = string(bodyText)
	} else {
		log.Println(err)
	}

	return
}

func Http(httpMethod string, baseURL string, getParams map[string]string, httpHeaders map[string]string) (resp *http.Response, err error) {
	return httpResponse(httpMethod, baseURL, getParams, httpHeaders)
}

func HttpGet(baseURL string, getParams map[string]string, httpHeaders map[string]string) (body string, err error) {
	body, err = httpResponseBody("GET", baseURL, getParams, httpHeaders)
	return
}

func HttpPut(baseURL string, getParams map[string]string, httpHeaders map[string]string) (body string, err error) {
	// need to handle PUT body content
	body, err = httpResponseBody("PUT", baseURL, getParams, httpHeaders)
	return
}

func HttpPost(baseURL string, getParams map[string]string, httpHeaders map[string]string) (body string, err error) {
	// need to handle POST body content
	body, err = httpResponseBody("POST", baseURL, getParams, httpHeaders)
	return
}

func HttpDelete(baseURL string, getParams map[string]string, httpHeaders map[string]string) (body string, err error) {
	body, err = httpResponseBody("DELETE", baseURL, getParams, httpHeaders)
	return
}
<commit_msg>[golhhtpclient] fixing return of UrlRedirectTo<commit_after>package golhttpclient

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

func UrlRedirectTo(url string) string {
	client := &http.Client{
		CheckRedirect: func(req *http.Request, via []*http.Request) error {
			return nil
		},
	}

	resp, err := client.Get(url)

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

	return resp.Request.URL.String()
}

func LinkExists(url string) bool {
	var netClient = &http.Client{
		Timeout: time.Second * 10,
	}
	response, err := netClient.Get(url)
	if err != nil || response.StatusCode > 399 {
		return false
	}
	return true
}

func getURL(baseURL string, getParams map[string]string) (url *url.URL) {
	var getParamsURI string
	for key, val := range getParams {
		if getParamsURI == "" {
			getParamsURI = fmt.Sprintf("%s=%s", key, val)
		} else {
			getParamsURI = fmt.Sprintf("%s&%s=%s", getParamsURI, key, val)
		}
	}
	request_url := fmt.Sprintf("%s?%s", baseURL, getParamsURI)
	url, err := url.Parse(request_url)

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

func setHttpHeaders(req *http.Request, httpHeaders map[string]string) (err error) {
	basicAuth := strings.Split(httpHeaders["basicAuth"], ":")
	if len(basicAuth) > 1 {
		apiUsername, apiPassword := basicAuth[0], strings.Join(basicAuth[1:], ":")
		req.SetBasicAuth(apiUsername, apiPassword)
	}
	return
}

func httpResponse(httpMethod string, baseURL string, getParams map[string]string, httpHeaders map[string]string) (resp *http.Response, err error) {
	httpClient := &http.Client{
		Transport: &http.Transport{
			Dial: (&net.Dialer{
				Timeout:   30 * time.Second,
				KeepAlive: 30 * time.Second,
			}).Dial,
			TLSHandshakeTimeout:   10 * time.Second,
			ResponseHeaderTimeout: 10 * time.Second,
			ExpectContinueTimeout: 1 * time.Second,
		},
	}

	req, err := http.NewRequest(httpMethod, "", nil)
	if err != nil {
		return
	}
	req.URL = getURL(baseURL, getParams)
	setHttpHeaders(req, httpHeaders)

	resp, err = httpClient.Do(req)
	if err != nil {
		log.Println(err)
		return
	}

	return
}

func httpResponseBody(httpMethod string, baseURL string, getParams map[string]string, httpHeaders map[string]string) (body string, err error) {
	resp, err := httpResponse(httpMethod, baseURL, getParams, httpHeaders)
	bodyText, err := ioutil.ReadAll(resp.Body)
	if err == nil {
		body = string(bodyText)
	} else {
		log.Println(err)
	}

	return
}

func Http(httpMethod string, baseURL string, getParams map[string]string, httpHeaders map[string]string) (resp *http.Response, err error) {
	return httpResponse(httpMethod, baseURL, getParams, httpHeaders)
}

func HttpGet(baseURL string, getParams map[string]string, httpHeaders map[string]string) (body string, err error) {
	body, err = httpResponseBody("GET", baseURL, getParams, httpHeaders)
	return
}

func HttpPut(baseURL string, getParams map[string]string, httpHeaders map[string]string) (body string, err error) {
	// need to handle PUT body content
	body, err = httpResponseBody("PUT", baseURL, getParams, httpHeaders)
	return
}

func HttpPost(baseURL string, getParams map[string]string, httpHeaders map[string]string) (body string, err error) {
	// need to handle POST body content
	body, err = httpResponseBody("POST", baseURL, getParams, httpHeaders)
	return
}

func HttpDelete(baseURL string, getParams map[string]string, httpHeaders map[string]string) (body string, err error) {
	body, err = httpResponseBody("DELETE", baseURL, getParams, httpHeaders)
	return
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 Thomas de Zeeuw.
//
// Licensed onder the MIT license that can be found in the LICENSE file.

package logger

import "fmt"

// Tags are keywords usefull in searching through logs, for example:
//
//	tags := []Tags{"file.go", "myFn", "user:$user_id", "input:$input"}
//
// With this information you can lookup any logs for a specific user reporting
// a problem. Then you can find which function, in which file, is throwing the
// error.
type Tags []string

// String creates a comma separated list from the tags in string.
func (tags Tags) String() string {
	return string(tags.Bytes())
}

// Bytes does the same as Tags.String, but returns a byte slice.
func (tags Tags) Bytes() []byte {
	var buf []byte

	// Add each tag in the form of "tag, "
	for _, tag := range tags {
		buf = append(buf, tag...)
		buf = append(buf, ',')
		buf = append(buf, ' ')
	}

	// Drop the last ", "
	if len(buf) > 2 {
		buf = buf[:len(buf)-2]
	}

	return buf
}

func (tags Tags) MarshalJSON() ([]byte, error) {
	if len(tags) == 0 {
		return []byte("[]"), nil
	}

	str := "["
	for _, tag := range tags {
		str += fmt.Sprintf("%q, ", tag)
	}
	str = str[:len(str)-2] + "]"
	return []byte(str), nil
}
<commit_msg>Add fast path for Tags.Bytes<commit_after>// Copyright (C) 2015 Thomas de Zeeuw.
//
// Licensed onder the MIT license that can be found in the LICENSE file.

package logger

import "fmt"

// Tags are keywords usefull in searching through logs, for example:
//
//	tags := []Tags{"file.go", "myFn", "user:$user_id", "input:$input"}
//
// With this information you can lookup any logs for a specific user reporting
// a problem. Then you can find which function, in which file, is throwing the
// error.
type Tags []string

// String creates a comma separated list from the tags in string.
func (tags Tags) String() string {
	return string(tags.Bytes())
}

// Bytes does the same as Tags.String, but returns a byte slice.
func (tags Tags) Bytes() []byte {
	if len(tags) == 0 {
		return []byte{}
	}

	// Add each tag in the form of "tag, ".
	var buf []byte
	for _, tag := range tags {
		buf = append(buf, tag...)
		buf = append(buf, ',')
		buf = append(buf, ' ')
	}

	// Drop the last ", ".
	buf = buf[:len(buf)-2]
	return buf
}

func (tags Tags) MarshalJSON() ([]byte, error) {
	if len(tags) == 0 {
		return []byte("[]"), nil
	}

	str := "["
	for _, tag := range tags {
		str += fmt.Sprintf("%q, ", tag)
	}
	str = str[:len(str)-2] + "]"
	return []byte(str), nil
}
<|endoftext|>


<commit_before>package tasker

import (
	"context"
	"errors"
	"time"

	"github.com/NoneBorder/dora"
	"github.com/astaxie/beego/orm"
)

const (
	TaskStatPending = "pending"
	TaskStatRunning = "running"
	TaskStatRetry   = "retry"
	TaskStatFailed  = "failed"
	TaskStatSuccess = "success"
)

const (
	TaskCtxKeyLog       = "stdout"          // normal log record
	TaskCtxKeyExecAfter = "task-exec-after" // plan task exec time
)

// Task is the core object for tasker package.
type Task struct {
	Id         uint64
	Topic      string
	Status     string
	Timeout    int // 超时ms
	ExecAfter  time.Time `orm:"type(datetime);default(1971-01-01 00:00:00)"`
	Retry      int
	Input      string    `orm:"type(text)"`
	WorkerId   uint64
	WorkerFQDN string    `orm:"column(worker_fqdn);type(text)"`
	Created    time.Time `orm:"auto_now_add"`
	Updated    time.Time `orm:"auto_now"`
	Log        string    `orm:"type(text)"`
	Errlog     string    `orm:"type(text)"`
}

// ConsumeFn represents consume func definition.
type ConsumeFn func(ctx *context.Context, Input string, WorkerID uint64) (err error)

func (self *Task) TableIndex() [][]string {
	return [][]string{
		[]string{"Topic", "Status"},
	}
}

func (self *Task) TableEngine() string {
	return "INNODB"
}

// NewSimpleTask is new task with default settings.
func NewSimpleTask(topic, input string) *Task {
	return &Task{
		Topic:     topic,
		Status:    TaskStatPending,
		Timeout:   5000,
		ExecAfter: zeroTime,
		Retry:     3,
		Input:     input,
		WorkerId:  0,
	}
}

// Publish Task to Msg Queue.
func (self *Task) Publish() (err error) {
	o := orm.NewOrm()
	if _, err = o.Insert(self); err == nil {
		Stat(self.Topic, TaskStatPending, time.Duration(0))
	}
	return
}

func (self *Task) exec(ctx *context.Context, fn ConsumeFn) (err error) {
	errC := make(chan error)
	select {
	case errC <- fn(ctx, self.Input, self.WorkerId):
		err = <-errC

	case <-(*ctx).Done():
		err = (*ctx).Err()
	}

	return
}

func (self *Task) consume(fn ConsumeFn) bool {
	startT := time.Now().Local()
	ctx, cancel := context.WithTimeout(context.Background(), time.Duration(self.Timeout+1)*time.Microsecond)
	defer cancel()

	err := self.exec(&ctx, fn)
	success := err == nil

	if !success {
		// failed
		self.Errlog += err.Error() + "\n"
		self.Status = TaskStatFailed
		self.Retry -= 1
		if self.Retry > 0 {
			self.Status = TaskStatRetry

			// when the job will retry, you can update the next exec time
			if execAfter, ok := ctx.Value(TaskCtxKeyExecAfter).(time.Time); ok {
				self.ExecAfter = execAfter
			}
		}
	} else {
		self.Status = TaskStatSuccess
	}

	// stat task exec
	Stat(self.Topic, self.Status, time.Since(startT))

	// workerid set to 0
	self.WorkerId = 0

	// set stdout log from ctx
	if log, ok := ctx.Value(TaskCtxKeyLog).(string); ok && log != "" {
		self.Log = log
	}

	// update db record
	o := orm.NewOrm()
	for i := 0; i < 3; i++ {
		if _, err := o.Update(self); err != nil {
			dora.Error().Msgf("set task state failed: err=%s, task=%s", err.Error(), self)
		} else {
			break
		}
	}

	return success
}

// Consume a topic task.
func Consume(topic string, fn ConsumeFn) (int, error) {
	o := orm.NewOrm()
	if IsMaster {
		// 仅在 master 上对已经僵死的 task 进行重置，减轻 DB 压力
		if _, err := o.Raw(`UPDATE task SET status=?, retry=retry-1, worker_id=0 WHERE topic=? AND status=?
		AND TIMESTAMPDIFF(SECOND, updated, now())*1000-5000>timeout`,
			TaskStatRetry, topic, TaskStatRunning,
		).Exec(); err != nil {
			dora.Error().Msgf("update dead running task to waiting failed: %s", err.Error())
		}
	}

	maxConsumeTask := cap(RunningTaskChannel[topic]) - len(RunningTaskChannel[topic])
	if maxConsumeTask == 0 {
		return 0, errors.New("reached max running task limit")
	}

	workerID, err := UniqID.NextID()
	if err != nil {
		return 0, err
	}

	res, err := o.Raw(`UPDATE task SET status=?, worker_id=?, worker_fqdn=concat(worker_fqdn, ?) WHERE
		topic=? AND worker_id=0 AND status IN (?,?) AND exec_after <= NOW() LIMIT ?`,
		TaskStatRunning, workerID, FQDN()+"\n", topic, TaskStatPending, TaskStatRetry, maxConsumeTask,
	).Exec()
	if err != nil {
		// not update db
		return 0, err
	}

	num, _ := res.RowsAffected()
	if num == 0 {
		// no task for consume
		return 0, nil
	}

	tasks := []*Task{}
	_, err = o.Raw("SELECT * FROM task WHERE `topic`=? AND `status`=? AND `worker_id`=?",
		topic, TaskStatRunning, workerID,
	).QueryRows(&tasks)
	if len(tasks) == 0 || err != nil {
		return 0, err
	}

	// TODO: 如何保证程序退出时正在运行的 task 可用？当前超时后 5s 僵尸 task 会被重新激活，但不能保证原子性
	for _, t := range tasks {
		RunningTaskChannel[topic] <- true
		go func(t *Task) {
			t.consume(fn)
			<-RunningTaskChannel[topic]
		}(t)
	}

	return len(tasks), nil
}

// ConsumeCtxStdout write stdout log to context for record
func ConsumeCtxStdout(ctx *context.Context, log string) {
	*ctx = context.WithValue(*ctx, TaskCtxKeyLog, log)
}

// ConsumeCtxExecAfter update run time for next retry
func ConsumeCtxExecAfter(ctx *context.Context, t time.Time) {
	*ctx = context.WithValue(*ctx, TaskCtxKeyExecAfter, t)
}
<commit_msg>fix timeout error<commit_after>package tasker

import (
	"context"
	"errors"
	"time"

	"github.com/NoneBorder/dora"
	"github.com/astaxie/beego/orm"
)

const (
	TaskStatPending = "pending"
	TaskStatRunning = "running"
	TaskStatRetry   = "retry"
	TaskStatFailed  = "failed"
	TaskStatSuccess = "success"
)

const (
	TaskCtxKeyLog       = "stdout"          // normal log record
	TaskCtxKeyExecAfter = "task-exec-after" // plan task exec time
)

// Task is the core object for tasker package.
type Task struct {
	Id         uint64
	Topic      string
	Status     string
	Timeout    int // 超时ms
	ExecAfter  time.Time `orm:"type(datetime);default(1971-01-01 00:00:00)"`
	Retry      int
	Input      string    `orm:"type(text)"`
	WorkerId   uint64
	WorkerFQDN string    `orm:"column(worker_fqdn);type(text)"`
	Created    time.Time `orm:"auto_now_add"`
	Updated    time.Time `orm:"auto_now"`
	Log        string    `orm:"type(text)"`
	Errlog     string    `orm:"type(text)"`
}

// ConsumeFn represents consume func definition.
type ConsumeFn func(ctx *context.Context, Input string, WorkerID uint64) (err error)

func (self *Task) TableIndex() [][]string {
	return [][]string{
		[]string{"Topic", "Status"},
	}
}

func (self *Task) TableEngine() string {
	return "INNODB"
}

// NewSimpleTask is new task with default settings.
func NewSimpleTask(topic, input string) *Task {
	return &Task{
		Topic:     topic,
		Status:    TaskStatPending,
		Timeout:   5000,
		ExecAfter: zeroTime,
		Retry:     3,
		Input:     input,
		WorkerId:  0,
	}
}

// Publish Task to Msg Queue.
func (self *Task) Publish() (err error) {
	o := orm.NewOrm()
	if _, err = o.Insert(self); err == nil {
		Stat(self.Topic, TaskStatPending, time.Duration(0))
	}
	return
}

func (self *Task) exec(ctx *context.Context, fn ConsumeFn) (err error) {
	errC := make(chan error)
	select {
	case errC <- fn(ctx, self.Input, self.WorkerId):
		err = <-errC

	case <-(*ctx).Done():
		err = (*ctx).Err()
	}

	return
}

func (self *Task) consume(fn ConsumeFn) bool {
	startT := time.Now().Local()
	ctx, cancel := context.WithTimeout(context.Background(), time.Duration(self.Timeout+1)*time.Millisecond)
	defer cancel()

	err := self.exec(&ctx, fn)
	success := err == nil

	if !success {
		// failed
		self.Errlog += err.Error() + "\n"
		self.Status = TaskStatFailed
		self.Retry -= 1
		if self.Retry > 0 {
			self.Status = TaskStatRetry

			// when the job will retry, you can update the next exec time
			if execAfter, ok := ctx.Value(TaskCtxKeyExecAfter).(time.Time); ok {
				self.ExecAfter = execAfter
			}
		}
	} else {
		self.Status = TaskStatSuccess
	}

	// stat task exec
	Stat(self.Topic, self.Status, time.Since(startT))

	// workerid set to 0
	self.WorkerId = 0

	// set stdout log from ctx
	if log, ok := ctx.Value(TaskCtxKeyLog).(string); ok && log != "" {
		self.Log = log
	}

	// update db record
	o := orm.NewOrm()
	for i := 0; i < 3; i++ {
		if _, err := o.Update(self); err != nil {
			dora.Error().Msgf("set task state failed: err=%s, task=%s", err.Error(), self)
		} else {
			break
		}
	}

	return success
}

// Consume a topic task.
func Consume(topic string, fn ConsumeFn) (int, error) {
	o := orm.NewOrm()
	if IsMaster {
		// 仅在 master 上对已经僵死的 task 进行重置，减轻 DB 压力
		if _, err := o.Raw(`UPDATE task SET status=?, retry=retry-1, worker_id=0 WHERE topic=? AND status=?
		AND TIMESTAMPDIFF(SECOND, updated, now())*1000-5000>timeout`,
			TaskStatRetry, topic, TaskStatRunning,
		).Exec(); err != nil {
			dora.Error().Msgf("update dead running task to waiting failed: %s", err.Error())
		}
	}

	maxConsumeTask := cap(RunningTaskChannel[topic]) - len(RunningTaskChannel[topic])
	if maxConsumeTask == 0 {
		return 0, errors.New("reached max running task limit")
	}

	workerID, err := UniqID.NextID()
	if err != nil {
		return 0, err
	}

	res, err := o.Raw(`UPDATE task SET status=?, worker_id=?, worker_fqdn=concat(worker_fqdn, ?) WHERE
		topic=? AND worker_id=0 AND status IN (?,?) AND exec_after <= NOW() LIMIT ?`,
		TaskStatRunning, workerID, FQDN()+"\n", topic, TaskStatPending, TaskStatRetry, maxConsumeTask,
	).Exec()
	if err != nil {
		// not update db
		return 0, err
	}

	num, _ := res.RowsAffected()
	if num == 0 {
		// no task for consume
		return 0, nil
	}

	tasks := []*Task{}
	_, err = o.Raw("SELECT * FROM task WHERE `topic`=? AND `status`=? AND `worker_id`=?",
		topic, TaskStatRunning, workerID,
	).QueryRows(&tasks)
	if len(tasks) == 0 || err != nil {
		return 0, err
	}

	// TODO: 如何保证程序退出时正在运行的 task 可用？当前超时后 5s 僵尸 task 会被重新激活，但不能保证原子性
	for _, t := range tasks {
		RunningTaskChannel[topic] <- true
		go func(t *Task) {
			t.consume(fn)
			<-RunningTaskChannel[topic]
		}(t)
	}

	return len(tasks), nil
}

// ConsumeCtxStdout write stdout log to context for record
func ConsumeCtxStdout(ctx *context.Context, log string) {
	*ctx = context.WithValue(*ctx, TaskCtxKeyLog, log)
}

// ConsumeCtxExecAfter update run time for next retry
func ConsumeCtxExecAfter(ctx *context.Context, t time.Time) {
	*ctx = context.WithValue(*ctx, TaskCtxKeyExecAfter, t)
}
<|endoftext|>


<commit_before>package golog

import . "fmt"
import . "regexp"
import . "strings"
import "bytes"

var anonCounter <-chan int64
func init() {
    // goroutine providing a counter for anonymous variables
    c := make(chan int64)
    var i int64 = 1
    go func() {
        for {
            c <- i
            i++
        }
    }()
    anonCounter = c
}

// Term represents a single Prolog term which might be an atom, a structure,
// a number, etc.
type Term interface {
    // Functor returns the term's name
    Functor() string

    // Arity returns the number of arguments a term has. An atom has 0 arity.
    Arity() int

    // Arguments returns a slice of this term's arguments, if any
    Arguments() []Term

    // Body returns a term's second argument; otherwise, panics
    Body() Term

    // Head returns a term's first argument; otherwise, panics
    Head() Term

    // IsClause returns true if the term is like 'Head :- Body'
    IsClause() bool

    // String provides a string representation of a term
    String() string

    // Indicator() provides a "predicate indicator" representation of a term
    Indicator() string
}

type Structure struct {
    Func    string
    Args    []Term
}
func (self *Structure) Functor() string {
    return self.Func
}
func (self *Structure) Arity() int {
    return len(self.Args)
}
func (self *Structure) Arguments() []Term {
    return self.Args
}
func (self *Structure) Body() Term {
    return self.Args[1]
}
func (self *Structure) Head() Term {
    return self.Args[0]
}
func (self *Structure) IsClause() bool {
    return self.Arity() == 2 && self.Functor() == ":-"
}
func (self *Structure) String() string {
    // an atom
    quotedFunctor := QuoteFunctor(self.Functor())
    if self.Arity() == 0 {
        return quotedFunctor
    }

    var buf bytes.Buffer
    Fprintf(&buf, "%s(", quotedFunctor)
    arity := self.Arity()
    for i := 0; i<arity; i++ {
        if i>0 {
            Fprintf(&buf, ", ")
        }
        Fprintf(&buf, "%s", self.Arguments()[i])
    }
    Fprintf(&buf, ")")
    return buf.String()
}
func (self *Structure) Indicator() string {
    return Sprintf("%s/%d", self.Functor(), self.Arity())
}

type Variable struct {
    Name    string
}
func (self *Variable) Functor() string {
    panic("Variables have no Functor()")
}
func (self *Variable) Arity() int {
    panic("Variables have no Arity()")
}
func (self *Variable) Arguments() []Term {
    panic("Variables have no Arguments()")
}
func (self *Variable) Body() Term {
    panic("Variables have no Body()")
}
func (self *Variable) Head() Term {
    panic("Variables have no Head()")
}
func (self *Variable) IsClause() bool {
    return false
}
func (self *Variable) String() string {
    return self.Name
}
func (self *Variable) Indicator() string {
    return Sprintf("%s", self.Name)
}

// NewTerm creates a new term with the given functor and optional arguments
func NewTerm(functor string, arguments ...Term) Term {
    return &Structure{
        Func:   functor,
        Args:   arguments,
    }
}

func NewVar(name string) Term {
    // sanity check the variable name's syntax
    isCapitalized, err := MatchString(`^[A-Z_]`, name)
    maybePanic(err)
    if !isCapitalized {
        panic("Variable names must start with a capital letter or underscore")
    }

    // make sure anonymous variables are unique
    if name == "_" {
        i := <-anonCounter
        name = Sprintf("_G%d", i)
    }
    return &Variable{
        Name:   name,
    }
}

func IsVariable(t Term) bool {
    switch t.(type) {
        case *Structure:
            return false
        case *Variable:
            return true
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// QuoteFunctor returns a canonical representation of a term's name
// by quoting characters that require quoting
func QuoteFunctor(name string) string {
    nonAlpha, err := MatchString(`\W`, name)
    maybePanic(err)
    nonLower, err := MatchString(`^[^a-z]`, name)
    if nonAlpha || nonLower {
        escapedName := Replace(name, `'`, `\'`, -1)
        return Sprintf("'%s'", escapedName)
    }

    return name
}

func maybePanic(err error) {
    if err != nil {
        panic(err)
    }
}
<commit_msg>An Error type implementing the Term interface<commit_after>package golog

import . "fmt"
import . "regexp"
import . "strings"
import "bytes"

var anonCounter <-chan int64
func init() {
    // goroutine providing a counter for anonymous variables
    c := make(chan int64)
    var i int64 = 1
    go func() {
        for {
            c <- i
            i++
        }
    }()
    anonCounter = c
}

// Term represents a single Prolog term which might be an atom, a structure,
// a number, etc.
type Term interface {
    // Functor returns the term's name
    Functor() string

    // Arity returns the number of arguments a term has. An atom has 0 arity.
    Arity() int

    // Arguments returns a slice of this term's arguments, if any
    Arguments() []Term

    // Body returns a term's second argument; otherwise, panics
    Body() Term

    // Head returns a term's first argument; otherwise, panics
    Head() Term

    // Error returns an error value if this is an error term
    Error() error

    // IsClause returns true if the term is like 'Head :- Body'
    IsClause() bool

    // String provides a string representation of a term
    String() string

    // Indicator() provides a "predicate indicator" representation of a term
    Indicator() string
}

type Structure struct {
    Func    string
    Args    []Term
}
func (self *Structure) Functor() string {
    return self.Func
}
func (self *Structure) Arity() int {
    return len(self.Args)
}
func (self *Structure) Arguments() []Term {
    return self.Args
}
func (self *Structure) Body() Term {
    return self.Args[1]
}
func (self *Structure) Head() Term {
    return self.Args[0]
}
func (self *Structure) IsClause() bool {
    return self.Arity() == 2 && self.Functor() == ":-"
}
func (self *Structure) String() string {
    // an atom
    quotedFunctor := QuoteFunctor(self.Functor())
    if self.Arity() == 0 {
        return quotedFunctor
    }

    var buf bytes.Buffer
    Fprintf(&buf, "%s(", quotedFunctor)
    arity := self.Arity()
    for i := 0; i<arity; i++ {
        if i>0 {
            Fprintf(&buf, ", ")
        }
        Fprintf(&buf, "%s", self.Arguments()[i])
    }
    Fprintf(&buf, ")")
    return buf.String()
}
func (self *Structure) Indicator() string {
    return Sprintf("%s/%d", self.Functor(), self.Arity())
}
func (self *Structure) Error() error {
    panic("Can't call Error() on a Structure")
}

type Variable struct {
    Name    string
}
func (self *Variable) Functor() string {
    panic("Variables have no Functor()")
}
func (self *Variable) Arity() int {
    panic("Variables have no Arity()")
}
func (self *Variable) Arguments() []Term {
    panic("Variables have no Arguments()")
}
func (self *Variable) Body() Term {
    panic("Variables have no Body()")
}
func (self *Variable) Head() Term {
    panic("Variables have no Head()")
}
func (self *Variable) IsClause() bool {
    return false
}
func (self *Variable) String() string {
    return self.Name
}
func (self *Variable) Indicator() string {
    return Sprintf("%s", self.Name)
}
func (self *Variable) Error() error {
    panic("Can't call Error() on a Variable")
}

type Error string
func (self *Error) Functor() string {
    panic("Errors have no Functor()")
}
func (self *Error) Arity() int {
    panic("Errors have no Arity()")
}
func (self *Error) Arguments() []Term {
    panic("Errors have no Arguments()")
}
func (self *Error) Body() Term {
    panic("Errors have no Body()")
}
func (self *Error) Head() Term {
    panic("Errors have no Head()")
}
func (self *Error) IsClause() bool {
    return false
}
func (self *Error) String() string {
    return string(*self)
}
func (self *Error) Indicator() string {
    panic("Errors have no Indicator()")
}
func (self *Error) Error() error {
    return Errorf("%s", *self)
}

// NewTerm creates a new term with the given functor and optional arguments
func NewTerm(functor string, arguments ...Term) Term {
    return &Structure{
        Func:   functor,
        Args:   arguments,
    }
}

func NewVar(name string) Term {
    // sanity check the variable name's syntax
    isCapitalized, err := MatchString(`^[A-Z_]`, name)
    maybePanic(err)
    if !isCapitalized {
        panic("Variable names must start with a capital letter or underscore")
    }

    // make sure anonymous variables are unique
    if name == "_" {
        i := <-anonCounter
        name = Sprintf("_G%d", i)
    }
    return &Variable{
        Name:   name,
    }
}

func IsVariable(t Term) bool {
    switch t.(type) {
        case *Structure:
            return false
        case *Variable:
            return true
        case *Error:
            return false
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}
func IsError(t Term) bool {
    switch t.(type) {
        case *Structure:
            return false
        case *Variable:
            return false
        case *Error:
            return true
    }
    msg := Sprintf("Unexpected term type: %#v", t)
    panic(msg)
}

// QuoteFunctor returns a canonical representation of a term's name
// by quoting characters that require quoting
func QuoteFunctor(name string) string {
    nonAlpha, err := MatchString(`\W`, name)
    maybePanic(err)
    nonLower, err := MatchString(`^[^a-z]`, name)
    if nonAlpha || nonLower {
        escapedName := Replace(name, `'`, `\'`, -1)
        return Sprintf("'%s'", escapedName)
    }

    return name
}

func maybePanic(err error) {
    if err != nil {
        panic(err)
    }
}
<|endoftext|>


<commit_before>package rtfdoc

import "fmt"

func (text text) compose() string {
	var res string
	var emphasisBegin string
	var emphasisEnd string
	var emphText string
	if text.isBold {
		emphText += " \\b"
	}
	if text.isItalic {
		emphText += " \\i"
	}
	if text.isScaps {
		emphText += " \\scaps"
	}
	if text.isStrike {
		emphText += " \\strike"
	}
	if text.isSub {
		emphText += " \\sub"
	}
	if text.isSuper {
		emphText += " \\super"
	}
	if text.isUnderlining {
		emphText += " \\ul"
	}
	if emphText != "" {
		emphasisBegin = "{" + emphText + " "
		emphasisEnd = "}"
	}
	PreparedText := convertNonASCIIToUTF16(text.content)

	res += fmt.Sprintf("\n\\fs%d\\f%d \\cf%d %s%s %s\\f0", text.fontSize*2, text.fontCode, text.colorCode, emphasisBegin, PreparedText, emphasisEnd)
	return res
}

// AddText returns new text instance
func (p *paragraph) AddText(textStr string, fontSize int, fontCode string, colorCode string) *text {

	fn := 0
	for i, f := range *p.generalSettings.fontColor {
		if f.code == fontCode {

			fn = i
		}
	}

	fc := 0
	for i, c := range *p.generalSettings.colorTable {
		if c.name == colorCode {

			fc = i + 1
		}
	}
	txt := text{
		fontSize:  fontSize,
		fontCode:  fn,
		colorCode: fc,
		content:   textStr,
		generalSettings: generalSettings{
			colorTable: p.colorTable,
			fontColor:  p.fontColor,
		},
	}
	p.content = append(p.content, &txt)
	return &txt
}

//AddNewLine adds new line into paragraph text
func (p *paragraph) AddNewLine() *paragraph {
	txt := text{
		content: "\\line",
	}
	p.content = append(p.content, &txt)
	return p
}

// SetBold function sets text to Bold
func (text *text) SetBold() *text {
	text.isBold = true
	return text
}

// SetItalic function sets text to Italic
func (text *text) SetItalic() *text {
	text.isItalic = true
	return text
}

// SetUnderlining function sets text to Underlining
func (text *text) SetUnderlining() *text {
	text.isUnderlining = true
	return text
}

// SetSuper function sets text to Super
func (text *text) SetSuper() *text {
	text.isSuper = true
	return text
}

// SetSub function sets text to Sub
func (text *text) SetSub() *text {
	text.isSub = true
	return text
}

// SetScaps function sets text to Scaps
func (text *text) SetScaps() *text {
	text.isScaps = true
	return text
}

// SetStrike function sets text to Strike
func (text *text) SetStrike() *text {
	text.isBold = true
	return text
}

func (text *text) getEmphasis() string {
	return text.emphasis
}

// SetColor sets text color
func (text *text) SetColor(colorCode string) *text {
	for i := range *text.colorTable {
		if (*text.colorTable)[i].name == colorCode {
			// Присваиваем тексту порядковый номер шрифта
			text.colorCode = i + 1
		}
	}

	return text
}
<commit_msg>text compose fix<commit_after>package rtfdoc

import "fmt"

func (text text) compose() string {
	var res string
	var emphasisBegin string
	var emphasisEnd string
	var emphText string
	if text.isBold {
		emphText += " \\b"
	}
	if text.isItalic {
		emphText += " \\i"
	}
	if text.isScaps {
		emphText += " \\scaps"
	}
	if text.isStrike {
		emphText += " \\strike"
	}
	if text.isSub {
		emphText += " \\sub"
	}
	if text.isSuper {
		emphText += " \\super"
	}
	if text.isUnderlining {
		emphText += " \\ul"
	}
	if emphText != "" {
		emphasisBegin = "{" + emphText + " "
		emphasisEnd = "}"
	}
	PreparedText := convertNonASCIIToUTF16(text.content)

	res += fmt.Sprintf("\n\\fs%d\\f%d \\cf%d {%s%s %s}\\f0", text.fontSize*2, text.fontCode, text.colorCode, emphasisBegin, PreparedText, emphasisEnd)
	return res
}

// AddText returns new text instance
func (p *paragraph) AddText(textStr string, fontSize int, fontCode string, colorCode string) *text {

	fn := 0
	for i, f := range *p.generalSettings.fontColor {
		if f.code == fontCode {

			fn = i
		}
	}

	fc := 0
	for i, c := range *p.generalSettings.colorTable {
		if c.name == colorCode {

			fc = i + 1
		}
	}
	txt := text{
		fontSize:  fontSize,
		fontCode:  fn,
		colorCode: fc,
		content:   textStr,
		generalSettings: generalSettings{
			colorTable: p.colorTable,
			fontColor:  p.fontColor,
		},
	}
	p.content = append(p.content, &txt)
	return &txt
}

//AddNewLine adds new line into paragraph text
func (p *paragraph) AddNewLine() *paragraph {
	txt := text{
		content: "\\line",
	}
	p.content = append(p.content, &txt)
	return p
}

// SetBold function sets text to Bold
func (text *text) SetBold() *text {
	text.isBold = true
	return text
}

// SetItalic function sets text to Italic
func (text *text) SetItalic() *text {
	text.isItalic = true
	return text
}

// SetUnderlining function sets text to Underlining
func (text *text) SetUnderlining() *text {
	text.isUnderlining = true
	return text
}

// SetSuper function sets text to Super
func (text *text) SetSuper() *text {
	text.isSuper = true
	return text
}

// SetSub function sets text to Sub
func (text *text) SetSub() *text {
	text.isSub = true
	return text
}

// SetScaps function sets text to Scaps
func (text *text) SetScaps() *text {
	text.isScaps = true
	return text
}

// SetStrike function sets text to Strike
func (text *text) SetStrike() *text {
	text.isBold = true
	return text
}

func (text *text) getEmphasis() string {
	return text.emphasis
}

// SetColor sets text color
func (text *text) SetColor(colorCode string) *text {
	for i := range *text.colorTable {
		if (*text.colorTable)[i].name == colorCode {
			// Присваиваем тексту порядковый номер шрифта
			text.colorCode = i + 1
		}
	}

	return text
}
<|endoftext|>


<commit_before>package termloop

// Text represents a string that can be drawn to the screen.
type Text struct {
	x      int
	y      int
	fg     Attr
	bg     Attr
	text   []rune
	canvas []Cell
}

// NewText creates a new Text, at position (x, y). It sets the Text's
// background and foreground colors to fg and bg respectively, and sets the
// Text's text to be text.
// Returns a pointer to the new Text.
func NewText(x, y int, text string, fg, bg Attr) *Text {
	str := []rune(text)
	c := make([]Cell, len(str))
	for i := range c {
		c[i] = Cell{Ch: str[i], Fg: fg, Bg: bg}
	}
	return &Text{
		x:      x,
		y:      y,
		fg:     fg,
		bg:     bg,
		text:   str,
		canvas: c,
	}
}

func (t *Text) Tick(ev Event) {}

// Draw draws the Text to the Screen s.
func (t *Text) Draw(s *Screen) {
	w, _ := t.Size()
	for i := 0; i < w; i++ {
		s.RenderCell(t.x+i, t.y, &t.canvas[i])
	}
}

// Position returns the (x, y) coordinates of the Text.
func (t *Text) Position() (int, int) {
	return t.x, t.y
}

// Size returns the width and height of the Text.
func (t *Text) Size() (int, int) {
	return len(t.text), 1
}

// SetPosition sets the coordinates of the Text to be (x, y).
func (t *Text) SetPosition(x, y int) {
	t.x = x
	t.y = y
}

// Text returns the text of the Text.
func (t *Text) Text() string {
	return string(t.text)
}

// SetText sets the text of the Text to be text.
func (t *Text) SetText(text string) {
	t.text = []rune(text)
	c := make([]Cell, len(t.text))
	for i := range c {
		c[i] = Cell{Ch: t.text[i], Fg: t.fg, Bg: t.bg}
	}
	t.canvas = c
}

// Color returns the (foreground, background) colors of the Text.
func (t *Text) Color() (Attr, Attr) {
	return t.fg, t.bg
}

// SetColor sets the (foreground, background) colors of the Text
// to fg, bg respectively.
func (t *Text) SetColor(fg, bg Attr) {
	t.fg = fg
	t.bg = bg
}
<commit_msg>Fix bug with setting Text color<commit_after>package termloop

// Text represents a string that can be drawn to the screen.
type Text struct {
	x      int
	y      int
	fg     Attr
	bg     Attr
	text   []rune
	canvas []Cell
}

// NewText creates a new Text, at position (x, y). It sets the Text's
// background and foreground colors to fg and bg respectively, and sets the
// Text's text to be text.
// Returns a pointer to the new Text.
func NewText(x, y int, text string, fg, bg Attr) *Text {
	str := []rune(text)
	c := make([]Cell, len(str))
	for i := range c {
		c[i] = Cell{Ch: str[i], Fg: fg, Bg: bg}
	}
	return &Text{
		x:      x,
		y:      y,
		fg:     fg,
		bg:     bg,
		text:   str,
		canvas: c,
	}
}

func (t *Text) Tick(ev Event) {}

// Draw draws the Text to the Screen s.
func (t *Text) Draw(s *Screen) {
	w, _ := t.Size()
	for i := 0; i < w; i++ {
		s.RenderCell(t.x+i, t.y, &t.canvas[i])
	}
}

// Position returns the (x, y) coordinates of the Text.
func (t *Text) Position() (int, int) {
	return t.x, t.y
}

// Size returns the width and height of the Text.
func (t *Text) Size() (int, int) {
	return len(t.text), 1
}

// SetPosition sets the coordinates of the Text to be (x, y).
func (t *Text) SetPosition(x, y int) {
	t.x = x
	t.y = y
}

// Text returns the text of the Text.
func (t *Text) Text() string {
	return string(t.text)
}

// SetText sets the text of the Text to be text.
func (t *Text) SetText(text string) {
	t.text = []rune(text)
	c := make([]Cell, len(t.text))
	for i := range c {
		c[i] = Cell{Ch: t.text[i], Fg: t.fg, Bg: t.bg}
	}
	t.canvas = c
}

// Color returns the (foreground, background) colors of the Text.
func (t *Text) Color() (Attr, Attr) {
	return t.fg, t.bg
}

// SetColor sets the (foreground, background) colors of the Text
// to fg, bg respectively.
func (t *Text) SetColor(fg, bg Attr) {
	t.fg = fg
	t.bg = bg
	for i := range t.canvas {
		t.canvas[i].Fg = fg
		t.canvas[i].Bg = bg
	}
}
<|endoftext|>


<commit_before>package utils

import (
	"strconv"
	"time"
)

//TimetampToTime string Timetamp to Time
func TimetampToTime(v string) (time.Time, error) {
	t, err := strconv.ParseInt(v, 10, 64)
	if err != nil {
		return time.Time{}, err
	}
	switch len(v) {
	//java.lang.System.currentTimeMillis()
	case 13:
		return time.Unix(0, t*int64(time.Millisecond)).UTC(), nil
	case 19:
		return time.Unix(0, t).UTC(), nil
	}
	return time.Unix(t, 0).UTC(), nil
}
<commit_msg>新增 解析默认时间日期函数<commit_after>package utils

import (
	"strconv"
	"time"
)

//ParseTime
func ParseTime(v string) (time.Time, error) {
	t1, err := time.Parse("2006-01-02 15:04:05-07:00", v+"+08:00")
	if err != nil {
		return time.Now(), err
	}
	return t1, nil
}

//TimetampToTime string Timetamp to Time
func TimetampToTime(v string) (time.Time, error) {
	t, err := strconv.ParseInt(v, 10, 64)
	if err != nil {
		return time.Time{}, err
	}
	switch len(v) {
	//java.lang.System.currentTimeMillis()
	case 13:
		return time.Unix(0, t*int64(time.Millisecond)).UTC(), nil
	case 19:
		return time.Unix(0, t).UTC(), nil
	}
	return time.Unix(t, 0).UTC(), nil
}
<|endoftext|>


<commit_before>package tlsh

import (
	"fmt"
	"io/ioutil"
)

var windowLength = 5
var effBuckets = 256
var codeSize = 32
var numBuckets = 256

// LSH holds the hash components
type LSH struct {
	Checksum byte
	Length   byte
}

func getTriplets(slice []byte) (triplets [][]byte) {
	triplets = [][]byte{
		{slice[0], slice[1], slice[2]},
		{slice[0], slice[1], slice[3]},
		{slice[0], slice[2], slice[3]},
		{slice[0], slice[2], slice[4]},
		{slice[0], slice[1], slice[4]},
		{slice[0], slice[3], slice[4]},
	}
	return triplets
}

func quartilePoints(buckets []byte) (q1, q2, q3 byte) {
	buckets2 := make([]byte, effBuckets)
	copy(buckets2, buckets[:effBuckets])
	sortedBuckets := SortByteArray(buckets2)
	// 25%, 50% and 75%
	return sortedBuckets[(effBuckets/4)-1], sortedBuckets[(effBuckets/2)-1], sortedBuckets[effBuckets-(effBuckets/4)-1]
}

func makeHash(buckets []byte, q1, q2, q3 byte) []uint {
	var biHash []uint

	for i := 0; i < codeSize; i++ {
		var h uint
		for j := 0; j < 4; j++ {
			k := buckets[4*i+j]
			if q3 < k {
				h += 3 << (uint(j) * 2)
			} else if q2 < k {
				h += 2 << (uint(j) * 2)
			} else if q1 < k {
				h += 1 << (uint(j) * 2)
			}
		}
		biHash = append([]uint{h}, biHash...)
	}

	return biHash
}

//Hash calculates the TLSH for the input file
func Hash(filename string) (hash string, err error) {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return
	}
	buckets := make([]byte, numBuckets)
	chunk := make([]byte, windowLength)
	sw := 0
	for sw <= len(data)-windowLength {

		for j, x := sw+windowLength-1, 0; j >= sw; j, x = j-1, x+1 {
			chunk[x] = data[j]
		}

		sw++
		triplets := getTriplets(chunk)
		salt := []byte{2, 3, 5, 7, 11, 13}
		for i, triplet := range triplets {
			buckets[pearsonHash(salt[i], triplet)]++
		}
	}
	q1, q2, q3 := quartilePoints(buckets)
	fmt.Println(q1, q2, q3)
	q1Ratio := (q1 * 100 / q3) % 16
	q2Ratio := (q2 * 100 / q3) % 16
	fmt.Println(q1Ratio, q2Ratio)
	//checksum := pearsonHash(0, triplet)
	//fmt.Println(checksum)

	biHash := makeHash(buckets, q1, q2, q3)

	return
}
<commit_msg>Return string representation of hash<commit_after>package tlsh

import (
	"fmt"
	"io/ioutil"
)

var windowLength = 5
var effBuckets = 256
var codeSize = 32
var numBuckets = 256

// LSH holds the hash components
type LSH struct {
	Checksum byte
	Length   byte
}

func getTriplets(slice []byte) (triplets [][]byte) {
	triplets = [][]byte{
		{slice[0], slice[1], slice[2]},
		{slice[0], slice[1], slice[3]},
		{slice[0], slice[2], slice[3]},
		{slice[0], slice[2], slice[4]},
		{slice[0], slice[1], slice[4]},
		{slice[0], slice[3], slice[4]},
	}
	return triplets
}

func quartilePoints(buckets []byte) (q1, q2, q3 byte) {
	buckets2 := make([]byte, effBuckets)
	copy(buckets2, buckets[:effBuckets])
	sortedBuckets := SortByteArray(buckets2)
	// 25%, 50% and 75%
	return sortedBuckets[(effBuckets/4)-1], sortedBuckets[(effBuckets/2)-1], sortedBuckets[effBuckets-(effBuckets/4)-1]
}

func makeHash(buckets []byte, q1, q2, q3 byte) []uint {
	var biHash []uint

	for i := 0; i < codeSize; i++ {
		var h uint
		for j := 0; j < 4; j++ {
			k := buckets[4*i+j]
			if q3 < k {
				h += 3 << (uint(j) * 2)
			} else if q2 < k {
				h += 2 << (uint(j) * 2)
			} else if q1 < k {
				h += 1 << (uint(j) * 2)
			}
		}
		biHash = append([]uint{h}, biHash...)
	}

	return biHash
}

//Hash calculates the TLSH for the input file
func Hash(filename string) (hash string, err error) {
	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return
	}
	buckets := make([]byte, numBuckets)
	chunk := make([]byte, windowLength)
	sw := 0
	for sw <= len(data)-windowLength {

		for j, x := sw+windowLength-1, 0; j >= sw; j, x = j-1, x+1 {
			chunk[x] = data[j]
		}

		sw++
		triplets := getTriplets(chunk)
		salt := []byte{2, 3, 5, 7, 11, 13}
		for i, triplet := range triplets {
			buckets[pearsonHash(salt[i], triplet)]++
		}
	}
	q1, q2, q3 := quartilePoints(buckets)
	fmt.Println(q1, q2, q3)
	q1Ratio := (q1 * 100 / q3) % 16
	q2Ratio := (q2 * 100 / q3) % 16
	fmt.Println(q1Ratio, q2Ratio)
	//checksum := pearsonHash(0, triplet)
	//fmt.Println(checksum)

	biHash := makeHash(buckets, q1, q2, q3)

	for i := 0; i < len(biHash); i++ {
		hash += fmt.Sprintf("%02X", biHash[i])
	}

	return hash, nil
}
<|endoftext|>


<commit_before>package gogame

/*
#cgo pkg-config: sdl2
#include "SDL.h"

extern SDL_AudioDeviceID newAudioDevice(int frequency);
extern void closeAudioDevice(SDL_AudioDeviceID id);

*/
import "C"
import "errors"
import "unsafe"
import "math"

const FREQUENCY = 44100

var toneCache = make(map[int]*ToneGenerator)

//export soundGoCallback
func soundGoCallback(id int, ptr unsafe.Pointer, len int) {
	tg := toneCache[id]
	len /= 4
	// To create a Go slice backed by a C array
	// (without copying the original data), one needs to acquire this length
	// at runtime and use a type conversion to a pointer to a very big array and then
	// slice it to the length that you want (also remember to set
	// the cap if you're using Go 1.2 or later)
	slice := (*[1 << 30]float32)(unsafe.Pointer(ptr))[:len:len]
	tg.feedSamples(slice)
}

type ToneGenerator struct {
	dev    C.SDL_AudioDeviceID
	amp    float32
	freq   float32
	v      float32
	period int
	j      int
}

func NewToneGenerator() (*ToneGenerator, error) {
	dev := C.newAudioDevice(FREQUENCY)
	if dev == 0 {
		return nil, errors.New("Can't open tone generator")
	}
	sd := new(ToneGenerator)
	sd.dev = dev
	toneCache[int(sd.dev)] = sd
	return sd, nil
}

func (self *ToneGenerator) Start() {
	C.SDL_PauseAudioDevice(self.dev, 0)
}

func (self *ToneGenerator) Stop() {
	C.SDL_PauseAudioDevice(self.dev, 1)
}

func (self *ToneGenerator) SetFreq(freq int) {
	self.freq = float32(freq)
	self.v = 0
	self.j = 0
	self.period = int(2 * FREQUENCY / self.freq)
}

func (self *ToneGenerator) SetAmplitude(amp int) {
	self.amp = float32(amp)
}

func (self *ToneGenerator) Close() {
	C.closeAudioDevice(self.dev)
	delete(toneCache, int(self.dev))
}

func (self *ToneGenerator) feedSamples(data []float32) {
	for i := 0; i < len(data); i++ {
		data[i] = self.amp * float32(math.Sin(float64(self.v*2*math.Pi/FREQUENCY)))
		if self.j > self.period {
			self.v -= float32(self.period) * self.freq
			self.j = 0
		} else {
			self.v += self.freq
			self.j++
		}
	}
}
<commit_msg>Anem fent<commit_after>package gogame

/*
#cgo pkg-config: sdl2
#include "SDL.h"

extern SDL_AudioDeviceID newAudioDevice(int frequency);
extern void closeAudioDevice(SDL_AudioDeviceID id);

*/
import "C"
import "errors"
import "unsafe"
import "math"

const FREQUENCY = 44100

var toneCache = make(map[int]*ToneGenerator)

//export soundGoCallback
func soundGoCallback(id int, ptr unsafe.Pointer, len int) {
	tg := toneCache[id]
	len /= 4
	// To create a Go slice backed by a C array
	// (without copying the original data), one needs to acquire this length
	// at runtime and use a type conversion to a pointer to a very big array and then
	// slice it to the length that you want (also remember to set
	// the cap if you're using Go 1.2 or later)
	slice := (*[1 << 30]float32)(unsafe.Pointer(ptr))[:len:len]
	tg.feedSamples(slice)
}

type ToneGenerator struct {
	dev    C.SDL_AudioDeviceID
	amp    float32
	freq   float32
	v      float32
	period int
	j      int
}

func NewToneGenerator() (*ToneGenerator, error) {
	dev := C.newAudioDevice(FREQUENCY)
	if dev == 0 {
		return nil, errors.New("Can't open tone generator")
	}
	sd := new(ToneGenerator)
	sd.dev = dev
	toneCache[int(sd.dev)] = sd
	return sd, nil
}

func (self *ToneGenerator) Start() {
	C.SDL_PauseAudioDevice(self.dev, 0)
}

func (self *ToneGenerator) Stop() {
	C.SDL_PauseAudioDevice(self.dev, 1)
}

func (self *ToneGenerator) SetFreq(freq int) {
	self.freq = float32(freq)
	self.period = int(2 * FREQUENCY / self.freq)
}

func (self *ToneGenerator) SetAmplitude(amp int) {
	self.amp = float32(amp)
}

func (self *ToneGenerator) Close() {
	C.closeAudioDevice(self.dev)
	delete(toneCache, int(self.dev))
}

func (self *ToneGenerator) feedSamples(data []float32) {
	for i := 0; i < len(data); i++ {
		data[i] = self.amp * float32(math.Sin(float64(self.v*2*math.Pi/FREQUENCY)))
		if self.j > self.period {
			self.v -= float32(self.period) * self.freq
			self.j = 0
		} else {
			self.v += self.freq
			self.j++
		}
	}
}
<|endoftext|>


<commit_before>package drivers

import (
	"io"

	"github.com/lxc/lxd/lxd/migration"
	"github.com/lxc/lxd/lxd/operations"
	"github.com/lxc/lxd/lxd/state"
	"github.com/lxc/lxd/shared/api"
	"github.com/lxc/lxd/shared/logger"
)

// driver is the extended internal interface.
type driver interface {
	Driver

	init(state *state.State, name string, config map[string]string, logger logger.Logger, volIDFunc func(volType VolumeType, volName string) (int64, error), commonRulesFunc func(vol Volume) map[string]func(string) error)
	load() error
}

// Driver represents a low-level storage driver.
type Driver interface {
	// Internal.
	Config() map[string]string
	Info() Info
	HasVolume(vol Volume) bool

	// Pool.
	Create() error
	Delete(op *operations.Operation) error
	Mount() (bool, error)
	Unmount() (bool, error)
	GetResources() (*api.ResourcesStoragePool, error)
	Validate(config map[string]string) error
	Update(changedConfig map[string]string) error

	// Volumes.
	ValidateVolume(vol Volume, removeUnknownKeys bool) error
	CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Operation) error
	CreateVolumeFromCopy(vol Volume, srcVol Volume, copySnapshots bool, op *operations.Operation) error
	RefreshVolume(vol Volume, srcVol Volume, srcSnapshots []Volume, op *operations.Operation) error
	DeleteVolume(vol Volume, op *operations.Operation) error
	RenameVolume(vol Volume, newName string, op *operations.Operation) error
	UpdateVolume(vol Volume, changedConfig map[string]string) error
	GetVolumeUsage(vol Volume) (int64, error)
	SetVolumeQuota(vol Volume, size string, op *operations.Operation) error
	GetVolumeDiskPath(vol Volume) (string, error)

	// MountVolume mounts a storage volume, returns true if we caused a new mount, false if
	// already mounted.
	MountVolume(vol Volume, op *operations.Operation) (bool, error)

	// MountVolumeSnapshot mounts a storage volume snapshot as readonly, returns true if we
	// caused a new mount, false if already mounted.
	MountVolumeSnapshot(snapVol Volume, op *operations.Operation) (bool, error)

	// UnmountVolume unmounts a storage volume, returns true if unmounted, false if was not
	// mounted.
	UnmountVolume(vol Volume, op *operations.Operation) (bool, error)

	// UnmountVolume unmounts a storage volume snapshot, returns true if unmounted, false if was
	// not mounted.
	UnmountVolumeSnapshot(snapVol Volume, op *operations.Operation) (bool, error)

	CreateVolumeSnapshot(snapVol Volume, op *operations.Operation) error
	DeleteVolumeSnapshot(snapVol Volume, op *operations.Operation) error
	RenameVolumeSnapshot(snapVol Volume, newSnapshotName string, op *operations.Operation) error
	VolumeSnapshots(vol Volume, op *operations.Operation) ([]string, error)
	RestoreVolume(vol Volume, snapshotName string, op *operations.Operation) error

	// Migration.
	MigrationTypes(contentType ContentType, refresh bool) []migration.Type
	MigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs migration.VolumeSourceArgs, op *operations.Operation) error
	CreateVolumeFromMigration(vol Volume, conn io.ReadWriteCloser, volTargetArgs migration.VolumeTargetArgs, preFiller *VolumeFiller, op *operations.Operation) error

	// Backup.
	BackupVolume(vol Volume, targetPath string, optimized bool, snapshots bool, op *operations.Operation) error
	CreateVolumeFromBackup(vol Volume, snapshots []string, srcData io.ReadSeeker, optimizedStorage bool, op *operations.Operation) (func(vol Volume) error, func(), error)
}
<commit_msg>lxd/storage/drivers/interface: Comments on pool mount/unmount definitions<commit_after>package drivers

import (
	"io"

	"github.com/lxc/lxd/lxd/migration"
	"github.com/lxc/lxd/lxd/operations"
	"github.com/lxc/lxd/lxd/state"
	"github.com/lxc/lxd/shared/api"
	"github.com/lxc/lxd/shared/logger"
)

// driver is the extended internal interface.
type driver interface {
	Driver

	init(state *state.State, name string, config map[string]string, logger logger.Logger, volIDFunc func(volType VolumeType, volName string) (int64, error), commonRulesFunc func(vol Volume) map[string]func(string) error)
	load() error
}

// Driver represents a low-level storage driver.
type Driver interface {
	// Internal.
	Config() map[string]string
	Info() Info
	HasVolume(vol Volume) bool

	// Pool.
	Create() error
	Delete(op *operations.Operation) error
	// Mount mounts a storage pool if needed, returns true if we caused a new mount, false if already mounted.
	Mount() (bool, error)

	// Unmount unmounts a storage pool if needed, returns true if unmounted, false if was not mounted.
	Unmount() (bool, error)
	GetResources() (*api.ResourcesStoragePool, error)
	Validate(config map[string]string) error
	Update(changedConfig map[string]string) error

	// Volumes.
	ValidateVolume(vol Volume, removeUnknownKeys bool) error
	CreateVolume(vol Volume, filler *VolumeFiller, op *operations.Operation) error
	CreateVolumeFromCopy(vol Volume, srcVol Volume, copySnapshots bool, op *operations.Operation) error
	RefreshVolume(vol Volume, srcVol Volume, srcSnapshots []Volume, op *operations.Operation) error
	DeleteVolume(vol Volume, op *operations.Operation) error
	RenameVolume(vol Volume, newName string, op *operations.Operation) error
	UpdateVolume(vol Volume, changedConfig map[string]string) error
	GetVolumeUsage(vol Volume) (int64, error)
	SetVolumeQuota(vol Volume, size string, op *operations.Operation) error
	GetVolumeDiskPath(vol Volume) (string, error)

	// MountVolume mounts a storage volume, returns true if we caused a new mount, false if
	// already mounted.
	MountVolume(vol Volume, op *operations.Operation) (bool, error)

	// MountVolumeSnapshot mounts a storage volume snapshot as readonly, returns true if we
	// caused a new mount, false if already mounted.
	MountVolumeSnapshot(snapVol Volume, op *operations.Operation) (bool, error)

	// UnmountVolume unmounts a storage volume, returns true if unmounted, false if was not
	// mounted.
	UnmountVolume(vol Volume, op *operations.Operation) (bool, error)

	// UnmountVolume unmounts a storage volume snapshot, returns true if unmounted, false if was
	// not mounted.
	UnmountVolumeSnapshot(snapVol Volume, op *operations.Operation) (bool, error)

	CreateVolumeSnapshot(snapVol Volume, op *operations.Operation) error
	DeleteVolumeSnapshot(snapVol Volume, op *operations.Operation) error
	RenameVolumeSnapshot(snapVol Volume, newSnapshotName string, op *operations.Operation) error
	VolumeSnapshots(vol Volume, op *operations.Operation) ([]string, error)
	RestoreVolume(vol Volume, snapshotName string, op *operations.Operation) error

	// Migration.
	MigrationTypes(contentType ContentType, refresh bool) []migration.Type
	MigrateVolume(vol Volume, conn io.ReadWriteCloser, volSrcArgs migration.VolumeSourceArgs, op *operations.Operation) error
	CreateVolumeFromMigration(vol Volume, conn io.ReadWriteCloser, volTargetArgs migration.VolumeTargetArgs, preFiller *VolumeFiller, op *operations.Operation) error

	// Backup.
	BackupVolume(vol Volume, targetPath string, optimized bool, snapshots bool, op *operations.Operation) error
	CreateVolumeFromBackup(vol Volume, snapshots []string, srcData io.ReadSeeker, optimizedStorage bool, op *operations.Operation) (func(vol Volume) error, func(), error)
}
<|endoftext|>


<commit_before>package tree

import "fmt"

var limit = 3 // maximum amount of childs for each nodes

type Tree struct {
	root *Node
}

type Node struct {
	parent *Node
	child []*Node
	data Data
}

type Data struct {
	Id int
}

type Result struct {
	Parent int
	Child []int
	Data Data
}

var treeIndex map[int]*Node

func addNode (parent *Node, data Data) *Node {
	return &Node{parent, make([]*Node, limit), data}
}

func (tree *Tree) Insert(data Data) (node *Node) {
	treeIndex = make(map[int]*Node)
	if tree.root == nil {
		node = addNode(nil, data)
		treeIndex[data.Id] = node
		tree.root = node

		return
	}

	return
}

func (node *Node) SetAllNodes(results []*Result) {
	var newNode, currentNode *Node
	for _, result := range results {
		if result.Parent != 0 {
			currentNode = node.Search(result.Parent)
		} else {
			currentNode = node
		}
		newNode = currentNode.Insert(result.Data)
		treeIndex[result.Data.Id] = newNode
	}
}

func (node *Node) findFreeNode() *Node {
	stack := make([]*Node, 0, 32)
	stack = append(stack, node) // push root to stack
	var n *Node = nil

	for stack != nil {
		n, stack = stack[0], stack[1:] //pop first node

		for index := 0; index < len(n.child); index++ {
			if (n.child[index] == nil) {
				return n
			}
			stack = append(stack, n.child[index]) // push
		}
	}

	return nil
}

func (node *Node) Insert(data Data) (newNode *Node) {
	for i := 0; i< len(node.child); i++ {
		if (node.child[i] == nil) {
			newNode = addNode(node, data)
			treeIndex[data.Id] = node
			node.child[i] = newNode

			return
		}
	}

	freeNode := node.findFreeNode()
	newNode = freeNode.Insert(data)

	return
}

func (node *Node) Print() {
	if node == nil {
		return
	}

	fmt.Print(node.data)
	fmt.Print("\n")
	for i := 0; i < len(node.child); i++ {
		node.child[i].Print()
	}
}

func (node *Node) Search(id int) (n *Node) {

	n = treeIndex[id]
	if n == nil {
		return nil
	}

	return
}

func (node *Node) GetData() (result *Result) {
	var childs []int = make([]int, 0)
	for _, value := range node.child {
		if value != nil {
			childs = append(childs, value.data.Id)
		} else {
			childs = append(childs, 0)
		}
	}

	var parentNode int = 0

	if node.parent != nil {
		parentNode = node.parent.data.Id
	}

	return &Result{
		Parent: parentNode,
		Child: childs,
		Data: node.data,
	}
}

func getLevel(nodes []*Node) (results []*Node) {
	for _, value := range nodes {
		for index := 0; index < len(value.child); index++ {
			if (value.child[index] == nil) {
				continue
			}
			results = append(results, value.child[index])
		}
	}

	return
}

func (node *Node) GetNodes(level int) (results []*Result) {
	nodes := make([]*Node, 0)
	nodes = append(nodes, node)
	results = append(results, node.GetData())

	for index := 0; index < level; index++ {
		nodes = getLevel(nodes)
		for _, value := range nodes {
			results = append(results, value.GetData())
		}
	}

	return
}
<commit_msg>fix bug with caching<commit_after>package tree

import "fmt"

var limit = 3 // maximum amount of childs for each nodes

type Tree struct {
	root *Node
}

type Node struct {
	parent *Node
	child []*Node
	data Data
}

type Data struct {
	Id int
}

type Result struct {
	Parent int
	Child []int
	Data Data
}

var treeIndex map[int]*Node

func addNode (parent *Node, data Data) *Node {
	return &Node{parent, make([]*Node, limit), data}
}

func (tree *Tree) Insert(data Data) (node *Node) {
	treeIndex = make(map[int]*Node)
	if tree.root == nil {
		node = addNode(nil, data)
		treeIndex[data.Id] = node
		tree.root = node

		return
	}

	return
}

func (node *Node) SetAllNodes(results []*Result) {
	var newNode, currentNode *Node
	for _, result := range results {
		if result.Parent != 0 {
			currentNode = node.Search(result.Parent)
		} else {
			currentNode = node
		}
		newNode = currentNode.Insert(result.Data)
		treeIndex[result.Data.Id] = newNode
	}
}

func (node *Node) findFreeNode() *Node {
	stack := make([]*Node, 0, 32)
	stack = append(stack, node) // push root to stack
	var n *Node = nil

	for stack != nil {
		n, stack = stack[0], stack[1:] //pop first node

		for index := 0; index < len(n.child); index++ {
			if (n.child[index] == nil) {
				return n
			}
			stack = append(stack, n.child[index]) // push
		}
	}

	return nil
}

func (node *Node) Insert(data Data) (newNode *Node) {
	for i := 0; i< len(node.child); i++ {
		if (node.child[i] == nil) {
			newNode = addNode(node, data)
			treeIndex[data.Id] = newNode
			node.child[i] = newNode

			return
		}
	}

	freeNode := node.findFreeNode()
	newNode = freeNode.Insert(data)

	return
}

func (node *Node) Print() {
	if node == nil {
		return
	}

	fmt.Print(node.data)
	fmt.Print("\n")
	for i := 0; i < len(node.child); i++ {
		node.child[i].Print()
	}
}

func (node *Node) Search(id int) (n *Node) {

	n = treeIndex[id]
	if n == nil {
		return nil
	}

	return
}

func (node *Node) GetData() (result *Result) {
	var childs []int = make([]int, 0)
	for _, value := range node.child {
		if value != nil {
			childs = append(childs, value.data.Id)
		} else {
			childs = append(childs, 0)
		}
	}

	var parentNode int = 0

	if node.parent != nil {
		parentNode = node.parent.data.Id
	}

	return &Result{
		Parent: parentNode,
		Child: childs,
		Data: node.data,
	}
}

func getLevel(nodes []*Node) (results []*Node) {
	for _, value := range nodes {
		for index := 0; index < len(value.child); index++ {
			if (value.child[index] == nil) {
				continue
			}
			results = append(results, value.child[index])
		}
	}

	return
}

func (node *Node) GetNodes(level int) (results []*Result) {
	nodes := make([]*Node, 0)
	nodes = append(nodes, node)
	results = append(results, node.GetData())

	for index := 0; index < level; index++ {
		nodes = getLevel(nodes)
		for _, value := range nodes {
			results = append(results, value.GetData())
		}
	}

	return
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 CHEN Xianren. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

package tiny

import (
	"bytes"
	"net/http"
	"sync"
)

type Tree struct {
	handlers       []Handler
	names          []string
	methods, nodes map[string]*Node
	pool           sync.Pool
}

func (t *Tree) naming(name string, n *Node) {
	if len(name) > 0 {
		if t.nodes == nil {
			t.nodes = map[string]*Node{name: n}
		} else if _, ok := t.nodes[name]; ok {
			panic("duplicate route name: " + name)
		} else {
			t.nodes[name] = n
		}
	}
}

func (t *Tree) getParams() []string {
	if t.pool.New == nil {
		t.pool.New = func() interface{} {
			return make([]string, len(t.names))
		}
	}
	return t.pool.Get().([]string)
}

func (t *Tree) putParams(params []string) {
	t.pool.Put(params[:len(t.names)])
}

func (t *Tree) match(method, path string) (n *Node, params []string) {
	params = t.getParams()
	f := func(s string) (ok bool) {
		n, ok = t.methods[s]
		if ok {
			n, ok = n.match(path, params[:0])
			if ok && n != nil && n.handlers != nil {
				params = params[:len(n.names)]
				return true
			}
		}
		return false
	}
	if f(method) {
		return
	}
	if method != "" && f("") {
		return
	}
	n, params = nil, params[:0]
	return
}

func (t *Tree) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.RequestURI == "*" {
		if r.ProtoAtLeast(1, 1) {
			w.Header().Set("Connection", "close")
		}
		w.WriteHeader(http.StatusBadRequest)
		return
	}
	n, params := t.match(r.Method, r.URL.Path)
	ctx := &Context{ResponseWriter: w, Request: r, Params: params, tree: t, node: n}
	ctx.call(ctx.index)
	t.putParams(params)
}

func newTree(r *Router) *Tree {
	if r.above != nil {
		panic("subrouter not allowed")
	}
	t := &Tree{
		methods:  make(map[string]*Node, 10),
		handlers: copyHandlers(r.handlers),
	}
	var i int
	handlers := make([]Handler, 0, 10)
	tags := make([]Tag, 0, 10)
Loop:
	for {
		if r.above != nil {
			handlers = append(handlers, r.handlers...)
		}
		for ; i < len(r.routes); i++ {
			rr := r.routes[i]
			handlers = append(handlers, rr.handlers...)
			tags = append(tags, rr.tags...)
			if rr.below != nil {
				r = rr.below
				i = 0
				continue Loop
			}
			n, ok := t.methods[rr.method]
			if !ok {
				n = new(Node)
				t.methods[rr.method] = n
			}
			var names []string
			k := 0
			for _, tag := range tags {
				if tag.Kind > 0 {
					k++
				}
			}
			if k > 0 {
				names = make([]string, k)
				k = 0
			}
			for _, tag := range tags {
				if tag.Kind > 0 {
					n = n.mergeVariable(tag)
					names[k] = tag.Name
					k++
				} else {
					n = n.mergeStatic(tag)
				}
			}
			n.names = names
			if n.handlers != nil {
				panic("duplicate route " + rr.method + " " + n.path())
			} else {
				n.handlers = copyHandlers(handlers)
			}
			t.naming(rr.Name, n)
			if len(names) > len(t.names) {
				t.names = names
			}
			handlers = handlers[:len(handlers)-len(rr.handlers)]
			tags = tags[:len(tags)-len(rr.tags)]
		}
		if r.above != nil {
			i = r.above.index
			handlers = handlers[:len(handlers)-len(r.handlers)-len(r.above.handlers)]
			tags = tags[:len(tags)-len(r.above.tags)]
			r = r.above.above
		} else {
			break
		}
	}
	return t
}

type Node struct {
	tag          Tag
	above        *Node
	index        int
	static, back *Static
	variables    []*Node
	handlers     []Handler
	names        []string
}

type Static struct {
	below     *Node
	prefix    string
	indexes   []byte
	constants []*Static
	back      *Static
}

func (x *Static) merge(s string) *Static {
	for {
		i := bytes.IndexByte(x.indexes, s[0])
		if i == -1 {
			break
		}
		x = x.constants[i]
		i = 1
		for i < len(x.prefix) && i < len(s) {
			if x.prefix[i] == s[i] {
				i++
			} else {
				break
			}
		}
		if i == len(x.prefix) {
			if i == len(s) {
				return x
			} else {
				s = s[i:]
			}
		} else {
			y := &Static{
				below:     x.below,
				prefix:    x.prefix[i:],
				constants: x.constants,
				indexes:   x.indexes,
				back:      x,
			}
			x.below = nil
			x.prefix = x.prefix[:i]
			x.constants = []*Static{y}
			x.indexes = []byte{y.prefix[0]}
			if i == len(s) {
				return x
			}
			y = &Static{prefix: s[i:], back: x}
			x.constants = append(x.constants, y)
			x.indexes = append(x.indexes, y.prefix[0])
			return y
		}
	}
	y := &Static{prefix: s, back: x}
	x.constants = append(x.constants, y)
	x.indexes = append(x.indexes, y.prefix[0])
	return y
}

func (n *Node) mergeStatic(t Tag) *Node {
	if len(t.Name) == 0 {
		return n
	}
	if n.static == nil {
		n.static = new(Static)
	}
	x := n.static.merge(t.Name)
	if x.below == nil {
		x.below = &Node{tag: t, above: n, back: x}
	}
	return x.below
}

func (n *Node) mergeVariable(t Tag) *Node {
	var i int
	for ; i < len(n.variables); i++ {
		if v := n.variables[i]; t.Same(v.tag) {
			if t.Name != v.tag.Name {
				panic("inconsistent tag name: " + t.Name)
			}
			return v
		} else if t.Kind < v.tag.Kind {
			break
		}
	}
	n.variables = append(n.variables, nil)
	for j := len(n.variables) - 1; j > i; j-- {
		n.variables[j] = n.variables[j-1]
		n.variables[j].index = j + 1
	}
	v := &Node{tag: t, above: n, index: i + 1}
	n.variables[i] = v
	return v
}

func (n *Node) path() (s string) {
	for n != nil {
		s = n.tag.String() + s
		n = n.above
	}
	return
}

func (n *Node) match(path string, params []string) (*Node, bool) {
	var x *Static
	s, i := path, -1
Loop:
	for {
		if len(s) == 0 {
			return n, true
		}
		if i == -1 {
			x = n.static
			for x != nil {
				i = bytes.IndexByte(x.indexes, s[0])
				if i >= 0 {
					x = x.constants[i]
					i = len(x.prefix)
					if len(s) >= i && s[:i] == x.prefix {
						s = s[i:]
						if len(s) == 0 {
							return x.below, true
						}
						continue
					} else {
						x = x.back
					}
				}
				break
			}
			for x != nil {
				if x.below != nil {
					n = x.below
					i = -1
					continue Loop
				}
				s = path[len(path)-len(s)-len(x.prefix):]
				x = x.back
			}
			i = 0
		}
		for ; i < len(n.variables); i++ {
			if j := n.variables[i].tag.Boundary(s); j > 0 {
				params = append(params, s[:j])
				s = s[j:]
				n = n.variables[i]
				i = -1
				continue Loop
			}
		}
		if n.above == nil {
			break
		}
		if x = n.back; x != nil {
			for {
				s = path[len(path)-len(s)-len(x.prefix):]
				x = x.back
				if x == nil {
					break
				} else if x.below != nil {
					n = x.below
					i = 0
					continue Loop
				}
			}
		} else {
			i = len(params) - 1
			s = path[len(path)-len(s)-len(params[i]):]
			params = params[:i]
		}
		i = n.index
		n = n.above
	}
	return nil, false
}
<commit_msg>fix copy handlers more than once<commit_after>// Copyright (c) 2016 CHEN Xianren. All rights reserved.
// Use of this source code is governed by a MIT
// license that can be found in the LICENSE file.

package tiny

import (
	"bytes"
	"net/http"
	"sync"
)

type Tree struct {
	handlers       []Handler
	names          []string
	methods, nodes map[string]*Node
	pool           sync.Pool
}

func (t *Tree) naming(name string, n *Node) {
	if len(name) > 0 {
		if t.nodes == nil {
			t.nodes = map[string]*Node{name: n}
		} else if _, ok := t.nodes[name]; ok {
			panic("duplicate route name: " + name)
		} else {
			t.nodes[name] = n
		}
	}
}

func (t *Tree) getParams() []string {
	if t.pool.New == nil {
		t.pool.New = func() interface{} {
			return make([]string, len(t.names))
		}
	}
	return t.pool.Get().([]string)
}

func (t *Tree) putParams(params []string) {
	t.pool.Put(params[:len(t.names)])
}

func (t *Tree) match(method, path string) (n *Node, params []string) {
	params = t.getParams()
	f := func(s string) (ok bool) {
		n, ok = t.methods[s]
		if ok {
			n, ok = n.match(path, params[:0])
			if ok && n != nil && n.handlers != nil {
				params = params[:len(n.names)]
				return true
			}
		}
		return false
	}
	if f(method) {
		return
	}
	if method != "" && f("") {
		return
	}
	n, params = nil, params[:0]
	return
}

func (t *Tree) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if r.RequestURI == "*" {
		if r.ProtoAtLeast(1, 1) {
			w.Header().Set("Connection", "close")
		}
		w.WriteHeader(http.StatusBadRequest)
		return
	}
	n, params := t.match(r.Method, r.URL.Path)
	ctx := &Context{ResponseWriter: w, Request: r, Params: params, tree: t, node: n}
	ctx.call(ctx.index)
	t.putParams(params)
}

func newTree(r *Router) *Tree {
	if r.above != nil {
		panic("subrouter not allowed")
	}
	t := &Tree{
		methods:  make(map[string]*Node, 10),
		handlers: copyHandlers(r.handlers),
	}
	var i int
	handlers := make([]Handler, 0, 10)
	tags := make([]Tag, 0, 10)
Loop:
	for {
		if r.above != nil && i == 0 {
			handlers = append(handlers, r.handlers...)
		}
		for ; i < len(r.routes); i++ {
			rr := r.routes[i]
			handlers = append(handlers, rr.handlers...)
			tags = append(tags, rr.tags...)
			if rr.below != nil {
				r = rr.below
				i = 0
				continue Loop
			}
			n, ok := t.methods[rr.method]
			if !ok {
				n = new(Node)
				t.methods[rr.method] = n
			}
			var names []string
			k := 0
			for _, tag := range tags {
				if tag.Kind > 0 {
					k++
				}
			}
			if k > 0 {
				names = make([]string, k)
				k = 0
			}
			for _, tag := range tags {
				if tag.Kind > 0 {
					n = n.mergeVariable(tag)
					names[k] = tag.Name
					k++
				} else {
					n = n.mergeStatic(tag)
				}
			}
			n.names = names
			if n.handlers != nil {
				panic("duplicate route " + rr.method + " " + n.path())
			} else {
				n.handlers = copyHandlers(handlers)
			}
			t.naming(rr.Name, n)
			if len(names) > len(t.names) {
				t.names = names
			}
			handlers = handlers[:len(handlers)-len(rr.handlers)]
			tags = tags[:len(tags)-len(rr.tags)]
		}
		if r.above != nil {
			i = r.above.index
			handlers = handlers[:len(handlers)-len(r.handlers)-len(r.above.handlers)]
			tags = tags[:len(tags)-len(r.above.tags)]
			r = r.above.above
		} else {
			break
		}
	}
	return t
}

type Node struct {
	tag          Tag
	above        *Node
	index        int
	static, back *Static
	variables    []*Node
	handlers     []Handler
	names        []string
}

type Static struct {
	below     *Node
	prefix    string
	indexes   []byte
	constants []*Static
	back      *Static
}

func (x *Static) merge(s string) *Static {
	for {
		i := bytes.IndexByte(x.indexes, s[0])
		if i == -1 {
			break
		}
		x = x.constants[i]
		i = 1
		for i < len(x.prefix) && i < len(s) {
			if x.prefix[i] == s[i] {
				i++
			} else {
				break
			}
		}
		if i == len(x.prefix) {
			if i == len(s) {
				return x
			} else {
				s = s[i:]
			}
		} else {
			y := &Static{
				below:     x.below,
				prefix:    x.prefix[i:],
				constants: x.constants,
				indexes:   x.indexes,
				back:      x,
			}
			x.below = nil
			x.prefix = x.prefix[:i]
			x.constants = []*Static{y}
			x.indexes = []byte{y.prefix[0]}
			if i == len(s) {
				return x
			}
			y = &Static{prefix: s[i:], back: x}
			x.constants = append(x.constants, y)
			x.indexes = append(x.indexes, y.prefix[0])
			return y
		}
	}
	y := &Static{prefix: s, back: x}
	x.constants = append(x.constants, y)
	x.indexes = append(x.indexes, y.prefix[0])
	return y
}

func (n *Node) mergeStatic(t Tag) *Node {
	if len(t.Name) == 0 {
		return n
	}
	if n.static == nil {
		n.static = new(Static)
	}
	x := n.static.merge(t.Name)
	if x.below == nil {
		x.below = &Node{tag: t, above: n, back: x}
	}
	return x.below
}

func (n *Node) mergeVariable(t Tag) *Node {
	var i int
	for ; i < len(n.variables); i++ {
		if v := n.variables[i]; t.Same(v.tag) {
			if t.Name != v.tag.Name {
				panic("inconsistent tag name: " + t.Name)
			}
			return v
		} else if t.Kind < v.tag.Kind {
			break
		}
	}
	n.variables = append(n.variables, nil)
	for j := len(n.variables) - 1; j > i; j-- {
		n.variables[j] = n.variables[j-1]
		n.variables[j].index = j + 1
	}
	v := &Node{tag: t, above: n, index: i + 1}
	n.variables[i] = v
	return v
}

func (n *Node) path() (s string) {
	for n != nil {
		s = n.tag.String() + s
		n = n.above
	}
	return
}

func (n *Node) match(path string, params []string) (*Node, bool) {
	var x *Static
	s, i := path, -1
Loop:
	for {
		if len(s) == 0 {
			return n, true
		}
		if i == -1 {
			x = n.static
			for x != nil {
				i = bytes.IndexByte(x.indexes, s[0])
				if i >= 0 {
					x = x.constants[i]
					i = len(x.prefix)
					if len(s) >= i && s[:i] == x.prefix {
						s = s[i:]
						if len(s) == 0 {
							return x.below, true
						}
						continue
					} else {
						x = x.back
					}
				}
				break
			}
			for x != nil {
				if x.below != nil {
					n = x.below
					i = -1
					continue Loop
				}
				s = path[len(path)-len(s)-len(x.prefix):]
				x = x.back
			}
			i = 0
		}
		for ; i < len(n.variables); i++ {
			if j := n.variables[i].tag.Boundary(s); j > 0 {
				params = append(params, s[:j])
				s = s[j:]
				n = n.variables[i]
				i = -1
				continue Loop
			}
		}
		if n.above == nil {
			break
		}
		if x = n.back; x != nil {
			for {
				s = path[len(path)-len(s)-len(x.prefix):]
				x = x.back
				if x == nil {
					break
				} else if x.below != nil {
					n = x.below
					i = 0
					continue Loop
				}
			}
		} else {
			i = len(params) - 1
			s = path[len(path)-len(s)-len(params[i]):]
			params = params[:i]
		}
		i = n.index
		n = n.above
	}
	return nil, false
}
<|endoftext|>


<commit_before>package libclc

import (
  "text/template"
  "bufio"
  "path"
)

type UnitConfig struct {
  Units []*Unit
}

type Unit struct {
  Name string
  Image string
  Command string
  Type string
  Filename string
  Restart string
  Envs []string
  Ports []string
  Xfleet []string
}

func WriteUnits(units *UnitConfig, t *template.Template, path string) (error) {
  for _, service := range units.Units {
    err := WriteUnit(service, t, path)
    if err != nil {
      return err
    }
  }
  return nil
}

func WriteUnit(unit *Unit, t *template.Template, p string) (error) {
  fileName := unitFileName(unit)
  var err error

  if t == nil {
    t, err = GetTemplate("Service Template", "service.template")
  }
  err = WriteTemplatedFile(unit, t, path.Join(p, fileName))
  return err
}

func MakeUnit(service *Unit, t *template.Template, w *bufio.Writer) (error) {
  return t.Execute(w, service)
}

func unitFileName(service *Unit) string {
  switch service.Type {
  case "single":
    service.Filename = (service.Name + ".service")
  case "multi":
    service.Filename = (service.Name + "@.service")
  }

  return service.Filename
}
<commit_msg>Clean up unit template handling.<commit_after>package libclc

import (
  "text/template"
  "bufio"
  "path"
)

type UnitConfig struct {
  Units []*Unit
}

type Unit struct {
  Name string
  Image string
  Command string
  Type string
  Filename string
  Restart string
  Envs []string
  Ports []string
  Xfleet []string
}

func WriteUnits(units *UnitConfig, t *template.Template, path string) (error) {
  for _, service := range units.Units {
    err := WriteUnit(service, t, path)
    if err != nil {
      return err
    }
  }
  return nil
}

func WriteUnit(unit *Unit, t *template.Template, p string) (error) {
  fileName := unitFileName(unit)
  var err error

  t, err = unitTemplate(t)
  if err != nil {
    return err
  }
  err = WriteTemplatedFile(unit, t, path.Join(p, fileName))
  return err
}

func MakeUnit(service *Unit, t *template.Template, w *bufio.Writer) (error) {
  t, err := unitTemplate(t)
  if err != nil {
    return err
  }
  return t.Execute(w, service)
}

func unitTemplate(t *template.Template) (*template.Template, error) {
  if t == nil {
    return GetTemplate("Service Template", "service.template")
  }
  return t, nil
}

func unitFileName(service *Unit) string {
  switch service.Type {
  case "single":
    service.Filename = (service.Name + ".service")
  case "multi":
    service.Filename = (service.Name + "@.service")
  }

  return service.Filename
}
<|endoftext|>


<commit_before>package kala

import (
	"math/big"
	"net"
)

func MacAddressToWorkerId(mac string) (int64, error) {
	hw, err := net.ParseMAC(mac)
	if err != nil {
		return 0, err
	}

	workerId := new(big.Int).SetBytes([]byte(hw)).Int64()

	return workerId, nil
}
<commit_msg>Return worker id as uint when converting from mac address<commit_after>package kala

import (
	"math/big"
	"net"
)

func MacAddressToWorkerId(mac string) (uint64, error) {
	hw, err := net.ParseMAC(mac)
	if err != nil {
		return 0, err
	}

	workerId := new(big.Int).SetBytes([]byte(hw)).Uint64()

	return workerId, nil
}
<|endoftext|>


<commit_before>package bingo

import (
	"encoding/json"
	"net/http"
	"time"

	"github.com/fatih/color"
	"github.com/hifx/banner"
	"github.com/hifx/bingo/infra/log"
	"github.com/hifx/graceful"
	"goji.io/pat"
	"golang.org/x/net/context"
)

//PrintName prints the app name
func PrintName(str string) {
	color.New(color.FgYellow).Add(color.Bold).Println(banner.PrintS(str))
}

// PrintBanner prints the banner
func PrintBanner(a ...interface{}) {
	hd := color.New(color.FgGreen).Add(color.Bold)
	hd.Println("----------------------------------")
	hd.Println(a...)
	hd.Println("----------------------------------")
}

// PrintError prints the error
func PrintError(a ...interface{}) {
	hd := color.New(color.FgRed).Add(color.Bold)
	hd.Println("----------------------------------")
	hd.Println(a...)
	hd.Println("----------------------------------")
}

//Run gracefully starts the http server
func Run(addr string, timeout time.Duration, h http.Handler) {
	http.Handle("/", h)
	graceful.Run(addr, timeout, http.DefaultServeMux)
}

//BoundParam returns the bound parameter with the given name. Wraps around goji's pat.Param
func BoundParam(ctx context.Context, name string) string {
	return pat.Param(ctx, name)
}

// JSONW writes JSON response to the given writer
func JSONW(w http.ResponseWriter, status int, l log.Logger, data interface{}) {
	d, err := json.MarshalIndent(data, "", "  ")
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)

	_, err = w.Write(d)
	if nil != err {
		l.Error("web.ioerror", err.Error())
	}
	_, err = w.Write([]byte("\n"))
	if nil != err {
		l.Error("web.ioerror", err.Error())
	}
}
<commit_msg>feature: added Close & ReadBody utilities.<commit_after>package bingo

import (
	"encoding/json"
	"io"
	"net/http"
	"reflect"
	"time"

	"github.com/fatih/color"
	"github.com/hifx/banner"
	"github.com/hifx/bingo/infra/log"
	"github.com/hifx/errgo"
	"github.com/hifx/graceful"
	"goji.io/pat"
	"golang.org/x/net/context"
)

//PrintName prints the app name
func PrintName(str string) {
	color.New(color.FgYellow).Add(color.Bold).Println(banner.PrintS(str))
}

// PrintBanner prints the banner
func PrintBanner(a ...interface{}) {
	hd := color.New(color.FgGreen).Add(color.Bold)
	hd.Println("----------------------------------")
	hd.Println(a...)
	hd.Println("----------------------------------")
}

// PrintError prints the error
func PrintError(a ...interface{}) {
	hd := color.New(color.FgRed).Add(color.Bold)
	hd.Println("----------------------------------")
	hd.Println(a...)
	hd.Println("----------------------------------")
}

//Run gracefully starts the http server
func Run(addr string, timeout time.Duration, h http.Handler) {
	http.Handle("/", h)
	graceful.Run(addr, timeout, http.DefaultServeMux)
}

//BoundParam returns the bound parameter with the given name. Wraps around goji's pat.Param
func BoundParam(ctx context.Context, name string) string {
	return pat.Param(ctx, name)
}

// JSONW writes JSON response to the given writer
func JSONW(w http.ResponseWriter, status int, l log.Logger, data interface{}) {
	d, err := json.MarshalIndent(data, "", "  ")
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)

	_, err = w.Write(d)
	if nil != err {
		l.Error("web.ioerror", err.Error())
	}
	_, err = w.Write([]byte("\n"))
	if nil != err {
		l.Error("web.ioerror", err.Error())
	}
}

//Close an io.Closer object by handling it's error.
// Example:
// 		h, err := app.Init(env)
// 		defer utils.Close(h, conf.Config.Log())
func Close(closer io.Closer, log log.Logger) {
	if err := closer.Close(); err != nil {
		log.Crit("Failed to Close Object: %#v\n Error: %s ", err.Error())
	}
}

// ReadBody decodes request.Body into the destination.
//  Warning: des should be a pointer
func ReadBody(request *http.Request, des interface{}, msg string) error {
	if kind := reflect.TypeOf(des).Kind(); kind != reflect.Ptr {
		return errgo.Errorf("des should be a pointer: but got %#v", kind)
	}
	if err := json.NewDecoder(request.Body).Decode(des); err != nil {
		return errgo.Errorf("Failed to decode request body,Error: %s", err.Error())
	}
	return nil
}
<|endoftext|>


<commit_before>package d3dmath

import (
	"fmt"
	"math"
)

type Vec3 [3]float32

func (v Vec3) Add(w Vec3) Vec3 {
	return Vec3{v[0] + w[0], v[1] + w[1], v[2] + w[2]}
}

func (v Vec3) Sub(w Vec3) Vec3 {
	return Vec3{v[0] - w[0], v[1] - w[1], v[2] - w[2]}
}

func (v Vec3) Dot(w Vec3) float32 {
	return v[0]*w[0] + v[1]*w[1] + v[2]*w[2]
}

func (v Vec3) Cross(w Vec3) Vec3 {
	return Vec3{
		v[1]*w[2] - v[2]*w[1],
		v[2]*w[0] - v[0]*w[2],
		v[0]*w[1] - v[1]*w[0],
	}
}

func (v Vec3) MulScalar(s float32) Vec3 {
	return Vec3{v[0] * s, v[1] * s, v[2] * s}
}

//          | m0 m1 m2
//          | m3 m4 m5
//    *     | m6 m7 m8
// ---------+---------
// v0 v1 v2 | ...
func (v Vec3) MulMat(m Mat3) Vec3 {
	return Vec3{
		v[0]*m[0] + v[1]*m[3] + v[2]*m[6],
		v[0]*m[1] + v[1]*m[4] + v[2]*m[7],
		v[0]*m[2] + v[1]*m[5] + v[2]*m[8],
	}
}

func (v Vec3) SquareNorm() float32 {
	return v[0]*v[0] + v[1]*v[1] + v[2]*v[2]
}

func (v Vec3) Norm() float32 {
	return float32(math.Sqrt(float64(v.SquareNorm())))
}

func (v Vec3) Normalized() Vec3 {
	f := 1.0 / v.Norm()
	return Vec3{f * v[0], f * v[1], f * v[2]}
}

func (v Vec3) Homgeneous() Vec4 {
	return Vec4{v[0], v[1], v[2], 1}
}

func (v Vec3) String() string {
	return fmt.Sprintf("(%.2f %.2f %.2f)", v[0], v[1], v[2])
}
<commit_msg>Add AddVec3 to sum arbitraty number of Vec3s<commit_after>package d3dmath

import (
	"fmt"
	"math"
)

type Vec3 [3]float32

func (v Vec3) Add(w Vec3) Vec3 {
	return Vec3{v[0] + w[0], v[1] + w[1], v[2] + w[2]}
}

func (v Vec3) Sub(w Vec3) Vec3 {
	return Vec3{v[0] - w[0], v[1] - w[1], v[2] - w[2]}
}

func (v Vec3) Dot(w Vec3) float32 {
	return v[0]*w[0] + v[1]*w[1] + v[2]*w[2]
}

func (v Vec3) Cross(w Vec3) Vec3 {
	return Vec3{
		v[1]*w[2] - v[2]*w[1],
		v[2]*w[0] - v[0]*w[2],
		v[0]*w[1] - v[1]*w[0],
	}
}

func (v Vec3) MulScalar(s float32) Vec3 {
	return Vec3{v[0] * s, v[1] * s, v[2] * s}
}

//          | m0 m1 m2
//          | m3 m4 m5
//    *     | m6 m7 m8
// ---------+---------
// v0 v1 v2 | ...
func (v Vec3) MulMat(m Mat3) Vec3 {
	return Vec3{
		v[0]*m[0] + v[1]*m[3] + v[2]*m[6],
		v[0]*m[1] + v[1]*m[4] + v[2]*m[7],
		v[0]*m[2] + v[1]*m[5] + v[2]*m[8],
	}
}

func (v Vec3) SquareNorm() float32 {
	return v[0]*v[0] + v[1]*v[1] + v[2]*v[2]
}

func (v Vec3) Norm() float32 {
	return float32(math.Sqrt(float64(v.SquareNorm())))
}

func (v Vec3) Normalized() Vec3 {
	f := 1.0 / v.Norm()
	return Vec3{f * v[0], f * v[1], f * v[2]}
}

func (v Vec3) Homgeneous() Vec4 {
	return Vec4{v[0], v[1], v[2], 1}
}

func (v Vec3) String() string {
	return fmt.Sprintf("(%.2f %.2f %.2f)", v[0], v[1], v[2])
}

func AddVec3(v0 Vec3, v ...Vec3) Vec3 {
	if len(v) == 0 {
		return v0
	}
	return v0.Add(AddVec3(v[0], v[1:]...))
}<|endoftext|>