<commit_before>package concrete

import (
	"sort"

	gr "github.com/gonum/graph"
)

// A simple int alias.
type GonumNode int

func (node GonumNode) ID() int {
	return int(node)
}

// Just a collection of two nodes
type GonumEdge struct {
	H, T gr.Node
}

func (edge GonumEdge) Head() gr.Node {
	return edge.H
}

func (edge GonumEdge) Tail() gr.Node {
	return edge.T
}

// A GonumGraph is a very generalized graph that can handle an arbitrary number of vertices and edges -- as well as act as either directed or undirected.
//
// Internally, it uses a map of successors AND predecessors, to speed up some operations (such as getting all successors/predecessors). It also speeds up thing like adding edges (assuming both edges exist).
//
// However, its generality is also its weakness (and partially a flaw in needing to satisfy MutableGraph). For most purposes, creating your own graph is probably better. For instance, see discrete.TileGraph for an example
// of an immutable 2D grid of tiles that also implements the Graph interface, but would be more suitable if all you needed was a simple undirected 2D grid.
type GonumGraph struct {
	successors   map[int]map[int]float64
	predecessors map[int]map[int]float64
	nodeMap      map[int]gr.Node
	directed     bool
}

func NewGonumGraph(directed bool) *GonumGraph {
	return &GonumGraph{
		successors:   make(map[int]map[int]float64),
		predecessors: make(map[int]map[int]float64),
		nodeMap:      make(map[int]gr.Node),
		directed:     directed,
	}
}

func NewPreAllocatedGonumGraph(directed bool, numVertices int) *GonumGraph {
	return &GonumGraph{
		successors:   make(map[int]map[int]float64, numVertices),
		predecessors: make(map[int]map[int]float64, numVertices),
		nodeMap:      make(map[int]gr.Node, numVertices),
		directed:     directed,
	}
}

/* Mutable Graph implementation */

func (graph *GonumGraph) NewNode(successors []gr.Node) (node gr.Node) {
	nodeList := graph.NodeList()
	ids := make([]int, len(nodeList))
	for i, node := range nodeList {
		ids[i] = node.ID()
	}

	nodes := sort.IntSlice(ids)
	sort.Sort(&nodes)
	for i, node := range nodes {
		if i != node {
			graph.AddNode(GonumNode(i), successors)
			return GonumNode(i)
		}
	}

	newID := len(nodes)
	graph.AddNode(GonumNode(newID), successors)
	return GonumNode(newID)
}

func (graph *GonumGraph) AddNode(node gr.Node, successors []gr.Node) {
	id := node.ID()
	if _, ok := graph.successors[id]; ok {
		return
	}

	graph.nodeMap[id] = node

	graph.successors[id] = make(map[int]float64, len(successors))
	if !graph.directed {
		graph.predecessors[id] = make(map[int]float64, len(successors))
	} else {
		graph.predecessors[id] = make(map[int]float64)
	}
	for _, successor := range successors {
		succ := successor.ID()
		graph.successors[id][succ] = 1.0

		// Always add the reciprocal node to the graph
		if _, ok := graph.successors[succ]; !ok {
			graph.nodeMap[succ] = successor
			graph.predecessors[succ] = make(map[int]float64)
			graph.successors[succ] = make(map[int]float64)
		}

		graph.predecessors[succ][id] = 1.0

		// But only add the reciprocal edge if we're undirected
		if !graph.directed {
			graph.successors[succ][id] = 1.0
			graph.predecessors[id][succ] = 1.0
		}
	}
}

func (graph *GonumGraph) AddEdge(e gr.Edge) {
	id := e.Head().ID()
	successor := e.Tail().ID()
	if _, ok := graph.successors[id]; !ok {
		return
	}

	if _, ok := graph.successors[successor]; !ok {
		graph.nodeMap[successor] = e.Tail()
		graph.successors[successor] = make(map[int]float64)
		graph.predecessors[successor] = make(map[int]float64)
	}

	graph.successors[id][successor] = 1.0
	graph.predecessors[successor][id] = 1.0

	if !graph.directed {
		graph.successors[successor][id] = 1.0
		graph.predecessors[id][successor] = 1.0
	}
}

func (graph *GonumGraph) SetEdgeCost(e gr.Edge, cost float64) {
	id := e.Head().ID()
	successor := e.Tail().ID()
	// Normally I'd use graph.vertices.Contains(id) as above, but this is equivalent and a bit easier to read here
	if _, ok := graph.successors[id]; !ok {
		return
	} else if _, ok := graph.successors[id][successor]; !ok {
		return
	}
	graph.successors[id][successor] = cost
	graph.predecessors[successor][id] = cost

	// By the spec, only the empty graph will be toggled between directed and undirected. Therefore we can be sure the reciprocal edge exists
	if !graph.directed {
		graph.successors[successor][id] = cost
		graph.predecessors[id][successor] = cost
	}
}

func (graph *GonumGraph) RemoveNode(node gr.Node) {
	id := node.ID()
	if _, ok := graph.successors[id]; ok {
		return
	}
	delete(graph.nodeMap, id)

	for succ, _ := range graph.successors[id] {
		delete(graph.predecessors[succ], id)
	}
	delete(graph.successors, id)

	for pred, _ := range graph.predecessors[id] {
		delete(graph.successors[pred], id)
	}
	delete(graph.predecessors, id)

}

func (graph *GonumGraph) RemoveEdge(e gr.Edge) {
	id := e.Head().ID()
	succ := e.Tail().ID()
	if _, ok := graph.successors[id]; !ok {
		return
	} else if _, ok := graph.successors[succ]; !ok {
		return
	}

	delete(graph.successors[id], succ)
	delete(graph.predecessors[succ], id)
	if !graph.directed {
		delete(graph.predecessors[id], succ)
		delete(graph.successors[succ], id)
	}
}

func (graph *GonumGraph) EmptyGraph() {
	if len(graph.successors) == 0 {
		return
	}
	graph.successors = make(map[int]map[int]float64)
	graph.predecessors = make(map[int]map[int]float64)
	graph.nodeMap = make(map[int]gr.Node)
}

func (graph *GonumGraph) SetDirected(directed bool) {
	if len(graph.successors) > 0 {
		return
	}
	graph.directed = directed
}

/* Graph implementation */

func (graph *GonumGraph) Successors(node gr.Node) []gr.Node {
	id := node.ID()
	if _, ok := graph.successors[id]; !ok {
		return nil
	}

	successors := make([]gr.Node, len(graph.successors[id]))
	for succ, _ := range graph.successors[id] {
		successors = append(successors, graph.nodeMap[succ])
	}

	return successors
}

func (graph *GonumGraph) IsSuccessor(node, successor gr.Node) bool {
	succ := successor.ID()
	id := node.ID()
	if _, ok := graph.successors[id]; !ok {
		return false
	}

	_, ok := graph.successors[id][succ]

	return ok
}

func (graph *GonumGraph) Predecessors(node gr.Node) []gr.Node {
	id := node.ID()
	if _, ok := graph.successors[id]; !ok {
		return nil
	}

	predecessors := make([]gr.Node, len(graph.predecessors[id]))
	for pred, _ := range graph.predecessors[id] {
		predecessors = append(predecessors, graph.nodeMap[pred])
	}

	return predecessors
}

func (graph *GonumGraph) IsPredecessor(node, predecessor gr.Node) bool {
	id := node.ID()
	pred := predecessor.ID()
	if _, ok := graph.successors[id]; !ok {
		return false
	}

	_, ok := graph.predecessors[id][pred]

	return ok
}

func (graph *GonumGraph) Neighbors(node gr.Node) []gr.Node {
	id := node.ID()
	if _, ok := graph.successors[id]; !ok {
		return nil
	}

	neighbors := make([]gr.Node, 0, len(graph.predecessors[id])+len(graph.successors[id]))
	for succ, _ := range graph.successors[id] {
		neighbors = append(neighbors, graph.nodeMap[succ])
	}

	for pred, _ := range graph.predecessors[id] {
		// We should only add the predecessor if it wasn't already added from successors
		if _, ok := graph.successors[pred]; !ok {
			neighbors = append(neighbors, graph.nodeMap[pred])
		}
	}

	return neighbors
}

func (graph *GonumGraph) IsNeighbor(node, neigh gr.Node) bool {
	id := node.ID()
	neighbor := neigh.ID()
	if _, ok := graph.successors[id]; !ok {
		return false
	}

	_, succ := graph.predecessors[id][neighbor]
	_, pred := graph.predecessors[id][neighbor]

	return succ || pred
}

func (graph *GonumGraph) NodeExists(node gr.Node) bool {
	_, ok := graph.successors[node.ID()]

	return ok
}

func (graph *GonumGraph) Degree(node gr.Node) int {
	id := node.ID()
	if _, ok := graph.successors[id]; !ok {
		return 0
	}

	return len(graph.successors[id]) + len(graph.predecessors[id])
}

func (graph *GonumGraph) EdgeList() []gr.Edge {
	eList := make([]gr.Edge, 0, len(graph.successors))
	for id, succMap := range graph.successors {
		for succ, _ := range succMap {
			eList = append(eList, GonumEdge{graph.nodeMap[id], graph.nodeMap[succ]})
		}
	}

	return eList
}

func (graph *GonumGraph) NodeList() []gr.Node {
	nodes := make([]gr.Node, 0, len(graph.successors))
	for _, node := range graph.nodeMap {
		nodes = append(nodes, node)
	}

	return nodes
}

func (graph *GonumGraph) IsDirected() bool {
	return graph.directed
}

func (graph *GonumGraph) Cost(node, succ gr.Node) float64 {
	return graph.successors[node.ID()][succ.ID()]
}
<commit_msg>correct sense of test for existing node<commit_after>package concrete

import (
	"sort"

	gr "github.com/gonum/graph"
)

// A simple int alias.
type GonumNode int

func (node GonumNode) ID() int {
	return int(node)
}

// Just a collection of two nodes
type GonumEdge struct {
	H, T gr.Node
}

func (edge GonumEdge) Head() gr.Node {
	return edge.H
}

func (edge GonumEdge) Tail() gr.Node {
	return edge.T
}

// A GonumGraph is a very generalized graph that can handle an arbitrary number of vertices and edges -- as well as act as either directed or undirected.
//
// Internally, it uses a map of successors AND predecessors, to speed up some operations (such as getting all successors/predecessors). It also speeds up thing like adding edges (assuming both edges exist).
//
// However, its generality is also its weakness (and partially a flaw in needing to satisfy MutableGraph). For most purposes, creating your own graph is probably better. For instance, see discrete.TileGraph for an example
// of an immutable 2D grid of tiles that also implements the Graph interface, but would be more suitable if all you needed was a simple undirected 2D grid.
type GonumGraph struct {
	successors   map[int]map[int]float64
	predecessors map[int]map[int]float64
	nodeMap      map[int]gr.Node
	directed     bool
}

func NewGonumGraph(directed bool) *GonumGraph {
	return &GonumGraph{
		successors:   make(map[int]map[int]float64),
		predecessors: make(map[int]map[int]float64),
		nodeMap:      make(map[int]gr.Node),
		directed:     directed,
	}
}

func NewPreAllocatedGonumGraph(directed bool, numVertices int) *GonumGraph {
	return &GonumGraph{
		successors:   make(map[int]map[int]float64, numVertices),
		predecessors: make(map[int]map[int]float64, numVertices),
		nodeMap:      make(map[int]gr.Node, numVertices),
		directed:     directed,
	}
}

/* Mutable Graph implementation */

func (graph *GonumGraph) NewNode(successors []gr.Node) (node gr.Node) {
	nodeList := graph.NodeList()
	ids := make([]int, len(nodeList))
	for i, node := range nodeList {
		ids[i] = node.ID()
	}

	nodes := sort.IntSlice(ids)
	sort.Sort(&nodes)
	for i, node := range nodes {
		if i != node {
			graph.AddNode(GonumNode(i), successors)
			return GonumNode(i)
		}
	}

	newID := len(nodes)
	graph.AddNode(GonumNode(newID), successors)
	return GonumNode(newID)
}

func (graph *GonumGraph) AddNode(node gr.Node, successors []gr.Node) {
	id := node.ID()
	if _, ok := graph.successors[id]; ok {
		return
	}

	graph.nodeMap[id] = node

	graph.successors[id] = make(map[int]float64, len(successors))
	if !graph.directed {
		graph.predecessors[id] = make(map[int]float64, len(successors))
	} else {
		graph.predecessors[id] = make(map[int]float64)
	}
	for _, successor := range successors {
		succ := successor.ID()
		graph.successors[id][succ] = 1.0

		// Always add the reciprocal node to the graph
		if _, ok := graph.successors[succ]; !ok {
			graph.nodeMap[succ] = successor
			graph.predecessors[succ] = make(map[int]float64)
			graph.successors[succ] = make(map[int]float64)
		}

		graph.predecessors[succ][id] = 1.0

		// But only add the reciprocal edge if we're undirected
		if !graph.directed {
			graph.successors[succ][id] = 1.0
			graph.predecessors[id][succ] = 1.0
		}
	}
}

