<commit_before>package build

import (
	gobuild "go/build"
	"go/token"
	"strconv"
	"strings"
	"testing"

	"github.com/kisielk/gotool"
	"github.com/shurcooL/go/importgraphutil"
)

// Natives augment the standard library with GopherJS-specific changes.
// This test ensures that none of the standard library packages are modified
// in a way that adds imports which the original upstream standard library package
// does not already import. Doing that can increase generated output size or cause
// other unexpected issues (since the cmd/go tool does not know about these extra imports),
// so it's best to avoid it.
//
// It checks all standard library packages. Each package is considered as a normal
// package, as a test package, and as an external test package.
func TestNativesDontImportExtraPackages(t *testing.T) {
	// Calculate the forward import graph for all standard library packages.
	// It's needed for populateImportSet.
	stdOnly := gobuild.Default
	stdOnly.GOPATH = "" // We only care about standard library, so skip all GOPATH packages.
	forward, _, err := importgraphutil.BuildNoTests(&stdOnly)
	if err != nil {
		t.Fatalf("importgraphutil.BuildNoTests: %v", err)
	}

	// populateImportSet takes a slice of imports, and populates set with those
	// imports, as well as their transitive dependencies. That way, the set can
	// be quickly queried to check if a package is in the import graph of imports.
	//
	// Note, this does not include transitive imports of test/xtest packages,
	// which could cause some false positives. It currently doesn't, but if it does,
	// then support for that should be added here.
	populateImportSet := func(imports []string, set *map[string]struct{}) {
		for _, p := range imports {
			(*set)[p] = struct{}{}
			switch p {
			case "sync":
				(*set)["github.com/gopherjs/gopherjs/nosync"] = struct{}{}
			}
			transitiveImports := forward.Search(p)
			for p := range transitiveImports {
				(*set)[p] = struct{}{}
			}
		}
	}

	// Check all standard library packages.
	//
	// The general strategy is to first import each standard library package using the
	// normal build.Import, which returns a *build.Package. That contains Imports, TestImports,
	// and XTestImports values that are considered the "real imports".
	//
	// That list of direct imports is then expanded to the transitive closure by populateImportSet,
	// meaning all packages that are indirectly imported are also added to the set.
	//
	// Then, github.com/gopherjs/gopherjs/build.parseAndAugment(*build.Package) returns []*ast.File.
	// Those augmented parsed Go files of the package are checked, one file at at time, one import
	// at a time. Each import is verified to belong in the set of allowed real imports.
	for _, pkg := range gotool.ImportPaths([]string{"std"}) {
		// Normal package.
		{
			// Import the real normal package, and populate its real import set.
			bpkg, err := gobuild.Import(pkg, "", gobuild.ImportComment)
			if err != nil {
				t.Fatalf("gobuild.Import: %v", err)
			}
			realImports := make(map[string]struct{})
			populateImportSet(bpkg.Imports, &realImports)

			// Use parseAndAugment to get a list of augmented AST files.
			fset := token.NewFileSet()
			files, err := parseAndAugment(bpkg, false, fset)
			if err != nil {
				t.Fatalf("github.com/gopherjs/gopherjs/build.parseAndAugment: %v", err)
			}

			// Verify imports of normal augmented AST files.
			for _, f := range files {
				fileName := fset.File(f.Pos()).Name()
				normalFile := !strings.HasSuffix(fileName, "_test.go")
				if !normalFile {
					continue
				}
				for _, imp := range f.Imports {
					importPath, err := strconv.Unquote(imp.Path.Value)
					if err != nil {
						t.Fatalf("strconv.Unquote(%v): %v", imp.Path.Value, err)
					}
					if importPath == "github.com/gopherjs/gopherjs/js" {
						continue
					}
					if _, ok := realImports[importPath]; !ok {
						t.Errorf("augmented normal package %q imports %q in file %v, but real %q doesn't:\nrealImports = %q", bpkg.ImportPath, importPath, fileName, bpkg.ImportPath, toSlice(realImports))
					}
				}
			}
		}

		// Test package.
		{
			// Import the real test package, and populate its real import set.
			bpkg, err := gobuild.Import(pkg, "", gobuild.ImportComment)
			if err != nil {
				t.Fatalf("gobuild.Import: %v", err)
			}
			realTestImports := make(map[string]struct{})
			populateImportSet(bpkg.TestImports, &realTestImports)

			// Use parseAndAugment to get a list of augmented AST files.
			fset := token.NewFileSet()
			files, err := parseAndAugment(bpkg, true, fset)
			if err != nil {
				t.Fatalf("github.com/gopherjs/gopherjs/build.parseAndAugment: %v", err)
			}

			// Verify imports of test augmented AST files.
			for _, f := range files {
				fileName, pkgName := fset.File(f.Pos()).Name(), f.Name.String()
				testFile := strings.HasSuffix(fileName, "_test.go") && !strings.HasSuffix(pkgName, "_test")
				if !testFile {
					continue
				}
				for _, imp := range f.Imports {
					importPath, err := strconv.Unquote(imp.Path.Value)
					if err != nil {
						t.Fatalf("strconv.Unquote(%v): %v", imp.Path.Value, err)
					}
					if importPath == "github.com/gopherjs/gopherjs/js" {
						continue
					}
					if _, ok := realTestImports[importPath]; !ok {
						t.Errorf("augmented test package %q imports %q in file %v, but real %q doesn't:\nrealTestImports = %q", bpkg.ImportPath, importPath, fileName, bpkg.ImportPath, toSlice(realTestImports))
					}
				}
			}
		}

		// External test package.
		{
			// Import the real external test package, and populate its real import set.
			bpkg, err := gobuild.Import(pkg, "", gobuild.ImportComment)
			if err != nil {
				t.Fatalf("gobuild.Import: %v", err)
			}
			realXTestImports := make(map[string]struct{})
			populateImportSet(bpkg.XTestImports, &realXTestImports)

			// Add _test suffix to import path to cause parseAndAugment to use external test mode.
			bpkg.ImportPath += "_test"

			// Use parseAndAugment to get a list of augmented AST files, then check only the external test files.
			fset := token.NewFileSet()
			files, err := parseAndAugment(bpkg, true, fset)
			if err != nil {
				t.Fatalf("github.com/gopherjs/gopherjs/build.parseAndAugment: %v", err)
			}

			// Verify imports of external test augmented AST files.
			for _, f := range files {
				fileName, pkgName := fset.File(f.Pos()).Name(), f.Name.String()
				xTestFile := strings.HasSuffix(fileName, "_test.go") && strings.HasSuffix(pkgName, "_test")
				if !xTestFile {
					continue
				}
				for _, imp := range f.Imports {
					importPath, err := strconv.Unquote(imp.Path.Value)
					if err != nil {
						t.Fatalf("strconv.Unquote(%v): %v", imp.Path.Value, err)
					}
					if importPath == "github.com/gopherjs/gopherjs/js" {
						continue
					}
					if _, ok := realXTestImports[importPath]; !ok {
						t.Errorf("augmented external test package %q imports %q in file %v, but real %q doesn't:\nrealXTestImports = %q", bpkg.ImportPath, importPath, fileName, bpkg.ImportPath, toSlice(realXTestImports))
					}
				}
			}
		}
	}
}

func toSlice(m map[string]struct{}) []string {
	s := make([]string, 0, len(m))
	for v := range m {
		s = append(s, v)
	}
	return s
}
<commit_msg>build: Printing formatting style change.<commit_after>package build

import (
	"fmt"
	gobuild "go/build"
	"go/token"
	"strconv"
	"strings"
	"testing"

	"github.com/kisielk/gotool"
	"github.com/shurcooL/go/importgraphutil"
)

// Natives augment the standard library with GopherJS-specific changes.
// This test ensures that none of the standard library packages are modified
// in a way that adds imports which the original upstream standard library package
// does not already import. Doing that can increase generated output size or cause
// other unexpected issues (since the cmd/go tool does not know about these extra imports),
// so it's best to avoid it.
//
// It checks all standard library packages. Each package is considered as a normal
// package, as a test package, and as an external test package.
func TestNativesDontImportExtraPackages(t *testing.T) {
	// Calculate the forward import graph for all standard library packages.
	// It's needed for populateImportSet.
	stdOnly := gobuild.Default
	stdOnly.GOPATH = "" // We only care about standard library, so skip all GOPATH packages.
	forward, _, err := importgraphutil.BuildNoTests(&stdOnly)
	if err != nil {
		t.Fatalf("importgraphutil.BuildNoTests: %v", err)
	}

	// populateImportSet takes a slice of imports, and populates set with those
	// imports, as well as their transitive dependencies. That way, the set can
	// be quickly queried to check if a package is in the import graph of imports.
	//
	// Note, this does not include transitive imports of test/xtest packages,
	// which could cause some false positives. It currently doesn't, but if it does,
	// then support for that should be added here.
	populateImportSet := func(imports []string, set *stringSet) {
		for _, p := range imports {
			(*set)[p] = struct{}{}
			switch p {
			case "sync":
				(*set)["github.com/gopherjs/gopherjs/nosync"] = struct{}{}
			}
			transitiveImports := forward.Search(p)
			for p := range transitiveImports {
				(*set)[p] = struct{}{}
			}
		}
	}

	// Check all standard library packages.
	//
	// The general strategy is to first import each standard library package using the
	// normal build.Import, which returns a *build.Package. That contains Imports, TestImports,
	// and XTestImports values that are considered the "real imports".
	//
	// That list of direct imports is then expanded to the transitive closure by populateImportSet,
	// meaning all packages that are indirectly imported are also added to the set.
	//
	// Then, github.com/gopherjs/gopherjs/build.parseAndAugment(*build.Package) returns []*ast.File.
	// Those augmented parsed Go files of the package are checked, one file at at time, one import
	// at a time. Each import is verified to belong in the set of allowed real imports.
	for _, pkg := range gotool.ImportPaths([]string{"std"}) {
		// Normal package.
		{
			// Import the real normal package, and populate its real import set.
			bpkg, err := gobuild.Import(pkg, "", gobuild.ImportComment)
			if err != nil {
				t.Fatalf("gobuild.Import: %v", err)
			}
			realImports := make(stringSet)
			populateImportSet(bpkg.Imports, &realImports)

			// Use parseAndAugment to get a list of augmented AST files.
			fset := token.NewFileSet()
			files, err := parseAndAugment(bpkg, false, fset)
			if err != nil {
				t.Fatalf("github.com/gopherjs/gopherjs/build.parseAndAugment: %v", err)
			}

			// Verify imports of normal augmented AST files.
			for _, f := range files {
				fileName := fset.File(f.Pos()).Name()
				normalFile := !strings.HasSuffix(fileName, "_test.go")
				if !normalFile {
					continue
				}
				for _, imp := range f.Imports {
					importPath, err := strconv.Unquote(imp.Path.Value)
					if err != nil {
						t.Fatalf("strconv.Unquote(%v): %v", imp.Path.Value, err)
					}
					if importPath == "github.com/gopherjs/gopherjs/js" {
						continue
					}
					if _, ok := realImports[importPath]; !ok {
						t.Errorf("augmented normal package %q imports %q in file %v, but real %q doesn't:\nrealImports = %v", bpkg.ImportPath, importPath, fileName, bpkg.ImportPath, realImports)
					}
				}
			}
		}

		// Test package.
		{
			// Import the real test package, and populate its real import set.
			bpkg, err := gobuild.Import(pkg, "", gobuild.ImportComment)
			if err != nil {
				t.Fatalf("gobuild.Import: %v", err)
			}
			realTestImports := make(stringSet)
			populateImportSet(bpkg.TestImports, &realTestImports)

			// Use parseAndAugment to get a list of augmented AST files.
			fset := token.NewFileSet()
			files, err := parseAndAugment(bpkg, true, fset)
			if err != nil {
				t.Fatalf("github.com/gopherjs/gopherjs/build.parseAndAugment: %v", err)
			}

			// Verify imports of test augmented AST files.
			for _, f := range files {
				fileName, pkgName := fset.File(f.Pos()).Name(), f.Name.String()
				testFile := strings.HasSuffix(fileName, "_test.go") && !strings.HasSuffix(pkgName, "_test")
				if !testFile {
					continue
				}
				for _, imp := range f.Imports {
					importPath, err := strconv.Unquote(imp.Path.Value)
					if err != nil {
						t.Fatalf("strconv.Unquote(%v): %v", imp.Path.Value, err)
					}
					if importPath == "github.com/gopherjs/gopherjs/js" {
						continue
					}
					if _, ok := realTestImports[importPath]; !ok {
						t.Errorf("augmented test package %q imports %q in file %v, but real %q doesn't:\nrealTestImports = %v", bpkg.ImportPath, importPath, fileName, bpkg.ImportPath, realTestImports)
					}
				}
			}
		}

		// External test package.
		{
			// Import the real external test package, and populate its real import set.
			bpkg, err := gobuild.Import(pkg, "", gobuild.ImportComment)
			if err != nil {
				t.Fatalf("gobuild.Import: %v", err)
			}
			realXTestImports := make(stringSet)
			populateImportSet(bpkg.XTestImports, &realXTestImports)

			// Add _test suffix to import path to cause parseAndAugment to use external test mode.
			bpkg.ImportPath += "_test"

			// Use parseAndAugment to get a list of augmented AST files, then check only the external test files.
			fset := token.NewFileSet()
			files, err := parseAndAugment(bpkg, true, fset)
			if err != nil {
				t.Fatalf("github.com/gopherjs/gopherjs/build.parseAndAugment: %v", err)
			}

			// Verify imports of external test augmented AST files.
			for _, f := range files {
				fileName, pkgName := fset.File(f.Pos()).Name(), f.Name.String()
				xTestFile := strings.HasSuffix(fileName, "_test.go") && strings.HasSuffix(pkgName, "_test")
				if !xTestFile {
					continue
				}
				for _, imp := range f.Imports {
					importPath, err := strconv.Unquote(imp.Path.Value)
					if err != nil {
						t.Fatalf("strconv.Unquote(%v): %v", imp.Path.Value, err)
					}
					if importPath == "github.com/gopherjs/gopherjs/js" {
						continue
					}
					if _, ok := realXTestImports[importPath]; !ok {
						t.Errorf("augmented external test package %q imports %q in file %v, but real %q doesn't:\nrealXTestImports = %v", bpkg.ImportPath, importPath, fileName, bpkg.ImportPath, realXTestImports)
					}
				}
			}
		}
	}
}

