<commit_before>//Helper Methods for Key and Value Interface

package api

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/prataprc/collatejson"
)

var KEY_SEPARATOR []byte = []byte{0xff, 0xff, 0xff, 0xff}

func NewKey(data [][]byte, docid string) (Key, error) {

	var err error
	var key Key
	key.raw.keybytes = data
	key.raw.docid = docid

	jsoncodec := collatejson.NewCodec()
	//convert key to its collatejson encoded byte representation
	buf := new(bytes.Buffer)
	for _, k := range key.raw.keybytes {
		if _, err = buf.Write(jsoncodec.Encode(k)); err != nil {
			return key, err
		}
		if _, err = buf.Write(KEY_SEPARATOR); err != nil {
			return key, err
		}
	}
	//write the docid in the end
	if _, err = buf.Write([]byte(key.raw.docid)); err != nil {
		return key, err
	}

	key.encoded = buf.Bytes()

	return key, nil

}

func NewValue(data [][]byte, docid string, vbucket int, seqno int64) (Value, error) {

	var val Value

	val.raw.Keybytes = data
	val.raw.Docid = docid
	val.raw.Vbucket = vbucket
	val.raw.Seqno = seqno

	var err error
	if val.encoded, err = json.Marshal(val.raw); err != nil {
		return val, err
	}
	return val, nil
}

func NewKeyFromEncodedBytes(b []byte) (Key, error) {

	var k Key
	//FIXME Add decoding for bytes for k.raw
	k.encoded = b
	return k, nil

}

func NewValueFromEncodedBytes(b []byte) (Value, error) {

	var val Value
	var err error
	if b != nil {
		err = json.Unmarshal(b, &val.raw)
	}
	val.encoded = b
	return val, err

}

func (k *Key) Compare(than Key) int {

	//strip the docid before bytewise comparison
	i1 := bytes.LastIndex(k.encoded, KEY_SEPARATOR)
	b1 := k.encoded[0:i1]

	b2 := than.EncodedBytes()
	i2 := bytes.LastIndex(b2, KEY_SEPARATOR)
	b2 = b2[0:i2]

	return bytes.Compare(b1, b2)
}

func (k *Key) EncodedBytes() []byte {

	return k.encoded
}

func (k *Key) String() string {
	var buf bytes.Buffer
	buf.WriteString("Key:[")
	for i, key := range k.raw.keybytes {
		buf.WriteString(fmt.Sprintf("%v", string(key)))
		if i < len(k.raw.keybytes)-1 {
			buf.WriteString(" ")
		}
	}
	buf.WriteString("]")
	if k.raw.docid != "" {
		buf.WriteString(fmt.Sprintf(" Docid:%v ", k.raw.docid))
	}
	return buf.String()
}

func (v *Value) EncodedBytes() []byte {

	return v.encoded

}

func (v *Value) KeyBytes() Keybytes {

	return v.raw.Keybytes
}

func (v *Value) Docid() string {

	return v.raw.Docid
}

func (v *Value) String() string {
	var buf bytes.Buffer
	buf.WriteString("Key:[")
	for i, key := range v.raw.Keybytes {
		buf.WriteString(fmt.Sprintf("%v", string(key)))
		if i < len(v.raw.Keybytes)-1 {
			buf.WriteString(" ")
		}
	}
	buf.WriteString("]")
	buf.WriteString(fmt.Sprintf("Docid:%v ", v.raw.Docid))
	buf.WriteString(fmt.Sprintf("Vbucket:%d ", v.raw.Vbucket))
	buf.WriteString(fmt.Sprintf("Seqno:%d", v.raw.Seqno))
	return buf.String()
}
<commit_msg>Change vbucket/seqno from int64 to uint64<commit_after>//Helper Methods for Key and Value Interface

package api

import (
	"bytes"
	"encoding/json"
	"fmt"
	"github.com/prataprc/collatejson"
)

var KEY_SEPARATOR []byte = []byte{0xff, 0xff, 0xff, 0xff}

func NewKey(data [][]byte, docid string) (Key, error) {

	var err error
	var key Key
	key.raw.keybytes = data
	key.raw.docid = docid

	jsoncodec := collatejson.NewCodec()
	//convert key to its collatejson encoded byte representation
	buf := new(bytes.Buffer)
	for _, k := range key.raw.keybytes {
		if _, err = buf.Write(jsoncodec.Encode(k)); err != nil {
			return key, err
		}
		if _, err = buf.Write(KEY_SEPARATOR); err != nil {
			return key, err
		}
	}
	//write the docid in the end
	if _, err = buf.Write([]byte(key.raw.docid)); err != nil {
		return key, err
	}

	key.encoded = buf.Bytes()

	return key, nil

}

func NewValue(data [][]byte, docid string, vbucket uint, seqno uint64) (Value, error) {

	var val Value

	val.raw.Keybytes = data
	val.raw.Docid = docid
	val.raw.Vbucket = vbucket
	val.raw.Seqno = seqno

	var err error
	if val.encoded, err = json.Marshal(val.raw); err != nil {
		return val, err
	}
	return val, nil
}

func NewKeyFromEncodedBytes(b []byte) (Key, error) {

	var k Key
	//FIXME Add decoding for bytes for k.raw
	k.encoded = b
	return k, nil

}

func NewValueFromEncodedBytes(b []byte) (Value, error) {

	var val Value
	var err error
	if b != nil {
		err = json.Unmarshal(b, &val.raw)
	}
	val.encoded = b
	return val, err

}

func (k *Key) Compare(than Key) int {

	//strip the docid before bytewise comparison
	i1 := bytes.LastIndex(k.encoded, KEY_SEPARATOR)
	b1 := k.encoded[0:i1]

	b2 := than.EncodedBytes()
	i2 := bytes.LastIndex(b2, KEY_SEPARATOR)
	b2 = b2[0:i2]

	return bytes.Compare(b1, b2)
}

func (k *Key) EncodedBytes() []byte {

	return k.encoded
}

func (k *Key) String() string {
	var buf bytes.Buffer
	buf.WriteString("Key:[")
	for i, key := range k.raw.keybytes {
		buf.WriteString(fmt.Sprintf("%v", string(key)))
		if i < len(k.raw.keybytes)-1 {
			buf.WriteString(" ")
		}
	}
	buf.WriteString("]")
	if k.raw.docid != "" {
		buf.WriteString(fmt.Sprintf(" Docid:%v ", k.raw.docid))
	}
	return buf.String()
}

func (v *Value) EncodedBytes() []byte {

	return v.encoded

}

func (v *Value) KeyBytes() Keybytes {

	return v.raw.Keybytes
}

func (v *Value) Docid() string {

	return v.raw.Docid
}

func (v *Value) String() string {
	var buf bytes.Buffer
	buf.WriteString("Key:[")
	for i, key := range v.raw.Keybytes {
		buf.WriteString(fmt.Sprintf("%v", string(key)))
		if i < len(v.raw.Keybytes)-1 {
			buf.WriteString(" ")
		}
	}
	buf.WriteString("]")
	buf.WriteString(fmt.Sprintf("Docid:%v ", v.raw.Docid))
	buf.WriteString(fmt.Sprintf("Vbucket:%d ", v.raw.Vbucket))
	buf.WriteString(fmt.Sprintf("Seqno:%d", v.raw.Seqno))
	return buf.String()
}
<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"

	"github.com/aerogo/aero"
	"github.com/aerogo/sitemap"
	"github.com/animenotifier/arn"
	"github.com/animenotifier/notify.moe/components/js"
)

// configureAssets adds all the routes used for media assets.
func configureAssets(app *aero.Application) {
	// Script bundle
	scriptBundle := js.Bundle()

	// Service worker
	serviceWorkerBytes, err := ioutil.ReadFile("sw/service-worker.js")
	serviceWorker := string(serviceWorkerBytes)

	if err != nil {
		panic("Couldn't load service worker")
	}

	app.Get("/scripts", func(ctx *aero.Context) string {
		return ctx.JavaScript(scriptBundle)
	})

	app.Get("/scripts.js", func(ctx *aero.Context) string {
		return ctx.JavaScript(scriptBundle)
	})

	app.Get("/service-worker", func(ctx *aero.Context) string {
		return ctx.JavaScript(serviceWorker)
	})

	// Web manifest
	app.Get("/manifest.json", func(ctx *aero.Context) string {
		return ctx.JSON(app.Config.Manifest)
	})

	// Favicon
	app.Get("/favicon.ico", func(ctx *aero.Context) string {
		return ctx.File("images/brand/64.png")
	})

	// Images
	app.Get("/images/*file", func(ctx *aero.Context) string {
		return ctx.File("images" + ctx.Get("file"))
	})

	// Videos
	app.Get("/videos/*file", func(ctx *aero.Context) string {
		return ctx.File("videos" + ctx.Get("file"))
	})

	// Anime sitemap
	app.Get("/sitemap/anime.txt", func(ctx *aero.Context) string {
		sitemap := sitemap.New()
		prefix := "https://" + app.Config.Domain

		for anime := range arn.StreamAnime() {
			sitemap.Add(prefix + anime.Link())
		}

		return ctx.Text(sitemap.Text())
	})

	// Character sitemap
	app.Get("/sitemap/character.txt", func(ctx *aero.Context) string {
		sitemap := sitemap.New()
		prefix := "https://" + app.Config.Domain

		for character := range arn.StreamCharacters() {
			sitemap.Add(prefix + character.Link())
		}

		return ctx.Text(sitemap.Text())
	})

	// User sitemap
	app.Get("/sitemap/user.txt", func(ctx *aero.Context) string {
		sitemap := sitemap.New()
		prefix := "https://" + app.Config.Domain

		for user := range arn.StreamUsers() {
			sitemap.Add(prefix + user.Link())
		}

		return ctx.Text(sitemap.Text())
	})

	// For benchmarks
	app.Get("/hello", func(ctx *aero.Context) string {
		return ctx.Text("Hello World")
	})
}
<commit_msg>Added more sitemaps<commit_after>package main

import (
	"io/ioutil"

	"github.com/aerogo/aero"
	"github.com/aerogo/sitemap"
	"github.com/animenotifier/arn"
	"github.com/animenotifier/notify.moe/components/js"
)

// configureAssets adds all the routes used for media assets.
func configureAssets(app *aero.Application) {
	// Script bundle
	scriptBundle := js.Bundle()

	// Service worker
	serviceWorkerBytes, err := ioutil.ReadFile("sw/service-worker.js")
	serviceWorker := string(serviceWorkerBytes)

	if err != nil {
		panic("Couldn't load service worker")
	}

	app.Get("/scripts", func(ctx *aero.Context) string {
		return ctx.JavaScript(scriptBundle)
	})

	app.Get("/scripts.js", func(ctx *aero.Context) string {
		return ctx.JavaScript(scriptBundle)
	})

	app.Get("/service-worker", func(ctx *aero.Context) string {
		return ctx.JavaScript(serviceWorker)
	})

	// Web manifest
	app.Get("/manifest.json", func(ctx *aero.Context) string {
		return ctx.JSON(app.Config.Manifest)
	})

	// Favicon
	app.Get("/favicon.ico", func(ctx *aero.Context) string {
		return ctx.File("images/brand/64.png")
	})

	// Images
	app.Get("/images/*file", func(ctx *aero.Context) string {
		return ctx.File("images" + ctx.Get("file"))
	})

	// Videos
	app.Get("/videos/*file", func(ctx *aero.Context) string {
		return ctx.File("videos" + ctx.Get("file"))
	})

	// Anime sitemap
	app.Get("/sitemap/anime.txt", func(ctx *aero.Context) string {
		sitemap := sitemap.New()
		prefix := "https://" + app.Config.Domain

		for anime := range arn.StreamAnime() {
			sitemap.Add(prefix + anime.Link())
		}

		return ctx.Text(sitemap.Text())
	})

	// Character sitemap
	app.Get("/sitemap/character.txt", func(ctx *aero.Context) string {
		sitemap := sitemap.New()
		prefix := "https://" + app.Config.Domain

		for character := range arn.StreamCharacters() {
			sitemap.Add(prefix + character.Link())
		}

		return ctx.Text(sitemap.Text())
	})

	// User sitemap
	app.Get("/sitemap/user.txt", func(ctx *aero.Context) string {
		sitemap := sitemap.New()
		prefix := "https://" + app.Config.Domain

		for user := range arn.StreamUsers() {
			sitemap.Add(prefix + user.Link())
		}

		return ctx.Text(sitemap.Text())
	})

	// SoundTrack sitemap
	app.Get("/sitemap/soundtrack.txt", func(ctx *aero.Context) string {
		sitemap := sitemap.New()
		prefix := "https://" + app.Config.Domain

		for soundTrack := range arn.StreamSoundTracks() {
			sitemap.Add(prefix + soundTrack.Link())
		}

		return ctx.Text(sitemap.Text())
	})

	// Thread sitemap
	app.Get("/sitemap/thread.txt", func(ctx *aero.Context) string {
		sitemap := sitemap.New()
		prefix := "https://" + app.Config.Domain

		for thread := range arn.StreamThreads() {
			sitemap.Add(prefix + thread.Link())
		}

		return ctx.Text(sitemap.Text())
	})

	// Post sitemap
	app.Get("/sitemap/post.txt", func(ctx *aero.Context) string {
		sitemap := sitemap.New()
		prefix := "https://" + app.Config.Domain

		for post := range arn.StreamPosts() {
			sitemap.Add(prefix + post.Link())
		}

		return ctx.Text(sitemap.Text())
	})

	// For benchmarks
	app.Get("/hello", func(ctx *aero.Context) string {
		return ctx.Text("Hello World")
	})
}
<|endoftext|>


<commit_before>// package atomic provides functions to atomically change files.
package atomic

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
)

