<commit_before>package winrmtest

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"net/http"
	"strconv"
	"strings"

	"github.com/masterzen/winrm/soap"
	"github.com/masterzen/xmlpath"
)

type wsman struct {
	commands     []command
	identitySeed int
}

type command struct {
	id      string
	text    string
	handler CommandFunc
}

func (w *wsman) HandleCommand(cmd string, f CommandFunc) string {
	w.commands = append(w.commands,
		command{
			id:      "456",
			text:    cmd,
			handler: f,
		})

	return "456"
}

func (w *wsman) CommandByText(cmd string) *command {
	for _, c := range w.commands {
		if c.text == cmd {
			return &c
		}
	}
	return nil
}

func (w *wsman) CommandById(id string) *command {
	for _, c := range w.commands {
		if c.id == id {
			return &c
		}
	}
	return nil
}

func (w *wsman) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
	rw.Header().Add("Content-Type", "application/soap+xml")

	defer r.Body.Close()
	env, err := xmlpath.Parse(r.Body)

	if err != nil {
		return
	}

	action := readAction(env)
	if strings.HasSuffix(action, "transfer/Create") {
		// create a new shell

		rw.Write([]byte(`
			<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell">
				<rsp:ShellId>123</rsp:ShellId>
			</env:Envelope>`))

	} else if strings.HasSuffix(action, "shell/Command") {
		// execute on behalf of the client
		text := readCommand(env)
		cmd := w.CommandByText(text)

		if cmd == nil {
			fmt.Printf("I don't know this command: Command=%s\n", text)
			rw.WriteHeader(http.StatusInternalServerError)
			return
		}

		rw.Write([]byte(fmt.Sprintf(`
			<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell">
				<rsp:CommandId>%s</rsp:CommandId>
			</env:Envelope>`, cmd.id)))

	} else if strings.HasSuffix(action, "shell/Receive") {
		// client ready to receive the results

		id := readCommandIdFromDesiredStream(env)
		cmd := w.CommandById(id)

		if cmd == nil {
			fmt.Printf("I don't know this command: CommandId=%s\n", id)
			rw.WriteHeader(http.StatusInternalServerError)
			return
		}

		stdout := bytes.NewBuffer(make([]byte, 0))
		stderr := bytes.NewBuffer(make([]byte, 0))
		result := cmd.handler(stdout, stderr)
		content := base64.StdEncoding.EncodeToString(stdout.Bytes())

		rw.Write([]byte(fmt.Sprintf(`
			<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell">
				<rsp:ReceiveResponse>
					<rsp:Stream Name="stdout" CommandId="456">%s</rsp:Stream>
					<rsp:Stream Name="stdout" CommandId="456" End="true"></rsp:Stream>
					<rsp:Stream Name="stderr" CommandId="456" End="true"></rsp:Stream>
					<rsp:CommandState State="http://schemas.microsoft.com/wbem/wsman/1/windows/shell/CommandState/Done">
						<rsp:ExitCode>%d</rsp:ExitCode>
					</rsp:CommandState>
				</rsp:ReceiveResponse>
			</env:Envelope>`, content, result)))

	} else if strings.HasSuffix(action, "transfer/Delete") {
		// end of the session
		rw.WriteHeader(http.StatusOK)
	} else {
		fmt.Printf("I don't know this action: %s\n", action)
		rw.WriteHeader(http.StatusInternalServerError)
	}
}

func readAction(env *xmlpath.Node) string {
	xpath, err := xmlpath.CompileWithNamespace(
		"//a:Action", soap.GetAllNamespaces())

	if err != nil {
		return ""
	}

	action, _ := xpath.String(env)
	return action
}

func readCommand(env *xmlpath.Node) string {
	xpath, err := xmlpath.CompileWithNamespace(
		"//rsp:Command", soap.GetAllNamespaces())

	if err != nil {
		return ""
	}

	command, _ := xpath.String(env)
	if unquoted, err := strconv.Unquote(command); err == nil {
		return unquoted
	}
	return command
}

func readCommandIdFromDesiredStream(env *xmlpath.Node) string {
	xpath, err := xmlpath.CompileWithNamespace(
		"//rsp:DesiredStream/@CommandId", soap.GetAllNamespaces())

	if err != nil {
		return ""
	}

	id, _ := xpath.String(env)
	return id
}
<commit_msg>Generate unique Command identifiers<commit_after>package winrmtest

import (
	"bytes"
	"encoding/base64"
	"fmt"
	"net/http"
	"strconv"
	"strings"
	"time"

	"github.com/masterzen/winrm/soap"
	"github.com/masterzen/xmlpath"
)

type wsman struct {
	commands     []command
	identitySeed int
}

type command struct {
	id      string
	text    string
	handler CommandFunc
}

func (w *wsman) HandleCommand(cmd string, f CommandFunc) string {
	id := newId("cmd")
	w.commands = append(w.commands,
		command{
			id:      id,
			text:    cmd,
			handler: f,
		})

	return id
}

func (w *wsman) CommandByText(cmd string) *command {
	for _, c := range w.commands {
		if c.text == cmd {
			return &c
		}
	}
	return nil
}

func (w *wsman) CommandById(id string) *command {
	for _, c := range w.commands {
		if c.id == id {
			return &c
		}
	}
	return nil
}

func (w *wsman) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
	rw.Header().Add("Content-Type", "application/soap+xml")

	defer r.Body.Close()
	env, err := xmlpath.Parse(r.Body)

	if err != nil {
		return
	}

	action := readAction(env)
	if strings.HasSuffix(action, "transfer/Create") {
		// create a new shell

		rw.Write([]byte(`
			<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell">
				<rsp:ShellId>123</rsp:ShellId>
			</env:Envelope>`))

	} else if strings.HasSuffix(action, "shell/Command") {
		// execute on behalf of the client
		text := readCommand(env)
		cmd := w.CommandByText(text)

		if cmd == nil {
			fmt.Printf("I don't know this command: Command=%s\n", text)
			rw.WriteHeader(http.StatusInternalServerError)
			return
		}

		rw.Write([]byte(fmt.Sprintf(`
			<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell">
				<rsp:CommandId>%s</rsp:CommandId>
			</env:Envelope>`, cmd.id)))

	} else if strings.HasSuffix(action, "shell/Receive") {
		// client ready to receive the results

		id := readCommandIdFromDesiredStream(env)
		cmd := w.CommandById(id)

		if cmd == nil {
			fmt.Printf("I don't know this command: CommandId=%s\n", id)
			rw.WriteHeader(http.StatusInternalServerError)
			return
		}

		stdout := bytes.NewBuffer(make([]byte, 0))
		stderr := bytes.NewBuffer(make([]byte, 0))
		result := cmd.handler(stdout, stderr)
		content := base64.StdEncoding.EncodeToString(stdout.Bytes())

		rw.Write([]byte(fmt.Sprintf(`
			<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:rsp="http://schemas.microsoft.com/wbem/wsman/1/windows/shell">
				<rsp:ReceiveResponse>
					<rsp:Stream Name="stdout" CommandId="%s">%s</rsp:Stream>
					<rsp:Stream Name="stdout" CommandId="%s" End="true"></rsp:Stream>
					<rsp:Stream Name="stderr" CommandId="%s" End="true"></rsp:Stream>
					<rsp:CommandState State="http://schemas.microsoft.com/wbem/wsman/1/windows/shell/CommandState/Done">
						<rsp:ExitCode>%d</rsp:ExitCode>
					</rsp:CommandState>
				</rsp:ReceiveResponse>
			</env:Envelope>`, id, content, id, id, result)))

	} else if strings.HasSuffix(action, "transfer/Delete") {
		// end of the session
		rw.WriteHeader(http.StatusOK)
	} else {
		fmt.Printf("I don't know this action: %s\n", action)
		rw.WriteHeader(http.StatusInternalServerError)
	}
}

func readAction(env *xmlpath.Node) string {
	xpath, err := xmlpath.CompileWithNamespace(
		"//a:Action", soap.GetAllNamespaces())

	if err != nil {
		return ""
	}

	action, _ := xpath.String(env)
	return action
}

func readCommand(env *xmlpath.Node) string {
	xpath, err := xmlpath.CompileWithNamespace(
		"//rsp:Command", soap.GetAllNamespaces())

	if err != nil {
		return ""
	}

	command, _ := xpath.String(env)
	if unquoted, err := strconv.Unquote(command); err == nil {
		return unquoted
	}
	return command
}

func readCommandIdFromDesiredStream(env *xmlpath.Node) string {
	xpath, err := xmlpath.CompileWithNamespace(
		"//rsp:DesiredStream/@CommandId", soap.GetAllNamespaces())

	if err != nil {
		return ""
	}

	id, _ := xpath.String(env)
	return id
}

func newId(prefix string) string {
	return fmt.Sprintf("%s-%d", prefix, uint32(time.Now().UTC().Unix()))
}
<|endoftext|>


<commit_before>package geo

import (
	"math"
)

// Represents a Physical Point in geographic notation [lat, lng].
type Point struct {
	lat float64
	lng float64
}

const (
	EARTH_RADIUS = 6356.7523 // Earth's radius ~= 6,356.7523km
)

// Returns a new Point populated by the passed in latitude (lat) and longitude (lng) values.
func NewPoint(lat float64, lng float64) *Point {
	return &Point{lat: lat, lng: lng}
}

// Returns Point p's latitude.
func (p *Point) Lat() float64 {
	return p.lat
}

// Returns Point p's longitude.
func (p *Point) Lng() float64 {
	return p.lng
}

// Returns a Point populated with the lat and lng coordinates of transposing the origin point the distance (in meters) supplied by the compass bearing (in degrees) supplied.
// Original Implementation from: http://www.movable-type.co.uk/scripts/latlong.html
func (p *Point) PointAtDistanceAndBearing(dist float64, bearing float64) *Point {

	dr := dist / EARTH_RADIUS

	bearing = (bearing * (math.Pi / 180.0))

	lat1 := (p.lat * (math.Pi / 180.0))
	lng1 := (p.lng * (math.Pi / 180.0))

	lat2_part1 := math.Sin(lat1) * math.Cos(dr)
	lat2_part2 := math.Cos(lat1) * math.Sin(dr) * math.Cos(bearing)

	lat2 := math.Asin(lat2_part1 + lat2_part2)

	lng2_part1 := math.Sin(bearing) * math.Sin(dr) * math.Cos(lat1)
	lng2_part2 := math.Cos(dr) - (math.Sin(lat1) * math.Sin(lat2))

	lng2 := lng1 + math.Atan2(lng2_part1, lng2_part2)
	lng2 = math.Mod((lng2+3*math.Pi), (2*math.Pi)) - math.Pi

	lat2 = lat2 * (180.0 / math.Pi)
	lng2 = lng2 * (180.0 / math.Pi)

	return &Point{lat: lat2, lng: lng2}
}

