<commit_before>// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.

package donna

import (`testing`; `fmt`; `runtime`; `strings`)

func expect(t *testing.T, actual, expected interface{}) {
        var passed bool

        _, file, line, _ := runtime.Caller(1)           // Get the calling file path and line number.
        file = file[strings.LastIndex(file, `/`) + 1:]  // Keep file name only.

        switch expected.(type) {
        case bool:
                if assertion, ok := actual.(bool); ok {
                        passed = (assertion == expected)
                }
        case int:
                if assertion, ok := actual.(int); ok {
                        passed = (assertion == expected)
                }
        case uint64:
                if assertion, ok := actual.(uint64); ok {
                        passed = (assertion == expected)
                }
        default:
                passed = (fmt.Sprintf(`%v`, actual) == fmt.Sprintf(`%v`, expected))
        }

        if passed {
                t.Logf("\r\t\x1B[32m%s line %d: %v\x1B[0m", file, line, actual)
        } else {
                t.Errorf("\r\t\x1B[31m%s line %d\nExpected: %v\n  Actual: %v\x1B[0m", file, line, expected, actual)
        }
}

func contains(t *testing.T, actual interface{}, expected string) {
        containsMatcher(t, fmt.Sprintf(`%v`, actual), expected, true)
}

func doesNotContain(t *testing.T, actual interface{}, expected string) {
        containsMatcher(t, fmt.Sprintf(`%v`, actual), expected, false)
}

func containsMatcher(t *testing.T, actual, expected string, match bool) {
        var passed bool

        _, file, line, _ := runtime.Caller(2)
        file = file[strings.LastIndex(file, `/`) + 1:]

        if match {
                passed = (actual == expected)
        } else {
                passed = (actual != expected)
        }

        if passed {
                t.Logf("\r\t\x1B[32m%s line %d: %v\x1B[0m", file, line, actual)
        } else {
                t.Errorf("\r\t\x1B[31m%s line %d\nContains: %s\n  Actual: %s\x1B[0m", file, line, expected, actual)
        }
}

func TestBitmask000(t *testing.T) { // White
        passed := [8]Bitmask{0}
        for square := A2; square <= H2; square++ {
                i := square - A2
                if Col(square) > 0 {
                        passed[i].fill(square - 1, 8, 0, 0x00FFFFFFFFFFFFFF)
                }
                passed[i].fill(square, 8, 0, 0x00FFFFFFFFFFFFFF)
                if Col(square) < 7 {
                        passed[i].fill(square + 1, 8, 0, 0x00FFFFFFFFFFFFFF)
                }
        }
        expect(t, passed[0], Bitmask(0x0303030303030000))
        expect(t, passed[1], Bitmask(0x0707070707070000))
        expect(t, passed[2], Bitmask(0x0E0E0E0E0E0E0000))
        expect(t, passed[3], Bitmask(0x1C1C1C1C1C1C0000))
        expect(t, passed[4], Bitmask(0x3838383838380000))
        expect(t, passed[5], Bitmask(0x7070707070700000))
        expect(t, passed[6], Bitmask(0xE0E0E0E0E0E00000))
        expect(t, passed[7], Bitmask(0xC0C0C0C0C0C00000))
}

func TestBitmask010(t *testing.T) { // Black
        passed := [8]Bitmask{0}
        for square := A7; square <= H7; square++ {
                i := square - A7
                if Col(square) > 0 {
                        passed[i].fill(square - 1, -8, 0, 0xFFFFFFFFFFFFFF00)
                }
                passed[i].fill(square, -8, 0, 0xFFFFFFFFFFFFFF00)
                if Col(square) < 7 {
                        passed[i].fill(square + 1, -8, 0, 0xFFFFFFFFFFFFFF00)
                }
        }
        expect(t, passed[0], Bitmask(0x0000030303030303))
        expect(t, passed[1], Bitmask(0x0000070707070707))
        expect(t, passed[2], Bitmask(0x00000E0E0E0E0E0E))
        expect(t, passed[3], Bitmask(0x00001C1C1C1C1C1C))
        expect(t, passed[4], Bitmask(0x0000383838383838))
        expect(t, passed[5], Bitmask(0x0000707070707070))
        expect(t, passed[6], Bitmask(0x0000E0E0E0E0E0E0))
        expect(t, passed[7], Bitmask(0x0000C0C0C0C0C0C0))
}

func TestBitmask030(t *testing.T) { // White
        forward := [8]Bitmask{0}
        for square := A4; square <= H4; square++ {
                i := square - A4
                forward[i].fill(square, 8, 0, 0x00FFFFFFFFFFFFFF)
        }
        expect(t, forward[0], Bitmask(0x0101010100000000))
        expect(t, forward[1], Bitmask(0x0202020200000000))
        expect(t, forward[2], Bitmask(0x0404040400000000))
        expect(t, forward[3], Bitmask(0x0808080800000000))
        expect(t, forward[4], Bitmask(0x1010101000000000))
        expect(t, forward[5], Bitmask(0x2020202000000000))
        expect(t, forward[6], Bitmask(0x4040404000000000))
        expect(t, forward[7], Bitmask(0x8080808000000000))
}

func TestBitmask040(t *testing.T) { // Black
        forward := [8]Bitmask{0}
        for square := A7; square <= H7; square++ {
                i := square - A7
                forward[i].fill(square, -8, 0, 0xFFFFFFFFFFFFFF00)
        }
        expect(t, forward[0], Bitmask(0x0000010101010101))
        expect(t, forward[1], Bitmask(0x0000020202020202))
        expect(t, forward[2], Bitmask(0x0000040404040404))
        expect(t, forward[3], Bitmask(0x0000080808080808))
        expect(t, forward[4], Bitmask(0x0000101010101010))
        expect(t, forward[5], Bitmask(0x0000202020202020))
        expect(t, forward[6], Bitmask(0x0000404040404040))
        expect(t, forward[7], Bitmask(0x0000808080808080))
}

func TestBitmask050(t *testing.T) {
        mask := Bitmask(0x0000000000000001)
        bit := mask.pop()
        expect(t, bit, 0)
        expect(t, mask, Bitmask(0x0000000000000000))

        mask = Bitmask(0x8000000000000000)
        bit = mask.pop()
        expect(t, bit, 63)
        expect(t, mask, Bitmask(0x0000000000000000))
}
<commit_msg>Fixed containment expectation<commit_after>// Copyright (c) 2013 by Michael Dvorkin. All Rights Reserved.
// Use of this source code is governed by a MIT-style license that can
// be found in the LICENSE file.

package donna

import (`testing`; `fmt`; `runtime`; `strings`)

func expect(t *testing.T, actual, expected interface{}) {
        var passed bool

        _, file, line, _ := runtime.Caller(1)           // Get the calling file path and line number.
        file = file[strings.LastIndex(file, `/`) + 1:]  // Keep file name only.

        switch expected.(type) {
        case bool:
                if assertion, ok := actual.(bool); ok {
                        passed = (assertion == expected)
                }
        case int:
                if assertion, ok := actual.(int); ok {
                        passed = (assertion == expected)
                }
        case uint64:
                if assertion, ok := actual.(uint64); ok {
                        passed = (assertion == expected)
                }
        default:
                passed = (fmt.Sprintf(`%v`, actual) == fmt.Sprintf(`%v`, expected))
        }

        if passed {
                t.Logf("\r\t\x1B[32m%s line %d: %v\x1B[0m", file, line, actual)
        } else {
                t.Errorf("\r\t\x1B[31m%s line %d\nExpected: %v\n  Actual: %v\x1B[0m", file, line, expected, actual)
        }
}

func contains(t *testing.T, actual interface{}, expected string) {
        containsMatcher(t, fmt.Sprintf(`%v`, actual), expected, true)
}

func doesNotContain(t *testing.T, actual interface{}, expected string) {
        containsMatcher(t, fmt.Sprintf(`%v`, actual), expected, false)
}

func containsMatcher(t *testing.T, actual, expected string, match bool) {
        var passed bool

        _, file, line, _ := runtime.Caller(2)
        file = file[strings.LastIndex(file, `/`) + 1:]

        if match {
                passed = strings.Contains(actual, expected)
        } else {
                passed = !strings.Contains(actual, expected)
        }

        if passed {
                t.Logf("\r\t\x1B[32m%s line %d: %v\x1B[0m", file, line, actual)
        } else {
                t.Errorf("\r\t\x1B[31m%s line %d\nContains: %s\n  Actual: %s\x1B[0m", file, line, expected, actual)
        }
}

func TestBitmask000(t *testing.T) { // White
        passed := [8]Bitmask{0}
        for square := A2; square <= H2; square++ {
                i := square - A2
                if Col(square) > 0 {
                        passed[i].fill(square - 1, 8, 0, 0x00FFFFFFFFFFFFFF)
                }
                passed[i].fill(square, 8, 0, 0x00FFFFFFFFFFFFFF)
                if Col(square) < 7 {
                        passed[i].fill(square + 1, 8, 0, 0x00FFFFFFFFFFFFFF)
                }
        }
        expect(t, passed[0], Bitmask(0x0303030303030000))
        expect(t, passed[1], Bitmask(0x0707070707070000))
        expect(t, passed[2], Bitmask(0x0E0E0E0E0E0E0000))
        expect(t, passed[3], Bitmask(0x1C1C1C1C1C1C0000))
        expect(t, passed[4], Bitmask(0x3838383838380000))
        expect(t, passed[5], Bitmask(0x7070707070700000))
        expect(t, passed[6], Bitmask(0xE0E0E0E0E0E00000))
        expect(t, passed[7], Bitmask(0xC0C0C0C0C0C00000))
}

func TestBitmask010(t *testing.T) { // Black
        passed := [8]Bitmask{0}
        for square := A7; square <= H7; square++ {
                i := square - A7
                if Col(square) > 0 {
                        passed[i].fill(square - 1, -8, 0, 0xFFFFFFFFFFFFFF00)
                }
                passed[i].fill(square, -8, 0, 0xFFFFFFFFFFFFFF00)
                if Col(square) < 7 {
                        passed[i].fill(square + 1, -8, 0, 0xFFFFFFFFFFFFFF00)
                }
        }
        expect(t, passed[0], Bitmask(0x0000030303030303))
        expect(t, passed[1], Bitmask(0x0000070707070707))
        expect(t, passed[2], Bitmask(0x00000E0E0E0E0E0E))
        expect(t, passed[3], Bitmask(0x00001C1C1C1C1C1C))
        expect(t, passed[4], Bitmask(0x0000383838383838))
        expect(t, passed[5], Bitmask(0x0000707070707070))
        expect(t, passed[6], Bitmask(0x0000E0E0E0E0E0E0))
        expect(t, passed[7], Bitmask(0x0000C0C0C0C0C0C0))
}

func TestBitmask030(t *testing.T) { // White
        forward := [8]Bitmask{0}
        for square := A4; square <= H4; square++ {
                i := square - A4
                forward[i].fill(square, 8, 0, 0x00FFFFFFFFFFFFFF)
        }
        expect(t, forward[0], Bitmask(0x0101010100000000))
        expect(t, forward[1], Bitmask(0x0202020200000000))
        expect(t, forward[2], Bitmask(0x0404040400000000))
        expect(t, forward[3], Bitmask(0x0808080800000000))
        expect(t, forward[4], Bitmask(0x1010101000000000))
        expect(t, forward[5], Bitmask(0x2020202000000000))
        expect(t, forward[6], Bitmask(0x4040404000000000))
        expect(t, forward[7], Bitmask(0x8080808000000000))
}

func TestBitmask040(t *testing.T) { // Black
        forward := [8]Bitmask{0}
        for square := A7; square <= H7; square++ {
                i := square - A7
                forward[i].fill(square, -8, 0, 0xFFFFFFFFFFFFFF00)
        }
        expect(t, forward[0], Bitmask(0x0000010101010101))
        expect(t, forward[1], Bitmask(0x0000020202020202))
        expect(t, forward[2], Bitmask(0x0000040404040404))
        expect(t, forward[3], Bitmask(0x0000080808080808))
        expect(t, forward[4], Bitmask(0x0000101010101010))
        expect(t, forward[5], Bitmask(0x0000202020202020))
        expect(t, forward[6], Bitmask(0x0000404040404040))
        expect(t, forward[7], Bitmask(0x0000808080808080))
}

func TestBitmask050(t *testing.T) {
        mask := Bitmask(0x0000000000000001)
        bit := mask.pop()
        expect(t, bit, 0)
        expect(t, mask, Bitmask(0x0000000000000000))

        mask = Bitmask(0x8000000000000000)
        bit = mask.pop()
        expect(t, bit, 63)
        expect(t, mask, Bitmask(0x0000000000000000))
}
<|endoftext|>


<commit_before>package network

import (
	"golang.org/x/time/rate"
	"math"
	"math/rand"
	"time"
)

type Throttler struct {
	limiter   *rate.Limiter
	onBackOff func(int)
}

func NewThrottler(throttleLimit int, onBackOffFn func(int)) Throttler {
	return Throttler{
		limiter:   rate.NewLimiter(rate.Limit(throttleLimit), throttleLimit),
		onBackOff: onBackOffFn,
	}
}

func NewStaticBackoffThrottler(throttleLimit int, backOffDuration time.Duration) Throttler {
	return Throttler{
		limiter:   rate.NewLimiter(rate.Limit(throttleLimit), throttleLimit),
		onBackOff: staticBackoffFn(backOffDuration),
	}
}

func staticBackoffFn(backOffDuration time.Duration) func(attempt int) {
	return func(_ int) {
		time.Sleep(backOffDuration)
	}
}

