<commit_before>package floats

import "math"

// InsufficientElements is an error type used by FindFirst
type InsufficientElements struct{}

// Error makes InsufficientElements satisfy the error interface
func (i *InsufficientElements) Error() string {
	return "floats: insufficient elements found"
}

// Add returns the element-wise sum of all the slices with the
// results stored in the first slice.
// For computational efficiency, it is assumed that all of
// the variadic arguments have the same length. If this is
// in doubt, EqLen can be called first.
func Add(dst []float64, slices ...[]float64) {
	if len(slices) == 0 {
		return
	}
	if len(dst) != len(slices[0]) {
		panic("floats: length of destination does not match length of the slices")
	}
	for _, slice := range slices {
		for j, val := range slice {
			dst[j] += val
		}
	}
}

// AddConst adds a constant to all of the values in s
func AddConst(s []float64, c float64) {
	for i := range s {
		s[i] += c
	}
}

// ApplyFunc applies a function (math.Exp, math.Sin, etc.) to every element
// of the slice
func Apply(s []float64, f func(float64) float64) {
	for i, val := range s {
		s[i] = f(val)
	}
}

// Cumprod finds the cumulative product of the first i elements in
// s and puts them in place into the ith element of the
// destination. Panic will occur if lengths of do not match
func CumProd(dst, s []float64) {
	if len(dst) != len(s) {
		panic("floats: length of destination does not match length of the source")
	}
	dst[0] = s[0]
	for i := 1; i < len(s); i++ {
		dst[i] = dst[i-1] * s[i]
	}
	return
}

// Cumsum finds the cumulative sum of the first i elements in
// s and puts them in place into the ith element of the
// destination. Panic will occur if lengths of arguments do not match
func CumSum(dst, s []float64) {
	if len(dst) != len(s) {
		panic("floats: length of destination does not match length of the source")
	}
	dst[0] = s[0]
	for i := 1; i < len(s); i++ {
		dst[i] = dst[i-1] + s[i]
	}
}

// Dot computes the dot product of s1 and s2, i.e.
// sum_{i = 1}^N s1[n]*s2[n]
// Panic will occur if lengths of arguments do not match
func Dot(s1, s2 []float64) float64 {
	if len(s1) != len(s2) {
		panic("floats: lengths of the slices do not match")
	}
	var sum float64
	for i, val := range s1 {
		sum += val * s2[i]
	}
	return sum
}

// Eq returns false if the slices have different lengths
// or if |s1[i] - s2[i]| > tol for any i.
func Eq(s1, s2 []float64, tol float64) bool {
	if len(s1) != len(s2) {
		return false
	}
	for i, val := range s1 {
		if math.Abs(s2[i]-val) > tol {
			return false
		}
	}
	return true
}

// Eqlen returns true if all of the slices have equal length,
// and false otherwise. Returns true if there are no input slices
func EqLen(slices ...[]float64) bool {
	// This length check is needed: http://play.golang.org/p/sdty6YiLhM
	if len(slices) == 0 {
		return true
	}
	l := len(slices[0])
	for i := 1; i < len(slices); i++ {
		if len(slices[i]) != l {
			return false
		}
	}
	return true
}

// Find finds the first k indices of  s for which
// the function f returns true and stores them in
// inds. If k < 0, all such elements are found.
// Find will reslice inds to have 0 length, and will append
// found indices to inds.
// If k > 0 and there are fewer than k elements in s satisfying f,
// all of the found elements will be returned along with an
// InsufficientElements error
func Find(inds []int, k int, s []float64, f func(float64) bool) ([]int, error) {

	// inds is also returned to allow for calling with nil

	// Reslice inds to have zero length
	inds = inds[:0]

	// If zero elements requested, can just return
	if k == 0 {
		return inds, nil
	}

	// If k < 0, return all of the found indices
	if k < 0 {
		for i, val := range s {
			if f(val) {
				inds = append(inds, i)
			}
		}
		return inds, nil
	}

	// Otherwise, find the first k elements
	nFound := 0
	for i, val := range s {
		if f(val) {
			inds = append(inds, i)
			nFound++
			if nFound == k {
				return inds, nil
			}
		}
	}
	// Finished iterating over the loop, which means k elements were not found
	return inds, &InsufficientElements{}
}

// LogSpan returns a set of N equally spaced points in log space between l and u,
// where N is equal to the len(dst). The first element of the
// resulting dst will be l and the final element of dst will be u.
// If len(dst) = 0, dst will be returned unchanged, and if len(dst) = 1, the
// only element of dst will become l
// Note that this call will return NaNs if either l or u are negative, and
// will return all zeros if l or u is zero.
func LogSpan(dst []float64, l, u float64) {
	Span(dst, math.Log(l), math.Log(u))
	Apply(dst, math.Exp)
}

// Logsumexp returns the log of the sum of the exponentials of the values in s
func LogSumExp(s []float64) (lse float64) {
	// Want to do this in a numerically stable way which avoids
	// overflow and underflow
	// First, find the maximum value in the slice.
	maxval, _ := Max(s)
	if math.IsInf(maxval, 0) {
		// If it's infinity either way, the logsumexp will be infinity as well
		// returning now avoids NaNs
		return maxval
	}
	// Compute the sumexp part
	for _, val := range s {
		lse += math.Exp(val - maxval)
	}
	// Take the log and add back on the constant taken out
	lse = math.Log(lse) + maxval
	return lse
}

// Max returns the maximum value in the slice and the location of
// the maximum value. If the input slice is empty, zero is returned
// as the minimum value and -1 is returned as the index.
func Max(s []float64) (max float64, ind int) {
	if len(s) == 0 {
		return max, -1 // Ind is -1 to make clear it's not the zeroth index.
	}
	max = s[0]
	ind = 0
	for i, val := range s {
		if val > max {
			max = val
			ind = i
		}
	}
	return max, ind
}

// Min returns the minimum value in the slice and the index of
// the minimum value. If the input slice is empty, zero is returned
// as the minimum value and -1 is returned as the index.
func Min(s []float64) (min float64, ind int) {
	if len(s) == 0 {
		return min, -1 // Ind is -1 to make clear it's not the zeroth index.
	}
	min = s[0]
	ind = 0
	for i, val := range s {
		if val < min {
			min = val
			ind = i
		}
	}
	return min, ind
}

// Norm returns the L norm of the slice S, defined as
// (sum_{i=1}^N s[i]^N)^{1/N}
// Special cases:
// L = math.Inf(1) gives the maximum value
// Does not correctly compute the zero norm
func Norm(s []float64, L float64) (norm float64) {
	// Should this complain if L is not positive?
	// Should this be done in log space for better numerical stability?
	//	would be more cost
	//	maybe only if L is high?
	if L == 2 {
		for _, val := range s {
			norm += val * val
		}
		return math.Pow(norm, 0.5)
	}
	if L == 1 {
		for _, val := range s {
			norm += math.Abs(val)
		}
		return norm
	}
	if math.IsInf(L, 1) {
		norm, _ = Max(s)
		return norm
	}
	for _, val := range s {
		norm += math.Pow(math.Abs(val), L)
	}
	return math.Pow(norm, 1/L)
}

// Prod returns the product of the elements of the slice
// Returns 1 if len(s) = 0
func Prod(s []float64) (prod float64) {
	prod = 1
	for _, val := range s {
		prod *= val
	}
	return prod
}

// Scale multiplies every element in s by c
func Scale(s []float64, c float64) {
	for i := range s {
		s[i] *= c
	}
}

// Span returns a set of N equally spaced points between l and u, where N
// is equal to the length of the destination. The first element of the destination
// is l, the final element of the destination is u.
// If len(dst) = 0, dst will be returned unchanged, and if len(dst) = 1, the
// only element of dst will become l
func Span(dst []float64, l, u float64) {
	n := len(dst)
	if n < 2 {
		if n == 0 {
			return
		}
		if n == 1 {
			dst[0] = l
			return
		}
	}
	step := (u - l) / float64(n-1)
	for i := range dst {
		dst[i] = l + step*float64(i)
	}
}

// Sub subtracts, element-wise, the first argument from the second. Assumes
// the lengths of s and t match (can be tested with EqLen)
func Sub(s, t []float64) {
	if len(s) != len(t) {
		panic("floats: length of the slices do not match")
	}
	for i, val := range t {
		s[i] -= val
	}
}

// SubDst subtracts, element-wise, the first argument from the second and
// store the result in destination. Assumes the lengths of s and t match
// (can be tested with EqLen)
func SubDst(dst, s, t []float64) {
	if len(s) != len(t) {
		panic("floats: length of subtractor and subtractee do not match")
	}
	if len(dst) != len(s) {
		panic("floats: length of destination does not match length of subtractor")
	}
	for i, val := range t {
		dst[i] = s[i] - val
	}
}

// Sum returns the sum of the elements of the slice
func Sum(s []float64) (sum float64) {
	for _, val := range s {
		sum += val
	}
	return
}
<commit_msg>Changed generators to return the slice and to accept nil arguments<commit_after>package floats

import "math"

// InsufficientElements is an error type used by FindFirst
type InsufficientElements struct{}

// Error makes InsufficientElements satisfy the error interface
func (i *InsufficientElements) Error() string {
	return "floats: insufficient elements found"
}

// Add returns the element-wise sum of all the slices with the
// results stored in the first slice.
// For computational efficiency, it is assumed that all of
// the variadic arguments have the same length. If this is
// in doubt, EqLen can be called first.
func Add(dst []float64, slices ...[]float64) []float64 {
	if len(slices) == 0 {
		return nil
	}
	if len(dst) != len(slices[0]) {
		if dst == nil {
			dst = make([]float64, len(slices[0]))
		} else {
			panic("floats: length of destination does not match length of the slices")
		}
	}
	for _, slice := range slices {
		for j, val := range slice {
			dst[j] += val
		}
	}
	return dst
}

// AddConst adds a constant to all of the values in s
func AddConst(s []float64, c float64) {
	for i := range s {
		s[i] += c
	}
}

// ApplyFunc applies a function (math.Exp, math.Sin, etc.) to every element
// of the slice
func Apply(s []float64, f func(float64) float64) {
	for i, val := range s {
		s[i] = f(val)
	}
}

// Cumprod finds the cumulative product of the first i elements in
// s and puts them in place into the ith element of the
// destination. Panic will occur if lengths of do not match
func CumProd(dst, s []float64) []float64 {
	if len(dst) != len(s) {
		if dst == nil {
			dst = make([]float64, len(s))
		} else {
			panic("floats: length of destination does not match length of the source")
		}
	}
	dst[0] = s[0]
	for i := 1; i < len(s); i++ {
		dst[i] = dst[i-1] * s[i]
	}
	return dst
}

// Cumsum finds the cumulative sum of the first i elements in
// s and puts them in place into the ith element of the
// destination. Panic will occur if lengths of arguments do not match
func CumSum(dst, s []float64) []float64 {
	if len(dst) != len(s) {
		if dst == nil {
			dst = make([]float64, len(s))
		} else {
			panic("floats: length of destination does not match length of the source")
		}
	}
	dst[0] = s[0]
	for i := 1; i < len(s); i++ {
		dst[i] = dst[i-1] + s[i]
	}
	return dst
}

// Dot computes the dot product of s1 and s2, i.e.
// sum_{i = 1}^N s1[n]*s2[n]
// Panic will occur if lengths of arguments do not match
func Dot(s1, s2 []float64) float64 {
	if len(s1) != len(s2) {
		panic("floats: lengths of the slices do not match")
	}
	var sum float64
	for i, val := range s1 {
		sum += val * s2[i]
	}
	return sum
}

// Eq returns false if the slices have different lengths
// or if |s1[i] - s2[i]| > tol for any i.
func Eq(s1, s2 []float64, tol float64) bool {
	if len(s1) != len(s2) {
		return false
	}
	for i, val := range s1 {
		if math.Abs(s2[i]-val) > tol {
			return false
		}
	}
	return true
}

// Eqlen returns true if all of the slices have equal length,
// and false otherwise. Returns true if there are no input slices
func EqLen(slices ...[]float64) bool {
	// This length check is needed: http://play.golang.org/p/sdty6YiLhM
	if len(slices) == 0 {
		return true
	}
	l := len(slices[0])
	for i := 1; i < len(slices); i++ {
		if len(slices[i]) != l {
			return false
		}
	}
	return true
}

