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

package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

const unknown = "<<unknown>>"

// variables to allow tests to modify the values
var (
	procVersion = "/proc/version"
	osRelease   = "/etc/os-release"

	// Clear Linux has a different path (for stateless support)
	osReleaseClr = "/usr/lib/os-release"
)

func fileExists(path string) bool {
	if _, err := os.Stat(path); os.IsNotExist(err) {
		return false
	}

	return true
}

func getFileContents(file string) (string, error) {
	bytes, err := ioutil.ReadFile(file)
	if err != nil {
		return "", err
	}

	return string(bytes), nil
}

func getKernelVersion() (string, error) {
	contents, err := getFileContents(procVersion)
	if err != nil {
		return "", err
	}

	fields := strings.Fields(contents)

	if len(fields) < 3 {
		return "", fmt.Errorf("unexpected contents in %v", procVersion)
	}

	version := fields[2]

	return version, nil
}

func getDistroDetails() (name, version string, err error) {
	files := []string{osRelease, osReleaseClr}

	for _, file := range files {

		contents, err := getFileContents(file)
		if err != nil {
			if os.IsNotExist(err) {
				continue
			}

			return "", "", err
		}

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

		for _, line := range lines {
			if strings.HasPrefix(line, "NAME=") {
				fields := strings.Split(line, "=")
				name = strings.Trim(fields[1], `"`)
			} else if strings.HasPrefix(line, "VERSION_ID=") {
				fields := strings.Split(line, "=")
				version = strings.Trim(fields[1], `"`)
			}
		}

		if name != "" && version != "" {
			return name, version, nil
		}
	}

	return "", "", fmt.Errorf("failed to find expected fields in one of %v", files)
}

func getCPUDetails() (vendor, model string, err error) {
	cpuinfo, err := getCPUInfo(procCPUInfo)
	if err != nil {
		return "", "", err
	}

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

	for _, line := range lines {
		if strings.HasPrefix(line, "vendor_id") {
			fields := strings.Split(line, ":")
			if len(fields) > 1 {
				vendor = strings.TrimSpace(fields[1])
			}
		} else if strings.HasPrefix(line, "model name") {
			fields := strings.Split(line, ":")
			if len(fields) > 1 {
				model = strings.TrimSpace(fields[1])
			}
		}
	}

	if vendor != "" && model != "" {
		return vendor, model, nil
	}

	return "", "", fmt.Errorf("failed to find expected fields in file %v", procCPUInfo)
}

// resolvePath returns the fully resolved and expanded value of the
// specified path.
func resolvePath(path string) (string, error) {
	if path == "" {
		return "", fmt.Errorf("path must be specified")
	}

	absolute, err := filepath.Abs(path)
	if err != nil {
		return "", err
	}

	resolved, err := filepath.EvalSymlinks(absolute)
	if err != nil {
		return "", err
	}

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

package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
)

const unknown = "<<unknown>>"

// variables to allow tests to modify the values
var (
	procVersion = "/proc/version"
	osRelease   = "/etc/os-release"

	// Clear Linux has a different path (for stateless support)
	osReleaseClr = "/usr/lib/os-release"
)

func fileExists(path string) bool {
	if _, err := os.Stat(path); os.IsNotExist(err) {
		return false
	}

	return true
}

func getFileContents(file string) (string, error) {
	bytes, err := ioutil.ReadFile(file)
	if err != nil {
		return "", err
	}

	return string(bytes), nil
}

func getKernelVersion() (string, error) {
	contents, err := getFileContents(procVersion)
	if err != nil {
		return "", err
	}

	fields := strings.Fields(contents)

	if len(fields) < 3 {
		return "", fmt.Errorf("unexpected contents in %v", procVersion)
	}

	version := fields[2]

	return version, nil
}

// getDistroDetails returns the distributions name and version string.
// If it is not possible to determine both values an error is
// returned.
func getDistroDetails() (name, version string, err error) {
	files := []string{osRelease, osReleaseClr}

	for _, file := range files {
		contents, err := getFileContents(file)
		if err != nil {
			if os.IsNotExist(err) {
				continue
			}

			return "", "", err
		}

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

		for _, line := range lines {
			if strings.HasPrefix(line, "NAME=") {
				fields := strings.Split(line, "=")
				name = strings.Trim(fields[1], `"`)
			} else if strings.HasPrefix(line, "VERSION_ID=") {
				fields := strings.Split(line, "=")
				version = strings.Trim(fields[1], `"`)
			}
		}

		if name != "" && version != "" {
			return name, version, nil
		}
	}

	return "", "", fmt.Errorf("failed to find expected fields in one of %v", files)
}

// getCPUDetails returns the vendor and model of the CPU.
// If it is not possible to determine both values an error is
// returned.
func getCPUDetails() (vendor, model string, err error) {
	cpuinfo, err := getCPUInfo(procCPUInfo)
	if err != nil {
		return "", "", err
	}

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

	for _, line := range lines {
		if strings.HasPrefix(line, "vendor_id") {
			fields := strings.Split(line, ":")
			if len(fields) > 1 {
				vendor = strings.TrimSpace(fields[1])
			}
		} else if strings.HasPrefix(line, "model name") {
			fields := strings.Split(line, ":")
			if len(fields) > 1 {
				model = strings.TrimSpace(fields[1])
			}
		}
	}

	if vendor != "" && model != "" {
		return vendor, model, nil
	}

	return "", "", fmt.Errorf("failed to find expected fields in file %v", procCPUInfo)
}

// resolvePath returns the fully resolved and expanded value of the
// specified path.
func resolvePath(path string) (string, error) {
	if path == "" {
		return "", fmt.Errorf("path must be specified")
	}

	absolute, err := filepath.Abs(path)
	if err != nil {
		return "", err
	}

	resolved, err := filepath.EvalSymlinks(absolute)
	if err != nil {
		return "", err
	}

	return resolved, nil
}
<|endoftext|>


<commit_before>package main

import (
	"io/ioutil"
	"strings"
)

// Convert and concatenate a []int8 slice to a string
// inspired by perterGo: https://groups.google.com/forum/#!topic/golang-nuts/Jel8Bb-YwX8
func int8SliceToString(char []int8) string {
	s := make([]string, len(char))
	for i := range s {
		s[i] = string(char[i])
	}
	return strings.Join(s, "")
}

// TODO maybe change this to convert exclusively [65]int8 array ?

// Read a text file and return the content without the EOF carriage return
// this utility may be used with files from ``/sys` or ``/proc` file systems
func readAndTrimFile(path string) string {
	ret := ""
	data, err := ioutil.ReadFile(path)
	if err == nil {
		ret = strings.TrimRight(string(data), "\n") // Trimright remove the EOF carriage return
	}
	return ret
}

//TODO manage multiple line files ?
<commit_msg>Typos<commit_after>package main

import (
	"io/ioutil"
	"strings"
)

// Convert and concatenate a []int8 slice to a string
// inspired by perterGo: https://groups.google.com/forum/#!topic/golang-nuts/Jel8Bb-YwX8
func int8SliceToString(char []int8) string {
	s := make([]string, len(char))
	for i := range s {
		s[i] = string(char[i])
	}
	return strings.Join(s, "")
}

// TODO maybe change this to convert exclusively to [65]int8 array ?

// Read a text file and return the content without the EOF carriage return
// this utility may be used with files from `/sys` or `/proc` file systems
func readAndTrimFile(path string) string {
	ret := ""
	data, err := ioutil.ReadFile(path)
	if err == nil {
		ret = strings.TrimRight(string(data), "\n") // Trimright remove the EOF carriage return
	}
	return ret
}

//TODO manage multiple line files ?
<|endoftext|>


<commit_before>// Copyright © 2016 Aaron Longwell
//
// Use of this source code is governed by an MIT licese.
// Details in the LICENSE file.

package trello

type Checklist struct {
	ID         string      `json:"id"`
	Name       string      `json:"name"`
	IDBoard    string      `json:"idBoard,omitempty"`
	IDCard     string      `json:"idCard,omitempty"`
	Pos        int         `json:"pos,omitempty"`
	CheckItems []CheckItem `json:"checkItems,omitempty"`
}

type CheckItem struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	State       string `json:"state"`
	IDChecklist string `json:"idChecklist,omitempty"`
	Pos         int    `json:"pos,omitempty"`
}

// Manifestation of CheckItem when it appears in CheckItemStates
// on a Card.
type CheckItemState struct {
	IDCheckItem string `json:"idCheckItem"`
	State       string `json:"state"`
}
<commit_msg>fix: Trello have float values for checklist `Pos`<commit_after>// Copyright © 2016 Aaron Longwell
//
// Use of this source code is governed by an MIT licese.
// Details in the LICENSE file.

package trello

type Checklist struct {
	ID         string      `json:"id"`
	Name       string      `json:"name"`
	IDBoard    string      `json:"idBoard,omitempty"`
	IDCard     string      `json:"idCard,omitempty"`
	Pos        float64     `json:"pos,omitempty"`
	CheckItems []CheckItem `json:"checkItems,omitempty"`
}

type CheckItem struct {
	ID          string  `json:"id"`
	Name        string  `json:"name"`
	State       string  `json:"state"`
	IDChecklist string  `json:"idChecklist,omitempty"`
	Pos         float64 `json:"pos,omitempty"`
}

// Manifestation of CheckItem when it appears in CheckItemStates
// on a Card.
type CheckItemState struct {
	IDCheckItem string `json:"idCheckItem"`
	State       string `json:"state"`
}
<|endoftext|>


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

package netqueue

import (
	"bytes"
	"encoding/gob"
	. "launchpad.net/gocheck"
	"net"
	"sync"
	"testing"
	"time"
)

func Test(t *testing.T) {
	TestingT(t)
}

type S struct{}

var _ = Suite(&S{})

// SafeBuffer is a thread safe buffer.
type SafeBuffer struct {
	buf bytes.Buffer
	sync.Mutex
}

func (sb *SafeBuffer) Read(p []byte) (int, error) {
	sb.Lock()
	defer sb.Unlock()
	return sb.buf.Read(p)
}

func (sb *SafeBuffer) Write(p []byte) (int, error) {
	sb.Lock()
	defer sb.Unlock()
	return sb.buf.Write(p)
}

func (s *S) TestChannelFromWriter(c *C) {
	var buf SafeBuffer
	message := Message{
		Action: "delete",
		Args:   []string{"everything"},
	}
	var wg sync.WaitGroup
	wg.Add(1)
	ch, _ := ChannelFromWriter(&buf)
	go func() {
		ch <- message
		wg.Done()
	}()
	wg.Wait()
	var decodedMessage Message
	decoder := gob.NewDecoder(&buf)
	err := decoder.Decode(&decodedMessage)
	c.Assert(err, IsNil)
	c.Assert(decodedMessage, DeepEquals, message)
}

func (s *S) TestClosesErrChanIfClientCloseMessageChannel(c *C) {
	var buf SafeBuffer
	ch, errCh := ChannelFromWriter(&buf)
	close(ch)
	_, ok := <-errCh
	c.Assert(ok, Equals, false)
}

func (s *S) TestChannelFromReader(c *C) {
	var buf SafeBuffer
	messages := []Message{
		{Action: "delete", Args: []string{"everything"}},
		{Action: "rename", Args: []string{"old", "new"}},
		{Action: "destroy", Args: []string{"anything", "something", "otherthing"}},
	}
	encoder := gob.NewEncoder(&buf)
	for _, message := range messages {
		err := encoder.Encode(message)
		c.Assert(err, IsNil)
	}
	gotMessages := make([]Message, len(messages))
	ch, errCh := ChannelFromReader(&buf)
	for i := 0; i < len(messages); i++ {
		gotMessages[i] = <-ch
	}
	c.Assert(gotMessages, DeepEquals, messages)
	err := <-errCh
	c.Assert(err, IsNil)
	_, ok := <-ch
	c.Assert(ok, Equals, false)
	_, ok = <-errCh
	c.Assert(ok, Equals, false)
}

func (s *S) TestReadSendErrorsInTheErrorChannel(c *C) {
	messages := make(chan Message, 1)
	errChan := make(chan error, 1)
	conn := NewFakeConn("127.0.0.1:5055", "127.0.0.1:8080")
	conn.Close()
	go read(conn, messages, errChan)
	err := <-errChan
	c.Assert(err, NotNil)
	c.Assert(err.Error(), Equals, "Closed connection.")
}

func (s *S) TestQueueServerAddr(c *C) {
	listener := NewFakeListener("0.0.0.0:8000")
	server := QueueServer{listener: listener}
	c.Assert(server.Addr(), Equals, listener.Addr().String())
}

func (s *S) TestStartServerAndReadMessage(c *C) {
	message := Message{
		Action: "delete",
		Args:   []string{"something"},
	}
	server, err := StartServer("127.0.0.1:0")
	c.Assert(err, IsNil)
	defer server.Close()
	conn, err := net.Dial("tcp", server.Addr())
	c.Assert(err, IsNil)
	defer conn.Close()
	encoder := gob.NewEncoder(conn)
	err = encoder.Encode(message)
	c.Assert(err, IsNil)
	gotMessage, err := server.Message(2e9)
	c.Assert(err, IsNil)
	c.Assert(gotMessage, DeepEquals, message)
}

