<commit_before>package ik

import (
	"regexp"
)

type fluentRouterRule struct {
	re   *regexp.Regexp
	port Port
}

type FluentRouter struct {
	rules []*fluentRouterRule
}

type PatternError struct {
	message string
}

func (self *PatternError) Error() string {
	return self.message
}

func buildRegexpFromGlobPatternInner(pattern string, startPos int) (string, int, error) {
	state := 0
	chunk := ""

	patternLength := len(pattern)
	var i int
	for i = startPos; i < patternLength; i += 1 {
		if state == 0 {
			c := pattern[i]
			if c == '*' {
				state = 2
			} else if c == '}' || c == ',' {
				break
			} else if c == '{' {
				chunk += "(?:"
				first := true
				for {
					i += 1
					subchunk, lastPos, err := buildRegexpFromGlobPatternInner(pattern, i)
					if err != nil {
						return "", 0, err
					}
					if lastPos == patternLength {
						return "", 0, &PatternError{"unexpected end of pattern (in expectation of '}' or ',')"}
					}
					if !first {
						chunk += "|"
					}
					i = lastPos
					chunk += "(?:" + subchunk + ")"
					first = false
					if pattern[lastPos] == '}' {
						break
					} else if pattern[lastPos] != ',' {
						return "", 0, &PatternError{"never get here"}
					}
				}
				chunk += ")"
			} else {
				chunk += regexp.QuoteMeta(string(c))
			}
		} else if state == 1 {
			// escape
			c := pattern[i]
			chunk += regexp.QuoteMeta(string(c))
			state = 0
		} else if state == 2 {
			c := pattern[i]
			if c == '*' {
				state = 3
			} else {
				chunk += "[^.]*" + regexp.QuoteMeta(string(c))
				state = 0
			}
		} else if state == 3 {
			// recursive any
			c := pattern[i]
			if c == '*' {
				return "", 0, &PatternError{"unexpected *"}
			} else if c == '.' {
				chunk += "(?:.*\\.|^)"
			} else {
				chunk += ".*" + regexp.QuoteMeta(string(c))
			}
			state = 0
		}
	}
	if state == 2 {
		chunk += "[^.]*"
	} else if state == 3 {
		chunk += ".*"
	}
	return chunk, i, nil
}

func BuildRegexpFromGlobPattern(pattern string) (string, error) {
	chunk, pos, err := buildRegexpFromGlobPatternInner(pattern, 0)
	if err != nil {
		return "", err
	}
	if pos != len(pattern) {
		return "", &PatternError{"unexpected '" + string(pattern[pos]) + "'"}
	}
	return "^" + chunk + "$", nil
}

func (router *FluentRouter) AddRule(pattern string, port Port) error {
	chunk, err := BuildRegexpFromGlobPattern(pattern)
	if err != nil {
		return err
	}
	re, err := regexp.Compile(chunk)
	if err != nil {
		return err
	}
	newRule := &fluentRouterRule{re, port}
	router.rules = append(router.rules, newRule)
	return nil
}

func (router *FluentRouter) Emit(records []FluentRecord) error {
	recordMap := make(map[Port][]FluentRecord)
	for _, record := range records {
		for _, rule := range router.rules {
			if rule.re.MatchString(record.Tag) {
				recordsForPort, ok := recordMap[rule.port]
				if !ok {
					recordsForPort = make([]FluentRecord, 0)
				}
				recordMap[rule.port] = append(recordsForPort, record)
			}
		}
	}
	for port, records := range recordMap {
		err := port.Emit(records)
		if err != nil {
			return err
		}
	}
	return nil
}

func NewFluentRouter() *FluentRouter {
	return &FluentRouter{make([]*fluentRouterRule, 0)}
}
<commit_msg>Do not emit the same records to the same port more than once<commit_after>package ik

import (
	"regexp"
)

type fluentRouterRule struct {
	re   *regexp.Regexp
	port Port
}

type FluentRouter struct {
	rules []*fluentRouterRule
}

type PatternError struct {
	message string
}

func (self *PatternError) Error() string {
	return self.message
}

func buildRegexpFromGlobPatternInner(pattern string, startPos int) (string, int, error) {
	state := 0
	chunk := ""

	patternLength := len(pattern)
	var i int
	for i = startPos; i < patternLength; i += 1 {
		if state == 0 {
			c := pattern[i]
			if c == '*' {
				state = 2
			} else if c == '}' || c == ',' {
				break
			} else if c == '{' {
				chunk += "(?:"
				first := true
				for {
					i += 1
					subchunk, lastPos, err := buildRegexpFromGlobPatternInner(pattern, i)
					if err != nil {
						return "", 0, err
					}
					if lastPos == patternLength {
						return "", 0, &PatternError{"unexpected end of pattern (in expectation of '}' or ',')"}
					}
					if !first {
						chunk += "|"
					}
					i = lastPos
					chunk += "(?:" + subchunk + ")"
					first = false
					if pattern[lastPos] == '}' {
						break
					} else if pattern[lastPos] != ',' {
						return "", 0, &PatternError{"never get here"}
					}
				}
				chunk += ")"
			} else {
				chunk += regexp.QuoteMeta(string(c))
			}
		} else if state == 1 {
			// escape
			c := pattern[i]
			chunk += regexp.QuoteMeta(string(c))
			state = 0
		} else if state == 2 {
			c := pattern[i]
			if c == '*' {
				state = 3
			} else {
				chunk += "[^.]*" + regexp.QuoteMeta(string(c))
				state = 0
			}
		} else if state == 3 {
			// recursive any
			c := pattern[i]
			if c == '*' {
				return "", 0, &PatternError{"unexpected *"}
			} else if c == '.' {
				chunk += "(?:.*\\.|^)"
			} else {
				chunk += ".*" + regexp.QuoteMeta(string(c))
			}
			state = 0
		}
	}
	if state == 2 {
		chunk += "[^.]*"
	} else if state == 3 {
		chunk += ".*"
	}
	return chunk, i, nil
}

func BuildRegexpFromGlobPattern(pattern string) (string, error) {
	chunk, pos, err := buildRegexpFromGlobPatternInner(pattern, 0)
	if err != nil {
		return "", err
	}
	if pos != len(pattern) {
		return "", &PatternError{"unexpected '" + string(pattern[pos]) + "'"}
	}
	return "^" + chunk + "$", nil
}

func (router *FluentRouter) AddRule(pattern string, port Port) error {
	chunk, err := BuildRegexpFromGlobPattern(pattern)
	if err != nil {
		return err
	}
	re, err := regexp.Compile(chunk)
	if err != nil {
		return err
	}
	newRule := &fluentRouterRule{re, port}
	router.rules = append(router.rules, newRule)
	return nil
}

func (router *FluentRouter) Emit(records []FluentRecord) error {
	recordMap := make(map[Port][]FluentRecord)
	numRecords := len(records)
	for i := 0; i < numRecords; i += 1 {
		record := &records[i]
		for _, rule := range router.rules {
			if rule.re.MatchString(record.Tag) {
				recordsForPort, ok := recordMap[rule.port]
				if !ok {
					recordsForPort = make([]FluentRecord, 0)
				} else {
					lastRecord := &recordsForPort[len(recordsForPort) - 1]
					if &lastRecord.Data == &record.Data {
						continue
					}
				}
				recordMap[rule.port] = append(recordsForPort, *record)
			}
		}
	}
	for port, records := range recordMap {
		err := port.Emit(records)
		if err != nil {
			return err
		}
	}
	return nil
}

func NewFluentRouter() *FluentRouter {
	return &FluentRouter{make([]*fluentRouterRule, 0)}
}
<|endoftext|>


<commit_before>package bridge

import (
	"errors"
	"flag"
	"fmt"
	log "github.com/Sirupsen/logrus"
	"net/http"
	"os"
	"time"

	"github.com/facebookgo/inject"
	"github.com/stellar/gateway/bridge/config"
	"github.com/stellar/gateway/bridge/handlers"
	"github.com/stellar/gateway/db"
	"github.com/stellar/gateway/db/drivers/mysql"
	"github.com/stellar/gateway/db/drivers/postgres"
	"github.com/stellar/gateway/horizon"
	"github.com/stellar/gateway/listener"
	"github.com/stellar/gateway/protocols/federation"
	"github.com/stellar/gateway/protocols/stellartoml"
	"github.com/stellar/gateway/server"
	"github.com/stellar/gateway/submitter"
	"github.com/zenazn/goji"
	"github.com/zenazn/goji/web/middleware"
)

// App is the application object
type App struct {
	config         config.Config
	requestHandler handlers.RequestHandler
}

// NewApp constructs an new App instance from the provided config.
func NewApp(config config.Config, migrateFlag bool) (app *App, err error) {
	var g inject.Graph

	var driver db.Driver
	switch config.Database.Type {
	case "mysql":
		driver = &mysql.Driver{}
	case "postgres":
		driver = &postgres.Driver{}
	case "":
		// Allow to start gateway server with a single endpoint: /payment
		break
	default:
		return nil, fmt.Errorf("%s database has no driver", config.Database.Type)
	}

	var entityManager db.EntityManagerInterface
	var repository db.RepositoryInterface

	if driver != nil {
		err = driver.Init(config.Database.URL)
		if err != nil {
			return
		}

		entityManager = db.NewEntityManager(driver)
		repository = db.NewRepository(driver)
	}

	if migrateFlag {
		if driver == nil {
			log.Fatal("No database driver.")
			return
		}

		var migrationsApplied int
		migrationsApplied, err = driver.MigrateUp("gateway")
		if err != nil {
			return
		}

		log.Info("Applied migrations: ", migrationsApplied)
		os.Exit(0)
		return
	}

	h := horizon.New(config.Horizon)

	log.Print("Creating and initializing TransactionSubmitter")
	ts := submitter.NewTransactionSubmitter(&h, entityManager, config.NetworkPassphrase, time.Now)
	if err != nil {
		return
	}

	log.Print("Initializing Authorizing account")

	if config.Accounts.AuthorizingSeed == "" {
		log.Warning("No accounts.authorizing_seed param. Skipping...")
	} else {
		err = ts.InitAccount(config.Accounts.AuthorizingSeed)
		if err != nil {
			return
		}
	}

	if config.Accounts.BaseSeed == "" {
		log.Warning("No accounts.base_seed param. Skipping...")
	} else {
		log.Print("Initializing Base account")
		err = ts.InitAccount(config.Accounts.BaseSeed)
		if err != nil {
			return
		}
	}

	log.Print("TransactionSubmitter created")

	log.Print("Creating and starting PaymentListener")

	var paymentListener listener.PaymentListener

	if config.Accounts.ReceivingAccountID == "" {
		log.Warning("No accounts.receiving_account_id param. Skipping...")
	} else if config.Hooks.Receive == "" {
		log.Warning("No hooks.receive param. Skipping...")
	} else {
		paymentListener, err = listener.NewPaymentListener(&config, entityManager, &h, repository, time.Now)
		if err != nil {
			return
		}
		err = paymentListener.Listen()
		if err != nil {
			return
		}

		log.Print("PaymentListener created")
	}

	if len(config.APIKey) > 0 && len(config.APIKey) < 15 {
		err = errors.New("api-key have to be at least 15 chars long")
		return
	}

	requestHandler := handlers.RequestHandler{}

	err = g.Provide(
		&inject.Object{Value: &requestHandler},
		&inject.Object{Value: &config},
		&inject.Object{Value: &stellartoml.Resolver{}},
		&inject.Object{Value: &federation.Resolver{}},
		&inject.Object{Value: &h},
		&inject.Object{Value: &ts},
		&inject.Object{Value: &paymentListener},
		&inject.Object{Value: &http.Client{}},
	)

	if err != nil {
		log.Fatal("Injector: ", err)
	}

	if err := g.Populate(); err != nil {
		log.Fatal("Injector: ", err)
	}

	app = &App{
		config:         config,
		requestHandler: requestHandler,
	}
	return
}

// Serve starts the server
func (a *App) Serve() {
	portString := fmt.Sprintf(":%d", *a.config.Port)
	flag.Set("bind", portString)

	goji.Abandon(middleware.Logger)
	goji.Use(server.StripTrailingSlashMiddleware())
	goji.Use(server.HeadersMiddleware())
	if a.config.APIKey != "" {
		goji.Use(server.APIKeyMiddleware(a.config.APIKey))
	}

	if a.config.Accounts.AuthorizingSeed != "" {
		goji.Post("/authorize", a.requestHandler.Authorize)
	} else {
		log.Warning("accounts.authorizing_seed not provided. /authorize endpoint will not be available.")
	}

	goji.Post("/builder", a.requestHandler.Builder)
	goji.Post("/payment", a.requestHandler.Payment)

	goji.Serve()
}
<commit_msg>allow Get<commit_after>package bridge

