<commit_before>// Package channel provides functions to alter the values of separate color
// channels in an image.
package channel

import (
	"github.com/hawx/img/utils"
	"github.com/hawx/img/altcolor"
	"image/color"
	"math"
)

// Red applies the Adjuster to the red channel of each pixel in the Image.
var Red = utils.MapAdjuster(RedC)

func RedC(adj utils.Adjuster) utils.Composable {
	return func(c color.Color) color.Color {
		r,g,b,a := utils.RatioRGBA(c)
		r = adj(r)
		if r > 1 { r = 1 } else if r < 0 { r = 0 }
		return color.NRGBA{uint8(r * 255), uint8(g * 255), uint8(b * 255), uint8(a * 255)}
	}
}

// Green applies the Adjuster to the green channel of each pixel in the Image.
var Green = utils.MapAdjuster(GreenC)

func GreenC(adj utils.Adjuster) utils.Composable {
	return func(c color.Color) color.Color {
		r,g,b,a := utils.RatioRGBA(c)
		g = adj(g)
		if g > 1 { g = 1 } else if g < 0 { g = 0 }
		return color.NRGBA{uint8(r * 255), uint8(g * 255), uint8(b * 255), uint8(a * 255)}
	}
}

// Blue applies the Adjuster to the blue channel of each pixel in the Image.
var Blue = utils.MapAdjuster(BlueC)

func BlueC(adj utils.Adjuster) utils.Composable {
	return func(c color.Color) color.Color {
		r,g,b,a := utils.RatioRGBA(c)
		b = adj(b)
		if b > 1 { b = 1 } else if b < 0 { b = 0 }
		return color.NRGBA{uint8(r * 255), uint8(g * 255), uint8(b * 255), uint8(a * 255)}
	}
}

// Alpha applies the Adjuster to the alpha channel of each pixel in the Image.
var Alpha = utils.MapAdjuster(AlphaC)

func AlphaC(adj utils.Adjuster) utils.Composable {
	return func(c color.Color) color.Color {
		r,g,b,a := utils.RatioRGBA(c)
		a = adj(a)
		if a > 1 { a = 1 } else if a < 0 { a = 0 }
		return color.NRGBA{uint8(r * 255), uint8(g * 255), uint8(b * 255), uint8(a * 255)}
	}
}

// Hue shifts the hue of the Image using the function given.
var Hue = utils.MapAdjuster(HueC)

func HueC(adj utils.Adjuster) utils.Composable {
	return func(c color.Color) color.Color {
		h := altcolor.HSLAModel.Convert(c).(altcolor.HSLA)
		h.H = math.Mod(adj(h.H), 360)
		return h
	}
}

// Saturation adjusts the saturation of the Image using the function given.
var Saturation = utils.MapAdjuster(SaturationC)

func SaturationC(adj utils.Adjuster) utils.Composable {
	return func(c color.Color) color.Color {
		h := altcolor.HSLAModel.Convert(c).(altcolor.HSLA)
		h.S = adj(h.S)
		if h.S > 1 { h.S = 1 }
		if h.S < 0 { h.S = 0 }
		return h
	}
}

// Lightness adjusts the lightness of the Image using the function given.
var Lightness = utils.MapAdjuster(LightnessC)

func LightnessC(adj utils.Adjuster) utils.Composable {
	return func(c color.Color) color.Color {
		h := altcolor.HSLAModel.Convert(c).(altcolor.HSLA)
		h.L = adj(h.L)
		if h.L > 1 { h.L = 1 }
		if h.L < 0 { h.L = 0 }
		return h
	}
}

// Brightness adjusts the brightness of the Image using the function given.
var Brightness = utils.MapAdjuster(BrightnessC)

func BrightnessC(adj utils.Adjuster) utils.Composable {
	return func(c color.Color) color.Color {
		h := altcolor.HSIAModel.Convert(c).(altcolor.HSIA)
		h.I = adj(h.I)
		if h.I > 1 { h.I = 1 }
		if h.I < 0 { h.I = 0 }
		return h
	}
}
<commit_msg>Say Adjuster not function in channel docs<commit_after>// Package channel provides functions to alter the values of separate color
// channels in an image.
package channel

import (
	"github.com/hawx/img/utils"
	"github.com/hawx/img/altcolor"
	"image/color"
	"math"
)

// Red applies the Adjuster to the red channel of each pixel in the Image.
var Red = utils.MapAdjuster(RedC)

func RedC(adj utils.Adjuster) utils.Composable {
	return func(c color.Color) color.Color {
		r,g,b,a := utils.RatioRGBA(c)
		r = adj(r)
		if r > 1 { r = 1 } else if r < 0 { r = 0 }
		return color.NRGBA{uint8(r * 255), uint8(g * 255), uint8(b * 255), uint8(a * 255)}
	}
}

// Green applies the Adjuster to the green channel of each pixel in the Image.
var Green = utils.MapAdjuster(GreenC)

func GreenC(adj utils.Adjuster) utils.Composable {
	return func(c color.Color) color.Color {
		r,g,b,a := utils.RatioRGBA(c)
		g = adj(g)
		if g > 1 { g = 1 } else if g < 0 { g = 0 }
		return color.NRGBA{uint8(r * 255), uint8(g * 255), uint8(b * 255), uint8(a * 255)}
	}
}

// Blue applies the Adjuster to the blue channel of each pixel in the Image.
var Blue = utils.MapAdjuster(BlueC)

func BlueC(adj utils.Adjuster) utils.Composable {
	return func(c color.Color) color.Color {
		r,g,b,a := utils.RatioRGBA(c)
		b = adj(b)
		if b > 1 { b = 1 } else if b < 0 { b = 0 }
		return color.NRGBA{uint8(r * 255), uint8(g * 255), uint8(b * 255), uint8(a * 255)}
	}
}

// Alpha applies the Adjuster to the alpha channel of each pixel in the Image.
var Alpha = utils.MapAdjuster(AlphaC)

func AlphaC(adj utils.Adjuster) utils.Composable {
	return func(c color.Color) color.Color {
		r,g,b,a := utils.RatioRGBA(c)
		a = adj(a)
		if a > 1 { a = 1 } else if a < 0 { a = 0 }
		return color.NRGBA{uint8(r * 255), uint8(g * 255), uint8(b * 255), uint8(a * 255)}
	}
}

// Hue shifts the hue of the Image using the Adjuster given.
var Hue = utils.MapAdjuster(HueC)

func HueC(adj utils.Adjuster) utils.Composable {
	return func(c color.Color) color.Color {
		h := altcolor.HSLAModel.Convert(c).(altcolor.HSLA)
		h.H = math.Mod(adj(h.H), 360)
		return h
	}
}

// Saturation adjusts the saturation of the Image using the Adjuster given.
var Saturation = utils.MapAdjuster(SaturationC)

func SaturationC(adj utils.Adjuster) utils.Composable {
	return func(c color.Color) color.Color {
		h := altcolor.HSLAModel.Convert(c).(altcolor.HSLA)
		h.S = adj(h.S)
		if h.S > 1 { h.S = 1 }
		if h.S < 0 { h.S = 0 }
		return h
	}
}

// Lightness adjusts the lightness of the Image using the Adjuster given.
var Lightness = utils.MapAdjuster(LightnessC)

func LightnessC(adj utils.Adjuster) utils.Composable {
	return func(c color.Color) color.Color {
		h := altcolor.HSLAModel.Convert(c).(altcolor.HSLA)
		h.L = adj(h.L)
		if h.L > 1 { h.L = 1 }
		if h.L < 0 { h.L = 0 }
		return h
	}
}

// Brightness adjusts the brightness of the Image using the Adjuster given.
var Brightness = utils.MapAdjuster(BrightnessC)

func BrightnessC(adj utils.Adjuster) utils.Composable {
	return func(c color.Color) color.Color {
		h := altcolor.HSIAModel.Convert(c).(altcolor.HSIA)
		h.I = adj(h.I)
		if h.I > 1 { h.I = 1 }
		if h.I < 0 { h.I = 0 }
		return h
	}
}
<|endoftext|>


<commit_before>// Package ranger implements an io.ReaderAt and io.ReadSeeker-compliant
// implementation of a caching HTTP range request client.
package ranger

import (
	"errors"
	"io"
	"sync"
)

// DefaultBlockSize is the default size for the blocks that are downloaded from the server and cached.
const DefaultBlockSize int = 128 * 1024

// Reader is an io.ReaderAt and io.ReadSeeker backed by a partial block store.
type Reader struct {
	// the range fetcher with which to download blocks
	Fetcher RangeFetcher

	// size of the blocks fetched from the source and cached; lower values translate to lower memory usage, but typically require more requests
	BlockSize int

	blocks      map[int][]byte
	mutex       sync.RWMutex
	initialized bool

	off int64
}

// ReadAt reads len(p) bytes from the ranged-over source.
// It returns the number of bytes read and the error, if any.
// ReadAt always returns a non-nil error when n < len(b). At end of file, that error is io.EOF.
func (r *Reader) ReadAt(p []byte, off int64) (int, error) {
	if !r.initialized {
		err := r.init()
		if err != nil {
			return 0, err
		}
	}

	l := len(p)

	if off < 0 {
		return 0, errors.New("read before beginning of file")
	}

	if off+int64(l) > r.Length() {
		return 0, errors.New("read beyond end of file")
	}

	startBlock, nblocks := blockRange(off, l, r.BlockSize)
	ranges := make([]BlockByteRange, nblocks)
	nreq := 0
	r.mutex.RLock()
	for i := 0; i < nblocks; i++ {
		bn := startBlock + i
		if _, ok := r.blocks[bn]; ok {
			continue
		}
		ranges[nreq] = BlockByteRange{
			bn,
			int64(bn * r.BlockSize),
			int64(((bn + 1) * r.BlockSize) - 1),
		}
		if ranges[nreq].End > r.Length() {
			ranges[nreq].End = r.Length()
		}

		nreq++
	}
	r.mutex.RUnlock()
	ranges = ranges[:nreq]

	// Lock here so that we don't end up dispatching
	// multiple requests for the same blocks.
	r.mutex.Lock()
	blox, err := r.Fetcher.FetchBlocks(ranges)
	if err != nil {
		return 0, err
	}
	for _, v := range blox {
		r.blocks[v.Number] = v.Data
	}
	r.mutex.Unlock()

	return r.copyRangeToBuffer(p, off)
}

func (r *Reader) copyRangeToBuffer(p []byte, off int64) (int, error) {
	remaining := len(p)
	block := int(off / int64(r.BlockSize))
	startOffset := off % int64(r.BlockSize)
	ncopied := 0

	r.mutex.RLock()
	defer r.mutex.RUnlock()

	for remaining > 0 {
		copylen := r.BlockSize
		if copylen > remaining {
			copylen = remaining
		}

		// if we need to copy more bytes than exist in this block
		if startOffset+int64(copylen) > int64(r.BlockSize) {
			copylen = int(int64(r.BlockSize) - startOffset)
		}

		if _, ok := r.blocks[block]; !ok {
			return 0, errors.New("lies: we were told we had blocks to copy")
		}
		copy(p[ncopied:ncopied+copylen], r.blocks[block][startOffset:])

		remaining -= copylen
		ncopied += copylen

		block++
		startOffset = 0
	}

	var err error
	if off+int64(len(p)) == r.Length() {
		err = io.EOF
	}

	return ncopied, err
}

// Length returns the length of the ranged-over source.
func (r *Reader) Length() int64 {
	if !r.initialized {
		r.init()
	}
	return r.Fetcher.Length()
}

// Read reads len(p) bytes from ranged-over source.
// It returns the number of bytes read and the error, if any.
// EOF is signaled by a zero count with err set to io.EOF.
func (r *Reader) Read(p []byte) (int, error) {
	if r.off == r.Length() {
		return 0, io.EOF
	}

	nread, err := r.ReadAt(p, r.off)
	r.off += int64(nread)
	return nread, err
}

// Seek sets the offset for the next Read to offset, interpreted
// according to whence: 0 means relative to the origin of the file, 1 means relative
// to the current offset, and 2 means relative to the end. It returns the new offset
// and an error, if any.
func (r *Reader) Seek(off int64, whence int) (int64, error) {
	switch whence {
	case 0:
		if off > r.Length() {
			return 0, errors.New("seek beyond end of file")
		}
		r.off = off
	case 1:
		off = r.off + off
		if off > r.Length() {
			return 0, errors.New("seek beyond end of file")
		}
		r.off = off
	case 2:
		off = r.Length() + off
		if off < 0 {
			return 0, errors.New("seek beyond beginning of file")
		}
		r.off = off
	}
	return r.off, nil
}

func (r *Reader) init() error {
	r.mutex.Lock()
	defer r.mutex.Unlock()

	r.initialized = true
	r.blocks = make(map[int][]byte)
	if r.BlockSize == 0 {
		r.BlockSize = DefaultBlockSize
	}

	err := r.Fetcher.Initialize(r.BlockSize)
	if err != nil {
		return err
	}
	return nil
}

