<commit_before>//
// Code used in populating JSON objects to generating Keybase-style
// signatures.
//
package libkb

import (
	"fmt"
	"github.com/keybase/go-jsonw"
	"time"
)

func ClientId() *jsonw.Wrapper {
	ret := jsonw.NewDictionary()
	ret.SetKey("version", jsonw.NewString(CLIENT_VERSION))
	ret.SetKey("name", jsonw.NewString(GO_CLIENT_ID))
	return ret
}

func (u *User) ToTrackingStatementKey(errp *error) *jsonw.Wrapper {
	ret := jsonw.NewDictionary()

	if !u.HasActiveKey() {
		*errp = fmt.Errorf("User %s doesn't have an active key")
	} else {
		fokid := u.GetEldestFOKID()
		ret.SetKey("kid", jsonw.NewString(fokid.Kid.String()))
		if fokid.Fp != nil {
			ret.SetKey("key_fingerprint", jsonw.NewString(fokid.Fp.String()))
		}
	}
	return ret
}

func (u *User) ToTrackingStatementBasics(errp *error) *jsonw.Wrapper {
	ret := jsonw.NewDictionary()
	ret.SetKey("username", jsonw.NewString(u.name))
	if last_id_change, err := u.basics.AtKey("last_id_change").GetInt(); err == nil {
		ret.SetKey("last_id_change", jsonw.NewInt(last_id_change))
	}
	if id_version, err := u.basics.AtKey("id_version").GetInt(); err == nil {
		ret.SetKey("id_version", jsonw.NewInt(id_version))
	}
	return ret
}

func (u *User) ToTrackingStatementSeqTail() *jsonw.Wrapper {
	return u.sigs.AtKey("last")
}

func (u *User) ToTrackingStatement(w *jsonw.Wrapper) (err error) {

	track := jsonw.NewDictionary()
	track.SetKey("key", u.ToTrackingStatementKey(&err))
	track.SetKey("seq_tail", u.ToTrackingStatementSeqTail())
	track.SetKey("basics", u.ToTrackingStatementBasics(&err))
	track.SetKey("id", jsonw.NewString(u.id.String()))
	track.SetKey("remote_proofs", u.IdTable.ToTrackingStatement())

	if err != nil {
		return
	}

	w.SetKey("type", jsonw.NewString("track"))
	w.SetKey("version", jsonw.NewInt(KEYBASE_SIGNATURE_V1))
	w.SetKey("track", track)
	return
}

func (u *User) ToKeyStanza(sk GenericKey, eldest *FOKID) (ret *jsonw.Wrapper, err error) {
	ret = jsonw.NewDictionary()
	ret.SetKey("uid", jsonw.NewString(u.id.String()))
	ret.SetKey("username", jsonw.NewString(u.name))
	ret.SetKey("host", jsonw.NewString(CANONICAL_HOST))

	if eldest == nil {
		eldest = u.GetEldestFOKID()
	}

	var signingKid KID
	if sk != nil {
		signingKid = sk.GetKid()
	} else if signingKid = G.Env.GetPerDeviceKID(); signingKid == nil {
		err = NoSecretKeyError{}
		return
	}

	if sk != nil {
		if fp := sk.GetFingerprintP(); fp != nil {
			ret.SetKey("fingerprint", jsonw.NewString(fp.String()))
			ret.SetKey("key_id", jsonw.NewString(fp.ToKeyId()))
		}
	}

	ret.SetKey("kid", jsonw.NewString(signingKid.String()))
	if eldest != nil {
		ret.SetKey("eldest_kid", jsonw.NewString(eldest.Kid.String()))
	}

	return
}

func (s *SocialProofChainLink) ToTrackingStatement() (*jsonw.Wrapper, error) {
	ret := s.BaseToTrackingStatement()
	err := remoteProofToTrackingStatement(s, ret)
	if err != nil {
		ret = nil
	}
	return ret, err
}

func (idt *IdentityTable) ToTrackingStatement() *jsonw.Wrapper {
	v := idt.activeProofs
	tmp := make([]*jsonw.Wrapper, 0, len(v))
	for _, proof := range v {
		if d, err := proof.ToTrackingStatement(); err != nil {
			G.Log.Warning("Problem with a proof: %s", err.Error())
		} else if d != nil {
			tmp = append(tmp, d)
		}
	}
	ret := jsonw.NewArray(len(tmp))
	for i, d := range tmp {
		ret.SetIndex(i, d)
	}
	return ret
}

func (g *GenericChainLink) BaseToTrackingStatement() *jsonw.Wrapper {
	ret := jsonw.NewDictionary()
	ret.SetKey("curr", jsonw.NewString(g.id.String()))
	ret.SetKey("sig_id", jsonw.NewString(g.GetSigId().ToString(true)))

	rkp := jsonw.NewDictionary()
	ret.SetKey("remote_key_proof", rkp)
	rkp.SetKey("state", jsonw.NewInt(g.GetProofState()))

	prev := g.GetPrev()
	var prev_val *jsonw.Wrapper
	if prev == nil {
		prev_val = jsonw.NewNil()
	} else {
		prev_val = jsonw.NewString(prev.String())
	}

	ret.SetKey("prev", prev_val)
	ret.SetKey("ctime", jsonw.NewInt64(g.unpacked.ctime))
	ret.SetKey("etime", jsonw.NewInt64(g.unpacked.etime))
	return ret
}

func remoteProofToTrackingStatement(s RemoteProofChainLink, base *jsonw.Wrapper) error {
	typ_s := s.TableKey()
	if i, found := REMOTE_SERVICE_TYPES[typ_s]; !found {
		return fmt.Errorf("No service type found for '%s' in proof %d",
			typ_s, s.GetSeqno())
	} else {
		base.AtKey("remote_key_proof").SetKey("proof_type", jsonw.NewInt(i))
	}
	base.AtKey("remote_key_proof").SetKey("check_data_json", s.CheckDataJson())
	base.SetKey("sig_type", jsonw.NewInt(SIG_TYPE_REMOTE_PROOF))
	return nil
}

func (u *User) ProofMetadata(ei int, signingKey GenericKey, eldest *FOKID) (ret *jsonw.Wrapper, err error) {

	var seqno int
	var prev_s string
	var key, prev *jsonw.Wrapper

	last_seqno := u.sigChain.GetLastKnownSeqno()
	last_link := u.sigChain.GetLastKnownId()
	if last_link == nil {
		seqno = 1
		prev = jsonw.NewNil()
	} else {
		seqno = int(last_seqno) + 1
		prev_s = last_link.String()
		prev = jsonw.NewString(prev_s)
	}

	if ei == 0 {
		ei = SIG_EXPIRE_IN
	}

	ret = jsonw.NewDictionary()
	ret.SetKey("tag", jsonw.NewString("signature"))
	ret.SetKey("ctime", jsonw.NewInt64(time.Now().Unix()))
	ret.SetKey("expire_in", jsonw.NewInt(ei))
	ret.SetKey("seqno", jsonw.NewInt(seqno))
	ret.SetKey("prev", prev)

	body := jsonw.NewDictionary()
	key, err = u.ToKeyStanza(signingKey, eldest)
	if err != nil {
		ret = nil
		return
	}
	body.SetKey("key", key)
	ret.SetKey("body", body)

	return
}

func (u1 *User) TrackingProofFor(signingKey GenericKey, u2 *User) (ret *jsonw.Wrapper, err error) {
	ret, err = u1.ProofMetadata(0, signingKey, nil)
	if err == nil {
		err = u2.ToTrackingStatement(ret.AtKey("body"))
	}
	return
}

func (u *User) SelfProof(signingKey GenericKey, eldest *FOKID) (ret *jsonw.Wrapper, err error) {
	ret, err = u.ProofMetadata(0, signingKey, eldest)
	if err == nil {
		body := ret.AtKey("body")
		body.SetKey("version", jsonw.NewInt(KEYBASE_SIGNATURE_V1))
		body.SetKey("type", jsonw.NewString("web_service_binding"))
	}
	return
}

func (u *User) ServiceProof(signingKey GenericKey, typ ServiceType, remotename string) (ret *jsonw.Wrapper, err error) {
	ret, err = u.SelfProof(signingKey, nil)
	if err != nil {
		return
	}
	ret.AtKey("body").SetKey("service", typ.ToServiceJson(remotename))
	return
}

// SimpleSignJson marshals the given Json structure and then signs it.
func SignJson(jw *jsonw.Wrapper, key GenericKey) (out string, id *SigId, lid LinkId, err error) {
	var tmp []byte
	if tmp, err = jw.Marshal(); err != nil {
		return
	}
	out, id, err = key.SignToString(tmp)
	lid = ComputeLinkId(tmp)
	return
}

func KeyToProofJson(key GenericKey) *jsonw.Wrapper {
	d := jsonw.NewDictionary()
	d.SetKey("kid", jsonw.NewString(key.GetKid().String()))
	return d
}

func (u *User) KeyProof(newkey GenericKey, signingkey GenericKey, typ string, ei int, device *Device) (ret *jsonw.Wrapper, err error) {
	ret, err = u.ProofMetadata(ei, signingkey, nil)
	if err != nil {
		return
	}
	body := ret.AtKey("body")
	body.SetKey("version", jsonw.NewInt(KEYBASE_SIGNATURE_V1))
	body.SetKey("type", jsonw.NewString(typ))

	if device != nil {
		kid := newkey.GetKid().String()
		device.Kid = &kid
		body.SetKey("device", device.Export())
	}

	kp := KeyToProofJson(newkey)
	if typ == SIBKEY_TYPE && newkey.CanSign() {
		rsig_json := jsonw.NewDictionary()
		rsig_json.SetKey("reverse_key_sig", jsonw.NewString(signingkey.GetKid().String()))
		var rsig string
		if rsig, _, _, err = SignJson(rsig_json, newkey); err != nil {
			return
		}
		rsig_dict := jsonw.NewDictionary()
		rsig_dict.SetKey("sig", jsonw.NewString(rsig))
		rsig_dict.SetKey("type", jsonw.NewString("kb"))
		kp.SetKey("reverse_sig", rsig_dict)
	}
	// 'typ' can be 'subkey' or 'sibkey'
	body.SetKey(typ, kp)
	return
}
<commit_msg>Sign parent_kid into signature for subkeys<commit_after>//
// Code used in populating JSON objects to generating Keybase-style
// signatures.
//
package libkb

import (
	"fmt"
	"github.com/keybase/go-jsonw"
	"time"
)

func ClientId() *jsonw.Wrapper {
	ret := jsonw.NewDictionary()
	ret.SetKey("version", jsonw.NewString(CLIENT_VERSION))
	ret.SetKey("name", jsonw.NewString(GO_CLIENT_ID))
	return ret
}

func (u *User) ToTrackingStatementKey(errp *error) *jsonw.Wrapper {
	ret := jsonw.NewDictionary()

	if !u.HasActiveKey() {
		*errp = fmt.Errorf("User %s doesn't have an active key")
	} else {
		fokid := u.GetEldestFOKID()
		ret.SetKey("kid", jsonw.NewString(fokid.Kid.String()))
		if fokid.Fp != nil {
			ret.SetKey("key_fingerprint", jsonw.NewString(fokid.Fp.String()))
		}
	}
	return ret
}

func (u *User) ToTrackingStatementBasics(errp *error) *jsonw.Wrapper {
	ret := jsonw.NewDictionary()
	ret.SetKey("username", jsonw.NewString(u.name))
	if last_id_change, err := u.basics.AtKey("last_id_change").GetInt(); err == nil {
		ret.SetKey("last_id_change", jsonw.NewInt(last_id_change))
	}
	if id_version, err := u.basics.AtKey("id_version").GetInt(); err == nil {
		ret.SetKey("id_version", jsonw.NewInt(id_version))
	}
	return ret
}

func (u *User) ToTrackingStatementSeqTail() *jsonw.Wrapper {
	return u.sigs.AtKey("last")
}

func (u *User) ToTrackingStatement(w *jsonw.Wrapper) (err error) {

	track := jsonw.NewDictionary()
	track.SetKey("key", u.ToTrackingStatementKey(&err))
	track.SetKey("seq_tail", u.ToTrackingStatementSeqTail())
	track.SetKey("basics", u.ToTrackingStatementBasics(&err))
	track.SetKey("id", jsonw.NewString(u.id.String()))
	track.SetKey("remote_proofs", u.IdTable.ToTrackingStatement())

	if err != nil {
		return
	}

	w.SetKey("type", jsonw.NewString("track"))
	w.SetKey("version", jsonw.NewInt(KEYBASE_SIGNATURE_V1))
	w.SetKey("track", track)
	return
}

