<commit_before>package data

//DB is used for referencing db type systems.
const DB = "db"

//SERVER is used for referencing server type systems.
const SERVER = "server"

//TOOL is used for referencing tool type systems.
const TOOL = "tool"

//WEB is used for referencing web type systems.
const WEB = "web"

// Definition stores information about a system, used for importing data only.
type Definition struct {
	ID          string
	Name        string
	Type        string
	User        string
	Password    string
	URL         string
	Server      string
	DB          string
	Host        string
	Port        string
	SID         string
	Env         string
	Location    []string
	Responsible []string
	Notes       []string
}

// YamlData stores information about all systems, used for importing data only.
type YamlData struct {
	Defs []Definition
}

//ConfigMeta contains properties which are not part of the system information, for internal use.
type ConfigMeta struct {
	IsValid bool
}

//User contains information about login credentials.
type User struct {
	Name     string `json:"name"`
	User     string `json:"user"`
	Password string `json:"password"`
}

// Config stores data about a system, used for managing and exporting data.
type Config struct {
	ID          string     `json:"id"`
	Name        string     `json:"name"`
	Type        string     `json:"type"`
	User        string     `json:"user"`
	Password    string     `json:"password,omitempty"`
	URL         string     `json:"url"`
	Server      string     `json:"server,omitempty"`
	DB          string     `json:"db,omitempty"`
	Host        string     `json:"host,omitempty"`
	Port        string     `json:"port,omitempty"`
	SID         string     `json:"sid,omitempty"`
	Env         string     `json:"env"`
	Location    []string   `json:"location,omitempty"`
	Responsible []string   `json:"responsible,omitempty"`
	Notes       []string   `json:"notes,omitempty"`
	Meta        ConfigMeta `json:"-"`
}
<commit_msg>Omit empty environment and user in JSON<commit_after>package data

//DB is used for referencing db type systems.
const DB = "db"

//SERVER is used for referencing server type systems.
const SERVER = "server"

//TOOL is used for referencing tool type systems.
const TOOL = "tool"

//WEB is used for referencing web type systems.
const WEB = "web"

// Definition stores information about a system, used for importing data only.
type Definition struct {
	ID          string
	Name        string
	Type        string
	User        string
	Password    string
	URL         string
	Server      string
	DB          string
	Host        string
	Port        string
	SID         string
	Env         string
	Location    []string
	Responsible []string
	Notes       []string
}

// YamlData stores information about all systems, used for importing data only.
type YamlData struct {
	Defs []Definition
}

//ConfigMeta contains properties which are not part of the system information, for internal use.
type ConfigMeta struct {
	IsValid bool
}

//User contains information about login credentials.
type User struct {
	Name     string `json:"name"`
	User     string `json:"user"`
	Password string `json:"password"`
}

// Config stores data about a system, used for managing and exporting data.
type Config struct {
	ID          string     `json:"id"`
	Name        string     `json:"name"`
	Type        string     `json:"type"`
	User        string     `json:"user,omitempty"`
	Password    string     `json:"password,omitempty"`
	URL         string     `json:"url"`
	Server      string     `json:"server,omitempty"`
	DB          string     `json:"db,omitempty"`
	Host        string     `json:"host,omitempty"`
	Port        string     `json:"port,omitempty"`
	SID         string     `json:"sid,omitempty"`
	Env         string     `json:"env,omitempty"`
	Location    []string   `json:"location,omitempty"`
	Responsible []string   `json:"responsible,omitempty"`
	Notes       []string   `json:"notes,omitempty"`
	Meta        ConfigMeta `json:"-"`
}
<|endoftext|>


<commit_before>// Copyright 2013 The go-toggl 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 toggl

import (
	"errors"
	"fmt"
	"time"
)

// ProjectUsersService handles communication with the workspace related
// methods of the Toggl API.
//
// Toggl API docs: https://github.com/toggl/toggl_api_docs/blob/master/chapters/workspaces.md
type ProjectUsersService struct {
	client *Client
}

// ProjectUser represents association between project and user.
type ProjectUser struct {
	ID          int        `json:"id,omitempty"`
	ProjectID   int        `json:"pid,omitempty"`
	UserID      int        `json:"uid,omitempty"`
	WorkspaceID int        `json:"wid,omitempty"`
	Manager     bool       `json:"manager,omitempty"`
	Rate        float64    `json:"rate,omitempty"`
	At          *time.Time `json:"time,omitempty"`
}

// ProjectUserResponse acts as a response wrapper where response returns
// in format of "data": Project's object.
type ProjectUserResponse struct {
	Data *ProjectUser `json:"data,omitempty"`
}

// ProjectUserCreate represents posted data to be sent to project users endpoint.
type ProjectUserCreate struct {
	ProjectUser *ProjectUser `json:"project_user,omitempty"`
}

// Create a project user.
//
// Toggl API docs: https://github.com/toggl/toggl_api_docs/blob/master/chapters/project_users.md#create-a-project-user
func (s *ProjectUsersService) Create(pu *ProjectUser) (*ProjectUser, error) {
	u := "project_users"
	puc := &ProjectUserCreate{ProjectUser: pu}
	req, err := s.client.NewRequest("POST", u, puc)
	if err != nil {
		return nil, err
	}

	data := new(ProjectUserResponse)
	_, err = s.client.Do(req, data)

	return data.Data, err
}
<commit_msg>Removed unused imported package on project users.<commit_after>// Copyright 2013 The go-toggl 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 toggl

import (
	"time"
)

// ProjectUsersService handles communication with the workspace related
// methods of the Toggl API.
//
// Toggl API docs: https://github.com/toggl/toggl_api_docs/blob/master/chapters/workspaces.md
type ProjectUsersService struct {
	client *Client
}

// ProjectUser represents association between project and user.
type ProjectUser struct {
	ID          int        `json:"id,omitempty"`
	ProjectID   int        `json:"pid,omitempty"`
	UserID      int        `json:"uid,omitempty"`
	WorkspaceID int        `json:"wid,omitempty"`
	Manager     bool       `json:"manager,omitempty"`
	Rate        float64    `json:"rate,omitempty"`
	At          *time.Time `json:"time,omitempty"`
}

// ProjectUserResponse acts as a response wrapper where response returns
// in format of "data": Project's object.
type ProjectUserResponse struct {
	Data *ProjectUser `json:"data,omitempty"`
}

// ProjectUserCreate represents posted data to be sent to project users endpoint.
type ProjectUserCreate struct {
	ProjectUser *ProjectUser `json:"project_user,omitempty"`
}

// Create a project user.
//
// Toggl API docs: https://github.com/toggl/toggl_api_docs/blob/master/chapters/project_users.md#create-a-project-user
func (s *ProjectUsersService) Create(pu *ProjectUser) (*ProjectUser, error) {
	u := "project_users"
	puc := &ProjectUserCreate{ProjectUser: pu}
	req, err := s.client.NewRequest("POST", u, puc)
	if err != nil {
		return nil, err
	}

	data := new(ProjectUserResponse)
	_, err = s.client.Do(req, data)

	return data.Data, err
}
<|endoftext|>


<commit_before>package tokenizer

// Tokenizer is an interface for tokenizers.
type Tokenizer interface {
	// Next processes the next token and returns true
	// if there are more tokens to process.
	Next() bool
	// Token returns the current token.
	// It must be called after Next.
	Token() string
}

type chain struct {
	tokenizers []Tokenizer
	tokIndex   int
	token      string
}

// Chain returns a Tokenizer that combines the given tokenizers into a chain.
//
// The Next method of chain gets tokens serially from the chained tokenizers
// until the last one returns false. For example, the following code:
//
// 	ch := tokenizer.Chain(tokenizer.Words("hello world"), tokenizer.Words("this is me"))
// 	for ch.Next() {
//		fmt.Printf("%s, ", ch.Token())
//	}
//
// will print:
//
//	hello, world, this, is, me,
//
func Chain(tokenizers ...Tokenizer) Tokenizer {
	return &chain{tokenizers: tokenizers}
}

func (ch *chain) Next() bool {
	for {
		if ch.tokenizers[ch.tokIndex].Next() {
			return true
		}
		ch.tokIndex++
		if ch.tokIndex >= len(ch.tokenizers) {
			return false
		}
	}
}

func (ch *chain) Token() string {
	return ch.tokenizers[ch.tokIndex].Token()
}
<commit_msg>tokenizer: add comment.<commit_after>// Package tokenizer declares interface for tokenizing input,
// and implements a words tokenizer.
package tokenizer

// Tokenizer is an interface for tokenizers.
type Tokenizer interface {
	// Next processes the next token and returns true
	// if there are more tokens to process.
	Next() bool
	// Token returns the current token.
	// It must be called after Next.
	Token() string
}

type chain struct {
	tokenizers []Tokenizer
	tokIndex   int
	token      string
}

// Chain returns a Tokenizer that combines the given tokenizers into a chain.
//
// The Next method of chain gets tokens serially from the chained tokenizers
// until the last one returns false. For example, the following code:
//
// 	ch := tokenizer.Chain(tokenizer.Words("hello world"), tokenizer.Words("this is me"))
// 	for ch.Next() {
//		fmt.Printf("%s, ", ch.Token())
//	}
//
// will print:
//
//	hello, world, this, is, me,
//
func Chain(tokenizers ...Tokenizer) Tokenizer {
	return &chain{tokenizers: tokenizers}
}

func (ch *chain) Next() bool {
	for {
		if ch.tokenizers[ch.tokIndex].Next() {
			return true
		}
		ch.tokIndex++
		if ch.tokIndex >= len(ch.tokenizers) {
			return false
		}
	}
}

func (ch *chain) Token() string {
	return ch.tokenizers[ch.tokIndex].Token()
}
<|endoftext|>


<commit_before>package sudoku

type CellList []*Cell

type intList []int

func getRow(cell *Cell) int {
	return cell.Row
}

func getCol(cell *Cell) int {
	return cell.Col
}

func getBlock(cell *Cell) int {
	return cell.Block
}

func (self CellList) SameRow() bool {
	return self.CollectNums(getRow).Same()
}

func (self CellList) SameCol() bool {
	return self.CollectNums(getCol).Same()
}

func (self CellList) SameBlock() bool {
	return self.CollectNums(getBlock).Same()
}

func (self CellList) FilterByPossible(possible int) CellList {
	//TODO: test this
	filter := func(cell *Cell) bool {
		return cell.Possible(possible)
	}
	return self.Filter(filter)
}

func (self CellList) CollectNums(fetcher func(*Cell) int) intList {
	var result intList
	for _, cell := range self {
		result = append(result, fetcher(cell))
	}
	return result
}

func (self CellList) Filter(filter func(*Cell) bool) CellList {
	var result CellList
	for _, cell := range self {
		if filter(cell) {
			result = append(result, cell)
		}
	}
	return result
}

func (self intList) Same() bool {
	if len(self) == 0 {
		return true
	}
	target := self[0]
	for _, num := range self {
		if target != num {
			return false
		}
	}
	return true
}
<commit_msg>Define Row() and Col() on CellList.<commit_after>package sudoku

type CellList []*Cell

type intList []int

func getRow(cell *Cell) int {
	return cell.Row
}

func getCol(cell *Cell) int {
	return cell.Col
}

func getBlock(cell *Cell) int {
	return cell.Block
}

func (self CellList) SameRow() bool {
	return self.CollectNums(getRow).Same()
}

func (self CellList) SameCol() bool {
	return self.CollectNums(getCol).Same()
}

func (self CellList) SameBlock() bool {
	return self.CollectNums(getBlock).Same()
}

func (self CellList) Row() int {
	//Will return the row of a random item.
	if len(self) == 0 {
		return 0
	}
	return self[0].Row
}

func (self CellList) Col() int {
	if len(self) == 0 {
		return 0
	}
	return self[0].Col
}

func (self CellList) FilterByPossible(possible int) CellList {
	//TODO: test this
	filter := func(cell *Cell) bool {
		return cell.Possible(possible)
	}
	return self.Filter(filter)
}

func (self CellList) CollectNums(fetcher func(*Cell) int) intList {
	var result intList
	for _, cell := range self {
		result = append(result, fetcher(cell))
	}
	return result
}

func (self CellList) Filter(filter func(*Cell) bool) CellList {
	var result CellList
	for _, cell := range self {
		if filter(cell) {
			result = append(result, cell)
		}
	}
	return result
}

func (self intList) Same() bool {
	if len(self) == 0 {
		return true
	}
	target := self[0]
	for _, num := range self {
		if target != num {
			return false
		}
	}
	return true
}
<|endoftext|>


<commit_before>package main

import "fmt"

// pass slice as function argument
func addValue(foo []string) {
	foo = append(foo, "c")
	fmt.Println("modify foo", foo)
}

func main() {
	foo := []string{"a", "b"}
	fmt.Println("before foo:", foo)
	addValue(foo)
	fmt.Println("after foo:", foo)
}
<commit_msg>update slice example.<commit_after>package main

import "fmt"

// pass slice as function argument
func addValue(foo []string) {
	foo = append(foo, "c")
	fmt.Println("modify foo", foo)
}

func main() {
	foo := []string{"a", "b"}
	fmt.Println("before foo:", foo)
	addValue(foo)
	fmt.Println("after foo:", foo)
	bar := foo[:1]
	fmt.Println("bar:", bar)
	s1 := append(bar, "c")
	fmt.Println("foo:", foo)
	fmt.Println("s1:", s1)
	s2 := append(bar, "d")
	fmt.Println("foo:", foo)
	fmt.Println("s2:", s2)
	s3 := append(bar, "e", "f")
	fmt.Println("foo:", foo)
	fmt.Println("s3:", s3)
}
<|endoftext|>