// WriteFile atomically writes the contents of r to the specified filepath.  If
// an error occurs, the target file is guaranteed to be either fully written, or
// not written at all.  WriteFile overwrites any file that exists at the
// location (but only if the write fully succeeds, otherwise the existing file
// is unmodified).
func WriteFile(filename string, r io.Reader) (err error) {
	// write to a temp file first, then we'll atomically replace the target file
	// with the temp file.
	dir, file := filepath.Split(filename)
	f, err := ioutil.TempFile(dir, file)
	if err != nil {
		return fmt.Errorf("cannot create temp file: %v", err)
	}
	defer func() {
		if err != nil {
			// Don't leave the temp file lying around on error.
			_ = os.Remove(f.Name()) // yes, ignore the error, not much we can do about it.
		}
	}()
	// ensure we always close f. Note that this does not conflict with  the
	// close below, as close is idempotent.
	defer f.Close()
	name := f.Name()
	if _, err := io.Copy(f, r); err != nil {
		return fmt.Errorf("cannot write data to tempfile %q: %v", name, err)
	}
	if err := f.Close(); err != nil {
		return fmt.Errorf("can't close tempfile %q: %v", name, err)
	}

	// get the file mode from the original file and use that for the replacement
	// file, too.
	info, err := os.Stat(filename)
	if os.IsNotExist(err) {
		// no original file
	} else if err != nil {
		return err
	} else {
		if err := os.Chmod(name, info.Mode()); err != nil {
			return fmt.Errorf("can't set filemode on tempfile %q: %v", name, err)
		}
	}
	if err := ReplaceFile(name, filename); err != nil {
		return fmt.Errorf("cannot replace %q with tempfile %q: %v", filename, name, err)
	}
	return nil
}
<commit_msg>WriteFile(): handle relative paths<commit_after>// package atomic provides functions to atomically change files.
package atomic

import (
	"fmt"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
)

// WriteFile atomically writes the contents of r to the specified filepath.  If
// an error occurs, the target file is guaranteed to be either fully written, or
// not written at all.  WriteFile overwrites any file that exists at the
// location (but only if the write fully succeeds, otherwise the existing file
// is unmodified).
func WriteFile(filename string, r io.Reader) (err error) {
	// write to a temp file first, then we'll atomically replace the target file
	// with the temp file.
	dir, file := filepath.Split(filename)
	if dir == "" {
		dir = "."
	}

	f, err := ioutil.TempFile(dir, file)
	if err != nil {
		return fmt.Errorf("cannot create temp file: %v", err)
	}
	defer func() {
		if err != nil {
			// Don't leave the temp file lying around on error.
			_ = os.Remove(f.Name()) // yes, ignore the error, not much we can do about it.
		}
	}()
	// ensure we always close f. Note that this does not conflict with  the
	// close below, as close is idempotent.
	defer f.Close()
	name := f.Name()
	if _, err := io.Copy(f, r); err != nil {
		return fmt.Errorf("cannot write data to tempfile %q: %v", name, err)
	}
	if err := f.Close(); err != nil {
		return fmt.Errorf("can't close tempfile %q: %v", name, err)
	}

	// get the file mode from the original file and use that for the replacement
	// file, too.
	info, err := os.Stat(filename)
	if os.IsNotExist(err) {
		// no original file
	} else if err != nil {
		return err
	} else {
		if err := os.Chmod(name, info.Mode()); err != nil {
			return fmt.Errorf("can't set filemode on tempfile %q: %v", name, err)
		}
	}
	if err := ReplaceFile(name, filename); err != nil {
		return fmt.Errorf("cannot replace %q with tempfile %q: %v", filename, name, err)
	}
	return nil
}
<|endoftext|>


<commit_before>package hoverfly

import (
	"fmt"
	log "github.com/Sirupsen/logrus"
	"net/url"
	"os"
	"path"
	"regexp"
	"strings"
	"time"
)

func (d *DBClient) Import(uri string) error {

	// assuming file URI is URL:
	if IsURL(uri) {
		log.WithFields(log.Fields{
			"isURL":      IsURL(uri),
			"importFrom": uri,
		}).Info("URL")
		return d.ImportFromUrl(uri)
	}
	// assuming file URI is disk location
	ext := path.Ext(uri)
	if ext != ".json" {
		return fmt.Errorf("Failed to import payloads, only JSON files are acceppted. Given file: %s", uri)
	} else {
		// checking whether it exists
		exists, err := exists(uri)
		if err != nil {
			return fmt.Errorf("Failed to import payloads from %s. Got error: %s", uri, err.Error())
		}
		if exists {
			// file is JSON and it exist
			return d.ImportFromDisk(uri)
		} else {
			return fmt.Errorf("Failed to import payloads, given file '%s' does not exist", uri)
		}
	}
}

const URL string = `^((ftp|https?):\/\/)(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(([a-zA-Z0-9]+([-\.][a-zA-Z0-9]+)*)|((www\.)?))?(([a-z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-z\x{00a1}-\x{ffff}]{2,}))?))(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$`

var rxURL = regexp.MustCompile(URL)

func IsURL(str string) bool {
	if str == "" || len(str) >= 2083 || len(str) <= 3 || strings.HasPrefix(str, ".") {
		return false
	}
	u, err := url.Parse(str)
	if err != nil {
		return false
	}
	if strings.HasPrefix(u.Host, ".") {
		return false
	}
	if u.Host == "" && (u.Path != "" && !strings.Contains(u.Path, ".")) {
		return false
	}

	return rxURL.MatchString(str)

}
func (d *DBClient) ImportPayloads(payloads []Payload) error {
	if len(payloads) > 0 {
		success := 0
		failed := 0
		for _, pl := range payloads {
			// recalculating request hash and storing it in database
			r := RequestContainer{Details: pl.Request}
			key := r.Hash()

			// regenerating key
			pl.ID = key

			bts, err := pl.Encode()
			if err != nil {
				log.WithFields(log.Fields{
					"error": err.Error(),
				}).Error("Failed to encode payload")
				failed += 1
			} else {
				// hook
				var en Entry
				en.ActionType = ActionTypeRequestCaptured
				en.Message = "imported"
				en.Time = time.Now()
				en.Data = bts

				if err := d.Hooks.Fire(ActionTypeRequestCaptured, &en); err != nil {
					log.WithFields(log.Fields{
						"error":      err.Error(),
						"message":    en.Message,
						"actionType": ActionTypeRequestCaptured,
					}).Error("failed to fire hook")
				}

				d.Cache.Set([]byte(key), bts)
				if err == nil {
					success += 1
				} else {
					failed += 1
				}
			}
		}
		log.WithFields(log.Fields{
			"total":      len(payloads),
			"successful": success,
			"failed":     failed,
		}).Info("payloads imported")
		return nil
	} else {
		return fmt.Errorf("Bad request. Nothing to import!")
	}

}
<commit_msg>checking whether exists<commit_after>package hoverfly

import (
	"fmt"
	log "github.com/Sirupsen/logrus"
	"net/url"
	"os"
	"path"
	"regexp"
	"strings"
	"time"
)

func (d *DBClient) Import(uri string) error {

	// assuming file URI is URL:
	if IsURL(uri) {
		log.WithFields(log.Fields{
			"isURL":      IsURL(uri),
			"importFrom": uri,
		}).Info("URL")
		return d.ImportFromUrl(uri)
	}
	// assuming file URI is disk location
	ext := path.Ext(uri)
	if ext != ".json" {
		return fmt.Errorf("Failed to import payloads, only JSON files are acceppted. Given file: %s", uri)
	} else {
		// checking whether it exists
		exists, err := exists(uri)
		if err != nil {
			return fmt.Errorf("Failed to import payloads from %s. Got error: %s", uri, err.Error())
		}
		if exists {
			// file is JSON and it exist
			return d.ImportFromDisk(uri)
		} else {
			return fmt.Errorf("Failed to import payloads, given file '%s' does not exist", uri)
		}
	}
}

const URL string = `^((ftp|https?):\/\/)(\S+(:\S*)?@)?((([1-9]\d?|1\d\d|2[01]\d|22[0-3])(\.(1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.([0-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(([a-zA-Z0-9]+([-\.][a-zA-Z0-9]+)*)|((www\.)?))?(([a-z\x{00a1}-\x{ffff}0-9]+-?-?)*[a-z\x{00a1}-\x{ffff}0-9]+)(?:\.([a-z\x{00a1}-\x{ffff}]{2,}))?))(:(\d{1,5}))?((\/|\?|#)[^\s]*)?$`

var rxURL = regexp.MustCompile(URL)

func IsURL(str string) bool {
	if str == "" || len(str) >= 2083 || len(str) <= 3 || strings.HasPrefix(str, ".") {
		return false
	}
	u, err := url.Parse(str)
	if err != nil {
		return false
	}
	if strings.HasPrefix(u.Host, ".") {
		return false
	}
	if u.Host == "" && (u.Path != "" && !strings.Contains(u.Path, ".")) {
		return false
	}

	return rxURL.MatchString(str)

}

func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return true, err
}

func (d *DBClient) ImportFromDisk(path string) error {
	log.Warn("importing from disk")
	return nil
}

func (d *DBClient) ImportFromUrl(url string) error {
	log.Warn("importing from url")
	return nil
}

func (d *DBClient) ImportPayloads(payloads []Payload) error {
	if len(payloads) > 0 {
		success := 0
		failed := 0
		for _, pl := range payloads {
			// recalculating request hash and storing it in database
			r := RequestContainer{Details: pl.Request}
			key := r.Hash()

			// regenerating key
			pl.ID = key

			bts, err := pl.Encode()
			if err != nil {
				log.WithFields(log.Fields{
					"error": err.Error(),
				}).Error("Failed to encode payload")
				failed += 1
			} else {
				// hook
				var en Entry
				en.ActionType = ActionTypeRequestCaptured
				en.Message = "imported"
				en.Time = time.Now()
				en.Data = bts

				if err := d.Hooks.Fire(ActionTypeRequestCaptured, &en); err != nil {
					log.WithFields(log.Fields{
						"error":      err.Error(),
						"message":    en.Message,
						"actionType": ActionTypeRequestCaptured,
					}).Error("failed to fire hook")
				}

				d.Cache.Set([]byte(key), bts)
				if err == nil {
					success += 1
				} else {
					failed += 1
				}
			}
		}
		log.WithFields(log.Fields{
			"total":      len(payloads),
			"successful": success,
			"failed":     failed,
		}).Info("payloads imported")
		return nil
	} else {
		return fmt.Errorf("Bad request. Nothing to import!")
	}

}
<|endoftext|>


<commit_before>package binary

import (
	"bytes"
	"errors"
	"reflect"
	"strings"
	"unsafe"
)

// Marshaler is a interface implemented by types that can marshal themselves into binary stream data.
type Marshaler interface {
	MarshalStream(*bytes.Buffer) error
}

// Unmarshaler is a interface implemented by types that can unmarshal binary stream data to themselves.
type Unmarshaler interface {
	UnmarshalStream(*bytes.Buffer) error
}

// Marshal encodes struct v into buf.
// If v is not a struct, Marshal returns an InvalidMarshalTypeError.
func Marshal(v interface{}, buf *bytes.Buffer) error {
	vv := reflect.ValueOf(v)
	t := vv.Type()
	if t.Kind() != reflect.Struct {
		return InvalidMarshalTypeError{t}
	}

	for i := 0; i < vv.NumField(); i++ {
		field := vv.Field(i)
		tag := strings.ToLower(t.Field(i).Tag.Get("stream"))
		if tag == "pass" || !field.CanInterface() {
			continue
		}

		sp := strings.Split(tag, ",")
		option := make(map[string]struct{})
		for _, v := range sp {
			option[v] = struct{}{}
		}

		fv := field.Interface()
		if marshaler, ok := fv.(Marshaler); ok {
			if err := marshaler.MarshalStream(buf); err != nil {
				return err
			}
			continue
		}

		var endian ByteOrder = BigEndian
		if _, ok := option["little"]; ok {
			endian = LittleEndian
		}

		if field.Kind() == reflect.Slice && i+1 != vv.NumField() {
			return MarshalError{
				errors.New("Exported slice element should be last while marshaling"),
				t.Field(i),
			}
		}

		if err := pack(field, buf, endian); err != nil {
			return MarshalError{err, t.Field(i)}
		}

	}
	return nil
}

