<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os"
	"strings"
	"time"

	"h12.me/kafka/broker"
)

const (
	clientID = "h12.me/kafka/kafpro"
)

type Config struct {
	Broker  string
	Meta    MetaConfig
	Coord   CoordConfig
	Offset  OffsetConfig
	Commit  CommitConfig
	Time    TimeConfig
	Consume ConsumeConfig
}

type CoordConfig struct {
	GroupName string
}

type OffsetConfig struct {
	GroupName string
	Topic     string
	Partition int
}

type TimeConfig struct {
	Topic     string
	Partition int
	Time      string
}

type ConsumeConfig struct {
	Topic     string
	Partition int
	Offset    int
}

type MetaConfig struct {
	Topics []string
}

type CommitConfig struct {
	GroupName string
	Topic     string
	Partition int
	Offset    int
	Retention int // millisecond
}

func main() {
	var cfg Config
	flag.StringVar(&cfg.Broker, "broker", "", "broker address")

	// get subcommand
	if len(os.Args) < 2 {
		usage()
		os.Exit(1)
	}
	subCmd := os.Args[1]
	os.Args = append(os.Args[0:1], os.Args[2:]...)

	switch subCmd {
	case "meta":
		var topicsArg string
		flag.StringVar(&topicsArg, "topics", "", "topic names seperated by comma")
		flag.Parse()
		br := broker.New(broker.DefaultConfig().WithAddr(cfg.Broker))
		cfg.Meta.Topics = strings.Split(topicsArg, ",")
		if err := meta(br, &cfg.Meta); err != nil {
			log.Fatal(err)
		}
	case "coord":
		flag.StringVar(&cfg.Coord.GroupName, "group", "", "group name")
		flag.Parse()
		br := broker.New(broker.DefaultConfig().WithAddr(cfg.Broker))
		if err := coord(br, &cfg.Coord); err != nil {
			log.Fatal(err)
		}
	case "offset":
		flag.StringVar(&cfg.Offset.GroupName, "group", "", "group name")
		flag.StringVar(&cfg.Offset.Topic, "topic", "", "topic name")
		flag.IntVar(&cfg.Offset.Partition, "partition", 0, "partition")
		flag.Parse()
		br := broker.New(broker.DefaultConfig().WithAddr(cfg.Broker))
		if err := offset(br, &cfg.Offset); err != nil {
			log.Fatal(err)
		}
	case "commit":
		flag.StringVar(&cfg.Commit.GroupName, "group", "", "group name")
		flag.StringVar(&cfg.Commit.Topic, "topic", "", "topic name")
		flag.IntVar(&cfg.Commit.Partition, "partition", 0, "partition")
		flag.IntVar(&cfg.Commit.Offset, "offset", 0, "offset")
		flag.IntVar(&cfg.Commit.Retention, "retention", 0, "retention")
		flag.Parse()
		br := broker.New(broker.DefaultConfig().WithAddr(cfg.Broker))
		if err := commit(br, &cfg.Commit); err != nil {
			log.Fatal(err)
		}
	case "time":
		flag.StringVar(&cfg.Time.Topic, "topic", "", "topic name")
		flag.IntVar(&cfg.Time.Partition, "partition", 0, "partition")
		flag.StringVar(&cfg.Time.Time, "time", "", "time")
		flag.Parse()
		br := broker.New(broker.DefaultConfig().WithAddr(cfg.Broker))
		if err := timeOffset(br, &cfg.Time); err != nil {
			log.Fatal(err)
		}
	case "consume":
		flag.StringVar(&cfg.Consume.Topic, "topic", "", "topic name")
		flag.IntVar(&cfg.Consume.Partition, "partition", 0, "partition")
		flag.IntVar(&cfg.Consume.Offset, "offset", 0, "offset")
		flag.Parse()
		br := broker.New(broker.DefaultConfig().WithAddr(cfg.Broker))
		if err := consume(br, &cfg.Consume); err != nil {
			log.Fatal(err)
		}
	default:
		log.Fatalf("invalid subcommand %s", subCmd)
	}
}

func usage() {
	fmt.Println(`
kafpro is a command line tool for querying Kafka wire API

Usage:

	kafpro command [arguments]

The commands are:

	meta     TopicMetadataRequest
	consume  FetchRequest
	time     OffsetRequest
	offset   OffsetFetchRequestV1
	commit   OffsetCommitRequestV1
	coord    GroupCoordinatorRequest

`)
	flag.PrintDefaults()
}

func meta(br *broker.B, cfg *MetaConfig) error {
	resp, err := br.TopicMetadata(cfg.Topics...)
	if err != nil {
		return err
	}
	fmt.Println(toJSON(resp))
	return nil
}

func coord(br *broker.B, coord *CoordConfig) error {
	reqMsg := broker.GroupCoordinatorRequest(coord.GroupName)
	req := &broker.Request{
		ClientID:       clientID,
		RequestMessage: &reqMsg,
	}
	resp := &broker.GroupCoordinatorResponse{}
	if err := br.Do(req, resp); err != nil {
		return err
	}
	fmt.Println(toJSON(&resp))
	if resp.ErrorCode.HasError() {
		return resp.ErrorCode
	}
	return nil
}

func offset(br *broker.B, cfg *OffsetConfig) error {
	req := &broker.Request{
		ClientID: clientID,
		RequestMessage: &broker.OffsetFetchRequestV1{
			ConsumerGroup: cfg.GroupName,
			PartitionInTopics: []broker.PartitionInTopic{
				{
					TopicName:  cfg.Topic,
					Partitions: []int32{int32(cfg.Partition)},
				},
			},
		},
	}
	resp := broker.OffsetFetchResponse{}
	if err := br.Do(req, &resp); err != nil {
		return err
	}
	fmt.Println(toJSON(&resp))
	for i := range resp {
		t := &resp[i]
		if t.TopicName == cfg.Topic {
			for j := range resp[i].OffsetMetadataInPartitions {
				p := &t.OffsetMetadataInPartitions[j]
				if p.Partition == int32(cfg.Partition) {
					if p.ErrorCode.HasError() {
						return p.ErrorCode
					}
				}
			}
		}
	}
	return nil
}

func commit(br *broker.B, cfg *CommitConfig) error {
	req := &broker.Request{
		ClientID: clientID,
		RequestMessage: &broker.OffsetCommitRequestV1{
			ConsumerGroupID: cfg.GroupName,
			OffsetCommitInTopicV1s: []broker.OffsetCommitInTopicV1{
				{
					TopicName: cfg.Topic,
					OffsetCommitInPartitionV1s: []broker.OffsetCommitInPartitionV1{
						{
							Partition: int32(cfg.Partition),
							Offset:    int64(cfg.Offset),
							// TimeStamp in milliseconds
							TimeStamp: time.Now().Add(time.Duration(cfg.Retention)*time.Millisecond).Unix() * 1000,
						},
					},
				},
			},
		},
	}
	resp := broker.OffsetCommitResponse{}
	if err := br.Do(req, &resp); err != nil {
		return err
	}
	for i := range resp {
		t := &resp[i]
		if t.TopicName == cfg.Topic {
			for j := range t.ErrorInPartitions {
				p := &t.ErrorInPartitions[j]
				if int(p.Partition) == cfg.Partition {
					if p.ErrorCode.HasError() {
						return p.ErrorCode
					}
				}
			}
		}
	}
	return nil
}

func timeOffset(br *broker.B, cfg *TimeConfig) error {
	var t time.Time
	switch cfg.Time {
	case "latest":
		t = broker.Latest
	case "earliest":
		t = broker.Earliest
	default:
		var err error
		t, err = time.Parse("2006-01-02T15:04:05", cfg.Time)
		if err != nil {
			return err
		}
	}
	resp, err := br.OffsetByTime(cfg.Topic, int32(cfg.Partition), t)
	if err != nil {
		return err
	}
	fmt.Println(toJSON(&resp))
	return nil
}

func consume(br *broker.B, cfg *ConsumeConfig) error {
	req := &broker.Request{
		ClientID: clientID,
		RequestMessage: &broker.FetchRequest{
			ReplicaID:   -1,
			MaxWaitTime: int32(time.Second / time.Millisecond),
			MinBytes:    int32(1024),
			FetchOffsetInTopics: []broker.FetchOffsetInTopic{
				{
					TopicName: cfg.Topic,
					FetchOffsetInPartitions: []broker.FetchOffsetInPartition{
						{
							Partition:   int32(cfg.Partition),
							FetchOffset: int64(cfg.Offset),
							MaxBytes:    int32(1000),
						},
					},
				},
			},
		},
	}
	resp := broker.FetchResponse{}
	if err := br.Do(req, &resp); err != nil {
		return err
	}
	fmt.Println(toJSON(resp))
	for _, t := range resp {
		for _, p := range t.FetchMessageSetInPartitions {
			ms, err := p.MessageSet.Flatten()
			if err != nil {
				return err
			}
			fmt.Println(toJSON(ms))
		}
	}
	return nil
}

func toJSON(v interface{}) string {
	buf, _ := json.MarshalIndent(v, "", "\t")
	return string(buf)
}
<commit_msg>move GroupCoordinator to broker package<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"os"
	"strings"
	"time"

	"h12.me/kafka/broker"
)

const (
	clientID = "h12.me/kafka/kafpro"
)

type Config struct {
	Broker  string
	Meta    MetaConfig
	Coord   CoordConfig
	Offset  OffsetConfig
	Commit  CommitConfig
	Time    TimeConfig
	Consume ConsumeConfig
}

type CoordConfig struct {
	GroupName string
}

type OffsetConfig struct {
	GroupName string
	Topic     string
	Partition int
}

type TimeConfig struct {
	Topic     string
	Partition int
	Time      string
}

type ConsumeConfig struct {
	Topic     string
	Partition int
	Offset    int
}

type MetaConfig struct {
	Topics []string
}

type CommitConfig struct {
	GroupName string
	Topic     string
	Partition int
	Offset    int
	Retention int // millisecond
}

func main() {
	var cfg Config
	flag.StringVar(&cfg.Broker, "broker", "", "broker address")

	// get subcommand
	if len(os.Args) < 2 {
		usage()
		os.Exit(1)
	}
	subCmd := os.Args[1]
	os.Args = append(os.Args[0:1], os.Args[2:]...)

	switch subCmd {
	case "meta":
		var topicsArg string
		flag.StringVar(&topicsArg, "topics", "", "topic names seperated by comma")
		flag.Parse()
		br := broker.New(broker.DefaultConfig().WithAddr(cfg.Broker))
		cfg.Meta.Topics = strings.Split(topicsArg, ",")
		if err := meta(br, &cfg.Meta); err != nil {
			log.Fatal(err)
		}
	case "coord":
		flag.StringVar(&cfg.Coord.GroupName, "group", "", "group name")
		flag.Parse()
		br := broker.New(broker.DefaultConfig().WithAddr(cfg.Broker))
		if err := coord(br, &cfg.Coord); err != nil {
			log.Fatal(err)
		}
	case "offset":
		flag.StringVar(&cfg.Offset.GroupName, "group", "", "group name")
		flag.StringVar(&cfg.Offset.Topic, "topic", "", "topic name")
		flag.IntVar(&cfg.Offset.Partition, "partition", 0, "partition")
		flag.Parse()
		br := broker.New(broker.DefaultConfig().WithAddr(cfg.Broker))
		if err := offset(br, &cfg.Offset); err != nil {
			log.Fatal(err)
		}
	case "commit":
		flag.StringVar(&cfg.Commit.GroupName, "group", "", "group name")
		flag.StringVar(&cfg.Commit.Topic, "topic", "", "topic name")
		flag.IntVar(&cfg.Commit.Partition, "partition", 0, "partition")
		flag.IntVar(&cfg.Commit.Offset, "offset", 0, "offset")
		flag.IntVar(&cfg.Commit.Retention, "retention", 0, "retention")
		flag.Parse()
		br := broker.New(broker.DefaultConfig().WithAddr(cfg.Broker))
		if err := commit(br, &cfg.Commit); err != nil {
			log.Fatal(err)
		}
	case "time":
		flag.StringVar(&cfg.Time.Topic, "topic", "", "topic name")
		flag.IntVar(&cfg.Time.Partition, "partition", 0, "partition")
		flag.StringVar(&cfg.Time.Time, "time", "", "time")
		flag.Parse()
		br := broker.New(broker.DefaultConfig().WithAddr(cfg.Broker))
		if err := timeOffset(br, &cfg.Time); err != nil {
			log.Fatal(err)
		}
	case "consume":
		flag.StringVar(&cfg.Consume.Topic, "topic", "", "topic name")
		flag.IntVar(&cfg.Consume.Partition, "partition", 0, "partition")
		flag.IntVar(&cfg.Consume.Offset, "offset", 0, "offset")
		flag.Parse()
		br := broker.New(broker.DefaultConfig().WithAddr(cfg.Broker))
		if err := consume(br, &cfg.Consume); err != nil {
			log.Fatal(err)
		}
	default:
		log.Fatalf("invalid subcommand %s", subCmd)
	}
}

