<commit_before>/*
 *
 * Copyright 2015 gRPC authors.
 *
 * 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.
 *
 */

//go:generate protoc -I ../routeguide --go_out=plugins=grpc:../routeguide ../routeguide/route_guide.proto

// Package main implements a simple gRPC server that demonstrates how to use gRPC-Go libraries
// to perform unary, client streaming, server streaming and full duplex RPCs.
//
// It implements the route guide service whose definition can be found in routeguide/route_guide.proto.
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"math"
	"net"
	"sync"
	"time"

	"golang.org/x/net/context"
	"google.golang.org/grpc"

	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/testdata"

	"github.com/golang/protobuf/proto"

	pb "google.golang.org/grpc/examples/route_guide/routeguide"
)

var (
	tls        = flag.Bool("tls", false, "Connection uses TLS if true, else plain TCP")
	certFile   = flag.String("cert_file", "", "The TLS cert file")
	keyFile    = flag.String("key_file", "", "The TLS key file")
	jsonDBFile = flag.String("json_db_file", "testdata/route_guide_db.json", "A json file containing a list of features")
	port       = flag.Int("port", 10000, "The server port")
)

type routeGuideServer struct {
	savedFeatures []*pb.Feature // read-only after initialized

	mu         sync.Mutex // protects routeNotes
	routeNotes map[string][]*pb.RouteNote
}

// GetFeature returns the feature at the given point.
func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) {
	for _, feature := range s.savedFeatures {
		if proto.Equal(feature.Location, point) {
			return feature, nil
		}
	}
	// No feature was found, return an unnamed feature
	return &pb.Feature{Location: point}, nil
}

// ListFeatures lists all features contained within the given bounding Rectangle.
func (s *routeGuideServer) ListFeatures(rect *pb.Rectangle, stream pb.RouteGuide_ListFeaturesServer) error {
	for _, feature := range s.savedFeatures {
		if inRange(feature.Location, rect) {
			if err := stream.Send(feature); err != nil {
				return err
			}
		}
	}
	return nil
}

// RecordRoute records a route composited of a sequence of points.
//
// It gets a stream of points, and responds with statistics about the "trip":
// number of points,  number of known features visited, total distance traveled, and
// total time spent.
func (s *routeGuideServer) RecordRoute(stream pb.RouteGuide_RecordRouteServer) error {
	var pointCount, featureCount, distance int32
	var lastPoint *pb.Point
	startTime := time.Now()
	for {
		point, err := stream.Recv()
		if err == io.EOF {
			endTime := time.Now()
			return stream.SendAndClose(&pb.RouteSummary{
				PointCount:   pointCount,
				FeatureCount: featureCount,
				Distance:     distance,
				ElapsedTime:  int32(endTime.Sub(startTime).Seconds()),
			})
		}
		if err != nil {
			return err
		}
		pointCount++
		for _, feature := range s.savedFeatures {
			if proto.Equal(feature.Location, point) {
				featureCount++
			}
		}
		if lastPoint != nil {
			distance += calcDistance(lastPoint, point)
		}
		lastPoint = point
	}
}

// RouteChat receives a stream of message/location pairs, and responds with a stream of all
// previous messages at each of those locations.
func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error {
	for {
		in, err := stream.Recv()
		if err == io.EOF {
			return nil
		}
		if err != nil {
			return err
		}
		key := serialize(in.Location)

		s.mu.Lock()
		s.routeNotes[key] = append(s.routeNotes[key], in)
		// Note: this copy prevents blocking other clients while serving this one.
		// We don't need to do a deep copy, because elements in the slice are
		// insert-only and never modified.
		rn := make([]*pb.RouteNote, len(s.routeNotes[key]))
		copy(rn, s.routeNotes[key])
		s.mu.Unlock()

		for _, note := range rn {
			if err := stream.Send(note); err != nil {
				return err
			}
		}
	}
}

// loadFeatures loads features from a JSON file.
func (s *routeGuideServer) loadFeatures(filePath string) {
	file, err := ioutil.ReadFile(filePath)
	if err != nil {
		log.Fatalf("Failed to load default features: %v", err)
	}
	if err := json.Unmarshal(file, &s.savedFeatures); err != nil {
		log.Fatalf("Failed to load default features: %v", err)
	}
}

func toRadians(num float64) float64 {
	return num * math.Pi / float64(180)
}

// calcDistance calculates the distance between two points using the "haversine" formula.
// This code was taken from http://www.movable-type.co.uk/scripts/latlong.html.
func calcDistance(p1 *pb.Point, p2 *pb.Point) int32 {
	const CordFactor float64 = 1e7
	const R float64 = float64(6371000) // metres
	lat1 := float64(p1.Latitude) / CordFactor
	lat2 := float64(p2.Latitude) / CordFactor
	lng1 := float64(p1.Longitude) / CordFactor
	lng2 := float64(p2.Longitude) / CordFactor
	φ1 := toRadians(lat1)
	φ2 := toRadians(lat2)
	Δφ := toRadians(lat2 - lat1)
	Δλ := toRadians(lng2 - lng1)

	a := math.Sin(Δφ/2)*math.Sin(Δφ/2) +
		math.Cos(φ1)*math.Cos(φ2)*
			math.Sin(Δλ/2)*math.Sin(Δλ/2)
	c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))

	distance := R * c
	return int32(distance)
}

func inRange(point *pb.Point, rect *pb.Rectangle) bool {
	left := math.Min(float64(rect.Lo.Longitude), float64(rect.Hi.Longitude))
	right := math.Max(float64(rect.Lo.Longitude), float64(rect.Hi.Longitude))
	top := math.Max(float64(rect.Lo.Latitude), float64(rect.Hi.Latitude))
	bottom := math.Min(float64(rect.Lo.Latitude), float64(rect.Hi.Latitude))

	if float64(point.Longitude) >= left &&
		float64(point.Longitude) <= right &&
		float64(point.Latitude) >= bottom &&
		float64(point.Latitude) <= top {
		return true
	}
	return false
}

func serialize(point *pb.Point) string {
	return fmt.Sprintf("%d %d", point.Latitude, point.Longitude)
}

func newServer() *routeGuideServer {
	s := &routeGuideServer{routeNotes: make(map[string][]*pb.RouteNote)}
	s.loadFeatures(*jsonDBFile)
	return s
}

func main() {
	flag.Parse()
	lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", *port))
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}
	var opts []grpc.ServerOption
	if *tls {
		if *certFile == "" {
			*certFile = testdata.Path("server1.pem")
		}
		if *keyFile == "" {
			*keyFile = testdata.Path("server1.key")
		}
		creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile)
		if err != nil {
			log.Fatalf("Failed to generate credentials %v", err)
		}
		opts = []grpc.ServerOption{grpc.Creds(creds)}
	}
	grpcServer := grpc.NewServer(opts...)
	pb.RegisterRouteGuideServer(grpcServer, newServer())
	grpcServer.Serve(lis)
}
<commit_msg>routeguide: reimplement distance calculation<commit_after>/*
 *
 * Copyright 2015 gRPC authors.
 *
 * 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.
 *
 */

//go:generate protoc -I ../routeguide --go_out=plugins=grpc:../routeguide ../routeguide/route_guide.proto

// Package main implements a simple gRPC server that demonstrates how to use gRPC-Go libraries
// to perform unary, client streaming, server streaming and full duplex RPCs.
//
// It implements the route guide service whose definition can be found in routeguide/route_guide.proto.
package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"math"
	"net"
	"sync"
	"time"

	"golang.org/x/net/context"
	"google.golang.org/grpc"

	"google.golang.org/grpc/credentials"
	"google.golang.org/grpc/testdata"

	"github.com/golang/protobuf/proto"

	pb "google.golang.org/grpc/examples/route_guide/routeguide"
)

var (
	tls        = flag.Bool("tls", false, "Connection uses TLS if true, else plain TCP")
	certFile   = flag.String("cert_file", "", "The TLS cert file")
	keyFile    = flag.String("key_file", "", "The TLS key file")
	jsonDBFile = flag.String("json_db_file", "testdata/route_guide_db.json", "A json file containing a list of features")
	port       = flag.Int("port", 10000, "The server port")
)

type routeGuideServer struct {
	savedFeatures []*pb.Feature // read-only after initialized

	mu         sync.Mutex // protects routeNotes
	routeNotes map[string][]*pb.RouteNote
}

// GetFeature returns the feature at the given point.
func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) {
	for _, feature := range s.savedFeatures {
		if proto.Equal(feature.Location, point) {
			return feature, nil
		}
	}
	// No feature was found, return an unnamed feature
	return &pb.Feature{Location: point}, nil
}

// ListFeatures lists all features contained within the given bounding Rectangle.
func (s *routeGuideServer) ListFeatures(rect *pb.Rectangle, stream pb.RouteGuide_ListFeaturesServer) error {
	for _, feature := range s.savedFeatures {
		if inRange(feature.Location, rect) {
			if err := stream.Send(feature); err != nil {
				return err
			}
		}
	}
	return nil
}

// RecordRoute records a route composited of a sequence of points.
//
// It gets a stream of points, and responds with statistics about the "trip":
// number of points,  number of known features visited, total distance traveled, and
// total time spent.
func (s *routeGuideServer) RecordRoute(stream pb.RouteGuide_RecordRouteServer) error {
	var pointCount, featureCount, distance int32
	var lastPoint *pb.Point
	startTime := time.Now()
	for {
		point, err := stream.Recv()
		if err == io.EOF {
			endTime := time.Now()
			return stream.SendAndClose(&pb.RouteSummary{
				PointCount:   pointCount,
				FeatureCount: featureCount,
				Distance:     distance,
				ElapsedTime:  int32(endTime.Sub(startTime).Seconds()),
			})
		}
		if err != nil {
			return err
		}
		pointCount++
		for _, feature := range s.savedFeatures {
			if proto.Equal(feature.Location, point) {
				featureCount++
			}
		}
		if lastPoint != nil {
			distance += calcDistance(lastPoint, point)
		}
		lastPoint = point
	}
}

// RouteChat receives a stream of message/location pairs, and responds with a stream of all
// previous messages at each of those locations.
func (s *routeGuideServer) RouteChat(stream pb.RouteGuide_RouteChatServer) error {
	for {
		in, err := stream.Recv()
		if err == io.EOF {
			return nil
		}
		if err != nil {
			return err
		}
		key := serialize(in.Location)

		s.mu.Lock()
		s.routeNotes[key] = append(s.routeNotes[key], in)
		// Note: this copy prevents blocking other clients while serving this one.
		// We don't need to do a deep copy, because elements in the slice are
		// insert-only and never modified.
		rn := make([]*pb.RouteNote, len(s.routeNotes[key]))
		copy(rn, s.routeNotes[key])
		s.mu.Unlock()

		for _, note := range rn {
			if err := stream.Send(note); err != nil {
				return err
			}
		}
	}
}

// loadFeatures loads features from a JSON file.
func (s *routeGuideServer) loadFeatures(filePath string) {
	file, err := ioutil.ReadFile(filePath)
	if err != nil {
		log.Fatalf("Failed to load default features: %v", err)
	}
	if err := json.Unmarshal(file, &s.savedFeatures); err != nil {
		log.Fatalf("Failed to load default features: %v", err)
	}
}

func toRadians(num float64) float64 {
	return num * math.Pi / float64(180)
}

// calcDistance calculates the distance between two points using the "haversine" formula.
// The formula is based on http://mathforum.org/library/drmath/view/51879.html.
func calcDistance(p1 *pb.Point, p2 *pb.Point) int32 {
	const CordFactor float64 = 1e7
	const R float64 = float64(6371000) // earth radius in metres
	lat1 := toRadians(float64(p1.Latitude) / CordFactor)
	lat2 := toRadians(float64(p2.Latitude) / CordFactor)
	lng1 := toRadians(float64(p1.Longitude) / CordFactor)
	lng2 := toRadians(float64(p2.Longitude) / CordFactor)
	dlat := lat2 - lat1
	dlng := lng2 - lng1

	a := math.Sin(dlat/2)*math.Sin(dlat/2) +
		math.Cos(lat1)*math.Cos(lat2)*
			math.Sin(dlng/2)*math.Sin(dlng/2)
	c := 2 * math.Atan2(math.Sqrt(a), math.Sqrt(1-a))

	distance := R * c
	return int32(distance)
}

func inRange(point *pb.Point, rect *pb.Rectangle) bool {
	left := math.Min(float64(rect.Lo.Longitude), float64(rect.Hi.Longitude))
	right := math.Max(float64(rect.Lo.Longitude), float64(rect.Hi.Longitude))
	top := math.Max(float64(rect.Lo.Latitude), float64(rect.Hi.Latitude))
	bottom := math.Min(float64(rect.Lo.Latitude), float64(rect.Hi.Latitude))

	if float64(point.Longitude) >= left &&
		float64(point.Longitude) <= right &&
		float64(point.Latitude) >= bottom &&
		float64(point.Latitude) <= top {
		return true
	}
	return false
}

