<commit_before>package tlsh

import (
	"fmt"
	"io/ioutil"
	"math"
)

const (
	LOG_1_5 = 0.4054651
	LOG_1_3 = 0.26236426
	LOG_1_1 = 0.095310180
)

var (
	windowLength = 5
	effBuckets   = 128
	codeSize     = 32
	numBuckets   = 256
)

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

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

func quartilePoints(buckets []byte) (q1, q2, q3 byte) {
	var spl, spr byte
	var p1 byte = byte(effBuckets/4 - 1)
	var p2 byte = byte(effBuckets/2 - 1)
	var p3 byte = byte(effBuckets - effBuckets/4 - 1)
	var end byte = byte(effBuckets - 1)

	bucket_copy := make([]byte, effBuckets)
	copy(bucket_copy, buckets[:effBuckets])

	short_cut_left := make([]byte, effBuckets)
	short_cut_right := make([]byte, effBuckets)

	for l, r := byte(0), end; ; {
		ret := partition(&bucket_copy, l, r)
		if ret > p2 {
			r = ret - 1
			short_cut_right[spr] = ret
			spr++
		} else if ret < p2 {
			l = ret + 1
			short_cut_left[spl] = ret
			spl++
		} else {
			q2 = bucket_copy[p2]
			break
		}
	}

	short_cut_left[spl] = p2 - 1
	short_cut_right[spr] = p2 + 1

	for i, l := byte(0), byte(0); i <= spl; i++ {
		r := short_cut_left[i]
		if r > p1 {
			for ; ; {
				ret := partition(&bucket_copy, l, r)
				if ret > p1 {
					r = ret - 1
				} else if ret < p1 {
					l = ret + 1
				} else {
					q1 = bucket_copy[p1]
					break
				}
			}
			break
		} else if r < p1 {
			l = r
		} else {
			q1 = bucket_copy[p1]
			break
		}
	}

	for i, r := byte(0), end; i <= spr; i++ {
		l := short_cut_right[i]
		if l < p3 {
			for ; ; {
				ret := partition(&bucket_copy, l, r)
				if ret > p3 {
					r = ret - 1
				} else if ret < p3 {
					l = ret + 1
				} else {
					q3 = bucket_copy[p3]
					break
				}
			}
			break
		} else if l > p3 {
			r = l
		} else {
			q3 = bucket_copy[p3]
			break
		}
	}

	return q1, q2, q3
}

func partition(buf *[]byte, left, right byte) byte {

	if left == right {
		return left
	}

	if left + 1 == right {
		if (*buf)[left] > (*buf)[right] {
			(*buf)[right], (*buf)[left] = (*buf)[left], (*buf)[right]
		}
		return left
	}

	var ret byte = left
	var pivot byte = (left + right) >> 1
	var val byte = (*buf)[pivot]

	(*buf)[pivot] = (*buf)[right]
	(*buf)[right] = val

	for i := left; i < right; i++ {
		if ((*buf))[i] < val {
			(*buf)[i], (*buf)[ret] = (*buf)[ret], (*buf)[i]
			ret++
		}
	}

	(*buf)[right] = (*buf)[ret]
	(*buf)[ret] = val

	return ret;
}

func lValue(length int) byte {
	var l byte

	if length <= 656 {
		l = byte(math.Floor(math.Log(float64(length)) / LOG_1_5))
	} else if length <= 3199 {
		l = byte(math.Floor(math.Log(float64(length))/LOG_1_3 - 8.72777))
	} else {
		l = byte(math.Floor(math.Log(float64(length))/LOG_1_1 - 62.5472))
	}

	return l % 255
}

func swapByte(in byte) byte {
	var out byte

	out = ((in & 0xF0) >> 4) & 0x0F
	out |= ((in & 0x0F) << 4) & 0xF0

	return out
}

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

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

	return biHash
}

//Hash calculates the TLSH for the input file
func Hash(filename string) (hash string, err error) {

	buckets := make([]byte, numBuckets)
	chunk := make([]byte, windowLength)
	salt := []byte{2, 3, 5, 7, 11, 13}
	sw := 0
	checksum := byte(0)

	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return
	}

	for sw <= len(data)-windowLength {

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

		sw++
		triplets := getTriplets(chunk)

		checksumTriplet := []byte{chunk[0], chunk[1], checksum}
		checksum = pearsonHash(0, checksumTriplet)

		for i, triplet := range triplets {
			buckets[pearsonHash(salt[i], triplet)]++
		}
	}
	q1, q2, q3 := quartilePoints(buckets)
	q1Ratio := (q1 * 100 / q3) % 16
	q2Ratio := (q2 * 100 / q3) % 16
	lValue := lValue(len(data))
	biHash := makeHash(buckets, q1, q2, q3)

	fmt.Printf("checksum=%02X\n", swapByte(checksum))
	fmt.Printf("L=%02X\n", swapByte(lValue))
	fmt.Printf("q1Ratio=%X, q2Ratio=%x\n", q1Ratio, q2Ratio)

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

	return hash, nil
}
<commit_msg>Construct TLSH hash<commit_after>package tlsh

import (
	"fmt"
	"io/ioutil"
	"math"
)

const (
	LOG_1_5 = 0.4054651
	LOG_1_3 = 0.26236426
	LOG_1_1 = 0.095310180
)

var (
	windowLength = 5
	effBuckets   = 128
	codeSize     = 32
	numBuckets   = 256
)

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

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

func quartilePoints(buckets []byte) (q1, q2, q3 byte) {
	var spl, spr byte
	var p1 byte = byte(effBuckets/4 - 1)
	var p2 byte = byte(effBuckets/2 - 1)
	var p3 byte = byte(effBuckets - effBuckets/4 - 1)
	var end byte = byte(effBuckets - 1)

	bucket_copy := make([]byte, effBuckets)
	copy(bucket_copy, buckets[:effBuckets])

	short_cut_left := make([]byte, effBuckets)
	short_cut_right := make([]byte, effBuckets)

	for l, r := byte(0), end; ; {
		ret := partition(&bucket_copy, l, r)
		if ret > p2 {
			r = ret - 1
			short_cut_right[spr] = ret
			spr++
		} else if ret < p2 {
			l = ret + 1
			short_cut_left[spl] = ret
			spl++
		} else {
			q2 = bucket_copy[p2]
			break
		}
	}

	short_cut_left[spl] = p2 - 1
	short_cut_right[spr] = p2 + 1

	for i, l := byte(0), byte(0); i <= spl; i++ {
		r := short_cut_left[i]
		if r > p1 {
			for ; ; {
				ret := partition(&bucket_copy, l, r)
				if ret > p1 {
					r = ret - 1
				} else if ret < p1 {
					l = ret + 1
				} else {
					q1 = bucket_copy[p1]
					break
				}
			}
			break
		} else if r < p1 {
			l = r
		} else {
			q1 = bucket_copy[p1]
			break
		}
	}

	for i, r := byte(0), end; i <= spr; i++ {
		l := short_cut_right[i]
		if l < p3 {
			for ; ; {
				ret := partition(&bucket_copy, l, r)
				if ret > p3 {
					r = ret - 1
				} else if ret < p3 {
					l = ret + 1
				} else {
					q3 = bucket_copy[p3]
					break
				}
			}
			break
		} else if l > p3 {
			r = l
		} else {
			q3 = bucket_copy[p3]
			break
		}
	}

	return q1, q2, q3
}

func partition(buf *[]byte, left, right byte) byte {

	if left == right {
		return left
	}

	if left + 1 == right {
		if (*buf)[left] > (*buf)[right] {
			(*buf)[right], (*buf)[left] = (*buf)[left], (*buf)[right]
		}
		return left
	}

	var ret byte = left
	var pivot byte = (left + right) >> 1
	var val byte = (*buf)[pivot]

	(*buf)[pivot] = (*buf)[right]
	(*buf)[right] = val

	for i := left; i < right; i++ {
		if ((*buf))[i] < val {
			(*buf)[i], (*buf)[ret] = (*buf)[ret], (*buf)[i]
			ret++
		}
	}

	(*buf)[right] = (*buf)[ret]
	(*buf)[ret] = val

	return ret;
}

func lValue(length int) byte {
	var l byte

	if length <= 656 {
		l = byte(math.Floor(math.Log(float64(length)) / LOG_1_5))
	} else if length <= 3199 {
		l = byte(math.Floor(math.Log(float64(length))/LOG_1_3 - 8.72777))
	} else {
		l = byte(math.Floor(math.Log(float64(length))/LOG_1_1 - 62.5472))
	}

	return l % 255
}

func swapByte(in byte) byte {
	var out byte

	out = ((in & 0xF0) >> 4) & 0x0F
	out |= ((in & 0x0F) << 4) & 0xF0

	return out
}

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

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

	return biHash
}

func hashTLSH(length int, buckets []byte, checksum, q1, q2, q3 byte) []byte {

	// binary representation of buckets
	biHash := bucketsBinaryRepresentation(buckets, q1, q2, q3)

	q1Ratio := byte(float32(q1) * 100 / float32(q3)) % 16
	q2Ratio := byte(float32(q2) * 100 / float32(q3)) % 16

	qRatio := ((q1Ratio & 0xF) << 4) | (q2Ratio & 0xF)

	// prepend header
	return append([]byte{swapByte(checksum), swapByte(lValue(length)), qRatio}, biHash...)
}

func makeStringTLSH(biHash []byte) (hash string) {

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

	return
}

//Hash calculates the TLSH for the input file
func Hash(filename string) (hash string, err error) {

	buckets := make([]byte, numBuckets)
	chunk := make([]byte, windowLength)
	salt := []byte{2, 3, 5, 7, 11, 13}
	sw := 0
	checksum := byte(0)

	data, err := ioutil.ReadFile(filename)
	if err != nil {
		return
	}

	for sw <= len(data)-windowLength {

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

		sw++
		triplets := getTriplets(chunk)

		checksumTriplet := []byte{chunk[0], chunk[1], checksum}
		checksum = pearsonHash(0, checksumTriplet)

		for i, triplet := range triplets {
			buckets[pearsonHash(salt[i], triplet)]++
		}
	}
	q1, q2, q3 := quartilePoints(buckets)

	hash = makeStringTLSH(hashTLSH(len(data), buckets, checksum, q1, q2, q3))

	return hash, nil
}
<|endoftext|>


<commit_before>package toml

import (
	"errors"
	"fmt"
	"io/ioutil"
	"runtime"
	"strconv"
	"strings"
	"time"
)

type tomlValue struct {
	value    interface{}
	position Position
}

// TomlTree is the result of the parsing of a TOML file.
type TomlTree struct {
	values   map[string]interface{}
	position Position
}

func newTomlTree() *TomlTree {
	return &TomlTree{
		values:   make(map[string]interface{}),
		position: Position{},
	}
}

// Has returns a boolean indicating if the given key exists.
func (t *TomlTree) Has(key string) bool {
	if key == "" {
		return false
	}
	return t.HasPath(strings.Split(key, "."))
}

// HasPath returns true if the given path of keys exists, false otherwise.
func (t *TomlTree) HasPath(keys []string) bool {
	return t.GetPath(keys) != nil
}

// Keys returns the keys of the toplevel tree.
// Warning: this is a costly operation.
func (t *TomlTree) Keys() []string {
	var keys []string
	for k := range t.values {
		keys = append(keys, k)
	}
	return keys
}

// Get the value at key in the TomlTree.
// Key is a dot-separated path (e.g. a.b.c).
// Returns nil if the path does not exist in the tree.
// If keys is of length zero, the current tree is returned.
func (t *TomlTree) Get(key string) interface{} {
	if key == "" {
		return t
	}
	return t.GetPath(strings.Split(key, "."))
}

// GetPath returns the element in the tree indicated by 'keys'.
// If keys is of length zero, the current tree is returned.
func (t *TomlTree) GetPath(keys []string) interface{} {
	if len(keys) == 0 {
		return t
	}
	subtree := t
	for _, intermediateKey := range keys[:len(keys)-1] {
		value, exists := subtree.values[intermediateKey]
		if !exists {
			return nil
		}
		switch node := value.(type) {
		case *TomlTree:
			subtree = node
		case []*TomlTree:
			// go to most recent element
			if len(node) == 0 {
				return nil
			}
			subtree = node[len(node)-1]
		default:
			return nil // cannot naigate through other node types
		}
	}
	// branch based on final node type
	switch node := subtree.values[keys[len(keys)-1]].(type) {
	case *tomlValue:
		return node.value
	default:
		return node
	}
}

// GetPosition returns the position of the given key.
func (t *TomlTree) GetPosition(key string) Position {
	if key == "" {
		return t.position
	}
	return t.GetPositionPath(strings.Split(key, "."))
}