func usage() {
	fmt.Println(`
kafpro is a command line tool for querying Kafka wire API

Usage:

	kafpro command [arguments]

The commands are:

	meta     TopicMetadataRequest
	consume  FetchRequest
	time     OffsetRequest
	offset   OffsetFetchRequestV1
	commit   OffsetCommitRequestV1
	coord    GroupCoordinatorRequest

`)
	flag.PrintDefaults()
}

func meta(br *broker.B, cfg *MetaConfig) error {
	resp, err := br.TopicMetadata(cfg.Topics...)
	if err != nil {
		return err
	}
	fmt.Println(toJSON(resp))
	return nil
}

func coord(br *broker.B, coord *CoordConfig) error {
	resp, err := br.GroupCoordinator(coord.GroupName)
	if err != nil {
		return err
	}
	fmt.Println(toJSON(resp))
	return nil
}

func offset(br *broker.B, cfg *OffsetConfig) error {
	req := &broker.Request{
		ClientID: clientID,
		RequestMessage: &broker.OffsetFetchRequestV1{
			ConsumerGroup: cfg.GroupName,
			PartitionInTopics: []broker.PartitionInTopic{
				{
					TopicName:  cfg.Topic,
					Partitions: []int32{int32(cfg.Partition)},
				},
			},
		},
	}
	resp := broker.OffsetFetchResponse{}
	if err := br.Do(req, &resp); err != nil {
		return err
	}
	fmt.Println(toJSON(&resp))
	for i := range resp {
		t := &resp[i]
		if t.TopicName == cfg.Topic {
			for j := range resp[i].OffsetMetadataInPartitions {
				p := &t.OffsetMetadataInPartitions[j]
				if p.Partition == int32(cfg.Partition) {
					if p.ErrorCode.HasError() {
						return p.ErrorCode
					}
				}
			}
		}
	}
	return nil
}

func commit(br *broker.B, cfg *CommitConfig) error {
	req := &broker.Request{
		ClientID: clientID,
		RequestMessage: &broker.OffsetCommitRequestV1{
			ConsumerGroupID: cfg.GroupName,
			OffsetCommitInTopicV1s: []broker.OffsetCommitInTopicV1{
				{
					TopicName: cfg.Topic,
					OffsetCommitInPartitionV1s: []broker.OffsetCommitInPartitionV1{
						{
							Partition: int32(cfg.Partition),
							Offset:    int64(cfg.Offset),
							// TimeStamp in milliseconds
							TimeStamp: time.Now().Add(time.Duration(cfg.Retention)*time.Millisecond).Unix() * 1000,
						},
					},
				},
			},
		},
	}
	resp := broker.OffsetCommitResponse{}
	if err := br.Do(req, &resp); err != nil {
		return err
	}
	for i := range resp {
		t := &resp[i]
		if t.TopicName == cfg.Topic {
			for j := range t.ErrorInPartitions {
				p := &t.ErrorInPartitions[j]
				if int(p.Partition) == cfg.Partition {
					if p.ErrorCode.HasError() {
						return p.ErrorCode
					}
				}
			}
		}
	}
	return nil
}

func timeOffset(br *broker.B, cfg *TimeConfig) error {
	var t time.Time
	switch cfg.Time {
	case "latest":
		t = broker.Latest
	case "earliest":
		t = broker.Earliest
	default:
		var err error
		t, err = time.Parse("2006-01-02T15:04:05", cfg.Time)
		if err != nil {
			return err
		}
	}
	resp, err := br.OffsetByTime(cfg.Topic, int32(cfg.Partition), t)
	if err != nil {
		return err
	}
	fmt.Println(toJSON(&resp))
	return nil
}

func consume(br *broker.B, cfg *ConsumeConfig) error {
	req := &broker.Request{
		ClientID: clientID,
		RequestMessage: &broker.FetchRequest{
			ReplicaID:   -1,
			MaxWaitTime: int32(time.Second / time.Millisecond),
			MinBytes:    int32(1024),
			FetchOffsetInTopics: []broker.FetchOffsetInTopic{
				{
					TopicName: cfg.Topic,
					FetchOffsetInPartitions: []broker.FetchOffsetInPartition{
						{
							Partition:   int32(cfg.Partition),
							FetchOffset: int64(cfg.Offset),
							MaxBytes:    int32(1000),
						},
					},
				},
			},
		},
	}
	resp := broker.FetchResponse{}
	if err := br.Do(req, &resp); err != nil {
		return err
	}
	fmt.Println(toJSON(resp))
	for _, t := range resp {
		for _, p := range t.FetchMessageSetInPartitions {
			ms, err := p.MessageSet.Flatten()
			if err != nil {
				return err
			}
			fmt.Println(toJSON(ms))
		}
	}
	return nil
}

func toJSON(v interface{}) string {
	buf, _ := json.MarshalIndent(v, "", "\t")
	return string(buf)
}
<|endoftext|>


<commit_before>
package core

import ("fmt"
	"os"
	"strconv"
	"runtime"
	"math"
	"bytes"
	"time"
	"github.com/jackyb/go-sdl2/sdl"
	"github.com/op/go-nanomsg"
	"github.com/fire/go-ogre3d"
	"github.com/jmckaskill/go-capnproto")

type InputState struct {
	yawSens float32
	pitchSens float32
	orientationFactor float32 // +1/-1 easy switch between look around and manipulate something
	yaw float32 // degrees, modulo [-180,180] range
	pitch float32 // degrees, clamped [-90,90] range
	roll float32
	orientation ogre.Quaternion // current orientation
}

func InitCore() {
	var gameThreadParams GameThreadParams
	gameThreadParams.start = time.Now() // There's an small time before this variable is initalized,
	// it probably doesn't matter... Someone timed Go initalization at 1.94us on Linux.

	sdl.Init(sdl.INIT_EVERYTHING)
	var event sdl.Event
	window := sdl.CreateWindow("es_core::SDL",
		sdl.WINDOWPOS_UNDEFINED,
		sdl.WINDOWPOS_UNDEFINED,
		800,
		600,
		sdl.WINDOW_SHOWN)
	if window == nil {
		panic(fmt.Sprintf("sdl.CreateWindow failed: %s\n", sdl.GetError()))
	}
	defer sdl.Quit()
	var info sdl.SysWMInfo
	if !window.GetWMInfo(&info) {
		panic(fmt.Sprintf("window.GetWMInfo failed.\n"))
	}
	var version sdl.Version
	sdl.GetVersion(&version)

	fmt.Printf("Sdl Major Version: %d\n", version.Major)
	fmt.Printf("Sdl Minor Version: %d\n", version.Minor)
	fmt.Printf("Sdl Patch level: %d\n", version.Patch)
	fmt.Printf("Sdl Subsystem: %s\n", getSubsystemString(info))
	root := ogre.NewRoot("", "", "ogre.log")
	defer root.Destroy()
	wd, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	if runtime.GOOS == "windows" {
		root.LoadPlugin(wd  + "/RenderSystem_GL3Plus")
		}
	if runtime.GOOS == "darwin" {
		root.LoadPlugin(wd  + "/../frameworks/RenderSystem_GL3Plus")
	}

	renderers := root.GetAvailableRenderers()
	if renderers.RenderSystemListSize() != 1 {

		panic(fmt.Sprintf("Failed to initalize RendererRenderSystem_GL"))
	}
	root.SetRenderSystem(renderers.RenderSystemListGet(0))
	root.Initialise(false, "es_core::ogre")
	params := ogre.CreateNameValuePairList()
	if runtime.GOOS == "windows" {
		windowsInfo := info.GetWindowsInfo()
		windowString := strconv.FormatUint(uint64(*(*uint32)(windowsInfo.Window)), 10)
		params.AddPair("parentWindowHandle", windowString)
	}
	if runtime.GOOS == "darwin" {
		params.AddPair("macAPI", "cocoa")
		cocoaInfo := info.GetCocoaInfo()
		windowString := strconv.FormatUint(uint64(*(*uint32)(cocoaInfo.Window)), 10)
		params.AddPair("parentWindowHandle", windowString)
	}

	renderWindow := root.CreateRenderWindow("es_core::ogre", 800, 600, false, params)
	renderWindow.SetVisible(true)

	nnGameSocket, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.BUS)
        if err != nil {
                panic(err)
        }
        _, err = nnGameSocket.Bind("tcp://127.0.0.1:60206")
        if err != nil {
                panic(err)
        }

	nnRenderSocket, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.BUS)
	if err != nil {
                panic(err)
        }
        _, err = nnRenderSocket.Bind("tcp://127.0.0.1:60207")
        if err != nil {
                panic(err)
        }

	nnInputPub, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.PUB)
        if err != nil {
                panic(err)
        }
        _, err = nnInputPub.Bind("tcp://127.0.0.1:60208")
        if err != nil {
                panic(err)
        }

	nnInputPull, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.PULL)
        if err != nil {
                panic(err)
        }
        _, err = nnInputPull.Bind("tcp://127.0.0.1:60209")
        if err != nil {
                panic(err)
        }
	go gameThread(gameThreadParams)
	var renderThreadParams RenderThreadParams
	renderThreadParams.start = gameThreadParams.start
	renderThreadParams.root = root
	renderThreadParams.window = window
	renderThreadParams.ogreWindow = renderWindow

	go renderThread(renderThreadParams)

	window.SetGrab(true)
	sdl.SetRelativeMouseMode(true)

	shutdownRequested := false
	var is InputState
	is.yawSens = 0.1
	is.yaw = 0.0
	is.pitchSens = 0.1
	is.pitch = 0.0
	is.roll = 0.0
	is.orientationFactor = -1.0 // Look around config

	for !shutdownRequested /* && SDL_GetTicks() < MAX_RUN_TIME */ {
		// We wait here.
		b, err := nnInputPull.Recv(0)
		if err != nil {
			fmt.Printf("%s\n", err)
		}
		s, _, err := capn.ReadFromMemoryZeroCopy(b)
		if err != nil {
			fmt.Printf("Read error %v\n", err)
			return
		}
		state := ReadRootState(s)
		fmt.Printf("Game push received:\n")
		// poll for events before processing the request
		// NOTE: this is how SDL builds the internal mouse and keyboard state
		// TODO: done this way does not meet the objectives of smooth, frame independent mouse view control,
		// Plus it throws some latency into the calling thread

		for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent {
			switch t := event.(type) {
			case *sdl.KeyDownEvent:
				fmt.Printf("SDL keyboard event:\n")
			case *sdl.KeyUpEvent:
				fmt.Printf("SDL keyboard event:\n")
				if t.Keysym.Scancode == sdl.SCANCODE_ESCAPE {
					sendShutdown(nnRenderSocket, nnGameSocket)
					shutdownRequested = true
				}
			case *sdl.MouseMotionEvent:
				// + when manipulating an object, - when doing a first person view .. needs to be configurable?
				is.yaw += is.orientationFactor * is.yawSens * float32(t.XRel)
				if is.yaw >= 0.0 {
					is.yaw = float32(math.Mod(float64(is.yaw) + 180.0, 360.0) - 180.0)
				} else {
					is.yaw = float32(math.Mod(float64(is.yaw) - 180.0, 360.0) + 180.0)
				}
				// + when manipulating an object, - when doing a first person view .. needs to be configurable?
				is.pitch += is.orientationFactor * is.pitchSens * float32(t.YRel)
				if is.pitch > 90.0 {
					is.pitch = 90.0
				} else if ( is.pitch < -90.0 ) {
					is.pitch = -90.0
				}
				// build a quaternion of the current orientation
				var r ogre.Matrix3
				r.FromEulerAnglesYXZ( deg2Rad(is.yaw), deg2Rad(is.pitch), deg2Rad(is.roll))
				is.orientation.FromRotationMatrix(r)
			case *sdl.MouseButtonEvent:
				fmt.Printf("SDL mouse button event:\n")
			case *sdl.QuitEvent:
			    // push a shutdown on the control socket, game and render will pick it up later
				// NOTE: if the message patterns change we may still have to deal with hangs here
				sendShutdown(nnRenderSocket, nnGameSocket)
				shutdownRequested = true
			default:
				fmt.Printf("SDL_Event: %T\n", t);

			}
		}
		switch {
		// we are ready to process the request now
		case state.Mouse():
			buttons := sdl.GetMouseState(nil, nil)
			fmt.Printf("buttons: %d\n", buttons)
			s := capn.NewBuffer(nil)
			ms := NewRootInputMouse(s)
			ms.SetW(is.orientation.W())
			ms.SetX(is.orientation.X())
			ms.SetY(is.orientation.Y())
			ms.SetZ(is.orientation.Z())
			ms.SetButtons(buttons)
			buf := bytes.Buffer{}
			s.WriteTo(&buf)
			nnInputPub.Send(append([]byte("input.mouse:"), buf.Bytes()...), 0)
			fmt.Printf("Mouse input sent.\n")

		case state.Kb():
		// looking at a few hardcoded keys for now
		// NOTE: I suspect it would be perfectly safe to grab that pointer once, and read it from a different thread?
			state := sdl.GetKeyboardState()
			t := capn.NewBuffer(nil)
			kbs := NewRootInputKb(t)
			kbs.SetW(state[sdl.SCANCODE_W] != 0)
			kbs.SetA(state[sdl.SCANCODE_A] != 0)
			kbs.SetS(state[sdl.SCANCODE_S] != 0)
			kbs.SetD(state[sdl.SCANCODE_D] != 0)
			kbs.SetSpace(state[sdl.SCANCODE_SPACE] != 0)
			kbs.SetLalt(state[sdl.SCANCODE_LALT] != 0)
			b := bytes.Buffer{}
			t.WriteTo(&b)
			nnInputPub.Send(append([]byte("input.kb:"), b.Bytes()...), 0)
			fmt.Printf("Keyboard input sent.\n")

		case state.MouseReset():
			var q ogre.Quaternion;
			is.orientation = q.FromValues(state.Quaternion().W(), state.Quaternion().X(),
				state.Quaternion().Y(), state.Quaternion().Z())
			var r ogre.Matrix3
			is.orientation.ToRotationMatrix(&r)
			var rfYAngle, rfPAngle, rfRAngle float32
			r.ToEulerAnglesYXZ(&rfYAngle, &rfPAngle, &rfRAngle)
			is.yaw = rad2Deg(rfYAngle)
			is.pitch = rad2Deg(rfPAngle)
			is.roll = rad2Deg(rfRAngle)
		case state.ConfigLookAround():
			if state.LookAround().ManipulateObject() {
				fmt.Printf("Input configuration: manipulate object\n");
				is.orientationFactor = 1.0;
			} else {
				fmt.Printf("Input configuration: look around\n");
				is.orientationFactor = -1.0
			}
		}
	}
	if !shutdownRequested {
      sendShutdown(nnRenderSocket, nnGameSocket)
      shutdownRequested = true
    }
    waitShutdown(nnInputPull, &gameThreadParams)
}