// NewReader returns a newly-initialized Reader,
// which also initializes its provided RangeFetcher.
// It returns the new reader and an error, if any.
func NewReader(fetcher RangeFetcher) (*Reader, error) {
	r := &Reader{
		Fetcher: fetcher,
	}
	err := r.init()
	if err != nil {
		return nil, err
	}
	return r, nil
}
<commit_msg>Rework Reader.init and introduce an error return to Length<commit_after>// Package ranger implements an io.ReaderAt and io.ReadSeeker-compliant
// implementation of a caching HTTP range request client.
package ranger

import (
	"errors"
	"io"
	"sync"
)

// DefaultBlockSize is the default size for the blocks that are downloaded from the server and cached.
const DefaultBlockSize int = 128 * 1024

// Reader is an io.ReaderAt and io.ReadSeeker backed by a partial block store.
type Reader struct {
	// the range fetcher with which to download blocks
	Fetcher RangeFetcher

	// size of the blocks fetched from the source and cached; lower values translate to lower memory usage, but typically require more requests
	BlockSize int

	blocks      map[int][]byte
	mutex       sync.RWMutex
	initialized bool

	len int64
	off int64
}

// ReadAt reads len(p) bytes from the ranged-over source.
// It returns the number of bytes read and the error, if any.
// ReadAt always returns a non-nil error when n < len(b). At end of file, that error is io.EOF.
func (r *Reader) ReadAt(p []byte, off int64) (int, error) {
	err := r.init()
	if err != nil {
		return 0, err
	}

	l := len(p)

	if off < 0 {
		return 0, errors.New("read before beginning of file")
	}

	r.mutex.RLock()

	if off+int64(l) > r.len {
		r.mutex.RUnlock()
		return 0, errors.New("read beyond end of file")
	}

	startBlock, nblocks := blockRange(off, l, r.BlockSize)
	ranges := make([]BlockByteRange, nblocks)
	nreq := 0
	for i := 0; i < nblocks; i++ {
		bn := startBlock + i
		if _, ok := r.blocks[bn]; ok {
			continue
		}
		ranges[nreq] = BlockByteRange{
			bn,
			int64(bn * r.BlockSize),
			int64(((bn + 1) * r.BlockSize) - 1),
		}
		if ranges[nreq].End > r.len {
			ranges[nreq].End = r.len
		}

		nreq++
	}

	ranges = ranges[:nreq]
	r.mutex.RUnlock()

	// Lock here so that we don't end up dispatching
	// multiple requests for the same blocks.
	r.mutex.Lock()
	blox, err := r.Fetcher.FetchBlocks(ranges)
	if err != nil {
		return 0, err
	}
	for _, v := range blox {
		r.blocks[v.Number] = v.Data
	}
	r.mutex.Unlock()

	return r.copyRangeToBuffer(p, off)
}

// invariant: after init()
func (r *Reader) copyRangeToBuffer(p []byte, off int64) (int, error) {
	remaining := len(p)
	block := int(off / int64(r.BlockSize))
	startOffset := off % int64(r.BlockSize)
	ncopied := 0

	r.mutex.RLock()
	defer r.mutex.RUnlock()

	for remaining > 0 {
		copylen := r.BlockSize
		if copylen > remaining {
			copylen = remaining
		}

		// if we need to copy more bytes than exist in this block
		if startOffset+int64(copylen) > int64(r.BlockSize) {
			copylen = int(int64(r.BlockSize) - startOffset)
		}

		if _, ok := r.blocks[block]; !ok {
			return 0, errors.New("lies: we were told we had blocks to copy")
		}
		copy(p[ncopied:ncopied+copylen], r.blocks[block][startOffset:])

		remaining -= copylen
		ncopied += copylen

		block++
		startOffset = 0
	}

	var err error
	if off+int64(len(p)) == r.len {
		err = io.EOF
	}

	return ncopied, err
}

// Length returns the length of the ranged-over source.
func (r *Reader) Length() (int64, error) {
	err := r.init()
	if err != nil {
		return 0, err
	}
	return r.len, nil
}

// Read reads len(p) bytes from ranged-over source.
// It returns the number of bytes read and the error, if any.
// EOF is signaled by a zero count with err set to io.EOF.
func (r *Reader) Read(p []byte) (int, error) {
	err := r.init()
	if err != nil {
		return 0, err
	}

	if r.off == r.len {
		return 0, io.EOF
	}

	nread, err := r.ReadAt(p, r.off)
	r.off += int64(nread)
	return nread, err
}

// Seek sets the offset for the next Read to offset, interpreted
// according to whence: 0 means relative to the origin of the file, 1 means relative
// to the current offset, and 2 means relative to the end. It returns the new offset
// and an error, if any.
func (r *Reader) Seek(off int64, whence int) (int64, error) {
	err := r.init()
	if err != nil {
		return 0, err
	}

	r.mutex.Lock()
	defer r.mutex.Unlock()

	switch whence {
	case 0:
		if off > r.len {
			return 0, errors.New("seek beyond end of file")
		}
		r.off = off
	case 1:
		off = r.off + off
		if off > r.len {
			return 0, errors.New("seek beyond end of file")
		}
		r.off = off
	case 2:
		off = r.len + off
		if off < 0 {
			return 0, errors.New("seek beyond beginning of file")
		}
		r.off = off
	}
	return r.off, nil
}

func (r *Reader) init() error {
	r.mutex.RLock()
	if !r.initialized {
		r.mutex.RUnlock()
		r.mutex.Lock()
		defer r.mutex.Unlock()

		r.blocks = make(map[int][]byte)
		if r.BlockSize == 0 {
			r.BlockSize = DefaultBlockSize
		}

		err := r.Fetcher.Initialize(r.BlockSize)
		if err != nil {
			return err
		}

		r.len = r.Fetcher.Length()

		r.initialized = true
	} else {
		r.mutex.RUnlock()
	}
	return nil
}

// NewReader returns a newly-initialized Reader,
// which also initializes its provided RangeFetcher.
// It returns the new reader and an error, if any.
func NewReader(fetcher RangeFetcher) (*Reader, error) {
	r := &Reader{
		Fetcher: fetcher,
	}
	err := r.init()
	if err != nil {
		return nil, err
	}
	return r, nil
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"fmt"
	"time"
	"github.com/urfave/cli"
	"github.com/ebfe/go.pcsclite/scard"
)

type Reader struct {
	ctx *scard.Context
	c *cli.Context
	name string
	card *scard.Card
}

func NewReader(c *cli.Context) *Reader {
	ctx, err := scard.EstablishContext()
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %s\n", err)
		return nil
	}

	readers, err := ctx.ListReaders()
	if err != nil || len(readers) == 0 {
		fmt.Fprintf(os.Stderr, "エラー: リーダーが見つかりません。\n")
		return nil
	}
	if len(readers) >= 2 {
		fmt.Fprintf(os.Stderr,
			"警告: 複数のリーダーが見つかりました。最初のものを使います。\n")
	}

	reader := new(Reader)
	reader.ctx = ctx
	reader.c = c
	reader.name = readers[0]
	reader.card = nil
	return reader
}

func (self *Reader) Finalize() {
	self.ctx.Release()
}

func (self *Reader) CheckCard() {
	self.WaitForCard()
	aid := "D3 92 f0 00 26 01 00 00 00 01"
	apdu := "00 A4 04 0C" + " 0A " + aid
	sw1, sw2, _ := self.Tx(apdu)
	if sw1 == 0x90 && sw2 == 0x00 {
		return
	}

	fmt.Fprintf(os.Stderr, "これは個人番号カードではありません。\n")
	os.Exit(1)
}

func (self *Reader) GetCard() *scard.Card {
	card, _ := self.ctx.Connect(
		self.name, scard.SHARE_EXCLUSIVE, scard.PROTOCOL_ANY)
	self.card = card
	return card
}

func (self *Reader) WaitForCard() *scard.Card {
	rs := make([]scard.ReaderState, 1)
	rs[0].Reader = self.name
	rs[0].CurrentState = scard.STATE_UNAWARE
	for i := 0; i < 3; i++ {
		err := self.ctx.GetStatusChange(rs, scard.INFINITE)
		if err != nil {
			fmt.Fprintf(os.Stderr, "エラー: %s\n", err)
			return nil
		}
		if rs[0].EventState&scard.STATE_PRESENT != 0 {
			card, _ := self.ctx.Connect(
				self.name, scard.SHARE_EXCLUSIVE, scard.PROTOCOL_ANY)
			self.card = card
			return card
		}
		fmt.Fprintf(os.Stderr, "wait for card...\n")
		time.Sleep(1 * time.Second)
	}
	fmt.Fprintf(os.Stderr, "カードが見つかりません。\n")
	os.Exit(1)
	return nil
}

func (self *Reader) SelectAP(aid string) (uint8, uint8) {
	return self.SelectDF(aid)
}

func (self *Reader) SelectDF(id string) (uint8, uint8) {
	bid := ToBytes(id)
	apdu := "00 A4 04 0C" + fmt.Sprintf(" %02X % X", len(bid), bid)
	sw1, sw2, _ := self.Tx(apdu)
	return sw1, sw2
}

func (self *Reader) SelectEF(id string) (uint8, uint8) {
	bid := ToBytes(id)
	apdu := "00 A4 02 0C" + fmt.Sprintf(" %02X % X", len(bid), bid)
	sw1, sw2, _ := self.Tx(apdu)
	return sw1, sw2
}

func (self *Reader) Tx(apdu string) (uint8, uint8, []byte) {
	card := self.card
	if self.c.Bool("verbose") {
		fmt.Printf(">> %v\n", apdu)
	}
	cmd := ToBytes(apdu)
	res, err := card.Transmit(cmd)
	if err != nil {
		fmt.Printf("err: %s\n", err)
		return 0, 0, nil
	}

	if self.c.Bool("verbose") {
		for i := 0; i < len(res); i++ {
			if i % 0x10 == 0 {
				fmt.Print("<<")
			}
			fmt.Printf(" %02X", res[i])
			if i % 0x10 == 0x0f {
				fmt.Println()
			}
		}
		fmt.Println()
	}

	l := len(res)
	if l == 2 {
		return res[0], res[1], nil
	}else if l > 2 {
		return res[l-2], res[l-1], res[:l-2]
	}
	return 0, 0, nil
}

func (self *Reader) ReadBinary(size uint16) []byte {
	var l uint8
	var apdu string
	var pos uint16
	pos = 0
	var res []byte

	for pos < size {
		if size - pos > 0xFF {
			l = 0
		}else{
			l = uint8(size - pos)
		}
		apdu = fmt.Sprintf("00 B0 %02X %02X %02X",
			pos >> 8 & 0xFF, pos & 0xFF, l)
		sw1, sw2, data := self.Tx(apdu)
		if sw1 != 0x90 || sw2 != 0x00 {
			return nil
		}
		res = append(res, data...)
		pos += uint16(len(data))
	}
	return res
}
<commit_msg>change in and out symbol<commit_after>package main

import (
	"os"
	"fmt"
	"time"
	"github.com/urfave/cli"
	"github.com/ebfe/go.pcsclite/scard"
)

type Reader struct {
	ctx *scard.Context
	c *cli.Context
	name string
	card *scard.Card
}

func NewReader(c *cli.Context) *Reader {
	ctx, err := scard.EstablishContext()
	if err != nil {
		fmt.Fprintf(os.Stderr, "error: %s\n", err)
		return nil
	}

	readers, err := ctx.ListReaders()
	if err != nil || len(readers) == 0 {
		fmt.Fprintf(os.Stderr, "エラー: リーダーが見つかりません。\n")
		return nil
	}
	if len(readers) >= 2 {
		fmt.Fprintf(os.Stderr,
			"警告: 複数のリーダーが見つかりました。最初のものを使います。\n")
	}

	reader := new(Reader)
	reader.ctx = ctx
	reader.c = c
	reader.name = readers[0]
	reader.card = nil
	return reader
}

func (self *Reader) Finalize() {
	self.ctx.Release()
}

func (self *Reader) CheckCard() {
	self.WaitForCard()
	aid := "D3 92 f0 00 26 01 00 00 00 01"
	apdu := "00 A4 04 0C" + " 0A " + aid
	sw1, sw2, _ := self.Tx(apdu)
	if sw1 == 0x90 && sw2 == 0x00 {
		return
	}

	fmt.Fprintf(os.Stderr, "これは個人番号カードではありません。\n")
	os.Exit(1)
}

func (self *Reader) GetCard() *scard.Card {
	card, _ := self.ctx.Connect(
		self.name, scard.SHARE_EXCLUSIVE, scard.PROTOCOL_ANY)
	self.card = card
	return card
}

func (self *Reader) WaitForCard() *scard.Card {
	rs := make([]scard.ReaderState, 1)
	rs[0].Reader = self.name
	rs[0].CurrentState = scard.STATE_UNAWARE
	for i := 0; i < 3; i++ {
		err := self.ctx.GetStatusChange(rs, scard.INFINITE)
		if err != nil {
			fmt.Fprintf(os.Stderr, "エラー: %s\n", err)
			return nil
		}
		if rs[0].EventState&scard.STATE_PRESENT != 0 {
			card, _ := self.ctx.Connect(
				self.name, scard.SHARE_EXCLUSIVE, scard.PROTOCOL_ANY)
			self.card = card
			return card
		}
		fmt.Fprintf(os.Stderr, "wait for card...\n")
		time.Sleep(1 * time.Second)
	}
	fmt.Fprintf(os.Stderr, "カードが見つかりません。\n")
	os.Exit(1)
	return nil
}

