<commit_before>package rpc

import (
	"bytes"
	"encoding/json"
	"math/big"

	"github.com/ethereum/go-ethereum/ethutil"
)

func blockNumber(raw json.RawMessage, number *int64) (err error) {
	var str string
	if err = json.Unmarshal(raw, &str); err != nil {
		return errDecodeArgs
	}

	switch str {
	case "latest":
		*number = -1
	case "pending":
		*number = 0
	default:
		*number = ethutil.String2Big(str).Int64()
	}
	return nil
}

type GetBlockByHashArgs struct {
	BlockHash    string
	Transactions bool
}

func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []interface{}
	r := bytes.NewReader(b)
	if err := json.NewDecoder(r).Decode(&obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 1 {
		return errArguments
	}
	args.BlockHash = obj[0].(string)

	if len(obj) > 1 {
		args.Transactions = obj[1].(bool)
	}

	return nil
}

type GetBlockByNumberArgs struct {
	BlockNumber  int64
	Transactions bool
}

func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []interface{}
	r := bytes.NewReader(b)
	if err := json.NewDecoder(r).Decode(&obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 1 {
		return errArguments
	}

	if v, ok := obj[0].(float64); ok {
		args.BlockNumber = int64(v)
	} else {
		args.BlockNumber = ethutil.Big(obj[0].(string)).Int64()
	}

	if len(obj) > 1 {
		args.Transactions = obj[1].(bool)
	}

	return nil
}

type NewTxArgs struct {
	From     string
	To       string
	Value    *big.Int
	Gas      *big.Int
	GasPrice *big.Int
	Data     string

	BlockNumber int64
}

func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
	var obj struct{ From, To, Value, Gas, GasPrice, Data string }
	if err = UnmarshalRawMessages(b, &obj, &args.BlockNumber); err != nil {
		return err
	}

	args.From = obj.From
	args.To = obj.To
	args.Value = ethutil.Big(obj.Value)
	args.Gas = ethutil.Big(obj.Gas)
	args.GasPrice = ethutil.Big(obj.GasPrice)
	args.Data = obj.Data

	return nil
}

type GetStorageArgs struct {
	Address     string
	BlockNumber int64
}

func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) {
	if err = UnmarshalRawMessages(b, &args.Address, &args.BlockNumber); err != nil {
		return errDecodeArgs
	}

	return nil
}

func (args *GetStorageArgs) requirements() error {
	if len(args.Address) == 0 {
		return NewErrorWithMessage(errArguments, "Address cannot be blank")
	}
	return nil
}

type GetStorageAtArgs struct {
	Address     string
	Key         string
	BlockNumber int64
}

func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []string
	if err = UnmarshalRawMessages(b, &obj, &args.BlockNumber); err != nil {
		return errDecodeArgs
	}
	if len(obj) < 2 {
		return errDecodeArgs
	}

	args.Address = obj[0]
	args.Key = obj[1]

	return nil
}

func (args *GetStorageAtArgs) requirements() error {
	if len(args.Address) == 0 {
		return NewErrorWithMessage(errArguments, "Address cannot be blank")
	}

	if len(args.Key) == 0 {
		return NewErrorWithMessage(errArguments, "Key cannot be blank")
	}
	return nil
}

type GetTxCountArgs struct {
	Address     string
	BlockNumber int64
}

func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) {
	if err = UnmarshalRawMessages(b, &args.Address, &args.BlockNumber); err != nil {
		return errDecodeArgs
	}

	return nil
}

func (args *GetTxCountArgs) requirements() error {
	if len(args.Address) == 0 {
		return NewErrorWithMessage(errArguments, "Address cannot be blank")
	}
	return nil
}

type GetBalanceArgs struct {
	Address     string
	BlockNumber int64
}

func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) {
	if err = UnmarshalRawMessages(b, &args.Address, &args.BlockNumber); err != nil {
		return errDecodeArgs
	}

	return nil
}

func (args *GetBalanceArgs) requirements() error {
	if len(args.Address) == 0 {
		return NewErrorWithMessage(errArguments, "Address cannot be blank")
	}
	return nil
}

type GetDataArgs struct {
	Address     string
	BlockNumber int64
}

func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) {
	if err = UnmarshalRawMessages(b, &args.Address, &args.BlockNumber); err != nil {
		return errDecodeArgs
	}

	return nil
}

func (args *GetDataArgs) requirements() error {
	if len(args.Address) == 0 {
		return NewErrorWithMessage(errArguments, "Address cannot be blank")
	}
	return nil
}

type BlockNumIndexArgs struct {
	BlockNumber int64
	Index       int64
}

type HashIndexArgs struct {
	BlockHash string
	Index     int64
}

type Sha3Args struct {
	Data string
}

func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) {
	var obj []interface{}
	r := bytes.NewReader(b)
	if err := json.NewDecoder(r).Decode(&obj); err != nil {
		return NewErrorWithMessage(errDecodeArgs, err.Error())
	}

	if len(obj) < 1 {
		return errArguments
	}
	args.Data = obj[0].(string)

	return nil
}

// type FilterArgs struct {
// 	FromBlock uint64
// 	ToBlock   uint64
// 	Limit     uint64
// 	Offset    uint64
// 	Address   string
// 	Topics    []string
// }

// func (args *FilterArgs) UnmarshalJSON(b []byte) (err error) {
// 	var obj []struct {
// 		FromBlock string   `json:"fromBlock"`
// 		ToBlock   string   `json:"toBlock"`
// 		Limit     string   `json:"limit"`
// 		Offset    string   `json:"offset"`
// 		Address   string   `json:"address"`
// 		Topics    []string `json:"topics"`
// 	}

// 	if err = json.Unmarshal(b, &obj); err != nil {
// 		return errDecodeArgs
// 	}

// 	if len(obj) < 1 {
// 		return errArguments
// 	}
// 	args.FromBlock = uint64(ethutil.Big(obj[0].FromBlock).Int64())
// 	args.ToBlock = uint64(ethutil.Big(obj[0].ToBlock).Int64())
// 	args.Limit = uint64(ethutil.Big(obj[0].Limit).Int64())
// 	args.Offset = uint64(ethutil.Big(obj[0].Offset).Int64())
// 	args.Address = obj[0].Address
// 	args.Topics = obj[0].Topics

// 	return nil
// }

type FilterOptions struct {
	Earliest int64
	Latest   int64
	Address  interface{}
	Topics   []interface{}
	Skip     int
	Max      int
}