func (s *S) TestMessageNegativeTimeout(c *C) {
	server := QueueServer{
		messages: make(chan Message, 1),
		errors:   make(chan error, 1),
	}
	var (
		got, want Message
		err       error
		wg        sync.WaitGroup
	)
	want = Message{Action: "create"}
	wg.Add(1)
	go func() {
		got, err = server.Message(-1)
		wg.Done()
	}()
	time.Sleep(1e6)
	server.messages <- want
	wg.Wait()
	c.Assert(err, IsNil)
	c.Assert(got, DeepEquals, want)
}
<commit_msg>netqueue: ensure that write sends errors to the error channel<commit_after>// Copyright 2012 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package netqueue

import (
	"bytes"
	"encoding/gob"
	. "launchpad.net/gocheck"
	"net"
	"sync"
	"testing"
	"time"
)

func Test(t *testing.T) {
	TestingT(t)
}

type S struct{}

var _ = Suite(&S{})

// SafeBuffer is a thread safe buffer.
type SafeBuffer struct {
	buf bytes.Buffer
	sync.Mutex
}

func (sb *SafeBuffer) Read(p []byte) (int, error) {
	sb.Lock()
	defer sb.Unlock()
	return sb.buf.Read(p)
}

func (sb *SafeBuffer) Write(p []byte) (int, error) {
	sb.Lock()
	defer sb.Unlock()
	return sb.buf.Write(p)
}

func (s *S) TestChannelFromWriter(c *C) {
	var buf SafeBuffer
	message := Message{
		Action: "delete",
		Args:   []string{"everything"},
	}
	var wg sync.WaitGroup
	wg.Add(1)
	ch, _ := ChannelFromWriter(&buf)
	go func() {
		ch <- message
		wg.Done()
	}()
	wg.Wait()
	var decodedMessage Message
	decoder := gob.NewDecoder(&buf)
	err := decoder.Decode(&decodedMessage)
	c.Assert(err, IsNil)
	c.Assert(decodedMessage, DeepEquals, message)
}

func (s *S) TestClosesErrChanIfClientCloseMessageChannel(c *C) {
	var buf SafeBuffer
	ch, errCh := ChannelFromWriter(&buf)
	close(ch)
	_, ok := <-errCh
	c.Assert(ok, Equals, false)
}

func (s *S) TestWriteSendErrorsInTheErrorChannel(c *C) {
	messages := make(chan Message, 1)
	errCh := make(chan error, 1)
	conn := NewFakeConn("127.0.0.1:2345", "127.0.0.1:12345")
	conn.Close()
	go write(conn, messages, errCh)
	messages <- Message{}
	close(messages)
	err, ok := <-errCh
	c.Assert(ok, Equals, true)
	c.Assert(err, NotNil)
	c.Assert(err.Error(), Equals, "Closed connection.")
}

func (s *S) TestChannelFromReader(c *C) {
	var buf SafeBuffer
	messages := []Message{
		{Action: "delete", Args: []string{"everything"}},
		{Action: "rename", Args: []string{"old", "new"}},
		{Action: "destroy", Args: []string{"anything", "something", "otherthing"}},
	}
	encoder := gob.NewEncoder(&buf)
	for _, message := range messages {
		err := encoder.Encode(message)
		c.Assert(err, IsNil)
	}
	gotMessages := make([]Message, len(messages))
	ch, errCh := ChannelFromReader(&buf)
	for i := 0; i < len(messages); i++ {
		gotMessages[i] = <-ch
	}
	c.Assert(gotMessages, DeepEquals, messages)
	err := <-errCh
	c.Assert(err, IsNil)
	_, ok := <-ch
	c.Assert(ok, Equals, false)
	_, ok = <-errCh
	c.Assert(ok, Equals, false)
}

func (s *S) TestReadSendErrorsInTheErrorChannel(c *C) {
	messages := make(chan Message, 1)
	errChan := make(chan error, 1)
	conn := NewFakeConn("127.0.0.1:5055", "127.0.0.1:8080")
	conn.Close()
	go read(conn, messages, errChan)
	err := <-errChan
	c.Assert(err, NotNil)
	c.Assert(err.Error(), Equals, "Closed connection.")
}

func (s *S) TestQueueServerAddr(c *C) {
	listener := NewFakeListener("0.0.0.0:8000")
	server := QueueServer{listener: listener}
	c.Assert(server.Addr(), Equals, listener.Addr().String())
}

func (s *S) TestStartServerAndReadMessage(c *C) {
	message := Message{
		Action: "delete",
		Args:   []string{"something"},
	}
	server, err := StartServer("127.0.0.1:0")
	c.Assert(err, IsNil)
	defer server.Close()
	conn, err := net.Dial("tcp", server.Addr())
	c.Assert(err, IsNil)
	defer conn.Close()
	encoder := gob.NewEncoder(conn)
	err = encoder.Encode(message)
	c.Assert(err, IsNil)
	gotMessage, err := server.Message(2e9)
	c.Assert(err, IsNil)
	c.Assert(gotMessage, DeepEquals, message)
}

func (s *S) TestMessageNegativeTimeout(c *C) {
	server := QueueServer{
		messages: make(chan Message, 1),
		errors:   make(chan error, 1),
	}
	var (
		got, want Message
		err       error
		wg        sync.WaitGroup
	)
	want = Message{Action: "create"}
	wg.Add(1)
	go func() {
		got, err = server.Message(-1)
		wg.Done()
	}()
	time.Sleep(1e6)
	server.messages <- want
	wg.Wait()
	c.Assert(err, IsNil)
	c.Assert(got, DeepEquals, want)
}
<|endoftext|>


<commit_before>package processors

import (
	"github.com/mitchellh/mapstructure"
	"github.com/vjeantet/bitfan/codecs"
	"github.com/vjeantet/bitfan/core/config"
	"github.com/vjeantet/bitfan/processors/doc"
	"gopkg.in/go-playground/validator.v8"
)

type Base struct {
	Send                  PacketSender
	NewPacket             PacketBuilder
	Logger                Logger
	Memory                Memory
	WebHook               WebHook
	ConfigWorkingLocation string
	DataLocation          string
	PipelineID            int
}

// B returns the Base Processor
func (b *Base) B() *Base {
	return b
}

func (b *Base) Doc() *doc.Processor {
	return &doc.Processor{}
}

func (b *Base) SetPipelineID(ID int) {
	b.PipelineID = ID
}

func (b *Base) Configure(ctx ProcessorContext, conf map[string]interface{}) error { return nil }

func (b *Base) Receive(e IPacket) error { return nil }

func (b *Base) Tick(e IPacket) error { return nil }

func (b *Base) Start(e IPacket) error { return nil }

func (b *Base) Stop(e IPacket) error { return nil }

func (b *Base) MaxConcurent() int {
	return 0
}

func (b *Base) ConfigureAndValidate(ctx ProcessorContext, conf map[string]interface{}, rawVal interface{}) error {

	// Logger
	b.Logger = ctx.Log()

	// Configuration location dir
	b.ConfigWorkingLocation = ctx.ConfigWorkingLocation()

	// Packet Sender func
	b.Send = ctx.PacketSender()

	// Packet Builder func
	b.NewPacket = ctx.PacketBuilder()

	// StoreSpace
	b.Memory = ctx.Memory()

	// WebHook
	b.WebHook = ctx.WebHook()

	// Datalocation
	b.DataLocation = ctx.DataLocation()

	//Codecs
	if v, ok := conf["codec"]; ok {
		switch vcodec := v.(type) {
		case *config.Codec:
			conf["codec"] = codecs.New(vcodec.Name, vcodec.Options, ctx.Log(), ctx.ConfigWorkingLocation())
		}
	}

	// Set processor's user options
	if err := mapstructure.Decode(conf, rawVal); err != nil {
		return err
	}

	// validates processor's user options
	if err := validator.New(&validator.Config{TagName: "validate"}).Struct(rawVal); err != nil {
		return err
	}

	return nil
}
<commit_msg>core : allow weaked typed value in pipeline configuration ( "42" => 42, "true" => true, ....)<commit_after>package processors

import (
	"github.com/mitchellh/mapstructure"
	"github.com/vjeantet/bitfan/codecs"
	"github.com/vjeantet/bitfan/core/config"
	"github.com/vjeantet/bitfan/processors/doc"
	"gopkg.in/go-playground/validator.v8"
)

type Base struct {
	Send                  PacketSender
	NewPacket             PacketBuilder
	Logger                Logger
	Memory                Memory
	WebHook               WebHook
	ConfigWorkingLocation string
	DataLocation          string
	PipelineID            int
}

// B returns the Base Processor
func (b *Base) B() *Base {
	return b
}

func (b *Base) Doc() *doc.Processor {
	return &doc.Processor{}
}

func (b *Base) SetPipelineID(ID int) {
	b.PipelineID = ID
}

func (b *Base) Configure(ctx ProcessorContext, conf map[string]interface{}) error { return nil }

func (b *Base) Receive(e IPacket) error { return nil }

func (b *Base) Tick(e IPacket) error { return nil }

func (b *Base) Start(e IPacket) error { return nil }

func (b *Base) Stop(e IPacket) error { return nil }

func (b *Base) MaxConcurent() int {
	return 0
}

func (b *Base) ConfigureAndValidate(ctx ProcessorContext, conf map[string]interface{}, rawVal interface{}) error {

	// Logger
	b.Logger = ctx.Log()

	// Configuration location dir
	b.ConfigWorkingLocation = ctx.ConfigWorkingLocation()

	// Packet Sender func
	b.Send = ctx.PacketSender()

	// Packet Builder func
	b.NewPacket = ctx.PacketBuilder()

	// StoreSpace
	b.Memory = ctx.Memory()

	// WebHook
	b.WebHook = ctx.WebHook()

	// Datalocation
	b.DataLocation = ctx.DataLocation()

	//Codecs
	if v, ok := conf["codec"]; ok {
		switch vcodec := v.(type) {
		case *config.Codec:
			conf["codec"] = codecs.New(vcodec.Name, vcodec.Options, ctx.Log(), ctx.ConfigWorkingLocation())
		}
	}

	// Set processor's user options
	if err := mapstructure.WeakDecode(conf, rawVal); err != nil {
		return err
	}

	// validates processor's user options
	if err := validator.New(&validator.Config{TagName: "validate"}).Struct(rawVal); err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package cli

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
	"mynewt.apache.org/newt/newt/builder"
	"mynewt.apache.org/newt/newt/pkg"
	"mynewt.apache.org/newt/newt/project"
	"mynewt.apache.org/newt/newt/target"
	"mynewt.apache.org/newt/util"
)

const TARGET_TEST_NAME = "unittest"

func pkgIsTestable(pack *pkg.LocalPackage) bool {
	return util.NodeExist(pack.BasePath() + "/src/test")
}

func buildRunCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, nil)
	}

	t := ResolveTarget(args[0])
	if t == nil {
		NewtUsage(cmd, util.NewNewtError("invalid target name: "+args[0]))
	}

	b, err := builder.NewBuilder(t)
	if err != nil {
		NewtUsage(nil, err)
	}
	err = b.Build()
	if err != nil {
		NewtUsage(nil, err)
	}

	util.StatusMessage(util.VERBOSITY_DEFAULT, "App successfully built: %s\n",
		b.AppElfPath())
}

func cleanRunCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, util.NewNewtError("Must specify target"))
	}

	cleanAll := false
	targets := []*target.Target{}
	for _, arg := range args {
		if arg == TARGET_KEYWORD_ALL {
			cleanAll = true
		} else {
			t := ResolveTarget(arg)
			if t == nil {
				NewtUsage(cmd, util.NewNewtError("invalid target name"+arg))
			}
			targets = append(targets, t)
		}
	}

	if cleanAll {
		path := builder.BinRoot()
		util.StatusMessage(util.VERBOSITY_VERBOSE,
			"Cleaning directory %s\n", path)

		err := os.RemoveAll(path)
		if err != nil {
			NewtUsage(cmd, err)
		}
	} else {
		for _, t := range targets {
			b, err := builder.NewBuilder(t)
			if err != nil {
				NewtUsage(cmd, err)
			}
			err = b.Clean()
			if err != nil {
				NewtUsage(cmd, err)
			}
		}
	}
}

func testRunCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, nil)
	}

	// Verify and resolve each specified package.
	testAll := false
	packs := []*pkg.LocalPackage{}
	for _, pkgName := range args {
		if pkgName == "all" {
			testAll = true
		} else {
			dep, err := pkg.NewDependency(nil, pkgName)
			if err != nil {
				NewtUsage(cmd, util.NewNewtError(fmt.Sprintf("invalid "+
					"package name: %s (%s)", pkgName, err.Error())))
			}
			if dep == nil {
				NewtUsage(cmd, util.NewNewtError("invalid package name: "+
					pkgName))
			}
			pack := project.GetProject().ResolveDependency(dep)
			if pack == nil {
				NewtUsage(cmd, util.NewNewtError("unknown package: "+
					pkgName))
			}

			packs = append(packs, pack.(*pkg.LocalPackage))
		}
	}

	// Test each specified package.
	t := ResolveTarget(TARGET_TEST_NAME)
	if t == nil {
		NewtUsage(nil, util.NewNewtError("Can't find unit test target: "+
			TARGET_TEST_NAME))
	}

	if testAll {
		packs = []*pkg.LocalPackage{}
		for _, repoHash := range project.GetProject().PackageList() {
			for _, pack := range *repoHash {
				lclPack := pack.(*pkg.LocalPackage)

				if pkgIsTestable(lclPack) {
					packs = append(packs, lclPack)
				}
			}
		}
	}

	for _, pack := range packs {
		b, err := builder.NewBuilder(t)
		if err != nil {
			NewtUsage(nil, err)
		}

		err = b.Test(pack)
		if err != nil {
			NewtUsage(nil, err)
		}
	}
}

func downloadRunCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, util.NewNewtError("Must specify target"))
	}

	t := ResolveTarget(args[0])
	if t == nil {
		NewtUsage(cmd, util.NewNewtError("Invalid target name"+args[0]))
	}

	b, err := builder.NewBuilder(t)
	if err != nil {
		NewtUsage(cmd, err)
	}

	err = b.Download()
	if err != nil {
		NewtUsage(cmd, err)
	}
}

func debugRunCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, util.NewNewtError("Must specify target"))
	}

	t := ResolveTarget(args[0])
	if t == nil {
		NewtUsage(cmd, util.NewNewtError("Invalid target name"+args[0]))
	}

	b, err := builder.NewBuilder(t)
	if err != nil {
		NewtUsage(cmd, err)
	}

	err = b.Debug()
	if err != nil {
		NewtUsage(cmd, err)
	}
}

func sizeRunCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, util.NewNewtError("Must specify target"))
	}

	t := ResolveTarget(args[0])
	if t == nil {
		NewtUsage(cmd, util.NewNewtError("Invalid target name"+args[0]))
	}

	b, err := builder.NewBuilder(t)
	if err != nil {
		NewtUsage(cmd, err)
	}

	err = b.Size()
	if err != nil {
		NewtUsage(cmd, err)
	}
}

func AddBuildCommands(cmd *cobra.Command) {
	buildHelpText := ""
	buildHelpEx := ""
	buildCmd := &cobra.Command{
		Use:     "build",
		Short:   "Builds one or more apps.",
		Long:    buildHelpText,
		Example: buildHelpEx,
		Run:     buildRunCmd,
	}

	cmd.AddCommand(buildCmd)

	cleanHelpText := ""
	cleanHelpEx := ""
	cleanCmd := &cobra.Command{
		Use:     "clean",
		Short:   "Deletes app build artifacts.",
		Long:    cleanHelpText,
		Example: cleanHelpEx,
		Run:     cleanRunCmd,
	}

	cmd.AddCommand(cleanCmd)

	testHelpText := ""
	testHelpEx := ""
	testCmd := &cobra.Command{
		Use:     "test",
		Short:   "Executes unit tests for one or more packages",
		Long:    testHelpText,
		Example: testHelpEx,
		Run:     testRunCmd,
	}

	cmd.AddCommand(testCmd)

	downloadHelpText := "Download app image to target for <target-name>."
	downloadHelpEx := "  newt download <target-name>\n"

	downloadCmd := &cobra.Command{
		Use:     "download",
		Short:   "Download built target to board",
		Long:    downloadHelpText,
		Example: downloadHelpEx,
		Run:     downloadRunCmd,
	}
	cmd.AddCommand(downloadCmd)

	debugHelpText := "Open debugger session for <target-name>."
	debugHelpEx := "  newt debug <target-name>\n"

	debugCmd := &cobra.Command{
		Use:     "debug",
		Short:   "Open debugger session to target",
		Long:    debugHelpText,
		Example: debugHelpEx,
		Run:     debugRunCmd,
	}
	cmd.AddCommand(debugCmd)

	sizeHelpText := "Calculate the size of target components specified by " +
		"<target-name>."
	sizeHelpEx := "  newt size <target-name>\n"

	sizeCmd := &cobra.Command{
		Use:     "size",
		Short:   "Size of target components",
		Long:    sizeHelpText,
		Example: sizeHelpEx,
		Run:     sizeRunCmd,
	}
	cmd.AddCommand(sizeCmd)
}
<commit_msg>Fix error msg formatting when encountering unknown target.<commit_after>/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package cli

import (
	"fmt"
	"os"

	"github.com/spf13/cobra"
	"mynewt.apache.org/newt/newt/builder"
	"mynewt.apache.org/newt/newt/pkg"
	"mynewt.apache.org/newt/newt/project"
	"mynewt.apache.org/newt/newt/target"
	"mynewt.apache.org/newt/util"
)

const TARGET_TEST_NAME = "unittest"

func pkgIsTestable(pack *pkg.LocalPackage) bool {
	return util.NodeExist(pack.BasePath() + "/src/test")
}

func buildRunCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, nil)
	}

	t := ResolveTarget(args[0])
	if t == nil {
		NewtUsage(cmd, util.NewNewtError("invalid target name: "+args[0]))
	}

	b, err := builder.NewBuilder(t)
	if err != nil {
		NewtUsage(nil, err)
	}
	err = b.Build()
	if err != nil {
		NewtUsage(nil, err)
	}

	util.StatusMessage(util.VERBOSITY_DEFAULT, "App successfully built: %s\n",
		b.AppElfPath())
}

func cleanRunCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, util.NewNewtError("Must specify target"))
	}

	cleanAll := false
	targets := []*target.Target{}
	for _, arg := range args {
		if arg == TARGET_KEYWORD_ALL {
			cleanAll = true
		} else {
			t := ResolveTarget(arg)
			if t == nil {
				NewtUsage(cmd, util.NewNewtError("invalid target name: "+arg))
			}
			targets = append(targets, t)
		}
	}

	if cleanAll {
		path := builder.BinRoot()
		util.StatusMessage(util.VERBOSITY_VERBOSE,
			"Cleaning directory %s\n", path)

		err := os.RemoveAll(path)
		if err != nil {
			NewtUsage(cmd, err)
		}
	} else {
		for _, t := range targets {
			b, err := builder.NewBuilder(t)
			if err != nil {
				NewtUsage(cmd, err)
			}
			err = b.Clean()
			if err != nil {
				NewtUsage(cmd, err)
			}
		}
	}
}

func testRunCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, nil)
	}

	// Verify and resolve each specified package.
	testAll := false
	packs := []*pkg.LocalPackage{}
	for _, pkgName := range args {
		if pkgName == "all" {
			testAll = true
		} else {
			dep, err := pkg.NewDependency(nil, pkgName)
			if err != nil {
				NewtUsage(cmd, util.NewNewtError(fmt.Sprintf("invalid "+
					"package name: %s (%s)", pkgName, err.Error())))
			}
			if dep == nil {
				NewtUsage(cmd, util.NewNewtError("invalid package name: "+
					pkgName))
			}
			pack := project.GetProject().ResolveDependency(dep)
			if pack == nil {
				NewtUsage(cmd, util.NewNewtError("unknown package: "+
					pkgName))
			}

			packs = append(packs, pack.(*pkg.LocalPackage))
		}
	}

	// Test each specified package.
	t := ResolveTarget(TARGET_TEST_NAME)
	if t == nil {
		NewtUsage(nil, util.NewNewtError("Can't find unit test target: "+
			TARGET_TEST_NAME))
	}

	if testAll {
		packs = []*pkg.LocalPackage{}
		for _, repoHash := range project.GetProject().PackageList() {
			for _, pack := range *repoHash {
				lclPack := pack.(*pkg.LocalPackage)

				if pkgIsTestable(lclPack) {
					packs = append(packs, lclPack)
				}
			}
		}
	}

	for _, pack := range packs {
		b, err := builder.NewBuilder(t)
		if err != nil {
			NewtUsage(nil, err)
		}

		err = b.Test(pack)
		if err != nil {
			NewtUsage(nil, err)
		}
	}
}

func downloadRunCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, util.NewNewtError("Must specify target"))
	}

	t := ResolveTarget(args[0])
	if t == nil {
		NewtUsage(cmd, util.NewNewtError("Invalid target name: "+args[0]))
	}

	b, err := builder.NewBuilder(t)
	if err != nil {
		NewtUsage(cmd, err)
	}

	err = b.Download()
	if err != nil {
		NewtUsage(cmd, err)
	}
}

func debugRunCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, util.NewNewtError("Must specify target"))
	}

	t := ResolveTarget(args[0])
	if t == nil {
		NewtUsage(cmd, util.NewNewtError("Invalid target name: "+args[0]))
	}

	b, err := builder.NewBuilder(t)
	if err != nil {
		NewtUsage(cmd, err)
	}

	err = b.Debug()
	if err != nil {
		NewtUsage(cmd, err)
	}
}

func sizeRunCmd(cmd *cobra.Command, args []string) {
	if len(args) < 1 {
		NewtUsage(cmd, util.NewNewtError("Must specify target"))
	}

	t := ResolveTarget(args[0])
	if t == nil {
		NewtUsage(cmd, util.NewNewtError("Invalid target name: "+args[0]))
	}

	b, err := builder.NewBuilder(t)
	if err != nil {
		NewtUsage(cmd, err)
	}

	err = b.Size()
	if err != nil {
		NewtUsage(cmd, err)
	}
}

func AddBuildCommands(cmd *cobra.Command) {
	buildHelpText := ""
	buildHelpEx := ""
	buildCmd := &cobra.Command{
		Use:     "build",
		Short:   "Builds one or more apps.",
		Long:    buildHelpText,
		Example: buildHelpEx,
		Run:     buildRunCmd,
	}

	cmd.AddCommand(buildCmd)

	cleanHelpText := ""
	cleanHelpEx := ""
	cleanCmd := &cobra.Command{
		Use:     "clean",
		Short:   "Deletes app build artifacts.",
		Long:    cleanHelpText,
		Example: cleanHelpEx,
		Run:     cleanRunCmd,
	}

	cmd.AddCommand(cleanCmd)

	testHelpText := ""
	testHelpEx := ""
	testCmd := &cobra.Command{
		Use:     "test",
		Short:   "Executes unit tests for one or more packages",
		Long:    testHelpText,
		Example: testHelpEx,
		Run:     testRunCmd,
	}

	cmd.AddCommand(testCmd)

	downloadHelpText := "Download app image to target for <target-name>."
	downloadHelpEx := "  newt download <target-name>\n"

	downloadCmd := &cobra.Command{
		Use:     "download",
		Short:   "Download built target to board",
		Long:    downloadHelpText,
		Example: downloadHelpEx,
		Run:     downloadRunCmd,
	}
	cmd.AddCommand(downloadCmd)

	debugHelpText := "Open debugger session for <target-name>."
	debugHelpEx := "  newt debug <target-name>\n"

	debugCmd := &cobra.Command{
		Use:     "debug",
		Short:   "Open debugger session to target",
		Long:    debugHelpText,
		Example: debugHelpEx,
		Run:     debugRunCmd,
	}
	cmd.AddCommand(debugCmd)

	sizeHelpText := "Calculate the size of target components specified by " +
		"<target-name>."
	sizeHelpEx := "  newt size <target-name>\n"

	sizeCmd := &cobra.Command{
		Use:     "size",
		Short:   "Size of target components",
		Long:    sizeHelpText,
		Example: sizeHelpEx,
		Run:     sizeRunCmd,
	}
	cmd.AddCommand(sizeCmd)
}
<|endoftext|>


<commit_before>package observers

import (
	"github.com/sirupsen/logrus"

	"github.com/ivan1993spb/snake-server/engine"
	"github.com/ivan1993spb/snake-server/objects/wall"
	"github.com/ivan1993spb/snake-server/world"
)

const ruinsFactor = 0.20

var dotsMaskOne = engine.NewDotsMask([][]uint8{{1}})

var ruins = []*engine.DotsMask{
	dotsMaskOne,
	engine.DotsMaskSquare2x2,
	engine.DotsMaskTank,
	engine.DotsMaskHome1,
	engine.DotsMaskHome2,
	engine.DotsMaskCross,
	engine.DotsMaskDiagonal,
	engine.DotsMaskCrossSmall,
	engine.DotsMaskDiagonalSmall,
	engine.DotsMaskLabyrinth,
	engine.DotsMaskTunnel1,
	engine.DotsMaskTunnel2,
	engine.DotsMaskBigHome,
}

func calcRuinsCount(size uint16) uint16 {
	return uint16(float32(size) * ruinsFactor)
}

type WallObserver struct{}

func (WallObserver) Observe(stop <-chan struct{}, w *world.World, logger logrus.FieldLogger) {
	area, err := engine.NewArea(w.Width(), w.Height())
	if err != nil {
		logger.WithError(err).Error("cannot create area in wall observer")
		return
	}

	size := area.Size()
	ruinsCount := calcRuinsCount(size)
	var counter uint16

	for counter < ruinsCount {
		for i := 0; i < len(ruins); i++ {
			mask := ruins[i].TurnRandom()

			if area.Width() >= mask.Width() && area.Height() >= mask.Height() {
				rect, err := area.NewRandomRect(mask.Width(), mask.Height(), 0, 0)
				if err != nil {
					continue
				}

				location := mask.Location(rect.X(), rect.Y())
				if location.DotCount() > ruinsCount-counter {
					location = location[:ruinsCount-counter]
				}

				if w.LocationOccupied(location) {
					continue
				}

				if _, err := wall.NewWallLocation(w, location); err != nil {
					logger.WithError(err).Error("error on wall creation")
				} else {
					counter += location.DotCount()
				}
			}
		}
	}
}
<commit_msg>Run wall generation in goroutine<commit_after>package observers