func deg2Rad(deg float32) float32 {
	return deg * math.Pi / 180
}

func rad2Deg (rad float32) float32 {
	return rad * 180 / math.Pi
}

func sendShutdown(nnRenderSocket *nanomsg.Socket, nnGameSocket *nanomsg.Socket) {
	s := capn.NewBuffer(nil)
	stop := NewRootStop(s)
	stop.SetStop(true)
	buf := bytes.Buffer{}
	s.WriteTo(&buf)
	fmt.Printf("Render socket shutdown.\n")
	nnRenderSocket.Send(buf.Bytes(), 0)
	fmt.Printf("Game socket shutdown.\n")
	nnGameSocket.Send(buf.Bytes(), 0)
}

func waitShutdown(nnInputPull *nanomsg.Socket, params *GameThreadParams) {
	// For now, loop the input thread for a bit to flush out any events
	continueTime := time.Since(params.start) + 500 * time.Millisecond  // An eternity.
	for time.Since(params.start) < continueTime {
		msg, _ := nnInputPull.Recv(nanomsg.DontWait)
		if msg == nil {
			sdl.Delay(10)
		}
	}
}

func getSubsystemString(info sdl.SysWMInfo) string {
	switch info.Subsystem {
	case 0:
	    return "Unknown"
	case 1:
		return "Windows"
	case 2:
		return "X11"
	case 3:
		return "DirectFB"
	case 4:
		return "Cocoa"
	case 5:
		return "UiKit"
	}
	return "Unknown"
}
<commit_msg>Use externalGLControl and externalGLContext.<commit_after>
package core

import ("fmt"
	"os"
	"strconv"
	"runtime"
	"math"
	"bytes"
	"time"
	"github.com/jackyb/go-sdl2/sdl"
	"github.com/op/go-nanomsg"
	"github.com/fire/go-ogre3d"
	"github.com/jmckaskill/go-capnproto")

type InputState struct {
	yawSens float32
	pitchSens float32
	orientationFactor float32 // +1/-1 easy switch between look around and manipulate something
	yaw float32 // degrees, modulo [-180,180] range
	pitch float32 // degrees, clamped [-90,90] range
	roll float32
	orientation ogre.Quaternion // current orientation
}

func InitCore() {
	var gameThreadParams GameThreadParams
	gameThreadParams.start = time.Now() // There's an small time before this variable is initalized,
	// it probably doesn't matter... Someone timed Go initalization at 1.94us on Linux.

	sdl.Init(sdl.INIT_EVERYTHING)
	var event sdl.Event
	window := sdl.CreateWindow("es_core::SDL",
		sdl.WINDOWPOS_UNDEFINED,
		sdl.WINDOWPOS_UNDEFINED,
		800,
		600,
		sdl.WINDOW_OPENGL|sdl.WINDOW_SHOWN)
	if window == nil {
		panic(fmt.Sprintf("sdl.CreateWindow failed: %s\n", sdl.GetError()))
	}
	defer sdl.Quit()
	glContext := sdl.GL_CreateContext(window)

	var info sdl.SysWMInfo
	if !window.GetWMInfo(&info) {
		panic(fmt.Sprintf("window.GetWMInfo failed.\n"))
	}
	var version sdl.Version
	sdl.GetVersion(&version)

	fmt.Printf("Sdl Major Version: %d\n", version.Major)
	fmt.Printf("Sdl Minor Version: %d\n", version.Minor)
	fmt.Printf("Sdl Patch level: %d\n", version.Patch)
	fmt.Printf("Sdl Subsystem: %s\n", getSubsystemString(info))
	root := ogre.NewRoot("", "", "ogre.log")
	defer root.Destroy()
	wd, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	if runtime.GOOS == "windows" {
		root.LoadPlugin(wd  + "/RenderSystem_GL3Plus")
		}
	if runtime.GOOS == "darwin" {
		root.LoadPlugin(wd  + "/../frameworks/RenderSystem_GL3Plus")
	}

	renderers := root.GetAvailableRenderers()
	if renderers.RenderSystemListSize() != 1 {

		panic(fmt.Sprintf("Failed to initalize RendererRenderSystem_GL"))
	}
	root.SetRenderSystem(renderers.RenderSystemListGet(0))
	root.Initialise(false, "es_core::ogre")
	params := ogre.CreateNameValuePairList()
	if runtime.GOOS == "windows" {
		params.AddPair("externalGLControl", "1")
		// Only supported for Win32 on Ogre 1.9 not on other platforms (documentation needs fixing to accurately reflect this)
		params.AddPair("externalGLContext", strconv.FormatUint(uint64(uintptr(glContext)), 10))

		windowsInfo := info.GetWindowsInfo()
		windowString := strconv.FormatUint(uint64(uintptr(windowsInfo.Window)), 10)
		params.AddPair("externalWindowHandle", windowString)
	}
	if runtime.GOOS == "darwin" {
		params.AddPair("macAPI", "cocoa")
		cocoaInfo := info.GetCocoaInfo()
		params.AddPair("parentWindowHandle", strconv.FormatUint(uint64(*(*uint32)(cocoaInfo.Window)), 10))
	}

	renderWindow := root.CreateRenderWindow("es_core::ogre", 800, 600, false, params)
	renderWindow.SetVisible(true)

	nnGameSocket, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.BUS)
        if err != nil {
                panic(err)
        }
        _, err = nnGameSocket.Bind("tcp://127.0.0.1:60206")
        if err != nil {
                panic(err)
        }

	nnRenderSocket, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.BUS)
	if err != nil {
                panic(err)
        }
        _, err = nnRenderSocket.Bind("tcp://127.0.0.1:60207")
        if err != nil {
                panic(err)
        }

	nnInputPub, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.PUB)
        if err != nil {
                panic(err)
        }
        _, err = nnInputPub.Bind("tcp://127.0.0.1:60208")
        if err != nil {
                panic(err)
        }

	nnInputPull, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.PULL)
        if err != nil {
                panic(err)
        }
        _, err = nnInputPull.Bind("tcp://127.0.0.1:60209")
        if err != nil {
                panic(err)
        }
	go gameThread(gameThreadParams)
	var renderThreadParams RenderThreadParams
	renderThreadParams.start = gameThreadParams.start
	renderThreadParams.root = root
	renderThreadParams.window = window
	renderThreadParams.ogreWindow = renderWindow

	go renderThread(renderThreadParams)

	window.SetGrab(true)
	sdl.SetRelativeMouseMode(true)

	shutdownRequested := false
	var is InputState
	is.yawSens = 0.1
	is.yaw = 0.0
	is.pitchSens = 0.1
	is.pitch = 0.0
	is.roll = 0.0
	is.orientationFactor = -1.0 // Look around config

	for !shutdownRequested /* && SDL_GetTicks() < MAX_RUN_TIME */ {
		// We wait here.
		b, err := nnInputPull.Recv(0)
		if err != nil {
			fmt.Printf("%s\n", err)
		}
		s, _, err := capn.ReadFromMemoryZeroCopy(b)
		if err != nil {
			fmt.Printf("Read error %v\n", err)
			return
		}
		state := ReadRootState(s)
		fmt.Printf("Game push received:\n")
		// poll for events before processing the request
		// NOTE: this is how SDL builds the internal mouse and keyboard state
		// TODO: done this way does not meet the objectives of smooth, frame independent mouse view control,
		// Plus it throws some latency into the calling thread

		for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent {
			switch t := event.(type) {
			case *sdl.KeyDownEvent:
				fmt.Printf("SDL keyboard event:\n")
			case *sdl.KeyUpEvent:
				fmt.Printf("SDL keyboard event:\n")
				if t.Keysym.Scancode == sdl.SCANCODE_ESCAPE {
					sendShutdown(nnRenderSocket, nnGameSocket)
					shutdownRequested = true
				}
			case *sdl.MouseMotionEvent:
				// + when manipulating an object, - when doing a first person view .. needs to be configurable?
				is.yaw += is.orientationFactor * is.yawSens * float32(t.XRel)
				if is.yaw >= 0.0 {
					is.yaw = float32(math.Mod(float64(is.yaw) + 180.0, 360.0) - 180.0)
				} else {
					is.yaw = float32(math.Mod(float64(is.yaw) - 180.0, 360.0) + 180.0)
				}
				// + when manipulating an object, - when doing a first person view .. needs to be configurable?
				is.pitch += is.orientationFactor * is.pitchSens * float32(t.YRel)
				if is.pitch > 90.0 {
					is.pitch = 90.0
				} else if ( is.pitch < -90.0 ) {
					is.pitch = -90.0
				}
				// build a quaternion of the current orientation
				var r ogre.Matrix3
				r.FromEulerAnglesYXZ( deg2Rad(is.yaw), deg2Rad(is.pitch), deg2Rad(is.roll))
				is.orientation.FromRotationMatrix(r)
			case *sdl.MouseButtonEvent:
				fmt.Printf("SDL mouse button event:\n")
			case *sdl.QuitEvent:
			    // push a shutdown on the control socket, game and render will pick it up later
				// NOTE: if the message patterns change we may still have to deal with hangs here
				sendShutdown(nnRenderSocket, nnGameSocket)
				shutdownRequested = true
			default:
				fmt.Printf("SDL_Event: %T\n", t);

			}
		}
		switch {
		// we are ready to process the request now
		case state.Mouse():
			buttons := sdl.GetMouseState(nil, nil)
			fmt.Printf("buttons: %d\n", buttons)
			s := capn.NewBuffer(nil)
			ms := NewRootInputMouse(s)
			ms.SetW(is.orientation.W())
			ms.SetX(is.orientation.X())
			ms.SetY(is.orientation.Y())
			ms.SetZ(is.orientation.Z())
			ms.SetButtons(buttons)
			buf := bytes.Buffer{}
			s.WriteTo(&buf)
			nnInputPub.Send(append([]byte("input.mouse:"), buf.Bytes()...), 0)
			fmt.Printf("Mouse input sent.\n")

		case state.Kb():
		// looking at a few hardcoded keys for now
		// NOTE: I suspect it would be perfectly safe to grab that pointer once, and read it from a different thread?
			state := sdl.GetKeyboardState()
			t := capn.NewBuffer(nil)
			kbs := NewRootInputKb(t)
			kbs.SetW(state[sdl.SCANCODE_W] != 0)
			kbs.SetA(state[sdl.SCANCODE_A] != 0)
			kbs.SetS(state[sdl.SCANCODE_S] != 0)
			kbs.SetD(state[sdl.SCANCODE_D] != 0)
			kbs.SetSpace(state[sdl.SCANCODE_SPACE] != 0)
			kbs.SetLalt(state[sdl.SCANCODE_LALT] != 0)
			b := bytes.Buffer{}
			t.WriteTo(&b)
			nnInputPub.Send(append([]byte("input.kb:"), b.Bytes()...), 0)
			fmt.Printf("Keyboard input sent.\n")

		case state.MouseReset():
			var q ogre.Quaternion;
			is.orientation = q.FromValues(state.Quaternion().W(), state.Quaternion().X(),
				state.Quaternion().Y(), state.Quaternion().Z())
			var r ogre.Matrix3
			is.orientation.ToRotationMatrix(&r)
			var rfYAngle, rfPAngle, rfRAngle float32
			r.ToEulerAnglesYXZ(&rfYAngle, &rfPAngle, &rfRAngle)
			is.yaw = rad2Deg(rfYAngle)
			is.pitch = rad2Deg(rfPAngle)
			is.roll = rad2Deg(rfRAngle)
		case state.ConfigLookAround():
			if state.LookAround().ManipulateObject() {
				fmt.Printf("Input configuration: manipulate object\n");
				is.orientationFactor = 1.0;
			} else {
				fmt.Printf("Input configuration: look around\n");
				is.orientationFactor = -1.0
			}
		}
	}
	if !shutdownRequested {
      sendShutdown(nnRenderSocket, nnGameSocket)
      shutdownRequested = true
    }
    waitShutdown(nnInputPull, &gameThreadParams)
}

