<commit_before>/* Go (cgo) interface to libgeoip */
package geoip

/*
#cgo CFLAGS: -I/opt/local/include -I/usr/local/include -I/usr/include
#cgo LDFLAGS: -lGeoIP -L/opt/local/lib -L/usr/local/lib -L/usr/lib
#include <stdio.h>
#include <errno.h>
#include <GeoIP.h>
#include <GeoIPCity.h>

//typedef GeoIP* GeoIP_pnt
*/
import "C"

import (
	"fmt"
	"log"
	"os"
	"runtime"
	"sync"
	"unsafe"
)

type GeoIP struct {
	db *C.GeoIP
	mu sync.Mutex
}

func (gi *GeoIP) free() {
	if gi == nil {
		return
	}
	if gi.db == nil {
		gi = nil
		return
	}
	C.GeoIP_delete(gi.db)
	gi = nil
	return
}

// Opens a GeoIP database by filename, all formats supported by libgeoip are
// supported though there are only functions to access some of the databases in this API.
// The database is opened in MEMORY_CACHE mode, if you need to optimize for memory
// instead of performance you should change this.
// If you don't pass a filename, it will try opening the database from
// a list of common paths.
func Open(files ...string) (*GeoIP, error) {
	if len(files) == 0 {
		files = []string{
			"/usr/share/GeoIP/GeoIP.dat",       // Linux default
			"/usr/share/local/GeoIP/GeoIP.dat", // source install?
			"/usr/local/share/GeoIP/GeoIP.dat", // FreeBSD
			"/opt/local/share/GeoIP/GeoIP.dat", // MacPorts
			"/usr/share/GeoIP/GeoIP.dat",       // ArchLinux
		}
	}

	g := &GeoIP{}
	runtime.SetFinalizer(g, (*GeoIP).free)

	var err error

	for _, file := range files {

		// libgeoip prints errors if it can't open the file, so check first
		if _, err := os.Stat(file); err != nil {
			if os.IsExist(err) {
				log.Println(err)
			}
			continue
		}

		cbase := C.CString(file)
		defer C.free(unsafe.Pointer(cbase))

		g.db, err = C.GeoIP_open(cbase, C.GEOIP_MEMORY_CACHE)
		if g.db != nil && err != nil {
			break
		}
	}
	if err != nil {
		return nil, fmt.Errorf("Error opening GeoIP database (%s): %s", files, err)
	}

	if g.db == nil {
		return nil, fmt.Errorf("Didn't open GeoIP database (%s)", files)
	}

	C.GeoIP_set_charset(g.db, C.GEOIP_CHARSET_UTF8)
	return g, nil
}

// SetCustomDirectory sets the default location for the GeoIP .dat files used when
// calling OpenType()
func SetCustomDirectory(dir string) {
	cdir := C.CString(dir)
	defer C.free(unsafe.Pointer(cdir))
	C.GeoIP_setup_custom_directory(cdir)
}

// OpenType opens a specified GeoIP database type in the default location. Constants
// are defined for each database type (for example GEOIP_COUNTRY_EDITION).
func OpenType(dbType int) (*GeoIP, error) {
	g := &GeoIP{}
	runtime.SetFinalizer(g, (*GeoIP).free)

	var err error

	g.db, err = C.GeoIP_open_type(C.int(dbType), C.GEOIP_MEMORY_CACHE)
	if err != nil {
		return nil, fmt.Errorf("Error opening GeoIP database (%d): %s", dbType, err)
	}

	if g.db == nil {
		return nil, fmt.Errorf("Didn't open GeoIP database (%d)", dbType)
	}

	C.GeoIP_set_charset(g.db, C.GEOIP_CHARSET_UTF8)

	return g, nil
}

// Takes an IPv4 address string and returns the organization name for that IP.
// Requires the GeoIP organization database.
func (gi *GeoIP) GetOrg(ip string) string {
	name, _ := gi.GetName(ip)
	return name
}

// Works on the ASN, Netspeed, Organization and probably other
// databases, takes and IP string and returns a "name" and the
// netmask.
func (gi *GeoIP) GetName(ip string) (name string, netmask int) {
	if gi.db == nil {
		return
	}

	gi.mu.Lock()
	defer gi.mu.Unlock()

	cip := C.CString(ip)
	defer C.free(unsafe.Pointer(cip))
	cname := C.GeoIP_name_by_addr(gi.db, cip)

	if cname != nil {
		name = C.GoString(cname)
		defer C.free(unsafe.Pointer(cname))
		netmask = int(C.GeoIP_last_netmask(gi.db))
		return
	}
	return
}

type GeoIPRecord struct {
	CountryCode  string
	CountryCode3 string
	CountryName  string
	Region       string
	City         string
	PostalCode   string
	Latitude     float32
	Longitude    float32
	// DMACode       int
	AreaCode      int
	CharSet       int
	ContinentCode string
}

// Returns the "City Record" for an IP address. Requires the GeoCity(Lite)
// database - http://www.maxmind.com/en/city
func (gi *GeoIP) GetRecord(ip string) *GeoIPRecord {
	if gi.db == nil {
		return nil
	}

	cip := C.CString(ip)
	defer C.free(unsafe.Pointer(cip))
	record := C.GeoIP_record_by_addr(gi.db, cip)
	if record == nil {
		return nil
	}
	// defer C.free(unsafe.Pointer(record))
	defer C.GeoIPRecord_delete(record)
	rec := new(GeoIPRecord)
	rec.CountryCode = C.GoString(record.country_code)
	rec.CountryCode3 = C.GoString(record.country_code3)
	rec.CountryName = C.GoString(record.country_name)
	rec.Region = C.GoString(record.region)
	rec.City = C.GoString(record.city)
	rec.PostalCode = C.GoString(record.postal_code)
	rec.Latitude = float32(record.latitude)
	rec.Longitude = float32(record.longitude)
	rec.AreaCode = int(record.area_code)
	rec.CharSet = int(record.charset)
	rec.ContinentCode = C.GoString(record.continent_code)

	return rec
}

// Returns the country code and region code for an IP address. Requires
// the GeoIP Region database.
func (gi *GeoIP) GetRegion(ip string) (string, string) {
	if gi.db == nil {
		return "", ""
	}

	cip := C.CString(ip)
	defer C.free(unsafe.Pointer(cip))
	region := C.GeoIP_region_by_addr(gi.db, cip)
	if region == nil {
		return "", ""
	}

	countryCode := C.GoString(&region.country_code[0])
	regionCode := C.GoString(&region.region[0])
	defer C.free(unsafe.Pointer(region))

	return countryCode, regionCode
}

// Returns the region name given a country code and region code
func GetRegionName(countryCode, regionCode string) string {

	cc := C.CString(countryCode)
	defer C.free(unsafe.Pointer(cc))

	rc := C.CString(regionCode)
	defer C.free(unsafe.Pointer(rc))

	region := C.GeoIP_region_name_by_code(cc, rc)
	if region == nil {
		return ""
	}

	// it's a static string constant, don't free this
	regionName := C.GoString(region)

	return regionName
}

// Same as GetName() but for IPv6 addresses.
func (gi *GeoIP) GetNameV6(ip string) (name string, netmask int) {
	if gi.db == nil {
		return
	}

	gi.mu.Lock()
	defer gi.mu.Unlock()

	cip := C.CString(ip)
	defer C.free(unsafe.Pointer(cip))
	cname := C.GeoIP_name_by_addr_v6(gi.db, cip)

	if cname != nil {
		name = C.GoString(cname)
		defer C.free(unsafe.Pointer(cname))
		netmask = int(C.GeoIP_last_netmask(gi.db))
		return
	}
	return
}

// Takes an IPv4 address string and returns the country code for that IP
// and the netmask for that IP range.
func (gi *GeoIP) GetCountry(ip string) (cc string, netmask int) {
	if gi.db == nil {
		return
	}

	gi.mu.Lock() // Lock to make sure we get the right result from GeoIP_last_netmask
	defer gi.mu.Unlock()

	cip := C.CString(ip)
	defer C.free(unsafe.Pointer(cip))
	ccountry := C.GeoIP_country_code_by_addr(gi.db, cip)

	if ccountry != nil {
		cc = C.GoString(ccountry)
		netmask = int(C.GeoIP_last_netmask(gi.db))
		return
	}
	return
}

// GetCountry_v6 works the same as GetCountry except for IPv6 addresses, be sure to
// load a database with IPv6 data to get any results.
func (gi *GeoIP) GetCountry_v6(ip string) (cc string, netmask int) {
	if gi.db == nil {
		return
	}

	gi.mu.Lock()
	defer gi.mu.Unlock()

	cip := C.CString(ip)
	defer C.free(unsafe.Pointer(cip))
	ccountry := C.GeoIP_country_code_by_addr_v6(gi.db, cip)
	if ccountry != nil {
		cc = C.GoString(ccountry)
		netmask = int(C.GeoIP_last_netmask(gi.db))
		return
	}
	return
}
<commit_msg>Fix SetCustomDirectory<commit_after>/* Go (cgo) interface to libgeoip */
package geoip

/*
#cgo CFLAGS: -I/opt/local/include -I/usr/local/include -I/usr/include
#cgo LDFLAGS: -lGeoIP -L/opt/local/lib -L/usr/local/lib -L/usr/lib
#include <stdio.h>
#include <errno.h>
#include <GeoIP.h>
#include <GeoIPCity.h>

//typedef GeoIP* GeoIP_pnt
*/
import "C"

import (
	"fmt"
	"log"
	"os"
	"runtime"
	"sync"
	"unsafe"
)

type GeoIP struct {
	db *C.GeoIP
	mu sync.Mutex
}

func (gi *GeoIP) free() {
	if gi == nil {
		return
	}
	if gi.db == nil {
		gi = nil
		return
	}
	C.GeoIP_delete(gi.db)
	gi = nil
	return
}

// Opens a GeoIP database by filename, all formats supported by libgeoip are
// supported though there are only functions to access some of the databases in this API.
// The database is opened in MEMORY_CACHE mode, if you need to optimize for memory
// instead of performance you should change this.
// If you don't pass a filename, it will try opening the database from
// a list of common paths.
func Open(files ...string) (*GeoIP, error) {
	if len(files) == 0 {
		files = []string{
			"/usr/share/GeoIP/GeoIP.dat",       // Linux default
			"/usr/share/local/GeoIP/GeoIP.dat", // source install?
			"/usr/local/share/GeoIP/GeoIP.dat", // FreeBSD
			"/opt/local/share/GeoIP/GeoIP.dat", // MacPorts
			"/usr/share/GeoIP/GeoIP.dat",       // ArchLinux
		}
	}

	g := &GeoIP{}
	runtime.SetFinalizer(g, (*GeoIP).free)

	var err error

	for _, file := range files {

		// libgeoip prints errors if it can't open the file, so check first
		if _, err := os.Stat(file); err != nil {
			if os.IsExist(err) {
				log.Println(err)
			}
			continue
		}

		cbase := C.CString(file)
		defer C.free(unsafe.Pointer(cbase))

		g.db, err = C.GeoIP_open(cbase, C.GEOIP_MEMORY_CACHE)
		if g.db != nil && err != nil {
			break
		}
	}
	if err != nil {
		return nil, fmt.Errorf("Error opening GeoIP database (%s): %s", files, err)
	}

	if g.db == nil {
		return nil, fmt.Errorf("Didn't open GeoIP database (%s)", files)
	}

	C.GeoIP_set_charset(g.db, C.GEOIP_CHARSET_UTF8)
	return g, nil
}

// SetCustomDirectory sets the default location for the GeoIP .dat files used when
// calling OpenType()
func SetCustomDirectory(dir string) {
	cdir := C.CString(dir)
	// GeoIP doesn't copy the string, so don't free it when we're done here.
	// defer C.free(unsafe.Pointer(cdir))
	C.GeoIP_setup_custom_directory(cdir)
}

// OpenType opens a specified GeoIP database type in the default location. Constants
// are defined for each database type (for example GEOIP_COUNTRY_EDITION).
func OpenType(dbType int) (*GeoIP, error) {
	g := &GeoIP{}
	runtime.SetFinalizer(g, (*GeoIP).free)

	var err error

	g.db, err = C.GeoIP_open_type(C.int(dbType), C.GEOIP_MEMORY_CACHE)
	if err != nil {
		return nil, fmt.Errorf("Error opening GeoIP database (%d): %s", dbType, err)
	}

	if g.db == nil {
		return nil, fmt.Errorf("Didn't open GeoIP database (%d)", dbType)
	}

	C.GeoIP_set_charset(g.db, C.GEOIP_CHARSET_UTF8)

	return g, nil
}

// Takes an IPv4 address string and returns the organization name for that IP.
// Requires the GeoIP organization database.
func (gi *GeoIP) GetOrg(ip string) string {
	name, _ := gi.GetName(ip)
	return name
}

// Works on the ASN, Netspeed, Organization and probably other
// databases, takes and IP string and returns a "name" and the
// netmask.
func (gi *GeoIP) GetName(ip string) (name string, netmask int) {
	if gi.db == nil {
		return
	}

	gi.mu.Lock()
	defer gi.mu.Unlock()

	cip := C.CString(ip)
	defer C.free(unsafe.Pointer(cip))
	cname := C.GeoIP_name_by_addr(gi.db, cip)

	if cname != nil {
		name = C.GoString(cname)
		defer C.free(unsafe.Pointer(cname))
		netmask = int(C.GeoIP_last_netmask(gi.db))
		return
	}
	return
}

