<commit_before>package main

import (
	"fmt"
	"log"
	"time"

	"gobot.io/x/gobot"
	"gobot.io/x/gobot/drivers/gpio"
	"gobot.io/x/gobot/platforms/raspi"

	"flag"

	local "./drivers/gpio"
)

func main() {
	doorOpenTemp := flag.Int("temp-open-door", 30, "Temperature for trigger open door")
	flapOpenTemp := flag.Int("temp-open-flap", 40, "Temperature for trigger open flap")
	allCloseTemp := flag.Int("temp-close-all", 24, "Temperature for trigget class all")
	dhtInterval := flag.String("interval-poll-sensor", "5m", "Interval polling DHT")

	flag.Parse()

	fmt.Println(
		time.Microsecond,
		time.Millisecond,
		time.Nanosecond,
	)

	master := gobot.NewMaster()

	r := raspi.NewAdaptor()

	m1 := gpio.NewMotorDriver(r, "")
	m1.SetName("Door Motor")
	m1.ForwardPin = "7"   // 4
	m1.BackwardPin = "11" // 17

	m2 := gpio.NewMotorDriver(r, "")
	m2.SetName("Flap Motor")
	m2.ForwardPin = "13"  // 27
	m2.BackwardPin = "15" // 22

	s := local.NewDHTSensorDriver(r, "16") //23
	s.SetName("Sensor")
	if d, err := time.ParseDuration(*dhtInterval); err != nil {
		s.PollInterval(d)
	}

	f := NewFire(m1, m2, s)

	work := func() {
		s.On(gpio.Data, func(data interface{}) {
			t := data.(float32)
			log.Printf("Current temperature %.1f", t)

			if t >= float32(*flapOpenTemp) {
				f.OpenFlap()
			}

			if t >= float32(*doorOpenTemp) {
				f.OpenDoor()
			}

			if t > 0.0 && t <= float32(*allCloseTemp) {
				f.CloseDoor()
				f.CloseFlap()
			}
		})

		s.On(gpio.Error, func(data interface{}) {
			log.Print("Error DHT")
			log.Println(data)
		})
	}

	master.AddRobot(gobot.NewRobot("fire",
		[]gobot.Connection{r},
		[]gobot.Device{m1, m2, s},
		work,
	))

	master.Start()
}
<commit_msg>Remove unused code<commit_after>package main

import (
	"log"
	"time"

	"gobot.io/x/gobot"
	"gobot.io/x/gobot/drivers/gpio"
	"gobot.io/x/gobot/platforms/raspi"

	"flag"

	local "./drivers/gpio"
)

func main() {
	doorOpenTemp := flag.Int("temp-open-door", 30, "Temperature for trigger open door")
	flapOpenTemp := flag.Int("temp-open-flap", 40, "Temperature for trigger open flap")
	allCloseTemp := flag.Int("temp-close-all", 24, "Temperature for trigget class all")
	dhtInterval := flag.String("interval-poll-sensor", "5m", "Interval polling DHT")

	flag.Parse()

	r := raspi.NewAdaptor()

	m1 := gpio.NewMotorDriver(r, "")
	m1.SetName("Door Motor")
	m1.ForwardPin = "7"   // 4
	m1.BackwardPin = "11" // 17

	m2 := gpio.NewMotorDriver(r, "")
	m2.SetName("Flap Motor")
	m2.ForwardPin = "13"  // 27
	m2.BackwardPin = "15" // 22

	s := local.NewDHTSensorDriver(r, "16") //23
	s.SetName("Sensor")
	if d, err := time.ParseDuration(*dhtInterval); err != nil {
		s.PollInterval(d)
	}

	f := NewFire(m1, m2, s)

	work := func() {
		s.On(gpio.Data, func(data interface{}) {
			t := data.(float32)
			log.Printf("Current temperature %.1f", t)

			if t >= float32(*flapOpenTemp) {
				f.OpenFlap()
			}

			if t >= float32(*doorOpenTemp) {
				f.OpenDoor()
			}

			if t > 0.0 && t <= float32(*allCloseTemp) {
				f.CloseDoor()
				f.CloseFlap()
			}
		})

		s.On(gpio.Error, func(data interface{}) {
			log.Print("Error DHT")
			log.Println(data)
		})
	}

	robot := gobot.NewRobot("fire",
		[]gobot.Connection{r},
		[]gobot.Device{m1, m2, s},
		work,
	)

	robot.Start()
}
<|endoftext|>


<commit_before>package handlers_test

import (
	"encoding/base64"
	"io"
	"net/http"
	"net/http/httptest"

	"code.cloudfoundry.org/bbs/events"
	"code.cloudfoundry.org/bbs/events/eventfakes"
	"code.cloudfoundry.org/bbs/format"
	"code.cloudfoundry.org/bbs/handlers"
	"code.cloudfoundry.org/bbs/models"
	"code.cloudfoundry.org/bbs/models/test/model_helpers"
	"code.cloudfoundry.org/lager"
	"code.cloudfoundry.org/lager/lagertest"
	"github.com/vito/go-sse/sse"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Event Handlers", func() {
	var (
		logger     lager.Logger
		desiredHub events.Hub
		actualHub  events.Hub

		handler         *handlers.EventHandler
		eventStreamDone chan struct{}
		server          *httptest.Server
	)

	BeforeEach(func() {
		logger = lagertest.NewTestLogger("test")
		desiredHub = events.NewHub()
		actualHub = events.NewHub()
		handler = handlers.NewEventHandler(desiredHub, actualHub)

		eventStreamDone = make(chan struct{})
	})

	AfterEach(func() {
		desiredHub.Close()
		actualHub.Close()
		server.Close()
	})

	var ItStreamsEventsFromHub = func(hubRef *events.Hub) {
		Describe("Streaming Events", func() {
			var hub events.Hub
			var response *http.Response

			BeforeEach(func() {
				hub = *hubRef
			})

			JustBeforeEach(func() {
				var err error
				response, err = http.Get(server.URL)
				Expect(err).NotTo(HaveOccurred())
			})

			Context("when failing to subscribe to the event hub", func() {
				BeforeEach(func() {
					hub.Close()
				})

				It("returns an internal server error", func() {
					Expect(response.StatusCode).To(Equal(http.StatusInternalServerError))
				})
			})

			Context("when successfully subscribing to the event hub", func() {
				It("emits events from the hub to the connection", func() {
					reader := sse.NewReadCloser(response.Body)

					hub.Emit(&eventfakes.FakeEvent{Token: "A"})
					encodedPayload := base64.StdEncoding.EncodeToString([]byte("A"))

					Expect(reader.Next()).To(Equal(sse.Event{
						ID:   "0",
						Name: "fake",
						Data: []byte(encodedPayload),
					}))

					hub.Emit(&eventfakes.FakeEvent{Token: "B"})

					encodedPayload = base64.StdEncoding.EncodeToString([]byte("B"))
					Expect(reader.Next()).To(Equal(sse.Event{
						ID:   "1",
						Name: "fake",
						Data: []byte(encodedPayload),
					}))
				})

				It("returns Content-Type as text/event-stream", func() {
					Expect(response.Header.Get("Content-Type")).To(Equal("text/event-stream; charset=utf-8"))
					Expect(response.Header.Get("Cache-Control")).To(Equal("no-cache, no-store, must-revalidate"))
					Expect(response.Header.Get("Connection")).To(Equal("keep-alive"))
				})

				Context("when the source provides an unmarshalable event", func() {
					It("closes the event stream to the client", func() {
						hub.Emit(eventfakes.UnmarshalableEvent{Fn: func() {}})

						reader := sse.NewReadCloser(response.Body)
						_, err := reader.Next()
						Expect(err).To(Equal(io.EOF))
					})
				})

				Context("when the event source returns an error", func() {
					BeforeEach(func() {
						hub.Close()
					})

					It("closes the client event stream", func() {
						reader := sse.NewReadCloser(response.Body)
						_, err := reader.Next()
						Expect(err).To(Equal(io.EOF))
					})
				})

				Context("when the client closes the response body", func() {
					It("returns early", func() {
						reader := sse.NewReadCloser(response.Body)
						hub.Emit(eventfakes.FakeEvent{Token: "A"})
						err := reader.Close()
						Expect(err).NotTo(HaveOccurred())
						Eventually(eventStreamDone, 10).Should(BeClosed())
					})
				})
			})
		})
	}

	Describe("Subscribe_r0", func() {
		BeforeEach(func() {
			server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				handler.Subscribe_r0(logger, w, r)
				close(eventStreamDone)
			}))
		})

		Describe("Subscribe to Desired Events", func() {
			ItStreamsEventsFromHub(&desiredHub)

			It("migrates desired lrps down to v0", func() {
				response, err := http.Get(server.URL)
				Expect(err).NotTo(HaveOccurred())
				reader := sse.NewReadCloser(response.Body)

				desiredLRP := model_helpers.NewValidDesiredLRP("guid")
				event := models.NewDesiredLRPCreatedEvent(desiredLRP)

				migratedLRP := desiredLRP.VersionDownTo(format.V0)
				Expect(migratedLRP).NotTo(Equal(desiredLRP))
				migratedEvent := models.NewDesiredLRPCreatedEvent(migratedLRP)

				expectedEvent, err := events.NewEventFromModelEvent(0, migratedEvent)
				Expect(err).NotTo(HaveOccurred())

				desiredHub.Emit(event)

				Expect(reader.Next()).To(Equal(expectedEvent))
			})
		})

		Describe("Subscribe to Actual Events", func() {
			ItStreamsEventsFromHub(&actualHub)
		})
	})

})
<commit_msg>compare events instead of encoded bytes<commit_after>package handlers_test

import (
	"encoding/base64"
	"io"
	"net/http"
	"net/http/httptest"

	"code.cloudfoundry.org/bbs/events"
	"code.cloudfoundry.org/bbs/events/eventfakes"
	"code.cloudfoundry.org/bbs/format"
	"code.cloudfoundry.org/bbs/handlers"
	"code.cloudfoundry.org/bbs/models"
	"code.cloudfoundry.org/bbs/models/test/model_helpers"
	"code.cloudfoundry.org/lager"
	"code.cloudfoundry.org/lager/lagertest"
	"github.com/vito/go-sse/sse"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("Event Handlers", func() {
	var (
		logger     lager.Logger
		desiredHub events.Hub
		actualHub  events.Hub

		handler         *handlers.EventHandler
		eventStreamDone chan struct{}
		server          *httptest.Server
	)

	BeforeEach(func() {
		logger = lagertest.NewTestLogger("test")
		desiredHub = events.NewHub()
		actualHub = events.NewHub()
		handler = handlers.NewEventHandler(desiredHub, actualHub)

		eventStreamDone = make(chan struct{})
	})

	AfterEach(func() {
		desiredHub.Close()
		actualHub.Close()
		server.Close()
	})

	var ItStreamsEventsFromHub = func(hubRef *events.Hub) {
		Describe("Streaming Events", func() {
			var hub events.Hub
			var response *http.Response

			BeforeEach(func() {
				hub = *hubRef
			})

			JustBeforeEach(func() {
				var err error
				response, err = http.Get(server.URL)
				Expect(err).NotTo(HaveOccurred())
			})

			Context("when failing to subscribe to the event hub", func() {
				BeforeEach(func() {
					hub.Close()
				})

				It("returns an internal server error", func() {
					Expect(response.StatusCode).To(Equal(http.StatusInternalServerError))
				})
			})

			Context("when successfully subscribing to the event hub", func() {
				It("emits events from the hub to the connection", func() {
					reader := sse.NewReadCloser(response.Body)

					hub.Emit(&eventfakes.FakeEvent{Token: "A"})
					encodedPayload := base64.StdEncoding.EncodeToString([]byte("A"))

					Expect(reader.Next()).To(Equal(sse.Event{
						ID:   "0",
						Name: "fake",
						Data: []byte(encodedPayload),
					}))

					hub.Emit(&eventfakes.FakeEvent{Token: "B"})

					encodedPayload = base64.StdEncoding.EncodeToString([]byte("B"))
					Expect(reader.Next()).To(Equal(sse.Event{
						ID:   "1",
						Name: "fake",
						Data: []byte(encodedPayload),
					}))
				})

				It("returns Content-Type as text/event-stream", func() {
					Expect(response.Header.Get("Content-Type")).To(Equal("text/event-stream; charset=utf-8"))
					Expect(response.Header.Get("Cache-Control")).To(Equal("no-cache, no-store, must-revalidate"))
					Expect(response.Header.Get("Connection")).To(Equal("keep-alive"))
				})

				Context("when the source provides an unmarshalable event", func() {
					It("closes the event stream to the client", func() {
						hub.Emit(eventfakes.UnmarshalableEvent{Fn: func() {}})

						reader := sse.NewReadCloser(response.Body)
						_, err := reader.Next()
						Expect(err).To(Equal(io.EOF))
					})
				})

				Context("when the event source returns an error", func() {
					BeforeEach(func() {
						hub.Close()
					})

					It("closes the client event stream", func() {
						reader := sse.NewReadCloser(response.Body)
						_, err := reader.Next()
						Expect(err).To(Equal(io.EOF))
					})
				})

				Context("when the client closes the response body", func() {
					It("returns early", func() {
						reader := sse.NewReadCloser(response.Body)
						hub.Emit(eventfakes.FakeEvent{Token: "A"})
						err := reader.Close()
						Expect(err).NotTo(HaveOccurred())
						Eventually(eventStreamDone, 10).Should(BeClosed())
					})
				})
			})
		})
	}

	Describe("Subscribe_r0", func() {
		BeforeEach(func() {
			server = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				handler.Subscribe_r0(logger, w, r)
				close(eventStreamDone)
			}))
		})

		Describe("Subscribe to Desired Events", func() {
			ItStreamsEventsFromHub(&desiredHub)

			It("migrates desired lrps down to v0", func() {
				response, err := http.Get(server.URL)
				Expect(err).NotTo(HaveOccurred())
				reader := sse.NewReadCloser(response.Body)

				desiredLRP := model_helpers.NewValidDesiredLRP("guid")
				event := models.NewDesiredLRPCreatedEvent(desiredLRP)

				migratedLRP := desiredLRP.VersionDownTo(format.V0)
				Expect(migratedLRP).NotTo(Equal(desiredLRP))
				migratedEvent := models.NewDesiredLRPCreatedEvent(migratedLRP)

				desiredHub.Emit(event)

				events := events.NewEventSource(reader)
				actualEvent, err := events.Next()
				Expect(err).NotTo(HaveOccurred())
				Expect(actualEvent).To(Equal(migratedEvent))
			})
		})

		Describe("Subscribe to Actual Events", func() {
			ItStreamsEventsFromHub(&actualHub)
		})
	})

})
<|endoftext|>


