<commit_before>// Copyright 2016 Keybase Inc. All rights reserved.
// Use of this source code is governed by a BSD
// license that can be found in the LICENSE file.

package kbfsblock

import (
	"encoding/hex"
	"fmt"

	"github.com/keybase/client/go/protocol/keybase1"
	"github.com/keybase/kbfs/kbfscrypto"
)

// RefNonce is a 64-bit unique sequence of bytes for identifying this
// reference of a block ID from other references to the same
// (duplicated) block.
type RefNonce [8]byte

// ZeroRefNonce is a special BlockRefNonce used for the initial
// reference to a block.
var ZeroRefNonce = RefNonce([8]byte{0, 0, 0, 0, 0, 0, 0, 0})

func (nonce RefNonce) String() string {
	return hex.EncodeToString(nonce[:])
}

// MakeRefNonce generates a non-zero block reference nonce using a
// CSPRNG. This is used for distinguishing different references to the
// same ID.
func MakeRefNonce() (RefNonce, error) {
	var nonce RefNonce
	for nonce == ZeroRefNonce {
		err := kbfscrypto.RandRead(nonce[:])
		if err != nil {
			return ZeroRefNonce, err
		}
	}
	return nonce, nil
}

// Context contains all the information used by the server to identify
// blocks (other than the ID).
//
// NOTE: Don't add or modify anything in this struct without
// considering how old clients will handle them.
type Context struct {
	// Creator is the UID that was first charged for the initial
	// reference to this block.
	Creator keybase1.UserOrTeamID `codec:"c"`
	// Writer is the UID that should be charged for this reference to
	// the block.  If empty, it defaults to Creator.
	Writer keybase1.UserOrTeamID `codec:"w,omitempty"`
	// When RefNonce is all 0s, this is the initial reference to a
	// particular block.  Using a constant refnonce for the initial
	// reference allows the server to identify and optimize for the
	// common case where there is only one reference for a block.  Two
	// initial references cannot happen simultaneously, because the
	// encrypted block contents (and thus the block ID) will be
	// randomized by the server-side block crypt key half.  All
	// subsequent references to the same block must have a random
	// RefNonce (it can't be a monotonically increasing number because
	// that would require coordination among clients).
	RefNonce RefNonce `codec:"r,omitempty"`
	// BlockType indicates the type of the block (data
	// vs. metadata). This is used, for example, when deciding how the
	// block affects quotas.
	BlockType keybase1.BlockType `codec:"b,omitempty"`
}

// MakeFirstContext makes the initial context for a block with the
// given creator.
func MakeFirstContext(
	creator keybase1.UserOrTeamID, bType keybase1.BlockType) Context {
	return Context{Creator: creator, BlockType: bType}
}

// MakeContext makes a context with the given creator, writer, and
// nonce, where the writer is not necessarily equal to the creator,
// and the nonce is usually non-zero.
func MakeContext(
	creator keybase1.UserOrTeamID, writer keybase1.UserOrTeamID, nonce RefNonce,
	bType keybase1.BlockType) Context {
	return Context{
		Creator:   creator,
		Writer:    writer,
		RefNonce:  nonce,
		BlockType: bType,
	}
}

// GetCreator returns the creator of the associated block.
func (c Context) GetCreator() keybase1.UserOrTeamID {
	return c.Creator
}

// GetWriter returns the writer of the associated block.
func (c Context) GetWriter() keybase1.UserOrTeamID {
	if !c.Writer.IsNil() {
		return c.Writer
	}
	return c.Creator
}

// SetWriter sets the Writer field, if necessary.
func (c *Context) SetWriter(newWriter keybase1.UserOrTeamID) {
	if c.Creator != newWriter {
		c.Writer = newWriter
	} else {
		// save some bytes by not populating the separate Writer
		// field if it matches the creator.
		c.Writer = ""
	}
}

// GetRefNonce returns the ref nonce of the associated block.
func (c Context) GetRefNonce() RefNonce {
	return c.RefNonce
}

// GetBlockType returns the block type of the associated block.
func (c Context) GetBlockType() keybase1.BlockType {
	return c.BlockType
}

// IsFirstRef returns whether or not p represents the first reference
// to the corresponding ID.
func (c Context) IsFirstRef() bool {
	return c.RefNonce == ZeroRefNonce
}

func (c Context) String() string {
	if c == (Context{}) {
		return "Context{}"
	}
	s := fmt.Sprintf("Context{Creator: %s", c.Creator)
	if len(c.Writer) > 0 {
		s += fmt.Sprintf(", Writer: %s", c.Writer)
	}
	if c.RefNonce != ZeroRefNonce {
		s += fmt.Sprintf(", RefNonce: %s", c.RefNonce)
	}
	if c.BlockType != keybase1.BlockType_DATA {
		s += ", BlockType: " + c.BlockType.String()
	}
	s += "}"
	return s
}

// ContextMap is a map from a block ID to a list of its contexts.
type ContextMap map[ID][]Context
<commit_msg>kbfsblock: allow writer to be empty in json<commit_after>// Copyright 2016 Keybase Inc. All rights reserved.
// Use of this source code is governed by a BSD
// license that can be found in the LICENSE file.

package kbfsblock

import (
	"encoding/hex"
	"fmt"

	"github.com/keybase/client/go/protocol/keybase1"
	"github.com/keybase/kbfs/kbfscrypto"
)

// RefNonce is a 64-bit unique sequence of bytes for identifying this
// reference of a block ID from other references to the same
// (duplicated) block.
type RefNonce [8]byte

// ZeroRefNonce is a special BlockRefNonce used for the initial
// reference to a block.
var ZeroRefNonce = RefNonce([8]byte{0, 0, 0, 0, 0, 0, 0, 0})

func (nonce RefNonce) String() string {
	return hex.EncodeToString(nonce[:])
}

// MakeRefNonce generates a non-zero block reference nonce using a
// CSPRNG. This is used for distinguishing different references to the
// same ID.
func MakeRefNonce() (RefNonce, error) {
	var nonce RefNonce
	for nonce == ZeroRefNonce {
		err := kbfscrypto.RandRead(nonce[:])
		if err != nil {
			return ZeroRefNonce, err
		}
	}
	return nonce, nil
}

// Context contains all the information used by the server to identify
// blocks (other than the ID).
//
// NOTE: Don't add or modify anything in this struct without
// considering how old clients will handle them.
type Context struct {
	// Creator is the UID that was first charged for the initial
	// reference to this block.
	Creator keybase1.UserOrTeamID `codec:"c"`
	// Writer is the UID that should be charged for this reference to
	// the block.  If empty, it defaults to Creator.
	Writer keybase1.UserOrTeamID `codec:"w,omitempty" json:",omitempty"`
	// When RefNonce is all 0s, this is the initial reference to a
	// particular block.  Using a constant refnonce for the initial
	// reference allows the server to identify and optimize for the
	// common case where there is only one reference for a block.  Two
	// initial references cannot happen simultaneously, because the
	// encrypted block contents (and thus the block ID) will be
	// randomized by the server-side block crypt key half.  All
	// subsequent references to the same block must have a random
	// RefNonce (it can't be a monotonically increasing number because
	// that would require coordination among clients).
	RefNonce RefNonce `codec:"r,omitempty"`
	// BlockType indicates the type of the block (data
	// vs. metadata). This is used, for example, when deciding how the
	// block affects quotas.
	BlockType keybase1.BlockType `codec:"b,omitempty"`
}

// MakeFirstContext makes the initial context for a block with the
// given creator.
func MakeFirstContext(
	creator keybase1.UserOrTeamID, bType keybase1.BlockType) Context {
	return Context{Creator: creator, BlockType: bType}
}

// MakeContext makes a context with the given creator, writer, and
// nonce, where the writer is not necessarily equal to the creator,
// and the nonce is usually non-zero.
func MakeContext(
	creator keybase1.UserOrTeamID, writer keybase1.UserOrTeamID, nonce RefNonce,
	bType keybase1.BlockType) Context {
	return Context{
		Creator:   creator,
		Writer:    writer,
		RefNonce:  nonce,
		BlockType: bType,
	}
}

// GetCreator returns the creator of the associated block.
func (c Context) GetCreator() keybase1.UserOrTeamID {
	return c.Creator
}

// GetWriter returns the writer of the associated block.
func (c Context) GetWriter() keybase1.UserOrTeamID {
	if !c.Writer.IsNil() {
		return c.Writer
	}
	return c.Creator
}

// SetWriter sets the Writer field, if necessary.
func (c *Context) SetWriter(newWriter keybase1.UserOrTeamID) {
	if c.Creator != newWriter {
		c.Writer = newWriter
	} else {
		// save some bytes by not populating the separate Writer
		// field if it matches the creator.
		c.Writer = ""
	}
}

// GetRefNonce returns the ref nonce of the associated block.
func (c Context) GetRefNonce() RefNonce {
	return c.RefNonce
}

// GetBlockType returns the block type of the associated block.
func (c Context) GetBlockType() keybase1.BlockType {
	return c.BlockType
}

// IsFirstRef returns whether or not p represents the first reference
// to the corresponding ID.
func (c Context) IsFirstRef() bool {
	return c.RefNonce == ZeroRefNonce
}

func (c Context) String() string {
	if c == (Context{}) {
		return "Context{}"
	}
	s := fmt.Sprintf("Context{Creator: %s", c.Creator)
	if len(c.Writer) > 0 {
		s += fmt.Sprintf(", Writer: %s", c.Writer)
	}
	if c.RefNonce != ZeroRefNonce {
		s += fmt.Sprintf(", RefNonce: %s", c.RefNonce)
	}
	if c.BlockType != keybase1.BlockType_DATA {
		s += ", BlockType: " + c.BlockType.String()
	}
	s += "}"
	return s
}

// ContextMap is a map from a block ID to a list of its contexts.
type ContextMap map[ID][]Context
<|endoftext|>


<commit_before>// Copyright 2016 Keybase Inc. All rights reserved.
// Use of this source code is governed by a BSD
// license that can be found in the LICENSE file.

package kbfsblock

import (
	"encoding/hex"
	"fmt"

	"github.com/keybase/client/go/protocol/keybase1"
	"github.com/keybase/kbfs/kbfscrypto"
)

// RefNonce is a 64-bit unique sequence of bytes for identifying this
// reference of a block ID from other references to the same
// (duplicated) block.
type RefNonce [8]byte

// ZeroRefNonce is a special BlockRefNonce used for the initial
// reference to a block.
var ZeroRefNonce = RefNonce([8]byte{0, 0, 0, 0, 0, 0, 0, 0})

func (nonce RefNonce) String() string {
	return hex.EncodeToString(nonce[:])
}

// MakeRefNonce generates a non-zero block reference nonce using a
// CSPRNG. This is used for distinguishing different references to the
// same ID.
func MakeRefNonce() (RefNonce, error) {
	var nonce RefNonce
	for nonce == ZeroRefNonce {
		err := kbfscrypto.RandRead(nonce[:])
		if err != nil {
			return ZeroRefNonce, err
		}
	}
	return nonce, nil
}

// Context contains all the information used by the server to identify
// blocks (other than the ID).
//
// NOTE: Don't add or modify anything in this struct without
// considering how old clients will handle them.
type Context struct {
	// Creator is the UID that was first charged for the initial
	// reference to this block.
	Creator keybase1.UserOrTeamID `codec:"c"`
	// Writer is the UID that should be charged for this reference to
	// the block.  If empty, it defaults to Creator.
	Writer keybase1.UserOrTeamID `codec:"w,omitempty"`
	// When RefNonce is all 0s, this is the initial reference to a
	// particular block.  Using a constant refnonce for the initial
	// reference allows the server to identify and optimize for the
	// common case where there is only one reference for a block.  Two
	// initial references cannot happen simultaneously, because the
	// encrypted block contents (and thus the block ID) will be
	// randomized by the server-side block crypt key half.  All
	// subsequent references to the same block must have a random
	// RefNonce (it can't be a monotonically increasing number because
	// that would require coordination among clients).
	RefNonce RefNonce `codec:"r,omitempty"`
	// BlockType indicates the type of the block (data
	// vs. metadata). This is used, for example, when deciding how the
	// block affects quotas.
	BlockType keybase1.BlockType `codec:"b,omitempty"`
}

// MakeFirstContext makes the initial context for a block with the
// given creator.
func MakeFirstContext(
	creator keybase1.UserOrTeamID, bType keybase1.BlockType) Context {
	return Context{Creator: creator, BlockType: bType}
}

// MakeContext makes a context with the given creator, writer, and
// nonce, where the writer is not necessarily equal to the creator,
// and the nonce is usually non-zero.
func MakeContext(
	creator keybase1.UserOrTeamID, writer keybase1.UserOrTeamID, nonce RefNonce,
	bType keybase1.BlockType) Context {
	return Context{
		Creator:   creator,
		Writer:    writer,
		RefNonce:  nonce,
		BlockType: bType,
	}
}

// GetCreator returns the creator of the associated block.
func (c Context) GetCreator() keybase1.UserOrTeamID {
	return c.Creator
}

// GetWriter returns the writer of the associated block.
func (c Context) GetWriter() keybase1.UserOrTeamID {
	if !c.Writer.IsNil() {
		return c.Writer
	}
	return c.Creator
}

