<commit_before>package rpc // import "collectd.org/rpc"

import (
	"io"

	"collectd.org/api"
	pb "collectd.org/rpc/proto"
	"collectd.org/rpc/proto/types"
	"github.com/golang/protobuf/ptypes"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
)

// CollectdServer is an idiomatic Go interface for proto.CollectdServer Use
// RegisterCollectdServer() to hook an object, which implements this interface,
// up to the gRPC server.
type CollectdServer interface {
	Query(*api.Identifier) (<-chan *api.ValueList, error)
}

// RegisterCollectdServer registers the implementation srv with the gRPC instance s.
func RegisterCollectdServer(s *grpc.Server, srv CollectdServer) {
	pb.RegisterCollectdServer(s, &collectdWrapper{
		srv: srv,
	})
}

type DispatchServer interface {
	api.Writer
}

func RegisterDispatchServer(s *grpc.Server, srv DispatchServer) {
	pb.RegisterDispatchServer(s, &dispatchWrapper{
		srv: srv,
	})
}

func MarshalValue(v api.Value) (*types.Value, error) {
	switch v := v.(type) {
	case api.Counter:
		return &types.Value{
			Value: &types.Value_Counter{Counter: uint64(v)},
		}, nil
	case api.Derive:
		return &types.Value{
			Value: &types.Value_Derive{Derive: int64(v)},
		}, nil
	case api.Gauge:
		return &types.Value{
			Value: &types.Value_Gauge{Gauge: float64(v)},
		}, nil
	default:
		return nil, grpc.Errorf(codes.InvalidArgument, "%T values are not supported", v)
	}
}

func UnmarshalValue(in *types.Value) (api.Value, error) {
	switch pbValue := in.GetValue().(type) {
	case *types.Value_Counter:
		return api.Counter(pbValue.Counter), nil
	case *types.Value_Derive:
		return api.Derive(pbValue.Derive), nil
	case *types.Value_Gauge:
		return api.Gauge(pbValue.Gauge), nil
	default:
		return nil, grpc.Errorf(codes.Internal, "%T values are not supported", pbValue)
	}
}

func MarshalIdentifier(id *api.Identifier) *types.Identifier {
	return &types.Identifier{
		Host:           id.Host,
		Plugin:         id.Plugin,
		PluginInstance: id.PluginInstance,
		Type:           id.Type,
		TypeInstance:   id.TypeInstance,
	}
}

func UnmarshalIdentifier(in *types.Identifier) *api.Identifier {
	return &api.Identifier{
		Host:           in.Host,
		Plugin:         in.Plugin,
		PluginInstance: in.PluginInstance,
		Type:           in.Type,
		TypeInstance:   in.TypeInstance,
	}
}

func MarshalValueList(vl *api.ValueList) (*types.ValueList, error) {
	t, err := ptypes.TimestampProto(vl.Time)
	if err != nil {
		return nil, err
	}

	var pbValues []*types.Value
	for _, v := range vl.Values {
		pbValue, err := MarshalValue(v)
		if err != nil {
			return nil, err
		}

		pbValues = append(pbValues, pbValue)
	}

	return &types.ValueList{
		Values:     pbValues,
		Time:       t,
		Interval:   ptypes.DurationProto(vl.Interval),
		Identifier: MarshalIdentifier(&vl.Identifier),
	}, nil
}

func UnmarshalValueList(in *types.ValueList) (*api.ValueList, error) {
	t, err := ptypes.Timestamp(in.GetTime())
	if err != nil {
		return nil, err
	}

	interval, err := ptypes.Duration(in.GetInterval())
	if err != nil {
		return nil, err
	}

	var values []api.Value
	for _, pbValue := range in.GetValues() {
		v, err := UnmarshalValue(pbValue)
		if err != nil {
			return nil, err
		}

		values = append(values, v)
	}

	return &api.ValueList{
		Identifier: *UnmarshalIdentifier(in.GetIdentifier()),
		Time:       t,
		Interval:   interval,
		Values:     values,
		DSNames:    in.DsNames,
	}, nil
}

// dispatchWrapper implements pb.DispatchServer using srv.
type dispatchWrapper struct {
	srv DispatchServer
}

func (wrap *dispatchWrapper) DispatchValues(stream pb.Dispatch_DispatchValuesServer) error {
	for {
		req, err := stream.Recv()
		if err == io.EOF {
			break
		}
		if err != nil {
			return err
		}

		vl, err := UnmarshalValueList(req.GetValueList())
		if err != nil {
			return err
		}

		if err := wrap.srv.Write(*vl); err != nil {
			return grpc.Errorf(codes.Internal, "Write(%v): %v", vl, err)
		}
	}

	return stream.SendAndClose(&pb.DispatchValuesResponse{})
}

// collectdWrapper implements pb.CollectdServer using srv.
type collectdWrapper struct {
	srv CollectdServer
}

func (wrap *collectdWrapper) QueryValues(req *pb.QueryValuesRequest, stream pb.Collectd_QueryValuesServer) error {
	id := UnmarshalIdentifier(req.GetIdentifier())

	ch, err := wrap.srv.Query(id)
	if err != nil {
		return grpc.Errorf(codes.Internal, "Query(%v): %v", id, err)
	}

	for vl := range ch {
		pbVL, err := MarshalValueList(vl)
		if err != nil {
			return err
		}

		res := &pb.QueryValuesResponse{
			ValueList: pbVL,
		}
		if err := stream.Send(res); err != nil {
			return err
		}
	}

	return nil
}
<commit_msg>Package rpc: Add NewDispatchClient().<commit_after>package rpc // import "collectd.org/rpc"

import (
	"io"

	"collectd.org/api"
	pb "collectd.org/rpc/proto"
	"collectd.org/rpc/proto/types"
	"github.com/golang/protobuf/ptypes"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
)

// CollectdServer is an idiomatic Go interface for proto.CollectdServer Use
// RegisterCollectdServer() to hook an object, which implements this interface,
// up to the gRPC server.
type CollectdServer interface {
	Query(*api.Identifier) (<-chan *api.ValueList, error)
}

// RegisterCollectdServer registers the implementation srv with the gRPC instance s.
func RegisterCollectdServer(s *grpc.Server, srv CollectdServer) {
	pb.RegisterCollectdServer(s, &collectdWrapper{
		srv: srv,
	})
}

type DispatchServer interface {
	api.Writer
}

func RegisterDispatchServer(s *grpc.Server, srv DispatchServer) {
	pb.RegisterDispatchServer(s, &dispatchWrapper{
		srv: srv,
	})
}

type dispatchClient struct {
	ctx    context.Context
	client pb.DispatchClient
}

func NewDispatchClient(ctx context.Context, conn *grpc.ClientConn) api.Writer {
	return &dispatchClient{
		ctx:    ctx,
		client: pb.NewDispatchClient(conn),
	}
}

func (c *dispatchClient) Write(vl api.ValueList) error {
	pbVL, err := MarshalValueList(&vl)
	if err != nil {
		return err
	}

	stream, err := c.client.DispatchValues(c.ctx)
	if err != nil {
		return err
	}

	req := &pb.DispatchValuesRequest{
		ValueList: pbVL,
	}
	if err := stream.Send(req); err != nil {
		stream.CloseSend()
		return err
	}

	_, err = stream.CloseAndRecv()
	return err
}

func MarshalValue(v api.Value) (*types.Value, error) {
	switch v := v.(type) {
	case api.Counter:
		return &types.Value{
			Value: &types.Value_Counter{Counter: uint64(v)},
		}, nil
	case api.Derive:
		return &types.Value{
			Value: &types.Value_Derive{Derive: int64(v)},
		}, nil
	case api.Gauge:
		return &types.Value{
			Value: &types.Value_Gauge{Gauge: float64(v)},
		}, nil
	default:
		return nil, grpc.Errorf(codes.InvalidArgument, "%T values are not supported", v)
	}
}

func UnmarshalValue(in *types.Value) (api.Value, error) {
	switch pbValue := in.GetValue().(type) {
	case *types.Value_Counter:
		return api.Counter(pbValue.Counter), nil
	case *types.Value_Derive:
		return api.Derive(pbValue.Derive), nil
	case *types.Value_Gauge:
		return api.Gauge(pbValue.Gauge), nil
	default:
		return nil, grpc.Errorf(codes.Internal, "%T values are not supported", pbValue)
	}
}

func MarshalIdentifier(id *api.Identifier) *types.Identifier {
	return &types.Identifier{
		Host:           id.Host,
		Plugin:         id.Plugin,
		PluginInstance: id.PluginInstance,
		Type:           id.Type,
		TypeInstance:   id.TypeInstance,
	}
}

func UnmarshalIdentifier(in *types.Identifier) *api.Identifier {
	return &api.Identifier{
		Host:           in.Host,
		Plugin:         in.Plugin,
		PluginInstance: in.PluginInstance,
		Type:           in.Type,
		TypeInstance:   in.TypeInstance,
	}
}

func MarshalValueList(vl *api.ValueList) (*types.ValueList, error) {
	t, err := ptypes.TimestampProto(vl.Time)
	if err != nil {
		return nil, err
	}

	var pbValues []*types.Value
	for _, v := range vl.Values {
		pbValue, err := MarshalValue(v)
		if err != nil {
			return nil, err
		}

		pbValues = append(pbValues, pbValue)
	}

	return &types.ValueList{
		Values:     pbValues,
		Time:       t,
		Interval:   ptypes.DurationProto(vl.Interval),
		Identifier: MarshalIdentifier(&vl.Identifier),
	}, nil
}

func UnmarshalValueList(in *types.ValueList) (*api.ValueList, error) {
	t, err := ptypes.Timestamp(in.GetTime())
	if err != nil {
		return nil, err
	}

	interval, err := ptypes.Duration(in.GetInterval())
	if err != nil {
		return nil, err
	}

	var values []api.Value
	for _, pbValue := range in.GetValues() {
		v, err := UnmarshalValue(pbValue)
		if err != nil {
			return nil, err
		}

		values = append(values, v)
	}

	return &api.ValueList{
		Identifier: *UnmarshalIdentifier(in.GetIdentifier()),
		Time:       t,
		Interval:   interval,
		Values:     values,
		DSNames:    in.DsNames,
	}, nil
}

// dispatchWrapper implements pb.DispatchServer using srv.
type dispatchWrapper struct {
	srv DispatchServer
}

func (wrap *dispatchWrapper) DispatchValues(stream pb.Dispatch_DispatchValuesServer) error {
	for {
		req, err := stream.Recv()
		if err == io.EOF {
			break
		}
		if err != nil {
			return err
		}

		vl, err := UnmarshalValueList(req.GetValueList())
		if err != nil {
			return err
		}

		if err := wrap.srv.Write(*vl); err != nil {
			return grpc.Errorf(codes.Internal, "Write(%v): %v", vl, err)
		}
	}

	return stream.SendAndClose(&pb.DispatchValuesResponse{})
}

// collectdWrapper implements pb.CollectdServer using srv.
type collectdWrapper struct {
	srv CollectdServer
}