func (u *User) ToKeyStanza(sk GenericKey, eldest *FOKID) (ret *jsonw.Wrapper, err error) {
	ret = jsonw.NewDictionary()
	ret.SetKey("uid", jsonw.NewString(u.id.String()))
	ret.SetKey("username", jsonw.NewString(u.name))
	ret.SetKey("host", jsonw.NewString(CANONICAL_HOST))

	if eldest == nil {
		eldest = u.GetEldestFOKID()
	}

	var signingKid KID
	if sk != nil {
		signingKid = sk.GetKid()
	} else if signingKid = G.Env.GetPerDeviceKID(); signingKid == nil {
		err = NoSecretKeyError{}
		return
	}

	if sk != nil {
		if fp := sk.GetFingerprintP(); fp != nil {
			ret.SetKey("fingerprint", jsonw.NewString(fp.String()))
			ret.SetKey("key_id", jsonw.NewString(fp.ToKeyId()))
		}
	}

	ret.SetKey("kid", jsonw.NewString(signingKid.String()))
	if eldest != nil {
		ret.SetKey("eldest_kid", jsonw.NewString(eldest.Kid.String()))
	}

	return
}

func (s *SocialProofChainLink) ToTrackingStatement() (*jsonw.Wrapper, error) {
	ret := s.BaseToTrackingStatement()
	err := remoteProofToTrackingStatement(s, ret)
	if err != nil {
		ret = nil
	}
	return ret, err
}

func (idt *IdentityTable) ToTrackingStatement() *jsonw.Wrapper {
	v := idt.activeProofs
	tmp := make([]*jsonw.Wrapper, 0, len(v))
	for _, proof := range v {
		if d, err := proof.ToTrackingStatement(); err != nil {
			G.Log.Warning("Problem with a proof: %s", err.Error())
		} else if d != nil {
			tmp = append(tmp, d)
		}
	}
	ret := jsonw.NewArray(len(tmp))
	for i, d := range tmp {
		ret.SetIndex(i, d)
	}
	return ret
}

func (g *GenericChainLink) BaseToTrackingStatement() *jsonw.Wrapper {
	ret := jsonw.NewDictionary()
	ret.SetKey("curr", jsonw.NewString(g.id.String()))
	ret.SetKey("sig_id", jsonw.NewString(g.GetSigId().ToString(true)))

	rkp := jsonw.NewDictionary()
	ret.SetKey("remote_key_proof", rkp)
	rkp.SetKey("state", jsonw.NewInt(g.GetProofState()))

	prev := g.GetPrev()
	var prev_val *jsonw.Wrapper
	if prev == nil {
		prev_val = jsonw.NewNil()
	} else {
		prev_val = jsonw.NewString(prev.String())
	}

	ret.SetKey("prev", prev_val)
	ret.SetKey("ctime", jsonw.NewInt64(g.unpacked.ctime))
	ret.SetKey("etime", jsonw.NewInt64(g.unpacked.etime))
	return ret
}

func remoteProofToTrackingStatement(s RemoteProofChainLink, base *jsonw.Wrapper) error {
	typ_s := s.TableKey()
	if i, found := REMOTE_SERVICE_TYPES[typ_s]; !found {
		return fmt.Errorf("No service type found for '%s' in proof %d",
			typ_s, s.GetSeqno())
	} else {
		base.AtKey("remote_key_proof").SetKey("proof_type", jsonw.NewInt(i))
	}
	base.AtKey("remote_key_proof").SetKey("check_data_json", s.CheckDataJson())
	base.SetKey("sig_type", jsonw.NewInt(SIG_TYPE_REMOTE_PROOF))
	return nil
}

func (u *User) ProofMetadata(ei int, signingKey GenericKey, eldest *FOKID) (ret *jsonw.Wrapper, err error) {

	var seqno int
	var prev_s string
	var key, prev *jsonw.Wrapper

	last_seqno := u.sigChain.GetLastKnownSeqno()
	last_link := u.sigChain.GetLastKnownId()
	if last_link == nil {
		seqno = 1
		prev = jsonw.NewNil()
	} else {
		seqno = int(last_seqno) + 1
		prev_s = last_link.String()
		prev = jsonw.NewString(prev_s)
	}

	if ei == 0 {
		ei = SIG_EXPIRE_IN
	}

	ret = jsonw.NewDictionary()
	ret.SetKey("tag", jsonw.NewString("signature"))
	ret.SetKey("ctime", jsonw.NewInt64(time.Now().Unix()))
	ret.SetKey("expire_in", jsonw.NewInt(ei))
	ret.SetKey("seqno", jsonw.NewInt(seqno))
	ret.SetKey("prev", prev)

	body := jsonw.NewDictionary()
	key, err = u.ToKeyStanza(signingKey, eldest)
	if err != nil {
		ret = nil
		return
	}
	body.SetKey("key", key)
	ret.SetKey("body", body)

	return
}

func (u1 *User) TrackingProofFor(signingKey GenericKey, u2 *User) (ret *jsonw.Wrapper, err error) {
	ret, err = u1.ProofMetadata(0, signingKey, nil)
	if err == nil {
		err = u2.ToTrackingStatement(ret.AtKey("body"))
	}
	return
}

func (u *User) SelfProof(signingKey GenericKey, eldest *FOKID) (ret *jsonw.Wrapper, err error) {
	ret, err = u.ProofMetadata(0, signingKey, eldest)
	if err == nil {
		body := ret.AtKey("body")
		body.SetKey("version", jsonw.NewInt(KEYBASE_SIGNATURE_V1))
		body.SetKey("type", jsonw.NewString("web_service_binding"))
	}
	return
}

func (u *User) ServiceProof(signingKey GenericKey, typ ServiceType, remotename string) (ret *jsonw.Wrapper, err error) {
	ret, err = u.SelfProof(signingKey, nil)
	if err != nil {
		return
	}
	ret.AtKey("body").SetKey("service", typ.ToServiceJson(remotename))
	return
}

// SimpleSignJson marshals the given Json structure and then signs it.
func SignJson(jw *jsonw.Wrapper, key GenericKey) (out string, id *SigId, lid LinkId, err error) {
	var tmp []byte
	if tmp, err = jw.Marshal(); err != nil {
		return
	}
	out, id, err = key.SignToString(tmp)
	lid = ComputeLinkId(tmp)
	return
}

func KeyToProofJson(newkey GenericKey, typ string, signingKey GenericKey) (ret *jsonw.Wrapper, err error) {
	ret = jsonw.NewDictionary()

	if typ == SIBKEY_TYPE && newkey.CanSign() {
		var rsig string
		rsig_json := jsonw.NewDictionary()
		rsig_json.SetKey("reverse_key_sig", jsonw.NewString(signingKey.GetKid().String()))
		if rsig, _, _, err = SignJson(rsig_json, newkey); err != nil {
			return
		}
		rsig_dict := jsonw.NewDictionary()
		rsig_dict.SetKey("sig", jsonw.NewString(rsig))
		rsig_dict.SetKey("type", jsonw.NewString("kb"))
		ret.SetKey("reverse_sig", rsig_dict)
	}

	// For subkeys let's say who are parent is.  In this case it's the signing key,
	// though that can change in the future.
	if typ == SUBKEY_TYPE && signingKey != nil {
		ret.SetKey("parent_kid", jsonw.NewString(signingKey.GetKid().String()))
	}

	ret.SetKey("kid", jsonw.NewString(newkey.GetKid().String()))
	return
}

func (u *User) KeyProof(newkey GenericKey, signingkey GenericKey, typ string, ei int, device *Device) (ret *jsonw.Wrapper, err error) {
	ret, err = u.ProofMetadata(ei, signingkey, nil)
	if err != nil {
		return
	}
	body := ret.AtKey("body")
	body.SetKey("version", jsonw.NewInt(KEYBASE_SIGNATURE_V1))
	body.SetKey("type", jsonw.NewString(typ))

	if device != nil {
		kid := newkey.GetKid().String()
		device.Kid = &kid
		body.SetKey("device", device.Export())
	}

	var kp *jsonw.Wrapper
	if kp, err = KeyToProofJson(newkey, typ, signingkey); err != nil {
		return
	}

	// 'typ' can be 'subkey' or 'sibkey'
	body.SetKey(typ, kp)
	return
}
<|endoftext|>


<commit_before>// Copyright 2014 Alvaro J. Genial. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package ez provides an easy but powerful way to define unit tests and benchmarks that are compatible with package `testing`.
package ez
<commit_msg>Shorten package description<commit_after>// Copyright 2014 Alvaro J. Genial. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package ez provides an easy, powerful way to define tests and benchmarks that are compatible with package `testing`.
package ez
<|endoftext|>


<commit_before>package libzt

/*
#cgo CFLAGS: -I ./include
#cgo darwin LDFLAGS: -L ${SRCDIR}/darwin/ -lzt -lstdc++ -lm -std=c++11
#cgo linux LDFLAGS: -L ${SRCDIR}/linux/ -lzt -lstdc++ -lm -std=c++11

#include "libzt.h"
#include <netdb.h>
*/
import "C"
import (
	"unsafe"
	"syscall"
	"net"
	"errors"
)

const ZT_MAX_IPADDR_LEN = C.ZT_MAX_IPADDR_LEN

func SimpleStart(homePath, networkId string) {
	C.zts_simple_start(C.CString(homePath), C.CString(networkId))
}

func GetIpv4Address(networkId string) string {
	address := make([]byte, ZT_MAX_IPADDR_LEN)
	C.zts_get_ipv4_address(C.CString(networkId), (*C.char)(unsafe.Pointer(&address[0])), C.ZT_MAX_IPADDR_LEN)
	return string(address)
}

func GetIpv6Address(networkId string) string {
	address := make([]byte, ZT_MAX_IPADDR_LEN)
	C.zts_get_ipv6_address(C.CString(networkId), (*C.char)(unsafe.Pointer(&address[0])), C.ZT_MAX_IPADDR_LEN)
	return string(address)
}

// TODO: Return err as second value

func Close(fd int) int {
	return (int)(C.zts_close(cint(fd)))
}

func Listen6(port uint16) (net.Listener, error) {
	fd := Socket(syscall.AF_INET6, syscall.SOCK_STREAM, 0)
	if fd < 0 {
		return nil, errors.New("Error in opening socket")
	}

	serverSocket := syscall.RawSockaddrInet6{Flowinfo: 0, Family: syscall.AF_INET6, Port: port}
	retVal := bind6(fd, serverSocket)
	if retVal < 0 {
		return nil, errors.New("ERROR on binding")
	}

	retVal = listen(fd, 1)
	if retVal < 0 {
		return nil, errors.New("ERROR listening")
	}

	return &TCP6Listener{fd: fd}, nil
}

func Connect6(ip string, port uint16) (net.Conn, error){
	clientSocket := syscall.RawSockaddrInet6{Flowinfo: 0, Family: syscall.AF_INET6, Port: port, Addr: parseIPV6(ip)}

	fd := Socket(syscall.AF_INET6, syscall.SOCK_STREAM, 0)
	if fd < 0 {
		return nil, errors.New("Error in opening socket")
	}

	retVal := (int)(C.zts_connect(cint(fd), (*C.struct_sockaddr)(unsafe.Pointer(&clientSocket)), syscall.SizeofSockaddrInet6))
	if retVal < 0 {
		return nil, errors.New("Unable to connect")
	}

	conn := &Connection{
		fd: fd,
	}
	return conn, nil
}

func Socket(family int, socketType int, protocol int) int {
	return (int)(C.zts_socket(cint(family), cint(socketType), cint(protocol)))
}

func listen(fd int, backlog int) int {
	return (int)(C.zts_listen(cint(fd), cint(backlog)))
}

func bind6(fd int, sockerAddr syscall.RawSockaddrInet6) int {
	return (int)(C.zts_bind(cint(fd), (*C.struct_sockaddr)(unsafe.Pointer(&sockerAddr)), syscall.SizeofSockaddrInet6))
}

func accept6(fd int) (int, syscall.RawSockaddrInet6) {
	socketAddr := syscall.RawSockaddrInet6{}
	socketLength := syscall.SizeofSockaddrInet6
	return (int)(C.zts_accept(cint(fd), (*C.struct_sockaddr)(unsafe.Pointer(&socketAddr)), (*C.socklen_t)(unsafe.Pointer(&socketLength)))), socketAddr
}

func cint(value int) C.int {
	return (C.int)(value)
}

func parseIPV6(ipString string) [16]byte {
	ip := net.ParseIP(ipString)
	var arr [16]byte
	copy(arr[:], ip)
	return arr
}

<commit_msg>Stricter access modifiers<commit_after>package libzt

/*
#cgo CFLAGS: -I ./include
#cgo darwin LDFLAGS: -L ${SRCDIR}/darwin/ -lzt -lstdc++ -lm -std=c++11
#cgo linux LDFLAGS: -L ${SRCDIR}/linux/ -lzt -lstdc++ -lm -std=c++11

#include "libzt.h"
#include <netdb.h>
*/
import "C"
import (
	"unsafe"
	"syscall"
	"net"
	"errors"
)

const ZT_MAX_IPADDR_LEN = C.ZT_MAX_IPADDR_LEN

func SimpleStart(homePath, networkId string) {
	C.zts_simple_start(C.CString(homePath), C.CString(networkId))
}