func serialize(point *pb.Point) string {
	return fmt.Sprintf("%d %d", point.Latitude, point.Longitude)
}

func newServer() *routeGuideServer {
	s := &routeGuideServer{routeNotes: make(map[string][]*pb.RouteNote)}
	s.loadFeatures(*jsonDBFile)
	return s
}

func main() {
	flag.Parse()
	lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", *port))
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}
	var opts []grpc.ServerOption
	if *tls {
		if *certFile == "" {
			*certFile = testdata.Path("server1.pem")
		}
		if *keyFile == "" {
			*keyFile = testdata.Path("server1.key")
		}
		creds, err := credentials.NewServerTLSFromFile(*certFile, *keyFile)
		if err != nil {
			log.Fatalf("Failed to generate credentials %v", err)
		}
		opts = []grpc.ServerOption{grpc.Creds(creds)}
	}
	grpcServer := grpc.NewServer(opts...)
	pb.RegisterRouteGuideServer(grpcServer, newServer())
	grpcServer.Serve(lis)
}
<|endoftext|>


<commit_before>package physics

import "github.com/leafo/weeklyloops/loops"

type ForceGenerator interface {
	Apply(particle *Particle3d)
}

type ForceGeneratorFunc func(*Particle3d)

func (self ForceGeneratorFunc) Apply(p *Particle3d) {
	self(p)
}

var gravity = ForceGeneratorFunc(func(p *Particle3d) {
	p.ApplyForce(loops.Vec3{0, -15, 0})
})

type Particle3d struct {
	Pos         loops.Vec3
	vel         loops.Vec3
	accel       loops.Vec3
	inverseMass float64

	forces []ForceGenerator
}

func NewParticle3d(mass, x, y, z float64) *Particle3d {
	forces := make([]ForceGenerator, 0)
	forces = append(forces, gravity)

	return &Particle3d{
		Pos:         loops.Vec3{float32(x), float32(y), float32(z)},
		forces:      forces,
		inverseMass: 1 / mass,
	}
}

func (self *Particle3d) SetMass(mass float64) {
	self.inverseMass = 1 / mass
}

func (self *Particle3d) ApplyForce(force loops.Vec3) {
	if self.inverseMass == 0 {
		return
	}

	self.accel = self.accel.Add(force.Scale(float32(self.inverseMass)))
}

func (self *Particle3d) Update(dt float64) {
	if self.inverseMass == 0 {
		return
	}

	self.Pos = self.Pos.Add(self.vel.Scale(float32(dt)))
	self.accel = loops.Vec3{}

	for _, fg := range self.forces {
		fg.Apply(self)
	}

	self.vel = self.vel.Add(self.accel.Scale(float32(dt)))
}
<commit_msg>Mass()<commit_after>package physics

import "github.com/leafo/weeklyloops/loops"

type ForceGenerator interface {
	Apply(particle *Particle3d)
}

type ForceGeneratorFunc func(*Particle3d)

func (self ForceGeneratorFunc) Apply(p *Particle3d) {
	self(p)
}

var gravity = ForceGeneratorFunc(func(p *Particle3d) {
	p.ApplyForce(loops.Vec3{0, -15, 0})
})

type Particle3d struct {
	Pos         loops.Vec3
	vel         loops.Vec3
	accel       loops.Vec3
	inverseMass float64

	forces []ForceGenerator
}

func NewParticle3d(mass, x, y, z float64) *Particle3d {
	forces := make([]ForceGenerator, 0)
	forces = append(forces, gravity)

	return &Particle3d{
		Pos:         loops.Vec3{float32(x), float32(y), float32(z)},
		forces:      forces,
		inverseMass: 1 / mass,
	}
}

func (self *Particle3d) SetMass(mass float64) {
	self.inverseMass = 1 / mass
}

func (self *Particle3d) Mass() float64 {
	return 1 / self.inverseMass
}

func (self *Particle3d) ApplyForce(force loops.Vec3) {
	if self.inverseMass == 0 {
		return
	}

	self.accel = self.accel.Add(force.Scale(float32(self.inverseMass)))
}

func (self *Particle3d) Update(dt float64) {
	if self.inverseMass == 0 {
		return
	}

	self.Pos = self.Pos.Add(self.vel.Scale(float32(dt)))
	self.accel = loops.Vec3{}

	for _, fg := range self.forces {
		fg.Apply(self)
	}

	self.vel = self.vel.Add(self.accel.Scale(float32(dt)))
}
<|endoftext|>


<commit_before>package dou

import (
	"net/http"
	"net/http/httptest"
	"reflect"
	"testing"
)

type recorder struct {
	calledTime int
}

func newRecorder() *recorder {
	return &recorder{calledTime: 0}
}

type testAPI struct {
	beforeDispatchCalled bool
	afterDispatchCalled  bool
	recoverCalled        bool
}

func (p *testAPI) BeforeDispatch(w http.ResponseWriter, r *http.Request) (http.ResponseWriter, *http.Request) {
	p.beforeDispatchCalled = true
	return w, r
}

func (p *testAPI) AfterDispatch(w http.ResponseWriter, r *http.Request) (http.ResponseWriter, *http.Request) {
	p.afterDispatchCalled = true
	return w, r
}

func (p *testAPI) OnPanic(w http.ResponseWriter, r *http.Request) {
	p.recoverCalled = true
}

func (p *testAPI) Marshal(v interface{}) ([]byte, error) {
	return nil, nil
}

func (p *testAPI) Unmarshal(data []byte, v interface{}) error {
	return nil
}

func (p *testAPI) APIStatus(w http.ResponseWriter, code int) {
}

func TestCallBeforeDispatchAndAfterDispatch(t *testing.T) {
	request, _ := http.NewRequest("GET", "/", nil)
	response := httptest.NewRecorder()

	ta := &testAPI{}

	Register("testapi", ta)
	defer delete(plugins, "testapi")

	a, err := NewAPI("testapi")
	a.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})

	if err != nil {
		panic(err)
	}

	a.LogStackTrace = false

	if err != nil {
		panic(err)
	}

	a.ServeHTTP(response, request)

	if !ta.beforeDispatchCalled {
		t.Error("Plugin.BeforeDispatch should be called")
	}

	if !ta.afterDispatchCalled {
		t.Error("Plugin.AfterDispatch should be called")
	}
}

func TestCallOnPanicIfOccurPanicInHandler(t *testing.T) {
	request, _ := http.NewRequest("GET", "/", nil)
	response := httptest.NewRecorder()

	ta := &testAPI{}

	Register("testapi", ta)
	defer delete(plugins, "testapi")

	a, err := NewAPI("testapi")
	a.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		panic("<test panic>")
	})

	if err != nil {
		panic(err)
	}

	a.LogStackTrace = false

	if err != nil {
		panic(err)
	}

	a.ServeHTTP(response, request)

	if !ta.recoverCalled {
		t.Error("Plugin.OnPanic should be called")
	}
}

func TestCallAfterDispatchIfOccurPanicInHandler(t *testing.T) {
	request, _ := http.NewRequest("GET", "/", nil)
	response := httptest.NewRecorder()

	ta := &testAPI{}

	Register("testapi", ta)
	defer delete(plugins, "testapi")

	a, err := NewAPI("testapi")
	a.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		panic("<test panic>")
	})

	if err != nil {
		panic(err)
	}

	a.LogStackTrace = false

	a.ServeHTTP(response, request)

	if !ta.afterDispatchCalled {
		t.Error("Plugin.AfterDispatch should be called")
	}
}

func TestNewSafeWriter(t *testing.T) {
	request, _ := http.NewRequest("GET", "/", nil)
	response := httptest.NewRecorder()

	http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		sw := NewSafeWriter(w)

		if !reflect.DeepEqual(sw.ResponseWriter, w) {
			t.Error("NewSafeWriter should set given value to .ResponseWriter")
		}

		if sw.Wrote != false {
			t.Error("NewSafeWriter should set false to .wrote")
		}
	}).ServeHTTP(response, request)
}

func TestNewSafeWriterWrite(t *testing.T) {
	request, _ := http.NewRequest("GET", "/", nil)
	response := httptest.NewRecorder()

	http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		sw := NewSafeWriter(w)
		sw.Write([]byte("hello"))

		if sw.Wrote != true {
			t.Error("NewSafeWriter.Wrote should be true after called Write")
		}
	}).ServeHTTP(response, request)
}
<commit_msg>Write test for API.Ok and API.Error<commit_after>package dou

import (
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"reflect"
	"strings"
	"testing"
)

type recorder struct {
	calledTime int
}

func newRecorder() *recorder {
	return &recorder{calledTime: 0}
}

type testAPI struct {
	beforeDispatchCalled bool
	afterDispatchCalled  bool
	recoverCalled        bool
}

func (p *testAPI) BeforeDispatch(w http.ResponseWriter, r *http.Request) (http.ResponseWriter, *http.Request) {
	p.beforeDispatchCalled = true
	return w, r
}

func (p *testAPI) AfterDispatch(w http.ResponseWriter, r *http.Request) (http.ResponseWriter, *http.Request) {
	p.afterDispatchCalled = true
	return w, r
}

func (p *testAPI) OnPanic(w http.ResponseWriter, r *http.Request) {
	p.recoverCalled = true
}

// Enable to stub
var testAPIMarshal = func(v interface{}) ([]byte, error) {
	return nil, nil
}

func (p *testAPI) Marshal(v interface{}) ([]byte, error) {
	return testAPIMarshal(v)
}

// Enable to stub
var testAPIUnmarshal = func(data []byte, v interface{}) error {
	return nil
}

func (p *testAPI) Unmarshal(data []byte, v interface{}) error {
	return testAPIUnmarshal(data, v)
}

func (p *testAPI) APIStatus(w http.ResponseWriter, code int) {
}

func TestCallBeforeDispatchAndAfterDispatch(t *testing.T) {
	request, _ := http.NewRequest("GET", "/", nil)
	response := httptest.NewRecorder()

	ta := &testAPI{}

	Register("testapi", ta)
	defer delete(plugins, "testapi")

	a, err := NewAPI("testapi")
	a.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})

	if err != nil {
		panic(err)
	}

	a.LogStackTrace = false

	if err != nil {
		panic(err)
	}

	a.ServeHTTP(response, request)

	if !ta.beforeDispatchCalled {
		t.Error("Plugin.BeforeDispatch should be called")
	}

	if !ta.afterDispatchCalled {
		t.Error("Plugin.AfterDispatch should be called")
	}
}

func TestCallOnPanicIfOccurPanicInHandler(t *testing.T) {
	request, _ := http.NewRequest("GET", "/", nil)
	response := httptest.NewRecorder()

	ta := &testAPI{}

	Register("testapi", ta)
	defer delete(plugins, "testapi")

	a, err := NewAPI("testapi")
	a.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		panic("<test panic>")
	})

	if err != nil {
		panic(err)
	}

	a.LogStackTrace = false

	if err != nil {
		panic(err)
	}

	a.ServeHTTP(response, request)

	if !ta.recoverCalled {
		t.Error("Plugin.OnPanic should be called")
	}
}

func TestCallAfterDispatchIfOccurPanicInHandler(t *testing.T) {
	request, _ := http.NewRequest("GET", "/", nil)
	response := httptest.NewRecorder()

	ta := &testAPI{}

	Register("testapi", ta)
	defer delete(plugins, "testapi")

	a, err := NewAPI("testapi")
	a.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		panic("<test panic>")
	})

	if err != nil {
		panic(err)
	}

	a.LogStackTrace = false

	a.ServeHTTP(response, request)

	if !ta.afterDispatchCalled {
		t.Error("Plugin.AfterDispatch should be called")
	}
}

func TestNewSafeWriter(t *testing.T) {
	request, _ := http.NewRequest("GET", "/", nil)
	response := httptest.NewRecorder()

	http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		sw := NewSafeWriter(w)

		if !reflect.DeepEqual(sw.ResponseWriter, w) {
			t.Error("NewSafeWriter should set given value to .ResponseWriter")
		}

		if sw.Wrote != false {
			t.Error("NewSafeWriter should set false to .wrote")
		}
	}).ServeHTTP(response, request)
}