<commit_before>// Copyright 2011 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.

// Implementation of TempServer

package httptest

import (
	"fmt"
	"http"
	"net"
)

// A Server is an HTTP server listening on a system-chosen port on the
// local loopback interface, for use in end-to-end HTTP tests.
type Server struct {
	URL      string // base URL of form http://ipaddr:port with no trailing slash
	Listener net.Listener
}

// NewServer starts and returns a new Server.
// The caller should call Close when finished, to shut it down.
func NewServer(handler http.Handler) *Server {
	ts := new(Server)
	l, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		if l, err = net.Listen("tcp6", "[::1]:0"); err != nil {
			panic(fmt.Sprintf("httptest: failed to listen on a port: %v", err))
		}
	}
	ts.Listener = l
	ts.URL = "http://" + l.Addr().String()
	server := &http.Server{Handler: handler}
	go server.Serve(l)
	return ts
}

// Close shuts down the temporary server.
func (s *Server) Close() {
	s.Listener.Close()
}
<commit_msg>httptest: fix docs out-of-sync from earlier renaming<commit_after>// Copyright 2011 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.

// Implementation of Server

package httptest

import (
	"fmt"
	"http"
	"net"
)

// A Server is an HTTP server listening on a system-chosen port on the
// local loopback interface, for use in end-to-end HTTP tests.
type Server struct {
	URL      string // base URL of form http://ipaddr:port with no trailing slash
	Listener net.Listener
}

// NewServer starts and returns a new Server.
// The caller should call Close when finished, to shut it down.
func NewServer(handler http.Handler) *Server {
	ts := new(Server)
	l, err := net.Listen("tcp", "127.0.0.1:0")
	if err != nil {
		if l, err = net.Listen("tcp6", "[::1]:0"); err != nil {
			panic(fmt.Sprintf("httptest: failed to listen on a port: %v", err))
		}
	}
	ts.Listener = l
	ts.URL = "http://" + l.Addr().String()
	server := &http.Server{Handler: handler}
	go server.Serve(l)
	return ts
}

// Close shuts down the server.
func (s *Server) Close() {
	s.Listener.Close()
}
<|endoftext|>


<commit_before>// Copyright 2012 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 strings_test

import (
	"fmt"
	"strings"
)

// Fields are: ["foo" "bar" "baz"]
func ExampleFields() {
	fmt.Printf("Fields are: %q", strings.Fields("  foo bar  baz   "))
}
<commit_msg>strings: more examples<commit_after>// Copyright 2012 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 strings_test

import (
	"fmt"
	"strings"
)

// Fields are: ["foo" "bar" "baz"]
func ExampleFields() {
	fmt.Printf("Fields are: %q", strings.Fields("  foo bar  baz   "))
}

// true
// false
// true
// true
func ExampleContains() {
	fmt.Println(strings.Contains("seafood", "foo"))
	fmt.Println(strings.Contains("seafood", "bar"))
	fmt.Println(strings.Contains("seafood", ""))
	fmt.Println(strings.Contains("", ""))
}

// false
// true
// false
// false
func ExampleContainsAny() {
	fmt.Println(strings.ContainsAny("team", "i"))
	fmt.Println(strings.ContainsAny("failure", "u & i"))
	fmt.Println(strings.ContainsAny("foo", ""))
	fmt.Println(strings.ContainsAny("", ""))

}

// 3
// 5
func ExampleCount() {
	fmt.Println(strings.Count("cheese", "e"))
	fmt.Println(strings.Count("five", "")) // before & after each rune
}

// true
func ExampleEqualFold() {
	fmt.Println(strings.EqualFold("Go", "go"))
}

// 4
// -1
func ExampleIndex() {
	fmt.Println(strings.Index("chicken", "ken"))
	fmt.Println(strings.Index("chicken", "dmr"))
}

// 4
// -1
func ExampleRune() {
	fmt.Println(strings.IndexRune("chicken", 'k'))
	fmt.Println(strings.IndexRune("chicken", 'd'))
}

// 0
// 3
// -1
func ExampleLastIndex() {
	fmt.Println(strings.Index("go gopher", "go"))
	fmt.Println(strings.LastIndex("go gopher", "go"))
	fmt.Println(strings.LastIndex("go gopher", "rodent"))
}

// foo, bar, baz
func ExampleJoin() {
	s := []string{"foo", "bar", "baz"}
	fmt.Println(strings.Join(s, ", "))
}

// banana
func ExampleRepeat() {
	fmt.Println("ba" + strings.Repeat("na", 2))
}

// oinky oinky oink
// moo moo moo
func ExampleReplace() {
	fmt.Println(strings.Replace("oink oink oink", "k", "ky", 2))
	fmt.Println(strings.Replace("oink oink oink", "oink", "moo", -1))
}

// ["a" "b" "c"]
// ["" "man " "plan " "canal panama"]
// [" " "x" "y" "z" " "]
func ExampleSplit() {
	fmt.Printf("%q\n", strings.Split("a,b,c", ","))
	fmt.Printf("%q\n", strings.Split("a man a plan a canal panama", "a "))
	fmt.Printf("%q\n", strings.Split(" xyz ", ""))
}

// ["a" "b,c"]
// [] (nil = true)
func ExampleSplitN() {
	fmt.Printf("%q\n", strings.SplitN("a,b,c", ",", 2))
	z := strings.SplitN("a,b,c", ",", 0)
	fmt.Printf("%q (nil = %v)\n", z, z == nil)
}

// ["a," "b," "c"]
func ExampleSplitAfter() {
	fmt.Printf("%q\n", strings.SplitAfter("a,b,c", ","))
}

// ["a," "b,c"]
func ExampleSplitAfterN() {
	fmt.Printf("%q\n", strings.SplitAfterN("a,b,c", ",", 2))
}

// Her Royal Highness
func ExampleTitle() {
	fmt.Println(strings.Title("her royal highness"))
}

// LOUD NOISES
// ХЛЕБ
func ExampleToTitle() {
	fmt.Println(strings.ToTitle("loud noises"))
	fmt.Println(strings.ToTitle("хлеб"))
}

// [Achtung]
func ExampleTrim() {
	fmt.Printf("[%s]", strings.Trim(" !!! Achtung !!! ", "! "))
}

// 'Gjnf oevyyvt naq gur fyvgul tbcure...
func ExampleMap() {
	rot13 := func(r rune) rune {
		switch {
		case r >= 'A' && r <= 'Z':
			return 'A' + (r-'A'+13)%26
		case r >= 'a' && r <= 'z':
			return 'a' + (r-'a'+13)%26
		}
		return r
	}
	fmt.Println(strings.Map(rot13, "'Twas brillig and the slithy gopher..."))
}

// a lone gopher
func ExampleTrimSpace() {
	fmt.Println(strings.TrimSpace(" \t\n a lone gopher \n\t\r\n"))
}

// This is HTML!
func ExampleNewReplacer() {
	r := strings.NewReplacer("<", "<", ">", ">")
	fmt.Println(r.Replace("This is HTML!"))
}

// GOPHER
func ExampleToUpper() {
	fmt.Println(strings.ToUpper("Gopher"))
}

// gopher
func ExampleToLower() {
	fmt.Println(strings.ToLower("Gopher"))
}
<|endoftext|>


<commit_before>// Copyright 2012 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 strings_test

import (
	"fmt"
	"strings"
	"unicode"
)

func ExampleFields() {
	fmt.Printf("Fields are: %q", strings.Fields("  foo bar  baz   "))
	// Output: Fields are: ["foo" "bar" "baz"]
}

func ExampleFieldsFunc() {
	f := func(c rune) bool {
		return !unicode.IsLetter(c) && !unicode.IsNumber(c)
	}
	fmt.Printf("Fields are: %q", strings.FieldsFunc("  foo1;bar2,baz3...", f))
	// Output: Fields are: ["foo1" "bar2" "baz3"]
}

func ExampleContains() {
	fmt.Println(strings.Contains("seafood", "foo"))
	fmt.Println(strings.Contains("seafood", "bar"))
	fmt.Println(strings.Contains("seafood", ""))
	fmt.Println(strings.Contains("", ""))
	// Output:
	// true
	// false
	// true
	// true
}

func ExampleContainsAny() {
	fmt.Println(strings.ContainsAny("team", "i"))
	fmt.Println(strings.ContainsAny("failure", "u & i"))
	fmt.Println(strings.ContainsAny("foo", ""))
	fmt.Println(strings.ContainsAny("", ""))
	// Output:
	// false
	// true
	// false
	// false
}

func ExampleCount() {
	fmt.Println(strings.Count("cheese", "e"))
	fmt.Println(strings.Count("five", "")) // before & after each rune
	// Output:
	// 3
	// 5
}

func ExampleEqualFold() {
	fmt.Println(strings.EqualFold("Go", "go"))
	// Output: true
}

func ExampleIndex() {
	fmt.Println(strings.Index("chicken", "ken"))
	fmt.Println(strings.Index("chicken", "dmr"))
	// Output:
	// 4
	// -1
}

func ExampleIndexFunc() {
	f := func(c rune) bool {
		return unicode.Is(unicode.Han, c)
	}
	fmt.Println(strings.IndexFunc("Hello, 世界", f))
	fmt.Println(strings.IndexFunc("Hello, world", f))
	// Output:
	// 7
	// -1
}

func ExampleIndexRune() {
	fmt.Println(strings.IndexRune("chicken", 'k'))
	fmt.Println(strings.IndexRune("chicken", 'd'))
	// Output:
	// 4
	// -1
}

func ExampleLastIndex() {
	fmt.Println(strings.Index("go gopher", "go"))
	fmt.Println(strings.LastIndex("go gopher", "go"))
	fmt.Println(strings.LastIndex("go gopher", "rodent"))
	// Output:
	// 0
	// 3
	// -1
}