type GeoIPRecord struct {
	CountryCode  string
	CountryCode3 string
	CountryName  string
	Region       string
	City         string
	PostalCode   string
	Latitude     float32
	Longitude    float32
	// DMACode       int
	AreaCode      int
	CharSet       int
	ContinentCode string
}

// Returns the "City Record" for an IP address. Requires the GeoCity(Lite)
// database - http://www.maxmind.com/en/city
func (gi *GeoIP) GetRecord(ip string) *GeoIPRecord {
	if gi.db == nil {
		return nil
	}

	cip := C.CString(ip)
	defer C.free(unsafe.Pointer(cip))
	record := C.GeoIP_record_by_addr(gi.db, cip)
	if record == nil {
		return nil
	}
	// defer C.free(unsafe.Pointer(record))
	defer C.GeoIPRecord_delete(record)
	rec := new(GeoIPRecord)
	rec.CountryCode = C.GoString(record.country_code)
	rec.CountryCode3 = C.GoString(record.country_code3)
	rec.CountryName = C.GoString(record.country_name)
	rec.Region = C.GoString(record.region)
	rec.City = C.GoString(record.city)
	rec.PostalCode = C.GoString(record.postal_code)
	rec.Latitude = float32(record.latitude)
	rec.Longitude = float32(record.longitude)
	rec.AreaCode = int(record.area_code)
	rec.CharSet = int(record.charset)
	rec.ContinentCode = C.GoString(record.continent_code)

	return rec
}

// Returns the country code and region code for an IP address. Requires
// the GeoIP Region database.
func (gi *GeoIP) GetRegion(ip string) (string, string) {
	if gi.db == nil {
		return "", ""
	}

	cip := C.CString(ip)
	defer C.free(unsafe.Pointer(cip))
	region := C.GeoIP_region_by_addr(gi.db, cip)
	if region == nil {
		return "", ""
	}

	countryCode := C.GoString(&region.country_code[0])
	regionCode := C.GoString(&region.region[0])
	defer C.free(unsafe.Pointer(region))

	return countryCode, regionCode
}

// Returns the region name given a country code and region code
func GetRegionName(countryCode, regionCode string) string {

	cc := C.CString(countryCode)
	defer C.free(unsafe.Pointer(cc))

	rc := C.CString(regionCode)
	defer C.free(unsafe.Pointer(rc))

	region := C.GeoIP_region_name_by_code(cc, rc)
	if region == nil {
		return ""
	}

	// it's a static string constant, don't free this
	regionName := C.GoString(region)

	return regionName
}

// Same as GetName() but for IPv6 addresses.
func (gi *GeoIP) GetNameV6(ip string) (name string, netmask int) {
	if gi.db == nil {
		return
	}

	gi.mu.Lock()
	defer gi.mu.Unlock()

	cip := C.CString(ip)
	defer C.free(unsafe.Pointer(cip))
	cname := C.GeoIP_name_by_addr_v6(gi.db, cip)

	if cname != nil {
		name = C.GoString(cname)
		defer C.free(unsafe.Pointer(cname))
		netmask = int(C.GeoIP_last_netmask(gi.db))
		return
	}
	return
}

// Takes an IPv4 address string and returns the country code for that IP
// and the netmask for that IP range.
func (gi *GeoIP) GetCountry(ip string) (cc string, netmask int) {
	if gi.db == nil {
		return
	}

	gi.mu.Lock() // Lock to make sure we get the right result from GeoIP_last_netmask
	defer gi.mu.Unlock()

	cip := C.CString(ip)
	defer C.free(unsafe.Pointer(cip))
	ccountry := C.GeoIP_country_code_by_addr(gi.db, cip)

	if ccountry != nil {
		cc = C.GoString(ccountry)
		netmask = int(C.GeoIP_last_netmask(gi.db))
		return
	}
	return
}

// GetCountry_v6 works the same as GetCountry except for IPv6 addresses, be sure to
// load a database with IPv6 data to get any results.
func (gi *GeoIP) GetCountry_v6(ip string) (cc string, netmask int) {
	if gi.db == nil {
		return
	}

	gi.mu.Lock()
	defer gi.mu.Unlock()

	cip := C.CString(ip)
	defer C.free(unsafe.Pointer(cip))
	ccountry := C.GeoIP_country_code_by_addr_v6(gi.db, cip)
	if ccountry != nil {
		cc = C.GoString(ccountry)
		netmask = int(C.GeoIP_last_netmask(gi.db))
		return
	}
	return
}
<|endoftext|>


<commit_before>package godbg

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"regexp"
	"runtime"
	"strings"
)

// http://stackoverflow.com/a/23554672/6309 https://vividcortex.com/blog/2013/12/03/go-idiom-package-and-object/
// you design a type with methods as usual, and then you also place matching functions at the package level itself.
// These functions simply delegate to a default instance of the type that’s a private package-level variable, created in an init() function.

// Pdbg allows to print debug message with indent and function name added
type Pdbg struct {
	bout     *bytes.Buffer
	berr     *bytes.Buffer
	sout     *bufio.Writer
	serr     *bufio.Writer
	breaks   []string
	excludes []string
	skips    []string
}

// Out returns a writer for normal messages.
// By default, os.StdOut
func Out() io.Writer {
	return pdbg.Out()
}

// Out returns a writer for normal messages for a given pdbg instance.
// By default, os.StdOut
func (pdbg *Pdbg) Out() io.Writer {
	if pdbg.sout == nil {
		return os.Stdout
	}
	return pdbg.sout
}

// Err returns a writer for error messages.
// By default, os.StdErr
func Err() io.Writer {
	return pdbg.Err()
}

// Err returns a writer for error messages for a given pdbg instance.
// By default, os.StdErr
func (pdbg *Pdbg) Err() io.Writer {
	if pdbg.serr == nil {
		return os.Stderr
	}
	return pdbg.serr
}

// global pdbg used for printing
var pdbg = NewPdbg()

// Option set an option for a Pdbg
// http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis
type Option func(*Pdbg)

// SetBuffers is an option for replacing stdout and stderr by
// bytes buffers (in a bufio.Writer).
// If apdbg is nil, set for the global pdbg instance
func SetBuffers(apdbg *Pdbg) {
	if apdbg == nil {
		apdbg = pdbg
	}
	apdbg.bout = bytes.NewBuffer(nil)
	apdbg.sout = bufio.NewWriter(apdbg.bout)
	apdbg.berr = bytes.NewBuffer(nil)
	apdbg.serr = bufio.NewWriter(apdbg.berr)
}

// SetExcludes set excludes on a pdbg (nil for global pdbg)
func (pdbg *Pdbg) SetExcludes(excludes []string) {
	pdbg.excludes = excludes
}

// OptExcludes is an option to set excludes at the creation of a pdbg
func OptExcludes(excludes []string) Option {
	return func(apdbg *Pdbg) {
		apdbg.SetExcludes(excludes)
	}
}

// SetSkips set skips on a pdbg (nil for global pdbg)
func (pdbg *Pdbg) SetSkips(skips []string) {
	sk := []string{"/godbg.go'"}
	sk = append(sk, skips...)
	pdbg.skips = sk
}

// OptSkips is an option to set excludes at the creation of a pdbg
func OptSkips(skips []string) Option {
	return func(apdbg *Pdbg) {
		apdbg.SetSkips(skips)
	}
}

// NewPdbg creates a PDbg instance, with options
func NewPdbg(options ...Option) *Pdbg {
	newpdbg := &Pdbg{}
	for _, option := range options {
		option(newpdbg)
	}
	newpdbg.breaks = append(newpdbg.breaks, "smartystreets")
	//newpdbg.breaks = append(newpdbg.breaks, "(*Pdbg).Pdbgf")
	newpdbg.skips = append(newpdbg.skips, "/godbg.go'")
	return newpdbg
}

// ResetIOs reset the out and err buffer of global pdbg instance
func ResetIOs() {
	pdbg.ResetIOs()
}

// ResetIOs reset the out and err buffer
// (unless they were the default stdout and stderr,
// in which case it does nothing)
func (pdbg *Pdbg) ResetIOs() {
	if pdbg.sout != nil {
		pdbg.bout = bytes.NewBuffer(nil)
		pdbg.sout.Reset(pdbg.bout)
		pdbg.berr = bytes.NewBuffer(nil)
		pdbg.serr.Reset(pdbg.berr)
	}
}

// OutString returns the string for out messages for the global pdbg instance.
// It flushes the out buffer.
// If out is set to os.Stdout, returns an empty string
func OutString() string {
	return pdbg.OutString()
}

// OutString returns the string for out messages for a given pdbg instance.
// It flushes the out buffer.
// If out is set to os.Stdout, returns an empty string
func (pdbg *Pdbg) OutString() string {
	if pdbg.sout == nil {
		return ""
	}
	pdbg.sout.Flush()
	return pdbg.bout.String()
}

// ErrString returns the string for error messages for the global pdbg instance.
// It flushes the err buffer.
// If err is set to os.StdErr, returns an empty string
func ErrString() string {
	return pdbg.ErrString()
}

// ErrString returns the string for error messages for a given pdbg instance.
// It flushes the err buffer.
// If err is set to os.StdErr, returns an empty string
func (pdbg *Pdbg) ErrString() string {
	if pdbg.serr == nil {
		return ""
	}
	pdbg.serr.Flush()
	return pdbg.berr.String()
}

// NoOutput checks if there is any output recorded on Stdout or Stderr
func NoOutput() bool {
	return OutString() == "" && ErrString() == ""
}

// NoOutput checks if there is any output recorded on Stdout or Stderr
// for a given pdbg instance.
func (pdbg *Pdbg) NoOutput() bool {
	return pdbg.OutString() == "" && pdbg.ErrString() == ""
}

func (pdbg *Pdbg) pdbgExcluded(dbg string) bool {
	for _, e := range pdbg.excludes {
		if strings.Contains(dbg, e) {
			// fmt.Printf("EXCLUDE over '%v' including '%v'\n", dbg, e) // DBG
			return true
		}
	}
	return false
}

func (pdbg *Pdbg) pdbgBreak(dbg string) bool {
	for _, b := range pdbg.breaks {
		if strings.Contains(dbg, b) {
			// fmt.Printf("BREAK over '%v' including '%v'\n", dbg, b) // DBG
			return true
		}
	}
	return false
}

func (pdbg *Pdbg) pdbgSkip(dbg string) (bool, int) {
	depthToAdd := 0
	for i, s := range pdbg.skips {
		if strings.Contains(dbg, s) {
			if i > 0 {
				depthToAdd = 1
			}
			// fmt.Printf("SKIP over '%v' including '%v'\n", dbg, s) // DBG
			return true, depthToAdd
		}
	}
	return false, depthToAdd
}

// Pdbgf uses global Pdbg variable for printing strings, with indent and function name
func Pdbgf(format string, args ...interface{}) string {
	return pdbg.Pdbgf(format, args...)
}

type caller func(skip int) (pc uintptr, file string, line int, ok bool)

var mycaller = runtime.Caller

// Perrdbgf uses Stderr for printing strings, with indent and function name
func Perrdbgf(format string, args ...interface{}) string {
	return pdbg.pdbgfw(format, os.Stderr, args...)
}

// Pdbgf uses custom Pdbg variable for printing strings, with indent and function name
func (pdbg *Pdbg) Pdbgf(format string, args ...interface{}) string {
	return pdbg.pdbgfw(format, pdbg.Err(), args...)
}

func (pdbg *Pdbg) pdbgfw(format string, iow io.Writer, args ...interface{}) string {
	msg := fmt.Sprintf(format+"\n", args...)
	msg = strings.TrimSpace(msg)

	pmsg := ""
	depth := 0
	nbskip := 0
	nbInitialSkips := 0
	first := true
	addOneForSkip := 0
	// fmt.Printf("~~~~~~~~~~~~~~~~~~~~~~\n") // DBG
	for ok := true; ok; {
		pc, file, line, ok := mycaller(depth)
		if !ok {
			break
		}
		fname := runtime.FuncForPC(pc).Name()
		fline := fmt.Sprintf("Name of function: '%v': '%+x' (line %v): file '%v'\n", fname, fname, line, file)
		// fmt.Println(fline) // DBG
		if pdbg.pdbgExcluded(fline) {
			depth = depth + 1
			if first {
				return ""
			}
			continue
		}
		if pdbg.pdbgBreak(fline) {
			break
		}
		if isSkipped, depthToAdd := pdbg.pdbgSkip(fline); isSkipped {
			depth = depth + 1
			nbskip = nbskip + 1
			addOneForSkip = addOneForSkip + depthToAdd
			continue
		}
		fnamerx1 := regexp.MustCompile(`.*\.func[^a-zA-Z0-9]`)
		fname = fnamerx1.ReplaceAllString(fname, "func.")
		fnamerx2 := regexp.MustCompile(`.*/`)
		fname = fnamerx2.ReplaceAllString(fname, "")
		if !strings.HasPrefix(fname, "func.") {
			fnamerx3 := regexp.MustCompile(`^.*?\.`)
			// fmt.Printf("fname before: '%v'", fname)
			fname = fnamerx3.ReplaceAllString(fname, "")
			// fmt.Printf(" => fname after: '%v'\n", fname)
			fnamerx4 := regexp.MustCompile(`[\(\)]`)
			fname = fnamerx4.ReplaceAllString(fname, "")
		}
		dbg := fname + ":" + fmt.Sprintf("%d", line)
		if first {
			// fmt.Printf(" => nbskip '%v'; addOneForSkip '%v'\n", nbskip, addOneForSkip) // DBG
			nbInitialSkips = nbskip - addOneForSkip
			pmsg = "[" + dbg + "]"
		} else {
			pmsg = pmsg + " (" + dbg + ")"
		}
		first = false
		depth = depth + 1
	}
	finalDepth := depth
	depth = finalDepth - nbInitialSkips - 1

	spaces := ""
	if depth >= 0 {
		spaces = strings.Repeat(" ", depth*2)
	}
	// fmt.Printf("spaces '%s', finalDepth '%d', depth '%d', nbInitialSkips '%d', addOneForSkip='%d'\n", spaces, finalDepth, depth, nbInitialSkips, addOneForSkip) // DBG
	res := pmsg
	if pmsg != "" {
		pmsg = spaces + pmsg + "\n"
	}
	msg = pmsg + spaces + "  " + msg + "\n"
	// fmt.Printf("==> MSG '%v'\n", msg) // DBG
	fmt.Fprint(pdbg.Err(), fmt.Sprint(msg))
	return res
}