func deg2Rad(deg float32) float32 {
	return deg * math.Pi / 180
}

func rad2Deg (rad float32) float32 {
	return rad * 180 / math.Pi
}

func sendShutdown(nnRenderSocket *nanomsg.Socket, nnGameSocket *nanomsg.Socket) {
	s := capn.NewBuffer(nil)
	stop := NewRootStop(s)
	stop.SetStop(true)
	buf := bytes.Buffer{}
	s.WriteTo(&buf)
	fmt.Printf("Render socket shutdown.\n")
	nnRenderSocket.Send(buf.Bytes(), 0)
	fmt.Printf("Game socket shutdown.\n")
	nnGameSocket.Send(buf.Bytes(), 0)
}

func waitShutdown(nnInputPull *nanomsg.Socket, params *GameThreadParams) {
	// For now, loop the input thread for a bit to flush out any events
	continueTime := time.Since(params.start) + 500 * time.Millisecond  // An eternity.
	for time.Since(params.start) < continueTime {
		msg, _ := nnInputPull.Recv(nanomsg.DontWait)
		if msg == nil {
			sdl.Delay(10)
		}
	}
}

func getSubsystemString(info sdl.SysWMInfo) string {
	switch info.Subsystem {
	case 0:
	    return "Unknown"
	case 1:
		return "Windows"
	case 2:
		return "X11"
	case 3:
		return "DirectFB"
	case 4:
		return "Cocoa"
	case 5:
		return "UiKit"
	}
	return "Unknown"
}
<|endoftext|>


<commit_before>
package core

import ("fmt"
	"os"
	"strconv"
	"github.com/jackyb/go-sdl2/sdl"
	"github.com/op/go-nanomsg"
	"github.com/fire/go-ogre3d"
	"github.com/ugorji/go/codec"
	"runtime")

type InputState struct {
	yawSens float32
	pitchSens float32
	orientationFactor float32 // +1/-1 easy switch between look around and manipulate something
	yaw float32 // degrees, modulo [-180,180] range
	pitch float32 // degrees, clamped [-90,90] range
	roll float32
	// orientation ogre.Quaternion // current orientation
}

func InitCore() {
	sdl.Init(sdl.INIT_EVERYTHING)
	window := sdl.CreateWindow("es_core::SDL",
		sdl.WINDOWPOS_UNDEFINED,
		sdl.WINDOWPOS_UNDEFINED,
		800,
		600,
		sdl.WINDOW_SHOWN)
	if window == nil {
		panic(fmt.Sprintf("sdl.CreateWindow failed: %s\n", sdl.GetError()))
	}
	defer sdl.Quit()
	var info sdl.SysWMInfo
	if !window.GetWMInfo(&info) {
		panic(fmt.Sprintf("window.GetWMInfo failed.\n"))
	}
	// Parse and print info's version
	// Parse and print info's SYSWM_TYPE
	root := ogre.NewRoot("", "", "ogre.log")
	defer root.Destroy()
	wd, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	if runtime.GOOS == "windows" {
	root.LoadPlugin(wd  + "/RenderSystem_GL")
		}
	if runtime.GOOS == "darwin" {
		root.LoadPlugin(wd  + "/../frameworks/RenderSystem_GL")
	}

	renderers := root.GetAvailableRenderers()
	if renderers.RenderSystemListSize() != 1 {

		panic(fmt.Sprintf("Failed to initalize RendererRenderSystem_GL"))
	}
	root.SetRenderSystem(renderers.RenderSystemListGet(0))
	root.Initialise(false, "es_core::ogre")
	params := ogre.CreateNameValuePairList()
	params.AddPair("macAPI", "cocoa")
	cocoaInfo := info.GetCocoaInfo()
	windowString := strconv.FormatUint(uint64(*(*uint32)(cocoaInfo.Window)), 10)
	params.AddPair("parentWindowHandle", windowString)

	renderWindow := root.CreateRenderWindow("es_core::ogre", 800, 600, false, params)
//	renderWindow.SetVisible(true)

	nnGameSocket, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.BUS)
        if err != nil {
                panic(err)
        }
        _, err = nnGameSocket.Bind("tcp://127.0.0.1:60206")
        if err != nil {
                panic(err)
        }

	nnRenderSocket, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.BUS)
	if err != nil {
                panic(err)
        }
        _, err = nnRenderSocket.Bind("tcp://127.0.0.1:60207")
        if err != nil {
                panic(err)
        }

	nnInputPub, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.PUB)
        if err != nil {
                panic(err)
        }
        _, err = nnInputPub.Bind("tcp://127.0.0.1:60208")
        if err != nil {
                panic(err)
        }

	nnInputPull, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.PULL)
        if err != nil {
                panic(err)
        }
        _, err = nnInputPull.Bind("tcp://127.0.0.1:60209")
        if err != nil {
                panic(err)
        }
	go gameThread()
	var renderThreadParams RenderThreadParams
	renderThreadParams.root = root
	renderThreadParams.window = window
	renderThreadParams.ogreWindow = renderWindow

	go renderThread(renderThreadParams)

	window.SetGrab(true)
	sdl.SetRelativeMouseMode(true)

	shutdownRequested := false
	var is InputState
	is.yawSens = 0.1
	is.yaw = 0.0
	is.pitchSens = 0.1
	is.pitch = 0.0
	is.roll = 0.0
	is.orientationFactor = -1.0 // Look around config

	// Msgpack
	var (
		v interface{} //Value to decode into
		mh codec.MsgpackHandle
	)

	for !shutdownRequested {
		var b []byte
		// We wait here.
		b, err = nnInputPull.Recv(0)
		fmt.Printf("Game push received:\n")
		if err != nil {
			fmt.Printf("%s\n", err)
		}
		dec := codec.NewDecoderBytes(b, &mh)
		err = dec.Decode(&v)
		if err != nil {
			fmt.Printf("%s\n", err)
		}

		// poll for events before processing the request
		// NOTE: this is how SDL builds the internal mouse and keyboard state
		// TODO: done this way does not meet the objectives of smooth, frame independent mouse view control,
		// Plus it throws some latency into the calling thread

		var event sdl.Event
		for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent {
			switch t := event.(type) {
			case *sdl.KeyDownEvent:
				fmt.Printf("SDL keyboard event:\n")
			case *sdl.KeyUpEvent:
				fmt.Printf("SDL keyboard event:\n")
				if t.Keysym.Scancode == sdl.SCANCODE_ESCAPE {
					// Todo
					sendShutdown(nnRenderSocket, nnGameSocket)
					shutdownRequested = true
				}
			}
		}
	}
}

func sendShutdown (nnRenderSocket *nanomsg.Socket, nnGameSocket *nanomsg.Socket) {
	fmt.Printf("Render socket shutdown.\n")
	fmt.Printf("Game socket shutdown.\n")
}
<commit_msg>Handle on Windows sdl and parentWindowHandle.<commit_after>
package core

import ("fmt"
	"os"
	"strconv"
	"github.com/jackyb/go-sdl2/sdl"
	"github.com/op/go-nanomsg"
	"github.com/fire/go-ogre3d"
	"github.com/ugorji/go/codec"
	"runtime")

type InputState struct {
	yawSens float32
	pitchSens float32
	orientationFactor float32 // +1/-1 easy switch between look around and manipulate something
	yaw float32 // degrees, modulo [-180,180] range
	pitch float32 // degrees, clamped [-90,90] range
	roll float32
	// orientation ogre.Quaternion // current orientation
}

