<commit_before>package endly

import (
	"github.com/lunixbochs/vtclean"
	"strings"
)

const commandNotFound = "command not found"
const noSuchFileOrDirectory = "no such file or directory"
const programCanBeFound = "can be found in the following packages"
const errorIsNotRecoverable = "Error is not recoverable"
const notInstalled = "not installed"

//CheckNoSuchFileOrDirectory checks for no such file or directory message in the provided stdout.
func CheckNoSuchFileOrDirectory(stdout ...string) bool {
	if len(stdout) == 0 {
		return false
	}
	candidate := strings.ToLower(strings.Join(stdout, "\n"))
	return strings.Contains(candidate, noSuchFileOrDirectory)
}

//CheckCommandNotFound checks for command not found message in the provided stdout.
func CheckCommandNotFound(stdout ...string) bool {
	if len(stdout) == 0 {
		return false
	}
	candidate := strings.ToLower(strings.Join(stdout, "\n"))
	return strings.Contains(candidate, commandNotFound) || strings.Contains(candidate, notInstalled)
}

//ExtractColumn extract a column from the line for provided index
func ExtractColumn(line string, columnIndex int) (string, bool) {
	var columns, has = ExtractColumns(line)
	if !has {
		return "", has
	}
	if columnIndex < len(columns) {
		return columns[columnIndex], true
	}
	return "", false
}

//ExtractColumns extract all column from the line
func ExtractColumns(line string) ([]string, bool) {
	if line == "" {
		return []string{}, false
	}
	line = vtclean.Clean(line, false)
	var index = -1
	var expectColumn = true
	var result = make([]string, 0)

	for i := 0; i < len(line); i++ {
		var aChar = string(line[i : i+1])
		if aChar == " " || aChar == "\t" {
			expectColumn = true
			continue
		}
		if expectColumn {
			index++
			result = append(result, "")
			expectColumn = false
		}
		result[index] += aChar
	}
	return result, true
}

func escapeStdout(stdout string) string {
	return vtclean.Clean(stdout, true)
}
<commit_msg>expanded not fund definition<commit_after>package endly

import (
	"github.com/lunixbochs/vtclean"
	"strings"
)

const commandNotFound = "command not found"
const noSuchFileOrDirectory = "no such file or directory"
const programCanBeFound = "can be found in the following packages"
const errorIsNotRecoverable = "Error is not recoverable"
const notInstalled = "not installed"
const canNotOpen = "Can't open"

//CheckNoSuchFileOrDirectory checks for no such file or directory message in the provided stdout.
func CheckNoSuchFileOrDirectory(stdout ...string) bool {
	if len(stdout) == 0 {
		return false
	}
	candidate := strings.ToLower(strings.Join(stdout, "\n"))
	return strings.Contains(candidate, noSuchFileOrDirectory)
}

//CheckCommandNotFound checks for command not found message in the provided stdout.
func CheckCommandNotFound(stdout ...string) bool {
	if len(stdout) == 0 {
		return false
	}
	candidate := strings.ToLower(strings.Join(stdout, "\n"))
	return strings.Contains(candidate, commandNotFound) || strings.Contains(candidate, notInstalled) || strings.Contains(candidate, canNotOpen)
}

//ExtractColumn extract a column from the line for provided index
func ExtractColumn(line string, columnIndex int) (string, bool) {
	var columns, has = ExtractColumns(line)
	if !has {
		return "", has
	}
	if columnIndex < len(columns) {
		return columns[columnIndex], true
	}
	return "", false
}

//ExtractColumns extract all column from the line
func ExtractColumns(line string) ([]string, bool) {
	if line == "" {
		return []string{}, false
	}
	line = vtclean.Clean(line, false)
	var index = -1
	var expectColumn = true
	var result = make([]string, 0)

	for i := 0; i < len(line); i++ {
		var aChar = string(line[i : i+1])
		if aChar == " " || aChar == "\t" {
			expectColumn = true
			continue
		}
		if expectColumn {
			index++
			result = append(result, "")
			expectColumn = false
		}
		result[index] += aChar
	}
	return result, true
}

func escapeStdout(stdout string) string {
	return vtclean.Clean(stdout, true)
}
<|endoftext|>


<commit_before>package memkv

import (
	"reflect"
	"testing"
)

var getTests = []struct {
	Key   string
	Value string
}{
	{"/myapp/database/username", "admin"},
	{"/myapp/database/password", "123456789"},
}

func TestGet(t *testing.T) {
	for _, tt := range getTests {
		s := New()
		s.Set(tt.Key, tt.Value)
		got, ok := s.Get(tt.Key)
		if !ok {
			t.Errorf("missing key")
		}
		want := Node{tt.Key, tt.Value}
		if got != want {
			t.Errorf("wanted %v, got %v", want, got)
		}
	}
}

type missingKeyResult struct {
	node Node
	ok   bool
}

func TestMissingKey(t *testing.T) {
	s := New()
	want := missingKeyResult{Node{}, false}
	node, ok := s.Get("/missing/key")
	got := missingKeyResult{node, ok}
	if !reflect.DeepEqual(got, want) {
		t.Errorf("wanted %v, got %v", want, got)
	}
}

type getAllResult struct {
	nodes []Node
}

func TestGetAll(t *testing.T) {
	s := New()
	s.Set("/myapp/database/username", "admin")
	s.Set("/myapp/database/password", "123456789")
	s.Set("/myapp/port", "80")
	want := getAllResult{
		nodes: []Node{
			Node{"/myapp/database/password", "123456789"},
			Node{"/myapp/database/username", "admin"},
		},
	}
	nodes, err := s.GetAll("/myapp/*/*")
	if err != nil {
		t.Error(err.Error())
	}
	got := getAllResult{nodes}
	if !reflect.DeepEqual(got, want) {
		t.Errorf("wanted %v, got %v", want, got)
	}
}
<commit_msg>add test for bad pattern<commit_after>package memkv

import (
	"reflect"
	"testing"
)

var getTests = []struct {
	Key   string
	Value string
}{
	{"/myapp/database/username", "admin"},
	{"/myapp/database/password", "123456789"},
}

func TestGet(t *testing.T) {
	for _, tt := range getTests {
		s := New()
		s.Set(tt.Key, tt.Value)
		got, ok := s.Get(tt.Key)
		if !ok {
			t.Errorf("missing key")
		}
		want := Node{tt.Key, tt.Value}
		if got != want {
			t.Errorf("wanted %v, got %v", want, got)
		}
	}
}

type missingKeyResult struct {
	node Node
	ok   bool
}

func TestMissingKey(t *testing.T) {
	s := New()
	want := missingKeyResult{Node{}, false}
	node, ok := s.Get("/missing/key")
	got := missingKeyResult{node, ok}
	if !reflect.DeepEqual(got, want) {
		t.Errorf("wanted %v, got %v", want, got)
	}
}

type getAllResult struct {
	nodes []Node
}

func TestGetAll(t *testing.T) {
	s := New()
	s.Set("/myapp/database/username", "admin")
	s.Set("/myapp/database/password", "123456789")
	s.Set("/myapp/port", "80")
	want := getAllResult{
		nodes: []Node{
			Node{"/myapp/database/password", "123456789"},
			Node{"/myapp/database/username", "admin"},
		},
	}
	nodes, err := s.GetAll("/myapp/*/*")
	if err != nil {
		t.Error(err.Error())
	}
	got := getAllResult{nodes}
	if !reflect.DeepEqual(got, want) {
		t.Errorf("wanted %v, got %v", want, got)
	}
}

func TestGetAllBadPattern(t *testing.T) {
	s := New()
	s.Set("/myapp/database/username", "admin")
	_, err := s.GetAll("[]a]")
	if err == nil {
		t.Error("expected an error on bad pattern")
	}
}
<|endoftext|>


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

// +build windows

package libdokan

import (
	"fmt"
	"path"
	"sync"

	"github.com/keybase/kbfs/dokan"
)

// Mounter defines interface for different mounting strategies
type Mounter interface {
	Dir() string
	Mount(dokan.FileSystem) error
	Unmount() error
}

// DefaultMounter will only call fuse.Mount and fuse.Unmount directly
type DefaultMounter struct {
	lock  sync.Mutex
	dir   string
	force bool
	mnt   *dokan.MountHandle
}

// NewDefaultMounter creates a default mounter.
func NewDefaultMounter(dir string) *DefaultMounter {
	return &DefaultMounter{dir: dir, force: false}
}

// NewForceMounter creates a force mounter.
func NewForceMounter(dir string) *DefaultMounter {
	return &DefaultMounter{dir: dir, force: true}
}

// Mount uses default mount and blocks.
func (m *DefaultMounter) Mount(fs dokan.FileSystem) error {
	h, err := m.mountHelper(fs)
	if err != nil {
		return err
	}
	return h.BlockTillDone()
}

// mountHelper is needed since Unmount may be called from an another
// go-routine.
func (m *DefaultMounter) mountHelper(fs dokan.FileSystem) (*dokan.MountHandle, error) {
	// m.dir is constant and safe to access outside the lock.
	handle, err := dokan.Mount(fs, m.dir)
	if err != nil {
		return nil, err
	}

	m.lock.Lock()
	defer m.lock.Unlock()
	m.mnt = handle
	return handle, nil
}

// Unmount uses default unmount
func (m *DefaultMounter) Unmount() error {
	if m.mnt == nil {
		return nil
	}
	m.lock.Lock()
	h := m.mnt
	m.lock.Unlock()
	return h.Close()
}

// Dir returns mount directory.
func (m *DefaultMounter) Dir() string {
	return m.dir
}

// volumeName returns the directory (base) name
func volumeName(dir string) (string, error) {
	volName := path.Base(dir)
	if volName == "." || volName == "/" {
		err := fmt.Errorf("Bad volume name: %v", volName)
		return "", err
	}
	return volName, nil
}
<commit_msg>libdokan: Unmount first when using ForceMounter<commit_after>// Copyright 2015 Keybase Inc. All rights reserved.
// Use of this source code is governed by a BSD
// license that can be found in the LICENSE file.

// +build windows

package libdokan

import (
	"fmt"
	"path"
	"sync"

	"github.com/keybase/kbfs/dokan"
)

// Mounter defines interface for different mounting strategies
type Mounter interface {
	Dir() string
	Mount(dokan.FileSystem) error
	Unmount() error
}

// DefaultMounter will only call fuse.Mount and fuse.Unmount directly
type DefaultMounter struct {
	lock  sync.Mutex
	dir   string
	force bool
	mnt   *dokan.MountHandle
}

// NewDefaultMounter creates a default mounter.
func NewDefaultMounter(dir string) *DefaultMounter {
	return &DefaultMounter{dir: dir, force: false}
}

// NewForceMounter creates a force mounter.
func NewForceMounter(dir string) *DefaultMounter {
	return &DefaultMounter{dir: dir, force: true}
}

// Mount uses default mount and blocks.
func (m *DefaultMounter) Mount(fs dokan.FileSystem) error {
	if m.force {
		dokan.Unmount(m.dir)
	}
	h, err := m.mountHelper(fs)
	if err != nil {
		return err
	}
	return h.BlockTillDone()
}

// mountHelper is needed since Unmount may be called from an another
// go-routine.
func (m *DefaultMounter) mountHelper(fs dokan.FileSystem) (*dokan.MountHandle, error) {
	// m.dir is constant and safe to access outside the lock.
	handle, err := dokan.Mount(fs, m.dir)
	if err != nil {
		return nil, err
	}

	m.lock.Lock()
	defer m.lock.Unlock()
	m.mnt = handle
	return handle, nil
}

// Unmount uses default unmount
func (m *DefaultMounter) Unmount() error {
	if m.mnt == nil {
		return nil
	}
	m.lock.Lock()
	h := m.mnt
	m.lock.Unlock()
	return h.Close()
}

// Dir returns mount directory.
func (m *DefaultMounter) Dir() string {
	return m.dir
}

// volumeName returns the directory (base) name
func volumeName(dir string) (string, error) {
	volName := path.Base(dir)
	if volName == "." || volName == "/" {
		err := fmt.Errorf("Bad volume name: %v", volName)
		return "", err
	}
	return volName, nil
}
<|endoftext|>


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

// +build windows

package libdokan

import (
	"fmt"
	"path"
	"sync"
	"time"

	"github.com/keybase/kbfs/dokan"
)

// Mounter defines interface for different mounting strategies
type Mounter interface {
	Dir() string
	Mount(dokan.FileSystem) error
	Unmount() error
}

// DefaultMounter will only call fuse.Mount and fuse.Unmount directly
type DefaultMounter struct {
	lock  sync.Mutex
	dir   string
	force bool
	mnt   *dokan.MountHandle
}

// NewDefaultMounter creates a default mounter.
func NewDefaultMounter(dir string) *DefaultMounter {
	return &DefaultMounter{dir: dir, force: false}
}

// NewForceMounter creates a force mounter.
func NewForceMounter(dir string) *DefaultMounter {
	return &DefaultMounter{dir: dir, force: true}
}

// Mount uses default mount and blocks.
func (m *DefaultMounter) Mount(fs dokan.FileSystem) error {
	var err error
	var h *dokan.MountHandle
	// Retry loop
	for i := 1; true; i++ {
		h, err = m.mountHelper(fs)
		// break if success, no force or too many tries.
		if err == nil || i > 3 {
			break
		}
		// Sleep two times 100ms, 200ms, ...
		time.Sleep(time.Duration(i) * 100 * time.Millisecond)
		if m.force {
			dokan.Unmount(m.dir)
			time.Sleep(time.Duration(i) * 100 * time.Millisecond)
		}
	}

	if err != nil {
		return err
	}
	return h.BlockTillDone()
}