func (args *FilterOptions) UnmarshalJSON(b []byte) (err error) {
	var obj []struct {
		FromBlock string        `json:"fromBlock"`
		ToBlock   string        `json:"toBlock"`
		Limit     string        `json:"limit"`
		Offset    string        `json:"offset"`
		Address   string        `json:"address"`
		Topics    []interface{} `json:"topics"`
	}

	if err = json.Unmarshal(b, &obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 1 {
		return errArguments
	}
	args.Earliest = int64(ethutil.Big(obj[0].FromBlock).Int64())
	args.Latest = int64(ethutil.Big(obj[0].ToBlock).Int64())
	args.Max = int(ethutil.Big(obj[0].Limit).Int64())
	args.Skip = int(ethutil.Big(obj[0].Offset).Int64())
	args.Address = obj[0].Address
	args.Topics = obj[0].Topics

	return nil
}

// type FilterChangedArgs struct {
// 	n int
// }

type DbArgs struct {
	Database string
	Key      string
	Value    string
}

func (args *DbArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []interface{}
	r := bytes.NewReader(b)
	if err := json.NewDecoder(r).Decode(&obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 2 {
		return errArguments
	}
	args.Database = obj[0].(string)
	args.Key = obj[1].(string)

	if len(obj) > 2 {
		args.Value = obj[2].(string)
	}

	return nil
}

func (a *DbArgs) requirements() error {
	if len(a.Database) == 0 {
		return NewErrorWithMessage(errArguments, "Database cannot be blank")
	}
	if len(a.Key) == 0 {
		return NewErrorWithMessage(errArguments, "Key cannot be blank")
	}
	return nil
}

type WhisperMessageArgs struct {
	Payload  string
	To       string
	From     string
	Topic    []string
	Priority uint32
	Ttl      uint32
}

func (args *WhisperMessageArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []struct {
		Payload  string
		To       string
		From     string
		Topic    []string
		Priority string
		Ttl      string
	}

	if err = json.Unmarshal(b, &obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 1 {
		return errArguments
	}
	args.Payload = obj[0].Payload
	args.To = obj[0].To
	args.From = obj[0].From
	args.Topic = obj[0].Topic
	args.Priority = uint32(ethutil.Big(obj[0].Priority).Int64())
	args.Ttl = uint32(ethutil.Big(obj[0].Ttl).Int64())

	return nil
}

type CompileArgs struct {
	Source string
}

func (args *CompileArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []interface{}
	r := bytes.NewReader(b)
	if err := json.NewDecoder(r).Decode(&obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) > 0 {
		args.Source = obj[0].(string)
	}

	return nil
}

type FilterStringArgs struct {
	Word string
}

func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []string
	r := bytes.NewReader(b)
	if err := json.NewDecoder(r).Decode(&obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 1 {
		return errDecodeArgs
	}

	args.Word = obj[0]

	return nil
}

type FilterIdArgs struct {
	Id int
}

func (args *FilterIdArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []string
	r := bytes.NewReader(b)
	if err := json.NewDecoder(r).Decode(&obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 1 {
		return errDecodeArgs
	}

	args.Id = int(ethutil.Big(obj[0]).Int64())

	return nil
}

type WhisperIdentityArgs struct {
	Identity string
}

func (args *WhisperIdentityArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []string
	r := bytes.NewReader(b)
	if err := json.NewDecoder(r).Decode(&obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 1 {
		return errDecodeArgs
	}

	args.Identity = obj[0]

	return nil
}

type WhisperFilterArgs struct {
	To     string `json:"to"`
	From   string
	Topics []string
}

func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []struct {
		To     string
		From   string
		Topics []string
	}

	if err = json.Unmarshal(b, &obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 1 {
		return errArguments
	}

	args.To = obj[0].To
	args.From = obj[0].From
	args.Topics = obj[0].Topics

	return nil
}
<commit_msg>BlockHash must be a string<commit_after>package rpc

import (
	"bytes"
	"encoding/json"
	"math/big"

	"github.com/ethereum/go-ethereum/ethutil"
)

func blockNumber(raw json.RawMessage, number *int64) (err error) {
	var str string
	if err = json.Unmarshal(raw, &str); err != nil {
		return errDecodeArgs
	}

	switch str {
	case "latest":
		*number = -1
	case "pending":
		*number = 0
	default:
		*number = ethutil.String2Big(str).Int64()
	}
	return nil
}

type GetBlockByHashArgs struct {
	BlockHash    string
	Transactions bool
}

func (args *GetBlockByHashArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []interface{}
	r := bytes.NewReader(b)
	if err := json.NewDecoder(r).Decode(&obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 1 {
		return errArguments
	}

	argstr, ok := obj[0].(string)
	if !ok {
		return errDecodeArgs
	}
	args.BlockHash = argstr

	if len(obj) > 1 {
		args.Transactions = obj[1].(bool)
	}

	return nil
}

type GetBlockByNumberArgs struct {
	BlockNumber  int64
	Transactions bool
}

func (args *GetBlockByNumberArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []interface{}
	r := bytes.NewReader(b)
	if err := json.NewDecoder(r).Decode(&obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 1 {
		return errArguments
	}

	if v, ok := obj[0].(float64); ok {
		args.BlockNumber = int64(v)
	} else {
		args.BlockNumber = ethutil.Big(obj[0].(string)).Int64()
	}

	if len(obj) > 1 {
		args.Transactions = obj[1].(bool)
	}

	return nil
}

type NewTxArgs struct {
	From     string
	To       string
	Value    *big.Int
	Gas      *big.Int
	GasPrice *big.Int
	Data     string

	BlockNumber int64
}

func (args *NewTxArgs) UnmarshalJSON(b []byte) (err error) {
	var obj struct{ From, To, Value, Gas, GasPrice, Data string }
	if err = UnmarshalRawMessages(b, &obj, &args.BlockNumber); err != nil {
		return err
	}

	args.From = obj.From
	args.To = obj.To
	args.Value = ethutil.Big(obj.Value)
	args.Gas = ethutil.Big(obj.Gas)
	args.GasPrice = ethutil.Big(obj.GasPrice)
	args.Data = obj.Data

	return nil
}

type GetStorageArgs struct {
	Address     string
	BlockNumber int64
}

func (args *GetStorageArgs) UnmarshalJSON(b []byte) (err error) {
	if err = UnmarshalRawMessages(b, &args.Address, &args.BlockNumber); err != nil {
		return errDecodeArgs
	}

	return nil
}

func (args *GetStorageArgs) requirements() error {
	if len(args.Address) == 0 {
		return NewErrorWithMessage(errArguments, "Address cannot be blank")
	}
	return nil
}

type GetStorageAtArgs struct {
	Address     string
	Key         string
	BlockNumber int64
}

func (args *GetStorageAtArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []string
	if err = UnmarshalRawMessages(b, &obj, &args.BlockNumber); err != nil {
		return errDecodeArgs
	}
	if len(obj) < 2 {
		return errDecodeArgs
	}

	args.Address = obj[0]
	args.Key = obj[1]

	return nil
}

func (args *GetStorageAtArgs) requirements() error {
	if len(args.Address) == 0 {
		return NewErrorWithMessage(errArguments, "Address cannot be blank")
	}

	if len(args.Key) == 0 {
		return NewErrorWithMessage(errArguments, "Key cannot be blank")
	}
	return nil
}

type GetTxCountArgs struct {
	Address     string
	BlockNumber int64
}

func (args *GetTxCountArgs) UnmarshalJSON(b []byte) (err error) {
	if err = UnmarshalRawMessages(b, &args.Address, &args.BlockNumber); err != nil {
		return errDecodeArgs
	}

	return nil
}

func (args *GetTxCountArgs) requirements() error {
	if len(args.Address) == 0 {
		return NewErrorWithMessage(errArguments, "Address cannot be blank")
	}
	return nil
}

type GetBalanceArgs struct {
	Address     string
	BlockNumber int64
}

func (args *GetBalanceArgs) UnmarshalJSON(b []byte) (err error) {
	if err = UnmarshalRawMessages(b, &args.Address, &args.BlockNumber); err != nil {
		return errDecodeArgs
	}

	return nil
}

func (args *GetBalanceArgs) requirements() error {
	if len(args.Address) == 0 {
		return NewErrorWithMessage(errArguments, "Address cannot be blank")
	}
	return nil
}

type GetDataArgs struct {
	Address     string
	BlockNumber int64
}

func (args *GetDataArgs) UnmarshalJSON(b []byte) (err error) {
	if err = UnmarshalRawMessages(b, &args.Address, &args.BlockNumber); err != nil {
		return errDecodeArgs
	}

	return nil
}

func (args *GetDataArgs) requirements() error {
	if len(args.Address) == 0 {
		return NewErrorWithMessage(errArguments, "Address cannot be blank")
	}
	return nil
}

type BlockNumIndexArgs struct {
	BlockNumber int64
	Index       int64
}

type HashIndexArgs struct {
	BlockHash string
	Index     int64
}

type Sha3Args struct {
	Data string
}

func (args *Sha3Args) UnmarshalJSON(b []byte) (err error) {
	var obj []interface{}
	r := bytes.NewReader(b)
	if err := json.NewDecoder(r).Decode(&obj); err != nil {
		return NewErrorWithMessage(errDecodeArgs, err.Error())
	}

	if len(obj) < 1 {
		return errArguments
	}
	args.Data = obj[0].(string)

	return nil
}

// type FilterArgs struct {
// 	FromBlock uint64
// 	ToBlock   uint64
// 	Limit     uint64
// 	Offset    uint64
// 	Address   string
// 	Topics    []string
// }

// func (args *FilterArgs) UnmarshalJSON(b []byte) (err error) {
// 	var obj []struct {
// 		FromBlock string   `json:"fromBlock"`
// 		ToBlock   string   `json:"toBlock"`
// 		Limit     string   `json:"limit"`
// 		Offset    string   `json:"offset"`
// 		Address   string   `json:"address"`
// 		Topics    []string `json:"topics"`
// 	}

// 	if err = json.Unmarshal(b, &obj); err != nil {
// 		return errDecodeArgs
// 	}

// 	if len(obj) < 1 {
// 		return errArguments
// 	}
// 	args.FromBlock = uint64(ethutil.Big(obj[0].FromBlock).Int64())
// 	args.ToBlock = uint64(ethutil.Big(obj[0].ToBlock).Int64())
// 	args.Limit = uint64(ethutil.Big(obj[0].Limit).Int64())
// 	args.Offset = uint64(ethutil.Big(obj[0].Offset).Int64())
// 	args.Address = obj[0].Address
// 	args.Topics = obj[0].Topics

// 	return nil
// }

type FilterOptions struct {
	Earliest int64
	Latest   int64
	Address  interface{}
	Topics   []interface{}
	Skip     int
	Max      int
}

func (args *FilterOptions) UnmarshalJSON(b []byte) (err error) {
	var obj []struct {
		FromBlock string        `json:"fromBlock"`
		ToBlock   string        `json:"toBlock"`
		Limit     string        `json:"limit"`
		Offset    string        `json:"offset"`
		Address   string        `json:"address"`
		Topics    []interface{} `json:"topics"`
	}

	if err = json.Unmarshal(b, &obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 1 {
		return errArguments
	}
	args.Earliest = int64(ethutil.Big(obj[0].FromBlock).Int64())
	args.Latest = int64(ethutil.Big(obj[0].ToBlock).Int64())
	args.Max = int(ethutil.Big(obj[0].Limit).Int64())
	args.Skip = int(ethutil.Big(obj[0].Offset).Int64())
	args.Address = obj[0].Address
	args.Topics = obj[0].Topics

	return nil
}

// type FilterChangedArgs struct {
// 	n int
// }

type DbArgs struct {
	Database string
	Key      string
	Value    string
}

func (args *DbArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []interface{}
	r := bytes.NewReader(b)
	if err := json.NewDecoder(r).Decode(&obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 2 {
		return errArguments
	}
	args.Database = obj[0].(string)
	args.Key = obj[1].(string)

	if len(obj) > 2 {
		args.Value = obj[2].(string)
	}

	return nil
}

func (a *DbArgs) requirements() error {
	if len(a.Database) == 0 {
		return NewErrorWithMessage(errArguments, "Database cannot be blank")
	}
	if len(a.Key) == 0 {
		return NewErrorWithMessage(errArguments, "Key cannot be blank")
	}
	return nil
}

type WhisperMessageArgs struct {
	Payload  string
	To       string
	From     string
	Topic    []string
	Priority uint32
	Ttl      uint32
}

func (args *WhisperMessageArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []struct {
		Payload  string
		To       string
		From     string
		Topic    []string
		Priority string
		Ttl      string
	}

	if err = json.Unmarshal(b, &obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 1 {
		return errArguments
	}
	args.Payload = obj[0].Payload
	args.To = obj[0].To
	args.From = obj[0].From
	args.Topic = obj[0].Topic
	args.Priority = uint32(ethutil.Big(obj[0].Priority).Int64())
	args.Ttl = uint32(ethutil.Big(obj[0].Ttl).Int64())

	return nil
}

type CompileArgs struct {
	Source string
}

func (args *CompileArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []interface{}
	r := bytes.NewReader(b)
	if err := json.NewDecoder(r).Decode(&obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) > 0 {
		args.Source = obj[0].(string)
	}

	return nil
}

type FilterStringArgs struct {
	Word string
}

func (args *FilterStringArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []string
	r := bytes.NewReader(b)
	if err := json.NewDecoder(r).Decode(&obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 1 {
		return errDecodeArgs
	}

	args.Word = obj[0]

	return nil
}

type FilterIdArgs struct {
	Id int
}

func (args *FilterIdArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []string
	r := bytes.NewReader(b)
	if err := json.NewDecoder(r).Decode(&obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 1 {
		return errDecodeArgs
	}

	args.Id = int(ethutil.Big(obj[0]).Int64())

	return nil
}

type WhisperIdentityArgs struct {
	Identity string
}

func (args *WhisperIdentityArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []string
	r := bytes.NewReader(b)
	if err := json.NewDecoder(r).Decode(&obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 1 {
		return errDecodeArgs
	}

	args.Identity = obj[0]

	return nil
}

type WhisperFilterArgs struct {
	To     string `json:"to"`
	From   string
	Topics []string
}

func (args *WhisperFilterArgs) UnmarshalJSON(b []byte) (err error) {
	var obj []struct {
		To     string
		From   string
		Topics []string
	}

	if err = json.Unmarshal(b, &obj); err != nil {
		return errDecodeArgs
	}

	if len(obj) < 1 {
		return errArguments
	}

	args.To = obj[0].To
	args.From = obj[0].From
	args.Topics = obj[0].Topics

	return nil
}
<|endoftext|>


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

package maps

import (
	"bytes"
	"io"
	"log"
)

// Polyline represents a list of lat,lng points encoded as a byte array.
// See: https://developers.google.com/maps/documentation/utilities/polylinealgorithm
type Polyline struct {
	Points string `json:"points"`
}

// DecodePolyline converts a polyline encoded string to an array of LatLng objects.
func DecodePolyline(poly string) []LatLng {
	p := &Polyline{
		Points: poly,
	}
	return p.Decode()
}

// Decode converts this encoded Polyline to an array of LatLng objects.
func (p *Polyline) Decode() []LatLng {
	input := bytes.NewBufferString(p.Points)

	var lat, lng int64
	path := make([]LatLng, 0, len(p.Points)/2)
	for {
		dlat, _ := decodeInt(input)
		dlng, err := decodeInt(input)
		if err == io.EOF {
			return path
		}
		if err != nil {
			log.Fatal("unexpected err decoding polyline", err)
		}

		lat, lng = lat+dlat, lng+dlng
		path = append(path, LatLng{
			Lat: float64(lat) * 1e-5,
			Lng: float64(lng) * 1e-5,
		})
	}
}

// Encode returns a new encoded Polyline from the given path.
func Encode(path []LatLng) string {
	var prevLat, prevLng int64

	out := new(bytes.Buffer)
	out.Grow(len(path) * 4)

	for _, point := range path {
		lat := int64(point.Lat * 1e5)
		lng := int64(point.Lng * 1e5)

		encodeInt(lat-prevLat, out)
		encodeInt(lng-prevLng, out)

		prevLat, prevLng = lat, lng
	}

	return out.String()
}

// decodeInt reads an encoded int64 from the passed io.ByteReader.
func decodeInt(r io.ByteReader) (int64, error) {
	result := int64(1)
	var shift uint8

	for {
		raw, err := r.ReadByte()
		if err != nil {
			return 0, err
		}

		b := raw - 63 - 1
		result += int64(b) << shift
		shift += 5

		if b < 0x1f {
			bit := result & 1
			result >>= 1
			if bit != 0 {
				result = ^result
			}
			return result, nil
		}
	}
}

// encodeInt writes an encoded int64 to the passed io.ByteWriter.
func encodeInt(v int64, w io.ByteWriter) {
	if v < 0 {
		v = ^(v << 1)
	} else {
		v <<= 1
	}
	for v >= 0x20 {
		w.WriteByte((0x20 | (byte(v) & 0x1f)) + 63)
		v >>= 5
	}
	w.WriteByte(byte(v) + 63)
}
<commit_msg>Fix decodeInt polyline decoding<commit_after>// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package maps

import (
	"bytes"
	"io"
	"log"
)

// Polyline represents a list of lat,lng points encoded as a byte array.
// See: https://developers.google.com/maps/documentation/utilities/polylinealgorithm
type Polyline struct {
	Points string `json:"points"`
}

// DecodePolyline converts a polyline encoded string to an array of LatLng objects.
func DecodePolyline(poly string) []LatLng {
	p := &Polyline{
		Points: poly,
	}
	return p.Decode()
}

// Decode converts this encoded Polyline to an array of LatLng objects.
func (p *Polyline) Decode() []LatLng {
	input := bytes.NewBufferString(p.Points)

	var lat, lng int64
	path := make([]LatLng, 0, len(p.Points)/2)
	for {
		dlat, _ := decodeInt(input)
		dlng, err := decodeInt(input)
		if err == io.EOF {
			return path
		}
		if err != nil {
			log.Fatal("unexpected err decoding polyline", err)
		}

		lat, lng = lat+dlat, lng+dlng
		path = append(path, LatLng{
			Lat: float64(lat) * 1e-5,
			Lng: float64(lng) * 1e-5,
		})
	}
}

// Encode returns a new encoded Polyline from the given path.
func Encode(path []LatLng) string {
	var prevLat, prevLng int64

	out := new(bytes.Buffer)
	out.Grow(len(path) * 4)

	for _, point := range path {
		lat := int64(point.Lat * 1e5)
		lng := int64(point.Lng * 1e5)

		encodeInt(lat-prevLat, out)
		encodeInt(lng-prevLng, out)

		prevLat, prevLng = lat, lng
	}

	return out.String()
}

// decodeInt reads an encoded int64 from the passed io.ByteReader.
func decodeInt(r io.ByteReader) (int64, error) {
	result := int64(0)
	var shift uint8

	for {
		raw, err := r.ReadByte()
		if err != nil {
			return 0, err
		}

		b := raw - 63
		result += int64(b&0x1f) << shift
		shift += 5

		if b < 0x20 {
			bit := result & 1
			result >>= 1
			if bit != 0 {
				result = ^result
			}
			return result, nil
		}
	}
}

// encodeInt writes an encoded int64 to the passed io.ByteWriter.
func encodeInt(v int64, w io.ByteWriter) {
	if v < 0 {
		v = ^(v << 1)
	} else {
		v <<= 1
	}
	for v >= 0x20 {
		w.WriteByte((0x20 | (byte(v) & 0x1f)) + 63)
		v >>= 5
	}
	w.WriteByte(byte(v) + 63)
}
<|endoftext|>


<commit_before>package main

import (
	// import the entire framework (including bundled verilog)
	_ "github.com/ReconfigureIO/sdaccel"

	// Use the new SMI protocol package
	"github.com/ReconfigureIO/sdaccel/smi"
)

// magic identifier for exporting
func Top(
	inputData uintptr,
	outputData uintptr,
	length uint32,

	readReq chan<- smi.Flit64,
	readResp <-chan smi.Flit64,

	writeReq chan<- smi.Flit64,
	writeResp <-chan smi.Flit64) {

	histogram := [512]uint32{}

	// Read all of the input data into a channel
	inputChan := make(chan uint32)
	go smi.ReadBurstUInt32(readReq, readResp, inputData, smi.DefaultOptions, length, inputChan)

	// The host needs to provide the length we should read
	for ; length > 0; length-- {
		// First we'll pull of each sample from the channel
		sample := <-inputChan
		// calculate the bin for the histogram
		index := uint16(sample) >> (16 - 9)

		// And increment the value in that bin
		histogram[uint(index)] += 1
	}

	data := make(chan uint32)
	go func() {
		for i := 0; i < 512; i++ {
			data <- histogram[i]
		}
	}()

	smi.WriteBurstUInt32(
		writeReq, writeResp, outputData, smi.DefaultOptions, 512, data)
}
<commit_msg>update smi example with calculate function outside Top for testing<commit_after>package main

import (
	// import the entire framework (including bundled verilog)
	_ "github.com/ReconfigureIO/sdaccel"

	// Use the new SMI protocol package
	"github.com/ReconfigureIO/sdaccel/smi"
)

// function to calculate the bin for each sample
func CalculateIndex(sample uint32) uint16 {
	return uint16(sample) >> (16 - 9)
}

// magic identifier for exporting
func Top(
	inputData uintptr,
	outputData uintptr,
	length uint32,

	readReq chan<- smi.Flit64,
	readResp <-chan smi.Flit64,

	writeReq chan<- smi.Flit64,
	writeResp <-chan smi.Flit64) {

	histogram := [512]uint32{}

	// Read all of the input data into a channel
	inputChan := make(chan uint32)
	go smi.ReadBurstUInt32(readReq, readResp, inputData, smi.DefaultOptions, length, inputChan)

	// The host needs to provide the length we should read
	for ; length > 0; length-- {
		// First we'll pull of each sample from the channel
		sample := <-inputChan

		// And increment the value in the correct bin using the calculation function
		histogram[CalculateIndex(sample)] += 1
	}

	data := make(chan uint32)
	go func() {
		for i := 0; i < 512; i++ {
			data <- histogram[i]
		}
	}()

// Write the results to shared memory
	smi.WriteBurstUInt32(
		writeReq, writeResp, outputData, smi.DefaultOptions, 512, data)
}
<|endoftext|>


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

package collector

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/log"
)

// Numerical metric provided by /proc/drbd.
type drbdNumericalMetric struct {
	desc       *prometheus.Desc
	valueType  prometheus.ValueType
	multiplier float64
}

func newDRBDNumericalMetric(name string, desc string, valueType prometheus.ValueType, multiplier float64) drbdNumericalMetric {
	return drbdNumericalMetric{
		desc: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "drbd", name),
			desc,
			[]string{"device"}, nil),
		valueType:  valueType,
		multiplier: multiplier,
	}
}

// String pair metric provided by /proc/drbd.
type drbdStringPairMetric struct {
	desc      *prometheus.Desc
	valueOkay string
}

func (metric *drbdStringPairMetric) isOkay(value string) float64 {
	if value == metric.valueOkay {
		return 1
	}
	return 0
}

func newDRBDStringPairMetric(name string, desc string, valueOkay string) drbdStringPairMetric {
	return drbdStringPairMetric{
		desc: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "drbd", name),
			desc,
			[]string{"device", "node"}, nil),
		valueOkay: valueOkay,
	}
}

var (
	drbdNumericalMetrics = map[string]drbdNumericalMetric{
		"ns": newDRBDNumericalMetric(
			"network_sent_bytes_total",
			"Total number of bytes sent via the network.",
			prometheus.CounterValue,
			1024),
		"nr": newDRBDNumericalMetric(
			"network_received_bytes_total",
			"Total number of bytes received via the network.",
			prometheus.CounterValue,
			1),
		"dw": newDRBDNumericalMetric(
			"disk_written_bytes_total",
			"Net data written on local hard disk; in bytes.",
			prometheus.CounterValue,
			1024),
		"dr": newDRBDNumericalMetric(
			"disk_read_bytes_total",
			"Net data read from local hard disk; in bytes.",
			prometheus.CounterValue,
			1024),
		"al": newDRBDNumericalMetric(
			"activitylog_writes_total",
			"Number of updates of the activity log area of the meta data.",
			prometheus.CounterValue,
			1),
		"bm": newDRBDNumericalMetric(
			"bitmap_writes_total",
			"Number of updates of the bitmap area of the meta data.",
			prometheus.CounterValue,
			1),
		"lo": newDRBDNumericalMetric(
			"local_pending",
			"Number of open requests to the local I/O sub-system.",
			prometheus.GaugeValue,
			1),
		"pe": newDRBDNumericalMetric(
			"remote_pending",
			"Number of requests sent to the peer, but that have not yet been answered by the latter.",
			prometheus.GaugeValue,
			1),
		"ua": newDRBDNumericalMetric(
			"remote_unacknowledged",
			"Number of requests received by the peer via the network connection, but that have not yet been answered.",
			prometheus.GaugeValue,
			1),
		"ap": newDRBDNumericalMetric(
			"application_pending",
			"Number of block I/O requests forwarded to DRBD, but not yet answered by DRBD.",
			prometheus.GaugeValue,
			1),
		"ep": newDRBDNumericalMetric(
			"epochs",
			"Number of Epochs currently on the fly.",
			prometheus.GaugeValue,
			1),
		"oos": newDRBDNumericalMetric(
			"out_of_sync_bytes",
			"Amount of data known to be out of sync; in bytes.",
			prometheus.GaugeValue,
			1024),
	}
	drbdStringPairMetrics = map[string]drbdStringPairMetric{
		"ro": newDRBDStringPairMetric(
			"node_role_is_primary",
			"Whether the role of the node is in the primary state.",
			"Primary"),
		"ds": newDRBDStringPairMetric(
			"disk_state_is_up_to_date",
			"Whether the disk of the node is up to date.",
			"UpToDate"),
	}

	drbdConnected = prometheus.NewDesc(
		prometheus.BuildFQName(namespace, "drbd", "connected"),
		"Whether DRBD is connected to the peer.",
		[]string{"device"}, nil)
)

type drbdCollector struct{}

func init() {
	registerCollector("drbd", defaultDisabled, newDRBDCollector)
}

func newDRBDCollector() (Collector, error) {
	return &drbdCollector{}, nil
}

func (c *drbdCollector) Update(ch chan<- prometheus.Metric) error {
	statsFile := procFilePath("drbd")
	file, err := os.Open(statsFile)
	if err != nil {
		if os.IsNotExist(err) {
			log.Debugf("Not collecting DRBD statistics, as %s does not exist: %s", statsFile, err)
			return nil
		}
		return err
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	scanner.Split(bufio.ScanWords)
	device := "unknown"
	for scanner.Scan() {
		field := scanner.Text()
		if kv := strings.Split(field, ":"); len(kv) == 2 {
			if id, err := strconv.ParseUint(kv[0], 10, 64); err == nil && kv[1] == "" {
				device = fmt.Sprintf("drbd%d", id)
			} else if metric, ok := drbdNumericalMetrics[kv[0]]; ok {
				// Numerical value.
				value, err := strconv.ParseFloat(kv[1], 64)
				if err != nil {
					return err
				}
				ch <- prometheus.MustNewConstMetric(
					metric.desc, metric.valueType,
					value*metric.multiplier, device)
			} else if metric, ok := drbdStringPairMetrics[kv[0]]; ok {
				// String pair value.
				values := strings.Split(kv[1], "/")
				ch <- prometheus.MustNewConstMetric(
					metric.desc, prometheus.GaugeValue,
					metric.isOkay(values[0]), device, "local")
				ch <- prometheus.MustNewConstMetric(
					metric.desc, prometheus.GaugeValue,
					metric.isOkay(values[1]), device, "remote")
			} else if kv[0] == "cs" {
				// Connection state.
				var connected float64
				if kv[1] == "Connected" {
					connected = 1
				}
				ch <- prometheus.MustNewConstMetric(
					drbdConnected, prometheus.GaugeValue,
					connected, device)
			} else {
				log.Debugf("Don't know how to process key-value pair [%s: %q]", kv[0], kv[1])
			}
		} else {
			log.Debugf("Don't know how to process string %q", field)
		}
	}
	return scanner.Err()
}
<commit_msg>collector: clean up DRBD collector, less global state<commit_after>// Copyright 2016 The Prometheus Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package collector

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/common/log"
)

// Numerical metric provided by /proc/drbd.
type drbdNumericalMetric struct {
	desc       *prometheus.Desc
	valueType  prometheus.ValueType
	multiplier float64
}

func newDRBDNumericalMetric(name, desc string, valueType prometheus.ValueType, multiplier float64) drbdNumericalMetric {
	return drbdNumericalMetric{
		desc: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "drbd", name),
			desc,
			[]string{"device"},
			nil,
		),
		valueType:  valueType,
		multiplier: multiplier,
	}
}

// String pair metric provided by /proc/drbd.
type drbdStringPairMetric struct {
	desc    *prometheus.Desc
	valueOK string
}

func (m *drbdStringPairMetric) isOkay(v string) float64 {
	if v == m.valueOK {
		return 1
	}

	return 0
}

func newDRBDStringPairMetric(name, desc, valueOK string) drbdStringPairMetric {
	return drbdStringPairMetric{
		desc: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "drbd", name),
			desc,
			[]string{"device", "node"},
			nil,
		),
		valueOK: valueOK,
	}
}

type drbdCollector struct {
	numerical  map[string]drbdNumericalMetric
	stringPair map[string]drbdStringPairMetric
	connected  *prometheus.Desc
}

func init() {
	registerCollector("drbd", defaultDisabled, newDRBDCollector)
}

func newDRBDCollector() (Collector, error) {
	return &drbdCollector{
		numerical: map[string]drbdNumericalMetric{
			"ns": newDRBDNumericalMetric(
				"network_sent_bytes_total",
				"Total number of bytes sent via the network.",
				prometheus.CounterValue,
				1024,
			),
			"nr": newDRBDNumericalMetric(
				"network_received_bytes_total",
				"Total number of bytes received via the network.",
				prometheus.CounterValue,
				1,
			),
			"dw": newDRBDNumericalMetric(
				"disk_written_bytes_total",
				"Net data written on local hard disk; in bytes.",
				prometheus.CounterValue,
				1024,
			),
			"dr": newDRBDNumericalMetric(
				"disk_read_bytes_total",
				"Net data read from local hard disk; in bytes.",
				prometheus.CounterValue,
				1024,
			),
			"al": newDRBDNumericalMetric(
				"activitylog_writes_total",
				"Number of updates of the activity log area of the meta data.",
				prometheus.CounterValue,
				1,
			),
			"bm": newDRBDNumericalMetric(
				"bitmap_writes_total",
				"Number of updates of the bitmap area of the meta data.",
				prometheus.CounterValue,
				1,
			),
			"lo": newDRBDNumericalMetric(
				"local_pending",
				"Number of open requests to the local I/O sub-system.",
				prometheus.GaugeValue,
				1,
			),
			"pe": newDRBDNumericalMetric(
				"remote_pending",
				"Number of requests sent to the peer, but that have not yet been answered by the latter.",
				prometheus.GaugeValue,
				1,
			),
			"ua": newDRBDNumericalMetric(
				"remote_unacknowledged",
				"Number of requests received by the peer via the network connection, but that have not yet been answered.",
				prometheus.GaugeValue,
				1,
			),
			"ap": newDRBDNumericalMetric(
				"application_pending",
				"Number of block I/O requests forwarded to DRBD, but not yet answered by DRBD.",
				prometheus.GaugeValue,
				1,
			),
			"ep": newDRBDNumericalMetric(
				"epochs",
				"Number of Epochs currently on the fly.",
				prometheus.GaugeValue,
				1,
			),
			"oos": newDRBDNumericalMetric(
				"out_of_sync_bytes",
				"Amount of data known to be out of sync; in bytes.",
				prometheus.GaugeValue,
				1024,
			),
		},

		stringPair: map[string]drbdStringPairMetric{
			"ro": newDRBDStringPairMetric(
				"node_role_is_primary",
				"Whether the role of the node is in the primary state.",
				"Primary",
			),
			"ds": newDRBDStringPairMetric(
				"disk_state_is_up_to_date",
				"Whether the disk of the node is up to date.",
				"UpToDate",
			),
		},

		connected: prometheus.NewDesc(
			prometheus.BuildFQName(namespace, "drbd", "connected"),
			"Whether DRBD is connected to the peer.",
			[]string{"device"},
			nil,
		),
	}, nil
}

func (c *drbdCollector) Update(ch chan<- prometheus.Metric) error {
	statsFile := procFilePath("drbd")
	file, err := os.Open(statsFile)
	if err != nil {
		if os.IsNotExist(err) {
			log.Debugf("drbd: %s does not exist, skipping: %s", statsFile, err)
			return nil
		}

		return err
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)
	scanner.Split(bufio.ScanWords)
	device := "unknown"

	for scanner.Scan() {
		field := scanner.Text()

		kv := strings.Split(field, ":")
		if len(kv) != 2 {
			log.Debugf("drbd: skipping invalid key:value pair %q", field)
			continue
		}

		if id, err := strconv.ParseUint(kv[0], 10, 64); err == nil && kv[1] == "" {
			// New DRBD device encountered.
			device = fmt.Sprintf("drbd%d", id)
			continue
		}

		if m, ok := c.numerical[kv[0]]; ok {
			// Numerical value.
			v, err := strconv.ParseFloat(kv[1], 64)
			if err != nil {
				return err
			}

			ch <- prometheus.MustNewConstMetric(
				m.desc,
				m.valueType,
				v*m.multiplier,
				device,
			)

			continue
		}

		if m, ok := c.stringPair[kv[0]]; ok {
			// String pair value.
			values := strings.Split(kv[1], "/")
			ch <- prometheus.MustNewConstMetric(
				m.desc,
				prometheus.GaugeValue,
				m.isOkay(values[0]),
				device,
				"local",
			)

			ch <- prometheus.MustNewConstMetric(
				m.desc,
				prometheus.GaugeValue,
				m.isOkay(values[1]),
				device,
				"remote",
			)

			continue
		}

		if kv[0] == "cs" {
			// Connection state.
			var connected float64
			if kv[1] == "Connected" {
				connected = 1
			}

			ch <- prometheus.MustNewConstMetric(
				c.connected,
				prometheus.GaugeValue,
				connected,
				device,
			)

			continue
		}

		log.Debugf("drbd: unhandled key-value pair: [%s: %q]", kv[0], kv[1])
	}

	return scanner.Err()
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Marin Atanasov Nikolov <dnaeon@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer
//    in this position and unchanged.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package recorder

import (
	"bufio"
	"bytes"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httputil"
	"os"

	"github.com/dnaeon/go-vcr/cassette"
)

// Recorder states
const (
	ModeRecording = iota
	ModeReplaying
)

// Recorder represents a type used to record and replay
// client and server interactions
type Recorder struct {
	// Operating mode of the recorder
	mode int

	// Cassette used by the recorder
	cassette *cassette.Cassette

	// Transport that can be used by clients to inject
	Transport *Transport
}

// Proxies client requests to their original destination
func requestHandler(r *http.Request, c *cassette.Cassette, mode int) (*cassette.Interaction, error) {
	// Return interaction from cassette if in replay mode
	if mode == ModeReplaying {
		return c.GetInteraction(r)
	}

	// Copy the original request, so we can read the form values
	reqBytes, err := httputil.DumpRequestOut(r, true)
	if err != nil {
		return nil, err
	}

	reqBuffer := bytes.NewBuffer(reqBytes)
	copiedReq, err := http.ReadRequest(bufio.NewReader(reqBuffer))
	if err != nil {
		return nil, err
	}

	err = copiedReq.ParseForm()
	if err != nil {
		return nil, err
	}

	// Perform client request to it's original
	// destination and record interactions
	body := ioutil.NopCloser(r.Body)
	req, err := http.NewRequest(r.Method, r.URL.String(), body)
	if err != nil {
		return nil, err
	}

	req.Header = r.Header
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}

	// Record the interaction and add it to the cassette
	reqBody, err := ioutil.ReadAll(req.Body)
	if err != nil {
		return nil, err
	}

	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	// Add interaction to cassette
	interaction := &cassette.Interaction{
		Request: cassette.Request{
			Body:    string(reqBody),
			Form:    copiedReq.PostForm,
			Headers: req.Header,
			URL:     req.URL.String(),
			Method:  req.Method,
		},
		Response: cassette.Response{
			Body:    string(respBody),
			Headers: resp.Header,
			Status:  resp.Status,
			Code:    resp.StatusCode,
		},
	}
	c.AddInteraction(interaction)

	return interaction, nil
}

// New creates a new recorder
func New(cassetteName string) (*Recorder, error) {
	var mode int
	var c *cassette.Cassette
	cassetteFile := fmt.Sprintf("%s.yaml", cassetteName)

	// Depending on whether the cassette file exists or not we
	// either create a new empty cassette or load from file
	if _, err := os.Stat(cassetteFile); os.IsNotExist(err) {
		// Create new cassette and enter in recording mode
		c = cassette.New(cassetteName)
		mode = ModeRecording
	} else {
		// Load cassette from file and enter replay mode
		c, err = cassette.Load(cassetteName)
		if err != nil {
			return nil, err
		}
		mode = ModeReplaying
	}

	// A transport which can be used by clients to inject
	transport := &Transport{c: c, mode: mode}

	r := &Recorder{
		mode:      mode,
		cassette:  c,
		Transport: transport,
	}

	return r, nil
}

// Stop is used to stop the recorder and save any recorded interactions
func (r *Recorder) Stop() error {
	if r.mode == ModeRecording {
		if err := r.cassette.Save(); err != nil {
			return err
		}
	}

	return nil
}

// Transport either records or replays responses from a cassette, depending on its mode
type Transport struct {
	c    *cassette.Cassette
	mode int
}

// RoundTrip implements the http.RoundTripper interface
func (t *Transport) RoundTrip(r *http.Request) (*http.Response, error) {
	// Pass cassette and mode to handler, so that interactions can be
	// retrieved or recorded depending on the current recorder mode
	interaction, err := requestHandler(r, t.c, t.mode)

	if err != nil {
		panic(fmt.Errorf("Failed to process request for URL %s: %s", r.URL, err))
	}

	buf := bytes.NewBuffer([]byte(interaction.Response.Body))

	return &http.Response{
		Status:        interaction.Response.Status,
		StatusCode:    interaction.Response.Code,
		Proto:         "HTTP/1.0",
		ProtoMajor:    1,
		ProtoMinor:    0,
		Request:       r,
		Header:        interaction.Response.Headers,
		Close:         true,
		ContentLength: int64(buf.Len()),
		Body:          ioutil.NopCloser(buf),
	}, nil
}

// CancelRequest implements the github.com/coreos/etcd/client.CancelableTransport interface
func (t *Transport) CancelRequest(req *http.Request) {
	// noop
}
<commit_msg>Revert "Support https"<commit_after>// Copyright (c) 2015 Marin Atanasov Nikolov <dnaeon@gmail.com>
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer
//    in this position and unchanged.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

package recorder

import (
	"bufio"
	"bytes"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/http/httptest"
	"net/http/httputil"
	"net/url"
	"os"

	"github.com/dnaeon/go-vcr/cassette"
)

// Recorder states
const (
	ModeRecording = iota
	ModeReplaying
)

// Recorder represents a type used to record and replay
// client and server interactions
type Recorder struct {
	// Operating mode of the recorder
	mode int

	// HTTP server used to mock requests
	server *httptest.Server

	// Cassette used by the recorder
	cassette *cassette.Cassette

	// Transport that can be used by clients to inject
	Transport *http.Transport
}

// Proxies client requests to their original destination
func requestHandler(r *http.Request, c *cassette.Cassette, mode int) (*cassette.Interaction, error) {
	// Return interaction from cassette if in replay mode
	if mode == ModeReplaying {
		return c.GetInteraction(r)
	}

	// Copy the original request, so we can read the form values
	reqBytes, err := httputil.DumpRequestOut(r, true)
	if err != nil {
		return nil, err
	}

	reqBuffer := bytes.NewBuffer(reqBytes)
	copiedReq, err := http.ReadRequest(bufio.NewReader(reqBuffer))
	if err != nil {
		return nil, err
	}

	err = copiedReq.ParseForm()
	if err != nil {
		return nil, err
	}

	// Perform client request to it's original
	// destination and record interactions
	body := ioutil.NopCloser(r.Body)
	req, err := http.NewRequest(r.Method, r.URL.String(), body)
	if err != nil {
		return nil, err
	}

	req.Header = r.Header
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return nil, err
	}

	// Record the interaction and add it to the cassette
	reqBody, err := ioutil.ReadAll(req.Body)
	if err != nil {
		return nil, err
	}

	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	// Add interaction to cassette
	interaction := &cassette.Interaction{
		Request: cassette.Request{
			Body:    string(reqBody),
			Form:    copiedReq.PostForm,
			Headers: req.Header,
			URL:     req.URL.String(),
			Method:  req.Method,
		},
		Response: cassette.Response{
			Body:    string(respBody),
			Headers: resp.Header,
			Status:  resp.Status,
			Code:    resp.StatusCode,
		},
	}
	c.AddInteraction(interaction)

	return interaction, nil
}

// New creates a new recorder
func New(cassetteName string) (*Recorder, error) {
	var mode int
	var c *cassette.Cassette
	cassetteFile := fmt.Sprintf("%s.yaml", cassetteName)

	// Depending on whether the cassette file exists or not we
	// either create a new empty cassette or load from file
	if _, err := os.Stat(cassetteFile); os.IsNotExist(err) {
		// Create new cassette and enter in recording mode
		c = cassette.New(cassetteName)
		mode = ModeRecording
	} else {
		// Load cassette from file and enter replay mode
		c, err = cassette.Load(cassetteName)
		if err != nil {
			return nil, err
		}
		mode = ModeReplaying
	}

	// Handler for client requests
	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// Pass cassette and mode to handler, so that interactions can be
		// retrieved or recorded depending on the current recorder mode
		interaction, err := requestHandler(r, c, mode)

		if err != nil {
			panic(fmt.Errorf("Failed to process request for URL %s: %s", r.URL, err))
		}

		w.WriteHeader(interaction.Response.Code)
		fmt.Fprintln(w, interaction.Response.Body)
	})

	// HTTP server used to mock requests
	server := httptest.NewServer(handler)

	// A proxy function which routes all requests through our HTTP server
	// Can be used by clients to inject into their own transports
	proxyURL, err := url.Parse(server.URL)
	if err != nil {
		return nil, err
	}

	// A transport which can be used by clients to inject
	transport := &http.Transport{
		Proxy: http.ProxyURL(proxyURL),
	}

	r := &Recorder{
		mode:      mode,
		server:    server,
		cassette:  c,
		Transport: transport,
	}

	return r, nil
}

// Stop is used to stop the recorder and save any recorded interactions
func (r *Recorder) Stop() error {
	r.server.Close()

	if r.mode == ModeRecording {
		if err := r.cassette.Save(); err != nil {
			return err
		}
	}

	return nil
}
<|endoftext|>


<commit_before>// Package registry contains client primitives to interact with a remote Docker registry.
package registry // import "github.com/docker/docker/registry"

import (
	"crypto/tls"
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/docker/distribution/registry/client/transport"
	"github.com/docker/go-connections/tlsconfig"
	"github.com/sirupsen/logrus"
)

var (
	// ErrAlreadyExists is an error returned if an image being pushed
	// already exists on the remote side
	ErrAlreadyExists = errors.New("Image already exists")
)

func newTLSConfig(hostname string, isSecure bool) (*tls.Config, error) {
	// PreferredServerCipherSuites should have no effect
	tlsConfig := tlsconfig.ServerDefault()

	tlsConfig.InsecureSkipVerify = !isSecure

	if isSecure && CertsDir != "" {
		hostDir := filepath.Join(CertsDir, cleanPath(hostname))
		logrus.Debugf("hostDir: %s", hostDir)
		if err := ReadCertsDirectory(tlsConfig, hostDir); err != nil {
			return nil, err
		}
	}

	return tlsConfig, nil
}

func hasFile(files []os.FileInfo, name string) bool {
	for _, f := range files {
		if f.Name() == name {
			return true
		}
	}
	return false
}

// ReadCertsDirectory reads the directory for TLS certificates
// including roots and certificate pairs and updates the
// provided TLS configuration.
func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error {
	fs, err := ioutil.ReadDir(directory)
	if err != nil && !os.IsNotExist(err) {
		return err
	}

	for _, f := range fs {
		if strings.HasSuffix(f.Name(), ".crt") {
			if tlsConfig.RootCAs == nil {
				systemPool, err := tlsconfig.SystemCertPool()
				if err != nil {
					return fmt.Errorf("unable to get system cert pool: %v", err)
				}
				tlsConfig.RootCAs = systemPool
			}
			logrus.Debugf("crt: %s", filepath.Join(directory, f.Name()))
			data, err := ioutil.ReadFile(filepath.Join(directory, f.Name()))
			if err != nil {
				return err
			}
			tlsConfig.RootCAs.AppendCertsFromPEM(data)
		}
		if strings.HasSuffix(f.Name(), ".cert") {
			certName := f.Name()
			keyName := certName[:len(certName)-5] + ".key"
			logrus.Debugf("cert: %s", filepath.Join(directory, f.Name()))
			if !hasFile(fs, keyName) {
				return fmt.Errorf("missing key %s for client certificate %s. Note that CA certificates should use the extension .crt", keyName, certName)
			}
			cert, err := tls.LoadX509KeyPair(filepath.Join(directory, certName), filepath.Join(directory, keyName))
			if err != nil {
				return err
			}
			tlsConfig.Certificates = append(tlsConfig.Certificates, cert)
		}
		if strings.HasSuffix(f.Name(), ".key") {
			keyName := f.Name()
			certName := keyName[:len(keyName)-4] + ".cert"
			logrus.Debugf("key: %s", filepath.Join(directory, f.Name()))
			if !hasFile(fs, certName) {
				return fmt.Errorf("Missing client certificate %s for key %s", certName, keyName)
			}
		}
	}

	return nil
}

// Headers returns request modifiers with a User-Agent and metaHeaders
func Headers(userAgent string, metaHeaders http.Header) []transport.RequestModifier {
	modifiers := []transport.RequestModifier{}
	if userAgent != "" {
		modifiers = append(modifiers, transport.NewHeaderRequestModifier(http.Header{
			"User-Agent": []string{userAgent},
		}))
	}
	if metaHeaders != nil {
		modifiers = append(modifiers, transport.NewHeaderRequestModifier(metaHeaders))
	}
	return modifiers
}

// HTTPClient returns an HTTP client structure which uses the given transport
// and contains the necessary headers for redirected requests
func HTTPClient(transport http.RoundTripper) *http.Client {
	return &http.Client{
		Transport:     transport,
		CheckRedirect: addRequiredHeadersToRedirectedRequests,
	}
}

func trustedLocation(req *http.Request) bool {
	var (
		trusteds = []string{"docker.com", "docker.io"}
		hostname = strings.SplitN(req.Host, ":", 2)[0]
	)
	if req.URL.Scheme != "https" {
		return false
	}

	for _, trusted := range trusteds {
		if hostname == trusted || strings.HasSuffix(hostname, "."+trusted) {
			return true
		}
	}
	return false
}

// addRequiredHeadersToRedirectedRequests adds the necessary redirection headers
// for redirected requests
func addRequiredHeadersToRedirectedRequests(req *http.Request, via []*http.Request) error {
	if len(via) != 0 && via[0] != nil {
		if trustedLocation(req) && trustedLocation(via[0]) {
			req.Header = via[0].Header
			return nil
		}
		for k, v := range via[0].Header {
			if k != "Authorization" {
				for _, vv := range v {
					req.Header.Add(k, vv)
				}
			}
		}
	}
	return nil
}

// NewTransport returns a new HTTP transport. If tlsConfig is nil, it uses the
// default TLS configuration.
func NewTransport(tlsConfig *tls.Config) *http.Transport {
	if tlsConfig == nil {
		tlsConfig = tlsconfig.ServerDefault()
	}

	direct := &net.Dialer{
		Timeout:   30 * time.Second,
		KeepAlive: 30 * time.Second,
		DualStack: true,
	}

	base := &http.Transport{
		Proxy:               http.ProxyFromEnvironment,
		DialContext:         direct.DialContext,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig:     tlsConfig,
		// TODO(dmcgowan): Call close idle connections when complete and use keep alive
		DisableKeepAlives: true,
	}

	return base
}
<commit_msg>Don't die when daemon cannot read certs.d<commit_after>// Package registry contains client primitives to interact with a remote Docker registry.
package registry // import "github.com/docker/docker/registry"

import (
	"crypto/tls"
	"errors"
	"fmt"
	"io/ioutil"
	"net"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/docker/distribution/registry/client/transport"
	"github.com/docker/go-connections/tlsconfig"
	"github.com/sirupsen/logrus"
)

var (
	// ErrAlreadyExists is an error returned if an image being pushed
	// already exists on the remote side
	ErrAlreadyExists = errors.New("Image already exists")
)

func newTLSConfig(hostname string, isSecure bool) (*tls.Config, error) {
	// PreferredServerCipherSuites should have no effect
	tlsConfig := tlsconfig.ServerDefault()

	tlsConfig.InsecureSkipVerify = !isSecure

	if isSecure && CertsDir != "" {
		hostDir := filepath.Join(CertsDir, cleanPath(hostname))
		logrus.Debugf("hostDir: %s", hostDir)
		if err := ReadCertsDirectory(tlsConfig, hostDir); err != nil {
			return nil, err
		}
	}

	return tlsConfig, nil
}

func hasFile(files []os.FileInfo, name string) bool {
	for _, f := range files {
		if f.Name() == name {
			return true
		}
	}
	return false
}

// ReadCertsDirectory reads the directory for TLS certificates
// including roots and certificate pairs and updates the
// provided TLS configuration.
func ReadCertsDirectory(tlsConfig *tls.Config, directory string) error {
	fs, err := ioutil.ReadDir(directory)
	if err != nil && !os.IsNotExist(err) && !os.IsPermission(err) {
		return err
	}

	for _, f := range fs {
		if strings.HasSuffix(f.Name(), ".crt") {
			if tlsConfig.RootCAs == nil {
				systemPool, err := tlsconfig.SystemCertPool()
				if err != nil {
					return fmt.Errorf("unable to get system cert pool: %v", err)
				}
				tlsConfig.RootCAs = systemPool
			}
			logrus.Debugf("crt: %s", filepath.Join(directory, f.Name()))
			data, err := ioutil.ReadFile(filepath.Join(directory, f.Name()))
			if err != nil {
				return err
			}
			tlsConfig.RootCAs.AppendCertsFromPEM(data)
		}
		if strings.HasSuffix(f.Name(), ".cert") {
			certName := f.Name()
			keyName := certName[:len(certName)-5] + ".key"
			logrus.Debugf("cert: %s", filepath.Join(directory, f.Name()))
			if !hasFile(fs, keyName) {
				return fmt.Errorf("missing key %s for client certificate %s. Note that CA certificates should use the extension .crt", keyName, certName)
			}
			cert, err := tls.LoadX509KeyPair(filepath.Join(directory, certName), filepath.Join(directory, keyName))
			if err != nil {
				return err
			}
			tlsConfig.Certificates = append(tlsConfig.Certificates, cert)
		}
		if strings.HasSuffix(f.Name(), ".key") {
			keyName := f.Name()
			certName := keyName[:len(keyName)-4] + ".cert"
			logrus.Debugf("key: %s", filepath.Join(directory, f.Name()))
			if !hasFile(fs, certName) {
				return fmt.Errorf("Missing client certificate %s for key %s", certName, keyName)
			}
		}
	}

	return nil
}

// Headers returns request modifiers with a User-Agent and metaHeaders
func Headers(userAgent string, metaHeaders http.Header) []transport.RequestModifier {
	modifiers := []transport.RequestModifier{}
	if userAgent != "" {
		modifiers = append(modifiers, transport.NewHeaderRequestModifier(http.Header{
			"User-Agent": []string{userAgent},
		}))
	}
	if metaHeaders != nil {
		modifiers = append(modifiers, transport.NewHeaderRequestModifier(metaHeaders))
	}
	return modifiers
}

// HTTPClient returns an HTTP client structure which uses the given transport
// and contains the necessary headers for redirected requests
func HTTPClient(transport http.RoundTripper) *http.Client {
	return &http.Client{
		Transport:     transport,
		CheckRedirect: addRequiredHeadersToRedirectedRequests,
	}
}

func trustedLocation(req *http.Request) bool {
	var (
		trusteds = []string{"docker.com", "docker.io"}
		hostname = strings.SplitN(req.Host, ":", 2)[0]
	)
	if req.URL.Scheme != "https" {
		return false
	}

	for _, trusted := range trusteds {
		if hostname == trusted || strings.HasSuffix(hostname, "."+trusted) {
			return true
		}
	}
	return false
}

// addRequiredHeadersToRedirectedRequests adds the necessary redirection headers
// for redirected requests
func addRequiredHeadersToRedirectedRequests(req *http.Request, via []*http.Request) error {
	if len(via) != 0 && via[0] != nil {
		if trustedLocation(req) && trustedLocation(via[0]) {
			req.Header = via[0].Header
			return nil
		}
		for k, v := range via[0].Header {
			if k != "Authorization" {
				for _, vv := range v {
					req.Header.Add(k, vv)
				}
			}
		}
	}
	return nil
}

// NewTransport returns a new HTTP transport. If tlsConfig is nil, it uses the
// default TLS configuration.
func NewTransport(tlsConfig *tls.Config) *http.Transport {
	if tlsConfig == nil {
		tlsConfig = tlsconfig.ServerDefault()
	}

	direct := &net.Dialer{
		Timeout:   30 * time.Second,
		KeepAlive: 30 * time.Second,
		DualStack: true,
	}

	base := &http.Transport{
		Proxy:               http.ProxyFromEnvironment,
		DialContext:         direct.DialContext,
		TLSHandshakeTimeout: 10 * time.Second,
		TLSClientConfig:     tlsConfig,
		// TODO(dmcgowan): Call close idle connections when complete and use keep alive
		DisableKeepAlives: true,
	}

	return base
}
<|endoftext|>


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

package types

import (
	"net/url"

	"github.com/coreos/container-linux-config-transpiler/config/astyaml"

	ignTypes "github.com/coreos/ignition/config/v2_1/types"
	"github.com/coreos/ignition/config/validate/astnode"
	"github.com/coreos/ignition/config/validate/report"
	"github.com/vincent-petithory/dataurl"
)

type FileUser struct {
	Id   *int   `yaml:"id"`
	Name string `yaml:"name"`
}

type FileGroup struct {
	Id   *int   `yaml:"id"`
	Name string `yaml:"name"`
}

type File struct {
	Filesystem string       `yaml:"filesystem"`
	Path       string       `yaml:"path"`
	User       FileUser     `yaml:"user"`
	Group      FileGroup    `yaml:"group"`
	Mode       int          `yaml:"mode"`
	Contents   FileContents `yaml:"contents"`
}

type FileContents struct {
	Remote Remote `yaml:"remote"`
	Inline string `yaml:"inline"`
}

type Remote struct {
	Url          string       `yaml:"url"`
	Compression  string       `yaml:"compression"`
	Verification Verification `yaml:"verification"`
}

type Directory struct {
	Filesystem string    `yaml:"filesystem"`
	Path       string    `yaml:"path"`
	User       FileUser  `yaml:"user"`
	Group      FileGroup `yaml:"group"`
	Mode       int       `yaml:"mode"`
}

type Link struct {
	Filesystem string    `yaml:"filesystem"`
	Path       string    `yaml:"path"`
	User       FileUser  `yaml:"user"`
	Group      FileGroup `yaml:"group"`
	Hard       bool      `yaml:"hard"`
	Target     string    `yaml:"target"`
}

func init() {
	register2_0(func(in Config, ast astnode.AstNode, out ignTypes.Config, platform string) (ignTypes.Config, report.Report, astnode.AstNode) {
		r := report.Report{}
		files_node, _ := getNodeChildPath(ast, "storage", "files")
		for i, file := range in.Storage.Files {
			file_node, _ := getNodeChild(files_node, i)
			newFile := ignTypes.File{
				Node: ignTypes.Node{
					Filesystem: file.Filesystem,
					Path:       file.Path,
					User: ignTypes.NodeUser{
						ID:   file.User.Id,
						Name: file.User.Name,
					},
					Group: ignTypes.NodeGroup{
						ID:   file.Group.Id,
						Name: file.Group.Name,
					},
				},
				FileEmbedded1: ignTypes.FileEmbedded1{
					Mode: file.Mode,
				},
			}

			if file.Contents.Inline != "" {
				newFile.Contents = ignTypes.FileContents{
					Source: (&url.URL{
						Scheme: "data",
						Opaque: "," + dataurl.EscapeString(file.Contents.Inline),
					}).String(),
				}
			}

			if file.Contents.Remote.Url != "" {
				source, err := url.Parse(file.Contents.Remote.Url)
				if err != nil {
					// if invalid, record error and continue
					convertReport := report.ReportFromError(err, report.EntryError)
					if n, err := getNodeChildPath(file_node, "contents", "remote", "url"); err == nil {
						line, col, _ := n.ValueLineCol(nil)
						convertReport.AddPosition(line, col, "")
					}
					continue
				}

				// patch the yaml tree to look like the ignition tree by making contents
				// the remote section and changing the name from url -> source
				asYamlNode, ok := file_node.(astyaml.YamlNode)
				if ok {
					newContents, _ := getNodeChildPath(file_node, "contents", "remote")
					newContentsAsYaml := newContents.(astyaml.YamlNode)
					asYamlNode.ChangeKey("contents", "contents", newContentsAsYaml)

					url, _ := getNodeChild(newContents.(astyaml.YamlNode), "url")
					newContentsAsYaml.ChangeKey("url", "source", url.(astyaml.YamlNode))
				}

				newFile.Contents = ignTypes.FileContents{Source: source.String()}

			}

			if newFile.Contents == (ignTypes.FileContents{}) {
				newFile.Contents = ignTypes.FileContents{
					Source: "data:,",
				}
			}

			newFile.Contents.Compression = file.Contents.Remote.Compression
			newFile.Contents.Verification = convertVerification(file.Contents.Remote.Verification)

			out.Storage.Files = append(out.Storage.Files, newFile)
		}
		for _, dir := range in.Storage.Directories {
			out.Storage.Directories = append(out.Storage.Directories, ignTypes.Directory{
				Node: ignTypes.Node{
					Filesystem: dir.Filesystem,
					Path:       dir.Path,
					User: ignTypes.NodeUser{
						ID:   dir.User.Id,
						Name: dir.User.Name,
					},
					Group: ignTypes.NodeGroup{
						ID:   dir.Group.Id,
						Name: dir.Group.Name,
					},
				},
				DirectoryEmbedded1: ignTypes.DirectoryEmbedded1{
					Mode: dir.Mode,
				},
			})
		}
		for _, link := range in.Storage.Links {
			out.Storage.Links = append(out.Storage.Links, ignTypes.Link{
				Node: ignTypes.Node{
					Filesystem: link.Filesystem,
					Path:       link.Path,
					User: ignTypes.NodeUser{
						ID:   link.User.Id,
						Name: link.User.Name,
					},
					Group: ignTypes.NodeGroup{
						ID:   link.Group.Id,
						Name: link.Group.Name,
					},
				},
				LinkEmbedded1: ignTypes.LinkEmbedded1{
					Hard:   link.Hard,
					Target: link.Target,
				},
			})
		}
		return out, r, ast
	})
}
<commit_msg>config/types/files: actually report remote url errors<commit_after>// Copyright 2016 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package types

import (
	"net/url"

	"github.com/coreos/container-linux-config-transpiler/config/astyaml"

	ignTypes "github.com/coreos/ignition/config/v2_1/types"
	"github.com/coreos/ignition/config/validate/astnode"
	"github.com/coreos/ignition/config/validate/report"
	"github.com/vincent-petithory/dataurl"
)

type FileUser struct {
	Id   *int   `yaml:"id"`
	Name string `yaml:"name"`
}

type FileGroup struct {
	Id   *int   `yaml:"id"`
	Name string `yaml:"name"`
}

type File struct {
	Filesystem string       `yaml:"filesystem"`
	Path       string       `yaml:"path"`
	User       FileUser     `yaml:"user"`
	Group      FileGroup    `yaml:"group"`
	Mode       int          `yaml:"mode"`
	Contents   FileContents `yaml:"contents"`
}

type FileContents struct {
	Remote Remote `yaml:"remote"`
	Inline string `yaml:"inline"`
}

type Remote struct {
	Url          string       `yaml:"url"`
	Compression  string       `yaml:"compression"`
	Verification Verification `yaml:"verification"`
}

type Directory struct {
	Filesystem string    `yaml:"filesystem"`
	Path       string    `yaml:"path"`
	User       FileUser  `yaml:"user"`
	Group      FileGroup `yaml:"group"`
	Mode       int       `yaml:"mode"`
}

type Link struct {
	Filesystem string    `yaml:"filesystem"`
	Path       string    `yaml:"path"`
	User       FileUser  `yaml:"user"`
	Group      FileGroup `yaml:"group"`
	Hard       bool      `yaml:"hard"`
	Target     string    `yaml:"target"`
}

func init() {
	register2_0(func(in Config, ast astnode.AstNode, out ignTypes.Config, platform string) (ignTypes.Config, report.Report, astnode.AstNode) {
		r := report.Report{}
		files_node, _ := getNodeChildPath(ast, "storage", "files")
		for i, file := range in.Storage.Files {
			file_node, _ := getNodeChild(files_node, i)
			newFile := ignTypes.File{
				Node: ignTypes.Node{
					Filesystem: file.Filesystem,
					Path:       file.Path,
					User: ignTypes.NodeUser{
						ID:   file.User.Id,
						Name: file.User.Name,
					},
					Group: ignTypes.NodeGroup{
						ID:   file.Group.Id,
						Name: file.Group.Name,
					},
				},
				FileEmbedded1: ignTypes.FileEmbedded1{
					Mode: file.Mode,
				},
			}

			if file.Contents.Inline != "" {
				newFile.Contents = ignTypes.FileContents{
					Source: (&url.URL{
						Scheme: "data",
						Opaque: "," + dataurl.EscapeString(file.Contents.Inline),
					}).String(),
				}
			}

			if file.Contents.Remote.Url != "" {
				source, err := url.Parse(file.Contents.Remote.Url)
				if err != nil {
					// if invalid, record error and continue
					convertReport := report.ReportFromError(err, report.EntryError)
					if n, err := getNodeChildPath(file_node, "contents", "remote", "url"); err == nil {
						line, col, _ := n.ValueLineCol(nil)
						convertReport.AddPosition(line, col, "")
					}
					r.Merge(convertReport)
					continue
				}

				// patch the yaml tree to look like the ignition tree by making contents
				// the remote section and changing the name from url -> source
				asYamlNode, ok := file_node.(astyaml.YamlNode)
				if ok {
					newContents, _ := getNodeChildPath(file_node, "contents", "remote")
					newContentsAsYaml := newContents.(astyaml.YamlNode)
					asYamlNode.ChangeKey("contents", "contents", newContentsAsYaml)

					url, _ := getNodeChild(newContents.(astyaml.YamlNode), "url")
					newContentsAsYaml.ChangeKey("url", "source", url.(astyaml.YamlNode))
				}

				newFile.Contents = ignTypes.FileContents{Source: source.String()}

			}

			if newFile.Contents == (ignTypes.FileContents{}) {
				newFile.Contents = ignTypes.FileContents{
					Source: "data:,",
				}
			}

			newFile.Contents.Compression = file.Contents.Remote.Compression
			newFile.Contents.Verification = convertVerification(file.Contents.Remote.Verification)

			out.Storage.Files = append(out.Storage.Files, newFile)
		}
		for _, dir := range in.Storage.Directories {
			out.Storage.Directories = append(out.Storage.Directories, ignTypes.Directory{
				Node: ignTypes.Node{
					Filesystem: dir.Filesystem,
					Path:       dir.Path,
					User: ignTypes.NodeUser{
						ID:   dir.User.Id,
						Name: dir.User.Name,
					},
					Group: ignTypes.NodeGroup{
						ID:   dir.Group.Id,
						Name: dir.Group.Name,
					},
				},
				DirectoryEmbedded1: ignTypes.DirectoryEmbedded1{
					Mode: dir.Mode,
				},
			})
		}
		for _, link := range in.Storage.Links {
			out.Storage.Links = append(out.Storage.Links, ignTypes.Link{
				Node: ignTypes.Node{
					Filesystem: link.Filesystem,
					Path:       link.Path,
					User: ignTypes.NodeUser{
						ID:   link.User.Id,
						Name: link.User.Name,
					},
					Group: ignTypes.NodeGroup{
						ID:   link.Group.Id,
						Name: link.Group.Name,
					},
				},
				LinkEmbedded1: ignTypes.LinkEmbedded1{
					Hard:   link.Hard,
					Target: link.Target,
				},
			})
		}
		return out, r, ast
	})
}
<|endoftext|>


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

package dark

import (
	"github.com/google/gxui"
	"github.com/google/gxui/math"
	"github.com/google/gxui/mixins"
	"time"
)

type ProgressBar struct {
	mixins.ProgressBar
	theme        *Theme
	timer        *time.Timer
	chevrons     gxui.Canvas
	chevronWidth int
	scroll       int
}

func CreateProgressBar(theme *Theme) gxui.ProgressBar {
	b := &ProgressBar{}
	b.Init(b, theme)
	b.theme = theme
	b.OnAttach(func() {
		events := theme.Driver().Events()
		b.timer = time.AfterFunc(time.Millisecond*50, func() {
			b.scroll = (b.scroll + 1) % (b.chevronWidth * 2)
			events <- b.Redraw
			b.timer.Reset(time.Millisecond * 50)
		})
	})
	b.OnDetach(func() {
		if b.chevrons != nil {
			b.chevrons.Release()
			b.chevrons = nil
			b.timer.Stop()
			b.timer = nil
		}
	})
	b.SetBackgroundBrush(gxui.CreateBrush(gxui.Gray10))
	b.SetBorderPen(gxui.CreatePen(1, gxui.Gray40))
	return b
}

func (b *ProgressBar) Layout(r math.Rect) {
	b.ProgressBar.Layout(r)

	if b.chevrons != nil {
		b.chevrons.Release()
		b.chevrons = nil
	}
	if r.Size().Area() > 0 {
		b.chevrons = b.theme.Driver().CreateCanvas(r.Size())
		b.chevronWidth = r.H() / 2
		cw := b.chevronWidth
		for x := -cw * 2; x < r.W(); x += cw * 2 {
			// x0    x2
			// |  x1 |  x3
			//    |     |
			// A-----B    - y0
			//  \     \
			//   \     \
			//    F     C - y1
			//   /     /
			//  /     /
			// E-----D    - y2
			y0, y1, y2 := 0, r.H()/2, r.H()
			x0, x1 := x, x+cw/2
			x2, x3 := x0+cw, x1+cw
			var chevron = gxui.Polygon{
				/* A */ gxui.PolygonVertex{Position: math.Point{X: x0, Y: y0}},
				/* B */ gxui.PolygonVertex{Position: math.Point{X: x2, Y: y0}},
				/* C */ gxui.PolygonVertex{Position: math.Point{X: x3, Y: y1}},
				/* D */ gxui.PolygonVertex{Position: math.Point{X: x2, Y: y2}},
				/* E */ gxui.PolygonVertex{Position: math.Point{X: x0, Y: y2}},
				/* F */ gxui.PolygonVertex{Position: math.Point{X: x1, Y: y1}},
			}
			b.chevrons.DrawPolygon(chevron, gxui.TransparentPen, gxui.CreateBrush(gxui.Gray30))
		}
		b.chevrons.Complete()
	}
}

func (b *ProgressBar) PaintProgress(c gxui.Canvas, r math.Rect, frac float32) {
	r.Max.X = math.Lerp(r.Min.X, r.Max.X, frac)
	c.DrawRect(r, gxui.CreateBrush(gxui.Gray50))
	c.Push()
	c.AddClip(r)
	c.DrawCanvas(b.chevrons, math.Point{X: b.scroll})
	c.Pop()
}
<commit_msg>progress bar: prevent some minor data races<commit_after>// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package dark

import (
	"time"

	"github.com/google/gxui"
	"github.com/google/gxui/math"
	"github.com/google/gxui/mixins"
)

type ProgressBar struct {
	mixins.ProgressBar
	theme        *Theme
	ticker       *time.Ticker
	chevrons     gxui.Canvas
	chevronWidth int
	scroll       int
}

func CreateProgressBar(theme *Theme) gxui.ProgressBar {
	b := &ProgressBar{}
	b.Init(b, theme)
	b.theme = theme

	b.OnAttach(func() {
		events := theme.Driver().Events()
		b.ticker = time.NewTicker(time.Millisecond * 50)
		go func() {
			for range b.ticker.C {
				select {
				case events <- b.animationTick:
				default:
					// Don't block if the event channel is saturated.
				}
			}
		}()
	})

	b.OnDetach(func() {
		if b.chevrons != nil {
			b.chevrons.Release()
			b.chevrons = nil
			b.ticker.Stop()
			b.ticker = nil
		}
	})
	b.SetBackgroundBrush(gxui.CreateBrush(gxui.Gray10))
	b.SetBorderPen(gxui.CreatePen(1, gxui.Gray40))
	return b
}

func (b *ProgressBar) animationTick() {
	if b.Attached() {
		b.scroll = (b.scroll + 1) % (b.chevronWidth * 2)
		b.Redraw()
	}
}

func (b *ProgressBar) Layout(r math.Rect) {
	b.ProgressBar.Layout(r)

	if b.chevrons != nil {
		b.chevrons.Release()
		b.chevrons = nil
	}
	if r.Size().Area() > 0 {
		b.chevrons = b.theme.Driver().CreateCanvas(r.Size())
		b.chevronWidth = r.H() / 2
		cw := b.chevronWidth
		for x := -cw * 2; x < r.W(); x += cw * 2 {
			// x0    x2
			// |  x1 |  x3
			//    |     |
			// A-----B    - y0
			//  \     \
			//   \     \
			//    F     C - y1
			//   /     /
			//  /     /
			// E-----D    - y2
			y0, y1, y2 := 0, r.H()/2, r.H()
			x0, x1 := x, x+cw/2
			x2, x3 := x0+cw, x1+cw
			var chevron = gxui.Polygon{
				/* A */ gxui.PolygonVertex{Position: math.Point{X: x0, Y: y0}},
				/* B */ gxui.PolygonVertex{Position: math.Point{X: x2, Y: y0}},
				/* C */ gxui.PolygonVertex{Position: math.Point{X: x3, Y: y1}},
				/* D */ gxui.PolygonVertex{Position: math.Point{X: x2, Y: y2}},
				/* E */ gxui.PolygonVertex{Position: math.Point{X: x0, Y: y2}},
				/* F */ gxui.PolygonVertex{Position: math.Point{X: x1, Y: y1}},
			}
			b.chevrons.DrawPolygon(chevron, gxui.TransparentPen, gxui.CreateBrush(gxui.Gray30))
		}
		b.chevrons.Complete()
	}
}

func (b *ProgressBar) PaintProgress(c gxui.Canvas, r math.Rect, frac float32) {
	r.Max.X = math.Lerp(r.Min.X, r.Max.X, frac)
	c.DrawRect(r, gxui.CreateBrush(gxui.Gray50))
	c.Push()
	c.AddClip(r)
	c.DrawCanvas(b.chevrons, math.Point{X: b.scroll})
	c.Pop()
}
<|endoftext|>


<commit_before>package server

import (
	"database/sql"
	"github.com/VinkDong/asset-alarm/log"
	"github.com/bitly/go-simplejson"
	"strconv"
)

type Record struct {
	Id       int64
	CreditId int64
	Type     string
	Amount   float64
	Credit   float64
	Debit    float64
	Time     string
}

func (c *Record) ConvertFormRow(rows *sql.Rows) error {
	var err error
	if err = rows.Scan(&c.Id, &c.CreditId, &c.Type, &c.Amount, &c.Credit, &c.Debit, &c.Time); err != nil {
		log.Error("convert rows to credit object error")
	}
	return err
}

func (r *Record) ConvertFromJson(js *simplejson.Json) {
	r.Id = js.Get("id").MustInt64()
	r.CreditId = js.Get("cid").MustInt64()
	r.Type = js.Get("type").MustString()
	r.Amount = js.Get("amount").MustFloat64()
	r.Credit = js.Get("credit").MustFloat64()
	r.Debit = js.Get("debit").MustFloat64()
	r.Time = js.Get("time").MustString()
}

func (r *Record) Save() error{
	var stmtSql string
	if r.Id == 0 {
		stmtSql = "INSERT INTO record(credit_id,type,amount,credit,debit,time) VALUES (?,?,?,?,?,?);"
	} else {
		stmtSql = "UPDATE record SET credit_id = ?,type = ? ,amount = ? ,credit = ? ,debit = ?, time = ? where id = " +
			strconv.FormatInt(r.Id, 8)
	}
	c := &Credit{}
	c.Browse(r.CreditId)
	c.Debit += r.Amount
	c.Balance += r.Amount
	err := c.Save()
	if err != nil {
		return err
	}
	tx, stmt, err := prepareStmt(stmtSql)
	if err != nil {
		log.Error(err)
		return err
	}
	defer stmt.Close()
	result, err := stmt.Exec(r.CreditId, r.Type, r.Amount, r.Credit, r.Debit, r.Time)
	if err != nil{
		return err
	}
	id, err := result.LastInsertId()
	if err != nil{
		return err
	}
	tx.Commit()
	r.Id = id
	return nil
}<commit_msg>fix record prefix from c to r<commit_after>package server

import (
	"database/sql"
	"github.com/VinkDong/asset-alarm/log"
	"github.com/bitly/go-simplejson"
	"strconv"
)

type Record struct {
	Id       int64
	CreditId int64
	Type     string
	Amount   float64
	Credit   float64
	Debit    float64
	Time     string
}

func (r *Record) ConvertFormRow(rows *sql.Rows) error {
	var err error
	if err = rows.Scan(&r.Id, &r.CreditId, &r.Type, &r.Amount, &r.Credit, &r.Debit, &r.Time); err != nil {
		log.Error("convert rows to credit object error")
	}
	return err
}

func (r *Record) ConvertFromJson(js *simplejson.Json) {
	r.Id = js.Get("id").MustInt64()
	r.CreditId = js.Get("cid").MustInt64()
	r.Type = js.Get("type").MustString()
	r.Amount = js.Get("amount").MustFloat64()
	r.Credit = js.Get("credit").MustFloat64()
	r.Debit = js.Get("debit").MustFloat64()
	r.Time = js.Get("time").MustString()
}

func (r *Record) Save() error{
	var stmtSql string
	if r.Id == 0 {
		stmtSql = "INSERT INTO record(credit_id,type,amount,credit,debit,time) VALUES (?,?,?,?,?,?);"
	} else {
		stmtSql = "UPDATE record SET credit_id = ?,type = ? ,amount = ? ,credit = ? ,debit = ?, time = ? where id = " +
			strconv.FormatInt(r.Id, 8)
	}
	c := &Credit{}
	c.Browse(r.CreditId)
	c.Debit += r.Amount
	c.Balance += r.Amount
	err := c.Save()
	if err != nil {
		return err
	}
	tx, stmt, err := prepareStmt(stmtSql)
	if err != nil {
		log.Error(err)
		return err
	}
	defer stmt.Close()
	result, err := stmt.Exec(r.CreditId, r.Type, r.Amount, r.Credit, r.Debit, r.Time)
	if err != nil{
		return err
	}
	id, err := result.LastInsertId()
	if err != nil{
		return err
	}
	tx.Commit()
	r.Id = id
	return nil
}<|endoftext|>