func NewIncrementalBackoffThrottler(throttleLimit int, backOffDuration time.Duration, incrementDuration time.Duration) Throttler {
	return Throttler{
		limiter:   rate.NewLimiter(rate.Limit(throttleLimit), throttleLimit),
		onBackOff: incrementalBackoffFn(backOffDuration, incrementDuration),
	}
}

func incrementalBackoffFn(backOffDuration time.Duration, incrementDuration time.Duration) func(attempt int) {
	return func(attempt int) {
		sleepMillis := float64(backOffDuration.Milliseconds()) + math.Pow(float64(incrementDuration), float64(attempt))
		time.Sleep(time.Duration(sleepMillis) * time.Millisecond)
	}
}

func NewRandomisedBackoffThrottler(throttleLimit int, minDuration, maxDuration time.Duration) Throttler {
	return Throttler{
		limiter:   rate.NewLimiter(rate.Limit(throttleLimit), throttleLimit),
		onBackOff: randomisedBackoffFn(maxDuration, minDuration),
	}
}

func randomisedBackoffFn(maxDuration time.Duration, minDuration time.Duration) func(attempt int) {
	return func(attempt int) {
		randMillis := (rand.Int63() * (maxDuration.Milliseconds() - minDuration.Milliseconds())) + minDuration.Milliseconds()
		time.Sleep(time.Duration(randMillis) * time.Millisecond)
	}
}

func (t *Throttler) Acquire() {
	attempt := 0
	for {
		if t.limiter.Allow() {
			break
		}

		attempt += 1
		t.onBackOff(attempt)
	}
}
<commit_msg>AV-502 Limit number of outbound connections a node tries to open at once<commit_after>package network

import (
	"golang.org/x/time/rate"
	"math"
	"math/rand"
	"time"
)

type Throttler interface {
	Acquire()
}

type BlockingThrottler struct {
	limiter   *rate.Limiter
	onBackOff func(int)
}

func (t BlockingThrottler) Acquire() {
	attempt := 0
	for {
		if t.limiter.Allow() {
			break
		}

		attempt += 1
		t.onBackOff(attempt)
	}
}

func NewThrottler(throttleLimit int, onBackOffFn func(int)) Throttler {
	return BlockingThrottler{
		limiter:   rate.NewLimiter(rate.Limit(throttleLimit), throttleLimit),
		onBackOff: onBackOffFn,
	}
}

func NewStaticBackoffThrottler(throttleLimit int, backOffDuration time.Duration) Throttler {
	return BlockingThrottler{
		limiter:   rate.NewLimiter(rate.Limit(throttleLimit), throttleLimit),
		onBackOff: staticBackoffFn(backOffDuration),
	}
}

func staticBackoffFn(backOffDuration time.Duration) func(attempt int) {
	return func(_ int) {
		time.Sleep(backOffDuration)
	}
}

func NewIncrementalBackoffThrottler(throttleLimit int, backOffDuration time.Duration, incrementDuration time.Duration) Throttler {
	return BlockingThrottler{
		limiter:   rate.NewLimiter(rate.Limit(throttleLimit), throttleLimit),
		onBackOff: incrementalBackoffFn(backOffDuration, incrementDuration),
	}
}

func incrementalBackoffFn(backOffDuration time.Duration, incrementDuration time.Duration) func(attempt int) {
	return func(attempt int) {
		sleepMillis := float64(backOffDuration.Milliseconds()) + math.Pow(float64(incrementDuration), float64(attempt))
		time.Sleep(time.Duration(sleepMillis) * time.Millisecond)
	}
}

func NewRandomisedBackoffThrottler(throttleLimit int, minDuration, maxDuration time.Duration) Throttler {
	return BlockingThrottler{
		limiter:   rate.NewLimiter(rate.Limit(throttleLimit), throttleLimit),
		onBackOff: randomisedBackoffFn(maxDuration, minDuration),
	}
}

func randomisedBackoffFn(maxDuration time.Duration, minDuration time.Duration) func(attempt int) {
	return func(attempt int) {
		randMillis := (rand.Int63() * (maxDuration.Milliseconds() - minDuration.Milliseconds())) + minDuration.Milliseconds()
		time.Sleep(time.Duration(randMillis) * time.Millisecond)
	}
}
<|endoftext|>


<commit_before><commit_msg>formatted comment<commit_after><|endoftext|>


<commit_before>package stick

import (
	"fmt"
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"unicode"
	"unicode/utf8"

	"github.com/256dpi/xo"
	"github.com/asaskevich/govalidator"
)

// Validatable represents a type that can be validated.
type Validatable interface {
	Validate() error
}

// NoValidation can be embedded in a struct to provide a no-op validation method.
type NoValidation struct{}

// Validate will perform no validation.
func (*NoValidation) Validate() error {
	return nil
}

// ValidationError describes a validation error.
type ValidationError struct {
	Reports []ValidationReport
}

// ValidationReport is a single validation error.
type ValidationReport struct {
	Path  []string
	Error error
}

// Error implements the error interface.
func (e ValidationError) Error() string {
	// prepare errors
	var errs []string
	for _, report := range e.Reports {
		errs = append(errs, fmt.Sprintf("%s: %s", strings.Join(report.Path, "."), report.Error.Error()))
	}

	return strings.Join(errs, "; ")
}

// Validator is used to validate an object.
type Validator struct {
	obj     Accessible
	path    []string
	reports []ValidationReport
}

// Validate will validate the provided accessible using the specified validator
// function.
func Validate(obj Accessible, fn func(v *Validator)) error {
	// prepare validator
	val := &Validator{obj: obj}

	// run validator
	fn(val)

	return val.Error()
}

// Nest nest validation under the specified field.
func (v *Validator) Nest(field string, fn func()) {
	// push
	v.path = append(v.path, field)

	// yield
	fn()

	// pop
	v.path = v.path[:len(v.path)-1]
}

// Value will validate the value at the named field using the provided rules.
// If the value is optional it will be skipped if nil or unwrapped if present.
func (v *Validator) Value(name string, optional bool, rules ...Rule) {
	// get value
	value := MustGet(v.obj, name)

	// prepare context
	ctx := RuleContext{
		IValue: value,
		RValue: reflect.ValueOf(value),
	}

	// handle optionals
	if optional {
		// skip if nil
		if ctx.IsNil() {
			return
		}

		// otherwise unwrap pointer once
		ctx.RValue = ctx.RValue.Elem()
		ctx.IValue = ctx.RValue.Interface()
	}

	// execute rules
	for _, rule := range rules {
		err := rule(ctx)
		if err != nil {
			v.Report(name, err)
		}
	}
}

// Items will validate each item of the slice at the named field using the
// provided rules.
func (v *Validator) Items(name string, rules ...Rule) {
	// get slice
	slice := reflect.ValueOf(MustGet(v.obj, name))

	// execute rules for each item
	v.Nest(name, func() {
		for i := 0; i < slice.Len(); i++ {
			// get item
			item := slice.Index(i)

			// prepare context
			ctx := RuleContext{
				IValue: item.Interface(),
				RValue: item,
			}

			// execute rules
			for _, rule := range rules {
				err := rule(ctx)
				if err != nil {
					v.Report(strconv.Itoa(i), err)
				}
			}
		}
	})
}

// Report will report a validation error.
func (v *Validator) Report(name string, err error) {
	// copy path
	path := append([]string{}, v.path...)
	path = append(path, name)

	// add report
	v.reports = append(v.reports, ValidationReport{
		Path:  path,
		Error: err,
	})
}

// Error will return the accumulated error or nil of no errors have yet been
// reported.
func (v *Validator) Error() error {
	// check errors
	if len(v.reports) > 0 {
		return ValidationError{Reports: v.reports}
	}

	return nil
}

// RuleContext carries the to be checked value.
type RuleContext struct {
	IValue interface{}
	RValue reflect.Value
}

// IsNil returns whether the value is nil.
func (c *RuleContext) IsNil() bool {
	// check plain nil
	if c.IValue == nil {
		return true
	}

	// check typed nils
	switch c.RValue.Kind() {
	case reflect.Ptr, reflect.Slice, reflect.Map:
		return c.RValue.IsNil()
	}

	return false
}

// Unwrap will unwrap all pointers.
func (c *RuleContext) Unwrap() bool {
	// unwrap pointers
	var unwrapped bool
	for c.RValue.Kind() == reflect.Ptr {
		c.RValue = c.RValue.Elem()
		unwrapped = true
	}
	if unwrapped {
		c.IValue = c.RValue.Interface()
	}

	return unwrapped
}

// Guard will run the provided function if a concrete value can be unwrapped.
func (c *RuleContext) Guard(fn func() error) error {
	// check nil
	if c.IsNil() {
		return nil
	}

	// unwrap
	c.Unwrap()

	return fn()
}

// Rule is a single validation rule.
type Rule func(ctx RuleContext) error

// IsOK will run the provided validation function.
func IsOK(fn func() error) Rule {
	return func(RuleContext) error {
		return fn()
	}
}

func isZero(ctx RuleContext) bool {
	// check nil
	if ctx.IsNil() {
		return true
	}

	// check using IsZero method
	type isZero interface {
		IsZero() bool
	}
	if v, ok := ctx.IValue.(isZero); ok {
		// check zeroness
		if !v.IsZero() {
			return false
		}

		return true
	}

	// check using Zero method
	type zero interface {
		Zero() bool
	}
	if v, ok := ctx.IValue.(zero); ok {
		// check zeroness
		if !v.Zero() {
			return false
		}

		return true
	}

	// unwrap pointer and check nil again if unwrapped
	if ctx.Unwrap() && ctx.IsNil() {
		return true
	}

	// check zeroness
	if !ctx.RValue.IsZero() {
		return false
	}

	return true
}

// IsZero will check if the provided value is zero. It will determine zeroness
// using IsZero() or Zero() if implemented and default back to reflect. A nil
// pointer, slice, array or map is also considered as zero.
func IsZero(ctx RuleContext) error {
	// check zeroness
	if !isZero(ctx) {
		return xo.SF("not zero")
	}

	return nil
}

// IsNotZero will check if the provided value is not zero. It will determine
// zeroness using IsZero() or Zero() if implemented and default back to reflect.
// A nil pointer, slice, array or map is also considered as zero.
func IsNotZero(ctx RuleContext) error {
	// check zeroness
	if isZero(ctx) {
		return xo.SF("zero")
	}

	return nil
}

func isEmpty(ctx RuleContext) bool {
	// check nil
	if ctx.IsNil() {
		return true
	}

	// unwrap
	ctx.Unwrap()

	// check array, slice, map and string length
	switch ctx.RValue.Kind() {
	case reflect.Slice, reflect.Map:
		return ctx.RValue.Len() == 0
	}

	panic(fmt.Sprintf("stick: cannot check length of %T", ctx.IValue))
}

// IsEmpty will check if the provided value is empty. Emptiness can only be
// checked for slices and maps.
func IsEmpty(ctx RuleContext) error {
	// check emptiness
	if !isEmpty(ctx) {
		return xo.SF("not empty")
	}

	return nil
}

// IsNotEmpty will check if the provided value is not empty. Emptiness can only
// be checked for slices and maps.
func IsNotEmpty(ctx RuleContext) error {
	// check emptiness
	if isEmpty(ctx) {
		return xo.SF("empty")
	}

	return nil
}

// IsValid will check if the value is valid by calling Validate(), IsValid() or
// Valid().
func IsValid(ctx RuleContext) error {
	// check using Validate() method
	if v, ok := ctx.IValue.(Validatable); ok {
		return v.Validate()
	}

	// check using IsValid() method
	type isValid interface {
		IsValid() bool
	}
	if v, ok := ctx.IValue.(isValid); ok {
		// check validity
		if !v.IsValid() {
			return xo.SF("invalid")
		}

		return nil
	}

	// check using Valid() method
	type valid interface {
		Valid() bool
	}
	if v, ok := ctx.IValue.(valid); ok {
		// check validity
		if !v.Valid() {
			return xo.SF("invalid")
		}

		return nil
	}

	panic(fmt.Sprintf("stick: cannot check validity of %T", ctx.IValue))
}

// IsMinLen checks whether the value has at least the specified length.
func IsMinLen(min int) Rule {
	return func(ctx RuleContext) error {
		return ctx.Guard(func() error {
			// check length
			if ctx.RValue.Len() < min {
				return xo.SF("too short")
			}

			return nil
		})
	}
}

// IsMaxLen checks whether the value does not exceed the specified length.
func IsMaxLen(max int) Rule {
	return func(ctx RuleContext) error {
		// check length
		if ctx.RValue.Len() > max {
			return xo.SF("too long")
		}

		return nil
	}
}

// IsMinInt checks whether the value satisfies the provided minimum.
func IsMinInt(min int64) Rule {
	return func(ctx RuleContext) error {
		return ctx.Guard(func() error {
			// check value
			switch ctx.RValue.Kind() {
			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			default:
				panic("stick: expected int value")
			}

			// check min
			if ctx.RValue.Int() < min {
				return xo.SF("too small")
			}

			return nil
		})
	}
}

// IsMaxInt checks whether the value satisfies the provided maximum.
func IsMaxInt(max int64) Rule {
	return func(ctx RuleContext) error {
		return ctx.Guard(func() error {
			// check value
			switch ctx.RValue.Kind() {
			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			default:
				panic("stick: expected int value")
			}

			// check min
			if ctx.RValue.Int() > max {
				return xo.SF("too big")
			}

			return nil
		})
	}
}

// IsMinUint checks whether the value satisfies the provided minimum.
func IsMinUint(min uint64) Rule {
	return func(ctx RuleContext) error {
		return ctx.Guard(func() error {
			// check value
			switch ctx.RValue.Kind() {
			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			default:
				panic("stick: expected uint value")
			}

			// check range
			if ctx.RValue.Uint() < min {
				return xo.SF("too small")
			}

			return nil
		})
	}
}