// SetWriter sets the Writer field, if necessary.
func (c *Context) SetWriter(newWriter keybase1.UserOrTeamID) {
	if c.Creator != newWriter {
		c.Writer = newWriter
	} else {
		// save some bytes by not populating the separate Writer
		// field if it matches the creator.
		c.Writer = ""
	}
}

// GetRefNonce returns the ref nonce of the associated block.
func (c Context) GetRefNonce() RefNonce {
	return c.RefNonce
}

// GetBlockType returns the block type of the associated block.
func (c Context) GetBlockType() keybase1.BlockType {
	return c.BlockType
}

// IsFirstRef returns whether or not p represents the first reference
// to the corresponding ID.
func (c Context) IsFirstRef() bool {
	return c.RefNonce == ZeroRefNonce
}

func (c Context) String() string {
	if c == (Context{}) {
		return "Context{}"
	}
	s := fmt.Sprintf("Context{Creator: %s", c.Creator)
	if len(c.Writer) > 0 {
		s += fmt.Sprintf(", Writer: %s", c.Writer)
	}
	if c.RefNonce != ZeroRefNonce {
		s += fmt.Sprintf(", RefNonce: %s", c.RefNonce)
	}
	if c.BlockType != keybase1.BlockType_DATA {
		s += ", BlockType: MD"
	}
	s += "}"
	return s
}

// ContextMap is a map from a block ID to a list of its contexts.
type ContextMap map[ID][]Context
<commit_msg>kbfsblock: include right type for non-data blocks in strings<commit_after>// Copyright 2016 Keybase Inc. All rights reserved.
// Use of this source code is governed by a BSD
// license that can be found in the LICENSE file.

package kbfsblock

import (
	"encoding/hex"
	"fmt"

	"github.com/keybase/client/go/protocol/keybase1"
	"github.com/keybase/kbfs/kbfscrypto"
)

// RefNonce is a 64-bit unique sequence of bytes for identifying this
// reference of a block ID from other references to the same
// (duplicated) block.
type RefNonce [8]byte

// ZeroRefNonce is a special BlockRefNonce used for the initial
// reference to a block.
var ZeroRefNonce = RefNonce([8]byte{0, 0, 0, 0, 0, 0, 0, 0})

func (nonce RefNonce) String() string {
	return hex.EncodeToString(nonce[:])
}

// MakeRefNonce generates a non-zero block reference nonce using a
// CSPRNG. This is used for distinguishing different references to the
// same ID.
func MakeRefNonce() (RefNonce, error) {
	var nonce RefNonce
	for nonce == ZeroRefNonce {
		err := kbfscrypto.RandRead(nonce[:])
		if err != nil {
			return ZeroRefNonce, err
		}
	}
	return nonce, nil
}

// Context contains all the information used by the server to identify
// blocks (other than the ID).
//
// NOTE: Don't add or modify anything in this struct without
// considering how old clients will handle them.
type Context struct {
	// Creator is the UID that was first charged for the initial
	// reference to this block.
	Creator keybase1.UserOrTeamID `codec:"c"`
	// Writer is the UID that should be charged for this reference to
	// the block.  If empty, it defaults to Creator.
	Writer keybase1.UserOrTeamID `codec:"w,omitempty"`
	// When RefNonce is all 0s, this is the initial reference to a
	// particular block.  Using a constant refnonce for the initial
	// reference allows the server to identify and optimize for the
	// common case where there is only one reference for a block.  Two
	// initial references cannot happen simultaneously, because the
	// encrypted block contents (and thus the block ID) will be
	// randomized by the server-side block crypt key half.  All
	// subsequent references to the same block must have a random
	// RefNonce (it can't be a monotonically increasing number because
	// that would require coordination among clients).
	RefNonce RefNonce `codec:"r,omitempty"`
	// BlockType indicates the type of the block (data
	// vs. metadata). This is used, for example, when deciding how the
	// block affects quotas.
	BlockType keybase1.BlockType `codec:"b,omitempty"`
}

// MakeFirstContext makes the initial context for a block with the
// given creator.
func MakeFirstContext(
	creator keybase1.UserOrTeamID, bType keybase1.BlockType) Context {
	return Context{Creator: creator, BlockType: bType}
}

// MakeContext makes a context with the given creator, writer, and
// nonce, where the writer is not necessarily equal to the creator,
// and the nonce is usually non-zero.
func MakeContext(
	creator keybase1.UserOrTeamID, writer keybase1.UserOrTeamID, nonce RefNonce,
	bType keybase1.BlockType) Context {
	return Context{
		Creator:   creator,
		Writer:    writer,
		RefNonce:  nonce,
		BlockType: bType,
	}
}

// GetCreator returns the creator of the associated block.
func (c Context) GetCreator() keybase1.UserOrTeamID {
	return c.Creator
}

// GetWriter returns the writer of the associated block.
func (c Context) GetWriter() keybase1.UserOrTeamID {
	if !c.Writer.IsNil() {
		return c.Writer
	}
	return c.Creator
}

// SetWriter sets the Writer field, if necessary.
func (c *Context) SetWriter(newWriter keybase1.UserOrTeamID) {
	if c.Creator != newWriter {
		c.Writer = newWriter
	} else {
		// save some bytes by not populating the separate Writer
		// field if it matches the creator.
		c.Writer = ""
	}
}

// GetRefNonce returns the ref nonce of the associated block.
func (c Context) GetRefNonce() RefNonce {
	return c.RefNonce
}

// GetBlockType returns the block type of the associated block.
func (c Context) GetBlockType() keybase1.BlockType {
	return c.BlockType
}

// IsFirstRef returns whether or not p represents the first reference
// to the corresponding ID.
func (c Context) IsFirstRef() bool {
	return c.RefNonce == ZeroRefNonce
}

func (c Context) String() string {
	if c == (Context{}) {
		return "Context{}"
	}
	s := fmt.Sprintf("Context{Creator: %s", c.Creator)
	if len(c.Writer) > 0 {
		s += fmt.Sprintf(", Writer: %s", c.Writer)
	}
	if c.RefNonce != ZeroRefNonce {
		s += fmt.Sprintf(", RefNonce: %s", c.RefNonce)
	}
	if c.BlockType != keybase1.BlockType_DATA {
		s += ", BlockType: " + c.BlockType.String()
	}
	s += "}"
	return s
}

// ContextMap is a map from a block ID to a list of its contexts.
type ContextMap map[ID][]Context
<|endoftext|>


<commit_before>/**
 *  Copyright 2014 Paul Querna
 *
 *  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 ffjsoninception

import (
	"fmt"
	"reflect"
	"strings"

	"github.com/pquerna/ffjson/shared"
)

var validValues []string = []string{
	"FFTok_left_brace",
	"FFTok_left_bracket",
	"FFTok_integer",
	"FFTok_double",
	"FFTok_string",
	"FFTok_bool",
	"FFTok_null",
}

func CreateUnmarshalJSON(ic *Inception, si *StructInfo) error {
	out := ""
	ic.OutputImports[`fflib "github.com/pquerna/ffjson/fflib/v1"`] = true
	if len(si.Fields) > 0 {
		ic.OutputImports[`"bytes"`] = true
	}
	ic.OutputImports[`"fmt"`] = true

	out += tplStr(decodeTpl["header"], header{
		IC: ic,
		SI: si,
	})

	out += tplStr(decodeTpl["ujFunc"], ujFunc{
		SI:          si,
		IC:          ic,
		ValidValues: validValues,
		ResetFields: ic.ResetFields,
	})

	ic.OutputFuncs = append(ic.OutputFuncs, out)

	return nil
}

func handleField(ic *Inception, name string, typ reflect.Type, ptr bool, quoted bool) string {
	return handleFieldAddr(ic, name, false, typ, ptr, quoted)
}

func handleFieldAddr(ic *Inception, name string, takeAddr bool, typ reflect.Type, ptr bool, quoted bool) string {
	out := fmt.Sprintf("/* handler: %s type=%v kind=%v quoted=%t*/\n", name, typ, typ.Kind(), quoted)

	umlx := typ.Implements(unmarshalFasterType) || typeInInception(ic, typ, shared.MustDecoder)
	umlx = umlx || reflect.PtrTo(typ).Implements(unmarshalFasterType)

	umlstd := typ.Implements(unmarshalerType) || reflect.PtrTo(typ).Implements(unmarshalerType)

	out += tplStr(decodeTpl["handleUnmarshaler"], handleUnmarshaler{
		IC:                   ic,
		Name:                 name,
		Typ:                  typ,
		Ptr:                  reflect.Ptr,
		TakeAddr:             takeAddr || ptr,
		UnmarshalJSONFFLexer: umlx,
		Unmarshaler:          umlstd,
	})

	if umlx || umlstd {
		return out
	}

	// TODO(pquerna): generic handling of token type mismatching struct type
	switch typ.Kind() {
	case reflect.Int,
		reflect.Int8,
		reflect.Int16,
		reflect.Int32,
		reflect.Int64:

		allowed := buildTokens(quoted, "FFTok_string", "FFTok_integer", "FFTok_null")
		out += getAllowTokens(typ.Name(), allowed...)

		out += getNumberHandler(ic, name, takeAddr || ptr, typ, "ParseInt")

	case reflect.Uint,
		reflect.Uint8,
		reflect.Uint16,
		reflect.Uint32,
		reflect.Uint64:

		allowed := buildTokens(quoted, "FFTok_string", "FFTok_integer", "FFTok_null")
		out += getAllowTokens(typ.Name(), allowed...)

		out += getNumberHandler(ic, name, takeAddr || ptr, typ, "ParseUint")

	case reflect.Float32,
		reflect.Float64:

		allowed := buildTokens(quoted, "FFTok_string", "FFTok_double", "FFTok_integer", "FFTok_null")
		out += getAllowTokens(typ.Name(), allowed...)

		out += getNumberHandler(ic, name, takeAddr || ptr, typ, "ParseFloat")

	case reflect.Bool:
		ic.OutputImports[`"bytes"`] = true
		ic.OutputImports[`"errors"`] = true

		allowed := buildTokens(quoted, "FFTok_string", "FFTok_bool", "FFTok_null")
		out += getAllowTokens(typ.Name(), allowed...)

		out += tplStr(decodeTpl["handleBool"], handleBool{
			Name:     name,
			Typ:      typ,
			TakeAddr: takeAddr || ptr,
		})

	case reflect.Ptr:
		out += tplStr(decodeTpl["handlePtr"], handlePtr{
			IC:     ic,
			Name:   name,
			Typ:    typ,
			Quoted: quoted,
		})

	case reflect.Array,
		reflect.Slice:
		out += getArrayHandler(ic, name, typ, ptr)

	case reflect.String:
		// Is it a json.Number?
		if typ.PkgPath() == "encoding/json" && typ.Name() == "Number" {
			// Fall back to json package to rely on the valid number check.
			// See: https://github.com/golang/go/blob/f05c3aa24d815cd3869153750c9875e35fc48a6e/src/encoding/json/decode.go#L897
			ic.OutputImports[`"encoding/json"`] = true
			out += tplStr(decodeTpl["handleFallback"], handleFallback{
				Name: name,
				Typ:  typ,
				Kind: typ.Kind(),
			})
		} else {
			out += tplStr(decodeTpl["handleString"], handleString{
				IC:       ic,
				Name:     name,
				Typ:      typ,
				TakeAddr: takeAddr || ptr,
				Quoted:   quoted,
			})
		}
	case reflect.Interface:
		ic.OutputImports[`"encoding/json"`] = true
		out += tplStr(decodeTpl["handleFallback"], handleFallback{
			Name: name,
			Typ:  typ,
			Kind: typ.Kind(),
		})
	case reflect.Map:
		out += tplStr(decodeTpl["handleObject"], handleObject{
			IC:       ic,
			Name:     name,
			Typ:      typ,
			Ptr:      reflect.Ptr,
			TakeAddr: takeAddr || ptr,
		})
	default:
		ic.OutputImports[`"encoding/json"`] = true
		out += tplStr(decodeTpl["handleFallback"], handleFallback{
			Name: name,
			Typ:  typ,
			Kind: typ.Kind(),
		})
	}

	return out
}

func getArrayHandler(ic *Inception, name string, typ reflect.Type, ptr bool) string {
	if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
		ic.OutputImports[`"encoding/base64"`] = true
		useReflectToSet := false
		if typ.Elem().Name() != "byte" {
			ic.OutputImports[`"reflect"`] = true
			useReflectToSet = true
		}

		return tplStr(decodeTpl["handleByteSlice"], handleArray{
			IC:              ic,
			Name:            name,
			Typ:             typ,
			Ptr:             reflect.Ptr,
			UseReflectToSet: useReflectToSet,
		})
	}

	if typ.Elem().Kind() == reflect.Struct && typ.Elem().Name() != "" {
		goto sliceOrArray
	}

	if (typ.Elem().Kind() == reflect.Struct || typ.Elem().Kind() == reflect.Map) ||
		typ.Elem().Kind() == reflect.Array || typ.Elem().Kind() == reflect.Slice &&
		typ.Elem().Name() == "" {
		ic.OutputImports[`"encoding/json"`] = true

		return tplStr(decodeTpl["handleFallback"], handleFallback{
			Name: name,
			Typ:  typ,
			Kind: typ.Kind(),
		})
	}