// stringSet is used to print a set of strings in a more readable way.
type stringSet map[string]struct{}

func (m stringSet) String() string {
	s := make([]string, 0, len(m))
	for v := range m {
		s = append(s, v)
	}
	return fmt.Sprintf("%q", s)
}
<|endoftext|>


<commit_before>package builder

import (
	"fmt"
	"testing"

	"github.com/gernest/ngorm/dialects/ql"
	"github.com/gernest/ngorm/fixture"
	"github.com/gernest/ngorm/search"
)

func TestGroup(t *testing.T) {
	e := fixture.TestEngine()
	s := GroupSQL(e)
	if s != "" {
		t.Errorf("expected an empty string got %s", s)
	}
	by := "location"
	search.Group(e, by)
	s = GroupSQL(e)
	expect := " GROUP BY " + by
	if s != expect {
		t.Errorf("expected %s got %s", expect, s)
	}

}

func TestLimitAndOffsetSQL(t *testing.T) {
	e := fixture.TestEngine()
	e.Dialect = ql.Memory()
	limit := 2
	offset := 4
	search.Limit(e, limit)
	search.Offset(e, offset)
	expect := fmt.Sprintf(" LIMIT %d OFFSET %d", limit, offset)
	s := LimitAndOffsetSQL(e)
	if s != expect {
		t.Errorf("expected %s got %s", expect, s)
	}

}
<commit_msg>[builder] Add TestPrepareQuerySQL<commit_after>package builder

import (
	"fmt"
	"testing"

	"github.com/gernest/ngorm/dialects/ql"
	"github.com/gernest/ngorm/fixture"
	"github.com/gernest/ngorm/search"
)

func TestGroup(t *testing.T) {
	e := fixture.TestEngine()
	s := GroupSQL(e)
	if s != "" {
		t.Errorf("expected an empty string got %s", s)
	}
	by := "location"
	search.Group(e, by)
	s = GroupSQL(e)
	expect := " GROUP BY " + by
	if s != expect {
		t.Errorf("expected %s got %s", expect, s)
	}

}

func TestLimitAndOffsetSQL(t *testing.T) {
	e := fixture.TestEngine()
	e.Dialect = ql.Memory()
	limit := 2
	offset := 4
	search.Limit(e, limit)
	search.Offset(e, offset)
	expect := fmt.Sprintf(" LIMIT %d OFFSET %d", limit, offset)
	s := LimitAndOffsetSQL(e)
	if s != expect {
		t.Errorf("expected %s got %s", expect, s)
	}

}

func TestPrepareQuerySQL(t *testing.T) {
	e := fixture.TestEngine()
	e.Dialect = ql.Memory()
	search.Limit(e, 1)
	search.Where(e, "name=?", "gernest")
	var user fixture.User
	s := PrepareQuerySQL(e, &user)
	fmt.Println(s)
}
<|endoftext|>


<commit_before>// Copyright 2015, Joe Tsai. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE.md file.

package bzip2

import (
	"bytes"
	"io"
	"io/ioutil"
	"testing"

	"github.com/dsnet/compress/internal/testutil"
)

const (
	binary  = "../testdata/binary.bin"
	digits  = "../testdata/digits.txt"
	huffman = "../testdata/huffman.txt"
	random  = "../testdata/random.bin"
	repeats = "../testdata/repeats.bin"
	twain   = "../testdata/twain.txt"
	zeros   = "../testdata/zeros.bin"
)

func TestRoundTrip(t *testing.T) {
	var vectors = []struct {
		input []byte
	}{
		{input: testutil.MustLoadFile(binary, -1)},
		{input: testutil.MustLoadFile(digits, -1)},
		{input: testutil.MustLoadFile(huffman, -1)},
		{input: testutil.MustLoadFile(random, -1)},
		{input: testutil.MustLoadFile(repeats, -1)},
		{input: testutil.MustLoadFile(twain, -1)},
		{input: testutil.MustLoadFile(zeros, -1)},
	}

	for i, v := range vectors {
		var buf bytes.Buffer
		rd := bytes.NewReader(v.input)
		wr := NewWriter(&buf)
		cnt, err := io.Copy(wr, rd)
		if err != nil {
			t.Errorf("test %d, write error: got %v", i, err)
		}
		if cnt != int64(len(v.input)) {
			t.Errorf("test %d, write count mismatch: got %d, want %d", i, cnt, len(v.input))
		}
		if err := wr.Close(); err != nil {
			t.Errorf("test %d, close error: got %v", i, err)
		}

		output, err := ioutil.ReadAll(NewReader(&buf))
		if err != nil {
			t.Errorf("test %d, read error: got %v", i, err)
		}
		t.Log(len(output), len(v.input))

		if !bytes.Equal(output, v.input) {
			t.Errorf("test %d, output data mismatch", i)
		}
	}
}
<commit_msg>bzip2: remove spurious testing.Log output<commit_after>// Copyright 2015, Joe Tsai. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE.md file.

package bzip2

import (
	"bytes"
	"io"
	"io/ioutil"
	"testing"

	"github.com/dsnet/compress/internal/testutil"
)

const (
	binary  = "../testdata/binary.bin"
	digits  = "../testdata/digits.txt"
	huffman = "../testdata/huffman.txt"
	random  = "../testdata/random.bin"
	repeats = "../testdata/repeats.bin"
	twain   = "../testdata/twain.txt"
	zeros   = "../testdata/zeros.bin"
)

func TestRoundTrip(t *testing.T) {
	var vectors = []struct {
		input []byte
	}{
		{input: testutil.MustLoadFile(binary, -1)},
		{input: testutil.MustLoadFile(digits, -1)},
		{input: testutil.MustLoadFile(huffman, -1)},
		{input: testutil.MustLoadFile(random, -1)},
		{input: testutil.MustLoadFile(repeats, -1)},
		{input: testutil.MustLoadFile(twain, -1)},
		{input: testutil.MustLoadFile(zeros, -1)},
	}

	for i, v := range vectors {
		var buf bytes.Buffer
		rd := bytes.NewReader(v.input)
		wr := NewWriter(&buf)
		cnt, err := io.Copy(wr, rd)
		if err != nil {
			t.Errorf("test %d, write error: got %v", i, err)
		}
		if cnt != int64(len(v.input)) {
			t.Errorf("test %d, write count mismatch: got %d, want %d", i, cnt, len(v.input))
		}
		if err := wr.Close(); err != nil {
			t.Errorf("test %d, close error: got %v", i, err)
		}

		output, err := ioutil.ReadAll(NewReader(&buf))
		if err != nil {
			t.Errorf("test %d, read error: got %v", i, err)
		}

		if !bytes.Equal(output, v.input) {
			t.Errorf("test %d, output data mismatch", i)
		}
	}
}
<|endoftext|>


<commit_before>// Package ccs provides GCM Cloud Connection Server (XMPP) client implementation.
// https://developer.android.com/google/gcm/ccs.html
package ccs

import (
	"errors"
	"fmt"
	"strings"

	json "github.com/bitly/go-simplejson"
	"github.com/soygul/nbusy-server/xmpp"
)

const (
	gcmXML    = `<message id=""><gcm xmlns="google:mobile:data">%v</gcm></message>`
	gcmACK    = `{"to": "%v", "message_id": "%v", "message_type": "ack"}`
	gcmDomain = "gcm.googleapis.com"
)

// Conn is a GCM CCS connection.
type Conn struct {
	Endpoint, SenderID, APIKey string
	Debug                      bool
	xmppConn                   *xmpp.Client //xmpp.Connection
	isConnected                bool
}

// New function connects to GCM CCS server and returns the connection object and an error (only if there were any).
// Accepts a CCS endpoint URI (production or staging) along with relevant credentials.
// Optionally debug mode can be enabled to dump all CSS communications to stdout.
func New(endpoint, senderID, apiKey string, debug bool) (*Conn, error) {
	if !strings.Contains(senderID, gcmDomain) {
		senderID += "@" + gcmDomain
	}

	c := &Conn{
		Endpoint: endpoint,
		SenderID: senderID,
		APIKey:   apiKey,
		Debug:    debug,
	}

	err := c.open()
	if debug {
		if err == nil {
			fmt.Printf("New CCS connection established with parameters: %+v\n", c)
		} else {
			if err == nil {
				fmt.Printf("New CCS connection failed established with parameters: %+v\n", c)
			}
		}
	}

	return c, err
}

func (c *Conn) open() error {
	xc, err := xmpp.NewClient(c.Endpoint, c.SenderID, c.APIKey, c.Debug)
	if err != nil {
		return err
	}

	c.xmppConn = xc
	c.isConnected = true
	return nil
}

// Listen starts listening for incoming messages from the CCS connection.
func (c *Conn) Listen(msgChan chan map[string]interface{}, errChan chan error) error {
	if !c.isConnected {
		return errors.New("no ccs connection")
	}

	for {
		event, err := c.xmppConn.Recv() //xmppConn.Listen
		if err != nil {
			c.xmppConn.Close()
			c.isConnected = false
			return err
		}

		go func(event interface{}) {
			switch v := event.(type) {
			case xmpp.Chat: //xmpp.Message
				isGcmMessage, message, err := c.handleMessage(v.Other[0])
				if err != nil {
					errChan <- err
					return
				}
				if isGcmMessage {
					return
				}
				msgChan <- message
			}
		}(event)
	}
}

// Close a CSS connection.
func (c *Conn) Close() error {
	c.isConnected = false
	return c.xmppConn.Close()
}

func (c *Conn) handleMessage(msg string) (isGcmMessage bool, message map[string]interface{}, err error) {
	fmt.Printf("Incoming message: %v", msg)
	jsonData, err := json.NewJson([]byte(msg))
	if err != nil {
		return false, nil, errors.New("unknow message")
	}

	from, _ := jsonData.Get("from").String()
	messageID, _ := jsonData.Get("message_id").String()
	if _, ok := jsonData.CheckGet("message_type"); ok {
		err, _ := jsonData.Get("error").String()

		switch v, _ := jsonData.Get("message_type").String(); v {
		case "ack":
			return true, nil, nil
		case "nack":
			errFormat := "From: %v, MessageID: %v, Error: %v"
			result := fmt.Sprintf(errFormat, from, messageID, err)
			return true, nil, errors.New(result)
		}
	} else {
		ack := fmt.Sprintf(gcmACK, from, messageID)
		c.xmppConn.SendOrg(fmt.Sprintf(gcmXML, ack)) //xmppConn.SendRaw -or- just .Send (and .SendMsg for the other)
	}

	if _, ok := jsonData.CheckGet("from"); ok {
		data, _ := jsonData.Get("data").Map()
		return false, data, nil
	}

	return false, nil, errors.New("unknow message")
}

// Send a GCM CCS message.
func (c *Conn) Send(message *Message) error {
	if !c.isConnected {
		return errors.New("no connection")
	}

	res := fmt.Sprintf(gcmXML, message)
	c.xmppConn.SendOrg(res) //xmppConn.SendRaw

	return nil
}
<commit_msg>fix debug log<commit_after>// Package ccs provides GCM Cloud Connection Server (XMPP) client implementation.
// https://developer.android.com/google/gcm/ccs.html
package ccs

import (
	"errors"
	"fmt"
	"strings"

	json "github.com/bitly/go-simplejson"
	"github.com/soygul/nbusy-server/xmpp"
)

const (
	gcmXML    = `<message id=""><gcm xmlns="google:mobile:data">%v</gcm></message>`
	gcmACK    = `{"to": "%v", "message_id": "%v", "message_type": "ack"}`
	gcmDomain = "gcm.googleapis.com"
)

// Conn is a GCM CCS connection.
type Conn struct {
	Endpoint, SenderID, APIKey string
	Debug                      bool
	xmppConn                   *xmpp.Client //xmpp.Connection
	isConnected                bool
}

// New function connects to GCM CCS server and returns the connection object and an error (only if there were any).
// Accepts a CCS endpoint URI (production or staging) along with relevant credentials.
// Optionally debug mode can be enabled to dump all CSS communications to stdout.
func New(endpoint, senderID, apiKey string, debug bool) (*Conn, error) {
	if !strings.Contains(senderID, gcmDomain) {
		senderID += "@" + gcmDomain
	}

	c := &Conn{
		Endpoint: endpoint,
		SenderID: senderID,
		APIKey:   apiKey,
		Debug:    debug,
	}

	err := c.open()
	if debug {
		if err == nil {
			fmt.Printf("New CCS connection established with parameters: %+v\n", c)
		} else {
			fmt.Printf("New CCS connection failed to establish with parameters: %+v\n", c)
		}
	}

	return c, err
}

func (c *Conn) open() error {
	xc, err := xmpp.NewClient(c.Endpoint, c.SenderID, c.APIKey, c.Debug)
	if err != nil {
		return err
	}

	c.xmppConn = xc
	c.isConnected = true
	return nil
}