func (wrap *collectdWrapper) QueryValues(req *pb.QueryValuesRequest, stream pb.Collectd_QueryValuesServer) error {
	id := UnmarshalIdentifier(req.GetIdentifier())

	ch, err := wrap.srv.Query(id)
	if err != nil {
		return grpc.Errorf(codes.Internal, "Query(%v): %v", id, err)
	}

	for vl := range ch {
		pbVL, err := MarshalValueList(vl)
		if err != nil {
			return err
		}

		res := &pb.QueryValuesResponse{
			ValueList: pbVL,
		}
		if err := stream.Send(res); err != nil {
			return err
		}
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"image"
	"image/color"
	_ "image/gif"
	"image/jpeg"
	_ "image/png"
	"log"
	"os"
)

func checkerror(err error) {
	if err != nil {
		log.Fatalln("[ERROR]", err)
	}
}

func invertcolor(somecolor uint32, somealpha uint32) uint32 {
	return somealpha - somecolor
}

var (
	red        = flag.Int("red", 0, "red percentage")
	green      = flag.Int("green", 0, "green percentage")
	blue       = flag.Int("blue", 0, "blue percentage")
	inputfile  = flag.String("input", "", "blue percentage")
	outputfile = flag.String("output", "", "blue percentage")
)

func outline(source image.Image) image.Image {
	bounds := source.Bounds()

	target := image.NewRGBA(image.Rect(bounds.Min.Y, bounds.Min.X, bounds.Max.X, bounds.Max.Y))

	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			if (x == bounds.Min.X) || (x == bounds.Max.X-1) || (y == bounds.Min.Y) || (y == bounds.Max.Y-1) {
				var xx int
				var yy int

				if x == bounds.Min.X {
					xx = 1
				}

				if x == bounds.Max.X-1 {
					xx = bounds.Max.X - 2
				}

				if y == bounds.Min.Y {
					yy = 1
				}

				if y == bounds.Max.Y-1 {
					yy = bounds.Max.Y - 2
				}

				r, g, b, a := source.At(xx, yy).RGBA()

				target.Set(xx, yy, color.RGBA{uint8(r), uint8(g), uint8(b), uint8(a)})
			} else {
				r, g, b, a := source.At(x, y).RGBA()
				target.Set(x, y, color.RGBA{uint8(r), uint8(g), uint8(b), uint8(a)})
			}
		}
	}

	return target
}

func mini(m image.Image) image.Image {
	bounds := m.Bounds()

	target := image.NewRGBA(image.Rect(bounds.Min.Y, bounds.Min.X, bounds.Max.X, bounds.Max.Y))

	for y := bounds.Min.Y + 1; y < bounds.Max.Y-1; y++ {
		for x := bounds.Min.X + 1; x < bounds.Max.X-1; x++ {
			r, g, b, a := m.At(x, y).RGBA()

			r1, g1, b1, _ := m.At(x, y-1).RGBA()
			r2, g2, b2, _ := m.At(x-1, y).RGBA()
			r3, g3, b3, _ := m.At(x+1, y).RGBA()
			r4, g4, b4, _ := m.At(x, y+1).RGBA()

			r0 := (r1 + r2 + r3 + r4 + (2.0 * r)) / 6.0
			g0 := (g1 + g2 + g3 + g4 + (2.0 * g)) / 6.0
			b0 := (b1 + b2 + b3 + b4 + (2.0 * b)) / 6.0

			target.Set(x, y, color.RGBA{uint8(r0 / 255), uint8(g0 / 255), uint8(b0 / 255), uint8(a / 255)})
		}
	}

	return target
}

func colour(m image.Image) image.Image {
	bounds := m.Bounds()

	rm := image.NewRGBA(image.Rect(bounds.Min.Y, bounds.Min.X, bounds.Max.X, bounds.Max.Y))

	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			r, g, b, a := m.At(x, y).RGBA()

			r = invertcolor(r, a)
			g = invertcolor(g, a)
			b = invertcolor(b, a)

			//r = r * uint32(*red)
			//g = g * uint32(*green)
			//b = b * uint32(*blue)

			rm.Set(x, y, color.RGBA{uint8(r), uint8(g), uint8(b), uint8(a)})
		}
	}

	return rm
}

func main() {
	flag.Parse()

	file, err := os.Open(*inputfile)
	checkerror(err)

	tofile, err := os.Create(*outputfile)
	checkerror(err)

	defer file.Close()
	defer tofile.Close()

	m, _, err := image.Decode(file)

	// rm := colour(m)
	rm := mini(m)
	rm = outline(m)

	jpeg.Encode(tofile, rm, &jpeg.Options{jpeg.DefaultQuality})
}
<commit_msg>working on it<commit_after>package main

import (
	"flag"
	"image"
	"image/color"
	_ "image/gif"
	"image/jpeg"
	_ "image/png"
	"log"
	"os"
)

func checkerror(err error) {
	if err != nil {
		log.Fatalln("[ERROR]", err)
	}
}

func invertcolor(somecolor uint32, somealpha uint32) uint32 {
	return somealpha - somecolor
}

var (
	red        = flag.Int("red", 0, "red percentage")
	green      = flag.Int("green", 0, "green percentage")
	blue       = flag.Int("blue", 0, "blue percentage")
	inputfile  = flag.String("input", "", "blue percentage")
	outputfile = flag.String("output", "", "blue percentage")
)

func outline(source image.Image) image.Image {
	bounds := source.Bounds()

	target := image.NewRGBA(image.Rect(bounds.Min.Y, bounds.Min.X, bounds.Max.X, bounds.Max.Y))

	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			if (x == bounds.Min.X) || (x == bounds.Max.X-1) || (y == bounds.Min.Y) || (y == bounds.Max.Y-1) {
				var xx int
				var yy int

				if x == bounds.Min.X {
					xx = 1
				}

				if x == bounds.Max.X-1 {
					xx = bounds.Max.X - 2
				}

				if y == bounds.Min.Y {
					yy = 1
				}

				if y == bounds.Max.Y-1 {
					yy = bounds.Max.Y - 2
				}

				r, g, b, a := source.At(xx, yy).RGBA()

				target.Set(x, y, color.RGBA{uint8(r / 255), uint8(g / 255), uint8(b / 255), uint8(a / 255)})
			} else {
				r, g, b, a := source.At(x, y).RGBA()
				target.Set(x, y, color.RGBA{uint8(r), uint8(g), uint8(b), uint8(a)})
			}
		}
	}

	return target
}

func mini(source image.Image) image.Image {
	bounds := source.Bounds()

	target := image.NewRGBA(image.Rect(bounds.Min.Y, bounds.Min.X, bounds.Max.X, bounds.Max.Y))

	return target
}

func smooth(m image.Image) image.Image {
	bounds := m.Bounds()

	target := image.NewRGBA(image.Rect(bounds.Min.Y, bounds.Min.X, bounds.Max.X, bounds.Max.Y))

	for y := bounds.Min.Y + 1; y < bounds.Max.Y-1; y++ {
		for x := bounds.Min.X + 1; x < bounds.Max.X-1; x++ {
			r, g, b, a := m.At(x, y).RGBA()

			r1, g1, b1, _ := m.At(x, y-1).RGBA()
			r2, g2, b2, _ := m.At(x-1, y).RGBA()
			r3, g3, b3, _ := m.At(x+1, y).RGBA()
			r4, g4, b4, _ := m.At(x, y+1).RGBA()

			r0 := (r1 + r2 + r3 + r4 + (2.0 * r)) / 6.0
			g0 := (g1 + g2 + g3 + g4 + (2.0 * g)) / 6.0
			b0 := (b1 + b2 + b3 + b4 + (2.0 * b)) / 6.0

			target.Set(x, y, color.RGBA{uint8(r0 / 255), uint8(g0 / 255), uint8(b0 / 255), uint8(a / 255)})
		}
	}

	return target
}

func colour(m image.Image) image.Image {
	bounds := m.Bounds()

	rm := image.NewRGBA(image.Rect(bounds.Min.Y, bounds.Min.X, bounds.Max.X, bounds.Max.Y))

	for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
		for x := bounds.Min.X; x < bounds.Max.X; x++ {
			r, g, b, a := m.At(x, y).RGBA()

			r = invertcolor(r, a)
			g = invertcolor(g, a)
			b = invertcolor(b, a)

			//r = r * uint32(*red)
			//g = g * uint32(*green)
			//b = b * uint32(*blue)

			rm.Set(x, y, color.RGBA{uint8(r), uint8(g), uint8(b), uint8(a)})
		}
	}

	return rm
}

func main() {
	flag.Parse()

	file, err := os.Open(*inputfile)
	checkerror(err)

	tofile, err := os.Create(*outputfile)
	checkerror(err)

	defer file.Close()
	defer tofile.Close()

	m, _, err := image.Decode(file)

	// rm := colour(m)
	rm := smooth(m)
	rm = outline(rm)

	jpeg.Encode(tofile, rm, &jpeg.Options{jpeg.DefaultQuality})
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"fmt"
	"log"

	"github.com/Cox-Automotive/alks-go"
	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func resourceAlksIamRole() *schema.Resource {
	return &schema.Resource{
		CreateContext: resourceAlksIamRoleCreate,
		ReadContext:   resourceAlksIamRoleRead,
		UpdateContext: resourceAlksIamRoleUpdate,
		DeleteContext: resourceAlksIamRoleDelete,
		Importer: &schema.ResourceImporter{
			StateContext: schema.ImportStatePassthroughContext,
		},
		SchemaVersion: 1,
		MigrateState:  migrateState,
		Schema: map[string]*schema.Schema{
			"name": {
				Type:          schema.TypeString,
				Optional:      true,
				Computed:      true,
				ForceNew:      true,
				ConflictsWith: []string{"name_prefix"},
			},
			"name_prefix": {
				Type:          schema.TypeString,
				Optional:      true,
				Computed:      true,
				ForceNew:      true,
				ConflictsWith: []string{"name"},
			},
			"type": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"include_default_policies": {
				Type:     schema.TypeBool,
				Required: true,
				ForceNew: true,
			},
			"role_added_to_ip": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"ip_arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"enable_alks_access": {
				Type:     schema.TypeBool,
				Default:  false,
				Optional: true,
			},
			"template_fields": {
				Type:     schema.TypeMap,
				Elem:     schema.TypeString,
				ForceNew: true,
				Optional: true,
			},
			"max_session_duration_in_seconds": {
				Type:     schema.TypeInt,
				Default:  3600,
				Optional: true,
			},
		},
	}
}

func resourceAlksIamRoleCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
	log.Printf("[INFO] ALKS IAM Role Create")

	var roleName = NameWithPrefix(d.Get("name").(string), d.Get("name_prefix").(string))
	var roleType = d.Get("type").(string)
	var incDefPol = d.Get("include_default_policies").(bool)
	var enableAlksAccess = d.Get("enable_alks_access").(bool)
	var rawTemplateFields = d.Get("template_fields").(map[string]interface{})
	var maxSessionDurationInSeconds = d.Get("max_session_duration_in_seconds").(int)

	templateFields := make(map[string]string)
	for k, v := range rawTemplateFields {
		templateFields[k] = v.(string)
	}

	var include int
	if incDefPol {
		include = 1
	}

	client := meta.(*alks.Client)
	if err := validateIAMEnabled(client); err != nil {
		return diag.FromErr(err)
	}

	options := alks.CreateIamRoleOptions{IncDefPols: include,
		AlksAccess:                  enableAlksAccess,
		TemplateFields:              templateFields,
		MaxSessionDurationInSeconds: maxSessionDurationInSeconds}

	resp, err := client.CreateIamRoleWithOptions(roleName, roleType, options)
	if err != nil {
		return diag.FromErr(err)
	}

	d.SetId(resp.RoleName)
	_ = d.Set("role_added_to_ip", resp.RoleAddedToIP)

	log.Printf("[INFO] alks_iamrole.id: %v", d.Id())

	return resourceAlksIamRoleRead(ctx, d, meta)
}

func resourceAlksIamRoleDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
	log.Printf("[INFO] ALKS IAM Role Delete")

	client := meta.(*alks.Client)
	if err := validateIAMEnabled(client); err != nil {
		return diag.FromErr(err)
	}

	if err := client.DeleteIamRole(d.Id()); err != nil {
		return diag.FromErr(err)
	}

	return nil
}

func resourceAlksIamRoleRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
	log.Printf("[INFO] ALKS IAM Role Read")

	client := meta.(*alks.Client)

	// Check if role exists.
	if d.Id() == "" || d.Id() == "none" {
		return nil
	}

	foundRole, err := client.GetIamRole(d.Id())

	if err != nil {
		d.SetId("")
		return nil
	}

	log.Printf("[INFO] alks_iamrole.id %v", d.Id())

	_ = d.Set("name", foundRole.RoleName)
	_ = d.Set("name_prefix", NamePrefixFromName(foundRole.RoleName))
	_ = d.Set("arn", foundRole.RoleArn)
	_ = d.Set("ip_arn", foundRole.RoleIPArn)
	_ = d.Set("enable_alks_access", foundRole.AlksAccess)

	// TODO: In the future, our API or tags need to dynamically grab these values.
	//  Till then, all imports require a destroy + create.
	//_ = d.Set("type", foundrole.RoleType)
	//_ = d.Set("include_default_policies", foundrole.InclDefaultPolicies)

	return nil
}

func resourceAlksIamRoleUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
	log.Printf("[INFO] ALKS IAM Role Update")

	// enable partial state mode
	d.Partial(true)

	if d.HasChange("enable_alks_access") {
		// try updating enable_alks_access
		if err := updateAlksAccess(d, meta); err != nil {
			return diag.FromErr(err)
		}
	}

	d.Partial(false)

	return resourceAlksIamRoleRead(ctx, d, meta)
}

func updateAlksAccess(d *schema.ResourceData, meta interface{}) error {
	var alksAccess = d.Get("enable_alks_access").(bool)
	var roleArn = d.Get("arn").(string)
	client := meta.(*alks.Client)
	if err := validateIAMEnabled(client); err != nil {
		return err
	}
	// create the machine identity
	if alksAccess {
		_, err := client.AddRoleMachineIdentity(roleArn)
		if err != nil {
			return err
		}
	} else {
		// delete the machine identity
		_, err := client.DeleteRoleMachineIdentity(roleArn)
		if err != nil {
			return err
		}
	}
	return nil
}

func migrateState(version int, state *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) {
	switch version {
	case 0:
		log.Println("[INFO] Found Instance State v0, migrating to v1")
		return migrateV0toV1(state)
	default:
		return state, fmt.Errorf("Unrecognized version '%d' in schema for instance of ALKS IAM role '%s'", version, state.Attributes["name"])
	}
}

func migrateV0toV1(state *terraform.InstanceState) (*terraform.InstanceState, error) {
	if state.Empty() {
		log.Println("[DEBUG] Empty InstanceState, nothing to migrate")
		return state, nil
	}

	if _, ok := state.Attributes["enable_alks_access"]; !ok {
		log.Printf("[DEBUG] Attributes before migration: %#v", state.Attributes)
		state.Attributes["enable_alks_access"] = "false"
		log.Printf("[DEBUG] Attributes after migration: %#v", state.Attributes)
	}

	return state, nil
}
<commit_msg>Adds tag fields to IamRoleCreate and retrofits function calls with newest alks-go signatures<commit_after>package main

import (
	"context"
	"fmt"
	"log"

	"github.com/Cox-Automotive/alks-go"
	"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
	"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
	"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func resourceAlksIamRole() *schema.Resource {
	return &schema.Resource{
		CreateContext: resourceAlksIamRoleCreate,
		ReadContext:   resourceAlksIamRoleRead,
		UpdateContext: resourceAlksIamRoleUpdate,
		DeleteContext: resourceAlksIamRoleDelete,
		Importer: &schema.ResourceImporter{
			StateContext: schema.ImportStatePassthroughContext,
		},
		SchemaVersion: 1,
		MigrateState:  migrateState,
		Schema: map[string]*schema.Schema{
			"name": {
				Type:          schema.TypeString,
				Optional:      true,
				Computed:      true,
				ForceNew:      true,
				ConflictsWith: []string{"name_prefix"},
			},
			"name_prefix": {
				Type:          schema.TypeString,
				Optional:      true,
				Computed:      true,
				ForceNew:      true,
				ConflictsWith: []string{"name"},
			},
			"type": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},
			"include_default_policies": {
				Type:     schema.TypeBool,
				Required: true,
				ForceNew: true,
			},
			"role_added_to_ip": {
				Type:     schema.TypeBool,
				Computed: true,
			},
			"arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"ip_arn": {
				Type:     schema.TypeString,
				Computed: true,
			},
			"enable_alks_access": {
				Type:     schema.TypeBool,
				Default:  false,
				Optional: true,
			},
			"template_fields": {
				Type:     schema.TypeMap,
				Elem:     schema.TypeString,
				ForceNew: true,
				Optional: true,
			},
			"max_session_duration_in_seconds": {
				Type:     schema.TypeInt,
				Default:  3600,
				Optional: true,
			},
			"tags": {
				Type:     schema.TypeMap,
				Elem:     schema.TypeString,
				ForceNew: false,
				Optional: true,
			},
		},
	}
}

func resourceAlksIamRoleCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
	log.Printf("[INFO] ALKS IAM Role Create")

	var roleName = NameWithPrefix(d.Get("name").(string), d.Get("name_prefix").(string))
	var roleType = d.Get("type").(string)
	var incDefPol = d.Get("include_default_policies").(bool)
	var enableAlksAccess = d.Get("enable_alks_access").(bool)
	var rawTemplateFields = d.Get("template_fields").(map[string]interface{})
	var maxSessionDurationInSeconds = d.Get("max_session_duration_in_seconds").(int)
	var rawTags = d.Get("tags").(map[string]interface{})

	templateFields := make(map[string]string)
	for k, v := range rawTemplateFields {
		templateFields[k] = v.(string)
	}

	tags := []*alks.Tag{}
	for k, v := range rawTags {
		kp := &k
		vp := &v
		tags = append(tags, &alks.Tag{Key: kp, Value: vp})
	}

	var include int
	if incDefPol {
		include = 1
	}

	client := meta.(*alks.Client)
	if err := validateIAMEnabled(client); err != nil {
		return diag.FromErr(err)
	}

	options := &alks.CreateIamRoleOptions{
		RoleName:                    &roleName,
		RoleType:                    &roleType,
		IncludeDefaultPolicies:      &include,
		AlksAccess:                  &enableAlksAccess,
		TemplateFields:              &templateFields,
		MaxSessionDurationInSeconds: &maxSessionDurationInSeconds,
		Tags:                        &tags,
	}

	resp, err := client.CreateIamRole(options)
	if err != nil {
		return diag.FromErr(err)
	}

	d.SetId(resp.RoleName)
	_ = d.Set("role_added_to_ip", resp.RoleAddedToIP)

	log.Printf("[INFO] alks_iamrole.id: %v", d.Id())

	return resourceAlksIamRoleRead(ctx, d, meta)
}

func resourceAlksIamRoleDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
	log.Printf("[INFO] ALKS IAM Role Delete")

	client := meta.(*alks.Client)
	if err := validateIAMEnabled(client); err != nil {
		return diag.FromErr(err)
	}

	if err := client.DeleteIamRole(d.Id()); err != nil {
		return diag.FromErr(err)
	}

	return nil
}

func resourceAlksIamRoleRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
	log.Printf("[INFO] ALKS IAM Role Read")

	client := meta.(*alks.Client)

	// Check if role exists.
	if d.Id() == "" || d.Id() == "none" {
		return nil
	}

	foundRole, err := client.GetIamRole(d.Id())

	if err != nil {
		d.SetId("")
		return nil
	}

	log.Printf("[INFO] alks_iamrole.id %v", d.Id())

	_ = d.Set("name", foundRole.RoleName)
	_ = d.Set("name_prefix", NamePrefixFromName(foundRole.RoleName))
	_ = d.Set("arn", foundRole.RoleArn)
	_ = d.Set("ip_arn", foundRole.RoleIPArn)
	_ = d.Set("enable_alks_access", foundRole.AlksAccess)

	// TODO: In the future, our API or tags need to dynamically grab these values.
	//  Till then, all imports require a destroy + create.
	//_ = d.Set("type", foundrole.RoleType)
	//_ = d.Set("include_default_policies", foundrole.InclDefaultPolicies)

	return nil
}

func resourceAlksIamRoleUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
	log.Printf("[INFO] ALKS IAM Role Update")

	// enable partial state mode
	d.Partial(true)

	if d.HasChange("enable_alks_access") {
		// try updating enable_alks_access
		if err := updateAlksAccess(d, meta); err != nil {
			return diag.FromErr(err)
		}
	}

	d.Partial(false)

	return resourceAlksIamRoleRead(ctx, d, meta)
}

func updateAlksAccess(d *schema.ResourceData, meta interface{}) error {
	var alksAccess = d.Get("enable_alks_access").(bool)
	var roleArn = d.Get("arn").(string)
	client := meta.(*alks.Client)
	if err := validateIAMEnabled(client); err != nil {
		return err
	}
	// create the machine identity
	if alksAccess {
		_, err := client.AddRoleMachineIdentity(roleArn)
		if err != nil {
			return err
		}
	} else {
		// delete the machine identity
		_, err := client.DeleteRoleMachineIdentity(roleArn)
		if err != nil {
			return err
		}
	}
	return nil
}

func migrateState(version int, state *terraform.InstanceState, meta interface{}) (*terraform.InstanceState, error) {
	switch version {
	case 0:
		log.Println("[INFO] Found Instance State v0, migrating to v1")
		return migrateV0toV1(state)
	default:
		return state, fmt.Errorf("Unrecognized version '%d' in schema for instance of ALKS IAM role '%s'", version, state.Attributes["name"])
	}
}

func migrateV0toV1(state *terraform.InstanceState) (*terraform.InstanceState, error) {
	if state.Empty() {
		log.Println("[DEBUG] Empty InstanceState, nothing to migrate")
		return state, nil
	}

	if _, ok := state.Attributes["enable_alks_access"]; !ok {
		log.Printf("[DEBUG] Attributes before migration: %#v", state.Attributes)
		state.Attributes["enable_alks_access"] = "false"
		log.Printf("[DEBUG] Attributes after migration: %#v", state.Attributes)
	}

	return state, nil
}
<|endoftext|>


<commit_before>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/hashicorp/terraform/helper/diff"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"github.com/mitchellh/goamz/ec2"
)

