<commit_before>package main

import (
	"github.com/gobs/cmd"

	"fmt"
	"strings"
)

var (
	words = []string{"one", "two", "three", "four"}
)

func CompletionFunction(text, line string) (matches []string) {
	// for the "ls" command we let readline show real file names
	if strings.HasPrefix(line, "ls ") {
		return
	}

	// for all other commands, we pick from our list of completion words
	for _, w := range words {
		if strings.HasPrefix(w, text) {
			matches = append(matches, w)
		}
	}

	return
}

func Exit(line string) (stop bool) {
	fmt.Println("goodbye!")
	return true
}

func main() {
	commander := &cmd.Cmd{HistoryFile: ".rlhistory", Complete: CompletionFunction, EnableShell: true}
	commander.Init()

	commander.Add(cmd.Command{
		"ls",
		`list stuff`,
		func(line string) (stop bool) {
			fmt.Println("listing stuff")
			return
		},
		nil})

	commander.Add(cmd.Command{
		Name: ">",
		Help: `Set prompt`,
		Call: func(line string) (stop bool) {
			commander.Prompt = line
			return
		}})

	commander.Add(cmd.Command{
		"exit",
		`terminate example`,
		Exit,
		nil})

	commander.CmdLoop()
}
<commit_msg>Added args command. A good way to see how command line parsing works<commit_after>package main

import (
	"github.com/gobs/cmd"
	"github.com/gobs/args"

	"fmt"
	"strings"
)

var (
	words = []string{"one", "two", "three", "four"}
)

func CompletionFunction(text, line string) (matches []string) {
	// for the "ls" command we let readline show real file names
	if strings.HasPrefix(line, "ls ") {
		return
	}

	// for all other commands, we pick from our list of completion words
	for _, w := range words {
		if strings.HasPrefix(w, text) {
			matches = append(matches, w)
		}
	}

	return
}

func Exit(line string) (stop bool) {
	fmt.Println("goodbye!")
	return true
}

func main() {
	commander := &cmd.Cmd{HistoryFile: ".rlhistory", Complete: CompletionFunction, EnableShell: true}
	commander.Init()

	commander.Add(cmd.Command{
		"ls",
		`list stuff`,
		func(line string) (stop bool) {
			fmt.Println("listing stuff")
			return
		},
		nil})

	commander.Add(cmd.Command{
		Name: ">",
		Help: `Set prompt`,
		Call: func(line string) (stop bool) {
			commander.Prompt = line
			return
		}})

	commander.Add(cmd.Command{
		Name: "args",
		Help: "parse args",
		Call: func(line string) (stop bool) {
			fmt.Printf("%q\n", args.GetArgs(line))
			return
		}})

	commander.Add(cmd.Command{
		"exit",
		`terminate example`,
		Exit,
		nil})

	commander.CmdLoop()
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/hex"
	"encoding/json"
	"github.com/cfilipov/apns"
)

func main() {
	cert, _ := apns.LoadPemFile("notifyme_cert.pem") // Load the pem file from the current dir.
	conn, _ := apns.DialAPN(&cert, apns.SANDBOX, false)
	token, _ := hex.DecodeString("beefca5e") // Use a real APNs token.

	jsonData := make(map[string]interface{})
	aps := map[string]string{}
	aps["alert"] = "Hello World!"
	jsonData["aps"] = aps
	payload, _ := json.Marshal(jsonData)

	notification := apns.SimpleNotification{
		TokenLength:   uint16(len(token)),
		DeviceToken:   token,
		PayloadLength: uint16(len(payload)),
		Payload:       payload,
	}

	notification.WriteTo(conn)
}
<commit_msg>Simplify example.go<commit_after>package main

import (
	"encoding/hex"
	"github.com/cfilipov/apns"
)

func main() {
	cert, _ := apns.LoadPemFile("notifyme_cert.pem") // Load the pem file from the current dir.
	conn, _ := apns.DialAPN(&cert, apns.SANDBOX, false)
	token, _ := hex.DecodeString("beefca5e") // Use a real APNs token.
	payload := []byte(`{"aps":{"alert":"Hello World!"}}`)

	notification := apns.SimpleNotification{
		TokenLength:   uint16(len(token)),
		DeviceToken:   token,
		PayloadLength: uint16(len(payload)),
		Payload:       payload,
	}

	notification.WriteTo(conn)
}
<|endoftext|>


<commit_before>package mockos

import (
	"bytes"
	"crypto/rand"
	"testing"

	"github.com/golang/protobuf/proto"
	"github.com/google/gnxi/utils/mockos/pb"
	"github.com/kylelemons/godebug/pretty"
)

func TestHashValidation(t *testing.T) {
	tests := []struct {
		os   *OS
		want bool
	}{
		{
			os: &OS{
				MockOS: pb.MockOS{
					Version:               "1.0a",
					Cookie:                "yyhnueaolrkoehvxcphhkxgvcilzppoh",
					Padding:               []byte("These are some bits to pad things out"),
					Incompatible:          true,
					ActivationFailMessage: "This is a test activationFailMessage",
					Hash:                  []byte{252, 85, 174, 147, 254, 203, 37, 51, 0, 249, 102, 183, 117, 56, 23, 63},
				},
			},
			want: true,
		},
		{
			os: &OS{
				MockOS: pb.MockOS{
					Version:               "2.2b",
					Cookie:                "yyhnueaolrasdfasdgdfsgdflkjsakfsdkoh",
					Padding:               []byte("These are some bits to pad things out a lot!"),
					Incompatible:          true,
					ActivationFailMessage: "This is a test activationFailMessage",
					Hash:                  []byte("Bad Hash"),
				},
			},
		},
	}

	for _, test := range tests {
		got := test.os.CheckHash()
		if got != test.want {
			t.Errorf("Want %v, Got %v", test.want, got)
		}
	}
}

func TestValidateOS(t *testing.T) {
	tests := []struct {
		os *OS
	}{
		{
			os: &OS{
				MockOS: pb.MockOS{
					Version:               "1.0a",
					Cookie:                "yyhnueaolrkoehvxcphhkxgvcilzppoh",
					Padding:               []byte("These are some bits to pad things out"),
					Incompatible:          false,
					ActivationFailMessage: "",
					Hash:                  []byte{236, 238, 38, 29, 175, 162, 142, 132, 150, 19, 79, 233, 230, 165, 179, 35},
				},
			},
		},
		{
			os: &OS{
				MockOS: pb.MockOS{
					Version:               "2.2b",
					Cookie:                "yyhnueaolrasdfasdgdfsgdflkjsakfsdkoh",
					Padding:               []byte("These are some bits to pad things out a lot!"),
					Incompatible:          false,
					ActivationFailMessage: "This is a test activationFailMessage",
					Hash:                  []byte("Bad Hash"),
				},
			},
		},
		{
			os: &OS{
				MockOS: pb.MockOS{
					Version:               "1.0a",
					Cookie:                "yyhnueaolrkoehvxcphhkxgvcilzppoh",
					Padding:               []byte("These are some bits to pad things out"),
					Incompatible:          true,
					ActivationFailMessage: "This is a test activationFailMessage",
					Hash:                  []byte{252, 85, 174, 147, 254, 203, 37, 51, 0, 249, 102, 183, 117, 56, 23, 63},
				},
			},
		},
		{
			os: nil,
		},
	}
	for _, test := range tests {
		var serializedOS []byte
		if test.os != nil {
			serializedOS, _ = proto.Marshal(&test.os.MockOS)
		} else {
			serializedOS = make([]byte, 1000000)
			rand.Read(serializedOS)
		}
		bb := new(bytes.Buffer)
		bb.Write(serializedOS)
		os := ValidateOS(bb)
		if diff := pretty.Compare(test.os, os); diff != "" {
			t.Errorf("ValidateOS(): (-want +got):\n%s", diff)
		}
	}
}
<commit_msg>Ignore XXX_SizeCache field in pb.MockOS struct<commit_after>package mockos

import (
	"bytes"
	"crypto/rand"
	"testing"

	"github.com/golang/protobuf/proto"
	"github.com/google/gnxi/utils/mockos/pb"
	"github.com/google/go-cmp/cmp"
	"github.com/google/go-cmp/cmp/cmpopts"
)

func TestHashValidation(t *testing.T) {
	tests := []struct {
		os   *OS
		want bool
	}{
		{
			os: &OS{
				MockOS: pb.MockOS{
					Version:               "1.0a",
					Cookie:                "yyhnueaolrkoehvxcphhkxgvcilzppoh",
					Padding:               []byte("These are some bits to pad things out"),
					Incompatible:          true,
					ActivationFailMessage: "This is a test activationFailMessage",
					Hash:                  []byte{252, 85, 174, 147, 254, 203, 37, 51, 0, 249, 102, 183, 117, 56, 23, 63},
				},
			},
			want: true,
		},
		{
			os: &OS{
				MockOS: pb.MockOS{
					Version:               "2.2b",
					Cookie:                "yyhnueaolrasdfasdgdfsgdflkjsakfsdkoh",
					Padding:               []byte("These are some bits to pad things out a lot!"),
					Incompatible:          true,
					ActivationFailMessage: "This is a test activationFailMessage",
					Hash:                  []byte("Bad Hash"),
				},
			},
		},
	}

	for _, test := range tests {
		got := test.os.CheckHash()
		if got != test.want {
			t.Errorf("Want %v, Got %v", test.want, got)
		}
	}
}