import (
	"errors"
	"flag"
	"fmt"
	log "github.com/Sirupsen/logrus"
	"net/http"
	"os"
	"time"

	"github.com/facebookgo/inject"
	"github.com/stellar/gateway/bridge/config"
	"github.com/stellar/gateway/bridge/handlers"
	"github.com/stellar/gateway/db"
	"github.com/stellar/gateway/db/drivers/mysql"
	"github.com/stellar/gateway/db/drivers/postgres"
	"github.com/stellar/gateway/horizon"
	"github.com/stellar/gateway/listener"
	"github.com/stellar/gateway/protocols/federation"
	"github.com/stellar/gateway/protocols/stellartoml"
	"github.com/stellar/gateway/server"
	"github.com/stellar/gateway/submitter"
	"github.com/zenazn/goji"
	"github.com/zenazn/goji/web/middleware"
)

// App is the application object
type App struct {
	config         config.Config
	requestHandler handlers.RequestHandler
}

// NewApp constructs an new App instance from the provided config.
func NewApp(config config.Config, migrateFlag bool) (app *App, err error) {
	var g inject.Graph

	var driver db.Driver
	switch config.Database.Type {
	case "mysql":
		driver = &mysql.Driver{}
	case "postgres":
		driver = &postgres.Driver{}
	case "":
		// Allow to start gateway server with a single endpoint: /payment
		break
	default:
		return nil, fmt.Errorf("%s database has no driver", config.Database.Type)
	}

	var entityManager db.EntityManagerInterface
	var repository db.RepositoryInterface

	if driver != nil {
		err = driver.Init(config.Database.URL)
		if err != nil {
			return
		}

		entityManager = db.NewEntityManager(driver)
		repository = db.NewRepository(driver)
	}

	if migrateFlag {
		if driver == nil {
			log.Fatal("No database driver.")
			return
		}

		var migrationsApplied int
		migrationsApplied, err = driver.MigrateUp("gateway")
		if err != nil {
			return
		}

		log.Info("Applied migrations: ", migrationsApplied)
		os.Exit(0)
		return
	}

	h := horizon.New(config.Horizon)

	log.Print("Creating and initializing TransactionSubmitter")
	ts := submitter.NewTransactionSubmitter(&h, entityManager, config.NetworkPassphrase, time.Now)
	if err != nil {
		return
	}

	log.Print("Initializing Authorizing account")

	if config.Accounts.AuthorizingSeed == "" {
		log.Warning("No accounts.authorizing_seed param. Skipping...")
	} else {
		err = ts.InitAccount(config.Accounts.AuthorizingSeed)
		if err != nil {
			return
		}
	}

	if config.Accounts.BaseSeed == "" {
		log.Warning("No accounts.base_seed param. Skipping...")
	} else {
		log.Print("Initializing Base account")
		err = ts.InitAccount(config.Accounts.BaseSeed)
		if err != nil {
			return
		}
	}

	log.Print("TransactionSubmitter created")

	log.Print("Creating and starting PaymentListener")

	var paymentListener listener.PaymentListener

	if config.Accounts.ReceivingAccountID == "" {
		log.Warning("No accounts.receiving_account_id param. Skipping...")
	} else if config.Hooks.Receive == "" {
		log.Warning("No hooks.receive param. Skipping...")
	} else {
		paymentListener, err = listener.NewPaymentListener(&config, entityManager, &h, repository, time.Now)
		if err != nil {
			return
		}
		err = paymentListener.Listen()
		if err != nil {
			return
		}

		log.Print("PaymentListener created")
	}

	if len(config.APIKey) > 0 && len(config.APIKey) < 15 {
		err = errors.New("api-key have to be at least 15 chars long")
		return
	}

	requestHandler := handlers.RequestHandler{}

	err = g.Provide(
		&inject.Object{Value: &requestHandler},
		&inject.Object{Value: &config},
		&inject.Object{Value: &stellartoml.Resolver{}},
		&inject.Object{Value: &federation.Resolver{}},
		&inject.Object{Value: &h},
		&inject.Object{Value: &ts},
		&inject.Object{Value: &paymentListener},
		&inject.Object{Value: &http.Client{}},
	)

	if err != nil {
		log.Fatal("Injector: ", err)
	}

	if err := g.Populate(); err != nil {
		log.Fatal("Injector: ", err)
	}

	app = &App{
		config:         config,
		requestHandler: requestHandler,
	}
	return
}

// Serve starts the server
func (a *App) Serve() {
	portString := fmt.Sprintf(":%d", *a.config.Port)
	flag.Set("bind", portString)

	goji.Abandon(middleware.Logger)
	goji.Use(server.StripTrailingSlashMiddleware())
	goji.Use(server.HeadersMiddleware())
	if a.config.APIKey != "" {
		goji.Use(server.APIKeyMiddleware(a.config.APIKey))
	}

	if a.config.Accounts.AuthorizingSeed != "" {
		goji.Post("/authorize", a.requestHandler.Authorize)
	} else {
		log.Warning("accounts.authorizing_seed not provided. /authorize endpoint will not be available.")
	}

	goji.Post("/builder", a.requestHandler.Builder)
	goji.Post("/payment", a.requestHandler.Payment)
	goji.Get("/payment", a.requestHandler.Payment)

	goji.Serve()
}
<|endoftext|>


<commit_before>package git

/*
#include <git2.h>
#include <git2/sys/repository.h>
*/
import "C"
import (
	"runtime"
	"unsafe"
)

// Repository
type Repository struct {
	ptr *C.git_repository
	// Remotes represents the collection of remotes and can be
	// used to add, remove and configure remotes for this
	// repository.
	Remotes RemoteCollection
	// Submodules represents the collection of submodules and can
	// be used to add, remove and configure submodules in this
	// repostiory.
	Submodules SubmoduleCollection
	// References represents the collection of references and can
	// be used to create, remove or update refernces for this repository.
	References ReferenceCollection
	// Notes represents the collection of notes and can be used to
	// read, write and delete notes from this repository.
	Notes NoteCollection
	// Tags represents the collection of tags and can be used to create,
	// list and iterate tags in this repository.
	Tags TagsCollection
}

func newRepositoryFromC(ptr *C.git_repository) *Repository {
	repo := &Repository{ptr: ptr}

	repo.Remotes.repo = repo
	repo.Submodules.repo = repo
	repo.References.repo = repo
	repo.Notes.repo = repo
	repo.Tags.repo = repo

	runtime.SetFinalizer(repo, (*Repository).Free)

	return repo
}

func OpenRepository(path string) (*Repository, error) {
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	var ptr *C.git_repository
	ret := C.git_repository_open(&ptr, cpath)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newRepositoryFromC(ptr), nil
}

func OpenRepositoryExtended(path string) (*Repository, error) {
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	var ptr *C.git_repository
	ret := C.git_repository_open_ext(&ptr, cpath, 0, nil)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newRepositoryFromC(ptr), nil
}

func InitRepository(path string, isbare bool) (*Repository, error) {
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	var ptr *C.git_repository
	ret := C.git_repository_init(&ptr, cpath, ucbool(isbare))
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newRepositoryFromC(ptr), nil
}

func NewRepositoryWrapOdb(odb *Odb) (repo *Repository, err error) {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	var ptr *C.git_repository
	ret := C.git_repository_wrap_odb(&ptr, odb.ptr)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newRepositoryFromC(ptr), nil
}

func (v *Repository) SetRefdb(refdb *Refdb) {
	C.git_repository_set_refdb(v.ptr, refdb.ptr)
}

func (v *Repository) Free() {
	runtime.SetFinalizer(v, nil)
	C.git_repository_free(v.ptr)
}

func (v *Repository) Config() (*Config, error) {
	config := new(Config)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_repository_config(&config.ptr, v.ptr)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	runtime.SetFinalizer(config, (*Config).Free)
	return config, nil
}

func (v *Repository) Index() (*Index, error) {
	var ptr *C.git_index

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_repository_index(&ptr, v.ptr)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newIndexFromC(ptr), nil
}

func (v *Repository) lookupType(id *Oid, t ObjectType) (*Object, error) {
	var ptr *C.git_object

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_object_lookup(&ptr, v.ptr, id.toC(), C.git_otype(t))
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return allocObject(ptr, v), nil
}

func (v *Repository) Lookup(id *Oid) (*Object, error) {
	return v.lookupType(id, ObjectAny)
}

func (v *Repository) LookupTree(id *Oid) (*Tree, error) {
	obj, err := v.lookupType(id, ObjectTree)
	if err != nil {
		return nil, err
	}

	return obj.AsTree()
}

func (v *Repository) LookupCommit(id *Oid) (*Commit, error) {
	obj, err := v.lookupType(id, ObjectCommit)
	if err != nil {
		return nil, err
	}

	return obj.AsCommit()
}

func (v *Repository) LookupBlob(id *Oid) (*Blob, error) {
	obj, err := v.lookupType(id, ObjectBlob)
	if err != nil {
		return nil, err
	}

	return obj.AsBlob()
}

func (v *Repository) LookupTag(id *Oid) (*Tag, error) {
	obj, err := v.lookupType(id, ObjectTag)
	if err != nil {
		return nil, err
	}

	return obj.AsTag()
}

func (v *Repository) Head() (*Reference, error) {
	var ptr *C.git_reference

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_repository_head(&ptr, v.ptr)
	if ecode < 0 {
		return nil, MakeGitError(ecode)
	}

	return newReferenceFromC(ptr, v), nil
}

func (v *Repository) SetHead(refname string) error {
	cname := C.CString(refname)
	defer C.free(unsafe.Pointer(cname))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_repository_set_head(v.ptr, cname)
	if ecode != 0 {
		return MakeGitError(ecode)
	}
	return nil
}

func (v *Repository) SetHeadDetached(id *Oid) error {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_repository_set_head_detached(v.ptr, id.toC())
	if ecode != 0 {
		return MakeGitError(ecode)
	}
	return nil
}

func (v *Repository) IsHeadDetached() (bool, error) {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_repository_head_detached(v.ptr)
	if ret < 0 {
		return false, MakeGitError(ret)
	}

	return ret != 0, nil
}

func (v *Repository) Walk() (*RevWalk, error) {

	var walkPtr *C.git_revwalk

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_revwalk_new(&walkPtr, v.ptr)
	if ecode < 0 {
		return nil, MakeGitError(ecode)
	}

	return revWalkFromC(v, walkPtr), nil
}

func (v *Repository) CreateCommit(
	refname string, author, committer *Signature,
	message string, tree *Tree, parents ...*Commit) (*Oid, error) {

	oid := new(Oid)

	var cref *C.char
	if refname == "" {
		cref = nil
	} else {
		cref = C.CString(refname)
		defer C.free(unsafe.Pointer(cref))
	}

	cmsg := C.CString(message)
	defer C.free(unsafe.Pointer(cmsg))

	var cparents []*C.git_commit = nil
	var parentsarg **C.git_commit = nil

	nparents := len(parents)
	if nparents > 0 {
		cparents = make([]*C.git_commit, nparents)
		for i, v := range parents {
			cparents[i] = v.cast_ptr
		}
		parentsarg = &cparents[0]
	}

	authorSig, err := author.toC()
	if err != nil {
		return nil, err
	}
	defer C.git_signature_free(authorSig)

	committerSig, err := committer.toC()
	if err != nil {
		return nil, err
	}
	defer C.git_signature_free(committerSig)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_commit_create(
		oid.toC(), v.ptr, cref,
		authorSig, committerSig,
		nil, cmsg, tree.cast_ptr, C.size_t(nparents), parentsarg)

	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return oid, nil
}

func (v *Odb) Free() {
	runtime.SetFinalizer(v, nil)
	C.git_odb_free(v.ptr)
}

func (v *Refdb) Free() {
	runtime.SetFinalizer(v, nil)
	C.git_refdb_free(v.ptr)
}

func (v *Repository) Odb() (odb *Odb, err error) {
	odb = new(Odb)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	if ret := C.git_repository_odb(&odb.ptr, v.ptr); ret < 0 {
		return nil, MakeGitError(ret)
	}

	runtime.SetFinalizer(odb, (*Odb).Free)
	return odb, nil
}

func (repo *Repository) Path() string {
	return C.GoString(C.git_repository_path(repo.ptr))
}

func (repo *Repository) IsBare() bool {
	return C.git_repository_is_bare(repo.ptr) != 0
}

func (repo *Repository) Workdir() string {
	return C.GoString(C.git_repository_workdir(repo.ptr))
}

func (repo *Repository) SetWorkdir(workdir string, updateGitlink bool) error {
	cstr := C.CString(workdir)
	defer C.free(unsafe.Pointer(cstr))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	if ret := C.git_repository_set_workdir(repo.ptr, cstr, cbool(updateGitlink)); ret < 0 {
		return MakeGitError(ret)
	}

	return nil
}

func (v *Repository) TreeBuilder() (*TreeBuilder, error) {
	bld := new(TreeBuilder)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	if ret := C.git_treebuilder_new(&bld.ptr, v.ptr, nil); ret < 0 {
		return nil, MakeGitError(ret)
	}
	runtime.SetFinalizer(bld, (*TreeBuilder).Free)

	bld.repo = v
	return bld, nil
}