// GetPositionPath returns the element in the tree indicated by 'keys'.
// If keys is of length zero, the current tree is returned.
func (t *TomlTree) GetPositionPath(keys []string) Position {
	if len(keys) == 0 {
		return t.position
	}
	subtree := t
	for _, intermediateKey := range keys[:len(keys)-1] {
		value, exists := subtree.values[intermediateKey]
		if !exists {
			return Position{0, 0}
		}
		switch node := value.(type) {
		case *TomlTree:
			subtree = node
		case []*TomlTree:
			// go to most recent element
			if len(node) == 0 {
				return Position{0, 0}
			}
			subtree = node[len(node)-1]
		default:
			return Position{0, 0}
		}
	}
	// branch based on final node type
	switch node := subtree.values[keys[len(keys)-1]].(type) {
	case *tomlValue:
		return node.position
	case *TomlTree:
		return node.position
	case []*TomlTree:
		// go to most recent element
		if len(node) == 0 {
			return Position{0, 0}
		}
		return node[len(node)-1].position
	default:
		return Position{0, 0}
	}
}

// GetDefault works like Get but with a default value
func (t *TomlTree) GetDefault(key string, def interface{}) interface{} {
	val := t.Get(key)
	if val == nil {
		return def
	}
	return val
}

// Set an element in the tree.
// Key is a dot-separated path (e.g. a.b.c).
// Creates all necessary intermediates trees, if needed.
func (t *TomlTree) Set(key string, value interface{}) {
	t.SetPath(strings.Split(key, "."), value)
}

// SetPath sets an element in the tree.
// Keys is an array of path elements (e.g. {"a","b","c"}).
// Creates all necessary intermediates trees, if needed.
func (t *TomlTree) SetPath(keys []string, value interface{}) {
	subtree := t
	for _, intermediateKey := range keys[:len(keys)-1] {
		nextTree, exists := subtree.values[intermediateKey]
		if !exists {
			nextTree = newTomlTree()
			subtree.values[intermediateKey] = &nextTree // add new element here
		}
		switch node := nextTree.(type) {
		case *TomlTree:
			subtree = node
		case []*TomlTree:
			// go to most recent element
			if len(node) == 0 {
				// create element if it does not exist
				subtree.values[intermediateKey] = append(node, newTomlTree())
			}
			subtree = node[len(node)-1]
		}
	}
	subtree.values[keys[len(keys)-1]] = value
}

// createSubTree takes a tree and a key and create the necessary intermediate
// subtrees to create a subtree at that point. In-place.
//
// e.g. passing a.b.c will create (assuming tree is empty) tree[a], tree[a][b]
// and tree[a][b][c]
//
// Returns nil on success, error object on failure
func (t *TomlTree) createSubTree(keys []string, pos Position) error {
	subtree := t
	for _, intermediateKey := range keys {
		if intermediateKey == "" {
			return fmt.Errorf("empty intermediate table")
		}
		nextTree, exists := subtree.values[intermediateKey]
		if !exists {
			tree := newTomlTree()
			tree.position = pos
			subtree.values[intermediateKey] = tree
			nextTree = tree
		}

		switch node := nextTree.(type) {
		case []*TomlTree:
			subtree = node[len(node)-1]
		case *TomlTree:
			subtree = node
		default:
			return fmt.Errorf("unknown type for path %s (%s)",
				strings.Join(keys, "."), intermediateKey)
		}
	}
	return nil
}

// encodes a string to a TOML-compliant string value
func encodeTomlString(value string) string {
	result := ""
	for _, rr := range value {
		intRr := uint16(rr)
		switch rr {
		case '\b':
			result += "\\b"
		case '\t':
			result += "\\t"
		case '\n':
			result += "\\n"
		case '\f':
			result += "\\f"
		case '\r':
			result += "\\r"
		case '"':
			result += "\\\""
		case '\\':
			result += "\\\\"
		default:
			if intRr < 0x001F {
				result += fmt.Sprintf("\\u%0.4X", intRr)
			} else {
				result += string(rr)
			}
		}
	}
	return result
}

// Value print support function for ToString()
// Outputs the TOML compliant string representation of a value
func toTomlValue(item interface{}, indent int) string {
	tab := strings.Repeat(" ", indent)
	switch value := item.(type) {
	case int64:
		return tab + strconv.FormatInt(value, 10)
	case float64:
		return tab + strconv.FormatFloat(value, 'f', -1, 64)
	case string:
		return tab + "\"" + encodeTomlString(value) + "\""
	case bool:
		if value {
			return "true"
		}
		return "false"
	case time.Time:
		return tab + value.Format(time.RFC3339)
	case []interface{}:
		result := tab + "[\n"
		for _, item := range value {
			result += toTomlValue(item, indent+2) + ",\n"
		}
		return result + tab + "]"
	default:
		panic(fmt.Sprintf("unsupported value type: %v", value))
	}
}

// Recursive support function for ToString()
// Outputs a tree, using the provided keyspace to prefix group names
func (t *TomlTree) toToml(indent, keyspace string) string {
	result := ""
	for k, v := range t.values {
		// figure out the keyspace
		combinedKey := k
		if keyspace != "" {
			combinedKey = keyspace + "." + combinedKey
		}
		// output based on type
		switch node := v.(type) {
		case []*TomlTree:
			for _, item := range node {
				if len(item.Keys()) > 0 {
					result += fmt.Sprintf("\n%s[[%s]]\n", indent, combinedKey)
				}
				result += item.toToml(indent+"  ", combinedKey)
			}
		case *TomlTree:
			if len(node.Keys()) > 0 {
				result += fmt.Sprintf("\n%s[%s]\n", indent, combinedKey)
			}
			result += node.toToml(indent+"  ", combinedKey)
		case *tomlValue:
			result += fmt.Sprintf("%s%s = %s\n", indent, k, toTomlValue(node.value, 0))
		default:
			panic(fmt.Sprintf("unsupported node type: %v", node))
		}
	}
	return result
}

func (t *TomlTree) Query(query string) (*QueryResult, error) {
	if q, err := CompileQuery(query); err != nil {
		return nil, err
	} else {
		return q.Execute(t), nil
	}
}

// ToString generates a human-readable representation of the current tree.
// Output spans multiple lines, and is suitable for ingest by a TOML parser
func (t *TomlTree) ToString() string {
	return t.toToml("", "")
}

// Load creates a TomlTree from a string.
func Load(content string) (tree *TomlTree, err error) {
	defer func() {
		if r := recover(); r != nil {
			if _, ok := r.(runtime.Error); ok {
				panic(r)
			}
			err = errors.New(r.(string))
		}
	}()
	tree = parseToml(lexToml(content))
	return
}

// LoadFile creates a TomlTree from a file.
func LoadFile(path string) (tree *TomlTree, err error) {
	buff, ferr := ioutil.ReadFile(path)
	if ferr != nil {
		err = ferr
	} else {
		s := string(buff)
		tree, err = Load(s)
	}
	return
}
<commit_msg>Fix inserting values into a tree<commit_after>package toml

import (
	"errors"
	"fmt"
	"io/ioutil"
	"runtime"
	"strconv"
	"strings"
	"time"
)

type tomlValue struct {
	value    interface{}
	position Position
}

// TomlTree is the result of the parsing of a TOML file.
type TomlTree struct {
	values   map[string]interface{}
	position Position
}

func newTomlTree() *TomlTree {
	return &TomlTree{
		values:   make(map[string]interface{}),
		position: Position{},
	}
}

// Has returns a boolean indicating if the given key exists.
func (t *TomlTree) Has(key string) bool {
	if key == "" {
		return false
	}
	return t.HasPath(strings.Split(key, "."))
}

// HasPath returns true if the given path of keys exists, false otherwise.
func (t *TomlTree) HasPath(keys []string) bool {
	return t.GetPath(keys) != nil
}

// Keys returns the keys of the toplevel tree.
// Warning: this is a costly operation.
func (t *TomlTree) Keys() []string {
	var keys []string
	for k := range t.values {
		keys = append(keys, k)
	}
	return keys
}

// Get the value at key in the TomlTree.
// Key is a dot-separated path (e.g. a.b.c).
// Returns nil if the path does not exist in the tree.
// If keys is of length zero, the current tree is returned.
func (t *TomlTree) Get(key string) interface{} {
	if key == "" {
		return t
	}
	return t.GetPath(strings.Split(key, "."))
}

// GetPath returns the element in the tree indicated by 'keys'.
// If keys is of length zero, the current tree is returned.
func (t *TomlTree) GetPath(keys []string) interface{} {
	if len(keys) == 0 {
		return t
	}
	subtree := t
	for _, intermediateKey := range keys[:len(keys)-1] {
		value, exists := subtree.values[intermediateKey]
		if !exists {
			return nil
		}
		switch node := value.(type) {
		case *TomlTree:
			subtree = node
		case []*TomlTree:
			// go to most recent element
			if len(node) == 0 {
				return nil
			}
			subtree = node[len(node)-1]
		default:
			return nil // cannot naigate through other node types
		}
	}
	// branch based on final node type
	switch node := subtree.values[keys[len(keys)-1]].(type) {
	case *tomlValue:
		return node.value
	default:
		return node
	}
}

// GetPosition returns the position of the given key.
func (t *TomlTree) GetPosition(key string) Position {
	if key == "" {
		return t.position
	}
	return t.GetPositionPath(strings.Split(key, "."))
}

// GetPositionPath returns the element in the tree indicated by 'keys'.
// If keys is of length zero, the current tree is returned.
func (t *TomlTree) GetPositionPath(keys []string) Position {
	if len(keys) == 0 {
		return t.position
	}
	subtree := t
	for _, intermediateKey := range keys[:len(keys)-1] {
		value, exists := subtree.values[intermediateKey]
		if !exists {
			return Position{0, 0}
		}
		switch node := value.(type) {
		case *TomlTree:
			subtree = node
		case []*TomlTree:
			// go to most recent element
			if len(node) == 0 {
				return Position{0, 0}
			}
			subtree = node[len(node)-1]
		default:
			return Position{0, 0}
		}
	}
	// branch based on final node type
	switch node := subtree.values[keys[len(keys)-1]].(type) {
	case *tomlValue:
		return node.position
	case *TomlTree:
		return node.position
	case []*TomlTree:
		// go to most recent element
		if len(node) == 0 {
			return Position{0, 0}
		}
		return node[len(node)-1].position
	default:
		return Position{0, 0}
	}
}

// GetDefault works like Get but with a default value
func (t *TomlTree) GetDefault(key string, def interface{}) interface{} {
	val := t.Get(key)
	if val == nil {
		return def
	}
	return val
}

// Set an element in the tree.
// Key is a dot-separated path (e.g. a.b.c).
// Creates all necessary intermediates trees, if needed.
func (t *TomlTree) Set(key string, value interface{}) {
	t.SetPath(strings.Split(key, "."), value)
}

// SetPath sets an element in the tree.
// Keys is an array of path elements (e.g. {"a","b","c"}).
// Creates all necessary intermediates trees, if needed.
func (t *TomlTree) SetPath(keys []string, value interface{}) {
	subtree := t
	for _, intermediateKey := range keys[:len(keys)-1] {
		nextTree, exists := subtree.values[intermediateKey]
		if !exists {
			nextTree = newTomlTree()
			subtree.values[intermediateKey] = nextTree // add new element here
		}
		switch node := nextTree.(type) {
		case *TomlTree:
			subtree = node
		case []*TomlTree:
			// go to most recent element
			if len(node) == 0 {
				// create element if it does not exist
				subtree.values[intermediateKey] = append(node, newTomlTree())
			}
			subtree = node[len(node)-1]
		}
	}
	subtree.values[keys[len(keys)-1]] = &tomlValue{value: value}
}

// createSubTree takes a tree and a key and create the necessary intermediate
// subtrees to create a subtree at that point. In-place.
//
// e.g. passing a.b.c will create (assuming tree is empty) tree[a], tree[a][b]
// and tree[a][b][c]
//
// Returns nil on success, error object on failure
func (t *TomlTree) createSubTree(keys []string, pos Position) error {
	subtree := t
	for _, intermediateKey := range keys {
		if intermediateKey == "" {
			return fmt.Errorf("empty intermediate table")
		}
		nextTree, exists := subtree.values[intermediateKey]
		if !exists {
			tree := newTomlTree()
			tree.position = pos
			subtree.values[intermediateKey] = tree
			nextTree = tree
		}

		switch node := nextTree.(type) {
		case []*TomlTree:
			subtree = node[len(node)-1]
		case *TomlTree:
			subtree = node
		default:
			return fmt.Errorf("unknown type for path %s (%s)",
				strings.Join(keys, "."), intermediateKey)
		}
	}
	return nil
}

// encodes a string to a TOML-compliant string value
func encodeTomlString(value string) string {
	result := ""
	for _, rr := range value {
		intRr := uint16(rr)
		switch rr {
		case '\b':
			result += "\\b"
		case '\t':
			result += "\\t"
		case '\n':
			result += "\\n"
		case '\f':
			result += "\\f"
		case '\r':
			result += "\\r"
		case '"':
			result += "\\\""
		case '\\':
			result += "\\\\"
		default:
			if intRr < 0x001F {
				result += fmt.Sprintf("\\u%0.4X", intRr)
			} else {
				result += string(rr)
			}
		}
	}
	return result
}