// Listen starts listening for incoming messages from the CCS connection.
func (c *Conn) Listen(msgChan chan map[string]interface{}, errChan chan error) error {
	if !c.isConnected {
		return errors.New("no ccs connection")
	}

	for {
		event, err := c.xmppConn.Recv() //xmppConn.Listen
		if err != nil {
			c.xmppConn.Close()
			c.isConnected = false
			return err
		}

		go func(event interface{}) {
			switch v := event.(type) {
			case xmpp.Chat: //xmpp.Message
				isGcmMessage, message, err := c.handleMessage(v.Other[0])
				if err != nil {
					errChan <- err
					return
				}
				if isGcmMessage {
					return
				}
				msgChan <- message
			}
		}(event)
	}
}

// Close a CSS connection.
func (c *Conn) Close() error {
	c.isConnected = false
	return c.xmppConn.Close()
}

func (c *Conn) handleMessage(msg string) (isGcmMessage bool, message map[string]interface{}, err error) {
	fmt.Printf("Incoming message: %v\n", msg)
	jsonData, err := json.NewJson([]byte(msg))
	if err != nil {
		return false, nil, errors.New("unknow message")
	}

	from, _ := jsonData.Get("from").String()
	messageID, _ := jsonData.Get("message_id").String()
	if _, ok := jsonData.CheckGet("message_type"); ok {
		err, _ := jsonData.Get("error").String()

		switch v, _ := jsonData.Get("message_type").String(); v {
		case "ack":
			return true, nil, nil
		case "nack":
			errFormat := "From: %v, MessageID: %v, Error: %v"
			result := fmt.Sprintf(errFormat, from, messageID, err)
			return true, nil, errors.New(result)
		}
	} else {
		ack := fmt.Sprintf(gcmACK, from, messageID)
		c.xmppConn.SendOrg(fmt.Sprintf(gcmXML, ack)) //xmppConn.SendRaw -or- just .Send (and .SendMsg for the other)
	}

	if _, ok := jsonData.CheckGet("from"); ok {
		data, _ := jsonData.Get("data").Map()
		return false, data, nil
	}

	return false, nil, errors.New("unknow message")
}

// Send a GCM CCS message.
func (c *Conn) Send(message *Message) error {
	if !c.isConnected {
		return errors.New("no connection")
	}

	res := fmt.Sprintf(gcmXML, message)
	c.xmppConn.SendOrg(res) //xmppConn.SendRaw

	return nil
}
<|endoftext|>


<commit_before>package mymath

import (
	"fmt"
	"testing"
)

func TestSqurt(t *testing.T) {
	actualNums := []float64{1.0, 2.0, 3.0, 4.0, 5.0}
	expectedNums := []float64{
		1.0,
		1.4142135,
		1.7320508,
		2.0,
		2.2360679,
	}

	for i, exp := range expectedNums {
		actual := fmt.Sprintf("%1.8f", Squrt(actualNums[i]))
		expected := fmt.Sprintf("%1.7f", exp)
		if actual[:9] != expected {
			t.Errorf("got %v \nwant %v", actual, expected)
		}
	}
}
<commit_msg>Modify testing<commit_after>package mymath

import (
	"math"
	"testing"
)

func TestSqurt(t *testing.T) {

	var tests = []struct {
		num  float64
		want float64
	}{
		{1.0, 1.0},
		{2.0, 1.4142135},
		{3.0, 1.7320508},
		{4.0, 2.0},
		{5.0, 2.2360679},
	}

	for _, test := range tests {
		got := Squrt(test.num)
		if math.Abs(got-test.want) > 0.0000001 {
			t.Errorf("Squrt(%1.8f) returned %1.8f, want %1.8f", test.num, got, test.want)
		}
	}
}
<|endoftext|>


<commit_before>/*
The Ginkgo CLI

The Ginkgo CLI is fully documented [here](http://onsi.github.io/ginkgo/#the_ginkgo_cli)

To install:

	go install github.com/onsi/ginkgo/ginkgo

To run tests:

	ginkgo

To run tests in all subdirectories:

	ginkgo -r

To run tests in particular packages:

	ginkgo <flags> /path/to/package /path/to/another/package

To monitor packages and rerun tests when changes occur:

	ginkgo -watch <-r> </path/to/package>

passing `ginkgo -watch` the `-r` flag will recursively detect all test suites under the current directory and monitor them.
`-watch` does not detect *new* packages. Moreover, changes in package X only rerun the tests for package X, tests for packages
that depend on X are not rerun.

[OSX only] To receive (desktop) notifications when a test run completes:

	ginkgo -notify

this is particularly useful with `ginkgo -watch`.  Notifications are currently only supported on OS X and require that you `brew install terminal-notifier`

To run tests in parallel

	ginkgo -nodes=N

where N is the number of nodes.  By default the Ginkgo CLI will spin up a server that the individual
test processes stream test output to.  The CLI then aggregates these streams into one coherent stream of output.
An alternative is to have the parallel nodes run and then present the resulting, final, output in one monolithic chunk - you can opt into this if streaming is giving you trouble:

	ginkgo -nodes=N -stream=false

On windows, the default value for stream is false.

To bootstrap a test suite:

	ginkgo bootstrap

To generate a test file:

	ginkgo generate <test_file_name>

To unfocus tests:

	ginkgo unfocus

To print out Ginkgo's version:

	ginkgo version

To get more help:

	ginkgo help
*/
package main

import (
	"flag"
	"fmt"
	"github.com/onsi/ginkgo/config"
	"github.com/onsi/ginkgo/ginkgo/testsuite"
	"os"
	"os/signal"
	"runtime"
	"time"
)

var numCPU int
var parallelStream bool
var recurse bool
var runMagicI bool
var race bool
var cover bool
var watch bool
var notify bool

func init() {
	onWindows := (runtime.GOOS == "windows")
	onOSX := (runtime.GOOS == "darwin")

	config.Flags("", false)

	flag.IntVar(&(numCPU), "nodes", 1, "The number of parallel test nodes to run")
	flag.BoolVar(&(parallelStream), "stream", !onWindows, "Aggregate parallel test output into one coherent stream (default: true)")
	flag.BoolVar(&(recurse), "r", false, "Find and run test suites under the current directory recursively")
	flag.BoolVar(&(runMagicI), "i", false, "Run go test -i first, then run the test suite")
	flag.BoolVar(&(race), "race", false, "Run tests with race detection enabled")
	flag.BoolVar(&(cover), "cover", false, "Run tests with coverage analysis, will generate coverage profiles with the package name in the current directory")
	flag.BoolVar(&(watch), "watch", false, "Monitor the target packages for changes, then run tests when changes are detected")
	if onOSX {
		flag.BoolVar(&(notify), "notify", false, "Send desktop notifications when a test run completes")
	}

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage of ginkgo:\n\n")
		fmt.Fprintf(os.Stderr, "ginkgo <FLAGS> <DIRECTORY> ...\n  Run the tests in the passed in <DIRECTORY> (or the current directory if left blank).\n  ginkgo accepts the following flags:\n")
		flag.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\n")
		fmt.Fprintf(os.Stderr, "ginkgo bootstrap\n  Bootstrap a test suite for the current package.\n\n")
		fmt.Fprintf(os.Stderr, "ginkgo generate <SUBJECT>\n  Generate a test file for SUBJECT, the file will be named SUBJECT_test.go\n  If omitted, a file named after the package will be created.\n\n")
		fmt.Fprintf(os.Stderr, "ginkgo unfocus\n  Unfocuses any focused tests.\n\n")
		fmt.Fprintf(os.Stderr, "ginkgo version\n  Print ginkgo's version.\n\n")
		fmt.Fprintf(os.Stderr, "ginkgo help\n  Print this usage information.\n")
	}

	flag.Parse()
}

func main() {
	if flag.NArg() > 0 {
		args := flag.Args()
		handled := handleSubcommands(args)
		if handled {
			os.Exit(0)
		}
	}

	if notify {
		verifyNotificationsAreAvailable()
	}

	runner := newTestRunner(numCPU, parallelStream, runMagicI, race, cover)

	registerSignalHandler(runner)

	if watch {
		watchTests(runner)
	} else {
		runTests(runner)
	}
}

func handleSubcommands(args []string) bool {
	switch args[0] {
	case "bootstrap":
		generateBootstrap()
	case "generate":
		subject := ""
		if len(args) > 1 {
			subject = args[1]
		}
		generateSpec(subject)
	case "unfocus", "blur":
		unfocusSpecs()
	case "help":
		flag.Usage()
	case "version":
		fmt.Printf("Ginkgo V%s\n", config.VERSION)
	default:
		return false
	}

	return true
}

func findSuites() []*testsuite.TestSuite {
	suites := []*testsuite.TestSuite{}

	if flag.NArg() > 0 {
		for _, dir := range flag.Args() {
			suites = append(suites, testsuite.SuitesInDir(dir, recurse)...)
		}
	} else {
		suites = testsuite.SuitesInDir(".", recurse)
	}

	if len(suites) == 0 {
		fmt.Printf("Found no test suites.\nFor usage instructions:\n\tginkgo help\n")
		os.Exit(1)
	}

	return suites
}

func runTests(runner *testRunner) {
	t := time.Now()

	suites := findSuites()

	passed := true
	for _, suite := range suites {
		suitePassed := runner.runSuite(suite)
		sendSuiteCompletionNotification(suite, suitePassed)

		if !suitePassed {
			passed = false
			break
		}
	}

	fmt.Printf("\nGinkgo ran in %s\n", time.Since(t))

	if passed {
		fmt.Printf("Test Suite Passed\n")
		os.Exit(0)
	} else {
		fmt.Printf("Test Suite Failed\n")
		os.Exit(1)
	}
}

func watchTests(runner *testRunner) {
	suites := findSuites()

	modifiedSuite := make(chan *testsuite.TestSuite)
	for _, suite := range suites {
		go suite.Watch(modifiedSuite)
	}

	if !recurse {
		suitePassed := runner.runSuite(suites[0])
		sendSuiteCompletionNotification(suites[0], suitePassed)
	}

	for {
		suite := <-modifiedSuite
		sendNotification("Ginkgo", fmt.Sprintf(`Detected change in "%s"...`, suite.PackageName))

		fmt.Printf("\n\nDetected change in %s\n\n", suite.PackageName)
		suitePassed := runner.runSuite(suite)

		sendSuiteCompletionNotification(suite, suitePassed)
	}
}

func registerSignalHandler(runner *testRunner) {
	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt, os.Kill)

		select {
		case sig := <-c:
			runner.abort(sig)
			os.Exit(1)
		}
	}()
}
<commit_msg>optionally keep-going when a failing test is encountered<commit_after>/*
The Ginkgo CLI

The Ginkgo CLI is fully documented [here](http://onsi.github.io/ginkgo/#the_ginkgo_cli)

To install:

	go install github.com/onsi/ginkgo/ginkgo

To run tests:

	ginkgo

To run tests in all subdirectories:

	ginkgo -r

To run tests in particular packages:

	ginkgo <flags> /path/to/package /path/to/another/package

By default, when running multiple tests (with -r or a list of packages) Ginkgo will abort when a test fails.  To have Ginkgo run subsequent test suites instead you can:

	ginkgo -keep-going

To monitor packages and rerun tests when changes occur:

	ginkgo -watch <-r> </path/to/package>

passing `ginkgo -watch` the `-r` flag will recursively detect all test suites under the current directory and monitor them.
`-watch` does not detect *new* packages. Moreover, changes in package X only rerun the tests for package X, tests for packages
that depend on X are not rerun.

[OSX only] To receive (desktop) notifications when a test run completes:

	ginkgo -notify

this is particularly useful with `ginkgo -watch`.  Notifications are currently only supported on OS X and require that you `brew install terminal-notifier`

To run tests in parallel

	ginkgo -nodes=N

where N is the number of nodes.  By default the Ginkgo CLI will spin up a server that the individual
test processes stream test output to.  The CLI then aggregates these streams into one coherent stream of output.
An alternative is to have the parallel nodes run and then present the resulting, final, output in one monolithic chunk - you can opt into this if streaming is giving you trouble:

	ginkgo -nodes=N -stream=false

On windows, the default value for stream is false.

To bootstrap a test suite:

	ginkgo bootstrap

To generate a test file:

	ginkgo generate <test_file_name>

To unfocus tests:

	ginkgo unfocus

To print out Ginkgo's version:

	ginkgo version

To get more help:

	ginkgo help
*/
package main

import (
	"flag"
	"fmt"
	"github.com/onsi/ginkgo/config"
	"github.com/onsi/ginkgo/ginkgo/testsuite"
	"os"
	"os/signal"
	"runtime"
	"time"
)

var numCPU int
var parallelStream bool
var recurse bool
var runMagicI bool
var race bool
var cover bool
var watch bool
var notify bool
var keepGoing bool

func init() {
	onWindows := (runtime.GOOS == "windows")
	onOSX := (runtime.GOOS == "darwin")

	config.Flags("", false)

	flag.IntVar(&(numCPU), "nodes", 1, "The number of parallel test nodes to run")
	flag.BoolVar(&(parallelStream), "stream", !onWindows, "Aggregate parallel test output into one coherent stream (default: true)")
	flag.BoolVar(&(recurse), "r", false, "Find and run test suites under the current directory recursively")
	flag.BoolVar(&(runMagicI), "i", false, "Run go test -i first, then run the test suite")
	flag.BoolVar(&(race), "race", false, "Run tests with race detection enabled")
	flag.BoolVar(&(cover), "cover", false, "Run tests with coverage analysis, will generate coverage profiles with the package name in the current directory")
	flag.BoolVar(&(watch), "watch", false, "Monitor the target packages for changes, then run tests when changes are detected")
	flag.BoolVar(&(keepGoing), "keep-going", false, "When turned on failures from earlier test suites do not prevent later test suites from running")
	if onOSX {
		flag.BoolVar(&(notify), "notify", false, "Send desktop notifications when a test run completes")
	}

	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage of ginkgo:\n\n")
		fmt.Fprintf(os.Stderr, "ginkgo <FLAGS> <DIRECTORY> ...\n  Run the tests in the passed in <DIRECTORY> (or the current directory if left blank).\n  ginkgo accepts the following flags:\n")
		flag.PrintDefaults()
		fmt.Fprintf(os.Stderr, "\n")
		fmt.Fprintf(os.Stderr, "ginkgo bootstrap\n  Bootstrap a test suite for the current package.\n\n")
		fmt.Fprintf(os.Stderr, "ginkgo generate <SUBJECT>\n  Generate a test file for SUBJECT, the file will be named SUBJECT_test.go\n  If omitted, a file named after the package will be created.\n\n")
		fmt.Fprintf(os.Stderr, "ginkgo unfocus\n  Unfocuses any focused tests.\n\n")
		fmt.Fprintf(os.Stderr, "ginkgo version\n  Print ginkgo's version.\n\n")
		fmt.Fprintf(os.Stderr, "ginkgo help\n  Print this usage information.\n")
	}

	flag.Parse()
}