sliceOrArray:

	if typ.Kind() == reflect.Array {
		return tplStr(decodeTpl["handleArray"], handleArray{
			IC:    ic,
			Name:  name,
			Typ:   typ,
			IsPtr: ptr,
			Ptr:   reflect.Ptr,
		})
	}

	return tplStr(decodeTpl["handleSlice"], handleArray{
		IC:    ic,
		Name:  name,
		Typ:   typ,
		IsPtr: ptr,
		Ptr:   reflect.Ptr,
	})
}

func getAllowTokens(name string, tokens ...string) string {
	return tplStr(decodeTpl["allowTokens"], allowTokens{
		Name:   name,
		Tokens: tokens,
	})
}

func getNumberHandler(ic *Inception, name string, takeAddr bool, typ reflect.Type, parsefunc string) string {
	return tplStr(decodeTpl["handlerNumeric"], handlerNumeric{
		IC:        ic,
		Name:      name,
		ParseFunc: parsefunc,
		TakeAddr:  takeAddr,
		Typ:       typ,
	})
}

func getNumberSize(typ reflect.Type) string {
	return fmt.Sprintf("%d", typ.Bits())
}

func getType(ic *Inception, name string, typ reflect.Type) string {
	s := typ.Name()

	if typ.PkgPath() != "" && typ.PkgPath() != ic.PackagePath {
		path := removeVendor(typ.PkgPath())
		ic.OutputImports[`"`+path+`"`] = true
		s = typ.String()
	}

	if s == "" {
		return typ.String()
	}

	return s
}

// removeVendor removes everything before and including a '/vendor/'
// substring in the package path.
// This is needed becuase that full path can't be used in the
// import statement.
func removeVendor(path string) string {
	i := strings.Index(path, "/vendor/")
	if i == -1 {
		return path
	}
	return path[i+8:]
}

func buildTokens(containsOptional bool, optional string, required ...string) []string {
	if containsOptional {
		return append(required, optional)
	}

	return required
}

func unquoteField(quoted bool) string {
	// The outer quote of a string is already stripped out by
	// the lexer. We need to check if the inner string is also
	// quoted. If so, we will decode it as json string. If decoding
	// fails, we will use the original string
	if quoted {
		return `
		unquoted, ok := fflib.UnquoteBytes(outBuf)
		if ok {
			outBuf = unquoted
		}
		`
	}
	return ""
}

func getTmpVarFor(name string) string {
	return "tmp_" + strings.Replace(name, ".", "__", -1)
}
<commit_msg>remove _ from get tmp var<commit_after>/**
 *  Copyright 2014 Paul Querna
 *
 *  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 ffjsoninception

import (
	"fmt"
	"reflect"
	"strings"

	"github.com/pquerna/ffjson/shared"
)

var validValues []string = []string{
	"FFTok_left_brace",
	"FFTok_left_bracket",
	"FFTok_integer",
	"FFTok_double",
	"FFTok_string",
	"FFTok_bool",
	"FFTok_null",
}

func CreateUnmarshalJSON(ic *Inception, si *StructInfo) error {
	out := ""
	ic.OutputImports[`fflib "github.com/pquerna/ffjson/fflib/v1"`] = true
	if len(si.Fields) > 0 {
		ic.OutputImports[`"bytes"`] = true
	}
	ic.OutputImports[`"fmt"`] = true

	out += tplStr(decodeTpl["header"], header{
		IC: ic,
		SI: si,
	})

	out += tplStr(decodeTpl["ujFunc"], ujFunc{
		SI:          si,
		IC:          ic,
		ValidValues: validValues,
		ResetFields: ic.ResetFields,
	})

	ic.OutputFuncs = append(ic.OutputFuncs, out)

	return nil
}

func handleField(ic *Inception, name string, typ reflect.Type, ptr bool, quoted bool) string {
	return handleFieldAddr(ic, name, false, typ, ptr, quoted)
}

func handleFieldAddr(ic *Inception, name string, takeAddr bool, typ reflect.Type, ptr bool, quoted bool) string {
	out := fmt.Sprintf("/* handler: %s type=%v kind=%v quoted=%t*/\n", name, typ, typ.Kind(), quoted)

	umlx := typ.Implements(unmarshalFasterType) || typeInInception(ic, typ, shared.MustDecoder)
	umlx = umlx || reflect.PtrTo(typ).Implements(unmarshalFasterType)

	umlstd := typ.Implements(unmarshalerType) || reflect.PtrTo(typ).Implements(unmarshalerType)

	out += tplStr(decodeTpl["handleUnmarshaler"], handleUnmarshaler{
		IC:                   ic,
		Name:                 name,
		Typ:                  typ,
		Ptr:                  reflect.Ptr,
		TakeAddr:             takeAddr || ptr,
		UnmarshalJSONFFLexer: umlx,
		Unmarshaler:          umlstd,
	})

	if umlx || umlstd {
		return out
	}

	// TODO(pquerna): generic handling of token type mismatching struct type
	switch typ.Kind() {
	case reflect.Int,
		reflect.Int8,
		reflect.Int16,
		reflect.Int32,
		reflect.Int64:

		allowed := buildTokens(quoted, "FFTok_string", "FFTok_integer", "FFTok_null")
		out += getAllowTokens(typ.Name(), allowed...)

		out += getNumberHandler(ic, name, takeAddr || ptr, typ, "ParseInt")

	case reflect.Uint,
		reflect.Uint8,
		reflect.Uint16,
		reflect.Uint32,
		reflect.Uint64:

		allowed := buildTokens(quoted, "FFTok_string", "FFTok_integer", "FFTok_null")
		out += getAllowTokens(typ.Name(), allowed...)

		out += getNumberHandler(ic, name, takeAddr || ptr, typ, "ParseUint")

	case reflect.Float32,
		reflect.Float64:

		allowed := buildTokens(quoted, "FFTok_string", "FFTok_double", "FFTok_integer", "FFTok_null")
		out += getAllowTokens(typ.Name(), allowed...)

		out += getNumberHandler(ic, name, takeAddr || ptr, typ, "ParseFloat")

	case reflect.Bool:
		ic.OutputImports[`"bytes"`] = true
		ic.OutputImports[`"errors"`] = true

		allowed := buildTokens(quoted, "FFTok_string", "FFTok_bool", "FFTok_null")
		out += getAllowTokens(typ.Name(), allowed...)

		out += tplStr(decodeTpl["handleBool"], handleBool{
			Name:     name,
			Typ:      typ,
			TakeAddr: takeAddr || ptr,
		})

	case reflect.Ptr:
		out += tplStr(decodeTpl["handlePtr"], handlePtr{
			IC:     ic,
			Name:   name,
			Typ:    typ,
			Quoted: quoted,
		})

	case reflect.Array,
		reflect.Slice:
		out += getArrayHandler(ic, name, typ, ptr)

	case reflect.String:
		// Is it a json.Number?
		if typ.PkgPath() == "encoding/json" && typ.Name() == "Number" {
			// Fall back to json package to rely on the valid number check.
			// See: https://github.com/golang/go/blob/f05c3aa24d815cd3869153750c9875e35fc48a6e/src/encoding/json/decode.go#L897
			ic.OutputImports[`"encoding/json"`] = true
			out += tplStr(decodeTpl["handleFallback"], handleFallback{
				Name: name,
				Typ:  typ,
				Kind: typ.Kind(),
			})
		} else {
			out += tplStr(decodeTpl["handleString"], handleString{
				IC:       ic,
				Name:     name,
				Typ:      typ,
				TakeAddr: takeAddr || ptr,
				Quoted:   quoted,
			})
		}
	case reflect.Interface:
		ic.OutputImports[`"encoding/json"`] = true
		out += tplStr(decodeTpl["handleFallback"], handleFallback{
			Name: name,
			Typ:  typ,
			Kind: typ.Kind(),
		})
	case reflect.Map:
		out += tplStr(decodeTpl["handleObject"], handleObject{
			IC:       ic,
			Name:     name,
			Typ:      typ,
			Ptr:      reflect.Ptr,
			TakeAddr: takeAddr || ptr,
		})
	default:
		ic.OutputImports[`"encoding/json"`] = true
		out += tplStr(decodeTpl["handleFallback"], handleFallback{
			Name: name,
			Typ:  typ,
			Kind: typ.Kind(),
		})
	}

	return out
}

func getArrayHandler(ic *Inception, name string, typ reflect.Type, ptr bool) string {
	if typ.Kind() == reflect.Slice && typ.Elem().Kind() == reflect.Uint8 {
		ic.OutputImports[`"encoding/base64"`] = true
		useReflectToSet := false
		if typ.Elem().Name() != "byte" {
			ic.OutputImports[`"reflect"`] = true
			useReflectToSet = true
		}

		return tplStr(decodeTpl["handleByteSlice"], handleArray{
			IC:              ic,
			Name:            name,
			Typ:             typ,
			Ptr:             reflect.Ptr,
			UseReflectToSet: useReflectToSet,
		})
	}

	if typ.Elem().Kind() == reflect.Struct && typ.Elem().Name() != "" {
		goto sliceOrArray
	}

	if (typ.Elem().Kind() == reflect.Struct || typ.Elem().Kind() == reflect.Map) ||
		typ.Elem().Kind() == reflect.Array || typ.Elem().Kind() == reflect.Slice &&
		typ.Elem().Name() == "" {
		ic.OutputImports[`"encoding/json"`] = true

		return tplStr(decodeTpl["handleFallback"], handleFallback{
			Name: name,
			Typ:  typ,
			Kind: typ.Kind(),
		})
	}

sliceOrArray:

	if typ.Kind() == reflect.Array {
		return tplStr(decodeTpl["handleArray"], handleArray{
			IC:    ic,
			Name:  name,
			Typ:   typ,
			IsPtr: ptr,
			Ptr:   reflect.Ptr,
		})
	}

	return tplStr(decodeTpl["handleSlice"], handleArray{
		IC:    ic,
		Name:  name,
		Typ:   typ,
		IsPtr: ptr,
		Ptr:   reflect.Ptr,
	})
}

func getAllowTokens(name string, tokens ...string) string {
	return tplStr(decodeTpl["allowTokens"], allowTokens{
		Name:   name,
		Tokens: tokens,
	})
}

func getNumberHandler(ic *Inception, name string, takeAddr bool, typ reflect.Type, parsefunc string) string {
	return tplStr(decodeTpl["handlerNumeric"], handlerNumeric{
		IC:        ic,
		Name:      name,
		ParseFunc: parsefunc,
		TakeAddr:  takeAddr,
		Typ:       typ,
	})
}

func getNumberSize(typ reflect.Type) string {
	return fmt.Sprintf("%d", typ.Bits())
}

func getType(ic *Inception, name string, typ reflect.Type) string {
	s := typ.Name()

	if typ.PkgPath() != "" && typ.PkgPath() != ic.PackagePath {
		path := removeVendor(typ.PkgPath())
		ic.OutputImports[`"`+path+`"`] = true
		s = typ.String()
	}

	if s == "" {
		return typ.String()
	}

	return s
}

// removeVendor removes everything before and including a '/vendor/'
// substring in the package path.
// This is needed becuase that full path can't be used in the
// import statement.
func removeVendor(path string) string {
	i := strings.Index(path, "/vendor/")
	if i == -1 {
		return path
	}
	return path[i+8:]
}

func buildTokens(containsOptional bool, optional string, required ...string) []string {
	if containsOptional {
		return append(required, optional)
	}

	return required
}

func unquoteField(quoted bool) string {
	// The outer quote of a string is already stripped out by
	// the lexer. We need to check if the inner string is also
	// quoted. If so, we will decode it as json string. If decoding
	// fails, we will use the original string
	if quoted {
		return `
		unquoted, ok := fflib.UnquoteBytes(outBuf)
		if ok {
			outBuf = unquoted
		}
		`
	}
	return ""
}

func getTmpVarFor(name string) string {
	return "tmp" + strings.Replace(strings.Title(strings.Replace(name, ".", " ", -1)), " ", "", -1)
}
<|endoftext|>


<commit_before>package influxdb

import (
	"strings"
	"sync"
	"time"

	client "github.com/influxdata/influxdb/client/v2"
)

//InfluxDB is the interface to Influx instance
type InfluxDB struct {
	Port        string
	Host        string
	Precision   string
	Consistency string
	Client      client.Client
	Buffer      map[string]client.BatchPoints
	mutex       sync.Mutex
}

type registryMetaData struct {
	DB          string
	Retention   string
	Measurement string
	Tag         string
	TagValue    string
	Field       string
	FieldValue  interface{}
}

func New(host, port string) *InfluxDB {
	db := new(InfluxDB)
	db.Host = host
	db.Port = port
	db.Precision = "ns"
	db.Consistency = "any"
	db.Buffer = make(map[string]client.BatchPoints)
	db.Connect()
	return db
}

//Registry a new Point to InfluxDB
func (db *InfluxDB) Registry(tag string, value interface{}) (err error) {
	// Create a new point batch
	meta := db.parseTag(tag)
	bp, err := db.FindOrCreateBatchPoint(tag)
	if err != nil {
		return
	}
	tags := map[string]string{meta.Tag: meta.TagValue}
	fields := map[string]interface{}{
		meta.Field: value,
	}

	pt, err := client.NewPoint(meta.Measurement, tags, fields, time.Now())
	if err != nil {
		return
	}
	bp.AddPoint(pt)
	return
}
func (db *InfluxDB) Flush(tag string) (err error) {
	meta := db.parseTag(tag)
	bp, found := db.Buffer[meta.DB+"."+meta.Retention]
	if found {
		err = db.Client.Write(bp)
	}
	return
}

