<commit_before>package glacier

import (
	"crypto/sha256"
	"fmt"
	"hash"
	"io"
)

const (
	KiB = 1024
	MiB = 1024 * KiB
)

type treeHashNode struct {
	Hash  [sha256.Size]byte
	Left  *treeHashNode
	Right *treeHashNode
}

type TreeHash struct {
	whole   hash.Hash
	part    hash.Hash
	hashers io.Writer
	hashes  []treeHashNode
	written int
}

func NewTreeHash() *TreeHash {
	var result TreeHash
	result.whole = sha256.New()
	result.part = sha256.New()
	result.hashers = io.MultiWriter(result.whole, result.part)
	result.hashes = make([]treeHashNode, 0)
	return &result
}

func (th *TreeHash) Write(p []byte) (n int, err error) {
	if len(p) > 1024*1024 {
		th.written = 0
	}
	var nn int
	for len(p) > 1024*1024 {
		nn, _ = th.hashers.Write(p[:1024*1024-th.written])
		n += nn
		// hash part and add to tree
		p = p[nn:]
	}

	// complete chunk and write part of next one
	if th.written+len(p) > 1024*1024 {

	}

	// not enough to complete a 1 MiB chunk
	if len(p) < 1024*1024-th.written {
		nn, _ = th.hashers.Write(p)
		n += nn
		th.written += nn
	}

	return
}

func (th *TreeHash) Close() error {
	// complete last chunk
	return nil
}

func (th *TreeHash) TreeHash() string {
	return ""
}

func (th *TreeHash) Hash() string {
	return ""
}

// TODO hash entire file at the same time
func createTreeHash(r io.Reader) (*treeHashNode, []byte, error) {
	wholeHash := sha256.New()
	partHash := sha256.New()
	hashers := io.MultiWriter(partHash, wholeHash)
	hashes := make([]treeHashNode, 0)
	outIndex := 0

	// generate hashes for 1 MiB chunks
	n, err := io.CopyN(hashers, r, MiB)
	for err == nil {
		hashes = append(hashes, treeHashNode{})
		partHash.Sum(hashes[outIndex].Hash[:0])
		partHash.Reset()
		outIndex++
		n, err = io.CopyN(hashers, r, MiB)
	}
	if err != nil && err != io.EOF {
		return nil, nil, err
	}
	if n > 0 {
		hashes = append(hashes, treeHashNode{})
		partHash.Sum(hashes[outIndex].Hash[:0])
		partHash.Reset()
		outIndex++
	}

	// build tree
	// TODO calculate levels remaining and grow once
	childIndex := 0
	added := outIndex
	remainderIndex := -1
	for added > 1 || remainderIndex != -1 {
		children := added
		added = 0
		// pair up
		for children > 1 {
			hashes = append(hashes, treeHashNode{})
			hashes[outIndex].Left = &hashes[childIndex]
			hashes[outIndex].Right = &hashes[childIndex+1]
			partHash.Write(hashes[childIndex].Hash[:])
			partHash.Write(hashes[childIndex+1].Hash[:])
			partHash.Sum(hashes[outIndex].Hash[:0])
			partHash.Reset()
			outIndex++

			children -= 2
			childIndex += 2
			added++
		}
		if children == 1 {
			// have a remainder that couldn't be paired up
			if remainderIndex == -1 {
				// hold on to remainder for later
				remainderIndex = childIndex
				childIndex++
			} else {
				// join with existing remainder
				hashes = append(hashes, treeHashNode{})
				hashes[outIndex].Left = &hashes[childIndex]
				hashes[outIndex].Right = &hashes[remainderIndex]
				partHash.Write(hashes[childIndex].Hash[:])
				partHash.Write(hashes[remainderIndex].Hash[:])
				partHash.Sum(hashes[outIndex].Hash[:0])
				partHash.Reset()
				outIndex++

				remainderIndex = -1
				childIndex++
				added++
			}
		}
	}

	return &hashes[outIndex-1], wholeHash.Sum(nil), nil
}

func (t *treeHashNode) node() string {
	name := fmt.Sprintf("\"%p\"", t)
	label := fmt.Sprintf("\tlabel = \"%s\"\n", string(toHex(t.Hash[:4])))

	node := name + " [\n" + label + "];\n"

	var edges string
	if t.Left != nil {
		left := fmt.Sprintf("\"%p\"", t.Left)
		edges += name + " -> " + left + ";\n"
	}
	if t.Right != nil {
		right := fmt.Sprintf("\"%p\"", t.Right)
		edges += name + " -> " + right + ";\n"
	}

	return node + edges
}

func (t *treeHashNode) dot() string {
	digraph := "digraph g {\n"
	digraph += "node [\n\tshape = box\n];\n"

	var recurse func(t *treeHashNode)
	recurse = func(t *treeHashNode) {
		if t.Left != nil {
			recurse(t.Left)
		}
		if t.Right != nil {
			recurse(t.Right)
		}
		digraph += t.node()
	}
	recurse(t)

	digraph += "{\n\trank=same;\n"
	recurse = func(t *treeHashNode) {
		if t.Left == nil && t.Right == nil {
			digraph += fmt.Sprintf("\t\"%p\"\n", t)
		} else {
			if t.Left != nil {
				recurse(t.Left)
			}
			if t.Right != nil {
				recurse(t.Right)
			}
		}
	}
	recurse(t)
	digraph += "}\n"

	digraph += "}\n"
	return digraph
}
<commit_msg>Have tree hash writer, untested.<commit_after>package glacier

import (
	"crypto/sha256"
	"fmt"
	"hash"
	"io"
)

const (
	KiB = 1024
	MiB = 1024 * KiB
)

type treeHashNode struct {
	Hash  [sha256.Size]byte
	Left  *treeHashNode
	Right *treeHashNode
}

type TreeHash struct {
	whole   hash.Hash
	part    hash.Hash
	hashers io.Writer
	written int
	nodes   []treeHashNode
}

func NewTreeHash() *TreeHash {
	var result TreeHash
	result.whole = sha256.New()
	result.part = sha256.New()
	result.hashers = io.MultiWriter(result.whole, result.part)
	result.nodes = make([]treeHashNode, 0)
	return &result
}

func (th *TreeHash) Write(p []byte) (n int, err error) {
	// check if we can't fill up remaining chunk
	if len(p) < 1024*1024-th.written {
		n, err = th.hashers.Write(p)
		th.written += n
		return
	}

	// fill remaining chunk
	nn, _ := th.hashers.Write(p[:1024*1024-th.written])
	n += nn
	p = p[nn:]
	th.nodes = append(th.nodes, treeHashNode{})
	th.part.Sum(th.nodes[len(th.nodes)-1].Hash[:0])
	th.part.Reset()

	// write all full chunks
	th.written = 0
	for len(p) > 1024*1024 {
		nn, _ = th.hashers.Write(p[:1024*1024-th.written])
		n += nn
		p = p[nn:]
		th.nodes = append(th.nodes, treeHashNode{})
		th.part.Sum(th.nodes[len(th.nodes)-1].Hash[:0])
		th.part.Reset()
	}

	th.written, _ = th.hashers.Write(p)
	n += th.written

	return
}

func (th *TreeHash) Close() error {
	// create last node
	th.nodes = append(th.nodes, treeHashNode{})
	th.part.Sum(th.nodes[len(th.nodes)-1].Hash[:0])
	th.part.Reset()

	// create tree
	outIndex := len(th.nodes)
	childIndex := 0
	added := outIndex
	remainderIndex := -1
	for added > 1 || remainderIndex != -1 {
		children := added
		added = 0
		// pair up
		for children > 1 {
			th.nodes = append(th.nodes, treeHashNode{})
			th.nodes[outIndex].Left = &th.nodes[childIndex]
			th.nodes[outIndex].Right = &th.nodes[childIndex+1]
			th.part.Write(th.nodes[childIndex].Hash[:])
			th.part.Write(th.nodes[childIndex+1].Hash[:])
			th.part.Sum(th.nodes[outIndex].Hash[:0])
			th.part.Reset()
			outIndex++

			children -= 2
			childIndex += 2
			added++
		}
		if children == 1 {
			// have a remainder that couldn't be paired up
			if remainderIndex == -1 {
				// hold on to remainder for later
				remainderIndex = childIndex
				childIndex++
			} else {
				// join with existing remainder
				th.nodes = append(th.nodes, treeHashNode{})
				th.nodes[outIndex].Left = &th.nodes[childIndex]
				th.nodes[outIndex].Right = &th.nodes[remainderIndex]
				th.part.Write(th.nodes[childIndex].Hash[:])
				th.part.Write(th.nodes[remainderIndex].Hash[:])
				th.part.Sum(th.nodes[outIndex].Hash[:0])
				th.part.Reset()
				outIndex++

				remainderIndex = -1
				childIndex++
				added++
			}
		}
	}
	return nil
}

func (th *TreeHash) TreeHash() string {
	return string(toHex(th.nodes[len(th.nodes)-1].Hash[:]))
}

func (th *TreeHash) Hash() string {
	return string(toHex(th.whole.Sum(nil)))
}

func (th *TreeHash) Reset() {
	th.whole.Reset()
	th.part.Reset()
	th.written = 0
	th.nodes = th.nodes[:0]
}

// TODO hash entire file at the same time
func createTreeHash(r io.Reader) (*treeHashNode, []byte, error) {
	wholeHash := sha256.New()
	partHash := sha256.New()
	hashers := io.MultiWriter(partHash, wholeHash)
	hashes := make([]treeHashNode, 0)
	outIndex := 0

	// generate hashes for 1 MiB chunks
	n, err := io.CopyN(hashers, r, MiB)
	for err == nil {
		hashes = append(hashes, treeHashNode{})
		partHash.Sum(hashes[outIndex].Hash[:0])
		partHash.Reset()
		outIndex++
		n, err = io.CopyN(hashers, r, MiB)
	}
	if err != nil && err != io.EOF {
		return nil, nil, err
	}
	if n > 0 {
		hashes = append(hashes, treeHashNode{})
		partHash.Sum(hashes[outIndex].Hash[:0])
		partHash.Reset()
		outIndex++
	}

	// build tree
	// TODO calculate levels remaining and grow once
	childIndex := 0
	added := outIndex
	remainderIndex := -1
	for added > 1 || remainderIndex != -1 {
		children := added
		added = 0
		// pair up
		for children > 1 {
			hashes = append(hashes, treeHashNode{})
			hashes[outIndex].Left = &hashes[childIndex]
			hashes[outIndex].Right = &hashes[childIndex+1]
			partHash.Write(hashes[childIndex].Hash[:])
			partHash.Write(hashes[childIndex+1].Hash[:])
			partHash.Sum(hashes[outIndex].Hash[:0])
			partHash.Reset()
			outIndex++

			children -= 2
			childIndex += 2
			added++
		}
		if children == 1 {
			// have a remainder that couldn't be paired up
			if remainderIndex == -1 {
				// hold on to remainder for later
				remainderIndex = childIndex
				childIndex++
			} else {
				// join with existing remainder
				hashes = append(hashes, treeHashNode{})
				hashes[outIndex].Left = &hashes[childIndex]
				hashes[outIndex].Right = &hashes[remainderIndex]
				partHash.Write(hashes[childIndex].Hash[:])
				partHash.Write(hashes[remainderIndex].Hash[:])
				partHash.Sum(hashes[outIndex].Hash[:0])
				partHash.Reset()
				outIndex++

				remainderIndex = -1
				childIndex++
				added++
			}
		}
	}

	return &hashes[outIndex-1], wholeHash.Sum(nil), nil
}

func (t *treeHashNode) node() string {
	name := fmt.Sprintf("\"%p\"", t)
	label := fmt.Sprintf("\tlabel = \"%s\"\n", string(toHex(t.Hash[:4])))

	node := name + " [\n" + label + "];\n"

	var edges string
	if t.Left != nil {
		left := fmt.Sprintf("\"%p\"", t.Left)
		edges += name + " -> " + left + ";\n"
	}
	if t.Right != nil {
		right := fmt.Sprintf("\"%p\"", t.Right)
		edges += name + " -> " + right + ";\n"
	}

	return node + edges
}

func (t *treeHashNode) dot() string {
	digraph := "digraph g {\n"
	digraph += "node [\n\tshape = box\n];\n"

	var recurse func(t *treeHashNode)
	recurse = func(t *treeHashNode) {
		if t.Left != nil {
			recurse(t.Left)
		}
		if t.Right != nil {
			recurse(t.Right)
		}
		digraph += t.node()
	}
	recurse(t)

	digraph += "{\n\trank=same;\n"
	recurse = func(t *treeHashNode) {
		if t.Left == nil && t.Right == nil {
			digraph += fmt.Sprintf("\t\"%p\"\n", t)
		} else {
			if t.Left != nil {
				recurse(t.Left)
			}
			if t.Right != nil {
				recurse(t.Right)
			}
		}
	}
	recurse(t)
	digraph += "}\n"

	digraph += "}\n"
	return digraph
}
<|endoftext|>


<commit_before>package cairo

//#cgo pkg-config: cairo
//#include <stdlib.h>
//#include <stdint.h>
//#include <cairo/cairo.h>
//
//static void* cgo_id_malloc(uint64_t id) {
//	uint64_t* p = (uint64_t*) malloc(sizeof(uint64_t));
//	*p = id;
//	return p;
//}
//
//static void gocairo_free(void* data) {
//	free(data);
//}
//
//static cairo_destroy_func_t gocairo_free_get() {
//	return &gocairo_free;
//}
import "C"

import (
	"sync"
	"unsafe"
)

