<commit_before>// Package machineid provides support for reading the unique machine id of most OSs (without admin privileges).
//
// https://github.com/denisbrodbeck/machineid
//
// This package is Cross-Platform (tested on Win7+, Debian 8+, Ubuntu 14.04+, OS X 10.6+, FreeBSD 11+)
// and does not use any internal hardware IDs (no MAC, BIOS, or CPU).
//
// Returned machine IDs are generally stable for the OS installation
// and usually stay the same after updates or hardware changes.
//
// This package allows sharing of machine IDs in a secure way by
// calculating HMAC-SHA256 over a user provided app ID, which is keyed by the machine id.
//
// Caveat: Image-based environments have usually the same machine-id (perfect clone).
// Linux users can generate a new id with `dbus-uuidgen` and put the id into
// `/var/lib/dbus/machine-id` and `/etc/machine-id`.
// Windows users can use the `sysprep` toolchain to create images, which produce valid images ready for distribution.
package machineid // import "github.com/denisbrodbeck/machineid"

import (
	"fmt"
)

// ID returns the platform specific machine id of the current host OS.
// Regard the returned id as "confidential" and consider using ProtectedID() instead.
func ID() (string, error) {
	id, err := machineID()
	if err != nil {
		return "", fmt.Errorf("machineid: %v", err)
	}
	return id, nil
}

// ProtectedID returns a hashed version of the machine ID in a cryptographically secure way,
// using a fixed, application-specific key.
// Internally, this function calculates HMAC-SHA256 of the application ID, keyed by the machine ID.
func ProtectedID(appID string) (string, error) {
	id, err := ID()
	if err != nil {
		return "", fmt.Errorf("machineid: %v", err)
	}
	return protect(appID, id), nil
}
<commit_msg>Update doc.<commit_after>// Package machineid provides support for reading the unique machine id of most OSs (without admin privileges).
//
// https://github.com/denisbrodbeck/machineid
//
// https://godoc.org/github.com/denisbrodbeck/machineid/cmd/machineid
//
// This package is Cross-Platform (tested on Win7+, Debian 8+, Ubuntu 14.04+, OS X 10.6+, FreeBSD 11+)
// and does not use any internal hardware IDs (no MAC, BIOS, or CPU).
//
// Returned machine IDs are generally stable for the OS installation
// and usually stay the same after updates or hardware changes.
//
// This package allows sharing of machine IDs in a secure way by
// calculating HMAC-SHA256 over a user provided app ID, which is keyed by the machine id.
//
// Caveat: Image-based environments have usually the same machine-id (perfect clone).
// Linux users can generate a new id with `dbus-uuidgen` and put the id into
// `/var/lib/dbus/machine-id` and `/etc/machine-id`.
// Windows users can use the `sysprep` toolchain to create images, which produce valid images ready for distribution.
package machineid // import "github.com/denisbrodbeck/machineid"

import (
	"fmt"
)

// ID returns the platform specific machine id of the current host OS.
// Regard the returned id as "confidential" and consider using ProtectedID() instead.
func ID() (string, error) {
	id, err := machineID()
	if err != nil {
		return "", fmt.Errorf("machineid: %v", err)
	}
	return id, nil
}

// ProtectedID returns a hashed version of the machine ID in a cryptographically secure way,
// using a fixed, application-specific key.
// Internally, this function calculates HMAC-SHA256 of the application ID, keyed by the machine ID.
func ProtectedID(appID string) (string, error) {
	id, err := ID()
	if err != nil {
		return "", fmt.Errorf("machineid: %v", err)
	}
	return protect(appID, id), nil
}
<|endoftext|>


