<commit_before>package slinga

import (
	"bufio"
	"github.com/golang/glog"
	"os/exec"
	"strings"
)

// HelmCodeExecutor is an executor that uses Helm for deployment of apps on kubernetes
type HelmCodeExecutor struct {
	Code *Code
}

func HelmName(str string) string {
	r := strings.NewReplacer("#", "-", "_", "-")
	return r.Replace(str)
}

// Install for HelmCodeExecutor runs "helm install" for the corresponding helm chart
func (executor HelmCodeExecutor) Install(key string, labels LabelSet, dependencies map[string]string) error {
	uid := HelmName(key)

	content, err := executor.Code.processCodeContent(labels, dependencies)
	if err != nil {
		return err
	}

	chartName := content["chart"]["name"]

	// TODO(slukjanov): Replace with marshalling all params to temp file (YAML)
	setValues := ""
	if params, ok := content["params"]; ok {
		for key, value := range params {
			setValues += key + "=" + value + ","
		}
	}

	helmArgs := []string{"install", "--name", uid}
	if len(setValues) > 0 {
		helmArgs = append(helmArgs, "--set", setValues)
	}
	if version, ok := content["chart"]["version"]; ok {
		helmArgs = append(helmArgs, "--version", version)
	}
	if namespace, ok := content["chart"]["namespace"]; ok {
		helmArgs = append(helmArgs, "--namespace", namespace)
	} else {
		helmArgs = append(helmArgs, "--namespace", "aptomi")
	}
	helmArgs = append(helmArgs, chartName)

	return runHelmCmd(helmArgs...)
}

// Update for HelmCodeExecutor runs "helm update" for the corresponding helm chart
func (executor HelmCodeExecutor) Update(key string, labels LabelSet) error {
	// TODO: implement update method
	return nil
}

// Destroy for HelmCodeExecutor runs "helm delete" for the corresponding helm chart
func (executor HelmCodeExecutor) Destroy(key string) error {
	uid := helmName(key)

	return runHelmCmd("delete", "--purge", uid)
}

func runHelmCmd(helmArgs ...string) error {
	return runCmd("helm", helmArgs...)
}

func runCmd(cmdName string, cmdArgs ...string) error {
	cmd := exec.Command(cmdName, cmdArgs...)
	glog.Infof("Running command '%s' with args: %s", cmdName, cmdArgs)

	cmdStdoutReader, err := cmd.StdoutPipe()
	if err != nil {
		glog.Errorf("Failed running command '%s' (with args: %s): %s", cmdName, cmdArgs, err)
		return err
	}

	cmdStdoutScanner := bufio.NewScanner(cmdStdoutReader)
	go func() {
		for cmdStdoutScanner.Scan() {
			glog.Infof("%s out | %s\n", cmdName, cmdStdoutScanner.Text())
		}
	}()

	cmdStderrReader, err := cmd.StderrPipe()
	if err != nil {
		glog.Errorf("Failed running command '%s' (with args: %s): %s", cmdName, cmdArgs, err)
		return err
	}

	cmdStderrScanner := bufio.NewScanner(cmdStderrReader)
	go func() {
		for cmdStderrScanner.Scan() {
			glog.Infof("%s err | %s\n", cmdName, cmdStderrScanner.Text())
		}
	}()

	err = cmd.Start()
	if err != nil {
		glog.Errorf("Failed running command '%s' (with args: %s): %s", cmdName, cmdArgs, err)
		return err
	}

	err = cmd.Wait()
	if err != nil {
		glog.Errorf("Failed running command '%s' (with args: %s): %s", cmdName, cmdArgs, err)
		return err
	}

	return nil
}
<commit_msg>Fix typo<commit_after>package slinga

import (
	"bufio"
	"github.com/golang/glog"
	"os/exec"
	"strings"
)

// HelmCodeExecutor is an executor that uses Helm for deployment of apps on kubernetes
type HelmCodeExecutor struct {
	Code *Code
}

func HelmName(str string) string {
	r := strings.NewReplacer("#", "-", "_", "-")
	return r.Replace(str)
}

// Install for HelmCodeExecutor runs "helm install" for the corresponding helm chart
func (executor HelmCodeExecutor) Install(key string, labels LabelSet, dependencies map[string]string) error {
	uid := HelmName(key)

	content, err := executor.Code.processCodeContent(labels, dependencies)
	if err != nil {
		return err
	}

	chartName := content["chart"]["name"]

	// TODO(slukjanov): Replace with marshalling all params to temp file (YAML)
	setValues := ""
	if params, ok := content["params"]; ok {
		for key, value := range params {
			setValues += key + "=" + value + ","
		}
	}

	helmArgs := []string{"install", "--name", uid}
	if len(setValues) > 0 {
		helmArgs = append(helmArgs, "--set", setValues)
	}
	if version, ok := content["chart"]["version"]; ok {
		helmArgs = append(helmArgs, "--version", version)
	}
	if namespace, ok := content["chart"]["namespace"]; ok {
		helmArgs = append(helmArgs, "--namespace", namespace)
	} else {
		helmArgs = append(helmArgs, "--namespace", "aptomi")
	}
	helmArgs = append(helmArgs, chartName)

	return runHelmCmd(helmArgs...)
}

// Update for HelmCodeExecutor runs "helm update" for the corresponding helm chart
func (executor HelmCodeExecutor) Update(key string, labels LabelSet) error {
	// TODO: implement update method
	return nil
}

// Destroy for HelmCodeExecutor runs "helm delete" for the corresponding helm chart
func (executor HelmCodeExecutor) Destroy(key string) error {
	uid := HelmName(key)

	return runHelmCmd("delete", "--purge", uid)
}

func runHelmCmd(helmArgs ...string) error {
	return runCmd("helm", helmArgs...)
}

