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

package benchmark_test

import (
	"os"
	"testing"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/x/ref/lib/security/securityflag"
	_ "v.io/x/ref/runtime/factories/static"
	"v.io/x/ref/runtime/internal/rpc/benchmark/internal"
	"v.io/x/ref/test"
	"v.io/x/ref/test/benchmark"
)

var (
	serverAddr string
	ctx        *context.T
)

// Benchmarks for non-streaming RPC.
func runEcho(b *testing.B, payloadSize int) {
	internal.CallEcho(b, ctx, serverAddr, b.N, payloadSize, benchmark.AddStats(b, 16))
}

func Benchmark____1B(b *testing.B) { runEcho(b, 1) }
func Benchmark___10B(b *testing.B) { runEcho(b, 10) }
func Benchmark__100B(b *testing.B) { runEcho(b, 100) }
func Benchmark___1KB(b *testing.B) { runEcho(b, 1000) }
func Benchmark__10KB(b *testing.B) { runEcho(b, 10000) }
func Benchmark_100KB(b *testing.B) { runEcho(b, 100000) }

// Benchmarks for streaming RPC.
func runEchoStream(b *testing.B, chunkCnt, payloadSize int) {
	internal.CallEchoStream(b, ctx, serverAddr, b.N, chunkCnt, payloadSize, benchmark.AddStats(b, 16))
}

func Benchmark____1_chunk_____1B(b *testing.B) { runEchoStream(b, 1, 1) }
func Benchmark____1_chunk____10B(b *testing.B) { runEchoStream(b, 1, 10) }
func Benchmark____1_chunk___100B(b *testing.B) { runEchoStream(b, 1, 100) }
func Benchmark____1_chunk____1KB(b *testing.B) { runEchoStream(b, 1, 1000) }
func Benchmark____1_chunk___10KB(b *testing.B) { runEchoStream(b, 1, 10000) }
func Benchmark____1_chunk__100KB(b *testing.B) { runEchoStream(b, 1, 100000) }
func Benchmark___10_chunk_____1B(b *testing.B) { runEchoStream(b, 10, 1) }
func Benchmark___10_chunk____10B(b *testing.B) { runEchoStream(b, 10, 10) }
func Benchmark___10_chunk___100B(b *testing.B) { runEchoStream(b, 10, 100) }
func Benchmark___10_chunk____1KB(b *testing.B) { runEchoStream(b, 10, 1000) }
func Benchmark___10_chunk___10KB(b *testing.B) { runEchoStream(b, 10, 10000) }
func Benchmark___10_chunk__100KB(b *testing.B) { runEchoStream(b, 10, 100000) }
func Benchmark__100_chunk_____1B(b *testing.B) { runEchoStream(b, 100, 1) }
func Benchmark__100_chunk____10B(b *testing.B) { runEchoStream(b, 100, 10) }
func Benchmark__100_chunk___100B(b *testing.B) { runEchoStream(b, 100, 100) }
func Benchmark__100_chunk____1KB(b *testing.B) { runEchoStream(b, 100, 1000) }
func Benchmark__100_chunk___10KB(b *testing.B) { runEchoStream(b, 100, 10000) }
func Benchmark__100_chunk__100KB(b *testing.B) { runEchoStream(b, 100, 100000) }
func Benchmark___1K_chunk_____1B(b *testing.B) { runEchoStream(b, 1000, 1) }
func Benchmark___1K_chunk____10B(b *testing.B) { runEchoStream(b, 1000, 10) }
func Benchmark___1K_chunk___100B(b *testing.B) { runEchoStream(b, 1000, 100) }
func Benchmark___1K_chunk____1KB(b *testing.B) { runEchoStream(b, 1000, 1000) }
func Benchmark___1K_chunk___10KB(b *testing.B) { runEchoStream(b, 1000, 10000) }
func Benchmark___1K_chunk__100KB(b *testing.B) { runEchoStream(b, 1000, 100000) }

// Benchmarks for per-chunk throughput in streaming RPC.
func runPerChunk(b *testing.B, payloadSize int) {
	internal.CallEchoStream(b, ctx, serverAddr, 1, b.N, payloadSize, benchmark.NewStats(1))
}

func Benchmark__per_chunk____1B(b *testing.B) { runPerChunk(b, 1) }
func Benchmark__per_chunk___10B(b *testing.B) { runPerChunk(b, 10) }
func Benchmark__per_chunk__100B(b *testing.B) { runPerChunk(b, 100) }
func Benchmark__per_chunk___1KB(b *testing.B) { runPerChunk(b, 1000) }
func Benchmark__per_chunk__10KB(b *testing.B) { runPerChunk(b, 10000) }
func Benchmark__per_chunk_100KB(b *testing.B) { runPerChunk(b, 100000) }

// Benchmarks for non-streaming RPC while running streaming RPC in background.
func runMux(b *testing.B, payloadSize, chunkCntB, payloadSizeB int) {
	_, stop := internal.StartEchoStream(&testing.B{}, ctx, serverAddr, 0, chunkCntB, payloadSizeB, benchmark.NewStats(1))
	internal.CallEcho(b, ctx, serverAddr, b.N, payloadSize, benchmark.AddStats(b, 16))
	stop()
}

func Benchmark___10B_mux__100_chunks___10B(b *testing.B) { runMux(b, 10, 100, 10) }
func Benchmark___10B_mux__100_chunks__100B(b *testing.B) { runMux(b, 10, 100, 100) }
func Benchmark___10B_mux__100_chunks___1KB(b *testing.B) { runMux(b, 10, 100, 1000) }
func Benchmark___10B_mux__100_chunks__10KB(b *testing.B) { runMux(b, 10, 100, 10000) }
func Benchmark___10B_mux___1K_chunks___10B(b *testing.B) { runMux(b, 10, 1000, 10) }
func Benchmark___10B_mux___1K_chunks__100B(b *testing.B) { runMux(b, 10, 1000, 100) }
func Benchmark___10B_mux___1K_chunks___1KB(b *testing.B) { runMux(b, 10, 1000, 1000) }
func Benchmark___10B_mux___1K_chunks__10KB(b *testing.B) { runMux(b, 10, 1000, 10000) }
func Benchmark___1KB_mux__100_chunks___10B(b *testing.B) { runMux(b, 1000, 100, 10) }
func Benchmark___1KB_mux__100_chunks__100B(b *testing.B) { runMux(b, 1000, 100, 100) }
func Benchmark___1KB_mux__100_chunks___1KB(b *testing.B) { runMux(b, 1000, 100, 1000) }
func Benchmark___1KB_mux__100_chunks__10KB(b *testing.B) { runMux(b, 1000, 100, 10000) }
func Benchmark___1KB_mux___1K_chunks___10B(b *testing.B) { runMux(b, 1000, 1000, 10) }
func Benchmark___1KB_mux___1K_chunks__100B(b *testing.B) { runMux(b, 1000, 1000, 100) }
func Benchmark___1KB_mux___1K_chunks___1KB(b *testing.B) { runMux(b, 1000, 1000, 1000) }
func Benchmark___1KB_mux___1K_chunks__10KB(b *testing.B) { runMux(b, 1000, 1000, 10000) }

// A single empty test to avoid:
// testing: warning: no tests to run
// from showing up when running benchmarks in this package via "go test"
func TestNoOp(t *testing.T) {}

func TestMain(m *testing.M) {
	test.Init()
	// We do not use defer here since this program will exit at the end of
	// this function through os.Exit().
	var shutdown v23.Shutdown
	ctx, shutdown = test.V23Init()

	ctx, server, err := v23.WithNewServer(ctx, "", internal.NewService(), securityflag.NewAuthorizerOrDie())
	if err != nil {
		ctx.Fatalf("NewServer failed: %v", err)
	}
	serverAddr = server.Status().Endpoints[0].Name()

	// Create a VC to exclude the VC setup time from the benchmark.
	internal.CallEcho(&testing.B{}, ctx, serverAddr, 1, 0, benchmark.NewStats(1))

	r := benchmark.RunTestMain(m)
	shutdown()
	os.Exit(r)
}
<commit_msg>rpc/benchmark: Make benchmark test pass under XServers state.<commit_after>// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package benchmark_test

import (
	"os"
	"testing"

	"v.io/v23"
	"v.io/v23/context"
	"v.io/x/ref/lib/security/securityflag"
	_ "v.io/x/ref/runtime/factories/static"
	"v.io/x/ref/runtime/internal/rpc/benchmark/internal"
	"v.io/x/ref/test"
	"v.io/x/ref/test/benchmark"
)

var (
	serverAddr string
	ctx        *context.T
)

// Benchmarks for non-streaming RPC.
func runEcho(b *testing.B, payloadSize int) {
	internal.CallEcho(b, ctx, serverAddr, b.N, payloadSize, benchmark.AddStats(b, 16))
}

func Benchmark____1B(b *testing.B) { runEcho(b, 1) }
func Benchmark___10B(b *testing.B) { runEcho(b, 10) }
func Benchmark__100B(b *testing.B) { runEcho(b, 100) }
func Benchmark___1KB(b *testing.B) { runEcho(b, 1000) }
func Benchmark__10KB(b *testing.B) { runEcho(b, 10000) }
func Benchmark_100KB(b *testing.B) { runEcho(b, 100000) }

// Benchmarks for streaming RPC.
func runEchoStream(b *testing.B, chunkCnt, payloadSize int) {
	internal.CallEchoStream(b, ctx, serverAddr, b.N, chunkCnt, payloadSize, benchmark.AddStats(b, 16))
}

func Benchmark____1_chunk_____1B(b *testing.B) { runEchoStream(b, 1, 1) }
func Benchmark____1_chunk____10B(b *testing.B) { runEchoStream(b, 1, 10) }
func Benchmark____1_chunk___100B(b *testing.B) { runEchoStream(b, 1, 100) }
func Benchmark____1_chunk____1KB(b *testing.B) { runEchoStream(b, 1, 1000) }
func Benchmark____1_chunk___10KB(b *testing.B) { runEchoStream(b, 1, 10000) }
func Benchmark____1_chunk__100KB(b *testing.B) { runEchoStream(b, 1, 100000) }
func Benchmark___10_chunk_____1B(b *testing.B) { runEchoStream(b, 10, 1) }
func Benchmark___10_chunk____10B(b *testing.B) { runEchoStream(b, 10, 10) }
func Benchmark___10_chunk___100B(b *testing.B) { runEchoStream(b, 10, 100) }
func Benchmark___10_chunk____1KB(b *testing.B) { runEchoStream(b, 10, 1000) }
func Benchmark___10_chunk___10KB(b *testing.B) { runEchoStream(b, 10, 10000) }
func Benchmark___10_chunk__100KB(b *testing.B) { runEchoStream(b, 10, 100000) }
func Benchmark__100_chunk_____1B(b *testing.B) { runEchoStream(b, 100, 1) }
func Benchmark__100_chunk____10B(b *testing.B) { runEchoStream(b, 100, 10) }
func Benchmark__100_chunk___100B(b *testing.B) { runEchoStream(b, 100, 100) }
func Benchmark__100_chunk____1KB(b *testing.B) { runEchoStream(b, 100, 1000) }
func Benchmark__100_chunk___10KB(b *testing.B) { runEchoStream(b, 100, 10000) }
func Benchmark__100_chunk__100KB(b *testing.B) { runEchoStream(b, 100, 100000) }
func Benchmark___1K_chunk_____1B(b *testing.B) { runEchoStream(b, 1000, 1) }
func Benchmark___1K_chunk____10B(b *testing.B) { runEchoStream(b, 1000, 10) }
func Benchmark___1K_chunk___100B(b *testing.B) { runEchoStream(b, 1000, 100) }
func Benchmark___1K_chunk____1KB(b *testing.B) { runEchoStream(b, 1000, 1000) }
func Benchmark___1K_chunk___10KB(b *testing.B) { runEchoStream(b, 1000, 10000) }
func Benchmark___1K_chunk__100KB(b *testing.B) { runEchoStream(b, 1000, 100000) }

// Benchmarks for per-chunk throughput in streaming RPC.
func runPerChunk(b *testing.B, payloadSize int) {
	internal.CallEchoStream(b, ctx, serverAddr, 1, b.N, payloadSize, benchmark.NewStats(1))
}

func Benchmark__per_chunk____1B(b *testing.B) { runPerChunk(b, 1) }
func Benchmark__per_chunk___10B(b *testing.B) { runPerChunk(b, 10) }
func Benchmark__per_chunk__100B(b *testing.B) { runPerChunk(b, 100) }
func Benchmark__per_chunk___1KB(b *testing.B) { runPerChunk(b, 1000) }
func Benchmark__per_chunk__10KB(b *testing.B) { runPerChunk(b, 10000) }
func Benchmark__per_chunk_100KB(b *testing.B) { runPerChunk(b, 100000) }

// Benchmarks for non-streaming RPC while running streaming RPC in background.
func runMux(b *testing.B, payloadSize, chunkCntB, payloadSizeB int) {
	_, stop := internal.StartEchoStream(&testing.B{}, ctx, serverAddr, 0, chunkCntB, payloadSizeB, benchmark.NewStats(1))
	internal.CallEcho(b, ctx, serverAddr, b.N, payloadSize, benchmark.AddStats(b, 16))
	stop()
}

func Benchmark___10B_mux__100_chunks___10B(b *testing.B) { runMux(b, 10, 100, 10) }
func Benchmark___10B_mux__100_chunks__100B(b *testing.B) { runMux(b, 10, 100, 100) }
func Benchmark___10B_mux__100_chunks___1KB(b *testing.B) { runMux(b, 10, 100, 1000) }
func Benchmark___10B_mux__100_chunks__10KB(b *testing.B) { runMux(b, 10, 100, 10000) }
func Benchmark___10B_mux___1K_chunks___10B(b *testing.B) { runMux(b, 10, 1000, 10) }
func Benchmark___10B_mux___1K_chunks__100B(b *testing.B) { runMux(b, 10, 1000, 100) }
func Benchmark___10B_mux___1K_chunks___1KB(b *testing.B) { runMux(b, 10, 1000, 1000) }
func Benchmark___10B_mux___1K_chunks__10KB(b *testing.B) { runMux(b, 10, 1000, 10000) }
func Benchmark___1KB_mux__100_chunks___10B(b *testing.B) { runMux(b, 1000, 100, 10) }
func Benchmark___1KB_mux__100_chunks__100B(b *testing.B) { runMux(b, 1000, 100, 100) }
func Benchmark___1KB_mux__100_chunks___1KB(b *testing.B) { runMux(b, 1000, 100, 1000) }
func Benchmark___1KB_mux__100_chunks__10KB(b *testing.B) { runMux(b, 1000, 100, 10000) }
func Benchmark___1KB_mux___1K_chunks___10B(b *testing.B) { runMux(b, 1000, 1000, 10) }
func Benchmark___1KB_mux___1K_chunks__100B(b *testing.B) { runMux(b, 1000, 1000, 100) }
func Benchmark___1KB_mux___1K_chunks___1KB(b *testing.B) { runMux(b, 1000, 1000, 1000) }
func Benchmark___1KB_mux___1K_chunks__10KB(b *testing.B) { runMux(b, 1000, 1000, 10000) }