func pack(v reflect.Value, buf *bytes.Buffer, endian ByteOrder) error {
	kind := v.Kind()
	fv := v.Interface()

	switch kind {
	case reflect.Int, reflect.Uint:
		break // explicit break expression to clarify separated case with "bool"

	case reflect.Bool:
		fv, ok := fv.(bool)
		if !ok {
			return TypeAssertionError{"bool"}
		}

		var err error
		if fv {
			err = buf.WriteByte(1)
		} else {
			err = buf.WriteByte(0)
		}

		if err != nil {
			return err
		}

	case reflect.Int8:
		fv, ok := fv.(int8)
		if !ok {
			return TypeAssertionError{"int8"}
		}
		if err := buf.WriteByte(*(*byte)(unsafe.Pointer(&fv))); err != nil {
			return err
		}

	case reflect.Uint8:
		fv, ok := fv.(byte)
		if !ok {
			return TypeAssertionError{"byte"}
		}
		if err := buf.WriteByte(fv); err != nil {
			return err
		}

	case reflect.Int16:
		fv, ok := fv.(int16)
		if !ok {
			return TypeAssertionError{"int16"}
		}
		b := make([]byte, 2)
		endian.PutInt16(b, fv)
		if _, err := buf.Write(b); err != nil {
			return err
		}

	case reflect.Uint16:
		fv, ok := fv.(uint16)
		if !ok {
			return TypeAssertionError{"uint16"}
		}
		b := make([]byte, 2)
		endian.PutUint16(b, fv)
		if _, err := buf.Write(b); err != nil {
			return err
		}

	case reflect.Int32:
		fv, ok := fv.(int32)
		if !ok {
			return TypeAssertionError{"int32"}
		}
		b := make([]byte, 4)
		endian.PutInt32(b, fv)
		if _, err := buf.Write(b); err != nil {
			return err
		}

	case reflect.Uint32:
		fv, ok := fv.(uint32)
		if !ok {
			return TypeAssertionError{"uint32"}
		}
		b := make([]byte, 4)
		endian.PutUint32(b, fv)
		if _, err := buf.Write(b); err != nil {
			return err
		}

	case reflect.Int64:
		fv, ok := fv.(int64)
		if !ok {
			return TypeAssertionError{"int64"}
		}
		b := make([]byte, 8)
		endian.PutInt64(b, fv)
		if _, err := buf.Write(b); err != nil {
			return err
		}

	case reflect.Uint64:
		fv, ok := fv.(uint64)
		if !ok {
			return TypeAssertionError{"uint64"}
		}
		b := make([]byte, 8)
		endian.PutUint64(b, fv)
		if _, err := buf.Write(b); err != nil {
			return err
		}

	case reflect.Float32:
		fv, ok := fv.(float32)
		if !ok {
			return TypeAssertionError{"float32"}
		}
		b := make([]byte, 4)
		endian.PutFloat32(b, fv)
		if _, err := buf.Write(b); err != nil {
			return err
		}

	case reflect.Float64:
		fv, ok := fv.(float64)
		if !ok {
			return TypeAssertionError{"float64"}
		}
		b := make([]byte, 8)
		endian.PutFloat64(b, fv)
		if _, err := buf.Write(b); err != nil {
			return err
		}

	case reflect.Struct:
		if err := Marshal(fv, buf); err != nil {
			return err
		}

	case reflect.Array, reflect.Slice:
		length := v.Len()
		if v.Type().Elem().Kind() == reflect.Uint8 {
			if _, err := buf.Write(v.Slice(0, length).Interface().([]byte)); err != nil {
				return err
			}
			break
		}

		for j := 0; j < length; j++ {
			if err := pack(v.Index(j), buf, endian); err != nil {
				return err
			}
		}

	}
	return nil
}

// Unmarshal parses binary stream data from buf and stores the result in the struct pointed by v.
func Unmarshal(v interface{}, buf *bytes.Buffer) error {
	vv := reflect.ValueOf(v).Elem()
	t := vv.Type()
	for i := 0; i < t.NumField(); i++ {
		field := vv.Field(i)
		tag := strings.ToLower(t.Field(i).Tag.Get("stream"))
		if tag == "pass" || !field.CanSet() {
			continue
		}

		sp := strings.Split(tag, ",")
		option := make(map[string]struct{})
		for _, v := range sp {
			option[v] = struct{}{}
		}

		fv := field.Addr().Interface()
		if unmarshaler, ok := fv.(Unmarshaler); ok {
			if err := unmarshaler.UnmarshalStream(buf); err != nil {
				return err
			}
			continue
		}

		var endian ByteOrder = BigEndian
		if _, ok := option["little"]; ok {
			endian = LittleEndian
		}

		if field.Kind() == reflect.Slice && i+1 != vv.NumField() {
			return UnmarshalError{
				errors.New("Exported slice element should be last while unmarshaling"),
				t.Field(i),
			}
		}

		if err := unpack(field, buf, endian); err != nil {
			return UnmarshalError{err, t.Field(i)}
		}
	}
	return nil
}

func unpack(v reflect.Value, buf *bytes.Buffer, endian ByteOrder) error {
	kind := v.Kind()

	switch kind {
	case reflect.Int, reflect.Uint:
		break // explicit break expression to clarify separated case with "bool"

	case reflect.Bool:
		x, err := buf.ReadByte()
		if err != nil {
			return err
		}
		if x != 0 {
			v.SetBool(true)
		}

	case reflect.Int8:
		x, err := buf.ReadByte()
		if err != nil {
			return err
		}
		v.SetInt(int64(*(*int8)(unsafe.Pointer(&x))))

	case reflect.Uint8:
		x, err := buf.ReadByte()
		if err != nil {
			return err
		}
		v.SetUint(uint64(x))

	case reflect.Int16:
		b := make([]byte, 2)
		if _, err := buf.Read(b); err != nil {
			return err
		}
		v.SetInt(int64(endian.Int16(b)))

	case reflect.Uint16:
		b := make([]byte, 2)
		if _, err := buf.Read(b); err != nil {
			return err
		}
		v.SetUint(uint64(endian.Uint16(b)))

	case reflect.Int32:
		b := make([]byte, 4)
		if _, err := buf.Read(b); err != nil {
			return err
		}
		v.SetInt(int64(endian.Int32(b)))

	case reflect.Uint32:
		b := make([]byte, 4)
		if _, err := buf.Read(b); err != nil {
			return err
		}
		v.SetUint(uint64(endian.Uint32(b)))

	case reflect.Int64:
		b := make([]byte, 8)
		if _, err := buf.Read(b); err != nil {
			return err
		}
		v.SetInt(endian.Int64(b))

	case reflect.Uint64:
		b := make([]byte, 8)
		if _, err := buf.Read(b); err != nil {
			return err
		}
		v.SetUint(endian.Uint64(b))

	case reflect.Float32:
		b := make([]byte, 4)
		if _, err := buf.Read(b); err != nil {
			return err
		}
		v.SetFloat(float64(endian.Float32(b)))

	case reflect.Float64:
		b := make([]byte, 8)
		if _, err := buf.Read(b); err != nil {
			return err
		}
		v.SetFloat(endian.Float64(b))

	case reflect.Struct:
		if err := Unmarshal(v.Addr().Interface(), buf); err != nil {
			return err
		}

	case reflect.Array, reflect.Slice:
		length := v.Len()
		if v.Type().Elem().Kind() == reflect.Uint8 {
			if _, err := buf.Read(v.Slice(0, length).Interface().([]byte)); err != nil {
				return err
			}
			break
		}

		for j := 0; j < length; j++ {
			if err := unpack(v.Index(j), buf, endian); err != nil {
				return err
			}
		}
	}
	return nil
}

type InvalidMarshalTypeError struct {
	T reflect.Type
}

func (err InvalidMarshalTypeError) Error() string {
	return "The second argument of Marshal should be struct; given " + err.T.Kind().String()
}

type InvalidUnmarshalTypeError struct {
	T reflect.Type
}

func (err InvalidUnmarshalTypeError) Error() string {
	return "The second argument of Marshal should be struct pointer; given " + err.T.Kind().String()
}

type TypeAssertionError struct {
	totype string
}

func (err TypeAssertionError) Error() string {
	return "Type assertion failed to " + err.totype
}

type MarshalError struct {
	E     error
	field reflect.StructField
}

func (err MarshalError) Error() string {
	return "Error while marshaling " + err.field.Name + ": " + err.E.Error()
}

type UnmarshalError struct {
	E     error
	field reflect.StructField
}

func (err UnmarshalError) Error() string {
	return "Error while marshaling " + err.field.Name + ": " + err.E.Error()
}
<commit_msg>Add more information to Unmarshaler doc-comments<commit_after>package binary

import (
	"bytes"
	"errors"
	"reflect"
	"strings"
	"unsafe"
)

// Marshaler is a interface implemented by types that can marshal themselves into binary stream data.
type Marshaler interface {
	MarshalStream(*bytes.Buffer) error
}

// Unmarshaler is a interface implemented by types that can unmarshal binary stream data to themselves.
// If a type is struct, UnmarshalStream should be nil-safe.
type Unmarshaler interface {
	UnmarshalStream(*bytes.Buffer) error
}

// Marshal encodes struct v into buf.
// If v is not a struct, Marshal returns an InvalidMarshalTypeError.
func Marshal(v interface{}, buf *bytes.Buffer) error {
	vv := reflect.ValueOf(v)
	t := vv.Type()
	if t.Kind() != reflect.Struct {
		return InvalidMarshalTypeError{t}
	}

	for i := 0; i < vv.NumField(); i++ {
		field := vv.Field(i)
		tag := strings.ToLower(t.Field(i).Tag.Get("stream"))
		if tag == "pass" || !field.CanInterface() {
			continue
		}

		sp := strings.Split(tag, ",")
		option := make(map[string]struct{})
		for _, v := range sp {
			option[v] = struct{}{}
		}

		fv := field.Interface()
		if marshaler, ok := fv.(Marshaler); ok {
			if err := marshaler.MarshalStream(buf); err != nil {
				return err
			}
			continue
		}

		var endian ByteOrder = BigEndian
		if _, ok := option["little"]; ok {
			endian = LittleEndian
		}

		if field.Kind() == reflect.Slice && i+1 != vv.NumField() {
			return MarshalError{
				errors.New("Exported slice element should be last while marshaling"),
				t.Field(i),
			}
		}

		if err := pack(field, buf, endian); err != nil {
			return MarshalError{err, t.Field(i)}
		}

	}
	return nil
}

func pack(v reflect.Value, buf *bytes.Buffer, endian ByteOrder) error {
	kind := v.Kind()
	fv := v.Interface()

	switch kind {
	case reflect.Int, reflect.Uint:
		break // explicit break expression to clarify separated case with "bool"

	case reflect.Bool:
		fv, ok := fv.(bool)
		if !ok {
			return TypeAssertionError{"bool"}
		}

		var err error
		if fv {
			err = buf.WriteByte(1)
		} else {
			err = buf.WriteByte(0)
		}

		if err != nil {
			return err
		}

	case reflect.Int8:
		fv, ok := fv.(int8)
		if !ok {
			return TypeAssertionError{"int8"}
		}
		if err := buf.WriteByte(*(*byte)(unsafe.Pointer(&fv))); err != nil {
			return err
		}

	case reflect.Uint8:
		fv, ok := fv.(byte)
		if !ok {
			return TypeAssertionError{"byte"}
		}
		if err := buf.WriteByte(fv); err != nil {
			return err
		}

	case reflect.Int16:
		fv, ok := fv.(int16)
		if !ok {
			return TypeAssertionError{"int16"}
		}
		b := make([]byte, 2)
		endian.PutInt16(b, fv)
		if _, err := buf.Write(b); err != nil {
			return err
		}

	case reflect.Uint16:
		fv, ok := fv.(uint16)
		if !ok {
			return TypeAssertionError{"uint16"}
		}
		b := make([]byte, 2)
		endian.PutUint16(b, fv)
		if _, err := buf.Write(b); err != nil {
			return err
		}

	case reflect.Int32:
		fv, ok := fv.(int32)
		if !ok {
			return TypeAssertionError{"int32"}
		}
		b := make([]byte, 4)
		endian.PutInt32(b, fv)
		if _, err := buf.Write(b); err != nil {
			return err
		}

	case reflect.Uint32:
		fv, ok := fv.(uint32)
		if !ok {
			return TypeAssertionError{"uint32"}
		}
		b := make([]byte, 4)
		endian.PutUint32(b, fv)
		if _, err := buf.Write(b); err != nil {
			return err
		}

	case reflect.Int64:
		fv, ok := fv.(int64)
		if !ok {
			return TypeAssertionError{"int64"}
		}
		b := make([]byte, 8)
		endian.PutInt64(b, fv)
		if _, err := buf.Write(b); err != nil {
			return err
		}

	case reflect.Uint64:
		fv, ok := fv.(uint64)
		if !ok {
			return TypeAssertionError{"uint64"}
		}
		b := make([]byte, 8)
		endian.PutUint64(b, fv)
		if _, err := buf.Write(b); err != nil {
			return err
		}

	case reflect.Float32:
		fv, ok := fv.(float32)
		if !ok {
			return TypeAssertionError{"float32"}
		}
		b := make([]byte, 4)
		endian.PutFloat32(b, fv)
		if _, err := buf.Write(b); err != nil {
			return err
		}

	case reflect.Float64:
		fv, ok := fv.(float64)
		if !ok {
			return TypeAssertionError{"float64"}
		}
		b := make([]byte, 8)
		endian.PutFloat64(b, fv)
		if _, err := buf.Write(b); err != nil {
			return err
		}

	case reflect.Struct:
		if err := Marshal(fv, buf); err != nil {
			return err
		}

	case reflect.Array, reflect.Slice:
		length := v.Len()
		if v.Type().Elem().Kind() == reflect.Uint8 {
			if _, err := buf.Write(v.Slice(0, length).Interface().([]byte)); err != nil {
				return err
			}
			break
		}

		for j := 0; j < length; j++ {
			if err := pack(v.Index(j), buf, endian); err != nil {
				return err
			}
		}

	}
	return nil
}

// Unmarshal parses binary stream data from buf and stores the result in the struct pointed by v.
func Unmarshal(v interface{}, buf *bytes.Buffer) error {
	vv := reflect.ValueOf(v).Elem()
	t := vv.Type()
	for i := 0; i < t.NumField(); i++ {
		field := vv.Field(i)
		tag := strings.ToLower(t.Field(i).Tag.Get("stream"))
		if tag == "pass" || !field.CanSet() {
			continue
		}

		sp := strings.Split(tag, ",")
		option := make(map[string]struct{})
		for _, v := range sp {
			option[v] = struct{}{}
		}

		fv := field.Addr().Interface()
		if unmarshaler, ok := fv.(Unmarshaler); ok {
			if err := unmarshaler.UnmarshalStream(buf); err != nil {
				return err
			}
			continue
		}

		var endian ByteOrder = BigEndian
		if _, ok := option["little"]; ok {
			endian = LittleEndian
		}

		if field.Kind() == reflect.Slice && i+1 != vv.NumField() {
			return UnmarshalError{
				errors.New("Exported slice element should be last while unmarshaling"),
				t.Field(i),
			}
		}

		if err := unpack(field, buf, endian); err != nil {
			return UnmarshalError{err, t.Field(i)}
		}
	}
	return nil
}