// mountHelper is needed since Unmount may be called from an another
// go-routine.
func (m *DefaultMounter) mountHelper(fs dokan.FileSystem) (*dokan.MountHandle, error) {
	// m.dir is constant and safe to access outside the lock.
	handle, err := dokan.Mount(fs, m.dir)
	if err != nil {
		return nil, err
	}

	m.lock.Lock()
	defer m.lock.Unlock()
	m.mnt = handle
	return handle, nil
}

// Unmount uses default unmount
func (m *DefaultMounter) Unmount() error {
	if m.mnt == nil {
		return nil
	}
	m.lock.Lock()
	h := m.mnt
	m.lock.Unlock()
	return h.Close()
}

// Dir returns mount directory.
func (m *DefaultMounter) Dir() string {
	return m.dir
}

// volumeName returns the directory (base) name
func volumeName(dir string) (string, error) {
	volName := path.Base(dir)
	if volName == "." || volName == "/" {
		err := fmt.Errorf("Bad volume name: %v", volName)
		return "", err
	}
	return volName, nil
}
<commit_msg>libdokan: Even more conservative mount with more retries<commit_after>// Copyright 2015 Keybase Inc. All rights reserved.
// Use of this source code is governed by a BSD
// license that can be found in the LICENSE file.

// +build windows

package libdokan

import (
	"fmt"
	"path"
	"sync"
	"time"

	"github.com/keybase/kbfs/dokan"
)

// Mounter defines interface for different mounting strategies
type Mounter interface {
	Dir() string
	Mount(dokan.FileSystem) error
	Unmount() error
}

// DefaultMounter will only call fuse.Mount and fuse.Unmount directly
type DefaultMounter struct {
	lock  sync.Mutex
	dir   string
	force bool
	mnt   *dokan.MountHandle
}

// NewDefaultMounter creates a default mounter.
func NewDefaultMounter(dir string) *DefaultMounter {
	return &DefaultMounter{dir: dir, force: false}
}

// NewForceMounter creates a force mounter.
func NewForceMounter(dir string) *DefaultMounter {
	return &DefaultMounter{dir: dir, force: true}
}

// Mount uses default mount and blocks.
func (m *DefaultMounter) Mount(fs dokan.FileSystem) error {
	var err error
	var h *dokan.MountHandle
	// Retry loop
	for i := 1; true; i *= 2 {
		h, err = m.mountHelper(fs)
		// break if success, no force or too many tries.
		if err == nil || i > 20 {
			break
		}
		// Sleep two times 100ms, 200ms, 400, 800...
		time.Sleep(time.Duration(i) * 100 * time.Millisecond)
		if m.force {
			dokan.Unmount(m.dir)
			time.Sleep(time.Duration(i) * 100 * time.Millisecond)
		}
	}

	if err != nil {
		return err
	}
	return h.BlockTillDone()
}

// mountHelper is needed since Unmount may be called from an another
// go-routine.
func (m *DefaultMounter) mountHelper(fs dokan.FileSystem) (*dokan.MountHandle, error) {
	// m.dir is constant and safe to access outside the lock.
	handle, err := dokan.Mount(fs, m.dir)
	if err != nil {
		return nil, err
	}

	m.lock.Lock()
	defer m.lock.Unlock()
	m.mnt = handle
	return handle, nil
}

// Unmount uses default unmount
func (m *DefaultMounter) Unmount() error {
	if m.mnt == nil {
		return nil
	}
	m.lock.Lock()
	h := m.mnt
	m.lock.Unlock()
	return h.Close()
}

// Dir returns mount directory.
func (m *DefaultMounter) Dir() string {
	return m.dir
}

// volumeName returns the directory (base) name
func volumeName(dir string) (string, error) {
	volName := path.Base(dir)
	if volName == "." || volName == "/" {
		err := fmt.Errorf("Bad volume name: %v", volName)
		return "", err
	}
	return volName, nil
}
<|endoftext|>


<commit_before>package stripe

import "encoding/json"

// InvoiceLineType is the list of allowed values for the invoice line's type.
type InvoiceLineType string

// List of values that InvoiceLineType can take.
const (
	InvoiceLineTypeInvoiceItem  InvoiceLineType = "invoiceitem"
	InvoiceLineTypeSubscription InvoiceLineType = "subscription"
)

// InvoiceBilling is the type of billing method for this invoice.
type InvoiceBilling string

// List of values that InvoiceBilling can take.
const (
	InvoiceBillingChargeAutomatically InvoiceBilling = "charge_automatically"
	InvoiceBillingSendInvoice         InvoiceBilling = "send_invoice"
)

// InvoiceBillingReason is the reason why a given invoice was created
type InvoiceBillingReason string

// List of values that InvoiceBillingReason can take.
const (
	InvoiceBillingReasonManual             InvoiceBillingReason = "manual"
	InvoiceBillingReasonSubscription       InvoiceBillingReason = "subscription"
	InvoiceBillingReasonSubscriptionCreate InvoiceBillingReason = "subscription_create"
	InvoiceBillingReasonSubscriptionCycle  InvoiceBillingReason = "subscription_cycle"
	InvoiceBillingReasonSubscriptionUpdate InvoiceBillingReason = "subscription_update"
	InvoiceBillingReasonUpcoming           InvoiceBillingReason = "upcoming"
)

// InvoiceBillingStatus is the reason why a given invoice was created
type InvoiceBillingStatus string

// List of values that InvoiceBillingStatus can take.
const (
	InvoiceBillingStatusDraft         InvoiceBillingStatus = "draft"
	InvoiceBillingStatusOpen          InvoiceBillingStatus = "open"
	InvoiceBillingStatusPaid          InvoiceBillingStatus = "paid"
	InvoiceBillingStatusUncollectible InvoiceBillingStatus = "uncollectible"
	InvoiceBillingStatusVoid          InvoiceBillingStatus = "void"
)

// InvoiceUpcomingInvoiceItemParams is the set of parameters that can be used when adding or modifying
// invoice items on an upcoming invoice.
// For more details see https://stripe.com/docs/api#upcoming_invoice-invoice_items.
type InvoiceUpcomingInvoiceItemParams struct {
	Amount       *int64  `form:"amount"`
	Currency     *string `form:"currency"`
	Description  *string `form:"description"`
	Discountable *bool   `form:"discountable"`
	InvoiceItem  *string `form:"invoiceitem"`
}

// InvoiceParams is the set of parameters that can be used when creating or updating an invoice.
// For more details see https://stripe.com/docs/api#create_invoice, https://stripe.com/docs/api#update_invoice.
type InvoiceParams struct {
	Params              `form:"*"`
	AutoAdvance         *bool    `form:"auto_advance"`
	ApplicationFee      *int64   `form:"application_fee"`
	Billing             *string  `form:"billing"`
	Customer            *string  `form:"customer"`
	DaysUntilDue        *int64   `form:"days_until_due"`
	DefaultSource       *string  `form:"default_source"`
	Description         *string  `form:"description"`
	DueDate             *int64   `form:"due_date"`
	Paid                *bool    `form:"paid"`
	StatementDescriptor *string  `form:"statement_descriptor"`
	Subscription        *string  `form:"subscription"`
	TaxPercent          *float64 `form:"tax_percent"`

	// These are all for exclusive use by GetNext.

	Coupon                         *string                           `form:"coupon"`
	InvoiceItems                   *InvoiceUpcomingInvoiceItemParams `form:"invoice_items"`
	SubscriptionBillingCycleAnchor *int64                            `form:"subscription_billing_cycle_anchor"`
	SubscriptionCancelAtPeriodEnd  *bool                             `form:"subscription_cancel_at_period_end"`
	SubscriptionItems              []*SubscriptionItemsParams        `form:"subscription_items"`
	SubscriptionPlan               *string                           `form:"subscription_plan"`
	SubscriptionProrate            *bool                             `form:"subscription_prorate"`
	SubscriptionProrationDate      *int64                            `form:"subscription_proration_date"`
	SubscriptionQuantity           *int64                            `form:"subscription_quantity"`
	SubscriptionTaxPercent         *float64                          `form:"subscription_tax_percent"`
	SubscriptionTrialEnd           *int64                            `form:"subscription_trial_end"`
	SubscriptionTrialFromPlan      *bool                             `form:"subscription_trial_from_plan"`
}

// InvoiceListParams is the set of parameters that can be used when listing invoices.
// For more details see https://stripe.com/docs/api#list_customer_invoices.
type InvoiceListParams struct {
	ListParams   `form:"*"`
	Billing      *string           `form:"billing"`
	Customer     *string           `form:"customer"`
	Date         *int64            `form:"date"`
	DateRange    *RangeQueryParams `form:"date"`
	DueDate      *int64            `form:"due_date"`
	Subscription *string           `form:"subscription"`
}

// InvoiceLineListParams is the set of parameters that can be used when listing invoice line items.
// For more details see https://stripe.com/docs/api#invoice_lines.
type InvoiceLineListParams struct {
	ListParams `form:"*"`

	Customer *string `form:"customer"`

	// ID is the invoice ID to list invoice lines for.
	ID *string `form:"-"` // Goes in the URL

	Subscription *string `form:"subscription"`
}

// InvoiceFinalizeParams is the set of parameters that can be used when finalizing invoices.
type InvoiceFinalizeParams struct {
	Params      `form:"*"`
	AutoAdvance *bool `form:"auto_advance"`
}

// InvoiceMarkUncollectibleParams is the set of parameters that can be used when marking
// invoices as uncollectible.
type InvoiceMarkUncollectibleParams struct {
	Params `form:"*"`
}

// InvoicePayParams is the set of parameters that can be used when
// paying invoices. For more details, see:
// https://stripe.com/docs/api#pay_invoice.
type InvoicePayParams struct {
	Params        `form:"*"`
	Forgive       *bool   `form:"forgive"`
	PaidOutOfBand *bool   `form:"paid_out_of_band"`
	Source        *string `form:"source"`
}

// InvoiceSendParams is the set of parameters that can be used when sending invoices.
type InvoiceSendParams struct {
	Params `form:"*"`
}

// InvoiceVoidParams is the set of parameters that can be used when voiding invoices.
type InvoiceVoidParams struct {
	Params `form:"*"`
}

// Invoice is the resource representing a Stripe invoice.
// For more details see https://stripe.com/docs/api#invoice_object.
type Invoice struct {
	AmountDue                 int64                `json:"amount_due"`
	AmountPaid                int64                `json:"amount_paid"`
	AmountRemaining           int64                `json:"amount_remaining"`
	ApplicationFee            int64                `json:"application_fee"`
	AttemptCount              int64                `json:"attempt_count"`
	Attempted                 bool                 `json:"attempted"`
	AutoAdvance               bool                 `json:"auto_advance"`
	Billing                   InvoiceBilling       `json:"billing"`
	BillingReason             InvoiceBillingReason `json:"billing_reason"`
	Charge                    *Charge              `json:"charge"`
	Currency                  Currency             `json:"currency"`
	Customer                  *Customer            `json:"customer"`
	Date                      int64                `json:"date"`
	DefaultSource             *PaymentSource       `json:"default_source"`
	Description               string               `json:"description"`
	Discount                  *Discount            `json:"discount"`
	DueDate                   int64                `json:"due_date"`
	EndingBalance             int64                `json:"ending_balance"`
	FinalizedAt               int64                `json:"finalized_at"`
	HostedInvoiceURL          string               `json:"hosted_invoice_url"`
	ID                        string               `json:"id"`
	InvoicePDF                string               `json:"invoice_pdf"`
	Lines                     *InvoiceLineList     `json:"lines"`
	Livemode                  bool                 `json:"livemode"`
	Metadata                  map[string]string    `json:"metadata"`
	NextPaymentAttempt        int64                `json:"next_payment_attempt"`
	Number                    string               `json:"number"`
	Paid                      bool                 `json:"paid"`
	PeriodEnd                 int64                `json:"period_end"`
	PeriodStart               int64                `json:"period_start"`
	ReceiptNumber             string               `json:"receipt_number"`
	StartingBalance           int64                `json:"starting_balance"`
	StatementDescriptor       string               `json:"statement_descriptor"`
	Status                    InvoiceBillingStatus `json:"status"`
	Subscription              string               `json:"subscription"`
	SubscriptionProrationDate int64                `json:"subscription_proration_date"`
	Subtotal                  int64                `json:"subtotal"`
	Tax                       int64                `json:"tax"`
	TaxPercent                float64              `json:"tax_percent"`
	Total                     int64                `json:"total"`
	WebhooksDeliveredAt       int64                `json:"webhooks_delivered_at"`
}

// InvoiceList is a list of invoices as retrieved from a list endpoint.
type InvoiceList struct {
	ListMeta
	Data []*Invoice `json:"data"`
}