func (graph *GonumGraph) AddEdge(e gr.Edge) {
	id := e.Head().ID()
	successor := e.Tail().ID()
	if _, ok := graph.successors[id]; !ok {
		return
	}

	if _, ok := graph.successors[successor]; !ok {
		graph.nodeMap[successor] = e.Tail()
		graph.successors[successor] = make(map[int]float64)
		graph.predecessors[successor] = make(map[int]float64)
	}

	graph.successors[id][successor] = 1.0
	graph.predecessors[successor][id] = 1.0

	if !graph.directed {
		graph.successors[successor][id] = 1.0
		graph.predecessors[id][successor] = 1.0
	}
}

func (graph *GonumGraph) SetEdgeCost(e gr.Edge, cost float64) {
	id := e.Head().ID()
	successor := e.Tail().ID()
	// Normally I'd use graph.vertices.Contains(id) as above, but this is equivalent and a bit easier to read here
	if _, ok := graph.successors[id]; !ok {
		return
	} else if _, ok := graph.successors[id][successor]; !ok {
		return
	}
	graph.successors[id][successor] = cost
	graph.predecessors[successor][id] = cost

	// By the spec, only the empty graph will be toggled between directed and undirected. Therefore we can be sure the reciprocal edge exists
	if !graph.directed {
		graph.successors[successor][id] = cost
		graph.predecessors[id][successor] = cost
	}
}

func (graph *GonumGraph) RemoveNode(node gr.Node) {
	id := node.ID()
	if _, ok := graph.successors[id]; !ok {
		return
	}
	delete(graph.nodeMap, id)

	for succ, _ := range graph.successors[id] {
		delete(graph.predecessors[succ], id)
	}
	delete(graph.successors, id)

	for pred, _ := range graph.predecessors[id] {
		delete(graph.successors[pred], id)
	}
	delete(graph.predecessors, id)

}

func (graph *GonumGraph) RemoveEdge(e gr.Edge) {
	id := e.Head().ID()
	succ := e.Tail().ID()
	if _, ok := graph.successors[id]; !ok {
		return
	} else if _, ok := graph.successors[succ]; !ok {
		return
	}

	delete(graph.successors[id], succ)
	delete(graph.predecessors[succ], id)
	if !graph.directed {
		delete(graph.predecessors[id], succ)
		delete(graph.successors[succ], id)
	}
}

func (graph *GonumGraph) EmptyGraph() {
	if len(graph.successors) == 0 {
		return
	}
	graph.successors = make(map[int]map[int]float64)
	graph.predecessors = make(map[int]map[int]float64)
	graph.nodeMap = make(map[int]gr.Node)
}

func (graph *GonumGraph) SetDirected(directed bool) {
	if len(graph.successors) > 0 {
		return
	}
	graph.directed = directed
}

/* Graph implementation */

func (graph *GonumGraph) Successors(node gr.Node) []gr.Node {
	id := node.ID()
	if _, ok := graph.successors[id]; !ok {
		return nil
	}

	successors := make([]gr.Node, len(graph.successors[id]))
	for succ, _ := range graph.successors[id] {
		successors = append(successors, graph.nodeMap[succ])
	}

	return successors
}

func (graph *GonumGraph) IsSuccessor(node, successor gr.Node) bool {
	succ := successor.ID()
	id := node.ID()
	if _, ok := graph.successors[id]; !ok {
		return false
	}

	_, ok := graph.successors[id][succ]

	return ok
}

func (graph *GonumGraph) Predecessors(node gr.Node) []gr.Node {
	id := node.ID()
	if _, ok := graph.successors[id]; !ok {
		return nil
	}

	predecessors := make([]gr.Node, len(graph.predecessors[id]))
	for pred, _ := range graph.predecessors[id] {
		predecessors = append(predecessors, graph.nodeMap[pred])
	}

	return predecessors
}

func (graph *GonumGraph) IsPredecessor(node, predecessor gr.Node) bool {
	id := node.ID()
	pred := predecessor.ID()
	if _, ok := graph.successors[id]; !ok {
		return false
	}

	_, ok := graph.predecessors[id][pred]

	return ok
}

func (graph *GonumGraph) Neighbors(node gr.Node) []gr.Node {
	id := node.ID()
	if _, ok := graph.successors[id]; !ok {
		return nil
	}

	neighbors := make([]gr.Node, 0, len(graph.predecessors[id])+len(graph.successors[id]))
	for succ, _ := range graph.successors[id] {
		neighbors = append(neighbors, graph.nodeMap[succ])
	}

	for pred, _ := range graph.predecessors[id] {
		// We should only add the predecessor if it wasn't already added from successors
		if _, ok := graph.successors[pred]; !ok {
			neighbors = append(neighbors, graph.nodeMap[pred])
		}
	}

	return neighbors
}

func (graph *GonumGraph) IsNeighbor(node, neigh gr.Node) bool {
	id := node.ID()
	neighbor := neigh.ID()
	if _, ok := graph.successors[id]; !ok {
		return false
	}

	_, succ := graph.predecessors[id][neighbor]
	_, pred := graph.predecessors[id][neighbor]

	return succ || pred
}

func (graph *GonumGraph) NodeExists(node gr.Node) bool {
	_, ok := graph.successors[node.ID()]

	return ok
}

func (graph *GonumGraph) Degree(node gr.Node) int {
	id := node.ID()
	if _, ok := graph.successors[id]; !ok {
		return 0
	}

	return len(graph.successors[id]) + len(graph.predecessors[id])
}

func (graph *GonumGraph) EdgeList() []gr.Edge {
	eList := make([]gr.Edge, 0, len(graph.successors))
	for id, succMap := range graph.successors {
		for succ, _ := range succMap {
			eList = append(eList, GonumEdge{graph.nodeMap[id], graph.nodeMap[succ]})
		}
	}

	return eList
}

func (graph *GonumGraph) NodeList() []gr.Node {
	nodes := make([]gr.Node, 0, len(graph.successors))
	for _, node := range graph.nodeMap {
		nodes = append(nodes, node)
	}

	return nodes
}

func (graph *GonumGraph) IsDirected() bool {
	return graph.directed
}

func (graph *GonumGraph) Cost(node, succ gr.Node) float64 {
	return graph.successors[node.ID()][succ.ID()]
}
<|endoftext|>


<commit_before>package main

import (
  "fmt"
  "time"
  "math/rand"
)

func ReallyLongAndExpensiveOperation(channel chan int){
  for {
    rand.Seed(time.Now().UTC().UnixNano())
    i := rand.Intn(1000)
    time.Sleep( time.Duration(i) * time.Millisecond)
    channel <- i
  }
}

func main() {
  channel := make(chan int)
  go ReallyLongAndExpensiveOperation(channel)
  for {
    fmt.Println("I waited", <-channel, "milliseconds")
  }
}<commit_msg>Mejor ejemplo de concurrencia<commit_after>package main

import (
    "fmt"
    "time"
)

func pinger(c chan string) {
    for i := 0; ; i++ {
        c <- "ping"
    }
}

func ponger(c chan string) {
    for i := 0; ; i++ {
        c <- "pong"
    }
}

func printer(c chan string) {
    for {
        msg := <- c
        fmt.Println(msg)
        time.Sleep(time.Second * 1)
    }
}

func main() {
    var c chan string = make(chan string)

    go pinger(c)
    go ponger(c)
    go printer(c)

    var input string
    fmt.Scanln(&input)
}<|endoftext|>


<commit_before>package main

import "fmt"

func main() {
	// []T is a slice with elements of type T.
	// Like array's slice is also a numbered sequence of elements of
	// single type, but unlike array whoes size is fixed and cannot be
	// altered, silce can grow and shrink. A slice is a descriptor of an array segment.
	// It consists of a pointer to the array, the length of the segment, and
	// its capacity (the maximum length of the segment).

	// see Go Slices: usage and internals [http://blog.golang.org/go-slices-usage-and-internals]
	// some note worthy properties of slices are:
	// slice is a referrence type
	// slice can grow beyond the size defined at the time of declaration
	// slice can sub divided, each of these sub slices refer to the same underlying array
	// zero value of slice is nil
	// a nil slice has length and capacity of zero (0)

	// built in function make is used to intialize a slice, which creates the
	// underlying array and return the a pointer to this array.
	// make([]T,len,cap) if cap is omitted the it would be equal to length.
	s := make([]int32, 3)
	s[0] = 12
	s[1] = 1234

	// Trying to access or set an index that does not exists, results in run-time crash
	// and the program terminates. To get around this limitation use the built in
	// function "append"
	// uncomment the following line to see the error in action
	// s[3] = 98

	// slice elemnts are zeroed .i.e. the elements that are not assigned a value,
	// will intialized to their respective types zero value. For example in
	// case of numbers array the value of third (3) element would set to zero (0)
	fmt.Printf("%#v\n", s)

	// slice literal syntax
	weekDays := []string{"Mon", "Tue", "Wed", "Thus", "Fri", "Sat", "Sun"}
	fmt.Printf("Days in week %#v\n", weekDays)

	// add elements to slice
	s = append(s, 9868)
	fmt.Printf("%#v\n", s)

	// The length is the number of elements referred to by the slice.
	// The capacity is the number of elements in the underlying array
	// (beginning at the element referred to by the slice pointer)
	// The length and capacity of a slice can be inspected using the built-in len and cap functions.
	a := []int32{1, 2}
	fmt.Printf("len=%d cap=%d %v\n", len(a), cap(a), a)

	// see how length and capacity changes as we append to the slice
	// adding thrid element would double to slices initial capacity.
	// If the backing array of a is too small to fit all the given values
	// a bigger array will be allocated. The returned slice will point
	// to the newly allocated array.
	a = append(a, 23)
	fmt.Printf("len=%d cap=%d %v\n", len(a), cap(a), a)

	a = append(a, 41)
	fmt.Printf("len=%d cap=%d %v\n", len(a), cap(a), a)

	a = append(a, 234)
	fmt.Printf("len=%d cap=%d %v\n", len(a), cap(a), a)

	a = append(a, 400)
	fmt.Printf("len=%d cap=%d %v\n", len(a), cap(a), a)

	// Slices can be re-sliced, creating a new slice value that points to the same array.
	// The expression s[lo:hi], evaluates to a slice of the elements from lo through hi-1, inclusive.
	// create a new slice pointing to same array, but has no elements
	b := a[0:0]
	fmt.Printf("b = %v\n", b)

	// has exactly one element, specifically it has element at the first index
	b = a[0:1]
	fmt.Printf("b = %v\n", b)

	// contains elements 0 - through 2
	b = a[:len(a)-3]
	fmt.Printf("b = %v\n", b)

	// contains elements 2 - 5
	b = a[2:]
	fmt.Printf("b = %v\n", b)

	// contains all elements
	b = a[:]
	fmt.Printf("b = %v\n", b)

	// slice can be copied to create new slice
	// func copy(dst, src []T) int
	// The copy function supports copying between slices of different
	// lengths (it will copy only up to the smaller number of elements).
	// In addition, copy can handle source and destination slices that share
	// the same underlying array, handling overlapping slices correctly.
	newSlice := []int32{111, 222, 333}
	fmt.Printf("before copy newSlice = %v\n", newSlice)
	copy(newSlice, a)
	fmt.Printf("newSlice = %v\n", newSlice)

	// use the subscript notation to access an slice element.
	// NOTE: trying to access a existing index will cause run-time crash
	fmt.Printf("First day of the week is %s\n", weekDays[0])

	// you can also iterate over the array using for..range loop
	for indx, val := range a {
		fmt.Printf("Range: element at index %d is %d\n", indx, val)
	}

	// or using for loop
	for i := 0; i < len(a); i++ {
		fmt.Printf("For: element at index %d is %d\n", i, a[i])
	}
}
<commit_msg>fix typo<commit_after>package main

import "fmt"