func ExampleJoin() {
	s := []string{"foo", "bar", "baz"}
	fmt.Println(strings.Join(s, ", "))
	// Output: foo, bar, baz
}

func ExampleRepeat() {
	fmt.Println("ba" + strings.Repeat("na", 2))
	// Output: banana
}

func ExampleReplace() {
	fmt.Println(strings.Replace("oink oink oink", "k", "ky", 2))
	fmt.Println(strings.Replace("oink oink oink", "oink", "moo", -1))
	// Output:
	// oinky oinky oink
	// moo moo moo
}

func ExampleSplit() {
	fmt.Printf("%q\n", strings.Split("a,b,c", ","))
	fmt.Printf("%q\n", strings.Split("a man a plan a canal panama", "a "))
	fmt.Printf("%q\n", strings.Split(" xyz ", ""))
	fmt.Printf("%q\n", strings.Split("", "Bernardo O'Higgins"))
	// Output:
	// ["a" "b" "c"]
	// ["" "man " "plan " "canal panama"]
	// [" " "x" "y" "z" " "]
	// [""]
}

func ExampleSplitN() {
	fmt.Printf("%q\n", strings.SplitN("a,b,c", ",", 2))
	z := strings.SplitN("a,b,c", ",", 0)
	fmt.Printf("%q (nil = %v)\n", z, z == nil)
	// Output:
	// ["a" "b,c"]
	// [] (nil = true)
}

func ExampleSplitAfter() {
	fmt.Printf("%q\n", strings.SplitAfter("a,b,c", ","))
	// Output: ["a," "b," "c"]
}

func ExampleSplitAfterN() {
	fmt.Printf("%q\n", strings.SplitAfterN("a,b,c", ",", 2))
	// Output: ["a," "b,c"]
}

func ExampleTitle() {
	fmt.Println(strings.Title("her royal highness"))
	// Output: Her Royal Highness
}

func ExampleToTitle() {
	fmt.Println(strings.ToTitle("loud noises"))
	fmt.Println(strings.ToTitle("хлеб"))
	// Output:
	// LOUD NOISES
	// ХЛЕБ
}

func ExampleTrim() {
	fmt.Printf("[%q]", strings.Trim(" !!! Achtung! Achtung! !!! ", "! "))
	// Output: ["Achtung! Achtung"]
}

func ExampleMap() {
	rot13 := func(r rune) rune {
		switch {
		case r >= 'A' && r <= 'Z':
			return 'A' + (r-'A'+13)%26
		case r >= 'a' && r <= 'z':
			return 'a' + (r-'a'+13)%26
		}
		return r
	}
	fmt.Println(strings.Map(rot13, "'Twas brillig and the slithy gopher..."))
	// Output: 'Gjnf oevyyvt naq gur fyvgul tbcure...
}

func ExampleTrimSpace() {
	fmt.Println(strings.TrimSpace(" \t\n a lone gopher \n\t\r\n"))
	// Output: a lone gopher
}

func ExampleNewReplacer() {
	r := strings.NewReplacer("<", "<", ">", ">")
	fmt.Println(r.Replace("This is HTML!"))
	// Output: This is <b>HTML</b>!
}

func ExampleToUpper() {
	fmt.Println(strings.ToUpper("Gopher"))
	// Output: GOPHER
}

func ExampleToLower() {
	fmt.Println(strings.ToLower("Gopher"))
	// Output: gopher
}

func ExampleTrimSuffix() {
	var s = "Hello, goodbye, etc!"
	s = strings.TrimSuffix(s, "goodbye, etc!")
	s = strings.TrimSuffix(s, "planet")
	fmt.Print(s, "world!")
	// Output: Hello, world!
}

func ExampleTrimPrefix() {
	var s = "Goodbye,, world!"
	s = strings.TrimPrefix(s, "Goodbye,")
	s = strings.TrimPrefix(s, "Howdy,")
	fmt.Print("Hello" + s)
	// Output: Hello, world!
}
<commit_msg>strings: Add example function for IndexAny<commit_after>// Copyright 2012 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 strings_test

import (
	"fmt"
	"strings"
	"unicode"
)

func ExampleFields() {
	fmt.Printf("Fields are: %q", strings.Fields("  foo bar  baz   "))
	// Output: Fields are: ["foo" "bar" "baz"]
}

func ExampleFieldsFunc() {
	f := func(c rune) bool {
		return !unicode.IsLetter(c) && !unicode.IsNumber(c)
	}
	fmt.Printf("Fields are: %q", strings.FieldsFunc("  foo1;bar2,baz3...", f))
	// Output: Fields are: ["foo1" "bar2" "baz3"]
}

func ExampleContains() {
	fmt.Println(strings.Contains("seafood", "foo"))
	fmt.Println(strings.Contains("seafood", "bar"))
	fmt.Println(strings.Contains("seafood", ""))
	fmt.Println(strings.Contains("", ""))
	// Output:
	// true
	// false
	// true
	// true
}

func ExampleContainsAny() {
	fmt.Println(strings.ContainsAny("team", "i"))
	fmt.Println(strings.ContainsAny("failure", "u & i"))
	fmt.Println(strings.ContainsAny("foo", ""))
	fmt.Println(strings.ContainsAny("", ""))
	// Output:
	// false
	// true
	// false
	// false
}

func ExampleCount() {
	fmt.Println(strings.Count("cheese", "e"))
	fmt.Println(strings.Count("five", "")) // before & after each rune
	// Output:
	// 3
	// 5
}

func ExampleEqualFold() {
	fmt.Println(strings.EqualFold("Go", "go"))
	// Output: true
}

func ExampleIndex() {
	fmt.Println(strings.Index("chicken", "ken"))
	fmt.Println(strings.Index("chicken", "dmr"))
	// Output:
	// 4
	// -1
}

func ExampleIndexFunc() {
	f := func(c rune) bool {
		return unicode.Is(unicode.Han, c)
	}
	fmt.Println(strings.IndexFunc("Hello, 世界", f))
	fmt.Println(strings.IndexFunc("Hello, world", f))
	// Output:
	// 7
	// -1
}

func ExampleIndexAny() {
	fmt.Println(strings.IndexAny("chicken", "aeiouy"))
	fmt.Println(strings.IndexAny("crwth", "aeiouy"))
	// Output:
	// 2
	// -1
}

func ExampleIndexRune() {
	fmt.Println(strings.IndexRune("chicken", 'k'))
	fmt.Println(strings.IndexRune("chicken", 'd'))
	// Output:
	// 4
	// -1
}

func ExampleLastIndex() {
	fmt.Println(strings.Index("go gopher", "go"))
	fmt.Println(strings.LastIndex("go gopher", "go"))
	fmt.Println(strings.LastIndex("go gopher", "rodent"))
	// Output:
	// 0
	// 3
	// -1
}

func ExampleJoin() {
	s := []string{"foo", "bar", "baz"}
	fmt.Println(strings.Join(s, ", "))
	// Output: foo, bar, baz
}

func ExampleRepeat() {
	fmt.Println("ba" + strings.Repeat("na", 2))
	// Output: banana
}

func ExampleReplace() {
	fmt.Println(strings.Replace("oink oink oink", "k", "ky", 2))
	fmt.Println(strings.Replace("oink oink oink", "oink", "moo", -1))
	// Output:
	// oinky oinky oink
	// moo moo moo
}

func ExampleSplit() {
	fmt.Printf("%q\n", strings.Split("a,b,c", ","))
	fmt.Printf("%q\n", strings.Split("a man a plan a canal panama", "a "))
	fmt.Printf("%q\n", strings.Split(" xyz ", ""))
	fmt.Printf("%q\n", strings.Split("", "Bernardo O'Higgins"))
	// Output:
	// ["a" "b" "c"]
	// ["" "man " "plan " "canal panama"]
	// [" " "x" "y" "z" " "]
	// [""]
}

func ExampleSplitN() {
	fmt.Printf("%q\n", strings.SplitN("a,b,c", ",", 2))
	z := strings.SplitN("a,b,c", ",", 0)
	fmt.Printf("%q (nil = %v)\n", z, z == nil)
	// Output:
	// ["a" "b,c"]
	// [] (nil = true)
}

func ExampleSplitAfter() {
	fmt.Printf("%q\n", strings.SplitAfter("a,b,c", ","))
	// Output: ["a," "b," "c"]
}

func ExampleSplitAfterN() {
	fmt.Printf("%q\n", strings.SplitAfterN("a,b,c", ",", 2))
	// Output: ["a," "b,c"]
}

func ExampleTitle() {
	fmt.Println(strings.Title("her royal highness"))
	// Output: Her Royal Highness
}

func ExampleToTitle() {
	fmt.Println(strings.ToTitle("loud noises"))
	fmt.Println(strings.ToTitle("хлеб"))
	// Output:
	// LOUD NOISES
	// ХЛЕБ
}

func ExampleTrim() {
	fmt.Printf("[%q]", strings.Trim(" !!! Achtung! Achtung! !!! ", "! "))
	// Output: ["Achtung! Achtung"]
}

func ExampleMap() {
	rot13 := func(r rune) rune {
		switch {
		case r >= 'A' && r <= 'Z':
			return 'A' + (r-'A'+13)%26
		case r >= 'a' && r <= 'z':
			return 'a' + (r-'a'+13)%26
		}
		return r
	}
	fmt.Println(strings.Map(rot13, "'Twas brillig and the slithy gopher..."))
	// Output: 'Gjnf oevyyvt naq gur fyvgul tbcure...
}

func ExampleTrimSpace() {
	fmt.Println(strings.TrimSpace(" \t\n a lone gopher \n\t\r\n"))
	// Output: a lone gopher
}

func ExampleNewReplacer() {
	r := strings.NewReplacer("<", "<", ">", ">")
	fmt.Println(r.Replace("This is HTML!"))
	// Output: This is <b>HTML</b>!
}

func ExampleToUpper() {
	fmt.Println(strings.ToUpper("Gopher"))
	// Output: GOPHER
}

func ExampleToLower() {
	fmt.Println(strings.ToLower("Gopher"))
	// Output: gopher
}

func ExampleTrimSuffix() {
	var s = "Hello, goodbye, etc!"
	s = strings.TrimSuffix(s, "goodbye, etc!")
	s = strings.TrimSuffix(s, "planet")
	fmt.Print(s, "world!")
	// Output: Hello, world!
}

func ExampleTrimPrefix() {
	var s = "Goodbye,, world!"
	s = strings.TrimPrefix(s, "Goodbye,")
	s = strings.TrimPrefix(s, "Howdy,")
	fmt.Print("Hello" + s)
	// Output: Hello, world!
}
<|endoftext|>


<commit_before>package scanner

import (
	"bufio"
	"encoding/gob"
	"errors"
	"fmt"
	"github.com/Symantec/Dominator/lib/fsutil"
	"github.com/Symantec/Dominator/lib/image"
	"github.com/proxypoke/group.go"
	"io"
	"log"
	"os"
	"os/user"
	"path"
	"syscall"
)

const (
	dirPerms = syscall.S_IRWXU | syscall.S_IRGRP | syscall.S_IXGRP |
		syscall.S_IROTH | syscall.S_IXOTH
	filePerms = syscall.S_IRUSR | syscall.S_IWUSR | syscall.S_IRGRP |
		syscall.S_IROTH
)

func (imdb *ImageDataBase) addImage(image *image.Image, name string,
	username *string) error {
	if err := image.Verify(); err != nil {
		return err
	}
	imdb.Lock()
	defer imdb.Unlock()
	if _, ok := imdb.imageMap[name]; ok {
		return errors.New("image: " + name + " already exists")
	} else {
		err := imdb.checkDirectoryPermissions(path.Dir(name), username)
		if err != nil {
			return err
		}
		filename := path.Join(imdb.baseDir, name)
		file, err := os.OpenFile(filename, os.O_CREATE|os.O_EXCL|os.O_RDWR,
			filePerms)
		if err != nil {
			if os.IsExist(err) {
				return errors.New("cannot add a previously deleted image")
			}
			return err
		}
		defer file.Close()
		w := bufio.NewWriter(file)
		defer w.Flush()
		writer := fsutil.NewChecksumWriter(w)
		defer writer.WriteChecksum()
		encoder := gob.NewEncoder(writer)
		encoder.Encode(image)
		imdb.imageMap[name] = image
		imdb.addNotifiers.sendPlain(name, "add", imdb.logger)
		return nil
	}
}