func main() {
	if flag.NArg() > 0 {
		args := flag.Args()
		handled := handleSubcommands(args)
		if handled {
			os.Exit(0)
		}
	}

	if notify {
		verifyNotificationsAreAvailable()
	}

	runner := newTestRunner(numCPU, parallelStream, runMagicI, race, cover)

	registerSignalHandler(runner)

	if watch {
		watchTests(runner)
	} else {
		runTests(runner)
	}
}

func handleSubcommands(args []string) bool {
	switch args[0] {
	case "bootstrap":
		generateBootstrap()
	case "generate":
		subject := ""
		if len(args) > 1 {
			subject = args[1]
		}
		generateSpec(subject)
	case "unfocus", "blur":
		unfocusSpecs()
	case "help":
		flag.Usage()
	case "version":
		fmt.Printf("Ginkgo V%s\n", config.VERSION)
	default:
		return false
	}

	return true
}

func findSuites() []*testsuite.TestSuite {
	suites := []*testsuite.TestSuite{}

	if flag.NArg() > 0 {
		for _, dir := range flag.Args() {
			suites = append(suites, testsuite.SuitesInDir(dir, recurse)...)
		}
	} else {
		suites = testsuite.SuitesInDir(".", recurse)
	}

	if len(suites) == 0 {
		fmt.Printf("Found no test suites.\nFor usage instructions:\n\tginkgo help\n")
		os.Exit(1)
	}

	return suites
}

func runTests(runner *testRunner) {
	t := time.Now()

	suites := findSuites()
	suitesThatFailed := []*testsuite.TestSuite{}

	passed := true
	for _, suite := range suites {
		suitePassed := runner.runSuite(suite)
		sendSuiteCompletionNotification(suite, suitePassed)

		if !suitePassed {
			passed = false
			suitesThatFailed = append(suitesThatFailed, suite)
			if !keepGoing {
				break
			}
		}
	}

	if keepGoing && !passed {
		fmt.Println("\nThere were failures detected in the following suites:")
		for _, suite := range suitesThatFailed {
			fmt.Printf("\t%s\n", suite.PackageName)
		}
	}

	fmt.Printf("\nGinkgo ran in %s\n", time.Since(t))

	if passed {
		fmt.Printf("Test Suite Passed\n")
		os.Exit(0)
	} else {
		fmt.Printf("Test Suite Failed\n")
		os.Exit(1)
	}
}

func watchTests(runner *testRunner) {
	suites := findSuites()

	modifiedSuite := make(chan *testsuite.TestSuite)
	for _, suite := range suites {
		go suite.Watch(modifiedSuite)
	}

	if !recurse {
		suitePassed := runner.runSuite(suites[0])
		sendSuiteCompletionNotification(suites[0], suitePassed)
	}

	for {
		suite := <-modifiedSuite
		sendNotification("Ginkgo", fmt.Sprintf(`Detected change in "%s"...`, suite.PackageName))

		fmt.Printf("\n\nDetected change in %s\n\n", suite.PackageName)
		suitePassed := runner.runSuite(suite)

		sendSuiteCompletionNotification(suite, suitePassed)
	}
}

func registerSignalHandler(runner *testRunner) {
	go func() {
		c := make(chan os.Signal, 1)
		signal.Notify(c, os.Interrupt, os.Kill)

		select {
		case sig := <-c:
			runner.abort(sig)
			os.Exit(1)
		}
	}()
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"net/http"
)

var cached []string = make([]string, 0)
var ttl int = 0

func handle(w http.ResponseWriter, r *http.Request) {

}

func main() {

	http.HandleFunc("/", handle)
	log.Fatal(http.ListenAndServe(":8000", nil))
}
<commit_msg>start working on server<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"time"
)

var listen *string = flag.String("listen", ":8000", "\"[address]:<port>\" to bind to. [default: \":8000\"]")
var username *string = flag.String("username", "", "GitHub username to fetch keys for. [required]")
var ttl *int64 = flag.Int64("ttl", 86400, "Time in seconds to cache GitHub keys for. [default: 86400 (one day)]")

var cache []string = make([]string, 0)
var expire int64 = 0

func fetchKeys() error {
	fmt.Printf("Fetching keys for GitHub user \"%s\"\n", *username)
	var resp *http.Response
	var err error
	var uri string = fmt.Sprintf("https://api.github.com/users/%s/keys", *username)
	resp, err = http.Get(uri)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	var body []byte
	body, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		return err
	}

	var keys []map[string]interface{} = make([]map[string]interface{}, 0)
	err = json.Unmarshal(body, &keys)
	if err != nil {
		return err
	}

	var newCache []string = make([]string, 0)
	for _, key := range keys {
		newCache = append(newCache, key["key"].(string))
	}
	var newExpire int64 = time.Now().UTC().Unix() + *ttl
	cache = newCache
	expire = newExpire

	return nil
}

func logRequest(r *http.Request) {
	fmt.Printf("\"%s\"\t\"%s\"\t\"%s\"\t\"%s\"\t\"%s\"\t\"%s\"", r.Method, r.URL, r.Proto, r.Host, r.RemoteAddr, r.RequestURI)
}

func handle(w http.ResponseWriter, r *http.Request) {
	logRequest(r)
	if r.Method != "GET" {
		w.WriteHeader(http.StatusMethodNotAllowed)
		return
	}

	var err error
	var now int64 = time.Now().UTC().Unix()
	if now >= expire {
		err = fetchKeys()
		if err != nil {
			w.WriteHeader(http.StatusInternalServerError)
			return
		}
	}

	if len(cache) > 0 {
		w.WriteHeader(http.StatusOK)
		for _, key := range cache {
			fmt.Fprintf(w, "%s\n", key)
		}
	} else {
		w.WriteHeader(http.StatusNoContent)
	}
}

func main() {
	flag.Parse()
	if *username == "" {
		log.Fatal("Must provide `-username` parameter. e.g. `github-keys -username \"github-username\"`")
	}

	var err error
	err = fetchKeys()
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Starting server on \"%s\" for GitHub user \"%s\"\n", *listen, *username)
	http.HandleFunc("/", handle)
	err = http.ListenAndServe(*listen, nil)
	if err != nil {
		log.Fatal(err)
	}
}
<|endoftext|>


<commit_before>package github

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"regexp"
	"strings"

	"github.com/github/hub/utils"
)

type verboseTransport struct {
	Transport   *http.Transport
	Verbose     bool
	OverrideURL *url.URL
}

func (t *verboseTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
	if t.Verbose {
		t.dumpRequest(req)
	}

	if t.OverrideURL != nil {
		req = cloneRequest(req)
		req.Header.Set("X-Original-Scheme", req.URL.Scheme)
		req.URL.Scheme = t.OverrideURL.Scheme
		req.URL.Host = t.OverrideURL.Host
	}

	resp, err = t.Transport.RoundTrip(req)

	if err == nil && t.Verbose {
		t.dumpResponse(resp)
	}

	return
}

func (t *verboseTransport) dumpRequest(req *http.Request) {
	info := fmt.Sprintf("> %s %s://%s%s", req.Method, req.URL.Scheme, req.Host, req.URL.Path)
	t.verbosePrintln(info)
	t.dumpHeaders(req.Header, ">")
	body := t.dumpBody(req.Body)
	if body != nil {
		// reset body since it's been read
		req.Body = body
	}
}

func (t *verboseTransport) dumpResponse(resp *http.Response) {
	info := fmt.Sprintf("< HTTP %d", resp.StatusCode)
	location, err := resp.Location()
	if err == nil {
		info = fmt.Sprintf("%s\n< Location: %s", info, location.String())
	}
	t.verbosePrintln(info)
	t.dumpHeaders(resp.Header, "<")
	body := t.dumpBody(resp.Body)
	if body != nil {
		// reset body since it's been read
		resp.Body = body
	}
}

func (t *verboseTransport) dumpHeaders(header http.Header, indent string) {
	dumpHeaders := []string{"Authorization", "X-GitHub-OTP", "Localtion"}
	for _, h := range dumpHeaders {
		v := header.Get(h)
		if v != "" {
			r := regexp.MustCompile("(?i)^(basic|token) (.+)")
			if r.MatchString(v) {
				v = r.ReplaceAllString(v, "$1 [REDACTED]")
			}

			info := fmt.Sprintf("%s %s: %s", indent, h, v)
			t.verbosePrintln(info)
		}
	}
}

func (t *verboseTransport) dumpBody(body io.ReadCloser) io.ReadCloser {
	if body == nil {
		return nil
	}

	defer body.Close()
	buf := new(bytes.Buffer)
	_, err := io.Copy(buf, body)
	utils.Check(err)

	if buf.Len() > 0 {
		t.verbosePrintln(buf.String())
	}

	return ioutil.NopCloser(buf)
}

func (t *verboseTransport) verbosePrintln(msg string) {
	if isTerminal(os.Stderr.Fd()) {
		msg = fmt.Sprintf("\\e[36m%s\\e[m", msg)
	}

	fmt.Fprintln(os.Stderr, msg)
}

func newHttpClient(testHost string, verbose bool) *http.Client {
	var testURL *url.URL
	if testHost != "" {
		testURL, _ = url.Parse(testHost)
	}
	tr := &verboseTransport{
		Transport:   &http.Transport{Proxy: proxyFromEnvironment},
		Verbose:     verbose,
		OverrideURL: testURL,
	}
	return &http.Client{Transport: tr}
}

func cloneRequest(req *http.Request) *http.Request {
	dup := new(http.Request)
	*dup = *req
	dup.URL, _ = url.Parse(req.URL.String())
	dup.Header = make(http.Header)
	for k, s := range req.Header {
		dup.Header[k] = s
	}
	return dup
}

// An implementation of http.ProxyFromEnvironment that isn't broken
func proxyFromEnvironment(req *http.Request) (*url.URL, error) {
	proxy := os.Getenv("http_proxy")
	if proxy == "" {
		proxy = os.Getenv("HTTP_PROXY")
	}
	if proxy == "" {
		return nil, nil
	}

	proxyURL, err := url.Parse(proxy)
	if err != nil || !strings.HasPrefix(proxyURL.Scheme, "http") {
		if proxyURL, err := url.Parse("http://" + proxy); err == nil {
			return proxyURL, nil
		}
	}

	if err != nil {
		return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err)
	}

	return proxyURL, nil
}
<commit_msg>Fix cuke failure due to missing port for original request<commit_after>package github

import (
	"bytes"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"net/url"
	"os"
	"regexp"
	"strings"

	"github.com/github/hub/utils"
)

type verboseTransport struct {
	Transport   *http.Transport
	Verbose     bool
	OverrideURL *url.URL
}

func (t *verboseTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
	if t.Verbose {
		t.dumpRequest(req)
	}

	if t.OverrideURL != nil {
		port := "80"
		if s := strings.Split(req.URL.Host, ":"); len(s) > 1 {
			port = s[1]
		}

		req = cloneRequest(req)
		req.Header.Set("X-Original-Scheme", req.URL.Scheme)
		req.Header.Set("X-Original-Port", port)
		req.URL.Scheme = t.OverrideURL.Scheme
		req.URL.Host = t.OverrideURL.Host
	}

	resp, err = t.Transport.RoundTrip(req)

	if err == nil && t.Verbose {
		t.dumpResponse(resp)
	}

	return
}

func (t *verboseTransport) dumpRequest(req *http.Request) {
	info := fmt.Sprintf("> %s %s://%s%s", req.Method, req.URL.Scheme, req.Host, req.URL.Path)
	t.verbosePrintln(info)
	t.dumpHeaders(req.Header, ">")
	body := t.dumpBody(req.Body)
	if body != nil {
		// reset body since it's been read
		req.Body = body
	}
}

func (t *verboseTransport) dumpResponse(resp *http.Response) {
	info := fmt.Sprintf("< HTTP %d", resp.StatusCode)
	location, err := resp.Location()
	if err == nil {
		info = fmt.Sprintf("%s\n< Location: %s", info, location.String())
	}
	t.verbosePrintln(info)
	t.dumpHeaders(resp.Header, "<")
	body := t.dumpBody(resp.Body)
	if body != nil {
		// reset body since it's been read
		resp.Body = body
	}
}

func (t *verboseTransport) dumpHeaders(header http.Header, indent string) {
	dumpHeaders := []string{"Authorization", "X-GitHub-OTP", "Localtion"}
	for _, h := range dumpHeaders {
		v := header.Get(h)
		if v != "" {
			r := regexp.MustCompile("(?i)^(basic|token) (.+)")
			if r.MatchString(v) {
				v = r.ReplaceAllString(v, "$1 [REDACTED]")
			}

			info := fmt.Sprintf("%s %s: %s", indent, h, v)
			t.verbosePrintln(info)
		}
	}
}