func (v *Repository) TreeBuilderFromTree(tree *Tree) (*TreeBuilder, error) {
	bld := new(TreeBuilder)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	if ret := C.git_treebuilder_new(&bld.ptr, v.ptr, tree.cast_ptr); ret < 0 {
		return nil, MakeGitError(ret)
	}
	runtime.SetFinalizer(bld, (*TreeBuilder).Free)

	bld.repo = v
	return bld, nil
}

type RepositoryState int

const (
	RepositoryStateNone                 RepositoryState = C.GIT_REPOSITORY_STATE_NONE
	RepositoryStateMerge                RepositoryState = C.GIT_REPOSITORY_STATE_MERGE
	RepositoryStateRevert               RepositoryState = C.GIT_REPOSITORY_STATE_REVERT
	RepositoryStateCherrypick           RepositoryState = C.GIT_REPOSITORY_STATE_CHERRYPICK
	RepositoryStateBisect               RepositoryState = C.GIT_REPOSITORY_STATE_BISECT
	RepositoryStateRebase               RepositoryState = C.GIT_REPOSITORY_STATE_REBASE
	RepositoryStateRebaseInteractive    RepositoryState = C.GIT_REPOSITORY_STATE_REBASE_INTERACTIVE
	RepositoryStateRebaseMerge          RepositoryState = C.GIT_REPOSITORY_STATE_REBASE_MERGE
	RepositoryStateApplyMailbox         RepositoryState = C.GIT_REPOSITORY_STATE_APPLY_MAILBOX
	RepositoryStateApplyMailboxOrRebase RepositoryState = C.GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE
)

func (r *Repository) State() RepositoryState {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	return RepositoryState(C.git_repository_state(r.ptr))
}

func (r *Repository) StateCleanup() error {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	cErr := C.git_repository_state_cleanup(r.ptr)
	if cErr < 0 {
		return MakeGitError(cErr)
	}
	return nil
}
<commit_msg>Add missing RepositoryOpenExtended arguments<commit_after>package git

/*
#include <git2.h>
#include <git2/sys/repository.h>
*/
import "C"
import (
	"runtime"
	"unsafe"
)

// Repository
type Repository struct {
	ptr *C.git_repository
	// Remotes represents the collection of remotes and can be
	// used to add, remove and configure remotes for this
	// repository.
	Remotes RemoteCollection
	// Submodules represents the collection of submodules and can
	// be used to add, remove and configure submodules in this
	// repostiory.
	Submodules SubmoduleCollection
	// References represents the collection of references and can
	// be used to create, remove or update refernces for this repository.
	References ReferenceCollection
	// Notes represents the collection of notes and can be used to
	// read, write and delete notes from this repository.
	Notes NoteCollection
	// Tags represents the collection of tags and can be used to create,
	// list and iterate tags in this repository.
	Tags TagsCollection
}

func newRepositoryFromC(ptr *C.git_repository) *Repository {
	repo := &Repository{ptr: ptr}

	repo.Remotes.repo = repo
	repo.Submodules.repo = repo
	repo.References.repo = repo
	repo.Notes.repo = repo
	repo.Tags.repo = repo

	runtime.SetFinalizer(repo, (*Repository).Free)

	return repo
}

func OpenRepository(path string) (*Repository, error) {
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	var ptr *C.git_repository
	ret := C.git_repository_open(&ptr, cpath)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newRepositoryFromC(ptr), nil
}

type RepositoryOpenFlag int

const (
	RepositoryOpenNoSearch RepositoryOpenFlag = C.GIT_REPOSITORY_OPEN_NO_SEARCH
	RepositoryOpenCrossFs  RepositoryOpenFlag = C.GIT_REPOSITORY_OPEN_CROSS_FS
	RepositoryOpenBare     RepositoryOpenFlag = C.GIT_REPOSITORY_OPEN_BARE
)

func OpenRepositoryExtended(path string, flags RepositoryOpenFlag, ceiling string) (*Repository, error) {
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	var cceiling *C.char = nil
	if len(ceiling) > 0 {
		cceiling = C.CString(ceiling)
		defer C.free(unsafe.Pointer(cceiling))
	}

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	var ptr *C.git_repository
	ret := C.git_repository_open_ext(&ptr, cpath, C.uint(flags), cceiling)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newRepositoryFromC(ptr), nil
}

func InitRepository(path string, isbare bool) (*Repository, error) {
	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	var ptr *C.git_repository
	ret := C.git_repository_init(&ptr, cpath, ucbool(isbare))
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newRepositoryFromC(ptr), nil
}

func NewRepositoryWrapOdb(odb *Odb) (repo *Repository, err error) {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	var ptr *C.git_repository
	ret := C.git_repository_wrap_odb(&ptr, odb.ptr)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newRepositoryFromC(ptr), nil
}

func (v *Repository) SetRefdb(refdb *Refdb) {
	C.git_repository_set_refdb(v.ptr, refdb.ptr)
}

func (v *Repository) Free() {
	runtime.SetFinalizer(v, nil)
	C.git_repository_free(v.ptr)
}

func (v *Repository) Config() (*Config, error) {
	config := new(Config)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_repository_config(&config.ptr, v.ptr)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	runtime.SetFinalizer(config, (*Config).Free)
	return config, nil
}

func (v *Repository) Index() (*Index, error) {
	var ptr *C.git_index

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_repository_index(&ptr, v.ptr)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newIndexFromC(ptr), nil
}

func (v *Repository) lookupType(id *Oid, t ObjectType) (*Object, error) {
	var ptr *C.git_object

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_object_lookup(&ptr, v.ptr, id.toC(), C.git_otype(t))
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return allocObject(ptr, v), nil
}

func (v *Repository) Lookup(id *Oid) (*Object, error) {
	return v.lookupType(id, ObjectAny)
}

func (v *Repository) LookupTree(id *Oid) (*Tree, error) {
	obj, err := v.lookupType(id, ObjectTree)
	if err != nil {
		return nil, err
	}

	return obj.AsTree()
}

func (v *Repository) LookupCommit(id *Oid) (*Commit, error) {
	obj, err := v.lookupType(id, ObjectCommit)
	if err != nil {
		return nil, err
	}

	return obj.AsCommit()
}

func (v *Repository) LookupBlob(id *Oid) (*Blob, error) {
	obj, err := v.lookupType(id, ObjectBlob)
	if err != nil {
		return nil, err
	}

	return obj.AsBlob()
}

func (v *Repository) LookupTag(id *Oid) (*Tag, error) {
	obj, err := v.lookupType(id, ObjectTag)
	if err != nil {
		return nil, err
	}

	return obj.AsTag()
}

func (v *Repository) Head() (*Reference, error) {
	var ptr *C.git_reference

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_repository_head(&ptr, v.ptr)
	if ecode < 0 {
		return nil, MakeGitError(ecode)
	}

	return newReferenceFromC(ptr, v), nil
}

func (v *Repository) SetHead(refname string) error {
	cname := C.CString(refname)
	defer C.free(unsafe.Pointer(cname))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_repository_set_head(v.ptr, cname)
	if ecode != 0 {
		return MakeGitError(ecode)
	}
	return nil
}

func (v *Repository) SetHeadDetached(id *Oid) error {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_repository_set_head_detached(v.ptr, id.toC())
	if ecode != 0 {
		return MakeGitError(ecode)
	}
	return nil
}

func (v *Repository) IsHeadDetached() (bool, error) {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_repository_head_detached(v.ptr)
	if ret < 0 {
		return false, MakeGitError(ret)
	}

	return ret != 0, nil
}

func (v *Repository) Walk() (*RevWalk, error) {

	var walkPtr *C.git_revwalk

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_revwalk_new(&walkPtr, v.ptr)
	if ecode < 0 {
		return nil, MakeGitError(ecode)
	}

	return revWalkFromC(v, walkPtr), nil
}

func (v *Repository) CreateCommit(
	refname string, author, committer *Signature,
	message string, tree *Tree, parents ...*Commit) (*Oid, error) {

	oid := new(Oid)

	var cref *C.char
	if refname == "" {
		cref = nil
	} else {
		cref = C.CString(refname)
		defer C.free(unsafe.Pointer(cref))
	}

	cmsg := C.CString(message)
	defer C.free(unsafe.Pointer(cmsg))

	var cparents []*C.git_commit = nil
	var parentsarg **C.git_commit = nil

	nparents := len(parents)
	if nparents > 0 {
		cparents = make([]*C.git_commit, nparents)
		for i, v := range parents {
			cparents[i] = v.cast_ptr
		}
		parentsarg = &cparents[0]
	}

	authorSig, err := author.toC()
	if err != nil {
		return nil, err
	}
	defer C.git_signature_free(authorSig)

	committerSig, err := committer.toC()
	if err != nil {
		return nil, err
	}
	defer C.git_signature_free(committerSig)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_commit_create(
		oid.toC(), v.ptr, cref,
		authorSig, committerSig,
		nil, cmsg, tree.cast_ptr, C.size_t(nparents), parentsarg)

	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return oid, nil
}

func (v *Odb) Free() {
	runtime.SetFinalizer(v, nil)
	C.git_odb_free(v.ptr)
}

func (v *Refdb) Free() {
	runtime.SetFinalizer(v, nil)
	C.git_refdb_free(v.ptr)
}

func (v *Repository) Odb() (odb *Odb, err error) {
	odb = new(Odb)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	if ret := C.git_repository_odb(&odb.ptr, v.ptr); ret < 0 {
		return nil, MakeGitError(ret)
	}

	runtime.SetFinalizer(odb, (*Odb).Free)
	return odb, nil
}

func (repo *Repository) Path() string {
	return C.GoString(C.git_repository_path(repo.ptr))
}

func (repo *Repository) IsBare() bool {
	return C.git_repository_is_bare(repo.ptr) != 0
}

func (repo *Repository) Workdir() string {
	return C.GoString(C.git_repository_workdir(repo.ptr))
}

func (repo *Repository) SetWorkdir(workdir string, updateGitlink bool) error {
	cstr := C.CString(workdir)
	defer C.free(unsafe.Pointer(cstr))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	if ret := C.git_repository_set_workdir(repo.ptr, cstr, cbool(updateGitlink)); ret < 0 {
		return MakeGitError(ret)
	}

	return nil
}

func (v *Repository) TreeBuilder() (*TreeBuilder, error) {
	bld := new(TreeBuilder)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	if ret := C.git_treebuilder_new(&bld.ptr, v.ptr, nil); ret < 0 {
		return nil, MakeGitError(ret)
	}
	runtime.SetFinalizer(bld, (*TreeBuilder).Free)

	bld.repo = v
	return bld, nil
}

func (v *Repository) TreeBuilderFromTree(tree *Tree) (*TreeBuilder, error) {
	bld := new(TreeBuilder)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	if ret := C.git_treebuilder_new(&bld.ptr, v.ptr, tree.cast_ptr); ret < 0 {
		return nil, MakeGitError(ret)
	}
	runtime.SetFinalizer(bld, (*TreeBuilder).Free)

	bld.repo = v
	return bld, nil
}

type RepositoryState int

const (
	RepositoryStateNone                 RepositoryState = C.GIT_REPOSITORY_STATE_NONE
	RepositoryStateMerge                RepositoryState = C.GIT_REPOSITORY_STATE_MERGE
	RepositoryStateRevert               RepositoryState = C.GIT_REPOSITORY_STATE_REVERT
	RepositoryStateCherrypick           RepositoryState = C.GIT_REPOSITORY_STATE_CHERRYPICK
	RepositoryStateBisect               RepositoryState = C.GIT_REPOSITORY_STATE_BISECT
	RepositoryStateRebase               RepositoryState = C.GIT_REPOSITORY_STATE_REBASE
	RepositoryStateRebaseInteractive    RepositoryState = C.GIT_REPOSITORY_STATE_REBASE_INTERACTIVE
	RepositoryStateRebaseMerge          RepositoryState = C.GIT_REPOSITORY_STATE_REBASE_MERGE
	RepositoryStateApplyMailbox         RepositoryState = C.GIT_REPOSITORY_STATE_APPLY_MAILBOX
	RepositoryStateApplyMailboxOrRebase RepositoryState = C.GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE
)

func (r *Repository) State() RepositoryState {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	return RepositoryState(C.git_repository_state(r.ptr))
}

func (r *Repository) StateCleanup() error {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	cErr := C.git_repository_state_cleanup(r.ptr)
	if cErr < 0 {
		return MakeGitError(cErr)
	}
	return nil
}
<|endoftext|>


<commit_before>package git

import (
	"io/ioutil"
	"testing"
)