func TestValidateOS(t *testing.T) {
	tests := []struct {
		os *OS
	}{
		{
			os: &OS{
				MockOS: pb.MockOS{
					Version:               "1.0a",
					Cookie:                "yyhnueaolrkoehvxcphhkxgvcilzppoh",
					Padding:               []byte("These are some bits to pad things out"),
					Incompatible:          false,
					ActivationFailMessage: "",
					Hash:                  []byte{236, 238, 38, 29, 175, 162, 142, 132, 150, 19, 79, 233, 230, 165, 179, 35},
				},
			},
		},
		{
			os: &OS{
				MockOS: pb.MockOS{
					Version:               "2.2b",
					Cookie:                "yyhnueaolrasdfasdgdfsgdflkjsakfsdkoh",
					Padding:               []byte("These are some bits to pad things out a lot!"),
					Incompatible:          false,
					ActivationFailMessage: "This is a test activationFailMessage",
					Hash:                  []byte("Bad Hash"),
				},
			},
		},
		{
			os: &OS{
				MockOS: pb.MockOS{
					Version:               "1.0a",
					Cookie:                "yyhnueaolrkoehvxcphhkxgvcilzppoh",
					Padding:               []byte("These are some bits to pad things out"),
					Incompatible:          true,
					ActivationFailMessage: "This is a test activationFailMessage",
					Hash:                  []byte{252, 85, 174, 147, 254, 203, 37, 51, 0, 249, 102, 183, 117, 56, 23, 63},
				},
			},
		},
		{
			os: nil,
		},
	}
	for _, test := range tests {
		var serializedOS []byte
		if test.os != nil {
			serializedOS, _ = proto.Marshal(&test.os.MockOS)
		} else {
			serializedOS = make([]byte, 1000000)
			rand.Read(serializedOS)
		}
		bb := new(bytes.Buffer)
		bb.Write(serializedOS)
		os := ValidateOS(bb)
		if diff := cmp.Diff(test.os, os, cmpopts.IgnoreFields(pb.MockOS{}, "XXX_sizecache")); diff != "" {
			t.Errorf("ValidateOS(): (-want +got):\n%s", diff)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/YoungPioneers/blog4go"
	"os"
	"os/signal"
	"runtime"
	"syscall"
	"time"
)

type MyHook struct {
	something string
}

func (self *MyHook) Fire(level blog4go.Level, message string) {
	if level > blog4go.ERROR {
		fmt.Println(message)
	}
}

func main() {
	runtime.GOMAXPROCS(4)

	writers, err := blog4go.NewFileWriterFromConfigAsFile("config.xml")
	if nil != err {
		fmt.Println(err.Error())
		os.Exit(1)
	}
	defer writers.Close()
	writers.Debug("Debug")
	writers.Trace("Trace")
	writers.Info("Info")
	writers.Warn("Warn")
	writers.Error("Error")
	writers.Critical("Critical")

	// blog
	//writer, err := blog4go.NewBaseFileWriter("output.log")
	//if nil != err {
	//fmt.Println(err.Error())
	//os.Exit(1)
	//}
	//defer writer.Close()

	// test rotate line
	//writer.SetRotateLines(100)

	// test hook
	//hook := new(MyHook)
	//writer.SetHook(hook)

	//for i := 1; i < 5; i++ {
	//go logging(writer)
	//}

	// blog writers
	//writers, err := blog4go.NewFileWriter("./")
	//if nil != err {
	//fmt.Println(err.Error())
	//os.Exit(1)
	//}
	//defer writers.Close()
	//writers.Debug("Debug")
	//writers.Trace("Trace")
	//writers.Info("Info")
	//writers.Warn("Warn")
	//writers.Error("Error")
	//writers.Critical("Critical")

	// socket writer
	// nc -u -l 12124
	//socketWriter, err := blog4go.NewSocketWriter("udp", "127.0.0.1:12124")
	//defer socketWriter.Close()
	//socketWriter.Debug("debug")

	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGTERM, os.Interrupt, os.Kill)

	for {
		select {
		case <-c:
			fmt.Println("Exit..")
			time.Sleep(1 * time.Second)
			return
		}
	}
}

type T struct {
	A int
	B string
}

// blog
func logging(writer *blog4go.BaseFileWriter) {
	t := T{123, "test"}
	d := int64(18)
	for {
		writer.Debug("test_debug")
		writer.Trace("test_trace")
		writer.Info("test_info")
		writer.Warn("test_warn")
		writer.Error("test_error")
		writer.Critical("test_critical")
		writer.Debugf("haha %s. en\\en, always %d and %5.4f, %t, %+v", "eddie", d, 3.14159, true, t)
		time.Sleep(2 * time.Second)
	}
}
<commit_msg>fix测试用例<commit_after>package main

import (
	"fmt"
	"github.com/YoungPioneers/blog4go"
	"os"
	"os/signal"
	"runtime"
	"syscall"
	"time"
)

type MyHook struct {
	something string
}

func (self *MyHook) Fire(level blog4go.Level, message string) {
	if level > blog4go.ERROR {
		fmt.Println(message)
	}
}

func main() {
	runtime.GOMAXPROCS(4)

	writers, err := blog4go.NewFileWriterFromConfigAsFile("config.xml")
	if nil != err {
		fmt.Println(err.Error())
		os.Exit(1)
	}
	defer writers.Close()
	writers.Debug("Debug")
	writers.Trace("Trace")
	writers.Info("Info")
	writers.Warn("Warn")
	writers.Error("Error")
	writers.Critical("Critical")

	// blog
	writer, err := blog4go.NewBaseFileWriter("output.log")
	if nil != err {
		fmt.Println(err.Error())
		os.Exit(1)
	}
	defer writer.Close()

	// test rotate line
	writer.SetRotateLines(100)

	// test hook
	hook := new(MyHook)
	writer.SetHook(hook)

	for i := 1; i < 5; i++ {
		go logging(writer)
	}

	// blog writers
	pure_writers, err := blog4go.NewFileWriter("./")
	if nil != err {
		fmt.Println(err.Error())
		os.Exit(1)
	}
	defer pure_writers.Close()
	pure_writers.Debug("Debug")
	pure_writers.Trace("Trace")
	pure_writers.Info("Info")
	pure_writers.Warn("Warn")
	pure_writers.Error("Error")
	pure_writers.Critical("Critical")

	// socket writer
	// nc -u -l 12124
	socketWriter, err := blog4go.NewSocketWriter("udp", "127.0.0.1:12124")
	defer socketWriter.Close()
	socketWriter.Debug("debug")

	c := make(chan os.Signal, 1)
	signal.Notify(c, syscall.SIGTERM, os.Interrupt, os.Kill)

	for {
		select {
		case <-c:
			fmt.Println("Exit..")
			time.Sleep(1 * time.Second)
			return
		}
	}
}

type T struct {
	A int
	B string
}

// blog
func logging(writer *blog4go.BaseFileWriter) {
	t := T{123, "test"}
	d := int64(18)
	for {
		writer.Debug("test_debug")
		writer.Trace("test_trace")
		writer.Info("test_info")
		writer.Warn("test_warn")
		writer.Error("test_error")
		writer.Critical("test_critical")
		writer.Debugf("haha %s. en\\en, always %d and %5.4f, %t, %+v", "eddie", d, 3.14159, true, t)
		time.Sleep(2 * time.Second)
	}
}
<|endoftext|>


<commit_before>package main

import (
        "fmt"
        "github.com/soh335/go-dnssd"
)

func main() {
        bc := make(chan *dnssd.BrowseReply)
        ctx, berr := dnssd.Browse(dnssd.DNSServiceInterfaceIndexAny, "_http._tcp", bc)

        if berr != nil {
                fmt.Println(berr)
                return
        }

        go dnssd.Process(ctx)

        for {
                browseReply, ok := <-bc
                if !ok {
                  fmt.Println("closed")
                  break
                }
                fmt.Println(browseReply)

                fmt.Println("start resolve")

                rc := make(chan *dnssd.ResolveReply)
                rctx, rerr := dnssd.Resolve(
                        dnssd.DNSServiceFlagsForceMulticast,
                        browseReply.InterfaceIndex,
                        browseReply.ServiceName,
                        browseReply.RegType,
                        browseReply.ReplyDomain,
                        rc,
                )

                if rerr != nil {
                        fmt.Println(rerr)
                        return
                }

                go dnssd.Process(rctx)

                resolveReply, _ := <-rc
                fmt.Println(resolveReply)

                qc := make(chan *dnssd.QueryRecordReply)
                qctx, qerr := dnssd.QueryRecord(
                        dnssd.DNSServiceFlagsForceMulticast,
                        resolveReply.InterfaceIndex,
                        resolveReply.FullName,
                        dnssd.DNSServiceType_SRV,
                        dnssd.DNSServiceClass_IN,
                        qc,
                )

                if qerr != nil {
                        fmt.Println(qerr)
                        return
                }

                go dnssd.Process(qctx)

                queryRecordReply, _ := <-qc
                fmt.Println(queryRecordReply)
                fmt.Println(queryRecordReply.SRV())

                gc := make(chan *dnssd.GetAddrInfoReply)
                gctx, gerr := dnssd.GetAddrInfo(
                        dnssd.DNSServiceFlagsForceMulticast,
                        0,
                        dnssd.DNSServiceProtocol_IPv4,
                        resolveReply.HostTarget,
                        gc,
                )

                if gerr != nil {
                        fmt.Println(gerr)
                        return
                }

                go dnssd.Process(gctx)

                getAddrInfoReply, _ := <-gc
                fmt.Println(getAddrInfoReply)
        }
}

<commit_msg>update example/test.go<commit_after>package main

import (
        "fmt"
        "github.com/soh335/go-dnssd"
)

func main() {
        bc := make(chan *dnssd.BrowseReply)
        ctx, err := dnssd.Browse(dnssd.DNSServiceInterfaceIndexAny, "_http._tcp", bc)

        if err != nil {
                fmt.Println(err)
                return
        }

        go dnssd.Process(ctx)

        for {
                browseReply, ok := <-bc
                if !ok {
                  fmt.Println("closed")
                  break
                }
                fmt.Println(browseReply)

                fmt.Println("start resolve")

                rc := make(chan *dnssd.ResolveReply)
                rctx, err := dnssd.Resolve(
                        dnssd.DNSServiceFlagsForceMulticast,
                        browseReply.InterfaceIndex,
                        browseReply.ServiceName,
                        browseReply.RegType,
                        browseReply.ReplyDomain,
                        rc,
                )

                if err != nil {
                        fmt.Println(err)
                        return
                }

                go dnssd.Process(rctx)

                resolveReply, _ := <-rc
                fmt.Println(resolveReply)

                qc := make(chan *dnssd.QueryRecordReply)
                qctx, err := dnssd.QueryRecord(
                        dnssd.DNSServiceFlagsForceMulticast,
                        resolveReply.InterfaceIndex,
                        resolveReply.FullName,
                        dnssd.DNSServiceType_SRV,
                        dnssd.DNSServiceClass_IN,
                        qc,
                )

                if err != nil {
                        fmt.Println(err)
                        return
                }

                go dnssd.Process(qctx)

                queryRecordReply, _ := <-qc
                fmt.Println(queryRecordReply)
                fmt.Println(queryRecordReply.SRV())

                gc := make(chan *dnssd.GetAddrInfoReply)
                gctx, err := dnssd.GetAddrInfo(
                        dnssd.DNSServiceFlagsForceMulticast,
                        0,
                        dnssd.DNSServiceProtocol_IPv4,
                        resolveReply.HostTarget,
                        gc,
                )

                if err != nil {
                        fmt.Println(err)
                        return
                }

                go dnssd.Process(gctx)

                getAddrInfoReply, _ := <-gc
                fmt.Println(getAddrInfoReply)
        }
}

<|endoftext|>


<commit_before>package validates
<commit_msg>Write test cases for "validates" package.<commit_after>package validates

import (
	"testing"
)

type shapeTest struct {
	Rows    int
	Columns int
}

func TestShapeShouldBePositiveCausesNothing(t *testing.T) {
	test := &shapeTest{Rows: 1, Columns: 1}

	defer func() {
		if p := recover(); p != nil {
			t.Error("Positive rows or columns should be valid, but causes panic.")
			t.Fatalf(
				"# rows = %d, columns = %d",
				test.Rows,
				test.Columns,
			)
		}
	}()
	ShapeShouldBePositive(test.Rows, test.Columns)
}

func TestShapeShouldBePositiveCausePanicWithZeroRwos(t *testing.T) {
	test := shapeTest{Rows: 0, Columns: 1}

	defer func() {
		if p := recover(); p != NON_POSITIVE_SIZE_PANIC {
			t.Error(
				"Non-positive rows or columns should be invalid, but causes nothing.",
			)
			t.Fatalf(
				"# rows = %d, columns = %d",
				test.Rows,
				test.Columns,
			)
		}
	}()
	ShapeShouldBePositive(test.Rows, test.Columns)
}

func TestShapeShouldBePositiveCausePanicWithZeroColumns(t *testing.T) {
	test := shapeTest{Rows: 1, Columns: 0}

	defer func() {
		if p := recover(); p != NON_POSITIVE_SIZE_PANIC {
			t.Error(
				"Non-positive rows or columns should be invalid, but causes nothing.",
			)
			t.Fatalf(
				"# rows = %d, columns = %d",
				test.Rows,
				test.Columns,
			)
		}
	}()
	ShapeShouldBePositive(test.Rows, test.Columns)
}

func TestShapeShouldBePositiveCausePanicWithZeros(t *testing.T) {
	test := shapeTest{Rows: 0, Columns: 0}

	defer func() {
		if p := recover(); p != NON_POSITIVE_SIZE_PANIC {
			t.Error(
				"Non-positive rows or columns should be invalid, but causes nothing.",
			)
			t.Fatalf(
				"# rows = %d, columns = %d",
				test.Rows,
				test.Columns,
			)
		}
	}()
	ShapeShouldBePositive(test.Rows, test.Columns)
}

func TestShapeShouldBePositiveCausePanicWithNegativeRows(t *testing.T) {
	test := shapeTest{Rows: -1, Columns: 0}

	defer func() {
		if p := recover(); p != NON_POSITIVE_SIZE_PANIC {
			t.Error(
				"Non-positive rows or columns should be invalid, but causes nothing.",
			)
			t.Fatalf(
				"# rows = %d, columns = %d",
				test.Rows,
				test.Columns,
			)
		}
	}()
	ShapeShouldBePositive(test.Rows, test.Columns)
}

func TestShapeShouldBePositiveCausePanicWithNegativeColumnns(t *testing.T) {
	test := shapeTest{Rows: 0, Columns: -1}

	defer func() {
		if p := recover(); p != NON_POSITIVE_SIZE_PANIC {
			t.Error(
				"Non-positive rows or columns should be invalid, but causes nothing.",
			)
			t.Fatalf(
				"# rows = %d, columns = %d",
				test.Rows,
				test.Columns,
			)
		}
	}()
	ShapeShouldBePositive(test.Rows, test.Columns)
}

func TestShapeShouldBePositiveCausePanicWithNegative(t *testing.T) {
	test := shapeTest{Rows: -1, Columns: -1}

	defer func() {
		if p := recover(); p != NON_POSITIVE_SIZE_PANIC {
			t.Error(
				"Non-positive rows or columns should be invalid, but causes nothing.",
			)
			t.Fatalf(
				"# rows = %d, columns = %d",
				test.Rows,
				test.Columns,
			)
		}
	}()
	ShapeShouldBePositive(test.Rows, test.Columns)
}

type indexTest struct {
	Row    int
	Column int
}

type rangeTest struct {
	Shape shapeTest
	Index indexTest
}

func TestIndexShouldBeInRangeCausesNothing(t *testing.T) {
	testSeq := []*rangeTest{
		&rangeTest{
			Shape: shapeTest{Rows: 4, Columns: 3},
			Index: indexTest{Row: 0, Column: 0},
		},

		&rangeTest{
			Shape: shapeTest{Rows: 4, Columns: 3},
			Index: indexTest{Row: 0, Column: 1},
		},

		&rangeTest{
			Shape: shapeTest{Rows: 4, Columns: 3},
			Index: indexTest{Row: 1, Column: 0},
		},

		&rangeTest{
			Shape: shapeTest{Rows: 4, Columns: 3},
			Index: indexTest{Row: 3, Column: 0},
		},

		&rangeTest{
			Shape: shapeTest{Rows: 4, Columns: 3},
			Index: indexTest{Row: 0, Column: 2},
		},

		&rangeTest{
			Shape: shapeTest{Rows: 4, Columns: 3},
			Index: indexTest{Row: 3, Column: 2},
		},
	}

	for _, test := range testSeq {
		defer func(test *rangeTest) {
			if p := recover(); p != nil {
				t.Error("Inside-of-range index should be valid, but causes panic.")
				t.Fatalf(
					"# rows = %d, columns = %d, row = %d, column = %d",
					test.Shape.Rows,
					test.Shape.Columns,
					test.Index.Row,
					test.Index.Column,
				)
			}
		}(test)

		IndexShouldBeInRange(
			test.Shape.Rows,
			test.Shape.Columns,
			test.Index.Row,
			test.Index.Column,
		)
	}
}

func TestIndexShouldBeInRangeCausesPanicWithNegativeRow(t *testing.T) {
	test := &rangeTest{
		Shape: shapeTest{Rows: 4, Columns: 3},
		Index: indexTest{Row: -1, Column: 0},
	}

	defer func() {
		if p := recover(); p != OUT_OF_RANGE_PANIC {
			t.Error("Outside-of-range index should be invalid, but causes nothing.")
			t.Fatalf(
				"# rows = %d, columns = %d, row = %d, column = %d",
				test.Shape.Rows,
				test.Shape.Columns,
				test.Index.Row,
				test.Index.Column,
			)
		}
	}()

	IndexShouldBeInRange(
		test.Shape.Rows,
		test.Shape.Columns,
		test.Index.Row,
		test.Index.Column,
	)
}

func TestIndexShouldBeInRangeCausesPanicWithNegativeColumn(t *testing.T) {
	test := &rangeTest{
		Shape: shapeTest{Rows: 4, Columns: 3},
		Index: indexTest{Row: 0, Column: -1},
	}

	defer func() {
		if p := recover(); p != OUT_OF_RANGE_PANIC {
			t.Error("Outside-of-range index should be invalid, but causes nothing.")
			t.Fatalf(
				"# rows = %d, columns = %d, row = %d, column = %d",
				test.Shape.Rows,
				test.Shape.Columns,
				test.Index.Row,
				test.Index.Column,
			)
		}
	}()

	IndexShouldBeInRange(
		test.Shape.Rows,
		test.Shape.Columns,
		test.Index.Row,
		test.Index.Column,
	)
}

func TestIndexShouldBeInRangeCausesPanicWithNegative(t *testing.T) {
	test := &rangeTest{
		Shape: shapeTest{Rows: 4, Columns: 3},
		Index: indexTest{Row: -1, Column: -1},
	}

	defer func() {
		if p := recover(); p != OUT_OF_RANGE_PANIC {
			t.Error("Outside-of-range index should be invalid, but causes nothing.")
			t.Fatalf(
				"# rows = %d, columns = %d, row = %d, column = %d",
				test.Shape.Rows,
				test.Shape.Columns,
				test.Index.Row,
				test.Index.Column,
			)
		}
	}()

	IndexShouldBeInRange(
		test.Shape.Rows,
		test.Shape.Columns,
		test.Index.Row,
		test.Index.Column,
	)
}

func TestIndexShouldBeInRangeCausesPanicWithLargeRow(t *testing.T) {
	test := &rangeTest{
		Shape: shapeTest{Rows: 4, Columns: 3},
		Index: indexTest{Row: 4, Column: 0},
	}

	defer func() {
		if p := recover(); p != OUT_OF_RANGE_PANIC {
			t.Error("Outside-of-range index should be invalid, but causes nothing.")
			t.Fatalf(
				"# rows = %d, columns = %d, row = %d, column = %d",
				test.Shape.Rows,
				test.Shape.Columns,
				test.Index.Row,
				test.Index.Column,
			)
		}
	}()

	IndexShouldBeInRange(
		test.Shape.Rows,
		test.Shape.Columns,
		test.Index.Row,
		test.Index.Column,
	)
}

func TestIndexShouldBeInRangeCausesPanicWithLargeColumn(t *testing.T) {
	test := &rangeTest{
		Shape: shapeTest{Rows: 4, Columns: 3},
		Index: indexTest{Row: 0, Column: 3},
	}

	defer func() {
		if p := recover(); p != OUT_OF_RANGE_PANIC {
			t.Error("Outside-of-range index should be invalid, but causes nothing.")
			t.Fatalf(
				"# rows = %d, columns = %d, row = %d, column = %d",
				test.Shape.Rows,
				test.Shape.Columns,
				test.Index.Row,
				test.Index.Column,
			)
		}
	}()

	IndexShouldBeInRange(
		test.Shape.Rows,
		test.Shape.Columns,
		test.Index.Row,
		test.Index.Column,
	)
}

func TestIndexShouldBeInRangeCausesPanicWithLarge(t *testing.T) {
	test := &rangeTest{
		Shape: shapeTest{Rows: 4, Columns: 3},
		Index: indexTest{Row: 4, Column: 3},
	}

	defer func() {
		if p := recover(); p != OUT_OF_RANGE_PANIC {
			t.Error("Outside-of-range index should be invalid, but causes nothing.")
			t.Fatalf(
				"# rows = %d, columns = %d, row = %d, column = %d",
				test.Shape.Rows,
				test.Shape.Columns,
				test.Index.Row,
				test.Index.Column,
			)
		}
	}()

	IndexShouldBeInRange(
		test.Shape.Rows,
		test.Shape.Columns,
		test.Index.Row,
		test.Index.Column,
	)
}
<|endoftext|>


<commit_before>package skiplist_test

import (
	"fmt"

	. "github.com/kkdai/skiplist"
)

func ExampleNewSkipList() {
	//New a skiplist
	sl := NewSkipList()

	//Insert search key 50, value "5", value could be anything.
	sl.Insert(50, "5")
}

func ExampleSearch() {
	//New a skiplist
	sl := NewSkipList()

	//Insert search key 50, value "5", value could be anything.
	sl.Insert(50, "5")
	sl.Insert(40, "4")
	sl.Insert(70, "7")
	sl.Insert(100, "10")

	//Search key, which time complexity O(log n)
	ret, err := sl.Search(50)
	if err == nil {
		fmt.Println("key 50: val->", ret)
	} else {
		fmt.Println("Not found, ", err)
	}
}

func ExampleDelete() {
	//New a skiplist
	sl := NewSkipList()

	//Insert search key 50, value "5", value could be anything.
	sl.Insert(70, "7")

	//Delete by search key
	err := sl.Delete(70)
	if err != nil {
		fmt.Println("Delete not found")
	}
}
<commit_msg>More about example naming convention<commit_after>package skiplist_test

import (
	"fmt"

	. "github.com/kkdai/skiplist"
)

func ExampleNewSkipList() {
	//New a skiplist
	sl := NewSkipList()
}

func ExampleSkiplist_Insert() {
	//New a skiplist
	sl := NewSkipList()

	//Insert search key 50, value "5", value could be anything.
	sl.Insert(50, "5")
}

func ExampleSkiplist_Search() {
	//New a skiplist
	sl := NewSkipList()

	//Insert search key 50, value "5", value could be anything.
	sl.Insert(50, "5")
	sl.Insert(40, "4")
	sl.Insert(70, "7")
	sl.Insert(100, "10")

	//Search key, which time complexity O(log n)
	ret, err := sl.Search(50)
	if err == nil {
		fmt.Println("key 50: val->", ret)
	} else {
		fmt.Println("Not found, ", err)
	}
}

func ExampleSkiplist_Delete() {
	//New a skiplist
	sl := NewSkipList()

	//Insert search key 50, value "5", value could be anything.
	sl.Insert(70, "7")

	//Delete by search key
	err := sl.Delete(70)
	if err != nil {
		fmt.Println("Delete not found")
	}
}
<|endoftext|>


<commit_before>// Copyright (C) 2015 Thomas de Zeeuw.
//
// Licensed onder the MIT license that can be found in the LICENSE file.

package logger

import (
	"errors"
	"fmt"
	"time"
)

func ExampleTags() {
	tags := Tags{"tag1", "tag2"}
	fmt.Print(tags.String())
	// Output:
	// tag1, tag2
}

func ExampleMsg() {
	msg := Msg{Error, "My message", Tags{"tag1", "tag2"}, time.Now()}
	fmt.Print(msg.String())
	// Prints:
	// 2015-05-24 17:39:50 [ERROR] tag1, tag2: My message
}

func ExampleLogger_Fatal() {
	log, err := NewConsole("App")
	if err != nil {
		panic(err)
	}

	defer func() {
		if recv := recover(); recv != nil {
			log.Fatal(Tags{"file.go", "main"}, recv)
		}
	}()
	panic("Oh no!")
	// Logs:
	// 2015-03-01 17:20:52 [FATAL] file.go, main: Oh no!
	// goroutine 1 [running]:
	// github.com/Thomasdezeeuw/logger.(*Logger).Fatal(0xc08200a200,0xc08201fe00)
	// 	/go/src/github.com/Thomasdezeeuw/logger/logger.go:97 +0x8d
	// main.func·001()
	// 	/go/src/github.com/Thomasdezeeuw/logger/_examples/file.go:35 +0xc4
	// main.main()
	// 	/go/src/github.com/Thomasdezeeuw/logger/_examples/file.go:53 +0x2a9
}

func ExampleLogger_Error() {
	log, err := NewConsole("App")
	if err != nil {
		panic(err)
	}

	err = errors.New("Some error")
	log.Error(Tags{"file.go", "main"}, err)
	// Logs:
	// 2015-03-01 17:20:52 [ERROR] file.go, main: Some error
}

func ExampleLogger_Info() {
	log, err := NewConsole("App")
	if err != nil {
		panic(err)
	}

	log.Info(Tags{"file.go", "main"}, "my %s message", "info")
	// Logs:
	// 2015-03-01 17:20:52 [INFO ] file.go, main: My info message
}

func ExampleLogger_Debug() {
	log, err := NewConsole("App")
	if err != nil {
		panic(err)
	}

	log.Debug(Tags{"file.go", "main"}, "my %s message", "debug")
	// Logs:
	// 2015-03-01 17:20:52 [DEBUG] file.go, main: My debug message
}

func ExampleGet() {
	// First create a logger, for example in the main init function.
	log1, err := NewConsole("App")
	if err != nil {
		panic(err)
	}

	// Then get the logger somewhere else.
	log2, err := Get("App")
	if err != nil {
		panic(err)
	}

	log1.Info(Tags{"main"}, "Both these messages")
	log2.Info(Tags{"main"}, "are writting to the same logger")
}
<commit_msg>Fix examples<commit_after>// Copyright (C) 2015 Thomas de Zeeuw.
//
// Licensed onder the MIT license that can be found in the LICENSE file.

package logger

import (
	"errors"
	"fmt"
	"time"
)

func ExampleTags() {
	tags := Tags{"tag1", "tag2"}
	fmt.Print(tags.String())
	// Output:
	// tag1, tag2
}

func ExampleMsg() {
	t, _ := time.Parse("2006-01-02 15:04:05", "2015-05-24 17:39:50")
	msg := Msg{Error, "My message", Tags{"tag1", "tag2"}, t}
	fmt.Print(msg.String())
	// Output:
	// 2015-05-24 17:39:50 [Error] tag1, tag2: My message
}

func ExampleLogger_Fatal() {
	log, err := NewConsole("App")
	if err != nil {
		panic(err)
	}

	defer func() {
		if recv := recover(); recv != nil {
			log.Fatal(Tags{"file.go", "main"}, recv)
		}
	}()
	panic("Oh no!")
	// Logs:
	// 2015-03-01 17:20:52 [FATAL] file.go, main: Oh no!
	// goroutine 1 [running]:
	// github.com/Thomasdezeeuw/logger.(*Logger).Fatal(0xc08200a200,0xc08201fe00)
	// 	/go/src/github.com/Thomasdezeeuw/logger/logger.go:97 +0x8d
	// main.func·001()
	// 	/go/src/github.com/Thomasdezeeuw/logger/_examples/file.go:35 +0xc4
	// main.main()
	// 	/go/src/github.com/Thomasdezeeuw/logger/_examples/file.go:53 +0x2a9
}

func ExampleLogger_Error() {
	log, err := NewConsole("App")
	if err != nil {
		panic(err)
	}

	err = errors.New("Some error")
	log.Error(Tags{"file.go", "main"}, err)
	// Logs:
	// 2015-03-01 17:20:52 [Error] file.go, main: Some error
}

func ExampleLogger_Info() {
	log, err := NewConsole("App")
	if err != nil {
		panic(err)
	}

	log.Info(Tags{"file.go", "main"}, "my %s message", "info")
	// Logs:
	// 2015-03-01 17:20:52 [info] file.go, main: My info message
}

func ExampleLogger_Debug() {
	log, err := NewConsole("App")
	if err != nil {
		panic(err)
	}

	log.Debug(Tags{"file.go", "main"}, "my %s message", "debug")
	// Logs:
	// 2015-03-01 17:20:52 [debug] file.go, main: My debug message
}

func ExampleGet() {
	// First create a logger, for example in the main init function.
	log1, err := NewConsole("App")
	if err != nil {
		panic(err)
	}

	// Then get the logger somewhere else.
	log2, err := Get("App")
	if err != nil {
		panic(err)
	}

	log1.Info(Tags{"main"}, "Both these messages")
	log2.Info(Tags{"main"}, "are writting to the same logger")
}
<|endoftext|>


<commit_before>package nagiosplugin_test

import (
	"github.com/fractalcat/nagiosplugin"
	"math"
)

func ExampleExit() {
	nagiosplugin.Exit(nagiosplugin.CRITICAL, "Badness over 9000!")
}

func Example() {
	check := nagiosplugin.NewCheck()
	// Make sure the check always (as much as possible) exits with
	// the correct output and return code.
	defer check.Finish()
	// (If the check panicked on the next line, it'd exit with a
	// default UNKNOWN result.)
	//
	// Our check is testing the internal consistency of the
	// universe.
	value := math.Pi
	// We add a counter metric with a minimum of zero, an unbounded
	// maximum, a warning threshold of 4000.0 and a critical
	// threshold of 9000.0 (for graphing purposes).
	check.AddPerfDatum("badness", "c", value, 0.0, math.Inf(1), 4000.0, 9000.0)
	// Add an OK check result as the universe appears sane.
	check.AddResult(nagiosplugin.OK, "Everything looks shiny from here, cap'n")
	// We potentially perform more checks and add more results here;
	// if there's more than one, the highest result will be the one
	// returned (in order OK, WARNING, CRITICAL, UNKNOWN).

	// Output:
	// OK: Everything looks shiny from here, cap'n | badness=3.141592653589793c;4000;9000;0;
}
<commit_msg>Actually, pi should be dimensionless<commit_after>package nagiosplugin_test

import (
	"github.com/fractalcat/nagiosplugin"
	"math"
)

func ExampleExit() {
	nagiosplugin.Exit(nagiosplugin.CRITICAL, "Badness over 9000!")
}

func Example() {
	check := nagiosplugin.NewCheck()
	// Make sure the check always (as much as possible) exits with
	// the correct output and return code.
	defer check.Finish()
	// (If the check panicked on the next line, it'd exit with a
	// default UNKNOWN result.)
	//
	// Our check is testing the internal consistency of the
	// universe.
	value := math.Pi
	// We add a dimensionless metric with a minimum of zero, an
	// unbounded maximum, a warning threshold of 4000.0 and a
	// critical threshold of 9000.0 (for graphing purposes).
	check.AddPerfDatum("badness", "", value, 0.0, math.Inf(1), 4000.0, 9000.0)
	// Add an OK check result as the universe appears sane.
	check.AddResult(nagiosplugin.OK, "Everything looks shiny from here, cap'n")
	// We potentially perform more checks and add more results here;
	// if there's more than one, the highest result will be the one
	// returned (in order OK, WARNING, CRITICAL, UNKNOWN).

	// Output:
	// OK: Everything looks shiny from here, cap'n | badness=3.141592653589793;4000;9000;0;
}
<|endoftext|>


<commit_before>package daemon_test

import (
	"fmt"
	"go-daemon"
	"log"
	"os"
	"os/signal"
	"syscall"
)

func ExampleReborn() {
	if err := daemon.Reborn(027, "/"); err != nil {
		os.Exit(1)
	}

	signals := make(chan os.Signal, 8)
	signal.Notify(signals, syscall.SIGKILL, syscall.SIGTERM)
	for sig := range signals {
		if sig == syscall.SIGTERM {
			return
		}
	}
}

func ExampleRedirectStream() {
	file, err := os.OpenFile("/tmp/daemon-log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600)
	if err != nil {
		os.Exit(1)
	}

	if err = daemon.RedirectStream(os.Stdout, file); err != nil {
		os.Exit(2)
	}
	if err = daemon.RedirectStream(os.Stderr, file); err != nil {
		os.Exit(2)
	}
	file.Close()

	fmt.Println("some message")
	log.Println("some message")
}
<commit_msg>+ Реализована функция ExampleServeSignals<commit_after>package daemon_test

import (
	"fmt"
	"go-daemon"
	"log"
	"os"
	"os/signal"
	"syscall"
)

func ExampleReborn() {
	if err := daemon.Reborn(027, "/"); err != nil {
		os.Exit(1)
	}

	signals := make(chan os.Signal, 8)
	signal.Notify(signals, syscall.SIGKILL, syscall.SIGTERM)
	for sig := range signals {
		if sig == syscall.SIGTERM {
			return
		}
	}
}

func ExampleRedirectStream() {
	file, err := os.OpenFile("/tmp/daemon-log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600)
	if err != nil {
		os.Exit(1)
	}

	if err = daemon.RedirectStream(os.Stdout, file); err != nil {
		os.Exit(2)
	}
	if err = daemon.RedirectStream(os.Stderr, file); err != nil {
		os.Exit(2)
	}
	file.Close()

	fmt.Println("some message")
	log.Println("some message")
}

func ExampleServeSignals() {

	TermHandler := func(sig os.Signal) (stop bool, err error) {
		log.Println("SIGTERM:", sig)
		stop = true
		return
	}

	HupHandler := func(sig os.Signal) (stop bool, err error) {
		log.Println("SIGHUP:", sig)
		stop = false
		return
	}

	daemon.SignalsHandler(TermHandler, syscall.SIGTERM, syscall.SIGKILL)
	daemon.SignalsHandler(HupHandler, syscall.SIGHUP)

	err := daemon.ServeSignals()
	if err != nil {
		log.Println("Error:", err)
	}
}
<|endoftext|>


<commit_before>package net

import (
	"bytes"
	"encoding/json"
	"fmt"
	e "gowork/error"
	"gowork/extern/logging"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)

var (
	HTTP_METHOD_GET    = "GET"
	HTTP_METHOD_PUT    = "PUT"
	HTTP_METHOD_POST   = "POST"
	HTTP_METHOD_PATCH  = "PATCH"
	HTTP_METHOD_DELETE = "DELETE"

	CONTENT_NONE = ""
	CONTENT_JSON = "application/json"
	CONTENT_YAML = "application/yaml"
)

type HTTPRequest struct {
	Method       string
	URL          string
	UserID       string
	X_Auth_Token string
	Form         interface{}
	Body         interface{}
}

type HTTPResponse struct {
	Code int         `json:"code, omitempty"`
	Msg  string      `json:"msg, omitempty"`
	Data interface{} `json:"data, omitempty"`
}

type IRequest interface {
	DoRequest(resp interface{}) *e.WError
}

// warpper
type Responser http.ResponseWriter
type Requester http.Request
type HandlerFunc func(http.ResponseWriter, *http.Request)
type Handler interface {
	ServeHTTP(http.ResponseWriter, *http.Request)
}

func Serve(srvPort string, handler http.Handler) {
	logging.Info("[Serve] Try to listen on port: %s", srvPort)
	go func() {
		err := http.ListenAndServe(srvPort, handler)
		if err != nil {
			logging.Error("[Serve] Listen failed, error = %s", err.Error())
			return
		}
	}()
}

func Health(srvPort string, handler http.Handler) {
	logging.Info("[Health] Try to monitor health condition on port: %s", srvPort)
	go func() {
		err := http.ListenAndServe(srvPort, handler)
		if err != nil {
			logging.Error("[Health] monitor failed, error = %s", err.Error())
			return
		}
	}()
}

func HandleFunc(addr string, handler HandlerFunc) {
	http.HandleFunc(addr, handler)
}

///////////////////////////////////////////////////////////////////////
type Request struct {
	ID      string
	URL     string
	Method  string
	Content string
	Req     *http.Request
}

func NewRequest(id string, target string, method string, content string, contentType string) *Request {
	req := &Request{
		ID:      id,
		URL:     target,
		Method:  method,
		Content: content,
	}

	request, err := http.NewRequest(req.Method, req.URL, strings.NewReader(req.Content))
	if err != nil {
		logging.Error("[NewRequest] Fatal error when create request, error = %s, url = %s", err.Error(), target)
		return nil
	}

	if contentType != CONTENT_NONE {
		request.Header.Set("Content-Type", contentType)
	}

	req.Req = request

	return req
}

func (req *Request) AddHeader(key string, value string) {
	req.Req.Header.Add(key, value)
}

func (req *Request) DoRequest(resp interface{}) (*http.Response, *e.WError) {
	logging.Debug("[Request.DoRequest, id: %s] start connection[to: %s, method: %s, content: %s]", req.ID, req.URL, req.Method, req.Content)
	client := &http.Client{}
	client.Timeout = time.Duration(4 * time.Second)

	response, err := client.Do(req.Req)
	if err != nil {
		logging.Error("[Request.DoRequest] Failed to talk with remote server, error = %s, id: %s", err.Error(), req.ID)
		return nil, e.NewWError(1003, "Failed to request to remote server[url: %s], error = %s", req.URL, err.Error())
	}

	if response.StatusCode < 200 || response.StatusCode >= 300 {
		logging.Error("[Request.DoRequest] Error returns with code: %d, msg: %s", response.StatusCode, response.Status)
		return nil, e.NewWError(1003, "Error returns with code: %d, msg: %s", response.StatusCode, response.Status)
	}

	if resp != nil {
		defer response.Body.Close()

		text, err := ioutil.ReadAll(response.Body)
		if err != nil {
			logging.Error("[Request.DoRequest, id: %s] Failed to read body of response: %v", req.ID, response.Body)
			return nil, e.NewWError(1003, err.Error())
		}

		err = json.Unmarshal(text, &resp)
		if err != nil {
			logging.Error("[Request.DoRequest, id: %s] json unmarshal, error: %s", req.ID, err.Error())
			return nil, e.NewWError(1003, err.Error())
		}

		return nil, nil
	}

	return response, nil
}

func Serialize(source map[string]interface{}) string {
	text, err := json.Marshal(&source)
	if err != nil {
		logging.Error("[Serialize] Failed to convert map to json byte, error: %s", err.Error())
		return ""
	}

	buff := bytes.NewBuffer(text)

	return string(buff.Bytes())
}

func Call(name string, url string, method string, content string, contentType string, resp interface{}) (string, *e.WError) {
	req := NewRequest(name, url, method, content, contentType)
	if req == nil {
		logging.Error("[Call, id: %s] Failed to create Request", name)
		return "", e.NewWError(1003, "Failed to create Request")
	}

	if resp != nil {
		_, err := req.DoRequest(resp)
		if err != nil {
			logging.Error("[Call, id: %s] Failed to do Request, error = %s", name, err.Error())
			return "", err
		}

		return "", nil
	}

	response, err := req.DoRequest(nil)
	if err != nil {
		logging.Error("[Call, id: %s] Failed to do Request, error = %s", name, err.Error())
		return "", err
	}

	text, ee := ioutil.ReadAll(response.Body)
	if ee != nil {
		logging.Error("[Call, id: %s] Failed to read body of response: %v", name, response.Body)
		return "", e.NewWError(1003, ee.Error())
	}

	return string(text), nil
}

func GetRequestBody(req *http.Request, v interface{}) (interface{}, *e.WError) {
	buff := bytes.NewBufferString("")
	_, err := io.Copy(buff, req.Body)
	if err != nil {
		logging.Error("[GetRequestBody] Failed to copy req body error, request = %v, error = %s", req.Body, err.Error())
		return nil, e.NewWError(e.ERR_CODE_IO, "Failed to copy req body, error = %s", err.Error())
	}
	text := buff.String()
	req.Body = ioutil.NopCloser(strings.NewReader(text))

	err = json.Unmarshal([]byte(text), v)
	if err != nil {
		logging.Error("[GetRequestBody] Failed to unmarshal json body error, text = %s, error = %s", text, err.Error())
		return nil, e.NewWError(e.ERR_CODE_IO, "Failed to unmarshal json body, error = %s", err.Error())
	}

	return v, nil
}

func GetResponseData(err *e.WError, data interface{}) []byte {
	resp := &HTTPResponse{}
	if err == nil {
		resp.Code = 0
		resp.Msg = "ok"
	} else {
		resp.Code = err.Code()
		resp.Msg = err.Error()
	}
	resp.Data = data

	r, we := json.Marshal(resp)
	if we != nil {
		logging.Error("[GetResponseData] Failed, %s, data = %v", err.Error(), data)
		panic(fmt.Sprintf("[GetResponseData] Failed, %s", we.Error()))
	}

	return r
}

func LogGetResponseData(req *http.Request, err *e.WError, data interface{}) []byte {
	ret := GetResponseData(err, data)

	body := ""
	b_body, ee := ioutil.ReadAll(req.Body)
	if ee == nil {
		body = string(b_body)
	}

	logReq := HTTPRequest{
		Method: req.Method,
		URL:    req.RequestURI,
		Form:   req.Form,
		Body:   body,
	}
	logging.Info("HANDLE_LOG: url = %s, request = %#v", req.RequestURI, logReq)
	logging.Debug("HANDLE_RESPONSE: response = %s", string(ret))

	return ret
}
<commit_msg>return valid para<commit_after>package net

import (
	"bytes"
	"encoding/json"
	"fmt"
	e "gowork/error"
	"gowork/extern/logging"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
	"time"
)

var (
	HTTP_METHOD_GET    = "GET"
	HTTP_METHOD_PUT    = "PUT"
	HTTP_METHOD_POST   = "POST"
	HTTP_METHOD_PATCH  = "PATCH"
	HTTP_METHOD_DELETE = "DELETE"

	CONTENT_NONE = ""
	CONTENT_JSON = "application/json"
	CONTENT_YAML = "application/yaml"
)

type HTTPRequest struct {
	Method       string
	URL          string
	UserID       string
	X_Auth_Token string
	Form         interface{}
	Body         interface{}
}

type HTTPResponse struct {
	Code int         `json:"code, omitempty"`
	Msg  string      `json:"msg, omitempty"`
	Data interface{} `json:"data, omitempty"`
}

type IRequest interface {
	DoRequest(resp interface{}) *e.WError
}

// warpper
type Responser http.ResponseWriter
type Requester http.Request
type HandlerFunc func(http.ResponseWriter, *http.Request)
type Handler interface {
	ServeHTTP(http.ResponseWriter, *http.Request)
}

func Serve(srvPort string, handler http.Handler) {
	logging.Info("[Serve] Try to listen on port: %s", srvPort)
	go func() {
		err := http.ListenAndServe(srvPort, handler)
		if err != nil {
			logging.Error("[Serve] Listen failed, error = %s", err.Error())
			return
		}
	}()
}

func Health(srvPort string, handler http.Handler) {
	logging.Info("[Health] Try to monitor health condition on port: %s", srvPort)
	go func() {
		err := http.ListenAndServe(srvPort, handler)
		if err != nil {
			logging.Error("[Health] monitor failed, error = %s", err.Error())
			return
		}
	}()
}

func HandleFunc(addr string, handler HandlerFunc) {
	http.HandleFunc(addr, handler)
}

///////////////////////////////////////////////////////////////////////
type Request struct {
	ID      string
	URL     string
	Method  string
	Content string
	Req     *http.Request
}

func NewRequest(id string, target string, method string, content string, contentType string) *Request {
	req := &Request{
		ID:      id,
		URL:     target,
		Method:  method,
		Content: content,
	}

	request, err := http.NewRequest(req.Method, req.URL, strings.NewReader(req.Content))
	if err != nil {
		logging.Error("[NewRequest] Fatal error when create request, error = %s, url = %s", err.Error(), target)
		return nil
	}

	if contentType != CONTENT_NONE {
		request.Header.Set("Content-Type", contentType)
	}

	req.Req = request

	return req
}

func (req *Request) AddHeader(key string, value string) {
	req.Req.Header.Add(key, value)
}

func (req *Request) DoRequest(resp interface{}) (*http.Response, *e.WError) {
	logging.Debug("[Request.DoRequest, id: %s] start connection[to: %s, method: %s, content: %s]", req.ID, req.URL, req.Method, req.Content)
	client := &http.Client{}
	client.Timeout = time.Duration(4 * time.Second)

	response, err := client.Do(req.Req)
	if err != nil {
		logging.Error("[Request.DoRequest] Failed to talk with remote server, error = %s, id: %s", err.Error(), req.ID)
		return nil, e.NewWError(1003, "Failed to request to remote server[url: %s], error = %s", req.URL, err.Error())
	}

	if response.StatusCode < 200 || response.StatusCode >= 300 {
		logging.Error("[Request.DoRequest] Error returns with code: %d, msg: %s", response.StatusCode, response.Status)
		return nil, e.NewWError(1003, "Error returns with code: %d, msg: %s", response.StatusCode, response.Status)
	}

	if resp != nil {
		defer response.Body.Close()

		text, err := ioutil.ReadAll(response.Body)
		if err != nil {
			logging.Error("[Request.DoRequest, id: %s] Failed to read body of response: %v", req.ID, response.Body)
			return nil, e.NewWError(1003, err.Error())
		}

		err = json.Unmarshal(text, &resp)
		if err != nil {
			logging.Error("[Request.DoRequest, id: %s] json unmarshal, error: %s", req.ID, err.Error())
			return nil, e.NewWError(1003, err.Error())
		}

		return nil, nil
	}

	return response, nil
}

func Serialize(source map[string]interface{}) string {
	text, err := json.Marshal(&source)
	if err != nil {
		logging.Error("[Serialize] Failed to convert map to json byte, error: %s", err.Error())
		return ""
	}

	buff := bytes.NewBuffer(text)

	return string(buff.Bytes())
}

func Call(name string, url string, method string, content string, contentType string, resp interface{}) (string, *e.WError) {
	req := NewRequest(name, url, method, content, contentType)
	if req == nil {
		logging.Error("[Call, id: %s] Failed to create Request", name)
		return "", e.NewWError(1003, "Failed to create Request")
	}

	if resp != nil {
		_, err := req.DoRequest(resp)
		if err != nil {
			logging.Error("[Call, id: %s] Failed to do Request, error = %s", name, err.Error())
			return "", err
		}

		return "", nil
	}

	response, err := req.DoRequest(nil)
	if err != nil {
		logging.Error("[Call, id: %s] Failed to do Request, error = %s", name, err.Error())
		return "", err
	}

	text, ee := ioutil.ReadAll(response.Body)
	if ee != nil {
		logging.Error("[Call, id: %s] Failed to read body of response: %v", name, response.Body)
		return "", e.NewWError(1003, ee.Error())
	}

	return string(text), nil
}

func GetRequestBody(req *http.Request, v interface{}) (interface{}, *e.WError) {

	alter := map[string]interface{}{}

	buff := bytes.NewBufferString("")
	_, err := io.Copy(buff, req.Body)
	if err != nil {
		logging.Error("[GetRequestBody] Failed to copy req body error, request = %v, error = %s", req.Body, err.Error())
		return nil, e.NewWError(e.ERR_CODE_IO, "Failed to copy req body, error = %s", err.Error())
	}
	text := buff.String()
	req.Body = ioutil.NopCloser(strings.NewReader(text))

	if v == nil {
		err = json.Unmarshal([]byte(text), alter)
	} else {
		err = json.Unmarshal([]byte(text), v)
	}
	if err != nil {
		logging.Error("[GetRequestBody] Failed to unmarshal json body error, text = %s, error = %s", text, err.Error())
		return nil, e.NewWError(e.ERR_CODE_IO, "Failed to unmarshal json body, error = %s", err.Error())
	}

	return alter, nil
}

func GetResponseData(err *e.WError, data interface{}) []byte {
	resp := &HTTPResponse{}
	if err == nil {
		resp.Code = 0
		resp.Msg = "ok"
	} else {
		resp.Code = err.Code()
		resp.Msg = err.Error()
	}
	resp.Data = data

	r, we := json.Marshal(resp)
	if we != nil {
		logging.Error("[GetResponseData] Failed, %s, data = %v", err.Error(), data)
		panic(fmt.Sprintf("[GetResponseData] Failed, %s", we.Error()))
	}

	return r
}

func LogGetResponseData(req *http.Request, err *e.WError, data interface{}) []byte {
	ret := GetResponseData(err, data)

	body := ""
	b_body, ee := ioutil.ReadAll(req.Body)
	if ee == nil {
		body = string(b_body)
	}

	logReq := HTTPRequest{
		Method: req.Method,
		URL:    req.RequestURI,
		Form:   req.Form,
		Body:   body,
	}
	logging.Info("HANDLE_LOG: url = %s, request = %#v", req.RequestURI, logReq)
	logging.Debug("HANDLE_RESPONSE: response = %s", string(ret))

	return ret
}
<|endoftext|>


<commit_before>// Package netstate provides routines to obtain the available set of
// of network addresess, for determining changes to those addresses and for
// selecting from amongst them according to some set of policies that are
// implemented by applying simple predicates (functions with names of the form
// Is<condition>) to filter or find the first matching address from a list
// of addresses. The intent is to make it easy to create policies that do
// things like 'find the first IPv4 unicast address that is globally routable,
// failing that use a private IPv4 address, and failing that, an IPv6 address'.
//
// A simple usage would be:
//
//   state, _ := netstate.GetAccessibleIPs()
//   ipv4 := state.Filter(netstate.IsPublicIPv4)
//   // ipv4 will contain all of the public IPv4 addresses, if any.
//
// The example policy described above would be implemented using a
// series of calls to Filter with appropriate predicates.
//
// In some cases, it may be necessary to take IP routing information
// into account and hence interface hosting the address. The interface
// hosting each address is provided in the AddrIfc structure used to represent
// addresses and the IP routing information is provided by the GetAccessibleIPs
// function which will typically be used to obtain the available IP addresses.
//
// Although most commercial networking hardware supports IPv6, some consumer
// devices and more importantly many ISPs do not, so routines are provided
// to allow developers to easily distinguish between the two and to use
// whichever is appropriate for their product/situation.
//
// The term 'accessible' is used to refer to any non-loopback IP address.
// The term 'public' is used to refer to any globally routable IP address.
//
// All IPv6 addresses are intended to be 'public', but any starting with
// fc00::/7 (RFC4193) are reserved for private use, but the go
// net libraries do not appear to recognise this. Similarly fe80::/10
// (RFC 4291) are reserved for 'site-local' usage, but again this is not
// implemented in the go libraries. Any developer who needs to distinguish
// these cases will need to write their own routines to test for them.
//
// When using the go net package it is important to remember that IPv6
// addresses subsume IPv4 and hence in many cases the same internal
// representation is used for both, thus testing for the length of the IP
// address is unreliable. The reliable test is to use the net.To4() which
// will return a non-nil result if can be used as an IPv4 one. Any address
// can be used as an IPv6 and hence the only reliable way to test for an IPv6
// address that is not an IPv4 one also is for the To4 call to return nil for
// it.
package netstate

import (
	"fmt"
	"net"
	"strings"

	"veyron.io/veyron/veyron2/ipc"

	"veyron.io/veyron/veyron/lib/netconfig"
)

// AddrIfc represents a network address and the network interface that
// hosts it.
type AddrIfc struct {
	// Network address
	Addr net.Addr

	// The name of the network interface this address is hosted on, empty
	// if this information is not available.
	Name string

	// The IPRoutes of the network interface this address is hosted on,
	// nil if this information is not available.
	IPRoutes []*netconfig.IPRoute
}

func (a *AddrIfc) String() string {
	if a.IPRoutes != nil {
		r := fmt.Sprintf("%s: %s[", a.Addr, a.Name)
		for _, rt := range a.IPRoutes {
			src := ""
			if rt.PreferredSource != nil {
				src = ", src: " + rt.PreferredSource.String()
			}
			r += fmt.Sprintf("{%d: net: %s, gw: %s%s}, ", rt.IfcIndex, rt.Net, rt.Gateway, src)
		}
		r = strings.TrimSuffix(r, ", ")
		r += "]"
		return r
	}
	return a.Addr.String()
}

func (a *AddrIfc) Address() net.Addr {
	return a.Addr
}

func (a *AddrIfc) InterfaceIndex() int {
	if len(a.IPRoutes) == 0 {
		return -1
	}
	return a.IPRoutes[0].IfcIndex
}

func (a *AddrIfc) InterfaceName() string {
	return a.Name
}

func (a *AddrIfc) Networks() []net.Addr {
	nets := []net.Addr{}
	for _, r := range a.IPRoutes {
		nets = append(nets, &r.Net)
	}
	return nets
}

type AddrList []ipc.Address

func (al AddrList) String() string {
	r := ""
	for _, v := range al {
		r += fmt.Sprintf("(%s) ", v)
	}
	return strings.TrimRight(r, " ")
}

// GetAll gets all of the available addresses on the device, including
// loopback addresses, non-IP protocols etc.
func GetAll() (AddrList, error) {
	interfaces, err := net.Interfaces()
	if err != nil {
		return nil, err
	}
	routes := netconfig.GetIPRoutes(false)
	routeTable := make(map[int][]*netconfig.IPRoute)
	for _, r := range routes {
		routeTable[r.IfcIndex] = append(routeTable[r.IfcIndex], r)
	}
	var all AddrList
	for _, ifc := range interfaces {
		addrs, err := ifc.Addrs()
		if err != nil {
			continue
		}
		for _, a := range addrs {
			all = append(all, &AddrIfc{a, ifc.Name, routeTable[ifc.Index]})
		}
	}
	return all, nil
}

// GetAccessibleIPs returns all of the accessible IP addresses on the device
// - i.e. excluding loopback and unspecified addresses.
// The IP addresses returned will be host addresses.
func GetAccessibleIPs() (AddrList, error) {
	all, err := GetAll()
	if err != nil {
		return nil, err
	}
	return all.Map(accessibleIPHost), nil
}

func accessibleIPHost(a ipc.Address) ipc.Address {
	if !IsAccessibleIP(a) {
		return nil
	}
	aifc, ok := a.(*AddrIfc)
	if !ok {
		return nil
	}
	ip := AsIPAddr(aifc.Addr)
	if ip == nil {
		return aifc
	}
	aifc.Addr = ip
	return aifc
}

// AddressPredicate defines the function signature for predicate functions
// to be used with AddrList
type AddressPredicate func(a ipc.Address) bool

// Filter returns all of the addresses for which the predicate
// function is true.
func (al AddrList) Filter(predicate AddressPredicate) AddrList {
	r := AddrList{}
	for _, a := range al {
		if predicate(a) {
			r = append(r, a)
		}
	}
	return r
}

type Mapper func(a ipc.Address) ipc.Address

// Map will apply the Mapper function to all of the items in its receiver
// and return a new AddrList containing all of the non-nil results from
// said calls.
func (al AddrList) Map(mapper Mapper) AddrList {
	var ral AddrList
	for _, a := range al {
		if na := mapper(a); na != nil {
			ral = append(ral, na)
		}
	}
	return ral
}

// Convert the network address component of an ipc.Address into an instance
// with a net.Addr that contains an IP host address (as opposed to a
// network CIDR for example).
func ConvertToIPHost(a ipc.Address) ipc.Address {
	aifc, ok := a.(*AddrIfc)
	if !ok {
		return nil
	}
	aifc.Addr = AsIPAddr(aifc.Addr)
	return aifc
}

// IsIPProtocol returns true if its parameter is one of the allowed
// network/protocol values for IP.
func IsIPProtocol(n string) bool {
	switch n {
	case "ip+net", "ip", "tcp", "tcp4", "tcp6", "udp":
		return true
	default:
		return false

	}
}

// AsIPAddr returns its argument as a net.IPAddr if that's possible.
func AsIPAddr(a net.Addr) *net.IPAddr {
	if v, ok := a.(*net.IPAddr); ok {
		return v
	}
	if ipn, ok := a.(*net.IPNet); ok {
		return &net.IPAddr{IP: ipn.IP}
	}
	if IsIPProtocol(a.Network()) {
		if r := net.ParseIP(a.String()); r != nil {
			return &net.IPAddr{IP: r}
		}
	}
	return nil
}

// AsIP returns its argument as a net.IP if that's possible.
func AsIP(a net.Addr) net.IP {
	ipAddr := AsIPAddr(a)
	if ipAddr == nil {
		return nil
	}
	return ipAddr.IP
}

// IsUnspecified returns true if its argument is an unspecified IP address
func IsUnspecifiedIP(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil {
		return ip.IsUnspecified()
	}
	return false
}

// IsLoopback returns true if its argument is a loopback IP address
func IsLoopbackIP(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil && !ip.IsUnspecified() {
		return ip.IsLoopback()
	}
	return false
}

// IsAccessible returns true if its argument is an accessible (non-loopback)
// IP address.
func IsAccessibleIP(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil && !ip.IsUnspecified() {
		return !ip.IsLoopback()
	}
	return false
}

// IsUnicastIP returns true if its argument is a unicast IP address.
func IsUnicastIP(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil && !ip.IsUnspecified() {
		// ipv4 or v6
		return !(ip.IsMulticast() || ip.IsLinkLocalMulticast() || ip.IsInterfaceLocalMulticast())
	}
	return false
}

// IsUnicastIPv4 returns true if its argument is a unicast IP4 address
func IsUnicastIPv4(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil && ip.To4() != nil {
		return !ip.IsUnspecified() && !ip.IsMulticast()
	}
	return false
}

// IsPublicUnicastIPv4 returns true if its argument is a globally routable,
// public IPv4 unicast address.
func IsPublicUnicastIPv4(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil && !ip.IsUnspecified() {
		if t := ip.To4(); t != nil && IsGloballyRoutableIP(t) {
			return !ip.IsMulticast()
		}
	}
	return false
}

// IsUnicastIPv6 returns true if its argument is a unicast IPv6 address
func IsUnicastIPv6(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil && ip.To4() == nil {
		return !ip.IsUnspecified() && !(ip.IsLinkLocalMulticast() || ip.IsInterfaceLocalMulticast())
	}
	return false
}

// IsUnicastIPv6 returns true if its argument is a globally routable IP6
// address
func IsPublicUnicastIPv6(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil && ip.To4() == nil {
		if t := ip.To16(); t != nil && IsGloballyRoutableIP(t) {
			return true
		}
	}
	return false
}

// IsPublicUnicastIP returns true if its argument is a global routable IPv4
// or 6 address.
func IsPublicUnicastIP(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil {
		if t := ip.To4(); t != nil && IsGloballyRoutableIP(t) {
			return true
		}
		if t := ip.To16(); t != nil && IsGloballyRoutableIP(t) {
			return true
		}
	}
	return false
}

func diffAB(a, b AddrList) AddrList {
	diff := AddrList{}
	for _, av := range a {
		found := false
		for _, bv := range b {
			if av.Address().Network() == bv.Address().Network() &&
				av.Address().String() == bv.Address().String() {
				found = true
				break
			}
		}
		if !found {
			diff = append(diff, av)
		}
	}
	return diff
}

// FindAdded returns the set addresses that are present in b, but not
// in a - i.e. have been added.
func FindAdded(a, b AddrList) AddrList {
	return diffAB(b, a)
}

// FindRemoved returns the set of addresses that are present in a, but not
// in b - i.e. have been removed.
func FindRemoved(a, b AddrList) AddrList {
	return diffAB(a, b)
}

// SameMachine returns true if the provided addr is on the node
// executing this function.
func SameMachine(addr net.Addr) (bool, error) {
	// The available interfaces may change between calls.
	addrs, err := GetAll()
	if err != nil {
		return false, err
	}

	ips := make(map[string]struct{})
	for _, a := range addrs {
		ip, _, err := net.ParseCIDR(a.Address().String())
		if err != nil {
			return false, err
		}
		ips[ip.String()] = struct{}{}
	}

	client, _, err := net.SplitHostPort(addr.String())
	if err != nil {
		return false, err
	}

	_, islocal := ips[client]
	return islocal, nil
}
<commit_msg>veyron/services/mgmt/binary/binaryd: Make port configurable.<commit_after>// Package netstate provides routines to obtain the available set of
// of network addresess, for determining changes to those addresses and for
// selecting from amongst them according to some set of policies that are
// implemented by applying simple predicates (functions with names of the form
// Is<condition>) to filter or find the first matching address from a list
// of addresses. The intent is to make it easy to create policies that do
// things like 'find the first IPv4 unicast address that is globally routable,
// failing that use a private IPv4 address, and failing that, an IPv6 address'.
//
// A simple usage would be:
//
//   state, _ := netstate.GetAccessibleIPs()
//   ipv4 := state.Filter(netstate.IsPublicUnicastIPv4)
//   // ipv4 will contain all of the public IPv4 addresses, if any.
//
// The example policy described above would be implemented using a
// series of calls to Filter with appropriate predicates.
//
// In some cases, it may be necessary to take IP routing information
// into account and hence interface hosting the address. The interface
// hosting each address is provided in the AddrIfc structure used to represent
// addresses and the IP routing information is provided by the GetAccessibleIPs
// function which will typically be used to obtain the available IP addresses.
//
// Although most commercial networking hardware supports IPv6, some consumer
// devices and more importantly many ISPs do not, so routines are provided
// to allow developers to easily distinguish between the two and to use
// whichever is appropriate for their product/situation.
//
// The term 'accessible' is used to refer to any non-loopback IP address.
// The term 'public' is used to refer to any globally routable IP address.
//
// All IPv6 addresses are intended to be 'public', but any starting with
// fc00::/7 (RFC4193) are reserved for private use, but the go
// net libraries do not appear to recognise this. Similarly fe80::/10
// (RFC 4291) are reserved for 'site-local' usage, but again this is not
// implemented in the go libraries. Any developer who needs to distinguish
// these cases will need to write their own routines to test for them.
//
// When using the go net package it is important to remember that IPv6
// addresses subsume IPv4 and hence in many cases the same internal
// representation is used for both, thus testing for the length of the IP
// address is unreliable. The reliable test is to use the net.To4() which
// will return a non-nil result if can be used as an IPv4 one. Any address
// can be used as an IPv6 and hence the only reliable way to test for an IPv6
// address that is not an IPv4 one also is for the To4 call to return nil for
// it.
package netstate

import (
	"fmt"
	"net"
	"strings"

	"veyron.io/veyron/veyron2/ipc"

	"veyron.io/veyron/veyron/lib/netconfig"
)

// AddrIfc represents a network address and the network interface that
// hosts it.
type AddrIfc struct {
	// Network address
	Addr net.Addr

	// The name of the network interface this address is hosted on, empty
	// if this information is not available.
	Name string

	// The IPRoutes of the network interface this address is hosted on,
	// nil if this information is not available.
	IPRoutes []*netconfig.IPRoute
}

func (a *AddrIfc) String() string {
	if a.IPRoutes != nil {
		r := fmt.Sprintf("%s: %s[", a.Addr, a.Name)
		for _, rt := range a.IPRoutes {
			src := ""
			if rt.PreferredSource != nil {
				src = ", src: " + rt.PreferredSource.String()
			}
			r += fmt.Sprintf("{%d: net: %s, gw: %s%s}, ", rt.IfcIndex, rt.Net, rt.Gateway, src)
		}
		r = strings.TrimSuffix(r, ", ")
		r += "]"
		return r
	}
	return a.Addr.String()
}

func (a *AddrIfc) Address() net.Addr {
	return a.Addr
}

func (a *AddrIfc) InterfaceIndex() int {
	if len(a.IPRoutes) == 0 {
		return -1
	}
	return a.IPRoutes[0].IfcIndex
}

func (a *AddrIfc) InterfaceName() string {
	return a.Name
}

func (a *AddrIfc) Networks() []net.Addr {
	nets := []net.Addr{}
	for _, r := range a.IPRoutes {
		nets = append(nets, &r.Net)
	}
	return nets
}

type AddrList []ipc.Address

func (al AddrList) String() string {
	r := ""
	for _, v := range al {
		r += fmt.Sprintf("(%s) ", v)
	}
	return strings.TrimRight(r, " ")
}

// GetAll gets all of the available addresses on the device, including
// loopback addresses, non-IP protocols etc.
func GetAll() (AddrList, error) {
	interfaces, err := net.Interfaces()
	if err != nil {
		return nil, err
	}
	routes := netconfig.GetIPRoutes(false)
	routeTable := make(map[int][]*netconfig.IPRoute)
	for _, r := range routes {
		routeTable[r.IfcIndex] = append(routeTable[r.IfcIndex], r)
	}
	var all AddrList
	for _, ifc := range interfaces {
		addrs, err := ifc.Addrs()
		if err != nil {
			continue
		}
		for _, a := range addrs {
			all = append(all, &AddrIfc{a, ifc.Name, routeTable[ifc.Index]})
		}
	}
	return all, nil
}

// GetAccessibleIPs returns all of the accessible IP addresses on the device
// - i.e. excluding loopback and unspecified addresses.
// The IP addresses returned will be host addresses.
func GetAccessibleIPs() (AddrList, error) {
	all, err := GetAll()
	if err != nil {
		return nil, err
	}
	return all.Map(accessibleIPHost), nil
}

func accessibleIPHost(a ipc.Address) ipc.Address {
	if !IsAccessibleIP(a) {
		return nil
	}
	aifc, ok := a.(*AddrIfc)
	if !ok {
		return nil
	}
	ip := AsIPAddr(aifc.Addr)
	if ip == nil {
		return aifc
	}
	aifc.Addr = ip
	return aifc
}

// AddressPredicate defines the function signature for predicate functions
// to be used with AddrList
type AddressPredicate func(a ipc.Address) bool

// Filter returns all of the addresses for which the predicate
// function is true.
func (al AddrList) Filter(predicate AddressPredicate) AddrList {
	r := AddrList{}
	for _, a := range al {
		if predicate(a) {
			r = append(r, a)
		}
	}
	return r
}

type Mapper func(a ipc.Address) ipc.Address

// Map will apply the Mapper function to all of the items in its receiver
// and return a new AddrList containing all of the non-nil results from
// said calls.
func (al AddrList) Map(mapper Mapper) AddrList {
	var ral AddrList
	for _, a := range al {
		if na := mapper(a); na != nil {
			ral = append(ral, na)
		}
	}
	return ral
}

// Convert the network address component of an ipc.Address into an instance
// with a net.Addr that contains an IP host address (as opposed to a
// network CIDR for example).
func ConvertToIPHost(a ipc.Address) ipc.Address {
	aifc, ok := a.(*AddrIfc)
	if !ok {
		return nil
	}
	aifc.Addr = AsIPAddr(aifc.Addr)
	return aifc
}

// IsIPProtocol returns true if its parameter is one of the allowed
// network/protocol values for IP.
func IsIPProtocol(n string) bool {
	switch n {
	case "ip+net", "ip", "tcp", "tcp4", "tcp6", "udp":
		return true
	default:
		return false

	}
}

// AsIPAddr returns its argument as a net.IPAddr if that's possible.
func AsIPAddr(a net.Addr) *net.IPAddr {
	if v, ok := a.(*net.IPAddr); ok {
		return v
	}
	if ipn, ok := a.(*net.IPNet); ok {
		return &net.IPAddr{IP: ipn.IP}
	}
	if IsIPProtocol(a.Network()) {
		if r := net.ParseIP(a.String()); r != nil {
			return &net.IPAddr{IP: r}
		}
	}
	return nil
}

// AsIP returns its argument as a net.IP if that's possible.
func AsIP(a net.Addr) net.IP {
	ipAddr := AsIPAddr(a)
	if ipAddr == nil {
		return nil
	}
	return ipAddr.IP
}

// IsUnspecified returns true if its argument is an unspecified IP address
func IsUnspecifiedIP(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil {
		return ip.IsUnspecified()
	}
	return false
}

// IsLoopback returns true if its argument is a loopback IP address
func IsLoopbackIP(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil && !ip.IsUnspecified() {
		return ip.IsLoopback()
	}
	return false
}

// IsAccessible returns true if its argument is an accessible (non-loopback)
// IP address.
func IsAccessibleIP(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil && !ip.IsUnspecified() {
		return !ip.IsLoopback()
	}
	return false
}

// IsUnicastIP returns true if its argument is a unicast IP address.
func IsUnicastIP(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil && !ip.IsUnspecified() {
		// ipv4 or v6
		return !(ip.IsMulticast() || ip.IsLinkLocalMulticast() || ip.IsInterfaceLocalMulticast())
	}
	return false
}

// IsUnicastIPv4 returns true if its argument is a unicast IP4 address
func IsUnicastIPv4(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil && ip.To4() != nil {
		return !ip.IsUnspecified() && !ip.IsMulticast()
	}
	return false
}

// IsPublicUnicastIPv4 returns true if its argument is a globally routable,
// public IPv4 unicast address.
func IsPublicUnicastIPv4(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil && !ip.IsUnspecified() {
		if t := ip.To4(); t != nil && IsGloballyRoutableIP(t) {
			return !ip.IsMulticast()
		}
	}
	return false
}

// IsUnicastIPv6 returns true if its argument is a unicast IPv6 address
func IsUnicastIPv6(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil && ip.To4() == nil {
		return !ip.IsUnspecified() && !(ip.IsLinkLocalMulticast() || ip.IsInterfaceLocalMulticast())
	}
	return false
}

// IsUnicastIPv6 returns true if its argument is a globally routable IP6
// address
func IsPublicUnicastIPv6(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil && ip.To4() == nil {
		if t := ip.To16(); t != nil && IsGloballyRoutableIP(t) {
			return true
		}
	}
	return false
}

// IsPublicUnicastIP returns true if its argument is a global routable IPv4
// or 6 address.
func IsPublicUnicastIP(a ipc.Address) bool {
	if ip := AsIP(a.Address()); ip != nil {
		if t := ip.To4(); t != nil && IsGloballyRoutableIP(t) {
			return true
		}
		if t := ip.To16(); t != nil && IsGloballyRoutableIP(t) {
			return true
		}
	}
	return false
}

func diffAB(a, b AddrList) AddrList {
	diff := AddrList{}
	for _, av := range a {
		found := false
		for _, bv := range b {
			if av.Address().Network() == bv.Address().Network() &&
				av.Address().String() == bv.Address().String() {
				found = true
				break
			}
		}
		if !found {
			diff = append(diff, av)
		}
	}
	return diff
}

// FindAdded returns the set addresses that are present in b, but not
// in a - i.e. have been added.
func FindAdded(a, b AddrList) AddrList {
	return diffAB(b, a)
}

// FindRemoved returns the set of addresses that are present in a, but not
// in b - i.e. have been removed.
func FindRemoved(a, b AddrList) AddrList {
	return diffAB(a, b)
}

// SameMachine returns true if the provided addr is on the node
// executing this function.
func SameMachine(addr net.Addr) (bool, error) {
	// The available interfaces may change between calls.
	addrs, err := GetAll()
	if err != nil {
		return false, err
	}

	ips := make(map[string]struct{})
	for _, a := range addrs {
		ip, _, err := net.ParseCIDR(a.Address().String())
		if err != nil {
			return false, err
		}
		ips[ip.String()] = struct{}{}
	}

	client, _, err := net.SplitHostPort(addr.String())
	if err != nil {
		return false, err
	}

	_, islocal := ips[client]
	return islocal, nil
}
<|endoftext|>


<commit_before>package gojsonschema

import (
	"fmt"
)

func DebugDisplayJsonSchema(d *JsonSchemaDocument) {
	debugDisplayJsonSchemaRecursive(d.rootSchema, 0)
}

func debugDisplayJsonSchemaRecursive(s *JsonSchema, level int) {
	for i := 0; i != level; i++ {
		fmt.Printf(" ")
	}

	if s.property == nil {
		fmt.Printf("(nil)")
	} else {
		fmt.Printf(*s.property)
	}

	for i := range s.children {
		debugDisplayJsonSchemaRecursive(s.children[i], level+1)
	}

	fmt.Printf("\n")
}
<commit_msg>fixed display<commit_after>package gojsonschema

import (
	"fmt"
)

func DebugDisplayJsonSchema(d *JsonSchemaDocument) {
	debugDisplayJsonSchemaRecursive(d.rootSchema, 0)
}

func debugDisplayJsonSchemaRecursive(s *JsonSchema, level int) {
	for i := 0; i != level; i++ {
		fmt.Printf(" ")
	}

	if s.property == nil {
		fmt.Printf("(nil)")
	} else {
		fmt.Printf(*s.property)
	}

	fmt.Printf("\n")

	for i := range s.children {
		debugDisplayJsonSchemaRecursive(s.children[i], level+1)
	}

}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"go/ast"
	"go/parser"
	"go/printer"
	"go/token"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"time"
	"unicode/utf8"
)

var (
	sRuneError = eRune()
)

type void struct{}

type jString string

func (s jString) String() string {
	return string(s)
}

func (s *jString) UnmarshalJSON(p []byte) error {
	if bytes.Equal(p, []byte("null")) {
		return nil
	}
	return json.Unmarshal(p, (*string)(s))
}

type jData []byte

func (d jData) MarshalJSON() ([]byte, error) {
	if len(d) == 0 {
		return []byte(`""`), nil
	}

	buf := bytes.NewBufferString(`"base64:`)
	enc := base64.NewEncoder(base64.StdEncoding, buf)

	for len(d) > 0 {
		r, n := utf8.DecodeRune(d)
		if r == utf8.RuneError {
			enc.Write(sRuneError)
		} else {
			enc.Write(d[:n])
		}
		d = d[n:]
	}

	enc.Close()
	buf.WriteByte('"')
	return buf.Bytes(), nil
}

func errStr(err error) string {
	if err != nil {
		return err.Error()
	}
	return ""
}

func envSlice(envMap map[string]string) []string {
	env := []string{}
	for k, v := range envMap {
		env = append(env, k+"="+v)
	}
	if len(env) == 0 {
		env = os.Environ()
	}
	return env
}

func defaultEnv() map[string]string {
	return map[string]string{
		"GOROOT": runtime.GOROOT(),
		"GOARCH": runtime.GOARCH,
		"GOOS":   runtime.GOOS,
	}
}

func orString(a ...string) string {
	for _, s := range a {
		if s != "" {
			return s
		}
	}
	return ""
}

func parseAstFile(fn string, s string, mode parser.Mode) (fset *token.FileSet, af *ast.File, err error) {
	fset = token.NewFileSet()
	var src interface{}
	if s != "" {
		src = s
	}
	if fn == "" {
		fn = "<stdin>"
	}
	af, err = parser.ParseFile(fset, fn, src, mode)
	return
}

func newPrinter(tabIndent bool, tabWidth int) *printer.Config {
	mode := printer.UseSpaces
	if tabIndent {
		mode |= printer.TabIndent
	}
	return &printer.Config{
		Mode:     mode,
		Tabwidth: tabWidth,
	}
}

func printSrc(fset *token.FileSet, v interface{}, tabIndent bool, tabWidth int) (src string, err error) {
	p := newPrinter(tabIndent, tabWidth)
	buf := &bytes.Buffer{}
	if err = p.Fprint(buf, fset, v); err == nil {
		src = buf.String()
	}
	return
}

func fiHasGoExt(fi os.FileInfo) bool {
	return strings.HasSuffix(fi.Name(), ".go")
}

func parsePkg(fset *token.FileSet, srcDir string, mode parser.Mode) (pkg *ast.Package, pkgs map[string]*ast.Package, err error) {
	if pkgs, err = parser.ParseDir(fset, srcDir, fiHasGoExt, mode); pkgs != nil {
		_, pkgName := filepath.Split(srcDir)
		// we aren't going to support package whose name don't match the directory unless it's main
		p, ok := pkgs[pkgName]
		if !ok {
			p, ok = pkgs["main"]
		}
		if ok {
			pkg, err = ast.NewPackage(fset, p.Files, nil, nil)
		}
	}
	return
}

func rootDirs(env map[string]string) []string {
	dirs := []string{}
	gopath := ""
	if len(env) == 0 {
		gopath = os.Getenv("GOPATH")
	} else {
		gopath = env["GOPATH"]
	}

	gorootBase := runtime.GOROOT()
	if len(env) > 0 && env["GOROOT"] != "" {
		gorootBase = env["GOROOT"]
	} else if fn := os.Getenv("GOROOT"); fn != "" {
		gorootBase = fn
	}
	goroot := filepath.Join(gorootBase, "src", "pkg")

	dirsSeen := map[string]bool{}
	for _, fn := range filepath.SplitList(gopath) {
		if dirsSeen[fn] {
			continue
		}
		dirsSeen[fn] = true

		// goroot may be a part of gopath and we don't want that
		if fn != "" && !strings.HasPrefix(fn, gorootBase) {
			fn := filepath.Join(fn, "src")
			if fi, err := os.Stat(fn); err == nil && fi.IsDir() {
				dirs = append(dirs, fn)
			}
		}
	}

	if fi, err := os.Stat(goroot); err == nil && fi.IsDir() {
		dirs = append(dirs, goroot)
	}

	return dirs
}

func findPkg(fset *token.FileSet, importPath string, dirs []string, mode parser.Mode) (pkg *ast.Package, pkgs map[string]*ast.Package, err error) {
	for _, dir := range dirs {
		srcDir := filepath.Join(dir, importPath)
		if pkg, pkgs, err = parsePkg(fset, srcDir, mode); pkg != nil {
			return
		}
	}
	return
}

func eRune() []byte {
	s := make([]byte, utf8.RuneLen(utf8.RuneError))
	n := utf8.EncodeRune(s, utf8.RuneError)
	s = s[:n]
	return s
}

func tempDir(env map[string]string, subDirs ...string) string {
	dir := ""

	if env != nil {
		for _, k := range []string{"TMP", "TMPDIR"} {
			dir = env[k]
			if dir != "" {
				break
			}
		}
	}

	if dir == "" {
		dir = os.TempDir()
	}

	args := append([]string{dir, "GoSublime-temp"}, subDirs...)
	dir = filepath.Join(args...)
	os.MkdirAll(dir, 0777)

	return dir
}

func post(r Response) {
	sendCh <- r
}

func postMessage(format string, a ...interface{}) {
	post(Response{
		Token: "margo.message",
		Data: M{
			"message": fmt.Sprintf(format, a...),
		},
	})
}

func fileImportPaths(af *ast.File) []string {
	l := []string{}

	if af != nil {
		for _, decl := range af.Decls {
			if gdecl, ok := decl.(*ast.GenDecl); ok {
				for _, spec := range gdecl.Specs {
					if ispec, ok := spec.(*ast.ImportSpec); ok {
						ipath := unquote(ispec.Path.Value)
						if ipath != "C" {
							l = append(l, ipath)
						}
					}
				}
			}
		}
	}

	return l
}

func pathList(p, pathSep string) []string {
	if pathSep == "" {
		pathSep = string(filepath.ListSeparator)
	}
	l := strings.Split(p, pathSep)

	i := 0
	for _, s := range l {
		if s != "" {
			l[i] = s
			i += 1
		}
	}

	return l[:i]
}

func envRootList(env map[string]string) (string, []string) {
	if env == nil {
		return "", []string{}
	}
	return env["GOROOT"], pathList(env["GOPATH"], env["_pathsep"])
}

func msDur(start time.Time) time.Duration {
	dur := time.Now().Sub(start)
	dur -= dur % time.Millisecond
	return dur
}
<commit_msg>* add a unique id generator that's consistent with that GoSublime's gs.uid()<commit_after>package main

import (
	"bytes"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"go/ast"
	"go/parser"
	"go/printer"
	"go/token"
	"os"
	"path/filepath"
	"runtime"
	"strings"
	"time"
	"unicode/utf8"
)

var (
	sRuneError = eRune()
)

type void struct{}

type jString string

func (s jString) String() string {
	return string(s)
}

func (s *jString) UnmarshalJSON(p []byte) error {
	if bytes.Equal(p, []byte("null")) {
		return nil
	}
	return json.Unmarshal(p, (*string)(s))
}

type jData []byte

func (d jData) MarshalJSON() ([]byte, error) {
	if len(d) == 0 {
		return []byte(`""`), nil
	}

	buf := bytes.NewBufferString(`"base64:`)
	enc := base64.NewEncoder(base64.StdEncoding, buf)

	for len(d) > 0 {
		r, n := utf8.DecodeRune(d)
		if r == utf8.RuneError {
			enc.Write(sRuneError)
		} else {
			enc.Write(d[:n])
		}
		d = d[n:]
	}

	enc.Close()
	buf.WriteByte('"')
	return buf.Bytes(), nil
}

func uid() string {
	return "mg#" + numbers.nextString()
}

func errStr(err error) string {
	if err != nil {
		return err.Error()
	}
	return ""
}

func envSlice(envMap map[string]string) []string {
	env := []string{}
	for k, v := range envMap {
		env = append(env, k+"="+v)
	}
	if len(env) == 0 {
		env = os.Environ()
	}
	return env
}

func defaultEnv() map[string]string {
	return map[string]string{
		"GOROOT": runtime.GOROOT(),
		"GOARCH": runtime.GOARCH,
		"GOOS":   runtime.GOOS,
	}
}

func orString(a ...string) string {
	for _, s := range a {
		if s != "" {
			return s
		}
	}
	return ""
}

func parseAstFile(fn string, s string, mode parser.Mode) (fset *token.FileSet, af *ast.File, err error) {
	fset = token.NewFileSet()
	var src interface{}
	if s != "" {
		src = s
	}
	if fn == "" {
		fn = "<stdin>"
	}
	af, err = parser.ParseFile(fset, fn, src, mode)
	return
}

func newPrinter(tabIndent bool, tabWidth int) *printer.Config {
	mode := printer.UseSpaces
	if tabIndent {
		mode |= printer.TabIndent
	}
	return &printer.Config{
		Mode:     mode,
		Tabwidth: tabWidth,
	}
}

func printSrc(fset *token.FileSet, v interface{}, tabIndent bool, tabWidth int) (src string, err error) {
	p := newPrinter(tabIndent, tabWidth)
	buf := &bytes.Buffer{}
	if err = p.Fprint(buf, fset, v); err == nil {
		src = buf.String()
	}
	return
}

func fiHasGoExt(fi os.FileInfo) bool {
	return strings.HasSuffix(fi.Name(), ".go")
}

func parsePkg(fset *token.FileSet, srcDir string, mode parser.Mode) (pkg *ast.Package, pkgs map[string]*ast.Package, err error) {
	if pkgs, err = parser.ParseDir(fset, srcDir, fiHasGoExt, mode); pkgs != nil {
		_, pkgName := filepath.Split(srcDir)
		// we aren't going to support package whose name don't match the directory unless it's main
		p, ok := pkgs[pkgName]
		if !ok {
			p, ok = pkgs["main"]
		}
		if ok {
			pkg, err = ast.NewPackage(fset, p.Files, nil, nil)
		}
	}
	return
}

func rootDirs(env map[string]string) []string {
	dirs := []string{}
	gopath := ""
	if len(env) == 0 {
		gopath = os.Getenv("GOPATH")
	} else {
		gopath = env["GOPATH"]
	}

	gorootBase := runtime.GOROOT()
	if len(env) > 0 && env["GOROOT"] != "" {
		gorootBase = env["GOROOT"]
	} else if fn := os.Getenv("GOROOT"); fn != "" {
		gorootBase = fn
	}
	goroot := filepath.Join(gorootBase, "src", "pkg")

	dirsSeen := map[string]bool{}
	for _, fn := range filepath.SplitList(gopath) {
		if dirsSeen[fn] {
			continue
		}
		dirsSeen[fn] = true

		// goroot may be a part of gopath and we don't want that
		if fn != "" && !strings.HasPrefix(fn, gorootBase) {
			fn := filepath.Join(fn, "src")
			if fi, err := os.Stat(fn); err == nil && fi.IsDir() {
				dirs = append(dirs, fn)
			}
		}
	}

	if fi, err := os.Stat(goroot); err == nil && fi.IsDir() {
		dirs = append(dirs, goroot)
	}

	return dirs
}

func findPkg(fset *token.FileSet, importPath string, dirs []string, mode parser.Mode) (pkg *ast.Package, pkgs map[string]*ast.Package, err error) {
	for _, dir := range dirs {
		srcDir := filepath.Join(dir, importPath)
		if pkg, pkgs, err = parsePkg(fset, srcDir, mode); pkg != nil {
			return
		}
	}
	return
}

func eRune() []byte {
	s := make([]byte, utf8.RuneLen(utf8.RuneError))
	n := utf8.EncodeRune(s, utf8.RuneError)
	s = s[:n]
	return s
}

func tempDir(env map[string]string, subDirs ...string) string {
	dir := ""

	if env != nil {
		for _, k := range []string{"TMP", "TMPDIR"} {
			dir = env[k]
			if dir != "" {
				break
			}
		}
	}

	if dir == "" {
		dir = os.TempDir()
	}

	args := append([]string{dir, "GoSublime-temp"}, subDirs...)
	dir = filepath.Join(args...)
	os.MkdirAll(dir, 0777)

	return dir
}

func post(r Response) {
	sendCh <- r
}

func postMessage(format string, a ...interface{}) {
	post(Response{
		Token: "margo.message",
		Data: M{
			"message": fmt.Sprintf(format, a...),
		},
	})
}

func fileImportPaths(af *ast.File) []string {
	l := []string{}

	if af != nil {
		for _, decl := range af.Decls {
			if gdecl, ok := decl.(*ast.GenDecl); ok {
				for _, spec := range gdecl.Specs {
					if ispec, ok := spec.(*ast.ImportSpec); ok {
						ipath := unquote(ispec.Path.Value)
						if ipath != "C" {
							l = append(l, ipath)
						}
					}
				}
			}
		}
	}

	return l
}

func pathList(p, pathSep string) []string {
	if pathSep == "" {
		pathSep = string(filepath.ListSeparator)
	}
	l := strings.Split(p, pathSep)

	i := 0
	for _, s := range l {
		if s != "" {
			l[i] = s
			i += 1
		}
	}

	return l[:i]
}

func envRootList(env map[string]string) (string, []string) {
	if env == nil {
		return "", []string{}
	}
	return env["GOROOT"], pathList(env["GOPATH"], env["_pathsep"])
}

func msDur(start time.Time) time.Duration {
	dur := time.Now().Sub(start)
	dur -= dur % time.Millisecond
	return dur
}
<|endoftext|>


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

package gommander

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"sync"
)

type NodeList []*Node

// Filter a NodeList based on a predicate function.
// The predicate function should return true, if the Node in the
// list should be kept. Otherwise false should be returned.
// The result is a new NodeList containing the Nodes which the
// predicate function returned true for.
func (l NodeList) Filter(fn func(*Node) bool) NodeList {
	var p []*Node
	for _, v := range l {
		if fn(v) {
			p = append(p, v)
		}
	}
	return p
}

// Connect each Node in NodeList to their respective servers.
func (l NodeList) Connect() error {

	for _, n := range l {
		if err := n.Connect(); err != nil {
			return err
		}
	}

	return nil
}

// Close the connections for each Node in the NodeList.
func (l NodeList) Close() error {

	for _, n := range l {
		if err := n.Close(); err != nil {
			return err
		}
	}

	return nil
}

// Perform an operation against each Node in the NodeList.
// The result will be channel of Responses for each Node in the NodeList.
func (l NodeList) Each(fn func(*Node, func(Response) error) error) (chan Response, error) {

	var wg sync.WaitGroup
	wg.Add(len(l))

	responses := make(chan Response)

	for _, n := range l {

		respond := func(res Response) error {
			responses <- res
			wg.Done()
			return nil
		}

		if err := fn(n, respond); err != nil {
			println(err)
		}
	}

	go func() {
		wg.Wait()
		close(responses)
	}()

	return responses, nil
}

// Execute a Request against each Node in the NodeList.
// The result will be channel of Responses for each Node in the NodeList.
func (l NodeList) Execute(req Request) (chan Response, error) {
	return l.Each(func(n *Node, respond func(Response) error) error {
		req.Respond = respond
		return n.Execute(req)
	})
}

// Run a command against each Node in the NodeList.
// The result will be channel of Responses for each Node in the NodeList.
func (l NodeList) Run(command string) (chan Response, error) {
	req := Request{
		Command: command,
		Stdin:   new(bytes.Buffer),
	}

	return l.Execute(req)
}

// Copy a file from src to dest on each Node.
// The result will be channel of Responses for each Node in the NodeList.
func (l NodeList) Copy(src string, dest string) (chan Response, error) {

	command := "cat - > " + dest
	input := new(bytes.Buffer)

	in, err := os.Open(src)
	if err != nil {
		return nil, err
	}

	defer in.Close()

	if _, err = io.Copy(input, in); err != nil {
		return nil, err
	}

	return l.Each(func(n *Node, respond func(Response) error) error {

		req := Request{
			Command: command,
			Stdin:   bytes.NewReader(input.Bytes()),
			Respond: respond,
		}

		return n.Execute(req)
	})
}

// Write a file from at dest on each Node.
// The result will be channel of Responses for each Node in the NodeList.
func (l NodeList) Write(dest string, content *bytes.Reader) (chan Response, error) {

	command := "cat - > " + dest
	stdin := new(bytes.Buffer)

	fmt.Fprintln(stdin, "C0755", content.Len(), dest)
	if _, err := io.Copy(stdin, content); err != nil {
		return nil, err
	}

	return l.Each(func(n *Node, respond func(Response) error) error {

		req := Request{
			Command: command,
			Stdin:   bytes.NewReader(stdin.Bytes()),
			Respond: respond,
		}

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

package gommander

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"sync"
)

type NodeList []*Node

// Filter a NodeList based on a predicate function.
// The predicate function should return true, if the Node in the
// list should be kept. Otherwise false should be returned.
// The result is a new NodeList containing the Nodes which the
// predicate function returned true for.
func (l NodeList) Filter(fn func(*Node) bool) NodeList {
	var p []*Node
	for _, v := range l {
		if fn(v) {
			p = append(p, v)
		}
	}
	return p
}

// Connect each Node in NodeList to their respective servers.
func (l NodeList) Connect() error {

	for _, n := range l {
		if err := n.Connect(); err != nil {
			return err
		}
	}

	return nil
}

// Close the connections for each Node in the NodeList.
func (l NodeList) Close() error {

	for _, n := range l {
		if err := n.Close(); err != nil {
			return err
		}
	}

	return nil
}

// Perform an operation against each Node in the NodeList.
// The result will be channel of Responses for each Node in the NodeList.
func (l NodeList) Each(fn func(*Node, func(Response) error) error) (chan Response, error) {

	var wg sync.WaitGroup
	wg.Add(len(l))

	responses := make(chan Response)

	for _, n := range l {

		respond := func(res Response) error {
			responses <- res
			wg.Done()
			return nil
		}

		if err := fn(n, respond); err != nil {
			println(err)
		}
	}

	go func() {
		wg.Wait()
		close(responses)
	}()

	return responses, nil
}

// Execute a Request against each Node in the NodeList.
// The result will be channel of Responses for each Node in the NodeList.
func (l NodeList) Execute(req Request) (chan Response, error) {
	return l.Each(func(n *Node, respond func(Response) error) error {
		req.Respond = respond
		return n.Execute(req)
	})
}

// Run a command against each Node in the NodeList.
// The result will be channel of Responses for each Node in the NodeList.
func (l NodeList) Run(command string) (chan Response, error) {
	req := Request{
		Command: command,
		Stdin:   new(bytes.Buffer),
	}

	return l.Execute(req)
}

// Copy a file from src to dest on each Node.
// The result will be channel of Responses for each Node in the NodeList.
func (l NodeList) Copy(src string, dest string) (chan Response, error) {

	command := "cat - > " + dest
	input := new(bytes.Buffer)

	in, err := os.Open(src)
	if err != nil {
		return nil, err
	}

	defer in.Close()

	if _, err = io.Copy(input, in); err != nil {
		return nil, err
	}

	return l.Each(func(n *Node, respond func(Response) error) error {

		req := Request{
			Command: command,
			Stdin:   bytes.NewReader(input.Bytes()),
			Respond: respond,
		}

		return n.Execute(req)
	})
}

// Write a file from at dest on each Node.
// The result will be channel of Responses for each Node in the NodeList.
func (l NodeList) Write(dest string, content *bytes.Reader) (chan Response, error) {

	command := "cat - > " + dest
	stdin := new(bytes.Buffer)

	fmt.Fprintln(stdin, "C0755", content.Len(), dest)
	if _, err := io.Copy(stdin, content); err != nil {
		return nil, err
	}

	return l.Each(func(n *Node, respond func(Response) error) error {

		req := Request{
			Command: command,
			Stdin:   bytes.NewReader(stdin.Bytes()),
			Respond: respond,
		}

		return n.Execute(req)
	})
}

// Write a file from at dest on each Node.
// The result will be channel of Responses for each Node in the NodeList.
func (l NodeList) WriteBytes(dest string, content []byte) (chan Response, error) {

	command := "cat - > " + dest
	stdin := new(bytes.Buffer)

	fmt.Fprintln(stdin, "C0755", len(content), dest)
	if _, err := io.Copy(stdin, bytes.NewReader(content)); err != nil {
		return nil, err
	}

	return l.Each(func(n *Node, respond func(Response) error) error {

		req := Request{
			Command: command,
			Stdin:   bytes.NewReader(stdin.Bytes()),
			Respond: respond,
		}

		return n.Execute(req)
	})
}
<|endoftext|>