var r = regexp.MustCompile(`:\d+[\)\]]`)
var r2 = regexp.MustCompile(`func\.\d+[\)\]]`)

// ShouldEqualNL is a custom goconvey assertion to ignore differences
// with func id and lines: `[globalPdbgExcludeTest:16] (func.019:167)` would
// be equal to [globalPdbgExcludeTest] (func)
// (see https://github.com/smartystreets/goconvey/wiki/Custom-Assertions)
func ShouldEqualNL(actual interface{}, expected ...interface{}) string {
	a := actual.(string)
	e := expected[0].(string)
	a = r.ReplaceAllStringFunc(a, func(s string) string { return s[len(s)-1:] })
	e = r.ReplaceAllStringFunc(e, func(s string) string { return s[len(s)-1:] })
	a = r2.ReplaceAllStringFunc(a, func(s string) string { return "func" + s[len(s)-1:] })
	e = r2.ReplaceAllStringFunc(e, func(s string) string { return "func" + s[len(s)-1:] })
	a = strings.TrimRight(a, "\r\n")
	e = strings.TrimRight(e, "\r\n")
	if a == e {
		return ""
	}
	return fmt.Sprintf("Extected: '%s'\nActual:   '%s'\n(Should be equal even with different lines and function ids)", e, a)
}
<commit_msg>godbg pdbgfw actually uses the io.Writer passed<commit_after>package godbg

import (
	"bufio"
	"bytes"
	"fmt"
	"io"
	"os"
	"regexp"
	"runtime"
	"strings"
)

// http://stackoverflow.com/a/23554672/6309 https://vividcortex.com/blog/2013/12/03/go-idiom-package-and-object/
// you design a type with methods as usual, and then you also place matching functions at the package level itself.
// These functions simply delegate to a default instance of the type that’s a private package-level variable, created in an init() function.

// Pdbg allows to print debug message with indent and function name added
type Pdbg struct {
	bout     *bytes.Buffer
	berr     *bytes.Buffer
	sout     *bufio.Writer
	serr     *bufio.Writer
	breaks   []string
	excludes []string
	skips    []string
}

// Out returns a writer for normal messages.
// By default, os.StdOut
func Out() io.Writer {
	return pdbg.Out()
}

// Out returns a writer for normal messages for a given pdbg instance.
// By default, os.StdOut
func (pdbg *Pdbg) Out() io.Writer {
	if pdbg.sout == nil {
		return os.Stdout
	}
	return pdbg.sout
}

// Err returns a writer for error messages.
// By default, os.StdErr
func Err() io.Writer {
	return pdbg.Err()
}

// Err returns a writer for error messages for a given pdbg instance.
// By default, os.StdErr
func (pdbg *Pdbg) Err() io.Writer {
	if pdbg.serr == nil {
		return os.Stderr
	}
	return pdbg.serr
}

// global pdbg used for printing
var pdbg = NewPdbg()

// Option set an option for a Pdbg
// http://dave.cheney.net/2014/10/17/functional-options-for-friendly-apis
type Option func(*Pdbg)

// SetBuffers is an option for replacing stdout and stderr by
// bytes buffers (in a bufio.Writer).
// If apdbg is nil, set for the global pdbg instance
func SetBuffers(apdbg *Pdbg) {
	if apdbg == nil {
		apdbg = pdbg
	}
	apdbg.bout = bytes.NewBuffer(nil)
	apdbg.sout = bufio.NewWriter(apdbg.bout)
	apdbg.berr = bytes.NewBuffer(nil)
	apdbg.serr = bufio.NewWriter(apdbg.berr)
}

// SetExcludes set excludes on a pdbg (nil for global pdbg)
func (pdbg *Pdbg) SetExcludes(excludes []string) {
	pdbg.excludes = excludes
}

// OptExcludes is an option to set excludes at the creation of a pdbg
func OptExcludes(excludes []string) Option {
	return func(apdbg *Pdbg) {
		apdbg.SetExcludes(excludes)
	}
}

// SetSkips set skips on a pdbg (nil for global pdbg)
func (pdbg *Pdbg) SetSkips(skips []string) {
	sk := []string{"/godbg.go'"}
	sk = append(sk, skips...)
	pdbg.skips = sk
}

// OptSkips is an option to set excludes at the creation of a pdbg
func OptSkips(skips []string) Option {
	return func(apdbg *Pdbg) {
		apdbg.SetSkips(skips)
	}
}

// NewPdbg creates a PDbg instance, with options
func NewPdbg(options ...Option) *Pdbg {
	newpdbg := &Pdbg{}
	for _, option := range options {
		option(newpdbg)
	}
	newpdbg.breaks = append(newpdbg.breaks, "smartystreets")
	//newpdbg.breaks = append(newpdbg.breaks, "(*Pdbg).Pdbgf")
	newpdbg.skips = append(newpdbg.skips, "/godbg.go'")
	return newpdbg
}

// ResetIOs reset the out and err buffer of global pdbg instance
func ResetIOs() {
	pdbg.ResetIOs()
}

// ResetIOs reset the out and err buffer
// (unless they were the default stdout and stderr,
// in which case it does nothing)
func (pdbg *Pdbg) ResetIOs() {
	if pdbg.sout != nil {
		pdbg.bout = bytes.NewBuffer(nil)
		pdbg.sout.Reset(pdbg.bout)
		pdbg.berr = bytes.NewBuffer(nil)
		pdbg.serr.Reset(pdbg.berr)
	}
}

// OutString returns the string for out messages for the global pdbg instance.
// It flushes the out buffer.
// If out is set to os.Stdout, returns an empty string
func OutString() string {
	return pdbg.OutString()
}

// OutString returns the string for out messages for a given pdbg instance.
// It flushes the out buffer.
// If out is set to os.Stdout, returns an empty string
func (pdbg *Pdbg) OutString() string {
	if pdbg.sout == nil {
		return ""
	}
	pdbg.sout.Flush()
	return pdbg.bout.String()
}

// ErrString returns the string for error messages for the global pdbg instance.
// It flushes the err buffer.
// If err is set to os.StdErr, returns an empty string
func ErrString() string {
	return pdbg.ErrString()
}

// ErrString returns the string for error messages for a given pdbg instance.
// It flushes the err buffer.
// If err is set to os.StdErr, returns an empty string
func (pdbg *Pdbg) ErrString() string {
	if pdbg.serr == nil {
		return ""
	}
	pdbg.serr.Flush()
	return pdbg.berr.String()
}

// NoOutput checks if there is any output recorded on Stdout or Stderr
func NoOutput() bool {
	return OutString() == "" && ErrString() == ""
}

// NoOutput checks if there is any output recorded on Stdout or Stderr
// for a given pdbg instance.
func (pdbg *Pdbg) NoOutput() bool {
	return pdbg.OutString() == "" && pdbg.ErrString() == ""
}

func (pdbg *Pdbg) pdbgExcluded(dbg string) bool {
	for _, e := range pdbg.excludes {
		if strings.Contains(dbg, e) {
			// fmt.Printf("EXCLUDE over '%v' including '%v'\n", dbg, e) // DBG
			return true
		}
	}
	return false
}

func (pdbg *Pdbg) pdbgBreak(dbg string) bool {
	for _, b := range pdbg.breaks {
		if strings.Contains(dbg, b) {
			// fmt.Printf("BREAK over '%v' including '%v'\n", dbg, b) // DBG
			return true
		}
	}
	return false
}

func (pdbg *Pdbg) pdbgSkip(dbg string) (bool, int) {
	depthToAdd := 0
	for i, s := range pdbg.skips {
		if strings.Contains(dbg, s) {
			if i > 0 {
				depthToAdd = 1
			}
			// fmt.Printf("SKIP over '%v' including '%v'\n", dbg, s) // DBG
			return true, depthToAdd
		}
	}
	return false, depthToAdd
}

// Pdbgf uses global Pdbg variable for printing strings, with indent and function name
func Pdbgf(format string, args ...interface{}) string {
	return pdbg.Pdbgf(format, args...)
}

type caller func(skip int) (pc uintptr, file string, line int, ok bool)

var mycaller = runtime.Caller

// Perrdbgf uses Stderr for printing strings, with indent and function name
func Perrdbgf(format string, args ...interface{}) string {
	return pdbg.pdbgfw(format, os.Stderr, args...)
}

// Pdbgf uses custom Pdbg variable for printing strings, with indent and function name
func (pdbg *Pdbg) Pdbgf(format string, args ...interface{}) string {
	return pdbg.pdbgfw(format, pdbg.Err(), args...)
}

func (pdbg *Pdbg) pdbgfw(format string, iow io.Writer, args ...interface{}) string {
	msg := fmt.Sprintf(format+"\n", args...)
	msg = strings.TrimSpace(msg)

	pmsg := ""
	depth := 0
	nbskip := 0
	nbInitialSkips := 0
	first := true
	addOneForSkip := 0
	// fmt.Printf("~~~~~~~~~~~~~~~~~~~~~~\n") // DBG
	for ok := true; ok; {
		pc, file, line, ok := mycaller(depth)
		if !ok {
			break
		}
		fname := runtime.FuncForPC(pc).Name()
		fline := fmt.Sprintf("Name of function: '%v': '%+x' (line %v): file '%v'\n", fname, fname, line, file)
		// fmt.Println(fline) // DBG
		if pdbg.pdbgExcluded(fline) {
			depth = depth + 1
			if first {
				return ""
			}
			continue
		}
		if pdbg.pdbgBreak(fline) {
			break
		}
		if isSkipped, depthToAdd := pdbg.pdbgSkip(fline); isSkipped {
			depth = depth + 1
			nbskip = nbskip + 1
			addOneForSkip = addOneForSkip + depthToAdd
			continue
		}
		fnamerx1 := regexp.MustCompile(`.*\.func[^a-zA-Z0-9]`)
		fname = fnamerx1.ReplaceAllString(fname, "func.")
		fnamerx2 := regexp.MustCompile(`.*/`)
		fname = fnamerx2.ReplaceAllString(fname, "")
		if !strings.HasPrefix(fname, "func.") {
			fnamerx3 := regexp.MustCompile(`^.*?\.`)
			// fmt.Printf("fname before: '%v'", fname)
			fname = fnamerx3.ReplaceAllString(fname, "")
			// fmt.Printf(" => fname after: '%v'\n", fname)
			fnamerx4 := regexp.MustCompile(`[\(\)]`)
			fname = fnamerx4.ReplaceAllString(fname, "")
		}
		dbg := fname + ":" + fmt.Sprintf("%d", line)
		if first {
			// fmt.Printf(" => nbskip '%v'; addOneForSkip '%v'\n", nbskip, addOneForSkip) // DBG
			nbInitialSkips = nbskip - addOneForSkip
			pmsg = "[" + dbg + "]"
		} else {
			pmsg = pmsg + " (" + dbg + ")"
		}
		first = false
		depth = depth + 1
	}
	finalDepth := depth
	depth = finalDepth - nbInitialSkips - 1

	spaces := ""
	if depth >= 0 {
		spaces = strings.Repeat(" ", depth*2)
	}
	// fmt.Printf("spaces '%s', finalDepth '%d', depth '%d', nbInitialSkips '%d', addOneForSkip='%d'\n", spaces, finalDepth, depth, nbInitialSkips, addOneForSkip) // DBG
	res := pmsg
	if pmsg != "" {
		pmsg = spaces + pmsg + "\n"
	}
	msg = pmsg + spaces + "  " + msg + "\n"
	// fmt.Printf("==> MSG '%v'\n", msg) // DBG
	fmt.Fprint(iow, fmt.Sprint(msg))
	return res
}

var r = regexp.MustCompile(`:\d+[\)\]]`)
var r2 = regexp.MustCompile(`func\.\d+[\)\]]`)