func GetIpv4Address(networkId string) string {
	address := make([]byte, ZT_MAX_IPADDR_LEN)
	C.zts_get_ipv4_address(C.CString(networkId), (*C.char)(unsafe.Pointer(&address[0])), C.ZT_MAX_IPADDR_LEN)
	return string(address)
}

func GetIpv6Address(networkId string) string {
	address := make([]byte, ZT_MAX_IPADDR_LEN)
	C.zts_get_ipv6_address(C.CString(networkId), (*C.char)(unsafe.Pointer(&address[0])), C.ZT_MAX_IPADDR_LEN)
	return string(address)
}

func Listen6(port uint16) (net.Listener, error) {
	fd := socket(syscall.AF_INET6, syscall.SOCK_STREAM, 0)
	if fd < 0 {
		return nil, errors.New("Error in opening socket")
	}

	serverSocket := syscall.RawSockaddrInet6{Flowinfo: 0, Family: syscall.AF_INET6, Port: port}
	retVal := bind6(fd, serverSocket)
	if retVal < 0 {
		return nil, errors.New("ERROR on binding")
	}

	retVal = listen(fd, 1)
	if retVal < 0 {
		return nil, errors.New("ERROR listening")
	}

	return &TCP6Listener{fd: fd}, nil
}

func Connect6(ip string, port uint16) (net.Conn, error){
	clientSocket := syscall.RawSockaddrInet6{Flowinfo: 0, Family: syscall.AF_INET6, Port: port, Addr: parseIPV6(ip)}

	fd := socket(syscall.AF_INET6, syscall.SOCK_STREAM, 0)
	if fd < 0 {
		return nil, errors.New("Error in opening socket")
	}

	retVal := (int)(C.zts_connect(cint(fd), (*C.struct_sockaddr)(unsafe.Pointer(&clientSocket)), syscall.SizeofSockaddrInet6))
	if retVal < 0 {
		return nil, errors.New("Unable to connect")
	}

	conn := &Connection{
		fd: fd,
	}
	return conn, nil
}

func close(fd int) int {
	return (int)(C.zts_close(cint(fd)))
}

func socket(family int, socketType int, protocol int) int {
	return (int)(C.zts_socket(cint(family), cint(socketType), cint(protocol)))
}

func listen(fd int, backlog int) int {
	return (int)(C.zts_listen(cint(fd), cint(backlog)))
}

func bind6(fd int, sockerAddr syscall.RawSockaddrInet6) int {
	return (int)(C.zts_bind(cint(fd), (*C.struct_sockaddr)(unsafe.Pointer(&sockerAddr)), syscall.SizeofSockaddrInet6))
}

func accept6(fd int) (int, syscall.RawSockaddrInet6) {
	socketAddr := syscall.RawSockaddrInet6{}
	socketLength := syscall.SizeofSockaddrInet6
	return (int)(C.zts_accept(cint(fd), (*C.struct_sockaddr)(unsafe.Pointer(&socketAddr)), (*C.socklen_t)(unsafe.Pointer(&socketLength)))), socketAddr
}

func cint(value int) C.int {
	return (C.int)(value)
}

func parseIPV6(ipString string) [16]byte {
	ip := net.ParseIP(ipString)
	var arr [16]byte
	copy(arr[:], ip)
	return arr
}

<|endoftext|>


<commit_before>package is

import (
	"fmt"
	"log"
	"reflect"
	"testing"
)

// Is provides methods that leverage the existing testing capabilities found
// in the Go test framework. The methods provided allow for a more natural,
// efficient and expressive approach to writing tests. The goal is to write
// fewer lines of code while improving communication of intent.
type Is struct {
	TB         testing.TB
	strict     bool
	failFormat string
	failArgs   []interface{}
}

// New creates a new instance of the Is object and stores a reference to the
// provided testing object.
func New(tb testing.TB) *Is {
	if tb == nil {
		log.Fatalln("You must provide a testing object.")
	}
	return &Is{TB: tb, strict: true}
}

// Msg defines a message to print in the event of a failure. This allows you
// to print out additional information about a failure if it happens.
func (is *Is) Msg(format string, args ...interface{}) *Is {
	return &Is{
		TB:         is.TB,
		strict:     is.strict,
		failFormat: format,
		failArgs:   args,
	}
}

// AddMsg appends a message to print in the event of a failure. This allows
// you to build a failure message in multiple steps. If no message was
// previously set, simply sets the message.
//
// This method is most useful as a way of setting a default error message,
// then adding additional information to the output for specific assertions.
// For example:
//
// is := is.New(t).Msg("User ID: %d",u.ID)
// /*do things*/
// is.AddMsg("Raw Response: %s",body).Equal(res.StatusCode, http.StatusCreated)
func (is *Is) AddMsg(format string, args ...interface{}) *Is {
	if is.failFormat == "" {
		return is.Msg(format, args...)
	}
	return &Is{
		TB:         is.TB,
		strict:     is.strict,
		failFormat: fmt.Sprintf("%s - %s", is.failFormat, format),
		failArgs:   append(is.failArgs, args...),
	}
}

// Lax returns a copy of this instance of Is which does not abort the test if
// a failure occurs. Use this to run a set of tests and see all the failures
// at once.
func (is *Is) Lax() *Is {
	return &Is{
		TB:         is.TB,
		strict:     false,
		failFormat: is.failFormat,
		failArgs:   is.failArgs,
	}
}

// Strict returns a copy of this instance of Is which aborts the test if a
// failure occurs. This is the default behavior, thus this method has no
// effect unless it is used to reverse a previous call to Lax.
func (is *Is) Strict() *Is {
	return &Is{
		TB:         is.TB,
		strict:     true,
		failFormat: is.failFormat,
		failArgs:   is.failArgs,
	}
}

// Equal performs a deep compare of the provided objects and fails if they are
// not equal.
//
// Equal does not respect type differences. If the types are different and
// comparable (eg int32 and int64), they will be compared as though they are
// the same type.
func (is *Is) Equal(a interface{}, b interface{}) {
	is.TB.Helper()
	if !isEqual(a, b) {
		fail(is, "expected objects '%s' and '%s' to be equal, but got: %v and %v",
			objectTypeName(a),
			objectTypeName(b), a, b)
	}
}

// NotEqual performs a deep compare of the provided objects and fails if they are
// equal.
//
// NotEqual does not respect type differences. If the types are different and
// comparable (eg int32 and int64), they will be compared as though they are
// the same type.
func (is *Is) NotEqual(a interface{}, b interface{}) {
	is.TB.Helper()
	if isEqual(a, b) {
		fail(is, "expected objects '%s' and '%s' not to be equal",
			objectTypeName(a),
			objectTypeName(b))
	}
}

// OneOf performs a deep compare of the provided object and an array of
// comparison objects. It fails if the first object is not equal to one of the
// comparison objects.
//
// OneOf does not respect type differences. If the types are different and
// comparable (eg int32 and int64), they will be compared as though they are
// the same type.
func (is *Is) OneOf(a interface{}, b ...interface{}) {
	is.TB.Helper()
	result := false
	for _, o := range b {
		result = isEqual(a, o)
		if result {
			break
		}
	}
	if !result {
		fail(is, "expected object '%s' to be equal to one of '%s', but got: %v and %v",
			objectTypeName(a),
			objectTypeNames(b), a, b)
	}
}

// NotOneOf performs a deep compare of the provided object and an array of
// comparison objects. It fails if the first object is equal to one of the
// comparison objects.
//
// NotOneOf does not respect type differences. If the types are different and
// comparable (eg int32 and int64), they will be compared as though they are
// the same type.
func (is *Is) NotOneOf(a interface{}, b ...interface{}) {
	is.TB.Helper()
	result := false
	for _, o := range b {
		result = isEqual(a, o)
		if result {
			break
		}
	}
	if result {
		fail(is, "expected object '%s' not to be equal to one of '%s', but got: %v and %v",
			objectTypeName(a),
			objectTypeNames(b), a, b)
	}
}

// Err checks the provided error object to determine if an error is present.
func (is *Is) Err(e error) {
	is.TB.Helper()
	if isNil(e) {
		fail(is, "expected error")
	}
}

// NotErr checks the provided error object to determine if an error is not
// present.
func (is *Is) NotErr(e error) {
	is.TB.Helper()
	if !isNil(e) {
		fail(is, "expected no error, but got: %v", e)
	}
}

// Nil checks the provided object to determine if it is nil.
func (is *Is) Nil(o interface{}) {
	is.TB.Helper()
	if !isNil(o) {
		fail(is, "expected object '%s' to be nil, but got: %v", objectTypeName(o), o)
	}
}

// NotNil checks the provided object to determine if it is not nil.
func (is *Is) NotNil(o interface{}) {
	is.TB.Helper()
	if isNil(o) {
		fail(is, "expected object '%s' not to be nil", objectTypeName(o))
	}
}

// True checks the provided boolean to determine if it is true.
func (is *Is) True(b bool) {
	is.TB.Helper()
	if !b {
		fail(is, "expected boolean to be true")
	}
}

// False checks the provided boolean to determine if is false.
func (is *Is) False(b bool) {
	is.TB.Helper()
	if b {
		fail(is, "expected boolean to be false")
	}
}

// Zero checks the provided object to determine if it is the zero value
// for the type of that object. The zero value is the same as what the object
// would contain when initialized but not assigned.
//
// This method, for example, would be used to determine if a string is empty,
// an array is empty or a map is empty. It could also be used to determine if
// a number is 0.
//
// In cases such as slice, map, array and chan, a nil value is treated the
// same as an object with len == 0
func (is *Is) Zero(o interface{}) {
	is.TB.Helper()
	if !isZero(o) {
		fail(is, "expected object '%s' to be zero value, but it was: %v", objectTypeName(o), o)
	}
}

// NotZero checks the provided object to determine if it is not the zero
// value for the type of that object. The zero value is the same as what the
// object would contain when initialized but not assigned.
//
// This method, for example, would be used to determine if a string is not
// empty, an array is not empty or a map is not empty. It could also be used
// to determine if a number is not 0.
//
// In cases such as slice, map, array and chan, a nil value is treated the
// same as an object with len == 0
func (is *Is) NotZero(o interface{}) {
	is.TB.Helper()
	if isZero(o) {
		fail(is, "expected object '%s' not to be zero value", objectTypeName(o))
	}
}

// Len checks the provided object to determine if it is the same length as the
// provided length argument.
//
// If the object is not one of type array, slice or map, it will fail.
func (is *Is) Len(o interface{}, l int) {
	is.TB.Helper()
	t := reflect.TypeOf(o)
	if o == nil ||
		(t.Kind() != reflect.Array &&
			t.Kind() != reflect.Slice &&
			t.Kind() != reflect.Map) {
		fail(is, "expected object '%s' to be of length '%d', but the object is not one of array, slice or map", objectTypeName(o), l)
		return
	}

	rLen := reflect.ValueOf(o).Len()
	if rLen != l {
		fail(is, "expected object '%s' to be of length '%d' but it was: %d", objectTypeName(o), l, rLen)
	}
}

// ShouldPanic expects the provided function to panic. If the function does
// not panic, this assertion fails.
func (is *Is) ShouldPanic(f func()) {
	is.TB.Helper()
	defer func() {
		r := recover()
		if r == nil {
			fail(is, "expected function to panic")
		}
	}()
	f()
}
<commit_msg>Add New() method to Is instance.<commit_after>package is

import (
	"fmt"
	"log"
	"reflect"
	"testing"
)

// Is provides methods that leverage the existing testing capabilities found
// in the Go test framework. The methods provided allow for a more natural,
// efficient and expressive approach to writing tests. The goal is to write
// fewer lines of code while improving communication of intent.
type Is struct {
	TB         testing.TB
	strict     bool
	failFormat string
	failArgs   []interface{}
}

// New creates a new instance of the Is object and stores a reference to the
// provided testing object.
func New(tb testing.TB) *Is {
	if tb == nil {
		log.Fatalln("You must provide a testing object.")
	}
	return &Is{TB: tb, strict: true}
}

// New creates a new copy of your Is object and replaces the internal testing
// object with the provided testing object. This is useful for re-initializing
// your `is` instance inside a subtest so that it doesn't panic when using
// Strict mode.
//
// For example, creating your initial instance as such
//  is := is.New(t)
// is the convention, but this obviously shadows the `is` package namespace.
// Inside your subtest, you can do the exact same thing to initialize a locally scoped
// variable that uses the subtest's testing.T object.
func (is *Is) New(tb testing.TB) *Is {
	return &Is{
		TB:         tb,
		strict:     is.strict,
		failFormat: is.failFormat,
		failArgs:   is.failArgs,
	}
}

// Msg defines a message to print in the event of a failure. This allows you
// to print out additional information about a failure if it happens.
func (is *Is) Msg(format string, args ...interface{}) *Is {
	return &Is{
		TB:         is.TB,
		strict:     is.strict,
		failFormat: format,
		failArgs:   args,
	}
}