func (db *InfluxDB) FindOrCreateBatchPoint(tag string) (batch client.BatchPoints, err error) {
	meta := db.parseTag(tag)
	batch, found := db.Buffer[meta.DB+"."+meta.Retention]
	if !found {
		batch, err = db.createBatchPoint(tag)
	}
	return
}

func (db *InfluxDB) createBatchPoint(tag string) (batch client.BatchPoints, err error) {
	db.mutex.Lock()
	defer db.mutex.Unlock()
	meta := db.parseTag(tag)
	bp, err := client.NewBatchPoints(client.BatchPointsConfig{
		Database:        meta.DB,
		Precision:       db.Precision,
		WriteConsistency: db.Consistency
		RetentionPolicy: meta.Retention,
	})
	db.Buffer[meta.DB+"."+meta.Retention] = bp
	batch = bp
	return
}

func (db *InfluxDB) parseTag(tag string) (meta registryMetaData) {
	parts := strings.Split(tag, ".")
	meta.DB = parts[0]
	meta.Retention = parts[1]
	meta.Measurement = parts[2]
	meta.Tag = parts[3]
	meta.TagValue = parts[4]
	meta.Field = parts[5]
	return
}

func (db *InfluxDB) Connect() (err error) {
	c, err := client.NewHTTPClient(client.HTTPConfig{
		Addr: db.Host + ":" + db.Port,
	})
	if err != nil {
		return
	}
	db.Client = c
	return
}
func (db *InfluxDB) FlushAll() (err error) {
	db.mutex.Lock()
	defer db.mutex.Unlock()
	for k, v := range db.Buffer {
		err = db.Client.Write(v)
		if err != nil {
			return
		}
		delete(db.Buffer, k)
	}
	return
}

//IsConnected checks if connection is open
func (db *InfluxDB) IsConnected() (connected bool) {
	_, _, err := db.Client.Ping(200 * time.Millisecond)
	if err != nil {
		connected = false
	}
	connected = true
	return
}
<commit_msg>:bug: fix sintax error (#2)<commit_after>package influxdb

import (
	"strings"
	"sync"
	"time"

	client "github.com/influxdata/influxdb/client/v2"
)

//InfluxDB is the interface to Influx instance
type InfluxDB struct {
	Port        string
	Host        string
	Precision   string
	Consistency string
	Client      client.Client
	Buffer      map[string]client.BatchPoints
	mutex       sync.Mutex
}

type registryMetaData struct {
	DB          string
	Retention   string
	Measurement string
	Tag         string
	TagValue    string
	Field       string
	FieldValue  interface{}
}

func New(host, port string) *InfluxDB {
	db := new(InfluxDB)
	db.Host = host
	db.Port = port
	db.Precision = "ns"
	db.Consistency = "any"
	db.Buffer = make(map[string]client.BatchPoints)
	db.Connect()
	return db
}

//Registry a new Point to InfluxDB
func (db *InfluxDB) Registry(tag string, value interface{}) (err error) {
	// Create a new point batch
	meta := db.parseTag(tag)
	bp, err := db.FindOrCreateBatchPoint(tag)
	if err != nil {
		return
	}
	tags := map[string]string{meta.Tag: meta.TagValue}
	fields := map[string]interface{}{
		meta.Field: value,
	}

	pt, err := client.NewPoint(meta.Measurement, tags, fields, time.Now())
	if err != nil {
		return
	}
	bp.AddPoint(pt)
	return
}
func (db *InfluxDB) Flush(tag string) (err error) {
	meta := db.parseTag(tag)
	bp, found := db.Buffer[meta.DB+"."+meta.Retention]
	if found {
		err = db.Client.Write(bp)
	}
	return
}

func (db *InfluxDB) FindOrCreateBatchPoint(tag string) (batch client.BatchPoints, err error) {
	meta := db.parseTag(tag)
	batch, found := db.Buffer[meta.DB+"."+meta.Retention]
	if !found {
		batch, err = db.createBatchPoint(tag)
	}
	return
}

func (db *InfluxDB) createBatchPoint(tag string) (batch client.BatchPoints, err error) {
	db.mutex.Lock()
	defer db.mutex.Unlock()
	meta := db.parseTag(tag)
	bp, err := client.NewBatchPoints(client.BatchPointsConfig{
		Database:        meta.DB,
		Precision:       db.Precision,
		WriteConsistency: db.Consistency,
		RetentionPolicy: meta.Retention,
	})
	db.Buffer[meta.DB+"."+meta.Retention] = bp
	batch = bp
	return
}

func (db *InfluxDB) parseTag(tag string) (meta registryMetaData) {
	parts := strings.Split(tag, ".")
	meta.DB = parts[0]
	meta.Retention = parts[1]
	meta.Measurement = parts[2]
	meta.Tag = parts[3]
	meta.TagValue = parts[4]
	meta.Field = parts[5]
	return
}

func (db *InfluxDB) Connect() (err error) {
	c, err := client.NewHTTPClient(client.HTTPConfig{
		Addr: db.Host + ":" + db.Port,
	})
	if err != nil {
		return
	}
	db.Client = c
	return
}
func (db *InfluxDB) FlushAll() (err error) {
	db.mutex.Lock()
	defer db.mutex.Unlock()
	for k, v := range db.Buffer {
		err = db.Client.Write(v)
		if err != nil {
			return
		}
		delete(db.Buffer, k)
	}
	return
}

//IsConnected checks if connection is open
func (db *InfluxDB) IsConnected() (connected bool) {
	_, _, err := db.Client.Ping(200 * time.Millisecond)
	if err != nil {
		connected = false
	}
	connected = true
	return
}
<|endoftext|>


<commit_before>package ChronosDB
import (
    "testing"
    "time"
    "strconv"
)

func Test_relativeToAbsoluteTime(t *testing.T) {
    input := "5"
    now := time.Now()
    ret, err := relativeToAbsoluteTime(now, input, "M")
    if err != nil {
        t.Error("relativeToAbsoluteTime err")
    } else {
        diff, err := strconv.ParseInt(input, 10, 64)
        if err != nil {
            t.Error("relativeToAbsoluteTime parse int err")
        }
        tResult := now.AddDate(0, int(-diff), 0)

        if tResult.UTC().Unix() * 1000 != ret {
            t.Error("relativeToAbsoluteTime result err")
        }
    }
}
<commit_msg>revise unit test<commit_after>package ChronosDB
import (
    "testing"
    "time"
    "strconv"
)

func Test_relativeToAbsoluteTimeInDay(t *testing.T) {
    input := "256"
    now := time.Now()

    ret, err := relativeToAbsoluteTime(now, input, "d")
    if err != nil {
        t.Error(err)
    } else {
        diff, err := strconv.ParseInt(input, 10, 64)
        if err != nil {
            t.Error( err)
        }
        tResult := now.AddDate(0, 0,int(-diff))

        if tResult.UTC().Unix() * 1000 != ret {
            t.Error(ret)
        }
    }
}
func Test_relativeToAbsoluteTimeInMonth(t *testing.T) {
    input := "5"
    now := time.Now()

    ret, err := relativeToAbsoluteTime(now, input, "M")
    if err != nil {
        t.Error(err)
    } else {
        diff, err := strconv.ParseInt(input, 10, 64)
        if err != nil {
            t.Error( err)
        }
        tResult := now.AddDate(0, int(-diff), 0)

        if tResult.UTC().Unix() * 1000 != ret {
            t.Error(ret)
        }
    }
}

func Test_relativeToAbsoluteTimeInYear(t *testing.T) {
    input := "5"
    now := time.Now()

    ret, err := relativeToAbsoluteTime(now, input, "y")
    if err != nil {
        t.Error(err)
    } else {
        diff, err := strconv.ParseInt(input, 10, 64)
        if err != nil {
            t.Error(err)
        }
        tResult := now.AddDate(int(-diff), 0, 0)

        if tResult.UTC().Unix() * 1000 != ret {
            t.Error(ret)
            t.Error(tResult.UTC().Unix() * 1000 )
        }
    }
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"github.com/gorilla/mux"
	"html/template"
	"io/ioutil"
	"net/http"
	"os"
)

func redirectLogin(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r, "/login", 301)
}

type staticAssetPlugs struct {
	Origin string
}

type staticHtmlPlugs struct {
	CdnPrefix string
}

func initStaticRouter(router *mux.Router) error {
	asset := make(map[string]string)

	for _, dir := range []string{"js", "css", "images"} {
		files, err := ioutil.ReadDir("./" + dir)
		if err != nil {
			logger.Errorf("cannot read directory ./%s: %v", dir, err)
			return err
		}

		for _, file := range files {
			sl := string(os.PathSeparator)
			path := sl + dir + sl + file.Name()

			contents, err := ioutil.ReadFile("." + path)
			if err != nil {
				logger.Errorf("cannot read file %s: %v", path, err)
				return err
			}

			if dir == "js" {
				asset[path] = "window.API='" + os.Getenv("ORIGIN") + "/api';" + string(contents)
			} else {
				asset[path] = string(contents)
			}

			logger.Debugf("routing %s", path)
			router.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
				fmt.Fprint(w, asset[r.URL.Path])
			})
		}
	}

	pages := []string{
		"login",
		"signup",
		"dashboard",
		"account",
	}

	html := make(map[string]string)
	for _, page := range pages {
		contents, err := ioutil.ReadFile(page + ".html")
		if err != nil {
			logger.Errorf("cannot read file %s.html: %v", page, err)
			return err
		}

		t, err := template.New(page).Delims("<<<", ">>>").Parse(string(contents))
		if err != nil {
			logger.Errorf("cannot parse /%s template: %v", page, err)
			return err
		}

		var buf bytes.Buffer
		t.Execute(&buf, &staticHtmlPlugs{CdnPrefix: os.Getenv("CDN_PREFIX")})

		html["/" + page] = buf.String()
	}

	for _, page := range pages {
		router.HandleFunc("/" + page, func(w http.ResponseWriter, r *http.Request) {
			fmt.Fprint(w, html[r.URL.Path])
		})
	}

	return nil
}
<commit_msg>router_static.go: redirect / to login<commit_after>package main

import (
	"bytes"
	"fmt"
	"github.com/gorilla/mux"
	"html/template"
	"io/ioutil"
	"net/http"
	"os"
)

func redirectLogin(w http.ResponseWriter, r *http.Request) {
	http.Redirect(w, r, "/login", 301)
}

type staticAssetPlugs struct {
	Origin string
}

type staticHtmlPlugs struct {
	CdnPrefix string
}

func initStaticRouter(router *mux.Router) error {
	asset := make(map[string]string)

	for _, dir := range []string{"js", "css", "images"} {
		files, err := ioutil.ReadDir("./" + dir)
		if err != nil {
			logger.Errorf("cannot read directory ./%s: %v", dir, err)
			return err
		}

		for _, file := range files {
			sl := string(os.PathSeparator)
			path := sl + dir + sl + file.Name()

			contents, err := ioutil.ReadFile("." + path)
			if err != nil {
				logger.Errorf("cannot read file %s: %v", path, err)
				return err
			}

			if dir == "js" {
				asset[path] = "window.API='" + os.Getenv("ORIGIN") + "/api';" + string(contents)
			} else {
				asset[path] = string(contents)
			}

			logger.Debugf("routing %s", path)
			router.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
				fmt.Fprint(w, asset[r.URL.Path])
			})
		}
	}

	pages := []string{
		"login",
		"signup",
		"dashboard",
		"account",
	}

	html := make(map[string]string)
	for _, page := range pages {
		contents, err := ioutil.ReadFile(page + ".html")
		if err != nil {
			logger.Errorf("cannot read file %s.html: %v", page, err)
			return err
		}

		t, err := template.New(page).Delims("<<<", ">>>").Parse(string(contents))
		if err != nil {
			logger.Errorf("cannot parse /%s template: %v", page, err)
			return err
		}

		var buf bytes.Buffer
		t.Execute(&buf, &staticHtmlPlugs{CdnPrefix: os.Getenv("CDN_PREFIX")})

		html["/" + page] = buf.String()
	}

	for _, page := range pages {
		router.HandleFunc("/" + page, func(w http.ResponseWriter, r *http.Request) {
			fmt.Fprint(w, html[r.URL.Path])
		})
	}

	router.HandleFunc("/", redirectLogin)

	return nil
}
<|endoftext|>


<commit_before>package runner

import (
	"bytes"
	"fmt"
	"time"

	"golang.org/x/net/context"

	"github.com/iron-io/functions/api/models"
	"github.com/iron-io/titan/common"
	"github.com/iron-io/titan/runner/agent"
	"github.com/iron-io/titan/runner/configloader"
	"github.com/iron-io/titan/runner/drivers"
	"github.com/iron-io/titan/runner/drivers/docker"
	"github.com/iron-io/titan/runner/drivers/mock"
)

type Config struct {
	Ctx      context.Context
	Route    *models.Route
	Endpoint string
	Payload  string
	Timeout  time.Duration
}

type Runner struct {
	cfg    *Config
	status string
	out    bytes.Buffer
	err    bytes.Buffer
}

func New(cfg *Config) *Runner {
	return &Runner{
		cfg: cfg,
	}
}