import (
	"github.com/sirupsen/logrus"

	"github.com/ivan1993spb/snake-server/engine"
	"github.com/ivan1993spb/snake-server/objects/wall"
	"github.com/ivan1993spb/snake-server/world"
)

const ruinsFactor = 0.20

var dotsMaskOne = engine.NewDotsMask([][]uint8{{1}})

var ruins = []*engine.DotsMask{
	dotsMaskOne,
	engine.DotsMaskSquare2x2,
	engine.DotsMaskTank,
	engine.DotsMaskHome1,
	engine.DotsMaskHome2,
	engine.DotsMaskCross,
	engine.DotsMaskDiagonal,
	engine.DotsMaskCrossSmall,
	engine.DotsMaskDiagonalSmall,
	engine.DotsMaskLabyrinth,
	engine.DotsMaskTunnel1,
	engine.DotsMaskTunnel2,
	engine.DotsMaskBigHome,
}

func calcRuinsCount(size uint16) uint16 {
	return uint16(float32(size) * ruinsFactor)
}

type WallObserver struct{}

func (WallObserver) Observe(stop <-chan struct{}, w *world.World, logger logrus.FieldLogger) {
	go func() {
		area, err := engine.NewArea(w.Width(), w.Height())
		if err != nil {
			logger.WithError(err).Error("cannot create area in wall observer")
			return
		}

		size := area.Size()
		ruinsCount := calcRuinsCount(size)
		var counter uint16

		for counter < ruinsCount {
			for i := 0; i < len(ruins); i++ {
				mask := ruins[i].TurnRandom()

				if area.Width() >= mask.Width() && area.Height() >= mask.Height() {
					rect, err := area.NewRandomRect(mask.Width(), mask.Height(), 0, 0)
					if err != nil {
						continue
					}

					location := mask.Location(rect.X(), rect.Y())
					if location.DotCount() > ruinsCount-counter {
						location = location[:ruinsCount-counter]
					}

					if w.LocationOccupied(location) {
						continue
					}

					if _, err := wall.NewWallLocation(w, location); err != nil {
						logger.WithError(err).Error("error on wall creation")
					} else {
						counter += location.DotCount()
					}
				}
			}
		}
	}()
}
<|endoftext|>


<commit_before>package goflagbuilder

import (
	"flag"
	"log"
	"reflect"
	"strconv"
	"strings"
)

type flagKind interface {
	Set(v reflect.Value, s string) error
	Get(v reflect.Value) interface{}
	String(v reflect.Value) string
}

type value struct {
	value  reflect.Value
	kind   flagKind
	isBool bool
}

func (v value) Set(s string) error {
	return v.kind.Set(v.value, s)
}

func (v value) Get() interface{} { return v.kind.Get(v.value) }

func (v value) String() string { return v.kind.String(v.value) }

func (v value) IsBoolFlag() bool { return v.isBool }

func find(k reflect.Kind) flagKind {
	switch k {
	case reflect.Bool:
		return boolKind{}

	case reflect.Int:
		return intKind{}

	case reflect.Int64:
		return int64Kind{}

	case reflect.Uint:
		return uintKind{}

	case reflect.Uint64:
		return uint64Kind{}

	case reflect.Float64:
		return float64Kind{}

	case reflect.String:
		return stringKind{}
	}

	return nil
}

func isGetter(r reflect.Value) bool {
	return r.Type().Implements(reflect.TypeOf((*flag.Getter)(nil)).Elem())
}

func findKind(r reflect.Value) flagKind {
	kind := find(r.Kind())
	if kind != nil {
		return kind
	}

	if r.Kind() == reflect.Slice {
		kind := sliceKind{itemKind: find(r.Type().Elem().Kind())}
		if kind.itemKind != nil {
			return kind
		}
	}

	log.Println("Type:", r.Type())
	log.Println("Getter:", reflect.TypeOf((*flag.Getter)(nil)).Elem())
	log.Println("Implements:", reflect.PtrTo(r.Type()).Implements(reflect.TypeOf((*flag.Getter)(nil)).Elem()))

	if isGetter(r) || (r.CanAddr() && isGetter(r.Addr())) {
		return getterKind{}
	}

	return nil
}

// bool Kind

type boolKind struct{}

func (boolKind) Set(r reflect.Value, s string) error {
	ps, err := strconv.ParseBool(s)
	r.SetBool(ps)
	return err
}

func (boolKind) Get(r reflect.Value) interface{} { return r.Bool() }

func (boolKind) String(r reflect.Value) string {
	return strconv.FormatBool(r.Bool())
}

// int Kind

type intKind struct{}

func (intKind) Set(r reflect.Value, s string) error {
	ps, err := strconv.ParseInt(s, 0, strconv.IntSize)
	r.SetInt(ps)
	return err
}

func (intKind) Get(r reflect.Value) interface{} { return int(r.Int()) }

func (intKind) String(r reflect.Value) string {
	return strconv.FormatInt(r.Int(), 10)
}

// int64 Kind

type int64Kind struct{}

func (int64Kind) Set(r reflect.Value, s string) error {
	ps, err := strconv.ParseInt(s, 0, 64)
	r.SetInt(ps)
	return err
}

func (int64Kind) Get(r reflect.Value) interface{} { return r.Int() }

func (int64Kind) String(r reflect.Value) string {
	return strconv.FormatInt(r.Int(), 10)
}

// uint Kind

type uintKind struct{}

func (uintKind) Set(r reflect.Value, s string) error {
	ps, err := strconv.ParseUint(s, 0, strconv.IntSize)
	r.SetUint(ps)
	return err
}

func (uintKind) Get(r reflect.Value) interface{} { return uint(r.Uint()) }

func (uintKind) String(r reflect.Value) string {
	return strconv.FormatUint(r.Uint(), 10)
}

// uint64 Kind

type uint64Kind struct{}

func (uint64Kind) Set(r reflect.Value, s string) error {
	ps, err := strconv.ParseUint(s, 0, 64)
	r.SetUint(ps)
	return err
}

func (uint64Kind) Get(r reflect.Value) interface{} { return r.Uint() }

func (uint64Kind) String(r reflect.Value) string {
	return strconv.FormatUint(r.Uint(), 10)
}

// float64 Kind

type float64Kind struct{}

func (float64Kind) Set(r reflect.Value, s string) error {
	ps, err := strconv.ParseFloat(s, 64)
	r.SetFloat(ps)
	return err
}

func (float64Kind) Get(r reflect.Value) interface{} { return r.Float() }

func (float64Kind) String(r reflect.Value) string {
	return strconv.FormatFloat(r.Float(), 'g', -1, 64)
}

// string Kind

type stringKind struct{}

func (stringKind) Set(r reflect.Value, s string) error {
	r.SetString(s)
	return nil
}

func (stringKind) Get(r reflect.Value) interface{} { return r.String() }

func (stringKind) String(r reflect.Value) string { return r.String() }

// flag.Getter Value

type getterKind struct{}

func getter(r reflect.Value) flag.Getter {
	if isGetter(r) {
		return r.Interface().(flag.Getter)
	}

	if r.CanAddr() && isGetter(r.Addr()) {
		return r.Addr().Interface().(flag.Getter)
	}

	panic("not a getter")
}

func (getterKind) Set(r reflect.Value, s string) error {
	fv := getter(r)
	return fv.Set(s)
}

func (getterKind) Get(r reflect.Value) interface{} {
	fv := getter(r)
	return fv.Get()
}

func (getterKind) String(r reflect.Value) string {
	fv := getter(r)
	return fv.String()
}

// slice Kind

type sliceKind struct {
	itemKind flagKind
}

func (v sliceKind) Set(r reflect.Value, s string) error {
	itemValue := reflect.New(r.Type().Elem())
	if err := v.itemKind.Set(itemValue.Elem(), s); err != nil {
		return err
	}

	r.Set(reflect.Append(r, itemValue.Elem()))
	return nil
}

func (sliceKind) Get(r reflect.Value) interface{} { return r.Interface() }

func (sliceKind) String(r reflect.Value) string {
	var b strings.Builder
	b.WriteString("[")

	for i := 0; i < r.Len(); i++ {
		if i != 0 {
			b.WriteString(", ")
		}
		b.WriteString(r.Index(i).String())
	}

	b.WriteString("]")
	return b.String()
}

// map Kind

type mapKind struct {
	keyval    reflect.Value
	valueKind flagKind
}

func (v mapKind) Set(r reflect.Value, s string) error {
	itemValue := reflect.New(r.Type().Elem())
	if err := v.valueKind.Set(itemValue.Elem(), s); err != nil {
		return err
	}

	r.SetMapIndex(v.keyval, itemValue.Elem())
	return nil
}

func (v mapKind) Get(r reflect.Value) interface{} {
	return v.valueKind.Get(r.MapIndex(v.keyval))
}

func (v mapKind) String(r reflect.Value) string {
	return v.valueKind.String(r.MapIndex(v.keyval))
}
<commit_msg>Remove unnecessary log statements.<commit_after>package goflagbuilder

import (
	"flag"
	"reflect"
	"strconv"
	"strings"
)

type flagKind interface {
	Set(v reflect.Value, s string) error
	Get(v reflect.Value) interface{}
	String(v reflect.Value) string
}

type value struct {
	value  reflect.Value
	kind   flagKind
	isBool bool
}

func (v value) Set(s string) error {
	return v.kind.Set(v.value, s)
}

func (v value) Get() interface{} { return v.kind.Get(v.value) }

func (v value) String() string { return v.kind.String(v.value) }

func (v value) IsBoolFlag() bool { return v.isBool }

func find(k reflect.Kind) flagKind {
	switch k {
	case reflect.Bool:
		return boolKind{}

	case reflect.Int:
		return intKind{}

	case reflect.Int64:
		return int64Kind{}

	case reflect.Uint:
		return uintKind{}

	case reflect.Uint64:
		return uint64Kind{}

	case reflect.Float64:
		return float64Kind{}

	case reflect.String:
		return stringKind{}
	}

	return nil
}

func isGetter(r reflect.Value) bool {
	return r.Type().Implements(reflect.TypeOf((*flag.Getter)(nil)).Elem())
}

func findKind(r reflect.Value) flagKind {
	kind := find(r.Kind())
	if kind != nil {
		return kind
	}

	if r.Kind() == reflect.Slice {
		kind := sliceKind{itemKind: find(r.Type().Elem().Kind())}
		if kind.itemKind != nil {
			return kind
		}
	}

	if isGetter(r) || (r.CanAddr() && isGetter(r.Addr())) {
		return getterKind{}
	}

	return nil
}

// bool Kind

type boolKind struct{}

func (boolKind) Set(r reflect.Value, s string) error {
	ps, err := strconv.ParseBool(s)
	r.SetBool(ps)
	return err
}

func (boolKind) Get(r reflect.Value) interface{} { return r.Bool() }

func (boolKind) String(r reflect.Value) string {
	return strconv.FormatBool(r.Bool())
}

// int Kind

type intKind struct{}

func (intKind) Set(r reflect.Value, s string) error {
	ps, err := strconv.ParseInt(s, 0, strconv.IntSize)
	r.SetInt(ps)
	return err
}

func (intKind) Get(r reflect.Value) interface{} { return int(r.Int()) }

func (intKind) String(r reflect.Value) string {
	return strconv.FormatInt(r.Int(), 10)
}

// int64 Kind

type int64Kind struct{}

func (int64Kind) Set(r reflect.Value, s string) error {
	ps, err := strconv.ParseInt(s, 0, 64)
	r.SetInt(ps)
	return err
}

func (int64Kind) Get(r reflect.Value) interface{} { return r.Int() }

func (int64Kind) String(r reflect.Value) string {
	return strconv.FormatInt(r.Int(), 10)
}

// uint Kind

type uintKind struct{}

func (uintKind) Set(r reflect.Value, s string) error {
	ps, err := strconv.ParseUint(s, 0, strconv.IntSize)
	r.SetUint(ps)
	return err
}

func (uintKind) Get(r reflect.Value) interface{} { return uint(r.Uint()) }

func (uintKind) String(r reflect.Value) string {
	return strconv.FormatUint(r.Uint(), 10)
}

// uint64 Kind

type uint64Kind struct{}

func (uint64Kind) Set(r reflect.Value, s string) error {
	ps, err := strconv.ParseUint(s, 0, 64)
	r.SetUint(ps)
	return err
}

func (uint64Kind) Get(r reflect.Value) interface{} { return r.Uint() }

func (uint64Kind) String(r reflect.Value) string {
	return strconv.FormatUint(r.Uint(), 10)
}

// float64 Kind

type float64Kind struct{}

func (float64Kind) Set(r reflect.Value, s string) error {
	ps, err := strconv.ParseFloat(s, 64)
	r.SetFloat(ps)
	return err
}