var free = C.gocairo_free_get()

type (
	id        uint64
	subtypeID uint64
)

func (s subtypeID) c() unsafe.Pointer {
	return C.cgo_id_malloc(C.uint64_t(s))
}

var (
	nextID uint64
	idmux  = &sync.Mutex{}
	idkey  = &C.cairo_user_data_key_t{}
	stkey  = &C.cairo_user_data_key_t{}

	subtypes = map[string]subtypeID{}
)

func generateID() unsafe.Pointer {
	idmux.Lock()
	defer idmux.Unlock()

	p := C.cgo_id_malloc(C.uint64_t(nextID))
	nextID++
	return unsafe.Pointer(p)
}

func ctoint(p unsafe.Pointer) uint64 {
	return uint64(*(*C.uint64_t)(p))
}

func surfaceSetID(s *C.cairo_surface_t) {
	if C.cairo_surface_get_user_data(s, idkey) != nil {
		return
	}
	C.cairo_surface_set_user_data(s, idkey, generateID(), free)
}

func surfaceGetID(s *C.cairo_surface_t) id {
	p := C.cairo_surface_get_user_data(s, idkey)
	if p == nil {
		panic("surface does not have ID - created outside of cairo binding and not registered")
	}
	return id(ctoint(p))
}

//XtensionRegisterAlienSurface registers a surface created outside of this
//package and creates a Surface of the proper type.
//
//This is only necessary if you are using another library that creates its own
//libcairo surface that will interact with this package.
//
//If s is a mapped image surface you must use XtensionRegisterAlienMappedSurface.
func XtensionRegisterAlienSurface(s *C.cairo_surface_t) (Surface, error) {
	surfaceSetID(s)
	return XtensionRevivifySurface(s)
}

//XtensionRegisterAlienMappedSurface registers a mapped image surface s.
//The surface s was mapped from is required.
//
//It is okay if from has been previously registered.
//
//This is only necessary if you are using another library that creates its own
//libcairo surface that will interact with this package.
func XtensionRegisterAlienMappedSurface(s, from *C.cairo_surface_t) (S, From Surface, err error) {
	From, err = XtensionRegisterAlienSurface(from)
	if err != nil {
		return
	}
	S, err = XtensionRegisterAlienSurface(s)
	if err != nil {
		return
	}
	S = toMapped(S.(ImageSurface))
	registerImageSurface(S, from)
	return
}

func deviceSetID(d *C.cairo_device_t) {
	if C.cairo_device_get_user_data(d, idkey) != nil {
		return
	}
	C.cairo_device_set_user_data(d, idkey, generateID(), free)
}

func deviceGetID(d *C.cairo_device_t) id {
	p := C.cairo_device_get_user_data(d, idkey)
	if p == nil {
		panic("device does not have ID - created outside of cairo binding and not registered")
	}
	return id(ctoint(p))
}

func fontSetSubtypeID(f *C.cairo_font_face_t, s subtypeID) {
	if fontType(C.cairo_font_face_get_type(f)) != FontTypeUser {
		panic("font is not a user font")
	}
	if C.cairo_font_face_get_user_data(f, stkey) != nil {
		panic("font already has subtype set")
	}
	C.cairo_font_face_set_user_data(f, stkey, s.c(), free)
}

func fontGetSubtypeID(f *C.cairo_font_face_t) subtypeID {
	if fontType(C.cairo_font_face_get_type(f)) != FontTypeUser {
		panic("font is not a user font")
	}
	p := C.cairo_font_face_get_user_data(f, stkey)
	if p == nil {
		panic("no subtype set: font not registered")
	}
	return subtypeID(ctoint(p))
}

//XtensionRegisterAlienDevice registers a device created outside of this
//package and creates a Device of the proper type.
//
//This is only necessary if you are using another library that creates its own
//libcairo device that will interact with this package.
func XtensionRegisterAlienDevice(d *C.cairo_device_t) (Device, error) {
	deviceSetID(d)
	return newCairoDevice(d)
}

type fontsubfac struct {
	name string
	fac  func(*C.cairo_font_face_t) (Font, error)
}

var (
	fontsubtypenames = map[string]subtypeID{}
	fontsubtypes     = map[subtypeID]*fontsubfac{}
)

//XtensionRegisterUserAlienFontSubtype registers a factory to create a Go wrapper
//around an existing libcairo user font and associates it with a unique name,
//retrievable via Subtype.
//
//After the subtype is registered, instances MUST be registered with
//XtensionRegisterAlienUserFont.
func XtensionRegisterAlienUserFontSubtype(name string, fac func(*C.cairo_font_face_t) (Font, error)) {
	if name == "" {
		panic("user font subtype name must not be empty string")
	}
	if fac == nil {
		panic("user font factory must not be nil")
	}
	idmux.Lock()
	defer idmux.Unlock()

	if _, ok := fontsubtypenames[name]; ok {
		panic("subtype " + name + " previously registered")
	}

	id := subtypeID(nextID)
	fontsubtypenames[name] = id
	fontsubtypes[id] = &fontsubfac{
		name: name,
		fac:  fac,
	}
	nextID++
}

//XtensionRegisterAlienUserFont registers a libcairo user font with cairo.
//
//The subtype must be registered XtensionRegisterAlienUserFontSubtype.
func XtensionRegisterAlienUserFont(subtype string, f *C.cairo_font_face_t) (Font, error) {
	id := fontsubtypenames[subtype]
	fontSetSubtypeID(f, id)
	return fontsubtypes[id].fac(f)
}
<commit_msg>fixed transposition in documentation<commit_after>package cairo

//#cgo pkg-config: cairo
//#include <stdlib.h>
//#include <stdint.h>
//#include <cairo/cairo.h>
//
//static void* cgo_id_malloc(uint64_t id) {
//	uint64_t* p = (uint64_t*) malloc(sizeof(uint64_t));
//	*p = id;
//	return p;
//}
//
//static void gocairo_free(void* data) {
//	free(data);
//}
//
//static cairo_destroy_func_t gocairo_free_get() {
//	return &gocairo_free;
//}
import "C"

import (
	"sync"
	"unsafe"
)

var free = C.gocairo_free_get()

type (
	id        uint64
	subtypeID uint64
)

func (s subtypeID) c() unsafe.Pointer {
	return C.cgo_id_malloc(C.uint64_t(s))
}

var (
	nextID uint64
	idmux  = &sync.Mutex{}
	idkey  = &C.cairo_user_data_key_t{}
	stkey  = &C.cairo_user_data_key_t{}

	subtypes = map[string]subtypeID{}
)

func generateID() unsafe.Pointer {
	idmux.Lock()
	defer idmux.Unlock()

	p := C.cgo_id_malloc(C.uint64_t(nextID))
	nextID++
	return unsafe.Pointer(p)
}

func ctoint(p unsafe.Pointer) uint64 {
	return uint64(*(*C.uint64_t)(p))
}

func surfaceSetID(s *C.cairo_surface_t) {
	if C.cairo_surface_get_user_data(s, idkey) != nil {
		return
	}
	C.cairo_surface_set_user_data(s, idkey, generateID(), free)
}

func surfaceGetID(s *C.cairo_surface_t) id {
	p := C.cairo_surface_get_user_data(s, idkey)
	if p == nil {
		panic("surface does not have ID - created outside of cairo binding and not registered")
	}
	return id(ctoint(p))
}

//XtensionRegisterAlienSurface registers a surface created outside of this
//package and creates a Surface of the proper type.
//
//This is only necessary if you are using another library that creates its own
//libcairo surface that will interact with this package.
//
//If s is a mapped image surface you must use XtensionRegisterAlienMappedSurface.
func XtensionRegisterAlienSurface(s *C.cairo_surface_t) (Surface, error) {
	surfaceSetID(s)
	return XtensionRevivifySurface(s)
}

//XtensionRegisterAlienMappedSurface registers a mapped image surface s.
//The surface s was mapped from is required.
//
//It is okay if from has been previously registered.
//
//This is only necessary if you are using another library that creates its own
//libcairo surface that will interact with this package.
func XtensionRegisterAlienMappedSurface(s, from *C.cairo_surface_t) (S, From Surface, err error) {
	From, err = XtensionRegisterAlienSurface(from)
	if err != nil {
		return
	}
	S, err = XtensionRegisterAlienSurface(s)
	if err != nil {
		return
	}
	S = toMapped(S.(ImageSurface))
	registerImageSurface(S, from)
	return
}

func deviceSetID(d *C.cairo_device_t) {
	if C.cairo_device_get_user_data(d, idkey) != nil {
		return
	}
	C.cairo_device_set_user_data(d, idkey, generateID(), free)
}

func deviceGetID(d *C.cairo_device_t) id {
	p := C.cairo_device_get_user_data(d, idkey)
	if p == nil {
		panic("device does not have ID - created outside of cairo binding and not registered")
	}
	return id(ctoint(p))
}

func fontSetSubtypeID(f *C.cairo_font_face_t, s subtypeID) {
	if fontType(C.cairo_font_face_get_type(f)) != FontTypeUser {
		panic("font is not a user font")
	}
	if C.cairo_font_face_get_user_data(f, stkey) != nil {
		panic("font already has subtype set")
	}
	C.cairo_font_face_set_user_data(f, stkey, s.c(), free)
}

func fontGetSubtypeID(f *C.cairo_font_face_t) subtypeID {
	if fontType(C.cairo_font_face_get_type(f)) != FontTypeUser {
		panic("font is not a user font")
	}
	p := C.cairo_font_face_get_user_data(f, stkey)
	if p == nil {
		panic("no subtype set: font not registered")
	}
	return subtypeID(ctoint(p))
}

//XtensionRegisterAlienDevice registers a device created outside of this
//package and creates a Device of the proper type.
//
//This is only necessary if you are using another library that creates its own
//libcairo device that will interact with this package.
func XtensionRegisterAlienDevice(d *C.cairo_device_t) (Device, error) {
	deviceSetID(d)
	return newCairoDevice(d)
}

type fontsubfac struct {
	name string
	fac  func(*C.cairo_font_face_t) (Font, error)
}

var (
	fontsubtypenames = map[string]subtypeID{}
	fontsubtypes     = map[subtypeID]*fontsubfac{}
)

//XtensionRegisterAlienUserFontSubtype registers a factory to create a Go wrapper
//around an existing libcairo user font and associates it with a unique name,
//retrievable via Subtype.
//
//After the subtype is registered, instances MUST be registered with
//XtensionRegisterAlienUserFont.
func XtensionRegisterAlienUserFontSubtype(name string, fac func(*C.cairo_font_face_t) (Font, error)) {
	if name == "" {
		panic("user font subtype name must not be empty string")
	}
	if fac == nil {
		panic("user font factory must not be nil")
	}
	idmux.Lock()
	defer idmux.Unlock()

	if _, ok := fontsubtypenames[name]; ok {
		panic("subtype " + name + " previously registered")
	}

	id := subtypeID(nextID)
	fontsubtypenames[name] = id
	fontsubtypes[id] = &fontsubfac{
		name: name,
		fac:  fac,
	}
	nextID++
}

//XtensionRegisterAlienUserFont registers a libcairo user font with cairo.
//
//The subtype must be registered XtensionRegisterAlienUserFontSubtype.
func XtensionRegisterAlienUserFont(subtype string, f *C.cairo_font_face_t) (Font, error) {
	id := fontsubtypenames[subtype]
	fontSetSubtypeID(f, id)
	return fontsubtypes[id].fac(f)
}
<|endoftext|>


<commit_before>package gotetra

import (
	"encoding/binary"
	"math"
	"os"
)

type GadgetHeader struct {
	NPart [6]uint32
	Mass [6]float64
	Time, Redshift float64
	FlagSfr, FlagFeedback int32
	NPartTotal [6]uint32
	FlagCooling, NumFiles int32
	BoxSize, Omega0, OmegaLambda, HubbleParam float64
	FlagStellarAge, HashTabSize int32

	Padding [88]byte
}

// ReadInt32 returns single 32-bit interger from the given file generated on
// a machine with the given endianness.
func ReadInt32(f *os.File, order binary.ByteOrder) int32 {
	var n int32
	if err := binary.Read(f, order, &n); err != nil { panic(err) }
	return n
}

// Standardize returns a standardized header the corresponds to the source
// Gadget header.
func (gh *GadgetHeader) Standardize() *Header {
	h := &Header{}

	h.Count = int64(gh.NPart[1] + gh.NPart[0] << 32)
	h.TotalCount = int64(gh.NPartTotal[1] + gh.NPartTotal[0] << 32)
	h.Mass = float64(gh.Mass[1])
	h.BoxSize = float64(gh.BoxSize)

	h.Cosmo.Z = gh.Redshift
	h.Cosmo.OmegaM = gh.Omega0
	h.Cosmo.OmegaL = gh.OmegaLambda
	h.Cosmo.H100 = gh.HubbleParam

	return h
}

// WrapDistance returns a value of x which is inside the box described by h.
func (h *GadgetHeader) WrapDistance(x float64) float64 {
	if x < 0 {
		return x + h.BoxSize
	} else if x >= h.BoxSize {
		return x - h.BoxSize
	}
	return x
}