// This must be called with the lock held.
func (imdb *ImageDataBase) checkDirectoryPermissions(dirname string,
	username *string) error {
	if username == nil {
		return nil
	}
	directoryMetadata, ok := imdb.directoryMap[dirname]
	if !ok {
		return fmt.Errorf("no metadata for: \"%s\"", dirname)
	}
	if directoryMetadata.OwnerGroup == "" {
		return nil
	}
	if *username == "" {
		return errors.New("no username: unauthenticated connection")
	}
	return checkUserInGroup(*username, directoryMetadata.OwnerGroup)
}

func (imdb *ImageDataBase) checkImage(name string) bool {
	imdb.RLock()
	defer imdb.RUnlock()
	_, ok := imdb.imageMap[name]
	return ok
}

func (imdb *ImageDataBase) chownDirectory(dirname, ownerGroup string) error {
	dirname = path.Clean(dirname)
	imdb.RLock()
	directoryMetadata, ok := imdb.directoryMap[dirname]
	imdb.RUnlock()
	if !ok {
		return fmt.Errorf("no metadata for: \"%s\"", dirname)
	}
	directoryMetadata.OwnerGroup = ownerGroup
	imdb.Lock()
	defer imdb.Unlock()
	return imdb.updateDirectoryMetadata(
		image.Directory{Name: dirname, Metadata: directoryMetadata})
}

// This must be called with the lock held.
func (imdb *ImageDataBase) updateDirectoryMetadata(
	directory image.Directory) error {
	oldDirectoryMetadata, ok := imdb.directoryMap[directory.Name]
	if ok && directory.Metadata == oldDirectoryMetadata {
		return nil
	}
	if err := imdb.updateDirectoryMetadataFile(directory); err != nil {
		return err
	}
	imdb.directoryMap[directory.Name] = directory.Metadata
	imdb.mkdirNotifiers.sendMakeDirectory(directory, imdb.logger)
	return nil
}

func (imdb *ImageDataBase) updateDirectoryMetadataFile(
	directory image.Directory) error {
	filename := path.Join(imdb.baseDir, directory.Name, metadataFile)
	oldDirectoryMetadata, ok := imdb.directoryMap[directory.Name]
	if oldDirectoryMetadata == (image.DirectoryMetadata{}) {
		if !ok {
			return nil
		}
		return os.Remove(filename)
	}
	file, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, filePerms)
	if err != nil {
		return err
	}
	if err := writeDirectoryMetadata(file, directory.Metadata); err != nil {
		file.Close()
		return err
	}
	return file.Close()
}

func writeDirectoryMetadata(file io.Writer,
	directoryMetadata image.DirectoryMetadata) error {
	w := bufio.NewWriter(file)
	writer := fsutil.NewChecksumWriter(w)
	if err := gob.NewEncoder(writer).Encode(directoryMetadata); err != nil {
		return err
	}
	if err := writer.WriteChecksum(); err != nil {
		return err
	}
	return w.Flush()
}

func (imdb *ImageDataBase) countDirectories() uint {
	imdb.RLock()
	defer imdb.RUnlock()
	return uint(len(imdb.directoryMap))
}

func (imdb *ImageDataBase) countImages() uint {
	imdb.RLock()
	defer imdb.RUnlock()
	return uint(len(imdb.imageMap))
}

func (imdb *ImageDataBase) deleteImage(name string, username *string) error {
	imdb.Lock()
	defer imdb.Unlock()
	if _, ok := imdb.imageMap[name]; ok {
		err := imdb.checkDirectoryPermissions(path.Dir(name), username)
		if err != nil {
			return err
		}
		filename := path.Join(imdb.baseDir, name)
		if err := os.Truncate(filename, 0); err != nil {
			return err
		}
		delete(imdb.imageMap, name)
		imdb.deleteNotifiers.sendPlain(name, "delete", imdb.logger)
		return nil
	} else {
		return errors.New("image: " + name + " does not exist")
	}
}

func (imdb *ImageDataBase) getImage(name string) *image.Image {
	imdb.RLock()
	defer imdb.RUnlock()
	return imdb.imageMap[name]
}

func (imdb *ImageDataBase) listDirectories() []image.Directory {
	imdb.RLock()
	defer imdb.RUnlock()
	directories := make([]image.Directory, 0, len(imdb.directoryMap))
	for name, metadata := range imdb.directoryMap {
		directories = append(directories,
			image.Directory{Name: name, Metadata: metadata})
	}
	return directories
}

func (imdb *ImageDataBase) listImages() []string {
	imdb.RLock()
	defer imdb.RUnlock()
	names := make([]string, 0)
	for name := range imdb.imageMap {
		names = append(names, name)
	}
	return names
}

func (imdb *ImageDataBase) makeDirectory(directory image.Directory,
	username string, userRpc bool) error {
	directory.Name = path.Clean(directory.Name)
	pathname := path.Join(imdb.baseDir, directory.Name)
	imdb.Lock()
	defer imdb.Unlock()
	oldDirectoryMetadata, ok := imdb.directoryMap[directory.Name]
	if userRpc {
		if ok {
			return fmt.Errorf("directory: %s already exists", directory.Name)
		}
		directory.Metadata = oldDirectoryMetadata
		parentMetadata, ok := imdb.directoryMap[path.Dir(directory.Name)]
		if !ok {
			return fmt.Errorf("no metadata for: %s", path.Dir(directory.Name))
		}
		if parentMetadata.OwnerGroup != "" {
			if err := checkUserInGroup(username,
				parentMetadata.OwnerGroup); err != nil {
				return err
			}
		}
		directory.Metadata.OwnerGroup = parentMetadata.OwnerGroup
	}
	if err := os.Mkdir(pathname, dirPerms); err != nil && !os.IsExist(err) {
		return err
	}
	return imdb.updateDirectoryMetadata(directory)
}

func checkUserInGroup(username, ownerGroup string) error {
	userData, err := user.Lookup(username)
	if err != nil {
		return err
	}
	groupData, err := group.Lookup(ownerGroup)
	if err != nil {
		return err
	}
	if userData.Gid == groupData.Gid {
		return nil
	}
	for _, member := range groupData.Members {
		if username == member {
			return nil
		}
	}
	return fmt.Errorf("user: %s not a member of: %s", username, ownerGroup)
}

func (imdb *ImageDataBase) registerAddNotifier() <-chan string {
	channel := make(chan string, 1)
	imdb.Lock()
	defer imdb.Unlock()
	imdb.addNotifiers[channel] = channel
	return channel
}

func (imdb *ImageDataBase) registerDeleteNotifier() <-chan string {
	channel := make(chan string, 1)
	imdb.Lock()
	defer imdb.Unlock()
	imdb.deleteNotifiers[channel] = channel
	return channel
}

func (imdb *ImageDataBase) registerMakeDirectoryNotifier() <-chan image.Directory {
	channel := make(chan image.Directory, 1)
	imdb.Lock()
	defer imdb.Unlock()
	imdb.mkdirNotifiers[channel] = channel
	return channel
}

func (imdb *ImageDataBase) unregisterAddNotifier(channel <-chan string) {
	imdb.Lock()
	defer imdb.Unlock()
	delete(imdb.addNotifiers, channel)
}

func (imdb *ImageDataBase) unregisterDeleteNotifier(channel <-chan string) {
	imdb.Lock()
	defer imdb.Unlock()
	delete(imdb.deleteNotifiers, channel)
}

func (imdb *ImageDataBase) unregisterMakeDirectoryNotifier(
	channel <-chan image.Directory) {
	imdb.Lock()
	defer imdb.Unlock()
	delete(imdb.mkdirNotifiers, channel)
}

func (n notifiers) sendPlain(name string, operation string,
	logger *log.Logger) {
	if len(n) < 1 {
		return
	} else {
		plural := "s"
		if len(n) < 2 {
			plural = ""
		}
		logger.Printf("Sending %s notification to: %d listener%s\n",
			operation, len(n), plural)
	}
	for _, sendChannel := range n {
		go func(channel chan<- string) {
			channel <- name
		}(sendChannel)
	}
}

func (n makeDirectoryNotifiers) sendMakeDirectory(dir image.Directory,
	logger *log.Logger) {
	if len(n) < 1 {
		return
	} else {
		plural := "s"
		if len(n) < 2 {
			plural = ""
		}
		logger.Printf("Sending mkdir notification to: %d listener%s\n",
			len(n), plural)
	}
	for _, sendChannel := range n {
		go func(channel chan<- image.Directory) {
			channel <- dir
		}(sendChannel)
	}
}
<commit_msg>Fix bug in imageserver when first changing ownership of a directory.<commit_after>package scanner

import (
	"bufio"
	"encoding/gob"
	"errors"
	"fmt"
	"github.com/Symantec/Dominator/lib/fsutil"
	"github.com/Symantec/Dominator/lib/image"
	"github.com/proxypoke/group.go"
	"io"
	"log"
	"os"
	"os/user"
	"path"
	"syscall"
)

const (
	dirPerms = syscall.S_IRWXU | syscall.S_IRGRP | syscall.S_IXGRP |
		syscall.S_IROTH | syscall.S_IXOTH
	filePerms = syscall.S_IRUSR | syscall.S_IWUSR | syscall.S_IRGRP |
		syscall.S_IROTH
)

func (imdb *ImageDataBase) addImage(image *image.Image, name string,
	username *string) error {
	if err := image.Verify(); err != nil {
		return err
	}
	imdb.Lock()
	defer imdb.Unlock()
	if _, ok := imdb.imageMap[name]; ok {
		return errors.New("image: " + name + " already exists")
	} else {
		err := imdb.checkDirectoryPermissions(path.Dir(name), username)
		if err != nil {
			return err
		}
		filename := path.Join(imdb.baseDir, name)
		file, err := os.OpenFile(filename, os.O_CREATE|os.O_EXCL|os.O_RDWR,
			filePerms)
		if err != nil {
			if os.IsExist(err) {
				return errors.New("cannot add a previously deleted image")
			}
			return err
		}
		defer file.Close()
		w := bufio.NewWriter(file)
		defer w.Flush()
		writer := fsutil.NewChecksumWriter(w)
		defer writer.WriteChecksum()
		encoder := gob.NewEncoder(writer)
		encoder.Encode(image)
		imdb.imageMap[name] = image
		imdb.addNotifiers.sendPlain(name, "add", imdb.logger)
		return nil
	}
}

// This must be called with the lock held.
func (imdb *ImageDataBase) checkDirectoryPermissions(dirname string,
	username *string) error {
	if username == nil {
		return nil
	}
	directoryMetadata, ok := imdb.directoryMap[dirname]
	if !ok {
		return fmt.Errorf("no metadata for: \"%s\"", dirname)
	}
	if directoryMetadata.OwnerGroup == "" {
		return nil
	}
	if *username == "" {
		return errors.New("no username: unauthenticated connection")
	}
	return checkUserInGroup(*username, directoryMetadata.OwnerGroup)
}

func (imdb *ImageDataBase) checkImage(name string) bool {
	imdb.RLock()
	defer imdb.RUnlock()
	_, ok := imdb.imageMap[name]
	return ok
}

func (imdb *ImageDataBase) chownDirectory(dirname, ownerGroup string) error {
	dirname = path.Clean(dirname)
	imdb.RLock()
	directoryMetadata, ok := imdb.directoryMap[dirname]
	imdb.RUnlock()
	if !ok {
		return fmt.Errorf("no metadata for: \"%s\"", dirname)
	}
	directoryMetadata.OwnerGroup = ownerGroup
	imdb.Lock()
	defer imdb.Unlock()
	return imdb.updateDirectoryMetadata(
		image.Directory{Name: dirname, Metadata: directoryMetadata})
}

// This must be called with the lock held.
func (imdb *ImageDataBase) updateDirectoryMetadata(
	directory image.Directory) error {
	oldDirectoryMetadata, ok := imdb.directoryMap[directory.Name]
	if ok && directory.Metadata == oldDirectoryMetadata {
		return nil
	}
	if err := imdb.updateDirectoryMetadataFile(directory); err != nil {
		return err
	}
	imdb.directoryMap[directory.Name] = directory.Metadata
	imdb.mkdirNotifiers.sendMakeDirectory(directory, imdb.logger)
	return nil
}