// AddMsg appends a message to print in the event of a failure. This allows
// you to build a failure message in multiple steps. If no message was
// previously set, simply sets the message.
//
// This method is most useful as a way of setting a default error message,
// then adding additional information to the output for specific assertions.
// For example:
//
// is := is.New(t).Msg("User ID: %d",u.ID)
// /*do things*/
// is.AddMsg("Raw Response: %s",body).Equal(res.StatusCode, http.StatusCreated)
func (is *Is) AddMsg(format string, args ...interface{}) *Is {
	if is.failFormat == "" {
		return is.Msg(format, args...)
	}
	return &Is{
		TB:         is.TB,
		strict:     is.strict,
		failFormat: fmt.Sprintf("%s - %s", is.failFormat, format),
		failArgs:   append(is.failArgs, args...),
	}
}

// Lax returns a copy of this instance of Is which does not abort the test if
// a failure occurs. Use this to run a set of tests and see all the failures
// at once.
func (is *Is) Lax() *Is {
	return &Is{
		TB:         is.TB,
		strict:     false,
		failFormat: is.failFormat,
		failArgs:   is.failArgs,
	}
}

// Strict returns a copy of this instance of Is which aborts the test if a
// failure occurs. This is the default behavior, thus this method has no
// effect unless it is used to reverse a previous call to Lax.
func (is *Is) Strict() *Is {
	return &Is{
		TB:         is.TB,
		strict:     true,
		failFormat: is.failFormat,
		failArgs:   is.failArgs,
	}
}

// Equal performs a deep compare of the provided objects and fails if they are
// not equal.
//
// Equal does not respect type differences. If the types are different and
// comparable (eg int32 and int64), they will be compared as though they are
// the same type.
func (is *Is) Equal(a interface{}, b interface{}) {
	is.TB.Helper()
	if !isEqual(a, b) {
		fail(is, "expected objects '%s' and '%s' to be equal, but got: %v and %v",
			objectTypeName(a),
			objectTypeName(b), a, b)
	}
}

// NotEqual performs a deep compare of the provided objects and fails if they are
// equal.
//
// NotEqual does not respect type differences. If the types are different and
// comparable (eg int32 and int64), they will be compared as though they are
// the same type.
func (is *Is) NotEqual(a interface{}, b interface{}) {
	is.TB.Helper()
	if isEqual(a, b) {
		fail(is, "expected objects '%s' and '%s' not to be equal",
			objectTypeName(a),
			objectTypeName(b))
	}
}

// OneOf performs a deep compare of the provided object and an array of
// comparison objects. It fails if the first object is not equal to one of the
// comparison objects.
//
// OneOf does not respect type differences. If the types are different and
// comparable (eg int32 and int64), they will be compared as though they are
// the same type.
func (is *Is) OneOf(a interface{}, b ...interface{}) {
	is.TB.Helper()
	result := false
	for _, o := range b {
		result = isEqual(a, o)
		if result {
			break
		}
	}
	if !result {
		fail(is, "expected object '%s' to be equal to one of '%s', but got: %v and %v",
			objectTypeName(a),
			objectTypeNames(b), a, b)
	}
}

// NotOneOf performs a deep compare of the provided object and an array of
// comparison objects. It fails if the first object is equal to one of the
// comparison objects.
//
// NotOneOf does not respect type differences. If the types are different and
// comparable (eg int32 and int64), they will be compared as though they are
// the same type.
func (is *Is) NotOneOf(a interface{}, b ...interface{}) {
	is.TB.Helper()
	result := false
	for _, o := range b {
		result = isEqual(a, o)
		if result {
			break
		}
	}
	if result {
		fail(is, "expected object '%s' not to be equal to one of '%s', but got: %v and %v",
			objectTypeName(a),
			objectTypeNames(b), a, b)
	}
}

// Err checks the provided error object to determine if an error is present.
func (is *Is) Err(e error) {
	is.TB.Helper()
	if isNil(e) {
		fail(is, "expected error")
	}
}

// NotErr checks the provided error object to determine if an error is not
// present.
func (is *Is) NotErr(e error) {
	is.TB.Helper()
	if !isNil(e) {
		fail(is, "expected no error, but got: %v", e)
	}
}

// Nil checks the provided object to determine if it is nil.
func (is *Is) Nil(o interface{}) {
	is.TB.Helper()
	if !isNil(o) {
		fail(is, "expected object '%s' to be nil, but got: %v", objectTypeName(o), o)
	}
}

// NotNil checks the provided object to determine if it is not nil.
func (is *Is) NotNil(o interface{}) {
	is.TB.Helper()
	if isNil(o) {
		fail(is, "expected object '%s' not to be nil", objectTypeName(o))
	}
}

// True checks the provided boolean to determine if it is true.
func (is *Is) True(b bool) {
	is.TB.Helper()
	if !b {
		fail(is, "expected boolean to be true")
	}
}

// False checks the provided boolean to determine if is false.
func (is *Is) False(b bool) {
	is.TB.Helper()
	if b {
		fail(is, "expected boolean to be false")
	}
}

// Zero checks the provided object to determine if it is the zero value
// for the type of that object. The zero value is the same as what the object
// would contain when initialized but not assigned.
//
// This method, for example, would be used to determine if a string is empty,
// an array is empty or a map is empty. It could also be used to determine if
// a number is 0.
//
// In cases such as slice, map, array and chan, a nil value is treated the
// same as an object with len == 0
func (is *Is) Zero(o interface{}) {
	is.TB.Helper()
	if !isZero(o) {
		fail(is, "expected object '%s' to be zero value, but it was: %v", objectTypeName(o), o)
	}
}

// NotZero checks the provided object to determine if it is not the zero
// value for the type of that object. The zero value is the same as what the
// object would contain when initialized but not assigned.
//
// This method, for example, would be used to determine if a string is not
// empty, an array is not empty or a map is not empty. It could also be used
// to determine if a number is not 0.
//
// In cases such as slice, map, array and chan, a nil value is treated the
// same as an object with len == 0
func (is *Is) NotZero(o interface{}) {
	is.TB.Helper()
	if isZero(o) {
		fail(is, "expected object '%s' not to be zero value", objectTypeName(o))
	}
}

// Len checks the provided object to determine if it is the same length as the
// provided length argument.
//
// If the object is not one of type array, slice or map, it will fail.
func (is *Is) Len(o interface{}, l int) {
	is.TB.Helper()
	t := reflect.TypeOf(o)
	if o == nil ||
		(t.Kind() != reflect.Array &&
			t.Kind() != reflect.Slice &&
			t.Kind() != reflect.Map) {
		fail(is, "expected object '%s' to be of length '%d', but the object is not one of array, slice or map", objectTypeName(o), l)
		return
	}

	rLen := reflect.ValueOf(o).Len()
	if rLen != l {
		fail(is, "expected object '%s' to be of length '%d' but it was: %d", objectTypeName(o), l, rLen)
	}
}

// ShouldPanic expects the provided function to panic. If the function does
// not panic, this assertion fails.
func (is *Is) ShouldPanic(f func()) {
	is.TB.Helper()
	defer func() {
		r := recover()
		if r == nil {
			fail(is, "expected function to panic")
		}
	}()
	f()
}
<|endoftext|>


<commit_before>package is

import (
	"reflect"
	"regexp"
	"time"
)

var typeTime = reflect.TypeOf(time.Time{})

const (
	EmailPattern = `^[a-zA-Z0-9!#$%&\'*+\\/=?^_{|}~-]+(?:\.[a-zA-Z0-9!#$%&\'*+\\/=?^_{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$`
	UrlPattern   = `((http|https|ftp){1}\:\/\/)?([a-zA-Z0-9]+[a-zA-Z0-9\-\.]+[a-zA-Z0-9]+\.(net|cn|co|hk|tw|com|edu|gov|us|int|mil|org|int|mil|vg|uk|idv|tk|se|nz|nu|nl|ms|jp|jobs|it|ind|gen|firm|in|gs|fr|fm|eu|es|de|bz|be|at|am|ag|mx|asia|ws|xxx|tv|cc|ca|mobi|me|biz|arpa|info|name|pro|aero|coop|museum|ly|eg|mk)|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})){1}(:[a-zA-Z0-9]*)?\/?([a-zA-Z0-9\-\._\?\'\/\\\+&%\$#\=~])*`
)

func Email(v string) bool {
	ok, err := regexp.MatchString(EmailPattern, v)
	return ok && err == nil
}

func Url(v string) bool {
	ok, err := regexp.MatchString(UrlPattern, v)
	return ok && err == nil
}

// borrow from "labix.org/v2/mgo/bson"
func Zero(v reflect.Value) bool {
	switch v.Kind() {
	case reflect.String:
		return len(v.String()) == 0
	case reflect.Ptr, reflect.Interface:
		return v.IsNil()
	case reflect.Slice:
		return v.Len() == 0
	case reflect.Map:
		return v.Len() == 0
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return v.Int() == 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return v.Uint() == 0
	case reflect.Float32, reflect.Float64:
		return v.Float() == 0
	case reflect.Bool:
		return !v.Bool()
	case reflect.Struct:
		if v.Type() == typeTime {
			return v.Interface().(time.Time).IsZero()
		}
		for i := v.NumField() - 1; i >= 0; i-- {
			if !Zero(v.Field(i)) {
				return false
			}
		}
		return true
	}
	return false
}
<commit_msg>update bson package<commit_after>package is

import (
	"reflect"
	"regexp"
	"time"
)

var typeTime = reflect.TypeOf(time.Time{})

const (
	EmailPattern = `^[a-zA-Z0-9!#$%&\'*+\\/=?^_{|}~-]+(?:\.[a-zA-Z0-9!#$%&\'*+\\/=?^_{|}~-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$`
	UrlPattern   = `((http|https|ftp){1}\:\/\/)?([a-zA-Z0-9]+[a-zA-Z0-9\-\.]+[a-zA-Z0-9]+\.(net|cn|co|hk|tw|com|edu|gov|us|int|mil|org|int|mil|vg|uk|idv|tk|se|nz|nu|nl|ms|jp|jobs|it|ind|gen|firm|in|gs|fr|fm|eu|es|de|bz|be|at|am|ag|mx|asia|ws|xxx|tv|cc|ca|mobi|me|biz|arpa|info|name|pro|aero|coop|museum|ly|eg|mk)|([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})){1}(:[a-zA-Z0-9]*)?\/?([a-zA-Z0-9\-\._\?\'\/\\\+&%\$#\=~])*`
)

func Email(v string) bool {
	ok, err := regexp.MatchString(EmailPattern, v)
	return ok && err == nil
}

func Url(v string) bool {
	ok, err := regexp.MatchString(UrlPattern, v)
	return ok && err == nil
}

// borrow from "gopkg.in/mgo.v2/bson"
func Zero(v reflect.Value) bool {
	switch v.Kind() {
	case reflect.String:
		return len(v.String()) == 0
	case reflect.Ptr, reflect.Interface:
		return v.IsNil()
	case reflect.Slice:
		return v.Len() == 0
	case reflect.Map:
		return v.Len() == 0
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return v.Int() == 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return v.Uint() == 0
	case reflect.Float32, reflect.Float64:
		return v.Float() == 0
	case reflect.Bool:
		return !v.Bool()
	case reflect.Struct:
		if v.Type() == typeTime {
			return v.Interface().(time.Time).IsZero()
		}
		for i := v.NumField() - 1; i >= 0; i-- {
			if !Zero(v.Field(i)) {
				return false
			}
		}
		return true
	}
	return false
}
<|endoftext|>


<commit_before>package app

import (
	"encoding/json"
	"fmt"

	"github.com/murlokswarm/errors"
	"github.com/murlokswarm/log"
	"github.com/murlokswarm/markup"
	"github.com/murlokswarm/uid"
)