func main() {
	// []T is a slice with elements of type T.
	// Like array's slice is also a numbered sequence of elements of
	// single type, but unlike array whoes size is fixed and cannot be
	// altered, silce can grow and shrink. A slice is a descriptor of an array segment.
	// It consists of a pointer to the array, the length of the segment, and
	// its capacity (the maximum length of the segment).

	// see Go Slices: usage and internals [http://blog.golang.org/go-slices-usage-and-internals]
	// some note worthy properties of slices are:
	// slice is a referrence type
	// slice can grow beyond the size defined at the time of declaration
	// slice can sub divided, each of these sub slices refer to the same underlying array
	// zero value of slice is nil
	// a nil slice has length and capacity of zero (0)

	// built in function make is used to intialize a slice, which creates the
	// underlying array and return the a pointer to this array.
	// make([]T,len,cap) if cap is omitted the it would be equal to length.
	s := make([]int32, 3)
	s[0] = 12
	s[1] = 1234

	// Trying to access or set an index that does not exists, results in run-time crash
	// and the program terminates. To get around this limitation use the built in
	// function "append"
	// uncomment the following line to see the error in action
	// s[3] = 98

	// slice elemnts are zeroed .i.e. the elements that are not assigned a value,
	// will intialized to their respective types zero value. For example in
	// case of numbers array the value of third (3) element would set to zero (0)
	fmt.Printf("%#v\n", s)

	// slice literal syntax
	weekDays := []string{"Mon", "Tue", "Wed", "Thus", "Fri", "Sat", "Sun"}
	fmt.Printf("Days in week %#v\n", weekDays)

	// add elements to slice
	s = append(s, 9868)
	fmt.Printf("%#v\n", s)

	// The length is the number of elements referred to by the slice.
	// The capacity is the number of elements in the underlying array
	// (beginning at the element referred to by the slice pointer)
	// The length and capacity of a slice can be inspected using the built-in len and cap functions.
	a := []int32{1, 2}
	fmt.Printf("len=%d cap=%d %v\n", len(a), cap(a), a)

	// see how length and capacity changes as we append to the slice
	// adding thrid element would double to slices initial capacity.
	// If the backing array of a is too small to fit all the given values
	// a bigger array will be allocated. The returned slice will point
	// to the newly allocated array.
	a = append(a, 23)
	fmt.Printf("len=%d cap=%d %v\n", len(a), cap(a), a)

	a = append(a, 41)
	fmt.Printf("len=%d cap=%d %v\n", len(a), cap(a), a)

	a = append(a, 234)
	fmt.Printf("len=%d cap=%d %v\n", len(a), cap(a), a)

	a = append(a, 400)
	fmt.Printf("len=%d cap=%d %v\n", len(a), cap(a), a)

	// Slices can be re-sliced, creating a new slice value that points to the same array.
	// The expression s[lo:hi], evaluates to a slice of the elements from lo through hi-1, inclusive.
	// create a new slice pointing to same array, but has no elements
	b := a[0:0]
	fmt.Printf("b = %v\n", b)

	// has exactly one element, specifically it has element at the first index
	b = a[0:1]
	fmt.Printf("b = %v\n", b)

	// contains elements 0 - through 2
	b = a[:len(a)-3]
	fmt.Printf("b = %v\n", b)

	// contains elements 2 - 5
	b = a[2:]
	fmt.Printf("b = %v\n", b)

	// contains all elements
	b = a[:]
	fmt.Printf("b = %v\n", b)

	// slice can be copied to create new slice
	// func copy(dst, src []T) int
	// The copy function supports copying between slices of different
	// lengths (it will copy only up to the smaller number of elements).
	// In addition, copy can handle source and destination slices that share
	// the same underlying array, handling overlapping slices correctly.
	newSlice := []int32{111, 222, 333}
	fmt.Printf("before copy newSlice = %v\n", newSlice)
	copy(newSlice, a)
	fmt.Printf("newSlice = %v\n", newSlice)

	// use the subscript notation to access an slice element.
	// NOTE: trying to access a non-existing index will cause run-time crash
	fmt.Printf("First day of the week is %s\n", weekDays[0])

	// you can also iterate over the array using for..range loop
	for indx, val := range a {
		fmt.Printf("Range: element at index %d is %d\n", indx, val)
	}

	// or using for loop
	for i := 0; i < len(a); i++ {
		fmt.Printf("For: element at index %d is %d\n", i, a[i])
	}
}
<|endoftext|>


<commit_before>package parser

import (
	"encoding/json"
	"errors"
	"fmt"
	"strconv"
	"strings"
	"unicode"
)

func ParseArguments(args []string) (res map[string]interface{}, err error) {
	res = make(map[string]interface{}, 0)
	if len(args) == 0 {
		return res, nil
	}

	var key string
	isSettingKey := false
	for i := 0; i < len(args); i++ {
		if args[i] == "--" {
			return nil, fmt.Errorf("-- is an invalid argument.")
		}
		if strings.HasPrefix(args[i], "--") {
			key = normalizePropertyName(args[i])
			if _, ok := res[key]; ok {
				return nil, fmt.Errorf("Option '%s' is specified twice.", key)
			}
			if i+1 == len(args) || strings.HasPrefix(args[i+1], "--") {
				res[key] = nil
			} else {
				isSettingKey = true
			}
			continue
		}
		if isSettingKey {
			if _, ok := res[key]; !ok {
				res[key] = args[i]
			} else if _, ok := res[key].(string); ok {
				array := make([]interface{}, 0)
				array = append(array, res[key], args[i])
				res[key] = array
			} else {
				res[key] = append(res[key].([]interface{}), args[i])
			}
			continue
		} else {
			jsonArg := map[string]interface{}{}
			err = json.Unmarshal([]byte(args[i]), &jsonArg)
			if err != nil {
				return nil, fmt.Errorf("Invalid JSON: %s.", args[i])
			}
			normalizeKeys(jsonArg)
			for k, v := range jsonArg {
				if _, ok := res[k]; ok {
					return nil, fmt.Errorf("Option '%s' is specified twice.", k)
				}
				res[k] = v
			}
			continue
		}
	}
	return res, nil
}

func normalizeKeys(arg interface{}) {
	if argObj, isObj := arg.(map[string]interface{}); isObj {
		for k, v := range argObj {
			n := normalizePropertyName(k)
			delete(argObj, k)
			(argObj)[n] = v
			normalizeKeys(v)
		}
	} else if argArray, isArray := arg.([]interface{}); isArray {
		for _, v := range argArray {
			normalizeKeys(v)
		}
	}
}

func normalizePropertyName(prName string) string {
	prName = strings.TrimLeft(prName, "--")
	array := strings.Split(prName, "-")
	res := make([]rune, 0)
	for _, item := range array {
		chars := []rune(item)
		chars[0] = unicode.ToUpper(chars[0])
		res = append(res, chars...)
	}
	return string(res)
}

func normalizeValue(value string) interface{} {
	var obj interface{} = value
	if val, err := strconv.ParseFloat(value, 64); err == nil {
		obj = val
	} else if val, err := strconv.ParseBool(value); err == nil {
		obj = val
	}
	return obj
}

type state func(r rune) error

var curState state
var curQuote rune
var curItem []rune
var items []string

func parseObject(obj string) interface{} {
	curState = startParseKey
	curQuote = '\000'
	curItem = []rune{}
	items = []string{}
	for _, c := range obj {
		err := curState(c)
		if err != nil {
			return normalizeValue(obj)
		}
	}
	curState('\000')
	if len(items) <= 1 {
		return normalizeValue(obj)
	}
	res := make(map[string]interface{}, 0)
	for i := 0; i < len(items); i += 2 {
		key := normalizePropertyName(items[i])
		if i == len(items)-1 {
			res[key] = nil
		} else {
			res[key] = normalizeValue(items[i+1])
		}
	}
	return res
}

func saveCurItem() {
	items = append(items, string(curItem))
	curItem = []rune{}
}

func startParseKey(r rune) error {
	switch r {
	case '\'', '"':
		curQuote = r
		curState = parseQuotedKey
	default:
		curItem = append(curItem, r)
		curState = parseSimpleKey
	}
	return nil
}

func parseSimpleKey(r rune) error {
	switch r {
	case '=':
		curState = startParseValue
		saveCurItem()
	case '\000':
		saveCurItem()
	default:
		curItem = append(curItem, r)
	}
	return nil
}

func parseQuotedKey(r rune) error {
	switch r {
	case curQuote:
		curState = keyParsed
		saveCurItem()
	case '\000':
		return errors.New("")
	default:
		curItem = append(curItem, r)
	}
	return nil
}

func keyParsed(r rune) error {
	switch r {
	case '=':
		curState = startParseValue
		return nil
	case '\000':
		return nil
	default:
		return errors.New("")

	}
}

func startParseValue(r rune) error {
	switch r {
	case '\'', '"':
		curQuote = r
		curState = parseQuotedValue
	default:
		curItem = append(curItem, r)
		curState = parseSimpleValue
	}
	return nil
}

func parseSimpleValue(r rune) error {
	switch r {
	case ',':
		curState = startParseKey
		saveCurItem()
	case '\000':
		saveCurItem()
	default:
		curItem = append(curItem, r)
	}
	return nil
}

func parseQuotedValue(r rune) error {
	switch r {
	case curQuote:
		curState = valueParsed
		saveCurItem()
	case '\000':
		return errors.New("")
	default:
		curItem = append(curItem, r)
	}
	return nil
}

func valueParsed(r rune) error {
	switch r {
	case ',':
		curState = startParseKey
		return nil
	case '\000':
		return nil
	default:
		return errors.New("")

	}
}
<commit_msg>export the key normalization function because we need it in model loader<commit_after>package parser

import (
	"encoding/json"
	"errors"
	"fmt"
	"strconv"
	"strings"
	"unicode"
)

func ParseArguments(args []string) (res map[string]interface{}, err error) {
	res = make(map[string]interface{}, 0)
	if len(args) == 0 {
		return res, nil
	}

	var key string
	isSettingKey := false
	for i := 0; i < len(args); i++ {
		if args[i] == "--" {
			return nil, fmt.Errorf("-- is an invalid argument.")
		}
		if strings.HasPrefix(args[i], "--") {
			key = normalizePropertyName(args[i])
			if _, ok := res[key]; ok {
				return nil, fmt.Errorf("Option '%s' is specified twice.", key)
			}
			if i+1 == len(args) || strings.HasPrefix(args[i+1], "--") {
				res[key] = nil
			} else {
				isSettingKey = true
			}
			continue
		}
		if isSettingKey {
			if _, ok := res[key]; !ok {
				res[key] = args[i]
			} else if _, ok := res[key].(string); ok {
				array := make([]interface{}, 0)
				array = append(array, res[key], args[i])
				res[key] = array
			} else {
				res[key] = append(res[key].([]interface{}), args[i])
			}
			continue
		} else {
			jsonArg := map[string]interface{}{}
			err = json.Unmarshal([]byte(args[i]), &jsonArg)
			if err != nil {
				return nil, fmt.Errorf("Invalid JSON: %s.", args[i])
			}
			NormalizeKeys(jsonArg)
			for k, v := range jsonArg {
				if _, ok := res[k]; ok {
					return nil, fmt.Errorf("Option '%s' is specified twice.", k)
				}
				res[k] = v
			}
			continue
		}
	}
	return res, nil
}

func NormalizeKeys(arg interface{}) {
	if argObj, isObj := arg.(map[string]interface{}); isObj {
		for k, v := range argObj {
			n := normalizePropertyName(k)
			delete(argObj, k)
			(argObj)[n] = v
			NormalizeKeys(v)
		}
	} else if argArray, isArray := arg.([]interface{}); isArray {
		for _, v := range argArray {
			NormalizeKeys(v)
		}
	}
}

func normalizePropertyName(prName string) string {
	prName = strings.TrimLeft(prName, "--")
	array := strings.Split(prName, "-")
	res := make([]rune, 0)
	for _, item := range array {
		chars := []rune(item)
		chars[0] = unicode.ToUpper(chars[0])
		res = append(res, chars...)
	}
	return string(res)
}

func normalizeValue(value string) interface{} {
	var obj interface{} = value
	if val, err := strconv.ParseFloat(value, 64); err == nil {
		obj = val
	} else if val, err := strconv.ParseBool(value); err == nil {
		obj = val
	}
	return obj
}

type state func(r rune) error

var curState state
var curQuote rune
var curItem []rune
var items []string

func parseObject(obj string) interface{} {
	curState = startParseKey
	curQuote = '\000'
	curItem = []rune{}
	items = []string{}
	for _, c := range obj {
		err := curState(c)
		if err != nil {
			return normalizeValue(obj)
		}
	}
	curState('\000')
	if len(items) <= 1 {
		return normalizeValue(obj)
	}
	res := make(map[string]interface{}, 0)
	for i := 0; i < len(items); i += 2 {
		key := normalizePropertyName(items[i])
		if i == len(items)-1 {
			res[key] = nil
		} else {
			res[key] = normalizeValue(items[i+1])
		}
	}
	return res
}

func saveCurItem() {
	items = append(items, string(curItem))
	curItem = []rune{}
}

func startParseKey(r rune) error {
	switch r {
	case '\'', '"':
		curQuote = r
		curState = parseQuotedKey
	default:
		curItem = append(curItem, r)
		curState = parseSimpleKey
	}
	return nil
}

func parseSimpleKey(r rune) error {
	switch r {
	case '=':
		curState = startParseValue
		saveCurItem()
	case '\000':
		saveCurItem()
	default:
		curItem = append(curItem, r)
	}
	return nil
}

func parseQuotedKey(r rune) error {
	switch r {
	case curQuote:
		curState = keyParsed
		saveCurItem()
	case '\000':
		return errors.New("")
	default:
		curItem = append(curItem, r)
	}
	return nil
}

func keyParsed(r rune) error {
	switch r {
	case '=':
		curState = startParseValue
		return nil
	case '\000':
		return nil
	default:
		return errors.New("")

	}
}

func startParseValue(r rune) error {
	switch r {
	case '\'', '"':
		curQuote = r
		curState = parseQuotedValue
	default:
		curItem = append(curItem, r)
		curState = parseSimpleValue
	}
	return nil
}

func parseSimpleValue(r rune) error {
	switch r {
	case ',':
		curState = startParseKey
		saveCurItem()
	case '\000':
		saveCurItem()
	default:
		curItem = append(curItem, r)
	}
	return nil
}

func parseQuotedValue(r rune) error {
	switch r {
	case curQuote:
		curState = valueParsed
		saveCurItem()
	case '\000':
		return errors.New("")
	default:
		curItem = append(curItem, r)
	}
	return nil
}