// ShouldEqualNL is a custom goconvey assertion to ignore differences
// with func id and lines: `[globalPdbgExcludeTest:16] (func.019:167)` would
// be equal to [globalPdbgExcludeTest] (func)
// (see https://github.com/smartystreets/goconvey/wiki/Custom-Assertions)
func ShouldEqualNL(actual interface{}, expected ...interface{}) string {
	a := actual.(string)
	e := expected[0].(string)
	a = r.ReplaceAllStringFunc(a, func(s string) string { return s[len(s)-1:] })
	e = r.ReplaceAllStringFunc(e, func(s string) string { return s[len(s)-1:] })
	a = r2.ReplaceAllStringFunc(a, func(s string) string { return "func" + s[len(s)-1:] })
	e = r2.ReplaceAllStringFunc(e, func(s string) string { return "func" + s[len(s)-1:] })
	a = strings.TrimRight(a, "\r\n")
	e = strings.TrimRight(e, "\r\n")
	if a == e {
		return ""
	}
	return fmt.Sprintf("Extected: '%s'\nActual:   '%s'\n(Should be equal even with different lines and function ids)", e, a)
}
<|endoftext|>


<commit_before>package gorle

import (
	"bytes"
	"fmt"
	"strconv"
)

func encode(s string) string {
	count := 1
	var o bytes.Buffer
	var i int
	for i = 0; i < len(s)-1; i++ {
		if s[i] == s[i+1] {
			count++
		} else {
			o.WriteString(fmt.Sprintf("%d%c", count, s[i]))
			count = 1
		}
	}
	o.WriteString(fmt.Sprintf("%d%c", count, s[i]))
	return o.String()
}

func decode(s string) string {
	var o bytes.Buffer
	var count string
	for i := 0; i < len(s); i++ {
		if val, _ := strconv.Atoi(string(s[i])); val > 0 && val <= 9 {
			if countN, err := strconv.Atoi(count); err == nil {
				count = fmt.Sprintf("%d%d", countN, val)
			} else {
				count = string(s[i])
			}
		} else {
			count2, _ := strconv.Atoi(count)
			for j := 0; j < count2; j++ {
				o.WriteString(fmt.Sprintf("%c", s[i]))
			}
			count = ""
		}
	}
	return o.String()
}
<commit_msg>Capitalized<commit_after>package gorle

import (
	"bytes"
	"fmt"
	"strconv"
)

func Encode(s string) string {
	count := 1
	var o bytes.Buffer
	var i int
	for i = 0; i < len(s)-1; i++ {
		if s[i] == s[i+1] {
			count++
		} else {
			o.WriteString(fmt.Sprintf("%d%c", count, s[i]))
			count = 1
		}
	}
	o.WriteString(fmt.Sprintf("%d%c", count, s[i]))
	return o.String()
}

func Decode(s string) string {
	var o bytes.Buffer
	var count string
	for i := 0; i < len(s); i++ {
		if val, _ := strconv.Atoi(string(s[i])); val > 0 && val <= 9 {
			if countN, err := strconv.Atoi(count); err == nil {
				count = fmt.Sprintf("%d%d", countN, val)
			} else {
				count = string(s[i])
			}
		} else {
			count2, _ := strconv.Atoi(count)
			for j := 0; j < count2; j++ {
				o.WriteString(fmt.Sprintf("%c", s[i]))
			}
			count = ""
		}
	}
	return o.String()
}
<|endoftext|>


<commit_before>package gospy

import (
	"reflect"
	"github.com/cfmobile/gmock"
	"fmt"
)

type ParamList []interface{}

type CallList []ParamList

type GoSpy struct {
	Called  bool
	Calls   CallList
	mock   *gmock.GMock
}

func (self *GoSpy) Restore() {
	self.mock.Restore()
}

func (self *GoSpy) Reset() {
	self.Called = false
	self.Calls = nil
}

func (self *GoSpy) storeCall(arguments []reflect.Value) {
	self.Called = true;

	var call ParamList
	for _, arg := range arguments {
		call = append(call, arg.Interface())
	}

	self.Calls = append(self.Calls, call)
}

func Spy(targetFuncVar interface{}) *GoSpy {
	spy := createSpy(targetFuncVar)
	defaultFn := spy.getDefaultFn()
	spy.setTargetFn(defaultFn)
	return spy
}

func SpyAndFake(targetFuncVar interface{}) *GoSpy {
	return SpyAndFakeWithReturn(targetFuncVar) //nil fakeReturnValues will create default
}

func SpyAndFakeWithReturn(targetFuncVar interface{}, fakeReturnValues ...interface{}) *GoSpy {
	spy := createSpy(targetFuncVar)
	fakeReturnFn := spy.getFnWithReturnValues(fakeReturnValues)
	spy.setTargetFn(fakeReturnFn)
	return spy
}

func SpyAndFakeWithFunc(targetFuncVar interface{}, mockFunc interface{}) *GoSpy {
	targetType := reflect.ValueOf(targetFuncVar).Type()
	mockFuncType := reflect.ValueOf(mockFunc).Type()

	if targetType != mockFuncType {
		panic(fmt.Sprintf("Fake function has to have the same signature as the target [target: %+v, mock: %+v]", targetType, mockFuncType))
	}

	spy := createSpy(targetFuncVar)
	fakeFuncFn := spy.getFnWithMockFunc(mockFunc)
	spy.setTargetFn(fakeFuncFn)
	return spy
}

func (self *GoSpy) setTargetFn(fn func(args []reflect.Value) []reflect.Value) {
	targetType := self.mock.GetTarget().Type()
	wrapperFn := func(args []reflect.Value) []reflect.Value {
		self.storeCall(args)
		return reflect.MakeFunc(targetType, fn).Call(args)
	}

	targetFn := reflect.MakeFunc(targetType, wrapperFn)
	self.mock.Replace(targetFn.Interface())
}

func (self *GoSpy) getDefaultFn() (func(args []reflect.Value) []reflect.Value) {
	return self.mock.GetOriginal().Call
}

func (self *GoSpy) getFnWithReturnValues(fakeReturnValues []interface{}) (func(args []reflect.Value) []reflect.Value) {
	// Gets the expected number of return values from the target
	var numReturnValues = self.mock.GetTarget().Type().NumOut()

	if fakeReturnValues != nil && numReturnValues != len(fakeReturnValues) {
		panic("Invalid number of return values. Either specify all or none")
	}

	return func(args []reflect.Value) (results []reflect.Value) {
		// Builds slice of return values, if required
		targetType := self.mock.GetTarget().Type()
		for i := 0; i < numReturnValues; i++ {
			returnItem := reflect.New(targetType.Out(i))

			var returnElem = returnItem.Elem()

			// Gets value for return from fakeReturnValues, or leaves default constructed value if not available
			if fakeReturnValues != nil && fakeReturnValues[i] != nil {
				returnElem.Set(reflect.ValueOf(fakeReturnValues[i]))
			}

			results = append(results, returnElem)
		}

		return results
	}
}

func (self *GoSpy) getFnWithMockFunc(mockFunc interface{}) (func(args []reflect.Value) []reflect.Value) {
	mockFuncValue := reflect.ValueOf(mockFunc)
	if !mockFuncValue.IsValid() {
		targetType := self.mock.GetTarget().Type()
		mockFuncValue = reflect.Zero(targetType)
	}

	return mockFuncValue.Call
}

func createSpy(targetFuncPtr interface{}) *GoSpy {
	if !targetIsValid(targetFuncPtr) {
		panic("Spy target has to be the pointer to a Func variable")
	}

	spy := &GoSpy{Called: false, Calls: nil, mock: gmock.CreateMockWithTarget(targetFuncPtr)}

	return spy
}

func targetIsValid(target interface{}) bool {
	// Target has to be a ptr to a function
	targetValue := reflect.ValueOf(target)
	return targetValue.Kind() == reflect.Ptr &&
		   targetValue.Elem().Kind() == reflect.Func
}<commit_msg>RS - Renamed ParamList type to ArgList<commit_after>package gospy

import (
	"reflect"
	"github.com/cfmobile/gmock"
	"fmt"
)

type ArgList []interface{}

type CallList []ArgList

type GoSpy struct {
	Called  bool
	Calls   CallList
	mock   *gmock.GMock
}

func (self *GoSpy) Restore() {
	self.mock.Restore()
}

func (self *GoSpy) Reset() {
	self.Called = false
	self.Calls = nil
}

func (self *GoSpy) storeCall(arguments []reflect.Value) {
	self.Called = true;

	var call ArgList
	for _, arg := range arguments {
		call = append(call, arg.Interface())
	}

	self.Calls = append(self.Calls, call)
}

func Spy(targetFuncVar interface{}) *GoSpy {
	spy := createSpy(targetFuncVar)
	defaultFn := spy.getDefaultFn()
	spy.setTargetFn(defaultFn)
	return spy
}

func SpyAndFake(targetFuncVar interface{}) *GoSpy {
	return SpyAndFakeWithReturn(targetFuncVar) //nil fakeReturnValues will create default
}

func SpyAndFakeWithReturn(targetFuncVar interface{}, fakeReturnValues ...interface{}) *GoSpy {
	spy := createSpy(targetFuncVar)
	fakeReturnFn := spy.getFnWithReturnValues(fakeReturnValues)
	spy.setTargetFn(fakeReturnFn)
	return spy
}

func SpyAndFakeWithFunc(targetFuncVar interface{}, mockFunc interface{}) *GoSpy {
	targetType := reflect.ValueOf(targetFuncVar).Type()
	mockFuncType := reflect.ValueOf(mockFunc).Type()

	if targetType != mockFuncType {
		panic(fmt.Sprintf("Fake function has to have the same signature as the target [target: %+v, mock: %+v]", targetType, mockFuncType))
	}

	spy := createSpy(targetFuncVar)
	fakeFuncFn := spy.getFnWithMockFunc(mockFunc)
	spy.setTargetFn(fakeFuncFn)
	return spy
}

func (self *GoSpy) setTargetFn(fn func(args []reflect.Value) []reflect.Value) {
	targetType := self.mock.GetTarget().Type()
	wrapperFn := func(args []reflect.Value) []reflect.Value {
		self.storeCall(args)
		return reflect.MakeFunc(targetType, fn).Call(args)
	}

	targetFn := reflect.MakeFunc(targetType, wrapperFn)
	self.mock.Replace(targetFn.Interface())
}

func (self *GoSpy) getDefaultFn() (func(args []reflect.Value) []reflect.Value) {
	return self.mock.GetOriginal().Call
}

func (self *GoSpy) getFnWithReturnValues(fakeReturnValues []interface{}) (func(args []reflect.Value) []reflect.Value) {
	// Gets the expected number of return values from the target
	var numReturnValues = self.mock.GetTarget().Type().NumOut()

	if fakeReturnValues != nil && numReturnValues != len(fakeReturnValues) {
		panic("Invalid number of return values. Either specify all or none")
	}

	return func(args []reflect.Value) (results []reflect.Value) {
		// Builds slice of return values, if required
		targetType := self.mock.GetTarget().Type()
		for i := 0; i < numReturnValues; i++ {
			returnItem := reflect.New(targetType.Out(i))

			var returnElem = returnItem.Elem()

			// Gets value for return from fakeReturnValues, or leaves default constructed value if not available
			if fakeReturnValues != nil && fakeReturnValues[i] != nil {
				returnElem.Set(reflect.ValueOf(fakeReturnValues[i]))
			}

			results = append(results, returnElem)
		}

		return results
	}
}

func (self *GoSpy) getFnWithMockFunc(mockFunc interface{}) (func(args []reflect.Value) []reflect.Value) {
	mockFuncValue := reflect.ValueOf(mockFunc)
	if !mockFuncValue.IsValid() {
		targetType := self.mock.GetTarget().Type()
		mockFuncValue = reflect.Zero(targetType)
	}

	return mockFuncValue.Call
}

func createSpy(targetFuncPtr interface{}) *GoSpy {
	if !targetIsValid(targetFuncPtr) {
		panic("Spy target has to be the pointer to a Func variable")
	}

	spy := &GoSpy{Called: false, Calls: nil, mock: gmock.CreateMockWithTarget(targetFuncPtr)}

	return spy
}

func targetIsValid(target interface{}) bool {
	// Target has to be a ptr to a function
	targetValue := reflect.ValueOf(target)
	return targetValue.Kind() == reflect.Ptr &&
		   targetValue.Elem().Kind() == reflect.Func
}<|endoftext|>


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

package graph

// All a node needs to do is identify itself. This allows the user to pass in nodes more
// interesting than an int, but also allow us to reap the benefits of having a map-storable,
// ==able type.
type Node interface {
	ID() int
}

// Allows edges to do something more interesting that just be a group of nodes. While the methods
// are called Head and Tail, they are not considered directed unless the given interface specifies
// otherwise.
type Edge interface {
	Head() Node
	Tail() Node
}

// A Graph implements the behavior of an undirected graph.
//
// All methods in Graph are implicitly undirected. Graph algorithms that care about directionality
// will intelligently choose the DirectedGraph behavior if that interface is also implemented,
// even if the function itself only takes in a Graph (or a super-interface of graph).
type Graph interface {
	// NodeExists returns true when node is currently in the graph.
	NodeExists(Node) bool

	// NodeList returns a list of all nodes in no particular order, useful for
	// determining things like if a graph is fully connected. The caller is
	// free to modify this list. Implementations should construct a new list
	// and not return internal representation.
	NodeList() []Node

	// Neighbors returns all nodes connected by any edge to this node.
	Neighbors(Node) []Node

	// EdgeBetween returns an edge between node and neighbor such that
	// Head is one argument and Tail is the other. If no
	// such edge exists, this function returns nil.
	EdgeBetween(node, neighbor Node) Edge
}