func unpack(v reflect.Value, buf *bytes.Buffer, endian ByteOrder) error {
	kind := v.Kind()

	switch kind {
	case reflect.Int, reflect.Uint:
		break // explicit break expression to clarify separated case with "bool"

	case reflect.Bool:
		x, err := buf.ReadByte()
		if err != nil {
			return err
		}
		if x != 0 {
			v.SetBool(true)
		}

	case reflect.Int8:
		x, err := buf.ReadByte()
		if err != nil {
			return err
		}
		v.SetInt(int64(*(*int8)(unsafe.Pointer(&x))))

	case reflect.Uint8:
		x, err := buf.ReadByte()
		if err != nil {
			return err
		}
		v.SetUint(uint64(x))

	case reflect.Int16:
		b := make([]byte, 2)
		if _, err := buf.Read(b); err != nil {
			return err
		}
		v.SetInt(int64(endian.Int16(b)))

	case reflect.Uint16:
		b := make([]byte, 2)
		if _, err := buf.Read(b); err != nil {
			return err
		}
		v.SetUint(uint64(endian.Uint16(b)))

	case reflect.Int32:
		b := make([]byte, 4)
		if _, err := buf.Read(b); err != nil {
			return err
		}
		v.SetInt(int64(endian.Int32(b)))

	case reflect.Uint32:
		b := make([]byte, 4)
		if _, err := buf.Read(b); err != nil {
			return err
		}
		v.SetUint(uint64(endian.Uint32(b)))

	case reflect.Int64:
		b := make([]byte, 8)
		if _, err := buf.Read(b); err != nil {
			return err
		}
		v.SetInt(endian.Int64(b))

	case reflect.Uint64:
		b := make([]byte, 8)
		if _, err := buf.Read(b); err != nil {
			return err
		}
		v.SetUint(endian.Uint64(b))

	case reflect.Float32:
		b := make([]byte, 4)
		if _, err := buf.Read(b); err != nil {
			return err
		}
		v.SetFloat(float64(endian.Float32(b)))

	case reflect.Float64:
		b := make([]byte, 8)
		if _, err := buf.Read(b); err != nil {
			return err
		}
		v.SetFloat(endian.Float64(b))

	case reflect.Struct:
		if err := Unmarshal(v.Addr().Interface(), buf); err != nil {
			return err
		}

	case reflect.Array, reflect.Slice:
		length := v.Len()
		if v.Type().Elem().Kind() == reflect.Uint8 {
			if _, err := buf.Read(v.Slice(0, length).Interface().([]byte)); err != nil {
				return err
			}
			break
		}

		for j := 0; j < length; j++ {
			if err := unpack(v.Index(j), buf, endian); err != nil {
				return err
			}
		}
	}
	return nil
}

type InvalidMarshalTypeError struct {
	T reflect.Type
}

func (err InvalidMarshalTypeError) Error() string {
	return "The second argument of Marshal should be struct; given " + err.T.Kind().String()
}

type InvalidUnmarshalTypeError struct {
	T reflect.Type
}

func (err InvalidUnmarshalTypeError) Error() string {
	return "The second argument of Marshal should be struct pointer; given " + err.T.Kind().String()
}

type TypeAssertionError struct {
	totype string
}

func (err TypeAssertionError) Error() string {
	return "Type assertion failed to " + err.totype
}

type MarshalError struct {
	E     error
	field reflect.StructField
}

func (err MarshalError) Error() string {
	return "Error while marshaling " + err.field.Name + ": " + err.E.Error()
}

type UnmarshalError struct {
	E     error
	field reflect.StructField
}

func (err UnmarshalError) Error() string {
	return "Error while marshaling " + err.field.Name + ": " + err.E.Error()
}
<|endoftext|>


<commit_before>package util_test

import (
	. "github.com/naaman/busl/util"
	"testing"
)

func TestIsTrueTrueValueIsTrue(t *testing.T) {
	trueCheck, _ := IsTrue.Check([]interface{}{true}, []string{})
	if !trueCheck {
		t.Errorf("Expected IsTrue to return true, but got false.")
	}
}

func TestIsTrueFalseValueIsFalse(t *testing.T) {
	trueCheck, _ := IsTrue.Check([]interface{}{false}, []string{})
	if trueCheck {
		t.Errorf("Expected IsTrue to return false, but got true.")
	}
}

func TestIsFalseFalseValueIsTrue(t *testing.T) {
	falseCheck, _ := IsFalse.Check([]interface{}{false}, []string{})
	if !falseCheck {
		t.Errorf("Expected IsFalse to return true, but got false.")
	}
}

func TestIsFalseTrueValueIsFalse(t *testing.T) {
	falseCheck, _ := IsFalse.Check([]interface{}{true}, []string{})
	if falseCheck {
		t.Errorf("Expected IsFalse to return false, but got true.")
	}
}

func TestIsEmptyStringEmptyStringValueIsTrue(t *testing.T) {
	emptyStringCheck, _ := IsEmptyString.Check([]interface{}{""}, []string{})
	if !emptyStringCheck {
		t.Errorf("Expected IsEmptyString to return true, but got false.")
	}
}

func TestIsEmptyStringStringWithDataIsFalse(t *testing.T) {
	emptyStringCheck, _ := IsEmptyString.Check([]interface{}{"d"}, []string{})
	if emptyStringCheck {
		t.Errorf("Expected IsEmptyString to return true, but got false.")
	}
}

func TestIsEmptyStringNilValueIsFalse(t *testing.T) {
	emptyStringCheck, _ := IsEmptyString.Check([]interface{}{nil}, []string{})
	if emptyStringCheck {
		t.Errorf("Expected IsEmptyString to return true, but got false.")
	}
}
<commit_msg>Rewrite checkers tests as a table.<commit_after>package util_test

import (
	. "github.com/naaman/busl/util"
	check "gopkg.in/check.v1"
	"testing"
)

type checkerTest struct {
	check    check.Checker
	input    []interface{}
	expected bool
}

var checkerTests = []checkerTest{
	checkerTest{IsTrue, []interface{}{true}, true},
	checkerTest{IsTrue, []interface{}{false}, false},
	checkerTest{IsFalse, []interface{}{false}, true},
	checkerTest{IsFalse, []interface{}{true}, false},
	checkerTest{IsEmptyString, []interface{}{""}, true},
	checkerTest{IsEmptyString, []interface{}{"d"}, false},
	checkerTest{IsEmptyString, []interface{}{nil}, false},
}

func TestCheckers(t *testing.T) {
	for _, c := range checkerTests {
		actual, _ := c.check.Check(c.input, []string{})
		if actual != c.expected {
			t.Errorf("Expected %T to return %v, but got %v.", c.check, c.expected, actual)
		}
	}
}
<|endoftext|>


<commit_before>package util

import (
	"fmt"
	"github.com/codegangsta/cli"
)

func (u *SomaUtil) GetCliArgumentCount(c *cli.Context) int {
	a := c.Args()
	if !a.Present() {
		return 0
	}
	return len(a.Tail()) + 1
}

func (u *SomaUtil) ValidateCliArgument(c *cli.Context, pos uint8, s string) {
	a := c.Args()
	if a.Get(int(pos)-1) != s {
		u.Abort(fmt.Sprintf("Syntax error, missing keyword: ", s))
	}
}

func (u *SomaUtil) ValidateCliArgumentCount(c *cli.Context, i uint8) {
	a := c.Args()
	if i == 0 {
		if a.Present() {
			u.Abort("Syntax error, command takes no arguments")
		}
	} else {
		if !a.Present() || len(a.Tail()) != (int(i)-1) {
			u.Abort("Syntax error")
		}
	}
}

func (u *SomaUtil) GetFullArgumentSlice(c *cli.Context) []string {
	sl := []string{c.Args().First()}
	sl = append(sl, c.Args().Tail()...)
	return sl
}