// A single empty test to avoid:
// testing: warning: no tests to run
// from showing up when running benchmarks in this package via "go test"
func TestNoOp(t *testing.T) {}

func TestMain(m *testing.M) {
	test.Init()
	// We do not use defer here since this program will exit at the end of
	// this function through os.Exit().
	var shutdown v23.Shutdown
	ctx, shutdown = test.V23Init()

	_, server, err := v23.WithNewServer(ctx, "", internal.NewService(), securityflag.NewAuthorizerOrDie())
	if err != nil {
		ctx.Fatalf("NewServer failed: %v", err)
	}
	serverAddr = server.Status().Endpoints[0].Name()

	// Create a VC to exclude the VC setup time from the benchmark.
	internal.CallEcho(&testing.B{}, ctx, serverAddr, 1, 0, benchmark.NewStats(1))

	r := benchmark.RunTestMain(m)
	shutdown()
	os.Exit(r)
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	udt "github.com/fffw/go-udtwrapper"
	"io"
	"io/ioutil"
	"net"
	"os"
	"os/signal"
	"syscall"
	"time"
)

var verbose = false

// Usage prints out the usage of this module.
// Assumes flags use go stdlib flag pacakage.
var Usage = func() {
	text := `benchmark - UDT/TCP benchmark tool

Usage:

  server: %s -s<udt address> <tcp address>
  benchmarker:   %s [udt | tcp] <remote address>

Address format is Go's: [host]:port
`

	fmt.Fprintf(os.Stderr, text, os.Args[0], os.Args[0])
	flag.PrintDefaults()
}

type args struct {
	verbose bool
	listen  bool
	bs      int64

	udtAddr string
	tcpAddr string

	dialUdt    bool
	dialTcp    bool
	remoteAddr string
}

func parseArgs() args {
	var a args

	// setup + parse flags
	flag.BoolVar(&a.listen, "server", false, "listen for connections")
	flag.BoolVar(&a.listen, "s", false, "listen for connections (short)")
	flag.BoolVar(&a.dialUdt, "udt", false, "use udt client")
	flag.BoolVar(&a.dialTcp, "tcp", false, "use tcp client")
	flag.BoolVar(&a.verbose, "v", false, "verbose debugging")
	flag.Int64Var(&a.bs, "bs", 65536, "block size to send and receive")
	flag.Usage = Usage
	flag.Parse()
	osArgs := flag.Args()

	if a.listen {
		if len(osArgs) < 2 {
			Usage()
			exit("")
		}
		a.udtAddr = osArgs[0]
		a.tcpAddr = osArgs[1]
	} else {
		if len(osArgs) < 1 {
			Usage()
			exit("")
		}
		a.remoteAddr = osArgs[0]
	}

	return a
}

func main() {
	args := parseArgs()
	verbose = args.verbose

	go func() {
		// wait until we exit.
		sigc := make(chan os.Signal, 1)
		signal.Notify(sigc, syscall.SIGABRT)
		<-sigc
		panic("ABORT! ABORT! ABORT!")
	}()

	var err error
	if args.listen {
		err = Listen(args.udtAddr, args.tcpAddr, args.bs)
	} else {
		var c net.Conn
		if args.dialUdt {
			c, err = Dial("udt", args.remoteAddr)
		} else {
			c, err = Dial("tcp", args.remoteAddr)
		}
		if err != nil {
			exit("%s", err)
		}
		err = benchmark(c, args.bs)
	}

	if err != nil {
		exit("%s", err)
	}
}

func exit(format string, vals ...interface{}) {
	if format != "" {
		fmt.Fprintf(os.Stderr, "benchmark error: "+format+"\n", vals...)
	}
	os.Exit(1)
}

func log(format string, vals ...interface{}) {
	if verbose {
		fmt.Fprintf(os.Stderr, "benchmark log: "+format+"\n", vals...)
	}
}

// Listen listens and accepts one incoming UDT connection on a given port,
// and pipes all incoming data to os.Stdout.
func Listen(udtAddr string, tcpAddr string, bs int64) error {
	udt, err := udt.Listen("udt", udtAddr)
	if err != nil {
		return err
	}
	log("udt listening at %s", udt.Addr())

	tcp, err := net.Listen("tcp", tcpAddr)
	if err != nil {
		return err
	}
	log("tcp listening at %s", tcp.Addr())

	done := make(chan interface{}, 2)
	run := func(l net.Listener) (err error) {
		for {
			var c net.Conn
			c, err = l.Accept()
			if err != nil {
				return
			}
			log("accepted connection from %s", c.RemoteAddr())

			go func() {
				var n int64
				for {
					select {
					case <-done:
						return
					default:
						n, err = io.CopyN(c, c, bs)
						if err != nil {
							return
						}
						log("Copied back %d bytes", n)
					}
				}
				c.Close()

				return
			}()
		}
	}

	go run(udt)
	go run(tcp)
	// wait until we exit.
	sigc := make(chan os.Signal, 1)
	signal.Notify(sigc, syscall.SIGHUP, syscall.SIGINT,
		syscall.SIGTERM, syscall.SIGQUIT)
	<-sigc
	done <- nil
	return nil
}

// Dial connects to a remote address and pipes all os.Stdin to the remote end.
// If localAddr is set, uses it to Dial from.
func Dial(network, remoteAddr string) (c net.Conn, err error) {
	log("%s dialing %s", network, remoteAddr)
	if network == "udt" {
		c, err = udt.Dial("udt", remoteAddr)
	} else {
		c, err = net.Dial("tcp", remoteAddr)
	}
	if err != nil {
		return
	}
	log("connected to %s", c.RemoteAddr())
	return

}

func benchmark(c net.Conn, bs int64) (err error) {
	defer c.Close()
	rand, err := os.Open("/dev/zero")
	if err != nil {
		return
	}
	log("piping random to connection")

	done := make(chan interface{}, 2)
	var sent, recved int64
	startTime := time.Now()

	reportStat := func(prefix string, bytes int64) {
		timeSpent := time.Now().Sub(startTime) / time.Second
		fmt.Printf("%s %d bytes in %d sec, %d Bps\n", prefix, bytes, timeSpent, bytes/int64(timeSpent))
	}
	go func() {
		ticker := time.Tick(time.Second)
		for {
			select {
			case <-ticker:
				reportStat("Sent", sent)
			case <-done:
				return
			default:
				n, _ := io.CopyN(c, rand, bs)
				sent = sent + n
			}
		}
	}()
	go func() {
		ticker := time.Tick(time.Second)
		for {
			select {
			case <-ticker:
				reportStat("Recv", recved)
			case <-done:
				return
			default:
				n, _ := io.CopyN(ioutil.Discard, c, bs)
				recved = recved + n
			}
		}
	}()

	// wait until we exit.
	sigc := make(chan os.Signal, 1)
	signal.Notify(sigc, syscall.SIGHUP, syscall.SIGINT,
		syscall.SIGTERM, syscall.SIGQUIT)
	<-sigc
	done <- nil
	reportStat("Sent", sent)
	reportStat("Recv", recved)
	c.Close()
	return
}
<commit_msg>close server socket when EOF<commit_after>package main

import (
	"flag"
	"fmt"
	udt "github.com/fffw/go-udtwrapper"
	"io"
	"io/ioutil"
	"net"
	"os"
	"os/signal"
	"syscall"
	"time"
)

var verbose = false

// Usage prints out the usage of this module.
// Assumes flags use go stdlib flag pacakage.
var Usage = func() {
	text := `benchmark - UDT/TCP benchmark tool

Usage:

  server: %s -s<udt address> <tcp address>
  benchmarker:   %s [udt | tcp] <remote address>

Address format is Go's: [host]:port
`

	fmt.Fprintf(os.Stderr, text, os.Args[0], os.Args[0])
	flag.PrintDefaults()
}

type args struct {
	verbose bool
	listen  bool
	bs      int64

	udtAddr string
	tcpAddr string

	dialUdt    bool
	dialTcp    bool
	remoteAddr string
}

func parseArgs() args {
	var a args

	// setup + parse flags
	flag.BoolVar(&a.listen, "server", false, "listen for connections")
	flag.BoolVar(&a.listen, "s", false, "listen for connections (short)")
	flag.BoolVar(&a.dialUdt, "udt", false, "use udt client")
	flag.BoolVar(&a.dialTcp, "tcp", false, "use tcp client")
	flag.BoolVar(&a.verbose, "v", false, "verbose debugging")
	flag.Int64Var(&a.bs, "bs", 65536, "block size to send and receive")
	flag.Usage = Usage
	flag.Parse()
	osArgs := flag.Args()

	if a.listen {
		if len(osArgs) < 2 {
			Usage()
			exit("")
		}
		a.udtAddr = osArgs[0]
		a.tcpAddr = osArgs[1]
	} else {
		if len(osArgs) < 1 {
			Usage()
			exit("")
		}
		a.remoteAddr = osArgs[0]
	}

	return a
}

func main() {
	args := parseArgs()
	verbose = args.verbose

	go func() {
		// wait until we exit.
		sigc := make(chan os.Signal, 1)
		signal.Notify(sigc, syscall.SIGABRT)
		<-sigc
		panic("ABORT! ABORT! ABORT!")
	}()

	var err error
	if args.listen {
		err = Listen(args.udtAddr, args.tcpAddr, args.bs)
	} else {
		var c net.Conn
		if args.dialUdt {
			c, err = Dial("udt", args.remoteAddr)
		} else {
			c, err = Dial("tcp", args.remoteAddr)
		}
		if err != nil {
			exit("%s", err)
		}
		err = benchmark(c, args.bs)
	}

	if err != nil {
		exit("%s", err)
	}
}

func exit(format string, vals ...interface{}) {
	if format != "" {
		fmt.Fprintf(os.Stderr, "benchmark error: "+format+"\n", vals...)
	}
	os.Exit(1)
}

func log(format string, vals ...interface{}) {
	if verbose {
		fmt.Fprintf(os.Stderr, "benchmark log: "+format+"\n", vals...)
	}
}

// Listen listens and accepts one incoming UDT connection on a given port,
// and pipes all incoming data to os.Stdout.
func Listen(udtAddr string, tcpAddr string, bs int64) error {
	udt, err := udt.Listen("udt", udtAddr)
	if err != nil {
		return err
	}
	log("udt listening at %s", udt.Addr())

	tcp, err := net.Listen("tcp", tcpAddr)
	if err != nil {
		return err
	}
	log("tcp listening at %s", tcp.Addr())

	done := make(chan interface{}, 2)
	run := func(l net.Listener) (err error) {
		for {
			var c net.Conn
			c, err = l.Accept()
			if err != nil {
				return
			}
			log("accepted connection from %s", c.RemoteAddr())

			go func() {
				for {
					select {
					case <-done:
						c.Close()
						return
					default:
						n, e := io.CopyN(c, c, bs)
						if e == io.EOF {
							c.Close()
							return
						}
						log("Copied back %d bytes", n)
					}
				}

				return
			}()
		}
	}

	go run(udt)
	go run(tcp)
	// wait until we exit.
	sigc := make(chan os.Signal, 1)
	signal.Notify(sigc, syscall.SIGHUP, syscall.SIGINT,
		syscall.SIGTERM, syscall.SIGQUIT)
	<-sigc
	fmt.Println("Quit now")
	done <- nil
	return nil
}

// Dial connects to a remote address and pipes all os.Stdin to the remote end.
// If localAddr is set, uses it to Dial from.
func Dial(network, remoteAddr string) (c net.Conn, err error) {
	log("%s dialing %s", network, remoteAddr)
	if network == "udt" {
		c, err = udt.Dial("udt", remoteAddr)
	} else {
		c, err = net.Dial("tcp", remoteAddr)
	}
	if err != nil {
		return
	}
	log("connected to %s", c.RemoteAddr())
	return

}

func benchmark(c net.Conn, bs int64) (err error) {
	defer c.Close()
	rand, err := os.Open("/dev/zero")
	if err != nil {
		return
	}
	log("piping random to connection")

	done := make(chan interface{}, 2)
	var sent, recved int64
	startTime := time.Now()

	reportStat := func(prefix string, bytes int64) {
		timeSpent := time.Now().Sub(startTime) / time.Second
		fmt.Printf("%s %d bytes in %d sec, %d Bps\n", prefix, bytes, timeSpent, bytes/int64(timeSpent))
	}
	go func() {
		ticker := time.Tick(time.Second)
		for {
			select {
			case <-ticker:
				reportStat("Sent", sent)
			case <-done:
				return
			default:
				n, _ := io.CopyN(c, rand, bs)
				sent = sent + n
			}
		}
	}()
	go func() {
		ticker := time.Tick(time.Second)
		for {
			select {
			case <-ticker:
				reportStat("Recv", recved)
			case <-done:
				return
			default:
				n, _ := io.CopyN(ioutil.Discard, c, bs)
				recved = recved + n
			}
		}
	}()

	// wait until we exit.
	sigc := make(chan os.Signal, 1)
	signal.Notify(sigc, syscall.SIGHUP, syscall.SIGINT,
		syscall.SIGTERM, syscall.SIGQUIT)
	<-sigc
	fmt.Println("Quit now, final result:")
	done <- nil
	done <- nil
	reportStat("Sent", sent)
	reportStat("Recv", recved)
	c.Close()
	return
}
<|endoftext|>


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

package encoding

import (
	"unicode/utf8"

	"code.google.com/p/go.text/transform"
)

// utf8Enc holds a rune's UTF-8 encoding in data[:len].
type utf8Enc struct {
	len  uint8
	data [3]byte
}