func valueParsed(r rune) error {
	switch r {
	case ',':
		curState = startParseKey
		return nil
	case '\000':
		return nil
	default:
		return errors.New("")

	}
}
<|endoftext|>


<commit_before>package clover

import (
	"crypto/sha512"
	"encoding/hex"
	"errors"
	"github.com/plimble/unik/mock_unik"
	"github.com/stretchr/testify/assert"
	"testing"
)

type mockResponseType struct {
	store *Mockallstore
}

func setUpCodeResponseType() (*codeRespType, *mockResponseType) {
	mu := mock_unik.NewMockGenerator()
	mu.On("Generate").Return("1")

	store := NewMockallstore()
	config := NewAuthConfig(store)
	config.AddAuthCodeGrant(store)
	mock := &mockResponseType{store}

	rt := newCodeRespType(config, mu)
	return rt, mock
}

func generateAuthRequest(resType string) *authorizeRequest {
	ar := &authorizeRequest{
		state:        "0",
		redirectURI:  "http://localhost",
		responseType: resType,
		scope:        "email",
		clientID:     "1001",
		client: &DefaultClient{
			ClientID:     "1",
			RedirectURI:  "http://localhost",
			ClientSecret: "xyz",
			GrantType:    []string{AUTHORIZATION_CODE},
			UserID:       "1",
			Scope:        []string{"email"},
		},
	}

	return ar
}

func genTestAuthCode(rt *codeRespType, ar *authorizeRequest) *AuthorizeCode {
	return &AuthorizeCode{
		Code:        hashCode("1"),
		ClientID:    ar.client.GetClientID(),
		UserID:      ar.client.GetUserID(),
		Expires:     addSecondUnix(rt.config.AuthCodeLifetime),
		Scope:       []string{"email"},
		RedirectURI: ar.redirectURI,
	}
}

func hashCode(code string) string {
	hasher := sha512.New()
	hasher.Write([]byte(code))
	return hex.EncodeToString(hasher.Sum(nil))
}

func TestGetAuthResponse(t *testing.T) {
	rt, mock := setUpCodeResponseType()
	ar := generateAuthRequest("code")
	ac := genTestAuthCode(rt, ar)

	mock.store.On("SetAuthorizeCode", ac).Return(nil)
	resp := rt.GetAuthResponse(ar, ar.client, ar.client.GetScope())

	assert.Equal(t, 302, resp.code)
	assert.False(t, resp.IsError())
}

func TestGetAuthResponseError(t *testing.T) {
	rt, mock := setUpCodeResponseType()
	ar := generateAuthRequest("code")
	ac := genTestAuthCode(rt, ar)

	mock.store.On("SetAuthorizeCode", ac).Return(errors.New("test"))
	resp := rt.GetAuthResponse(ar, ar.client, ar.client.GetScope())

	assert.Equal(t, 500, resp.code)
	assert.True(t, resp.IsError())
}

func TestCreateAuthCode(t *testing.T) {
	rt, mock := setUpCodeResponseType()
	ar := generateAuthRequest("code")
	ac := genTestAuthCode(rt, ar)

	mock.store.On("SetAuthorizeCode", ac).Return(nil)
	code, resp := rt.createAuthCode(ar.client, ar.client.GetScope(), ar.client.GetRedirectURI())

	assert.Nil(t, resp)
	assert.Equal(t, ac.Code, code.Code)
}

func TestCreateAuthCodeError(t *testing.T) {
	rt, mock := setUpCodeResponseType()
	ar := generateAuthRequest("code")
	ac := genTestAuthCode(rt, ar)

	mock.store.On("SetAuthorizeCode", ac).Return(errors.New("test"))
	code, resp := rt.createAuthCode(ar.client, ar.client.GetScope(), ar.client.GetRedirectURI())

	assert.Nil(t, code)
	assert.True(t, resp.IsError())
}

func TestGenerateAuthCode(t *testing.T) {
	rt, _ := setUpCodeResponseType()
	code := rt.generateAuthCode()
	assert.NotEmpty(t, code)
}
<commit_msg>fix code test resptype<commit_after>package clover

import (
	"crypto/sha512"
	"encoding/hex"
	"errors"
	"github.com/plimble/unik/mock_unik"
	"github.com/stretchr/testify/assert"
	"testing"
)

type mockResponseType struct {
	store *Mockallstore
}

func setUpCodeResponseType() (*codeRespType, *mockResponseType) {
	store := NewMockallstore()
	mock := &mockResponseType{store}

	config := NewAuthConfig(store)
	config.AddAuthCodeGrant(store)

	mu := mock_unik.NewMockGenerator()
	mu.On("Generate").Return("1")
	rt := newCodeRespType(config, mu)
	return rt, mock
}

func generateAuthRequest(resType string) *authorizeRequest {
	ar := &authorizeRequest{
		state:        "0",
		redirectURI:  "http://localhost",
		responseType: resType,
		scope:        "email",
		clientID:     "1001",
		client: &DefaultClient{
			ClientID:     "1",
			RedirectURI:  "http://localhost",
			ClientSecret: "xyz",
			GrantType:    []string{AUTHORIZATION_CODE},
			UserID:       "1",
			Scope:        []string{"email"},
		},
	}

	return ar
}

func genTestAuthCode(rt *codeRespType, ar *authorizeRequest) *AuthorizeCode {
	return &AuthorizeCode{
		Code:        hashCode("1"),
		ClientID:    ar.client.GetClientID(),
		UserID:      ar.client.GetUserID(),
		Expires:     addSecondUnix(rt.config.AuthCodeLifetime),
		Scope:       []string{"email"},
		RedirectURI: ar.redirectURI,
	}
}

func hashCode(code string) string {
	hasher := sha512.New()
	hasher.Write([]byte(code))
	return hex.EncodeToString(hasher.Sum(nil))
}

func TestGetAuthResponse(t *testing.T) {
	rt, mock := setUpCodeResponseType()
	ar := generateAuthRequest("code")
	ac := genTestAuthCode(rt, ar)

	mock.store.On("SetAuthorizeCode", ac).Return(nil)
	resp := rt.GetAuthResponse(ar, ar.client, ar.client.GetScope())

	assert.Equal(t, 302, resp.code)
	assert.False(t, resp.IsError())
}

func TestGetAuthResponseError(t *testing.T) {
	rt, mock := setUpCodeResponseType()
	ar := generateAuthRequest("code")
	ac := genTestAuthCode(rt, ar)

	mock.store.On("SetAuthorizeCode", ac).Return(errors.New("test"))
	resp := rt.GetAuthResponse(ar, ar.client, ar.client.GetScope())

	assert.Equal(t, 500, resp.code)
	assert.True(t, resp.IsError())
}

func TestCreateAuthCode(t *testing.T) {
	rt, mock := setUpCodeResponseType()
	ar := generateAuthRequest("code")
	ac := genTestAuthCode(rt, ar)

	mock.store.On("SetAuthorizeCode", ac).Return(nil)
	code, resp := rt.createAuthCode(ar.client, ar.client.GetScope(), ar.client.GetRedirectURI())

	assert.Nil(t, resp)
	assert.Equal(t, ac.Code, code.Code)
}

func TestCreateAuthCodeError(t *testing.T) {
	rt, mock := setUpCodeResponseType()
	ar := generateAuthRequest("code")
	ac := genTestAuthCode(rt, ar)

	mock.store.On("SetAuthorizeCode", ac).Return(errors.New("test"))
	code, resp := rt.createAuthCode(ar.client, ar.client.GetScope(), ar.client.GetRedirectURI())

	assert.Nil(t, code)
	assert.True(t, resp.IsError())
}

func TestGenerateAuthCode(t *testing.T) {
	rt, _ := setUpCodeResponseType()
	code := rt.generateAuthCode()
	assert.NotEmpty(t, code)
}
<|endoftext|>


<commit_before>package goent_test

import (
	"math"
	"testing"

	"github.com/kzahedi/goent"
)

func TestMIasEntropies(t *testing.T) {
	t.Log("Testing Mutual Information as Entropy minus Conditional Entropy")
	p1 := [][]float64{
		{1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0},
		{1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0},
		{1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0},
		{1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0}}

	px := []float64{1.0 / 4.0, 1.0 / 4.0, 1.0 / 4.0, 1.0 / 4.0}

	mi1 := goent.MutualInformation2(p1)
	ch1 := goent.ConditionalEntropy2(p1)
	h1 := goent.Entropy2(px)
	diff1 := mi1 - (h1 - ch1)

	if math.Abs(diff1) > 0.0001 {
		t.Errorf(" I(X;Y) = H(X) - H(X|Y) but the difference is %f, MI: %f, cH: %f, H:%f", math.Abs(diff1), mi1, ch1, h1)
	}

	p2 := [][]float64{
		{1.0 / 4.0, 0.0, 0.0, 0.0},
		{0.0, 1.0 / 4.0, 0.0, 0.0},
		{0.0, 0.0, 1.0 / 4.0, 0.0},
		{0.0, 0.0, 0.0, 1.0 / 4.0}}

	mi2 := goent.MutualInformation2(p2)  // I(X;Y) = H(X) - H(X|Y)
	ch2 := goent.ConditionalEntropy2(p2) // H(X|Y)
	h2 := goent.Entropy2(px)             // H(X)
	diff2 := mi2 - (h2 - ch2)

	if math.Abs(diff2) > 0.0001 {
		t.Errorf(" I(X;Y) = H(X) - H(X|Y) but the difference is %f, MI: %f, cH: %f, H:%f", math.Abs(diff2), mi2, ch2, h2)
	}

}
<commit_msg>New test case<commit_after>package goent_test

import (
	"math"
	"math/rand"
	"testing"
	"time"

	"github.com/kzahedi/goent"
)

func TestMIasEntropies(t *testing.T) {
	t.Log("Testing Mutual Information as Entropy minus Conditional Entropy")
	rand.Seed(time.Now().UnixNano())
	p1 := [][]float64{
		{1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0},
		{1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0},
		{1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0},
		{1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0, 1.0 / 16.0}}

	px := []float64{1.0 / 4.0, 1.0 / 4.0, 1.0 / 4.0, 1.0 / 4.0}

	mi1 := goent.MutualInformation2(p1)
	ch1 := goent.ConditionalEntropy2(p1)
	h1 := goent.Entropy2(px)
	diff1 := mi1 - (h1 - ch1)

	if math.Abs(diff1) > 0.0001 {
		t.Errorf(" I(X;Y) = H(X) - H(X|Y) but the difference is %f, MI: %f, cH: %f, H:%f", math.Abs(diff1), mi1, ch1, h1)
	}

	p2 := [][]float64{
		{1.0 / 4.0, 0.0, 0.0, 0.0},
		{0.0, 1.0 / 4.0, 0.0, 0.0},
		{0.0, 0.0, 1.0 / 4.0, 0.0},
		{0.0, 0.0, 0.0, 1.0 / 4.0}}

	mi2 := goent.MutualInformation2(p2)  // I(X;Y) = H(X) - H(X|Y)
	ch2 := goent.ConditionalEntropy2(p2) // H(X|Y)
	h2 := goent.Entropy2(px)             // H(X)
	diff2 := mi2 - (h2 - ch2)

	if math.Abs(diff2) > 0.0001 {
		t.Errorf(" I(X;Y) = H(X) - H(X|Y) but the difference is %f, MI: %f, cH: %f, H:%f", math.Abs(diff2), mi2, ch2, h2)
	}
}

func TestCMIasMI(t *testing.T) {
	t.Log("Testing Conditional Mutual Information as Mutual Informations")
	pxyz := make([][][]float64, 5, 5)

	sum := 0.0
	for x := 0; x < 5; x++ {
		pxyz[x] = make([][]float64, 5, 5)
		for y := 0; y < 5; y++ {
			pxyz[x][y] = make([]float64, 5, 5)
		}
	}
	for x := 0; x < 5; x++ {
		for y := 0; y < 5; y++ {
			for z := 0; z < 5; z++ {
				v := rand.Float64()
				pxyz[x][y][z] += v
				sum += v
			}
		}
	}
	for x := 0; x < 5; x++ {
		for y := 0; y < 5; y++ {
			for z := 0; z < 5; z++ {
				pxyz[x][y][z] /= sum
			}
		}
	}

	pxz := make([][]float64, 5, 5)
	for x := 0; x < 5; x++ {
		pxz[x] = make([]float64, 5, 5)
	}
	sum = 0.0
	for x := 0; x < 5; x++ {
		for y := 0; y < 5; y++ {
			for z := 0; z < 5; z++ {
				pxz[x][z] += pxyz[x][y][z]
				sum += pxyz[x][y][z]
			}
		}
	}

	if math.Abs(sum-1.0) > 0.0001 {
		t.Errorf("\\sum_{x,y,z} p(x,y,z) should be 1.0 but it is %f", sum)
	}

	px_yz := make([][]float64, 5, 5)
	for x := 0; x < 5; x++ {
		px_yz[x] = make([]float64, 25, 25)
		for y := 0; y < 5; y++ {
			for z := 0; z < 5; z++ {
				px_yz[x][y*5+z] = pxyz[x][y][z]
			}
		}
	}

	cmi := goent.ConditionalMutualInformation2(pxyz)
	multi := goent.MutualInformation2(px_yz)
	mi := goent.MutualInformation2(pxz)
	diff := cmi - (multi - mi)

	if math.Abs(diff) > 0.0001 {
		t.Errorf("I(X;Y|Z) = I(X;Y,Z) - I(X;Z) but the difference is %f, I(X;Y|Z): %f, I(X;Y,Z): %f, I(X;Z):%f", math.Abs(diff), cmi, multi, mi)
	}

}
<|endoftext|>


