<commit_before>// Package french provides a common deck used for playing poker and other traditional card games.
package french

import(

)

// Suit defines the standard suits, using ascii hex values for convenience
type Suit int

const (
	Naked Suit = 0
	Spades     = 0x2660
	Hearts     = 0x2661
	Diamonds   = 0x2662
	Clubs      = 0x2663
)

type Card struct {
	Id    int
	Suit  Suit
	Value int
	Label string
	Deck  int
}

// Back is a convenience holder for the ascii card back code
const Back int = 0x1F0A0

var AceOfSpades     = Card{ 0x1F0A1, Spades,    1, "Ace of Spades" }
var	DeuceOfSpades   = Card{ 0x1F0A2, Spades,    2, "Two of Spades" }
var	ThreeOfSpades   = Card{ 0x1F0A3, Spades,    3, "Three of Spades" }
var	FourOfSpades    = Card{ 0x1F0A4, Spades,    4, "Four of Spades" }
var	FiveOfSpades    = Card{ 0x1F0A5, Spades,    5, "Five of Spades" }
var	SixOfSpades     = Card{ 0x1F0A6, Spades,    6, "Six of Spades" }
var	SevenOfSpades   = Card{ 0x1F0A7, Spades,    7, "Seven of Spades" }
var	EightOfSpades   = Card{ 0x1F0A8, Spades,    8, "Eight of Spades" }
var	NineOfSpades    = Card{ 0x1F0A9, Spades,    9, "Nine of Spades" }
var	TenOfSpades     = Card{ 0x1F0AA, Spades,   10, "Ten of Spades" }
var	JackOfSpades    = Card{ 0x1F0AB, Spades,   11, "Jack of Spades" }
var	QueenOfSpades   = Card{ 0x1F0AD, Spades,   12, "Queen of Spades" }
var	KingOfSpades    = Card{ 0x1F0AE, Spades,   13, "King of Spades" }

var AceOfHearts     = Card{ 0x1F0B1, Hearts,    1, "Ace of Hearts" }
var	DeuceOfHearts   = Card{ 0x1F0B2, Hearts,    2, "Two of Hearts" }
var	ThreeOfHearts   = Card{ 0x1F0B3, Hearts,    3, "Three of Hearts" }
var	FourOfHearts    = Card{ 0x1F0B4, Hearts,    4, "Four of Hearts" }
var	FiveOfHearts    = Card{ 0x1F0B5, Hearts,    5, "Five of Hearts" }
var	SixOfHearts     = Card{ 0x1F0B6, Hearts,    6, "Six of Hearts" }
var	SevenOfHearts   = Card{ 0x1F0B7, Hearts,    7, "Seven of Hearts" }
var	EightOfHearts   = Card{ 0x1F0B8, Hearts,    8, "Eight of Hearts" }
var	NineOfHearts    = Card{ 0x1F0B9, Hearts,    9, "Nine of Hearts" }
var	TenOfHearts     = Card{ 0x1F0BA, Hearts,   10, "Ten of Hearts" }
var	JackOfHearts    = Card{ 0x1F0BB, Hearts,   11, "Jack of Hearts" }
var	QueenOfHearts   = Card{ 0x1F0BD, Hearts,   12, "Queen of Hearts" }
var	KingOfHearts    = Card{ 0x1F0BE, Hearts,   13, "King of Hearts" }

var AceOfDiamonds   = Card{ 0x1F0C1, Diamonds,  1, "Ace of Diamonds" }
var	DeuceOfDiamonds = Card{ 0x1F0C2, Diamonds,  2, "Two of Diamonds" }
var	ThreeOfDiamonds = Card{ 0x1F0C3, Diamonds,  3, "Three of Diamonds" }
var	FourOfDiamonds  = Card{ 0x1F0C4, Diamonds,  4, "Four of Diamonds" }
var	FiveOfDiamonds  = Card{ 0x1F0C5, Diamonds,  5, "Five of Diamonds" }
var	SixOfDiamonds   = Card{ 0x1F0C6, Diamonds,  6, "Six of Diamonds" }
var	SevenOfDiamonds = Card{ 0x1F0C7, Diamonds,  7, "Seven of Diamonds" }
var	EightOfDiamonds = Card{ 0x1F0C8, Diamonds,  8, "Eight of Diamonds" }
var	NineOfDiamonds  = Card{ 0x1F0C9, Diamonds,  9, "Nine of Diamonds" }
var	TenOfDiamonds   = Card{ 0x1F0CA, Diamonds, 10, "Ten of Diamonds" }
var	JackOfDiamonds  = Card{ 0x1F0CB, Diamonds, 11, "Jack of Diamonds" }
var	QueenOfDiamonds = Card{ 0x1F0CD, Diamonds, 12, "Queen of Diamonds" }
var	KingOfDiamonds  = Card{ 0x1F0CE, Diamonds, 13, "King of Diamonds" }

var AceOfClubs      = Card{ 0x1F0D1, Clubs,     1, "Ace of Clubs" }
var	DeuceOfClubs    = Card{ 0x1F0D2, Clubs,     2, "Two of Clubs" }
var	ThreeOfClubs    = Card{ 0x1F0D3, Clubs,     3, "Three of Clubs" }
var	FourOfClubs     = Card{ 0x1F0D4, Clubs,     4, "Four of Clubs" }
var	FiveOfClubs     = Card{ 0x1F0D5, Clubs,     5, "Five of Clubs" }
var	SixOfClubs      = Card{ 0x1F0D6, Clubs,     6, "Six of Clubs" }
var	SevenOfClubs    = Card{ 0x1F0D7, Clubs,     7, "Seven of Clubs" }
var	EightOfClubs    = Card{ 0x1F0D8, Clubs,     8, "Eight of Clubs" }
var	NineOfClubs     = Card{ 0x1F0D9, Clubs,     9, "Nine of Clubs" }
var	TenOfClubs      = Card{ 0x1F0DA, Clubs,    10, "Ten of Clubs" }
var	JackOfClubs     = Card{ 0x1F0DB, Clubs,    11, "Jack of Clubs" }
var	QueenOfClubs    = Card{ 0x1F0DD, Clubs,    12, "Queen of Clubs" }
var	KingOfClubs     = Card{ 0x1F0DE, Clubs,    13, "King of Clubs" }

var BlackJoker      = Card{ 0x1F0CF, Naked,    15, "Black Joker" }
var WhiteJoker      = Card{ 0x1F0DF, Naked,    15, "White Joker" }

// NewSpades creates a slice of all spades in a standard deck
func NewSpades() []interface{} {
	return []interface{}{
		AceOfSpades, DeuceOfSpades, ThreeOfSpades, FourOfSpades, FiveOfSpades,
		SixOfSpades, SevenOfSpades, EightOfSpades, NineOfSpades, TenOfSpades,
		JackOfSpades, QueenOfSpades, KingOfSpades,
	}
}

// NewHearts creates a slice of all hearts in a standard deck
func NewHearts() []interface{} {
	return []interface{}{
		AceOfHearts, DeuceOfHearts, ThreeOfHearts, FourOfHearts, FiveOfHearts,
		SixOfHearts, SevenOfHearts, EightOfHearts, NineOfHearts, TenOfHearts,
		JackOfHearts, QueenOfHearts, KingOfHearts,
	}
}

// NewDiamonds creates a slice of all diamonds in a standard deck
func NewDiamonds() []interface{} {
	return []interface{}{
		AceOfDiamonds, DeuceOfDiamonds, ThreeOfDiamonds, FourOfDiamonds, FiveOfDiamonds,
		SixOfDiamonds, SevenOfDiamonds, EightOfDiamonds, NineOfDiamonds, TenOfDiamonds,
		JackOfDiamonds, QueenOfDiamonds, KingOfDiamonds,
	}
}

// NewClubs creates a slice of all clubs in a standard deck
func NewClubs() []interface{} {
	return []interface{}{
		AceOfClubs, DeuceOfClubs, ThreeOfClubs, FourOfClubs, FiveOfClubs,
		SixOfClubs, SevenOfClubs, EightOfClubs, NineOfClubs, TenOfClubs,
		JackOfClubs, QueenOfClubs, KingOfClubs,
	}
}

func pushToDeck(deck []interface{}, cards []interface{}, id int, offset int) []interface{} {
	for j, card := range cards {
		card.Deck = id
		deck[offset + j] = card
	}
	return deck
}

// NewDecks builds a new slice with as many decks and jokers requested
func NewDecks(count int, jokers int) []interface{} {
	out := make([]interface{}, (count * 52) + jokers)
	added := 0
	for i := 0; i < count; i++ {
		out = pushToDeck(out, NewSpades(), i, added)
		out = pushToDeck(out, NewHearts(), i, added)
		out = pushToDeck(out, NewDiamonds(), i, added)
		out = pushToDeck(out, NewClubs(), i, added)
		added += 52
	}
	for i := 0; i < jokers; i++ {
		if i % 2 == 0 {
			out[added + i] = BlackJoker
		} else {
			out[added + i] = WhiteJoker
		}
	}
	return out
}
<commit_msg>Added Deck index.<commit_after>// Package french provides a common deck used for playing poker and other traditional card games.
package french

import(

)

// Suit defines the standard suits, using ascii hex values for convenience
type Suit int

const (
	Naked Suit = 0
	Spades     = 0x2660
	Hearts     = 0x2661
	Diamonds   = 0x2662
	Clubs      = 0x2663
)

type Card struct {
	Id    int
	Suit  Suit
	Value int
	Label string
	Deck  int
}

// Back is a convenience holder for the ascii card back code
const Back int = 0x1F0A0

var AceOfSpades     = Card{ 0x1F0A1, Spades,    1, "Ace of Spades",     0 }
var	DeuceOfSpades   = Card{ 0x1F0A2, Spades,    2, "Two of Spades",     0 }
var	ThreeOfSpades   = Card{ 0x1F0A3, Spades,    3, "Three of Spades",   0 }
var	FourOfSpades    = Card{ 0x1F0A4, Spades,    4, "Four of Spades",    0 }
var	FiveOfSpades    = Card{ 0x1F0A5, Spades,    5, "Five of Spades",    0 }
var	SixOfSpades     = Card{ 0x1F0A6, Spades,    6, "Six of Spades",     0 }
var	SevenOfSpades   = Card{ 0x1F0A7, Spades,    7, "Seven of Spades",   0 }
var	EightOfSpades   = Card{ 0x1F0A8, Spades,    8, "Eight of Spades",   0 }
var	NineOfSpades    = Card{ 0x1F0A9, Spades,    9, "Nine of Spades",    0 }
var	TenOfSpades     = Card{ 0x1F0AA, Spades,   10, "Ten of Spades",     0 }
var	JackOfSpades    = Card{ 0x1F0AB, Spades,   11, "Jack of Spades",    0 }
var	QueenOfSpades   = Card{ 0x1F0AD, Spades,   12, "Queen of Spades",   0 }
var	KingOfSpades    = Card{ 0x1F0AE, Spades,   13, "King of Spades",    0 }

var AceOfHearts     = Card{ 0x1F0B1, Hearts,    1, "Ace of Hearts",     0 }
var	DeuceOfHearts   = Card{ 0x1F0B2, Hearts,    2, "Two of Hearts",     0 }
var	ThreeOfHearts   = Card{ 0x1F0B3, Hearts,    3, "Three of Hearts",   0 }
var	FourOfHearts    = Card{ 0x1F0B4, Hearts,    4, "Four of Hearts",    0 }
var	FiveOfHearts    = Card{ 0x1F0B5, Hearts,    5, "Five of Hearts",    0 }
var	SixOfHearts     = Card{ 0x1F0B6, Hearts,    6, "Six of Hearts",     0 }
var	SevenOfHearts   = Card{ 0x1F0B7, Hearts,    7, "Seven of Hearts",   0 }
var	EightOfHearts   = Card{ 0x1F0B8, Hearts,    8, "Eight of Hearts",   0 }
var	NineOfHearts    = Card{ 0x1F0B9, Hearts,    9, "Nine of Hearts",    0 }
var	TenOfHearts     = Card{ 0x1F0BA, Hearts,   10, "Ten of Hearts",     0 }
var	JackOfHearts    = Card{ 0x1F0BB, Hearts,   11, "Jack of Hearts",    0 }
var	QueenOfHearts   = Card{ 0x1F0BD, Hearts,   12, "Queen of Hearts",   0 }
var	KingOfHearts    = Card{ 0x1F0BE, Hearts,   13, "King of Hearts",    0 }

var AceOfDiamonds   = Card{ 0x1F0C1, Diamonds,  1, "Ace of Diamonds",   0 }
var	DeuceOfDiamonds = Card{ 0x1F0C2, Diamonds,  2, "Two of Diamonds",   0 }
var	ThreeOfDiamonds = Card{ 0x1F0C3, Diamonds,  3, "Three of Diamonds", 0 }
var	FourOfDiamonds  = Card{ 0x1F0C4, Diamonds,  4, "Four of Diamonds",  0 }
var	FiveOfDiamonds  = Card{ 0x1F0C5, Diamonds,  5, "Five of Diamonds",  0 }
var	SixOfDiamonds   = Card{ 0x1F0C6, Diamonds,  6, "Six of Diamonds",   0 }
var	SevenOfDiamonds = Card{ 0x1F0C7, Diamonds,  7, "Seven of Diamonds", 0 }
var	EightOfDiamonds = Card{ 0x1F0C8, Diamonds,  8, "Eight of Diamonds", 0 }
var	NineOfDiamonds  = Card{ 0x1F0C9, Diamonds,  9, "Nine of Diamonds",  0 }
var	TenOfDiamonds   = Card{ 0x1F0CA, Diamonds, 10, "Ten of Diamonds",   0 }
var	JackOfDiamonds  = Card{ 0x1F0CB, Diamonds, 11, "Jack of Diamonds",  0 }
var	QueenOfDiamonds = Card{ 0x1F0CD, Diamonds, 12, "Queen of Diamonds", 0 }
var	KingOfDiamonds  = Card{ 0x1F0CE, Diamonds, 13, "King of Diamonds",  0 }