func InitCore() {
	sdl.Init(sdl.INIT_EVERYTHING)
	window := sdl.CreateWindow("es_core::SDL",
		sdl.WINDOWPOS_UNDEFINED,
		sdl.WINDOWPOS_UNDEFINED,
		800,
		600,
		sdl.WINDOW_SHOWN)
	if window == nil {
		panic(fmt.Sprintf("sdl.CreateWindow failed: %s\n", sdl.GetError()))
	}
	defer sdl.Quit()
	var info sdl.SysWMInfo
	if !window.GetWMInfo(&info) {
		panic(fmt.Sprintf("window.GetWMInfo failed.\n"))
	}
	// Parse and print info's version
	// Parse and print info's SYSWM_TYPE
	root := ogre.NewRoot("", "", "ogre.log")
	defer root.Destroy()
	wd, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	if runtime.GOOS == "windows" {
		root.LoadPlugin(wd  + "/RenderSystem_GL")
		}
	if runtime.GOOS == "darwin" {
		root.LoadPlugin(wd  + "/../frameworks/RenderSystem_GL")
	}

	renderers := root.GetAvailableRenderers()
	if renderers.RenderSystemListSize() != 1 {

		panic(fmt.Sprintf("Failed to initalize RendererRenderSystem_GL"))
	}
	root.SetRenderSystem(renderers.RenderSystemListGet(0))
	root.Initialise(false, "es_core::ogre")
	params := ogre.CreateNameValuePairList()
	if runtime.GOOS == "windows" {
		windowsInfo := info.GetWindowsInfo()
		windowString := strconv.FormatUint(uint64(*(*uint32)(windowsInfo.Window)), 10)
		params.AddPair("parentWindowHandle", windowString)
	}
	if runtime.GOOS == "darwin" {
		params.AddPair("macAPI", "cocoa")
		cocoaInfo := info.GetCocoaInfo()
		windowString := strconv.FormatUint(uint64(*(*uint32)(cocoaInfo.Window)), 10)
		params.AddPair("parentWindowHandle", windowString)
	}

	renderWindow := root.CreateRenderWindow("es_core::ogre", 800, 600, false, params)
//	renderWindow.SetVisible(true)

	nnGameSocket, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.BUS)
        if err != nil {
                panic(err)
        }
        _, err = nnGameSocket.Bind("tcp://127.0.0.1:60206")
        if err != nil {
                panic(err)
        }

	nnRenderSocket, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.BUS)
	if err != nil {
                panic(err)
        }
        _, err = nnRenderSocket.Bind("tcp://127.0.0.1:60207")
        if err != nil {
                panic(err)
        }

	nnInputPub, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.PUB)
        if err != nil {
                panic(err)
        }
        _, err = nnInputPub.Bind("tcp://127.0.0.1:60208")
        if err != nil {
                panic(err)
        }

	nnInputPull, err := nanomsg.NewSocket(nanomsg.AF_SP, nanomsg.PULL)
        if err != nil {
                panic(err)
        }
        _, err = nnInputPull.Bind("tcp://127.0.0.1:60209")
        if err != nil {
                panic(err)
        }
	go gameThread()
	var renderThreadParams RenderThreadParams
	renderThreadParams.root = root
	renderThreadParams.window = window
	renderThreadParams.ogreWindow = renderWindow

	go renderThread(renderThreadParams)

	window.SetGrab(true)
	sdl.SetRelativeMouseMode(true)

	shutdownRequested := false
	var is InputState
	is.yawSens = 0.1
	is.yaw = 0.0
	is.pitchSens = 0.1
	is.pitch = 0.0
	is.roll = 0.0
	is.orientationFactor = -1.0 // Look around config

	// Msgpack
	var (
		v interface{} //Value to decode into
		mh codec.MsgpackHandle
	)

	for !shutdownRequested {
		var b []byte
		// We wait here.
		b, err = nnInputPull.Recv(0)
		fmt.Printf("Game push received:\n")
		if err != nil {
			fmt.Printf("%s\n", err)
		}
		dec := codec.NewDecoderBytes(b, &mh)
		err = dec.Decode(&v)
		if err != nil {
			fmt.Printf("%s\n", err)
		}

		// poll for events before processing the request
		// NOTE: this is how SDL builds the internal mouse and keyboard state
		// TODO: done this way does not meet the objectives of smooth, frame independent mouse view control,
		// Plus it throws some latency into the calling thread

		var event sdl.Event
		for event = sdl.PollEvent(); event != nil; event = sdl.PollEvent {
			switch t := event.(type) {
			case *sdl.KeyDownEvent:
				fmt.Printf("SDL keyboard event:\n")
			case *sdl.KeyUpEvent:
				fmt.Printf("SDL keyboard event:\n")
				if t.Keysym.Scancode == sdl.SCANCODE_ESCAPE {
					// Todo
					sendShutdown(nnRenderSocket, nnGameSocket)
					shutdownRequested = true
				}
			}
		}
	}
}

func sendShutdown (nnRenderSocket *nanomsg.Socket, nnGameSocket *nanomsg.Socket) {
	fmt.Printf("Render socket shutdown.\n")
	fmt.Printf("Game socket shutdown.\n")
}
<|endoftext|>


<commit_before><commit_msg>fix grammar in a comment<commit_after><|endoftext|>


<commit_before>package cf

import (
	"fmt"
	"io/ioutil"
	"os"

	ginkgoconfig "github.com/onsi/ginkgo/config"
	. "github.com/onsi/gomega"
	. "github.com/vito/cmdtest/matchers"
)

func AsUser(user UserContext, actions func()) {
	originalCfHomeDir := os.Getenv("CF_HOME")
	cfHomeDir, err := ioutil.TempDir("", fmt.Sprintf("cf_home_%d", ginkgoconfig.GinkgoConfig.ParallelNode))

	if err != nil {
		panic("Error: could not create temporary home directory: " + err.Error())
	}

	os.Setenv("CF_HOME", cfHomeDir)

	defer func() {
		Expect(Cf("logout")).To(ExitWith(0))
		os.Setenv("CF_HOME", originalCfHomeDir)
		os.RemoveAll(cfHomeDir)
	}()

	Expect(Cf("api", user.ApiUrl)).To(ExitWith(0))
	Expect(Cf("auth", user.Username, user.Password)).To(ExitWith(0))
	Expect(Cf("target", "-o", user.Org, "-s", user.Space)).To(ExitWith(0))

	actions()
}
<commit_msg>Decompose AsUser into public methods: InitiateUserContext and RestoreUserContext<commit_after>package cf

import (
	"fmt"
	"io/ioutil"
	"os"

	ginkgoconfig "github.com/onsi/ginkgo/config"
	. "github.com/onsi/gomega"
	. "github.com/vito/cmdtest/matchers"
)

func AsUser(userContext UserContext, actions func()) {
	originalCfHomeDir, currentCfHomeDir := InitiateUserContext(userContext)

	defer func() {
		RestoreUserContext(userContext, originalCfHomeDir, currentCfHomeDir)
	}()

	actions()
}

func InitiateUserContext(userContext UserContext) (originalCfHomeDir, currentCfHomeDir string) {
	originalCfHomeDir = os.Getenv("CF_HOME")
	currentCfHomeDir, err := ioutil.TempDir("", fmt.Sprintf("cf_home_%d", ginkgoconfig.GinkgoConfig.ParallelNode))

	if err != nil {
		panic("Error: could not create temporary home directory: " + err.Error())
	}

	os.Setenv("CF_HOME", currentCfHomeDir)

	Expect(Cf("api", userContext.ApiUrl)).To(ExitWith(0))
	Expect(Cf("auth", userContext.Username, userContext.Password)).To(ExitWith(0))
	Expect(Cf("target", "-o", userContext.Org, "-s", userContext.Space)).To(ExitWith(0))

	return
}

func RestoreUserContext(_ UserContext, originalCfHomeDir, currentCfHomeDir string) {
	Expect(Cf("logout")).To(ExitWith(0))
	os.Setenv("CF_HOME", originalCfHomeDir)
	os.RemoveAll(currentCfHomeDir)
}
<|endoftext|>


<commit_before>package cgo

import (
	"fmt"
	"go/ast"
	"go/token"
	"go/types"
	"regexp"
	"strings"
)

var (
	constructorName = regexp.MustCompile(`^New([A-Z]\w+)`)
)

// Struct is a helpful facade over types.Named which is intended to only contain a struct
type Struct struct {
	*Named
}

func NewStruct(named *types.Named) *Struct {
	if _, ok := named.Underlying().(*types.Struct); !ok {
		panic("only structs belong in structs")
	}
	return &Struct{NewNamed(named)}
}

// Struct returns the underlying struct
func (s Struct) Struct() *types.Struct {
	if _, ok := s.Named.Underlying().(*types.Struct); !ok {
		fmt.Println(s.Named)
	}
	return s.Named.Underlying().(*types.Struct)
}

// ToAst returns the go/ast representation of the CGo wrapper of the Array type
func (s Struct) ToAst() []ast.Decl {
	decls := []ast.Decl{s.NewAst(), s.StringAst()}
	decls = append(decls, s.FieldAccessorsAst()...)
	decls = append(decls, s.MethodAsts()...)
	return decls
}

func (s Struct) FieldAccessorsAst() []ast.Decl {
	var accessors []ast.Decl
	for i := 0; i < s.Struct().NumFields(); i++ {
		field := s.Struct().Field(i)
		if ShouldGenerateField(field) {
			accessors = append(accessors, s.Getter(field), s.Setter(field))
		}
	}

	return accessors
}

func (s Struct) Getter(field *types.Var) ast.Decl {
	functionName := s.FieldName(field) + "_get"
	selfIdent := NewIdent("self")
	localVarIdent := NewIdent("value")
	fieldIdent := NewIdent(field.Name())
	castExpression := CastUnsafePtrOfTypeUuid(DeRef(s.CTypeName()), selfIdent)

	assignment := &ast.AssignStmt{
		Lhs: []ast.Expr{localVarIdent},
		Tok: token.DEFINE,
		Rhs: []ast.Expr{
			&ast.SelectorExpr{
				X:   castExpression,
				Sel: fieldIdent,
			},
		},
	}

	funcDecl := &ast.FuncDecl{
		Doc: &ast.CommentGroup{
			List: ExportComments(functionName),
		},
		Name: NewIdent(functionName),
		Type: &ast.FuncType{
			Params: InstanceMethodParams(),
			Results: &ast.FieldList{
				List: []*ast.Field{{Type: TypeToArgumentTypeExpr(field.Type())}},
			},
		},
		Body: &ast.BlockStmt{
			List: []ast.Stmt{
				assignment,
				Return(CastOut(field.Type(), localVarIdent)),
			},
		},
	}

	return funcDecl
}

func (s Struct) Setter(field *types.Var) ast.Decl {
	functionName := s.FieldName(field) + "_set"
	selfIdent := NewIdent("self")
	localVarIdent := NewIdent("value")
	transformedLocalVarIdent := NewIdent("val")
	fieldIdent := NewIdent(field.Name())
	castExpression := CastUnsafePtrOfTypeUuid(DeRef(s.CTypeName()), selfIdent)
	typedField := UnsafePtrOrBasic(field, field.Type())
	typedField.Names = []*ast.Ident{localVarIdent}
	params := InstanceMethodParams(typedField)
	firstAssignmentCastRhs := CastExpr(field.Type(), localVarIdent)
	secondAssignment := ast.Expr(transformedLocalVarIdent)

	if isStringPointer(field.Type()) {
		strPtrCast := CastExpr(field.Type(), localVarIdent).(*ast.UnaryExpr)
		firstAssignmentCastRhs = strPtrCast.X
		secondAssignment = Ref(transformedLocalVarIdent)
	}

	funcDecl := &ast.FuncDecl{
		Doc: &ast.CommentGroup{
			List: ExportComments(functionName),
		},
		Name: NewIdent(functionName),
		Type: &ast.FuncType{
			Params: params,
		},
		Body: &ast.BlockStmt{
			List: []ast.Stmt{
				&ast.AssignStmt{
					Lhs: []ast.Expr{transformedLocalVarIdent},
					Tok: token.DEFINE,
					Rhs: []ast.Expr{firstAssignmentCastRhs},
				},
				&ast.AssignStmt{
					Lhs: []ast.Expr{
						&ast.SelectorExpr{
							X:   castExpression,
							Sel: fieldIdent,
						},
					},
					Tok: token.ASSIGN,
					Rhs: []ast.Expr{secondAssignment},
				},
			},
		},
	}

	return funcDecl
}

func (s Struct) FieldName(field *types.Var) string {
	return s.CName() + "_" + field.Name()
}

func (s Struct) IsConstructor(f *Func) bool {
	matches := constructorName.FindStringSubmatch(f.Name())
	if len(matches) > 1 && strings.HasPrefix(matches[1], s.Obj().Name()) {
		return true
	}
	return false
}

func (s Struct) ConstructorName(f *Func) string {
	return strings.Replace(f.Name(), s.Obj().Name(), "", 1)
}

func isStringPointer(t types.Type) bool {
	if ptr, ok := t.(*types.Pointer); ok {
		if basic, okB := ptr.Elem().(*types.Basic); okB && basic.Kind() == types.String {
			return true
		}
	}
	return false
}
<commit_msg>clean up struct<commit_after>package cgo