// charmap describes an 8-bit character set encoding.
type charmap struct {
	// name is the encoding's name.
	name string
	// asciiSuperset states whether the encoding is a superset of ASCII.
	asciiSuperset bool
	// low is the lower bound of the encoded byte for a non-ASCII rune. If
	// charmap.asciiSuperset is true then this will be 0x80, otherwise 0x00.
	low uint8
	// replacement is the encoded replacement character.
	replacement byte
	// decode is the map from encoded byte to UTF-8.
	decode [256]utf8Enc
	// encoding is the map from runes to encoded bytes. Each entry is a
	// uint32: the high 8 bits are the encoded byte and the low 24 bits are
	// the rune. The table entries are sorted by ascending rune.
	encode [256]uint32
}

func (m *charmap) NewDecoder() transform.Transformer {
	return charmapDecoder{charmap: m}
}

func (m *charmap) NewEncoder() transform.Transformer {
	return &charmapEncoder{charmap: m}
}

func (m *charmap) String() string {
	return m.name
}

// charmapDecoder implements transform.Transformer by decoding to UTF-8.
type charmapDecoder struct {
	charmap *charmap
}

func (m charmapDecoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
	for i, c := range src {
		if m.charmap.asciiSuperset && c < utf8.RuneSelf {
			if nDst >= len(dst) {
				err = transform.ErrShortDst
				break
			}
			dst[nDst] = c
			nDst++
			nSrc = i + 1
			continue
		}

		decode := &m.charmap.decode[c]
		n := int(decode.len)
		if nDst+n > len(dst) {
			err = transform.ErrShortDst
			break
		}
		// It's 15% faster to avoid calling copy for these tiny slices.
		for j := 0; j < n; j++ {
			dst[nDst] = decode.data[j]
			nDst++
		}
		nSrc = i + 1
	}
	return nDst, nSrc, err
}

// charmapEncoder implements transform.Transformer by encoding from UTF-8.
type charmapEncoder struct {
	charmap *charmap
}

func (m *charmapEncoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
	r, size := rune(0), 0
	for nSrc < len(src) {
		if nDst >= len(dst) {
			err = transform.ErrShortDst
			break
		}
		r = rune(src[nSrc])

		// Decode a 1-byte rune.
		if r < utf8.RuneSelf {
			nSrc++
			if m.charmap.asciiSuperset {
				dst[nDst] = uint8(r)
				nDst++
				continue
			}

		} else {
			// Decode a multi-byte rune.
			r, size = utf8.DecodeRune(src[nSrc:])
			if size == 1 {
				// All valid runes of size 1 (those below utf8.RuneSelf) were
				// handled above. We have invalid UTF-8.
				if !atEOF && !utf8.FullRune(src[nSrc:]) {
					err = transform.ErrShortSrc
					break
				}
			}
			nSrc += size
			if r == utf8.RuneError {
				dst[nDst] = m.charmap.replacement
				nDst++
				continue
			}
		}

		// Binary search in [low, high) for that rune in the m.charmap.encode table.
		for low, high := int(m.charmap.low), 0x100; ; {
			if low >= high {
				dst[nDst] = m.charmap.replacement
				nDst++
				break
			}
			mid := (low + high) / 2
			got := m.charmap.encode[mid]
			gotRune := rune(got & (1<<24 - 1))
			if gotRune < r {
				low = mid + 1
			} else if gotRune > r {
				high = mid
			} else {
				dst[nDst] = byte(got >> 24)
				nDst++
				break
			}
		}
	}
	return nDst, nSrc, err
}
<commit_msg>go.text/encoding: simplify charmapEncoder now that https://codereview.appspot.com/12087043/ "remove UTF-8 synchronization" has landed.<commit_after>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package encoding

import (
	"unicode/utf8"

	"code.google.com/p/go.text/transform"
)

// utf8Enc holds a rune's UTF-8 encoding in data[:len].
type utf8Enc struct {
	len  uint8
	data [3]byte
}

// charmap describes an 8-bit character set encoding.
type charmap struct {
	// name is the encoding's name.
	name string
	// asciiSuperset states whether the encoding is a superset of ASCII.
	asciiSuperset bool
	// low is the lower bound of the encoded byte for a non-ASCII rune. If
	// charmap.asciiSuperset is true then this will be 0x80, otherwise 0x00.
	low uint8
	// replacement is the encoded replacement character.
	replacement byte
	// decode is the map from encoded byte to UTF-8.
	decode [256]utf8Enc
	// encoding is the map from runes to encoded bytes. Each entry is a
	// uint32: the high 8 bits are the encoded byte and the low 24 bits are
	// the rune. The table entries are sorted by ascending rune.
	encode [256]uint32
}

func (m *charmap) NewDecoder() transform.Transformer {
	return charmapDecoder{charmap: m}
}

func (m *charmap) NewEncoder() transform.Transformer {
	return charmapEncoder{charmap: m}
}

func (m *charmap) String() string {
	return m.name
}

// charmapDecoder implements transform.Transformer by decoding to UTF-8.
type charmapDecoder struct {
	charmap *charmap
}

func (m charmapDecoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
	for i, c := range src {
		if m.charmap.asciiSuperset && c < utf8.RuneSelf {
			if nDst >= len(dst) {
				err = transform.ErrShortDst
				break
			}
			dst[nDst] = c
			nDst++
			nSrc = i + 1
			continue
		}

		decode := &m.charmap.decode[c]
		n := int(decode.len)
		if nDst+n > len(dst) {
			err = transform.ErrShortDst
			break
		}
		// It's 15% faster to avoid calling copy for these tiny slices.
		for j := 0; j < n; j++ {
			dst[nDst] = decode.data[j]
			nDst++
		}
		nSrc = i + 1
	}
	return nDst, nSrc, err
}

// charmapEncoder implements transform.Transformer by encoding from UTF-8.
type charmapEncoder struct {
	charmap *charmap
}

func (m charmapEncoder) Transform(dst, src []byte, atEOF bool) (nDst, nSrc int, err error) {
	r, size := rune(0), 0
	for nSrc < len(src) {
		if nDst >= len(dst) {
			err = transform.ErrShortDst
			break
		}
		r = rune(src[nSrc])

		// Decode a 1-byte rune.
		if r < utf8.RuneSelf {
			nSrc++
			if m.charmap.asciiSuperset {
				dst[nDst] = uint8(r)
				nDst++
				continue
			}

		} else {
			// Decode a multi-byte rune.
			r, size = utf8.DecodeRune(src[nSrc:])
			if size == 1 {
				// All valid runes of size 1 (those below utf8.RuneSelf) were
				// handled above. We have invalid UTF-8.
				if !atEOF && !utf8.FullRune(src[nSrc:]) {
					err = transform.ErrShortSrc
					break
				}
			}
			nSrc += size
			if r == utf8.RuneError {
				dst[nDst] = m.charmap.replacement
				nDst++
				continue
			}
		}

		// Binary search in [low, high) for that rune in the m.charmap.encode table.
		for low, high := int(m.charmap.low), 0x100; ; {
			if low >= high {
				dst[nDst] = m.charmap.replacement
				nDst++
				break
			}
			mid := (low + high) / 2
			got := m.charmap.encode[mid]
			gotRune := rune(got & (1<<24 - 1))
			if gotRune < r {
				low = mid + 1
			} else if gotRune > r {
				high = mid
			} else {
				dst[nDst] = byte(got >> 24)
				nDst++
				break
			}
		}
	}
	return nDst, nSrc, err
}
<|endoftext|>


<commit_before>package engine

import (
	"math"
)

type Transform struct {
	gameObject *GameObject
	parent     *Transform
	position   Vector
	rotation   Vector
	scale      Vector

	children []*Transform

	worldPosition Vector
	worldRotation Vector
	worldScale    Vector
	matrix        Matrix
	parentMatrix  Matrix
	updatedMatrix bool
	childOfScene  bool

	depth       int8
	inDepthList bool
}

func NewTransform(g *GameObject) *Transform {
	return &Transform{g, nil, Zero, Zero, One, make([]*Transform, 0), Zero, Zero, One, Identity(), Identity(), false, false, 0, false}
}

func (t *Transform) SetDepth(depth int8) {
	t.removeFromDepthMap()
	t.depth = depth
	//If object is in scene add to depth map
	if t.InScene() {
		t.checkDepth()
	}
}

func (t *Transform) SetDepthRecursive(depth int8) {
	t.SetDepth(depth)
	for _, c := range t.children {
		c.SetDepthRecursive(depth)
	}
}

func (t *Transform) checkDepth() {
	if !t.inDepthList {
		depthMap.Add(int(t.depth), t.gameObject)
		t.inDepthList = true
	}
}

func (t *Transform) checkDepthRecursive() {
	t.checkDepth()
	for _, c := range t.children {
		c.checkDepthRecursive()
	}
}

func (t *Transform) removeFromDepthMap() {
	if t.inDepthList {
		depthMap.Remove(int(t.depth), t.gameObject)
	}
	t.inDepthList = false
}

func (t *Transform) removeFromDepthMapRecursive() {
	t.removeFromDepthMap()
	for _, c := range t.children {
		c.removeFromDepthMapRecursive()
	}
}

/*
Checking if object is somewhere in scene.
*/
func (t *Transform) InScene() bool {
	return t.childOfScene || (t.parent != nil && t.parent.InScene())
}

func (t *Transform) Depth() int8 {
	return t.depth
}

func (t *Transform) Position() Vector {
	return t.position
}

func (t *Transform) Rotation() Vector {
	return t.rotation
}

func (t *Transform) Angle() float32 {
	return t.WorldRotation().Z
}

func (t *Transform) Direction() Vector {
	angle := t.Angle() * RadianConst
	return NewVector2(float32(math.Cos(float64(angle))), float32(math.Sin(float64(angle))))
}

func (t *Transform) DirectionTransform(up Vector) Vector {
	angle := float32(RadianConst)
	angle *= (t.Angle() + float32(math.Atan2(float64(up.Y), float64(up.X)))*float32(DegreeConst))
	return NewVector2(float32(math.Cos(float64(angle))), float32(math.Sin(float64(angle))))
}

func (t *Transform) Scale() Vector {
	return t.scale
}

func (t *Transform) SetPosition(vect Vector) {
	t.updatedMatrix = false
	t.position = vect
}

func (t *Transform) SetPositionf(x, y float32) {
	t.updatedMatrix = false
	t.position.X, t.position.Y = x, y
}

func (t *Transform) SetRotation(vect Vector) {
	t.updatedMatrix = false
	t.rotation = vect
}

func (t *Transform) SetRotationf(z float32) {
	t.updatedMatrix = false
	t.rotation.Z = z
}

func (t *Transform) SetScale(vect Vector) {
	t.updatedMatrix = false
	t.scale = vect
}

func (t *Transform) SetScalef(x, y float32) {
	t.updatedMatrix = false
	t.scale.X, t.scale.Y = x, y
}

func (t *Transform) WorldPosition() Vector {
	if t.parent == nil {
		return t.position
	}
	t.updateMatrix()
	return t.worldPosition
}

func (t *Transform) WorldRotation() Vector {
	if t.parent == nil {
		return t.rotation
	}
	t.updateMatrix()
	return t.worldRotation
}

func (t *Transform) WorldScale() Vector {
	if t.parent == nil {
		return t.scale
	}
	t.updateMatrix()
	return t.worldScale
}

func (t *Transform) SetWorldPosition(vect Vector) {
	if t.parent == nil {
		t.SetPosition(vect)
		return
	}
	t.parent.updateMatrix()
	t.SetPosition(vect.Transform(t.parent.matrix.Invert()))
}

func (t *Transform) SetWorldPositionf(x, y float32) {
	t.SetWorldPosition(NewVector3(x, y, t.worldPosition.Z))
}

func (t *Transform) SetWorldRotation(vect Vector) {
	if t.parent == nil {
		t.SetRotation(vect)
	} else {
		t.worldRotation = vect
		t.SetRotation(vect.Sub(t.parent.WorldRotation()))
	}
}

func (t *Transform) SetWorldRotationf(z float32) {
	t.SetWorldRotation(NewVector3(t.worldRotation.X, t.worldRotation.Y, z))
}

func (t *Transform) SetWorldScale(vect Vector) {
	if t.parent == nil {
		t.SetScale(vect)
	} else {
		t.worldScale = vect
		t.SetScale(vect.Div(t.parent.WorldScale()))
	}
}

func (t *Transform) SetWorldScalef(x, y float32) {
	t.SetWorldScale(NewVector3(x, y, t.worldScale.Z))
}

func (t *Transform) Parent() *Transform {
	return t.parent
}

func (t *Transform) GameObject() *GameObject {
	return t.gameObject.GameObject()
}

func (t *Transform) Child(index int) *Transform {
	if index < len(t.children) {
		return t.children[index]
	}
	return nil
}

func (t *Transform) Children() []*Transform {
	arr := make([]*Transform, len(t.children))
	copy(arr, t.children)
	return arr
}

func (t *Transform) Translate(v Vector) {
	a := t.Position()
	t.SetPosition(a.Add(v))
}

func (t *Transform) Translatef(x, y float32) {
	t.Translate(NewVector3(x, y, 0))
}

func (t *Transform) SetParent(parent *Transform) {
	if t.parent == parent {
		if parent == nil {
			if t.childOfScene {
				return
			}
		} else {
			return
		}
	}

	//Remove from scene if needed
	if t.childOfScene && parent != nil {
		GetScene().SceneBase().removeGameObject(t.gameObject)
	}

	//if parent is not nil, remove this transform from parent
	if t.parent != nil {
		for i, c := range t.parent.children {
			if t == c {
				t.parent.children = append(t.parent.children[:i], t.parent.children[i+1:]...)
				break
			}
		}
	}

	//if depth is not updated, update it
	t.checkDepth()

	//check if object was outside of scene
	wasOutsideScene := !t.InScene()

	//Keep the position after changing parents
	if t.parent != nil {
		scale := t.WorldScale()
		position := t.WorldPosition()
		rotation := t.WorldRotation()
		t.parent = parent
		t.updatedMatrix = false
		t.SetWorldPosition(position)
		t.SetWorldRotation(rotation)
		t.SetWorldScale(scale)
	} else {
		scale := t.Scale()
		position := t.Position()
		rotation := t.Rotation()
		t.parent = parent
		t.updatedMatrix = false
		t.SetRotation(position)
		t.SetRotation(rotation)
		t.SetScale(scale)
	}

	//If parent is nil add to scene else add to transform children
	if parent != nil {
		parent.children = append(parent.children, t)
	} else {
		GetScene().SceneBase().addGameObject(t.gameObject)
	}

	//If object was outside of scene active it silencly and check if depth needs to be updated
	if wasOutsideScene {
		t.gameObject.setActiveRecursiveSilent(true)
		t.checkDepthRecursive()
	}
}

