<commit_before>package xlog

import (
	"bytes"
	"log"
	"runtime"
	"sync"
	"testing"
	"time"

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

var fakeNow = time.Date(0, 0, 0, 0, 0, 0, 0, time.Local)
var critialLoggerMux = sync.Mutex{}

func init() {
	now = func() time.Time {
		return fakeNow
	}
}

func TestNew(t *testing.T) {
	oc := NewOutputChannel(newTestOutput())
	defer oc.Close()
	c := Config{
		Level:  LevelError,
		Output: oc,
		Fields: F{"foo": "bar"},
	}
	L := New(c)
	l, ok := L.(*logger)
	if assert.True(t, ok) {
		assert.Equal(t, LevelError, l.level)
		assert.Equal(t, c.Output, l.output)
		assert.Equal(t, F{"foo": "bar"}, F(l.fields))
		// Ensure l.fields is a clone
		c.Fields["bar"] = "baz"
		assert.Equal(t, F{"foo": "bar"}, F(l.fields))
		l.close()
	}
}

func TestCopy(t *testing.T) {
	oc := NewOutputChannel(newTestOutput())
	defer oc.Close()
	c := Config{
		Level:  LevelError,
		Output: oc,
		Fields: F{"foo": "bar"},
	}
	l := New(c).(*logger)
	l2 := Copy(l).(*logger)
	assert.Equal(t, l.output, l2.output)
	assert.Equal(t, l.level, l2.level)
	assert.Equal(t, l.fields, l2.fields)
	l2.SetField("bar", "baz")
	assert.Equal(t, map[string]interface{}{"foo": "bar"}, l.fields)
	assert.Equal(t, map[string]interface{}{"foo": "bar", "bar": "baz"}, l2.fields)

	assert.Equal(t, NopLogger, Copy(NopLogger))
	assert.Equal(t, NopLogger, Copy(nil))
}

func TestNewDefautOutput(t *testing.T) {
	L := New(Config{})
	l, ok := L.(*logger)
	if assert.True(t, ok) {
		assert.NotNil(t, l.output)
		l.close()
	}
}

func TestSend(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.send(LevelDebug, 1, "test", F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "debug", "message": "test", "foo": "bar"}, last)

	l.SetField("bar", "baz")
	l.send(LevelInfo, 1, "test", F{"foo": "bar"})
	last = <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "info", "message": "test", "foo": "bar", "bar": "baz"}, last)

	l = New(Config{Output: o, Level: 1}).(*logger)
	o.reset()
	l.send(0, 2, "test", F{"foo": "bar"})
	assert.True(t, o.empty())
}

func TestSendDrop(t *testing.T) {
	buf := bytes.NewBuffer(nil)
	critialLoggerMux.Lock()
	oldCritialLogger := critialLogger
	critialLogger = log.New(buf, "", 0)
	defer func() {
		critialLogger = oldCritialLogger
		critialLoggerMux.Unlock()
	}()
	oc := NewOutputChannelBuffer(Discard, 1)
	defer oc.Close()
	l := New(Config{Output: oc}).(*logger)
	l.send(LevelDebug, 2, "test", F{"foo": "bar"})
	l.send(LevelDebug, 2, "test", F{"foo": "bar"})
	l.send(LevelDebug, 2, "test", F{"foo": "bar"})
	for i := 0; i < 10; i++ {
		runtime.Gosched()
		if "send error: buffer fullsend error: buffer full" == buf.String() {
			return
		}
	}
	t.Fail()
}

func TestWxtractFields(t *testing.T) {
	v := []interface{}{"a", 1, map[string]interface{}{"foo": "bar"}}
	f := extractFields(&v)
	assert.Equal(t, map[string]interface{}{"foo": "bar"}, f)
	assert.Equal(t, []interface{}{"a", 1}, v)

	v = []interface{}{map[string]interface{}{"foo": "bar"}, "a", 1}
	f = extractFields(&v)
	assert.Nil(t, f)
	assert.Equal(t, []interface{}{map[string]interface{}{"foo": "bar"}, "a", 1}, v)

	v = []interface{}{"a", 1, F{"foo": "bar"}}
	f = extractFields(&v)
	assert.Equal(t, map[string]interface{}{"foo": "bar"}, f)
	assert.Equal(t, []interface{}{"a", 1}, v)

	v = []interface{}{}
	f = extractFields(&v)
	assert.Nil(t, f)
	assert.Equal(t, []interface{}{}, v)
}

func TestDebug(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.Debug("test", F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "debug", "message": "test", "foo": "bar"}, last)
}

func TestDebugf(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.Debugf("test %d", 1, F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "debug", "message": "test 1", "foo": "bar"}, last)
}

func TestInfo(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.Info("test", F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "info", "message": "test", "foo": "bar"}, last)
}

func TestInfof(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.Infof("test %d", 1, F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "info", "message": "test 1", "foo": "bar"}, last)
}

func TestWarn(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.Warn("test", F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "warn", "message": "test", "foo": "bar"}, last)
}

func TestWarnf(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.Warnf("test %d", 1, F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "warn", "message": "test 1", "foo": "bar"}, last)
}

func TestError(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.Error("test", F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "error", "message": "test", "foo": "bar"}, last)
}

func TestErrorf(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.Errorf("test %d%v", 1, F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "error", "message": "test 1", "foo": "bar"}, last)
}

func TestFatal(t *testing.T) {
	e := exit1
	exited := 0
	exit1 = func() { exited++ }
	defer func() { exit1 = e }()
	o := newTestOutput()
	l := New(Config{Output: NewOutputChannel(o)}).(*logger)
	l.Fatal("test", F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "fatal", "message": "test", "foo": "bar"}, last)
	assert.Equal(t, 1, exited)
}

func TestFatalf(t *testing.T) {
	e := exit1
	exited := 0
	exit1 = func() { exited++ }
	defer func() { exit1 = e }()
	o := newTestOutput()
	l := New(Config{Output: NewOutputChannel(o)}).(*logger)
	l.Fatalf("test %d%v", 1, F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "fatal", "message": "test 1", "foo": "bar"}, last)
	assert.Equal(t, 1, exited)
}

func TestWrite(t *testing.T) {
	o := newTestOutput()
	xl := New(Config{Output: NewOutputChannel(o)}).(*logger)
	l := log.New(xl, "prefix ", 0)
	l.Printf("test")
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "info", "message": "prefix test"}, last)
}
<commit_msg>Fix SendDrop test<commit_after>package xlog

import (
	"io"
	"io/ioutil"
	"log"
	"sync"
	"testing"
	"time"

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

var fakeNow = time.Date(0, 0, 0, 0, 0, 0, 0, time.Local)
var critialLoggerMux = sync.Mutex{}

func init() {
	now = func() time.Time {
		return fakeNow
	}
}

func TestNew(t *testing.T) {
	oc := NewOutputChannel(newTestOutput())
	defer oc.Close()
	c := Config{
		Level:  LevelError,
		Output: oc,
		Fields: F{"foo": "bar"},
	}
	L := New(c)
	l, ok := L.(*logger)
	if assert.True(t, ok) {
		assert.Equal(t, LevelError, l.level)
		assert.Equal(t, c.Output, l.output)
		assert.Equal(t, F{"foo": "bar"}, F(l.fields))
		// Ensure l.fields is a clone
		c.Fields["bar"] = "baz"
		assert.Equal(t, F{"foo": "bar"}, F(l.fields))
		l.close()
	}
}

func TestCopy(t *testing.T) {
	oc := NewOutputChannel(newTestOutput())
	defer oc.Close()
	c := Config{
		Level:  LevelError,
		Output: oc,
		Fields: F{"foo": "bar"},
	}
	l := New(c).(*logger)
	l2 := Copy(l).(*logger)
	assert.Equal(t, l.output, l2.output)
	assert.Equal(t, l.level, l2.level)
	assert.Equal(t, l.fields, l2.fields)
	l2.SetField("bar", "baz")
	assert.Equal(t, map[string]interface{}{"foo": "bar"}, l.fields)
	assert.Equal(t, map[string]interface{}{"foo": "bar", "bar": "baz"}, l2.fields)

	assert.Equal(t, NopLogger, Copy(NopLogger))
	assert.Equal(t, NopLogger, Copy(nil))
}

func TestNewDefautOutput(t *testing.T) {
	L := New(Config{})
	l, ok := L.(*logger)
	if assert.True(t, ok) {
		assert.NotNil(t, l.output)
		l.close()
	}
}

func TestSend(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.send(LevelDebug, 1, "test", F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "debug", "message": "test", "foo": "bar"}, last)

	l.SetField("bar", "baz")
	l.send(LevelInfo, 1, "test", F{"foo": "bar"})
	last = <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "info", "message": "test", "foo": "bar", "bar": "baz"}, last)

	l = New(Config{Output: o, Level: 1}).(*logger)
	o.reset()
	l.send(0, 2, "test", F{"foo": "bar"})
	assert.True(t, o.empty())
}

func TestSendDrop(t *testing.T) {
	r, w := io.Pipe()
	go func() {
		critialLoggerMux.Lock()
		defer critialLoggerMux.Unlock()
		oldCritialLogger := critialLogger
		critialLogger = log.New(w, "", 0)
		o := newTestOutput()
		oc := NewOutputChannelBuffer(Discard, 1)
		l := New(Config{Output: oc}).(*logger)
		l.send(LevelDebug, 2, "test", F{"foo": "bar"})
		l.send(LevelDebug, 2, "test", F{"foo": "bar"})
		l.send(LevelDebug, 2, "test", F{"foo": "bar"})
		o.get()
		o.get()
		o.get()
		oc.Close()
		critialLogger = oldCritialLogger
		w.Close()
	}()
	b, err := ioutil.ReadAll(r)
	assert.NoError(t, err)
	assert.Contains(t, string(b), "send error: buffer full")
}

func TestWxtractFields(t *testing.T) {
	v := []interface{}{"a", 1, map[string]interface{}{"foo": "bar"}}
	f := extractFields(&v)
	assert.Equal(t, map[string]interface{}{"foo": "bar"}, f)
	assert.Equal(t, []interface{}{"a", 1}, v)

	v = []interface{}{map[string]interface{}{"foo": "bar"}, "a", 1}
	f = extractFields(&v)
	assert.Nil(t, f)
	assert.Equal(t, []interface{}{map[string]interface{}{"foo": "bar"}, "a", 1}, v)

	v = []interface{}{"a", 1, F{"foo": "bar"}}
	f = extractFields(&v)
	assert.Equal(t, map[string]interface{}{"foo": "bar"}, f)
	assert.Equal(t, []interface{}{"a", 1}, v)

	v = []interface{}{}
	f = extractFields(&v)
	assert.Nil(t, f)
	assert.Equal(t, []interface{}{}, v)
}

func TestDebug(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.Debug("test", F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "debug", "message": "test", "foo": "bar"}, last)
}

func TestDebugf(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.Debugf("test %d", 1, F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "debug", "message": "test 1", "foo": "bar"}, last)
}

func TestInfo(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.Info("test", F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "info", "message": "test", "foo": "bar"}, last)
}

func TestInfof(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.Infof("test %d", 1, F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "info", "message": "test 1", "foo": "bar"}, last)
}

func TestWarn(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.Warn("test", F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "warn", "message": "test", "foo": "bar"}, last)
}

func TestWarnf(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.Warnf("test %d", 1, F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "warn", "message": "test 1", "foo": "bar"}, last)
}

func TestError(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.Error("test", F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "error", "message": "test", "foo": "bar"}, last)
}

func TestErrorf(t *testing.T) {
	o := newTestOutput()
	l := New(Config{Output: o}).(*logger)
	l.Errorf("test %d%v", 1, F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "error", "message": "test 1", "foo": "bar"}, last)
}

func TestFatal(t *testing.T) {
	e := exit1
	exited := 0
	exit1 = func() { exited++ }
	defer func() { exit1 = e }()
	o := newTestOutput()
	l := New(Config{Output: NewOutputChannel(o)}).(*logger)
	l.Fatal("test", F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "fatal", "message": "test", "foo": "bar"}, last)
	assert.Equal(t, 1, exited)
}

func TestFatalf(t *testing.T) {
	e := exit1
	exited := 0
	exit1 = func() { exited++ }
	defer func() { exit1 = e }()
	o := newTestOutput()
	l := New(Config{Output: NewOutputChannel(o)}).(*logger)
	l.Fatalf("test %d%v", 1, F{"foo": "bar"})
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "fatal", "message": "test 1", "foo": "bar"}, last)
	assert.Equal(t, 1, exited)
}