func (imdb *ImageDataBase) updateDirectoryMetadataFile(
	directory image.Directory) error {
	filename := path.Join(imdb.baseDir, directory.Name, metadataFile)
	_, ok := imdb.directoryMap[directory.Name]
	if directory.Metadata == (image.DirectoryMetadata{}) {
		if !ok {
			return nil
		}
		return os.Remove(filename)
	}
	file, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, filePerms)
	if err != nil {
		return err
	}
	if err := writeDirectoryMetadata(file, directory.Metadata); err != nil {
		file.Close()
		return err
	}
	return file.Close()
}

func writeDirectoryMetadata(file io.Writer,
	directoryMetadata image.DirectoryMetadata) error {
	w := bufio.NewWriter(file)
	writer := fsutil.NewChecksumWriter(w)
	if err := gob.NewEncoder(writer).Encode(directoryMetadata); err != nil {
		return err
	}
	if err := writer.WriteChecksum(); err != nil {
		return err
	}
	return w.Flush()
}

func (imdb *ImageDataBase) countDirectories() uint {
	imdb.RLock()
	defer imdb.RUnlock()
	return uint(len(imdb.directoryMap))
}

func (imdb *ImageDataBase) countImages() uint {
	imdb.RLock()
	defer imdb.RUnlock()
	return uint(len(imdb.imageMap))
}

func (imdb *ImageDataBase) deleteImage(name string, username *string) error {
	imdb.Lock()
	defer imdb.Unlock()
	if _, ok := imdb.imageMap[name]; ok {
		err := imdb.checkDirectoryPermissions(path.Dir(name), username)
		if err != nil {
			return err
		}
		filename := path.Join(imdb.baseDir, name)
		if err := os.Truncate(filename, 0); err != nil {
			return err
		}
		delete(imdb.imageMap, name)
		imdb.deleteNotifiers.sendPlain(name, "delete", imdb.logger)
		return nil
	} else {
		return errors.New("image: " + name + " does not exist")
	}
}

func (imdb *ImageDataBase) getImage(name string) *image.Image {
	imdb.RLock()
	defer imdb.RUnlock()
	return imdb.imageMap[name]
}

func (imdb *ImageDataBase) listDirectories() []image.Directory {
	imdb.RLock()
	defer imdb.RUnlock()
	directories := make([]image.Directory, 0, len(imdb.directoryMap))
	for name, metadata := range imdb.directoryMap {
		directories = append(directories,
			image.Directory{Name: name, Metadata: metadata})
	}
	return directories
}

func (imdb *ImageDataBase) listImages() []string {
	imdb.RLock()
	defer imdb.RUnlock()
	names := make([]string, 0)
	for name := range imdb.imageMap {
		names = append(names, name)
	}
	return names
}

func (imdb *ImageDataBase) makeDirectory(directory image.Directory,
	username string, userRpc bool) error {
	directory.Name = path.Clean(directory.Name)
	pathname := path.Join(imdb.baseDir, directory.Name)
	imdb.Lock()
	defer imdb.Unlock()
	oldDirectoryMetadata, ok := imdb.directoryMap[directory.Name]
	if userRpc {
		if ok {
			return fmt.Errorf("directory: %s already exists", directory.Name)
		}
		directory.Metadata = oldDirectoryMetadata
		parentMetadata, ok := imdb.directoryMap[path.Dir(directory.Name)]
		if !ok {
			return fmt.Errorf("no metadata for: %s", path.Dir(directory.Name))
		}
		if parentMetadata.OwnerGroup != "" {
			if err := checkUserInGroup(username,
				parentMetadata.OwnerGroup); err != nil {
				return err
			}
		}
		directory.Metadata.OwnerGroup = parentMetadata.OwnerGroup
	}
	if err := os.Mkdir(pathname, dirPerms); err != nil && !os.IsExist(err) {
		return err
	}
	return imdb.updateDirectoryMetadata(directory)
}

func checkUserInGroup(username, ownerGroup string) error {
	userData, err := user.Lookup(username)
	if err != nil {
		return err
	}
	groupData, err := group.Lookup(ownerGroup)
	if err != nil {
		return err
	}
	if userData.Gid == groupData.Gid {
		return nil
	}
	for _, member := range groupData.Members {
		if username == member {
			return nil
		}
	}
	return fmt.Errorf("user: %s not a member of: %s", username, ownerGroup)
}

func (imdb *ImageDataBase) registerAddNotifier() <-chan string {
	channel := make(chan string, 1)
	imdb.Lock()
	defer imdb.Unlock()
	imdb.addNotifiers[channel] = channel
	return channel
}

func (imdb *ImageDataBase) registerDeleteNotifier() <-chan string {
	channel := make(chan string, 1)
	imdb.Lock()
	defer imdb.Unlock()
	imdb.deleteNotifiers[channel] = channel
	return channel
}

func (imdb *ImageDataBase) registerMakeDirectoryNotifier() <-chan image.Directory {
	channel := make(chan image.Directory, 1)
	imdb.Lock()
	defer imdb.Unlock()
	imdb.mkdirNotifiers[channel] = channel
	return channel
}

func (imdb *ImageDataBase) unregisterAddNotifier(channel <-chan string) {
	imdb.Lock()
	defer imdb.Unlock()
	delete(imdb.addNotifiers, channel)
}

func (imdb *ImageDataBase) unregisterDeleteNotifier(channel <-chan string) {
	imdb.Lock()
	defer imdb.Unlock()
	delete(imdb.deleteNotifiers, channel)
}

func (imdb *ImageDataBase) unregisterMakeDirectoryNotifier(
	channel <-chan image.Directory) {
	imdb.Lock()
	defer imdb.Unlock()
	delete(imdb.mkdirNotifiers, channel)
}

func (n notifiers) sendPlain(name string, operation string,
	logger *log.Logger) {
	if len(n) < 1 {
		return
	} else {
		plural := "s"
		if len(n) < 2 {
			plural = ""
		}
		logger.Printf("Sending %s notification to: %d listener%s\n",
			operation, len(n), plural)
	}
	for _, sendChannel := range n {
		go func(channel chan<- string) {
			channel <- name
		}(sendChannel)
	}
}

func (n makeDirectoryNotifiers) sendMakeDirectory(dir image.Directory,
	logger *log.Logger) {
	if len(n) < 1 {
		return
	} else {
		plural := "s"
		if len(n) < 2 {
			plural = ""
		}
		logger.Printf("Sending mkdir notification to: %d listener%s\n",
			len(n), plural)
	}
	for _, sendChannel := range n {
		go func(channel chan<- image.Directory) {
			channel <- dir
		}(sendChannel)
	}
}
<|endoftext|>


<commit_before>package main

/*
    TODO:
        - Read stdin line by line instead of all at once ( http://stackoverflow.com/questions/12363030/read-from-initial-stdin-in-go )
        - Make it use the CSV writer to write out the stuff instead of println
        - Use flag parsing to determine which field(s) to print out
        - Allow writing out the data with a different delimiter than what it came in with
*/

import (
    //"bufio"
    "encoding/csv"
    "flag"
    "fmt"
    "io"
    "io/ioutil"
    "os"
    "strconv"
    "strings"
    "unicode/utf8"
)

var separator = flag.String("separator", ",", "Single character to be used as a separator between fields")
var fieldNumsRaw = flag.String("fieldNums", "", "Comma-separated list of field indexes (starting at 0) to print to the command line")
var outputJoiner = flag.String("outJoinStr", ",", "Separator to use when printing multiple columns in your output. Only valid if outputting something meant to be passed to cut/awk, and not a properly-formatted, quoted CSV file.")

func main() {
    flag.Parse()

    var fieldNums []int

    for _, numStr := range strings.Split(*fieldNumsRaw, ",") {
        numStr := strings.TrimSpace(numStr)
        numInt, err := strconv.Atoi(numStr)
        if err != nil {
            panic(err)
        }
        fieldNums = append(fieldNums, numInt)
    }

    bytes, err := ioutil.ReadAll(os.Stdin)
    if err != nil {
        panic(err)
    }

    lines := strings.Split(string(bytes), "\n")

    for _, line := range lines {
        fields, err := processLine(line)
        if err != nil {
            if err == io.EOF {
                break
            } else {
                panic(err)
            }
        }

        var toPrint []string
        for _, num := range fieldNums {
            toPrint = append(toPrint, fields[num])
        }
        fmt.Println(strings.Join(toPrint, *outputJoiner))
    }
}

func processLine(line string) ([]string, error) {
    strReader := strings.NewReader(line)
    csvReader := csv.NewReader(strReader)

    sepString := *separator
    /*
    fmt.Println("Separator is", string(sepString[0]))
    fmt.Println("'", rune(sepString[0]), "'")
    fmt.Println("'", string(rune("\t"[0])), "'")
    r, size := utf8.DecodeRuneInString(sepString)
    fmt.Println("'", string(r), "'")
    fmt.Println(size)
    */
    _ = utf8.DecodeRuneInString

    csvReader.Comma = rune(sepString[0])

    fields, err := csvReader.Read()
    if err != nil {
        if err == io.EOF {
            return nil, io.EOF
        } else {
            panic(err)
        }
    }

    return fields, nil
}
<commit_msg>Fixed output truncation with CSV dumper, writer now prints out all fields unless otherwise specified<commit_after>package main

/*
    TODO:
        - Read stdin line by line instead of all at once ( http://stackoverflow.com/questions/12363030/read-from-initial-stdin-in-go )
        - Make it use the CSV writer to write out the stuff instead of println
        - Use flag parsing to determine which field(s) to print out
        - Allow writing out the data with a different delimiter than what it came in with
*/

import (
    //"bufio"
    "encoding/csv"
    "flag"
    "fmt"
    "io"
    "io/ioutil"
    "os"
    "strconv"
    "strings"
    "unicode/utf8"
)

var separator = flag.String("separator", ",", "Single character to be used as a separator between fields")
var fieldNumsRaw = flag.String("fieldNums", "", "Comma-separated list of field indexes (starting at 0) to print to the command line")

var noPrintRealCSV = flag.Bool("noPrintCSV", false, "Program defaults to printing valid, quoted, well-formatted CSV. If this flag is supplied, output is returned as a string joined by outJoinStr. noPrintCSV is assumed to imply you want to pass the output to naive tools like cut or awk.")
var outputJoiner = flag.String("outJoinStr", ",", "Separator to use when printing multiple columns in your output. Only valid if outputting something meant to be passed to cut/awk, and not a properly-formatted, quoted CSV file.")

func main() {
    flag.Parse()

    var fieldNums []int

    if *fieldNumsRaw != "" {
        for _, numStr := range strings.Split(*fieldNumsRaw, ",") {
            numStr := strings.TrimSpace(numStr)
            numInt, err := strconv.Atoi(numStr)
            if err != nil {
                panic(err)
            }
            fieldNums = append(fieldNums, numInt)
        }
    }

    // TODO: Make this stream from stdin, and also stream from a file
    bytes, err := ioutil.ReadAll(os.Stdin)
    if err != nil {
        panic(err)
    }

    lines := strings.Split(string(bytes), "\n")

    csvWriter := csv.NewWriter(os.Stdout)

    for _, line := range lines {
        fields, err := processLine(line)
        if err != nil {
            if err == io.EOF {
                break
            } else {
                panic(err)
            }
        }

        var toPrint []string
        if *fieldNumsRaw == "" {
            for i, _ := range fields {
                toPrint = append(toPrint, fields[i])
            }
        } else {
            for _, num := range fieldNums {
                toPrint = append(toPrint, fields[num])
            }
        }

        if *noPrintRealCSV == false {
            csvWriter.Write(toPrint)
        } else {
            fmt.Println(strings.Join(toPrint, *outputJoiner))
        }
    }
    if *noPrintRealCSV == false {
        csvWriter.Flush()
    }
}

func processLine(line string) ([]string, error) {
    strReader := strings.NewReader(line)
    csvReader := csv.NewReader(strReader)

    sepString := *separator
    /*
    fmt.Println("Separator is", string(sepString[0]))
    fmt.Println("'", rune(sepString[0]), "'")
    fmt.Println("'", string(rune("\t"[0])), "'")
    r, size := utf8.DecodeRuneInString(sepString)
    fmt.Println("'", string(r), "'")
    fmt.Println(size)
    */
    _ = utf8.DecodeRuneInString

    csvReader.Comma = rune(sepString[0])

    fields, err := csvReader.Read()
    if err != nil {
        if err == io.EOF {
            return nil, io.EOF
        } else {
            panic(err)
        }
    }

    return fields, nil
}
<|endoftext|>