func (u *SomaUtil) ParseVariableArguments(keys []string, rKeys []string, args []string) (map[string]string, []string) {
	// return map of the parse result
	result := make(map[string]string)
	// map to test which required keys were found
	argumentCheck := make(map[string]bool)
	// return slice which optional keys were found
	optionalKeys := make([]string, 0)
	// no required keys is valid
	if len(rKeys) > 0 {
		for _, key := range rKeys {
			argumentCheck[key] = false
		}
	}
	skipNext := false

	for pos, val := range args {
		// skip current argument if last argument was a keyword
		if skipNext {
			skipNext = false
			continue
		}

		if u.SliceContainsString(val, keys) {
			// check back-to-back keywords
			u.CheckStringNotAKeyword(args[pos+1], keys)
			result[val] = args[pos+1]
			argumentCheck[val] = true
			skipNext = true
			if !u.SliceContainsString(val, rKeys) {
				optionalKeys = append(optionalKeys, val)
			}
			continue
		}
		// keywords trigger continue, arguments are skipped over.
		// reaching this is an error
		u.Abort(fmt.Sprintf("Syntax error, erroneus argument: %s", val))
	}

	// check we managed to collect all required keywords
	for _, v := range argumentCheck {
		if !v {
			u.Abort(fmt.Sprintf("Syntax error, missing keyword: %s", v))
		}
	}

	return result, optionalKeys
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix
<commit_msg>Add util function ParseVariadicArguments<commit_after>package util

import (
	"fmt"
	"github.com/codegangsta/cli"
)

func (u *SomaUtil) GetCliArgumentCount(c *cli.Context) int {
	a := c.Args()
	if !a.Present() {
		return 0
	}
	return len(a.Tail()) + 1
}

func (u *SomaUtil) ValidateCliArgument(c *cli.Context, pos uint8, s string) {
	a := c.Args()
	if a.Get(int(pos)-1) != s {
		u.Abort(fmt.Sprintf("Syntax error, missing keyword: ", s))
	}
}

func (u *SomaUtil) ValidateCliArgumentCount(c *cli.Context, i uint8) {
	a := c.Args()
	if i == 0 {
		if a.Present() {
			u.Abort("Syntax error, command takes no arguments")
		}
	} else {
		if !a.Present() || len(a.Tail()) != (int(i)-1) {
			u.Abort("Syntax error")
		}
	}
}

func (u *SomaUtil) GetFullArgumentSlice(c *cli.Context) []string {
	sl := []string{c.Args().First()}
	sl = append(sl, c.Args().Tail()...)
	return sl
}

func (u *SomaUtil) ParseVariableArguments(keys []string, rKeys []string, args []string) (map[string]string, []string) {
	// return map of the parse result
	result := make(map[string]string)
	// map to test which required keys were found
	argumentCheck := make(map[string]bool)
	// return slice which optional keys were found
	optionalKeys := make([]string, 0)
	// no required keys is valid
	if len(rKeys) > 0 {
		for _, key := range rKeys {
			argumentCheck[key] = false
		}
	}
	skipNext := false

	for pos, val := range args {
		// skip current argument if last argument was a keyword
		if skipNext {
			skipNext = false
			continue
		}

		if u.SliceContainsString(val, keys) {
			// check back-to-back keywords
			u.CheckStringNotAKeyword(args[pos+1], keys)
			result[val] = args[pos+1]
			argumentCheck[val] = true
			skipNext = true
			if !u.SliceContainsString(val, rKeys) {
				optionalKeys = append(optionalKeys, val)
			}
			continue
		}
		// keywords trigger continue, arguments are skipped over.
		// reaching this is an error
		u.Abort(fmt.Sprintf("Syntax error, erroneus argument: %s", val))
	}

	// check we managed to collect all required keywords
	for _, v := range argumentCheck {
		if !v {
			u.Abort(fmt.Sprintf("Syntax error, missing keyword: %s", v))
		}
	}

	return result, optionalKeys
}

/*
 * This function parses whitespace separated argument lists of
 * keyword/value pairs were keywords can be specified multiple
 * times, some keywords are required and some only allowed once.
 * Sequence of multiple keywords are detected and lead to abort
 *
 * multKeys => [ "port", "transport" ]
 * uniqKeys => [ "team" ]
 * reqKeys  => [ "team" ]
 * args     => [ "port", "53", "transport", "tcp", "transport",
 *               "udp", "team", "ITOMI" ]
 *
 * result => result["team"] = [ "ITOMI" ]
 *           result["port"] = [ "53" ]
 *           result["transport"] = [ "tcp", "udp" ]
 */
func (u *SomaUtil) ParseVariadicArguments(
	multKeys []string, // keys that may appear multiple times
	uniqKeys []string, // keys that are allowed at most once
	reqKeys []string, // keys that are required at least one
	args []string, // arguments to parse
) map[string][]string {
	// returns a map of slices of string
	result := make(map[string][]string)

	// merge key slices
	keys := append(multKeys, uniqKeys...)

	// helper to skip over next value in args slice
	skip := false

	for pos, val := range args {
		// skip current arg if last argument was a keyword
		if skip {
			skip = false
			continue
		}

		if u.SliceContainsString(val, keys) {
			// check for back-to-back keyswords
			u.CheckStringNotAKeyword(args[pos+1], keys)

			// append value of current keyword into result map
			result[val] = append(result[val], args[pos+1])
			skip = true
			continue
		}
		// keywords trigger continue before this
		// values after keywords are skip'ed
		// reaching this is an error
		u.Abort(fmt.Sprintf("Syntax error, erroneus argument: %s", val))
	}

	// check if we managed to collect all required keywords
	for _, key := range reqKeys {
		_, ok := result[key] // ok is false if slice is nil
		if !ok {
			u.Abort(fmt.Sprintf("Syntax error, missing keyword: %s", key))
		}
	}

	// check if unique keywords were only specified once
	for _, key := range uniqKeys {
		sl, ok := result[key]
		if ok && (len(sl) > 1) {
			u.Abort(fmt.Sprintf("Syntax error, keyword must only be provided once: %s", key))
		}
	}

	return result
}

// vim: ts=4 sw=4 sts=4 noet fenc=utf-8 ffs=unix
<|endoftext|>


<commit_before>// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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.

// This file implements a cadvisor datasource, that collects metrics from an instance
// of cadvisor runing on a specific host.

package datasource

import (
	"testing"
	"time"

	cadvisor "github.com/google/cadvisor/info/v1"
	fuzz "github.com/google/gofuzz"
	"github.com/stretchr/testify/assert"
)

func TestWithFuzzInput(t *testing.T) {
	for i := 0; i < 1000; i++ {
		testWithFuzzInternal()
	}
}

func testWithFuzzInternal() {
	inputStats := []*cadvisor.ContainerStats{}
	fuzz.New().Fuzz(&inputStats)
	_ = sampleContainerStats(inputStats, time.Now(), time.Nanosecond, false)
}

func TestWithNoDownsampling(t *testing.T) {
	start := time.Now()
	resolution := time.Second
	inputStats := []*cadvisor.ContainerStats{
		{
			Timestamp: start,
		},
		{
			Timestamp: start.Add(resolution),
		},
		{
			Timestamp: start.Add(resolution * 2),
		},
		{
			Timestamp: start.Add(resolution * 3),
		},
	}
	output := sampleContainerStats(inputStats, start, resolution, false)
	assert.Equal(t, output, inputStats)
}

func TestWithDownsampling(t *testing.T) {
	start := time.Now()
	inputStats := []*cadvisor.ContainerStats{}
	for i := 1; i <= 4; i++ {
		inputStats = append(inputStats, &cadvisor.ContainerStats{Timestamp: start.Add(time.Second * time.Duration(i))})
	}

	output := sampleContainerStats(inputStats, start, time.Second*2, false)
	assert.Len(t, output, 2)
}

func TestWithLargeDownsampling(t *testing.T) {
	start := time.Now()
	inputStats := []*cadvisor.ContainerStats{}
	for i := 1; i <= 100; i++ {
		inputStats = append(inputStats, &cadvisor.ContainerStats{Timestamp: start.Add(time.Second * time.Duration(i))})
	}
	output := sampleContainerStats(inputStats, start, time.Minute, false)
	assert.Len(t, output, 2)
}
<commit_msg>Added unit tests for sampling stats with aligning enabled<commit_after>// Copyright 2014 Google Inc. All Rights Reserved.
//
// 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.

// This file implements a cadvisor datasource, that collects metrics from an instance
// of cadvisor runing on a specific host.

package datasource

import (
	"testing"
	"time"

	cadvisor "github.com/google/cadvisor/info/v1"
	fuzz "github.com/google/gofuzz"
	"github.com/stretchr/testify/assert"
)

func TestWithFuzzInput(t *testing.T) {
	for i := 0; i < 1000; i++ {
		testWithFuzzInternal()
	}
}

func testWithFuzzInternal() {
	inputStats := []*cadvisor.ContainerStats{}
	fuzz.New().Fuzz(&inputStats)
	_ = sampleContainerStats(inputStats, time.Now(), time.Nanosecond, false)
	_ = sampleContainerStats(inputStats, time.Now(), time.Nanosecond, true)
}

func TestWithNoDownsampling(t *testing.T) {
	start := time.Now()
	resolution := time.Second
	inputStats := []*cadvisor.ContainerStats{
		{
			Timestamp: start,
		},
		{
			Timestamp: start.Add(resolution),
		},
		{
			Timestamp: start.Add(resolution * 2),
		},
		{
			Timestamp: start.Add(resolution * 3),
		},
	}
	output := sampleContainerStats(inputStats, start, resolution, false)
	assert.Equal(t, output, inputStats)
}

func TestWithDownsampling(t *testing.T) {
	start := time.Now()
	inputStats := []*cadvisor.ContainerStats{}
	for i := 1; i <= 4; i++ {
		inputStats = append(inputStats, &cadvisor.ContainerStats{Timestamp: start.Add(time.Second * time.Duration(i))})
	}

	output := sampleContainerStats(inputStats, start, time.Second*2, false)
	assert.Len(t, output, 2)
}

func TestWithLargeDownsampling(t *testing.T) {
	start := time.Now()
	inputStats := []*cadvisor.ContainerStats{}
	for i := 1; i <= 100; i++ {
		inputStats = append(inputStats, &cadvisor.ContainerStats{Timestamp: start.Add(time.Second * time.Duration(i))})
	}
	output := sampleContainerStats(inputStats, start, time.Minute, false)
	assert.Len(t, output, 2)
}

func getTime(h, m, s int) time.Time {
	return time.Date(2015, time.July, 10, h, m, s, 0, time.UTC)
}

func TestWithNoDownsamplingAndAligning(t *testing.T) {
	resolution := time.Minute
	start := getTime(10, 0, 5)
	inputStats := []*cadvisor.ContainerStats{
		{
			Timestamp: getTime(10, 1, 5),
		},
		{
			Timestamp: getTime(10, 2, 5),
		},
	}
	outputStats := []*cadvisor.ContainerStats{
		{
			Timestamp: getTime(10, 1, 0),
		},
		{
			Timestamp: getTime(10, 2, 0),
		},
	}
	output := sampleContainerStats(inputStats, start, resolution, true)
	assert.Equal(t, output, outputStats)
}

func TestWithDownsamplingAndAligning(t *testing.T) {
	resolution := time.Minute
	start := getTime(10, 0, 5)
	inputStats := []*cadvisor.ContainerStats{
		{
			Timestamp: getTime(10, 0, 1),
		},
		{
			Timestamp: getTime(10, 0, 10),
		},
		{
			Timestamp: getTime(10, 1, 1),
		},
		{
			Timestamp: getTime(10, 1, 10),
		},
		{
			Timestamp: getTime(10, 2, 1),
		},
		{
			Timestamp: getTime(10, 2, 10),
		},
	}
	outputStats := []*cadvisor.ContainerStats{
		{
			Timestamp: getTime(10, 1, 0),
		},
		{
			Timestamp: getTime(10, 2, 0),
		},
	}
	output := sampleContainerStats(inputStats, start, resolution, true)
	assert.Equal(t, output, outputStats)
}

func TestWithAligningAndAlignedStart(t *testing.T) {
	resolution := time.Minute
	start := getTime(10, 0, 0)
	inputStats := []*cadvisor.ContainerStats{
		{
			Timestamp: getTime(10, 0, 1),
		},
		{
			Timestamp: getTime(10, 0, 10),
		},
		{
			Timestamp: getTime(10, 1, 1),
		},
		{
			Timestamp: getTime(10, 1, 10),
		},
		{
			Timestamp: getTime(10, 2, 1),
		},
		{
			Timestamp: getTime(10, 2, 10),
		},
	}
	outputStats := []*cadvisor.ContainerStats{
		{
			Timestamp: getTime(10, 0, 0),
		},
		{
			Timestamp: getTime(10, 1, 0),
		},
		{
			Timestamp: getTime(10, 2, 0),
		},
	}
	output := sampleContainerStats(inputStats, start, resolution, true)
	assert.Equal(t, output, outputStats)
}
<|endoftext|>


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

// Copyright 2015 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package types

import (
	"math"
	"strconv"
	"strings"

	"github.com/juju/errors"
	"github.com/pingcap/tidb/mysql"
	"github.com/pingcap/tidb/sessionctx/variable"
)

func truncateStr(str string, flen int) string {
	if flen != UnspecifiedLength && len(str) > flen {
		str = str[:flen]
	}
	return str
}

var unsignedUpperBound = map[byte]uint64{
	mysql.TypeTiny:     math.MaxUint8,
	mysql.TypeShort:    math.MaxUint16,
	mysql.TypeInt24:    mysql.MaxUint24,
	mysql.TypeLong:     math.MaxUint32,
	mysql.TypeLonglong: math.MaxUint64,
	mysql.TypeBit:      math.MaxUint64,
	mysql.TypeEnum:     math.MaxUint64,
	mysql.TypeSet:      math.MaxUint64,
}

var signedUpperBound = map[byte]int64{
	mysql.TypeTiny:     math.MaxInt8,
	mysql.TypeShort:    math.MaxInt16,
	mysql.TypeInt24:    mysql.MaxInt24,
	mysql.TypeLong:     math.MaxInt32,
	mysql.TypeLonglong: math.MaxInt64,
}

var signedLowerBound = map[byte]int64{
	mysql.TypeTiny:     math.MinInt8,
	mysql.TypeShort:    math.MinInt16,
	mysql.TypeInt24:    mysql.MinInt24,
	mysql.TypeLong:     math.MinInt32,
	mysql.TypeLonglong: math.MinInt64,
}

func convertFloatToInt(sc *variable.StatementContext, fval float64, lowerBound, upperBound int64, tp byte) (int64, error) {
	val := RoundFloat(fval)
	if val < float64(lowerBound) {
		return lowerBound, overflow(val, tp)
	}

	if val > float64(upperBound) {
		return upperBound, overflow(val, tp)
	}
	return int64(val), nil
}

func convertIntToInt(val int64, lowerBound int64, upperBound int64, tp byte) (int64, error) {
	if val < lowerBound {
		return lowerBound, overflow(val, tp)
	}

	if val > upperBound {
		return upperBound, overflow(val, tp)
	}

	return val, nil
}

func convertUintToInt(val uint64, upperBound int64, tp byte) (int64, error) {
	if val > uint64(upperBound) {
		return upperBound, overflow(val, tp)
	}

	return int64(val), nil
}

func convertIntToUint(val int64, upperBound uint64, tp byte) (uint64, error) {
	if val < 0 {
		return 0, overflow(val, tp)
	}

	if uint64(val) > upperBound {
		return upperBound, overflow(val, tp)
	}

	return uint64(val), nil
}

func convertUintToUint(val uint64, upperBound uint64, tp byte) (uint64, error) {
	if val > upperBound {
		return upperBound, overflow(val, tp)
	}

	return val, nil
}

func convertFloatToUint(sc *variable.StatementContext, fval float64, upperBound uint64, tp byte) (uint64, error) {
	val := RoundFloat(fval)
	if val < 0 {
		return uint64(int64(val)), overflow(val, tp)
	}

	if val > float64(upperBound) {
		return upperBound, overflow(val, tp)
	}
	return uint64(val), nil
}

func isCastType(tp byte) bool {
	switch tp {
	case mysql.TypeString, mysql.TypeDuration, mysql.TypeDatetime,
		mysql.TypeDate, mysql.TypeLonglong, mysql.TypeNewDecimal:
		return true
	}
	return false
}

// StrToInt converts a string to an integer at the best-effort.
func StrToInt(sc *variable.StatementContext, str string) (int64, error) {
	str = strings.TrimSpace(str)
	validPrefix, err := getValidIntPrefix(sc, str)
	iVal, err1 := strconv.ParseInt(validPrefix, 10, 64)
	if err1 != nil {
		return iVal, errors.Trace(ErrOverflow)
	}
	return iVal, errors.Trace(err)
}

// StrToUint converts a string to an unsigned interger at the best-effortt.
func StrToUint(sc *variable.StatementContext, str string) (uint64, error) {
	str = strings.TrimSpace(str)
	validPrefix, err := getValidIntPrefix(sc, str)
	if validPrefix[0] == '+' {
		validPrefix = validPrefix[1:]
	}
	uVal, err1 := strconv.ParseUint(validPrefix, 10, 64)
	if err1 != nil {
		return uVal, errors.Trace(ErrOverflow)
	}
	return uVal, errors.Trace(err)
}

// getValidIntPrefix gets prefix of the string which can be successfully parsed as int.
func getValidIntPrefix(sc *variable.StatementContext, str string) (string, error) {
	floatPrefix, err := getValidFloatPrefix(sc, str)
	if err != nil {
		return floatPrefix, errors.Trace(err)
	}
	return floatStrToIntStr(floatPrefix)
}

// floatStrToIntStr converts a valid float string into valid integer string which can be parsed by
// strconv.ParseInt, we can't parse float first then convert it to string because precision will
// be lost.
func floatStrToIntStr(validFloat string) (string, error) {
	var dotIdx = -1
	var eIdx = -1
	for i := 0; i < len(validFloat); i++ {
		switch validFloat[i] {
		case '.':
			dotIdx = i
		case 'e', 'E':
			eIdx = i
		}
	}
	if dotIdx == -1 && eIdx == -1 {
		return validFloat, nil
	}
	var intCnt int
	digits := make([]byte, 0, len(validFloat))
	if dotIdx == -1 {
		digits = append(digits, validFloat[:eIdx]...)
		intCnt = len(digits)
	} else {
		digits = append(digits, validFloat[:dotIdx]...)
		intCnt = len(digits)
		if eIdx == -1 {
			digits = append(digits, validFloat[dotIdx+1:]...)
		} else {
			digits = append(digits, validFloat[dotIdx+1:eIdx]...)
		}
	}
	if eIdx != -1 {
		exp, err := strconv.Atoi(validFloat[eIdx+1:])
		if err != nil {
			return validFloat, errors.Trace(err)
		}
		if exp > 0 && intCnt > (math.MaxInt64-exp) {
			// (exp + incCnt) overflows MaxInt64.
			return validFloat, errors.Trace(ErrOverflow)
		}
		intCnt += exp
	}
	if intCnt <= 0 {
		return "0", nil
	}
	if intCnt == 1 && (digits[0] == '-' || digits[0] == '+') {
		return "0", nil
	}
	var validInt string
	if intCnt <= len(digits) {
		validInt = string(digits[:intCnt])
	} else {
		extraZeroCount := intCnt - len(digits)
		if extraZeroCount > 20 {
			// Return overflow to avoid allocating too much memory.
			return validFloat, errors.Trace(ErrOverflow)
		}
		validInt = string(digits) + strings.Repeat("0", extraZeroCount)
	}
	return validInt, nil
}

// StrToFloat converts a string to a float64 at the best-effort.
func StrToFloat(sc *variable.StatementContext, str string) (float64, error) {
	str = strings.TrimSpace(str)
	validStr, err := getValidFloatPrefix(sc, str)
	f, err1 := strconv.ParseFloat(validStr, 64)
	if err1 != nil {
		return f, errors.Trace(err1)
	}
	return f, errors.Trace(err)
}

// getValidFloatPrefix gets prefix of string which can be successfully parsed as float.
func getValidFloatPrefix(sc *variable.StatementContext, s string) (valid string, err error) {
	var (
		sawDot   bool
		sawDigit bool
		validLen int
		eIdx     int
	)
	for i := 0; i < len(s); i++ {
		c := s[i]
		if c == '+' || c == '-' {
			if i != 0 && i != eIdx+1 { // "1e+1" is valid.
				break
			}
		} else if c == '.' {
			if sawDot || eIdx > 0 { // "1.1." or "1e1.1"
				break
			}
			sawDot = true
			if sawDigit { // "123." is valid.
				validLen = i + 1
			}
		} else if c == 'e' || c == 'E' {
			if !sawDigit { // "+.e"
				break
			}
			if eIdx != 0 { // "1e5e"
				break
			}
			eIdx = i
		} else if c < '0' || c > '9' {
			break
		} else {
			sawDigit = true
			validLen = i + 1
		}
	}
	valid = s[:validLen]
	if valid == "" {
		valid = "0"
	}
	if validLen == 0 || validLen != len(s) {
		err = errors.Trace(handleTruncateError(sc))
	}
	return valid, err
}

// ToString converts an interface to a string.
func ToString(value interface{}) (string, error) {
	switch v := value.(type) {
	case bool:
		if v {
			return "1", nil
		}
		return "0", nil
	case int:
		return strconv.FormatInt(int64(v), 10), nil
	case int64:
		return strconv.FormatInt(int64(v), 10), nil
	case uint64:
		return strconv.FormatUint(uint64(v), 10), nil
	case float32:
		return strconv.FormatFloat(float64(v), 'f', -1, 32), nil
	case float64:
		return strconv.FormatFloat(float64(v), 'f', -1, 64), nil
	case string:
		return v, nil
	case []byte:
		return string(v), nil
	case Time:
		return v.String(), nil
	case Duration:
		return v.String(), nil
	case *MyDecimal:
		return v.String(), nil
	case Hex:
		return v.ToString(), nil
	case Bit:
		return v.ToString(), nil
	case Enum:
		return v.String(), nil
	case Set:
		return v.String(), nil
	default:
		return "", errors.Errorf("cannot convert %v(type %T) to string", value, value)
	}
}
<commit_msg>types: optimize floatStrToIntStr (#2396)<commit_after>// Copyright 2014 The ql Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSES/QL-LICENSE file.

// Copyright 2015 PingCAP, Inc.
//
// 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,
// See the License for the specific language governing permissions and
// limitations under the License.

package types

import (
	"math"
	"strconv"
	"strings"

	"github.com/juju/errors"
	"github.com/pingcap/tidb/mysql"
	"github.com/pingcap/tidb/sessionctx/variable"
)

func truncateStr(str string, flen int) string {
	if flen != UnspecifiedLength && len(str) > flen {
		str = str[:flen]
	}
	return str
}

var unsignedUpperBound = map[byte]uint64{
	mysql.TypeTiny:     math.MaxUint8,
	mysql.TypeShort:    math.MaxUint16,
	mysql.TypeInt24:    mysql.MaxUint24,
	mysql.TypeLong:     math.MaxUint32,
	mysql.TypeLonglong: math.MaxUint64,
	mysql.TypeBit:      math.MaxUint64,
	mysql.TypeEnum:     math.MaxUint64,
	mysql.TypeSet:      math.MaxUint64,
}

var signedUpperBound = map[byte]int64{
	mysql.TypeTiny:     math.MaxInt8,
	mysql.TypeShort:    math.MaxInt16,
	mysql.TypeInt24:    mysql.MaxInt24,
	mysql.TypeLong:     math.MaxInt32,
	mysql.TypeLonglong: math.MaxInt64,
}

var signedLowerBound = map[byte]int64{
	mysql.TypeTiny:     math.MinInt8,
	mysql.TypeShort:    math.MinInt16,
	mysql.TypeInt24:    mysql.MinInt24,
	mysql.TypeLong:     math.MinInt32,
	mysql.TypeLonglong: math.MinInt64,
}

func convertFloatToInt(sc *variable.StatementContext, fval float64, lowerBound, upperBound int64, tp byte) (int64, error) {
	val := RoundFloat(fval)
	if val < float64(lowerBound) {
		return lowerBound, overflow(val, tp)
	}

	if val > float64(upperBound) {
		return upperBound, overflow(val, tp)
	}
	return int64(val), nil
}

func convertIntToInt(val int64, lowerBound int64, upperBound int64, tp byte) (int64, error) {
	if val < lowerBound {
		return lowerBound, overflow(val, tp)
	}

	if val > upperBound {
		return upperBound, overflow(val, tp)
	}

	return val, nil
}

func convertUintToInt(val uint64, upperBound int64, tp byte) (int64, error) {
	if val > uint64(upperBound) {
		return upperBound, overflow(val, tp)
	}

	return int64(val), nil
}

func convertIntToUint(val int64, upperBound uint64, tp byte) (uint64, error) {
	if val < 0 {
		return 0, overflow(val, tp)
	}

	if uint64(val) > upperBound {
		return upperBound, overflow(val, tp)
	}

	return uint64(val), nil
}

func convertUintToUint(val uint64, upperBound uint64, tp byte) (uint64, error) {
	if val > upperBound {
		return upperBound, overflow(val, tp)
	}

	return val, nil
}

func convertFloatToUint(sc *variable.StatementContext, fval float64, upperBound uint64, tp byte) (uint64, error) {
	val := RoundFloat(fval)
	if val < 0 {
		return uint64(int64(val)), overflow(val, tp)
	}

	if val > float64(upperBound) {
		return upperBound, overflow(val, tp)
	}
	return uint64(val), nil
}

func isCastType(tp byte) bool {
	switch tp {
	case mysql.TypeString, mysql.TypeDuration, mysql.TypeDatetime,
		mysql.TypeDate, mysql.TypeLonglong, mysql.TypeNewDecimal:
		return true
	}
	return false
}

// StrToInt converts a string to an integer at the best-effort.
func StrToInt(sc *variable.StatementContext, str string) (int64, error) {
	str = strings.TrimSpace(str)
	validPrefix, err := getValidIntPrefix(sc, str)
	iVal, err1 := strconv.ParseInt(validPrefix, 10, 64)
	if err1 != nil {
		return iVal, errors.Trace(ErrOverflow)
	}
	return iVal, errors.Trace(err)
}

// StrToUint converts a string to an unsigned interger at the best-effortt.
func StrToUint(sc *variable.StatementContext, str string) (uint64, error) {
	str = strings.TrimSpace(str)
	validPrefix, err := getValidIntPrefix(sc, str)
	if validPrefix[0] == '+' {
		validPrefix = validPrefix[1:]
	}
	uVal, err1 := strconv.ParseUint(validPrefix, 10, 64)
	if err1 != nil {
		return uVal, errors.Trace(ErrOverflow)
	}
	return uVal, errors.Trace(err)
}

// getValidIntPrefix gets prefix of the string which can be successfully parsed as int.
func getValidIntPrefix(sc *variable.StatementContext, str string) (string, error) {
	floatPrefix, err := getValidFloatPrefix(sc, str)
	if err != nil {
		return floatPrefix, errors.Trace(err)
	}
	return floatStrToIntStr(floatPrefix)
}

// floatStrToIntStr converts a valid float string into valid integer string which can be parsed by
// strconv.ParseInt, we can't parse float first then convert it to string because precision will
// be lost.
func floatStrToIntStr(validFloat string) (string, error) {
	var dotIdx = -1
	var eIdx = -1
	for i := 0; i < len(validFloat); i++ {
		switch validFloat[i] {
		case '.':
			dotIdx = i
		case 'e', 'E':
			eIdx = i
		}
	}
	if eIdx == -1 {
		if dotIdx == -1 {
			return validFloat, nil
		}
		return validFloat[:dotIdx], nil
	}
	var intCnt int
	digits := make([]byte, 0, len(validFloat))
	if dotIdx == -1 {
		digits = append(digits, validFloat[:eIdx]...)
		intCnt = len(digits)
	} else {
		digits = append(digits, validFloat[:dotIdx]...)
		intCnt = len(digits)
		digits = append(digits, validFloat[dotIdx+1:eIdx]...)
	}
	exp, err := strconv.Atoi(validFloat[eIdx+1:])
	if err != nil {
		return validFloat, errors.Trace(err)
	}
	if exp > 0 && intCnt > (math.MaxInt64-exp) {
		// (exp + incCnt) overflows MaxInt64.
		return validFloat, errors.Trace(ErrOverflow)
	}
	intCnt += exp
	if intCnt <= 0 {
		return "0", nil
	}
	if intCnt == 1 && (digits[0] == '-' || digits[0] == '+') {
		return "0", nil
	}
	var validInt string
	if intCnt <= len(digits) {
		validInt = string(digits[:intCnt])
	} else {
		extraZeroCount := intCnt - len(digits)
		if extraZeroCount > 20 {
			// Return overflow to avoid allocating too much memory.
			return validFloat, errors.Trace(ErrOverflow)
		}
		validInt = string(digits) + strings.Repeat("0", extraZeroCount)
	}
	return validInt, nil
}

// StrToFloat converts a string to a float64 at the best-effort.
func StrToFloat(sc *variable.StatementContext, str string) (float64, error) {
	str = strings.TrimSpace(str)
	validStr, err := getValidFloatPrefix(sc, str)
	f, err1 := strconv.ParseFloat(validStr, 64)
	if err1 != nil {
		return f, errors.Trace(err1)
	}
	return f, errors.Trace(err)
}

// getValidFloatPrefix gets prefix of string which can be successfully parsed as float.
func getValidFloatPrefix(sc *variable.StatementContext, s string) (valid string, err error) {
	var (
		sawDot   bool
		sawDigit bool
		validLen int
		eIdx     int
	)
	for i := 0; i < len(s); i++ {
		c := s[i]
		if c == '+' || c == '-' {
			if i != 0 && i != eIdx+1 { // "1e+1" is valid.
				break
			}
		} else if c == '.' {
			if sawDot || eIdx > 0 { // "1.1." or "1e1.1"
				break
			}
			sawDot = true
			if sawDigit { // "123." is valid.
				validLen = i + 1
			}
		} else if c == 'e' || c == 'E' {
			if !sawDigit { // "+.e"
				break
			}
			if eIdx != 0 { // "1e5e"
				break
			}
			eIdx = i
		} else if c < '0' || c > '9' {
			break
		} else {
			sawDigit = true
			validLen = i + 1
		}
	}
	valid = s[:validLen]
	if valid == "" {
		valid = "0"
	}
	if validLen == 0 || validLen != len(s) {
		err = errors.Trace(handleTruncateError(sc))
	}
	return valid, err
}

// ToString converts an interface to a string.
func ToString(value interface{}) (string, error) {
	switch v := value.(type) {
	case bool:
		if v {
			return "1", nil
		}
		return "0", nil
	case int:
		return strconv.FormatInt(int64(v), 10), nil
	case int64:
		return strconv.FormatInt(int64(v), 10), nil
	case uint64:
		return strconv.FormatUint(uint64(v), 10), nil
	case float32:
		return strconv.FormatFloat(float64(v), 'f', -1, 32), nil
	case float64:
		return strconv.FormatFloat(float64(v), 'f', -1, 64), nil
	case string:
		return v, nil
	case []byte:
		return string(v), nil
	case Time:
		return v.String(), nil
	case Duration:
		return v.String(), nil
	case *MyDecimal:
		return v.String(), nil
	case Hex:
		return v.ToString(), nil
	case Bit:
		return v.ToString(), nil
	case Enum:
		return v.String(), nil
	case Set:
		return v.String(), nil
	default:
		return "", errors.Errorf("cannot convert %v(type %T) to string", value, value)
	}
}
<|endoftext|>


<commit_before>package v3

import (
	"fmt"
	"io/ioutil"
	"path"
	"strings"
	"time"

	"github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/cloudfoundry-incubator/cf-test-helpers/cf"
	"github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/cloudfoundry-incubator/cf-test-helpers/generator"
	. "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/onsi/ginkgo"
	. "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/onsi/gomega"
	. "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/onsi/gomega/gbytes"
	. "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/onsi/gomega/gexec"
	archive_helpers "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/pivotal-golang/archiver/extractor/test_helper"
	"github.com/cloudfoundry/cf-acceptance-tests/helpers/assets"
	. "github.com/cloudfoundry/cf-acceptance-tests/helpers/v3_helpers"
)

var _ = Describe("buildpack", func() {
	var (
		appName       string
		appGuid       string
		buildpackName string
		packageGuid   string
		spaceGuid     string
		token         string
	)

	BeforeEach(func() {
		appName = generator.PrefixedRandomName("CATS-APP-")
		spaceGuid = GetSpaceGuidFromName(context.RegularUserContext().Space)
		appGuid = CreateApp(appName, spaceGuid, "{}")
		packageGuid = CreatePackage(appGuid)
		token = GetAuthToken()
		uploadUrl := fmt.Sprintf("%s%s/v3/packages/%s/upload", config.Protocol(), config.ApiEndpoint, packageGuid)
		UploadPackage(uploadUrl, assets.NewAssets().DoraZip, token)
		WaitForPackageToBeReady(packageGuid)

		buildpackName = generator.PrefixedRandomName("CATS-BP-")
		buildpackZip := createBuildpack()

		cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
			Expect(cf.Cf("create-buildpack", buildpackName, buildpackZip, "999").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		})
	})

	AfterEach(func() {
		FetchRecentLogs(appGuid, token, config)

		cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
			Expect(cf.Cf("delete-buildpack", buildpackName, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		})
		DeleteApp(appGuid)
	})

	It("Stages with a user specified admin buildpack", func() {
		StageBuildpackPackage(packageGuid, buildpackName)
		Eventually(func() *Session {
			return FetchRecentLogs(appGuid, token, config)
		}, 1*time.Minute, 10*time.Second).Should(Say("STAGED WITH CUSTOM BUILDPACK"))
	})

	It("Stages with a user specified github buildpack", func() {
		StageBuildpackPackage(packageGuid, "http://github.com/cloudfoundry/go-buildpack")

		Eventually(func() *Session {
			return FetchRecentLogs(appGuid, token, config)
		}, 3*time.Minute, 10*time.Second).Should(Say("Godep"))
	})

	It("uses buildpack cache for staging", func() {
		firstDropletGuid := StageBuildpackPackage(packageGuid, buildpackName)
		dropletPath := fmt.Sprintf("/v3/droplets/%s", firstDropletGuid)
		Eventually(func() *Session {
			result := cf.Cf("curl", dropletPath).Wait(DEFAULT_TIMEOUT)
			if strings.Contains(string(result.Out.Contents()), "FAILED") {
				Fail("staging failed")
			}
			return result
		}, CF_PUSH_TIMEOUT).Should(Say("custom buildpack contents - cache not found"))

		// Wait for buildpack cache to be uploaded to blobstore.
		time.Sleep(DEFAULT_TIMEOUT)

		secondDropletGuid := StageBuildpackPackage(packageGuid, buildpackName)
		dropletPath = fmt.Sprintf("/v3/droplets/%s", secondDropletGuid)
		Eventually(func() *Session {
			result := cf.Cf("curl", dropletPath).Wait(DEFAULT_TIMEOUT)
			if strings.Contains(string(result.Out.Contents()), "FAILED") {
				Fail("staging failed")
			}
			if strings.Contains(string(result.Out.Contents()), "cache not found") {
				Fail("cache was not found")
			}
			return result
		}, CF_PUSH_TIMEOUT).Should(Say("custom buildpack contents - here's a cache"))

		Expect(secondDropletGuid).NotTo(Equal(firstDropletGuid))
	})
})

func createBuildpack() string {
	tmpPath, err := ioutil.TempDir("", "buildpack-cats")
	Expect(err).ToNot(HaveOccurred())

	buildpackArchivePath := path.Join(tmpPath, "buildpack.zip")

	archive_helpers.CreateZipArchive(buildpackArchivePath, []archive_helpers.ArchiveFile{
		{
			Name: "bin/compile",
			Body: `#!/usr/bin/env bash

echo "STAGED WITH CUSTOM BUILDPACK"

mkdir -p $1 $2
if [ -f "$2/cached-file" ]; then
cp $2/cached-file $1/content
else
echo "cache not found" > $1/content
fi

content=$(cat $1/content)
echo "web: while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; echo "custom buildpack contents - $content"; } | nc -l \$PORT; done" > $1/Procfile

echo "here's a cache" > $2/cached-file
`,
		},
		{
			Name: "bin/detect",
			Body: `#!/bin/bash
echo no
exit 1
`,
		},
		{
			Name: "bin/release",
			Body: `#!/usr/bin/env bash

cat <<EOF
---
config_vars:
  PATH: bin:/usr/local/bin:/usr/bin:/bin
  FROM_BUILD_PACK: "yes"
default_process_types:
  web: while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; echo "custom buildpack contents - $content"; } | nc -l \$PORT; done
EOF
`,
		},
	})

	return buildpackArchivePath
}
<commit_msg>Use correct buildpack for pushing dora<commit_after>package v3

import (
	"fmt"
	"io/ioutil"
	"path"
	"strings"
	"time"

	"github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/cloudfoundry-incubator/cf-test-helpers/cf"
	"github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/cloudfoundry-incubator/cf-test-helpers/generator"
	. "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/onsi/ginkgo"
	. "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/onsi/gomega"
	. "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/onsi/gomega/gbytes"
	. "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/onsi/gomega/gexec"
	archive_helpers "github.com/cloudfoundry/cf-acceptance-tests/Godeps/_workspace/src/github.com/pivotal-golang/archiver/extractor/test_helper"
	"github.com/cloudfoundry/cf-acceptance-tests/helpers/assets"
	. "github.com/cloudfoundry/cf-acceptance-tests/helpers/v3_helpers"
)

var _ = Describe("buildpack", func() {
	var (
		appName       string
		appGuid       string
		buildpackName string
		packageGuid   string
		spaceGuid     string
		token         string
	)

	BeforeEach(func() {
		appName = generator.PrefixedRandomName("CATS-APP-")
		spaceGuid = GetSpaceGuidFromName(context.RegularUserContext().Space)
		appGuid = CreateApp(appName, spaceGuid, "{}")
		packageGuid = CreatePackage(appGuid)
		token = GetAuthToken()
		uploadUrl := fmt.Sprintf("%s%s/v3/packages/%s/upload", config.Protocol(), config.ApiEndpoint, packageGuid)
		UploadPackage(uploadUrl, assets.NewAssets().DoraZip, token)
		WaitForPackageToBeReady(packageGuid)

		buildpackName = generator.PrefixedRandomName("CATS-BP-")
		buildpackZip := createBuildpack()

		cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
			Expect(cf.Cf("create-buildpack", buildpackName, buildpackZip, "999").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		})
	})

	AfterEach(func() {
		FetchRecentLogs(appGuid, token, config)

		cf.AsUser(context.AdminUserContext(), DEFAULT_TIMEOUT, func() {
			Expect(cf.Cf("delete-buildpack", buildpackName, "-f").Wait(DEFAULT_TIMEOUT)).To(Exit(0))
		})
		DeleteApp(appGuid)
	})

	It("Stages with a user specified admin buildpack", func() {
		StageBuildpackPackage(packageGuid, buildpackName)
		Eventually(func() *Session {
			return FetchRecentLogs(appGuid, token, config)
		}, 1*time.Minute, 10*time.Second).Should(Say("STAGED WITH CUSTOM BUILDPACK"))
	})

	It("Stages with a user specified github buildpack", func() {
		StageBuildpackPackage(packageGuid, "http://github.com/cloudfoundry/ruby-buildpack")

		Eventually(func() *Session {
			return FetchRecentLogs(appGuid, token, config)
		}, 3*time.Minute, 10*time.Second).Should(Say("Compiling Ruby/Rack"))
	})

	It("uses buildpack cache for staging", func() {
		firstDropletGuid := StageBuildpackPackage(packageGuid, buildpackName)
		dropletPath := fmt.Sprintf("/v3/droplets/%s", firstDropletGuid)
		Eventually(func() *Session {
			result := cf.Cf("curl", dropletPath).Wait(DEFAULT_TIMEOUT)
			if strings.Contains(string(result.Out.Contents()), "FAILED") {
				Fail("staging failed")
			}
			return result
		}, CF_PUSH_TIMEOUT).Should(Say("custom buildpack contents - cache not found"))

		// Wait for buildpack cache to be uploaded to blobstore.
		time.Sleep(DEFAULT_TIMEOUT)

		secondDropletGuid := StageBuildpackPackage(packageGuid, buildpackName)
		dropletPath = fmt.Sprintf("/v3/droplets/%s", secondDropletGuid)
		Eventually(func() *Session {
			result := cf.Cf("curl", dropletPath).Wait(DEFAULT_TIMEOUT)
			if strings.Contains(string(result.Out.Contents()), "FAILED") {
				Fail("staging failed")
			}
			if strings.Contains(string(result.Out.Contents()), "cache not found") {
				Fail("cache was not found")
			}
			return result
		}, CF_PUSH_TIMEOUT).Should(Say("custom buildpack contents - here's a cache"))

		Expect(secondDropletGuid).NotTo(Equal(firstDropletGuid))
	})
})