const (
	jsFmt = `
function Mount(id, markup) {
    const sel = '[data-murlok-root="' + id + '"]';
    const elem = document.querySelector(sel);
    elem.innerHTML = markup;
}

function RenderFull(id, markup) {
    const sel = '[data-murlok-id="' + id + '"]';
    const elem = document.querySelector(sel);
    elem.outerHTML = markup;
}

function RenderAttributes(id, attrs) {
    const sel = '[data-murlok-id="' + id + '"]';
    const elem = document.querySelector(sel);

    for (var name in attrs) {
        if (elem.hasAttribute(name) && attrs[name].length == 0) {
            elem.removeAttribute(name);
            continue;
        }
        elem.setAttribute(name, attrs[name]);
    }
}

function GetAttributeValue(elem, name) {
    if (!elem.hasAttribute(name)) {
        return null;
    }
    return elem.getAttribute(name);
}

function CallEvent(id, method, self, event) {
    var arg;

    var value = null;
    if (typeof self.value !== undefined) {
        value = self.value;
    }

    switch (event.type) {
        case "click":
        case "contextmenu":
        case "dblclick":
        case "mousedown":
        case "mouseenter":
        case "mouseleave":
        case "mousemove":
        case "mouseover":
        case "mouseout":
        case "mouseup":
        case "drag":
        case "dragend":
        case "dragenter":
        case "dragleave":
        case "dragover":
        case "dragstart":
        case "drop":
            arg = MakeMouseArg(event);
            break;

        case "mousewheel":
            arg = MakeWheelArg(event);
            break;

        case "keydown":
        case "keypress":
        case "keyup":
            arg = MakeKeyboardArg(event);
            break;

        case "change":
            arg = MakeChangeArg(value);
            break;

        default:
            arg = { "test": "merd" };
            break;
    }

    arg.Target = {
        ID: GetAttributeValue(self, "id"),
        Class: GetAttributeValue(self, "class"),
        Index: GetAttributeValue(self, "data-murlok-index"),
        Value: value,
        Tag: self.tagName.toLowerCase()
    };

    Call(id, method, arg);
}

function MakeMouseArg(event) {
    return {
        AltKey: event.altKey,
        Button: event.button,
        ClientX: event.clientX,
        ClientY: event.clientY,
        CtrlKey: event.ctrlKey,
        Detail: event.detail,
        MetaKey: event.metaKey,
        PageX: event.pageX,
        PageY: event.pageY,
        ScreenX: event.screenX,
        ScreenY: event.screenY,
        ShiftKey: event.shiftKey
    };
}

function MakeWheelArg(event) {
    return {
        DeltaX: event.deltaX,
        DeltaY: event.deltaY,
        DeltaZ: event.deltaZ,
        DeltaMode: event.deltaMode
    };
}

function MakeKeyboardArg(event) {
    return {
        AltKey: event.altKey,
        CtrlKey: event.ctrlKey,
        CharCode: event.charCode,
        KeyCode: event.keyCode,
        Location: event.location,
        MetaKey: event.metaKey,
        ShiftKey: event.shiftKey
    };
}

function MakeChangeArg(value) {
    return {
        Value: value
    };
}

function Call(id, method, arg) {
    let msg = {
        ID: id,
        Method: method,
        Arg: JSON.stringify(arg)
    };

    msg = JSON.stringify(msg);
    %v
}
    `
)

// DOMElement represents a DOM element.
type DOMElement struct {
	Tag   string // The tag of the element. e.g. div.
	ID    string // The id attribute.
	Class string // the class attribute.
	Value string // The value attrivute.
	Index string // The data-murlok-index attribute.
}

type jsMsg struct {
	ID     uid.ID
	Method string
	Arg    string
}

// HandleEvent allows to call the component method or map the component field
// described in msg.
// Should be used only in a driver.
func HandleEvent(msg string) {
	var jsMsg jsMsg
	if err := json.Unmarshal([]byte(msg), &jsMsg); err != nil {
		log.Error(errors.New(err))
		return
	}
	markup.HandleEvent(jsMsg.ID, jsMsg.Method, jsMsg.Arg)
}

// MurlokJS returns the javascript code allowing bidirectional communication
// between a context and it's webview.
// Should be used only in drivers implementations.
func MurlokJS() string {
	return fmt.Sprintf(jsFmt, driver.JavascriptBridge())
}
<commit_msg>orthodox<commit_after>package app

import (
	"encoding/json"
	"fmt"

	"github.com/murlokswarm/errors"
	"github.com/murlokswarm/log"
	"github.com/murlokswarm/markup"
	"github.com/murlokswarm/uid"
)

const (
	jsFmt = `
function Mount(id, markup) {
    const sel = '[data-murlok-root="' + id + '"]';
    const elem = document.querySelector(sel);
    elem.innerHTML = markup;
}

function RenderFull(id, markup) {
    const sel = '[data-murlok-id="' + id + '"]';
    const elem = document.querySelector(sel);
    elem.outerHTML = markup;
}

function RenderAttributes(id, attrs) {
    const sel = '[data-murlok-id="' + id + '"]';
    const elem = document.querySelector(sel);

    for (var name in attrs) {
        if (elem.hasAttribute(name) && attrs[name].length == 0) {
            elem.removeAttribute(name);
            continue;
        }
        elem.setAttribute(name, attrs[name]);
    }
}

function GetAttributeValue(elem, name) {
    if (!elem.hasAttribute(name)) {
        return null;
    }
    return elem.getAttribute(name);
}

function CallEvent(id, method, self, event) {
    var arg;

    var value = null;
    if (typeof self.value !== undefined) {
        value = self.value;
    }

    switch (event.type) {
        case "click":
        case "contextmenu":
        case "dblclick":
        case "mousedown":
        case "mouseenter":
        case "mouseleave":
        case "mousemove":
        case "mouseover":
        case "mouseout":
        case "mouseup":
        case "drag":
        case "dragend":
        case "dragenter":
        case "dragleave":
        case "dragover":
        case "dragstart":
        case "drop":
            arg = MakeMouseArg(event);
            break;

        case "mousewheel":
            arg = MakeWheelArg(event);
            break;

        case "keydown":
        case "keypress":
        case "keyup":
            arg = MakeKeyboardArg(event);
            break;

        case "change":
            arg = MakeChangeArg(value);
            break;

        default:
            arg = { "test": "merd" };
            break;
    }

    arg.Target = {
        ID: GetAttributeValue(self, "id"),
        Class: GetAttributeValue(self, "class"),
        Index: GetAttributeValue(self, "data-murlok-index"),
        Value: value,
        Tag: self.tagName.toLowerCase()
    };

    Call(id, method, arg);
}

function MakeMouseArg(event) {
    return {
        AltKey: event.altKey,
        Button: event.button,
        ClientX: event.clientX,
        ClientY: event.clientY,
        CtrlKey: event.ctrlKey,
        Detail: event.detail,
        MetaKey: event.metaKey,
        PageX: event.pageX,
        PageY: event.pageY,
        ScreenX: event.screenX,
        ScreenY: event.screenY,
        ShiftKey: event.shiftKey
    };
}

function MakeWheelArg(event) {
    return {
        DeltaX: event.deltaX,
        DeltaY: event.deltaY,
        DeltaZ: event.deltaZ,
        DeltaMode: event.deltaMode
    };
}

function MakeKeyboardArg(event) {
    return {
        AltKey: event.altKey,
        CtrlKey: event.ctrlKey,
        CharCode: event.charCode,
        KeyCode: event.keyCode,
        Location: event.location,
        MetaKey: event.metaKey,
        ShiftKey: event.shiftKey
    };
}

function MakeChangeArg(value) {
    return {
        Value: value
    };
}

function Call(id, method, arg) {
    let msg = {
        ID: id,
        Method: method,
        Arg: JSON.stringify(arg)
    };

    msg = JSON.stringify(msg);
    %v
}
    `
)

// DOMElement represents a DOM element.
type DOMElement struct {
	Tag   string // The tag of the element. e.g. div.
	ID    string // The id attribute.
	Class string // the class attribute.
	Value string // The value attribute.
	Index string // The data-murlok-index attribute.
}

type jsMsg struct {
	ID     uid.ID
	Method string
	Arg    string
}

// HandleEvent allows to call the component method or map the component field
// described in msg.
// Should be used only in a driver.
func HandleEvent(msg string) {
	var jsMsg jsMsg
	if err := json.Unmarshal([]byte(msg), &jsMsg); err != nil {
		log.Error(errors.New(err))
		return
	}
	markup.HandleEvent(jsMsg.ID, jsMsg.Method, jsMsg.Arg)
}

// MurlokJS returns the javascript code allowing bidirectional communication
// between a context and it's webview.
// Should be used only in drivers implementations.
func MurlokJS() string {
	return fmt.Sprintf(jsFmt, driver.JavascriptBridge())
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"time"

	"github.com/go-chat-bot/bot"
)

type Kubebot struct {
	token    string
	admins   map[string]bool
	channels map[string]bool
	commands map[string]bool
}

const (
	forbiddenUserMessage     string = "%s - ⚠ kubectl forbidden for user @%s\n"
	forbiddenChannelMessage  string = "%s - ⚠ Channel %s forbidden for user @%s\n"
	forbiddenCommandMessage  string = "%s - ⚠ Command %s forbidden for user @%s\n"
	forbiddenFlagMessage     string = "%s - ⚠ Flag(s) %s forbidden for user @%s\n"
	forbiddenUserResponse    string = "Sorry @%s, but you don't have permission to run this command :confused:"
	forbiddenChannelResponse string = "Sorry @%s, but I'm not allowed to run this command here :zipper_mouth_face:"
	forbiddenCommandResponse string = "Sorry @%s, but I cannot run this command. I'm allowed to run `%s`"
	forbiddenFlagResponse    string = "Sorry @%s, but I'm not allowed to run one of your flags."
	okResponse               string = "Roger that!\n@%s, this is the response to your request:\n ```\n%s\n``` "
)

var (
	ignored = map[string]map[string]bool{
		"get": map[string]bool{
			"-f":           true,
			"--filename":   true,
			"-w":           true,
			"--watch":      true,
			"--watch-only": true,
		},
		"describe": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"create": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"replace": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"patch": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"delete": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"edit": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"apply": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"logs": map[string]bool{
			"-f":       true,
			"--follow": true,
		},
		"rolling-update": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"scale": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"attach": map[string]bool{
			"-i":      true,
			"--stdin": true,
			"-t":      true,
			"--tty":   true,
		},
		"exec": map[string]bool{
			"-i":      true,
			"--stdin": true,
			"-t":      true,
			"--tty":   true,
		},
		"run": map[string]bool{
			"--leave-stdin-open": true,
			"-i":                 true,
			"--stdin":            true,
			"--tty":              true,
		},
		"expose": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"autoscale": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"label": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"annotate": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"convert": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
	}
)

func validateFlags(arguments ...string) error {
	if len(arguments) <= 1 {
		return nil
	}

	for i := 1; i < len(arguments); i++ {
		if ignored[arguments[0]][arguments[i]] {
			return errors.New(fmt.Sprintf("Error: %s is an invalid flag", arguments[i]))
		}

	}

	return nil
}

func kubectl(command *bot.Cmd) (msg string, err error) {
	t := time.Now()
	time := t.Format(time.RFC3339)
	nickname := command.User.Nick

	if !kb.admins[nickname] {
		fmt.Printf(forbiddenUserMessage, time, nickname)
		return fmt.Sprintf(forbiddenUserResponse, nickname), nil
	}

	if !kb.channels[command.Channel] {
		fmt.Printf(forbiddenChannelMessage, time, command.Channel, nickname)
		return fmt.Sprintf(forbiddenChannelResponse, nickname), nil
	}

	if len(command.Args) > 0 && !kb.commands[command.Args[0]] {
		fmt.Printf(forbiddenCommandMessage, time, command.Args, nickname)
		return fmt.Sprintf(forbiddenCommandResponse, nickname, kb.commands), nil
	}

	if err := validateFlags(command.Args...); err != nil {
		fmt.Printf(forbiddenFlagMessage, time, command.Args, nickname)
		return fmt.Sprintf(forbiddenFlagResponse, nickname), nil
	}

	output := execute("kubectl", command.Args...)

	return fmt.Sprintf(okResponse, nickname, output), nil
}

func init() {
	bot.RegisterCommand(
		"kubectl",
		"Kubectl Slack integration",
		"",
		kubectl)
}
<commit_msg>Updated error message<commit_after>package main

import (
	"errors"
	"fmt"
	"time"

	"github.com/go-chat-bot/bot"
)

type Kubebot struct {
	token    string
	admins   map[string]bool
	channels map[string]bool
	commands map[string]bool
}

const (
	forbiddenUserMessage     string = "%s - ⚠ kubectl forbidden for user @%s\n"
	forbiddenChannelMessage  string = "%s - ⚠ Channel %s forbidden for user @%s\n"
	forbiddenCommandMessage  string = "%s - ⚠ Command %s forbidden for user @%s\n"
	forbiddenFlagMessage     string = "%s - ⚠ Flag(s) %s forbidden for user @%s\n"
	forbiddenUserResponse    string = "Sorry @%s, but you don't have permission to run this command :confused:"
	forbiddenChannelResponse string = "Sorry @%s, but I'm not allowed to run this command here :zipper_mouth_face:"
	forbiddenCommandResponse string = "Sorry @%s, but I cannot run this command."
	forbiddenFlagResponse    string = "Sorry @%s, but I'm not allowed to run one of your flags."
	okResponse               string = "Roger that!\n@%s, this is the response to your request:\n ```\n%s\n``` "
)

var (
	ignored = map[string]map[string]bool{
		"get": map[string]bool{
			"-f":           true,
			"--filename":   true,
			"-w":           true,
			"--watch":      true,
			"--watch-only": true,
		},
		"describe": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"create": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"replace": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"patch": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"delete": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"edit": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"apply": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"logs": map[string]bool{
			"-f":       true,
			"--follow": true,
		},
		"rolling-update": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"scale": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"attach": map[string]bool{
			"-i":      true,
			"--stdin": true,
			"-t":      true,
			"--tty":   true,
		},
		"exec": map[string]bool{
			"-i":      true,
			"--stdin": true,
			"-t":      true,
			"--tty":   true,
		},
		"run": map[string]bool{
			"--leave-stdin-open": true,
			"-i":                 true,
			"--stdin":            true,
			"--tty":              true,
		},
		"expose": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"autoscale": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"label": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"annotate": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
		"convert": map[string]bool{
			"-f":         true,
			"--filename": true,
		},
	}
)