func TestWrite(t *testing.T) {
	o := newTestOutput()
	xl := New(Config{Output: NewOutputChannel(o)}).(*logger)
	l := log.New(xl, "prefix ", 0)
	l.Printf("test")
	last := <-o.w
	assert.Contains(t, last["file"], "log_test.go:")
	delete(last, "file")
	assert.Equal(t, map[string]interface{}{"time": fakeNow, "level": "info", "message": "prefix test"}, last)
}
<|endoftext|>


<commit_before>//
// xlsx2json package wraps the github.com/tealag/xlsx package (used under a BSD License) and  a fork of Robert Krimen's Otto
// Javascript engine (under an MIT License) providing an scriptable xlsx2json exporter, explorer and importer utility.
//
// @author R. S. Doiel, <rsdoiel@gmail.com>
//
// Copyright (c) 2016, R. S. Doiel
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
package xlsx2json

import (
	"encoding/json"
	"fmt"

	// 3rd party packages
	"github.com/robertkrimen/otto"
	"github.com/tealeg/xlsx"
)

// Version is the library and utilty version number
const Version = "0.0.1"

type jsResponse struct {
	Path   string                 `json:"path"`
	Source map[string]interface{} `json:"source"`
	Error  string                 `json:"error"`
}

// Run runs the xlsx2json transform with optional JavaScript support.
// Continued processing can be achieved with subsequent calls to
// the JS VM. It returns the VM, an array of JSON encoded blobs and error.
func Run(inputFilename string, sheetNo int, jsFilename, jsCallback string) (*otto.Otto, []string, error) {
	var (
		xlFile *xlsx.File
		vm     *otto.Otto
		err    error
		output []string
	)

	jsMap := false
	vm, err = NewJavaScriptVM([]string{jsFilename})
	if err != nil {
		return nil, output, err
	}
	if jsFilename != "" && jsCallback != "" {
		jsMap = true
	}

	// Read from the given file path
	xlFile, err = xlsx.OpenFile(inputFilename)
	if err != nil {
		return vm, output, fmt.Errorf("Can't open %s, %s", inputFilename, err)
	}

	for i, sheet := range xlFile.Sheets {
		if sheetNo == i {
			columnNames := []string{}

			for rowNo, row := range sheet.Rows {
				jsonBlob := map[string]string{}
				for colNo, cell := range row.Cells {
					if rowNo == 0 {
						columnNames = append(columnNames, cell.String())
					} else {
						// Build a map and render it out
						if colNo < len(columnNames) {
							jsonBlob[columnNames[colNo]] = cell.String()
						} else {
							k := fmt.Sprintf("column_%d", colNo+1)
							columnNames = append(columnNames, k)
							jsonBlob[k] = cell.String()
						}
					}
				}
				if rowNo > 0 {
					src, err := json.Marshal(jsonBlob)
					if err != nil {
						return vm, output, fmt.Errorf("Can't render JSON blob, %s", err)
					}
					if jsMap == true {
						// We're eval the callback from inside a closure to be safer
						js := fmt.Sprintf("(function(){ return %s(%s);}())", jsCallback, src)
						jsValue, err := vm.Eval(js)
						if err != nil {
							return vm, output, fmt.Errorf("row: %d, Can't run %s, %s", rowNo, jsFilename, err)
						}
						val, err := jsValue.Export()
						if err != nil {
							return vm, output, fmt.Errorf("row: %d, Can't convert JavaScript value %s(%s), %s", rowNo, jsCallback, src, err)
						}
						src, err = json.Marshal(val)
						if err != nil {
							return vm, output, fmt.Errorf("row: %d, src: %s\njs returned %v\nerror: %s", rowNo, js, jsValue, err)
						}
						response := new(jsResponse)
						err = json.Unmarshal(src, &response)
						if err != nil {
							return vm, output, fmt.Errorf("row: %d, do not understand response %s, %s", rowNo, src, err)
						}
						if response.Error != "" {
							return vm, output, fmt.Errorf("row: %d, %s", rowNo, response.Error)
						}
						// Now re-package response.Source into a JSON blob
						src, err = json.Marshal(response.Source)
						if err != nil {
							return vm, output, fmt.Errorf("row: %d, %s", rowNo, err)
						}
					}
					output = append(output, string(src))
				}
			}
		}
	}
	return vm, output, nil
}
<commit_msg>fixed reference cell.String()<commit_after>//
// xlsx2json package wraps the github.com/tealag/xlsx package (used under a BSD License) and  a fork of Robert Krimen's Otto
// Javascript engine (under an MIT License) providing an scriptable xlsx2json exporter, explorer and importer utility.
//
// @author R. S. Doiel, <rsdoiel@gmail.com>
//
// Copyright (c) 2016, R. S. Doiel
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this
//   list of conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice,
//   this list of conditions and the following disclaimer in the documentation
//   and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
package xlsx2json

import (
	"encoding/json"
	"fmt"

	// 3rd party packages
	"github.com/robertkrimen/otto"
	"github.com/tealeg/xlsx"
)

// Version is the library and utilty version number
const Version = "0.0.1"

type jsResponse struct {
	Path   string                 `json:"path"`
	Source map[string]interface{} `json:"source"`
	Error  string                 `json:"error"`
}

// Run runs the xlsx2json transform with optional JavaScript support.
// Continued processing can be achieved with subsequent calls to
// the JS VM. It returns the VM, an array of JSON encoded blobs and error.
func Run(inputFilename string, sheetNo int, jsFilename, jsCallback string) (*otto.Otto, []string, error) {
	var (
		xlFile *xlsx.File
		vm     *otto.Otto
		err    error
		output []string
	)

	jsMap := false
	vm, err = NewJavaScriptVM([]string{jsFilename})
	if err != nil {
		return nil, output, err
	}
	if jsFilename != "" && jsCallback != "" {
		jsMap = true
	}

	// Read from the given file path
	xlFile, err = xlsx.OpenFile(inputFilename)
	if err != nil {
		return vm, output, fmt.Errorf("Can't open %s, %s", inputFilename, err)
	}

	for i, sheet := range xlFile.Sheets {
		if sheetNo == i {
			columnNames := []string{}

			for rowNo, row := range sheet.Rows {
				jsonBlob := map[string]string{}
				for colNo, cell := range row.Cells {
					if rowNo == 0 {
						s, _ := cell.String()
						columnNames = append(columnNames, s)
					} else {
						// Build a map and render it out
						if colNo < len(columnNames) {
							s, _ := cell.String()
							jsonBlob[columnNames[colNo]] = s
						} else {
							k := fmt.Sprintf("column_%d", colNo+1)
							columnNames = append(columnNames, k)
							s, _ := cell.String()
							jsonBlob[k] = s
						}
					}
				}
				if rowNo > 0 {
					src, err := json.Marshal(jsonBlob)
					if err != nil {
						return vm, output, fmt.Errorf("Can't render JSON blob, %s", err)
					}
					if jsMap == true {
						// We're eval the callback from inside a closure to be safer
						js := fmt.Sprintf("(function(){ return %s(%s);}())", jsCallback, src)
						jsValue, err := vm.Eval(js)
						if err != nil {
							return vm, output, fmt.Errorf("row: %d, Can't run %s, %s", rowNo, jsFilename, err)
						}
						val, err := jsValue.Export()
						if err != nil {
							return vm, output, fmt.Errorf("row: %d, Can't convert JavaScript value %s(%s), %s", rowNo, jsCallback, src, err)
						}
						src, err = json.Marshal(val)
						if err != nil {
							return vm, output, fmt.Errorf("row: %d, src: %s\njs returned %v\nerror: %s", rowNo, js, jsValue, err)
						}
						response := new(jsResponse)
						err = json.Unmarshal(src, &response)
						if err != nil {
							return vm, output, fmt.Errorf("row: %d, do not understand response %s, %s", rowNo, src, err)
						}
						if response.Error != "" {
							return vm, output, fmt.Errorf("row: %d, %s", rowNo, response.Error)
						}
						// Now re-package response.Source into a JSON blob
						src, err = json.Marshal(response.Source)
						if err != nil {
							return vm, output, fmt.Errorf("row: %d, %s", rowNo, err)
						}
					}
					output = append(output, string(src))
				}
			}
		}
	}
	return vm, output, nil
}
<|endoftext|>


<commit_before>package xlsx

import (
	"bytes"
	"fmt"
	"io"
	"testing"
	"time"
)

type CellIndexTestCase struct {
	x        uint64
	y        uint64
	expected string
}

func TestCellIndex(t *testing.T) {

	tests := []CellIndexTestCase{
		CellIndexTestCase{0, 0, "A1"},
		CellIndexTestCase{2, 2, "C3"},
		CellIndexTestCase{26, 45, "AA46"},
		CellIndexTestCase{2600, 100000, "CVA100001"},
	}

	for _, c := range tests {
		cellX, cellY := CellIndex(c.x, c.y)
		s := fmt.Sprintf("%s%d", cellX, cellY)
		if s != c.expected {
			t.Errorf("expected %s, got %s", c.expected, s)
		}
	}
}

type OADateTestCase struct {
	datetime time.Time
	expected string
}

func TestOADate(t *testing.T) {

	tests := []OADateTestCase{
		OADateTestCase{time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC), "25569"},
		OADateTestCase{time.Date(1970, 1, 1, 12, 20, 0, 0, time.UTC), "25569.513889"},
		OADateTestCase{time.Date(2014, 12, 20, 0, 0, 0, 0, time.UTC), "41993"},
	}

	for _, d := range tests {
		s := OADate(d.datetime)
		if s != d.expected {
			t.Errorf("expected %s, got %s", d.expected, s)
		}
	}
}

func TestTemplates(t *testing.T) {

	var b bytes.Buffer
	var err error
	var s Sheet

	err = TemplateContentTypes.Execute(&b, nil)
	if err != nil {
		t.Errorf("template TemplateContentTypes failed to Execute returning error %s", err.Error())
	}

	err = TemplateRelationships.Execute(&b, nil)
	if err != nil {
		t.Errorf("template TemplateRelationships failed to Execute returning error %s", err.Error())
	}

	err = TemplateApp.Execute(&b, nil)
	if err != nil {
		t.Errorf("template TemplateApp failed to Execute returning error %s", err.Error())
	}

	err = TemplateCore.Execute(&b, s.DocumentInfo)
	if err != nil {
		t.Errorf("template TemplateCore failed to Execute returning error %s", err.Error())
	}

	err = TemplateWorkbook.Execute(&b, nil)
	if err != nil {
		t.Errorf("template TemplateWorkbook failed to Execute returning error %s", err.Error())
	}

	err = TemplateWorkbookRelationships.Execute(&b, nil)
	if err != nil {
		t.Errorf("template TemplateWorkbookRelationships failed to Execute returning error %s", err.Error())
	}

	err = TemplateStyles.Execute(&b, nil)
	if err != nil {
		t.Errorf("template TemplateStyles failed to Execute returning error %s", err.Error())
	}

	err = TemplateStringLookups.Execute(&b, []string{})
	if err != nil {
		t.Errorf("template TemplateStringLookups failed to Execute returning error %s", err.Error())
	}

	sheet := struct {
		Cols  []Column
		Rows  []string
		Start string
		End   string
	}{
		Cols:  []Column{},
		Rows:  []string{},
		Start: "A1",
		End:   "C3",
	}

	err = TemplateSheetStart.Execute(&b, sheet)
	if err != nil {
		t.Errorf("template TemplateSheetStart failed to Execute returning error %s", err.Error())
	}

	for i, _ := range sheet.Rows {
		rb := &bytes.Buffer{}
		rowString := fmt.Sprintf(`<row r="%d">%s</row>`, uint64(i), rb.String())
		_, err = io.WriteString(&b, rowString)
	}
}
<commit_msg>Change template tests to reflect the arguments now passed to them<commit_after>package xlsx

import (
	"bytes"
	"fmt"
	"io"
	"testing"
	"time"
)

type CellIndexTestCase struct {
	x        uint64
	y        uint64
	expected string
}

func TestCellIndex(t *testing.T) {

	tests := []CellIndexTestCase{
		CellIndexTestCase{0, 0, "A1"},
		CellIndexTestCase{2, 2, "C3"},
		CellIndexTestCase{26, 45, "AA46"},
		CellIndexTestCase{2600, 100000, "CVA100001"},
	}

	for _, c := range tests {
		cellX, cellY := CellIndex(c.x, c.y)
		s := fmt.Sprintf("%s%d", cellX, cellY)
		if s != c.expected {
			t.Errorf("expected %s, got %s", c.expected, s)
		}
	}
}

type OADateTestCase struct {
	datetime time.Time
	expected string
}