func (float64Kind) Get(r reflect.Value) interface{} { return r.Float() }

func (float64Kind) String(r reflect.Value) string {
	return strconv.FormatFloat(r.Float(), 'g', -1, 64)
}

// string Kind

type stringKind struct{}

func (stringKind) Set(r reflect.Value, s string) error {
	r.SetString(s)
	return nil
}

func (stringKind) Get(r reflect.Value) interface{} { return r.String() }

func (stringKind) String(r reflect.Value) string { return r.String() }

// flag.Getter Value

type getterKind struct{}

func getter(r reflect.Value) flag.Getter {
	if isGetter(r) {
		return r.Interface().(flag.Getter)
	}

	if r.CanAddr() && isGetter(r.Addr()) {
		return r.Addr().Interface().(flag.Getter)
	}

	panic("not a getter")
}

func (getterKind) Set(r reflect.Value, s string) error {
	fv := getter(r)
	return fv.Set(s)
}

func (getterKind) Get(r reflect.Value) interface{} {
	fv := getter(r)
	return fv.Get()
}

func (getterKind) String(r reflect.Value) string {
	fv := getter(r)
	return fv.String()
}

// slice Kind

type sliceKind struct {
	itemKind flagKind
}

func (v sliceKind) Set(r reflect.Value, s string) error {
	itemValue := reflect.New(r.Type().Elem())
	if err := v.itemKind.Set(itemValue.Elem(), s); err != nil {
		return err
	}

	r.Set(reflect.Append(r, itemValue.Elem()))
	return nil
}

func (sliceKind) Get(r reflect.Value) interface{} { return r.Interface() }

func (sliceKind) String(r reflect.Value) string {
	var b strings.Builder
	b.WriteString("[")

	for i := 0; i < r.Len(); i++ {
		if i != 0 {
			b.WriteString(", ")
		}
		b.WriteString(r.Index(i).String())
	}

	b.WriteString("]")
	return b.String()
}

// map Kind

type mapKind struct {
	keyval    reflect.Value
	valueKind flagKind
}

func (v mapKind) Set(r reflect.Value, s string) error {
	itemValue := reflect.New(r.Type().Elem())
	if err := v.valueKind.Set(itemValue.Elem(), s); err != nil {
		return err
	}

	r.SetMapIndex(v.keyval, itemValue.Elem())
	return nil
}

func (v mapKind) Get(r reflect.Value) interface{} {
	return v.valueKind.Get(r.MapIndex(v.keyval))
}

func (v mapKind) String(r reflect.Value) string {
	return v.valueKind.String(r.MapIndex(v.keyval))
}
<|endoftext|>


<commit_before>// Copyright (C) 2016  Arista Networks, Inc.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the COPYING file.

package client

import (
	"crypto/tls"
	"crypto/x509"
	"flag"
	"io/ioutil"
	"strings"

	"github.com/aristanetworks/glog"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
)

// ParseFlags registers some additional common flags,
// parses the flags, and returns the resulting gRPC options,
// and other settings to connect to the gRPC interface.
func ParseFlags() (username string, password string, get string,
	subscriptions, addrs []string,
	opts []grpc.DialOption) {

	var (
		addrsFlag = flag.String("addrs", "localhost:6042",
			"Comma-separated list of addresses of OpenConfig gRPC servers")

		caFileFlag = flag.String("cafile", "",
			"Path to server TLS certificate file")

		certFileFlag = flag.String("certfile", "",
			"Path to client TLS certificate file")

		getFlag = flag.String("get", "",
			"Path to get to upon connecting to the server")

		keyFileFlag = flag.String("keyfile", "",
			"Path to client TLS private key file")

		passwordFlag = flag.String("password", "",
			"Password to authenticate with")

		subscribeFlag = flag.String("subscribe", "",
			"Comma-separated list of paths to subscribe to upon connecting to the server")

		usernameFlag = flag.String("username", "",
			"Username to authenticate with")

		tlsFlag = flag.Bool("tls", false,
			"Enable TLS")
	)

	flag.Parse()
	if *tlsFlag || *caFileFlag != "" || *certFileFlag != "" {
		config := &tls.Config{}
		if *caFileFlag != "" {
			b, err := ioutil.ReadFile(*caFileFlag)
			if err != nil {
				glog.Fatal(err)
			}
			cp := x509.NewCertPool()
			if !cp.AppendCertsFromPEM(b) {
				glog.Fatalf("credentials: failed to append certificates")
			}
			config.RootCAs = cp
		} else {
			config.InsecureSkipVerify = true
		}
		if *certFileFlag != "" {
			if *keyFileFlag == "" {
				glog.Fatalf("Please provide both -certfile and -keyfile")
			}
			cert, err := tls.LoadX509KeyPair(*certFileFlag, *keyFileFlag)
			if err != nil {
				glog.Fatal(err)
			}
			config.Certificates = []tls.Certificate{cert}
		}
		opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(config)))
	} else {
		opts = append(opts, grpc.WithInsecure())
	}
	addrs = strings.Split(*addrsFlag, ",")
	if *getFlag != "" {
		if *subscribeFlag != "" {
			glog.Fatal("-get and -subscribe are mutually exclusive")
		} else if len(addrs) > 1 {
			glog.Fatal("Please specify a single address in -addrs with -get")
		}
	}
	if *subscribeFlag != "" {
		subscriptions = strings.Split(*subscribeFlag, ",")
	}
	return *usernameFlag, *passwordFlag, *getFlag, subscriptions, addrs, opts
}
<commit_msg>openconfig/client: default to subscribing to everything<commit_after>// Copyright (C) 2016  Arista Networks, Inc.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the COPYING file.

package client

import (
	"crypto/tls"
	"crypto/x509"
	"flag"
	"io/ioutil"
	"strings"

	"github.com/aristanetworks/glog"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials"
)

// ParseFlags registers some additional common flags,
// parses the flags, and returns the resulting gRPC options,
// and other settings to connect to the gRPC interface.
func ParseFlags() (username string, password string, get string,
	subscriptions, addrs []string,
	opts []grpc.DialOption) {

	var (
		addrsFlag = flag.String("addrs", "localhost:6042",
			"Comma-separated list of addresses of OpenConfig gRPC servers")

		caFileFlag = flag.String("cafile", "",
			"Path to server TLS certificate file")

		certFileFlag = flag.String("certfile", "",
			"Path to client TLS certificate file")

		getFlag = flag.String("get", "",
			"Path to get to upon connecting to the server")

		keyFileFlag = flag.String("keyfile", "",
			"Path to client TLS private key file")

		passwordFlag = flag.String("password", "",
			"Password to authenticate with")

		subscribeFlag = flag.String("subscribe", "",
			"Comma-separated list of paths to subscribe to upon connecting to the server")

		usernameFlag = flag.String("username", "",
			"Username to authenticate with")

		tlsFlag = flag.Bool("tls", false,
			"Enable TLS")
	)

	flag.Parse()
	if *tlsFlag || *caFileFlag != "" || *certFileFlag != "" {
		config := &tls.Config{}
		if *caFileFlag != "" {
			b, err := ioutil.ReadFile(*caFileFlag)
			if err != nil {
				glog.Fatal(err)
			}
			cp := x509.NewCertPool()
			if !cp.AppendCertsFromPEM(b) {
				glog.Fatalf("credentials: failed to append certificates")
			}
			config.RootCAs = cp
		} else {
			config.InsecureSkipVerify = true
		}
		if *certFileFlag != "" {
			if *keyFileFlag == "" {
				glog.Fatalf("Please provide both -certfile and -keyfile")
			}
			cert, err := tls.LoadX509KeyPair(*certFileFlag, *keyFileFlag)
			if err != nil {
				glog.Fatal(err)
			}
			config.Certificates = []tls.Certificate{cert}
		}
		opts = append(opts, grpc.WithTransportCredentials(credentials.NewTLS(config)))
	} else {
		opts = append(opts, grpc.WithInsecure())
	}
	addrs = strings.Split(*addrsFlag, ",")
	if *getFlag != "" {
		if *subscribeFlag != "" {
			glog.Fatal("-get and -subscribe are mutually exclusive")
		} else if len(addrs) > 1 {
			glog.Fatal("Please specify a single address in -addrs with -get")
		}
	} else {
		subscriptions = strings.Split(*subscribeFlag, ",")
	}
	return *usernameFlag, *passwordFlag, *getFlag, subscriptions, addrs, opts
}
<|endoftext|>


<commit_before>package promgrpc_test

import (
	"net"
	"testing"
	"time"

	"github.com/piotrkowalczuk/promgrpc"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
)

func TestInterceptor_Dialer(t *testing.T) {
	interceptor := promgrpc.NewInterceptor(nil)
	fn := interceptor.Dialer(func(addr string, timeout time.Duration) (net.Conn, error) {
		return nil, nil
	})
	_, err := fn("X", 1*time.Second)
	if err != nil {
		t.Fatalf("unexpected error: %s", err.Error())
	}
}

func TestInterceptor_UnaryServer(t *testing.T) {
	interceptor := promgrpc.NewInterceptor(nil)
	_, err := interceptor.UnaryServer()(context.Background(), nil, &grpc.UnaryServerInfo{}, func(ctx context.Context, req interface{}) (interface{}, error) {
		return nil, nil
	})
	if err != nil {
		t.Fatalf("unexpected error: %s", err.Error())
	}
}

func TestInterceptor_StreamServer(t *testing.T) {
	interceptor := promgrpc.NewInterceptor(nil)
	err := interceptor.StreamServer()(context.Background(), nil, &grpc.StreamServerInfo{}, func(srv interface{}, stream grpc.ServerStream) error {
		return nil
	})
	if err != nil {
		t.Fatalf("unexpected error: %s", err.Error())
	}
}

func TestInterceptor_UnaryClient(t *testing.T) {
	interceptor := promgrpc.NewInterceptor(nil)
	err := interceptor.UnaryClient()(context.Background(), "method", nil, nil, nil, func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, opts ...grpc.CallOption) error {
		return nil
	})
	if err != nil {
		t.Fatalf("unexpected error: %s", err.Error())
	}
}

func TestInterceptor_StreamClient(t *testing.T) {
	interceptor := promgrpc.NewInterceptor(nil)
	_, err := interceptor.StreamClient()(context.Background(), &grpc.StreamDesc{}, nil, "method", func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, opts ...grpc.CallOption) (grpc.ClientStream, error) {
		return nil, nil
	})
	if err != nil {
		t.Fatalf("unexpected error: %s", err.Error())
	}
}
<commit_msg>dialer example<commit_after>package promgrpc_test

import (
	"net"
	"testing"
	"time"

	"github.com/piotrkowalczuk/promgrpc"
	"golang.org/x/net/context"
	"google.golang.org/grpc"
)

func ExampleInterceptor_Dialer() {
	interceptor := promgrpc.NewInterceptor(nil)

	var opts []grpc.DialOption
	opts = append(opts, grpc.WithDialer(interceptor.Dialer(func(addr string, timeout time.Duration) (net.Conn, error) {
		return net.DialTimeout("tcp", addr, timeout)
	})))
}

func TestInterceptor_Dialer(t *testing.T) {
	interceptor := promgrpc.NewInterceptor(nil)
	fn := interceptor.Dialer(func(addr string, timeout time.Duration) (net.Conn, error) {
		return nil, nil
	})
	_, err := fn("X", 1*time.Second)
	if err != nil {
		t.Fatalf("unexpected error: %s", err.Error())
	}
}

func TestInterceptor_UnaryServer(t *testing.T) {
	interceptor := promgrpc.NewInterceptor(nil)
	_, err := interceptor.UnaryServer()(context.Background(), nil, &grpc.UnaryServerInfo{}, func(ctx context.Context, req interface{}) (interface{}, error) {
		return nil, nil
	})
	if err != nil {
		t.Fatalf("unexpected error: %s", err.Error())
	}
}

func TestInterceptor_StreamServer(t *testing.T) {
	interceptor := promgrpc.NewInterceptor(nil)
	err := interceptor.StreamServer()(context.Background(), nil, &grpc.StreamServerInfo{}, func(srv interface{}, stream grpc.ServerStream) error {
		return nil
	})
	if err != nil {
		t.Fatalf("unexpected error: %s", err.Error())
	}
}

func TestInterceptor_UnaryClient(t *testing.T) {
	interceptor := promgrpc.NewInterceptor(nil)
	err := interceptor.UnaryClient()(context.Background(), "method", nil, nil, nil, func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, opts ...grpc.CallOption) error {
		return nil
	})
	if err != nil {
		t.Fatalf("unexpected error: %s", err.Error())
	}
}

func TestInterceptor_StreamClient(t *testing.T) {
	interceptor := promgrpc.NewInterceptor(nil)
	_, err := interceptor.StreamClient()(context.Background(), &grpc.StreamDesc{}, nil, "method", func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, opts ...grpc.CallOption) (grpc.ClientStream, error) {
		return nil, nil
	})
	if err != nil {
		t.Fatalf("unexpected error: %s", err.Error())
	}
}
<|endoftext|>


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

package proptools

import (
	"fmt"
	"reflect"
	"sync"
	"sync/atomic"
)