func validateFlags(arguments ...string) error {
	if len(arguments) <= 1 {
		return nil
	}

	for i := 1; i < len(arguments); i++ {
		if ignored[arguments[0]][arguments[i]] {
			return errors.New(fmt.Sprintf("Error: %s is an invalid flag", arguments[i]))
		}

	}

	return nil
}

func kubectl(command *bot.Cmd) (msg string, err error) {
	t := time.Now()
	time := t.Format(time.RFC3339)
	nickname := command.User.Nick

	if !kb.admins[nickname] {
		fmt.Printf(forbiddenUserMessage, time, nickname)
		return fmt.Sprintf(forbiddenUserResponse, nickname), nil
	}

	if !kb.channels[command.Channel] {
		fmt.Printf(forbiddenChannelMessage, time, command.Channel, nickname)
		return fmt.Sprintf(forbiddenChannelResponse, nickname), nil
	}

	if len(command.Args) > 0 && !kb.commands[command.Args[0]] {
		fmt.Printf(forbiddenCommandMessage, time, command.Args, nickname)
		return fmt.Sprintf(forbiddenCommandResponse, nickname), nil
	}

	if err := validateFlags(command.Args...); err != nil {
		fmt.Printf(forbiddenFlagMessage, time, command.Args, nickname)
		return fmt.Sprintf(forbiddenFlagResponse, nickname), nil
	}

	output := execute("kubectl", command.Args...)

	return fmt.Sprintf(okResponse, nickname, output), nil
}

func init() {
	bot.RegisterCommand(
		"kubectl",
		"Kubectl Slack integration",
		"",
		kubectl)
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"time"
)

var Servers map[string]*ServerItem

const ExpirationTime = time.Second * 30 // Server Timeout
const TokenLength = 10                  // Token length in characters

type ServerItem struct {
	Status     int
	Expiration *time.Timer
	Info       ServerInfo
}

type ServerInfo struct {
	GUID           string
	Map            string
	CurrentPlayers int
	MaxPlayers     int
	Version        string
}

// We might change how we manage servers, so have some wrappers

// Creates the Server map
func InitServers() {
	Servers = make(map[string]*ServerItem)
}

// Adds a server to the map
func AddServer(s ServerInfo) string {
	token := RandStr(10)

	server := new(ServerItem)
	server.Status = 1
	server.Info = s
	server.Expiration = time.NewTimer(ExpirationTime)

	go func() {
		<-server.Expiration.C
		DeleteServer(token)
	}()

	Servers[token] = server

	return token
}

// Updates a server in the map
func SetServer(token string, status int, s ServerInfo) error {
	if !IsServer(token) {
		return errors.New("Inexistant server")
	}

	Servers[token].Status = status
	Servers[token].Info = s
	Servers[token].Expiration.Reset(ExpirationTime)

	return nil
}

// Checks if a server is in the map. Returns True if it exists, False otherwise
func IsServer(token string) bool {
	_, ok := Servers[token]
	return ok
}

// Gets a list of all the servers in the map. It also filters on Status == 0
func GetServers(getAll bool) []ServerInfo {
	list := make([]ServerInfo, 0)

	i := 0
	for k := range Servers {
		if Servers[k].Status == 0 {
			list = append(list, Servers[k].Info)
			i++
		}
	}

	return list
}

// Deletes a server in the map, given the right token.
func DeleteServer(token string) bool {
	if IsServer(token) {
		delete(Servers, token)
		return true
	}
	return false
}
<commit_msg>Forgot to implement /all<commit_after>package main

import (
	"errors"
	"time"
)

var Servers map[string]*ServerItem

const ExpirationTime = time.Second * 30 // Server Timeout
const TokenLength = 10                  // Token length in characters

type ServerItem struct {
	Status     int
	Expiration *time.Timer
	Info       ServerInfo
}

type ServerInfo struct {
	GUID           string
	Map            string
	CurrentPlayers int
	MaxPlayers     int
	Version        string
}

// We might change how we manage servers, so have some wrappers

// Creates the Server map
func InitServers() {
	Servers = make(map[string]*ServerItem)
}

// Adds a server to the map
func AddServer(s ServerInfo) string {
	token := RandStr(10)

	server := new(ServerItem)
	server.Status = 1
	server.Info = s
	server.Expiration = time.NewTimer(ExpirationTime)

	go func() {
		<-server.Expiration.C
		DeleteServer(token)
	}()

	Servers[token] = server

	return token
}

// Updates a server in the map
func SetServer(token string, status int, s ServerInfo) error {
	if !IsServer(token) {
		return errors.New("Inexistant server")
	}

	Servers[token].Status = status
	Servers[token].Info = s
	Servers[token].Expiration.Reset(ExpirationTime)

	return nil
}

// Checks if a server is in the map. Returns True if it exists, False otherwise
func IsServer(token string) bool {
	_, ok := Servers[token]
	return ok
}

// Gets a list of all the servers in the map. It also filters on Status == 0
func GetServers(getAll bool) []ServerInfo {
	list := make([]ServerInfo, 0)

	i := 0
	for k := range Servers {
		if getAll || Servers[k].Status == 0 {
			list = append(list, Servers[k].Info)
			i++
		}
	}

	return list
}

// Deletes a server in the map, given the right token.
func DeleteServer(token string) bool {
	if IsServer(token) {
		delete(Servers, token)
		return true
	}
	return false
}
<|endoftext|>


<commit_before>package query

import (
	"pilosa/db"

	"github.com/davecgh/go-spew/spew"
	"tux21b.org/v1/gocql/uuid"
)

type QueryInput interface{}

type QueryResults struct {
	Data interface{}
}

type Query struct {
	Operation string
	Inputs    []QueryInput //"strconv"
	// Represents a parsed query. Inputs can be Query or Bitmap objects
	// Maybe Bitmap and Query objects should have different fields to avoid using interface{}
	ProfileId uint64
}

func QueryPlanForPQL(database *db.Database, pql string, destination *db.Location) *QueryPlan {
	tokens := Lex(pql)
	query_parser := QueryParser{}
	query, err := query_parser.Parse(tokens)
	spew.Dump("-------------------------------------")
	spew.Dump(query)
	spew.Dump("-------------------------------------")
	if err != nil {
		panic(err)
	}
	query_planner := QueryPlanner{Database: database}
	id := uuid.RandomUUID()
	query_plan := query_planner.Plan(query, &id, destination)
	return query_plan
}
<commit_msg>remove debugging code<commit_after>package query

import (
	"pilosa/db"
	"tux21b.org/v1/gocql/uuid"
)

type QueryInput interface{}

type QueryResults struct {
	Data interface{}
}

type Query struct {
	Operation string
	Inputs    []QueryInput //"strconv"
	// Represents a parsed query. Inputs can be Query or Bitmap objects
	// Maybe Bitmap and Query objects should have different fields to avoid using interface{}
	ProfileId uint64
}

func QueryPlanForPQL(database *db.Database, pql string, destination *db.Location) *QueryPlan {
	tokens := Lex(pql)
	query_parser := QueryParser{}
	query, err := query_parser.Parse(tokens)
	if err != nil {
		panic(err)
	}
	query_planner := QueryPlanner{Database: database}
	id := uuid.RandomUUID()
	query_plan := query_planner.Plan(query, &id, destination)
	return query_plan
}
<|endoftext|>


<commit_before>package driver

import (
	"github.com/realglobe-Inc/go-lib-rg/erro"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"time"
)

// mondodb を使うドライバー。

type mongoRegistry struct {
	dbName   string
	collName string
	*mgo.Session
}

// ユーザー情報。
func NewMongoUserRegistry(url, dbName, collName string) (UserRegistry, error) {
	sess, err := mgo.Dial(url)
	if err != nil {
		return nil, erro.Wrap(err)
	}

	usrUuidIdx := mgo.Index{
		Key:      []string{"user_uuid"},
		Unique:   true,
		DropDups: true,
		Sparse:   true,
	}
	if err := sess.DB(dbName).C(collName).EnsureIndex(usrUuidIdx); err != nil {
		return nil, erro.Wrap(err)
	}

	keyIdx := mgo.Index{
		Key:      []string{"user_uuid", "key"},
		Unique:   true,
		DropDups: true,
		Sparse:   true,
	}
	if err := sess.DB(dbName).C(collName).EnsureIndex(keyIdx); err != nil {
		return nil, erro.Wrap(err)
	}

	return &mongoRegistry{dbName, collName, sess}, nil
}

type mongoAttribute struct {
	UsrUuid  string      `bson:"user_uuid"`
	AttrName string      `bson:"key"`
	Attr     interface{} `bson:"value"`
}

func (reg *mongoRegistry) Attributes(usrUuid string) (attrs map[string]interface{}, err error) {
	query := reg.DB(reg.dbName).C(reg.collName).Find(bson.M{"user_uuid": usrUuid})
	if n, err := query.Count(); err != nil {
		return nil, erro.Wrap(err)
	} else if n == 0 {
		return nil, nil
	}
	mongoAttrs := []mongoAttribute{}
	if err := query.Iter().All(&mongoAttrs); err != nil {
		return nil, erro.Wrap(err)
	}
	attrs = map[string]interface{}{}
	for _, mongoAttr := range mongoAttrs {
		attrs[mongoAttr.AttrName] = mongoAttr.Attr
	}
	return attrs, nil
}

func (reg *mongoRegistry) Attribute(usrUuid, attrName string) (attr interface{}, err error) {
	query := reg.DB(reg.dbName).C(reg.collName).Find(bson.M{"user_uuid": usrUuid, "key": attrName})
	if n, err := query.Count(); err != nil {
		return nil, erro.Wrap(err)
	} else if n == 0 {
		return nil, nil
	}
	var mongoAttr mongoAttribute
	if err := query.One(&mongoAttr); err != nil {
		return nil, erro.Wrap(err)
	}
	return mongoAttr.Attr, nil
}

func (reg *mongoRegistry) AddAttribute(usrUuid, attrName string, attr interface{}) error {
	mongoAttr := &mongoAttribute{usrUuid, attrName, attr}
	if _, err := reg.DB(reg.dbName).C(reg.collName).Upsert(bson.M{"user_uuid": usrUuid, "key": attrName}, mongoAttr); err != nil {
		return erro.Wrap(err)
	}
	return nil
}

func (reg *mongoRegistry) RemoveAttribute(usrUuid, attrName string) error {
	if err := reg.DB(reg.dbName).C(reg.collName).Remove(bson.M{"user_uuid": usrUuid, "key": attrName}); err != nil {
		return erro.Wrap(err)
	}
	return nil
}

// ジョブ。
func NewMongoJobRegistry(url, dbName, collName string) (JobRegistry, error) {
	sess, err := mgo.Dial(url)
	if err != nil {
		return nil, erro.Wrap(err)
	}

	jobIdIdx := mgo.Index{
		Key:      []string{"job_id"},
		Unique:   true,
		DropDups: true,
		Sparse:   true,
	}
	if err := sess.DB(dbName).C(collName).EnsureIndex(jobIdIdx); err != nil {
		return nil, erro.Wrap(err)
	}

	deadlineIdx := mgo.Index{
		Key: []string{"deadline"},
	}
	if err := sess.DB(dbName).C(collName).EnsureIndex(deadlineIdx); err != nil {
		return nil, erro.Wrap(err)
	}

	return &mongoRegistry{dbName, collName, sess}, nil
}

type mongoJobResult struct {
	JobId    string            `bson:"job_id"`
	Deadline time.Time         `bson:"deadline"`
	Status   int               `bson:"status"`
	Headers  map[string]string `bson:"headers,omitempty"`
	Body     string            `bson:"body,omitempty"`
}

func (reg *mongoRegistry) Result(jobId string) (*JobResult, error) {
	query := reg.DB(reg.dbName).C(reg.collName).Find(bson.M{"job_id": jobId})
	if n, err := query.Count(); err != nil {
		return nil, erro.Wrap(err)
	} else if n == 0 {
		return nil, nil
	}
	var res mongoJobResult
	if err := query.One(&res); err != nil {
		return nil, erro.Wrap(err)
	}
	return &JobResult{res.Status, res.Headers, res.Body}, nil
}

func (reg *mongoRegistry) AddResult(jobId string, res *JobResult, deadline time.Time) error {
	mongoRes := &mongoJobResult{jobId, deadline, res.Status, res.Headers, res.Body}
	if _, err := reg.DB(reg.dbName).C(reg.collName).Upsert(bson.M{"job_id": jobId}, mongoRes); err != nil {
		return erro.Wrap(err)
	}

	// 古いのを削除。
	reg.DB(reg.dbName).C(reg.collName).RemoveAll(bson.M{"deadline": bson.M{"$lt": time.Now()}})

	return nil
}

