<commit_before>/*
 * Copyright (c) 2013 Kurt Jung (Gmail: kurt.w.jung)
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package gofpdf

import (
	"bytes"
	"compress/zlib"
	"fmt"
	// "github.com/davecgh/go-spew/spew"
	"bufio"
	"io"
	"math"
	"os"
	"path/filepath"
	"strings"
)

func round(f float64) int {
	if f < 0 {
		return -int(math.Floor(-f + 0.5))
	}
	return int(math.Floor(f + 0.5))
}

func sprintf(fmtStr string, args ...interface{}) string {
	return fmt.Sprintf(fmtStr, args...)
}

// Returns true if the specified normal file exists
func fileExist(filename string) (ok bool) {
	info, err := os.Stat(filename)
	if err == nil {
		if ^os.ModePerm&info.Mode() == 0 {
			ok = true
		}
	}
	return ok
}

// Returns the size of the specified file; ok will be false
// if the file does not exist or is not an ordinary file
func fileSize(filename string) (size int64, ok bool) {
	info, err := os.Stat(filename)
	ok = err == nil
	if ok {
		size = info.Size()
	}
	return
}

// Returns a new buffer populated with the contents of the specified Reader
func bufferFromReader(r io.Reader) (b *bytes.Buffer, err error) {
	b = new(bytes.Buffer)
	_, err = b.ReadFrom(r)
	return
}

// Returns true if the two specified float slices are equal
func slicesEqual(a, b []float64) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}

// Returns a zlib-compressed copy of the specified byte array
func sliceCompress(data []byte) []byte {
	var buf bytes.Buffer
	cmp, _ := zlib.NewWriterLevel(&buf, zlib.BestSpeed)
	cmp.Write(data)
	cmp.Close()
	return buf.Bytes()
}

// Returns an uncompressed copy of the specified zlib-compressed byte array
func sliceUncompress(data []byte) (outData []byte, err error) {
	inBuf := bytes.NewReader(data)
	r, err := zlib.NewReader(inBuf)
	defer r.Close()
	if err == nil {
		var outBuf bytes.Buffer
		_, err = outBuf.ReadFrom(r)
		if err == nil {
			outData = outBuf.Bytes()
		}
	}
	return
}

// Convert UTF-8 to UTF-16BE with BOM; from http://www.fpdf.org/
func utf8toutf16(s string) string {
	res := make([]byte, 0, 8)
	res = append(res, 0xFE, 0xFF)
	nb := len(s)
	i := 0
	for i < nb {
		c1 := byte(s[i])
		i++
		if c1 >= 224 {
			// 3-byte character
			c2 := byte(s[i])
			i++
			c3 := byte(s[i])
			i++
			res = append(res, ((c1&0x0F)<<4)+((c2&0x3C)>>2),
				((c2&0x03)<<6)+(c3&0x3F))
		} else if c1 >= 192 {
			// 2-byte character
			c2 := byte(s[i])
			i++
			res = append(res, ((c1 & 0x1C) >> 2),
				((c1&0x03)<<6)+(c2&0x3F))
		} else {
			// Single-byte character
			res = append(res, 0, c1)
		}
	}
	return string(res)
}

// Return a if cnd is true, otherwise b
func intIf(cnd bool, a, b int) int {
	if cnd {
		return a
	}
	return b
}

// Return aStr if cnd is true, otherwise bStr
func strIf(cnd bool, aStr, bStr string) string {
	if cnd {
		return aStr
	}
	return bStr
}

// Dump the internals of the specified values
// func dump(fileStr string, a ...interface{}) {
// 	fl, err := os.OpenFile(fileStr, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
// 	if err == nil {
// 		fmt.Fprintf(fl, "----------------\n")
// 		spew.Fdump(fl, a...)
// 		fl.Close()
// 	}
// }

func repClosure(m map[rune]byte) func(string) string {
	var buf bytes.Buffer
	return func(str string) string {
		var ch byte
		var ok bool
		buf.Truncate(0)
		for _, r := range str {
			if r < 0x80 {
				ch = byte(r)
			} else {
				ch, ok = m[r]
				if !ok {
					ch = byte('.')
				}
			}
			buf.WriteByte(ch)
		}
		return buf.String()
	}
}

// UnicodeTranslator returns a function that can be used to translate, where
// possible, utf-8 strings to a form that is compatible with the specified code
// page. The returned function accepts a string and returns a string.
//
// r is a reader that should read a buffer made up of content lines that
// pertain to the code page of interest. Each line is made up of three
// whitespace separated fields. The first begins with "!" and is followed by
// two hexadecimal digits that identify the glyph position in the code page of
// interest. The second field begins with "U+" and is followed by the unicode
// code point value. The third is the glyph name. A number of these code page
// map files are packaged with the gfpdf library in the font directory.
//
// An error occurs only if a line is read that does not conform to the expected
// format. In this case, the returned function is valid but does not perform
// any rune translation.
func UnicodeTranslator(r io.Reader) (f func(string) string, err error) {
	m := make(map[rune]byte)
	var uPos, cPos uint32
	var lineStr, nameStr string
	sc := bufio.NewScanner(r)
	for sc.Scan() {
		lineStr = sc.Text()
		lineStr = strings.TrimSpace(lineStr)
		if len(lineStr) > 0 {
			_, err = fmt.Sscanf(lineStr, "!%2X U+%4X %s", &cPos, &uPos, &nameStr)
			if err == nil {
				if cPos >= 0x80 {
					m[rune(uPos)] = byte(cPos)
				}
			}
		}
	}
	if err == nil {
		f = repClosure(m)
	} else {
		f = func(s string) string {
			return s
		}
	}
	return
}

// UnicodeTranslatorFromFile returns a function that can be used to translate,
// where possible, utf-8 strings to a form that is compatible with the
// specified code page. See UnicodeTranslator for more details.
//
// fileStr identifies a font descriptor file that maps glyph positions to names.
//
// If an error occurs reading the file, the returned function is valid but does
// not perform any rune translation.
func UnicodeTranslatorFromFile(fileStr string) (f func(string) string, err error) {
	var fl *os.File
	fl, err = os.Open(fileStr)
	if err == nil {
		f, err = UnicodeTranslator(fl)
		fl.Close()
	} else {
		f = func(s string) string {
			return s
		}
	}
	return
}

// UnicodeTranslatorFromDescriptor returns a function that can be used to
// translate, where possible, utf-8 strings to a form that is compatible with
// the specified code page. See UnicodeTranslator for more details.
//
// cpStr identifies a code page. A descriptor file in the font directory, set
// with the fontDirStr argument in the call to New(), should have this name
// plus the extension ".map". If cpStr is empty, it will be replaced with
// "cp1252", the gofpdf code page default.
//
// If an error occurs reading the descriptor, the returned function is valid
// but does not perform any rune translation.
//
// The CellFormat (4) example demonstrates this method.
func (f *Fpdf) UnicodeTranslatorFromDescriptor(cpStr string) (rep func(string) string) {
	var str string
	var ok bool
	if f.err != nil {
		return
	}
	if len(cpStr) == 0 {
		cpStr = "cp1252"
	}
	str, ok = embeddedMapList[cpStr]
	if ok {
		rep, f.err = UnicodeTranslator(strings.NewReader(str))
	} else {
		rep, f.err = UnicodeTranslatorFromFile(filepath.Join(f.fontpath, cpStr) + ".map")
	}
	return
}

// Transform moves a point by given X, Y offset
func (p *PointType) Transform(x, y float64) PointType {
	return PointType{p.X + x, p.Y + y}
}

// Orientation returns the orientation of a given size:
// "P" for portrait, "L" for landscape
func (s *SizeType) Orientation() string {
	if s == nil || s.Ht == s.Wd {
		return ""
	}
	if s.Wd > s.Ht {
		return "L"
	}
	return "P"
}

// ScaleBy expands a size by a certain factor
func (s *SizeType) ScaleBy(factor float64) SizeType {
	return SizeType{s.Wd * factor, s.Ht * factor}
}

// ScaleToWidth adjusts the height of a size to match the given width
func (s *SizeType) ScaleToWidth(width float64) SizeType {
	height := s.Ht * width / s.Wd
	return SizeType{width, height}
}

// ScaleToHeight adjusts the width of a size to match the given height
func (s *SizeType) ScaleToHeight(height float64) SizeType {
	width := s.Wd * height / s.Ht
	return SizeType{width, height}
}
<commit_msg>Return 'do nothing' function for Unicode translator rather than nil if document is in error state<commit_after>/*
 * Copyright (c) 2013 Kurt Jung (Gmail: kurt.w.jung)
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

package gofpdf

import (
	"bytes"
	"compress/zlib"
	"fmt"
	// "github.com/davecgh/go-spew/spew"
	"bufio"
	"io"
	"math"
	"os"
	"path/filepath"
	"strings"
)

func round(f float64) int {
	if f < 0 {
		return -int(math.Floor(-f + 0.5))
	}
	return int(math.Floor(f + 0.5))
}

func sprintf(fmtStr string, args ...interface{}) string {
	return fmt.Sprintf(fmtStr, args...)
}

// Returns true if the specified normal file exists
func fileExist(filename string) (ok bool) {
	info, err := os.Stat(filename)
	if err == nil {
		if ^os.ModePerm&info.Mode() == 0 {
			ok = true
		}
	}
	return ok
}

// Returns the size of the specified file; ok will be false
// if the file does not exist or is not an ordinary file
func fileSize(filename string) (size int64, ok bool) {
	info, err := os.Stat(filename)
	ok = err == nil
	if ok {
		size = info.Size()
	}
	return
}

// Returns a new buffer populated with the contents of the specified Reader
func bufferFromReader(r io.Reader) (b *bytes.Buffer, err error) {
	b = new(bytes.Buffer)
	_, err = b.ReadFrom(r)
	return
}

// Returns true if the two specified float slices are equal
func slicesEqual(a, b []float64) bool {
	if len(a) != len(b) {
		return false
	}
	for i := range a {
		if a[i] != b[i] {
			return false
		}
	}
	return true
}

// Returns a zlib-compressed copy of the specified byte array
func sliceCompress(data []byte) []byte {
	var buf bytes.Buffer
	cmp, _ := zlib.NewWriterLevel(&buf, zlib.BestSpeed)
	cmp.Write(data)
	cmp.Close()
	return buf.Bytes()
}

// Returns an uncompressed copy of the specified zlib-compressed byte array
func sliceUncompress(data []byte) (outData []byte, err error) {
	inBuf := bytes.NewReader(data)
	r, err := zlib.NewReader(inBuf)
	defer r.Close()
	if err == nil {
		var outBuf bytes.Buffer
		_, err = outBuf.ReadFrom(r)
		if err == nil {
			outData = outBuf.Bytes()
		}
	}
	return
}

// Convert UTF-8 to UTF-16BE with BOM; from http://www.fpdf.org/
func utf8toutf16(s string) string {
	res := make([]byte, 0, 8)
	res = append(res, 0xFE, 0xFF)
	nb := len(s)
	i := 0
	for i < nb {
		c1 := byte(s[i])
		i++
		if c1 >= 224 {
			// 3-byte character
			c2 := byte(s[i])
			i++
			c3 := byte(s[i])
			i++
			res = append(res, ((c1&0x0F)<<4)+((c2&0x3C)>>2),
				((c2&0x03)<<6)+(c3&0x3F))
		} else if c1 >= 192 {
			// 2-byte character
			c2 := byte(s[i])
			i++
			res = append(res, ((c1 & 0x1C) >> 2),
				((c1&0x03)<<6)+(c2&0x3F))
		} else {
			// Single-byte character
			res = append(res, 0, c1)
		}
	}
	return string(res)
}

// Return a if cnd is true, otherwise b
func intIf(cnd bool, a, b int) int {
	if cnd {
		return a
	}
	return b
}

// Return aStr if cnd is true, otherwise bStr
func strIf(cnd bool, aStr, bStr string) string {
	if cnd {
		return aStr
	}
	return bStr
}

// doNothing returns the passed string with no translation.
func doNothing(s string) string {
	return s
}

// Dump the internals of the specified values
// func dump(fileStr string, a ...interface{}) {
// 	fl, err := os.OpenFile(fileStr, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0600)
// 	if err == nil {
// 		fmt.Fprintf(fl, "----------------\n")
// 		spew.Fdump(fl, a...)
// 		fl.Close()
// 	}
// }

func repClosure(m map[rune]byte) func(string) string {
	var buf bytes.Buffer
	return func(str string) string {
		var ch byte
		var ok bool
		buf.Truncate(0)
		for _, r := range str {
			if r < 0x80 {
				ch = byte(r)
			} else {
				ch, ok = m[r]
				if !ok {
					ch = byte('.')
				}
			}
			buf.WriteByte(ch)
		}
		return buf.String()
	}
}

// UnicodeTranslator returns a function that can be used to translate, where
// possible, utf-8 strings to a form that is compatible with the specified code
// page. The returned function accepts a string and returns a string.
//
// r is a reader that should read a buffer made up of content lines that
// pertain to the code page of interest. Each line is made up of three
// whitespace separated fields. The first begins with "!" and is followed by
// two hexadecimal digits that identify the glyph position in the code page of
// interest. The second field begins with "U+" and is followed by the unicode
// code point value. The third is the glyph name. A number of these code page
// map files are packaged with the gfpdf library in the font directory.
//
// An error occurs only if a line is read that does not conform to the expected
// format. In this case, the returned function is valid but does not perform
// any rune translation.
func UnicodeTranslator(r io.Reader) (f func(string) string, err error) {
	m := make(map[rune]byte)
	var uPos, cPos uint32
	var lineStr, nameStr string
	sc := bufio.NewScanner(r)
	for sc.Scan() {
		lineStr = sc.Text()
		lineStr = strings.TrimSpace(lineStr)
		if len(lineStr) > 0 {
			_, err = fmt.Sscanf(lineStr, "!%2X U+%4X %s", &cPos, &uPos, &nameStr)
			if err == nil {
				if cPos >= 0x80 {
					m[rune(uPos)] = byte(cPos)
				}
			}
		}
	}
	if err == nil {
		f = repClosure(m)
	} else {
		f = doNothing
	}
	return
}

// UnicodeTranslatorFromFile returns a function that can be used to translate,
// where possible, utf-8 strings to a form that is compatible with the
// specified code page. See UnicodeTranslator for more details.
//
// fileStr identifies a font descriptor file that maps glyph positions to names.
//
// If an error occurs reading the file, the returned function is valid but does
// not perform any rune translation.
func UnicodeTranslatorFromFile(fileStr string) (f func(string) string, err error) {
	var fl *os.File
	fl, err = os.Open(fileStr)
	if err == nil {
		f, err = UnicodeTranslator(fl)
		fl.Close()
	} else {
		f = doNothing
	}
	return
}

// UnicodeTranslatorFromDescriptor returns a function that can be used to
// translate, where possible, utf-8 strings to a form that is compatible with
// the specified code page. See UnicodeTranslator for more details.
//
// cpStr identifies a code page. A descriptor file in the font directory, set
// with the fontDirStr argument in the call to New(), should have this name
// plus the extension ".map". If cpStr is empty, it will be replaced with
// "cp1252", the gofpdf code page default.
//
// If an error occurs reading the descriptor, the returned function is valid
// but does not perform any rune translation.
//
// The CellFormat_codepage example demonstrates this method.
func (f *Fpdf) UnicodeTranslatorFromDescriptor(cpStr string) (rep func(string) string) {
	var str string
	var ok bool
	if f.err == nil {
		if len(cpStr) == 0 {
			cpStr = "cp1252"
		}
		str, ok = embeddedMapList[cpStr]
		if ok {
			rep, f.err = UnicodeTranslator(strings.NewReader(str))
		} else {
			rep, f.err = UnicodeTranslatorFromFile(filepath.Join(f.fontpath, cpStr) + ".map")
		}
	} else {
		rep = doNothing
	}
	return
}

// Transform moves a point by given X, Y offset
func (p *PointType) Transform(x, y float64) PointType {
	return PointType{p.X + x, p.Y + y}
}

// Orientation returns the orientation of a given size:
// "P" for portrait, "L" for landscape
func (s *SizeType) Orientation() string {
	if s == nil || s.Ht == s.Wd {
		return ""
	}
	if s.Wd > s.Ht {
		return "L"
	}
	return "P"
}

// ScaleBy expands a size by a certain factor
func (s *SizeType) ScaleBy(factor float64) SizeType {
	return SizeType{s.Wd * factor, s.Ht * factor}
}

// ScaleToWidth adjusts the height of a size to match the given width
func (s *SizeType) ScaleToWidth(width float64) SizeType {
	height := s.Ht * width / s.Wd
	return SizeType{width, height}
}

// ScaleToHeight adjusts the width of a size to match the given height
func (s *SizeType) ScaleToHeight(height float64) SizeType {
	width := s.Wd * height / s.Ht
	return SizeType{width, height}
}
<|endoftext|>


<commit_before>package gko

import (
	"fmt"
	"io"
	"os"
	"strings"

	uuid "github.com/satori/go.uuid"

	"golang.org/x/text/encoding/japanese"
	"golang.org/x/text/transform"
)

// SafeURL return url safe strings.
func SafeURL(s string) string {
	s = strings.Replace(s, "+", "-", -1)
	s = strings.Replace(s, "/", "_", -1)
	s = strings.Replace(s, "=", "", -1)
	return s
}

// UUID generate string formatted by uuid.
func UUID() string {
	return uuid.NewV4().String()
}

// ProcessRecursively process directory using f recursively.
func ProcessRecursively(dir string, f func(d string) error) error {
	d, err := os.Open(dir)
	if err != nil {
		return fmt.Errorf("failt to open directory: %s", err)
	}
	i, err := d.Stat()
	if err != nil {
		return fmt.Errorf("fail to get file stat: %s", err)
	}
	if !i.IsDir() {
		return fmt.Errorf("%s is not directory", dir)
	}

	if err := f(dir); err != nil {
		return err
	}

	ds, err := d.Readdir(0)
	if err != nil {
		return err
	}
	for _, d := range ds {
		if d.IsDir() {
			if err := ProcessRecursively(d.Name(), f); err != nil {
				return err
			}
		}
	}
	return nil
}

// SliceRetrivedDuplicate returns new slice retrived duplicate data from slice.
func SliceRetrivedDuplicate(slice []string) []string {
	m := make(map[string]bool)
	newSlice := make([]string, 0, len(slice))
	for _, s := range slice {
		if m[s] == false {
			m[s] = true
			newSlice = append(newSlice, s)
		}
	}

	ns := newSlice
	return ns[:len(ns)]
}

// SliceToBoolMap changes slice to map.
func SliceToBoolMap(slice []string) map[string]bool {
	m := make(map[string]bool)
	for _, s := range slice {
		m[s] = true
	}
	return m
}

// UTF8ToSJIS is convert utf8 to shiftjis.
func UTF8ToSJIS(w io.Writer) io.Writer {
	return transform.NewWriter(w, japanese.ShiftJIS.NewEncoder())
}

// SJISToUTF8 is convert shiftjis to utf8.
func SJISToUTF8(r io.Reader) io.Reader {
	return transform.NewReader(r, japanese.ShiftJIS.NewDecoder())
}
<commit_msg>rename method<commit_after>package gko

import (
	"fmt"
	"io"
	"os"
	"strings"

	uuid "github.com/satori/go.uuid"

	"golang.org/x/text/encoding/japanese"
	"golang.org/x/text/transform"
)

// SafeURL return url safe strings.
func SafeURL(s string) string {
	s = strings.Replace(s, "+", "-", -1)
	s = strings.Replace(s, "/", "_", -1)
	s = strings.Replace(s, "=", "", -1)
	return s
}

// UUID generate string formatted by uuid.
func UUID() string {
	return uuid.NewV4().String()
}

// ProcessRecursively process directory using f recursively.
func ProcessRecursively(dir string, f func(d string) error) error {
	d, err := os.Open(dir)
	if err != nil {
		return fmt.Errorf("failt to open directory: %s", err)
	}
	i, err := d.Stat()
	if err != nil {
		return fmt.Errorf("fail to get file stat: %s", err)
	}
	if !i.IsDir() {
		return fmt.Errorf("%s is not directory", dir)
	}

	if err := f(dir); err != nil {
		return err
	}

	ds, err := d.Readdir(0)
	if err != nil {
		return err
	}
	for _, d := range ds {
		if d.IsDir() {
			if err := ProcessRecursively(d.Name(), f); err != nil {
				return err
			}
		}
	}
	return nil
}

// RetrivedDuplicateFromSlice returns new slice retrived duplicate data from slice.
func RetrivedDuplicateFromSlice(slice []string) []string {
	m := make(map[string]bool)
	newSlice := make([]string, 0, len(slice))
	for _, s := range slice {
		if m[s] == false {
			m[s] = true
			newSlice = append(newSlice, s)
		}
	}

	ns := newSlice
	return ns[:len(ns)]
}

// SliceToBoolMap changes slice to map.
func SliceToBoolMap(slice []string) map[string]bool {
	m := make(map[string]bool)
	for _, s := range slice {
		m[s] = true
	}
	return m
}

// UTF8ToSJIS is convert utf8 to shiftjis.
func UTF8ToSJIS(w io.Writer) io.Writer {
	return transform.NewWriter(w, japanese.ShiftJIS.NewEncoder())
}

// SJISToUTF8 is convert shiftjis to utf8.
func SJISToUTF8(r io.Reader) io.Reader {
	return transform.NewReader(r, japanese.ShiftJIS.NewDecoder())
}
<|endoftext|>


<commit_before>package gson

import "reflect"
import "unsafe"

func bytes2str(bytes []byte) string {
	if bytes == nil {
		return ""
	}
	sl := (*reflect.SliceHeader)(unsafe.Pointer(&bytes))
	st := &reflect.StringHeader{Data: sl.Data, Len: sl.Len}
	return *(*string)(unsafe.Pointer(st))
}

func str2bytes(str string) []byte {
	if str == "" {
		return nil
	}
	st := (*reflect.StringHeader)(unsafe.Pointer(&str))
	sl := &reflect.SliceHeader{Data: st.Data, Len: st.Len, Cap: st.Len}
	return *(*[]byte)(unsafe.Pointer(sl))
}
<commit_msg>abs for integers.<commit_after>package gson

import "reflect"
import "unsafe"

func bytes2str(bytes []byte) string {
	if bytes == nil {
		return ""
	}
	sl := (*reflect.SliceHeader)(unsafe.Pointer(&bytes))
	st := &reflect.StringHeader{Data: sl.Data, Len: sl.Len}
	return *(*string)(unsafe.Pointer(st))
}

func str2bytes(str string) []byte {
	if str == "" {
		return nil
	}
	st := (*reflect.StringHeader)(unsafe.Pointer(&str))
	sl := &reflect.SliceHeader{Data: st.Data, Len: st.Len, Cap: st.Len}
	return *(*[]byte)(unsafe.Pointer(sl))
}

func absInt8(val int8) uint8 {
	mask := val >> 7
	return uint8((mask + val) ^ mask)
}

func absInt16(val int16) uint16 {
	mask := val >> 15
	return uint16((mask + val) ^ mask)
}

func absInt32(val int32) uint32 {
	mask := val >> 31
	return uint32((mask + val) ^ mask)
}

func absInt64(val int64) uint64 {
	mask := val >> 63
	return uint64((mask + val) ^ mask)
}
<|endoftext|>


<commit_before>package uuid

import (
	"encoding/binary"
	"fmt"
)

// The UUID represents Universally Unique IDentifier (which is 128 bit long).
type UUID [16]byte

// NIL is defined in RFC 4122 section 4.1.7.
// The nil UUID is special form of UUID that is specified to have all 128 bits set to zero.
var NIL = &UUID{
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
}

// Version of the UUID represents a kind of subtype specifier.
func (u *UUID) Version() int {
	return int(binary.BigEndian.Uint16(u[6:8]) >> 12)
}

// String returns the human readable form of the UUID.
func (u *UUID) String() string {
	return fmt.Sprintf("%x-%x-%x-%x-%x", u[0:4], u[4:6], u[6:8], u[8:10], u[10:])
}

func (u *UUID) variantRFC4122() {
	u[8] = (u[8] & 0x3f) | 0x80
}
<commit_msg>feat: add standard namespace UUID<commit_after>package uuid

import (
	"encoding/binary"
	"fmt"
)

// The UUID represents Universally Unique IDentifier (which is 128 bit long).
type UUID [16]byte

var (
	// NIL is defined in RFC 4122 section 4.1.7.
	// The nil UUID is special form of UUID that is specified to have all 128 bits set to zero.
	NIL = &UUID{
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
	}
	// NameSpace_DNS assume name to be a fully-qualified domain name.
	// Declared in RFC 4122 Appendix C.
	NameSpace_DNS = &UUID{
		0x6b, 0xa7, 0xb8, 0x10, 0x9d, 0xad, 0x11, 0xd1,
		0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
	}
	// NameSpace_URL assume name to be a URL.
	// Declared in RFC 4122 Appendix C.
	NameSpace_URL = &UUID{
		0x6b, 0xa7, 0xb8, 0x11, 0x9d, 0xad, 0x11, 0xd1,
		0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
	}
	// Namespace_OID assume name to be an ISO OID.
	// Declared in RFC 4122 Appendix C.
	NameSpace_OID = &UUID{
		0x6b, 0xa7, 0xb8, 0x12, 0x9d, 0xad, 0x11, 0xd1,
		0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
	}
	// Namespace_X500 assume name to be a X.500 DN (in DER or a text output format).
	// Declared in RFC 4122 Appendix C.
	NameSpace_X500 = &UUID{
		0x6b, 0xa7, 0xb8, 0x14, 0x9d, 0xad, 0x11, 0xd1,
		0x80, 0xb4, 0x00, 0xc0, 0x4f, 0xd4, 0x30, 0xc8,
	}
)

// Version of the UUID represents a kind of subtype specifier.
func (u *UUID) Version() int {
	return int(binary.BigEndian.Uint16(u[6:8]) >> 12)
}

// String returns the human readable form of the UUID.
func (u *UUID) String() string {
	return fmt.Sprintf("%x-%x-%x-%x-%x", u[0:4], u[4:6], u[6:8], u[8:10], u[10:])
}

func (u *UUID) variantRFC4122() {
	u[8] = (u[8] & 0x3f) | 0x80
}
<|endoftext|>


<commit_before>package main

import (
	"html"
	"log"
	"net/http"
	// My library
	"github.com/malnick/vctl_lib"
)

func config() {

	config := GetConfig()
	log.Printf(config.Pvendpoint)
}

func run() {

	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
	})

	log.Fatal(http.ListenAndServe(":8080", nil))

}
<commit_msg>vctl.go<commit_after>package main

import (
	"io/ioutil"
	"log"
)

type Page struct {
	Title string
	Body  []byte
}

func (p *Page) save() error {
	filename := p.Title + ".txt"
	return ioutil.WriteFile(filename, p.Body, 0600)
}

func loadPage(title string) (*Page, error) {
	filename := title + ".txt"
	body, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	return &Page{Title: title, Body: body}, nil
}

func main() {
	p1 := &Page{Title: "VersionCtl", Body: []byte("Eventually a go template...")}
	p1.save()
	p2, _ := loadPage("VerstionCtl")
	log.Printf(string(p2.Body))
}
<|endoftext|>


<commit_before>// Copyright (c) 2013 Laurent Moussault. All rights reserved.
// Licensed under a simplified BSD license (see LICENSE file).

package glam

import "github.com/drakmaniso/glam/math"

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

// `Vec3` is a single-precision vector with 3 components.
type Vec3 struct {
	X float32
	Y float32
	Z float32
}

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

// `Homogenized` returns the homogeneous coordinates of `a`.
func (a Vec3) Homogenized() Vec4 {
	return Vec4{a.X, a.Y, a.Z, 1.0}
}

// `HomogenizedAsDirection` returns the homogeneous coordinates
// of a point at infinity in the direction of `a`.
func (a Vec3) HomogenizedAsDirection() Vec4 {
	return Vec4{a.X, a.Y, a.Z, 0.0}
}

// `Returns` the dehomogenization of `a` (perspective divide).
// `a.Z` must be non-zero.
func (a Vec3) Dehomogenized() Vec2 {
	return Vec2{a.X / a.Z, a.Y / a.Z}
}

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

// `Plus` returns the sum `a + b`.
//
// See also `Add`.
func (a Vec3) Plus(b Vec3) Vec3 {
	return Vec3{a.X + b.X, a.Y + b.Y, a.Z + b.Z}
}

// `Add` sets `a` to the sum `a + b`.
//
// More efficient than `Plus`.
func (a *Vec3) Add(b Vec3) {
	a.X += b.X
	a.Y += b.Y
	a.Z += b.Z
}
		{ , , ,  },
		{ , , ,  },
		{ , , ,  },
		{ 0, 0, 0, 1 },

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

// `Minus` returns the difference `a - b`.
//
// See also `Subtract`.
func (a Vec3) Minus(b Vec3) Vec3 {
	return Vec3{a.X - b.X, a.Y - b.Y, a.Z - b.Z}
}

// `Subtract` sets `a` to the difference `a - b`.
// More efficient than `Minus`.
func (a *Vec3) Subtract(b Vec3) {
	a.X -= b.X
	a.Y -= b.Y
	a.Z -= b.Z
}

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

// `Inverse` return the inverse of `a`.
//
// See also `Invert`.
func (a Vec3) Inverse() Vec3 {
	return Vec3{-a.X, -a.Y, -a.Z}
}

// `Invert` sets `a` to its inverse.
//
// More efficient than `Inverse`.
func (a *Vec3) Invert() {
	a.X = -a.X
	a.Y = -a.Y
	a.Z = -a.Z
}

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

// `Times` returns the product of `a` with the scalar `s`.
//
// See also `Multiply`.
func (a Vec3) Times(s float32) Vec3 {
	return Vec3{a.X * s, a.Y * s, a.Z * s}
}

// `Multiply` sets `a` to the product of `a` with the scalar `s`.
// More efficient than `Times`.
func (a *Vec3) Multiply(s float32) {
	a.X *= s
	a.Y *= s
	a.Z *= s
}

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

// `Slash` returns the division of `a` by the scalar `s`.
// `s` must be non-zero.
//
// See also `Divide`.
func (a Vec3) Slash(s float32) Vec3 {
	return Vec3{a.X / s, a.Y / s, a.Z / s}
}

// `Divide` sets `a` to the division of `a` by the scalar `s`.
// `s` must be non-zero.
//
// More efficient than `Slash`.
func (a *Vec3) Divide(s float32) {
	a.X /= s
	a.Y /= s
	a.Z /= s
}

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

// `Cross` returns the cross product of `a` and `b`.
func (a Vec3) Cross(b Vec3) Vec3 {
	return Vec3{
		a.Y*b.Z - a.Z*b.Y,
		a.Z*b.X - a.X*b.Z,
		a.X*b.Y - a.Y*b.X,
	}
}

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

// `Dot` returns the dot product of `a` and `b`.
func (a Vec3) Dot(b Vec3) float32 {
	return a.X*b.X + a.Y*b.Y + a.Z*b.Z
}

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

// `Length` returns `|a|` (the euclidian length of `a`).
func (a Vec3) Length() float32 {
	return math.Sqrt(a.X*a.X + a.Y*a.Y + a.Z*a.Z)
}

// `Normalized` return `a/|a|` (i.e. the normalization of `a`).
// `a` must be non-zero.
//
// See also `Normalize`.
func (a Vec3) Normalized() Vec3 {
	length := math.Sqrt(a.X*a.X + a.Y*a.Y + a.Z*a.Z)
	return Vec3{a.X / length, a.Y / length, a.Z / length}
}

// `Normalize` sets `a` to `a/|a|` (i.e. normalizes `a`).
// `a` must be non-zero.
//
// More efficitent than `Normalized`.
func (a *Vec3) Normalize() {
	length := math.Sqrt(a.X*a.X + a.Y*a.Y + a.Z*a.Z)
	a.X /= length
	a.Y /= length
	a.Z /= length
}

//------------------------------------------------------------------------------
<commit_msg>Fix copy/paste<commit_after>// Copyright (c) 2013 Laurent Moussault. All rights reserved.
// Licensed under a simplified BSD license (see LICENSE file).

package glam

import "github.com/drakmaniso/glam/math"

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

// `Vec3` is a single-precision vector with 3 components.
type Vec3 struct {
	X float32
	Y float32
	Z float32
}

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

// `Homogenized` returns the homogeneous coordinates of `a`.
func (a Vec3) Homogenized() Vec4 {
	return Vec4{a.X, a.Y, a.Z, 1.0}
}

// `HomogenizedAsDirection` returns the homogeneous coordinates
// of a point at infinity in the direction of `a`.
func (a Vec3) HomogenizedAsDirection() Vec4 {
	return Vec4{a.X, a.Y, a.Z, 0.0}
}

// `Returns` the dehomogenization of `a` (perspective divide).
// `a.Z` must be non-zero.
func (a Vec3) Dehomogenized() Vec2 {
	return Vec2{a.X / a.Z, a.Y / a.Z}
}

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

// `Plus` returns the sum `a + b`.
//
// See also `Add`.
func (a Vec3) Plus(b Vec3) Vec3 {
	return Vec3{a.X + b.X, a.Y + b.Y, a.Z + b.Z}
}

// `Add` sets `a` to the sum `a + b`.
//
// More efficient than `Plus`.
func (a *Vec3) Add(b Vec3) {
	a.X += b.X
	a.Y += b.Y
	a.Z += b.Z
}

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

// `Minus` returns the difference `a - b`.
//
// See also `Subtract`.
func (a Vec3) Minus(b Vec3) Vec3 {
	return Vec3{a.X - b.X, a.Y - b.Y, a.Z - b.Z}
}

// `Subtract` sets `a` to the difference `a - b`.
// More efficient than `Minus`.
func (a *Vec3) Subtract(b Vec3) {
	a.X -= b.X
	a.Y -= b.Y
	a.Z -= b.Z
}

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

// `Inverse` return the inverse of `a`.
//
// See also `Invert`.
func (a Vec3) Inverse() Vec3 {
	return Vec3{-a.X, -a.Y, -a.Z}
}

// `Invert` sets `a` to its inverse.
//
// More efficient than `Inverse`.
func (a *Vec3) Invert() {
	a.X = -a.X
	a.Y = -a.Y
	a.Z = -a.Z
}

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

// `Times` returns the product of `a` with the scalar `s`.
//
// See also `Multiply`.
func (a Vec3) Times(s float32) Vec3 {
	return Vec3{a.X * s, a.Y * s, a.Z * s}
}

// `Multiply` sets `a` to the product of `a` with the scalar `s`.
// More efficient than `Times`.
func (a *Vec3) Multiply(s float32) {
	a.X *= s
	a.Y *= s
	a.Z *= s
}

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

// `Slash` returns the division of `a` by the scalar `s`.
// `s` must be non-zero.
//
// See also `Divide`.
func (a Vec3) Slash(s float32) Vec3 {
	return Vec3{a.X / s, a.Y / s, a.Z / s}
}

// `Divide` sets `a` to the division of `a` by the scalar `s`.
// `s` must be non-zero.
//
// More efficient than `Slash`.
func (a *Vec3) Divide(s float32) {
	a.X /= s
	a.Y /= s
	a.Z /= s
}

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

// `Cross` returns the cross product of `a` and `b`.
func (a Vec3) Cross(b Vec3) Vec3 {
	return Vec3{
		a.Y*b.Z - a.Z*b.Y,
		a.Z*b.X - a.X*b.Z,
		a.X*b.Y - a.Y*b.X,
	}
}

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

// `Dot` returns the dot product of `a` and `b`.
func (a Vec3) Dot(b Vec3) float32 {
	return a.X*b.X + a.Y*b.Y + a.Z*b.Z
}

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

// `Length` returns `|a|` (the euclidian length of `a`).
func (a Vec3) Length() float32 {
	return math.Sqrt(a.X*a.X + a.Y*a.Y + a.Z*a.Z)
}

// `Normalized` return `a/|a|` (i.e. the normalization of `a`).
// `a` must be non-zero.
//
// See also `Normalize`.
func (a Vec3) Normalized() Vec3 {
	length := math.Sqrt(a.X*a.X + a.Y*a.Y + a.Z*a.Z)
	return Vec3{a.X / length, a.Y / length, a.Z / length}
}

// `Normalize` sets `a` to `a/|a|` (i.e. normalizes `a`).
// `a` must be non-zero.
//
// More efficitent than `Normalized`.
func (a *Vec3) Normalize() {
	length := math.Sqrt(a.X*a.X + a.Y*a.Y + a.Z*a.Z)
	a.X /= length
	a.Y /= length
	a.Z /= length
}

//------------------------------------------------------------------------------
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"errors"
	"fmt"
	"os/exec"
	"regexp"
	"strconv"
	"strings"

	"gopkg.in/telegram-bot-api.v4"
)

// RegisterVLAN adds "vlan", "in", "out" commands to bot
func RegisterVLAN(bot Bot, ifaces *Interfaces) {
	ifaces.Update()
	v := &vlan{Interfaces: ifaces}
	bot.Add("vlan", func(bot Bot, msg *tgbotapi.Message, tokens *Tokens) string {
		return v.replyToVLAN(bot, msg, tokens)
	})
	bot.Add("up", func(bot Bot, msg *tgbotapi.Message, tokens *Tokens) string {
		return v.replyToIn(bot, msg, tokens)
	})
	bot.Add("in", func(bot Bot, msg *tgbotapi.Message, tokens *Tokens) string {
		return v.replyToIn(bot, msg, tokens)
	})
	bot.Add("down", func(bot Bot, msg *tgbotapi.Message, tokens *Tokens) string {
		return v.replyToOut(bot, msg, tokens)
	})
	bot.Add("out", func(bot Bot, msg *tgbotapi.Message, tokens *Tokens) string {
		return v.replyToOut(bot, msg, tokens)
	})
}

// VLAN data
type vlan struct {
	Selected   int         // Currently selected vlan
	Interfaces *Interfaces // Enumeration of interfaces
	Device     string      // Device name for selected VLAN
	IFB        string      // IFB device name for selected vlan
}

// Impairment parameters
type params struct {
	delay, jitter     int
	loss, correlation float64
}

// ReplyToVLAN selects a particular VLAN
func (v *vlan) replyToVLAN(bot Bot, msg *tgbotapi.Message, tokens *Tokens) string {
	if tokens.Remaining() < 1 {
		return "Error: must provide the VLAN number (vlan <vlan_number>)"
	}
	vlan, err := strconv.Atoi(tokens.Next())
	if err != nil {
		return err.Error()
	}
	if vlan < 1 || vlan > 4094 {
		return "Error: VLAN number must be between 1 and 4094"
	}
	suffix := fmt.Sprintf(".%d", vlan)
	found := ""
	for name := range v.Interfaces.Current {
		if strings.HasSuffix(name, suffix) {
			found = name
			break
		}
	}
	if found == "" {
		return fmt.Sprintf("Error: VLAN %d is not found. Run \"ip\" for more info", vlan)
	}
	v.Selected = vlan
	v.Device = found
	ifb, err := v.getIFB()
	if err != nil {
		return fmt.Sprintf("Could not get IFB: %s", err.Error())
	}
	v.IFB = ifb
	return fmt.Sprintf("VLAN %d selected", vlan)
}

// ReplyToIn adds delay in the upstream direction
func (v *vlan) replyToIn(bot Bot, msg *tgbotapi.Message, tokens *Tokens) string {
	if v.IFB == "" {
		return "Current VLAN does not have IFB device assigned"
	}
	params, err := v.getParams(msg, tokens)
	if err != nil {
		return err.Error()
	}
	return v.impair(v.IFB, params)
}

// ReplyToOut adds delay in the downstream direction
func (v *vlan) replyToOut(bot Bot, msg *tgbotapi.Message, tokens *Tokens) string {
	params, err := v.getParams(msg, tokens)
	if err != nil {
		return err.Error()
	}
	return v.impair(v.Device, params)
}

// Get Delay, Jitter, PL and PL correlation from command
func (v *vlan) getParams(msg *tgbotapi.Message, tokens *Tokens) (params, error) {
	result := params{}
	if v.Selected == 0 {
		return result, errors.New("No VLAN selected. Run \"vlan\" for more info")
	}
	if tokens.Remaining() <= 0 {
		return result, errors.New("Error: must at least provide delay (ms). Format: [in|out] <delay_ms> <jitter_ms> <PL %> <correlation %>")
	}
	msDelay, err := strconv.Atoi(tokens.Next())
	if err != nil {
		return result, fmt.Errorf("delay is not an int: %s", err.Error())
	}
	if msDelay < 0 || msDelay > 4094 {
		return result, errors.New("Error: Delay must be between 0 and 4094 milliseconds")
	}
	result.delay = msDelay
	if tokens.Remaining() > 0 {
		msJitter, err := strconv.Atoi(tokens.Next())
		if err != nil {
			tokens.Back()
			return result, nil
		}
		if msJitter < 0 || msJitter > 4094 {
			return result, errors.New("Error: Jitter must be between 0 and 4094 milliseconds")
		}
		result.jitter = msJitter
	}
	if tokens.Remaining() > 0 {
		pl, err := strconv.ParseFloat(tokens.Next(), 32)
		if err != nil {
			tokens.Back()
			return result, nil
		}
		if pl < 0 || pl > 100 {
			return result, errors.New("Error: Packet loss must be between 0.0 and 100.0 percent")
		}
		result.loss = pl
	}
	if tokens.Remaining() > 0 {
		corr, err := strconv.ParseFloat(tokens.Next(), 32)
		if err != nil {
			tokens.Back()
			return result, nil
		}
		if corr < 0 || corr > 100 {
			return result, errors.New("Error: Correlation must be between 0.0 and 100.0 percent")
		}
		result.correlation = corr
	}
	return result, nil
}

// Add impairments (delay, jitter, loss...) to an interface
func (v *vlan) impair(iface string, p params) string {
	messages := make([]string, 0, 10)
	// Remove any qdisc
	cmd := exec.Command("tc", "qdisc", "del", "dev", iface, "root")
	var outDel bytes.Buffer
	cmd.Stdout = &outDel
	if err := cmd.Run(); err != nil {
		messages = append(messages, fmt.Sprintf("Warn: failed to clear interface settings, proceeding anyway (%s)", err.Error()))
	} else {
		messages = append(messages, fmt.Sprintf("Cleared interface %s", iface))
	}
	messages = append(messages, outDel.String())
	// Prepare for adding jitter and packet loss
	cmdLine := fmt.Sprintf("tc qdisc add dev %s root netem", iface)
	doApply := false
	if p.delay != 0 {
		doApply = true
		cmdLine = fmt.Sprintf("%s delay %dms", cmdLine, p.delay)
		if p.jitter != 0 {
			cmdLine = fmt.Sprintf("%s %dms distribution normal", cmdLine, p.jitter)
		}
	}
	if p.loss != 0 {
		doApply = true
		cmdLine = fmt.Sprintf("%s loss %f%%", cmdLine, p.loss)
		if p.correlation != 0 {
			cmdLine = fmt.Sprintf("%s %f%%", cmdLine, p.correlation)
		}
	}
	// If delay != 0, add it
	var outAdd bytes.Buffer
	if doApply {
		messages = append(messages, fmt.Sprintf("Policy for interface %s: %dms delay (%dms jitter), %f%% PL (%f%% correlation)", iface, p.delay, p.jitter, p.loss, p.correlation))
		fields := strings.Fields(cmdLine)
		cmd = exec.Command(fields[0], fields[1:]...)
		cmd.Stdout = &outAdd
		if err := cmd.Run(); err != nil {
			messages = append(messages, fmt.Sprintf("Error at qdisc add: %s", err.Error()))
		}
		messages = append(messages, outAdd.String())

	}
	// Return the output of the qdisc commands
	return strings.Join(messages, "\n")
}

// Gets the IFB interface associated to the selected VLAN
func (v *vlan) getIFB() (string, error) {
	cmd := exec.Command("tc", "filter", "show", "dev", v.Device, "root")
	var outShow bytes.Buffer
	cmd.Stdout = &outShow
	if err := cmd.Run(); err != nil {
		return "", fmt.Errorf("Error at filter show: %s", err.Error())
	}
	data := outShow.String()
	re := regexp.MustCompile("Egress Redirect to device ifb[0-9]")
	match := re.FindString(data)
	if match == "" {
		return "", fmt.Errorf("Missing IFB device for %s in %s", v.Device, data)
	}
	ifbFields := strings.Fields(match)
	return ifbFields[len(ifbFields)-1], nil
}
<commit_msg>less scary warning message<commit_after>package main

import (
	"bytes"
	"errors"
	"fmt"
	"os/exec"
	"regexp"
	"strconv"
	"strings"

	"gopkg.in/telegram-bot-api.v4"
)

// RegisterVLAN adds "vlan", "in", "out" commands to bot
func RegisterVLAN(bot Bot, ifaces *Interfaces) {
	ifaces.Update()
	v := &vlan{Interfaces: ifaces}
	bot.Add("vlan", func(bot Bot, msg *tgbotapi.Message, tokens *Tokens) string {
		return v.replyToVLAN(bot, msg, tokens)
	})
	bot.Add("up", func(bot Bot, msg *tgbotapi.Message, tokens *Tokens) string {
		return v.replyToIn(bot, msg, tokens)
	})
	bot.Add("in", func(bot Bot, msg *tgbotapi.Message, tokens *Tokens) string {
		return v.replyToIn(bot, msg, tokens)
	})
	bot.Add("down", func(bot Bot, msg *tgbotapi.Message, tokens *Tokens) string {
		return v.replyToOut(bot, msg, tokens)
	})
	bot.Add("out", func(bot Bot, msg *tgbotapi.Message, tokens *Tokens) string {
		return v.replyToOut(bot, msg, tokens)
	})
}

// VLAN data
type vlan struct {
	Selected   int         // Currently selected vlan
	Interfaces *Interfaces // Enumeration of interfaces
	Device     string      // Device name for selected VLAN
	IFB        string      // IFB device name for selected vlan
}

// Impairment parameters
type params struct {
	delay, jitter     int
	loss, correlation float64
}

// ReplyToVLAN selects a particular VLAN
func (v *vlan) replyToVLAN(bot Bot, msg *tgbotapi.Message, tokens *Tokens) string {
	if tokens.Remaining() < 1 {
		return "Error: must provide the VLAN number (vlan <vlan_number>)"
	}
	vlan, err := strconv.Atoi(tokens.Next())
	if err != nil {
		return err.Error()
	}
	if vlan < 1 || vlan > 4094 {
		return "Error: VLAN number must be between 1 and 4094"
	}
	suffix := fmt.Sprintf(".%d", vlan)
	found := ""
	for name := range v.Interfaces.Current {
		if strings.HasSuffix(name, suffix) {
			found = name
			break
		}
	}
	if found == "" {
		return fmt.Sprintf("Error: VLAN %d is not found. Run \"ip\" for more info", vlan)
	}
	v.Selected = vlan
	v.Device = found
	ifb, err := v.getIFB()
	if err != nil {
		return fmt.Sprintf("Could not get IFB: %s", err.Error())
	}
	v.IFB = ifb
	return fmt.Sprintf("VLAN %d selected", vlan)
}

// ReplyToIn adds delay in the upstream direction
func (v *vlan) replyToIn(bot Bot, msg *tgbotapi.Message, tokens *Tokens) string {
	if v.IFB == "" {
		return "Current VLAN does not have IFB device assigned"
	}
	params, err := v.getParams(msg, tokens)
	if err != nil {
		return err.Error()
	}
	return v.impair(v.IFB, params)
}

// ReplyToOut adds delay in the downstream direction
func (v *vlan) replyToOut(bot Bot, msg *tgbotapi.Message, tokens *Tokens) string {
	params, err := v.getParams(msg, tokens)
	if err != nil {
		return err.Error()
	}
	return v.impair(v.Device, params)
}

// Get Delay, Jitter, PL and PL correlation from command
func (v *vlan) getParams(msg *tgbotapi.Message, tokens *Tokens) (params, error) {
	result := params{}
	if v.Selected == 0 {
		return result, errors.New("No VLAN selected. Run \"vlan\" for more info")
	}
	if tokens.Remaining() <= 0 {
		return result, errors.New("Error: must at least provide delay (ms). Format: [in|out] <delay_ms> <jitter_ms> <PL %> <correlation %>")
	}
	msDelay, err := strconv.Atoi(tokens.Next())
	if err != nil {
		return result, fmt.Errorf("delay is not an int: %s", err.Error())
	}
	if msDelay < 0 || msDelay > 4094 {
		return result, errors.New("Error: Delay must be between 0 and 4094 milliseconds")
	}
	result.delay = msDelay
	if tokens.Remaining() > 0 {
		msJitter, err := strconv.Atoi(tokens.Next())
		if err != nil {
			tokens.Back()
			return result, nil
		}
		if msJitter < 0 || msJitter > 4094 {
			return result, errors.New("Error: Jitter must be between 0 and 4094 milliseconds")
		}
		result.jitter = msJitter
	}
	if tokens.Remaining() > 0 {
		pl, err := strconv.ParseFloat(tokens.Next(), 32)
		if err != nil {
			tokens.Back()
			return result, nil
		}
		if pl < 0 || pl > 100 {
			return result, errors.New("Error: Packet loss must be between 0.0 and 100.0 percent")
		}
		result.loss = pl
	}
	if tokens.Remaining() > 0 {
		corr, err := strconv.ParseFloat(tokens.Next(), 32)
		if err != nil {
			tokens.Back()
			return result, nil
		}
		if corr < 0 || corr > 100 {
			return result, errors.New("Error: Correlation must be between 0.0 and 100.0 percent")
		}
		result.correlation = corr
	}
	return result, nil
}

// Add impairments (delay, jitter, loss...) to an interface
func (v *vlan) impair(iface string, p params) string {
	messages := make([]string, 0, 10)
	// Remove any qdisc
	cmd := exec.Command("tc", "qdisc", "del", "dev", iface, "root")
	var outDel bytes.Buffer
	cmd.Stdout = &outDel
	if err := cmd.Run(); err != nil {
		messages = append(messages, fmt.Sprintf("Warn: nothing to clear in interface %s. Proceeding (%s)", iface, err.Error()))
	} else {
		messages = append(messages, fmt.Sprintf("Cleared interface %s", iface))
	}
	messages = append(messages, outDel.String())
	// Prepare for adding jitter and packet loss
	cmdLine := fmt.Sprintf("tc qdisc add dev %s root netem", iface)
	doApply := false
	if p.delay != 0 {
		doApply = true
		cmdLine = fmt.Sprintf("%s delay %dms", cmdLine, p.delay)
		if p.jitter != 0 {
			cmdLine = fmt.Sprintf("%s %dms distribution normal", cmdLine, p.jitter)
		}
	}
	if p.loss != 0 {
		doApply = true
		cmdLine = fmt.Sprintf("%s loss %f%%", cmdLine, p.loss)
		if p.correlation != 0 {
			cmdLine = fmt.Sprintf("%s %f%%", cmdLine, p.correlation)
		}
	}
	// If delay != 0, add it
	var outAdd bytes.Buffer
	if doApply {
		messages = append(messages, fmt.Sprintf("Policy for interface %s: %dms delay (%dms jitter), %f%% PL (%f%% correlation)", iface, p.delay, p.jitter, p.loss, p.correlation))
		fields := strings.Fields(cmdLine)
		cmd = exec.Command(fields[0], fields[1:]...)
		cmd.Stdout = &outAdd
		if err := cmd.Run(); err != nil {
			messages = append(messages, fmt.Sprintf("Error at qdisc add: %s", err.Error()))
		}
		messages = append(messages, outAdd.String())

	}
	// Return the output of the qdisc commands
	return strings.Join(messages, "\n")
}

// Gets the IFB interface associated to the selected VLAN
func (v *vlan) getIFB() (string, error) {
	cmd := exec.Command("tc", "filter", "show", "dev", v.Device, "root")
	var outShow bytes.Buffer
	cmd.Stdout = &outShow
	if err := cmd.Run(); err != nil {
		return "", fmt.Errorf("Error at filter show: %s", err.Error())
	}
	data := outShow.String()
	re := regexp.MustCompile("Egress Redirect to device ifb[0-9]")
	match := re.FindString(data)
	if match == "" {
		return "", fmt.Errorf("Missing IFB device for %s in %s", v.Device, data)
	}
	ifbFields := strings.Fields(match)
	return ifbFields[len(ifbFields)-1], nil
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/urfave/cli"
)

var ErrWrongStateFile = errors.New("fconf: wrong state file")

type WifiState struct {
	Enabled bool  `json:"enabled"`
	Configg *Wifi `json:"config"`
}

func WifiClientCMD(ctx *cli.Context) error {
	if ctx.IsSet(enableFlag) {
		return EnableWifiClient(ctx)
	}
	if ctx.IsSet(disableFlag) {
		return DisableWifi(ctx)
	}
	if ctx.IsSet(removeFlag) {
		return RemoveWifi(ctx)
	}
	if ctx.IsSet(configFlag) {
		return configWifiClient(ctx)
	}
	return nil
}

//EnableWifiClient enables wifi client. If the config flag is set, wifi is
//configured before being enabled.
func EnableWifiClient(ctx *cli.Context) error {
	if ctx.IsSet(configFlag) {
		err := configWifiClient(ctx)
		if err != nil {
			return err
		}
	}
	i := getInterface(ctx)
	if i == "" {
		return errors.New("missing interface, you must specify interface")
	}
	w, err := wifiClientState(i)
	if err != nil {
		return err
	}
	if w.Configg.Interface == "" {
		w.Configg.Interface = "wlan0"
	}
	service := "wpa_supplicant@" + w.Configg.Interface
	err = restartService(service)
	if err != nil {
		return err
	}
	err = enableService(service)
	if err != nil {
		return err
	}
	err = restartService("systemd-networkd")
	if err != nil {
		return err
	}
	w.Enabled = true
	data, err := json.Marshal(w)
	if err != nil {
		return err
	}
	return keepState(
		fmt.Sprintf(defaultWifiClientConfig, w.Configg.Interface), data)

}

func wifiClientState(i string) (*WifiState, error) {
	dir := os.Getenv("FCONF_CONFIGDIR")
	if dir == "" {
		dir = fconfConfigDir
	}
	b, err := ioutil.ReadFile(filepath.Join(dir,
		fmt.Sprintf(defaultWifiClientConfig, i)))
	if err != nil {
		return nil, err
	}
	w := &WifiState{}
	err = json.Unmarshal(b, w)
	if err != nil {
		return nil, err
	}
	if w.Configg == nil {
		return nil, ErrWrongStateFile
	}
	return w, nil
}

func configWifiClient(ctx *cli.Context) error {
	base := ctx.String("dir")
	name := ctx.String("name")
	src := ctx.String("config")
	if src == "" {
		return errors.New("fconf: missing configuration source file")
	}
	var b []byte
	var err error
	if src == "stdin" {
		b, err = ReadFromStdin()
		if err != nil {
			return err
		}
	} else {
		b, err = ioutil.ReadFile(src)
		if err != nil {
			return err
		}
	}
	e := Wifi{}
	err = json.Unmarshal(b, &e)
	if err != nil {
		return err
	}
	if e.Interface == "" {
		e.Interface = "wlan0"
	}
	err = checkDir(base)
	if err != nil {
		return err
	}
	if strings.Contains(name, "%s") {
		name = fmt.Sprintf(name, e.Interface)
	}
	filename := filepath.Join(base, name)
	err = CreateSystemdFile(e, filename, 0644)
	if err != nil {
		return err
	}
	fmt.Printf("successful written wifi configuration to %s \n", filename)
	path := "/etc/wpa_supplicant/"
	err = checkDir(path)
	if err != nil {
		return err
	}
	cname := "wpa_supplicant-" + e.Interface + ".conf"
	s, err := wifiConfig(e.Username, e.Password)
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(filepath.Join(path, cname), []byte(s), 0644)
	if err != nil {
		return err
	}
	state := &WifiState{Configg: &e}
	ws, err := wifiClientState(e.Interface)
	if err == nil {
		state.Enabled = ws.Enabled
	}
	b, _ = json.Marshal(state)
	fmt.Printf("successful written wifi connection  configuration to %s \n", filepath.Join(path, cname))
	setInterface(ctx, e.Interface)
	return keepState(
		fmt.Sprintf(defaultWifiClientConfig, e.Interface), b)
}

func wifiConfig(username, password string) (string, error) {
	cmd := "/usr/bin/wpa_passphrase"
	firstLine := "ctrl_interface=/run/wpa_supplicant_fconf"
	o, err := exec.Command(cmd, username, password).Output()
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("%s \n \n%s\n", firstLine, string(o)), nil
}

func DisableWifi(ctx *cli.Context) error {
	if ctx.IsSet(configFlag) {
		fmt.Println("WARN: config flag will be ignored when diable flag is used")
	}
	i := getInterface(ctx)
	if i == "" {
		return errors.New("missing interface, you must specify interface")
	}
	w, err := wifiClientState(i)
	if err != nil {
		return err
	}
	service := "wpa_supplicant@" + w.Configg.Interface
	err = disableService(service)
	if err != nil {
		return err
	}
	err = stopService(service)
	if err != nil {
		return err
	}
	err = restartService("systemd-networkd")
	if err != nil {
		return err
	}
	w.Enabled = false
	data, err := json.Marshal(w)
	if err != nil {
		return err
	}
	_, err = exec.Command("ip", "addr", "flush", "dev", w.Configg.Interface).Output()
	if err != nil {
		return fmt.Errorf("ERROR: running ip addr flush dev %s %v",
			w.Configg.Interface, err,
		)
	}
	unit := filepath.Join(networkBase,
		fmt.Sprintf(wirelessService, w.Configg.Interface))
	err = removeFile(unit)
	if err != nil {
		return err
	}
	return keepState(
		fmt.Sprintf(defaultWifiClientConfig, i), data)
}

func RemoveWifi(ctx *cli.Context) error {
	i := getInterface(ctx)
	if i == "" {
		return errors.New("missing interface, you must specify interface")
	}
	w, err := wifiClientState(i)
	if err != nil {
		return err
	}

	// remove systemd file
	unit := filepath.Join(networkBase, wirelessService)
	err = removeFile(unit)
	if err != nil {
		return err
	}
	path := "/etc/wpa_supplicant/"
	cname := "wpa_supplicant-" + w.Configg.Interface + ".conf"

	// remove client connection
	err = removeFile(filepath.Join(path, cname))
	if err != nil {
		return err
	}
	err = DisableWifi(ctx)
	if err != nil {
		return err
	}

	// Remove any interface settings
	err = FlushInterface(w.Configg.Interface)
	if err != nil {
		return err
	}

	// remove the state file
	stateFile := filepath.Join(stateDir(),
		fmt.Sprintf(defaultWifiClientConfig, i))
	return removeFile(stateFile)
}
<commit_msg>wifi: Create the systemd unit file if not there already<commit_after>package main

import (
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"os"
	"os/exec"
	"path/filepath"
	"strings"

	"github.com/urfave/cli"
)

var ErrWrongStateFile = errors.New("fconf: wrong state file")

type WifiState struct {
	Enabled bool  `json:"enabled"`
	Configg *Wifi `json:"config"`
}

func WifiClientCMD(ctx *cli.Context) error {
	if ctx.IsSet(enableFlag) {
		return EnableWifiClient(ctx)
	}
	if ctx.IsSet(disableFlag) {
		return DisableWifi(ctx)
	}
	if ctx.IsSet(removeFlag) {
		return RemoveWifi(ctx)
	}
	if ctx.IsSet(configFlag) {
		return configWifiClient(ctx)
	}
	return nil
}

//EnableWifiClient enables wifi client. If the config flag is set, wifi is
//configured before being enabled.
func EnableWifiClient(ctx *cli.Context) error {
	if ctx.IsSet(configFlag) {
		err := configWifiClient(ctx)
		if err != nil {
			return err
		}
	}
	i := getInterface(ctx)
	if i == "" {
		return errors.New("missing interface, you must specify interface")
	}
	w, err := wifiClientState(i)
	if err != nil {
		return err
	}
	if w.Configg.Interface == "" {
		w.Configg.Interface = "wlan0"
	}
	unit := filepath.Join(networkBase,
		fmt.Sprintf(wirelessService, w.Configg.Interface))
	_, err = os.Stat(unit)
	if os.IsNotExist(err) {
		err = CreateSystemdFile(w.Configg, unit, 0644)
		if err != nil {
			return err
		}
	}
	service := "wpa_supplicant@" + w.Configg.Interface
	err = restartService(service)
	if err != nil {
		return err
	}
	err = enableService(service)
	if err != nil {
		return err
	}
	err = restartService("systemd-networkd")
	if err != nil {
		return err
	}
	w.Enabled = true
	data, err := json.Marshal(w)
	if err != nil {
		return err
	}
	return keepState(
		fmt.Sprintf(defaultWifiClientConfig, w.Configg.Interface), data)

}

func wifiClientState(i string) (*WifiState, error) {
	dir := os.Getenv("FCONF_CONFIGDIR")
	if dir == "" {
		dir = fconfConfigDir
	}
	b, err := ioutil.ReadFile(filepath.Join(dir,
		fmt.Sprintf(defaultWifiClientConfig, i)))
	if err != nil {
		return nil, err
	}
	w := &WifiState{}
	err = json.Unmarshal(b, w)
	if err != nil {
		return nil, err
	}
	if w.Configg == nil {
		return nil, ErrWrongStateFile
	}
	return w, nil
}

func configWifiClient(ctx *cli.Context) error {
	base := ctx.String("dir")
	name := ctx.String("name")
	src := ctx.String("config")
	if src == "" {
		return errors.New("fconf: missing configuration source file")
	}
	var b []byte
	var err error
	if src == "stdin" {
		b, err = ReadFromStdin()
		if err != nil {
			return err
		}
	} else {
		b, err = ioutil.ReadFile(src)
		if err != nil {
			return err
		}
	}
	e := Wifi{}
	err = json.Unmarshal(b, &e)
	if err != nil {
		return err
	}
	if e.Interface == "" {
		e.Interface = "wlan0"
	}
	err = checkDir(base)
	if err != nil {
		return err
	}
	if strings.Contains(name, "%s") {
		name = fmt.Sprintf(name, e.Interface)
	}
	filename := filepath.Join(base, name)
	err = CreateSystemdFile(e, filename, 0644)
	if err != nil {
		return err
	}
	fmt.Printf("successful written wifi configuration to %s \n", filename)
	path := "/etc/wpa_supplicant/"
	err = checkDir(path)
	if err != nil {
		return err
	}
	cname := "wpa_supplicant-" + e.Interface + ".conf"
	s, err := wifiConfig(e.Username, e.Password)
	if err != nil {
		return err
	}
	err = ioutil.WriteFile(filepath.Join(path, cname), []byte(s), 0644)
	if err != nil {
		return err
	}
	state := &WifiState{Configg: &e}
	ws, err := wifiClientState(e.Interface)
	if err == nil {
		state.Enabled = ws.Enabled
	}
	b, _ = json.Marshal(state)
	fmt.Printf("successful written wifi connection  configuration to %s \n", filepath.Join(path, cname))
	setInterface(ctx, e.Interface)
	return keepState(
		fmt.Sprintf(defaultWifiClientConfig, e.Interface), b)
}

func wifiConfig(username, password string) (string, error) {
	cmd := "/usr/bin/wpa_passphrase"
	firstLine := "ctrl_interface=/run/wpa_supplicant_fconf"
	o, err := exec.Command(cmd, username, password).Output()
	if err != nil {
		return "", err
	}
	return fmt.Sprintf("%s \n \n%s\n", firstLine, string(o)), nil
}

func DisableWifi(ctx *cli.Context) error {
	if ctx.IsSet(configFlag) {
		fmt.Println("WARN: config flag will be ignored when diable flag is used")
	}
	i := getInterface(ctx)
	if i == "" {
		return errors.New("missing interface, you must specify interface")
	}
	w, err := wifiClientState(i)
	if err != nil {
		return err
	}
	service := "wpa_supplicant@" + w.Configg.Interface
	err = disableService(service)
	if err != nil {
		return err
	}
	err = stopService(service)
	if err != nil {
		return err
	}
	err = restartService("systemd-networkd")
	if err != nil {
		return err
	}
	w.Enabled = false
	data, err := json.Marshal(w)
	if err != nil {
		return err
	}
	_, err = exec.Command("ip", "addr", "flush", "dev", w.Configg.Interface).Output()
	if err != nil {
		return fmt.Errorf("ERROR: running ip addr flush dev %s %v",
			w.Configg.Interface, err,
		)
	}
	unit := filepath.Join(networkBase,
		fmt.Sprintf(wirelessService, w.Configg.Interface))
	err = removeFile(unit)
	if err != nil {
		return err
	}
	return keepState(
		fmt.Sprintf(defaultWifiClientConfig, i), data)
}

func RemoveWifi(ctx *cli.Context) error {
	i := getInterface(ctx)
	if i == "" {
		return errors.New("missing interface, you must specify interface")
	}
	w, err := wifiClientState(i)
	if err != nil {
		return err
	}

	// remove systemd file
	unit := filepath.Join(networkBase, wirelessService)
	err = removeFile(unit)
	if err != nil {
		return err
	}
	path := "/etc/wpa_supplicant/"
	cname := "wpa_supplicant-" + w.Configg.Interface + ".conf"

	// remove client connection
	err = removeFile(filepath.Join(path, cname))
	if err != nil {
		return err
	}
	err = DisableWifi(ctx)
	if err != nil {
		return err
	}

	// Remove any interface settings
	err = FlushInterface(w.Configg.Interface)
	if err != nil {
		return err
	}

	// remove the state file
	stateFile := filepath.Join(stateDir(),
		fmt.Sprintf(defaultWifiClientConfig, i))
	return removeFile(stateFile)
}
<|endoftext|>


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

package main

import (
	"fmt"
	"html/template"
	"io/ioutil"
	"net/http"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"

	"github.com/russross/blackfriday"
)

type Page struct {
	Title string
	Body  []byte
}

func (p *Page) save() error {
	filename := p.Title + ".txt"
	return ioutil.WriteFile(filename, p.Body, 0600)
}

func loadPage(title string) (*Page, error) {
	filename := title + ".txt"
	body, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	html := blackfriday.MarkdownCommon(body)
	fmt.Println(string(html)) // TODO remove
	return &Page{Title: title, Body: html}, nil
}

func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
	p, err := loadPage(title)
	if err != nil {
		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
		return
	}
	renderTemplate(w, "view", p)
}

func editHandler(w http.ResponseWriter, r *http.Request, title string) {
	p, err := loadPage(title)
	if err != nil {
		p = &Page{Title: title}
	}
	renderTemplate(w, "edit", p)
}

func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
	body := r.FormValue("body")
	p := &Page{Title: title, Body: []byte(body)}
	err := p.save()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	http.Redirect(w, r, "/view/"+title, http.StatusFound)
}

var templateDir string = "templates"
var templateFiles []string = []string{
	filepath.Join(templateDir, "edit.html"),
	filepath.Join(templateDir, "view.html")}

var templates = template.Must(template.ParseFiles(templateFiles...))

func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
	// TODO http://stackoverflow.com/questions/18589973/html-template-how-to-get-javascript-json-escaping-without-script-tag
	err := templates.ExecuteTemplate(w, tmpl+".html", p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

var validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$")

func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		m := validPath.FindStringSubmatch(r.URL.Path)
		if m == nil {
			http.NotFound(w, r)
			return
		}
		fn(w, r, m[2])
	}
}

func main() {
	var server = "localhost:8080"

	var browser *exec.Cmd
	var url string = "http://" + server + "/view/Home"

	switch runtime.GOOS {
	case "windows":
		browser = exec.Command(`C:\Windows\System32\rundll32.exe`, "url.dll,FileProtocolHandler", url)
	case "darwin":
		browser = exec.Command("open", url)
	default:
		browser = exec.Command("xdg-open", url)
	}
	if err := browser.Start(); err != nil {
		panic(err)
	}

	http.HandleFunc("/view/", makeHandler(viewHandler))
	http.HandleFunc("/edit/", makeHandler(editHandler))
	http.HandleFunc("/save/", makeHandler(saveHandler))
	http.ListenAndServe(server, nil)
}
<commit_msg>Moved the wiki pages into their own directory.<commit_after>// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package main

import (
	"fmt"
	"html/template"
	"io/ioutil"
	"net/http"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"runtime"

	"github.com/russross/blackfriday"
)

type Page struct {
	Title string
	Body  []byte
}

var pagesDir string = "pages"

func init() {
	if _, err := os.Stat(pagesDir); os.IsNotExist(err) {
		if err := os.Mkdir(pagesDir, 0700); err != nil {
			panic(err)
		}
	}
}

func (p *Page) save() error {
	filename := filepath.Join(pagesDir, p.Title+".txt")
	return ioutil.WriteFile(filename, p.Body, 0600)
}

func loadPage(title string) (*Page, error) {
	filename := filepath.Join(pagesDir, title+".txt")
	body, err := ioutil.ReadFile(filename)
	if err != nil {
		return nil, err
	}
	html := blackfriday.MarkdownCommon(body)
	fmt.Println(string(html)) // TODO remove
	return &Page{Title: title, Body: html}, nil
}

func viewHandler(w http.ResponseWriter, r *http.Request, title string) {
	p, err := loadPage(title)
	if err != nil {
		http.Redirect(w, r, "/edit/"+title, http.StatusFound)
		return
	}
	renderTemplate(w, "view", p)
}

func editHandler(w http.ResponseWriter, r *http.Request, title string) {
	p, err := loadPage(title)
	if err != nil {
		p = &Page{Title: title}
	}
	renderTemplate(w, "edit", p)
}

func saveHandler(w http.ResponseWriter, r *http.Request, title string) {
	body := r.FormValue("body")
	p := &Page{Title: title, Body: []byte(body)}
	err := p.save()
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}
	http.Redirect(w, r, "/view/"+title, http.StatusFound)
}

var templateDir string = "templates"
var templateFiles []string = []string{
	filepath.Join(templateDir, "edit.html"),
	filepath.Join(templateDir, "view.html")}

var templates = template.Must(template.ParseFiles(templateFiles...))

func renderTemplate(w http.ResponseWriter, tmpl string, p *Page) {
	// TODO http://stackoverflow.com/questions/18589973/html-template-how-to-get-javascript-json-escaping-without-script-tag
	err := templates.ExecuteTemplate(w, tmpl+".html", p)
	if err != nil {
		http.Error(w, err.Error(), http.StatusInternalServerError)
	}
}

var validPath = regexp.MustCompile("^/(edit|save|view)/([a-zA-Z0-9]+)$")

func makeHandler(fn func(http.ResponseWriter, *http.Request, string)) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		m := validPath.FindStringSubmatch(r.URL.Path)
		if m == nil {
			http.NotFound(w, r)
			return
		}
		fn(w, r, m[2])
	}
}

func main() {
	var server = "localhost:8080"

	var browser *exec.Cmd
	var url string = "http://" + server + "/view/Home"

	switch runtime.GOOS {
	case "windows":
		browser = exec.Command(`C:\Windows\System32\rundll32.exe`, "url.dll,FileProtocolHandler", url)
	case "darwin":
		browser = exec.Command("open", url)
	default:
		browser = exec.Command("xdg-open", url)
	}
	if err := browser.Start(); err != nil {
		panic(err)
	}

	http.HandleFunc("/view/", makeHandler(viewHandler))
	http.HandleFunc("/edit/", makeHandler(editHandler))
	http.HandleFunc("/save/", makeHandler(saveHandler))
	http.ListenAndServe(server, nil)
}
<|endoftext|>


<commit_before>package tsplitter

const (
	noneType = iota
	knownType
	ambiguousType
	unknownType
)

type Words struct {
	words     []string
	wordTypes []int
	size      int

	knownDeDup   map[string]struct{}
	unknownDeDup map[string]struct{}
}

func newWords() *Words {
	return &Words{
		knownDeDup:   make(map[string]struct{}),
		unknownDeDup: make(map[string]struct{}),
	}
}

func (w *Words) add(word string, wordType int) {
	w.words = append(w.words, word)
	w.wordTypes = append(w.wordTypes, wordType)
	w.addDedup(word, wordType)
	w.size++
}

func (w *Words) addDedup(word string, wordType int) {
	switch wordType {
	case knownType:
		w.knownDeDup[word] = struct{}{}
	case unknownType:
		w.unknownDeDup[word] = struct{}{}
	}
}

func (w *Words) removeDedup(word string, wordType int) {
	switch wordType {
	case knownType:
		delete(w.knownDeDup, word)
	case unknownType:
		delete(w.unknownDeDup, word)
	}
}

func (w *Words) addKnown(word string) {
	w.add(word, knownType)
}

func (w *Words) addUnKnown(word string) {
	w.add(word, unknownType)
}

func (w *Words) concatLast(word string, newWordType int) {
	last := w.size - 1

	w.removeDedup(w.words[last], w.wordTypes[last])
	w.words[last] += word
	w.wordTypes[last] = newWordType
	w.addDedup(w.words[last], w.wordTypes[last])
}

func (w *Words) isLastType(wordType int) bool {
	return w.wordTypes[w.size-1] == wordType
}

func (w *Words) All() []string {
	return w.words
}

func (w *Words) Unknown() []string {
	result := make([]string, len(w.unknownDeDup))
	i := 0
	for k, _ := range w.unknownDeDup {
		result[i] = k
		i++
	}

	return result
}

func (w *Words) Known() []string {
	result := make([]string, len(w.knownDeDup))
	i := 0
	for k, _ := range w.knownDeDup {
		result[i] = k
		i++
	}

	return result
}

func (w *Words) Size() int {
	return w.size
}
<commit_msg>go fmt<commit_after>package tsplitter

const (
	noneType = iota
	knownType
	ambiguousType
	unknownType
)

type Words struct {
	words     []string
	wordTypes []int
	size      int

	knownDeDup   map[string]struct{}
	unknownDeDup map[string]struct{}
}

func newWords() *Words {
	return &Words{
		knownDeDup:   make(map[string]struct{}),
		unknownDeDup: make(map[string]struct{}),
	}
}

func (w *Words) add(word string, wordType int) {
	w.words = append(w.words, word)
	w.wordTypes = append(w.wordTypes, wordType)
	w.addDedup(word, wordType)
	w.size++
}

func (w *Words) addDedup(word string, wordType int) {
	switch wordType {
	case knownType:
		w.knownDeDup[word] = struct{}{}
	case unknownType:
		w.unknownDeDup[word] = struct{}{}
	}
}

func (w *Words) removeDedup(word string, wordType int) {
	switch wordType {
	case knownType:
		delete(w.knownDeDup, word)
	case unknownType:
		delete(w.unknownDeDup, word)
	}
}

func (w *Words) addKnown(word string) {
	w.add(word, knownType)
}

func (w *Words) addUnKnown(word string) {
	w.add(word, unknownType)
}

func (w *Words) concatLast(word string, newWordType int) {
	last := w.size - 1

	w.removeDedup(w.words[last], w.wordTypes[last])
	w.words[last] += word
	w.wordTypes[last] = newWordType
	w.addDedup(w.words[last], w.wordTypes[last])
}

func (w *Words) isLastType(wordType int) bool {
	return w.wordTypes[w.size-1] == wordType
}

func (w *Words) All() []string {
	return w.words
}

func (w *Words) Unknown() []string {
	result := make([]string, len(w.unknownDeDup))
	i := 0
	for k := range w.unknownDeDup {
		result[i] = k
		i++
	}

	return result
}

func (w *Words) Known() []string {
	result := make([]string, len(w.knownDeDup))
	i := 0
	for k := range w.knownDeDup {
		result[i] = k
		i++
	}

	return result
}

func (w *Words) Size() int {
	return w.size
}
<|endoftext|>


<commit_before>package main

import (
	"archive/tar"
	"compress/gzip"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"mime"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
	"syscall"

	"cloud.google.com/go/pubsub"
	"cloud.google.com/go/storage"
	"golang.org/x/net/context"
)

const updateTopicString string = "onesie-updates"
const updateSub string = "onesie-server"

func main() {
	log.Println("Starting")
	pubsubClient, err := pubsub.NewClient(context.Background(), "940380154622")
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}

	updateTopic := pubsubClient.Topic(updateTopicString)
	sub := pubsubClient.Subscription(updateSub)
	b, err := sub.Exists(context.Background())
	if err != nil {
		log.Fatal(err)
	}
	if !b {
		sub, err = pubsubClient.CreateSubscription(context.Background(), updateSub, pubsub.SubscriptionConfig{
			Topic: updateTopic,
		})
		if err != nil {
			log.Fatal(err)
		}
	}

	var mu sync.Mutex
	received := 0
	cctx, cancel := context.WithCancel(context.Background())
	err = sub.Receive(cctx, func(ctx context.Context, msg *pubsub.Message) {
		mu.Lock()
		defer mu.Unlock()
		received++
		if received >= 4 {
			cancel()
			msg.Nack()
			return
		}

		fmt.Printf("Got message: %q\n", string(msg.Data))

		if msgStr == "deploy" {
			// TODO: Figure out which thing to update
			domain := msg.Attributes["domain"]
			path := msg.Attributes["path"]

			// Expand into archive
			archive, err := gzip.NewReader(bufr)
			if err != nil {
				log.Panicf("Error creating gzip reader: %+v", err)
			}
			defer archive.Close()

			// Go through file by file
			tarReader := tar.NewReader(archive)
			buf := make([]byte, 160)
			for {
				header, err := tarReader.Next()
				if err == io.EOF {
					break
				} else if err != nil {
					log.Panicf("Error reading tar: %+v", err)
				}

				path := filepath.Join(domain, header.Name)
				switch header.Typeflag {
				case tar.TypeDir:
					continue
				case tar.TypeReg:
					w := bkt.Object(path).NewWriter(c)
					defer w.Close()
					w.ACL = []storage.ACLRule{{Entity: storage.AllUsers, Role: storage.RoleReader}}
					if filepath.Ext(path) != "" {
						w.ObjectAttrs.ContentType = mime.TypeByExtension(filepath.Ext(path))
					}
					wrtn, err := io.CopyBuffer(w, tarReader, buf)
					if err != nil {
						log.Printf("Error writing data to GCS: %+v", err)
					}
					log.Printf("Wrote %v bytes to %s", wrtn, path)
				default:
					log.Printf("Unable to figure out type: %v (%s)", header.Typeflag, path)
				}
			}
		}

		if msgStr == "update" {
			// Merge Certs
			files, err := ioutil.ReadDir("/opt/onesie-configs/certs/")
			if err != nil {
				log.Fatalf("Error iterating through files: %+v", err)
			}

			dhparam, err := ioutil.ReadFile(fmt.Sprintf("/opt/onesie-configs/dhparam.pem"))
			if err != nil {
				log.Fatalf("Error reading dhparam: %+v", err)
			}

			for _, file := range files {
				// cat /opt/onesie-configs/certs/$i/{privkey,fullchain}.pem /opt/onesie-configs/dhparam.pem > /opt/onesie-configs/hitch/$i.pem
				log.Printf("Parsing file: %+v", file)
				privkey, err := ioutil.ReadFile(fmt.Sprintf("/opt/onesie-configs/certs/%s/privkey.pem", file.Name()))
				if err != nil {
					log.Printf("Error reading privkey: %+v", err)
					continue
				}
				fullchain, err := ioutil.ReadFile(fmt.Sprintf("/opt/onesie-configs/certs/%s/fullchain.pem", file.Name()))
				if err != nil {
					log.Printf("Error reading fullchain: %+v", err)
					continue
				}

				// Write out
				f, err := os.OpenFile(fmt.Sprintf("/opt/onesie-configs/hitch/%s.pem", file.Name()), os.O_APPEND|os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
				if err != nil {
					log.Printf("Error opening output pem: %+v", err)
					continue
				}
				defer f.Close()

				if _, err = f.Write(privkey); err != nil {
					log.Printf("Error writing privkey to output pem: %+v", err)
					continue
				}
				if _, err = f.Write(fullchain); err != nil {
					log.Printf("Error writing fullchain to output pem: %+v", err)
					continue
				}
				if _, err = f.Write(dhparam); err != nil {
					log.Printf("Error writing dhparam to output pem: %+v", err)
					continue
				}
			}

			// Get hitch PID, send sighup
			out, err := exec.Command("/bin/pidof", "hitch").Output()
			if err != nil {
				log.Printf("Error running pidof: %+v", err)
			}
			for _, pidStr := range strings.Split(string(out), " ") {
				pid, err := strconv.Atoi(strings.TrimSpace(pidStr))
				if err != nil {
					log.Printf("Error parsing string: %+v", err)
					continue
				}
				log.Printf("Sending SIGHUP to %+v", pid)
				syscall.Kill(pid, syscall.SIGHUP)
			}
		}
		msg.Ack()
	})

	if err != nil {
		log.Println(err)
	}

	log.Println("Finished.")
}
<commit_msg>Get everything compiling<commit_after>package main

import (
	"archive/tar"
	"compress/gzip"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"mime"
	"os"
	"os/exec"
	"path/filepath"
	"strconv"
	"strings"
	"sync"
	"syscall"

	"cloud.google.com/go/pubsub"
	"cloud.google.com/go/storage"
	"golang.org/x/net/context"
)

const updateTopicString string = "onesie-updates"
const updateSub string = "onesie-server"

func main() {
	log.Println("Starting")
	pubsubClient, err := pubsub.NewClient(context.Background(), "940380154622")
	if err != nil {
		log.Fatalf("Failed to create client: %v", err)
	}

	updateTopic := pubsubClient.Topic(updateTopicString)
	sub := pubsubClient.Subscription(updateSub)
	b, err := sub.Exists(context.Background())
	if err != nil {
		log.Fatal(err)
	}
	if !b {
		sub, err = pubsubClient.CreateSubscription(context.Background(), updateSub, pubsub.SubscriptionConfig{
			Topic: updateTopic,
		})
		if err != nil {
			log.Fatal(err)
		}
	}

	var mu sync.Mutex
	received := 0
	cctx, cancel := context.WithCancel(context.Background())
	err = sub.Receive(cctx, func(ctx context.Context, msg *pubsub.Message) {
		mu.Lock()
		defer mu.Unlock()
		received++
		if received >= 4 {
			cancel()
			msg.Nack()
			return
		}

		msgStr := string(msg.Data)
		fmt.Printf("Got message: %q\n", msgStr)

		if msgStr == "deploy" {
			domain := msg.Attributes["domain"]
			path := msg.Attributes["path"]
			log.Printf("Opening for archive: %s", path)

			// Open google storage client
			client, err := storage.NewClient(ctx)
			if err != nil {
				log.Panicf("Error connecting to Google Storage: %+v", err)
			}
			defer client.Close()
			bkt := client.Bucket("onesie")
			obj := bkt.Object(path)
			r, err := obj.NewReader(ctx)
			if err != nil {
				log.Panicf("Error opening object: %+v", err)
			}
			defer r.Close()

			// Expand into archive
			archive, err := gzip.NewReader(r)
			if err != nil {
				log.Panicf("Error creating gzip reader: %+v", err)
			}
			defer archive.Close()

			// Go through file by file
			tarReader := tar.NewReader(archive)
			buf := make([]byte, 160)
			for {
				header, err := tarReader.Next()
				if err == io.EOF {
					break
				} else if err != nil {
					log.Panicf("Error reading tar: %+v", err)
				}

				path := filepath.Join(domain, header.Name)
				switch header.Typeflag {
				case tar.TypeDir:
					continue
				case tar.TypeReg:
					w := bkt.Object(path).NewWriter(ctx)
					defer w.Close()
					w.ACL = []storage.ACLRule{{Entity: storage.AllUsers, Role: storage.RoleReader}}
					if filepath.Ext(path) != "" {
						w.ObjectAttrs.ContentType = mime.TypeByExtension(filepath.Ext(path))
					}
					wrtn, err := io.CopyBuffer(w, tarReader, buf)
					if err != nil {
						log.Printf("Error writing data to GCS: %+v", err)
					}
					log.Printf("Wrote %v bytes to %s", wrtn, path)
				default:
					log.Printf("Unable to figure out type: %v (%s)", header.Typeflag, path)
				}
			}
		}

		if msgStr == "update" {
			// Merge Certs
			files, err := ioutil.ReadDir("/opt/onesie-configs/certs/")
			if err != nil {
				log.Fatalf("Error iterating through files: %+v", err)
			}

			dhparam, err := ioutil.ReadFile(fmt.Sprintf("/opt/onesie-configs/dhparam.pem"))
			if err != nil {
				log.Fatalf("Error reading dhparam: %+v", err)
			}

			for _, file := range files {
				// cat /opt/onesie-configs/certs/$i/{privkey,fullchain}.pem /opt/onesie-configs/dhparam.pem > /opt/onesie-configs/hitch/$i.pem
				log.Printf("Parsing file: %+v", file)
				privkey, err := ioutil.ReadFile(fmt.Sprintf("/opt/onesie-configs/certs/%s/privkey.pem", file.Name()))
				if err != nil {
					log.Printf("Error reading privkey: %+v", err)
					continue
				}
				fullchain, err := ioutil.ReadFile(fmt.Sprintf("/opt/onesie-configs/certs/%s/fullchain.pem", file.Name()))
				if err != nil {
					log.Printf("Error reading fullchain: %+v", err)
					continue
				}

				// Write out
				f, err := os.OpenFile(fmt.Sprintf("/opt/onesie-configs/hitch/%s.pem", file.Name()), os.O_APPEND|os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
				if err != nil {
					log.Printf("Error opening output pem: %+v", err)
					continue
				}
				defer f.Close()

				if _, err = f.Write(privkey); err != nil {
					log.Printf("Error writing privkey to output pem: %+v", err)
					continue
				}
				if _, err = f.Write(fullchain); err != nil {
					log.Printf("Error writing fullchain to output pem: %+v", err)
					continue
				}
				if _, err = f.Write(dhparam); err != nil {
					log.Printf("Error writing dhparam to output pem: %+v", err)
					continue
				}
			}

			// Get hitch PID, send sighup
			out, err := exec.Command("/bin/pidof", "hitch").Output()
			if err != nil {
				log.Printf("Error running pidof: %+v", err)
			}
			for _, pidStr := range strings.Split(string(out), " ") {
				pid, err := strconv.Atoi(strings.TrimSpace(pidStr))
				if err != nil {
					log.Printf("Error parsing string: %+v", err)
					continue
				}
				log.Printf("Sending SIGHUP to %+v", pid)
				syscall.Kill(pid, syscall.SIGHUP)
			}
		}
		msg.Ack()
	})

	if err != nil {
		log.Println(err)
	}

	log.Println("Finished.")
}
<|endoftext|>


<commit_before>// Copyright 2016 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package factom_test

import (
	"testing"

	"fmt"
	"net/http"
	"net/http/httptest"

	. "github.com/FactomProject/factom"
)

func TestAckStrings(t *testing.T) {
	status := new(EntryStatus)
	status.CommitTxID = "107c239ee41bb2b0cfa19d8760deb82c942f1bac8ad99516f2f801bf16ae2998"
	//status.EntryHash = "1b363e01af0c0e28f0acbc33bc816ec11f4b28680797e74e341476409dd52295"
	gtd := new(TransactionData)
	gtd.Status = "TransactionACK"
	gtd.TransactionDateString = "2017-02-15 13:01:41"

	status.CommitData = *gtd

	entryPrintout := status.String()

	expectedString := `TxID: 107c239ee41bb2b0cfa19d8760deb82c942f1bac8ad99516f2f801bf16ae2998
Status: TransactionACK
Date: 2017-02-15 13:01:41
`
	if entryPrintout != expectedString {
		t.Errorf("expected:%s\nrecieved:%s", expectedString, entryPrintout)
	}
	t.Log(entryPrintout)

	txstatus := new(FactoidTxStatus)
	txstatus.TxID = "b8b12fba54bd1857b0262bba1b71dbeb4e17404570c2ebe50de0dabf061d575c"
	//gtdfct := new(GeneralTransactionData)
	txstatus.Status = "TransactionACK"
	txstatus.TransactionDateString = "2017-02-15 15:07:27"
	//txstatus.CommitData = *gtdfct
	fctPrintout := txstatus.String()

	expectedfctString := `TxID: b8b12fba54bd1857b0262bba1b71dbeb4e17404570c2ebe50de0dabf061d575c
Status: TransactionACK
Date: 2017-02-15 15:07:27
`
	if fctPrintout != expectedfctString {
		t.Errorf("expected:%s\nrecieved:%s", expectedfctString, fctPrintout)
	}
	t.Log(fctPrintout)
}

func TestAckFct(t *testing.T) {

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, `{
   "jsonrpc":"2.0",
   "id":0,
   "result":{
      "txid":"f1d9919829fa71ce18caf1bd8659cce8a06c0026d3f3fffc61054ebb25ebeaa0",
      "transactiondate":1441138021975,
      "transactiondatestring":"2015-09-01 15:07:01",
      "blockdate":1441137600000,
      "blockdatestring":"2015-09-01 15:00:00",
      "status":"DBlockConfirmed"
   }
}`)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)

	//tx := "02015a43cc6d37010100afd7c200031cce24bcc43b596af105167de2c03603c20ada3314a7cfb47befcad4883e6fafd6e4200ceb0a10711f9fb61bc983cb4761817e4b3ff6c31ab0d5da6afb03625e368859013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29dcc6c027a9d321129381d2d8badb3ccd591fd8a515166ca09a8a72cbf3837916c8e4789b0452dffc708ccde097163a86fd0ac23b11416cebb7ccebcdadbba908"
	//txid := "d998c577a9da5dab3d5634753db3e377e392d72d0204d31bd922df483546da4d"
	tx := "dummy1"
	txid := "dummy2"

	txStatus, err := FactoidACK(txid, tx)
	if err != nil {
		t.Error(err)
	}

	expectedfctString := `TxID: f1d9919829fa71ce18caf1bd8659cce8a06c0026d3f3fffc61054ebb25ebeaa0
Status: DBlockConfirmed
Date: 2015-09-01 15:07:01
`
	if txStatus.String() != expectedfctString {
		t.Errorf("expected:%s\nrecieved:%s", expectedfctString, txStatus.String())
	}
	t.Log(txStatus.String())
}

func TestAckEntry(t *testing.T) {

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, `{
   "jsonrpc":"2.0",
   "id":0,
   "result":{
      "committxid":"e5b5be39a41df43a3c46beaa238dc5e6f7bb11115a8da1a9b45cd694e257935a",
      "entryhash":"9228b4b080b3cf94cceea866b74c48319f2093f56bd5a63465288e9a71437ee8",
      "commitdata":{
         "transactiondate":1449547801861,
         "transactiondatestring":"2015-12-07 22:10:01",
         "blockdate":1449547800000,
         "blockdatestring":"2015-12-07 22:10:00",
         "status":"DBlockConfirmed"
      },
      "entrydata":{
         "blockdate":1449547800000,
         "blockdatestring":"2015-12-07 22:10:00",
         "status":"DBlockConfirmed"
      }
   }
}`)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	//fmt.Println("exposed URL:",url)
	SetFactomdServer(url)

	tx := "dummy1"
	ehash := "dummy2"

	entryStatus, err := EntryRevealACK(ehash, tx, ZeroHash)
	if err != nil {
		t.Error(err)
	}

	expectedEntryString := `EntryHash: 9228b4b080b3cf94cceea866b74c48319f2093f56bd5a63465288e9a71437ee8
Status: DBlockConfirmed
` +
		`Date: ` +
		`
TxID: e5b5be39a41df43a3c46beaa238dc5e6f7bb11115a8da1a9b45cd694e257935a
Status: DBlockConfirmed
Date: 2015-12-07 22:10:01
`
	if entryStatus.String() != expectedEntryString {
		t.Errorf("expected:%s\nrecieved:%s", expectedEntryString, entryStatus.String())
	}
	t.Log(entryStatus.String())
}
<commit_msg>test cleanup<commit_after>// Copyright 2016 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package factom_test

import (
	"testing"

	"fmt"
	"net/http"
	"net/http/httptest"

	. "github.com/FactomProject/factom"
)

// TODO: these tests need a lot of cleanup, possibly just re-write

func TestAckStrings(t *testing.T) {
	status := new(EntryStatus)
	status.CommitTxID = "107c239ee41bb2b0cfa19d8760deb82c942f1bac8ad99516f2f801bf16ae2998"
	//status.EntryHash = "1b363e01af0c0e28f0acbc33bc816ec11f4b28680797e74e341476409dd52295"
	gtd := new(TransactionData)
	gtd.Status = "TransactionACK"
	gtd.TransactionDateString = "2017-02-15 13:01:41"

	status.CommitData = *gtd

	entryPrintout := status.String()

	expectedString := `TxID: 107c239ee41bb2b0cfa19d8760deb82c942f1bac8ad99516f2f801bf16ae2998
Status: TransactionACK
Date: 2017-02-15 13:01:41
`
	if entryPrintout != expectedString {
		t.Errorf("expected:%s\nrecieved:%s", expectedString, entryPrintout)
	}
	t.Log(entryPrintout)

	txstatus := new(FactoidTxStatus)
	txstatus.TxID = "b8b12fba54bd1857b0262bba1b71dbeb4e17404570c2ebe50de0dabf061d575c"
	//gtdfct := new(GeneralTransactionData)
	txstatus.Status = "TransactionACK"
	txstatus.TransactionDateString = "2017-02-15 15:07:27"
	//txstatus.CommitData = *gtdfct
	fctPrintout := txstatus.String()

	expectedfctString := `TxID: b8b12fba54bd1857b0262bba1b71dbeb4e17404570c2ebe50de0dabf061d575c
Status: TransactionACK
Date: 2017-02-15 15:07:27
`
	if fctPrintout != expectedfctString {
		t.Errorf("expected:%s\nrecieved:%s", expectedfctString, fctPrintout)
	}
	t.Log(fctPrintout)
}

func TestAckFct(t *testing.T) {

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, `{
		   "jsonrpc":"2.0",
		   "id":0,
		   "result":{
		      "txid":"f1d9919829fa71ce18caf1bd8659cce8a06c0026d3f3fffc61054ebb25ebeaa0",
		      "transactiondate":1441138021975,
		      "transactiondatestring":"2015-09-01 15:07:01",
		      "blockdate":1441137600000,
		      "blockdatestring":"2015-09-01 15:00:00",
		      "status":"DBlockConfirmed"
		   }
		}`)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	SetFactomdServer(url)

	//tx := "02015a43cc6d37010100afd7c200031cce24bcc43b596af105167de2c03603c20ada3314a7cfb47befcad4883e6fafd6e4200ceb0a10711f9fb61bc983cb4761817e4b3ff6c31ab0d5da6afb03625e368859013b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29dcc6c027a9d321129381d2d8badb3ccd591fd8a515166ca09a8a72cbf3837916c8e4789b0452dffc708ccde097163a86fd0ac23b11416cebb7ccebcdadbba908"
	//txid := "d998c577a9da5dab3d5634753db3e377e392d72d0204d31bd922df483546da4d"
	tx := "dummy1"
	txid := "dummy2"

	txStatus, err := FactoidACK(txid, tx)
	if err != nil {
		t.Error(err)
	}

	expectedfctString := `TxID: f1d9919829fa71ce18caf1bd8659cce8a06c0026d3f3fffc61054ebb25ebeaa0
Status: DBlockConfirmed
Date: 2015-09-01 15:07:01
`
	if txStatus.String() != expectedfctString {
		t.Errorf("expected:%s\nrecieved:%s", expectedfctString, txStatus.String())
	}
	t.Log(txStatus.String())
}

func TestAckEntry(t *testing.T) {

	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "application/json")
		fmt.Fprintln(w, `{
		   "jsonrpc":"2.0",
		   "id":0,
		   "result":{
		      "committxid":"e5b5be39a41df43a3c46beaa238dc5e6f7bb11115a8da1a9b45cd694e257935a",
		      "entryhash":"9228b4b080b3cf94cceea866b74c48319f2093f56bd5a63465288e9a71437ee8",
		      "commitdata":{
		         "transactiondate":1449547801861,
		         "transactiondatestring":"2015-12-07 22:10:01",
		         "blockdate":1449547800000,
		         "blockdatestring":"2015-12-07 22:10:00",
		         "status":"DBlockConfirmed"
		      },
		      "entrydata":{
		         "blockdate":1449547800000,
		         "blockdatestring":"2015-12-07 22:10:00",
		         "status":"DBlockConfirmed"
		      }
		   }
		}`)
	}))
	defer ts.Close()

	url := ts.URL[7:]
	//fmt.Println("exposed URL:",url)
	SetFactomdServer(url)

	tx := "dummy1"
	ehash := "dummy2"

	entryStatus, err := EntryRevealACK(ehash, tx, ZeroHash)
	if err != nil {
		t.Error(err)
	}

	expectedEntryString := `EntryHash: 9228b4b080b3cf94cceea866b74c48319f2093f56bd5a63465288e9a71437ee8
Status: DBlockConfirmed
` +
		`Date: ` +
		`
TxID: e5b5be39a41df43a3c46beaa238dc5e6f7bb11115a8da1a9b45cd694e257935a
Status: DBlockConfirmed
Date: 2015-12-07 22:10:01
`
	if entryStatus.String() != expectedEntryString {
		t.Errorf("expected:%s\nrecieved:%s", expectedEntryString, entryStatus.String())
	}
	t.Log(entryStatus.String())
}
<|endoftext|>