<commit_before>package client

import (
	"fmt"
	"time"

	"github.com/getlantern/balancer"
)

// getBalancer waits for a message from client.balCh to arrive and then it
// writes it back to client.balCh before returning it as a value. This way we
// always have a balancer at client.balCh and, if we don't have one, it would
// block until one arrives.
func (client *Client) getBalancer() *balancer.Balancer {
	bal, ok := client.bal.Get(24 * time.Hour)
	if !ok {
		panic("No balancer!")
	}
	return bal.(*balancer.Balancer)
}

// initBalancer takes hosts from cfg.ChainedServers and it uses them to create a
// balancer.
func (client *Client) initBalancer(cfg *ClientConfig) (*balancer.Balancer, error) {
	if len(cfg.ChainedServers) == 0 {
		return nil, fmt.Errorf("No chained servers configured, not initializing balancer")
	}
	// The dialers slice must be large enough to handle all chained
	// servers.
	dialers := make([]*balancer.Dialer, 0, len(cfg.ChainedServers))

	// Add chained (CONNECT proxy) servers.
	log.Debugf("Adding %d chained servers", len(cfg.ChainedServers))
	for _, s := range cfg.ChainedServers {
		dialer, err := s.Dialer(cfg.DeviceID)
		if err == nil {
			dialers = append(dialers, dialer)
		} else {
			log.Errorf("Unable to configure chained server. Received error: %v", err)
		}
	}

	bal := balancer.New(dialers...)
	var oldBal *balancer.Balancer
	var ok bool
	ob, ok := client.bal.Get(0 * time.Millisecond)
	if ok {
		oldBal = ob.(*balancer.Balancer)
	}

	log.Trace("Publishing balancer")
	client.bal.Set(bal)

	if oldBal != nil {
		// Close old balancer on a goroutine to avoid blocking here
		go func() {
			oldBal.Close()
			log.Debug("Closed old balancer")
		}()
	}

	return bal, nil
}
<commit_msg>flashlight to use new balancer<commit_after>package client

import (
	"fmt"
	"time"

	"github.com/getlantern/balancer"
)

// getBalancer waits for a message from client.balCh to arrive and then it
// writes it back to client.balCh before returning it as a value. This way we
// always have a balancer at client.balCh and, if we don't have one, it would
// block until one arrives.
func (client *Client) getBalancer() *balancer.Balancer {
	bal, ok := client.bal.Get(24 * time.Hour)
	if !ok {
		panic("No balancer!")
	}
	return bal.(*balancer.Balancer)
}

// initBalancer takes hosts from cfg.ChainedServers and it uses them to create a
// balancer.
func (client *Client) initBalancer(cfg *ClientConfig) (*balancer.Balancer, error) {
	if len(cfg.ChainedServers) == 0 {
		return nil, fmt.Errorf("No chained servers configured, not initializing balancer")
	}
	// The dialers slice must be large enough to handle all chained
	// servers.
	dialers := make([]*balancer.Dialer, 0, len(cfg.ChainedServers))

	// Add chained (CONNECT proxy) servers.
	log.Debugf("Adding %d chained servers", len(cfg.ChainedServers))
	for _, s := range cfg.ChainedServers {
		dialer, err := s.Dialer(cfg.DeviceID)
		if err == nil {
			dialers = append(dialers, dialer)
		} else {
			log.Errorf("Unable to configure chained server. Received error: %v", err)
		}
	}

	bal := balancer.New(balancer.QualityFirst, dialers...)
	var oldBal *balancer.Balancer
	var ok bool
	ob, ok := client.bal.Get(0 * time.Millisecond)
	if ok {
		oldBal = ob.(*balancer.Balancer)
	}

	log.Trace("Publishing balancer")
	client.bal.Set(bal)

	if oldBal != nil {
		// Close old balancer on a goroutine to avoid blocking here
		go func() {
			oldBal.Close()
			log.Debug("Closed old balancer")
		}()
	}

	return bal, nil
}
<|endoftext|>


<commit_before>package osversion

/*
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/sysctl.h>

int darwin_get_os(char* str, size_t size) {
    return sysctlbyname("kern.osrelease", str, &size, NULL, 0);
}
*/
import "C"

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
	"unsafe"
)

func GetString() (string, error) {
	bufferSize := C.size_t(256)
	str := (*C.char)(C.malloc(bufferSize))
	defer C.free(unsafe.Pointer(str))

	err := C.darwin_get_os(str, bufferSize)
	if err == -1 {
		return "", errors.New(fmt.Sprintf("Error running sysctl: %v", err))
	}
	return C.GoString(str), nil
}

func GetHumanReadable() (string, error) {
	versions := []string{
		"OS X 10.0.{patch} Cheetah",
		"OS X 10.1.{patch} Puma",
		"OS X 10.2.{patch} Jaguar",
		"OS X 10.3.{patch} Panther",
		"OS X 10.4.{patch} Tiger",
		"OS X 10.5.{patch} Leopard",
		"OS X 10.6.{patch} Snow Leopard",
		"OS X 10.7.{patch} Lion",
		"OS X 10.8.{patch} Mountain Lion",
		"OS X 10.9.{patch} Mavericks",
		"OS X 10.10.{patch} Yosemite",
		"OS X 10.11.{patch} El Capitan",
	}

	version, err := GetSemanticVersion()
	if err != nil {
		return "", err
	}
	if version.Major < 4 || version.Major > 11 {
		return "", errors.New("Unknown OS X version")
	}

	return strings.Replace(versions[version.Major-4],
		"{patch}",
		strconv.FormatUint(version.Patch, 10),
		1), nil
}
<commit_msg>Do not consider unknown versions an error<commit_after>package osversion

/*
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/sysctl.h>

int darwin_get_os(char* str, size_t size) {
    return sysctlbyname("kern.osrelease", str, &size, NULL, 0);
}
*/
import "C"

import (
	"errors"
	"fmt"
	"strconv"
	"strings"
	"unsafe"
)

func GetString() (string, error) {
	bufferSize := C.size_t(256)
	str := (*C.char)(C.malloc(bufferSize))
	defer C.free(unsafe.Pointer(str))

	err := C.darwin_get_os(str, bufferSize)
	if err == -1 {
		return "", errors.New(fmt.Sprintf("Error running sysctl: %v", err))
	}
	return C.GoString(str), nil
}

func GetHumanReadable() (string, error) {
	version, err := GetSemanticVersion()
	if err != nil {
		return "", err
	}
	if version.Major < 4 || version.Major > 11 {
		return fmt.Sprintf("Unknown OS X version: %s", version.String()), nil
	}

	return strings.Replace(versions[version.Major-4],
		"{patch}",
		strconv.FormatUint(version.Patch, 10),
		1), nil
}

var versions = []string{
	"OS X 10.0.{patch} Cheetah",
	"OS X 10.1.{patch} Puma",
	"OS X 10.2.{patch} Jaguar",
	"OS X 10.3.{patch} Panther",
	"OS X 10.4.{patch} Tiger",
	"OS X 10.5.{patch} Leopard",
	"OS X 10.6.{patch} Snow Leopard",
	"OS X 10.7.{patch} Lion",
	"OS X 10.8.{patch} Mountain Lion",
	"OS X 10.9.{patch} Mavericks",
	"OS X 10.10.{patch} Yosemite",
	"OS X 10.11.{patch} El Capitan",
}
<|endoftext|>