import (
	"go/ast"
	"go/token"
	"go/types"
	"regexp"
	"strings"
)

var (
	constructorName = regexp.MustCompile(`^New([A-Z]\w+)`)
)

// Struct is a helpful facade over types.Named which is intended to only contain a struct
type Struct struct {
	*Named
}

func NewStruct(named *types.Named) *Struct {
	if _, ok := named.Underlying().(*types.Struct); !ok {
		panic("only structs belong in structs")
	}
	return &Struct{NewNamed(named)}
}

// Struct returns the underlying struct
func (s Struct) Struct() *types.Struct {
	return s.Underlying().(*types.Struct)
}

// ToAst returns the go/ast representation of the CGo wrapper of the Array type
func (s Struct) ToAst() []ast.Decl {
	decls := []ast.Decl{s.NewAst(), s.StringAst()}
	decls = append(decls, s.FieldAccessorsAst()...)
	decls = append(decls, s.MethodAsts()...)
	return decls
}

func (s Struct) FieldAccessorsAst() []ast.Decl {
	var accessors []ast.Decl
	for i := 0; i < s.Struct().NumFields(); i++ {
		field := s.Struct().Field(i)
		if ShouldGenerateField(field) {
			accessors = append(accessors, s.Getter(field), s.Setter(field))
		}
	}

	return accessors
}

func (s Struct) Getter(field *types.Var) ast.Decl {
	functionName := s.FieldName(field) + "_get"
	selfIdent := NewIdent("self")
	localVarIdent := NewIdent("value")
	fieldIdent := NewIdent(field.Name())
	castExpression := CastUnsafePtrOfTypeUuid(DeRef(s.CTypeName()), selfIdent)

	assignment := &ast.AssignStmt{
		Lhs: []ast.Expr{localVarIdent},
		Tok: token.DEFINE,
		Rhs: []ast.Expr{
			&ast.SelectorExpr{
				X:   castExpression,
				Sel: fieldIdent,
			},
		},
	}

	funcDecl := &ast.FuncDecl{
		Doc: &ast.CommentGroup{
			List: ExportComments(functionName),
		},
		Name: NewIdent(functionName),
		Type: &ast.FuncType{
			Params: InstanceMethodParams(),
			Results: &ast.FieldList{
				List: []*ast.Field{{Type: TypeToArgumentTypeExpr(field.Type())}},
			},
		},
		Body: &ast.BlockStmt{
			List: []ast.Stmt{
				assignment,
				Return(CastOut(field.Type(), localVarIdent)),
			},
		},
	}

	return funcDecl
}

func (s Struct) Setter(field *types.Var) ast.Decl {
	functionName := s.FieldName(field) + "_set"
	selfIdent := NewIdent("self")
	localVarIdent := NewIdent("value")
	transformedLocalVarIdent := NewIdent("val")
	fieldIdent := NewIdent(field.Name())
	castExpression := CastUnsafePtrOfTypeUuid(DeRef(s.CTypeName()), selfIdent)
	typedField := UnsafePtrOrBasic(field, field.Type())
	typedField.Names = []*ast.Ident{localVarIdent}
	params := InstanceMethodParams(typedField)
	firstAssignmentCastRhs := CastExpr(field.Type(), localVarIdent)
	secondAssignment := ast.Expr(transformedLocalVarIdent)

	if isStringPointer(field.Type()) {
		strPtrCast := CastExpr(field.Type(), localVarIdent).(*ast.UnaryExpr)
		firstAssignmentCastRhs = strPtrCast.X
		secondAssignment = Ref(transformedLocalVarIdent)
	}

	funcDecl := &ast.FuncDecl{
		Doc: &ast.CommentGroup{
			List: ExportComments(functionName),
		},
		Name: NewIdent(functionName),
		Type: &ast.FuncType{
			Params: params,
		},
		Body: &ast.BlockStmt{
			List: []ast.Stmt{
				&ast.AssignStmt{
					Lhs: []ast.Expr{transformedLocalVarIdent},
					Tok: token.DEFINE,
					Rhs: []ast.Expr{firstAssignmentCastRhs},
				},
				&ast.AssignStmt{
					Lhs: []ast.Expr{
						&ast.SelectorExpr{
							X:   castExpression,
							Sel: fieldIdent,
						},
					},
					Tok: token.ASSIGN,
					Rhs: []ast.Expr{secondAssignment},
				},
			},
		},
	}

	return funcDecl
}

func (s Struct) FieldName(field *types.Var) string {
	return s.CName() + "_" + field.Name()
}

func (s Struct) IsConstructor(f *Func) bool {
	matches := constructorName.FindStringSubmatch(f.Name())
	if len(matches) > 1 && strings.HasPrefix(matches[1], s.Obj().Name()) {
		return true
	}
	return false
}

func (s Struct) ConstructorName(f *Func) string {
	return strings.Replace(f.Name(), s.Obj().Name(), "", 1)
}

func isStringPointer(t types.Type) bool {
	if ptr, ok := t.(*types.Pointer); ok {
		if basic, okB := ptr.Elem().(*types.Basic); okB && basic.Kind() == types.String {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>// Copyright 2016 Michal Witkowski. All Rights Reserved.
// See LICENSE for licensing terms.

package grpc_middleware

import (
	"context"
	"fmt"
	"testing"

	"github.com/stretchr/testify/require"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
)

var (
	someServiceName  = "SomeService.StreamMethod"
	parentUnaryInfo  = &grpc.UnaryServerInfo{FullMethod: someServiceName}
	parentStreamInfo = &grpc.StreamServerInfo{
		FullMethod:     someServiceName,
		IsServerStream: true,
	}
	someValue     = 1
	parentContext = context.WithValue(context.TODO(), "parent", someValue)
)

func TestChainUnaryServer(t *testing.T) {
	input := "input"
	output := "output"

	first := func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
		requireContextValue(t, ctx, "parent", "first interceptor must know the parent context value")
		require.Equal(t, parentUnaryInfo, info, "first interceptor must know the someUnaryServerInfo")
		ctx = context.WithValue(ctx, "first", 1)
		return handler(ctx, req)
	}
	second := func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
		requireContextValue(t, ctx, "parent", "second interceptor must know the parent context value")
		requireContextValue(t, ctx, "first", "second interceptor must know the first context value")
		require.Equal(t, parentUnaryInfo, info, "second interceptor must know the someUnaryServerInfo")
		ctx = context.WithValue(ctx, "second", 1)
		return handler(ctx, req)
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		require.EqualValues(t, input, req, "handler must get the input")
		requireContextValue(t, ctx, "parent", "handler must know the parent context value")
		requireContextValue(t, ctx, "first", "handler must know the first context value")
		requireContextValue(t, ctx, "second", "handler must know the second context value")
		return output, nil
	}

	chain := ChainUnaryServer(first, second)
	out, _ := chain(parentContext, input, parentUnaryInfo, handler)
	require.EqualValues(t, output, out, "chain must return handler's output")
}

func TestChainStreamServer(t *testing.T) {
	someService := &struct{}{}
	recvMessage := "received"
	sentMessage := "sent"
	outputError := fmt.Errorf("some error")

	first := func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
		requireContextValue(t, stream.Context(), "parent", "first interceptor must know the parent context value")
		require.Equal(t, parentStreamInfo, info, "first interceptor must know the parentStreamInfo")
		require.Equal(t, someService, srv, "first interceptor must know someService")
		wrapped := WrapServerStream(stream)
		wrapped.WrappedContext = context.WithValue(stream.Context(), "first", 1)
		return handler(srv, wrapped)
	}
	second := func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
		requireContextValue(t, stream.Context(), "parent", "second interceptor must know the parent context value")
		requireContextValue(t, stream.Context(), "parent", "second interceptor must know the first context value")
		require.Equal(t, parentStreamInfo, info, "second interceptor must know the parentStreamInfo")
		require.Equal(t, someService, srv, "second interceptor must know someService")
		wrapped := WrapServerStream(stream)
		wrapped.WrappedContext = context.WithValue(stream.Context(), "second", 1)
		return handler(srv, wrapped)
	}
	handler := func(srv interface{}, stream grpc.ServerStream) error {
		require.Equal(t, someService, srv, "handler must know someService")
		requireContextValue(t, stream.Context(), "parent", "handler must know the parent context value")
		requireContextValue(t, stream.Context(), "first", "handler must know the first context value")
		requireContextValue(t, stream.Context(), "second", "handler must know the second context value")
		require.NoError(t, stream.RecvMsg(recvMessage), "handler must have access to stream messages")
		require.NoError(t, stream.SendMsg(sentMessage), "handler must be able to send stream messages")
		return outputError
	}
	fakeStream := &fakeServerStream{ctx: parentContext, recvMessage: recvMessage}
	chain := ChainStreamServer(first, second)
	err := chain(someService, fakeStream, parentStreamInfo, handler)
	require.Equal(t, outputError, err, "chain must return handler's error")
	require.Equal(t, sentMessage, fakeStream.sentMessage, "handler's sent message must propagate to stream")
}

func TestChainUnaryClient(t *testing.T) {
	ignoredMd := metadata.Pairs("foo", "bar")
	parentOpts := []grpc.CallOption{grpc.Header(&ignoredMd)}
	reqMessage := "request"
	replyMessage := "reply"
	outputError := fmt.Errorf("some error")

	first := func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
		requireContextValue(t, ctx, "parent", "first must know the parent context value")
		require.Equal(t, someServiceName, method, "first must know someService")
		require.Len(t, opts, 1, "first should see parent CallOptions")
		wrappedCtx := context.WithValue(ctx, "first", 1)
		return invoker(wrappedCtx, method, req, reply, cc, opts...)
	}
	second := func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
		requireContextValue(t, ctx, "parent", "second must know the parent context value")
		require.Equal(t, someServiceName, method, "second must know someService")
		require.Len(t, opts, 1, "second should see parent CallOptions")
		wrappedOpts := append(opts, grpc.WaitForReady(false))
		wrappedCtx := context.WithValue(ctx, "second", 1)
		return invoker(wrappedCtx, method, req, reply, cc, wrappedOpts...)
	}
	invoker := func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, opts ...grpc.CallOption) error {
		require.Equal(t, someServiceName, method, "invoker must know someService")
		requireContextValue(t, ctx, "parent", "invoker must know the parent context value")
		requireContextValue(t, ctx, "first", "invoker must know the first context value")
		requireContextValue(t, ctx, "second", "invoker must know the second context value")
		require.Len(t, opts, 2, "invoker should see both CallOpts from second and parent")
		return outputError
	}
	chain := ChainUnaryClient(first, second)
	err := chain(parentContext, someServiceName, reqMessage, replyMessage, nil, invoker, parentOpts...)
	require.Equal(t, outputError, err, "chain must return invokers's error")
}

func TestChainStreamClient(t *testing.T) {
	ignoredMd := metadata.Pairs("foo", "bar")
	parentOpts := []grpc.CallOption{grpc.Header(&ignoredMd)}
	clientStream := &fakeClientStream{}
	fakeStreamDesc := &grpc.StreamDesc{ClientStreams: true, ServerStreams: true, StreamName: someServiceName}

	first := func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
		requireContextValue(t, ctx, "parent", "first must know the parent context value")
		require.Equal(t, someServiceName, method, "first must know someService")
		require.Len(t, opts, 1, "first should see parent CallOptions")
		wrappedCtx := context.WithValue(ctx, "first", 1)
		return streamer(wrappedCtx, desc, cc, method, opts...)
	}
	second := func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
		requireContextValue(t, ctx, "parent", "second must know the parent context value")
		require.Equal(t, someServiceName, method, "second must know someService")
		require.Len(t, opts, 1, "second should see parent CallOptions")
		wrappedOpts := append(opts, grpc.WaitForReady(false))
		wrappedCtx := context.WithValue(ctx, "second", 1)
		return streamer(wrappedCtx, desc, cc, method, wrappedOpts...)
	}
	streamer := func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, opts ...grpc.CallOption) (grpc.ClientStream, error) {
		require.Equal(t, someServiceName, method, "streamer must know someService")
		require.Equal(t, fakeStreamDesc, desc, "streamer must see the right StreamDesc")

		requireContextValue(t, ctx, "parent", "streamer must know the parent context value")
		requireContextValue(t, ctx, "first", "streamer must know the first context value")
		requireContextValue(t, ctx, "second", "streamer must know the second context value")
		require.Len(t, opts, 2, "streamer should see both CallOpts from second and parent")
		return clientStream, nil
	}
	chain := ChainStreamClient(first, second)
	someStream, err := chain(parentContext, fakeStreamDesc, nil, someServiceName, streamer, parentOpts...)
	require.NoError(t, err, "chain must not return an error")
	require.Equal(t, clientStream, someStream, "chain must return invokers's clientstream")
}