// ReadGadget reads the gadget particle catalog located at the given location
// generated on a machine with the given endianness and returns the particles
// along with the standardized header file contained within.
func ReadGadget(fileName string, order binary.ByteOrder) (*Header, []Particle) {
	f, err := os.Open(fileName)
	if err != nil { panic(err) }

	gh := &GadgetHeader{}

	_ = ReadInt32(f, order)
	binary.Read(f, binary.LittleEndian, gh)
	_ = ReadInt32(f, order)

	h := gh.Standardize()
	floatBuf := make([]float32, 3 * h.Count)
	ps := make([]Particle, h.Count)

	_ = ReadInt32(f, order)
	binary.Read(f, order, floatBuf)
	_ = ReadInt32(f, order)

	for i := range ps {
		ps[i].Xs[0] = gh.WrapDistance(float64(floatBuf[3 * i + 0]))
		ps[i].Xs[1] = gh.WrapDistance(float64(floatBuf[3 * i + 1]))
		ps[i].Xs[2] = gh.WrapDistance(float64(floatBuf[3 * i + 2]))
	}

	_ = ReadInt32(f, order)
	binary.Read(f, order, floatBuf)
	_ = ReadInt32(f, order)

	rootA := float32(math.Sqrt(float64(gh.Time)))
	for i := range ps {
		ps[i].Vs[0] = float64(floatBuf[3 * i + 0] * rootA)
		ps[i].Vs[1] = float64(floatBuf[3 * i + 1] * rootA)
		ps[i].Vs[2] = float64(floatBuf[3 * i + 2] * rootA)
	}

	ids := make([]int64, h.Count)

	_ = ReadInt32(f, order)
	binary.Read(f, order, ids)
	_ = ReadInt32(f, order)

	for i := range ps { ps[i].Id = ids[i] }

	return ps, h
}
<commit_msg>Fixed compile error in io.g<commit_after>package gotetra

import (
	"encoding/binary"
	"math"
	"os"
)

type GadgetHeader struct {
	NPart [6]uint32
	Mass [6]float64
	Time, Redshift float64
	FlagSfr, FlagFeedback int32
	NPartTotal [6]uint32
	FlagCooling, NumFiles int32
	BoxSize, Omega0, OmegaLambda, HubbleParam float64
	FlagStellarAge, HashTabSize int32

	Padding [88]byte
}

// ReadInt32 returns single 32-bit interger from the given file generated on
// a machine with the given endianness.
func ReadInt32(f *os.File, order binary.ByteOrder) int32 {
	var n int32
	if err := binary.Read(f, order, &n); err != nil { panic(err) }
	return n
}

// Standardize returns a standardized header the corresponds to the source
// Gadget header.
func (gh *GadgetHeader) Standardize() *Header {
	h := &Header{}

	h.Count = int64(gh.NPart[1] + gh.NPart[0] << 32)
	h.TotalCount = int64(gh.NPartTotal[1] + gh.NPartTotal[0] << 32)
	h.Mass = float64(gh.Mass[1])
	h.BoxSize = float64(gh.BoxSize)

	h.Cosmo.Z = gh.Redshift
	h.Cosmo.OmegaM = gh.Omega0
	h.Cosmo.OmegaL = gh.OmegaLambda
	h.Cosmo.H100 = gh.HubbleParam

	return h
}

// WrapDistance returns a value of x which is inside the box described by h.
func (h *GadgetHeader) WrapDistance(x float64) float64 {
	if x < 0 {
		return x + h.BoxSize
	} else if x >= h.BoxSize {
		return x - h.BoxSize
	}
	return x
}

// ReadGadget reads the gadget particle catalog located at the given location
// generated on a machine with the given endianness and returns the particles
// along with the standardized header file contained within.
func ReadGadget(fileName string, order binary.ByteOrder) (*Header, []Particle) {
	f, err := os.Open(fileName)
	if err != nil { panic(err) }

	gh := &GadgetHeader{}

	_ = ReadInt32(f, order)
	binary.Read(f, binary.LittleEndian, gh)
	_ = ReadInt32(f, order)

	h := gh.Standardize()
	floatBuf := make([]float32, 3 * h.Count)
	ps := make([]Particle, h.Count)

	_ = ReadInt32(f, order)
	binary.Read(f, order, floatBuf)
	_ = ReadInt32(f, order)

	for i := range ps {
		ps[i].Xs[0] = gh.WrapDistance(float64(floatBuf[3 * i + 0]))
		ps[i].Xs[1] = gh.WrapDistance(float64(floatBuf[3 * i + 1]))
		ps[i].Xs[2] = gh.WrapDistance(float64(floatBuf[3 * i + 2]))
	}

	_ = ReadInt32(f, order)
	binary.Read(f, order, floatBuf)
	_ = ReadInt32(f, order)

	rootA := float32(math.Sqrt(float64(gh.Time)))
	for i := range ps {
		ps[i].Vs[0] = float64(floatBuf[3 * i + 0] * rootA)
		ps[i].Vs[1] = float64(floatBuf[3 * i + 1] * rootA)
		ps[i].Vs[2] = float64(floatBuf[3 * i + 2] * rootA)
	}

	ids := make([]int64, h.Count)

	_ = ReadInt32(f, order)
	binary.Read(f, order, ids)
	_ = ReadInt32(f, order)

	for i := range ps { ps[i].Id = ids[i] }

	return h, ps
}
<|endoftext|>


<commit_before><commit_msg>make pauze work<commit_after><|endoftext|>


<commit_before>//go:build js

// Copyright 2017 Google LLC
//
// 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 chrome exposes Go versions of Chrome's extension APIs.
package chrome

import (
	"errors"
	"syscall/js"
)

var (
	// chrome is a reference to the 'chrome' object.
	chrome = js.Global().Get("chrome")
	// runtime is a reference to the'chrome.runtime' object.
	runtime = func() js.Value {
		if chrome.IsUndefined() {
			return js.Undefined() // Not running under chrome.
		}
		return chrome.Get("runtime")
	}()
	// extensionID is the unique ID allocated to our extension.
	extensionID = func() string {
		if runtime.IsUndefined() {
			return "" // Not running under chrome.
		}
		return runtime.Get("id").String()
	}()
)

// Runtime returns a reference to 'chrome.runtime'.
func Runtime() js.Value {
	return runtime
}

// ExtensionID returns the unique ID allocated to this extension.
func ExtensionID() string {
	return extensionID
}

// LastError returns the error (if any) from the last call. Returns nil if there
// was no error.
//
// See https://developer.chrome.com/apps/runtime#property-lastError.
func LastError() error {
	if err := runtime.Get("lastError"); !err.IsNull() && !err.IsUndefined() {
		return errors.New(err.Get("message").String())
	}
	return nil
}
<commit_msg>Remove unused APIs<commit_after>//go:build js

// Copyright 2017 Google LLC
//
// 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 chrome exposes Go versions of Chrome's extension APIs.
package chrome

import (
	"syscall/js"
)

var (
	// chrome is a reference to the 'chrome' object.
	chrome = js.Global().Get("chrome")
	// runtime is a reference to the'chrome.runtime' object.
	runtime = func() js.Value {
		if chrome.IsUndefined() {
			return js.Undefined() // Not running under chrome.
		}
		return chrome.Get("runtime")
	}()
	// extensionID is the unique ID allocated to our extension.
	extensionID = func() string {
		if runtime.IsUndefined() {
			return "" // Not running under chrome.
		}
		return runtime.Get("id").String()
	}()
)

// ExtensionID returns the unique ID allocated to this extension.
func ExtensionID() string {
	return extensionID
}
<|endoftext|>


<commit_before>package client

import (
	"bytes"
	"fmt"
	"net/http"
	"strings"
	"sync"

	"github.com/gorilla/websocket"
)

// internal client
type client struct {
	options Options

	sync.RWMutex
	subscribers map[<-chan []byte]*subscriber
}

// internal subscriber
type subscriber struct {
	wg    sync.WaitGroup
	ch    chan<- []byte
	exit  chan bool
	topic string
}

// Client is the interface provided by this package
type Client interface {
	Publish(topic string, payload []byte) error
	Subscribe(topic string) (<-chan []byte, error)
	Unsubscribe(<-chan []byte) error
}

// Selector provides a server list to publish/subscribe to
type Selector interface {
	Get(topic string) ([]string, error)
	Set(servers ...string) error
}

var (
	// The default client
	Default = newClient()
	// The default server list
	Servers = []string{"http://127.0.0.1:8081"}
	// The default number of retries
	Retries = 1
)

func newClient(opts ...Option) *client {
	options := Options{
		Selector: new(SelectAll),
		Servers:  Servers,
		Retries:  Retries,
	}

	for _, o := range opts {
		o(&options)
	}

	var servers []string

	for _, addr := range options.Servers {
		if !strings.HasPrefix(addr, "http") {
			addr = fmt.Sprintf("http://%s", addr)
		}
		servers = append(servers, addr)
	}

	// set servers
	WithServers(servers...)(&options)
	options.Selector.Set(options.Servers...)

	return &client{
		options:     options,
		subscribers: make(map[<-chan []byte]*subscriber),
	}
}

func publish(addr, topic string, payload []byte) error {
	url := fmt.Sprintf("%s/pub?topic=%s", addr, topic)
	rsp, err := http.Post(url, "application/json", bytes.NewBuffer(payload))
	if err != nil {
		return err
	}
	rsp.Body.Close()
	if rsp.StatusCode != 200 {
		return fmt.Errorf("Non 200 response %d", rsp.StatusCode)
	}
	return nil
}

func subscribe(addr string, s *subscriber) error {
	if strings.HasPrefix(addr, "http") {
		addr = strings.TrimPrefix(addr, "http")
		addr = "ws" + addr
	}

	url := fmt.Sprintf("%s/sub?topic=%s", addr, s.topic)
	c, _, err := websocket.DefaultDialer.Dial(url, make(http.Header))
	if err != nil {
		return err
	}

	go func() {
		defer s.wg.Done()

		for {
			t, p, err := c.ReadMessage()
			if err != nil || t == websocket.CloseMessage {
				c.Close()
				return
			}

			select {
			case <-s.exit:
				c.Close()
				return
			default:
				s.ch <- p
			}
		}
	}()

	return nil
}

func (c *client) Publish(topic string, payload []byte) error {
	servers, err := c.options.Selector.Get(topic)
	if err != nil {
		return err
	}

	var grr error
	for _, addr := range servers {
		for i := 0; i < 1+c.options.Retries; i++ {
			err := publish(addr, topic, payload)
			if err == nil {
				break
			}
			grr = err
		}
	}
	return grr
}

func (c *client) Subscribe(topic string) (<-chan []byte, error) {
	servers, err := c.options.Selector.Get(topic)
	if err != nil {
		return nil, err
	}

	ch := make(chan []byte, len(c.options.Servers)*100)

	s := &subscriber{
		ch:    ch,
		exit:  make(chan bool),
		topic: topic,
	}

	var grr error
	for _, addr := range servers {
		for i := 0; i < 1+c.options.Retries; i++ {
			err := subscribe(addr, s)
			if err == nil {
				s.wg.Add(1)
				break
			}
			grr = err
		}
	}

	return ch, grr
}

func (c *client) Unsubscribe(ch <-chan []byte) error {
	c.Lock()
	defer c.Unlock()
	if sub, ok := c.subscribers[ch]; ok {
		return sub.Close()
	}
	return nil
}

func (s *subscriber) Close() error {
	select {
	case <-s.exit:
	default:
		close(s.exit)
		s.wg.Wait()
	}
	return nil
}

// Publish via the default Client
func Publish(topic string, payload []byte) error {
	return Default.Publish(topic, payload)
}

// Subscribe via the default Client
func Subscribe(topic string) (<-chan []byte, error) {
	return Default.Subscribe(topic)
}

// Unsubscribe via the default Client
func Unsubscribe(ch <-chan []byte) error {
	return Default.Unsubscribe(ch)
}

// New returns a new Client
func New(opts ...Option) Client {
	return newClient(opts...)
}
<commit_msg>don't block the exit chan<commit_after>package client

import (
	"bytes"
	"fmt"
	"net/http"
	"strings"
	"sync"

	"github.com/gorilla/websocket"
)

// internal client
type client struct {
	options Options

	sync.RWMutex
	subscribers map[<-chan []byte]*subscriber
}

// internal subscriber
type subscriber struct {
	wg    sync.WaitGroup
	ch    chan<- []byte
	exit  chan bool
	topic string
}

// Client is the interface provided by this package
type Client interface {
	Publish(topic string, payload []byte) error
	Subscribe(topic string) (<-chan []byte, error)
	Unsubscribe(<-chan []byte) error
}

// Selector provides a server list to publish/subscribe to
type Selector interface {
	Get(topic string) ([]string, error)
	Set(servers ...string) error
}

var (
	// The default client
	Default = newClient()
	// The default server list
	Servers = []string{"http://127.0.0.1:8081"}
	// The default number of retries
	Retries = 1
)

func newClient(opts ...Option) *client {
	options := Options{
		Selector: new(SelectAll),
		Servers:  Servers,
		Retries:  Retries,
	}

	for _, o := range opts {
		o(&options)
	}

	var servers []string

	for _, addr := range options.Servers {
		if !strings.HasPrefix(addr, "http") {
			addr = fmt.Sprintf("http://%s", addr)
		}
		servers = append(servers, addr)
	}

	// set servers
	WithServers(servers...)(&options)
	options.Selector.Set(options.Servers...)

	return &client{
		options:     options,
		subscribers: make(map[<-chan []byte]*subscriber),
	}
}

func publish(addr, topic string, payload []byte) error {
	url := fmt.Sprintf("%s/pub?topic=%s", addr, topic)
	rsp, err := http.Post(url, "application/json", bytes.NewBuffer(payload))
	if err != nil {
		return err
	}
	rsp.Body.Close()
	if rsp.StatusCode != 200 {
		return fmt.Errorf("Non 200 response %d", rsp.StatusCode)
	}
	return nil
}