<commit_before>package wca

const (
	EConsole         = 0x0
	EMultimedia      = 0x1
	ECommunications  = 0x2
	ERole_enum_count = 0x3
)

const (
	DELETE       = 0x00010000
	READ_CONTROL = 0x00020000
	SYNCHRONIZE  = 0x00100000
	WRITE_DAC    = 0x00040000
	WRITE_OWNER  = 0x00080000
)

const (
	EVENT_ALL_ACCESS   = 0x1F0003
	EVENT_MODIFY_STATE = 0x0002
)

const (
	CREATE_EVENT_INITIAL_SET  = 0x00000002
	CREATE_EVENT_MANUAL_RESET = 0x00000001
)

// The following constants are defined in Audioclient.h.
const (
	AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY = 0x1
	AUDCLNT_BUFFERFLAGS_SILENT             = 0x2
	AUDCLNT_BUFFERFLAGS_TIMESTAMP_ERROR    = 0x4
)

const (
	AUDCLNT_STREAMFLAGS_CROSSPROCESS        = 0x00010000
	AUDCLNT_STREAMFLAGS_LOOPBACK            = 0x00020000
	AUDCLNT_STREAMFLAGS_EVENTCALLBACK       = 0x00040000
	AUDCLNT_STREAMFLAGS_NOPERSIST           = 0x00080000
	AUDCLNT_STREAMFLAGS_RATEADJUST          = 0x00100000
	AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM      = 0x80000000
	AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY = 0x08000000
)

// the following AUDCLNT_SHAREMODE enumeration values are defined in audiosessiontypes.h.
const (
	AUDCLNT_SHAREMODE_SHARED    = 0x0
	AUDCLNT_SHAREMODE_EXCLUSIVE = 0x1
)

const (
	ENDPOINT_SYSFX_ENABLED  = 0x00000000
	ENDPOINT_SYSFX_DISABLED = 0x00000001
)

const (
	DEVICE_STATE_ACTIVE     = 0x00000001
	DEVICE_STATE_DISABLED   = 0x00000002
	DEVICE_STATE_NOTPRESENT = 0x00000004
	DEVICE_STATE_UNPLUGGED  = 0x00000008
	DEVICE_STATEMASK_ALL    = 0x0000000F
)

const (
	ERender              = 0x0
	ECapture             = 0x1
	EAll                 = 0x2
	EDataFlow_enum_count = 0x3
)

const (
	STGM_READ       = 0x0
	STGM_WRITE      = 0x1
	STGM_READ_WRITE = 0x2
)

const (
	CLSCTX_INPROC_SERVER          = 0x1
	CLSCTX_INPROC_HANDLER         = 0x2
	CLSCTX_LOCAL_SERVER           = 0x4
	CLSCTX_INPROC_SERVER16        = 0x8
	CLSCTX_REMOTE_SERVER          = 0x10
	CLSCTX_INPROC_HANDLER16       = 0x20
	CLSCTX_RESERVED1              = 0x40
	CLSCTX_RESERVED2              = 0x80
	CLSCTX_RESERVED3              = 0x100
	CLSCTX_RESERVED4              = 0x200
	CLSCTX_NO_CODE_DOWNLOAD       = 0x400
	CLSCTX_RESERVED5              = 0x800
	CLSCTX_NO_CUSTOM_MARSHAL      = 0x1000
	CLSCTX_ENABLE_CODE_DOWNLOAD   = 0x2000
	CLSCTX_NO_FAILURE_LOG         = 0x4000
	CLSCTX_DISABLE_AAA            = 0x8000
	CLSCTX_ENABLE_AAA             = 0x10000
	CLSCTX_FROM_DEFAULT_CONTEXT   = 0x20000
	CLSCTX_ACTIVATE_32_BIT_SERVER = 0x40000
	CLSCTX_ACTIVATE_64_BIT_SERVER = 0x80000
	CLSCTX_ENABLE_CLOAKING        = 0x100000
	CLSCTX_APPCONTAINER           = 0x400000
	CLSCTX_ACTIVATE_AAA_AS_IU     = 0x800000
	CLSCTX_PS_DLL                 = 0x80000000
	CLSCTX_ALL                    = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER
)
<commit_msg>Add constant<commit_after>package wca

// The following constant is declared in MMReg.h.
const (
	WAVE_FORMAT_PCM = 0x1
)

// The following constant is declared in WinBase.h.
const (
	INFINITE = 0xFFFFFFFF // Infinite timeout
)

const (
	EConsole         = 0x0
	EMultimedia      = 0x1
	ECommunications  = 0x2
	ERole_enum_count = 0x3
)

const (
	DELETE       = 0x00010000
	READ_CONTROL = 0x00020000
	SYNCHRONIZE  = 0x00100000
	WRITE_DAC    = 0x00040000
	WRITE_OWNER  = 0x00080000
)

const (
	EVENT_ALL_ACCESS   = 0x1F0003
	EVENT_MODIFY_STATE = 0x0002
)

const (
	CREATE_EVENT_INITIAL_SET  = 0x00000002
	CREATE_EVENT_MANUAL_RESET = 0x00000001
)

// The following constants are defined in Audioclient.h.
const (
	AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY = 0x1
	AUDCLNT_BUFFERFLAGS_SILENT             = 0x2
	AUDCLNT_BUFFERFLAGS_TIMESTAMP_ERROR    = 0x4
)

const (
	AUDCLNT_STREAMFLAGS_CROSSPROCESS        = 0x00010000
	AUDCLNT_STREAMFLAGS_LOOPBACK            = 0x00020000
	AUDCLNT_STREAMFLAGS_EVENTCALLBACK       = 0x00040000
	AUDCLNT_STREAMFLAGS_NOPERSIST           = 0x00080000
	AUDCLNT_STREAMFLAGS_RATEADJUST          = 0x00100000
	AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM      = 0x80000000
	AUDCLNT_STREAMFLAGS_SRC_DEFAULT_QUALITY = 0x08000000
)

// the following AUDCLNT_SHAREMODE enumeration values are defined in audiosessiontypes.h.
const (
	AUDCLNT_SHAREMODE_SHARED    = 0x0
	AUDCLNT_SHAREMODE_EXCLUSIVE = 0x1
)

const (
	ENDPOINT_SYSFX_ENABLED  = 0x00000000
	ENDPOINT_SYSFX_DISABLED = 0x00000001
)

const (
	DEVICE_STATE_ACTIVE     = 0x00000001
	DEVICE_STATE_DISABLED   = 0x00000002
	DEVICE_STATE_NOTPRESENT = 0x00000004
	DEVICE_STATE_UNPLUGGED  = 0x00000008
	DEVICE_STATEMASK_ALL    = 0x0000000F
)

const (
	ERender              = 0x0
	ECapture             = 0x1
	EAll                 = 0x2
	EDataFlow_enum_count = 0x3
)

const (
	STGM_READ       = 0x0
	STGM_WRITE      = 0x1
	STGM_READ_WRITE = 0x2
)

const (
	CLSCTX_INPROC_SERVER          = 0x1
	CLSCTX_INPROC_HANDLER         = 0x2
	CLSCTX_LOCAL_SERVER           = 0x4
	CLSCTX_INPROC_SERVER16        = 0x8
	CLSCTX_REMOTE_SERVER          = 0x10
	CLSCTX_INPROC_HANDLER16       = 0x20
	CLSCTX_RESERVED1              = 0x40
	CLSCTX_RESERVED2              = 0x80
	CLSCTX_RESERVED3              = 0x100
	CLSCTX_RESERVED4              = 0x200
	CLSCTX_NO_CODE_DOWNLOAD       = 0x400
	CLSCTX_RESERVED5              = 0x800
	CLSCTX_NO_CUSTOM_MARSHAL      = 0x1000
	CLSCTX_ENABLE_CODE_DOWNLOAD   = 0x2000
	CLSCTX_NO_FAILURE_LOG         = 0x4000
	CLSCTX_DISABLE_AAA            = 0x8000
	CLSCTX_ENABLE_AAA             = 0x10000
	CLSCTX_FROM_DEFAULT_CONTEXT   = 0x20000
	CLSCTX_ACTIVATE_32_BIT_SERVER = 0x40000
	CLSCTX_ACTIVATE_64_BIT_SERVER = 0x80000
	CLSCTX_ENABLE_CLOAKING        = 0x100000
	CLSCTX_APPCONTAINER           = 0x400000
	CLSCTX_ACTIVATE_AAA_AS_IU     = 0x800000
	CLSCTX_PS_DLL                 = 0x80000000
	CLSCTX_ALL                    = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER
)
<|endoftext|>


<commit_before>package dhcp

import (
	"bytes"
	"fmt"
	"net"
	"time"

	"github.com/onesimus-systems/dhcp4"
	"github.com/onesimus-systems/packet-guardian/src/common"
)

type Network struct {
	Global               *Global
	Name                 string
	Settings             *Settings
	RegisteredSettings   *Settings
	regOptionsCached     bool
	UnregisteredSettings *Settings
	unregOptionsCached   bool
	Subnets              []*Subnet
}

func newNetwork(name string) *Network {
	return &Network{
		Name:                 name,
		Settings:             newSettingsBlock(),
		RegisteredSettings:   newSettingsBlock(),
		UnregisteredSettings: newSettingsBlock(),
	}
}

// GetLeaseTime returns the lease time given the requested time req and if the client is registered.
// If req is 0 then the default lease time is returned. Otherwise it will return the lower of
// req and the maximum lease time. If the network does not have an explicitly set duration for either,
// it will get the duration from Global.
func (n *Network) GetLeaseTime(req time.Duration, registered bool) time.Duration {
	// TODO: Clean this up
	if registered {
		if req == 0 {
			if n.RegisteredSettings.DefaultLeaseTime != 0 {
				return n.RegisteredSettings.DefaultLeaseTime
			}
			if n.Settings.DefaultLeaseTime != 0 {
				return n.Settings.DefaultLeaseTime
			}
			// Save the result for later
			n.Settings.DefaultLeaseTime = n.Global.GetLeaseTime(req, registered)
			return n.Settings.DefaultLeaseTime
		}

		if n.RegisteredSettings.MaxLeaseTime != 0 {
			if req < n.RegisteredSettings.MaxLeaseTime {
				return req
			}
			return n.RegisteredSettings.MaxLeaseTime
		}
		if n.Settings.MaxLeaseTime != 0 {
			if req < n.Settings.MaxLeaseTime {
				return req
			}
			return n.Settings.MaxLeaseTime
		}

		// Save the result for later
		n.Settings.MaxLeaseTime = n.Global.GetLeaseTime(req, registered)

		if req < n.Settings.MaxLeaseTime {
			return req
		}
		return n.Settings.MaxLeaseTime
	}

	if req == 0 {
		if n.UnregisteredSettings.DefaultLeaseTime != 0 {
			return n.UnregisteredSettings.DefaultLeaseTime
		}
		if n.Settings.DefaultLeaseTime != 0 {
			return n.Settings.DefaultLeaseTime
		}
		// Save the result for later
		n.Settings.DefaultLeaseTime = n.Global.GetLeaseTime(req, registered)
		return n.Settings.DefaultLeaseTime
	}

	if n.UnregisteredSettings.MaxLeaseTime != 0 {
		if req < n.UnregisteredSettings.MaxLeaseTime {
			return req
		}
		return n.UnregisteredSettings.MaxLeaseTime
	}
	if n.Settings.MaxLeaseTime != 0 {
		if req < n.Settings.MaxLeaseTime {
			return req
		}
		return n.Settings.MaxLeaseTime
	}

	// Save the result for later
	n.Settings.MaxLeaseTime = n.Global.GetLeaseTime(req, registered)

	if req < n.Settings.MaxLeaseTime {
		return req
	}
	return n.Settings.MaxLeaseTime
}

func (n *Network) GetOptions(registered bool) dhcp4.Options {
	if registered && n.regOptionsCached {
		return n.RegisteredSettings.Options
	} else if !registered && n.unregOptionsCached {
		return n.UnregisteredSettings.Options
	}

	higher := n.Global.GetOptions(registered)
	if registered {
		// Merge network "global" setting into registered settings
		for c, v := range n.Settings.Options {
			if _, ok := n.RegisteredSettings.Options[c]; !ok {
				n.RegisteredSettings.Options[c] = v
			}
		}
		// Merge Global setting into registered setting
		for c, v := range higher {
			if _, ok := n.RegisteredSettings.Options[c]; !ok {
				n.RegisteredSettings.Options[c] = v
			}
		}
		n.regOptionsCached = true
		return n.RegisteredSettings.Options
	}

	// Merge network "global" setting into unregistered settings
	for c, v := range n.Settings.Options {
		if _, ok := n.UnregisteredSettings.Options[c]; !ok {
			n.UnregisteredSettings.Options[c] = v
		}
	}
	// Merge Global setting into unregistered setting
	for c, v := range higher {
		if _, ok := n.UnregisteredSettings.Options[c]; !ok {
			n.UnregisteredSettings.Options[c] = v
		}
	}
	n.unregOptionsCached = true
	return n.UnregisteredSettings.Options
}

func (n *Network) Includes(ip net.IP) bool {
	for _, s := range n.Subnets {
		if s.Includes(ip) {
			return true
		}
	}
	return false
}

func (n *Network) GetFreeLease(e *common.Environment, registered bool) *Lease {
	for _, s := range n.Subnets {
		if s.AllowUnknown == registered {
			continue
		}
		if l := s.GetFreeLease(e); l != nil {
			return l
		}
	}
	return nil
}