var AceOfClubs      = Card{ 0x1F0D1, Clubs,     1, "Ace of Clubs",      0 }
var	DeuceOfClubs    = Card{ 0x1F0D2, Clubs,     2, "Two of Clubs",      0 }
var	ThreeOfClubs    = Card{ 0x1F0D3, Clubs,     3, "Three of Clubs",    0 }
var	FourOfClubs     = Card{ 0x1F0D4, Clubs,     4, "Four of Clubs",     0 }
var	FiveOfClubs     = Card{ 0x1F0D5, Clubs,     5, "Five of Clubs",     0 }
var	SixOfClubs      = Card{ 0x1F0D6, Clubs,     6, "Six of Clubs",      0 }
var	SevenOfClubs    = Card{ 0x1F0D7, Clubs,     7, "Seven of Clubs",    0 }
var	EightOfClubs    = Card{ 0x1F0D8, Clubs,     8, "Eight of Clubs",    0 }
var	NineOfClubs     = Card{ 0x1F0D9, Clubs,     9, "Nine of Clubs",     0 }
var	TenOfClubs      = Card{ 0x1F0DA, Clubs,    10, "Ten of Clubs",      0 }
var	JackOfClubs     = Card{ 0x1F0DB, Clubs,    11, "Jack of Clubs",     0 }
var	QueenOfClubs    = Card{ 0x1F0DD, Clubs,    12, "Queen of Clubs",    0 }
var	KingOfClubs     = Card{ 0x1F0DE, Clubs,    13, "King of Clubs",     0 }

var BlackJoker      = Card{ 0x1F0CF, Naked,    15, "Black Joker",       0 }
var WhiteJoker      = Card{ 0x1F0DF, Naked,    15, "White Joker",       0 }

// NewSpades creates a slice of all spades in a standard deck
func NewSpades() []interface{} {
	return []interface{}{
		AceOfSpades, DeuceOfSpades, ThreeOfSpades, FourOfSpades, FiveOfSpades,
		SixOfSpades, SevenOfSpades, EightOfSpades, NineOfSpades, TenOfSpades,
		JackOfSpades, QueenOfSpades, KingOfSpades,
	}
}

// NewHearts creates a slice of all hearts in a standard deck
func NewHearts() []interface{} {
	return []interface{}{
		AceOfHearts, DeuceOfHearts, ThreeOfHearts, FourOfHearts, FiveOfHearts,
		SixOfHearts, SevenOfHearts, EightOfHearts, NineOfHearts, TenOfHearts,
		JackOfHearts, QueenOfHearts, KingOfHearts,
	}
}

// NewDiamonds creates a slice of all diamonds in a standard deck
func NewDiamonds() []interface{} {
	return []interface{}{
		AceOfDiamonds, DeuceOfDiamonds, ThreeOfDiamonds, FourOfDiamonds, FiveOfDiamonds,
		SixOfDiamonds, SevenOfDiamonds, EightOfDiamonds, NineOfDiamonds, TenOfDiamonds,
		JackOfDiamonds, QueenOfDiamonds, KingOfDiamonds,
	}
}

// NewClubs creates a slice of all clubs in a standard deck
func NewClubs() []interface{} {
	return []interface{}{
		AceOfClubs, DeuceOfClubs, ThreeOfClubs, FourOfClubs, FiveOfClubs,
		SixOfClubs, SevenOfClubs, EightOfClubs, NineOfClubs, TenOfClubs,
		JackOfClubs, QueenOfClubs, KingOfClubs,
	}
}

func pushToDeck(deck []interface{}, cards []interface{}, id int, offset int) []interface{} {
	for j, card := range cards {
		card.Deck = id
		deck[offset + j] = card
	}
	return deck
}

// NewDecks builds a new slice with as many decks and jokers requested
func NewDecks(count int, jokers int) []interface{} {
	out := make([]interface{}, (count * 52) + jokers)
	added := 0
	for i := 0; i < count; i++ {
		out = pushToDeck(out, NewSpades(), i, added)
		out = pushToDeck(out, NewHearts(), i, added)
		out = pushToDeck(out, NewDiamonds(), i, added)
		out = pushToDeck(out, NewClubs(), i, added)
		added += 52
	}
	for i := 0; i < jokers; i++ {
		if i % 2 == 0 {
			out[added + i] = BlackJoker
		} else {
			out[added + i] = WhiteJoker
		}
	}
	return out
}
<|endoftext|>


<commit_before><commit_msg>Define Alpha 10<commit_after><|endoftext|>


<commit_before>package auth

import (
	"errors"
	"fmt"

	"github.com/chrisolsen/ae/attachment"
	"github.com/chrisolsen/ae/model"
	"github.com/chrisolsen/ae/store"
	"golang.org/x/net/context"
	"google.golang.org/appengine/datastore"
)

const accountsTable string = "accounts"

// AccountPayload contains the account and related data
type AccountPayload struct {
	Account

	// other attributes and relations
}

// Account model
type Account struct {
	model.Base

	FirstName string `json:"firstName" datastore:",noindex"`
	LastName  string `json:"lastName" datastore:",noindex"`
	Gender    string `json:"gender" datastore:",noindex"`
	Locale    string `json:"locale" datastore:",noindex"`
	Location  string `json:"location" datastore:",noindex"`
	Name      string `json:"name" datastore:",noindex"`
	Timezone  int    `json:"timezone" datastore:",noindex"`
	Email     string `json:"email"`

	Photo attachment.File `json:"photo"`
}

type AccountStore struct {
	store.Base
}

func NewAccountStore() AccountStore {
	s := AccountStore{}
	s.TableName = "accounts"
	return s
}

// Create creates a new account and creates its default subscriptions
func (s *AccountStore) Create(c context.Context, creds *Credentials, account *Account) (*datastore.Key, error) {
	var err error
	var accountKey *datastore.Key
	var cStore = NewCredentialStore()
	err = datastore.RunInTransaction(c, func(tc context.Context) error {
		accountKey, err = s.Base.Create(tc, account, nil)
		if err != nil {
			return fmt.Errorf("failed to create account: %v", err)
		}

		_, err = cStore.Create(tc, creds, accountKey)
		if err != nil {
			return fmt.Errorf("failed to create credentials: %v", err)
		}

		return nil
	}, &datastore.TransactionOptions{XG: true})

	return accountKey, nil
}

// GetAccountKeyByCredentials fetches the account matching the auth provider credentials
func (s *AccountStore) GetAccountKeyByCredentials(c context.Context, creds *Credentials) (*datastore.Key, error) {
	var err error
	cstore := NewCredentialStore()
	// on initial signup the account key will exist within the credentials
	if creds.AccountKey != nil {
		var accountCreds []*Credentials
		_, err = cstore.GetByParent(c, creds.AccountKey, 0, -1, &accountCreds)
		if err != nil {
			return nil, fmt.Errorf("failed to find credentials by parent account: %v", err)
		}
		// validate credentials
		for _, ac := range accountCreds {
			if ac.ProviderID == creds.ProviderID && ac.ProviderName == creds.ProviderName {
				return creds.AccountKey, nil
			}
		}
		return nil, errors.New("no matching credentials found for account")
	}

	// by provider
	if len(creds.ProviderID) > 0 {
		return cstore.GetAccountKeyByProvider(c, creds)
	}

	// by username
	var userNameCreds []*Credentials
	_, err = cstore.GetByUsername(c, creds.Username, &userNameCreds)
	if err != nil {
		return nil, err
	}

	if len(userNameCreds) != 1 {
		return nil, errors.New("unable to find unique credentials")
	}

	err = checkCrypt(userNameCreds[0].Password, creds.Password)
	if err != nil {
		return nil, err
	}
	return userNameCreds[0].Key.Parent(), nil
}
<commit_msg>remove old unused type and const<commit_after>package auth

import (
	"errors"
	"fmt"

	"github.com/chrisolsen/ae/attachment"
	"github.com/chrisolsen/ae/model"
	"github.com/chrisolsen/ae/store"
	"golang.org/x/net/context"
	"google.golang.org/appengine/datastore"
)

// Account model
type Account struct {
	model.Base

	FirstName string `json:"firstName" datastore:",noindex"`
	LastName  string `json:"lastName" datastore:",noindex"`
	Gender    string `json:"gender" datastore:",noindex"`
	Locale    string `json:"locale" datastore:",noindex"`
	Location  string `json:"location" datastore:",noindex"`
	Name      string `json:"name" datastore:",noindex"`
	Timezone  int    `json:"timezone" datastore:",noindex"`
	Email     string `json:"email"`

	Photo attachment.File `json:"photo"`
}

type AccountStore struct {
	store.Base
}

func NewAccountStore() AccountStore {
	s := AccountStore{}
	s.TableName = "accounts"
	return s
}

// Create creates a new account and creates its default subscriptions
func (s *AccountStore) Create(c context.Context, creds *Credentials, account *Account) (*datastore.Key, error) {
	var err error
	var accountKey *datastore.Key
	var cStore = NewCredentialStore()
	err = datastore.RunInTransaction(c, func(tc context.Context) error {
		accountKey, err = s.Base.Create(tc, account, nil)
		if err != nil {
			return fmt.Errorf("failed to create account: %v", err)
		}

		_, err = cStore.Create(tc, creds, accountKey)
		if err != nil {
			return fmt.Errorf("failed to create credentials: %v", err)
		}

		return nil
	}, &datastore.TransactionOptions{XG: true})

	return accountKey, nil
}

// GetAccountKeyByCredentials fetches the account matching the auth provider credentials
func (s *AccountStore) GetAccountKeyByCredentials(c context.Context, creds *Credentials) (*datastore.Key, error) {
	var err error
	cstore := NewCredentialStore()
	// on initial signup the account key will exist within the credentials
	if creds.AccountKey != nil {
		var accountCreds []*Credentials
		_, err = cstore.GetByParent(c, creds.AccountKey, 0, -1, &accountCreds)
		if err != nil {
			return nil, fmt.Errorf("failed to find credentials by parent account: %v", err)
		}
		// validate credentials
		for _, ac := range accountCreds {
			if ac.ProviderID == creds.ProviderID && ac.ProviderName == creds.ProviderName {
				return creds.AccountKey, nil
			}
		}
		return nil, errors.New("no matching credentials found for account")
	}

	// by provider
	if len(creds.ProviderID) > 0 {
		return cstore.GetAccountKeyByProvider(c, creds)
	}

	// by username
	var userNameCreds []*Credentials
	_, err = cstore.GetByUsername(c, creds.Username, &userNameCreds)
	if err != nil {
		return nil, err
	}

	if len(userNameCreds) != 1 {
		return nil, errors.New("unable to find unique credentials")
	}

	err = checkCrypt(userNameCreds[0].Password, creds.Password)
	if err != nil {
		return nil, err
	}
	return userNameCreds[0].Key.Parent(), nil
}
<|endoftext|>


<commit_before>package main

import (
	"strings"

	log "github.com/Sirupsen/logrus"
)

// AuthService describes the required and optional services that may be supplied by an authentication
// backend for cloudpipe.
type AuthService interface {
	Validate(username, token string) (bool, error)
}

// ConnectToAuthService initializes an appropriate AuthService implementation based on a (possibly
// omitted) service address.
func ConnectToAuthService(address string) (AuthService, error) {
	if address == "" {
		return NullAuthService{}, nil
	}

	if !strings.HasPrefix(address, "https://") {
		log.WithFields(log.Fields{
			"address": address,
		}).Warn("Non-HTTPS address in use for authentication. Bad! Bad! Bad!")
	}

	return RemoteAuthService{ValidateURL: address}, nil
}

// RemoteAuthService is an auth service that's implemented by calls to an HTTPS remote API.
type RemoteAuthService struct {
	ValidateURL string
}

// Validate sends a request to the configured authentication service to determine whether or not
// a username-token pair is valid.
func (service RemoteAuthService) Validate(username, token string) (bool, error) {

	return false, nil
}

// NullAuthService is an AuthService implementation that refuses all users and provides no optional
// capabilities. It's used as a default if no AuthService is provided and is useful to embed in
// test cases.
type NullAuthService struct{}

// Validate rejects all username-token pairs.
func (service NullAuthService) Validate(username, token string) (bool, error) {
	return false, nil
}

// Ensure that NullAuthService adheres to the AuthService interface.

var _ AuthService = NullAuthService{}
<commit_msg>Implement an (HTTP) remote auth service.<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"strings"

	log "github.com/Sirupsen/logrus"
)

// AuthService describes the required and optional services that may be supplied by an authentication
// backend for cloudpipe.
type AuthService interface {
	Validate(username, token string) (bool, error)
}