<commit_before>/*
Copyright 2015 The Kubernetes Authors.

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 io

import (
	"fmt"
	"io/ioutil"
	"os"

	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/kubernetes/pkg/api/v1"
)

// LoadPodFromFile will read, decode, and return a Pod from a file.
func LoadPodFromFile(filePath string) (*v1.Pod, error) {
	if filePath == "" {
		return nil, fmt.Errorf("file path not specified")
	}
	podDef, err := ioutil.ReadFile(filePath)
	if err != nil {
		return nil, fmt.Errorf("failed to read file path %s: %+v", filePath, err)
	}
	if len(podDef) == 0 {
		return nil, fmt.Errorf("file was empty: %s", filePath)
	}
	pod := &v1.Pod{}

	codec := api.Codecs.LegacyCodec(api.Registry.GroupOrDie(v1.GroupName).GroupVersion)
	if err := runtime.DecodeInto(codec, podDef, pod); err != nil {
		return nil, fmt.Errorf("failed decoding file: %v", err)
	}
	return pod, nil
}

// SavePodToFile will encode and save a pod to a given path & permissions
func SavePodToFile(pod *v1.Pod, filePath string, perm os.FileMode) error {
	if filePath == "" {
		return fmt.Errorf("file path not specified")
	}
	codec := api.Codecs.LegacyCodec(api.Registry.GroupOrDie(v1.GroupName).GroupVersion)
	data, err := runtime.Encode(codec, pod)
	if err != nil {
		return fmt.Errorf("failed encoding pod: %v", err)
	}
	return ioutil.WriteFile(filePath, data, perm)
}
<commit_msg>run root-rewrite-v1-..., compile<commit_after>/*
Copyright 2015 The Kubernetes Authors.

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 io

import (
	"fmt"
	"io/ioutil"
	"os"

	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/kubernetes/pkg/api"
	"k8s.io/api/core/v1"
)

// LoadPodFromFile will read, decode, and return a Pod from a file.
func LoadPodFromFile(filePath string) (*v1.Pod, error) {
	if filePath == "" {
		return nil, fmt.Errorf("file path not specified")
	}
	podDef, err := ioutil.ReadFile(filePath)
	if err != nil {
		return nil, fmt.Errorf("failed to read file path %s: %+v", filePath, err)
	}
	if len(podDef) == 0 {
		return nil, fmt.Errorf("file was empty: %s", filePath)
	}
	pod := &v1.Pod{}

	codec := api.Codecs.LegacyCodec(api.Registry.GroupOrDie(v1.GroupName).GroupVersion)
	if err := runtime.DecodeInto(codec, podDef, pod); err != nil {
		return nil, fmt.Errorf("failed decoding file: %v", err)
	}
	return pod, nil
}

// SavePodToFile will encode and save a pod to a given path & permissions
func SavePodToFile(pod *v1.Pod, filePath string, perm os.FileMode) error {
	if filePath == "" {
		return fmt.Errorf("file path not specified")
	}
	codec := api.Codecs.LegacyCodec(api.Registry.GroupOrDie(v1.GroupName).GroupVersion)
	data, err := runtime.Encode(codec, pod)
	if err != nil {
		return fmt.Errorf("failed encoding pod: %v", err)
	}
	return ioutil.WriteFile(filePath, data, perm)
}
<|endoftext|>


<commit_before>package imgo

import (
	"errors"
	"os"

	"image/png"
	"image/jpeg"

	"image"
	"image/color"
)

func GetImageHeight(img image.Image) int {
	return img.Bounds().Max.Y
}

func GetImageWidth(img image.Image) int {
	return img.Bounds().Max.X
}

// decode a image and retrun golang image interface
func DecodeImage(filePath string) (img image.Image, err error) {
	reader, err := os.Open(filePath)
	if err != nil {
		return nil, err
	}
	defer reader.Close()

	img,_,err = image.Decode(reader)

	return
}

//convert image to NRGBA
func convertToNRGBA(src image.Image) *image.NRGBA {
	srcBounds := src.Bounds()
	dstBounds := srcBounds.Sub(srcBounds.Min)

	dst := image.NewNRGBA(dstBounds)

	dstMinX := dstBounds.Min.X
	dstMinY := dstBounds.Min.Y

	srcMinX := srcBounds.Min.X
	srcMinY := srcBounds.Min.Y
	srcMaxX := srcBounds.Max.X
	srcMaxY := srcBounds.Max.Y

	switch src0 := src.(type) {

	case *image.NRGBA:
		rowSize := srcBounds.Dx() * 4
		numRows := srcBounds.Dy()

		i0 := dst.PixOffset(dstMinX, dstMinY)
		j0 := src0.PixOffset(srcMinX, srcMinY)

		di := dst.Stride
		dj := src0.Stride

		for row := 0; row < numRows; row++ {
			copy(dst.Pix[i0:i0+rowSize], src0.Pix[j0:j0+rowSize])
			i0 += di
			j0 += dj
		}

	case *image.NRGBA64:
		i0 := dst.PixOffset(dstMinX, dstMinY)
		for y := srcMinY; y < srcMaxY; y, i0 = y+1, i0+dst.Stride {
			for x, i := srcMinX, i0; x < srcMaxX; x, i = x+1, i+4 {

				j := src0.PixOffset(x, y)

				dst.Pix[i+0] = src0.Pix[j+0]
				dst.Pix[i+1] = src0.Pix[j+2]
				dst.Pix[i+2] = src0.Pix[j+4]
				dst.Pix[i+3] = src0.Pix[j+6]

			}
		}

	case *image.RGBA:
		i0 := dst.PixOffset(dstMinX, dstMinY)
		for y := srcMinY; y < srcMaxY; y, i0 = y+1, i0+dst.Stride {
			for x, i := srcMinX, i0; x < srcMaxX; x, i = x+1, i+4 {

				j := src0.PixOffset(x, y)
				a := src0.Pix[j+3]
				dst.Pix[i+3] = a

				switch a {
				case 0:
					dst.Pix[i+0] = 0
					dst.Pix[i+1] = 0
					dst.Pix[i+2] = 0
				case 0xff:
					dst.Pix[i+0] = src0.Pix[j+0]
					dst.Pix[i+1] = src0.Pix[j+1]
					dst.Pix[i+2] = src0.Pix[j+2]
				default:
					dst.Pix[i+0] = uint8(uint16(src0.Pix[j+0]) * 0xff / uint16(a))
					dst.Pix[i+1] = uint8(uint16(src0.Pix[j+1]) * 0xff / uint16(a))
					dst.Pix[i+2] = uint8(uint16(src0.Pix[j+2]) * 0xff / uint16(a))
				}
			}
		}

	case *image.RGBA64:
		i0 := dst.PixOffset(dstMinX, dstMinY)
		for y := srcMinY; y < srcMaxY; y, i0 = y+1, i0+dst.Stride {
			for x, i := srcMinX, i0; x < srcMaxX; x, i = x+1, i+4 {

				j := src0.PixOffset(x, y)
				a := src0.Pix[j+6]
				dst.Pix[i+3] = a

				switch a {
				case 0:
					dst.Pix[i+0] = 0
					dst.Pix[i+1] = 0
					dst.Pix[i+2] = 0
				case 0xff:
					dst.Pix[i+0] = src0.Pix[j+0]
					dst.Pix[i+1] = src0.Pix[j+2]
					dst.Pix[i+2] = src0.Pix[j+4]
				default:
					dst.Pix[i+0] = uint8(uint16(src0.Pix[j+0]) * 0xff / uint16(a))
					dst.Pix[i+1] = uint8(uint16(src0.Pix[j+2]) * 0xff / uint16(a))
					dst.Pix[i+2] = uint8(uint16(src0.Pix[j+4]) * 0xff / uint16(a))
				}
			}
		}

	case *image.Gray:
		i0 := dst.PixOffset(dstMinX, dstMinY)
		for y := srcMinY; y < srcMaxY; y, i0 = y+1, i0+dst.Stride {
			for x, i := srcMinX, i0; x < srcMaxX; x, i = x+1, i+4 {

				j := src0.PixOffset(x, y)
				c := src0.Pix[j]
				dst.Pix[i+0] = c
				dst.Pix[i+1] = c
				dst.Pix[i+2] = c
				dst.Pix[i+3] = 0xff

			}
		}

	case *image.Gray16:
		i0 := dst.PixOffset(dstMinX, dstMinY)
		for y := srcMinY; y < srcMaxY; y, i0 = y+1, i0+dst.Stride {
			for x, i := srcMinX, i0; x < srcMaxX; x, i = x+1, i+4 {

				j := src0.PixOffset(x, y)
				c := src0.Pix[j]
				dst.Pix[i+0] = c
				dst.Pix[i+1] = c
				dst.Pix[i+2] = c
				dst.Pix[i+3] = 0xff

			}
		}

	case *image.YCbCr:
		i0 := dst.PixOffset(dstMinX, dstMinY)
		for y := srcMinY; y < srcMaxY; y, i0 = y+1, i0+dst.Stride {
			for x, i := srcMinX, i0; x < srcMaxX; x, i = x+1, i+4 {

				yj := src0.YOffset(x, y)
				cj := src0.COffset(x, y)
				r, g, b := color.YCbCrToRGB(src0.Y[yj], src0.Cb[cj], src0.Cr[cj])

				dst.Pix[i+0] = r
				dst.Pix[i+1] = g
				dst.Pix[i+2] = b
				dst.Pix[i+3] = 0xff

			}
		}

	default:
		i0 := dst.PixOffset(dstMinX, dstMinY)
		for y := srcMinY; y < srcMaxY; y, i0 = y+1, i0+dst.Stride {
			for x, i := srcMinX, i0; x < srcMaxX; x, i = x+1, i+4 {

				c := color.NRGBAModel.Convert(src.At(x, y)).(color.NRGBA)

				dst.Pix[i+0] = c.R
				dst.Pix[i+1] = c.G
				dst.Pix[i+2] = c.B
				dst.Pix[i+3] = c.A

			}
		}
	}

	return dst
}

// read a image return a image matrix
func Read(filepath string)(imgMatrix [][][]uint8 , err error){
	img,decodeErr:=DecodeImage(filepath)
	if decodeErr!=nil{
		err = decodeErr
		return
	}

	bounds:=img.Bounds()
	width:=bounds.Max.X  //width
	height:=bounds.Max.Y  //height

	src:=convertToNRGBA(img)
	imgMatrix = NewRGBAMatrix(height,width)

	for i:=0;i<height;i++{
		for j:=0;j<width;j++{
			c:=src.At(j,i)
			r,g,b,a:=c.RGBA()
			imgMatrix[i][j][0]=uint8(r)
			imgMatrix[i][j][1]=uint8(g)
			imgMatrix[i][j][2]=uint8(b)
			imgMatrix[i][j][3]=uint8(a)

		}
	}
	return
}

// read a image return a image matrix , if appear an error it will panic
func MustRead(filepath string)(imgMatrix [][][]uint8){
	img,decodeErr:=DecodeImage(filepath)
	if decodeErr!=nil{
		panic(decodeErr)
	}

	bounds:=img.Bounds()
	width:=bounds.Max.X
	height:=bounds.Max.Y

	src:=convertToNRGBA(img)
	imgMatrix = NewRGBAMatrix(height,width)

	for i:=0;i<height;i++{
		for j:=0;j<width;j++{
			c:=src.At(j,i)
			r,g,b,a:=c.RGBA()
			imgMatrix[i][j][0]=uint8(r)
			imgMatrix[i][j][1]=uint8(g)
			imgMatrix[i][j][2]=uint8(b)
			imgMatrix[i][j][3]=uint8(a)

		}
	}
	return
}

// save a image matrix as a png , if unsuccessful it will return a error
func SaveAsPNG(filepath string , imgMatrix [][][]uint8) error {
	height:=len(imgMatrix)
	width:=len(imgMatrix[0])

	if height == 0 {
		return errors.New("imgMatrix is a null matrix!")
	}

	nrgba:=image.NewNRGBA(image.Rect(0,0,width,height))

	for i:=0;i<height;i++{
		for j:=0;j<width;j++{
			nrgba.SetNRGBA(j,i,color.NRGBA{imgMatrix[i][j][0],imgMatrix[i][j][1],imgMatrix[i][j][2],imgMatrix[i][j][3]})
		}
	}
	outfile, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer outfile.Close()

	png.Encode(outfile,nrgba)

	return nil
}

// save a image matrix as a jpeg , if unsuccessful it will return a error
func SaveAsJPEG(filepath string , imgMatrix [][][]uint8) error {
	height:=len(imgMatrix)
	width:=len(imgMatrix[0])

	if height == 0 {
		return errors.New("imgMatrix is a null matrix!")
	}

	nrgba:=image.NewNRGBA(image.Rect(0,0,width,height))

	for i:=0;i<height;i++{
		for j:=0;j<width;j++{
			nrgba.SetNRGBA(j,i,color.NRGBA{imgMatrix[i][j][0],imgMatrix[i][j][1],imgMatrix[i][j][2],imgMatrix[i][j][3]})
		}
	}
	outfile, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer outfile.Close()

	jpeg.Encode(outfile,nrgba,nil)

	return nil
}<commit_msg>add check in savefunction<commit_after>package imgo

import (
	"errors"
	"os"

	"image/png"
	"image/jpeg"

	"image"
	"image/color"
)

func GetImageHeight(img image.Image) int {
	return img.Bounds().Max.Y
}

func GetImageWidth(img image.Image) int {
	return img.Bounds().Max.X
}

// decode a image and retrun golang image interface
func DecodeImage(filePath string) (img image.Image, err error) {
	reader, err := os.Open(filePath)
	if err != nil {
		return nil, err
	}
	defer reader.Close()

	img,_,err = image.Decode(reader)

	return
}

//convert image to NRGBA
func convertToNRGBA(src image.Image) *image.NRGBA {
	srcBounds := src.Bounds()
	dstBounds := srcBounds.Sub(srcBounds.Min)

	dst := image.NewNRGBA(dstBounds)

	dstMinX := dstBounds.Min.X
	dstMinY := dstBounds.Min.Y

	srcMinX := srcBounds.Min.X
	srcMinY := srcBounds.Min.Y
	srcMaxX := srcBounds.Max.X
	srcMaxY := srcBounds.Max.Y

	switch src0 := src.(type) {

	case *image.NRGBA:
		rowSize := srcBounds.Dx() * 4
		numRows := srcBounds.Dy()

		i0 := dst.PixOffset(dstMinX, dstMinY)
		j0 := src0.PixOffset(srcMinX, srcMinY)

		di := dst.Stride
		dj := src0.Stride

		for row := 0; row < numRows; row++ {
			copy(dst.Pix[i0:i0+rowSize], src0.Pix[j0:j0+rowSize])
			i0 += di
			j0 += dj
		}

	case *image.NRGBA64:
		i0 := dst.PixOffset(dstMinX, dstMinY)
		for y := srcMinY; y < srcMaxY; y, i0 = y+1, i0+dst.Stride {
			for x, i := srcMinX, i0; x < srcMaxX; x, i = x+1, i+4 {

				j := src0.PixOffset(x, y)

				dst.Pix[i+0] = src0.Pix[j+0]
				dst.Pix[i+1] = src0.Pix[j+2]
				dst.Pix[i+2] = src0.Pix[j+4]
				dst.Pix[i+3] = src0.Pix[j+6]

			}
		}

	case *image.RGBA:
		i0 := dst.PixOffset(dstMinX, dstMinY)
		for y := srcMinY; y < srcMaxY; y, i0 = y+1, i0+dst.Stride {
			for x, i := srcMinX, i0; x < srcMaxX; x, i = x+1, i+4 {

				j := src0.PixOffset(x, y)
				a := src0.Pix[j+3]
				dst.Pix[i+3] = a

				switch a {
				case 0:
					dst.Pix[i+0] = 0
					dst.Pix[i+1] = 0
					dst.Pix[i+2] = 0
				case 0xff:
					dst.Pix[i+0] = src0.Pix[j+0]
					dst.Pix[i+1] = src0.Pix[j+1]
					dst.Pix[i+2] = src0.Pix[j+2]
				default:
					dst.Pix[i+0] = uint8(uint16(src0.Pix[j+0]) * 0xff / uint16(a))
					dst.Pix[i+1] = uint8(uint16(src0.Pix[j+1]) * 0xff / uint16(a))
					dst.Pix[i+2] = uint8(uint16(src0.Pix[j+2]) * 0xff / uint16(a))
				}
			}
		}

	case *image.RGBA64:
		i0 := dst.PixOffset(dstMinX, dstMinY)
		for y := srcMinY; y < srcMaxY; y, i0 = y+1, i0+dst.Stride {
			for x, i := srcMinX, i0; x < srcMaxX; x, i = x+1, i+4 {

				j := src0.PixOffset(x, y)
				a := src0.Pix[j+6]
				dst.Pix[i+3] = a

				switch a {
				case 0:
					dst.Pix[i+0] = 0
					dst.Pix[i+1] = 0
					dst.Pix[i+2] = 0
				case 0xff:
					dst.Pix[i+0] = src0.Pix[j+0]
					dst.Pix[i+1] = src0.Pix[j+2]
					dst.Pix[i+2] = src0.Pix[j+4]
				default:
					dst.Pix[i+0] = uint8(uint16(src0.Pix[j+0]) * 0xff / uint16(a))
					dst.Pix[i+1] = uint8(uint16(src0.Pix[j+2]) * 0xff / uint16(a))
					dst.Pix[i+2] = uint8(uint16(src0.Pix[j+4]) * 0xff / uint16(a))
				}
			}
		}

	case *image.Gray:
		i0 := dst.PixOffset(dstMinX, dstMinY)
		for y := srcMinY; y < srcMaxY; y, i0 = y+1, i0+dst.Stride {
			for x, i := srcMinX, i0; x < srcMaxX; x, i = x+1, i+4 {

				j := src0.PixOffset(x, y)
				c := src0.Pix[j]
				dst.Pix[i+0] = c
				dst.Pix[i+1] = c
				dst.Pix[i+2] = c
				dst.Pix[i+3] = 0xff

			}
		}

	case *image.Gray16:
		i0 := dst.PixOffset(dstMinX, dstMinY)
		for y := srcMinY; y < srcMaxY; y, i0 = y+1, i0+dst.Stride {
			for x, i := srcMinX, i0; x < srcMaxX; x, i = x+1, i+4 {

				j := src0.PixOffset(x, y)
				c := src0.Pix[j]
				dst.Pix[i+0] = c
				dst.Pix[i+1] = c
				dst.Pix[i+2] = c
				dst.Pix[i+3] = 0xff

			}
		}

	case *image.YCbCr:
		i0 := dst.PixOffset(dstMinX, dstMinY)
		for y := srcMinY; y < srcMaxY; y, i0 = y+1, i0+dst.Stride {
			for x, i := srcMinX, i0; x < srcMaxX; x, i = x+1, i+4 {

				yj := src0.YOffset(x, y)
				cj := src0.COffset(x, y)
				r, g, b := color.YCbCrToRGB(src0.Y[yj], src0.Cb[cj], src0.Cr[cj])

				dst.Pix[i+0] = r
				dst.Pix[i+1] = g
				dst.Pix[i+2] = b
				dst.Pix[i+3] = 0xff

			}
		}

	default:
		i0 := dst.PixOffset(dstMinX, dstMinY)
		for y := srcMinY; y < srcMaxY; y, i0 = y+1, i0+dst.Stride {
			for x, i := srcMinX, i0; x < srcMaxX; x, i = x+1, i+4 {

				c := color.NRGBAModel.Convert(src.At(x, y)).(color.NRGBA)

				dst.Pix[i+0] = c.R
				dst.Pix[i+1] = c.G
				dst.Pix[i+2] = c.B
				dst.Pix[i+3] = c.A

			}
		}
	}

	return dst
}

// read a image return a image matrix
func Read(filepath string)(imgMatrix [][][]uint8 , err error){
	img,decodeErr:=DecodeImage(filepath)
	if decodeErr!=nil{
		err = decodeErr
		return
	}

	bounds:=img.Bounds()
	width:=bounds.Max.X  //width
	height:=bounds.Max.Y  //height

	src:=convertToNRGBA(img)
	imgMatrix = NewRGBAMatrix(height,width)

	for i:=0;i<height;i++{
		for j:=0;j<width;j++{
			c:=src.At(j,i)
			r,g,b,a:=c.RGBA()
			imgMatrix[i][j][0]=uint8(r)
			imgMatrix[i][j][1]=uint8(g)
			imgMatrix[i][j][2]=uint8(b)
			imgMatrix[i][j][3]=uint8(a)

		}
	}
	return
}

// read a image return a image matrix , if appear an error it will panic
func MustRead(filepath string)(imgMatrix [][][]uint8){
	img,decodeErr:=DecodeImage(filepath)
	if decodeErr!=nil{
		panic(decodeErr)
	}

	bounds:=img.Bounds()
	width:=bounds.Max.X
	height:=bounds.Max.Y

	src:=convertToNRGBA(img)
	imgMatrix = NewRGBAMatrix(height,width)

	for i:=0;i<height;i++{
		for j:=0;j<width;j++{
			c:=src.At(j,i)
			r,g,b,a:=c.RGBA()
			imgMatrix[i][j][0]=uint8(r)
			imgMatrix[i][j][1]=uint8(g)
			imgMatrix[i][j][2]=uint8(b)
			imgMatrix[i][j][3]=uint8(a)

		}
	}
	return
}

// save a image matrix as a png , if unsuccessful it will return a error
func SaveAsPNG(filepath string , imgMatrix [][][]uint8) error {
	height:=len(imgMatrix)
	width:=len(imgMatrix[0])

	if height == 0 || width == 0 {
		return errors.New("The input of matrix is illegal!")
	}

	nrgba:=image.NewNRGBA(image.Rect(0,0,width,height))

	for i:=0;i<height;i++{
		for j:=0;j<width;j++{
			nrgba.SetNRGBA(j,i,color.NRGBA{imgMatrix[i][j][0],imgMatrix[i][j][1],imgMatrix[i][j][2],imgMatrix[i][j][3]})
		}
	}
	outfile, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer outfile.Close()

	png.Encode(outfile,nrgba)

	return nil
}

// save a image matrix as a jpeg , if unsuccessful it will return a error
func SaveAsJPEG(filepath string , imgMatrix [][][]uint8) error {
	height:=len(imgMatrix)
	width:=len(imgMatrix[0])

	if height == 0 || width == 0 {
		return errors.New("The input of matrix is illegal!")
	}

	nrgba:=image.NewNRGBA(image.Rect(0,0,width,height))

	for i:=0;i<height;i++{
		for j:=0;j<width;j++{
			nrgba.SetNRGBA(j,i,color.NRGBA{imgMatrix[i][j][0],imgMatrix[i][j][1],imgMatrix[i][j][2],imgMatrix[i][j][3]})
		}
	}
	outfile, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer outfile.Close()

	jpeg.Encode(outfile,nrgba,nil)

	return nil
}<|endoftext|>


<commit_before>// Copyright 2014 Markus Dittrich. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// io contains routines for reading of data files
package main

import (
	"bufio"
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"strconv"
	"strings"
)

// name of output directory
const outputDirName = "output"

// Columns describes the content of a reaction data output file including a
// column of time values and an arbitrary number of integer data columns
type Columns struct {
	times  []float64
	counts [][]int
}

// StringColumns describes the content of a trigger data output file including a
// column of time values and an arbitrary number of string valued data columns
// NOTE: The data is kept as string values since they can contain either
// integer or float values and we have to wait with coercing them until run time
type StringColumns struct {
	times  []float64
	values [][]string
}

// loadData reads all the reaction count data in the file paths provided by dataPaths
// and either returns the individually as a list or averages them
func loadData(dataPaths []string, haveHeader, averageData bool) ([]*Columns, error) {

	var data []*Columns
	if averageData {
		cols, err := readAverageCounts(dataPaths, haveHeader)
		if err != nil {
			return nil, err
		}
		data = append(data, cols)
	} else {
		for _, dataPath := range dataPaths {
			cols, err := readCounts(dataPath, haveHeader)
			if err != nil {
				return nil, err
			}
			data = append(data, cols)
		}
	}
	return data, nil
}

// readAverageCounts parses all data in in the list of reaction data
// filenames and computes and returns the average.
//
// NOTE: this function assumes that the data files all have the same
// shape, i.e. the same number of rows and columns
//
// NOTE: the average computation is done with integer arithmetic
func readAverageCounts(fileNames []string, haveHeader bool) (*Columns, error) {

	var averageCols *Columns
	for i, fileName := range fileNames {
		col, err := readCounts(fileName, haveHeader)
		if err != nil {
			return nil, err
		}

		if i != 0 {
			for r := 0; r < len(averageCols.times); r++ {
				for c := 0; c < len(averageCols.counts); c++ {
					averageCols.counts[c][r] += col.counts[c][r]
				}
			}
		} else { // set the average to the first data set
			averageCols = col
		}
	}

	numDataSets := len(fileNames)
	for r := 0; r < len(averageCols.times); r++ {
		for c := 0; c < len(averageCols.counts); c++ {
			averageCols.counts[c][r] = averageCols.counts[c][r] / numDataSets
		}
	}
	return averageCols, nil
}

// readCounts reads in the time values and counts from the provided
// reaction data file and returns them as a Column struct
func readCounts(fileName string, haveHeader bool) (*Columns, error) {

	file, err := os.Open(fileName)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)

	// throw away header
	if haveHeader {
		scanner.Scan()
	}

	// read row by row
	var cols Columns
	for r := 0; scanner.Scan(); r++ {
		lineItems := strings.Fields(scanner.Text())

		if r == 0 {
			cols.times = make([]float64, 0)
			n := len(lineItems) - 1
			cols.counts = make([][]int, n)
			for i := 0; i < n; i++ {
				cols.counts[i] = make([]int, 0)
			}
		}

		t, err := strconv.ParseFloat(lineItems[0], 64)
		if err != nil {
			return nil, err
		}
		cols.times = append(cols.times, t)

		for i, cs := range lineItems[1:] {
			c, err := strconv.Atoi(cs)
			if err != nil {
				return nil, err
			}
			cols.counts[i] = append(cols.counts[i], c)
		}
	}

	// sanity check - we expect at least one row of data
	if len(cols.times) == 0 {
		return nil, fmt.Errorf("%s: contains no data", fileName)
	}

	return &cols, nil
}

// loadStringData reads all the reaction data columns as strings. The
// string data loader is used for analyzing trigger data since this
// typically contains a mix of integer and float data
func loadStringData(dataPaths []string, haveHeader bool) ([]*StringColumns, error) {

	var data []*StringColumns
	for _, dataPath := range dataPaths {
		cols, err := readStringCounts(dataPath, haveHeader)
		if err != nil {
			return nil, err
		}
		data = append(data, cols)
	}
	return data, nil
}

// readStringCounts reads in the time values and the rest of the column
// data (could be ints, floats) and returns them as a StringColumns struct
func readStringCounts(fileName string, haveHeader bool) (*StringColumns, error) {

	file, err := os.Open(fileName)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)

	// throw away header
	if haveHeader {
		scanner.Scan()
	}

	// read row by row
	var cols StringColumns
	for r := 0; scanner.Scan(); r++ {
		lineItems := strings.Fields(scanner.Text())

		if r == 0 {
			cols.times = make([]float64, 0)
			n := len(lineItems) - 1
			cols.values = make([][]string, n)
			for i := 0; i < n; i++ {
				cols.values[i] = make([]string, 0)
			}
		}

		t, err := strconv.ParseFloat(lineItems[0], 64)
		if err != nil {
			return nil, err
		}
		cols.times = append(cols.times, t)

		for i, c := range lineItems[1:] {
			cols.values[i] = append(cols.values[i], c)
		}
	}

	// sanity check - we expect at least one row of data
	if len(cols.times) == 0 {
		return nil, fmt.Errorf("%s: contains no data", fileName)
	}

	return &cols, nil
}

// getDataPaths returns a list of all reaction data files names that were
// generated as part of this run (at least one but could be many for multi
// seed runs)
func getDataPaths(path, dataFile string, seed, numSeeds int) ([]string, error) {

	var dataPaths []string
	dataDir := getOutputDir(path)

	// check if data file has a single format specifier
	count := strings.Count(dataFile, "%")

	switch count {
	case 0:
		filePath := filepath.Join(dataDir, dataFile)
		dataPaths = append(dataPaths, filePath)
	case 1:
		if numSeeds == 1 {
			fileName := fmt.Sprintf(dataFile, seed)
			filePath := filepath.Join(dataDir, fileName)
			dataPaths = append(dataPaths, filePath)
		} else {
			for i := 1; i < numSeeds+1; i++ {
				fileName := fmt.Sprintf(dataFile, i)
				filePath := filepath.Join(dataDir, fileName)
				dataPaths = append(dataPaths, filePath)
			}
		}
	default:
		return nil, errors.New("datafile has too many format specifiers")
	}

	return dataPaths, nil
}

// getOutputDir returns the path in which the output for the testcase at path
// is located
func getOutputDir(testPath string) string {
	return filepath.Join(testPath, outputDirName)
}

// testFileEmpty checks that the given file exists and is empty
func testFileEmpty(filePath string) (bool, error) {
	fi, err := os.Stat(filePath)
	if err != nil {
		return false, err
	}

	if fi.Size() != 0 {
		return false, nil
	}
	return true, nil
}

// testFileNonEmpty check that the given file exists and is non-empty.
func testFileNonEmpty(testPath string) (bool, error) {
	fi, err := os.Stat(testPath)
	if err != nil {
		return false, err
	}

	if fi.Size() == 0 {
		return false, nil
	}
	return true, nil
}

// testFileExists checks that the given file exists
func testFileExists(testPath string) (bool, error) {
	_, err := os.Stat(testPath)
	if err != nil {
		return false, nil
	}
	return true, nil
}

// testFileSize checks that the given file exists and has the requested
// file size
func testFileSize(testPath string, size int64) (bool, error) {
	fi, err := os.Stat(testPath)
	if err != nil {
		return false, err
	}

	if fi.Size() != size {
		return false, nil
	}
	return true, nil
}

// testNoFile checks that there is no file at the given path
func testNoFile(testPath string) (bool, error) {
	if _, err := os.Stat(testPath); os.IsNotExist(err) {
		return true, nil
	}
	return false, nil
}

// isSymLink checkes that the given path exists, is a symlink and points to
// the provided file.
func testFileSymLink(destFilePath, filePath string) (bool, error) {
	//fi, err := os.Lstat(filePath)
	//if err != nil {
	//	return false, err
	//}

	targetPath, err := os.Readlink(filePath)
	if err != nil {
		return false, err
	}
	if targetPath != destFilePath {
		return false, nil
	}
	return true, nil
}
<commit_msg>Small code cleanup.<commit_after>// Copyright 2014 Markus Dittrich. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
//
// io contains routines for reading of data files
package main

import (
	"bufio"
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"strconv"
	"strings"
)

// name of output directory
const outputDirName = "output"

// Columns describes the content of a reaction data output file including a
// column of time values and an arbitrary number of integer data columns
type Columns struct {
	times  []float64
	counts [][]int
}

// StringColumns describes the content of a trigger data output file including a
// column of time values and an arbitrary number of string valued data columns
// NOTE: The data is kept as string values since they can contain either
// integer or float values and we have to wait with coercing them until run time
type StringColumns struct {
	times  []float64
	values [][]string
}

// loadData reads all the reaction count data in the file paths provided by dataPaths
// and either returns the individually as a list or averages them
func loadData(dataPaths []string, haveHeader, averageData bool) ([]*Columns, error) {

	var data []*Columns
	if averageData {
		cols, err := readAverageCounts(dataPaths, haveHeader)
		if err != nil {
			return nil, err
		}
		data = append(data, cols)
	} else {
		for _, dataPath := range dataPaths {
			cols, err := readCounts(dataPath, haveHeader)
			if err != nil {
				return nil, err
			}
			data = append(data, cols)
		}
	}
	return data, nil
}

// readAverageCounts parses all data in in the list of reaction data
// filenames and computes and returns the average.
//
// NOTE: this function assumes that the data files all have the same
// shape, i.e. the same number of rows and columns
//
// NOTE: the average computation is done with integer arithmetic
func readAverageCounts(fileNames []string, haveHeader bool) (*Columns, error) {

	var averageCols *Columns
	for i, fileName := range fileNames {
		col, err := readCounts(fileName, haveHeader)
		if err != nil {
			return nil, err
		}

		if i != 0 {
			for r := 0; r < len(averageCols.times); r++ {
				for c := 0; c < len(averageCols.counts); c++ {
					averageCols.counts[c][r] += col.counts[c][r]
				}
			}
		} else { // set the average to the first data set
			averageCols = col
		}
	}

	numDataSets := len(fileNames)
	for r := 0; r < len(averageCols.times); r++ {
		for c := 0; c < len(averageCols.counts); c++ {
			averageCols.counts[c][r] = averageCols.counts[c][r] / numDataSets
		}
	}
	return averageCols, nil
}

// readCounts reads in the time values and counts from the provided
// reaction data file and returns them as a Column struct
func readCounts(fileName string, haveHeader bool) (*Columns, error) {

	file, err := os.Open(fileName)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)

	// throw away header
	if haveHeader {
		scanner.Scan()
	}

	// read row by row
	var cols Columns
	for r := 0; scanner.Scan(); r++ {
		lineItems := strings.Fields(scanner.Text())

		if r == 0 {
			cols.times = make([]float64, 0)
			n := len(lineItems) - 1
			cols.counts = make([][]int, n)
			for i := 0; i < n; i++ {
				cols.counts[i] = make([]int, 0)
			}
		}

		t, err := strconv.ParseFloat(lineItems[0], 64)
		if err != nil {
			return nil, err
		}
		cols.times = append(cols.times, t)

		for i, cs := range lineItems[1:] {
			c, err := strconv.Atoi(cs)
			if err != nil {
				return nil, err
			}
			cols.counts[i] = append(cols.counts[i], c)
		}
	}

	// sanity check - we expect at least one row of data
	if len(cols.times) == 0 {
		return nil, fmt.Errorf("%s: contains no data", fileName)
	}

	return &cols, nil
}

// loadStringData reads all the reaction data columns as strings. The
// string data loader is used for analyzing trigger data since this
// typically contains a mix of integer and float data
func loadStringData(dataPaths []string, haveHeader bool) ([]*StringColumns, error) {

	var data []*StringColumns
	for _, dataPath := range dataPaths {
		cols, err := readStringCounts(dataPath, haveHeader)
		if err != nil {
			return nil, err
		}
		data = append(data, cols)
	}
	return data, nil
}

// readStringCounts reads in the time values and the rest of the column
// data (could be ints, floats) and returns them as a StringColumns struct
func readStringCounts(fileName string, haveHeader bool) (*StringColumns, error) {

	file, err := os.Open(fileName)
	if err != nil {
		return nil, err
	}
	defer file.Close()

	scanner := bufio.NewScanner(file)

	// throw away header
	if haveHeader {
		scanner.Scan()
	}

	// read row by row
	var cols StringColumns
	for r := 0; scanner.Scan(); r++ {
		lineItems := strings.Fields(scanner.Text())

		if r == 0 {
			cols.times = make([]float64, 0)
			n := len(lineItems) - 1
			cols.values = make([][]string, n)
			for i := 0; i < n; i++ {
				cols.values[i] = make([]string, 0)
			}
		}

		t, err := strconv.ParseFloat(lineItems[0], 64)
		if err != nil {
			return nil, err
		}
		cols.times = append(cols.times, t)

		for i, c := range lineItems[1:] {
			cols.values[i] = append(cols.values[i], c)
		}
	}

	// sanity check - we expect at least one row of data
	if len(cols.times) == 0 {
		return nil, fmt.Errorf("%s: contains no data", fileName)
	}

	return &cols, nil
}

// getDataPaths returns a list of all reaction data files names that were
// generated as part of this run (at least one but could be many for multi
// seed runs)
func getDataPaths(path, dataFile string, seed, numSeeds int) ([]string, error) {

	var dataPaths []string
	dataDir := getOutputDir(path)

	// check if data file has a single format specifier
	count := strings.Count(dataFile, "%")

	switch count {
	case 0:
		filePath := filepath.Join(dataDir, dataFile)
		dataPaths = append(dataPaths, filePath)
	case 1:
		if numSeeds == 1 {
			fileName := fmt.Sprintf(dataFile, seed)
			filePath := filepath.Join(dataDir, fileName)
			dataPaths = append(dataPaths, filePath)
		} else {
			for i := 1; i < numSeeds+1; i++ {
				fileName := fmt.Sprintf(dataFile, i)
				filePath := filepath.Join(dataDir, fileName)
				dataPaths = append(dataPaths, filePath)
			}
		}
	default:
		return nil, errors.New("datafile has too many format specifiers")
	}

	return dataPaths, nil
}

// getOutputDir returns the path in which the output for the testcase at path
// is located
func getOutputDir(testPath string) string {
	return filepath.Join(testPath, outputDirName)
}

// testFileEmpty checks that the given file exists and is empty
func testFileEmpty(filePath string) (bool, error) {
	fi, err := os.Stat(filePath)
	if err != nil {
		return false, err
	}

	if fi.Size() != 0 {
		return false, nil
	}
	return true, nil
}

// testFileNonEmpty check that the given file exists and is non-empty.
func testFileNonEmpty(testPath string) (bool, error) {
	fi, err := os.Stat(testPath)
	if err != nil {
		return false, err
	}

	if fi.Size() == 0 {
		return false, nil
	}
	return true, nil
}

// testFileExists checks that the given file exists
func testFileExists(testPath string) (bool, error) {
	_, err := os.Stat(testPath)
	if err != nil {
		return false, nil
	}
	return true, nil
}

// testFileSize checks that the given file exists and has the requested
// file size
func testFileSize(testPath string, size int64) (bool, error) {
	fi, err := os.Stat(testPath)
	if err != nil {
		return false, err
	}

	if fi.Size() != size {
		return false, nil
	}
	return true, nil
}

// testNoFile checks that there is no file at the given path
func testNoFile(testPath string) (bool, error) {
	if _, err := os.Stat(testPath); os.IsNotExist(err) {
		return true, nil
	}
	return false, nil
}

// isSymLink checkes that the given path exists, is a symlink and points to
// the provided file.
func testFileSymLink(destFilePath, filePath string) (bool, error) {
	targetPath, err := os.Readlink(filePath)
	if err != nil {
		return false, err
	}
	if targetPath != destFilePath {
		return false, nil
	}
	return true, nil
}
<|endoftext|>


<commit_before>package jq

import (
	"encoding/json"
	"time"

	log "github.com/ngaut/logging"
)

type WorkerFunc func(input []byte, ret chan<- []byte, done chan<- struct{}, err chan<- error)

type Jq struct {
	name            string
	mgr             QueueManager
	opt             JqOptions
	workerParamChan chan workerParam
	workers         []*workerWrapper
	waiting         chan *Job
}

type JqOptions struct {
	QueueCheckInterval time.Duration
	CocurrentWorkerNum int
}

var DefaultOpt = JqOptions{
	CocurrentWorkerNum: 10000,
	QueueCheckInterval: 100 * time.Millisecond,
}

type workerParam struct {
	job       Job
	respQueue Queue
	ret       chan []byte
	done      chan struct{}
	err       chan error
}

type workerWrapper struct {
	workerFunc WorkerFunc
	c          chan workerParam
	stop       chan struct{}
}

func (w *workerWrapper) Close() {
	close(w.c)
	w.stop <- struct{}{}
}

func (w *workerWrapper) run() {
	for {
		select {
		case param := <-w.c:
			go w.workerFunc(param.job.Data, param.ret, param.done, param.err)
			for {
				var msg Msg
				select {
				case b := <-param.ret:
					msg.Type = MSG_RET
					msg.Data = b
				case err := <-param.err:
					msg.Type = MSG_ERR
					msg.Data = []byte(err.Error())
				case <-param.done:
					msg.Type = MSG_DONE
				}
				b, _ := json.Marshal(msg)
				err := param.respQueue.Push(b)
				// this queue maybe had destroied
				if err != nil {
					log.Error(err)
					break
				}
				// finish
				if msg.Type == MSG_ERR || msg.Type == MSG_DONE {
					break
				}
			}
		case <-w.stop:
			break
		}
	}
}

func newWorkerWrapper(workerFunc WorkerFunc, paramChan chan workerParam) *workerWrapper {
	ret := &workerWrapper{
		workerFunc: workerFunc,
		c:          paramChan,
		stop:       make(chan struct{}),
	}
	go ret.run()
	return ret
}

func NewJq(name string, queueMgr QueueManager, workerFunc WorkerFunc) *Jq {
	return NewJqWithOpt(name, queueMgr, workerFunc, DefaultOpt)
}

func NewJqWithOpt(name string, queueMgr QueueManager, workerFunc WorkerFunc, opt JqOptions) *Jq {
	jq := &Jq{
		name:            name,
		mgr:             queueMgr,
		opt:             opt,
		workerParamChan: make(chan workerParam),
		waiting:         make(chan *Job),
	}

	for i := 0; i < jq.opt.CocurrentWorkerNum; i++ {
		jq.workers = append(jq.workers, newWorkerWrapper(workerFunc, jq.workerParamChan))
	}

	go jq.enqueueLoop()
	return jq
}

func (jq *Jq) enqueueLoop() {
	for job := range jq.waiting {
		q, err := jq.mgr.GetOrCreate(jq.name + "_waiting_jobs")
		if err != nil {
			panic(err)
		}
		if q != nil {
			b, _ := json.Marshal(job)
			err = q.Push(b)
			if err != nil {
				log.Error(err, "error occurred when pushing job, sleep 1s and retry")
				time.Sleep(1000 * time.Millisecond)
				continue
			}
		}
	}
}

func (jq *Jq) DispatchForever() {
	q, err := jq.mgr.GetOrCreate(jq.name + "_waiting_jobs")
	if err != nil {
		panic(err)
	}

	for {
		b, err := q.Pop()
		if err == ErrEmpty {
			time.Sleep(jq.opt.QueueCheckInterval)
			continue
		}
		if err != nil {
			log.Error(err, "error occurred when fetching job, sleep 1s and retry")
			time.Sleep(1000 * time.Millisecond)
			continue
		}
		var job Job
		err = json.Unmarshal(b, &job)
		if err != nil {
			log.Error(err)
			continue
		}

		// check response channel
		qname := jq.name + "_job_" + job.Id
		respq, err := jq.mgr.Get(qname)
		if err != nil {
			log.Warning("get return channel error, ignore this job")
			continue
		}

		// try post job to worker
		jq.workerParamChan <- workerParam{
			job:       job,
			respQueue: respq,
			err:       make(chan error),
			done:      make(chan struct{}),
			ret:       make(chan []byte),
		}
	}
}

func (jq *Jq) waitForResponse(job *Job, respQueue Queue) {
	// remove reponse channel when we are not waiting
	defer jq.mgr.Del(respQueue.Name())

	startTime := time.Now()
	timeoutCheck := true
	// check from response channel
	for {
		b, err := respQueue.Pop()
		if err == ErrEmpty {
			time.Sleep(jq.opt.QueueCheckInterval)
			// check timeout
			if timeoutCheck && job.Timeout > 0 && time.Now().Sub(startTime) > job.Timeout {
				job.onErr(ErrTimeout)
				return
			}
			continue
		}
		if err != nil {
			if job.onErr != nil {
				job.onErr(err)
			}
			return
		}

		// get response
		timeoutCheck = false
		// read response value
		var msg Msg
		err = json.Unmarshal(b, &msg)
		if err != nil {
			if job.onErr != nil {
				job.onErr(err)
			}
			return
		}

		switch msg.Type {
		case MSG_RET:
			if job.onRet != nil {
				job.onRet(msg.Data)
			}
		case MSG_DONE:
			return
		case MSG_ERR:
			if job.onErr != nil {
				job.onErr(err)
			}
			return
		}
	}
}

func (jq *Jq) SubmitWithTimeout(data []byte, timeout time.Duration, onRet func([]byte), onErr func(error), sync bool) {
	job := &Job{
		Id:      genId(),
		Data:    data,
		Timeout: timeout,
		onRet:   onRet,
		onErr:   onErr,
	}

	// create response channel
	retQueueName := jq.name + "_job_" + job.Id
	q, err := jq.mgr.GetOrCreate(retQueueName)
	if err != nil {
		if job.onErr != nil {
			job.onErr(err)
		}
		return
	}

	// post job
	jq.waiting <- job

	// wait for response
	if sync {
		jq.waitForResponse(job, q)
	} else {
		go jq.waitForResponse(job, q)
	}
}

func (jq *Jq) Submit(data []byte, onRet func([]byte), onErr func(error), sync bool) {
	jq.SubmitWithTimeout(data, 0, onRet, onErr, sync)
}
<commit_msg>add help constructure<commit_after>package jq

import (
	"encoding/json"
	"time"

	log "github.com/ngaut/logging"
)

type WorkerFunc func(input []byte, ret chan<- []byte, done chan<- struct{}, err chan<- error)

type Jq struct {
	name            string
	mgr             QueueManager
	opt             JqOptions
	workerParamChan chan workerParam
	workers         []*workerWrapper
	waiting         chan *Job
}

type JqOptions struct {
	QueueCheckInterval time.Duration
	CocurrentWorkerNum int
}

var DefaultOpt = JqOptions{
	CocurrentWorkerNum: 10000,
	QueueCheckInterval: 100 * time.Millisecond,
}

type workerParam struct {
	job       Job
	respQueue Queue
	ret       chan []byte
	done      chan struct{}
	err       chan error
}

type workerWrapper struct {
	workerFunc WorkerFunc
	c          chan workerParam
	stop       chan struct{}
}

func (w *workerWrapper) Close() {
	close(w.c)
	w.stop <- struct{}{}
}

func (w *workerWrapper) run() {
	for {
		select {
		case param := <-w.c:
			go w.workerFunc(param.job.Data, param.ret, param.done, param.err)
			for {
				var msg Msg
				select {
				case b := <-param.ret:
					msg.Type = MSG_RET
					msg.Data = b
				case err := <-param.err:
					msg.Type = MSG_ERR
					msg.Data = []byte(err.Error())
				case <-param.done:
					msg.Type = MSG_DONE
				}
				b, _ := json.Marshal(msg)
				err := param.respQueue.Push(b)
				// this queue maybe had destroied
				if err != nil {
					log.Error(err)
					break
				}
				// finish
				if msg.Type == MSG_ERR || msg.Type == MSG_DONE {
					break
				}
			}
		case <-w.stop:
			break
		}
	}
}

func newWorkerWrapper(workerFunc WorkerFunc, paramChan chan workerParam) *workerWrapper {
	ret := &workerWrapper{
		workerFunc: workerFunc,
		c:          paramChan,
		stop:       make(chan struct{}),
	}
	go ret.run()
	return ret
}

func NewJq(name string, queueMgr QueueManager, workerFunc WorkerFunc) *Jq {
	return NewJqWithOpt(name, queueMgr, workerFunc, DefaultOpt)
}

func NewMemJq(name string, workerFunc WorkerFunc) *Jq {
	return NewJqWithOpt(name, MemQueueManagerFactory(MemQFactory), workerFunc, DefaultOpt)
}

func NewJqWithOpt(name string, queueMgr QueueManager, workerFunc WorkerFunc, opt JqOptions) *Jq {
	jq := &Jq{
		name:            name,
		mgr:             queueMgr,
		opt:             opt,
		workerParamChan: make(chan workerParam),
		waiting:         make(chan *Job),
	}

	for i := 0; i < jq.opt.CocurrentWorkerNum; i++ {
		jq.workers = append(jq.workers, newWorkerWrapper(workerFunc, jq.workerParamChan))
	}

	go jq.enqueueLoop()
	return jq
}

func (jq *Jq) enqueueLoop() {
	for job := range jq.waiting {
		q, err := jq.mgr.GetOrCreate(jq.name + "_waiting_jobs")
		if err != nil {
			panic(err)
		}
		if q != nil {
			b, _ := json.Marshal(job)
			err = q.Push(b)
			if err != nil {
				log.Error(err, "error occurred when pushing job, sleep 1s and retry")
				time.Sleep(1000 * time.Millisecond)
				continue
			}
		}
	}
}

func (jq *Jq) DispatchForever() {
	q, err := jq.mgr.GetOrCreate(jq.name + "_waiting_jobs")
	if err != nil {
		panic(err)
	}

	for {
		b, err := q.Pop()
		if err == ErrEmpty {
			time.Sleep(jq.opt.QueueCheckInterval)
			continue
		}
		if err != nil {
			log.Error(err, "error occurred when fetching job, sleep 1s and retry")
			time.Sleep(1000 * time.Millisecond)
			continue
		}
		var job Job
		err = json.Unmarshal(b, &job)
		if err != nil {
			log.Error(err)
			continue
		}

		// check response channel
		qname := jq.name + "_job_" + job.Id
		respq, err := jq.mgr.Get(qname)
		if err != nil {
			log.Warning("get return channel error, ignore this job")
			continue
		}

		// try post job to worker
		jq.workerParamChan <- workerParam{
			job:       job,
			respQueue: respq,
			err:       make(chan error),
			done:      make(chan struct{}),
			ret:       make(chan []byte),
		}
	}
}

func (jq *Jq) waitForResponse(job *Job, respQueue Queue) {
	// remove reponse channel when we are not waiting
	defer jq.mgr.Del(respQueue.Name())

	startTime := time.Now()
	timeoutCheck := true
	// check from response channel
	for {
		b, err := respQueue.Pop()
		if err == ErrEmpty {
			time.Sleep(jq.opt.QueueCheckInterval)
			// check timeout
			if timeoutCheck && job.Timeout > 0 && time.Now().Sub(startTime) > job.Timeout {
				job.onErr(ErrTimeout)
				return
			}
			continue
		}
		if err != nil {
			if job.onErr != nil {
				job.onErr(err)
			}
			return
		}

		// get response
		timeoutCheck = false
		// read response value
		var msg Msg
		err = json.Unmarshal(b, &msg)
		if err != nil {
			if job.onErr != nil {
				job.onErr(err)
			}
			return
		}

		switch msg.Type {
		case MSG_RET:
			if job.onRet != nil {
				job.onRet(msg.Data)
			}
		case MSG_DONE:
			return
		case MSG_ERR:
			if job.onErr != nil {
				job.onErr(err)
			}
			return
		}
	}
}

func (jq *Jq) SubmitWithTimeout(data []byte, timeout time.Duration, onRet func([]byte), onErr func(error), sync bool) {
	job := &Job{
		Id:      genId(),
		Data:    data,
		Timeout: timeout,
		onRet:   onRet,
		onErr:   onErr,
	}

	// create response channel
	retQueueName := jq.name + "_job_" + job.Id
	q, err := jq.mgr.GetOrCreate(retQueueName)
	if err != nil {
		if job.onErr != nil {
			job.onErr(err)
		}
		return
	}

	// post job
	jq.waiting <- job

	// wait for response
	if sync {
		jq.waitForResponse(job, q)
	} else {
		go jq.waitForResponse(job, q)
	}
}

func (jq *Jq) Submit(data []byte, onRet func([]byte), onErr func(error), sync bool) {
	jq.SubmitWithTimeout(data, 0, onRet, onErr, sync)
}
<|endoftext|>


<commit_before>package conntrack

import (
	"fmt"
	"io"
	"sync"
	"text/tabwriter"
	"time"
)

type reason = string

type Instance struct {
	maxEntries int
	Timeout    func(Entry) time.Duration

	mu              sync.Mutex
	entries         map[Entry]handles
	waitersByReason map[reason]handles
	waitersByEntry  map[Entry][]*EntryHandle
}

type handles = map[*EntryHandle]struct{}

func NewInstance() *Instance {
	i := &Instance{
		maxEntries: 200,
		Timeout: func(e Entry) time.Duration {
			// udp is the main offender, and the default is allegedly 30s.
			return 30 * time.Second
		},
		entries:         make(map[Entry]handles),
		waitersByReason: make(map[reason]handles),
		waitersByEntry:  make(map[Entry][]*EntryHandle),
	}
	return i
}

func (i *Instance) SetMaxEntries(max int) {
	i.mu.Lock()
	defer i.mu.Unlock()
	prev := i.maxEntries
	i.maxEntries = max
	for j := prev; j < max; j++ {
		i.wakeAny()
	}
}

func (i *Instance) remove(eh *EntryHandle) {
	i.mu.Lock()
	defer i.mu.Unlock()
	hs := i.entries[eh.e]
	delete(hs, eh)
	if len(hs) == 0 {
		delete(i.entries, eh.e)
		i.wakeWaiter(eh.reason)
	}
}

func (i *Instance) chooseWakeReason(avoid reason) reason {
	for k := range i.waitersByReason {
		if k == avoid {
			continue
		}
		return k
	}
	return avoid
}

func (i *Instance) wakeWaiter(avoid reason) {
	r := i.chooseWakeReason(avoid)
	i.wakeReason(r)
}

func (i *Instance) wakeAny() {
	for r := range i.waitersByReason {
		i.wakeReason(r)
		break
	}
}

func (i *Instance) wakeReason(r reason) {
	for k := range i.waitersByReason[r] {
		i.wakeEntry(k.e)
		break
	}
}

func (i *Instance) wakeEntry(e Entry) {
	i.entries[e] = make(handles)
	for _, eh := range i.waitersByEntry[e] {
		i.entries[e][eh] = struct{}{}
		delete(i.waitersByReason[eh.reason], eh)
		eh.added.Unlock()
	}
	delete(i.waitersByEntry, e)
}

func (i *Instance) Wait(e Entry, reason string) (eh *EntryHandle) {
	eh = &EntryHandle{
		reason: reason,
		e:      e,
		i:      i,
	}
	i.mu.Lock()
	hs, ok := i.entries[eh.e]
	if ok {
		hs[eh] = struct{}{}
		i.mu.Unlock()
		return
	}
	if len(i.entries) < i.maxEntries {
		i.entries[eh.e] = handles{
			eh: struct{}{},
		}
		i.mu.Unlock()
		return
	}
	eh.added.Lock()
	if i.waitersByReason[reason] == nil {
		i.waitersByReason[reason] = make(handles)
	}
	i.waitersByReason[reason][eh] = struct{}{}
	i.waitersByEntry[e] = append(i.waitersByEntry[e], eh)
	i.mu.Unlock()
	eh.added.Lock()
	return
}

func (i *Instance) PrintStatus(w io.Writer) {
	tw := tabwriter.NewWriter(w, 0, 0, 2, ' ', 0)
	i.mu.Lock()
	fmt.Fprintf(w, "num entries: %d\n", len(i.entries))
	fmt.Fprintln(w)
	fmt.Fprintln(w, "waiters:")
	fmt.Fprintf(tw, "num\treason\n")
	for r, ws := range i.waitersByReason {
		fmt.Fprintf(tw, "%d\t%q\n", len(ws), r)
	}
	tw.Flush()
	fmt.Fprintln(w)
	fmt.Fprintln(w, "handles:")
	fmt.Fprintf(tw, "protocol\tlocal\tremote\treason\texpires\n")
	for e, hs := range i.entries {
		for h := range hs {
			fmt.Fprintf(tw,
				"%q\t%q\t%q\t%q\t%s\n",
				e.Protocol, e.LocalAddr, e.RemoteAddr, h.reason,
				func() interface{} {
					if h.expires.IsZero() {
						return "not done"
					} else {
						return time.Until(h.expires)
					}
				}(),
			)
		}
	}
	i.mu.Unlock()
	tw.Flush()
}
<commit_msg>conntrack: Fix spurious wake ups on empty reason wait lists<commit_after>package conntrack

import (
	"fmt"
	"io"
	"sync"
	"text/tabwriter"
	"time"
)

type reason = string

type Instance struct {
	maxEntries int
	Timeout    func(Entry) time.Duration

	mu              sync.Mutex
	entries         map[Entry]handles
	waitersByReason map[reason]handles
	waitersByEntry  map[Entry][]*EntryHandle
}

type handles = map[*EntryHandle]struct{}

func NewInstance() *Instance {
	i := &Instance{
		maxEntries: 200,
		Timeout: func(e Entry) time.Duration {
			// udp is the main offender, and the default is allegedly 30s.
			return 30 * time.Second
		},
		entries:         make(map[Entry]handles),
		waitersByReason: make(map[reason]handles),
		waitersByEntry:  make(map[Entry][]*EntryHandle),
	}
	return i
}

func (i *Instance) SetMaxEntries(max int) {
	i.mu.Lock()
	defer i.mu.Unlock()
	prev := i.maxEntries
	i.maxEntries = max
	for j := prev; j < max; j++ {
		i.wakeAny()
	}
}

func (i *Instance) remove(eh *EntryHandle) {
	i.mu.Lock()
	defer i.mu.Unlock()
	hs := i.entries[eh.e]
	delete(hs, eh)
	if len(hs) == 0 {
		delete(i.entries, eh.e)
		i.wakeWaiter(eh.reason)
	}
}

func (i *Instance) chooseWakeReason(avoid reason) reason {
	for k := range i.waitersByReason {
		if k == avoid {
			continue
		}
		return k
	}
	return avoid
}

func (i *Instance) wakeWaiter(avoid reason) {
	r := i.chooseWakeReason(avoid)
	i.wakeReason(r)
}

func (i *Instance) wakeAny() {
	for r := range i.waitersByReason {
		i.wakeReason(r)
		break
	}
}

func (i *Instance) wakeReason(r reason) {
	for k := range i.waitersByReason[r] {
		i.wakeEntry(k.e)
		break
	}
}

func (i *Instance) wakeEntry(e Entry) {
	i.entries[e] = make(handles)
	for _, eh := range i.waitersByEntry[e] {
		i.entries[e][eh] = struct{}{}
		delete(i.waitersByReason[eh.reason], eh)
		if len(i.waitersByReason[eh.reason]) == 0 {
			delete(i.waitersByReason, eh.reason)
		}
		eh.added.Unlock()
	}
	delete(i.waitersByEntry, e)
}

func (i *Instance) Wait(e Entry, reason string) (eh *EntryHandle) {
	eh = &EntryHandle{
		reason: reason,
		e:      e,
		i:      i,
	}
	i.mu.Lock()
	hs, ok := i.entries[eh.e]
	if ok {
		hs[eh] = struct{}{}
		i.mu.Unlock()
		return
	}
	if len(i.entries) < i.maxEntries {
		i.entries[eh.e] = handles{
			eh: struct{}{},
		}
		i.mu.Unlock()
		return
	}
	eh.added.Lock()
	if i.waitersByReason[reason] == nil {
		i.waitersByReason[reason] = make(handles)
	}
	i.waitersByReason[reason][eh] = struct{}{}
	i.waitersByEntry[e] = append(i.waitersByEntry[e], eh)
	i.mu.Unlock()
	eh.added.Lock()
	return
}

func (i *Instance) PrintStatus(w io.Writer) {
	tw := tabwriter.NewWriter(w, 0, 0, 2, ' ', 0)
	i.mu.Lock()
	fmt.Fprintf(w, "num entries: %d\n", len(i.entries))
	fmt.Fprintln(w)
	fmt.Fprintln(w, "waiters:")
	fmt.Fprintf(tw, "num\treason\n")
	for r, ws := range i.waitersByReason {
		fmt.Fprintf(tw, "%d\t%q\n", len(ws), r)
	}
	tw.Flush()
	fmt.Fprintln(w)
	fmt.Fprintln(w, "handles:")
	fmt.Fprintf(tw, "protocol\tlocal\tremote\treason\texpires\n")
	for e, hs := range i.entries {
		for h := range hs {
			fmt.Fprintf(tw,
				"%q\t%q\t%q\t%q\t%s\n",
				e.Protocol, e.LocalAddr, e.RemoteAddr, h.reason,
				func() interface{} {
					if h.expires.IsZero() {
						return "not done"
					} else {
						return time.Until(h.expires)
					}
				}(),
			)
		}
	}
	i.mu.Unlock()
	tw.Flush()
}
<|endoftext|>


<commit_before>package osc

import (
	"bufio"
	"bytes"
	"log"
	"net"
	"os"
	"sync"
	"testing"
	"time"

	"golang.org/x/net/context"
)

func TestAppendArguments(t *testing.T) {
	oscAddress := "/address"
	message := NewMessage(oscAddress)
	if message.Address != oscAddress {
		t.Errorf("OSC address should be \"%s\" and is \"%s\"", oscAddress, message.Address)
	}

	message.Append("string argument")
	message.Append(123456789)
	message.Append(true)

	if message.CountArguments() != 3 {
		t.Errorf("Number of arguments should be %d and is %d", 3, message.CountArguments())
	}
}

func TestEqualMessage(t *testing.T) {
	msg1 := NewMessage("/address")
	msg2 := NewMessage("/address")

	msg1.Append(1234)
	msg2.Append(1234)
	msg1.Append("test string")
	msg2.Append("test string")

	if !msg1.Equals(msg2) {
		t.Error("Messages should be equal")
	}
}

func TestHandle(t *testing.T) {
	server := &Server{Addr: "localhost:6677"}
	err := server.Handle("/address/test", func(msg *Message) {})
	if err != nil {
		t.Error("Expected that OSC address '/address/test' is valid")
	}
}

func TestHandleWithInvalidAddress(t *testing.T) {
	server := &Server{Addr: "localhost:6677"}
	err := server.Handle("/address*/test", func(msg *Message) {})
	if err == nil {
		t.Error("Expected error with '/address*/test'")
	}
}