// Find finds the first k indices of  s for which
// the function f returns true and stores them in
// inds. If k < 0, all such elements are found.
// Find will reslice inds to have 0 length, and will append
// found indices to inds.
// If k > 0 and there are fewer than k elements in s satisfying f,
// all of the found elements will be returned along with an
// InsufficientElements error
func Find(inds []int, k int, s []float64, f func(float64) bool) ([]int, error) {

	// inds is also returned to allow for calling with nil

	// Reslice inds to have zero length
	inds = inds[:0]

	// If zero elements requested, can just return
	if k == 0 {
		return inds, nil
	}

	// If k < 0, return all of the found indices
	if k < 0 {
		for i, val := range s {
			if f(val) {
				inds = append(inds, i)
			}
		}
		return inds, nil
	}

	// Otherwise, find the first k elements
	nFound := 0
	for i, val := range s {
		if f(val) {
			inds = append(inds, i)
			nFound++
			if nFound == k {
				return inds, nil
			}
		}
	}
	// Finished iterating over the loop, which means k elements were not found
	return inds, &InsufficientElements{}
}

// LogSpan returns a set of N equally spaced points in log space between l and u,
// where N is equal to the len(dst). The first element of the
// resulting dst will be l and the final element of dst will be u.
// If len(dst) = 0, dst will be returned unchanged, and if len(dst) = 1, the
// only element of dst will become l
// Note that this call will return NaNs if either l or u are negative, and
// will return all zeros if l or u is zero.
func LogSpan(dst []float64, l, u float64) []float64 {
	Span(dst, math.Log(l), math.Log(u))
	Apply(dst, math.Exp)
	return dst
}

// Logsumexp returns the log of the sum of the exponentials of the values in s
func LogSumExp(s []float64) (lse float64) {
	// Want to do this in a numerically stable way which avoids
	// overflow and underflow
	// First, find the maximum value in the slice.
	maxval, _ := Max(s)
	if math.IsInf(maxval, 0) {
		// If it's infinity either way, the logsumexp will be infinity as well
		// returning now avoids NaNs
		return maxval
	}
	// Compute the sumexp part
	for _, val := range s {
		lse += math.Exp(val - maxval)
	}
	// Take the log and add back on the constant taken out
	lse = math.Log(lse) + maxval
	return lse
}

// Max returns the maximum value in the slice and the location of
// the maximum value. If the input slice is empty, zero is returned
// as the minimum value and -1 is returned as the index.
func Max(s []float64) (max float64, ind int) {
	if len(s) == 0 {
		return max, -1 // Ind is -1 to make clear it's not the zeroth index.
	}
	max = s[0]
	ind = 0
	for i, val := range s {
		if val > max {
			max = val
			ind = i
		}
	}
	return max, ind
}

// Min returns the minimum value in the slice and the index of
// the minimum value. If the input slice is empty, zero is returned
// as the minimum value and -1 is returned as the index.
func Min(s []float64) (min float64, ind int) {
	if len(s) == 0 {
		return min, -1 // Ind is -1 to make clear it's not the zeroth index.
	}
	min = s[0]
	ind = 0
	for i, val := range s {
		if val < min {
			min = val
			ind = i
		}
	}
	return min, ind
}

// Norm returns the L norm of the slice S, defined as
// (sum_{i=1}^N s[i]^N)^{1/N}
// Special cases:
// L = math.Inf(1) gives the maximum value
// Does not correctly compute the zero norm
func Norm(s []float64, L float64) (norm float64) {
	// Should this complain if L is not positive?
	// Should this be done in log space for better numerical stability?
	//	would be more cost
	//	maybe only if L is high?
	if L == 2 {
		for _, val := range s {
			norm += val * val
		}
		return math.Pow(norm, 0.5)
	}
	if L == 1 {
		for _, val := range s {
			norm += math.Abs(val)
		}
		return norm
	}
	if math.IsInf(L, 1) {
		norm, _ = Max(s)
		return norm
	}
	for _, val := range s {
		norm += math.Pow(math.Abs(val), L)
	}
	return math.Pow(norm, 1/L)
}

// Prod returns the product of the elements of the slice
// Returns 1 if len(s) = 0
func Prod(s []float64) (prod float64) {
	prod = 1
	for _, val := range s {
		prod *= val
	}
	return prod
}

// Scale multiplies every element in s by c
func Scale(s []float64, c float64) {
	for i := range s {
		s[i] *= c
	}
}

// Span returns a set of N equally spaced points between l and u, where N
// is equal to the length of the destination. The first element of the destination
// is l, the final element of the destination is u.
// If len(dst) = 0, dst will be returned unchanged, and if len(dst) = 1, the
// only element of dst will become l
func Span(dst []float64, l, u float64) []float64 {
	n := len(dst)
	if n < 2 {
		if n == 0 {
			return nil
		}
		if n == 1 {
			dst[0] = l
			return nil
		}
	}
	step := (u - l) / float64(n-1)
	for i := range dst {
		dst[i] = l + step*float64(i)
	}
	return dst
}

// Sub subtracts, element-wise, the first argument from the second. Assumes
// the lengths of s and t match (can be tested with EqLen)
func Sub(s, t []float64) {
	if len(s) != len(t) {
		panic("floats: length of the slices do not match")
	}
	for i, val := range t {
		s[i] -= val
	}
}

// SubDst subtracts, element-wise, the first argument from the second and
// store the result in destination. Assumes the lengths of s and t match
// (can be tested with EqLen)
func SubDst(dst, s, t []float64) []float64 {
	if len(s) != len(t) {
		panic("floats: length of subtractor and subtractee do not match")
	}
	if len(dst) != len(s) {
		if dst == nil {
			dst = make([]float64, len(s))
		} else {
			panic("floats: length of destination does not match length of subtractor")
		}
	}
	for i, val := range t {
		dst[i] = s[i] - val
	}
	return dst
}

// Sum returns the sum of the elements of the slice
func Sum(s []float64) (sum float64) {
	for _, val := range s {
		sum += val
	}
	return
}
<|endoftext|>


<commit_before>package pb

import (
	"fmt"
	"strings"
	"time"
)

type Units int

const (
	// U_NO are default units, they represent a simple value and are not formatted at all.
	U_NO Units = iota
	// U_BYTES units are formatted in a human readable way (b, Bb, Mb, ...)
	U_BYTES
	// U_DURATION units are formatted in a human readable way (3h14m15s)
	U_DURATION
)

func Format(i int64) *formatter {
	return &formatter{n: i}
}

type formatter struct {
	n      int64
	unit   Units
	width  int
	perSec bool
}

func (f *formatter) Value(n int64) *formatter {
	f.n = n
	return f
}

func (f *formatter) To(unit Units) *formatter {
	f.unit = unit
	return f
}

func (f *formatter) Width(width int) *formatter {
	f.width = width
	return f
}

func (f *formatter) PerSec() *formatter {
	f.perSec = true
	return f
}

func (f *formatter) String() (out string) {
	switch f.unit {
	case U_BYTES:
		return formatBytes(f.n)
	case U_DURATION:
		d := time.Duration(f.n)
		if d > time.Hour*24 {
			out = fmt.Sprintf("%dd", d/24/time.Hour)
			d -= (d / time.Hour / 24) * (time.Hour * 24)
		}
		out = fmt.Sprintf("%s%v", out, d)
	default:
		out = fmt.Sprintf(fmt.Sprintf("%%%dd", f.width), f.n)
	}
	if f.perSec {
		out += "/s"
	}
	return
}

// Convert bytes to human readable string. Like a 2 MB, 64.2 KB, 52 B
func formatBytes(i int64) (result string) {
	switch {
	case i > (1024 * 1024 * 1024 * 1024):
		result = fmt.Sprintf("%.02f TB", float64(i)/1024/1024/1024/1024)
	case i > (1024 * 1024 * 1024):
		result = fmt.Sprintf("%.02f GB", float64(i)/1024/1024/1024)
	case i > (1024 * 1024):
		result = fmt.Sprintf("%.02f MB", float64(i)/1024/1024)
	case i > 1024:
		result = fmt.Sprintf("%.02f KB", float64(i)/1024)
	default:
		result = fmt.Sprintf("%d B", i)
	}
	result = strings.Trim(result, " ")
	return
}
<commit_msg>fix formatter Bytes per second<commit_after>package pb

import (
	"fmt"
	"strings"
	"time"
)

type Units int

const (
	// U_NO are default units, they represent a simple value and are not formatted at all.
	U_NO Units = iota
	// U_BYTES units are formatted in a human readable way (b, Bb, Mb, ...)
	U_BYTES
	// U_DURATION units are formatted in a human readable way (3h14m15s)
	U_DURATION
)

func Format(i int64) *formatter {
	return &formatter{n: i}
}

type formatter struct {
	n      int64
	unit   Units
	width  int
	perSec bool
}

func (f *formatter) Value(n int64) *formatter {
	f.n = n
	return f
}

func (f *formatter) To(unit Units) *formatter {
	f.unit = unit
	return f
}

func (f *formatter) Width(width int) *formatter {
	f.width = width
	return f
}

func (f *formatter) PerSec() *formatter {
	f.perSec = true
	return f
}

func (f *formatter) String() (out string) {
	switch f.unit {
	case U_BYTES:
		out = formatBytes(f.n)
	case U_DURATION:
		d := time.Duration(f.n)
		if d > time.Hour*24 {
			out = fmt.Sprintf("%dd", d/24/time.Hour)
			d -= (d / time.Hour / 24) * (time.Hour * 24)
		}
		out = fmt.Sprintf("%s%v", out, d)
	default:
		out = fmt.Sprintf(fmt.Sprintf("%%%dd", f.width), f.n)
	}
	if f.perSec {
		out += "/s"
	}
	return
}

// Convert bytes to human readable string. Like a 2 MB, 64.2 KB, 52 B
func formatBytes(i int64) (result string) {
	switch {
	case i > (1024 * 1024 * 1024 * 1024):
		result = fmt.Sprintf("%.02f TB", float64(i)/1024/1024/1024/1024)
	case i > (1024 * 1024 * 1024):
		result = fmt.Sprintf("%.02f GB", float64(i)/1024/1024/1024)
	case i > (1024 * 1024):
		result = fmt.Sprintf("%.02f MB", float64(i)/1024/1024)
	case i > 1024:
		result = fmt.Sprintf("%.02f KB", float64(i)/1024)
	default:
		result = fmt.Sprintf("%d B", i)
	}
	result = strings.Trim(result, " ")
	return
}
<|endoftext|>


<commit_before>package color

import (
	"fmt"
)

// Format represents a format string with the highlight verbs fully parsed.
type Format struct {
	colored  string // highlight verbs replaced with their escape sequences
	stripped string // highlight verbs stripped
}

// Get returns the colored string if color is true, and the stripped string otherwise.
func (f *Format) Get(color bool) string {
	if color {
		return f.colored
	}
	return f.stripped
}

// Append appends f2's strings to f's and returns the resulting Format.
func (f *Format) Append(f2 *Format) *Format {
	return &Format{f.colored + f2.colored, f.stripped + f2.stripped}
}

// Eprintf printfs the arguments into f and returns the resulting Format.
func (f *Format) Eprintf(a ...interface{}) *Format {
	return &Format{fmt.Sprintf(f.colored, a...), fmt.Sprintf(f.stripped, a...)}
}

// Eprintfp printfs f2 into f and returns the resulting Format.
func (f *Format) Eprintfp(f2 *Format) *Format {
	return &Format{fmt.Sprintf(f.colored, f2.colored), fmt.Sprintf(f.stripped, f2.stripped)}
}

// Prepare returns a Format structure using f as the base string.
func Prepare(f string) *Format {
	return &Format{Highlight(f), Strip(f)}
}
<commit_msg>small fix<commit_after>package color

import (
	"fmt"
)

// Format represents a format string with the highlight verbs fully parsed.
type Format struct {
	colored  string // highlight verbs replaced with their escape sequences
	stripped string // highlight verbs stripped
}

// Get returns the colored string if color is true, and the stripped string otherwise.
func (f *Format) Get(color bool) string {
	if color {
		return f.colored
	}
	return f.stripped
}

// Append appends f2 to f and returns the resulting Format.
func (f *Format) Append(f2 *Format) *Format {
	return &Format{f.colored + f2.colored, f.stripped + f2.stripped}
}

// Eprintf printfs the arguments into f and returns the resulting Format.
func (f *Format) Eprintf(a ...interface{}) *Format {
	return &Format{fmt.Sprintf(f.colored, a...), fmt.Sprintf(f.stripped, a...)}
}