func TestResetToCommit(t *testing.T) {
	t.Parallel()
	repo := createTestRepo(t)
	seedTestRepo(t, repo)
	// create commit to reset to
	commitId, _ := updateReadme(t, repo, "testing reset")
	// create commit to reset from
	nextCommitId, _ := updateReadme(t, repo, "will be reset")

	// confirm that we wrote "will be reset" to the readme
	newBytes, err := ioutil.ReadFile(pathInRepo(repo, "README"))
	checkFatal(t, err)
	if string(newBytes) != "will be reset" {
		t.Fatalf("expected %s to equal 'will be reset'", string(newBytes))
	}

	// confirm that the head of the repo is the next commit id
	head, err := repo.Head()
	checkFatal(t, err)
	if head.Target().String() != nextCommitId.String() {
		t.Fatalf(
			"expected to be at latest commit %s, but was %s",
			nextCommitId.String(),
			head.Target().String(),
		)
	}

	commitToResetTo, err := repo.LookupCommit(commitId)
	checkFatal(t, err)

	repo.ResetToCommit(commitToResetTo, ResetHard, &CheckoutOpts{})

	// check that the file now reads "testing reset" like it did before
	bytes, err := ioutil.ReadFile(pathInRepo(repo, "README"))
	checkFatal(t, err)
	if string(bytes) != "testing reset" {
		t.Fatalf("expected %s to equal 'testing reset'", string(bytes))
	}
}
<commit_msg>Clean up one leaked temporary directory<commit_after>package git

import (
	"io/ioutil"
	"testing"
)

func TestResetToCommit(t *testing.T) {
	t.Parallel()
	repo := createTestRepo(t)
	defer cleanupTestRepo(t, repo)

	seedTestRepo(t, repo)
	// create commit to reset to
	commitId, _ := updateReadme(t, repo, "testing reset")
	// create commit to reset from
	nextCommitId, _ := updateReadme(t, repo, "will be reset")

	// confirm that we wrote "will be reset" to the readme
	newBytes, err := ioutil.ReadFile(pathInRepo(repo, "README"))
	checkFatal(t, err)
	if string(newBytes) != "will be reset" {
		t.Fatalf("expected %s to equal 'will be reset'", string(newBytes))
	}

	// confirm that the head of the repo is the next commit id
	head, err := repo.Head()
	checkFatal(t, err)
	if head.Target().String() != nextCommitId.String() {
		t.Fatalf(
			"expected to be at latest commit %s, but was %s",
			nextCommitId.String(),
			head.Target().String(),
		)
	}

	commitToResetTo, err := repo.LookupCommit(commitId)
	checkFatal(t, err)

	repo.ResetToCommit(commitToResetTo, ResetHard, &CheckoutOpts{})

	// check that the file now reads "testing reset" like it did before
	bytes, err := ioutil.ReadFile(pathInRepo(repo, "README"))
	checkFatal(t, err)
	if string(bytes) != "testing reset" {
		t.Fatalf("expected %s to equal 'testing reset'", string(bytes))
	}
}
<|endoftext|>


<commit_before>// Copyright 2011 Miek Gieben. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Reflect is a small name server which sends back the IP address of its client, the
// recursive resolver.
// When queried for type A (resp. AAAA), it sends back the IPv4 (resp. v6) address.
// In the additional section the port number and transport are shown.
//
// Basic use pattern:
//
//	dig @localhost -p 8053 whoami.miek.nl A
//
//	;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2157
//	;; flags: qr rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
//	;; QUESTION SECTION:
//	;whoami.miek.nl.			IN	A
//
//	;; ANSWER SECTION:
//	whoami.miek.nl.		0	IN	A	127.0.0.1
//
//	;; ADDITIONAL SECTION:
//	whoami.miek.nl.		0	IN	TXT	"Port: 56195 (udp)"
//
// Similar services: whoami.ultradns.net, whoami.akamai.net. Also (but it
// is not their normal goal): rs.dns-oarc.net, porttest.dns-oarc.net,
// amiopen.openresolvers.org.
//
// Original version is from: Stephane Bortzmeyer <stephane+grong@bortzmeyer.org>.
//
// Adapted to Go (i.e. completely rewritten) by Miek Gieben <miek@miek.nl>.
package main

import (
	"flag"
	"fmt"
	"github.com/miekg/dns"
	"log"
	"net"
	"os"
	"os/signal"
	"runtime"
	"runtime/pprof"
	"strconv"
	"strings"
	"syscall"
	"time"
)

var (
	printf   *bool
	compress *bool
	tsig     *string
)

const dom = "whoami.miek.nl."

func handleReflect(w dns.ResponseWriter, r *dns.Msg) {
	var (
		v4  bool
		rr  dns.RR
		str string
		a   net.IP
	)
	// TC must be done here
	m := new(dns.Msg)
	m.SetReply(r)
	m.Compress = *compress
	if ip, ok := w.RemoteAddr().(*net.UDPAddr); ok {
		str = "Port: " + strconv.Itoa(ip.Port) + " (udp)"
		a = ip.IP
		v4 = a.To4() != nil
	}
	if ip, ok := w.RemoteAddr().(*net.TCPAddr); ok {
		str = "Port: " + strconv.Itoa(ip.Port) + " (tcp)"
		a = ip.IP
		v4 = a.To4() != nil
	}

	/*
		if o := r.IsEdns0(); o != nil {
			for _, s := range o.Option {
				switch e := s.(type) {
				case *dns.EDNS0_SUBNET:
					log.Printf("Edns0 subnet %s", e.Address)
				}
			}
		}
	*/

	if v4 {
		rr = new(dns.A)
		rr.(*dns.A).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0}
		rr.(*dns.A).A = a.To4()
	} else {
		rr = new(dns.AAAA)
		rr.(*dns.AAAA).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 0}
		rr.(*dns.AAAA).AAAA = a
	}

	t := new(dns.TXT)
	t.Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0}
	t.Txt = []string{str}

	switch r.Question[0].Qtype {
	case dns.TypeAXFR:
		c := make(chan *dns.Envelope)
		var e *error
		if err := dns.TransferOut(w, r, c, e); err != nil {
			close(c)
			return
		}
		soa, _ := dns.NewRR(`whoami.miek.nl. IN SOA elektron.atoom.net. miekg.atoom.net. (
			2009032802
			21600
			7200
			604800
			3600)`)
		c <- &dns.Envelope{RR: []dns.RR{soa, t, rr, soa}}
		close(c)
		w.Hijack()
		// w.Close() // Client closes
		return
	case dns.TypeTXT:
		m.Answer = append(m.Answer, t)
		m.Extra = append(m.Extra, rr)
	default:
		fallthrough
	case dns.TypeAAAA, dns.TypeA:
		m.Answer = append(m.Answer, rr)
		m.Extra = append(m.Extra, t)
	}

	if r.IsTsig() != nil {
		if w.TsigStatus() == nil {
			m.SetTsig(r.Extra[len(r.Extra)-1].(*dns.TSIG).Hdr.Name, dns.HmacMD5, 300, time.Now().Unix())
		} else {
			println("Status", w.TsigStatus().Error())
		}
	}
	if *printf {
		fmt.Printf("%v\n", m.String())
	}
	w.WriteMsg(m)
}

func serve(net, name, secret string) {
	switch name {
	case "":
		err := dns.ListenAndServe(":8053", net, nil)
		if err != nil {
			fmt.Printf("Failed to setup the "+net+" server: %s\n", err.Error())
		}
	default:
		server := &dns.Server{Addr: ":8053", Net: net, TsigSecret: map[string]string{name: secret}}
		err := server.ListenAndServe()
		if err != nil {
			fmt.Printf("Failed to setup the "+net+" server: %s\n", err.Error())
		}
	}
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU()*4)
	cpuprofile := flag.String("cpuprofile", "", "write cpu profile to file")
	printf = flag.Bool("print", false, "print replies")
	compress = flag.Bool("compress", false, "compress replies")
	tsig = flag.String("tsig", "", "use MD5 hmac tsig: keyname:base64")
	var name, secret string
	flag.Usage = func() {
		flag.PrintDefaults()
	}
	flag.Parse()
	if *tsig != "" {
		a := strings.SplitN(*tsig, ":", 2)
		name, secret = dns.Fqdn(a[0]), a[1] // fqdn the name, which everybody forgets...
	}
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	dns.HandleFunc("miek.nl.", handleReflect)
	dns.HandleFunc("authors.bind.", dns.HandleAuthors)
	dns.HandleFunc("authors.server.", dns.HandleAuthors)
	dns.HandleFunc("version.bind.", dns.HandleVersion)
	dns.HandleFunc("version.server.", dns.HandleVersion)
	go serve("tcp", name, secret)
	go serve("udp", name, secret)
	sig := make(chan os.Signal)
	signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
forever:
	for {
		select {
		case s := <-sig:
			fmt.Printf("Signal (%d) received, stopping\n", s)
			break forever
		}
	}
}
<commit_msg>Remove xfr<commit_after>// Copyright 2011 Miek Gieben. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Reflect is a small name server which sends back the IP address of its client, the
// recursive resolver.
// When queried for type A (resp. AAAA), it sends back the IPv4 (resp. v6) address.
// In the additional section the port number and transport are shown.
//
// Basic use pattern:
//
//	dig @localhost -p 8053 whoami.miek.nl A
//
//	;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 2157
//	;; flags: qr rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
//	;; QUESTION SECTION:
//	;whoami.miek.nl.			IN	A
//
//	;; ANSWER SECTION:
//	whoami.miek.nl.		0	IN	A	127.0.0.1
//
//	;; ADDITIONAL SECTION:
//	whoami.miek.nl.		0	IN	TXT	"Port: 56195 (udp)"
//
// Similar services: whoami.ultradns.net, whoami.akamai.net. Also (but it
// is not their normal goal): rs.dns-oarc.net, porttest.dns-oarc.net,
// amiopen.openresolvers.org.
//
// Original version is from: Stephane Bortzmeyer <stephane+grong@bortzmeyer.org>.
//
// Adapted to Go (i.e. completely rewritten) by Miek Gieben <miek@miek.nl>.
package main

import (
	"flag"
	"fmt"
	"github.com/miekg/dns"
	"log"
	"net"
	"os"
	"os/signal"
	"runtime"
	"runtime/pprof"
	"strconv"
	"strings"
	"syscall"
	"time"
)

var (
	printf   *bool
	compress *bool
	tsig     *string
)

const dom = "whoami.miek.nl."

func handleReflect(w dns.ResponseWriter, r *dns.Msg) {
	var (
		v4  bool
		rr  dns.RR
		str string
		a   net.IP
	)
	// TC must be done here
	m := new(dns.Msg)
	m.SetReply(r)
	m.Compress = *compress
	if ip, ok := w.RemoteAddr().(*net.UDPAddr); ok {
		str = "Port: " + strconv.Itoa(ip.Port) + " (udp)"
		a = ip.IP
		v4 = a.To4() != nil
	}
	if ip, ok := w.RemoteAddr().(*net.TCPAddr); ok {
		str = "Port: " + strconv.Itoa(ip.Port) + " (tcp)"
		a = ip.IP
		v4 = a.To4() != nil
	}

	/*
		if o := r.IsEdns0(); o != nil {
			for _, s := range o.Option {
				switch e := s.(type) {
				case *dns.EDNS0_SUBNET:
					log.Printf("Edns0 subnet %s", e.Address)
				}
			}
		}
	*/

	if v4 {
		rr = new(dns.A)
		rr.(*dns.A).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 0}
		rr.(*dns.A).A = a.To4()
	} else {
		rr = new(dns.AAAA)
		rr.(*dns.AAAA).Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 0}
		rr.(*dns.AAAA).AAAA = a
	}

	t := new(dns.TXT)
	t.Hdr = dns.RR_Header{Name: dom, Rrtype: dns.TypeTXT, Class: dns.ClassINET, Ttl: 0}
	t.Txt = []string{str}

	switch r.Question[0].Qtype {
	case dns.TypeTXT:
		m.Answer = append(m.Answer, t)
		m.Extra = append(m.Extra, rr)
	default:
		fallthrough
	case dns.TypeAAAA, dns.TypeA:
		m.Answer = append(m.Answer, rr)
		m.Extra = append(m.Extra, t)
	}

	if r.IsTsig() != nil {
		if w.TsigStatus() == nil {
			m.SetTsig(r.Extra[len(r.Extra)-1].(*dns.TSIG).Hdr.Name, dns.HmacMD5, 300, time.Now().Unix())
		} else {
			println("Status", w.TsigStatus().Error())
		}
	}
	if *printf {
		fmt.Printf("%v\n", m.String())
	}
	w.WriteMsg(m)
}

func serve(net, name, secret string) {
	switch name {
	case "":
		err := dns.ListenAndServe(":8053", net, nil)
		if err != nil {
			fmt.Printf("Failed to setup the "+net+" server: %s\n", err.Error())
		}
	default:
		server := &dns.Server{Addr: ":8053", Net: net, TsigSecret: map[string]string{name: secret}}
		err := server.ListenAndServe()
		if err != nil {
			fmt.Printf("Failed to setup the "+net+" server: %s\n", err.Error())
		}
	}
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU()*4)
	cpuprofile := flag.String("cpuprofile", "", "write cpu profile to file")
	printf = flag.Bool("print", false, "print replies")
	compress = flag.Bool("compress", false, "compress replies")
	tsig = flag.String("tsig", "", "use MD5 hmac tsig: keyname:base64")
	var name, secret string
	flag.Usage = func() {
		flag.PrintDefaults()
	}
	flag.Parse()
	if *tsig != "" {
		a := strings.SplitN(*tsig, ":", 2)
		name, secret = dns.Fqdn(a[0]), a[1] // fqdn the name, which everybody forgets...
	}
	if *cpuprofile != "" {
		f, err := os.Create(*cpuprofile)
		if err != nil {
			log.Fatal(err)
		}
		pprof.StartCPUProfile(f)
		defer pprof.StopCPUProfile()
	}

	dns.HandleFunc("miek.nl.", handleReflect)
	dns.HandleFunc("authors.bind.", dns.HandleAuthors)
	dns.HandleFunc("authors.server.", dns.HandleAuthors)
	dns.HandleFunc("version.bind.", dns.HandleVersion)
	dns.HandleFunc("version.server.", dns.HandleVersion)
	go serve("tcp", name, secret)
	go serve("udp", name, secret)
	sig := make(chan os.Signal)
	signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