func TestServerMessageDispatching(t *testing.T) {
	finish := make(chan bool)
	start := make(chan bool)
	done := sync.WaitGroup{}
	done.Add(2)

	// Start the OSC server in a new go-routine
	go func() {
		conn, err := net.ListenPacket("udp", "localhost:6677")
		if err != nil {
			t.Fatal(err)
		}
		defer conn.Close()

		server := &Server{Addr: "localhost:6677"}
		err = server.Handle("/address/test", func(msg *Message) {
			if len(msg.Arguments) != 1 {
				t.Error("Argument length should be 1 and is: " + string(len(msg.Arguments)))
			}

			if msg.Arguments[0].(int32) != 1122 {
				t.Error("Argument should be 1122 and is: " + string(msg.Arguments[0].(int32)))
			}

			// Stop OSC server
			conn.Close()
			finish <- true
		})
		if err != nil {
			t.Error("Error adding message handler")
		}

		start <- true
		server.Serve(context.Background(), conn)
	}()

	go func() {
		timeout := time.After(5 * time.Second)
		select {
		case <-timeout:
		case <-start:
			time.Sleep(500 * time.Millisecond)
			client := NewClient("localhost", 6677)
			msg := NewMessage("/address/test")
			msg.Append(int32(1122))
			client.Send(msg)
		}

		done.Done()

		select {
		case <-timeout:
		case <-finish:
		}
		done.Done()
	}()

	done.Wait()
}