<commit_before>/*

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 v1beta1

import (
	"reflect"
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/onsi/gomega"
	"github.com/open-policy-agent/frameworks/constraint/pkg/core/templates"
	"golang.org/x/net/context"
	apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/types"
)

func TestStorageConstraintTemplate(t *testing.T) {
	key := types.NamespacedName{
		Name: "foo",
	}
	created := &ConstraintTemplate{
		ObjectMeta: metav1.ObjectMeta{
			Name: "foo",
		}}
	g := gomega.NewGomegaWithT(t)

	// Test Create
	fetched := &ConstraintTemplate{}
	g.Expect(c.Create(context.TODO(), created)).NotTo(gomega.HaveOccurred())

	g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred())
	g.Expect(fetched).To(gomega.Equal(created))

	// Test Updating the Labels
	updated := fetched.DeepCopy()
	updated.Labels = map[string]string{"hello": "world"}
	g.Expect(c.Update(context.TODO(), updated)).NotTo(gomega.HaveOccurred())

	g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred())
	g.Expect(fetched).To(gomega.Equal(updated))

	// Test Delete
	g.Expect(c.Delete(context.TODO(), fetched)).NotTo(gomega.HaveOccurred())
	g.Expect(c.Get(context.TODO(), key, fetched)).To(gomega.HaveOccurred())
}

func TestTypeConversion(t *testing.T) {
	scheme := runtime.NewScheme()
	AddToSchemes.AddToScheme(scheme)

	versioned := &ConstraintTemplate{
		TypeMeta: metav1.TypeMeta{
			Kind:       "ConstraintTemplate",
			APIVersion: "templates.gatekeeper.sh/v1alpha1",
		},
		ObjectMeta: metav1.ObjectMeta{
			Name: "MustHaveMoreCats",
		},
		Spec: ConstraintTemplateSpec{
			CRD: CRD{
				Spec: CRDSpec{
					Names: Names{
						Kind: "MustHaveMoreCats",
					},
					Validation: &Validation{
						OpenAPIV3Schema: &apiextensionsv1beta1.JSONSchemaProps{
							Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
								"message": apiextensionsv1beta1.JSONSchemaProps{
									Type: "string",
								},
								"labels": apiextensionsv1beta1.JSONSchemaProps{
									Type: "array",
									Items: &apiextensionsv1beta1.JSONSchemaPropsOrArray{
										Schema: &apiextensionsv1beta1.JSONSchemaProps{
											Type: "object",
											Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
												"key":          apiextensionsv1beta1.JSONSchemaProps{Type: "string"},
												"allowedRegex": apiextensionsv1beta1.JSONSchemaProps{Type: "string"},
											},
										},
									},
								},
							},
						},
					},
				},
			},
			Targets: []Target{
				{
					Target: "sometarget",
					Rego:   `package hello ; violation[{"msg": "msg"}] { true }`,
				},
			},
		},
	}
	versionedCopy := versioned.DeepCopy()
	// Kind and API Version do not survive the conversion process
	versionedCopy.Kind = ""
	versionedCopy.APIVersion = ""

	unversioned := &templates.ConstraintTemplate{}
	scheme.Convert(versioned, unversioned, nil)
	recast := &ConstraintTemplate{}
	scheme.Convert(unversioned, recast, nil)
	if !reflect.DeepEqual(versionedCopy, recast) {
		t.Error(cmp.Diff(versionedCopy, recast))
	}
}
<commit_msg>Fix version in Constraint Template v1beta1 test<commit_after>/*

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 v1beta1

import (
	"reflect"
	"testing"

	"github.com/google/go-cmp/cmp"
	"github.com/onsi/gomega"
	"github.com/open-policy-agent/frameworks/constraint/pkg/core/templates"
	"golang.org/x/net/context"
	apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/types"
)

func TestStorageConstraintTemplate(t *testing.T) {
	key := types.NamespacedName{
		Name: "foo",
	}
	created := &ConstraintTemplate{
		ObjectMeta: metav1.ObjectMeta{
			Name: "foo",
		}}
	g := gomega.NewGomegaWithT(t)

	// Test Create
	fetched := &ConstraintTemplate{}
	g.Expect(c.Create(context.TODO(), created)).NotTo(gomega.HaveOccurred())

	g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred())
	g.Expect(fetched).To(gomega.Equal(created))

	// Test Updating the Labels
	updated := fetched.DeepCopy()
	updated.Labels = map[string]string{"hello": "world"}
	g.Expect(c.Update(context.TODO(), updated)).NotTo(gomega.HaveOccurred())

	g.Expect(c.Get(context.TODO(), key, fetched)).NotTo(gomega.HaveOccurred())
	g.Expect(fetched).To(gomega.Equal(updated))

	// Test Delete
	g.Expect(c.Delete(context.TODO(), fetched)).NotTo(gomega.HaveOccurred())
	g.Expect(c.Get(context.TODO(), key, fetched)).To(gomega.HaveOccurred())
}

func TestTypeConversion(t *testing.T) {
	scheme := runtime.NewScheme()
	AddToSchemes.AddToScheme(scheme)

	versioned := &ConstraintTemplate{
		TypeMeta: metav1.TypeMeta{
			Kind:       "ConstraintTemplate",
			APIVersion: "templates.gatekeeper.sh/v1beta1",
		},
		ObjectMeta: metav1.ObjectMeta{
			Name: "MustHaveMoreCats",
		},
		Spec: ConstraintTemplateSpec{
			CRD: CRD{
				Spec: CRDSpec{
					Names: Names{
						Kind: "MustHaveMoreCats",
					},
					Validation: &Validation{
						OpenAPIV3Schema: &apiextensionsv1beta1.JSONSchemaProps{
							Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
								"message": apiextensionsv1beta1.JSONSchemaProps{
									Type: "string",
								},
								"labels": apiextensionsv1beta1.JSONSchemaProps{
									Type: "array",
									Items: &apiextensionsv1beta1.JSONSchemaPropsOrArray{
										Schema: &apiextensionsv1beta1.JSONSchemaProps{
											Type: "object",
											Properties: map[string]apiextensionsv1beta1.JSONSchemaProps{
												"key":          apiextensionsv1beta1.JSONSchemaProps{Type: "string"},
												"allowedRegex": apiextensionsv1beta1.JSONSchemaProps{Type: "string"},
											},
										},
									},
								},
							},
						},
					},
				},
			},
			Targets: []Target{
				{
					Target: "sometarget",
					Rego:   `package hello ; violation[{"msg": "msg"}] { true }`,
				},
			},
		},
	}
	versionedCopy := versioned.DeepCopy()
	// Kind and API Version do not survive the conversion process
	versionedCopy.Kind = ""
	versionedCopy.APIVersion = ""

	unversioned := &templates.ConstraintTemplate{}
	scheme.Convert(versioned, unversioned, nil)
	recast := &ConstraintTemplate{}
	scheme.Convert(unversioned, recast, nil)
	if !reflect.DeepEqual(versionedCopy, recast) {
		t.Error(cmp.Diff(versionedCopy, recast))
	}
}
<|endoftext|>


<commit_before>package dkim

import (
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"io/ioutil"
	"mime/quotedprintable"
	"net"
	"strings"
)

// PubKeyRep represents a parsed version of public key record
type PubKeyRep struct {
	Version      string
	HashAlgo     []string
	KeyType      string
	Note         string
	PubKey       rsa.PublicKey
	ServiceType  []string
	FlagTesting  bool // flag y
	FlagIMustBeD bool // flag i
}

// NewPubKeyRespFromDNS retrieves the TXT record from DNS based on the specified domain and selector
// and parses it.
func NewPubKeyRespFromDNS(selector, domain string) (*PubKeyRep, verifyOutput, error) {
	txt, err := net.LookupTXT(selector + "._domainkey." + domain)
	if err != nil {
		if strings.HasSuffix(err.Error(), "no such host") {
			return nil, PERMFAIL, ErrVerifyNoKeyForSignature
		}

		return nil, TEMPFAIL, ErrVerifyKeyUnavailable
	}

	// empty record
	if len(txt) == 0 {
		return nil, PERMFAIL, ErrVerifyNoKeyForSignature
	}

	// parsing, we keep the first record
	// TODO: if there is multiple record

	return NewPubKeyResp(txt[0])
}

// NewPubKeyResp parses DKIM record (usually from DNS)
func NewPubKeyResp(dkimRecord string) (*PubKeyRep, verifyOutput, error) {
	pkr := new(PubKeyRep)
	pkr.Version = "DKIM1"
	pkr.HashAlgo = []string{"sha1", "sha256"}
	pkr.KeyType = "rsa"
	pkr.FlagTesting = false
	pkr.FlagIMustBeD = false

	p := strings.Split(dkimRecord, ";")
	for i, data := range p {
		keyVal := strings.SplitN(data, "=", 2)
		val := ""
		if len(keyVal) > 1 {
			val = strings.TrimSpace(keyVal[1])
		}
		switch strings.ToLower(strings.TrimSpace(keyVal[0])) {
		case "v":
			// RFC: is this tag is specified it MUST be the first in the record
			if i != 0 {
				return nil, PERMFAIL, ErrVerifyTagVMustBeTheFirst
			}
			pkr.Version = val
			if pkr.Version != "DKIM1" {
				return nil, PERMFAIL, ErrVerifyVersionMusBeDkim1
			}
		case "h":
			p := strings.Split(strings.ToLower(val), ":")
			pkr.HashAlgo = []string{}
			for _, h := range p {
				h = strings.TrimSpace(h)
				if h == "sha1" || h == "sha256" {
					pkr.HashAlgo = append(pkr.HashAlgo, h)
				}
			}
			// if empty switch back to default
			if len(pkr.HashAlgo) == 0 {
				pkr.HashAlgo = []string{"sha1", "sha256"}
			}
		case "k":
			if strings.ToLower(val) != "rsa" {
				return nil, PERMFAIL, ErrVerifyBadKeyType
			}
		case "n":
			qp, err := ioutil.ReadAll(quotedprintable.NewReader(strings.NewReader(val)))
			if err == nil {
				val = string(qp)
			}
			pkr.Note = val
		case "p":
			rawkey := val
			if rawkey == "" {
				return nil, PERMFAIL, ErrVerifyRevokedKey
			}
			un64, err := base64.StdEncoding.DecodeString(rawkey)
			if err != nil {
				return nil, PERMFAIL, ErrVerifyBadKey
			}
			pk, err := x509.ParsePKIXPublicKey(un64)
			if pk, ok := pk.(*rsa.PublicKey); ok {
				pkr.PubKey = *pk
			}
		case "s":
			t := strings.Split(strings.ToLower(val), ":")
			for _, tt := range t {
				tt = strings.TrimSpace(tt)
				switch tt {
				case "*":
					pkr.ServiceType = append(pkr.ServiceType, "all")
				case "email":
					pkr.ServiceType = append(pkr.ServiceType, tt)
				}
			}
		case "t":
			flags := strings.Split(strings.ToLower(val), ":")
			for _, flag := range flags {
				if flag == "y" {
					pkr.FlagTesting = true
					continue
				}
				if flag == "s" {
					pkr.FlagIMustBeD = true
				}
			}
		}
	}

	// if no pubkey
	if pkr.PubKey == (rsa.PublicKey{}) {
		return nil, PERMFAIL, ErrVerifyNoKey
	}

	// No service type
	if len(pkr.ServiceType) == 0 {
		pkr.ServiceType = []string{"all"}
	}

	return pkr, SUCCESS, nil
}
<commit_msg>More canonical flag checing for the testing flag<commit_after>package dkim

import (
	"crypto/rsa"
	"crypto/x509"
	"encoding/base64"
	"io/ioutil"
	"mime/quotedprintable"
	"net"
	"strings"
)

// PubKeyRep represents a parsed version of public key record
type PubKeyRep struct {
	Version      string
	HashAlgo     []string
	KeyType      string
	Note         string
	PubKey       rsa.PublicKey
	ServiceType  []string
	FlagTesting  bool // flag y
	FlagIMustBeD bool // flag i
}

// NewPubKeyRespFromDNS retrieves the TXT record from DNS based on the specified domain and selector
// and parses it.
func NewPubKeyRespFromDNS(selector, domain string) (*PubKeyRep, verifyOutput, error) {
	txt, err := net.LookupTXT(selector + "._domainkey." + domain)
	if err != nil {
		if strings.HasSuffix(err.Error(), "no such host") {
			return nil, PERMFAIL, ErrVerifyNoKeyForSignature
		}

		return nil, TEMPFAIL, ErrVerifyKeyUnavailable
	}

	// empty record
	if len(txt) == 0 {
		return nil, PERMFAIL, ErrVerifyNoKeyForSignature
	}

	// parsing, we keep the first record
	// TODO: if there is multiple record

	return NewPubKeyResp(txt[0])
}

// NewPubKeyResp parses DKIM record (usually from DNS)
func NewPubKeyResp(dkimRecord string) (*PubKeyRep, verifyOutput, error) {
	pkr := new(PubKeyRep)
	pkr.Version = "DKIM1"
	pkr.HashAlgo = []string{"sha1", "sha256"}
	pkr.KeyType = "rsa"
	pkr.FlagTesting = false
	pkr.FlagIMustBeD = false

	p := strings.Split(dkimRecord, ";")
	for i, data := range p {
		keyVal := strings.SplitN(data, "=", 2)
		val := ""
		if len(keyVal) > 1 {
			val = strings.TrimSpace(keyVal[1])
		}
		switch strings.ToLower(strings.TrimSpace(keyVal[0])) {
		case "v":
			// RFC: is this tag is specified it MUST be the first in the record
			if i != 0 {
				return nil, PERMFAIL, ErrVerifyTagVMustBeTheFirst
			}
			pkr.Version = val
			if pkr.Version != "DKIM1" {
				return nil, PERMFAIL, ErrVerifyVersionMusBeDkim1
			}
		case "h":
			p := strings.Split(strings.ToLower(val), ":")
			pkr.HashAlgo = []string{}
			for _, h := range p {
				h = strings.TrimSpace(h)
				if h == "sha1" || h == "sha256" {
					pkr.HashAlgo = append(pkr.HashAlgo, h)
				}
			}
			// if empty switch back to default
			if len(pkr.HashAlgo) == 0 {
				pkr.HashAlgo = []string{"sha1", "sha256"}
			}
		case "k":
			if strings.ToLower(val) != "rsa" {
				return nil, PERMFAIL, ErrVerifyBadKeyType
			}
		case "n":
			qp, err := ioutil.ReadAll(quotedprintable.NewReader(strings.NewReader(val)))
			if err == nil {
				val = string(qp)
			}
			pkr.Note = val
		case "p":
			rawkey := val
			if rawkey == "" {
				return nil, PERMFAIL, ErrVerifyRevokedKey
			}
			un64, err := base64.StdEncoding.DecodeString(rawkey)
			if err != nil {
				return nil, PERMFAIL, ErrVerifyBadKey
			}
			pk, err := x509.ParsePKIXPublicKey(un64)
			if pk, ok := pk.(*rsa.PublicKey); ok {
				pkr.PubKey = *pk
			}
		case "s":
			t := strings.Split(strings.ToLower(val), ":")
			for _, tt := range t {
				tt = strings.TrimSpace(tt)
				switch tt {
				case "*":
					pkr.ServiceType = append(pkr.ServiceType, "all")
				case "email":
					pkr.ServiceType = append(pkr.ServiceType, tt)
				}
			}
		case "t":
			flags := strings.Split(strings.ToLower(val), ":")
			for _, flag := range flags {
				flag = strings.TrimSpace(flag)
				switch flag {
				case "y":
					pkr.FlagTesting = true
				case "s":
					pkr.FlagIMustBeD = true
				}
			}
		}
	}

	// if no pubkey
	if pkr.PubKey == (rsa.PublicKey{}) {
		return nil, PERMFAIL, ErrVerifyNoKey
	}

	// No service type
	if len(pkr.ServiceType) == 0 {
		pkr.ServiceType = []string{"all"}
	}

	return pkr, SUCCESS, nil
}
<|endoftext|>


<commit_before>package imageprocessor

import (
	"crypto/rand"
	"github.com/gophergala/imgurgo/uploadedfile"
	"log"
)

func init() {
	hashGetter := make(chan string)
	length := 7

	go func() {
		for {
			str := ""

			for len(str) < length {
				c := 10
				bArr := make([]byte, c)
				_, err := rand.Read(bArr)
				if err != nil {
					log.Println("error:", err)
					break
				}

				for _, b := range bArr {
					if len(str) == length {
						break
					}

					/**
					 * Each byte will be in [0, 256), but we only care about:
					 *
					 * [48, 57]     0-9
					 * [65, 90]     A-Z
					 * [97, 122]    a-z
					 *
					 * Which means that the highest bit will always be zero, since the last byte with high bit
					 * zero is 01111111 = 127 which is higher than 122. Lower our odds of having to re-roll a byte by
					 * dividing by two (right bit shift of 1).
					 */

					b = b >> 1

					// The byte is any of        0-9                  A-Z                      a-z
					byteIsAllowable := (b >= 48 && b <= 57) || (b >= 65 && b <= 90) || (b >= 97 && b <= 122)

					if byteIsAllowable {
						str += string(b)
					}
				}

			}

			hashGetter <- str
		}
	}()
}

type multiProcessType []ProcessType

func (this multiProcessType) Process(image *uploadedfile.UploadedFile) error {
	for _, processor := range this {
		err := processor.Process(image)
		if err != nil {
			return err
		}
	}

	return nil
}

type asyncProcessType []ProcessType

func (this asyncProcessType) Process(image *uploadedfile.UploadedFile) error {
	results := make(chan bool, len(this))
	errs := make(chan error, len(this))

	for _, processor := range this {
		go func(p ProcessType) {
			err := processor.Process(image)
			if err != nil {
				errs <- err
			}

			results <- true
		}(processor)
	}

	for i := 0; i < len(this); i++ {
		select {
		case <-results:
		case err := <-errs:
			return err
		}
	}

	return nil
}

type ProcessType interface {
	Process(image *uploadedfile.UploadedFile) error
}

type ImageProcessor struct {
	processor ProcessType
}

func (this *ImageProcessor) Run(image *uploadedfile.UploadedFile) error {
	return this.processor.Process(image)
}

func Factory(maxFileSize int64, file *uploadedfile.UploadedFile) (*ImageProcessor, error) {
	size, err := file.FileSize()
	if err != nil {
		return &ImageProcessor{}, err
	}

	processor := multiProcessType{}

	if size > maxFileSize {
		processor = append(processor, &ImageScaler{maxFileSize})
	}

	return &ImageProcessor{processor}, nil
}
<commit_msg>don't need an extra results channel<commit_after>package imageprocessor