// Eprintfp printfs f2 into f and returns the resulting Format.
func (f *Format) Eprintfp(f2 *Format) *Format {
	return &Format{fmt.Sprintf(f.colored, f2.colored), fmt.Sprintf(f.stripped, f2.stripped)}
}

// Prepare returns a Format structure using f as the base string.
func Prepare(f string) *Format {
	return &Format{Highlight(f), Strip(f)}
}
<|endoftext|>


<commit_before>package influxdb

import (
	"fmt"
	bulkQuerygen "github.com/influxdata/influxdb-comparisons/bulk_query_gen"
	"math/rand"
	"strings"
	"time"
)

// InfluxDevops produces Influx-specific queries for all the devops query types.
type InfluxDevops struct {
	InfluxCommon
	AllInterval  bulkQuerygen.TimeInterval
}

// NewInfluxDevops makes an InfluxDevops object ready to generate Queries.
func newInfluxDevopsCommon(lang Language, dbConfig bulkQuerygen.DatabaseConfig, start, end time.Time) bulkQuerygen.QueryGenerator {
	if !start.Before(end) {
		panic("bad time order")
	}
	if _, ok := dbConfig["database-name"]; !ok {
		panic("need influx database name")
	}

	return &InfluxDevops{
		InfluxCommon: *newInfluxCommon(lang, dbConfig["database-bname"]),
		AllInterval:  bulkQuerygen.NewTimeInterval(start, end),
	}
}

// Dispatch fulfills the QueryGenerator interface.
func (d *InfluxDevops) Dispatch(i, scaleVar int) bulkQuerygen.Query {
	q := bulkQuerygen.NewHTTPQuery() // from pool
	bulkQuerygen.DevopsDispatchAll(d, i, q, scaleVar)
	return q
}

func (d *InfluxDevops) MaxCPUUsageHourByMinuteOneHost(q bulkQuerygen.Query, scaleVar int) {
	d.maxCPUUsageHourByMinuteNHosts(q.(*bulkQuerygen.HTTPQuery), scaleVar, 1, time.Hour)
}

func (d *InfluxDevops) MaxCPUUsageHourByMinuteTwoHosts(q bulkQuerygen.Query, scaleVar int) {
	d.maxCPUUsageHourByMinuteNHosts(q.(*bulkQuerygen.HTTPQuery), scaleVar, 2, time.Hour)
}

func (d *InfluxDevops) MaxCPUUsageHourByMinuteFourHosts(q bulkQuerygen.Query, scaleVar int) {
	d.maxCPUUsageHourByMinuteNHosts(q.(*bulkQuerygen.HTTPQuery), scaleVar, 4, time.Hour)
}

func (d *InfluxDevops) MaxCPUUsageHourByMinuteEightHosts(q bulkQuerygen.Query, scaleVar int) {
	d.maxCPUUsageHourByMinuteNHosts(q.(*bulkQuerygen.HTTPQuery), scaleVar, 8, time.Hour)
}

func (d *InfluxDevops) MaxCPUUsageHourByMinuteSixteenHosts(q bulkQuerygen.Query, scaleVar int) {
	d.maxCPUUsageHourByMinuteNHosts(q.(*bulkQuerygen.HTTPQuery), scaleVar, 16, time.Hour)
}

func (d *InfluxDevops) MaxCPUUsageHourByMinuteThirtyTwoHosts(q bulkQuerygen.Query, scaleVar int) {
	d.maxCPUUsageHourByMinuteNHosts(q.(*bulkQuerygen.HTTPQuery), scaleVar, 32, time.Hour)
}

func (d *InfluxDevops) MaxCPUUsage12HoursByMinuteOneHost(q bulkQuerygen.Query, scaleVar int) {
	d.maxCPUUsageHourByMinuteNHosts(q.(*bulkQuerygen.HTTPQuery), scaleVar, 1, 12*time.Hour)
}

// MaxCPUUsageHourByMinuteThirtyTwoHosts populates a Query with a query that looks like:
// SELECT max(usage_user) from cpu where (hostname = '$HOSTNAME_1' or ... or hostname = '$HOSTNAME_N') and time >= '$HOUR_START' and time < '$HOUR_END' group by time(1m)
func (d *InfluxDevops) maxCPUUsageHourByMinuteNHosts(qi bulkQuerygen.Query, scaleVar, nhosts int, timeRange time.Duration) {
	interval := d.AllInterval.RandWindow(timeRange)
	nn := rand.Perm(scaleVar)[:nhosts]

	hostnames := []string{}
	for _, n := range nn {
		hostnames = append(hostnames, fmt.Sprintf("host_%d", n))
	}

	hostnameClauses := []string{}
	for _, s := range hostnames {
		if d.language == InfluxQL {
			hostnameClauses = append(hostnameClauses, fmt.Sprintf("hostname = '%s'", s))
		} else {
			hostnameClauses = append(hostnameClauses, fmt.Sprintf(`r.hostname == "%s"`, s))
		}
	}

	combinedHostnameClause := strings.Join(hostnameClauses, " or ")

	var query string
	if d.language == InfluxQL {
		query = fmt.Sprintf("SELECT max(usage_user) from cpu where (%s) and time >= '%s' and time < '%s' group by time(1m)", combinedHostnameClause, interval.StartString(), interval.EndString())
	} else { // Flux
		query = fmt.Sprintf(`from(db:"%s") ` +
			`|> range(start:%s, stop:%s) ` +
			`|> filter(fn:(r) => r._measurement == "cpu" and r._field == "usage_user" and (%s)) ` +
			`|> keep(columns:["_start", "_stop", "_time", "_value"]) ` +
			`|> window(period:1m) ` +
			`|> max() ` +
			`|> yield()`,
			d.DatabaseName,
			interval.StartString(), interval.EndString(),
			combinedHostnameClause)
	}

	humanLabel := fmt.Sprintf("InfluxDB (%s) max cpu, rand %4d hosts, rand %s by 1m", d.language.String(), nhosts, timeRange)

	q := qi.(*bulkQuerygen.HTTPQuery)
	d.getHttpQuery(humanLabel, interval.StartString(), query, q)
}

// MeanCPUUsageDayByHourAllHosts populates a Query with a query that looks like:
// SELECT mean(usage_user) from cpu where time >= '$DAY_START' and time < '$DAY_END' group by time(1h),hostname
func (d *InfluxDevops) MeanCPUUsageDayByHourAllHostsGroupbyHost(qi bulkQuerygen.Query, _ int) {
	interval := d.AllInterval.RandWindow(24 * time.Hour)

	var query string
	if d.language == InfluxQL {
		query = fmt.Sprintf("SELECT mean(usage_user) from cpu where time >= '%s' and time < '%s' group by time(1h),hostname", interval.StartString(), interval.EndString())
	} else {
		query = fmt.Sprintf(`from(db:"%s") ` +
			`|> range(start:%s, stop:%s) ` +
			`|> filter(fn:(r) => r._measurement == "cpu" and r._field == "usage_user") ` +
			`|> window(every:1h) ` +
			`|> mean() ` +
			`|> group(by:["hostname"]) ` +
			`|> keep(columns:["_start", "hostname", "_value"]) ` +
			`|> yield()`,
			d.DatabaseName,
			interval.StartString(), interval.EndString())
	}

	humanLabel := fmt.Sprintf("InfluxDB (%s) mean cpu, all hosts, rand 1day by 1hour", d.language.String())
	q := qi.(*bulkQuerygen.HTTPQuery)
	d.getHttpQuery(humanLabel, interval.StartString(), query, q)
}

//func (d *InfluxDevops) MeanCPUUsageDayByHourAllHostsGroupbyHost(qi Query, _ int) {
//	interval := d.AllInterval.RandWindow(24*time.Hour)
//
//	v := url.Values{}
//	v.Set("db", d.DatabaseName)
//	v.Set("q", fmt.Sprintf("SELECT count(usage_user) from cpu where time >= '%s' and time < '%s' group by time(1h)", interval.StartString(), interval.EndString()))
//
//	humanLabel := "Influx mean cpu, all hosts, rand 1day by 1hour"
//	q := qi.(*bulkQuerygen.HTTPQuery)
//	q.HumanLabel = []byte(humanLabel)
//	q.HumanDescription = []byte(fmt.Sprintf("%s: %s", humanLabel, interval.StartString()))
//	q.Method = []byte("GET")
//	q.Path = []byte(fmt.Sprintf("/query?%s", v.Encode()))
//	q.Body = nil
//}
<commit_msg>Fix typo<commit_after>package influxdb

import (
	"fmt"
	bulkQuerygen "github.com/influxdata/influxdb-comparisons/bulk_query_gen"
	"math/rand"
	"strings"
	"time"
)

// InfluxDevops produces Influx-specific queries for all the devops query types.
type InfluxDevops struct {
	InfluxCommon
	AllInterval  bulkQuerygen.TimeInterval
}

// NewInfluxDevops makes an InfluxDevops object ready to generate Queries.
func newInfluxDevopsCommon(lang Language, dbConfig bulkQuerygen.DatabaseConfig, start, end time.Time) bulkQuerygen.QueryGenerator {
	if !start.Before(end) {
		panic("bad time order")
	}
	if _, ok := dbConfig["database-name"]; !ok {
		panic("need influx database name")
	}

	return &InfluxDevops{
		InfluxCommon: *newInfluxCommon(lang, dbConfig["database-name"]),
		AllInterval:  bulkQuerygen.NewTimeInterval(start, end),
	}
}

// Dispatch fulfills the QueryGenerator interface.
func (d *InfluxDevops) Dispatch(i, scaleVar int) bulkQuerygen.Query {
	q := bulkQuerygen.NewHTTPQuery() // from pool
	bulkQuerygen.DevopsDispatchAll(d, i, q, scaleVar)
	return q
}

func (d *InfluxDevops) MaxCPUUsageHourByMinuteOneHost(q bulkQuerygen.Query, scaleVar int) {
	d.maxCPUUsageHourByMinuteNHosts(q.(*bulkQuerygen.HTTPQuery), scaleVar, 1, time.Hour)
}

func (d *InfluxDevops) MaxCPUUsageHourByMinuteTwoHosts(q bulkQuerygen.Query, scaleVar int) {
	d.maxCPUUsageHourByMinuteNHosts(q.(*bulkQuerygen.HTTPQuery), scaleVar, 2, time.Hour)
}

func (d *InfluxDevops) MaxCPUUsageHourByMinuteFourHosts(q bulkQuerygen.Query, scaleVar int) {
	d.maxCPUUsageHourByMinuteNHosts(q.(*bulkQuerygen.HTTPQuery), scaleVar, 4, time.Hour)
}

func (d *InfluxDevops) MaxCPUUsageHourByMinuteEightHosts(q bulkQuerygen.Query, scaleVar int) {
	d.maxCPUUsageHourByMinuteNHosts(q.(*bulkQuerygen.HTTPQuery), scaleVar, 8, time.Hour)
}

func (d *InfluxDevops) MaxCPUUsageHourByMinuteSixteenHosts(q bulkQuerygen.Query, scaleVar int) {
	d.maxCPUUsageHourByMinuteNHosts(q.(*bulkQuerygen.HTTPQuery), scaleVar, 16, time.Hour)
}

func (d *InfluxDevops) MaxCPUUsageHourByMinuteThirtyTwoHosts(q bulkQuerygen.Query, scaleVar int) {
	d.maxCPUUsageHourByMinuteNHosts(q.(*bulkQuerygen.HTTPQuery), scaleVar, 32, time.Hour)
}

func (d *InfluxDevops) MaxCPUUsage12HoursByMinuteOneHost(q bulkQuerygen.Query, scaleVar int) {
	d.maxCPUUsageHourByMinuteNHosts(q.(*bulkQuerygen.HTTPQuery), scaleVar, 1, 12*time.Hour)
}