// Value print support function for ToString()
// Outputs the TOML compliant string representation of a value
func toTomlValue(item interface{}, indent int) string {
	tab := strings.Repeat(" ", indent)
	switch value := item.(type) {
	case int64:
		return tab + strconv.FormatInt(value, 10)
	case float64:
		return tab + strconv.FormatFloat(value, 'f', -1, 64)
	case string:
		return tab + "\"" + encodeTomlString(value) + "\""
	case bool:
		if value {
			return "true"
		}
		return "false"
	case time.Time:
		return tab + value.Format(time.RFC3339)
	case []interface{}:
		result := tab + "[\n"
		for _, item := range value {
			result += toTomlValue(item, indent+2) + ",\n"
		}
		return result + tab + "]"
	default:
		panic(fmt.Sprintf("unsupported value type: %v", value))
	}
}

// Recursive support function for ToString()
// Outputs a tree, using the provided keyspace to prefix group names
func (t *TomlTree) toToml(indent, keyspace string) string {
	result := ""
	for k, v := range t.values {
		// figure out the keyspace
		combinedKey := k
		if keyspace != "" {
			combinedKey = keyspace + "." + combinedKey
		}
		// output based on type
		switch node := v.(type) {
		case []*TomlTree:
			for _, item := range node {
				if len(item.Keys()) > 0 {
					result += fmt.Sprintf("\n%s[[%s]]\n", indent, combinedKey)
				}
				result += item.toToml(indent+"  ", combinedKey)
			}
		case *TomlTree:
			if len(node.Keys()) > 0 {
				result += fmt.Sprintf("\n%s[%s]\n", indent, combinedKey)
			}
			result += node.toToml(indent+"  ", combinedKey)
		case *tomlValue:
			result += fmt.Sprintf("%s%s = %s\n", indent, k, toTomlValue(node.value, 0))
		default:
			panic(fmt.Sprintf("unsupported node type: %v", node))
		}
	}
	return result
}

func (t *TomlTree) Query(query string) (*QueryResult, error) {
	if q, err := CompileQuery(query); err != nil {
		return nil, err
	} else {
		return q.Execute(t), nil
	}
}

// ToString generates a human-readable representation of the current tree.
// Output spans multiple lines, and is suitable for ingest by a TOML parser
func (t *TomlTree) ToString() string {
	return t.toToml("", "")
}

// Load creates a TomlTree from a string.
func Load(content string) (tree *TomlTree, err error) {
	defer func() {
		if r := recover(); r != nil {
			if _, ok := r.(runtime.Error); ok {
				panic(r)
			}
			err = errors.New(r.(string))
		}
	}()
	tree = parseToml(lexToml(content))
	return
}

// LoadFile creates a TomlTree from a file.
func LoadFile(path string) (tree *TomlTree, err error) {
	buff, ferr := ioutil.ReadFile(path)
	if ferr != nil {
		err = ferr
	} else {
		s := string(buff)
		tree, err = Load(s)
	}
	return
}
<|endoftext|>


<commit_before>package pbast

import (
	"reflect"
)

type Type interface {
	TypeName() string
}

type BuiltinType string

func (t BuiltinType) TypeName() string {
	return string(t)
}

const (
	Double   BuiltinType = "double"
	Float    BuiltinType = "float"
	Int32    BuiltinType = "int32"
	Int64    BuiltinType = "int64"
	UInt32   BuiltinType = "uint32"
	UInt64   BuiltinType = "uint64"
	SInt32   BuiltinType = "sint32"
	SInt64   BuiltinType = "sint64"
	Fixed32  BuiltinType = "fixed32"
	Fixed64  BuiltinType = "fixed64"
	SFixed32 BuiltinType = "sfixed32"
	SFixed64 BuiltinType = "sfixed64"
	Bool     BuiltinType = "bool"
	String   BuiltinType = "string"
	Bytes    BuiltinType = "bytes"
)

func (e Enum) TypeName() string {
	return e.Name
}

func (e Message) TypeName() string {
	return e.Name
}

func IsSameType(t1, t2 Type) bool {
	if t1.TypeName() != t2.TypeName() {
		return false
	}
	return reflect.DeepEqual(t1, t2)
}

type TypeAdder interface {
	AddType(Type)
}
<commit_msg>Define well known types in Protocol Buffers<commit_after>package pbast

import (
	"reflect"
)

type Type interface {
	TypeName() string
}

type BuiltinType string

func (t BuiltinType) TypeName() string {
	return string(t)
}

const (
	Double   BuiltinType = "double"
	Float    BuiltinType = "float"
	Int32    BuiltinType = "int32"
	Int64    BuiltinType = "int64"
	UInt32   BuiltinType = "uint32"
	UInt64   BuiltinType = "uint64"
	SInt32   BuiltinType = "sint32"
	SInt64   BuiltinType = "sint64"
	Fixed32  BuiltinType = "fixed32"
	Fixed64  BuiltinType = "fixed64"
	SFixed32 BuiltinType = "sfixed32"
	SFixed64 BuiltinType = "sfixed64"
	Bool     BuiltinType = "bool"
	String   BuiltinType = "string"
	Bytes    BuiltinType = "bytes"
)

type WellKnownType string

func (t WellKnownType) TypeName() string {
	return string(t)
}

const (
	Any             WellKnownType = "google.protobuf.Any"
	Api             WellKnownType = "google.protobuf.Api"
	BoolValue       WellKnownType = "google.protobuf.BoolValue"
	BytesValue      WellKnownType = "google.protobuf.BytesValue"
	DoubleValue     WellKnownType = "google.protobuf.DoubleValue"
	Duration        WellKnownType = "google.protobuf.Duration"
	Empty           WellKnownType = "google.protobuf.Empty"
	WellKnownEnum   WellKnownType = "google.protobuf.Enum"
	EnumValue       WellKnownType = "google.protobuf.EnumValue"
	WellKnownField  WellKnownType = "google.protobuf.Field"
	Cardinality     WellKnownType = "google.protobuf.Cardinality"
	Kind            WellKnownType = "google.protobuf.Kind"
	FieldMask       WellKnownType = "google.protobuf.FieldMask"
	FloatValue      WellKnownType = "google.protobuf.FloatValue"
	Int32Value      WellKnownType = "google.protobuf.Int32Value"
	Int64Value      WellKnownType = "google.protobuf.Int64Value"
	ListValue       WellKnownType = "google.protobuf.ListValue"
	Method          WellKnownType = "google.protobuf.Method"
	Mixin           WellKnownType = "google.protobuf.Mixin"
	NullValue       WellKnownType = "google.protobuf.NullValue"
	WellKnownOption WellKnownType = "google.protobuf.Option"
	SourceContext   WellKnownType = "google.protobuf.SourceContext"
	StringValue     WellKnownType = "google.protobuf.StringValue"
	WellKnownStruct WellKnownType = "google.protobuf.Struct"
	WellKnownSyntax WellKnownType = "google.protobuf.Syntax"
	Timestamp       WellKnownType = "google.protobuf.Timestamp"
	UInt32Value     WellKnownType = "google.protobuf.UInt32Value"
	UInt64Value     WellKnownType = "google.protobuf.UInt64Value"
	Value           WellKnownType = "google.protobuf.Value"

// Define well know type for "Type" when coming up with how to resolve naming conflict
)

func (e Enum) TypeName() string {
	return e.Name
}

func (e Message) TypeName() string {
	return e.Name
}

func IsSameType(t1, t2 Type) bool {
	if t1.TypeName() != t2.TypeName() {
		return false
	}
	return reflect.DeepEqual(t1, t2)
}

type TypeAdder interface {
	AddType(Type)
}
<|endoftext|>


<commit_before>package core

import (
	"reflect"
	"sort"
	"strings"
	"time"
)

const (
	POSTGRES = "postgres"
	SQLITE   = "sqlite3"
	MYSQL    = "mysql"
	MSSQL    = "mssql"
	ORACLE   = "oracle"
)

// xorm SQL types
type SQLType struct {
	Name           string
	DefaultLength  int
	DefaultLength2 int
}

const (
	UNKNOW_TYPE = iota
	TEXT_TYPE
	BLOB_TYPE
	TIME_TYPE
	NUMERIC_TYPE
)

func (s *SQLType) IsType(st int) bool {
	if t, ok := SqlTypes[s.Name]; ok && t == st {
		return true
	}
	return false
}

func (s *SQLType) IsText() bool {
	return s.IsType(TEXT_TYPE)
}

func (s *SQLType) IsBlob() bool {
	return s.IsType(BLOB_TYPE)
}

func (s *SQLType) IsTime() bool {
	return s.IsType(TIME_TYPE)
}

func (s *SQLType) IsNumeric() bool {
	return s.IsType(NUMERIC_TYPE)
}

func (s *SQLType) IsJson() bool {
	return s.Name == Json
}

var (
	Bit       = "BIT"
	TinyInt   = "TINYINT"
	SmallInt  = "SMALLINT"
	MediumInt = "MEDIUMINT"
	Int       = "INT"
	Integer   = "INTEGER"
	BigInt    = "BIGINT"

	Enum = "ENUM"
	Set  = "SET"

	Char       = "CHAR"
	Varchar    = "VARCHAR"
	NVarchar   = "NVARCHAR"
	TinyText   = "TINYTEXT"
	Text       = "TEXT"
	Clob       = "CLOB"
	MediumText = "MEDIUMTEXT"
	LongText   = "LONGTEXT"
	Uuid       = "UUID"

	Date       = "DATE"
	DateTime   = "DATETIME"
	Time       = "TIME"
	TimeStamp  = "TIMESTAMP"
	TimeStampz = "TIMESTAMPZ"

	Decimal = "DECIMAL"
	Numeric = "NUMERIC"

	Real   = "REAL"
	Float  = "FLOAT"
	Double = "DOUBLE"

	Binary     = "BINARY"
	VarBinary  = "VARBINARY"
	TinyBlob   = "TINYBLOB"
	Blob       = "BLOB"
	MediumBlob = "MEDIUMBLOB"
	LongBlob   = "LONGBLOB"
	Bytea      = "BYTEA"

	Bool = "BOOL"

	Serial    = "SERIAL"
	BigSerial = "BIGSERIAL"

	Json  = "JSON"
	Jsonb = "JSONB"

	SqlTypes = map[string]int{
		Bit:       NUMERIC_TYPE,
		TinyInt:   NUMERIC_TYPE,
		SmallInt:  NUMERIC_TYPE,
		MediumInt: NUMERIC_TYPE,
		Int:       NUMERIC_TYPE,
		Integer:   NUMERIC_TYPE,
		BigInt:    NUMERIC_TYPE,

		Enum:  TEXT_TYPE,
		Set:   TEXT_TYPE,
		Json:  TEXT_TYPE,
		Jsonb: TEXT_TYPE,

		Char:       TEXT_TYPE,
		Varchar:    TEXT_TYPE,
		NVarchar:   TEXT_TYPE,
		TinyText:   TEXT_TYPE,
		Text:       TEXT_TYPE,
		MediumText: TEXT_TYPE,
		LongText:   TEXT_TYPE,
		Uuid:       TEXT_TYPE,
		Clob:       TEXT_TYPE,

		Date:       TIME_TYPE,
		DateTime:   TIME_TYPE,
		Time:       TIME_TYPE,
		TimeStamp:  TIME_TYPE,
		TimeStampz: TIME_TYPE,

		Decimal: NUMERIC_TYPE,
		Numeric: NUMERIC_TYPE,
		Real:    NUMERIC_TYPE,
		Float:   NUMERIC_TYPE,
		Double:  NUMERIC_TYPE,

		Binary:    BLOB_TYPE,
		VarBinary: BLOB_TYPE,

		TinyBlob:   BLOB_TYPE,
		Blob:       BLOB_TYPE,
		MediumBlob: BLOB_TYPE,
		LongBlob:   BLOB_TYPE,
		Bytea:      BLOB_TYPE,

		Bool: NUMERIC_TYPE,

		Serial:    NUMERIC_TYPE,
		BigSerial: NUMERIC_TYPE,
	}

	intTypes  = sort.StringSlice{"*int", "*int16", "*int32", "*int8"}
	uintTypes = sort.StringSlice{"*uint", "*uint16", "*uint32", "*uint8"}
)

// !nashtsai! treat following var as interal const values, these are used for reflect.TypeOf comparision
var (
	c_EMPTY_STRING       string
	c_BOOL_DEFAULT       bool
	c_BYTE_DEFAULT       byte
	c_COMPLEX64_DEFAULT  complex64
	c_COMPLEX128_DEFAULT complex128
	c_FLOAT32_DEFAULT    float32
	c_FLOAT64_DEFAULT    float64
	c_INT64_DEFAULT      int64
	c_UINT64_DEFAULT     uint64
	c_INT32_DEFAULT      int32
	c_UINT32_DEFAULT     uint32
	c_INT16_DEFAULT      int16
	c_UINT16_DEFAULT     uint16
	c_INT8_DEFAULT       int8
	c_UINT8_DEFAULT      uint8
	c_INT_DEFAULT        int
	c_UINT_DEFAULT       uint
	c_TIME_DEFAULT       time.Time
)