func (r *Runner) Run() error {
	var err error

	runnerConfig := configloader.RunnerConfiguration()

	au := agent.ConfigAuth{runnerConfig.Registries}

	// TODO: Is this really required for Titan's driver?
	// Can we remove it?
	env := common.NewEnvironment(func(e *common.Environment) {})

	// TODO: Create a drivers.New(runnerConfig) in Titan
	driver, err := selectDriver(env, runnerConfig)
	if err != nil {
		return err
	}

	ctask := &containerTask{
		cfg:    r.cfg,
		auth:   &au,
		stdout: &r.out,
		stderr: &r.err,
	}

	result, err := driver.Run(r.cfg.Ctx, ctask)
	if err != nil {
		return err
	}

	r.status = result.Status()

	return nil
}

func (r *Runner) ReadOut() []byte {
	return r.out.Bytes()
}

func (r Runner) ReadErr() []byte {
	return r.err.Bytes()
}

func (r Runner) Status() string {
	return r.status
}

func selectDriver(env *common.Environment, conf *agent.Config) (drivers.Driver, error) {
	switch conf.Driver {
	case "docker":
		docker := docker.NewDocker(env, conf.DriverConfig)
		return docker, nil
	case "mock":
		return mock.New(), nil
	}
	return nil, fmt.Errorf("driver %v not found", conf.Driver)
}
<commit_msg>clean unnecessary code<commit_after>package runner

import (
	"bytes"
	"fmt"
	"time"

	"golang.org/x/net/context"

	"github.com/iron-io/functions/api/models"
	"github.com/iron-io/titan/common"
	"github.com/iron-io/titan/runner/agent"
	"github.com/iron-io/titan/runner/drivers"
	driverscommon "github.com/iron-io/titan/runner/drivers/common"
	"github.com/iron-io/titan/runner/drivers/docker"
	"github.com/iron-io/titan/runner/drivers/mock"
)

type Config struct {
	Ctx     context.Context
	Route   *models.Route
	Payload string
	Timeout time.Duration
}

type Runner struct {
	cfg    *Config
	status string
	out    bytes.Buffer
	err    bytes.Buffer
}

func New(cfg *Config) *Runner {
	return &Runner{
		cfg: cfg,
	}
}

func (r *Runner) Run() error {
	var err error

	// TODO: Is this really required for Titan's driver?
	// Can we remove it?
	env := common.NewEnvironment(func(e *common.Environment) {})

	// TODO: Create a drivers.New(runnerConfig) in Titan
	driver, err := selectDriver("docker", env, &driverscommon.Config{})
	if err != nil {
		return err
	}

	ctask := &containerTask{
		cfg:    r.cfg,
		auth:   &agent.ConfigAuth{},
		stdout: &r.out,
		stderr: &r.err,
	}

	result, err := driver.Run(r.cfg.Ctx, ctask)
	if err != nil {
		return err
	}

	r.status = result.Status()

	return nil
}

func (r *Runner) ReadOut() []byte {
	return r.out.Bytes()
}

func (r Runner) ReadErr() []byte {
	return r.err.Bytes()
}

func (r Runner) Status() string {
	return r.status
}

func selectDriver(driver string, env *common.Environment, conf *driverscommon.Config) (drivers.Driver, error) {
	switch driver {
	case "docker":
		docker := docker.NewDocker(env, conf)
		return docker, nil
	case "mock":
		return mock.New(), nil
	}
	return nil, fmt.Errorf("driver %v not found", driver)
}
<|endoftext|>


<commit_before>package utils

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"os"
	"strings"
	"testing"

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

func bigFile() {
	ioutil.WriteFile("bigfile.test", bytes.Repeat([]byte("z"), 75000000), 0666)
}

func BenchmarkMD5(b *testing.B) {
	bigFile()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		MD5HashFile("bigfile.test")
	}
}

func BenchmarkXXHash(b *testing.B) {
	bigFile()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		XXHashFile("bigfile.test")
	}
}
func BenchmarkImoHash(b *testing.B) {
	bigFile()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		IMOHashFile("bigfile.test")
	}
}

func BenchmarkSha256(b *testing.B) {
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		SHA256("hello,world")
	}
}

func TestExists(t *testing.T) {
	bigFile()
	defer os.Remove("bigfile.test")
	fmt.Println(GetLocalIPs())
	assert.True(t, Exists("bigfile.test"))
	assert.False(t, Exists("doesnotexist"))
}

func TestMD5HashFile(t *testing.T) {
	bigFile()
	defer os.Remove("bigfile.test")
	b, err := MD5HashFile("bigfile.test")
	assert.Nil(t, err)
	assert.Equal(t, "8304ff018e02baad0e3555bade29a405", fmt.Sprintf("%x", b))
	_, err = MD5HashFile("bigfile.test.nofile")
	assert.NotNil(t, err)
}

func TestIMOHashFile(t *testing.T) {
	bigFile()
	defer os.Remove("bigfile.test")
	b, err := IMOHashFile("bigfile.test")
	assert.Nil(t, err)
	assert.Equal(t, "c0d1e123ca94148ffea146137684ebb9", fmt.Sprintf("%x", b))
}

func TestXXHashFile(t *testing.T) {
	bigFile()
	defer os.Remove("bigfile.test")
	b, err := XXHashFile("bigfile.test")
	assert.Nil(t, err)
	assert.Equal(t, "4918740eb5ccb6f7", fmt.Sprintf("%x", b))
	_, err = XXHashFile("nofile")
	assert.NotNil(t, err)
}

func TestSHA256(t *testing.T) {
	assert.Equal(t, "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b", SHA256("hello, world"))
}

func TestByteCountDecimal(t *testing.T) {
	assert.Equal(t, "10.0 kB", ByteCountDecimal(10240))
	assert.Equal(t, "50 B", ByteCountDecimal(50))
	assert.Equal(t, "12.4 MB", ByteCountDecimal(13002343))
}

func TestMissingChunks(t *testing.T) {
	fileSize := 100
	chunkSize := 10
	rand.Seed(1)
	bigBuff := make([]byte, fileSize)
	rand.Read(bigBuff)
	ioutil.WriteFile("missing.test", bigBuff, 0644)
	empty := make([]byte, chunkSize)
	f, err := os.OpenFile("missing.test", os.O_RDWR, 0644)
	assert.Nil(t, err)
	for block := 0; block < fileSize/chunkSize; block++ {
		if block == 0 || block == 4 || block == 5 || block >= 7 {
			f.WriteAt(empty, int64(block*chunkSize))
		}
	}
	f.Close()

	chunkRanges := MissingChunks("missing.test", int64(fileSize), chunkSize)
	assert.Equal(t, []int64{10, 0, 1, 40, 2, 70, 3}, chunkRanges)

	chunks := ChunkRangesToChunks(chunkRanges)
	assert.Equal(t, []int64{0, 40, 50, 70, 80, 90}, chunks)

	os.Remove("missing.test")

	content := []byte("temporary file's content")
	tmpfile, err := ioutil.TempFile("", "example")
	if err != nil {
		log.Fatal(err)
	}

	defer os.Remove(tmpfile.Name()) // clean up

	if _, err := tmpfile.Write(content); err != nil {
		panic(err)
	}
	if err := tmpfile.Close(); err != nil {
		panic(err)
	}
	chunkRanges = MissingChunks(tmpfile.Name(), int64(len(content)), chunkSize)
	assert.Empty(t, chunkRanges)
	chunkRanges = MissingChunks(tmpfile.Name(), int64(len(content)+10), chunkSize)
	assert.Empty(t, chunkRanges)
	chunkRanges = MissingChunks(tmpfile.Name()+"ok", int64(len(content)), chunkSize)
	assert.Empty(t, chunkRanges)
	chunks = ChunkRangesToChunks(chunkRanges)
	assert.Empty(t, chunks)
}

// func Test1(t *testing.T) {
// 	chunkRanges := MissingChunks("../../m/bigfile.test", int64(75000000), 1024*64/2)
// 	fmt.Println(chunkRanges)
// 	fmt.Println(ChunkRangesToChunks((chunkRanges)))
// 	assert.Nil(t, nil)
// }

func TestHashFile(t *testing.T) {
	content := []byte("temporary file's content")
	tmpfile, err := ioutil.TempFile("", "example")
	if err != nil {
		log.Fatal(err)
	}

	defer os.Remove(tmpfile.Name()) // clean up

	if _, err := tmpfile.Write(content); err != nil {
		panic(err)
	}
	if err := tmpfile.Close(); err != nil {
		panic(err)
	}
	hashed, err := HashFile(tmpfile.Name())
	assert.Nil(t, err)
	assert.Equal(t, "18c9673a4bb8325d323e7f24fda9ae1e", fmt.Sprintf("%x", hashed))
}

func TestPublicIP(t *testing.T) {
	ip, err := PublicIP()
	fmt.Println(ip)
	assert.True(t, strings.Contains(ip, ".") || strings.Contains(ip, ":"))
	assert.Nil(t, err)
}

func TestLocalIP(t *testing.T) {
	ip := LocalIP()
	fmt.Println(ip)
	assert.True(t, strings.Contains(ip, ".") || strings.Contains(ip, ":"))
}

func TestGetRandomName(t *testing.T) {
	name := GetRandomName()
	fmt.Println(name)
	assert.NotEmpty(t, name)
}

func TestFindOpenPorts(t *testing.T) {
	openPorts := FindOpenPorts("localhost", 9009, 4)
	assert.Equal(t, []int{9009, 9010, 9011, 9012}, openPorts)
}

func TestIsLocalIP(t *testing.T) {
	assert.True(t, IsLocalIP("192.168.0.14:9009"))
}
<commit_msg>update utils benchmark<commit_after>package utils

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"os"
	"strings"
	"testing"

	"github.com/schollz/croc/v8/src/models"
	"github.com/stretchr/testify/assert"
)

var bigFileSize = 75000000

func bigFile() {
	ioutil.WriteFile("bigfile.test", bytes.Repeat([]byte("z"), bigFileSize), 0666)
}

func BenchmarkMD5(b *testing.B) {
	bigFile()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		MD5HashFile("bigfile.test")
	}
}

func BenchmarkXXHash(b *testing.B) {
	bigFile()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		XXHashFile("bigfile.test")
	}
}
func BenchmarkImoHash(b *testing.B) {
	bigFile()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		IMOHashFile("bigfile.test")
	}
}

func BenchmarkSha256(b *testing.B) {
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		SHA256("hello,world")
	}
}

func BenchmarkMissingChunks(b *testing.B) {
	bigFile()
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		MissingChunks("bigfile.test", int64(bigFileSize), models.TCP_BUFFER_SIZE/2)
	}
}

func TestExists(t *testing.T) {
	bigFile()
	defer os.Remove("bigfile.test")
	fmt.Println(GetLocalIPs())
	assert.True(t, Exists("bigfile.test"))
	assert.False(t, Exists("doesnotexist"))
}

func TestMD5HashFile(t *testing.T) {
	bigFile()
	defer os.Remove("bigfile.test")
	b, err := MD5HashFile("bigfile.test")
	assert.Nil(t, err)
	assert.Equal(t, "8304ff018e02baad0e3555bade29a405", fmt.Sprintf("%x", b))
	_, err = MD5HashFile("bigfile.test.nofile")
	assert.NotNil(t, err)
}

func TestIMOHashFile(t *testing.T) {
	bigFile()
	defer os.Remove("bigfile.test")
	b, err := IMOHashFile("bigfile.test")
	assert.Nil(t, err)
	assert.Equal(t, "c0d1e123ca94148ffea146137684ebb9", fmt.Sprintf("%x", b))
}

func TestXXHashFile(t *testing.T) {
	bigFile()
	defer os.Remove("bigfile.test")
	b, err := XXHashFile("bigfile.test")
	assert.Nil(t, err)
	assert.Equal(t, "4918740eb5ccb6f7", fmt.Sprintf("%x", b))
	_, err = XXHashFile("nofile")
	assert.NotNil(t, err)
}

func TestSHA256(t *testing.T) {
	assert.Equal(t, "09ca7e4eaa6e8ae9c7d261167129184883644d07dfba7cbfbc4c8a2e08360d5b", SHA256("hello, world"))
}

func TestByteCountDecimal(t *testing.T) {
	assert.Equal(t, "10.0 kB", ByteCountDecimal(10240))
	assert.Equal(t, "50 B", ByteCountDecimal(50))
	assert.Equal(t, "12.4 MB", ByteCountDecimal(13002343))
}

func TestMissingChunks(t *testing.T) {
	fileSize := 100
	chunkSize := 10
	rand.Seed(1)
	bigBuff := make([]byte, fileSize)
	rand.Read(bigBuff)
	ioutil.WriteFile("missing.test", bigBuff, 0644)
	empty := make([]byte, chunkSize)
	f, err := os.OpenFile("missing.test", os.O_RDWR, 0644)
	assert.Nil(t, err)
	for block := 0; block < fileSize/chunkSize; block++ {
		if block == 0 || block == 4 || block == 5 || block >= 7 {
			f.WriteAt(empty, int64(block*chunkSize))
		}
	}
	f.Close()

	chunkRanges := MissingChunks("missing.test", int64(fileSize), chunkSize)
	assert.Equal(t, []int64{10, 0, 1, 40, 2, 70, 3}, chunkRanges)

	chunks := ChunkRangesToChunks(chunkRanges)
	assert.Equal(t, []int64{0, 40, 50, 70, 80, 90}, chunks)

	os.Remove("missing.test")

	content := []byte("temporary file's content")
	tmpfile, err := ioutil.TempFile("", "example")
	if err != nil {
		log.Fatal(err)
	}

	defer os.Remove(tmpfile.Name()) // clean up

	if _, err := tmpfile.Write(content); err != nil {
		panic(err)
	}
	if err := tmpfile.Close(); err != nil {
		panic(err)
	}
	chunkRanges = MissingChunks(tmpfile.Name(), int64(len(content)), chunkSize)
	assert.Empty(t, chunkRanges)
	chunkRanges = MissingChunks(tmpfile.Name(), int64(len(content)+10), chunkSize)
	assert.Empty(t, chunkRanges)
	chunkRanges = MissingChunks(tmpfile.Name()+"ok", int64(len(content)), chunkSize)
	assert.Empty(t, chunkRanges)
	chunks = ChunkRangesToChunks(chunkRanges)
	assert.Empty(t, chunks)
}