func (n *Network) GetLeaseByMAC(mac net.HardwareAddr, registered bool) *Lease {
	for _, s := range n.Subnets {
		if s.AllowUnknown == registered {
			continue
		}
		for _, p := range s.Pools {
			for _, l := range p.Leases {
				if bytes.Equal(l.MAC, mac) {
					return l
				}
			}
		}
	}
	return nil
}

func (n *Network) GetLeaseByIP(ip net.IP, registered bool) *Lease {
	for _, s := range n.Subnets {
		if s.AllowUnknown == registered {
			continue
		}
		for _, p := range s.Pools {
			if l, ok := p.Leases[ip.String()]; ok {
				return l
			}
		}
	}
	return nil
}

func (n *Network) Print() {
	fmt.Printf("\n---Network Configuration - %s---\n", n.Name)
	fmt.Println("\n--Network Settings--")
	n.Settings.Print()
	fmt.Println("\n--Network Registered Settings--")
	n.RegisteredSettings.Print()
	fmt.Println("\n--Network Unregistered Settings--")
	n.UnregisteredSettings.Print()
	fmt.Println("\n--Subnets in network--")
	for _, s := range n.Subnets {
		s.Print()
	}
}
<commit_msg>Fixed issue with unregistered clients receiving registered lease time<commit_after>package dhcp

import (
	"bytes"
	"fmt"
	"net"
	"time"

	"github.com/onesimus-systems/dhcp4"
	"github.com/onesimus-systems/packet-guardian/src/common"
)

type Network struct {
	Global               *Global
	Name                 string
	Settings             *Settings
	RegisteredSettings   *Settings
	regOptionsCached     bool
	UnregisteredSettings *Settings
	unregOptionsCached   bool
	Subnets              []*Subnet
}

func newNetwork(name string) *Network {
	return &Network{
		Name:                 name,
		Settings:             newSettingsBlock(),
		RegisteredSettings:   newSettingsBlock(),
		UnregisteredSettings: newSettingsBlock(),
	}
}

// GetLeaseTime returns the lease time given the requested time req and if the client is registered.
// If req is 0 then the default lease time is returned. Otherwise it will return the lower of
// req and the maximum lease time. If the network does not have an explicitly set duration for either,
// it will get the duration from Global.
func (n *Network) GetLeaseTime(req time.Duration, registered bool) time.Duration {
	// TODO: Clean this up
	if registered {
		if req == 0 {
			if n.RegisteredSettings.DefaultLeaseTime != 0 {
				return n.RegisteredSettings.DefaultLeaseTime
			}
			if n.Settings.DefaultLeaseTime != 0 {
				return n.Settings.DefaultLeaseTime
			}
			// Save the result for later
			n.RegisteredSettings.DefaultLeaseTime = n.Global.GetLeaseTime(req, registered)
			return n.RegisteredSettings.DefaultLeaseTime
		}

		if n.RegisteredSettings.MaxLeaseTime != 0 {
			if req < n.RegisteredSettings.MaxLeaseTime {
				return req
			}
			return n.RegisteredSettings.MaxLeaseTime
		}
		if n.Settings.MaxLeaseTime != 0 {
			if req < n.Settings.MaxLeaseTime {
				return req
			}
			return n.Settings.MaxLeaseTime
		}

		// Save the result for later
		n.RegisteredSettings.MaxLeaseTime = n.Global.GetLeaseTime(req, registered)

		if req < n.RegisteredSettings.MaxLeaseTime {
			return req
		}
		return n.RegisteredSettings.MaxLeaseTime
	}

	if req == 0 {
		if n.UnregisteredSettings.DefaultLeaseTime != 0 {
			return n.UnregisteredSettings.DefaultLeaseTime
		}
		if n.Settings.DefaultLeaseTime != 0 {
			return n.Settings.DefaultLeaseTime
		}
		// Save the result for later
		n.UnregisteredSettings.DefaultLeaseTime = n.Global.GetLeaseTime(req, registered)
		return n.UnregisteredSettings.DefaultLeaseTime
	}

	if n.UnregisteredSettings.MaxLeaseTime != 0 {
		if req < n.UnregisteredSettings.MaxLeaseTime {
			return req
		}
		return n.UnregisteredSettings.MaxLeaseTime
	}
	if n.Settings.MaxLeaseTime != 0 {
		if req < n.Settings.MaxLeaseTime {
			return req
		}
		return n.Settings.MaxLeaseTime
	}

	// Save the result for later
	n.UnregisteredSettings.MaxLeaseTime = n.Global.GetLeaseTime(req, registered)

	if req < n.UnregisteredSettings.MaxLeaseTime {
		return req
	}
	return n.UnregisteredSettings.MaxLeaseTime
}

func (n *Network) GetOptions(registered bool) dhcp4.Options {
	if registered && n.regOptionsCached {
		return n.RegisteredSettings.Options
	} else if !registered && n.unregOptionsCached {
		return n.UnregisteredSettings.Options
	}

	higher := n.Global.GetOptions(registered)
	if registered {
		// Merge network "global" setting into registered settings
		for c, v := range n.Settings.Options {
			if _, ok := n.RegisteredSettings.Options[c]; !ok {
				n.RegisteredSettings.Options[c] = v
			}
		}
		// Merge Global setting into registered setting
		for c, v := range higher {
			if _, ok := n.RegisteredSettings.Options[c]; !ok {
				n.RegisteredSettings.Options[c] = v
			}
		}
		n.regOptionsCached = true
		return n.RegisteredSettings.Options
	}

	// Merge network "global" setting into unregistered settings
	for c, v := range n.Settings.Options {
		if _, ok := n.UnregisteredSettings.Options[c]; !ok {
			n.UnregisteredSettings.Options[c] = v
		}
	}
	// Merge Global setting into unregistered setting
	for c, v := range higher {
		if _, ok := n.UnregisteredSettings.Options[c]; !ok {
			n.UnregisteredSettings.Options[c] = v
		}
	}
	n.unregOptionsCached = true
	return n.UnregisteredSettings.Options
}

func (n *Network) Includes(ip net.IP) bool {
	for _, s := range n.Subnets {
		if s.Includes(ip) {
			return true
		}
	}
	return false
}

func (n *Network) GetFreeLease(e *common.Environment, registered bool) *Lease {
	for _, s := range n.Subnets {
		if s.AllowUnknown == registered {
			continue
		}
		if l := s.GetFreeLease(e); l != nil {
			return l
		}
	}
	return nil
}

func (n *Network) GetLeaseByMAC(mac net.HardwareAddr, registered bool) *Lease {
	for _, s := range n.Subnets {
		if s.AllowUnknown == registered {
			continue
		}
		for _, p := range s.Pools {
			for _, l := range p.Leases {
				if bytes.Equal(l.MAC, mac) {
					return l
				}
			}
		}
	}
	return nil
}

func (n *Network) GetLeaseByIP(ip net.IP, registered bool) *Lease {
	for _, s := range n.Subnets {
		if s.AllowUnknown == registered {
			continue
		}
		for _, p := range s.Pools {
			if l, ok := p.Leases[ip.String()]; ok {
				return l
			}
		}
	}
	return nil
}

func (n *Network) Print() {
	fmt.Printf("\n---Network Configuration - %s---\n", n.Name)
	fmt.Println("\n--Network Settings--")
	n.Settings.Print()
	fmt.Println("\n--Network Registered Settings--")
	n.RegisteredSettings.Print()
	fmt.Println("\n--Network Unregistered Settings--")
	n.UnregisteredSettings.Print()
	fmt.Println("\n--Subnets in network--")
	for _, s := range n.Subnets {
		s.Print()
	}
}
<|endoftext|>


<commit_before>package main

import (
	"log"
	"os"
	"runtime"
	"strconv"
	"sync"

	"github.com/votinginfoproject/sms-worker/civic_api"
	"github.com/votinginfoproject/sms-worker/env"
	"github.com/votinginfoproject/sms-worker/logger"
	"github.com/votinginfoproject/sms-worker/queue"
	"github.com/votinginfoproject/sms-worker/response"
	"github.com/votinginfoproject/sms-worker/sms"
	"github.com/votinginfoproject/sms-worker/util"
	"github.com/yvasiyarov/gorelic"
)

func main() {
	env.Load()
	host, _ := os.Hostname()

	if os.Getenv("ENVIRONMENT") == "production" {
		agent := gorelic.NewAgent()
		agent.NewrelicName = "sms-worker" + "-" + host
		agent.NewrelicLicense = os.Getenv("NEWRELIC_TOKEN")
		agent.NewrelicPollInterval = 15
		agent.Run()
	}

	procs, err := strconv.Atoi(os.Getenv("PROCS"))
	if err != nil {
		log.Fatal("[ERROR] you must specify procs in the .env file")
	}
	runtime.GOMAXPROCS(procs)

	routines, err := strconv.Atoi(os.Getenv("ROUTINES"))
	if err != nil {
		log.Fatal("[ERROR] you must specify routines in the .env file")
	}

	log.SetOutput(logger.New())

	api := civicApi.New(os.Getenv("CIVIC_API_KEY"), os.Getenv("CIVIC_API_ELECTION_ID"), util.MakeRequest)
	res := response.New(api)

	sms := sms.New(os.Getenv("TWILIO_SID"), os.Getenv("TWILIO_TOKEN"), os.Getenv("TWILIO_NUMBER"))

	queue := queue.New()
	queue.Connect()

	var wg sync.WaitGroup

	for i := 0; i < routines; i++ {
		wg.Add(1)

		go func(wg *sync.WaitGroup, routine int) {
			defer wg.Done()

			log.Print("[INFO] Started routine ", routine)

			for {
				message, number, rawMsg, getErr := queue.GetMessage(routine)
				if getErr != nil {
					log.Printf("[ERROR] [%d] %s", routine, getErr)
					continue
				}

				reply := res.Generate(message)

				log.Printf("[INFO] [%d] Sending '%s' To %s", routine, reply, number)

				sms.Send(reply, number)

				delErr := queue.DeleteMessage(rawMsg)
				if delErr != nil {
					log.Printf("[ERROR] [%d] %s", routine, delErr)
					continue
				}
			}
		}(&wg, i)
	}

	wg.Wait()
}
<commit_msg>continue on sms err<commit_after>package main

import (
	"log"
	"os"
	"runtime"
	"strconv"
	"sync"

	"github.com/votinginfoproject/sms-worker/civic_api"
	"github.com/votinginfoproject/sms-worker/env"
	"github.com/votinginfoproject/sms-worker/logger"
	"github.com/votinginfoproject/sms-worker/queue"
	"github.com/votinginfoproject/sms-worker/response"
	"github.com/votinginfoproject/sms-worker/sms"
	"github.com/votinginfoproject/sms-worker/util"
	"github.com/yvasiyarov/gorelic"
)

func main() {
	env.Load()
	host, _ := os.Hostname()

	if os.Getenv("ENVIRONMENT") == "production" {
		agent := gorelic.NewAgent()
		agent.NewrelicName = "sms-worker" + "-" + host
		agent.NewrelicLicense = os.Getenv("NEWRELIC_TOKEN")
		agent.NewrelicPollInterval = 15
		agent.Run()
	}

	procs, err := strconv.Atoi(os.Getenv("PROCS"))
	if err != nil {
		log.Fatal("[ERROR] you must specify procs in the .env file")
	}
	runtime.GOMAXPROCS(procs)

	routines, err := strconv.Atoi(os.Getenv("ROUTINES"))
	if err != nil {
		log.Fatal("[ERROR] you must specify routines in the .env file")
	}

	log.SetOutput(logger.New())

	api := civicApi.New(os.Getenv("CIVIC_API_KEY"), os.Getenv("CIVIC_API_ELECTION_ID"), util.MakeRequest)
	res := response.New(api)

	sms := sms.New(os.Getenv("TWILIO_SID"), os.Getenv("TWILIO_TOKEN"), os.Getenv("TWILIO_NUMBER"))

	queue := queue.New()
	queue.Connect()

	var wg sync.WaitGroup

	for i := 0; i < routines; i++ {
		wg.Add(1)

		go func(wg *sync.WaitGroup, routine int) {
			defer wg.Done()

			log.Print("[INFO] Started routine ", routine)

			for {
				message, number, rawMsg, getErr := queue.GetMessage(routine)
				if getErr != nil {
					log.Printf("[ERROR] [%d] %s", routine, getErr)
					continue
				}

				reply := res.Generate(message)

				log.Printf("[INFO] [%d] Sending '%s' To %s", routine, reply, number)

				smsErr := sms.Send(reply, number)
				if smsErr != nil {
					log.Printf("[ERROR] [%d] %s", routine, smsErr)
					continue
				}

				delErr := queue.DeleteMessage(rawMsg)
				if delErr != nil {
					log.Printf("[ERROR] [%d] %s", routine, delErr)
					continue
				}
			}
		}(&wg, i)
	}

	wg.Wait()
}
<|endoftext|>


<commit_before>// Copyright 2016 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 bigquery

import (
	"context"
	"errors"
	"math"
	"reflect"
	"testing"
	"time"

	"cloud.google.com/go/civil"

	bq "google.golang.org/api/bigquery/v2"
)