func createBuildpack() string {
	tmpPath, err := ioutil.TempDir("", "buildpack-cats")
	Expect(err).ToNot(HaveOccurred())

	buildpackArchivePath := path.Join(tmpPath, "buildpack.zip")

	archive_helpers.CreateZipArchive(buildpackArchivePath, []archive_helpers.ArchiveFile{
		{
			Name: "bin/compile",
			Body: `#!/usr/bin/env bash

echo "STAGED WITH CUSTOM BUILDPACK"

mkdir -p $1 $2
if [ -f "$2/cached-file" ]; then
cp $2/cached-file $1/content
else
echo "cache not found" > $1/content
fi

content=$(cat $1/content)
echo "web: while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; echo "custom buildpack contents - $content"; } | nc -l \$PORT; done" > $1/Procfile

echo "here's a cache" > $2/cached-file
`,
		},
		{
			Name: "bin/detect",
			Body: `#!/bin/bash
echo no
exit 1
`,
		},
		{
			Name: "bin/release",
			Body: `#!/usr/bin/env bash

cat <<EOF
---
config_vars:
  PATH: bin:/usr/local/bin:/usr/bin:/bin
  FROM_BUILD_PACK: "yes"
default_process_types:
  web: while true; do { echo -e 'HTTP/1.1 200 OK\r\n'; echo "custom buildpack contents - $content"; } | nc -l \$PORT; done
EOF
`,
		},
	})

	return buildpackArchivePath
}
<|endoftext|>