func (self *Reader) SelectAP(aid string) (uint8, uint8) {
	return self.SelectDF(aid)
}

func (self *Reader) SelectDF(id string) (uint8, uint8) {
	bid := ToBytes(id)
	apdu := "00 A4 04 0C" + fmt.Sprintf(" %02X % X", len(bid), bid)
	sw1, sw2, _ := self.Tx(apdu)
	return sw1, sw2
}

func (self *Reader) SelectEF(id string) (uint8, uint8) {
	bid := ToBytes(id)
	apdu := "00 A4 02 0C" + fmt.Sprintf(" %02X % X", len(bid), bid)
	sw1, sw2, _ := self.Tx(apdu)
	return sw1, sw2
}

func (self *Reader) Tx(apdu string) (uint8, uint8, []byte) {
	card := self.card
	if self.c.Bool("verbose") {
		fmt.Printf("< %v\n", apdu)
	}
	cmd := ToBytes(apdu)
	res, err := card.Transmit(cmd)
	if err != nil {
		fmt.Printf("err: %s\n", err)
		return 0, 0, nil
	}

	if self.c.Bool("verbose") {
		for i := 0; i < len(res); i++ {
			if i % 0x10 == 0 {
				fmt.Print(">")
			}
			fmt.Printf(" %02X", res[i])
			if i % 0x10 == 0x0f {
				fmt.Println()
			}
		}
		fmt.Println()
	}

	l := len(res)
	if l == 2 {
		return res[0], res[1], nil
	}else if l > 2 {
		return res[l-2], res[l-1], res[:l-2]
	}
	return 0, 0, nil
}

func (self *Reader) ReadBinary(size uint16) []byte {
	var l uint8
	var apdu string
	var pos uint16
	pos = 0
	var res []byte

	for pos < size {
		if size - pos > 0xFF {
			l = 0
		}else{
			l = uint8(size - pos)
		}
		apdu = fmt.Sprintf("00 B0 %02X %02X %02X",
			pos >> 8 & 0xFF, pos & 0xFF, l)
		sw1, sw2, data := self.Tx(apdu)
		if sw1 != 0x90 || sw2 != 0x00 {
			return nil
		}
		res = append(res, data...)
		pos += uint16(len(data))
	}
	return res
}
<|endoftext|>


<commit_before>// Code generated by "stringer -type ExprSourceType"; DO NOT EDIT.

package hclpack

import "strconv"

const (
	_ExprSourceType_name_0 = "ExprNative"
	_ExprSourceType_name_1 = "ExprTemplate"
)

func (i ExprSourceType) String() string {
	switch {
	case i == 78:
		return _ExprSourceType_name_0
	case i == 84:
		return _ExprSourceType_name_1
	default:
		return "ExprSourceType(" + strconv.FormatInt(int64(i), 10) + ")"
	}
}
<commit_msg>hclpack: Update ExprSourceType.String to include ExprLiteralJSON<commit_after>// Code generated by "stringer -type ExprSourceType"; DO NOT EDIT.

package hclpack

import "strconv"

const (
	_ExprSourceType_name_0 = "ExprLiteralJSON"
	_ExprSourceType_name_1 = "ExprNative"
	_ExprSourceType_name_2 = "ExprTemplate"
)

func (i ExprSourceType) String() string {
	switch {
	case i == 76:
		return _ExprSourceType_name_0
	case i == 78:
		return _ExprSourceType_name_1
	case i == 84:
		return _ExprSourceType_name_2
	default:
		return "ExprSourceType(" + strconv.FormatInt(int64(i), 10) + ")"
	}
}
<|endoftext|>


<commit_before>/**
 * Minecraft Forge
 * Copyright (c) 2016.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation version 2.1
 * of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package util

import (
	"archive/zip"
	"bufio"
	"fmt"
	"io"
	"os"
	"path/filepath"

	"github.com/fatih/color"
	"github.com/ulikunitz/xz/lzma"
	"os/exec"
)

func DecompLauncher() {
	DecompLzma(getMcDir()+"/launcher.jar.lzma", getMcDir()+"/launcher.jar")
}

func DecompJRE(version string) {
	var targetName string

	//TODO get from json
	if GetThisPlatform() == "darwin" {
		targetName = "jre-osx-64-" + version + ".lzma"
	} else if GetThisPlatform() == "windows" {
		if GetThisArch() == "amd64" {
			targetName = "jre-win-64-" + version + ".lzma"
		} else if GetThisArch() == "386" {
			targetName = "jre-win-32-" + version + ".lzma"
		}
	}
	DecompLzma(getRuntimeJREDir()+"/"+targetName, getRuntimeJREDir()+"/jre.zip")
	// println("test")

	//Cant figure out why this doesnt work so problem meet hammer
	if GetThisPlatform() != "darwin"{
		unzip(getRuntimeJREDir()+"/jre.zip", getRuntimeJREDir())
	} else {
		_, err := exec.Command("ditto", "-xk", targetName, getRuntimeJREDir()).CombinedOutput()
		if err != nil {
			color.Red("problem unziping " + targetName + "%", err)
		}
	}

}

func DecompLzma(archive, target string) {
	f, err := os.Open(archive)

	if err != nil {
		fmt.Println(err)
	}

	r, err := lzma.NewReader(bufio.NewReader(f))

	if err != nil {
		fmt.Println(err)
	}

	output, err := os.Create(target)

	if err != nil {
		color.Red("error %s", err)
	}

	cop, err := io.Copy(output, r)
	fmt.Println(cop, "creaded")
	os.Remove(archive)

}

//Taken & modified from https://gist.github.com/svett/424e6784facc0ba907ae#file-extract-go
func unzip(archive, target string) error {
	reader, err := zip.OpenReader(archive)

	if err != nil {
		return err
	}

	defer  reader.Close()

	if err := os.MkdirAll(target, 0777); err != nil {
		return err
	}

	for _, file := range reader.File {
		path := filepath.Join(target, file.Name)
		if file.FileInfo().IsDir() {
			os.MkdirAll(path, file.Mode())
			continue
		}

		fileReader, err := file.Open()
		if err != nil {
			return err
		}

		targetFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
		if err != nil {
			fileReader.Close()
			return err
		}

		if _, err := io.Copy(targetFile, fileReader); err != nil {
			fileReader.Close()
			targetFile.Close()
			return err
		}

		fileReader.Close()
		targetFile.Close()
	}

	return os.Remove(archive)
}
<commit_msg>Cherrypick '27960e52b7cd62b78e7f09a956d0fbf24d2d4dce'<commit_after>/**
 * Minecraft Forge
 * Copyright (c) 2016.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation version 2.1
 * of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */
package util

import (
	"archive/zip"
	"bufio"
	"fmt"
	"io"
	"os"
	"path/filepath"

	"github.com/fatih/color"
	"github.com/ulikunitz/xz/lzma"
	"os/exec"
)

func DecompLauncher() {
	DecompLzma(getMcDir()+"/launcher.jar.lzma", getMcDir()+"/launcher.jar")
}

func DecompJRE(version string) {
	var targetName string

	//TODO get from json
	if GetThisPlatform() == "darwin" {
		targetName = "jre-osx-64-" + version + ".lzma"
	} else if GetThisPlatform() == "windows" {
		if GetThisArch() == "amd64" {
			targetName = "jre-win-64-" + version + ".lzma"
		} else if GetThisArch() == "386" {
			targetName = "jre-win-32-" + version + ".lzma"
		}
	}
	DecompLzma(getRuntimeJREDir()+"/"+targetName, getRuntimeJREDir()+"/jre.zip")
	// println("test")

	//Cant figure out why this doesnt work so problem meet hammer
	if GetThisPlatform() != "darwin"{
		unzip(getRuntimeJREDir()+"/jre.zip", getRuntimeJREDir())
	} else {
		_, err := exec.Command("ditto", "-xk", targetName, getRuntimeJREDir()).CombinedOutput()
		if err != nil {
			color.Red("problem unziping " + targetName + "%s", err)
		}
	}

}

func DecompLzma(archive, target string) {
	f, err := os.Open(archive)

	if err != nil {
		fmt.Println(err)
	}

	r, err := lzma.NewReader(bufio.NewReader(f))

	if err != nil {
		fmt.Println(err)
	}

	output, err := os.Create(target)

	if err != nil {
		color.Red("error %s", err)
	}

	cop, err := io.Copy(output, r)
	fmt.Println(cop, "creaded")
	os.Remove(archive)

}

//Taken & modified from https://gist.github.com/svett/424e6784facc0ba907ae#file-extract-go
func unzip(archive, target string) error {
	reader, err := zip.OpenReader(archive)

	if err != nil {
		return err
	}

	defer  reader.Close()

	if err := os.MkdirAll(target, 0777); err != nil {
		return err
	}

	for _, file := range reader.File {
		path := filepath.Join(target, file.Name)
		if file.FileInfo().IsDir() {
			os.MkdirAll(path, file.Mode())
			continue
		}

		fileReader, err := file.Open()
		if err != nil {
			return err
		}

		targetFile, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode())
		if err != nil {
			fileReader.Close()
			return err
		}

		if _, err := io.Copy(targetFile, fileReader); err != nil {
			fileReader.Close()
			targetFile.Close()
			return err
		}

		fileReader.Close()
		targetFile.Close()
	}

	return os.Remove(archive)
}
<|endoftext|>


<commit_before>package containers

import (
	kapi "k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/resource"
	"fmt"
)

type OContainer struct {
	kapi.Container
}

func Container(name, image string) *OContainer {
	c := OContainer{}
	c.Name = name
	c.Image = image
	c.TerminationMessagePath = "/dev/termination-log"
	return &c
}

func (c *OContainer) Command(args ...string) *OContainer {
	c.Container.Command = args
	return c
}

func (c *OContainer) EnvVar(name, value string) *OContainer {
	c.Container.Env = append(c.Container.Env, kapi.EnvVar{Name: name, Value: value})
	return c
}

func (c *OContainer) EnvVars(envs []kapi.EnvVar) *OContainer {
	c.Container.Env = envs
	return c
}

// TODO we might want to add some handling around building Quantities too
func (c *OContainer) ResourceLimit(name kapi.ResourceName, q resource.Quantity) *OContainer {
	if c.Resources.Limits == nil {
		c.Resources.Limits = make(kapi.ResourceList, 1)
	}
	c.Resources.Limits[name] = q
	return c
}

func (c *OContainer) ResourceRequest(name kapi.ResourceName, q resource.Quantity) *OContainer {
	if c.Resources.Requests == nil {
		c.Resources.Requests = make(kapi.ResourceList, 1)
	}
	c.Resources.Requests[name] = q
	return c
}

func (c *OContainer) Ports(ports ...*OContainerPort) *OContainer {
	kports := make([]kapi.ContainerPort, len(ports))
	for idx, p := range ports {
		kports[idx] = p.ContainerPort
	}
	c.Container.Ports = kports
	return c
}

func (c *OContainer) SetLivenessProbe(probe kapi.Probe) *OContainer {
	c.LivenessProbe = &probe
	return c
}

func (c *OContainer) SetReadinessProbe(probe kapi.Probe) *OContainer {
	c.ReadinessProbe = &probe
	return c
}

func (c *OContainer) SetVolumeMount(name, mountpath string, ro bool) *OContainer {
	if c.VolumeMounts == nil {
		c.VolumeMounts = []kapi.VolumeMount{}
	}
	vm := kapi.VolumeMount{Name: name, MountPath: mountpath, ReadOnly: ro}
	c.VolumeMounts = append(c.VolumeMounts, vm)
	return c
}

type OContainerPort struct {
	kapi.ContainerPort
}

func ContainerPort(name string, port int) *OContainerPort {
	cp := OContainerPort{}
	cp.Name = name
	cp.ContainerPort.ContainerPort = port
	cp.ContainerPort.Protocol = kapi.ProtocolTCP
	return &cp
}

func (cp *OContainerPort) Protocol(proto kapi.Protocol) *OContainerPort {
	cp.ContainerPort.Protocol = proto
	return cp
}

func (cp *OContainerPort) SetName(name string) *OContainerPort {
	cp.Name = name
	return cp
}

func (cp *OContainerPort) HostPort(port int) *OContainerPort {
	cp.ContainerPort.HostPort = port
	return cp
}

func (cp *OContainerPort) HostIP(hostip string) *OContainerPort {
	cp.ContainerPort.HostIP = hostip
	return cp
}
<commit_msg>Unused import<commit_after>package containers

import (
	kapi "k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/resource"
)

type OContainer struct {
	kapi.Container
}

func Container(name, image string) *OContainer {
	c := OContainer{}
	c.Name = name
	c.Image = image
	c.TerminationMessagePath = "/dev/termination-log"
	return &c
}

func (c *OContainer) Command(args ...string) *OContainer {
	c.Container.Command = args
	return c
}

func (c *OContainer) EnvVar(name, value string) *OContainer {
	c.Container.Env = append(c.Container.Env, kapi.EnvVar{Name: name, Value: value})
	return c
}