func TestServerMessageReceiving(t *testing.T) {
	finish := make(chan bool)
	start := make(chan bool)
	done := sync.WaitGroup{}
	done.Add(2)

	// Start the server in a go-routine
	go func() {
		server := &Server{}
		c, err := net.ListenPacket("udp", "localhost:6677")
		if err != nil {
			t.Fatal(err)
		}
		defer c.Close()

		// Start the client
		start <- true
		packet, addr, err := server.ReceivePacket(context.Background(), c)
		if err != nil {
			t.Error("Server error")
			return
		}
		if packet == nil {
			t.Error("nil packet")
			return
		}
		msg := packet.(*Message)
		if msg.CountArguments() != 2 {
			t.Errorf("Argument length should be 2 and is: %d\n", msg.CountArguments())
		}
		if msg.Arguments[0].(int32) != 1122 {
			t.Error("Argument should be 1122 and is: " + string(msg.Arguments[0].(int32)))
		}
		if msg.Arguments[1].(int32) != 3344 {
			t.Error("Argument should be 3344 and is: " + string(msg.Arguments[1].(int32)))
		}

		if addr == nil {
			t.Error("addr was empty")
		}

		c.Close()
		finish <- true
	}()

	go func() {
		timeout := time.After(5 * time.Second)
		select {
		case <-timeout:
		case <-start:
			client := NewClient("localhost", 6677)
			msg := NewMessage("/address/test")
			msg.Append(int32(1122))
			msg.Append(int32(3344))
			time.Sleep(500 * time.Millisecond)
			client.Send(msg)
		}

		done.Done()

		select {
		case <-timeout:
		case <-finish:
		}
		done.Done()
	}()

	done.Wait()
}