func TestNewSafeWriterWrite(t *testing.T) {
	request, _ := http.NewRequest("GET", "/", nil)
	response := httptest.NewRecorder()

	http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		sw := NewSafeWriter(w)
		sw.Write([]byte("hello"))

		if sw.Wrote != true {
			t.Error("NewSafeWriter.Wrote should be true after called Write")
		}
	}).ServeHTTP(response, request)
}
func TestAPIOkSetGivenHTTPStatusCodeAndResponseBody(t *testing.T) {
	request, _ := http.NewRequest("GET", "/", nil)
	response := httptest.NewRecorder()

	Register("testapi", &testAPI{})
	defer delete(plugins, "testapi")

	expectedBodyString := "stubed testAPIMarshal"
	expectedCode := http.StatusCreated

	// stub testAPI.Marshal
	testAPIMarshal = func(v interface{}) ([]byte, error) {
		return []byte(expectedBodyString), nil
	}

	a, err := NewAPI("testapi")
	a.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		a.Ok(w, "", expectedCode)
	})

	if err != nil {
		panic(err)
	}

	a.ServeHTTP(response, request)

	// [Test] http status code
	if response.Code != expectedCode {
		t.Errorf("API.OK should set given status code\nexpected: %v\ngot: %v\n", expectedCode, response.Code)
	}

	// [Test] responseBody
	gotBody, err := ioutil.ReadAll(response.Body)

	if err != nil {
		panic(err)
	}

	gotBodyString := strings.TrimSuffix(string(gotBody), "\n")

	if gotBodyString != expectedBodyString {
		t.Errorf("API.OK should marshal given resource and write it\nexpected: %v\ngot: %v\n", expectedBodyString, gotBodyString)
	}
}

func TestAPIOkSet200IfGiven0AsHTTPStatusCode(t *testing.T) {
	request, _ := http.NewRequest("GET", "/", nil)
	response := httptest.NewRecorder()

	Register("testapi", &testAPI{})
	defer delete(plugins, "testapi")

	a, err := NewAPI("testapi")
	a.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		a.Ok(w, "", 0)
	})

	if err != nil {
		panic(err)
	}

	a.ServeHTTP(response, request)

	if response.Code != http.StatusOK {
		t.Errorf("API.OK should set 200 if given 0\nexpected: %v\ngot: %v\n", http.StatusOK, response.Code)
	}

}

func TestAPIErrorSetGivenHTTPStatusCodeAndResponseBody(t *testing.T) {
	request, _ := http.NewRequest("GET", "/", nil)
	response := httptest.NewRecorder()

	Register("testapi", &testAPI{})
	defer delete(plugins, "testapi")

	expectedBodyString := "stubed testAPIMarshal"
	expectedCode := http.StatusNotFound

	// stub testAPI.Marshal
	testAPIMarshal = func(v interface{}) ([]byte, error) {
		return []byte(expectedBodyString), nil
	}

	a, err := NewAPI("testapi")
	a.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		a.Error(w, "", expectedCode)
	})

	if err != nil {
		panic(err)
	}

	a.ServeHTTP(response, request)

	// [Test] http status code
	if response.Code != expectedCode {
		t.Errorf("API.Error should set given status code\nexpected: %v\ngot: %v\n", expectedCode, response.Code)
	}

	// [Test] responseBody
	gotBody, err := ioutil.ReadAll(response.Body)

	if err != nil {
		panic(err)
	}

	gotBodyString := strings.TrimSuffix(string(gotBody), "\n")

	if gotBodyString != expectedBodyString {
		t.Errorf("API.Error should marshal given resource and write it\nexpected: \"%v\"\ngot: \"%v\"\n", expectedBodyString, gotBodyString)
	}
}

func TestAPIErrorSet500IfGiven0AsHTTPStatusCode(t *testing.T) {
	request, _ := http.NewRequest("GET", "/", nil)
	response := httptest.NewRecorder()

	Register("testapi", &testAPI{})
	defer delete(plugins, "testapi")

	a, err := NewAPI("testapi")
	a.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		a.Error(w, "", 0)
	})

	if err != nil {
		panic(err)
	}

	a.ServeHTTP(response, request)

	if response.Code != http.StatusInternalServerError {
		t.Errorf("API.OK should set 200 if given 0\nexpected: %v\ngot: %v\n", http.StatusOK, response.Code)
	}

}
<|endoftext|>


<commit_before>package catalog

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

	"github.com/dnaeon/gru/graph"
	"github.com/dnaeon/gru/module"
	"github.com/dnaeon/gru/resource"
)

// ErrEmptyCatalog is returned when no resources were found from the
// loaded modules in the catalog
var ErrEmptyCatalog = errors.New("Catalog is empty")

type resourceMap map[string]resource.Resource

// Catalog type represents a collection of modules loaded from HCL or JSON
type Catalog struct {
	modules []*module.Module
}

// newCatalog creates a new empty catalog
func newCatalog() *Catalog {
	c := &Catalog{
		modules: make([]*module.Module, 0),
	}

	return c
}

// createResourceMap creates a map of the unique resource IDs and
// the actual resource instances
func (c *Catalog) createResourceMap() (resourceMap, error) {
	// A map containing the unique resource ID and the
	// module where the resource has been declared
	rModuleMap := make(map[string]string)

	rMap := make(resourceMap)
	for _, m := range c.modules {
		for _, r := range m.Resources {
			id := r.ID()
			if _, ok := rMap[id]; ok {
				return rMap, fmt.Errorf("Duplicate resource %s in %s, previous declaration was in %s", id, m.Name, rModuleMap[id])
			}
			rModuleMap[id] = m.Name
			rMap[id] = r
		}
	}

	if len(rMap) == 0 {
		return rMap, ErrEmptyCatalog
	}

	return rMap, nil
}

// resourceGraph creates a DAG graph for the resources in catalog
func (c *Catalog) resourceGraph() (*graph.Graph, error) {
	// Create a DAG graph of the resources in catalog
	// The generated graph can be topologically sorted in order to
	// determine the proper order of evaluating resources
	// If the graph cannot be sorted, it means we have a
	// circular dependency in our resources
	g := graph.NewGraph()

	resources, err := c.createResourceMap()
	if err != nil {
		return g, err
	}

	// A map containing the resource ids and their nodes in the graph
	// Create a graph nodes for each resource from the catalog
	nodes := make(map[string]*graph.Node)
	for name := range resources {
		node := graph.NewNode(name)
		nodes[name] = node
		g.AddNode(node)
	}

	// Connect the nodes in the graph
	for name, r := range resources {
		deps := r.Want()
		for _, dep := range deps {
			if _, ok := resources[dep]; !ok {
				e := fmt.Errorf("Resource %s wants %s, which is not in catalog", name, dep)
				return g, e
			}
			g.AddEdge(nodes[name], nodes[dep])
		}
	}

	return g, nil
}

// Run processes the catalog
func (c *Catalog) Run() error {
	rMap, err := c.createResourceMap()
	if err != nil {
		return err
	}

	// Perform topological sort of the resources graph
	g, err := c.resourceGraph()
	if err != nil {
		return err
	}

	sorted, err := g.Sort()
	if err != nil {
		return err
	}

	for _, node := range sorted {
		r := rMap[node.Name]
		id := r.ID()

		err = r.Validate()
		if err != nil {
			log.Printf("Failed to validate resource %s: %s", id, err)
			continue
		}

		state, err := r.Evaluate()
		if err != nil {
			log.Printf("Failed to evaluate resource '%s': %s", id, err)
			continue
		}

		if !resource.StateIsValid(state.Want) || !resource.StateIsValid(state.Current) {
			log.Printf("Invalid state(s) for resource %s: want %s, current %s", id, state.Want, state.Current)
			continue
		}

		if state.Want == state.Current {
			continue
		}

		if state.Want == resource.StatePresent || state.Want == resource.StateRunning {
			switch state.Current {
			case resource.StateAbsent, resource.StateStopped:
				log.Printf("%s is %s, should be %s", id, state.Current, state.Want)
				r.Create()
			case resource.StateUpdate:
				log.Printf("%s changed, should be updated", id)
				r.Update()
			}
		} else if state.Want == resource.StateAbsent || state.Want == resource.StateStopped {
			switch state.Current {
			case resource.StatePresent, resource.StateRunning, resource.StateUpdate:
				log.Printf("%s is %s, should be %s", id, state.Current, state.Want)
				r.Delete()
			}
		}
	}

	return nil
}

// GenerateCatalogDOT generates a DOT file for the resources in catalog
func (c *Catalog) GenerateCatalogDOT(w io.Writer) error {
	g, err := c.resourceGraph()
	if err != nil {
		return err
	}
	g.GenerateDOT("resources", w)

	// Try a topological sort of the graph
	// In case of circular dependencies in the graph
	// generate a DOT file for the remaining nodes in the graph,
	// which would give us the resources causing circular dependencies
	if nodes, err := g.Sort(); err == graph.ErrCircularDependency {
		circularGraph := graph.NewGraph()
		circularGraph.AddNode(nodes...)
		circularGraph.GenerateDOT("resources_circular", w)
	}

	return nil
}

// Len returns the number of unique resources found in catalog
func (c *Catalog) Len() int {
	resources, err := c.createResourceMap()
	if err != nil {
		return 0
	}

	return len(resources)
}

// Load creates a catalog from the provided module name
func Load(main, path string) (*Catalog, error) {
	c := newCatalog()

	// Discover all modules from the provided module path
	registry, err := module.Discover(path)
	if _, ok := registry[main]; !ok {
		return c, fmt.Errorf("Module %s was not found in the module path", main)
	}

	// A map containing the module names and the actual loaded modules
	moduleNames := make(map[string]*module.Module)
	for n, p := range registry {
		m, err := module.Load(n, p)
		if err != nil {
			return c, err
		}
		moduleNames[n] = m
	}

	// A map containing the modules as graph nodes
	// The graph is used to determine if we have
	// circular module imports and also to provide the
	// proper ordering of loading modules after a
	// topological sort of the graph nodes
	nodes := make(map[string]*graph.Node)
	for n := range moduleNames {
		node := graph.NewNode(n)
		nodes[n] = node
	}

	// Recursively find all imports that the main module has and
	// resolve the dependency graph
	g := graph.NewGraph()
	var createModuleGraph func(m *module.Module) error
	createModuleGraph = func(m *module.Module) error {
		if !g.NodeExists(m.Name) {
			g.AddNode(nodes[m.Name])
		} else {
			return nil
		}

		for _, importName := range m.ModuleImport.Module {
			if _, ok := moduleNames[importName]; !ok {
				return fmt.Errorf("Module %s imports %s, which is not in the module path", m.Name, importName)
			}

			// Build the dependencies of imported modules as well
			createModuleGraph(moduleNames[importName])

			// Finally connect the nodes in the graph
			g.AddEdge(nodes[m.Name], nodes[importName])
		}

		return nil
	}

	//	Build the dependency graph of the module imports
	err = createModuleGraph(moduleNames[main])
	if err != nil {
		return c, err
	}

	// Topologically sort the graph
	// In case of an error it means we have a circular import
	sorted, err := g.Sort()
	if err != nil {
		return c, err
	}

	// Finally add the sorted modules to the catalog
	for _, node := range sorted {
		c.modules = append(c.modules, moduleNames[node.Name])
	}

	return c, nil
}

// MarshalJSON creates a stripped down version of the catalog in JSON,
// which contains all resources from the catalog and is suitable for
// clients to consume in order to create a single-module catalog from it.
func (c *Catalog) MarshalJSON() ([]byte, error) {
	rMap, err := c.createResourceMap()
	if err != nil {
		return nil, err
	}

	resources := make([]resourceMap, 0)
	for _, r := range rMap {
		rJson := resourceMap{
			r.Type(): r,
		}
		resources = append(resources, rJson)
	}

	return json.Marshal(map[string]interface{}{
		"resource": resources,
	})
}
<commit_msg>Update resource it if is out of date<commit_after>package catalog

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

	"github.com/dnaeon/gru/graph"
	"github.com/dnaeon/gru/module"
	"github.com/dnaeon/gru/resource"
)

// ErrEmptyCatalog is returned when no resources were found from the
// loaded modules in the catalog
var ErrEmptyCatalog = errors.New("Catalog is empty")

type resourceMap map[string]resource.Resource

// Catalog type represents a collection of modules loaded from HCL or JSON
type Catalog struct {
	modules []*module.Module
}

// newCatalog creates a new empty catalog
func newCatalog() *Catalog {
	c := &Catalog{
		modules: make([]*module.Module, 0),
	}

	return c
}

// createResourceMap creates a map of the unique resource IDs and
// the actual resource instances
func (c *Catalog) createResourceMap() (resourceMap, error) {
	// A map containing the unique resource ID and the
	// module where the resource has been declared
	rModuleMap := make(map[string]string)

	rMap := make(resourceMap)
	for _, m := range c.modules {
		for _, r := range m.Resources {
			id := r.ID()
			if _, ok := rMap[id]; ok {
				return rMap, fmt.Errorf("Duplicate resource %s in %s, previous declaration was in %s", id, m.Name, rModuleMap[id])
			}
			rModuleMap[id] = m.Name
			rMap[id] = r
		}
	}

	if len(rMap) == 0 {
		return rMap, ErrEmptyCatalog
	}

	return rMap, nil
}