func (c *OContainer) EnvVars(envs []kapi.EnvVar) *OContainer {
	c.Container.Env = envs
	return c
}

// TODO we might want to add some handling around building Quantities too
func (c *OContainer) ResourceLimit(name kapi.ResourceName, q resource.Quantity) *OContainer {
	if c.Resources.Limits == nil {
		c.Resources.Limits = make(kapi.ResourceList, 1)
	}
	c.Resources.Limits[name] = q
	return c
}

func (c *OContainer) ResourceRequest(name kapi.ResourceName, q resource.Quantity) *OContainer {
	if c.Resources.Requests == nil {
		c.Resources.Requests = make(kapi.ResourceList, 1)
	}
	c.Resources.Requests[name] = q
	return c
}

func (c *OContainer) Ports(ports ...*OContainerPort) *OContainer {
	kports := make([]kapi.ContainerPort, len(ports))
	for idx, p := range ports {
		kports[idx] = p.ContainerPort
	}
	c.Container.Ports = kports
	return c
}

func (c *OContainer) SetLivenessProbe(probe kapi.Probe) *OContainer {
	c.LivenessProbe = &probe
	return c
}

func (c *OContainer) SetReadinessProbe(probe kapi.Probe) *OContainer {
	c.ReadinessProbe = &probe
	return c
}

func (c *OContainer) SetVolumeMount(name, mountpath string, ro bool) *OContainer {
	if c.VolumeMounts == nil {
		c.VolumeMounts = []kapi.VolumeMount{}
	}
	vm := kapi.VolumeMount{Name: name, MountPath: mountpath, ReadOnly: ro}
	c.VolumeMounts = append(c.VolumeMounts, vm)
	return c
}

type OContainerPort struct {
	kapi.ContainerPort
}

func ContainerPort(name string, port int) *OContainerPort {
	cp := OContainerPort{}
	cp.Name = name
	cp.ContainerPort.ContainerPort = port
	cp.ContainerPort.Protocol = kapi.ProtocolTCP
	return &cp
}

func (cp *OContainerPort) Protocol(proto kapi.Protocol) *OContainerPort {
	cp.ContainerPort.Protocol = proto
	return cp
}

func (cp *OContainerPort) SetName(name string) *OContainerPort {
	cp.Name = name
	return cp
}

func (cp *OContainerPort) HostPort(port int) *OContainerPort {
	cp.ContainerPort.HostPort = port
	return cp
}

func (cp *OContainerPort) HostIP(hostip string) *OContainerPort {
	cp.ContainerPort.HostIP = hostip
	return cp
}
<|endoftext|>


<commit_before>package util

import "testing"

var findContextTests = []struct {
	text          string
	pos           int
	lineno, colno int
	line          string
}{
	{"a\nb", 2, 1, 0, "b"},
}

func TestFindContext(t *testing.T) {
	for _, tt := range findContextTests {
		lineno, colno, line := FindContext(tt.text, tt.pos)
		if lineno != tt.lineno || colno != tt.colno || line != tt.line {
			t.Errorf("FindContext(%v, %v) => (%v, %v, %v), want (%v, %v, %v)",
				lineno, colno, line, tt.lineno, tt.colno, tt.line)
		}
	}
}

var SubstringByRuneTests = []struct {
	s         string
	low, high int
	wantedStr string
	wantedErr error
}{
	{"Hello world", 1, 4, "ell", nil},
	{"你好世界", 0, 0, "", nil},
	{"你好世界", 1, 1, "", nil},
	{"你好世界", 1, 2, "好", nil},
	{"你好世界", 1, 4, "好世界", nil},
	{"你好世界", -1, -1, "", IndexOutOfRange},
	{"你好世界", 0, 5, "", IndexOutOfRange},
	{"你好世界", 5, 5, "", IndexOutOfRange},
}

func TestSubstringByRune(t *testing.T) {
	for _, tt := range SubstringByRuneTests {
		s, e := SubstringByRune(tt.s, tt.low, tt.high)
		if s != tt.wantedStr || e != tt.wantedErr {
			t.Errorf("SubstringByRune(%q, %v, %d) => (%q, %v), want (%q, %v)",
				tt.s, tt.low, tt.high, s, e, tt.wantedStr, tt.wantedErr)
		}
	}
}

var NthRuneTests = []struct {
	s          string
	n          int
	wantedRune rune
	wantedErr  error
}{
	{"你好世界", -1, 0, IndexOutOfRange},
	{"你好世界", 0, '你', nil},
	{"你好世界", 4, 0, IndexOutOfRange},
}

func TestNthRune(t *testing.T) {
	for _, tt := range NthRuneTests {
		r, e := NthRune(tt.s, tt.n)
		if r != tt.wantedRune || e != tt.wantedErr {
			t.Errorf("NthRune(%q, %v) => (%q, %v), want (%q, %v)",
				tt.s, tt.n, r, e, tt.wantedRune, tt.wantedErr)
		}
	}
}
<commit_msg>Fix a fmt call with missing arguments<commit_after>package util

import "testing"

var findContextTests = []struct {
	text          string
	pos           int
	lineno, colno int
	line          string
}{
	{"a\nb", 2, 1, 0, "b"},
}

func TestFindContext(t *testing.T) {
	for _, tt := range findContextTests {
		lineno, colno, line := FindContext(tt.text, tt.pos)
		if lineno != tt.lineno || colno != tt.colno || line != tt.line {
			t.Errorf("FindContext(%v, %v) => (%v, %v, %v), want (%v, %v, %v)",
				tt.text, tt.pos, lineno, colno, line, tt.lineno, tt.colno, tt.line)
		}
	}
}

var SubstringByRuneTests = []struct {
	s         string
	low, high int
	wantedStr string
	wantedErr error
}{
	{"Hello world", 1, 4, "ell", nil},
	{"你好世界", 0, 0, "", nil},
	{"你好世界", 1, 1, "", nil},
	{"你好世界", 1, 2, "好", nil},
	{"你好世界", 1, 4, "好世界", nil},
	{"你好世界", -1, -1, "", IndexOutOfRange},
	{"你好世界", 0, 5, "", IndexOutOfRange},
	{"你好世界", 5, 5, "", IndexOutOfRange},
}

func TestSubstringByRune(t *testing.T) {
	for _, tt := range SubstringByRuneTests {
		s, e := SubstringByRune(tt.s, tt.low, tt.high)
		if s != tt.wantedStr || e != tt.wantedErr {
			t.Errorf("SubstringByRune(%q, %v, %d) => (%q, %v), want (%q, %v)",
				tt.s, tt.low, tt.high, s, e, tt.wantedStr, tt.wantedErr)
		}
	}
}

var NthRuneTests = []struct {
	s          string
	n          int
	wantedRune rune
	wantedErr  error
}{
	{"你好世界", -1, 0, IndexOutOfRange},
	{"你好世界", 0, '你', nil},
	{"你好世界", 4, 0, IndexOutOfRange},
}

func TestNthRune(t *testing.T) {
	for _, tt := range NthRuneTests {
		r, e := NthRune(tt.s, tt.n)
		if r != tt.wantedRune || e != tt.wantedErr {
			t.Errorf("NthRune(%q, %v) => (%q, %v), want (%q, %v)",
				tt.s, tt.n, r, e, tt.wantedRune, tt.wantedErr)
		}
	}
}
<|endoftext|>


<commit_before>package gorma

// GormaDesign is the root definition for Gorma
var GormaDesign *StorageGroupDefinition

const (
	// StorageGroup is the constant string used as the index in the
	// GormaConstructs map
	StorageGroup = "storagegroup"
	// MySQL is the StorageType for MySQL databases
	MySQL RelationalStorageType = "mysql"
	// Postgres is the StorageType for Postgres
	Postgres RelationalStorageType = "postgres"
	// None is For tests
	None RelationalStorageType = ""
	// Boolean is a bool field type
	Boolean FieldType = "bool"
	// Integer is an integer field type
	Integer FieldType = "integer"
	// BigInteger is a large integer field type
	BigInteger FieldType = "biginteger"
	// AutoInteger is not implemented
	AutoInteger FieldType = "auto_integer"
	// AutoBigInteger is not implemented
	AutoBigInteger FieldType = "auto_biginteger"
	// Decimal is a float field type
	Decimal FieldType = "decimal"
	// BigDecimal is a large float field type
	BigDecimal FieldType = "bigdecimal"
	// String is a varchar field type
	String FieldType = "string"
	// Text is a large string field type
	Text FieldType = "text"
	// UUID is not implemented yet
	UUID FieldType = "uuid"
	// Timestamp is a date/time field in the database
	Timestamp FieldType = "timestamp"
	// NullableTimestamp is a timestamp that may not be
	// populated.  Fields with no value will be null in the database
	NullableTimestamp FieldType = "nulltimestamp"
	// NotFound is used internally
	NotFound FieldType = "notfound"
	// HasOne is used internally
	HasOne FieldType = "hasone"
	// HasOneKey is used internally
	HasOneKey FieldType = "hasonekey"
	// HasMany is used internally
	HasMany FieldType = "hasmany"
	// HasManyKey is used internally
	HasManyKey FieldType = "hasmanykey"
	// Many2Many is used internally
	Many2Many FieldType = "many2many"
	// Many2ManyKey is used internally
	Many2ManyKey FieldType = "many2manykey"
	// BelongsTo is used internally
	BelongsTo FieldType = "belongsto"
)
<commit_msg>Add SQLite3 support to gorma<commit_after>package gorma

// GormaDesign is the root definition for Gorma
var GormaDesign *StorageGroupDefinition

const (
	// StorageGroup is the constant string used as the index in the
	// GormaConstructs map
	StorageGroup = "storagegroup"
	// MySQL is the StorageType for MySQL databases
	MySQL RelationalStorageType = "mysql"
	// Postgres is the StorageType for Postgres
	Postgres RelationalStorageType = "postgres"
	// SQLite3 is the StorageType for SQLite3 databases
	SQLite3 RelationalStorageType = "sqlite3"
	// None is For tests
	None RelationalStorageType = ""
	// Boolean is a bool field type
	Boolean FieldType = "bool"
	// Integer is an integer field type
	Integer FieldType = "integer"
	// BigInteger is a large integer field type
	BigInteger FieldType = "biginteger"
	// AutoInteger is not implemented
	AutoInteger FieldType = "auto_integer"
	// AutoBigInteger is not implemented
	AutoBigInteger FieldType = "auto_biginteger"
	// Decimal is a float field type
	Decimal FieldType = "decimal"
	// BigDecimal is a large float field type
	BigDecimal FieldType = "bigdecimal"
	// String is a varchar field type
	String FieldType = "string"
	// Text is a large string field type
	Text FieldType = "text"
	// UUID is not implemented yet
	UUID FieldType = "uuid"
	// Timestamp is a date/time field in the database
	Timestamp FieldType = "timestamp"
	// NullableTimestamp is a timestamp that may not be
	// populated.  Fields with no value will be null in the database
	NullableTimestamp FieldType = "nulltimestamp"
	// NotFound is used internally
	NotFound FieldType = "notfound"
	// HasOne is used internally
	HasOne FieldType = "hasone"
	// HasOneKey is used internally
	HasOneKey FieldType = "hasonekey"
	// HasMany is used internally
	HasMany FieldType = "hasmany"
	// HasManyKey is used internally
	HasManyKey FieldType = "hasmanykey"
	// Many2Many is used internally
	Many2Many FieldType = "many2many"
	// Many2ManyKey is used internally
	Many2ManyKey FieldType = "many2manykey"
	// BelongsTo is used internally
	BelongsTo FieldType = "belongsto"
)
<|endoftext|>


<commit_before>package concurrent

import "sync/atomic"

// Result is a simple model of a concurrent task, having a
// simple payload and an error.
type Result struct {
	Msg string
	Err error
}

// ScatterGather forks the workTable into separate goroutines
// with callbacks onSuccess and onError. The results are gathered
// in slice. Neither onSuccess nor onError should panic, otherwise
// ScatterGather panics.
func ScatterGather(workTable map[string]func() (string, error), onSuccess func(string, string) Result, onError func(string, string, error) Result) []Result {
	amountOfWork := len(workTable)
	if amountOfWork == 0 {
		return []Result{}
	}
	scatterChannel := make(chan Result, amountOfWork)
	var ops uint64
	for key, work := range workTable {
		go func(k string, w func() (string, error)) {
			defer closeOnDone(&ops, uint64(amountOfWork), scatterChannel)
			msg, err := w()
			if err == nil {
				scatterChannel <- onSuccess(k, msg)
			} else {
				scatterChannel <- onError(k, msg, err)
			}
		}(key, work)
	}

	results := make([]Result, 0, amountOfWork)
	for res := range scatterChannel {
		results = append(results, res)
	}
	return results
}

func closeOnDone(ops *uint64, amountOfWork uint64, ch chan Result) {
	if atomic.AddUint64(ops, 1) == amountOfWork {
		close(ch)
	}
}
<commit_msg>define some internal types<commit_after>package concurrent

import "sync/atomic"

// Result is a simple model of a concurrent task, having a
// simple payload and an error.
type Result struct {
	Msg string
	Err error
}

type successHandler func(string, string) Result

type errorHandler func(string, string, error) Result

type workTable map[string]func() (string, error)