// IsMaxUint checks whether the value satisfies the provided maximum.
func IsMaxUint(max uint64) Rule {
	return func(ctx RuleContext) error {
		return ctx.Guard(func() error {
			// check value
			switch ctx.RValue.Kind() {
			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			default:
				panic("stick: expected uint value")
			}

			// check max
			if ctx.RValue.Uint() > max {
				return xo.SF("too big")
			}

			return nil
		})
	}
}

// IsMinFloat checks whether the value satisfies the provided minimum.
func IsMinFloat(min float64) Rule {
	return func(ctx RuleContext) error {
		// check value
		switch ctx.RValue.Kind() {
		case reflect.Float32, reflect.Float64:
		default:
			panic("stick: expected float value")
		}

		// check min
		if ctx.RValue.Float() < min {
			return xo.SF("too small")
		}

		return nil
	}
}

// IsMaxFloat checks whether the value satisfies the provided maximum.
func IsMaxFloat(max float64) Rule {
	return func(ctx RuleContext) error {
		return ctx.Guard(func() error {
			// check value
			switch ctx.RValue.Kind() {
			case reflect.Float32, reflect.Float64:
			default:
				panic("stick: expected float value")
			}

			// check max
			if ctx.RValue.Float() > max {
				return xo.SF("too big")
			}

			return nil
		})
	}
}

// IsFormat will check of the value corresponds to the format determined by the
// provided string format checker.
func IsFormat(fns ...func(string) bool) Rule {
	return func(ctx RuleContext) error {
		return ctx.Guard(func() error {
			// check value
			if ctx.RValue.Kind() != reflect.String {
				panic("stick: expected string value")
			}

			// get string
			str := ctx.RValue.String()

			// check zero
			if str == "" {
				return nil
			}

			// check validity
			for _, fn := range fns {
				if !fn(str) {
					return xo.SF("invalid format")
				}
			}

			return nil
		})
	}
}

// IsRegexMatch will check if a string matches a regular expression.
func IsRegexMatch(reg *regexp.Regexp) Rule {
	return IsFormat(reg.MatchString)
}

// IsPatternMatch will check if a string matches a regular expression pattern.
func IsPatternMatch(pattern string) Rule {
	return IsRegexMatch(regexp.MustCompile(pattern))
}

// IsEmail will check if a string is a valid email.
var IsEmail = IsFormat(govalidator.IsEmail)

// IsURL will check if a string is a valid URL.
var IsURL = IsFormat(govalidator.IsURL)

// IsHost will check if a string is a valid host.
var IsHost = IsFormat(govalidator.IsHost)

// IsDNSName will check if a string is a valid DNS name.
var IsDNSName = IsFormat(govalidator.IsDNSName)

// IsIPAddress will check if a string is a valid IP address.
var IsIPAddress = IsFormat(govalidator.IsIP)

// IsNumeric will check if a string is numeric.
var IsNumeric = IsFormat(govalidator.IsNumeric)

// IsValidUTF8 will check if a string is valid utf8.
var IsValidUTF8 = IsFormat(utf8.ValidString)

// IsVisible will check if a string is visible.
var IsVisible = IsFormat(utf8.ValidString, func(s string) bool {
	// count characters and whitespace
	c := 0
	w := 0
	for _, r := range s {
		c++
		if unicode.IsSpace(r) {
			w++
		}
	}

	return w < c
})
<commit_msg>stick: return safe error<commit_after>package stick

import (
	"fmt"
	"reflect"
	"regexp"
	"strconv"
	"strings"
	"unicode"
	"unicode/utf8"

	"github.com/256dpi/xo"
	"github.com/asaskevich/govalidator"
)

// Validatable represents a type that can be validated.
type Validatable interface {
	Validate() error
}

// NoValidation can be embedded in a struct to provide a no-op validation method.
type NoValidation struct{}

// Validate will perform no validation.
func (*NoValidation) Validate() error {
	return nil
}

// ValidationError describes a validation error.
type ValidationError struct {
	Reports []ValidationReport
}

// ValidationReport is a single validation error.
type ValidationReport struct {
	Path  []string
	Error error
}

// Error implements the error interface.
func (e ValidationError) Error() string {
	// prepare errors
	var errs []string
	for _, report := range e.Reports {
		errs = append(errs, fmt.Sprintf("%s: %s", strings.Join(report.Path, "."), report.Error.Error()))
	}

	return strings.Join(errs, "; ")
}

// Validator is used to validate an object.
type Validator struct {
	obj     Accessible
	path    []string
	reports []ValidationReport
}

// Validate will validate the provided accessible using the specified validator
// function.
func Validate(obj Accessible, fn func(v *Validator)) error {
	// prepare validator
	val := &Validator{obj: obj}

	// run validator
	fn(val)

	return xo.SW(val.Error())
}

// Nest nest validation under the specified field.
func (v *Validator) Nest(field string, fn func()) {
	// push
	v.path = append(v.path, field)

	// yield
	fn()

	// pop
	v.path = v.path[:len(v.path)-1]
}

// Value will validate the value at the named field using the provided rules.
// If the value is optional it will be skipped if nil or unwrapped if present.
func (v *Validator) Value(name string, optional bool, rules ...Rule) {
	// get value
	value := MustGet(v.obj, name)

	// prepare context
	ctx := RuleContext{
		IValue: value,
		RValue: reflect.ValueOf(value),
	}

	// handle optionals
	if optional {
		// skip if nil
		if ctx.IsNil() {
			return
		}

		// otherwise unwrap pointer once
		ctx.RValue = ctx.RValue.Elem()
		ctx.IValue = ctx.RValue.Interface()
	}

	// execute rules
	for _, rule := range rules {
		err := rule(ctx)
		if err != nil {
			v.Report(name, err)
		}
	}
}

// Items will validate each item of the slice at the named field using the
// provided rules.
func (v *Validator) Items(name string, rules ...Rule) {
	// get slice
	slice := reflect.ValueOf(MustGet(v.obj, name))

	// execute rules for each item
	v.Nest(name, func() {
		for i := 0; i < slice.Len(); i++ {
			// get item
			item := slice.Index(i)

			// prepare context
			ctx := RuleContext{
				IValue: item.Interface(),
				RValue: item,
			}

			// execute rules
			for _, rule := range rules {
				err := rule(ctx)
				if err != nil {
					v.Report(strconv.Itoa(i), err)
				}
			}
		}
	})
}

// Report will report a validation error.
func (v *Validator) Report(name string, err error) {
	// copy path
	path := append([]string{}, v.path...)
	path = append(path, name)

	// add report
	v.reports = append(v.reports, ValidationReport{
		Path:  path,
		Error: err,
	})
}

// Error will return the accumulated error or nil of no errors have yet been
// reported.
func (v *Validator) Error() error {
	// check errors
	if len(v.reports) > 0 {
		return ValidationError{Reports: v.reports}
	}

	return nil
}

// RuleContext carries the to be checked value.
type RuleContext struct {
	IValue interface{}
	RValue reflect.Value
}

// IsNil returns whether the value is nil.
func (c *RuleContext) IsNil() bool {
	// check plain nil
	if c.IValue == nil {
		return true
	}

	// check typed nils
	switch c.RValue.Kind() {
	case reflect.Ptr, reflect.Slice, reflect.Map:
		return c.RValue.IsNil()
	}

	return false
}

// Unwrap will unwrap all pointers.
func (c *RuleContext) Unwrap() bool {
	// unwrap pointers
	var unwrapped bool
	for c.RValue.Kind() == reflect.Ptr {
		c.RValue = c.RValue.Elem()
		unwrapped = true
	}
	if unwrapped {
		c.IValue = c.RValue.Interface()
	}

	return unwrapped
}

// Guard will run the provided function if a concrete value can be unwrapped.
func (c *RuleContext) Guard(fn func() error) error {
	// check nil
	if c.IsNil() {
		return nil
	}

	// unwrap
	c.Unwrap()

	return fn()
}

// Rule is a single validation rule.
type Rule func(ctx RuleContext) error

// IsOK will run the provided validation function.
func IsOK(fn func() error) Rule {
	return func(RuleContext) error {
		return fn()
	}
}

func isZero(ctx RuleContext) bool {
	// check nil
	if ctx.IsNil() {
		return true
	}

	// check using IsZero method
	type isZero interface {
		IsZero() bool
	}
	if v, ok := ctx.IValue.(isZero); ok {
		// check zeroness
		if !v.IsZero() {
			return false
		}

		return true
	}

	// check using Zero method
	type zero interface {
		Zero() bool
	}
	if v, ok := ctx.IValue.(zero); ok {
		// check zeroness
		if !v.Zero() {
			return false
		}

		return true
	}

	// unwrap pointer and check nil again if unwrapped
	if ctx.Unwrap() && ctx.IsNil() {
		return true
	}

	// check zeroness
	if !ctx.RValue.IsZero() {
		return false
	}

	return true
}

// IsZero will check if the provided value is zero. It will determine zeroness
// using IsZero() or Zero() if implemented and default back to reflect. A nil
// pointer, slice, array or map is also considered as zero.
func IsZero(ctx RuleContext) error {
	// check zeroness
	if !isZero(ctx) {
		return xo.SF("not zero")
	}

	return nil
}

// IsNotZero will check if the provided value is not zero. It will determine
// zeroness using IsZero() or Zero() if implemented and default back to reflect.
// A nil pointer, slice, array or map is also considered as zero.
func IsNotZero(ctx RuleContext) error {
	// check zeroness
	if isZero(ctx) {
		return xo.SF("zero")
	}

	return nil
}

func isEmpty(ctx RuleContext) bool {
	// check nil
	if ctx.IsNil() {
		return true
	}

	// unwrap
	ctx.Unwrap()

	// check array, slice, map and string length
	switch ctx.RValue.Kind() {
	case reflect.Slice, reflect.Map:
		return ctx.RValue.Len() == 0
	}

	panic(fmt.Sprintf("stick: cannot check length of %T", ctx.IValue))
}

// IsEmpty will check if the provided value is empty. Emptiness can only be
// checked for slices and maps.
func IsEmpty(ctx RuleContext) error {
	// check emptiness
	if !isEmpty(ctx) {
		return xo.SF("not empty")
	}

	return nil
}

// IsNotEmpty will check if the provided value is not empty. Emptiness can only
// be checked for slices and maps.
func IsNotEmpty(ctx RuleContext) error {
	// check emptiness
	if isEmpty(ctx) {
		return xo.SF("empty")
	}

	return nil
}

// IsValid will check if the value is valid by calling Validate(), IsValid() or
// Valid().
func IsValid(ctx RuleContext) error {
	// check using Validate() method
	if v, ok := ctx.IValue.(Validatable); ok {
		return v.Validate()
	}

	// check using IsValid() method
	type isValid interface {
		IsValid() bool
	}
	if v, ok := ctx.IValue.(isValid); ok {
		// check validity
		if !v.IsValid() {
			return xo.SF("invalid")
		}

		return nil
	}

	// check using Valid() method
	type valid interface {
		Valid() bool
	}
	if v, ok := ctx.IValue.(valid); ok {
		// check validity
		if !v.Valid() {
			return xo.SF("invalid")
		}

		return nil
	}

	panic(fmt.Sprintf("stick: cannot check validity of %T", ctx.IValue))
}

// IsMinLen checks whether the value has at least the specified length.
func IsMinLen(min int) Rule {
	return func(ctx RuleContext) error {
		return ctx.Guard(func() error {
			// check length
			if ctx.RValue.Len() < min {
				return xo.SF("too short")
			}

			return nil
		})
	}
}

// IsMaxLen checks whether the value does not exceed the specified length.
func IsMaxLen(max int) Rule {
	return func(ctx RuleContext) error {
		// check length
		if ctx.RValue.Len() > max {
			return xo.SF("too long")
		}

		return nil
	}
}

// IsMinInt checks whether the value satisfies the provided minimum.
func IsMinInt(min int64) Rule {
	return func(ctx RuleContext) error {
		return ctx.Guard(func() error {
			// check value
			switch ctx.RValue.Kind() {
			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			default:
				panic("stick: expected int value")
			}

			// check min
			if ctx.RValue.Int() < min {
				return xo.SF("too small")
			}

			return nil
		})
	}
}

// IsMaxInt checks whether the value satisfies the provided maximum.
func IsMaxInt(max int64) Rule {
	return func(ctx RuleContext) error {
		return ctx.Guard(func() error {
			// check value
			switch ctx.RValue.Kind() {
			case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			default:
				panic("stick: expected int value")
			}

			// check min
			if ctx.RValue.Int() > max {
				return xo.SF("too big")
			}

			return nil
		})
	}
}

// IsMinUint checks whether the value satisfies the provided minimum.
func IsMinUint(min uint64) Rule {
	return func(ctx RuleContext) error {
		return ctx.Guard(func() error {
			// check value
			switch ctx.RValue.Kind() {
			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			default:
				panic("stick: expected uint value")
			}

			// check range
			if ctx.RValue.Uint() < min {
				return xo.SF("too small")
			}

			return nil
		})
	}
}

// IsMaxUint checks whether the value satisfies the provided maximum.
func IsMaxUint(max uint64) Rule {
	return func(ctx RuleContext) error {
		return ctx.Guard(func() error {
			// check value
			switch ctx.RValue.Kind() {
			case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			default:
				panic("stick: expected uint value")
			}

			// check max
			if ctx.RValue.Uint() > max {
				return xo.SF("too big")
			}

			return nil
		})
	}
}