// MaxCPUUsageHourByMinuteThirtyTwoHosts populates a Query with a query that looks like:
// SELECT max(usage_user) from cpu where (hostname = '$HOSTNAME_1' or ... or hostname = '$HOSTNAME_N') and time >= '$HOUR_START' and time < '$HOUR_END' group by time(1m)
func (d *InfluxDevops) maxCPUUsageHourByMinuteNHosts(qi bulkQuerygen.Query, scaleVar, nhosts int, timeRange time.Duration) {
	interval := d.AllInterval.RandWindow(timeRange)
	nn := rand.Perm(scaleVar)[:nhosts]

	hostnames := []string{}
	for _, n := range nn {
		hostnames = append(hostnames, fmt.Sprintf("host_%d", n))
	}

	hostnameClauses := []string{}
	for _, s := range hostnames {
		if d.language == InfluxQL {
			hostnameClauses = append(hostnameClauses, fmt.Sprintf("hostname = '%s'", s))
		} else {
			hostnameClauses = append(hostnameClauses, fmt.Sprintf(`r.hostname == "%s"`, s))
		}
	}

	combinedHostnameClause := strings.Join(hostnameClauses, " or ")

	var query string
	if d.language == InfluxQL {
		query = fmt.Sprintf("SELECT max(usage_user) from cpu where (%s) and time >= '%s' and time < '%s' group by time(1m)", combinedHostnameClause, interval.StartString(), interval.EndString())
	} else { // Flux
		query = fmt.Sprintf(`from(db:"%s") ` +
			`|> range(start:%s, stop:%s) ` +
			`|> filter(fn:(r) => r._measurement == "cpu" and r._field == "usage_user" and (%s)) ` +
			`|> keep(columns:["_start", "_stop", "_time", "_value"]) ` +
			`|> window(period:1m) ` +
			`|> max() ` +
			`|> yield()`,
			d.DatabaseName,
			interval.StartString(), interval.EndString(),
			combinedHostnameClause)
	}

	humanLabel := fmt.Sprintf("InfluxDB (%s) max cpu, rand %4d hosts, rand %s by 1m", d.language.String(), nhosts, timeRange)

	q := qi.(*bulkQuerygen.HTTPQuery)
	d.getHttpQuery(humanLabel, interval.StartString(), query, q)
}

// MeanCPUUsageDayByHourAllHosts populates a Query with a query that looks like:
// SELECT mean(usage_user) from cpu where time >= '$DAY_START' and time < '$DAY_END' group by time(1h),hostname
func (d *InfluxDevops) MeanCPUUsageDayByHourAllHostsGroupbyHost(qi bulkQuerygen.Query, _ int) {
	interval := d.AllInterval.RandWindow(24 * time.Hour)

	var query string
	if d.language == InfluxQL {
		query = fmt.Sprintf("SELECT mean(usage_user) from cpu where time >= '%s' and time < '%s' group by time(1h),hostname", interval.StartString(), interval.EndString())
	} else {
		query = fmt.Sprintf(`from(db:"%s") ` +
			`|> range(start:%s, stop:%s) ` +
			`|> filter(fn:(r) => r._measurement == "cpu" and r._field == "usage_user") ` +
			`|> window(every:1h) ` +
			`|> mean() ` +
			`|> group(by:["hostname"]) ` +
			`|> keep(columns:["_start", "hostname", "_value"]) ` +
			`|> yield()`,
			d.DatabaseName,
			interval.StartString(), interval.EndString())
	}

	humanLabel := fmt.Sprintf("InfluxDB (%s) mean cpu, all hosts, rand 1day by 1hour", d.language.String())
	q := qi.(*bulkQuerygen.HTTPQuery)
	d.getHttpQuery(humanLabel, interval.StartString(), query, q)
}

//func (d *InfluxDevops) MeanCPUUsageDayByHourAllHostsGroupbyHost(qi Query, _ int) {
//	interval := d.AllInterval.RandWindow(24*time.Hour)
//
//	v := url.Values{}
//	v.Set("db", d.DatabaseName)
//	v.Set("q", fmt.Sprintf("SELECT count(usage_user) from cpu where time >= '%s' and time < '%s' group by time(1h)", interval.StartString(), interval.EndString()))
//
//	humanLabel := "Influx mean cpu, all hosts, rand 1day by 1hour"
//	q := qi.(*bulkQuerygen.HTTPQuery)
//	q.HumanLabel = []byte(humanLabel)
//	q.HumanDescription = []byte(fmt.Sprintf("%s: %s", humanLabel, interval.StartString()))
//	q.Method = []byte("GET")
//	q.Path = []byte(fmt.Sprintf("/query?%s", v.Encode()))
//	q.Body = nil
//}
<|endoftext|>


<commit_before>package tests_test

import (
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"kubevirt.io/kubevirt/tests/util"

	"kubevirt.io/client-go/kubecli"
	"kubevirt.io/kubevirt/tests"
	cd "kubevirt.io/kubevirt/tests/containerdisk"
)

var _ = PDescribe("Ensure stable functionality", func() {

	var err error
	var virtClient kubecli.KubevirtClient

	BeforeEach(func() {
		virtClient, err = kubecli.GetKubevirtClient()
		util.PanicOnError(err)

		tests.BeforeTestCleanup()
	})

	Measure("by repeately starting vmis many times without issues", func(b Benchmarker) {
		b.Time("from_start_to_ready", func() {
			vmi := tests.NewRandomVMIWithEphemeralDiskAndUserdata(cd.ContainerDiskFor(cd.ContainerDiskCirros), "#!/bin/bash\necho 'hello'\n")
			vmi, err := virtClient.VirtualMachineInstance(util.NamespaceTestDefault).Create(vmi)
			Expect(err).To(BeNil(), "Create VMI successfully")
			tests.WaitForSuccessfulVMIStart(vmi)
		})
	}, 15)
})
<commit_msg>stability_test: simplify<commit_after>package tests_test

import (
	. "github.com/onsi/ginkgo"

	"kubevirt.io/kubevirt/tests"
	"kubevirt.io/kubevirt/tests/libvmi"
)

// Replace PDescribe with FDescribe in order to measure if your changes made
// VMI startup any worse
var _ = PDescribe("Ensure stable functionality", func() {

	BeforeEach(func() {
		tests.BeforeTestCleanup()
	})

	Measure("by repeately starting vmis many times without issues", func(b Benchmarker) {
		b.Time("from_start_to_ready", func() {
			tests.RunVMIAndExpectLaunch(libvmi.NewCirros(), 30)
		})
	}, 15)
})
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/julienschmidt/httprouter"
)

func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	fmt.Fprint(w, "Welcome!\n")
}

func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name"))
	fmt.Fprintf(w, "hello, %v\n", ps)
	fmt.Fprintf(w, "%v\n", r)
}

func handler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	fmt.Fprintf(w, "%s; %s; %s\n", r.Method, r.URL, r.Proto)
	fmt.Fprintf(w, "Host = %q\n", r.Host)
	fmt.Fprintf(w, "RemoteAddr = %q\n", r.RemoteAddr)

	for k, v := range r.Header {
		fmt.Fprintf(w, "Header[%q] = %q\n", k, v)
	}

	if err := r.ParseForm(); err != nil {
		log.Print(err)
	}
	for k, v := range r.Form {
		fmt.Fprintf(w, "Form[%q] = %q\n", k, v)
	}
	fmt.Fprintf(w, "Params: %v\n", ps)

	content, err := ioutil.ReadAll(r.Body)
	if err != nil {
		log.Fatal(err)
	}
	defer r.Body.Close()
	fmt.Fprintf(w, "body: %s\n", content)
}

func main() {
	router := httprouter.New()
	router.GET("/", Index)
	router.GET("/hello/:name", Hello)
	router.GET("/handler", handler)
	router.POST("/handler", handler)

	log.Fatal(http.ListenAndServe(":8080", router))
}
<commit_msg>parse http post body<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"net/http"

	"github.com/julienschmidt/httprouter"
)

func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
	fmt.Fprint(w, "Welcome!\n")
}

func Hello(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	fmt.Fprintf(w, "hello, %s!\n", ps.ByName("name"))
	fmt.Fprintf(w, "hello, %v\n", ps)
	fmt.Fprintf(w, "%v\n", r)
}

func handler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
	fmt.Fprintf(w, "%s; %s; %s\n", r.Method, r.URL, r.Proto)
	fmt.Fprintf(w, "Host = %q\n", r.Host)
	fmt.Fprintf(w, "RemoteAddr = %q\n", r.RemoteAddr)

	for k, v := range r.Header {
		fmt.Fprintf(w, "Header[%q] = %q\n", k, v)
	}

	if err := r.ParseForm(); err != nil {
		log.Print(err)
	}
	for k, v := range r.Form {
		fmt.Fprintf(w, "Form[%q] = %q\n", k, v)
	}
	for k, v := range r.PostForm {
		fmt.Fprintf(w, "PostForm[%q] = %q\n", k, v)
	}

	fmt.Fprintf(w, "Params: %v\n", ps)

	content, err := ioutil.ReadAll(r.Body)
	defer r.Body.Close()
	if err != nil {
		log.Fatal(err)
	}
	fmt.Fprintf(w, "body: %s\n", content)
}

func main() {
	router := httprouter.New()
	router.GET("/", Index)
	router.GET("/hello/:name", Hello)
	router.GET("/handler", handler)
	router.POST("/handler", handler)

	log.Fatal(http.ListenAndServe(":8080", router))
}
<|endoftext|>


<commit_before>package xsdvalidate

// Common String and Error implementations.
type errorMessage struct {
	Message string
}

// Implementation of the Stringer Interface.
func (e errorMessage) String() string {
	return e.Message
}

// Implementation of the Error Interface.
func (e errorMessage) Error() string {
	return e.String()
}

// Returned when initialization an initialization error occured.
type Libxml2Error struct {
	errorMessage
}

// Returned when xml parsing caused error(s).
type XmlParserError struct {
	errorMessage
}

// Returned when xsd parsing caused a error(s).
type XsdParserError struct {
	errorMessage
}

// Returned when validation caused an error, to access the fields use type assertion.
type ValidationError struct {
	Code     int
	Message  string
	Level    int
	Line     int
	NodeName string
}

// Implementation of the Stringer interface.
func (e ValidationError) String() string {
	return e.Message
}

// Implementation of the Error interface.
func (e ValidationError) Error() string {
	return e.String()
}
<commit_msg>Minor doc fix<commit_after>package xsdvalidate

// Common String and Error implementations.
type errorMessage struct {
	Message string
}

// Implementation of the Stringer Interface.
func (e errorMessage) String() string {
	return e.Message
}

// Implementation of the Error Interface.
func (e errorMessage) Error() string {
	return e.String()
}

// Returned when initialization an initialization error occured.
type Libxml2Error struct {
	errorMessage
}

// Returned when xml parsing caused error(s).
type XmlParserError struct {
	errorMessage
}

// Returned when xsd parsing caused a error(s).
type XsdParserError struct {
	errorMessage
}

// Returned when validation caused an error, to access the fields use type assertion (see example).
type ValidationError struct {
	Code     int
	Message  string
	Level    int
	Line     int
	NodeName string
}

// Implementation of the Stringer interface.
func (e ValidationError) String() string {
	return e.Message
}

// Implementation of the Error interface.
func (e ValidationError) Error() string {
	return e.String()
}
<|endoftext|>


<commit_before>package revel

import (
	"fmt"
	"path/filepath"
	"runtime/debug"
	"strconv"
	"strings"
)

// Error description, used as an argument to the error template.
type Error struct {
	SourceType               string   // The type of source that failed to build.
	Title, Path, Description string   // Description of the error, as presented to the user.
	Line, Column             int      // Where the error was encountered.
	SourceLines              []string // The entire source file, split into lines.
	Stack                    string   // The raw stack trace string from debug.Stack().
	MetaError                string   // Error that occurred producing the error page.
	Link                     string   // A configurable link to wrap the error source in
}

// An object to hold the per-source-line details.
type sourceLine struct {
	Source  string
	Line    int
	IsError bool
}

// NewErrorFromPanic method finds the deepest stack from in user code and
// provide a code listing of that, on the line that eventually triggered
// the panic.  Returns nil if no relevant stack frame can be found.
func NewErrorFromPanic(err interface{}) *Error {

	// Parse the filename and line from the originating line of app code.
	// /Users/robfig/code/gocode/src/revel/samples/booking/app/controllers/hotels.go:191 (0x44735)
	stack := string(debug.Stack())
	frame, basePath := findRelevantStackFrame(stack)
	if frame == -1 {
		return nil
	}

	stack = stack[frame:]
	stackElement := stack[:strings.Index(stack, "\n")]
	colonIndex := strings.LastIndex(stackElement, ":")
	filename := stackElement[:colonIndex]
	var line int
	fmt.Sscan(stackElement[colonIndex+1:], &line)

	// Show an error page.
	description := "Unspecified error"
	if err != nil {
		description = fmt.Sprint(err)
	}
	return &Error{
		Title:       "Runtime Panic",
		Path:        filename[len(basePath):],
		Line:        line,
		Description: description,
		SourceLines: MustReadLines(filename),
		Stack:       stack,
	}
}