// ScatterGather forks the workTable into separate goroutines
// with callbacks onSuccess and onError. The results are gathered
// in slice. Neither onSuccess nor onError should panic, otherwise
// ScatterGather panics.
func ScatterGather(wt workTable, onSuccess successHandler, onError errorHandler) []Result {
	amountOfWork := len(wt)
	if amountOfWork == 0 {
		return []Result{}
	}
	scatterChannel := make(chan Result, amountOfWork)
	var ops uint64
	for key, work := range wt {
		go func(k string, w func() (string, error)) {
			defer closeOnDone(&ops, uint64(amountOfWork), scatterChannel)
			msg, err := w()
			if err == nil {
				scatterChannel <- onSuccess(k, msg)
			} else {
				scatterChannel <- onError(k, msg, err)
			}
		}(key, work)
	}

	results := make([]Result, 0, amountOfWork)
	for res := range scatterChannel {
		results = append(results, res)
	}
	return results
}

func closeOnDone(ops *uint64, amountOfWork uint64, ch chan Result) {
	if atomic.AddUint64(ops, 1) == amountOfWork {
		close(ch)
	}
}
<|endoftext|>


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

package main

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

var cmdClean = &Command{
	UsageLine: "clean [-i] [-r] [-n] [-x] [packages]",
	Short:     "remove object files",
	Long: `
Clean removes object files from package source directories.
The go command builds most objects in a temporary directory,
so go clean is mainly concerned with object files left by other
tools or by manual invocations of go build.

Specifically, clean removes the following files from each of the
source directories corresponding to the import paths:

	_obj/            old object directory, left from Makefiles
	_test/           old test directory, left from Makefiles
	_testmain.go     old gotest file, left from Makefiles
	test.out         old test log, left from Makefiles
	build.out        old test log, left from Makefiles
	*.[568ao]        object files, left from Makefiles

	DIR(.exe)        from go build
	DIR.test(.exe)   from go test -c
	MAINFILE(.exe)   from go build MAINFILE.go
	*.so             from SWIG

In the list, DIR represents the final path element of the
directory, and MAINFILE is the base name of any Go source
file in the directory that is not included when building
the package.

The -i flag causes clean to remove the corresponding installed
archive or binary (what 'go install' would create).

The -n flag causes clean to print the remove commands it would execute,
but not run them.

The -r flag causes clean to be applied recursively to all the
dependencies of the packages named by the import paths.

The -x flag causes clean to print remove commands as it executes them.

For more about specifying packages, see 'go help packages'.
	`,
}

var cleanI bool // clean -i flag
var cleanN bool // clean -n flag
var cleanR bool // clean -r flag
var cleanX bool // clean -x flag

func init() {
	// break init cycle
	cmdClean.Run = runClean

	cmdClean.Flag.BoolVar(&cleanI, "i", false, "")
	cmdClean.Flag.BoolVar(&cleanN, "n", false, "")
	cmdClean.Flag.BoolVar(&cleanR, "r", false, "")
	cmdClean.Flag.BoolVar(&cleanX, "x", false, "")
}

func runClean(cmd *Command, args []string) {
	for _, pkg := range packagesAndErrors(args) {
		clean(pkg)
	}
}

var cleaned = map[*Package]bool{}

// TODO: These are dregs left by Makefile-based builds.
// Eventually, can stop deleting these.
var cleanDir = map[string]bool{
	"_test": true,
	"_obj":  true,
}

var cleanFile = map[string]bool{
	"_testmain.go": true,
	"test.out":     true,
	"build.out":    true,
	"a.out":        true,
}

var cleanExt = map[string]bool{
	".5":  true,
	".6":  true,
	".8":  true,
	".a":  true,
	".o":  true,
	".so": true,
}

func clean(p *Package) {
	if cleaned[p] {
		return
	}
	if p.Dir == "" {
		errorf("can't load package: %v", p.Error)
		return
	}
	dirs, err := ioutil.ReadDir(p.Dir)
	if err != nil {
		errorf("go clean %s: %v", p.Dir, err)
		return
	}

	var b builder
	b.print = fmt.Print

	packageFile := map[string]bool{}
	if p.Name != "main" {
		// Record which files are not in package main.
		// The others are.
		keep := func(list []string) {
			for _, f := range list {
				packageFile[f] = true
			}
		}
		keep(p.GoFiles)
		keep(p.CgoFiles)
		keep(p.TestGoFiles)
		keep(p.XTestGoFiles)
	}

	_, elem := filepath.Split(p.Dir)
	allRemove := []string{
		elem,
		elem + ".exe",
		elem + ".test",
		elem + ".test.exe",
	}
	for _, dir := range dirs {
		name := dir.Name()
		if packageFile[name] {
			continue
		}
		if !dir.IsDir() && strings.HasSuffix(name, ".go") {
			base := name[:len(name)-len(".go")]
			allRemove = append(allRemove, base, base+".exe")
		}
	}
	if cleanN || cleanX {
		b.showcmd(p.Dir, "rm -f %s", strings.Join(allRemove, " "))
	}

	toRemove := map[string]bool{}
	for _, name := range allRemove {
		toRemove[name] = true
	}
	for _, dir := range dirs {
		name := dir.Name()
		if dir.IsDir() {
			// TODO: Remove once Makefiles are forgotten.
			if cleanDir[name] {
				if cleanN || cleanX {
					b.showcmd(p.Dir, "rm -r %s", name)
					if cleanN {
						continue
					}
				}
				if err := os.RemoveAll(filepath.Join(p.Dir, name)); err != nil {
					errorf("go clean: %v", err)
				}
			}
			continue
		}

		if cleanN {
			continue
		}

		if cleanFile[name] || cleanExt[filepath.Ext(name)] || toRemove[name] {
			removeFile(filepath.Join(p.Dir, name))
		}
	}

	if cleanI && p.target != "" {
		if cleanN || cleanX {
			b.showcmd("", "rm -f %s", p.target)
		}
		if !cleanN {
			removeFile(p.target)
		}
	}

	if cleanI && p.usesSwig() {
		for _, f := range stringList(p.SwigFiles, p.SwigCXXFiles) {
			dir := p.swigDir(&buildContext)
			soname := p.swigSoname(f)
			target := filepath.Join(dir, soname)
			if cleanN || cleanX {
				b.showcmd("", "rm -f %s", target)
			}
			if !cleanN {
				removeFile(target)
			}
		}
	}

	if cleanR {
		for _, p1 := range p.imports {
			clean(p1)
		}
	}
}

// removeFile tries to remove file f, if error other than file doesn't exist
// occurs, it will report the error.
func removeFile(f string) {
	if err := os.Remove(f); err != nil && !os.IsNotExist(err) {
		errorf("go clean: %v", err)
	}
}
<commit_msg>cmd/go: prevent packages from being cleaned more than once<commit_after>// Copyright 2012 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

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

var cmdClean = &Command{
	UsageLine: "clean [-i] [-r] [-n] [-x] [packages]",
	Short:     "remove object files",
	Long: `
Clean removes object files from package source directories.
The go command builds most objects in a temporary directory,
so go clean is mainly concerned with object files left by other
tools or by manual invocations of go build.

Specifically, clean removes the following files from each of the
source directories corresponding to the import paths:

	_obj/            old object directory, left from Makefiles
	_test/           old test directory, left from Makefiles
	_testmain.go     old gotest file, left from Makefiles
	test.out         old test log, left from Makefiles
	build.out        old test log, left from Makefiles
	*.[568ao]        object files, left from Makefiles

	DIR(.exe)        from go build
	DIR.test(.exe)   from go test -c
	MAINFILE(.exe)   from go build MAINFILE.go
	*.so             from SWIG

In the list, DIR represents the final path element of the
directory, and MAINFILE is the base name of any Go source
file in the directory that is not included when building
the package.

The -i flag causes clean to remove the corresponding installed
archive or binary (what 'go install' would create).

The -n flag causes clean to print the remove commands it would execute,
but not run them.

The -r flag causes clean to be applied recursively to all the
dependencies of the packages named by the import paths.

The -x flag causes clean to print remove commands as it executes them.

For more about specifying packages, see 'go help packages'.
	`,
}

var cleanI bool // clean -i flag
var cleanN bool // clean -n flag
var cleanR bool // clean -r flag
var cleanX bool // clean -x flag

func init() {
	// break init cycle
	cmdClean.Run = runClean

	cmdClean.Flag.BoolVar(&cleanI, "i", false, "")
	cmdClean.Flag.BoolVar(&cleanN, "n", false, "")
	cmdClean.Flag.BoolVar(&cleanR, "r", false, "")
	cmdClean.Flag.BoolVar(&cleanX, "x", false, "")
}

func runClean(cmd *Command, args []string) {
	for _, pkg := range packagesAndErrors(args) {
		clean(pkg)
	}
}

var cleaned = map[*Package]bool{}

// TODO: These are dregs left by Makefile-based builds.
// Eventually, can stop deleting these.
var cleanDir = map[string]bool{
	"_test": true,
	"_obj":  true,
}

var cleanFile = map[string]bool{
	"_testmain.go": true,
	"test.out":     true,
	"build.out":    true,
	"a.out":        true,
}

var cleanExt = map[string]bool{
	".5":  true,
	".6":  true,
	".8":  true,
	".a":  true,
	".o":  true,
	".so": true,
}

func clean(p *Package) {
	if cleaned[p] {
		return
	}
	cleaned[p] = true

	if p.Dir == "" {
		errorf("can't load package: %v", p.Error)
		return
	}
	dirs, err := ioutil.ReadDir(p.Dir)
	if err != nil {
		errorf("go clean %s: %v", p.Dir, err)
		return
	}

	var b builder
	b.print = fmt.Print

	packageFile := map[string]bool{}
	if p.Name != "main" {
		// Record which files are not in package main.
		// The others are.
		keep := func(list []string) {
			for _, f := range list {
				packageFile[f] = true
			}
		}
		keep(p.GoFiles)
		keep(p.CgoFiles)
		keep(p.TestGoFiles)
		keep(p.XTestGoFiles)
	}

	_, elem := filepath.Split(p.Dir)
	allRemove := []string{
		elem,
		elem + ".exe",
		elem + ".test",
		elem + ".test.exe",
	}
	for _, dir := range dirs {
		name := dir.Name()
		if packageFile[name] {
			continue
		}
		if !dir.IsDir() && strings.HasSuffix(name, ".go") {
			base := name[:len(name)-len(".go")]
			allRemove = append(allRemove, base, base+".exe")
		}
	}
	if cleanN || cleanX {
		b.showcmd(p.Dir, "rm -f %s", strings.Join(allRemove, " "))
	}

	toRemove := map[string]bool{}
	for _, name := range allRemove {
		toRemove[name] = true
	}
	for _, dir := range dirs {
		name := dir.Name()
		if dir.IsDir() {
			// TODO: Remove once Makefiles are forgotten.
			if cleanDir[name] {
				if cleanN || cleanX {
					b.showcmd(p.Dir, "rm -r %s", name)
					if cleanN {
						continue
					}
				}
				if err := os.RemoveAll(filepath.Join(p.Dir, name)); err != nil {
					errorf("go clean: %v", err)
				}
			}
			continue
		}

		if cleanN {
			continue
		}

		if cleanFile[name] || cleanExt[filepath.Ext(name)] || toRemove[name] {
			removeFile(filepath.Join(p.Dir, name))
		}
	}

	if cleanI && p.target != "" {
		if cleanN || cleanX {
			b.showcmd("", "rm -f %s", p.target)
		}
		if !cleanN {
			removeFile(p.target)
		}
	}

	if cleanI && p.usesSwig() {
		for _, f := range stringList(p.SwigFiles, p.SwigCXXFiles) {
			dir := p.swigDir(&buildContext)
			soname := p.swigSoname(f)
			target := filepath.Join(dir, soname)
			if cleanN || cleanX {
				b.showcmd("", "rm -f %s", target)
			}
			if !cleanN {
				removeFile(target)
			}
		}
	}

	if cleanR {
		for _, p1 := range p.imports {
			clean(p1)
		}
	}
}

// removeFile tries to remove file f, if error other than file doesn't exist
// occurs, it will report the error.
func removeFile(f string) {
	if err := os.Remove(f); err != nil && !os.IsNotExist(err) {
		errorf("go clean: %v", err)
	}
}
<|endoftext|>


<commit_before>package api

import (
	"code.google.com/p/go.net/websocket"
	"crypto/tls"
	"launchpad.net/juju-core/log"
	"launchpad.net/juju-core/state"
	"launchpad.net/tomb"
	"net"
	"net/http"
	"sync"
)

// srvState represents a single client's connection to the state.
type srvState struct {
	srv  *Server
	conn *websocket.Conn
}

type Server struct {
	tomb  tomb.Tomb
	wg    sync.WaitGroup
	state *state.State
	addr  net.Addr
}

// Serve serves the given state by accepting requests
// on the given listener, using the given certificate
// and key (in PEM format) for authentication.
func NewServer(s *state.State, addr string, cert, key []byte) (*Server, error) {
	lis, err := net.Listen("tcp", addr)
	if err != nil {
		return nil, err
	}
	tlsCert, err := tls.X509KeyPair(cert, key)
	if err != nil {
		return nil, err
	}
	srv := &Server{
		state: s,
		addr:  lis.Addr(),
	}
	lis = tls.NewListener(lis, &tls.Config{
		Certificates: []tls.Certificate{tlsCert},
	})
	go func() {
		defer srv.tomb.Done()
		srv.tomb.Kill(srv.run(lis))
	}()
	return srv, nil
}