var scalarTests = []struct {
	val  interface{}
	want string
}{
	{int64(0), "0"},
	{3.14, "3.14"},
	{3.14159e-87, "3.14159e-87"},
	{true, "true"},
	{"string", "string"},
	{"\u65e5\u672c\u8a9e\n", "\u65e5\u672c\u8a9e\n"},
	{math.NaN(), "NaN"},
	{[]byte("foo"), "Zm9v"}, // base64 encoding of "foo"
	{time.Date(2016, 3, 20, 4, 22, 9, 5000, time.FixedZone("neg1-2", -3720)),
		"2016-03-20 04:22:09.000005-01:02"},
	{civil.Date{2016, 3, 20}, "2016-03-20"},
	{civil.Time{4, 5, 6, 789000000}, "04:05:06.789000"},
	{civil.DateTime{civil.Date{2016, 3, 20}, civil.Time{4, 5, 6, 789000000}}, "2016-03-20 04:05:06.789000"},
}

type S1 struct {
	A int
	B *S2
	C bool
}

type S2 struct {
	D string
	e int
}

var s1 = S1{
	A: 1,
	B: &S2{D: "s"},
	C: true,
}

func sval(s string) bq.QueryParameterValue {
	return bq.QueryParameterValue{Value: s}
}

func TestParamValueScalar(t *testing.T) {
	for _, test := range scalarTests {
		got, err := paramValue(reflect.ValueOf(test.val))
		if err != nil {
			t.Errorf("%v: got %v, want nil", test.val, err)
			continue
		}
		want := sval(test.want)
		if !reflect.DeepEqual(got, want) {
			t.Errorf("%v:\ngot  %+v\nwant %+v", test.val, got, want)
		}
	}
}

func TestParamValueArray(t *testing.T) {
	qpv := bq.QueryParameterValue{ArrayValues: []*bq.QueryParameterValue{
		{Value: "1"},
		{Value: "2"},
	},
	}
	for _, test := range []struct {
		val  interface{}
		want bq.QueryParameterValue
	}{
		{[]int(nil), bq.QueryParameterValue{}},
		{[]int{}, bq.QueryParameterValue{}},
		{[]int{1, 2}, qpv},
		{[2]int{1, 2}, qpv},
	} {
		got, err := paramValue(reflect.ValueOf(test.val))
		if err != nil {
			t.Fatal(err)
		}
		if !reflect.DeepEqual(got, test.want) {
			t.Errorf("%#v:\ngot  %+v\nwant %+v", test.val, got, test.want)
		}
	}
}

func TestParamValueStruct(t *testing.T) {
	got, err := paramValue(reflect.ValueOf(s1))
	if err != nil {
		t.Fatal(err)
	}
	want := bq.QueryParameterValue{
		StructValues: map[string]bq.QueryParameterValue{
			"A": sval("1"),
			"B": bq.QueryParameterValue{
				StructValues: map[string]bq.QueryParameterValue{
					"D": sval("s"),
				},
			},
			"C": sval("true"),
		},
	}
	if !reflect.DeepEqual(got, want) {
		t.Errorf("got  %+v\nwant %+v", got, want)
	}
}

func TestParamValueErrors(t *testing.T) {
	// paramValue lets a few invalid types through, but paramType catches them.
	// Since we never call one without the other that's fine.
	for _, val := range []interface{}{nil, new([]int)} {
		_, err := paramValue(reflect.ValueOf(val))
		if err == nil {
			t.Errorf("%v (%T): got nil, want error", val, val)
		}
	}
}

func TestParamType(t *testing.T) {
	for _, test := range []struct {
		val  interface{}
		want *bq.QueryParameterType
	}{
		{0, int64ParamType},
		{uint32(32767), int64ParamType},
		{3.14, float64ParamType},
		{float32(3.14), float64ParamType},
		{math.NaN(), float64ParamType},
		{true, boolParamType},
		{"", stringParamType},
		{"string", stringParamType},
		{time.Now(), timestampParamType},
		{[]byte("foo"), bytesParamType},
		{[]int{}, &bq.QueryParameterType{Type: "ARRAY", ArrayType: int64ParamType}},
		{[3]bool{}, &bq.QueryParameterType{Type: "ARRAY", ArrayType: boolParamType}},
		{S1{}, &bq.QueryParameterType{
			Type: "STRUCT",
			StructTypes: []*bq.QueryParameterTypeStructTypes{
				{Name: "A", Type: int64ParamType},
				{Name: "B", Type: &bq.QueryParameterType{
					Type: "STRUCT",
					StructTypes: []*bq.QueryParameterTypeStructTypes{
						{Name: "D", Type: stringParamType},
					},
				}},
				{Name: "C", Type: boolParamType},
			},
		}},
	} {
		got, err := paramType(reflect.TypeOf(test.val))
		if err != nil {
			t.Fatal(err)
		}
		if !reflect.DeepEqual(got, test.want) {
			t.Errorf("%v (%T): got %v, want %v", test.val, test.val, got, test.want)
		}
	}
}

func TestParamTypeErrors(t *testing.T) {
	for _, val := range []interface{}{
		nil, uint(0), new([]int), make(chan int),
	} {
		_, err := paramType(reflect.TypeOf(val))
		if err == nil {
			t.Errorf("%v (%T): got nil, want error", val, val)
		}
	}
}

func TestIntegration_ScalarParam(t *testing.T) {
	c := getClient(t)
	for _, test := range scalarTests {
		got, err := paramRoundTrip(c, test.val)
		if err != nil {
			t.Fatal(err)
		}
		if !equal(got, test.val) {
			t.Errorf("\ngot  %#v (%T)\nwant %#v (%T)", got, got, test.val, test.val)
		}
	}
}

func TestIntegration_OtherParam(t *testing.T) {
	c := getClient(t)
	for _, test := range []struct {
		val  interface{}
		want interface{}
	}{
		{[]int(nil), []Value(nil)},
		{[]int{}, []Value(nil)},
		{[]int{1, 2}, []Value{int64(1), int64(2)}},
		{[3]int{1, 2, 3}, []Value{int64(1), int64(2), int64(3)}},
		{S1{}, []Value{int64(0), nil, false}},
		{s1, []Value{int64(1), []Value{"s"}, true}},
	} {
		got, err := paramRoundTrip(c, test.val)
		if err != nil {
			t.Fatal(err)
		}
		if !equal(got, test.want) {
			t.Errorf("\ngot  %#v (%T)\nwant %#v (%T)", got, got, test.want, test.want)
		}
	}
}

func paramRoundTrip(c *Client, x interface{}) (Value, error) {
	q := c.Query("select ?")
	q.Parameters = []QueryParameter{{Value: x}}
	it, err := q.Read(context.Background())
	if err != nil {
		return nil, err
	}
	var val []Value
	err = it.Next(&val)
	if err != nil {
		return nil, err
	}
	if len(val) != 1 {
		return nil, errors.New("wrong number of values")
	}
	return val[0], nil
}

func equal(x1, x2 interface{}) bool {
	if reflect.TypeOf(x1) != reflect.TypeOf(x2) {
		return false
	}
	switch x1 := x1.(type) {
	case float64:
		if math.IsNaN(x1) {
			return math.IsNaN(x2.(float64))
		}
		return x1 == x2
	case time.Time:
		// BigQuery is only accurate to the microsecond.
		return x1.Round(time.Microsecond).Equal(x2.(time.Time).Round(time.Microsecond))
	default:
		return reflect.DeepEqual(x1, x2)
	}
}
<commit_msg>bigquery: fix import path for context<commit_after>// Copyright 2016 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 bigquery

import (
	"errors"
	"math"
	"reflect"
	"testing"
	"time"

	"cloud.google.com/go/civil"
	"golang.org/x/net/context"
	bq "google.golang.org/api/bigquery/v2"
)

var scalarTests = []struct {
	val  interface{}
	want string
}{
	{int64(0), "0"},
	{3.14, "3.14"},
	{3.14159e-87, "3.14159e-87"},
	{true, "true"},
	{"string", "string"},
	{"\u65e5\u672c\u8a9e\n", "\u65e5\u672c\u8a9e\n"},
	{math.NaN(), "NaN"},
	{[]byte("foo"), "Zm9v"}, // base64 encoding of "foo"
	{time.Date(2016, 3, 20, 4, 22, 9, 5000, time.FixedZone("neg1-2", -3720)),
		"2016-03-20 04:22:09.000005-01:02"},
	{civil.Date{2016, 3, 20}, "2016-03-20"},
	{civil.Time{4, 5, 6, 789000000}, "04:05:06.789000"},
	{civil.DateTime{civil.Date{2016, 3, 20}, civil.Time{4, 5, 6, 789000000}}, "2016-03-20 04:05:06.789000"},
}

type S1 struct {
	A int
	B *S2
	C bool
}

type S2 struct {
	D string
	e int
}

var s1 = S1{
	A: 1,
	B: &S2{D: "s"},
	C: true,
}

func sval(s string) bq.QueryParameterValue {
	return bq.QueryParameterValue{Value: s}
}

func TestParamValueScalar(t *testing.T) {
	for _, test := range scalarTests {
		got, err := paramValue(reflect.ValueOf(test.val))
		if err != nil {
			t.Errorf("%v: got %v, want nil", test.val, err)
			continue
		}
		want := sval(test.want)
		if !reflect.DeepEqual(got, want) {
			t.Errorf("%v:\ngot  %+v\nwant %+v", test.val, got, want)
		}
	}
}

func TestParamValueArray(t *testing.T) {
	qpv := bq.QueryParameterValue{ArrayValues: []*bq.QueryParameterValue{
		{Value: "1"},
		{Value: "2"},
	},
	}
	for _, test := range []struct {
		val  interface{}
		want bq.QueryParameterValue
	}{
		{[]int(nil), bq.QueryParameterValue{}},
		{[]int{}, bq.QueryParameterValue{}},
		{[]int{1, 2}, qpv},
		{[2]int{1, 2}, qpv},
	} {
		got, err := paramValue(reflect.ValueOf(test.val))
		if err != nil {
			t.Fatal(err)
		}
		if !reflect.DeepEqual(got, test.want) {
			t.Errorf("%#v:\ngot  %+v\nwant %+v", test.val, got, test.want)
		}
	}
}

func TestParamValueStruct(t *testing.T) {
	got, err := paramValue(reflect.ValueOf(s1))
	if err != nil {
		t.Fatal(err)
	}
	want := bq.QueryParameterValue{
		StructValues: map[string]bq.QueryParameterValue{
			"A": sval("1"),
			"B": bq.QueryParameterValue{
				StructValues: map[string]bq.QueryParameterValue{
					"D": sval("s"),
				},
			},
			"C": sval("true"),
		},
	}
	if !reflect.DeepEqual(got, want) {
		t.Errorf("got  %+v\nwant %+v", got, want)
	}
}

func TestParamValueErrors(t *testing.T) {
	// paramValue lets a few invalid types through, but paramType catches them.
	// Since we never call one without the other that's fine.
	for _, val := range []interface{}{nil, new([]int)} {
		_, err := paramValue(reflect.ValueOf(val))
		if err == nil {
			t.Errorf("%v (%T): got nil, want error", val, val)
		}
	}
}

func TestParamType(t *testing.T) {
	for _, test := range []struct {
		val  interface{}
		want *bq.QueryParameterType
	}{
		{0, int64ParamType},
		{uint32(32767), int64ParamType},
		{3.14, float64ParamType},
		{float32(3.14), float64ParamType},
		{math.NaN(), float64ParamType},
		{true, boolParamType},
		{"", stringParamType},
		{"string", stringParamType},
		{time.Now(), timestampParamType},
		{[]byte("foo"), bytesParamType},
		{[]int{}, &bq.QueryParameterType{Type: "ARRAY", ArrayType: int64ParamType}},
		{[3]bool{}, &bq.QueryParameterType{Type: "ARRAY", ArrayType: boolParamType}},
		{S1{}, &bq.QueryParameterType{
			Type: "STRUCT",
			StructTypes: []*bq.QueryParameterTypeStructTypes{
				{Name: "A", Type: int64ParamType},
				{Name: "B", Type: &bq.QueryParameterType{
					Type: "STRUCT",
					StructTypes: []*bq.QueryParameterTypeStructTypes{
						{Name: "D", Type: stringParamType},
					},
				}},
				{Name: "C", Type: boolParamType},
			},
		}},
	} {
		got, err := paramType(reflect.TypeOf(test.val))
		if err != nil {
			t.Fatal(err)
		}
		if !reflect.DeepEqual(got, test.want) {
			t.Errorf("%v (%T): got %v, want %v", test.val, test.val, got, test.want)
		}
	}
}

func TestParamTypeErrors(t *testing.T) {
	for _, val := range []interface{}{
		nil, uint(0), new([]int), make(chan int),
	} {
		_, err := paramType(reflect.TypeOf(val))
		if err == nil {
			t.Errorf("%v (%T): got nil, want error", val, val)
		}
	}
}

func TestIntegration_ScalarParam(t *testing.T) {
	c := getClient(t)
	for _, test := range scalarTests {
		got, err := paramRoundTrip(c, test.val)
		if err != nil {
			t.Fatal(err)
		}
		if !equal(got, test.val) {
			t.Errorf("\ngot  %#v (%T)\nwant %#v (%T)", got, got, test.val, test.val)
		}
	}
}

func TestIntegration_OtherParam(t *testing.T) {
	c := getClient(t)
	for _, test := range []struct {
		val  interface{}
		want interface{}
	}{
		{[]int(nil), []Value(nil)},
		{[]int{}, []Value(nil)},
		{[]int{1, 2}, []Value{int64(1), int64(2)}},
		{[3]int{1, 2, 3}, []Value{int64(1), int64(2), int64(3)}},
		{S1{}, []Value{int64(0), nil, false}},
		{s1, []Value{int64(1), []Value{"s"}, true}},
	} {
		got, err := paramRoundTrip(c, test.val)
		if err != nil {
			t.Fatal(err)
		}
		if !equal(got, test.want) {
			t.Errorf("\ngot  %#v (%T)\nwant %#v (%T)", got, got, test.want, test.want)
		}
	}
}