func (t *verboseTransport) dumpBody(body io.ReadCloser) io.ReadCloser {
	if body == nil {
		return nil
	}

	defer body.Close()
	buf := new(bytes.Buffer)
	_, err := io.Copy(buf, body)
	utils.Check(err)

	if buf.Len() > 0 {
		t.verbosePrintln(buf.String())
	}

	return ioutil.NopCloser(buf)
}

func (t *verboseTransport) verbosePrintln(msg string) {
	if isTerminal(os.Stderr.Fd()) {
		msg = fmt.Sprintf("\\e[36m%s\\e[m", msg)
	}

	fmt.Fprintln(os.Stderr, msg)
}

func newHttpClient(testHost string, verbose bool) *http.Client {
	var testURL *url.URL
	if testHost != "" {
		testURL, _ = url.Parse(testHost)
	}
	tr := &verboseTransport{
		Transport:   &http.Transport{Proxy: proxyFromEnvironment},
		Verbose:     verbose,
		OverrideURL: testURL,
	}
	return &http.Client{Transport: tr}
}

func cloneRequest(req *http.Request) *http.Request {
	dup := new(http.Request)
	*dup = *req
	dup.URL, _ = url.Parse(req.URL.String())
	dup.Header = make(http.Header)
	for k, s := range req.Header {
		dup.Header[k] = s
	}
	return dup
}

// An implementation of http.ProxyFromEnvironment that isn't broken
func proxyFromEnvironment(req *http.Request) (*url.URL, error) {
	proxy := os.Getenv("http_proxy")
	if proxy == "" {
		proxy = os.Getenv("HTTP_PROXY")
	}
	if proxy == "" {
		return nil, nil
	}

	proxyURL, err := url.Parse(proxy)
	if err != nil || !strings.HasPrefix(proxyURL.Scheme, "http") {
		if proxyURL, err := url.Parse("http://" + proxy); err == nil {
			return proxyURL, nil
		}
	}

	if err != nil {
		return nil, fmt.Errorf("invalid proxy address %q: %v", proxy, err)
	}

	return proxyURL, nil
}
<|endoftext|>


<commit_before>package network

import (
	"errors"
	"net"
	"reflect"

	"github.com/NebulousLabs/Andromeda/encoding"
)

func ReadPrefix(conn net.Conn) ([]byte, error) {
	prefix := make([]byte, 4)
	if n, err := conn.Read(prefix); err != nil || n != len(prefix) {
		return nil, errors.New("could not read length prefix")
	}
	msgLen := int(encoding.DecUint64(prefix))
	if msgLen > maxMsgLen {
		return nil, errors.New("message too long")
	}
	// read msgLen bytes
	var data []byte
	buf := make([]byte, 1024)
	for total := 0; total < msgLen; {
		n, err := conn.Read(buf)
		if err != nil {
			return nil, err
		}
		data = append(data, buf[:n]...)
		total += n
	}
	if len(data) != msgLen {
		return nil, errors.New("message length mismatch")
	}
	return data, nil
}

func ReadObject(conn net.Conn, obj interface{}) error {
	data, err := ReadPrefix(conn)
	if err != nil {
		return err
	}
	return encoding.Unmarshal(data, obj)
}

func WritePrefix(conn net.Conn, data []byte) (int, error) {
	encLen := encoding.EncUint64(uint64(len(data)))
	return conn.Write(append(encLen[:4], data...))
}

func WriteObject(conn net.Conn, obj interface{}) (int, error) {
	return WritePrefix(conn, encoding.Marshal(obj))
}

// RPC performs a Remote Procedure Call by sending the procedure name and
// encoded argument, and decoding the response into the supplied object.
// 'resp' must be a pointer. If arg is nil, no object is sent. If 'resp' is
// nil, no response is read.
func (na *NetAddress) RPC(t byte, arg, resp interface{}) error {
	return na.Call(func(conn net.Conn) error {
		conn.Write([]byte{t})
		if arg != nil {
			if _, err := WriteObject(conn, arg); err != nil {
				return err
			}
		}
		if resp != nil {
			return ReadObject(conn, resp)
		}
		return nil
	})
}

func (tcps *TCPServer) Register(t byte, fn interface{}) {
	// all handlers are function with at least one in and one error out
	val, typ := reflect.ValueOf(fn), reflect.TypeOf(fn)
	if typ.Kind() != reflect.Func || typ.NumIn() < 1 ||
		typ.NumOut() != 1 || typ.Out(0) != reflect.TypeOf((*error)(nil)).Elem() {
		panic("registered function has wrong type signature")
	}

	switch {
	// func(net.Conn, []byte) error
	case typ.NumIn() == 2 && typ.In(0) == reflect.TypeOf((*net.Conn)(nil)).Elem() && typ.In(1) == reflect.TypeOf([]byte{}):
		tcps.handlerMap[t] = fn.(func(net.Conn, []byte) error)
	// func(Type, *Type) error
	case typ.NumIn() == 2 && typ.In(0).Kind() != reflect.Ptr && typ.In(1).Kind() == reflect.Ptr:
		tcps.registerRPC(t, val, typ)
	// func(Type) error
	case typ.NumIn() == 1 && typ.In(0).Kind() != reflect.Ptr:
		tcps.registerArg(t, val, typ)
	// func(*Type) error
	case typ.NumIn() == 1 && typ.In(0).Kind() == reflect.Ptr:
		tcps.registerResp(t, val, typ)
	default:
		panic("registered function has wrong type signature")
	}
}

// registerRPC is for handlers that return a value. The input is decoded and
// passed to fn, which stores its result in a pointer argument. This argument
// is then written back to the caller. fn must have the type signature:
//     func(Type, *Type) error
func (tcps *TCPServer) registerRPC(t byte, fn reflect.Value, typ reflect.Type) {
	tcps.handlerMap[t] = func(conn net.Conn, b []byte) error {
		// create object to decode into
		arg := reflect.New(typ.In(0))
		if err := encoding.Unmarshal(b, arg.Interface()); err != nil {
			return err
		}
		// call fn on object
		resp := reflect.New(typ.In(1))
		if err := fn.Call([]reflect.Value{arg.Elem(), resp})[0].Interface(); err != nil {
			return err.(error)
		}
		// write response
		_, err := WriteObject(conn, resp.Elem().Interface())
		return err
	}
}

// registerArg is for RPCs that do not return a value.
func (tcps *TCPServer) registerArg(t byte, fn reflect.Value, typ reflect.Type) {
	tcps.handlerMap[t] = func(_ net.Conn, b []byte) error {
		// create object to decode into
		arg := reflect.New(typ.In(0))
		if err := encoding.Unmarshal(b, arg.Interface()); err != nil {
			return err
		}
		// call fn on object
		if err := fn.Call([]reflect.Value{arg.Elem()})[0].Interface(); err != nil {
			return err.(error)
		}
		return nil
	}
}

// registerResp is for RPCs that do not take a value.
func (tcps *TCPServer) registerResp(t byte, fn reflect.Value, typ reflect.Type) {
	tcps.handlerMap[t] = func(conn net.Conn, _ []byte) error {
		// create object to hold response
		resp := reflect.New(typ.In(0))
		// call fn
		if err := fn.Call([]reflect.Value{resp})[0].Interface(); err != nil {
			return err.(error)
		}
		// write response
		_, err := WriteObject(conn, resp.Elem().Interface())
		return err
	}
}

// sendHostname replies to the send with the sender's external IP.
func sendHostname(conn net.Conn, _ []byte) error {
	host, _, _ := net.SplitHostPort(conn.RemoteAddr().String())
	_, err := WritePrefix(conn, []byte(host))
	return err
}

// sharePeers transmits at most 'num' peers over the connection.
// TODO: choose random peers?
func (tcps *TCPServer) sharePeers(addrs *[]NetAddress) error {
	for addr := range tcps.addressbook {
		if len(*addrs) == 10 { // arbitrary
			break
		}
		*addrs = append(*addrs, addr)
	}
	return nil
}

// addPeer adds the connecting peer to its address book
func (tcps *TCPServer) addPeer(peer NetAddress) error {
	tcps.addressbook[peer] = struct{}{}
	return nil
}
<commit_msg>fix RPC nil prefix<commit_after>package network

import (
	"errors"
	"net"
	"reflect"

	"github.com/NebulousLabs/Andromeda/encoding"
)

func ReadPrefix(conn net.Conn) ([]byte, error) {
	prefix := make([]byte, 4)
	if n, err := conn.Read(prefix); err != nil || n != len(prefix) {
		return nil, errors.New("could not read length prefix")
	}
	msgLen := int(encoding.DecUint64(prefix))
	if msgLen > maxMsgLen {
		return nil, errors.New("message too long")
	}
	// read msgLen bytes
	var data []byte
	buf := make([]byte, 1024)
	for total := 0; total < msgLen; {
		n, err := conn.Read(buf)
		if err != nil {
			return nil, err
		}
		data = append(data, buf[:n]...)
		total += n
	}
	if len(data) != msgLen {
		return nil, errors.New("message length mismatch")
	}
	return data, nil
}

func ReadObject(conn net.Conn, obj interface{}) error {
	data, err := ReadPrefix(conn)
	if err != nil {
		return err
	}
	return encoding.Unmarshal(data, obj)
}

func WritePrefix(conn net.Conn, data []byte) (int, error) {
	encLen := encoding.EncUint64(uint64(len(data)))
	return conn.Write(append(encLen[:4], data...))
}

func WriteObject(conn net.Conn, obj interface{}) (int, error) {
	return WritePrefix(conn, encoding.Marshal(obj))
}

// RPC performs a Remote Procedure Call by sending the procedure name and
// encoded argument, and decoding the response into the supplied object.
// 'resp' must be a pointer. If arg is nil, no object is sent. If 'resp' is
// nil, no response is read.
func (na *NetAddress) RPC(t byte, arg, resp interface{}) error {
	return na.Call(func(conn net.Conn) error {
		conn.Write([]byte{t})
		var data []byte
		if arg != nil {
			data = encoding.Marshal(arg)
		}
		if _, err := WritePrefix(conn, data); err != nil {
			return err
		}
		if resp != nil {
			return ReadObject(conn, resp)
		}
		return nil
	})
}

func (tcps *TCPServer) Register(t byte, fn interface{}) {
	// all handlers are function with at least one in and one error out
	val, typ := reflect.ValueOf(fn), reflect.TypeOf(fn)
	if typ.Kind() != reflect.Func || typ.NumIn() < 1 ||
		typ.NumOut() != 1 || typ.Out(0) != reflect.TypeOf((*error)(nil)).Elem() {
		panic("registered function has wrong type signature")
	}

	switch {
	// func(net.Conn, []byte) error
	case typ.NumIn() == 2 && typ.In(0) == reflect.TypeOf((*net.Conn)(nil)).Elem() && typ.In(1) == reflect.TypeOf([]byte{}):
		tcps.handlerMap[t] = fn.(func(net.Conn, []byte) error)
	// func(Type, *Type) error
	case typ.NumIn() == 2 && typ.In(0).Kind() != reflect.Ptr && typ.In(1).Kind() == reflect.Ptr:
		tcps.registerRPC(t, val, typ)
	// func(Type) error
	case typ.NumIn() == 1 && typ.In(0).Kind() != reflect.Ptr:
		tcps.registerArg(t, val, typ)
	// func(*Type) error
	case typ.NumIn() == 1 && typ.In(0).Kind() == reflect.Ptr:
		tcps.registerResp(t, val, typ)
	default:
		panic("registered function has wrong type signature")
	}
}

// registerRPC is for handlers that return a value. The input is decoded and
// passed to fn, which stores its result in a pointer argument. This argument
// is then written back to the caller. fn must have the type signature:
//     func(Type, *Type) error
func (tcps *TCPServer) registerRPC(t byte, fn reflect.Value, typ reflect.Type) {
	tcps.handlerMap[t] = func(conn net.Conn, b []byte) error {
		// create object to decode into
		arg := reflect.New(typ.In(0))
		if err := encoding.Unmarshal(b, arg.Interface()); err != nil {
			return err
		}
		// call fn on object
		resp := reflect.New(typ.In(1))
		if err := fn.Call([]reflect.Value{arg.Elem(), resp})[0].Interface(); err != nil {
			return err.(error)
		}
		// write response
		_, err := WriteObject(conn, resp.Elem().Interface())
		return err
	}
}

// registerArg is for RPCs that do not return a value.
func (tcps *TCPServer) registerArg(t byte, fn reflect.Value, typ reflect.Type) {
	tcps.handlerMap[t] = func(_ net.Conn, b []byte) error {
		// create object to decode into
		arg := reflect.New(typ.In(0))
		if err := encoding.Unmarshal(b, arg.Interface()); err != nil {
			return err
		}
		// call fn on object
		if err := fn.Call([]reflect.Value{arg.Elem()})[0].Interface(); err != nil {
			return err.(error)
		}
		return nil
	}
}

// registerResp is for RPCs that do not take a value.
func (tcps *TCPServer) registerResp(t byte, fn reflect.Value, typ reflect.Type) {
	tcps.handlerMap[t] = func(conn net.Conn, _ []byte) error {
		// create object to hold response
		resp := reflect.New(typ.In(0))
		// call fn
		if err := fn.Call([]reflect.Value{resp})[0].Interface(); err != nil {
			return err.(error)
		}
		// write response
		_, err := WriteObject(conn, resp.Elem().Interface())
		return err
	}
}

// sendHostname replies to the send with the sender's external IP.
func sendHostname(conn net.Conn, _ []byte) error {
	host, _, _ := net.SplitHostPort(conn.RemoteAddr().String())
	_, err := WritePrefix(conn, []byte(host))
	return err
}