func CloneProperties(structValue reflect.Value) reflect.Value {
	result := reflect.New(structValue.Type())
	CopyProperties(result.Elem(), structValue)
	return result
}

func CopyProperties(dstValue, srcValue reflect.Value) {
	typ := dstValue.Type()
	if srcValue.Type() != typ {
		panic(fmt.Errorf("can't copy mismatching types (%s <- %s)",
			dstValue.Kind(), srcValue.Kind()))
	}

	for i, field := range typeFields(typ) {
		if field.PkgPath != "" {
			// The field is not exported so just skip it.
			continue
		}

		srcFieldValue := srcValue.Field(i)
		dstFieldValue := dstValue.Field(i)
		dstFieldInterfaceValue := reflect.Value{}
		origDstFieldValue := dstFieldValue

		switch srcFieldValue.Kind() {
		case reflect.Bool, reflect.String, reflect.Int, reflect.Uint:
			dstFieldValue.Set(srcFieldValue)
		case reflect.Struct:
			CopyProperties(dstFieldValue, srcFieldValue)
		case reflect.Slice:
			if !srcFieldValue.IsNil() {
				if srcFieldValue != dstFieldValue {
					newSlice := reflect.MakeSlice(field.Type, srcFieldValue.Len(),
						srcFieldValue.Len())
					reflect.Copy(newSlice, srcFieldValue)
					dstFieldValue.Set(newSlice)
				}
			} else {
				dstFieldValue.Set(srcFieldValue)
			}
		case reflect.Interface:
			if srcFieldValue.IsNil() {
				dstFieldValue.Set(srcFieldValue)
				break
			}

			srcFieldValue = srcFieldValue.Elem()

			if srcFieldValue.Kind() != reflect.Ptr {
				panic(fmt.Errorf("can't clone field %q: interface refers to a non-pointer",
					field.Name))
			}
			if srcFieldValue.Type().Elem().Kind() != reflect.Struct {
				panic(fmt.Errorf("can't clone field %q: interface points to a non-struct",
					field.Name))
			}

			if dstFieldValue.IsNil() || dstFieldValue.Elem().Type() != srcFieldValue.Type() {
				// We can't use the existing destination allocation, so
				// clone a new one.
				newValue := reflect.New(srcFieldValue.Type()).Elem()
				dstFieldValue.Set(newValue)
				dstFieldInterfaceValue = dstFieldValue
				dstFieldValue = newValue
			} else {
				dstFieldValue = dstFieldValue.Elem()
			}
			fallthrough
		case reflect.Ptr:
			if srcFieldValue.IsNil() {
				origDstFieldValue.Set(srcFieldValue)
				break
			}

			srcFieldValue := srcFieldValue.Elem()

			switch srcFieldValue.Kind() {
			case reflect.Struct:
				if !dstFieldValue.IsNil() {
					// Re-use the existing allocation.
					CopyProperties(dstFieldValue.Elem(), srcFieldValue)
					break
				} else {
					newValue := CloneProperties(srcFieldValue)
					if dstFieldInterfaceValue.IsValid() {
						dstFieldInterfaceValue.Set(newValue)
					} else {
						origDstFieldValue.Set(newValue)
					}
				}
			case reflect.Bool, reflect.Int64, reflect.String:
				newValue := reflect.New(srcFieldValue.Type())
				newValue.Elem().Set(srcFieldValue)
				origDstFieldValue.Set(newValue)
			default:
				panic(fmt.Errorf("can't clone field %q: points to a %s",
					field.Name, srcFieldValue.Kind()))
			}
		default:
			panic(fmt.Errorf("unexpected kind for property struct field %q: %s",
				field.Name, srcFieldValue.Kind()))
		}
	}
}

func ZeroProperties(structValue reflect.Value) {
	typ := structValue.Type()

	for i, field := range typeFields(typ) {
		if field.PkgPath != "" {
			// The field is not exported so just skip it.
			continue
		}

		fieldValue := structValue.Field(i)

		switch fieldValue.Kind() {
		case reflect.Bool, reflect.String, reflect.Slice, reflect.Int, reflect.Uint:
			fieldValue.Set(reflect.Zero(fieldValue.Type()))
		case reflect.Interface:
			if fieldValue.IsNil() {
				break
			}

			// We leave the pointer intact and zero out the struct that's
			// pointed to.
			fieldValue = fieldValue.Elem()
			if fieldValue.Kind() != reflect.Ptr {
				panic(fmt.Errorf("can't zero field %q: interface refers to a non-pointer",
					field.Name))
			}
			if fieldValue.Type().Elem().Kind() != reflect.Struct {
				panic(fmt.Errorf("can't zero field %q: interface points to a non-struct",
					field.Name))
			}
			fallthrough
		case reflect.Ptr:
			switch fieldValue.Type().Elem().Kind() {
			case reflect.Struct:
				if fieldValue.IsNil() {
					break
				}
				ZeroProperties(fieldValue.Elem())
			case reflect.Bool, reflect.Int64, reflect.String:
				fieldValue.Set(reflect.Zero(fieldValue.Type()))
			default:
				panic(fmt.Errorf("can't zero field %q: points to a %s",
					field.Name, fieldValue.Elem().Kind()))
			}
		case reflect.Struct:
			ZeroProperties(fieldValue)
		default:
			panic(fmt.Errorf("unexpected kind for property struct field %q: %s",
				field.Name, fieldValue.Kind()))
		}
	}
}

func CloneEmptyProperties(structValue reflect.Value) reflect.Value {
	result := reflect.New(structValue.Type())
	cloneEmptyProperties(result.Elem(), structValue)
	return result
}

func cloneEmptyProperties(dstValue, srcValue reflect.Value) {
	typ := srcValue.Type()
	for i, field := range typeFields(typ) {
		if field.PkgPath != "" {
			// The field is not exported so just skip it.
			continue
		}

		srcFieldValue := srcValue.Field(i)
		dstFieldValue := dstValue.Field(i)
		dstFieldInterfaceValue := reflect.Value{}

		switch srcFieldValue.Kind() {
		case reflect.Bool, reflect.String, reflect.Slice, reflect.Int, reflect.Uint:
			// Nothing
		case reflect.Struct:
			cloneEmptyProperties(dstFieldValue, srcFieldValue)
		case reflect.Interface:
			if srcFieldValue.IsNil() {
				break
			}

			srcFieldValue = srcFieldValue.Elem()
			if srcFieldValue.Kind() != reflect.Ptr {
				panic(fmt.Errorf("can't clone empty field %q: interface refers to a non-pointer",
					field.Name))
			}
			if srcFieldValue.Type().Elem().Kind() != reflect.Struct {
				panic(fmt.Errorf("can't clone empty field %q: interface points to a non-struct",
					field.Name))
			}

			newValue := reflect.New(srcFieldValue.Type()).Elem()
			dstFieldValue.Set(newValue)
			dstFieldInterfaceValue = dstFieldValue
			dstFieldValue = newValue
			fallthrough
		case reflect.Ptr:
			switch srcFieldValue.Type().Elem().Kind() {
			case reflect.Struct:
				if srcFieldValue.IsNil() {
					break
				}
				newValue := CloneEmptyProperties(srcFieldValue.Elem())
				if dstFieldInterfaceValue.IsValid() {
					dstFieldInterfaceValue.Set(newValue)
				} else {
					dstFieldValue.Set(newValue)
				}
			case reflect.Bool, reflect.Int64, reflect.String:
				// Nothing
			default:
				panic(fmt.Errorf("can't clone empty field %q: points to a %s",
					field.Name, srcFieldValue.Elem().Kind()))
			}

		default:
			panic(fmt.Errorf("unexpected kind for property struct field %q: %s",
				field.Name, srcFieldValue.Kind()))
		}
	}
}

// reflect.Type.Field allocates a []int{} to hold the index every time it is called, which ends up
// being a significant portion of the GC pressure.  It can't reuse the same one in case a caller
// modifies the backing array through the slice.  Since we don't modify it, cache the result
// locally to reduce allocations.
type typeFieldMap map[reflect.Type][]reflect.StructField

var (
	// Stores an atomic pointer to map caching Type to its StructField
	typeFieldCache atomic.Value
	// Lock used by slow path updating the cache pointer
	typeFieldCacheWriterLock sync.Mutex
)

func init() {
	typeFieldCache.Store(make(typeFieldMap))
}

func typeFields(typ reflect.Type) []reflect.StructField {
	// Fast path
	cache := typeFieldCache.Load().(typeFieldMap)
	if typeFields, ok := cache[typ]; ok {
		return typeFields
	}

	// Slow path
	typeFields := make([]reflect.StructField, typ.NumField())

	for i := range typeFields {
		typeFields[i] = typ.Field(i)
	}

	typeFieldCacheWriterLock.Lock()
	defer typeFieldCacheWriterLock.Unlock()

	old := typeFieldCache.Load().(typeFieldMap)
	cache = make(typeFieldMap)
	for k, v := range old {
		cache[k] = v
	}

	cache[typ] = typeFields

	typeFieldCache.Store(cache)

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

package proptools

import (
	"fmt"
	"reflect"
	"sync"
)

func CloneProperties(structValue reflect.Value) reflect.Value {
	result := reflect.New(structValue.Type())
	CopyProperties(result.Elem(), structValue)
	return result
}

func CopyProperties(dstValue, srcValue reflect.Value) {
	typ := dstValue.Type()
	if srcValue.Type() != typ {
		panic(fmt.Errorf("can't copy mismatching types (%s <- %s)",
			dstValue.Kind(), srcValue.Kind()))
	}

	for i, field := range typeFields(typ) {
		if field.PkgPath != "" {
			// The field is not exported so just skip it.
			continue
		}

		srcFieldValue := srcValue.Field(i)
		dstFieldValue := dstValue.Field(i)
		dstFieldInterfaceValue := reflect.Value{}
		origDstFieldValue := dstFieldValue

		switch srcFieldValue.Kind() {
		case reflect.Bool, reflect.String, reflect.Int, reflect.Uint:
			dstFieldValue.Set(srcFieldValue)
		case reflect.Struct:
			CopyProperties(dstFieldValue, srcFieldValue)
		case reflect.Slice:
			if !srcFieldValue.IsNil() {
				if srcFieldValue != dstFieldValue {
					newSlice := reflect.MakeSlice(field.Type, srcFieldValue.Len(),
						srcFieldValue.Len())
					reflect.Copy(newSlice, srcFieldValue)
					dstFieldValue.Set(newSlice)
				}
			} else {
				dstFieldValue.Set(srcFieldValue)
			}
		case reflect.Interface:
			if srcFieldValue.IsNil() {
				dstFieldValue.Set(srcFieldValue)
				break
			}

			srcFieldValue = srcFieldValue.Elem()

			if srcFieldValue.Kind() != reflect.Ptr {
				panic(fmt.Errorf("can't clone field %q: interface refers to a non-pointer",
					field.Name))
			}
			if srcFieldValue.Type().Elem().Kind() != reflect.Struct {
				panic(fmt.Errorf("can't clone field %q: interface points to a non-struct",
					field.Name))
			}

			if dstFieldValue.IsNil() || dstFieldValue.Elem().Type() != srcFieldValue.Type() {
				// We can't use the existing destination allocation, so
				// clone a new one.
				newValue := reflect.New(srcFieldValue.Type()).Elem()
				dstFieldValue.Set(newValue)
				dstFieldInterfaceValue = dstFieldValue
				dstFieldValue = newValue
			} else {
				dstFieldValue = dstFieldValue.Elem()
			}
			fallthrough
		case reflect.Ptr:
			if srcFieldValue.IsNil() {
				origDstFieldValue.Set(srcFieldValue)
				break
			}

			srcFieldValue := srcFieldValue.Elem()

			switch srcFieldValue.Kind() {
			case reflect.Struct:
				if !dstFieldValue.IsNil() {
					// Re-use the existing allocation.
					CopyProperties(dstFieldValue.Elem(), srcFieldValue)
					break
				} else {
					newValue := CloneProperties(srcFieldValue)
					if dstFieldInterfaceValue.IsValid() {
						dstFieldInterfaceValue.Set(newValue)
					} else {
						origDstFieldValue.Set(newValue)
					}
				}
			case reflect.Bool, reflect.Int64, reflect.String:
				newValue := reflect.New(srcFieldValue.Type())
				newValue.Elem().Set(srcFieldValue)
				origDstFieldValue.Set(newValue)
			default:
				panic(fmt.Errorf("can't clone field %q: points to a %s",
					field.Name, srcFieldValue.Kind()))
			}
		default:
			panic(fmt.Errorf("unexpected kind for property struct field %q: %s",
				field.Name, srcFieldValue.Kind()))
		}
	}
}

func ZeroProperties(structValue reflect.Value) {
	typ := structValue.Type()

	for i, field := range typeFields(typ) {
		if field.PkgPath != "" {
			// The field is not exported so just skip it.
			continue
		}

		fieldValue := structValue.Field(i)

		switch fieldValue.Kind() {
		case reflect.Bool, reflect.String, reflect.Slice, reflect.Int, reflect.Uint:
			fieldValue.Set(reflect.Zero(fieldValue.Type()))
		case reflect.Interface:
			if fieldValue.IsNil() {
				break
			}

			// We leave the pointer intact and zero out the struct that's
			// pointed to.
			fieldValue = fieldValue.Elem()
			if fieldValue.Kind() != reflect.Ptr {
				panic(fmt.Errorf("can't zero field %q: interface refers to a non-pointer",
					field.Name))
			}
			if fieldValue.Type().Elem().Kind() != reflect.Struct {
				panic(fmt.Errorf("can't zero field %q: interface points to a non-struct",
					field.Name))
			}
			fallthrough
		case reflect.Ptr:
			switch fieldValue.Type().Elem().Kind() {
			case reflect.Struct:
				if fieldValue.IsNil() {
					break
				}
				ZeroProperties(fieldValue.Elem())
			case reflect.Bool, reflect.Int64, reflect.String:
				fieldValue.Set(reflect.Zero(fieldValue.Type()))
			default:
				panic(fmt.Errorf("can't zero field %q: points to a %s",
					field.Name, fieldValue.Elem().Kind()))
			}
		case reflect.Struct:
			ZeroProperties(fieldValue)
		default:
			panic(fmt.Errorf("unexpected kind for property struct field %q: %s",
				field.Name, fieldValue.Kind()))
		}
	}
}

func CloneEmptyProperties(structValue reflect.Value) reflect.Value {
	result := reflect.New(structValue.Type())
	cloneEmptyProperties(result.Elem(), structValue)
	return result
}

func cloneEmptyProperties(dstValue, srcValue reflect.Value) {
	typ := srcValue.Type()
	for i, field := range typeFields(typ) {
		if field.PkgPath != "" {
			// The field is not exported so just skip it.
			continue
		}

		srcFieldValue := srcValue.Field(i)
		dstFieldValue := dstValue.Field(i)
		dstFieldInterfaceValue := reflect.Value{}

		switch srcFieldValue.Kind() {
		case reflect.Bool, reflect.String, reflect.Slice, reflect.Int, reflect.Uint:
			// Nothing
		case reflect.Struct:
			cloneEmptyProperties(dstFieldValue, srcFieldValue)
		case reflect.Interface:
			if srcFieldValue.IsNil() {
				break
			}

			srcFieldValue = srcFieldValue.Elem()
			if srcFieldValue.Kind() != reflect.Ptr {
				panic(fmt.Errorf("can't clone empty field %q: interface refers to a non-pointer",
					field.Name))
			}
			if srcFieldValue.Type().Elem().Kind() != reflect.Struct {
				panic(fmt.Errorf("can't clone empty field %q: interface points to a non-struct",
					field.Name))
			}

			newValue := reflect.New(srcFieldValue.Type()).Elem()
			dstFieldValue.Set(newValue)
			dstFieldInterfaceValue = dstFieldValue
			dstFieldValue = newValue
			fallthrough
		case reflect.Ptr:
			switch srcFieldValue.Type().Elem().Kind() {
			case reflect.Struct:
				if srcFieldValue.IsNil() {
					break
				}
				newValue := CloneEmptyProperties(srcFieldValue.Elem())
				if dstFieldInterfaceValue.IsValid() {
					dstFieldInterfaceValue.Set(newValue)
				} else {
					dstFieldValue.Set(newValue)
				}
			case reflect.Bool, reflect.Int64, reflect.String:
				// Nothing
			default:
				panic(fmt.Errorf("can't clone empty field %q: points to a %s",
					field.Name, srcFieldValue.Elem().Kind()))
			}

		default:
			panic(fmt.Errorf("unexpected kind for property struct field %q: %s",
				field.Name, srcFieldValue.Kind()))
		}
	}
}

var typeFieldCache sync.Map

func typeFields(typ reflect.Type) []reflect.StructField {
	// reflect.Type.Field allocates a []int{} to hold the index every time it is called, which ends up
	// being a significant portion of the GC pressure.  It can't reuse the same one in case a caller
	// modifies the backing array through the slice.  Since we don't modify it, cache the result
	// locally to reduce allocations.

	// Fast path
	if typeFields, ok := typeFieldCache.Load(typ); ok {
		return typeFields.([]reflect.StructField)
	}

	// Slow path
	typeFields := make([]reflect.StructField, typ.NumField())

	for i := range typeFields {
		typeFields[i] = typ.Field(i)
	}

	typeFieldCache.Store(typ, typeFields)

	return typeFields
}
<|endoftext|>


<commit_before>package gophercloud

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
)