func (t *Transform) SetParent2(g *GameObject) {
	if g == nil {
		t.SetParent(nil)
	} else {
		t.SetParent(g.transform)
	}
}

/*
Faster option will be to use Stamps, each transform will have stamp and parterStamp
*/
func (t *Transform) updateMatrix() bool {
	if t.updatedMatrix {
		if t.parent != nil {
			t.parent.updateMatrix()
			if t.parent.matrix == t.parentMatrix {
				return false
			}
		} else {
			return false
		}
	}

	trans := t

	s, r, p := trans.scale, trans.rotation, trans.position

	trans.matrix.Reset()
	mat := &trans.matrix

	mat.Scale(s.X, s.Y, s.Z)
	mat.RotateX(r.X, 1)
	mat.RotateY(r.Y, 1)
	mat.RotateZ(r.Z, -1)
	mat.Translate(p.X, p.Y, p.Z)

	if trans.parent != nil {
		trans.parent.updateMatrix()
		t.parentMatrix = trans.parent.matrix
		mat.MulPtr(&t.parentMatrix)
		t.worldScale = trans.parent.worldScale.Mul(trans.scale)
		t.worldRotation = trans.parent.worldRotation.Add(trans.rotation)
	} else {
		t.worldScale = trans.scale
		t.worldRotation = trans.rotation
	}

	t.worldPosition = mat.Translation()

	//fmt.Println(t.GameObject().name)

	t.updatedMatrix = true
	return true
}

func (t *Transform) Matrix() Matrix {
	t.updateMatrix()
	return t.matrix
}

func (t *Transform) clone(parent *GameObject) *Transform {
	tn := NewTransform(parent)
	tn.position = t.position
	tn.rotation = t.rotation
	tn.scale = t.scale
	for _, c := range t.children {
		c.gameObject.Clone().transform.SetParent(tn)
	}
	tn.depth = t.depth
	return tn
}
<commit_msg>Fixed bug in SetParent.<commit_after>package engine

import (
	"math"
)

type Transform struct {
	gameObject *GameObject
	parent     *Transform
	position   Vector
	rotation   Vector
	scale      Vector

	children []*Transform

	worldPosition Vector
	worldRotation Vector
	worldScale    Vector
	matrix        Matrix
	parentMatrix  Matrix
	updatedMatrix bool
	childOfScene  bool

	depth       int8
	inDepthList bool
}

func NewTransform(g *GameObject) *Transform {
	return &Transform{g, nil, Zero, Zero, One, make([]*Transform, 0), Zero, Zero, One, Identity(), Identity(), false, false, 0, false}
}

func (t *Transform) SetDepth(depth int8) {
	t.removeFromDepthMap()
	t.depth = depth
	//If object is in scene add to depth map
	if t.InScene() {
		t.checkDepth()
	}
}

func (t *Transform) SetDepthRecursive(depth int8) {
	t.SetDepth(depth)
	for _, c := range t.children {
		c.SetDepthRecursive(depth)
	}
}

func (t *Transform) checkDepth() {
	if !t.inDepthList {
		depthMap.Add(int(t.depth), t.gameObject)
		t.inDepthList = true
	}
}

func (t *Transform) checkDepthRecursive() {
	t.checkDepth()
	for _, c := range t.children {
		c.checkDepthRecursive()
	}
}

func (t *Transform) removeFromDepthMap() {
	if t.inDepthList {
		depthMap.Remove(int(t.depth), t.gameObject)
	}
	t.inDepthList = false
}

func (t *Transform) removeFromDepthMapRecursive() {
	t.removeFromDepthMap()
	for _, c := range t.children {
		c.removeFromDepthMapRecursive()
	}
}

/*
Checking if object is somewhere in scene.
*/
func (t *Transform) InScene() bool {
	return t.childOfScene || (t.parent != nil && t.parent.InScene())
}

func (t *Transform) Depth() int8 {
	return t.depth
}

func (t *Transform) Position() Vector {
	return t.position
}

func (t *Transform) Rotation() Vector {
	return t.rotation
}

func (t *Transform) Angle() float32 {
	return t.WorldRotation().Z
}

func (t *Transform) Direction() Vector {
	angle := t.Angle() * RadianConst
	return NewVector2(float32(math.Cos(float64(angle))), float32(math.Sin(float64(angle))))
}

func (t *Transform) DirectionTransform(up Vector) Vector {
	angle := float32(RadianConst)
	angle *= (t.Angle() + float32(math.Atan2(float64(up.Y), float64(up.X)))*float32(DegreeConst))
	return NewVector2(float32(math.Cos(float64(angle))), float32(math.Sin(float64(angle))))
}

func (t *Transform) Scale() Vector {
	return t.scale
}

func (t *Transform) SetPosition(vect Vector) {
	t.updatedMatrix = false
	t.position = vect
}

func (t *Transform) SetPositionf(x, y float32) {
	t.updatedMatrix = false
	t.position.X, t.position.Y = x, y
}

func (t *Transform) SetRotation(vect Vector) {
	t.updatedMatrix = false
	t.rotation = vect
}

func (t *Transform) SetRotationf(z float32) {
	t.updatedMatrix = false
	t.rotation.Z = z
}

func (t *Transform) SetScale(vect Vector) {
	t.updatedMatrix = false
	t.scale = vect
}

func (t *Transform) SetScalef(x, y float32) {
	t.updatedMatrix = false
	t.scale.X, t.scale.Y = x, y
}

func (t *Transform) WorldPosition() Vector {
	if t.parent == nil {
		return t.position
	}
	t.updateMatrix()
	return t.worldPosition
}

func (t *Transform) WorldRotation() Vector {
	if t.parent == nil {
		return t.rotation
	}
	t.updateMatrix()
	return t.worldRotation
}

func (t *Transform) WorldScale() Vector {
	if t.parent == nil {
		return t.scale
	}
	t.updateMatrix()
	return t.worldScale
}

func (t *Transform) SetWorldPosition(vect Vector) {
	if t.parent == nil {
		t.SetPosition(vect)
		return
	}
	t.parent.updateMatrix()
	t.SetPosition(vect.Transform(t.parent.matrix.Invert()))
}

func (t *Transform) SetWorldPositionf(x, y float32) {
	t.SetWorldPosition(NewVector3(x, y, t.worldPosition.Z))
}

func (t *Transform) SetWorldRotation(vect Vector) {
	if t.parent == nil {
		t.SetRotation(vect)
	} else {
		t.worldRotation = vect
		t.SetRotation(vect.Sub(t.parent.WorldRotation()))
	}
}

func (t *Transform) SetWorldRotationf(z float32) {
	t.SetWorldRotation(NewVector3(t.worldRotation.X, t.worldRotation.Y, z))
}

func (t *Transform) SetWorldScale(vect Vector) {
	if t.parent == nil {
		t.SetScale(vect)
	} else {
		t.worldScale = vect
		t.SetScale(vect.Div(t.parent.WorldScale()))
	}
}

func (t *Transform) SetWorldScalef(x, y float32) {
	t.SetWorldScale(NewVector3(x, y, t.worldScale.Z))
}

func (t *Transform) Parent() *Transform {
	return t.parent
}

func (t *Transform) GameObject() *GameObject {
	return t.gameObject.GameObject()
}

func (t *Transform) Child(index int) *Transform {
	if index < len(t.children) {
		return t.children[index]
	}
	return nil
}

func (t *Transform) Children() []*Transform {
	arr := make([]*Transform, len(t.children))
	copy(arr, t.children)
	return arr
}

func (t *Transform) Translate(v Vector) {
	a := t.Position()
	t.SetPosition(a.Add(v))
}

func (t *Transform) Translatef(x, y float32) {
	t.Translate(NewVector3(x, y, 0))
}

func (t *Transform) SetParent(parent *Transform) {
	if t.parent == parent {
		if parent == nil {
			if t.childOfScene {
				return
			}
		} else {
			return
		}
	}

	//Remove from scene if needed
	if t.childOfScene && parent != nil {
		GetScene().SceneBase().removeGameObject(t.gameObject)
	}

	//if parent is not nil, remove this transform from parent
	if t.parent != nil {
		for i, c := range t.parent.children {
			if t == c {
				t.parent.children = append(t.parent.children[:i], t.parent.children[i+1:]...)
				break
			}
		}
	}

	//if depth is not updated, update it
	t.checkDepth()

	//check if object was outside of scene
	wasOutsideScene := !t.InScene()

	//Keep the position after changing parents
	scale := t.WorldScale()
	position := t.WorldPosition()
	rotation := t.WorldRotation()
	t.parent = parent
	t.updatedMatrix = false
	t.SetWorldPosition(position)
	t.SetWorldRotation(rotation)
	t.SetWorldScale(scale)

	//If parent is nil add to scene else add to transform children
	if parent != nil {
		parent.children = append(parent.children, t)
	} else {
		GetScene().SceneBase().addGameObject(t.gameObject)
	}

	//If object was outside of scene active it silencly and check if depth needs to be updated
	if wasOutsideScene {
		t.gameObject.setActiveRecursiveSilent(true)
		t.checkDepthRecursive()
	}
}

func (t *Transform) SetParent2(g *GameObject) {
	if g == nil {
		t.SetParent(nil)
	} else {
		t.SetParent(g.transform)
	}
}

/*
Faster option will be to use Stamps, each transform will have stamp and parterStamp
*/
func (t *Transform) updateMatrix() bool {
	if t.updatedMatrix {
		if t.parent != nil {
			t.parent.updateMatrix()
			if t.parent.matrix == t.parentMatrix {
				return false
			}
		} else {
			return false
		}
	}

	trans := t

	s, r, p := trans.scale, trans.rotation, trans.position

	trans.matrix.Reset()
	mat := &trans.matrix

	mat.Scale(s.X, s.Y, s.Z)
	mat.RotateX(r.X, 1)
	mat.RotateY(r.Y, 1)
	mat.RotateZ(r.Z, -1)
	mat.Translate(p.X, p.Y, p.Z)

	if trans.parent != nil {
		trans.parent.updateMatrix()
		t.parentMatrix = trans.parent.matrix
		mat.MulPtr(&t.parentMatrix)
		t.worldScale = trans.parent.worldScale.Mul(trans.scale)
		t.worldRotation = trans.parent.worldRotation.Add(trans.rotation)
	} else {
		t.worldScale = trans.scale
		t.worldRotation = trans.rotation
	}

	t.worldPosition = mat.Translation()

	//fmt.Println(t.GameObject().name)

	t.updatedMatrix = true
	return true
}

func (t *Transform) Matrix() Matrix {
	t.updateMatrix()
	return t.matrix
}

func (t *Transform) clone(parent *GameObject) *Transform {
	tn := NewTransform(parent)
	tn.position = t.position
	tn.rotation = t.rotation
	tn.scale = t.scale
	for _, c := range t.children {
		c.gameObject.Clone().transform.SetParent(tn)
	}
	tn.depth = t.depth
	return tn
}
<|endoftext|>


<commit_before>package runtime

import (
    "crypto/sha1"
    "io"
    "fmt"
    "os/exec"
    "bytes"
    "syscall"
    "os"
    "io/ioutil"
    "log"
)

func RunCode(code string) (*Result) {
    h := sha1.New()
    io.WriteString(h, code)
    sha := fmt.Sprintf("%x", h.Sum(nil))

    out_filename := fmt.Sprintf("/tmp/%s.output", sha)
    src_filename := fmt.Sprintf("/tmp/%s.go", sha)
    var b []byte
    var result Result
    var err error

    // read a Result from the file and if no error, try to decode
    if b, err = ioutil.ReadFile(out_filename); err == nil {
        result, err = decodeResults(b)
    }

    // if there was an error, compile and run the code again
    if err != nil {
        log.Println("Compiling and running code")
        err := ioutil.WriteFile(src_filename, []byte(code), 0644)
        if err != nil {
            panic(err)
        }
        result = runGoProgram(src_filename)
        ioutil.WriteFile(out_filename, result.encode(), 0644)
    }

    return &result
}

func runGoProgram(file string) Result {
    pid := os.Getpid()
    exec_file := fmt.Sprintf("/tmp/prog-%d", pid)
    compile_file := fmt.Sprintf("%s-compiled.o", exec_file)
    compiled := run("go", "tool", "compile", "-o", compile_file, file)
    run("rm", compile_file) // cleanup unneeded file

    if compiled.success() {
        run("go", "build", "-o", exec_file, file)
        result := run(exec_file)

        run("rm", exec_file) // cleanup unneeded file
        return result
    } else {
        return compiled
    }
}

func run(exe string, args ...string) Result {
    var exit_code int
    cmd := exec.Command(exe, args...)
    cmdOutput := &bytes.Buffer{}
    cmd.Stdout = cmdOutput
    cmd.Stderr = cmdOutput

    if err := cmd.Run(); err != nil {
        //if err != nil {
        //    os.Stderr.WriteString(fmt.Sprintf("Error: %s\n", err.Error()))
        //}
        if exitError, ok := err.(*exec.ExitError); ok {
            exit_code = exitError.Sys().(syscall.WaitStatus).ExitStatus()
        }
    } else {
        // Success
        exit_code = cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
    }

    return Result{
        exit_code,
        string(cmdOutput.Bytes()),
    }
}<commit_msg>use os.remove instead of calling the rm shell command<commit_after>package runtime

import (
    "crypto/sha1"
    "io"
    "fmt"
    "os/exec"
    "bytes"
    "syscall"
    "os"
    "io/ioutil"
    "log"
)

func RunCode(code string) (*Result) {
    h := sha1.New()
    io.WriteString(h, code)
    sha := fmt.Sprintf("%x", h.Sum(nil))

    out_filename := fmt.Sprintf("/tmp/%s.output", sha)
    src_filename := fmt.Sprintf("/tmp/%s.go", sha)
    var b []byte
    var result Result
    var err error

    // read a Result from the file and if no error, try to decode
    if b, err = ioutil.ReadFile(out_filename); err == nil {
        result, err = decodeResults(b)
    }

    // if there was an error, compile and run the code again
    if err != nil {
        log.Println("Compiling and running code")
        err := ioutil.WriteFile(src_filename, []byte(code), 0644)
        defer os.Remove(src_filename)
        if err != nil {
            panic(err)
        }
        result = runGoProgram(src_filename)
        ioutil.WriteFile(out_filename, result.encode(), 0644)
    }

    return &result
}