// Directed graphs are characterized by having seperable Heads and Tails in their edges.
// That is, if node1 goes to node2, that does not necessarily imply that node2 goes to node1.
//
// While it's possible for a directed graph to have fully reciprocal edges (i.e. the graph is
// symmetric) -- it is not required to be. The graph is also required to implement Graph
// because in many cases it can be useful to know all neighbors regardless of direction.
type DirectedGraph interface {
	Graph
	// Successors gives the nodes connected by OUTBOUND edges.
	// If the graph is an undirected graph, this set is equal to Predecessors.
	Successors(Node) []Node

	// EdgeTo returns an edge between node and successor such that
	// Head returns node and Tail returns successor, if no
	// such edge exists, this function returns nil.
	EdgeTo(node, successor Node) Edge

	// Predecessors gives the nodes connected by INBOUND edges.
	// If the graph is an undirected graph, this set is equal to Successors.
	Predecessors(Node) []Node
}

// Returns all undirected edges in the graph
type EdgeLister interface {
	EdgeList() []Edge
}

type EdgeListGraph interface {
	Graph
	EdgeLister
}

// Returns all directed edges in the graph.
type DirectedEdgeLister interface {
	DirectedEdgeList() []Edge
}

type DirectedEdgeListGraph interface {
	Graph
	DirectedEdgeLister
}

// A crunch graph forces a sparse graph to become a dense graph. That is, if the node IDs are
// [1,4,9,7] it would "crunch" the ids into the contiguous block [0,1,2,3]. Order is not
// required to be preserved between the non-cruched and crunched instances (that means in
// the example above 0 may correspond to 4 or 7 or 9, not necessarily 1).
//
// All dense graphs must have the first ID as 0.
type CrunchGraph interface {
	Graph
	Crunch()
}

// A Graph that implements Coster has an actual cost between adjacent nodes, also known as a
// weighted graph. If a graph implements coster and a function needs to read cost (e.g. A*),
// this function will take precedence over the Uniform Cost function (all weights are 1) if "nil"
// is passed in for the function argument.
//
// If the argument is nil, or the edge is invalid for some reason, this should return math.Inf(1)
type Coster interface {
	Cost(edge Edge) float64
}

type CostGraph interface {
	Coster
	Graph
}

type CostDirectedGraph interface {
	Coster
	DirectedGraph
}

// A graph that implements HeuristicCoster implements a heuristic between any two given nodes.
// Like Coster, if a graph implements this and a function needs a heuristic cost (e.g. A*), this
// function will take precedence over the Null Heuristic (always returns 0) if "nil" is passed in
// for the function argument. If HeuristicCost is not intended to be used, it can be implemented as
// the null heuristic (always returns 0.)
type HeuristicCoster interface {
	// HeuristicCost returns a heuristic cost between any two nodes.
	HeuristicCost(node1, node2 Node) float64
}

// A Mutable is a graph that can have arbitrary nodes and edges added or removed.
//
// Anything implementing Mutable is required to store the actual argument. So if AddNode(myNode) is
// called and later a user calls on the graph graph.NodeList(), the node added by AddNode must be
// an the exact node, not a new node with the same ID.
//
// In any case where conflict is possible (e.g. adding two nodes with the same ID), the later
// call always supercedes the earlier one.
//
// Functions will generally expect one of MutableGraph or MutableDirectedGraph and not Mutable
// itself. That said, any function that takes Mutable[x], the destination mutable should
// always be a different graph than the source.
type Mutable interface {
	// NewNode adds a node with an arbitrary ID and returns the new, unique ID
	// used.
	NewNode() Node

	// Adds a node to the graph. If this is called multiple times for the same ID, the newer node
	// overwrites the old one.
	AddNode(Node)

	// EmptyGraph clears the graph of all nodes and edges.
	EmptyGraph()

	// RemoveNode removes a node from the graph, as well as any edges
	// attached to it. If no such node exists, this is a no-op, not an error.
	RemoveNode(Node)
}

// MutableGraph is an interface ensuring the implementation of the ability to construct
// an arbitrary undirected graph. It is very important to note that any implementation
// of MutableGraph absolutely cannot safely implement the DirectedGraph interface.
//
// A MutableGraph is required to store any Edge argument in the same way Mutable must
// store a Node argument -- any retrieval call is required to return the exact supplied edge.
// This is what makes it incompatible with DirectedGraph.
//
// A call to AddEdgeBetween(Edge{head,tail}) make is so there is simply no way to safely
// return EdgeTo(tail, head) since the edge returned will, by this contract, need to be
// Head() == head and Tail() == tail when the reverse must be true to fulfill the
// functionality guaranteed of EdgeTo.
type MutableGraph interface {
	CostGraph
	Mutable

	// Like EdgeBetween in Graph, AddEdgeBetween adds an edge between two nodes.
	// If one or both nodes do not exist, the Graph is expected to add them.
	AddEdgeBetween(e Edge, cost float64)

	// RemoveEdge clears the stored edge between two nodes. Calling this will never
	// remove a node. If the edge does not exist this is a no-op, not an error.
	RemoveEdgeBetween(e Edge)
}

// MutableDirectedGraph is an interface that ensures one can construct an arbitrary directed
// graph. Naturally, a MutableDirectedGraph works for both undirected and directed cases,
// but simply using a MutableGraph may be cleaner. As the documentation for MutableGraph
// notes, however, a graph cannot safely implement MutableGraph and MutableDirectedGraph
// at the same time, because of the functionality of a EdgeTo in DirectedGraph.
type MutableDirectedGraph interface {
	CostDirectedGraph
	Mutable

	// Adds an edge FROM e.Head TO e.Tail. Newer calls overwrite older ones.
	// If the nodes Head or Tail do not exist in the graph, this must add them.
	AddEdgeTo(e Edge, cost float64)

	// Removes an edge FROM e.Head TO e.Tail. If no such edge exists, this is a no-op,
	// not an error.
	RemoveEdgeTo(e Edge)
}

// A function that returns the cost of following an edge
type CostFunc func(Edge) float64

// Estimates the cost of travelling between two nodes
type HeuristicCostFunc func(Node, Node) float64

// Convenience constants for AddEdge and RemoveEdge
const (
	Directed   bool = true
	Undirected      = false
)

// Determines if a MutableGraph implements DirectedGraph and panics if it does.
// This is a utility function to detect unsafe implementations. It's mostly for internal use,
// but is exported since it may be useful to people who use the package for their own tests.
func VetMutableGraph(g MutableGraph) {
	if _, ok := g.(DirectedGraph); ok {
		panic("A MutableGraph implements DirectedGraph; this is unsafe!")
	}
}
<commit_msg>Removed useless convenience constants<commit_after>// Copyright ©2014 The gonum Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package graph

// All a node needs to do is identify itself. This allows the user to pass in nodes more
// interesting than an int, but also allow us to reap the benefits of having a map-storable,
// ==able type.
type Node interface {
	ID() int
}

// Allows edges to do something more interesting that just be a group of nodes. While the methods
// are called Head and Tail, they are not considered directed unless the given interface specifies
// otherwise.
type Edge interface {
	Head() Node
	Tail() Node
}

// A Graph implements the behavior of an undirected graph.
//
// All methods in Graph are implicitly undirected. Graph algorithms that care about directionality
// will intelligently choose the DirectedGraph behavior if that interface is also implemented,
// even if the function itself only takes in a Graph (or a super-interface of graph).
type Graph interface {
	// NodeExists returns true when node is currently in the graph.
	NodeExists(Node) bool

	// NodeList returns a list of all nodes in no particular order, useful for
	// determining things like if a graph is fully connected. The caller is
	// free to modify this list. Implementations should construct a new list
	// and not return internal representation.
	NodeList() []Node

	// Neighbors returns all nodes connected by any edge to this node.
	Neighbors(Node) []Node

	// EdgeBetween returns an edge between node and neighbor such that
	// Head is one argument and Tail is the other. If no
	// such edge exists, this function returns nil.
	EdgeBetween(node, neighbor Node) Edge
}

// Directed graphs are characterized by having seperable Heads and Tails in their edges.
// That is, if node1 goes to node2, that does not necessarily imply that node2 goes to node1.
//
// While it's possible for a directed graph to have fully reciprocal edges (i.e. the graph is
// symmetric) -- it is not required to be. The graph is also required to implement Graph
// because in many cases it can be useful to know all neighbors regardless of direction.
type DirectedGraph interface {
	Graph
	// Successors gives the nodes connected by OUTBOUND edges.
	// If the graph is an undirected graph, this set is equal to Predecessors.
	Successors(Node) []Node

	// EdgeTo returns an edge between node and successor such that
	// Head returns node and Tail returns successor, if no
	// such edge exists, this function returns nil.
	EdgeTo(node, successor Node) Edge

	// Predecessors gives the nodes connected by INBOUND edges.
	// If the graph is an undirected graph, this set is equal to Successors.
	Predecessors(Node) []Node
}

// Returns all undirected edges in the graph
type EdgeLister interface {
	EdgeList() []Edge
}

type EdgeListGraph interface {
	Graph
	EdgeLister
}

// Returns all directed edges in the graph.
type DirectedEdgeLister interface {
	DirectedEdgeList() []Edge
}

type DirectedEdgeListGraph interface {
	Graph
	DirectedEdgeLister
}

// A crunch graph forces a sparse graph to become a dense graph. That is, if the node IDs are
// [1,4,9,7] it would "crunch" the ids into the contiguous block [0,1,2,3]. Order is not
// required to be preserved between the non-cruched and crunched instances (that means in
// the example above 0 may correspond to 4 or 7 or 9, not necessarily 1).
//
// All dense graphs must have the first ID as 0.
type CrunchGraph interface {
	Graph
	Crunch()
}

// A Graph that implements Coster has an actual cost between adjacent nodes, also known as a
// weighted graph. If a graph implements coster and a function needs to read cost (e.g. A*),
// this function will take precedence over the Uniform Cost function (all weights are 1) if "nil"
// is passed in for the function argument.
//
// If the argument is nil, or the edge is invalid for some reason, this should return math.Inf(1)
type Coster interface {
	Cost(edge Edge) float64
}

type CostGraph interface {
	Coster
	Graph
}

type CostDirectedGraph interface {
	Coster
	DirectedGraph
}

// A graph that implements HeuristicCoster implements a heuristic between any two given nodes.
// Like Coster, if a graph implements this and a function needs a heuristic cost (e.g. A*), this
// function will take precedence over the Null Heuristic (always returns 0) if "nil" is passed in
// for the function argument. If HeuristicCost is not intended to be used, it can be implemented as
// the null heuristic (always returns 0.)
type HeuristicCoster interface {
	// HeuristicCost returns a heuristic cost between any two nodes.
	HeuristicCost(node1, node2 Node) float64
}

// A Mutable is a graph that can have arbitrary nodes and edges added or removed.
//
// Anything implementing Mutable is required to store the actual argument. So if AddNode(myNode) is
// called and later a user calls on the graph graph.NodeList(), the node added by AddNode must be
// an the exact node, not a new node with the same ID.
//
// In any case where conflict is possible (e.g. adding two nodes with the same ID), the later
// call always supercedes the earlier one.
//
// Functions will generally expect one of MutableGraph or MutableDirectedGraph and not Mutable
// itself. That said, any function that takes Mutable[x], the destination mutable should
// always be a different graph than the source.
type Mutable interface {
	// NewNode adds a node with an arbitrary ID and returns the new, unique ID
	// used.
	NewNode() Node

	// Adds a node to the graph. If this is called multiple times for the same ID, the newer node
	// overwrites the old one.
	AddNode(Node)

	// EmptyGraph clears the graph of all nodes and edges.
	EmptyGraph()

	// RemoveNode removes a node from the graph, as well as any edges
	// attached to it. If no such node exists, this is a no-op, not an error.
	RemoveNode(Node)
}

// MutableGraph is an interface ensuring the implementation of the ability to construct
// an arbitrary undirected graph. It is very important to note that any implementation
// of MutableGraph absolutely cannot safely implement the DirectedGraph interface.
//
// A MutableGraph is required to store any Edge argument in the same way Mutable must
// store a Node argument -- any retrieval call is required to return the exact supplied edge.
// This is what makes it incompatible with DirectedGraph.
//
// A call to AddEdgeBetween(Edge{head,tail}) make is so there is simply no way to safely
// return EdgeTo(tail, head) since the edge returned will, by this contract, need to be
// Head() == head and Tail() == tail when the reverse must be true to fulfill the
// functionality guaranteed of EdgeTo.
type MutableGraph interface {
	CostGraph
	Mutable

	// Like EdgeBetween in Graph, AddEdgeBetween adds an edge between two nodes.
	// If one or both nodes do not exist, the Graph is expected to add them.
	AddEdgeBetween(e Edge, cost float64)

	// RemoveEdge clears the stored edge between two nodes. Calling this will never
	// remove a node. If the edge does not exist this is a no-op, not an error.
	RemoveEdgeBetween(e Edge)
}

// MutableDirectedGraph is an interface that ensures one can construct an arbitrary directed
// graph. Naturally, a MutableDirectedGraph works for both undirected and directed cases,
// but simply using a MutableGraph may be cleaner. As the documentation for MutableGraph
// notes, however, a graph cannot safely implement MutableGraph and MutableDirectedGraph
// at the same time, because of the functionality of a EdgeTo in DirectedGraph.
type MutableDirectedGraph interface {
	CostDirectedGraph
	Mutable

	// Adds an edge FROM e.Head TO e.Tail. Newer calls overwrite older ones.
	// If the nodes Head or Tail do not exist in the graph, this must add them.
	AddEdgeTo(e Edge, cost float64)

	// Removes an edge FROM e.Head TO e.Tail. If no such edge exists, this is a no-op,
	// not an error.
	RemoveEdgeTo(e Edge)
}