// Error method constructs a plaintext version of the error, taking
// account that fields are optionally set. Returns e.g. Compilation Error
// (in views/header.html:51): expected right delim in end; got "}"
func (e *Error) Error() string {
	loc := ""
	if e.Path != "" {
		line := ""
		if e.Line != 0 {
			line = fmt.Sprintf(":%d", e.Line)
		}
		loc = fmt.Sprintf("(in %s%s)", e.Path, line)
	}
	header := loc
	if e.Title != "" {
		if loc != "" {
			header = fmt.Sprintf("%s %s: ", e.Title, loc)
		} else {
			header = fmt.Sprintf("%s: ", e.Title)
		}
	}
	return fmt.Sprintf("%s%s", header, e.Description)
}

// ContextSource method returns a snippet of the source around
// where the error occurred.
func (e *Error) ContextSource() []sourceLine {
	if e.SourceLines == nil {
		return nil
	}
	start := (e.Line - 1) - 5
	if start < 0 {
		start = 0
	}
	end := (e.Line - 1) + 5
	if end > len(e.SourceLines) {
		end = len(e.SourceLines)
	}

	var lines []sourceLine = make([]sourceLine, end-start)
	for i, src := range e.SourceLines[start:end] {
		fileLine := start + i + 1
		lines[i] = sourceLine{src, fileLine, fileLine == e.Line}
	}
	return lines
}

// SetLink method prepares a link and assign to Error.Link attribute
func (e *Error) SetLink(errorLink string) {
	errorLink = strings.Replace(errorLink, "{{Path}}", e.Path, -1)
	errorLink = strings.Replace(errorLink, "{{Line}}", strconv.Itoa(e.Line), -1)

	e.Link = "" + e.Path + ":" + strconv.Itoa(e.Line) + ""
}

// Return the character index of the first relevant stack frame, or -1 if none were found.
// Additionally it returns the base path of the tree in which the identified code resides.
func findRelevantStackFrame(stack string) (int, string) {
	if frame := strings.Index(stack, filepath.ToSlash(BasePath)); frame != -1 {
		return frame, BasePath
	}
	for _, module := range Modules {
		if frame := strings.Index(stack, filepath.ToSlash(module.Path)); frame != -1 {
			return frame, module.Path
		}
	}
	return -1, ""
}
<commit_msg>Instead of trimming stack traces to last frame of current project, include any other projects in src/ except for Revel<commit_after>package revel

import (
	"fmt"
	"path/filepath"
	"runtime/debug"
	"strconv"
	"strings"
)

// Error description, used as an argument to the error template.
type Error struct {
	SourceType               string   // The type of source that failed to build.
	Title, Path, Description string   // Description of the error, as presented to the user.
	Line, Column             int      // Where the error was encountered.
	SourceLines              []string // The entire source file, split into lines.
	Stack                    string   // The raw stack trace string from debug.Stack().
	MetaError                string   // Error that occurred producing the error page.
	Link                     string   // A configurable link to wrap the error source in
}

// An object to hold the per-source-line details.
type sourceLine struct {
	Source  string
	Line    int
	IsError bool
}

// NewErrorFromPanic method finds the deepest stack from in user code and
// provide a code listing of that, on the line that eventually triggered
// the panic.  Returns nil if no relevant stack frame can be found.
func NewErrorFromPanic(err interface{}) *Error {

	// Parse the filename and line from the originating line of app code.
	// /Users/robfig/code/gocode/src/revel/samples/booking/app/controllers/hotels.go:191 (0x44735)
	stack := string(debug.Stack())
	frame, basePath := findRelevantStackFrame(stack)
	if frame == -1 {
		return nil
	}

	stack = stack[frame:]
	stackElement := stack[:strings.Index(stack, "\n")]
	colonIndex := strings.LastIndex(stackElement, ":")
	filename := stackElement[:colonIndex]
	var line int
	fmt.Sscan(stackElement[colonIndex+1:], &line)

	// Show an error page.
	description := "Unspecified error"
	if err != nil {
		description = fmt.Sprint(err)
	}
	return &Error{
		Title:       "Runtime Panic",
		Path:        filename[len(basePath):],
		Line:        line,
		Description: description,
		SourceLines: MustReadLines(filename),
		Stack:       stack,
	}
}

// Error method constructs a plaintext version of the error, taking
// account that fields are optionally set. Returns e.g. Compilation Error
// (in views/header.html:51): expected right delim in end; got "}"
func (e *Error) Error() string {
	loc := ""
	if e.Path != "" {
		line := ""
		if e.Line != 0 {
			line = fmt.Sprintf(":%d", e.Line)
		}
		loc = fmt.Sprintf("(in %s%s)", e.Path, line)
	}
	header := loc
	if e.Title != "" {
		if loc != "" {
			header = fmt.Sprintf("%s %s: ", e.Title, loc)
		} else {
			header = fmt.Sprintf("%s: ", e.Title)
		}
	}
	return fmt.Sprintf("%s%s", header, e.Description)
}

// ContextSource method returns a snippet of the source around
// where the error occurred.
func (e *Error) ContextSource() []sourceLine {
	if e.SourceLines == nil {
		return nil
	}
	start := (e.Line - 1) - 5
	if start < 0 {
		start = 0
	}
	end := (e.Line - 1) + 5
	if end > len(e.SourceLines) {
		end = len(e.SourceLines)
	}

	var lines []sourceLine = make([]sourceLine, end-start)
	for i, src := range e.SourceLines[start:end] {
		fileLine := start + i + 1
		lines[i] = sourceLine{src, fileLine, fileLine == e.Line}
	}
	return lines
}

// SetLink method prepares a link and assign to Error.Link attribute
func (e *Error) SetLink(errorLink string) {
	errorLink = strings.Replace(errorLink, "{{Path}}", e.Path, -1)
	errorLink = strings.Replace(errorLink, "{{Line}}", strconv.Itoa(e.Line), -1)

	e.Link = "" + e.Path + ":" + strconv.Itoa(e.Line) + ""
}

// Return the character index of the first relevant stack frame, or -1 if none were found.
// Additionally it returns the base path of the tree in which the identified code resides.
func findRelevantStackFrame(stack string) (int, string) {
	// Find first item in SourcePath that isn't in RevelPath.
	// If first item is in RevelPath, keep track of position, trim and check again.
	partialStack := stack
	sourcePath := filepath.ToSlash(SourcePath)
	revelPath := filepath.ToSlash(RevelPath)
	sumFrame := 0
	for {
		frame := strings.Index(partialStack, sourcePath)
		revelFrame := strings.Index(partialStack, revelPath)

		if frame == -1 {
			break
		} else if frame != revelFrame {
			return sumFrame + frame, SourcePath
		} else {
			// Need to at least trim off the first character so this frame isn't caught again.
			partialStack = partialStack[frame + 1:]
			sumFrame += frame + 1
		}
	}
	for _, module := range Modules {
		if frame := strings.Index(stack, filepath.ToSlash(module.Path)); frame != -1 {
			return frame, module.Path
		}
	}
	return -1, ""
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package tchannel

import (
	"fmt"

	"golang.org/x/net/context"
)

const (
	// Message id for protocol level errors
	invalidMessageID uint32 = 0xFFFFFFFF
)

// A SystemErrCode indicates how a caller should handle a system error returned from a peer
type SystemErrCode byte

//go:generate stringer -type=SystemErrCode

const (
	// ErrCodeInvalid is an invalid error code, and should not be used
	ErrCodeInvalid SystemErrCode = 0x00

	// ErrCodeTimeout indicates the peer timed out.  Callers can retry the request
	// on another peer if the request is safe to retry.
	ErrCodeTimeout SystemErrCode = 0x01

	// ErrCodeCancelled indicates that the request was cancelled on the peer.  Callers
	// can retry the request on the same or another peer if the request is safe to retry
	ErrCodeCancelled SystemErrCode = 0x02

	// ErrCodeBusy indicates that the request was not dispatched because the peer
	// was too busy to handle it.  Callers can retry the request on another peer, and should
	// reweight their connections to direct less traffic to this peer until it recovers.
	ErrCodeBusy SystemErrCode = 0x03

	// ErrCodeDeclined indicates that the request not dispatched because the peer
	// declined to handle it, typically because the peer is not yet ready to handle it.
	// Callers can retry the request on another peer, but should not reweight their connections
	// and should continue to send traffic to this peer.
	ErrCodeDeclined SystemErrCode = 0x04

	// ErrCodeUnexpected indicates that the request failed for an unexpected reason, typically
	// a crash or other unexpected handling.  The request may have been processed before the failure;
	// callers should retry the request on this or another peer only if the request is safe to retry
	ErrCodeUnexpected SystemErrCode = 0x05

	// ErrCodeBadRequest indicates that the request was malformed, and could not be processed.
	// Callers should not bother to retry the request, as there is no chance it will be handled.
	ErrCodeBadRequest SystemErrCode = 0x06

	// ErrCodeNetwork indicates a network level error, such as a connection reset.
	// Callers can retry the request if the request is safe to retry
	ErrCodeNetwork SystemErrCode = 0x07

	// ErrCodeProtocol indincates a fatal protocol error communicating with the peer.  The connection
	// will be terminated.
	ErrCodeProtocol SystemErrCode = 0xFF
)

var (
	// ErrServerBusy is a SystemError indicating the server is busy
	ErrServerBusy = NewSystemError(ErrCodeBusy, "server busy")

	// ErrRequestCancelled is a SystemError indicating the request has been cancelled on the peer
	ErrRequestCancelled = NewSystemError(ErrCodeCancelled, "request cancelled")

	// ErrTimeout is a SytemError indicating the request has timed out
	ErrTimeout = NewSystemError(ErrCodeTimeout, "timeout")

	// ErrTimeoutRequired is a SystemError indicating that timeouts must be specified.
	ErrTimeoutRequired = NewSystemError(ErrCodeBadRequest, "timeout required")

	// ErrChannelClosed is a SystemError indicating that the channel has been closed.
	ErrChannelClosed = NewSystemError(ErrCodeDeclined, "closed channel")

	// ErrMethodTooLarge is a SystemError indicating that the method is too large.
	ErrMethodTooLarge = NewSystemError(ErrCodeProtocol, "method too large")
)

// A SystemError is a system-level error, containing an error code and message
// TODO(mmihic): Probably we want to hide this interface, and let application code
// just deal with standard raw errors.
type SystemError struct {
	code    SystemErrCode
	msg     string
	wrapped error
}

// NewSystemError defines a new SystemError with a code and message
func NewSystemError(code SystemErrCode, msg string, args ...interface{}) error {
	return SystemError{code: code, msg: fmt.Sprintf(msg, args...)}
}

// NewWrappedSystemError defines a new SystemError wrapping an existing error
func NewWrappedSystemError(code SystemErrCode, wrapped error) error {
	if se, ok := wrapped.(SystemError); ok {
		return se
	}

	return SystemError{code: code, msg: fmt.Sprintf("sys err %x: %s", code, wrapped.Error()), wrapped: wrapped}
}

// Error returns the code and message, conforming to the error interface
func (se SystemError) Error() string {
	return fmt.Sprintf("tchannel error %v: %s", se.Code(), se.msg)
}

// Wrapped returns the wrapped error
func (se SystemError) Wrapped() error { return se.wrapped }

// Code returns the SystemError code, for sending to a peer
func (se SystemError) Code() SystemErrCode {
	return se.code
}

// Message returns the SystemError message.
func (se SystemError) Message() string {
	return se.msg
}

// GetContextError converts the context error to a tchannel error.
func GetContextError(err error) error {
	if err == context.DeadlineExceeded {
		return ErrTimeout
	}
	return err
}

// GetSystemErrorCode returns the code to report for the given error.  If the error is a
// SystemError, we can get the code directly.  Otherwise treat it as an unexpected error
func GetSystemErrorCode(err error) SystemErrCode {
	if se, ok := err.(SystemError); ok {
		return se.Code()
	}

	return ErrCodeUnexpected
}

// GetSystemErrorMessage returns the message to report for the given error.  If the error is a
// SystemError, we can get the underlying message. Otherwise, use the Error() method.
func GetSystemErrorMessage(err error) string {
	if se, ok := err.(SystemError); ok {
		return se.Message()
	}

	return err.Error()
}
<commit_msg>Fix SystemError.Error, code was printed twice<commit_after>// Copyright (c) 2015 Uber Technologies, Inc.

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package tchannel

import (
	"fmt"

	"golang.org/x/net/context"
)

const (
	// Message id for protocol level errors
	invalidMessageID uint32 = 0xFFFFFFFF
)

// A SystemErrCode indicates how a caller should handle a system error returned from a peer
type SystemErrCode byte

//go:generate stringer -type=SystemErrCode

const (
	// ErrCodeInvalid is an invalid error code, and should not be used
	ErrCodeInvalid SystemErrCode = 0x00

	// ErrCodeTimeout indicates the peer timed out.  Callers can retry the request
	// on another peer if the request is safe to retry.
	ErrCodeTimeout SystemErrCode = 0x01

	// ErrCodeCancelled indicates that the request was cancelled on the peer.  Callers
	// can retry the request on the same or another peer if the request is safe to retry
	ErrCodeCancelled SystemErrCode = 0x02

	// ErrCodeBusy indicates that the request was not dispatched because the peer
	// was too busy to handle it.  Callers can retry the request on another peer, and should
	// reweight their connections to direct less traffic to this peer until it recovers.
	ErrCodeBusy SystemErrCode = 0x03

	// ErrCodeDeclined indicates that the request not dispatched because the peer
	// declined to handle it, typically because the peer is not yet ready to handle it.
	// Callers can retry the request on another peer, but should not reweight their connections
	// and should continue to send traffic to this peer.
	ErrCodeDeclined SystemErrCode = 0x04

	// ErrCodeUnexpected indicates that the request failed for an unexpected reason, typically
	// a crash or other unexpected handling.  The request may have been processed before the failure;
	// callers should retry the request on this or another peer only if the request is safe to retry
	ErrCodeUnexpected SystemErrCode = 0x05

	// ErrCodeBadRequest indicates that the request was malformed, and could not be processed.
	// Callers should not bother to retry the request, as there is no chance it will be handled.
	ErrCodeBadRequest SystemErrCode = 0x06

	// ErrCodeNetwork indicates a network level error, such as a connection reset.
	// Callers can retry the request if the request is safe to retry
	ErrCodeNetwork SystemErrCode = 0x07

	// ErrCodeProtocol indincates a fatal protocol error communicating with the peer.  The connection
	// will be terminated.
	ErrCodeProtocol SystemErrCode = 0xFF
)

var (
	// ErrServerBusy is a SystemError indicating the server is busy
	ErrServerBusy = NewSystemError(ErrCodeBusy, "server busy")

	// ErrRequestCancelled is a SystemError indicating the request has been cancelled on the peer
	ErrRequestCancelled = NewSystemError(ErrCodeCancelled, "request cancelled")

	// ErrTimeout is a SytemError indicating the request has timed out
	ErrTimeout = NewSystemError(ErrCodeTimeout, "timeout")

	// ErrTimeoutRequired is a SystemError indicating that timeouts must be specified.
	ErrTimeoutRequired = NewSystemError(ErrCodeBadRequest, "timeout required")

	// ErrChannelClosed is a SystemError indicating that the channel has been closed.
	ErrChannelClosed = NewSystemError(ErrCodeDeclined, "closed channel")

	// ErrMethodTooLarge is a SystemError indicating that the method is too large.
	ErrMethodTooLarge = NewSystemError(ErrCodeProtocol, "method too large")
)

// A SystemError is a system-level error, containing an error code and message
// TODO(mmihic): Probably we want to hide this interface, and let application code
// just deal with standard raw errors.
type SystemError struct {
	code    SystemErrCode
	msg     string
	wrapped error
}

// NewSystemError defines a new SystemError with a code and message
func NewSystemError(code SystemErrCode, msg string, args ...interface{}) error {
	return SystemError{code: code, msg: fmt.Sprintf(msg, args...)}
}

// NewWrappedSystemError defines a new SystemError wrapping an existing error
func NewWrappedSystemError(code SystemErrCode, wrapped error) error {
	if se, ok := wrapped.(SystemError); ok {
		return se
	}

	return SystemError{code: code, msg: fmt.Sprint(wrapped), wrapped: wrapped}
}

// Error returns the code and message, conforming to the error interface
func (se SystemError) Error() string {
	return fmt.Sprintf("tchannel error %v: %s", se.Code(), se.msg)
}

// Wrapped returns the wrapped error
func (se SystemError) Wrapped() error { return se.wrapped }

// Code returns the SystemError code, for sending to a peer
func (se SystemError) Code() SystemErrCode {
	return se.code
}

// Message returns the SystemError message.
func (se SystemError) Message() string {
	return se.msg
}

// GetContextError converts the context error to a tchannel error.
func GetContextError(err error) error {
	if err == context.DeadlineExceeded {
		return ErrTimeout
	}
	return err
}

// GetSystemErrorCode returns the code to report for the given error.  If the error is a
// SystemError, we can get the code directly.  Otherwise treat it as an unexpected error
func GetSystemErrorCode(err error) SystemErrCode {
	if se, ok := err.(SystemError); ok {
		return se.Code()
	}

	return ErrCodeUnexpected
}

// GetSystemErrorMessage returns the message to report for the given error.  If the error is a
// SystemError, we can get the underlying message. Otherwise, use the Error() method.
func GetSystemErrorMessage(err error) string {
	if se, ok := err.(SystemError); ok {
		return se.Message()
	}

	return err.Error()
}
<|endoftext|>


<commit_before>package errors

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"strconv"
	"strings"
	"text/template"

	"github.com/facebookgo/stack"
	uuid "github.com/nu7hatch/gouuid"
)