// sharePeers transmits at most 'num' peers over the connection.
// TODO: choose random peers?
func (tcps *TCPServer) sharePeers(addrs *[]NetAddress) error {
	for addr := range tcps.addressbook {
		if len(*addrs) == 10 { // arbitrary
			break
		}
		*addrs = append(*addrs, addr)
	}
	return nil
}

// addPeer adds the connecting peer to its address book
func (tcps *TCPServer) addPeer(peer NetAddress) error {
	tcps.addressbook[peer] = struct{}{}
	return nil
}
<|endoftext|>


<commit_before>package hybrid

import (
	"math"

	"github.com/ready-steady/adapt/algorithm"
	"github.com/ready-steady/adapt/algorithm/internal"
	"github.com/ready-steady/adapt/grid"
)

const (
	none = ^uint(0)
)

var (
	infinity = math.Inf(1.0)
)

// Strategy is a basic strategy.
type Strategy struct {
	ni uint
	no uint

	guide Guide

	lmin uint
	lmax uint
	εl   float64
	εt   float64

	active *internal.Active
	hash   *internal.Hash
	unique *internal.Unique

	lndices []lndex
	indices []index

	lcursor map[string]uint
	icursor map[string]uint
}

// Guide is a grid-refinement tool of a basic strategy.
type Guide interface {
	grid.Indexer
	grid.RefinerToward
}

type lndex struct {
	score float64
	from  uint
	till  uint
}

type index struct {
	score float64
}

// NewStrategy creates a basic strategy.
func NewStrategy(inputs, outputs uint, guide Guide, minLevel, maxLevel uint,
	localError, totalError float64) *Strategy {

	return &Strategy{
		ni: inputs,
		no: outputs,

		guide: guide,

		lmin: minLevel,
		lmax: maxLevel,
		εl:   localError,
		εt:   totalError,

		active: internal.NewActive(inputs),
		hash:   internal.NewHash(inputs),
		unique: internal.NewUnique(inputs),

		lcursor: make(map[string]uint),
		icursor: make(map[string]uint),
	}
}

func (self *Strategy) First() *algorithm.State {
	state := &algorithm.State{}
	state.Lndices = self.active.First()
	state.Indices, state.Counts = internal.Index(self.guide, state.Lndices, self.ni)
	return state
}

func (self *Strategy) Next(state *algorithm.State,
	surrogate *algorithm.Surrogate) *algorithm.State {

	for {
		self.consume(state)
		if self.check() {
			return nil
		}
		k := self.choose()
		if k == none {
			return nil
		}
		state = &algorithm.State{}
		state.Lndices = self.active.Next(k)
		state.Indices, state.Counts = self.index(state.Lndices, surrogate)
		if len(state.Indices) > 0 {
			return state
		}
	}
}

func (self *Strategy) Score(element *algorithm.Element) float64 {
	return internal.MaxAbsolute(element.Surplus) * element.Volume
}

func (self *Strategy) check() bool {
	total := 0.0
	for i := range self.active.Positions {
		total += self.lndices[i].score
		if total > self.εt {
			return false
		}
	}
	return true
}

func (self *Strategy) choose() uint {
	if len(self.active.Positions) == 0 {
		return none
	}
	k, max := none, 0.0
	for i := range self.active.Positions {
		if score := self.lndices[i].score; score > max {
			k, max = i, score
		}
	}
	if max <= 0.0 {
		return none
	}
	return k
}

func (self *Strategy) consume(state *algorithm.State) {
	ni := self.ni
	nol, noi := uint(len(self.lndices)), uint(len(self.indices))
	nnl, nni := uint(len(state.Counts)), uint(len(state.Scores))

	levels := internal.Levelize(state.Lndices, ni)

	self.lndices = append(self.lndices, make([]lndex, nnl)...)
	lndices := self.lndices[nol:]

	self.indices = append(self.indices, make([]index, nni)...)
	indices := self.indices[noi:]

	for i, offset := uint(0), uint(0); i < nnl; i++ {
		count := state.Counts[i]

		if levels[i] < uint64(self.lmin) {
			lndices[i].score = infinity
			for j := uint(0); j < count; j++ {
				indices[offset+j].score = infinity
			}
		} else if levels[i] < uint64(self.lmax) {
			for j := uint(0); j < count; j++ {
				lndices[i].score = math.Max(lndices[i].score, state.Scores[offset+j])
				indices[offset+j].score = state.Scores[offset+j]
			}
		}
		lndices[i].from = noi + offset
		lndices[i].till = noi + offset + count

		lndex := state.Lndices[i*ni : (i+1)*ni]
		self.lcursor[self.hash.Key(lndex)] = nol + i
		for j := uint(0); j < count; j++ {
			index := state.Indices[(offset+j)*ni : (offset+j+1)*ni]
			self.icursor[self.hash.Key(index)] = noi + offset + j
		}

		offset += count
	}
}

func (self *Strategy) index(lndices []uint64, surrogate *algorithm.Surrogate) ([]uint64, []uint) {
	ni := self.ni
	nn := uint(len(lndices)) / ni
	indices, counts := []uint64(nil), make([]uint, nn)
	for i, offset := uint(0), uint(0); i < nn; i++ {
		lndex := lndices[i*ni : (i+1)*ni]
		for j := uint(0); j < ni; j++ {
			level := lndex[j]
			if level == 0 {
				continue
			}

			lndex[j] = level - 1
			k, ok := self.lcursor[self.hash.Key(lndex)]
			lndex[j] = level
			if !ok {
				panic("the index set is not admissible")
			}

			for k, m := self.lndices[k].from, self.lndices[k].till; k < m; k++ {
				if self.indices[k].score >= self.εl {
					index := surrogate.Indices[k*ni : (k+1)*ni]
					indices = append(indices, self.unique.Distil(
						self.guide.RefineToward(index, j))...)
				}
			}
		}
		counts[i] = uint(len(indices))/ni - offset
		offset += counts[i]
	}
	return indices, counts
}
<commit_msg>a/hybrid: move up the uniqueness check<commit_after>package hybrid

import (
	"math"

	"github.com/ready-steady/adapt/algorithm"
	"github.com/ready-steady/adapt/algorithm/internal"
	"github.com/ready-steady/adapt/grid"
)

const (
	none = ^uint(0)
)

var (
	infinity = math.Inf(1.0)
)

// Strategy is a basic strategy.
type Strategy struct {
	ni uint
	no uint

	guide Guide

	lmin uint
	lmax uint
	εl   float64
	εt   float64

	active *internal.Active
	hash   *internal.Hash
	unique *internal.Unique

	lndices []lndex
	indices []index

	lcursor map[string]uint
	icursor map[string]uint
}

// Guide is a grid-refinement tool of a basic strategy.
type Guide interface {
	grid.Indexer
	grid.RefinerToward
}

type lndex struct {
	score float64
	from  uint
	till  uint
}

type index struct {
	score float64
}

// NewStrategy creates a basic strategy.
func NewStrategy(inputs, outputs uint, guide Guide, minLevel, maxLevel uint,
	localError, totalError float64) *Strategy {

	return &Strategy{
		ni: inputs,
		no: outputs,

		guide: guide,

		lmin: minLevel,
		lmax: maxLevel,
		εl:   localError,
		εt:   totalError,

		active: internal.NewActive(inputs),
		hash:   internal.NewHash(inputs),
		unique: internal.NewUnique(inputs),

		lcursor: make(map[string]uint),
		icursor: make(map[string]uint),
	}
}

func (self *Strategy) First() *algorithm.State {
	state := &algorithm.State{}
	state.Lndices = self.active.First()
	state.Indices, state.Counts = internal.Index(self.guide, state.Lndices, self.ni)
	return state
}

func (self *Strategy) Next(state *algorithm.State,
	surrogate *algorithm.Surrogate) *algorithm.State {

	for {
		self.consume(state)
		if self.check() {
			return nil
		}
		k := self.choose()
		if k == none {
			return nil
		}

		state = &algorithm.State{}
		state.Lndices = self.active.Next(k)

		indices := self.index(state.Lndices, surrogate)
		nn := uint(len(indices))

		state.Counts = make([]uint, nn)
		for i := uint(0); i < nn; i++ {
			indices := self.unique.Distil(indices[i])
			state.Indices = append(state.Indices, indices...)
			state.Counts[i] = uint(len(indices)) / self.ni
		}

		if len(state.Indices) > 0 {
			return state
		}
	}
}

func (self *Strategy) Score(element *algorithm.Element) float64 {
	return internal.MaxAbsolute(element.Surplus) * element.Volume
}

func (self *Strategy) check() bool {
	total := 0.0
	for i := range self.active.Positions {
		total += self.lndices[i].score
		if total > self.εt {
			return false
		}
	}
	return true
}

func (self *Strategy) choose() uint {
	if len(self.active.Positions) == 0 {
		return none
	}
	k, max := none, 0.0
	for i := range self.active.Positions {
		if score := self.lndices[i].score; score > max {
			k, max = i, score
		}
	}
	if max <= 0.0 {
		return none
	}
	return k
}

func (self *Strategy) consume(state *algorithm.State) {
	ni := self.ni
	nol, noi := uint(len(self.lndices)), uint(len(self.indices))
	nnl, nni := uint(len(state.Counts)), uint(len(state.Scores))

	levels := internal.Levelize(state.Lndices, ni)

	self.lndices = append(self.lndices, make([]lndex, nnl)...)
	lndices := self.lndices[nol:]

	self.indices = append(self.indices, make([]index, nni)...)
	indices := self.indices[noi:]

	for i, offset := uint(0), uint(0); i < nnl; i++ {
		count := state.Counts[i]

		if levels[i] < uint64(self.lmin) {
			lndices[i].score = infinity
			for j := uint(0); j < count; j++ {
				indices[offset+j].score = infinity
			}
		} else if levels[i] < uint64(self.lmax) {
			for j := uint(0); j < count; j++ {
				lndices[i].score = math.Max(lndices[i].score, state.Scores[offset+j])
				indices[offset+j].score = state.Scores[offset+j]
			}
		}
		lndices[i].from = noi + offset
		lndices[i].till = noi + offset + count

		lndex := state.Lndices[i*ni : (i+1)*ni]
		self.lcursor[self.hash.Key(lndex)] = nol + i
		for j := uint(0); j < count; j++ {
			index := state.Indices[(offset+j)*ni : (offset+j+1)*ni]
			self.icursor[self.hash.Key(index)] = noi + offset + j
		}

		offset += count
	}
}

func (self *Strategy) index(lndices []uint64, surrogate *algorithm.Surrogate) [][]uint64 {
	ni := self.ni
	nn := uint(len(lndices)) / ni
	indices := make([][]uint64, nn)
	for i := uint(0); i < nn; i++ {
		lndex := lndices[i*ni : (i+1)*ni]
		for j := uint(0); j < ni; j++ {
			level := lndex[j]
			if level == 0 {
				continue
			}

			lndex[j] = level - 1
			k, ok := self.lcursor[self.hash.Key(lndex)]
			lndex[j] = level
			if !ok {
				panic("the index set is not admissible")
			}

			for k, m := self.lndices[k].from, self.lndices[k].till; k < m; k++ {
				if self.indices[k].score >= self.εl {
					index := surrogate.Indices[k*ni : (k+1)*ni]
					indices[i] = append(indices[i], self.guide.RefineToward(index, j)...)
				}
			}
		}
	}
	return indices
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"io/ioutil"
	"log"
	"os"
	"runtime"
	"strings"
	"syscall"
)