import (
	"crypto/rand"
	"github.com/gophergala/imgurgo/uploadedfile"
	"log"
)

func init() {
	hashGetter := make(chan string)
	length := 7

	go func() {
		for {
			str := ""

			for len(str) < length {
				c := 10
				bArr := make([]byte, c)
				_, err := rand.Read(bArr)
				if err != nil {
					log.Println("error:", err)
					break
				}

				for _, b := range bArr {
					if len(str) == length {
						break
					}

					/**
					 * Each byte will be in [0, 256), but we only care about:
					 *
					 * [48, 57]     0-9
					 * [65, 90]     A-Z
					 * [97, 122]    a-z
					 *
					 * Which means that the highest bit will always be zero, since the last byte with high bit
					 * zero is 01111111 = 127 which is higher than 122. Lower our odds of having to re-roll a byte by
					 * dividing by two (right bit shift of 1).
					 */

					b = b >> 1

					// The byte is any of        0-9                  A-Z                      a-z
					byteIsAllowable := (b >= 48 && b <= 57) || (b >= 65 && b <= 90) || (b >= 97 && b <= 122)

					if byteIsAllowable {
						str += string(b)
					}
				}

			}

			hashGetter <- str
		}
	}()
}

type multiProcessType []ProcessType

func (this multiProcessType) Process(image *uploadedfile.UploadedFile) error {
	for _, processor := range this {
		err := processor.Process(image)
		if err != nil {
			return err
		}
	}

	return nil
}

type asyncProcessType []ProcessType

func (this asyncProcessType) Process(image *uploadedfile.UploadedFile) error {
	errs := make(chan error, len(this))

	for _, processor := range this {
		go func(p ProcessType) {
			err := processor.Process(image)
			if err != nil {
				errs <- err
			}
		}(processor)
	}

	for i := 0; i < len(this); i++ {
		select {
		case err := <-errs:
			if err != nil {
				return err
			}
		}
	}

	return nil
}

type ProcessType interface {
	Process(image *uploadedfile.UploadedFile) error
}

type ImageProcessor struct {
	processor ProcessType
}

func (this *ImageProcessor) Run(image *uploadedfile.UploadedFile) error {
	return this.processor.Process(image)
}

func Factory(maxFileSize int64, file *uploadedfile.UploadedFile) (*ImageProcessor, error) {
	size, err := file.FileSize()
	if err != nil {
		return &ImageProcessor{}, err
	}

	processor := multiProcessType{}

	if size > maxFileSize {
		processor = append(processor, &ImageScaler{maxFileSize})
	}

	return &ImageProcessor{processor}, nil
}
<|endoftext|>


<commit_before>package dtls

import (
	"errors"
	"sync"
	"time"
)

type Listener struct {
	transport          Transport
	peers              map[string]*Peer
	readQueue          chan *msg
	mux                sync.Mutex
	wg                 sync.WaitGroup
	isShutdown         bool
	cipherSuites       []CipherSuite
	compressionMethods []CompressionMethod
}

type msg struct {
	data []byte
	peer *Peer
}

func NewUdpListener(listener string, readTimeout time.Duration) (*Listener, error) {
	utrans, err := newUdpTransport(listener, readTimeout)
	if err != nil {
		return nil, err
	}

	l := &Listener{transport: utrans, peers: make(map[string]*Peer), readQueue: make(chan *msg, 128)}
	l.wg.Add(1)
	go receiver(l)
	return l, nil
}

func receiver(l *Listener) {
	if l.isShutdown {
		logDebug("dtls: [%s][%s] receiver shutting down", l.transport.Type(), l.transport.Local())
		l.wg.Done()
		return
	}
	logDebug("dtls: [%s][%s] waiting for packet", l.transport.Type(), l.transport.Local())
	data, peer, err := l.transport.ReadPacket()
	if err != nil {
		logError("[%s][%s] failed to read packet: %s", l.transport.Type(), l.transport.Local(), err.Error())
		l.wg.Done()
		return
	}

	l.mux.Lock()
	p, found := l.peers[peer.String()]
	l.mux.Unlock()
	if !found {
		//this is where server code will go
		logInfo("dtls: [%s][%s] received from unknown peer %s", l.transport.Type(), l.transport.Local(), peer.String())
		p, _ = l.addServerPeer(peer)
	} else {
		logInfo("dtls: [%s][%s] received from peer %s", l.transport.Type(), l.transport.Local(), peer.String())
	}

	for {
		rec, rem, err := p.session.parseRecord(data)
		if err != nil {
			logWarn("dtls: [%s][%s] error parsing record from %s: %s", l.transport.Type(), l.transport.Local(), peer.String(), err.Error())
			l.RemovePeer(p, AlertDesc_DecodeError)
			break
		}

		if rec.IsHandshake() {
			if !p.session.isHandshakeDone() {
				logDebug("dtls: [%s][%s] handshake in progress from %s", l.transport.Type(), l.transport.Local(), peer.String())
				if err := p.session.processHandshakePacket(rec); err != nil {
					l.RemovePeer(p, AlertDesc_HandshakeFailure)
					logWarn("dtls: [%s][%s] failed to complete handshake for %s: %s", l.transport.Type(), l.transport.Local(), peer.String(), err.Error())
				}
			} else {
				l.RemovePeer(p, AlertDesc_HandshakeFailure)
				logWarn("dtls: [%s][%s] received handshake message after handshake is complete for %s", l.transport.Type(), l.transport.Local(), peer.String())
			}
		} else if rec.IsAlert() {
			//handle alert
			alert, err := parseAlert(rec.Data)
			if err != nil {
				l.RemovePeer(p, AlertDesc_DecodeError)
				logWarn("dtls: [%s][%s] failed to parse alert for %s: %s", l.transport.Type(), l.transport.Local(), peer.String(), err.Error())
			}
			if alert.Type == AlertType_Warning {
				logInfo("dtls: [%s][%s] received warning alert from %s: %s", l.transport.Type(), l.transport.Local(), peer.String(), alertDescToString(alert.Desc))
			} else {
				l.RemovePeer(p, AlertDesc_Noop)
				logWarn("dtls: [%s][%s] received fatal alert from %s: %s", l.transport.Type(), l.transport.Local(), peer.String(), alertDescToString(alert.Desc))
			}
		} else if rec.IsAppData() && !p.session.isHandshakeDone() {
			l.RemovePeer(p, AlertDesc_DecryptError)
			logWarn("dtls: [%s][%s] received app data message without completing handshake for %s", l.transport.Type(), l.transport.Local(), peer.String())
		} else {
			if p.queue != nil {
				p.queue <- rec.Data
			} else {
				l.readQueue <- &msg{rec.Data, p}
			}
			//TODO handle case where queue is full and not being read
		}
		if rem == nil {
			break
		} else {
			data = rem
		}
	}

	l.wg.Add(1)
	go receiver(l)
	l.wg.Done()
	//TODO need to queue records for each session so that we can process multiple in parallel
}

func (l *Listener) RemovePeer(peer *Peer, alertDesc uint8) error {
	l.mux.Lock()
	if alertDesc != AlertDesc_Noop {
		peer.Close(alertDesc)
	}
	delete(l.peers, peer.RemoteAddr())
	l.mux.Unlock()
	return nil
}

func (l *Listener) addServerPeer(tpeer TransportPeer) (*Peer, error) {
	peer := &Peer{peer: tpeer}
	peer.session = newServerSession(peer.peer)
	if l.cipherSuites != nil {
		peer.session.cipherSuites = l.cipherSuites
	}
	if l.compressionMethods != nil {
		peer.session.compressionMethods = l.compressionMethods
	}
	l.mux.Lock()
	l.peers[peer.peer.String()] = peer
	l.mux.Unlock()
	return peer, nil
}

type PeerParams struct {
	Addr             string
	Identity         string
	HandshakeTimeout time.Duration
}

func (l *Listener) AddPeer(addr string, identity string) (*Peer, error) {
	return l.AddPeerWithParams(&PeerParams{Addr: addr, Identity: identity, HandshakeTimeout: time.Second * 20})
}

func (l *Listener) AddPeerWithParams(params *PeerParams) (*Peer, error) {
	peer := &Peer{peer: l.transport.NewPeer(params.Addr)}
	peer.UseQueue(true)
	peer.session = newClientSession(peer.peer)
	if l.cipherSuites != nil {
		peer.session.cipherSuites = l.cipherSuites
	}
	if l.compressionMethods != nil {
		peer.session.compressionMethods = l.compressionMethods
	}
	peer.session.Client.Identity = params.Identity
	l.mux.Lock()
	l.peers[peer.peer.String()] = peer
	l.mux.Unlock()
	peer.session.startHandshake()
	if err := peer.session.waitForHandshake(params.HandshakeTimeout); err != nil {
		l.mux.Lock()
		delete(l.peers, peer.peer.String())
		l.mux.Unlock()
		return nil, err
	}
	return peer, nil
}

func (l *Listener) Read() ([]byte, *Peer) {
	msg := <-l.readQueue

	return msg.data, msg.peer
}

func (l *Listener) Shutdown() error {
	l.isShutdown = true
	//gracefully send alerts to each connected peer
	err := l.transport.Shutdown()
	l.wg.Wait()
	return err
}

func (l *Listener) AddCipherSuite(cipherSuite CipherSuite) {
	if l.cipherSuites == nil {
		l.cipherSuites = make([]CipherSuite, 0, 4)
	}
	l.cipherSuites = append(l.cipherSuites, cipherSuite)
	return
}

func (l *Listener) AddCompressionMethod(compressionMethod CompressionMethod) {
	if l.compressionMethods == nil {
		l.compressionMethods = make([]CompressionMethod, 0, 4)
	}
	l.compressionMethods = append(l.compressionMethods, compressionMethod)
	return
}

func (l *Listener) FindPeer(addr string) (*Peer, error) {
	l.mux.Lock()
	p, found := l.peers[addr]
	l.mux.Unlock()
	if found {
		return p, nil
	} else {
		return nil, errors.New("dtls: Peer [" + addr + "] not found.")
	}
}
<commit_msg>Added function for counting the number of registered peers.<commit_after>package dtls

import (
	"errors"
	"sync"
	"time"
)

type Listener struct {
	transport          Transport
	peers              map[string]*Peer
	readQueue          chan *msg
	mux                sync.Mutex
	wg                 sync.WaitGroup
	isShutdown         bool
	cipherSuites       []CipherSuite
	compressionMethods []CompressionMethod
}

type msg struct {
	data []byte
	peer *Peer
}

func NewUdpListener(listener string, readTimeout time.Duration) (*Listener, error) {
	utrans, err := newUdpTransport(listener, readTimeout)
	if err != nil {
		return nil, err
	}

	l := &Listener{transport: utrans, peers: make(map[string]*Peer), readQueue: make(chan *msg, 128)}
	l.wg.Add(1)
	go receiver(l)
	return l, nil
}

func receiver(l *Listener) {
	if l.isShutdown {
		logDebug("dtls: [%s][%s] receiver shutting down", l.transport.Type(), l.transport.Local())
		l.wg.Done()
		return
	}
	logDebug("dtls: [%s][%s] waiting for packet", l.transport.Type(), l.transport.Local())
	data, peer, err := l.transport.ReadPacket()
	if err != nil {
		logError("[%s][%s] failed to read packet: %s", l.transport.Type(), l.transport.Local(), err.Error())
		l.wg.Done()
		return
	}

	l.mux.Lock()
	p, found := l.peers[peer.String()]
	l.mux.Unlock()
	if !found {
		//this is where server code will go
		logInfo("dtls: [%s][%s] received from unknown peer %s", l.transport.Type(), l.transport.Local(), peer.String())
		p, _ = l.addServerPeer(peer)
	} else {
		logInfo("dtls: [%s][%s] received from peer %s", l.transport.Type(), l.transport.Local(), peer.String())
	}

	for {
		rec, rem, err := p.session.parseRecord(data)
		if err != nil {
			logWarn("dtls: [%s][%s] error parsing record from %s: %s", l.transport.Type(), l.transport.Local(), peer.String(), err.Error())
			l.RemovePeer(p, AlertDesc_DecodeError)
			break
		}

		if rec.IsHandshake() {
			if !p.session.isHandshakeDone() {
				logDebug("dtls: [%s][%s] handshake in progress from %s", l.transport.Type(), l.transport.Local(), peer.String())
				if err := p.session.processHandshakePacket(rec); err != nil {
					l.RemovePeer(p, AlertDesc_HandshakeFailure)
					logWarn("dtls: [%s][%s] failed to complete handshake for %s: %s", l.transport.Type(), l.transport.Local(), peer.String(), err.Error())
				}
			} else {
				l.RemovePeer(p, AlertDesc_HandshakeFailure)
				logWarn("dtls: [%s][%s] received handshake message after handshake is complete for %s", l.transport.Type(), l.transport.Local(), peer.String())
			}
		} else if rec.IsAlert() {
			//handle alert
			alert, err := parseAlert(rec.Data)
			if err != nil {
				l.RemovePeer(p, AlertDesc_DecodeError)
				logWarn("dtls: [%s][%s] failed to parse alert for %s: %s", l.transport.Type(), l.transport.Local(), peer.String(), err.Error())
			}
			if alert.Type == AlertType_Warning {
				logInfo("dtls: [%s][%s] received warning alert from %s: %s", l.transport.Type(), l.transport.Local(), peer.String(), alertDescToString(alert.Desc))
			} else {
				l.RemovePeer(p, AlertDesc_Noop)
				logWarn("dtls: [%s][%s] received fatal alert from %s: %s", l.transport.Type(), l.transport.Local(), peer.String(), alertDescToString(alert.Desc))
			}
		} else if rec.IsAppData() && !p.session.isHandshakeDone() {
			l.RemovePeer(p, AlertDesc_DecryptError)
			logWarn("dtls: [%s][%s] received app data message without completing handshake for %s", l.transport.Type(), l.transport.Local(), peer.String())
		} else {
			if p.queue != nil {
				p.queue <- rec.Data
			} else {
				l.readQueue <- &msg{rec.Data, p}
			}
			//TODO handle case where queue is full and not being read
		}
		if rem == nil {
			break
		} else {
			data = rem
		}
	}

	l.wg.Add(1)
	go receiver(l)
	l.wg.Done()
	//TODO need to queue records for each session so that we can process multiple in parallel
}