// func Test1(t *testing.T) {
// 	chunkRanges := MissingChunks("../../m/bigfile.test", int64(75000000), 1024*64/2)
// 	fmt.Println(chunkRanges)
// 	fmt.Println(ChunkRangesToChunks((chunkRanges)))
// 	assert.Nil(t, nil)
// }

func TestHashFile(t *testing.T) {
	content := []byte("temporary file's content")
	tmpfile, err := ioutil.TempFile("", "example")
	if err != nil {
		log.Fatal(err)
	}

	defer os.Remove(tmpfile.Name()) // clean up

	if _, err := tmpfile.Write(content); err != nil {
		panic(err)
	}
	if err := tmpfile.Close(); err != nil {
		panic(err)
	}
	hashed, err := HashFile(tmpfile.Name())
	assert.Nil(t, err)
	assert.Equal(t, "18c9673a4bb8325d323e7f24fda9ae1e", fmt.Sprintf("%x", hashed))
}

func TestPublicIP(t *testing.T) {
	ip, err := PublicIP()
	fmt.Println(ip)
	assert.True(t, strings.Contains(ip, ".") || strings.Contains(ip, ":"))
	assert.Nil(t, err)
}

func TestLocalIP(t *testing.T) {
	ip := LocalIP()
	fmt.Println(ip)
	assert.True(t, strings.Contains(ip, ".") || strings.Contains(ip, ":"))
}

func TestGetRandomName(t *testing.T) {
	name := GetRandomName()
	fmt.Println(name)
	assert.NotEmpty(t, name)
}

func TestFindOpenPorts(t *testing.T) {
	openPorts := FindOpenPorts("localhost", 9009, 4)
	assert.Equal(t, []int{9009, 9010, 9011, 9012}, openPorts)
}

func TestIsLocalIP(t *testing.T) {
	assert.True(t, IsLocalIP("192.168.0.14:9009"))
}
<|endoftext|>


<commit_before>package consts

const (
	YmlExtension          = ".yml"
	ConfigPath            = "./config/"
	DictionariesPath      = "./dictionaries/"
	ServerConfigPath      = ConfigPath + "server" + YmlExtension
	LoggerConfigPath      = ConfigPath + "logger" + YmlExtension
	LocaleEn              = "en"
	LocaleJa              = "ja"
	EnvGitHubClientID     = "XPRESS_GITHUB_CLIENT_ID"
	EnvGitHubClientSecret = "XPRESS_GITHUB_CLIENT_SECRET"
)
<commit_msg>Updated app/consts/consts.go.<commit_after>package consts

const (
	YmlExtension          = ".yml"
	ConfigPath            = "./config/"
	DictionariesPath      = "./dictionaries/"
	ServerConfigPath      = ConfigPath + "server" + YmlExtension
	LoggerConfigPath      = ConfigPath + "logger" + YmlExtension
	LocaleEn              = "en"
	LocaleJa              = "ja"
	EnvGitHubClientID     = "X_GH_ID"
	EnvGitHubClientSecret = "X_GH_SECRET"
)
<|endoftext|>


<commit_before>package storage

import (
	"fmt"
	"github.com/pkg/errors"
	"github.com/viant/toolbox"
	"io"
	"io/ioutil"
	"net/url"
	"os"
	"path"
	"strings"
)

var fileMode os.FileMode = 0644

//Service represents abstract way to accessing local or remote storage
type fileStorageService struct{}

//List returns a list of object for supplied url
func (s *fileStorageService) List(URL string) ([]Object, error) {
	file, err := toolbox.OpenFile(URL)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	stat, err := file.Stat()
	if err == nil {
		if !stat.IsDir() {
			return []Object{
				newFileObject(URL, stat),
			}, nil
		}
	}
	files, err := file.Readdir(0)
	if err != nil {
		return nil, err
	}
	var result = make([]Object, 0)
	result = append(result, newFileObject(URL, stat))

	var parsedURL, _ = url.Parse(URL)
	for _, fileInfo := range files {
		var fileName = fileInfo.Name()
		if parsedURL != nil {
			fileName = strings.Replace(fileName, parsedURL.Path, "", 1)
		}
		fileURL := toolbox.URLPathJoin(URL, fileName)
		result = append(result, newFileObject(fileURL, fileInfo))
	}
	return result, nil
}

//Exists returns true if resource exists
func (s *fileStorageService) Exists(URL string) (bool, error) {
	parsedUrl, err := url.Parse(URL)
	if err != nil {
		return false, err
	}
	if parsedUrl.Scheme != "file" {
		return false, fmt.Errorf("Invalid schema, expected file but had: %v", parsedUrl.Scheme)
	}
	return toolbox.FileExists(parsedUrl.Path), nil
}

func (s *fileStorageService) Close() error {
	return nil
}

//Object returns a Object for supplied url
func (s *fileStorageService) StorageObject(URL string) (Object, error) {
	file, err := toolbox.OpenFile(URL)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	fileInfo, err := os.Stat(file.Name())
	if err != nil {
		return nil, err
	}
	return newFileObject(URL, fileInfo), nil
}

//Download returns reader for downloaded storage object
func (s *fileStorageService) Download(object Object) (io.ReadCloser, error) {
	return toolbox.OpenFile(object.URL())
}

//Upload uploads provided reader content for supplied url.
func (s *fileStorageService) Upload(URL string, reader io.Reader) error {
	parsedUrl, err := url.Parse(URL)
	if err != nil {
		return err
	}
	if parsedUrl.Scheme != "file" {
		return fmt.Errorf("Invalid schema, expected file but had: %v", parsedUrl.Scheme)
	}

	parentDir, _ := path.Split(parsedUrl.Path)

	err = toolbox.CreateDirIfNotExist(parentDir)
	if err != nil {
		return err
	}
	data, err := ioutil.ReadAll(reader)
	if err != nil {
		return err
	}
	return ioutil.WriteFile(parsedUrl.Path, data, fileMode)
}

func (s *fileStorageService) Register(schema string, service Service) error {
	return errors.New("unsupported")
}

//Delete removes passed in storage object
func (s *fileStorageService) Delete(object Object) error {
	fileName := toolbox.Filename(object.URL())
	return os.Remove(fileName)
}

type fileStorageObject struct {
	*AbstractObject
}

func NewFileStorage() Service {
	return &fileStorageService{}
}

func (o *fileStorageObject) Unwrap(target interface{}) error {
	if fileInfo, casted := target.(*os.FileInfo); casted {
		source, ok := o.Source.(os.FileInfo)
		if !ok {
			return fmt.Errorf("failed to cast %T into %T", o.Source, target)
		}
		*fileInfo = source
		return nil
	}

	return fmt.Errorf("unsuported target %T", target)
}

func (o *fileStorageObject) FileInfo() os.FileInfo {
	if source, ok := o.Source.(os.FileInfo); ok {
		return source
	}
	return nil
}

func newFileObject(url string, fileInfo os.FileInfo) Object {
	abstract := NewAbstractStorageObject(url, fileInfo, fileInfo)
	result := &fileStorageObject{
		AbstractObject: abstract,
	}
	result.AbstractObject.Object = result
	return result
}
<commit_msg>patched writing bin files<commit_after>package storage

import (
	"fmt"
	"github.com/pkg/errors"
	"github.com/viant/toolbox"
	"io"
	"io/ioutil"
	"net/url"
	"os"
	"path"
	"strings"
)

var fileMode os.FileMode = 0644
var execFileMode os.FileMode = 0755

//Service represents abstract way to accessing local or remote storage
type fileStorageService struct{}

//List returns a list of object for supplied url
func (s *fileStorageService) List(URL string) ([]Object, error) {
	file, err := toolbox.OpenFile(URL)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	stat, err := file.Stat()
	if err == nil {
		if !stat.IsDir() {
			return []Object{
				newFileObject(URL, stat),
			}, nil
		}
	}
	files, err := file.Readdir(0)
	if err != nil {
		return nil, err
	}
	var result = make([]Object, 0)
	result = append(result, newFileObject(URL, stat))

	var parsedURL, _ = url.Parse(URL)
	for _, fileInfo := range files {
		var fileName = fileInfo.Name()
		if parsedURL != nil {
			fileName = strings.Replace(fileName, parsedURL.Path, "", 1)
		}
		fileURL := toolbox.URLPathJoin(URL, fileName)
		result = append(result, newFileObject(fileURL, fileInfo))
	}
	return result, nil
}

//Exists returns true if resource exists
func (s *fileStorageService) Exists(URL string) (bool, error) {
	parsedUrl, err := url.Parse(URL)
	if err != nil {
		return false, err
	}
	if parsedUrl.Scheme != "file" {
		return false, fmt.Errorf("Invalid schema, expected file but had: %v", parsedUrl.Scheme)
	}
	return toolbox.FileExists(parsedUrl.Path), nil
}

func (s *fileStorageService) Close() error {
	return nil
}

//Object returns a Object for supplied url
func (s *fileStorageService) StorageObject(URL string) (Object, error) {
	file, err := toolbox.OpenFile(URL)
	if err != nil {
		return nil, err
	}
	defer file.Close()
	fileInfo, err := os.Stat(file.Name())
	if err != nil {
		return nil, err
	}
	return newFileObject(URL, fileInfo), nil
}

//Download returns reader for downloaded storage object
func (s *fileStorageService) Download(object Object) (io.ReadCloser, error) {
	return toolbox.OpenFile(object.URL())
}

//Upload uploads provided reader content for supplied url.
func (s *fileStorageService) Upload(URL string, reader io.Reader) error {
	parsedUrl, err := url.Parse(URL)
	if err != nil {
		return err
	}
	if parsedUrl.Scheme != "file" {
		return fmt.Errorf("Invalid schema, expected file but had: %v", parsedUrl.Scheme)
	}

	parentDir, _ := path.Split(parsedUrl.Path)

	err = toolbox.CreateDirIfNotExist(parentDir)
	if err != nil {
		return err
	}
	data, err := ioutil.ReadAll(reader)
	if err != nil {
		return err
	}
	if path.Ext(parsedUrl.Path) == "" {
		return ioutil.WriteFile(parsedUrl.Path, data, execFileMode)
	}
	return ioutil.WriteFile(parsedUrl.Path, data, fileMode)
}

func (s *fileStorageService) Register(schema string, service Service) error {
	return errors.New("unsupported")
}

//Delete removes passed in storage object
func (s *fileStorageService) Delete(object Object) error {
	fileName := toolbox.Filename(object.URL())
	return os.Remove(fileName)
}

type fileStorageObject struct {
	*AbstractObject
}

func NewFileStorage() Service {
	return &fileStorageService{}
}

func (o *fileStorageObject) Unwrap(target interface{}) error {
	if fileInfo, casted := target.(*os.FileInfo); casted {
		source, ok := o.Source.(os.FileInfo)
		if !ok {
			return fmt.Errorf("failed to cast %T into %T", o.Source, target)
		}
		*fileInfo = source
		return nil
	}

	return fmt.Errorf("unsuported target %T", target)
}

func (o *fileStorageObject) FileInfo() os.FileInfo {
	if source, ok := o.Source.(os.FileInfo); ok {
		return source
	}
	return nil
}

func newFileObject(url string, fileInfo os.FileInfo) Object {
	abstract := NewAbstractStorageObject(url, fileInfo, fileInfo)
	result := &fileStorageObject{
		AbstractObject: abstract,
	}
	result.AbstractObject.Object = result
	return result
}
<|endoftext|>


<commit_before>// A trivial LightStep Go tracer example.
//
// $ go build -o lightstep_trivial github.com/lightstep/lightstep-tracer-go/examples/trivial
// $ ./lightstep_trivial --access_token=YOUR_ACCESS_TOKEN

package main

import (
	"flag"
	"fmt"
	"os"

	"golang.org/x/net/context"

	"github.com/lightstep/lightstep-tracer-go"
	"github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/log"
)

var accessToken = flag.String("access_token", "", "your LightStep access token")

func subRoutine(ctx context.Context) {
	trivialSpan, ctx := opentracing.StartSpanFromContext(ctx, "test span")
	defer trivialSpan.Finish()
	trivialSpan.LogEvent("logged something")
	trivialSpan.LogFields(log.String("string_key", "some string value"), log.Object("trivialSpan", trivialSpan))

	subSpan := opentracing.StartSpan(
		"child span", opentracing.ChildOf(trivialSpan.Context()))
	trivialSpan.LogFields(log.Int("int_key", 42), log.Object("subSpan", subSpan))
	defer subSpan.Finish()
}