func resource_aws_instance_create(
	s *terraform.ResourceState,
	d *terraform.ResourceDiff,
	meta interface{}) (*terraform.ResourceState, error) {
	p := meta.(*ResourceProvider)
	ec2conn := p.ec2conn

	// Merge the diff into the state so that we have all the attributes
	// properly.
	rs := s.MergeDiff(d)

	// Create the instance
	runOpts := &ec2.RunInstances{
		ImageId:      rs.Attributes["ami"],
		InstanceType: rs.Attributes["instance_type"],
	}
	log.Printf("[DEBUG] Run configuration: %#v", runOpts)
	runResp, err := ec2conn.RunInstances(runOpts)
	if err != nil {
		return nil, fmt.Errorf("Error launching source instance: %s", err)
	}

	instance := &runResp.Instances[0]
	log.Printf("[INFO] Instance ID: %s", instance.InstanceId)

	// Store the resulting ID so we can look this up later
	rs.ID = instance.InstanceId

	// Wait for the instance to become running so we can get some attributes
	// that aren't available until later.
	log.Printf(
		"[DEBUG] Waiting for instance (%s) to become running",
		instance.InstanceId)

	stateConf := &resource.StateChangeConf{
		Pending: []string{"pending"},
		Target:  "running",
		Refresh: InstanceStateRefreshFunc(ec2conn, instance.InstanceId),
		Timeout: 10 * time.Minute,
	}

	instanceRaw, err := stateConf.WaitForState()

	if err != nil {
		return rs, fmt.Errorf(
			"Error waiting for instance (%s) to become ready: %s",
			instance.InstanceId, err)
	}

	instance = instanceRaw.(*ec2.Instance)

	// Set our attributes
	return resource_aws_instance_update_state(rs, instance)
}

func resource_aws_instance_destroy(
	s *terraform.ResourceState,
	meta interface{}) error {
	p := meta.(*ResourceProvider)
	ec2conn := p.ec2conn

	log.Printf("[INFO] Terminating instance: %s", s.ID)
	if _, err := ec2conn.TerminateInstances([]string{s.ID}); err != nil {
		return fmt.Errorf("Error terminating instance: %s", err)
	}

	log.Printf(
		"[DEBUG] Waiting for instance (%s) to become terminated",
		s.ID)

	stateConf := &resource.StateChangeConf{
		Pending: []string{"pending", "running", "shutting-down", "stopped", "stopping"},
		Target:  "terminated",
		Refresh: InstanceStateRefreshFunc(ec2conn, s.ID),
	}

	_, err := stateConf.WaitForState()

	if err != nil {
		return fmt.Errorf(
			"Error waiting for instance (%s) to terminate: %s",
			s.ID, err)
	}

	return nil
}

func resource_aws_instance_diff(
	s *terraform.ResourceState,
	c *terraform.ResourceConfig,
	meta interface{}) (*terraform.ResourceDiff, error) {
	b := &diff.ResourceBuilder{
		CreateComputedAttrs: []string{
			"public_dns",
			"public_ip",
			"private_dns",
			"private_ip",
		},

		RequiresNewAttrs: []string{
			"ami",
			"availability_zone",
			"instance_type",
		},
	}

	return b.Diff(s, c)
}

func resource_aws_instance_refresh(
	s *terraform.ResourceState,
	meta interface{}) (*terraform.ResourceState, error) {
	p := meta.(*ResourceProvider)
	ec2conn := p.ec2conn

	resp, err := ec2conn.Instances([]string{s.ID}, ec2.NewFilter())
	if err != nil {
		// If the instance was not found, return nil so that we can show
		// that the instance is gone.
		if ec2err, ok := err.(*ec2.Error); ok && ec2err.Code == "InvalidInstanceID.NotFound" {
			return nil, nil
		}

		// Some other error, report it
		return s, err
	}

	// If nothing was found, then return no state
	if len(resp.Reservations) == 0 {
		return nil, nil
	}

	instance := &resp.Reservations[0].Instances[0]

	// If the instance is terminated, then it is gone
	if instance.State.Name == "terminated" {
		return nil, nil
	}

	return resource_aws_instance_update_state(s, instance)
}

func resource_aws_instance_update_state(
	s *terraform.ResourceState,
	instance *ec2.Instance) (*terraform.ResourceState, error) {
	s.Attributes["public_dns"] = instance.DNSName
	s.Attributes["public_ip"] = instance.PublicIpAddress
	s.Attributes["private_dns"] = instance.PrivateDNSName
	s.Attributes["private_ip"] = instance.PrivateIpAddress
	return s, nil
}

// InstanceStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch
// an EC2 instance.
func InstanceStateRefreshFunc(conn *ec2.EC2, instanceID string) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {
		resp, err := conn.Instances([]string{instanceID}, ec2.NewFilter())
		if err != nil {
			if ec2err, ok := err.(*ec2.Error); ok && ec2err.Code == "InvalidInstanceID.NotFound" {
				// Set this to nil as if we didn't find anything.
				resp = nil
			} else {
				log.Printf("Error on InstanceStateRefresh: %s", err)
				return nil, "", err
			}
		}

		if resp == nil || len(resp.Reservations) == 0 || len(resp.Reservations[0].Instances) == 0 {
			// Sometimes AWS just has consistency issues and doesn't see
			// our instance yet. Return an empty state.
			return nil, "", nil
		}

		i := &resp.Reservations[0].Instances[0]
		return i, i.State.Name, nil
	}
}
<commit_msg>providers/aws: timeout in state change conf<commit_after>package aws

import (
	"fmt"
	"log"
	"time"

	"github.com/hashicorp/terraform/helper/diff"
	"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/terraform"
	"github.com/mitchellh/goamz/ec2"
)

func resource_aws_instance_create(
	s *terraform.ResourceState,
	d *terraform.ResourceDiff,
	meta interface{}) (*terraform.ResourceState, error) {
	p := meta.(*ResourceProvider)
	ec2conn := p.ec2conn

	// Merge the diff into the state so that we have all the attributes
	// properly.
	rs := s.MergeDiff(d)

	// Create the instance
	runOpts := &ec2.RunInstances{
		ImageId:      rs.Attributes["ami"],
		InstanceType: rs.Attributes["instance_type"],
	}
	log.Printf("[DEBUG] Run configuration: %#v", runOpts)
	runResp, err := ec2conn.RunInstances(runOpts)
	if err != nil {
		return nil, fmt.Errorf("Error launching source instance: %s", err)
	}

	instance := &runResp.Instances[0]
	log.Printf("[INFO] Instance ID: %s", instance.InstanceId)

	// Store the resulting ID so we can look this up later
	rs.ID = instance.InstanceId

	// Wait for the instance to become running so we can get some attributes
	// that aren't available until later.
	log.Printf(
		"[DEBUG] Waiting for instance (%s) to become running",
		instance.InstanceId)

	stateConf := &resource.StateChangeConf{
		Pending: []string{"pending"},
		Target:  "running",
		Refresh: InstanceStateRefreshFunc(ec2conn, instance.InstanceId),
		Timeout: 10 * time.Minute,
	}

	instanceRaw, err := stateConf.WaitForState()

	if err != nil {
		return rs, fmt.Errorf(
			"Error waiting for instance (%s) to become ready: %s",
			instance.InstanceId, err)
	}

	instance = instanceRaw.(*ec2.Instance)

	// Set our attributes
	return resource_aws_instance_update_state(rs, instance)
}

func resource_aws_instance_destroy(
	s *terraform.ResourceState,
	meta interface{}) error {
	p := meta.(*ResourceProvider)
	ec2conn := p.ec2conn

	log.Printf("[INFO] Terminating instance: %s", s.ID)
	if _, err := ec2conn.TerminateInstances([]string{s.ID}); err != nil {
		return fmt.Errorf("Error terminating instance: %s", err)
	}

	log.Printf(
		"[DEBUG] Waiting for instance (%s) to become terminated",
		s.ID)

	stateConf := &resource.StateChangeConf{
		Pending: []string{"pending", "running", "shutting-down", "stopped", "stopping"},
		Target:  "terminated",
		Refresh: InstanceStateRefreshFunc(ec2conn, s.ID),
		Timeout: 10 * time.Minute,
	}

	_, err := stateConf.WaitForState()

	if err != nil {
		return fmt.Errorf(
			"Error waiting for instance (%s) to terminate: %s",
			s.ID, err)
	}

	return nil
}

func resource_aws_instance_diff(
	s *terraform.ResourceState,
	c *terraform.ResourceConfig,
	meta interface{}) (*terraform.ResourceDiff, error) {
	b := &diff.ResourceBuilder{
		CreateComputedAttrs: []string{
			"public_dns",
			"public_ip",
			"private_dns",
			"private_ip",
		},

		RequiresNewAttrs: []string{
			"ami",
			"availability_zone",
			"instance_type",
		},
	}

	return b.Diff(s, c)
}

func resource_aws_instance_refresh(
	s *terraform.ResourceState,
	meta interface{}) (*terraform.ResourceState, error) {
	p := meta.(*ResourceProvider)
	ec2conn := p.ec2conn

	resp, err := ec2conn.Instances([]string{s.ID}, ec2.NewFilter())
	if err != nil {
		// If the instance was not found, return nil so that we can show
		// that the instance is gone.
		if ec2err, ok := err.(*ec2.Error); ok && ec2err.Code == "InvalidInstanceID.NotFound" {
			return nil, nil
		}

		// Some other error, report it
		return s, err
	}

	// If nothing was found, then return no state
	if len(resp.Reservations) == 0 {
		return nil, nil
	}

	instance := &resp.Reservations[0].Instances[0]

	// If the instance is terminated, then it is gone
	if instance.State.Name == "terminated" {
		return nil, nil
	}

	return resource_aws_instance_update_state(s, instance)
}

func resource_aws_instance_update_state(
	s *terraform.ResourceState,
	instance *ec2.Instance) (*terraform.ResourceState, error) {
	s.Attributes["public_dns"] = instance.DNSName
	s.Attributes["public_ip"] = instance.PublicIpAddress
	s.Attributes["private_dns"] = instance.PrivateDNSName
	s.Attributes["private_ip"] = instance.PrivateIpAddress
	return s, nil
}

// InstanceStateRefreshFunc returns a resource.StateRefreshFunc that is used to watch
// an EC2 instance.
func InstanceStateRefreshFunc(conn *ec2.EC2, instanceID string) resource.StateRefreshFunc {
	return func() (interface{}, string, error) {
		resp, err := conn.Instances([]string{instanceID}, ec2.NewFilter())
		if err != nil {
			if ec2err, ok := err.(*ec2.Error); ok && ec2err.Code == "InvalidInstanceID.NotFound" {
				// Set this to nil as if we didn't find anything.
				resp = nil
			} else {
				log.Printf("Error on InstanceStateRefresh: %s", err)
				return nil, "", err
			}
		}

		if resp == nil || len(resp.Reservations) == 0 || len(resp.Reservations[0].Instances) == 0 {
			// Sometimes AWS just has consistency issues and doesn't see
			// our instance yet. Return an empty state.
			return nil, "", nil
		}

		i := &resp.Reservations[0].Instances[0]
		return i, i.State.Name, nil
	}
}
<|endoftext|>


<commit_before>// timeutil provides a set of time utilities including comparisons,
// conversion to "DT8" int32 and "DT14" int64 formats and other
// capabilities.
package timeutil

import (
	"fmt"
	"strings"
	"time"
)

// More predefined layouts for use in Time.Format and time.Parse.
const (
	DT14                = "20060102150405"
	DT8                 = "20060102"
	DT6                 = "200601"
	RFC3339FullDate     = "2006-01-02"
	ISO8601YM           = "2006-01"
	ISO8601ZHour        = "2006-01-02T15:04:05-07"
	ISO8601Z            = "2006-01-02T15:04:05-0700"
	InsightlyApiQuery   = "_1/_2/2006 _3:04:05 PM"
	InsightlyApiObject  = "2006-01-02 15:04:05"
	ISO8601MilliNoTz    = "2006-01-02T15:04:05.000"
	ISO8601CompactZ     = "20060102T150405Z"
	ISO8601CompactLocal = "20060102T150405"
	DateMDYSlash        = "01/02/2006"
	DateDMYHM2          = "02:01:06 15:04" // GMT time in format dd:mm:yy hh:mm
)