func TestReadTimeout(t *testing.T) {
	start := make(chan bool)
	wg := sync.WaitGroup{}
	wg.Add(2)

	go func() {
		defer wg.Done()

		select {
		case <-time.After(5 * time.Second):
			t.Fatal("timed out")
		case <-start:
			client := NewClient("localhost", 6677)
			msg := NewMessage("/address/test1")
			err := client.Send(msg)
			if err != nil {
				t.Fatal(err)
			}
			time.Sleep(150 * time.Millisecond)
			msg = NewMessage("/address/test2")
			err = client.Send(msg)
			if err != nil {
				t.Fatal(err)
			}
		}
	}()

	go func() {
		defer wg.Done()

		var ctx context.Context
		timeout := 100 * time.Millisecond

		server := &Server{}
		c, err := net.ListenPacket("udp", "localhost:6677")
		if err != nil {
			t.Fatal(err)
		}
		defer c.Close()

		start <- true
		ctx, _ = context.WithTimeout(context.Background(), timeout)
		p, addr, err := server.ReceivePacket(ctx, c)
		if err != nil {
			t.Errorf("Server error: %v", err)
			return
		}
		if got, want := p.(*Message).Address, "/address/test1"; got != want {
			t.Errorf("Wrong address; got = %s want = %s", got, want)
		}
		if addr == nil {
			t.Errorf("Addr was nil")
		}

		// Second receive should time out since client is delayed 150 milliseconds
		ctx, _ = context.WithTimeout(context.Background(), timeout)
		if _, _, err = server.ReceivePacket(ctx, c); err == nil {
			t.Errorf("Expected error")
			return
		}

		// Next receive should get it
		ctx, _ = context.WithTimeout(context.Background(), timeout)
		p, addr, err = server.ReceivePacket(ctx, c)
		if err != nil {
			t.Errorf("Server error: %v", err)
			return
		}
		if got, want := p.(*Message).Address, "/address/test2"; got != want {
			t.Errorf("Wrong address; got = %s, want = %s", got, want)
		}
		if addr == nil {
			t.Errorf("Addr was nil")
		}
	}()

	wg.Wait()
}