// ConnectToAuthService initializes an appropriate AuthService implementation based on a (possibly
// omitted) service address.
func ConnectToAuthService(address string) (AuthService, error) {
	if address == "" {
		return NullAuthService{}, nil
	}

	if !strings.HasPrefix(address, "https://") {
		log.WithFields(log.Fields{
			"address": address,
		}).Warn("Non-HTTPS address in use for authentication. Bad! Bad! Bad!")
	}

	if !strings.HasSuffix(address, "/") {
		address = address + "/"
	}

	return RemoteAuthService{ValidateURL: address + "validate"}, nil
}

// RemoteAuthService is an auth service that's implemented by calls to an HTTPS remote API.
type RemoteAuthService struct {
	ValidateURL string
}

// Validate sends a request to the configured authentication service to determine whether or not
// a username-token pair is valid.
func (service RemoteAuthService) Validate(username, token string) (bool, error) {
	v := url.Values{}
	v.Set("username", username)
	v.Set("token", token)
	resp, err := http.Get(service.ValidateURL + "?" + v.Encode())
	if err != nil {
		return false, err
	}

	switch resp.StatusCode {
	case http.StatusNoContent:
		return true, nil
	case http.StatusNotFound:
		return false, nil
	default:
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			body = []byte(fmt.Sprintf("Error fetching body: %v", err))
		}
		log.WithFields(log.Fields{
			"status": resp.Status,
			"body":   string(body),
		}).Error("The authentication service did something unexpected.")
		return false, fmt.Errorf("unexpected HTTP status %d from auth service", resp.StatusCode)
	}
}

// NullAuthService is an AuthService implementation that refuses all users and provides no optional
// capabilities. It's used as a default if no AuthService is provided and is useful to embed in
// test cases.
type NullAuthService struct{}

// Validate rejects all username-token pairs.
func (service NullAuthService) Validate(username, token string) (bool, error) {
	return false, nil
}

// Ensure that NullAuthService adheres to the AuthService interface.

var _ AuthService = NullAuthService{}
<|endoftext|>


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

package gzip_test

import (
	"bytes"
	"compress/gzip"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/http/httptest"
	"os"
	"strings"
	"time"
)

func Example_writerReader() {
	var buf bytes.Buffer
	zw := gzip.NewWriter(&buf)

	// Setting the Header fields is optional.
	zw.Name = "a-new-hope.txt"
	zw.Comment = "an epic space opera by George Lucas"
	zw.ModTime = time.Date(1977, time.May, 25, 0, 0, 0, 0, time.UTC)

	_, err := zw.Write([]byte("A long time ago in a galaxy far, far away..."))
	if err != nil {
		log.Fatal(err)
	}

	if err := zw.Close(); err != nil {
		log.Fatal(err)
	}

	zr, err := gzip.NewReader(&buf)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Name: %s\nComment: %s\nModTime: %s\n\n", zr.Name, zr.Comment, zr.ModTime.UTC())

	if _, err := io.Copy(os.Stdout, zr); err != nil {
		log.Fatal(err)
	}

	if err := zr.Close(); err != nil {
		log.Fatal(err)
	}

	// Output:
	// Name: a-new-hope.txt
	// Comment: an epic space opera by George Lucas
	// ModTime: 1977-05-25 00:00:00 +0000 UTC
	//
	// A long time ago in a galaxy far, far away...
}

func ExampleReader_Multistream() {
	var buf bytes.Buffer
	zw := gzip.NewWriter(&buf)

	var files = []struct {
		name    string
		comment string
		modTime time.Time
		data    string
	}{
		{"file-1.txt", "file-header-1", time.Date(2006, time.February, 1, 3, 4, 5, 0, time.UTC), "Hello Gophers - 1"},
		{"file-2.txt", "file-header-2", time.Date(2007, time.March, 2, 4, 5, 6, 1, time.UTC), "Hello Gophers - 2"},
	}

	for _, file := range files {
		zw.Name = file.name
		zw.Comment = file.comment
		zw.ModTime = file.modTime

		if _, err := zw.Write([]byte(file.data)); err != nil {
			log.Fatal(err)
		}

		if err := zw.Close(); err != nil {
			log.Fatal(err)
		}

		zw.Reset(&buf)
	}

	zr, err := gzip.NewReader(&buf)
	if err != nil {
		log.Fatal(err)
	}

	for {
		zr.Multistream(false)
		fmt.Printf("Name: %s\nComment: %s\nModTime: %s\n\n", zr.Name, zr.Comment, zr.ModTime.UTC())

		if _, err := io.Copy(os.Stdout, zr); err != nil {
			log.Fatal(err)
		}

		fmt.Print("\n\n")

		err = zr.Reset(&buf)
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
	}

	if err := zr.Close(); err != nil {
		log.Fatal(err)
	}

	// Output:
	// Name: file-1.txt
	// Comment: file-header-1
	// ModTime: 2006-02-01 03:04:05 +0000 UTC
	//
	// Hello Gophers - 1
	//
	// Name: file-2.txt
	// Comment: file-header-2
	// ModTime: 2007-03-02 04:05:06 +0000 UTC
	//
	// Hello Gophers - 2
}

func Example_compressingReader() {
	// This is an example of writing a compressing reader.
	// This can be useful for an HTTP client body, as shown.

	const testdata = "the data to be compressed"

	// This HTTP handler is just for testing purposes.
	handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		zr, err := gzip.NewReader(req.Body)
		if err != nil {
			log.Fatal(err)
		}

		// Just output the data for the example.
		if _, err := io.Copy(os.Stdout, zr); err != nil {
			log.Fatal(err)
		}
	})
	ts := httptest.NewServer(handler)
	defer ts.Close()

	// The remainder is the example code.

	// The data we want to compress, as an io.Reader
	dataReader := strings.NewReader(testdata)

	// bodyReader is the body of the HTTP request, as an io.Reader.
	// httpWriter is the body of the HTTP request, as an io.Writer.
	bodyReader, httpWriter := io.Pipe()

	// gzipWriter compresses data to httpWriter.
	gzipWriter := gzip.NewWriter(httpWriter)

	// errch collects any errors from the writing goroutine.
	errch := make(chan error, 1)

	go func() {
		defer close(errch)
		sentErr := false
		sendErr := func(err error) {
			if !sentErr {
				errch <- err
				sentErr = true
			}
		}

		// Copy our data to gzipWriter, which compresses it to
		// gzipWriter, which feeds it to bodyReader.
		if _, err := io.Copy(gzipWriter, dataReader); err != nil && err != io.ErrClosedPipe {
			sendErr(err)
		}
		if err := gzipWriter.Close(); err != nil && err != io.ErrClosedPipe {
			sendErr(err)
		}
		if err := httpWriter.Close(); err != nil && err != io.ErrClosedPipe {
			sendErr(err)
		}
	}()

	// Send an HTTP request to the test server.
	req, err := http.NewRequest("PUT", ts.URL, bodyReader)
	if err != nil {
		log.Fatal(err)
	}

	// Note that passing req to http.Client.Do promises that it
	// will close the body, in this case bodyReader.
	// That ensures that the goroutine will exit.
	resp, err := ts.Client().Do(req)
	if err != nil {
		log.Fatal(err)
	}

	// Check whether there was an error compressing the data.
	if err := <-errch; err != nil {
		log.Fatal(err)
	}

	// For this example we don't care about the response.
	resp.Body.Close()

	// Output: the data to be compressed
}
<commit_msg>compress/gzip: always close bodyReader in Example_compressingReader<commit_after>// Copyright 2016 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package gzip_test

import (
	"bytes"
	"compress/gzip"
	"fmt"
	"io"
	"log"
	"net/http"
	"net/http/httptest"
	"os"
	"strings"
	"time"
)

func Example_writerReader() {
	var buf bytes.Buffer
	zw := gzip.NewWriter(&buf)

	// Setting the Header fields is optional.
	zw.Name = "a-new-hope.txt"
	zw.Comment = "an epic space opera by George Lucas"
	zw.ModTime = time.Date(1977, time.May, 25, 0, 0, 0, 0, time.UTC)

	_, err := zw.Write([]byte("A long time ago in a galaxy far, far away..."))
	if err != nil {
		log.Fatal(err)
	}

	if err := zw.Close(); err != nil {
		log.Fatal(err)
	}

	zr, err := gzip.NewReader(&buf)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Name: %s\nComment: %s\nModTime: %s\n\n", zr.Name, zr.Comment, zr.ModTime.UTC())

	if _, err := io.Copy(os.Stdout, zr); err != nil {
		log.Fatal(err)
	}

	if err := zr.Close(); err != nil {
		log.Fatal(err)
	}

	// Output:
	// Name: a-new-hope.txt
	// Comment: an epic space opera by George Lucas
	// ModTime: 1977-05-25 00:00:00 +0000 UTC
	//
	// A long time ago in a galaxy far, far away...
}

func ExampleReader_Multistream() {
	var buf bytes.Buffer
	zw := gzip.NewWriter(&buf)

	var files = []struct {
		name    string
		comment string
		modTime time.Time
		data    string
	}{
		{"file-1.txt", "file-header-1", time.Date(2006, time.February, 1, 3, 4, 5, 0, time.UTC), "Hello Gophers - 1"},
		{"file-2.txt", "file-header-2", time.Date(2007, time.March, 2, 4, 5, 6, 1, time.UTC), "Hello Gophers - 2"},
	}

	for _, file := range files {
		zw.Name = file.name
		zw.Comment = file.comment
		zw.ModTime = file.modTime

		if _, err := zw.Write([]byte(file.data)); err != nil {
			log.Fatal(err)
		}

		if err := zw.Close(); err != nil {
			log.Fatal(err)
		}

		zw.Reset(&buf)
	}

	zr, err := gzip.NewReader(&buf)
	if err != nil {
		log.Fatal(err)
	}

	for {
		zr.Multistream(false)
		fmt.Printf("Name: %s\nComment: %s\nModTime: %s\n\n", zr.Name, zr.Comment, zr.ModTime.UTC())

		if _, err := io.Copy(os.Stdout, zr); err != nil {
			log.Fatal(err)
		}

		fmt.Print("\n\n")

		err = zr.Reset(&buf)
		if err == io.EOF {
			break
		}
		if err != nil {
			log.Fatal(err)
		}
	}

	if err := zr.Close(); err != nil {
		log.Fatal(err)
	}

	// Output:
	// Name: file-1.txt
	// Comment: file-header-1
	// ModTime: 2006-02-01 03:04:05 +0000 UTC
	//
	// Hello Gophers - 1
	//
	// Name: file-2.txt
	// Comment: file-header-2
	// ModTime: 2007-03-02 04:05:06 +0000 UTC
	//
	// Hello Gophers - 2
}

func Example_compressingReader() {
	// This is an example of writing a compressing reader.
	// This can be useful for an HTTP client body, as shown.

	const testdata = "the data to be compressed"

	// This HTTP handler is just for testing purposes.
	handler := http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
		zr, err := gzip.NewReader(req.Body)
		if err != nil {
			log.Fatal(err)
		}

		// Just output the data for the example.
		if _, err := io.Copy(os.Stdout, zr); err != nil {
			log.Fatal(err)
		}
	})
	ts := httptest.NewServer(handler)
	defer ts.Close()

	// The remainder is the example code.

	// The data we want to compress, as an io.Reader
	dataReader := strings.NewReader(testdata)

	// bodyReader is the body of the HTTP request, as an io.Reader.
	// httpWriter is the body of the HTTP request, as an io.Writer.
	bodyReader, httpWriter := io.Pipe()

	// Make sure that bodyReader is always closed, so that the
	// goroutine below will always exit.
	defer bodyReader.Close()

	// gzipWriter compresses data to httpWriter.
	gzipWriter := gzip.NewWriter(httpWriter)

	// errch collects any errors from the writing goroutine.
	errch := make(chan error, 1)

	go func() {
		defer close(errch)
		sentErr := false
		sendErr := func(err error) {
			if !sentErr {
				errch <- err
				sentErr = true
			}
		}

		// Copy our data to gzipWriter, which compresses it to
		// gzipWriter, which feeds it to bodyReader.
		if _, err := io.Copy(gzipWriter, dataReader); err != nil && err != io.ErrClosedPipe {
			sendErr(err)
		}
		if err := gzipWriter.Close(); err != nil && err != io.ErrClosedPipe {
			sendErr(err)
		}
		if err := httpWriter.Close(); err != nil && err != io.ErrClosedPipe {
			sendErr(err)
		}
	}()

	// Send an HTTP request to the test server.
	req, err := http.NewRequest("PUT", ts.URL, bodyReader)
	if err != nil {
		log.Fatal(err)
	}

	// Note that passing req to http.Client.Do promises that it
	// will close the body, in this case bodyReader.
	resp, err := ts.Client().Do(req)
	if err != nil {
		log.Fatal(err)
	}

	// Check whether there was an error compressing the data.
	if err := <-errch; err != nil {
		log.Fatal(err)
	}

	// For this example we don't care about the response.
	resp.Body.Close()

	// Output: the data to be compressed
}
<|endoftext|>