const (
	RFC3339Min         = "0000-01-01T00:00:00Z"
	RFC3339Max         = "9999-12-31T23:59:59Z"
	RFC3339Zero        = "0001-01-01T00:00:00Z"
	RFC3339YMDZeroUnix = int64(-62135596800)
)

// Reformat a time string from one format to another
func FromTo(value, fromLayout, toLayout string) (string, error) {
	t, err := time.Parse(fromLayout, strings.TrimSpace(value))
	if err != nil {
		return "", err
	}
	return t.Format(toLayout), nil
}

// ParseFirst attempts to parse a string with a set of layouts.
func ParseFirst(layouts []string, value string) (time.Time, error) {
	value = strings.TrimSpace(value)
	if len(value) == 0 || len(layouts) == 0 {
		return time.Now(), fmt.Errorf(
			"Requires value [%v] and at least one layout [%v]", value, strings.Join(layouts, ","))
	}
	for _, layout := range layouts {
		layout = strings.TrimSpace(layout)
		if len(layout) == 0 {
			continue
		}
		if dt, err := time.Parse(layout, value); err == nil {
			return dt, nil
		}
	}
	return time.Now(), fmt.Errorf("Cannot parse time [%v] with layouts [%v]",
		value, strings.Join(layouts, ","))
}

var FormatMap = map[string]string{
	"RFC3339":    time.RFC3339,
	"RFC3339YMD": RFC3339FullDate,
	"ISO8601YM":  ISO8601YM,
}

func GetFormat(formatName string) (string, error) {
	format, ok := FormatMap[strings.TrimSpace(formatName)]
	if !ok {
		return "", fmt.Errorf("Format Not Found: %v", format)
	}
	return format, nil
}

// FormatQuarter takes quarter time and formats it using "Q# YYYY".
func FormatQuarter(t time.Time) string {
	return fmt.Sprintf("Q%d %d", MonthToQuarter(uint8(t.Month())), t.Year())
}

func TimeRFC3339Zero() time.Time {
	t0, _ := time.Parse(time.RFC3339, RFC3339Zero)
	return t0
}

type RFC3339YMDTime struct{ time.Time }

type ISO8601NoTzMilliTime struct{ time.Time }

func (t *RFC3339YMDTime) UnmarshalJSON(buf []byte) error {
	tt, isNil, err := timeUnmarshalJSON(buf, RFC3339FullDate)
	if err != nil || isNil {
		return err
	}
	t.Time = tt
	return nil
}

func (t RFC3339YMDTime) MarshalJSON() ([]byte, error) {
	return timeMarshalJSON(t.Time, RFC3339FullDate)
}

func (t *ISO8601NoTzMilliTime) UnmarshalJSON(buf []byte) error {
	tt, isNil, err := timeUnmarshalJSON(buf, ISO8601MilliNoTz)
	if err != nil || isNil {
		return err
	}
	t.Time = tt
	return nil
}

func (t ISO8601NoTzMilliTime) MarshalJSON() ([]byte, error) {
	return timeMarshalJSON(t.Time, ISO8601MilliNoTz)
}

func timeUnmarshalJSON(buf []byte, layout string) (time.Time, bool, error) {
	str := string(buf)
	isNil := true
	if str == "null" || str == "\"\"" {
		return time.Time{}, isNil, nil
	}
	tt, err := time.Parse(layout, strings.Trim(str, `"`))
	if err != nil {
		return time.Time{}, false, err
	}
	return tt, false, nil
}

func timeMarshalJSON(t time.Time, layout string) ([]byte, error) {
	return []byte(`"` + t.Format(layout) + `"`), nil
}
<commit_msg>update SQLTimestamp format name<commit_after>// timeutil provides a set of time utilities including comparisons,
// conversion to "DT8" int32 and "DT14" int64 formats and other
// capabilities.
package timeutil

import (
	"fmt"
	"strings"
	"time"
)

// More predefined layouts for use in Time.Format and time.Parse.
const (
	DT14                = "20060102150405"
	DT8                 = "20060102"
	DT6                 = "200601"
	RFC3339FullDate     = "2006-01-02"
	ISO8601YM           = "2006-01"
	ISO8601ZHour        = "2006-01-02T15:04:05-07"
	ISO8601Z            = "2006-01-02T15:04:05-0700"
	InsightlyApiQuery   = "_1/_2/2006 _3:04:05 PM"
	SQLTimestamp        = "2006-01-02 15:04:05" // MySQL, BigQuery, etc.
	ISO8601MilliNoTz    = "2006-01-02T15:04:05.000"
	ISO8601CompactZ     = "20060102T150405Z"
	ISO8601CompactLocal = "20060102T150405"
	DateMDYSlash        = "01/02/2006"
	DateDMYHM2          = "02:01:06 15:04" // GMT time in format dd:mm:yy hh:mm
)

const (
	RFC3339Min         = "0000-01-01T00:00:00Z"
	RFC3339Max         = "9999-12-31T23:59:59Z"
	RFC3339Zero        = "0001-01-01T00:00:00Z"
	RFC3339YMDZeroUnix = int64(-62135596800)
)

// Reformat a time string from one format to another
func FromTo(value, fromLayout, toLayout string) (string, error) {
	t, err := time.Parse(fromLayout, strings.TrimSpace(value))
	if err != nil {
		return "", err
	}
	return t.Format(toLayout), nil
}

// ParseFirst attempts to parse a string with a set of layouts.
func ParseFirst(layouts []string, value string) (time.Time, error) {
	value = strings.TrimSpace(value)
	if len(value) == 0 || len(layouts) == 0 {
		return time.Now(), fmt.Errorf(
			"Requires value [%v] and at least one layout [%v]", value, strings.Join(layouts, ","))
	}
	for _, layout := range layouts {
		layout = strings.TrimSpace(layout)
		if len(layout) == 0 {
			continue
		}
		if dt, err := time.Parse(layout, value); err == nil {
			return dt, nil
		}
	}
	return time.Now(), fmt.Errorf("Cannot parse time [%v] with layouts [%v]",
		value, strings.Join(layouts, ","))
}

var FormatMap = map[string]string{
	"RFC3339":    time.RFC3339,
	"RFC3339YMD": RFC3339FullDate,
	"ISO8601YM":  ISO8601YM,
}

func GetFormat(formatName string) (string, error) {
	format, ok := FormatMap[strings.TrimSpace(formatName)]
	if !ok {
		return "", fmt.Errorf("Format Not Found: %v", format)
	}
	return format, nil
}

// FormatQuarter takes quarter time and formats it using "Q# YYYY".
func FormatQuarter(t time.Time) string {
	return fmt.Sprintf("Q%d %d", MonthToQuarter(uint8(t.Month())), t.Year())
}

func TimeRFC3339Zero() time.Time {
	t0, _ := time.Parse(time.RFC3339, RFC3339Zero)
	return t0
}

type RFC3339YMDTime struct{ time.Time }

type ISO8601NoTzMilliTime struct{ time.Time }

func (t *RFC3339YMDTime) UnmarshalJSON(buf []byte) error {
	tt, isNil, err := timeUnmarshalJSON(buf, RFC3339FullDate)
	if err != nil || isNil {
		return err
	}
	t.Time = tt
	return nil
}

func (t RFC3339YMDTime) MarshalJSON() ([]byte, error) {
	return timeMarshalJSON(t.Time, RFC3339FullDate)
}

func (t *ISO8601NoTzMilliTime) UnmarshalJSON(buf []byte) error {
	tt, isNil, err := timeUnmarshalJSON(buf, ISO8601MilliNoTz)
	if err != nil || isNil {
		return err
	}
	t.Time = tt
	return nil
}

func (t ISO8601NoTzMilliTime) MarshalJSON() ([]byte, error) {
	return timeMarshalJSON(t.Time, ISO8601MilliNoTz)
}

func timeUnmarshalJSON(buf []byte, layout string) (time.Time, bool, error) {
	str := string(buf)
	isNil := true
	if str == "null" || str == "\"\"" {
		return time.Time{}, isNil, nil
	}
	tt, err := time.Parse(layout, strings.Trim(str, `"`))
	if err != nil {
		return time.Time{}, false, err
	}
	return tt, false, nil
}

func timeMarshalJSON(t time.Time, layout string) ([]byte, error) {
	return []byte(`"` + t.Format(layout) + `"`), nil
}
<|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.

// Perform a hermetic build of gcsfuse at a particular version, producing
// release binaries and packages.
package main

import (
	"errors"
	"flag"
	"fmt"
	"log"
	"os"
)

var fVersion = flag.String("version", "", "Version number of the release.")
var fCommit = flag.String("commit", "", "Commit at which to build.")
var fOS = flag.String("os", "", "OS for which to build, e.g. linux or darwin.")
var fArch = flag.String("arch", "amd64", "Architecture for which to build.")
var fOutputDir = flag.String("output_dir", "", "Where to write outputs.")
var fRPM = flag.Bool("rpm", true, "Build .rpm in addition to .deb.")

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

func getSettings() (version, commit, osys, arch, outputDir string, err error) {
	if *fVersion == "" {
		err = errors.New("You must set --version.")
		return
	}
	version = *fVersion

	if *fCommit == "" {
		err = errors.New("You must set --commit.")
		return
	}
	commit = *fCommit

	if *fOS == "" {
		err = errors.New("You must set --os.")
		return
	}
	osys = *fOS

	if *fArch == "" {
		err = errors.New("You must set --arch.")
		return
	}
	arch = *fArch

	// Output dir
	outputDir = *fOutputDir
	if outputDir == "" {
		outputDir, err = os.Getwd()
		if err != nil {
			err = fmt.Errorf("Getwd: %v", err)
			return
		}
	}

	return
}

////////////////////////////////////////////////////////////////////////
// main logic
////////////////////////////////////////////////////////////////////////

func run() (err error) {
	// Ensure that all of the tools we need are present.
	err = checkForTools()
	if err != nil {
		return
	}

	// Read flags.
	version, commit, osys, arch, outputDir, err := getSettings()
	if err != nil {
		return
	}

	// Build release binaries.
	binDir, err := buildBinaries(version, commit, osys, arch)
	if err != nil {
		err = fmt.Errorf("buildBinaries: %v", err)
		return
	}

	defer os.RemoveAll(binDir)

	// Write out a tarball.
	err = packageTarball(binDir, version, osys, arch, outputDir)
	if err != nil {
		err = fmt.Errorf("packageTarball: %v", err)
		return
	}

	// Write out .deb and maybe .rpm files if we're building for Linux.
	if osys == "linux" {
		err = packageDeb(binDir, version, osys, arch, *fOutputDir)
		if err != nil {
			err = fmt.Errorf("packageDeb: %v", err)
			return
		}

		if *fRPM {
			err = packageRpm(binDir, version, osys, arch, *fOutputDir)
			if err != nil {
				err = fmt.Errorf("packageDeb: %v", err)
				return
			}
		}
	}

	return
}

func main() {
	log.SetFlags(log.Lmicroseconds)
	flag.Parse()

	err := run()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}
<commit_msg>Inverted the RPM default.<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.