var (
	IntType   = reflect.TypeOf(c_INT_DEFAULT)
	Int8Type  = reflect.TypeOf(c_INT8_DEFAULT)
	Int16Type = reflect.TypeOf(c_INT16_DEFAULT)
	Int32Type = reflect.TypeOf(c_INT32_DEFAULT)
	Int64Type = reflect.TypeOf(c_INT64_DEFAULT)

	UintType   = reflect.TypeOf(c_UINT_DEFAULT)
	Uint8Type  = reflect.TypeOf(c_UINT8_DEFAULT)
	Uint16Type = reflect.TypeOf(c_UINT16_DEFAULT)
	Uint32Type = reflect.TypeOf(c_UINT32_DEFAULT)
	Uint64Type = reflect.TypeOf(c_UINT64_DEFAULT)

	Float32Type = reflect.TypeOf(c_FLOAT32_DEFAULT)
	Float64Type = reflect.TypeOf(c_FLOAT64_DEFAULT)

	Complex64Type  = reflect.TypeOf(c_COMPLEX64_DEFAULT)
	Complex128Type = reflect.TypeOf(c_COMPLEX128_DEFAULT)

	StringType = reflect.TypeOf(c_EMPTY_STRING)
	BoolType   = reflect.TypeOf(c_BOOL_DEFAULT)
	ByteType   = reflect.TypeOf(c_BYTE_DEFAULT)

	TimeType = reflect.TypeOf(c_TIME_DEFAULT)
)

var (
	PtrIntType   = reflect.PtrTo(IntType)
	PtrInt8Type  = reflect.PtrTo(Int8Type)
	PtrInt16Type = reflect.PtrTo(Int16Type)
	PtrInt32Type = reflect.PtrTo(Int32Type)
	PtrInt64Type = reflect.PtrTo(Int64Type)

	PtrUintType   = reflect.PtrTo(UintType)
	PtrUint8Type  = reflect.PtrTo(Uint8Type)
	PtrUint16Type = reflect.PtrTo(Uint16Type)
	PtrUint32Type = reflect.PtrTo(Uint32Type)
	PtrUint64Type = reflect.PtrTo(Uint64Type)

	PtrFloat32Type = reflect.PtrTo(Float32Type)
	PtrFloat64Type = reflect.PtrTo(Float64Type)

	PtrComplex64Type  = reflect.PtrTo(Complex64Type)
	PtrComplex128Type = reflect.PtrTo(Complex128Type)

	PtrStringType = reflect.PtrTo(StringType)
	PtrBoolType   = reflect.PtrTo(BoolType)
	PtrByteType   = reflect.PtrTo(ByteType)

	PtrTimeType = reflect.PtrTo(TimeType)
)

// Type2SQLType generate SQLType acorrding Go's type
func Type2SQLType(t reflect.Type) (st SQLType) {
	switch k := t.Kind(); k {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
		st = SQLType{Int, 0, 0}
	case reflect.Int64, reflect.Uint64:
		st = SQLType{BigInt, 0, 0}
	case reflect.Float32:
		st = SQLType{Float, 0, 0}
	case reflect.Float64:
		st = SQLType{Double, 0, 0}
	case reflect.Complex64, reflect.Complex128:
		st = SQLType{Varchar, 64, 0}
	case reflect.Array, reflect.Slice, reflect.Map:
		if t.Elem() == reflect.TypeOf(c_BYTE_DEFAULT) {
			st = SQLType{Blob, 0, 0}
		} else {
			st = SQLType{Text, 0, 0}
		}
	case reflect.Bool:
		st = SQLType{Bool, 0, 0}
	case reflect.String:
		st = SQLType{Varchar, 255, 0}
	case reflect.Struct:
		if t.ConvertibleTo(TimeType) {
			st = SQLType{DateTime, 0, 0}
		} else {
			// TODO need to handle association struct
			st = SQLType{Text, 0, 0}
		}
	case reflect.Ptr:
		st = Type2SQLType(t.Elem())
	default:
		st = SQLType{Text, 0, 0}
	}
	return
}

// default sql type change to go types
func SQLType2Type(st SQLType) reflect.Type {
	name := strings.ToUpper(st.Name)
	switch name {
	case Bit, TinyInt, SmallInt, MediumInt, Int, Integer, Serial:
		return reflect.TypeOf(1)
	case BigInt, BigSerial:
		return reflect.TypeOf(int64(1))
	case Float, Real:
		return reflect.TypeOf(float32(1))
	case Double:
		return reflect.TypeOf(float64(1))
	case Char, Varchar, NVarchar, TinyText, Text, MediumText, LongText, Enum, Set, Uuid, Clob:
		return reflect.TypeOf("")
	case TinyBlob, Blob, LongBlob, Bytea, Binary, MediumBlob, VarBinary:
		return reflect.TypeOf([]byte{})
	case Bool:
		return reflect.TypeOf(true)
	case DateTime, Date, Time, TimeStamp, TimeStampz:
		return reflect.TypeOf(c_TIME_DEFAULT)
	case Decimal, Numeric:
		return reflect.TypeOf("")
	default:
		return reflect.TypeOf("")
	}
}
<commit_msg>added bytes type<commit_after>package core

import (
	"reflect"
	"sort"
	"strings"
	"time"
)

const (
	POSTGRES = "postgres"
	SQLITE   = "sqlite3"
	MYSQL    = "mysql"
	MSSQL    = "mssql"
	ORACLE   = "oracle"
)

// xorm SQL types
type SQLType struct {
	Name           string
	DefaultLength  int
	DefaultLength2 int
}

const (
	UNKNOW_TYPE = iota
	TEXT_TYPE
	BLOB_TYPE
	TIME_TYPE
	NUMERIC_TYPE
)

func (s *SQLType) IsType(st int) bool {
	if t, ok := SqlTypes[s.Name]; ok && t == st {
		return true
	}
	return false
}

func (s *SQLType) IsText() bool {
	return s.IsType(TEXT_TYPE)
}

func (s *SQLType) IsBlob() bool {
	return s.IsType(BLOB_TYPE)
}

func (s *SQLType) IsTime() bool {
	return s.IsType(TIME_TYPE)
}

func (s *SQLType) IsNumeric() bool {
	return s.IsType(NUMERIC_TYPE)
}

func (s *SQLType) IsJson() bool {
	return s.Name == Json
}

var (
	Bit       = "BIT"
	TinyInt   = "TINYINT"
	SmallInt  = "SMALLINT"
	MediumInt = "MEDIUMINT"
	Int       = "INT"
	Integer   = "INTEGER"
	BigInt    = "BIGINT"

	Enum = "ENUM"
	Set  = "SET"

	Char       = "CHAR"
	Varchar    = "VARCHAR"
	NVarchar   = "NVARCHAR"
	TinyText   = "TINYTEXT"
	Text       = "TEXT"
	Clob       = "CLOB"
	MediumText = "MEDIUMTEXT"
	LongText   = "LONGTEXT"
	Uuid       = "UUID"

	Date       = "DATE"
	DateTime   = "DATETIME"
	Time       = "TIME"
	TimeStamp  = "TIMESTAMP"
	TimeStampz = "TIMESTAMPZ"

	Decimal = "DECIMAL"
	Numeric = "NUMERIC"

	Real   = "REAL"
	Float  = "FLOAT"
	Double = "DOUBLE"

	Binary     = "BINARY"
	VarBinary  = "VARBINARY"
	TinyBlob   = "TINYBLOB"
	Blob       = "BLOB"
	MediumBlob = "MEDIUMBLOB"
	LongBlob   = "LONGBLOB"
	Bytea      = "BYTEA"

	Bool = "BOOL"

	Serial    = "SERIAL"
	BigSerial = "BIGSERIAL"

	Json  = "JSON"
	Jsonb = "JSONB"

	SqlTypes = map[string]int{
		Bit:       NUMERIC_TYPE,
		TinyInt:   NUMERIC_TYPE,
		SmallInt:  NUMERIC_TYPE,
		MediumInt: NUMERIC_TYPE,
		Int:       NUMERIC_TYPE,
		Integer:   NUMERIC_TYPE,
		BigInt:    NUMERIC_TYPE,

		Enum:  TEXT_TYPE,
		Set:   TEXT_TYPE,
		Json:  TEXT_TYPE,
		Jsonb: TEXT_TYPE,

		Char:       TEXT_TYPE,
		Varchar:    TEXT_TYPE,
		NVarchar:   TEXT_TYPE,
		TinyText:   TEXT_TYPE,
		Text:       TEXT_TYPE,
		MediumText: TEXT_TYPE,
		LongText:   TEXT_TYPE,
		Uuid:       TEXT_TYPE,
		Clob:       TEXT_TYPE,

		Date:       TIME_TYPE,
		DateTime:   TIME_TYPE,
		Time:       TIME_TYPE,
		TimeStamp:  TIME_TYPE,
		TimeStampz: TIME_TYPE,

		Decimal: NUMERIC_TYPE,
		Numeric: NUMERIC_TYPE,
		Real:    NUMERIC_TYPE,
		Float:   NUMERIC_TYPE,
		Double:  NUMERIC_TYPE,

		Binary:    BLOB_TYPE,
		VarBinary: BLOB_TYPE,

		TinyBlob:   BLOB_TYPE,
		Blob:       BLOB_TYPE,
		MediumBlob: BLOB_TYPE,
		LongBlob:   BLOB_TYPE,
		Bytea:      BLOB_TYPE,

		Bool: NUMERIC_TYPE,

		Serial:    NUMERIC_TYPE,
		BigSerial: NUMERIC_TYPE,
	}

	intTypes  = sort.StringSlice{"*int", "*int16", "*int32", "*int8"}
	uintTypes = sort.StringSlice{"*uint", "*uint16", "*uint32", "*uint8"}
)

// !nashtsai! treat following var as interal const values, these are used for reflect.TypeOf comparision
var (
	c_EMPTY_STRING       string
	c_BOOL_DEFAULT       bool
	c_BYTE_DEFAULT       byte
	c_COMPLEX64_DEFAULT  complex64
	c_COMPLEX128_DEFAULT complex128
	c_FLOAT32_DEFAULT    float32
	c_FLOAT64_DEFAULT    float64
	c_INT64_DEFAULT      int64
	c_UINT64_DEFAULT     uint64
	c_INT32_DEFAULT      int32
	c_UINT32_DEFAULT     uint32
	c_INT16_DEFAULT      int16
	c_UINT16_DEFAULT     uint16
	c_INT8_DEFAULT       int8
	c_UINT8_DEFAULT      uint8
	c_INT_DEFAULT        int
	c_UINT_DEFAULT       uint
	c_TIME_DEFAULT       time.Time
)

var (
	IntType   = reflect.TypeOf(c_INT_DEFAULT)
	Int8Type  = reflect.TypeOf(c_INT8_DEFAULT)
	Int16Type = reflect.TypeOf(c_INT16_DEFAULT)
	Int32Type = reflect.TypeOf(c_INT32_DEFAULT)
	Int64Type = reflect.TypeOf(c_INT64_DEFAULT)

	UintType   = reflect.TypeOf(c_UINT_DEFAULT)
	Uint8Type  = reflect.TypeOf(c_UINT8_DEFAULT)
	Uint16Type = reflect.TypeOf(c_UINT16_DEFAULT)
	Uint32Type = reflect.TypeOf(c_UINT32_DEFAULT)
	Uint64Type = reflect.TypeOf(c_UINT64_DEFAULT)

	Float32Type = reflect.TypeOf(c_FLOAT32_DEFAULT)
	Float64Type = reflect.TypeOf(c_FLOAT64_DEFAULT)

	Complex64Type  = reflect.TypeOf(c_COMPLEX64_DEFAULT)
	Complex128Type = reflect.TypeOf(c_COMPLEX128_DEFAULT)

	StringType = reflect.TypeOf(c_EMPTY_STRING)
	BoolType   = reflect.TypeOf(c_BOOL_DEFAULT)
	ByteType   = reflect.TypeOf(c_BYTE_DEFAULT)
	BytesType  = reflect.SliceOf(ByteType)

	TimeType = reflect.TypeOf(c_TIME_DEFAULT)
)

var (
	PtrIntType   = reflect.PtrTo(IntType)
	PtrInt8Type  = reflect.PtrTo(Int8Type)
	PtrInt16Type = reflect.PtrTo(Int16Type)
	PtrInt32Type = reflect.PtrTo(Int32Type)
	PtrInt64Type = reflect.PtrTo(Int64Type)

	PtrUintType   = reflect.PtrTo(UintType)
	PtrUint8Type  = reflect.PtrTo(Uint8Type)
	PtrUint16Type = reflect.PtrTo(Uint16Type)
	PtrUint32Type = reflect.PtrTo(Uint32Type)
	PtrUint64Type = reflect.PtrTo(Uint64Type)

	PtrFloat32Type = reflect.PtrTo(Float32Type)
	PtrFloat64Type = reflect.PtrTo(Float64Type)

	PtrComplex64Type  = reflect.PtrTo(Complex64Type)
	PtrComplex128Type = reflect.PtrTo(Complex128Type)

	PtrStringType = reflect.PtrTo(StringType)
	PtrBoolType   = reflect.PtrTo(BoolType)
	PtrByteType   = reflect.PtrTo(ByteType)

	PtrTimeType = reflect.PtrTo(TimeType)
)