// resourceGraph creates a DAG graph for the resources in catalog
func (c *Catalog) resourceGraph() (*graph.Graph, error) {
	// Create a DAG graph of the resources in catalog
	// The generated graph can be topologically sorted in order to
	// determine the proper order of evaluating resources
	// If the graph cannot be sorted, it means we have a
	// circular dependency in our resources
	g := graph.NewGraph()

	resources, err := c.createResourceMap()
	if err != nil {
		return g, err
	}

	// A map containing the resource ids and their nodes in the graph
	// Create a graph nodes for each resource from the catalog
	nodes := make(map[string]*graph.Node)
	for name := range resources {
		node := graph.NewNode(name)
		nodes[name] = node
		g.AddNode(node)
	}

	// Connect the nodes in the graph
	for name, r := range resources {
		deps := r.Want()
		for _, dep := range deps {
			if _, ok := resources[dep]; !ok {
				e := fmt.Errorf("Resource %s wants %s, which is not in catalog", name, dep)
				return g, e
			}
			g.AddEdge(nodes[name], nodes[dep])
		}
	}

	return g, nil
}

// Run processes the catalog
func (c *Catalog) Run() error {
	rMap, err := c.createResourceMap()
	if err != nil {
		return err
	}

	// Perform topological sort of the resources graph
	g, err := c.resourceGraph()
	if err != nil {
		return err
	}

	sorted, err := g.Sort()
	if err != nil {
		return err
	}

	for _, node := range sorted {
		r := rMap[node.Name]
		id := r.ID()

		err = r.Validate()
		if err != nil {
			log.Printf("Failed to validate resource %s: %s", id, err)
			continue
		}

		state, err := r.Evaluate()
		if err != nil {
			log.Printf("Failed to evaluate resource '%s': %s", id, err)
			continue
		}

		if !resource.StateIsValid(state.Want) || !resource.StateIsValid(state.Current) {
			log.Printf("Invalid state(s) for resource %s: want %s, current %s", id, state.Want, state.Current)
			continue
		}

		// If resource is in the desired state, but out of date
		if state.Want == state.Current && state.Update {
			r.Update()
			continue
		}

		log.Printf("%s is %s, should be %s", id, state.Current, state.Want)
		if state.Want == resource.StatePresent || state.Want == resource.StateRunning {
			if state.Current == resource.StateAbsent || state.Current == resource.StateStopped {
				r.Create()
			}
		} else {
			if state.Current == resource.StatePresent || state.Current == resource.StateRunning {
				r.Delete()
			}
		}

		if state.Update {
			r.Update()
		}
	}

	return nil
}

// GenerateCatalogDOT generates a DOT file for the resources in catalog
func (c *Catalog) GenerateCatalogDOT(w io.Writer) error {
	g, err := c.resourceGraph()
	if err != nil {
		return err
	}
	g.GenerateDOT("resources", w)

	// Try a topological sort of the graph
	// In case of circular dependencies in the graph
	// generate a DOT file for the remaining nodes in the graph,
	// which would give us the resources causing circular dependencies
	if nodes, err := g.Sort(); err == graph.ErrCircularDependency {
		circularGraph := graph.NewGraph()
		circularGraph.AddNode(nodes...)
		circularGraph.GenerateDOT("resources_circular", w)
	}

	return nil
}

// Len returns the number of unique resources found in catalog
func (c *Catalog) Len() int {
	resources, err := c.createResourceMap()
	if err != nil {
		return 0
	}

	return len(resources)
}

// Load creates a catalog from the provided module name
func Load(main, path string) (*Catalog, error) {
	c := newCatalog()

	// Discover all modules from the provided module path
	registry, err := module.Discover(path)
	if _, ok := registry[main]; !ok {
		return c, fmt.Errorf("Module %s was not found in the module path", main)
	}

	// A map containing the module names and the actual loaded modules
	moduleNames := make(map[string]*module.Module)
	for n, p := range registry {
		m, err := module.Load(n, p)
		if err != nil {
			return c, err
		}
		moduleNames[n] = m
	}

	// A map containing the modules as graph nodes
	// The graph is used to determine if we have
	// circular module imports and also to provide the
	// proper ordering of loading modules after a
	// topological sort of the graph nodes
	nodes := make(map[string]*graph.Node)
	for n := range moduleNames {
		node := graph.NewNode(n)
		nodes[n] = node
	}

	// Recursively find all imports that the main module has and
	// resolve the dependency graph
	g := graph.NewGraph()
	var createModuleGraph func(m *module.Module) error
	createModuleGraph = func(m *module.Module) error {
		if !g.NodeExists(m.Name) {
			g.AddNode(nodes[m.Name])
		} else {
			return nil
		}

		for _, importName := range m.ModuleImport.Module {
			if _, ok := moduleNames[importName]; !ok {
				return fmt.Errorf("Module %s imports %s, which is not in the module path", m.Name, importName)
			}

			// Build the dependencies of imported modules as well
			createModuleGraph(moduleNames[importName])

			// Finally connect the nodes in the graph
			g.AddEdge(nodes[m.Name], nodes[importName])
		}

		return nil
	}

	//	Build the dependency graph of the module imports
	err = createModuleGraph(moduleNames[main])
	if err != nil {
		return c, err
	}

	// Topologically sort the graph
	// In case of an error it means we have a circular import
	sorted, err := g.Sort()
	if err != nil {
		return c, err
	}

	// Finally add the sorted modules to the catalog
	for _, node := range sorted {
		c.modules = append(c.modules, moduleNames[node.Name])
	}

	return c, nil
}

// MarshalJSON creates a stripped down version of the catalog in JSON,
// which contains all resources from the catalog and is suitable for
// clients to consume in order to create a single-module catalog from it.
func (c *Catalog) MarshalJSON() ([]byte, error) {
	rMap, err := c.createResourceMap()
	if err != nil {
		return nil, err
	}

	resources := make([]resourceMap, 0)
	for _, r := range rMap {
		rJson := resourceMap{
			r.Type(): r,
		}
		resources = append(resources, rJson)
	}

	return json.Marshal(map[string]interface{}{
		"resource": resources,
	})
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"github.com/docker/docker/pkg/archive"
	"io"
	"io/ioutil"
	"net/http"
	"os"
)

var VERSION = "0.2.0"

func usage() {
	fmt.Printf("Usage: %s https://example.org/download.tar.bz2\n", os.Args[0])
	os.Exit(1)
}

func version() {
	fmt.Println(VERSION)
	os.Exit(0)
}

func tls_config() *tls.Config {
	pool := x509.NewCertPool()
	cert, err := ioutil.ReadFile("./.cert")
	if err != nil {
		fmt.Printf("Failed to load certificate -- %s\n", err)
		os.Exit(1)
	}
	pool.AppendCertsFromPEM(cert)
	return &tls.Config{RootCAs: pool}
}

func download(url string) io.Reader {
	transport := &http.Transport{TLSClientConfig: tls_config()}
	client := &http.Client{Transport: transport}
	response, err := client.Get(url)
	if err != nil {
		fmt.Printf("Failed to download %s -- %s\n", url, err)
		os.Exit(1)
	}
	fmt.Printf("Downloaded %s\n", url)
	return response.Body
}

func main() {
	if len(os.Args) < 2 {
		usage()
	}
	if os.Args[1] == "-v" {
		version()
	}
	err := archive.Untar(download(os.Args[1]), "/", nil)
	if err != nil {
		fmt.Printf("Failed to extract -- %s\n", err)
	}
	fmt.Println("Successfully extracted archive")
}
<commit_msg>update to 0.2.1<commit_after>package main

import (
	"crypto/tls"
	"crypto/x509"
	"fmt"
	"github.com/docker/docker/pkg/archive"
	"io"
	"io/ioutil"
	"net/http"
	"os"
)

var VERSION = "0.2.1"

func usage() {
	fmt.Printf("Usage: %s https://example.org/download.tar.bz2\n", os.Args[0])
	os.Exit(1)
}

func version() {
	fmt.Println(VERSION)
	os.Exit(0)
}

func tls_config() *tls.Config {
	pool := x509.NewCertPool()
	cert, err := ioutil.ReadFile("./.cert")
	if err != nil {
		fmt.Printf("Failed to load certificate -- %s\n", err)
		os.Exit(1)
	}
	pool.AppendCertsFromPEM(cert)
	return &tls.Config{RootCAs: pool}
}

func download(url string) io.Reader {
	transport := &http.Transport{TLSClientConfig: tls_config()}
	client := &http.Client{Transport: transport}
	response, err := client.Get(url)
	if err != nil {
		fmt.Printf("Failed to download %s -- %s\n", url, err)
		os.Exit(1)
	}
	fmt.Printf("Downloaded %s\n", url)
	return response.Body
}

func main() {
	if len(os.Args) < 2 {
		usage()
	}
	if os.Args[1] == "-v" {
		version()
	}
	err := archive.Untar(download(os.Args[1]), "/", nil)
	if err != nil {
		fmt.Printf("Failed to extract -- %s\n", err)
	}
	fmt.Println("Successfully extracted archive")
}
<|endoftext|>


<commit_before>package cgo

import (
	"github.com/stretchr/testify/assert"
	"go/ast"
	"testing"
)

func TestSingleImport(t *testing.T) {
	subject := Imports("C")
	assert.NotNil(t, subject)
	genDecl := subject.(*ast.GenDecl)
	assert.Equal(t, 1, len(genDecl.Specs))
	importSpec := genDecl.Specs[0].(*ast.ImportSpec)
	assert.Equal(t, "\"C\"", importSpec.Path.Value)
}

func TestMultipleImports(t *testing.T) {
	subject := Imports("foo", "bar", "baz")
	assert.NotNil(t, subject)
	genDecl := subject.(*ast.GenDecl)
	assert.Equal(t, 3, len(genDecl.Specs))
}
<commit_msg>fix the import test<commit_after>package cgo

import (
	"github.com/stretchr/testify/assert"
	"go/ast"
	"testing"
)

func TestSingleImport(t *testing.T) {
	subject := Imports("C")
	assert.NotNil(t, subject)
	genDecl := subject
	assert.Equal(t, 1, len(genDecl.Specs))
	importSpec := genDecl.Specs[0].(*ast.ImportSpec)
	assert.Equal(t, "\"C\"", importSpec.Path.Value)
}

func TestMultipleImports(t *testing.T) {
	subject := Imports("foo", "bar", "baz")
	assert.NotNil(t, subject)
	genDecl := subject
	assert.Equal(t, 3, len(genDecl.Specs))
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"errors"
	"fmt"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// DATA MODEL

type CarOwner struct {
	OwnerID string `json:"userID"`
	Name    string `json:"name"`
}

type Car struct {
	CarID string `json:"carID"`
}

type TestData struct {
	CarOwners []CarOwner `json:"carOwners"`
	Cars      []Car      `json:"cars"`
}

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

// ============================================================================================================================
// Main
// ============================================================================================================================
func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

// Init resets all the things
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	if len(args) != 1 {
		return nil, errors.New("Incorrect number of arguments. Expecting 1")
	}

	// Create test cars
	t.addTestdata(stub, args[0])

	return nil, nil
}

func (t *SimpleChaincode) addTestdata(stub shim.ChaincodeStubInterface, testDataAsJson string) error {
	var testData TestData
	err := json.Unmarshal([]byte(testDataAsJson), &testData)
	if err != nil {
		return errors.New("Error while unmarshalling testdata")
	}

	for _, carOwner := range testData.CarOwners {
		carOwnerAsBytes, err := json.Marshal(carOwner)
		if err != nil {
			return errors.New("Error marshalling testCarOwner, reason: " + err.Error())
		}

		err = StoreObjectInChain(stub, carOwner.OwnerID, "_owners", carOwnerAsBytes)
		if err != nil {
			return errors.New("error in storing object, reason: " + err.Error())
		}
	}

	for _, car := range testData.Cars {
		carAsBytes, err := json.Marshal(car)
		if err != nil {
			return errors.New("Error marshalling testCar, reason: " + err.Error())
		}

		err = StoreObjectInChain(stub, car.CarID, "_cars", carAsBytes)
		if err != nil {
			return errors.New("error in storing object, reason: " + err.Error())
		}
	}

	return nil
}

func getTestData(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	fmt.Println("Retrieving Owner Name")

	if len(args) < 1 {
		fmt.Println("Invalid number of arguments")
		return nil, errors.New("Missing owner ID")
	}

	var ownerID = args[0]
	bytes, err := stub.GetState(ownerID)
	if err != nil {
		fmt.Println("Could not fetch owner id "+ownerID+" from ledger", err)
		return nil, err
	}
	return bytes, nil
}