// Stop stops the server and returns when all requests that
// it is running have completed.
func (srv *Server) Stop() error {
	srv.tomb.Kill(nil)
	return srv.tomb.Wait()
}

func (srv *Server) run(lis net.Listener) error {
	srv.wg.Add(1)
	go func() {
		<-srv.tomb.Dying()
		lis.Close()
		srv.wg.Done()
	}()
	handler := websocket.Handler(func(conn *websocket.Conn) {
		defer conn.Close()
		srv.wg.Add(1)
		defer srv.wg.Done()
		// If we've got to this stage and the tomb is still
		// alive, we know that any tomb.Kill must occur after we
		// have called wg.Add, so we avoid the possibility of a
		// handler goroutine running after Stop has returned.
		if srv.tomb.Err() != tomb.ErrStillAlive {
			return
		}
		st := &srvState{
			srv:  srv,
			conn: conn,
		}
		st.run()
	})
	// The error from http.Serve is not interesting.
	http.Serve(lis, handler)
	return nil
}

// Addr returns the address that the server is listening on.
func (srv *Server) Addr() string {
	return srv.addr.String()
}

type rpcRequest struct {
	Request string // placeholder only
}

type rpcResponse struct {
	Response string // placeholder only
	Error    string
}

func (st *srvState) run() {
	msgs := make(chan rpcRequest)
	go st.readRequests(msgs)
	for {
		var req rpcRequest
		var ok bool
		select {
		case req, ok := <-msgs:
			if !ok {
				return
			}
		case <-st.srv.tomb.Dying():
			return
		}
		var resp rpcResponse
		// placeholder for executing some arbitrary operation
		// on state.
		m, err := st.srv.state.Machine(req.Request)
		if err != nil {
			resp.Error = err.Error()
		} else {
			instId, err := m.InstanceId()
			if err != nil {
				resp.Error = err.Error()
			} else {
				resp.Response = string(instId)
			}
		}
		err = websocket.JSON.Send(st.conn, &resp)
		if err != nil {
			log.Printf("api: error sending reply: %v", err)
			return
		}
	}
}

func (st *srvState) readRequests(c chan<- rpcRequest) {
	var req rpcRequest
	for {
		req = rpcRequest{} // avoid any potential cross-message contamination.
		err := websocket.JSON.Receive(st.conn, &req)
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Printf("api: error receiving request: %v", err)
			break
		}
		c <- req
	}
	close(c)
}
<commit_msg>state/api: actually wait for WaitGroup<commit_after>package api

import (
	"code.google.com/p/go.net/websocket"
	"crypto/tls"
	"io"
	"launchpad.net/juju-core/log"
	"launchpad.net/juju-core/state"
	"launchpad.net/tomb"
	"net"
	"net/http"
	"sync"
)

// srvState represents a single client's connection to the state.
type srvState struct {
	srv  *Server
	conn *websocket.Conn
}

type Server struct {
	tomb  tomb.Tomb
	wg    sync.WaitGroup
	state *state.State
	addr  net.Addr
}

// Serve serves the given state by accepting requests
// on the given listener, using the given certificate
// and key (in PEM format) for authentication.
func NewServer(s *state.State, addr string, cert, key []byte) (*Server, error) {
	lis, err := net.Listen("tcp", addr)
	if err != nil {
		return nil, err
	}
	tlsCert, err := tls.X509KeyPair(cert, key)
	if err != nil {
		return nil, err
	}
	srv := &Server{
		state: s,
		addr:  lis.Addr(),
	}
	lis = tls.NewListener(lis, &tls.Config{
		Certificates: []tls.Certificate{tlsCert},
	})
	go func() {
		defer srv.tomb.Done()
		srv.run(lis)
	}()
	return srv, nil
}

// Stop stops the server and returns when all requests that
// it is running have completed.
func (srv *Server) Stop() error {
	srv.tomb.Kill(nil)
	return srv.tomb.Wait()
}

func (srv *Server) run(lis net.Listener) {
	defer srv.wg.Wait()
	srv.wg.Add(1)
	go func() {
		<-srv.tomb.Dying()
		lis.Close()
		srv.wg.Done()
	}()
	handler := websocket.Handler(func(conn *websocket.Conn) {
		defer conn.Close()
		srv.wg.Add(1)
		defer srv.wg.Done()
		// If we've got to this stage and the tomb is still
		// alive, we know that any tomb.Kill must occur after we
		// have called wg.Add, so we avoid the possibility of a
		// handler goroutine running after Stop has returned.
		if srv.tomb.Err() != tomb.ErrStillAlive {
			return
		}
		st := &srvState{
			srv:  srv,
			conn: conn,
		}
		st.run()
	})
	// The error from http.Serve is not interesting.
	http.Serve(lis, handler)
}

// Addr returns the address that the server is listening on.
func (srv *Server) Addr() string {
	return srv.addr.String()
}

type rpcRequest struct {
	Request string // placeholder only
}

type rpcResponse struct {
	Response string // placeholder only
	Error    string
}

func (st *srvState) run() {
	msgs := make(chan rpcRequest)
	go st.readRequests(msgs)
	for {
		var req rpcRequest
		var ok bool
		select {
		case req, ok = <-msgs:
			if !ok {
				return
			}
		case <-st.srv.tomb.Dying():
			return
		}
		var resp rpcResponse
		// placeholder for executing some arbitrary operation
		// on state.
		m, err := st.srv.state.Machine(req.Request)
		if err != nil {
			resp.Error = err.Error()
		} else {
			instId, err := m.InstanceId()
			if err != nil {
				resp.Error = err.Error()
			} else {
				resp.Response = string(instId)
			}
		}
		err = websocket.JSON.Send(st.conn, &resp)
		if err != nil {
			log.Printf("api: error sending reply: %v", err)
			return
		}
	}
}

func (st *srvState) readRequests(c chan<- rpcRequest) {
	var req rpcRequest
	for {
		req = rpcRequest{} // avoid any potential cross-message contamination.
		err := websocket.JSON.Receive(st.conn, &req)
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Printf("api: error receiving request: %v", err)
			break
		}
		c <- req
	}
	close(c)
}
<|endoftext|>


<commit_before>package main

import (
	"cf"
	"cf/api"
	"cf/app"
	"cf/commands"
	"cf/configuration"
	"cf/manifest"
	"cf/net"
	"cf/requirements"
	"cf/terminal"
	"fileutils"
	"fmt"
	"os"
)

func main() {
	fileutils.SetTmpPathPrefix("cf")

	if os.Getenv("CF_COLOR") == "" {
		os.Setenv("CF_COLOR", "true")
	}

	termUI := terminal.NewUI()
	configRepo := configuration.NewConfigurationDiskRepository()
	config := loadConfig(termUI, configRepo)
	manifestRepo := manifest.NewManifestDiskRepository()
	repoLocator := api.NewRepositoryLocator(config, configRepo, map[string]net.Gateway{
		"auth":             net.NewUAAGateway(),
		"cloud-controller": net.NewCloudControllerGateway(),
		"uaa":              net.NewUAAGateway(),
	})

	cmdFactory := commands.NewFactory(termUI, config, configRepo, manifestRepo, repoLocator)
	reqFactory := requirements.NewFactory(termUI, config, repoLocator)
	cmdRunner := commands.NewRunner(cmdFactory, reqFactory)

	app, err := app.NewApp(cmdRunner)
	if err != nil {
		return
	}
	app.Run(os.Args)
}

func loadConfig(termUI terminal.UI, configRepo configuration.ConfigurationRepository) (config *configuration.Configuration) {
	config, err := configRepo.Get()
	if err != nil {
		termUI.Failed(fmt.Sprintf(
			"Error loading config. Please reset target (%s) and log in (%s).",
			terminal.CommandColor(fmt.Sprintf("%s target", cf.Name())),
			terminal.CommandColor(fmt.Sprintf("%s login", cf.Name())),
		))
		configRepo.Delete()
		os.Exit(1)
		return
	}
	return
}
<commit_msg>Display helpful message when cf crashes<commit_after>package main

import (
	"cf"
	"cf/api"
	"cf/app"
	"cf/commands"
	"cf/configuration"
	"cf/manifest"
	"cf/net"
	"cf/requirements"
	"cf/terminal"
	"fileutils"
	"fmt"
	"os"
	"runtime/debug"
	"strings"
)

func main() {
	defer func() {
		maybeSomething := recover()

		if maybeSomething != nil {
			displayCrashDialog()
		}
	}()

	fileutils.SetTmpPathPrefix("cf")

	if os.Getenv("CF_COLOR") == "" {
		os.Setenv("CF_COLOR", "true")
	}

	termUI := terminal.NewUI()
	configRepo := configuration.NewConfigurationDiskRepository()
	config := loadConfig(termUI, configRepo)
	manifestRepo := manifest.NewManifestDiskRepository()
	repoLocator := api.NewRepositoryLocator(config, configRepo, map[string]net.Gateway{
		"auth":             net.NewUAAGateway(),
		"cloud-controller": net.NewCloudControllerGateway(),
		"uaa":              net.NewUAAGateway(),
	})

	cmdFactory := commands.NewFactory(termUI, config, configRepo, manifestRepo, repoLocator)
	reqFactory := requirements.NewFactory(termUI, config, repoLocator)
	cmdRunner := commands.NewRunner(cmdFactory, reqFactory)

	app, err := app.NewApp(cmdRunner)
	if err != nil {
		return
	}
	app.Run(os.Args)
}

func loadConfig(termUI terminal.UI, configRepo configuration.ConfigurationRepository) (config *configuration.Configuration) {
	config, err := configRepo.Get()
	if err != nil {
		termUI.Failed(fmt.Sprintf(
			"Error loading config. Please reset target (%s) and log in (%s).",
			terminal.CommandColor(fmt.Sprintf("%s target", cf.Name())),
			terminal.CommandColor(fmt.Sprintf("%s login", cf.Name())),
		))
		configRepo.Delete()
		os.Exit(1)
		return
	}
	return
}

func displayCrashDialog() {
	formattedString := `

       d8888 888       888 888       888        .d8888b.  888    888 888     888  .d8888b.  888    d8P   .d8888b.
      d88888 888   o   888 888   o   888       d88P  Y88b 888    888 888     888 d88P  Y88b 888   d8P   d88P  Y88b
     d88P888 888  d8b  888 888  d8b  888       Y88b.      888    888 888     888 888    888 888  d8P    Y88b.
    d88P 888 888 d888b 888 888 d888b 888        "Y888b.   8888888888 888     888 888        888d88K      "Y888b.
   d88P  888 888d88888b888 888d88888b888           "Y88b. 888    888 888     888 888        8888888b        "Y88b.
  d88P   888 88888P Y88888 88888P Y88888             "888 888    888 888     888 888    888 888  Y88b         "888
 d8888888888 8888P   Y8888 8888P   Y8888       Y88b  d88P 888    888 Y88b. .d88P Y88b  d88P 888   Y88b  Y88b  d88P d8b
d88P     888 888P     Y888 888P     Y888        "Y8888P"  888    888  "Y88888P"   "Y8888P"  888    Y88b  "Y8888P"  Y8P

Something completely unexpected happened. This is a bug in %s.
Please file this bug : https://github.com/cloudfoundry/cli/issues
Tell us that you ran this command:

	%s

and got this stack trace:

%s
	`

	stackTrace := "\t" + strings.Replace(string(debug.Stack()), "\n", "\n\t", -1)
	println(fmt.Sprintf(formattedString, cf.Name(), strings.Join(os.Args, " "), stackTrace))
	os.Exit(1)
}
<|endoftext|>


<commit_before>package agi

import (
	"bufio"
	"fmt"
	"io"
	"net"
	"os"
	"regexp"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/pkg/errors"
)

// State describes the Asterisk channel state.  There are mapped
// directly to the Asterisk enumerations.
type State int

const (
	// StateDown indicates the channel is down and available
	StateDown State = iota

	// StateReserved indicates the channel is down but reserved
	StateReserved

	// StateOffhook indicates that the channel is offhook
	StateOffhook

	// StateDialing indicates that digits have been dialed
	StateDialing

	// StateRing indicates the channel is ringing
	StateRing

	// StateRinging indicates the channel's remote end is rining (the channel is receiving ringback)
	StateRinging

	// StateUp indicates the channel is up
	StateUp

	// StateBusy indicates the line is busy
	StateBusy

	// StateDialingOffHook indicates digits have been dialed while offhook
	StateDialingOffHook

	// StatePreRing indicates the channel has detected an incoming call and is waiting for ring
	StatePreRing
)

// AGI represents an AGI session
type AGI struct {
	// Variables stored the initial variables
	// transmitted from Asterisk at the start
	// of the AGI session.
	Variables map[string]string

	r    io.Reader
	eagi io.Reader
	w    io.Writer

	conn net.Conn

	mu sync.Mutex
}