const (
	no_VALUE = "<no value>"
)

const (
	ERRCODE_PARSE_TPL_ERROR = 100
	ERRCODE_EXEC_TPL_ERROR  = 101
)

var (
	UsingLoadedTemplate = true
)

var (
	errorTemplate  map[uint64]errCodeTemplate
	errCodeDefined map[uint64]bool
)

func init() {
	errorTemplate = make(map[uint64]errCodeTemplate)
	errCodeDefined = make(map[uint64]bool)
}

type Params map[string]interface{}

type errorString struct {
	s string
}

func (e *errorString) Error() string {
	return e.s
}

func New(text string) error {
	return &errorString{text}
}

func Errorf(format string, a ...interface{}) error {
	return fmt.Errorf(format, a...)
}

func T(code uint64, template string) errCodeTemplate {
	if _, exist := errCodeDefined[code]; exist {
		strErr := fmt.Sprintf("error code %d already exist", code)
		panic(strErr)
	} else {
		errCodeDefined[code] = true
	}
	return errCodeTemplate{code: code, template: template}
}

type ErrorContext map[string]interface{}

func (p ErrorContext) String() string {
	if bJson, e := json.Marshal(p); e == nil {
		return string(bJson)
	}
	return ""
}

type ErrCode interface {
	Id() string
	Code() uint64
	Error() string
	StackTrace() string
	Context() ErrorContext
	FullError() error
}

type errCodeTemplate struct {
	code     uint64
	template string
}

func (p *errCodeTemplate) New(v ...Params) (err ErrCode) {
	params := Params{}
	if v != nil {
		for _, param := range v {
			for pn, pv := range param {
				params[pn] = pv
			}
		}
	}

	var tpl *errCodeTemplate = p
	if UsingLoadedTemplate {
		if t, exist := errorTemplate[p.code]; exist {
			tpl = &t
		}
	}

	strCode := fmt.Sprintf("ERRCODE:%d", tpl.code)

	stack := stack.CallersMulti(1)

	errId := "<NO-UUID>"
	if errUUID, e := uuid.NewV4(); e == nil {
		errId = errUUID.String()
	}

	if t, e := template.New(strCode).Parse(tpl.template); e != nil {
		strErr := fmt.Sprintf("parser error template failed, code: %d, error: %s", tpl.code, e)
		err = &errorCode{id: errId, code: ERRCODE_PARSE_TPL_ERROR, message: strErr, stackTrace: stack.String(), context: params}
		return
	} else {
		var buf bytes.Buffer
		if e := t.Execute(&buf, params); e != nil {
			strErr := fmt.Sprintf("execute template failed, code: %d, error: %s", tpl.code, e)
			return &errorCode{id: errId, code: ERRCODE_EXEC_TPL_ERROR, message: strErr, stackTrace: stack.String(), context: params}
		} else {
			bufstr := strings.Replace(buf.String(), no_VALUE, "[NO_VALUE]", -1)
			return &errorCode{id: errId, code: tpl.code, message: bufstr, stackTrace: stack.String(), context: params}
		}
	}
}

func (p *errCodeTemplate) IsEqual(err error) bool {
	if e, ok := err.(ErrCode); ok {
		if e.Code() == p.code {
			return true
		}
	}
	return false
}

type errorCode struct {
	id         string
	code       uint64
	message    string
	stackTrace string
	context    map[string]interface{}
}

func (p *errorCode) Id() string {
	return p.id
}

func (p *errorCode) Code() uint64 {
	return p.code
}

func (p *errorCode) Error() string {
	return fmt.Sprintf("[ERR-%d]: %s", p.code, p.message)
}

func (p *errorCode) FullError() error {
	errLines := make([]string, 1)
	errLines[0] = fmt.Sprintf("ERR_ID: %s\nCODE: %d", p.id, p.code)
	errLines = append(errLines, "MESSAGE:")
	errLines = append(errLines, p.message)
	errLines = append(errLines, "CONTEXT:")
	errLines = append(errLines, p.Context().String())
	errLines = append(errLines, "ORIGINAL_STACK_TRACE:")
	errLines = append(errLines, p.stackTrace)
	return New(strings.Join(errLines, "\n"))
}

func (p *errorCode) Context() ErrorContext {
	return p.context
}

func (p *errorCode) StackTrace() string {
	return p.stackTrace
}

func LoadMessageTemplate(fileName string) error {
	var fileLines []string
	if bFile, e := ioutil.ReadFile(fileName); e != nil {
		return e
	} else {
		fileLines = strings.Split(string(bFile), "\n")
	}

	if len(fileLines) == 0 {
		return nil
	}

	for i, line := range fileLines {

		line = strings.TrimSpace(line)
		line = strings.TrimRight(line, "\r\n")
		if line == "" {
			continue
		}

		datas := strings.Split(line, "=")

		if len(datas) != 2 {
			return Errorf("the error code template column count is not equal 2, line: %d", i+1)
		}

		strCode := strings.TrimSpace(datas[0])
		tmpl := strings.TrimSpace(datas[1])

		if code, e := strconv.ParseUint(strCode, 10, 32); e != nil {
			return e
		} else if code > 0 {
			if _, exist := errorTemplate[code]; exist {
				return Errorf("error code of %d already exist, line %d", code, i+1)
			}
			errorTemplate[code] = errCodeTemplate{code: code, template: tmpl}
		} else {
			return Errorf("error code should greater than 0, line %d", i+1)
		}
	}
	return nil
}

func IsErrCode(err error) bool {
	_, ok := err.(ErrCode)
	return ok
}
<commit_msg>add error id crc32<commit_after>package errors

import (
	"bytes"
	"encoding/json"
	"fmt"
	"hash/crc32"
	"io/ioutil"
	"strconv"
	"strings"
	"text/template"

	"github.com/facebookgo/stack"
	uuid "github.com/nu7hatch/gouuid"
)

const (
	no_VALUE = "<no value>"
)

const (
	ERRCODE_PARSE_TPL_ERROR = 100
	ERRCODE_EXEC_TPL_ERROR  = 101
)

var (
	UsingLoadedTemplate = true
)

var (
	errorTemplate  map[uint64]errCodeTemplate
	errCodeDefined map[uint64]bool
)

func init() {
	errorTemplate = make(map[uint64]errCodeTemplate)
	errCodeDefined = make(map[uint64]bool)
}

type Params map[string]interface{}

type errorString struct {
	s string
}

func (e *errorString) Error() string {
	return e.s
}

func New(text string) error {
	return &errorString{text}
}

func Errorf(format string, a ...interface{}) error {
	return fmt.Errorf(format, a...)
}

func T(code uint64, template string) errCodeTemplate {
	if _, exist := errCodeDefined[code]; exist {
		strErr := fmt.Sprintf("error code %d already exist", code)
		panic(strErr)
	} else {
		errCodeDefined[code] = true
	}
	return errCodeTemplate{code: code, template: template}
}

type ErrorContext map[string]interface{}

func (p ErrorContext) String() string {
	if bJson, e := json.Marshal(p); e == nil {
		return string(bJson)
	}
	return ""
}

type ErrCode interface {
	Id() string
	Code() uint64
	Error() string
	StackTrace() string
	Context() ErrorContext
	FullError() error
}

type errCodeTemplate struct {
	code     uint64
	template string
}