// 別名。
func NewMongoNameRegistry(url, dbName, collName string) (NameRegistry, error) {
	sess, err := mgo.Dial(url)
	if err != nil {
		return nil, erro.Wrap(err)
	}

	jobIdIdx := mgo.Index{
		Key:      []string{"name"},
		Unique:   true,
		DropDups: true,
		Sparse:   true,
	}
	if err := sess.DB(dbName).C(collName).EnsureIndex(jobIdIdx); err != nil {
		return nil, erro.Wrap(err)
	}

	return &mongoRegistry{dbName, collName, sess}, nil
}

type mongoAddress struct {
	Name string `bson:"name"`
	Addr string `bson:"address"`
}

func (reg *mongoRegistry) Address(name string) (addr string, err error) {
	query := reg.DB(reg.dbName).C(reg.collName).Find(bson.M{"name": name})
	if n, err := query.Count(); err != nil {
		return "", erro.Wrap(err)
	} else if n == 0 {
		return "", nil
	}
	var mongoAddr mongoAddress
	if err := query.One(&mongoAddr); err != nil {
		return "", erro.Wrap(err)
	}
	return mongoAddr.Addr, nil
}

func (reg *mongoRegistry) Addresses(name string) (addrs []string, err error) {
	query := reg.DB(reg.dbName).C(reg.collName).Find(bson.M{"name": bson.M{"$regex": name + "$"}})
	var mongoAddrs []mongoAddress
	if err := query.All(&mongoAddrs); err != nil {
		return nil, erro.Wrap(err)
	}
	for _, mongoAddr := range mongoAddrs {
		addrs = append(addrs, mongoAddr.Addr)
	}
	return addrs, nil
}

// イベント。
func NewMongoEventRegistry(url, dbName, collName string) (EventRegistry, error) {
	sess, err := mgo.Dial(url)
	if err != nil {
		return nil, erro.Wrap(err)
	}

	eventIdx := mgo.Index{
		Key:      []string{"user_uuid", "event"},
		Unique:   true,
		DropDups: true,
		Sparse:   true,
	}
	if err := sess.DB(dbName).C(collName).EnsureIndex(eventIdx); err != nil {
		return nil, erro.Wrap(err)
	}

	return &mongoRegistry{dbName, collName, sess}, nil
}

type mongoHandler struct {
	UsrUuid string  `bson:"user_uuid"`
	Event   string  `bson:"event"`
	Hndl    Handler `bson:"handler"`
}

func (reg *mongoRegistry) Handler(usrUuid, event string) (Handler, error) {
	query := reg.DB(reg.dbName).C(reg.collName).Find(bson.M{"user_uuid": usrUuid, "event": event})
	if n, err := query.Count(); err != nil {
		return nil, erro.Wrap(err)
	} else if n == 0 {
		return nil, nil
	}
	var res mongoHandler
	if err := query.One(&res); err != nil {
		return nil, erro.Wrap(err)
	}
	return res.Hndl, nil
}

func (reg *mongoRegistry) AddHandler(usrUuid, event string, hndl Handler) error {
	mongoHndl := &mongoHandler{usrUuid, event, hndl}
	if _, err := reg.DB(reg.dbName).C(reg.collName).Upsert(bson.M{"user_uuid": usrUuid, "event": event}, mongoHndl); err != nil {
		return erro.Wrap(err)
	}
	return nil
}

func (reg *mongoRegistry) RemoveHandler(usrUuid, event string) error {
	if err := reg.DB(reg.dbName).C(reg.collName).Remove(bson.M{"user_uuid": usrUuid, "event": event}); err != nil {
		return erro.Wrap(err)
	}
	return nil
}
<commit_msg>変数名を変更<commit_after>package driver

import (
	"github.com/realglobe-Inc/go-lib-rg/erro"
	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
	"time"
)

// mondodb を使うドライバー。

type mongoRegistry struct {
	dbName   string
	collName string
	*mgo.Session
}

// ユーザー情報。
func NewMongoUserRegistry(url, dbName, collName string) (UserRegistry, error) {
	sess, err := mgo.Dial(url)
	if err != nil {
		return nil, erro.Wrap(err)
	}

	usrUuidIdx := mgo.Index{
		Key:      []string{"user_uuid"},
		Unique:   true,
		DropDups: true,
		Sparse:   true,
	}
	if err := sess.DB(dbName).C(collName).EnsureIndex(usrUuidIdx); err != nil {
		return nil, erro.Wrap(err)
	}

	keyIdx := mgo.Index{
		Key:      []string{"user_uuid", "key"},
		Unique:   true,
		DropDups: true,
		Sparse:   true,
	}
	if err := sess.DB(dbName).C(collName).EnsureIndex(keyIdx); err != nil {
		return nil, erro.Wrap(err)
	}

	return &mongoRegistry{dbName, collName, sess}, nil
}

type mongoAttribute struct {
	UsrUuid  string      `bson:"user_uuid"`
	AttrName string      `bson:"key"`
	Attr     interface{} `bson:"value"`
}

func (reg *mongoRegistry) Attributes(usrUuid string) (attrs map[string]interface{}, err error) {
	query := reg.DB(reg.dbName).C(reg.collName).Find(bson.M{"user_uuid": usrUuid})
	if n, err := query.Count(); err != nil {
		return nil, erro.Wrap(err)
	} else if n == 0 {
		return nil, nil
	}
	mongoAttrs := []mongoAttribute{}
	if err := query.Iter().All(&mongoAttrs); err != nil {
		return nil, erro.Wrap(err)
	}
	attrs = map[string]interface{}{}
	for _, mongoAttr := range mongoAttrs {
		attrs[mongoAttr.AttrName] = mongoAttr.Attr
	}
	return attrs, nil
}

func (reg *mongoRegistry) Attribute(usrUuid, attrName string) (attr interface{}, err error) {
	query := reg.DB(reg.dbName).C(reg.collName).Find(bson.M{"user_uuid": usrUuid, "key": attrName})
	if n, err := query.Count(); err != nil {
		return nil, erro.Wrap(err)
	} else if n == 0 {
		return nil, nil
	}
	var mongoAttr mongoAttribute
	if err := query.One(&mongoAttr); err != nil {
		return nil, erro.Wrap(err)
	}
	return mongoAttr.Attr, nil
}

func (reg *mongoRegistry) AddAttribute(usrUuid, attrName string, attr interface{}) error {
	mongoAttr := &mongoAttribute{usrUuid, attrName, attr}
	if _, err := reg.DB(reg.dbName).C(reg.collName).Upsert(bson.M{"user_uuid": usrUuid, "key": attrName}, mongoAttr); err != nil {
		return erro.Wrap(err)
	}
	return nil
}

func (reg *mongoRegistry) RemoveAttribute(usrUuid, attrName string) error {
	if err := reg.DB(reg.dbName).C(reg.collName).Remove(bson.M{"user_uuid": usrUuid, "key": attrName}); err != nil {
		return erro.Wrap(err)
	}
	return nil
}

// ジョブ。
func NewMongoJobRegistry(url, dbName, collName string) (JobRegistry, error) {
	sess, err := mgo.Dial(url)
	if err != nil {
		return nil, erro.Wrap(err)
	}

	jobIdIdx := mgo.Index{
		Key:      []string{"job_id"},
		Unique:   true,
		DropDups: true,
		Sparse:   true,
	}
	if err := sess.DB(dbName).C(collName).EnsureIndex(jobIdIdx); err != nil {
		return nil, erro.Wrap(err)
	}

	deadlineIdx := mgo.Index{
		Key: []string{"deadline"},
	}
	if err := sess.DB(dbName).C(collName).EnsureIndex(deadlineIdx); err != nil {
		return nil, erro.Wrap(err)
	}

	return &mongoRegistry{dbName, collName, sess}, nil
}

type mongoJobResult struct {
	JobId    string            `bson:"job_id"`
	Deadline time.Time         `bson:"deadline"`
	Status   int               `bson:"status"`
	Headers  map[string]string `bson:"headers,omitempty"`
	Body     string            `bson:"body,omitempty"`
}

func (reg *mongoRegistry) Result(jobId string) (*JobResult, error) {
	query := reg.DB(reg.dbName).C(reg.collName).Find(bson.M{"job_id": jobId})
	if n, err := query.Count(); err != nil {
		return nil, erro.Wrap(err)
	} else if n == 0 {
		return nil, nil
	}
	var res mongoJobResult
	if err := query.One(&res); err != nil {
		return nil, erro.Wrap(err)
	}
	return &JobResult{res.Status, res.Headers, res.Body}, nil
}

func (reg *mongoRegistry) AddResult(jobId string, res *JobResult, deadline time.Time) error {
	mongoRes := &mongoJobResult{jobId, deadline, res.Status, res.Headers, res.Body}
	if _, err := reg.DB(reg.dbName).C(reg.collName).Upsert(bson.M{"job_id": jobId}, mongoRes); err != nil {
		return erro.Wrap(err)
	}

	// 古いのを削除。
	reg.DB(reg.dbName).C(reg.collName).RemoveAll(bson.M{"deadline": bson.M{"$lt": time.Now()}})

	return nil
}

// 別名。
func NewMongoNameRegistry(url, dbName, collName string) (NameRegistry, error) {
	sess, err := mgo.Dial(url)
	if err != nil {
		return nil, erro.Wrap(err)
	}

	nameIdx := mgo.Index{
		Key:      []string{"name"},
		Unique:   true,
		DropDups: true,
		Sparse:   true,
	}
	if err := sess.DB(dbName).C(collName).EnsureIndex(nameIdx); err != nil {
		return nil, erro.Wrap(err)
	}

	return &mongoRegistry{dbName, collName, sess}, nil
}

type mongoAddress struct {
	Name string `bson:"name"`
	Addr string `bson:"address"`
}

func (reg *mongoRegistry) Address(name string) (addr string, err error) {
	query := reg.DB(reg.dbName).C(reg.collName).Find(bson.M{"name": name})
	if n, err := query.Count(); err != nil {
		return "", erro.Wrap(err)
	} else if n == 0 {
		return "", nil
	}
	var mongoAddr mongoAddress
	if err := query.One(&mongoAddr); err != nil {
		return "", erro.Wrap(err)
	}
	return mongoAddr.Addr, nil
}

func (reg *mongoRegistry) Addresses(name string) (addrs []string, err error) {
	query := reg.DB(reg.dbName).C(reg.collName).Find(bson.M{"name": bson.M{"$regex": name + "$"}})
	var mongoAddrs []mongoAddress
	if err := query.All(&mongoAddrs); err != nil {
		return nil, erro.Wrap(err)
	}
	for _, mongoAddr := range mongoAddrs {
		addrs = append(addrs, mongoAddr.Addr)
	}
	return addrs, nil
}

// イベント。
func NewMongoEventRegistry(url, dbName, collName string) (EventRegistry, error) {
	sess, err := mgo.Dial(url)
	if err != nil {
		return nil, erro.Wrap(err)
	}

	eventIdx := mgo.Index{
		Key:      []string{"user_uuid", "event"},
		Unique:   true,
		DropDups: true,
		Sparse:   true,
	}
	if err := sess.DB(dbName).C(collName).EnsureIndex(eventIdx); err != nil {
		return nil, erro.Wrap(err)
	}

	return &mongoRegistry{dbName, collName, sess}, nil
}

type mongoHandler struct {
	UsrUuid string  `bson:"user_uuid"`
	Event   string  `bson:"event"`
	Hndl    Handler `bson:"handler"`
}

func (reg *mongoRegistry) Handler(usrUuid, event string) (Handler, error) {
	query := reg.DB(reg.dbName).C(reg.collName).Find(bson.M{"user_uuid": usrUuid, "event": event})
	if n, err := query.Count(); err != nil {
		return nil, erro.Wrap(err)
	} else if n == 0 {
		return nil, nil
	}
	var res mongoHandler
	if err := query.One(&res); err != nil {
		return nil, erro.Wrap(err)
	}
	return res.Hndl, nil
}

func (reg *mongoRegistry) AddHandler(usrUuid, event string, hndl Handler) error {
	mongoHndl := &mongoHandler{usrUuid, event, hndl}
	if _, err := reg.DB(reg.dbName).C(reg.collName).Upsert(bson.M{"user_uuid": usrUuid, "event": event}, mongoHndl); err != nil {
		return erro.Wrap(err)
	}
	return nil
}

func (reg *mongoRegistry) RemoveHandler(usrUuid, event string) error {
	if err := reg.DB(reg.dbName).C(reg.collName).Remove(bson.M{"user_uuid": usrUuid, "event": event}); err != nil {
		return erro.Wrap(err)
	}
	return nil
}
<|endoftext|>


<commit_before>package vfs

import (
	"fmt"
	"os"
	"path"
	"strings"
)

const (
	separator = "/"
)

func hasSubdir(root, dir string) (string, bool) {
	root = path.Clean(root)
	if !strings.HasSuffix(root, separator) {
		root += separator
	}
	dir = path.Clean(dir)
	if !strings.HasPrefix(dir, root) {
		return "", false
	}
	return dir[len(root):], true
}