func requireContextValue(t *testing.T, ctx context.Context, key string, msg ...interface{}) {
	val := ctx.Value(key)
	require.NotNil(t, val, msg...)
	require.Equal(t, someValue, val, msg...)
}
<commit_msg>Chain tests: add missing checks and fix typos (#359)<commit_after>// Copyright 2016 Michal Witkowski. All Rights Reserved.
// See LICENSE for licensing terms.

package grpc_middleware

import (
	"context"
	"fmt"
	"testing"

	"github.com/stretchr/testify/require"
	"google.golang.org/grpc"
	"google.golang.org/grpc/metadata"
)

var (
	someServiceName  = "SomeService.StreamMethod"
	parentUnaryInfo  = &grpc.UnaryServerInfo{FullMethod: someServiceName}
	parentStreamInfo = &grpc.StreamServerInfo{
		FullMethod:     someServiceName,
		IsServerStream: true,
	}
	someValue     = 1
	parentContext = context.WithValue(context.TODO(), "parent", someValue)
)

func TestChainUnaryServer(t *testing.T) {
	input := "input"
	output := "output"

	first := func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
		requireContextValue(t, ctx, "parent", "first interceptor must know the parent context value")
		require.Equal(t, parentUnaryInfo, info, "first interceptor must know the someUnaryServerInfo")
		ctx = context.WithValue(ctx, "first", 1)
		return handler(ctx, req)
	}
	second := func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
		requireContextValue(t, ctx, "parent", "second interceptor must know the parent context value")
		requireContextValue(t, ctx, "first", "second interceptor must know the first context value")
		require.Equal(t, parentUnaryInfo, info, "second interceptor must know the someUnaryServerInfo")
		ctx = context.WithValue(ctx, "second", 1)
		return handler(ctx, req)
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		require.EqualValues(t, input, req, "handler must get the input")
		requireContextValue(t, ctx, "parent", "handler must know the parent context value")
		requireContextValue(t, ctx, "first", "handler must know the first context value")
		requireContextValue(t, ctx, "second", "handler must know the second context value")
		return output, nil
	}

	chain := ChainUnaryServer(first, second)
	out, _ := chain(parentContext, input, parentUnaryInfo, handler)
	require.EqualValues(t, output, out, "chain must return handler's output")
}

func TestChainStreamServer(t *testing.T) {
	someService := &struct{}{}
	recvMessage := "received"
	sentMessage := "sent"
	outputError := fmt.Errorf("some error")

	first := func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
		requireContextValue(t, stream.Context(), "parent", "first interceptor must know the parent context value")
		require.Equal(t, parentStreamInfo, info, "first interceptor must know the parentStreamInfo")
		require.Equal(t, someService, srv, "first interceptor must know someService")
		wrapped := WrapServerStream(stream)
		wrapped.WrappedContext = context.WithValue(stream.Context(), "first", 1)
		return handler(srv, wrapped)
	}
	second := func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
		requireContextValue(t, stream.Context(), "parent", "second interceptor must know the parent context value")
		requireContextValue(t, stream.Context(), "first", "second interceptor must know the first context value")
		require.Equal(t, parentStreamInfo, info, "second interceptor must know the parentStreamInfo")
		require.Equal(t, someService, srv, "second interceptor must know someService")
		wrapped := WrapServerStream(stream)
		wrapped.WrappedContext = context.WithValue(stream.Context(), "second", 1)
		return handler(srv, wrapped)
	}
	handler := func(srv interface{}, stream grpc.ServerStream) error {
		require.Equal(t, someService, srv, "handler must know someService")
		requireContextValue(t, stream.Context(), "parent", "handler must know the parent context value")
		requireContextValue(t, stream.Context(), "first", "handler must know the first context value")
		requireContextValue(t, stream.Context(), "second", "handler must know the second context value")
		require.NoError(t, stream.RecvMsg(recvMessage), "handler must have access to stream messages")
		require.NoError(t, stream.SendMsg(sentMessage), "handler must be able to send stream messages")
		return outputError
	}
	fakeStream := &fakeServerStream{ctx: parentContext, recvMessage: recvMessage}
	chain := ChainStreamServer(first, second)
	err := chain(someService, fakeStream, parentStreamInfo, handler)
	require.Equal(t, outputError, err, "chain must return handler's error")
	require.Equal(t, sentMessage, fakeStream.sentMessage, "handler's sent message must propagate to stream")
}

func TestChainUnaryClient(t *testing.T) {
	ignoredMd := metadata.Pairs("foo", "bar")
	parentOpts := []grpc.CallOption{grpc.Header(&ignoredMd)}
	reqMessage := "request"
	replyMessage := "reply"
	outputError := fmt.Errorf("some error")

	first := func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
		requireContextValue(t, ctx, "parent", "first must know the parent context value")
		require.Equal(t, someServiceName, method, "first must know someService")
		require.Len(t, opts, 1, "first should see parent CallOptions")
		wrappedCtx := context.WithValue(ctx, "first", 1)
		return invoker(wrappedCtx, method, req, reply, cc, opts...)
	}
	second := func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
		requireContextValue(t, ctx, "parent", "second must know the parent context value")
		requireContextValue(t, ctx, "first", "second must know the first context value")
		require.Equal(t, someServiceName, method, "second must know someService")
		require.Len(t, opts, 1, "second should see parent CallOptions")
		wrappedOpts := append(opts, grpc.WaitForReady(false))
		wrappedCtx := context.WithValue(ctx, "second", 1)
		return invoker(wrappedCtx, method, req, reply, cc, wrappedOpts...)
	}
	invoker := func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, opts ...grpc.CallOption) error {
		require.Equal(t, someServiceName, method, "invoker must know someService")
		requireContextValue(t, ctx, "parent", "invoker must know the parent context value")
		requireContextValue(t, ctx, "first", "invoker must know the first context value")
		requireContextValue(t, ctx, "second", "invoker must know the second context value")
		require.Len(t, opts, 2, "invoker should see both CallOpts from second and parent")
		return outputError
	}
	chain := ChainUnaryClient(first, second)
	err := chain(parentContext, someServiceName, reqMessage, replyMessage, nil, invoker, parentOpts...)
	require.Equal(t, outputError, err, "chain must return invokers's error")
}

func TestChainStreamClient(t *testing.T) {
	ignoredMd := metadata.Pairs("foo", "bar")
	parentOpts := []grpc.CallOption{grpc.Header(&ignoredMd)}
	clientStream := &fakeClientStream{}
	fakeStreamDesc := &grpc.StreamDesc{ClientStreams: true, ServerStreams: true, StreamName: someServiceName}

	first := func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
		requireContextValue(t, ctx, "parent", "first must know the parent context value")
		require.Equal(t, someServiceName, method, "first must know someService")
		require.Len(t, opts, 1, "first should see parent CallOptions")
		wrappedCtx := context.WithValue(ctx, "first", 1)
		return streamer(wrappedCtx, desc, cc, method, opts...)
	}
	second := func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
		requireContextValue(t, ctx, "parent", "second must know the parent context value")
		requireContextValue(t, ctx, "first", "second must know the first context value")
		require.Equal(t, someServiceName, method, "second must know someService")
		require.Len(t, opts, 1, "second should see parent CallOptions")
		wrappedOpts := append(opts, grpc.WaitForReady(false))
		wrappedCtx := context.WithValue(ctx, "second", 1)
		return streamer(wrappedCtx, desc, cc, method, wrappedOpts...)
	}
	streamer := func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, opts ...grpc.CallOption) (grpc.ClientStream, error) {
		require.Equal(t, someServiceName, method, "streamer must know someService")
		require.Equal(t, fakeStreamDesc, desc, "streamer must see the right StreamDesc")

		requireContextValue(t, ctx, "parent", "streamer must know the parent context value")
		requireContextValue(t, ctx, "first", "streamer must know the first context value")
		requireContextValue(t, ctx, "second", "streamer must know the second context value")
		require.Len(t, opts, 2, "streamer should see both CallOpts from second and parent")
		return clientStream, nil
	}
	chain := ChainStreamClient(first, second)
	someStream, err := chain(parentContext, fakeStreamDesc, nil, someServiceName, streamer, parentOpts...)
	require.NoError(t, err, "chain must not return an error")
	require.Equal(t, clientStream, someStream, "chain must return invokers's clientstream")
}

func requireContextValue(t *testing.T, ctx context.Context, key string, msg ...interface{}) {
	val := ctx.Value(key)
	require.NotNil(t, val, msg...)
	require.Equal(t, someValue, val, msg...)
}
<|endoftext|>


<commit_before>package violetear

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

func TestResponseWriterStatus(t *testing.T) {
	rec := httptest.NewRecorder()
	rw := NewResponseWriter(rec, "")

	expect(t, rw.Status(), 200)

	rw.Write([]byte(""))
	expect(t, rw.Status(), http.StatusOK)
	expect(t, rw.Size(), 0)
}

func TestResponseWriterSize(t *testing.T) {
	rec := httptest.NewRecorder()
	rw := NewResponseWriter(rec, "")

	rw.Write([]byte("日本語"))
	expect(t, rw.Size(), 9)

	rw.Write([]byte("a"))
	expect(t, rw.Size(), 10)
}

func TestResponseWriterHeader(t *testing.T) {
	rec := httptest.NewRecorder()
	rw := NewResponseWriter(rec, "")

	expect(t, len(rec.Header()), len(rw.Header()))
}

func TestResponseWriterWrite(t *testing.T) {
	rec := httptest.NewRecorder()
	rw := NewResponseWriter(rec, "")

	rw.Write([]byte("Hello world"))
	rw.Write([]byte(". !"))

	expect(t, rec.Code, rw.Status())
	expect(t, rec.Body.String(), "Hello world. !")
	expect(t, rw.Status(), http.StatusOK)
	expect(t, rw.Size(), 14)
}

func TestResponseWriterWriteHeader(t *testing.T) {
	rec := httptest.NewRecorder()
	rw := NewResponseWriter(rec, "")

	rw.WriteHeader(http.StatusNotFound)

	expect(t, rec.Code, rw.Status())
	expect(t, rw.Status(), 404)
	expect(t, rec.Body.String(), "")
	expect(t, rw.Status(), http.StatusNotFound)
	expect(t, rw.Size(), 0)
}

func TestResponseWriterLogger(t *testing.T) {
	mylogger := func(w *ResponseWriter, r *http.Request) {
		expect(t, r.URL.String(), "/test")
		expect(t, w.RequestID(), "123")
		expect(t, w.Size(), 11)
		expect(t, w.Status(), 200)
	}
	router := New()
	router.LogRequests = true
	router.RequestID = "rid"
	router.Logger = mylogger
	router.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
		expect(t, w.Header().Get("rid"), "123")
		w.Write([]byte("hello world"))
	})
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/test", nil)
	req.Header.Set("rid", "123")
	router.ServeHTTP(w, req)
	expect(t, w.Code, 200)
	expect(t, w.HeaderMap.Get("rid"), "123")
}

func TestResponseWriterLoggerStatus200(t *testing.T) {
	mylogger := func(w *ResponseWriter, r *http.Request) {
		expect(t, r.URL.String(), "/test")
		expect(t, w.RequestID(), "123")
		expect(t, w.Size(), 0)
		expect(t, w.Status(), 200)
	}
	router := New()
	router.LogRequests = true
	router.RequestID = "rid"
	router.Logger = mylogger
	router.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
		expect(t, w.Header().Get("rid"), "123")
	})
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/test", nil)
	req.Header.Set("rid", "123")
	router.ServeHTTP(w, req)
	expect(t, w.Code, 200)
	expect(t, w.HeaderMap.Get("rid"), "123")
}