func (p *errCodeTemplate) New(v ...Params) (err ErrCode) {
	params := Params{}
	if v != nil {
		for _, param := range v {
			for pn, pv := range param {
				params[pn] = pv
			}
		}
	}

	var tpl *errCodeTemplate = p
	if UsingLoadedTemplate {
		if t, exist := errorTemplate[p.code]; exist {
			tpl = &t
		}
	}

	strCode := fmt.Sprintf("ERRCODE:%d", tpl.code)

	stack := stack.CallersMulti(1)

	errId := "<NO-UUID>"
	if errUUID, e := uuid.NewV4(); e == nil {
		errId = errUUID.String()
	}

	crcErrId := crc32.ChecksumIEEE([]byte(errId))

	if t, e := template.New(strCode).Parse(tpl.template); e != nil {
		strErr := fmt.Sprintf("parser error template failed, code: %d, error: %s", tpl.code, e)
		err = &errorCode{id: errId, id_crc: crcErrId, code: ERRCODE_PARSE_TPL_ERROR, message: strErr, stackTrace: stack.String(), context: params}
		return
	} else {
		var buf bytes.Buffer
		if e := t.Execute(&buf, params); e != nil {
			strErr := fmt.Sprintf("execute template failed, code: %d, error: %s", tpl.code, e)
			return &errorCode{id: errId, id_crc: crcErrId, code: ERRCODE_EXEC_TPL_ERROR, message: strErr, stackTrace: stack.String(), context: params}
		} else {
			bufstr := strings.Replace(buf.String(), no_VALUE, "[NO_VALUE]", -1)
			return &errorCode{id: errId, id_crc: crcErrId, code: tpl.code, message: bufstr, stackTrace: stack.String(), context: params}
		}
	}
}

func (p *errCodeTemplate) IsEqual(err error) bool {
	if e, ok := err.(ErrCode); ok {
		if e.Code() == p.code {
			return true
		}
	}
	return false
}

type errorCode struct {
	id         string
	id_crc     uint32
	code       uint64
	message    string
	stackTrace string
	context    map[string]interface{}
}

func (p *errorCode) Id() string {
	return p.id
}

func (p *errorCode) Code() uint64 {
	return p.code
}

func (p *errorCode) Error() string {
	return fmt.Sprintf("[ERR-%d-%0xd]: %s", p.code, p.id_crc, p.message)
}

func (p *errorCode) FullError() error {
	errLines := make([]string, 1)
	errLines[0] = fmt.Sprintf("ERR_ID: %s\nCODE: %d-%0xd", p.id, p.code, p.id_crc)
	errLines = append(errLines, "MESSAGE:")
	errLines = append(errLines, p.message)
	errLines = append(errLines, "CONTEXT:")
	errLines = append(errLines, p.Context().String())
	errLines = append(errLines, "ORIGINAL_STACK_TRACE:")
	errLines = append(errLines, p.stackTrace)
	return New(strings.Join(errLines, "\n"))
}

func (p *errorCode) Context() ErrorContext {
	return p.context
}

func (p *errorCode) StackTrace() string {
	return p.stackTrace
}

func LoadMessageTemplate(fileName string) error {
	var fileLines []string
	if bFile, e := ioutil.ReadFile(fileName); e != nil {
		return e
	} else {
		fileLines = strings.Split(string(bFile), "\n")
	}

	if len(fileLines) == 0 {
		return nil
	}

	for i, line := range fileLines {

		line = strings.TrimSpace(line)
		line = strings.TrimRight(line, "\r\n")
		if line == "" {
			continue
		}

		datas := strings.Split(line, "=")

		if len(datas) != 2 {
			return Errorf("the error code template column count is not equal 2, line: %d", i+1)
		}

		strCode := strings.TrimSpace(datas[0])
		tmpl := strings.TrimSpace(datas[1])

		if code, e := strconv.ParseUint(strCode, 10, 32); e != nil {
			return e
		} else if code > 0 {
			if _, exist := errorTemplate[code]; exist {
				return Errorf("error code of %d already exist, line %d", code, i+1)
			}
			errorTemplate[code] = errCodeTemplate{code: code, template: tmpl}
		} else {
			return Errorf("error code should greater than 0, line %d", i+1)
		}
	}
	return nil
}

func IsErrCode(err error) bool {
	_, ok := err.(ErrCode)
	return ok
}
<|endoftext|>


<commit_before>package ethrpc

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"math/big"
	"net/http"
)

// EthError - ethereum error
type EthError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

func (err EthError) Error() string {
	return fmt.Sprintf("Error %d (%s)", err.Code, err.Message)
}

type ethResponse struct {
	ID      int             `json:"id"`
	JSONRPC string          `json:"jsonrpc"`
	Result  json.RawMessage `json:"result"`
	Error   *EthError       `json:"error"`
}

type ethRequest struct {
	ID      int           `json:"id"`
	JSONRPC string        `json:"jsonrpc"`
	Method  string        `json:"method"`
	Params  []interface{} `json:"params"`
}

// EthRPC - Ethereum rpc client
type EthRPC struct {
	url   string
	Debug bool
}

// NewEthRPC create new rpc client with given url
func NewEthRPC(url string) *EthRPC {
	return &EthRPC{url: url}
}

func (rpc *EthRPC) call(method string, target interface{}, params ...interface{}) error {
	result, err := rpc.RawCall(method, params...)
	if err != nil {
		return err
	}

	if target == nil {
		return nil
	}

	if err := json.Unmarshal(result, target); err != nil {
		return err
	}

	return nil
}

// RawCall returns raw response of method call
func (rpc *EthRPC) RawCall(method string, params ...interface{}) (json.RawMessage, error) {
	request := ethRequest{
		ID:      1,
		JSONRPC: "2.0",
		Method:  method,
		Params:  params,
	}

	body, err := json.Marshal(request)
	if err != nil {
		return nil, err
	}

	response, err := http.Post(rpc.url, "application/json", bytes.NewBuffer(body))
	if response != nil {
		defer response.Body.Close()
	}
	if err != nil {
		return nil, err
	}

	data, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return nil, err
	}

	if rpc.Debug {
		log.Printf("%s\nRequest: %s\nResponse: %s\n", method, body, data)
	}

	resp := new(ethResponse)
	if err := json.Unmarshal(data, resp); err != nil {
		return nil, err
	}

	if resp.Error != nil {
		return nil, *resp.Error
	}

	return resp.Result, nil

}

// Web3ClientVersion returns the current client version.
func (rpc *EthRPC) Web3ClientVersion() (string, error) {
	var clientVersion string

	err := rpc.call("web3_clientVersion", &clientVersion)
	return clientVersion, err
}

// Web3Sha3 returns Keccak-256 (not the standardized SHA3-256) of the given data.
func (rpc *EthRPC) Web3Sha3(data []byte) (string, error) {
	var hash string

	err := rpc.call("web3_sha3", &hash, fmt.Sprintf("0x%x", data))
	return hash, err
}

// NetVersion returns the current network protocol version.
func (rpc *EthRPC) NetVersion() (string, error) {
	var version string

	err := rpc.call("net_version", &version)
	return version, err
}

// NetListening returns true if client is actively listening for network connections.
func (rpc *EthRPC) NetListening() (bool, error) {
	var listening bool

	err := rpc.call("net_listening", &listening)
	return listening, err
}