func (l *Listener) RemovePeer(peer *Peer, alertDesc uint8) error {
	l.mux.Lock()
	if alertDesc != AlertDesc_Noop {
		peer.Close(alertDesc)
	}
	delete(l.peers, peer.RemoteAddr())
	l.mux.Unlock()
	return nil
}

func (l *Listener) addServerPeer(tpeer TransportPeer) (*Peer, error) {
	peer := &Peer{peer: tpeer}
	peer.session = newServerSession(peer.peer)
	if l.cipherSuites != nil {
		peer.session.cipherSuites = l.cipherSuites
	}
	if l.compressionMethods != nil {
		peer.session.compressionMethods = l.compressionMethods
	}
	l.mux.Lock()
	l.peers[peer.peer.String()] = peer
	l.mux.Unlock()
	return peer, nil
}

type PeerParams struct {
	Addr             string
	Identity         string
	HandshakeTimeout time.Duration
}

func (l *Listener) AddPeer(addr string, identity string) (*Peer, error) {
	return l.AddPeerWithParams(&PeerParams{Addr: addr, Identity: identity, HandshakeTimeout: time.Second * 20})
}

func (l *Listener) AddPeerWithParams(params *PeerParams) (*Peer, error) {
	peer := &Peer{peer: l.transport.NewPeer(params.Addr)}
	peer.UseQueue(true)
	peer.session = newClientSession(peer.peer)
	if l.cipherSuites != nil {
		peer.session.cipherSuites = l.cipherSuites
	}
	if l.compressionMethods != nil {
		peer.session.compressionMethods = l.compressionMethods
	}
	peer.session.Client.Identity = params.Identity
	l.mux.Lock()
	l.peers[peer.peer.String()] = peer
	l.mux.Unlock()
	peer.session.startHandshake()
	if err := peer.session.waitForHandshake(params.HandshakeTimeout); err != nil {
		l.mux.Lock()
		delete(l.peers, peer.peer.String())
		l.mux.Unlock()
		return nil, err
	}
	return peer, nil
}

func (l *Listener) Read() ([]byte, *Peer) {
	msg := <-l.readQueue

	return msg.data, msg.peer
}

func (l *Listener) Shutdown() error {
	l.isShutdown = true
	//gracefully send alerts to each connected peer
	err := l.transport.Shutdown()
	l.wg.Wait()
	return err
}

func (l *Listener) AddCipherSuite(cipherSuite CipherSuite) {
	if l.cipherSuites == nil {
		l.cipherSuites = make([]CipherSuite, 0, 4)
	}
	l.cipherSuites = append(l.cipherSuites, cipherSuite)
	return
}

func (l *Listener) AddCompressionMethod(compressionMethod CompressionMethod) {
	if l.compressionMethods == nil {
		l.compressionMethods = make([]CompressionMethod, 0, 4)
	}
	l.compressionMethods = append(l.compressionMethods, compressionMethod)
	return
}

func (l *Listener) FindPeer(addr string) (*Peer, error) {
	l.mux.Lock()
	p, found := l.peers[addr]
	l.mux.Unlock()
	if found {
		return p, nil
	} else {
		return nil, errors.New("dtls: Peer [" + addr + "] not found.")
	}
}

func (l *Listener) CountPeers() int {
	var count int
	l.mux.Lock()
	count = len(l.peers)
	l.mux.Unlock()
	return count
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"github.com/wsxiaoys/terminal"
	"math"
	"strconv"
	"strings"
)

type Dump struct {
	start    int64
	nextAddr int64
	buf      []uint32
}

// Expects format:
// 0x01549090:  00000000 00000000 ffffff1f ffffffff   *................*
func (dmp *Dump) Append(line string) error {
	if !strings.HasPrefix(line, "0x") || []byte(line)[10] != ':' {
		// Ignore bad format
		//fmt.Println("Ignoring %20s", line)
		return nil
	}

	var addr int64
	fields := strings.Fields(line)
	if len(fields) < 2 {
		return nil
	}

	if !strings.HasPrefix(fields[0], "0x") || !strings.HasSuffix(fields[0], ":") {
		return fmt.Errorf("Invalid addr. Read %v", fields)
	}

	addr, err := strconv.ParseInt(
		strings.TrimLeft(strings.TrimRight(fields[0], ":"), "0x"), 16, 64)
	if err != nil {
		return fmt.Errorf("Invalid addr: %s", err)
	}

	if dmp.buf == nil {
		dmp.start = addr
		dmp.nextAddr = addr
		dmp.buf = make([]uint32, 0, 2048)
	} else if addr != dmp.nextAddr {
		return fmt.Errorf("Line address 0x%x not expected 0x%x", addr, dmp.nextAddr)
	}

	i := 1
	for ; i <= 4; i++ {
		a, err := strconv.ParseInt(fields[i], 16, 64)
		if err != nil {
			return fmt.Errorf("Invalid int at 0x%x: %s", dmp.nextAddr, err)
		} else {
			dmp.nextAddr += 4
			dmp.buf = append(dmp.buf, uint32(a))
		}
	}

	//fmt.Printf("Read from dump %d at 0x%08x\n", i, addr)
	e := len(dmp.buf)
	reconstructed := []byte(fmt.Sprintf("0x%08x:  %08x %08x %08x %08x", addr,
		dmp.buf[e-4], dmp.buf[e-3], dmp.buf[e-2], dmp.buf[e-1]))
	orig := []byte(line)[:len(reconstructed)]
	if bytes.Compare(reconstructed, orig) != 0 {
		fmt.Printf("Didn't read right:\nOrig:\n%q\nReconstructed:\n%q\n",
			orig, reconstructed)
	}

	return nil
}

// Interpret the stack dump using the given symbol table.
// Unless limits are -1, limit the dump to the given range.
func (dmp *Dump) Walk(funcs *FunctionSearch, lowerLimit, upperLimit int64) {
	var ll int64 = math.MinInt64
	if lowerLimit > 0 {
		ll = lowerLimit - (lowerLimit % 16)
	}

	var ul int64 = math.MaxInt64
	if upperLimit > 0 {
		ul = upperLimit + (16 - (upperLimit % 16))
	}

	syms := make([]string, 0, 4)

	funcs.Top()

	for i, v32 := range dmp.buf {
		v := int64(v32)

		byteOffset := i * 4
		addr := dmp.start + int64(byteOffset)

		if addr < ll {
			continue
		}
		if addr >= ul {
			fmt.Println()
			return
		}

		if byteOffset%16 == 0 {
			fmt.Printf("\n0x%08x:  ", addr)
		}

		var delta int64
		if v >= addr {
			delta = v - addr
		} else {
			delta = addr - v
		}

		symbol := funcs.Find(uint64(v))

		const thresh = 0x1000
		switch {
		//case v == 0:
		//fmt.Printf("%08x  ", v)
		case symbol != nil:
			colorFmt := "@r"
			if symbol.Size == 0 {
				colorFmt = "@{rY}"
			}

			terminal.Stdout.Colorf(colorFmt+"%8.8s@{|}  ", symbol.Name)
			syms = append(syms, fmt.Sprintf("%s{0x%x}", symbol.Name, symbol.Value))
		case delta < thresh:
			// Pointer into stack
			terminal.Stdout.Colorf("@{.bK}stk%05x@{|}  ", delta)
		default:
			fmt.Printf("%08x  ", v)
		}

		if i%4 == 3 && len(syms) > 0 {
			fmt.Print(syms)
			syms = syms[:0]
		}

	}

	fmt.Println()
}
<commit_msg>Print offsets more clearly.<commit_after>package main

import (
	"bytes"
	"fmt"
	"github.com/wsxiaoys/terminal"
	"math"
	"strconv"
	"strings"
)

type Dump struct {
	start    int64
	nextAddr int64
	buf      []uint32
}

// Expects format:
// 0x01549090:  00000000 00000000 ffffff1f ffffffff   *................*
func (dmp *Dump) Append(line string) error {
	if !strings.HasPrefix(line, "0x") || []byte(line)[10] != ':' {
		// Ignore bad format
		//fmt.Println("Ignoring %20s", line)
		return nil
	}

	var addr int64
	fields := strings.Fields(line)
	if len(fields) < 2 {
		return nil
	}

	if !strings.HasPrefix(fields[0], "0x") || !strings.HasSuffix(fields[0], ":") {
		return fmt.Errorf("Invalid addr. Read %v", fields)
	}

	addr, err := strconv.ParseInt(
		strings.TrimLeft(strings.TrimRight(fields[0], ":"), "0x"), 16, 64)
	if err != nil {
		return fmt.Errorf("Invalid addr: %s", err)
	}

	if dmp.buf == nil {
		dmp.start = addr
		dmp.nextAddr = addr
		dmp.buf = make([]uint32, 0, 2048)
	} else if addr != dmp.nextAddr {
		return fmt.Errorf("Line address 0x%x not expected 0x%x", addr, dmp.nextAddr)
	}

	i := 1
	for ; i <= 4; i++ {
		a, err := strconv.ParseInt(fields[i], 16, 64)
		if err != nil {
			return fmt.Errorf("Invalid int at 0x%x: %s", dmp.nextAddr, err)
		} else {
			dmp.nextAddr += 4
			dmp.buf = append(dmp.buf, uint32(a))
		}
	}

	//fmt.Printf("Read from dump %d at 0x%08x\n", i, addr)
	e := len(dmp.buf)
	reconstructed := []byte(fmt.Sprintf("0x%08x:  %08x %08x %08x %08x", addr,
		dmp.buf[e-4], dmp.buf[e-3], dmp.buf[e-2], dmp.buf[e-1]))
	orig := []byte(line)[:len(reconstructed)]
	if bytes.Compare(reconstructed, orig) != 0 {
		fmt.Printf("Didn't read right:\nOrig:\n%q\nReconstructed:\n%q\n",
			orig, reconstructed)
	}

	return nil
}

// Interpret the stack dump using the given symbol table.
// Unless limits are -1, limit the dump to the given range.
func (dmp *Dump) Walk(funcs *FunctionSearch, lowerLimit, upperLimit int64) {
	var ll int64 = math.MinInt64
	if lowerLimit > 0 {
		ll = lowerLimit - (lowerLimit % 16)
	}

	var ul int64 = math.MaxInt64
	if upperLimit > 0 {
		ul = upperLimit + (16 - (upperLimit % 16))
	}

	syms := make([]string, 0, 4)

	funcs.Top()

	for i, v32 := range dmp.buf {
		v := int64(v32)

		byteOffset := i * 4
		addr := dmp.start + int64(byteOffset)

		if addr < ll {
			continue
		}
		if addr >= ul {
			fmt.Println()
			return
		}

		if byteOffset%16 == 0 {
			fmt.Printf("\n0x%08x:  ", addr)
		}

		var delta int64
		if v >= addr {
			delta = v - addr
		} else {
			delta = addr - v
		}

		symbol := funcs.Find(uint64(v))

		const thresh = 0x1000
		switch {
		//case v == 0:
		//fmt.Printf("%08x  ", v)
		case symbol != nil:
			colorFmt := "@r"
			if symbol.Size == 0 {
				colorFmt = "@{rY}"
			}

			terminal.Stdout.Colorf(colorFmt+"%8.8s@{|}  ", symbol.Name)
			syms = append(syms, fmt.Sprintf("%s{0x%x + 0x%x}", symbol.Name, symbol.Value, uint64(v)-symbol.Value))
		case delta < thresh:
			// Pointer into stack
			sign := "+"
			if v < addr {
				sign = "-"
			}
			terminal.Stdout.Colorf("@{.bK}stk%s%04x@{|}  ", sign, delta)
		default:
			fmt.Printf("%08x  ", v)
		}

		if i%4 == 3 && len(syms) > 0 {
			fmt.Print(syms)
			syms = syms[:0]
		}

	}

	fmt.Println()
}
<|endoftext|>