func paramRoundTrip(c *Client, x interface{}) (Value, error) {
	q := c.Query("select ?")
	q.Parameters = []QueryParameter{{Value: x}}
	it, err := q.Read(context.Background())
	if err != nil {
		return nil, err
	}
	var val []Value
	err = it.Next(&val)
	if err != nil {
		return nil, err
	}
	if len(val) != 1 {
		return nil, errors.New("wrong number of values")
	}
	return val[0], nil
}

func equal(x1, x2 interface{}) bool {
	if reflect.TypeOf(x1) != reflect.TypeOf(x2) {
		return false
	}
	switch x1 := x1.(type) {
	case float64:
		if math.IsNaN(x1) {
			return math.IsNaN(x2.(float64))
		}
		return x1 == x2
	case time.Time:
		// BigQuery is only accurate to the microsecond.
		return x1.Round(time.Microsecond).Equal(x2.(time.Time).Round(time.Microsecond))
	default:
		return reflect.DeepEqual(x1, x2)
	}
}
<|endoftext|>


<commit_before>/*
Package contextio provides a simple way to sign API requests for http://Context.IO.

The simplest usage is to use DoJSON() to return a json byte array that you can use elsewhere in your code.
For more advanced usage, you can use Do() and parse through the http.Response struct yourself. It is not
specific to an API version, so you can use it to make any request you would make through http://console.Context.IO.
*/
package contextio

import (
	"bytes"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strings"

	"github.com/garyburd/go-oauth/oauth"
)

const (
	// max memory that ParseMultipartForm will use, see https://golang.org/pkg/net/http/#Request.ParseMultipartForm
	defaultMaxMemory = 32 << 21 // 64 MB
)

// the default host that the library contacts
const defaultAPIHost = "api.context.io"

// ContextIO is a struct containing the authentication information and a pointer to the oauth client
type ContextIO struct {
	key     string
	secret  string
	client  *oauth.Client
	apiHost string
}

// NewContextIO returns a ContextIO struct based on your CIO User and Secret
func NewContextIO(key, secret string) *ContextIO {
	c := &oauth.Client{
		Credentials: oauth.Credentials{
			Token:  key,
			Secret: secret,
		},
	}

	return &ContextIO{
		key:     key,
		secret:  secret,
		client:  c,
		apiHost: defaultAPIHost,
	}
}

// SetAPIHost sets the domain (i.e. "api.context.io) for the requests, useful if you are mocking the API for testing
func (c *ContextIO) SetAPIHost(h string) *ContextIO {
	c.apiHost = h
	return c
}

// NewRequest generates a request and signs it
func (c *ContextIO) NewRequest(method, q string, queryParams url.Values, body *string) (req *http.Request, err error) {
	// make sure q has a slash in front of it
	if q[0:1] != "/" {
		q = "/" + q
	}

	query := c.apiHost + q
	if len(queryParams) > 0 {
		query = query + "?" + queryParams.Encode()
	}
	req, err = http.NewRequest(method, "https://"+query, strings.NewReader(*body))
	if err != nil {
		return nil, err
	}
	req.URL.Opaque = q
	req.Header.Set("User-Agent", "GoContextIO Simple Library v. 0.2")

	v := url.Values{}
	switch method {
	case "PUT", "POST", "DELETE":
		// need form data here if uploading
		req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

		v, err = url.ParseQuery(*body)
		if err != nil {
			return nil, err
		}
	}

	err = c.client.SetAuthorizationHeader(req.Header, nil, req.Method, req.URL, v)
	if err != nil {
		return nil, err
	}
	return req, nil
}

// AttachFile will create a file upload in the request, assumes NewRequest has already been called
func (c *ContextIO) AttachFile(req *http.Request, fieldName, fileName string) error {
	f, err := os.Open(fileName)
	if err != nil {
		return err
	}
	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)
	part, err := writer.CreateFormFile(fieldName, filepath.Base(fileName))
	if err != nil {
		return err
	}
	_, err = io.Copy(part, f)
	if err != nil {
		return err
	}

	// transfer the existing post vals into the new body
	for key, valSlice := range req.PostForm {
		for _, val := range valSlice {
			err = writer.WriteField(key, val)
			if err != nil {
				return err
			}
		}
	}
	err = writer.Close()
	if err != nil {
		return err
	}
	rc := ioutil.NopCloser(body)
	req.Body = rc
	// update the form
	err = req.ParseMultipartForm(defaultMaxMemory)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", writer.FormDataContentType())
	return nil
}

// Do signs the request and returns an *http.Response. The body is a standard response.Body
// and must have defer response.Body.close().  Does not support uploads, use NewRequest and AttachFile for that.
// This is 2 legged authentication, and will not currently work with 3 legged authentication.
func (c *ContextIO) Do(method, q string, params url.Values, body *string) (response *http.Response, err error) {
	req, err := c.NewRequest(method, q, params, body)
	if err != nil {
		return nil, err
	}
	return http.DefaultClient.Do(req)
}

// DoJSON passes the request to Do and then returns the json in a []byte array
func (c *ContextIO) DoJSON(method, q string, params url.Values, body *string) (json []byte, err error) {
	response, err := c.Do(method, q, params, body)
	if err != nil {
		return nil, err
	}
	defer func() { _ = response.Body.Close() }()
	json, err = ioutil.ReadAll(response.Body)
	return json, err
}
<commit_msg>Panic fixes on nil body<commit_after>/*
Package contextio provides a simple way to sign API requests for http://Context.IO.

The simplest usage is to use DoJSON() to return a json byte array that you can use elsewhere in your code.
For more advanced usage, you can use Do() and parse through the http.Response struct yourself. It is not
specific to an API version, so you can use it to make any request you would make through http://console.Context.IO.
*/
package contextio

import (
	"bytes"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"net/url"
	"os"
	"path/filepath"
	"strings"

	"github.com/garyburd/go-oauth/oauth"
)

const (
	// max memory that ParseMultipartForm will use, see https://golang.org/pkg/net/http/#Request.ParseMultipartForm
	defaultMaxMemory = 32 << 21 // 64 MB
)

// the default host that the library contacts
const defaultAPIHost = "api.context.io"

// ContextIO is a struct containing the authentication information and a pointer to the oauth client
type ContextIO struct {
	key     string
	secret  string
	client  *oauth.Client
	apiHost string
}

// NewContextIO returns a ContextIO struct based on your CIO User and Secret
func NewContextIO(key, secret string) *ContextIO {
	c := &oauth.Client{
		Credentials: oauth.Credentials{
			Token:  key,
			Secret: secret,
		},
	}

	return &ContextIO{
		key:     key,
		secret:  secret,
		client:  c,
		apiHost: defaultAPIHost,
	}
}

// SetAPIHost sets the domain (i.e. "api.context.io) for the requests, useful if you are mocking the API for testing
func (c *ContextIO) SetAPIHost(h string) *ContextIO {
	c.apiHost = h
	return c
}

// NewRequest generates a request and signs it
func (c *ContextIO) NewRequest(method, q string, queryParams url.Values, body *string) (req *http.Request, err error) {
	// make sure q has a slash in front of it
	if q[0:1] != "/" {
		q = "/" + q
	}

	query := c.apiHost + q
	if len(queryParams) > 0 {
		query = query + "?" + queryParams.Encode()
	}
	if body != nil {
		// if body is nil, this produces a panic
		req, err = http.NewRequest(method, "https://"+query, strings.NewReader(*body))
	} else {
		req, err = http.NewRequest(method, "https://"+query, nil)
	}
	if err != nil {
		return nil, err
	}
	req.URL.Opaque = q
	req.Header.Set("User-Agent", "GoContextIO Simple Library v. 0.2")

	v := url.Values{}
	switch method {
	case "PUT", "POST", "DELETE":
		// need form data here if uploading
		req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

		if body != nil {
			v, err = url.ParseQuery(*body)
			if err != nil {
				return nil, err
			}
		}
	}

	err = c.client.SetAuthorizationHeader(req.Header, nil, req.Method, req.URL, v)
	if err != nil {
		return nil, err
	}
	return req, nil
}

// AttachFile will create a file upload in the request, assumes NewRequest has already been called
func (c *ContextIO) AttachFile(req *http.Request, fieldName, fileName string) error {
	f, err := os.Open(fileName)
	if err != nil {
		return err
	}
	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)
	part, err := writer.CreateFormFile(fieldName, filepath.Base(fileName))
	if err != nil {
		return err
	}
	_, err = io.Copy(part, f)
	if err != nil {
		return err
	}

	// transfer the existing post vals into the new body
	for key, valSlice := range req.PostForm {
		for _, val := range valSlice {
			err = writer.WriteField(key, val)
			if err != nil {
				return err
			}
		}
	}
	err = writer.Close()
	if err != nil {
		return err
	}
	rc := ioutil.NopCloser(body)
	req.Body = rc
	// update the form
	err = req.ParseMultipartForm(defaultMaxMemory)
	if err != nil {
		return err
	}
	req.Header.Set("Content-Type", writer.FormDataContentType())
	return nil
}

// Do signs the request and returns an *http.Response. The body is a standard response.Body
// and must have defer response.Body.close().  Does not support uploads, use NewRequest and AttachFile for that.
// This is 2 legged authentication, and will not currently work with 3 legged authentication.
func (c *ContextIO) Do(method, q string, params url.Values, body *string) (response *http.Response, err error) {
	req, err := c.NewRequest(method, q, params, body)
	if err != nil {
		return nil, err
	}
	return http.DefaultClient.Do(req)
}

// DoJSON passes the request to Do and then returns the json in a []byte array
func (c *ContextIO) DoJSON(method, q string, params url.Values, body *string) (json []byte, err error) {
	response, err := c.Do(method, q, params, body)
	if err != nil {
		return nil, err
	}
	defer func() { _ = response.Body.Close() }()
	json, err = ioutil.ReadAll(response.Body)
	return json, err
}
<|endoftext|>


<commit_before>package converter

import (
	"crypto/md5"
	"crypto/sha1"
	"encoding/base32"
	"encoding/base64"
	"encoding/csv"
	"encoding/hex"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"strconv"
	"strings"
	"time"
)

type ConversionFunc func(interface{}, *interface{}) error

type Conversion interface {
	// Convert func ConversionFunc
}

func Chain(left ConversionFunc, rights ...ConversionFunc) ConversionFunc {
	fn := left
	for _, right := range rights {
		fn = Pipe(fn, right)
	}
	return fn
}

func Pipe(left, right ConversionFunc) ConversionFunc {
	return func(in interface{}, output *interface{}) error {
		var tmpOutput interface{}

		err := left(in, &tmpOutput)
		if err != nil {
			return err
		}

		return right(tmpOutput, output)
	}
}

func ConvertBytesToBase64(in interface{}, out *interface{}) error {
	*out = base64.StdEncoding.EncodeToString(in.([]byte))
	return nil
}

func ConvertBase64ToBytes(in interface{}, out *interface{}) error {
	data, err := base64.StdEncoding.DecodeString(in.(string))
	if err != nil {
		return err
	}
	*out = data
	return nil
}

func ConvertBytesToBase32(in interface{}, out *interface{}) error {
	*out = base32.StdEncoding.EncodeToString(in.([]byte))
	return nil
}

func ConvertBase32ToBytes(in interface{}, out *interface{}) error {
	data, err := base32.StdEncoding.DecodeString(in.(string))
	if err != nil {
		return err
	}
	*out = data
	return nil
}

func ConvertBytesToString(in interface{}, out *interface{}) error {
	*out = string(in.([]byte))
	return nil
}

func ConvertStringToBytes(in interface{}, out *interface{}) error {
	*out = []byte(in.(string))
	return nil
}

func ConvertBytesToHex(in interface{}, out *interface{}) error {
	*out = hex.EncodeToString(in.([]byte))
	return nil
}

func ConvertHexToBytes(in interface{}, out *interface{}) error {
	data, err := hex.DecodeString(in.(string))
	if err != nil {
		return err
	}
	*out = data
	return nil
}

func ConvertIntegerToString(in interface{}, out *interface{}) error {
	*out = strconv.Itoa(in.(int))
	return nil
}

func ConvertStringToInteger(in interface{}, out *interface{}) (err error) {
	*out, err = strconv.Atoi(in.(string))
	return err
}

func ConvertStringToFloat(in interface{}, out *interface{}) (err error) {
	*out, err = strconv.ParseFloat(in.(string), 64)
	return err
}

func ConvertFloatToString(in interface{}, out *interface{}) (err error) {
	*out = strconv.FormatFloat(in.(float64), 'f', -1, 64)
	return err
}

func ConvertBytesToMd5sum(in interface{}, out *interface{}) (err error) {
	*out = fmt.Sprintf("%x", md5.Sum(in.([]byte)))
	return err
}

func ConvertBytesToSha1sum(in interface{}, out *interface{}) (err error) {
	*out = fmt.Sprintf("%x", sha1.Sum(in.([]byte)))
	return err
}

func ConvertJsonToStruct(in interface{}, out *interface{}) (err error) {
	return json.Unmarshal(in.([]byte), out)
}

func ConvertStructToJson(in interface{}, out *interface{}) (err error) {
	*out, err = json.Marshal(in)
	return err
}

func ConvertXmlToStruct(in interface{}, out *interface{}) (err error) {
	return xml.Unmarshal(in.([]byte), out)
}

func ConvertStructToXml(in interface{}, out *interface{}) (err error) {
	*out, err = xml.Marshal(in)
	return err
}