func main() {
	var dependencies []StaticLibrary
	parallels := 0
	done := make(chan bool)

	// set parallel numbers
	runtime.GOMAXPROCS(runtime.NumCPU())

	// Parse flags
	version := flag.String("v", NGINX_VERSION, "nginx version")
	nginxConfigurePath := flag.String("c", "", "configuration file for building nginx")
	modulesConfPath := flag.String("m", "", "configuration file for 3rd party modules")
	workParentDir := flag.String("d", "", "working directory")
	jobs := flag.Int("j", runtime.NumCPU(), "jobs to build nginx")
	verbose := flag.Bool("verbose", false, "verbose mode")
	pcreStatic := flag.Bool("pcre", false, "embedded PCRE statically")
	pcreVersion := flag.String("pcreversion", PCRE_VERSION, "PCRE version")
	openSSLStatic := flag.Bool("openssl", false, "embedded OpenSSL statically")
	openSSLVersion := flag.String("opensslversion", OPENSSL_VERSION, "OpenSSL version")
	zlibStatic := flag.Bool("zlib", false, "embedded zlib statically")
	zlibVersion := flag.String("zlibversion", ZLIB_VERSION, "zlib version")
	clear := flag.Bool("clear", false, "remove entries in working directory")
	versionPrint := flag.Bool("version", false, "print nginx-build versions")
	versionsPrint := flag.Bool("versions", false, "print nginx versions")
	openResty := flag.Bool("openresty", false, "download openresty instead of nginx")
	tengine := flag.Bool("tengine", false, "download tengine instead of nginx")
	openRestyVersion := flag.String("openrestyversion", OPENRESTY_VERSION, "openresty version")
	tengineVersion := flag.String("tengineversion", TENGINE_VERSION, "tengine version")
	configureOnly := flag.Bool("configureonly", false, "configuring nginx only not building")

	var configureOptions ConfigureOptions
	argsString := makeArgsString()
	argsBool := makeArgsBool()
	var multiflag StringFlag

	for k, v := range argsString {
		if k == "add-module" {
			flag.Var(&multiflag, k, v.Desc)
		} else {
			v.Value = flag.String(k, "", v.Desc)
			argsString[k] = v
		}
	}

	for k, v := range argsBool {
		v.Enabled = flag.Bool(k, false, v.Desc)
		argsBool[k] = v
	}

	flag.Parse()

	// Allow multiple flags for `--add-module`
	{
		tmp := argsString["add-module"]
		tmp_ := multiflag.String()
		tmp.Value = &tmp_
		argsString["add-module"] = tmp
	}

	configureOptions.Values = argsString
	configureOptions.Bools = argsBool

	if *versionPrint {
		printNginxBuildVersion()
		os.Exit(0)
	}

	if *versionsPrint {
		printNginxVersions()
		os.Exit(0)
	}

	printFirstMsg()

	// set verbose mode
	VerboseEnabled = *verbose

	var nginxBuilder Builder
	if *openResty && *tengine {
		log.Fatal("select one between '-openresty' and '-tengine'.")
	}
	if *openResty {
		nginxBuilder = makeBuilder(COMPONENT_OPENRESTY, *openRestyVersion)
	} else if *tengine {
		nginxBuilder = makeBuilder(COMPONENT_TENGINE, *tengineVersion)
	} else {
		nginxBuilder = makeBuilder(COMPONENT_NGINX, *version)
	}
	pcreBuilder := makeBuilder(COMPONENT_PCRE, *pcreVersion)
	openSSLBuilder := makeBuilder(COMPONENT_OPENSSL, *openSSLVersion)
	zlibBuilder := makeBuilder(COMPONENT_ZLIB, *zlibVersion)

	// change default umask
	_ = syscall.Umask(0)

	versionCheck(*version)

	nginxConfigure, err := fileGetContents(*nginxConfigurePath)
	if err != nil {
		log.Fatal(err)
	}
	nginxConfigure = normalizeConfigure(nginxConfigure)

	modules3rd, err := loadModules3rdFile(*modulesConfPath)
	if err != nil {
		log.Fatal(err)
	}

	if len(*workParentDir) == 0 {
		log.Fatal("set working directory with -d")
	}

	if !fileExists(*workParentDir) {
		err := os.Mkdir(*workParentDir, 0755)
		if err != nil {
			log.Fatalf("Failed to create working directory(%s) does not exist.", *workParentDir)
		}
	}

	var workDir string
	if *openResty {
		workDir = *workParentDir + "/" + *openRestyVersion
	} else if *tengine {
		workDir = *workParentDir + "/" + *tengineVersion
	} else {
		workDir = *workParentDir + "/" + *version
	}
	if *clear {
		err := clearWorkDir(workDir)
		if err != nil {
			log.Fatal(err)
		}
	}

	if !fileExists(workDir) {
		err := os.Mkdir(workDir, 0755)
		if err != nil {
			log.Fatalf("Failed to create working directory(%s) does not exist.", workDir)
		}
	}

	rootDir := saveCurrentDir()
	// cd workDir
	err = os.Chdir(workDir)
	if err != nil {
		log.Fatal(err)
	}

	if *pcreStatic {
		parallels++
		go downloadAndExtractParallel(&pcreBuilder, done)
	}

	if *openSSLStatic {
		parallels++
		go downloadAndExtractParallel(&openSSLBuilder, done)
	}

	if *zlibStatic {
		parallels++
		go downloadAndExtractParallel(&zlibBuilder, done)
	}

	parallels++
	go downloadAndExtractParallel(&nginxBuilder, done)

	if len(modules3rd) > 0 {
		parallels += len(modules3rd)
		for _, m := range modules3rd {
			go downloadAndExtractModule3rdParallel(m, done)
		}

	}

	// wait until all downloading processes by goroutine finish
	for i := 0; i < parallels; i++ {
		<-done
	}

	if len(modules3rd) > 0 {
		for _, m := range modules3rd {
			provideModule3rd(&m)
		}
	}

	// cd workDir/nginx-${version}
	os.Chdir(nginxBuilder.sourcePath())

	if *pcreStatic {
		dependencies = append(dependencies, makeStaticLibrary(&pcreBuilder))
	}

	if *openSSLStatic {
		dependencies = append(dependencies, makeStaticLibrary(&openSSLBuilder))
	}

	if *zlibStatic {
		dependencies = append(dependencies, makeStaticLibrary(&zlibBuilder))
	}

	log.Printf("Generate configure script for %s.....", nginxBuilder.sourcePath())

	if *pcreStatic && pcreBuilder.isIncludeWithOption(nginxConfigure) {
		log.Printf(pcreBuilder.warnMsgWithLibrary())
	}

	if *openSSLStatic && openSSLBuilder.isIncludeWithOption(nginxConfigure) {
		log.Printf(openSSLBuilder.warnMsgWithLibrary())

	}

	if *zlibStatic && zlibBuilder.isIncludeWithOption(nginxConfigure) {
		log.Printf(zlibBuilder.warnMsgWithLibrary())
	}

	if strings.Contains(nginxConfigure, "--add-module=") {
		log.Println("[warn]Using '--add-module' is discouraged. Instead give ini-file with '-m' to 'nginx-build'")
	}

	configureScript := configureGen(nginxConfigure, modules3rd, dependencies, configureOptions, rootDir)

	err = ioutil.WriteFile("./nginx-configure", []byte(configureScript), 0655)
	if err != nil {
		log.Fatalf("Failed to generate configure script for %s", nginxBuilder.sourcePath())
	}

	log.Printf("Configure %s.....", nginxBuilder.sourcePath())

	err = configureNginx()
	if err != nil {
		log.Printf("Failed to configure %s\n", nginxBuilder.sourcePath())
		printFatalMsg(err, "nginx-configure.log")
	}

	if *configureOnly {
		printLastMsg(workDir, nginxBuilder.sourcePath(), *openResty, *configureOnly)
		return
	}

	log.Printf("Build %s.....", nginxBuilder.sourcePath())

	if *openSSLStatic {
		// Workarounds for protecting a failure of building nginx with static-linked OpenSSL.

		// Unfortunately a build of OpenSSL fails when multi-CPUs are used.
		*jobs = 1

		// Sometimes machine hardware name('uname -m') is different
		// from machine processor architecture name('uname -p') on Mac.
		// Specifically, `uname -p` is 'i386' and `uname -m` is 'x86_64'.
		// In this case, a build of OpenSSL fails.
		// So it needs to convince OpenSSL with KERNEL_BITS.
		if runtime.GOOS == "darwin" && runtime.GOARCH == "amd64" {
			os.Setenv("KERNEL_BITS", "64")
		}
	}

	err = buildNginx(*jobs)
	if err != nil {
		log.Printf("Failed to build %s\n", nginxBuilder.sourcePath())
		printFatalMsg(err, "nginx-build.log")
	}

	printLastMsg(workDir, nginxBuilder.sourcePath(), *openResty, *configureOnly)

	// cd rootDir
	os.Chdir(rootDir)
}
<commit_msg>changed working directory layout.<commit_after>package main

import (
	"flag"
	"io/ioutil"
	"log"
	"os"
	"runtime"
	"strings"
	"syscall"
)

func main() {
	var dependencies []StaticLibrary
	parallels := 0
	done := make(chan bool)

	// set parallel numbers
	runtime.GOMAXPROCS(runtime.NumCPU())

	// Parse flags
	version := flag.String("v", NGINX_VERSION, "nginx version")
	nginxConfigurePath := flag.String("c", "", "configuration file for building nginx")
	modulesConfPath := flag.String("m", "", "configuration file for 3rd party modules")
	workParentDir := flag.String("d", "", "working directory")
	jobs := flag.Int("j", runtime.NumCPU(), "jobs to build nginx")
	verbose := flag.Bool("verbose", false, "verbose mode")
	pcreStatic := flag.Bool("pcre", false, "embedded PCRE statically")
	pcreVersion := flag.String("pcreversion", PCRE_VERSION, "PCRE version")
	openSSLStatic := flag.Bool("openssl", false, "embedded OpenSSL statically")
	openSSLVersion := flag.String("opensslversion", OPENSSL_VERSION, "OpenSSL version")
	zlibStatic := flag.Bool("zlib", false, "embedded zlib statically")
	zlibVersion := flag.String("zlibversion", ZLIB_VERSION, "zlib version")
	clear := flag.Bool("clear", false, "remove entries in working directory")
	versionPrint := flag.Bool("version", false, "print nginx-build versions")
	versionsPrint := flag.Bool("versions", false, "print nginx versions")
	openResty := flag.Bool("openresty", false, "download openresty instead of nginx")
	tengine := flag.Bool("tengine", false, "download tengine instead of nginx")
	openRestyVersion := flag.String("openrestyversion", OPENRESTY_VERSION, "openresty version")
	tengineVersion := flag.String("tengineversion", TENGINE_VERSION, "tengine version")
	configureOnly := flag.Bool("configureonly", false, "configuring nginx only not building")

	var configureOptions ConfigureOptions
	argsString := makeArgsString()
	argsBool := makeArgsBool()
	var multiflag StringFlag

	for k, v := range argsString {
		if k == "add-module" {
			flag.Var(&multiflag, k, v.Desc)
		} else {
			v.Value = flag.String(k, "", v.Desc)
			argsString[k] = v
		}
	}

	for k, v := range argsBool {
		v.Enabled = flag.Bool(k, false, v.Desc)
		argsBool[k] = v
	}

	flag.Parse()

	// Allow multiple flags for `--add-module`
	{
		tmp := argsString["add-module"]
		tmp_ := multiflag.String()
		tmp.Value = &tmp_
		argsString["add-module"] = tmp
	}

	configureOptions.Values = argsString
	configureOptions.Bools = argsBool

	if *versionPrint {
		printNginxBuildVersion()
		os.Exit(0)
	}

	if *versionsPrint {
		printNginxVersions()
		os.Exit(0)
	}

	printFirstMsg()

	// set verbose mode
	VerboseEnabled = *verbose

	var nginxBuilder Builder
	if *openResty && *tengine {
		log.Fatal("select one between '-openresty' and '-tengine'.")
	}
	if *openResty {
		nginxBuilder = makeBuilder(COMPONENT_OPENRESTY, *openRestyVersion)
	} else if *tengine {
		nginxBuilder = makeBuilder(COMPONENT_TENGINE, *tengineVersion)
	} else {
		nginxBuilder = makeBuilder(COMPONENT_NGINX, *version)
	}
	pcreBuilder := makeBuilder(COMPONENT_PCRE, *pcreVersion)
	openSSLBuilder := makeBuilder(COMPONENT_OPENSSL, *openSSLVersion)
	zlibBuilder := makeBuilder(COMPONENT_ZLIB, *zlibVersion)

	// change default umask
	_ = syscall.Umask(0)

	versionCheck(*version)

	nginxConfigure, err := fileGetContents(*nginxConfigurePath)
	if err != nil {
		log.Fatal(err)
	}
	nginxConfigure = normalizeConfigure(nginxConfigure)

	modules3rd, err := loadModules3rdFile(*modulesConfPath)
	if err != nil {
		log.Fatal(err)
	}

	if len(*workParentDir) == 0 {
		log.Fatal("set working directory with -d")
	}

	if !fileExists(*workParentDir) {
		err := os.Mkdir(*workParentDir, 0755)
		if err != nil {
			log.Fatalf("Failed to create working directory(%s) does not exist.", *workParentDir)
		}
	}

	var workDir string
	if *openResty {
		workDir = *workParentDir + "/openresty/" + *openRestyVersion
	} else if *tengine {
		workDir = *workParentDir + "/tengine/" + *tengineVersion
	} else {
		workDir = *workParentDir + "/nginx/" + *version
	}
	if *clear {
		err := clearWorkDir(workDir)
		if err != nil {
			log.Fatal(err)
		}
	}

	if !fileExists(workDir) {
		err := os.MkdirAll(workDir, 0755)
		if err != nil {
			log.Fatalf("Failed to create working directory(%s) does not exist.", workDir)
		}
	}

	rootDir := saveCurrentDir()
	// cd workDir
	err = os.Chdir(workDir)
	if err != nil {
		log.Fatal(err)
	}

	if *pcreStatic {
		parallels++
		go downloadAndExtractParallel(&pcreBuilder, done)
	}

	if *openSSLStatic {
		parallels++
		go downloadAndExtractParallel(&openSSLBuilder, done)
	}

	if *zlibStatic {
		parallels++
		go downloadAndExtractParallel(&zlibBuilder, done)
	}

	parallels++
	go downloadAndExtractParallel(&nginxBuilder, done)

	if len(modules3rd) > 0 {
		parallels += len(modules3rd)
		for _, m := range modules3rd {
			go downloadAndExtractModule3rdParallel(m, done)
		}

	}

	// wait until all downloading processes by goroutine finish
	for i := 0; i < parallels; i++ {
		<-done
	}

	if len(modules3rd) > 0 {
		for _, m := range modules3rd {
			provideModule3rd(&m)
		}
	}

	// cd workDir/nginx-${version}
	os.Chdir(nginxBuilder.sourcePath())

	if *pcreStatic {
		dependencies = append(dependencies, makeStaticLibrary(&pcreBuilder))
	}

	if *openSSLStatic {
		dependencies = append(dependencies, makeStaticLibrary(&openSSLBuilder))
	}

	if *zlibStatic {
		dependencies = append(dependencies, makeStaticLibrary(&zlibBuilder))
	}

	log.Printf("Generate configure script for %s.....", nginxBuilder.sourcePath())

	if *pcreStatic && pcreBuilder.isIncludeWithOption(nginxConfigure) {
		log.Printf(pcreBuilder.warnMsgWithLibrary())
	}

	if *openSSLStatic && openSSLBuilder.isIncludeWithOption(nginxConfigure) {
		log.Printf(openSSLBuilder.warnMsgWithLibrary())

	}

	if *zlibStatic && zlibBuilder.isIncludeWithOption(nginxConfigure) {
		log.Printf(zlibBuilder.warnMsgWithLibrary())
	}

	if strings.Contains(nginxConfigure, "--add-module=") {
		log.Println("[warn]Using '--add-module' is discouraged. Instead give ini-file with '-m' to 'nginx-build'")
	}

	configureScript := configureGen(nginxConfigure, modules3rd, dependencies, configureOptions, rootDir)

	err = ioutil.WriteFile("./nginx-configure", []byte(configureScript), 0655)
	if err != nil {
		log.Fatalf("Failed to generate configure script for %s", nginxBuilder.sourcePath())
	}

	log.Printf("Configure %s.....", nginxBuilder.sourcePath())

	err = configureNginx()
	if err != nil {
		log.Printf("Failed to configure %s\n", nginxBuilder.sourcePath())
		printFatalMsg(err, "nginx-configure.log")
	}

	if *configureOnly {
		printLastMsg(workDir, nginxBuilder.sourcePath(), *openResty, *configureOnly)
		return
	}

	log.Printf("Build %s.....", nginxBuilder.sourcePath())

	if *openSSLStatic {
		// Workarounds for protecting a failure of building nginx with static-linked OpenSSL.

		// Unfortunately a build of OpenSSL fails when multi-CPUs are used.
		*jobs = 1

		// Sometimes machine hardware name('uname -m') is different
		// from machine processor architecture name('uname -p') on Mac.
		// Specifically, `uname -p` is 'i386' and `uname -m` is 'x86_64'.
		// In this case, a build of OpenSSL fails.
		// So it needs to convince OpenSSL with KERNEL_BITS.
		if runtime.GOOS == "darwin" && runtime.GOARCH == "amd64" {
			os.Setenv("KERNEL_BITS", "64")
		}
	}

	err = buildNginx(*jobs)
	if err != nil {
		log.Printf("Failed to build %s\n", nginxBuilder.sourcePath())
		printFatalMsg(err, "nginx-build.log")
	}

	printLastMsg(workDir, nginxBuilder.sourcePath(), *openResty, *configureOnly)

	// cd rootDir
	os.Chdir(rootDir)
}
<|endoftext|>