// Response represents a response to an AGI
// request.
type Response struct {
	Error        error  // Error received, if any
	Status       int    // HTTP-style status code received
	Result       int    // Result is the numerical return (if parseable)
	ResultString string // Result value as a string
	Value        string // Value is the (optional) string value returned
}

// Err returns the error value from the response
func (r *Response) Err() error {
	return r.Error
}

// Val returns the response value and error
func (r *Response) Val() (string, error) {
	return r.Value, r.Error
}

// Regex for AGI response result code and value
var responseRegex = regexp.MustCompile(`^([\d]{3})\sresult=(\-?[[:alnum:]]*)(\s.*)?$`)

const (
	// StatusOK indicates the AGI command was
	// accepted.
	StatusOK = 200

	// StatusInvalid indicates Asterisk did not
	// understand the command.
	StatusInvalid = 510

	// StatusDeadChannel indicates that the command
	// cannot be performed on a dead (hungup) channel.
	StatusDeadChannel = 511

	// StatusEndUsage indicates...TODO
	StatusEndUsage = 520
)

// HandlerFunc is a function which accepts an AGI instance
type HandlerFunc func(*AGI)

// New creates an AGI session from the given reader and writer.
func New(r io.Reader, w io.Writer) *AGI {
	return NewWithEAGI(r, w, nil)
}

// NewWithEAGI returns a new AGI session to the given `os.Stdin` `io.Reader`,
// EAGI `io.Reader`, and `os.Stdout` `io.Writer`. The initial variables will
// be read in.
func NewWithEAGI(r io.Reader, w io.Writer, eagi io.Reader) *AGI {
	a := AGI{
		Variables: make(map[string]string),
		r:         r,
		w:         w,
		eagi:      eagi,
	}

	s := bufio.NewScanner(a.r)
	for s.Scan() {
		if s.Text() == "" {
			break
		}

		terms := strings.SplitN(s.Text(), ":", 2)
		if len(terms) == 2 {
			a.Variables[strings.TrimSpace(terms[0])] = strings.TrimSpace(terms[1])
		}
	}

	return &a
}

// NewConn returns a new AGI session bound to the given net.Conn interface
func NewConn(conn net.Conn) *AGI {
	a := New(conn, conn)
	a.conn = conn
	return a
}

// NewStdio returns a new AGI session to stdin and stdout.
func NewStdio() *AGI {
	return New(os.Stdin, os.Stdout)
}

// NewEAGI returns a new AGI session to stdin, the EAGI stream (FD=3), and stdout.
func NewEAGI() *AGI {
	return NewWithEAGI(os.Stdin, os.Stdout, os.NewFile(uintptr(3), "/dev/stdeagi"))
}

// Listen binds an AGI HandlerFunc to the given TCP `host:port` address, creating a FastAGI service.
func Listen(addr string, handler HandlerFunc) error {
	if addr == "" {
		addr = "localhost:4573"
	}

	l, err := net.Listen("tcp", addr)
	if err != nil {
		return errors.Wrap(err, "failed to bind server")
	}
	defer l.Close() // nolint: errcheck

	for {
		conn, err := l.Accept()
		if err != nil {
			return errors.Wrap(err, "failed to accept TCP connection")
		}

		go handler(NewConn(conn))
	}
}

// Close closes any network connection associated with the AGI instance
func (a *AGI) Close() (err error) {
	if a.conn != nil {
		err = a.conn.Close()
		a.conn = nil
	}
	return
}

// EAGI enables access to the EAGI incoming stream (if available).
func (a *AGI) EAGI() io.Reader {
	return a.eagi
}

// Command sends the given command line to stdout
// and returns the response.
// TODO: this does not handle multi-line responses properly
func (a *AGI) Command(cmd ...string) (resp *Response) {
	resp = &Response{}

	a.mu.Lock()
	defer a.mu.Unlock()

	cmdString := strings.Join(cmd, " ") + "\n"
	_, err := a.w.Write([]byte(cmdString))
	if err != nil {
		resp.Error = errors.Wrap(err, "failed to send command")
		return
	}

	s := bufio.NewScanner(a.r)
	for s.Scan() {
		raw := s.Text()
		if raw == "" {
			break
		}

		// Parse and store the result code
		pieces := responseRegex.FindStringSubmatch(raw)
		if pieces == nil {
			resp.Error = fmt.Errorf("failed to parse result: %s", raw)
			return
		}

		// Status code is the first substring
		resp.Status, err = strconv.Atoi(pieces[1])
		if err != nil {
			resp.Error = errors.Wrap(err, "failed to get status code")
			return
		}

		// Result code is the second substring
		resp.ResultString = pieces[2]
		resp.Result, err = strconv.Atoi(pieces[2])
		if err != nil {
			resp.Error = errors.Wrap(err, "failed to parse status code as an integer")
			return
		}

		// Value is the third (and optional) substring
		wrappedVal := strings.TrimSpace(pieces[3])
		resp.Value = strings.TrimSuffix(strings.TrimPrefix(wrappedVal, "("), ")")

		// FIXME: handle multiple line return values
		break // nolint
	}

	// If the Status code is not 200, return an error
	if resp.Status != 200 {
		resp.Error = fmt.Errorf("Non-200 status code")
	}
	return
}

// Answer answers the channel
func (a *AGI) Answer() error {
	return a.Command("ANSWER").Err()
}

// Status returns the channel status
func (a *AGI) Status() (State, error) {
	r, err := a.Command("CHANNEL STATUS").Val()
	if err != nil {
		return StateDown, err
	}
	state, err := strconv.Atoi(r)
	if err != nil {
		return StateDown, fmt.Errorf("Failed to parse state %s", r)
	}
	return State(state), nil
}

// Exec runs a dialplan application
func (a *AGI) Exec(cmd ...string) (string, error) {
	cmd = append([]string{"EXEC"}, cmd...)
	return a.Command(cmd...).Val()
}

// Get gets the value of the given channel variable
func (a *AGI) Get(key string) (string, error) {
	return a.Command("GET VARIABLE", key).Val()
}

// GetData plays a file and receives DTMF, returning the received digits
func (a *AGI) GetData(name string, timeout int, maxdigits int) (digit string, err error) {
	return a.Command("GET DATA", name, strconv.Itoa(timeout), strconv.Itoa(maxdigits)).Val()
}

// Hangup terminates the call
func (a *AGI) Hangup() error {
	return a.Command("HANGUP").Err()
}

// RecordOptions describes the options available when recording
type RecordOptions struct {
	// Format is the format of the audio file to record; defaults to "wav".
	Format string

	// EscapeDigits is the set of digits on receipt of which will terminate the recording. Default is "#".  This may not be blank.
	EscapeDigits string

	// Timeout is the maximum time to allow for the recording.  Defaults to 5 minutes.
	Timeout time.Duration

	// Silence is the maximum amount of silence to allow before ending the recording.  The finest resolution is to the second.   0=disabled, which is the default.
	Silence time.Duration

	// Beep controls whether a beep is played before starting the recording.  Defaults to false.
	Beep bool

	// Offset is the number of samples in the recording to advance before storing to the file.  This is means of clipping the beginning of a recording.  Defaults to 0.
	Offset int
}

// Record records audio to a file
func (a *AGI) Record(name string, opts *RecordOptions) error {
	if opts == nil {
		opts = &RecordOptions{}
	}
	if opts.Format == "" {
		opts.Format = "wav"
	}
	if opts.EscapeDigits == "" {
		opts.EscapeDigits = "#"
	}
	if opts.Timeout == 0 {
		opts.Timeout = 5 * time.Minute
	}

	cmd := strings.Join([]string{
		"RECORD FILE ",
		name,
		opts.Format,
		opts.EscapeDigits,
		toMSec(opts.Timeout),
	}, " ")

	if opts.Offset > 0 {
		cmd += " " + strconv.Itoa(opts.Offset)
	}

	if opts.Beep {
		cmd += " BEEP"
	}

	if opts.Silence > 0 {
		cmd += " s=" + toSec(opts.Silence)
	}

	return a.Command(cmd).Err()
}

// SayAlpha plays a character string, annunciating each character.
func (a *AGI) SayAlpha(label string, escapeDigits string) (digit string, err error) {
	return a.Command("SAY ALPHA", label, escapeDigits).Val()
}

// SayDigits plays a digit string, annunciating each digit.
func (a *AGI) SayDigits(number string, escapeDigits string) (digit string, err error) {
	return a.Command("SAY DIGITS", number, escapeDigits).Val()
}

// SayDate plays a date
func (a *AGI) SayDate(when time.Time, escapeDigits string) (digit string, err error) {
	return a.Command("SAY DATE", toEpoch(when), escapeDigits).Val()
}

// SayDateTime plays a date using the given format.  See `voicemail.conf` for the format syntax; defaults to `ABdY 'digits/at' IMp`.
func (a *AGI) SayDateTime(when time.Time, escapeDigits string, format string) (digit string, err error) {
	// Extract the timezone from the time
	zone, _ := when.Zone()

	// Use the Asterisk default format if we are not given one
	if format == "" {
		format = "ABdY 'digits/at' IMp"
	}

	return a.Command("SAY DATETIME", toEpoch(when), escapeDigits, format, zone).Val()
}

// SayNumber plays the given number.
func (a *AGI) SayNumber(number string, escapeDigits string) (digit string, err error) {
	return a.Command("SAY NUMBER", number, escapeDigits).Val()
}

// SayPhonetic plays the given phrase phonetically
func (a *AGI) SayPhonetic(phrase string, escapeDigits string) (digit string, err error) {
	return a.Command("SAY PHOENTIC", phrase, escapeDigits).Val()
}

// SayTime plays the time part of the given timestamp
func (a *AGI) SayTime(when time.Time, escapeDigits string) (digit string, err error) {
	return a.Command("SAY TIME", toEpoch(when), escapeDigits).Val()
}

// Set sets the given channel variable to
// the provided value.
func (a *AGI) Set(key, val string) error {
	return a.Command("SET VARIABLE", key, val).Err()
}

// StreamFile plays the given file to the channel
func (a *AGI) StreamFile(name string, escapeDigits string, offset int) (digit string, err error) {
	return a.Command("STREAM FILE", name, escapeDigits, strconv.Itoa(offset)).Val()
}

// Verbose logs the given message to the verbose message system
func (a *AGI) Verbose(msg string, level int) error {
	return a.Command("VERBOSE", strconv.Quote(msg), strconv.Itoa(level)).Err()
}

// WaitForDigit waits for a DTMF digit and returns what is received
func (a *AGI) WaitForDigit(timeout time.Duration) (digit string, err error) {
	resp := a.Command("WAIT FOR DIGIT", toMSec(timeout))
	return string(resp.Result), resp.Error
}
<commit_msg>Some enhancements (#7)<commit_after>package agi

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"net"
	"os"
	"regexp"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/pkg/errors"
)

// State describes the Asterisk channel state.  There are mapped
// directly to the Asterisk enumerations.
type State int

const (
	// StateDown indicates the channel is down and available
	StateDown State = iota

	// StateReserved indicates the channel is down but reserved
	StateReserved

	// StateOffhook indicates that the channel is offhook
	StateOffhook

	// StateDialing indicates that digits have been dialed
	StateDialing

	// StateRing indicates the channel is ringing
	StateRing

	// StateRinging indicates the channel's remote end is rining (the channel is receiving ringback)
	StateRinging

	// StateUp indicates the channel is up
	StateUp

	// StateBusy indicates the line is busy
	StateBusy

	// StateDialingOffHook indicates digits have been dialed while offhook
	StateDialingOffHook

	// StatePreRing indicates the channel has detected an incoming call and is waiting for ring
	StatePreRing
)

// AGI represents an AGI session
type AGI struct {
	// Variables stored the initial variables
	// transmitted from Asterisk at the start
	// of the AGI session.
	Variables map[string]string

	r    io.Reader
	eagi io.Reader
	w    io.Writer

	conn net.Conn

	mu sync.Mutex

	// Logging ability
	logger *log.Logger
}

// Response represents a response to an AGI
// request.
type Response struct {
	Error        error  // Error received, if any
	Status       int    // HTTP-style status code received
	Result       int    // Result is the numerical return (if parseable)
	ResultString string // Result value as a string
	Value        string // Value is the (optional) string value returned
}

// Err returns the error value from the response
func (r *Response) Err() error {
	return r.Error
}

// Val returns the response value and error
func (r *Response) Val() (string, error) {
	return r.Value, r.Error
}

// Regex for AGI response result code and value
var responseRegex = regexp.MustCompile(`^([\d]{3})\sresult=(\-?[[:alnum:]]*)(\s.*)?$`)

const (
	// StatusOK indicates the AGI command was
	// accepted.
	StatusOK = 200

	// StatusInvalid indicates Asterisk did not
	// understand the command.
	StatusInvalid = 510

	// StatusDeadChannel indicates that the command
	// cannot be performed on a dead (hungup) channel.
	StatusDeadChannel = 511

	// StatusEndUsage indicates...TODO
	StatusEndUsage = 520
)

// HandlerFunc is a function which accepts an AGI instance
type HandlerFunc func(*AGI)

// New creates an AGI session from the given reader and writer.
func New(r io.Reader, w io.Writer) *AGI {
	return NewWithEAGI(r, w, nil)
}