// DefaultUserAgent is the default User-Agent string set in the request header.
const DefaultUserAgent = "gophercloud/v1.0"

// UserAgent represents a User-Agent header.
type UserAgent struct {
	// prepend is the slice of User-Agent strings to prepend to DefaultUserAgent.
	// All the strings to prepend are accumulated and prepended in the Join method.
	prepend []string
}

// Prepend prepends a user-defined string to the default User-Agent string. Users
// may pass in one or more strings to prepend.
func (ua *UserAgent) Prepend(s ...string) {
	ua.prepend = append(s, ua.prepend...)
}

// Join concatenates all the user-defined User-Agend strings with the default
// Gophercloud User-Agent string.
func (ua *UserAgent) Join() string {
	uaSlice := append(ua.prepend, DefaultUserAgent)
	return strings.Join(uaSlice, " ")
}

// ProviderClient stores details that are required to interact with any
// services within a specific provider's API.
//
// Generally, you acquire a ProviderClient by calling the NewClient method in
// the appropriate provider's child package, providing whatever authentication
// credentials are required.
type ProviderClient struct {
	// IdentityBase is the base URL used for a particular provider's identity
	// service - it will be used when issuing authenticatation requests. It
	// should point to the root resource of the identity service, not a specific
	// identity version.
	IdentityBase string

	// IdentityEndpoint is the identity endpoint. This may be a specific version
	// of the identity service. If this is the case, this endpoint is used rather
	// than querying versions first.
	IdentityEndpoint string

	// TokenID is the ID of the most recently issued valid token.
	TokenID string

	// EndpointLocator describes how this provider discovers the endpoints for
	// its constituent services.
	EndpointLocator EndpointLocator

	// HTTPClient allows users to interject arbitrary http, https, or other transit behaviors.
	HTTPClient http.Client

	// UserAgent represents the User-Agent header in the HTTP request.
	UserAgent UserAgent

	// ReauthFunc is the function used to re-authenticate the user if the request
	// fails with a 401 HTTP response code. This a needed because there may be multiple
	// authentication functions for different Identity service versions.
	ReauthFunc func() error
}

// AuthenticatedHeaders returns a map of HTTP headers that are common for all
// authenticated service requests.
func (client *ProviderClient) AuthenticatedHeaders() map[string]string {
	if client.TokenID == "" {
		return map[string]string{}
	}
	return map[string]string{"X-Auth-Token": client.TokenID}
}

// RequestOpts customizes the behavior of the provider.Request() method.
type RequestOpts struct {
	// JSONBody, if provided, will be encoded as JSON and used as the body of the HTTP request. The
	// content type of the request will default to "application/json" unless overridden by MoreHeaders.
	// It's an error to specify both a JSONBody and a RawBody.
	JSONBody interface{}
	// RawBody contains an io.Reader that will be consumed by the request directly. No content-type
	// will be set unless one is provided explicitly by MoreHeaders.
	RawBody io.Reader

	// JSONResponse, if provided, will be populated with the contents of the response body parsed as
	// JSON.
	JSONResponse interface{}
	// OkCodes contains a list of numeric HTTP status codes that should be interpreted as success. If
	// the response has a different code, an error will be returned.
	OkCodes []int

	// MoreHeaders specifies additional HTTP headers to be provide on the request. If a header is
	// provided with a blank value (""), that header will be *omitted* instead: use this to suppress
	// the default Accept header or an inferred Content-Type, for example.
	MoreHeaders map[string]string
}

// UnexpectedResponseCodeError is returned by the Request method when a response code other than
// those listed in OkCodes is encountered.
type UnexpectedResponseCodeError struct {
	URL      string
	Method   string
	Expected []int
	Actual   int
	Body     []byte
}

func (err *UnexpectedResponseCodeError) Error() string {
	return fmt.Sprintf(
		"Expected HTTP response code %v when accessing [%s %s], but got %d instead\n%s",
		err.Expected, err.Method, err.URL, err.Actual, err.Body,
	)
}

var applicationJSON = "application/json"

// Request performs an HTTP request using the ProviderClient's current HTTPClient. An authentication
// header will automatically be provided.
func (client *ProviderClient) Request(method, url string, options RequestOpts) (*http.Response, error) {
	var body io.Reader
	var contentType *string

	// Derive the content body by either encoding an arbitrary object as JSON, or by taking a provided
	// io.Reader as-is. Default the content-type to application/json.
	if options.JSONBody != nil {
		if options.RawBody != nil {
			panic("Please provide only one of JSONBody or RawBody to gophercloud.Request().")
		}

		rendered, err := json.Marshal(options.JSONBody)
		if err != nil {
			return nil, err
		}

		body = bytes.NewReader(rendered)
		contentType = &applicationJSON
	}

	if options.RawBody != nil {
		body = options.RawBody
	}

	// Construct the http.Request.
	req, err := http.NewRequest(method, url, body)
	if err != nil {
		return nil, err
	}

	// Populate the request headers. Apply options.MoreHeaders last, to give the caller the chance to
	// modify or omit any header.
	if contentType != nil {
		req.Header.Set("Content-Type", *contentType)
	}
	req.Header.Set("Accept", applicationJSON)

	for k, v := range client.AuthenticatedHeaders() {
		req.Header.Add(k, v)
	}

	// Set the User-Agent header
	req.Header.Set("User-Agent", client.UserAgent.Join())

	if options.MoreHeaders != nil {
		for k, v := range options.MoreHeaders {
			if v != "" {
				req.Header.Set(k, v)
			} else {
				req.Header.Del(k)
			}
		}
	}

	// Issue the request.
	resp, err := client.HTTPClient.Do(req)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode == http.StatusUnauthorized {
		if client.ReauthFunc != nil {
			err = client.ReauthFunc()
			if err != nil {
				return nil, fmt.Errorf("Error trying to re-authenticate: %s", err)
			}
			resp, err = client.Request(method, url, options)
			if err != nil {
				return nil, fmt.Errorf("Successfully re-authenticated, but got error executing request: %s", err)
			}
		}
	}

	// Allow default OkCodes if none explicitly set
	if options.OkCodes == nil {
		options.OkCodes = defaultOkCodes(method)
	}

	// Validate the HTTP response status.
	var ok bool
	for _, code := range options.OkCodes {
		if resp.StatusCode == code {
			ok = true
			break
		}
	}
	if !ok {
		body, _ := ioutil.ReadAll(resp.Body)
		resp.Body.Close()
		return resp, &UnexpectedResponseCodeError{
			URL:      url,
			Method:   method,
			Expected: options.OkCodes,
			Actual:   resp.StatusCode,
			Body:     body,
		}
	}

	// Parse the response body as JSON, if requested to do so.
	if options.JSONResponse != nil {
		defer resp.Body.Close()
		json.NewDecoder(resp.Body).Decode(options.JSONResponse)
	}

	return resp, nil
}

func defaultOkCodes(method string) []int {
	switch {
	case method == "GET":
		return []int{200}
	case method == "POST":
		return []int{201, 202}
	case method == "PUT":
		return []int{201, 202}
	case method == "DELETE":
		return []int{202, 204}
	}

	return []int{}
}
<commit_msg>Add convenience methods for HTTP operations<commit_after>package gophercloud

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"net/http"
	"strings"
)

// DefaultUserAgent is the default User-Agent string set in the request header.
const DefaultUserAgent = "gophercloud/v1.0"

// UserAgent represents a User-Agent header.
type UserAgent struct {
	// prepend is the slice of User-Agent strings to prepend to DefaultUserAgent.
	// All the strings to prepend are accumulated and prepended in the Join method.
	prepend []string
}

// Prepend prepends a user-defined string to the default User-Agent string. Users
// may pass in one or more strings to prepend.
func (ua *UserAgent) Prepend(s ...string) {
	ua.prepend = append(s, ua.prepend...)
}

// Join concatenates all the user-defined User-Agend strings with the default
// Gophercloud User-Agent string.
func (ua *UserAgent) Join() string {
	uaSlice := append(ua.prepend, DefaultUserAgent)
	return strings.Join(uaSlice, " ")
}

// ProviderClient stores details that are required to interact with any
// services within a specific provider's API.
//
// Generally, you acquire a ProviderClient by calling the NewClient method in
// the appropriate provider's child package, providing whatever authentication
// credentials are required.
type ProviderClient struct {
	// IdentityBase is the base URL used for a particular provider's identity
	// service - it will be used when issuing authenticatation requests. It
	// should point to the root resource of the identity service, not a specific
	// identity version.
	IdentityBase string

	// IdentityEndpoint is the identity endpoint. This may be a specific version
	// of the identity service. If this is the case, this endpoint is used rather
	// than querying versions first.
	IdentityEndpoint string

	// TokenID is the ID of the most recently issued valid token.
	TokenID string

	// EndpointLocator describes how this provider discovers the endpoints for
	// its constituent services.
	EndpointLocator EndpointLocator

	// HTTPClient allows users to interject arbitrary http, https, or other transit behaviors.
	HTTPClient http.Client

	// UserAgent represents the User-Agent header in the HTTP request.
	UserAgent UserAgent

	// ReauthFunc is the function used to re-authenticate the user if the request
	// fails with a 401 HTTP response code. This a needed because there may be multiple
	// authentication functions for different Identity service versions.
	ReauthFunc func() error
}