<commit_before>package simlog

import (
	"fmt"
	"runtime"
)

type Logger interface {
	FuncIn()
	FuncOut()
	Debug(format string, a ...interface{})
	Error(format string, a ...interface{})
}

type logger struct {
}

var simlog = &logger{}

func FuncIn() {
	simlog.printLog("[DEBUG]", "%s", "IN")
}

func FuncOut() {
	simlog.printLog("[DEBUG]", "%s", "OUT")
}

func Debugf(format string, a ...interface{}) {
	simlog.printLog("[DEBUG]", format, a...)
}

func Errorf(format string, a ...interface{}) {
	simlog.printLog("[ERROR]", format, a...)
}

func Debug(i interface{}) {
	switch v := i.(type) {
	case error:
		simlog.printLog("[DEBUG]", v.Error())
	case fmt.Stringer:
		simlog.printLog("[DEBUG]", v.String())
	case string:
		simlog.printLog("[DEBUG]", v)
	default:
		panic("can't print input!")
	}
}

func Error(i interface{}) {
	switch v := i.(type) {
	case error:
		simlog.printLog("[ERROR]", v.Error())
	case fmt.Stringer:
		simlog.printLog("[ERROR]", v.String())
	default:
		panic("can't print input!")
	}
}

func (l *logger) printLog(tag string, format string, a ...interface{}) {
	pc := make([]uintptr, 10)
	runtime.Callers(3, pc)
	f := runtime.FuncForPC(pc[0])
	_, line := f.FileLine(pc[0])
	var buf string
	buf += fmt.Sprintf("[%s][%s:%d] ", tag, f.Name(), line)
	if len(a) == 0 {
		buf += format
	} else {
		buf += fmt.Sprintf(format, a)
	}
	fmt.Println(buf)
}
<commit_msg>comments on exposed functions in simlog package<commit_after>package simlog

import (
	"fmt"
	"runtime"
)

// Logger represents log interface for simra
type Logger interface {
	printLog(tag string, format string, a ...interface{})
}

type logger struct {
}

var simlog Logger = &logger{}

// FuncIn shows log for function in
func FuncIn() {
	simlog.printLog("[DEBUG]", "%s", "IN")
}

// FuncOut shows log for function out
func FuncOut() {
	simlog.printLog("[DEBUG]", "%s", "OUT")
}

// Debugf shows debug log with specified format and arguments
func Debugf(format string, a ...interface{}) {
	simlog.printLog("[DEBUG]", format, a...)
}

// Errorf shows error log with specified format and arguments
func Errorf(format string, a ...interface{}) {
	simlog.printLog("[ERROR]", format, a...)
}

// Debug shows debug log with specified object
func Debug(i interface{}) {
	switch v := i.(type) {
	case error:
		simlog.printLog("[DEBUG]", v.Error())
	case fmt.Stringer:
		simlog.printLog("[DEBUG]", v.String())
	case string:
		simlog.printLog("[DEBUG]", v)
	default:
		panic("can't print input!")
	}
}

// Error shows error log with specified object
func Error(i interface{}) {
	switch v := i.(type) {
	case error:
		simlog.printLog("[ERROR]", v.Error())
	case fmt.Stringer:
		simlog.printLog("[ERROR]", v.String())
	default:
		panic("can't print input!")
	}
}

func (l *logger) printLog(tag string, format string, a ...interface{}) {
	pc := make([]uintptr, 10)
	runtime.Callers(3, pc)
	f := runtime.FuncForPC(pc[0])
	_, line := f.FileLine(pc[0])
	var buf string
	buf += fmt.Sprintf("[%s][%s:%d] ", tag, f.Name(), line)
	if len(a) == 0 {
		buf += format
	} else {
		buf += fmt.Sprintf(format, a)
	}
	fmt.Println(buf)
}
<|endoftext|>


<commit_before>// Package geoip2 provides a wrapper around the maxminddb package for
// easy use with the MaxMind GeoIP2 and GeoLite2 databases. The records for
// the IP address is returned from this package as well-formed structures
// that match the internal layout of data from MaxMind.
package geoip2

import (
	"net"

	"github.com/oschwald/maxminddb-golang"
)