<commit_before>package jspb

import (
	"github.com/gopherjs/gopherjs/js"
)

// ProtoMessage is implemented by... all *js.Objects.
// But it'll do for an interface to Serialize and Deserialize
type ProtoMessage interface {
	Call(string, ...interface{}) *js.Object
}

// Serialize marshals the provided ProtoMessage into
// a slice of bytes using the serializeBinary ProtobufJS function.
func Serialize(m ProtoMessage) []byte {
	return m.Call("serializeBinary").Interface().([]byte)
}

// Deserialize unmarshals the provided ProtoMessage bytes into
// a generic *js.Object of the provided type,
// returning an error if one was thrown.
func Deserialize(m ProtoMessage, rawBytes []byte) (o *js.Object, err error) {
	// Recover any thrown JS errors
	defer func() {
		e := recover()
		if e == nil {
			return
		}

		if e, ok := e.(*js.Error); ok {
			err = e
		} else {
			panic(e)
		}
	}()

	return m.Call("deserializeBinary", rawBytes), err
}
<commit_msg>Remove now unused interface<commit_after><|endoftext|>


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

package jsutil

import "github.com/gopherjs/gopherjs/js"

// Object is some stuff JS objects can do.
type Object interface {
	Get(string) *js.Object
	Set(string, interface{})
	Call(string, ...interface{}) *js.Object
}

// Element represents a DOM element.
type Element interface {
	Object
	SetAttribute(string, interface{}) Element
	AddChildren(...Element) Element
	RemoveChildren(...Element) Element
	AddEventListener(string, func(*js.Object)) Element
	Show() Element
	Hide() Element
}

type element struct {
	*js.Object
}

// Wrap turns a *js.Object into an Element.
func Wrap(o *js.Object) Element { return &element{o} }

// SetAttribute calls the JS setAttribute method, returning e for chaining.
func (e *element) SetAttribute(attr string, value interface{}) Element {
	e.Call("setAttribute", attr, value)
	return e
}

// AddChildren calls the JS method appendChild for each element, returning e for chaining.
func (e *element) AddChildren(children ...Element) Element {
	for _, c := range children {
		e.Call("appendChild", c)
	}
	return e
}

// RemoveChildren calls the JS method removeChild for each element, returning e for chaining.
func (e *element) RemoveChildren(children ...Element) Element {
	for _, c := range children {
		e.Call("removeChild", c)
	}
	return e
}

// AddEventListener calls the JS method addEventListener, returning e for chaining.
func (e *element) AddEventListener(event string, handler func(*js.Object)) Element {
	e.Call("addEventListener", event, handler)
	return e
}

// Show removes the display attribute.
func (e *element) Show() Element {
	e.Call("removeAttribute", "display")
	return e
}

// Hide sets the display attribute to "none".
func (e *element) Hide() Element {
	e.Call("setAttribute", "display", "none")
	return e
}
<commit_msg>Move comments<commit_after>// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package jsutil

import "github.com/gopherjs/gopherjs/js"

// Object is some stuff JS objects can do.
type Object interface {
	Get(string) *js.Object
	Set(string, interface{})
	Call(string, ...interface{}) *js.Object
}

// Element represents a DOM element.
type Element interface {
	Object

	// SetAttribute calls the JS setAttribute method, returning the element for chaining.
	SetAttribute(string, interface{}) Element

	// RemoveAttribute calls the JS removeAttribute method, returning the element for chaining.
	RemoveAttribute(string) Element

	// AddChildren calls the JS method appendChild for each element, returning the element for chaining.
	AddChildren(...Element) Element

	// RemoveChildren calls the JS method removeChild for each element, returning the element for chaining.
	RemoveChildren(...Element) Element

	// AddEventListener calls the JS method addEventListener, returning the element for chaining.
	AddEventListener(string, func(*js.Object)) Element

	// Show removes the display attribute, returning the element for chaining.
	Show() Element

	// Hide sets the display attribute to "none", returning the element for chaining.
	Hide() Element
}

type element struct {
	*js.Object
}

// Wrap turns a *js.Object into an Element.
func Wrap(o *js.Object) Element { return &element{o} }

func (e *element) SetAttribute(attr string, value interface{}) Element {
	e.Call("setAttribute", attr, value)
	return e
}

func (e *element) RemoveAttribute(attr string) Element {
	e.Call("removeAttribute", attr)
	return e
}

func (e *element) AddChildren(children ...Element) Element {
	for _, c := range children {
		e.Call("appendChild", c)
	}
	return e
}

func (e *element) RemoveChildren(children ...Element) Element {
	for _, c := range children {
		e.Call("removeChild", c)
	}
	return e
}

func (e *element) AddEventListener(event string, handler func(*js.Object)) Element {
	e.Call("addEventListener", event, handler)
	return e
}

func (e *element) Show() Element {
	e.Call("removeAttribute", "display")
	return e
}

func (e *element) Hide() Element {
	e.Call("setAttribute", "display", "none")
	return e
}
<|endoftext|>


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

package aerospike

import (
	"math/rand"
	"strings"
	"testing"

	"github.com/aerospike/aerospike-client-go/pkg/ripemd160"
)

var res []byte

func doTheHash(buf []byte, b *testing.B) {
	hash := ripemd160.New()
	for i := 0; i < b.N; i++ {
		hash.Reset()
		hash.Write(buf)
		hash.Sum(res)
	}
}

func Benchmark_K_Hash_S_______1(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 1))
	doTheHash(buffer, b)
}

func Benchmark_K_Hash_S______10(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 10))
	doTheHash(buffer, b)
}

func Benchmark_K_Hash_S_____100(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 100))
	doTheHash(buffer, b)
}

func Benchmark_K_Hash_S____1000(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 1000))
	doTheHash(buffer, b)
}

func Benchmark_K_Hash_S__10_000(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 10000))
	doTheHash(buffer, b)
}

func Benchmark_K_Hash_S_100_000(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 100000))
	doTheHash(buffer, b)
}

func makeKeys(val interface{}, b *testing.B) {
	for i := 0; i < b.N; i++ {
		_, err := NewKey("ns", "set", val)
		if err != nil {
			panic(err)
		}
	}
}

func Benchmark_NewKey_String______1(b *testing.B) {
	buffer := strings.Repeat("s", 1)
	makeKeys(buffer, b)
}

func Benchmark_NewKey_String_____10(b *testing.B) {
	buffer := strings.Repeat("s", 10)
	makeKeys(buffer, b)
}

func Benchmark_NewKey_String____100(b *testing.B) {
	buffer := strings.Repeat("s", 100)
	makeKeys(buffer, b)
}

func Benchmark_NewKey_String___1000(b *testing.B) {
	buffer := strings.Repeat("s", 1000)
	makeKeys(buffer, b)
}

func Benchmark_NewKey_String__10000(b *testing.B) {
	buffer := strings.Repeat("s", 10000)
	makeKeys(buffer, b)
}

func Benchmark_NewKey_String_100000(b *testing.B) {
	buffer := strings.Repeat("s", 100000)
	makeKeys(buffer, b)
}
func Benchmark_NewKey_Byte______1(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 1))
	makeKeys(buffer, b)
}

func Benchmark_NewKey_Byte_____10(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 10))
	makeKeys(buffer, b)
}

func Benchmark_NewKey_Byte____100(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 100))
	makeKeys(buffer, b)
}

func Benchmark_NewKey_Byte___1000(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 1000))
	makeKeys(buffer, b)
}

func Benchmark_NewKey_Byte__10000(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 10000))
	makeKeys(buffer, b)
}

func Benchmark_NewKey_Byte_100000(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 100000))
	makeKeys(buffer, b)
}

func Benchmark_NewKey_________Int(b *testing.B) {
	makeKeys(rand.Int63(), b)
}

func Benchmark_NewKey_____Float64(b *testing.B) {
	makeKeys(rand.Float64(), b)
}

func Benchmark_NewKey_List_No_Reflect(b *testing.B) {
	list := []interface{}{
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
	}
	makeKeys(list, b)
}

func Benchmark_NewKey_List_With_Reflect(b *testing.B) {
	list := []string{
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
	}
	makeKeys(list, b)
}
<commit_msg>Rename some functions in benchmarks<commit_after>// Copyright 2013-2016 Aerospike, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package aerospike

import (
	"math/rand"
	"strings"
	"testing"

	"github.com/aerospike/aerospike-client-go/pkg/ripemd160"
)

var res []byte

func doTheHash(buf []byte, b *testing.B) {
	hash := ripemd160.New()
	for i := 0; i < b.N; i++ {
		hash.Reset()
		hash.Write(buf)
		hash.Sum(res)
	}
}

func Benchmark_Key_Hash_S_______1(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 1))
	doTheHash(buffer, b)
}

func Benchmark_Key_Hash_S______10(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 10))
	doTheHash(buffer, b)
}

func Benchmark_Key_Hash_S_____100(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 100))
	doTheHash(buffer, b)
}

func Benchmark_Key_Hash_S____1000(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 1000))
	doTheHash(buffer, b)
}

func Benchmark_Key_Hash_S__10_000(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 10000))
	doTheHash(buffer, b)
}

func Benchmark_Key_Hash_S_100_000(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 100000))
	doTheHash(buffer, b)
}

var _key *Key

func makeKeys(val interface{}, b *testing.B) {
	var err error
	for i := 0; i < b.N; i++ {
		_key, err = NewKey("ns", "set", val)
		if err != nil {
			panic(err)
		}
	}
}

func Benchmark_NewKey_String______1(b *testing.B) {
	buffer := strings.Repeat("s", 1)
	makeKeys(buffer, b)
}

func Benchmark_NewKey_String_____10(b *testing.B) {
	buffer := strings.Repeat("s", 10)
	makeKeys(buffer, b)
}

func Benchmark_NewKey_String____100(b *testing.B) {
	buffer := strings.Repeat("s", 100)
	makeKeys(buffer, b)
}

func Benchmark_NewKey_String___1000(b *testing.B) {
	buffer := strings.Repeat("s", 1000)
	makeKeys(buffer, b)
}

func Benchmark_NewKey_String__10000(b *testing.B) {
	buffer := strings.Repeat("s", 10000)
	makeKeys(buffer, b)
}

func Benchmark_NewKey_String_100000(b *testing.B) {
	buffer := strings.Repeat("s", 100000)
	makeKeys(buffer, b)
}
func Benchmark_NewKey_Byte______1(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 1))
	makeKeys(buffer, b)
}

func Benchmark_NewKey_Byte_____10(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 10))
	makeKeys(buffer, b)
}

func Benchmark_NewKey_Byte____100(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 100))
	makeKeys(buffer, b)
}

func Benchmark_NewKey_Byte___1000(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 1000))
	makeKeys(buffer, b)
}

func Benchmark_NewKey_Byte__10000(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 10000))
	makeKeys(buffer, b)
}

func Benchmark_NewKey_Byte_100000(b *testing.B) {
	buffer := []byte(strings.Repeat("s", 100000))
	makeKeys(buffer, b)
}

func Benchmark_NewKey_________Int(b *testing.B) {
	makeKeys(rand.Int63(), b)
}

func Benchmark_NewKey_____Float64(b *testing.B) {
	makeKeys(rand.Float64(), b)
}

func Benchmark_NewKey_List_No_Reflect(b *testing.B) {
	list := []interface{}{
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
	}
	makeKeys(list, b)
}

func Benchmark_NewKey_List_With_Reflect(b *testing.B) {
	list := []string{
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
		strings.Repeat("s", 1e3),
	}
	makeKeys(list, b)
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/couchbaselabs/indexing/api"
	//    "github.com/couchbaselabs/dparval"
	"errors"
	"log"
	"net"
	"net/rpc"
	"net/rpc/jsonrpc"
)

type MutationManager struct {
	indexmap map[string]api.Finder
}

var mutationMgr MutationManager