// NewWithEAGI returns a new AGI session to the given `os.Stdin` `io.Reader`,
// EAGI `io.Reader`, and `os.Stdout` `io.Writer`. The initial variables will
// be read in.
func NewWithEAGI(r io.Reader, w io.Writer, eagi io.Reader) *AGI {
	a := AGI{
		Variables: make(map[string]string),
		r:         r,
		w:         w,
		eagi:      eagi,
	}

	s := bufio.NewScanner(a.r)
	for s.Scan() {
		if s.Text() == "" {
			break
		}

		terms := strings.SplitN(s.Text(), ":", 2)
		if len(terms) == 2 {
			a.Variables[strings.TrimSpace(terms[0])] = strings.TrimSpace(terms[1])
		}
	}

	return &a
}

// NewConn returns a new AGI session bound to the given net.Conn interface
func NewConn(conn net.Conn) *AGI {
	a := New(conn, conn)
	a.conn = conn
	return a
}

// NewStdio returns a new AGI session to stdin and stdout.
func NewStdio() *AGI {
	return New(os.Stdin, os.Stdout)
}

// NewEAGI returns a new AGI session to stdin, the EAGI stream (FD=3), and stdout.
func NewEAGI() *AGI {
	return NewWithEAGI(os.Stdin, os.Stdout, os.NewFile(uintptr(3), "/dev/stdeagi"))
}

// Listen binds an AGI HandlerFunc to the given TCP `host:port` address, creating a FastAGI service.
func Listen(addr string, handler HandlerFunc) error {
	if addr == "" {
		addr = "localhost:4573"
	}

	l, err := net.Listen("tcp", addr)
	if err != nil {
		return errors.Wrap(err, "failed to bind server")
	}
	defer l.Close() // nolint: errcheck

	for {
		conn, err := l.Accept()
		if err != nil {
			return errors.Wrap(err, "failed to accept TCP connection")
		}

		go handler(NewConn(conn))
	}
}

// Close closes any network connection associated with the AGI instance
func (a *AGI) Close() (err error) {
	if a.conn != nil {
		err = a.conn.Close()
		a.conn = nil
	}
	return
}

// EAGI enables access to the EAGI incoming stream (if available).
func (a *AGI) EAGI() io.Reader {
	return a.eagi
}

// Command sends the given command line to stdout
// and returns the response.
// TODO: this does not handle multi-line responses properly
func (a *AGI) Command(cmd ...string) (resp *Response) {
	resp = &Response{}
	cmdString := strings.Join(cmd, " ")
	var raw string

	a.mu.Lock()
	defer a.mu.Unlock()

	// Logging raw command and answer
	if a.logger != nil {
		defer func() {
			resString := ""
			if resp.Error == nil {
				resString += " Sta:" + strconv.Itoa(resp.Status)
				resString += " Res:" + strconv.Itoa(resp.Result)
				if resp.ResultString != "" {
					resString += " Str:" + resp.ResultString
				}
				if resp.Value != "" {
					resString += " Val:" + resp.Value
				}
			} else {
				resString += " Err:" + resp.Error.Error()
			}
			resString = "{" + strings.TrimSpace(resString) + "}"
			a.logger.Printf("#%s -> %s -> %s", cmdString, raw, resString)
		}()
	}

	_, err := a.w.Write([]byte(cmdString + "\n"))
	if err != nil {
		resp.Error = errors.Wrap(err, "failed to send command")
		return
	}

	s := bufio.NewScanner(a.r)
	for s.Scan() {
		raw = s.Text()
		if raw == "" {
			break
		}

		// Parse and store the result code
		pieces := responseRegex.FindStringSubmatch(raw)
		if pieces == nil {
			resp.Error = fmt.Errorf("failed to parse result: %s", raw)
			return
		}

		// Status code is the first substring
		resp.Status, err = strconv.Atoi(pieces[1])
		if err != nil {
			resp.Error = errors.Wrap(err, "failed to get status code")
			return
		}

		// Result code is the second substring
		resp.ResultString = pieces[2]
		resp.Result, err = strconv.Atoi(pieces[2])
		if err != nil {
			resp.Error = errors.Wrap(err, "failed to parse status code as an integer")
			return
		}

		// Value is the third (and optional) substring
		wrappedVal := strings.TrimSpace(pieces[3])
		resp.Value = strings.TrimSuffix(strings.TrimPrefix(wrappedVal, "("), ")")

		// FIXME: handle multiple line return values
		break // nolint
	}

	// If the Status code is not 200, return an error
	if resp.Status != 200 {
		resp.Error = fmt.Errorf("Non-200 status code")
	}
	return
}

// Answer answers the channel
func (a *AGI) Answer() error {
	return a.Command("ANSWER").Err()
}

// Status returns the channel status
func (a *AGI) Status() (State, error) {
	r, err := a.Command("CHANNEL STATUS").Val()
	if err != nil {
		return StateDown, err
	}
	state, err := strconv.Atoi(r)
	if err != nil {
		return StateDown, fmt.Errorf("Failed to parse state %s", r)
	}
	return State(state), nil
}

// Exec runs a dialplan application
func (a *AGI) Exec(cmd ...string) (string, error) {
	cmd = append([]string{"EXEC"}, cmd...)
	return a.Command(cmd...).Val()
}

// Get gets the value of the given channel variable
func (a *AGI) Get(key string) (string, error) {
	return a.Command("GET VARIABLE", key).Val()
}

// GetData plays a file and receives DTMF, returning the received digits
func (a *AGI) GetData(name string, timeout int, maxdigits int) (digit string, err error) {
	return a.Command("GET DATA", name, strconv.Itoa(timeout), strconv.Itoa(maxdigits)).Val()
}

// Hangup terminates the call
func (a *AGI) Hangup() error {
	return a.Command("HANGUP").Err()
}

// RecordOptions describes the options available when recording
type RecordOptions struct {
	// Format is the format of the audio file to record; defaults to "wav".
	Format string

	// EscapeDigits is the set of digits on receipt of which will terminate the recording. Default is "#".  This may not be blank.
	EscapeDigits string

	// Timeout is the maximum time to allow for the recording.  Defaults to 5 minutes.
	Timeout time.Duration

	// Silence is the maximum amount of silence to allow before ending the recording.  The finest resolution is to the second.   0=disabled, which is the default.
	Silence time.Duration

	// Beep controls whether a beep is played before starting the recording.  Defaults to false.
	Beep bool

	// Offset is the number of samples in the recording to advance before storing to the file.  This is means of clipping the beginning of a recording.  Defaults to 0.
	Offset int
}

// Record records audio to a file
func (a *AGI) Record(name string, opts *RecordOptions) error {
	if opts == nil {
		opts = &RecordOptions{}
	}
	if opts.Format == "" {
		opts.Format = "wav"
	}
	if opts.EscapeDigits == "" {
		opts.EscapeDigits = "#"
	}
	if opts.Timeout == 0 {
		opts.Timeout = 5 * time.Minute
	}

	cmd := strings.Join([]string{
		"RECORD FILE ",
		name,
		opts.Format,
		opts.EscapeDigits,
		toMSec(opts.Timeout),
	}, " ")

	if opts.Offset > 0 {
		cmd += " " + strconv.Itoa(opts.Offset)
	}

	if opts.Beep {
		cmd += " BEEP"
	}

	if opts.Silence > 0 {
		cmd += " s=" + toSec(opts.Silence)
	}

	return a.Command(cmd).Err()
}

// SayAlpha plays a character string, annunciating each character.
func (a *AGI) SayAlpha(label string, escapeDigits string) (digit string, err error) {
	return a.Command("SAY ALPHA", label, escapeDigits).Val()
}

// SayDigits plays a digit string, annunciating each digit.
func (a *AGI) SayDigits(number string, escapeDigits string) (digit string, err error) {
	return a.Command("SAY DIGITS", number, escapeDigits).Val()
}

// SayDate plays a date
func (a *AGI) SayDate(when time.Time, escapeDigits string) (digit string, err error) {
	return a.Command("SAY DATE", toEpoch(when), escapeDigits).Val()
}

// SayDateTime plays a date using the given format.  See `voicemail.conf` for the format syntax; defaults to `ABdY 'digits/at' IMp`.
func (a *AGI) SayDateTime(when time.Time, escapeDigits string, format string) (digit string, err error) {
	// Extract the timezone from the time
	zone, _ := when.Zone()

	// Use the Asterisk default format if we are not given one
	if format == "" {
		format = "ABdY 'digits/at' IMp"
	}

	return a.Command("SAY DATETIME", toEpoch(when), escapeDigits, format, zone).Val()
}

// SayNumber plays the given number.
func (a *AGI) SayNumber(number string, escapeDigits string) (digit string, err error) {
	return a.Command("SAY NUMBER", number, escapeDigits).Val()
}

// SayPhonetic plays the given phrase phonetically
func (a *AGI) SayPhonetic(phrase string, escapeDigits string) (digit string, err error) {
	return a.Command("SAY PHOENTIC", phrase, escapeDigits).Val()
}

// SayTime plays the time part of the given timestamp
func (a *AGI) SayTime(when time.Time, escapeDigits string) (digit string, err error) {
	return a.Command("SAY TIME", toEpoch(when), escapeDigits).Val()
}

// Set sets the given channel variable to
// the provided value.
func (a *AGI) Set(key, val string) error {
	return a.Command("SET VARIABLE", key, val).Err()
}

// StreamFile plays the given file to the channel
func (a *AGI) StreamFile(name string, escapeDigits string, offset int) (digit string, err error) {
	return a.Command("STREAM FILE", name, escapeDigits, strconv.Itoa(offset)).Val()
}

// Verbose logs the given message to the verbose message system
func (a *AGI) Verbose(msg string, level int) error {
	return a.Command("VERBOSE", strconv.Quote(msg), strconv.Itoa(level)).Err()
}

// Verbosef logs the formatted verbose output
func (a *AGI) Verbosef(format string, args ...interface{}) error {
	return a.Verbose(fmt.Sprintf(format, args...), 9)
}

// WaitForDigit waits for a DTMF digit and returns what is received
func (a *AGI) WaitForDigit(timeout time.Duration) (digit string, err error) {
	resp := a.Command("WAIT FOR DIGIT", toMSec(timeout))
	resp.ResultString = ""
	if resp.Error == nil && strconv.IsPrint(rune(resp.Result)) {
		resp.ResultString = string(resp.Result)
	}
	return resp.ResultString, resp.Error
}

// SetLogger setup external logger for low-level logging
func (a *AGI) SetLogger(l *log.Logger) error {
	if l != nil && a.logger != nil {
		return errors.New("Logger already attached")
	}
	a.logger = l

	// Output variables
	if a.logger != nil {
		for k, v := range a.Variables {
			a.logger.Printf("$%s=%s\n", k, v)
		}
	}

	return nil
}
<|endoftext|>


<commit_before>// Code generated by depstubber. DO NOT EDIT.
// This is a simple stub for k8s.io/client-go/kubernetes/typed/core/v1, strictly for use in testing.

// See the LICENSE file for information about the licensing of the original library.
// Source: k8s.io/client-go/kubernetes/typed/core/v1 (exports: SecretInterface; functions: )

// Package core is a stub of k8s.io/client-go/kubernetes/typed/core/v1, generated by depstubber.
package core

import (
	context "context"
	time "time"
)

type SecretInterface interface {
	Create(_ context.Context, _ interface{}, _ interface{}) (interface{}, error)
	Delete(_ context.Context, _ string, _ interface{}) error
	DeleteCollection(_ context.Context, _ interface{}, _ interface{}) error
	Get(_ context.Context, _ string, _ interface{}) (interface{}, error)
	List(_ context.Context, _ interface{}) (interface{}, error)
	Patch(_ context.Context, _ string, _ interface{}, _ []byte, _ interface{}, _ ...string) (interface{}, error)
	Update(_ context.Context, _ interface{}, _ interface{}) (interface{}, error)
	Watch(_ context.Context, _ interface{}) (interface{}, error)
}
<commit_msg>Remove erroneous import from stub<commit_after>// Code generated by depstubber. DO NOT EDIT.
// This is a simple stub for k8s.io/client-go/kubernetes/typed/core/v1, strictly for use in testing.

// See the LICENSE file for information about the licensing of the original library.
// Source: k8s.io/client-go/kubernetes/typed/core/v1 (exports: SecretInterface; functions: )

// Package core is a stub of k8s.io/client-go/kubernetes/typed/core/v1, generated by depstubber.
package core

import (
	context "context"
)

type SecretInterface interface {
	Create(_ context.Context, _ interface{}, _ interface{}) (interface{}, error)
	Delete(_ context.Context, _ string, _ interface{}) error
	DeleteCollection(_ context.Context, _ interface{}, _ interface{}) error
	Get(_ context.Context, _ string, _ interface{}) (interface{}, error)
	List(_ context.Context, _ interface{}) (interface{}, error)
	Patch(_ context.Context, _ string, _ interface{}, _ []byte, _ interface{}, _ ...string) (interface{}, error)
	Update(_ context.Context, _ interface{}, _ interface{}) (interface{}, error)
	Watch(_ context.Context, _ interface{}) (interface{}, error)
}
<|endoftext|>