func TestOADate(t *testing.T) {

	tests := []OADateTestCase{
		OADateTestCase{time.Date(1970, 1, 1, 0, 0, 0, 0, time.UTC), "25569"},
		OADateTestCase{time.Date(1970, 1, 1, 12, 20, 0, 0, time.UTC), "25569.513889"},
		OADateTestCase{time.Date(2014, 12, 20, 0, 0, 0, 0, time.UTC), "41993"},
	}

	for _, d := range tests {
		s := OADate(d.datetime)
		if s != d.expected {
			t.Errorf("expected %s, got %s", d.expected, s)
		}
	}
}

func TestTemplates(t *testing.T) {

	var b bytes.Buffer
	var err error
	var s Sheet
	var sheetNames = []string{"SheetOne", "SheetTwo"}

	err = TemplateContentTypes.Execute(&b, nil)
	if err != nil {
		t.Errorf("template TemplateContentTypes failed to Execute returning error %s", err.Error())
	}

	err = TemplateRelationships.Execute(&b, nil)
	if err != nil {
		t.Errorf("template TemplateRelationships failed to Execute returning error %s", err.Error())
	}

	err = TemplateApp.Execute(&b, sheetNames)
	if err != nil {
		t.Errorf("template TemplateApp failed to Execute returning error %s", err.Error())
	}

	err = TemplateCore.Execute(&b, s.DocumentInfo)
	if err != nil {
		t.Errorf("template TemplateCore failed to Execute returning error %s", err.Error())
	}

	err = TemplateWorkbook.Execute(&b, nil)
	if err != nil {
		t.Errorf("template TemplateWorkbook failed to Execute returning error %s", err.Error())
	}

	err = TemplateWorkbookRelationships.Execute(&b, sheetNames)
	if err != nil {
		t.Errorf("template TemplateWorkbookRelationships failed to Execute returning error %s", err.Error())
	}

	err = TemplateStyles.Execute(&b, nil)
	if err != nil {
		t.Errorf("template TemplateStyles failed to Execute returning error %s", err.Error())
	}

	err = TemplateStringLookups.Execute(&b, []string{})
	if err != nil {
		t.Errorf("template TemplateStringLookups failed to Execute returning error %s", err.Error())
	}

	sheet := struct {
		Cols  []Column
		Rows  []string
		Start string
		End   string
	}{
		Cols:  []Column{},
		Rows:  []string{},
		Start: "A1",
		End:   "C3",
	}

	err = TemplateSheetStart.Execute(&b, sheet)
	if err != nil {
		t.Errorf("template TemplateSheetStart failed to Execute returning error %s", err.Error())
	}

	for i, _ := range sheet.Rows {
		rb := &bytes.Buffer{}
		rowString := fmt.Sprintf(`<row r="%d">%s</row>`, uint64(i), rb.String())
		_, err = io.WriteString(&b, rowString)
	}
}
<|endoftext|>


<commit_before>package xmlstream

import (
	"encoding/xml"
	"io"
	"reflect"
	"sync"
)

// Tag is the interface implemented by the objects that can be unmarshalled
// by the Parse function.
//
// The method TagName should returns the local name of the XML element to
// unmarshal.
//
// The objects implementing this interface are similar to those passed to
// the function xml.Unmarshal (http://golang.org/pkg/encoding/xml/#Unmarshal).
type Tag interface {
	TagName() string
}

// Handler is the interface implemented by objects that can handle
// the unmarshalled Tag passed as a parameter.
//
// Note that the parameter t is a pointer to the underlying Tag element.
type Handler interface {
	HandleTag(t interface{})
}

// Parse streams an XML file and unmarshals the xml elements it encounters as soon
// as they match the tag name of one of the tags parameters. A pointer to the
// unmarshalled tag is then passed to the method HandleTag` of the handler.
//
// If the parameter maxRoutines is equals to zero, `HandleTag` is always called
// sequentially. If this parameter is greater than zero, at most maxRoutines
// goroutines will be started. When no more goroutines are available, the callback
// is called sequentially. If the parameter is negative, the parser will launch
// as many goroutines as needed. It is equivalent to set maxRoutines to the
// maximum int32 value.
func Parse(r io.Reader, handler Handler, maxRoutines int32, tags ...Tag) error {
	var (
		// Number of goroutines currently running.
		rRoutines int32 = 0

		// Mapping between the xml local name and  the underlying type of a Tag.
		nameToType map[string]reflect.Type = make(map[string]reflect.Type)

		// XML decoder.
		decoder *xml.Decoder = xml.NewDecoder(r)

		// Waiting group used to wait for all the goroutines to finish.
		// See http://golang.org/pkg/sync/#example_WaitGroup
		wg sync.WaitGroup
	)

	// Map the xml local name of a Tag to its underlying type.
	nameToType = make(map[string]reflect.Type)
	for _, tag := range tags {
		t := reflect.TypeOf(tag)
		nameToType[tag.TagName()] = t
	}

	// Negative value for `maxRoutines` is equivalent of assigning it
	// to the maximal int32 value. In other words, allow the parser
	// to launch as many goroutines as needed.
	if maxRoutines < 0 {
		maxRoutines = 2147483647 // max int32
	}

	// Wait for all the goroutines to complete before returning.
	defer wg.Wait()

	for {
		// Read tokens from the XML document in a stream.
		token, err := decoder.Token()
		if err != nil {
			if err == io.EOF {
				// End of file. Expected behavior.
				err = nil
			}
			return err
		}
		// Inspect the type of the token just read.
		switch el := token.(type) {
		case xml.StartElement:
			// Read the tag name and compare with the XML element.
			if tagType, ok := nameToType[el.Name.Local]; ok {
				// create a new tag
				tag := reflect.New(tagType).Interface()
				// Decode a whole chunk of following XML.
				err := decoder.DecodeElement(tag, &el)
				if err != nil {
					return err
				}

				// Do some stuff with the retrieved object...
				if rRoutines < maxRoutines {
					// ...In parallel ツ
					wg.Add(1)
					rRoutines++
					go func() {
						defer func() {
							wg.Done()
							rRoutines--
						}()
						handler.HandleTag(tag)
					}()
				} else {
					// ...Sequentially.
					handler.HandleTag(tag)
				}
			}
		}
	}
	return nil
}
<commit_msg>First draft of a new, simpler design<commit_after>package xmlstream

import (
	"encoding/xml"
	"io"
	"reflect"
)

// Tag is the interface implemented by the objects that can be unmarshalled
// by the Parse function.
//
// The method TagName should returns the local name of the XML element to
// unmarshal.
//
// The objects implementing this interface are similar to those passed to
// the function xml.Unmarshal (http://golang.org/pkg/encoding/xml/#Unmarshal).
type Tag interface {
	TagName() string
}

type Scanner struct {
	decoder    *xml.Decoder
	tags       []Tag
	latestTag  *Tag
	nameToType map[string]reflect.Type // map xml local name to Tag's type
	err        error
}

func NewScanner(r io.Reader, tags ...Tag) *Scanner {
	s := Scanner{
		decoder:    xml.NewDecoder(r),
		tags:       tags,
		nameToType: make(map[string]reflect.Type, len(tags)),
	}

	// Map the xml local name of a Tag to its underlying type.
	for _, tag := range s.tags {
		t := reflect.TypeOf(tag)
		s.nameToType[tag.TagName()] = t
	}
	return &s
}

func (s *Scanner) Scan() bool {
	if (*s).err != nil {
		return false
	}
	// Read next token.
	token, err := (*s).decoder.Token()
	if err != nil {
		(*s).latestTag = nil
		(*s).err = err
		return false
	}
	// Inspect the type of the token.
	switch el := token.(type) {
	case xml.StartElement:
		// Read the tag name and compare with the XML element.
		if tagType, ok := (*s).nameToType[el.Name.Local]; ok {
			// create a new tag
			tag := reflect.New(tagType).Interface()
			// Decode a whole chunk of following XML.
			err := (*s).decoder.DecodeElement(tag, &el)
			(*s).latestTag = nil
			(*s).err = err
			return err != nil
		}
	}
}

// Tag output a pointer to the next Tag.
func (s *Scanner) Tag() *Tag {
	return (*s).latestTag
}

func (s *Scanner) ReadErr() error {
	if (*s).err != nil && (*s).err != io.EOF {
		return (*s).err
	}
	return nil
}
<|endoftext|>


<commit_before>package cluster

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

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

	nID := NextID(10)

	msgToEncode := message{NodeID: 1, MsgType: NEXT_ID_RESPONSE, Body: nID.Bytes()}
	bytes, err := msgToEncode.encode()
	a.Nil(err)

	decodedMsg, err := decode(bytes)
	a.Nil(err)
	a.Equal(decodedMsg.Type, NEXT_ID_RESPONSE)
	a.Equal(decodedMsg.NodeID, 1)

	nextID, err := DecodeNextID(decodedMsg.Body)
	a.Nil(err)
	a.Equal(int(*nextID), 10)
}
<commit_msg>Fix for tests<commit_after>package cluster

import (
	"github.com/stretchr/testify/assert"
	"testing"
)

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

	nID := NextID(10)

	msgToEncode := message{NodeID: 1, Type: NEXT_ID_RESPONSE, Body: nID.Bytes()}
	bytes, err := msgToEncode.encode()
	a.Nil(err)

	decodedMsg, err := decode(bytes)
	a.Nil(err)
	a.Equal(decodedMsg.Type, NEXT_ID_RESPONSE)
	a.Equal(decodedMsg.NodeID, 1)

	nextID, err := DecodeNextID(decodedMsg.Body)
	a.Nil(err)
	a.Equal(int(*nextID), 10)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"os"
	"strings"

	"github.com/gopherjs/gopherjs/js"

	"mvdan.cc/sh/syntax"
)

func main() {
	exps := js.Module.Get("exports")

	exps.Set("syntax", map[string]interface{}{})

	stx := exps.Get("syntax")
	stx.Set("NodeType", func(v interface{}) (typ string) {
		if v == nil {
			return "nil"
		}
		node, ok := v.(syntax.Node)
		if !ok {
			throw("NodeType requires a Node argument")
		}
		typ = fmt.Sprintf("%T", node)
		if i := strings.LastIndexAny(typ, "*.]"); i >= 0 {
			typ = typ[i+1:]
		}
		return typ
	})

	stx.Set("NewParser", func() *js.Object {
		p := syntax.NewParser()
		return js.MakeWrapper(jsParser{p})
	})

	stx.Set("Walk", func(node syntax.Node, jsFn func(*js.Object) bool) {
		f := func(node syntax.Node) bool {
			if node == nil {
				return jsFn(nil)
			}
			return jsFn(js.MakeWrapper(node))
		}
		syntax.Walk(node, f)

	})
	stx.Set("DebugPrint", func(node syntax.Node) {
		syntax.DebugPrint(os.Stdout, node)
	})

	stx.Set("NewPrinter", func() *js.Object {
		p := syntax.NewPrinter()
		return js.MakeWrapper(jsPrinter{p})
	})
}

func throw(v interface{}) {
	js.Global.Call("$throwRuntimeError", fmt.Sprint(v))
}

type jsParser struct {
	*syntax.Parser
}

func (p jsParser) Parse(src, name string) *js.Object {
	f, err := p.Parser.Parse(strings.NewReader(src), name)
	if err != nil {
		throw(err)
	}
	return js.MakeWrapper(f)
}

type jsPrinter struct {
	*syntax.Printer
}

func (p jsPrinter) Print(file *syntax.File) string {
	var buf bytes.Buffer
	if err := p.Printer.Print(&buf, file); err != nil {
		throw(err)
	}
	return buf.String()
}
<commit_msg>_js: use gopherjs/js.MakeFullWrapper<commit_after>package main

import (
	"bytes"
	"fmt"
	"os"
	"strings"

	"github.com/gopherjs/gopherjs/js"

	"mvdan.cc/sh/syntax"
)

func main() {
	exps := js.Module.Get("exports")

	exps.Set("syntax", map[string]interface{}{})

	stx := exps.Get("syntax")
	stx.Set("NodeType", func(v interface{}) (typ string) {
		if v == nil {
			return "nil"
		}
		node, ok := v.(syntax.Node)
		if !ok {
			throw("NodeType requires a Node argument")
		}
		typ = fmt.Sprintf("%T", node)
		if i := strings.LastIndexAny(typ, "*.]"); i >= 0 {
			typ = typ[i+1:]
		}
		return typ
	})

	stx.Set("NewParser", func() *js.Object {
		p := syntax.NewParser()
		return js.MakeFullWrapper(jsParser{p})
	})

	stx.Set("Walk", func(node syntax.Node, jsFn func(*js.Object) bool) {
		f := func(node syntax.Node) bool {
			if node == nil {
				return jsFn(nil)
			}
			return jsFn(js.MakeFullWrapper(node))
		}
		syntax.Walk(node, f)

	})
	stx.Set("DebugPrint", func(node syntax.Node) {
		syntax.DebugPrint(os.Stdout, node)
	})

	stx.Set("NewPrinter", func() *js.Object {
		p := syntax.NewPrinter()
		return js.MakeFullWrapper(jsPrinter{p})
	})
}