// IsMinFloat checks whether the value satisfies the provided minimum.
func IsMinFloat(min float64) Rule {
	return func(ctx RuleContext) error {
		// check value
		switch ctx.RValue.Kind() {
		case reflect.Float32, reflect.Float64:
		default:
			panic("stick: expected float value")
		}

		// check min
		if ctx.RValue.Float() < min {
			return xo.SF("too small")
		}

		return nil
	}
}

// IsMaxFloat checks whether the value satisfies the provided maximum.
func IsMaxFloat(max float64) Rule {
	return func(ctx RuleContext) error {
		return ctx.Guard(func() error {
			// check value
			switch ctx.RValue.Kind() {
			case reflect.Float32, reflect.Float64:
			default:
				panic("stick: expected float value")
			}

			// check max
			if ctx.RValue.Float() > max {
				return xo.SF("too big")
			}

			return nil
		})
	}
}

// IsFormat will check of the value corresponds to the format determined by the
// provided string format checker.
func IsFormat(fns ...func(string) bool) Rule {
	return func(ctx RuleContext) error {
		return ctx.Guard(func() error {
			// check value
			if ctx.RValue.Kind() != reflect.String {
				panic("stick: expected string value")
			}

			// get string
			str := ctx.RValue.String()

			// check zero
			if str == "" {
				return nil
			}

			// check validity
			for _, fn := range fns {
				if !fn(str) {
					return xo.SF("invalid format")
				}
			}

			return nil
		})
	}
}

// IsRegexMatch will check if a string matches a regular expression.
func IsRegexMatch(reg *regexp.Regexp) Rule {
	return IsFormat(reg.MatchString)
}

// IsPatternMatch will check if a string matches a regular expression pattern.
func IsPatternMatch(pattern string) Rule {
	return IsRegexMatch(regexp.MustCompile(pattern))
}

// IsEmail will check if a string is a valid email.
var IsEmail = IsFormat(govalidator.IsEmail)

// IsURL will check if a string is a valid URL.
var IsURL = IsFormat(govalidator.IsURL)

// IsHost will check if a string is a valid host.
var IsHost = IsFormat(govalidator.IsHost)

// IsDNSName will check if a string is a valid DNS name.
var IsDNSName = IsFormat(govalidator.IsDNSName)

// IsIPAddress will check if a string is a valid IP address.
var IsIPAddress = IsFormat(govalidator.IsIP)

// IsNumeric will check if a string is numeric.
var IsNumeric = IsFormat(govalidator.IsNumeric)

// IsValidUTF8 will check if a string is valid utf8.
var IsValidUTF8 = IsFormat(utf8.ValidString)

// IsVisible will check if a string is visible.
var IsVisible = IsFormat(utf8.ValidString, func(s string) bool {
	// count characters and whitespace
	c := 0
	w := 0
	for _, r := range s {
		c++
		if unicode.IsSpace(r) {
			w++
		}
	}

	return w < c
})
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/4ydx/gltext"
	"github.com/4ydx/gltext/v4.1"
	"github.com/go-gl/gl/v4.1-core/gl"
	"github.com/go-gl/glfw/v3.2/glfw"
	"github.com/go-gl/mathgl/mgl32"
	"golang.org/x/image/math/fixed"
	"math"
	"os"
	"runtime"
	"time"
)

var useStrictCoreProfile = (runtime.GOOS == "darwin")

func main() {
	runtime.LockOSThread()

	err := glfw.Init()
	if err != nil {
		panic("glfw error")
	}
	defer glfw.Terminate()

	glfw.WindowHint(glfw.Resizable, glfw.False)
	glfw.WindowHint(glfw.ContextVersionMajor, 3)
	glfw.WindowHint(glfw.ContextVersionMinor, 3)
	if useStrictCoreProfile {
		glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True)
		glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
	}
	glfw.WindowHint(glfw.OpenGLDebugContext, glfw.True)

	window, err := glfw.CreateWindow(640, 480, "Testing", nil, nil)
	if err != nil {
		panic(err)
	}
	window.MakeContextCurrent()
	if err := gl.Init(); err != nil {
		panic(err)
	}
	version := gl.GoStr(gl.GetString(gl.VERSION))
	fmt.Println("Opengl version", version)

	// code from here
	gltext.IsDebug = false

	var font *v41.Font
	config, err := gltext.LoadTruetypeFontConfig("fontconfigs")
	if err == nil {
		font, err = v41.NewFont(config)
		if err != nil {
			panic(err)
		}
		fmt.Println("Font loaded from disk...")
	} else {
		fd, err := os.Open("font/font_1_honokamin.ttf")
		if err != nil {
			panic(err)
		}
		defer fd.Close()

		// Japanese character ranges
		// http://www.rikai.com/library/kanjitables/kanji_codes.unicode.shtml
		runeRanges := make(gltext.RuneRanges, 0)
		runeRanges = append(runeRanges, gltext.RuneRange{Low: 0x3000, High: 0x3030})
		runeRanges = append(runeRanges, gltext.RuneRange{Low: 0x3040, High: 0x309f})
		runeRanges = append(runeRanges, gltext.RuneRange{Low: 0x30a0, High: 0x30ff})
		runeRanges = append(runeRanges, gltext.RuneRange{Low: 0x4e00, High: 0x9faf})
		runeRanges = append(runeRanges, gltext.RuneRange{Low: 0xff00, High: 0xffef})

		scale := fixed.Int26_6(24)
		runesPerRow := fixed.Int26_6(128)
		config, err = gltext.NewTruetypeFontConfig(fd, scale, runeRanges, runesPerRow)
		if err != nil {
			panic(err)
		}
		font, err = v41.NewFont(config)
		if err != nil {
			panic(err)
		}
		err = config.Save("fontconfigs")
		if err != nil {
			panic(err)
		}
	}

	width, height := window.GetSize()
	font.ResizeWindow(float32(width), float32(height))

	scaleMin, scaleMax := float32(1.0), float32(1.1)
	text := v41.NewText(font, scaleMin, scaleMax)
	str := "梅干しが大好き。ウメボシガダイスキ。"
	for _, s := range str {
		fmt.Printf("%c: %d\n", s, rune(s))
	}
	text.SetString(str)
	text.SetColor(mgl32.Vec3{1, 1, 1})
	text.FadeOutPerFrame = 0.01

	i := 0
	start := time.Now()

	gl.ClearColor(0.4, 0.4, 0.4, 0.0)
	for !window.ShouldClose() {
		gl.Clear(gl.COLOR_BUFFER_BIT)

		// Position can be set freely
		text.SetPosition(mgl32.Vec2{0, float32(i)})
		i++
		if i > 200 {
			i = -200
		}
		text.Draw()

		// just for illustrative purposes
		// i imagine that user interaction of some sort will trigger these rather than a moment in time

		// fade out
		if math.Floor(time.Now().Sub(start).Seconds()) == 5 {
			text.BeginFadeOut()
		}

		// show text
		if math.Floor(time.Now().Sub(start).Seconds()) == 10 {
			text.Show()
		}

		// hide
		if math.Floor(time.Now().Sub(start).Seconds()) == 15 {
			text.Hide()
		}

		window.SwapBuffers()
		glfw.PollEvents()
	}
	text.Release()
	font.Release()
}
<commit_msg>Reorder.<commit_after>package main

import (
	"fmt"
	"github.com/4ydx/gltext"
	"github.com/4ydx/gltext/v4.1"
	"github.com/go-gl/gl/v4.1-core/gl"
	"github.com/go-gl/glfw/v3.2/glfw"
	"github.com/go-gl/mathgl/mgl32"
	"golang.org/x/image/math/fixed"
	"math"
	"os"
	"runtime"
	"time"
)

var useStrictCoreProfile = (runtime.GOOS == "darwin")

func main() {
	runtime.LockOSThread()

	err := glfw.Init()
	if err != nil {
		panic("glfw error")
	}
	defer glfw.Terminate()

	glfw.WindowHint(glfw.Resizable, glfw.False)
	glfw.WindowHint(glfw.ContextVersionMajor, 3)
	glfw.WindowHint(glfw.ContextVersionMinor, 3)
	if useStrictCoreProfile {
		glfw.WindowHint(glfw.OpenGLForwardCompatible, glfw.True)
		glfw.WindowHint(glfw.OpenGLProfile, glfw.OpenGLCoreProfile)
	}
	glfw.WindowHint(glfw.OpenGLDebugContext, glfw.True)

	window, err := glfw.CreateWindow(640, 480, "Testing", nil, nil)
	if err != nil {
		panic(err)
	}
	window.MakeContextCurrent()
	if err := gl.Init(); err != nil {
		panic(err)
	}
	version := gl.GoStr(gl.GetString(gl.VERSION))
	fmt.Println("Opengl version", version)

	// code from here
	gltext.IsDebug = false

	var font *v41.Font
	config, err := gltext.LoadTruetypeFontConfig("fontconfigs")
	if err == nil {
		font, err = v41.NewFont(config)
		if err != nil {
			panic(err)
		}
		fmt.Println("Font loaded from disk...")
	} else {
		fd, err := os.Open("font/font_1_honokamin.ttf")
		if err != nil {
			panic(err)
		}
		defer fd.Close()

		// Japanese character ranges
		// http://www.rikai.com/library/kanjitables/kanji_codes.unicode.shtml
		runeRanges := make(gltext.RuneRanges, 0)
		runeRanges = append(runeRanges, gltext.RuneRange{Low: 0x3000, High: 0x3030})
		runeRanges = append(runeRanges, gltext.RuneRange{Low: 0x3040, High: 0x309f})
		runeRanges = append(runeRanges, gltext.RuneRange{Low: 0x30a0, High: 0x30ff})
		runeRanges = append(runeRanges, gltext.RuneRange{Low: 0x4e00, High: 0x9faf})
		runeRanges = append(runeRanges, gltext.RuneRange{Low: 0xff00, High: 0xffef})

		scale := fixed.Int26_6(24)
		runesPerRow := fixed.Int26_6(128)
		config, err = gltext.NewTruetypeFontConfig(fd, scale, runeRanges, runesPerRow)
		if err != nil {
			panic(err)
		}
		err = config.Save("fontconfigs")
		if err != nil {
			panic(err)
		}
		font, err = v41.NewFont(config)
		if err != nil {
			panic(err)
		}
	}

	width, height := window.GetSize()
	font.ResizeWindow(float32(width), float32(height))

	scaleMin, scaleMax := float32(1.0), float32(1.1)
	text := v41.NewText(font, scaleMin, scaleMax)
	str := "梅干しが大好き。ウメボシガダイスキ。"
	for _, s := range str {
		fmt.Printf("%c: %d\n", s, rune(s))
	}
	text.SetString(str)
	text.SetColor(mgl32.Vec3{1, 1, 1})
	text.FadeOutPerFrame = 0.01

	i := 0
	start := time.Now()

	gl.ClearColor(0.4, 0.4, 0.4, 0.0)
	for !window.ShouldClose() {
		gl.Clear(gl.COLOR_BUFFER_BIT)

		// Position can be set freely
		text.SetPosition(mgl32.Vec2{0, float32(i)})
		i++
		if i > 200 {
			i = -200
		}
		text.Draw()

		// just for illustrative purposes
		// i imagine that user interaction of some sort will trigger these rather than a moment in time

		// fade out
		if math.Floor(time.Now().Sub(start).Seconds()) == 5 {
			text.BeginFadeOut()
		}

		// show text
		if math.Floor(time.Now().Sub(start).Seconds()) == 10 {
			text.Show()
		}

		// hide
		if math.Floor(time.Now().Sub(start).Seconds()) == 15 {
			text.Hide()
		}

		window.SwapBuffers()
		glfw.PollEvents()
	}
	text.Release()
	font.Release()
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"time"
)

type DailyData struct {
	stock_no string
	date     time.Time
}

func (d *DailyData) Url() string {
	return fmt.Sprintf(TWSECSV, d.date.Year(), d.date.Month(), d.stock_no, d.date.UnixNano())
}

func main() {
	d := &DailyData{
		stock_no: "2618",
		date:     time.Now(),
	}

	fmt.Println(d.Url())
}
<commit_msg>Add Round.<commit_after>package main

import (
	"fmt"
	"time"
)

type DailyData struct {
	stock_no string
	date     time.Time
}

func (d *DailyData) Url() string {
	return fmt.Sprintf(TWSECSV, d.date.Year(), d.date.Month(), d.stock_no, d.date.UnixNano())
}

func (d *DailyData) Round() {
	year, month, day := d.date.Date()
	d.date = time.Date(year, month-1, day, 0, 0, 0, 0, time.UTC)
}

func main() {
	d := &DailyData{
		stock_no: "2618",
		date:     time.Now(),
	}

	fmt.Println(d.Url())
	d.Round()
	fmt.Println(d.Url())
	d.Round()
	fmt.Println(d.Url())
	d.Round()
	fmt.Println(d.Url())
	d.Round()
	fmt.Println(d.Url())
	d.Round()
	fmt.Println(d.Url())
	d.Round()
	fmt.Println(d.Url())
	d.Round()
	fmt.Println(d.Url())
	d.Round()
	fmt.Println(d.Url())
	d.Round()
	fmt.Println(d.Url())
	d.Round()
	fmt.Println(d.Url())
	d.Round()
	fmt.Println(d.Url())
	d.Round()
	fmt.Println(d.Url())
}
<|endoftext|>


<commit_before>package gogrs

import (
	"encoding/csv"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"regexp"
	"strconv"
	"strings"
	"time"
)

type memData map[int64][][]string

// DailyData start with stock no, date.
type DailyData struct {
	No      string
	Date    time.Time
	RawData [][]string
	hasData memData
}