func ConvertStringToCsv(in interface{}, out *interface{}) (err error) {
	r := csv.NewReader(strings.NewReader(in.(string)))
	*out, err = r.ReadAll()
	return err
}

func Delayer(duration time.Duration) ConversionFunc {
	return func(in interface{}, out *interface{}) error {
		time.Sleep(duration)
		*out = in
		return nil
	}
}

var HundredMillisecondDelayer = Delayer(100 * time.Millisecond)
var OneSecondDelayer = Delayer(time.Second)
var TwoSecondDelayer = Delayer(2 * time.Second)
var FiveSecondDelayer = Delayer(5 * time.Second)
var TenSecondDelayer = Delayer(10 * time.Second)
var OneMinuteDelayer = Delayer(time.Minute)

func DateToTimeConverter(format string) ConversionFunc {
	return func(in interface{}, out *interface{}) (err error) {
		*out, err = time.Parse(format, in.(string))
		return err
	}
}

var ConvertANSICToTime = DateToTimeConverter(time.ANSIC)
var ConvertRFC3339ToTime = DateToTimeConverter(time.RFC3339)
var ConvertRFC822ToTime = DateToTimeConverter(time.RFC822)
var ConvertRFC850ToTime = DateToTimeConverter(time.RFC850)
var ConvertRFC1123ToTime = DateToTimeConverter(time.RFC1123)
var ConvertUnixDateToTime = DateToTimeConverter(time.UnixDate)

func ConvertTimeToUnix(in interface{}, out *interface{}) (err error) {
	*out = in.(time.Time).Unix()
	return nil
}
<commit_msg>Increase code coverage<commit_after>package converter

import (
	"crypto/md5"
	"crypto/sha1"
	"encoding/base32"
	"encoding/base64"
	"encoding/csv"
	"encoding/hex"
	"encoding/json"
	"encoding/xml"
	"fmt"
	"strconv"
	"strings"
	"time"
)

type ConversionFunc func(interface{}, *interface{}) error

type Conversion interface {
	// Convert func ConversionFunc
}

func Chain(left ConversionFunc, rights ...ConversionFunc) ConversionFunc {
	fn := left
	for _, right := range rights {
		fn = Pipe(fn, right)
	}
	return fn
}

func Pipe(left, right ConversionFunc) ConversionFunc {
	return func(in interface{}, output *interface{}) error {
		var tmpOutput interface{}

		if err := left(in, &tmpOutput); err != nil {
			return err
		}

		return right(tmpOutput, output)
	}
}

func ConvertBytesToBase64(in interface{}, out *interface{}) error {
	*out = base64.StdEncoding.EncodeToString(in.([]byte))
	return nil
}

func ConvertBase64ToBytes(in interface{}, out *interface{}) (err error) {
	*out, err = base64.StdEncoding.DecodeString(in.(string))
	return err
}

func ConvertBytesToBase32(in interface{}, out *interface{}) error {
	*out = base32.StdEncoding.EncodeToString(in.([]byte))
	return nil
}

func ConvertBase32ToBytes(in interface{}, out *interface{}) (err error) {
	*out, err = base32.StdEncoding.DecodeString(in.(string))
	return err
}

func ConvertBytesToString(in interface{}, out *interface{}) error {
	*out = string(in.([]byte))
	return nil
}

func ConvertStringToBytes(in interface{}, out *interface{}) error {
	*out = []byte(in.(string))
	return nil
}

func ConvertBytesToHex(in interface{}, out *interface{}) error {
	*out = hex.EncodeToString(in.([]byte))
	return nil
}

func ConvertHexToBytes(in interface{}, out *interface{}) (err error) {
	*out, err = hex.DecodeString(in.(string))
	return err
}

func ConvertIntegerToString(in interface{}, out *interface{}) error {
	*out = strconv.Itoa(in.(int))
	return nil
}

func ConvertStringToInteger(in interface{}, out *interface{}) (err error) {
	*out, err = strconv.Atoi(in.(string))
	return err
}

func ConvertStringToFloat(in interface{}, out *interface{}) (err error) {
	*out, err = strconv.ParseFloat(in.(string), 64)
	return err
}

func ConvertFloatToString(in interface{}, out *interface{}) (err error) {
	*out = strconv.FormatFloat(in.(float64), 'f', -1, 64)
	return err
}

func ConvertBytesToMd5sum(in interface{}, out *interface{}) (err error) {
	*out = fmt.Sprintf("%x", md5.Sum(in.([]byte)))
	return err
}

func ConvertBytesToSha1sum(in interface{}, out *interface{}) (err error) {
	*out = fmt.Sprintf("%x", sha1.Sum(in.([]byte)))
	return err
}

func ConvertJsonToStruct(in interface{}, out *interface{}) (err error) {
	return json.Unmarshal(in.([]byte), out)
}

func ConvertStructToJson(in interface{}, out *interface{}) (err error) {
	*out, err = json.Marshal(in)
	return err
}

func ConvertXmlToStruct(in interface{}, out *interface{}) (err error) {
	return xml.Unmarshal(in.([]byte), out)
}

func ConvertStructToXml(in interface{}, out *interface{}) (err error) {
	*out, err = xml.Marshal(in)
	return err
}

func ConvertStringToCsv(in interface{}, out *interface{}) (err error) {
	r := csv.NewReader(strings.NewReader(in.(string)))
	*out, err = r.ReadAll()
	return err
}

func Delayer(duration time.Duration) ConversionFunc {
	return func(in interface{}, out *interface{}) error {
		time.Sleep(duration)
		*out = in
		return nil
	}
}

var HundredMillisecondDelayer = Delayer(100 * time.Millisecond)
var OneSecondDelayer = Delayer(time.Second)
var TwoSecondDelayer = Delayer(2 * time.Second)
var FiveSecondDelayer = Delayer(5 * time.Second)
var TenSecondDelayer = Delayer(10 * time.Second)
var OneMinuteDelayer = Delayer(time.Minute)

func DateToTimeConverter(format string) ConversionFunc {
	return func(in interface{}, out *interface{}) (err error) {
		*out, err = time.Parse(format, in.(string))
		return err
	}
}

var ConvertANSICToTime = DateToTimeConverter(time.ANSIC)
var ConvertRFC3339ToTime = DateToTimeConverter(time.RFC3339)
var ConvertRFC822ToTime = DateToTimeConverter(time.RFC822)
var ConvertRFC850ToTime = DateToTimeConverter(time.RFC850)
var ConvertRFC1123ToTime = DateToTimeConverter(time.RFC1123)
var ConvertUnixDateToTime = DateToTimeConverter(time.UnixDate)

func ConvertTimeToUnix(in interface{}, out *interface{}) (err error) {
	*out = in.(time.Time).Unix()
	return nil
}
<|endoftext|>


<commit_before>// +build coprocess

//go:generate msgp
//msgp:ignore CoProcessor CoProcessMiddleware CoProcessMiddlewareConfig TykMiddleware

package main

import (
	"github.com/Sirupsen/logrus"
	"github.com/gorilla/context"
	"github.com/mitchellh/mapstructure"

	"github.com/TykTechnologies/tyk/coprocess"
	"github.com/TykTechnologies/tykcommon"

	"bytes"
	"errors"
	"io/ioutil"
	"net/http"
)

// EnableCoProcess will be overridden by config.EnableCoProcess.
var EnableCoProcess = false

// GlobalDispatcher will be implemented by the current CoProcess driver.
var GlobalDispatcher coprocess.Dispatcher

// CoProcessMiddleware is the basic CP middleware struct.
type CoProcessMiddleware struct {
	*TykMiddleware
	HookType         coprocess.HookType
	HookName         string
	MiddlewareDriver tykcommon.MiddlewareDriver
}

// CreateCoProcessMiddleware initializes a new CP middleware, takes hook type (pre, post, etc.), hook name ("my_hook") and driver ("python").
func CreateCoProcessMiddleware(hookName string, hookType coprocess.HookType, mwDriver tykcommon.MiddlewareDriver, tykMwSuper *TykMiddleware) func(http.Handler) http.Handler {
	dMiddleware := &CoProcessMiddleware{
		TykMiddleware:    tykMwSuper,
		HookType:         hookType,
		HookName:         hookName,
		MiddlewareDriver: mwDriver,
	}

	return CreateMiddleware(dMiddleware, tykMwSuper)
}

func doCoprocessReload() {
	log.WithFields(logrus.Fields{
		"prefix": "coprocess",
	}).Info("Reloading middlewares")
	GlobalDispatcher.Reload()

}

// CoProcessor represents a CoProcess during the request.
type CoProcessor struct {
	HookType   coprocess.HookType
	Middleware *CoProcessMiddleware
}

// GetObjectFromRequest constructs a CoProcessObject from a given http.Request.
func (c *CoProcessor) GetObjectFromRequest(r *http.Request) *coprocess.Object {

	defer r.Body.Close()
	originalBody, _ := ioutil.ReadAll(r.Body)

	var object *coprocess.Object
	var miniRequestObject *coprocess.MiniRequestObject

	miniRequestObject = &coprocess.MiniRequestObject{
		Headers:         ProtoMap(r.Header),
		SetHeaders:      make(map[string]string, 0),
		DeleteHeaders:   make([]string, 0),
		Body:            string(originalBody),
		Url:             r.URL.Path,
		Params:          ProtoMap(r.URL.Query()),
		AddParams:       make(map[string]string),
		ExtendedParams:  ProtoMap(nil),
		DeleteParams:    make([]string, 0),
		ReturnOverrides: &coprocess.ReturnOverrides{-1, ""},
	}

	object = &coprocess.Object{
		Request:  miniRequestObject,
		HookName: c.Middleware.HookName,
	}

	// If a middleware is set, take its HookType, otherwise override it with CoProcessor.HookType
	if c.Middleware != nil && c.HookType == 0 {
		c.HookType = c.Middleware.HookType
	}

	object.HookType = c.HookType

	object.Metadata = make(map[string]string, 0)
	object.Spec = make(map[string]string, 0)

	// object.Session = SessionState{}

	// Append spec data:
	if c.Middleware != nil {
		object.Spec = map[string]string{
			"OrgID": c.Middleware.TykMiddleware.Spec.OrgID,
			"APIID": c.Middleware.TykMiddleware.Spec.APIID,
		}
	}

	// Encode the session object (if not a pre-process & not a custom key check):
	if c.HookType != coprocess.HookType_Pre && c.HookType != coprocess.HookType_CustomKeyCheck {
		var session interface{}
		session = context.Get(r, SessionData)
		if session != nil {
			sessionState := session.(SessionState)
			object.Session = ProtoSessionState(sessionState)
		}
	}

	return object
}

// ObjectPostProcess does CoProcessObject post-processing (adding/removing headers or params, etc.).
func (c *CoProcessor) ObjectPostProcess(object *coprocess.Object, r *http.Request) {
	r.ContentLength = int64(len(object.Request.Body))
	r.Body = ioutil.NopCloser(bytes.NewBufferString(object.Request.Body))

	for _, dh := range object.Request.DeleteHeaders {
		r.Header.Del(dh)
	}

	for h, v := range object.Request.SetHeaders {
		r.Header.Set(h, v)
	}

	values := r.URL.Query()
	for _, k := range object.Request.DeleteParams {
		values.Del(k)
	}

	for p, v := range object.Request.AddParams {
		values.Set(p, v)
	}

	r.URL.RawQuery = values.Encode()
}

// CoProcessInit creates a new CoProcessDispatcher, it will be called when Tyk starts.
func CoProcessInit() (err error) {
	if config.CoProcessOptions.EnableCoProcess {
		GlobalDispatcher, err = NewCoProcessDispatcher()
		EnableCoProcess = true
	}
	return err
}

// CoProcessMiddlewareConfig holds the middleware configuration.
type CoProcessMiddlewareConfig struct {
	ConfigData map[string]string `mapstructure:"config_data" bson:"config_data" json:"config_data"`
}

// New lets you do any initialisations for the object can be done here
func (m *CoProcessMiddleware) New() {}

// GetConfig retrieves the configuration from the API config - we user mapstructure for this for simplicity
func (m *CoProcessMiddleware) GetConfig() (interface{}, error) {
	var thisModuleConfig CoProcessMiddlewareConfig

	err := mapstructure.Decode(m.TykMiddleware.Spec.APIDefinition.RawData, &thisModuleConfig)
	if err != nil {
		log.WithFields(logrus.Fields{
			"prefix": "jsvm",
		}).Error(err)
		return nil, err
	}

	return thisModuleConfig, nil
}

// IsEnabledForSpec checks if this middleware should be enabled for a given API.
func (m *CoProcessMiddleware) IsEnabledForSpec() bool {
	// This flag is true when Tyk has been compiled with CP support and when the configuration enables it.
	var enableCoProcess bool = config.CoProcessOptions.EnableCoProcess && EnableCoProcess
	// This flag indicates if the current spec specifies any CP custom middleware.
	var usesCoProcessMiddleware bool

	var supportedDrivers = []tykcommon.MiddlewareDriver{tykcommon.PythonDriver, tykcommon.LuaDriver, tykcommon.GrpcDriver}

	for _, driver := range supportedDrivers {
		if m.TykMiddleware.Spec.CustomMiddleware.Driver == driver && CoProcessName == string(driver) {
			usesCoProcessMiddleware = true
			break
		}
	}

	if usesCoProcessMiddleware && enableCoProcess {
		log.WithFields(logrus.Fields{
			"prefix": "coprocess",
		}).Debug("Enabling CP middleware.")
		return true
	}

	if usesCoProcessMiddleware && !enableCoProcess {
		log.WithFields(logrus.Fields{
			"prefix": "coprocess",
		}).Error("Your API specifies a CP custom middleware, either Tyk wasn't build with CP support or CP is not enabled in your Tyk configuration file!")
	}

	if !usesCoProcessMiddleware && m.TykMiddleware.Spec.CustomMiddleware.Driver != "" {
		log.WithFields(logrus.Fields{
			"prefix": "coprocess",
		}).Error("CP Driver not supported: ", m.TykMiddleware.Spec.CustomMiddleware.Driver)
	}

	return false
}