type mountPoint struct {
	point string
	fs    VFS
}

func (m *mountPoint) String() string {
	return fmt.Sprintf("%s at %s", m.fs, m.point)
}

// Mounter implements he VFS interface and allows mounting different virtual
// file systems at arbitraty points, working much like a UNIX filesystem.
// Note that the first mounted filesystem must be always at "/".
type Mounter struct {
	points []*mountPoint
}

func (m *Mounter) fs(p string) (VFS, string, error) {
	for ii := len(m.points) - 1; ii >= 0; ii-- {
		if rel, ok := hasSubdir(m.points[ii].point, p); ok {
			return m.points[ii].fs, rel, nil
		}
	}
	return nil, "", os.ErrNotExist
}

// Mount mounts the given filesystem at the given mount point. Unless the
// mount point is /, it must be an already existing directory.
func (m *Mounter) Mount(fs VFS, point string) error {
	point = path.Clean(point)
	if point == "." || point == "" {
		point = "/"
	}
	if point == "/" {
		if len(m.points) > 0 {
			return fmt.Errorf("%s is already mounted at /", m.points[0])
		}
		m.points = append(m.points, &mountPoint{point, fs})
		return nil
	}
	stat, err := m.Stat(point)
	if err != nil {
		return err
	}
	if !stat.IsDir() {
		return fmt.Errorf("%s is not a directory", point)
	}
	m.points = append(m.points, &mountPoint{point, fs})
	return nil
}

// Umount umounts the filesystem from the given mount point. If there are other filesystems
// mounted below it or there's no filesystem mounted at that point, an error is returned.
func (m *Mounter) Umount(point string) error {
	point = path.Clean(point)
	for ii, v := range m.points {
		if v.point == point {
			// Check if we have mount points below this one
			for _, vv := range m.points[ii:] {
				if _, ok := hasSubdir(v.point, vv.point); ok {
					return fmt.Errorf("can't umount %s because %s is mounted below it", point, vv)
				}
			}
			m.points = append(m.points[:ii], m.points[ii+1:]...)
			return nil
		}
	}
	return fmt.Errorf("no filesystem mounted at %s", point)
}

func (m *Mounter) Open(path string) (RFile, error) {
	fs, p, err := m.fs(path)
	if err != nil {
		return nil, err
	}
	return fs.Open(p)
}

func (m *Mounter) OpenFile(path string, flag int, perm os.FileMode) (WFile, error) {
	fs, p, err := m.fs(path)
	if err != nil {
		return nil, err
	}
	return fs.OpenFile(p, flag, perm)
}

func (m *Mounter) Lstat(path string) (os.FileInfo, error) {
	fs, p, err := m.fs(path)
	if err != nil {
		return nil, err
	}
	return fs.Lstat(p)
}

func (m *Mounter) Stat(path string) (os.FileInfo, error) {
	fs, p, err := m.fs(path)
	if err != nil {
		return nil, err
	}
	return fs.Stat(p)
}

func (m *Mounter) ReadDir(path string) ([]os.FileInfo, error) {
	fs, p, err := m.fs(path)
	if err != nil {
		return nil, err
	}
	return fs.ReadDir(p)
}

func (m *Mounter) Mkdir(path string, perm os.FileMode) error {
	fs, p, err := m.fs(path)
	if err != nil {
		return err
	}
	return fs.Mkdir(p, perm)
}

func (m *Mounter) Remove(path string) error {
	// TODO: Don't allow removing an empty directory
	// with a mount below it.
	fs, p, err := m.fs(path)
	if err != nil {
		return err
	}
	return fs.Remove(p)
}

func (m *Mounter) String() string {
	s := make([]string, len(m.points))
	for ii, v := range m.points {
		s[ii] = v.String()
	}
	return fmt.Sprintf("Mounter: %s", strings.Join(s, ", "))
}

func mounterCompileTimeCheck() VFS {
	return &Mounter{}
}
<commit_msg>Fix typo in comment<commit_after>package vfs

import (
	"fmt"
	"os"
	"path"
	"strings"
)

const (
	separator = "/"
)

func hasSubdir(root, dir string) (string, bool) {
	root = path.Clean(root)
	if !strings.HasSuffix(root, separator) {
		root += separator
	}
	dir = path.Clean(dir)
	if !strings.HasPrefix(dir, root) {
		return "", false
	}
	return dir[len(root):], true
}

type mountPoint struct {
	point string
	fs    VFS
}

func (m *mountPoint) String() string {
	return fmt.Sprintf("%s at %s", m.fs, m.point)
}

// Mounter implements the VFS interface and allows mounting different virtual
// file systems at arbitraty points, working much like a UNIX filesystem.
// Note that the first mounted filesystem must be always at "/".
type Mounter struct {
	points []*mountPoint
}

func (m *Mounter) fs(p string) (VFS, string, error) {
	for ii := len(m.points) - 1; ii >= 0; ii-- {
		if rel, ok := hasSubdir(m.points[ii].point, p); ok {
			return m.points[ii].fs, rel, nil
		}
	}
	return nil, "", os.ErrNotExist
}

// Mount mounts the given filesystem at the given mount point. Unless the
// mount point is /, it must be an already existing directory.
func (m *Mounter) Mount(fs VFS, point string) error {
	point = path.Clean(point)
	if point == "." || point == "" {
		point = "/"
	}
	if point == "/" {
		if len(m.points) > 0 {
			return fmt.Errorf("%s is already mounted at /", m.points[0])
		}
		m.points = append(m.points, &mountPoint{point, fs})
		return nil
	}
	stat, err := m.Stat(point)
	if err != nil {
		return err
	}
	if !stat.IsDir() {
		return fmt.Errorf("%s is not a directory", point)
	}
	m.points = append(m.points, &mountPoint{point, fs})
	return nil
}

// Umount umounts the filesystem from the given mount point. If there are other filesystems
// mounted below it or there's no filesystem mounted at that point, an error is returned.
func (m *Mounter) Umount(point string) error {
	point = path.Clean(point)
	for ii, v := range m.points {
		if v.point == point {
			// Check if we have mount points below this one
			for _, vv := range m.points[ii:] {
				if _, ok := hasSubdir(v.point, vv.point); ok {
					return fmt.Errorf("can't umount %s because %s is mounted below it", point, vv)
				}
			}
			m.points = append(m.points[:ii], m.points[ii+1:]...)
			return nil
		}
	}
	return fmt.Errorf("no filesystem mounted at %s", point)
}

func (m *Mounter) Open(path string) (RFile, error) {
	fs, p, err := m.fs(path)
	if err != nil {
		return nil, err
	}
	return fs.Open(p)
}

func (m *Mounter) OpenFile(path string, flag int, perm os.FileMode) (WFile, error) {
	fs, p, err := m.fs(path)
	if err != nil {
		return nil, err
	}
	return fs.OpenFile(p, flag, perm)
}

func (m *Mounter) Lstat(path string) (os.FileInfo, error) {
	fs, p, err := m.fs(path)
	if err != nil {
		return nil, err
	}
	return fs.Lstat(p)
}

func (m *Mounter) Stat(path string) (os.FileInfo, error) {
	fs, p, err := m.fs(path)
	if err != nil {
		return nil, err
	}
	return fs.Stat(p)
}

func (m *Mounter) ReadDir(path string) ([]os.FileInfo, error) {
	fs, p, err := m.fs(path)
	if err != nil {
		return nil, err
	}
	return fs.ReadDir(p)
}

func (m *Mounter) Mkdir(path string, perm os.FileMode) error {
	fs, p, err := m.fs(path)
	if err != nil {
		return err
	}
	return fs.Mkdir(p, perm)
}

func (m *Mounter) Remove(path string) error {
	// TODO: Don't allow removing an empty directory
	// with a mount below it.
	fs, p, err := m.fs(path)
	if err != nil {
		return err
	}
	return fs.Remove(p)
}

func (m *Mounter) String() string {
	s := make([]string, len(m.points))
	for ii, v := range m.points {
		s[ii] = v.String()
	}
	return fmt.Sprintf("Mounter: %s", strings.Join(s, ", "))
}

func mounterCompileTimeCheck() VFS {
	return &Mounter{}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"go/ast"
	"go/parser"
	"go/printer"
	"go/token"
	"os"
	"path/filepath"
)

var operators = map[string]token.Token{
	"==": token.EQL,
	"!=": token.NEQ,
}

type Visitor struct {
	Token token.Token
	Exps  []*ast.BinaryExpr
}

func (v *Visitor) Visit(node ast.Node) ast.Visitor {
	if exp, ok := node.(*ast.BinaryExpr); ok {
		if exp.Op == v.Token {
			v.Exps = append(v.Exps, exp)
		}
	}
	return v
}

func Err(s string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "error: "+s, args...)
}

func Errf(s string, args ...interface{}) {
	Err(s, args...)
	os.Exit(1)
}

func main() {
	op := flag.String("op", "==", "operator to look for")
	rep := flag.String("rep", "!=", "replacement operator")
	outdir := flag.String("o", ".", "output directory")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: mutator [flags] [filename]\n")
		flag.PrintDefaults()
	}
	flag.Parse()

	if _, ok := operators[*op]; !ok {
		Errf("%s is not a valid mutator\n", *op)
	}
	if _, ok := operators[*rep]; !ok {
		Errf("%s is not a valid replacement\n", *rep)
	}

	filename := flag.Arg(0)
	if filename == "" {
		flag.Usage()
		Errf("must provide a filename\n")
	}
	fset := token.NewFileSet()
	file, err := parser.ParseFile(fset, filename, nil, parser.ParseComments)
	if err != nil {
		Errf("could not parse %s: %s\n", filename, err)
	}

	visitor := Visitor{Token: operators[*op]}
	ast.Walk(&visitor, file)

	fmt.Printf("You have %d occurences of %s\n", len(visitor.Exps), *op)
	for i, exp := range visitor.Exps {
		name := filepath.Base(filename)
		dir := filepath.Join(*outdir, fmt.Sprintf("%s_%d", name, i))
		if err := os.Mkdir(dir, 0770); err != nil {
			Err("could not create directory: %s\n", err)
			continue
		}
		path := filepath.Join(dir, name)
		fmt.Println(path)
		func() {
			out, err := os.Create(path)
			if err != nil {
				Err("could not create file: %s\n", err)
				return
			}
			defer out.Close()

			oldOp := exp.Op
			exp.Op = operators[*op]
			printer.Fprint(out, fset, file)
			exp.Op = oldOp
		}()
	}
}
<commit_msg>Replace the operator correctly.<commit_after>package main

import (
	"flag"
	"fmt"
	"go/ast"
	"go/parser"
	"go/printer"
	"go/token"
	"os"
	"path/filepath"
)

var operators = map[string]token.Token{
	"==": token.EQL,
	"!=": token.NEQ,
}

type Visitor struct {
	Token token.Token
	Exps  []*ast.BinaryExpr
}

func (v *Visitor) Visit(node ast.Node) ast.Visitor {
	if exp, ok := node.(*ast.BinaryExpr); ok {
		if exp.Op == v.Token {
			v.Exps = append(v.Exps, exp)
		}
	}
	return v
}

func Err(s string, args ...interface{}) {
	fmt.Fprintf(os.Stderr, "error: "+s, args...)
}

func Errf(s string, args ...interface{}) {
	Err(s, args...)
	os.Exit(1)
}

func main() {
	op := flag.String("op", "==", "operator to look for")
	rep := flag.String("rep", "!=", "replacement operator")
	outdir := flag.String("o", ".", "output directory")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "Usage: mutator [flags] [filename]\n")
		flag.PrintDefaults()
	}
	flag.Parse()

	if _, ok := operators[*op]; !ok {
		Errf("%s is not a valid mutator\n", *op)
	}
	if _, ok := operators[*rep]; !ok {
		Errf("%s is not a valid replacement\n", *rep)
	}

	filename := flag.Arg(0)
	if filename == "" {
		flag.Usage()
		Errf("must provide a filename\n")
	}
	fset := token.NewFileSet()
	file, err := parser.ParseFile(fset, filename, nil, parser.ParseComments)
	if err != nil {
		Errf("could not parse %s: %s\n", filename, err)
	}

	visitor := Visitor{Token: operators[*op]}
	ast.Walk(&visitor, file)

	fmt.Printf("You have %d occurences of %s\n", len(visitor.Exps), *op)
	for i, exp := range visitor.Exps {
		name := filepath.Base(filename)
		dir := filepath.Join(*outdir, fmt.Sprintf("%s_%d", name, i))
		if err := os.Mkdir(dir, 0770); err != nil {
			Err("could not create directory: %s\n", err)
			continue
		}
		path := filepath.Join(dir, name)
		fmt.Println(path)
		func() {
			out, err := os.Create(path)
			if err != nil {
				Err("could not create file: %s\n", err)
				return
			}
			defer out.Close()

			oldOp := exp.Op
			exp.Op = operators[*rep]
			printer.Fprint(out, fset, file)
			exp.Op = oldOp
		}()
	}
}
<|endoftext|>