<commit_before>package phdremote

    const ClientHTML = `

        <meta name="viewport" content="initial-scale=0.5, width=640, user-scalable=no">
        <meta name="apple-mobile-web-app-status-bar-style" content="black">
        <meta name="apple-mobile-web-app-capable" content="yes">

        <svg id="bull" width="100%%" height="100%%" style="opacity:0; position: absolute; top: 0; left: 0;">
            <g >
                <line x1="0px" y1="50%%" x2="100%%" y2="50%%" stroke="red" stroke-width="1" />
                <line x1="50%%" y1="0px" x2="50%%" y2="100%%" stroke="red" stroke-width="1" />
                <circle cx="50%%" cy="50%%" r="10%%" stroke="red" stroke-width="1" fill="none" />
                <circle cx="50%%" cy="50%%" r="4%%" stroke="red" stroke-width="1" fill="none" />
                <circle cx="50%%" cy="50%%" r="2%%" stroke="red" stroke-width="1" fill="none" />
            </g>
        </svg>
        <svg id="marker" width="20" height="20" style="position: absolute; top: 0; left: 0;">
            <g id="m-select" style="opacity:0">
                <rect x="-4" y="-4" width="10" height="10" stroke="white" stroke-width="2" fill="none" />
                <rect x="14" y="-4" width="10" height="10" stroke="white" stroke-width="2" fill="none" />
                <rect x="-4" y="14" width="10" height="10" stroke="white" stroke-width="2" fill="none" />
                <rect x="14" y="14" width="10" height="10" stroke="white" stroke-width="2" fill="none" />
            </g>
            <g id="m-calib" style="opacity:0">
                <rect x="0" y="0" width="20" height="20" stroke="yellow" stroke-width="4" stroke-dasharray="2 2" fill="none" />
            </g>
            <g id="m-guide" style="opacity:0">
                <line x1="10" y1="0" x2="10" y2="20" stroke="green" stroke-width="2" />
                <line x1="0" y1="10" x2="20" y2="10" stroke="green" stroke-width="2" />
                <rect x="4" y="4" width="12" height="12" stroke="green" stroke-width="2" fill="none" />
            </g>
            <g id="m-lost"  style="opacity:0">
                <line x1="0" y1="0" x2="20" y2="20" stroke="red" stroke-width="2" />
                <line x1="20" y1="0" x2="0" y2="20" stroke="red" stroke-width="2" />
                <rect x="0" y="0" width="20" height="20" stroke="red" stroke-width="4" fill="none" />
            </g>
        </svg>

        0.5s
        1.0s
        2.0s

        GUIDE
        STOP
        LOOP

          <svg width="60px" height="60px">
            <g >
                <path d="M30,10 L30,50 A20,20 0 0,1 30,10 z" fill="black" />
                <path d="M30,50 L30,10 A20,20 0 0,1 30,50 z" fill="firebrick" />
            </g>
          </svg>

            <svg width="40px" height="40px">
            <g >
                <animateTransform id="solvedspinner"
                    attributeName="transform"
                    attributeType="XML"
                    type="rotate"
                    from="0 20 20"
                    to="360 20 20"
                    dur="10s"
                    begin="indefinite"
                    repeatCount="indefinite"/>
                <line x1="60%%" y1="30%%" x2="20%%" y2="60%%" stroke="black" stroke-width="1" />
                <line x1="20%%" y1="60%%" x2="80%%" y2="80%%" stroke="black" stroke-width="1" />
                <line x1="80%%" y1="80%%" x2="60%%" y2="30%%" stroke="black" stroke-width="1" />
                <circle cx="60%%" cy="30%%" r="8%%" stroke="black" stroke-width="1" fill="firebrick" />
                <circle cx="20%%" cy="60%%" r="8%%" stroke="black" stroke-width="1" fill="firebrick" />
                <circle cx="80%%" cy="80%%" r="8%%" stroke="black" stroke-width="1" fill="firebrick" />
            </g>

            </svg>

            <svg width="40px" height="40px">
            <g >
                <line x1="0px" y1="50%%" x2="100%%" y2="50%%" stroke="black" stroke-width="1" />
                <line x1="50%%" y1="0px" x2="50%%" y2="100%%" stroke="black" stroke-width="1" />
                <circle cx="50%%" cy="50%%" r="20%%" stroke="black" stroke-width="1" fill="none" />
                <circle cx="50%%" cy="50%%" r="10%%" stroke="black" stroke-width="1" fill="none" />
            </g>
            </svg>

`
<commit_msg>ghost plate solve<commit_after>package phdremote

    const ClientHTML = `

        <meta name="viewport" content="initial-scale=0.5, width=640, user-scalable=no">
        <meta name="apple-mobile-web-app-status-bar-style" content="black">
        <meta name="apple-mobile-web-app-capable" content="yes">

        <svg id="bull" width="100%%" height="100%%" style="opacity:0; position: absolute; top: 0; left: 0;">
            <g >
                <line x1="0px" y1="50%%" x2="100%%" y2="50%%" stroke="red" stroke-width="1" />
                <line x1="50%%" y1="0px" x2="50%%" y2="100%%" stroke="red" stroke-width="1" />
                <circle cx="50%%" cy="50%%" r="10%%" stroke="red" stroke-width="1" fill="none" />
                <circle cx="50%%" cy="50%%" r="4%%" stroke="red" stroke-width="1" fill="none" />
                <circle cx="50%%" cy="50%%" r="2%%" stroke="red" stroke-width="1" fill="none" />
            </g>
        </svg>
        <svg id="marker" width="20" height="20" style="position: absolute; top: 0; left: 0;">
            <g id="m-select" style="opacity:0">
                <rect x="-4" y="-4" width="10" height="10" stroke="white" stroke-width="2" fill="none" />
                <rect x="14" y="-4" width="10" height="10" stroke="white" stroke-width="2" fill="none" />
                <rect x="-4" y="14" width="10" height="10" stroke="white" stroke-width="2" fill="none" />
                <rect x="14" y="14" width="10" height="10" stroke="white" stroke-width="2" fill="none" />
            </g>
            <g id="m-calib" style="opacity:0">
                <rect x="0" y="0" width="20" height="20" stroke="yellow" stroke-width="4" stroke-dasharray="2 2" fill="none" />
            </g>
            <g id="m-guide" style="opacity:0">
                <line x1="10" y1="0" x2="10" y2="20" stroke="green" stroke-width="2" />
                <line x1="0" y1="10" x2="20" y2="10" stroke="green" stroke-width="2" />
                <rect x="4" y="4" width="12" height="12" stroke="green" stroke-width="2" fill="none" />
            </g>
            <g id="m-lost"  style="opacity:0">
                <line x1="0" y1="0" x2="20" y2="20" stroke="red" stroke-width="2" />
                <line x1="20" y1="0" x2="0" y2="20" stroke="red" stroke-width="2" />
                <rect x="0" y="0" width="20" height="20" stroke="red" stroke-width="4" fill="none" />
            </g>
        </svg>

        0.5s
        1.0s
        2.0s

        GUIDE
        STOP
        LOOP

          <svg width="60px" height="60px">
            <g >
                <path d="M30,10 L30,50 A20,20 0 0,1 30,10 z" fill="black" />
                <path d="M30,50 L30,10 A20,20 0 0,1 30,50 z" fill="firebrick" />
            </g>
          </svg>

            <svg width="40px" height="40px">
            <g >
                <animateTransform id="solvedspinner"
                    attributeName="transform"
                    attributeType="XML"
                    type="rotate"
                    from="0 20 20"
                    to="360 20 20"
                    dur="10s"
                    begin="indefinite"
                    repeatCount="indefinite"/>
                <line x1="60%%" y1="30%%" x2="20%%" y2="60%%" stroke="black" stroke-width="1" />
                <line x1="20%%" y1="60%%" x2="80%%" y2="80%%" stroke="black" stroke-width="1" />
                <line x1="80%%" y1="80%%" x2="60%%" y2="30%%" stroke="black" stroke-width="1" />
                <circle cx="60%%" cy="30%%" r="8%%" stroke="black" stroke-width="1" fill="firebrick" />
                <circle cx="20%%" cy="60%%" r="8%%" stroke="black" stroke-width="1" fill="firebrick" />
                <circle cx="80%%" cy="80%%" r="8%%" stroke="black" stroke-width="1" fill="firebrick" />
            </g>

            </svg>

            <svg width="40px" height="40px">
            <g >
                <line x1="0px" y1="50%%" x2="100%%" y2="50%%" stroke="black" stroke-width="1" />
                <line x1="50%%" y1="0px" x2="50%%" y2="100%%" stroke="black" stroke-width="1" />
                <circle cx="50%%" cy="50%%" r="20%%" stroke="black" stroke-width="1" fill="none" />
                <circle cx="50%%" cy="50%%" r="10%%" stroke="black" stroke-width="1" fill="none" />
            </g>
            </svg>

`
<|endoftext|>


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

// Package fnv implements FNV-1 and FNV-1a, non-cryptographic hash functions
// created by Glenn Fowler, Landon Curt Noll, and Phong Vo.
// See http://isthe.com/chongo/tech/comp/fnv/.
package fnv

import (
	"hash"
)

type (
	sum32  uint32
	sum32a uint32
	sum64  uint64
	sum64a uint64
)

const (
	offset32 = 2166136261
	offset64 = 14695981039346656037
	prime32  = 16777619
	prime64  = 1099511628211
)

// New32 returns a new 32-bit FNV-1 hash.Hash.
func New32() hash.Hash32 {
	var s sum32 = offset32
	return &s
}

// New32a returns a new 32-bit FNV-1a hash.Hash.
func New32a() hash.Hash32 {
	var s sum32a = offset32
	return &s
}

// New64 returns a new 64-bit FNV-1 hash.Hash.
func New64() hash.Hash64 {
	var s sum64 = offset64
	return &s
}

// New64a returns a new 64-bit FNV-1a hash.Hash.
func New64a() hash.Hash64 {
	var s sum64a = offset64
	return &s
}

func (s *sum32) Reset()  { *s = offset32 }
func (s *sum32a) Reset() { *s = offset32 }
func (s *sum64) Reset()  { *s = offset64 }
func (s *sum64a) Reset() { *s = offset64 }

func (s *sum32) Sum32() uint32  { return uint32(*s) }
func (s *sum32a) Sum32() uint32 { return uint32(*s) }
func (s *sum64) Sum64() uint64  { return uint64(*s) }
func (s *sum64a) Sum64() uint64 { return uint64(*s) }

func (s *sum32) Write(data []byte) (int, error) {
	hash := *s
	for _, c := range data {
		hash *= prime32
		hash ^= sum32(c)
	}
	*s = hash
	return len(data), nil
}

func (s *sum32a) Write(data []byte) (int, error) {
	hash := *s
	for _, c := range data {
		hash ^= sum32a(c)
		hash *= prime32
	}
	*s = hash
	return len(data), nil
}

func (s *sum64) Write(data []byte) (int, error) {
	hash := *s
	for _, c := range data {
		hash *= prime64
		hash ^= sum64(c)
	}
	*s = hash
	return len(data), nil
}

func (s *sum64a) Write(data []byte) (int, error) {
	hash := *s
	for _, c := range data {
		hash ^= sum64a(c)
		hash *= prime64
	}
	*s = hash
	return len(data), nil
}

func (s *sum32) Size() int  { return 4 }
func (s *sum32a) Size() int { return 4 }
func (s *sum64) Size() int  { return 8 }
func (s *sum64a) Size() int { return 8 }

func (s *sum32) BlockSize() int  { return 1 }
func (s *sum32a) BlockSize() int { return 1 }
func (s *sum64) BlockSize() int  { return 1 }
func (s *sum64a) BlockSize() int { return 1 }

func (s *sum32) Sum(in []byte) []byte {
	v := uint32(*s)
	return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
}

func (s *sum32a) Sum(in []byte) []byte {
	v := uint32(*s)
	return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
}