// URL return stock csv url path.
func (d DailyData) URL() string {
	path := fmt.Sprintf(TWSECSV, d.Date.Year(), d.Date.Month(), d.Date.Year(), d.Date.Month(), d.No, RandInt())
	return fmt.Sprintf("%s%s", TWSEHOST, path)
}

// Round will do sub one month.
func (d *DailyData) Round() {
	year, month, _ := d.Date.Date()
	d.Date = time.Date(year, month-1, 1, 0, 0, 0, 0, time.UTC)
}

// GetData return csv data in array.
func (d *DailyData) GetData() ([][]string, error) {
	if d.hasData == nil {
		d.hasData = make(memData)
	}
	if len(d.hasData[d.Date.Unix()]) == 0 {
		csvFiles, err := http.Get(d.URL())
		if err != nil {
			fmt.Println("[err] >>> ", err)
			return nil, err
		}
		defer csvFiles.Body.Close()
		data, _ := ioutil.ReadAll(csvFiles.Body)
		csvArrayContent := strings.Split(string(data), "\n")
		for i := range csvArrayContent {
			csvArrayContent[i] = strings.TrimSpace(csvArrayContent[i])
		}
		if len(csvArrayContent) > 2 {
			csvReader := csv.NewReader(strings.NewReader(strings.Join(csvArrayContent[2:], "\n")))
			allData, err := csvReader.ReadAll()
			d.RawData = append(allData, d.RawData...)
			d.hasData[d.Date.Unix()] = allData
			return allData, err
		}
		return nil, errors.New("Not enough data.")
	}
	return d.hasData[d.Date.Unix()], nil
}

func (d DailyData) GetDataMap() map[time.Time]interface{} {
	data := make(map[time.Time]interface{})
	dailyData, _ := d.GetData()
	for _, v := range dailyData {
		data[parseDate(v[0])] = v
	}
	return data
}

type FmtDailyData struct {
	Date       time.Time
	Volume     uint64
	TotalPrice uint64
	Open       float64
	High       float64
	Low        float64
	Price      float64
	Range      float64
	Totalsale  uint64
}

var dateReg = regexp.MustCompile(`[\d]{2,}`)

func parseDate(strDate string) time.Time {
	p := dateReg.FindAllString(strDate, -1)
	year, _ := strconv.Atoi(p[0])
	mon, _ := strconv.Atoi(p[1])
	day, _ := strconv.Atoi(p[2])
	return time.Date(year+1911, time.Month(mon), day, 0, 0, 0, 0, time.Local)
}

func (d DailyData) FormatDailyData() {
	for _, v := range d.RawData {
		var d FmtDailyData
		d.Date = parseDate(v[0])

		volume, _ := strconv.ParseUint(strings.Replace(v[1], ",", "", -1), 10, 32)
		d.Volume = volume

		totalprice, _ := strconv.ParseUint(strings.Replace(v[2], ",", "", -1), 10, 32)
		d.TotalPrice = totalprice

		open, _ := strconv.ParseFloat(v[3], 64)
		d.Open = open

		high, _ := strconv.ParseFloat(v[4], 64)
		d.High = high

		low, _ := strconv.ParseFloat(v[5], 64)
		d.Low = low

		price, _ := strconv.ParseFloat(v[6], 64)
		d.Price = price

		range_, _ := strconv.ParseFloat(v[7], 64)
		d.Range = range_

		totalsale, _ := strconv.ParseUint(strings.Replace(v[8], ",", "", -1), 10, 64)
		d.Totalsale = totalsale

		fmt.Println(d)
	}
}
<commit_msg>Naming.<commit_after>package gogrs

import (
	"encoding/csv"
	"errors"
	"fmt"
	"io/ioutil"
	"net/http"
	"regexp"
	"strconv"
	"strings"
	"time"
)

type memData map[int64][][]string

// DailyData start with stock no, date.
type DailyData struct {
	No      string
	Date    time.Time
	RawData [][]string
	hasData memData
}

// URL return stock csv url path.
func (d DailyData) URL() string {
	path := fmt.Sprintf(TWSECSV, d.Date.Year(), d.Date.Month(), d.Date.Year(), d.Date.Month(), d.No, RandInt())
	return fmt.Sprintf("%s%s", TWSEHOST, path)
}

// Round will do sub one month.
func (d *DailyData) Round() {
	year, month, _ := d.Date.Date()
	d.Date = time.Date(year, month-1, 1, 0, 0, 0, 0, time.UTC)
}

// GetData return csv data in array.
func (d *DailyData) GetData() ([][]string, error) {
	if d.hasData == nil {
		d.hasData = make(memData)
	}
	if len(d.hasData[d.Date.Unix()]) == 0 {
		csvFiles, err := http.Get(d.URL())
		if err != nil {
			fmt.Println("[err] >>> ", err)
			return nil, err
		}
		defer csvFiles.Body.Close()
		data, _ := ioutil.ReadAll(csvFiles.Body)
		csvArrayContent := strings.Split(string(data), "\n")
		for i := range csvArrayContent {
			csvArrayContent[i] = strings.TrimSpace(csvArrayContent[i])
		}
		if len(csvArrayContent) > 2 {
			csvReader := csv.NewReader(strings.NewReader(strings.Join(csvArrayContent[2:], "\n")))
			allData, err := csvReader.ReadAll()
			d.RawData = append(allData, d.RawData...)
			d.hasData[d.Date.Unix()] = allData
			return allData, err
		}
		return nil, errors.New("Not enough data.")
	}
	return d.hasData[d.Date.Unix()], nil
}

func (d DailyData) GetDataMap() map[time.Time]interface{} {
	data := make(map[time.Time]interface{})
	dailyData, _ := d.GetData()
	for _, v := range dailyData {
		data[parseDate(v[0])] = v
	}
	return data
}

type FmtDailyData struct {
	Date       time.Time
	Volume     uint64
	TotalPrice uint64
	Open       float64
	High       float64
	Low        float64
	Price      float64
	Range      float64
	Totalsale  uint64
}

var dateReg = regexp.MustCompile(`[\d]{2,}`)

func parseDate(strDate string) time.Time {
	p := dateReg.FindAllString(strDate, -1)
	year, _ := strconv.Atoi(p[0])
	mon, _ := strconv.Atoi(p[1])
	day, _ := strconv.Atoi(p[2])
	return time.Date(year+1911, time.Month(mon), day, 0, 0, 0, 0, time.Local)
}

func (d DailyData) FormatDailyData() {
	for _, v := range d.RawData {
		var d FmtDailyData
		d.Date = parseDate(v[0])

		volume, _ := strconv.ParseUint(strings.Replace(v[1], ",", "", -1), 10, 32)
		d.Volume = volume

		totalprice, _ := strconv.ParseUint(strings.Replace(v[2], ",", "", -1), 10, 32)
		d.TotalPrice = totalprice

		open, _ := strconv.ParseFloat(v[3], 64)
		d.Open = open

		high, _ := strconv.ParseFloat(v[4], 64)
		d.High = high

		low, _ := strconv.ParseFloat(v[5], 64)
		d.Low = low

		price, _ := strconv.ParseFloat(v[6], 64)
		d.Price = price

		rangeData, _ := strconv.ParseFloat(v[7], 64)
		d.Range = rangeData

		totalsale, _ := strconv.ParseUint(strings.Replace(v[8], ",", "", -1), 10, 64)
		d.Totalsale = totalsale

		fmt.Println(d)
	}
}
<|endoftext|>


<commit_before>package kvlog_test

import (
	"bytes"
	"fmt"

	log "github.com/Sirupsen/logrus"
	"github.com/gwatts/kvlog"
)

func Example() {
	var buf bytes.Buffer

	log.SetOutput(&buf)
	log.SetFormatter(
		kvlog.New(
			kvlog.IncludeCaller(),
			kvlog.WithPrimaryFields("action", "status")))

	log.WithFields(log.Fields{
		"action":          "user_login",
		"status":          "ok",
		"username":        "joe_user",
		"email":           "joe@example.com",
		"active_sessions": 4,
	}).Info("User logged in")

	// replace the timestamp so the output is consistent
	output := "2017-01-02T12:00:00.000Z " + buf.String()[25:]
	fmt.Println(output)

	// Output: 2017-01-02T12:00:00.000Z ll="info" srcfnc="Example" srcline=29 action="user_login" status="ok" active_sessions=4 email="joe@example.com" username="joe_user" _msg="User logged in"
}
<commit_msg>Make test less sensitive to line numbers<commit_after>package kvlog_test

import (
	"bytes"
	"fmt"
	"regexp"

	log "github.com/Sirupsen/logrus"
	"github.com/gwatts/kvlog"
)

func Example() {
	var buf bytes.Buffer

	log.SetOutput(&buf)
	log.SetFormatter(
		kvlog.New(
			kvlog.IncludeCaller(),
			kvlog.WithPrimaryFields("action", "status")))

	log.WithFields(log.Fields{
		"action":          "user_login",
		"status":          "ok",
		"username":        "joe_user",
		"email":           "joe@example.com",
		"active_sessions": 4,
	}).Info("User logged in")

	// replace the timestamp so the output is consistent
	output := "2017-01-02T12:00:00.000Z " + buf.String()[25:]

	// replace srcline so tests aren't sensitive to exact line number
	output = regexp.MustCompile(`srcline=\d+`).ReplaceAllLiteralString(output, `srcline=100`)

	fmt.Println(output)
	// Output: 2017-01-02T12:00:00.000Z ll="info" srcfnc="Example" srcline=100 action="user_login" status="ok" active_sessions=4 email="joe@example.com" username="joe_user" _msg="User logged in"
}
<|endoftext|>


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

package apd_test

import (
	"fmt"

	"github.com/cockroachdb/apd"
)

// ExampleOverflow demonstrates how to detect or error on overflow.
func ExampleContext_overflow() {
	// Create a context that will overflow at 1e3.
	c := apd.Context{
		MaxExponent: 2,
		Traps:       apd.Overflow,
	}
	one := apd.New(1, 0)
	d := apd.New(997, 0)
	for {
		res, err := c.Add(d, d, one)
		fmt.Printf("d: %8s, overflow: %5v, err: %v\n", d, res.Overflow(), err)
		if err != nil {
			return
		}
	}
	// Output: d:      998, overflow: false, err: <nil>
	// d:      999, overflow: false, err: <nil>
	// d: Infinity, overflow:  true, err: overflow
}

// ExampleInexact demonstrates how to detect inexact operations.
func ExampleContext_inexact() {
	d := apd.New(27, 0)
	three := apd.New(3, 0)
	c := apd.BaseContext.WithPrecision(5)
	for {
		res, err := c.Quo(d, d, three)
		fmt.Printf("d: %7s, inexact: %5v, err: %v\n", d, res.Inexact(), err)
		if err != nil {
			return
		}
		if res.Inexact() {
			return
		}
	}
	// Output: d:       9, inexact: false, err: <nil>
	// d:       3, inexact: false, err: <nil>
	// d:       1, inexact: false, err: <nil>
	// d: 0.33333, inexact:  true, err: <nil>
}

func ExampleContext_Quantize() {
	input, _, _ := apd.NewFromString("123.45")
	output := new(apd.Decimal)
	c := apd.BaseContext.WithPrecision(10)
	for i := int32(-3); i <= 3; i++ {
		res, _ := c.Quantize(output, input, i)
		fmt.Printf("%2v: %s", i, output)
		if res != 0 {
			fmt.Printf(" (%s)", res)
		}
		fmt.Println()
	}
	// Output: -3: 123.450
	// -2: 123.45
	// -1: 123.5 (inexact, rounded)
	//  0: 123 (inexact, rounded)
	//  1: 1.2E+2 (inexact, rounded)
	//  2: 1E+2 (inexact, rounded)
	//  3: 0E+3 (inexact, rounded)
}

func ExampleErrDecimal() {
	c := apd.BaseContext.WithPrecision(5)
	ed := apd.MakeErrDecimal(c)
	d := apd.New(10, 0)
	fmt.Printf("%s, err: %v\n", d, ed.Err())
	ed.Add(d, d, apd.New(2, 1)) // add 20
	fmt.Printf("%s, err: %v\n", d, ed.Err())
	ed.Quo(d, d, apd.New(0, 0)) // divide by zero
	fmt.Printf("%s, err: %v\n", d, ed.Err())
	ed.Sub(d, d, apd.New(1, 0)) // attempt to subtract 1
	// The subtraction doesn't occur and doesn't change the error.
	fmt.Printf("%s, err: %v\n", d, ed.Err())
	// Output: 10, err: <nil>
	// 30, err: <nil>
	// Infinity, err: division by zero
	// Infinity, err: division by zero
}

// ExampleToIntegralX demonstrates how to use ToIntegralX to check if a
// number is an integer or not. Note the variations between integer (which
// allows zeros after the decimal point) and strict (which does not). See
// the documentation on Inexact and Rounded.
func ExampleContext_ToIntegralX() {
	inputs := []string{
		"123.4",
		"123.0",
		"123",
		"12E1",
		"120E-1",
		"120E-2",
	}
	for _, input := range inputs {
		d, _, _ := apd.NewFromString(input)
		res, _ := apd.BaseContext.ToIntegralX(d, d)
		integer := !res.Inexact()
		strict := !res.Rounded()
		fmt.Printf("input: % 6s, ToIntegralX: % 3s, integer: % 5t, strict: % 5t, res:", input, d, integer, strict)
		if res != 0 {
			fmt.Printf(" %s", res)
		}
		fmt.Println()
	}
	// Output: input:  123.4, ToIntegralX: 123, integer: false, strict: false, res: inexact, rounded
	// input:  123.0, ToIntegralX: 123, integer:  true, strict: false, res: rounded
	// input:    123, ToIntegralX: 123, integer:  true, strict:  true, res:
	// input:   12E1, ToIntegralX: 120, integer:  true, strict:  true, res:
	// input: 120E-1, ToIntegralX:  12, integer:  true, strict: false, res: rounded
	// input: 120E-2, ToIntegralX:   1, integer: false, strict: false, res: inexact, rounded
}
<commit_msg>remove unsupported ' ' flag of %t<commit_after>// Copyright 2016 The Cockroach Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
// implied. See the License for the specific language governing
// permissions and limitations under the License.