// NetPeerCount returns number of peers currently connected to the client.
func (rpc *EthRPC) NetPeerCount() (int, error) {
	var response string
	if err := rpc.call("net_peerCount", &response); err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthProtocolVersion returns the current ethereum protocol version.
func (rpc *EthRPC) EthProtocolVersion() (string, error) {
	var protocolVersion string

	err := rpc.call("eth_protocolVersion", &protocolVersion)
	return protocolVersion, err
}

// EthSyncing returns an object with data about the sync status or false.
func (rpc *EthRPC) EthSyncing() (*Syncing, error) {
	result, err := rpc.RawCall("eth_syncing")
	if err != nil {
		return nil, err
	}
	syncing := new(Syncing)
	if bytes.Equal(result, []byte("false")) {
		return syncing, nil
	}
	err = json.Unmarshal(result, syncing)
	return syncing, err
}

// EthCoinbase returns the client coinbase address
func (rpc *EthRPC) EthCoinbase() (string, error) {
	var address string

	err := rpc.call("eth_coinbase", &address)
	return address, err
}

// EthMining returns true if client is actively mining new blocks.
func (rpc *EthRPC) EthMining() (bool, error) {
	var mining bool

	err := rpc.call("eth_mining", &mining)
	return mining, err
}

// EthHashrate returns the number of hashes per second that the node is mining with.
func (rpc *EthRPC) EthHashrate() (int, error) {
	var response string

	if err := rpc.call("eth_hashrate", &response); err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthGasPrice returns the current price per gas in wei.
func (rpc *EthRPC) EthGasPrice() (big.Int, error) {
	var response string
	if err := rpc.call("eth_gasPrice", &response); err != nil {
		return big.Int{}, err
	}

	return ParseBigInt(response)
}

// EthAccounts returns a list of addresses owned by client.
func (rpc *EthRPC) EthAccounts() ([]string, error) {
	accounts := []string{}

	err := rpc.call("eth_accounts", &accounts)
	return accounts, err
}

// EthBlockNumber returns the number of most recent block.
func (rpc *EthRPC) EthBlockNumber() (int, error) {
	var response string
	if err := rpc.call("eth_blockNumber", &response); err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthGetBalance returns the balance of the account of given address in wei.
func (rpc *EthRPC) EthGetBalance(address, block string) (big.Int, error) {
	var response string
	if err := rpc.call("eth_getBalance", &response, address, block); err != nil {
		return big.Int{}, err
	}

	return ParseBigInt(response)
}

// EthGetTransactionCount returns the number of transactions sent from an address.
func (rpc *EthRPC) EthGetTransactionCount(address, block string) (int, error) {
	var response string

	if err := rpc.call("eth_getTransactionCount", &response, address, block); err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthGetBlockTransactionCountByHash returns the number of transactions in a block from a block matching the given block hash.
func (rpc *EthRPC) EthGetBlockTransactionCountByHash(hash string) (int, error) {
	var response string

	if err := rpc.call("eth_getBlockTransactionCountByHash", &response, hash); err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthGetBlockTransactionCountByNumber returns the number of transactions in a block from a block matching the given block
func (rpc *EthRPC) EthGetBlockTransactionCountByNumber(number int) (int, error) {
	var response string

	if err := rpc.call("eth_getBlockTransactionCountByNumber", &response, fmt.Sprintf("0x%x", number)); err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthGetUncleCountByBlockHash returns the number of uncles in a block from a block matching the given block hash.
func (rpc *EthRPC) EthGetUncleCountByBlockHash(hash string) (int, error) {
	var response string

	if err := rpc.call("eth_getUncleCountByBlockHash", &response, hash); err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthGetUncleCountByBlockNumber returns the number of uncles in a block from a block matching the given block number.
func (rpc *EthRPC) EthGetUncleCountByBlockNumber(number int) (int, error) {
	var response string

	if err := rpc.call("eth_getUncleCountByBlockNumber", &response, fmt.Sprintf("0x%x", number)); err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthGetCode returns code at a given address.
func (rpc *EthRPC) EthGetCode(address, block string) (string, error) {
	var code string

	err := rpc.call("eth_getCode", &code, address, block)
	return code, err
}

// EthSign signs data with a given address.
func (rpc *EthRPC) EthSign(address, data string) (string, error) {
	var signature string

	err := rpc.call("eth_sign", &signature, address, data)
	return signature, err
}

// EthSendTransaction creates new message call transaction or a contract creation, if the data field contains code.
func (rpc *EthRPC) EthSendTransaction(transaction T) (string, error) {
	var hash string

	err := rpc.call("eth_sendTransaction", &hash, transaction)
	return hash, err
}

// EthSendRawTransaction creates new message call transaction or a contract creation for signed transactions.
func (rpc *EthRPC) EthSendRawTransaction(data string) (string, error) {
	var hash string

	err := rpc.call("eth_sendRawTransaction", &hash, data)
	return hash, err
}

// EthCall executes a new message call immediately without creating a transaction on the block chain.
func (rpc *EthRPC) EthCall(transaction *T, tag string) (string, error) {
	var data string

	err := rpc.call("eth_call", &data, transaction, tag)
	return data, err
}

// EthEstimateGas makes a call or transaction, which won't be added to the blockchain and returns the used gas, which can be used for estimating the used gas.
func (rpc *EthRPC) EthEstimateGas(transaction *T) (int, error) {
	var response string

	err := rpc.call("eth_estimateGas", &response, transaction)
	if err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthGetTransactionByHash returns the information about a transaction requested by transaction hash.
func (rpc *EthRPC) EthGetTransactionByHash(hash string) (*Transaction, error) {
	transaction := new(Transaction)

	err := rpc.call("eth_getTransactionByHash", &transaction, hash)
	if err != nil {
		return nil, err
	}

	return transaction, nil
}

// EthGetTransactionByBlockHashAndIndex returns information about a transaction by block hash and transaction index position.
func (rpc *EthRPC) EthGetTransactionByBlockHashAndIndex(blockHash string, transactionIndex int) (*Transaction, error) {
	transaction := new(Transaction)

	err := rpc.call("eth_getTransactionByBlockHashAndIndex", &transaction, blockHash, IntToHex(transactionIndex))
	if err != nil {
		return nil, err
	}

	return transaction, nil
}

// EthGetTransactionByBlockNumberAndIndex returns information about a transaction by block number and transaction index position.
func (rpc *EthRPC) EthGetTransactionByBlockNumberAndIndex(blockNumber, transactionIndex int) (*Transaction, error) {
	transaction := new(Transaction)

	err := rpc.call("eth_getTransactionByBlockNumberAndIndex", &transaction, IntToHex(blockNumber), IntToHex(transactionIndex))
	if err != nil {
		return nil, err
	}

	return transaction, nil
}

// EthGetTransactionReceipt returns the receipt of a transaction by transaction hash.
// Note That the receipt is not available for pending transactions.
func (rpc *EthRPC) EthGetTransactionReceipt(hash string) (*TransactionReceipt, error) {
	transactionReceipt := new(TransactionReceipt)

	err := rpc.call("eth_getTransactionReceipt", &transactionReceipt, hash)
	if err != nil {
		return nil, err
	}

	return transactionReceipt, nil
}

// EthGetCompilers returns a list of available compilers in the client.
func (rpc *EthRPC) EthGetCompilers() ([]string, error) {
	compilers := []string{}

	err := rpc.call("eth_getCompilers", &compilers)
	return compilers, err
}
<commit_msg>Fix get transaction methods.<commit_after>package ethrpc

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"math/big"
	"net/http"
)

// EthError - ethereum error
type EthError struct {
	Code    int    `json:"code"`
	Message string `json:"message"`
}

func (err EthError) Error() string {
	return fmt.Sprintf("Error %d (%s)", err.Code, err.Message)
}

type ethResponse struct {
	ID      int             `json:"id"`
	JSONRPC string          `json:"jsonrpc"`
	Result  json.RawMessage `json:"result"`
	Error   *EthError       `json:"error"`
}

type ethRequest struct {
	ID      int           `json:"id"`
	JSONRPC string        `json:"jsonrpc"`
	Method  string        `json:"method"`
	Params  []interface{} `json:"params"`
}

// EthRPC - Ethereum rpc client
type EthRPC struct {
	url   string
	Debug bool
}

// NewEthRPC create new rpc client with given url
func NewEthRPC(url string) *EthRPC {
	return &EthRPC{url: url}
}

func (rpc *EthRPC) call(method string, target interface{}, params ...interface{}) error {
	result, err := rpc.RawCall(method, params...)
	if err != nil {
		return err
	}

	if target == nil {
		return nil
	}

	if err := json.Unmarshal(result, target); err != nil {
		return err
	}

	return nil
}

// RawCall returns raw response of method call
func (rpc *EthRPC) RawCall(method string, params ...interface{}) (json.RawMessage, error) {
	request := ethRequest{
		ID:      1,
		JSONRPC: "2.0",
		Method:  method,
		Params:  params,
	}

	body, err := json.Marshal(request)
	if err != nil {
		return nil, err
	}

	response, err := http.Post(rpc.url, "application/json", bytes.NewBuffer(body))
	if response != nil {
		defer response.Body.Close()
	}
	if err != nil {
		return nil, err
	}

	data, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return nil, err
	}

	if rpc.Debug {
		log.Printf("%s\nRequest: %s\nResponse: %s\n", method, body, data)
	}

	resp := new(ethResponse)
	if err := json.Unmarshal(data, resp); err != nil {
		return nil, err
	}

	if resp.Error != nil {
		return nil, *resp.Error
	}

	return resp.Result, nil

}

// Web3ClientVersion returns the current client version.
func (rpc *EthRPC) Web3ClientVersion() (string, error) {
	var clientVersion string

	err := rpc.call("web3_clientVersion", &clientVersion)
	return clientVersion, err
}

// Web3Sha3 returns Keccak-256 (not the standardized SHA3-256) of the given data.
func (rpc *EthRPC) Web3Sha3(data []byte) (string, error) {
	var hash string

	err := rpc.call("web3_sha3", &hash, fmt.Sprintf("0x%x", data))
	return hash, err
}

// NetVersion returns the current network protocol version.
func (rpc *EthRPC) NetVersion() (string, error) {
	var version string

	err := rpc.call("net_version", &version)
	return version, err
}

// NetListening returns true if client is actively listening for network connections.
func (rpc *EthRPC) NetListening() (bool, error) {
	var listening bool

	err := rpc.call("net_listening", &listening)
	return listening, err
}

// NetPeerCount returns number of peers currently connected to the client.
func (rpc *EthRPC) NetPeerCount() (int, error) {
	var response string
	if err := rpc.call("net_peerCount", &response); err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthProtocolVersion returns the current ethereum protocol version.
func (rpc *EthRPC) EthProtocolVersion() (string, error) {
	var protocolVersion string

	err := rpc.call("eth_protocolVersion", &protocolVersion)
	return protocolVersion, err
}

// EthSyncing returns an object with data about the sync status or false.
func (rpc *EthRPC) EthSyncing() (*Syncing, error) {
	result, err := rpc.RawCall("eth_syncing")
	if err != nil {
		return nil, err
	}
	syncing := new(Syncing)
	if bytes.Equal(result, []byte("false")) {
		return syncing, nil
	}
	err = json.Unmarshal(result, syncing)
	return syncing, err
}

// EthCoinbase returns the client coinbase address
func (rpc *EthRPC) EthCoinbase() (string, error) {
	var address string

	err := rpc.call("eth_coinbase", &address)
	return address, err
}

// EthMining returns true if client is actively mining new blocks.
func (rpc *EthRPC) EthMining() (bool, error) {
	var mining bool

	err := rpc.call("eth_mining", &mining)
	return mining, err
}

// EthHashrate returns the number of hashes per second that the node is mining with.
func (rpc *EthRPC) EthHashrate() (int, error) {
	var response string

	if err := rpc.call("eth_hashrate", &response); err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthGasPrice returns the current price per gas in wei.
func (rpc *EthRPC) EthGasPrice() (big.Int, error) {
	var response string
	if err := rpc.call("eth_gasPrice", &response); err != nil {
		return big.Int{}, err
	}

	return ParseBigInt(response)
}

// EthAccounts returns a list of addresses owned by client.
func (rpc *EthRPC) EthAccounts() ([]string, error) {
	accounts := []string{}

	err := rpc.call("eth_accounts", &accounts)
	return accounts, err
}

// EthBlockNumber returns the number of most recent block.
func (rpc *EthRPC) EthBlockNumber() (int, error) {
	var response string
	if err := rpc.call("eth_blockNumber", &response); err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthGetBalance returns the balance of the account of given address in wei.
func (rpc *EthRPC) EthGetBalance(address, block string) (big.Int, error) {
	var response string
	if err := rpc.call("eth_getBalance", &response, address, block); err != nil {
		return big.Int{}, err
	}

	return ParseBigInt(response)
}

// EthGetTransactionCount returns the number of transactions sent from an address.
func (rpc *EthRPC) EthGetTransactionCount(address, block string) (int, error) {
	var response string

	if err := rpc.call("eth_getTransactionCount", &response, address, block); err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthGetBlockTransactionCountByHash returns the number of transactions in a block from a block matching the given block hash.
func (rpc *EthRPC) EthGetBlockTransactionCountByHash(hash string) (int, error) {
	var response string

	if err := rpc.call("eth_getBlockTransactionCountByHash", &response, hash); err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthGetBlockTransactionCountByNumber returns the number of transactions in a block from a block matching the given block
func (rpc *EthRPC) EthGetBlockTransactionCountByNumber(number int) (int, error) {
	var response string

	if err := rpc.call("eth_getBlockTransactionCountByNumber", &response, fmt.Sprintf("0x%x", number)); err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthGetUncleCountByBlockHash returns the number of uncles in a block from a block matching the given block hash.
func (rpc *EthRPC) EthGetUncleCountByBlockHash(hash string) (int, error) {
	var response string

	if err := rpc.call("eth_getUncleCountByBlockHash", &response, hash); err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthGetUncleCountByBlockNumber returns the number of uncles in a block from a block matching the given block number.
func (rpc *EthRPC) EthGetUncleCountByBlockNumber(number int) (int, error) {
	var response string

	if err := rpc.call("eth_getUncleCountByBlockNumber", &response, fmt.Sprintf("0x%x", number)); err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthGetCode returns code at a given address.
func (rpc *EthRPC) EthGetCode(address, block string) (string, error) {
	var code string

	err := rpc.call("eth_getCode", &code, address, block)
	return code, err
}

// EthSign signs data with a given address.
func (rpc *EthRPC) EthSign(address, data string) (string, error) {
	var signature string

	err := rpc.call("eth_sign", &signature, address, data)
	return signature, err
}

// EthSendTransaction creates new message call transaction or a contract creation, if the data field contains code.
func (rpc *EthRPC) EthSendTransaction(transaction T) (string, error) {
	var hash string

	err := rpc.call("eth_sendTransaction", &hash, transaction)
	return hash, err
}

// EthSendRawTransaction creates new message call transaction or a contract creation for signed transactions.
func (rpc *EthRPC) EthSendRawTransaction(data string) (string, error) {
	var hash string

	err := rpc.call("eth_sendRawTransaction", &hash, data)
	return hash, err
}

// EthCall executes a new message call immediately without creating a transaction on the block chain.
func (rpc *EthRPC) EthCall(transaction *T, tag string) (string, error) {
	var data string

	err := rpc.call("eth_call", &data, transaction, tag)
	return data, err
}

// EthEstimateGas makes a call or transaction, which won't be added to the blockchain and returns the used gas, which can be used for estimating the used gas.
func (rpc *EthRPC) EthEstimateGas(transaction *T) (int, error) {
	var response string

	err := rpc.call("eth_estimateGas", &response, transaction)
	if err != nil {
		return 0, err
	}

	return ParseInt(response)
}

// EthGetTransactionByHash returns the information about a transaction requested by transaction hash.
func (rpc *EthRPC) EthGetTransactionByHash(hash string) (*Transaction, error) {
	transaction := new(Transaction)

	err := rpc.call("eth_getTransactionByHash", transaction, hash)
	if err != nil {
		return nil, err
	}

	return transaction, nil
}

// EthGetTransactionByBlockHashAndIndex returns information about a transaction by block hash and transaction index position.
func (rpc *EthRPC) EthGetTransactionByBlockHashAndIndex(blockHash string, transactionIndex int) (*Transaction, error) {
	transaction := new(Transaction)

	err := rpc.call("eth_getTransactionByBlockHashAndIndex", transaction, blockHash, IntToHex(transactionIndex))
	if err != nil {
		return nil, err
	}

	return transaction, nil
}

// EthGetTransactionByBlockNumberAndIndex returns information about a transaction by block number and transaction index position.
func (rpc *EthRPC) EthGetTransactionByBlockNumberAndIndex(blockNumber, transactionIndex int) (*Transaction, error) {
	transaction := new(Transaction)

	err := rpc.call("eth_getTransactionByBlockNumberAndIndex", transaction, IntToHex(blockNumber), IntToHex(transactionIndex))
	if err != nil {
		return nil, err
	}

	return transaction, nil
}

// EthGetTransactionReceipt returns the receipt of a transaction by transaction hash.
// Note That the receipt is not available for pending transactions.
func (rpc *EthRPC) EthGetTransactionReceipt(hash string) (*TransactionReceipt, error) {
	transactionReceipt := new(TransactionReceipt)

	err := rpc.call("eth_getTransactionReceipt", transactionReceipt, hash)
	if err != nil {
		return nil, err
	}

	return transactionReceipt, nil
}

// EthGetCompilers returns a list of available compilers in the client.
func (rpc *EthRPC) EthGetCompilers() ([]string, error) {
	compilers := []string{}

	err := rpc.call("eth_getCompilers", &compilers)
	return compilers, err
}
<|endoftext|>