func throw(v interface{}) {
	js.Global.Call("$throwRuntimeError", fmt.Sprint(v))
}

type jsParser struct {
	*syntax.Parser
}

func (p jsParser) Parse(src, name string) *js.Object {
	f, err := p.Parser.Parse(strings.NewReader(src), name)
	if err != nil {
		throw(err)
	}
	return js.MakeFullWrapper(f)
}

type jsPrinter struct {
	*syntax.Printer
}

func (p jsPrinter) Print(file *syntax.File) string {
	var buf bytes.Buffer
	if err := p.Printer.Print(&buf, file); err != nil {
		throw(err)
	}
	return buf.String()
}
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"errors"
	"io/ioutil"
	"strings"
)

// CPUStats represente les stats CPU
type CPUStats struct {
	User    uint64
	Nice    uint64
	Sys     uint64
	Idle    uint64
	Wait    uint64
	Irq     uint64
	SoftIrq uint64
	Stolen  uint64
}

// Sum adds all "stats" (cpu time)
func (s *CPUStats) Sum() uint64 {
	return s.Idle + s.Irq + s.Nice + s.SoftIrq + s.Stolen + s.Sys + s.User + s.Wait
}

// GetCPUStats retourne les stats CPU
func GetCPUStats() (*map[string]CPUStats, error) {
	procStats, err := ioutil.ReadFile("/proc/stat")
	if err != nil {
		return nil, err
	}
	scanner := bufio.NewScanner(bytes.NewReader(procStats))
	cStats := make(map[string]CPUStats)
	for scanner.Scan() {
		line := scanner.Text()
		if !strings.HasPrefix(line, "cpu") {
			continue
		}
		parts := strings.Fields(line)
		if len(parts) < 8 {
			return nil, errors.New("bad data found in /proc/stat - " + line)
		}
		cStats[parts[0]] = CPUStats{
			User:    parseUint64(parts[1]),
			Nice:    parseUint64(parts[2]),
			Sys:     parseUint64(parts[3]),
			Idle:    parseUint64(parts[4]),
			Wait:    parseUint64(parts[5]),
			Irq:     parseUint64(parts[6]),
			SoftIrq: parseUint64(parts[7]),
			Stolen:  parseUint64(parts[8]),
		}
	}
	return &cStats, nil
}
<commit_msg>Update cpu.go<commit_after>package main

import (
	"bufio"
	"bytes"
	"errors"
	"io/ioutil"
	"strings"
)

// CPUStats represente les stats CPU
type CPUStats struct {
	User    uint64
	Nice    uint64
	Sys     uint64
	Idle    uint64
	Wait    uint64
	Irq     uint64
	SoftIrq uint64
	Stolen  uint64
}

// Sum adds all "stats" (cpu time)
func (s *CPUStats) Sum() uint64 {
	return s.Idle + s.Irq + s.Nice + s.SoftIrq + s.Stolen + s.Sys + s.User + s.Wait
}

// GetCPUStats retourne les stats CPU
func GetCPUStats() (*map[string]CPUStats, error) {
	procStats, err := ioutil.ReadFile("/proc/stat")
	if err != nil {
		return nil, err
	}
	scanner := bufio.NewScanner(bytes.NewReader(procStats))
	cStats := make(map[string]CPUStats)
	for scanner.Scan() {
		line := scanner.Text()
		if !strings.HasPrefix(line, "cpu ") {
			continue
		}
		parts := strings.Fields(line)
		if len(parts) < 8 {
			return nil, errors.New("bad data found in /proc/stat - " + line)
		}
		cStats[parts[0]] = CPUStats{
			User:    parseUint64(parts[1]),
			Nice:    parseUint64(parts[2]),
			Sys:     parseUint64(parts[3]),
			Idle:    parseUint64(parts[4]),
			Wait:    parseUint64(parts[5]),
			Irq:     parseUint64(parts[6]),
			SoftIrq: parseUint64(parts[7]),
			Stolen:  parseUint64(parts[8]),
		}
	}
	return &cStats, nil
}
<|endoftext|>


<commit_before>// Copyright 2009 Thomas Jager <mail@jager.no> All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Driver for ADAM-4000 series I/O Modules from Advantech

package main

import (
	"bufio"
	"encoding/hex"
	"strconv"
	"strings"
)

func NewADAM4000(addr byte, rc *bufio.Reader, wc *bufio.Writer) *ADAM4000 {
	return &ADAM4000{address: addr, rc: rc, wc: wc, Value: make([]float64, 8)}
}

func (a *ADAM4000) GetName() (string, error) {
	resp, err := a.comResF("$%02XM\r", a.address)
	if err != nil {
		return "", err
	}
	a.Name = strings.Trim(string(resp[3:]), "\r ")
	return a.Name, nil
}

func (a *ADAM4000) GetAllValue() ([]float64, error) {
	resp, err := a.comResF("#%02X\r", a.address)
	if err != nil {
		return nil, err
	}
	values := string(resp[1:])
	a.Value[0], err = strconv.ParseFloat(values[0:7], 64)
	a.Value[1], err = strconv.ParseFloat(values[7:14], 64)
	a.Value[2], err = strconv.ParseFloat(values[14:21], 64)
	a.Value[3], err = strconv.ParseFloat(values[21:28], 64)
	a.Value[4], err = strconv.ParseFloat(values[28:35], 64)
	a.Value[5], err = strconv.ParseFloat(values[35:42], 64)
	a.Value[6], err = strconv.ParseFloat(values[42:49], 64)
	a.Value[7], err = strconv.ParseFloat(values[49:56], 64)
	return a.Value, err
}

func (a *ADAM4000) GetChannelValue(n int) (float64, error) {
	resp, err := a.comResF("#%02X%d\r", a.address, n)
	if err != nil {
		return float64(0), err
	}
	values := string(resp[1:])
	a.Value[n], err = strconv.ParseFloat(values[0:7], 64)
	return a.Value[n], err
}

func (a *ADAM4000) GetVersion() (string, error) {
	resp, err := a.comResF("$%02XF\r", a.address)
	if err != nil {
		return "", err
	}
	a.Version = strings.Trim(string(resp[3:]), "\r ")
	return a.Version, nil
}

func (a *ADAM4000) SetChannelRange(channel int, rangec InputRangeCode) error {
	_, err := a.comResF("$%02X7C%dR%02X\r", a.address, channel, byte(rangec))
	if err != nil {
		return err
	}
	return nil
}

func (a *ADAM4000) GetChannelRange(channel int) (InputRangeCode, error) {
	resp, err := a.comResF("$%02X8C%d\r", a.address, channel)
	if err != nil {
		return 0, err
	}
	rangec := make([]byte, 1)
	hex.Decode(rangec, resp[6:8])
	return InputRangeCode(rangec[0]), nil
}

func (a *ADAM4000) SyncronizeRead() error {
	//Stub
	return nil
}

func (a *ADAM4000) SyncronizedValue() ([]float64, error) {
	//Stub
	return nil, nil
}

func (a *ADAM4000) GetConfig() error {
	resp, err := a.comResF("$%02X2\r", a.address)
	if err != nil {
		return err
	}

	addr := make([]byte, 1)
	typecode := make([]byte, 1)
	baud := make([]byte, 1)
	data := make([]byte, 1)

	hex.Decode(addr, resp[1:3])
	hex.Decode(typecode, resp[3:5])
	hex.Decode(baud, resp[5:7])
	hex.Decode(data, resp[7:9])

	a.Address = addr[0]
	a.InputRange = InputRangeCode(typecode[0])
	a.BaudRate = BaudRateCode(baud[0])
	return nil
}
<commit_msg>SetConfig<commit_after>// Copyright 2009 Thomas Jager <mail@jager.no> All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Driver for ADAM-4000 series I/O Modules from Advantech

package main

import (
	"bufio"
	"encoding/hex"
	"fmt"
	"strconv"
	"strings"
)

func NewADAM4000(addr byte, rc *bufio.Reader, wc *bufio.Writer) *ADAM4000 {
	return &ADAM4000{address: addr, rc: rc, wc: wc, Value: make([]float64, 8)}
}

func (a *ADAM4000) GetName() (string, error) {
	resp, err := a.comResF("$%02XM\r", a.address)
	if err != nil {
		return "", err
	}
	a.Name = strings.Trim(string(resp[3:]), "\r ")
	return a.Name, nil
}

func (a *ADAM4000) GetAllValue() ([]float64, error) {
	resp, err := a.comResF("#%02X\r", a.address)
	if err != nil {
		return nil, err
	}
	values := string(resp[1:])
	fmt.Printf("%d\n", len(values))
	if len(values) == 57 {
		a.Value[0], err = strconv.ParseFloat(values[0:7], 64)
		a.Value[1], err = strconv.ParseFloat(values[7:14], 64)
		a.Value[2], err = strconv.ParseFloat(values[14:21], 64)
		a.Value[3], err = strconv.ParseFloat(values[21:28], 64)
		a.Value[4], err = strconv.ParseFloat(values[28:35], 64)
		a.Value[5], err = strconv.ParseFloat(values[35:42], 64)
		a.Value[6], err = strconv.ParseFloat(values[42:49], 64)
		a.Value[7], err = strconv.ParseFloat(values[49:56], 64)
	} else {
		intvals := make([]int64, 8)
		intvals[0], err = strconv.ParseInt(values[0:4], 16, 64)
		intvals[1], err = strconv.ParseInt(values[4:8], 16, 64)
		intvals[2], err = strconv.ParseInt(values[8:12], 16, 64)
		intvals[3], err = strconv.ParseInt(values[12:16], 16, 64)
		intvals[4], err = strconv.ParseInt(values[16:20], 16, 64)
		intvals[5], err = strconv.ParseInt(values[20:24], 16, 64)
		intvals[6], err = strconv.ParseInt(values[24:28], 16, 64)
		intvals[7], err = strconv.ParseInt(values[28:32], 16, 64)
		a.Value[0] = float64(intvals[0])
		a.Value[1] = float64(intvals[1])
		a.Value[2] = float64(intvals[2])
		a.Value[3] = float64(intvals[3])
		a.Value[4] = float64(intvals[4])
		a.Value[5] = float64(intvals[5])
		a.Value[6] = float64(intvals[6])
		a.Value[7] = float64(intvals[7])
	}
	return a.Value, err
}

func (a *ADAM4000) GetChannelValue(n int) (float64, error) {
	resp, err := a.comResF("#%02X%d\r", a.address, n)
	if err != nil {
		return float64(0), err
	}
	values := string(resp[1:])
	if len(values) == 7 {
		a.Value[n], err = strconv.ParseFloat(values[0:7], 64)
	} else {
		intval, _ := strconv.ParseInt(values[0:4], 16, 64)
		a.Value[n] = float64(intval)
	}
	return a.Value[n], err
}

func (a *ADAM4000) GetVersion() (string, error) {
	resp, err := a.comResF("$%02XF\r", a.address)
	if err != nil {
		return "", err
	}
	a.Version = strings.Trim(string(resp[3:]), "\r ")
	return a.Version, nil
}

func (a *ADAM4000) SetChannelRange(channel int, rangec InputRangeCode) error {
	_, err := a.comResF("$%02X7C%dR%02X\r", a.address, channel, byte(rangec))
	if err != nil {
		return err
	}
	return nil
}

func (a *ADAM4000) GetChannelRange(channel int) (InputRangeCode, error) {
	resp, err := a.comResF("$%02X8C%d\r", a.address, channel)
	if err != nil {
		return 0, err
	}
	rangec := make([]byte, 1)
	hex.Decode(rangec, resp[6:8])
	return InputRangeCode(rangec[0]), nil
}

func (a *ADAM4000) SyncronizeRead() error {
	//Stub
	return nil
}

func (a *ADAM4000) SyncronizedValue() ([]float64, error) {
	//Stub
	return nil, nil
}