// Perform a hermetic build of gcsfuse at a particular version, producing
// release binaries and packages.
package main

import (
	"errors"
	"flag"
	"fmt"
	"log"
	"os"
)

var fVersion = flag.String("version", "", "Version number of the release.")
var fCommit = flag.String("commit", "", "Commit at which to build.")
var fOS = flag.String("os", "", "OS for which to build, e.g. linux or darwin.")
var fArch = flag.String("arch", "amd64", "Architecture for which to build.")
var fOutputDir = flag.String("output_dir", "", "Where to write outputs.")
var fRPM = flag.Bool("rpm", false, "Build .rpm in addition to .deb.")

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

func getSettings() (version, commit, osys, arch, outputDir string, err error) {
	if *fVersion == "" {
		err = errors.New("You must set --version.")
		return
	}
	version = *fVersion

	if *fCommit == "" {
		err = errors.New("You must set --commit.")
		return
	}
	commit = *fCommit

	if *fOS == "" {
		err = errors.New("You must set --os.")
		return
	}
	osys = *fOS

	if *fArch == "" {
		err = errors.New("You must set --arch.")
		return
	}
	arch = *fArch

	// Output dir
	outputDir = *fOutputDir
	if outputDir == "" {
		outputDir, err = os.Getwd()
		if err != nil {
			err = fmt.Errorf("Getwd: %v", err)
			return
		}
	}

	return
}

////////////////////////////////////////////////////////////////////////
// main logic
////////////////////////////////////////////////////////////////////////

func run() (err error) {
	// Ensure that all of the tools we need are present.
	err = checkForTools()
	if err != nil {
		return
	}

	// Read flags.
	version, commit, osys, arch, outputDir, err := getSettings()
	if err != nil {
		return
	}

	// Build release binaries.
	binDir, err := buildBinaries(version, commit, osys, arch)
	if err != nil {
		err = fmt.Errorf("buildBinaries: %v", err)
		return
	}

	defer os.RemoveAll(binDir)

	// Write out a tarball.
	err = packageTarball(binDir, version, osys, arch, outputDir)
	if err != nil {
		err = fmt.Errorf("packageTarball: %v", err)
		return
	}

	// Write out .deb and maybe .rpm files if we're building for Linux.
	if osys == "linux" {
		err = packageDeb(binDir, version, osys, arch, *fOutputDir)
		if err != nil {
			err = fmt.Errorf("packageDeb: %v", err)
			return
		}

		if *fRPM {
			err = packageRpm(binDir, version, osys, arch, *fOutputDir)
			if err != nil {
				err = fmt.Errorf("packageDeb: %v", err)
				return
			}
		}
	}

	return
}