func (m *MutationManager) ProcessSingleMutation(mutation *api.Mutation, reply *bool) error {
	log.Printf("Received Mutation Type %s Indexid %v, Docid %v, Vbucket %v, Seqno %v", mutation.Type, mutation.Indexid, mutation.Docid, mutation.Vbucket, mutation.Seqno)

	//FIXME change this to channel based
	*reply = false

	if mutation.Type == "INSERT" {

		var key api.Key
		var value api.Value
		var err error

		if key, err = api.NewKey(mutation.SecondaryKey, mutation.Docid); err != nil {
			log.Printf("Error Generating Key From Mutation %v", err)
			*reply = false
			return err
		}

		if value, err = api.NewValue(mutation.SecondaryKey, mutation.Docid, mutation.Vbucket, mutation.Seqno); err != nil {
			log.Printf("Error Generating Value From Mutation %v", err)
			*reply = false
			return err
		}

		if engine, ok := m.indexmap[mutation.Indexid]; ok {
			if err := engine.InsertMutation(key, value); err != nil {
				log.Printf("Error from Engine during InsertMutation %v", err)
				*reply = false
				return err
			}
		} else {
			log.Printf("Unknown Index %v or Engine not found", mutation.Indexid)
			*reply = false
			return errors.New("Unknown Index or Engine not found")
		}

		*reply = true

	} else if mutation.Type == "DELETE" {

		if engine, ok := m.indexmap[mutation.Indexid]; ok {
			if err := engine.DeleteMutation(mutation.Docid); err != nil {
				log.Printf("Error from Engine during Delete Mutation %v", err)
				*reply = false
				return err
			}
		} else {
			log.Printf("Unknown Index %v or Engine not found", mutation.Indexid)
			*reply = false
			return errors.New("Unknown Index or Engine not found")
		}
		*reply = true

	}
	return nil
}

func RegisterIndexWithMutationHandler(indexinfo api.IndexInfo) {
	mutationMgr.indexmap[indexinfo.Uuid] = indexinfo.Engine
}

func StartMutationManager() error {

	log.Println("Starting Mutation Manager")
	server := rpc.NewServer()
	server.Register(&mutationMgr)

	server.HandleHTTP(rpc.DefaultRPCPath, rpc.DefaultDebugPath)
	mutationMgr.indexmap = make(map[string]api.Finder)

	l, e := net.Listen("tcp", ":8096")
	if e != nil {
		return e
	}

	for {
		conn, err := l.Accept()
		if err != nil {
			return err
		}

		go server.ServeCodec(jsonrpc.NewServerCodec(conn))
	}
	return nil
}
<commit_msg>Add notification channel to mutation manager<commit_after>package main

import (
	"errors"
	"github.com/couchbaselabs/indexing/api"
	"log"
	"net"
	"net/rpc"
	"net/rpc/jsonrpc"
)

type MutationManager struct {
	indexmap map[string]api.Finder
}

var mutationMgr MutationManager

type ddlNotification struct {
	indexinfo api.IndexInfo
	ddltype   api.RequestType
}

func (m *MutationManager) ProcessSingleMutation(mutation *api.Mutation, reply *bool) error {
	log.Printf("Received Mutation Type %s Indexid %v, Docid %v, Vbucket %v, Seqno %v", mutation.Type, mutation.Indexid, mutation.Docid, mutation.Vbucket, mutation.Seqno)

	//FIXME change this to channel based
	*reply = false

	if mutation.Type == "INSERT" {

		var key api.Key
		var value api.Value
		var err error

		if key, err = api.NewKey(mutation.SecondaryKey, mutation.Docid); err != nil {
			log.Printf("Error Generating Key From Mutation %v", err)
			*reply = false
			return err
		}

		if value, err = api.NewValue(mutation.SecondaryKey, mutation.Docid, mutation.Vbucket, mutation.Seqno); err != nil {
			log.Printf("Error Generating Value From Mutation %v", err)
			*reply = false
			return err
		}

		if engine, ok := m.indexmap[mutation.Indexid]; ok {
			if err := engine.InsertMutation(key, value); err != nil {
				log.Printf("Error from Engine during InsertMutation %v", err)
				*reply = false
				return err
			}
		} else {
			log.Printf("Unknown Index %v or Engine not found", mutation.Indexid)
			*reply = false
			return errors.New("Unknown Index or Engine not found")
		}

		*reply = true

	} else if mutation.Type == "DELETE" {

		if engine, ok := m.indexmap[mutation.Indexid]; ok {
			if err := engine.DeleteMutation(mutation.Docid); err != nil {
				log.Printf("Error from Engine during Delete Mutation %v", err)
				*reply = false
				return err
			}
		} else {
			log.Printf("Unknown Index %v or Engine not found", mutation.Indexid)
			*reply = false
			return errors.New("Unknown Index or Engine not found")
		}
		*reply = true

	}
	return nil
}

func StartMutationManager() (chan ddlNotification, error) {

	var err error
	//start the rpc server
	if err = startRPCServer(); err != nil {
		return nil, err
	}

	//create a channel to receive notification from indexer
	//and start a goroutine to listen to it
	chnotify = make(chan ddlNotification)
	go acceptIndexerNotification(chnotify)
	return chnotify, nil
}

func startRPCServer() error {

	log.Println("Starting Mutation Manager")
	server := rpc.NewServer()
	server.Register(&mutationMgr)

	server.HandleHTTP(rpc.DefaultRPCPath, rpc.DefaultDebugPath)
	mutationMgr.indexmap = make(map[string]api.Finder)

	l, err := net.Listen("tcp", ":8096")
	if err != nil {
		return err
	}

	go func() {
		for {
			conn, err := l.Accept()
			if err != nil {
				log.Printf("Error in Accept %v. Shutting down")
				//FIXME Add a cleanup function
				return
			}
			go server.ServeCodec(jsonrpc.NewServerCodec(conn))
		}
	}()
	return nil

}

func acceptIndexerNotification(chnotify chan ddlNotification) {

	ok := true
	var ddl ddlNotification
	for ok {
		ddl, ok = <-chnotify
		if ok {
			switch ddl.ddltype {
			case api.CREATE:
				mutationMgr.indexmap[ddl.indexinfo.Uuid] = ddl.indexinfo.Engine
			case api.DROP:
				delete(mutationMgr.indexmap, ddl.indexinfo.Uuid)
			default:
				log.Printf("Mutation Manager Received Unsupported Notification %v", ddl.ddltype)
			}
		}
	}
}
<|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.

// Blueprint is a meta-build system that reads in Blueprints files that describe
// modules that need to be built, and produces a Ninja
// (http://martine.github.io/ninja/) manifest describing the commands that need
// to be run and their dependencies.  Where most build systems use built-in
// rules or a domain-specific language to describe the logic how modules are
// converted to build rules, Blueprint delegates this to per-project build logic
// written in Go.  For large, heterogenous projects this allows the inherent
// complexity of the build logic to be maintained in a high-level language,
// while still allowing simple changes to individual modules by modifying easy
// to understand Blueprints files.
//
// Blueprint uses a bootstrapping process to allow the code for Blueprint,
// the code for the build logic, and the code for the project being compiled
// to all live in the project.  Dependencies between the layers are fully
// tracked - a change to the logic code will cause the logic to be recompiled,
// regenerate the project build manifest, and run modified project rules.  A
// change to Blueprint itself will cause Blueprint to rebuild, and then rebuild
// the logic, etc.
//
// A Blueprints file is a list of modules in a pseudo-python data format, where
// the module type looks like a function call, and the properties of the module
// look like optional arguments.  For example, a simple module might look like:
//
// cc_library(
//     name = "cmd",
//     srcs = [
//         "main.c",
//     ],
//     deps = [
//         "libc",
//     ],
// )
//
// subdirs = ["subdir1", "subdir2"]
//
// The modules from the top level Blueprints file and recursively through any
// subdirectories listed by the "subdirs" variable are read by Blueprint, and
// their properties are stored into property structs by module type.  Once
// all modules are read, Blueprint calls any registered Mutators, in
// registration order.  Mutators can visit each module top-down or bottom-up,
// and modify them as necessary.  Common modifications include setting
// properties on modules to propagate information down from dependers to
// dependees (for example, telling a module what kinds of parents depend on it),
// or splitting a module into multiple variants (for example, one per
// architecture being compiled).  After all Mutators have run, each module is
// asked to generate build rules based on property values, and then singletons
// can generate any build rules from the output of all modules.
//
// The per-project build logic defines a top level command, referred to in the
// documentation as the "primary builder".  This command is responsible for
// registering the module types needed for the project, as well as any
// singletons or mutators, and then calling into Blueprint with the path of the
// root Blueprint file.
package blueprint
<commit_msg>Indent code block in doc.go<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.

// Blueprint is a meta-build system that reads in Blueprints files that describe
// modules that need to be built, and produces a Ninja
// (http://martine.github.io/ninja/) manifest describing the commands that need
// to be run and their dependencies.  Where most build systems use built-in
// rules or a domain-specific language to describe the logic how modules are
// converted to build rules, Blueprint delegates this to per-project build logic
// written in Go.  For large, heterogenous projects this allows the inherent
// complexity of the build logic to be maintained in a high-level language,
// while still allowing simple changes to individual modules by modifying easy
// to understand Blueprints files.
//
// Blueprint uses a bootstrapping process to allow the code for Blueprint,
// the code for the build logic, and the code for the project being compiled
// to all live in the project.  Dependencies between the layers are fully
// tracked - a change to the logic code will cause the logic to be recompiled,
// regenerate the project build manifest, and run modified project rules.  A
// change to Blueprint itself will cause Blueprint to rebuild, and then rebuild
// the logic, etc.
//
// A Blueprints file is a list of modules in a pseudo-python data format, where
// the module type looks like a function call, and the properties of the module
// look like optional arguments.  For example, a simple module might look like:
//
//   cc_library(
//       name = "cmd",
//       srcs = [
//           "main.c",
//       ],
//       deps = [
//           "libc",
//       ],
//   )
//
//   subdirs = ["subdir1", "subdir2"]
//
// The modules from the top level Blueprints file and recursively through any
// subdirectories listed by the "subdirs" variable are read by Blueprint, and
// their properties are stored into property structs by module type.  Once
// all modules are read, Blueprint calls any registered Mutators, in
// registration order.  Mutators can visit each module top-down or bottom-up,
// and modify them as necessary.  Common modifications include setting
// properties on modules to propagate information down from dependers to
// dependees (for example, telling a module what kinds of parents depend on it),
// or splitting a module into multiple variants (for example, one per
// architecture being compiled).  After all Mutators have run, each module is
// asked to generate build rules based on property values, and then singletons
// can generate any build rules from the output of all modules.
//
// The per-project build logic defines a top level command, referred to in the
// documentation as the "primary builder".  This command is responsible for
// registering the module types needed for the project, as well as any
// singletons or mutators, and then calling into Blueprint with the path of the
// root Blueprint file.
package blueprint
<|endoftext|>


<commit_before>package jtime

/* Package jtime provides flexible JSON time.Time marshing/unmarshaling

How it works?

Use jtime.Time in your struct, and before calling json.Marshal/json.Unmarashal
set the marshaller using SetMarshaller.

You can either write your own marshaller or use two of the available marshallers:
* FormatMashaller uses time.Time format to marshal/unmarshal time as JSON strings
* UnixMarshaler marshal time.Time to JSON integers (with or without msec)

jtime.Time embeds time.Time so you can use all time.Time methods with it.

Example:

	package main

	import (
		"encoding/json"
		"fmt"
		"log"

		"bitbucket.org/tebeka/jtime"
	)

	type T struct {
		Created jtime.Time `json:"created"`
	}

	func main() {
		jtime.SetMarshaler(&jtime.UnixMarshaler{})
		data := []byte(`{"created":1382135725}`) // Oct 18, 2013
		t := T{}
		if err := json.Unmarshal(data, &t); err != nil {
			log.Fatalf("error umarshaling: %s\n", err)
		}
		fmt.Println(t.Created) // 2013-10-18 15:35:25 -0700 PDT
	}

Caution: Changing marshaller in mid-flight is dangerous :)
*/
<commit_msg>right doc<commit_after>/* Package jtime provides flexible JSON time.Time marshing/unmarshaling

How it works?

Use jtime.Time in your struct, and before calling json.Marshal/json.Unmarashal
set the marshaller using SetMarshaller.

You can either write your own marshaller or use two of the available marshallers:
* FormatMashaller uses time.Time format to marshal/unmarshal time as JSON strings
* UnixMarshaler marshal time.Time to JSON integers (with or without msec)

jtime.Time embeds time.Time so you can use all time.Time methods with it.

Example:

	package main

	import (
		"encoding/json"
		"fmt"
		"log"

		"bitbucket.org/tebeka/jtime"
	)

	type T struct {
		Created jtime.Time `json:"created"`
	}

	func main() {
		jtime.SetMarshaler(&jtime.UnixMarshaler{})
		data := []byte(`{"created":1382135725}`) // Oct 18, 2013
		t := T{}
		if err := json.Unmarshal(data, &t); err != nil {
			log.Fatalf("error umarshaling: %s\n", err)
		}
		fmt.Println(t.Created) // 2013-10-18 15:35:25 -0700 PDT
	}

Caution: Changing marshaller in mid-flight is dangerous :)
*/
package jtime
<|endoftext|>