// Type2SQLType generate SQLType acorrding Go's type
func Type2SQLType(t reflect.Type) (st SQLType) {
	switch k := t.Kind(); k {
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32:
		st = SQLType{Int, 0, 0}
	case reflect.Int64, reflect.Uint64:
		st = SQLType{BigInt, 0, 0}
	case reflect.Float32:
		st = SQLType{Float, 0, 0}
	case reflect.Float64:
		st = SQLType{Double, 0, 0}
	case reflect.Complex64, reflect.Complex128:
		st = SQLType{Varchar, 64, 0}
	case reflect.Array, reflect.Slice, reflect.Map:
		if t.Elem() == reflect.TypeOf(c_BYTE_DEFAULT) {
			st = SQLType{Blob, 0, 0}
		} else {
			st = SQLType{Text, 0, 0}
		}
	case reflect.Bool:
		st = SQLType{Bool, 0, 0}
	case reflect.String:
		st = SQLType{Varchar, 255, 0}
	case reflect.Struct:
		if t.ConvertibleTo(TimeType) {
			st = SQLType{DateTime, 0, 0}
		} else {
			// TODO need to handle association struct
			st = SQLType{Text, 0, 0}
		}
	case reflect.Ptr:
		st = Type2SQLType(t.Elem())
	default:
		st = SQLType{Text, 0, 0}
	}
	return
}

// default sql type change to go types
func SQLType2Type(st SQLType) reflect.Type {
	name := strings.ToUpper(st.Name)
	switch name {
	case Bit, TinyInt, SmallInt, MediumInt, Int, Integer, Serial:
		return reflect.TypeOf(1)
	case BigInt, BigSerial:
		return reflect.TypeOf(int64(1))
	case Float, Real:
		return reflect.TypeOf(float32(1))
	case Double:
		return reflect.TypeOf(float64(1))
	case Char, Varchar, NVarchar, TinyText, Text, MediumText, LongText, Enum, Set, Uuid, Clob:
		return reflect.TypeOf("")
	case TinyBlob, Blob, LongBlob, Bytea, Binary, MediumBlob, VarBinary:
		return reflect.TypeOf([]byte{})
	case Bool:
		return reflect.TypeOf(true)
	case DateTime, Date, Time, TimeStamp, TimeStampz:
		return reflect.TypeOf(c_TIME_DEFAULT)
	case Decimal, Numeric:
		return reflect.TypeOf("")
	default:
		return reflect.TypeOf("")
	}
}
<|endoftext|>


<commit_before>package goldi

import (
	"fmt"
	"reflect"
	"runtime"
	"strings"
)

// A Type holds all information that is necessary to create a new instance of a type ID
type Type struct {
	generator          reflect.Value
	generatorType      reflect.Type
	generatorArguments []reflect.Value
}

// NewType creates a new Type and checks if the given factory method can be used get a go type
//
// This function will panic if the factoryFunction is no function, returns zero or more than
// one parameter or the return parameter is no pointer or interface type.
// If the number of given factoryParameters does not match the number of arguments of the
// factoryFunction this function will panic as well
func NewType(factoryFunction interface{}, factoryParameters ...interface{}) *Type {
	defer func() {
		if r := recover(); r != nil {
			panic(fmt.Errorf("could not register type: %v", r))
		}
	}()

	generatorType := reflect.TypeOf(factoryFunction)
	if generatorType.Kind() != reflect.Func {
		panic(fmt.Errorf("kind was %v, not Func", generatorType.Kind()))
	}

	if generatorType.NumOut() != 1 {
		panic(fmt.Errorf("invalid number of return parameters: %d", generatorType.NumOut()))
	}

	kindOfGeneratedType := generatorType.Out(0).Kind()
	if kindOfGeneratedType != reflect.Interface && kindOfGeneratedType != reflect.Ptr {
		panic(fmt.Errorf("return parameter is no interface or pointer but a %v", kindOfGeneratedType))
	}

	if generatorType.NumIn() != len(factoryParameters) {
		panic(fmt.Errorf("invalid number of input parameters: got %d but expected %d", generatorType.NumIn(), len(factoryParameters)))
	}

	return &Type{
		generator:          reflect.ValueOf(factoryFunction),
		generatorType:      generatorType,
		generatorArguments: buildGeneratorCallArguments(generatorType, factoryParameters),
	}
}

func buildGeneratorCallArguments(generatorType reflect.Type, factoryParameters []interface{}) []reflect.Value {
	args := make([]reflect.Value, len(factoryParameters))
	for i, argument := range factoryParameters {
		expectedArgumentType := generatorType.In(i)
		args[i] = reflect.ValueOf(argument)
		if args[i].Kind() != expectedArgumentType.Kind() {
			if stringArg, isString := argument.(string); isString && isParameterOrTypeReference(stringArg) == false {
				panic(fmt.Errorf("input argument %d is of type %s but needs to be a %s", i+1, args[i].Kind(), expectedArgumentType.Kind()))
			}
		}
	}

	return args
}

// Generate will instantiate a new instance of the according type.
// The given configuration is used to resolve parameters that are used in the type factory method
// The type registry is used to lazily resolve type references
func (t *Type) Generate(config map[string]interface{}, registry TypeRegistry) interface{} {
	defer func() {
		if r := recover(); r != nil {
			panic(fmt.Errorf("could not generate type: %v", r))
		}
	}()

	args := make([]reflect.Value, len(t.generatorArguments))
	for i, argument := range t.generatorArguments {
		args[i] = t.resolveParameter(i, argument, t.generatorType.In(i), config, registry)
	}

	result := t.generator.Call(args)
	if len(result) == 0 {
		panic(fmt.Errorf("no return parameter found. Seems like you did not use goldi.NewTypeGenerator to create this TypeGenerator"))
	}

	return result[0].Interface()
}

func (t *Type) resolveParameter(i int, argument reflect.Value, expectedArgument reflect.Type, config map[string]interface{}, registry TypeRegistry) reflect.Value {
	if argument.Kind() != reflect.String {
		return argument
	}

	stringArgument := argument.Interface().(string)
	if isParameterOrTypeReference(stringArgument) == false {
		return argument
	}

	if stringArgument[0] == '@' {
		return t.resolveTypeReference(i, stringArgument[1:], config, registry, expectedArgument)
	}

	parameterName := stringArgument[1 : len(stringArgument)-1]
	configuredValue, isConfigured := config[parameterName]
	if isConfigured == false {
		return argument
	}

	argument = reflect.New(expectedArgument).Elem()
	argument.Set(reflect.ValueOf(configuredValue))
	return argument
}

func (t *Type) resolveTypeReference(i int, typeID string, config map[string]interface{}, registry TypeRegistry, expectedArgument reflect.Type) reflect.Value {
	referencedType, typeDefined := registry[typeID]
	if typeDefined == false {
		panic(fmt.Errorf("the referenced type \"@%s\" has not been defined", typeID))
	}

	typeInstance := referencedType.Generate(config, registry)
	if reflect.TypeOf(typeInstance).AssignableTo(expectedArgument) == false {
		panic(t.invalidReferencedTypeErr(typeID, typeInstance, i))
	}

	// TODO check if this type is assignable and generate helpful error message if not
	argument := reflect.New(expectedArgument).Elem()
	argument.Set(reflect.ValueOf(typeInstance))
	return argument
}

func (t *Type) invalidReferencedTypeErr(typeID string, typeInstance interface{}, i int) error {
	factoryName := runtime.FuncForPC(t.generator.Pointer()).Name()
	factoryNameParts := strings.Split(factoryName, "/")
	factoryName = factoryNameParts[len(factoryNameParts)-1]

	n := t.generator.Type().NumIn()
	factoryArguments := make([]string, n)
	for i := 0; i < n; i++ {
		arg := t.generator.Type().In(i)
		factoryArguments[i] = arg.String()
	}

	err := fmt.Errorf("the referenced type \"@%s\" (type %T) can not be passed as argument %d to the function signature %s(%s)",
		typeID, typeInstance, i+1, factoryName, strings.Join(factoryArguments, ", "),
	)

	return err
}

// typeReferenceArguments is an internal function that returns all generator arguments that are type references
func (t *Type) typeReferenceArguments() []string {
	var typeRefParameters []string
	for _, argument := range t.generatorArguments {
		stringArgument := argument.Interface().(string)
		if isTypeReference(stringArgument) {
			typeRefParameters = append(typeRefParameters, stringArgument[1:])
		}
	}
	return typeRefParameters
}

// parameterArguments is an internal function that returns all generator arguments that are parameters
func (t *Type) parameterArguments() []string {
	var parameterArguments []string
	for _, argument := range t.generatorArguments {
		stringArgument := argument.Interface().(string)
		if isParameter(stringArgument) {
			parameterArguments = append(parameterArguments, stringArgument[1:len(stringArgument)-1])
		}
	}
	return parameterArguments
}

func isParameterOrTypeReference(p string) bool {
	return isParameter(p) || isTypeReference(p)
}

func isParameter(p string) bool {
	if len(p) < 2 {
		return false
	}

	return p[0] == '%' && p[len(p)-1] == '%'
}

func isTypeReference(p string) bool {
	if len(p) < 2 {
		return false
	}

	return p[0] == '@'
}
<commit_msg>Consequently use factory instead of generator<commit_after>package goldi

import (
	"fmt"
	"reflect"
	"runtime"
	"strings"
)

// A Type holds all information that is necessary to create a new instance of a type ID
type Type struct {
	factory          reflect.Value
	factoryType      reflect.Type
	factoryArguments []reflect.Value
}

// NewType creates a new Type and checks if the given factory method can be used get a go type
//
// This function will panic if the factoryFunction is no function, returns zero or more than
// one parameter or the return parameter is no pointer or interface type.
// If the number of given factoryParameters does not match the number of arguments of the
// factoryFunction this function will panic as well
func NewType(factoryFunction interface{}, factoryParameters ...interface{}) *Type {
	defer func() {
		if r := recover(); r != nil {
			panic(fmt.Errorf("could not register type: %v", r))
		}
	}()

	factoryType := reflect.TypeOf(factoryFunction)
	if factoryType.Kind() != reflect.Func {
		panic(fmt.Errorf("kind was %v, not Func", factoryType.Kind()))
	}

	if factoryType.NumOut() != 1 {
		panic(fmt.Errorf("invalid number of return parameters: %d", factoryType.NumOut()))
	}

	kindOfGeneratedType := factoryType.Out(0).Kind()
	if kindOfGeneratedType != reflect.Interface && kindOfGeneratedType != reflect.Ptr {
		panic(fmt.Errorf("return parameter is no interface or pointer but a %v", kindOfGeneratedType))
	}

	if factoryType.NumIn() != len(factoryParameters) {
		panic(fmt.Errorf("invalid number of input parameters: got %d but expected %d", factoryType.NumIn(), len(factoryParameters)))
	}

	return &Type{
		factory:          reflect.ValueOf(factoryFunction),
		factoryType:      factoryType,
		factoryArguments: buildFactoryCallArguments(factoryType, factoryParameters),
	}
}

func buildFactoryCallArguments(factoryType reflect.Type, factoryParameters []interface{}) []reflect.Value {
	args := make([]reflect.Value, len(factoryParameters))
	for i, argument := range factoryParameters {
		expectedArgumentType := factoryType.In(i)
		args[i] = reflect.ValueOf(argument)
		if args[i].Kind() != expectedArgumentType.Kind() {
			if stringArg, isString := argument.(string); isString && isParameterOrTypeReference(stringArg) == false {
				panic(fmt.Errorf("input argument %d is of type %s but needs to be a %s", i+1, args[i].Kind(), expectedArgumentType.Kind()))
			}
		}
	}

	return args
}

// Generate will instantiate a new instance of the according type.
// The given configuration is used to resolve parameters that are used in the type factory method
// The type registry is used to lazily resolve type references
func (t *Type) Generate(config map[string]interface{}, registry TypeRegistry) interface{} {
	defer func() {
		if r := recover(); r != nil {
			panic(fmt.Errorf("could not generate type: %v", r))
		}
	}()

	args := make([]reflect.Value, len(t.factoryArguments))
	for i, argument := range t.factoryArguments {
		args[i] = t.resolveParameter(i, argument, t.factoryType.In(i), config, registry)
	}

	result := t.factory.Call(args)
	if len(result) == 0 {
		panic(fmt.Errorf("no return parameter found. Seems like you did not use goldi.NewType to create this Type"))
	}

	return result[0].Interface()
}