func TestReadPaddedString(t *testing.T) {
	buf1 := []byte{'t', 'e', 's', 't', 's', 't', 'r', 'i', 'n', 'g', 0, 0}
	buf2 := []byte{'t', 'e', 's', 't', 0, 0, 0, 0}

	bytesBuffer := bytes.NewBuffer(buf1)
	st, n, err := readPaddedString(bufio.NewReader(bytesBuffer))
	if err != nil {
		t.Error("Error reading padded string: " + err.Error())
	}

	if n != 12 {
		t.Errorf("Number of bytes needs to be 12 and is: %d\n", n)
	}

	if st != "teststring" {
		t.Errorf("String should be \"teststring\" and is \"%s\"", st)
	}

	bytesBuffer = bytes.NewBuffer(buf2)
	st, n, err = readPaddedString(bufio.NewReader(bytesBuffer))
	if err != nil {
		t.Error("Error reading padded string: " + err.Error())
	}

	if n != 8 {
		t.Errorf("Number of bytes needs to be 8 and is: %d\n", n)
	}

	if st != "test" {
		t.Errorf("String should be \"test\" and is \"%s\"", st)
	}
}

func TestWritePaddedString(t *testing.T) {
	buf := []byte{}
	bytesBuffer := bytes.NewBuffer(buf)
	testString := "testString"
	expectedNumberOfWrittenBytes := len(testString) + padBytesNeeded(len(testString))

	n, err := writePaddedString(testString, bytesBuffer)
	if err != nil {
		t.Errorf(err.Error())
	}

	if n != expectedNumberOfWrittenBytes {
		t.Errorf("Expected number of written bytes should be \"%d\" and is \"%d\"", expectedNumberOfWrittenBytes, n)
	}
}

func TestPadBytesNeeded(t *testing.T) {
	var n int
	n = padBytesNeeded(4)
	if n != 4 {
		t.Errorf("Number of pad bytes should be 4 and is: %d", n)
	}

	n = padBytesNeeded(3)
	if n != 1 {
		t.Errorf("Number of pad bytes should be 1 and is: %d", n)
	}

	n = padBytesNeeded(1)
	if n != 3 {
		t.Errorf("Number of pad bytes should be 3 and is: %d", n)
	}

	n = padBytesNeeded(0)
	if n != 4 {
		t.Errorf("Number of pad bytes should be 4 and is: %d", n)
	}

	n = padBytesNeeded(32)
	if n != 4 {
		t.Errorf("Number of pad bytes should be 4 and is: %d", n)
	}

	n = padBytesNeeded(63)
	if n != 1 {
		t.Errorf("Number of pad bytes should be 1 and is: %d", n)
	}

	n = padBytesNeeded(10)
	if n != 2 {
		t.Errorf("Number of pad bytes should be 2 and is: %d", n)
	}
}

func TestTypeTagsString(t *testing.T) {
	msg := NewMessage("/some/address")
	msg.Append(int32(100))
	msg.Append(true)
	msg.Append(false)

	typeTags, err := msg.TypeTags()
	if err != nil {
		t.Error(err.Error())
	}

	if typeTags != ",iTF" {
		t.Errorf("Type tag string should be ',iTF' and is: %s", typeTags)
	}
}

func TestClientSetLocalAddr(t *testing.T) {
	client := NewClient("localhost", 8967)
	err := client.SetLocalAddr("localhost", 41789)
	if err != nil {
		t.Error(err.Error())
	}
	expectedAddr := "127.0.0.1:41789"
	if client.laddr.String() != expectedAddr {
		t.Errorf("Expected laddr to be %s but was %s", expectedAddr, client.laddr.String())
	}
}

func TestMain(m *testing.M) {
	log.SetFlags(log.Flags() | log.Lshortfile)
	os.Exit(m.Run())
}
<commit_msg>add unit test for ParsePacket<commit_after>package osc

import (
	"bufio"
	"bytes"
	"log"
	"net"
	"os"
	"reflect"
	"sync"
	"testing"
	"time"

	"golang.org/x/net/context"
)

func TestAppendArguments(t *testing.T) {
	oscAddress := "/address"
	message := NewMessage(oscAddress)
	if message.Address != oscAddress {
		t.Errorf("OSC address should be \"%s\" and is \"%s\"", oscAddress, message.Address)
	}

	message.Append("string argument")
	message.Append(123456789)
	message.Append(true)

	if message.CountArguments() != 3 {
		t.Errorf("Number of arguments should be %d and is %d", 3, message.CountArguments())
	}
}

func TestEqualMessage(t *testing.T) {
	msg1 := NewMessage("/address")
	msg2 := NewMessage("/address")

	msg1.Append(1234)
	msg2.Append(1234)
	msg1.Append("test string")
	msg2.Append("test string")

	if !msg1.Equals(msg2) {
		t.Error("Messages should be equal")
	}
}

func TestHandle(t *testing.T) {
	server := &Server{Addr: "localhost:6677"}
	err := server.Handle("/address/test", func(msg *Message) {})
	if err != nil {
		t.Error("Expected that OSC address '/address/test' is valid")
	}
}

func TestHandleWithInvalidAddress(t *testing.T) {
	server := &Server{Addr: "localhost:6677"}
	err := server.Handle("/address*/test", func(msg *Message) {})
	if err == nil {
		t.Error("Expected error with '/address*/test'")
	}
}

func TestServerMessageDispatching(t *testing.T) {
	finish := make(chan bool)
	start := make(chan bool)
	done := sync.WaitGroup{}
	done.Add(2)

	// Start the OSC server in a new go-routine
	go func() {
		conn, err := net.ListenPacket("udp", "localhost:6677")
		if err != nil {
			t.Fatal(err)
		}
		defer conn.Close()

		server := &Server{Addr: "localhost:6677"}
		err = server.Handle("/address/test", func(msg *Message) {
			if len(msg.Arguments) != 1 {
				t.Error("Argument length should be 1 and is: " + string(len(msg.Arguments)))
			}

			if msg.Arguments[0].(int32) != 1122 {
				t.Error("Argument should be 1122 and is: " + string(msg.Arguments[0].(int32)))
			}

			// Stop OSC server
			conn.Close()
			finish <- true
		})
		if err != nil {
			t.Error("Error adding message handler")
		}

		start <- true
		server.Serve(context.Background(), conn)
	}()

	go func() {
		timeout := time.After(5 * time.Second)
		select {
		case <-timeout:
		case <-start:
			time.Sleep(500 * time.Millisecond)
			client := NewClient("localhost", 6677)
			msg := NewMessage("/address/test")
			msg.Append(int32(1122))
			client.Send(msg)
		}

		done.Done()

		select {
		case <-timeout:
		case <-finish:
		}
		done.Done()
	}()

	done.Wait()
}

func TestServerMessageReceiving(t *testing.T) {
	finish := make(chan bool)
	start := make(chan bool)
	done := sync.WaitGroup{}
	done.Add(2)

	// Start the server in a go-routine
	go func() {
		server := &Server{}
		c, err := net.ListenPacket("udp", "localhost:6677")
		if err != nil {
			t.Fatal(err)
		}
		defer c.Close()

		// Start the client
		start <- true
		packet, addr, err := server.ReceivePacket(context.Background(), c)
		if err != nil {
			t.Error("Server error")
			return
		}
		if packet == nil {
			t.Error("nil packet")
			return
		}
		msg := packet.(*Message)
		if msg.CountArguments() != 2 {
			t.Errorf("Argument length should be 2 and is: %d\n", msg.CountArguments())
		}
		if msg.Arguments[0].(int32) != 1122 {
			t.Error("Argument should be 1122 and is: " + string(msg.Arguments[0].(int32)))
		}
		if msg.Arguments[1].(int32) != 3344 {
			t.Error("Argument should be 3344 and is: " + string(msg.Arguments[1].(int32)))
		}

		if addr == nil {
			t.Error("addr was empty")
		}

		c.Close()
		finish <- true
	}()

	go func() {
		timeout := time.After(5 * time.Second)
		select {
		case <-timeout:
		case <-start:
			client := NewClient("localhost", 6677)
			msg := NewMessage("/address/test")
			msg.Append(int32(1122))
			msg.Append(int32(3344))
			time.Sleep(500 * time.Millisecond)
			client.Send(msg)
		}

		done.Done()

		select {
		case <-timeout:
		case <-finish:
		}
		done.Done()
	}()

	done.Wait()
}

func TestReadTimeout(t *testing.T) {
	start := make(chan bool)
	wg := sync.WaitGroup{}
	wg.Add(2)

	go func() {
		defer wg.Done()

		select {
		case <-time.After(5 * time.Second):
			t.Fatal("timed out")
		case <-start:
			client := NewClient("localhost", 6677)
			msg := NewMessage("/address/test1")
			err := client.Send(msg)
			if err != nil {
				t.Fatal(err)
			}
			time.Sleep(150 * time.Millisecond)
			msg = NewMessage("/address/test2")
			err = client.Send(msg)
			if err != nil {
				t.Fatal(err)
			}
		}
	}()

	go func() {
		defer wg.Done()

		var ctx context.Context
		timeout := 100 * time.Millisecond

		server := &Server{}
		c, err := net.ListenPacket("udp", "localhost:6677")
		if err != nil {
			t.Fatal(err)
		}
		defer c.Close()

		start <- true
		ctx, _ = context.WithTimeout(context.Background(), timeout)
		p, addr, err := server.ReceivePacket(ctx, c)
		if err != nil {
			t.Errorf("Server error: %v", err)
			return
		}
		if got, want := p.(*Message).Address, "/address/test1"; got != want {
			t.Errorf("Wrong address; got = %s want = %s", got, want)
		}
		if addr == nil {
			t.Errorf("Addr was nil")
		}

		// Second receive should time out since client is delayed 150 milliseconds
		ctx, _ = context.WithTimeout(context.Background(), timeout)
		if _, _, err = server.ReceivePacket(ctx, c); err == nil {
			t.Errorf("Expected error")
			return
		}

		// Next receive should get it
		ctx, _ = context.WithTimeout(context.Background(), timeout)
		p, addr, err = server.ReceivePacket(ctx, c)
		if err != nil {
			t.Errorf("Server error: %v", err)
			return
		}
		if got, want := p.(*Message).Address, "/address/test2"; got != want {
			t.Errorf("Wrong address; got = %s, want = %s", got, want)
		}
		if addr == nil {
			t.Errorf("Addr was nil")
		}
	}()

	wg.Wait()
}