func runCmd(cmdName string, cmdArgs ...string) error {
	cmd := exec.Command(cmdName, cmdArgs...)
	glog.Infof("Running command '%s' with args: %s", cmdName, cmdArgs)

	cmdStdoutReader, err := cmd.StdoutPipe()
	if err != nil {
		glog.Errorf("Failed running command '%s' (with args: %s): %s", cmdName, cmdArgs, err)
		return err
	}

	cmdStdoutScanner := bufio.NewScanner(cmdStdoutReader)
	go func() {
		for cmdStdoutScanner.Scan() {
			glog.Infof("%s out | %s\n", cmdName, cmdStdoutScanner.Text())
		}
	}()

	cmdStderrReader, err := cmd.StderrPipe()
	if err != nil {
		glog.Errorf("Failed running command '%s' (with args: %s): %s", cmdName, cmdArgs, err)
		return err
	}

	cmdStderrScanner := bufio.NewScanner(cmdStderrReader)
	go func() {
		for cmdStderrScanner.Scan() {
			glog.Infof("%s err | %s\n", cmdName, cmdStderrScanner.Text())
		}
	}()

	err = cmd.Start()
	if err != nil {
		glog.Errorf("Failed running command '%s' (with args: %s): %s", cmdName, cmdArgs, err)
		return err
	}

	err = cmd.Wait()
	if err != nil {
		glog.Errorf("Failed running command '%s' (with args: %s): %s", cmdName, cmdArgs, err)
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package html

import (
	"errors"
	"math"
	"net/http"

	"github.com/chrisolsen/ae/auth"
)

type page map[string]interface{}

// NewPage creates a new page
func NewPage() page {
	return page(make(map[string]interface{}))
}

// NewPageWithCSRFToken create a page with an initialized CSRF token
func NewPageWithCSRFToken(r *http.Request) page {
	p := NewPage()
	token := auth.NewCSRFToken(r)
	p["CSRFToken"] = token
	return p
}

// SetError sets any error that needs to be shown
func (p page) SetError(err interface{}) {
	switch err.(type) {
	case string:
		p["Error"] = errors.New(err.(string))
	case error:
		p["Error"] = err.(error)
	default:
		p["Error"] = nil
	}
}

// SetUser sets the current user
func (p page) SetUser(user interface{}) {
	p["CurrentUser"] = user
}

// Set sets the key and value
func (p page) Set(key string, val interface{}) {
	p[key] = val
}

// SetPageOffsets sets an array within the page to allow it to be iterated through
// in the template to create pagination links.
//  // .go file
// 	p := html.NewPage()
// 	items := []string {"foo", "bar", "bits", ...}
// 	p.SetPageOffsets(len(items), 10)
//
//  // template
//  {{range $index, $offset := .Offsets}}
//      {{add $index 1}}
//  {{end}}
func (p page) SetPageOffsets(itemCount, pageSize int) {
	offsetCount := int(math.Ceil(float64(itemCount) / float64(pageSize)))
	offsets := make([]int, offsetCount)
	for i := 0; i < offsetCount; i++ {
		offsets[i] = i * 10
	}
	p.Set("Offsets", offsets)
}
<commit_msg>make the *page* type public<commit_after>package html

import (
	"errors"
	"math"
	"net/http"

	"github.com/chrisolsen/ae/auth"
)

type Page map[string]interface{}

// NewPage creates a new page
func NewPage() Page {
	return Page(make(map[string]interface{}))
}

// NewPageWithCSRFToken create a page with an initialized CSRF token
func NewPageWithCSRFToken(r *http.Request) Page {
	p := NewPage()
	token := auth.NewCSRFToken(r)
	p["CSRFToken"] = token
	return p
}

// SetError sets any error that needs to be shown
func (p Page) SetError(err interface{}) {
	switch err.(type) {
	case string:
		p["Error"] = errors.New(err.(string))
	case error:
		p["Error"] = err.(error)
	default:
		p["Error"] = nil
	}
}

// SetUser sets the current user
func (p Page) SetUser(user interface{}) {
	p["CurrentUser"] = user
}

// Set sets the key and value
func (p Page) Set(key string, val interface{}) {
	p[key] = val
}

// SetPageOffsets sets an array within the page to allow it to be iterated through
// in the template to create pagination links.
//  // .go file
// 	p := html.NewPage()
// 	items := []string {"foo", "bar", "bits", ...}
// 	p.SetPageOffsets(len(items), 10)
//
//  // template
//  {{range $index, $offset := .Offsets}}
//      {{add $index 1}}
//  {{end}}
func (p Page) SetPageOffsets(itemCount, pageSize int) {
	offsetCount := int(math.Ceil(float64(itemCount) / float64(pageSize)))
	offsets := make([]int, offsetCount)
	for i := 0; i < offsetCount; i++ {
		offsets[i] = i * 10
	}
	p.Set("Offsets", offsets)
}
<|endoftext|>


<commit_before>package mysql

import (
	"database/sql"
	"errors"
	"fmt"
	"net/url"
	"reflect"
	"strconv"
	"strings"

	"github.com/VividCortex/mysqlerr"
	"github.com/grafana/grafana/pkg/setting"

	"github.com/go-sql-driver/mysql"
	"github.com/go-xorm/core"
	"github.com/grafana/grafana/pkg/infra/log"
	"github.com/grafana/grafana/pkg/models"
	"github.com/grafana/grafana/pkg/tsdb"
	"github.com/grafana/grafana/pkg/tsdb/sqleng"
)

func init() {
	tsdb.RegisterTsdbQueryEndpoint("mysql", newMysqlQueryEndpoint)
}

func characterEscape(s string, escapeChar string) string {
	return strings.Replace(s, escapeChar, url.QueryEscape(escapeChar), -1)
}

func newMysqlQueryEndpoint(datasource *models.DataSource) (tsdb.TsdbQueryEndpoint, error) {
	logger := log.New("tsdb.mysql")

	protocol := "tcp"
	if strings.HasPrefix(datasource.Url, "/") {
		protocol = "unix"
	}

	cnnstr := fmt.Sprintf("%s:%s@%s(%s)/%s?collation=utf8mb4_unicode_ci&parseTime=true&loc=UTC&allowNativePasswords=true",
		characterEscape(datasource.User, ":"),
		characterEscape(datasource.DecryptedPassword(), "@"),
		protocol,
		characterEscape(datasource.Url, ")"),
		characterEscape(datasource.Database, "?"),
	)

	tlsConfig, err := datasource.GetTLSConfig()
	if err != nil {
		return nil, err
	}

	if tlsConfig.RootCAs != nil || len(tlsConfig.Certificates) > 0 {
		tlsConfigString := fmt.Sprintf("ds%d", datasource.Id)
		if err := mysql.RegisterTLSConfig(tlsConfigString, tlsConfig); err != nil {
			return nil, err
		}
		cnnstr += "&tls=" + tlsConfigString
	}

	if setting.Env == setting.DEV {
		logger.Debug("getEngine", "connection", cnnstr)
	}

	config := sqleng.SqlQueryEndpointConfiguration{
		DriverName:        "mysql",
		ConnectionString:  cnnstr,
		Datasource:        datasource,
		TimeColumnNames:   []string{"time", "time_sec"},
		MetricColumnTypes: []string{"CHAR", "VARCHAR", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT"},
	}

	rowTransformer := mysqlQueryResultTransformer{
		log: logger,
	}

	return sqleng.NewSqlQueryEndpoint(&config, &rowTransformer, newMysqlMacroEngine(logger), logger)
}

type mysqlQueryResultTransformer struct {
	log log.Logger
}

func (t *mysqlQueryResultTransformer) TransformQueryResult(columnTypes []*sql.ColumnType, rows *core.Rows) (tsdb.RowValues, error) {
	values := make([]interface{}, len(columnTypes))

	for i := range values {
		scanType := columnTypes[i].ScanType()
		values[i] = reflect.New(scanType).Interface()

		if columnTypes[i].DatabaseTypeName() == "BIT" {
			values[i] = new([]byte)
		}
	}

	if err := rows.Scan(values...); err != nil {
		return nil, err
	}

	for i := 0; i < len(columnTypes); i++ {
		typeName := reflect.ValueOf(values[i]).Type().String()

		switch typeName {
		case "*sql.RawBytes":
			values[i] = string(*values[i].(*sql.RawBytes))
		case "*mysql.NullTime":
			sqlTime := (*values[i].(*mysql.NullTime))
			if sqlTime.Valid {
				values[i] = sqlTime.Time
			} else {
				values[i] = nil
			}
		case "*sql.NullInt64":
			nullInt64 := (*values[i].(*sql.NullInt64))
			if nullInt64.Valid {
				values[i] = nullInt64.Int64
			} else {
				values[i] = nil
			}
		case "*sql.NullFloat64":
			nullFloat64 := (*values[i].(*sql.NullFloat64))
			if nullFloat64.Valid {
				values[i] = nullFloat64.Float64
			} else {
				values[i] = nil
			}
		}

		if columnTypes[i].DatabaseTypeName() == "DECIMAL" {
			f, err := strconv.ParseFloat(values[i].(string), 64)

			if err == nil {
				values[i] = f
			} else {
				values[i] = nil
			}
		}
	}

	return values, nil
}

func (t *mysqlQueryResultTransformer) TransformQueryError(err error) error {
	if driverErr, ok := err.(*mysql.MySQLError); ok {
		if driverErr.Number != mysqlerr.ER_PARSE_ERROR && driverErr.Number != mysqlerr.ER_BAD_FIELD_ERROR && driverErr.Number != mysqlerr.ER_NO_SUCH_TABLE {
			t.log.Error("query error", "err", err)
			return errQueryFailed
		}
	}

	return err
}

var errQueryFailed = errors.New("Query failed. Please inspect Grafana server log for details")
<commit_msg>MySql: Fix password regression in MySQL datasource (#20376)<commit_after>package mysql

import (
	"database/sql"
	"errors"
	"fmt"
	"net/url"
	"reflect"
	"strconv"
	"strings"

	"github.com/VividCortex/mysqlerr"
	"github.com/grafana/grafana/pkg/setting"

	"github.com/go-sql-driver/mysql"
	"github.com/go-xorm/core"
	"github.com/grafana/grafana/pkg/infra/log"
	"github.com/grafana/grafana/pkg/models"
	"github.com/grafana/grafana/pkg/tsdb"
	"github.com/grafana/grafana/pkg/tsdb/sqleng"
)

func init() {
	tsdb.RegisterTsdbQueryEndpoint("mysql", newMysqlQueryEndpoint)
}

func characterEscape(s string, escapeChar string) string {
	return strings.Replace(s, escapeChar, url.QueryEscape(escapeChar), -1)
}

func newMysqlQueryEndpoint(datasource *models.DataSource) (tsdb.TsdbQueryEndpoint, error) {
	logger := log.New("tsdb.mysql")

	protocol := "tcp"
	if strings.HasPrefix(datasource.Url, "/") {
		protocol = "unix"
	}

	cnnstr := fmt.Sprintf("%s:%s@%s(%s)/%s?collation=utf8mb4_unicode_ci&parseTime=true&loc=UTC&allowNativePasswords=true",
		characterEscape(datasource.User, ":"),
		datasource.DecryptedPassword(),
		protocol,
		characterEscape(datasource.Url, ")"),
		characterEscape(datasource.Database, "?"),
	)

	tlsConfig, err := datasource.GetTLSConfig()
	if err != nil {
		return nil, err
	}

	if tlsConfig.RootCAs != nil || len(tlsConfig.Certificates) > 0 {
		tlsConfigString := fmt.Sprintf("ds%d", datasource.Id)
		if err := mysql.RegisterTLSConfig(tlsConfigString, tlsConfig); err != nil {
			return nil, err
		}
		cnnstr += "&tls=" + tlsConfigString
	}

	if setting.Env == setting.DEV {
		logger.Debug("getEngine", "connection", cnnstr)
	}

	config := sqleng.SqlQueryEndpointConfiguration{
		DriverName:        "mysql",
		ConnectionString:  cnnstr,
		Datasource:        datasource,
		TimeColumnNames:   []string{"time", "time_sec"},
		MetricColumnTypes: []string{"CHAR", "VARCHAR", "TINYTEXT", "TEXT", "MEDIUMTEXT", "LONGTEXT"},
	}

	rowTransformer := mysqlQueryResultTransformer{
		log: logger,
	}

	return sqleng.NewSqlQueryEndpoint(&config, &rowTransformer, newMysqlMacroEngine(logger), logger)
}

type mysqlQueryResultTransformer struct {
	log log.Logger
}

func (t *mysqlQueryResultTransformer) TransformQueryResult(columnTypes []*sql.ColumnType, rows *core.Rows) (tsdb.RowValues, error) {
	values := make([]interface{}, len(columnTypes))

	for i := range values {
		scanType := columnTypes[i].ScanType()
		values[i] = reflect.New(scanType).Interface()

		if columnTypes[i].DatabaseTypeName() == "BIT" {
			values[i] = new([]byte)
		}
	}

	if err := rows.Scan(values...); err != nil {
		return nil, err
	}

	for i := 0; i < len(columnTypes); i++ {
		typeName := reflect.ValueOf(values[i]).Type().String()

		switch typeName {
		case "*sql.RawBytes":
			values[i] = string(*values[i].(*sql.RawBytes))
		case "*mysql.NullTime":
			sqlTime := (*values[i].(*mysql.NullTime))
			if sqlTime.Valid {
				values[i] = sqlTime.Time
			} else {
				values[i] = nil
			}
		case "*sql.NullInt64":
			nullInt64 := (*values[i].(*sql.NullInt64))
			if nullInt64.Valid {
				values[i] = nullInt64.Int64
			} else {
				values[i] = nil
			}
		case "*sql.NullFloat64":
			nullFloat64 := (*values[i].(*sql.NullFloat64))
			if nullFloat64.Valid {
				values[i] = nullFloat64.Float64
			} else {
				values[i] = nil
			}
		}

		if columnTypes[i].DatabaseTypeName() == "DECIMAL" {
			f, err := strconv.ParseFloat(values[i].(string), 64)

			if err == nil {
				values[i] = f
			} else {
				values[i] = nil
			}
		}
	}

	return values, nil
}

func (t *mysqlQueryResultTransformer) TransformQueryError(err error) error {
	if driverErr, ok := err.(*mysql.MySQLError); ok {
		if driverErr.Number != mysqlerr.ER_PARSE_ERROR && driverErr.Number != mysqlerr.ER_BAD_FIELD_ERROR && driverErr.Number != mysqlerr.ER_NO_SUCH_TABLE {
			t.log.Error("query error", "err", err)
			return errQueryFailed
		}
	}

	return err
}

var errQueryFailed = errors.New("Query failed. Please inspect Grafana server log for details")
<|endoftext|>


<commit_before>/*
Copyright 2015 The Kubernetes Authors.

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

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

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

package util

import (
	"os"
	"path"

	"github.com/golang/glog"
)

const readyFileName = "ready"

// IsReady checks for the existence of a regular file
// called 'ready' in the given directory and returns
// true if that file exists.
func IsReady(dir string) bool {
	readyFile := path.Join(dir, readyFileName)
	s, err := os.Stat(readyFile)
	if err != nil {
		return false
	}

	if !s.Mode().IsRegular() {
		glog.Errorf("ready-file is not a file: %s", readyFile)
		return false
	}

	return true
}

// SetReady creates a file called 'ready' in the given
// directory.  It logs an error if the file cannot be
// created.
func SetReady(dir string) {
	if err := os.MkdirAll(dir, 0750); err != nil && !os.IsExist(err) {
		glog.Errorf("Can't mkdir %s: %v", dir, err)
		return
	}

	readyFile := path.Join(dir, readyFileName)
	file, err := os.Create(readyFile)
	if err != nil {
		glog.Errorf("Can't touch %s: %v", readyFile, err)
		return
	}
	file.Close()
}
<commit_msg>Prevent device unmount from deleting dir on err<commit_after>/*
Copyright 2015 The Kubernetes Authors.

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

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

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

package util

import (
	"fmt"
	"os"
	"path"

	"github.com/golang/glog"
	"k8s.io/kubernetes/pkg/util/mount"
)

const readyFileName = "ready"

// IsReady checks for the existence of a regular file
// called 'ready' in the given directory and returns
// true if that file exists.
func IsReady(dir string) bool {
	readyFile := path.Join(dir, readyFileName)
	s, err := os.Stat(readyFile)
	if err != nil {
		return false
	}

	if !s.Mode().IsRegular() {
		glog.Errorf("ready-file is not a file: %s", readyFile)
		return false
	}

	return true
}

// SetReady creates a file called 'ready' in the given
// directory.  It logs an error if the file cannot be
// created.
func SetReady(dir string) {
	if err := os.MkdirAll(dir, 0750); err != nil && !os.IsExist(err) {
		glog.Errorf("Can't mkdir %s: %v", dir, err)
		return
	}

	readyFile := path.Join(dir, readyFileName)
	file, err := os.Create(readyFile)
	if err != nil {
		glog.Errorf("Can't touch %s: %v", readyFile, err)
		return
	}
	file.Close()
}

// UnmountPath is a common unmount routine that unmounts the given path and
// deletes the remaining directory if successful.
func UnmountPath(mountPath string, mounter mount.Interface) error {
	if pathExists, pathErr := PathExists(mountPath); pathErr != nil {
		return fmt.Errorf("Error checking if path exists: %v", pathErr)
	} else if !pathExists {
		glog.Warningf("Warning: Unmount skipped because path does not exist: %v", mountPath)
		return nil
	}

	err := mounter.Unmount(mountPath)
	if err == nil {
		// Only delete directory on successful unmount
		glog.V(5).Infof("Unmounted %q. Deleting path.", mountPath)
		return os.Remove(mountPath)
	}

	return err
}

// PathExists returns true if the specified path exists.
func PathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	} else if os.IsNotExist(err) {
		return false, nil
	} else {
		return false, err
	}
}
<|endoftext|>


<commit_before>package main

import (
    "log"
    "github.com/trendrr/cheshire-golang/cheshire"
)

func main() {

    bootstrap := cheshire.NewBootstrapFile("example_config.yaml")
    log.Println("HERE:1")
    //a ping controller api controller.
    pinger := func(request *cheshire.Request,conn cheshire.Writer) {
        // log.Printf("PING! %s", request.Strest.Params)
        response := cheshire.NewResponse(request)
        response.Put("data", "PONG")
        // log.Printf("Sending REsponse: %s", response.TxnId())
        conn.Write(response)
    }
    //now register the api call
    cheshire.RegisterApi("/ping", "GET", pinger)
    log.Println("HERE:1")

    //an example html page
    four04 := func(request *cheshire.Request, conn *cheshire.HtmlWriter) {
        context := make(map[string]interface{})
        context["message"] = "this is a 404 page"
        conn.Render("/404.html", context)
    }
    cheshire.RegisterHtml("/404", "GET", four04)

    //an example redirect page
    redirect := func(request *cheshire.Request, conn *cheshire.HtmlWriter) {
        conn.Redirect("/ping")
    }
    cheshire.RegisterHtml("/redirect", "GET", redirect)

    log.Println("Starting")
    //starts listening on all configured interfaces
    bootstrap.Start()
}
<commit_msg>update example<commit_after>package main

import (
    "log"
    "github.com/trendrr/cheshire-golang/cheshire"
)

func main() {

    bootstrap := cheshire.NewBootstrapFile("example_config.yaml")
    log.Println("HERE:1")
    //a ping controller api controller.
    pinger := func(txn *cheshire.Txn) {
        // log.Printf("PING! %s", request.Strest.Params)
        response := cheshire.NewResponse(txn)
        response.Put("data", "PONG")
        // log.Printf("Sending REsponse: %s", response.TxnId())
        txn.Write(response)
    }
    //now register the api call
    cheshire.RegisterApi("/ping", "GET", pinger)
    log.Println("HERE:1")

    //an example html page
    four04 := func(txn *cheshire.Txn) {
        context := make(map[string]interface{})
        context["message"] = "this is a 404 page"
        cheshire.Render(txn, "/404.html", context)
    }
    cheshire.RegisterHtml("/404", "GET", four04)

    //an example redirect page
    redirect := func(txn *cheshire.Txn) {
        cheshire.Redirect(txn, "/ping")
    }
    cheshire.RegisterHtml("/redirect", "GET", redirect)

    log.Println("Starting")
    //starts listening on all configured interfaces
    bootstrap.Start()
}
<|endoftext|>


<commit_before>package multiconfig

import (
	"fmt"
	"os"
)

func ExampleDefaultLoader() {
	// Our struct which is used for configuration
	type ServerConfig struct {
		Name    string `default:"gopher"`
		Port    int    `default:"6060"`
		Enabled bool
		Users   []string
	}

	// Instantiate a default loader.
	d := NewWithPath("testdata/config.toml")

	s := &ServerConfig{}

	// It first sets the default values for each field with tag values defined
	// with "default", next it reads from config.toml, from environment
	// variables and finally from command line flags. It panic's if loading fails.
	d.MustLoad(s)

	fmt.Println("Host-->", s.Name)
	fmt.Println("Port-->", s.Port)

	// Output:
	// Host--> koding
	// Port--> 6060

}

func ExampleMultiLoader() {
	// Our struct which is used for configuration
	type ServerConfig struct {
		Name     string
		Port     int
		Enabled  bool
		Users    []string
		Postgres Postgres
	}

	os.Setenv("SERVERCONFIG_NAME", "koding")
	os.Setenv("SERVERCONFIG_PORT", "6060")

	// Create a custom multi loader intance based on your needs.
	f := &FlagLoader{}
	e := &EnvironmentLoader{}

	l := MultiLoader(f, e)

	// Load configs into our s variable from the sources above
	s := &ServerConfig{}
	err := l.Load(s)
	if err != nil {
		panic(err)
	}

	fmt.Println("Host-->", s.Name)
	fmt.Println("Port-->", s.Port)

	// Output:
	// Host--> koding
	// Port--> 6060
}

func ExampleEnvironmentLoader() {
	// Our struct which is used for configuration
	type ServerConfig struct {
		Name     string
		Port     int
		Enabled  bool
		Users    []string
		Postgres Postgres
	}

	// Assume those values defined before running the Loader
	os.Setenv("SERVERCONFIG_NAME", "koding")
	os.Setenv("SERVERCONFIG_PORT", "6060")

	// Instantiate loader
	l := &EnvironmentLoader{}

	s := &ServerConfig{}
	err := l.Load(s)
	if err != nil {
		panic(err)
	}

	fmt.Println("Host-->", s.Name)
	fmt.Println("Port-->", s.Port)

	// Output:
	// Host--> koding
	// Port--> 6060
}

func ExampleTOMLLoader() {
	// Our struct which is used for configuration
	type ServerConfig struct {
		Name     string
		Port     int
		Enabled  bool
		Users    []string
		Postgres Postgres
	}

	// Instantiate loader
	l := &TOMLLoader{Path: testTOML}

	s := &ServerConfig{}
	err := l.Load(s)
	if err != nil {
		panic(err)
	}

	fmt.Println("Host-->", s.Name)
	fmt.Println("Users-->", s.Users)

	// Output:
	// Host--> koding
	// Users--> [ankara istanbul]
}

func ExampleJSONLoader() {
	// Our struct which is used for configuration
	type ServerConfig struct {
		Name     string
		Port     int
		Enabled  bool
		Users    []string
		Postgres Postgres
	}

	// Instantiate loader
	l := &JSONLoader{Path: testJSON}

	s := &ServerConfig{}
	err := l.Load(s)
	if err != nil {
		panic(err)
	}

	fmt.Println("Host-->", s.Name)
	fmt.Println("Users-->", s.Users)

	// Output:
	// Host--> koding
	// Users--> [ankara istanbul]
}
<commit_msg>add example tests for YAML file<commit_after>package multiconfig

import (
	"fmt"
	"os"
)

func ExampleDefaultLoader() {
	// Our struct which is used for configuration
	type ServerConfig struct {
		Name    string `default:"gopher"`
		Port    int    `default:"6060"`
		Enabled bool
		Users   []string
	}

	// Instantiate a default loader.
	d := NewWithPath("testdata/config.toml")

	s := &ServerConfig{}

	// It first sets the default values for each field with tag values defined
	// with "default", next it reads from config.toml, from environment
	// variables and finally from command line flags. It panic's if loading fails.
	d.MustLoad(s)

	fmt.Println("Host-->", s.Name)
	fmt.Println("Port-->", s.Port)

	// Output:
	// Host--> koding
	// Port--> 6060

}

func ExampleMultiLoader() {
	// Our struct which is used for configuration
	type ServerConfig struct {
		Name     string
		Port     int
		Enabled  bool
		Users    []string
		Postgres Postgres
	}

	os.Setenv("SERVERCONFIG_NAME", "koding")
	os.Setenv("SERVERCONFIG_PORT", "6060")

	// Create a custom multi loader intance based on your needs.
	f := &FlagLoader{}
	e := &EnvironmentLoader{}

	l := MultiLoader(f, e)

	// Load configs into our s variable from the sources above
	s := &ServerConfig{}
	err := l.Load(s)
	if err != nil {
		panic(err)
	}

	fmt.Println("Host-->", s.Name)
	fmt.Println("Port-->", s.Port)

	// Output:
	// Host--> koding
	// Port--> 6060
}

func ExampleEnvironmentLoader() {
	// Our struct which is used for configuration
	type ServerConfig struct {
		Name     string
		Port     int
		Enabled  bool
		Users    []string
		Postgres Postgres
	}

	// Assume those values defined before running the Loader
	os.Setenv("SERVERCONFIG_NAME", "koding")
	os.Setenv("SERVERCONFIG_PORT", "6060")

	// Instantiate loader
	l := &EnvironmentLoader{}

	s := &ServerConfig{}
	err := l.Load(s)
	if err != nil {
		panic(err)
	}

	fmt.Println("Host-->", s.Name)
	fmt.Println("Port-->", s.Port)

	// Output:
	// Host--> koding
	// Port--> 6060
}

func ExampleTOMLLoader() {
	// Our struct which is used for configuration
	type ServerConfig struct {
		Name     string
		Port     int
		Enabled  bool
		Users    []string
		Postgres Postgres
	}

	// Instantiate loader
	l := &TOMLLoader{Path: testTOML}

	s := &ServerConfig{}
	err := l.Load(s)
	if err != nil {
		panic(err)
	}

	fmt.Println("Host-->", s.Name)
	fmt.Println("Users-->", s.Users)

	// Output:
	// Host--> koding
	// Users--> [ankara istanbul]
}

func ExampleJSONLoader() {
	// Our struct which is used for configuration
	type ServerConfig struct {
		Name     string
		Port     int
		Enabled  bool
		Users    []string
		Postgres Postgres
	}

	// Instantiate loader
	l := &JSONLoader{Path: testJSON}

	s := &ServerConfig{}
	err := l.Load(s)
	if err != nil {
		panic(err)
	}

	fmt.Println("Host-->", s.Name)
	fmt.Println("Users-->", s.Users)

	// Output:
	// Host--> koding
	// Users--> [ankara istanbul]
}

func ExampleYAMLLoader() {
	// Our struct which is used for configuration
	type ServerConfig struct {
		Name     string
		Port     int
		Enabled  bool
		Users    []string
		Postgres Postgres
	}

	// Instantiate loader
	l := &YAMLLoader{Path: testYAML}

	s := &ServerConfig{}
	err := l.Load(s)
	if err != nil {
		panic(err)
	}

	fmt.Println("Host-->", s.Name)
	fmt.Println("Users-->", s.Users)

	// Output:
	// Host--> koding
	// Users--> [ankara istanbul]
}
<|endoftext|>


<commit_before>package firego_test

import (
	"log"
	"time"

	"github.com/CloudCom/firego"
)

func ExampleFirebase_Auth() {
	fb := firego.New("https://someapp.firebaseio.com")
	fb.Auth("my-token")
}

func ExampleFirebase_Child() {
	fb := firego.New("https://someapp.firebaseio.com")
	childFB := fb.Child("some/child/path")

	log.Printf("My new ref %s\n", childFB)
}

func ExampleFirebase_Shallow() {
	fb := firego.New("https://someapp.firebaseio.com")
	// turn on
	fb.Shallow(true)
	// turn off
	fb.Shallow(false)
}

func ExampleFirebase_IncludePriority() {
	fb := firego.New("https://someapp.firebaseio.com")
	// turn on
	fb.IncludePriority(true)
	// turn off
	fb.IncludePriority(false)
}

func ExampleFirebase_Push() {
	fb := firego.New("https://someapp.firebaseio.com")
	newRef, err := fb.Push("my-value")
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("My new ref %s\n", newRef)
}

func ExampleFirebase_Remove() {
	fb := firego.New("https://someapp.firebaseio.com/some/value")
	if err := fb.Remove(); err != nil {
		log.Fatal(err)
	}
}

func ExampleFirebase_Set() {
	fb := firego.New("https://someapp.firebaseio.com")

	v := map[string]interface{}{
		"foo": "bar",
		"bar": 1,
		"bez": []string{"hello", "world"},
	}
	if err := fb.Set(v); err != nil {
		log.Fatal(err)
	}
}

func ExampleFirebase_Update() {
	fb := firego.New("https://someapp.firebaseio.com/some/value")
	if err := fb.Update("new-value"); err != nil {
		log.Fatal(err)
	}
}

func ExampleFirebase_Value() {
	fb := firego.New("https://someapp.firebaseio.com/some/value")
	var v interface{}
	if err := fb.Value(v); err != nil {
		log.Fatal(err)
	}

	log.Printf("My value %v\n", v)
}

func ExampleFirebase_Watch() {
	fb := firego.New("https://someapp.firebaseio.com/some/value")
	notifications := make(chan firego.Event)
	if err := fb.Watch(notifications); err != nil {
		log.Fatal(err)
	}

	for event := range notifications {
		log.Println("Event Received")
		log.Printf("Type: %s\n", event.Type)
		log.Printf("Path: %s\n", event.Path)
		log.Printf("Data: %v\n", event.Data)
		if event.Type == firego.EventTypeError {
			log.Print("Error occurred, loop ending")
		}
	}
}

func ExampleFirebase_StopWatching() {
	fb := firego.New("https://someapp.firebaseio.com/some/value")
	notifications := make(chan firego.Event)
	if err := fb.Watch(notifications); err != nil {
		log.Fatal(err)
	}

	go func() {
		for _ = range notifications {
		}
		log.Println("Channel closed")
	}()
	time.Sleep(10 * time.Millisecond) // let go routine start

	fb.StopWatching()
}
<commit_msg>fixing gofmt complaints<commit_after>package firego_test

import (
	"log"
	"time"

	"github.com/CloudCom/firego"
)

func ExampleFirebase_Auth() {
	fb := firego.New("https://someapp.firebaseio.com")
	fb.Auth("my-token")
}

func ExampleFirebase_Child() {
	fb := firego.New("https://someapp.firebaseio.com")
	childFB := fb.Child("some/child/path")

	log.Printf("My new ref %s\n", childFB)
}

func ExampleFirebase_Shallow() {
	fb := firego.New("https://someapp.firebaseio.com")
	// turn on
	fb.Shallow(true)
	// turn off
	fb.Shallow(false)
}

func ExampleFirebase_IncludePriority() {
	fb := firego.New("https://someapp.firebaseio.com")
	// turn on
	fb.IncludePriority(true)
	// turn off
	fb.IncludePriority(false)
}

func ExampleFirebase_Push() {
	fb := firego.New("https://someapp.firebaseio.com")
	newRef, err := fb.Push("my-value")
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("My new ref %s\n", newRef)
}

func ExampleFirebase_Remove() {
	fb := firego.New("https://someapp.firebaseio.com/some/value")
	if err := fb.Remove(); err != nil {
		log.Fatal(err)
	}
}

func ExampleFirebase_Set() {
	fb := firego.New("https://someapp.firebaseio.com")

	v := map[string]interface{}{
		"foo": "bar",
		"bar": 1,
		"bez": []string{"hello", "world"},
	}
	if err := fb.Set(v); err != nil {
		log.Fatal(err)
	}
}

func ExampleFirebase_Update() {
	fb := firego.New("https://someapp.firebaseio.com/some/value")
	if err := fb.Update("new-value"); err != nil {
		log.Fatal(err)
	}
}

func ExampleFirebase_Value() {
	fb := firego.New("https://someapp.firebaseio.com/some/value")
	var v interface{}
	if err := fb.Value(v); err != nil {
		log.Fatal(err)
	}

	log.Printf("My value %v\n", v)
}

func ExampleFirebase_Watch() {
	fb := firego.New("https://someapp.firebaseio.com/some/value")
	notifications := make(chan firego.Event)
	if err := fb.Watch(notifications); err != nil {
		log.Fatal(err)
	}

	for event := range notifications {
		log.Println("Event Received")
		log.Printf("Type: %s\n", event.Type)
		log.Printf("Path: %s\n", event.Path)
		log.Printf("Data: %v\n", event.Data)
		if event.Type == firego.EventTypeError {
			log.Print("Error occurred, loop ending")
		}
	}
}

func ExampleFirebase_StopWatching() {
	fb := firego.New("https://someapp.firebaseio.com/some/value")
	notifications := make(chan firego.Event)
	if err := fb.Watch(notifications); err != nil {
		log.Fatal(err)
	}

	go func() {
		for range notifications {
		}
		log.Println("Channel closed")
	}()
	time.Sleep(10 * time.Millisecond) // let go routine start

	fb.StopWatching()
}
<|endoftext|>


<commit_before>package aranGO

import "testing"
import "time"
import "log"

type Doc struct {
  Document
  Atr1 string  `json:"a1"`
  Num  int     `json:"num"`
  List int `json:"test"`
}

type Person struct {
  Document
  Name string
  Age  int
}

func TestExample(t *testing.T) {
  log.Println("Connection to database")

  s ,err:= Connect("http://pampa.dev:8529","diego","test",false)

  if err != nil {
    panic(err)
  }

  // Create Test Database
  user := []User{ User{ "diego","test",true,""}}
  err = s.CreateDB("pichicho",user)

  if err != nil {
    log.Println(err)
  }
  // create collection
  var colOpt CollectionOptions
  colOpt.Name = "test2"
  err = s.DB("pichicho").CreateCollection(&colOpt)
  var edges CollectionOptions
  edges.Name = "test2"
  edges.Type = 2
  if err != nil {
    log.Println(err)
  }
  col := s.DB("pichicho").Col("test2")
  if col == nil{
    panic("invalid colection")
  }
  // create document
  var doc Doc

  doc.Atr1 = "atributo 1"
  doc.Num  = 1
  col.Save(&doc)

  // update document
  doc.Atr1 = "e"
  doc.List = 28
  col.Replace(doc.Key,&doc)

  if doc.Error {
    log.Println(doc.Message)
  }

  err = col.Patch(doc.Key,map[string]int{ "num" : 99})
  if err != nil{
    panic(err)
  }

  db := s.DB("pichicho")

  //err = db.TruncateCollection("test2")

  q := NewQuery("FOR i in test2 FILTER i.test == 28 RETURN i")

  q.Batch = 5
  //q.Options["fullCount"] = true

  c, err := db.Execute(q)
  if err != nil{
    log.Println(err)
  }

  var i []Doc
  log.Println(c.FullCount())
  t1 := time.Now()
  c.FetchBatch(&i)
  log.Println(c.HasMore())
  log.Println(i)
  /*
  for more,err := c.FetchOne(&i); more ; more,err = c.FetchOne(&i){
    if err != nil {
      log.Println(err)
      break
    }
    log.Println(i)
  }
  */
  t2 := time.Now()
  log.Println("Time to fetch query:",t2.Sub(t1))

  // relate 2 docs

  var d,r Person
  d.Name = "Diego"; d.Age = 23
  r.Name = "Romi"; r.Age = 20

 // err = db.TruncateCollection("test2")
  // save both
  col.Save(&d)
  col.Save(&r)
  rel := db.Col("relations")
  log.Println("----->",rel.Relate(d.Id,r.Id,map[string]string{ "do" : "love" }))

  q2 := NewQuery(`FOR i in test2 FILTER i.gender > 40 return i `)

  t3 := time.Now()
  db.Execute(q2)
  db.Execute(q2)
  db.Execute(q2)
  db.Execute(q2)
  t4 := time.Now()
  log.Println(t4.Sub(t3))

}
<commit_msg>need to improve test<commit_after>package aranGO

import "testing"
import "time"
import "log"

type Doc struct {
  Document
  Atr1 string  `json:"a1"`
  Num  int     `json:"num"`
  List int `json:"test"`
}

type Person struct {
  Document
  Name string
  Age  int
}

func TestExample(t *testing.T) {
  log.Println("Connection to database")

  s ,err:= Connect("http://pampa.dev:8529","diego","test",false)

  if err != nil {
    panic(err)
  }

  // Create Test Database
  user := []User{ User{ "diego","test",true,""}}
  err = s.CreateDB("pichicho",user)

  if err != nil {
    log.Println(err)
  }
  // create collection
  var colOpt CollectionOptions
  var colOpt2 CollectionOptions
  colOpt2.IsEdge()
  colOpt.Name = "test2"
  colOpt2.Name = "relations"
  err = s.DB("pichicho").CreateCollection(&colOpt)
  err = s.DB("pichicho").CreateCollection(&colOpt2)
  var edges CollectionOptions
  edges.Name = "test2"
  edges.Type = 2
  if err != nil {
    log.Println(err)
  }
  col := s.DB("pichicho").Col("test2")
  if col == nil{
    panic("invalid colection")
  }
  // create document
  var doc Doc

  doc.Atr1 = "atributo 1"
  doc.Num  = 1
  col.Save(&doc)

  // update document
  doc.Atr1 = "e"
  doc.List = 28
  col.Replace(doc.Key,&doc)

  if doc.Error {
    log.Println(doc.Message)
  }

  err = col.Patch(doc.Key,map[string]int{ "num" : 99})
  if err != nil{
    panic(err)
  }

  db := s.DB("pichicho")

  //err = db.TruncateCollection("test2")

  q := NewQuery("FOR i in test2 FILTER i.test == 28 RETURN i")

  q.Batch = 5
  //q.Options["fullCount"] = true

  c, err := db.Execute(q)
  if err != nil{
    log.Println(err)
  }

  var i []Doc
  log.Println(c.FullCount())
  t1 := time.Now()
  c.FetchBatch(&i)
  log.Println(c.HasMore())
  log.Println(i)
  /*
  for more,err := c.FetchOne(&i); more ; more,err = c.FetchOne(&i){
    if err != nil {
      log.Println(err)
      break
    }
    log.Println(i)
  }
  */
  t2 := time.Now()
  log.Println("Time to fetch query:",t2.Sub(t1))

  // relate 2 docs

  var d,r Person
  d.Name = "Diego"; d.Age = 23
  r.Name = "Romi"; r.Age = 20

 // err = db.TruncateCollection("test2")
  // save both
  col.Save(&d)
  col.Save(&r)
  rel := db.Col("relations")
  if rel == nil {
    log.Println("invalid collection")
  }
  log.Println("----->",rel.Relate(d.Id,r.Id,map[string]string{ "do" : "love" }))

  q2 := NewQuery(`FOR i in test2 INSERT { name : i.name ,age : i.age} in test2`)
  db.Execute(q2)
  log.Println(c.Time)

}
<|endoftext|>


<commit_before>package parth_test

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

	"github.com/codemodus/parth"
)

var (
	r, rErr = http.NewRequest("GET", "/zero/1/2/key/nn4.4nn/5.5", nil)
)

func init() {
	if rErr != nil {
		panic(rErr)
	}
}

func Example() {
	var s string
	if err := parth.Segment(r.URL.Path, 4, &s); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(r.URL.Path)
	fmt.Printf("%v (%T)\n", s, s)

	// Output:
	// /zero/1/2/key/nn4.4nn/5.5
	// nn4.4nn (string)
}

func ExampleSegment() {
	var s string
	if err := parth.Segment(r.URL.Path, 4, &s); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(r.URL.Path)
	fmt.Printf("%v (%T)\n", s, s)

	// Output:
	// /zero/1/2/key/nn4.4nn/5.5
	// nn4.4nn (string)
}

func ExampleSequent() {
	var f float32
	if err := parth.Sequent(r.URL.Path, "key", &f); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(r.URL.Path)
	fmt.Printf("%v (%T)\n", f, f)

	// Output:
	// /zero/1/2/key/nn4.4nn/5.5
	// 4.4 (float32)
}

func ExampleSpan() {
	s, err := parth.Span(r.URL.Path, 2, 4)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(r.URL.Path)
	fmt.Println(s)

	// Output:
	// /zero/1/2/key/nn4.4nn/5.5
	// /2/key
}

func ExampleSubSeg() {
	var f float64
	if err := parth.SubSeg(r.URL.Path, "key", 1, &f); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(r.URL.Path)
	fmt.Printf("%v (%T)\n", f, f)

	// Output:
	// /zero/1/2/key/nn4.4nn/5.5
	// 5.5 (float64)
}

func ExampleSubSpan() {
	s0, err := parth.SubSpan(r.URL.Path, "zero", 2, 4)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	s1, err := parth.SubSpan(r.URL.Path, "1", 1, 3)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(r.URL.Path)
	fmt.Println(s0)
	fmt.Println(s1)

	// Output:
	// /zero/1/2/key/nn4.4nn/5.5
	// /key/nn4.4nn
	// /key/nn4.4nn
}

func ExampleParth() {
	var s string
	var f float32

	p := parth.New(r.URL.Path)
	p.Segment(0, &s)
	p.SubSeg("key", 1, &f)
	if err := p.Err(); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(r.URL.Path)
	fmt.Printf("%v (%T)\n", s, s)
	fmt.Printf("%v (%T)\n", f, f)

	// Output:
	// /zero/1/2/key/nn4.4nn/5.5
	// zero (string)
	// 5.5 (float32)
}

func ExampleUnmarshaler() {
	/*
		type mytype []byte

		func (m *mytype) UnmarshalSegment(seg string) error {
			*m = []byte(seg)
		}
	*/

	var m mytype

	if err := parth.Segment(r.URL.Path, 4, &m); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(r.URL.Path)
	fmt.Printf("%v == %q (%T)\n", m, m, m)

	// Output:
	// /zero/1/2/key/nn4.4nn/5.5
	// [110 110 52 46 52 110 110] == "nn4.4nn" (parth_test.mytype)
}

type mytype []byte

func (m *mytype) UnmarshalSegment(seg string) error {
	*m = []byte(seg)
	return nil
}
<commit_msg>Correct example file import<commit_after>package parth_test

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

	"github.com/codemodus/parth/v2"
)

var (
	r, rErr = http.NewRequest("GET", "/zero/1/2/key/nn4.4nn/5.5", nil)
)

func init() {
	if rErr != nil {
		panic(rErr)
	}
}

func Example() {
	var s string
	if err := parth.Segment(r.URL.Path, 4, &s); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(r.URL.Path)
	fmt.Printf("%v (%T)\n", s, s)

	// Output:
	// /zero/1/2/key/nn4.4nn/5.5
	// nn4.4nn (string)
}

func ExampleSegment() {
	var s string
	if err := parth.Segment(r.URL.Path, 4, &s); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(r.URL.Path)
	fmt.Printf("%v (%T)\n", s, s)

	// Output:
	// /zero/1/2/key/nn4.4nn/5.5
	// nn4.4nn (string)
}

func ExampleSequent() {
	var f float32
	if err := parth.Sequent(r.URL.Path, "key", &f); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(r.URL.Path)
	fmt.Printf("%v (%T)\n", f, f)

	// Output:
	// /zero/1/2/key/nn4.4nn/5.5
	// 4.4 (float32)
}

func ExampleSpan() {
	s, err := parth.Span(r.URL.Path, 2, 4)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(r.URL.Path)
	fmt.Println(s)

	// Output:
	// /zero/1/2/key/nn4.4nn/5.5
	// /2/key
}

func ExampleSubSeg() {
	var f float64
	if err := parth.SubSeg(r.URL.Path, "key", 1, &f); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(r.URL.Path)
	fmt.Printf("%v (%T)\n", f, f)

	// Output:
	// /zero/1/2/key/nn4.4nn/5.5
	// 5.5 (float64)
}

func ExampleSubSpan() {
	s0, err := parth.SubSpan(r.URL.Path, "zero", 2, 4)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	s1, err := parth.SubSpan(r.URL.Path, "1", 1, 3)
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(r.URL.Path)
	fmt.Println(s0)
	fmt.Println(s1)

	// Output:
	// /zero/1/2/key/nn4.4nn/5.5
	// /key/nn4.4nn
	// /key/nn4.4nn
}

func ExampleParth() {
	var s string
	var f float32

	p := parth.New(r.URL.Path)
	p.Segment(0, &s)
	p.SubSeg("key", 1, &f)
	if err := p.Err(); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(r.URL.Path)
	fmt.Printf("%v (%T)\n", s, s)
	fmt.Printf("%v (%T)\n", f, f)

	// Output:
	// /zero/1/2/key/nn4.4nn/5.5
	// zero (string)
	// 5.5 (float32)
}

func ExampleUnmarshaler() {
	/*
		type mytype []byte

		func (m *mytype) UnmarshalSegment(seg string) error {
			*m = []byte(seg)
		}
	*/

	var m mytype

	if err := parth.Segment(r.URL.Path, 4, &m); err != nil {
		fmt.Fprintln(os.Stderr, err)
	}

	fmt.Println(r.URL.Path)
	fmt.Printf("%v == %q (%T)\n", m, m, m)

	// Output:
	// /zero/1/2/key/nn4.4nn/5.5
	// [110 110 52 46 52 110 110] == "nn4.4nn" (parth_test.mytype)
}

type mytype []byte

func (m *mytype) UnmarshalSegment(seg string) error {
	*m = []byte(seg)
	return nil
}
<|endoftext|>


<commit_before>package etree_test

import (
    "encoding/xml/etree"
    "os"
)

// Create an etree Document, add XML entities to it, and serialize it to stdout.
func ExampleNewDocument() {
    doc := etree.NewDocument()
    doc.CreateProcInst("xml", `version="1.0" encoding="UTF-8"`)
    doc.CreateProcInst("xml-stylesheet", `type="text/xsl" href="style.xsl"`)

    people := doc.CreateElement("People")
    people.CreateComment("These are all known people")

    jon := people.CreateElement("Person")
    jon.CreateAttr("name", "Jon")

    sally := people.CreateElement("Person")
    sally.CreateAttr("name", "Sally")

    doc.Indent(2)
    doc.WriteTo(os.Stdout)
    // Output:
    // <?xml version="1.0" encoding="UTF-8"?>
    // <?xml-stylesheet type="text/xsl" href="style.xsl"?>
    // <People>
    //   <!-- These are all known people -->
    //   <Person name="Jon"/>
    //   <Person name="Sally"/>
    // </People>
}
<commit_msg>moved example in docs<commit_after>package etree_test

import (
    "encoding/xml/etree"
    "os"
)

// Create an etree Document, add XML entities to it, and serialize it to stdout.
func Example() {
    doc := etree.NewDocument()
    doc.CreateProcInst("xml", `version="1.0" encoding="UTF-8"`)
    doc.CreateProcInst("xml-stylesheet", `type="text/xsl" href="style.xsl"`)

    people := doc.CreateElement("People")
    people.CreateComment("These are all known people")

    jon := people.CreateElement("Person")
    jon.CreateAttr("name", "Jon")

    sally := people.CreateElement("Person")
    sally.CreateAttr("name", "Sally")

    doc.Indent(2)
    doc.WriteTo(os.Stdout)
    // Output:
    // <?xml version="1.0" encoding="UTF-8"?>
    // <?xml-stylesheet type="text/xsl" href="style.xsl"?>
    // <People>
    //   <!-- These are all known people -->
    //   <Person name="Jon"/>
    //   <Person name="Sally"/>
    // </People>
}
<|endoftext|>


<commit_before>package apps

import (
	"fmt"
	"time"

	. "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/onsi/ginkgo"
	. "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/onsi/gomega"
	. "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/onsi/gomega/gbytes"
	. "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/onsi/gomega/gexec"

	"github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/cloudfoundry-incubator/cf-test-helpers/cf"
	"github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/cloudfoundry-incubator/cf-test-helpers/generator"
	"github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/cloudfoundry-incubator/cf-test-helpers/helpers"
	"github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/cloudfoundry/noaa"
	"github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/cloudfoundry/noaa/events"
	"github.com/cloudfoundry/cf-acceptance-tests/helpers/app_helpers"
	"github.com/cloudfoundry/cf-acceptance-tests/helpers/assets"
	. "github.com/cloudfoundry/cf-acceptance-tests/helpers/matchers"

	"crypto/tls"
	"strings"

	"encoding/json"
	"os"
	"path/filepath"
)

var _ = Describe("loggregator", func() {
	var appName string
	const hundredthOfOneSecond = 10000 // this app uses millionth of seconds

	BeforeEach(func() {
		appName = generator.PrefixedRandomName("CATS-APP-")

		Expect(cf.Cf("push", appName, "--no-start", "-b", config.RubyBuildpackName, "-m", DEFAULT_MEMORY_LIMIT, "-p", assets.NewAssets().LoggregatorLoadGenerator, "-d", config.AppsDomain).Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		app_helpers.SetBackend(appName)
		Expect(cf.Cf("start", appName).Wait(CF_PUSH_TIMEOUT)).To(Exit(0))
	})

	AfterEach(func() {
		app_helpers.AppReport(appName, DEFAULT_TIMEOUT)

		Expect(cf.Cf("delete", appName, "-f", "-r").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
	})

	Context("cf logs", func() {
		var logs *Session

		BeforeEach(func() {
			logs = cf.Cf("logs", appName)
		})

		AfterEach(func() {
			// logs might be nil if the BeforeEach panics
			if logs != nil {
				logs.Interrupt().Wait(DEFAULT_TIMEOUT)
			}
		})

		It("exercises basic loggregator behavior", func() {
			Eventually(logs, (DEFAULT_TIMEOUT + time.Minute)).Should(Say("Connected, tailing logs for app"))

			Eventually(func() string {
				return helpers.CurlApp(appName, fmt.Sprintf("/log/sleep/%d", hundredthOfOneSecond))
			}, DEFAULT_TIMEOUT).Should(ContainSubstring("Muahaha"))

			Eventually(logs, (DEFAULT_TIMEOUT + time.Minute)).Should(Say("Muahaha"))
		})
	})

	Context("cf logs --recent", func() {
		It("makes loggregator buffer and dump log messages", func() {
			Eventually(func() string {
				return helpers.CurlApp(appName, fmt.Sprintf("/log/sleep/%d", hundredthOfOneSecond))
			}, DEFAULT_TIMEOUT).Should(ContainSubstring("Muahaha"))

			Eventually(func() *Session {
				appLogsSession := cf.Cf("logs", "--recent", appName)
				Expect(appLogsSession.Wait(DEFAULT_TIMEOUT)).To(Exit(0))
				return appLogsSession
			}, DEFAULT_TIMEOUT).Should(Say("Muahaha"))
		})
	})

	Context("firehose data", func() {
		It("shows logs and metrics", func() {
			config := helpers.LoadConfig()

			noaaConnection := noaa.NewConsumer(getDopplerEndpoint(), &tls.Config{InsecureSkipVerify: config.SkipSSLValidation}, nil)
			msgChan := make(chan *events.Envelope, 100000)
			errorChan := make(chan error)
			stopchan := make(chan struct{})
			go noaaConnection.Firehose(generator.RandomName(), getAdminUserAccessToken(), msgChan, errorChan, stopchan)
			defer close(stopchan)

			Eventually(func() string {
				return helpers.CurlApp(appName, fmt.Sprintf("/log/sleep/%d", hundredthOfOneSecond))
			}, DEFAULT_TIMEOUT).Should(ContainSubstring("Muahaha"))

			timeout := time.After(5 * time.Second)
			messages := make([]*events.Envelope, 0, 100000)

			for {
				select {
				case <-timeout:
					return
				case msg := <-msgChan:
					messages = append(messages, msg)
				}
			}

			Expect(messages).To(ContainElement(EnvelopeContainingMessageLike("Muahaha")), "To enable the logging & metrics firehose feature, please ask your CF administrator to add the 'doppler.firehose' scope to your CF admin user.")
		})
	})

	It("shows container metrics", func() {
		config := helpers.LoadConfig()
		appGuid := strings.TrimSpace(string(cf.Cf("app", appName, "--guid").Wait(DEFAULT_TIMEOUT).Out.Contents()))

		noaaConnection := noaa.NewConsumer(getDopplerEndpoint(), &tls.Config{InsecureSkipVerify: config.SkipSSLValidation}, nil)
		msgChan := make(chan *events.Envelope, 100000)
		errorChan := make(chan error)
		stopchan := make(chan struct{})
		go noaaConnection.Firehose(generator.RandomName(), getAdminUserAccessToken(), msgChan, errorChan, stopchan)
		defer close(stopchan)

		Eventually(func() bool {
			for {
				select {
				case msg := <-msgChan:
					if cm := msg.GetContainerMetric(); cm != nil {
						if cm.GetApplicationId() == appGuid && cm.GetInstanceIndex() == 0 {
							return true
						}
					}
				default:
					return false
				}
			}
		}, DEFAULT_TIMEOUT).Should(BeTrue())
	})
})

type cfHomeConfig struct {
	AccessToken         string
	LoggregatorEndpoint string
}

func getCfHomeConfig() *cfHomeConfig {
	myCfHomeConfig := &cfHomeConfig{}

	cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
		path := filepath.Join(os.Getenv("CF_HOME"), ".cf", "config.json")

		configFile, err := os.Open(path)
		if err != nil {
			panic(err)
		}

		decoder := json.NewDecoder(configFile)
		err = decoder.Decode(myCfHomeConfig)
		if err != nil {
			panic(err)
		}
	})

	return myCfHomeConfig
}

func getAdminUserAccessToken() string {
	return getCfHomeConfig().AccessToken
}

func getDopplerEndpoint() string {
	return strings.Replace(getCfHomeConfig().LoggregatorEndpoint, "loggregator", "doppler", -1)
}
<commit_msg>Allow firehose test to fail when it times out<commit_after>package apps

import (
	"fmt"
	"time"

	. "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/onsi/ginkgo"
	. "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/onsi/gomega"
	. "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/onsi/gomega/gbytes"
	. "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/onsi/gomega/gexec"

	"github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/cloudfoundry-incubator/cf-test-helpers/cf"
	"github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/cloudfoundry-incubator/cf-test-helpers/generator"
	"github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/cloudfoundry-incubator/cf-test-helpers/helpers"
	"github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/cloudfoundry/noaa"
	"github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/cloudfoundry/noaa/events"
	"github.com/cloudfoundry/cf-acceptance-tests/helpers/app_helpers"
	"github.com/cloudfoundry/cf-acceptance-tests/helpers/assets"
	. "github.com/cloudfoundry/cf-acceptance-tests/helpers/matchers"

	"crypto/tls"
	"strings"

	"encoding/json"
	"os"
	"path/filepath"
)

var _ = Describe("loggregator", func() {
	var appName string
	const hundredthOfOneSecond = 10000 // this app uses millionth of seconds

	BeforeEach(func() {
		appName = generator.PrefixedRandomName("CATS-APP-")

		Expect(cf.Cf("push", appName, "--no-start", "-b", config.RubyBuildpackName, "-m", DEFAULT_MEMORY_LIMIT, "-p", assets.NewAssets().LoggregatorLoadGenerator, "-d", config.AppsDomain).Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		app_helpers.SetBackend(appName)
		Expect(cf.Cf("start", appName).Wait(CF_PUSH_TIMEOUT)).To(Exit(0))
	})

	AfterEach(func() {
		app_helpers.AppReport(appName, DEFAULT_TIMEOUT)

		Expect(cf.Cf("delete", appName, "-f", "-r").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
	})

	Context("cf logs", func() {
		var logs *Session

		BeforeEach(func() {
			logs = cf.Cf("logs", appName)
		})

		AfterEach(func() {
			// logs might be nil if the BeforeEach panics
			if logs != nil {
				logs.Interrupt().Wait(DEFAULT_TIMEOUT)
			}
		})

		It("exercises basic loggregator behavior", func() {
			Eventually(logs, (DEFAULT_TIMEOUT + time.Minute)).Should(Say("Connected, tailing logs for app"))

			Eventually(func() string {
				return helpers.CurlApp(appName, fmt.Sprintf("/log/sleep/%d", hundredthOfOneSecond))
			}, DEFAULT_TIMEOUT).Should(ContainSubstring("Muahaha"))

			Eventually(logs, (DEFAULT_TIMEOUT + time.Minute)).Should(Say("Muahaha"))
		})
	})

	Context("cf logs --recent", func() {
		It("makes loggregator buffer and dump log messages", func() {
			Eventually(func() string {
				return helpers.CurlApp(appName, fmt.Sprintf("/log/sleep/%d", hundredthOfOneSecond))
			}, DEFAULT_TIMEOUT).Should(ContainSubstring("Muahaha"))

			Eventually(func() *Session {
				appLogsSession := cf.Cf("logs", "--recent", appName)
				Expect(appLogsSession.Wait(DEFAULT_TIMEOUT)).To(Exit(0))
				return appLogsSession
			}, DEFAULT_TIMEOUT).Should(Say("Muahaha"))
		})
	})

	Context("firehose data", func() {
		It("shows logs and metrics", func() {
			config := helpers.LoadConfig()

			noaaConnection := noaa.NewConsumer(getDopplerEndpoint(), &tls.Config{InsecureSkipVerify: config.SkipSSLValidation}, nil)
			msgChan := make(chan *events.Envelope, 100000)
			errorChan := make(chan error)
			stopchan := make(chan struct{})

			go noaaConnection.Firehose(generator.RandomName(), getAdminUserAccessToken(), msgChan, errorChan, stopchan)
			defer close(stopchan)

			Eventually(func() string {
				return helpers.CurlApp(appName, fmt.Sprintf("/log/sleep/%d", hundredthOfOneSecond))
			}, DEFAULT_TIMEOUT).Should(ContainSubstring("Muahaha"))

			Eventually(msgChan, 5).Should(Receive(EnvelopeContainingMessageLike("Muahaha")), "To enable the logging & metrics firehose feature, please ask your CF administrator to add the 'doppler.firehose' scope to your CF admin user.")
		})
	})

	It("shows container metrics", func() {
		config := helpers.LoadConfig()
		appGuid := strings.TrimSpace(string(cf.Cf("app", appName, "--guid").Wait(DEFAULT_TIMEOUT).Out.Contents()))

		noaaConnection := noaa.NewConsumer(getDopplerEndpoint(), &tls.Config{InsecureSkipVerify: config.SkipSSLValidation}, nil)
		msgChan := make(chan *events.Envelope, 100000)
		errorChan := make(chan error)
		stopchan := make(chan struct{})
		go noaaConnection.Firehose(generator.RandomName(), getAdminUserAccessToken(), msgChan, errorChan, stopchan)
		defer close(stopchan)

		Eventually(func() bool {
			for {
				select {
				case msg := <-msgChan:
					if cm := msg.GetContainerMetric(); cm != nil {
						if cm.GetApplicationId() == appGuid && cm.GetInstanceIndex() == 0 {
							return true
						}
					}
				default:
					return false
				}
			}
		}, DEFAULT_TIMEOUT).Should(BeTrue())
	})
})

type cfHomeConfig struct {
	AccessToken         string
	LoggregatorEndpoint string
}

func getCfHomeConfig() *cfHomeConfig {
	myCfHomeConfig := &cfHomeConfig{}

	cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
		path := filepath.Join(os.Getenv("CF_HOME"), ".cf", "config.json")

		configFile, err := os.Open(path)
		if err != nil {
			panic(err)
		}

		decoder := json.NewDecoder(configFile)
		err = decoder.Decode(myCfHomeConfig)
		if err != nil {
			panic(err)
		}
	})

	return myCfHomeConfig
}

func getAdminUserAccessToken() string {
	return getCfHomeConfig().AccessToken
}

func getDopplerEndpoint() string {
	return strings.Replace(getCfHomeConfig().LoggregatorEndpoint, "loggregator", "doppler", -1)
}
<|endoftext|>


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

package ext

import (
	"bytes"
	"testing"
	"testing/quick"

	. "code.google.com/p/goprotobuf/proto"
	. "code.google.com/p/goprotobuf/proto/testdata"
)

func TestDelimited(t *testing.T) {
	check := func(x int) bool {
		if x < 0 {
			x *= -1
		}

		var input *GoTest
		switch x % 2 {
		case 0:
			input = initGoTest(true)
		case 1:
			input = initGoTest(false)
		}

		reference, err := Marshal(input)
		if err != nil {
			return false
		}

		var buffer bytes.Buffer
		var written int

		for i := 0; i < x%100; i++ {
			n, err := WriteDelimited(&buffer, input)
			if err != nil {
				return false
			}
			if n < len(reference) {
				return false
			}

			written += n
		}

		var read int

		for i := 0; i < x%100; i++ {
			output := &GoTest{}
			n, err := ReadDelimited(&buffer, output)
			if err != nil {
				return false
			}

			raw, err := Marshal(output)
			if err != nil {
				return false
			}

			if !bytes.Equal(reference, raw) {
				return false
			}

			read += n
		}

		if written != read {
			return false
		}

		return true
	}

	if err := quick.Check(check, nil); err != nil {
		t.Error(err)
	}
}
<commit_msg>Include table tests for operations and end-to-end.<commit_after>// Copyright 2013 Matt T. Proud
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ext

import (
	"bytes"
	"testing"
	"testing/quick"

	. "code.google.com/p/goprotobuf/proto"
	. "code.google.com/p/goprotobuf/proto/testdata"
)

func TestWriteDelimited(t *testing.T) {
	for _, test := range []struct {
		msg Message
		buf []byte
		n   int
		err error
	}{
		{
			msg: &Empty{},
			n:   1,
			buf: []byte{0},
		},
		{
			msg: &GoEnum{Foo: FOO_FOO1.Enum()},
			n:   3,
			buf: []byte{2, 8, 1},
		},
	} {
		var buf bytes.Buffer
		if n, err := WriteDelimited(&buf, test.msg); n != test.n || err != test.err {
			t.Fatalf("WriteDelimited(buf, %#v) = %v, %v; want %v, %v", test.msg, n, err, test.n, test.err)
		}
		if out := buf.Bytes(); !bytes.Equal(out, test.buf) {
			t.Fatalf("WriteDelimited(buf, %#v); buf = %v; want %v", test.msg, out, test.buf)
		}
	}
}

func TestReadDelimited(t *testing.T) {
	for _, test := range []struct {
		buf []byte
		msg Message
		n   int
		err error
	}{
	// TODO(br): Uncomment pending end-to-end fix.
	//
	// {
	// 	BUF: []byte{0},
	// 	msg: &Empty{},
	// 	n: 1,
	// },
	// {
	// 	n: 3,
	// 	buf: []byte{2, 8, 1},
	// 	msg: &GoEnum{Foo: FOO_FOO1.Enum()},
	// },
	} {
		msg := Clone(test.msg)
		msg.Reset()
		if n, err := ReadDelimited(bytes.NewBuffer(test.buf), msg); n != test.n || err != test.err {
			t.Fatalf("ReadDelimited(%v, msg) = %v, %v; want %v, %v", test.buf, n, err, test.n, test.err)
		}
		if !Equal(msg, test.msg) {
			t.Fatalf("ReadDelimited(%v, msg); msg = %v; want %v", test.buf, msg, test.msg)
		}
	}
}

func TestEndToEndValid(t *testing.T) {
	for _, test := range []struct {
		msgs []Message
	}{
		{
		// TODO(br): Uncomment pending end-to-end fix.
		//
		// []Message{&Empty{}},
		// []Message{&GoEnum{Foo: FOO_FOO1.Enum()}, &Empty{}, &GoEnum{Foo: FOO_FOO1.Enum()}},
		// []Message{&GoEnum{Foo: FOO_FOO1.Enum()}},
		},
	} {
		var buf bytes.Buffer
		var written int
		for i, msg := range test.msgs {
			n, err := WriteDelimited(&buf, msg)
			if err != nil {
				// Assumption: TestReadDelimited and TestWriteDelimited are sufficient
				//             and inputs for this test are explicitly exercised there.
				t.Fatalf("WriteDelimited(buf, %v[%d]) = ?, %v; wanted ?, nil", test.msgs, i, err)
			}
			written += n
		}
		var read int
		for i, msg := range test.msgs {
			out := Clone(msg)
			out.Reset()
			n, _ := ReadDelimited(&buf, out)
			// Decide to do EOF checking?
			read += n
			if !Equal(out, msg) {
				t.Fatalf("out = %v; want %v[%d] = %#v", out, test.msgs, i, msg)
			}
		}
		if read != written {
			t.Fatalf("%v read = %d; want %d", test.msgs, read, written)
		}
	}
}

func TestDelimited(t *testing.T) {
	check := func(x int) bool {
		if x < 0 {
			x *= -1
		}

		var input *GoTest
		switch x % 2 {
		case 0:
			input = initGoTest(true)
		case 1:
			input = initGoTest(false)
		}

		reference, err := Marshal(input)
		if err != nil {
			return false
		}

		var buffer bytes.Buffer
		var written int

		for i := 0; i < x%100; i++ {
			n, err := WriteDelimited(&buffer, input)
			if err != nil {
				return false
			}
			if n < len(reference) {
				return false
			}

			written += n
		}

		var read int

		for i := 0; i < x%100; i++ {
			output := &GoTest{}
			n, err := ReadDelimited(&buffer, output)
			if err != nil {
				return false
			}

			raw, err := Marshal(output)
			if err != nil {
				return false
			}

			if !bytes.Equal(reference, raw) {
				return false
			}

			read += n
		}

		if written != read {
			return false
		}

		return true
	}

	if err := quick.Check(check, nil); err != nil {
		t.Error(err)
	}
}
<|endoftext|>


<commit_before>package appstore

// https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Subscriptions.html#//apple_ref/doc/uid/TP40008267-CH7-SW16
type NotificationType string

const (
	// Initial purchase of the subscription.
	NotificationTypeInitialBuy NotificationType = "INITIAL_BUY"
	// Subscription was canceled by Apple customer support.
	NotificationTypeCancel NotificationType = "CANCEL"
	// Automatic renewal was successful for an expired subscription.
	// Deprecated: DID_RECOVER should be used instead of RENEWAL
	NotificationTypeRenewal NotificationType = "RENEWAL"
	// Expired subscription recovered through a billing retry.
	NotificationTypeDidRecover NotificationType = "DID_RECOVER"
	// Customer renewed a subscription interactively after it lapsed.
	NotificationTypeInteractiveRenewal NotificationType = "INTERACTIVE_RENEWAL"
	// Customer changed the plan that takes affect at the next subscription renewal. Current active plan is not affected.
	NotificationTypeDidChangeRenewalPreference NotificationType = "DID_CHANGE_RENEWAL_PREF"
	// Customer changed the subscription renewal status. Current active plan is not affected.
	NotificationTypeDidChangeRenewalStatus NotificationType = "DID_CHANGE_RENEWAL_STATUS"
	// Subscription failed to renew due to a billing issue.
	NotificationTypeDidFailToRenew NotificationType = "DID_FAIL_TO_RENEW"
	// AppleCare successfully refunded the transaction for a consumable, non-consumable, or a non-renewing subscription.
	NotificationTypeRefund NotificationType = "REFUND"
	// App Store has started asking the customer to consent to your app’s subscription price increase.
	NotificationTypePriceIncreaseConsent NotificationType = "PRICE_INCREASE_CONSENT"
	// Customer’s subscription has successfully auto-renewed for a new transaction period.
	NotificationTypeDidRenew NotificationType = "DID_RENEW"
)

type NotificationEnvironment string

const (
	NotificationSandbox    NotificationEnvironment = "Sandbox"
	NotificationProduction NotificationEnvironment = "PROD"
)

type NotificationExpiresDate struct {
	ExpiresDateMS  string `json:"expires_date"`
	ExpiresDateUTC string `json:"expires_date_formatted"`
	ExpiresDatePST string `json:"expires_date_formatted_pst"`
}

type NotificationReceipt struct {
	UniqueIdentifier          string `json:"unique_identifier"`
	AppItemID                 string `json:"app_item_id"`
	Quantity                  string `json:"quantity"`
	VersionExternalIdentifier string `json:"version_external_identifier"`
	UniqueVendorIdentifier    string `json:"unique_vendor_identifier"`
	WebOrderLineItemID        string `json:"web_order_line_item_id"`
	ItemID                    string `json:"item_id"`
	ProductID                 string `json:"product_id"`
	BID                       string `json:"bid"`
	BVRS                      string `json:"bvrs"`
	TransactionID             string `json:"transaction_id"`
	OriginalTransactionID     string `json:"original_transaction_id"`
	IsTrialPeriod             string `json:"is_trial_period"`
	IsInIntroOfferPeriod      string `json:"is_in_intro_offer_period"`

	PurchaseDate
	OriginalPurchaseDate
	NotificationExpiresDate
	CancellationDate
}

type NotificationUnifiedReceipt struct {
	Status             int                  `json:"status"`
	Environment        Environment          `json:"environment"`
	LatestReceipt      string               `json:"latest_receipt"`
	LatestReceiptInfo  []InApp              `json:"latest_receipt_info"`
	PendingRenewalInfo []PendingRenewalInfo `json:"pending_renewal_info,omitempty"`
}

type SubscriptionNotification struct {
	Environment      NotificationEnvironment `json:"environment"`
	NotificationType NotificationType        `json:"notification_type"`

	// Not show in raw notify body
	Password              string `json:"password"`
	OriginalTransactionID string `json:"original_transaction_id"`
	AutoRenewAdamID       string `json:"auto_renew_adam_id"`

	// The primary key for identifying a subscription purchase.
	// Posted only if the notification_type is CANCEL.
	WebOrderLineItemID string `json:"web_order_line_item_id"`

	// This is the same as the Subscription Expiration Intent in the receipt.
	// Posted only if notification_type is RENEWAL or INTERACTIVE_RENEWAL.
	ExpirationIntent int `json:"expiration_intent"`

	// Auto renew info
	AutoRenewStatus    string `json:"auto_renew_status"` // false or true
	AutoRenewProductID string `json:"auto_renew_product_id"`

	// Posted if the notification_type is RENEWAL or INTERACTIVE_RENEWAL, and only if the renewal is successful.
	// Posted also if the notification_type is INITIAL_BUY.
	// Not posted for notification_type CANCEL.
	// Deprecated: use UnifiedReceipt.LatestReceipt instead. See details: https://developer.apple.com/documentation/appstoreservernotifications/ .
	LatestReceipt string `json:"latest_receipt"`
	// Deprecated: use UnifiedReceipt.LatestReceiptInfo instead. See details: https://developer.apple.com/documentation/appstoreservernotifications/ .
	LatestReceiptInfo NotificationReceipt `json:"latest_receipt_info"`

	// In the new notifications above properties latest_receipt, latest_receipt_info are moved under this one
	UnifiedReceipt NotificationUnifiedReceipt `json:"unified_receipt"`

	// Posted only if the notification_type is RENEWAL or CANCEL or if renewal failed and subscription expired.
	// Deprecated: see details: https://developer.apple.com/documentation/appstoreservernotifications/ .
	LatestExpiredReceipt string `json:"latest_expired_receipt"`
	// Deprecated: see details: https://developer.apple.com/documentation/appstoreservernotifications/ .
	LatestExpiredReceiptInfo NotificationReceipt `json:"latest_expired_receipt_info"`

	// Posted only if the notification_type is CANCEL.
	CancellationDate
}
<commit_msg>add some field in responsebody<commit_after>package appstore

// NotificationType is type
// https://developer.apple.com/documentation/appstoreservernotifications/notification_type
// https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Chapters/Subscriptions.html#//apple_ref/doc/uid/TP40008267-CH7-SW16
type NotificationType string

// list of NotificationType
const (
	// Initial purchase of the subscription.
	NotificationTypeInitialBuy NotificationType = "INITIAL_BUY"
	// Subscription was canceled by Apple customer support.
	NotificationTypeCancel NotificationType = "CANCEL"
	// Automatic renewal was successful for an expired subscription.
	// Deprecated: DID_RECOVER should be used instead of RENEWAL
	NotificationTypeRenewal NotificationType = "RENEWAL"
	// Expired subscription recovered through a billing retry.
	NotificationTypeDidRecover NotificationType = "DID_RECOVER"
	// Customer renewed a subscription interactively after it lapsed.
	NotificationTypeInteractiveRenewal NotificationType = "INTERACTIVE_RENEWAL"
	// Customer changed the plan that takes affect at the next subscription renewal. Current active plan is not affected.
	NotificationTypeDidChangeRenewalPreference NotificationType = "DID_CHANGE_RENEWAL_PREF"
	// Customer changed the subscription renewal status. Current active plan is not affected.
	NotificationTypeDidChangeRenewalStatus NotificationType = "DID_CHANGE_RENEWAL_STATUS"
	// Subscription failed to renew due to a billing issue.
	NotificationTypeDidFailToRenew NotificationType = "DID_FAIL_TO_RENEW"
	// AppleCare successfully refunded the transaction for a consumable, non-consumable, or a non-renewing subscription.
	NotificationTypeRefund NotificationType = "REFUND"
	// App Store has started asking the customer to consent to your app’s subscription price increase.
	NotificationTypePriceIncreaseConsent NotificationType = "PRICE_INCREASE_CONSENT"
	// Customer’s subscription has successfully auto-renewed for a new transaction period.
	NotificationTypeDidRenew NotificationType = "DID_RENEW"
)

// NotificationEnvironment is type
type NotificationEnvironment string

// list of NotificationEnvironment
const (
	NotificationSandbox    NotificationEnvironment = "Sandbox"
	NotificationProduction NotificationEnvironment = "PROD"
)

type NotificationExpiresDate struct {
	ExpiresDateMS  string `json:"expires_date"`
	ExpiresDateUTC string `json:"expires_date_formatted"`
	ExpiresDatePST string `json:"expires_date_formatted_pst"`
}

type NotificationReceipt struct {
	UniqueIdentifier          string `json:"unique_identifier"`
	AppItemID                 string `json:"app_item_id"`
	Quantity                  string `json:"quantity"`
	VersionExternalIdentifier string `json:"version_external_identifier"`
	UniqueVendorIdentifier    string `json:"unique_vendor_identifier"`
	WebOrderLineItemID        string `json:"web_order_line_item_id"`
	ItemID                    string `json:"item_id"`
	ProductID                 string `json:"product_id"`
	BID                       string `json:"bid"`
	BVRS                      string `json:"bvrs"`
	TransactionID             string `json:"transaction_id"`
	OriginalTransactionID     string `json:"original_transaction_id"`
	IsTrialPeriod             string `json:"is_trial_period"`
	IsInIntroOfferPeriod      string `json:"is_in_intro_offer_period"`

	PurchaseDate
	OriginalPurchaseDate
	NotificationExpiresDate
	CancellationDate
}

type NotificationUnifiedReceipt struct {
	Status             int                  `json:"status"`
	Environment        Environment          `json:"environment"`
	LatestReceipt      string               `json:"latest_receipt"`
	LatestReceiptInfo  []InApp              `json:"latest_receipt_info"`
	PendingRenewalInfo []PendingRenewalInfo `json:"pending_renewal_info,omitempty"`
}

// SubscriptionNotification is struct for
// https://developer.apple.com/documentation/appstoreservernotifications/responsebody
type SubscriptionNotification struct {
	Environment      NotificationEnvironment `json:"environment"`
	NotificationType NotificationType        `json:"notification_type"`

	// Not show in raw notify body
	Password              string `json:"password"`
	OriginalTransactionID string `json:"original_transaction_id"`
	AutoRenewAdamID       string `json:"auto_renew_adam_id"`

	// The primary key for identifying a subscription purchase.
	// Posted only if the notification_type is CANCEL.
	WebOrderLineItemID string `json:"web_order_line_item_id"`

	// This is the same as the Subscription Expiration Intent in the receipt.
	// Posted only if notification_type is RENEWAL or INTERACTIVE_RENEWAL.
	ExpirationIntent int `json:"expiration_intent"`

	// Auto renew info
	AutoRenewStatus    string `json:"auto_renew_status"` // false or true
	AutoRenewProductID string `json:"auto_renew_product_id"`

	// Posted if the notification_type is RENEWAL or INTERACTIVE_RENEWAL, and only if the renewal is successful.
	// Posted also if the notification_type is INITIAL_BUY.
	// Not posted for notification_type CANCEL.
	// Deprecated: use UnifiedReceipt.LatestReceipt instead. See details: https://developer.apple.com/documentation/appstoreservernotifications/ .
	LatestReceipt string `json:"latest_receipt"`
	// Deprecated: use UnifiedReceipt.LatestReceiptInfo instead. See details: https://developer.apple.com/documentation/appstoreservernotifications/ .
	LatestReceiptInfo NotificationReceipt `json:"latest_receipt_info"`

	// In the new notifications above properties latest_receipt, latest_receipt_info are moved under this one
	UnifiedReceipt NotificationUnifiedReceipt `json:"unified_receipt"`

	// Posted only if the notification_type is RENEWAL or CANCEL or if renewal failed and subscription expired.
	// Deprecated: see details: https://developer.apple.com/documentation/appstoreservernotifications/ .
	LatestExpiredReceipt string `json:"latest_expired_receipt"`
	// Deprecated: see details: https://developer.apple.com/documentation/appstoreservernotifications/ .
	LatestExpiredReceiptInfo NotificationReceipt `json:"latest_expired_receipt_info"`

	// BID is the app bundle ID
	BID string `json:"bid,omitempty"`
	// BVRS is the app bundle version
	BVRS string `json:"bvrs,omitempty"`

	// Posted only if the notification_type is CANCEL.
	CancellationDate
}
<|endoftext|>


<commit_before>package dbus

import (
	"reflect"
	"strings"
)

var (
	byteType       = reflect.TypeOf(byte(0))
	boolType       = reflect.TypeOf(false)
	uint8Type      = reflect.TypeOf(uint8(0))
	int16Type      = reflect.TypeOf(int16(0))
	uint16Type     = reflect.TypeOf(uint16(0))
	int32Type      = reflect.TypeOf(int32(0))
	uint32Type     = reflect.TypeOf(uint32(0))
	int64Type      = reflect.TypeOf(int64(0))
	uint64Type     = reflect.TypeOf(uint64(0))
	float64Type    = reflect.TypeOf(float64(0))
	stringType     = reflect.TypeOf("")
	signatureType  = reflect.TypeOf(Signature{""})
	objectPathType = reflect.TypeOf(ObjectPath(""))
	variantType    = reflect.TypeOf(Variant{Signature{""}, nil})
	interfacesType = reflect.TypeOf([]interface{}{})
)

type invalidTypeError struct {
	reflect.Type
}

func (err invalidTypeError) Error() string {
	return "dbus: invalid type " + err.Type.String()
}

var sigToType = map[byte]reflect.Type{
	'y': byteType,
	'b': boolType,
	'n': int16Type,
	'q': uint16Type,
	'i': int32Type,
	'u': uint32Type,
	'x': int64Type,
	't': uint64Type,
	'd': float64Type,
	's': stringType,
	'g': signatureType,
	'o': objectPathType,
	'v': variantType,
}

// Signature represents a correct type signature as specified
// by the DBus specification.
type Signature struct {
	str string
}

// GetSignature returns the concatenation of all the signatures
// of the given values. It panics if one of them is not representable
// in DBus.
func GetSignature(vs ...interface{}) Signature {
	var s string
	for _, v := range vs {
		s += getSignature(reflect.TypeOf(v))
	}
	return Signature{s}
}

func getSignature(v reflect.Type) string {
	// handle simple types first
	switch v.Kind() {
	case reflect.Uint8:
		return "y"
	case reflect.Bool:
		return "b"
	case reflect.Int16:
		return "n"
	case reflect.Uint16:
		return "q"
	case reflect.Int32, reflect.Int:
		return "i"
	case reflect.Uint32, reflect.Uint:
		return "u"
	case reflect.Int64:
		return "x"
	case reflect.Uint64:
		return "t"
	case reflect.Float64:
		return "d"
	case reflect.Ptr:
		return getSignature(v.Elem())
	case reflect.String:
		if v == objectPathType {
			return "o"
		}
		return "s"
	case reflect.Struct:
		if v == variantType {
			return "v"
		} else if v == signatureType {
			return "g"
		}
		var s string
		for i := 0; i < v.NumField(); i++ {
			s += getSignature(v.Field(i).Type)
		}
		return "(" + s + ")"
	case reflect.Array, reflect.Slice:
		return "a" + getSignature(v.Elem())
	case reflect.Map:
		return "a{" + getSignature(v.Key()) + getSignature(v.Elem()) + "}"
	}
	panic("unknown type " + v.String())
}

// StringToSig returns the signature represented by this string, or a
// SignatureError if the string is not a valid signature.
func StringToSig(s string) (sig Signature, err error) {
	if len(s) == 0 {
		return
	}
	sig.str = s
	for err == nil && len(s) != 0 {
		err, s = validSingle(s)
	}
	if err != nil {
		sig = Signature{""}
	}

	return
}

// SrintToSigMust behaves like StringToSig, except that it panics if s is not
// valid.
func StringToSigMust(s string) Signature {
	sig, err := StringToSig(s)
	if err != nil {
		panic(err)
	}
	return sig
}

// Empty retruns whether the signature is the empty signature.
func (s Signature) Empty() bool {
	return s.str == ""
}

// Single returns whether the signature represents a single, complete type.
func (s Signature) Single() bool {
	_, r := validSingle(s.str)
	return r == ""
}

// String returns the signature's string representation.
func (s Signature) String() string {
	return s.str
}

// Values returns a slice of pointers to values that match the given signature.
func (s Signature) Values() []interface{} {
	slice := make([]interface{}, 0)
	str := s.str
	for str != "" {
		slice = append(slice, reflect.New(value(str)).Interface())
		_, str = validSingle(str)
	}
	return slice
}

// A SignatureError indicates that a signature passed to a function or received
// on a connection is not a valid signature.
type SignatureError struct {
	Sig    string
	Reason string
}

func (err SignatureError) Error() string {
	return "invalid signature: '" + err.Sig + "' (" + err.Reason + ")"
}

// An ObjectPath is an object path as defined by the DBus spec.
type ObjectPath string

// IsValid returns whether the path is valid.
func (o ObjectPath) IsValid() bool {
	s := string(o)
	if len(s) == 0 {
		return false
	}
	if s[0] != '/' {
		return false
	}
	if s[len(s)-1] == '/' && len(s) != 1 {
		return false
	}
	// probably not used, but technically possible
	if s == "/" {
		return true
	}
	split := strings.Split(s[1:], "/")
	for _, v := range split {
		if len(v) == 0 {
			return false
		}
		for _, c := range v {
			if !((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') ||
				(c >= 'a' && c <= 'z') || c == '_') {

				return false
			}
		}
	}
	return true
}

// Variant represents a DBus variant type.
type Variant struct {
	sig   Signature
	value interface{}
}

// MakeVariant converts the given value to a Variant.
func MakeVariant(v interface{}) Variant {
	return Variant{GetSignature(v), v}
}

// Signature returns the DBus signature of the underlying value of v.
func (v Variant) Signature() Signature {
	return v.sig
}

// Value returns the underlying value of v.
func (v Variant) Value() interface{} {
	return v.value
}

func alignment(t reflect.Type) int {
	n, ok := map[reflect.Type]int{
		variantType:    1,
		objectPathType: 4,
		signatureType:  1,
	}[t]
	if ok {
		return n
	}
	switch t.Kind() {
	case reflect.Uint8:
		return 1
	case reflect.Uint16, reflect.Int16:
		return 2
	case reflect.Uint32, reflect.Int32, reflect.String, reflect.Array, reflect.Slice:
		return 4
	case reflect.Uint64, reflect.Int64, reflect.Float64, reflect.Struct:
		return 8
	case reflect.Ptr:
		return alignment(t.Elem())
	}
	return 1
}

func isKeyType(t reflect.Type) bool {
	switch t.Kind() {
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
		reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float64,
		reflect.String:

		return true
	}
	return false
}

// Try to read a single type from this string. If it was successfull, valid is
// true and r is the remaining unparsed part. Otherwise, valid is false and r is
// "".
func validSingle(s string) (err error, rem string) {
	if s == "" {
		return SignatureError{Sig: s, Reason: "empty signature"}, ""
	}
	switch s[0] {
	case 'y', 'b', 'n', 'q', 'i', 'u', 'x', 't', 'd', 's', 'g', 'o', 'v':
		return nil, s[1:]
	case 'a':
		if len(s) > 1 && s[1] == '{' {
			i := strings.LastIndex(s, "}")
			if i == -1 {
				return SignatureError{Sig: s, Reason: "unmatched '{'"}, ""
			}
			rem = s[i+1:]
			s = s[2:i]
			if err, _ = validSingle(s[0:1]); err != nil {
				return SignatureError{Sig: s, Reason: "invalid map key type"}, ""
			}
			err, nr := validSingle(s[1:])
			if err != nil {
				return err, ""
			}
			if nr != "" {
				return SignatureError{Sig: s, Reason: "too many types in dict"}, ""
			}
			return nil, rem
		}
		return validSingle(s[1:])
	case '(':
		i := strings.LastIndex(s, ")")
		if i == -1 {
			return SignatureError{Sig: s, Reason: "unmatched ')'"}, ""
		}
		rem = s[i+1:]
		s = s[1:i]
		for err == nil && s != "" {
			err, s = validSingle(s)
		}
		if err != nil {
			rem = ""
		}
		return
	}
	return SignatureError{Sig: s, Reason: "invalid type character"}, ""
}

// value returns the type of the given signature. It ignores any left over
// characters and panics if s doesn't start with a valid type signature.
func value(s string) (t reflect.Type) {
	err, _ := validSingle(s)
	if err != nil {
		panic(err)
	}

	if t, ok := sigToType[s[0]]; ok {
		return t
	}
	switch s[0] {
	case 'a':
		if s[1] == '{' {
			i := strings.LastIndex(s, "}")
			t = reflect.MapOf(sigToType[s[2]], value(s[3:i]))
		} else if s[1] == '(' {
			t = interfacesType
		} else {
			t = reflect.SliceOf(sigToType[s[1]])
		}
	case '(':
		t = interfacesType
	}
	return
}
<commit_msg>Don't allow signatures longer than 255 chars<commit_after>package dbus

import (
	"reflect"
	"strings"
)

var (
	byteType       = reflect.TypeOf(byte(0))
	boolType       = reflect.TypeOf(false)
	uint8Type      = reflect.TypeOf(uint8(0))
	int16Type      = reflect.TypeOf(int16(0))
	uint16Type     = reflect.TypeOf(uint16(0))
	int32Type      = reflect.TypeOf(int32(0))
	uint32Type     = reflect.TypeOf(uint32(0))
	int64Type      = reflect.TypeOf(int64(0))
	uint64Type     = reflect.TypeOf(uint64(0))
	float64Type    = reflect.TypeOf(float64(0))
	stringType     = reflect.TypeOf("")
	signatureType  = reflect.TypeOf(Signature{""})
	objectPathType = reflect.TypeOf(ObjectPath(""))
	variantType    = reflect.TypeOf(Variant{Signature{""}, nil})
	interfacesType = reflect.TypeOf([]interface{}{})
)

type invalidTypeError struct {
	reflect.Type
}

func (err invalidTypeError) Error() string {
	return "dbus: invalid type " + err.Type.String()
}

var sigToType = map[byte]reflect.Type{
	'y': byteType,
	'b': boolType,
	'n': int16Type,
	'q': uint16Type,
	'i': int32Type,
	'u': uint32Type,
	'x': int64Type,
	't': uint64Type,
	'd': float64Type,
	's': stringType,
	'g': signatureType,
	'o': objectPathType,
	'v': variantType,
}

// Signature represents a correct type signature as specified
// by the DBus specification.
type Signature struct {
	str string
}

// GetSignature returns the concatenation of all the signatures
// of the given values. It panics if one of them is not representable
// in DBus.
func GetSignature(vs ...interface{}) Signature {
	var s string
	for _, v := range vs {
		s += getSignature(reflect.TypeOf(v))
	}
	return Signature{s}
}

func getSignature(v reflect.Type) string {
	// handle simple types first
	switch v.Kind() {
	case reflect.Uint8:
		return "y"
	case reflect.Bool:
		return "b"
	case reflect.Int16:
		return "n"
	case reflect.Uint16:
		return "q"
	case reflect.Int32, reflect.Int:
		return "i"
	case reflect.Uint32, reflect.Uint:
		return "u"
	case reflect.Int64:
		return "x"
	case reflect.Uint64:
		return "t"
	case reflect.Float64:
		return "d"
	case reflect.Ptr:
		return getSignature(v.Elem())
	case reflect.String:
		if v == objectPathType {
			return "o"
		}
		return "s"
	case reflect.Struct:
		if v == variantType {
			return "v"
		} else if v == signatureType {
			return "g"
		}
		var s string
		for i := 0; i < v.NumField(); i++ {
			s += getSignature(v.Field(i).Type)
		}
		return "(" + s + ")"
	case reflect.Array, reflect.Slice:
		return "a" + getSignature(v.Elem())
	case reflect.Map:
		return "a{" + getSignature(v.Key()) + getSignature(v.Elem()) + "}"
	}
	panic("unknown type " + v.String())
}

// StringToSig returns the signature represented by this string, or a
// SignatureError if the string is not a valid signature.
func StringToSig(s string) (sig Signature, err error) {
	if len(s) == 0 {
		return
	}
	if len(s) > 255 {
		return Signature{""}, SignatureError{s, "too long"}
	}
	sig.str = s
	for err == nil && len(s) != 0 {
		err, s = validSingle(s)
	}
	if err != nil {
		sig = Signature{""}
	}

	return
}

// SrintToSigMust behaves like StringToSig, except that it panics if s is not
// valid.
func StringToSigMust(s string) Signature {
	sig, err := StringToSig(s)
	if err != nil {
		panic(err)
	}
	return sig
}

// Empty retruns whether the signature is the empty signature.
func (s Signature) Empty() bool {
	return s.str == ""
}

// Single returns whether the signature represents a single, complete type.
func (s Signature) Single() bool {
	_, r := validSingle(s.str)
	return r == ""
}

// String returns the signature's string representation.
func (s Signature) String() string {
	return s.str
}

// Values returns a slice of pointers to values that match the given signature.
func (s Signature) Values() []interface{} {
	slice := make([]interface{}, 0)
	str := s.str
	for str != "" {
		slice = append(slice, reflect.New(value(str)).Interface())
		_, str = validSingle(str)
	}
	return slice
}

// A SignatureError indicates that a signature passed to a function or received
// on a connection is not a valid signature.
type SignatureError struct {
	Sig    string
	Reason string
}

func (err SignatureError) Error() string {
	return "invalid signature: '" + err.Sig + "' (" + err.Reason + ")"
}

// An ObjectPath is an object path as defined by the DBus spec.
type ObjectPath string

// IsValid returns whether the path is valid.
func (o ObjectPath) IsValid() bool {
	s := string(o)
	if len(s) == 0 {
		return false
	}
	if s[0] != '/' {
		return false
	}
	if s[len(s)-1] == '/' && len(s) != 1 {
		return false
	}
	// probably not used, but technically possible
	if s == "/" {
		return true
	}
	split := strings.Split(s[1:], "/")
	for _, v := range split {
		if len(v) == 0 {
			return false
		}
		for _, c := range v {
			if !((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') ||
				(c >= 'a' && c <= 'z') || c == '_') {

				return false
			}
		}
	}
	return true
}

// Variant represents a DBus variant type.
type Variant struct {
	sig   Signature
	value interface{}
}

// MakeVariant converts the given value to a Variant.
func MakeVariant(v interface{}) Variant {
	return Variant{GetSignature(v), v}
}

// Signature returns the DBus signature of the underlying value of v.
func (v Variant) Signature() Signature {
	return v.sig
}

// Value returns the underlying value of v.
func (v Variant) Value() interface{} {
	return v.value
}

func alignment(t reflect.Type) int {
	n, ok := map[reflect.Type]int{
		variantType:    1,
		objectPathType: 4,
		signatureType:  1,
	}[t]
	if ok {
		return n
	}
	switch t.Kind() {
	case reflect.Uint8:
		return 1
	case reflect.Uint16, reflect.Int16:
		return 2
	case reflect.Uint32, reflect.Int32, reflect.String, reflect.Array, reflect.Slice:
		return 4
	case reflect.Uint64, reflect.Int64, reflect.Float64, reflect.Struct:
		return 8
	case reflect.Ptr:
		return alignment(t.Elem())
	}
	return 1
}

func isKeyType(t reflect.Type) bool {
	switch t.Kind() {
	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64,
		reflect.Int16, reflect.Int32, reflect.Int64, reflect.Float64,
		reflect.String:

		return true
	}
	return false
}

// Try to read a single type from this string. If it was successfull, valid is
// true and r is the remaining unparsed part. Otherwise, valid is false and r is
// "".
func validSingle(s string) (err error, rem string) {
	if s == "" {
		return SignatureError{Sig: s, Reason: "empty signature"}, ""
	}
	switch s[0] {
	case 'y', 'b', 'n', 'q', 'i', 'u', 'x', 't', 'd', 's', 'g', 'o', 'v':
		return nil, s[1:]
	case 'a':
		if len(s) > 1 && s[1] == '{' {
			i := strings.LastIndex(s, "}")
			if i == -1 {
				return SignatureError{Sig: s, Reason: "unmatched '{'"}, ""
			}
			rem = s[i+1:]
			s = s[2:i]
			if err, _ = validSingle(s[0:1]); err != nil {
				return SignatureError{Sig: s, Reason: "invalid map key type"}, ""
			}
			err, nr := validSingle(s[1:])
			if err != nil {
				return err, ""
			}
			if nr != "" {
				return SignatureError{Sig: s, Reason: "too many types in dict"}, ""
			}
			return nil, rem
		}
		return validSingle(s[1:])
	case '(':
		i := strings.LastIndex(s, ")")
		if i == -1 {
			return SignatureError{Sig: s, Reason: "unmatched ')'"}, ""
		}
		rem = s[i+1:]
		s = s[1:i]
		for err == nil && s != "" {
			err, s = validSingle(s)
		}
		if err != nil {
			rem = ""
		}
		return
	}
	return SignatureError{Sig: s, Reason: "invalid type character"}, ""
}

// value returns the type of the given signature. It ignores any left over
// characters and panics if s doesn't start with a valid type signature.
func value(s string) (t reflect.Type) {
	err, _ := validSingle(s)
	if err != nil {
		panic(err)
	}

	if t, ok := sigToType[s[0]]; ok {
		return t
	}
	switch s[0] {
	case 'a':
		if s[1] == '{' {
			i := strings.LastIndex(s, "}")
			t = reflect.MapOf(sigToType[s[2]], value(s[3:i]))
		} else if s[1] == '(' {
			t = interfacesType
		} else {
			t = reflect.SliceOf(sigToType[s[1]])
		}
	case '(':
		t = interfacesType
	}
	return
}
<|endoftext|>