// A function that returns the cost of following an edge
type CostFunc func(Edge) float64

// Estimates the cost of travelling between two nodes
type HeuristicCostFunc func(Node, Node) float64

// Determines if a MutableGraph implements DirectedGraph and panics if it does.
// This is a utility function to detect unsafe implementations. It's mostly for internal use,
// but is exported since it may be useful to people who use the package for their own tests.
func VetMutableGraph(g MutableGraph) {
	if _, ok := g.(DirectedGraph); ok {
		panic("A MutableGraph implements DirectedGraph; this is unsafe!")
	}
}
<|endoftext|>


<commit_before>package cmd

import (
	"os"
	"path/filepath"
	"strings"

	"github.com/mitchellh/go-homedir"
	"github.com/spf13/cobra"
	"github.com/stormcat24/protodep/helper"
	"github.com/stormcat24/protodep/logger"
	"github.com/stormcat24/protodep/service"
)

var (
	authProvider helper.AuthProvider
)

type protoResource struct {
	source       string
	relativeDest string
}

var upCmd = &cobra.Command{
	Use:   "up",
	Short: "Populate .proto vendors existing protodep.toml and lock",
	RunE: func(cmd *cobra.Command, args []string) error {

		isForceUpdate, err := cmd.Flags().GetBool("force")
		if err != nil {
			return err
		}
		logger.Info("force update = %t", isForceUpdate)

		isCleanupCache, err := cmd.Flags().GetBool("cleanup")
		if err != nil {
			return err
		}
		logger.Info("cleanup cache = %t", isCleanupCache)

		identityFile, err := cmd.Flags().GetString("identity-file")
		if err != nil {
			return err
		}
		logger.Info("identity file = %s", identityFile)

		password, err := cmd.Flags().GetString("password")
		if err != nil {
			return err
		}
		if password != "" {
			logger.Info("password = %s", strings.Repeat("x", len(password))) // Do not display the password.
		}

		pwd, err := os.Getwd()
		if err != nil {
			return err
		}

		homeDir, err := homedir.Dir()
		if err != nil {
			return err
		}

		identifyPath := filepath.Join(homeDir, ".ssh", identityFile)
		isSSH, err := helper.IsAvailableSSH(identifyPath)
		if err != nil {
			return err
		}
		if isSSH {
			authProvider = helper.NewAuthProvider(identifyPath, password)
		} else {
			authProvider = helper.NewAuthProvider("", "")
		}

		updateService := service.NewSync(authProvider, homeDir, pwd, pwd)
		return updateService.Resolve(isForceUpdate, isCleanupCache)
	},
}