func (t *Type) resolveParameter(i int, argument reflect.Value, expectedArgument reflect.Type, config map[string]interface{}, registry TypeRegistry) reflect.Value {
	if argument.Kind() != reflect.String {
		return argument
	}

	stringArgument := argument.Interface().(string)
	if isParameterOrTypeReference(stringArgument) == false {
		return argument
	}

	if stringArgument[0] == '@' {
		return t.resolveTypeReference(i, stringArgument[1:], config, registry, expectedArgument)
	}

	parameterName := stringArgument[1 : len(stringArgument)-1]
	configuredValue, isConfigured := config[parameterName]
	if isConfigured == false {
		return argument
	}

	argument = reflect.New(expectedArgument).Elem()
	argument.Set(reflect.ValueOf(configuredValue))
	return argument
}

func (t *Type) resolveTypeReference(i int, typeID string, config map[string]interface{}, registry TypeRegistry, expectedArgument reflect.Type) reflect.Value {
	referencedType, typeDefined := registry[typeID]
	if typeDefined == false {
		panic(fmt.Errorf("the referenced type \"@%s\" has not been defined", typeID))
	}

	typeInstance := referencedType.Generate(config, registry)
	if reflect.TypeOf(typeInstance).AssignableTo(expectedArgument) == false {
		panic(t.invalidReferencedTypeErr(typeID, typeInstance, i))
	}

	argument := reflect.New(expectedArgument).Elem()
	argument.Set(reflect.ValueOf(typeInstance))
	return argument
}

func (t *Type) invalidReferencedTypeErr(typeID string, typeInstance interface{}, i int) error {
	factoryName := runtime.FuncForPC(t.factory.Pointer()).Name()
	factoryNameParts := strings.Split(factoryName, "/")
	factoryName = factoryNameParts[len(factoryNameParts)-1]

	n := t.factory.Type().NumIn()
	factoryArguments := make([]string, n)
	for i := 0; i < n; i++ {
		arg := t.factory.Type().In(i)
		factoryArguments[i] = arg.String()
	}

	err := fmt.Errorf("the referenced type \"@%s\" (type %T) can not be passed as argument %d to the function signature %s(%s)",
		typeID, typeInstance, i+1, factoryName, strings.Join(factoryArguments, ", "),
	)

	return err
}

// typeReferenceArguments is an internal function that returns all factory arguments that are type references
func (t *Type) typeReferenceArguments() []string {
	var typeRefParameters []string
	for _, argument := range t.factoryArguments {
		stringArgument := argument.Interface().(string)
		if isTypeReference(stringArgument) {
			typeRefParameters = append(typeRefParameters, stringArgument[1:])
		}
	}
	return typeRefParameters
}

// parameterArguments is an internal function that returns all factory arguments that are parameters
func (t *Type) parameterArguments() []string {
	var parameterArguments []string
	for _, argument := range t.factoryArguments {
		stringArgument := argument.Interface().(string)
		if isParameter(stringArgument) {
			parameterArguments = append(parameterArguments, stringArgument[1:len(stringArgument)-1])
		}
	}
	return parameterArguments
}

func isParameterOrTypeReference(p string) bool {
	return isParameter(p) || isTypeReference(p)
}

func isParameter(p string) bool {
	if len(p) < 2 {
		return false
	}

	return p[0] == '%' && p[len(p)-1] == '%'
}

func isTypeReference(p string) bool {
	if len(p) < 2 {
		return false
	}

	return p[0] == '@'
}
<|endoftext|>


<commit_before>// Copyright 2016 Compose, an IBM Company
//
// 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 composeapi

import (
	"encoding/json"
)

// User structure
type User struct {
	ID string `json:"id"`
}

//GetUserJSON returns user JSON string
func (c *Client) GetUserJSON() (string, []error) {
	return c.getJSON("user")
}

//GetUser Gets information about user
func (c *Client) GetUser() (*User, []error) {
	body, errs := c.GetUserJSON()

	if errs != nil {
		return nil, errs
	}

	user := User{}
	json.Unmarshal([]byte(body), &user)
	return &user, nil
}
<commit_msg>Add the 'Name' field to the 'User' struct<commit_after>// Copyright 2016 Compose, an IBM Company
//
// 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 composeapi

import (
	"encoding/json"
)

// User structure
type User struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

//GetUserJSON returns user JSON string
func (c *Client) GetUserJSON() (string, []error) {
	return c.getJSON("user")
}

//GetUser Gets information about user
func (c *Client) GetUser() (*User, []error) {
	body, errs := c.GetUserJSON()

	if errs != nil {
		return nil, errs
	}

	user := User{}
	json.Unmarshal([]byte(body), &user)
	return &user, nil
}
<|endoftext|>


<commit_before>package victorops

import "net/url"

// User contains all the information of a user
type User struct {
	FirstName           string `json:"firstName"`
	LastName            string `json:"lastName"`
	UserName            string `json:"username"`
	Email               string `json:"email"`
	CreatedAt           string `json:"createdAt"`
	PasswordLastUpdated string `json:"passwordLastUpdated"`
	Verified            bool   `json:"verified"`
	SelfURL             string `json:"_selfUrl"`
}

// UsersResponse response to GetUsers
type usersResponse struct {
	Members [][]User `json:"users"`
	SelfURL string   `json:"_selfUrl"`
}

// UserInfo params for creating/modifying a user
type UserInfo struct {
	firstName       string
	lastName        string
	username        string
	email           string
	admin           bool
	expirationHours int
}

// GetUsers Get a list of users for your organization
func (client *Client) GetUsers() ([][]User, error) {
	var (
		users [][]User
	)
	response := &usersResponse{}
	err := client.get("api-public/v1/user", url.Values{}, response, true)
	if err != nil {
		return users, err
	}
	return response.Members, nil
}

// AddUser Add a user to your organization
func (client *Client) AddUser(info UserInfo) (User, error) {
	return User{}, nil
}

// RemoveUser Remove a user from your organization
func (client *Client) RemoveUser(user, replacement string) error {
	return nil
}

// GetUserInfo Get the information for the specified user
func (client *Client) GetUserInfo(user string) (User, error) {
	return User{}, nil
}

// UpdateUser Update the designated user
func (client *Client) UpdateUser(info UserInfo) (User, error) {
	return User{}, nil
}
<commit_msg>implement GetUserInfo method<commit_after>package victorops

import "net/url"

// User contains all the information of a user
type User struct {
	FirstName           string `json:"firstName"`
	LastName            string `json:"lastName"`
	UserName            string `json:"username"`
	Email               string `json:"email"`
	CreatedAt           string `json:"createdAt"`
	PasswordLastUpdated string `json:"passwordLastUpdated"`
	Verified            bool   `json:"verified"`
	SelfURL             string `json:"_selfUrl"`
}

// UsersResponse response to GetUsers
type usersResponse struct {
	Members [][]User `json:"users"`
	SelfURL string   `json:"_selfUrl"`
}

// UserInfo params for creating/modifying a user
type UserInfo struct {
	firstName       string
	lastName        string
	username        string
	email           string
	admin           bool
	expirationHours int
}

// GetUsers Get a list of users for your organization
func (client *Client) GetUsers() ([][]User, error) {
	var (
		users [][]User
	)
	response := &usersResponse{}
	err := client.get("api-public/v1/user", url.Values{}, response, true)
	if err != nil {
		return users, err
	}
	return response.Members, nil
}

// AddUser Add a user to your organization
func (client *Client) AddUser(info UserInfo) (User, error) {
	return User{}, nil
}

// RemoveUser Remove a user from your organization
func (client *Client) RemoveUser(user, replacement string) error {
	return nil
}

// GetUserInfo Get the information for the specified user
func (client *Client) GetUserInfo(nick string) (User, error) {
	response := &User{}
	err := client.get("api-public/v1/user/"+nick, url.Values{}, response, true)
	if err != nil {
		return User{}, err
	}
	return *response, nil
}

// UpdateUser Update the designated user
func (client *Client) UpdateUser(info UserInfo) (User, error) {
	return User{}, nil
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/russross/blackfriday"
	"github.com/spf13/viper"
)

// append to list if not in list already
func appendNew(list []string, name string) []string {
	found := false
	for _, el := range list {
		if el == name {
			found = true
		}
	}
	if !found {
		list = append(list, name)
	}
	return list
}

// load params config

func loadConfig() (*viper.Viper, error) {
	config := viper.New()
	config.SetConfigName("params")
	config.SetConfigType("toml")
	config.AddConfigPath(".")
	err := config.ReadInConfig()
	if err != nil {
		return nil, err
	}
	return config, nil
}

func markdown2html(b []byte) []byte {
	return blackfriday.MarkdownBasic(b)
}
<commit_msg>update blackfriday to v2<commit_after>package main

import (
	"github.com/russross/blackfriday"
	"github.com/spf13/viper"
)

// append to list if not in list already
func appendNew(list []string, name string) []string {
	found := false
	for _, el := range list {
		if el == name {
			found = true
		}
	}
	if !found {
		list = append(list, name)
	}
	return list
}

// load params config

func loadConfig() (*viper.Viper, error) {
	config := viper.New()
	config.SetConfigName("params")
	config.SetConfigType("toml")
	config.AddConfigPath(".")
	err := config.ReadInConfig()
	if err != nil {
		return nil, err
	}
	return config, nil
}

func markdown2html(b []byte) []byte {
	return blackfriday.Run(b, blackfriday.WithNoExtensions())
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"path"
	"regexp"
	"strconv"
)

const _WIKIWORD_RE = "([A-Z]+[A-Za-z0-9_]*){2,}"
const _WIKIWORD_ONLY_RE = "^" + _WIKIWORD_RE + "$"

var WIKIWORD_RE = regexp.MustCompile(_WIKIWORD_RE)
var WIKIWORD_ONLY_RE = regexp.MustCompile(_WIKIWORD_ONLY_RE)

// Is the given string a WikiWord
func IsWikiWord(word string) bool {
	return WIKIWORD_RE.MatchString(word)
}

func ExpandWikiWords(input []byte) []byte {
	l, ch := NewLexer(input)
	go l.Run()

	buf := &bytes.Buffer{}

	done := false
	for !done {
		item := <-ch
		switch item.Type {
		case TokenErr:
			done = true
		case TokenEOF:
			fmt.Println("Got an EOF")
			done = true
		case TokenWikiWord:
			buf.Write([]byte("["))
			buf.Write(item.Value)
			buf.Write([]byte("](/"))
			buf.Write(item.Value)
			buf.Write([]byte("/)"))
		default:
			buf.Write(item.Value)
		}
	}
	fmt.Println("Returning ", buf.String())
	return buf.Bytes()
}

func writeAndClose(wc io.WriteCloser, value []byte) error {
	defer wc.Close()
	_, err := wc.Write(value)
	return err
}

func copyAndClose(wc io.WriteCloser, input io.Reader) error {
	defer wc.Close()
	_, err := io.Copy(wc, input)
	return err
}

func getMaxFDBRevision(fInfos []os.FileInfo) int {
	maxRevision := -1
	for _, info := range fInfos {
		name := path.Base(info.Name())
		if fdb_Page_re.MatchString(name) {
			// Atoi cannot fail after passing the re test above
			if cur, err := strconv.Atoi(name); err == nil && cur > maxRevision {
				maxRevision = cur
			}
		}
	}
	return maxRevision
}

func getCountFDBAttachments(fInfos []os.FileInfo) int {
	count := 0
	for _, info := range fInfos {
		name := path.Base(info.Name())
		if fdb_Attachment_re.MatchString(name) {
			count++
		}
	}
	return count
}

func generateRevisionSplit(currentRevision, maxRevision int) (cur, min, max int) {
	cur = currentRevision
	if currentRevision < 0 {
		cur = maxRevision
	}
	max = cur + 5
	if max > maxRevision {
		max = maxRevision
	}
	min = cur - 5
	if min < 0 {
		min = 0
	}
	return cur, min, max
}

func generateInt(begin, end int) <-chan int {
	ch := make(chan int)

	go func() {
		defer close(ch)
		step := 1
		if begin >= end {
			step = -1
		}
		for i := begin; i != end; i += step {
			ch <- i
		}
		ch <- end
	}()
	return ch
}

func getListenAddress() string {
	return ""
}
<commit_msg>Fixed IsWikiWord to use a regexp on the whole string.<commit_after>package main

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"path"
	"regexp"
	"strconv"
)

const _WIKIWORD_RE = "([A-Z]+[A-Za-z0-9_]*){2,}"
const _WIKIWORD_ONLY_RE = "^" + _WIKIWORD_RE + "$"

var WIKIWORD_RE = regexp.MustCompile(_WIKIWORD_RE)
var WIKIWORD_ONLY_RE = regexp.MustCompile(_WIKIWORD_ONLY_RE)

// Is the given string a WikiWord
func IsWikiWord(word string) bool {
	return WIKIWORD_ONLY_RE.MatchString(word)
}

func ExpandWikiWords(input []byte) []byte {
	l, ch := NewLexer(input)
	go l.Run()

	buf := &bytes.Buffer{}

	done := false
	for !done {
		item := <-ch
		switch item.Type {
		case TokenErr:
			done = true
		case TokenEOF:
			fmt.Println("Got an EOF")
			done = true
		case TokenWikiWord:
			buf.Write([]byte("["))
			buf.Write(item.Value)
			buf.Write([]byte("](/"))
			buf.Write(item.Value)
			buf.Write([]byte("/)"))
		default:
			buf.Write(item.Value)
		}
	}
	fmt.Println("Returning ", buf.String())
	return buf.Bytes()
}