func runGoProgram(file string) Result {
    pid := os.Getpid()
    exec_file := fmt.Sprintf("/tmp/prog-%d", pid)
    compile_file := fmt.Sprintf("%s-compiled.o", exec_file)
    compiled := run("go", "tool", "compile", "-o", compile_file, file)
    defer os.Remove(compile_file) // cleanup unneeded file

    if compiled.success() {
        run("go", "build", "-o", exec_file, file)
        result := run(exec_file)

        defer os.Remove(exec_file) // cleanup unneeded file
        return result
    } else {
        return compiled
    }
}

func run(exe string, args ...string) Result {
    var exit_code int
    cmd := exec.Command(exe, args...)
    cmdOutput := &bytes.Buffer{}
    cmd.Stdout = cmdOutput
    cmd.Stderr = cmdOutput

    if err := cmd.Run(); err != nil {
        //if err != nil {
        //    os.Stderr.WriteString(fmt.Sprintf("Error: %s\n", err.Error()))
        //}
        if exitError, ok := err.(*exec.ExitError); ok {
            exit_code = exitError.Sys().(syscall.WaitStatus).ExitStatus()
        }
    } else {
        // Success
        exit_code = cmd.ProcessState.Sys().(syscall.WaitStatus).ExitStatus()
    }

    return Result{
        exit_code,
        string(cmdOutput.Bytes()),
    }
}<|endoftext|>


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

// Package flags holds command line options common to all GXUI samples.
package flags

import (
	"flag"
	"github.com/google/gxui"
	"github.com/google/gxui/themes/dark"
	"github.com/google/gxui/themes/light"
)

var DefaultScaleFactor float32
var FlagTheme string

func init() {
	flagTheme := flag.String("theme", "dark", "Theme to use {dark|light}.")
	defaultScaleFactor := flag.Float64("scaling", 1.0, "Adjusts the scaling of UI rendering")
	//flag.Parse()

	DefaultScaleFactor = float32(*defaultScaleFactor)
	FlagTheme = *flagTheme
}

// CreateTheme creates and returns the theme specified on the command line.
// The default theme is dark.
func CreateTheme(driver gxui.Driver) gxui.Theme {
	if FlagTheme == "light" {
		return light.CreateTheme(driver)
	}
	return dark.CreateTheme(driver)
}
<commit_msg>Avoid parsing gxui flags on init<commit_after>// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package flags holds command line options common to all GXUI samples.
package flags

import (
	"github.com/google/gxui"
	"github.com/google/gxui/themes/dark"
	"github.com/google/gxui/themes/light"
)

var DefaultScaleFactor float32
var FlagTheme string

func init() {
	DefaultScaleFactor = 1.0
	FlagTheme = "light"
}

// CreateTheme creates and returns the theme specified on the command line.
// The default theme is dark.
func CreateTheme(driver gxui.Driver) gxui.Theme {
	if FlagTheme == "light" {
		return light.CreateTheme(driver)
	}
	return dark.CreateTheme(driver)
}
<|endoftext|>


<commit_before>package weed_server

import (
	"context"
	"fmt"
	"io"
	"net/http"
	"os"
	"path"
	"strconv"
	"strings"
	"time"

	"github.com/chrislusf/seaweedfs/weed/filer"
	"github.com/chrislusf/seaweedfs/weed/glog"
	"github.com/chrislusf/seaweedfs/weed/operation"
	"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
	xhttp "github.com/chrislusf/seaweedfs/weed/s3api/http"
	"github.com/chrislusf/seaweedfs/weed/stats"
	"github.com/chrislusf/seaweedfs/weed/storage/needle"
	"github.com/chrislusf/seaweedfs/weed/util"
)

func (fs *FilerServer) autoChunk(ctx context.Context, w http.ResponseWriter, r *http.Request, contentLength int64, so *operation.StorageOption) {

	// autoChunking can be set at the command-line level or as a query param. Query param overrides command-line
	query := r.URL.Query()

	parsedMaxMB, _ := strconv.ParseInt(query.Get("maxMB"), 10, 32)
	maxMB := int32(parsedMaxMB)
	if maxMB <= 0 && fs.option.MaxMB > 0 {
		maxMB = int32(fs.option.MaxMB)
	}

	chunkSize := 1024 * 1024 * maxMB

	stats.FilerRequestCounter.WithLabelValues("chunk").Inc()
	start := time.Now()
	defer func() {
		stats.FilerRequestHistogram.WithLabelValues("chunk").Observe(time.Since(start).Seconds())
	}()

	var reply *FilerPostResult
	var err error
	var md5bytes []byte
	if r.Method == "POST" {
		if r.Header.Get("Content-Type") == "" && strings.HasSuffix(r.URL.Path, "/") {
			reply, err = fs.mkdir(ctx, w, r)
		} else {
			reply, md5bytes, err = fs.doPostAutoChunk(ctx, w, r, chunkSize, contentLength, so)
		}
	} else {
		reply, md5bytes, err = fs.doPutAutoChunk(ctx, w, r, chunkSize, contentLength, so)
	}
	if err != nil {
		if strings.HasPrefix(err.Error(), "read input:") {
			writeJsonError(w, r, 499, err)
		} else if strings.HasSuffix(err.Error(), "is a file") {
			writeJsonError(w, r, http.StatusConflict, err)
		} else {
			writeJsonError(w, r, http.StatusInternalServerError, err)
		}
	} else if reply != nil {
		if len(md5bytes) > 0 {
			md5InBase64 := util.Base64Encode(md5bytes)
			w.Header().Set("Content-MD5", md5InBase64)
		}
		writeJsonQuiet(w, r, http.StatusCreated, reply)
	}
}

func (fs *FilerServer) doPostAutoChunk(ctx context.Context, w http.ResponseWriter, r *http.Request, chunkSize int32, contentLength int64, so *operation.StorageOption) (filerResult *FilerPostResult, md5bytes []byte, replyerr error) {

	multipartReader, multipartReaderErr := r.MultipartReader()
	if multipartReaderErr != nil {
		return nil, nil, multipartReaderErr
	}

	part1, part1Err := multipartReader.NextPart()
	if part1Err != nil {
		return nil, nil, part1Err
	}

	fileName := part1.FileName()
	if fileName != "" {
		fileName = path.Base(fileName)
	}
	contentType := part1.Header.Get("Content-Type")
	if contentType == "application/octet-stream" {
		contentType = ""
	}

	fileChunks, md5Hash, chunkOffset, err, smallContent := fs.uploadReaderToChunks(w, r, part1, chunkSize, fileName, contentType, contentLength, so)
	if err != nil {
		return nil, nil, err
	}

	md5bytes = md5Hash.Sum(nil)
	filerResult, replyerr = fs.saveMetaData(ctx, r, fileName, contentType, so, md5bytes, fileChunks, chunkOffset, smallContent)
	if replyerr != nil {
		fs.filer.DeleteChunks(fileChunks)
	}

	return
}

func (fs *FilerServer) doPutAutoChunk(ctx context.Context, w http.ResponseWriter, r *http.Request, chunkSize int32, contentLength int64, so *operation.StorageOption) (filerResult *FilerPostResult, md5bytes []byte, replyerr error) {

	fileName := path.Base(r.URL.Path)
	contentType := r.Header.Get("Content-Type")
	if contentType == "application/octet-stream" {
		contentType = ""
	}

	fileChunks, md5Hash, chunkOffset, err, smallContent := fs.uploadReaderToChunks(w, r, r.Body, chunkSize, fileName, contentType, contentLength, so)
	if err != nil {
		return nil, nil, err
	}

	md5bytes = md5Hash.Sum(nil)
	filerResult, replyerr = fs.saveMetaData(ctx, r, fileName, contentType, so, md5bytes, fileChunks, chunkOffset, smallContent)
	if replyerr != nil {
		fs.filer.DeleteChunks(fileChunks)
	}

	return
}

func isAppend(r *http.Request) bool {
	return r.URL.Query().Get("op") == "append"
}

func skipCheckParentDirEntry(r *http.Request) bool {
	return r.URL.Query().Get("skipCheckParentDir") != "true"
}

func (fs *FilerServer) saveMetaData(ctx context.Context, r *http.Request, fileName string, contentType string, so *operation.StorageOption, md5bytes []byte, fileChunks []*filer_pb.FileChunk, chunkOffset int64, content []byte) (filerResult *FilerPostResult, replyerr error) {

	// detect file mode
	modeStr := r.URL.Query().Get("mode")
	if modeStr == "" {
		modeStr = "0660"
	}
	mode, err := strconv.ParseUint(modeStr, 8, 32)
	if err != nil {
		glog.Errorf("Invalid mode format: %s, use 0660 by default", modeStr)
		mode = 0660
	}

	// fix the path
	path := r.URL.Path
	if strings.HasSuffix(path, "/") {
		if fileName != "" {
			path += fileName
		}
	} else {
		if fileName != "" {
			if possibleDirEntry, findDirErr := fs.filer.FindEntry(ctx, util.FullPath(path)); findDirErr == nil {
				if possibleDirEntry.IsDirectory() {
					path += "/" + fileName
				}
			}
		}
	}

	var entry *filer.Entry
	var mergedChunks []*filer_pb.FileChunk

	isAppend := isAppend(r)
	isOffsetWrite := len(fileChunks) > 0 && fileChunks[0].Offset > 0
	// when it is an append
	if isAppend || isOffsetWrite {
		existingEntry, findErr := fs.filer.FindEntry(ctx, util.FullPath(path))
		if findErr != nil && findErr != filer_pb.ErrNotFound {
			glog.V(0).Infof("failing to find %s: %v", path, findErr)
		}
		entry = existingEntry
	}
	if entry != nil {
		entry.Mtime = time.Now()
		entry.Md5 = nil
		// adjust chunk offsets
		if isAppend {
			for _, chunk := range fileChunks {
				chunk.Offset += int64(entry.FileSize)
			}
			entry.FileSize += uint64(chunkOffset)
		}
		mergedChunks = append(entry.Chunks, fileChunks...)

		// TODO
		if len(entry.Content) > 0 {
			replyerr = fmt.Errorf("append to small file is not supported yet")
			return
		}

	} else {
		glog.V(4).Infoln("saving", path)
		mergedChunks = fileChunks
		entry = &filer.Entry{
			FullPath: util.FullPath(path),
			Attr: filer.Attr{
				Mtime:       time.Now(),
				Crtime:      time.Now(),
				Mode:        os.FileMode(mode),
				Uid:         OS_UID,
				Gid:         OS_GID,
				Replication: so.Replication,
				Collection:  so.Collection,
				TtlSec:      so.TtlSeconds,
				DiskType:    so.DiskType,
				Mime:        contentType,
				Md5:         md5bytes,
				FileSize:    uint64(chunkOffset),
			},
			Content: content,
		}
	}

	// maybe compact entry chunks
	mergedChunks, replyerr = filer.MaybeManifestize(fs.saveAsChunk(so), mergedChunks)
	if replyerr != nil {
		glog.V(0).Infof("manifestize %s: %v", r.RequestURI, replyerr)
		return
	}
	entry.Chunks = mergedChunks
	if isOffsetWrite {
		entry.Md5 = nil
		entry.FileSize = entry.Size()
	}

	filerResult = &FilerPostResult{
		Name: fileName,
		Size: int64(entry.FileSize),
	}

	entry.Extended = SaveAmzMetaData(r, entry.Extended, false)

	for k, v := range r.Header {
		if len(v) > 0 && len(v[0]) > 0 {
			if strings.HasPrefix(k, needle.PairNamePrefix) || k == "Cache-Control" || k == "Expires" || k == "Content-Disposition" {
				entry.Extended[k] = []byte(v[0])
			}
			if k == "Response-Content-Disposition" {
				entry.Extended["Content-Disposition"] = []byte(v[0])
			}
		}
	}

	if dbErr := fs.filer.CreateEntry(ctx, entry, false, false, nil, skipCheckParentDirEntry(r)); dbErr != nil {
		replyerr = dbErr
		filerResult.Error = dbErr.Error()
		glog.V(0).Infof("failing to write %s to filer server : %v", path, dbErr)
	}
	return filerResult, replyerr
}

func (fs *FilerServer) saveAsChunk(so *operation.StorageOption) filer.SaveDataAsChunkFunctionType {

	return func(reader io.Reader, name string, offset int64) (*filer_pb.FileChunk, string, string, error) {
		// assign one file id for one chunk
		fileId, urlLocation, auth, assignErr := fs.assignNewFileInfo(so)
		if assignErr != nil {
			return nil, "", "", assignErr
		}

		// upload the chunk to the volume server
		uploadOption := &operation.UploadOption{
			UploadUrl:         urlLocation,
			Filename:          name,
			Cipher:            fs.option.Cipher,
			IsInputCompressed: false,
			MimeType:          "",
			PairMap:           nil,
			Jwt:               auth,
		}
		uploadResult, uploadErr, _ := operation.Upload(reader, uploadOption)
		if uploadErr != nil {
			return nil, "", "", uploadErr
		}

		return uploadResult.ToPbFileChunk(fileId, offset), so.Collection, so.Replication, nil
	}
}

func (fs *FilerServer) mkdir(ctx context.Context, w http.ResponseWriter, r *http.Request) (filerResult *FilerPostResult, replyerr error) {

	// detect file mode
	modeStr := r.URL.Query().Get("mode")
	if modeStr == "" {
		modeStr = "0660"
	}
	mode, err := strconv.ParseUint(modeStr, 8, 32)
	if err != nil {
		glog.Errorf("Invalid mode format: %s, use 0660 by default", modeStr)
		mode = 0660
	}

	// fix the path
	path := r.URL.Path
	if strings.HasSuffix(path, "/") {
		path = path[:len(path)-1]
	}

	existingEntry, err := fs.filer.FindEntry(ctx, util.FullPath(path))
	if err == nil && existingEntry != nil {
		replyerr = fmt.Errorf("dir %s already exists", path)
		return
	}

	glog.V(4).Infoln("mkdir", path)
	entry := &filer.Entry{
		FullPath: util.FullPath(path),
		Attr: filer.Attr{
			Mtime:  time.Now(),
			Crtime: time.Now(),
			Mode:   os.FileMode(mode) | os.ModeDir,
			Uid:    OS_UID,
			Gid:    OS_GID,
		},
	}

	filerResult = &FilerPostResult{
		Name: util.FullPath(path).Name(),
	}

	if dbErr := fs.filer.CreateEntry(ctx, entry, false, false, nil, false); dbErr != nil {
		replyerr = dbErr
		filerResult.Error = dbErr.Error()
		glog.V(0).Infof("failing to create dir %s on filer server : %v", path, dbErr)
	}
	return filerResult, replyerr
}