package apd_test

import (
	"fmt"

	"github.com/cockroachdb/apd"
)

// ExampleOverflow demonstrates how to detect or error on overflow.
func ExampleContext_overflow() {
	// Create a context that will overflow at 1e3.
	c := apd.Context{
		MaxExponent: 2,
		Traps:       apd.Overflow,
	}
	one := apd.New(1, 0)
	d := apd.New(997, 0)
	for {
		res, err := c.Add(d, d, one)
		fmt.Printf("d: %8s, overflow: %5v, err: %v\n", d, res.Overflow(), err)
		if err != nil {
			return
		}
	}
	// Output: d:      998, overflow: false, err: <nil>
	// d:      999, overflow: false, err: <nil>
	// d: Infinity, overflow:  true, err: overflow
}

// ExampleInexact demonstrates how to detect inexact operations.
func ExampleContext_inexact() {
	d := apd.New(27, 0)
	three := apd.New(3, 0)
	c := apd.BaseContext.WithPrecision(5)
	for {
		res, err := c.Quo(d, d, three)
		fmt.Printf("d: %7s, inexact: %5v, err: %v\n", d, res.Inexact(), err)
		if err != nil {
			return
		}
		if res.Inexact() {
			return
		}
	}
	// Output: d:       9, inexact: false, err: <nil>
	// d:       3, inexact: false, err: <nil>
	// d:       1, inexact: false, err: <nil>
	// d: 0.33333, inexact:  true, err: <nil>
}

func ExampleContext_Quantize() {
	input, _, _ := apd.NewFromString("123.45")
	output := new(apd.Decimal)
	c := apd.BaseContext.WithPrecision(10)
	for i := int32(-3); i <= 3; i++ {
		res, _ := c.Quantize(output, input, i)
		fmt.Printf("%2v: %s", i, output)
		if res != 0 {
			fmt.Printf(" (%s)", res)
		}
		fmt.Println()
	}
	// Output: -3: 123.450
	// -2: 123.45
	// -1: 123.5 (inexact, rounded)
	//  0: 123 (inexact, rounded)
	//  1: 1.2E+2 (inexact, rounded)
	//  2: 1E+2 (inexact, rounded)
	//  3: 0E+3 (inexact, rounded)
}

func ExampleErrDecimal() {
	c := apd.BaseContext.WithPrecision(5)
	ed := apd.MakeErrDecimal(c)
	d := apd.New(10, 0)
	fmt.Printf("%s, err: %v\n", d, ed.Err())
	ed.Add(d, d, apd.New(2, 1)) // add 20
	fmt.Printf("%s, err: %v\n", d, ed.Err())
	ed.Quo(d, d, apd.New(0, 0)) // divide by zero
	fmt.Printf("%s, err: %v\n", d, ed.Err())
	ed.Sub(d, d, apd.New(1, 0)) // attempt to subtract 1
	// The subtraction doesn't occur and doesn't change the error.
	fmt.Printf("%s, err: %v\n", d, ed.Err())
	// Output: 10, err: <nil>
	// 30, err: <nil>
	// Infinity, err: division by zero
	// Infinity, err: division by zero
}

// ExampleToIntegralX demonstrates how to use ToIntegralX to check if a
// number is an integer or not. Note the variations between integer (which
// allows zeros after the decimal point) and strict (which does not). See
// the documentation on Inexact and Rounded.
func ExampleContext_ToIntegralX() {
	inputs := []string{
		"123.4",
		"123.0",
		"123",
		"12E1",
		"120E-1",
		"120E-2",
	}
	for _, input := range inputs {
		d, _, _ := apd.NewFromString(input)
		res, _ := apd.BaseContext.ToIntegralX(d, d)
		integer := !res.Inexact()
		strict := !res.Rounded()
		fmt.Printf("input: % 6s, ToIntegralX: % 3s, integer: %5t, strict: %5t, res:", input, d, integer, strict)
		if res != 0 {
			fmt.Printf(" %s", res)
		}
		fmt.Println()
	}
	// Output: input:  123.4, ToIntegralX: 123, integer: false, strict: false, res: inexact, rounded
	// input:  123.0, ToIntegralX: 123, integer:  true, strict: false, res: rounded
	// input:    123, ToIntegralX: 123, integer:  true, strict:  true, res:
	// input:   12E1, ToIntegralX: 120, integer:  true, strict:  true, res:
	// input: 120E-1, ToIntegralX:  12, integer:  true, strict: false, res: rounded
	// input: 120E-2, ToIntegralX:   1, integer: false, strict: false, res: inexact, rounded
}
<|endoftext|>


<commit_before>package jsoniter

import (
	"fmt"
	"os"
	"strings"
)

func ExampleMarshal() {
	type ColorGroup struct {
		ID     int
		Name   string
		Colors []string
	}
	group := ColorGroup{
		ID:     1,
		Name:   "Reds",
		Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
	}
	b, err := Marshal(group)
	if err != nil {
		fmt.Println("error:", err)
	}
	os.Stdout.Write(b)
	// Output:
	// {"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}
}

func ExampleUnmarshal() {
	var jsonBlob = []byte(`[
		{"Name": "Platypus", "Order": "Monotremata"},
		{"Name": "Quoll",    "Order": "Dasyuromorphia"}
	]`)
	type Animal struct {
		Name  string
		Order string
	}
	var animals []Animal
	err := Unmarshal(jsonBlob, &animals)
	if err != nil {
		fmt.Println("error:", err)
	}
	fmt.Printf("%+v", animals)
	// Output:
	// [{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}]
}

func ExampleConfigFastest_Marshal() {
	type ColorGroup struct {
		ID     int
		Name   string
		Colors []string
	}
	group := ColorGroup{
		ID:     1,
		Name:   "Reds",
		Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
	}
	stream := ConfigFastest.BorrowStream(nil)
	defer ConfigFastest.ReturnStream(stream)
	stream.WriteVal(group)
	if stream.Error != nil {
		fmt.Println("error:", stream.Error)
	}
	os.Stdout.Write(stream.Buffer())
	// Output:
	// {"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}
}

func ExampleConfigFastest_Unmarshal() {
	var jsonBlob = []byte(`[
		{"Name": "Platypus", "Order": "Monotremata"},
		{"Name": "Quoll",    "Order": "Dasyuromorphia"}
	]`)
	type Animal struct {
		Name  string
		Order string
	}
	var animals []Animal
	iter := ConfigFastest.BorrowIterator(jsonBlob)
	defer ConfigFastest.ReturnIterator(iter)
	iter.ReadVal(&animals)
	if iter.Error != nil {
		fmt.Println("error:", iter.Error)
	}
	fmt.Printf("%+v", animals)
	// Output:
	// [{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}]
}

func ExampleGet() {
	val := []byte(`{"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}`)
	fmt.Printf(Get(val, "Colors", 0).ToString())
	// Output:
	// Crimson
}

func ExampleMapKey() {
	hello := MyKey("hello")
	output, _ := Marshal(map[*MyKey]string{&hello: "world"})
	fmt.Println(string(output))
	obj := map[*MyKey]string{}
	Unmarshal(output, &obj)
	for k, v := range obj {
		fmt.Println(*k, v)
	}
	// Output:
	// {"Hello":"world"}
	// Hel world
}

type MyKey string

func (m *MyKey) MarshalText() ([]byte, error) {
	return []byte(strings.Replace(string(*m), "h", "H", -1)), nil
}

func (m *MyKey) UnmarshalText(text []byte) error {
	*m = MyKey(text[:3])
	return nil
}
<commit_msg>rename ExampleMyKey<commit_after>package jsoniter

import (
	"fmt"
	"os"
	"strings"
)

func ExampleMarshal() {
	type ColorGroup struct {
		ID     int
		Name   string
		Colors []string
	}
	group := ColorGroup{
		ID:     1,
		Name:   "Reds",
		Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
	}
	b, err := Marshal(group)
	if err != nil {
		fmt.Println("error:", err)
	}
	os.Stdout.Write(b)
	// Output:
	// {"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}
}

func ExampleUnmarshal() {
	var jsonBlob = []byte(`[
		{"Name": "Platypus", "Order": "Monotremata"},
		{"Name": "Quoll",    "Order": "Dasyuromorphia"}
	]`)
	type Animal struct {
		Name  string
		Order string
	}
	var animals []Animal
	err := Unmarshal(jsonBlob, &animals)
	if err != nil {
		fmt.Println("error:", err)
	}
	fmt.Printf("%+v", animals)
	// Output:
	// [{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}]
}

func ExampleConfigFastest_Marshal() {
	type ColorGroup struct {
		ID     int
		Name   string
		Colors []string
	}
	group := ColorGroup{
		ID:     1,
		Name:   "Reds",
		Colors: []string{"Crimson", "Red", "Ruby", "Maroon"},
	}
	stream := ConfigFastest.BorrowStream(nil)
	defer ConfigFastest.ReturnStream(stream)
	stream.WriteVal(group)
	if stream.Error != nil {
		fmt.Println("error:", stream.Error)
	}
	os.Stdout.Write(stream.Buffer())
	// Output:
	// {"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}
}

func ExampleConfigFastest_Unmarshal() {
	var jsonBlob = []byte(`[
		{"Name": "Platypus", "Order": "Monotremata"},
		{"Name": "Quoll",    "Order": "Dasyuromorphia"}
	]`)
	type Animal struct {
		Name  string
		Order string
	}
	var animals []Animal
	iter := ConfigFastest.BorrowIterator(jsonBlob)
	defer ConfigFastest.ReturnIterator(iter)
	iter.ReadVal(&animals)
	if iter.Error != nil {
		fmt.Println("error:", iter.Error)
	}
	fmt.Printf("%+v", animals)
	// Output:
	// [{Name:Platypus Order:Monotremata} {Name:Quoll Order:Dasyuromorphia}]
}

func ExampleGet() {
	val := []byte(`{"ID":1,"Name":"Reds","Colors":["Crimson","Red","Ruby","Maroon"]}`)
	fmt.Printf(Get(val, "Colors", 0).ToString())
	// Output:
	// Crimson
}

func ExampleMyKey() {
	hello := MyKey("hello")
	output, _ := Marshal(map[*MyKey]string{&hello: "world"})
	fmt.Println(string(output))
	obj := map[*MyKey]string{}
	Unmarshal(output, &obj)
	for k, v := range obj {
		fmt.Println(*k, v)
	}
	// Output:
	// {"Hello":"world"}
	// Hel world
}

type MyKey string

func (m *MyKey) MarshalText() ([]byte, error) {
	return []byte(strings.Replace(string(*m), "h", "H", -1)), nil
}

func (m *MyKey) UnmarshalText(text []byte) error {
	*m = MyKey(text[:3])
	return nil
}
<|endoftext|>


<commit_before>package blocks

import (
	"bufio"
	"compress/gzip"
	"encoding/json"
	"launchpad.net/goamz/aws"
	"launchpad.net/goamz/s3"
	"log"
	"time"
)

// Gets the key specified in the inbound message. Specify the bucket using a
// rule.
func GetS3(b *Block) {

	type getS3Rule struct {
		BucketName string
	}

	type job struct {
		bucket string
		key    string
		retry  int
	}

	var reader *bufio.Reader
	var dumping bool

	rule := &getS3Rule{}

	// The AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables are used.
	auth, err := aws.EnvAuth()
	if err != nil {
		panic(err.Error())
	}

	timer := time.NewTimer(time.Duration(10) * time.Second)
	todo := make(chan job, 2000) // max number of jobs is 2000
	s := s3.New(auth, aws.USEast)

	for {
		select {
		// timer will have a waiting message until we hit EOF. Each time this
		// case is called, one new message is emitted
		case <-timer.C:
			// this check should only be needed at the initialisation of the
			// block
			if !dumping {
				break
			}
			line, err := reader.ReadBytes(10)
			if err != nil {
				log.Println(err.Error())
				dumping = false
				break
			}
			var out interface{}
			err = json.Unmarshal(line, &out)
			if err != nil {
				log.Println(err)
				timer.Reset(time.Duration(0))
				break
			}
			outMsg := BMsg{
				Msg:          out,
				ResponseChan: nil,
			}
			broadcast(b.OutChans, outMsg)
			timer.Reset(time.Duration(0))
			// the inChan case is responsible for putting a job into the bufferred
			// todo channel
		case msg := <-b.InChan:
			if rule == nil {
				log.Println("no rule set")
				break
			}

			keyArray := getKeyValues(msg.Msg, "Key")
			if len(keyArray) == 0 {
				log.Println("No key found in message")
				break
			}
			keyInterface := keyArray[0]
			key := keyInterface.(string)

			bucketName := rule.BucketName
			j := job{
				bucket: bucketName,
				key:    key,
				retry:  0,
			}
			log.Println(j)
			//TODO this should be a priority queue
			if len(todo) == 100 {
				log.Println("Trying to queue up more than 100 keys!")
				break
			}
			todo <- j
		case r := <-b.Routes["set_rule"]:
			unmarshal(r, rule)
		case msg := <-b.Routes["get_rule"]:
			if rule == nil {
				marshal(msg, &getS3Rule{})
			} else {
				marshal(msg, &rule)
			}
		case <-b.QuitChan:
			quit(b)
			return
		case msg := <-b.AddChan:
			updateOutChans(msg, b)
		}
		// at this point either we've just emitted a message, finished a file,
		// loaded up a job, added an outChan or updated a rule. So we need to
		// check out what's going on.

		// if we're dumping then keep dumping
		if dumping {
			continue
		}
		// if there's nothing todo, then go wait for something to do
		if len(todo) == 0 {
			continue
		}
		// otherwise get on with the next key
		j := <-todo
		// Open Bucket
		bucket := s.Bucket(j.bucket)
		log.Println("[POLLS3] emitting", j.bucket, j.key)
		br, err := bucket.GetReader(j.key)
		if err != nil {
			log.Println(err)
			j.retry++
			if j.retry < 3 {
				todo <- j
			}
			continue // continue
		}
		defer br.Close()
		gr, err := gzip.NewReader(br)
		if err != nil {
			log.Println("failed to open a gzip reader")
			j.retry++
			if j.retry < 3 {
				todo <- j
			}
			continue // continue
		}
		defer gr.Close()
		// set the reader
		reader = bufio.NewReader(gr)
		timer.Reset(time.Duration(0))
		dumping = true
	}
}
<commit_msg>maybe fixed gets3 with a priority queue<commit_after>package blocks