func (s *sum64) Sum(in []byte) []byte {
	v := uint64(*s)
	return append(in, byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
}

func (s *sum64a) Sum(in []byte) []byte {
	v := uint64(*s)
	return append(in, byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
}
<commit_msg>hash/fnv: fix overview link currently returning 404.<commit_after>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package fnv implements FNV-1 and FNV-1a, non-cryptographic hash functions
// created by Glenn Fowler, Landon Curt Noll, and Phong Vo.
// See
// http://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function.
package fnv

import (
	"hash"
)

type (
	sum32  uint32
	sum32a uint32
	sum64  uint64
	sum64a uint64
)

const (
	offset32 = 2166136261
	offset64 = 14695981039346656037
	prime32  = 16777619
	prime64  = 1099511628211
)

// New32 returns a new 32-bit FNV-1 hash.Hash.
func New32() hash.Hash32 {
	var s sum32 = offset32
	return &s
}

// New32a returns a new 32-bit FNV-1a hash.Hash.
func New32a() hash.Hash32 {
	var s sum32a = offset32
	return &s
}

// New64 returns a new 64-bit FNV-1 hash.Hash.
func New64() hash.Hash64 {
	var s sum64 = offset64
	return &s
}

// New64a returns a new 64-bit FNV-1a hash.Hash.
func New64a() hash.Hash64 {
	var s sum64a = offset64
	return &s
}

func (s *sum32) Reset()  { *s = offset32 }
func (s *sum32a) Reset() { *s = offset32 }
func (s *sum64) Reset()  { *s = offset64 }
func (s *sum64a) Reset() { *s = offset64 }

func (s *sum32) Sum32() uint32  { return uint32(*s) }
func (s *sum32a) Sum32() uint32 { return uint32(*s) }
func (s *sum64) Sum64() uint64  { return uint64(*s) }
func (s *sum64a) Sum64() uint64 { return uint64(*s) }

func (s *sum32) Write(data []byte) (int, error) {
	hash := *s
	for _, c := range data {
		hash *= prime32
		hash ^= sum32(c)
	}
	*s = hash
	return len(data), nil
}

func (s *sum32a) Write(data []byte) (int, error) {
	hash := *s
	for _, c := range data {
		hash ^= sum32a(c)
		hash *= prime32
	}
	*s = hash
	return len(data), nil
}

func (s *sum64) Write(data []byte) (int, error) {
	hash := *s
	for _, c := range data {
		hash *= prime64
		hash ^= sum64(c)
	}
	*s = hash
	return len(data), nil
}

func (s *sum64a) Write(data []byte) (int, error) {
	hash := *s
	for _, c := range data {
		hash ^= sum64a(c)
		hash *= prime64
	}
	*s = hash
	return len(data), nil
}

func (s *sum32) Size() int  { return 4 }
func (s *sum32a) Size() int { return 4 }
func (s *sum64) Size() int  { return 8 }
func (s *sum64a) Size() int { return 8 }

func (s *sum32) BlockSize() int  { return 1 }
func (s *sum32a) BlockSize() int { return 1 }
func (s *sum64) BlockSize() int  { return 1 }
func (s *sum64a) BlockSize() int { return 1 }

func (s *sum32) Sum(in []byte) []byte {
	v := uint32(*s)
	return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
}

func (s *sum32a) Sum(in []byte) []byte {
	v := uint32(*s)
	return append(in, byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
}

func (s *sum64) Sum(in []byte) []byte {
	v := uint64(*s)
	return append(in, byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
}

func (s *sum64a) Sum(in []byte) []byte {
	v := uint64(*s)
	return append(in, byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
}
<|endoftext|>


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

package scorch

import (
	"fmt"

	"github.com/RoaringBitmap/roaring"

	"github.com/blevesearch/bleve/index"
	"github.com/blevesearch/bleve/index/scorch/segment"
	"github.com/blevesearch/bleve/index/scorch/segment/zap"
)

func (s *IndexSnapshotTermFieldReader) Optimize(kind string,
	octx index.OptimizableContext) (index.OptimizableContext, error) {
	if kind == "conjunction" {
		return s.optimizeConjunction(octx)
	}

	if kind == "disjunction:unadorned" {
		return s.optimizeDisjunctionUnadorned(octx)
	}

	return octx, nil
}

// ----------------------------------------------------------------

func (s *IndexSnapshotTermFieldReader) optimizeConjunction(
	octx index.OptimizableContext) (index.OptimizableContext, error) {
	if octx == nil {
		octx = &OptimizeTFRConjunction{snapshot: s.snapshot}
	}

	o, ok := octx.(*OptimizeTFRConjunction)
	if !ok {
		return octx, nil
	}

	if o.snapshot != s.snapshot {
		return nil, fmt.Errorf("tried to optimize conjunction across different snapshots")
	}

	o.tfrs = append(o.tfrs, s)

	return o, nil
}

type OptimizeTFRConjunction struct {
	snapshot *IndexSnapshot

	tfrs []*IndexSnapshotTermFieldReader
}

func (o *OptimizeTFRConjunction) Finish() (index.Optimized, error) {
	if len(o.tfrs) <= 1 {
		return nil, nil
	}

	for i := range o.snapshot.segment {
		itr0, ok := o.tfrs[0].iterators[i].(*zap.PostingsIterator)
		if !ok || itr0.ActualBM == nil {
			continue
		}

		itr1, ok := o.tfrs[1].iterators[i].(*zap.PostingsIterator)
		if !ok || itr1.ActualBM == nil {
			continue
		}

		bm := roaring.And(itr0.ActualBM, itr1.ActualBM)

		for _, tfr := range o.tfrs[2:] {
			itr, ok := tfr.iterators[i].(*zap.PostingsIterator)
			if !ok || itr.ActualBM == nil {
				continue
			}

			bm.And(itr.ActualBM)
		}

		// in this conjunction optimization, the postings iterators
		// will all share the same AND'ed together actual bitmap
		for _, tfr := range o.tfrs {
			itr, ok := tfr.iterators[i].(*zap.PostingsIterator)
			if ok && itr.ActualBM != nil {
				itr.ActualBM = bm
				itr.Actual = bm.Iterator()
			}
		}
	}

	return nil, nil
}

// ----------------------------------------------------------------

// An "unadorned" disjunction optimization is appropriate when
// additional or subsidiary information like freq-norm's and
// term-vectors are not required, and instead only the internal-id's
// are needed.
func (s *IndexSnapshotTermFieldReader) optimizeDisjunctionUnadorned(
	octx index.OptimizableContext) (index.OptimizableContext, error) {
	if octx == nil {
		octx = &OptimizeTFRDisjunctionUnadorned{snapshot: s.snapshot}
	}

	o, ok := octx.(*OptimizeTFRDisjunctionUnadorned)
	if !ok {
		return nil, nil
	}

	if o.snapshot != s.snapshot {
		return nil, fmt.Errorf("tried to optimize unadorned disjunction across different snapshots")
	}

	o.tfrs = append(o.tfrs, s)

	return o, nil
}

type OptimizeTFRDisjunctionUnadorned struct {
	snapshot *IndexSnapshot

	tfrs []*IndexSnapshotTermFieldReader
}

var OptimizeTFRDisjunctionUnadornedTerm = []byte("<disjunction:unadorned>")
var OptimizeTFRDisjunctionUnadornedField = "*"

// Finish of an unadorned disjunction optimization will compute a
// termFieldReader with an "actual" bitmap that represents the
// constituent bitmaps OR'ed together.  This termFieldReader cannot
// provide any freq-norm or termVector associated information.
func (o *OptimizeTFRDisjunctionUnadorned) Finish() (rv index.Optimized, err error) {
	if len(o.tfrs) <= 1 {
		return nil, nil
	}

	// We use an artificial term and field because the optimized
	// termFieldReader can represent multiple terms and fields.
	oTFR := &IndexSnapshotTermFieldReader{
		term:               OptimizeTFRDisjunctionUnadornedTerm,
		field:              OptimizeTFRDisjunctionUnadornedField,
		snapshot:           o.snapshot,
		iterators:          make([]segment.PostingsIterator, len(o.snapshot.segment)),
		segmentOffset:      0,
		includeFreq:        false,
		includeNorm:        false,
		includeTermVectors: false,
	}

	var docNums []uint32            // Collected docNum's from 1-hit posting lists.
	var actualBMs []*roaring.Bitmap // Collected from regular posting lists.

	for i := range o.snapshot.segment {
		docNums = docNums[:0]
		actualBMs = actualBMs[:0]

		for _, tfr := range o.tfrs {
			itr, ok := tfr.iterators[i].(*zap.PostingsIterator)
			if !ok {
				return nil, nil
			}

			docNum, ok := itr.DocNum1Hit()
			if ok {
				docNums = append(docNums, uint32(docNum))
				continue
			}

			if itr.ActualBM != nil {
				actualBMs = append(actualBMs, itr.ActualBM)
			}
		}

		var bm *roaring.Bitmap
		if len(actualBMs) > 2 {
			bm = roaring.HeapOr(actualBMs...)
		} else if len(actualBMs) == 2 {
			bm = roaring.Or(actualBMs[0], actualBMs[1])
		} else if len(actualBMs) == 1 {
			bm = actualBMs[0].Clone()
		}

		if bm == nil {
			bm = roaring.New()
		}

		bm.AddMany(docNums)

		oTFR.iterators[i], err = zap.PostingsIteratorFromBitmap(bm, false, false)
		if err != nil {
			return nil, nil
		}
	}

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

package scorch

import (
	"fmt"

	"github.com/RoaringBitmap/roaring"

	"github.com/blevesearch/bleve/index"
	"github.com/blevesearch/bleve/index/scorch/segment"
	"github.com/blevesearch/bleve/index/scorch/segment/zap"
)

func (s *IndexSnapshotTermFieldReader) Optimize(kind string,
	octx index.OptimizableContext) (index.OptimizableContext, error) {
	if kind == "conjunction" {
		return s.optimizeConjunction(octx)
	}

	if kind == "disjunction:unadorned" {
		return s.optimizeDisjunctionUnadorned(octx)
	}

	return octx, nil
}

var OptimizeDisjunctionUnadornedMinChildCardinality = uint64(256)

// ----------------------------------------------------------------

func (s *IndexSnapshotTermFieldReader) optimizeConjunction(
	octx index.OptimizableContext) (index.OptimizableContext, error) {
	if octx == nil {
		octx = &OptimizeTFRConjunction{snapshot: s.snapshot}
	}

	o, ok := octx.(*OptimizeTFRConjunction)
	if !ok {
		return octx, nil
	}

	if o.snapshot != s.snapshot {
		return nil, fmt.Errorf("tried to optimize conjunction across different snapshots")
	}

	o.tfrs = append(o.tfrs, s)

	return o, nil
}

type OptimizeTFRConjunction struct {
	snapshot *IndexSnapshot

	tfrs []*IndexSnapshotTermFieldReader
}

func (o *OptimizeTFRConjunction) Finish() (index.Optimized, error) {
	if len(o.tfrs) <= 1 {
		return nil, nil
	}

	for i := range o.snapshot.segment {
		itr0, ok := o.tfrs[0].iterators[i].(*zap.PostingsIterator)
		if !ok || itr0.ActualBM == nil {
			continue
		}

		itr1, ok := o.tfrs[1].iterators[i].(*zap.PostingsIterator)
		if !ok || itr1.ActualBM == nil {
			continue
		}

		bm := roaring.And(itr0.ActualBM, itr1.ActualBM)

		for _, tfr := range o.tfrs[2:] {
			itr, ok := tfr.iterators[i].(*zap.PostingsIterator)
			if !ok || itr.ActualBM == nil {
				continue
			}

			bm.And(itr.ActualBM)
		}

		// in this conjunction optimization, the postings iterators
		// will all share the same AND'ed together actual bitmap
		for _, tfr := range o.tfrs {
			itr, ok := tfr.iterators[i].(*zap.PostingsIterator)
			if ok && itr.ActualBM != nil {
				itr.ActualBM = bm
				itr.Actual = bm.Iterator()
			}
		}
	}

	return nil, nil
}

// ----------------------------------------------------------------

// An "unadorned" disjunction optimization is appropriate when
// additional or subsidiary information like freq-norm's and
// term-vectors are not required, and instead only the internal-id's
// are needed.
func (s *IndexSnapshotTermFieldReader) optimizeDisjunctionUnadorned(
	octx index.OptimizableContext) (index.OptimizableContext, error) {
	if octx == nil {
		octx = &OptimizeTFRDisjunctionUnadorned{snapshot: s.snapshot}
	}

	o, ok := octx.(*OptimizeTFRDisjunctionUnadorned)
	if !ok {
		return nil, nil
	}

	if o.snapshot != s.snapshot {
		return nil, fmt.Errorf("tried to optimize unadorned disjunction across different snapshots")
	}

	o.tfrs = append(o.tfrs, s)

	return o, nil
}

type OptimizeTFRDisjunctionUnadorned struct {
	snapshot *IndexSnapshot

	tfrs []*IndexSnapshotTermFieldReader
}

var OptimizeTFRDisjunctionUnadornedTerm = []byte("<disjunction:unadorned>")
var OptimizeTFRDisjunctionUnadornedField = "*"

// Finish of an unadorned disjunction optimization will compute a
// termFieldReader with an "actual" bitmap that represents the
// constituent bitmaps OR'ed together.  This termFieldReader cannot
// provide any freq-norm or termVector associated information.
func (o *OptimizeTFRDisjunctionUnadorned) Finish() (rv index.Optimized, err error) {
	if len(o.tfrs) <= 1 {
		return nil, nil
	}

	for i := range o.snapshot.segment {
		var cMax uint64

		for _, tfr := range o.tfrs {
			itr, ok := tfr.iterators[i].(*zap.PostingsIterator)
			if !ok {
				return nil, nil
			}

			if itr.ActualBM != nil {
				c := itr.ActualBM.GetCardinality()
				if cMax < c {
					cMax = c
				}
			}
		}

		// Heuristic to skip the optimization if all the constituent
		// bitmaps are too small, where the processing & resource
		// overhead to create the OR'ed bitmap outweighs the benefit.
		if cMax < OptimizeDisjunctionUnadornedMinChildCardinality {
			return nil, nil
		}
	}

	// We use an artificial term and field because the optimized
	// termFieldReader can represent multiple terms and fields.
	oTFR := &IndexSnapshotTermFieldReader{
		term:               OptimizeTFRDisjunctionUnadornedTerm,
		field:              OptimizeTFRDisjunctionUnadornedField,
		snapshot:           o.snapshot,
		iterators:          make([]segment.PostingsIterator, len(o.snapshot.segment)),
		segmentOffset:      0,
		includeFreq:        false,
		includeNorm:        false,
		includeTermVectors: false,
	}

	var docNums []uint32            // Collected docNum's from 1-hit posting lists.
	var actualBMs []*roaring.Bitmap // Collected from regular posting lists.

	for i := range o.snapshot.segment {
		docNums = docNums[:0]
		actualBMs = actualBMs[:0]

		for _, tfr := range o.tfrs {
			itr, ok := tfr.iterators[i].(*zap.PostingsIterator)
			if !ok {
				return nil, nil
			}

			docNum, ok := itr.DocNum1Hit()
			if ok {
				docNums = append(docNums, uint32(docNum))
				continue
			}

			if itr.ActualBM != nil {
				actualBMs = append(actualBMs, itr.ActualBM)
			}
		}

		var bm *roaring.Bitmap
		if len(actualBMs) > 2 {
			bm = roaring.HeapOr(actualBMs...)
		} else if len(actualBMs) == 2 {
			bm = roaring.Or(actualBMs[0], actualBMs[1])
		} else if len(actualBMs) == 1 {
			bm = actualBMs[0].Clone()
		}

		if bm == nil {
			bm = roaring.New()
		}

		bm.AddMany(docNums)

		oTFR.iterators[i], err = zap.PostingsIteratorFromBitmap(bm, false, false)
		if err != nil {
			return nil, nil
		}
	}

	return oTFR, nil
}
<|endoftext|>


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

// Package exec runs external commands. It wraps os.StartProcess to make it
// easier to remap stdin and stdout, connect I/O with pipes, and do other
// adjustments.
package exec

import (
	"bytes"
	"errors"
	"io"
	"os"
	"strconv"
	"syscall"
)

// Error records the name of a binary that failed to be be executed
// and the reason it failed.
type Error struct {
	Name string
	Err  error
}

func (e *Error) Error() string {
	return "exec: " + strconv.Quote(e.Name) + ": " + e.Err.Error()
}

// Cmd represents an external command being prepared or run.
type Cmd struct {
	// Path is the path of the command to run.
	//
	// This is the only field that must be set to a non-zero
	// value.
	Path string

	// Args holds command line arguments, including the command as Args[0].
	// If the Args field is empty or nil, Run uses {Path}.
	//
	// In typical use, both Path and Args are set by calling Command.
	Args []string

	// Env specifies the environment of the process.
	// If Env is nil, Run uses the current process's environment.
	Env []string

	// Dir specifies the working directory of the command.
	// If Dir is the empty string, Run runs the command in the
	// calling process's current directory.
	Dir string

	// Stdin specifies the process's standard input.
	// If Stdin is nil, the process reads from DevNull.
	Stdin io.Reader

	// Stdout and Stderr specify the process's standard output and error.
	//
	// If either is nil, Run connects the
	// corresponding file descriptor to /dev/null.
	//
	// If Stdout and Stderr are are the same writer, at most one
	// goroutine at a time will call Write.
	Stdout io.Writer
	Stderr io.Writer

	// ExtraFiles specifies additional open files to be inherited by the
	// new process. It does not include standard input, standard output, or
	// standard error. If non-nil, entry i becomes file descriptor 3+i.
	ExtraFiles []*os.File

	// SysProcAttr holds optional, operating system-specific attributes.
	// Run passes it to os.StartProcess as the os.ProcAttr's Sys field.
	SysProcAttr *syscall.SysProcAttr

	// Process is the underlying process, once started.
	Process *os.Process

	err             error // last error (from LookPath, stdin, stdout, stderr)
	finished        bool  // when Wait was called
	childFiles      []*os.File
	closeAfterStart []io.Closer
	closeAfterWait  []io.Closer
	goroutine       []func() error
	errch           chan error // one send per goroutine
}

// Command returns the Cmd struct to execute the named program with
// the given arguments.
//
// It sets Path and Args in the returned structure and zeroes the
// other fields.
//
// If name contains no path separators, Command uses LookPath to
// resolve the path to a complete name if possible. Otherwise it uses
// name directly.
//
// The returned Cmd's Args field is constructed from the command name
// followed by the elements of arg, so arg should not include the
// command name itself. For example, Command("echo", "hello")
func Command(name string, arg ...string) *Cmd {
	aname, err := LookPath(name)
	if err != nil {
		aname = name
	}
	return &Cmd{
		Path: aname,
		Args: append([]string{name}, arg...),
		err:  err,
	}
}

// interfaceEqual protects against panics from doing equality tests on
// two interfaces with non-comparable underlying types
func interfaceEqual(a, b interface{}) bool {
	defer func() {
		recover()
	}()
	return a == b
}

func (c *Cmd) envv() []string {
	if c.Env != nil {
		return c.Env
	}
	return os.Environ()
}

func (c *Cmd) argv() []string {
	if len(c.Args) > 0 {
		return c.Args
	}
	return []string{c.Path}
}

func (c *Cmd) stdin() (f *os.File, err error) {
	if c.Stdin == nil {
		f, err = os.Open(os.DevNull)
		c.closeAfterStart = append(c.closeAfterStart, f)
		return
	}

	if f, ok := c.Stdin.(*os.File); ok {
		return f, nil
	}

	pr, pw, err := os.Pipe()
	if err != nil {
		return
	}

	c.closeAfterStart = append(c.closeAfterStart, pr)
	c.closeAfterWait = append(c.closeAfterWait, pw)
	c.goroutine = append(c.goroutine, func() error {
		_, err := io.Copy(pw, c.Stdin)
		if err1 := pw.Close(); err == nil {
			err = err1
		}
		return err
	})
	return pr, nil
}

func (c *Cmd) stdout() (f *os.File, err error) {
	return c.writerDescriptor(c.Stdout)
}

func (c *Cmd) stderr() (f *os.File, err error) {
	if c.Stderr != nil && interfaceEqual(c.Stderr, c.Stdout) {
		return c.childFiles[1], nil
	}
	return c.writerDescriptor(c.Stderr)
}

func (c *Cmd) writerDescriptor(w io.Writer) (f *os.File, err error) {
	if w == nil {
		f, err = os.OpenFile(os.DevNull, os.O_WRONLY, 0)
		c.closeAfterStart = append(c.closeAfterStart, f)
		return
	}

	if f, ok := w.(*os.File); ok {
		return f, nil
	}

	pr, pw, err := os.Pipe()
	if err != nil {
		return
	}

	c.closeAfterStart = append(c.closeAfterStart, pw)
	c.closeAfterWait = append(c.closeAfterWait, pr)
	c.goroutine = append(c.goroutine, func() error {
		_, err := io.Copy(w, pr)
		return err
	})
	return pw, nil
}

// Run starts the specified command and waits for it to complete.
//
// The returned error is nil if the command runs, has no problems
// copying stdin, stdout, and stderr, and exits with a zero exit
// status.
//
// If the command fails to run or doesn't complete successfully, the
// error is of type *ExitError. Other error types may be
// returned for I/O problems.
func (c *Cmd) Run() error {
	if err := c.Start(); err != nil {
		return err
	}
	return c.Wait()
}

// Start starts the specified command but does not wait for it to complete.
func (c *Cmd) Start() error {
	if c.err != nil {
		return c.err
	}
	if c.Process != nil {
		return errors.New("exec: already started")
	}

	type F func(*Cmd) (*os.File, error)
	for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} {
		fd, err := setupFd(c)
		if err != nil {
			return err
		}
		c.childFiles = append(c.childFiles, fd)
	}
	c.childFiles = append(c.childFiles, c.ExtraFiles...)

	var err error
	c.Process, err = os.StartProcess(c.Path, c.argv(), &os.ProcAttr{
		Dir:   c.Dir,
		Files: c.childFiles,
		Env:   c.envv(),
		Sys:   c.SysProcAttr,
	})
	if err != nil {
		return err
	}

	for _, fd := range c.closeAfterStart {
		fd.Close()
	}

	c.errch = make(chan error, len(c.goroutine))
	for _, fn := range c.goroutine {
		go func(fn func() error) {
			c.errch <- fn()
		}(fn)
	}

	return nil
}

// An ExitError reports an unsuccessful exit by a command.
type ExitError struct {
	*os.Waitmsg
}

func (e *ExitError) Error() string {
	return e.Waitmsg.String()
}

// Wait waits for the command to exit.
// It must have been started by Start.
//
// The returned error is nil if the command runs, has no problems
// copying stdin, stdout, and stderr, and exits with a zero exit
// status.
//
// If the command fails to run or doesn't complete successfully, the
// error is of type *ExitError. Other error types may be
// returned for I/O problems.
func (c *Cmd) Wait() error {
	if c.Process == nil {
		return errors.New("exec: not started")
	}
	if c.finished {
		return errors.New("exec: Wait was already called")
	}
	c.finished = true
	msg, err := c.Process.Wait(0)

	var copyError error
	for _ = range c.goroutine {
		if err := <-c.errch; err != nil && copyError == nil {
			copyError = err
		}
	}

	for _, fd := range c.closeAfterWait {
		fd.Close()
	}

	if err != nil {
		return err
	} else if !msg.Exited() || msg.ExitStatus() != 0 {
		return &ExitError{msg}
	}

	return copyError
}

// Output runs the command and returns its standard output.
func (c *Cmd) Output() ([]byte, error) {
	if c.Stdout != nil {
		return nil, errors.New("exec: Stdout already set")
	}
	var b bytes.Buffer
	c.Stdout = &b
	err := c.Run()
	return b.Bytes(), err
}

// CombinedOutput runs the command and returns its combined standard
// output and standard error.
func (c *Cmd) CombinedOutput() ([]byte, error) {
	if c.Stdout != nil {
		return nil, errors.New("exec: Stdout already set")
	}
	if c.Stderr != nil {
		return nil, errors.New("exec: Stderr already set")
	}
	var b bytes.Buffer
	c.Stdout = &b
	c.Stderr = &b
	err := c.Run()
	return b.Bytes(), err
}

// StdinPipe returns a pipe that will be connected to the command's
// standard input when the command starts.
func (c *Cmd) StdinPipe() (io.WriteCloser, error) {
	if c.Stdin != nil {
		return nil, errors.New("exec: Stdin already set")
	}
	if c.Process != nil {
		return nil, errors.New("exec: StdinPipe after process started")
	}
	pr, pw, err := os.Pipe()
	if err != nil {
		return nil, err
	}
	c.Stdin = pr
	c.closeAfterStart = append(c.closeAfterStart, pr)
	c.closeAfterWait = append(c.closeAfterWait, pw)
	return pw, nil
}

// StdoutPipe returns a pipe that will be connected to the command's
// standard output when the command starts.
// The pipe will be closed automatically after Wait sees the command exit.
func (c *Cmd) StdoutPipe() (io.ReadCloser, error) {
	if c.Stdout != nil {
		return nil, errors.New("exec: Stdout already set")
	}
	if c.Process != nil {
		return nil, errors.New("exec: StdoutPipe after process started")
	}
	pr, pw, err := os.Pipe()
	if err != nil {
		return nil, err
	}
	c.Stdout = pw
	c.closeAfterStart = append(c.closeAfterStart, pw)
	c.closeAfterWait = append(c.closeAfterWait, pr)
	return pr, nil
}

// StderrPipe returns a pipe that will be connected to the command's
// standard error when the command starts.
// The pipe will be closed automatically after Wait sees the command exit.
func (c *Cmd) StderrPipe() (io.ReadCloser, error) {
	if c.Stderr != nil {
		return nil, errors.New("exec: Stderr already set")
	}
	if c.Process != nil {
		return nil, errors.New("exec: StderrPipe after process started")
	}
	pr, pw, err := os.Pipe()
	if err != nil {
		return nil, err
	}
	c.Stderr = pw
	c.closeAfterStart = append(c.closeAfterStart, pw)
	c.closeAfterWait = append(c.closeAfterWait, pr)
	return pr, nil
}
<commit_msg>os/exec: Fix documentation references to os.DevNull<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package exec runs external commands. It wraps os.StartProcess to make it
// easier to remap stdin and stdout, connect I/O with pipes, and do other
// adjustments.
package exec

import (
	"bytes"
	"errors"
	"io"
	"os"
	"strconv"
	"syscall"
)

// Error records the name of a binary that failed to be be executed
// and the reason it failed.
type Error struct {
	Name string
	Err  error
}

func (e *Error) Error() string {
	return "exec: " + strconv.Quote(e.Name) + ": " + e.Err.Error()
}

// Cmd represents an external command being prepared or run.
type Cmd struct {
	// Path is the path of the command to run.
	//
	// This is the only field that must be set to a non-zero
	// value.
	Path string

	// Args holds command line arguments, including the command as Args[0].
	// If the Args field is empty or nil, Run uses {Path}.
	//
	// In typical use, both Path and Args are set by calling Command.
	Args []string

	// Env specifies the environment of the process.
	// If Env is nil, Run uses the current process's environment.
	Env []string

	// Dir specifies the working directory of the command.
	// If Dir is the empty string, Run runs the command in the
	// calling process's current directory.
	Dir string

	// Stdin specifies the process's standard input. If Stdin is
	// nil, the process reads from the null device (os.DevNull).
	Stdin io.Reader

	// Stdout and Stderr specify the process's standard output and error.
	//
	// If either is nil, Run connects the corresponding file descriptor
	// to the null device (os.DevNull).
	//
	// If Stdout and Stderr are are the same writer, at most one
	// goroutine at a time will call Write.
	Stdout io.Writer
	Stderr io.Writer

	// ExtraFiles specifies additional open files to be inherited by the
	// new process. It does not include standard input, standard output, or
	// standard error. If non-nil, entry i becomes file descriptor 3+i.
	ExtraFiles []*os.File

	// SysProcAttr holds optional, operating system-specific attributes.
	// Run passes it to os.StartProcess as the os.ProcAttr's Sys field.
	SysProcAttr *syscall.SysProcAttr

	// Process is the underlying process, once started.
	Process *os.Process

	err             error // last error (from LookPath, stdin, stdout, stderr)
	finished        bool  // when Wait was called
	childFiles      []*os.File
	closeAfterStart []io.Closer
	closeAfterWait  []io.Closer
	goroutine       []func() error
	errch           chan error // one send per goroutine
}

// Command returns the Cmd struct to execute the named program with
// the given arguments.
//
// It sets Path and Args in the returned structure and zeroes the
// other fields.
//
// If name contains no path separators, Command uses LookPath to
// resolve the path to a complete name if possible. Otherwise it uses
// name directly.
//
// The returned Cmd's Args field is constructed from the command name
// followed by the elements of arg, so arg should not include the
// command name itself. For example, Command("echo", "hello")
func Command(name string, arg ...string) *Cmd {
	aname, err := LookPath(name)
	if err != nil {
		aname = name
	}
	return &Cmd{
		Path: aname,
		Args: append([]string{name}, arg...),
		err:  err,
	}
}

// interfaceEqual protects against panics from doing equality tests on
// two interfaces with non-comparable underlying types
func interfaceEqual(a, b interface{}) bool {
	defer func() {
		recover()
	}()
	return a == b
}

func (c *Cmd) envv() []string {
	if c.Env != nil {
		return c.Env
	}
	return os.Environ()
}

func (c *Cmd) argv() []string {
	if len(c.Args) > 0 {
		return c.Args
	}
	return []string{c.Path}
}

func (c *Cmd) stdin() (f *os.File, err error) {
	if c.Stdin == nil {
		f, err = os.Open(os.DevNull)
		c.closeAfterStart = append(c.closeAfterStart, f)
		return
	}

	if f, ok := c.Stdin.(*os.File); ok {
		return f, nil
	}

	pr, pw, err := os.Pipe()
	if err != nil {
		return
	}

	c.closeAfterStart = append(c.closeAfterStart, pr)
	c.closeAfterWait = append(c.closeAfterWait, pw)
	c.goroutine = append(c.goroutine, func() error {
		_, err := io.Copy(pw, c.Stdin)
		if err1 := pw.Close(); err == nil {
			err = err1
		}
		return err
	})
	return pr, nil
}

func (c *Cmd) stdout() (f *os.File, err error) {
	return c.writerDescriptor(c.Stdout)
}

func (c *Cmd) stderr() (f *os.File, err error) {
	if c.Stderr != nil && interfaceEqual(c.Stderr, c.Stdout) {
		return c.childFiles[1], nil
	}
	return c.writerDescriptor(c.Stderr)
}

func (c *Cmd) writerDescriptor(w io.Writer) (f *os.File, err error) {
	if w == nil {
		f, err = os.OpenFile(os.DevNull, os.O_WRONLY, 0)
		c.closeAfterStart = append(c.closeAfterStart, f)
		return
	}

	if f, ok := w.(*os.File); ok {
		return f, nil
	}

	pr, pw, err := os.Pipe()
	if err != nil {
		return
	}

	c.closeAfterStart = append(c.closeAfterStart, pw)
	c.closeAfterWait = append(c.closeAfterWait, pr)
	c.goroutine = append(c.goroutine, func() error {
		_, err := io.Copy(w, pr)
		return err
	})
	return pw, nil
}

// Run starts the specified command and waits for it to complete.
//
// The returned error is nil if the command runs, has no problems
// copying stdin, stdout, and stderr, and exits with a zero exit
// status.
//
// If the command fails to run or doesn't complete successfully, the
// error is of type *ExitError. Other error types may be
// returned for I/O problems.
func (c *Cmd) Run() error {
	if err := c.Start(); err != nil {
		return err
	}
	return c.Wait()
}

// Start starts the specified command but does not wait for it to complete.
func (c *Cmd) Start() error {
	if c.err != nil {
		return c.err
	}
	if c.Process != nil {
		return errors.New("exec: already started")
	}

	type F func(*Cmd) (*os.File, error)
	for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} {
		fd, err := setupFd(c)
		if err != nil {
			return err
		}
		c.childFiles = append(c.childFiles, fd)
	}
	c.childFiles = append(c.childFiles, c.ExtraFiles...)

	var err error
	c.Process, err = os.StartProcess(c.Path, c.argv(), &os.ProcAttr{
		Dir:   c.Dir,
		Files: c.childFiles,
		Env:   c.envv(),
		Sys:   c.SysProcAttr,
	})
	if err != nil {
		return err
	}

	for _, fd := range c.closeAfterStart {
		fd.Close()
	}

	c.errch = make(chan error, len(c.goroutine))
	for _, fn := range c.goroutine {
		go func(fn func() error) {
			c.errch <- fn()
		}(fn)
	}

	return nil
}

// An ExitError reports an unsuccessful exit by a command.
type ExitError struct {
	*os.Waitmsg
}

func (e *ExitError) Error() string {
	return e.Waitmsg.String()
}

// Wait waits for the command to exit.
// It must have been started by Start.
//
// The returned error is nil if the command runs, has no problems
// copying stdin, stdout, and stderr, and exits with a zero exit
// status.
//
// If the command fails to run or doesn't complete successfully, the
// error is of type *ExitError. Other error types may be
// returned for I/O problems.
func (c *Cmd) Wait() error {
	if c.Process == nil {
		return errors.New("exec: not started")
	}
	if c.finished {
		return errors.New("exec: Wait was already called")
	}
	c.finished = true
	msg, err := c.Process.Wait(0)

	var copyError error
	for _ = range c.goroutine {
		if err := <-c.errch; err != nil && copyError == nil {
			copyError = err
		}
	}

	for _, fd := range c.closeAfterWait {
		fd.Close()
	}

	if err != nil {
		return err
	} else if !msg.Exited() || msg.ExitStatus() != 0 {
		return &ExitError{msg}
	}

	return copyError
}

// Output runs the command and returns its standard output.
func (c *Cmd) Output() ([]byte, error) {
	if c.Stdout != nil {
		return nil, errors.New("exec: Stdout already set")
	}
	var b bytes.Buffer
	c.Stdout = &b
	err := c.Run()
	return b.Bytes(), err
}

// CombinedOutput runs the command and returns its combined standard
// output and standard error.
func (c *Cmd) CombinedOutput() ([]byte, error) {
	if c.Stdout != nil {
		return nil, errors.New("exec: Stdout already set")
	}
	if c.Stderr != nil {
		return nil, errors.New("exec: Stderr already set")
	}
	var b bytes.Buffer
	c.Stdout = &b
	c.Stderr = &b
	err := c.Run()
	return b.Bytes(), err
}

// StdinPipe returns a pipe that will be connected to the command's
// standard input when the command starts.
func (c *Cmd) StdinPipe() (io.WriteCloser, error) {
	if c.Stdin != nil {
		return nil, errors.New("exec: Stdin already set")
	}
	if c.Process != nil {
		return nil, errors.New("exec: StdinPipe after process started")
	}
	pr, pw, err := os.Pipe()
	if err != nil {
		return nil, err
	}
	c.Stdin = pr
	c.closeAfterStart = append(c.closeAfterStart, pr)
	c.closeAfterWait = append(c.closeAfterWait, pw)
	return pw, nil
}

// StdoutPipe returns a pipe that will be connected to the command's
// standard output when the command starts.
// The pipe will be closed automatically after Wait sees the command exit.
func (c *Cmd) StdoutPipe() (io.ReadCloser, error) {
	if c.Stdout != nil {
		return nil, errors.New("exec: Stdout already set")
	}
	if c.Process != nil {
		return nil, errors.New("exec: StdoutPipe after process started")
	}
	pr, pw, err := os.Pipe()
	if err != nil {
		return nil, err
	}
	c.Stdout = pw
	c.closeAfterStart = append(c.closeAfterStart, pw)
	c.closeAfterWait = append(c.closeAfterWait, pr)
	return pr, nil
}

// StderrPipe returns a pipe that will be connected to the command's
// standard error when the command starts.
// The pipe will be closed automatically after Wait sees the command exit.
func (c *Cmd) StderrPipe() (io.ReadCloser, error) {
	if c.Stderr != nil {
		return nil, errors.New("exec: Stderr already set")
	}
	if c.Process != nil {
		return nil, errors.New("exec: StderrPipe after process started")
	}
	pr, pw, err := os.Pipe()
	if err != nil {
		return nil, err
	}
	c.Stderr = pw
	c.closeAfterStart = append(c.closeAfterStart, pw)
	c.closeAfterWait = append(c.closeAfterWait, pr)
	return pr, nil
}
<|endoftext|>


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

// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris

package os

import (
	"runtime"
	"sync/atomic"
	"syscall"
)

// File represents an open file descriptor.
type File struct {
	*file
}

// file is the real representation of *File.
// The extra level of indirection ensures that no clients of os
// can overwrite this data, which could cause the finalizer
// to close the wrong file descriptor.
type file struct {
	fd      int
	name    string
	dirinfo *dirInfo // nil unless directory being read
	nepipe  int32    // number of consecutive EPIPE in Write
}

// Fd returns the integer Unix file descriptor referencing the open file.
func (f *File) Fd() uintptr {
	if f == nil {
		return ^(uintptr(0))
	}
	return uintptr(f.fd)
}

// NewFile returns a new File with the given file descriptor and name.
func NewFile(fd uintptr, name string) *File {
	fdi := int(fd)
	if fdi < 0 {
		return nil
	}
	f := &File{&file{fd: fdi, name: name}}
	runtime.SetFinalizer(f.file, (*file).close)
	return f
}

// Auxiliary information if the File describes a directory
type dirInfo struct {
	buf  []byte // buffer for directory I/O
	nbuf int    // length of buf; return value from Getdirentries
	bufp int    // location of next record in buf.
}

func epipecheck(file *File, e error) {
	if e == syscall.EPIPE {
		if atomic.AddInt32(&file.nepipe, 1) >= 10 {
			sigpipe()
		}
	} else {
		atomic.StoreInt32(&file.nepipe, 0)
	}
}

// DevNull is the name of the operating system's ``null device.''
// On Unix-like systems, it is "/dev/null"; on Windows, "NUL".
const DevNull = "/dev/null"

// OpenFile is the generalized open call; most users will use Open
// or Create instead.  It opens the named file with specified flag
// (O_RDONLY etc.) and perm, (0666 etc.) if applicable.  If successful,
// methods on the returned File can be used for I/O.
// If there is an error, it will be of type *PathError.
func OpenFile(name string, flag int, perm FileMode) (file *File, err error) {
	r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
	if e != nil {
		return nil, &PathError{"open", name, e}
	}

	// There's a race here with fork/exec, which we are
	// content to live with.  See ../syscall/exec_unix.go.
	if !supportsCloseOnExec {
		syscall.CloseOnExec(r)
	}

	return NewFile(uintptr(r), name), nil
}

// Close closes the File, rendering it unusable for I/O.
// It returns an error, if any.
func (f *File) Close() error {
	if f == nil {
		return ErrInvalid
	}
	return f.file.close()
}

func (file *file) close() error {
	if file == nil || file.fd < 0 {
		return syscall.EINVAL
	}
	var err error
	if e := syscall.Close(file.fd); e != nil {
		err = &PathError{"close", file.name, e}
	}
	file.fd = -1 // so it can't be closed again

	// no need for a finalizer anymore
	runtime.SetFinalizer(file, nil)
	return err
}

// Stat returns the FileInfo structure describing file.
// If there is an error, it will be of type *PathError.
func (f *File) Stat() (fi FileInfo, err error) {
	if f == nil {
		return nil, ErrInvalid
	}
	var stat syscall.Stat_t
	err = syscall.Fstat(f.fd, &stat)
	if err != nil {
		return nil, &PathError{"stat", f.name, err}
	}
	return fileInfoFromStat(&stat, f.name), nil
}

// Stat returns a FileInfo describing the named file.
// If there is an error, it will be of type *PathError.
func Stat(name string) (fi FileInfo, err error) {
	var stat syscall.Stat_t
	err = syscall.Stat(name, &stat)
	if err != nil {
		return nil, &PathError{"stat", name, err}
	}
	return fileInfoFromStat(&stat, name), nil
}

// Lstat returns a FileInfo describing the named file.
// If the file is a symbolic link, the returned FileInfo
// describes the symbolic link.  Lstat makes no attempt to follow the link.
// If there is an error, it will be of type *PathError.
func Lstat(name string) (fi FileInfo, err error) {
	var stat syscall.Stat_t
	err = syscall.Lstat(name, &stat)
	if err != nil {
		return nil, &PathError{"lstat", name, err}
	}
	return fileInfoFromStat(&stat, name), nil
}

func (f *File) readdir(n int) (fi []FileInfo, err error) {
	dirname := f.name
	if dirname == "" {
		dirname = "."
	}
	names, err := f.Readdirnames(n)
	fi = make([]FileInfo, 0, len(names))
	for _, filename := range names {
		fip, lerr := lstat(dirname + "/" + filename)
		if IsNotExist(lerr) {
			// File disappeared between readdir + stat.
			// Just treat it as if it didn't exist.
			continue
		}
		if lerr != nil {
			return fi, lerr
		}
		fi = append(fi, fip)
	}
	return fi, err
}

// Darwin and FreeBSD can't read or write 2GB+ at a time,
// even on 64-bit systems. See golang.org/issue/7812.
// Use 1GB instead of, say, 2GB-1, to keep subsequent
// reads aligned.
const (
	needsMaxRW = runtime.GOOS == "darwin" || runtime.GOOS == "freebsd"
	maxRW      = 1 << 30
)

// read reads up to len(b) bytes from the File.
// It returns the number of bytes read and an error, if any.
func (f *File) read(b []byte) (n int, err error) {
	if needsMaxRW && len(b) > maxRW {
		b = b[:maxRW]
	}
	return syscall.Read(f.fd, b)
}

// pread reads len(b) bytes from the File starting at byte offset off.
// It returns the number of bytes read and the error, if any.
// EOF is signaled by a zero count with err set to nil.
func (f *File) pread(b []byte, off int64) (n int, err error) {
	if needsMaxRW && len(b) > maxRW {
		b = b[:maxRW]
	}
	return syscall.Pread(f.fd, b, off)
}

// write writes len(b) bytes to the File.
// It returns the number of bytes written and an error, if any.
func (f *File) write(b []byte) (n int, err error) {
	for {
		bcap := b
		if needsMaxRW && len(bcap) > maxRW {
			bcap = bcap[:maxRW]
		}
		m, err := syscall.Write(f.fd, bcap)
		n += m

		// If the syscall wrote some data but not all (short write)
		// or it returned EINTR, then assume it stopped early for
		// reasons that are uninteresting to the caller, and try again.
		if 0 < m && m < len(bcap) || err == syscall.EINTR {
			b = b[m:]
			continue
		}

		if needsMaxRW && len(bcap) != len(b) && err == nil {
			b = b[m:]
			continue
		}

		return n, err
	}
}

// pwrite writes len(b) bytes to the File starting at byte offset off.
// It returns the number of bytes written and an error, if any.
func (f *File) pwrite(b []byte, off int64) (n int, err error) {
	if needsMaxRW && len(b) > maxRW {
		b = b[:maxRW]
	}
	return syscall.Pwrite(f.fd, b, off)
}

// seek sets the offset for the next Read or Write on file to offset, interpreted
// according to whence: 0 means relative to the origin of the file, 1 means
// relative to the current offset, and 2 means relative to the end.
// It returns the new offset and an error, if any.
func (f *File) seek(offset int64, whence int) (ret int64, err error) {
	return syscall.Seek(f.fd, offset, whence)
}

// Truncate changes the size of the named file.
// If the file is a symbolic link, it changes the size of the link's target.
// If there is an error, it will be of type *PathError.
func Truncate(name string, size int64) error {
	if e := syscall.Truncate(name, size); e != nil {
		return &PathError{"truncate", name, e}
	}
	return nil
}

// Remove removes the named file or directory.
// If there is an error, it will be of type *PathError.
func Remove(name string) error {
	// System call interface forces us to know
	// whether name is a file or directory.
	// Try both: it is cheaper on average than
	// doing a Stat plus the right one.
	e := syscall.Unlink(name)
	if e == nil {
		return nil
	}
	e1 := syscall.Rmdir(name)
	if e1 == nil {
		return nil
	}

	// Both failed: figure out which error to return.
	// OS X and Linux differ on whether unlink(dir)
	// returns EISDIR, so can't use that.  However,
	// both agree that rmdir(file) returns ENOTDIR,
	// so we can use that to decide which error is real.
	// Rmdir might also return ENOTDIR if given a bad
	// file path, like /etc/passwd/foo, but in that case,
	// both errors will be ENOTDIR, so it's okay to
	// use the error from unlink.
	if e1 != syscall.ENOTDIR {
		e = e1
	}
	return &PathError{"remove", name, e}
}

// basename removes trailing slashes and the leading directory name from path name
func basename(name string) string {
	i := len(name) - 1
	// Remove trailing slashes
	for ; i > 0 && name[i] == '/'; i-- {
		name = name[:i]
	}
	// Remove leading directory name
	for i--; i >= 0; i-- {
		if name[i] == '/' {
			name = name[i+1:]
			break
		}
	}

	return name
}

// TempDir returns the default directory to use for temporary files.
func TempDir() string {
	dir := Getenv("TMPDIR")
	if dir == "" {
		dir = "/tmp"
	}
	return dir
}
<commit_msg>os: no /tmp on android<commit_after>// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build darwin dragonfly freebsd linux nacl netbsd openbsd solaris

package os

import (
	"runtime"
	"sync/atomic"
	"syscall"
)

// File represents an open file descriptor.
type File struct {
	*file
}

// file is the real representation of *File.
// The extra level of indirection ensures that no clients of os
// can overwrite this data, which could cause the finalizer
// to close the wrong file descriptor.
type file struct {
	fd      int
	name    string
	dirinfo *dirInfo // nil unless directory being read
	nepipe  int32    // number of consecutive EPIPE in Write
}

// Fd returns the integer Unix file descriptor referencing the open file.
func (f *File) Fd() uintptr {
	if f == nil {
		return ^(uintptr(0))
	}
	return uintptr(f.fd)
}

// NewFile returns a new File with the given file descriptor and name.
func NewFile(fd uintptr, name string) *File {
	fdi := int(fd)
	if fdi < 0 {
		return nil
	}
	f := &File{&file{fd: fdi, name: name}}
	runtime.SetFinalizer(f.file, (*file).close)
	return f
}

// Auxiliary information if the File describes a directory
type dirInfo struct {
	buf  []byte // buffer for directory I/O
	nbuf int    // length of buf; return value from Getdirentries
	bufp int    // location of next record in buf.
}

func epipecheck(file *File, e error) {
	if e == syscall.EPIPE {
		if atomic.AddInt32(&file.nepipe, 1) >= 10 {
			sigpipe()
		}
	} else {
		atomic.StoreInt32(&file.nepipe, 0)
	}
}

// DevNull is the name of the operating system's ``null device.''
// On Unix-like systems, it is "/dev/null"; on Windows, "NUL".
const DevNull = "/dev/null"

// OpenFile is the generalized open call; most users will use Open
// or Create instead.  It opens the named file with specified flag
// (O_RDONLY etc.) and perm, (0666 etc.) if applicable.  If successful,
// methods on the returned File can be used for I/O.
// If there is an error, it will be of type *PathError.
func OpenFile(name string, flag int, perm FileMode) (file *File, err error) {
	r, e := syscall.Open(name, flag|syscall.O_CLOEXEC, syscallMode(perm))
	if e != nil {
		return nil, &PathError{"open", name, e}
	}

	// There's a race here with fork/exec, which we are
	// content to live with.  See ../syscall/exec_unix.go.
	if !supportsCloseOnExec {
		syscall.CloseOnExec(r)
	}

	return NewFile(uintptr(r), name), nil
}

// Close closes the File, rendering it unusable for I/O.
// It returns an error, if any.
func (f *File) Close() error {
	if f == nil {
		return ErrInvalid
	}
	return f.file.close()
}

func (file *file) close() error {
	if file == nil || file.fd < 0 {
		return syscall.EINVAL
	}
	var err error
	if e := syscall.Close(file.fd); e != nil {
		err = &PathError{"close", file.name, e}
	}
	file.fd = -1 // so it can't be closed again

	// no need for a finalizer anymore
	runtime.SetFinalizer(file, nil)
	return err
}

// Stat returns the FileInfo structure describing file.
// If there is an error, it will be of type *PathError.
func (f *File) Stat() (fi FileInfo, err error) {
	if f == nil {
		return nil, ErrInvalid
	}
	var stat syscall.Stat_t
	err = syscall.Fstat(f.fd, &stat)
	if err != nil {
		return nil, &PathError{"stat", f.name, err}
	}
	return fileInfoFromStat(&stat, f.name), nil
}

// Stat returns a FileInfo describing the named file.
// If there is an error, it will be of type *PathError.
func Stat(name string) (fi FileInfo, err error) {
	var stat syscall.Stat_t
	err = syscall.Stat(name, &stat)
	if err != nil {
		return nil, &PathError{"stat", name, err}
	}
	return fileInfoFromStat(&stat, name), nil
}

// Lstat returns a FileInfo describing the named file.
// If the file is a symbolic link, the returned FileInfo
// describes the symbolic link.  Lstat makes no attempt to follow the link.
// If there is an error, it will be of type *PathError.
func Lstat(name string) (fi FileInfo, err error) {
	var stat syscall.Stat_t
	err = syscall.Lstat(name, &stat)
	if err != nil {
		return nil, &PathError{"lstat", name, err}
	}
	return fileInfoFromStat(&stat, name), nil
}

func (f *File) readdir(n int) (fi []FileInfo, err error) {
	dirname := f.name
	if dirname == "" {
		dirname = "."
	}
	names, err := f.Readdirnames(n)
	fi = make([]FileInfo, 0, len(names))
	for _, filename := range names {
		fip, lerr := lstat(dirname + "/" + filename)
		if IsNotExist(lerr) {
			// File disappeared between readdir + stat.
			// Just treat it as if it didn't exist.
			continue
		}
		if lerr != nil {
			return fi, lerr
		}
		fi = append(fi, fip)
	}
	return fi, err
}

// Darwin and FreeBSD can't read or write 2GB+ at a time,
// even on 64-bit systems. See golang.org/issue/7812.
// Use 1GB instead of, say, 2GB-1, to keep subsequent
// reads aligned.
const (
	needsMaxRW = runtime.GOOS == "darwin" || runtime.GOOS == "freebsd"
	maxRW      = 1 << 30
)

// read reads up to len(b) bytes from the File.
// It returns the number of bytes read and an error, if any.
func (f *File) read(b []byte) (n int, err error) {
	if needsMaxRW && len(b) > maxRW {
		b = b[:maxRW]
	}
	return syscall.Read(f.fd, b)
}

// pread reads len(b) bytes from the File starting at byte offset off.
// It returns the number of bytes read and the error, if any.
// EOF is signaled by a zero count with err set to nil.
func (f *File) pread(b []byte, off int64) (n int, err error) {
	if needsMaxRW && len(b) > maxRW {
		b = b[:maxRW]
	}
	return syscall.Pread(f.fd, b, off)
}

// write writes len(b) bytes to the File.
// It returns the number of bytes written and an error, if any.
func (f *File) write(b []byte) (n int, err error) {
	for {
		bcap := b
		if needsMaxRW && len(bcap) > maxRW {
			bcap = bcap[:maxRW]
		}
		m, err := syscall.Write(f.fd, bcap)
		n += m

		// If the syscall wrote some data but not all (short write)
		// or it returned EINTR, then assume it stopped early for
		// reasons that are uninteresting to the caller, and try again.
		if 0 < m && m < len(bcap) || err == syscall.EINTR {
			b = b[m:]
			continue
		}

		if needsMaxRW && len(bcap) != len(b) && err == nil {
			b = b[m:]
			continue
		}

		return n, err
	}
}

// pwrite writes len(b) bytes to the File starting at byte offset off.
// It returns the number of bytes written and an error, if any.
func (f *File) pwrite(b []byte, off int64) (n int, err error) {
	if needsMaxRW && len(b) > maxRW {
		b = b[:maxRW]
	}
	return syscall.Pwrite(f.fd, b, off)
}

// seek sets the offset for the next Read or Write on file to offset, interpreted
// according to whence: 0 means relative to the origin of the file, 1 means
// relative to the current offset, and 2 means relative to the end.
// It returns the new offset and an error, if any.
func (f *File) seek(offset int64, whence int) (ret int64, err error) {
	return syscall.Seek(f.fd, offset, whence)
}

// Truncate changes the size of the named file.
// If the file is a symbolic link, it changes the size of the link's target.
// If there is an error, it will be of type *PathError.
func Truncate(name string, size int64) error {
	if e := syscall.Truncate(name, size); e != nil {
		return &PathError{"truncate", name, e}
	}
	return nil
}

// Remove removes the named file or directory.
// If there is an error, it will be of type *PathError.
func Remove(name string) error {
	// System call interface forces us to know
	// whether name is a file or directory.
	// Try both: it is cheaper on average than
	// doing a Stat plus the right one.
	e := syscall.Unlink(name)
	if e == nil {
		return nil
	}
	e1 := syscall.Rmdir(name)
	if e1 == nil {
		return nil
	}

	// Both failed: figure out which error to return.
	// OS X and Linux differ on whether unlink(dir)
	// returns EISDIR, so can't use that.  However,
	// both agree that rmdir(file) returns ENOTDIR,
	// so we can use that to decide which error is real.
	// Rmdir might also return ENOTDIR if given a bad
	// file path, like /etc/passwd/foo, but in that case,
	// both errors will be ENOTDIR, so it's okay to
	// use the error from unlink.
	if e1 != syscall.ENOTDIR {
		e = e1
	}
	return &PathError{"remove", name, e}
}

// basename removes trailing slashes and the leading directory name from path name
func basename(name string) string {
	i := len(name) - 1
	// Remove trailing slashes
	for ; i > 0 && name[i] == '/'; i-- {
		name = name[:i]
	}
	// Remove leading directory name
	for i--; i >= 0; i-- {
		if name[i] == '/' {
			name = name[i+1:]
			break
		}
	}

	return name
}

// TempDir returns the default directory to use for temporary files.
func TempDir() string {
	dir := Getenv("TMPDIR")
	if dir == "" {
		if runtime.GOOS == "android" {
			dir = "/data/local/tmp"
		} else {
			dir = "/tmp"
		}
	}
	return dir
}
<|endoftext|>