func (a *ADAM4000) GetConfig() error {
	resp, err := a.comResF("$%02X2\r", a.address)
	if err != nil {
		return err
	}

	addr := make([]byte, 1)
	typecode := make([]byte, 1)
	baud := make([]byte, 1)
	data := make([]byte, 1)

	hex.Decode(addr, resp[1:3])
	hex.Decode(typecode, resp[3:5])
	hex.Decode(baud, resp[5:7])
	hex.Decode(data, resp[7:9])

	a.Address = addr[0]
	a.InputRange = InputRangeCode(typecode[0])
	a.BaudRate = BaudRateCode(baud[0])
	fmt.Printf("%X\n", data)
	a.Integration_time = data[0]&byte(1<<7) > 0
	a.Checksum = data[0]&byte(1<<6) > 0
	a.DataFormat = DataFormatCode(data[0] & byte(2))
	if a.Address != a.address {
		fmt.Printf("Warning: Configured address (%d) differs from connected address (%d), in init mode?\n", a.Address, a.address)
	}
	return nil
}

func (a *ADAM4000) SetConfig() error {
	data := byte(a.DataFormat)
	if a.Integration_time {
		data |= byte(1 << 7)
	}
	if a.Checksum {
		data |= byte(1 << 6)
	}

	_, err := a.comResF("%%%02X%02XFF%02X%02X\r", a.address, a.Address, byte(a.BaudRate), data)
	return err
}
<|endoftext|>


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

package w32

import (
  "fmt"
  "syscall"
  "unsafe"
)

var (
  modadvapi32 = syscall.NewLazyDLL("advapi32.dll")

  procRegOpenKeyEx       = modadvapi32.NewProc("RegOpenKeyExW")
  procRegCloseKey        = modadvapi32.NewProc("RegCloseKey")
  procRegGetValue        = modadvapi32.NewProc("RegGetValueW")
  procRegEnumKeyEx       = modadvapi32.NewProc("RegEnumKeyExW")
  procRegSetKeyValue     = modadvapi32.NewProc("RegSetKeyValueW")
  procOpenEventLog       = modadvapi32.NewProc("OpenEventLogW")
  procReadEventLog       = modadvapi32.NewProc("ReadEventLogW")
  procCloseEventLog      = modadvapi32.NewProc("CloseEventLog")
  procRegOpenKeyEx       = modadvapi32.NewProc("RegOpenKeyExW")
  procRegCloseKey        = modadvapi32.NewProc("RegCloseKey")
  procRegGetValue        = modadvapi32.NewProc("RegGetValueW")
  procRegEnumKeyEx       = modadvapi32.NewProc("RegEnumKeyExW")
  procRegSetKeyValue     = modadvapi32.NewProc("RegSetKeyValueW")
  procOpenSCManager      = modadvapi32.NewProc("OpenSCManagerW")
  procCloseServiceHandle = modadvapi32.NewProc("CloseServiceHandle")
  procOpenService        = modadvapi32.NewProc("OpenServiceW")
  procStartService       = modadvapi32.NewProc("StartServiceW")
  procControlService     = modadvapi32.NewProc("ControlService")
)

func RegOpenKeyEx(hKey HKEY, subKey string, samDesired uint32) HKEY {
  var result HKEY
  ret, _, _ := procRegOpenKeyEx.Call(
    uintptr(hKey),
    uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
    uintptr(0),
    uintptr(samDesired),
    uintptr(unsafe.Pointer(&result)))

  if ret != ERROR_SUCCESS {
    panic(fmt.Sprintf("RegOpenKeyEx(%d, %s, %d) failed", hKey, subKey, samDesired))
  }
  return result
}

func RegCloseKey(hKey HKEY) {
  ret, _, _ := procRegCloseKey.Call(
    uintptr(hKey))

  if ret != ERROR_SUCCESS {
    panic(fmt.Sprintf("RegCloseKey(%d) failed", hKey))
  }
}

func RegGetString(hKey HKEY, subKey string, value string) string {
  var bufLen uint32
  procRegGetValue.Call(
    uintptr(hKey),
    uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
    uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))),
    uintptr(RRF_RT_REG_SZ),
    0,
    0,
    uintptr(unsafe.Pointer(&bufLen)))

  if bufLen == 0 {
    return ""
  }

  buf := make([]uint16, bufLen)
  ret, _, _ := procRegGetValue.Call(
    uintptr(hKey),
    uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
    uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))),
    uintptr(RRF_RT_REG_SZ),
    0,
    uintptr(unsafe.Pointer(&buf[0])),
    uintptr(unsafe.Pointer(&bufLen)))

  if ret != ERROR_SUCCESS {
    return ""
  }

  return syscall.UTF16ToString(buf)
}

func RegSetKeyValue(hKey HKEY, subKey string, valueName string, dwType DWORD, data uintptr, cbData uint16) (errno int) {
  ret, _, _ := procRegSetKeyValue.Call(
    uintptr(hKey),
    uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
    uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(valueName))),
    uintptr(dwType),
    data,
    uintptr(cbData))

  return int(ret)
}

func RegEnumKeyEx(hKey HKEY, index DWORD) string {
  var bufLen uint32 = 255
  buf := make([]uint16, bufLen)
  procRegEnumKeyEx.Call(
    uintptr(hKey),
    uintptr(index),
    uintptr(unsafe.Pointer(&buf[0])),
    uintptr(unsafe.Pointer(&bufLen)),
    0,
    0,
    0,
    0)
  return syscall.UTF16ToString(buf)
}

func OpenEventLog(servername, sourcename *uint16) HANDLE {
  ret, _, _ := procOpenEventLog.Call(
    uintptr(unsafe.Pointer(servername)),
    uintptr(unsafe.Pointer(sourcename)))

  return HANDLE(ret)
}

func ReadEventLog(eventlog HANDLE, readflags, recordoffset uint32, buffer []byte, numberofbytestoread uint32, bytesread, minnumberofbytesneeded *uint32) bool {
  ret, _, _ := procReadEventLog.Call(
    uintptr(eventlog),
    uintptr(readflags),
    uintptr(recordoffset),
    uintptr(unsafe.Pointer(&buffer[0])),
    uintptr(numberofbytestoread),
    uintptr(unsafe.Pointer(bytesread)),
    uintptr(unsafe.Pointer(minnumberofbytesneeded)))

  return ret != 0
}

func CloseEventLog(eventlog HANDLE) bool {
  ret, _, _ := procCloseEventLog.Call(
    uintptr(eventlog))

  return ret != 0
}

func OpenSCManager(lpMachineName, lpDatabaseName string, dwDesiredAccess DWORD) (HANDLE, error) {
  var p1, p2 uintptr
  if len(lpMachineName) > 0 {
    p1 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpMachineName)))
  }
  if len(lpDatabaseName) > 0 {
    p2 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDatabaseName)))
  }
  ret, _, _ := procOpenSCManager.Call(
    p1,
    p2,
    uintptr(dwDesiredAccess))

  if ret == 0 {
    return 0, syscall.GetLastError()
  }

  return HANDLE(ret), nil
}

func CloseServiceHandle(hSCObject HANDLE) error {
  ret, _, _ := procCloseServiceHandle.Call(uintptr(hSCObject))
  if ret == 0 {
    return syscall.GetLastError()
  }
  return nil
}

func OpenService(hSCManager HANDLE, lpServiceName string, dwDesiredAccess DWORD) (HANDLE, error) {
  ret, _, _ := procOpenService.Call(
    uintptr(hSCManager),
    uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceName))),
    uintptr(dwDesiredAccess))

  if ret == 0 {
    return 0, syscall.GetLastError()
  }

  return HANDLE(ret), nil
}

func StartService(hService HANDLE, lpServiceArgVectors []string) error {
  l := len(lpServiceArgVectors)
  var ret uintptr
  if l == 0 {
    ret, _, _ = procStartService.Call(
      uintptr(hService),
      0,
      0)
  } else {
    lpArgs := make([]uintptr, l)
    for i := 0; i < l; i++ {
      lpArgs[i] = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceArgVectors[i])))
    }

    ret, _, _ = procStartService.Call(
      uintptr(hService),
      uintptr(l),
      uintptr(unsafe.Pointer(&lpArgs[0])))
  }

  if ret == 0 {
    return syscall.GetLastError()
  }

  return nil
}

func ControlService(hService HANDLE, dwControl DWORD, lpServiceStatus *SERVICE_STATUS) bool {
  if lpServiceStatus == nil {
    panic("ControlService:lpServiceStatus cannot be nil")
  }

  ret, _, _ := procControlService.Call(
    uintptr(hService),
    uintptr(dwControl),
    uintptr(unsafe.Pointer(lpServiceStatus)))

  return ret != 0
}
<commit_msg>fix double procs<commit_after>// Copyright 2010 The W32 Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package w32

import (
    "fmt"
    "syscall"
    "unsafe"
)

var (
    modadvapi32 = syscall.NewLazyDLL("advapi32.dll")

    procRegOpenKeyEx       = modadvapi32.NewProc("RegOpenKeyExW")
    procRegCloseKey        = modadvapi32.NewProc("RegCloseKey")
    procRegGetValue        = modadvapi32.NewProc("RegGetValueW")
    procRegEnumKeyEx       = modadvapi32.NewProc("RegEnumKeyExW")
    procRegSetKeyValue     = modadvapi32.NewProc("RegSetKeyValueW")
    procOpenEventLog       = modadvapi32.NewProc("OpenEventLogW")
    procReadEventLog       = modadvapi32.NewProc("ReadEventLogW")
    procCloseEventLog      = modadvapi32.NewProc("CloseEventLog")
    procOpenSCManager      = modadvapi32.NewProc("OpenSCManagerW")
    procCloseServiceHandle = modadvapi32.NewProc("CloseServiceHandle")
    procOpenService        = modadvapi32.NewProc("OpenServiceW")
    procStartService       = modadvapi32.NewProc("StartServiceW")
    procControlService     = modadvapi32.NewProc("ControlService")
)

func RegOpenKeyEx(hKey HKEY, subKey string, samDesired uint32) HKEY {
    var result HKEY
    ret, _, _ := procRegOpenKeyEx.Call(
        uintptr(hKey),
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
        uintptr(0),
        uintptr(samDesired),
        uintptr(unsafe.Pointer(&result)))

    if ret != ERROR_SUCCESS {
        panic(fmt.Sprintf("RegOpenKeyEx(%d, %s, %d) failed", hKey, subKey, samDesired))
    }
    return result
}

func RegCloseKey(hKey HKEY) {
    ret, _, _ := procRegCloseKey.Call(
        uintptr(hKey))

    if ret != ERROR_SUCCESS {
        panic(fmt.Sprintf("RegCloseKey(%d) failed", hKey))
    }
}

func RegGetString(hKey HKEY, subKey string, value string) string {
    var bufLen uint32
    procRegGetValue.Call(
        uintptr(hKey),
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))),
        uintptr(RRF_RT_REG_SZ),
        0,
        0,
        uintptr(unsafe.Pointer(&bufLen)))

    if bufLen == 0 {
        return ""
    }

    buf := make([]uint16, bufLen)
    ret, _, _ := procRegGetValue.Call(
        uintptr(hKey),
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))),
        uintptr(RRF_RT_REG_SZ),
        0,
        uintptr(unsafe.Pointer(&buf[0])),
        uintptr(unsafe.Pointer(&bufLen)))

    if ret != ERROR_SUCCESS {
        return ""
    }

    return syscall.UTF16ToString(buf)
}

func RegSetKeyValue(hKey HKEY, subKey string, valueName string, dwType DWORD, data uintptr, cbData uint16) (errno int) {
    ret, _, _ := procRegSetKeyValue.Call(
        uintptr(hKey),
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))),
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(valueName))),
        uintptr(dwType),
        data,
        uintptr(cbData))

    return int(ret)
}

func RegEnumKeyEx(hKey HKEY, index DWORD) string {
    var bufLen uint32 = 255
    buf := make([]uint16, bufLen)
    procRegEnumKeyEx.Call(
        uintptr(hKey),
        uintptr(index),
        uintptr(unsafe.Pointer(&buf[0])),
        uintptr(unsafe.Pointer(&bufLen)),
        0,
        0,
        0,
        0)
    return syscall.UTF16ToString(buf)
}

func OpenEventLog(servername, sourcename *uint16) HANDLE {
    ret, _, _ := procOpenEventLog.Call(
        uintptr(unsafe.Pointer(servername)),
        uintptr(unsafe.Pointer(sourcename)))

    return HANDLE(ret)
}

func ReadEventLog(eventlog HANDLE, readflags, recordoffset uint32, buffer []byte, numberofbytestoread uint32, bytesread, minnumberofbytesneeded *uint32) bool {
    ret, _, _ := procReadEventLog.Call(
        uintptr(eventlog),
        uintptr(readflags),
        uintptr(recordoffset),
        uintptr(unsafe.Pointer(&buffer[0])),
        uintptr(numberofbytestoread),
        uintptr(unsafe.Pointer(bytesread)),
        uintptr(unsafe.Pointer(minnumberofbytesneeded)))

    return ret != 0
}