forever:
	for {
		select {
		case s := <-sig:
			fmt.Printf("Signal (%d) received, stopping\n", s)
			break forever
		}
	}
}
<|endoftext|>


<commit_before>
package main

import (
	"fmt"
	"log"
	"encoding/json"
	"net/rpc/jsonrpc"

	"github.com/hosom/gomandrake/filemeta"
	"github.com/natefinch/pie"
)

type HelloWorld struct {}

func (HelloWorld) Analyze(fmeta string, response *string) error {
	var fm filemeta.FileMeta
	json.Unmarshal([]byte(fmeta), &fm)
	log.Printf("Received call for Hello with name: %q", fm.Filepath)

	*response = fmt.Sprintf("{\"Hello\":%q}", fm.Filepath)

	return nil
}

func main () {
	log.SetPrefix("[helloworld]")
	p := pie.NewProvider()

	if err := p.RegisterName("HelloWorld", HelloWorld{}); err != nil {
		log.Fatalf("failed to register : %s", err)
	}
	p.ServeCodec(jsonrpc.NewServerCodec)
}
<commit_msg>fix logging prefix on HelloWorld<commit_after>
package main

import (
	"fmt"
	"log"
	"encoding/json"
	"net/rpc/jsonrpc"

	"github.com/hosom/gomandrake/filemeta"
	"github.com/natefinch/pie"
)

type HelloWorld struct {}

func (HelloWorld) Analyze(fmeta string, response *string) error {
	var fm filemeta.FileMeta
	json.Unmarshal([]byte(fmeta), &fm)
	log.Printf("Received call for Hello with name: %q", fm.Filepath)

	*response = fmt.Sprintf("{\"Hello\":%q}", fm.Filepath)

	return nil
}

func main () {
	log.SetPrefix("[helloworld] ")
	p := pie.NewProvider()

	if err := p.RegisterName("HelloWorld", HelloWorld{}); err != nil {
		log.Fatalf("failed to register : %s", err)
	}
	p.ServeCodec(jsonrpc.NewServerCodec)
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/marcusolsson/tui-go"
)

func main() {
	l := tui.NewList()
	l.SetFocused(true)
	l.AddItems("First row", "Second row", "Third row", "Fourth row", "Fifth row", "Sixth row")
	l.SetSelected(0)

	warning := tui.NewLabel("WARNING: This is a warning")
	warning.SetStyleName("warning")

	fatal := tui.NewLabel("FATAL: Cats and dogs are now living together.")
	fatal.SetStyleName("fatal")

	root := tui.NewVBox(l, warning, fatal)

	t := tui.NewTheme()
	t.SetStyle("list.item", tui.Style{Bg: tui.ColorCyan, Fg: tui.ColorMagenta})
	t.SetStyle("list.item.selected", tui.Style{Bg: tui.ColorRed, Fg: tui.ColorWhite})

	// The style name is appended to the widget name to support coloring of
	// individual labels.
	t.SetStyle("label.fatal", tui.Style{Bg: tui.ColorDefault, Fg: tui.ColorRed})
	t.SetStyle("label.warning", tui.Style{Bg: tui.ColorDefault, Fg: tui.ColorYellow})

	ui := tui.New(root)
	ui.SetTheme(t)
	ui.SetKeybinding("Esc", func() { ui.Quit() })

	if err := ui.Run(); err != nil {
		panic(err)
	}
}
<commit_msg>Demonstrate weird rendering with Painter.<commit_after>package main

import (
	"github.com/marcusolsson/tui-go"
)

func main() {
	okay := tui.NewLabel("Everything is fine.")

	l := tui.NewList()
	l.SetFocused(true)
	l.AddItems("First row", "Second row", "Third row", "Fourth row", "Fifth row", "Sixth row")
	l.SetSelected(0)

	warning := tui.NewLabel("WARNING: This is a warning")
	warning.SetStyleName("warning")

	fatal := tui.NewLabel("FATAL: Cats and dogs are now living together.")
	fatal.SetStyleName("fatal")

	okay2 := tui.NewLabel("Everything is still fine.")

	root := tui.NewVBox(okay, l, warning, fatal, okay2)

	t := tui.NewTheme()
	t.SetStyle("list.item", tui.Style{Bg: tui.ColorCyan, Fg: tui.ColorMagenta})
	t.SetStyle("list.item.selected", tui.Style{Bg: tui.ColorRed, Fg: tui.ColorWhite})

	// The style name is appended to the widget name to support coloring of
	// individual labels.
	t.SetStyle("label.fatal", tui.Style{Bg: tui.ColorDefault, Fg: tui.ColorRed})
	t.SetStyle("label.warning", tui.Style{Bg: tui.ColorDefault, Fg: tui.ColorYellow})

	normal := tui.Style{Bg: tui.ColorWhite, Fg: tui.ColorBlack}
	t.SetStyle("normal", normal)

	ui := tui.New(root)
	ui.SetTheme(t)
	ui.SetKeybinding("Esc", func() { ui.Quit() })

	if err := ui.Run(); err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/xitongsys/parquet-go/ParquetFile"
	"github.com/xitongsys/parquet-go/ParquetReader"
	"github.com/xitongsys/parquet-go/ParquetWriter"
	"log"
	"time"
)

type Student struct {
	Name   string  `parquet:"name=name, type=UTF8, encoding=PLAIN_DICTIONARY"`
	Age    int32   `parquet:"name=age, type=INT32"`
	Id     int64   `parquet:"name=id, type=INT64"`
	Weight float32 `parquet:"name=weight, type=FLOAT"`
	Sex    bool    `parquet:"name=sex, type=BOOLEAN"`
	Day    int32   `parquet:"name=day, type=DATE"`
}

func main() {
	fw, _ := ParquetFile.NewLocalFileWriter("flat.parquet")

	//write
	pw, _ := ParquetWriter.NewParquetWriter(fw, new(Student), 10)
	num := 100000000
	for i := 0; i < num; i++ {
		stu := Student{
			Name:   "StudentName",
			Age:    int32(20 + i%5),
			Id:     int64(i),
			Weight: float32(50.0 + float32(i)*0.1),
			Sex:    bool(i%2 == 0),
			Day:    int32(time.Now().Unix() / 3600 / 24),
		}
		pw.Write(stu)
	}
	pw.Flush(true)
	pw.WriteStop()
	log.Println("Write Finished")
	fw.Close()

	///read
	fr, _ := ParquetFile.NewLocalFileReader("flat.parquet")
	pr, err := ParquetReader.NewParquetReader(fr, new(Student), 4)
	if err != nil {
		log.Println("Failed new reader", err)
	}
	num = int(pr.GetNumRows())
	for i := 0; i < num; i++ {
		stus := make([]Student, 1)
		pr.Read(&stus)
		log.Println(stus)
	}

	pr.ReadStop()
	fr.Close()

}
<commit_msg>update example<commit_after>package main

import (
	"github.com/xitongsys/parquet-go/ParquetFile"
	"github.com/xitongsys/parquet-go/ParquetReader"
	"github.com/xitongsys/parquet-go/ParquetWriter"
	"log"
	"time"
)

type Student struct {
	Name   string  `parquet:"name=name, type=UTF8, encoding=PLAIN_DICTIONARY"`
	Age    int32   `parquet:"name=age, type=INT32"`
	Id     int64   `parquet:"name=id, type=INT64"`
	Weight float32 `parquet:"name=weight, type=FLOAT"`
	Sex    bool    `parquet:"name=sex, type=BOOLEAN"`
	Day    int32   `parquet:"name=day, type=DATE"`
}

func main() {
	fw, _ := ParquetFile.NewLocalFileWriter("flat.parquet")

	//write
	pw, _ := ParquetWriter.NewParquetWriter(fw, new(Student), 4)
	num := 10
	for i := 0; i < num; i++ {
		stu := Student{
			Name:   "StudentName",
			Age:    int32(20 + i%5),
			Id:     int64(i),
			Weight: float32(50.0 + float32(i)*0.1),
			Sex:    bool(i%2 == 0),
			Day:    int32(time.Now().Unix() / 3600 / 24),
		}
		pw.Write(stu)
	}
	pw.Flush(true)
	pw.WriteStop()
	log.Println("Write Finished")
	fw.Close()

	///read
	fr, _ := ParquetFile.NewLocalFileReader("flat.parquet")
	pr, err := ParquetReader.NewParquetReader(fr, new(Student), 4)
	if err != nil {
		log.Println("Failed new reader", err)
	}
	num = int(pr.GetNumRows())
	for i := 0; i < num; i++ {
		stus := make([]Student, 1)
		pr.Read(&stus)
		log.Println(stus)
	}

	pr.ReadStop()
	fr.Close()

}
<|endoftext|>


<commit_before>package diff

import (
	"bytes"
	"io"
	"os"
	"path/filepath"
)

func CompareFiles(file1, file2 string) (bool, error) {
	size := 1024 * 4
	buffer1, buffer2 := make([]byte, size), make([]byte, size)

	f1, err := os.Open(file1)
	if err != nil {
		return false, err
	}
	defer f1.Close()

	f2, err := os.Open(file2)
	if err != nil {
		return false, err
	}
	defer f2.Close()

	for {
		// Si hay error, se retorna
		n1, err := f1.Read(buffer1)
		if err != nil && err != io.EOF {
			return false, err
		}
		n2, err2 := f2.Read(buffer2)
		if err2 != nil && err2 != io.EOF {
			return false, err2
		}

		// Se llegó al final de ambos archivos.
		if err == io.EOF && err == err2 && n1 == n2 {
			return true, nil
		}

		// Se leyeron distintas cantidades, se llegó al final de uno.
		if n1 != n2 {
			return false, nil
		}

		result := bytes.Equal(buffer1, buffer2)
		if !result {
			return true, nil
		}
	}
}

func FindFilesIn(list []string, dirname string) []string {
	walkFunc := func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return nil
		}
		if !info.IsDir() {
			list = append(list, info.Name())
		}
		return nil
	}

	filepath.Walk(dirname, walkFunc)
	return list
}
<commit_msg>Avances<commit_after>package diff

import (
	"bytes"
	"io"
	"os"
	"path/filepath"
)

func CompareFiles(file1, file2 string) (bool, error) {
	size := 1024 * 4
	buffer1, buffer2 := make([]byte, size), make([]byte, size)

	f1, err := os.Open(file1)
	if err != nil {
		return false, err
	}
	defer f1.Close()

	f2, err := os.Open(file2)
	if err != nil {
		return false, err
	}
	defer f2.Close()

	for {
		// Si hay error, se retorna
		n1, err := f1.Read(buffer1)
		if err != nil && err != io.EOF {
			return false, err
		}
		n2, err2 := f2.Read(buffer2)
		if err2 != nil && err2 != io.EOF {
			return false, err2
		}

		// Se llegó al final de ambos archivos.
		if err == io.EOF && err == err2 && n1 == n2 {
			return true, nil
		}

		// Se leyeron distintas cantidades, se llegó al final de uno.
		if n1 != n2 {
			return false, nil
		}

		result := bytes.Equal(buffer1, buffer2)
		if !result {
			return true, nil
		}
	}
}

func FindFilesIn(list []string, dirname string) []string {
	walkFunc := func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return nil
		}

		if !info.IsDir() {
			list = append(list, path)
		}
		return nil
	}

	filepath.Walk(dirname, walkFunc)
	return list
}
<|endoftext|>


<commit_before>package should

import (
	"fmt"
	"net/http"
)

// MatchHTTPStatusCode asserts that the documented and actual HTTP status codes match
func MatchHTTPStatusCode(actual interface{}, expected ...interface{}) (fail string) {
	if msg := exactly(1, expected); msg != Ok {
		return msg
	}
	eStatus, ok := expected[0].(int)
	if !ok {
		return "Actual value should be an integer"
	}
	aRsp, ok := actual.(*http.Response)
	if !ok {
		return "Actual value should be a *http.Response"
	}
	aStatus := aRsp.StatusCode
	if aStatus == eStatus {
		return ""
	}

	return fmt.Sprintf(
		"HTTP Status Expected: %d %s. Got: %d %s. \nRequest: %#v.\nResponse: %#v.",
		eStatus, http.StatusText(eStatus),
		aStatus, http.StatusText(aStatus),
		aRsp.Request, aRsp,
	)
}
<commit_msg>Fixed http status code assertion<commit_after>package should