func initDepCmd() {
	upCmd.PersistentFlags().BoolP("force", "f", false, "update locked file and .proto vendors")
	upCmd.PersistentFlags().StringP("identity-file", "i", "id_rsa", "set the identity file for SSH")
	upCmd.PersistentFlags().StringP("password", "p", "", "set the password for SSH")
	upCmd.PersistentFlags().BoolP("cleanup", "c", false, "cleanup cache before exec.")
}
<commit_msg>Add a CLI flag to get dependencies via HTTPS (#49)<commit_after>package cmd

import (
	"os"
	"path/filepath"
	"strings"

	"github.com/mitchellh/go-homedir"
	"github.com/spf13/cobra"
	"github.com/stormcat24/protodep/helper"
	"github.com/stormcat24/protodep/logger"
	"github.com/stormcat24/protodep/service"
)

var (
	authProvider helper.AuthProvider
)

type protoResource struct {
	source       string
	relativeDest string
}

var upCmd = &cobra.Command{
	Use:   "up",
	Short: "Populate .proto vendors existing protodep.toml and lock",
	RunE: func(cmd *cobra.Command, args []string) error {

		isForceUpdate, err := cmd.Flags().GetBool("force")
		if err != nil {
			return err
		}
		logger.Info("force update = %t", isForceUpdate)

		isCleanupCache, err := cmd.Flags().GetBool("cleanup")
		if err != nil {
			return err
		}
		logger.Info("cleanup cache = %t", isCleanupCache)

		identityFile, err := cmd.Flags().GetString("identity-file")
		if err != nil {
			return err
		}
		logger.Info("identity file = %s", identityFile)

		password, err := cmd.Flags().GetString("password")
		if err != nil {
			return err
		}
		if password != "" {
			logger.Info("password = %s", strings.Repeat("x", len(password))) // Do not display the password.
		}

		useHttps, err := cmd.Flags().GetBool("use-https")
		if err != nil {
			return err
		}
		logger.Info("use https = %t", useHttps)

		pwd, err := os.Getwd()
		if err != nil {
			return err
		}

		homeDir, err := homedir.Dir()
		if err != nil {
			return err
		}

		if useHttps {
			authProvider = helper.NewAuthProvider("", "")
		} else {
			identifyPath := filepath.Join(homeDir, ".ssh", identityFile)
			isSSH, err := helper.IsAvailableSSH(identifyPath)
			if err != nil {
				return err
			}
			if isSSH {
				authProvider = helper.NewAuthProvider(identifyPath, password)
			} else {
				authProvider = helper.NewAuthProvider("", "")
			}
		}

		updateService := service.NewSync(authProvider, homeDir, pwd, pwd)
		return updateService.Resolve(isForceUpdate, isCleanupCache)
	},
}

func initDepCmd() {
	upCmd.PersistentFlags().BoolP("force", "f", false, "update locked file and .proto vendors")
	upCmd.PersistentFlags().StringP("identity-file", "i", "id_rsa", "set the identity file for SSH")
	upCmd.PersistentFlags().StringP("password", "p", "", "set the password for SSH")
	upCmd.PersistentFlags().BoolP("cleanup", "c", false, "cleanup cache before exec.")
	upCmd.PersistentFlags().BoolP("use-https", "u", false, "use HTTPS to get dependencies.")
}
<|endoftext|>


<commit_before>package ase

import (
	"bytes"
	"encoding/binary"
	"io"
	"unicode/utf16"
)

type Group struct {
	nameLen uint16
	Name    string
	Colors  []Color
}

func (group *Group) read(r io.Reader) (err error) {
	if err = group.readNameLen(r); err != nil {
		return
	}

	return group.readName(r)
}

func (group *Group) readNameLen(r io.Reader) error {
	return binary.Read(r, binary.BigEndian, &group.nameLen)
}

func (group *Group) readName(r io.Reader) (err error) {
	//	make array for our color name based on block length
	name := make([]uint16, group.nameLen)
	if err = binary.Read(r, binary.BigEndian, &name); err != nil {
		return
	}

	//	decode our name. we trim off the last byte since it's zero terminated
	group.Name = string(utf16.Decode(name[:len(name)-1]))

	return
}

func (group *Group) write(w io.Writer) (err error) {

	// Write group start headers (block entry, block length,  nameLen, name)
	if err = group.writeBlockStart(w); err != nil {
		return
	}

	if err = group.writeBlockLength(w); err != nil {
		return
	}

	if err = group.writeNameLen(w); err != nil {
		return
	}
	if err = group.writeName(w); err != nil {
		return
	}

	// Write group's colors
	for _, color := range group.Colors {
		if err = color.write(w); err != nil {
			return err
		}
	}

	// Write the group's closing headers
	if err = group.writeBlockEnd(w); err != nil {
		return
	}

	return nil
}

// Wrapper around writing a group start header.
func (group *Group) writeBlockStart(w io.Writer) (err error) {
	return binary.Write(w, binary.BigEndian, groupStart)
}

// Wrapper around writing a group end header.
func (group *Group) writeBlockEnd(w io.Writer) (err error) {
	// First writes the groupEnd block followed by a terminating zero.
	binary.Write(w, binary.BigEndian, groupEnd)
	return binary.Write(w, binary.BigEndian, uint16(0x0000))
}

// Encode the color's name length.
func (group *Group) writeNameLen(w io.Writer) (err error) {
	// Adding one to the name length accounts for the zero-terminated character.
	return binary.Write(w, binary.BigEndian, group.NameLen()+1)
}

// Encode the group's name.
func (group *Group) writeName(w io.Writer) (err error) {
	name := utf16.Encode([]rune(group.Name))
	name = append(name, uint16(0))
	return binary.Write(w, binary.BigEndian, name)
}

// Helper function that returns the length of a group's name.
func (group *Group) NameLen() uint16 {
	return uint16(len(group.Name))
}

// Write color's block length as a part of the ASE encoding.
func (group *Group) writeBlockLength(w io.Writer) (err error) {
	blockLength := group.calculateBlockLength()
	if err = binary.Write(w, binary.BigEndian, blockLength); err != nil {
		return err
	}
	return
}

// Calculates the block length to be written based on the color's attributes.
func (group *Group) calculateBlockLength() int32 {
	buf := new(bytes.Buffer)
	group.writeNameLen(buf)
	group.writeName(buf)
	return int32(buf.Len())
}
<commit_msg>(encode) write two terminating zeros for group.writeBlockEnd()<commit_after>package ase

import (
	"bytes"
	"encoding/binary"
	"io"
	"unicode/utf16"
)

type Group struct {
	nameLen uint16
	Name    string
	Colors  []Color
}

func (group *Group) read(r io.Reader) (err error) {
	if err = group.readNameLen(r); err != nil {
		return
	}

	return group.readName(r)
}

func (group *Group) readNameLen(r io.Reader) error {
	return binary.Read(r, binary.BigEndian, &group.nameLen)
}

func (group *Group) readName(r io.Reader) (err error) {
	//	make array for our color name based on block length
	name := make([]uint16, group.nameLen)
	if err = binary.Read(r, binary.BigEndian, &name); err != nil {
		return
	}

	//	decode our name. we trim off the last byte since it's zero terminated
	group.Name = string(utf16.Decode(name[:len(name)-1]))

	return
}

func (group *Group) write(w io.Writer) (err error) {

	// Write group start headers (block entry, block length,  nameLen, name)
	if err = group.writeBlockStart(w); err != nil {
		return
	}

	if err = group.writeBlockLength(w); err != nil {
		return
	}

	if err = group.writeNameLen(w); err != nil {
		return
	}
	if err = group.writeName(w); err != nil {
		return
	}

	// Write group's colors
	for _, color := range group.Colors {
		if err = color.write(w); err != nil {
			return err
		}
	}

	// Write the group's closing headers
	if err = group.writeBlockEnd(w); err != nil {
		return
	}

	return nil
}

// Wrapper around writing a group start header.
func (group *Group) writeBlockStart(w io.Writer) (err error) {
	return binary.Write(w, binary.BigEndian, groupStart)
}

// Wrapper around writing a group end header.
func (group *Group) writeBlockEnd(w io.Writer) (err error) {
	// First writes the groupEnd block followed by two terminating zeroes.
	binary.Write(w, binary.BigEndian, groupEnd)
	binary.Write(w, binary.BigEndian, uint16(0x0000))
	return binary.Write(w, binary.BigEndian, uint16(0x0000))
}

// Encode the color's name length.
func (group *Group) writeNameLen(w io.Writer) (err error) {
	// Adding one to the name length accounts for the zero-terminated character.
	return binary.Write(w, binary.BigEndian, group.NameLen()+1)
}

// Encode the group's name.
func (group *Group) writeName(w io.Writer) (err error) {
	name := utf16.Encode([]rune(group.Name))
	name = append(name, uint16(0))
	return binary.Write(w, binary.BigEndian, name)
}

// Helper function that returns the length of a group's name.
func (group *Group) NameLen() uint16 {
	return uint16(len(group.Name))
}

// Write color's block length as a part of the ASE encoding.
func (group *Group) writeBlockLength(w io.Writer) (err error) {
	blockLength := group.calculateBlockLength()
	if err = binary.Write(w, binary.BigEndian, blockLength); err != nil {
		return err
	}
	return
}

// Calculates the block length to be written based on the color's attributes.
func (group *Group) calculateBlockLength() int32 {
	buf := new(bytes.Buffer)
	group.writeNameLen(buf)
	group.writeName(buf)
	return int32(buf.Len())
}
<|endoftext|>


<commit_before>package testhelpers

import(
	. "github.com/onsi/gomega"
	"bytes"
  "io"
	"os"
  "strings"
  "wall_street"
)

func SimulatePipes(reader *wall_street.ReadlineReader, input string, block func()) []string {
	in, out, err := os.Pipe()
	Expect(err).NotTo(HaveOccurred())
	reader.SetReadPipe(in)

	go func() {
		defer out.Close()
		out.Write([]byte(input))
	}()

	return CaptureSTDOUT(reader, func() { block() })
}

func CaptureSTDOUT(reader *wall_street.ReadlineReader, block func()) []string {
	in, out, err := os.Pipe()
	Expect(err).ToNot(HaveOccurred())

	reader.SetWritePipe(out)

	block()
	out.Close()

	var buf bytes.Buffer
	io.Copy(&buf, in)
	if len(buf.String()) == 0 {
		return []string{}
	}

	return strings.Split(buf.String(), "\n")
}
<commit_msg>Add convenient newline to test helpers<commit_after>package testhelpers

import(
	. "github.com/onsi/gomega"
	"bytes"
  "io"
	"os"
  "strings"
  "wall_street"
)

func SimulatePipes(reader *wall_street.ReadlineReader, input string, block func()) []string {
	in, out, err := os.Pipe()
	Expect(err).NotTo(HaveOccurred())
	reader.SetReadPipe(in)

	go func() {
		defer out.Close()
		out.Write([]byte(input + "\n"))
	}()

	return CaptureSTDOUT(reader, func() { block() })
}

func CaptureSTDOUT(reader *wall_street.ReadlineReader, block func()) []string {
	in, out, err := os.Pipe()
	Expect(err).ToNot(HaveOccurred())

	reader.SetWritePipe(out)

	block()
	out.Close()

	var buf bytes.Buffer
	io.Copy(&buf, in)
	if len(buf.String()) == 0 {
		return []string{}
	}

	return strings.Split(buf.String(), "\n")
}
<|endoftext|>


<commit_before>// package declared as executable, not lib
package main

// an import
import "fmt"

// entry point
func main() {
	// call Printf function from fmt package
	fmt.Printf("hello, world\n")

	// call another function
	beyondHello()

}

func beyondHello(){
	// variable should be declared before being used
	var x int
	// assignation
	x = 3

	// type inference, declaration, assignation
	y := 4

	// a function returning 2 values
	sum, prod := learnMultiple(x, y)
	fmt.Println("sum:", sum, "prod:", prod)

	// another function call
	learnTypes()
}

// arguments x, y of type integers
// this function returns 2 integers, sum & prod
func learnMultiple(x, y int) (sum, prod int) {
	// two values returned
	return x+y, x*y

}

func learnTypes(){
	// string inference
	str := "Learn go"
	s2 := `string with
newline`
	// go source code use utf8 charset
	// rune type, for unicode char
	g := 'Σ'

	// float
	f := 3.14195
	// complex128 type, considered as float64 by compiler
	c := 3 + 4i
	// u declared as unsigned int
	var u uint = 7
	var pi float32 = 22. / 7

	// byte is an alias for uint8
	n := byte('\n')

	// array are size fixed
	var a4 [4]int // array size 4, int items 0, 0, 0, 0
	a3 := [...]int{3, 1, 5} // array size 3, int items 3, 1, 5

	// slices are size not fixed
	s3 := []int{4, 5, 9} // 3 ints slice
	s4 := make([]int, 4) // 4 ints slice initialized with zeros
	var d2 [][]float64
	bs := []byte("a slice")

	// add values to slice
	s3 = append(s3, 4, 5, 6)
	s3 = append(s3, []int{7,8,9}...)
	fmt.Println(s3)

	// declared & not used variables are errors
	// to ignore those unused values
	_, _, _, _, _, _, _, _, _, _, _, _, _ = str, s2, g, f, c, u, pi, n, a3, a4, bs, d2, s4
}
<commit_msg>golang, control flow (1)<commit_after>// package declared as executable, not lib
package main

// an import
import "fmt"

// entry point
func main() {
	// call Printf function from fmt package
	fmt.Printf("hello, world\n")

	// call another function
	beyondHello()

}

func beyondHello() {
	// variable should be declared before being used
	var x int
	// assignation
	x = 3

	// type inference, declaration, assignation
	y := 4

	// a function returning 2 values
	sum, prod := learnMultiple(x, y)
	fmt.Println("sum:", sum, "prod:", prod)

	// another function call
	learnTypes()
}

// arguments x, y of type integers
// this function returns 2 integers, sum & prod
func learnMultiple(x, y int) (sum, prod int) {
	// two values returned
	return x + y, x * y

}

func learnTypes() {
	// string inference
	str := "Learn go"
	s2 := `string with
newline`
	// go source code use utf8 charset
	// rune type, for unicode char
	g := 'Σ'

	// float
	f := 3.14195
	// complex128 type, considered as float64 by compiler
	c := 3 + 4i
	// u declared as unsigned int
	var u uint = 7
	var pi float32 = 22. / 7

	// byte is an alias for uint8
	n := byte('\n')

	// array are size fixed
	var a4 [4]int           // array size 4, int items 0, 0, 0, 0
	a3 := [...]int{3, 1, 5} // array size 3, int items 3, 1, 5

	// slices are size not fixed
	s3 := []int{4, 5, 9} // 3 ints slice
	s4 := make([]int, 4) // 4 ints slice initialized with zeros
	var d2 [][]float64
	bs := []byte("a slice")

	// add values to slice
	s3 = append(s3, 4, 5, 6)
	s3 = append(s3, []int{7, 8, 9}...)
	fmt.Println(s3)

	// maps are like python dictionaries
	m := map[string]int{"score": 5}
	m["distance"] = 5
	fmt.Println(m)

	// declared & not used variables are errors
	// to ignore those unused values
	_, _, _, _, _, _, _, _, _, _, _, _, _ = str, s2, g, f, c, u, pi, n, a3, a4, bs, d2, s4
	learnFlowControl()
}

func learnFlowControl() {
	if true {
		fmt.Println("bim")
	}
	if false {
		// if
	}else{
		// else
	}
	// switch case
	x := 42.0
	switch x {
	case 0:
	case 1:
		fmt.Println("0 or 1")
	case 42:
		fmt.Println("42")
	case 43:
		fmt.Println("43")
	}

	// for loop
	for x:=0; x<3; x++ {
		fmt.Println("i: ", x)
	}

	// k,v will go through the different k,v pairs of the map
	for k, v := range map[string]int{"une":1, "deux":2, "trois":3}{
		fmt.Printf("key=%s, value=%d\n", k, v)
	}

	//
}
<|endoftext|>


<commit_before>package main

import "fmt"

 func main() {
   fmt.Println("Hello")
fmt.Println("bye forever")
fmt.Println("Whoops, I'm back!")

	fmt.Println("Hello")
	fmt.Println("Is it me you're looking for?")
	fmt.Println("bye forever")
}
<commit_msg>Please?<commit_after>package main

import "fmt"

 func main() {
   fmt.Println("Hello")
fmt.Println("bye forever")
fmt.Println("Whoops, I'm back!")

	fmt.Println("Hello")
	fmt.Println("Is it me you're looking for?")
	fmt.Println("bye forever")
	fmt.Println("Forever and ever")
}
<|endoftext|>


<commit_before>// 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 privileges

import (
	"fmt"
	"strings"

	"github.com/juju/errors"
	"github.com/pingcap/tidb/context"
	"github.com/pingcap/tidb/model"
	"github.com/pingcap/tidb/mysql"
	"github.com/pingcap/tidb/privilege"
	"github.com/pingcap/tidb/sessionctx/variable"
	"github.com/pingcap/tidb/util/sqlexec"
)

var _ privilege.Checker = (*UserPrivileges)(nil)

type privileges struct {
	privs map[mysql.PrivilegeType]bool
}

func (ps *privileges) contain(p mysql.PrivilegeType) bool {
	if ps.privs == nil {
		return false
	}
	_, ok := ps.privs[p]
	return ok
}

func (ps *privileges) add(p mysql.PrivilegeType) {
	if ps.privs == nil {
		ps.privs = make(map[mysql.PrivilegeType]bool)
	}
	ps.privs[p] = true
}

type userPrivileges struct {
	// Global privileges
	GlobalPrivs *privileges
	// DBName-privileges
	DBPrivs map[string]*privileges
	// DBName-TableName-privileges
	TablePrivs map[string]map[string]*privileges
}

// UserPrivileges implements privilege.Checker interface.
// This is used to check privilege for the current user.
type UserPrivileges struct {
	username string
	host     string
	privs    *userPrivileges
}

// Check implements Checker.Check interface.
func (p *UserPrivileges) Check(ctx context.Context, db *model.DBInfo, tbl *model.TableInfo, privilege mysql.PrivilegeType) (bool, error) {
	if p.privs == nil {
		// Lazy load
		err := p.loadPrivileges(ctx)
		if err != nil {
			return false, errors.Trace(err)
		}
	}
	// Check global scope privileges.
	ok := p.privs.GlobalPrivs.contain(privilege)
	if ok {
		return true, nil
	}
	// Check db scope privileges.
	dbp, ok := p.privs.DBPrivs[db.Name.O]
	if ok {
		ok = dbp.contain(privilege)
		if ok {
			return true, nil
		}
	}
	if tbl == nil {
		return false, nil
	}
	// Check table scope privileges.
	dbTbl, ok := p.privs.TablePrivs[db.Name.O]
	if !ok {
		return false, nil
	}
	tblp, ok := dbTbl[tbl.Name.O]
	if !ok {
		return false, nil
	}
	return tblp.contain(privilege), nil
}

func (p *UserPrivileges) loadPrivileges(ctx context.Context) error {
	user := variable.GetSessionVars(ctx).User
	strs := strings.Split(user, "@")
	p.username, p.host = strs[0], strs[1]
	p.privs = &userPrivileges{}
	// Load privileges from mysql.User/DB/Table_privs/Column_privs table
	err := p.loadGlobalPrivileges(ctx)
	if err != nil {
		return errors.Trace(err)
	}
	err = p.loadDBScopePrivileges(ctx)
	if err != nil {
		return errors.Trace(err)
	}
	err = p.loadTableScopePrivileges(ctx)
	if err != nil {
		return errors.Trace(err)
	}
	// TODO: consider column scope privilege latter.
	return nil
}

// mysql.User/mysql.DB table privilege columns start from index 3.
// See: booststrap.go CreateUserTable/CreateDBPrivTable
const userTablePrivColumnStartIndex = 3
const dbTablePrivColumnStartIndex = 3

func (p *UserPrivileges) loadGlobalPrivileges(ctx context.Context) error {
	sql := fmt.Sprintf(`SELECT * FROM %s.%s WHERE User="%s" AND (Host="%s" OR Host="%%");`, mysql.SystemDB, mysql.UserTable, p.username, p.host)
	rs, err := ctx.(sqlexec.RestrictedSQLExecutor).ExecRestrictedSQL(ctx, sql)
	if err != nil {
		return errors.Trace(err)
	}
	defer rs.Close()
	ps := &privileges{}
	fs, err := rs.Fields()
	if err != nil {
		return errors.Trace(err)
	}
	for {
		row, err := rs.Next()
		if err != nil {
			return errors.Trace(err)
		}
		if row == nil {
			break
		}
		for i := userTablePrivColumnStartIndex; i < len(fs); i++ {
			d := row.Data[i]
			ed, ok := d.(mysql.Enum)
			if !ok {
				return errors.Errorf("Privilege should be mysql.Enum: %v(%T)", d, d)
			}
			if ed.String() != "Y" {
				continue
			}
			f := fs[i]
			p, ok := mysql.Col2PrivType[f.Name]
			if !ok {
				panic("Unknown Privilege Type!")
			}
			ps.add(p)
		}
	}
	p.privs.GlobalPrivs = ps
	return nil
}

func (p *UserPrivileges) loadDBScopePrivileges(ctx context.Context) error {
	sql := fmt.Sprintf(`SELECT * FROM %s.%s WHERE User="%s" AND (Host="%s" OR Host="%%");`, mysql.SystemDB, mysql.DBTable, p.username, p.host)
	rs, err := ctx.(sqlexec.RestrictedSQLExecutor).ExecRestrictedSQL(ctx, sql)
	if err != nil {
		return errors.Trace(err)
	}
	defer rs.Close()
	ps := make(map[string]*privileges)
	fs, err := rs.Fields()
	if err != nil {
		return errors.Trace(err)
	}
	for {
		row, err := rs.Next()
		if err != nil {
			return errors.Trace(err)
		}
		if row == nil {
			break
		}
		// DB
		db, ok := row.Data[1].(string)
		if !ok {
			panic("This should be never happened!")
		}
		ps[db] = &privileges{}
		for i := dbTablePrivColumnStartIndex; i < len(fs); i++ {
			d := row.Data[i]
			ed, ok := d.(mysql.Enum)
			if !ok {
				return errors.Errorf("Privilege should be mysql.Enum: %v(%T)", d, d)
			}
			if ed.String() != "Y" {
				continue
			}
			f := fs[i]
			p, ok := mysql.Col2PrivType[f.Name]
			if !ok {
				panic("Unknown Privilege Type!")
			}
			ps[db].add(p)
		}
	}
	p.privs.DBPrivs = ps
	return nil
}

func (p *UserPrivileges) loadTableScopePrivileges(ctx context.Context) error {
	sql := fmt.Sprintf(`SELECT * FROM %s.%s WHERE User="%s" AND (Host="%s" OR Host="%%");`, mysql.SystemDB, mysql.TablePrivTable, p.username, p.host)
	rs, err := ctx.(sqlexec.RestrictedSQLExecutor).ExecRestrictedSQL(ctx, sql)
	if err != nil {
		return errors.Trace(err)
	}
	defer rs.Close()
	ps := make(map[string]map[string]*privileges)
	for {
		row, err := rs.Next()
		if err != nil {
			return errors.Trace(err)
		}
		if row == nil {
			break
		}
		// DB
		db, ok := row.Data[1].(string)
		if !ok {
			panic("This should be never happened!")
		}
		// Table_name
		tbl, ok := row.Data[3].(string)
		if !ok {
			panic("This should be never happened!")
		}
		_, ok = ps[db]
		if !ok {
			ps[db] = make(map[string]*privileges)
		}
		ps[db][tbl] = &privileges{}
		// Table_priv
		tblPrivs, ok := row.Data[6].(mysql.Set)
		if !ok {
			panic("This should be never happened!")
		}
		pvs := strings.Split(tblPrivs.Name, ",")
		for _, d := range pvs {
			p, ok := mysql.SetStr2Priv[d]
			if !ok {
				panic("Unknown Privilege Type!")
			}
			ps[db][tbl].add(p)
		}
	}
	p.privs.TablePrivs = ps
	return nil
}
<commit_msg>privileges: Replace panic with error.<commit_after>// 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 privileges

import (
	"fmt"
	"strings"

	"github.com/juju/errors"
	"github.com/pingcap/tidb/context"
	"github.com/pingcap/tidb/model"
	"github.com/pingcap/tidb/mysql"
	"github.com/pingcap/tidb/privilege"
	"github.com/pingcap/tidb/sessionctx/variable"
	"github.com/pingcap/tidb/util/sqlexec"
)

var _ privilege.Checker = (*UserPrivileges)(nil)

type privileges struct {
	privs map[mysql.PrivilegeType]bool
}

func (ps *privileges) contain(p mysql.PrivilegeType) bool {
	if ps.privs == nil {
		return false
	}
	_, ok := ps.privs[p]
	return ok
}

func (ps *privileges) add(p mysql.PrivilegeType) {
	if ps.privs == nil {
		ps.privs = make(map[mysql.PrivilegeType]bool)
	}
	ps.privs[p] = true
}

type userPrivileges struct {
	// Global privileges
	GlobalPrivs *privileges
	// DBName-privileges
	DBPrivs map[string]*privileges
	// DBName-TableName-privileges
	TablePrivs map[string]map[string]*privileges
}

// UserPrivileges implements privilege.Checker interface.
// This is used to check privilege for the current user.
type UserPrivileges struct {
	username string
	host     string
	privs    *userPrivileges
}

// Check implements Checker.Check interface.
func (p *UserPrivileges) Check(ctx context.Context, db *model.DBInfo, tbl *model.TableInfo, privilege mysql.PrivilegeType) (bool, error) {
	if p.privs == nil {
		// Lazy load
		err := p.loadPrivileges(ctx)
		if err != nil {
			return false, errors.Trace(err)
		}
	}
	// Check global scope privileges.
	ok := p.privs.GlobalPrivs.contain(privilege)
	if ok {
		return true, nil
	}
	// Check db scope privileges.
	dbp, ok := p.privs.DBPrivs[db.Name.O]
	if ok {
		ok = dbp.contain(privilege)
		if ok {
			return true, nil
		}
	}
	if tbl == nil {
		return false, nil
	}
	// Check table scope privileges.
	dbTbl, ok := p.privs.TablePrivs[db.Name.O]
	if !ok {
		return false, nil
	}
	tblp, ok := dbTbl[tbl.Name.O]
	if !ok {
		return false, nil
	}
	return tblp.contain(privilege), nil
}

func (p *UserPrivileges) loadPrivileges(ctx context.Context) error {
	user := variable.GetSessionVars(ctx).User
	strs := strings.Split(user, "@")
	p.username, p.host = strs[0], strs[1]
	p.privs = &userPrivileges{}
	// Load privileges from mysql.User/DB/Table_privs/Column_privs table
	err := p.loadGlobalPrivileges(ctx)
	if err != nil {
		return errors.Trace(err)
	}
	err = p.loadDBScopePrivileges(ctx)
	if err != nil {
		return errors.Trace(err)
	}
	err = p.loadTableScopePrivileges(ctx)
	if err != nil {
		return errors.Trace(err)
	}
	// TODO: consider column scope privilege latter.
	return nil
}

// mysql.User/mysql.DB table privilege columns start from index 3.
// See: booststrap.go CreateUserTable/CreateDBPrivTable
const userTablePrivColumnStartIndex = 3
const dbTablePrivColumnStartIndex = 3

func (p *UserPrivileges) loadGlobalPrivileges(ctx context.Context) error {
	sql := fmt.Sprintf(`SELECT * FROM %s.%s WHERE User="%s" AND (Host="%s" OR Host="%%");`, mysql.SystemDB, mysql.UserTable, p.username, p.host)
	rs, err := ctx.(sqlexec.RestrictedSQLExecutor).ExecRestrictedSQL(ctx, sql)
	if err != nil {
		return errors.Trace(err)
	}
	defer rs.Close()
	ps := &privileges{}
	fs, err := rs.Fields()
	if err != nil {
		return errors.Trace(err)
	}
	for {
		row, err := rs.Next()
		if err != nil {
			return errors.Trace(err)
		}
		if row == nil {
			break
		}
		for i := userTablePrivColumnStartIndex; i < len(fs); i++ {
			d := row.Data[i]
			ed, ok := d.(mysql.Enum)
			if !ok {
				return errors.Errorf("Privilege should be mysql.Enum: %v(%T)", d, d)
			}
			if ed.String() != "Y" {
				continue
			}
			f := fs[i]
			p, ok := mysql.Col2PrivType[f.Name]
			if !ok {
				return errors.Errorf("Unknown Privilege Type!")
			}
			ps.add(p)
		}
	}
	p.privs.GlobalPrivs = ps
	return nil
}

func (p *UserPrivileges) loadDBScopePrivileges(ctx context.Context) error {
	sql := fmt.Sprintf(`SELECT * FROM %s.%s WHERE User="%s" AND (Host="%s" OR Host="%%");`, mysql.SystemDB, mysql.DBTable, p.username, p.host)
	rs, err := ctx.(sqlexec.RestrictedSQLExecutor).ExecRestrictedSQL(ctx, sql)
	if err != nil {
		return errors.Trace(err)
	}
	defer rs.Close()
	ps := make(map[string]*privileges)
	fs, err := rs.Fields()
	if err != nil {
		return errors.Trace(err)
	}
	for {
		row, err := rs.Next()
		if err != nil {
			return errors.Trace(err)
		}
		if row == nil {
			break
		}
		// DB
		db, ok := row.Data[1].(string)
		if !ok {
			errors.Errorf("This should be never happened!")
		}
		ps[db] = &privileges{}
		for i := dbTablePrivColumnStartIndex; i < len(fs); i++ {
			d := row.Data[i]
			ed, ok := d.(mysql.Enum)
			if !ok {
				return errors.Errorf("Privilege should be mysql.Enum: %v(%T)", d, d)
			}
			if ed.String() != "Y" {
				continue
			}
			f := fs[i]
			p, ok := mysql.Col2PrivType[f.Name]
			if !ok {
				return errors.Errorf("Unknown Privilege Type!")
			}
			ps[db].add(p)
		}
	}
	p.privs.DBPrivs = ps
	return nil
}

func (p *UserPrivileges) loadTableScopePrivileges(ctx context.Context) error {
	sql := fmt.Sprintf(`SELECT * FROM %s.%s WHERE User="%s" AND (Host="%s" OR Host="%%");`, mysql.SystemDB, mysql.TablePrivTable, p.username, p.host)
	rs, err := ctx.(sqlexec.RestrictedSQLExecutor).ExecRestrictedSQL(ctx, sql)
	if err != nil {
		return errors.Trace(err)
	}
	defer rs.Close()
	ps := make(map[string]map[string]*privileges)
	for {
		row, err := rs.Next()
		if err != nil {
			return errors.Trace(err)
		}
		if row == nil {
			break
		}
		// DB
		db, ok := row.Data[1].(string)
		if !ok {
			return errors.Errorf("This should be never happened!")
		}
		// Table_name
		tbl, ok := row.Data[3].(string)
		if !ok {
			return errors.Errorf("This should be never happened!")
		}
		_, ok = ps[db]
		if !ok {
			ps[db] = make(map[string]*privileges)
		}
		ps[db][tbl] = &privileges{}
		// Table_priv
		tblPrivs, ok := row.Data[6].(mysql.Set)
		if !ok {
			errors.Errorf("This should be never happened!")
		}
		pvs := strings.Split(tblPrivs.Name, ",")
		for _, d := range pvs {
			p, ok := mysql.SetStr2Priv[d]
			if !ok {
				return errors.Errorf("Unknown Privilege Type!")
			}
			ps[db][tbl].add(p)
		}
	}
	p.privs.TablePrivs = ps
	return nil
}
<|endoftext|>


<commit_before>// Copyright (C) 2017 Space Monkey, 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,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package httpsig

import (
	"crypto/rand"
	"crypto/rsa"
	"fmt"
	"io"
	"net/http"
	"strings"
	"time"
)

var (
	// Rand is a hookable reader used as a random byte source.
	Rand io.Reader = rand.Reader
)

// requestPath returns the :path pseudo header according to the HTTP/2 spec.
func requestPath(req *http.Request) string {
	path := req.URL.Path
	if path == "" {
		path = "/"
	}
	if req.URL.RawQuery != "" {
		path += "?" + req.URL.RawQuery
	}
	return path
}

// BuildSignatureString constructs a signature string following section 2.3
func BuildSignatureString(req *http.Request, headers []string) string {
	if len(headers) == 0 {
		headers = []string{"date"}
	}
	values := make([]string, 0, len(headers))
	for _, h := range headers {
		switch h {
		case "(request-target)":
			values = append(values, fmt.Sprintf("%s: %s %s",
				h, strings.ToLower(req.Method), requestPath(req)))
		case "host":
			values = append(values, fmt.Sprintf("%s: %s", h, req.Host))
		case "date":
			if req.Header.Get(h) == "" {
				req.Header.Set(h, time.Now().Format(time.RFC1123))
			}
			values = append(values, fmt.Sprintf("%s: %s", h, req.Header.Get(h)))
		default:
			for _, value := range req.Header[http.CanonicalHeaderKey(h)] {
				values = append(values,
					fmt.Sprintf("%s: %s", h, strings.TrimSpace(value)))
			}
		}
	}
	return strings.Join(values, "\n")
}

// BuildSignatureData is a convenience wrapper around BuildSignatureString that
// returns []byte instead of a string.
func BuildSignatureData(req *http.Request, headers []string) []byte {
	return []byte(BuildSignatureString(req, headers))
}

func toRSAPrivateKey(key interface{}) *rsa.PrivateKey {
	switch k := key.(type) {
	case *rsa.PrivateKey:
		return k
	default:
		return nil
	}
}

func toRSAPublicKey(key interface{}) *rsa.PublicKey {
	switch k := key.(type) {
	case *rsa.PublicKey:
		return k
	case *rsa.PrivateKey:
		return &k.PublicKey
	default:
		return nil
	}
}

func toHMACKey(key interface{}) []byte {
	switch k := key.(type) {
	case []byte:
		return k
	default:
		return nil
	}
}

func unsupportedAlgorithm(a Algorithm) error {
	return fmt.Errorf("key does not support algorithm %q", a.Name())
}
<commit_msg>Fix date format and timezone<commit_after>// Copyright (C) 2017 Space Monkey, 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,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package httpsig

import (
	"crypto/rand"
	"crypto/rsa"
	"fmt"
	"io"
	"net/http"
	"strings"
	"time"
)

var (
	// Rand is a hookable reader used as a random byte source.
	Rand io.Reader = rand.Reader
)

// requestPath returns the :path pseudo header according to the HTTP/2 spec.
func requestPath(req *http.Request) string {
	path := req.URL.Path
	if path == "" {
		path = "/"
	}
	if req.URL.RawQuery != "" {
		path += "?" + req.URL.RawQuery
	}
	return path
}

// BuildSignatureString constructs a signature string following section 2.3
func BuildSignatureString(req *http.Request, headers []string) string {
	if len(headers) == 0 {
		headers = []string{"date"}
	}
	values := make([]string, 0, len(headers))
	for _, h := range headers {
		switch h {
		case "(request-target)":
			values = append(values, fmt.Sprintf("%s: %s %s",
				h, strings.ToLower(req.Method), requestPath(req)))
		case "host":
			values = append(values, fmt.Sprintf("%s: %s", h, req.Host))
		case "date":
			if req.Header.Get(h) == "" {
				req.Header.Set(h, time.Now().UTC().Format(http.TimeFormat))
			}
			values = append(values, fmt.Sprintf("%s: %s", h, req.Header.Get(h)))
		default:
			for _, value := range req.Header[http.CanonicalHeaderKey(h)] {
				values = append(values,
					fmt.Sprintf("%s: %s", h, strings.TrimSpace(value)))
			}
		}
	}
	return strings.Join(values, "\n")
}

// BuildSignatureData is a convenience wrapper around BuildSignatureString that
// returns []byte instead of a string.
func BuildSignatureData(req *http.Request, headers []string) []byte {
	return []byte(BuildSignatureString(req, headers))
}

func toRSAPrivateKey(key interface{}) *rsa.PrivateKey {
	switch k := key.(type) {
	case *rsa.PrivateKey:
		return k
	default:
		return nil
	}
}

func toRSAPublicKey(key interface{}) *rsa.PublicKey {
	switch k := key.(type) {
	case *rsa.PublicKey:
		return k
	case *rsa.PrivateKey:
		return &k.PublicKey
	default:
		return nil
	}
}

func toHMACKey(key interface{}) []byte {
	switch k := key.(type) {
	case []byte:
		return k
	default:
		return nil
	}
}

func unsupportedAlgorithm(a Algorithm) error {
	return fmt.Errorf("key does not support algorithm %q", a.Name())
}
<|endoftext|>