func SaveAmzMetaData(r *http.Request, existing map[string][]byte, isReplace bool) (metadata map[string][]byte) {

	metadata = make(map[string][]byte)
	if !isReplace {
		for k, v := range existing {
			metadata[k] = v
		}
	}

	if sc := r.Header.Get(xhttp.AmzStorageClass); sc != "" {
		metadata[xhttp.AmzStorageClass] = []byte(sc)
	}

	if tags := r.Header.Get(xhttp.AmzObjectTagging); tags != "" {
		for _, v := range strings.Split(tags, "&") {
			tag := strings.Split(v, "=")
			if len(tag) == 2 {
				metadata[xhttp.AmzObjectTagging+"-"+tag[0]] = []byte(tag[1])
			} else if len(tag) == 1 {
				metadata[xhttp.AmzObjectTagging+"-"+tag[0]] = nil
			}
		}
	}

	for header, values := range r.Header {
		if strings.HasPrefix(header, xhttp.AmzUserMetaPrefix) {
			for _, value := range values {
				metadata[header] = []byte(value)
			}
		}
	}

	return

}
<commit_msg>fix-filer: calculation error of the method skipCheckParentDirEntry<commit_after>package weed_server

import (
	"context"
	"fmt"
	"io"
	"net/http"
	"os"
	"path"
	"strconv"
	"strings"
	"time"

	"github.com/chrislusf/seaweedfs/weed/filer"
	"github.com/chrislusf/seaweedfs/weed/glog"
	"github.com/chrislusf/seaweedfs/weed/operation"
	"github.com/chrislusf/seaweedfs/weed/pb/filer_pb"
	xhttp "github.com/chrislusf/seaweedfs/weed/s3api/http"
	"github.com/chrislusf/seaweedfs/weed/stats"
	"github.com/chrislusf/seaweedfs/weed/storage/needle"
	"github.com/chrislusf/seaweedfs/weed/util"
)

func (fs *FilerServer) autoChunk(ctx context.Context, w http.ResponseWriter, r *http.Request, contentLength int64, so *operation.StorageOption) {

	// autoChunking can be set at the command-line level or as a query param. Query param overrides command-line
	query := r.URL.Query()

	parsedMaxMB, _ := strconv.ParseInt(query.Get("maxMB"), 10, 32)
	maxMB := int32(parsedMaxMB)
	if maxMB <= 0 && fs.option.MaxMB > 0 {
		maxMB = int32(fs.option.MaxMB)
	}

	chunkSize := 1024 * 1024 * maxMB

	stats.FilerRequestCounter.WithLabelValues("chunk").Inc()
	start := time.Now()
	defer func() {
		stats.FilerRequestHistogram.WithLabelValues("chunk").Observe(time.Since(start).Seconds())
	}()

	var reply *FilerPostResult
	var err error
	var md5bytes []byte
	if r.Method == "POST" {
		if r.Header.Get("Content-Type") == "" && strings.HasSuffix(r.URL.Path, "/") {
			reply, err = fs.mkdir(ctx, w, r)
		} else {
			reply, md5bytes, err = fs.doPostAutoChunk(ctx, w, r, chunkSize, contentLength, so)
		}
	} else {
		reply, md5bytes, err = fs.doPutAutoChunk(ctx, w, r, chunkSize, contentLength, so)
	}
	if err != nil {
		if strings.HasPrefix(err.Error(), "read input:") {
			writeJsonError(w, r, 499, err)
		} else if strings.HasSuffix(err.Error(), "is a file") {
			writeJsonError(w, r, http.StatusConflict, err)
		} else {
			writeJsonError(w, r, http.StatusInternalServerError, err)
		}
	} else if reply != nil {
		if len(md5bytes) > 0 {
			md5InBase64 := util.Base64Encode(md5bytes)
			w.Header().Set("Content-MD5", md5InBase64)
		}
		writeJsonQuiet(w, r, http.StatusCreated, reply)
	}
}

func (fs *FilerServer) doPostAutoChunk(ctx context.Context, w http.ResponseWriter, r *http.Request, chunkSize int32, contentLength int64, so *operation.StorageOption) (filerResult *FilerPostResult, md5bytes []byte, replyerr error) {

	multipartReader, multipartReaderErr := r.MultipartReader()
	if multipartReaderErr != nil {
		return nil, nil, multipartReaderErr
	}

	part1, part1Err := multipartReader.NextPart()
	if part1Err != nil {
		return nil, nil, part1Err
	}

	fileName := part1.FileName()
	if fileName != "" {
		fileName = path.Base(fileName)
	}
	contentType := part1.Header.Get("Content-Type")
	if contentType == "application/octet-stream" {
		contentType = ""
	}

	fileChunks, md5Hash, chunkOffset, err, smallContent := fs.uploadReaderToChunks(w, r, part1, chunkSize, fileName, contentType, contentLength, so)
	if err != nil {
		return nil, nil, err
	}

	md5bytes = md5Hash.Sum(nil)
	filerResult, replyerr = fs.saveMetaData(ctx, r, fileName, contentType, so, md5bytes, fileChunks, chunkOffset, smallContent)
	if replyerr != nil {
		fs.filer.DeleteChunks(fileChunks)
	}

	return
}

func (fs *FilerServer) doPutAutoChunk(ctx context.Context, w http.ResponseWriter, r *http.Request, chunkSize int32, contentLength int64, so *operation.StorageOption) (filerResult *FilerPostResult, md5bytes []byte, replyerr error) {

	fileName := path.Base(r.URL.Path)
	contentType := r.Header.Get("Content-Type")
	if contentType == "application/octet-stream" {
		contentType = ""
	}

	fileChunks, md5Hash, chunkOffset, err, smallContent := fs.uploadReaderToChunks(w, r, r.Body, chunkSize, fileName, contentType, contentLength, so)
	if err != nil {
		return nil, nil, err
	}

	md5bytes = md5Hash.Sum(nil)
	filerResult, replyerr = fs.saveMetaData(ctx, r, fileName, contentType, so, md5bytes, fileChunks, chunkOffset, smallContent)
	if replyerr != nil {
		fs.filer.DeleteChunks(fileChunks)
	}

	return
}

func isAppend(r *http.Request) bool {
	return r.URL.Query().Get("op") == "append"
}

func skipCheckParentDirEntry(r *http.Request) bool {
	return r.URL.Query().Get("skipCheckParentDir") == "true"
}

func (fs *FilerServer) saveMetaData(ctx context.Context, r *http.Request, fileName string, contentType string, so *operation.StorageOption, md5bytes []byte, fileChunks []*filer_pb.FileChunk, chunkOffset int64, content []byte) (filerResult *FilerPostResult, replyerr error) {

	// detect file mode
	modeStr := r.URL.Query().Get("mode")
	if modeStr == "" {
		modeStr = "0660"
	}
	mode, err := strconv.ParseUint(modeStr, 8, 32)
	if err != nil {
		glog.Errorf("Invalid mode format: %s, use 0660 by default", modeStr)
		mode = 0660
	}

	// fix the path
	path := r.URL.Path
	if strings.HasSuffix(path, "/") {
		if fileName != "" {
			path += fileName
		}
	} else {
		if fileName != "" {
			if possibleDirEntry, findDirErr := fs.filer.FindEntry(ctx, util.FullPath(path)); findDirErr == nil {
				if possibleDirEntry.IsDirectory() {
					path += "/" + fileName
				}
			}
		}
	}

	var entry *filer.Entry
	var mergedChunks []*filer_pb.FileChunk

	isAppend := isAppend(r)
	isOffsetWrite := len(fileChunks) > 0 && fileChunks[0].Offset > 0
	// when it is an append
	if isAppend || isOffsetWrite {
		existingEntry, findErr := fs.filer.FindEntry(ctx, util.FullPath(path))
		if findErr != nil && findErr != filer_pb.ErrNotFound {
			glog.V(0).Infof("failing to find %s: %v", path, findErr)
		}
		entry = existingEntry
	}
	if entry != nil {
		entry.Mtime = time.Now()
		entry.Md5 = nil
		// adjust chunk offsets
		if isAppend {
			for _, chunk := range fileChunks {
				chunk.Offset += int64(entry.FileSize)
			}
			entry.FileSize += uint64(chunkOffset)
		}
		mergedChunks = append(entry.Chunks, fileChunks...)

		// TODO
		if len(entry.Content) > 0 {
			replyerr = fmt.Errorf("append to small file is not supported yet")
			return
		}

	} else {
		glog.V(4).Infoln("saving", path)
		mergedChunks = fileChunks
		entry = &filer.Entry{
			FullPath: util.FullPath(path),
			Attr: filer.Attr{
				Mtime:       time.Now(),
				Crtime:      time.Now(),
				Mode:        os.FileMode(mode),
				Uid:         OS_UID,
				Gid:         OS_GID,
				Replication: so.Replication,
				Collection:  so.Collection,
				TtlSec:      so.TtlSeconds,
				DiskType:    so.DiskType,
				Mime:        contentType,
				Md5:         md5bytes,
				FileSize:    uint64(chunkOffset),
			},
			Content: content,
		}
	}

	// maybe compact entry chunks
	mergedChunks, replyerr = filer.MaybeManifestize(fs.saveAsChunk(so), mergedChunks)
	if replyerr != nil {
		glog.V(0).Infof("manifestize %s: %v", r.RequestURI, replyerr)
		return
	}
	entry.Chunks = mergedChunks
	if isOffsetWrite {
		entry.Md5 = nil
		entry.FileSize = entry.Size()
	}

	filerResult = &FilerPostResult{
		Name: fileName,
		Size: int64(entry.FileSize),
	}

	entry.Extended = SaveAmzMetaData(r, entry.Extended, false)

	for k, v := range r.Header {
		if len(v) > 0 && len(v[0]) > 0 {
			if strings.HasPrefix(k, needle.PairNamePrefix) || k == "Cache-Control" || k == "Expires" || k == "Content-Disposition" {
				entry.Extended[k] = []byte(v[0])
			}
			if k == "Response-Content-Disposition" {
				entry.Extended["Content-Disposition"] = []byte(v[0])
			}
		}
	}

	if dbErr := fs.filer.CreateEntry(ctx, entry, false, false, nil, skipCheckParentDirEntry(r)); dbErr != nil {
		replyerr = dbErr
		filerResult.Error = dbErr.Error()
		glog.V(0).Infof("failing to write %s to filer server : %v", path, dbErr)
	}
	return filerResult, replyerr
}

func (fs *FilerServer) saveAsChunk(so *operation.StorageOption) filer.SaveDataAsChunkFunctionType {

	return func(reader io.Reader, name string, offset int64) (*filer_pb.FileChunk, string, string, error) {
		// assign one file id for one chunk
		fileId, urlLocation, auth, assignErr := fs.assignNewFileInfo(so)
		if assignErr != nil {
			return nil, "", "", assignErr
		}

		// upload the chunk to the volume server
		uploadOption := &operation.UploadOption{
			UploadUrl:         urlLocation,
			Filename:          name,
			Cipher:            fs.option.Cipher,
			IsInputCompressed: false,
			MimeType:          "",
			PairMap:           nil,
			Jwt:               auth,
		}
		uploadResult, uploadErr, _ := operation.Upload(reader, uploadOption)
		if uploadErr != nil {
			return nil, "", "", uploadErr
		}

		return uploadResult.ToPbFileChunk(fileId, offset), so.Collection, so.Replication, nil
	}
}

func (fs *FilerServer) mkdir(ctx context.Context, w http.ResponseWriter, r *http.Request) (filerResult *FilerPostResult, replyerr error) {

	// detect file mode
	modeStr := r.URL.Query().Get("mode")
	if modeStr == "" {
		modeStr = "0660"
	}
	mode, err := strconv.ParseUint(modeStr, 8, 32)
	if err != nil {
		glog.Errorf("Invalid mode format: %s, use 0660 by default", modeStr)
		mode = 0660
	}

	// fix the path
	path := r.URL.Path
	if strings.HasSuffix(path, "/") {
		path = path[:len(path)-1]
	}

	existingEntry, err := fs.filer.FindEntry(ctx, util.FullPath(path))
	if err == nil && existingEntry != nil {
		replyerr = fmt.Errorf("dir %s already exists", path)
		return
	}

	glog.V(4).Infoln("mkdir", path)
	entry := &filer.Entry{
		FullPath: util.FullPath(path),
		Attr: filer.Attr{
			Mtime:  time.Now(),
			Crtime: time.Now(),
			Mode:   os.FileMode(mode) | os.ModeDir,
			Uid:    OS_UID,
			Gid:    OS_GID,
		},
	}

	filerResult = &FilerPostResult{
		Name: util.FullPath(path).Name(),
	}

	if dbErr := fs.filer.CreateEntry(ctx, entry, false, false, nil, false); dbErr != nil {
		replyerr = dbErr
		filerResult.Error = dbErr.Error()
		glog.V(0).Infof("failing to create dir %s on filer server : %v", path, dbErr)
	}
	return filerResult, replyerr
}

func SaveAmzMetaData(r *http.Request, existing map[string][]byte, isReplace bool) (metadata map[string][]byte) {

	metadata = make(map[string][]byte)
	if !isReplace {
		for k, v := range existing {
			metadata[k] = v
		}
	}

	if sc := r.Header.Get(xhttp.AmzStorageClass); sc != "" {
		metadata[xhttp.AmzStorageClass] = []byte(sc)
	}

	if tags := r.Header.Get(xhttp.AmzObjectTagging); tags != "" {
		for _, v := range strings.Split(tags, "&") {
			tag := strings.Split(v, "=")
			if len(tag) == 2 {
				metadata[xhttp.AmzObjectTagging+"-"+tag[0]] = []byte(tag[1])
			} else if len(tag) == 1 {
				metadata[xhttp.AmzObjectTagging+"-"+tag[0]] = nil
			}
		}
	}

	for header, values := range r.Header {
		if strings.HasPrefix(header, xhttp.AmzUserMetaPrefix) {
			for _, value := range values {
				metadata[header] = []byte(value)
			}
		}
	}

	return

}
<|endoftext|>


<commit_before>package gotypes

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/format"
	"go/parser"
	"go/token"
	"io/ioutil"
	"os"
	"os/exec"
	"regexp"
	"strings"

	_ "golang.org/x/tools/go/gcimporter"
	"golang.org/x/tools/go/ssa"
	"golang.org/x/tools/go/types"
)