// InvoiceLine is the resource representing a Stripe invoice line item.
// For more details see https://stripe.com/docs/api#invoice_line_item_object.
type InvoiceLine struct {
	Amount           int64             `json:"amount"`
	Currency         Currency          `json:"currency"`
	Description      string            `json:"description"`
	Discountable     bool              `json:"discountable"`
	ID               string            `json:"id"`
	Livemode         bool              `json:"live_mode"`
	Metadata         map[string]string `json:"metadata"`
	Period           *Period           `json:"period"`
	Plan             *Plan             `json:"plan"`
	Proration        bool              `json:"proration"`
	Quantity         int64             `json:"quantity"`
	Subscription     string            `json:"subscription"`
	SubscriptionItem string            `json:"subscription_item"`
	Type             InvoiceLineType   `json:"type"`
}

// Period is a structure representing a start and end dates.
type Period struct {
	End   int64 `json:"end"`
	Start int64 `json:"start"`
}

// InvoiceLineList is a list object for invoice line items.
type InvoiceLineList struct {
	ListMeta
	Data []*InvoiceLine `json:"data"`
}

// UnmarshalJSON handles deserialization of an Invoice.
// This custom unmarshaling is needed because the resulting
// property may be an id or the full struct if it was expanded.
func (i *Invoice) UnmarshalJSON(data []byte) error {
	if id, ok := ParseID(data); ok {
		i.ID = id
		return nil
	}

	type invoice Invoice
	var v invoice
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}

	*i = Invoice(v)
	return nil
}
<commit_msg>Add support for new `invoice_items[*]` params on the Upcoming Invoice API<commit_after>package stripe

import "encoding/json"

// InvoiceLineType is the list of allowed values for the invoice line's type.
type InvoiceLineType string

// List of values that InvoiceLineType can take.
const (
	InvoiceLineTypeInvoiceItem  InvoiceLineType = "invoiceitem"
	InvoiceLineTypeSubscription InvoiceLineType = "subscription"
)

// InvoiceBilling is the type of billing method for this invoice.
type InvoiceBilling string

// List of values that InvoiceBilling can take.
const (
	InvoiceBillingChargeAutomatically InvoiceBilling = "charge_automatically"
	InvoiceBillingSendInvoice         InvoiceBilling = "send_invoice"
)

// InvoiceBillingReason is the reason why a given invoice was created
type InvoiceBillingReason string

// List of values that InvoiceBillingReason can take.
const (
	InvoiceBillingReasonManual             InvoiceBillingReason = "manual"
	InvoiceBillingReasonSubscription       InvoiceBillingReason = "subscription"
	InvoiceBillingReasonSubscriptionCreate InvoiceBillingReason = "subscription_create"
	InvoiceBillingReasonSubscriptionCycle  InvoiceBillingReason = "subscription_cycle"
	InvoiceBillingReasonSubscriptionUpdate InvoiceBillingReason = "subscription_update"
	InvoiceBillingReasonUpcoming           InvoiceBillingReason = "upcoming"
)

// InvoiceBillingStatus is the reason why a given invoice was created
type InvoiceBillingStatus string

// List of values that InvoiceBillingStatus can take.
const (
	InvoiceBillingStatusDraft         InvoiceBillingStatus = "draft"
	InvoiceBillingStatusOpen          InvoiceBillingStatus = "open"
	InvoiceBillingStatusPaid          InvoiceBillingStatus = "paid"
	InvoiceBillingStatusUncollectible InvoiceBillingStatus = "uncollectible"
	InvoiceBillingStatusVoid          InvoiceBillingStatus = "void"
)

// InvoiceUpcomingInvoiceItemPeriodParams represents the period associated with that invoice item
type InvoiceUpcomingInvoiceItemPeriodParams struct {
	End   *int64 `form:"end"`
	Start *int64 `form:"start"`
}

// InvoiceUpcomingInvoiceItemParams is the set of parameters that can be used when adding or modifying
// invoice items on an upcoming invoice.
// For more details see https://stripe.com/docs/api#upcoming_invoice-invoice_items.
type InvoiceUpcomingInvoiceItemParams struct {
	Amount       *int64                                  `form:"amount"`
	Currency     *string                                 `form:"currency"`
	Description  *string                                 `form:"description"`
	Discountable *bool                                   `form:"discountable"`
	InvoiceItem  *string                                 `form:"invoiceitem"`
	Period       *InvoiceUpcomingInvoiceItemPeriodParams `form:"period"`
	Quantity     *int64                                  `form:"quantity"`
	UnitAmount   *int64                                  `form:"unit_amount"`
}

// InvoiceParams is the set of parameters that can be used when creating or updating an invoice.
// For more details see https://stripe.com/docs/api#create_invoice, https://stripe.com/docs/api#update_invoice.
type InvoiceParams struct {
	Params              `form:"*"`
	AutoAdvance         *bool    `form:"auto_advance"`
	ApplicationFee      *int64   `form:"application_fee"`
	Billing             *string  `form:"billing"`
	Customer            *string  `form:"customer"`
	DaysUntilDue        *int64   `form:"days_until_due"`
	DefaultSource       *string  `form:"default_source"`
	Description         *string  `form:"description"`
	DueDate             *int64   `form:"due_date"`
	Paid                *bool    `form:"paid"`
	StatementDescriptor *string  `form:"statement_descriptor"`
	Subscription        *string  `form:"subscription"`
	TaxPercent          *float64 `form:"tax_percent"`

	// These are all for exclusive use by GetNext.

	Coupon                         *string                           `form:"coupon"`
	InvoiceItems                   *InvoiceUpcomingInvoiceItemParams `form:"invoice_items"`
	SubscriptionBillingCycleAnchor *int64                            `form:"subscription_billing_cycle_anchor"`
	SubscriptionCancelAtPeriodEnd  *bool                             `form:"subscription_cancel_at_period_end"`
	SubscriptionItems              []*SubscriptionItemsParams        `form:"subscription_items"`
	SubscriptionPlan               *string                           `form:"subscription_plan"`
	SubscriptionProrate            *bool                             `form:"subscription_prorate"`
	SubscriptionProrationDate      *int64                            `form:"subscription_proration_date"`
	SubscriptionQuantity           *int64                            `form:"subscription_quantity"`
	SubscriptionTaxPercent         *float64                          `form:"subscription_tax_percent"`
	SubscriptionTrialEnd           *int64                            `form:"subscription_trial_end"`
	SubscriptionTrialFromPlan      *bool                             `form:"subscription_trial_from_plan"`
}

// InvoiceListParams is the set of parameters that can be used when listing invoices.
// For more details see https://stripe.com/docs/api#list_customer_invoices.
type InvoiceListParams struct {
	ListParams   `form:"*"`
	Billing      *string           `form:"billing"`
	Customer     *string           `form:"customer"`
	Date         *int64            `form:"date"`
	DateRange    *RangeQueryParams `form:"date"`
	DueDate      *int64            `form:"due_date"`
	Subscription *string           `form:"subscription"`
}

// InvoiceLineListParams is the set of parameters that can be used when listing invoice line items.
// For more details see https://stripe.com/docs/api#invoice_lines.
type InvoiceLineListParams struct {
	ListParams `form:"*"`

	Customer *string `form:"customer"`

	// ID is the invoice ID to list invoice lines for.
	ID *string `form:"-"` // Goes in the URL

	Subscription *string `form:"subscription"`
}

// InvoiceFinalizeParams is the set of parameters that can be used when finalizing invoices.
type InvoiceFinalizeParams struct {
	Params      `form:"*"`
	AutoAdvance *bool `form:"auto_advance"`
}

// InvoiceMarkUncollectibleParams is the set of parameters that can be used when marking
// invoices as uncollectible.
type InvoiceMarkUncollectibleParams struct {
	Params `form:"*"`
}

// InvoicePayParams is the set of parameters that can be used when
// paying invoices. For more details, see:
// https://stripe.com/docs/api#pay_invoice.
type InvoicePayParams struct {
	Params        `form:"*"`
	Forgive       *bool   `form:"forgive"`
	PaidOutOfBand *bool   `form:"paid_out_of_band"`
	Source        *string `form:"source"`
}

// InvoiceSendParams is the set of parameters that can be used when sending invoices.
type InvoiceSendParams struct {
	Params `form:"*"`
}

// InvoiceVoidParams is the set of parameters that can be used when voiding invoices.
type InvoiceVoidParams struct {
	Params `form:"*"`
}

// Invoice is the resource representing a Stripe invoice.
// For more details see https://stripe.com/docs/api#invoice_object.
type Invoice struct {
	AmountDue                 int64                `json:"amount_due"`
	AmountPaid                int64                `json:"amount_paid"`
	AmountRemaining           int64                `json:"amount_remaining"`
	ApplicationFee            int64                `json:"application_fee"`
	AttemptCount              int64                `json:"attempt_count"`
	Attempted                 bool                 `json:"attempted"`
	AutoAdvance               bool                 `json:"auto_advance"`
	Billing                   InvoiceBilling       `json:"billing"`
	BillingReason             InvoiceBillingReason `json:"billing_reason"`
	Charge                    *Charge              `json:"charge"`
	Currency                  Currency             `json:"currency"`
	Customer                  *Customer            `json:"customer"`
	Date                      int64                `json:"date"`
	DefaultSource             *PaymentSource       `json:"default_source"`
	Description               string               `json:"description"`
	Discount                  *Discount            `json:"discount"`
	DueDate                   int64                `json:"due_date"`
	EndingBalance             int64                `json:"ending_balance"`
	FinalizedAt               int64                `json:"finalized_at"`
	HostedInvoiceURL          string               `json:"hosted_invoice_url"`
	ID                        string               `json:"id"`
	InvoicePDF                string               `json:"invoice_pdf"`
	Lines                     *InvoiceLineList     `json:"lines"`
	Livemode                  bool                 `json:"livemode"`
	Metadata                  map[string]string    `json:"metadata"`
	NextPaymentAttempt        int64                `json:"next_payment_attempt"`
	Number                    string               `json:"number"`
	Paid                      bool                 `json:"paid"`
	PeriodEnd                 int64                `json:"period_end"`
	PeriodStart               int64                `json:"period_start"`
	ReceiptNumber             string               `json:"receipt_number"`
	StartingBalance           int64                `json:"starting_balance"`
	StatementDescriptor       string               `json:"statement_descriptor"`
	Status                    InvoiceBillingStatus `json:"status"`
	Subscription              string               `json:"subscription"`
	SubscriptionProrationDate int64                `json:"subscription_proration_date"`
	Subtotal                  int64                `json:"subtotal"`
	Tax                       int64                `json:"tax"`
	TaxPercent                float64              `json:"tax_percent"`
	Total                     int64                `json:"total"`
	WebhooksDeliveredAt       int64                `json:"webhooks_delivered_at"`
}

// InvoiceList is a list of invoices as retrieved from a list endpoint.
type InvoiceList struct {
	ListMeta
	Data []*Invoice `json:"data"`
}

// InvoiceLine is the resource representing a Stripe invoice line item.
// For more details see https://stripe.com/docs/api#invoice_line_item_object.
type InvoiceLine struct {
	Amount           int64             `json:"amount"`
	Currency         Currency          `json:"currency"`
	Description      string            `json:"description"`
	Discountable     bool              `json:"discountable"`
	ID               string            `json:"id"`
	Livemode         bool              `json:"live_mode"`
	Metadata         map[string]string `json:"metadata"`
	Period           *Period           `json:"period"`
	Plan             *Plan             `json:"plan"`
	Proration        bool              `json:"proration"`
	Quantity         int64             `json:"quantity"`
	Subscription     string            `json:"subscription"`
	SubscriptionItem string            `json:"subscription_item"`
	Type             InvoiceLineType   `json:"type"`
}

// Period is a structure representing a start and end dates.
type Period struct {
	End   int64 `json:"end"`
	Start int64 `json:"start"`
}

// InvoiceLineList is a list object for invoice line items.
type InvoiceLineList struct {
	ListMeta
	Data []*InvoiceLine `json:"data"`
}

// UnmarshalJSON handles deserialization of an Invoice.
// This custom unmarshaling is needed because the resulting
// property may be an id or the full struct if it was expanded.
func (i *Invoice) UnmarshalJSON(data []byte) error {
	if id, ok := ParseID(data); ok {
		i.ID = id
		return nil
	}

	type invoice Invoice
	var v invoice
	if err := json.Unmarshal(data, &v); err != nil {
		return err
	}

	*i = Invoice(v)
	return nil
}
<|endoftext|>


<commit_before>package vagrant

import (
	"fmt"
	"github.com/mitchellh/mapstructure"
	"github.com/mitchellh/packer/packer"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"text/template"
)

type VBoxBoxConfig struct {
	OutputPath          string `mapstructure:"output"`
	VagrantfileTemplate string `mapstructure:"vagrantfile_template"`
}

type VBoxVagrantfileTemplate struct {
	BaseMacAddress string
}

type VBoxBoxPostProcessor struct {
	config VBoxBoxConfig
}

func (p *VBoxBoxPostProcessor) Configure(raw interface{}) error {
	err := mapstructure.Decode(raw, &p.config)
	if err != nil {
		return err
	}

	return nil
}