func writeAndClose(wc io.WriteCloser, value []byte) error {
	defer wc.Close()
	_, err := wc.Write(value)
	return err
}

func copyAndClose(wc io.WriteCloser, input io.Reader) error {
	defer wc.Close()
	_, err := io.Copy(wc, input)
	return err
}

func getMaxFDBRevision(fInfos []os.FileInfo) int {
	maxRevision := -1
	for _, info := range fInfos {
		name := path.Base(info.Name())
		if fdb_Page_re.MatchString(name) {
			// Atoi cannot fail after passing the re test above
			if cur, err := strconv.Atoi(name); err == nil && cur > maxRevision {
				maxRevision = cur
			}
		}
	}
	return maxRevision
}

func getCountFDBAttachments(fInfos []os.FileInfo) int {
	count := 0
	for _, info := range fInfos {
		name := path.Base(info.Name())
		if fdb_Attachment_re.MatchString(name) {
			count++
		}
	}
	return count
}

func generateRevisionSplit(currentRevision, maxRevision int) (cur, min, max int) {
	cur = currentRevision
	if currentRevision < 0 {
		cur = maxRevision
	}
	max = cur + 5
	if max > maxRevision {
		max = maxRevision
	}
	min = cur - 5
	if min < 0 {
		min = 0
	}
	return cur, min, max
}

func generateInt(begin, end int) <-chan int {
	ch := make(chan int)

	go func() {
		defer close(ch)
		step := 1
		if begin >= end {
			step = -1
		}
		for i := begin; i != end; i += step {
			ch <- i
		}
		ch <- end
	}()
	return ch
}

func getListenAddress() string {
	return ""
}
<|endoftext|>


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

package gocui

import (
	"bufio"
	"bytes"
	"errors"
	"strings"

	"github.com/nsf/termbox-go"
)

// A View is a window. It maintains its own internal buffer and cursor
// position.
type View struct {
	name                   string
	x0, y0, x1, y1         int
	ox, oy                 int
	cx, cy                 int
	lines                  [][]rune
	bgColor, fgColor       Attribute
	selBgColor, selFgColor Attribute
	overwrite              bool // overwrite in edit mode

	// If Editable is true, keystrokes will be added to the view's internal
	// buffer at the cursor position.
	Editable bool

	// If Highlight is true, Sel{Bg,Fg}Colors will be used
	// for the line under the cursor position.
	Highlight bool
}

// newView returns a new View object.
func newView(name string, x0, y0, x1, y1 int) *View {
	v := &View{
		name: name,
		x0:   x0,
		y0:   y0,
		x1:   x1,
		y1:   y1,
	}
	return v
}

// Size returns the number of visible columns and rows in the View.
func (v *View) Size() (x, y int) {
	return v.x1 - v.x0 - 1, v.y1 - v.y0 - 1
}

// Name returns the name of the view.
func (v *View) Name() string {
	return v.name
}

// setRune writes a rune at the given point, relative to the view. It
// checks if the position is valid and applies the view's colors, taking
// into account if the cell must be highlighted.
func (v *View) setRune(x, y int, ch rune) error {
	maxX, maxY := v.Size()
	if x < 0 || x >= maxX || y < 0 || y >= maxY {
		return errors.New("invalid point")
	}

	var fgColor, bgColor Attribute
	if v.Highlight && y == v.cy {
		fgColor = v.selFgColor
		bgColor = v.selBgColor
	} else {
		fgColor = v.fgColor
		bgColor = v.bgColor
	}
	termbox.SetCell(v.x0+x+1, v.y0+y+1, ch,
		termbox.Attribute(fgColor), termbox.Attribute(bgColor))
	return nil
}

// SetCursor sets the cursor position of the view at the given point,
// relative to the view. It checks if the position is valid.
func (v *View) SetCursor(x, y int) error {
	maxX, maxY := v.Size()
	if x < 0 || x >= maxX || y < 0 || y >= maxY {
		return errors.New("invalid point")
	}
	v.cx = x
	v.cy = y
	return nil
}

// Cursor returns the cursor position of the view.
func (v *View) Cursor() (x, y int) {
	return v.cx, v.cy
}

// SetOrigin sets the origin position of the view's internal buffer,
// so the buffer starts to be printed from this point, which means that
// it is linked with the origin point of view. It can be used to
// implement Horizontal and Vertical scrolling with just incrementing
// or decrementing ox and oy.
func (v *View) SetOrigin(x, y int) error {
	if x < 0 || y < 0 {
		return errors.New("invalid point")
	}
	v.ox = x
	v.oy = y
	return nil
}

// Origin returns the origin position of the view.
func (v *View) Origin() (x, y int) {
	return v.ox, v.oy
}

// Write appends a byte slice into the view's internal buffer. Because
// View implements the io.Writer interface, it can be passed as parameter
// of functions like fmt.Fprintf, fmt.Fprintln, io.Copy, etc. Clear must
// be called to clear the view's buffer.
func (v *View) Write(p []byte) (n int, err error) {
	r := bytes.NewReader(p)
	s := bufio.NewScanner(r)
	for s.Scan() {
		line := bytes.Runes(s.Bytes())
		v.lines = append(v.lines, line)
	}
	if err := s.Err(); err != nil {
		return 0, err
	}
	return len(p), nil
}

// draw re-draws the view's contents.
func (v *View) draw() error {
	maxX, maxY := v.Size()
	y := 0
	for i, line := range v.lines {
		if i < v.oy {
			continue
		}
		x := 0
		for j, ch := range line {
			if j < v.ox {
				continue
			}
			if x >= 0 && x < maxX && y >= 0 && y < maxY {
				if err := v.setRune(x, y, ch); err != nil {
					return err
				}
			}
			x++
		}
		y++
	}
	return nil
}

// Clear empties the view's internal buffer.
func (v *View) Clear() {
	v.lines = nil
	v.clearRunes()
}

// clearRunes erases all the cells in the view.
func (v *View) clearRunes() {
	maxX, maxY := v.Size()
	for x := 0; x < maxX; x++ {
		for y := 0; y < maxY; y++ {
			termbox.SetCell(v.x0+x+1, v.y0+y+1, ' ',
				termbox.Attribute(v.fgColor), termbox.Attribute(v.bgColor))
		}
	}
}

// writeRune writes a rune into the view's internal buffer, at the
// position corresponding to the point (x, y). The length of the internal
// buffer is increased if the point is out of bounds. Overwrite mode is
// governed by the value of View.overwrite.
func (v *View) writeRune(x, y int, ch rune) error {
	x = v.ox + x
	y = v.oy + y

	if x < 0 || y < 0 {
		return errors.New("invalid point")
	}

	if y >= len(v.lines) {
		if y >= cap(v.lines) {
			s := make([][]rune, y+1, (y+1)*2)
			copy(s, v.lines)
			v.lines = s
		} else {
			v.lines = v.lines[:y+1]
		}
	}
	if v.lines[y] == nil {
		v.lines[y] = make([]rune, x+1, (x+1)*2)
	} else if x >= len(v.lines[y]) {
		if x >= cap(v.lines[y]) {
			s := make([]rune, x+1, (x+1)*2)
			copy(s, v.lines[y])
			v.lines[y] = s
		} else {
			v.lines[y] = v.lines[y][:x+1]
		}
	}
	if !v.overwrite {
		v.lines[y] = append(v.lines[y], ' ')
		copy(v.lines[y][x+1:], v.lines[y][x:])
	}
	v.lines[y][x] = ch
	return nil
}

// deleteRune removes a rune from the view's internal buffer, at the
// position corresponding to the point (x, y).
func (v *View) deleteRune(x, y int) error {
	x = v.ox + x
	y = v.oy + y

	if x < 0 || y < 0 || y >= len(v.lines) || v.lines[y] == nil || x >= len(v.lines[y]) {
		return errors.New("invalid point")
	}
	copy(v.lines[y][x:], v.lines[y][x+1:])
	v.lines[y][len(v.lines[y])-1] = ' '
	return nil
}

// addLine adds a line into the view's internal buffer at the position
// corresponding to the point (x, y).
func (v *View) addLine(y int) error {
	y = v.oy + y

	if y < 0 || y >= len(v.lines) {
		return errors.New("invalid point")
	}
	v.lines = append(v.lines, nil)
	copy(v.lines[y+1:], v.lines[y:])
	v.lines[y] = nil
	return nil
}

// Line returns a string with the line of the view's internal buffer
// at the position corresponding to the point (x, y).
func (v *View) Line(y int) (string, error) {
	y = v.oy + y

	if y < 0 || y >= len(v.lines) {
		return "", errors.New("invalid point")
	}
	return string(v.lines[y]), nil
}

// Word returns a string with the word of the view's internal buffer
// at the position corresponding to the point (x, y).
func (v *View) Word(x, y int) (string, error) {
	x = v.ox + x
	y = v.oy + y

	if y < 0 || y >= len(v.lines) || x >= len(v.lines[y]) {
		return "", errors.New("invalid point")
	}
	l := string(v.lines[y])
	nl := strings.LastIndexFunc(l[:x], indexFunc)
	if nl == -1 {
		nl = 0
	} else {
		nl = nl + 1
	}
	nr := strings.IndexFunc(l[x:], indexFunc)
	if nr == -1 {
		nr = len(l)
	} else {
		nr = nr + x
	}
	return string(l[nl:nr]), nil
}

// indexFunc allows to split lines by words taking into account spaces
// and 0
func indexFunc(r rune) bool {
	return r == ' ' || r == 0
}
<commit_msg>Add View.Buffer()<commit_after>// Copyright 2014 The gocui Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gocui

import (
	"bufio"
	"bytes"
	"errors"
	"strings"

	"github.com/nsf/termbox-go"
)

// A View is a window. It maintains its own internal buffer and cursor
// position.
type View struct {
	name                   string
	x0, y0, x1, y1         int
	ox, oy                 int
	cx, cy                 int
	lines                  [][]rune
	bgColor, fgColor       Attribute
	selBgColor, selFgColor Attribute
	overwrite              bool // overwrite in edit mode

	// If Editable is true, keystrokes will be added to the view's internal
	// buffer at the cursor position.
	Editable bool

	// If Highlight is true, Sel{Bg,Fg}Colors will be used
	// for the line under the cursor position.
	Highlight bool
}

// newView returns a new View object.
func newView(name string, x0, y0, x1, y1 int) *View {
	v := &View{
		name: name,
		x0:   x0,
		y0:   y0,
		x1:   x1,
		y1:   y1,
	}
	return v
}

// Size returns the number of visible columns and rows in the View.
func (v *View) Size() (x, y int) {
	return v.x1 - v.x0 - 1, v.y1 - v.y0 - 1
}

// Name returns the name of the view.
func (v *View) Name() string {
	return v.name
}

// setRune writes a rune at the given point, relative to the view. It
// checks if the position is valid and applies the view's colors, taking
// into account if the cell must be highlighted.
func (v *View) setRune(x, y int, ch rune) error {
	maxX, maxY := v.Size()
	if x < 0 || x >= maxX || y < 0 || y >= maxY {
		return errors.New("invalid point")
	}

	var fgColor, bgColor Attribute
	if v.Highlight && y == v.cy {
		fgColor = v.selFgColor
		bgColor = v.selBgColor
	} else {
		fgColor = v.fgColor
		bgColor = v.bgColor
	}
	termbox.SetCell(v.x0+x+1, v.y0+y+1, ch,
		termbox.Attribute(fgColor), termbox.Attribute(bgColor))
	return nil
}

// SetCursor sets the cursor position of the view at the given point,
// relative to the view. It checks if the position is valid.
func (v *View) SetCursor(x, y int) error {
	maxX, maxY := v.Size()
	if x < 0 || x >= maxX || y < 0 || y >= maxY {
		return errors.New("invalid point")
	}
	v.cx = x
	v.cy = y
	return nil
}

// Cursor returns the cursor position of the view.
func (v *View) Cursor() (x, y int) {
	return v.cx, v.cy
}

// SetOrigin sets the origin position of the view's internal buffer,
// so the buffer starts to be printed from this point, which means that
// it is linked with the origin point of view. It can be used to
// implement Horizontal and Vertical scrolling with just incrementing
// or decrementing ox and oy.
func (v *View) SetOrigin(x, y int) error {
	if x < 0 || y < 0 {
		return errors.New("invalid point")
	}
	v.ox = x
	v.oy = y
	return nil
}

// Origin returns the origin position of the view.
func (v *View) Origin() (x, y int) {
	return v.ox, v.oy
}

// Write appends a byte slice into the view's internal buffer. Because
// View implements the io.Writer interface, it can be passed as parameter
// of functions like fmt.Fprintf, fmt.Fprintln, io.Copy, etc. Clear must
// be called to clear the view's buffer.
func (v *View) Write(p []byte) (n int, err error) {
	r := bytes.NewReader(p)
	s := bufio.NewScanner(r)
	for s.Scan() {
		line := bytes.Runes(s.Bytes())
		v.lines = append(v.lines, line)
	}
	if err := s.Err(); err != nil {
		return 0, err
	}
	return len(p), nil
}