<commit_before>package main

import "bytes"

/*
	TFTP v2 RFC http://tools.ietf.org/html/rfc1350
	TFTP Option Extension http://tools.ietf.org/html/rfc2347
	TODO: TFTP Blocksize Option http://tools.ietf.org/html/rfc2348http://tools.ietf.org/html/rfc2348
	TODO: TFTP Timeout Interval and Transfer Size Options http://tools.ietf.org/html/rfc2349http://tools.ietf.org/html/rfc2349
	TODO: TFTP Windowsize Option http://tools.ietf.org/html/rfc7440
*/

const (
	//OpcodeRead Read request (RRQ)
	OpcodeRead uint16 = 1
	//OpcodeWrite Write request (WRQ)
	OpcodeWrite uint16 = 2
	//OpcodeData Data (DATA)
	OpcodeData uint16 = 3
	//OpcodeACK Acknowledgment (ACK)
	OpcodeACK uint16 = 4
	//OpcodeErr Error (ERROR)
	OpcodeErr uint16 = 5
)

const (
	//ErrorNotDefined Not defined, see error message (if any).
	ErrorNotDefined = 0
	//ErrorFileNotFound File not found.
	ErrorFileNotFound = 1
	//ErrorAccessViolation Access violation.
	ErrorAccessViolation = 2
	//ErrorDiskFull Disk full or allocation exceeded.
	ErrorDiskFull = 3
	//ErrorIllegalOp Illegal TFTP operation.
	ErrorIllegalOp = 4
	//ErrorUnknownID Unknown transfer ID.
	ErrorUnknownID = 5
	//ErrorFileAlreadyExists File already exists.
	ErrorFileAlreadyExists = 6
	//ErrorNoSuchUser No such user.
	ErrorNoSuchUser = 7
)

const (
	//ModeNetASCII mode netascii
	ModeNetASCII string = "netascii"
	//ModeOctet mode octet
	ModeOctet string = "octet"
	//ModeMail mode mail
	ModeMail string = "mail"
)

/*
	RRQ/WRQ packet

	2 bytes     string    1 byte     string   1 byte
	------------------------------------------------
	| Opcode |  Filename  |   0  |    Mode    |   0  |
	------------------------------------------------

*/

//TFTPPacket interface to packet types
type TFTPPacket interface {
	Pack() []byte
	Unpack()
}

//TFTPReadWritePkt RRQ/WRQ packet
type TFTPReadWritePkt struct {
	Opcode   uint16
	Filename string
	Mode     string
}

//Pack returns []byte payload
func (p *TFTPReadWritePkt) Pack() []byte {
	var buff bytes.Buffer
	buff.Write([]byte{byte(p.Opcode)})
	buff.Write([]byte(p.Filename))
	buff.Write([]byte{0})
	buff.Write([]byte(p.Mode))
	buff.Write([]byte{0})
	return buff.Bytes()
}

//Unpack loads []byte payload
func (p *TFTPReadWritePkt) Unpack(data []byte) {
	p.Opcode = uint16(data[1])
	msgParsed := bytes.Split(data[2:len(data)], []byte{00})
	p.Filename = string(msgParsed[0])
	p.Mode = string(msgParsed[1])
}

//TFTPDataPkt TFTP data Packet
type TFTPDataPkt struct {
	Opcode uint16
	Block  int
	Data   []byte
}

//Pack returns []byte payload
func (p *TFTPDataPkt) Pack() []byte {
	var buff bytes.Buffer
	buff.Write([]byte{0})
	buff.Write([]byte{byte(p.Opcode)})
	buff.Write([]byte{0})
	buff.Write([]byte{byte(p.Block)})
	buff.Write([]byte(p.Data))
	return buff.Bytes()
}

//Unpack loads []byte payload
func (p *TFTPDataPkt) Unpack(data []byte) {
}

//TFTPAckPkt TFTP ACK Packet
type TFTPAckPkt struct {
	Opcode []byte
	Block  []byte
}

//Pack returns []byte payload
func (p *TFTPAckPkt) Pack() []byte {
	var buff bytes.Buffer
	buff.Write(p.Opcode)
	buff.Write([]byte(p.Block))
	return buff.Bytes()
}

//Unpack loads []byte payload
func (p *TFTPAckPkt) Unpack(data []byte) {
}

//TFTPErrPkt TFTP error Packet
type TFTPErrPkt struct {
	Opcode  []byte
	ErrCode []byte
	ErrMsg  string
}

//Pack returns []byte payload
func (p *TFTPErrPkt) Pack() []byte {
	var buff bytes.Buffer
	buff.Write(p.Opcode)
	buff.Write([]byte(p.ErrCode))
	buff.Write([]byte(p.ErrMsg))
	buff.Write([]byte{0})
	return buff.Bytes()
}

//Unpack loads []byte payload
func (p *TFTPErrPkt) Unpack(data []byte) {
}

//TFTPOptionPkt TFTP Option packet
type TFTPOptionPkt struct {
	Opcode    []byte
	OptionAck []byte
	Value1    []byte
	OptN      []byte
	ValueN    []byte
}

//Pack returns []byte payload
func (p *TFTPOptionPkt) Pack() []byte {
	var buff bytes.Buffer
	buff.Write(p.Opcode)
	buff.Write(p.OptionAck)
	buff.Write([]byte{0})
	buff.Write(p.Value1)
	buff.Write([]byte{0})
	buff.Write(p.OptN)
	buff.Write([]byte{0})
	buff.Write(p.ValueN)
	buff.Write([]byte{0})
	return buff.Bytes()
}

//Unpack loads []byte payload
func (p *TFTPOptionPkt) Unpack() {
}
<commit_msg>handle write requests. Completed basic state handling of client<commit_after>package main

import (
	"bytes"
	"encoding/binary"
)

/*
	TFTP v2 RFC http://tools.ietf.org/html/rfc1350
	TFTP Option Extension http://tools.ietf.org/html/rfc2347
	TODO: TFTP Blocksize Option http://tools.ietf.org/html/rfc2348
	TODO: TFTP Timeout Interval and Transfer Size Options http://tools.ietf.org/html/rfc2349
	TODO: TFTP Windowsize Option http://tools.ietf.org/html/rfc7440
*/

const (
	//OpcodeRead Read request (RRQ)
	OpcodeRead uint16 = 1
	//OpcodeWrite Write request (WRQ)
	OpcodeWrite uint16 = 2
	//OpcodeData Data (DATA)
	OpcodeData uint16 = 3
	//OpcodeACK Acknowledgment (ACK)
	OpcodeACK uint16 = 4
	//OpcodeErr Error (ERROR)
	OpcodeErr uint16 = 5
)

const (
	//ErrorNotDefined Not defined, see error message (if any).
	ErrorNotDefined uint16 = 0
	//ErrorFileNotFound File not found.
	ErrorFileNotFound uint16 = 1
	//ErrorAccessViolation Access violation.
	ErrorAccessViolation uint16 = 2
	//ErrorDiskFull Disk full or allocation exceeded.
	ErrorDiskFull uint16 = 3
	//ErrorIllegalOp Illegal TFTP operation.
	ErrorIllegalOp uint16 = 4
	//ErrorUnknownID Unknown transfer ID.
	ErrorUnknownID uint16 = 5
	//ErrorFileAlreadyExists File already exists.
	ErrorFileAlreadyExists uint16 = 6
	//ErrorNoSuchUser No such user.
	ErrorNoSuchUser uint16 = 7
)

const (
	//ModeNetASCII mode netascii
	ModeNetASCII string = "netascii"
	//ModeOctet mode octet
	ModeOctet string = "octet"
	//ModeMail mode mail
	ModeMail string = "mail"
)

const (
	//DefaultBlockSize the default block size of a connection
	DefaultBlockSize int = 512
)

/*
	RRQ/WRQ packet

	2 bytes     string    1 byte     string   1 byte
	------------------------------------------------
	| Opcode |  Filename  |   0  |    Mode    |   0  |
	------------------------------------------------

*/

//TFTPPacket interface to packet types
type TFTPPacket interface {
	Pack() []byte
	Unpack()
}

//TFTPReadWritePkt RRQ/WRQ packet
type TFTPReadWritePkt struct {
	Opcode   uint16
	Filename string
	Mode     string
}

//Pack returns []byte payload
func (p *TFTPReadWritePkt) Pack() []byte {
	buff := new(bytes.Buffer)
	err := binary.Write(buff, binary.BigEndian, p.Opcode)
	if err != nil {
		panic(err)
	}
	buff.Write([]byte(p.Filename))
	buff.Write([]byte{0})
	buff.Write([]byte(p.Mode))
	buff.Write([]byte{0})
	return buff.Bytes()
}

//Unpack loads []byte payload
func (p *TFTPReadWritePkt) Unpack(data []byte) {
	p.Opcode = uint16(data[1])
	msgParsed := bytes.Split(data[2:len(data)], []byte{00})
	p.Filename = string(msgParsed[0])
	p.Mode = string(msgParsed[1])
}

//TFTPDataPkt TFTP data Packet
type TFTPDataPkt struct {
	Opcode uint16
	Block  uint16
	Data   []byte
}

//Pack returns []byte payload
func (p *TFTPDataPkt) Pack() []byte {
	var err error
	buff := new(bytes.Buffer)
	err = binary.Write(buff, binary.BigEndian, p.Opcode)
	if err != nil {
		panic(err)
	}
	buff.Write([]byte{0})
	err = binary.Write(buff, binary.BigEndian, p.Block)
	if err != nil {
		panic(err)
	}
	buff.Write([]byte(p.Data))
	return buff.Bytes()
}

//Unpack loads []byte payload
func (p *TFTPDataPkt) Unpack(data []byte) {
	p.Opcode = uint16(data[1])
	p.Block = uint16(data[3])
	p.Data = data[4:]
}

//TFTPAckPkt TFTP ACK Packet
type TFTPAckPkt struct {
	Opcode uint16
	Block  uint16
}

//Pack returns []byte payload
func (p *TFTPAckPkt) Pack() []byte {
	var err error
	buff := new(bytes.Buffer)
	err = binary.Write(buff, binary.BigEndian, p.Opcode)
	if err != nil {
		panic(err)
	}
	err = binary.Write(buff, binary.BigEndian, p.Block)
	if err != nil {
		panic(err)
	}
	return buff.Bytes()
}

//Unpack loads []byte payload
func (p *TFTPAckPkt) Unpack(data []byte) {
}

//TFTPErrPkt TFTP error Packet
type TFTPErrPkt struct {
	Opcode  uint16
	ErrCode uint16
	ErrMsg  string
}

//Pack returns []byte payload
func (p *TFTPErrPkt) Pack() []byte {
	var err error
	buff := new(bytes.Buffer)
	err = binary.Write(buff, binary.BigEndian, p.Opcode)
	if err != nil {
		panic(err)
	}
	err = binary.Write(buff, binary.BigEndian, p.ErrCode)
	if err != nil {
		panic(err)
	}
	buff.Write([]byte(p.ErrMsg))
	buff.Write([]byte{0})
	return buff.Bytes()
}

//Unpack loads []byte payload
func (p *TFTPErrPkt) Unpack(data []byte) {
}

//TFTPOptionPkt TFTP Option packet
type TFTPOptionPkt struct {
	Opcode    uint16
	OptionAck []byte
	Value1    []byte
	OptN      []byte
	ValueN    []byte
}

//Pack returns []byte payload
func (p *TFTPOptionPkt) Pack() []byte {
	buff := new(bytes.Buffer)
	err := binary.Write(buff, binary.BigEndian, p.Opcode)
	if err != nil {
		panic(err)
	}
	buff.Write(p.OptionAck)
	buff.Write([]byte{0})
	buff.Write(p.Value1)
	buff.Write([]byte{0})
	buff.Write(p.OptN)
	buff.Write([]byte{0})
	buff.Write(p.ValueN)
	buff.Write([]byte{0})
	return buff.Bytes()
}

//Unpack loads []byte payload
func (p *TFTPOptionPkt) Unpack() {
}
<|endoftext|>