import (
	"fmt"
	"net/http"
)

// MatchHTTPStatusCode asserts that the documented and actual HTTP status codes match
func MatchHTTPStatusCode(actual interface{}, expected ...interface{}) (fail string) {
	if msg := exactly(1, expected); msg != Ok {
		return msg
	}
	eStatus, ok := expected[0].(int64)
	if !ok {
		return fmt.Sprintf("Expected value should be an integer, not a %T.", expected[0])
	}
	aRsp, ok := actual.(*http.Response)
	if !ok {
		return "Actual value should be a *http.Response"
	}
	aStatus := aRsp.StatusCode
	if aStatus == int(eStatus) {
		return ""
	}

	return fmt.Sprintf(
		"HTTP Status Expected: %d %s. Got: %d %s. \nRequest: %#v.\nResponse: %#v.",
		eStatus, http.StatusText(int(eStatus)),
		aStatus, http.StatusText(aStatus),
		aRsp.Request, aRsp,
	)
}
<|endoftext|>


<commit_before>package lua

import (
	"database/sql"
	"github.com/kkserver/kk-direct/direct"
	"github.com/kkserver/kk-lib/kk/dynamic"
	"github.com/kkserver/kk-lib/kk/json"
	"github.com/kkserver/kk-lua/lua"
	"log"
	"reflect"
	"strings"
)

var dbs = map[string]*sql.DB{}

var LuaKeys = []string{"lua"}

func ContextOpenlib(ctx direct.IContext) {

	L := lua.NewState()
	L.Openlibs()

	L.PushFunction(func(L *lua.State) int {

		keys := []string{}
		top := L.GetTop()

		for i := 0; i < top; i++ {
			keys = append(keys, L.ToString(-top+i))
		}

		vv := ctx.Get(keys)

		L.PushObject(vv)

		return 1
	})

	L.SetGlobal("get")

	L.PushFunction(func(L *lua.State) int {

		keys := []string{}
		top := L.GetTop()

		for i := 0; i < top; i++ {
			keys = append(keys, L.ToString(-top+i))
		}

		vv := ctx.Get(keys)

		L.PushString(dynamic.StringValue(vv, ""))

		return 1
	})

	L.SetGlobal("getString")

	L.PushFunction(func(L *lua.State) int {

		keys := []string{}
		top := L.GetTop()

		for i := 0; i < top; i++ {
			keys = append(keys, L.ToString(-top+i))
		}

		vv := ctx.Get(keys)

		L.PushInteger(dynamic.IntValue(vv, 0))

		return 1
	})

	L.SetGlobal("getInteger")

	L.PushFunction(func(L *lua.State) int {

		keys := []string{}
		top := L.GetTop()

		for i := 0; i < top; i++ {
			keys = append(keys, L.ToString(-top+i))
		}

		vv := ctx.Get(keys)

		L.PushNumber(dynamic.FloatValue(vv, 0))

		return 1
	})

	L.SetGlobal("getNumber")

	L.PushFunction(func(L *lua.State) int {

		keys := []string{}
		top := L.GetTop()

		for i := 0; i < top; i++ {
			keys = append(keys, L.ToString(-top+i))
		}

		vv := ctx.Get(keys)

		L.PushBoolean(dynamic.BooleanValue(vv, false))

		return 1
	})

	L.SetGlobal("getBoolean")

	L.NewTable()

	L.PushString("encode")
	L.PushFunction(func(L *lua.State) int {

		keys := []string{}
		top := L.GetTop()

		for i := 0; i < top; i++ {
			keys = append(keys, L.ToString(-top+i))
		}

		vv := ctx.Get(keys)

		b, _ := json.Encode(vv)

		L.PushString(string(b))

		return 1
	})
	L.RawSet(-3)

	L.PushString("decode")
	L.PushFunction(func(L *lua.State) int {

		keys := []string{}
		top := L.GetTop()

		for i := 0; i < top; i++ {
			keys = append(keys, L.ToString(-top+i))
		}

		vv := ctx.Get(keys)

		var v interface{} = nil

		err := json.Decode([]byte(dynamic.StringValue(vv, "{}")), &v)

		log.Println(vv, keys)

		if err != nil {
			L.PushString(err.Error())
		} else {
			L.PushObject(v)
		}

		return 1
	})
	L.RawSet(-3)

	L.SetGlobal("json")

	L.NewTable()

	L.PushString("query")
	L.PushFunction(func(L *lua.State) int {

		top := L.GetTop()

		if top > 1 {

			name := L.ToString(-top)
			s := L.ToString(-top + 1)
			args := []interface{}{}

			db, ok := dbs[name]

			var err error

			if !ok {

				idx := strings.Index(name, "://")

				if idx > 0 {

					db, err = sql.Open(name[:idx], name[idx+3:])

					if err != nil {
						log.Println("LUA db.query", "fail", err)
						L.NewTable()
						return 1
					} else {
						db.SetMaxIdleConns(6)
						db.SetMaxOpenConns(20)
						dbs[name] = db
					}

				} else {
					log.Println("LUA db.query", "fail", name)
					L.NewTable()
					return 1
				}

			}

			for i := 2; i < top; i++ {
				args = append(args, L.ToObject(-top+i))
			}

			log.Println("SQL", s, args)

			rows, err := db.Query(s, args...)

			if err != nil {
				log.Println("LUA db.query", "fail", err)
				log.Println("SQL", s, args)
				L.NewTable()
				return 1
			}

			defer rows.Close()

			var columns []string = nil

			columns, err = rows.Columns()

			if err != nil {
				log.Println("LUA db.query", "fail", err)
				L.NewTable()
				return 1
			}

			var values = make([]sql.NullString, len(columns))
			var refs = make([]interface{}, len(columns))

			for i, _ := range columns {
				refs[i] = &values[i]
			}

			L.NewTable()

			idx := int64(1)

			for rows.Next() {

				err = rows.Scan(refs...)

				if err != nil {
					log.Println("LUA db.query", "fail", err)
					return 1
				}

				log.Println(values)

				L.PushInteger(idx)
				L.NewTable()

				for i, name := range columns {
					vv := values[i]
					if vv.Valid {
						L.PushString(name)
						L.PushString(vv.String)
						L.RawSet(-3)
					}
				}

				L.RawSet(-3)

				idx = idx + 1
			}

			return 1
		}

		return 1
	})

	L.RawSet(-3)

	L.SetGlobal("db")

	ctx.Set(LuaKeys, L)
}

func ContextCloselib(ctx direct.IContext) {
	v := ctx.Get(LuaKeys)
	if v != nil {
		L, ok := v.(*lua.State)
		if ok {
			L.Close()
		}
		ctx.Set(LuaKeys, nil)
	}
}

func Openlib() {
	direct.UseWithType("^lua", reflect.TypeOf(Direct{}))
}
<commit_msg>Fix bug<commit_after>package lua

import (
	"database/sql"
	_ "github.com/go-sql-driver/mysql"
	"github.com/kkserver/kk-direct/direct"
	"github.com/kkserver/kk-lib/kk/dynamic"
	"github.com/kkserver/kk-lib/kk/json"
	"github.com/kkserver/kk-lua/lua"
	"log"
	"reflect"
	"strings"
)

var dbs = map[string]*sql.DB{}

var LuaKeys = []string{"lua"}

func ContextOpenlib(ctx direct.IContext) {

	L := lua.NewState()
	L.Openlibs()

	L.PushFunction(func(L *lua.State) int {

		keys := []string{}
		top := L.GetTop()

		for i := 0; i < top; i++ {
			keys = append(keys, L.ToString(-top+i))
		}

		vv := ctx.Get(keys)

		L.PushObject(vv)

		return 1
	})

	L.SetGlobal("get")

	L.PushFunction(func(L *lua.State) int {

		keys := []string{}
		top := L.GetTop()

		for i := 0; i < top; i++ {
			keys = append(keys, L.ToString(-top+i))
		}

		vv := ctx.Get(keys)

		L.PushString(dynamic.StringValue(vv, ""))

		return 1
	})

	L.SetGlobal("getString")

	L.PushFunction(func(L *lua.State) int {

		keys := []string{}
		top := L.GetTop()

		for i := 0; i < top; i++ {
			keys = append(keys, L.ToString(-top+i))
		}

		vv := ctx.Get(keys)

		L.PushInteger(dynamic.IntValue(vv, 0))

		return 1
	})

	L.SetGlobal("getInteger")

	L.PushFunction(func(L *lua.State) int {

		keys := []string{}
		top := L.GetTop()

		for i := 0; i < top; i++ {
			keys = append(keys, L.ToString(-top+i))
		}

		vv := ctx.Get(keys)

		L.PushNumber(dynamic.FloatValue(vv, 0))

		return 1
	})

	L.SetGlobal("getNumber")

	L.PushFunction(func(L *lua.State) int {

		keys := []string{}
		top := L.GetTop()

		for i := 0; i < top; i++ {
			keys = append(keys, L.ToString(-top+i))
		}

		vv := ctx.Get(keys)

		L.PushBoolean(dynamic.BooleanValue(vv, false))

		return 1
	})

	L.SetGlobal("getBoolean")

	L.NewTable()

	L.PushString("encode")
	L.PushFunction(func(L *lua.State) int {

		keys := []string{}
		top := L.GetTop()

		for i := 0; i < top; i++ {
			keys = append(keys, L.ToString(-top+i))
		}

		vv := ctx.Get(keys)

		b, _ := json.Encode(vv)

		L.PushString(string(b))

		return 1
	})
	L.RawSet(-3)

	L.PushString("decode")
	L.PushFunction(func(L *lua.State) int {

		keys := []string{}
		top := L.GetTop()

		for i := 0; i < top; i++ {
			keys = append(keys, L.ToString(-top+i))
		}

		vv := ctx.Get(keys)

		var v interface{} = nil

		err := json.Decode([]byte(dynamic.StringValue(vv, "{}")), &v)

		log.Println(vv, keys)

		if err != nil {
			L.PushString(err.Error())
		} else {
			L.PushObject(v)
		}

		return 1
	})
	L.RawSet(-3)

	L.SetGlobal("json")

	L.NewTable()

	L.PushString("query")
	L.PushFunction(func(L *lua.State) int {

		top := L.GetTop()

		if top > 1 {

			name := L.ToString(-top)
			s := L.ToString(-top + 1)
			args := []interface{}{}

			db, ok := dbs[name]

			var err error

			if !ok {

				idx := strings.Index(name, "://")

				if idx > 0 {

					db, err = sql.Open(name[:idx], name[idx+3:])

					if err != nil {
						log.Println("LUA db.query", "fail", err)
						L.NewTable()
						return 1
					} else {
						db.SetMaxIdleConns(6)
						db.SetMaxOpenConns(20)
						dbs[name] = db
					}

				} else {
					log.Println("LUA db.query", "fail", name)
					L.NewTable()
					return 1
				}

			}

			for i := 2; i < top; i++ {
				args = append(args, L.ToObject(-top+i))
			}

			log.Println("SQL", s, args)

			rows, err := db.Query(s, args...)

			if err != nil {
				log.Println("LUA db.query", "fail", err)
				log.Println("SQL", s, args)
				L.NewTable()
				return 1
			}

			defer rows.Close()

			var columns []string = nil

			columns, err = rows.Columns()

			if err != nil {
				log.Println("LUA db.query", "fail", err)
				L.NewTable()
				return 1
			}

			var values = make([]sql.NullString, len(columns))
			var refs = make([]interface{}, len(columns))

			for i, _ := range columns {
				refs[i] = &values[i]
			}

			L.NewTable()

			idx := int64(1)

			for rows.Next() {

				err = rows.Scan(refs...)

				if err != nil {
					log.Println("LUA db.query", "fail", err)
					return 1
				}

				log.Println(values)

				L.PushInteger(idx)
				L.NewTable()

				for i, name := range columns {
					vv := values[i]
					if vv.Valid {
						L.PushString(name)
						L.PushString(vv.String)
						L.RawSet(-3)
					}
				}

				L.RawSet(-3)

				idx = idx + 1
			}

			return 1
		}

		return 1
	})

	L.RawSet(-3)

	L.SetGlobal("db")

	ctx.Set(LuaKeys, L)
}

func ContextCloselib(ctx direct.IContext) {
	v := ctx.Get(LuaKeys)
	if v != nil {
		L, ok := v.(*lua.State)
		if ok {
			L.Close()
		}
		ctx.Set(LuaKeys, nil)
	}
}

func Openlib() {
	direct.UseWithType("^lua", reflect.TypeOf(Direct{}))
}
<|endoftext|>


<commit_before>package tflint

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"sync"

	"github.com/hashicorp/hcl2/hcl"
	"github.com/hashicorp/terraform/addrs"
	"github.com/hashicorp/terraform/configs"
	"github.com/hashicorp/terraform/lang"
	"github.com/hashicorp/terraform/terraform"
	"github.com/wata727/tflint/config"
	"github.com/wata727/tflint/issue"
	"github.com/wata727/tflint/logger"
	"github.com/wata727/tflint/state"
	"github.com/zclconf/go-cty/cty"
	"github.com/zclconf/go-cty/cty/convert"
	"github.com/zclconf/go-cty/cty/gocty"
)