func StoreObjectInChain(stub shim.ChaincodeStubInterface, objectID string, indexName string, object []byte) error {
	ID, err := WriteIDToBlockchainIndex(stub, indexName, objectID)
	if err != nil {
		return errors.New("Writing ID to index: " + indexName + "Reason: " + err.Error())
	}

	fmt.Println("adding: ", string(object))

	err = stub.PutState(string(ID), object)
	if err != nil {
		return errors.New("Putstate error: " + err.Error())
	}

	return nil
}

func WriteIDToBlockchainIndex(stub shim.ChaincodeStubInterface, indexName string, id string) ([]byte, error) {
	index, err := GetIndex(stub, indexName)
	if err != nil {
		return nil, err
	}

	index = append(index, id)

	jsonAsBytes, err := json.Marshal(index)
	if err != nil {
		return nil, errors.New("Error marshalling index '" + indexName + "': " + err.Error())
	}

	err = stub.PutState(indexName, jsonAsBytes)
	if err != nil {
		return nil, errors.New("Error storing new " + indexName + " into ledger")
	}

	return []byte(id), nil
}

func GetIndex(stub shim.ChaincodeStubInterface, indexName string) ([]string, error) {
	indexAsBytes, err := stub.GetState(indexName)
	if err != nil {
		return nil, errors.New("Failed to get " + indexName)
	}

	var index []string
	err = json.Unmarshal(indexAsBytes, &index)
	if err != nil {
		return nil, errors.New("Error unmarshalling index '" + indexName + "': " + err.Error())
	}

	return index, nil
}

// Invoke is our entry point to invoke a chaincode function
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("invoke is running " + function)

	// Handle different functions
	if function == "init" { //initialize the chaincode state, used as reset
		return t.Init(stub, "init", args)
	}
	fmt.Println("invoke did not find func: " + function) //error

	return nil, errors.New("Received unknown function invocation: " + function)
}

// Query is our entry point for queries
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("query is running " + function)
	// Handle different functions
	if function == "dummy_query" { //read a variable
		fmt.Println("hi there " + function) //error
		return nil, nil
	} else if function == "getTestData" {
		fmt.Println("Starting the function " + function)
		return getTestData(stub, args)
	}
	fmt.Println("query did not find func: " + function) //error

	return nil, errors.New("Received unknown function query: " + function)
}
<commit_msg>print test data<commit_after>package main

import (
	"encoding/json"
	"errors"
	"fmt"

	"github.com/hyperledger/fabric/core/chaincode/shim"
)

// DATA MODEL

type CarOwner struct {
	OwnerID string `json:"userID"`
	Name    string `json:"name"`
}

type Car struct {
	CarID string `json:"carID"`
}

type TestData struct {
	CarOwners []CarOwner `json:"carOwners"`
	Cars      []Car      `json:"cars"`
}

// SimpleChaincode example simple Chaincode implementation
type SimpleChaincode struct {
}

// ============================================================================================================================
// Main
// ============================================================================================================================
func main() {
	err := shim.Start(new(SimpleChaincode))
	if err != nil {
		fmt.Printf("Error starting Simple chaincode: %s", err)
	}
}

// Init resets all the things
func (t *SimpleChaincode) Init(stub shim.ChaincodeStubInterface, function string, initJson string) ([]byte, error) {
	fmt.Println(initJson)

	// Create test cars
	t.addTestdata(stub, initJson)

	return nil, nil
}

func (t *SimpleChaincode) addTestdata(stub shim.ChaincodeStubInterface, testDataAsJson string) error {
	var testData TestData
	err := json.Unmarshal([]byte(testDataAsJson), &testData)
	if err != nil {
		return errors.New("Error while unmarshalling testdata")
	}

	for _, carOwner := range testData.CarOwners {
		carOwnerAsBytes, err := json.Marshal(carOwner)
		if err != nil {
			return errors.New("Error marshalling testCarOwner, reason: " + err.Error())
		}

		err = StoreObjectInChain(stub, carOwner.OwnerID, "_owners", carOwnerAsBytes)
		if err != nil {
			return errors.New("error in storing object, reason: " + err.Error())
		}
	}

	for _, car := range testData.Cars {
		carAsBytes, err := json.Marshal(car)
		if err != nil {
			return errors.New("Error marshalling testCar, reason: " + err.Error())
		}

		err = StoreObjectInChain(stub, car.CarID, "_cars", carAsBytes)
		if err != nil {
			return errors.New("error in storing object, reason: " + err.Error())
		}
	}

	return nil
}

func getTestData(stub shim.ChaincodeStubInterface, args []string) ([]byte, error) {
	fmt.Println("Retrieving Owner Name")

	if len(args) < 1 {
		fmt.Println("Invalid number of arguments")
		return nil, errors.New("Missing owner ID")
	}

	var ownerID = args[0]
	bytes, err := stub.GetState(ownerID)
	if err != nil {
		fmt.Println("Could not fetch owner id "+ownerID+" from ledger", err)
		return nil, err
	}
	return bytes, nil
}

func StoreObjectInChain(stub shim.ChaincodeStubInterface, objectID string, indexName string, object []byte) error {
	ID, err := WriteIDToBlockchainIndex(stub, indexName, objectID)
	if err != nil {
		return errors.New("Writing ID to index: " + indexName + "Reason: " + err.Error())
	}

	fmt.Println("adding: ", string(object))

	err = stub.PutState(string(ID), object)
	if err != nil {
		return errors.New("Putstate error: " + err.Error())
	}

	return nil
}

func WriteIDToBlockchainIndex(stub shim.ChaincodeStubInterface, indexName string, id string) ([]byte, error) {
	index, err := GetIndex(stub, indexName)
	if err != nil {
		return nil, err
	}

	index = append(index, id)

	jsonAsBytes, err := json.Marshal(index)
	if err != nil {
		return nil, errors.New("Error marshalling index '" + indexName + "': " + err.Error())
	}

	err = stub.PutState(indexName, jsonAsBytes)
	if err != nil {
		return nil, errors.New("Error storing new " + indexName + " into ledger")
	}

	return []byte(id), nil
}

func GetIndex(stub shim.ChaincodeStubInterface, indexName string) ([]string, error) {
	indexAsBytes, err := stub.GetState(indexName)
	if err != nil {
		return nil, errors.New("Failed to get " + indexName)
	}

	var index []string
	err = json.Unmarshal(indexAsBytes, &index)
	if err != nil {
		return nil, errors.New("Error unmarshalling index '" + indexName + "': " + err.Error())
	}

	return index, nil
}

// Invoke is our entry point to invoke a chaincode function
func (t *SimpleChaincode) Invoke(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("invoke is running " + function)

	// Handle different functions
	if function == "init" { //initialize the chaincode state, used as reset
		return t.Init(stub, "init", args)
	}
	fmt.Println("invoke did not find func: " + function) //error

	return nil, errors.New("Received unknown function invocation: " + function)
}

// Query is our entry point for queries
func (t *SimpleChaincode) Query(stub shim.ChaincodeStubInterface, function string, args []string) ([]byte, error) {
	fmt.Println("query is running " + function)
	// Handle different functions
	if function == "dummy_query" { //read a variable
		fmt.Println("hi there " + function) //error
		return nil, nil
	} else if function == "getTestData" {
		fmt.Println("Starting the function " + function)
		return getTestData(stub, args)
	}
	fmt.Println("query did not find func: " + function) //error

	return nil, errors.New("Received unknown function query: " + function)
}
<|endoftext|>


<commit_before>package charmap

import (
	"strings"
)

// Private types for rune and string slices
type unicodeSequence []string

type sequenceIndex interface {
	index(char string) int
}

// Private map to hold all sequences
type charMap map[string]sequenceIndex

// Languagewise unicode ranges
var langBases = map[string]int{
	"en_US": 0,
	"en_IN": 0,
	"hi_IN": '\u0901',
	"bn_IN": '\u0981',
	"pa_IN": '\u0a01',
	"gu_IN": '\u0a81',
	"or_IN": '\u0b01',
	"ta_IN": '\u0b81',
	"te_IN": '\u0c01',
	"kn_IN": '\u0c81',
	"ml_IN": '\u0D01',
}

// Slices to hold unicode range for each languagges
var devaAlphabets = make(unicodeSequence, 80)
var bengAlphabets = make(unicodeSequence, 80)
var guruAlphabets = make(unicodeSequence, 80)
var gujrAlphabets = make(unicodeSequence, 80)
var oryaAlphabets = make(unicodeSequence, 80)
var tamlAlphabets = make(unicodeSequence, 80)
var teluAlphabets = make(unicodeSequence, 80)
var kndaAlphabets = make(unicodeSequence, 80)
var mlymAlphabets = make(unicodeSequence, 80)

var enUsAlphabets = unicodeSequence{`a`, `b`, `c`, `d`, `e`, `f`, `g`, `h`, `i`, `j`, `k`, `l`, `m`, `n`, `o`, `p`, `q`, `r`, `s`, `t`, `u`, `v`, `w`, `x`, `y`, `z`}

// Soundex values for English alphabet series
var soundexEnglish = unicodeSequence{`0`, `1`, `2`, `3`, `0`, `1`, `2`, `0`, `0`, `2`, `2`, `4`, `5`, `5`, `0`, `1`, `2`, `6`, `2`, `3`, `0`, `1`, `0`, `2`, `0`, `2`}