func (p *VBoxBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, error) {
	// TODO(mitchellh): Actually parse the base mac address
	tplData := &VBoxVagrantfileTemplate{}

	// Compile the output path
	outputPath, err := ProcessOutputPath(p.config.OutputPath, "aws", artifact)
	if err != nil {
		return nil, err
	}

	// Create a temporary directory for us to build the contents of the box in
	dir, err := ioutil.TempDir("", "packer")
	if err != nil {
		return nil, err
	}
	defer os.RemoveAll(dir)

	// Copy all of the original contents into the temporary directory
	for _, path := range artifact.Files() {
		ui.Message(fmt.Sprintf("Copying: %s", path))
		src, err := os.Open(path)
		if err != nil {
			return nil, err
		}
		defer src.Close()

		dst, err := os.Create(filepath.Join(dir, filepath.Base(path)))
		if err != nil {
			return nil, err
		}
		defer dst.Close()

		if _, err := io.Copy(dst, src); err != nil {
			return nil, err
		}
	}

	// Create the Vagrantfile from the template
	vf, err := os.Create(filepath.Join(dir, "Vagrantfile"))
	if err != nil {
		return nil, err
	}
	defer vf.Close()

	vagrantfileContents := defaultVBoxVagrantfile
	if p.config.VagrantfileTemplate != "" {
		f, err := os.Open(p.config.VagrantfileTemplate)
		if err != nil {
			return nil, err
		}
		defer f.Close()

		contents, err := ioutil.ReadAll(f)
		if err != nil {
			return nil, err
		}

		vagrantfileContents = string(contents)
	}

	t := template.Must(template.New("vagrantfile").Parse(vagrantfileContents))
	t.Execute(vf, tplData)
	vf.Close()

	// Create the metadata
	metadata := map[string]string{"provider": "virtualbox"}
	if err := WriteMetadata(dir, metadata); err != nil {
		return nil, err
	}

	// Compress the directory to the given output path
	ui.Message(fmt.Sprintf("Compressing box..."))
	if err := DirToBox(outputPath, dir); err != nil {
		return nil, err
	}

	return NewArtifact("virtualbox", outputPath), nil
}

var defaultVBoxVagrantfile = `
Vagrant.configure("2") do |config|
  config.vm.provider "virtualbox" do |vb|
    # TODO
  end
end
`
<commit_msg>post-processor/vagrant: virtualbox box provider should be "virtualbox"<commit_after>package vagrant

import (
	"fmt"
	"github.com/mitchellh/mapstructure"
	"github.com/mitchellh/packer/packer"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"text/template"
)

type VBoxBoxConfig struct {
	OutputPath          string `mapstructure:"output"`
	VagrantfileTemplate string `mapstructure:"vagrantfile_template"`
}

type VBoxVagrantfileTemplate struct {
	BaseMacAddress string
}

type VBoxBoxPostProcessor struct {
	config VBoxBoxConfig
}

func (p *VBoxBoxPostProcessor) Configure(raw interface{}) error {
	err := mapstructure.Decode(raw, &p.config)
	if err != nil {
		return err
	}

	return nil
}

func (p *VBoxBoxPostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, error) {
	// TODO(mitchellh): Actually parse the base mac address
	tplData := &VBoxVagrantfileTemplate{}

	// Compile the output path
	outputPath, err := ProcessOutputPath(p.config.OutputPath, "virtualbox", artifact)
	if err != nil {
		return nil, err
	}

	// Create a temporary directory for us to build the contents of the box in
	dir, err := ioutil.TempDir("", "packer")
	if err != nil {
		return nil, err
	}
	defer os.RemoveAll(dir)

	// Copy all of the original contents into the temporary directory
	for _, path := range artifact.Files() {
		ui.Message(fmt.Sprintf("Copying: %s", path))
		src, err := os.Open(path)
		if err != nil {
			return nil, err
		}
		defer src.Close()

		dst, err := os.Create(filepath.Join(dir, filepath.Base(path)))
		if err != nil {
			return nil, err
		}
		defer dst.Close()

		if _, err := io.Copy(dst, src); err != nil {
			return nil, err
		}
	}

	// Create the Vagrantfile from the template
	vf, err := os.Create(filepath.Join(dir, "Vagrantfile"))
	if err != nil {
		return nil, err
	}
	defer vf.Close()

	vagrantfileContents := defaultVBoxVagrantfile
	if p.config.VagrantfileTemplate != "" {
		f, err := os.Open(p.config.VagrantfileTemplate)
		if err != nil {
			return nil, err
		}
		defer f.Close()

		contents, err := ioutil.ReadAll(f)
		if err != nil {
			return nil, err
		}

		vagrantfileContents = string(contents)
	}

	t := template.Must(template.New("vagrantfile").Parse(vagrantfileContents))
	t.Execute(vf, tplData)
	vf.Close()

	// Create the metadata
	metadata := map[string]string{"provider": "virtualbox"}
	if err := WriteMetadata(dir, metadata); err != nil {
		return nil, err
	}

	// Compress the directory to the given output path
	ui.Message(fmt.Sprintf("Compressing box..."))
	if err := DirToBox(outputPath, dir); err != nil {
		return nil, err
	}

	return NewArtifact("virtualbox", outputPath), nil
}

var defaultVBoxVagrantfile = `
Vagrant.configure("2") do |config|
  config.vm.provider "virtualbox" do |vb|
    # TODO
  end
end
`
<|endoftext|>


<commit_before>// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package btcwire

import (
	"fmt"
	"io"
)

const (
	// MaxInvPerMsg is the maximum number of inventory vectors that can be in a
	// single bitcoin inv message.
	MaxInvPerMsg = 50000

	// Maximum payload size for an inventory vector.
	maxInvVectPayload = 4 + HashSize
)

// InvType represents the allowed types of inventory vectors.  See InvVect.
type InvType uint32

const (
	InvVect_Error InvType = 0
	InvVect_Tx    InvType = 1
	InvVect_Block InvType = 2
)

// Map of service flags back to their constant names for pretty printing.
var ivStrings = map[InvType]string{
	InvVect_Error: "ERROR",
	InvVect_Tx:    "MSG_TX",
	InvVect_Block: "MSG_BLOCK",
}

// String returns the InvType in human-readable form.
func (invtype InvType) String() string {
	if s, ok := ivStrings[invtype]; ok {
		return s
	}

	return fmt.Sprintf("Unknown InvType (%d)", uint32(invtype))
}

// InvVect defines a bitcoin inventory vector which is used to describe data,
// as specified by the Type field, that a peer wants, has, or does not have to
// another peer.
type InvVect struct {
	Type InvType // Type of data
	Hash ShaHash // Hash of the data
}

// NewInvVect returns a new InvVect using the provided type and hash.
func NewInvVect(typ InvType, hash *ShaHash) *InvVect {
	return &InvVect{
		Type: typ,
		Hash: *hash,
	}
}

// readInvVect reads an encoded InvVect from r depending on the protocol
// version.
func readInvVect(r io.Reader, pver uint32, iv *InvVect) error {
	err := readElements(r, &iv.Type, &iv.Hash)
	if err != nil {
		return err
	}
	return nil
}

// writeInvVect serializes an InvVect to w depending on the protocol version.
func writeInvVect(w io.Writer, pver uint32, iv *InvVect) error {
	err := writeElements(w, iv.Type, iv.Hash)
	if err != nil {
		return err
	}
	return nil
}
<commit_msg>Comment inventory vector constants.<commit_after>// Copyright (c) 2013 Conformal Systems LLC.
// Use of this source code is governed by an ISC
// license that can be found in the LICENSE file.

package btcwire

import (
	"fmt"
	"io"
)

const (
	// MaxInvPerMsg is the maximum number of inventory vectors that can be in a
	// single bitcoin inv message.
	MaxInvPerMsg = 50000

	// Maximum payload size for an inventory vector.
	maxInvVectPayload = 4 + HashSize
)

// InvType represents the allowed types of inventory vectors.  See InvVect.
type InvType uint32

// These constants define the various supported inventory vector types.
const (
	InvVect_Error InvType = 0
	InvVect_Tx    InvType = 1
	InvVect_Block InvType = 2
)

// Map of service flags back to their constant names for pretty printing.
var ivStrings = map[InvType]string{
	InvVect_Error: "ERROR",
	InvVect_Tx:    "MSG_TX",
	InvVect_Block: "MSG_BLOCK",
}

// String returns the InvType in human-readable form.
func (invtype InvType) String() string {
	if s, ok := ivStrings[invtype]; ok {
		return s
	}

	return fmt.Sprintf("Unknown InvType (%d)", uint32(invtype))
}

// InvVect defines a bitcoin inventory vector which is used to describe data,
// as specified by the Type field, that a peer wants, has, or does not have to
// another peer.
type InvVect struct {
	Type InvType // Type of data
	Hash ShaHash // Hash of the data
}

// NewInvVect returns a new InvVect using the provided type and hash.
func NewInvVect(typ InvType, hash *ShaHash) *InvVect {
	return &InvVect{
		Type: typ,
		Hash: *hash,
	}
}

// readInvVect reads an encoded InvVect from r depending on the protocol
// version.
func readInvVect(r io.Reader, pver uint32, iv *InvVect) error {
	err := readElements(r, &iv.Type, &iv.Hash)
	if err != nil {
		return err
	}
	return nil
}

// writeInvVect serializes an InvVect to w depending on the protocol version.
func writeInvVect(w io.Writer, pver uint32, iv *InvVect) error {
	err := writeElements(w, iv.Type, iv.Hash)
	if err != nil {
		return err
	}
	return nil
}
<|endoftext|>


<commit_before>package ipc

import (
	"encoding/json"
	"errors"
	"net"
	"syscall"

	"fmt"
	"github.com/op/go-logging"
	"io"
	"reflect"
)

const maxFdCount = 3

type MsgConn struct {
	log      *logging.Logger
	conn     *net.UnixConn
	buf      [1024]byte
	oob      []byte
	disp     *msgDispatcher
	factory  MsgFactory
	isClosed bool
	idGen    <-chan int
	respMan  *responseManager
	onClose  func()
}

type MsgServer struct {
	disp     *msgDispatcher
	factory  MsgFactory
	listener *net.UnixListener
	done     chan bool
	idGen    <-chan int
}

func NewServer(address string, factory MsgFactory, log *logging.Logger, handlers ...interface{}) (*MsgServer, error) {
	md, err := createDispatcher(log, handlers...)
	if err != nil {
		return nil, err
	}

	listener, err := net.ListenUnix("unix", &net.UnixAddr{address, "unix"})
	if err != nil {
		md.close()
		return nil, err
	}
	if err := setPassCred(listener); err != nil {
		return nil, errors.New("Failed to set SO_PASSCRED on listening socket: " + err.Error())
	}
	done := make(chan bool)
	idGen := newIdGen(done)
	return &MsgServer{
		disp:     md,
		factory:  factory,
		listener: listener,
		done:     done,
		idGen:    idGen,
	}, nil
}

func (s *MsgServer) Run() error {
	for {
		conn, err := s.listener.AcceptUnix()
		if err != nil {
			return err
		}
		if err := setPassCred(conn); err != nil {
			return errors.New("Failed to set SO_PASSCRED on accepted socket connection:" + err.Error())
		}
		mc := &MsgConn{
			conn:    conn,
			disp:    s.disp,
			oob:     createOobBuffer(),
			factory: s.factory,
			idGen:   s.idGen,
			respMan: newResponseManager(),
		}
		go mc.readLoop()
	}
	return nil
}

func (s *MsgServer) Close() error {
	s.disp.close()
	close(s.done)
	return s.listener.Close()
}

func Connect(address string, factory MsgFactory, log *logging.Logger, handlers ...interface{}) (*MsgConn, error) {
	md, err := createDispatcher(log, handlers...)
	if err != nil {
		return nil, err
	}
	conn, err := net.DialUnix("unix", nil, &net.UnixAddr{address, "unix"})
	if err != nil {
		return nil, err
	}
	done := make(chan bool)
	idGen := newIdGen(done)
	mc := &MsgConn{
		conn:    conn,
		disp:    md,
		oob:     createOobBuffer(),
		factory: factory,
		idGen:   idGen,
		respMan: newResponseManager(),
		onClose: func() {
			md.close()
			close(done)
		},
	}
	go mc.readLoop()
	return mc, nil
}

func newIdGen(done <-chan bool) <-chan int {
	ch := make(chan int)
	go idGenLoop(done, ch)
	return ch
}

func idGenLoop(done <-chan bool, out chan<- int) {
	current := int(1)
	for {
		select {
		case out <- current:
			current += 1
		case <-done:
			return
		}
	}
}

func (mc *MsgConn) readLoop() {
	for {
		if mc.processOneMessage() {
			return
		}
	}
}

func (mc *MsgConn) logger() *logging.Logger {
	if mc.log != nil {
		return mc.log
	}
	return defaultLog
}

func (mc *MsgConn) processOneMessage() bool {
	m, err := mc.readMessage()
	if err != nil {
		if err == io.EOF {
			mc.Close()
			return true
		}
		if !mc.isClosed {
			mc.logger().Warning("error on MsgConn.readMessage(): %v", err)
		}
		return true
	}
	if !mc.respMan.handle(m) {
		mc.disp.dispatch(m)
	}
	return false
}

func (mc *MsgConn) Close() error {
	mc.isClosed = true
	if mc.onClose != nil {
		mc.onClose()
	}
	return mc.conn.Close()
}

func createOobBuffer() []byte {
	oobSize := syscall.CmsgSpace(syscall.SizeofUcred) + syscall.CmsgSpace(4*maxFdCount)
	return make([]byte, oobSize)
}