func subscribe(addr string, s *subscriber) error {
	if strings.HasPrefix(addr, "http") {
		addr = strings.TrimPrefix(addr, "http")
		addr = "ws" + addr
	}

	url := fmt.Sprintf("%s/sub?topic=%s", addr, s.topic)
	c, _, err := websocket.DefaultDialer.Dial(url, make(http.Header))
	if err != nil {
		return err
	}

	go func() {
		defer s.wg.Done()

		for {
			t, p, err := c.ReadMessage()
			if err != nil || t == websocket.CloseMessage {
				c.Close()
				return
			}

			select {
			case <-s.exit:
				c.Close()
				return
			case s.ch <- p:
			}
		}
	}()

	return nil
}

func (c *client) Publish(topic string, payload []byte) error {
	servers, err := c.options.Selector.Get(topic)
	if err != nil {
		return err
	}

	var grr error
	for _, addr := range servers {
		for i := 0; i < 1+c.options.Retries; i++ {
			err := publish(addr, topic, payload)
			if err == nil {
				break
			}
			grr = err
		}
	}
	return grr
}

func (c *client) Subscribe(topic string) (<-chan []byte, error) {
	servers, err := c.options.Selector.Get(topic)
	if err != nil {
		return nil, err
	}

	ch := make(chan []byte, len(c.options.Servers)*256)

	s := &subscriber{
		ch:    ch,
		exit:  make(chan bool),
		topic: topic,
	}

	var grr error
	for _, addr := range servers {
		for i := 0; i < 1+c.options.Retries; i++ {
			err := subscribe(addr, s)
			if err == nil {
				s.wg.Add(1)
				break
			}
			grr = err
		}
	}

	return ch, grr
}

func (c *client) Unsubscribe(ch <-chan []byte) error {
	c.Lock()
	defer c.Unlock()
	if sub, ok := c.subscribers[ch]; ok {
		return sub.Close()
	}
	return nil
}

func (s *subscriber) Close() error {
	select {
	case <-s.exit:
	default:
		close(s.exit)
		s.wg.Wait()
	}
	return nil
}

// Publish via the default Client
func Publish(topic string, payload []byte) error {
	return Default.Publish(topic, payload)
}

// Subscribe via the default Client
func Subscribe(topic string) (<-chan []byte, error) {
	return Default.Subscribe(topic)
}

// Unsubscribe via the default Client
func Unsubscribe(ch <-chan []byte) error {
	return Default.Unsubscribe(ch)
}

// New returns a new Client
func New(opts ...Option) Client {
	return newClient(opts...)
}
<|endoftext|>


<commit_before>package quartz

import (
	"net"
	"net/rpc"
	"net/rpc/jsonrpc"
	"os"
	"os/signal"
	"reflect"
	"strings"
	"syscall"
)

// Quartz holds information about exported structs.
type Quartz struct {
	Registry *Registry
}

func newQuartz() *Quartz {
	return &Quartz{newRegistry()}
}

// RegisterName exports a struct via RPC and generates metadata for
// each of the struct's methods.
func (q *Quartz) RegisterName(name string, s interface{}) error {
	q.Registry.data[name] = newStructMetadata(s)
	t := reflect.TypeOf(s)
	for i := 0; i < t.NumMethod(); i++ {
		method := t.Method(i)
		// TODO: only export methods with JSON serializable arguments
		// and responses.
		metadata := &methodMetadata{
			method,
			structFieldToType(method.Type.In(1)),
		}
		q.Registry.data[name].NameToMethodMetadata[method.Name] = metadata
	}
	return rpc.RegisterName(name, s)
}

// Start launches the server.
func (q *Quartz) Start() {
	// The Ruby gem sets this environment variable for us.
	socketPath := "/tmp/quartz.socket"
	if os.Getenv("QUARTZ_SOCKET") != "" {
		socketPath = os.Getenv("QUARTZ_SOCKET")
	}

	// Start the server and accept connections on a
	// UNIX domain socket.
	rpc.RegisterName("Quartz", q.Registry)
	listener, err := net.Listen("unix", socketPath)
	if err != nil {
		panic(err)
	}

	// Destroy the socket file when the server is killed.
	sigc := make(chan os.Signal)
	signal.Notify(sigc, syscall.SIGTERM)
	go func() {
		<-sigc
		err := listener.Close()
		if err != nil {
			panic(err)
		}
		os.Exit(0)
	}()

	// Accept connections
	for {
		conn, err := listener.Accept()
		if err != nil {
			// The connection was closed by a signal.
			if strings.Contains(err.Error(), "use of closed network connection") {
				return
			}
			panic(err)
		}
		go jsonrpc.ServeConn(conn)
	}
}
<commit_msg>Make Go server more resilient<commit_after>package quartz

import (
	"fmt"
	"net"
	"net/rpc"
	"net/rpc/jsonrpc"
	"os"
	"os/signal"
	"reflect"
	"strings"
	"syscall"
)

// Quartz holds information about exported structs.
type Quartz struct {
	Registry *Registry
}

func newQuartz() *Quartz {
	return &Quartz{newRegistry()}
}

// RegisterName exports a struct via RPC and generates metadata for
// each of the struct's methods.
func (q *Quartz) RegisterName(name string, s interface{}) error {
	q.Registry.data[name] = newStructMetadata(s)
	t := reflect.TypeOf(s)
	for i := 0; i < t.NumMethod(); i++ {
		method := t.Method(i)
		// TODO: only export methods with JSON serializable arguments
		// and responses.
		metadata := &methodMetadata{
			method,
			structFieldToType(method.Type.In(1)),
		}
		q.Registry.data[name].NameToMethodMetadata[method.Name] = metadata
	}
	return rpc.RegisterName(name, s)
}

// Start launches the server.
func (q *Quartz) Start() {
	// The Ruby gem sets this environment variable for us.
	socketPath := "/tmp/quartz.socket"
	if os.Getenv("QUARTZ_SOCKET") != "" {
		socketPath = os.Getenv("QUARTZ_SOCKET")
	}

	// Start the server and accept connections on a
	// UNIX domain socket.
	rpc.RegisterName("Quartz", q.Registry)
	listener, err := net.Listen("unix", socketPath)
	if err != nil {
		panic(err)
	}

	// Destroy the socket file when the server is killed.
	sigc := make(chan os.Signal)
	signal.Notify(sigc, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGINT)
	go func() {
		<-sigc
		listener.Close()
		os.Remove(socketPath)
		os.Exit(0)
	}()

	// Accept connections
	for {
		conn, err := listener.Accept()
		if err != nil {
			// The connection was closed by a signal.
			if strings.Contains(err.Error(), "use of closed network connection") {
				return
			}

			fmt.Fprintf(os.Stderr, "error accepting connection: %s", err)
			continue
		}

		go func() {
			defer func() {
				if r := recover(); r != nil {
					fmt.Fprintf(os.Stderr, "Recovered from panic: %s", r)
				}
			}()

			jsonrpc.ServeConn(conn)
		}()
	}
}
<|endoftext|>


<commit_before>// Copyright 2019 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package status

import (
	"errors"
	"os"
	"path/filepath"
	"strings"

	"github.com/keybase/client/go/install"
	"github.com/keybase/client/go/libkb"
	keybase1 "github.com/keybase/client/go/protocol/keybase1"
	"github.com/keybase/go-framed-msgpack-rpc/rpc"
)

func GetCurrentStatus(mctx libkb.MetaContext) (res keybase1.CurrentStatus, err error) {
	cr := mctx.G().Env.GetConfig()
	if cr == nil {
		return res, nil
	}
	res.Configured = true
	if uid := cr.GetUID(); uid.Exists() {
		res.Registered = true
		res.User = libkb.NewUserThin(cr.GetUsername().String(), uid).Export()
	}
	res.SessionIsValid = mctx.ActiveDevice().Valid()
	res.LoggedIn = res.SessionIsValid
	res.DeviceName = mctx.ActiveDevice().Name()
	return res, nil
}

func GetExtendedStatus(mctx libkb.MetaContext) (res keybase1.ExtendedStatus, err error) {
	mctx = mctx.WithLogTag("EXTSTATUS")
	defer mctx.TraceTimed("GetExtendedStatus", func() error { return err })()
	g := mctx.G()

	res.Standalone = g.Env.GetStandalone()
	res.LogDir = g.Env.GetLogDir()
	res.Clients = libkb.GetClientStatus(mctx)

	if err = g.GetFullSelfer().WithSelf(mctx.Ctx(), func(me *libkb.User) error {
		ckf := me.GetComputedKeyFamily()
		if ckf == nil {
			return errors.New("Couldn't load key family")
		}
		device, err := ckf.GetCurrentDevice(g)
		if err != nil {
			mctx.Debug("| GetCurrentDevice failed: %s", err)
			res.DeviceErr = &keybase1.LoadDeviceErr{Where: "ckf.GetCurrentDevice", Desc: err.Error()}
		} else {
			res.Device = device.ProtExport()
		}

		ss := g.SecretStore()
		if me != nil && ss != nil {
			s, err := ss.RetrieveSecret(mctx, me.GetNormalizedName())
			if err == nil && !s.IsNil() {
				res.StoredSecret = true
			}
		}
		return nil
	}); err != nil {
		mctx.Debug("| could not load me user: %s", err)
		res.DeviceErr = &keybase1.LoadDeviceErr{Where: "libkb.LoadMe", Desc: err.Error()}
	}

	// cached device key status
	_, _, _, sk, ek := g.ActiveDevice.AllFields()
	res.DeviceSigKeyCached = sk != nil
	res.DeviceEncKeyCached = ek != nil

	ad := mctx.ActiveDevice()
	// cached paper key status
	if pk := ad.ProvisioningKey(mctx); pk != nil {
		if pk.EncryptionKey() != nil {
			res.PaperEncKeyCached = true
		}
		if pk.SigningKey() != nil {
			res.PaperSigKeyCached = true
		}
	}

	psc := ad.PassphraseStreamCache()
	res.PassphraseStreamCached = psc.ValidPassphraseStream()
	res.TsecCached = psc.ValidTsec()
	res.SecretPromptSkip = mctx.ActiveDevice().SecretPromptCancelTimer().WasRecentlyCanceled(mctx)

	current, all, err := libkb.GetAllProvisionedUsernames(mctx)
	if err != nil {
		mctx.Debug("| died in GetAllProvisionedUsernames()")
		return res, err
	}
	res.DefaultUsername = current.String()
	p := make([]string, len(all))
	for i, u := range all {
		p[i] = u.String()
	}
	res.ProvisionedUsernames = p

	accounts, err := libkb.GetConfiguredAccountsFromProvisionedUsernames(mctx, mctx.G().SecretStore(), current, all)
	if err != nil {
		mctx.Debug("| died in GetConfiguredAccounts()")
		return res, err
	}
	res.ConfiguredAccounts = accounts

	res.PlatformInfo = getPlatformInfo()
	res.DefaultDeviceID = g.Env.GetDeviceID()
	res.RememberPassphrase = g.Env.GetRememberPassphrase(g.Env.GetUsername())
	// DeviceEK status, can be nil if user is logged out
	deviceEKStorage := g.GetDeviceEKStorage()
	if deviceEKStorage != nil {
		dekNames, err := deviceEKStorage.ListAllForUser(mctx)
		if err != nil {
			return res, err
		}
		res.DeviceEkNames = dekNames
	}

	res.LocalDbStats = strings.Split(g.LocalDb.Stats(), "\n")
	res.LocalChatDbStats = strings.Split(g.LocalChatDb.Stats(), "\n")
	if cacheSizeInfo, err := CacheSizeInfo(g); err == nil {
		res.CacheDirSizeInfo = cacheSizeInfo
	}

	if g.ConnectionManager != nil {
		xp := g.ConnectionManager.LookupByClientType(keybase1.ClientType_KBFS)
		if xp == nil {
			mctx.Debug("| KBFS stats not available")
		} else {
			cli := &keybase1.SimpleFSClient{
				Cli: rpc.NewClient(
					xp, libkb.NewContextifiedErrorUnwrapper(g), nil),
			}
			stats, err := cli.SimpleFSGetStats(mctx.Ctx())
			if err != nil {
				mctx.Debug("| KBFS stats error: %+v", err)
			} else {
				res.LocalBlockCacheDbStats = stats.BlockCacheDbStats
				res.LocalSyncCacheDbStats = stats.SyncCacheDbStats
			}
		}
	}

	if g.UIRouter != nil {
		uiMapping := map[string]int{}
		for k, v := range g.UIRouter.DumpUIs() {
			uiMapping[k.String()] = int(v)
		}
		res.UiRouterMapping = uiMapping
	}

	return res, nil
}

func GetConfig(mctx libkb.MetaContext, forkType keybase1.ForkType) (c keybase1.Config, err error) {
	serverURI, err := mctx.G().Env.GetServerURI()
	if err != nil {
		return c, err
	}

	c.ServerURI = serverURI
	c.RunMode = string(mctx.G().Env.GetRunMode())
	c.SocketFile, err = mctx.G().Env.GetSocketBindFile()
	if err != nil {
		return c, err
	}

	gpg := mctx.G().GetGpgClient()
	canExec, err := gpg.CanExec(mctx)
	if err == nil {
		c.GpgExists = canExec
		c.GpgPath = gpg.Path(mctx)
	}

	c.Version = libkb.VersionString()
	c.VersionShort = libkb.Version

	var v []string
	libkb.VersionMessage(func(s string) {
		v = append(v, s)
	})
	c.VersionFull = strings.Join(v, "\n")

	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err == nil {
		c.Path = dir
	} else {
		mctx.Warning("Failed to get service path: %s", err)
	}

	realpath, err := libkb.CurrentBinaryRealpath()
	if err == nil {
		c.BinaryRealpath = realpath
	} else {
		mctx.Debug("Failed to get service realpath: %s", err)
	}

	c.ConfigPath = mctx.G().Env.GetConfigFilename()
	c.Label = mctx.G().Env.GetLabel()
	if forkType == keybase1.ForkType_AUTO {
		c.IsAutoForked = true
	}
	c.ForkType = forkType
	return c, nil
}