// Calculates the Haversine distance between two points.
// Original Implementation from: http://www.movable-type.co.uk/scripts/latlong.html
func (p *Point) GreatCircleDistance(p2 *Point) float64 {
	//r := 6356.7523 // km
	dLat := (p2.lat - p.lat) * (math.Pi / 180.0)
	dLon := (p2.lng - p.lng) * (math.Pi / 180.0)

	lat1 := p.lat * (math.Pi / 180.0)
	lat2 := p2.lat * (math.Pi / 180.0)

	a1 := math.Sin(dLat/2) * math.Sin(dLat/2)
	a2 := math.Sin(dLon/2) * math.Sin(dLon/2) * math.Cos(lat1) * math.Cos(lat2)

	a := a1 + a2

	c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))

	return EARTH_RADIUS * c
}
<commit_msg>[src] Removing uneeded commented out code<commit_after>package geo

import (
	"math"
)

// Represents a Physical Point in geographic notation [lat, lng].
type Point struct {
	lat float64
	lng float64
}

const (
	EARTH_RADIUS = 6356.7523 // Earth's radius ~= 6,356.7523km
)

// Returns a new Point populated by the passed in latitude (lat) and longitude (lng) values.
func NewPoint(lat float64, lng float64) *Point {
	return &Point{lat: lat, lng: lng}
}

// Returns Point p's latitude.
func (p *Point) Lat() float64 {
	return p.lat
}

// Returns Point p's longitude.
func (p *Point) Lng() float64 {
	return p.lng
}

// Returns a Point populated with the lat and lng coordinates of transposing the origin point the distance (in meters) supplied by the compass bearing (in degrees) supplied.
// Original Implementation from: http://www.movable-type.co.uk/scripts/latlong.html
func (p *Point) PointAtDistanceAndBearing(dist float64, bearing float64) *Point {

	dr := dist / EARTH_RADIUS

	bearing = (bearing * (math.Pi / 180.0))

	lat1 := (p.lat * (math.Pi / 180.0))
	lng1 := (p.lng * (math.Pi / 180.0))

	lat2_part1 := math.Sin(lat1) * math.Cos(dr)
	lat2_part2 := math.Cos(lat1) * math.Sin(dr) * math.Cos(bearing)

	lat2 := math.Asin(lat2_part1 + lat2_part2)

	lng2_part1 := math.Sin(bearing) * math.Sin(dr) * math.Cos(lat1)
	lng2_part2 := math.Cos(dr) - (math.Sin(lat1) * math.Sin(lat2))

	lng2 := lng1 + math.Atan2(lng2_part1, lng2_part2)
	lng2 = math.Mod((lng2+3*math.Pi), (2*math.Pi)) - math.Pi

	lat2 = lat2 * (180.0 / math.Pi)
	lng2 = lng2 * (180.0 / math.Pi)

	return &Point{lat: lat2, lng: lng2}
}

// Calculates the Haversine distance between two points.
// Original Implementation from: http://www.movable-type.co.uk/scripts/latlong.html
func (p *Point) GreatCircleDistance(p2 *Point) float64 {
	dLat := (p2.lat - p.lat) * (math.Pi / 180.0)
	dLon := (p2.lng - p.lng) * (math.Pi / 180.0)

	lat1 := p.lat * (math.Pi / 180.0)
	lat2 := p2.lat * (math.Pi / 180.0)

	a1 := math.Sin(dLat/2) * math.Sin(dLat/2)
	a2 := math.Sin(dLon/2) * math.Sin(dLon/2) * math.Cos(lat1) * math.Cos(lat2)

	a := a1 + a2

	c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))

	return EARTH_RADIUS * c
}
<|endoftext|>


<commit_before>// clock counts down to or up from a target time.
package main

import (
	"fmt"
	"os"
	"time"
)

func main() {
	target := time.Date(2016, 1, 1, 0, 0, 0, 0, time.UTC)

	// Exit on Enter key
	go func() {
		buf := make([]byte, 1)
		_, _ = os.Stdin.Read(buf)
		os.Exit(0)
	}()

	const (
		indent          = "\t"
		highlight_start = "\x1b[1;36m"
		highlight_end   = "\x1b[0m"
	)
	fmt.Print(indent, highlight_start, "Just Go", highlight_end, "\n")

	var previous time.Time

	for {
		now := time.Now()
		now = now.Add(time.Duration(-now.Nanosecond())) // truncate to second

		if now != previous {
			previous = now
			remaining := target.Sub(now)

			var sign string
			if remaining > 0 {
				sign = "-" // countdown is "T minus..."
			} else {
				sign = "+" // count up is "T plus..."
				remaining = -remaining
			}

			var days int
			if remaining >= 24*time.Hour {
				days = int(remaining / (24 * time.Hour))
				remaining = remaining % (24 * time.Hour)
			}

			fmt.Print(indent, now.Format(time.UnixDate), "  ", sign)
			if days > 0 {
				fmt.Print(days, "d")
			}
			fmt.Print(remaining, "          \r")
		}
		time.Sleep(50 * time.Millisecond)
	}
}
<commit_msg>forgot target<commit_after>// clock counts down to or up from a target time.
package main

import (
	"fmt"
	"os"
	"time"
)

func main() {
	// Exit on Enter key
	go func() {
		buf := make([]byte, 1)
		_, _ = os.Stdin.Read(buf)
		os.Exit(0)
	}()

	const (
		indent          = "\t"
		highlight_start = "\x1b[1;36m"
		highlight_end   = "\x1b[0m"
	)
	fmt.Print(indent, highlight_start, "Just Go", highlight_end, "\n")
	target := time.Date(2016, 1, 1, 0, 0, 0, 0, time.UTC)
	fmt.Print(indent, target.Format(time.UnixDate), "\n")

	var previous time.Time

	for {
		now := time.Now()
		now = now.Add(time.Duration(-now.Nanosecond())) // truncate to second

		if now != previous {
			previous = now
			remaining := target.Sub(now)

			var sign string
			if remaining > 0 {
				sign = "-" // countdown is "T minus..."
			} else {
				sign = "+" // count up is "T plus..."
				remaining = -remaining
			}

			var days int
			if remaining >= 24*time.Hour {
				days = int(remaining / (24 * time.Hour))
				remaining = remaining % (24 * time.Hour)
			}

			fmt.Print(indent, now.Format(time.UnixDate), "  ", sign)
			if days > 0 {
				fmt.Print(days, "d")
			}
			fmt.Print(remaining, "          \r")
		}
		time.Sleep(50 * time.Millisecond)
	}
}
<|endoftext|>


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

package gcsproxy_test

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"testing"

	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/gcs/mock_gcs"
	"github.com/jacobsa/gcsfuse/gcsproxy"
	. "github.com/jacobsa/oglematchers"
	"github.com/jacobsa/oglemock"
	. "github.com/jacobsa/ogletest"
	"golang.org/x/net/context"
	"google.golang.org/cloud/storage"
)