import (
	"bufio"
	"compress/gzip"
	"container/heap"
	"encoding/json"
	"launchpad.net/goamz/aws"
	"launchpad.net/goamz/s3"
	"log"
	"time"
)

// Gets the key specified in the inbound message. Specify the bucket using a
// rule.
func GetS3(b *Block) {

	type getS3Rule struct {
		BucketName string
	}

	type job struct {
		bucket string
		key    string
		retry  int
	}

	var reader *bufio.Reader
	var dumping bool

	rule := &getS3Rule{}

	// The AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables are used.
	auth, err := aws.EnvAuth()
	if err != nil {
		panic(err.Error())
	}

	// we make a priority queue to store keys in, in case Jacqui sends us a
	// billion keys to get all at once
	pq := &PriorityQueue{}
	heap.Init(pq)

	timer := time.NewTimer(time.Duration(10) * time.Second)
	s := s3.New(auth, aws.USEast)

	for {
		select {
		// timer will have a waiting message until we hit EOF. Each time this
		// case is called, one new message is emitted
		case <-timer.C:
			// this check should only be needed at the initialisation of the
			// block
			if !dumping {
				break
			}
			line, err := reader.ReadBytes(10)
			if err != nil {
				log.Println(err.Error())
				dumping = false
				break
			}
			var out interface{}
			err = json.Unmarshal(line, &out)
			if err != nil {
				log.Println(err)
				timer.Reset(time.Duration(0))
				break
			}
			outMsg := BMsg{
				Msg:          out,
				ResponseChan: nil,
			}
			broadcast(b.OutChans, outMsg)
			timer.Reset(time.Duration(0))
			// the inChan case is responsible for putting a job into the bufferred
			// todo channel
		case msg := <-b.InChan:
			if rule == nil {
				log.Println("no rule set")
				break
			}

			keyArray := getKeyValues(msg.Msg, "Key")
			if len(keyArray) == 0 {
				log.Println("No key found in message")
				break
			}
			keyInterface := keyArray[0]
			key := keyInterface.(string)

			bucketName := rule.BucketName
			j := &job{
				bucket: bucketName,
				key:    key,
				retry:  0,
			}
			queueMessage := &PQMessage{
				val: j,
				t:   time.Now(),
			}
			log.Println(j)
			heap.Push(pq, queueMessage)
		case r := <-b.Routes["set_rule"]:
			unmarshal(r, rule)
		case msg := <-b.Routes["get_rule"]:
			if rule == nil {
				marshal(msg, &getS3Rule{})
			} else {
				marshal(msg, &rule)
			}
		case <-b.QuitChan:
			quit(b)
			return
		case msg := <-b.AddChan:
			updateOutChans(msg, b)
		}
		// at this point either we've just emitted a message, finished a file,
		// loaded up a job, added an outChan or updated a rule. So we need to
		// check out what's going on.

		// if we're dumping then keep dumping
		if dumping {
			continue
		}
		// if there's nothing todo, then go wait for something to do
		if len(*pq) == 0 {
			continue
		}
		// otherwise get on with the next key
		msgInterface := heap.Pop(pq)
		msg, ok := msgInterface.(PQMessage)
		if !ok {
			log.Println("could not convert message to PQMessage")
			break
		}
		j, ok := msg.val.(job)
		if !ok {
			log.Println("could not convert job interface to job object")
			break
		}
		// Open Bucket
		bucket := s.Bucket(j.bucket)
		log.Println("[POLLS3] emitting", j.bucket, j.key)
		br, err := bucket.GetReader(j.key)
		if err != nil {
			log.Println(err)
			j.retry++
			if j.retry < 3 {
				heap.Push(pq, msg)
			}
			continue // continue
		}
		defer br.Close()
		gr, err := gzip.NewReader(br)
		if err != nil {
			log.Println("failed to open a gzip reader")
			j.retry++
			if j.retry < 3 {
				heap.Push(pq, msg)
			}
			continue // continue
		}
		defer gr.Close()
		// set the reader
		reader = bufio.NewReader(gr)
		timer.Reset(time.Duration(0))
		dumping = true
	}
}
<|endoftext|>


<commit_before>package storage

import (
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"strings"
	"time"
)

const (
	blobCopyStatusPending = "pending"
	blobCopyStatusSuccess = "success"
	blobCopyStatusAborted = "aborted"
	blobCopyStatusFailed  = "failed"
)

// CopyOptions includes the options for a copy blob operation
type CopyOptions struct {
	Timeout   uint
	Source    CopyOptionsConditions
	Destiny   CopyOptionsConditions
	RequestID string
}

// IncrementalCopyOptions includes the options for an incremental copy blob operation
type IncrementalCopyOptions struct {
	Timeout     uint
	Destination IncrementalCopyOptionsConditions
	RequestID   string
}

// CopyOptionsConditions includes some conditional options in a copy blob operation
type CopyOptionsConditions struct {
	LeaseID           string
	IfModifiedSince   *time.Time
	IfUnmodifiedSince *time.Time
	IfMatch           string
	IfNoneMatch       string
}

// IncrementalCopyOptionsConditions includes some conditional options in a copy blob operation
type IncrementalCopyOptionsConditions struct {
	IfModifiedSince   *time.Time
	IfUnmodifiedSince *time.Time
	IfMatch           string
	IfNoneMatch       string
}

// Copy starts a blob copy operation and waits for the operation to
// complete. sourceBlob parameter must be a canonical URL to the blob (can be
// obtained using GetBlobURL method.) There is no SLA on blob copy and therefore
// this helper method works faster on smaller files.
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Copy-Blob
func (b *Blob) Copy(sourceBlob string, options *CopyOptions) error {
	copyID, err := b.StartCopy(sourceBlob, options)
	if err != nil {
		return err
	}

	return b.WaitForCopy(copyID)
}

// StartCopy starts a blob copy operation.
// sourceBlob parameter must be a canonical URL to the blob (can be
// obtained using GetBlobURL method.)
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Copy-Blob
func (b *Blob) StartCopy(sourceBlob string, options *CopyOptions) (string, error) {
	params := url.Values{}
	headers := b.Container.bsc.client.getStandardHeaders()
	headers["x-ms-copy-source"] = sourceBlob
	headers = b.Container.bsc.client.addMetadataToHeaders(headers, b.Metadata)

	if options != nil {
		params = addTimeout(params, options.Timeout)
		headers = addToHeaders(headers, "x-ms-client-request-id", options.RequestID)
		// source
		headers = addToHeaders(headers, "x-ms-source-lease-id", options.Source.LeaseID)
		headers = addTimeToHeaders(headers, "x-ms-source-if-modified-since", options.Source.IfModifiedSince)
		headers = addTimeToHeaders(headers, "x-ms-source-if-unmodified-since", options.Source.IfUnmodifiedSince)
		headers = addToHeaders(headers, "x-ms-source-if-match", options.Source.IfMatch)
		headers = addToHeaders(headers, "x-ms-source-if-none-match", options.Source.IfNoneMatch)
		//destiny
		headers = addToHeaders(headers, "x-ms-lease-id", options.Destiny.LeaseID)
		headers = addTimeToHeaders(headers, "x-ms-if-modified-since", options.Destiny.IfModifiedSince)
		headers = addTimeToHeaders(headers, "x-ms-if-unmodified-since", options.Destiny.IfUnmodifiedSince)
		headers = addToHeaders(headers, "x-ms-if-match", options.Destiny.IfMatch)
		headers = addToHeaders(headers, "x-ms-if-none-match", options.Destiny.IfNoneMatch)
	}
	uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params)

	resp, err := b.Container.bsc.client.exec(http.MethodPut, uri, headers, nil, b.Container.bsc.auth)
	if err != nil {
		return "", err
	}
	defer readAndCloseBody(resp.body)

	if err := checkRespCode(resp.statusCode, []int{http.StatusAccepted, http.StatusCreated}); err != nil {
		return "", err
	}

	copyID := resp.headers.Get("x-ms-copy-id")
	if copyID == "" {
		return "", errors.New("Got empty copy id header")
	}
	return copyID, nil
}

// AbortCopyOptions includes the options for an abort blob operation
type AbortCopyOptions struct {
	Timeout   uint
	LeaseID   string `header:"x-ms-lease-id"`
	RequestID string `header:"x-ms-client-request-id"`
}

// AbortCopy aborts a BlobCopy which has already been triggered by the StartBlobCopy function.
// copyID is generated from StartBlobCopy function.
// currentLeaseID is required IF the destination blob has an active lease on it.
// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Abort-Copy-Blob
func (b *Blob) AbortCopy(copyID string, options *AbortCopyOptions) error {
	params := url.Values{
		"comp":   {"copy"},
		"copyid": {copyID},
	}
	headers := b.Container.bsc.client.getStandardHeaders()
	headers["x-ms-copy-action"] = "abort"

	if options != nil {
		params = addTimeout(params, options.Timeout)
		headers = mergeHeaders(headers, headersFromStruct(*options))
	}
	uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params)

	resp, err := b.Container.bsc.client.exec(http.MethodPut, uri, headers, nil, b.Container.bsc.auth)
	if err != nil {
		return err
	}
	readAndCloseBody(resp.body)
	return checkRespCode(resp.statusCode, []int{http.StatusNoContent})
}

// WaitForCopy loops until a BlobCopy operation is completed (or fails with error)
func (b *Blob) WaitForCopy(copyID string) error {
	for {
		err := b.GetProperties(nil)
		if err != nil {
			return err
		}

		if b.Properties.CopyID != copyID {
			return errBlobCopyIDMismatch
		}

		switch b.Properties.CopyStatus {
		case blobCopyStatusSuccess:
			return nil
		case blobCopyStatusPending:
			continue
		case blobCopyStatusAborted:
			return errBlobCopyAborted
		case blobCopyStatusFailed:
			return fmt.Errorf("storage: blob copy failed. Id=%s Description=%s", b.Properties.CopyID, b.Properties.CopyStatusDescription)
		default:
			return fmt.Errorf("storage: unhandled blob copy status: '%s'", b.Properties.CopyStatus)
		}
	}
}