func GetFullStatus(mctx libkb.MetaContext) (status *keybase1.FullStatus, err error) {
	status = &keybase1.FullStatus{}
	// The client overrides this value when sending logs
	status.Client.Version = libkb.VersionString()
	status.ConfigPath = mctx.G().Env.GetConfigFilename()

	status.CurStatus, err = GetCurrentStatus(mctx)
	if err != nil {
		return nil, err
	}

	// Duplicate the username at top-level for backwards compatibility of
	// output.
	if status.CurStatus.User != nil {
		status.Username = status.CurStatus.User.Username
	}

	status.ExtStatus, err = GetExtendedStatus(mctx)
	if err != nil {
		return nil, err
	}

	// set service status
	if status.ExtStatus.Standalone {
		status.Service.Running = false
	} else {
		status.Service.Running = true
	}
	status.Service.Version = libkb.VersionString()

	// set kbfs status
	kbfsInstalledVersion, err := install.KBFSBundleVersion(mctx.G(), "")
	if err != nil {
		mctx.Debug("Failed to get KBFSBundleVersion: %s", err)
	} else {
		status.Kbfs.InstalledVersion = kbfsInstalledVersion
	}
	if kbfs := GetFirstClient(status.ExtStatus.Clients, keybase1.ClientType_KBFS); kbfs != nil {
		status.Kbfs.Version = kbfs.Version
		status.Kbfs.Running = true
		// This just gets the mountpoint from the environment; the
		// user could have technically passed a different mountpoint
		// to KBFS on macOS or Linux.  TODO(KBFS-2723): fetch the
		// actual mountpoint with a new RPC from KBFS.
		mountDir, err := mctx.G().Env.GetMountDir()
		if err != nil {
			return nil, err
		}
		status.Kbfs.Mount = mountDir
	} else {
		status.Kbfs.Version = kbfsInstalledVersion
	}

	// set desktop status
	if desktop := GetFirstClient(status.ExtStatus.Clients, keybase1.ClientType_GUI_MAIN); desktop != nil {
		status.Desktop.Running = true
		status.Desktop.Version = desktop.Version
	}

	// set log paths
	status.Service.Log = getServiceLog(mctx, status.ExtStatus.LogDir)
	status.Service.EkLog = filepath.Join(status.ExtStatus.LogDir, libkb.EKLogFileName)
	status.Service.PerfLog = filepath.Join(status.ExtStatus.LogDir, libkb.PerfLogFileName)
	status.Kbfs.Log = filepath.Join(status.ExtStatus.LogDir, libkb.KBFSLogFileName)
	status.Desktop.Log = filepath.Join(status.ExtStatus.LogDir, libkb.GUILogFileName)
	status.Updater.Log = filepath.Join(status.ExtStatus.LogDir, libkb.UpdaterLogFileName)
	status.Start.Log = filepath.Join(status.ExtStatus.LogDir, libkb.StartLogFileName)
	status.Git.Log = filepath.Join(status.ExtStatus.LogDir, libkb.GitLogFileName)

	// set anything os-specific
	if err := osSpecific(mctx, status); err != nil {
		return nil, err
	}
	return status, nil
}
<commit_msg>more debug (#22722)<commit_after>// Copyright 2019 Keybase, Inc. All rights reserved. Use of
// this source code is governed by the included BSD license.

package status

import (
	"errors"
	"os"
	"path/filepath"
	"strings"

	"github.com/keybase/client/go/install"
	"github.com/keybase/client/go/libkb"
	keybase1 "github.com/keybase/client/go/protocol/keybase1"
	"github.com/keybase/go-framed-msgpack-rpc/rpc"
)

func GetCurrentStatus(mctx libkb.MetaContext) (res keybase1.CurrentStatus, err error) {
	cr := mctx.G().Env.GetConfig()
	if cr == nil {
		return res, nil
	}
	res.Configured = true
	if uid := cr.GetUID(); uid.Exists() {
		res.Registered = true
		res.User = libkb.NewUserThin(cr.GetUsername().String(), uid).Export()
	}
	res.SessionIsValid = mctx.ActiveDevice().Valid()
	res.LoggedIn = res.SessionIsValid
	res.DeviceName = mctx.ActiveDevice().Name()
	return res, nil
}

func GetExtendedStatus(mctx libkb.MetaContext) (res keybase1.ExtendedStatus, err error) {
	mctx = mctx.WithLogTag("EXTSTATUS")
	defer mctx.TraceTimed("GetExtendedStatus", func() error { return err })()
	g := mctx.G()

	res.Standalone = g.Env.GetStandalone()
	res.LogDir = g.Env.GetLogDir()
	res.Clients = libkb.GetClientStatus(mctx)

	if err = g.GetFullSelfer().WithSelf(mctx.Ctx(), func(me *libkb.User) error {
		ckf := me.GetComputedKeyFamily()
		if ckf == nil {
			return errors.New("Couldn't load key family")
		}
		device, err := ckf.GetCurrentDevice(g)
		if err != nil {
			mctx.Debug("| GetCurrentDevice failed: %s", err)
			res.DeviceErr = &keybase1.LoadDeviceErr{Where: "ckf.GetCurrentDevice", Desc: err.Error()}
		} else {
			res.Device = device.ProtExport()
		}

		ss := g.SecretStore()
		if me != nil && ss != nil {
			s, err := ss.RetrieveSecret(mctx, me.GetNormalizedName())
			if err == nil && !s.IsNil() {
				res.StoredSecret = true
			}
		}
		return nil
	}); err != nil {
		mctx.Debug("| could not load me user: %s", err)
		res.DeviceErr = &keybase1.LoadDeviceErr{Where: "libkb.LoadMe", Desc: err.Error()}
	}

	// cached device key status
	_, _, _, sk, ek := g.ActiveDevice.AllFields()
	res.DeviceSigKeyCached = sk != nil
	res.DeviceEncKeyCached = ek != nil

	ad := mctx.ActiveDevice()
	// cached paper key status
	if pk := ad.ProvisioningKey(mctx); pk != nil {
		if pk.EncryptionKey() != nil {
			res.PaperEncKeyCached = true
		}
		if pk.SigningKey() != nil {
			res.PaperSigKeyCached = true
		}
	}

	psc := ad.PassphraseStreamCache()
	res.PassphraseStreamCached = psc.ValidPassphraseStream()
	res.TsecCached = psc.ValidTsec()
	res.SecretPromptSkip = mctx.ActiveDevice().SecretPromptCancelTimer().WasRecentlyCanceled(mctx)

	current, all, err := libkb.GetAllProvisionedUsernames(mctx)
	if err != nil {
		mctx.Debug("| died in GetAllProvisionedUsernames()")
		return res, err
	}
	res.DefaultUsername = current.String()
	p := make([]string, len(all))
	for i, u := range all {
		p[i] = u.String()
	}
	res.ProvisionedUsernames = p

	accounts, err := libkb.GetConfiguredAccountsFromProvisionedUsernames(mctx, mctx.G().SecretStore(), current, all)
	if err != nil {
		mctx.Debug("| died in GetConfiguredAccounts()")
		return res, err
	}
	res.ConfiguredAccounts = accounts

	res.PlatformInfo = getPlatformInfo()
	res.DefaultDeviceID = g.Env.GetDeviceID()
	res.RememberPassphrase = g.Env.GetRememberPassphrase(g.Env.GetUsername())
	// DeviceEK status, can be nil if user is logged out
	deviceEKStorage := g.GetDeviceEKStorage()
	if deviceEKStorage != nil {
		dekNames, err := deviceEKStorage.ListAllForUser(mctx)
		if err != nil {
			return res, err
		}
		res.DeviceEkNames = dekNames
	}

	res.LocalDbStats = strings.Split(g.LocalDb.Stats(), "\n")
	res.LocalChatDbStats = strings.Split(g.LocalChatDb.Stats(), "\n")
	if cacheSizeInfo, err := CacheSizeInfo(g); err == nil {
		res.CacheDirSizeInfo = cacheSizeInfo
	}

	if g.ConnectionManager != nil {
		xp := g.ConnectionManager.LookupByClientType(keybase1.ClientType_KBFS)
		if xp == nil {
			mctx.Debug("| KBFS stats not available")
		} else {
			cli := &keybase1.SimpleFSClient{
				Cli: rpc.NewClient(
					xp, libkb.NewContextifiedErrorUnwrapper(g), nil),
			}
			stats, err := cli.SimpleFSGetStats(mctx.Ctx())
			if err != nil {
				mctx.Debug("| KBFS stats error: %+v", err)
			} else {
				res.LocalBlockCacheDbStats = stats.BlockCacheDbStats
				res.LocalSyncCacheDbStats = stats.SyncCacheDbStats
			}
		}
	}

	if g.UIRouter != nil {
		uiMapping := map[string]int{}
		for k, v := range g.UIRouter.DumpUIs() {
			uiMapping[k.String()] = int(v)
		}
		res.UiRouterMapping = uiMapping
	}

	return res, nil
}

func GetConfig(mctx libkb.MetaContext, forkType keybase1.ForkType) (c keybase1.Config, err error) {
	serverURI, err := mctx.G().Env.GetServerURI()
	if err != nil {
		return c, err
	}

	c.ServerURI = serverURI
	c.RunMode = string(mctx.G().Env.GetRunMode())
	c.SocketFile, err = mctx.G().Env.GetSocketBindFile()
	if err != nil {
		return c, err
	}

	gpg := mctx.G().GetGpgClient()
	canExec, err := gpg.CanExec(mctx)
	if err == nil {
		c.GpgExists = canExec
		c.GpgPath = gpg.Path(mctx)
	}

	c.Version = libkb.VersionString()
	c.VersionShort = libkb.Version

	var v []string
	libkb.VersionMessage(func(s string) {
		v = append(v, s)
	})
	c.VersionFull = strings.Join(v, "\n")

	dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
	if err == nil {
		c.Path = dir
	} else {
		mctx.Warning("Failed to get service path: %s", err)
	}

	realpath, err := libkb.CurrentBinaryRealpath()
	if err == nil {
		c.BinaryRealpath = realpath
	} else {
		mctx.Debug("Failed to get service realpath: %s", err)
	}

	c.ConfigPath = mctx.G().Env.GetConfigFilename()
	c.Label = mctx.G().Env.GetLabel()
	if forkType == keybase1.ForkType_AUTO {
		c.IsAutoForked = true
	}
	c.ForkType = forkType
	return c, nil
}

func GetFullStatus(mctx libkb.MetaContext) (status *keybase1.FullStatus, err error) {
	status = &keybase1.FullStatus{}
	// The client overrides this value when sending logs
	status.Client.Version = libkb.VersionString()
	status.ConfigPath = mctx.G().Env.GetConfigFilename()

	status.CurStatus, err = GetCurrentStatus(mctx)
	if err != nil {
		return nil, err
	}

	// Duplicate the username at top-level for backwards compatibility of
	// output.
	if status.CurStatus.User != nil {
		status.Username = status.CurStatus.User.Username
	}

	status.ExtStatus, err = GetExtendedStatus(mctx)
	if err != nil {
		return nil, err
	}

	// set service status
	if status.ExtStatus.Standalone {
		status.Service.Running = false
	} else {
		status.Service.Running = true
	}
	status.Service.Version = libkb.VersionString()

	// set kbfs status
	kbfsInstalledVersion, err := install.KBFSBundleVersion(mctx.G(), "")
	if err != nil {
		mctx.Debug("Failed to get KBFSBundleVersion: %s", err)
	} else {
		mctx.Debug("Got KBFSBundleVersion: %s", kbfsInstalledVersion)
		status.Kbfs.InstalledVersion = kbfsInstalledVersion
	}
	if kbfs := GetFirstClient(status.ExtStatus.Clients, keybase1.ClientType_KBFS); kbfs != nil {
		status.Kbfs.Version = kbfs.Version
		status.Kbfs.Running = true
		// This just gets the mountpoint from the environment; the
		// user could have technically passed a different mountpoint
		// to KBFS on macOS or Linux.  TODO(KBFS-2723): fetch the
		// actual mountpoint with a new RPC from KBFS.
		mountDir, err := mctx.G().Env.GetMountDir()
		if err != nil {
			return nil, err
		}
		status.Kbfs.Mount = mountDir
	} else {
		status.Kbfs.Version = kbfsInstalledVersion
	}

	// set desktop status
	if desktop := GetFirstClient(status.ExtStatus.Clients, keybase1.ClientType_GUI_MAIN); desktop != nil {
		status.Desktop.Running = true
		status.Desktop.Version = desktop.Version
	}

	// set log paths
	status.Service.Log = getServiceLog(mctx, status.ExtStatus.LogDir)
	status.Service.EkLog = filepath.Join(status.ExtStatus.LogDir, libkb.EKLogFileName)
	status.Service.PerfLog = filepath.Join(status.ExtStatus.LogDir, libkb.PerfLogFileName)
	status.Kbfs.Log = filepath.Join(status.ExtStatus.LogDir, libkb.KBFSLogFileName)
	status.Desktop.Log = filepath.Join(status.ExtStatus.LogDir, libkb.GUILogFileName)
	status.Updater.Log = filepath.Join(status.ExtStatus.LogDir, libkb.UpdaterLogFileName)
	status.Start.Log = filepath.Join(status.ExtStatus.LogDir, libkb.StartLogFileName)
	status.Git.Log = filepath.Join(status.ExtStatus.LogDir, libkb.GitLogFileName)

	// set anything os-specific
	mctx.Debug("Getting osSpecific status info : %s")
	if err := osSpecific(mctx, status); err != nil {
		return nil, err
	}
	return status, nil
}
<|endoftext|>


<commit_before>package gotool

import (
	"encoding/binary"
	"errors"
	"fmt"
	"net"
)

//ip格式转uint32
func IPv4toUint32(ip string) (uint32, error) {
	i := net.ParseIP(ip)
	if i == nil {
		return 0, errors.New("ParseIP error")
	}
	i = i.To4()
	return binary.BigEndian.Uint32(i), nil
}

////Uint32转ip格式 old
// func Uint32toIPv4(ipint uint32) string {
// 	a := ipint >> 24
// 	b := (ipint - (a << 24)) >> 16
// 	c := (ipint - (a << 24) - (b << 16)) >> 8
// 	d := ipint - (a << 24) - (b << 16) - (c << 8)
// 	return fmt.Sprintf("%v.%v.%v.%v", a, b, c, d)
// }

//Uint32转ip格式
func Uint32toIPv4(ipint uint32) string {
	ip := make(net.IP, 4)
	binary.BigEndian.PutUint32(ip, ipint)
	return ip.String()
}

//Uint32转成net.IP
func Uint32toIP(ipint uint32) net.IP {
	ip := make(net.IP, 4)
	binary.BigEndian.PutUint32(ip, ipint)
	return ip
}

//获取本机网卡IP
func GetLocalIP() ([]string, error) {
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		return nil, err
	}
	var ips []string
	for _, v := range addrs {
		if ipnet, ok := v.(*net.IPNet); ok {
			ip := ipnet.IP
			if ip.To4() != nil && !ip.IsLoopback() {
				ips = append(ips, ip.String())
			}
		}
	}
	return ips, nil
}