func (mc *MsgConn) readMessage() (*Message, error) {
	n, oobn, _, _, err := mc.conn.ReadMsgUnix(mc.buf[:], mc.oob)
	if err != nil {
		return nil, err
	}
	m, err := mc.parseMessage(mc.buf[:n])
	if err != nil {
		return nil, err
	}
	m.mconn = mc

	if oobn > 0 {
		err := m.parseControlData(mc.oob[:oobn])
		if err != nil {
		}
	}
	return m, nil
}

// AddHandlers registers a list of message handling functions with a MsgConn instance.
// Each handler function must have two arguments and return a single error value.  The
// first argument must be pointer to a message structure type.  A message structure type
// is a structure that must have a struct tag on the first field:
//
//    type FooMsg struct {
//        Stuff string  "Foo"   // <------ struct tag
//        // etc...
//    }
//
//    type SimpleMsg struct {
//        dummy int "Simple"   // struct has no fields, so add an unexported dummy field just for the tag
//    }
//
// The second argument to a handler function must have type *ipc.Message.  After a handler function
// has been registered, received messages matching the first argument will be dispatched to the corresponding
// handler function.
//
//     func fooHandler(foo *FooMsg, msg *ipc.Message) error { /* ... */ }
//     func simpleHandler(simple *SimpleMsg, msg *ipc.Message) error { /* ... */ }
//
//     /* register fooHandler() to handle incoming FooMsg and SimpleHandler to handle SimpleMsg */
//     conn.AddHandlers(fooHandler, simpleHandler)
//

func (mc *MsgConn) AddHandlers(args ...interface{}) error {
	for len(args) > 0 {
		if err := mc.disp.hmap.addHandler(args[0]); err != nil {
			return err
		}
		args = args[1:]
	}
	return nil
}

func (mc *MsgConn) SendMsg(msg interface{}, fds ...int) error {
	return mc.sendMessage(msg, <-mc.idGen, fds...)
}

func (mc *MsgConn) ExchangeMsg(msg interface{}, fds ...int) (ResponseReader, error) {
	id := <-mc.idGen
	rr := mc.respMan.register(id)

	if err := mc.sendMessage(msg, id, fds...); err != nil {
		rr.Done()
		return nil, err
	}
	return rr, nil
}

func (mc *MsgConn) sendMessage(msg interface{}, msgID int, fds ...int) error {
	msgType, err := getMessageType(msg)
	if err != nil {
		return err
	}
	base, err := mc.newBaseMessage(msgType, msgID, msg)
	if err != nil {
		return err
	}
	raw, err := json.Marshal(base)
	if err != nil {
		return err
	}
	return mc.sendRaw(raw, fds...)
}

func getMessageType(msg interface{}) (string, error) {
	t := reflect.TypeOf(msg)
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}
	if t.Kind() != reflect.Struct {
		return "", fmt.Errorf("sendMessage() msg (%T) is not a struct", msg)
	}
	if t.NumField() == 0 || len(t.Field(0).Tag) == 0 {
		return "", fmt.Errorf("sendMessage() msg struct (%T) does not have tag on first field")
	}
	return string(t.Field(0).Tag), nil
}

func (mc *MsgConn) newBaseMessage(msgType string, msgID int, body interface{}) (*BaseMsg, error) {
	bodyBytes, err := json.Marshal(body)
	if err != nil {
		return nil, err
	}
	base := new(BaseMsg)
	base.Type = msgType
	base.MsgID = msgID
	base.Body = bodyBytes
	return base, nil
}

func (mc *MsgConn) sendRaw(data []byte, fds ...int) error {
	if len(fds) > 0 {
		return mc.sendWithFds(data, fds)
	}
	_, err := mc.conn.Write(data)
	return err
}

func (mc *MsgConn) sendWithFds(data []byte, fds []int) error {
	oob := syscall.UnixRights(fds...)
	_, _, err := mc.conn.WriteMsgUnix(data, oob, nil)
	return err
}
<commit_msg>delimit each message with a length field<commit_after>package ipc

import (
	"encoding/json"
	"errors"
	"net"
	"syscall"

	"encoding/binary"
	"fmt"
	"github.com/op/go-logging"
	"io"
	"reflect"
)

const maxFdCount = 3
const maxMessageSz = 128 * 1024
const bufferSz = 1024

type MsgConn struct {
	log      *logging.Logger
	conn     *net.UnixConn
	buf      []byte
	oob      []byte
	disp     *msgDispatcher
	factory  MsgFactory
	isClosed bool
	idGen    <-chan int
	respMan  *responseManager
	onClose  func()
}

type MsgServer struct {
	log      *logging.Logger
	disp     *msgDispatcher
	factory  MsgFactory
	listener *net.UnixListener
	done     chan bool
	idGen    <-chan int
}

func NewServer(address string, factory MsgFactory, log *logging.Logger, handlers ...interface{}) (*MsgServer, error) {
	md, err := createDispatcher(log, handlers...)
	if err != nil {
		return nil, err
	}

	listener, err := net.ListenUnix("unix", &net.UnixAddr{address, "unix"})
	if err != nil {
		md.close()
		return nil, err
	}
	if err := setPassCred(listener); err != nil {
		return nil, errors.New("Failed to set SO_PASSCRED on listening socket: " + err.Error())
	}
	done := make(chan bool)
	idGen := newIdGen(done)
	return &MsgServer{
		log:      log,
		disp:     md,
		factory:  factory,
		listener: listener,
		done:     done,
		idGen:    idGen,
	}, nil
}

func (s *MsgServer) Run() error {
	for {
		conn, err := s.listener.AcceptUnix()
		if err != nil {
			return err
		}
		if err := setPassCred(conn); err != nil {
			return errors.New("Failed to set SO_PASSCRED on accepted socket connection:" + err.Error())
		}
		mc := &MsgConn{
			log:     s.log,
			conn:    conn,
			disp:    s.disp,
			buf:     make([]byte, bufferSz),
			oob:     createOobBuffer(),
			factory: s.factory,
			idGen:   s.idGen,
			respMan: newResponseManager(),
		}
		go mc.readLoop()
	}
	return nil
}

func (s *MsgServer) Close() error {
	s.disp.close()
	close(s.done)
	return s.listener.Close()
}

func Connect(address string, factory MsgFactory, log *logging.Logger, handlers ...interface{}) (*MsgConn, error) {
	md, err := createDispatcher(log, handlers...)
	if err != nil {
		return nil, err
	}
	conn, err := net.DialUnix("unix", nil, &net.UnixAddr{address, "unix"})
	if err != nil {
		return nil, err
	}
	done := make(chan bool)
	idGen := newIdGen(done)
	mc := &MsgConn{
		log:     log,
		conn:    conn,
		disp:    md,
		oob:     createOobBuffer(),
		factory: factory,
		idGen:   idGen,
		respMan: newResponseManager(),
		onClose: func() {
			md.close()
			close(done)
		},
	}
	go mc.readLoop()
	return mc, nil
}

func newIdGen(done <-chan bool) <-chan int {
	ch := make(chan int)
	go idGenLoop(done, ch)
	return ch
}

func idGenLoop(done <-chan bool, out chan<- int) {
	current := int(1)
	for {
		select {
		case out <- current:
			current += 1
		case <-done:
			return
		}
	}
}

func (mc *MsgConn) readLoop() {
	for {
		if mc.processOneMessage() {
			return
		}
	}
}

func (mc *MsgConn) logger() *logging.Logger {
	if mc.log != nil {
		return mc.log
	}
	return defaultLog
}

func (mc *MsgConn) processOneMessage() bool {
	m, err := mc.readMessage()
	if err != nil {
		if err == io.EOF {
			mc.Close()
			return true
		}
		if !mc.isClosed {
			mc.logger().Warning("error on MsgConn.readMessage(): %v", err)
		}
		return true
	}
	if !mc.respMan.handle(m) {
		mc.disp.dispatch(m)
	}
	return false
}

func (mc *MsgConn) Close() error {
	mc.isClosed = true
	if mc.onClose != nil {
		mc.onClose()
	}
	return mc.conn.Close()
}

func createOobBuffer() []byte {
	oobSize := syscall.CmsgSpace(syscall.SizeofUcred) + syscall.CmsgSpace(4*maxFdCount)
	return make([]byte, oobSize)
}

func (mc *MsgConn) readMessage() (*Message, error) {
	var szbuf [4]byte
	n, oobn, _, _, err := mc.conn.ReadMsgUnix(szbuf[:], mc.oob)
	if err != nil {
		return nil, err
	}
	sz := binary.BigEndian.Uint32(szbuf[:])
	if sz > maxMessageSz {
		return nil, fmt.Errorf("message size of (%d) exceeds maximum message size (%d)", sz, maxMessageSz)
	}
	if sz > uint32(len(mc.buf)) {
		mc.buf = make([]byte, sz)
	}
	n, _, _, _, err = mc.conn.ReadMsgUnix(mc.buf[:sz], nil)
	if err != nil {
		return nil, err
	}
	m, err := mc.parseMessage(mc.buf[:n])
	if err != nil {
		return nil, err
	}
	m.mconn = mc

	if oobn > 0 {
		err := m.parseControlData(mc.oob[:oobn])
		if err != nil {
		}
	}
	return m, nil
}

// AddHandlers registers a list of message handling functions with a MsgConn instance.
// Each handler function must have two arguments and return a single error value.  The
// first argument must be pointer to a message structure type.  A message structure type
// is a structure that must have a struct tag on the first field:
//
//    type FooMsg struct {
//        Stuff string  "Foo"   // <------ struct tag
//        // etc...
//    }
//
//    type SimpleMsg struct {
//        dummy int "Simple"   // struct has no fields, so add an unexported dummy field just for the tag
//    }
//
// The second argument to a handler function must have type *ipc.Message.  After a handler function
// has been registered, received messages matching the first argument will be dispatched to the corresponding
// handler function.
//
//     func fooHandler(foo *FooMsg, msg *ipc.Message) error { /* ... */ }
//     func simpleHandler(simple *SimpleMsg, msg *ipc.Message) error { /* ... */ }
//
//     /* register fooHandler() to handle incoming FooMsg and SimpleHandler to handle SimpleMsg */
//     conn.AddHandlers(fooHandler, simpleHandler)
//

func (mc *MsgConn) AddHandlers(args ...interface{}) error {
	for len(args) > 0 {
		if err := mc.disp.hmap.addHandler(args[0]); err != nil {
			return err
		}
		args = args[1:]
	}
	return nil
}

func (mc *MsgConn) SendMsg(msg interface{}, fds ...int) error {
	return mc.sendMessage(msg, <-mc.idGen, fds...)
}

func (mc *MsgConn) ExchangeMsg(msg interface{}, fds ...int) (ResponseReader, error) {
	id := <-mc.idGen
	rr := mc.respMan.register(id)

	if err := mc.sendMessage(msg, id, fds...); err != nil {
		rr.Done()
		return nil, err
	}
	return rr, nil
}

func (mc *MsgConn) sendMessage(msg interface{}, msgID int, fds ...int) error {
	msgType, err := getMessageType(msg)
	if err != nil {
		return err
	}
	base, err := mc.newBaseMessage(msgType, msgID, msg)
	if err != nil {
		return err
	}
	raw, err := json.Marshal(base)
	if err != nil {
		return err
	}
	buf := make([]byte, len(raw)+4)
	binary.BigEndian.PutUint32(buf, uint32(len(raw)))
	copy(buf[4:], raw)
	return mc.sendRaw(buf, fds...)
}

func getMessageType(msg interface{}) (string, error) {
	t := reflect.TypeOf(msg)
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}
	if t.Kind() != reflect.Struct {
		return "", fmt.Errorf("sendMessage() msg (%T) is not a struct", msg)
	}
	if t.NumField() == 0 || len(t.Field(0).Tag) == 0 {
		return "", fmt.Errorf("sendMessage() msg struct (%T) does not have tag on first field")
	}
	return string(t.Field(0).Tag), nil
}

func (mc *MsgConn) newBaseMessage(msgType string, msgID int, body interface{}) (*BaseMsg, error) {
	bodyBytes, err := json.Marshal(body)
	if err != nil {
		return nil, err
	}
	base := new(BaseMsg)
	base.Type = msgType
	base.MsgID = msgID
	base.Body = bodyBytes
	return base, nil
}

func (mc *MsgConn) sendRaw(data []byte, fds ...int) error {
	if len(fds) > 0 {
		return mc.sendWithFds(data, fds)
	}
	_, err := mc.conn.Write(data)
	return err
}

func (mc *MsgConn) sendWithFds(data []byte, fds []int) error {
	oob := syscall.UnixRights(fds...)
	_, _, err := mc.conn.WriteMsgUnix(data, oob, nil)
	return err
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"fmt"
	"os"
	"sync"
)

var cmdInspect = &Command{
	Exec:        runInspect,
	UsageLine:   "inspect [OPTIONS] IDENTIFIER [IDENTIFIER...]",
	Description: "Inspects a server, image or a bootscript.",
	Help:        "Inspects a server, image or a bootscript.",
}

type ScalewayResolvedIdentifier struct {
	// Identifiers holds matching identifiers
	Identifiers []ScalewayIdentifier

	// Needle is the criteria used to lookup identifiers
	Needle string
}