// draw re-draws the view's contents.
func (v *View) draw() error {
	maxX, maxY := v.Size()
	y := 0
	for i, line := range v.lines {
		if i < v.oy {
			continue
		}
		x := 0
		for j, ch := range line {
			if j < v.ox {
				continue
			}
			if x >= 0 && x < maxX && y >= 0 && y < maxY {
				if err := v.setRune(x, y, ch); err != nil {
					return err
				}
			}
			x++
		}
		y++
	}
	return nil
}

// Clear empties the view's internal buffer.
func (v *View) Clear() {
	v.lines = nil
	v.clearRunes()
}

// clearRunes erases all the cells in the view.
func (v *View) clearRunes() {
	maxX, maxY := v.Size()
	for x := 0; x < maxX; x++ {
		for y := 0; y < maxY; y++ {
			termbox.SetCell(v.x0+x+1, v.y0+y+1, ' ',
				termbox.Attribute(v.fgColor), termbox.Attribute(v.bgColor))
		}
	}
}

// writeRune writes a rune into the view's internal buffer, at the
// position corresponding to the point (x, y). The length of the internal
// buffer is increased if the point is out of bounds. Overwrite mode is
// governed by the value of View.overwrite.
func (v *View) writeRune(x, y int, ch rune) error {
	x = v.ox + x
	y = v.oy + y

	if x < 0 || y < 0 {
		return errors.New("invalid point")
	}

	if y >= len(v.lines) {
		if y >= cap(v.lines) {
			s := make([][]rune, y+1, (y+1)*2)
			copy(s, v.lines)
			v.lines = s
		} else {
			v.lines = v.lines[:y+1]
		}
	}
	if v.lines[y] == nil {
		v.lines[y] = make([]rune, x+1, (x+1)*2)
	} else if x >= len(v.lines[y]) {
		if x >= cap(v.lines[y]) {
			s := make([]rune, x+1, (x+1)*2)
			copy(s, v.lines[y])
			v.lines[y] = s
		} else {
			v.lines[y] = v.lines[y][:x+1]
		}
	}
	if !v.overwrite {
		v.lines[y] = append(v.lines[y], ' ')
		copy(v.lines[y][x+1:], v.lines[y][x:])
	}
	v.lines[y][x] = ch
	return nil
}

// deleteRune removes a rune from the view's internal buffer, at the
// position corresponding to the point (x, y).
func (v *View) deleteRune(x, y int) error {
	x = v.ox + x
	y = v.oy + y

	if x < 0 || y < 0 || y >= len(v.lines) || v.lines[y] == nil || x >= len(v.lines[y]) {
		return errors.New("invalid point")
	}
	copy(v.lines[y][x:], v.lines[y][x+1:])
	v.lines[y][len(v.lines[y])-1] = ' '
	return nil
}

// addLine adds a line into the view's internal buffer at the position
// corresponding to the point (x, y).
func (v *View) addLine(y int) error {
	y = v.oy + y

	if y < 0 || y >= len(v.lines) {
		return errors.New("invalid point")
	}
	v.lines = append(v.lines, nil)
	copy(v.lines[y+1:], v.lines[y:])
	v.lines[y] = nil
	return nil
}

// Buffer returns a string with the contents of the view's internal
// buffer
func (v *View) Buffer() string {
	str := ""
	for _, l := range v.lines {
		str += string(l) + "\n"
	}
	return strings.Replace(str, "\x00", " ", -1)
}

// Line returns a string with the line of the view's internal buffer
// at the position corresponding to the point (x, y).
func (v *View) Line(y int) (string, error) {
	y = v.oy + y

	if y < 0 || y >= len(v.lines) {
		return "", errors.New("invalid point")
	}
	return string(v.lines[y]), nil
}

// Word returns a string with the word of the view's internal buffer
// at the position corresponding to the point (x, y).
func (v *View) Word(x, y int) (string, error) {
	x = v.ox + x
	y = v.oy + y

	if y < 0 || y >= len(v.lines) || x >= len(v.lines[y]) {
		return "", errors.New("invalid point")
	}
	l := string(v.lines[y])
	nl := strings.LastIndexFunc(l[:x], indexFunc)
	if nl == -1 {
		nl = 0
	} else {
		nl = nl + 1
	}
	nr := strings.IndexFunc(l[x:], indexFunc)
	if nr == -1 {
		nr = len(l)
	} else {
		nr = nr + x
	}
	return string(l[nl:nr]), nil
}

// indexFunc allows to split lines by words taking into account spaces
// and 0
func indexFunc(r rune) bool {
	return r == ' ' || r == 0
}
<|endoftext|>


<commit_before>/* 	vote.go
_________________________________
Parses commands and executes them for Kylixor Discord Bot
Andrew Langhill
kylixor.com
*/

package main

import (
	"fmt"
	"strings"

	"github.com/bwmarrin/discordgo"
)

//startVote - begin a vote with variable vote options
func startVote(s *discordgo.Session, m *discordgo.MessageCreate, data string) bool {
	array := strings.SplitAfter(data, " ")
	options := array[0]
	text := array[1]

	switch options {
	case "1":
		s.ChannelMessageSend(m.ChannelID, "Starting vote...Upvote/Downvote to cast your vote")
		quoteMsg, _ := s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("```\n%s\n```", text))
		s.MessageReactionAdd(m.ChannelID, quoteMsg.ID, "upvote:402490285365657600")
		s.MessageReactionAdd(m.ChannelID, quoteMsg.ID, "downvote:402490335789318144")
		break

	default:
		break
	}

	return false
}
<commit_msg>More work on vote commands<commit_after>/* 	vote.go
_________________________________
Parses commands and executes them for Kylixor Discord Bot
Andrew Langhill
kylixor.com
*/

package main

import (
	"fmt"
	"strconv"
	"strings"

	"github.com/bwmarrin/discordgo"
)

//startVote - begin a vote with variable vote options
func startVote(s *discordgo.Session, m *discordgo.MessageCreate, data string) bool {
	//Parse the incoming command into data and strings
	array := strings.SplitAfterN(data, " ", 1)
	options := array[0]
	text := array[1]
	optionNum, err := strconv.Atoi(options)
	if err != nil {
		panic(err)
	}

	//How many vote options
	switch optionNum {
	case 1:
		s.ChannelMessageSend(m.ChannelID, "Starting vote...Upvote/Downvote to cast your vote")
		quoteMsg, _ := s.ChannelMessageSend(m.ChannelID, fmt.Sprintf("```\n%s\n```", text))
		s.MessageReactionAdd(m.ChannelID, quoteMsg.ID, "upvote:402490285365657600")
		s.MessageReactionAdd(m.ChannelID, quoteMsg.ID, "downvote:402490335789318144")
		//GetVoteResults(s, m, optionNum)
		break

	default:
		break
	}

	return false
}
<|endoftext|>


<commit_before>package mirror

import (
	"reflect"
)

// VisitType
type VisitType func(t *reflect.StructField, typeIndex, depth int) error

type typeWalker struct {
	indices map[reflect.Type]int
	types   []reflect.Type
}

func (walker *typeWalker) index(t reflect.Type) (int, bool) {
	idx, known := walker.indices[t]
	if known {
		return idx, true
	}
	idx = len(walker.types)
	walker.indices[t] = idx
	walker.types = append(walker.types, t)
	return idx, false
}

func (walker *typeWalker) walk(t *reflect.StructField, visit VisitType) error {
	if t == nil || visit == nil {
		return nil
	}
	type stackNode struct {
		field      *reflect.StructField
		currentIdx int
		parentIdx  int
		depth      int
		known      bool
	}
	idx, known := walker.index(t.Type)
	stack := []stackNode{{t, idx, idx, 0, known}}
	var node stackNode
	for len(stack) > 0 {
		node, stack = stack[0], stack[1:]
		err := visit(node.field, node.currentIdx, node.depth)
		if err != nil {
			return err
		}
		if node.known {
			// to prevent endless loops, don't follow known types
			continue
		}
		// follow container types
		parentIdx := node.currentIdx
		depth := node.depth + 1
		switch t := node.field.Type; t.Kind() {
		case reflect.Struct:
			fields := t.NumField()
			newNodes := make([]stackNode, 0, len(stack)+fields)
			for i := 0; i < fields; i++ {
				// add each field from struct to stack
				field := t.Field(i)
				typeIdx, known := walker.index(field.Type)
				newNodes = append(newNodes, stackNode{&field, typeIdx, parentIdx, depth, known})
			}
			newNodes = append(newNodes, stack...)
		case reflect.Ptr, reflect.Array, reflect.Slice, reflect.Map, reflect.Chan:
			// add element to stack
			field := &reflect.StructField{Type: t.Elem()}
			typeIdx, known := walker.index(field.Type)
			stack = append([]stackNodes{stackNode{&field, typeIdx, parentIdx, depth, known}}, stack...)
		}
	}
	return nil
}

// Walk will call visit on t and each type in t.
// It will follow struct fields, pointers, arrays, slices, maps and chans
// and call visit on each element.
// For struct fields, Walk will only follow into fields at the first occurence of their type.
// Function handling for reflect.Interface and reflect.Method has to be done by visit.
func Walk(t reflect.Type, visit VisitType) error {
	walker := &typeWalker{indices: make(map[reflect.Type]int)}
	return walker.walk(&reflect.StructField{Type: t}, visit)
}
<commit_msg>at it...<commit_after>package mirror

import (
	"reflect"
)

// VisitType
type VisitType func(t *reflect.StructField, typeIndex, depth int) error

type typeWalker struct {
	indices map[reflect.Type]int
	types   []reflect.Type
}

func (walker *typeWalker) index(t reflect.Type) (int, bool) {
	idx, known := walker.indices[t]
	if known {
		return idx, true
	}
	idx = len(walker.types)
	walker.indices[t] = idx
	walker.types = append(walker.types, t)
	return idx, false
}

func (walker *typeWalker) walk(t *reflect.StructField, visit VisitType) error {
	if t == nil || visit == nil {
		return nil
	}
	type stackNode struct {
		field      *reflect.StructField
		currentIdx int
		parentIdx  int
		depth      int
		known      bool
	}
	idx, known := walker.index(t.Type)
	stack := []stackNode{{t, idx, idx, 0, known}}
	var node stackNode
	for len(stack) > 0 {
		node, stack = stack[0], stack[1:]
		err := visit(node.field, node.currentIdx, node.depth)
		if err != nil {
			return err
		}
		if node.known {
			// to prevent endless loops, don't follow known types
			continue
		}
		// follow container types
		parentIdx := node.currentIdx
		depth := node.depth + 1
		switch t := node.field.Type; t.Kind() {
		case reflect.Struct:
			fields := t.NumField()
			newNodes := make([]stackNode, 0, len(stack)+fields)
			for i := 0; i < fields; i++ {
				// add each field from struct to stack
				field := t.Field(i)
				typeIdx, known := walker.index(field.Type)
				newNodes = append(newNodes, stackNode{&field, typeIdx, parentIdx, depth, known})
			}
			newNodes = append(newNodes, stack...)
		case reflect.Ptr, reflect.Array, reflect.Slice, reflect.Map, reflect.Chan:
			// add element to stack
			field := &reflect.StructField{Type: t.Elem()}
			typeIdx, known := walker.index(field.Type)
			stack = append([]stackNode{stackNode{&field, typeIdx, parentIdx, depth, known}}, stack...)
		}
	}
	return nil
}

// Walk will call visit on t and each type in t.
// It will follow struct fields, pointers, arrays, slices, maps and chans
// and call visit on each element.
// For struct fields, Walk will only follow into fields at the first occurence of their type.
// Function handling for reflect.Interface and reflect.Method has to be done by visit.
func Walk(t reflect.Type, visit VisitType) error {
	walker := &typeWalker{indices: make(map[reflect.Type]int)}
	return walker.walk(&reflect.StructField{Type: t}, visit)
}
<|endoftext|>


<commit_before>/*
Problem 2 - Even Fibonacci numbers
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2,
the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

By considering the terms in the Fibonacci sequence whose values do not exceed four million,
find the sum of the even-valued terms.
*/

package main

import "fmt"

func main() {
	sum, num1, num2 := 0, 1, 2
	for {
		if num2 >= 4000000 {
			break
		}
		if num2%2 == 0 {
			sum += num2
		}
		num1, num2 = num2, num1+num2
	}
	fmt.Println(sum)
}
<commit_msg>Use conditional for loop instead of if statement and breaking.<commit_after>/*
Problem 2 - Even Fibonacci numbers
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2,
the first 10 terms will be:

1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...

By considering the terms in the Fibonacci sequence whose values do not exceed four million,
find the sum of the even-valued terms.
*/

package main

import "fmt"

func main() {
	sum, num1, num2 := 0, 1, 2
	for num2 < 4000000 {
		if num2%2 == 0 {
			sum += num2
		}
		num1, num2 = num2, num1+num2
	}
	fmt.Println(sum)
}
<|endoftext|>