//将CIDR转成数字,如  1.0.0.0/24 转成 16777216 16777471
func CIDRToUint32(cidr string) (start uint32, end uint32, err error) {
	i, n, err := net.ParseCIDR(cidr)
	if err != nil {
		return
	}
	mask, bit := n.Mask.Size()
	start, err = IPv4toUint32(i.String())
	if err != nil {
		return
	}
	network, err := IPv4toUint32(n.IP.String())
	if err != nil {
		return
	}
	end = 1<<(uint32(bit-mask)) + network - 1
	return
}

//将CIDR转成起始IP-结束IP,如  192.168.0.0/24 转成 192.168.0.0 192.168.0.255
func CIDRToIPRange(cidr string) (startip string, endip string, err error) {
	start, end, err := CIDRToUint32(cidr)
	if err != nil {
		return
	}
	startip = Uint32toIPv4(start)
	endip = Uint32toIPv4(end)
	return
}

//将起始IP-结束IP转成CIDR,如 192.168.0.0 192.168.0.255  转成 192.168.0.0/24
func IPRangeToCIDR(startip string, endip string) (cidr string, err error) {
	start, err := IPv4toUint32(startip)
	if err != nil {
		return
	}
	end, err := IPv4toUint32(endip)
	if err != nil {
		return
	}
	//取主机位长度
	bit := len(fmt.Sprintf("%b", start^end))
	//起始地址（网络号）
	ipint := (start >> uint32(bit)) << uint32(bit)
	cidr = fmt.Sprintf("%v/%v", Uint32toIPv4(ipint), 32-bit)
	return
}

// 用startip,endip计算子网掩码长度，如192.168.0.0 192.168.0.255 返回 24
func IPNetMaskBit(startip string, endip string) (bit int, err error) {
	start, err := IPv4toUint32(startip)
	if err != nil {
		return
	}
	end, err := IPv4toUint32(endip)
	if err != nil {
		return
	}
	bit = 32 - len(fmt.Sprintf("%b", start^end))
	return
}

// Well-known IPv4 Private addresses
var (
	PrivateIPNet = []string{
		"10.0.0.0/8",
		"172.16.0.0/12",
		"192.168.0.0/16",
	}
)

//是否为私网ip
func IsPrivateIP(ip string) bool {
	for _, ipnet := range PrivateIPNet {
		_, n, _ := net.ParseCIDR(ipnet)
		if n.Contains(net.ParseIP(ip)) {
			return true
		}
	}
	return false
}
<commit_msg>新增 CIDRToIPMask,IPMaskToCIDR,InverseMask,MaskLength<commit_after>package gotool

import (
	"encoding/binary"
	"errors"
	"fmt"
	"net"
)

//ip格式转uint32
func IPv4toUint32(ip string) (uint32, error) {
	i := net.ParseIP(ip)
	if i == nil {
		return 0, errors.New("ParseIP error")
	}
	i = i.To4()
	return binary.BigEndian.Uint32(i), nil
}

////Uint32转ip格式 old
// func Uint32toIPv4(ipint uint32) string {
// 	a := ipint >> 24
// 	b := (ipint - (a << 24)) >> 16
// 	c := (ipint - (a << 24) - (b << 16)) >> 8
// 	d := ipint - (a << 24) - (b << 16) - (c << 8)
// 	return fmt.Sprintf("%v.%v.%v.%v", a, b, c, d)
// }

//Uint32转ip格式
func Uint32toIPv4(ipint uint32) string {
	ip := make(net.IP, 4)
	binary.BigEndian.PutUint32(ip, ipint)
	return ip.String()
}

//Uint32转成net.IP
func Uint32toIP(ipint uint32) net.IP {
	ip := make(net.IP, 4)
	binary.BigEndian.PutUint32(ip, ipint)
	return ip
}

//获取本机网卡IP
func GetLocalIP() ([]string, error) {
	addrs, err := net.InterfaceAddrs()
	if err != nil {
		return nil, err
	}
	var ips []string
	for _, v := range addrs {
		if ipnet, ok := v.(*net.IPNet); ok {
			ip := ipnet.IP
			if ip.To4() != nil && !ip.IsLoopback() {
				ips = append(ips, ip.String())
			}
		}
	}
	return ips, nil
}

//将CIDR转成数字,如  1.0.0.0/24 转成 16777216 16777471
func CIDRToUint32(cidr string) (start uint32, end uint32, err error) {
	i, n, err := net.ParseCIDR(cidr)
	if err != nil {
		return
	}
	mask, bit := n.Mask.Size()
	start, err = IPv4toUint32(i.String())
	if err != nil {
		return
	}
	network, err := IPv4toUint32(n.IP.String())
	if err != nil {
		return
	}
	end = 1<<(uint32(bit-mask)) + network - 1
	return
}

//将CIDR转成起始IP-结束IP,如  192.168.0.0/24 转成 192.168.0.0 192.168.0.255
func CIDRToIPRange(cidr string) (startip string, endip string, err error) {
	start, end, err := CIDRToUint32(cidr)
	if err != nil {
		return
	}
	startip = Uint32toIPv4(start)
	endip = Uint32toIPv4(end)
	return
}

//将起始IP-结束IP转成CIDR,如 192.168.0.0 192.168.0.255  转成 192.168.0.0/24
func IPRangeToCIDR(startip string, endip string) (cidr string, err error) {
	start, err := IPv4toUint32(startip)
	if err != nil {
		return
	}
	end, err := IPv4toUint32(endip)
	if err != nil {
		return
	}
	//取主机位长度
	bit := len(fmt.Sprintf("%b", start^end))
	//起始地址（网络号）
	ipint := (start >> uint32(bit)) << uint32(bit)
	cidr = fmt.Sprintf("%v/%v", Uint32toIPv4(ipint), 32-bit)
	return
}

// 用startip,endip计算子网掩码长度，如192.168.0.0 192.168.0.255 返回 24
func IPNetMaskBit(startip string, endip string) (bit int, err error) {
	start, err := IPv4toUint32(startip)
	if err != nil {
		return
	}
	end, err := IPv4toUint32(endip)
	if err != nil {
		return
	}
	bit = 32 - len(fmt.Sprintf("%b", start^end))
	return
}

//将 1.1.1.0/24  转成1.1.1.0 255.255.255.0
func CIDRToIPMask(cidr string) (string, string, error) {
	_, ipnet, err := net.ParseCIDR(cidr)
	if err != nil {
		return "", "", err
	}
	bytesToIP := func(b []byte) string {
		i := binary.BigEndian.Uint32(b)
		return Uint32toIPv4(i)
	}
	ip := ipnet.IP.String()
	mask := bytesToIP([]byte(ipnet.Mask))
	return ip, mask, nil
}

//将 1.1.1.0 255.255.255.0   转成 1.1.1.0/24
func IPMaskToCIDR(ip string, mask string) string {
	IP := net.ParseIP(ip)
	if IP == nil {
		return ""
	}
	return fmt.Sprintf("%s/%v", IP, MaskLength(mask))
}

//计算反掩码  将255.255.255.0 转成0.0.0.255
func InverseMask(mask string) string {
	i, err := IPv4toUint32(mask)
	if err != nil {
		return ""
	}
	return Uint32toIPv4(^i)
}

//计算掩码长度  255.255.255.0 得出 24
func MaskLength(mask string) int {
	ip := net.ParseIP(mask).To4()
	if ip == nil {
		return 0
	}
	i := []byte(ip)
	ipmask := net.IPv4Mask(i[0], i[1], i[2], i[3])
	ones, _ := ipmask.Size()
	return ones
}

// Well-known IPv4 Private addresses
var (
	PrivateIPNet = []string{
		"10.0.0.0/8",
		"172.16.0.0/12",
		"192.168.0.0/16",
	}
)