// resolveIdentifiers resolves needles provided by the user
func resolveIdentifiers(cmd *Command, needles []string, out chan ScalewayResolvedIdentifier) {
	// first attempt, only lookup from the cache
	var unresolved []string
	for _, needle := range needles {
		idents := cmd.API.Cache.LookUpIdentifiers(needle)
		if len(idents) == 0 {
			unresolved = append(unresolved, needle)
		} else {
			out <- ScalewayResolvedIdentifier{
				Identifiers: idents,
				Needle:      needle,
			}
		}
	}
	// fill the cache by fetching from the API and resolve missing identifiers
	if len(unresolved) > 0 {
		var wg sync.WaitGroup
		wg.Add(2)
		go func() {
			cmd.API.GetServers(true, 0)
			wg.Done()
		}()
		go func() {
			cmd.API.GetImages()
			wg.Done()
		}()
		wg.Wait()
		for _, needle := range unresolved {
			idents := cmd.API.Cache.LookUpIdentifiers(needle)
			out <- ScalewayResolvedIdentifier{
				Identifiers: idents,
				Needle:      needle,
			}
		}
	}
	close(out)
}

// inspectIdentifiers inspects identifiers concurrently
func inspectIdentifiers(cmd *Command, ci chan ScalewayResolvedIdentifier, cj chan interface{}) {
	var wg sync.WaitGroup
	for {
		idents, ok := <-ci
		if !ok {
			break
		}
		if len(idents.Identifiers) != 1 {
			if len(idents.Identifiers) == 0 {
				fmt.Fprintf(os.Stderr, "Unable to resolve identifier %s\n", idents.Needle)
			} else {
				fmt.Fprintf(os.Stderr, "Too many candidates for %s (%d)\n", idents.Needle, len(idents.Identifiers))
				for _, identifier := range idents.Identifiers {
					// FIXME: also print the name
					fmt.Fprintf(os.Stderr, "%s\n", identifier.Identifier)
				}
			}
		} else {
			ident := idents.Identifiers[0]
			wg.Add(1)
			go func() {
				if ident.Type == IDENTIFIER_SERVER {
					server, err := cmd.API.GetServer(ident.Identifier)
					if err == nil {
						cj <- server
					}
				} else if ident.Type == IDENTIFIER_IMAGE {
					image, err := cmd.API.GetImage(ident.Identifier)
					if err == nil {
						cj <- image
					}
				} else if ident.Type == IDENTIFIER_BOOTSCRIPT {
					// FIXME: bootscript
				}
				wg.Done()
			}()
		}
	}
	wg.Wait()
	close(cj)
}

func runInspect(cmd *Command, args []string) {
	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "usage: scw %s\n", cmd.UsageLine)
		os.Exit(1)
	}

	res := "["
	nb_inspected := 0
	ci := make(chan ScalewayResolvedIdentifier)
	cj := make(chan interface{})
	go resolveIdentifiers(cmd, args, ci)
	go inspectIdentifiers(cmd, ci, cj)
	for {
		data, open := <-cj
		if !open {
			break
		}
		data_b, err := json.MarshalIndent(data, "", "  ")
		if err == nil {
			if nb_inspected != 0 {
				res += ",\n"
			}
			res += string(data_b)
			nb_inspected += 1
		}
	}
	res += "]"

	fmt.Fprintf(os.Stdout, "%s\n", res)

	if len(args) != nb_inspected {
		os.Exit(1)
	}
}
<commit_msg>Updated usages to match Docker<commit_after>package main

import (
	"encoding/json"
	"fmt"
	"os"
	"sync"
)

var cmdInspect = &Command{
	Exec:        runInspect,
	UsageLine:   "inspect [OPTIONS] IDENTIFIER [IDENTIFIER...]",
	Description: "Inspects a server, image or a bootscript",
	Help:        "Inspects a server, image or a bootscript.",
}

type ScalewayResolvedIdentifier struct {
	// Identifiers holds matching identifiers
	Identifiers []ScalewayIdentifier

	// Needle is the criteria used to lookup identifiers
	Needle string
}

// resolveIdentifiers resolves needles provided by the user
func resolveIdentifiers(cmd *Command, needles []string, out chan ScalewayResolvedIdentifier) {
	// first attempt, only lookup from the cache
	var unresolved []string
	for _, needle := range needles {
		idents := cmd.API.Cache.LookUpIdentifiers(needle)
		if len(idents) == 0 {
			unresolved = append(unresolved, needle)
		} else {
			out <- ScalewayResolvedIdentifier{
				Identifiers: idents,
				Needle:      needle,
			}
		}
	}
	// fill the cache by fetching from the API and resolve missing identifiers
	if len(unresolved) > 0 {
		var wg sync.WaitGroup
		wg.Add(2)
		go func() {
			cmd.API.GetServers(true, 0)
			wg.Done()
		}()
		go func() {
			cmd.API.GetImages()
			wg.Done()
		}()
		wg.Wait()
		for _, needle := range unresolved {
			idents := cmd.API.Cache.LookUpIdentifiers(needle)
			out <- ScalewayResolvedIdentifier{
				Identifiers: idents,
				Needle:      needle,
			}
		}
	}
	close(out)
}

// inspectIdentifiers inspects identifiers concurrently
func inspectIdentifiers(cmd *Command, ci chan ScalewayResolvedIdentifier, cj chan interface{}) {
	var wg sync.WaitGroup
	for {
		idents, ok := <-ci
		if !ok {
			break
		}
		if len(idents.Identifiers) != 1 {
			if len(idents.Identifiers) == 0 {
				fmt.Fprintf(os.Stderr, "Unable to resolve identifier %s\n", idents.Needle)
			} else {
				fmt.Fprintf(os.Stderr, "Too many candidates for %s (%d)\n", idents.Needle, len(idents.Identifiers))
				for _, identifier := range idents.Identifiers {
					// FIXME: also print the name
					fmt.Fprintf(os.Stderr, "%s\n", identifier.Identifier)
				}
			}
		} else {
			ident := idents.Identifiers[0]
			wg.Add(1)
			go func() {
				if ident.Type == IDENTIFIER_SERVER {
					server, err := cmd.API.GetServer(ident.Identifier)
					if err == nil {
						cj <- server
					}
				} else if ident.Type == IDENTIFIER_IMAGE {
					image, err := cmd.API.GetImage(ident.Identifier)
					if err == nil {
						cj <- image
					}
				} else if ident.Type == IDENTIFIER_BOOTSCRIPT {
					// FIXME: bootscript
				}
				wg.Done()
			}()
		}
	}
	wg.Wait()
	close(cj)
}

func runInspect(cmd *Command, args []string) {
	if len(args) == 0 {
		fmt.Fprintf(os.Stderr, "usage: scw %s\n", cmd.UsageLine)
		os.Exit(1)
	}

	res := "["
	nb_inspected := 0
	ci := make(chan ScalewayResolvedIdentifier)
	cj := make(chan interface{})
	go resolveIdentifiers(cmd, args, ci)
	go inspectIdentifiers(cmd, ci, cj)
	for {
		data, open := <-cj
		if !open {
			break
		}
		data_b, err := json.MarshalIndent(data, "", "  ")
		if err == nil {
			if nb_inspected != 0 {
				res += ",\n"
			}
			res += string(data_b)
			nb_inspected += 1
		}
	}
	res += "]"

	fmt.Fprintf(os.Stdout, "%s\n", res)

	if len(args) != nb_inspected {
		os.Exit(1)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	irc "github.com/fluffle/goirc/client"
	"log"
	"net/http"
	"os"
	"path/filepath"
)

import (
	msglog "github.com/ciju/irclogs/ircfilelog"
	"github.com/ciju/irclogs/logserver"
)

// todo: directory to log to, as a flag
// todo: option for channel to connect to (list of channels?)

// serve the scroll back files and give api.
// the javascript files.
//

func logIRCMessages(root string, channel string, quit chan bool) {
	c := irc.SimpleClient("logbot")
	c.EnableStateTracking()

	c.AddHandler(irc.CONNECTED, func(conn *irc.Conn, line *irc.Line) {
		conn.Join(channel)
		fmt.Println("connecting to ", channel)
	})

	c.AddHandler(irc.DISCONNECTED, func(conn *irc.Conn, line *irc.Line) {
		fmt.Println("disconnecting")
		quit <- true
	})

	c.AddHandler("PRIVMSG", func(conn *irc.Conn, line *irc.Line) {
		// only log private messages to Nick's
		if line.Args[0] == channel {
			go msglog.LogLine(root, channel, line)
		}
	})

	if err := c.Connect("foonetic.net"); err != nil {
		fmt.Printf("Connection error: %s\n", err)
	}

}

func serveLogs(root string, page_size int, quit chan bool) {
	http.Handle("/logs",
		http.HandlerFunc(
			logserver.LogServerHandler(root, page_size)))
}

func serveAssets(dir string) {
	if dir == "" {
		log.Fatal("No directory given, to serve")
	}

	http.Handle("/", http.FileServer(http.Dir(dir)))
}

var (
	root      = flag.String("l", ".", "log directory, also to serve")
	page_size = flag.Int("s", 30, "page size, to be served")
	port      = flag.String("p", "3001", "port to serve assets and logs")
	channel   = flag.String("c", "#astest", "channel to connect to")
)

func main() {
	flag.Parse()

	quit := make(chan bool)

	p, err := filepath.Abs(*root)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Saving and serving logs to/from %s\n", p)

	os.MkdirAll(p, 0700)

	// go logIRCMessages(p, *channel, quit)
	go serveAssets("./assets")
	go serveLogs(p, *page_size, quit)

	fmt.Println("Serving at port", *port)
	if err := http.ListenAndServe(":"+*port, nil); err != nil {
		log.Fatal("error", err)
	}

	<-quit
}
<commit_msg>log irc channel<commit_after>package main

import (
	"flag"
	"fmt"
	irc "github.com/fluffle/goirc/client"
	"log"
	"net/http"
	"os"
	"path/filepath"
)

import (
	msglog "github.com/ciju/irclogs/ircfilelog"
	"github.com/ciju/irclogs/logserver"
)

// todo: directory to log to, as a flag
// todo: option for channel to connect to (list of channels?)

// serve the scroll back files and give api.
// the javascript files.
//

func logIRCMessages(root string, channel string, quit chan bool) {
	c := irc.SimpleClient("logbot")
	c.EnableStateTracking()

	c.AddHandler(irc.CONNECTED, func(conn *irc.Conn, line *irc.Line) {
		conn.Join(channel)
		fmt.Println("connecting to ", channel)
	})

	c.AddHandler(irc.DISCONNECTED, func(conn *irc.Conn, line *irc.Line) {
		fmt.Println("disconnecting")
		quit <- true
	})

	c.AddHandler("PRIVMSG", func(conn *irc.Conn, line *irc.Line) {
		// only log private messages to Nick's
		if line.Args[0] == channel {
			go msglog.LogLine(root, channel, line)
		}
	})

	if err := c.Connect("foonetic.net"); err != nil {
		fmt.Printf("Connection error: %s\n", err)
	}

}

func serveLogs(root string, page_size int, quit chan bool) {
	http.Handle("/logs",
		http.HandlerFunc(
			logserver.LogServerHandler(root, page_size)))
}

func serveAssets(dir string) {
	if dir == "" {
		log.Fatal("No directory given, to serve")
	}

	http.Handle("/", http.FileServer(http.Dir(dir)))
}

var (
	root      = flag.String("l", ".", "log directory, also to serve")
	page_size = flag.Int("s", 30, "page size, to be served")
	port      = flag.String("p", "3001", "port to serve assets and logs")
	channel   = flag.String("c", "#astest", "channel to connect to")
)

func main() {
	flag.Parse()

	quit := make(chan bool)

	p, err := filepath.Abs(*root)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Saving and serving logs to/from %s\n", p)

	os.MkdirAll(p, 0700)

	go logIRCMessages(p, *channel, quit)
	go serveAssets("./assets")
	go serveLogs(p, *page_size, quit)

	fmt.Println("Serving at port", *port)
	if err := http.ListenAndServe(":"+*port, nil); err != nil {
		log.Fatal("error", err)
	}

	<-quit
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/ajhager/rog"
	"github.com/ajhager/rog/wde"
	"image"
	"runtime"
)

var (
	width  = 40
	height = 20

	wall   = rog.Hex(0xffbb99)
	floorc = rog.Hex(0x885040)
	black  = rog.Hex(0x000000)
	white  = rog.Hex(0xffffff)
	lgrey  = rog.Hex(0xc8c8c8)
	dgrey  = rog.Hex(0x1e1e1e)

	pmap  = rog.NewMap(width, height)
	path  []image.Point
	x     = 0
	y     = 0
	first = true
	stats runtime.MemStats

	tmap = [][]rune{
		[]rune("                                        "),
		[]rune("                                        "),
		[]rune("                                        "),
		[]rune("                                        "),
		[]rune("################    ####################"),
		[]rune("                                        "),
		[]rune("                                        "),
		[]rune("    #           ####        #  #  #     "),
		[]rune("                                        "),
		[]rune("                                        "),
		[]rune("                                        "),
		[]rune("##############              #######     "),
		[]rune("#                                       "),
		[]rune("#            #                          "),
		[]rune("#            #                          "),
		[]rune("################ ## ## ## ## ## ## ## ##"),
		[]rune("                                        "),
		[]rune("                                        "),
		[]rune("                                        "),
		[]rune("                                        "),
	}
)

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())
}