func main() {
	log.SetFlags(log.Lmicroseconds)
	flag.Parse()

	err := run()
	if err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package logtap

import (
	"fmt"
	"github.com/boltdb/bolt"
	"github.com/pagodabox/golang-hatchet"
	"net/http"
	"strconv"
)

// HistoricalDrain matches the drain interface
type HistoricalDrain struct {
	port string
	max  int
	log  hatchet.Logger
	db   *bolt.DB
	deploy []string
}

// NewHistoricalDrain returns a new instance of a HistoricalDrain
func NewHistoricalDrain(port string, file string, max int) *HistoricalDrain {
	db, err := bolt.Open(file, 0644, nil)
	if err != nil {
		db, err = bolt.Open("./bolt.db", 0644, nil)
	}
	return &HistoricalDrain{
		port: port,
		max:  max,
		db:   db,
	}
}

// allow us to clear history of the deploy logs
func (h *HistoricalDrain) ClearDeploy() {
	h.deploy = []string{}
}

// Start starts the http listener.
// The listener on every request returns a json hash of logs of some arbitrary size
// default size is 100
func (h *HistoricalDrain) Start() {
	go func() {
		mux := http.NewServeMux()
		mux.HandleFunc("/logtap/system", h.handlerSystem)
		mux.HandleFunc("/logtap/deploy", h.handlerDeploy)
		err := http.ListenAndServe(":"+h.port, mux)
		if err != nil {
			h.log.Error("[LOGTAP]"+err.Error())
		}
	}()
}

func (h *HistoricalDrain) handlerDeploy(w http.ResponseWriter, r *http.Request) {
	for _, msg := range h.deploy {
		fmt.Fprintf(w, "%s", msg)
	}
}

// handler handles any web request with any path and returns logs
// this makes it so a client that talks to pagodabox's logvac
// can communicate with this system
func (h *HistoricalDrain) handlerSystem(w http.ResponseWriter, r *http.Request) {
	var limit int64
	if i, err := strconv.ParseInt(r.FormValue("limit"), 10, 64); err == nil {
		limit = i
	} else {
		limit = 10000
	}
	h.log.Debug("[LOGTAP][handler] limit: %d", limit)
	h.db.View(func(tx *bolt.Tx) error {
		// Create a new bucket.
		b := tx.Bucket([]byte("log"))
		c := b.Cursor()

		// move the curser along so we can start dropping logs
		// in the right order at the right place
		if int64(b.Stats().KeyN) > limit {
			c.First()
			move_forward := int64(b.Stats().KeyN) - limit
			for i := int64(1); i < move_forward; i++ {
				c.Next()
			}
		} else {
			c.First()
		}

		for k, v := c.Next(); k != nil; k, v = c.Next() {
			fmt.Fprintf(w, "%s - %s", k, v)
		}

		return nil
	})

}

// SetLogger really allows the logtap main struct
// to assign its own logger to the historical drain
func (h *HistoricalDrain) SetLogger(l hatchet.Logger) {
	h.log = l
}

// Write is used to implement the interface and do
// type switching
func (h *HistoricalDrain) Write(msg Message) {
  switch msg.Type {
  case "deploy":
  	h.WriteDeploy(msg)
  default :
    h.WriteSystem(msg)
  }
}

func (h *HistoricalDrain) WriteDeploy(msg Message) {
	h.deploy = append(h.deploy, (msg.Time.String()+" - "+msg.Content))
}

// WriteSyslog drops data into a capped collection of logs
// if we hit the limit the last log item will be removed from the beginning
func (h *HistoricalDrain) WriteSystem(msg Message) {
	h.log.Debug("[LOGTAP][Historical][write] message: (%s)%s", msg.Time.String(), msg.Content)
	h.db.Update(func(tx *bolt.Tx) error {
		bucket, err := tx.CreateBucketIfNotExists([]byte("log"))
		if err != nil {
			h.log.Error("[LOGTAP][Historical][write]" + err.Error())
			return err
		}
		err = bucket.Put([]byte(msg.Time.String()), []byte(msg.Content))
		if err != nil {
			h.log.Error("[LOGTAP][Historical][write]" + err.Error())
			return err
		}

		if bucket.Stats().KeyN > h.max {
			delete_count := bucket.Stats().KeyN - h.max
			c := bucket.Cursor()
			for i := 0; i < delete_count; i++ {
				c.First()
				c.Delete()
			}
		}

		return nil
	})

}
<commit_msg>messaging<commit_after>package logtap

import (
	"fmt"
	"github.com/boltdb/bolt"
	"github.com/pagodabox/golang-hatchet"
	"net/http"
	"strconv"
)

// HistoricalDrain matches the drain interface
type HistoricalDrain struct {
	port string
	max  int
	log  hatchet.Logger
	db   *bolt.DB
	deploy []string
}

// NewHistoricalDrain returns a new instance of a HistoricalDrain
func NewHistoricalDrain(port string, file string, max int) *HistoricalDrain {
	db, err := bolt.Open(file, 0644, nil)
	if err != nil {
		db, err = bolt.Open("./bolt.db", 0644, nil)
	}
	return &HistoricalDrain{
		port: port,
		max:  max,
		db:   db,
	}
}

// allow us to clear history of the deploy logs
func (h *HistoricalDrain) ClearDeploy() {
	h.deploy = []string{}
}

// Start starts the http listener.
// The listener on every request returns a json hash of logs of some arbitrary size
// default size is 100
func (h *HistoricalDrain) Start() {
	go func() {
		mux := http.NewServeMux()
		mux.HandleFunc("/logtap/system", h.handlerSystem)
		mux.HandleFunc("/logtap/deploy", h.handlerDeploy)
		err := http.ListenAndServe(":"+h.port, mux)
		if err != nil {
			h.log.Error("[LOGTAP]"+err.Error())
		}
	}()
}

// Handle deploys that come into this drain
// deploy logs should stay relatively short and should be cleared out easily
func (h *HistoricalDrain) handlerDeploy(w http.ResponseWriter, r *http.Request) {
	for _, msg := range h.deploy {
		fmt.Fprintf(w, "%s", msg)
	}
}

// handlerSystem handles any web request with any path and returns logs
// this makes it so a client that talks to pagodabox's logvac
// can communicate with this system
func (h *HistoricalDrain) handlerSystem(w http.ResponseWriter, r *http.Request) {
	var limit int64
	if i, err := strconv.ParseInt(r.FormValue("limit"), 10, 64); err == nil {
		limit = i
	} else {
		limit = 10000
	}
	h.log.Debug("[LOGTAP][handler] limit: %d", limit)
	h.db.View(func(tx *bolt.Tx) error {
		// Create a new bucket.
		b := tx.Bucket([]byte("log"))
		c := b.Cursor()

		// move the curser along so we can start dropping logs
		// in the right order at the right place
		if int64(b.Stats().KeyN) > limit {
			c.First()
			move_forward := int64(b.Stats().KeyN) - limit
			for i := int64(1); i < move_forward; i++ {
				c.Next()
			}
		} else {
			c.First()
		}

		for k, v := c.Next(); k != nil; k, v = c.Next() {
			fmt.Fprintf(w, "%s - %s", k, v)
		}

		return nil
	})

}

// SetLogger really allows the logtap main struct
// to assign its own logger to the historical drain
func (h *HistoricalDrain) SetLogger(l hatchet.Logger) {
	h.log = l
}

// Write is used to implement the interface and do
// type switching
func (h *HistoricalDrain) Write(msg Message) {
  switch msg.Type {
  case "deploy":
  	h.WriteDeploy(msg)
  default :
    h.WriteSystem(msg)
  }
}

// Write deploy logs to the deploy array.
// much quicker and better at handling deploy logs
func (h *HistoricalDrain) WriteDeploy(msg Message) {
	h.deploy = append(h.deploy, (msg.Time.String()+" - "+msg.Content))
}

// WriteSyslog drops data into a capped collection of logs
// if we hit the limit the last log item will be removed from the beginning
func (h *HistoricalDrain) WriteSystem(msg Message) {
	h.log.Debug("[LOGTAP][Historical][write] message: (%s)%s", msg.Time.String(), msg.Content)
	h.db.Update(func(tx *bolt.Tx) error {
		bucket, err := tx.CreateBucketIfNotExists([]byte("log"))
		if err != nil {
			h.log.Error("[LOGTAP][Historical][write]" + err.Error())
			return err
		}
		err = bucket.Put([]byte(msg.Time.String()), []byte(msg.Content))
		if err != nil {
			h.log.Error("[LOGTAP][Historical][write]" + err.Error())
			return err
		}

		if bucket.Stats().KeyN > h.max {
			delete_count := bucket.Stats().KeyN - h.max
			c := bucket.Cursor()
			for i := 0; i < delete_count; i++ {
				c.First()
				c.Delete()
			}
		}

		return nil
	})

}
<|endoftext|>


<commit_before>package jo

import (
	"fmt"
)

// A Scanner is a state machine which emits a series of Events when fed JSON
// input.
type Scanner struct {
	// Current state.
	state func(*Scanner, byte) Event

	// Scheduled state.
	stack []func(*Scanner, byte) Event

	// Used when delaying end events.
	end Event

	// Persisted syntax error.
	err error
}

// NewScanner initializes a new Scanner.
func NewScanner() *Scanner {
	s := &Scanner{stack: make([]func(*Scanner, byte) Event, 0, 4)}
	s.Reset()
	return s
}

// Reset restores a Scanner to its initial state.
func (s *Scanner) Reset() {
	s.state = beforeValue
	s.stack = append(s.stack[:0], afterTopValue)
	s.err = nil
}

// Scan accepts a byte of input and returns an Event.
func (s *Scanner) Scan(c byte) Event {
	return s.state(s, c)
}

// End signals the Scanner that the end of input has been reached. It returns
// an event just as Scan does.
func (s *Scanner) End() Event {
	// Feeding the state function whitespace will for NumberEnd events.
	// Note the bitwise operation to filter out the Space bit.
	ev := s.state(s, ' ') & (^Space)

	if s.err != nil {
		return Error
	}
	if len(s.stack) > 0 {
		return s.errorf(`unexpected end of JSON input`)
	}

	return ev
}

// LastError returns a syntax error description after either Scan or End has
// returned an Error event.
func (s *Scanner) LastError() error {
	return s.err
}

// errorf generates and persists an error.
func (s *Scanner) errorf(str string, args ...interface{}) Event {
	s.state = afterError
	s.err = fmt.Errorf(str, args...)
	return Error
}

// push pushes a state function onto the stack.
func (s *Scanner) push(fn func(*Scanner, byte) Event) {
	s.stack = append(s.stack, fn)
}

// next pops the next state function off the stack and invokes it.
func (s *Scanner) next(c byte) Event {
	n := len(s.stack) - 1
	s.state = s.stack[n]
	s.stack = s.stack[:n]

	return s.state(s, c)
}

// delay schedules an end event to be returned for the next byte of input.
func (s *Scanner) delay(ev Event) Event {
	s.state = delayed
	s.end = ev
	return None
}

func beforeValue(s *Scanner, c byte) Event {
	if c <= '9' {
		if c >= '1' {
			s.state = afterDigit
			return NumberStart
		} else if isSpace(c) {
			return Space
		} else if c == '"' {
			s.state = afterQuote
			s.end = StringEnd
			return StringStart
		} else if c == '-' {
			s.state = afterMinus
			return NumberStart
		} else if c == '0' {
			s.state = afterZero
			return NumberStart
		}
	} else if c == '{' {
		s.state = beforeFirstObjectKey
		return ObjectStart
	} else if c == '[' {
		s.state = beforeFirstArrayElement
		return ArrayStart
	} else if c == 't' {
		s.state = afterT
		return BoolStart
	} else if c == 'f' {
		s.state = afterF
		return BoolStart
	} else if c == 'n' {
		s.state = afterN
		return NullStart
	}

	return s.errorf(`invalid character %q in place of value start`)
}

func beforeFirstObjectKey(s *Scanner, c byte) Event {
	if isSpace(c) {
		return Space
	} else if c == '"' {
		s.state = afterQuote
		s.end = KeyEnd
		s.push(afterObjectKey)
		return KeyStart
	} else if c == '}' {
		return s.delay(ObjectEnd)
	}

	return s.errorf(`invalid character %q in object`, c)
}

func afterObjectKey(s *Scanner, c byte) Event {
	if isSpace(c) {
		return Space
	} else if c == ':' {
		s.state = beforeValue
		s.push(afterObjectValue)
		return None
	}

	return s.errorf(`invalid character %q after object key`, c)
}

func afterObjectValue(s *Scanner, c byte) Event {
	if isSpace(c) {
		return Space
	} else if c == ',' {
		s.state = afterObjectComma
		return None
	} else if c == '}' {
		return s.delay(ObjectEnd)
	}

	return s.errorf(`invalid character %q after object value`, c)
}

func afterObjectComma(s *Scanner, c byte) Event {
	if isSpace(c) {
		return Space
	} else if c == '"' {
		s.state = afterQuote
		s.end = KeyEnd
		s.push(afterObjectKey)
		return KeyStart
	}

	return s.errorf(`invalid character %q in place of object key`, c)
}

func beforeFirstArrayElement(s *Scanner, c byte) Event {
	if isSpace(c) {
		return Space
	} else if c == ']' {
		return s.delay(ArrayEnd)
	}

	s.push(afterArrayElement)
	return beforeValue(s, c)
}

func afterArrayElement(s *Scanner, c byte) Event {
	if isSpace(c) {
		return Space
	} else if c == ',' {
		s.state = beforeValue
		s.push(afterArrayElement)
		return None
	} else if c == ']' {
		return s.delay(ArrayEnd)
	}

	return s.errorf(`invalid character %q after array element`, c)
}

func afterQuote(s *Scanner, c byte) Event {
	if c == '"' {
		// At thie point, s.end has already been set to either StringEnd or
		// KeyEnd depending on the previous state function.
		s.state = delayed
		return None
	} else if c == '\\' {
		s.state = afterEsc
		return None
	} else if c >= 0x20 {
		return None
	}

	return s.errorf(`invalid character %q in string literal`, c)
}

func afterEsc(s *Scanner, c byte) Event {
	if isEsc(c) {
		s.state = afterQuote
		return None
	} else if c == 'u' {
		s.state = afterEscU
		return None
	}

	return s.errorf(`invalid character %q in character escape`, c)
}

func afterEscU(s *Scanner, c byte) Event {
	if isHex(c) {
		s.state = afterEscU1
		return None
	}

	return s.errorf(`invalid character %q in hexadecimal character escape`, c)
}

func afterEscU1(s *Scanner, c byte) Event {
	if isHex(c) {
		s.state = afterEscU12
		return None
	}

	return s.errorf(`invalid character %q in hexadecimal character escape`, c)
}

func afterEscU12(s *Scanner, c byte) Event {
	if isHex(c) {
		s.state = afterEscU123
		return None
	}

	return s.errorf(`invalid character %q in hexadecimal character escape`, c)
}

func afterEscU123(s *Scanner, c byte) Event {
	if isHex(c) {
		s.state = afterQuote
		return None
	}

	return s.errorf(`invalid character %q in hexadecimal character escape`, c)
}

func afterMinus(s *Scanner, c byte) Event {
	if c == '0' {
		s.state = afterZero
		return None
	} else if '1' <= c && c <= '9' {
		s.state = afterDigit
		return None
	}

	return s.errorf(`invalid character %q after "-"`, c)
}

func afterZero(s *Scanner, c byte) Event {
	if c == '.' {
		s.state = afterDot
		return None
	} else if c == 'e' || c == 'E' {
		s.state = afterE
		return None
	}

	return s.next(c) | NumberEnd
}

func afterDigit(s *Scanner, c byte) Event {
	if isDigit(c) {
		return None
	}

	return afterZero(s, c)
}

func afterDot(s *Scanner, c byte) Event {
	if isDigit(c) {
		s.state = afterDotDigit
		return None
	}

	return s.errorf(`invalid character %q after decimal point in numeric literal`, c)
}

func afterDotDigit(s *Scanner, c byte) Event {
	if isDigit(c) {
		return None
	} else if c == 'e' || c == 'E' {
		s.state = afterE
		return None
	}

	return s.next(c) | NumberEnd
}

func afterE(s *Scanner, c byte) Event {
	if isDigit(c) {
		s.state = afterEDigit
		return None
	} else if c == '-' || c == '+' {
		s.state = afterESign
		return None
	}

	return s.errorf(`invalid character %q in exponent of numeric literal`, c)
}

func afterESign(s *Scanner, c byte) Event {
	if isDigit(c) {
		s.state = afterEDigit
		return None
	}

	return s.errorf(`invalid character %q in exponent of numeric literal`, c)
}

func afterEDigit(s *Scanner, c byte) Event {
	if isDigit(c) {
		return None
	}

	return s.next(c) | NumberEnd
}

func afterT(s *Scanner, c byte) Event {
	if c == 'r' {
		s.state = afterTr
		return None
	}

	return s.errorf(`invalid character %q after "t"`, c)
}

func afterTr(s *Scanner, c byte) Event {
	if c == 'u' {
		s.state = afterTru
		return None
	}

	return s.errorf(`invalid character %q after "tr"`, c)
}

func afterTru(s *Scanner, c byte) Event {
	if c == 'e' {
		return s.delay(BoolEnd)
	}

	return s.errorf(`invalid character %q after "tru"`, c)
}

func afterF(s *Scanner, c byte) Event {
	if c == 'a' {
		s.state = afterFa
		return None
	}

	return s.errorf(`invalid character %q after "f"`, c)
}

func afterFa(s *Scanner, c byte) Event {
	if c == 'l' {
		s.state = afterFal
		return None
	}

	return s.errorf(`invalid character %q after "fa"`, c)
}

func afterFal(s *Scanner, c byte) Event {
	if c == 's' {
		s.state = afterFals
		return None
	}

	return s.errorf(`invalid character %q after "fal"`, c)
}

func afterFals(s *Scanner, c byte) Event {
	if c == 'e' {
		return s.delay(BoolEnd)
	}

	return s.errorf(`invalid character %q after "fals"`, c)
}

func afterN(s *Scanner, c byte) Event {
	if c == 'u' {
		s.state = afterNu
		return None
	}

	return s.errorf(`invalid character %q after "n"`, c)
}

func afterNu(s *Scanner, c byte) Event {
	if c == 'l' {
		s.state = afterNul
		return None
	}

	return s.errorf(`invalid character %q after "nu"`, c)
}

func afterNul(s *Scanner, c byte) Event {
	if c == 'l' {
		return s.delay(NullEnd)
	}

	return s.errorf(`invalid character %q after "nul"`, c)
}

func delayed(s *Scanner, c byte) Event {
	return s.next(c) | s.end
}

func afterTopValue(s *Scanner, c byte) Event {
	if isSpace(c) {
		return Space
	}

	return s.errorf(`invalid character %q after top-level value`, c)
}

func afterError(s *Scanner, c byte) Event {
	return Error
}

// isSpace returns true if c is a whitespace character.
func isSpace(c byte) bool {
	return c == ' ' || c == '\t' || c == '\r' || c == '\n'
}

// isDigit returns true if c is a valid decimal digit.
func isDigit(c byte) bool {
	return '0' <= c && c <= '9'
}

// isHex returns true if c is a valid hexadecimal digit.
func isHex(c byte) bool {
	return '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F'
}

// isEsc returns true if `\` + c is a valid escape sequence.
func isEsc(c byte) bool {
	return c == 'b' || c == 'f' || c == 'n' || c == 'r' || c == 't' ||
		c == '\\' || c == '/' || c == '"'
}
<commit_msg>Replace character class functions with a lookup table<commit_after>package jo

import (
	"fmt"
)

// A Scanner is a state machine which emits a series of Events when fed JSON
// input.
type Scanner struct {
	// Current state.
	state func(*Scanner, byte) Event

	// Scheduled state.
	stack []func(*Scanner, byte) Event

	// Used when delaying end events.
	end Event

	// Persisted syntax error.
	err error
}

// NewScanner initializes a new Scanner.
func NewScanner() *Scanner {
	s := &Scanner{stack: make([]func(*Scanner, byte) Event, 0, 4)}
	s.Reset()
	return s
}

// Reset restores a Scanner to its initial state.
func (s *Scanner) Reset() {
	s.state = beforeValue
	s.stack = append(s.stack[:0], afterTopValue)
	s.err = nil
}

// Scan accepts a byte of input and returns an Event.
func (s *Scanner) Scan(c byte) Event {
	return s.state(s, c)
}

// End signals the Scanner that the end of input has been reached. It returns
// an event just as Scan does.
func (s *Scanner) End() Event {
	// Feeding the state function whitespace will for NumberEnd events.
	// Note the bitwise operation to filter out the Space bit.
	ev := s.state(s, ' ') & (^Space)

	if s.err != nil {
		return Error
	}
	if len(s.stack) > 0 {
		return s.errorf(`unexpected end of JSON input`)
	}

	return ev
}

// LastError returns a syntax error description after either Scan or End has
// returned an Error event.
func (s *Scanner) LastError() error {
	return s.err
}

// errorf generates and persists an error.
func (s *Scanner) errorf(str string, args ...interface{}) Event {
	s.state = afterError
	s.err = fmt.Errorf(str, args...)
	return Error
}

// push pushes a state function onto the stack.
func (s *Scanner) push(fn func(*Scanner, byte) Event) {
	s.stack = append(s.stack, fn)
}

// next pops the next state function off the stack and invokes it.
func (s *Scanner) next(c byte) Event {
	n := len(s.stack) - 1
	s.state = s.stack[n]
	s.stack = s.stack[:n]

	return s.state(s, c)
}

// delay schedules an end event to be returned for the next byte of input.
func (s *Scanner) delay(ev Event) Event {
	s.state = delayed
	s.end = ev
	return None
}

func beforeValue(s *Scanner, c byte) Event {
	if c <= '9' {
		if c >= '1' {
			s.state = afterDigit
			return NumberStart
		} else if table[c]&isSpace != 0 {
			return Space
		} else if c == '"' {
			s.state = afterQuote
			s.end = StringEnd
			return StringStart
		} else if c == '-' {
			s.state = afterMinus
			return NumberStart
		} else if c == '0' {
			s.state = afterZero
			return NumberStart
		}
	} else if c == '{' {
		s.state = beforeFirstObjectKey
		return ObjectStart
	} else if c == '[' {
		s.state = beforeFirstArrayElement
		return ArrayStart
	} else if c == 't' {
		s.state = afterT
		return BoolStart
	} else if c == 'f' {
		s.state = afterF
		return BoolStart
	} else if c == 'n' {
		s.state = afterN
		return NullStart
	}

	return s.errorf(`invalid character %q in place of value start`)
}

func beforeFirstObjectKey(s *Scanner, c byte) Event {
	if table[c]&isSpace != 0 {
		return Space
	} else if c == '"' {
		s.state = afterQuote
		s.end = KeyEnd
		s.push(afterObjectKey)
		return KeyStart
	} else if c == '}' {
		return s.delay(ObjectEnd)
	}

	return s.errorf(`invalid character %q in object`, c)
}

func afterObjectKey(s *Scanner, c byte) Event {
	if table[c]&isSpace != 0 {
		return Space
	} else if c == ':' {
		s.state = beforeValue
		s.push(afterObjectValue)
		return None
	}

	return s.errorf(`invalid character %q after object key`, c)
}

func afterObjectValue(s *Scanner, c byte) Event {
	if table[c]&isSpace != 0 {
		return Space
	} else if c == ',' {
		s.state = afterObjectComma
		return None
	} else if c == '}' {
		return s.delay(ObjectEnd)
	}

	return s.errorf(`invalid character %q after object value`, c)
}

func afterObjectComma(s *Scanner, c byte) Event {
	if table[c]&isSpace != 0 {
		return Space
	} else if c == '"' {
		s.state = afterQuote
		s.end = KeyEnd
		s.push(afterObjectKey)
		return KeyStart
	}

	return s.errorf(`invalid character %q in place of object key`, c)
}

func beforeFirstArrayElement(s *Scanner, c byte) Event {
	if table[c]&isSpace != 0 {
		return Space
	} else if c == ']' {
		return s.delay(ArrayEnd)
	}

	s.push(afterArrayElement)
	return beforeValue(s, c)
}

func afterArrayElement(s *Scanner, c byte) Event {
	if table[c]&isSpace != 0 {
		return Space
	} else if c == ',' {
		s.state = beforeValue
		s.push(afterArrayElement)
		return None
	} else if c == ']' {
		return s.delay(ArrayEnd)
	}

	return s.errorf(`invalid character %q after array element`, c)
}

func afterQuote(s *Scanner, c byte) Event {
	if c == '"' {
		// At thie point, s.end has already been set to either StringEnd or
		// KeyEnd depending on the previous state function.
		s.state = delayed
		return None
	} else if c == '\\' {
		s.state = afterEsc
		return None
	} else if c >= 0x20 {
		return None
	}

	return s.errorf(`invalid character %q in string literal`, c)
}

func afterEsc(s *Scanner, c byte) Event {
	if table[c]&isEsc != 0 {
		s.state = afterQuote
		return None
	} else if c == 'u' {
		s.state = afterEscU
		return None
	}

	return s.errorf(`invalid character %q in character escape`, c)
}

func afterEscU(s *Scanner, c byte) Event {
	if table[c]&isHex != 0 {
		s.state = afterEscU1
		return None
	}

	return s.errorf(`invalid character %q in hexadecimal character escape`, c)
}

func afterEscU1(s *Scanner, c byte) Event {
	if table[c]&isHex != 0 {
		s.state = afterEscU12
		return None
	}

	return s.errorf(`invalid character %q in hexadecimal character escape`, c)
}

func afterEscU12(s *Scanner, c byte) Event {
	if table[c]&isHex != 0 {
		s.state = afterEscU123
		return None
	}

	return s.errorf(`invalid character %q in hexadecimal character escape`, c)
}

func afterEscU123(s *Scanner, c byte) Event {
	if table[c]&isHex != 0 {
		s.state = afterQuote
		return None
	}

	return s.errorf(`invalid character %q in hexadecimal character escape`, c)
}

func afterMinus(s *Scanner, c byte) Event {
	if c == '0' {
		s.state = afterZero
		return None
	} else if '1' <= c && c <= '9' {
		s.state = afterDigit
		return None
	}

	return s.errorf(`invalid character %q after "-"`, c)
}

func afterZero(s *Scanner, c byte) Event {
	if c == '.' {
		s.state = afterDot
		return None
	} else if c == 'e' || c == 'E' {
		s.state = afterE
		return None
	}

	return s.next(c) | NumberEnd
}

func afterDigit(s *Scanner, c byte) Event {
	if table[c]&isDigit != 0 {
		return None
	}

	return afterZero(s, c)
}

func afterDot(s *Scanner, c byte) Event {
	if table[c]&isDigit != 0 {
		s.state = afterDotDigit
		return None
	}

	return s.errorf(`invalid character %q after decimal point in numeric literal`, c)
}

func afterDotDigit(s *Scanner, c byte) Event {
	if table[c]&isDigit != 0 {
		return None
	} else if c == 'e' || c == 'E' {
		s.state = afterE
		return None
	}

	return s.next(c) | NumberEnd
}

func afterE(s *Scanner, c byte) Event {
	if table[c]&isDigit != 0 {
		s.state = afterEDigit
		return None
	} else if c == '-' || c == '+' {
		s.state = afterESign
		return None
	}

	return s.errorf(`invalid character %q in exponent of numeric literal`, c)
}

func afterESign(s *Scanner, c byte) Event {
	if table[c]&isDigit != 0 {
		s.state = afterEDigit
		return None
	}

	return s.errorf(`invalid character %q in exponent of numeric literal`, c)
}

func afterEDigit(s *Scanner, c byte) Event {
	if table[c]&isDigit != 0 {
		return None
	}

	return s.next(c) | NumberEnd
}

func afterT(s *Scanner, c byte) Event {
	if c == 'r' {
		s.state = afterTr
		return None
	}

	return s.errorf(`invalid character %q after "t"`, c)
}

func afterTr(s *Scanner, c byte) Event {
	if c == 'u' {
		s.state = afterTru
		return None
	}

	return s.errorf(`invalid character %q after "tr"`, c)
}

func afterTru(s *Scanner, c byte) Event {
	if c == 'e' {
		return s.delay(BoolEnd)
	}

	return s.errorf(`invalid character %q after "tru"`, c)
}

func afterF(s *Scanner, c byte) Event {
	if c == 'a' {
		s.state = afterFa
		return None
	}

	return s.errorf(`invalid character %q after "f"`, c)
}

func afterFa(s *Scanner, c byte) Event {
	if c == 'l' {
		s.state = afterFal
		return None
	}

	return s.errorf(`invalid character %q after "fa"`, c)
}

func afterFal(s *Scanner, c byte) Event {
	if c == 's' {
		s.state = afterFals
		return None
	}

	return s.errorf(`invalid character %q after "fal"`, c)
}

func afterFals(s *Scanner, c byte) Event {
	if c == 'e' {
		return s.delay(BoolEnd)
	}

	return s.errorf(`invalid character %q after "fals"`, c)
}

func afterN(s *Scanner, c byte) Event {
	if c == 'u' {
		s.state = afterNu
		return None
	}

	return s.errorf(`invalid character %q after "n"`, c)
}

func afterNu(s *Scanner, c byte) Event {
	if c == 'l' {
		s.state = afterNul
		return None
	}

	return s.errorf(`invalid character %q after "nu"`, c)
}

func afterNul(s *Scanner, c byte) Event {
	if c == 'l' {
		return s.delay(NullEnd)
	}

	return s.errorf(`invalid character %q after "nul"`, c)
}

func delayed(s *Scanner, c byte) Event {
	return s.next(c) | s.end
}

func afterTopValue(s *Scanner, c byte) Event {
	if table[c]&isSpace != 0 {
		return Space
	}

	return s.errorf(`invalid character %q after top-level value`, c)
}

func afterError(s *Scanner, c byte) Event {
	return Error
}

// Character type lookup table.
var table = [256]byte{}

const (
	isSpace = 1 << iota
	isDigit
	isHex
	isEsc
)

func init() {
	for i := 0; i < 256; i++ {
		c := byte(i)

		if c == ' ' || c == '\n' || c == '\t' || c == '\r' {
			table[i] |= isSpace
		}
		if '0' <= c && c <= '9' {
			table[i] |= isDigit
		}
		if '0' <= c && c <= '9' || 'a' <= c && c <= 'f' || 'A' <= c && c <= 'F' {
			table[i] |= isHex
		}
		if c == 'b' || c == 'f' || c == 'n' || c == 'r' || c == 't' ||
			c == '\\' || c == '/' || c == '"' {
			table[i] |= isEsc
		}
	}
}
<|endoftext|>


<commit_before>package rocket

type char struct {
	cargo       string
	sourceIndex int
	lineIndex   int
	colIndex    int
}

func GetChar(file string, coll int, line int, sourceIndex int) *char {
	wantedChar := string(file[sourceIndex])
	if wantedChar == " " {
		wantedChar = "SPACE"
	}
	if wantedChar == "\n" {
		wantedChar = ""
	}

	return &char{wantedChar, sourceIndex, line, coll}

}
<commit_msg>removed scanner, will add it back when i need it<commit_after><|endoftext|>