func TestReadPaddedString(t *testing.T) {
	for _, tt := range []struct {
		buf []byte // buffer
		n   int    // bytes needed
		s   string // resulting string
	}{
		{[]byte{'t', 'e', 's', 't', 's', 't', 'r', 'i', 'n', 'g', 0, 0}, 12, "teststring"},
		{[]byte{'t', 'e', 's', 't', 0, 0, 0, 0}, 8, "test"},
	} {
		buf := bytes.NewBuffer(tt.buf)
		s, n, err := readPaddedString(bufio.NewReader(buf))
		if err != nil {
			t.Errorf("%s: Error reading padded string: %s", s, err)
		}
		if got, want := n, tt.n; got != want {
			t.Errorf("%s: Bytes needed don't match; got = %d, want = %d", tt.s, got, want)
		}
		if got, want := s, tt.s; got != want {
			t.Errorf("%s: Strings don't match; got = %d, want = %d", tt.s, got, want)
		}
	}
}

func TestWritePaddedString(t *testing.T) {
	buf := []byte{}
	bytesBuffer := bytes.NewBuffer(buf)
	testString := "testString"
	expectedNumberOfWrittenBytes := len(testString) + padBytesNeeded(len(testString))

	n, err := writePaddedString(testString, bytesBuffer)
	if err != nil {
		t.Errorf(err.Error())
	}

	if n != expectedNumberOfWrittenBytes {
		t.Errorf("Expected number of written bytes should be \"%d\" and is \"%d\"", expectedNumberOfWrittenBytes, n)
	}
}

func TestPadBytesNeeded(t *testing.T) {
	var n int
	n = padBytesNeeded(4)
	if n != 4 {
		t.Errorf("Number of pad bytes should be 4 and is: %d", n)
	}

	n = padBytesNeeded(3)
	if n != 1 {
		t.Errorf("Number of pad bytes should be 1 and is: %d", n)
	}

	n = padBytesNeeded(1)
	if n != 3 {
		t.Errorf("Number of pad bytes should be 3 and is: %d", n)
	}

	n = padBytesNeeded(0)
	if n != 4 {
		t.Errorf("Number of pad bytes should be 4 and is: %d", n)
	}

	n = padBytesNeeded(32)
	if n != 4 {
		t.Errorf("Number of pad bytes should be 4 and is: %d", n)
	}

	n = padBytesNeeded(63)
	if n != 1 {
		t.Errorf("Number of pad bytes should be 1 and is: %d", n)
	}

	n = padBytesNeeded(10)
	if n != 2 {
		t.Errorf("Number of pad bytes should be 2 and is: %d", n)
	}
}

func TestTypeTagsString(t *testing.T) {
	msg := NewMessage("/some/address")
	msg.Append(int32(100))
	msg.Append(true)
	msg.Append(false)

	typeTags, err := msg.TypeTags()
	if err != nil {
		t.Error(err.Error())
	}

	if typeTags != ",iTF" {
		t.Errorf("Type tag string should be ',iTF' and is: %s", typeTags)
	}
}

func TestClientSetLocalAddr(t *testing.T) {
	client := NewClient("localhost", 8967)
	err := client.SetLocalAddr("localhost", 41789)
	if err != nil {
		t.Error(err.Error())
	}
	expectedAddr := "127.0.0.1:41789"
	if client.laddr.String() != expectedAddr {
		t.Errorf("Expected laddr to be %s but was %s", expectedAddr, client.laddr.String())
	}
}

func TestParsePacket(t *testing.T) {
	for _, tt := range []struct {
		desc string
		msg  string
		pkt  Packet
		ok   bool
	}{
		{"no_args",
			"/a/b/c" + nulls(2) + "," + nulls(3),
			makePacket("/a/b/c", nil),
			true},
		{"string_arg",
			"/d/e/f" + nulls(2) + ",s" + nulls(2) + "foo" + nulls(1),
			makePacket("/d/e/f", []string{"foo"}),
			true},
		{"empty", "", nil, false},
	} {
		pkt, err := ParsePacket(tt.msg)
		if err != nil && tt.ok {
			t.Errorf("%s: ParsePacket() returned unexpected error; %s", tt.desc, err)
		}
		if err == nil && !tt.ok {
			t.Errorf("%s: ParsePacket() expected error", tt.desc)
		}
		if !tt.ok {
			continue
		}

		pktBytes, err := pkt.ToByteArray()
		if err != nil {
			t.Errorf("%s: failure converting pkt to byte array; %s", tt.desc, err)
			continue
		}
		ttpktBytes, err := tt.pkt.ToByteArray()
		if err != nil {
			t.Errorf("%s: failure converting tt.pkt to byte array; %s", tt.desc, err)
			continue
		}
		if got, want := pktBytes, ttpktBytes; !reflect.DeepEqual(got, want) {
			t.Errorf("%s: ParsePacket() as bytes = '%s', want = '%s'", tt.desc, got, want)
			continue
		}
	}
}

const zero = string(byte(0))

// nulls returns a string of `i` nulls.
func nulls(i int) string {
	s := ""
	for j := 0; j < i; j++ {
		s += zero
	}
	return s
}

// makePacket creates a fake Message Packet.
func makePacket(addr string, args []string) Packet {
	msg := NewMessage(addr)
	for _, arg := range args {
		msg.Append(arg)
	}
	return msg
}

func TestMain(m *testing.M) {
	log.SetFlags(log.Flags() | log.Lshortfile)
	os.Exit(m.Run())
}
<|endoftext|>


<commit_before>/*
Checks that constraints on structs are met. Constraints are read as a comma-delimited list on the 'checks' annotation. Validate constraints by running `structcheck.Validate()`.

Example:
    package main

    import (
        "bytes"
        "encoding/json"
        "fmt"
        "github.com/Manbeardo/structcheck"
    )

    type MyJsonObjectType struct {
        NestedObject struct{
            Number  int  `checks:"Positive"`
            Pointer *int `checks:"NotNil"`
        }
    }

    var badJson = []byte(`{"NestedObject":{"Number":-1}}`)

    func main() {
        var o MyJsonObjectType
        json.NewDecoder(bytes.NewBuffer(badJson)).Decode(&o)
        err := structcheck.Validate(o)
        if err != nil {
            fmt.Println(err.Error())
        }
    }
Prints:
    The following field(s) failed checks:
        MyJsonObjectType.NestedObject.Number:  Positive: (int)(-1)
        MyJsonObjectType.NestedObject.Pointer: NotNil:   (*int)(nil)
*/
package structcheck
<commit_msg>updated overview godoc<commit_after>/*
Checks that constraints on structs are met. Constraints are read as a comma-delimited list on the 'checks' tag. Validate constraints by running `structcheck.Validate()`.

See structcheck.Check for the full list of checks.

Example:
    package main

    import (
        "bytes"
        "encoding/json"
        "fmt"
        "github.com/Manbeardo/structcheck"
    )

    type MyJsonObjectType struct {
        NestedObject struct{
            Number  int  `checks:"Positive"`
            Pointer *int `checks:"NotNil"`
        }
    }

    var badJson = []byte(`{"NestedObject":{"Number":-1}}`)

    func main() {
        var o MyJsonObjectType
        json.NewDecoder(bytes.NewBuffer(badJson)).Decode(&o)
        err := structcheck.Validate(o)
        if err != nil {
            fmt.Println(err.Error())
        }
    }
Prints:
    The following field(s) failed checks:
        MyJsonObjectType.NestedObject.Number:  Positive: (int)(-1)
        MyJsonObjectType.NestedObject.Pointer: NotNil:   (*int)(nil)
*/
package structcheck
<|endoftext|>


<commit_before>/*
  Go Language Raspberry Pi Interface
  (c) Copyright David Thorpe 2016-2020
  All Rights Reserved
  For Licensing and Usage information, please see LICENSE.md
*/

package main

import (
	"context"
	"fmt"
	"os"

	// Frameworks
	gopi "github.com/djthorpe/gopi/v2"
	app "github.com/djthorpe/gopi/v2/app"
)

////////////////////////////////////////////////////////////////////////////////

func SetBitmap(mgr gopi.SurfaceManager, bitmap gopi.Bitmap, origin gopi.Point) error {
	return mgr.Do(func(gopi.SurfaceManager) error {
		if surface, err := mgr.CreateSurfaceWithBitmap(bitmap, 0, 1.0, 0, origin, gopi.ZeroSize); err != nil {
			return err
		} else {
			fmt.Println(surface)
			return nil
		}
	})
}

func Main(app gopi.App, args []string) error {
	if len(args) > 0 {
		return gopi.ErrHelp
	}

	// Put red bitmap in middle of screen
	if bitmap, err := app.Surfaces().CreateBitmap(0, gopi.Size{100, 100}); err != nil {
		return err
	} else if err := SetBitmap(app.Surfaces(), bitmap, gopi.Point{100, 100}); err != nil {
		return err
	}

	// Wait for key press
	app.WaitForSignal(context.Background(), os.Interrupt)

	// Return success
	return nil
}

////////////////////////////////////////////////////////////////////////////////
// BOOTSTRAP

func main() {
	if app, err := app.NewCommandLineTool(Main, nil, "surfaces"); err != nil {
		fmt.Fprintln(os.Stderr, err)
	} else {
		// Run and exit
		os.Exit(app.Run())
	}
}
<commit_msg>Updated<commit_after>/*
  Go Language Raspberry Pi Interface
  (c) Copyright David Thorpe 2016-2020
  All Rights Reserved
  For Licensing and Usage information, please see LICENSE.md
*/

package main

import (
	"context"
	"fmt"
	"os"

	// Frameworks
	gopi "github.com/djthorpe/gopi/v2"
	app "github.com/djthorpe/gopi/v2/app"
)

////////////////////////////////////////////////////////////////////////////////

func SetBackground(mgr gopi.SurfaceManager) error {
	return mgr.Do(func(gopi.SurfaceManager) error {
		if _, err := mgr.CreateBackground(gopi.SURFACE_FLAG_BITMAP, 1.0); err != nil {
			return err
		} else {
			return nil
		}
	})
}

func SetBitmap(mgr gopi.SurfaceManager, bitmap gopi.Bitmap, origin gopi.Point) error {
	return mgr.Do(func(gopi.SurfaceManager) error {
		bitmap.ClearToColor(gopi.ColorRed)
		if surface, err := mgr.CreateSurfaceWithBitmap(bitmap, 0, 1.0, 0, origin, gopi.ZeroSize); err != nil {
			return err
		} else {
			return nil
		}
	})
}

func Main(app gopi.App, args []string) error {
	if len(args) > 0 {
		return gopi.ErrHelp
	}

	// Set Background
	if err := SetBackground(app.Surfaces()); err != nil {
		return err
	}

	// Put red bitmap on screen
	if bitmap, err := app.Surfaces().CreateBitmap(0, gopi.Size{100, 100}); err != nil {
		return err
	} else if err := SetBitmap(app.Surfaces(), bitmap, gopi.Point{100, 100}); err != nil {
		return err
	}

	// Wait for key press
	app.WaitForSignal(context.Background(), os.Interrupt)

	// Return success
	return nil
}

////////////////////////////////////////////////////////////////////////////////
// BOOTSTRAP