func movePlayer(xx, yy int) {
	if xx >= 0 && yy > 0 && xx < width && yy < height-1 && tmap[yy][xx] == ' ' {
		rog.Set(x, y, white, nil, " ")
		x = xx
		y = yy
		pmap.Fov(x, y, 20, true, rog.FOVCircular)
	}
}

func intensity(px, py, cx, cy, r int) float64 {
	r2 := float64(r * r)
	squaredDist := float64((px-cx)*(px-cx) + (py-cy)*(py-cy))
	coef1 := 1.0 / (1.0 + squaredDist/20)
	coef2 := coef1 - 1.0/(1.0+r2)
	return coef2 / (1.0 - 1.0/(1.0+r2))
}

func example() {
	if first {
		first = false
		for y := 0; y < height; y++ {
			for x := 0; x < width; x++ {
				if tmap[y][x] == '#' {
					pmap.Block(x, y, true)
				}
			}
		}
		movePlayer(23, 9)
	}

	if rog.Mouse().Left.Released {
		path = pmap.Path(x, y, rog.Mouse().Cell.X, rog.Mouse().Cell.Y)
	}

	switch rog.Key() {
	case rog.K:
		movePlayer(x, y-1)
	case rog.J:
		movePlayer(x, y+1)
	case rog.H:
		movePlayer(x-1, y)
	case rog.L:
		movePlayer(x+1, y)
	case rog.P:
		rog.Screenshot("test")
	case rog.Escape:
		rog.Close()
	}

	for cy := 0; cy < pmap.Height(); cy++ {
		for cx := 0; cx < pmap.Width(); cx++ {
			rog.Set(cx, cy, nil, black, " ")
			if pmap.Look(cx, cy) {
				i := intensity(x, y, cx, cy, 20)
				if tmap[cy][cx] == '#' {
					rog.Set(cx, cy, nil, wall.Scale(i), "")
				} else {
					rog.Set(cx, cy, rog.Scale(1.5), floorc.Scale(i), "✵")
				}
			}
		}
	}
	rog.Set(x, y, lgrey, nil, "웃")

	for _, p := range path {
		if p.X != x || p.Y != y {
			rog.Set(p.X, p.Y, lgrey, nil, "*")
		}
	}

	runtime.ReadMemStats(&stats)
	rog.Fill(0, 0, rog.Width(), 1, lgrey, rog.Dodge(dgrey), ' ')
	rog.Set(0, 0, nil, nil, "%vFPS %vMB %vGC %vGR", rog.Fps(), stats.HeapAlloc/1000000, stats.NumGC, runtime.NumGoroutine())
	rog.Fill(0, height-1, rog.Width(), 1, lgrey, rog.Dodge(dgrey), ' ')
	rog.Set(0, height-1, nil, nil, "Pos: %v %v Cell: %v %v", rog.Mouse().Pos.X, rog.Mouse().Pos.Y, rog.Mouse().Cell.X, rog.Mouse().Cell.Y)
}

func main() {
	rog.Open(width, height, 1, "Example", wde.Backend())
	for rog.IsOpen() {
		example()
		rog.Flush()
	}
}
<commit_msg>Remove screenshot taking from old demo<commit_after>package main

import (
	"github.com/ajhager/rog"
	"github.com/ajhager/rog/wde"
	"image"
	"runtime"
)

var (
	width  = 40
	height = 20

	wall   = rog.Hex(0xffbb99)
	floorc = rog.Hex(0x885040)
	black  = rog.Hex(0x000000)
	white  = rog.Hex(0xffffff)
	lgrey  = rog.Hex(0xc8c8c8)
	dgrey  = rog.Hex(0x1e1e1e)

	pmap  = rog.NewMap(width, height)
	path  []image.Point
	x     = 0
	y     = 0
	first = true
	stats runtime.MemStats

	tmap = [][]rune{
		[]rune("                                        "),
		[]rune("                                        "),
		[]rune("                                        "),
		[]rune("                                        "),
		[]rune("################    ####################"),
		[]rune("                                        "),
		[]rune("                                        "),
		[]rune("    #           ####        #  #  #     "),
		[]rune("                                        "),
		[]rune("                                        "),
		[]rune("                                        "),
		[]rune("##############              #######     "),
		[]rune("#                                       "),
		[]rune("#            #                          "),
		[]rune("#            #                          "),
		[]rune("################ ## ## ## ## ## ## ## ##"),
		[]rune("                                        "),
		[]rune("                                        "),
		[]rune("                                        "),
		[]rune("                                        "),
	}
)

func init() {
	runtime.GOMAXPROCS(runtime.NumCPU())
}

func movePlayer(xx, yy int) {
	if xx >= 0 && yy > 0 && xx < width && yy < height-1 && tmap[yy][xx] == ' ' {
		rog.Set(x, y, white, nil, " ")
		x = xx
		y = yy
		pmap.Fov(x, y, 20, true, rog.FOVCircular)
	}
}

func intensity(px, py, cx, cy, r int) float64 {
	r2 := float64(r * r)
	squaredDist := float64((px-cx)*(px-cx) + (py-cy)*(py-cy))
	coef1 := 1.0 / (1.0 + squaredDist/20)
	coef2 := coef1 - 1.0/(1.0+r2)
	return coef2 / (1.0 - 1.0/(1.0+r2))
}

func example() {
	if first {
		first = false
		for y := 0; y < height; y++ {
			for x := 0; x < width; x++ {
				if tmap[y][x] == '#' {
					pmap.Block(x, y, true)
				}
			}
		}
		movePlayer(23, 9)
	}

	if rog.Mouse().Left.Released {
		path = pmap.Path(x, y, rog.Mouse().Cell.X, rog.Mouse().Cell.Y)
	}

	switch rog.Key() {
	case rog.K:
		movePlayer(x, y-1)
	case rog.J:
		movePlayer(x, y+1)
	case rog.H:
		movePlayer(x-1, y)
	case rog.L:
		movePlayer(x+1, y)
	case rog.Escape:
		rog.Close()
	}

	for cy := 0; cy < pmap.Height(); cy++ {
		for cx := 0; cx < pmap.Width(); cx++ {
			rog.Set(cx, cy, nil, black, " ")
			if pmap.Look(cx, cy) {
				i := intensity(x, y, cx, cy, 20)
				if tmap[cy][cx] == '#' {
					rog.Set(cx, cy, nil, wall.Scale(i), "")
				} else {
					rog.Set(cx, cy, rog.Scale(1.5), floorc.Scale(i), "✵")
				}
			}
		}
	}
	rog.Set(x, y, lgrey, nil, "웃")

	for _, p := range path {
		if p.X != x || p.Y != y {
			rog.Set(p.X, p.Y, lgrey, nil, "*")
		}
	}

	runtime.ReadMemStats(&stats)
	rog.Fill(0, 0, rog.Width(), 1, lgrey, rog.Dodge(dgrey), ' ')
	rog.Set(0, 0, nil, nil, "%vFPS %vMB %vGC %vGR", rog.Fps(), stats.HeapAlloc/1000000, stats.NumGC, runtime.NumGoroutine())
	rog.Fill(0, height-1, rog.Width(), 1, lgrey, rog.Dodge(dgrey), ' ')
	rog.Set(0, height-1, nil, nil, "Pos: %v %v Cell: %v %v", rog.Mouse().Pos.X, rog.Mouse().Pos.Y, rog.Mouse().Cell.X, rog.Mouse().Cell.Y)
}

func main() {
	rog.Open(width, height, 1, "Example", wde.Backend())
	for rog.IsOpen() {
		example()
		rog.Flush()
	}
}
<|endoftext|>


<commit_before>package scheduler

import (
	"github.com/gogo/protobuf/proto"
	"strconv"

	log "github.com/golang/glog"
	mesos "github.com/mesos/mesos-go/mesosproto"
	sched "github.com/mesos/mesos-go/scheduler"
)

type Scheduler struct {
	executor      *mesos.ExecutorInfo
	tasksLaunched int
	tasksFinished int
	totalTasks    int
	JobsCh        chan string
}

func NewScheduler(exec *mesos.ExecutorInfo, ch chan string) *Scheduler {
	return &Scheduler{
		executor: exec,
		JobsCh:   ch,
	}
}

func (sched *Scheduler) Registered(driver sched.SchedulerDriver, frameworkId *mesos.FrameworkID, masterInfo *mesos.MasterInfo) {
	log.Infoln("Scheduler Registered with Master ", masterInfo)
}

func (sched *Scheduler) Reregistered(driver sched.SchedulerDriver, masterInfo *mesos.MasterInfo) {
	log.Infoln("Scheduler Re-Registered with Master ", masterInfo)
}

func (sched *Scheduler) Disconnected(sched.SchedulerDriver) {
	log.Infoln("Scheduler Disconnected")
}

func (sched *Scheduler) ResourceOffers(driver sched.SchedulerDriver, offers []*mesos.Offer) {
	logOffers(offers)

	for _, offer := range offers {

		//if we dont have any work to do, just driver.DeclineOffer(offerId *mesos.OfferID, filters *mesos.Filters)
		// see if we have any jobs waiting to run. for now, just use a channel full of jobs
		var data string
		select {
		case data, ok := <-sched.JobsCh:
			if ok {
				log.Infof("Got work %s\n", data)
			} else {
				//TODO should we abort?
				log.Infoln("Channel closed! FUCK why did this happen")
			}
		default:
			log.Infof("No pending work; declining offer %s: %+v", offer.Id, offer)
			driver.DeclineOffer(offer.Id, &mesos.Filters{RefuseSeconds: proto.Float64(1)})
			continue
		}

		taskId := &mesos.TaskID{
			Value: proto.String(strconv.Itoa(sched.tasksLaunched)),
		}

		task := &mesos.TaskInfo{
			Name:      proto.String("moroccron-task-" + taskId.GetValue()),
			TaskId:    taskId,
			SlaveId:   offer.SlaveId,
			Executor:  sched.executor,
			Resources: []*mesos.Resource{
			//TODO stuff in constraints
			//util.NewScalarResource("cpus", sched.cpuPerTask),
			//util.NewScalarResource("mem", sched.memPerTask),
			},
			Data: []byte(data),
		}
		log.Infof("Prepared task: %s with offer %s for launch\n", task.GetName(), offer.Id.GetValue())

		var tasks []*mesos.TaskInfo = []*mesos.TaskInfo{task}
		//TODO i dont understand how you can launch multiple tasks for a single offer
		log.Infoln("Launching ", len(tasks), " tasks for offer", offer.Id.GetValue())
		driver.LaunchTasks([]*mesos.OfferID{offer.Id}, tasks, &mesos.Filters{RefuseSeconds: proto.Float64(1)})
	}
}

func (sched *Scheduler) StatusUpdate(driver sched.SchedulerDriver, status *mesos.TaskStatus) {
	log.Infoln("Status update: task", status.TaskId.GetValue(), " is in state ", status.State.Enum().String())

	if status.GetState() == mesos.TaskState_TASK_FINISHED {
		sched.tasksFinished++
		log.Infoln("%v of %v tasks finished.", sched.tasksFinished, sched.totalTasks)
	}

	/*
		  //never shut down framework!
			if sched.tasksFinished >= sched.totalTasks {
				log.Infoln("Total tasks completed, stopping framework.")
				driver.Stop(false)
			}
	*/

	/*
		if status.GetState() == mesos.TaskState_TASK_LOST ||
			status.GetState() == mesos.TaskState_TASK_KILLED ||
			status.GetState() == mesos.TaskState_TASK_FAILED {
			log.Infoln(
				"Aborting because task", status.TaskId.GetValue(),
				"is in unexpected state", status.State.String(),
				"with message", status.GetMessage(),
			)
			driver.Abort()
		}
	*/
}

func (sched *Scheduler) OfferRescinded(s sched.SchedulerDriver, id *mesos.OfferID) {
	log.Infof("Offer '%v' rescinded.\n", *id)
}

func (sched *Scheduler) FrameworkMessage(s sched.SchedulerDriver, exId *mesos.ExecutorID, slvId *mesos.SlaveID, msg string) {
	log.Infof("Received framework message from executor '%v' on slave '%v': %s.\n", *exId, *slvId, msg)
}

func (sched *Scheduler) SlaveLost(s sched.SchedulerDriver, id *mesos.SlaveID) {
	log.Infof("Slave '%v' lost.\n", *id)
}

func (sched *Scheduler) ExecutorLost(s sched.SchedulerDriver, exId *mesos.ExecutorID, slvId *mesos.SlaveID, i int) {
	log.Infof("Executor '%v' lost on slave '%v' with exit code: %v.\n", *exId, *slvId, i)
}

func (sched *Scheduler) Error(driver sched.SchedulerDriver, err string) {
	log.Infoln("Scheduler received error:", err)
}
<commit_msg>just take all resources for a task<commit_after>package scheduler

import (
	"github.com/gogo/protobuf/proto"
	"strconv"

	log "github.com/golang/glog"
	mesos "github.com/mesos/mesos-go/mesosproto"
	util "github.com/mesos/mesos-go/mesosutil"
	sched "github.com/mesos/mesos-go/scheduler"
)

type Scheduler struct {
	executor      *mesos.ExecutorInfo
	tasksLaunched int
	tasksFinished int
	totalTasks    int
	JobsCh        chan string
}

func NewScheduler(exec *mesos.ExecutorInfo, ch chan string) *Scheduler {
	return &Scheduler{
		executor: exec,
		JobsCh:   ch,
	}
}