func CloseEventLog(eventlog HANDLE) bool {
    ret, _, _ := procCloseEventLog.Call(
        uintptr(eventlog))

    return ret != 0
}

func OpenSCManager(lpMachineName, lpDatabaseName string, dwDesiredAccess DWORD) (HANDLE, error) {
    var p1, p2 uintptr
    if len(lpMachineName) > 0 {
        p1 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpMachineName)))
    }
    if len(lpDatabaseName) > 0 {
        p2 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDatabaseName)))
    }
    ret, _, _ := procOpenSCManager.Call(
        p1,
        p2,
        uintptr(dwDesiredAccess))

    if ret == 0 {
        return 0, syscall.GetLastError()
    }

    return HANDLE(ret), nil
}

func CloseServiceHandle(hSCObject HANDLE) error {
    ret, _, _ := procCloseServiceHandle.Call(uintptr(hSCObject))
    if ret == 0 {
        return syscall.GetLastError()
    }
    return nil
}

func OpenService(hSCManager HANDLE, lpServiceName string, dwDesiredAccess DWORD) (HANDLE, error) {
    ret, _, _ := procOpenService.Call(
        uintptr(hSCManager),
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceName))),
        uintptr(dwDesiredAccess))

    if ret == 0 {
        return 0, syscall.GetLastError()
    }

    return HANDLE(ret), nil
}

func StartService(hService HANDLE, lpServiceArgVectors []string) error {
    l := len(lpServiceArgVectors)
    var ret uintptr
    if l == 0 {
        ret, _, _ = procStartService.Call(
            uintptr(hService),
            0,
            0)
    } else {
        lpArgs := make([]uintptr, l)
        for i := 0; i < l; i++ {
            lpArgs[i] = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceArgVectors[i])))
        }

        ret, _, _ = procStartService.Call(
            uintptr(hService),
            uintptr(l),
            uintptr(unsafe.Pointer(&lpArgs[0])))
    }

    if ret == 0 {
        return syscall.GetLastError()
    }

    return nil
}

func ControlService(hService HANDLE, dwControl DWORD, lpServiceStatus *SERVICE_STATUS) bool {
    if lpServiceStatus == nil {
        panic("ControlService:lpServiceStatus cannot be nil")
    }

    ret, _, _ := procControlService.Call(
        uintptr(hService),
        uintptr(dwControl),
        uintptr(unsafe.Pointer(lpServiceStatus)))

    return ret != 0
}
<|endoftext|>


<commit_before>package main

import "fmt"
import "net/http"
import "io/ioutil"

func check(err error, message string) {
	if err != nil {
		panic(err)
	}
	fmt.Println(message)
}

func main() {
	fmt.Println("starting http client to get http://localhost:8080/message")

	resp, err := http.Get("http://localhost:8080/message")
	check(err, "")

	defer resp.Body.Close()

	message, err := ioutil.ReadAll(resp.Body)
	check(err, "")

	fmt.Println("message :", string(message))

	fmt.Println("exit 0")
}
<commit_msg>update httpclient<commit_after>package main

import "fmt"
import "net/http"
import "io/ioutil"

func check(err error, message string) {
	if err != nil {
		panic(err)
	}
	fmt.Println(message)
}

func main() {
	data := "message"

	fmt.Println("starting http client to get http://localhost:8080/" + data)

	resp, err := http.Get("http://localhost:8080/" + data)
	check(err, "")

	defer resp.Body.Close()

	message, err := ioutil.ReadAll(resp.Body)
	check(err, "")

	fmt.Println("message :", string(message))

	fmt.Println("exit 0")
}
<|endoftext|>


<commit_before>package formula

import (
	"bytes"
	"fmt"
	"strconv"
	"strings"
	"text/scanner"
)

// This VM is quite simple, having only a general purpose
// register (R) and a boolean status register (S).
// Some instructions might contain an integer value (V):
//
//  N - set R = n
//  ADD - set R = R + V
//  SUB - set R = R - V
//  MULT - set R = R * V
//  DIV - set R = R / V
//  MOD - set R = R % V
//  JMPT - jump by V if S is true
//  JMPF - jump by V if S is false
//  EQ - set S = (R == V)
//  NEQ - set S = (R != V)
//  LT - set S = (R < V)
//  LTE - set S = (R <= V)
//  GT - set S = (R > V)
//  GTE - set S = (R >= V)
//  RET - end execution and return V
//
// If the end of the program is reached without finding
// a ret instruction, the last value of S is returned.
// as an integer.

type opCode uint8

const (
	// Instructions altering R
	opN opCode = iota + 1
	opADD
	opSUB
	opMULT
	opDIV
	opMOD
	// Special instructions
	opRET
	// Jump instructions
	opJMPT
	opJMPF
	// Comparison instructions
	opEQ
	opNEQ
	opLT
	opLTE
	opGT
	opGTE
)

func (o opCode) String() string {
	names := []string{"N", "ADD", "SUB", "MULT", "DIV", "MOD", "RET", "JMPT", "JMPF", "EQ", "NEQ", "LT", "LTE", "GT", "GTE"}
	return names[int(o)-1]
}

func (o opCode) Alters() bool {
	return o <= opMOD
}

func (o opCode) IsSpecial() bool {
	return o == opRET
}

func (o opCode) IsJump() bool {
	return o == opJMPT || o == opJMPF
}

func (o opCode) Compares() bool {
	return o >= opEQ
}

type instruction struct {
	opCode opCode
	value  int
}

func invalid(s *scanner.Scanner, what, val string) ([]*instruction, error) {
	return nil, fmt.Errorf("invalid %s in formula at %s: %q", what, s.Pos(), val)
}

func jumpTarget(s *scanner.Scanner, form string, chr byte) int {
	// look for matching chr
	offset := s.Pos().Offset
	paren := 0
	target := -1
	for ii, v := range []byte(form[offset:]) {
		if v == '(' {
			paren++
		} else if v == ')' {
			paren--
			if paren < 0 {
				target = offset + ii
				break
			}
		} else if v == chr && paren == 0 {
			target = offset + ii
			break
		}
	}
	return target
}

func makeJump(s *scanner.Scanner, form string, code *[]*instruction, op opCode, jumps map[int][]*instruction, chr byte) {
	// end of conditional, put the placeholder for a jump
	// and complete it once we reach the matching chr. Store the
	// current position of the jump in its value, so
	// calculating the relative offset is quicker.
	pos := len(*code)
	inst := &instruction{opCode: op, value: pos}
	*code = append(*code, inst)
	target := jumpTarget(s, form, chr)
	jumps[target] = append(jumps[target], inst)
}

func resolveJumps(s *scanner.Scanner, code []*instruction, jumps map[int][]*instruction) {
	// check for incomplete jumps to this location.
	// the pc should point at the next instruction
	// to be added and the jump is relative.
	pc := len(code)
	offset := s.Pos().Offset - 1
	for _, v := range jumps[offset] {
		v.value = pc - v.value - 1
	}
	delete(jumps, offset)
}

func compileVmFormula(form string) (Formula, error) {
	code, err := vmCompile(form)
	if err != nil {
		return nil, err
	}
	code = vmOptimize(code)
	return makeVmFunc(code), nil
}

func vmCompile(form string) ([]*instruction, error) {
	var s scanner.Scanner
	var err error
	s.Init(strings.NewReader(form))
	s.Error = func(s *scanner.Scanner, msg string) {
		err = fmt.Errorf("error parsing plural formula %s: %s", s.Pos(), msg)
	}
	s.Mode = scanner.ScanIdents | scanner.ScanInts
	tok := s.Scan()
	var code []*instruction
	var op bytes.Buffer
	var logic bytes.Buffer
	jumps := make(map[int][]*instruction)
	for tok != scanner.EOF && err == nil {
		switch tok {
		case scanner.Ident:
			if n := s.TokenText(); n != "n" {
				return invalid(&s, "ident", n)
			}
			code = append(code, &instruction{opCode: opN})
		case scanner.Int:
			val, _ := strconv.Atoi(s.TokenText())
			if op.Len() == 0 {
				// return statement
				code = append(code, &instruction{opCode: opRET, value: val})
			} else {
				var opc opCode
				switch op.String() {
				case "+":
					opc = opADD
				case "-":
					opc = opSUB
				case "*":
					opc = opMULT
				case "/":
					opc = opDIV
				case "%":
					opc = opMOD
				case "==":
					opc = opEQ
				case "!=":
					opc = opNEQ
				case "<":
					opc = opLT
				case "<=":
					opc = opLTE
				case ">":
					opc = opGT
				case ">=":
					opc = opGTE
				default:
					return invalid(&s, "op", op.String())
				}
				code = append(code, &instruction{opCode: opc, value: val})
				op.Reset()
			}
		case '?':
			resolveJumps(&s, code, jumps)
			makeJump(&s, form, &code, opJMPF, jumps, ':')
		case ':':
			resolveJumps(&s, code, jumps)
		case '!', '=', '<', '>', '%':
			op.WriteRune(tok)
		case '&', '|':
			// logic operations
			if logic.Len() == 0 {
				logic.WriteRune(tok)
			} else if logic.Len() == 1 {
				b := logic.Bytes()[0]
				if b != byte(tok) {
					return invalid(&s, "token", string(tok))
				}
				if b == '&' {
					makeJump(&s, form, &code, opJMPF, jumps, ':')
				} else {
					makeJump(&s, form, &code, opJMPT, jumps, '?')
				}
				logic.Reset()
			} else {
				return invalid(&s, "token", string(tok))
			}
		case '(':
		case ')':
			resolveJumps(&s, code, jumps)
		default:
			return invalid(&s, "token", string(tok))
		}
		tok = s.Scan()
	}
	return code, nil
}

func removeInstructions(insts []*instruction, start int, count int) []*instruction {
	insts = append(insts[:start], insts[start+count:]...)
	// Check for jumps that might be affected by the removal
	for kk := start; kk >= 0; kk-- {
		if in := insts[kk]; in.opCode.IsJump() && kk+in.value > start {
			in.value -= count
		}
	}
	return insts
}

func vmOptimize(insts []*instruction) []*instruction {
	// The optimizer is quite simple. Each pass is documented
	// at its beginning.

	//A first pass looks
	// for multiple comparison instructions that are preceeded
	// by exactly the same instructions and it removes the second
	// group of instructions.
	cmp := -1
	count := len(insts)
	ii := 0
	for ; ii < count; ii++ {
		v := insts[ii]
		if v.opCode.Compares() {
			if cmp >= 0 {
				delta := ii - cmp
				jj := cmp - 1
				for ; jj >= 0; jj-- {
					i1 := insts[jj]
					if !i1.opCode.Alters() {
						break
					}
					i2 := insts[jj+delta]
					if i1.opCode != i2.opCode || i1.value != i2.value {
						break
					}
				}
				equal := (cmp - 1) - jj
				if equal > 0 {
					ii -= equal
					count -= equal
					insts = removeInstructions(insts, ii, equal)
					continue
				}
			}
			cmp = ii
		}
	}
	// A second pass then looks for
	// instructions that set R = N when R is already
	// equal to N and it removes the second instruction.
	n := -1
	for ii = 0; ii < count; ii++ {
		v := insts[ii]
		if v.opCode == opN {
			if n >= 0 {
				insts = removeInstructions(insts, ii, 1)
				ii--
				count--
				continue
			}
			n = ii
		} else if v.opCode.Alters() {
			n = -1
		}
	}
	// Third pass looks for jumps which end up in a jump of the same type,
	// add adjusts the value to make just one jump.
	for ii := 0; ii < count; ii++ {
		v := insts[ii]
		if v.opCode.IsJump() {
			for true {
				t := ii + v.value + 1
				if t >= count {
					break
				}
				nv := insts[t]
				if nv.opCode != v.opCode {
					break
				}
				v.value += nv.value
			}
		}
	}
	return insts
}

func makeVmFunc(insts []*instruction) Formula {
	count := len(insts)
	return func(n int) int {
		return vmExec(insts, count, n)
	}
}