func main() {
	if app, err := app.NewCommandLineTool(Main, nil, "surfaces"); err != nil {
		fmt.Fprintln(os.Stderr, err)
	} else {
		// Run and exit
		os.Exit(app.Run())
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"github.com/aeden/traceroute"
)

func main() {
	out, err := traceroute.Traceroute("google.com", new(traceroute.TracerouteOptions))
	if err != nil {
		fmt.Printf("Error: ", err)
	}

	for i, hop := range out.Hops {
		addr := fmt.Sprintf("%v.%v.%v.%v", hop.Address[0], hop.Address[1], hop.Address[2], hop.Address[3])
		fmt.Printf("%-3d %v (%v)  %v\n", i, addr, addr, hop.ElapsedTime)
	}
}
<commit_msg>Specify host on the command line<commit_after>package main

import (
	"flag"
	"fmt"
	"github.com/aeden/traceroute"
)

func address(address [4]byte) string {
	return fmt.Sprintf("%v.%v.%v.%v", address[0], address[1], address[2], address[3])
}

func main() {
	flag.Parse()
	host := flag.Arg(0)
	options := traceroute.TracerouteOptions{}

	result, err := traceroute.Traceroute(host, &options)

	fmt.Printf("traceroute to %v (%v), %v hops max, %v byte packets\n", host, address(result.DestinationAddress), options.MaxHops, options.PacketSize)

	if err != nil {
		fmt.Printf("Error: ", err)
	}

	for i, hop := range result.Hops {
		addr := address(hop.Address)
		fmt.Printf("%-3d %v (%v)  %v\n", i, addr, addr, hop.ElapsedTime)
	}
}
<|endoftext|>


<commit_before>package main

import (
	"errors"

	"launchpad.net/gnuflag"
	"launchpad.net/juju-core/cmd"
	"launchpad.net/juju-core/juju"
)

// AddUnitCommand is responsible adding a set of units to a service of the environment.
type AddUnitCommand struct {
	EnvName     string
	ServiceName string
	NumUnits    int
}

func (c *AddUnitCommand) Info() *cmd.Info {
	return &cmd.Info{"add-unit", "", "add a service unit", ""}
}

func (c *AddUnitCommand) Init(f *gnuflag.FlagSet, args []string) error {
	addEnvironFlags(&c.EnvName, f)
	f.IntVar(&c.NumUnits, "num-units", 1, "Number of service units to add.")
	if err := f.Parse(true, args); err != nil {
		return err
	}
	args = f.Args()
	switch len(args) {
	case 1:
		c.ServiceName = args[0]
	case 0:
		return errors.New("no service specified")
	default:
		return cmd.CheckEmpty(args[1:])
	}
	if c.NumUnits < 1 {
		return errors.New("must add at least one unit")
	}
	return nil
}

// Run connects to the environment specified on the command line and calls
// service.AddUnit the specified number of times.
func (c *AddUnitCommand) Run(_ *cmd.Context) error {
	conn, err := juju.NewConn(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	st, err := conn.State()
	if err != nil {
		return err
	}
	service, err := st.Service(c.ServiceName)
	if err != nil {
		return err
	}
	_, err = conn.AddUnits(service, c.NumUnits)
	return err

}
<commit_msg>final tweaks<commit_after>package main

import (
	"errors"

	"launchpad.net/gnuflag"
	"launchpad.net/juju-core/cmd"
	"launchpad.net/juju-core/juju"
)

// AddUnitCommand is responsible adding additional units to a service.
type AddUnitCommand struct {
	EnvName     string
	ServiceName string
	NumUnits    int
}

func (c *AddUnitCommand) Info() *cmd.Info {
	return &cmd.Info{"add-unit", "", "add a service unit", ""}
}

func (c *AddUnitCommand) Init(f *gnuflag.FlagSet, args []string) error {
	addEnvironFlags(&c.EnvName, f)
	f.IntVar(&c.NumUnits, "num-units", 1, "Number of service units to add.")
	if err := f.Parse(true, args); err != nil {
		return err
	}
	args = f.Args()
	switch len(args) {
	case 1:
		c.ServiceName = args[0]
	case 0:
		return errors.New("no service specified")
	default:
		return cmd.CheckEmpty(args[1:])
	}
	if c.NumUnits < 1 {
		return errors.New("must add at least one unit")
	}
	return nil
}

// Run connects to the environment specified on the command line
// and calls conn.AddUnits.
func (c *AddUnitCommand) Run(_ *cmd.Context) error {
	conn, err := juju.NewConn(c.EnvName)
	if err != nil {
		return err
	}
	defer conn.Close()
	st, err := conn.State()
	if err != nil {
		return err
	}
	service, err := st.Service(c.ServiceName)
	if err != nil {
		return err
	}
	_, err = conn.AddUnits(service, c.NumUnits)
	return err

}
<|endoftext|>


<commit_before>/*
rqlite -- a replicated SQLite database.

rqlite is a distributed system that provides a replicated SQLite database.
rqlite is written in Go and uses Raft to achieve consensus across all the
instances of the SQLite databases. rqlite ensures that every change made to
the database is made to a majority of underlying SQLite files, or none-at-all.
*/

package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"path/filepath"
	"runtime/pprof"
	"strings"

	sql "github.com/otoolep/rqlite/db"
	httpd "github.com/otoolep/rqlite/http"
	"github.com/otoolep/rqlite/store"
)

const sqliteDSN = "db.sqlite"

// These variables are populated via the Go linker.
var (
	version = "2.1"
	commit  string
	branch  string
)

var httpAddr string
var x509Cert string
var x509Key string
var raftAddr string
var joinAddr string
var expvar bool
var dsn string
var inMem bool
var disRedirect bool
var showVersion bool
var cpuprofile string

const desc = `rqlite is a distributed system that provides a replicated SQLite database.`

func init() {
	flag.StringVar(&httpAddr, "http", "localhost:4001", "HTTP query server address. Set X.509 cert and key for HTTPS.")
	flag.StringVar(&x509Cert, "x509cert", "", "Path to X.509 certificate")
	flag.StringVar(&x509Key, "x509key", "", "Path to X.509 private key for certificate")
	flag.StringVar(&raftAddr, "raft", "localhost:4002", "Raft communication bind address")
	flag.StringVar(&joinAddr, "join", "", "protocol://host:port of leader to join")
	flag.BoolVar(&expvar, "expvar", true, "Serve expvar data on HTTP server")
	flag.StringVar(&dsn, "dsn", "", `SQLite DSN parameters. E.g. "cache=shared&mode=memory"`)
	flag.BoolVar(&inMem, "mem", false, "Use an in-memory database")
	flag.BoolVar(&disRedirect, "noredir", true, "Disable leader-redirect")
	flag.BoolVar(&showVersion, "version", false, "Show version information and exit")
	flag.StringVar(&cpuprofile, "cpuprofile", "", "Write CPU profile to file")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "\n%s\n\n", desc)
		fmt.Fprintf(os.Stderr, "Usage: %s [arguments] <data directory>\n", os.Args[0])
		flag.PrintDefaults()
	}

	// If commit, branch, or build time are not set, make that clear.
	if commit == "" {
		commit = "unknown"
	}
	if branch == "" {
		branch = "unknown"
	}
}

func main() {
	flag.Parse()

	if showVersion {
		fmt.Printf("rqlited version %s (commit %s)\n", version, commit)
		os.Exit(0)
	}

	// Ensure the data path is set.
	if flag.NArg() == 0 {
		flag.Usage()
		os.Exit(1)
	}

	dataPath := flag.Arg(0)

	// Configure logging and pump out initial message.
	log.SetFlags(log.LstdFlags)
	log.SetPrefix("[rqlited] ")
	log.Printf("rqlited starting, version %s, commit %s, branch %s", version, commit, branch)

	// Set up profiling, if requested.
	if cpuprofile != "" {
		log.Println("profiling enabled")
		f, err := os.Create(cpuprofile)
		if err != nil {
			log.Printf("unable to create path: %s", err.Error())
		}
		defer f.Close()

		err = pprof.StartCPUProfile(f)
		if err != nil {
			log.Printf("unable to start CPU Profile: %s", err.Error())
		}

		defer pprof.StopCPUProfile()
	}

	// Create and open the store.
	dataPath, err := filepath.Abs(dataPath)
	if err != nil {
		log.Fatalf("failed to determine absolute data path: %s", err.Error())
	}
	dbConf := sql.NewConfig()
	dbConf.DSN = dsn
	dbConf.Memory = inMem
	store := store.New(dbConf, dataPath, raftAddr)
	if err := store.Open(joinAddr == ""); err != nil {
		log.Fatalf("failed to open store: %s", err.Error())
	}

	// If join was specified, make the join request.
	if joinAddr != "" {
		if err := join(joinAddr, raftAddr); err != nil {
			log.Fatalf("failed to join node at %s: %s", joinAddr, err.Error())
		}
	}

	// Create the HTTP query server.
	s := httpd.New(httpAddr, store)
	s.CertFile = x509Cert
	s.KeyFile = x509Key
	s.DisableRedirect = disRedirect
	s.Expvar = expvar
	s.Version = version
	s.Commit = commit
	s.Branch = branch
	if err := s.Start(); err != nil {
		log.Fatalf("failed to start HTTP server: %s", err.Error())

	}

	terminate := make(chan os.Signal, 1)
	signal.Notify(terminate, os.Interrupt)
	<-terminate
	if err := store.Close(); err != nil {
		log.Printf("failed to close store: %s", err.Error())
	}
	log.Println("rqlite server stopped")
}

func join(joinAddr, raftAddr string) error {
	b, err := json.Marshal(map[string]string{"addr": raftAddr})
	if err != nil {
		return err
	}

	// Check for protocol scheme, and insert default if necessary.
	fullAddr := fmt.Sprintf("%s/join", joinAddr)
	if !strings.HasPrefix(joinAddr, "http://") && !strings.HasPrefix(joinAddr, "https://") {
		fullAddr = fmt.Sprintf("http://%s", joinAddr)
	}

	resp, err := http.Post(fullAddr, "application-type/json", bytes.NewReader(b))
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	return nil
}
<commit_msg>Less precise version<commit_after>/*
rqlite -- a replicated SQLite database.

rqlite is a distributed system that provides a replicated SQLite database.
rqlite is written in Go and uses Raft to achieve consensus across all the
instances of the SQLite databases. rqlite ensures that every change made to
the database is made to a majority of underlying SQLite files, or none-at-all.
*/

package main

import (
	"bytes"
	"encoding/json"
	"flag"
	"fmt"
	"log"
	"net/http"
	"os"
	"os/signal"
	"path/filepath"
	"runtime/pprof"
	"strings"

	sql "github.com/otoolep/rqlite/db"
	httpd "github.com/otoolep/rqlite/http"
	"github.com/otoolep/rqlite/store"
)

const sqliteDSN = "db.sqlite"

// These variables are populated via the Go linker.
var (
	version = "2"
	commit  string
	branch  string
)

var httpAddr string
var x509Cert string
var x509Key string
var raftAddr string
var joinAddr string
var expvar bool
var dsn string
var inMem bool
var disRedirect bool
var showVersion bool
var cpuprofile string

const desc = `rqlite is a distributed system that provides a replicated SQLite database.`

func init() {
	flag.StringVar(&httpAddr, "http", "localhost:4001", "HTTP query server address. Set X.509 cert and key for HTTPS.")
	flag.StringVar(&x509Cert, "x509cert", "", "Path to X.509 certificate")
	flag.StringVar(&x509Key, "x509key", "", "Path to X.509 private key for certificate")
	flag.StringVar(&raftAddr, "raft", "localhost:4002", "Raft communication bind address")
	flag.StringVar(&joinAddr, "join", "", "protocol://host:port of leader to join")
	flag.BoolVar(&expvar, "expvar", true, "Serve expvar data on HTTP server")
	flag.StringVar(&dsn, "dsn", "", `SQLite DSN parameters. E.g. "cache=shared&mode=memory"`)
	flag.BoolVar(&inMem, "mem", false, "Use an in-memory database")
	flag.BoolVar(&disRedirect, "noredir", true, "Disable leader-redirect")
	flag.BoolVar(&showVersion, "version", false, "Show version information and exit")
	flag.StringVar(&cpuprofile, "cpuprofile", "", "Write CPU profile to file")
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, "\n%s\n\n", desc)
		fmt.Fprintf(os.Stderr, "Usage: %s [arguments] <data directory>\n", os.Args[0])
		flag.PrintDefaults()
	}

	// If commit, branch, or build time are not set, make that clear.
	if commit == "" {
		commit = "unknown"
	}
	if branch == "" {
		branch = "unknown"
	}
}

func main() {
	flag.Parse()

	if showVersion {
		fmt.Printf("rqlited version %s (commit %s)\n", version, commit)
		os.Exit(0)
	}

	// Ensure the data path is set.
	if flag.NArg() == 0 {
		flag.Usage()
		os.Exit(1)
	}

	dataPath := flag.Arg(0)

	// Configure logging and pump out initial message.
	log.SetFlags(log.LstdFlags)
	log.SetPrefix("[rqlited] ")
	log.Printf("rqlited starting, version %s, commit %s, branch %s", version, commit, branch)

	// Set up profiling, if requested.
	if cpuprofile != "" {
		log.Println("profiling enabled")
		f, err := os.Create(cpuprofile)
		if err != nil {
			log.Printf("unable to create path: %s", err.Error())
		}
		defer f.Close()

		err = pprof.StartCPUProfile(f)
		if err != nil {
			log.Printf("unable to start CPU Profile: %s", err.Error())
		}

		defer pprof.StopCPUProfile()
	}

	// Create and open the store.
	dataPath, err := filepath.Abs(dataPath)
	if err != nil {
		log.Fatalf("failed to determine absolute data path: %s", err.Error())
	}
	dbConf := sql.NewConfig()
	dbConf.DSN = dsn
	dbConf.Memory = inMem
	store := store.New(dbConf, dataPath, raftAddr)
	if err := store.Open(joinAddr == ""); err != nil {
		log.Fatalf("failed to open store: %s", err.Error())
	}

	// If join was specified, make the join request.
	if joinAddr != "" {
		if err := join(joinAddr, raftAddr); err != nil {
			log.Fatalf("failed to join node at %s: %s", joinAddr, err.Error())
		}
	}

	// Create the HTTP query server.
	s := httpd.New(httpAddr, store)
	s.CertFile = x509Cert
	s.KeyFile = x509Key
	s.DisableRedirect = disRedirect
	s.Expvar = expvar
	s.Version = version
	s.Commit = commit
	s.Branch = branch
	if err := s.Start(); err != nil {
		log.Fatalf("failed to start HTTP server: %s", err.Error())

	}

	terminate := make(chan os.Signal, 1)
	signal.Notify(terminate, os.Interrupt)
	<-terminate
	if err := store.Close(); err != nil {
		log.Printf("failed to close store: %s", err.Error())
	}
	log.Println("rqlite server stopped")
}

func join(joinAddr, raftAddr string) error {
	b, err := json.Marshal(map[string]string{"addr": raftAddr})
	if err != nil {
		return err
	}

	// Check for protocol scheme, and insert default if necessary.
	fullAddr := fmt.Sprintf("%s/join", joinAddr)
	if !strings.HasPrefix(joinAddr, "http://") && !strings.HasPrefix(joinAddr, "https://") {
		fullAddr = fmt.Sprintf("http://%s", joinAddr)
	}

	resp, err := http.Post(fullAddr, "application-type/json", bytes.NewReader(b))
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	return nil
}
<|endoftext|>