func (sched *Scheduler) Registered(driver sched.SchedulerDriver, frameworkId *mesos.FrameworkID, masterInfo *mesos.MasterInfo) {
	log.Infoln("Scheduler Registered with Master ", masterInfo)
}

func (sched *Scheduler) Reregistered(driver sched.SchedulerDriver, masterInfo *mesos.MasterInfo) {
	log.Infoln("Scheduler Re-Registered with Master ", masterInfo)
}

func (sched *Scheduler) Disconnected(sched.SchedulerDriver) {
	log.Infoln("Scheduler Disconnected")
}

func (sched *Scheduler) ResourceOffers(driver sched.SchedulerDriver, offers []*mesos.Offer) {
	logOffers(offers)

	for _, offer := range offers {

		//if we dont have any work to do, just driver.DeclineOffer(offerId *mesos.OfferID, filters *mesos.Filters)
		// see if we have any jobs waiting to run. for now, just use a channel full of jobs
		var data string
		select {
		case data, ok := <-sched.JobsCh:
			if ok {
				log.Infof("Got work %s\n", data)
			} else {
				//TODO should we abort?
				log.Infoln("Channel closed! FUCK why did this happen")
			}
		default:
			log.Infof("No pending work; declining offer %s: %+v", offer.Id, offer)
			driver.DeclineOffer(offer.Id, &mesos.Filters{RefuseSeconds: proto.Float64(1)})
			continue
		}

		taskId := &mesos.TaskID{
			Value: proto.String(strconv.Itoa(sched.tasksLaunched)),
		}

		task := &mesos.TaskInfo{
			Name:     proto.String("moroccron-task-" + taskId.GetValue()),
			TaskId:   taskId,
			SlaveId:  offer.SlaveId,
			Executor: sched.executor,
			Resources: []*mesos.Resource{
				//TODO this is bad. We shouldnt just blindly use up all the offered resources, but... whatever
				util.NewScalarResource("cpus", getOfferCpu(offer)),
				util.NewScalarResource("mem", getOfferMem(offer)),
			},
			Data: []byte(data),
		}
		log.Infof("Prepared task: %s with offer %s for launch\n", task.GetName(), offer.Id.GetValue())

		var tasks []*mesos.TaskInfo = []*mesos.TaskInfo{task}
		//TODO i dont understand how you can launch multiple tasks for a single offer. Is the up to the framework to slice resources per task?
		log.Infoln("Launching ", len(tasks), " tasks for offer", offer.Id.GetValue())
		driver.LaunchTasks([]*mesos.OfferID{offer.Id}, tasks, &mesos.Filters{RefuseSeconds: proto.Float64(1)})
	}
}

func (sched *Scheduler) StatusUpdate(driver sched.SchedulerDriver, status *mesos.TaskStatus) {
	log.Infoln("Status update: task", status.TaskId.GetValue(), " is in state ", status.State.Enum().String())

	if status.GetState() == mesos.TaskState_TASK_FINISHED {
		sched.tasksFinished++
		log.Infoln("%v of %v tasks finished.", sched.tasksFinished, sched.totalTasks)
	}

	/*
		  //never shut down framework!
			if sched.tasksFinished >= sched.totalTasks {
				log.Infoln("Total tasks completed, stopping framework.")
				driver.Stop(false)
			}
	*/

	/*
		if status.GetState() == mesos.TaskState_TASK_LOST ||
			status.GetState() == mesos.TaskState_TASK_KILLED ||
			status.GetState() == mesos.TaskState_TASK_FAILED {
			log.Infoln(
				"Aborting because task", status.TaskId.GetValue(),
				"is in unexpected state", status.State.String(),
				"with message", status.GetMessage(),
			)
			driver.Abort()
		}
	*/
}

func (sched *Scheduler) OfferRescinded(s sched.SchedulerDriver, id *mesos.OfferID) {
	log.Infof("Offer '%v' rescinded.\n", *id)
}

func (sched *Scheduler) FrameworkMessage(s sched.SchedulerDriver, exId *mesos.ExecutorID, slvId *mesos.SlaveID, msg string) {
	log.Infof("Received framework message from executor '%v' on slave '%v': %s.\n", *exId, *slvId, msg)
}

func (sched *Scheduler) SlaveLost(s sched.SchedulerDriver, id *mesos.SlaveID) {
	log.Infof("Slave '%v' lost.\n", *id)
}

func (sched *Scheduler) ExecutorLost(s sched.SchedulerDriver, exId *mesos.ExecutorID, slvId *mesos.SlaveID, i int) {
	log.Infof("Executor '%v' lost on slave '%v' with exit code: %v.\n", *exId, *slvId, i)
}

func (sched *Scheduler) Error(driver sched.SchedulerDriver, err string) {
	log.Infoln("Scheduler received error:", err)
}
<|endoftext|>


<commit_before>// Copyright 2013 Artur Grabowski. All rights reserved.
// Use of this source code is governed by a ISC-style
// license that can be found in the LICENSE file.
package engine

import (
	"bsearch/index"
	"bsearch/parser"
	"fmt"
	"log"
	"net"
	"time"
	"github.com/art4711/bconf"
	"github.com/art4711/timers"
	"bufio"
)

type headers map[string]string

func (h headers) Add(k, v string) {
	h[k] = v
}

type EngineState struct {
	Conf bconf.Bconf
	Index *index.Index
	Timer *timers.Timer

}

func (s EngineState) Listener() {
	listenport := s.Conf.GetString("port", "search")

	ln, err := net.Listen("tcp", ":" + listenport)
	if err != nil {
		log.Fatal("listen: %v\n", err)
	}

	for {
		conn, err := ln.Accept()
		if err != nil {
			log.Fatal("accept %v\n", err)
		}
		go s.handle(conn)
	}
}

func (s EngineState) handle(conn net.Conn) {
	defer conn.Close()
	qt := s.Timer.Start("query")
	defer qt.Stop()

	b := [2048]byte{}
	n, err := conn.Read(b[:])
	if err != nil {
		log.Fatal("conn.Read %v\n", err)
	}
	bq := b[:n]

	writer := bufio.NewWriter(conn)
	defer writer.Flush()

	pt := qt.Start("parse")
	p := parser.Parse(s.Index, string(bq))
	q := p.Stack[0]

	docarr := make([]*index.IbDoc, 0)

	pt = pt.Handover("performQuery")
	search := index.NullDoc()
	for {
		d := q.NextDoc(search)
		if d == nil {
			break
		}
		docarr = append(docarr, d)
		*search = *d
		search.Inc()
	}
	pt = pt.Handover("ProcessHeaders")
	h := make(headers)
	q.ProcessHeaders(h)

	pt = pt.Handover("writeHeaders")
	for k, v := range h {
		fmt.Fprintf(writer, "info:%v:%v\n", k, v)
	}
	writer.WriteString(s.Index.Header())
	pt = pt.Handover("writeDocs")
	for o, d := range docarr {
		if d == nil {
			log.Fatalf("nil in docarr at %v", o)
		}
		doc, exists := s.Index.Docs[d.Id]
		if !exists {
			log.Printf("Doc %v does not exist", d.Id)
		}
		writer.Write(doc)
		writer.WriteString("\n")
	}
	pt.Stop()
}
<commit_msg>Make it compile too.<commit_after>// Copyright 2013 Artur Grabowski. All rights reserved.
// Use of this source code is governed by a ISC-style
// license that can be found in the LICENSE file.
package engine

import (
	"bsearch/index"
	"bsearch/parser"
	"fmt"
	"log"
	"net"
	"github.com/art4711/bconf"
	"github.com/art4711/timers"
	"bufio"
)

type headers map[string]string

func (h headers) Add(k, v string) {
	h[k] = v
}

type EngineState struct {
	Conf bconf.Bconf
	Index *index.Index
	Timer *timers.Timer

}

func (s EngineState) Listener() {
	listenport := s.Conf.GetString("port", "search")

	ln, err := net.Listen("tcp", ":" + listenport)
	if err != nil {
		log.Fatal("listen: %v\n", err)
	}

	for {
		conn, err := ln.Accept()
		if err != nil {
			log.Fatal("accept %v\n", err)
		}
		go s.handle(conn)
	}
}

func (s EngineState) handle(conn net.Conn) {
	defer conn.Close()
	qt := s.Timer.Start("query")
	defer qt.Stop()

	b := [2048]byte{}
	n, err := conn.Read(b[:])
	if err != nil {
		log.Fatal("conn.Read %v\n", err)
	}
	bq := b[:n]

	writer := bufio.NewWriter(conn)
	defer writer.Flush()

	pt := qt.Start("parse")
	p := parser.Parse(s.Index, string(bq))
	q := p.Stack[0]

	docarr := make([]*index.IbDoc, 0)

	pt = pt.Handover("performQuery")
	search := index.NullDoc()
	for {
		d := q.NextDoc(search)
		if d == nil {
			break
		}
		docarr = append(docarr, d)
		*search = *d
		search.Inc()
	}
	pt = pt.Handover("ProcessHeaders")
	h := make(headers)
	q.ProcessHeaders(h)

	pt = pt.Handover("writeHeaders")
	for k, v := range h {
		fmt.Fprintf(writer, "info:%v:%v\n", k, v)
	}
	writer.WriteString(s.Index.Header())
	pt = pt.Handover("writeDocs")
	for o, d := range docarr {
		if d == nil {
			log.Fatalf("nil in docarr at %v", o)
		}
		doc, exists := s.Index.Docs[d.Id]
		if !exists {
			log.Printf("Doc %v does not exist", d.Id)
		}
		writer.Write(doc)
		writer.WriteString("\n")
	}
	pt.Stop()
}
<|endoftext|>


<commit_before>package entity

import (
	"github.com/yofu/dxf/format"
	"github.com/yofu/dxf/handle"
	"github.com/yofu/dxf/table"
)

type Entity interface {
	IsEntity() bool
	Format(*format.Formatter)
	Handle() int
	SetHandle(*int)
	SetBlockRecord(handle.Handler)
	Layer() *table.Layer
	SetLayer(*table.Layer)
}

type entity struct {
	Type        EntityType     // 0
	handle      int            // 5
	blockRecord handle.Handler // 330
	layer       *table.Layer   // 8
}

func NewEntity(t EntityType) *entity {
	e := new(entity)
	e.Type = t
	e.layer = table.LY_0
	return e
}

func (e *entity) Format(f *format.Formatter) {
	f.WriteString(0, EntityTypeString(e.Type))
	f.WriteHex(5, e.handle)
	if e.blockRecord != nil {
		f.WriteString(102, "{ACAD_REACTORS")
		f.WriteHex(330, e.blockRecord.Handle())
		f.WriteString(102, "}")
	}
	f.WriteString(100, "AcDbEntity")
	f.WriteString(8, e.layer.Name)
}

func (e *entity) String() string {
	f := format.New()
	return e.FormatString(f)
}

func (e *entity) FormatString(f *format.Formatter) string {
	e.Format(f)
	return f.Output()
}

func (e *entity) Handle() int {
	return e.handle
}
func (e *entity) SetHandle(v *int) {
	e.handle = *v
	(*v)++
}

func (e *entity) SetBlockRecord(h handle.Handler) {
	e.blockRecord = h
}

func (e *entity) Layer() *table.Layer {
	return e.layer
}

func (e *entity) SetLayer(l *table.Layer) {
	e.layer = l
}
<commit_msg>add entity.owner<commit_after>package entity

import (
	"github.com/yofu/dxf/format"
	"github.com/yofu/dxf/handle"
	"github.com/yofu/dxf/table"
)

type Entity interface {
	IsEntity() bool
	Format(*format.Formatter)
	Handle() int
	SetHandle(*int)
	SetBlockRecord(handle.Handler)
	Layer() *table.Layer
	SetLayer(*table.Layer)
}

type entity struct {
	Type        EntityType     // 0
	handle      int            // 5
	blockRecord handle.Handler // 102 330
	owner       handle.Handler // 330
	layer       *table.Layer   // 8
}

func NewEntity(t EntityType) *entity {
	e := new(entity)
	e.Type = t
	e.layer = table.LY_0
	return e
}

func (e *entity) Format(f *format.Formatter) {
	f.WriteString(0, EntityTypeString(e.Type))
	f.WriteHex(5, e.handle)
	if e.blockRecord != nil {
		f.WriteString(102, "{ACAD_REACTORS")
		f.WriteHex(330, e.blockRecord.Handle())
		f.WriteString(102, "}")
	}
	if e.owner != nil {
		f.WriteHex(330, e.owner.Handle())
	}
	f.WriteString(100, "AcDbEntity")
	f.WriteString(8, e.layer.Name)
}

func (e *entity) String() string {
	f := format.New()
	return e.FormatString(f)
}

func (e *entity) FormatString(f *format.Formatter) string {
	e.Format(f)
	return f.Output()
}

func (e *entity) Handle() int {
	return e.handle
}
func (e *entity) SetHandle(v *int) {
	e.handle = *v
	(*v)++
}

func (e *entity) SetBlockRecord(h handle.Handler) {
	e.blockRecord = h
}

func (e *entity) SetOwner(h handle.Handler) {
	e.owner = h
}

func (e *entity) Layer() *table.Layer {
	return e.layer
}

func (e *entity) SetLayer(l *table.Layer) {
	e.layer = l
}
<|endoftext|>