// Soundex values for Indian language unicode series.
var soundexIndic = unicodeSequence{`0`, `N`, `0`, `0`, `A`, `A`, `B`, `B`, `C`, `C`, `P`, `Q`, `0`, `D`, `D`, `D`, `E`, `E`, `E`, `E`, `F`, `F`, `F`, `F`, `G`, `H`, `H`, `H`, `H`, `G`, `I`, `I`, `I`, `I`, `J`, `K`, `K`, `K`, `K`, `L`, `L`, `M`, `M`, `M`, `M`, `N`, `O`, `P`, `P`, `Q`, `Q`, `Q`, `R`, `S`, `S`, `S`, `T`, `0`, `0`, `0`, `0`, `A`, `B`, `B`, `C`, `C`, `P`, `P`, `E`, `D`, `D`, `D`, `D`, `E`, `E`, `E`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `E`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `P`, `Q`, `Q`, `Q`, `0`, `0`, `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `J`, `J`, `Q`, `P`, `P`, `F`}

// ISO15919 series specific to Indian languages
var iso15919IndicSeries = unicodeSequence{`m̐`, `ṁ`, `ḥ`, ``, `a`, `ā`, `i`, `ī`, `u`, `ū`, `ṛ`, `ḷ`, `ê`, `e`, `ē`, `ai`, `ô`, `o`, `ō`, `au`, `ka`, `kha`, `ga`, `gha`, `ṅa`, `ca`, `cha`, `ja`, `jha`, `ña`, `ṭa`, `ṭha`, `ḍa`, `ḍha`, `ṇa`, `ta`, `tha`, `da`, `dha`, `na`, `ṉa`, `pa`, `pha`, `ba`, `bha`, `ma`, `ya`, `ra`, `ṟa`, `la`, `ḷa`, `ḻa`, `va`, `śa`, `ṣa`, `sa`, `ha`, ``, ``, ``, `'`, `ā`, `i`, `ī`, `u`, `ū`, `ṛ`, `ṝ`, `ê`, `e`, `ē`, `ai`, `ô`, `o`, `ō`, `au`, ``, ``, ``, `oṃ`, ``, ``, ``, ``, ``, ``, ``, `qa`, `ḵẖa`, `ġ`, `za`, `ṛa`, `ṛha`, `fa`, `ẏa`, `ṝ`, `ḹ`, `ḷ`, `ḹ`, `.`, `..`, `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `…`, ``, ``, ``, ``, ``, ``, ``}

// IPA series specific for Indian languages
var ipaIndicSeries = unicodeSequence{`m`, `m`, ``, ``, `ə`, `aː`, `i`, `iː`, `u`, `uː`, `r̩`, `l̩`, `æ`, `e`, `eː`, `ɛː`, `ɔ`, `o`, `oː`, `ow`, `kə`, `kʰə`, `gə`, `gʱə`, `ŋə`, `ʧə`, `ʧʰə`, `ʤə`, `ʤʱə`, `ɲə`, `ʈə`, `ʈʰə`, `ɖə`, `ɖʱə`, `ɳə`, `t̪ə`, `t̪ʰə`, `d̪ə`, `d̪ʱə`, `n̪ə`, `nə`, `pə`, `pʰə`, `bə`, `bʱə`, `mə`, `jə`, `ɾə`, `rə`, `lə`, `ɭə`, `ɻə`, `ʋə`, `ɕə`, `ʂə`, `sə`, `ɦə`, ``, ``, ``, `ഽ`, `aː`, `i`, `iː`, `u`, `uː`, `r̩`, `l̩`, `e`, `eː`, `ɛː`, `ɔ`, `o`, `oː`, `ow`, ``, ``, ``, ``, ``, ``, ``, ``, ``, ``, `ow`, ``, ``, ``, ``, ``, ``, ``, ``, `r̩ː`, `l̩ː`, ``, ``, ``, ``, `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `൰`, ``, ``, ``, ``, ``, ``, ``, ``, ``, ``, ``, ``, ``, ``, ``}

// Map to hold rune sequence of each languages
var langMap = charMap{
	"hi_IN": devaAlphabets,
	"bn_IN": bengAlphabets,
	"pa_IN": guruAlphabets,
	"gu_IN": gujrAlphabets,
	"or_IN": oryaAlphabets,
	"ta_IN": tamlAlphabets,
	"te_IN": teluAlphabets,
	"kn_IN": kndaAlphabets,
	"ml_IN": mlymAlphabets,
}

func initializeUnicodeRange(slice unicodeSequence, begin int) {
	for i := 0; i < len(slice); i++ {
		slice[i] = string(begin + i)
	}
}

func init() {
	for key, value := range langMap {
		initializeUnicodeRange(value.(unicodeSequence), langBases[key])
	}

	langMap["soundex_en"] = soundexEnglish
	langMap["soundex_in"] = soundexIndic
	langMap["ISO15919"] = iso15919IndicSeries
	langMap["IPA"] = ipaIndicSeries
}

func (r unicodeSequence) index(char string) int {
	for i, value := range r {
		if value == char {
			return i
		}
	}

	return -1
}

func LanguageOf(char string) string {
	for lang, langRange := range langMap {
		if langRange.index(char) != -1 {
			return lang
		}
	}
	// Still not found then something wrong
	return "unknown"
}

func CharCompare(char1, char2 string) bool {

	if char1 == char2 {
		return true
	}

	char1Index := langMap[LanguageOf(char1)].index(char1)
	char2Index := langMap[LanguageOf(char2)].index(char2)

	if char1Index == char2Index {
		return true
	}

	return false
}

func SoundexCode(char string) (string, error) {
	var lang string
	char = strings.ToLower(char)
	if lang = LanguageOf(char); lang != "unknown" {
		if charIndex := langMap[lang].index(char); charIndex != -1 {
			var sequence unicodeSequence

			switch lang {
			case "en_US":
				sequence = langMap["soundex_en"].(unicodeSequence)
			default:
				sequence = langMap["soundex_in"].(unicodeSequence)
			}
			return sequence[charIndex], nil
		}
		return "0", &UnknownCharError{char, lang, "not found"}
	}
	return "0", &UnknownCharError{char, lang, "unknown language"}
}
<commit_msg>Added missing en_US alphabets to langMap<commit_after>package charmap

import (
	"strings"
)

// Private types for rune and string slices
type unicodeSequence []string

type sequenceIndex interface {
	index(char string) int
}

// Private map to hold all sequences
type charMap map[string]sequenceIndex

// Languagewise unicode ranges
var langBases = map[string]int{
	"en_US": 0,
	"en_IN": 0,
	"hi_IN": '\u0901',
	"bn_IN": '\u0981',
	"pa_IN": '\u0a01',
	"gu_IN": '\u0a81',
	"or_IN": '\u0b01',
	"ta_IN": '\u0b81',
	"te_IN": '\u0c01',
	"kn_IN": '\u0c81',
	"ml_IN": '\u0D01',
}

// Slices to hold unicode range for each languagges
var devaAlphabets = make(unicodeSequence, 80)
var bengAlphabets = make(unicodeSequence, 80)
var guruAlphabets = make(unicodeSequence, 80)
var gujrAlphabets = make(unicodeSequence, 80)
var oryaAlphabets = make(unicodeSequence, 80)
var tamlAlphabets = make(unicodeSequence, 80)
var teluAlphabets = make(unicodeSequence, 80)
var kndaAlphabets = make(unicodeSequence, 80)
var mlymAlphabets = make(unicodeSequence, 80)

var enUsAlphabets = unicodeSequence{`a`, `b`, `c`, `d`, `e`, `f`, `g`, `h`, `i`, `j`, `k`, `l`, `m`, `n`, `o`, `p`, `q`, `r`, `s`, `t`, `u`, `v`, `w`, `x`, `y`, `z`}

// Soundex values for English alphabet series
var soundexEnglish = unicodeSequence{`0`, `1`, `2`, `3`, `0`, `1`, `2`, `0`, `0`, `2`, `2`, `4`, `5`, `5`, `0`, `1`, `2`, `6`, `2`, `3`, `0`, `1`, `0`, `2`, `0`, `2`}

// Soundex values for Indian language unicode series.
var soundexIndic = unicodeSequence{`0`, `N`, `0`, `0`, `A`, `A`, `B`, `B`, `C`, `C`, `P`, `Q`, `0`, `D`, `D`, `D`, `E`, `E`, `E`, `E`, `F`, `F`, `F`, `F`, `G`, `H`, `H`, `H`, `H`, `G`, `I`, `I`, `I`, `I`, `J`, `K`, `K`, `K`, `K`, `L`, `L`, `M`, `M`, `M`, `M`, `N`, `O`, `P`, `P`, `Q`, `Q`, `Q`, `R`, `S`, `S`, `S`, `T`, `0`, `0`, `0`, `0`, `A`, `B`, `B`, `C`, `C`, `P`, `P`, `E`, `D`, `D`, `D`, `D`, `E`, `E`, `E`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `E`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `P`, `Q`, `Q`, `Q`, `0`, `0`, `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `0`, `J`, `J`, `Q`, `P`, `P`, `F`}

// ISO15919 series specific to Indian languages
var iso15919IndicSeries = unicodeSequence{`m̐`, `ṁ`, `ḥ`, ``, `a`, `ā`, `i`, `ī`, `u`, `ū`, `ṛ`, `ḷ`, `ê`, `e`, `ē`, `ai`, `ô`, `o`, `ō`, `au`, `ka`, `kha`, `ga`, `gha`, `ṅa`, `ca`, `cha`, `ja`, `jha`, `ña`, `ṭa`, `ṭha`, `ḍa`, `ḍha`, `ṇa`, `ta`, `tha`, `da`, `dha`, `na`, `ṉa`, `pa`, `pha`, `ba`, `bha`, `ma`, `ya`, `ra`, `ṟa`, `la`, `ḷa`, `ḻa`, `va`, `śa`, `ṣa`, `sa`, `ha`, ``, ``, ``, `'`, `ā`, `i`, `ī`, `u`, `ū`, `ṛ`, `ṝ`, `ê`, `e`, `ē`, `ai`, `ô`, `o`, `ō`, `au`, ``, ``, ``, `oṃ`, ``, ``, ``, ``, ``, ``, ``, `qa`, `ḵẖa`, `ġ`, `za`, `ṛa`, `ṛha`, `fa`, `ẏa`, `ṝ`, `ḹ`, `ḷ`, `ḹ`, `.`, `..`, `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `…`, ``, ``, ``, ``, ``, ``, ``}

// IPA series specific for Indian languages
var ipaIndicSeries = unicodeSequence{`m`, `m`, ``, ``, `ə`, `aː`, `i`, `iː`, `u`, `uː`, `r̩`, `l̩`, `æ`, `e`, `eː`, `ɛː`, `ɔ`, `o`, `oː`, `ow`, `kə`, `kʰə`, `gə`, `gʱə`, `ŋə`, `ʧə`, `ʧʰə`, `ʤə`, `ʤʱə`, `ɲə`, `ʈə`, `ʈʰə`, `ɖə`, `ɖʱə`, `ɳə`, `t̪ə`, `t̪ʰə`, `d̪ə`, `d̪ʱə`, `n̪ə`, `nə`, `pə`, `pʰə`, `bə`, `bʱə`, `mə`, `jə`, `ɾə`, `rə`, `lə`, `ɭə`, `ɻə`, `ʋə`, `ɕə`, `ʂə`, `sə`, `ɦə`, ``, ``, ``, `ഽ`, `aː`, `i`, `iː`, `u`, `uː`, `r̩`, `l̩`, `e`, `eː`, `ɛː`, `ɔ`, `o`, `oː`, `ow`, ``, ``, ``, ``, ``, ``, ``, ``, ``, ``, `ow`, ``, ``, ``, ``, ``, ``, ``, ``, `r̩ː`, `l̩ː`, ``, ``, ``, ``, `0`, `1`, `2`, `3`, `4`, `5`, `6`, `7`, `8`, `9`, `൰`, ``, ``, ``, ``, ``, ``, ``, ``, ``, ``, ``, ``, ``, ``, ``}

// Map to hold rune sequence of each languages
var langMap = charMap{
	"hi_IN": devaAlphabets,
	"bn_IN": bengAlphabets,
	"pa_IN": guruAlphabets,
	"gu_IN": gujrAlphabets,
	"or_IN": oryaAlphabets,
	"ta_IN": tamlAlphabets,
	"te_IN": teluAlphabets,
	"kn_IN": kndaAlphabets,
	"ml_IN": mlymAlphabets,
}

func initializeUnicodeRange(slice unicodeSequence, begin int) {
	for i := 0; i < len(slice); i++ {
		slice[i] = string(begin + i)
	}
}

func init() {
	for key, value := range langMap {
		initializeUnicodeRange(value.(unicodeSequence), langBases[key])
	}

	langMap["soundex_en"] = soundexEnglish
	langMap["soundex_in"] = soundexIndic
	langMap["ISO15919"] = iso15919IndicSeries
	langMap["IPA"] = ipaIndicSeries
	langMap["en_US"] = enUsAlphabets
}

func (r unicodeSequence) index(char string) int {
	for i, value := range r {
		if value == char {
			return i
		}
	}

	return -1
}

func LanguageOf(char string) string {
	for lang, langRange := range langMap {
		if langRange.index(char) != -1 {
			return lang
		}
	}
	// Still not found then something wrong
	return "unknown"
}

func CharCompare(char1, char2 string) bool {

	if char1 == char2 {
		return true
	}

	char1Index := langMap[LanguageOf(char1)].index(char1)
	char2Index := langMap[LanguageOf(char2)].index(char2)

	if char1Index == char2Index {
		return true
	}

	return false
}

func SoundexCode(char string) (string, error) {
	var lang string
	char = strings.ToLower(char)
	if lang = LanguageOf(char); lang != "unknown" {
		if charIndex := langMap[lang].index(char); charIndex != -1 {
			var sequence unicodeSequence

			switch lang {
			case "en_US":
				sequence = langMap["soundex_en"].(unicodeSequence)
			default:
				sequence = langMap["soundex_in"].(unicodeSequence)
			}
			return sequence[charIndex], nil
		}
		return "0", &UnknownCharError{char, lang, "not found"}
	}
	return "0", &UnknownCharError{char, lang, "unknown language"}
}
<|endoftext|>


<commit_before>// Package charset provides functions to decode and encode charsets.
package charset

import (
	"fmt"
	"io"
	"strings"

	"golang.org/x/text/encoding"
	"golang.org/x/text/encoding/charmap"
	"golang.org/x/text/encoding/japanese"
	"golang.org/x/text/encoding/simplifiedchinese"
	"golang.org/x/text/encoding/traditionalchinese"
)

var charsets = map[string]encoding.Encoding{
	"big5":         traditionalchinese.Big5,
	"euc-jp":       japanese.EUCJP,
	"gbk":          simplifiedchinese.GBK,
	"gb2312":       simplifiedchinese.GBK,     // as  GBK is a superset of HZGB2312,so just use GBK
	"gb18030":      simplifiedchinese.GB18030, // GB18030 Use for parse QQ business mail message
	"iso-2022-jp":  japanese.ISO2022JP,
	"iso-8859-1":   charmap.ISO8859_1,
	"iso-8859-2":   charmap.ISO8859_2,
	"iso-8859-3":   charmap.ISO8859_3,
	"iso-8859-4":   charmap.ISO8859_4,
	"iso-8859-10":  charmap.ISO8859_10,
	"iso-8859-13":  charmap.ISO8859_13,
	"iso-8859-14":  charmap.ISO8859_14,
	"iso-8859-15":  charmap.ISO8859_15,
	"iso-8859-16":  charmap.ISO8859_16,
	"koi8-r":       charmap.KOI8R,
	"shift_jis":    japanese.ShiftJIS,
	"windows-1250": charmap.Windows1250,
	"windows-1251": charmap.Windows1251,
	"windows-1252": charmap.Windows1252,
}

// Reader returns an io.Reader that converts the provided charset to UTF-8.
func Reader(charset string, input io.Reader) (io.Reader, error) {
	charset = strings.ToLower(charset)
	if charset == "utf-8" || charset == "us-ascii" {
		return input, nil
	}
	if enc, ok := charsets[charset]; ok {
		return enc.NewDecoder().Reader(input), nil
	}
	return nil, fmt.Errorf("unhandled charset %q", charset)
}
<commit_msg>adds iso-8859-9, closing #20<commit_after>// Package charset provides functions to decode and encode charsets.
package charset

import (
	"fmt"
	"io"
	"strings"

	"golang.org/x/text/encoding"
	"golang.org/x/text/encoding/charmap"
	"golang.org/x/text/encoding/japanese"
	"golang.org/x/text/encoding/simplifiedchinese"
	"golang.org/x/text/encoding/traditionalchinese"
)

var charsets = map[string]encoding.Encoding{
	"big5":         traditionalchinese.Big5,
	"euc-jp":       japanese.EUCJP,
	"gbk":          simplifiedchinese.GBK,
	"gb2312":       simplifiedchinese.GBK,     // as  GBK is a superset of HZGB2312,so just use GBK
	"gb18030":      simplifiedchinese.GB18030, // GB18030 Use for parse QQ business mail message
	"iso-2022-jp":  japanese.ISO2022JP,
	"iso-8859-1":   charmap.ISO8859_1,
	"iso-8859-2":   charmap.ISO8859_2,
	"iso-8859-3":   charmap.ISO8859_3,
	"iso-8859-4":   charmap.ISO8859_4,
	"iso-8859-9":   charmap.ISO8859_9,
	"iso-8859-10":  charmap.ISO8859_10,
	"iso-8859-13":  charmap.ISO8859_13,
	"iso-8859-14":  charmap.ISO8859_14,
	"iso-8859-15":  charmap.ISO8859_15,
	"iso-8859-16":  charmap.ISO8859_16,
	"koi8-r":       charmap.KOI8R,
	"shift_jis":    japanese.ShiftJIS,
	"windows-1250": charmap.Windows1250,
	"windows-1251": charmap.Windows1251,
	"windows-1252": charmap.Windows1252,
}

// Reader returns an io.Reader that converts the provided charset to UTF-8.
func Reader(charset string, input io.Reader) (io.Reader, error) {
	charset = strings.ToLower(charset)
	if charset == "utf-8" || charset == "us-ascii" {
		return input, nil
	}
	if enc, ok := charsets[charset]; ok {
		return enc.NewDecoder().Reader(input), nil
	}
	return nil, fmt.Errorf("unhandled charset %q", charset)
}
<|endoftext|>


<commit_before>package spvwallet

import (
	"fmt"
	"github.com/btcsuite/btcd/chaincfg/chainhash"
	"github.com/btcsuite/btcd/peer"
	"github.com/btcsuite/btcd/wire"
	"time"
)

var (
	maxHash              *chainhash.Hash
	MAX_UNCONFIRMED_TIME time.Duration = time.Hour * 24 * 7
)

func init() {
	h, err := chainhash.NewHashFromStr("0000000000000000000000000000000000000000000000000000000000000000")
	if err != nil {
		log.Fatal(err)
	}
	maxHash = h
}

func (w *SPVWallet) startChainDownload(p *peer.Peer) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("Unhandled error in startChainDownload", r)
		}
	}()
	w.mutex.Lock()
	defer w.mutex.Unlock()
	if w.blockchain.ChainState() == SYNCING {
		height, _ := w.blockchain.db.Height()
		if height >= uint32(p.LastBlock()) {
			moar := w.peerManager.CheckForMoreBlocks(height)
			if !moar {
				log.Info("Chain download complete")
				w.blockchain.SetChainState(WAITING)
				w.Rebroadcast()
				close(w.blockQueue)
			}
			return
		}
		gBlocks := wire.NewMsgGetBlocks(maxHash)
		hashes := w.blockchain.GetBlockLocatorHashes()
		gBlocks.BlockLocatorHashes = hashes
		p.QueueMessage(gBlocks, nil)
	}
}

func (w *SPVWallet) onMerkleBlock(p *peer.Peer, m *wire.MsgMerkleBlock) {
	if w.blockchain.ChainState() == SYNCING && w.peerManager.DownloadPeer() != nil && w.peerManager.DownloadPeer().ID() == p.ID() {
		queueHash := <-w.blockQueue
		headerHash := m.Header.BlockHash()
		if !headerHash.IsEqual(&queueHash) {
			log.Errorf("Peer%d is sending us blocks out of order", p.ID())
			p.Disconnect()
			return
		}
	}
	txids, err := checkMBlock(m)
	if err != nil {
		log.Errorf("Peer%d sent an invalid MerkleBlock", p.ID())
		p.Disconnect()
		return
	}
	newBlock, reorg, height, err := w.blockchain.CommitHeader(m.Header)
	if err != nil {
		log.Warning(err)
		return
	}
	if !newBlock {
		return
	}

	// We hit a reorg. Rollback the transactions and resync from the reorg point.
	if reorg != nil {
		err := w.txstore.processReorg(reorg.height)
		if err != nil {
			log.Error(err)
		}
		w.blockchain.SetChainState(SYNCING)
		w.blockchain.db.Put(*reorg, true)
		go w.startChainDownload(p)
		return
	}

	for _, txid := range txids {
		w.mutex.Lock()
		w.toDownload[*txid] = int32(height)
		w.mutex.Unlock()
	}
	log.Debugf("Received Merkle Block %s at height %d\n", m.Header.BlockHash().String(), height)
	if len(w.blockQueue) == 0 && w.blockchain.ChainState() == SYNCING {
		go w.startChainDownload(p)
	}
	if w.blockchain.ChainState() == WAITING {
		txns, err := w.txstore.Txns().GetAll(false)
		if err != nil {
			log.Error(err)
			return
		}
		now := time.Now()
		for i := len(txns) - 1; i >= 0; i-- {
			if now.After(txns[i].Timestamp.Add(MAX_UNCONFIRMED_TIME)) && txns[i].Height == int32(0) {
				log.Noticef("Marking tx as dead %s", txns[i].Txid)
				h, err := chainhash.NewHashFromStr(txns[i].Txid)
				if err != nil {
					log.Error(err)
					continue
				}
				err = w.txstore.markAsDead(*h)
				if err != nil {
					log.Error(err)
					continue
				}
			}
		}
	}
}

func (w *SPVWallet) onTx(p *peer.Peer, m *wire.MsgTx) {
	w.mutex.RLock()
	height := w.toDownload[m.TxHash()]
	w.mutex.RUnlock()
	hits, err := w.txstore.Ingest(m, height)
	if err != nil {
		log.Errorf("Error ingesting tx: %s\n", err.Error())
		return
	}
	if hits == 0 {
		log.Debugf("Tx %s from Peer%d had no hits, filter false positive.", m.TxHash().String(), p.ID())
		w.fPositives <- p
		return
	}
	w.updateFilterAndSend(p)
	log.Infof("Tx %s from Peer%d ingested and matches %d utxo/adrs.", m.TxHash().String(), p.ID(), hits)

	// FIXME: right now the hash stays in memory forever. We need to delete it but the way the code works,
	// FIXME: doing so will cause the height to get reset to zero if a peer relays the tx to us again.
}

func (w *SPVWallet) onInv(p *peer.Peer, m *wire.MsgInv) {
	go func() {
		defer func() {
			if err := recover(); err != nil {
				log.Error(err)
			}
		}()
		for _, inv := range m.InvList {
			switch inv.Type {
			case wire.InvTypeBlock:
				// Kind of lame to send separate getData messages but this allows us
				// to take advantage of the timeout on the upper layer. Otherwise we
				// need separate timeout handling.
				inv.Type = wire.InvTypeFilteredBlock
				gData := wire.NewMsgGetData()
				gData.AddInvVect(inv)
				p.QueueMessage(gData, nil)
				if w.blockchain.ChainState() == SYNCING && w.peerManager.DownloadPeer() != nil && w.peerManager.DownloadPeer().ID() == p.ID() {
					w.blockQueue <- inv.Hash
				}
			case wire.InvTypeTx:
				gData := wire.NewMsgGetData()
				gData.AddInvVect(inv)
				p.QueueMessage(gData, nil)
			default:
				continue
			}

		}
	}()
}

func (w *SPVWallet) onGetData(p *peer.Peer, m *wire.MsgGetData) {
	log.Debugf("Received getdata request from Peer%d\n", p.ID())
	var sent int32
	for _, thing := range m.InvList {
		if thing.Type == wire.InvTypeTx {
			tx, _, err := w.txstore.Txns().Get(thing.Hash)
			if err != nil {
				log.Errorf("Error getting tx %s: %s", thing.Hash.String(), err.Error())
				continue
			}
			p.QueueMessage(tx, nil)
			sent++
			continue
		}
		// didn't match, so it's not something we're responding to
		log.Debugf("We only respond to tx requests, ignoring")

	}
	log.Debugf("Sent %d of %d requested items to Peer%d", sent, len(m.InvList), p.ID())
}

func (w *SPVWallet) fPositiveHandler(quit chan int) {
exit:
	for {
		select {
		case peer := <-w.fPositives:
			w.mutex.RLock()
			falsePostives, _ := w.fpAccumulator[peer.ID()]
			w.mutex.RUnlock()
			falsePostives++
			if falsePostives > 7 {
				w.updateFilterAndSend(peer)
				log.Debugf("Reset %d false positives for Peer%d\n", falsePostives, peer.ID())
				// reset accumulator
				falsePostives = 0
			}
			w.mutex.Lock()
			w.fpAccumulator[peer.ID()] = falsePostives
			w.mutex.Unlock()
		case <-quit:
			break exit
		}
	}
}

func (w *SPVWallet) updateFilterAndSend(p *peer.Peer) {
	filt, err := w.txstore.GimmeFilter()
	if err != nil {
		log.Errorf("Error creating filter: %s\n", err.Error())
		return
	}
	// send filter
	p.QueueMessage(filt.MsgFilterLoad(), nil)
	log.Debugf("Sent filter to Peer%d\n", p.ID())
}

func (w *SPVWallet) Rebroadcast() {
	// get all unconfirmed txs
	invMsg, err := w.txstore.GetPendingInv()
	if err != nil {
		log.Errorf("Rebroadcast error: %s", err.Error())
	}
	if len(invMsg.InvList) == 0 { // nothing to broadcast, so don't
		return
	}
	for _, peer := range w.peerManager.ConnectedPeers() {
		peer.QueueMessage(invMsg, nil)
	}
}
<commit_msg>Add recover() to startChainDownload<commit_after>package spvwallet

import (
	"github.com/btcsuite/btcd/chaincfg/chainhash"
	"github.com/btcsuite/btcd/peer"
	"github.com/btcsuite/btcd/wire"
	"time"
)

var (
	maxHash              *chainhash.Hash
	MAX_UNCONFIRMED_TIME time.Duration = time.Hour * 24 * 7
)

func init() {
	h, err := chainhash.NewHashFromStr("0000000000000000000000000000000000000000000000000000000000000000")
	if err != nil {
		log.Fatal(err)
	}
	maxHash = h
}

func (w *SPVWallet) startChainDownload(p *peer.Peer) {
	defer func() {
		if r := recover(); r != nil {
			log.Error("Unhandled error in startChainDownload", r)
		}
	}()
	w.mutex.Lock()
	defer w.mutex.Unlock()
	if w.blockchain.ChainState() == SYNCING {
		height, _ := w.blockchain.db.Height()
		if height >= uint32(p.LastBlock()) {
			moar := w.peerManager.CheckForMoreBlocks(height)
			if !moar {
				log.Info("Chain download complete")
				w.blockchain.SetChainState(WAITING)
				w.Rebroadcast()
				close(w.blockQueue)
			}
			return
		}
		gBlocks := wire.NewMsgGetBlocks(maxHash)
		hashes := w.blockchain.GetBlockLocatorHashes()
		gBlocks.BlockLocatorHashes = hashes
		p.QueueMessage(gBlocks, nil)
	}
}

func (w *SPVWallet) onMerkleBlock(p *peer.Peer, m *wire.MsgMerkleBlock) {
	if w.blockchain.ChainState() == SYNCING && w.peerManager.DownloadPeer() != nil && w.peerManager.DownloadPeer().ID() == p.ID() {
		queueHash := <-w.blockQueue
		headerHash := m.Header.BlockHash()
		if !headerHash.IsEqual(&queueHash) {
			log.Errorf("Peer%d is sending us blocks out of order", p.ID())
			p.Disconnect()
			return
		}
	}
	txids, err := checkMBlock(m)
	if err != nil {
		log.Errorf("Peer%d sent an invalid MerkleBlock", p.ID())
		p.Disconnect()
		return
	}
	newBlock, reorg, height, err := w.blockchain.CommitHeader(m.Header)
	if err != nil {
		log.Warning(err)
		return
	}
	if !newBlock {
		return
	}

	// We hit a reorg. Rollback the transactions and resync from the reorg point.
	if reorg != nil {
		err := w.txstore.processReorg(reorg.height)
		if err != nil {
			log.Error(err)
		}
		w.blockchain.SetChainState(SYNCING)
		w.blockchain.db.Put(*reorg, true)
		go w.startChainDownload(p)
		return
	}

	for _, txid := range txids {
		w.mutex.Lock()
		w.toDownload[*txid] = int32(height)
		w.mutex.Unlock()
	}
	log.Debugf("Received Merkle Block %s at height %d\n", m.Header.BlockHash().String(), height)
	if len(w.blockQueue) == 0 && w.blockchain.ChainState() == SYNCING {
		go w.startChainDownload(p)
	}
	if w.blockchain.ChainState() == WAITING {
		txns, err := w.txstore.Txns().GetAll(false)
		if err != nil {
			log.Error(err)
			return
		}
		now := time.Now()
		for i := len(txns) - 1; i >= 0; i-- {
			if now.After(txns[i].Timestamp.Add(MAX_UNCONFIRMED_TIME)) && txns[i].Height == int32(0) {
				log.Noticef("Marking tx as dead %s", txns[i].Txid)
				h, err := chainhash.NewHashFromStr(txns[i].Txid)
				if err != nil {
					log.Error(err)
					continue
				}
				err = w.txstore.markAsDead(*h)
				if err != nil {
					log.Error(err)
					continue
				}
			}
		}
	}
}

func (w *SPVWallet) onTx(p *peer.Peer, m *wire.MsgTx) {
	w.mutex.RLock()
	height := w.toDownload[m.TxHash()]
	w.mutex.RUnlock()
	hits, err := w.txstore.Ingest(m, height)
	if err != nil {
		log.Errorf("Error ingesting tx: %s\n", err.Error())
		return
	}
	if hits == 0 {
		log.Debugf("Tx %s from Peer%d had no hits, filter false positive.", m.TxHash().String(), p.ID())
		w.fPositives <- p
		return
	}
	w.updateFilterAndSend(p)
	log.Infof("Tx %s from Peer%d ingested and matches %d utxo/adrs.", m.TxHash().String(), p.ID(), hits)

	// FIXME: right now the hash stays in memory forever. We need to delete it but the way the code works,
	// FIXME: doing so will cause the height to get reset to zero if a peer relays the tx to us again.
}

func (w *SPVWallet) onInv(p *peer.Peer, m *wire.MsgInv) {
	go func() {
		defer func() {
			if err := recover(); err != nil {
				log.Error(err)
			}
		}()
		for _, inv := range m.InvList {
			switch inv.Type {
			case wire.InvTypeBlock:
				// Kind of lame to send separate getData messages but this allows us
				// to take advantage of the timeout on the upper layer. Otherwise we
				// need separate timeout handling.
				inv.Type = wire.InvTypeFilteredBlock
				gData := wire.NewMsgGetData()
				gData.AddInvVect(inv)
				p.QueueMessage(gData, nil)
				if w.blockchain.ChainState() == SYNCING && w.peerManager.DownloadPeer() != nil && w.peerManager.DownloadPeer().ID() == p.ID() {
					w.blockQueue <- inv.Hash
				}
			case wire.InvTypeTx:
				gData := wire.NewMsgGetData()
				gData.AddInvVect(inv)
				p.QueueMessage(gData, nil)
			default:
				continue
			}

		}
	}()
}

func (w *SPVWallet) onGetData(p *peer.Peer, m *wire.MsgGetData) {
	log.Debugf("Received getdata request from Peer%d\n", p.ID())
	var sent int32
	for _, thing := range m.InvList {
		if thing.Type == wire.InvTypeTx {
			tx, _, err := w.txstore.Txns().Get(thing.Hash)
			if err != nil {
				log.Errorf("Error getting tx %s: %s", thing.Hash.String(), err.Error())
				continue
			}
			p.QueueMessage(tx, nil)
			sent++
			continue
		}
		// didn't match, so it's not something we're responding to
		log.Debugf("We only respond to tx requests, ignoring")

	}
	log.Debugf("Sent %d of %d requested items to Peer%d", sent, len(m.InvList), p.ID())
}

func (w *SPVWallet) fPositiveHandler(quit chan int) {
exit:
	for {
		select {
		case peer := <-w.fPositives:
			w.mutex.RLock()
			falsePostives, _ := w.fpAccumulator[peer.ID()]
			w.mutex.RUnlock()
			falsePostives++
			if falsePostives > 7 {
				w.updateFilterAndSend(peer)
				log.Debugf("Reset %d false positives for Peer%d\n", falsePostives, peer.ID())
				// reset accumulator
				falsePostives = 0
			}
			w.mutex.Lock()
			w.fpAccumulator[peer.ID()] = falsePostives
			w.mutex.Unlock()
		case <-quit:
			break exit
		}
	}
}

func (w *SPVWallet) updateFilterAndSend(p *peer.Peer) {
	filt, err := w.txstore.GimmeFilter()
	if err != nil {
		log.Errorf("Error creating filter: %s\n", err.Error())
		return
	}
	// send filter
	p.QueueMessage(filt.MsgFilterLoad(), nil)
	log.Debugf("Sent filter to Peer%d\n", p.ID())
}

func (w *SPVWallet) Rebroadcast() {
	// get all unconfirmed txs
	invMsg, err := w.txstore.GetPendingInv()
	if err != nil {
		log.Errorf("Rebroadcast error: %s", err.Error())
	}
	if len(invMsg.InvList) == 0 { // nothing to broadcast, so don't
		return
	}
	for _, peer := range w.peerManager.ConnectedPeers() {
		peer.QueueMessage(invMsg, nil)
	}
}
<|endoftext|>


<commit_before>package htmlelements

import "golang.org/x/net/html/atom"

// VoidElements - HTML elements that are void of has self closing tag
// http://www.w3.org/TR/html5/syntax.html#void-elements
var VoidElements = AtomSlice{
	atom.Area, atom.Base, atom.Br, atom.Col,
	atom.Embed, atom.Hr, atom.Img, atom.Input,
	atom.Keygen, atom.Link, atom.Meta, atom.Param,
	atom.Source, atom.Track, atom.Wbr,
}

// RawTextElements - can have text
// http://www.w3.org/TR/html5/syntax.html#raw-text-elements<F37>
var RawTextElements = AtomSlice{
	atom.Script, atom.Style,
}

// EscapableRawTextElements - can have text and character references, but the text must not contain an ambiguous ampersand.
// http://www.w3.org/TR/html5/syntax.html#escapable-raw-text-elements
var EscapableRawTextElements = AtomSlice{
	atom.Textarea, atom.Title,
}

// ForeignElements - whose start tag is marked as self-closing
// can't have any contents (since, again, as there's no end tag,
// no content can be put between the start tag and the end tag).
// Foreign elements whose start tag is not marked as self-closing
// can have text, character references, CDATA sections, other elements,
// and comments, but the text must not contain the character '<' (U+003C)
// or an ambiguous ampersand.
// http://www.w3.org/TR/html5/syntax.html#foreign-elements
var ForeignElements = AtomSlice{
	atom.Math, atom.Svg,
}

// NormalElements - All other allowed HTML elements are normal elements.
// http://www.w3.org/TR/html5/syntax.html#normal-elements
// generated;
var NormalElements = AtomSlice{
	atom.A,
	atom.Abbr,
	atom.Address,
	atom.Article,
	atom.Aside,
	atom.Audio,
	atom.B,
	atom.Bdi,
	atom.Bdo,
	atom.Blockquote,
	atom.Body,
	atom.Button,
	atom.Canvas,
	atom.Caption,
	atom.Cite,
	atom.Code,
	atom.Colgroup,
	atom.Command,
	atom.Data,
	atom.Datalist,
	atom.Dd,
	atom.Del,
	atom.Details,
	atom.Dfn,
	atom.Dialog,
	atom.Div,
	atom.Dl,
	atom.Dt,
	atom.Em,
	atom.Fieldset,
	atom.Figcaption,
	atom.Figure,
	atom.Footer,
	atom.Form,
	atom.H1,
	atom.H2,
	atom.H3,
	atom.H4,
	atom.H5,
	atom.H6,
	atom.Head,
	atom.Header,
	atom.Hgroup,
	atom.Html,
	atom.I,
	atom.Iframe,
	atom.Ins,
	atom.Kbd,
	atom.Label,
	atom.Legend,
	atom.Li,
	atom.Map,
	atom.Mark,
	atom.Menu,
	// atom.Menuitem,
	atom.Meter,
	atom.Nav,
	atom.Noscript,
	atom.Object,
	atom.Ol,
	atom.Optgroup,
	atom.Option,
	atom.Output,
	atom.P,
	atom.Pre,
	atom.Progress,
	atom.Q,
	atom.Rp,
	atom.Rt,
	atom.Ruby,
	atom.S,
	atom.Samp,
	atom.Script,
	atom.Section,
	atom.Select,
	atom.Small,
	atom.Span,
	atom.Strong,
	atom.Style,
	atom.Sub,
	atom.Summary,
	atom.Sup,
	atom.Table,
	atom.Tbody,
	atom.Td,
	// atom.Template,
	atom.Textarea,
	atom.Tfoot,
	atom.Th,
	atom.Thead,
	atom.Time,
	atom.Title,
	atom.Tr,
	atom.U,
	atom.Ul,
	atom.Var,
	atom.Video,
}
<commit_msg>Add atom.Menuitem, atom.Template<commit_after>package htmlelements

import "golang.org/x/net/html/atom"

// VoidElements - HTML elements that are void of has self closing tag
// http://www.w3.org/TR/html5/syntax.html#void-elements
var VoidElements = AtomSlice{
	atom.Area, atom.Base, atom.Br, atom.Col,
	atom.Embed, atom.Hr, atom.Img, atom.Input,
	atom.Keygen, atom.Link, atom.Meta, atom.Param,
	atom.Source, atom.Track, atom.Wbr,
}

// RawTextElements - can have text
// http://www.w3.org/TR/html5/syntax.html#raw-text-elements<F37>
var RawTextElements = AtomSlice{
	atom.Script, atom.Style,
}

// EscapableRawTextElements - can have text and character references, but the text must not contain an ambiguous ampersand.
// http://www.w3.org/TR/html5/syntax.html#escapable-raw-text-elements
var EscapableRawTextElements = AtomSlice{
	atom.Textarea, atom.Title,
}

// ForeignElements - whose start tag is marked as self-closing
// can't have any contents (since, again, as there's no end tag,
// no content can be put between the start tag and the end tag).
// Foreign elements whose start tag is not marked as self-closing
// can have text, character references, CDATA sections, other elements,
// and comments, but the text must not contain the character '<' (U+003C)
// or an ambiguous ampersand.
// http://www.w3.org/TR/html5/syntax.html#foreign-elements
var ForeignElements = AtomSlice{
	atom.Math, atom.Svg,
}

// NormalElements - All other allowed HTML elements are normal elements.
// http://www.w3.org/TR/html5/syntax.html#normal-elements
// generated;
var NormalElements = AtomSlice{
	atom.A,
	atom.Abbr,
	atom.Address,
	atom.Article,
	atom.Aside,
	atom.Audio,
	atom.B,
	atom.Bdi,
	atom.Bdo,
	atom.Blockquote,
	atom.Body,
	atom.Button,
	atom.Canvas,
	atom.Caption,
	atom.Cite,
	atom.Code,
	atom.Colgroup,
	atom.Command,
	atom.Data,
	atom.Datalist,
	atom.Dd,
	atom.Del,
	atom.Details,
	atom.Dfn,
	atom.Dialog,
	atom.Div,
	atom.Dl,
	atom.Dt,
	atom.Em,
	atom.Fieldset,
	atom.Figcaption,
	atom.Figure,
	atom.Footer,
	atom.Form,
	atom.H1,
	atom.H2,
	atom.H3,
	atom.H4,
	atom.H5,
	atom.H6,
	atom.Head,
	atom.Header,
	atom.Hgroup,
	atom.Html,
	atom.I,
	atom.Iframe,
	atom.Ins,
	atom.Kbd,
	atom.Label,
	atom.Legend,
	atom.Li,
	atom.Map,
	atom.Mark,
	atom.Menu,
	atom.Menuitem,
	atom.Meter,
	atom.Nav,
	atom.Noscript,
	atom.Object,
	atom.Ol,
	atom.Optgroup,
	atom.Option,
	atom.Output,
	atom.P,
	atom.Pre,
	atom.Progress,
	atom.Q,
	atom.Rp,
	atom.Rt,
	atom.Ruby,
	atom.S,
	atom.Samp,
	atom.Script,
	atom.Section,
	atom.Select,
	atom.Small,
	atom.Span,
	atom.Strong,
	atom.Style,
	atom.Sub,
	atom.Summary,
	atom.Sup,
	atom.Table,
	atom.Tbody,
	atom.Td,
	atom.Template,
	atom.Textarea,
	atom.Tfoot,
	atom.Th,
	atom.Thead,
	atom.Time,
	atom.Title,
	atom.Tr,
	atom.U,
	atom.Ul,
	atom.Var,
	atom.Video,
}
<|endoftext|>