//是否为私网ip
func IsPrivateIP(ip string) bool {
	for _, ipnet := range PrivateIPNet {
		_, n, _ := net.ParseCIDR(ipnet)
		if n.Contains(net.ParseIP(ip)) {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package goEnv

import (
	"fmt"
	"os"
	"testing"
)

type testStruct struct {
	A int    `cfg:"A" cfgDefault:"100"`
	B string `cfg:"B" cfgDefault:"200"`
	C string
	N string `cfg:"-"`
	p string
	S testSub `cfg:"S"`
}

type testSub struct {
	A int        `cfg:"A" cfgDefault:"300"`
	B string     `cfg:"C" cfgDefault:"400"`
	S testSubSub `cfg:"S"`
}
type testSubSub struct {
	A int    `cfg:"A" cfgDefault:"500"`
	B string `cfg:"S" cfgDefault:"600"`
}

func TestParse(t *testing.T) {

	os.Setenv("A", "900")
	os.Setenv("B", "TEST")

	s := &testStruct{A: 1, S: testSub{A: 1, B: "2"}}
	err := Parse(s)
	if err != nil {
		t.Fatal(err)
	}

	fmt.Printf("\n\nTestParseTags: %#v\n\n", s)

	os.Setenv("A", "900ERROR")

	err = Parse(s)
	if err == nil {
		t.Fatal("Error expected")
	}

	os.Setenv("A", "")

	err = Parse(s)
	if err != nil {
		t.Fatal(err)
	}

	s1 := "test"
	err = Parse(s1)
	if err == nil {
		t.Fatal("Error expected")
	}

	err = Parse(&s1)
	if err == nil {
		t.Fatal("Error expected")
	}
}
<commit_msg>improve int test<commit_after>package goEnv

import (
	"os"
	"testing"
)

type testStruct struct {
	A int    `cfg:"A" cfgDefault:"100"`
	B string `cfg:"B" cfgDefault:"200"`
	C string
	N string `cfg:"-"`
	M int
	p string
	S testSub `cfg:"S"`
}

type testSub struct {
	A int        `cfg:"A" cfgDefault:"300"`
	B string     `cfg:"C" cfgDefault:"400"`
	S testSubSub `cfg:"S"`
}
type testSubSub struct {
	A int    `cfg:"A" cfgDefault:"500"`
	B string `cfg:"S" cfgDefault:"600"`
}

func TestParse(t *testing.T) {

	Setup("cfg", "cfgDefault")

	os.Setenv("A", "900")
	os.Setenv("B", "TEST")

	s := &testStruct{A: 1, S: testSub{A: 1, B: "2"}}
	err := Parse(s)
	if err != nil {
		t.Fatal(err)
	}

	os.Setenv("A", "900ERROR")

	err = Parse(s)
	if err == nil {
		t.Fatal("Error expected")
	}

	os.Setenv("A", "")

	err = Parse(s)
	if err != nil {
		t.Fatal(err)
	}

	s1 := "test"
	err = Parse(s1)
	if err == nil {
		t.Fatal("Error expected")
	}

	err = Parse(&s1)
	if err == nil {
		t.Fatal("Error expected")
	}
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"errors"
	"flag"
	"fmt"
	"go/format"
	"os"
	"regexp"
	"strings"
	"time"
	"unicode"

	"labix.org/v2/mgo"
	"labix.org/v2/mgo/bson"
)

var errEmptyURL = errors.New("mongoschema: no URL specificed")

func main() {
	var generator Generator
	flag.StringVar(&generator.URL, "url", "", "mongo url for dial")
	flag.StringVar(&generator.DB, "db", "", "database to use")
	flag.StringVar(&generator.Collection, "collection", "", "collection to use")
	flag.StringVar(&generator.Struct, "struct", "", "name of the struct")
	flag.StringVar(&generator.Package, "package", "", "pkg for the generate code")
	flag.BoolVar(&generator.Raw, "raw", false, "output pre-gofmt code")
	flag.BoolVar(&generator.Comments, "comments", true, "output comments in code")
	flag.UintVar(&generator.Limit, "limit", 0, "maximum number of documents to scan")
	ignoredKeys := flag.String("ignored-keys", "", "comma separated list of key names to ignore")
	flag.Parse()

	generator.IgnoredKeys = strings.Split(*ignoredKeys, ",")

	if err := generator.Generate(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(2)
	}
}

type Generator struct {
	URL         string
	DB          string
	Collection  string
	Package     string
	Struct      string
	Raw         bool
	Comments    bool
	IgnoredKeys []string
	Limit       uint
}

func (s *Generator) connect() (*mgo.Session, *mgo.Collection, error) {
	if s.URL == "" {
		return nil, nil, errEmptyURL
	}

	session, err := mgo.Dial(s.URL)
	if err != nil {
		return nil, nil, err
	}
	session.EnsureSafe(&mgo.Safe{})
	session.SetBatch(1000)
	session.SetMode(mgo.Eventual, true)
	return session, session.DB(s.DB).C(s.Collection), nil
}

func (s *Generator) Generate() error {
	session, collection, err := s.connect()
	if err != nil {
		return err
	}

	root := StructType{}
	iter := collection.Find(nil).Iter()
	m := bson.M{}
	var seen uint
	for iter.Next(m) {
		if s.Limit != 0 && seen == s.Limit {
			break
		}
		root.Merge(NewType(m, s), s)
		m = bson.M{}
		seen++
	}
	if err := iter.Close(); err != nil {
		return err
	}
	session.Close()

	const srcFmt = "package %s\ntype %s %s"
	src := fmt.Sprintf(srcFmt, s.Package, s.Struct, root.GoType(s))
	if s.Raw {
		fmt.Println(src)
	}
	formatted, err := format.Source([]byte(src))
	if err != nil {
		return err
	}
	fmt.Printf("%s\n", formatted)
	return nil
}

type Type interface {
	GoType(gen *Generator) string
	Merge(t Type, gen *Generator) Type
}

type LiteralType struct {
	Literal string
}

func (l LiteralType) GoType(gen *Generator) string {
	return l.Literal
}

func (l LiteralType) Merge(t Type, gen *Generator) Type {
	if l.GoType(gen) == t.GoType(gen) {
		return l
	}
	return MixedType{l, t}
}

var NilType = LiteralType{Literal: "nil"}

type MixedType []Type

func (m MixedType) GoType(gen *Generator) string {
	if !gen.Comments {
		return "interface{}"
	}
	var b bytes.Buffer
	fmt.Fprint(&b, "interface{} /* ")
	for i, v := range m {
		fmt.Fprint(&b, v.GoType(gen))
		if i != len(m)-1 {
			fmt.Fprint(&b, ",")
		}
		fmt.Fprint(&b, " ")
	}
	fmt.Fprint(&b, " */")
	return b.String()
}

func (m MixedType) Merge(t Type, gen *Generator) Type {
	for _, e := range m {
		if e.GoType(gen) == t.GoType(gen) {
			return m
		}
	}
	return append(m, t)
}

type PrimitiveType uint

const (
	PrimitiveBinary PrimitiveType = iota
	PrimitiveBool
	PrimitiveDouble
	PrimitiveInt32
	PrimitiveInt64
	PrimitiveObjectId
	PrimitiveString
	PrimitiveTimestamp
)

func (p PrimitiveType) GoType(gen *Generator) string {
	switch p {
	case PrimitiveBinary:
		return "bson.Binary"
	case PrimitiveBool:
		return "bool"
	case PrimitiveDouble:
		return "float64"
	case PrimitiveInt32:
		return "int32"
	case PrimitiveInt64:
		return "int64"
	case PrimitiveString:
		return "string"
	case PrimitiveTimestamp:
		return "time.Time"
	case PrimitiveObjectId:
		return "bson.ObjectId"
	}
	panic(fmt.Sprintf("unknown primitive: %d", uint(p)))
}

func (p PrimitiveType) Merge(t Type, gen *Generator) Type {
	if p.GoType(gen) == t.GoType(gen) {
		return p
	}
	return MixedType{p, t}
}

type SliceType struct {
	Type
}

func (s SliceType) GoType(gen *Generator) string {
	return fmt.Sprintf("[]%s", s.Type.GoType(gen))
}

func (s SliceType) Merge(t Type, gen *Generator) Type {
	if s.GoType(gen) == t.GoType(gen) {
		return s
	}

	// If the target type is a slice of structs, we merge into the first struct
	// type in our own slice type.
	if targetSliceType, ok := t.(SliceType); ok {
		if targetSliceStructType, ok := targetSliceType.Type.(StructType); ok {
			// We're a slice of structs.
			if ownSliceStructType, ok := s.Type.(StructType); ok {
				s.Type = ownSliceStructType.Merge(targetSliceStructType, gen)
				return s
			}

			// We're a slice of mixed types, one of which may or may not be a struct.
			if sliceMixedType, ok := s.Type.(MixedType); ok {
				for i, v := range sliceMixedType {
					if vStructType, ok := v.(StructType); ok {
						sliceMixedType[i] = vStructType.Merge(targetSliceStructType, gen)
						return s
					}
				}
				return SliceType{Type: append(sliceMixedType, targetSliceStructType)}
			}
		}
	}
	return MixedType{s, t}
}

type StructType map[string]Type

func (s StructType) GoType(gen *Generator) string {
	var buf bytes.Buffer
	fmt.Fprintln(&buf, "struct {")
	for k, v := range s {
		if isValidFieldName(k) {
			var vGoType string

			if sscontains(gen.IgnoredKeys, k) {
				vGoType = "IgnoredField"
			} else {
				vGoType = v.GoType(gen)
			}

			fmt.Fprintf(
				&buf,
				"%s %s `bson:\"%s,omitempty\"`\n",
				makeFieldName(k),
				vGoType,
				k,
			)
		} else {
			if gen.Comments {
				fmt.Fprintf(&buf, "// skipping invalid field name %s\n", k)
			}
		}
	}
	fmt.Fprint(&buf, "}")
	return buf.String()
}

func (s StructType) Merge(t Type, gen *Generator) Type {
	if o, ok := t.(StructType); ok {
		for k, v := range o {
			if e, ok := s[k]; ok {
				s[k] = e.Merge(v, gen)
			} else {
				s[k] = v
			}
		}
		return s
	}
	return MixedType{s, t}
}

func NewType(v interface{}, gen *Generator) Type {
	switch i := v.(type) {
	default:
		panic(fmt.Sprintf("cannot determine type for %v with go type %T", v, v))
	case nil:
		return NilType
	case bson.ObjectId:
		return PrimitiveObjectId
	case bson.M:
		return NewStructType(i, gen)
	case []interface{}:
		if len(i) == 0 {
			return SliceType{Type: MixedType{}}
		}
		var s Type
		for _, v := range i {
			vt := NewType(v, gen)
			if vt == NilType {
				continue
			}
			if s == nil {
				s = SliceType{Type: vt}
			} else {
				s.Merge(SliceType{Type: vt}, gen)
			}
		}
		if s == nil {
			return SliceType{Type: MixedType{}}
		}
		return s
	case int, int64:
		return PrimitiveInt64
	case int32:
		return PrimitiveInt32
	case bool:
		return PrimitiveBool
	case string:
		return PrimitiveString
	case time.Time, bson.MongoTimestamp:
		return PrimitiveTimestamp
	case float32, float64:
		return PrimitiveDouble
	case bson.Binary:
		return PrimitiveBinary
	}
}

func NewStructType(m bson.M, gen *Generator) Type {
	s := StructType{}
	for k, v := range m {
		t := NewType(v, gen)
		if t == NilType {
			continue
		}
		s[k] = t
	}
	return s
}

func isValidFieldName(n string) bool {
	if n == "" {
		return false
	}
	if strings.IndexAny(n, "!*") == -1 {
		return true
	}
	return false
}

var (
	dashUnderscoreReplacer = strings.NewReplacer("-", " ", "_", " ")
	capsRe                 = regexp.MustCompile(`([A-Z])`)
	spaceRe                = regexp.MustCompile(`(\w+)`)
	forcedUpperCase        = map[string]bool{"id": true, "url": true, "api": true}
)

func split(str string) []string {
	str = dashUnderscoreReplacer.Replace(str)
	str = capsRe.ReplaceAllString(str, " $1")
	return spaceRe.FindAllString(str, -1)
}

func makeFieldName(s string) string {
	parts := split(s)
	for i, part := range parts {
		if forcedUpperCase[strings.ToLower(part)] {
			parts[i] = strings.ToUpper(part)
		} else {
			parts[i] = strings.Title(part)
		}
	}
	camel := strings.Join(parts, "")
	runes := []rune(camel)
	for i, c := range runes {
		ok := unicode.IsLetter(c) || unicode.IsDigit(c)
		if i == 0 {
			ok = unicode.IsLetter(c)
		}
		if !ok {
			runes[i] = '_'
		}
	}
	return string(runes)
}

func sscontains(l []string, v string) bool {
	for _, e := range l {
		if e == v {
			return true
		}
	}
	return false
}
<commit_msg>update mgo path<commit_after>package main

import (
	"bytes"
	"errors"
	"flag"
	"fmt"
	"go/format"
	"os"
	"regexp"
	"strings"
	"time"
	"unicode"

	"gopkg.in/mgo.v2"
	"gopkg.in/mgo.v2/bson"
)

var errEmptyURL = errors.New("mongoschema: no URL specificed")

func main() {
	var generator Generator
	flag.StringVar(&generator.URL, "url", "", "mongo url for dial")
	flag.StringVar(&generator.DB, "db", "", "database to use")
	flag.StringVar(&generator.Collection, "collection", "", "collection to use")
	flag.StringVar(&generator.Struct, "struct", "", "name of the struct")
	flag.StringVar(&generator.Package, "package", "", "pkg for the generate code")
	flag.BoolVar(&generator.Raw, "raw", false, "output pre-gofmt code")
	flag.BoolVar(&generator.Comments, "comments", true, "output comments in code")
	flag.UintVar(&generator.Limit, "limit", 0, "maximum number of documents to scan")
	ignoredKeys := flag.String("ignored-keys", "", "comma separated list of key names to ignore")
	flag.Parse()

	generator.IgnoredKeys = strings.Split(*ignoredKeys, ",")

	if err := generator.Generate(); err != nil {
		fmt.Fprintln(os.Stderr, err)
		os.Exit(2)
	}
}

type Generator struct {
	URL         string
	DB          string
	Collection  string
	Package     string
	Struct      string
	Raw         bool
	Comments    bool
	IgnoredKeys []string
	Limit       uint
}

func (s *Generator) connect() (*mgo.Session, *mgo.Collection, error) {
	if s.URL == "" {
		return nil, nil, errEmptyURL
	}

	session, err := mgo.Dial(s.URL)
	if err != nil {
		return nil, nil, err
	}
	session.EnsureSafe(&mgo.Safe{})
	session.SetBatch(1000)
	session.SetMode(mgo.Eventual, true)
	return session, session.DB(s.DB).C(s.Collection), nil
}

func (s *Generator) Generate() error {
	session, collection, err := s.connect()
	if err != nil {
		return err
	}

	root := StructType{}
	iter := collection.Find(nil).Iter()
	m := bson.M{}
	var seen uint
	for iter.Next(m) {
		if s.Limit != 0 && seen == s.Limit {
			break
		}
		root.Merge(NewType(m, s), s)
		m = bson.M{}
		seen++
	}
	if err := iter.Close(); err != nil {
		return err
	}
	session.Close()

	const srcFmt = "package %s\ntype %s %s"
	src := fmt.Sprintf(srcFmt, s.Package, s.Struct, root.GoType(s))
	if s.Raw {
		fmt.Println(src)
	}
	formatted, err := format.Source([]byte(src))
	if err != nil {
		return err
	}
	fmt.Printf("%s\n", formatted)
	return nil
}

type Type interface {
	GoType(gen *Generator) string
	Merge(t Type, gen *Generator) Type
}

type LiteralType struct {
	Literal string
}

func (l LiteralType) GoType(gen *Generator) string {
	return l.Literal
}

func (l LiteralType) Merge(t Type, gen *Generator) Type {
	if l.GoType(gen) == t.GoType(gen) {
		return l
	}
	return MixedType{l, t}
}

var NilType = LiteralType{Literal: "nil"}

type MixedType []Type

func (m MixedType) GoType(gen *Generator) string {
	if !gen.Comments {
		return "interface{}"
	}
	var b bytes.Buffer
	fmt.Fprint(&b, "interface{} /* ")
	for i, v := range m {
		fmt.Fprint(&b, v.GoType(gen))
		if i != len(m)-1 {
			fmt.Fprint(&b, ",")
		}
		fmt.Fprint(&b, " ")
	}
	fmt.Fprint(&b, " */")
	return b.String()
}

func (m MixedType) Merge(t Type, gen *Generator) Type {
	for _, e := range m {
		if e.GoType(gen) == t.GoType(gen) {
			return m
		}
	}
	return append(m, t)
}

type PrimitiveType uint

const (
	PrimitiveBinary PrimitiveType = iota
	PrimitiveBool
	PrimitiveDouble
	PrimitiveInt32
	PrimitiveInt64
	PrimitiveObjectId
	PrimitiveString
	PrimitiveTimestamp
)

func (p PrimitiveType) GoType(gen *Generator) string {
	switch p {
	case PrimitiveBinary:
		return "bson.Binary"
	case PrimitiveBool:
		return "bool"
	case PrimitiveDouble:
		return "float64"
	case PrimitiveInt32:
		return "int32"
	case PrimitiveInt64:
		return "int64"
	case PrimitiveString:
		return "string"
	case PrimitiveTimestamp:
		return "time.Time"
	case PrimitiveObjectId:
		return "bson.ObjectId"
	}
	panic(fmt.Sprintf("unknown primitive: %d", uint(p)))
}

func (p PrimitiveType) Merge(t Type, gen *Generator) Type {
	if p.GoType(gen) == t.GoType(gen) {
		return p
	}
	return MixedType{p, t}
}

type SliceType struct {
	Type
}

func (s SliceType) GoType(gen *Generator) string {
	return fmt.Sprintf("[]%s", s.Type.GoType(gen))
}

func (s SliceType) Merge(t Type, gen *Generator) Type {
	if s.GoType(gen) == t.GoType(gen) {
		return s
	}

	// If the target type is a slice of structs, we merge into the first struct
	// type in our own slice type.
	if targetSliceType, ok := t.(SliceType); ok {
		if targetSliceStructType, ok := targetSliceType.Type.(StructType); ok {
			// We're a slice of structs.
			if ownSliceStructType, ok := s.Type.(StructType); ok {
				s.Type = ownSliceStructType.Merge(targetSliceStructType, gen)
				return s
			}

			// We're a slice of mixed types, one of which may or may not be a struct.
			if sliceMixedType, ok := s.Type.(MixedType); ok {
				for i, v := range sliceMixedType {
					if vStructType, ok := v.(StructType); ok {
						sliceMixedType[i] = vStructType.Merge(targetSliceStructType, gen)
						return s
					}
				}
				return SliceType{Type: append(sliceMixedType, targetSliceStructType)}
			}
		}
	}
	return MixedType{s, t}
}

type StructType map[string]Type

func (s StructType) GoType(gen *Generator) string {
	var buf bytes.Buffer
	fmt.Fprintln(&buf, "struct {")
	for k, v := range s {
		if isValidFieldName(k) {
			var vGoType string

			if sscontains(gen.IgnoredKeys, k) {
				vGoType = "IgnoredField"
			} else {
				vGoType = v.GoType(gen)
			}

			fmt.Fprintf(
				&buf,
				"%s %s `bson:\"%s,omitempty\"`\n",
				makeFieldName(k),
				vGoType,
				k,
			)
		} else {
			if gen.Comments {
				fmt.Fprintf(&buf, "// skipping invalid field name %s\n", k)
			}
		}
	}
	fmt.Fprint(&buf, "}")
	return buf.String()
}

func (s StructType) Merge(t Type, gen *Generator) Type {
	if o, ok := t.(StructType); ok {
		for k, v := range o {
			if e, ok := s[k]; ok {
				s[k] = e.Merge(v, gen)
			} else {
				s[k] = v
			}
		}
		return s
	}
	return MixedType{s, t}
}

func NewType(v interface{}, gen *Generator) Type {
	switch i := v.(type) {
	default:
		panic(fmt.Sprintf("cannot determine type for %v with go type %T", v, v))
	case nil:
		return NilType
	case bson.ObjectId:
		return PrimitiveObjectId
	case bson.M:
		return NewStructType(i, gen)
	case []interface{}:
		if len(i) == 0 {
			return SliceType{Type: MixedType{}}
		}
		var s Type
		for _, v := range i {
			vt := NewType(v, gen)
			if vt == NilType {
				continue
			}
			if s == nil {
				s = SliceType{Type: vt}
			} else {
				s.Merge(SliceType{Type: vt}, gen)
			}
		}
		if s == nil {
			return SliceType{Type: MixedType{}}
		}
		return s
	case int, int64:
		return PrimitiveInt64
	case int32:
		return PrimitiveInt32
	case bool:
		return PrimitiveBool
	case string:
		return PrimitiveString
	case time.Time, bson.MongoTimestamp:
		return PrimitiveTimestamp
	case float32, float64:
		return PrimitiveDouble
	case bson.Binary:
		return PrimitiveBinary
	}
}

func NewStructType(m bson.M, gen *Generator) Type {
	s := StructType{}
	for k, v := range m {
		t := NewType(v, gen)
		if t == NilType {
			continue
		}
		s[k] = t
	}
	return s
}

func isValidFieldName(n string) bool {
	if n == "" {
		return false
	}
	if strings.IndexAny(n, "!*") == -1 {
		return true
	}
	return false
}

var (
	dashUnderscoreReplacer = strings.NewReplacer("-", " ", "_", " ")
	capsRe                 = regexp.MustCompile(`([A-Z])`)
	spaceRe                = regexp.MustCompile(`(\w+)`)
	forcedUpperCase        = map[string]bool{"id": true, "url": true, "api": true}
)

func split(str string) []string {
	str = dashUnderscoreReplacer.Replace(str)
	str = capsRe.ReplaceAllString(str, " $1")
	return spaceRe.FindAllString(str, -1)
}

func makeFieldName(s string) string {
	parts := split(s)
	for i, part := range parts {
		if forcedUpperCase[strings.ToLower(part)] {
			parts[i] = strings.ToUpper(part)
		} else {
			parts[i] = strings.Title(part)
		}
	}
	camel := strings.Join(parts, "")
	runes := []rune(camel)
	for i, c := range runes {
		ok := unicode.IsLetter(c) || unicode.IsDigit(c)
		if i == 0 {
			ok = unicode.IsLetter(c)
		}
		if !ok {
			runes[i] = '_'
		}
	}
	return string(runes)
}

func sscontains(l []string, v string) bool {
	for _, e := range l {
		if e == v {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>// Copyright 2016, RadiantBlue Technologies, 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 piazza

import (
	"net/http"
	"testing"

	"github.com/stretchr/testify/assert"
)

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

func xTestNT(t *testing.T) {
	assert := assert.New(t)
	server := &http.Server{Addr: ":19999", Handler: http.DefaultServeMux}
	err := server.ListenAndServe()
	assert.NoError(err)

	GetValueFromHeader(http.Header{}, "Content-Type")
	_, _, _, err = HTTP(GET, "localhost:19999", NewHeaderBuilder().AddJsonContentType().AddBasicAuth("foo", "bar").GetHeader(), nil)
	assert.NoError(err)
	_, _, _, err = HTTP(GET, "localhost:19999/exit", NewHeaderBuilder().GetHeader(), nil)
	assert.NoError(err)
}

func ExitFunc(response http.ResponseWriter, request *http.Request) {
	//log.Fatal("/exit handler called")
}
<commit_msg>Fixed the test<commit_after>// Copyright 2016, RadiantBlue Technologies, 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 piazza

import (
	"net/http"
	"testing"

	"github.com/stretchr/testify/assert"
)

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

func TestNT(t *testing.T) {
	assert := assert.New(t)

	var genericServer *GenericServer
	var server *ThingServer
	var sys *SystemConfig

	{
		var err error
		required := []ServiceName{}
		sys, err = NewSystemConfig(PzGoCommon, required)
		assert.NoError(err)

		genericServer = &GenericServer{Sys: sys}
		server = &ThingServer{}
		service := &ThingService{
			assert:  assert,
			IDCount: 0,
			Data:    make(map[string]string),
		}
		server.Init(service)
	}
	{
		var err error
		err = genericServer.Configure(server.routes)
		if err != nil {
			assert.FailNow("server failed to configure: " + err.Error())
		}
		_, err = genericServer.Start()
		if err != nil {
			assert.FailNow("server failed to start: " + err.Error())
		}
	}

	GetValueFromHeader(http.Header{}, "Content-Type")
	_, _, _, err := HTTP(GET, "localhost:"+LocalPortNumbers[PzGoCommon], NewHeaderBuilder().AddJsonContentType().AddBasicAuth("foo", "bar").GetHeader(), nil)
	assert.NoError(err)

	err = genericServer.Stop()
	assert.NoError(err)

}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"strings"

	"github.com/SpectoLabs/hoverfly/core/handlers/v2"
	"github.com/SpectoLabs/hoverfly/hoverctl/configuration"
	"github.com/SpectoLabs/hoverfly/hoverctl/wrapper"
	"github.com/spf13/cobra"
)

var middlewareBinary, middlewareScript, middlewareRemote string

var middlewareCmd = &cobra.Command{
	Use:   "middleware",
	Short: "Get and set Hoverfly middleware",
	Long: `
Hoverfly middleware can be set using the following
combinations of flags:

	--binary
	--binary --script
	--remote

If flags are not used, the current Hoverfly middleware
configuration will be shown.

`,

	Run: func(cmd *cobra.Command, args []string) {
		checkTargetAndExit(target)

		var middleware v2.MiddlewareView
		var err error

		if middlewareBinary == "" && middlewareScript == "" && middlewareRemote == "" {
			middleware, err = wrapper.GetMiddleware(*target)
			handleIfError(err)
			fmt.Println("Hoverfly middleware configuration is currently set to")
		} else {
			if middlewareRemote != "" {
				middleware, err = wrapper.SetMiddleware(*target, "", "", middlewareRemote)
				handleIfError(err)
				fmt.Println("Hoverfly middleware configuration has been set to")
			} else {
				script, err := configuration.ReadFile(middlewareScript)
				handleIfError(err)

				middleware, err = wrapper.SetMiddleware(*target, middlewareBinary, string(script), "")
				handleIfError(err)
				fmt.Println("Hoverfly middleware configuration has been set to")
			}
		}

		if middleware.Binary != "" {
			fmt.Println("Binary: " + middleware.Binary)
		}

		if middleware.Script != "" {
			middlewareScript := strings.Split(middleware.Script, "\n")
			if verbose || len(middlewareScript) < 5 {
				fmt.Println("Script: " + middleware.Script)
			}
			fmt.Println("Script: " + middlewareScript[0] + "\n" +
				middlewareScript[1] + "\n" +
				middlewareScript[2] + "\n" +
				middlewareScript[3] + "\n" +
				middlewareScript[4] + "\n" +
				"...")
		}

		if middleware.Remote != "" {
			fmt.Println("Remote: " + middleware.Remote)
		}
	},
}

func init() {
	RootCmd.AddCommand(middlewareCmd)
	middlewareCmd.PersistentFlags().StringVar(&middlewareBinary, "binary", "",
		"An absolute or relative path to a binary that Hoverfly will execute as middleware")
	middlewareCmd.PersistentFlags().StringVar(&middlewareScript, "script", "",
		"An absolute or relative path to a script that will be executed by the middleware binary")
	middlewareCmd.PersistentFlags().StringVar(&middlewareRemote, "remote", "",
		"A URL to a remote address that will be called by Hoverfly as middleware")
}
<commit_msg>Update middleware.go<commit_after>package cmd

import (
	"fmt"
	"strings"

	"github.com/SpectoLabs/hoverfly/core/handlers/v2"
	"github.com/SpectoLabs/hoverfly/hoverctl/configuration"
	"github.com/SpectoLabs/hoverfly/hoverctl/wrapper"
	"github.com/spf13/cobra"
)

var middlewareBinary, middlewareScript, middlewareRemote string

var middlewareCmd = &cobra.Command{
	Use:   "middleware",
	Short: "Get and set Hoverfly middleware",
	Long: `
Hoverfly middleware can be set using the following
combinations of flags:

	--binary
	--binary --script
	--remote

If flags are not used, the current Hoverfly middleware
configuration will be shown.

`,

	Run: func(cmd *cobra.Command, args []string) {
		checkTargetAndExit(target)

		var middleware v2.MiddlewareView
		var err error

		if middlewareBinary == "" && middlewareScript == "" && middlewareRemote == "" {
			middleware, err = wrapper.GetMiddleware(*target)
			handleIfError(err)
			fmt.Println("Hoverfly middleware configuration is currently set to")
		} else {
			if middlewareRemote != "" {
				middleware, err = wrapper.SetMiddleware(*target, "", "", middlewareRemote)
				handleIfError(err)
				fmt.Println("Hoverfly middleware configuration has been set to")
			} else {
				script, err := configuration.ReadFile(middlewareScript)
				handleIfError(err)

				middleware, err = wrapper.SetMiddleware(*target, middlewareBinary, string(script), "")
				handleIfError(err)
				fmt.Println("Hoverfly middleware configuration has been set to")
			}
		}

		if middleware.Binary != "" {
			fmt.Println("Binary: " + middleware.Binary)
		}

		if middleware.Script != "" {
			middlewareScript := strings.Split(middleware.Script, "\n")
			if verbose || len(middlewareScript) < 5 {
				fmt.Println("Script: " + middleware.Script)
			} else {
				fmt.Println("Script: " + middlewareScript[0] + "\n" +
					middlewareScript[1] + "\n" +
					middlewareScript[2] + "\n" +
					middlewareScript[3] + "\n" +
					middlewareScript[4] + "\n" +
					"...")
			}
		}

		if middleware.Remote != "" {
			fmt.Println("Remote: " + middleware.Remote)
		}
	},
}

func init() {
	RootCmd.AddCommand(middlewareCmd)
	middlewareCmd.PersistentFlags().StringVar(&middlewareBinary, "binary", "",
		"An absolute or relative path to a binary that Hoverfly will execute as middleware")
	middlewareCmd.PersistentFlags().StringVar(&middlewareScript, "script", "",
		"An absolute or relative path to a script that will be executed by the middleware binary")
	middlewareCmd.PersistentFlags().StringVar(&middlewareRemote, "remote", "",
		"A URL to a remote address that will be called by Hoverfly as middleware")
}
<|endoftext|>