<commit_before>/*

You can keep your model structs as is and use struct field tags to indicate to jsonapi
how you want your response built or your request deserialzied. What about my relationships?
jsonapi supports relationships out of the box and will even side load them in your response
into an "included" array--that contains associated objects.

jsonapi uses StructField tags to annotate the structs fields that you already have and use
in your app and then reads and writes jsonapi.org output based on the instructions you give
the library in your jsonapi tags.

Example structs using a Blog > Post > Comment structure,

				type Blog struct {
						Id            int       `jsonapi:"primary,blogs"`
						Title         string    `jsonapi:"attr,title"`
						Posts         []*Post   `jsonapi:"relation,posts"`
						CurrentPost   *Post     `jsonapi:"relation,current_post"`
						CurrentPostId int       `jsonapi:"attr,current_post_id"`
						CreatedAt     time.Time `jsonapi:"attr,created_at"`
						ViewCount     int       `jsonapi:"attr,view_count"`
				}

				type Post struct {
						Id       int        `jsonapi:"primary,posts"`
						BlogId   int        `jsonapi:"attr,blog_id"`
						Title    string     `jsonapi:"attr,title"`
						Body     string     `jsonapi:"attr,body"`
						Comments []*Comment `jsonapi:"relation,comments"`
				}

				type Comment struct {
						Id     int    `jsonapi:"primary,comments"`
						PostId int    `jsonapi:"attr,post_id"`
						Body   string `jsonapi:"attr,body"`
				}

jsonapi Tag Reference

Value, primary: "primary,<type field output>"

This indicates that this is the primary key field for this struct type. Tag
value arguments are comma separated.  The first argument must be, "primary", and
the second must be the name that should appear in the "type" field for all data
objects that represent this type of model.

Value, attr: "attr,<key name in attributes hash>"

These fields' values should end up in the "attribute" hash for a record.  The first
argument must be, "attr', and the second should be the name for the key to display in
the the "attributes" hash for that record.

Value, relation: "relation,<key name in relationships hash>"

Relations are struct fields that represent a one-to-one or one-to-many to other structs.
jsonapi will traverse the graph of relationships and marshal or unmarshal records.  The first
argument must be, "relation", and the second should be the name of the relationship, used as
the key in the "relationships" hash for the record.

Use the methods below to Marshal and Unmarshal jsonapi.org json payloads.

*/
package jsonapi
<commit_msg>link to readme from godoc<commit_after>/*
Visit the readme at https://github.com/shwoodard/jsonapi

You can keep your model structs as is and use struct field tags to indicate to jsonapi
how you want your response built or your request deserialzied. What about my relationships?
jsonapi supports relationships out of the box and will even side load them in your response
into an "included" array--that contains associated objects.

jsonapi uses StructField tags to annotate the structs fields that you already have and use
in your app and then reads and writes jsonapi.org output based on the instructions you give
the library in your jsonapi tags.

Example structs using a Blog > Post > Comment structure,

				type Blog struct {
						Id            int       `jsonapi:"primary,blogs"`
						Title         string    `jsonapi:"attr,title"`
						Posts         []*Post   `jsonapi:"relation,posts"`
						CurrentPost   *Post     `jsonapi:"relation,current_post"`
						CurrentPostId int       `jsonapi:"attr,current_post_id"`
						CreatedAt     time.Time `jsonapi:"attr,created_at"`
						ViewCount     int       `jsonapi:"attr,view_count"`
				}

				type Post struct {
						Id       int        `jsonapi:"primary,posts"`
						BlogId   int        `jsonapi:"attr,blog_id"`
						Title    string     `jsonapi:"attr,title"`
						Body     string     `jsonapi:"attr,body"`
						Comments []*Comment `jsonapi:"relation,comments"`
				}

				type Comment struct {
						Id     int    `jsonapi:"primary,comments"`
						PostId int    `jsonapi:"attr,post_id"`
						Body   string `jsonapi:"attr,body"`
				}

jsonapi Tag Reference

Value, primary: "primary,<type field output>"

This indicates that this is the primary key field for this struct type. Tag
value arguments are comma separated.  The first argument must be, "primary", and
the second must be the name that should appear in the "type" field for all data
objects that represent this type of model.

Value, attr: "attr,<key name in attributes hash>"

These fields' values should end up in the "attribute" hash for a record.  The first
argument must be, "attr', and the second should be the name for the key to display in
the the "attributes" hash for that record.

Value, relation: "relation,<key name in relationships hash>"

Relations are struct fields that represent a one-to-one or one-to-many to other structs.
jsonapi will traverse the graph of relationships and marshal or unmarshal records.  The first
argument must be, "relation", and the second should be the name of the relationship, used as
the key in the "relationships" hash for the record.

Use the methods below to Marshal and Unmarshal jsonapi.org json payloads.

*/
package jsonapi
<|endoftext|>


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

// Package websocket implements the WebSocket protocol defined in RFC 6455.
//
// Overview
//
// The Conn type represents a WebSocket connection. A server application calls
// the Upgrade function from an HTTP request handler to get a pointer to a
// Conn:
//
//  func handler(w http.ResponseWriter, r *http.Request) {
//      ws, err := websocket.Upgrade(w, r, nil, 1024, 1024)
//      if _, ok := err.(websocket.HandshakeError); ok {
//          http.Error(w, "Not a websocket handshake", 400)
//          return
//      } else if err != nil {
//          log.Println(err)
//          return
//      }
//      ... Use conn to send and receive messages.
//  }
//
// Call the connection WriteMessage and ReadMessages methods to send and
// receive messages as a slice of bytes. This snippet of code shows how to echo
// messages using these methods:
//
//  for {
//      messageType, p, err := conn.ReadMessage()
//      if err != nil {
//          return
//      }
//      if _, err := conn.WriteMessaage(messageType, p); err != nil {
//          return err
//      }
//  }
//
// In above snippet of code, p is a []byte and messageType is an int with value
// websocket.BinaryMessage or websocket.TextMessage.
//
// An application can also send and receive messages using the io.WriteCloser
// and io.Reader interfaces. To send a message, call the connection NextWriter
// method to get an io.WriteCloser, write the message to the writer and close
// the writer when done. To receive a message, call the connection NextReader
// method to get an io.Reader and read until io.EOF is returned. This snippet
// snippet shows how to echo messages using the NextWriter and NextReader
// methods:
//
//  for {
//      messageType, r, err := conn.NextReader()
//      if err != nil {
//          return
//      }
//      w, err := conn.NextWriter(messageType)
//      if err != nil {
//          return err
//      }
//      if _, err := io.Copy(w, r); err != nil {
//          return err
//      }
//      if err := w.Close(); err != nil {
//          return err
//      }
//  }
//
// Data Messages
//
// The WebSocket protocol distinguishes between text and binary data messages.
// Text messages are interpreted as UTF-8 encoded text. The interpretation of
// binary messages is left to the application.
//
// This package uses the TextMessage and BinaryMessage integer constants to
// identify the two data message types. The ReadMessage and NextReader methods
// return the type of the received message. The messageType argument to the
// WriteMessage and NextWriter methods specifies the type of a sent message.
//
// It is the application's responsibility to ensure that text messages are
// valid UTF-8 encoded text.
//
// Control Messages
//
// The WebSocket protocol defines three types of control messages: close, ping
// and pong. Call the connection WriteControl, WriteMessage or NextWriter
// methods to send a control message to the peer.
//
// Connections handle received ping and pong messages by invoking a callback
// function set with SetPingHandler and SetPongHandler methods. These callback
// functions can be invoked from the ReadMessage method, the NextReader method
// or from a call to the data message reader returned from NextReader.
//
// Connections handle received close messages by returning an error from the
// ReadMessage method, the NextReader method or from a call to the data message
// reader returned from NextReader.
//
// Concurrency
//
// A Conn supports a single concurrent caller to the write methods (NextWriter,
// SetWriteDeadline, WriteMessage) and a single concurrent caller to the read
// methods (NextReader, SetReadDeadline, ReadMessage). The Close and
// WriteControl methods can be called concurrently with all other methods.
//
package websocket
<commit_msg>Fixed Examples<commit_after>// Copyright 2013 Gary Burd. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package websocket implements the WebSocket protocol defined in RFC 6455.
//
// Overview
//
// The Conn type represents a WebSocket connection. A server application calls
// the Upgrade function from an HTTP request handler to get a pointer to a
// Conn:
//
//  func handler(w http.ResponseWriter, r *http.Request) {
//      ws, err := websocket.Upgrade(w, r, nil, 1024, 1024)
//      if _, ok := err.(websocket.HandshakeError); ok {
//          http.Error(w, "Not a websocket handshake", 400)
//          return
//      } else if err != nil {
//          log.Println(err)
//          return
//      }
//      ... Use conn to send and receive messages.
//  }
//
// Call the connection WriteMessage and ReadMessages methods to send and
// receive messages as a slice of bytes. This snippet of code shows how to echo
// messages using these methods:
//
//  for {
//      messageType, p, err := conn.ReadMessage()
//      if err != nil {
//          return
//      }
//      if err = conn.WriteMessage(messageType, p); err != nil {
//          return err
//      }
//  }
//
// In above snippet of code, p is a []byte and messageType is an int with value
// websocket.BinaryMessage or websocket.TextMessage.
//
// An application can also send and receive messages using the io.WriteCloser
// and io.Reader interfaces. To send a message, call the connection NextWriter
// method to get an io.WriteCloser, write the message to the writer and close
// the writer when done. To receive a message, call the connection NextReader
// method to get an io.Reader and read until io.EOF is returned. This snippet
// snippet shows how to echo messages using the NextWriter and NextReader
// methods:
//
//  for {
//      messageType, r, err := conn.NextReader()
//      if err != nil {
//          return
//      }
//      w, err := conn.NextWriter(messageType)
//      if err != nil {
//          return err
//      }
//      if _, err := io.Copy(w, r); err != nil {
//          return err
//      }
//      if err := w.Close(); err != nil {
//          return err
//      }
//  }
//
// Data Messages
//
// The WebSocket protocol distinguishes between text and binary data messages.
// Text messages are interpreted as UTF-8 encoded text. The interpretation of
// binary messages is left to the application.
//
// This package uses the TextMessage and BinaryMessage integer constants to
// identify the two data message types. The ReadMessage and NextReader methods
// return the type of the received message. The messageType argument to the
// WriteMessage and NextWriter methods specifies the type of a sent message.
//
// It is the application's responsibility to ensure that text messages are
// valid UTF-8 encoded text.
//
// Control Messages
//
// The WebSocket protocol defines three types of control messages: close, ping
// and pong. Call the connection WriteControl, WriteMessage or NextWriter
// methods to send a control message to the peer.
//
// Connections handle received ping and pong messages by invoking a callback
// function set with SetPingHandler and SetPongHandler methods. These callback
// functions can be invoked from the ReadMessage method, the NextReader method
// or from a call to the data message reader returned from NextReader.
//
// Connections handle received close messages by returning an error from the
// ReadMessage method, the NextReader method or from a call to the data message
// reader returned from NextReader.
//
// Concurrency
//
// A Conn supports a single concurrent caller to the write methods (NextWriter,
// SetWriteDeadline, WriteMessage) and a single concurrent caller to the read
// methods (NextReader, SetReadDeadline, ReadMessage). The Close and
// WriteControl methods can be called concurrently with all other methods.
//
package websocket
<|endoftext|>