func vmExec(insts []*instruction, count int, n int) int {
	var R int
	var S bool
	for ii := 0; ii < count; ii++ {
		i := insts[ii]
		switch i.opCode {
		case opN:
			R = n
		case opADD:
			R += i.value
		case opSUB:
			R -= i.value
		case opMULT:
			R *= i.value
		case opDIV:
			R /= i.value
		case opMOD:
			R %= i.value
		case opRET:
			return i.value
		case opJMPT:
			if S {
				ii += i.value
			}
		case opJMPF:
			if !S {
				ii += i.value
			}
		case opEQ:
			S = R == i.value
		case opNEQ:
			S = R != i.value
		case opLT:
			S = R < i.value
		case opLTE:
			S = R <= i.value
		case opGT:
			S = R > i.value
		case opGTE:
			S = R >= i.value
		}
	}
	return bint(S)
}
<commit_msg>Throw an error when a RHS is used as a variable.<commit_after>package formula

import (
	"bytes"
	"fmt"
	"strconv"
	"strings"
	"text/scanner"
)

// This VM is quite simple, having only a general purpose
// register (R) and a boolean status register (S).
// Some instructions might contain an integer value (V):
//
//  N - set R = n
//  ADD - set R = R + V
//  SUB - set R = R - V
//  MULT - set R = R * V
//  DIV - set R = R / V
//  MOD - set R = R % V
//  JMPT - jump by V if S is true
//  JMPF - jump by V if S is false
//  EQ - set S = (R == V)
//  NEQ - set S = (R != V)
//  LT - set S = (R < V)
//  LTE - set S = (R <= V)
//  GT - set S = (R > V)
//  GTE - set S = (R >= V)
//  RET - end execution and return V
//
// If the end of the program is reached without finding
// a ret instruction, the last value of S is returned.
// as an integer.

type opCode uint8

const (
	// Instructions altering R
	opN opCode = iota + 1
	opADD
	opSUB
	opMULT
	opDIV
	opMOD
	// Special instructions
	opRET
	// Jump instructions
	opJMPT
	opJMPF
	// Comparison instructions
	opEQ
	opNEQ
	opLT
	opLTE
	opGT
	opGTE
)

func (o opCode) String() string {
	names := []string{"N", "ADD", "SUB", "MULT", "DIV", "MOD", "RET", "JMPT", "JMPF", "EQ", "NEQ", "LT", "LTE", "GT", "GTE"}
	return names[int(o)-1]
}

func (o opCode) Alters() bool {
	return o <= opMOD
}

func (o opCode) IsSpecial() bool {
	return o == opRET
}

func (o opCode) IsJump() bool {
	return o == opJMPT || o == opJMPF
}

func (o opCode) Compares() bool {
	return o >= opEQ
}

type instruction struct {
	opCode opCode
	value  int
}

func invalid(s *scanner.Scanner, what, val string) ([]*instruction, error) {
	return nil, fmt.Errorf("invalid %s in formula at %s: %q", what, s.Pos(), val)
}

func jumpTarget(s *scanner.Scanner, form string, chr byte) int {
	// look for matching chr
	offset := s.Pos().Offset
	paren := 0
	target := -1
	for ii, v := range []byte(form[offset:]) {
		if v == '(' {
			paren++
		} else if v == ')' {
			paren--
			if paren < 0 {
				target = offset + ii
				break
			}
		} else if v == chr && paren == 0 {
			target = offset + ii
			break
		}
	}
	return target
}

func makeJump(s *scanner.Scanner, form string, code *[]*instruction, op opCode, jumps map[int][]*instruction, chr byte) {
	// end of conditional, put the placeholder for a jump
	// and complete it once we reach the matching chr. Store the
	// current position of the jump in its value, so
	// calculating the relative offset is quicker.
	pos := len(*code)
	inst := &instruction{opCode: op, value: pos}
	*code = append(*code, inst)
	target := jumpTarget(s, form, chr)
	jumps[target] = append(jumps[target], inst)
}

func resolveJumps(s *scanner.Scanner, code []*instruction, jumps map[int][]*instruction) {
	// check for incomplete jumps to this location.
	// the pc should point at the next instruction
	// to be added and the jump is relative.
	pc := len(code)
	offset := s.Pos().Offset - 1
	for _, v := range jumps[offset] {
		v.value = pc - v.value - 1
	}
	delete(jumps, offset)
}

func compileVmFormula(form string) (Formula, error) {
	code, err := vmCompile(form)
	if err != nil {
		return nil, err
	}
	code = vmOptimize(code)
	return makeVmFunc(code), nil
}

func vmCompile(form string) ([]*instruction, error) {
	var s scanner.Scanner
	var err error
	s.Init(strings.NewReader(form))
	s.Error = func(s *scanner.Scanner, msg string) {
		err = fmt.Errorf("error parsing plural formula %s: %s", s.Pos(), msg)
	}
	s.Mode = scanner.ScanIdents | scanner.ScanInts
	tok := s.Scan()
	var code []*instruction
	var op bytes.Buffer
	var logic bytes.Buffer
	jumps := make(map[int][]*instruction)
	for tok != scanner.EOF && err == nil {
		switch tok {
		case scanner.Ident:
			if n := s.TokenText(); n != "n" {
				return invalid(&s, "ident", n)
			}
			if op.Len() > 0 {
				return invalid(&s, "ident", "RHS variables are not supported")
			}
			code = append(code, &instruction{opCode: opN})
		case scanner.Int:
			val, _ := strconv.Atoi(s.TokenText())
			if op.Len() == 0 {
				// return statement
				code = append(code, &instruction{opCode: opRET, value: val})
			} else {
				var opc opCode
				switch op.String() {
				case "+":
					opc = opADD
				case "-":
					opc = opSUB
				case "*":
					opc = opMULT
				case "/":
					opc = opDIV
				case "%":
					opc = opMOD
				case "==":
					opc = opEQ
				case "!=":
					opc = opNEQ
				case "<":
					opc = opLT
				case "<=":
					opc = opLTE
				case ">":
					opc = opGT
				case ">=":
					opc = opGTE
				default:
					return invalid(&s, "op", op.String())
				}
				code = append(code, &instruction{opCode: opc, value: val})
				op.Reset()
			}
		case '?':
			resolveJumps(&s, code, jumps)
			makeJump(&s, form, &code, opJMPF, jumps, ':')
		case ':':
			resolveJumps(&s, code, jumps)
		case '!', '=', '<', '>', '%':
			op.WriteRune(tok)
		case '&', '|':
			// logic operations
			if logic.Len() == 0 {
				logic.WriteRune(tok)
			} else if logic.Len() == 1 {
				b := logic.Bytes()[0]
				if b != byte(tok) {
					return invalid(&s, "token", string(tok))
				}
				if b == '&' {
					makeJump(&s, form, &code, opJMPF, jumps, ':')
				} else {
					makeJump(&s, form, &code, opJMPT, jumps, '?')
				}
				logic.Reset()
			} else {
				return invalid(&s, "token", string(tok))
			}
		case '(':
		case ')':
			resolveJumps(&s, code, jumps)
		default:
			return invalid(&s, "token", string(tok))
		}
		tok = s.Scan()
	}
	return code, nil
}

func removeInstructions(insts []*instruction, start int, count int) []*instruction {
	insts = append(insts[:start], insts[start+count:]...)
	// Check for jumps that might be affected by the removal
	for kk := start; kk >= 0; kk-- {
		if in := insts[kk]; in.opCode.IsJump() && kk+in.value > start {
			in.value -= count
		}
	}
	return insts
}

func vmOptimize(insts []*instruction) []*instruction {
	// The optimizer is quite simple. Each pass is documented
	// at its beginning.

	//A first pass looks
	// for multiple comparison instructions that are preceeded
	// by exactly the same instructions and it removes the second
	// group of instructions.
	cmp := -1
	count := len(insts)
	ii := 0
	for ; ii < count; ii++ {
		v := insts[ii]
		if v.opCode.Compares() {
			if cmp >= 0 {
				delta := ii - cmp
				jj := cmp - 1
				for ; jj >= 0; jj-- {
					i1 := insts[jj]
					if !i1.opCode.Alters() {
						break
					}
					i2 := insts[jj+delta]
					if i1.opCode != i2.opCode || i1.value != i2.value {
						break
					}
				}
				equal := (cmp - 1) - jj
				if equal > 0 {
					ii -= equal
					count -= equal
					insts = removeInstructions(insts, ii, equal)
					continue
				}
			}
			cmp = ii
		}
	}
	// A second pass then looks for
	// instructions that set R = N when R is already
	// equal to N and it removes the second instruction.
	n := -1
	for ii = 0; ii < count; ii++ {
		v := insts[ii]
		if v.opCode == opN {
			if n >= 0 {
				insts = removeInstructions(insts, ii, 1)
				ii--
				count--
				continue
			}
			n = ii
		} else if v.opCode.Alters() {
			n = -1
		}
	}
	// Third pass looks for jumps which end up in a jump of the same type,
	// add adjusts the value to make just one jump.
	for ii := 0; ii < count; ii++ {
		v := insts[ii]
		if v.opCode.IsJump() {
			for true {
				t := ii + v.value + 1
				if t >= count {
					break
				}
				nv := insts[t]
				if nv.opCode != v.opCode {
					break
				}
				v.value += nv.value
			}
		}
	}
	return insts
}

func makeVmFunc(insts []*instruction) Formula {
	count := len(insts)
	return func(n int) int {
		return vmExec(insts, count, n)
	}
}

func vmExec(insts []*instruction, count int, n int) int {
	var R int
	var S bool
	for ii := 0; ii < count; ii++ {
		i := insts[ii]
		switch i.opCode {
		case opN:
			R = n
		case opADD:
			R += i.value
		case opSUB:
			R -= i.value
		case opMULT:
			R *= i.value
		case opDIV:
			R /= i.value
		case opMOD:
			R %= i.value
		case opRET:
			return i.value
		case opJMPT:
			if S {
				ii += i.value
			}
		case opJMPF:
			if !S {
				ii += i.value
			}
		case opEQ:
			S = R == i.value
		case opNEQ:
			S = R != i.value
		case opLT:
			S = R < i.value
		case opLTE:
			S = R <= i.value
		case opGT:
			S = R > i.value
		case opGTE:
			S = R >= i.value
		}
	}
	return bint(S)
}
<|endoftext|>


<commit_before>package node

import (
	"fmt"
	"github.com/MG-RAST/Shock/shock-server/conf"
	e "github.com/MG-RAST/Shock/shock-server/errors"
	"github.com/MG-RAST/Shock/shock-server/logger"
	"github.com/MG-RAST/Shock/shock-server/node"
	"github.com/MG-RAST/Shock/shock-server/request"
	"github.com/MG-RAST/Shock/shock-server/responder"
	"github.com/MG-RAST/Shock/shock-server/user"
	"github.com/MG-RAST/Shock/shock-server/util"
	"github.com/MG-RAST/golib/go-uuid/uuid"
	"github.com/MG-RAST/golib/mgo/bson"
	"github.com/MG-RAST/golib/stretchr/goweb/context"
	"net/http"
	"strconv"
	"strings"
)

type M map[string]interface{}
type ListOfMaps []M