func TestOgletest(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

func nameIs(name string) Matcher {
	return NewMatcher(
		func(candidate interface{}) error {
			req := candidate.(*gcs.CreateObjectRequest)
			if req.Attrs.Name != name {
				return errors.New("")
			}

			return nil
		},
		fmt.Sprintf("Name is: %s", name))
}

func contentsAre(s string) Matcher {
	return NewMatcher(
		func(candidate interface{}) error {
			// Snarf the contents.
			req := candidate.(*gcs.CreateObjectRequest)
			contents, err := ioutil.ReadAll(req.Contents)
			if err != nil {
				panic(err)
			}

			// Compare
			if string(contents) != s {
				return errors.New("")
			}

			return nil
		},
		fmt.Sprintf("Object contents are: %s", s))
}

func generationIs(g int64) Matcher {
	pred := func(c interface{}) error {
		req := c.(*gcs.CreateObjectRequest)
		if req.GenerationPrecondition == nil {
			return errors.New("which has a nil GenerationPrecondition field.")
		}

		if *req.GenerationPrecondition != g {
			return fmt.Errorf(
				"Which has *GenerationPrecondition == %v",
				*req.GenerationPrecondition)
		}

		return nil
	}

	return NewMatcher(
		pred,
		fmt.Sprintf("*GenerationPrecondition == %v", g))
}

////////////////////////////////////////////////////////////////////////
// Invariant-checking object proxy
////////////////////////////////////////////////////////////////////////

// A wrapper around ObjectProxy that calls CheckInvariants whenever invariants
// should hold. For catching logic errors early in the test.
type checkingObjectProxy struct {
	wrapped *gcsproxy.ObjectProxy
}

func (op *checkingObjectProxy) Name() string {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.Name()
}

func (op *checkingObjectProxy) Stat() (uint64, bool, error) {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.Stat(context.Background())
}

func (op *checkingObjectProxy) ReadAt(b []byte, o int64) (int, error) {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.ReadAt(context.Background(), b, o)
}

func (op *checkingObjectProxy) WriteAt(b []byte, o int64) (int, error) {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.WriteAt(context.Background(), b, o)
}

func (op *checkingObjectProxy) Truncate(n uint64) error {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.Truncate(context.Background(), n)
}

func (op *checkingObjectProxy) Sync() (uint64, error) {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.Sync(context.Background())
}

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

type ObjectProxyTest struct {
	objectName string
	bucket     mock_gcs.MockBucket
	op         checkingObjectProxy
}

func (t *ObjectProxyTest) setUp(ti *TestInfo, srcGeneration uint64) {
	t.objectName = "some/object"
	t.bucket = mock_gcs.NewMockBucket(ti.MockController, "bucket")

	var err error
	t.op.wrapped, err = gcsproxy.NewObjectProxy(
		context.Background(),
		t.bucket,
		t.objectName,
		srcGeneration)

	if err != nil {
		panic(err)
	}
}

////////////////////////////////////////////////////////////////////////
// No source object
////////////////////////////////////////////////////////////////////////

// A test whose initial conditions are a fresh object proxy without a source
// object set.
type NoSourceObjectTest struct {
	ObjectProxyTest
}

var _ SetUpInterface = &NoSourceObjectTest{}

func init() { RegisterTestSuite(&NoSourceObjectTest{}) }

func (t *NoSourceObjectTest) SetUp(ti *TestInfo) {
	t.ObjectProxyTest.setUp(ti, 0)
}

func (t *NoSourceObjectTest) Name() {
	ExpectEq(t.objectName, t.op.Name())
}

func (t *NoSourceObjectTest) Read_InitialState() {
	buf := make([]byte, 1024)
	n, err := t.op.ReadAt(buf, 0)

	ExpectEq(io.EOF, err)
	ExpectEq(0, n)
}

func (t *NoSourceObjectTest) WriteToEndOfObjectThenRead() {
	var buf []byte
	var n int
	var err error

	// Extend the object by writing twice.
	n, err = t.op.WriteAt([]byte("taco"), 0)
	AssertEq(nil, err)
	AssertEq(len("taco"), n)

	n, err = t.op.WriteAt([]byte("burrito"), int64(len("taco")))
	AssertEq(nil, err)
	AssertEq(len("burrito"), n)

	// Read the whole thing.
	buf = make([]byte, 1024)
	n, err = t.op.ReadAt(buf, 0)

	AssertEq(io.EOF, err)
	ExpectEq(len("tacoburrito"), n)
	ExpectEq("tacoburrito", string(buf[:n]))

	// Read a range in the middle.
	buf = make([]byte, 4)
	n, err = t.op.ReadAt(buf, 3)

	AssertEq(nil, err)
	ExpectEq(4, n)
	ExpectEq("obur", string(buf[:n]))
}

func (t *NoSourceObjectTest) WritePastEndOfObjectThenRead() {
	var n int
	var err error
	var buf []byte

	// Extend the object by writing past its end.
	n, err = t.op.WriteAt([]byte("taco"), 2)
	AssertEq(nil, err)
	AssertEq(len("taco"), n)

	// Read the whole thing.
	buf = make([]byte, 1024)
	n, err = t.op.ReadAt(buf, 0)

	AssertEq(io.EOF, err)
	ExpectEq(2+len("taco"), n)
	ExpectEq("\x00\x00taco", string(buf[:n]))

	// Read a range in the middle.
	buf = make([]byte, 4)
	n, err = t.op.ReadAt(buf, 1)

	AssertEq(nil, err)
	ExpectEq(4, n)
	ExpectEq("\x00tac", string(buf[:n]))
}

func (t *NoSourceObjectTest) WriteWithinObjectThenRead() {
	var n int
	var err error
	var buf []byte

	// Write several bytes to extend the object.
	n, err = t.op.WriteAt([]byte("00000"), 0)
	AssertEq(nil, err)
	AssertEq(len("00000"), n)

	// Overwrite some in the middle.
	n, err = t.op.WriteAt([]byte("11"), 1)
	AssertEq(nil, err)
	AssertEq(len("11"), n)

	// Read the whole thing.
	buf = make([]byte, 1024)
	n, err = t.op.ReadAt(buf, 0)

	AssertEq(io.EOF, err)
	ExpectEq(len("01100"), n)
	ExpectEq("01100", string(buf[:n]))
}

func (t *NoSourceObjectTest) GrowByTruncating() {
	var n int
	var err error
	var buf []byte

	// Truncate
	err = t.op.Truncate(4)
	AssertEq(nil, err)

	// Read the whole thing.
	buf = make([]byte, 1024)
	n, err = t.op.ReadAt(buf, 0)

	AssertEq(io.EOF, err)
	ExpectEq(4, n)
	ExpectEq("\x00\x00\x00\x00", string(buf[:n]))
}

func (t *NoSourceObjectTest) Sync_CallsCreateObject_NoInteractions() {
	// CreateObject -- should receive an empty string and a generation zero
	// precondition.
	ExpectCall(t.bucket, "CreateObject")(
		Any(),
		AllOf(nameIs(t.objectName), contentsAre(""), generationIs(0))).
		WillOnce(oglemock.Return(nil, errors.New("")))

	// Sync
	t.op.Sync()
}

func (t *NoSourceObjectTest) Sync_CallsCreateObject_AfterWriting() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Sync_CreateObjectFails() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Sync_CreateObjectSaysPreconditionFailed() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Sync_Successful() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_CallsBucket() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_BucketFails() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_InitialState() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_AfterShortening() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_AfterGrowing() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_AfterReading() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_AfterWriting() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_Clobbered() {
	AssertTrue(false, "TODO")
}

////////////////////////////////////////////////////////////////////////
// Source object present
////////////////////////////////////////////////////////////////////////

// A test whose initial conditions are an object proxy branching from a source
// object in the bucket.
type SourceObjectPresentTest struct {
	ObjectProxyTest
	sourceObject *storage.Object
}

var _ SetUpInterface = &SourceObjectPresentTest{}

func init() { RegisterTestSuite(&SourceObjectPresentTest{}) }

func (t *SourceObjectPresentTest) SetUp(ti *TestInfo) {
	t.ObjectProxyTest.setUp(ti, 123)
}

func (t *SourceObjectPresentTest) Read_CallsNewReader() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Read_NewReaderFails() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Read_NewReaderSucceeds() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Write_CallsNewReader() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Write_NewReaderFails() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Write_NewReaderSucceeds() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Truncate_CallsNewReader() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Truncate_NewReaderFails() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Truncate_NewReaderSucceeds() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_NoInteractions() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_AfterReading() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_AfterWriting() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_AfterTruncating() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_CallsCreateObject() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_CallsBucket() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_BucketFails() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_BucketSaysNotFound() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_InitialState() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_AfterShortening() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_AfterGrowing() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_AfterReading() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_AfterWriting() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_Clobbered() {
	AssertTrue(false, "TODO")
}
<commit_msg>NoSourceObjectTest.Sync_CallsCreateObject_AfterWriting<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package gcsproxy_test

import (
	"errors"
	"fmt"
	"io"
	"io/ioutil"
	"testing"

	"github.com/jacobsa/gcloud/gcs"
	"github.com/jacobsa/gcloud/gcs/mock_gcs"
	"github.com/jacobsa/gcsfuse/gcsproxy"
	. "github.com/jacobsa/oglematchers"
	"github.com/jacobsa/oglemock"
	. "github.com/jacobsa/ogletest"
	"golang.org/x/net/context"
	"google.golang.org/cloud/storage"
)

func TestOgletest(t *testing.T) { RunTests(t) }

////////////////////////////////////////////////////////////////////////
// Helpers
////////////////////////////////////////////////////////////////////////

func nameIs(name string) Matcher {
	return NewMatcher(
		func(candidate interface{}) error {
			req := candidate.(*gcs.CreateObjectRequest)
			if req.Attrs.Name != name {
				return errors.New("")
			}

			return nil
		},
		fmt.Sprintf("Name is: %s", name))
}

func contentsAre(s string) Matcher {
	return NewMatcher(
		func(candidate interface{}) error {
			// Snarf the contents.
			req := candidate.(*gcs.CreateObjectRequest)
			contents, err := ioutil.ReadAll(req.Contents)
			if err != nil {
				panic(err)
			}

			// Compare
			if string(contents) != s {
				return errors.New("")
			}

			return nil
		},
		fmt.Sprintf("Object contents are: %s", s))
}

func generationIs(g int64) Matcher {
	pred := func(c interface{}) error {
		req := c.(*gcs.CreateObjectRequest)
		if req.GenerationPrecondition == nil {
			return errors.New("which has a nil GenerationPrecondition field.")
		}

		if *req.GenerationPrecondition != g {
			return fmt.Errorf(
				"Which has *GenerationPrecondition == %v",
				*req.GenerationPrecondition)
		}

		return nil
	}

	return NewMatcher(
		pred,
		fmt.Sprintf("*GenerationPrecondition == %v", g))
}

////////////////////////////////////////////////////////////////////////
// Invariant-checking object proxy
////////////////////////////////////////////////////////////////////////

// A wrapper around ObjectProxy that calls CheckInvariants whenever invariants
// should hold. For catching logic errors early in the test.
type checkingObjectProxy struct {
	wrapped *gcsproxy.ObjectProxy
}

func (op *checkingObjectProxy) Name() string {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.Name()
}

func (op *checkingObjectProxy) Stat() (uint64, bool, error) {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.Stat(context.Background())
}

func (op *checkingObjectProxy) ReadAt(b []byte, o int64) (int, error) {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.ReadAt(context.Background(), b, o)
}

func (op *checkingObjectProxy) WriteAt(b []byte, o int64) (int, error) {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.WriteAt(context.Background(), b, o)
}

func (op *checkingObjectProxy) Truncate(n uint64) error {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.Truncate(context.Background(), n)
}

func (op *checkingObjectProxy) Sync() (uint64, error) {
	op.wrapped.CheckInvariants()
	defer op.wrapped.CheckInvariants()
	return op.wrapped.Sync(context.Background())
}

////////////////////////////////////////////////////////////////////////
// Boilerplate
////////////////////////////////////////////////////////////////////////

type ObjectProxyTest struct {
	objectName string
	bucket     mock_gcs.MockBucket
	op         checkingObjectProxy
}

func (t *ObjectProxyTest) setUp(ti *TestInfo, srcGeneration uint64) {
	t.objectName = "some/object"
	t.bucket = mock_gcs.NewMockBucket(ti.MockController, "bucket")

	var err error
	t.op.wrapped, err = gcsproxy.NewObjectProxy(
		context.Background(),
		t.bucket,
		t.objectName,
		srcGeneration)

	if err != nil {
		panic(err)
	}
}

////////////////////////////////////////////////////////////////////////
// No source object
////////////////////////////////////////////////////////////////////////

// A test whose initial conditions are a fresh object proxy without a source
// object set.
type NoSourceObjectTest struct {
	ObjectProxyTest
}

var _ SetUpInterface = &NoSourceObjectTest{}

func init() { RegisterTestSuite(&NoSourceObjectTest{}) }

func (t *NoSourceObjectTest) SetUp(ti *TestInfo) {
	t.ObjectProxyTest.setUp(ti, 0)
}

func (t *NoSourceObjectTest) Name() {
	ExpectEq(t.objectName, t.op.Name())
}

func (t *NoSourceObjectTest) Read_InitialState() {
	buf := make([]byte, 1024)
	n, err := t.op.ReadAt(buf, 0)

	ExpectEq(io.EOF, err)
	ExpectEq(0, n)
}

func (t *NoSourceObjectTest) WriteToEndOfObjectThenRead() {
	var buf []byte
	var n int
	var err error

	// Extend the object by writing twice.
	n, err = t.op.WriteAt([]byte("taco"), 0)
	AssertEq(nil, err)
	AssertEq(len("taco"), n)

	n, err = t.op.WriteAt([]byte("burrito"), int64(len("taco")))
	AssertEq(nil, err)
	AssertEq(len("burrito"), n)

	// Read the whole thing.
	buf = make([]byte, 1024)
	n, err = t.op.ReadAt(buf, 0)

	AssertEq(io.EOF, err)
	ExpectEq(len("tacoburrito"), n)
	ExpectEq("tacoburrito", string(buf[:n]))

	// Read a range in the middle.
	buf = make([]byte, 4)
	n, err = t.op.ReadAt(buf, 3)

	AssertEq(nil, err)
	ExpectEq(4, n)
	ExpectEq("obur", string(buf[:n]))
}

func (t *NoSourceObjectTest) WritePastEndOfObjectThenRead() {
	var n int
	var err error
	var buf []byte

	// Extend the object by writing past its end.
	n, err = t.op.WriteAt([]byte("taco"), 2)
	AssertEq(nil, err)
	AssertEq(len("taco"), n)

	// Read the whole thing.
	buf = make([]byte, 1024)
	n, err = t.op.ReadAt(buf, 0)

	AssertEq(io.EOF, err)
	ExpectEq(2+len("taco"), n)
	ExpectEq("\x00\x00taco", string(buf[:n]))

	// Read a range in the middle.
	buf = make([]byte, 4)
	n, err = t.op.ReadAt(buf, 1)

	AssertEq(nil, err)
	ExpectEq(4, n)
	ExpectEq("\x00tac", string(buf[:n]))
}

func (t *NoSourceObjectTest) WriteWithinObjectThenRead() {
	var n int
	var err error
	var buf []byte

	// Write several bytes to extend the object.
	n, err = t.op.WriteAt([]byte("00000"), 0)
	AssertEq(nil, err)
	AssertEq(len("00000"), n)

	// Overwrite some in the middle.
	n, err = t.op.WriteAt([]byte("11"), 1)
	AssertEq(nil, err)
	AssertEq(len("11"), n)

	// Read the whole thing.
	buf = make([]byte, 1024)
	n, err = t.op.ReadAt(buf, 0)

	AssertEq(io.EOF, err)
	ExpectEq(len("01100"), n)
	ExpectEq("01100", string(buf[:n]))
}

func (t *NoSourceObjectTest) GrowByTruncating() {
	var n int
	var err error
	var buf []byte

	// Truncate
	err = t.op.Truncate(4)
	AssertEq(nil, err)

	// Read the whole thing.
	buf = make([]byte, 1024)
	n, err = t.op.ReadAt(buf, 0)

	AssertEq(io.EOF, err)
	ExpectEq(4, n)
	ExpectEq("\x00\x00\x00\x00", string(buf[:n]))
}

func (t *NoSourceObjectTest) Sync_CallsCreateObject_NoInteractions() {
	// CreateObject -- should receive an empty string and a generation zero
	// precondition.
	ExpectCall(t.bucket, "CreateObject")(
		Any(),
		AllOf(nameIs(t.objectName), contentsAre(""), generationIs(0))).
		WillOnce(oglemock.Return(nil, errors.New("")))

	// Sync
	t.op.Sync()
}

func (t *NoSourceObjectTest) Sync_CallsCreateObject_AfterWriting() {
	// Write some data.
	n, err := t.op.WriteAt([]byte("taco"), 0)
	AssertEq(nil, err)
	AssertEq(4, n)

	// CreateObject -- should receive "taco" and a generation zero precondition.
	ExpectCall(t.bucket, "CreateObject")(
		Any(),
		AllOf(nameIs(t.objectName), contentsAre("taco"), generationIs(0))).
		WillOnce(oglemock.Return(nil, errors.New("")))

	// Sync
	t.op.Sync()
}

func (t *NoSourceObjectTest) Sync_CreateObjectFails() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Sync_CreateObjectSaysPreconditionFailed() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Sync_Successful() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_CallsBucket() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_BucketFails() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_InitialState() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_AfterShortening() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_AfterGrowing() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_AfterReading() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_AfterWriting() {
	AssertTrue(false, "TODO")
}

func (t *NoSourceObjectTest) Stat_Clobbered() {
	AssertTrue(false, "TODO")
}

////////////////////////////////////////////////////////////////////////
// Source object present
////////////////////////////////////////////////////////////////////////

// A test whose initial conditions are an object proxy branching from a source
// object in the bucket.
type SourceObjectPresentTest struct {
	ObjectProxyTest
	sourceObject *storage.Object
}

var _ SetUpInterface = &SourceObjectPresentTest{}

func init() { RegisterTestSuite(&SourceObjectPresentTest{}) }

func (t *SourceObjectPresentTest) SetUp(ti *TestInfo) {
	t.ObjectProxyTest.setUp(ti, 123)
}

func (t *SourceObjectPresentTest) Read_CallsNewReader() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Read_NewReaderFails() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Read_NewReaderSucceeds() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Write_CallsNewReader() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Write_NewReaderFails() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Write_NewReaderSucceeds() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Truncate_CallsNewReader() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Truncate_NewReaderFails() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Truncate_NewReaderSucceeds() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_NoInteractions() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_AfterReading() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_AfterWriting() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_AfterTruncating() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Sync_CallsCreateObject() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_CallsBucket() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_BucketFails() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_BucketSaysNotFound() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_InitialState() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_AfterShortening() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_AfterGrowing() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_AfterReading() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_AfterWriting() {
	AssertTrue(false, "TODO")
}

func (t *SourceObjectPresentTest) Stat_Clobbered() {
	AssertTrue(false, "TODO")
}
<|endoftext|>


<commit_before>package gen

import (
	"fmt"
	"regexp"
	"strings"
)

var defaultService = "org.bluez"

func isDefaultService(s string) bool {
	return len(s) >= len(defaultService) && s[:len(defaultService)] == defaultService
}

func createConstructors(api Api) []Constructor {

	// log.Debugf("-------------------------------------- %s", api.Interface)

	constructors := []Constructor{}
	constructors = inspectServiceName(api.Service, constructors)
	constructors = inspectObjectPath(api.ObjectPath, constructors)

	for i, c := range constructors {

		args := []string{}
		if c.Service == "" {
			args = append(args, "servicePath string")
			c.Service = "servicePath"
		} else {
			c.Service = fmt.Sprintf(`"%s"`, c.Service)
		}

		if c.ObjectPath == "" {
			args = append(args, "objectPath string")
			c.ObjectPath = "objectPath"
		} else {
			c.ObjectPath = fmt.Sprintf(`"%s"`, c.ObjectPath)
		}

		c.Args = strings.Join(args, ", ")

		docs := []string{}
		for _, doc := range c.Docs {
			for _, d1 := range strings.Split(doc, "\n") {
				docs = append(docs, "// \t"+d1)
			}
		}
		c.ArgsDocs = "//\n// Args:\n" + strings.Join(docs, "\n")

		// target as the deafult initializer
		if c.Role == "Target" {
			c.Role = ""
		}

		constructors[i] = c
	}

	// log.Debugf("constructors %++v", constructors)

	return constructors
}

func inspectServiceName(serviceName string, constructors []Constructor) []Constructor {

	// log.Debugf("ObjectPath %s", api.ObjectPath)
	// log.Debugf("Interface %s", api.Interface)

	apiService := serviceName
	if apiService != "" {
		apiService = strings.Split(apiService, " ")[0]
	}

	if !isDefaultService(apiService) {

		// log.Debugf("Service %s", apiService)

		// case 1
		// unique name (Target role)
		// org.bluez (Controller role)
		if strings.Contains(serviceName, "\n") {

			re := regexp.MustCompile(`(.+) \((.+?) .+\)`)
			matches1 := re.FindAllSubmatch([]byte(serviceName), -1)

			// log.Debugf("%s ----> %s", serviceName, matches1)

			for _, m1 := range matches1 {

				doc := ""
				srvc := strings.Trim(string(m1[1]), " \t")

				if !isDefaultService(srvc) {
					doc = srvc
					srvc = ""
				}

				docslist := []string{}
				if doc != "" {
					docslist = append(docslist, "servicePath: "+doc)
				}

				c := Constructor{
					Service: srvc,
					Role:    string(m1[2]),
					Docs:    docslist,
				}

				constructors = append(constructors, c)
			}
		} else {

			c := Constructor{
				Service: "",
				Role:    "",
				Docs: []string{
					"servicePath: " + serviceName,
				},
			}
			constructors = append(constructors, c)
		}
	} else {
		c := Constructor{
			Service:    apiService,
			Role:       "",
			ObjectPath: "",
			Args:       "",
			Docs:       []string{},
		}
		constructors = append(constructors, c)
	}

	return constructors
}

func inspectObjectPath(objectPath string, constructors []Constructor) []Constructor {

	constructors2 := []Constructor{}

	for _, c := range constructors {

		if strings.Contains(objectPath, "\n") {

			// log.Debugf("ObjectPath: \n----\n%s\n\n-----", objectPath)

			anchor1 := " (Target role)"
			idx := strings.Index(objectPath, anchor1)
			if idx > -1 {

				target := objectPath[:idx]

				anchor2 := "(Controller role)"
				idx2 := strings.Index(objectPath, anchor2)
				controller := objectPath[idx+len(anchor1) : idx2]

				target = strings.Replace(strings.Trim(target, " \t\n"), "\n", "", -1)
				controller = strings.Replace(strings.Trim(controller, " \t\n"), "\n\t", "", -1)

				// if Role is set apply a objectPath
				if c.Role == "Target" {
					c.ObjectPath = ""
					c.Docs = append(c.Docs, "objectPath: "+target)
				}

				if c.Role == "Controller" {
					c.ObjectPath = ""
					c.Docs = append(c.Docs, "objectPath: "+controller)
				}

				// if no Role, create a contructor for each objectPath
				if c.Role == "" {

					if controller != "" {
						c1 := c
						c1.Role = "Controller"
						c1.ObjectPath = ""
						c1.Docs = append(c1.Docs, "objectPath: "+controller)
						constructors2 = append(constructors2, c1)
					}

					if target != "" {
						c1 := c
						c1.Role = "Target"
						c1.ObjectPath = ""
						c1.Docs = append(c1.Docs, "objectPath: "+target)
						constructors2 = append(constructors2, c1)
					}

					continue
				}

			}

			constructors2 = append(constructors2, c)
			continue
		}

		// freely definable
		if strings.Contains(objectPath, "freely") {
			c.ObjectPath = ""
			c.Docs = append(c.Docs, "objectPath: "+objectPath)
		}

		// <application dependent>
		if strings.HasPrefix(objectPath, "<application") {
			c.Docs = append(c.Docs, "objectPath: "+objectPath)
			c.ObjectPath = ""
		}

		constructors2 = append(constructors2, c)
	}

	return constructors2
}
<commit_msg>fix defaults<commit_after>package gen

import (
	"fmt"
	"regexp"
	"strings"

	log "github.com/sirupsen/logrus"
)

var defaultService = "org.bluez"

func isDefaultService(s string) bool {
	return len(s) >= len(defaultService) && s[:len(defaultService)] == defaultService
}

func createConstructors(api Api) []Constructor {

	log.Debugf("-------------------------------------- %s", api.Interface)

	constructors := []Constructor{}
	constructors = inspectServiceName(api.Service, constructors)
	constructors = inspectObjectPath(api.ObjectPath, constructors)

	for i, c := range constructors {

		args := []string{}
		if c.Service == "" {
			args = append(args, "servicePath string")
			c.Service = "servicePath"
		} else {
			c.Service = fmt.Sprintf(`"%s"`, c.Service)
		}

		if c.ObjectPath == "" {
			args = append(args, "objectPath string")
			c.ObjectPath = "objectPath"
		} else {
			c.ObjectPath = fmt.Sprintf(`"%s"`, c.ObjectPath)
		}

		c.Args = strings.Join(args, ", ")

		docs := []string{}
		for _, doc := range c.Docs {
			for _, d1 := range strings.Split(doc, "\n") {
				docs = append(docs, "// \t"+d1)
			}
		}
		c.ArgsDocs = "//\n// Args:\n" + strings.Join(docs, "\n")

		// target as the deafult initializer
		if c.Role == "Target" {
			c.Role = ""
		}

		constructors[i] = c
	}

	// log.Debugf("constructors %++v", constructors)

	return constructors
}

func inspectServiceName(serviceName string, constructors []Constructor) []Constructor {

	// log.Debugf("ObjectPath %s", api.ObjectPath)
	// log.Debugf("Interface %s", api.Interface)

	apiService := serviceName
	if apiService != "" {
		apiService = strings.Split(apiService, " ")[0]
	}

	if !isDefaultService(apiService) {

		// log.Debugf("Service %s", apiService)

		// case 1
		// unique name (Target role)
		// org.bluez (Controller role)
		if strings.Contains(serviceName, "\n") {

			re := regexp.MustCompile(`(.+) \((.+?) .+\)`)
			matches1 := re.FindAllSubmatch([]byte(serviceName), -1)

			// log.Debugf("%s ----> %s", serviceName, matches1)

			for _, m1 := range matches1 {

				doc := ""
				srvc := strings.Trim(string(m1[1]), " \t")

				if !isDefaultService(srvc) {
					doc = srvc
					srvc = ""
				}

				docslist := []string{}
				if doc != "" {
					docslist = append(docslist, "servicePath: "+doc)
				}

				c := Constructor{
					Service: srvc,
					Role:    string(m1[2]),
					Docs:    docslist,
				}

				constructors = append(constructors, c)
			}
		} else {

			c := Constructor{
				Service: "",
				Role:    "",
				Docs: []string{
					"servicePath: " + serviceName,
				},
			}
			constructors = append(constructors, c)
		}
	} else {
		c := Constructor{
			Service:    apiService,
			Role:       "",
			ObjectPath: "",
			Args:       "",
			Docs:       []string{},
		}
		constructors = append(constructors, c)
	}

	return constructors
}

func inspectObjectPath(objectPath string, constructors []Constructor) []Constructor {

	constructors2 := []Constructor{}

	log.Debugf("%d %s", len(constructors), objectPath)
	log.Debugf("%+v", constructors)

	for _, c := range constructors {

		if strings.Contains(objectPath, "\n") {

			// log.Debugf("ObjectPath: \n----\n%s\n\n-----", objectPath)

			anchor1 := " (Target role)"
			idx := strings.Index(objectPath, anchor1)
			if idx > -1 {

				target := objectPath[:idx]

				anchor2 := "(Controller role)"
				idx2 := strings.Index(objectPath, anchor2)
				controller := objectPath[idx+len(anchor1) : idx2]

				target = strings.Replace(strings.Trim(target, " \t\n"), "\n", "", -1)
				controller = strings.Replace(strings.Trim(controller, " \t\n"), "\n\t", "", -1)

				// if Role is set apply a objectPath
				if c.Role == "Target" {
					c.ObjectPath = ""
					c.Docs = append(c.Docs, "objectPath: "+target)
				}

				if c.Role == "Controller" {
					c.ObjectPath = ""
					c.Docs = append(c.Docs, "objectPath: "+controller)
				}

				// if no Role, create a contructor for each objectPath
				if c.Role == "" {

					if controller != "" {
						c1 := c
						c1.Role = "Controller"
						c1.ObjectPath = ""
						c1.Docs = append(c1.Docs, "objectPath: "+controller)
						constructors2 = append(constructors2, c1)
					}

					if target != "" {
						c1 := c
						c1.Role = "Target"
						c1.ObjectPath = ""
						c1.Docs = append(c1.Docs, "objectPath: "+target)
						constructors2 = append(constructors2, c1)
					}

					continue
				}

			}

			constructors2 = append(constructors2, c)
			continue
		}

		defaultObjectPath := "/org/bluez"
		if len(objectPath) >= len(defaultObjectPath) && objectPath[:len(defaultObjectPath)] != defaultObjectPath {
			c.ObjectPath = ""
			c.Docs = append(c.Docs, "objectPath: "+objectPath)
		} else {
			c.ObjectPath = objectPath
		}

		log.Debugf("----> %++v", c)
		constructors2 = append(constructors2, c)
	}

	return constructors2
}
<|endoftext|>


<commit_before>// 22-24 august 2012
package main

import (
	"fmt"
	"strings"
	"sort"

	// for drawing the progress bar
	"image"
	"image/color"
	"image/draw"
	"image/png"
	"encoding/base64"
	"bytes"

	"html/template"
)

type SortOrder int
const (
	SortByRegion SortOrder = iota
	SortByBoxState
	SortByMediaState
)

type GameScan struct {
	Name		string
	HasNoScans	bool			// for whole games
	Region		string
	BoxState		ScanState
	MediaState	ScanState
	Error			error
}

type ScanSet []*GameScan

func GetConsoleScans(console string) (ScanSet, error) {
	var gameScans ScanSet

	games, err := GetGameList(console)
	if err != nil {
		return nil, fmt.Errorf("error getting %s game list: %v", console, err)
	}
	for _, game := range games {
//fmt.Println(game)
		if strings.HasPrefix(game, "List of " + console + " games") {	// omit list from report
			continue
		}
		scans, err := GetScans(game, console)
		if err == ErrGameNoScans {		// omit games for this console that will not have scans
			continue
		}
		if err != nil {
			gameScans = append(gameScans, &GameScan{
				Name:	game,
				Error:	err,
			})
			continue
		}
		if len(scans) == 0 {				// there are no scans at all
			gameScans = append(gameScans, &GameScan{
				Name:		game,
				HasNoScans:	true,
			})
			continue
		}
		nScans := 0
		for _, scan := range scans {
			var mediaState ScanState

			if scan.Console != console {	// omit scans from other consoles
				continue
			}
			nScans++
			boxState := scan.BoxScanState()
			mediaState = scan.MediaScanState()
			gameScans = append(gameScans, &GameScan{
				Name:		game,
				Region:		scan.Region,
				BoxState:		boxState,
				MediaState:	mediaState,
			})
		}
		if nScans == 0 {					// there are no scans for the specified console
			gameScans = append(gameScans, &GameScan{
				Name:		game,
				HasNoScans:	true,
			})
			continue
		}
	}
	return gameScans, nil
}

type sorter struct {
	scans		ScanSet
	sortOrder		SortOrder
}

// for sort.Interface
func (s sorter) Len() int {
	return len(s.scans)
}

func (s sorter) Less(i, j int) bool {
	scans := s.scans
	// the sort orders make no sense if there is either an error or no scans for a game, so handle those cases first
	if scans[i].Error != nil && scans[j].Error != nil {		// errors go first
		return scans[i].Name < scans[j].Name		// by title if they both error
	}
	if scans[i].Error != nil {
		return true
	}
	if scans[j].Error != nil {
		return false
	}
	if scans[i].HasNoScans && scans[j].HasNoScans {	// then lack of scans
		return scans[i].Name < scans[j].Name		// by title if they both lack scans
	}
	if scans[i].HasNoScans {
		return true
	}
	if scans[j].HasNoScans {
		return false
	}
	switch s.sortOrder {
	case SortByRegion:		// sort by region, then by name
		if scans[i].Region == scans[j].Region {			// then if they have the same region, alphabetically
			return scans[i].Name < scans[j].Name
		}
		return scans[i].Region < scans[j].Region			// finally
	case SortByBoxState:
		if scans[i].BoxState == scans[j].BoxState {			// then if they have the same region, alphabetically
			return scans[i].Name < scans[j].Name
		}
		return scans[i].BoxState < scans[j].BoxState		// finally
	case SortByMediaState:
		if scans[i].MediaState == scans[j].MediaState {		// then if they have the same region, alphabetically
			return scans[i].Name < scans[j].Name
		}
		return scans[i].MediaState < scans[j].MediaState	// finally
	}
	panic(fmt.Sprintf("invalid sort order %d", int(s.sortOrder)))
}

func (s sorter) Swap(i, j int) {
	s.scans[i], s.scans[j] = s.scans[j], s.scans[i]
}

func (scans ScanSet) Sort(so SortOrder) {
	sort.Sort(sorter{
		scans:		scans,
		sortOrder:		so,
	})
}

type Stats struct {
	nBoxScans			int
	nBoxHave				int
	nBoxGood			int
	nBoxBad				int
	nBoxIncomplete		int
	pBoxHave				float64
	pBoxGood			float64
	pBoxGoodAll			float64
	pBoxBad				float64
	pBoxBadAll			float64
	pBoxIncomplete		float64
	pBoxIncompleteAll		float64
	nMediaScans			int
	nMediaHave			int
	nMediaGood			int
	nMediaBad			int
	nMediaIncomplete		int
	pMediaHave			float64
	pMediaGood			float64
	pMediaGoodAll			float64
	pMediaBad			float64
	pMediaBadAll			float64
	pMediaIncomplete		float64
	pMediaIncompleteAll	float64
}

func pcnt(_a, _b int) float64 {
	if _a != 0 && _b == 0 {	// sanity check
		panic("we somehow have scans where none are expected")
	}
	if _b == 0 {
		return 0.0
	}
	a, b := float64(_a), float64(_b)
	return (a / b) * 100.0
}

func (scans ScanSet) GetStats(_filterRegion string) (stats Stats) {
	for _, scan := range scans {
		if scan.Error != nil || scan.HasNoScans {		// TODO really skip entries without scans?
			continue
		}
		if !filterRegion(scan.Region, _filterRegion) {
			continue
		}
		stats.nBoxScans++
		switch scan.BoxState {
		case Good:
			stats.nBoxGood++
			stats.nBoxHave++
		case Bad:
			stats.nBoxBad++
			stats.nBoxHave++
		case Incomplete:
			stats.nBoxIncomplete++
			stats.nBoxHave++
		}
		stats.nMediaScans++
		switch scan.MediaState {
		case Good:
			stats.nMediaGood++
			stats.nMediaHave++
		case Bad:
			stats.nMediaBad++
			stats.nMediaHave++
		case Incomplete:
			stats.nMediaIncomplete++
			stats.nMediaHave++
		}
	}
	stats.CalculatePercents()
	return
}

func (stats *Stats) Add(stats2 Stats) {
	stats.nBoxScans += stats2.nBoxScans
	stats.nBoxHave += stats2.nBoxHave
	stats.nBoxGood += stats2.nBoxGood
	stats.nBoxBad += stats2.nBoxBad
	stats.nMediaScans += stats2.nMediaScans
	stats.nMediaHave += stats2.nMediaHave
	stats.nMediaGood += stats2.nMediaGood
	stats.nMediaBad += stats2.nMediaBad
	stats.CalculatePercents()
}

func (stats *Stats) CalculatePercents() {
	stats.pBoxHave = pcnt(stats.nBoxHave, stats.nBoxScans)
	stats.pBoxGood = pcnt(stats.nBoxGood, stats.nBoxHave)
	stats.pBoxGoodAll = pcnt(stats.nBoxGood, stats.nBoxScans)
	stats.pBoxBad = pcnt(stats.nBoxBad, stats.nBoxHave)
	stats.pBoxBadAll = pcnt(stats.nBoxBad, stats.nBoxScans)
	stats.pBoxIncomplete = pcnt(stats.nBoxIncomplete, stats.nBoxHave)
	stats.pBoxIncompleteAll = pcnt(stats.nBoxIncomplete, stats.nBoxScans)

	stats.pMediaHave = pcnt(stats.nMediaHave, stats.nMediaScans)
	stats.pMediaGood = pcnt(stats.nMediaGood, stats.nMediaHave)
	stats.pMediaGoodAll = pcnt(stats.nMediaGood, stats.nMediaScans)
	stats.pMediaBad = pcnt(stats.nMediaBad, stats.nMediaHave)
	stats.pMediaBadAll = pcnt(stats.nMediaBad, stats.nMediaScans)
	stats.pMediaIncomplete = pcnt(stats.nMediaIncomplete, stats.nBoxHave)
	stats.pMediaIncompleteAll = pcnt(stats.nMediaIncomplete, stats.nMediaScans)
}

const pbarWidth = 300
const pbarHeight = 20
const pbarPercentFactor = 3
const pbarBorderThickness = 2

var (
	black = image.NewUniform(color.Black)
	white = image.NewUniform(color_missing)
	red = image.NewUniform(color_bad)
	green = image.NewUniform(color_good)
	yellow = image.NewUniform(color_incomplete)
)

func progressbar(pGoodAll float64, pBadAll float64, pIncAll float64) string {
	pbar := image.NewRGBA(image.Rect(0, 0,
		pbarWidth + (pbarBorderThickness * 2),
		pbarHeight + (pbarBorderThickness * 2)))
	// 1) fill black for border
	draw.Draw(pbar, pbar.Rect, black, image.ZP, draw.Src)
	// 2) draw white for what we have
	draw.Draw(pbar, image.Rect(
		pbarBorderThickness, pbarBorderThickness,
		pbarBorderThickness + pbarWidth,
		pbarBorderThickness + pbarHeight), white, image.ZP, draw.Src)
	// 3) figure out the rectanges for good, incomplete, and bad
	goodWid := int(pGoodAll + 0.5) * pbarPercentFactor
	badWid := int(pBadAll + 0.5) * pbarPercentFactor
	incompleteWid := int(pIncAll + 0.5) * pbarPercentFactor
	goodRect := image.Rect(
		pbarBorderThickness, pbarBorderThickness,
		pbarBorderThickness + goodWid,
		pbarBorderThickness + pbarHeight)
	incRect := image.Rect(
		pbarBorderThickness + goodWid, pbarBorderThickness,
		pbarBorderThickness + goodWid + incompleteWid,
		pbarBorderThickness + pbarHeight)
	badRect := image.Rect(
		pbarBorderThickness + goodWid + incompleteWid, pbarBorderThickness,
		pbarBorderThickness + goodWid + incompleteWid + badWid,
		pbarBorderThickness + pbarHeight)
	// 4) draw good, incomplete, and bad
	draw.Draw(pbar, goodRect, green, image.ZP, draw.Src)
	draw.Draw(pbar, incRect, yellow, image.ZP, draw.Src)
	draw.Draw(pbar, badRect, red, image.ZP, draw.Src)
	// 5) convert to base64 and return
	_pngDat := new(bytes.Buffer)
	pngDat := base64.NewEncoder(base64.StdEncoding, _pngDat)
	defer pngDat.Close()
	err := png.Encode(pngDat, pbar)
	if err != nil {
		panic(fmt.Errorf("error producing progress bar PNG: %v\n", err))
	}
	return _pngDat.String()
}

func (s Stats) BoxProgressBar() string {
	return progressbar(s.pBoxGoodAll, s.pBoxBadAll, s.pBoxIncompleteAll)
}

func (s Stats) MediaProgressBar() string {
	return progressbar(s.pMediaGoodAll, s.pMediaBadAll, s.pMediaIncompleteAll)
}

var gameStatsHTML = `

			Box
			We have %d of %d known scans (%.2f%%)

%d (%.2f%%) of them are good (%.2f%% overall)

%d (%.2f%%) of them are bad (%.2f%% overall)

			Media
			We have %d of %d known scans (%.2f%%)

%d (%.2f%%) of them are good (%.2f%% overall)

%d (%.2f%%) of them are bad (%.2f%% overall)

`

func (stats Stats) HTML() template.HTML {
	boxbar := stats.BoxProgressBar()
	mediabar := stats.MediaProgressBar()
	return template.HTML(fmt.Sprintf(gameStatsHTML,
		stats.nBoxHave, stats.nBoxScans, stats.pBoxHave,
		stats.nBoxGood, stats.pBoxGood, stats.pBoxGoodAll,
		stats.nBoxBad, stats.pBoxBad, stats.pBoxBadAll,
		boxbar,
		stats.nMediaHave, stats.nMediaScans, stats.pMediaHave,
		stats.nMediaGood, stats.pMediaGood, stats.pMediaGoodAll,
		stats.nMediaBad, stats.pMediaBad, stats.pMediaBadAll,
		mediabar))
}
<commit_msg>Meh; drop TODO on known scans in stats<commit_after>// 22-24 august 2012
package main

import (
	"fmt"
	"strings"
	"sort"

	// for drawing the progress bar
	"image"
	"image/color"
	"image/draw"
	"image/png"
	"encoding/base64"
	"bytes"

	"html/template"
)

type SortOrder int
const (
	SortByRegion SortOrder = iota
	SortByBoxState
	SortByMediaState
)

type GameScan struct {
	Name		string
	HasNoScans	bool			// for whole games
	Region		string
	BoxState		ScanState
	MediaState	ScanState
	Error			error
}

type ScanSet []*GameScan

func GetConsoleScans(console string) (ScanSet, error) {
	var gameScans ScanSet

	games, err := GetGameList(console)
	if err != nil {
		return nil, fmt.Errorf("error getting %s game list: %v", console, err)
	}
	for _, game := range games {
//fmt.Println(game)
		if strings.HasPrefix(game, "List of " + console + " games") {	// omit list from report
			continue
		}
		scans, err := GetScans(game, console)
		if err == ErrGameNoScans {		// omit games for this console that will not have scans
			continue
		}
		if err != nil {
			gameScans = append(gameScans, &GameScan{
				Name:	game,
				Error:	err,
			})
			continue
		}
		if len(scans) == 0 {				// there are no scans at all
			gameScans = append(gameScans, &GameScan{
				Name:		game,
				HasNoScans:	true,
			})
			continue
		}
		nScans := 0
		for _, scan := range scans {
			var mediaState ScanState

			if scan.Console != console {	// omit scans from other consoles
				continue
			}
			nScans++
			boxState := scan.BoxScanState()
			mediaState = scan.MediaScanState()
			gameScans = append(gameScans, &GameScan{
				Name:		game,
				Region:		scan.Region,
				BoxState:		boxState,
				MediaState:	mediaState,
			})
		}
		if nScans == 0 {					// there are no scans for the specified console
			gameScans = append(gameScans, &GameScan{
				Name:		game,
				HasNoScans:	true,
			})
			continue
		}
	}
	return gameScans, nil
}

type sorter struct {
	scans		ScanSet
	sortOrder		SortOrder
}

// for sort.Interface
func (s sorter) Len() int {
	return len(s.scans)
}

func (s sorter) Less(i, j int) bool {
	scans := s.scans
	// the sort orders make no sense if there is either an error or no scans for a game, so handle those cases first
	if scans[i].Error != nil && scans[j].Error != nil {		// errors go first
		return scans[i].Name < scans[j].Name		// by title if they both error
	}
	if scans[i].Error != nil {
		return true
	}
	if scans[j].Error != nil {
		return false
	}
	if scans[i].HasNoScans && scans[j].HasNoScans {	// then lack of scans
		return scans[i].Name < scans[j].Name		// by title if they both lack scans
	}
	if scans[i].HasNoScans {
		return true
	}
	if scans[j].HasNoScans {
		return false
	}
	switch s.sortOrder {
	case SortByRegion:		// sort by region, then by name
		if scans[i].Region == scans[j].Region {			// then if they have the same region, alphabetically
			return scans[i].Name < scans[j].Name
		}
		return scans[i].Region < scans[j].Region			// finally
	case SortByBoxState:
		if scans[i].BoxState == scans[j].BoxState {			// then if they have the same region, alphabetically
			return scans[i].Name < scans[j].Name
		}
		return scans[i].BoxState < scans[j].BoxState		// finally
	case SortByMediaState:
		if scans[i].MediaState == scans[j].MediaState {		// then if they have the same region, alphabetically
			return scans[i].Name < scans[j].Name
		}
		return scans[i].MediaState < scans[j].MediaState	// finally
	}
	panic(fmt.Sprintf("invalid sort order %d", int(s.sortOrder)))
}

func (s sorter) Swap(i, j int) {
	s.scans[i], s.scans[j] = s.scans[j], s.scans[i]
}

func (scans ScanSet) Sort(so SortOrder) {
	sort.Sort(sorter{
		scans:		scans,
		sortOrder:		so,
	})
}

type Stats struct {
	nBoxScans			int
	nBoxHave				int
	nBoxGood			int
	nBoxBad				int
	nBoxIncomplete		int
	pBoxHave				float64
	pBoxGood			float64
	pBoxGoodAll			float64
	pBoxBad				float64
	pBoxBadAll			float64
	pBoxIncomplete		float64
	pBoxIncompleteAll		float64
	nMediaScans			int
	nMediaHave			int
	nMediaGood			int
	nMediaBad			int
	nMediaIncomplete		int
	pMediaHave			float64
	pMediaGood			float64
	pMediaGoodAll			float64
	pMediaBad			float64
	pMediaBadAll			float64
	pMediaIncomplete		float64
	pMediaIncompleteAll	float64
}

func pcnt(_a, _b int) float64 {
	if _a != 0 && _b == 0 {	// sanity check
		panic("we somehow have scans where none are expected")
	}
	if _b == 0 {
		return 0.0
	}
	a, b := float64(_a), float64(_b)
	return (a / b) * 100.0
}

func (scans ScanSet) GetStats(_filterRegion string) (stats Stats) {
	for _, scan := range scans {
		if scan.Error != nil || scan.HasNoScans {		// we can't really count games without known scans since the stats are for known scans
			continue
		}
		if !filterRegion(scan.Region, _filterRegion) {
			continue
		}
		stats.nBoxScans++
		switch scan.BoxState {
		case Good:
			stats.nBoxGood++
			stats.nBoxHave++
		case Bad:
			stats.nBoxBad++
			stats.nBoxHave++
		case Incomplete:
			stats.nBoxIncomplete++
			stats.nBoxHave++
		}
		stats.nMediaScans++
		switch scan.MediaState {
		case Good:
			stats.nMediaGood++
			stats.nMediaHave++
		case Bad:
			stats.nMediaBad++
			stats.nMediaHave++
		case Incomplete:
			stats.nMediaIncomplete++
			stats.nMediaHave++
		}
	}
	stats.CalculatePercents()
	return
}

func (stats *Stats) Add(stats2 Stats) {
	stats.nBoxScans += stats2.nBoxScans
	stats.nBoxHave += stats2.nBoxHave
	stats.nBoxGood += stats2.nBoxGood
	stats.nBoxBad += stats2.nBoxBad
	stats.nMediaScans += stats2.nMediaScans
	stats.nMediaHave += stats2.nMediaHave
	stats.nMediaGood += stats2.nMediaGood
	stats.nMediaBad += stats2.nMediaBad
	stats.CalculatePercents()
}

func (stats *Stats) CalculatePercents() {
	stats.pBoxHave = pcnt(stats.nBoxHave, stats.nBoxScans)
	stats.pBoxGood = pcnt(stats.nBoxGood, stats.nBoxHave)
	stats.pBoxGoodAll = pcnt(stats.nBoxGood, stats.nBoxScans)
	stats.pBoxBad = pcnt(stats.nBoxBad, stats.nBoxHave)
	stats.pBoxBadAll = pcnt(stats.nBoxBad, stats.nBoxScans)
	stats.pBoxIncomplete = pcnt(stats.nBoxIncomplete, stats.nBoxHave)
	stats.pBoxIncompleteAll = pcnt(stats.nBoxIncomplete, stats.nBoxScans)

	stats.pMediaHave = pcnt(stats.nMediaHave, stats.nMediaScans)
	stats.pMediaGood = pcnt(stats.nMediaGood, stats.nMediaHave)
	stats.pMediaGoodAll = pcnt(stats.nMediaGood, stats.nMediaScans)
	stats.pMediaBad = pcnt(stats.nMediaBad, stats.nMediaHave)
	stats.pMediaBadAll = pcnt(stats.nMediaBad, stats.nMediaScans)
	stats.pMediaIncomplete = pcnt(stats.nMediaIncomplete, stats.nBoxHave)
	stats.pMediaIncompleteAll = pcnt(stats.nMediaIncomplete, stats.nMediaScans)
}

const pbarWidth = 300
const pbarHeight = 20
const pbarPercentFactor = 3
const pbarBorderThickness = 2

var (
	black = image.NewUniform(color.Black)
	white = image.NewUniform(color_missing)
	red = image.NewUniform(color_bad)
	green = image.NewUniform(color_good)
	yellow = image.NewUniform(color_incomplete)
)

func progressbar(pGoodAll float64, pBadAll float64, pIncAll float64) string {
	pbar := image.NewRGBA(image.Rect(0, 0,
		pbarWidth + (pbarBorderThickness * 2),
		pbarHeight + (pbarBorderThickness * 2)))
	// 1) fill black for border
	draw.Draw(pbar, pbar.Rect, black, image.ZP, draw.Src)
	// 2) draw white for what we have
	draw.Draw(pbar, image.Rect(
		pbarBorderThickness, pbarBorderThickness,
		pbarBorderThickness + pbarWidth,
		pbarBorderThickness + pbarHeight), white, image.ZP, draw.Src)
	// 3) figure out the rectanges for good, incomplete, and bad
	goodWid := int(pGoodAll + 0.5) * pbarPercentFactor
	badWid := int(pBadAll + 0.5) * pbarPercentFactor
	incompleteWid := int(pIncAll + 0.5) * pbarPercentFactor
	goodRect := image.Rect(
		pbarBorderThickness, pbarBorderThickness,
		pbarBorderThickness + goodWid,
		pbarBorderThickness + pbarHeight)
	incRect := image.Rect(
		pbarBorderThickness + goodWid, pbarBorderThickness,
		pbarBorderThickness + goodWid + incompleteWid,
		pbarBorderThickness + pbarHeight)
	badRect := image.Rect(
		pbarBorderThickness + goodWid + incompleteWid, pbarBorderThickness,
		pbarBorderThickness + goodWid + incompleteWid + badWid,
		pbarBorderThickness + pbarHeight)
	// 4) draw good, incomplete, and bad
	draw.Draw(pbar, goodRect, green, image.ZP, draw.Src)
	draw.Draw(pbar, incRect, yellow, image.ZP, draw.Src)
	draw.Draw(pbar, badRect, red, image.ZP, draw.Src)
	// 5) convert to base64 and return
	_pngDat := new(bytes.Buffer)
	pngDat := base64.NewEncoder(base64.StdEncoding, _pngDat)
	defer pngDat.Close()
	err := png.Encode(pngDat, pbar)
	if err != nil {
		panic(fmt.Errorf("error producing progress bar PNG: %v\n", err))
	}
	return _pngDat.String()
}

func (s Stats) BoxProgressBar() string {
	return progressbar(s.pBoxGoodAll, s.pBoxBadAll, s.pBoxIncompleteAll)
}

func (s Stats) MediaProgressBar() string {
	return progressbar(s.pMediaGoodAll, s.pMediaBadAll, s.pMediaIncompleteAll)
}

var gameStatsHTML = `

			Box
			We have %d of %d known scans (%.2f%%)

%d (%.2f%%) of them are good (%.2f%% overall)

%d (%.2f%%) of them are bad (%.2f%% overall)

			Media
			We have %d of %d known scans (%.2f%%)

%d (%.2f%%) of them are good (%.2f%% overall)

%d (%.2f%%) of them are bad (%.2f%% overall)

`

func (stats Stats) HTML() template.HTML {
	boxbar := stats.BoxProgressBar()
	mediabar := stats.MediaProgressBar()
	return template.HTML(fmt.Sprintf(gameStatsHTML,
		stats.nBoxHave, stats.nBoxScans, stats.pBoxHave,
		stats.nBoxGood, stats.pBoxGood, stats.pBoxGoodAll,
		stats.nBoxBad, stats.pBoxBad, stats.pBoxBadAll,
		boxbar,
		stats.nMediaHave, stats.nMediaScans, stats.pMediaHave,
		stats.nMediaGood, stats.pMediaGood, stats.pMediaGoodAll,
		stats.nMediaBad, stats.pMediaBad, stats.pMediaBadAll,
		mediabar))
}
<|endoftext|>


<commit_before>package run

import (
	"log"
	"bufio"
	"io"
	"os/exec"
	"sync"
)

// Run runs the command and returns a channel of output lines, errors and result of cmd.Wait
func Run(cmd *exec.Cmd) (
	lines chan string, errors chan error, resultCh chan error) {
	lines = make(chan string)
	errors = make(chan error, 1)
	resultCh = make(chan error)

	stdout, err := cmd.StdoutPipe()
	if err != nil {
		errors <- err
		return
	}
	stderr, err := cmd.StderrPipe()
	if err != nil {
		errors <- err
		return
	}

	err = cmd.Start()
	if err != nil {
		errors <- err
		return
	}

	var wg sync.WaitGroup
	go tailReader(bufio.NewReader(stdout), lines, errors, wg)
	go tailReader(bufio.NewReader(stderr), lines, errors, wg)

	go func() {
		wg.Wait()
		resultCh <- cmd.Wait()
	}()

	return
}

func tailReader(
	r *bufio.Reader, ch chan string, errCh chan error,
	wg sync.WaitGroup) {
	defer wg.Done()
	wg.Add(1)

	for {
		line, _, err := r.ReadLine()
		if err != nil {
			log.Printf("** %T | %#v | %v\n", err, err, err)

			if err != io.EOF {
				errCh <- err
			}
			break
		}
		ch <- string(line)
	}
}
<commit_msg>WaitGroup.Add must be called from the main goroutine. also pass it by address. this magically gets rid of the EBADF error<commit_after>package run

import (
	"bufio"
	"io"
	"os/exec"
	"sync"
)

// Run runs the command and returns a channel of output lines, errors and result of cmd.Wait
func Run(cmd *exec.Cmd) (
	lines chan string, errors chan error, resultCh chan error) {
	lines = make(chan string)
	errors = make(chan error, 1)
	resultCh = make(chan error)

	stdout, err := cmd.StdoutPipe()
	if err != nil {
		errors <- err
		return
	}
	stderr, err := cmd.StderrPipe()
	if err != nil {
		errors <- err
		return
	}

	err = cmd.Start()
	if err != nil {
		errors <- err
		return
	}

	go func() {
		var wg sync.WaitGroup
		wg.Add(2)
		go tailReader(bufio.NewReader(stdout), lines, errors, &wg)
		go tailReader(bufio.NewReader(stderr), lines, errors, &wg)
		wg.Wait()
		resultCh <- cmd.Wait()
	}()

	return
}

func tailReader(
	r *bufio.Reader, ch chan string, errCh chan error,
	wg *sync.WaitGroup) {
	defer wg.Done()
	for {
		line, _, err := r.ReadLine()
		if err != nil {
			// log.Printf("** %T | %#v | %v\n", err, err, err)

			if err != io.EOF {
				errCh <- err
			}
			break
		}
		ch <- string(line)
	}
}
<|endoftext|>


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

package main

import (
	"flag"
	"fmt"
	"log"
	"os"

	"golang.org/x/net/context"
	"golang.org/x/sys/unix"

	"github.com/googlecloudplatform/gcsfuse/fs"
	"github.com/googlecloudplatform/gcsfuse/perms"
	"github.com/googlecloudplatform/gcsfuse/timeutil"
	"github.com/jacobsa/fuse"
	"github.com/jacobsa/fuse/fsutil"
)

// In main, set flagSet to flag.CommandLine and pass in os.Args[1:]. In a test,
// pass in a virgin flag set and test arguments.
func run(
	args []string,
	flagSet *flag.FlagSet,
	handleSIGINT func(mountPoint string)) (err error) {
	// Populate the flag set and then parse flags.
	flags := populateFlagSet(flagSet)

	err = flagSet.Parse(args)
	if err != nil {
		err = fmt.Errorf("Parsing flags: %v", err)
		return
	}

	// Sanity check: make sure the temporary directory exists and is writable
	// currently. This gives a better user experience than harder to debug EIO
	// errors when reading files in the future.
	if flags.TempDir != "" {
		var f *os.File
		f, err = fsutil.AnonymousFile(flags.TempDir)
		f.Close()

		if err != nil {
			err = fmt.Errorf(
				"Error writing to temporary directory (%q); are you sure it exists "+
					"with the correct permissions?",
				err.Error())
			return
		}
	}

	// The file leaser used by the file system sizes its limit on number of
	// temporary files based on the process's rlimit. If this is too low, we'll
	// throw away cached content unnecessarily often. This is particularly a
	// problem on OS X, which has a crazy low default limit (256 as of OS X
	// 10.10.3). So print a warning if the limit is low.
	var rlimit unix.Rlimit
	if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlimit); err == nil {
		const reasonableLimit = 4096

		if rlimit.Cur < reasonableLimit {
			log.Printf(
				"Warning: low file rlimit of %d will cause cached content to be "+
					"frequently evicted. Consider raising with `ulimit -n`.",
				rlimit.Cur)
		}
	}

	// Choose UID and GID.
	uid, gid, err := perms.MyUserAndGroup()
	if err != nil {
		err = fmt.Errorf("MyUserAndGroup: %v", err)
		return
	}

	if flags.Uid >= 0 {
		uid = uint32(flags.Uid)
	}

	if flags.Gid >= 0 {
		gid = uint32(flags.Gid)
	}

	// Set up the bucket.
	bucket, err := setUpBucket(
		flags,
		conn,
		bucketName)

	if err != nil {
		err = fmt.Errorf("setUpBucket: %v", err)
		return
	}

	// Create a file system server.
	serverCfg := &fs.ServerConfig{
		Clock:                timeutil.RealClock(),
		Bucket:               bucket,
		TempDir:              flags.TempDir,
		TempDirLimitNumFiles: fs.ChooseTempDirLimitNumFiles(),
		TempDirLimitBytes:    flags.TempDirLimit,
		GCSChunkSize:         flags.GCSChunkSize,
		ImplicitDirectories:  flags.ImplicitDirs,
		DirTypeCacheTTL:      flags.TypeCacheTTL,
		Uid:                  uid,
		Gid:                  gid,
		FilePerms:            os.FileMode(flags.FileMode),
		DirPerms:             os.FileMode(flags.DirMode),
	}

	server, err := fs.NewServer(serverCfg)
	if err != nil {
		err = fmt.Errorf("fs.NewServer: %v", err)
		return
	}

	// Mount the file system.
	mountCfg := &fuse.MountConfig{
		FSName:      bucket.Name(),
		Options:     flags.MountOptions,
		ErrorLogger: log.New(os.Stderr, "fuse: ", log.Flags()),
	}

	mountedFS, err := fuse.Mount(mountPoint, server, mountCfg)
	if err != nil {
		err = fmt.Errorf("Mount: %v", err)
		return
	}

	log.Println("File system has been successfully mounted.")

	// Call the SIGINT handler as appropriate until this function returns.
	stopSIGINTHandler := registerSIGINTHandler(handleSIGINT)
	defer func() { stopSIGINTHandler <- struct{}{} }()

	// Wait for it to be unmounted.
	err = mountedFS.Join(context.Background())
	if err != nil {
		err = fmt.Errorf("MountedFileSystem.Join: %v", err)
		return
	}

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

package main

import (
	"flag"
	"fmt"
	"log"
	"os"

	"golang.org/x/net/context"
	"golang.org/x/sys/unix"

	"github.com/googlecloudplatform/gcsfuse/fs"
	"github.com/googlecloudplatform/gcsfuse/perms"
	"github.com/googlecloudplatform/gcsfuse/timeutil"
	"github.com/jacobsa/fuse"
	"github.com/jacobsa/fuse/fsutil"
)

// Set up a SIGINT handler that will invoke the supplied function for each
// SIGINT signal received. (Signals may be dropped while the handler is
// running.)
//
// Stop future calls to the handler by writing an element to the channel. Once
// the write proceeds, it is guaranteed that the handler will not be called
// again.
func registerSIGINTHandler(f func()) (stop chan<- struct{}) {
	panic("TODO")
}

// In main, set flagSet to flag.CommandLine and pass in os.Args[1:]. In a test,
// pass in a virgin flag set and test arguments.
func run(
	args []string,
	flagSet *flag.FlagSet,
	handleSIGINT func(mountPoint string)) (err error) {
	// Populate the flag set and then parse flags.
	flags := populateFlagSet(flagSet)

	err = flagSet.Parse(args)
	if err != nil {
		err = fmt.Errorf("Parsing flags: %v", err)
		return
	}

	// Sanity check: make sure the temporary directory exists and is writable
	// currently. This gives a better user experience than harder to debug EIO
	// errors when reading files in the future.
	if flags.TempDir != "" {
		var f *os.File
		f, err = fsutil.AnonymousFile(flags.TempDir)
		f.Close()

		if err != nil {
			err = fmt.Errorf(
				"Error writing to temporary directory (%q); are you sure it exists "+
					"with the correct permissions?",
				err.Error())
			return
		}
	}

	// The file leaser used by the file system sizes its limit on number of
	// temporary files based on the process's rlimit. If this is too low, we'll
	// throw away cached content unnecessarily often. This is particularly a
	// problem on OS X, which has a crazy low default limit (256 as of OS X
	// 10.10.3). So print a warning if the limit is low.
	var rlimit unix.Rlimit
	if err := unix.Getrlimit(unix.RLIMIT_NOFILE, &rlimit); err == nil {
		const reasonableLimit = 4096

		if rlimit.Cur < reasonableLimit {
			log.Printf(
				"Warning: low file rlimit of %d will cause cached content to be "+
					"frequently evicted. Consider raising with `ulimit -n`.",
				rlimit.Cur)
		}
	}

	// Choose UID and GID.
	uid, gid, err := perms.MyUserAndGroup()
	if err != nil {
		err = fmt.Errorf("MyUserAndGroup: %v", err)
		return
	}

	if flags.Uid >= 0 {
		uid = uint32(flags.Uid)
	}

	if flags.Gid >= 0 {
		gid = uint32(flags.Gid)
	}

	// Set up the bucket.
	bucket, err := setUpBucket(
		flags,
		conn,
		bucketName)

	if err != nil {
		err = fmt.Errorf("setUpBucket: %v", err)
		return
	}

	// Create a file system server.
	serverCfg := &fs.ServerConfig{
		Clock:                timeutil.RealClock(),
		Bucket:               bucket,
		TempDir:              flags.TempDir,
		TempDirLimitNumFiles: fs.ChooseTempDirLimitNumFiles(),
		TempDirLimitBytes:    flags.TempDirLimit,
		GCSChunkSize:         flags.GCSChunkSize,
		ImplicitDirectories:  flags.ImplicitDirs,
		DirTypeCacheTTL:      flags.TypeCacheTTL,
		Uid:                  uid,
		Gid:                  gid,
		FilePerms:            os.FileMode(flags.FileMode),
		DirPerms:             os.FileMode(flags.DirMode),
	}

	server, err := fs.NewServer(serverCfg)
	if err != nil {
		err = fmt.Errorf("fs.NewServer: %v", err)
		return
	}

	// Mount the file system.
	mountCfg := &fuse.MountConfig{
		FSName:      bucket.Name(),
		Options:     flags.MountOptions,
		ErrorLogger: log.New(os.Stderr, "fuse: ", log.Flags()),
	}

	mountedFS, err := fuse.Mount(mountPoint, server, mountCfg)
	if err != nil {
		err = fmt.Errorf("Mount: %v", err)
		return
	}

	log.Println("File system has been successfully mounted.")

	// Call the SIGINT handler as appropriate until this function returns.
	stopSIGINTHandler := registerSIGINTHandler(func() {
		handleSIGINT(mountPoint)
	})

	defer func() { stopSIGINTHandler <- struct{}{} }()

	// Wait for it to be unmounted.
	err = mountedFS.Join(context.Background())
	if err != nil {
		err = fmt.Errorf("MountedFileSystem.Join: %v", err)
		return
	}

	return
}
<|endoftext|>