// Runner checks templates according rules.
// For variables interplation, it has Terraform eval context,
// and state. After checking, it accumulates results as issues.
type Runner struct {
	TFConfig *configs.Config
	Issues   issue.Issues

	ctx    terraform.BuiltinEvalContext
	state  state.TFState
	config *config.Config
	logger *logger.Logger
}

// NewRunner returns new TFLint runner
// TODO: Generate variables from configs
func NewRunner(cfg *configs.Config) *Runner {
	return &Runner{
		ctx: terraform.BuiltinEvalContext{
			Evaluator: &terraform.Evaluator{
				Config:             cfg,
				VariableValues:     map[string]map[string]cty.Value{},
				VariableValuesLock: &sync.Mutex{},
			},
		},
		TFConfig: cfg,
		Issues:   []*issue.Issue{},
	}
}

// EvaluateExpr is a wrapper of terraform.BultinEvalContext.EvaluateExpr and gocty.FromCtyValue
// When it received slice as `ret`, it converts cty.Value to expected list type
// because raw cty.Value has TupleType.
func (r *Runner) EvaluateExpr(expr hcl.Expression, ret interface{}) error {
	if !isEvaluable(expr) {
		return &Error{
			Code: UnevaluableError,
			Message: fmt.Sprintf(
				"Unevaluable expression found in %s:%d",
				expr.Range().Filename,
				expr.Range().Start.Line,
			),
		}
	}

	val, diags := r.ctx.EvaluateExpr(expr, cty.DynamicPseudoType, nil)
	if diags.HasErrors() {
		return &Error{
			Code: EvaluationError,
			Message: fmt.Sprintf(
				"Failed to eval an expression in %s:%d",
				expr.Range().Filename,
				expr.Range().Start.Line,
			),
			Cause: diags.Err(),
		}
	}

	if !val.IsKnown() {
		return &Error{
			Code: UnknownValueError,
			Message: fmt.Sprintf(
				"Unknown value found in %s:%d; Please use environment variables or tfvars to set the value",
				expr.Range().Filename,
				expr.Range().Start.Line,
			),
		}
	}

	var err error
	switch ret.(type) {
	case *string:
		val, err = convert.Convert(val, cty.String)
	case *int:
		val, err = convert.Convert(val, cty.Number)
	case *[]string:
		val, err = convert.Convert(val, cty.List(cty.String))
	case *[]int:
		val, err = convert.Convert(val, cty.List(cty.Number))
	}

	if err != nil {
		return &Error{
			Code: TypeConversionError,
			Message: fmt.Sprintf(
				"Invalid type expression in %s:%d",
				expr.Range().Filename,
				expr.Range().Start.Line,
			),
			Cause: err,
		}
	}

	err = gocty.FromCtyValue(val, ret)
	if err != nil {
		return &Error{
			Code: TypeMismatchError,
			Message: fmt.Sprintf(
				"Invalid type expression in %s:%d",
				expr.Range().Filename,
				expr.Range().Start.Line,
			),
			Cause: err,
		}
	}
	return nil
}

func isEvaluable(expr hcl.Expression) bool {
	refs, diags := lang.ReferencesInExpr(expr)
	if diags.HasErrors() {
		panic(diags.Err())
	}
	for _, ref := range refs {
		switch ref.Subject.(type) {
		case addrs.InputVariable:
			// noop
		case addrs.TerraformAttr:
			// noop
		default:
			return false
		}
	}
	return true
}

func getWorkspace() string {
	if envVar := os.Getenv("TF_WORKSPACE"); envVar != "" {
		return envVar
	}

	envData, _ := ioutil.ReadFile(".terraform/environment")
	current := string(bytes.TrimSpace(envData))
	if current == "" {
		current = "default"
	}

	return current
}
<commit_msg>Add workspace metadata<commit_after>package tflint

import (
	"bytes"
	"fmt"
	"io/ioutil"
	"os"
	"sync"

	"github.com/hashicorp/hcl2/hcl"
	"github.com/hashicorp/terraform/addrs"
	"github.com/hashicorp/terraform/configs"
	"github.com/hashicorp/terraform/lang"
	"github.com/hashicorp/terraform/terraform"
	"github.com/wata727/tflint/config"
	"github.com/wata727/tflint/issue"
	"github.com/wata727/tflint/logger"
	"github.com/wata727/tflint/state"
	"github.com/zclconf/go-cty/cty"
	"github.com/zclconf/go-cty/cty/convert"
	"github.com/zclconf/go-cty/cty/gocty"
)

// Runner checks templates according rules.
// For variables interplation, it has Terraform eval context,
// and state. After checking, it accumulates results as issues.
type Runner struct {
	TFConfig *configs.Config
	Issues   issue.Issues

	ctx    terraform.BuiltinEvalContext
	state  state.TFState
	config *config.Config
	logger *logger.Logger
}

// NewRunner returns new TFLint runner
// TODO: Generate variables from configs
func NewRunner(cfg *configs.Config) *Runner {
	return &Runner{
		ctx: terraform.BuiltinEvalContext{
			Evaluator: &terraform.Evaluator{
				Meta: &terraform.ContextMeta{
					Env: getWorkspace(),
				},
				Config:             cfg,
				VariableValues:     map[string]map[string]cty.Value{},
				VariableValuesLock: &sync.Mutex{},
			},
		},
		TFConfig: cfg,
		Issues:   []*issue.Issue{},
	}
}

// EvaluateExpr is a wrapper of terraform.BultinEvalContext.EvaluateExpr and gocty.FromCtyValue
// When it received slice as `ret`, it converts cty.Value to expected list type
// because raw cty.Value has TupleType.
func (r *Runner) EvaluateExpr(expr hcl.Expression, ret interface{}) error {
	if !isEvaluable(expr) {
		return &Error{
			Code: UnevaluableError,
			Message: fmt.Sprintf(
				"Unevaluable expression found in %s:%d",
				expr.Range().Filename,
				expr.Range().Start.Line,
			),
		}
	}

	val, diags := r.ctx.EvaluateExpr(expr, cty.DynamicPseudoType, nil)
	if diags.HasErrors() {
		return &Error{
			Code: EvaluationError,
			Message: fmt.Sprintf(
				"Failed to eval an expression in %s:%d",
				expr.Range().Filename,
				expr.Range().Start.Line,
			),
			Cause: diags.Err(),
		}
	}

	if !val.IsKnown() {
		return &Error{
			Code: UnknownValueError,
			Message: fmt.Sprintf(
				"Unknown value found in %s:%d; Please use environment variables or tfvars to set the value",
				expr.Range().Filename,
				expr.Range().Start.Line,
			),
		}
	}

	var err error
	switch ret.(type) {
	case *string:
		val, err = convert.Convert(val, cty.String)
	case *int:
		val, err = convert.Convert(val, cty.Number)
	case *[]string:
		val, err = convert.Convert(val, cty.List(cty.String))
	case *[]int:
		val, err = convert.Convert(val, cty.List(cty.Number))
	}

	if err != nil {
		return &Error{
			Code: TypeConversionError,
			Message: fmt.Sprintf(
				"Invalid type expression in %s:%d",
				expr.Range().Filename,
				expr.Range().Start.Line,
			),
			Cause: err,
		}
	}

	err = gocty.FromCtyValue(val, ret)
	if err != nil {
		return &Error{
			Code: TypeMismatchError,
			Message: fmt.Sprintf(
				"Invalid type expression in %s:%d",
				expr.Range().Filename,
				expr.Range().Start.Line,
			),
			Cause: err,
		}
	}
	return nil
}

func isEvaluable(expr hcl.Expression) bool {
	refs, diags := lang.ReferencesInExpr(expr)
	if diags.HasErrors() {
		panic(diags.Err())
	}
	for _, ref := range refs {
		switch ref.Subject.(type) {
		case addrs.InputVariable:
			// noop
		case addrs.TerraformAttr:
			// noop
		default:
			return false
		}
	}
	return true
}

func getWorkspace() string {
	if envVar := os.Getenv("TF_WORKSPACE"); envVar != "" {
		return envVar
	}

	envData, _ := ioutil.ReadFile(".terraform/environment")
	current := string(bytes.TrimSpace(envData))
	if current == "" {
		current = "default"
	}

	return current
}
<|endoftext|>


<commit_before>package imjasonh

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"image"
	"image/color"
	"image/png"
	"log"
	"net/http"
)

const rgb8to16 = 0x101 // Multiply an 8-bit RGB value to 16-bit

const perlerForm = `

  <form method="POST" action="/perler" enctype="multipart/form-data">
    Select a PNG file
    <input type="file" name="file" id="file" accept="image/png"></input>
    <input type="submit" name="submit" value="Submit"></input>
  </form>

`

const perlerOut = `

Exciting!

`

func init() {
	http.HandleFunc("/perler", perlerHandler)
}

func perlerHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" {
		w.Write([]byte(perlerForm))
		return
	}

	mpf, _, err := r.FormFile("file")
	if err != nil {
		log.Fatal(err)
	}
	defer mpf.Close()

	img, err := png.Decode(mpf)
	if err != nil {
		log.Fatal(err)
	}

	// Make a palette out of all the possible bead colors
	var palette color.Palette
	for k, _ := range paletteMap {
		palette = append(palette, k)
	}
	paletted := palettedImage{img, palette}
	buf := bytes.NewBuffer(make([]byte, 0, 10000)) // TODO
	png.Encode(buf, paletted)
	dataURI := fmt.Sprintf("data:image/png;base64,%s", base64.StdEncoding.EncodeToString(buf.Bytes()))
	w.Write([]byte(fmt.Sprintf(perlerOut, dataURI)))
}

type palettedImage struct {
	orig    image.Image
	palette color.Palette
}

func (p palettedImage) ColorIndexAt(x, y int) uint8 {
	return uint8(p.palette.Index(p.orig.At(x, y)))
}
func (p palettedImage) At(x, y int) color.Color {
	return convert(p.palette, p.orig.At(x, y))
}
func (p palettedImage) Bounds() image.Rectangle {
	return p.orig.Bounds()
}
func (p palettedImage) ColorModel() color.Model {
	return color.ModelFunc(func(in color.Color) color.Color {
		return convert(p.palette, in)
	})
}
func convert(p color.Palette, c color.Color) color.Color {
	_, _, _, a := c.RGBA()
	if a == 0 {
		return color.Transparent
	}
	return p.Convert(c)
}

type myColor struct {
	r, g, b uint32
}

func (m myColor) RGBA() (r, g, b, a uint32) {
	return m.r * rgb8to16,
		m.g * rgb8to16,
		m.b * rgb8to16,
		255 * rgb8to16
}
func col(r, g, b uint32) color.Color {
	return myColor{r, g, b}
}