// IncrementalCopyBlob copies a snapshot of a source blob and copies to referring blob
// sourceBlob parameter must be a valid snapshot URL of the original blob.
// THe original blob mut be public, or use a Shared Access Signature.
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/incremental-copy-blob .
func (b *Blob) IncrementalCopyBlob(sourceBlobURL string, snapshotTime time.Time, options *IncrementalCopyOptions) (string, error) {
	params := url.Values{"comp": {"incrementalcopy"}}

	// need formatting to 7 decimal places so it's friendly to Windows and *nix
	snapshotTimeFormatted := snapshotTime.Format("2006-01-02T15:04:05.0000000Z")
	u, err := url.Parse(sourceBlobURL)
	if err != nil {
		return "", err
	}
	query := u.Query()
	query.Add("snapshot", snapshotTimeFormatted)
	encodedQuery := query.Encode()
	encodedQuery = strings.Replace(encodedQuery, "%3A", ":", -1)
	u.RawQuery = encodedQuery
	snapshotURL := u.String()

	headers := b.Container.bsc.client.getStandardHeaders()
	headers["x-ms-copy-source"] = snapshotURL

	if options != nil {
		addTimeout(params, options.Timeout)
		headers = addToHeaders(headers, "x-ms-client-request-id", options.RequestID)
		headers = addTimeToHeaders(headers, "x-ms-if-modified-since", options.Destination.IfModifiedSince)
		headers = addTimeToHeaders(headers, "x-ms-if-unmodified-since", options.Destination.IfUnmodifiedSince)
		headers = addToHeaders(headers, "x-ms-if-match", options.Destination.IfMatch)
		headers = addToHeaders(headers, "x-ms-if-none-match", options.Destination.IfNoneMatch)
	}

	// get URI of destination blob
	uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params)

	resp, err := b.Container.bsc.client.exec(http.MethodPut, uri, headers, nil, b.Container.bsc.auth)
	if err != nil {
		return "", err
	}
	defer readAndCloseBody(resp.body)

	if err := checkRespCode(resp.statusCode, []int{http.StatusAccepted}); err != nil {
		return "", err
	}

	copyID := resp.headers.Get("x-ms-copy-id")
	if copyID == "" {
		return "", errors.New("Got empty copy id header")
	}
	return copyID, nil
}
<commit_msg>Fix docs - GetBlobURL no longer exists (#705)<commit_after>package storage

import (
	"errors"
	"fmt"
	"net/http"
	"net/url"
	"strings"
	"time"
)

const (
	blobCopyStatusPending = "pending"
	blobCopyStatusSuccess = "success"
	blobCopyStatusAborted = "aborted"
	blobCopyStatusFailed  = "failed"
)

// CopyOptions includes the options for a copy blob operation
type CopyOptions struct {
	Timeout   uint
	Source    CopyOptionsConditions
	Destiny   CopyOptionsConditions
	RequestID string
}

// IncrementalCopyOptions includes the options for an incremental copy blob operation
type IncrementalCopyOptions struct {
	Timeout     uint
	Destination IncrementalCopyOptionsConditions
	RequestID   string
}

// CopyOptionsConditions includes some conditional options in a copy blob operation
type CopyOptionsConditions struct {
	LeaseID           string
	IfModifiedSince   *time.Time
	IfUnmodifiedSince *time.Time
	IfMatch           string
	IfNoneMatch       string
}

// IncrementalCopyOptionsConditions includes some conditional options in a copy blob operation
type IncrementalCopyOptionsConditions struct {
	IfModifiedSince   *time.Time
	IfUnmodifiedSince *time.Time
	IfMatch           string
	IfNoneMatch       string
}

// Copy starts a blob copy operation and waits for the operation to
// complete. sourceBlob parameter must be a canonical URL to the blob (can be
// obtained using the GetURL method.) There is no SLA on blob copy and therefore
// this helper method works faster on smaller files.
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Copy-Blob
func (b *Blob) Copy(sourceBlob string, options *CopyOptions) error {
	copyID, err := b.StartCopy(sourceBlob, options)
	if err != nil {
		return err
	}

	return b.WaitForCopy(copyID)
}

// StartCopy starts a blob copy operation.
// sourceBlob parameter must be a canonical URL to the blob (can be
// obtained using the GetURL method.)
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Copy-Blob
func (b *Blob) StartCopy(sourceBlob string, options *CopyOptions) (string, error) {
	params := url.Values{}
	headers := b.Container.bsc.client.getStandardHeaders()
	headers["x-ms-copy-source"] = sourceBlob
	headers = b.Container.bsc.client.addMetadataToHeaders(headers, b.Metadata)

	if options != nil {
		params = addTimeout(params, options.Timeout)
		headers = addToHeaders(headers, "x-ms-client-request-id", options.RequestID)
		// source
		headers = addToHeaders(headers, "x-ms-source-lease-id", options.Source.LeaseID)
		headers = addTimeToHeaders(headers, "x-ms-source-if-modified-since", options.Source.IfModifiedSince)
		headers = addTimeToHeaders(headers, "x-ms-source-if-unmodified-since", options.Source.IfUnmodifiedSince)
		headers = addToHeaders(headers, "x-ms-source-if-match", options.Source.IfMatch)
		headers = addToHeaders(headers, "x-ms-source-if-none-match", options.Source.IfNoneMatch)
		//destiny
		headers = addToHeaders(headers, "x-ms-lease-id", options.Destiny.LeaseID)
		headers = addTimeToHeaders(headers, "x-ms-if-modified-since", options.Destiny.IfModifiedSince)
		headers = addTimeToHeaders(headers, "x-ms-if-unmodified-since", options.Destiny.IfUnmodifiedSince)
		headers = addToHeaders(headers, "x-ms-if-match", options.Destiny.IfMatch)
		headers = addToHeaders(headers, "x-ms-if-none-match", options.Destiny.IfNoneMatch)
	}
	uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params)

	resp, err := b.Container.bsc.client.exec(http.MethodPut, uri, headers, nil, b.Container.bsc.auth)
	if err != nil {
		return "", err
	}
	defer readAndCloseBody(resp.body)

	if err := checkRespCode(resp.statusCode, []int{http.StatusAccepted, http.StatusCreated}); err != nil {
		return "", err
	}

	copyID := resp.headers.Get("x-ms-copy-id")
	if copyID == "" {
		return "", errors.New("Got empty copy id header")
	}
	return copyID, nil
}

// AbortCopyOptions includes the options for an abort blob operation
type AbortCopyOptions struct {
	Timeout   uint
	LeaseID   string `header:"x-ms-lease-id"`
	RequestID string `header:"x-ms-client-request-id"`
}

// AbortCopy aborts a BlobCopy which has already been triggered by the StartBlobCopy function.
// copyID is generated from StartBlobCopy function.
// currentLeaseID is required IF the destination blob has an active lease on it.
// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/Abort-Copy-Blob
func (b *Blob) AbortCopy(copyID string, options *AbortCopyOptions) error {
	params := url.Values{
		"comp":   {"copy"},
		"copyid": {copyID},
	}
	headers := b.Container.bsc.client.getStandardHeaders()
	headers["x-ms-copy-action"] = "abort"

	if options != nil {
		params = addTimeout(params, options.Timeout)
		headers = mergeHeaders(headers, headersFromStruct(*options))
	}
	uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params)

	resp, err := b.Container.bsc.client.exec(http.MethodPut, uri, headers, nil, b.Container.bsc.auth)
	if err != nil {
		return err
	}
	readAndCloseBody(resp.body)
	return checkRespCode(resp.statusCode, []int{http.StatusNoContent})
}

// WaitForCopy loops until a BlobCopy operation is completed (or fails with error)
func (b *Blob) WaitForCopy(copyID string) error {
	for {
		err := b.GetProperties(nil)
		if err != nil {
			return err
		}

		if b.Properties.CopyID != copyID {
			return errBlobCopyIDMismatch
		}

		switch b.Properties.CopyStatus {
		case blobCopyStatusSuccess:
			return nil
		case blobCopyStatusPending:
			continue
		case blobCopyStatusAborted:
			return errBlobCopyAborted
		case blobCopyStatusFailed:
			return fmt.Errorf("storage: blob copy failed. Id=%s Description=%s", b.Properties.CopyID, b.Properties.CopyStatusDescription)
		default:
			return fmt.Errorf("storage: unhandled blob copy status: '%s'", b.Properties.CopyStatus)
		}
	}
}

// IncrementalCopyBlob copies a snapshot of a source blob and copies to referring blob
// sourceBlob parameter must be a valid snapshot URL of the original blob.
// THe original blob mut be public, or use a Shared Access Signature.
//
// See https://docs.microsoft.com/en-us/rest/api/storageservices/fileservices/incremental-copy-blob .
func (b *Blob) IncrementalCopyBlob(sourceBlobURL string, snapshotTime time.Time, options *IncrementalCopyOptions) (string, error) {
	params := url.Values{"comp": {"incrementalcopy"}}

	// need formatting to 7 decimal places so it's friendly to Windows and *nix
	snapshotTimeFormatted := snapshotTime.Format("2006-01-02T15:04:05.0000000Z")
	u, err := url.Parse(sourceBlobURL)
	if err != nil {
		return "", err
	}
	query := u.Query()
	query.Add("snapshot", snapshotTimeFormatted)
	encodedQuery := query.Encode()
	encodedQuery = strings.Replace(encodedQuery, "%3A", ":", -1)
	u.RawQuery = encodedQuery
	snapshotURL := u.String()

	headers := b.Container.bsc.client.getStandardHeaders()
	headers["x-ms-copy-source"] = snapshotURL

	if options != nil {
		addTimeout(params, options.Timeout)
		headers = addToHeaders(headers, "x-ms-client-request-id", options.RequestID)
		headers = addTimeToHeaders(headers, "x-ms-if-modified-since", options.Destination.IfModifiedSince)
		headers = addTimeToHeaders(headers, "x-ms-if-unmodified-since", options.Destination.IfUnmodifiedSince)
		headers = addToHeaders(headers, "x-ms-if-match", options.Destination.IfMatch)
		headers = addToHeaders(headers, "x-ms-if-none-match", options.Destination.IfNoneMatch)
	}

	// get URI of destination blob
	uri := b.Container.bsc.client.getEndpoint(blobServiceName, b.buildPath(), params)

	resp, err := b.Container.bsc.client.exec(http.MethodPut, uri, headers, nil, b.Container.bsc.auth)
	if err != nil {
		return "", err
	}
	defer readAndCloseBody(resp.body)

	if err := checkRespCode(resp.statusCode, []int{http.StatusAccepted}); err != nil {
		return "", err
	}

	copyID := resp.headers.Get("x-ms-copy-id")
	if copyID == "" {
		return "", errors.New("Got empty copy id header")
	}
	return copyID, nil
}
<|endoftext|>


<commit_before>package store

import (
	"github.com/go-kit/kit/endpoint"
	"golang.org/x/net/context"
)

// Middleware takes a Factory and create a middleware that
// does WithStores and CloseAllIn
func Middleware(factory Factory) endpoint.Middleware {
	mware := func(inner endpoint.Endpoint) endpoint.Endpoint {
		return func(ctx context.Context, request interface{}) (response interface{}, err error) {
			ctx = WithFactory(ctx, factory)
			response, err = inner(ctx, request)
			CloseAllIn(ctx)
			return
		}
	}
	return mware
}
<commit_msg>store: Added RequestFunc and Cleanup<commit_after>package store

import (
	"net/http"

	"github.com/go-kit/kit/endpoint"
	httptransport "github.com/go-kit/kit/transport/http"
	"golang.org/x/net/context"
)

// RequestFunc returns a go-kit/kit/transpoirt/http.RequestFunc
// that will add a given factory to the context
func RequestFunc(factory Factory) httptransport.RequestFunc {
	return func(parent context.Context, r *http.Request) context.Context {
		return WithFactory(parent, factory)
	}
}

// Cleanup cleans up after RequestFunc.
// If you called RequestFunc in your http transport,
// you should use this
func Cleanup(inner endpoint.Endpoint) endpoint.Endpoint {
	return func(ctx context.Context, request interface{}) (response interface{}, err error) {
		response, err = inner(ctx, request)
		CloseAllIn(ctx)
		return
	}
}

// Middleware takes a Factory and create a middleware that
// does WithStores and CloseAllIn
func Middleware(factory Factory) endpoint.Middleware {
	mware := func(inner endpoint.Endpoint) endpoint.Endpoint {
		return func(ctx context.Context, request interface{}) (response interface{}, err error) {
			ctx = WithFactory(ctx, factory)
			response, err = inner(ctx, request)
			CloseAllIn(ctx)
			return
		}
	}
	return mware
}
<|endoftext|>


<commit_before>package store

import (
	"os"
	"reflect"
	"testing"
)

func setUpLeaseStore() (*Store, error) {
	return NewStore("leases_test.db")
}

func tearDownLeaseStore(db *Store) {
	db.Close()
	os.Remove("leases_test.db")
}

func TestLeaseStore(t *testing.T) {
	store, err := setUpLeaseStore()
	if err != nil {
		t.Fatal(err)
	}
	defer tearDownLeaseStore(store)

	lease := leaseTests[0].actual
	if err := store.PutLease(lease); err != nil {
		t.Fatal(err)
	}

	lease2, err := store.GetLease(lease.IP)
	if err != nil {
		t.Fatal(err)
	}

	if !reflect.DeepEqual(lease, lease2) {
		t.Fatalf("Leases don't match")
	}
}

func TestForEachLease(t *testing.T) {
	store, err := setUpLeaseStore()
	if err != nil {
		t.Fatal(err)
	}
	defer tearDownLeaseStore(store)

	lease1 := leaseTests[0].actual
	lease2 := leaseTests[1].actual

	store.PutLease(lease1)
	store.PutLease(lease2)

	var newLease1, newLease2 *Lease

	store.ForEachLease(func(l *Lease) {
		if l.IP.String() == "10.0.2.5" {
			newLease1 = l
		} else if l.IP.String() == "10.0.2.6" {
			newLease2 = l
		}
	})

	if newLease1 == nil {
		t.Error("newLease1 is nil")
	}
	if newLease2 == nil {
		t.Error("newLease2 is nil")
	}
}
<commit_msg>Fix failing store tests. Store wasn't being flushed before read.<commit_after>package store

import (
	"os"
	"reflect"
	"testing"
)

func setUpLeaseStore() (*Store, error) {
	return NewStore("leases_test.db")
}

func tearDownLeaseStore(db *Store) {
	db.Close()
	os.Remove("leases_test.db")
}

func TestLeaseStore(t *testing.T) {
	store, err := setUpLeaseStore()
	if err != nil {
		t.Fatal(err)
	}
	defer tearDownLeaseStore(store)

	lease := leaseTests[0].actual
	if err := store.PutLease(lease); err != nil {
		t.Fatal(err)
	}
	store.doFlush()

	lease2, err := store.GetLease(lease.IP)
	if err != nil {
		t.Fatal(err)
	}

	if !reflect.DeepEqual(lease, lease2) {
		t.Fatalf("Leases don't match")
	}
}

func TestForEachLease(t *testing.T) {
	store, err := setUpLeaseStore()
	if err != nil {
		t.Fatal(err)
	}
	defer tearDownLeaseStore(store)

	lease1 := leaseTests[0].actual
	lease2 := leaseTests[1].actual

	store.PutLease(lease1)
	store.PutLease(lease2)
	store.doFlush()

	var newLease1, newLease2 *Lease

	store.ForEachLease(func(l *Lease) {
		if l.IP.String() == "10.0.2.5" {
			newLease1 = l
		} else if l.IP.String() == "10.0.2.6" {
			newLease2 = l
		}
	})

	if newLease1 == nil {
		t.Error("newLease1 is nil")
	}
	if newLease2 == nil {
		t.Error("newLease2 is nil")
	}
}
<|endoftext|>