func TestResponseWriterLoggerStatus405(t *testing.T) {
	mylogger := func(w *ResponseWriter, r *http.Request) {
		expect(t, r.URL.String(), "/test")
		expect(t, w.RequestID(), "123")
		expect(t, w.Status(), 405)
	}
	router := New()
	router.LogRequests = true
	router.RequestID = "rid"
	router.Logger = mylogger
	router.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
		expect(t, w.Header().Get("rid"), "123")
	}, "POST")
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/test", nil)
	req.Header.Set("rid", "123")
	router.ServeHTTP(w, req)
	expect(t, w.Code, 405)
	expect(t, w.HeaderMap.Get("rid"), "123")
}

func TestResponseWriterNoLogger(t *testing.T) {
	router := New()
	router.LogRequests = false
	router.RequestID = "rid"
	router.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
		expect(t, w.Header().Get("rid"), "123")
	})
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/test", nil)
	req.Header.Set("rid", "123")
	router.ServeHTTP(w, req)
	expect(t, w.Code, 200)
	expect(t, w.HeaderMap.Get("rid"), "123")
}

func TestResponseWriterNoLogger405(t *testing.T) {
	router := New()
	router.LogRequests = false
	router.RequestID = "rid"
	router.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
		expect(t, w.Header().Get("rid"), "123")
	}, "POST")
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/test", nil)
	req.Header.Set("rid", "123")
	router.ServeHTTP(w, req)
	expect(t, w.Code, 405)
	expect(t, w.HeaderMap.Get("rid"), "123")
}

func TestResponseWriterLogger499(t *testing.T) {
	// TODO
}
<commit_msg>test 499<commit_after>package violetear

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

func TestResponseWriterStatus(t *testing.T) {
	rec := httptest.NewRecorder()
	rw := NewResponseWriter(rec, "")

	expect(t, rw.Status(), 200)

	rw.Write([]byte(""))
	expect(t, rw.Status(), http.StatusOK)
	expect(t, rw.Size(), 0)
}

func TestResponseWriterSize(t *testing.T) {
	rec := httptest.NewRecorder()
	rw := NewResponseWriter(rec, "")

	rw.Write([]byte("日本語"))
	expect(t, rw.Size(), 9)

	rw.Write([]byte("a"))
	expect(t, rw.Size(), 10)
}

func TestResponseWriterHeader(t *testing.T) {
	rec := httptest.NewRecorder()
	rw := NewResponseWriter(rec, "")

	expect(t, len(rec.Header()), len(rw.Header()))
}

func TestResponseWriterWrite(t *testing.T) {
	rec := httptest.NewRecorder()
	rw := NewResponseWriter(rec, "")

	rw.Write([]byte("Hello world"))
	rw.Write([]byte(". !"))

	expect(t, rec.Code, rw.Status())
	expect(t, rec.Body.String(), "Hello world. !")
	expect(t, rw.Status(), http.StatusOK)
	expect(t, rw.Size(), 14)
}

func TestResponseWriterWriteHeader(t *testing.T) {
	rec := httptest.NewRecorder()
	rw := NewResponseWriter(rec, "")

	rw.WriteHeader(http.StatusNotFound)

	expect(t, rec.Code, rw.Status())
	expect(t, rw.Status(), 404)
	expect(t, rec.Body.String(), "")
	expect(t, rw.Status(), http.StatusNotFound)
	expect(t, rw.Size(), 0)
}

func TestResponseWriterLogger(t *testing.T) {
	mylogger := func(w *ResponseWriter, r *http.Request) {
		expect(t, r.URL.String(), "/test")
		expect(t, w.RequestID(), "123")
		expect(t, w.Size(), 11)
		expect(t, w.Status(), 200)
	}
	router := New()
	router.LogRequests = true
	router.RequestID = "rid"
	router.Logger = mylogger
	router.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
		expect(t, w.Header().Get("rid"), "123")
		w.Write([]byte("hello world"))
	})
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/test", nil)
	req.Header.Set("rid", "123")
	router.ServeHTTP(w, req)
	expect(t, w.Code, 200)
	expect(t, w.HeaderMap.Get("rid"), "123")
}

func TestResponseWriterLoggerStatus200(t *testing.T) {
	mylogger := func(w *ResponseWriter, r *http.Request) {
		expect(t, r.URL.String(), "/test")
		expect(t, w.RequestID(), "123")
		expect(t, w.Size(), 0)
		expect(t, w.Status(), 200)
	}
	router := New()
	router.LogRequests = true
	router.RequestID = "rid"
	router.Logger = mylogger
	router.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
		expect(t, w.Header().Get("rid"), "123")
	})
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/test", nil)
	req.Header.Set("rid", "123")
	router.ServeHTTP(w, req)
	expect(t, w.Code, 200)
	expect(t, w.HeaderMap.Get("rid"), "123")
}

func TestResponseWriterLoggerStatus405(t *testing.T) {
	mylogger := func(w *ResponseWriter, r *http.Request) {
		expect(t, r.URL.String(), "/test")
		expect(t, w.RequestID(), "123")
		expect(t, w.Status(), 405)
	}
	router := New()
	router.LogRequests = true
	router.RequestID = "rid"
	router.Logger = mylogger
	router.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
		expect(t, w.Header().Get("rid"), "123")
	}, "POST")
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/test", nil)
	req.Header.Set("rid", "123")
	router.ServeHTTP(w, req)
	expect(t, w.Code, 405)
	expect(t, w.HeaderMap.Get("rid"), "123")
}

func TestResponseWriterNoLogger(t *testing.T) {
	router := New()
	router.LogRequests = false
	router.RequestID = "rid"
	router.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
		expect(t, w.Header().Get("rid"), "123")
	})
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/test", nil)
	req.Header.Set("rid", "123")
	router.ServeHTTP(w, req)
	expect(t, w.Code, 200)
	expect(t, w.HeaderMap.Get("rid"), "123")
}

func TestResponseWriterNoLogger405(t *testing.T) {
	router := New()
	router.LogRequests = false
	router.RequestID = "rid"
	router.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
		expect(t, w.Header().Get("rid"), "123")
	}, "POST")
	w := httptest.NewRecorder()
	req, _ := http.NewRequest("GET", "/test", nil)
	req.Header.Set("rid", "123")
	router.ServeHTTP(w, req)
	expect(t, w.Code, 405)
	expect(t, w.HeaderMap.Get("rid"), "123")
}

func TestResponseWriterLogger499(t *testing.T) {
	router := New()
	router.Verbose = false
	router.LogRequests = true
	router.Logger = func(w *ResponseWriter, r *http.Request) {
		expect(t, w.Status(), 499)
	}
	router.HandleFunc("*", func(w http.ResponseWriter, r *http.Request) {
		time.Sleep(10 * time.Millisecond)
	})
	ts := httptest.NewServer(router)
	defer ts.Close()
	client := &http.Client{
		Timeout: time.Duration(time.Millisecond),
	}
	client.Get(ts.URL)
}
<|endoftext|>


<commit_before>package ldap

import (
	"encoding/hex"
	"fmt"
	"regexp"

	l "github.com/go-ldap/ldap"
	"github.com/pkg/errors"
)

var (
	userRegexp = regexp.MustCompile(",[A-Z]+=")
)

func ParseUserCN(userDN string) (string, error) {
	dn, err := l.ParseDN(userDN)
	if err != nil {
		return "", errors.Wrapf(err, "Unable to parse userDN %s", userDN)
	}
	attributeName := dn.RDNs[0].Attributes[0].Type
	cn := dn.RDNs[0].Attributes[0].Value
	return fmt.Sprintf("%s=%s", attributeName, cn), nil
}

func EscapeFilterValue(filter string) string {
	//return l.EscapeFilter(strings.Replace(filter, "\\", "", -1))
	return l.EscapeFilter(filter)
}

func UnescapeFilterValue(filter string) string {
	repl := unescapeFilterRegex.ReplaceAllFunc(
		[]byte(filter),
		func(match []byte) []byte {
			// \( \) \\ \*
			if len(match) == 2 {
				return []byte{match[1]}
			}
			// had issues with Decode, TODO fix to use Decode?.
			res, _ := hex.DecodeString(string(match[1:]))
			return res
		},
	)
	return string(repl)
}
<commit_msg>minor fix<commit_after>package ldap

import (
	"encoding/hex"
	"fmt"
	"regexp"
	"strings"

	l "github.com/go-ldap/ldap"
	"github.com/pkg/errors"
)

var (
	userRegexp = regexp.MustCompile(",[A-Z]+=")
)

func ParseUserCN(userDN string) (string, error) {
	dn, err := l.ParseDN(userDN)
	if err != nil {
		return "", errors.Wrapf(err, "Unable to parse userDN %s", userDN)
	}
	attributeName := dn.RDNs[0].Attributes[0].Type
	cn := dn.RDNs[0].Attributes[0].Value
	return fmt.Sprintf("%s=%s", attributeName, cn), nil
}

func EscapeFilterValue(filter string) string {
	return l.EscapeFilter(strings.Replace(filter, "\\", "", -1))
}

func UnescapeFilterValue(filter string) string {
	repl := unescapeFilterRegex.ReplaceAllFunc(
		[]byte(filter),
		func(match []byte) []byte {
			// \( \) \\ \*
			if len(match) == 2 {
				return []byte{match[1]}
			}
			// had issues with Decode, TODO fix to use Decode?.
			res, _ := hex.DecodeString(string(match[1:]))
			return res
		},
	)
	return string(repl)
}
<|endoftext|>


<commit_before>package lfshttp

import (
	"fmt"
	"net/http"

	"github.com/google/slothfs/cookie"
)

func isCookieJarEnabledForHost(c *Client, host string) bool {
	_, cookieFileOk := c.uc.Get("http", fmt.Sprintf("https://%v", host), "cookieFile")

	return cookieFileOk
}

func getCookieJarForHost(c *Client, host string) (http.CookieJar, error) {
	cookieFile, _ := c.uc.Get("http", fmt.Sprintf("https://%v", host), "cookieFile")

	return cookie.NewJar(cookieFile)
}
<commit_msg>Allow tilde expansion in http.cookieFile config option<commit_after>package lfshttp

import (
	"fmt"
	"net/http"

	"github.com/git-lfs/git-lfs/tools"
	"github.com/google/slothfs/cookie"
)

func isCookieJarEnabledForHost(c *Client, host string) bool {
	_, cookieFileOk := c.uc.Get("http", fmt.Sprintf("https://%v", host), "cookieFile")

	return cookieFileOk
}

func getCookieJarForHost(c *Client, host string) (http.CookieJar, error) {
	cookieFile, _ := c.uc.Get("http", fmt.Sprintf("https://%v", host), "cookieFile")

	cookieFilePath, err := tools.ExpandPath(cookieFile, false)
	if err != nil {
		return nil, err
	}

	return cookie.NewJar(cookieFilePath)
}
<|endoftext|>


<commit_before>package job

import (
	"fmt"
	"strings"

	"github.com/go-hep/fwk"
)

func MsgLevel(lvl string) fwk.Level {
	switch strings.ToUpper(lvl) {
	case "DEBUG":
		return fwk.LvlDebug
	case "INFO":
		return fwk.LvlInfo
	case "WARNING":
		return fwk.LvlWarning
	case "ERROR":
		return fwk.LvlError
	default:
		panic(fmt.Errorf("fwk.MsgLevel: invalid fwk.Level string %q", lvl))
	}
	return fwk.LvlInfo
}
<commit_msg>job: govet<commit_after>package job

import (
	"fmt"
	"strings"

	"github.com/go-hep/fwk"
)

func MsgLevel(lvl string) fwk.Level {
	switch strings.ToUpper(lvl) {
	case "DEBUG":
		return fwk.LvlDebug
	case "INFO":
		return fwk.LvlInfo
	case "WARNING":
		return fwk.LvlWarning
	case "ERROR":
		return fwk.LvlError
	default:
		panic(fmt.Errorf("fwk.MsgLevel: invalid fwk.Level string %q", lvl))
	}
}
<|endoftext|>