// The City structure corresponds to the data in the GeoIP2/GeoLite2 City
// databases.
type City struct {
	City struct {
		GeoNameID uint              `maxminddb:"geoname_id"`
		Names     map[string]string `maxminddb:"names"`
	} `maxminddb:"city"`
	Continent struct {
		Code      string            `maxminddb:"code"`
		GeoNameID uint              `maxminddb:"geoname_id"`
		Names     map[string]string `maxminddb:"names"`
	} `maxminddb:"continent"`
	Country struct {
		GeoNameID uint              `maxminddb:"geoname_id"`
		IsoCode   string            `maxminddb:"iso_code"`
		Names     map[string]string `maxminddb:"names"`
	} `maxminddb:"country"`
	Location struct {
		Latitude  float64 `maxminddb:"latitude"`
		Longitude float64 `maxminddb:"longitude"`
		MetroCode uint    `maxminddb:"metro_code"`
		TimeZone  string  `maxminddb:"time_zone"`
	} `maxminddb:"location"`
	Postal struct {
		Code string `maxminddb:"code"`
	} `maxminddb:"postal"`
	RegisteredCountry struct {
		GeoNameID uint              `maxminddb:"geoname_id"`
		IsoCode   string            `maxminddb:"iso_code"`
		Names     map[string]string `maxminddb:"names"`
	} `maxminddb:"registered_country"`
	RepresentedCountry struct {
		GeoNameID uint              `maxminddb:"geoname_id"`
		IsoCode   string            `maxminddb:"iso_code"`
		Names     map[string]string `maxminddb:"names"`
		Type      string            `maxminddb:"type"`
	} `maxminddb:"represented_country"`
	Subdivisions []struct {
		GeoNameID uint              `maxminddb:"geoname_id"`
		IsoCode   string            `maxminddb:"iso_code"`
		Names     map[string]string `maxminddb:"names"`
	} `maxminddb:"subdivisions"`
	Traits struct {
		IsAnonymousProxy    bool `maxminddb:"is_anonymous_proxy"`
		IsSatelliteProvider bool `maxminddb:"is_satellite_provider"`
	} `maxminddb:"traits"`
}

// The Country structure corresponds to the data in the GeoIP2/GeoLite2
// Country databases.
type Country struct {
	Continent struct {
		Code      string            `maxminddb:"code"`
		GeoNameID uint              `maxminddb:"geoname_id"`
		Names     map[string]string `maxminddb:"names"`
	} `maxminddb:"continent"`
	Country struct {
		GeoNameID uint              `maxminddb:"geoname_id"`
		IsoCode   string            `maxminddb:"iso_code"`
		Names     map[string]string `maxminddb:"names"`
	} `maxminddb:"country"`
	RegisteredCountry struct {
		GeoNameID uint              `maxminddb:"geoname_id"`
		IsoCode   string            `maxminddb:"iso_code"`
		Names     map[string]string `maxminddb:"names"`
	} `maxminddb:"registered_country"`
	RepresentedCountry struct {
		GeoNameID uint              `maxminddb:"geoname_id"`
		IsoCode   string            `maxminddb:"iso_code"`
		Names     map[string]string `maxminddb:"names"`
		Type      string            `maxminddb:"type"`
	} `maxminddb:"represented_country"`
	Traits struct {
		IsAnonymousProxy    bool `maxminddb:"is_anonymous_proxy"`
		IsSatelliteProvider bool `maxminddb:"is_satellite_provider"`
	} `maxminddb:"traits"`
}

// The ConnectionType structure corresponds to the data in the GeoIP2
// Connection-Type database.
type ConnectionType struct {
	ConnectionType string `maxminddb:"connection_type"`
}

// The Domain structure corresponds to the data in the GeoIP2 Domain database.
type Domain struct {
	Domain string `maxminddb:"domain"`
}

// The ISP structure corresponds to the data in the GeoIP2 ISP database.
type ISP struct {
	AutonomousSystemNumber       uint   `maxminddb:"autonomous_system_number"`
	AutonomousSystemOrganization string `maxminddb:"autonomous_system_organization"`
	ISP                          string `maxminddb:"isp"`
	Organization                 string `maxminddb:"organization"`
}

// Reader holds the maxminddb.Reader structure. It should be created
// using the Open function.
type Reader struct {
	mmdbReader *maxminddb.Reader
	metadata   *maxminddb.Metadata
}

// Open takes a string path to a file and returns a Reader structure or an
// error. The database file is opened using a memory map. Use the Close method
// on the Reader object to return the resources to the system.
func Open(file string) (*Reader, error) {
	reader, err := maxminddb.Open(file)
	if err == nil {
		return &Reader{mmdbReader: reader, metadata: &reader.Metadata}, err
	} else {
		return &Reader{mmdbReader: reader}, err
	}
}

// FromBytes takes a byte slice corresponding to a GeoIP2/GeoLite2 database
// file and returns a Reader structure or an error.
func FromBytes(bytes []byte) (*Reader, error) {
	reader, err := maxminddb.FromBytes(bytes)
	if err == nil {
		return &Reader{mmdbReader: reader, metadata: &reader.Metadata}, err
	} else {
		return &Reader{mmdbReader: reader}, err
	}
}

// City takes an IP address as a net.IP struct and returns a City struct
// and/or an error. Although this can be used with other databases, this
// method generally should be used with the GeoIP2 or GeoLite2 City databases.
func (r *Reader) City(ipAddress net.IP) (*City, error) {
	var city City
	err := r.mmdbReader.Lookup(ipAddress, &city)
	return &city, err
}

// Country takes an IP address as a net.IP struct and returns a Country struct
// and/or an error. Although this can be used with other databases, this
// method generally should be used with the GeoIP2 or GeoLite2 Country
// databases.
func (r *Reader) Country(ipAddress net.IP) (*Country, error) {
	var country Country
	err := r.mmdbReader.Lookup(ipAddress, &country)
	return &country, err
}

// ConnectionType takes an IP address as a net.IP struct and returns a
// ConnectionType struct and/or an error
func (r *Reader) ConnectionType(ipAddress net.IP) (*ConnectionType, error) {
	var val ConnectionType
	err := r.mmdbReader.Lookup(ipAddress, &val)
	return &val, err
}

// Domain takes an IP address as a net.IP struct and returns a
// Domain struct and/or an error
func (r *Reader) Domain(ipAddress net.IP) (*Domain, error) {
	var val Domain
	err := r.mmdbReader.Lookup(ipAddress, &val)
	return &val, err
}

// ISP takes an IP address as a net.IP struct and returns a ISP struct and/or
// an error
func (r *Reader) ISP(ipAddress net.IP) (*ISP, error) {
	var val ISP
	err := r.mmdbReader.Lookup(ipAddress, &val)
	return &val, err
}

// Metadata takes no arguments and returns a struct containing metadata about
// the Maxmind database in use by the Reader.
func (r *Reader) Metadata() *maxminddb.Metadata {
	return r.metadata
}

// Close unmaps the database file from virtual memory and returns the
// resources to the system.
func (r *Reader) Close() {
	r.mmdbReader.Close()
}
<commit_msg>removing extra mmdb Metadata pointer<commit_after>// Package geoip2 provides a wrapper around the maxminddb package for
// easy use with the MaxMind GeoIP2 and GeoLite2 databases. The records for
// the IP address is returned from this package as well-formed structures
// that match the internal layout of data from MaxMind.
package geoip2

import (
	"net"

	"github.com/oschwald/maxminddb-golang"
)

// The City structure corresponds to the data in the GeoIP2/GeoLite2 City
// databases.
type City struct {
	City struct {
		GeoNameID uint              `maxminddb:"geoname_id"`
		Names     map[string]string `maxminddb:"names"`
	} `maxminddb:"city"`
	Continent struct {
		Code      string            `maxminddb:"code"`
		GeoNameID uint              `maxminddb:"geoname_id"`
		Names     map[string]string `maxminddb:"names"`
	} `maxminddb:"continent"`
	Country struct {
		GeoNameID uint              `maxminddb:"geoname_id"`
		IsoCode   string            `maxminddb:"iso_code"`
		Names     map[string]string `maxminddb:"names"`
	} `maxminddb:"country"`
	Location struct {
		Latitude  float64 `maxminddb:"latitude"`
		Longitude float64 `maxminddb:"longitude"`
		MetroCode uint    `maxminddb:"metro_code"`
		TimeZone  string  `maxminddb:"time_zone"`
	} `maxminddb:"location"`
	Postal struct {
		Code string `maxminddb:"code"`
	} `maxminddb:"postal"`
	RegisteredCountry struct {
		GeoNameID uint              `maxminddb:"geoname_id"`
		IsoCode   string            `maxminddb:"iso_code"`
		Names     map[string]string `maxminddb:"names"`
	} `maxminddb:"registered_country"`
	RepresentedCountry struct {
		GeoNameID uint              `maxminddb:"geoname_id"`
		IsoCode   string            `maxminddb:"iso_code"`
		Names     map[string]string `maxminddb:"names"`
		Type      string            `maxminddb:"type"`
	} `maxminddb:"represented_country"`
	Subdivisions []struct {
		GeoNameID uint              `maxminddb:"geoname_id"`
		IsoCode   string            `maxminddb:"iso_code"`
		Names     map[string]string `maxminddb:"names"`
	} `maxminddb:"subdivisions"`
	Traits struct {
		IsAnonymousProxy    bool `maxminddb:"is_anonymous_proxy"`
		IsSatelliteProvider bool `maxminddb:"is_satellite_provider"`
	} `maxminddb:"traits"`
}

// The Country structure corresponds to the data in the GeoIP2/GeoLite2
// Country databases.
type Country struct {
	Continent struct {
		Code      string            `maxminddb:"code"`
		GeoNameID uint              `maxminddb:"geoname_id"`
		Names     map[string]string `maxminddb:"names"`
	} `maxminddb:"continent"`
	Country struct {
		GeoNameID uint              `maxminddb:"geoname_id"`
		IsoCode   string            `maxminddb:"iso_code"`
		Names     map[string]string `maxminddb:"names"`
	} `maxminddb:"country"`
	RegisteredCountry struct {
		GeoNameID uint              `maxminddb:"geoname_id"`
		IsoCode   string            `maxminddb:"iso_code"`
		Names     map[string]string `maxminddb:"names"`
	} `maxminddb:"registered_country"`
	RepresentedCountry struct {
		GeoNameID uint              `maxminddb:"geoname_id"`
		IsoCode   string            `maxminddb:"iso_code"`
		Names     map[string]string `maxminddb:"names"`
		Type      string            `maxminddb:"type"`
	} `maxminddb:"represented_country"`
	Traits struct {
		IsAnonymousProxy    bool `maxminddb:"is_anonymous_proxy"`
		IsSatelliteProvider bool `maxminddb:"is_satellite_provider"`
	} `maxminddb:"traits"`
}

// The ConnectionType structure corresponds to the data in the GeoIP2
// Connection-Type database.
type ConnectionType struct {
	ConnectionType string `maxminddb:"connection_type"`
}

// The Domain structure corresponds to the data in the GeoIP2 Domain database.
type Domain struct {
	Domain string `maxminddb:"domain"`
}

// The ISP structure corresponds to the data in the GeoIP2 ISP database.
type ISP struct {
	AutonomousSystemNumber       uint   `maxminddb:"autonomous_system_number"`
	AutonomousSystemOrganization string `maxminddb:"autonomous_system_organization"`
	ISP                          string `maxminddb:"isp"`
	Organization                 string `maxminddb:"organization"`
}

// Reader holds the maxminddb.Reader structure. It should be created
// using the Open function.
type Reader struct {
	mmdbReader *maxminddb.Reader
}

// Open takes a string path to a file and returns a Reader structure or an
// error. The database file is opened using a memory map. Use the Close method
// on the Reader object to return the resources to the system.
func Open(file string) (*Reader, error) {
	reader, err := maxminddb.Open(file)
	return &Reader{mmdbReader: reader}, err
}

// FromBytes takes a byte slice corresponding to a GeoIP2/GeoLite2 database
// file and returns a Reader structure or an error.
func FromBytes(bytes []byte) (*Reader, error) {
	reader, err := maxminddb.FromBytes(bytes)
	return &Reader{mmdbReader: reader}, err
}

// City takes an IP address as a net.IP struct and returns a City struct
// and/or an error. Although this can be used with other databases, this
// method generally should be used with the GeoIP2 or GeoLite2 City databases.
func (r *Reader) City(ipAddress net.IP) (*City, error) {
	var city City
	err := r.mmdbReader.Lookup(ipAddress, &city)
	return &city, err
}

// Country takes an IP address as a net.IP struct and returns a Country struct
// and/or an error. Although this can be used with other databases, this
// method generally should be used with the GeoIP2 or GeoLite2 Country
// databases.
func (r *Reader) Country(ipAddress net.IP) (*Country, error) {
	var country Country
	err := r.mmdbReader.Lookup(ipAddress, &country)
	return &country, err
}

// ConnectionType takes an IP address as a net.IP struct and returns a
// ConnectionType struct and/or an error
func (r *Reader) ConnectionType(ipAddress net.IP) (*ConnectionType, error) {
	var val ConnectionType
	err := r.mmdbReader.Lookup(ipAddress, &val)
	return &val, err
}

// Domain takes an IP address as a net.IP struct and returns a
// Domain struct and/or an error
func (r *Reader) Domain(ipAddress net.IP) (*Domain, error) {
	var val Domain
	err := r.mmdbReader.Lookup(ipAddress, &val)
	return &val, err
}

// ISP takes an IP address as a net.IP struct and returns a ISP struct and/or
// an error
func (r *Reader) ISP(ipAddress net.IP) (*ISP, error) {
	var val ISP
	err := r.mmdbReader.Lookup(ipAddress, &val)
	return &val, err
}

// Metadata takes no arguments and returns a struct containing metadata about
// the Maxmind database in use by the Reader.
func (r *Reader) Metadata() *maxminddb.Metadata {
	return &r.mmdbReader.Metadata
}

// Close unmaps the database file from virtual memory and returns the
// resources to the system.
func (r *Reader) Close() {
	r.mmdbReader.Close()
}
<|endoftext|>