// https://github.com/golang/go/issues/11327
var bigNum = regexp.MustCompile("(\\.[0-9]*)|([0-9]+)[eE]\\-?[0-9]{3,}")

// https://github.com/golang/go/issues/11274
var formatBug1 = regexp.MustCompile("\\*/[ \t\n\r\f\v]*;")
var formatBug2 = regexp.MustCompile(";[ \t\n\r\f\v]*/\\*")

var gcCrash = regexp.MustCompile("\n/tmp/fuzz\\.gc[0-9]+:[0-9]+: internal compiler error: ")

func Fuzz(data []byte) int {
	if bigNum.Match(data) {
		return 0
	}
	goErr := gotypes(data)
	gcErr := gc(data)
	if goErr == nil && gcErr != nil && strings.Contains(gcErr.Error(), "line number out of range") {
		// https://github.com/golang/go/issues/11329
		return 0
	}
	if goErr == nil && gcErr != nil && strings.Contains(gcErr.Error(), "stupid shift:") {
		// https://github.com/golang/go/issues/11328
		return 0
	}
	if gcErr == nil && goErr != nil && strings.Contains(goErr.Error(), "untyped float constant") {
		// https://github.com/golang/go/issues/11350
		return 0
	}
	if goErr == nil && gcErr != nil && strings.Contains(gcErr.Error(), "(type float64) to type string") {
		// https://github.com/golang/go/issues/11353
		return 0
	}
	if goErr == nil && gcErr != nil && strings.Contains(gcErr.Error(), "(type complex128) to type string") {
		// https://github.com/golang/go/issues/11357
		return 0
	}
	if goErr == nil && gcErr != nil && strings.Contains(gcErr.Error(), "overflow in int -> string") {
		// https://github.com/golang/go/issues/11330
		return 0
	}
	if gcErr == nil && goErr != nil && strings.Contains(goErr.Error(), "illegal character U+") {
		// https://github.com/golang/go/issues/11359
		return 0
	}
	if goErr == nil && gcErr != nil && strings.Contains(gcErr.Error(), "larger than address space") {
		// Gc is more picky at rejecting huge objects.
		return 0
	}
	if goErr == nil && gcErr != nil && strings.Contains(gcErr.Error(), "non-canonical import path") {
		return 0
	}
	// go-fuzz is too smart so it can generate a program that contains "internal compiler error" in an error message :)
	if gcErr != nil && gcCrash.MatchString(gcErr.Error()) {
		if strings.Contains(gcErr.Error(), "internal compiler error: out of fixed registers") {
			// https://github.com/golang/go/issues/11352
			return 0
		}
		if strings.Contains(gcErr.Error(), "internal compiler error: naddr: bad HMUL") {
			// https://github.com/golang/go/issues/11358
			return 0
		}
		if strings.Contains(gcErr.Error(), "internal compiler error: treecopy Name") {
			// https://github.com/golang/go/issues/11361
			return 0
		}
		fmt.Printf("gc result: %v\n", gcErr)
		panic("gc compiler crashed")
	}
	if (goErr == nil) != (gcErr == nil) {
		fmt.Printf("go/types result: %v\n", goErr)
		fmt.Printf("gc result: %v\n", gcErr)
		panic("gc and go/types disagree")
	}
	if goErr != nil {
		return 0

	}
	if formatBug1.Match(data) || formatBug2.Match(data) {
		return 1
	}
	// https://github.com/golang/go/issues/11274
	data = bytes.Replace(data, []byte{'\r'}, []byte{' '}, -1)
	data1, err := format.Source(data)
	if err != nil {
		panic(err)
	}
	err = gotypes(data1)
	if err != nil {
		fmt.Printf("new: %q\n", data1)
		fmt.Printf("err: %v\n", err)
		panic("program become invalid after gofmt")
	}
	return 1
}

func gotypes(data []byte) (err error) {
	fset := token.NewFileSet()
	var f *ast.File
	f, err = parser.ParseFile(fset, "src.go", data, parser.ParseComments|parser.DeclarationErrors|parser.AllErrors)
	if err != nil {
		return
	}
	_, err = types.Check("pkg", fset, []*ast.File{f})
	if err != nil {
		return
	}
	prog := ssa.NewProgram(fset, ssa.BuildSerially|ssa.SanityCheckFunctions|ssa.GlobalDebug)
	prog.BuildAll()
	for _, pkg := range prog.AllPackages() {
		_, err := pkg.WriteTo(ioutil.Discard)
		if err != nil {
			panic(err)
		}
	}
	return
}

func gc(data []byte) error {
	f, err := ioutil.TempFile("", "fuzz.gc")
	if err != nil {
		return err
	}
	defer os.Remove(f.Name())
	defer f.Close()
	_, err = f.Write(data)
	if err != nil {
		return err
	}
	f.Close()
	out, err := exec.Command("compile", f.Name()).CombinedOutput()
	if err != nil {
		return fmt.Errorf("%s\n%s", out, err)
	}
	return nil
}
<commit_msg>remove fixed bugs from gotypes test<commit_after>package gotypes

import (
	"bytes"
	"fmt"
	"go/ast"
	"go/format"
	"go/parser"
	"go/token"
	"io/ioutil"
	"os"
	"os/exec"
	"regexp"
	"strings"

	_ "golang.org/x/tools/go/gcimporter"
	"golang.org/x/tools/go/ssa"
	"golang.org/x/tools/go/types"
)

// https://github.com/golang/go/issues/11327
var bigNum = regexp.MustCompile("(\\.[0-9]*)|([0-9]+)[eE]\\-?[0-9]{3,}")

// https://github.com/golang/go/issues/11274
var formatBug1 = regexp.MustCompile("\\*/[ \t\n\r\f\v]*;")
var formatBug2 = regexp.MustCompile(";[ \t\n\r\f\v]*/\\*")

var gcCrash = regexp.MustCompile("\n/tmp/fuzz\\.gc[0-9]+:[0-9]+: internal compiler error: ")

func Fuzz(data []byte) int {
	if bigNum.Match(data) {
		return 0
	}
	goErr := gotypes(data)
	gcErr := gc(data)
	if goErr == nil && gcErr != nil && strings.Contains(gcErr.Error(), "line number out of range") {
		// https://github.com/golang/go/issues/11329
		return 0
	}
	if goErr == nil && gcErr != nil && strings.Contains(gcErr.Error(), "stupid shift:") {
		// https://github.com/golang/go/issues/11328
		return 0
	}
	if gcErr == nil && goErr != nil && strings.Contains(goErr.Error(), "untyped float constant") {
		// https://github.com/golang/go/issues/11350
		return 0
	}
	if goErr == nil && gcErr != nil && strings.Contains(gcErr.Error(), "overflow in int -> string") {
		// https://github.com/golang/go/issues/11330
		return 0
	}
	if gcErr == nil && goErr != nil && strings.Contains(goErr.Error(), "illegal character U+") {
		// https://github.com/golang/go/issues/11359
		return 0
	}
	if goErr == nil && gcErr != nil && strings.Contains(gcErr.Error(), "larger than address space") {
		// Gc is more picky at rejecting huge objects.
		return 0
	}
	if goErr == nil && gcErr != nil && strings.Contains(gcErr.Error(), "non-canonical import path") {
		return 0
	}
	// go-fuzz is too smart so it can generate a program that contains "internal compiler error" in an error message :)
	if gcErr != nil && gcCrash.MatchString(gcErr.Error()) {
		if strings.Contains(gcErr.Error(), "internal compiler error: out of fixed registers") {
			// https://github.com/golang/go/issues/11352
			return 0
		}
		if strings.Contains(gcErr.Error(), "internal compiler error: treecopy Name") {
			// https://github.com/golang/go/issues/11361
			return 0
		}
		fmt.Printf("gc result: %v\n", gcErr)
		panic("gc compiler crashed")
	}
	if (goErr == nil) != (gcErr == nil) {
		fmt.Printf("go/types result: %v\n", goErr)
		fmt.Printf("gc result: %v\n", gcErr)
		panic("gc and go/types disagree")
	}
	if goErr != nil {
		return 0

	}
	if formatBug1.Match(data) || formatBug2.Match(data) {
		return 1
	}
	// https://github.com/golang/go/issues/11274
	data = bytes.Replace(data, []byte{'\r'}, []byte{' '}, -1)
	data1, err := format.Source(data)
	if err != nil {
		panic(err)
	}
	err = gotypes(data1)
	if err != nil {
		fmt.Printf("new: %q\n", data1)
		fmt.Printf("err: %v\n", err)
		panic("program become invalid after gofmt")
	}
	return 1
}

func gotypes(data []byte) (err error) {
	fset := token.NewFileSet()
	var f *ast.File
	f, err = parser.ParseFile(fset, "src.go", data, parser.ParseComments|parser.DeclarationErrors|parser.AllErrors)
	if err != nil {
		return
	}
	_, err = types.Check("pkg", fset, []*ast.File{f})
	if err != nil {
		return
	}
	prog := ssa.NewProgram(fset, ssa.BuildSerially|ssa.SanityCheckFunctions|ssa.GlobalDebug)
	prog.BuildAll()
	for _, pkg := range prog.AllPackages() {
		_, err := pkg.WriteTo(ioutil.Discard)
		if err != nil {
			panic(err)
		}
	}
	return
}

func gc(data []byte) error {
	f, err := ioutil.TempFile("", "fuzz.gc")
	if err != nil {
		return err
	}
	defer os.Remove(f.Name())
	defer f.Close()
	_, err = f.Write(data)
	if err != nil {
		return err
	}
	f.Close()
	out, err := exec.Command("compile", f.Name()).CombinedOutput()
	if err != nil {
		return fmt.Errorf("%s\n%s", out, err)
	}
	return nil
}
<|endoftext|>