// ProcessRequest will run any checks on the request on the way through the system, return an error to have the chain fail
func (m *CoProcessMiddleware) ProcessRequest(w http.ResponseWriter, r *http.Request, configuration interface{}) (error, int) {
	log.WithFields(logrus.Fields{
		"prefix": "coprocess",
	}).Debug("CoProcess Request, HookType: ", m.HookType)

	if !EnableCoProcess {
		return nil, 200
	}

	var thisExtractor IdExtractor
	if m.TykMiddleware.Spec.EnableCoProcessAuth && m.TykMiddleware.Spec.CustomMiddleware.IdExtractor.Extractor != nil {
		log.Println("Using extractor, defining thisExtractor")
		thisExtractor = m.TykMiddleware.Spec.CustomMiddleware.IdExtractor.Extractor.(IdExtractor)
	}

	var returnOverrides ReturnOverrides
	var SessionID string

	if m.HookType == coprocess.HookType_CustomKeyCheck && thisExtractor != nil {
		SessionID, returnOverrides = thisExtractor.ExtractAndCheck(r)

		if returnOverrides.ResponseCode != 0 {
			if returnOverrides.ResponseError == "" {
				return nil, returnOverrides.ResponseCode
			} else {
				err := errors.New(returnOverrides.ResponseError)
				return err, returnOverrides.ResponseCode
			}
		}
	}

	// It's also possible to override the HookType:
	thisCoProcessor := CoProcessor{
		Middleware: m,
		// HookType: coprocess.PreHook,
	}

	object := thisCoProcessor.GetObjectFromRequest(r)

	returnObject := thisCoProcessor.Dispatch(object)

	thisCoProcessor.ObjectPostProcess(returnObject, r)

	authHeaderValue := returnObject.Metadata["token"]

	// The CP middleware indicates this is a bad auth:
	if returnObject.Request.ReturnOverrides.ResponseCode > 400 {

		log.WithFields(logrus.Fields{
			"path":   r.URL.Path,
			"origin": GetIPFromRequest(r),
			"key":    authHeaderValue,
		}).Info("Attempted access with invalid key.")

		// Fire Authfailed Event
		AuthFailed(m.TykMiddleware, r, authHeaderValue)

		// Report in health check
		ReportHealthCheckValue(m.Spec.Health, KeyFailure, "1")

		return errors.New("Key not authorised"), int(returnObject.Request.ReturnOverrides.ResponseCode)
	}

	// The CP middleware didn't setup a session:
	if m.HookType == coprocess.HookType_CustomKeyCheck && returnObject.Session == nil {
		return errors.New("Key not authorised"), 403
	}

	// The CP middleware did setup a session, and we should pass it to the ID extractor (and cache it):
	if thisExtractor != nil {
		returnedSessionState := TykSessionState(returnObject.Session)
		thisExtractor.PostProcess(r, returnedSessionState, SessionID)
		return nil, 200
	}

	return nil, 200
}
<commit_msg>Enhance CP auth when not using ID extractor.<commit_after>// +build coprocess

//go:generate msgp
//msgp:ignore CoProcessor CoProcessMiddleware CoProcessMiddlewareConfig TykMiddleware

package main

import (
	"github.com/Sirupsen/logrus"
	"github.com/gorilla/context"
	"github.com/mitchellh/mapstructure"

	"github.com/TykTechnologies/tyk/coprocess"
	"github.com/TykTechnologies/tykcommon"

	"bytes"
	"errors"
	"io/ioutil"
	"net/http"
)

// EnableCoProcess will be overridden by config.EnableCoProcess.
var EnableCoProcess = false

// GlobalDispatcher will be implemented by the current CoProcess driver.
var GlobalDispatcher coprocess.Dispatcher

// CoProcessMiddleware is the basic CP middleware struct.
type CoProcessMiddleware struct {
	*TykMiddleware
	HookType         coprocess.HookType
	HookName         string
	MiddlewareDriver tykcommon.MiddlewareDriver
}

// CreateCoProcessMiddleware initializes a new CP middleware, takes hook type (pre, post, etc.), hook name ("my_hook") and driver ("python").
func CreateCoProcessMiddleware(hookName string, hookType coprocess.HookType, mwDriver tykcommon.MiddlewareDriver, tykMwSuper *TykMiddleware) func(http.Handler) http.Handler {
	dMiddleware := &CoProcessMiddleware{
		TykMiddleware:    tykMwSuper,
		HookType:         hookType,
		HookName:         hookName,
		MiddlewareDriver: mwDriver,
	}

	return CreateMiddleware(dMiddleware, tykMwSuper)
}

func doCoprocessReload() {
	log.WithFields(logrus.Fields{
		"prefix": "coprocess",
	}).Info("Reloading middlewares")
	GlobalDispatcher.Reload()

}

// CoProcessor represents a CoProcess during the request.
type CoProcessor struct {
	HookType   coprocess.HookType
	Middleware *CoProcessMiddleware
}

// GetObjectFromRequest constructs a CoProcessObject from a given http.Request.
func (c *CoProcessor) GetObjectFromRequest(r *http.Request) *coprocess.Object {

	defer r.Body.Close()
	originalBody, _ := ioutil.ReadAll(r.Body)

	var object *coprocess.Object
	var miniRequestObject *coprocess.MiniRequestObject

	miniRequestObject = &coprocess.MiniRequestObject{
		Headers:         ProtoMap(r.Header),
		SetHeaders:      make(map[string]string, 0),
		DeleteHeaders:   make([]string, 0),
		Body:            string(originalBody),
		Url:             r.URL.Path,
		Params:          ProtoMap(r.URL.Query()),
		AddParams:       make(map[string]string),
		ExtendedParams:  ProtoMap(nil),
		DeleteParams:    make([]string, 0),
		ReturnOverrides: &coprocess.ReturnOverrides{-1, ""},
	}

	object = &coprocess.Object{
		Request:  miniRequestObject,
		HookName: c.Middleware.HookName,
	}

	// If a middleware is set, take its HookType, otherwise override it with CoProcessor.HookType
	if c.Middleware != nil && c.HookType == 0 {
		c.HookType = c.Middleware.HookType
	}

	object.HookType = c.HookType

	object.Metadata = make(map[string]string, 0)
	object.Spec = make(map[string]string, 0)

	// object.Session = SessionState{}

	// Append spec data:
	if c.Middleware != nil {
		object.Spec = map[string]string{
			"OrgID": c.Middleware.TykMiddleware.Spec.OrgID,
			"APIID": c.Middleware.TykMiddleware.Spec.APIID,
		}
	}

	// Encode the session object (if not a pre-process & not a custom key check):
	if c.HookType != coprocess.HookType_Pre && c.HookType != coprocess.HookType_CustomKeyCheck {
		var session interface{}
		session = context.Get(r, SessionData)
		if session != nil {
			sessionState := session.(SessionState)
			object.Session = ProtoSessionState(sessionState)
		}
	}

	return object
}

// ObjectPostProcess does CoProcessObject post-processing (adding/removing headers or params, etc.).
func (c *CoProcessor) ObjectPostProcess(object *coprocess.Object, r *http.Request) {
	r.ContentLength = int64(len(object.Request.Body))
	r.Body = ioutil.NopCloser(bytes.NewBufferString(object.Request.Body))

	for _, dh := range object.Request.DeleteHeaders {
		r.Header.Del(dh)
	}

	for h, v := range object.Request.SetHeaders {
		r.Header.Set(h, v)
	}

	values := r.URL.Query()
	for _, k := range object.Request.DeleteParams {
		values.Del(k)
	}

	for p, v := range object.Request.AddParams {
		values.Set(p, v)
	}

	r.URL.RawQuery = values.Encode()
}

// CoProcessInit creates a new CoProcessDispatcher, it will be called when Tyk starts.
func CoProcessInit() (err error) {
	if config.CoProcessOptions.EnableCoProcess {
		GlobalDispatcher, err = NewCoProcessDispatcher()
		EnableCoProcess = true
	}
	return err
}

// CoProcessMiddlewareConfig holds the middleware configuration.
type CoProcessMiddlewareConfig struct {
	ConfigData map[string]string `mapstructure:"config_data" bson:"config_data" json:"config_data"`
}

// New lets you do any initialisations for the object can be done here
func (m *CoProcessMiddleware) New() {}

// GetConfig retrieves the configuration from the API config - we user mapstructure for this for simplicity
func (m *CoProcessMiddleware) GetConfig() (interface{}, error) {
	var thisModuleConfig CoProcessMiddlewareConfig

	err := mapstructure.Decode(m.TykMiddleware.Spec.APIDefinition.RawData, &thisModuleConfig)
	if err != nil {
		log.WithFields(logrus.Fields{
			"prefix": "jsvm",
		}).Error(err)
		return nil, err
	}

	return thisModuleConfig, nil
}

// IsEnabledForSpec checks if this middleware should be enabled for a given API.
func (m *CoProcessMiddleware) IsEnabledForSpec() bool {
	// This flag is true when Tyk has been compiled with CP support and when the configuration enables it.
	var enableCoProcess bool = config.CoProcessOptions.EnableCoProcess && EnableCoProcess
	// This flag indicates if the current spec specifies any CP custom middleware.
	var usesCoProcessMiddleware bool

	var supportedDrivers = []tykcommon.MiddlewareDriver{tykcommon.PythonDriver, tykcommon.LuaDriver, tykcommon.GrpcDriver}

	for _, driver := range supportedDrivers {
		if m.TykMiddleware.Spec.CustomMiddleware.Driver == driver && CoProcessName == string(driver) {
			usesCoProcessMiddleware = true
			break
		}
	}

	if usesCoProcessMiddleware && enableCoProcess {
		log.WithFields(logrus.Fields{
			"prefix": "coprocess",
		}).Debug("Enabling CP middleware.")
		return true
	}

	if usesCoProcessMiddleware && !enableCoProcess {
		log.WithFields(logrus.Fields{
			"prefix": "coprocess",
		}).Error("Your API specifies a CP custom middleware, either Tyk wasn't build with CP support or CP is not enabled in your Tyk configuration file!")
	}

	if !usesCoProcessMiddleware && m.TykMiddleware.Spec.CustomMiddleware.Driver != "" {
		log.WithFields(logrus.Fields{
			"prefix": "coprocess",
		}).Error("CP Driver not supported: ", m.TykMiddleware.Spec.CustomMiddleware.Driver)
	}

	return false
}

// ProcessRequest will run any checks on the request on the way through the system, return an error to have the chain fail
func (m *CoProcessMiddleware) ProcessRequest(w http.ResponseWriter, r *http.Request, configuration interface{}) (error, int) {
	log.WithFields(logrus.Fields{
		"prefix": "coprocess",
	}).Debug("CoProcess Request, HookType: ", m.HookType)

	if !EnableCoProcess {
		return nil, 200
	}

	var thisExtractor IdExtractor
	if m.TykMiddleware.Spec.EnableCoProcessAuth && m.TykMiddleware.Spec.CustomMiddleware.IdExtractor.Extractor != nil {
		log.Println("Using extractor, defining thisExtractor")
		thisExtractor = m.TykMiddleware.Spec.CustomMiddleware.IdExtractor.Extractor.(IdExtractor)
	}

	var returnOverrides ReturnOverrides
	var SessionID string

	if m.HookType == coprocess.HookType_CustomKeyCheck && thisExtractor != nil {
		SessionID, returnOverrides = thisExtractor.ExtractAndCheck(r)

		if returnOverrides.ResponseCode != 0 {
			if returnOverrides.ResponseError == "" {
				return nil, returnOverrides.ResponseCode
			} else {
				err := errors.New(returnOverrides.ResponseError)
				return err, returnOverrides.ResponseCode
			}
		}
	}

	// It's also possible to override the HookType:
	thisCoProcessor := CoProcessor{
		Middleware: m,
		// HookType: coprocess.PreHook,
	}

	object := thisCoProcessor.GetObjectFromRequest(r)

	returnObject := thisCoProcessor.Dispatch(object)

	thisCoProcessor.ObjectPostProcess(returnObject, r)

	authHeaderValue := returnObject.Metadata["token"]

	// The CP middleware indicates this is a bad auth:
	if returnObject.Request.ReturnOverrides.ResponseCode > 400 {

		log.WithFields(logrus.Fields{
			"path":   r.URL.Path,
			"origin": GetIPFromRequest(r),
			"key":    authHeaderValue,
		}).Info("Attempted access with invalid key.")

		// Fire Authfailed Event
		AuthFailed(m.TykMiddleware, r, authHeaderValue)

		// Report in health check
		ReportHealthCheckValue(m.Spec.Health, KeyFailure, "1")

		return errors.New("Key not authorised"), int(returnObject.Request.ReturnOverrides.ResponseCode)
	}

	// Is this a CP authentication middleware?
	if m.HookType == coprocess.HookType_CustomKeyCheck {
		// The CP middleware didn't setup a session:
		if returnObject.Session == nil {
			return errors.New("Key not authorised"), 403
		}

		returnedSessionState := TykSessionState(returnObject.Session)

		if thisExtractor == nil {
			// This API is not using the ID extractor, but we've got a session:
			m.Spec.SessionManager.UpdateSession(authHeaderValue, returnedSessionState, m.Spec.APIDefinition.SessionLifetime)
			context.Set(r, SessionData, returnedSessionState)
			context.Set(r, AuthHeaderValue, authHeaderValue)
		} else {
			// The CP middleware did setup a session, we should pass it to the ID extractor (caching):
			thisExtractor.PostProcess(r, returnedSessionState, SessionID)
		}
	}

	return nil, 200
}
<|endoftext|>