func main() {
	flag.Parse()
	if len(*accessToken) == 0 {
		fmt.Println("You must specify --access_token")
		os.Exit(1)
	}

	// Use LightStep as the global OpenTracing Tracer.
	opentracing.InitGlobalTracer(lightstep.NewTracer(lightstep.Options{
		AccessToken: *accessToken,
		Collector:   lightstep.Endpoint{"localhost", 9997, true},
		UseGRPC:     true,
	}))

	// Do something that's traced.
	subRoutine(context.Background())

	// Force a flush before exit.
	err := lightstep.FlushLightStepTracer(opentracing.GlobalTracer())
	if err != nil {
		panic(err)
	}
}
<commit_msg>Exercise more of the logging API<commit_after>// A trivial LightStep Go tracer example.
//
// $ go build -o lightstep_trivial github.com/lightstep/lightstep-tracer-go/examples/trivial
// $ ./lightstep_trivial --access_token=YOUR_ACCESS_TOKEN

package main

import (
	"flag"
	"fmt"
	"os"
	"time"

	"golang.org/x/net/context"

	"github.com/lightstep/lightstep-tracer-go"
	"github.com/opentracing/opentracing-go"
	"github.com/opentracing/opentracing-go/log"
)

var accessToken = flag.String("access_token", "", "your LightStep access token")

func subRoutine(ctx context.Context) {
	trivialSpan, ctx := opentracing.StartSpanFromContext(ctx, "test span")
	defer trivialSpan.Finish()
	trivialSpan.LogEvent("logged something")
	trivialSpan.LogFields(log.String("string_key", "some string value"), log.Object("trivialSpan", trivialSpan))

	subSpan := opentracing.StartSpan(
		"child span", opentracing.ChildOf(trivialSpan.Context()))
	trivialSpan.LogFields(log.Int("int_key", 42), log.Object("subSpan", subSpan),
		log.String("time.eager", fmt.Sprint(time.Now())),
		log.Lazy(func(fv log.Encoder) {
			fv.EmitString("time.lazy", fmt.Sprint(time.Now()))
		}))
	defer subSpan.Finish()
}