// AuthenticatedHeaders returns a map of HTTP headers that are common for all
// authenticated service requests.
func (client *ProviderClient) AuthenticatedHeaders() map[string]string {
	if client.TokenID == "" {
		return map[string]string{}
	}
	return map[string]string{"X-Auth-Token": client.TokenID}
}

// RequestOpts customizes the behavior of the provider.Request() method.
type RequestOpts struct {
	// JSONBody, if provided, will be encoded as JSON and used as the body of the HTTP request. The
	// content type of the request will default to "application/json" unless overridden by MoreHeaders.
	// It's an error to specify both a JSONBody and a RawBody.
	JSONBody interface{}
	// RawBody contains an io.Reader that will be consumed by the request directly. No content-type
	// will be set unless one is provided explicitly by MoreHeaders.
	RawBody io.Reader

	// JSONResponse, if provided, will be populated with the contents of the response body parsed as
	// JSON.
	JSONResponse interface{}
	// OkCodes contains a list of numeric HTTP status codes that should be interpreted as success. If
	// the response has a different code, an error will be returned.
	OkCodes []int

	// MoreHeaders specifies additional HTTP headers to be provide on the request. If a header is
	// provided with a blank value (""), that header will be *omitted* instead: use this to suppress
	// the default Accept header or an inferred Content-Type, for example.
	MoreHeaders map[string]string
}

// UnexpectedResponseCodeError is returned by the Request method when a response code other than
// those listed in OkCodes is encountered.
type UnexpectedResponseCodeError struct {
	URL      string
	Method   string
	Expected []int
	Actual   int
	Body     []byte
}

func (err *UnexpectedResponseCodeError) Error() string {
	return fmt.Sprintf(
		"Expected HTTP response code %v when accessing [%s %s], but got %d instead\n%s",
		err.Expected, err.Method, err.URL, err.Actual, err.Body,
	)
}

var applicationJSON = "application/json"

// Request performs an HTTP request using the ProviderClient's current HTTPClient. An authentication
// header will automatically be provided.
func (client *ProviderClient) Request(method, url string, options RequestOpts) (*http.Response, error) {
	var body io.Reader
	var contentType *string

	// Derive the content body by either encoding an arbitrary object as JSON, or by taking a provided
	// io.Reader as-is. Default the content-type to application/json.
	if options.JSONBody != nil {
		if options.RawBody != nil {
			panic("Please provide only one of JSONBody or RawBody to gophercloud.Request().")
		}

		rendered, err := json.Marshal(options.JSONBody)
		if err != nil {
			return nil, err
		}

		body = bytes.NewReader(rendered)
		contentType = &applicationJSON
	}

	if options.RawBody != nil {
		body = options.RawBody
	}

	// Construct the http.Request.
	req, err := http.NewRequest(method, url, body)
	if err != nil {
		return nil, err
	}

	// Populate the request headers. Apply options.MoreHeaders last, to give the caller the chance to
	// modify or omit any header.
	if contentType != nil {
		req.Header.Set("Content-Type", *contentType)
	}
	req.Header.Set("Accept", applicationJSON)

	for k, v := range client.AuthenticatedHeaders() {
		req.Header.Add(k, v)
	}

	// Set the User-Agent header
	req.Header.Set("User-Agent", client.UserAgent.Join())

	if options.MoreHeaders != nil {
		for k, v := range options.MoreHeaders {
			if v != "" {
				req.Header.Set(k, v)
			} else {
				req.Header.Del(k)
			}
		}
	}

	// Issue the request.
	resp, err := client.HTTPClient.Do(req)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode == http.StatusUnauthorized {
		if client.ReauthFunc != nil {
			err = client.ReauthFunc()
			if err != nil {
				return nil, fmt.Errorf("Error trying to re-authenticate: %s", err)
			}
			resp, err = client.Request(method, url, options)
			if err != nil {
				return nil, fmt.Errorf("Successfully re-authenticated, but got error executing request: %s", err)
			}
		}
	}

	// Allow default OkCodes if none explicitly set
	if options.OkCodes == nil {
		options.OkCodes = defaultOkCodes(method)
	}

	// Validate the HTTP response status.
	var ok bool
	for _, code := range options.OkCodes {
		if resp.StatusCode == code {
			ok = true
			break
		}
	}
	if !ok {
		body, _ := ioutil.ReadAll(resp.Body)
		resp.Body.Close()
		return resp, &UnexpectedResponseCodeError{
			URL:      url,
			Method:   method,
			Expected: options.OkCodes,
			Actual:   resp.StatusCode,
			Body:     body,
		}
	}

	// Parse the response body as JSON, if requested to do so.
	if options.JSONResponse != nil {
		defer resp.Body.Close()
		json.NewDecoder(resp.Body).Decode(options.JSONResponse)
	}

	return resp, nil
}

func defaultOkCodes(method string) []int {
	switch {
	case method == "GET":
		return []int{200}
	case method == "POST":
		return []int{201, 202}
	case method == "PUT":
		return []int{201, 202}
	case method == "DELETE":
		return []int{202, 204}
	}

	return []int{}
}

func (client *ProviderClient) Get(url string, JSONResponse *interface{}, opts *RequestOpts) (*http.Response, error) {
	if opts == nil {
		opts = &RequestOpts{}
	}
	if JSONResponse != nil {
		opts.JSONResponse = JSONResponse
	}
	return client.Request("GET", url, *opts)
}

func (client *ProviderClient) Post(url string, JSONBody interface{}, JSONResponse *interface{}, opts *RequestOpts) (*http.Response, error) {
	if opts == nil {
		opts = &RequestOpts{}
	}

	if v, ok := (JSONBody).(io.Reader); ok == true {
		opts.RawBody = v
	} else if JSONBody != nil {
		opts.JSONBody = JSONBody
	}

	if JSONResponse != nil {
		opts.JSONResponse = JSONResponse
	}

	return client.Request("POST", url, *opts)
}

func (client *ProviderClient) Put(url string, JSONBody interface{}, JSONResponse *interface{}, opts *RequestOpts) (*http.Response, error) {
	if opts == nil {
		opts = &RequestOpts{}
	}

	if v, ok := (JSONBody).(io.Reader); ok == true {
		opts.RawBody = v
	} else if JSONBody != nil {
		opts.JSONBody = JSONBody
	}

	if JSONResponse != nil {
		opts.JSONResponse = JSONResponse
	}

	return client.Request("PUT", url, *opts)
}

func (client *ProviderClient) Delete(url string, opts *RequestOpts) (*http.Response, error) {
	if opts == nil {
		opts = &RequestOpts{}
	}

	return client.Request("DELETE", url, *opts)
}
<|endoftext|>


<commit_before>// wc -- print byte, line, or word counts for files
// Part of goutils (https://github.com/trevorparker/goutils)
//
// Copyright (c) 2014 Trevor Parker <trevor@trevorparker.com>
// All rights reserved
//
// Distributed under the terms of the Modified BSD License (see LICENSE)

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

type arg struct {
	count_bytes bool
	count_lines bool
	count_words bool
	file        []string
}

const (
	usage_message string = "usage: wc [OPTION ...] [FILE ...]"
	help_message  string = `Count bytes, lines, or words for FILE or STDIN to STDOUT.

  -c, --bytes     count bytes
  -l, --lines     count newlines
  -w, --words     count words
  -h, --help      print this help message and exit
`
)

func usage(error string) {
	fmt.Fprintf(os.Stderr, "wc: %s\n%s\n", error, usage_message)
	os.Exit(1)
}

func help() {
	fmt.Printf("%s\n%s", usage_message, help_message)
	os.Exit(0)
}

func wc(file io.Reader, args arg, size int64) int64 {
	// Default the count to the size passed in (i.e.: stat() on a file)
	c := size

	if file == nil {
		file = os.Stdin
	}

	// Count bytes coming in through STDIN
	if c == 0 && args.count_bytes {
		s := bufio.NewScanner(file)
		s.Split(bufio.ScanBytes)
		for s.Scan() {
			c++
		}
	}

	// Count lines or words on STDIN or in the file passed in
	if args.count_lines && !args.count_bytes {
		c = 0
		s := bufio.NewScanner(file)
		s.Split(bufio.ScanLines)
		for s.Scan() {
			c++
		}
	} else if args.count_words && !args.count_bytes {
		c = 0
		s := bufio.NewScanner(file)
		s.Split(bufio.ScanWords)
		for s.Scan() {
			c++
		}
	}

	return c
}

func main() {
	args := arg{false, false, false, []string{}}
	reached_files := false
	for i := 1; i < len(os.Args); i++ {
		if reached_files == false {
			if os.Args[i] == "-h" || os.Args[i] == "--help" {
				help()
			}
			if os.Args[i] == "-c" || os.Args[i] == "--bytes" {
				args.count_bytes = true
				continue
			}
			if os.Args[i] == "-l" || os.Args[i] == "--lines" {
				args.count_lines = true
				continue
			}
			if os.Args[i] == "-w" || os.Args[i] == "--words" {
				args.count_words = true
				continue
			}
		}
		arg_v := os.Args[i]
		reached_files = true
		args.file = append(args.file, arg_v)
	}

	for i := range args.file {
		if len(args.file) == 0 || args.file[0] == "-" {
			count := wc(nil, args, 0)
			fmt.Fprintf(os.Stdout, "%d\n", count)
		} else {
			// Call stat() on the file to help byte count performance
			file, err := os.Open(args.file[i])
			stat, err := file.Stat()
			size := stat.Size()
			if err != nil {
				panic(err)
			}

			count := wc(file, args, size)
			fmt.Fprintf(os.Stdout, "%d %s\n", count, args.file[i])
		}
	}
}
<commit_msg>The arg `-` should refer to STDIN at any position<commit_after>// wc -- print byte, line, or word counts for files
// Part of goutils (https://github.com/trevorparker/goutils)
//
// Copyright (c) 2014 Trevor Parker <trevor@trevorparker.com>
// All rights reserved
//
// Distributed under the terms of the Modified BSD License (see LICENSE)

package main

import (
	"bufio"
	"fmt"
	"io"
	"os"
)

type arg struct {
	count_bytes bool
	count_lines bool
	count_words bool
	file        []string
}

const (
	usage_message string = "usage: wc [OPTION ...] [FILE ...]"
	help_message  string = `Count bytes, lines, or words for FILE or STDIN to STDOUT.

  -c, --bytes     count bytes
  -l, --lines     count newlines
  -w, --words     count words
  -h, --help      print this help message and exit
`
)

func usage(error string) {
	fmt.Fprintf(os.Stderr, "wc: %s\n%s\n", error, usage_message)
	os.Exit(1)
}

func help() {
	fmt.Printf("%s\n%s", usage_message, help_message)
	os.Exit(0)
}

func wc(file io.Reader, args arg, size int64) int64 {
	// Default the count to the size passed in (i.e.: stat() on a file)
	c := size

	if file == nil {
		file = os.Stdin
	}

	// Count bytes coming in through STDIN
	if c == 0 && args.count_bytes {
		s := bufio.NewScanner(file)
		s.Split(bufio.ScanBytes)
		for s.Scan() {
			c++
		}
	}

	// Count lines or words on STDIN or in the file passed in
	if args.count_lines && !args.count_bytes {
		c = 0
		s := bufio.NewScanner(file)
		s.Split(bufio.ScanLines)
		for s.Scan() {
			c++
		}
	} else if args.count_words && !args.count_bytes {
		c = 0
		s := bufio.NewScanner(file)
		s.Split(bufio.ScanWords)
		for s.Scan() {
			c++
		}
	}

	return c
}

func main() {
	args := arg{false, false, false, []string{}}
	reached_files := false
	for i := 1; i < len(os.Args); i++ {
		if reached_files == false {
			if os.Args[i] == "-h" || os.Args[i] == "--help" {
				help()
			}
			if os.Args[i] == "-c" || os.Args[i] == "--bytes" {
				args.count_bytes = true
				continue
			}
			if os.Args[i] == "-l" || os.Args[i] == "--lines" {
				args.count_lines = true
				continue
			}
			if os.Args[i] == "-w" || os.Args[i] == "--words" {
				args.count_words = true
				continue
			}
		}
		arg_v := os.Args[i]
		reached_files = true
		args.file = append(args.file, arg_v)
	}

	for i := range args.file {
		if len(args.file) == 0 || args.file[i] == "-" {
			count := wc(nil, args, 0)
			fmt.Fprintf(os.Stdout, "%d\n", count)
		} else {
			// Call stat() on the file to help byte count performance
			file, err := os.Open(args.file[i])
			stat, err := file.Stat()
			size := stat.Size()
			if err != nil {
				panic(err)
			}

			count := wc(file, args, size)
			fmt.Fprintf(os.Stdout, "%d %s\n", count, args.file[i])
		}
	}
}
<|endoftext|>