// GET: /node
// To do:
// - Iterate node queries
func (cr *NodeController) ReadMany(ctx context.Context) error {
	u, err := request.Authenticate(ctx.HttpRequest())
	if err != nil && err.Error() != e.NoAuth {
		return request.AuthError(err, ctx)
	}

	// Gather query params
	query := ctx.HttpRequest().URL.Query()

	// Setup query and nodes objects
	q := bson.M{}
	nodes := node.Nodes{}

	if u != nil {
		// Admin sees all
		if !u.Admin {
			q["$or"] = []bson.M{bson.M{"acl.read": "public"}, bson.M{"acl.read": u.Uuid}, bson.M{"acl.owner": u.Uuid}}
		}
	} else {
		if conf.ANON_READ {
			// select on only nodes that are publicly readable
			q["acl.read"] = "public"
		} else {
			return responder.RespondWithError(ctx, http.StatusUnauthorized, e.NoAuth)
		}
	}

	// Gather params to make db query. Do not include the
	// following list.
	paramlist := map[string]int{"limit": 1, "offset": 1, "query": 1, "querynode": 1, "owner": 1, "read": 1, "write": 1, "delete": 1, "public_owner": 1, "public_read": 1, "public_write": 1, "public_delete": 1}
	if _, ok := query["query"]; ok {
		for key := range query {
			if _, found := paramlist[key]; !found {
				keyStr := fmt.Sprintf("attributes.%s", key)
				value := query.Get(key)
				if value != "" {
					if numValue, err := strconv.Atoi(value); err == nil {
						q["$or"] = ListOfMaps{{keyStr: value}, {keyStr: numValue}}
					} else if value == "null" {
						q["$or"] = ListOfMaps{{keyStr: value}, {keyStr: nil}}
					} else {
						q[keyStr] = value
					}
				} else {
					existsMap := map[string]bool{
						"$exists": true,
					}
					q[keyStr] = existsMap
				}
			}
		}
	} else if _, ok := query["querynode"]; ok {
		for key := range query {
			if _, found := paramlist[key]; !found {
				value := query.Get(key)
				if value != "" {
					if numValue, err := strconv.Atoi(value); err == nil {
						q["$or"] = ListOfMaps{{key: value}, {key: numValue}}
					} else if value == "null" {
						q["$or"] = ListOfMaps{{key: value}, {key: nil}}
					} else {
						q[key] = value
					}
				} else {
					existsMap := map[string]bool{
						"$exists": true,
					}
					q[key] = existsMap
				}
			}
		}
	}

	// defaults
	limit := 25
	offset := 0
	if _, ok := query["limit"]; ok {
		limit = util.ToInt(query.Get("limit"))
	}
	if _, ok := query["offset"]; ok {
		offset = util.ToInt(query.Get("offset"))
	}

	// Allowing user to query based on ACL's with a comma-separated list of users.
	// Users can be written as a username or a UUID.
	for _, atype := range []string{"owner", "read", "write", "delete"} {
		if _, ok := query[atype]; ok {
			users := strings.Split(query.Get(atype), ",")
			for _, v := range users {
				if uuid.Parse(v) != nil {
					q["acl."+atype] = v
				} else {
					u := user.User{Username: v}
					if err := u.SetMongoInfo(); err != nil {
						err_msg := "err " + err.Error()
						logger.Error(err_msg)
						return responder.RespondWithError(ctx, http.StatusBadRequest, err_msg)
					}
					q["acl."+atype] = u.Uuid
				}
			}
		}
	}

	if _, ok := query["public_owner"]; ok {
		// If search is for public_owner AND owner = non-empty string then return zero nodes, no nodes can match this query.
		if _, exists := q["acl.owner"]; exists {
			return responder.RespondWithPaginatedData(ctx, nodes, limit, offset, 0)
		}
		q["acl.owner"] = ""
	}

	// Allowing users to query based on whether ACL is public
	for _, atype := range []string{"read", "write", "delete"} {
		if _, ok := query["public_"+atype]; ok {
			sizeMap := map[string]int{
				"$size": 0,
			}
			// Currently a node cannot be public and have an ACL at the same time, so this returns zero nodes.
			if _, exists := q["acl."+atype]; exists {
				return responder.RespondWithPaginatedData(ctx, nodes, limit, offset, 0)
			} else {
				q["acl."+atype] = sizeMap
			}
		}
	}

	// Get nodes from db
	count, err := nodes.GetPaginated(q, limit, offset)
	if err != nil {
		err_msg := "err " + err.Error()
		logger.Error(err_msg)
		return responder.RespondWithError(ctx, http.StatusBadRequest, err_msg)
	}
	return responder.RespondWithPaginatedData(ctx, nodes, limit, offset, count)
}
<commit_msg>Updating query handler to work with new ACL model.  Partially done.<commit_after>package node

import (
	"fmt"
	"github.com/MG-RAST/Shock/shock-server/conf"
	e "github.com/MG-RAST/Shock/shock-server/errors"
	"github.com/MG-RAST/Shock/shock-server/logger"
	"github.com/MG-RAST/Shock/shock-server/node"
	"github.com/MG-RAST/Shock/shock-server/request"
	"github.com/MG-RAST/Shock/shock-server/responder"
	"github.com/MG-RAST/Shock/shock-server/user"
	"github.com/MG-RAST/Shock/shock-server/util"
	"github.com/MG-RAST/golib/go-uuid/uuid"
	"github.com/MG-RAST/golib/mgo/bson"
	"github.com/MG-RAST/golib/stretchr/goweb/context"
	"net/http"
	"strconv"
	"strings"
	//	"time"
)

const shortForm = "2006-01-02"

// GET: /node
// To do:
// - Iterate node queries
func (cr *NodeController) ReadMany(ctx context.Context) error {
	u, err := request.Authenticate(ctx.HttpRequest())
	if err != nil && err.Error() != e.NoAuth {
		return request.AuthError(err, ctx)
	}

	// Gather query params
	query := ctx.HttpRequest().URL.Query()

	// Setup query and nodes objects
	q := bson.M{}
	qAcls := bson.M{}
	qOpts := bson.M{}
	qPerm := bson.M{}
	nodes := node.Nodes{}

	if u != nil {
		// Admin sees all
		if !u.Admin {
			qPerm["$or"] = []bson.M{bson.M{"acl.read": "public"}, bson.M{"acl.read": u.Uuid}, bson.M{"acl.owner": u.Uuid}}
		}
	} else {
		if conf.ANON_READ {
			// select on only nodes that are publicly readable
			qPerm["acl.read"] = "public"
		} else {
			return responder.RespondWithError(ctx, http.StatusUnauthorized, e.NoAuth)
		}
	}

	// Gather params to make db query. Do not include the
	// following list.
	paramlist := map[string]int{"limit": 1, "offset": 1, "query": 1, "querynode": 1, "owner": 1, "read": 1, "write": 1, "delete": 1, "public_owner": 1, "public_read": 1, "public_write": 1, "public_delete": 1}
	if _, ok := query["query"]; ok {
		for key := range query {
			if _, found := paramlist[key]; !found {
				keyStr := fmt.Sprintf("attributes.%s", key)
				value := query.Get(key)
				if value != "" {
					if numValue, err := strconv.Atoi(value); err == nil {
						qOpts["$or"] = []bson.M{bson.M{keyStr: value}, bson.M{keyStr: numValue}}
					} else if value == "null" {
						qOpts["$or"] = []bson.M{bson.M{keyStr: value}, bson.M{keyStr: nil}}
					} else {
						qOpts[keyStr] = value
					}
				} else {
					qOpts[keyStr] = map[string]bool{"$exists": true}
				}
			}
		}
	} else if _, ok := query["querynode"]; ok {
		for key := range query {
			if _, found := paramlist[key]; !found {

			}
		}
	}

	// defaults
	limit := 25
	offset := 0
	if _, ok := query["limit"]; ok {
		limit = util.ToInt(query.Get("limit"))
	}
	if _, ok := query["offset"]; ok {
		offset = util.ToInt(query.Get("offset"))
	}

	var MArray []bson.M

	// Allowing user to query based on ACL's with a comma-separated list of users.
	// Users can be written as a username or a UUID.
	for _, atype := range []string{"owner", "read", "write", "delete"} {
		if _, ok := query[atype]; ok {
			users := strings.Split(query.Get(atype), ",")
			for _, v := range users {
				if uuid.Parse(v) != nil {
					//qAcls["$and"] = {qAcls["$and"], bson.M{"acl." + atype: v}}
					MArray = append(MArray, bson.M{"acl." + atype: v})
				} else {
					u := user.User{Username: v}
					if err := u.SetMongoInfo(); err != nil {
						err_msg := "err " + err.Error()
						logger.Error(err_msg)
						return responder.RespondWithError(ctx, http.StatusBadRequest, err_msg)
					}
					MArray = append(MArray, bson.M{"acl." + atype: u.Uuid})
				}
			}
		}
	}

	// Allowing users to query based on whether ACL is public
	for _, atype := range []string{"owner", "read", "write", "delete"} {
		if _, ok := query["public_"+atype]; ok {
			MArray = append(MArray, bson.M{"acl." + atype: "public"})
		}
	}

	qAcls["$and"] = MArray

	// Combine permissions query with query parameters and ACL query into one AND clause
	q["$and"] = []bson.M{qPerm, qOpts, qAcls}

	// Get nodes from db
	count, err := nodes.GetPaginated(q, limit, offset)
	if err != nil {
		err_msg := "err " + err.Error()
		logger.Error(err_msg)
		return responder.RespondWithError(ctx, http.StatusBadRequest, err_msg)
	}
	return responder.RespondWithPaginatedData(ctx, nodes, limit, offset, count)
}
<|endoftext|>


<commit_before>package sentrylib

import (
	"errors"
	"io"
	"log"
	"time"
)

type Sentry interface {
	Serve() error
}

type sentry struct {
	config Config
}

func NewSentry(config Config) Sentry {
	return &sentry{
		config: config,
	}
}

func (server *sentry) Serve() error {
	log.SetFlags(log.Flags() | log.Llongfile)
	client := NewAprsClient(server.config.AprsServer, server.config.AprsUser, server.config.AprsPasscode, server.config.AprsFilter)

	store, err := NewBoltStore("sentry.db")
	//store, err := NewGoLevelDB("level.db")
	if err != nil {
		return err
	}

	mail := NewMailgunServer(server.config)

	// runs in background
	NewWebServer(store)

	duration := 25 * time.Hour
	if server.config.Cutoff != "" {
		duration, err = time.ParseDuration(server.config.Cutoff)
		if err != nil {
			return errors.New("Unable to parse Cutoff in config")
		}
	}

	worker := NewSentryWorker(store, duration, mail)

	go RunReaper(worker, duration, server.config.SkipCooldown)

	for {
		err = client.Dial()
		if err != nil {
			return err
		}
		count := 0
		totalTime := 0 * time.Second
		for client.Next() {
			frame, err := client.Frame()
			if err != nil {
				log.Println(err)
			}
			ts1 := time.Now()
			err = worker.HandleMessage(frame)
			ts2 := time.Now()
			dur := ts2.Sub(ts1)
			count++
			totalTime += dur
			avg := time.Duration(int64(totalTime) / int64(count))
			log.Println("\t\t\t\t\t", avg, dur)
			if err != nil {
				if !(err == FrameNotValidError || err.Error() == "no positions found") {
					log.Println(err)
				}
			}
		}
		err = client.Error()
		if err != io.EOF {
			return err
		} else {
			log.Println("Redial Triggered:", err)
		}
	}
}

func RunReaper(sentryWorker SentryWorker, duration time.Duration, skipCooldown bool) {
	if !skipCooldown {
		time.Sleep(duration)
	}
	for {
		nodes, err := sentryWorker.ReapLiveNodes()
		if err != nil {
			log.Println(err)
			continue
		}
		for _, v := range nodes {
			go sentryWorker.Email(v.Callsign, v.LastSeen)
		}
		time.Sleep(1 * time.Second)
	}
}
<commit_msg>Commenting out perf logging<commit_after>package sentrylib

import (
	"errors"
	"io"
	"log"
	"time"
)

type Sentry interface {
	Serve() error
}

type sentry struct {
	config Config
}

func NewSentry(config Config) Sentry {
	return &sentry{
		config: config,
	}
}

func (server *sentry) Serve() error {
	log.SetFlags(log.Flags() | log.Llongfile)
	client := NewAprsClient(server.config.AprsServer, server.config.AprsUser, server.config.AprsPasscode, server.config.AprsFilter)

	store, err := NewBoltStore("sentry.db")
	//store, err := NewGoLevelDB("level.db")
	if err != nil {
		return err
	}

	mail := NewMailgunServer(server.config)

	// runs in background
	NewWebServer(store)

	duration := 25 * time.Hour
	if server.config.Cutoff != "" {
		duration, err = time.ParseDuration(server.config.Cutoff)
		if err != nil {
			return errors.New("Unable to parse Cutoff in config")
		}
	}

	worker := NewSentryWorker(store, duration, mail)

	go RunReaper(worker, duration, server.config.SkipCooldown)

	for {
		err = client.Dial()
		if err != nil {
			return err
		}
		//count := 0
		//totalTime := 0 * time.Second
		for client.Next() {
			frame, err := client.Frame()
			if err != nil {
				log.Println(err)
			}
			//ts1 := time.Now()
			err = worker.HandleMessage(frame)
			//ts2 := time.Now()
			//dur := ts2.Sub(ts1)
			//count++
			//totalTime += dur
			//avg := time.Duration(int64(totalTime) / int64(count))
			//log.Println("\t\t\t\t\t", avg, dur)
			if err != nil {
				if !(err == FrameNotValidError || err.Error() == "no positions found") {
					log.Println(err)
				}
			}
		}
		err = client.Error()
		if err != io.EOF {
			return err
		} else {
			log.Println("Redial Triggered:", err)
		}
	}
}

func RunReaper(sentryWorker SentryWorker, duration time.Duration, skipCooldown bool) {
	if !skipCooldown {
		time.Sleep(duration)
	}
	for {
		nodes, err := sentryWorker.ReapLiveNodes()
		if err != nil {
			log.Println(err)
			continue
		}
		for _, v := range nodes {
			go sentryWorker.Email(v.Callsign, v.LastSeen)
		}
		time.Sleep(1 * time.Second)
	}
}
<|endoftext|>