func main() {
	flag.Parse()
	if len(*accessToken) == 0 {
		fmt.Println("You must specify --access_token")
		os.Exit(1)
	}

	// Use LightStep as the global OpenTracing Tracer.
	opentracing.InitGlobalTracer(lightstep.NewTracer(lightstep.Options{
		AccessToken: *accessToken,
		Collector:   lightstep.Endpoint{"localhost", 9997, true},
		UseGRPC:     true,
	}))

	// Do something that's traced.
	subRoutine(context.Background())

	// Force a flush before exit.
	err := lightstep.FlushLightStepTracer(opentracing.GlobalTracer())
	if err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package expr

import (
	"strings"
	"testing"
)

func TestInterval(t *testing.T) {

	var tests = []struct {
		t       string
		seconds int32
		sign    int
	}{
		{"1s", 1, 1},
		{"2d", 2 * 60 * 60 * 24, 1},
		{"10hours", 60 * 60 * 10, 1},
		{"7d13h45min21s", 7*24*60*60 + 13*60*60 + 45*60 + 21, 1},
		{"01hours", 60 * 60 * 1, 1},
		{"2d2d", 4 * 60 * 60 * 24, 1},

		{"1s", -1, -1},
		{"+2d", 2 * 60 * 60 * 24, -1},
		{"-10hours", -60 * 60 * 10, -1},
		{"-360h2min", -360*60*60 - 2*60, -1},
	}

	for _, tt := range tests {
		if secs, _ := IntervalString(tt.t, tt.sign); secs != tt.seconds {
			t.Errorf("intervalString(%q)=%d, want %d\n", tt.t, secs, tt.seconds)
		}
	}

	var exceptTests = []struct {
		t       string
		seconds int32
		err     string
		sign    int
	}{
		{"10m10s", 0, "unknown time units", 1},
		{"10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000y", 0, "value out of range", 1},
	}
	for _, tt := range exceptTests {
		secs, err := IntervalString(tt.t, tt.sign)
		if secs != tt.seconds {
			t.Errorf("intervalString(%q)=%d, want %d\n", tt.t, secs, tt.seconds)
		}
		if !strings.Contains(err.Error(), tt.err) {
			t.Errorf("Error of intervalString(%q)=%v, expected to contain %v\n", tt.t, err.Error(), tt.err)
		}
	}
}
<commit_msg>fix tests<commit_after>package expr

import (
	"strings"
	"testing"
)

func TestInterval(t *testing.T) {

	var tests = []struct {
		t       string
		seconds int32
		sign    int
	}{
		{"1s", 1, 1},
		{"2d", 2 * 60 * 60 * 24, 1},
		{"10hours", 60 * 60 * 10, 1},
		{"7d13h45min21s", 7*24*60*60 + 13*60*60 + 45*60 + 21, 1},
		{"01hours", 60 * 60 * 1, 1},
		{"2d2d", 4 * 60 * 60 * 24, 1},

		{"1s", -1, -1},
		{"10m10s", 610, 1},
		{"+2d", 2 * 60 * 60 * 24, -1},
		{"-10hours", -60 * 60 * 10, -1},
		{"-360h2min", -360*60*60 - 2*60, -1},
	}

	for _, tt := range tests {
		if secs, _ := IntervalString(tt.t, tt.sign); secs != tt.seconds {
			t.Errorf("intervalString(%q)=%d, want %d\n", tt.t, secs, tt.seconds)
		}
	}

	var exceptTests = []struct {
		t       string
		seconds int32
		err     string
		sign    int
	}{
		{"10x10s", 0, "unknown time units", 1},
		{"10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000y", 0, "value out of range", 1},
	}
	for _, tt := range exceptTests {
		secs, err := IntervalString(tt.t, tt.sign)
		if secs != tt.seconds {
			t.Errorf("intervalString(%q)=%d, want %d\n", tt.t, secs, tt.seconds)
		}
		if !strings.Contains(err.Error(), tt.err) {
			t.Errorf("Error of intervalString(%q)=%v, expected to contain %v\n", tt.t, err.Error(), tt.err)
		}
	}
}
<|endoftext|>


<commit_before>package ast

import (
	"bytes"
	"strings"
)

// Node is the the basis element of the ast
type Node interface {
	TokenLiteral() string
	String() string
}

// **---TokenLiteral-implementations---** //

// TokenLiteral impl for Program
func (p *Program) TokenLiteral() string {
	if len(p.Statements) > 0 {
		return p.Statements[0].TokenLiteral()
	}
	return ""
}

// TokenLiteral impl for LetStatement
func (l *LetStatement) TokenLiteral() string {
	return l.Token.Literal
}

// TokenLiteral impl for Identifier
func (i *Identifier) TokenLiteral() string {
	return i.Token.Literal
}

// TokenLiteral impl for AccessIdentifier
func (i *AccessIdentifier) TokenLiteral() string {
	return i.Token.Literal
}

// TokenLiteral impl for ExpressionStatement
func (e *ExpressionStatement) TokenLiteral() string {
	return e.Token.Literal
}

// TokenLiteral for ReturnStatement
func (r *ReturnStatement) TokenLiteral() string {
	return r.Token.Literal
}

// TokenLiteral for IntegerLiteral
func (i *IntegerLiteral) TokenLiteral() string {
	return i.Token.Literal
}

// TokenLiteral for FloatLiteral
func (f *FloatLiteral) TokenLiteral() string {
	return f.Token.Literal
}

// TokenLiteral for BooleanLiteral
func (b *BooleanLiteral) TokenLiteral() string {
	return b.Token.Literal
}

// TokenLiteral for NilLiteral
func (n *NilLiteral) TokenLiteral() string {
	return n.Token.Literal
}

// TokenLiteral for PrefixExpression
func (p *PrefixExpression) TokenLiteral() string {
	return p.Token.Literal
}

// TokenLiteral for InfixExpression
func (i *InfixExpression) TokenLiteral() string {
	return i.Token.Literal
}

// TokenLiteral for IfExpression
func (f *IfExpression) TokenLiteral() string {
	return f.Token.Literal
}

// TokenLiteral for WhileExpression
func (w *WhileExpression) TokenLiteral() string {
	return w.Token.Literal
}

// TokenLiteral for FunctionLiteral
func (f *FunctionLiteral) TokenLiteral() string {
	return f.Token.Literal
}

// TokenLiteral for BlockStatement
func (bs *BlockStatement) TokenLiteral() string {
	return bs.Token.Literal
}

// TokenLiteral for CallExpression
func (c *CallExpression) TokenLiteral() string {
	return c.Token.Literal
}

// TokenLiteral for StringLiteral
func (s *StringLiteral) TokenLiteral() string {
	return s.Token.Literal
}

// TokenLiteral for ArrayLiteral
func (a *ArrayLiteral) TokenLiteral() string {
	return a.Token.Literal
}

// TokenLiteral for IndexExpression
func (i *IndexExpression) TokenLiteral() string {
	return i.Token.Literal
}

// **---String-implementations---** //

// String for Program
func (p *Program) String() string {
	var b bytes.Buffer

	for _, s := range p.Statements {
		b.WriteString(s.String())
	}

	return b.String()
}

// String for LetStatement
func (l *LetStatement) String() string {
	var b bytes.Buffer

	b.WriteString(l.TokenLiteral())
	b.WriteByte(' ')
	b.WriteString(l.Name.String())
	b.WriteString(" = ")

	if l.Value != nil {
		b.WriteString(l.Value.String())
	}

	b.WriteString("; ")

	return b.String()
}

// String for PrefixExpression
func (p *PrefixExpression) String() string {
	var b bytes.Buffer

	b.WriteByte('(')
	b.WriteString(p.Operator.String())
	b.WriteString(p.Right.String())
	b.WriteByte(')')

	return b.String()
}

// String for InfixExpression
func (i *InfixExpression) String() string {
	var b bytes.Buffer

	b.WriteString("(")
	b.WriteString(i.Left.String())
	b.WriteByte(' ')
	b.WriteString(i.Operator.String())
	b.WriteByte(' ')
	b.WriteString(i.Right.String())
	b.WriteString(")")

	return b.String()
}

// String for IndexExpression
func (i *IndexExpression) String() string {
	var b bytes.Buffer

	b.WriteByte('(')
	b.WriteString(i.Left.String())
	b.WriteByte('[')
	b.WriteString(i.Index.String())
	b.WriteString("])")

	return b.String()
}

// String for ReturnStatement
func (r *ReturnStatement) String() string {
	var b bytes.Buffer

	b.WriteString(r.TokenLiteral())
	b.WriteByte(' ')

	if r.Value != nil {
		b.WriteString(r.Value.String())
	}

	b.WriteByte(';')

	return b.String()
}

// String for IfExpression
func (f *IfExpression) String() string {
	var b bytes.Buffer

	b.WriteString("if ")
	b.WriteString(f.Cond.String())
	b.WriteByte(' ')
	b.WriteString(f.Do.String())

	if f.Else != nil {
		b.WriteString(" else ")
		b.WriteString(f.Else.String())
	}

	return b.String()
}

// String for WhileExpression
func (w *WhileExpression) String() string {
	var b bytes.Buffer

	b.WriteString("while ")
	b.WriteString(w.Cond.String())
	b.WriteByte(' ')
	b.WriteString(w.Do.String())

	return b.String()
}

// String got FunctionLiteral
func (f *FunctionLiteral) String() string {
	var b bytes.Buffer

	params := []string{}
	for _, p := range f.Params {
		params = append(params, p.String())
	}

	b.WriteString(f.TokenLiteral())
	b.WriteString(strings.Join(params, ", "))
	b.WriteString(f.TokenLiteral())
	b.WriteByte(' ')
	b.WriteString(f.Body.String())

	return b.String()
}

// String for BlockStatement
func (bs *BlockStatement) String() string {
	var b bytes.Buffer

	b.WriteString("{ ")

	for _, s := range bs.Statements {
		b.WriteString(s.String())
	}

	b.WriteString("}")

	return b.String()
}

// String for CallExpression
func (c *CallExpression) String() string {
	var b bytes.Buffer

	args := []string{}
	for _, c := range c.Args {
		args = append(args, c.String())
	}

	b.WriteString(c.Func.String())
	b.WriteByte('(')
	b.WriteString(strings.Join(args, ", "))
	b.WriteByte(')')

	return b.String()
}

// String for ArrayLiteral
func (a *ArrayLiteral) String() string {
	var b bytes.Buffer

	elems := []string{}
	for _, e := range a.Elements {
		elems = append(elems, e.String())
	}

	b.WriteByte('[')
	b.WriteString(strings.Join(elems, ", "))
	b.WriteByte(']')

	return b.String()
}

// String for Identifier
func (i *Identifier) String() string {
	return i.Value
}

// String for AccessIdentifier
func (i *AccessIdentifier) String() string {
	names := []string{}
	for _, n := range i.Values {
		names = append(names, n)
	}
	return strings.Join(names, ".")
}

// String for ExpressionStatement
func (e *ExpressionStatement) String() string {
	if e.Expression != nil {
		return e.Expression.String()
	}

	return ""
}

// String for IntegerLiteral
func (i *IntegerLiteral) String() string {
	return i.Token.Literal
}

// String for FloatLiteral
func (f *FloatLiteral) String() string {
	return f.Token.Literal
}

// String for BooleanLiteral
func (b *BooleanLiteral) String() string {
	return b.Token.Literal
}

// String for NilLiteral
func (n *NilLiteral) String() string {
	return n.Token.Literal
}

// String for StringLiteral
func (s *StringLiteral) String() string {
	return s.Token.String()
}

// Statement is the basis for a statment in the ast
type Statement interface {
	Node
	statementNode()
}

// **---statementNode-implementations---** //

func (l *LetStatement) statementNode()        {}
func (e *ExpressionStatement) statementNode() {}
func (r *ReturnStatement) statementNode()     {}
func (bs *BlockStatement) statementNode()     {}

// Expression is the basis for a expression in the ast
type Expression interface {
	Node
	expressionNode()
}

// **---expressionNode-implementations---** //

func (i *Identifier) expressionNode()       {}
func (i *AccessIdentifier) expressionNode() {}
func (i *IntegerLiteral) expressionNode()   {}
func (f *FloatLiteral) expressionNode()     {}
func (p *PrefixExpression) expressionNode() {}
func (i *InfixExpression) expressionNode()  {}
func (b *BooleanLiteral) expressionNode()   {}
func (f *IfExpression) expressionNode()     {}
func (w *WhileExpression) expressionNode()  {}
func (f *FunctionLiteral) expressionNode()  {}
func (c *CallExpression) expressionNode()   {}
func (s *StringLiteral) expressionNode()    {}
func (a *ArrayLiteral) expressionNode()     {}
func (i *IndexExpression) expressionNode()  {}
func (n *NilLiteral) expressionNode()       {}
<commit_msg>fixed string ast printing type instead of value<commit_after>package ast

import (
	"bytes"
	"strings"
)

// Node is the the basis element of the ast
type Node interface {
	TokenLiteral() string
	String() string
}

// **---TokenLiteral-implementations---** //

// TokenLiteral impl for Program
func (p *Program) TokenLiteral() string {
	if len(p.Statements) > 0 {
		return p.Statements[0].TokenLiteral()
	}
	return ""
}

// TokenLiteral impl for LetStatement
func (l *LetStatement) TokenLiteral() string {
	return l.Token.Literal
}

// TokenLiteral impl for Identifier
func (i *Identifier) TokenLiteral() string {
	return i.Token.Literal
}

// TokenLiteral impl for AccessIdentifier
func (i *AccessIdentifier) TokenLiteral() string {
	return i.Token.Literal
}

// TokenLiteral impl for ExpressionStatement
func (e *ExpressionStatement) TokenLiteral() string {
	return e.Token.Literal
}

// TokenLiteral for ReturnStatement
func (r *ReturnStatement) TokenLiteral() string {
	return r.Token.Literal
}

// TokenLiteral for IntegerLiteral
func (i *IntegerLiteral) TokenLiteral() string {
	return i.Token.Literal
}

// TokenLiteral for FloatLiteral
func (f *FloatLiteral) TokenLiteral() string {
	return f.Token.Literal
}

// TokenLiteral for BooleanLiteral
func (b *BooleanLiteral) TokenLiteral() string {
	return b.Token.Literal
}

// TokenLiteral for NilLiteral
func (n *NilLiteral) TokenLiteral() string {
	return n.Token.Literal
}

// TokenLiteral for PrefixExpression
func (p *PrefixExpression) TokenLiteral() string {
	return p.Token.Literal
}

// TokenLiteral for InfixExpression
func (i *InfixExpression) TokenLiteral() string {
	return i.Token.Literal
}

// TokenLiteral for IfExpression
func (f *IfExpression) TokenLiteral() string {
	return f.Token.Literal
}

// TokenLiteral for WhileExpression
func (w *WhileExpression) TokenLiteral() string {
	return w.Token.Literal
}

// TokenLiteral for FunctionLiteral
func (f *FunctionLiteral) TokenLiteral() string {
	return f.Token.Literal
}

// TokenLiteral for BlockStatement
func (bs *BlockStatement) TokenLiteral() string {
	return bs.Token.Literal
}

// TokenLiteral for CallExpression
func (c *CallExpression) TokenLiteral() string {
	return c.Token.Literal
}

// TokenLiteral for StringLiteral
func (s *StringLiteral) TokenLiteral() string {
	return s.Token.Literal
}

// TokenLiteral for ArrayLiteral
func (a *ArrayLiteral) TokenLiteral() string {
	return a.Token.Literal
}

// TokenLiteral for IndexExpression
func (i *IndexExpression) TokenLiteral() string {
	return i.Token.Literal
}

// **---String-implementations---** //

// String for Program
func (p *Program) String() string {
	var b bytes.Buffer

	for _, s := range p.Statements {
		b.WriteString(s.String())
	}

	return b.String()
}

// String for LetStatement
func (l *LetStatement) String() string {
	var b bytes.Buffer

	b.WriteString(l.TokenLiteral())
	b.WriteByte(' ')
	b.WriteString(l.Name.String())
	b.WriteString(" = ")

	if l.Value != nil {
		b.WriteString(l.Value.String())
	}

	b.WriteString("; ")

	return b.String()
}

// String for PrefixExpression
func (p *PrefixExpression) String() string {
	var b bytes.Buffer

	b.WriteByte('(')
	b.WriteString(p.Operator.String())
	b.WriteString(p.Right.String())
	b.WriteByte(')')

	return b.String()
}

// String for InfixExpression
func (i *InfixExpression) String() string {
	var b bytes.Buffer

	b.WriteString("(")
	b.WriteString(i.Left.String())
	b.WriteByte(' ')
	b.WriteString(i.Operator.String())
	b.WriteByte(' ')
	b.WriteString(i.Right.String())
	b.WriteString(")")

	return b.String()
}

// String for IndexExpression
func (i *IndexExpression) String() string {
	var b bytes.Buffer

	b.WriteByte('(')
	b.WriteString(i.Left.String())
	b.WriteByte('[')
	b.WriteString(i.Index.String())
	b.WriteString("])")

	return b.String()
}

// String for ReturnStatement
func (r *ReturnStatement) String() string {
	var b bytes.Buffer

	b.WriteString(r.TokenLiteral())
	b.WriteByte(' ')

	if r.Value != nil {
		b.WriteString(r.Value.String())
	}

	b.WriteByte(';')

	return b.String()
}

// String for IfExpression
func (f *IfExpression) String() string {
	var b bytes.Buffer

	b.WriteString("if ")
	b.WriteString(f.Cond.String())
	b.WriteByte(' ')
	b.WriteString(f.Do.String())

	if f.Else != nil {
		b.WriteString(" else ")
		b.WriteString(f.Else.String())
	}

	return b.String()
}

// String for WhileExpression
func (w *WhileExpression) String() string {
	var b bytes.Buffer

	b.WriteString("while ")
	b.WriteString(w.Cond.String())
	b.WriteByte(' ')
	b.WriteString(w.Do.String())

	return b.String()
}

// String got FunctionLiteral
func (f *FunctionLiteral) String() string {
	var b bytes.Buffer

	params := []string{}
	for _, p := range f.Params {
		params = append(params, p.String())
	}

	b.WriteString(f.TokenLiteral())
	b.WriteString(strings.Join(params, ", "))
	b.WriteString(f.TokenLiteral())
	b.WriteByte(' ')
	b.WriteString(f.Body.String())

	return b.String()
}

// String for BlockStatement
func (bs *BlockStatement) String() string {
	var b bytes.Buffer

	b.WriteString("{ ")

	for _, s := range bs.Statements {
		b.WriteString(s.String())
	}

	b.WriteString("}")

	return b.String()
}

// String for CallExpression
func (c *CallExpression) String() string {
	var b bytes.Buffer

	args := []string{}
	for _, c := range c.Args {
		args = append(args, c.String())
	}

	b.WriteString(c.Func.String())
	b.WriteByte('(')
	b.WriteString(strings.Join(args, ", "))
	b.WriteByte(')')

	return b.String()
}

// String for ArrayLiteral
func (a *ArrayLiteral) String() string {
	var b bytes.Buffer

	elems := []string{}
	for _, e := range a.Elements {
		elems = append(elems, e.String())
	}

	b.WriteByte('[')
	b.WriteString(strings.Join(elems, ", "))
	b.WriteByte(']')

	return b.String()
}

// String for Identifier
func (i *Identifier) String() string {
	return i.Value
}

// String for AccessIdentifier
func (i *AccessIdentifier) String() string {
	names := []string{}
	for _, n := range i.Values {
		names = append(names, n)
	}
	return strings.Join(names, ".")
}

// String for ExpressionStatement
func (e *ExpressionStatement) String() string {
	if e.Expression != nil {
		return e.Expression.String()
	}

	return ""
}

// String for IntegerLiteral
func (i *IntegerLiteral) String() string {
	return i.Token.Literal
}

// String for FloatLiteral
func (f *FloatLiteral) String() string {
	return f.Token.Literal
}

// String for BooleanLiteral
func (b *BooleanLiteral) String() string {
	return b.Token.Literal
}

// String for NilLiteral
func (n *NilLiteral) String() string {
	return n.Token.Literal
}

// String for StringLiteral
func (s *StringLiteral) String() string {
	return "\"" + s.Token.Literal + "\""
}

// Statement is the basis for a statment in the ast
type Statement interface {
	Node
	statementNode()
}

// **---statementNode-implementations---** //

func (l *LetStatement) statementNode()        {}
func (e *ExpressionStatement) statementNode() {}
func (r *ReturnStatement) statementNode()     {}
func (bs *BlockStatement) statementNode()     {}

// Expression is the basis for a expression in the ast
type Expression interface {
	Node
	expressionNode()
}

// **---expressionNode-implementations---** //

func (i *Identifier) expressionNode()       {}
func (i *AccessIdentifier) expressionNode() {}
func (i *IntegerLiteral) expressionNode()   {}
func (f *FloatLiteral) expressionNode()     {}
func (p *PrefixExpression) expressionNode() {}
func (i *InfixExpression) expressionNode()  {}
func (b *BooleanLiteral) expressionNode()   {}
func (f *IfExpression) expressionNode()     {}
func (w *WhileExpression) expressionNode()  {}
func (f *FunctionLiteral) expressionNode()  {}
func (c *CallExpression) expressionNode()   {}
func (s *StringLiteral) expressionNode()    {}
func (a *ArrayLiteral) expressionNode()     {}
func (i *IndexExpression) expressionNode()  {}
func (n *NilLiteral) expressionNode()       {}
<|endoftext|>


<commit_before>package extension

import (
	"github.com/kayex/sirius"
	"github.com/kayex/sirius/text"
)

type Censor struct{}

func (*Censor) Run(m sirius.Message, cfg sirius.ExtensionConfig) (sirius.MessageAction, error) {
	strict := cfg.Boolean("strict")
	phrases := cfg.List("phrases")

	edit := m.EditText()

	for _, p := range phrases {
		if !m.Query(text.Word(p)) {
			continue
		}

		if strict {
			edit.Set(text.Code("CENSORED"))
			break
		}

		if cfg.Boolean("strike") {
			edit.SubstituteWord(p, text.Strike(p))
		} else {
			edit.SubstituteWord(p, text.Code("CENSORED"))
		}
	}

	return edit, nil
}
<commit_msg>Ignore case in censor extension<commit_after>package extension

import (
	"github.com/kayex/sirius"
	"github.com/kayex/sirius/text"
)

type Censor struct{}

func (*Censor) Run(m sirius.Message, cfg sirius.ExtensionConfig) (sirius.MessageAction, error) {
	strict := cfg.Boolean("strict")
	phrases := cfg.List("phrases")

	edit := m.EditText()

	for _, p := range phrases {
		if !m.Query(text.Lower(text.Word(p))) {
			continue
		}

		if strict {
			edit.Set(text.Code("CENSORED"))
			break
		}

		if cfg.Boolean("strike") {
			edit.SubstituteWord(p, text.Strike(p))
		} else {
			edit.SubstituteWord(p, text.Code("CENSORED"))
		}
	}

	return edit, nil
}
<|endoftext|>


<commit_before>package database

import (
	"github.com/paultag/go-dictd/dictd"
)

type FnordDatabase struct {
	dictd.Database
}

func (this *FnordDatabase) Match(query string, strat string) []*dictd.Definition {
	els := make([]*dictd.Definition, 1)
	els[0] = &dictd.Definition{Word: query}
	return els
}

func (this *FnordDatabase) Define(query string) []*dictd.Definition {
	els := make([]*dictd.Definition, 1)
	els[0] = &dictd.Definition{
		Word:       query,
		Definition: query,
	}
	return els
}

func (this *FnordDatabase) Info() string {
	return `Some long
Description goes here

and here.`
}

func (this *FnordDatabase) Description() string {
	return "fake testing database"
}
<commit_msg>reflow<commit_after>package database

import (
	"github.com/paultag/go-dictd/dictd"
)

type FnordDatabase struct{ dictd.Database }

func (this *FnordDatabase) Match(query string, strat string) []*dictd.Definition {
	els := make([]*dictd.Definition, 1)
	els[0] = &dictd.Definition{Word: query}
	return els
}

func (this *FnordDatabase) Define(query string) []*dictd.Definition {
	els := make([]*dictd.Definition, 1)
	els[0] = &dictd.Definition{
		Word:       query,
		Definition: query,
	}
	return els
}

func (this *FnordDatabase) Info() string {
	return `Some long
Description goes here

and here.`
}

func (this *FnordDatabase) Description() string {
	return "fake testing database"
}
<|endoftext|>