// Map of available Perler bead colors to their name
// From https://sites.google.com/site/degenatrons/other-stuff/bead-pattern-generator
var paletteMap = map[color.Color]string{
	// Perler bead colors
	col(255, 255, 255): "P01-WHITE",
	col(240, 230, 195): "P02-CREAM",
	col(255, 235, 55):  "P03-YELLOW",
	col(255, 115, 80):  "P04-ORANGE",
	col(205, 70, 90):   "P05-RED",
	col(240, 130, 175): "P06-BUBBLE-GUM",
	col(120, 95, 155):  "P07-PURPLE",
	col(35, 80, 145):   "P08-DARK-BLUE",
	col(45, 130, 200):  "P09-LIGHT-BLUE",
	col(40, 140, 100):  "P10-DARK-GREEN",
	col(75, 195, 180):  "P11-LIGHT-GREEN",
	col(110, 90, 85):   "P12-BROWN",
	col(150, 155, 160): "P17-GREY",
	col(0, 0, 0):       "P18-BLACK",
	col(165, 90, 90):   "P20-RUST",
	col(160, 130, 95):  "P21-LIGHT-BROWN",
	col(250, 205, 195): "P33-PEACH",
	col(205, 165, 135): "P35-TAN",
	col(255, 60, 130):  "P38-MAGENTA",
	col(90, 160, 205):  "P52-PASTEL-BLUE",
	col(135, 210, 145): "P53-PASTEL-GREEN",
	col(155, 135, 205): "P54-PASTEL-LAVENDER",
	col(215, 155, 200): "P55-PASTEL-PINK",
	col(245, 240, 155): "P56-PASTEL-YELLOW",
	col(250, 200, 85):  "P57-CHEDDAR",
	col(160, 215, 225): "P58-TOOTHPASTE",
	col(255, 90, 115):  "P59-HOT-CORAL",
	col(175, 90, 160):  "P60-PLUM",
	col(125, 210, 80):  "P61-KIWI-LIME",
	col(5, 150, 205):   "P62-TURQUOISE",
	col(255, 150, 160): "P63-BLUSH",
	col(85, 125, 185):  "P70-PERIWINKLE",
	col(245, 200, 230): "P79-LIGHT-PINK",
	col(115, 185, 115): "P80-BRIGHT-GREEN",
	col(240, 95, 165):  "P83-PINK",
	col(190, 70, 115):  "P88-RASPBERRY",
	col(240, 150, 110): "P90-BUTTERSCOTCH",
	col(0, 150, 165):   "P91-PARROT-GREEN",
	col(95, 100, 100):  "P92-DARK-GREY",

	// Hama bead colors
	col(250, 240, 195): "H02-CREAM",
	col(255, 215, 90):  "H03-YELLOW",
	col(240, 105, 95):  "H04-ORANGE",
	col(245, 155, 175): "H06-PINK",
	col(35, 85, 160):   "H08-BLUE",
	col(120, 90, 145):  "H07-PURPLE",
	col(25, 105, 180):  "H09-LIGHT-BLUE",
	col(35, 125, 95):   "H10-GREEN",
	col(70, 195, 165):  "H11-LIGHT-GREEN",
	col(100, 75, 80):   "H12-BROWN",
	col(145, 150, 155): "H17-GREY",
	col(170, 85, 80):   "H20-BROWN",
	col(190, 130, 100): "H21-LIGHT-BROWN",
	col(175, 75, 85):   "H22-DARK-RED",
	col(240, 170, 165): "H26-FLESH",
	col(225, 185, 150): "H27-BEIGE",
	col(70, 85, 90):    "H28-DARK-GREEN",
	col(195, 80, 115):  "H29-RASPBERRY",
	col(115, 75, 85):   "H30-BURGUNDY",
	col(105, 160, 175): "H31-TURQUOISE",
	col(255, 95, 200):  "H32-FUCHSIA",
	col(245, 240, 125): "H43-PASTEL-YELLOW",
	col(255, 120, 140): "H44-PASTEL-CORAL",
	col(165, 140, 205): "H45-PASTEL-PURPLE",
	col(80, 170, 225):  "H46-PASTEL-BLUE",
	col(150, 230, 160): "H47-PASTEL-GREEN",
	col(230, 135, 200): "H48-PASTEL-PINK",
	col(240, 175, 95):  "H60-TEDDY-BEAR",

	// Nabbi bead colors
	col(90, 85, 80):    "N02-DARK-BROWN",
	col(105, 75, 80):   "N03-BROWN-MEDIUM",
	col(150, 85, 100):  "N04-WINE-RED",
	col(190, 125, 85):  "N05-BUTTERSCOTCH",
	col(185, 160, 145): "N06-BEIGE",
	col(240, 195, 150): "N07-SKIN",
	col(160, 160, 155): "N08-ASH-GREY",
	col(70, 100, 90):   "N09-DARK-GREEN",
	col(230, 225, 225): "N10-LIGHT-GREY",
	col(115, 90, 155):  "N11-PURPLE",
	col(245, 225, 215): "N12-IVORY",
	col(255, 210, 75):  "N14-YELLOW",
	col(50, 145, 100):  "N16-GREEN",
	col(0, 120, 210):   "N17-BLUE",
	col(245, 200, 190): "N18-LIGHT-PINK",
	col(215, 65, 85):   "N19-LIGHT-RED",
	col(210, 155, 125): "N20-LIGHT-BROWN",
	col(255, 245, 175): "N21-LIGHT-YELLOW",
	col(55, 170, 100):  "N22-PEARL-GREEN",
	col(90, 170, 235):  "N23-PASTEL-BLUE",
	col(200, 185, 240): "N24-LILAC",
	col(255, 120, 165): "N25-OLD-ROSE",
	col(255, 185, 150): "N26-LIGHT-ORANGE",
	col(145, 105, 100): "N27-BROWN",
	col(160, 205, 245): "N28-LIGHT-BLUE",
	col(225, 160, 85):  "N29-PEARL-ORANGE",
	col(200, 200, 120): "N30-OLIVE",
}
<commit_msg>Resize the input image and show pixels<commit_after>package imjasonh

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"image"
	"image/color"
	"image/png"
	"log"
	"net/http"
)

const (
	rgb8to16 = 0x101 // Multiply an 8-bit RGB value to 16-bit

	bufSize = 2 << 17 // 256K
)

const perlerForm = `

  <form method="POST" action="/perler" enctype="multipart/form-data">
    Select a PNG file
    <input type="file" name="file" id="file" accept="image/png"></input>
    <input type="submit" name="submit" value="Submit"></input>
  </form>

`

const perlerOut = `

`

func init() {
	http.HandleFunc("/perler", perlerHandler)
}

func perlerHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method == "GET" {
		w.Write([]byte(perlerForm))
		return
	}

	mpf, _, err := r.FormFile("file")
	if err != nil {
		log.Fatal(err)
	}
	defer mpf.Close()

	img, err := png.Decode(mpf)
	if err != nil {
		log.Fatal(err)
	}

	// Make a palette out of all the possible bead colors
	var palette color.Palette
	for k, _ := range paletteMap {
		palette = append(palette, k)
	}
	paletted := palettedImage{img, palette}

	resized := resizedImage{paletted, 5, true}

	buf := bytes.NewBuffer(make([]byte, 0, bufSize))
	png.Encode(buf, resized)
	dataURI := fmt.Sprintf("data:image/png;base64,%s", base64.StdEncoding.EncodeToString(buf.Bytes()))
	w.Write([]byte(fmt.Sprintf(perlerOut, dataURI)))
}

type resizedImage struct {
	orig      image.Image
	factor    int
	delineate bool
}

func (r resizedImage) ColorModel() color.Model {
	return r.orig.ColorModel()
}

func (r resizedImage) Bounds() image.Rectangle {
	return image.Rectangle{r.orig.Bounds().Min, image.Point{
		X: r.orig.Bounds().Max.X * r.factor,
		Y: r.orig.Bounds().Max.Y * r.factor,
	}}
}

func (r resizedImage) At(x, y int) color.Color {
	if r.delineate && (x%r.factor == 0 || y%r.factor == 0) {
		return color.Gray{0}
	}
	return r.orig.At(x/r.factor, y/r.factor)
}

type palettedImage struct {
	orig    image.Image
	palette color.Palette
}

func (p palettedImage) ColorIndexAt(x, y int) uint8 {
	return uint8(p.palette.Index(p.orig.At(x, y)))
}
func (p palettedImage) At(x, y int) color.Color {
	return convert(p.palette, p.orig.At(x, y))
}
func (p palettedImage) Bounds() image.Rectangle {
	return p.orig.Bounds()
}
func (p palettedImage) ColorModel() color.Model {
	return color.ModelFunc(func(in color.Color) color.Color {
		return convert(p.palette, in)
	})
}
func convert(p color.Palette, c color.Color) color.Color {
	_, _, _, a := c.RGBA()
	if a == 0 {
		return color.Transparent
	}
	return p.Convert(c)
}

type myColor struct {
	r, g, b uint32
}

func (m myColor) RGBA() (r, g, b, a uint32) {
	return m.r * rgb8to16,
		m.g * rgb8to16,
		m.b * rgb8to16,
		255 * rgb8to16
}
func col(r, g, b uint32) color.Color {
	return myColor{r, g, b}
}

// Map of available Perler bead colors to their name
// From https://sites.google.com/site/degenatrons/other-stuff/bead-pattern-generator
var paletteMap = map[color.Color]string{
	// Perler bead colors
	col(255, 255, 255): "P01-WHITE",
	col(240, 230, 195): "P02-CREAM",
	col(255, 235, 55):  "P03-YELLOW",
	col(255, 115, 80):  "P04-ORANGE",
	col(205, 70, 90):   "P05-RED",
	col(240, 130, 175): "P06-BUBBLE-GUM",
	col(120, 95, 155):  "P07-PURPLE",
	col(35, 80, 145):   "P08-DARK-BLUE",
	col(45, 130, 200):  "P09-LIGHT-BLUE",
	col(40, 140, 100):  "P10-DARK-GREEN",
	col(75, 195, 180):  "P11-LIGHT-GREEN",
	col(110, 90, 85):   "P12-BROWN",
	col(150, 155, 160): "P17-GREY",
	col(0, 0, 0):       "P18-BLACK",
	col(165, 90, 90):   "P20-RUST",
	col(160, 130, 95):  "P21-LIGHT-BROWN",
	col(250, 205, 195): "P33-PEACH",
	col(205, 165, 135): "P35-TAN",
	col(255, 60, 130):  "P38-MAGENTA",
	col(90, 160, 205):  "P52-PASTEL-BLUE",
	col(135, 210, 145): "P53-PASTEL-GREEN",
	col(155, 135, 205): "P54-PASTEL-LAVENDER",
	col(215, 155, 200): "P55-PASTEL-PINK",
	col(245, 240, 155): "P56-PASTEL-YELLOW",
	col(250, 200, 85):  "P57-CHEDDAR",
	col(160, 215, 225): "P58-TOOTHPASTE",
	col(255, 90, 115):  "P59-HOT-CORAL",
	col(175, 90, 160):  "P60-PLUM",
	col(125, 210, 80):  "P61-KIWI-LIME",
	col(5, 150, 205):   "P62-TURQUOISE",
	col(255, 150, 160): "P63-BLUSH",
	col(85, 125, 185):  "P70-PERIWINKLE",
	col(245, 200, 230): "P79-LIGHT-PINK",
	col(115, 185, 115): "P80-BRIGHT-GREEN",
	col(240, 95, 165):  "P83-PINK",
	col(190, 70, 115):  "P88-RASPBERRY",
	col(240, 150, 110): "P90-BUTTERSCOTCH",
	col(0, 150, 165):   "P91-PARROT-GREEN",
	col(95, 100, 100):  "P92-DARK-GREY",

	// Hama bead colors
	col(250, 240, 195): "H02-CREAM",
	col(255, 215, 90):  "H03-YELLOW",
	col(240, 105, 95):  "H04-ORANGE",
	col(245, 155, 175): "H06-PINK",
	col(35, 85, 160):   "H08-BLUE",
	col(120, 90, 145):  "H07-PURPLE",
	col(25, 105, 180):  "H09-LIGHT-BLUE",
	col(35, 125, 95):   "H10-GREEN",
	col(70, 195, 165):  "H11-LIGHT-GREEN",
	col(100, 75, 80):   "H12-BROWN",
	col(145, 150, 155): "H17-GREY",
	col(170, 85, 80):   "H20-BROWN",
	col(190, 130, 100): "H21-LIGHT-BROWN",
	col(175, 75, 85):   "H22-DARK-RED",
	col(240, 170, 165): "H26-FLESH",
	col(225, 185, 150): "H27-BEIGE",
	col(70, 85, 90):    "H28-DARK-GREEN",
	col(195, 80, 115):  "H29-RASPBERRY",
	col(115, 75, 85):   "H30-BURGUNDY",
	col(105, 160, 175): "H31-TURQUOISE",
	col(255, 95, 200):  "H32-FUCHSIA",
	col(245, 240, 125): "H43-PASTEL-YELLOW",
	col(255, 120, 140): "H44-PASTEL-CORAL",
	col(165, 140, 205): "H45-PASTEL-PURPLE",
	col(80, 170, 225):  "H46-PASTEL-BLUE",
	col(150, 230, 160): "H47-PASTEL-GREEN",
	col(230, 135, 200): "H48-PASTEL-PINK",
	col(240, 175, 95):  "H60-TEDDY-BEAR",

	// Nabbi bead colors
	col(90, 85, 80):    "N02-DARK-BROWN",
	col(105, 75, 80):   "N03-BROWN-MEDIUM",
	col(150, 85, 100):  "N04-WINE-RED",
	col(190, 125, 85):  "N05-BUTTERSCOTCH",
	col(185, 160, 145): "N06-BEIGE",
	col(240, 195, 150): "N07-SKIN",
	col(160, 160, 155): "N08-ASH-GREY",
	col(70, 100, 90):   "N09-DARK-GREEN",
	col(230, 225, 225): "N10-LIGHT-GREY",
	col(115, 90, 155):  "N11-PURPLE",
	col(245, 225, 215): "N12-IVORY",
	col(255, 210, 75):  "N14-YELLOW",
	col(50, 145, 100):  "N16-GREEN",
	col(0, 120, 210):   "N17-BLUE",
	col(245, 200, 190): "N18-LIGHT-PINK",
	col(215, 65, 85):   "N19-LIGHT-RED",
	col(210, 155, 125): "N20-LIGHT-BROWN",
	col(255, 245, 175): "N21-LIGHT-YELLOW",
	col(55, 170, 100):  "N22-PEARL-GREEN",
	col(90, 170, 235):  "N23-PASTEL-BLUE",
	col(200, 185, 240): "N24-LILAC",
	col(255, 120, 165): "N25-OLD-ROSE",
	col(255, 185, 150): "N26-LIGHT-ORANGE",
	col(145, 105, 100): "N27-BROWN",
	col(160, 205, 245): "N28-LIGHT-BLUE",
	col(225, 160, 85):  "N29-PEARL-ORANGE",
	col(200, 200, 120): "N30-OLIVE",
}
<|endoftext|>