<commit_before>package core

import

// For outputting stuff
(
	"fmt"
	"net"
	"time"
) // For networking stuff
// For exiting
// For reversing strings

var (
	ALL_ON          = []byte{0x42, 0x00, 0x55}
	ALL_WHITE       = []byte{0xC2, 0x00, 0x55}
	ALL_OFF         = []byte{0x41, 0x00, 0x55}
	ALL_DISCO       = []byte{0x4D, 0x00, 0x55}
	BRIGHTNESS_UP   = []byte{0x3C, 0x00, 0x55}
	BRIGHTNESS_DOWN = []byte{0x34, 0x00, 0x55}
	WARMER          = []byte{0x3E, 0x00, 0x55}
	COOLER          = []byte{0x3F, 0x00, 0x55}
	ALL_ON_FULL     = []byte{0xB5, 0x00, 0x55}
	ALL_NIGHTLIGHT  = []byte{0xB9, 0x00, 0x55}
	ZONE2_SYNCPAIR  = []byte{0x47, 0x00, 0x55}
	ZONE2_OFF       = []byte{0x33, 0x00, 0x55}
)

//Bridge LimitlessLed bridge
type Bridge struct {
	*net.UDPConn        //extending bridge capabilities
	ip           string // The name of the bridge
}

func Dial(host string) (*Bridge, error) {
	addr, err := net.ResolveUDPAddr("udp4", host)

	if err != nil {
		fmt.Println("Error Resolving")
		return nil, err
	}

	s, err := net.DialUDP("udp4", nil, addr)
	if err != nil {
		fmt.Println("Error dialing")
		return nil, err
	}
	return &Bridge{s, host}, err
}

func (bridge *Bridge) SendCommand(command []byte) {
	fmt.Println("Sending command")
	_, err := bridge.Write(command)
	if err != nil {
		fmt.Println("Error writing")
		return
	}
	time.Sleep(time.Millisecond * 100)
}
<commit_msg>More comments<commit_after>package core

import

// For outputting stuff

"net"

// For networking stuff
// For exiting
// For reversing strings

var (
	ALL_ON          = []byte{0x42, 0x00, 0x55}
	ALL_WHITE       = []byte{0xC2, 0x00, 0x55}
	ALL_OFF         = []byte{0x41, 0x00, 0x55}
	ALL_DISCO       = []byte{0x4D, 0x00, 0x55}
	BRIGHTNESS_UP   = []byte{0x3C, 0x00, 0x55}
	BRIGHTNESS_DOWN = []byte{0x34, 0x00, 0x55}
	WARMER          = []byte{0x3E, 0x00, 0x55}
	COOLER          = []byte{0x3F, 0x00, 0x55}
	ALL_ON_FULL     = []byte{0xB5, 0x00, 0x55}
	ALL_NIGHTLIGHT  = []byte{0xB9, 0x00, 0x55}
	ZONE2_SYNCPAIR  = []byte{0x47, 0x00, 0x55}
	ZONE2_OFF       = []byte{0x33, 0x00, 0x55}
)

//Bridge LimitlessLed bridge
type Bridge struct {
	*net.UDPConn        //extending bridge capabilities
	ip           string // The name of the bridge
}
<|endoftext|>


<commit_before>// Package swio provides additional utilities on top of the standard io package.
package swio

import (
	"errors"
	"io"
	"io/ioutil"
)

// ReadSeekerAt is the interface that groups io.ReadSeeker and io.ReaderAt.
type ReadSeekerAt interface {
	io.ReadSeeker
	io.ReaderAt
}

// SeekerPosition returns the current offset of an io.Seeker
func SeekerPosition(r io.Seeker) (int64, error) {
	return r.Seek(0, 1)
}

// SeekBuffer contains a reader where all data read from it is buffered, and
// thus both readable and seekable. It essentially augments bytes.Reader so
// that all data does not need to be read at once.
type SeekBuffer struct {
	r ReadSeekerAt
}

// Read reads from the internal buffer or source reader until b is filled or an error
// occurs.
func (s *SeekBuffer) Read(b []byte) (int, error) {
	return s.r.Read(b)
}

// Seek implements io.Seeker for SeekBuffer. If the new offset goes beyond what is
// buffered, SeekBuffer will read from the source reader until offset can be reached
// or an error is returned. If whence is 2, SeekBuffer will read until EOF or an error
// is reached.
func (s *SeekBuffer) Seek(offset int64, whence int) (int64, error) {
	return s.r.Seek(offset, whence)
}

// ReadAt implements io.ReaderAt for SeekBuffer.
func (s *SeekBuffer) ReadAt(b []byte, off int64) (int, error) {
	return s.r.ReadAt(b, off)
}

type seekBuffer struct {
	src      ReadCounter
	buf      []byte
	position int64
}

// NewSeekBuffer creates a new SeekBuffer using reader r. l is the initial capacity
// of the internal buffer. If r happens to be a ReadSeeker already, r is used directly
// without any additional copies of the data.
func NewSeekBuffer(r io.Reader, l int64) *SeekBuffer {
	if rs, ok := r.(ReadSeekerAt); ok {
		return &SeekBuffer{rs}
	}
	return &SeekBuffer{&seekBuffer{
		buf: make([]byte, 0, l),
		src: NewReadCounter(r),
	}}
}

// NewSeekBufferCloser creates a new SeekBuffer using ReadCloser r. l is the initial
// capacity of the internal buffer. The close method from r is forwarded to the returned
// ReadSeekerCloser.
func NewSeekBufferCloser(r io.ReadCloser, l int64) ReadSeekerCloser {
	return NewReadSeekerCloser(NewSeekBuffer(r, l), r.Close)
}

func (r *seekBuffer) ReadAt(b []byte, off int64) (n int, err error) {
	// cannot modify state - see io.ReaderAt
	if off < 0 {
		return 0, errors.New("swio.ReadAt: negative offset")
	}

	if off < int64(len(r.buf)) {
		n = copy(b, r.buf[off:])
		off += int64(n)
		b = b[n:]
	}

	// is the offset past what we have buffered?
	if off > int64(len(r.buf)) {
		buf := make([]byte, off-int64(len(r.buf)))
		// get src to the offset
		var read int
		read, err = io.ReadFull(r.src, buf)
		r.buf = append(r.buf, buf[:read]...)
		if err != nil {
			return
		}
	}

	secondRead, err := io.ReadFull(r.src, b)
	r.buf = append(r.buf, b[:secondRead]...)

	n += secondRead

	return
}

func (r *seekBuffer) Read(b []byte) (n int, err error) {
	unread := r.buf[r.position:]

	// Get as much as we can from unread
	n = copy(b, unread)

	// If we got all we need from unread, we're done
	if len(b) == n {
		r.position += int64(n)
		return
	}

	// Fill the rest of b with r.src
	srcn, err := r.src.Read(b[n:])

	// Add new read from src to r.buf
	r.buf = append(r.buf, b[n:]...)

	// Seek to new position in r.buf, so we don't read the latest from src again
	r.position += int64(srcn + n)

	return srcn + n, err
}

func (r *seekBuffer) Seek(offset int64, whence int) (int64, error) {
	var err error
	pos := r.position

	// Get new offset (relative to beginning)
	switch whence {
	case 0:
		// offset stays as it is
	case 1:
		offset = offset + pos
	case 2:
		var remainder []byte
		remainder, err = ioutil.ReadAll(r.src)
		r.buf = append(r.buf, remainder...)
		offset = int64(len(r.buf)) + offset
	default:
		return pos, errors.New("seek: invalid whence")
	}

	originalOffset := offset

	// Have we read far enough into src?
	if diff := offset - r.src.BytesRead(); diff > 0 {
		var n int

		buf := make([]byte, diff)

		// No. Read diff bytes into src.
		n, err = r.src.Read(buf)

		// Copy onto r.buf
		r.buf = append(r.buf, buf[:n]...)
		r.position += int64(n)

		// Make offset correction if we didn't read buf full
		offset -= diff - int64(n)
	}

	// If we reached the EOF, but we got to where we're going, ignore EOF.
	if err == io.EOF && offset == originalOffset {
		err = nil
	}

	r.position = offset
	return offset, err
}
<commit_msg>Use os whence constants<commit_after>// Package swio provides additional utilities on top of the standard io package.
package swio

import (
	"errors"
	"io"
	"io/ioutil"
	"os"
)

// ReadSeekerAt is the interface that groups io.ReadSeeker and io.ReaderAt.
type ReadSeekerAt interface {
	io.ReadSeeker
	io.ReaderAt
}

// SeekerPosition returns the current offset of an io.Seeker
func SeekerPosition(r io.Seeker) (int64, error) {
	return r.Seek(0, 1)
}

// SeekBuffer contains a reader where all data read from it is buffered, and
// thus both readable and seekable. It essentially augments bytes.Reader so
// that all data does not need to be read at once.
type SeekBuffer struct {
	r ReadSeekerAt
}

// Read reads from the internal buffer or source reader until b is filled or an error
// occurs.
func (s *SeekBuffer) Read(b []byte) (int, error) {
	return s.r.Read(b)
}

// Seek implements io.Seeker for SeekBuffer. If the new offset goes beyond what is
// buffered, SeekBuffer will read from the source reader until offset can be reached
// or an error is returned. If whence is 2, SeekBuffer will read until EOF or an error
// is reached.
func (s *SeekBuffer) Seek(offset int64, whence int) (int64, error) {
	return s.r.Seek(offset, whence)
}

// ReadAt implements io.ReaderAt for SeekBuffer.
func (s *SeekBuffer) ReadAt(b []byte, off int64) (int, error) {
	return s.r.ReadAt(b, off)
}

type seekBuffer struct {
	src      ReadCounter
	buf      []byte
	position int64
}

// NewSeekBuffer creates a new SeekBuffer using reader r. l is the initial capacity
// of the internal buffer. If r happens to be a ReadSeeker already, r is used directly
// without any additional copies of the data.
func NewSeekBuffer(r io.Reader, l int64) *SeekBuffer {
	if rs, ok := r.(ReadSeekerAt); ok {
		return &SeekBuffer{rs}
	}
	return &SeekBuffer{&seekBuffer{
		buf: make([]byte, 0, l),
		src: NewReadCounter(r),
	}}
}

// NewSeekBufferCloser creates a new SeekBuffer using ReadCloser r. l is the initial
// capacity of the internal buffer. The close method from r is forwarded to the returned
// ReadSeekerCloser.
func NewSeekBufferCloser(r io.ReadCloser, l int64) ReadSeekerCloser {
	return NewReadSeekerCloser(NewSeekBuffer(r, l), r.Close)
}

func (r *seekBuffer) ReadAt(b []byte, off int64) (n int, err error) {
	// cannot modify state - see io.ReaderAt
	if off < 0 {
		return 0, errors.New("swio.ReadAt: negative offset")
	}

	if off < int64(len(r.buf)) {
		n = copy(b, r.buf[off:])
		off += int64(n)
		b = b[n:]
	}

	// is the offset past what we have buffered?
	if off > int64(len(r.buf)) {
		buf := make([]byte, off-int64(len(r.buf)))
		// get src to the offset
		var read int
		read, err = io.ReadFull(r.src, buf)
		r.buf = append(r.buf, buf[:read]...)
		if err != nil {
			return
		}
	}

	secondRead, err := io.ReadFull(r.src, b)
	r.buf = append(r.buf, b[:secondRead]...)

	n += secondRead

	return
}

func (r *seekBuffer) Read(b []byte) (n int, err error) {
	unread := r.buf[r.position:]

	// Get as much as we can from unread
	n = copy(b, unread)

	// If we got all we need from unread, we're done
	if len(b) == n {
		r.position += int64(n)
		return
	}

	// Fill the rest of b with r.src
	srcn, err := r.src.Read(b[n:])

	// Add new read from src to r.buf
	r.buf = append(r.buf, b[n:]...)

	// Seek to new position in r.buf, so we don't read the latest from src again
	r.position += int64(srcn + n)

	return srcn + n, err
}

func (r *seekBuffer) Seek(offset int64, whence int) (int64, error) {
	var err error
	pos := r.position

	// Get new offset (relative to beginning)
	switch whence {
	case os.SEEK_SET:
		// offset stays as it is
	case os.SEEK_CUR:
		offset = offset + pos
	case os.SEEK_END:
		var remainder []byte
		remainder, err = ioutil.ReadAll(r.src)
		r.buf = append(r.buf, remainder...)
		offset = int64(len(r.buf)) + offset
	default:
		return pos, errors.New("seek: invalid whence")
	}

	originalOffset := offset

	// Have we read far enough into src?
	if diff := offset - r.src.BytesRead(); diff > 0 {
		var n int

		buf := make([]byte, diff)

		// No. Read diff bytes into src.
		n, err = r.src.Read(buf)

		// Copy onto r.buf
		r.buf = append(r.buf, buf[:n]...)
		r.position += int64(n)

		// Make offset correction if we didn't read buf full
		offset -= diff - int64(n)
	}

	// If we reached the EOF, but we got to where we're going, ignore EOF.
	if err == io.EOF && offset == originalOffset {
		err = nil
	}

	r.position = offset
	return offset, err
}
<|endoftext|>