<commit_before>/**
 * Twist v0.1-dev
 *
 * (c) Harry Lawrence
 *
 * License: MIT
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

package main

import (
    "fmt"
    "../vendor/gocui"
)

func Layout(g *gocui.Gui) error {
    maxX, maxY := g.Size()
    file       := File{name:""}

    if v, err := g.SetView("side", -1, -1, 5, maxY); err != nil {
        if err != gocui.ErrorUnkView {
            return err
        }

        // Hide line numbers for now
        //fmt.Fprintln(v, "- 1")
        fmt.Fprintf(v, "%s", "")
    }

    if (!FilenameIsSet()) {
        if v, err := g.SetView("intro", 5, -1, maxX, maxY); err != nil {
            if err != gocui.ErrorUnkView {
                return err
            }
            fmt.Fprintf(v, "%s", `
                Welcome to Twist v0.1

                To start    : Ctrl+N (new)
                To quit     : Ctrl+C
                Editor Mode : Ctrl+K
                JS Mode     : Ctrl+J
            `)

            if err := g.SetCurrentView("intro"); err != nil {
                return err
            }
        }
    } else {
        if v, err := g.SetView("main", 5, -1, maxX, maxY); err != nil {
            if err != gocui.ErrorUnkView {
                return err
            }

            v.Editable = true

            filename := GetFilenameArg()
            file.SetName(filename)

            fmt.Fprintf(v, "%s", GetFileContents(file.Name()))

            if err := g.SetCurrentView("main"); err != nil {
                return err
            }
        }
    }

    // Set the current file name, defaults as empty string
    g.SetFilename(file.Name())

    if v, err := g.SetView("console", -1, maxY - 2, maxX, maxY); err != nil {
        if err != gocui.ErrorUnkView {
            return err
        }
        fmt.Fprint(v, "jsc >> ")
        v.Editable = true

        cx, cy := v.Cursor()
        if err := v.SetCursor(cx + 7, cy); err != nil {
            ox, oy := v.Origin()
            if err := v.SetOrigin(ox + 7, oy); err != nil {
                return err
            }
        }

    }
    return nil
}
<commit_msg>Removed old comment for line numbers<commit_after>/**
 * Twist v0.1-dev
 *
 * (c) Harry Lawrence
 *
 * License: MIT
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

package main

import (
    "fmt"
    "../vendor/gocui"
)

func Layout(g *gocui.Gui) error {
    maxX, maxY := g.Size()
    file       := File{name:""}

    if v, err := g.SetView("side", -1, -1, 5, maxY); err != nil {
        if err != gocui.ErrorUnkView {
            return err
        }

        fmt.Fprintf(v, "%s", "")
    }

    if (!FilenameIsSet()) {
        if v, err := g.SetView("intro", 5, -1, maxX, maxY); err != nil {
            if err != gocui.ErrorUnkView {
                return err
            }
            fmt.Fprintf(v, "%s", `
                Welcome to Twist v0.1

                To start    : Ctrl+N (new)
                To quit     : Ctrl+C
                Editor Mode : Ctrl+K
                JS Mode     : Ctrl+J
            `)

            if err := g.SetCurrentView("intro"); err != nil {
                return err
            }
        }
    } else {
        if v, err := g.SetView("main", 5, -1, maxX, maxY); err != nil {
            if err != gocui.ErrorUnkView {
                return err
            }

            v.Editable = true

            filename := GetFilenameArg()
            file.SetName(filename)

            fmt.Fprintf(v, "%s", GetFileContents(file.Name()))

            if err := g.SetCurrentView("main"); err != nil {
                return err
            }
        }
    }

    // Set the current file name, defaults as empty string
    g.SetFilename(file.Name())

    if v, err := g.SetView("console", -1, maxY - 2, maxX, maxY); err != nil {
        if err != gocui.ErrorUnkView {
            return err
        }
        fmt.Fprint(v, "jsc >> ")
        v.Editable = true

        cx, cy := v.Cursor()
        if err := v.SetCursor(cx + 7, cy); err != nil {
            ox, oy := v.Origin()
            if err := v.SetOrigin(ox + 7, oy); err != nil {
                return err
            }
        }

    }
    return nil
}
<|endoftext|>


<commit_before>package expreduce

import "fmt"

type allocIterState struct {
	currForm int
	remaining int
	currFormI int
}

type allocIter struct {
	forms []parsedForm
	alloc []int
	stack []allocIterState
}

// Returns if should continue, result is stored in ai.alloc.
func (ai *allocIter) next() bool {
	for len(ai.stack) > 0 {
		var p allocIterState
		l := len(ai.stack)
		ai.stack, p = ai.stack[:l-1], ai.stack[l-1]
		if p.currForm-1 >= 0 {
			ai.alloc[p.currForm-1] = p.currFormI
		}
		if p.currForm >= len(ai.forms) {
			return true
		}
		// If we are on the last form, we can check directly if the last form
		// can accomodate the remaining components.
		if p.currForm+1 >= len(ai.forms) {
			if (ai.forms[p.currForm].startI <= p.remaining) && (p.remaining <= ai.forms[p.currForm].endI) {
				ai.stack = append(ai.stack, allocIterState{
				p.currForm+1, 0, p.remaining})
			}
		} else {
			for i := Min(ai.forms[p.currForm].endI, p.remaining); i >= ai.forms[p.currForm].startI; i-- {
				if p.remaining-i >= 0 {
					ai.stack = append(ai.stack, allocIterState{
					p.currForm+1, p.remaining-i, i})
				}
			}
		}
	}
	return false
}

func NewAllocIter(l int, forms []parsedForm) allocIter {
	ai := allocIter{}
	ai.forms = forms
	ai.alloc = make([]int, len(forms))
	ai.stack = []allocIterState{
		allocIterState{0, l, 0},
	}
	return ai
}

type assnIterState struct {
	form int
	formPart int
	lastTaken int
}

type assnIter struct {
	forms []parsedForm
	assnData []int
	assns [][]int
	orderless bool
	taken []bool
	stack []assnIterState
}

func (asi *assnIter) pOrderless(lastTaken int, formDataI int, crossedBoundary bool) {
	if formDataI > 0 {
		asi.taken[lastTaken] = true
		asi.assnData[formDataI-1] = lastTaken
	}
	if formDataI >= len(asi.assnData) {
		fmt.Println(asi.assns)
	} else {
		// Determine if we crossed an allocation boundary.
		totComps := 0
		for i := 0; i < len(asi.assns) && totComps < formDataI+1; i++ {
			totComps += len(asi.assns[i])
		}
		willCrossBoundary := formDataI+1 == totComps

		startI := lastTaken+1
		if crossedBoundary {
			startI = 0
		}
		for i := startI; i < len(asi.taken); i++ {
			if !asi.taken[i] {
				asi.pOrderless(i, formDataI+1, willCrossBoundary)
			}
		}
	}
	if formDataI > 0 {
		asi.taken[lastTaken] = false
	}
}

func (asi *assnIter) p() {
	ai := NewAllocIter(len(asi.assnData), asi.forms)
	for i := range asi.assnData {
		asi.assnData[i] = i
	}
	for ai.next() {
		// Create slices against assnData.
		lasti := 0
		for i := range asi.assns {
			asi.assns[i] = asi.assnData[lasti:lasti+ai.alloc[i]]
			lasti += ai.alloc[i]
		}
		if !asi.orderless {
			fmt.Println(ai.alloc)
			fmt.Println(asi.assns)
		} else {
			asi.pOrderless(-1, 0, true)
		}
	}
}

func NewAssnIter(l int, forms []parsedForm, orderless bool) assnIter {
	asi := assnIter{}
	asi.forms = forms
	asi.assnData = make([]int, l)
	asi.assns = make([][]int, len(forms))
	asi.orderless = orderless
	asi.taken = make([]bool, l)
	return asi
}
<commit_msg>Simplify state.<commit_after>package expreduce

import "fmt"

type allocIterState struct {
	currForm int
	remaining int
	currFormI int
}

type allocIter struct {
	forms []parsedForm
	alloc []int
	stack []allocIterState
}

// Returns if should continue, result is stored in ai.alloc.
func (ai *allocIter) next() bool {
	for len(ai.stack) > 0 {
		var p allocIterState
		l := len(ai.stack)
		ai.stack, p = ai.stack[:l-1], ai.stack[l-1]
		if p.currForm-1 >= 0 {
			ai.alloc[p.currForm-1] = p.currFormI
		}
		if p.currForm >= len(ai.forms) {
			return true
		}
		// If we are on the last form, we can check directly if the last form
		// can accomodate the remaining components.
		if p.currForm+1 >= len(ai.forms) {
			if (ai.forms[p.currForm].startI <= p.remaining) && (p.remaining <= ai.forms[p.currForm].endI) {
				ai.stack = append(ai.stack, allocIterState{
				p.currForm+1, 0, p.remaining})
			}
		} else {
			for i := Min(ai.forms[p.currForm].endI, p.remaining); i >= ai.forms[p.currForm].startI; i-- {
				if p.remaining-i >= 0 {
					ai.stack = append(ai.stack, allocIterState{
					p.currForm+1, p.remaining-i, i})
				}
			}
		}
	}
	return false
}

func NewAllocIter(l int, forms []parsedForm) allocIter {
	ai := allocIter{}
	ai.forms = forms
	ai.alloc = make([]int, len(forms))
	ai.stack = []allocIterState{
		allocIterState{0, l, 0},
	}
	return ai
}

type assnIterState struct {
	lastTaken int
	formDataI int
	crossedBoundary bool
}

type assnIter struct {
	forms []parsedForm
	assnData []int
	assns [][]int
	orderless bool
	taken []bool
	stack []assnIterState
}

func (asi *assnIter) pOrderless(lastTaken int, formDataI int, crossedBoundary bool, toFree int) {
	if toFree > -1 {
		asi.taken[toFree] = false
		return
	}
	if formDataI > 0 {
		asi.taken[lastTaken] = true
		asi.assnData[formDataI-1] = lastTaken
	}
	if formDataI >= len(asi.assnData) {
		if formDataI > 0 {
			asi.pOrderless(-1, 0, true, lastTaken)
		}
		fmt.Println(asi.assns)
	} else {
		// Determine if we crossed an allocation boundary.
		totComps := 0
		for i := 0; i < len(asi.assns) && totComps < formDataI+1; i++ {
			totComps += len(asi.assns[i])
		}
		willCrossBoundary := formDataI+1 == totComps

		startI := lastTaken+1
		if crossedBoundary {
			startI = 0
		}
		for i := startI; i < len(asi.taken); i++ {
			if !asi.taken[i] {
				asi.pOrderless(i, formDataI+1, willCrossBoundary, -1)
			}
		}
		if formDataI > 0 {
			asi.pOrderless(-1, 0, true, lastTaken)
		}
	}
}

func (asi *assnIter) p() {
	ai := NewAllocIter(len(asi.assnData), asi.forms)
	for i := range asi.assnData {
		asi.assnData[i] = i
	}
	for ai.next() {
		// Create slices against assnData.
		lasti := 0
		for i := range asi.assns {
			asi.assns[i] = asi.assnData[lasti:lasti+ai.alloc[i]]
			lasti += ai.alloc[i]
		}
		if !asi.orderless {
			fmt.Println(ai.alloc)
			fmt.Println(asi.assns)
		} else {
			asi.pOrderless(-1, 0, true, -1)
		}
	}
}

func NewAssnIter(l int, forms []parsedForm, orderless bool) assnIter {
	asi := assnIter{}
	asi.forms = forms
	asi.assnData = make([]int, l)
	asi.assns = make([][]int, len(forms))
	asi.orderless = orderless
	asi.taken = make([]bool, l)
	return asi
}
<|endoftext|>


<commit_before>package dtrace

import (
	"fmt"
	"runtime"

	"github.com/sirupsen/logrus"
)

// Printf writes a debug entry to the log
func Printf(format string, args ...interface{}) {
	var (
		function, file string
		line           int
	)
	pc, _, _, ok := runtime.Caller(1)
	if ok {
		pcs := []uintptr{pc}
		frames := runtime.CallersFrames(pcs)
		frame, _ := frames.Next()
		function = frame.Function
		file = frame.File
		line = frame.Line
	}

	logrus.Debugf(fmt.Sprintf("%s (@%s.%s, %v)", format, function, file, line), args...)
}
<commit_msg>Fix: Improved readability of dtrace output<commit_after>package dtrace

import (
	"fmt"
	"path/filepath"
	"runtime"

	"github.com/sirupsen/logrus"
)

// Printf writes a debug entry to the log
func Printf(format string, args ...interface{}) {
	var (
		function, file string
		line           int
	)
	pc, _, _, ok := runtime.Caller(1)
	if ok {
		pcs := []uintptr{pc}
		frames := runtime.CallersFrames(pcs)
		frame, _ := frames.Next()
		function = frame.Function
		file = filepath.Base(frame.File)
		line = frame.Line
	}

	logrus.Debugf(fmt.Sprintf("%s (@%s %s,%v)", format, function, file, line), args...)
}
<|endoftext|>


<commit_before>package pushover

import (
	"github.com/TIBCOSoftware/flogo-lib/flow/activity"
	"github.com/op/go-logging"
	"github.com/toorop/pushover"
	"time"
)

// log is the default package logger
var log = logging.MustGetLogger("activity-pushover")

const (
	ivUserKey = "userKey"
	ivAuthToken = "authToken"
	ivMessage = "message"
	ivMessageTitle = "messageTitle"
	ivDevice = "device"
	ivSound = "sound"
	ivURL = "url"
	ivURLTitle = "urlTitle"
	ivPriority = "priority"
	ovStatus = "status"
)

// MyActivity is a stub for your Activity implementation
type PushoverActivity struct {
	metadata *activity.Metadata
}

// init create & register activity
func init() {
	md := activity.NewMetadata(jsonMetadata)
	activity.Register(&PushoverActivity{metadata: md})
}

// Metadata implements activity.Activity.Metadata
func (a *PushoverActivity) Metadata() *activity.Metadata {
	return a.metadata
}

// Eval implements activity.Activity.Eval
func (a *PushoverActivity) Eval(context activity.Context) (done bool, err error) {

	userKey := context.GetInput(ivUserKey)
	authToken := context.GetInput(ivAuthToken)
	message := context.GetInput(ivMessage)
	messageTitle := context.GetInput(ivMessageTitle)
	device := context.GetInput(ivDevice)
	sound := context.GetInput(ivSound)
	url := context.GetInput(ivURL)
	urlTitle := context.GetInput(ivURLTitle)

	// Check if mandatory credentials are set in config
	if userKey == nil || authToken == nil {
		log.Error("Missing Pushover Credentials")
		err := activity.NewError("Credential Config not specified")
		return false, err
	}

	// Check if there is a message to send
	if message == nil {
		log.Error("No Message to Send")
		context.SetOutput(ovStatus, "NO_MSG")
		return true, nil
	}

	// Now let's try to connect
	po, err := pushover.NewPushover(authToken.(string), userKey.(string))
	if err != nil {
		log.Error("PushOver Connection Error : ", err)
		context.SetOutput(ovStatus, "CONNECT_ERR")
		return true, nil
	}

	m := pushover.Message{}

	m.Message = message.(string)
	if context.GetInput(ivPriority) != nil {
		m.Priority = context.GetInput(ivPriority).(int)
	} else {
		m.Priority = 0;
	}
	if messageTitle != nil {
		m.Title = messageTitle.(string)
	}
	if device != nil {
		m.Device = device.(string)
	}
	if url != nil {
		m.Url = url.(string)
	}
	if urlTitle != nil {
		m.UrlTitle = urlTitle.(string)
	}
	m.Timestamp = time.Now().Unix()
	if sound != nil {
		m.Sound = sound.(string)
	}

	if preq, presp, err := po.Push(&m); err != nil {
		log.Error("Push Message Error : ", err)
		log.Error("Sent : ", preq)
		log.Error("Received : ", presp)
		context.SetOutput(ovStatus, "PUSH_ERR")
		return true, nil
	}

	context.SetOutput(ovStatus, "OK")

	return true, nil
}
<commit_msg>temporary switched off priority<commit_after>package pushover

import (
	"github.com/TIBCOSoftware/flogo-lib/flow/activity"
	"github.com/op/go-logging"
	"github.com/toorop/pushover"
	"time"
)

// log is the default package logger
var log = logging.MustGetLogger("activity-pushover")

const (
	ivUserKey = "userKey"
	ivAuthToken = "authToken"
	ivMessage = "message"
	ivMessageTitle = "messageTitle"
	ivDevice = "device"
	ivSound = "sound"
	ivURL = "url"
	ivURLTitle = "urlTitle"
	ivPriority = "priority"
	ovStatus = "status"
)

// MyActivity is a stub for your Activity implementation
type PushoverActivity struct {
	metadata *activity.Metadata
}

// init create & register activity
func init() {
	md := activity.NewMetadata(jsonMetadata)
	activity.Register(&PushoverActivity{metadata: md})
}

// Metadata implements activity.Activity.Metadata
func (a *PushoverActivity) Metadata() *activity.Metadata {
	return a.metadata
}

// Eval implements activity.Activity.Eval
func (a *PushoverActivity) Eval(context activity.Context) (done bool, err error) {

	userKey := context.GetInput(ivUserKey)
	authToken := context.GetInput(ivAuthToken)
	message := context.GetInput(ivMessage)
	messageTitle := context.GetInput(ivMessageTitle)
	device := context.GetInput(ivDevice)
	sound := context.GetInput(ivSound)
	url := context.GetInput(ivURL)
	urlTitle := context.GetInput(ivURLTitle)

	// Check if mandatory credentials are set in config
	if userKey == nil || authToken == nil {
		log.Error("Missing Pushover Credentials")
		err := activity.NewError("Credential Config not specified")
		return false, err
	}

	// Check if there is a message to send
	if message == nil {
		log.Error("No Message to Send")
		context.SetOutput(ovStatus, "NO_MSG")
		return true, nil
	}

	// Now let's try to connect
	po, err := pushover.NewPushover(authToken.(string), userKey.(string))
	if err != nil {
		log.Error("PushOver Connection Error : ", err)
		context.SetOutput(ovStatus, "CONNECT_ERR")
		return true, nil
	}

	m := pushover.Message{}

	m.Message = message.(string)
	// TURN OFF priority until I understand issue on flogo-web
	/*
	if context.GetInput(ivPriority) != nil {
		m.Priority = context.GetInput(ivPriority).(int)
	} else {
	*/
	m.Priority = 0;
	//}

	if messageTitle != nil {
		m.Title = messageTitle.(string)
	}
	if device != nil {
		m.Device = device.(string)
	}
	if url != nil {
		m.Url = url.(string)
	}
	if urlTitle != nil {
		m.UrlTitle = urlTitle.(string)
	}
	m.Timestamp = time.Now().Unix()
	if sound != nil {
		m.Sound = sound.(string)
	}

	if preq, presp, err := po.Push(&m); err != nil {
		log.Error("Push Message Error : ", err)
		log.Error("Sent : ", preq)
		log.Error("Received : ", presp)
		context.SetOutput(ovStatus, "PUSH_ERR")
		return true, nil
	}

	context.SetOutput(ovStatus, "OK")

	return true, nil
}
<|endoftext|>