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

package models

import (
	"bufio"
	"container/list"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path"
	"strings"

	"github.com/gogits/git"

	"github.com/gogits/gogs/modules/base"
)

// RepoFile represents a file object in git repository.
type RepoFile struct {
	*git.TreeEntry
	Path   string
	Size   int64
	Repo   *git.Repository
	Commit *git.Commit
}

// LookupBlob returns the content of an object.
func (file *RepoFile) LookupBlob() (*git.Blob, error) {
	if file.Repo == nil {
		return nil, ErrRepoFileNotLoaded
	}

	return file.Repo.LookupBlob(file.Id)
}

// GetBranches returns all branches of given repository.
func GetBranches(userName, repoName string) ([]string, error) {
	repo, err := git.OpenRepository(RepoPath(userName, repoName))
	if err != nil {
		return nil, err
	}

	refs, err := repo.AllReferences()
	if err != nil {
		return nil, err
	}

	brs := make([]string, len(refs))
	for i, ref := range refs {
		brs[i] = ref.BranchName()
	}
	return brs, nil
}

// GetTags returns all tags of given repository.
func GetTags(userName, repoName string) ([]string, error) {
	repo, err := git.OpenRepository(RepoPath(userName, repoName))
	if err != nil {
		return nil, err
	}

	refs, err := repo.AllTags()
	if err != nil {
		return nil, err
	}

	tags := make([]string, len(refs))
	for i, ref := range refs {
		tags[i] = ref.Name
	}
	return tags, nil
}

func IsBranchExist(userName, repoName, branchName string) bool {
	repo, err := git.OpenRepository(RepoPath(userName, repoName))
	if err != nil {
		return false
	}
	return repo.IsBranchExist(branchName)
}

func GetTargetFile(userName, repoName, branchName, commitId, rpath string) (*RepoFile, error) {
	repo, err := git.OpenRepository(RepoPath(userName, repoName))
	if err != nil {
		return nil, err
	}

	commit, err := repo.GetCommitOfBranch(branchName)
	if err != nil {
		commit, err = repo.GetCommit(commitId)
		if err != nil {
			return nil, err
		}
	}

	parts := strings.Split(path.Clean(rpath), "/")

	var entry *git.TreeEntry
	tree := commit.Tree
	for i, part := range parts {
		if i == len(parts)-1 {
			entry = tree.EntryByName(part)
			if entry == nil {
				return nil, ErrRepoFileNotExist
			}
		} else {
			tree, err = repo.SubTree(tree, part)
			if err != nil {
				return nil, err
			}
		}
	}

	size, err := repo.ObjectSize(entry.Id)
	if err != nil {
		return nil, err
	}

	repoFile := &RepoFile{
		entry,
		rpath,
		size,
		repo,
		commit,
	}

	return repoFile, nil
}

// GetReposFiles returns a list of file object in given directory of repository.
// func GetReposFilesOfBranch(userName, repoName, branchName, rpath string) ([]*RepoFile, error) {
// 	return getReposFiles(userName, repoName, commitId, rpath)
// }

// GetReposFiles returns a list of file object in given directory of repository.
func GetReposFiles(userName, repoName, commitId, rpath string) ([]*RepoFile, error) {
	return getReposFiles(userName, repoName, commitId, rpath)
}

func getReposFiles(userName, repoName, commitId string, rpath string) ([]*RepoFile, error) {
	repo, err := git.OpenRepository(RepoPath(userName, repoName))
	if err != nil {
		return nil, err
	}

	commit, err := repo.GetCommit(commitId)
	if err != nil {
		return nil, err
	}

	var repodirs []*RepoFile
	var repofiles []*RepoFile
	commit.Tree.Walk(func(dirname string, entry *git.TreeEntry) int {
		if dirname == rpath {
			// TODO: size get method shoule be improved
			size, err := repo.ObjectSize(entry.Id)
			if err != nil {
				return 0
			}

			var cm = commit
			var i int
			for {
				i = i + 1
				//fmt.Println(".....", i, cm.Id(), cm.ParentCount())
				if cm.ParentCount() == 0 {
					break
				} else if cm.ParentCount() == 1 {
					pt, _ := repo.SubTree(cm.Parent(0).Tree, dirname)
					if pt == nil {
						break
					}
					pEntry := pt.EntryByName(entry.Name)
					if pEntry == nil || !pEntry.Id.Equal(entry.Id) {
						break
					} else {
						cm = cm.Parent(0)
					}
				} else {
					var emptyCnt = 0
					var sameIdcnt = 0
					var lastSameCm *git.Commit
					//fmt.Println(".....", cm.ParentCount())
					for i := 0; i < cm.ParentCount(); i++ {
						//fmt.Println("parent", i, cm.Parent(i).Id())
						p := cm.Parent(i)
						pt, _ := repo.SubTree(p.Tree, dirname)
						var pEntry *git.TreeEntry
						if pt != nil {
							pEntry = pt.EntryByName(entry.Name)
						}

						//fmt.Println("pEntry", pEntry)

						if pEntry == nil {
							emptyCnt = emptyCnt + 1
							if emptyCnt+sameIdcnt == cm.ParentCount() {
								if lastSameCm == nil {
									goto loop
								} else {
									cm = lastSameCm
									break
								}
							}
						} else {
							//fmt.Println(i, "pEntry", pEntry.Id, "entry", entry.Id)
							if !pEntry.Id.Equal(entry.Id) {
								goto loop
							} else {
								lastSameCm = cm.Parent(i)
								sameIdcnt = sameIdcnt + 1
								if emptyCnt+sameIdcnt == cm.ParentCount() {
									// TODO: now follow the first parent commit?
									cm = lastSameCm
									//fmt.Println("sameId...")
									break
								}
							}
						}
					}
				}
			}

		loop:

			rp := &RepoFile{
				entry,
				path.Join(dirname, entry.Name),
				size,
				repo,
				cm,
			}

			if entry.IsFile() {
				repofiles = append(repofiles, rp)
			} else if entry.IsDir() {
				repodirs = append(repodirs, rp)
			}
		}
		return 0
	})

	return append(repodirs, repofiles...), nil
}

func GetCommit(userName, repoName, commitId string) (*git.Commit, error) {
	repo, err := git.OpenRepository(RepoPath(userName, repoName))
	if err != nil {
		return nil, err
	}

	return repo.GetCommit(commitId)
}

// GetCommitsByBranch returns all commits of given branch of repository.
func GetCommitsByBranch(userName, repoName, branchName string) (*list.List, error) {
	repo, err := git.OpenRepository(RepoPath(userName, repoName))
	if err != nil {
		return nil, err
	}
	r, err := repo.LookupReference(fmt.Sprintf("refs/heads/%s", branchName))
	if err != nil {
		return nil, err
	}
	return r.AllCommits()
}

// GetCommitsByCommitId returns all commits of given commitId of repository.
func GetCommitsByCommitId(userName, repoName, commitId string) (*list.List, error) {
	repo, err := git.OpenRepository(RepoPath(userName, repoName))
	if err != nil {
		return nil, err
	}
	oid, err := git.NewOidFromString(commitId)
	if err != nil {
		return nil, err
	}
	return repo.CommitsBefore(oid)
}

// Diff line types.
const (
	DIFF_LINE_PLAIN = iota + 1
	DIFF_LINE_ADD
	DIFF_LINE_DEL
	DIFF_LINE_SECTION
)

const (
	DIFF_FILE_ADD = iota + 1
	DIFF_FILE_CHANGE
	DIFF_FILE_DEL
)

type DiffLine struct {
	LeftIdx  int
	RightIdx int
	Type     int
	Content  string
}

func (d DiffLine) GetType() int {
	return d.Type
}

type DiffSection struct {
	Name  string
	Lines []*DiffLine
}

type DiffFile struct {
	Name               string
	Addition, Deletion int
	Type               int
	Sections           []*DiffSection
}

type Diff struct {
	TotalAddition, TotalDeletion int
	Files                        []*DiffFile
}

func (diff *Diff) NumFiles() int {
	return len(diff.Files)
}

const DIFF_HEAD = "diff --git "

func ParsePatch(reader io.Reader) (*Diff, error) {
	scanner := bufio.NewScanner(reader)
	var (
		curFile    *DiffFile
		curSection = &DiffSection{
			Lines: make([]*DiffLine, 0, 10),
		}

		leftLine, rightLine int
	)

	diff := &Diff{Files: make([]*DiffFile, 0)}
	var i int
	for scanner.Scan() {
		line := scanner.Text()
		// fmt.Println(i, line)
		if strings.HasPrefix(line, "+++ ") || strings.HasPrefix(line, "--- ") {
			continue
		}

		i = i + 1
		if line == "" {
			continue
		}
		if line[0] == ' ' {
			diffLine := &DiffLine{Type: DIFF_LINE_PLAIN, Content: line, LeftIdx: leftLine, RightIdx: rightLine}
			leftLine++
			rightLine++
			curSection.Lines = append(curSection.Lines, diffLine)
			continue
		} else if line[0] == '@' {
			curSection = &DiffSection{}
			curFile.Sections = append(curFile.Sections, curSection)
			ss := strings.Split(line, "@@")
			diffLine := &DiffLine{Type: DIFF_LINE_SECTION, Content: line}
			curSection.Lines = append(curSection.Lines, diffLine)

			// Parse line number.
			ranges := strings.Split(ss[len(ss)-2][1:], " ")
			leftLine, _ = base.StrTo(strings.Split(ranges[0], ",")[0][1:]).Int()
			rightLine, _ = base.StrTo(strings.Split(ranges[1], ",")[0]).Int()
			continue
		} else if line[0] == '+' {
			curFile.Addition++
			diff.TotalAddition++
			diffLine := &DiffLine{Type: DIFF_LINE_ADD, Content: line, RightIdx: rightLine}
			rightLine++
			curSection.Lines = append(curSection.Lines, diffLine)
			continue
		} else if line[0] == '-' {
			curFile.Deletion++
			diff.TotalDeletion++
			diffLine := &DiffLine{Type: DIFF_LINE_DEL, Content: line, LeftIdx: leftLine}
			if leftLine > 0 {
				leftLine++
			}
			curSection.Lines = append(curSection.Lines, diffLine)
			continue
		}

		// Get new file.
		if strings.HasPrefix(line, DIFF_HEAD) {
			fs := strings.Split(line[len(DIFF_HEAD):], " ")
			a := fs[0]

			curFile = &DiffFile{
				Name:     a[strings.Index(a, "/")+1:],
				Type:     DIFF_FILE_CHANGE,
				Sections: make([]*DiffSection, 0, 10),
			}
			diff.Files = append(diff.Files, curFile)

			// Check file diff type.
			for scanner.Scan() {
				switch {
				case strings.HasPrefix(scanner.Text(), "new file"):
					curFile.Type = DIFF_FILE_ADD
				case strings.HasPrefix(scanner.Text(), "deleted"):
					curFile.Type = DIFF_FILE_DEL
				case strings.HasPrefix(scanner.Text(), "index"):
					curFile.Type = DIFF_FILE_CHANGE
				}
				if curFile.Type > 0 {
					break
				}
			}
		}
	}

	return diff, nil
}

func GetDiff(repoPath, commitid string) (*Diff, error) {
	repo, err := git.OpenRepository(repoPath)
	if err != nil {
		return nil, err
	}

	commit, err := repo.GetCommit(commitid)
	if err != nil {
		return nil, err
	}

	// First commit of repository.
	if commit.ParentCount() == 0 {
		rd, wr := io.Pipe()
		go func() {
			cmd := exec.Command("git", "show", commitid)
			cmd.Dir = repoPath
			cmd.Stdout = wr
			cmd.Stdin = os.Stdin
			cmd.Stderr = os.Stderr
			cmd.Run()
			wr.Close()
		}()
		defer rd.Close()
		return ParsePatch(rd)
	}

	rd, wr := io.Pipe()
	go func() {
		cmd := exec.Command("git", "diff", commit.Parent(0).Oid.String(), commitid)
		cmd.Dir = repoPath
		cmd.Stdout = wr
		cmd.Stdin = os.Stdin
		cmd.Stderr = os.Stderr
		cmd.Run()
		wr.Close()
	}()
	defer rd.Close()
	return ParsePatch(rd)
}
<commit_msg>speedup models.getReposFiles, using os.Exec but the results may different with before<commit_after>// Copyright 2014 The Gogs Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.

package models

import (
	"bufio"
	"container/list"
	"fmt"
	"io"
	"os"
	"os/exec"
	"path"
	"strings"

	"github.com/gogits/git"

	"github.com/gogits/gogs/modules/base"
)

// RepoFile represents a file object in git repository.
type RepoFile struct {
	*git.TreeEntry
	Path   string
	Size   int64
	Repo   *git.Repository
	Commit *git.Commit
}

// LookupBlob returns the content of an object.
func (file *RepoFile) LookupBlob() (*git.Blob, error) {
	if file.Repo == nil {
		return nil, ErrRepoFileNotLoaded
	}

	return file.Repo.LookupBlob(file.Id)
}

// GetBranches returns all branches of given repository.
func GetBranches(userName, repoName string) ([]string, error) {
	repo, err := git.OpenRepository(RepoPath(userName, repoName))
	if err != nil {
		return nil, err
	}

	refs, err := repo.AllReferences()
	if err != nil {
		return nil, err
	}

	brs := make([]string, len(refs))
	for i, ref := range refs {
		brs[i] = ref.BranchName()
	}
	return brs, nil
}

// GetTags returns all tags of given repository.
func GetTags(userName, repoName string) ([]string, error) {
	repo, err := git.OpenRepository(RepoPath(userName, repoName))
	if err != nil {
		return nil, err
	}

	refs, err := repo.AllTags()
	if err != nil {
		return nil, err
	}

	tags := make([]string, len(refs))
	for i, ref := range refs {
		tags[i] = ref.Name
	}
	return tags, nil
}

func IsBranchExist(userName, repoName, branchName string) bool {
	repo, err := git.OpenRepository(RepoPath(userName, repoName))
	if err != nil {
		return false
	}
	return repo.IsBranchExist(branchName)
}

func GetTargetFile(userName, repoName, branchName, commitId, rpath string) (*RepoFile, error) {
	repo, err := git.OpenRepository(RepoPath(userName, repoName))
	if err != nil {
		return nil, err
	}

	commit, err := repo.GetCommitOfBranch(branchName)
	if err != nil {
		commit, err = repo.GetCommit(commitId)
		if err != nil {
			return nil, err
		}
	}

	parts := strings.Split(path.Clean(rpath), "/")

	var entry *git.TreeEntry
	tree := commit.Tree
	for i, part := range parts {
		if i == len(parts)-1 {
			entry = tree.EntryByName(part)
			if entry == nil {
				return nil, ErrRepoFileNotExist
			}
		} else {
			tree, err = repo.SubTree(tree, part)
			if err != nil {
				return nil, err
			}
		}
	}

	size, err := repo.ObjectSize(entry.Id)
	if err != nil {
		return nil, err
	}

	repoFile := &RepoFile{
		entry,
		rpath,
		size,
		repo,
		commit,
	}

	return repoFile, nil
}

// GetReposFiles returns a list of file object in given directory of repository.
// func GetReposFilesOfBranch(userName, repoName, branchName, rpath string) ([]*RepoFile, error) {
// 	return getReposFiles(userName, repoName, commitId, rpath)
// }

// GetReposFiles returns a list of file object in given directory of repository.
func GetReposFiles(userName, repoName, commitId, rpath string) ([]*RepoFile, error) {
	return getReposFiles(userName, repoName, commitId, rpath)
}

func getReposFiles(userName, repoName, commitId string, rpath string) ([]*RepoFile, error) {
	repopath := RepoPath(userName, repoName)
	repo, err := git.OpenRepository(repopath)
	if err != nil {
		return nil, err
	}

	commit, err := repo.GetCommit(commitId)
	if err != nil {
		return nil, err
	}

	var repodirs []*RepoFile
	var repofiles []*RepoFile
	commit.Tree.Walk(func(dirname string, entry *git.TreeEntry) int {
		if dirname == rpath {
			// TODO: size get method shoule be improved
			size, err := repo.ObjectSize(entry.Id)
			if err != nil {
				return 0
			}

			cmd := exec.Command("git", "log", "-1", "--pretty=format:%H", commitId, "--", entry.Name)
			cmd.Dir = repopath
			out, err := cmd.Output()
			if err != nil {
				return 0
			}
			filecm, err := repo.GetCommit(string(out))
			if err != nil {
				return 0
			}

			rp := &RepoFile{
				entry,
				path.Join(dirname, entry.Name),
				size,
				repo,
				filecm,
			}

			if entry.IsFile() {
				repofiles = append(repofiles, rp)
			} else if entry.IsDir() {
				repodirs = append(repodirs, rp)
			}
		}
		return 0
	})

	return append(repodirs, repofiles...), nil
}

func GetCommit(userName, repoName, commitId string) (*git.Commit, error) {
	repo, err := git.OpenRepository(RepoPath(userName, repoName))
	if err != nil {
		return nil, err
	}

	return repo.GetCommit(commitId)
}

// GetCommitsByBranch returns all commits of given branch of repository.
func GetCommitsByBranch(userName, repoName, branchName string) (*list.List, error) {
	repo, err := git.OpenRepository(RepoPath(userName, repoName))
	if err != nil {
		return nil, err
	}
	r, err := repo.LookupReference(fmt.Sprintf("refs/heads/%s", branchName))
	if err != nil {
		return nil, err
	}
	return r.AllCommits()
}

// GetCommitsByCommitId returns all commits of given commitId of repository.
func GetCommitsByCommitId(userName, repoName, commitId string) (*list.List, error) {
	repo, err := git.OpenRepository(RepoPath(userName, repoName))
	if err != nil {
		return nil, err
	}
	oid, err := git.NewOidFromString(commitId)
	if err != nil {
		return nil, err
	}
	return repo.CommitsBefore(oid)
}

// Diff line types.
const (
	DIFF_LINE_PLAIN = iota + 1
	DIFF_LINE_ADD
	DIFF_LINE_DEL
	DIFF_LINE_SECTION
)

const (
	DIFF_FILE_ADD = iota + 1
	DIFF_FILE_CHANGE
	DIFF_FILE_DEL
)

type DiffLine struct {
	LeftIdx  int
	RightIdx int
	Type     int
	Content  string
}

func (d DiffLine) GetType() int {
	return d.Type
}

type DiffSection struct {
	Name  string
	Lines []*DiffLine
}

type DiffFile struct {
	Name               string
	Addition, Deletion int
	Type               int
	Sections           []*DiffSection
}

type Diff struct {
	TotalAddition, TotalDeletion int
	Files                        []*DiffFile
}

func (diff *Diff) NumFiles() int {
	return len(diff.Files)
}

const DIFF_HEAD = "diff --git "

func ParsePatch(reader io.Reader) (*Diff, error) {
	scanner := bufio.NewScanner(reader)
	var (
		curFile    *DiffFile
		curSection = &DiffSection{
			Lines: make([]*DiffLine, 0, 10),
		}

		leftLine, rightLine int
	)

	diff := &Diff{Files: make([]*DiffFile, 0)}
	var i int
	for scanner.Scan() {
		line := scanner.Text()
		// fmt.Println(i, line)
		if strings.HasPrefix(line, "+++ ") || strings.HasPrefix(line, "--- ") {
			continue
		}

		i = i + 1
		if line == "" {
			continue
		}
		if line[0] == ' ' {
			diffLine := &DiffLine{Type: DIFF_LINE_PLAIN, Content: line, LeftIdx: leftLine, RightIdx: rightLine}
			leftLine++
			rightLine++
			curSection.Lines = append(curSection.Lines, diffLine)
			continue
		} else if line[0] == '@' {
			curSection = &DiffSection{}
			curFile.Sections = append(curFile.Sections, curSection)
			ss := strings.Split(line, "@@")
			diffLine := &DiffLine{Type: DIFF_LINE_SECTION, Content: line}
			curSection.Lines = append(curSection.Lines, diffLine)

			// Parse line number.
			ranges := strings.Split(ss[len(ss)-2][1:], " ")
			leftLine, _ = base.StrTo(strings.Split(ranges[0], ",")[0][1:]).Int()
			rightLine, _ = base.StrTo(strings.Split(ranges[1], ",")[0]).Int()
			continue
		} else if line[0] == '+' {
			curFile.Addition++
			diff.TotalAddition++
			diffLine := &DiffLine{Type: DIFF_LINE_ADD, Content: line, RightIdx: rightLine}
			rightLine++
			curSection.Lines = append(curSection.Lines, diffLine)
			continue
		} else if line[0] == '-' {
			curFile.Deletion++
			diff.TotalDeletion++
			diffLine := &DiffLine{Type: DIFF_LINE_DEL, Content: line, LeftIdx: leftLine}
			if leftLine > 0 {
				leftLine++
			}
			curSection.Lines = append(curSection.Lines, diffLine)
			continue
		}

		// Get new file.
		if strings.HasPrefix(line, DIFF_HEAD) {
			fs := strings.Split(line[len(DIFF_HEAD):], " ")
			a := fs[0]

			curFile = &DiffFile{
				Name:     a[strings.Index(a, "/")+1:],
				Type:     DIFF_FILE_CHANGE,
				Sections: make([]*DiffSection, 0, 10),
			}
			diff.Files = append(diff.Files, curFile)

			// Check file diff type.
			for scanner.Scan() {
				switch {
				case strings.HasPrefix(scanner.Text(), "new file"):
					curFile.Type = DIFF_FILE_ADD
				case strings.HasPrefix(scanner.Text(), "deleted"):
					curFile.Type = DIFF_FILE_DEL
				case strings.HasPrefix(scanner.Text(), "index"):
					curFile.Type = DIFF_FILE_CHANGE
				}
				if curFile.Type > 0 {
					break
				}
			}
		}
	}

	return diff, nil
}

func GetDiff(repoPath, commitid string) (*Diff, error) {
	repo, err := git.OpenRepository(repoPath)
	if err != nil {
		return nil, err
	}

	commit, err := repo.GetCommit(commitid)
	if err != nil {
		return nil, err
	}

	// First commit of repository.
	if commit.ParentCount() == 0 {
		rd, wr := io.Pipe()
		go func() {
			cmd := exec.Command("git", "show", commitid)
			cmd.Dir = repoPath
			cmd.Stdout = wr
			cmd.Stdin = os.Stdin
			cmd.Stderr = os.Stderr
			cmd.Run()
			wr.Close()
		}()
		defer rd.Close()
		return ParsePatch(rd)
	}

	rd, wr := io.Pipe()
	go func() {
		cmd := exec.Command("git", "diff", commit.Parent(0).Oid.String(), commitid)
		cmd.Dir = repoPath
		cmd.Stdout = wr
		cmd.Stdin = os.Stdin
		cmd.Stderr = os.Stderr
		cmd.Run()
		wr.Close()
	}()
	defer rd.Close()
	return ParsePatch(rd)
}
<|endoftext|>


<commit_before>package mol

import (
	"io/ioutil"
	"strconv"
	"strings"
)

func ParseFile(path string) (Molecule, error) {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return Molecule{}, err
	}
	return ParseString(string(data)), nil
}

func ParseString(data string) Molecule {
	lines := strings.Split(data, "\n")
	fields := strings.Fields(lines[3])
	natoms := parseInt(fields[0])
	nbonds := parseInt(fields[1])
	atoms := make([]Atom, natoms)
	for i := 0; i < natoms; i++ {
		fields := strings.Fields(lines[i+4])
		x := parseFloat(fields[0])
		y := parseFloat(fields[1])
		z := parseFloat(fields[2])
		symbol := fields[3]
		atoms[i] = Atom{x, y, z, symbol}
	}
	bonds := make([]Bond, nbonds)
	for i := 0; i < nbonds; i++ {
		fields := strings.Fields(lines[i+4+natoms])
		a := parseInt(fields[0]) - 1
		b := parseInt(fields[1]) - 1
		t := parseInt(fields[2])
		bonds[i] = Bond{a, b, t}
	}
	return Molecule{atoms, bonds}
}

func parseInt(x string) int {
	value, _ := strconv.ParseInt(x, 0, 0)
	return int(value)
}

func parseFloat(x string) float64 {
	value, _ := strconv.ParseFloat(x, 64)
	return value
}
<commit_msg>parser bug fix<commit_after>package mol

import (
	"io/ioutil"
	"strconv"
	"strings"
)

func ParseFile(path string) (Molecule, error) {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return Molecule{}, err
	}
	return ParseString(string(data)), nil
}

func ParseString(data string) Molecule {
	lines := strings.Split(data, "\n")
	natoms := parseInt(lines[3][0:3])
	nbonds := parseInt(lines[3][3:6])
	atoms := make([]Atom, natoms)
	for i := 0; i < natoms; i++ {
		fields := strings.Fields(lines[i+4])
		x := parseFloat(fields[0])
		y := parseFloat(fields[1])
		z := parseFloat(fields[2])
		symbol := fields[3]
		atoms[i] = Atom{x, y, z, symbol}
	}
	bonds := make([]Bond, nbonds)
	for i := 0; i < nbonds; i++ {
		line := lines[i+4+natoms]
		a := parseInt(line[0:3]) - 1
		b := parseInt(line[3:6]) - 1
		t := parseInt(line[6:9])
		bonds[i] = Bond{a, b, t}
	}
	return Molecule{atoms, bonds}
}

func parseInt(x string) int {
	x = strings.TrimSpace(x)
	value, _ := strconv.ParseInt(x, 0, 0)
	return int(value)
}

func parseFloat(x string) float64 {
	x = strings.TrimSpace(x)
	value, _ := strconv.ParseFloat(x, 64)
	return value
}
<|endoftext|>


<commit_before>package multierror

import (
	"bytes"
	"fmt"
	"strings"
	"errors"
)

// Error bundles multiple errors and make them obey the error interface
type Error struct {
	errs      []error
	formatter Formatter
}

// Formatter allows to customize the rendering of the multierror.
type Formatter func(errs []string) string

var DefaultFormatter = func(errs []string) string {
	buf := bytes.NewBuffer(nil)

	fmt.Fprintf(buf, "%d errors occurred:", len(errs))
	for _, line := range errs {
		fmt.Fprintf(buf, "\n%s", line)
	}

	return buf.String()
}

func (e *Error) Error() string {
	var f Formatter = DefaultFormatter
	if e.formatter != nil {
		f = e.formatter
	}

	var lines []string
	for _, err := range e.errs {
		lines = append(lines, err.Error())
	}

	return f(lines)
}

// Append creates a new mutlierror.Error structure or appends the arguments to an existing multierror
// err can be nil, or can be a non-multierror error.
//
// If err is nil and errs has only one element, that element is returned.
// I.e. a singleton error is never treated and (thus rendered) as a multierror.
// This also also effectively allows users to just pipe through the error value of a function call,
// without having to first check whether the error is non-nil.
func Append(err error, errs ...error) error {
	if err == nil && len(errs) == 1 {
		return errs[0]
	}
	if len(errs) == 1 && errs[0] == nil {
		return err
	}
	if err == nil {
		return &Error{errs: errs}
	}
	switch err := err.(type) {
	case *Error:
		err.errs = append(err.errs, errs...)
		return err
	default:
		return &Error{errs: append([]error{err}, errs...)}
	}
}

// Unfold returns the underlying list of errors wrapped in a multierror.
// If err is not a multierror, then a singleton list is returned.
func Unfold(err error) []error {
	if me, ok := err.(*Error); ok {
		return me.errs
	} else {
		return []error{err}
	}
}

// Uniq deduplicates a list of errors
func Uniq(errs []error) []error {
	type groupingKey struct {
		msg    string
		tagged bool
	}
	var ordered []groupingKey
	grouped := map[groupingKey][]error{}

	for _, err := range errs {
		msg, tag := TaggedError(err)
		key := groupingKey{
			msg:    msg,
			tagged: tag != "",
		}
		if _, ok := grouped[key]; !ok {
			ordered = append(ordered, key)
		}
		grouped[key] = append(grouped[key], err)
	}

	var res []error
	for _, key := range ordered {
		group := grouped[key]
		err := group[0]
		if key.tagged {
			var tags []string
			for _, e := range group {
				_, tag := TaggedError(e)
				tags = append(tags, tag)
			}
			err = fmt.Errorf("%w (%s)", errors.Unwrap(err), strings.Join(tags, ", "))
		} else {
			if n := len(group); n > 1 {
				err = fmt.Errorf("%w repeated %d times", err, n)
			}
		}
		res = append(res, err)
	}

	return res
}

type TaggableError interface {
	// TaggedError is like Error() but splits the error from the tag.
	TaggedError() (string, string)
}

// TaggedError is like Error() but if err implements TaggedError, it will
// invoke TaggeddError() and return error message and the tag. Otherwise the tag will be empty.
func TaggedError(err error) (string, string) {
	if te, ok := err.(TaggableError); ok {
		return te.TaggedError()
	}
	return err.Error(), ""
}

type taggedError struct {
	err error
	key string
}

// Tagged wraps an error with a tag. The resulting error implements the TaggableError interface
// and thus the tags can be unwrapped by Uniq in order to deduplicate error messages without loosing
// context.
func Tagged(key string, err error) error {
	return taggedError{err: err, key: key}
}

func (k taggedError) Error() string {
	return fmt.Sprintf("%s (%s)", k.err.Error(), k.key)
}

func (k taggedError) Unwrap() error {
	return k.err
}

func (k taggedError) TaggedError() (string, string) {
	return k.err.Error(), k.key
}

// WithFormatter sets a custom formatter if err is a multierror.
func WithFormatter(err error, f Formatter) error {
	if me, ok := err.(*Error); ok {
		cpy := *me
		cpy.formatter = f
		return &cpy
	} else {
		return err
	}
}
<commit_msg>Cleanup naming<commit_after>package multierror

import (
	"bytes"
	"errors"
	"fmt"
	"strings"
)

// Error bundles multiple errors and make them obey the error interface
type Error struct {
	errs      []error
	formatter Formatter
}

// Formatter allows to customize the rendering of the multierror.
type Formatter func(errs []string) string

var DefaultFormatter = func(errs []string) string {
	buf := bytes.NewBuffer(nil)

	fmt.Fprintf(buf, "%d errors occurred:", len(errs))
	for _, line := range errs {
		fmt.Fprintf(buf, "\n%s", line)
	}

	return buf.String()
}

func (e *Error) Error() string {
	var f Formatter = DefaultFormatter
	if e.formatter != nil {
		f = e.formatter
	}

	var lines []string
	for _, err := range e.errs {
		lines = append(lines, err.Error())
	}

	return f(lines)
}

// Append creates a new mutlierror.Error structure or appends the arguments to an existing multierror
// err can be nil, or can be a non-multierror error.
//
// If err is nil and errs has only one element, that element is returned.
// I.e. a singleton error is never treated and (thus rendered) as a multierror.
// This also also effectively allows users to just pipe through the error value of a function call,
// without having to first check whether the error is non-nil.
func Append(err error, errs ...error) error {
	if err == nil && len(errs) == 1 {
		return errs[0]
	}
	if len(errs) == 1 && errs[0] == nil {
		return err
	}
	if err == nil {
		return &Error{errs: errs}
	}
	switch err := err.(type) {
	case *Error:
		err.errs = append(err.errs, errs...)
		return err
	default:
		return &Error{errs: append([]error{err}, errs...)}
	}
}

// Unfold returns the underlying list of errors wrapped in a multierror.
// If err is not a multierror, then a singleton list is returned.
func Unfold(err error) []error {
	if me, ok := err.(*Error); ok {
		return me.errs
	} else {
		return []error{err}
	}
}

// Uniq deduplicates a list of errors
func Uniq(errs []error) []error {
	type groupingKey struct {
		msg    string
		tagged bool
	}
	var ordered []groupingKey
	grouped := map[groupingKey][]error{}

	for _, err := range errs {
		msg, tag := TaggedError(err)
		key := groupingKey{
			msg:    msg,
			tagged: tag != "",
		}
		if _, ok := grouped[key]; !ok {
			ordered = append(ordered, key)
		}
		grouped[key] = append(grouped[key], err)
	}

	var res []error
	for _, key := range ordered {
		group := grouped[key]
		err := group[0]
		if key.tagged {
			var tags []string
			for _, e := range group {
				_, tag := TaggedError(e)
				tags = append(tags, tag)
			}
			err = fmt.Errorf("%w (%s)", errors.Unwrap(err), strings.Join(tags, ", "))
		} else {
			if n := len(group); n > 1 {
				err = fmt.Errorf("%w repeated %d times", err, n)
			}
		}
		res = append(res, err)
	}

	return res
}

type TaggableError interface {
	// TaggedError is like Error() but splits the error from the tag.
	TaggedError() (string, string)
}

// TaggedError is like Error() but if err implements TaggedError, it will
// invoke TaggeddError() and return error message and the tag. Otherwise the tag will be empty.
func TaggedError(err error) (string, string) {
	if te, ok := err.(TaggableError); ok {
		return te.TaggedError()
	}
	return err.Error(), ""
}

type taggedError struct {
	tag string
	err error
}

// Tagged wraps an error with a tag. The resulting error implements the TaggableError interface
// and thus the tags can be unwrapped by Uniq in order to deduplicate error messages without loosing
// context.
func Tagged(tag string, err error) error {
	return taggedError{tag: tag, err: err}
}

func (t taggedError) Error() string {
	return fmt.Sprintf("%s (%s)", t.err.Error(), t.tag)
}

func (t taggedError) Unwrap() error {
	return t.err
}

func (t taggedError) TaggedError() (string, string) {
	return t.err.Error(), t.tag
}

// WithFormatter sets a custom formatter if err is a multierror.
func WithFormatter(err error, f Formatter) error {
	if me, ok := err.(*Error); ok {
		cpy := *me
		cpy.formatter = f
		return &cpy
	} else {
		return err
	}
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/asdine/storm"
	"github.com/labstack/echo"
	"github.com/labstack/echo/engine/fasthttp"
	"github.com/labstack/echo/middleware"
	"fmt"
	"log"
	"net/http"
	"os"
)

type (
	Mood struct {
		Value int `json:"mood"`
	}

	Subscribers struct {
		Users []Subscriber `json:"users"`
	}

	Subscription struct {
		Email string `json:"email"`
	}
)

func main() {
	database := createDatabase()
	defer database.Close()

	createCronJob(database, triggerMail(database))

	server := initServer(database)
	logFile := setLogLocation(server)
	defer logFile.Close()

	bind := getBind()
	log.Println("Starting server on bind " + bind + ".")
	server.Run(fasthttp.New(bind))
}

func getBind() string {
	if os.Getenv("OPENSHIFT_GO_PORT") != "" {
		return fmt.Sprintf("%s:%s", os.Getenv("OPENSHIFT_GO_IP"), os.Getenv("OPENSHIFT_GO_PORT"))
	} else {
		return ":8081"
	}
}

func initServer(database *storm.DB) (server *echo.Echo) {
	server = echo.New()

	server.Use(middleware.Logger())
	server.Get("/subscribers", getSubscribers(database))
	server.Get("/subscribers/:uuid", getSubscribersByUuid(database))
	server.Post("/subscribers", postSubscriber(database))
	server.Get("/moods", getDailyMoods(database))
	server.Get("/moods/:key", getDailyMoodsForm())
	server.Post("/moods/:key", postDailyMoods(database))

	return server
}

func setLogLocation(server *echo.Echo) (logFile *os.File) {
	if os.Getenv("OPENSHIFT_DATA_DIR") != "" {
		logFile, fileError := os.OpenFile(os.Getenv("OPENSHIFT_DATA_DIR") + "mut.log", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)

		if fileError != nil {
			log.Fatal(fileError)
		}

		log.SetOutput(logFile)
		server.SetLogOutput(logFile)
	}

	return logFile
}

func getDailyMoods(database *storm.DB) echo.HandlerFunc {
	return (func(context echo.Context) error {
		dailyMoods, databaseError := getAllDailyMoods(database)

		if databaseError != nil {
			return databaseError
		} else {
			return context.JSON(http.StatusOK, dailyMoods)
		}

		return nil
	})
}

func getDailyMoodsForm() echo.HandlerFunc {
	return (func(context echo.Context) error {
		key := context.Param("key")

		htmlContent := `

Select your mood

	<form method="POST" action="http://mut-musca.rhcloud.com/moods/` + key + `">
	<input type="hidden" name="mood" value="0">
	<input type="submit" value="Very unhappy">
	</form>

	<form method="POST" action="http://mut-musca.rhcloud.com/moods/` + key + `">
	<input type="hidden" name="mood" value="1">
	<input type="submit" value="Unhappy">
	</form>

	<form method="POST" action="http://mut-musca.rhcloud.com/moods/` + key + `">
	<input type="hidden" name="mood" value="2">
	<input type="submit" value="Neutral">
	</form>

	<form method="POST" action="http://mut-musca.rhcloud.com/moods/` + key + `">
	<input type="hidden" name="mood" value="3">
	<input type="submit" value="Happy">
	</form>

	<form method="POST" action="http://mut-musca.rhcloud.com/moods/` + key + `">
	<input type="hidden" name="mood" value="4">
	<input type="submit" value="Very happy">
	</form>

	`
		return context.HTML(http.StatusOK, htmlContent)

	})
}

func postDailyMoods(database *storm.DB) echo.HandlerFunc {
	return (func(context echo.Context) error {
		key := context.Param("key")
		mood := context.FormValue("mood")

		if feedbackIdentifier := getFeedbackIdentifier(database, key); feedbackIdentifier != nil {
			if databaseError := updateDailyMoods(database, feedbackIdentifier.DateString, mood); databaseError != nil {
				return databaseError
			} else {
				return context.String(http.StatusCreated, "Thank you!")
			}
		} else {
			return context.String(http.StatusNotFound, "Mood with key '"+key+"' not found!")
		}

		return nil
	})
}

func getSubscribers(database *storm.DB) echo.HandlerFunc {
	return (func(context echo.Context) error {
		subscribers, databaseError := getAllSubscribers(database)

		if databaseError != nil {
			return databaseError
		} else {
			return context.JSON(http.StatusOK, subscribers)
		}

		return nil
	})
}

func getSubscribersByUuid(database *storm.DB) echo.HandlerFunc {
	return (func(context echo.Context) error {
		uuid := context.Param("uuid")
		subscriber, databaseError := getSubscriberByUuid(database, uuid)

		if databaseError != nil {
			return databaseError
		} else {
			if subscriber != nil {
				return context.JSON(http.StatusOK, subscriber)
			} else {
				return context.String(http.StatusNotFound, "User with uuid '"+uuid+"' not found!")
			}
		}

		return nil
	})
}

func postSubscriber(db *storm.DB) echo.HandlerFunc {
	return (func(context echo.Context) error {
		subscription := new(Subscription)

		if jsonError := context.Bind(subscription); jsonError != nil {
			return jsonError
		} else {
			subscriber, databaseError := saveSubscriber(db, subscription)

			if databaseError != nil {
				return databaseError
			} else {
				return context.JSON(http.StatusCreated, subscriber)
			}
		}

		return nil
	})
}
<commit_msg>refactoring<commit_after>package main

import (
	"github.com/asdine/storm"
	"github.com/labstack/echo"
	"github.com/labstack/echo/engine/fasthttp"
	"github.com/labstack/echo/middleware"
	"fmt"
	"log"
	"net/http"
	"os"
)

type (
	Mood struct {
		Value int `json:"mood"`
	}

	Subscribers struct {
		Users []Subscriber `json:"users"`
	}

	Subscription struct {
		Email string `json:"email"`
	}
)

func main() {
	database := createDatabase()
	defer database.Close()

	createCronJob(database, triggerMail(database))

	server := initServer(database)
	appLogFile, requestLogFile := setLogLocation(server)
	defer appLogFile.Close()
	defer requestLogFile.Close()

	bind := getBind()
	log.Println("Starting server on bind " + bind + ".")
	server.Run(fasthttp.New(bind))
}

func getBind() string {
	if os.Getenv("OPENSHIFT_GO_PORT") != "" {
		return fmt.Sprintf("%s:%s", os.Getenv("OPENSHIFT_GO_IP"), os.Getenv("OPENSHIFT_GO_PORT"))
	} else {
		return ":8081"
	}
}

func initServer(database *storm.DB) (server *echo.Echo) {
	server = echo.New()

	server.Use(middleware.Logger())
	server.Get("/subscribers", getSubscribers(database))
	server.Get("/subscribers/:uuid", getSubscribersByUuid(database))
	server.Post("/subscribers", postSubscriber(database))
	server.Get("/moods", getDailyMoods(database))
	server.Get("/moods/:key", getDailyMoodsForm())
	server.Post("/moods/:key", postDailyMoods(database))

	return server
}

func setLogLocation(server *echo.Echo) (appLogFile *os.File, requestLogFile *os.File) {
	if os.Getenv("OPENSHIFT_DATA_DIR") != "" {
		appLogFile, fileError := os.OpenFile(os.Getenv("OPENSHIFT_DATA_DIR") + "mut-app.log", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)
		requestLogFile, fileError := os.OpenFile(os.Getenv("OPENSHIFT_DATA_DIR") + "mut-request.log", os.O_RDWR | os.O_CREATE | os.O_APPEND, 0666)

		if fileError != nil {
			log.Fatal(fileError)
		}

		log.SetOutput(appLogFile)
		server.SetLogOutput(requestLogFile)
	}

	return appLogFile, requestLogFile
}

func getDailyMoods(database *storm.DB) echo.HandlerFunc {
	return (func(context echo.Context) error {
		dailyMoods, databaseError := getAllDailyMoods(database)

		if databaseError != nil {
			return databaseError
		} else {
			return context.JSON(http.StatusOK, dailyMoods)
		}

		return nil
	})
}

func getDailyMoodsForm() echo.HandlerFunc {
	return (func(context echo.Context) error {
		key := context.Param("key")

		htmlContent := `

Select your mood

	<form method="POST" action="http://mut-musca.rhcloud.com/moods/` + key + `">
	<input type="hidden" name="mood" value="0">
	<input type="submit" value="Very unhappy">
	</form>

	<form method="POST" action="http://mut-musca.rhcloud.com/moods/` + key + `">
	<input type="hidden" name="mood" value="1">
	<input type="submit" value="Unhappy">
	</form>

	<form method="POST" action="http://mut-musca.rhcloud.com/moods/` + key + `">
	<input type="hidden" name="mood" value="2">
	<input type="submit" value="Neutral">
	</form>

	<form method="POST" action="http://mut-musca.rhcloud.com/moods/` + key + `">
	<input type="hidden" name="mood" value="3">
	<input type="submit" value="Happy">
	</form>

	<form method="POST" action="http://mut-musca.rhcloud.com/moods/` + key + `">
	<input type="hidden" name="mood" value="4">
	<input type="submit" value="Very happy">
	</form>

	`
		return context.HTML(http.StatusOK, htmlContent)

	})
}

func postDailyMoods(database *storm.DB) echo.HandlerFunc {
	return (func(context echo.Context) error {
		key := context.Param("key")
		mood := context.FormValue("mood")

		if feedbackIdentifier := getFeedbackIdentifier(database, key); feedbackIdentifier != nil {
			if databaseError := updateDailyMoods(database, feedbackIdentifier.DateString, mood); databaseError != nil {
				return databaseError
			} else {
				return context.String(http.StatusCreated, "Thank you!")
			}
		} else {
			return context.String(http.StatusNotFound, "Mood with key '"+key+"' not found!")
		}

		return nil
	})
}

func getSubscribers(database *storm.DB) echo.HandlerFunc {
	return (func(context echo.Context) error {
		subscribers, databaseError := getAllSubscribers(database)

		if databaseError != nil {
			return databaseError
		} else {
			return context.JSON(http.StatusOK, subscribers)
		}

		return nil
	})
}

func getSubscribersByUuid(database *storm.DB) echo.HandlerFunc {
	return (func(context echo.Context) error {
		uuid := context.Param("uuid")
		subscriber, databaseError := getSubscriberByUuid(database, uuid)

		if databaseError != nil {
			return databaseError
		} else {
			if subscriber != nil {
				return context.JSON(http.StatusOK, subscriber)
			} else {
				return context.String(http.StatusNotFound, "User with uuid '"+uuid+"' not found!")
			}
		}

		return nil
	})
}

func postSubscriber(db *storm.DB) echo.HandlerFunc {
	return (func(context echo.Context) error {
		subscription := new(Subscription)

		if jsonError := context.Bind(subscription); jsonError != nil {
			return jsonError
		} else {
			subscriber, databaseError := saveSubscriber(db, subscription)

			if databaseError != nil {
				return databaseError
			} else {
				return context.JSON(http.StatusCreated, subscriber)
			}
		}

		return nil
	})
}
<|endoftext|>


<commit_before>package nmoptim

import (
	"math"
	"fmt"
)

const (
	kMax = 1000          // arbitrarily chosen value for now
	ε    = 0.000001 // Stopping criterion point
	α    = 1.0
	β    = 0.5
	γ    = 2.0
)

var (
	evaluations = 0
)

// point is the type of points in ℝ^n
type point []float64

// simplex is the type used to represent a simplex
type simplex []point

// optfunc is the type of optimization functions. They run from ℝ^n → ℝ, here represented with float64's
type optfunc func([]float64) float64

type constrainfunc func([]float64)

// Evaluate the function, counting how many times it gets executed
func eval(f optfunc, p point) float64 {
	evaluations++
	return f(p)
}

// Optimize function f with Nelder-Mead. start points to a slice of starting points
// It is the responsibility of the caller to make sure the dimensionality is correct.
func Optimize(f optfunc, start [][]float64, cf constrainfunc) ([]float64, int, int) {
	evaluations = 0
	n := len(start)
	c := len(start[0])
	points := make([]point, 0)
	fv := make([]float64, n)

	for _, p := range start {
		points = append(points, point(p))
	}
	sx := simplex(points)
	if n != c+1 {
		fmt.Printf("Dimension: %v, StartPoints: %v\n")
		panic("Can't optimize with too few starting points")
	}

	// Set up initial values
	for i := range fv {
		if cf != nil {
			cf(sx[i])
		}
		fv[i] = eval(f, sx[i])
	}

	k := 0
	for ; k < kMax; k++ {
		// Find the largest index
		vg := 0
		for i := range fv {
			if fv[i] > fv[vg] {
				vg = i
			}
		}

		// Find the smallest index
		vs := 0
		for i := range fv {
			if fv[i] < fv[vs] {
				vs = i
			}
		}

		// Second largest index
		vh := vs
		for i := range fv {
			if fv[i] > fv[vh] && fv[i] < fv[vg] {
				vh = i
			}
		}

		// Print out the iteration point
		fmt.Printf("Iteration %v:\n", k)
		for i, endpoint := range(sx) {
			var marker string
			if i == vg {
				marker = "g"
			} else if i == vs {
				marker = "s"
			} else if i == vh {
				marker = "h"
			} else {
				marker = " "
			}

			fmt.Printf("\t%v sx[%v] = %v → %v\n", marker, i, endpoint, fv[i])
		}

		vm := sx.centroid(vg)

		vr := add(vm, sub(vm, sx[vg]).scale(α))
		if cf != nil {
			cf(vr)
		}
		fr := eval(f, vr)

		if fr < fv[vh] && fr >= fv[vs] {
			// Replace
			fv[vg] = fr
			sx[vg] = vr
		}

		// Investigate a step further
		if fr < fv[vs] {
			ve := add(vm, sub(vr, vm).scale(γ))
			if cf != nil {
				cf(ve)
			}

			fe := eval(f, ve)

			if fe < fr {
				sx[vg] = ve
				fv[vg] = fe
			} else {
				sx[vg] = vr
				fv[vg] = fr
			}
		}

		// Check contraction
		if fr >= fv[vh] {
			var vc point
			var fc float64
			if fr < fv[vg] && fr >= fv[vh] {
				// Outside contraction
				vc = add(vm, sub(vr, vm).scale(β))
			} else {
				// Inside contraction
				vc = sub(vm, sub(vm, sx[vg]).scale(β))
			}

			if cf != nil {
				cf(vc)
			}
			fc = eval(f, vc)

			if fc < fv[vg] {
				sx[vg] = vc
				fv[vg] = fc
			} else {
				for i := range sx {
					if i != vs {
						sx[i] = add(sx[vs], sub(sx[i], sx[vs]).scale(0.5))
					}
				}

				if cf != nil {
					cf(sx[vg])
				}
				fv[vg] = eval(f, sx[vg])

				if cf != nil {
					cf(sx[vh])
				}
				fv[vh] = eval(f, sx[vh])
			}
		}

		fsum := 0.0
		for _, v := range fv {
			fsum += v
		}

		favg := fsum / float64(len(fv))

		s := 0.0
		for _, v := range fv {
			s += math.Pow(v - favg, 2.0)
		}

		s = s * ( 1.0 / ( float64(len(fv)) + 1.0 ) )
		s = math.Sqrt(s)
		if s < ε {
			break
		}

		fmt.Printf("\t\tDone, convergence: %v\n", s)
	}

	vs := 0
	for i := range fv {
		if fv[i] < fv[vs] {
			vs = i
		}
	}

	return sx[vs], k, evaluations
}

// sub perform point subtraction
func sub(x point, y point) point {
	r := make(point, len(x))

	for i := range y {
		r[i] = x[i] - y[i]
	}

	return r
}

// add perform point addition
func add(x point, y point) point {
	r := make(point, len(x))

	for i := range y {
		r[i] = x[i] + y[i]
	}

	return r
}

// scale multiplies a point by a scalar
func (p point) scale(scalar float64) point {
	r := make(point, len(p))

	for i := range r {
		r[i] = scalar * p[i]
	}

	return r
}

// centroid calculates the centroid of a simplex of one dimensionality lower by omitting a point
func (s simplex) centroid(omit int) point {
	r := make(point, len(s[0]))

	for i := range r {
		c := 0.0
		for j := range s {
			if j == omit {
				continue
			} else {
				c += s[j][i]
			}
		}

		r[i] = c / float64((len(s) - 1))
	}

	return r
}
<commit_msg>go fmt.<commit_after>package nmoptim

import (
	"fmt"
	"math"
)

const (
	kMax = 1000     // arbitrarily chosen value for now
	ε    = 0.000001 // Stopping criterion point
	α    = 1.0
	β    = 0.5
	γ    = 2.0
)

var (
	evaluations = 0
)

// point is the type of points in ℝ^n
type point []float64

// simplex is the type used to represent a simplex
type simplex []point

// optfunc is the type of optimization functions. They run from ℝ^n → ℝ, here represented with float64's
type optfunc func([]float64) float64

type constrainfunc func([]float64)

// Evaluate the function, counting how many times it gets executed
func eval(f optfunc, p point) float64 {
	evaluations++
	return f(p)
}

// Optimize function f with Nelder-Mead. start points to a slice of starting points
// It is the responsibility of the caller to make sure the dimensionality is correct.
func Optimize(f optfunc, start [][]float64, cf constrainfunc) ([]float64, int, int) {
	evaluations = 0
	n := len(start)
	c := len(start[0])
	points := make([]point, 0)
	fv := make([]float64, n)

	for _, p := range start {
		points = append(points, point(p))
	}
	sx := simplex(points)
	if n != c+1 {
		fmt.Printf("Dimension: %v, StartPoints: %v\n")
		panic("Can't optimize with too few starting points")
	}

	// Set up initial values
	for i := range fv {
		if cf != nil {
			cf(sx[i])
		}
		fv[i] = eval(f, sx[i])
	}

	k := 0
	for ; k < kMax; k++ {
		// Find the largest index
		vg := 0
		for i := range fv {
			if fv[i] > fv[vg] {
				vg = i
			}
		}

		// Find the smallest index
		vs := 0
		for i := range fv {
			if fv[i] < fv[vs] {
				vs = i
			}
		}

		// Second largest index
		vh := vs
		for i := range fv {
			if fv[i] > fv[vh] && fv[i] < fv[vg] {
				vh = i
			}
		}

		// Print out the iteration point
		fmt.Printf("Iteration %v:\n", k)
		for i, endpoint := range sx {
			var marker string
			if i == vg {
				marker = "g"
			} else if i == vs {
				marker = "s"
			} else if i == vh {
				marker = "h"
			} else {
				marker = " "
			}

			fmt.Printf("\t%v sx[%v] = %v → %v\n", marker, i, endpoint, fv[i])
		}

		vm := sx.centroid(vg)

		vr := add(vm, sub(vm, sx[vg]).scale(α))
		if cf != nil {
			cf(vr)
		}
		fr := eval(f, vr)

		if fr < fv[vh] && fr >= fv[vs] {
			// Replace
			fv[vg] = fr
			sx[vg] = vr
		}

		// Investigate a step further
		if fr < fv[vs] {
			ve := add(vm, sub(vr, vm).scale(γ))
			if cf != nil {
				cf(ve)
			}

			fe := eval(f, ve)

			if fe < fr {
				sx[vg] = ve
				fv[vg] = fe
			} else {
				sx[vg] = vr
				fv[vg] = fr
			}
		}

		// Check contraction
		if fr >= fv[vh] {
			var vc point
			var fc float64
			if fr < fv[vg] && fr >= fv[vh] {
				// Outside contraction
				vc = add(vm, sub(vr, vm).scale(β))
			} else {
				// Inside contraction
				vc = sub(vm, sub(vm, sx[vg]).scale(β))
			}

			if cf != nil {
				cf(vc)
			}
			fc = eval(f, vc)

			if fc < fv[vg] {
				sx[vg] = vc
				fv[vg] = fc
			} else {
				for i := range sx {
					if i != vs {
						sx[i] = add(sx[vs], sub(sx[i], sx[vs]).scale(0.5))
					}
				}

				if cf != nil {
					cf(sx[vg])
				}
				fv[vg] = eval(f, sx[vg])

				if cf != nil {
					cf(sx[vh])
				}
				fv[vh] = eval(f, sx[vh])
			}
		}

		fsum := 0.0
		for _, v := range fv {
			fsum += v
		}

		favg := fsum / float64(len(fv))

		s := 0.0
		for _, v := range fv {
			s += math.Pow(v-favg, 2.0)
		}

		s = s * (1.0 / (float64(len(fv)) + 1.0))
		s = math.Sqrt(s)
		if s < ε {
			break
		}

		fmt.Printf("\t\tDone, convergence: %v\n", s)
	}

	vs := 0
	for i := range fv {
		if fv[i] < fv[vs] {
			vs = i
		}
	}

	return sx[vs], k, evaluations
}

// sub perform point subtraction
func sub(x point, y point) point {
	r := make(point, len(x))

	for i := range y {
		r[i] = x[i] - y[i]
	}

	return r
}

// add perform point addition
func add(x point, y point) point {
	r := make(point, len(x))

	for i := range y {
		r[i] = x[i] + y[i]
	}

	return r
}

// scale multiplies a point by a scalar
func (p point) scale(scalar float64) point {
	r := make(point, len(p))

	for i := range r {
		r[i] = scalar * p[i]
	}

	return r
}

// centroid calculates the centroid of a simplex of one dimensionality lower by omitting a point
func (s simplex) centroid(omit int) point {
	r := make(point, len(s[0]))

	for i := range r {
		c := 0.0
		for j := range s {
			if j == omit {
				continue
			} else {
				c += s[j][i]
			}
		}

		r[i] = c / float64((len(s) - 1))
	}

	return r
}
<|endoftext|>


<commit_before>package optimization

func reflection(x []float64, c []float64, alpha float64) (out []float64) {
	l := len(x)
	for i := 0; i < l; i++ {
		out = append(out, c[i]+alpha*(c[i]-x[i]))
	}
	return
}

func expansion(x []float64, c []float64, gamma float64) (out []float64) {
	l := len(x)
	for i := 0; i < l; i++ {
		out = append(out, c[i]+gamma*(x[i]-c[i]))
	}
	return
}

func contraction(x []float64, c []float64, beta float64) (out []float64) {
	l := len(x)
	for i := 0; i < l; i++ {
		out = append(out, c[i]+beta*(x[i]-c[i]))
	}
	return
}

func shrink(x []float64, y []float64, delta float64) (out []float64) {
	l := len(x)
	for i := 0; i < l; i++ {
		out = append(out, x[i]+delta*(y[i]-x[i]))
	}
	return
}
<commit_msg>Nelder-Mead start<commit_after>package optimization

type function interface {
	f() []float64
}

func reflection(x []float64, c []float64, alpha float64) (out []float64) {
	l := len(x)
	for i := 0; i < l; i++ {
		out = append(out, c[i]+alpha*(c[i]-x[i]))
	}
	return
}

func expansion(x []float64, c []float64, gamma float64) (out []float64) {
	l := len(x)
	for i := 0; i < l; i++ {
		out = append(out, c[i]+gamma*(x[i]-c[i]))
	}
	return
}

func contraction(x []float64, c []float64, beta float64) (out []float64) {
	l := len(x)
	for i := 0; i < l; i++ {
		out = append(out, c[i]+beta*(x[i]-c[i]))
	}
	return
}

func shrink(x []float64, y []float64, delta float64) (out []float64) {
	l := len(x)
	for i := 0; i < l; i++ {
		out = append(out, x[i]+delta*(y[i]-x[i]))
	}
	return
}

func neldermead(variable []float64, fn function) {

}
<|endoftext|>


<commit_before>package gwr

import (
	"fmt"
	"io"
)

// DataSource is the interface implemented by all
// data sources.
type DataSource interface {
	// NOTE: implementation is self encoding, but may abstract internally
	Info() DataSourceInfo
	Get(format string, w io.Writer) error
	Watch(format string, w io.Writer) error
}

// DataSourceInfo provides a description of each
// data source, such as name and supported formats.
type DataSourceInfo struct {
	Name    string
	Formats []string
	Attrs   map[string]interface{}
}

// DataSources is a flat collection of DataSources
// with a meta introspection data source.
type DataSources struct {
	sources   map[string]DataSource
	metaNouns metaNounDataSource
}

// NewDataSources creates a DataSources structure
// an sets up its "/meta/nouns" data source.
func NewDataSources() *DataSources {
	dss := &DataSources{
		sources: make(map[string]DataSource, 2),
	}
	dss.metaNouns.sources = dss
	dss.AddDataSource(NewMarshaledDataSource(
		&dss.metaNouns,
		map[string]GenericDataMarshal{
			"json": LDJSONMarshal,
			"text": nounsTextMarshal,
		},
	))
	return dss
}

// Info returns a map of all DataSource.Info() data
func (dss *DataSources) Info() map[string]DataSourceInfo {
	info := make(map[string]DataSourceInfo, len(dss.sources))
	for name, ds := range dss.sources {
		info[name] = ds.Info()
	}
	return info
}

// AddDataSource adds a DataSource, if none is
// already defined for the given name.
func (dss *DataSources) AddDataSource(ds DataSource) error {
	info := ds.Info()
	_, ok := dss.sources[info.Name]
	if ok {
		return fmt.Errorf("data source already defined")
	}
	dss.sources[info.Name] = ds
	dss.metaNouns.dataSourceAdded(ds)
	return nil
}

// TODO: do we really need to support removing data sources?  I can see the
// case for intermediaries perhaps, and suspect that is needed... but punting
// for now.
<commit_msg>DataSourceInfo: declare json field names<commit_after>package gwr

import (
	"fmt"
	"io"
)

// DataSource is the interface implemented by all
// data sources.
type DataSource interface {
	// NOTE: implementation is self encoding, but may abstract internally
	Info() DataSourceInfo
	Get(format string, w io.Writer) error
	Watch(format string, w io.Writer) error
}

// DataSourceInfo provides a description of each
// data source, such as name and supported formats.
type DataSourceInfo struct {
	Name    string                 `json:"name"`
	Formats []string               `json:"formats"`
	Attrs   map[string]interface{} `json:"attrs"`
}

// DataSources is a flat collection of DataSources
// with a meta introspection data source.
type DataSources struct {
	sources   map[string]DataSource
	metaNouns metaNounDataSource
}

// NewDataSources creates a DataSources structure
// an sets up its "/meta/nouns" data source.
func NewDataSources() *DataSources {
	dss := &DataSources{
		sources: make(map[string]DataSource, 2),
	}
	dss.metaNouns.sources = dss
	dss.AddDataSource(NewMarshaledDataSource(
		&dss.metaNouns,
		map[string]GenericDataMarshal{
			"json": LDJSONMarshal,
			"text": nounsTextMarshal,
		},
	))
	return dss
}

// Info returns a map of all DataSource.Info() data
func (dss *DataSources) Info() map[string]DataSourceInfo {
	info := make(map[string]DataSourceInfo, len(dss.sources))
	for name, ds := range dss.sources {
		info[name] = ds.Info()
	}
	return info
}

// AddDataSource adds a DataSource, if none is
// already defined for the given name.
func (dss *DataSources) AddDataSource(ds DataSource) error {
	info := ds.Info()
	_, ok := dss.sources[info.Name]
	if ok {
		return fmt.Errorf("data source already defined")
	}
	dss.sources[info.Name] = ds
	dss.metaNouns.dataSourceAdded(ds)
	return nil
}

// TODO: do we really need to support removing data sources?  I can see the
// case for intermediaries perhaps, and suspect that is needed... but punting
// for now.
<|endoftext|>


<commit_before>package oauth

import (
	"http"
	"io"
	"os"
	"strings"
	"testing"
)

func TestFoo(t *testing.T) {
	c := &Consumer{
		ConsumerKey:       "consumerkey",
		ConsumerSecret:    "consumersecret",
		RequestTokenUrl:   "http://www.mrjon.es/requesttoken",
		AuthorizeTokenUrl: "http://www.mrjon.es/authorizetoken",
		AccessTokenUrl:    "http://www.mrjon.es/accesstoken",
		CallbackUrl:       "http://www.mjon.es/callback",
	}

  checker := NewOAuthChecker(t)

	mockClient := NewMockHttpClient(t)
	mockClient.ExpectGet("http://www.mrjon.es/requesttoken", checker, "BODY")

	c.HttpClient = mockClient

	_, err := c.GetRequestToken()

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

}

type MockHttpClient struct {
	url          string
	oAuthChecker *OAuthChecker
	responseBody string

	t *testing.T
}

func NewMockHttpClient(t *testing.T) *MockHttpClient {
	return &MockHttpClient{t: t}
}

func (mock *MockHttpClient) Do(req *http.Request) (*http.Response, os.Error) {
	if req.URL.String() != mock.url {
		mock.t.Fatalf("URLs did not match.\nExpected: '%s'\nActual: '%s'",
			mock.url, req.URL.String())
	}
	if req.Header == nil {
		mock.t.Fatal("Missing 'Authorization' header.")
	}
     mock.oAuthChecker.CheckHeader(req.Header.Get("Authorization"))
//	if req.Header.Get("Authorization") != mock.oAuthHeader {
//		mock.t.Fatalf("OAuth Header did not match.\nExpected: '%s'\nActual: '%s'",
//			mock.oAuthHeader, req.Header.Get("Authorization"))
//	}

	return &http.Response{
		StatusCode: 200,
		Body:       NewMockBody(mock.responseBody),
	},
		nil
}

func (mock *MockHttpClient) ExpectGet(expectedUrl string, checker *OAuthChecker, responseBody string) {
	mock.url = expectedUrl
	mock.oAuthChecker = checker
	mock.responseBody = responseBody
}

type OAuthChecker struct {
  headerPairs map[string]string
  t *testing.T
}

func NewOAuthChecker(t *testing.T) *OAuthChecker {
     return &OAuthChecker{
            headerPairs: make(map[string]string),
            t: t,
     }
}

func (o *OAuthChecker) CheckHeader(header string) {
}

func (o *OAuthChecker) ExpectHeaderPair(key, value string) {
     o.headerPairs[key] = value;
}

type MockBody struct {
	reader io.Reader
}

func NewMockBody(body string) *MockBody {
	return &MockBody{
		reader: strings.NewReader(body),
	}
}

func (*MockBody) Close() os.Error {
	return nil
}

func (mock *MockBody) Read(p []byte) (n int, err os.Error) {
	return mock.reader.Read(p)
}
<commit_msg>test is almost coherent<commit_after>package oauth

import (
	"http"
	"io"
	"os"
	"strings"
	"testing"
)

func TestFoo(t *testing.T) {
  c := basicConsumer()

	mockClient := NewMockHttpClient(t)
	mockClient.ExpectGet(
  	"http://www.mrjon.es/requesttoken",
    map[string]string{
        "oauth_callback": http.URLEscape("http://www.mrjon.es/callback"),
        "oauth_consumer_key": "consumerkey",
//        "oauth_nonce":
//        "oauth_signature":
        "oauth_signature_method": "HMAC-SHA1",
//        "oauth_timestamp":
//        "oauth_version": "1.0",
    },
    "oauth_token=TOKEN&oauth_token_secret=SECRET")

	c.HttpClient = mockClient

	token, err := c.GetRequestToken()

	if err != nil {
		t.Fatal(err)
	}
  assertEq(t, "TOKEN", token.Token)
  assertEq(t, "SECRET", token.TokenSecret)
}

func basicConsumer() *Consumer {
	return &Consumer{
		ConsumerKey:       "consumerkey",
		ConsumerSecret:    "consumersecret",
		RequestTokenUrl:   "http://www.mrjon.es/requesttoken",
		AuthorizeTokenUrl: "http://www.mrjon.es/authorizetoken",
		AccessTokenUrl:    "http://www.mrjon.es/accesstoken",
		CallbackUrl:       "http://www.mrjon.es/callback",
	}
}

func assertEq(t *testing.T, expected interface{}, actual interface{}) {
     assertEqM(t, expected, actual, "")
}

func assertEqM(t *testing.T, expected interface{}, actual interface{}, msg string) {
     if (expected != actual) {
        t.Fatalf("Assertion error.\n\tExpected: '%s'\n\tActual:   '%s'\n\tMessage:  '%s'",
                            expected, actual, msg)
     }
}

type MockHttpClient struct {
	url          string
	oAuthChecker *OAuthChecker
	responseBody string

	t *testing.T
}

func NewMockHttpClient(t *testing.T) *MockHttpClient {
	return &MockHttpClient{t: t}
}

func (mock *MockHttpClient) Do(req *http.Request) (*http.Response, os.Error) {
	if req.URL.String() != mock.url {
		mock.t.Fatalf("URLs did not match.\nExpected: '%s'\nActual: '%s'",
			mock.url, req.URL.String())
	}
	if req.Header == nil {
		mock.t.Fatal("Missing 'Authorization' header.")
	}
  mock.oAuthChecker.CheckHeader(req.Header.Get("Authorization"))

	return &http.Response{
		StatusCode: 200,
		Body:       NewMockBody(mock.responseBody),
	},
		nil
}

func (mock *MockHttpClient) ExpectGet(
     expectedUrl string, expectedOAuthPairs map[string]string, responseBody string) {
	mock.url = expectedUrl
	mock.oAuthChecker = NewOAuthChecker(mock.t, expectedOAuthPairs)
	mock.responseBody = responseBody
}

type OAuthChecker struct {
  headerPairs map[string]string
  t *testing.T
}

func NewOAuthChecker(t *testing.T, headerPairs map[string]string) *OAuthChecker {
     return &OAuthChecker{
            headerPairs: headerPairs,
            t: t,
     }
}

func (o *OAuthChecker) CheckHeader(header string) {
     assertEqM(o.t, "OAuth ", header[0:6], "OAuth Header did not begin correctly.")
     paramsStr := header[6:]
     params := strings.Split(paramsStr, "\n    ", -1)
     paramMap := make(map[string]string)
     for _, param := range params {
         keyvalue := strings.Split(param, "=", -1)
         // line looks like: key="value", strip off the quotes
         // TODO(mrjones): this is pretty hacky
         paramMap[keyvalue[0]] = keyvalue[1][1:len(keyvalue[1])-2]
     }
     for key, value := range o.headerPairs {
         assertEqM(o.t, value, paramMap[key], "For OAuth parameter " + key)
     }
}

type MockBody struct {
	reader io.Reader
}

func NewMockBody(body string) *MockBody {
	return &MockBody{
		reader: strings.NewReader(body),
	}
}

func (*MockBody) Close() os.Error {
	return nil
}

func (mock *MockBody) Read(p []byte) (n int, err os.Error) {
	return mock.reader.Read(p)
}
<|endoftext|>


<commit_before>package osmpbf

import (
	"fmt"
	"io"
	"os"
	"reflect"
	"testing"
	"time"
)

const (
	// originally downloaded from http://download.geofabrik.de/europe/great-britain/england/greater-london.html
	London    = "greater-london-140324.osm.pbf"
	LondonURL = "https://googledrive.com/host/0B8pisLiGtmqDR3dOR3hrWUpRTVE"
)

func init() {
	_, err := os.Stat(London)
	if os.IsNotExist(err) {
		panic(fmt.Sprintf("\nDownload %s from %s.\nFor example: 'wget -O %s %s'", London, LondonURL, London, LondonURL))
	}
}

func TestDecoder(t *testing.T) {
	f, err := os.Open(London)
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()

	var n *Node
	en := &Node{
		ID:  18088578,
		Lat: 51.5442632,
		Lon: -0.2010027,
		Tags: map[string]string{
			"alt_name":   "The King's Head",
			"amenity":    "pub",
			"created_by": "JOSM",
			"name":       "The Luminaire",
			"note":       "Live music venue too",
		},
	}

	var w *Way
	ew := &Way{
		ID:      4257116,
		NodeIDs: []int64{21544864, 333731851, 333731852, 333731850, 333731855, 333731858, 333731854, 108047, 769984352, 21544864},
		Tags: map[string]string{
			"area":    "yes",
			"highway": "pedestrian",
			"name":    "Fitzroy Square",
		},
	}

	var r *Relation
	er := &Relation{
		ID: 7677,
		Members: []Member{
			Member{ID: 4875932, Type: WayType, Role: "outer"},
			Member{ID: 4894305, Type: WayType, Role: "inner"},
		},
		Tags: map[string]string{
			"created_by": "Potlatch 0.9c",
			"type":       "multipolygon",
		},
	}

	d := NewDecoder(f)
	for {
		if v, err := d.Decode(); err == io.EOF {
			break
		} else if err != nil {
			t.Fatal(err)
		} else {
			switch v := v.(type) {
			case *Node:
				if v.ID == en.ID {
					n = v
				}
			case *Way:
				if v.ID == ew.ID {
					w = v
				}
			case *Relation:
				if v.ID == er.ID {
					r = v
				}
			default:
				t.Fatalf("unknown type %T", v)
			}
		}
	}

	if !reflect.DeepEqual(en, n) {
		t.Errorf("\nExpected: %#v\nActual:   %#v", en, n)
	}
	if !reflect.DeepEqual(ew, w) {
		t.Errorf("\nExpected: %#v\nActual:   %#v", ew, w)
	}
	if !reflect.DeepEqual(er, r) {
		t.Errorf("\nExpected: %#v\nActual:   %#v", er, r)
	}
}

func BenchmarkDecoder(b *testing.B) {
	f, err := os.Open(London)
	if err != nil {
		b.Fatal(err)
	}
	defer f.Close()

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		f.Seek(0, 0)
		d := NewDecoder(f)
		n, w, r, count, start := 0, 0, 0, 0, time.Now()
		for {
			if v, err := d.Decode(); err == io.EOF {
				break
			} else if err != nil {
				b.Fatal(err)
			} else {
				switch v := v.(type) {
				case *Node:
					n++
				case *Way:
					w++
				case *Relation:
					r++
				default:
					b.Fatalf("unknown type %T", v)
				}
			}
			count++
		}
		b.Logf("Done in %.3f seconds. Total: %d, Nodes: %d, Ways: %d, Relations: %d\n",
			time.Now().Sub(start).Seconds(), count, n, w, r)
	}
}
<commit_msg>Better test and benchmark.<commit_after>package osmpbf

import (
	"fmt"
	"io"
	"os"
	"reflect"
	"testing"
	"time"
)

const (
	// originally downloaded from http://download.geofabrik.de/europe/great-britain/england/greater-london.html
	London    = "greater-london-140324.osm.pbf"
	LondonURL = "https://googledrive.com/host/0B8pisLiGtmqDR3dOR3hrWUpRTVE"
)

func init() {
	_, err := os.Stat(London)
	if os.IsNotExist(err) {
		panic(fmt.Sprintf("\nDownload %s from %s.\nFor example: 'wget -O %s %s'", London, LondonURL, London, LondonURL))
	}
}

func TestDecoder(t *testing.T) {
	f, err := os.Open(London)
	if err != nil {
		t.Fatal(err)
	}
	defer f.Close()

	var n *Node
	en := &Node{
		ID:  18088578,
		Lat: 51.5442632,
		Lon: -0.2010027,
		Tags: map[string]string{
			"alt_name":   "The King's Head",
			"amenity":    "pub",
			"created_by": "JOSM",
			"name":       "The Luminaire",
			"note":       "Live music venue too",
		},
	}

	var w *Way
	ew := &Way{
		ID:      4257116,
		NodeIDs: []int64{21544864, 333731851, 333731852, 333731850, 333731855, 333731858, 333731854, 108047, 769984352, 21544864},
		Tags: map[string]string{
			"area":    "yes",
			"highway": "pedestrian",
			"name":    "Fitzroy Square",
		},
	}

	var r *Relation
	er := &Relation{
		ID: 7677,
		Members: []Member{
			Member{ID: 4875932, Type: WayType, Role: "outer"},
			Member{ID: 4894305, Type: WayType, Role: "inner"},
		},
		Tags: map[string]string{
			"created_by": "Potlatch 0.9c",
			"type":       "multipolygon",
		},
	}

	var nc, wc, rc int
	enc, ewc, erc := 2729006, 459055, 12833
	d := NewDecoder(f)
	for {
		if v, err := d.Decode(); err == io.EOF {
			break
		} else if err != nil {
			t.Fatal(err)
		} else {
			switch v := v.(type) {
			case *Node:
				nc++
				if v.ID == en.ID {
					n = v
				}
			case *Way:
				wc++
				if v.ID == ew.ID {
					w = v
				}
			case *Relation:
				rc++
				if v.ID == er.ID {
					r = v
				}
			default:
				t.Fatalf("unknown type %T", v)
			}
		}
	}

	if !reflect.DeepEqual(en, n) {
		t.Errorf("\nExpected: %#v\nActual:   %#v", en, n)
	}
	if !reflect.DeepEqual(ew, w) {
		t.Errorf("\nExpected: %#v\nActual:   %#v", ew, w)
	}
	if !reflect.DeepEqual(er, r) {
		t.Errorf("\nExpected: %#v\nActual:   %#v", er, r)
	}
	if enc != nc || ewc != wc || erc != rc {
		t.Errorf("\nExpected %7d nodes, %7d ways, %7d relations\nGot      %7d nodes, %7d ways, %7d relations", enc, ewc, erc, nc, wc, rc)
	}
}

func BenchmarkDecoder(b *testing.B) {
	file := os.Getenv("OSMPBF_BENCHMARK_FILE")
	if file == "" {
		file = London
	}
	f, err := os.Open(file)
	if err != nil {
		b.Fatal(err)
	}
	defer f.Close()

	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		f.Seek(0, 0)
		d := NewDecoder(f)
		n, w, r, c, start := 0, 0, 0, 0, time.Now()
		for {
			if v, err := d.Decode(); err == io.EOF {
				break
			} else if err != nil {
				b.Fatal(err)
			} else {
				switch v := v.(type) {
				case *Node:
					n++
				case *Way:
					w++
				case *Relation:
					r++
				default:
					b.Fatalf("unknown type %T", v)
				}
			}
			c++
		}

		b.Logf("Done in %.3f seconds. Total: %d, Nodes: %d, Ways: %d, Relations: %d\n",
			time.Now().Sub(start).Seconds(), c, n, w, r)
	}
}
<|endoftext|>


<commit_before>package zeroformatter

import (
	"encoding/binary"
	"errors"
	"fmt"
	"math"
	"reflect"
	"time"
	"unicode/utf16"

	"github.com/shamaton/zeroformatter/char"
	"github.com/shamaton/zeroformatter/datetimeoffset"
)

type deserializer struct {
	data []byte
}

func createDeserializer(data []byte) *deserializer {
	return &deserializer{
		data: data,
	}
}

const minStructDataSize = 9

func Deserialize(holder interface{}, data []byte) error {
	ds := createDeserializer(data)

	t := reflect.ValueOf(holder)
	if t.Kind() != reflect.Ptr {
		return fmt.Errorf("holder must set pointer value. but got: %t", holder)
	}

	t = t.Elem()
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}

	// byte to Struct
	if t.Kind() == reflect.Struct && !isDateTime(t) && !isDateTimeOffset(t) {
		return ds.deserializeStruct(t)
	}

	// byte to primitive
	_, err := ds.deserialize(t, 0)
	return err
}

func (d *deserializer) deserializeStruct(t reflect.Value) error {
	dataLen := len(d.data)
	if dataLen < minStructDataSize {
		return fmt.Errorf("data size is not enough: %d", dataLen)
	}

	// data lookup
	offset := uint32(0)

	// size
	b, offset := d.read_s4(offset)
	size := binary.LittleEndian.Uint32(b)
	if size != uint32(dataLen) {
		return fmt.Errorf("data size is wrong [ %d : %d ]", size, dataLen)
	}

	// index
	b, offset = d.read_s4(offset)
	dataIndex := binary.LittleEndian.Uint32(b)
	if dataIndex != uint32(t.NumField()-1) {
		return fmt.Errorf("data index is diffrent [ %d : %d ]", dataIndex, t.NumField()-1)
	}

	for i := 0; i < t.NumField(); i++ {
		b, offset = d.read_s4(offset)
		dataOffset := binary.LittleEndian.Uint32(b)
		if _, err := d.deserialize(t.Field(i), dataOffset); err != nil {
			return err
		}
	}
	return nil
}

func isDateTime(value reflect.Value) bool {
	i := value.Interface()
	switch i.(type) {
	case time.Time:
		return true
	}
	return false
}

func isDateTimeOffset(value reflect.Value) bool {
	i := value.Interface()
	switch i.(type) {
	case datetimeoffset.DateTimeOffset:
		return true
	}
	return false
}

func isDuration(value reflect.Value) bool {
	// check type
	i := value.Interface()
	switch i.(type) {
	case time.Duration:
		return true
	}
	return false
}

func isChar(value reflect.Value) bool {
	i := value.Interface()
	switch i.(type) {
	case char.Char:
		return true
	}
	return false
}

func (d *deserializer) read_s1(index uint32) (byte, uint32) {
	rb := uint32(1)
	return d.data[index], index + rb
}

func (d *deserializer) read_s2(index uint32) ([]byte, uint32) {
	rb := uint32(2)
	return d.data[index : index+rb], index + rb
}

func (d *deserializer) read_s4(index uint32) ([]byte, uint32) {
	rb := uint32(4)
	return d.data[index : index+rb], index + rb
}

func (d *deserializer) read_s8(index uint32) ([]byte, uint32) {
	rb := uint32(8)
	return d.data[index : index+rb], index + rb
}

func (d *deserializer) deserialize(rv reflect.Value, offset uint32) (uint32, error) {
	var err error

	switch rv.Kind() {
	case reflect.Int8:
		b, o := d.read_s1(offset)
		v := int8(b)
		rv.Set(reflect.ValueOf(v))
		// update
		offset = o

	case reflect.Int16:
		// Int16 [short(2)]
		b, o := d.read_s2(offset)
		_v := binary.LittleEndian.Uint16(b)
		v := int16(_v)
		rv.Set(reflect.ValueOf(v))
		// update
		offset = o

	case reflect.Int32:
		// char is used instead of rune
		if isChar(rv) {
			// rune [ushort(2)]
			b, o := d.read_s2(offset)
			u16s := []uint16{binary.LittleEndian.Uint16(b)}
			_v := utf16.Decode(u16s)
			v := char.Char(_v[0])
			rv.Set(reflect.ValueOf(v))

			// update
			offset = o
		} else {
			// Int32 [int(4)]
			b, o := d.read_s4(offset)
			_v := binary.LittleEndian.Uint32(b)
			v := int32(int32(_v))
			rv.Set(reflect.ValueOf(v))
			// update
			offset = o
		}

	case reflect.Int:
		// Int32 [int(4)]
		b, o := d.read_s4(offset)
		_v := binary.LittleEndian.Uint32(b)
		// NOTE : double cast
		v := int(int32(_v))
		rv.Set(reflect.ValueOf(v))
		// update
		offset = o

	case reflect.Int64:
		if isDuration(rv) {
			// todo : NOTE procedure is as same as datetime
			b, o1 := d.read_s8(offset)
			seconds := binary.LittleEndian.Uint64(b)
			b, o2 := d.read_s4(o1)
			nanos := binary.LittleEndian.Uint32(b)
			v := time.Duration(int64(seconds)*1000*1000 + int64(nanos))

			rv.Set(reflect.ValueOf(v))
			// update
			offset = o2
		} else {
			// Int64 [long(8)]
			b, o := d.read_s8(offset)
			_v := binary.LittleEndian.Uint64(b)
			v := int64(_v)
			rv.SetInt(v)
			// update
			offset = o
		}

	case reflect.Uint8:
		// byte in cSharp
		_v, o := d.read_s1(offset)
		v := uint8(_v)
		rv.Set(reflect.ValueOf(v))
		// update
		offset = o

	case reflect.Uint16:
		// Uint16 / Char
		b, o := d.read_s2(offset)
		v := binary.LittleEndian.Uint16(b)
		rv.Set(reflect.ValueOf(v))
		// update
		offset = o

	case reflect.Uint32:
		b, o := d.read_s4(offset)
		v := binary.LittleEndian.Uint32(b)
		rv.Set(reflect.ValueOf(v))
		// update
		offset = o

	case reflect.Uint:
		b, o := d.read_s4(offset)
		_v := binary.LittleEndian.Uint32(b)
		v := uint(_v)
		rv.Set(reflect.ValueOf(v))
		// update
		offset = o

	case reflect.Uint64:
		b, o := d.read_s8(offset)
		v := binary.LittleEndian.Uint64(b)
		rv.SetUint(v)
		// update
		offset = o

	case reflect.Float32:
		// Single
		b, o := d.read_s4(offset)
		_v := binary.LittleEndian.Uint32(b)
		v := math.Float32frombits(_v)
		rv.Set(reflect.ValueOf(v))
		// update
		offset = o

	case reflect.Float64:
		// Double
		b, o := d.read_s8(offset)
		_v := binary.LittleEndian.Uint64(b)
		v := math.Float64frombits(_v)
		rv.Set(reflect.ValueOf(v))
		// update
		offset = o

	case reflect.Bool:
		b, o := d.read_s1(offset)
		if b == 0x01 {
			rv.SetBool(true)
		} else if b == 0x00 {
			rv.SetBool(false)
		}
		// update
		offset = o

	case reflect.String:
		b, o := d.read_s4(offset)
		l := binary.LittleEndian.Uint32(b)
		v := string(d.data[o : o+l])
		rv.SetString(v)
		// update
		offset = o + l

	case reflect.Struct:
		if isDateTimeOffset(rv) {
			b, o1 := d.read_s8(offset)
			seconds := binary.LittleEndian.Uint64(b)
			b, o2 := d.read_s4(o1)
			nanos := binary.LittleEndian.Uint32(b)
			b, o3 := d.read_s2(o2)
			offMin := binary.LittleEndian.Uint16(b)

			v := datetimeoffset.Unix(int64(seconds)-int64(offMin*60), int64(nanos))
			rv.Set(reflect.ValueOf(v))
			// update
			offset = o3

		} else if isDateTime(rv) {
			b, o1 := d.read_s8(offset)
			seconds := binary.LittleEndian.Uint64(b)
			b, o2 := d.read_s4(o1)
			nanos := binary.LittleEndian.Uint32(b)
			v := time.Unix(int64(seconds), int64(nanos))

			rv.Set(reflect.ValueOf(v))
			// update
			offset = o2
		} else {
			for i := 0; i < rv.NumField(); i++ {
				offset, err = d.deserialize(rv.Field(i), offset)
				if err != nil {
					return 0, err
				}
			}
		}

	case reflect.Slice:
		// element type
		e := rv.Type().Elem()

		// length
		b, offset := d.read_s4(offset)
		l := int(int32(binary.LittleEndian.Uint32(b)))

		// data is null
		if l < 0 {
			return offset, nil
		}

		o := offset
		tmpSlice := reflect.MakeSlice(rv.Type(), l, l)

		for i := 0; i < l; i++ {
			v := reflect.New(e).Elem()
			o, err = d.deserialize(v, o)
			if err != nil {
				return 0, err
			}

			tmpSlice.Index(i).Set(v)
		}
		rv.Set(tmpSlice)

		// update
		offset = o

	case reflect.Array:
		// element type
		e := rv.Type().Elem()

		// length
		b, offset := d.read_s4(offset)
		l := int(int32(binary.LittleEndian.Uint32(b)))

		// data is null
		if l < 0 {
			return offset, nil
		}
		if l != rv.Len() {
			return 0, fmt.Errorf("Array Length is different : data[%d] array[%d]", l, rv.Len())
		}

		o := offset
		for i := 0; i < l; i++ {
			v := reflect.New(e).Elem()
			o, err = d.deserialize(v, o)
			if err != nil {
				return 0, err
			}
			rv.Index(i).Set(v)
		}

		// update
		offset = o

	case reflect.Ptr:
		e := rv.Type().Elem()
		v := reflect.New(e).Elem()
		offset, err = d.deserialize(v, offset)
		rv.Set(v.Addr())

	default:
		err = errors.New(fmt.Sprint("this type is not supported : ", rv.Type()))
	}

	return offset, err
}
<commit_msg>decrease memory allocation<commit_after>package zeroformatter

import (
	"encoding/binary"
	"errors"
	"fmt"
	"math"
	"reflect"
	"time"
	"unicode/utf16"

	"github.com/shamaton/zeroformatter/char"
	"github.com/shamaton/zeroformatter/datetimeoffset"
)

type deserializer struct {
	data []byte
}

func createDeserializer(data []byte) *deserializer {
	return &deserializer{
		data: data,
	}
}

const minStructDataSize = 9

func Deserialize(holder interface{}, data []byte) error {
	ds := createDeserializer(data)

	t := reflect.ValueOf(holder)
	if t.Kind() != reflect.Ptr {
		return fmt.Errorf("holder must set pointer value. but got: %t", holder)
	}

	t = t.Elem()
	if t.Kind() == reflect.Ptr {
		t = t.Elem()
	}

	// byte to Struct
	if t.Kind() == reflect.Struct && !isDateTime(t) && !isDateTimeOffset(t) {
		return ds.deserializeStruct(t)
	}

	// byte to primitive
	_, err := ds.deserialize(t, 0)
	return err
}

func (d *deserializer) deserializeStruct(t reflect.Value) error {
	dataLen := len(d.data)
	if dataLen < minStructDataSize {
		return fmt.Errorf("data size is not enough: %d", dataLen)
	}

	// data lookup
	offset := uint32(0)

	// size
	b, offset := d.read_s4(offset)
	size := binary.LittleEndian.Uint32(b)
	if size != uint32(dataLen) {
		return fmt.Errorf("data size is wrong [ %d : %d ]", size, dataLen)
	}

	// index
	b, offset = d.read_s4(offset)
	dataIndex := binary.LittleEndian.Uint32(b)
	if dataIndex != uint32(t.NumField()-1) {
		return fmt.Errorf("data index is diffrent [ %d : %d ]", dataIndex, t.NumField()-1)
	}

	for i := 0; i < t.NumField(); i++ {
		b, offset = d.read_s4(offset)
		dataOffset := binary.LittleEndian.Uint32(b)
		if _, err := d.deserialize(t.Field(i), dataOffset); err != nil {
			return err
		}
	}
	return nil
}

func isDateTime(value reflect.Value) bool {
	i := value.Interface()
	switch i.(type) {
	case time.Time:
		return true
	}
	return false
}

func isDateTimeOffset(value reflect.Value) bool {
	i := value.Interface()
	switch i.(type) {
	case datetimeoffset.DateTimeOffset:
		return true
	}
	return false
}

func isDuration(value reflect.Value) bool {
	// check type
	i := value.Interface()
	switch i.(type) {
	case time.Duration:
		return true
	}
	return false
}

func isChar(value reflect.Value) bool {
	i := value.Interface()
	switch i.(type) {
	case char.Char:
		return true
	}
	return false
}

func (d *deserializer) read_s1(index uint32) (byte, uint32) {
	rb := uint32(1)
	return d.data[index], index + rb
}

func (d *deserializer) read_s2(index uint32) ([]byte, uint32) {
	rb := uint32(2)
	return d.data[index : index+rb], index + rb
}

func (d *deserializer) read_s4(index uint32) ([]byte, uint32) {
	rb := uint32(4)
	return d.data[index : index+rb], index + rb
}

func (d *deserializer) read_s8(index uint32) ([]byte, uint32) {
	rb := uint32(8)
	return d.data[index : index+rb], index + rb
}

func (d *deserializer) deserialize(rv reflect.Value, offset uint32) (uint32, error) {
	var err error

	switch rv.Kind() {
	case reflect.Int8:
		b, o := d.read_s1(offset)
		rv.SetInt(int64(b))
		// update
		offset = o

	case reflect.Int16:
		// Int16 [short(2)]
		b, o := d.read_s2(offset)
		_v := binary.LittleEndian.Uint16(b)
		rv.SetInt(int64(_v))
		// update
		offset = o

	case reflect.Int32:
		// char is used instead of rune
		if isChar(rv) {
			// rune [ushort(2)]
			b, o := d.read_s2(offset)
			u16s := []uint16{binary.LittleEndian.Uint16(b)}
			_v := utf16.Decode(u16s)
			v := char.Char(_v[0])
			rv.Set(reflect.ValueOf(v))

			// update
			offset = o
		} else {
			// Int32 [int(4)]
			b, o := d.read_s4(offset)
			_v := binary.LittleEndian.Uint32(b)
			// NOTE : double cast
			rv.SetInt(int64(int32(_v)))
			// update
			offset = o
		}

	case reflect.Int:
		// Int32 [int(4)]
		b, o := d.read_s4(offset)
		_v := binary.LittleEndian.Uint32(b)
		// NOTE : double cast
		rv.SetInt(int64(int32(_v)))
		// update
		offset = o

	case reflect.Int64:
		if isDuration(rv) {
			// todo : NOTE procedure is as same as datetime
			b, o1 := d.read_s8(offset)
			seconds := binary.LittleEndian.Uint64(b)
			b, o2 := d.read_s4(o1)
			nanos := binary.LittleEndian.Uint32(b)
			v := time.Duration(int64(seconds)*1000*1000 + int64(nanos))

			rv.Set(reflect.ValueOf(v))
			// update
			offset = o2
		} else {
			// Int64 [long(8)]
			b, o := d.read_s8(offset)
			v := binary.LittleEndian.Uint64(b)
			rv.SetInt(int64(v))
			// update
			offset = o
		}

	case reflect.Uint8:
		// byte in cSharp
		_v, o := d.read_s1(offset)
		rv.SetUint(uint64(_v))
		// update
		offset = o

	case reflect.Uint16:
		// Uint16 / Char
		b, o := d.read_s2(offset)
		v := binary.LittleEndian.Uint16(b)
		rv.SetUint(uint64(v))
		// update
		offset = o

	case reflect.Uint32:
		b, o := d.read_s4(offset)
		v := binary.LittleEndian.Uint32(b)
		rv.SetUint(uint64(v))
		// update
		offset = o

	case reflect.Uint:
		b, o := d.read_s4(offset)
		v := binary.LittleEndian.Uint32(b)
		rv.SetUint(uint64(v))
		// update
		offset = o

	case reflect.Uint64:
		b, o := d.read_s8(offset)
		v := binary.LittleEndian.Uint64(b)
		rv.SetUint(v)
		// update
		offset = o

	case reflect.Float32:
		// Single
		b, o := d.read_s4(offset)
		_v := binary.LittleEndian.Uint32(b)
		v := math.Float32frombits(_v)
		rv.SetFloat(float64(v))
		// update
		offset = o

	case reflect.Float64:
		// Double
		b, o := d.read_s8(offset)
		_v := binary.LittleEndian.Uint64(b)
		v := math.Float64frombits(_v)
		rv.SetFloat(v)
		// update
		offset = o

	case reflect.Bool:
		b, o := d.read_s1(offset)
		if b == 0x01 {
			rv.SetBool(true)
		} else if b == 0x00 {
			rv.SetBool(false)
		}
		// update
		offset = o

	case reflect.String:
		b, o := d.read_s4(offset)
		l := binary.LittleEndian.Uint32(b)
		v := string(d.data[o : o+l])
		rv.SetString(v)
		// update
		offset = o + l

	case reflect.Struct:
		if isDateTimeOffset(rv) {
			b, o1 := d.read_s8(offset)
			seconds := binary.LittleEndian.Uint64(b)
			b, o2 := d.read_s4(o1)
			nanos := binary.LittleEndian.Uint32(b)
			b, o3 := d.read_s2(o2)
			offMin := binary.LittleEndian.Uint16(b)

			v := datetimeoffset.Unix(int64(seconds)-int64(offMin*60), int64(nanos))
			rv.Set(reflect.ValueOf(v))
			// update
			offset = o3

		} else if isDateTime(rv) {
			b, o1 := d.read_s8(offset)
			seconds := binary.LittleEndian.Uint64(b)
			b, o2 := d.read_s4(o1)
			nanos := binary.LittleEndian.Uint32(b)
			v := time.Unix(int64(seconds), int64(nanos))

			rv.Set(reflect.ValueOf(v))
			// update
			offset = o2
		} else {
			for i := 0; i < rv.NumField(); i++ {
				offset, err = d.deserialize(rv.Field(i), offset)
				if err != nil {
					return 0, err
				}
			}
		}

	case reflect.Slice:
		// element type
		e := rv.Type().Elem()

		// length
		b, offset := d.read_s4(offset)
		l := int(int32(binary.LittleEndian.Uint32(b)))

		// data is null
		if l < 0 {
			return offset, nil
		}

		o := offset
		tmpSlice := reflect.MakeSlice(rv.Type(), l, l)

		for i := 0; i < l; i++ {
			v := reflect.New(e).Elem()
			o, err = d.deserialize(v, o)
			if err != nil {
				return 0, err
			}

			tmpSlice.Index(i).Set(v)
		}
		rv.Set(tmpSlice)

		// update
		offset = o

	case reflect.Array:
		// element type
		e := rv.Type().Elem()

		// length
		b, offset := d.read_s4(offset)
		l := int(int32(binary.LittleEndian.Uint32(b)))

		// data is null
		if l < 0 {
			return offset, nil
		}
		if l != rv.Len() {
			return 0, fmt.Errorf("Array Length is different : data[%d] array[%d]", l, rv.Len())
		}

		o := offset
		for i := 0; i < l; i++ {
			v := reflect.New(e).Elem()
			o, err = d.deserialize(v, o)
			if err != nil {
				return 0, err
			}
			rv.Index(i).Set(v)
		}

		// update
		offset = o

	case reflect.Ptr:
		e := rv.Type().Elem()
		v := reflect.New(e).Elem()
		offset, err = d.deserialize(v, offset)
		rv.Set(v.Addr())

	default:
		err = errors.New(fmt.Sprint("this type is not supported : ", rv.Type()))
	}

	return offset, err
}
<|endoftext|>


<commit_before>/*Package paint provides functions to edit group of pixels on an image.*/
package paint

import (
	"image"
	"image/color"
	"math"

	"github.com/anthonynsimon/bild/clone"
	"github.com/anthonynsimon/bild/util"
)

const (
	maxDistance = 510.0
)

type fillPoint struct {
	X, Y                  int
	MarkedFromBelow       bool
	MarkedFromAbove       bool
	PreviousFillEdgeLeft  int
	PreviousFillEdgeRight int
}

// FloodFill fills a area of the image with a provided color and returns the new image.
// Parameter sp is the starting point of the fill.
// Parameter c is the fill color.
// Parameter fuzz is the percentage of maximum color distance tolerated when flooding the area.
func FloodFill(img image.Image, sp image.Point, c color.Color, fuzz float64) *image.RGBA {

	var st util.Stack
	var point fillPoint
	visited := make(map[int]bool)
	im := clone.AsRGBA(img)

	maxX := im.Bounds().Dx() - 1
	maxY := im.Bounds().Dy() - 1
	if sp.X > maxX || sp.X < 0 || sp.Y > maxY || sp.Y < 0 {
		return im
	}

	fuzzSquared := math.Pow(maxDistance*fuzz/100, 2)
	matchColor := color.NRGBAModel.Convert(im.At(sp.X, sp.Y)).(color.NRGBA)

	st.Push(fillPoint{sp.X, sp.Y, true, true, 0, 0})

	// loop until there are no more points remaining
	for st.Len() > 0 {
		point = st.Pop().(fillPoint)
		pixOffset := im.PixOffset(point.X, point.Y)

		if !visited[pixOffset] {

			im.Set(point.X, point.Y, c)
			visited[pixOffset] = true

			// fill left side
			xpos := point.X
			for {
				xpos--
				if xpos < 0 {
					xpos = 0
					break
				}
				pixOffset = im.PixOffset(xpos, point.Y)
				if isColorMatch(im, pixOffset, matchColor, fuzzSquared) {
					im.Set(xpos, point.Y, c)
					visited[pixOffset] = true
				} else {
					break
				}
			}

			leftFillEdge := xpos - 1
			if leftFillEdge < 0 {
				leftFillEdge = 0
			}

			// fill right side
			xpos = point.X
			for {
				xpos++
				if xpos > maxX {
					break
				}

				pixOffset = im.PixOffset(xpos, point.Y)
				if isColorMatch(im, pixOffset, matchColor, fuzzSquared) {
					im.Set(xpos, point.Y, c)
					visited[pixOffset] = true
				} else {
					break
				}
			}
			rightFillEdge := xpos + 1
			if rightFillEdge > maxX {
				rightFillEdge = maxX
			}

			// skip every second check for pixels above and below
			skipCheckAbove := false
			skipCheckBelow := false

			// check pixels above/below the fill line
			for x := leftFillEdge; x <= rightFillEdge; x++ {
				outOfPreviousRange := x >= point.PreviousFillEdgeRight || x <= point.PreviousFillEdgeLeft

				if skipCheckBelow {
					skipCheckBelow = !skipCheckBelow
				} else {
					if point.MarkedFromBelow == true || outOfPreviousRange {
						if point.Y > 0 {
							pixOffset = im.PixOffset(x, point.Y-1)
							if false == visited[pixOffset] && isColorMatch(im, pixOffset, matchColor, fuzzSquared) {
								skipCheckBelow = true
								st.Push(fillPoint{x, (point.Y - 1), true, false, leftFillEdge, rightFillEdge})
							}
						}
					}
				}

				if skipCheckAbove {
					skipCheckAbove = !skipCheckAbove
				} else {
					if point.MarkedFromAbove == true || outOfPreviousRange {
						if point.Y < maxY {

							pixOffset = im.PixOffset(x, point.Y+1)
							if false == visited[pixOffset] && isColorMatch(im, pixOffset, matchColor, fuzzSquared) {
								skipCheckAbove = true
								st.Push(fillPoint{x, (point.Y + 1), false, true, leftFillEdge, rightFillEdge})
							}
						}
					}
				}
			}
		}
	}

	return im
}

func isColorMatch(im *image.RGBA, pixel int, mc color.NRGBA, fuzzSquared float64) bool {

	i := pixel
	c1 := mc
	c2 := color.NRGBA{R: im.Pix[i+0], G: im.Pix[i+1], B: im.Pix[i+2], A: im.Pix[i+3]}

	rDiff := float64(c1.R) - float64(c2.R)
	gDiff := float64(c1.G) - float64(c2.G)
	bDiff := float64(c1.B) - float64(c2.B)
	aDiff := float64(c1.A) - float64(c2.A)

	distanceR := math.Max(math.Pow(rDiff, 2), math.Pow(rDiff-aDiff, 2))
	distanceG := math.Max(math.Pow(gDiff, 2), math.Pow(gDiff-aDiff, 2))
	distanceB := math.Max(math.Pow(bDiff, 2), math.Pow(bDiff-aDiff, 2))
	distance := (distanceR + distanceG + distanceB) / 3

	if distance > fuzzSquared {
		return false
	}

	return true
}
<commit_msg>Fix typo<commit_after>/*Package paint provides functions to edit a group of pixels on an image.*/
package paint

import (
	"image"
	"image/color"
	"math"

	"github.com/anthonynsimon/bild/clone"
	"github.com/anthonynsimon/bild/util"
)

const (
	maxDistance = 510.0
)

type fillPoint struct {
	X, Y                  int
	MarkedFromBelow       bool
	MarkedFromAbove       bool
	PreviousFillEdgeLeft  int
	PreviousFillEdgeRight int
}

// FloodFill fills a area of the image with a provided color and returns the new image.
// Parameter sp is the starting point of the fill.
// Parameter c is the fill color.
// Parameter fuzz is the percentage of maximum color distance tolerated when flooding the area.
func FloodFill(img image.Image, sp image.Point, c color.Color, fuzz float64) *image.RGBA {

	var st util.Stack
	var point fillPoint
	visited := make(map[int]bool)
	im := clone.AsRGBA(img)

	maxX := im.Bounds().Dx() - 1
	maxY := im.Bounds().Dy() - 1
	if sp.X > maxX || sp.X < 0 || sp.Y > maxY || sp.Y < 0 {
		return im
	}

	fuzzSquared := math.Pow(maxDistance*fuzz/100, 2)
	matchColor := color.NRGBAModel.Convert(im.At(sp.X, sp.Y)).(color.NRGBA)

	st.Push(fillPoint{sp.X, sp.Y, true, true, 0, 0})

	// loop until there are no more points remaining
	for st.Len() > 0 {
		point = st.Pop().(fillPoint)
		pixOffset := im.PixOffset(point.X, point.Y)

		if !visited[pixOffset] {

			im.Set(point.X, point.Y, c)
			visited[pixOffset] = true

			// fill left side
			xpos := point.X
			for {
				xpos--
				if xpos < 0 {
					xpos = 0
					break
				}
				pixOffset = im.PixOffset(xpos, point.Y)
				if isColorMatch(im, pixOffset, matchColor, fuzzSquared) {
					im.Set(xpos, point.Y, c)
					visited[pixOffset] = true
				} else {
					break
				}
			}

			leftFillEdge := xpos - 1
			if leftFillEdge < 0 {
				leftFillEdge = 0
			}

			// fill right side
			xpos = point.X
			for {
				xpos++
				if xpos > maxX {
					break
				}

				pixOffset = im.PixOffset(xpos, point.Y)
				if isColorMatch(im, pixOffset, matchColor, fuzzSquared) {
					im.Set(xpos, point.Y, c)
					visited[pixOffset] = true
				} else {
					break
				}
			}
			rightFillEdge := xpos + 1
			if rightFillEdge > maxX {
				rightFillEdge = maxX
			}

			// skip every second check for pixels above and below
			skipCheckAbove := false
			skipCheckBelow := false

			// check pixels above/below the fill line
			for x := leftFillEdge; x <= rightFillEdge; x++ {
				outOfPreviousRange := x >= point.PreviousFillEdgeRight || x <= point.PreviousFillEdgeLeft

				if skipCheckBelow {
					skipCheckBelow = !skipCheckBelow
				} else {
					if point.MarkedFromBelow == true || outOfPreviousRange {
						if point.Y > 0 {
							pixOffset = im.PixOffset(x, point.Y-1)
							if false == visited[pixOffset] && isColorMatch(im, pixOffset, matchColor, fuzzSquared) {
								skipCheckBelow = true
								st.Push(fillPoint{x, (point.Y - 1), true, false, leftFillEdge, rightFillEdge})
							}
						}
					}
				}

				if skipCheckAbove {
					skipCheckAbove = !skipCheckAbove
				} else {
					if point.MarkedFromAbove == true || outOfPreviousRange {
						if point.Y < maxY {

							pixOffset = im.PixOffset(x, point.Y+1)
							if false == visited[pixOffset] && isColorMatch(im, pixOffset, matchColor, fuzzSquared) {
								skipCheckAbove = true
								st.Push(fillPoint{x, (point.Y + 1), false, true, leftFillEdge, rightFillEdge})
							}
						}
					}
				}
			}
		}
	}

	return im
}

func isColorMatch(im *image.RGBA, pixel int, mc color.NRGBA, fuzzSquared float64) bool {

	i := pixel
	c1 := mc
	c2 := color.NRGBA{R: im.Pix[i+0], G: im.Pix[i+1], B: im.Pix[i+2], A: im.Pix[i+3]}

	rDiff := float64(c1.R) - float64(c2.R)
	gDiff := float64(c1.G) - float64(c2.G)
	bDiff := float64(c1.B) - float64(c2.B)
	aDiff := float64(c1.A) - float64(c2.A)

	distanceR := math.Max(math.Pow(rDiff, 2), math.Pow(rDiff-aDiff, 2))
	distanceG := math.Max(math.Pow(gDiff, 2), math.Pow(gDiff-aDiff, 2))
	distanceB := math.Max(math.Pow(bDiff, 2), math.Pow(bDiff-aDiff, 2))
	distance := (distanceR + distanceG + distanceB) / 3

	if distance > fuzzSquared {
		return false
	}

	return true
}
<|endoftext|>


<commit_before>package main

import (
	"os"
	"strings"
	"unicode"
)

func replacer(parameters map[string]string) func(string) string {
	params := paramReplacer(parameters)
	return func(input string) string {
		return os.ExpandEnv(params.Replace(input))
	}
}

func paramReplacer(parameters map[string]string) *strings.Replacer {
	rep := make([]string, 0, len(parameters))
	for key, value := range parameters {
		// colon parameter
		rep = append(rep, ":"+key)
		rep = append(rep, value)

		// bracket parameter
		rep = append(rep, "{"+key+"}")
		rep = append(rep, value)
	}

	return strings.NewReplacer(rep...)
}

func findParam(input string) string {
	out := ""

	if input[0] == ':' {
		out = input[1:]

	}

	if input[0] == '{' && input[len(input)-1] == '}' {
		out = input[1 : len(input)-1]
	}

	return out

}

func paramFinder(input []string) []string {
	params := make([]string, 0)
	for _, p := range input {
		if param := findParam(p); param != "" {
			params = append(params, param)
		}
	}

	return params
}

func splitFunc(r rune) bool {
	if unicode.IsSpace(r) {
		return true
	}

	return unicode.IsSpace(r) ||
		r == ',' ||
		r == '"' ||
		r == '{' ||
		r == '}' ||
		r == '[' ||
		r == ']'
}

func dataSpliter(input string) []string {
	tmp := strings.FieldsFunc(input, splitFunc)
	result := make([]string, 0, len(tmp))
	for i := range tmp {
		if tmp[i] != ":" {
			result = append(result, tmp[i])
		}
	}
	return result
}
<commit_msg>Fix panic on parameter finding<commit_after>package main

import (
	"os"
	"strings"
	"unicode"
)

func replacer(parameters map[string]string) func(string) string {
	params := paramReplacer(parameters)
	return func(input string) string {
		return os.ExpandEnv(params.Replace(input))
	}
}

func paramReplacer(parameters map[string]string) *strings.Replacer {
	rep := make([]string, 0, len(parameters))
	for key, value := range parameters {
		// colon parameter
		rep = append(rep, ":"+key)
		rep = append(rep, value)

		// bracket parameter
		rep = append(rep, "{"+key+"}")
		rep = append(rep, value)
	}

	return strings.NewReplacer(rep...)
}

func findParam(input string) string {
	out := ""

	if len(input) == 0 {
		return out
	}

	if input[0] == ':' {
		out = input[1:]

	}

	if input[0] == '{' && input[len(input)-1] == '}' {
		out = input[1 : len(input)-1]
	}

	return out

}

func paramFinder(input []string) []string {
	params := make([]string, 0)
	for _, p := range input {
		if param := findParam(p); param != "" {
			params = append(params, param)
		}
	}

	return params
}

func splitFunc(r rune) bool {
	if unicode.IsSpace(r) {
		return true
	}

	return unicode.IsSpace(r) ||
		r == ',' ||
		r == '"' ||
		r == '{' ||
		r == '}' ||
		r == '[' ||
		r == ']'
}

func dataSpliter(input string) []string {
	tmp := strings.FieldsFunc(input, splitFunc)
	result := make([]string, 0, len(tmp))
	for i := range tmp {
		if tmp[i] != ":" {
			result = append(result, tmp[i])
		}
	}
	return result
}
<|endoftext|>


<commit_before>package audio

// DataFormat is an enum type to indicate the underlying data format used.
type DataFormat int

const (
	// Integer represents the int type
	Integer DataFormat = iota
	// Float represents the float64 type
	Float
	// Byte represents the byte type
	Byte
)

// Format is a high level representation of the underlying
type Format struct {
	// Channels is the number of channels contained in the data
	Channels int
	// SampleRate is the sampling rate in Hz
	SampleRate int
	// BitDepth is the number of bits of data for each sample
	BitDepth int
}

// PCMBuffer provides useful methods to read/manipulate audio buffers in PCM format
type PCMBuffer struct {
	Format *Format
	Ints   []int
	Floats []float64
	Bytes  []byte
	// DataType indicates the format used for the underlying data
	DataType DataFormat
}

// NewPCMIntBuffer returns a new PCM buffer backed by the passed integer samples
func NewPCMIntBuffer(data []int, format *Format) *PCMBuffer {
	return &PCMBuffer{
		Format:   format,
		DataType: Integer,
		Ints:     data,
	}
}

// NewPCMFloatBuffer returns a new PCM buffer backed by the passed float samples
func NewPCMFloatBuffer(data []float64, format *Format) *PCMBuffer {
	return &PCMBuffer{
		Format:   format,
		DataType: Float,
		Floats:   data,
	}
}

// NewPCMByteBuffer returns a new PCM buffer backed by the passed float samples
func NewPCMByteBuffer(data []byte, format *Format) *PCMBuffer {
	return &PCMBuffer{
		Format:   format,
		DataType: Byte,
		Bytes:    data,
	}
}

// Size returns the number of frames contained in the buffer.
func (b *PCMBuffer) Size() (numFrames int) {
	if b == nil || b.Format == nil {
		return 0
	}
	numChannels := b.Format.Channels
	if numChannels == 0 {
		numChannels = 1
	}
	switch b.DataType {
	case Integer:
		numFrames = len(b.Ints) / numChannels
	case Float:
		numFrames = len(b.Floats) / numChannels
	case Byte:
		sampleSize := int((b.Format.BitDepth-1)/8 + 1)
		numFrames = (len(b.Bytes) / sampleSize) / numChannels
	}
	return numFrames
}

func (b *PCMBuffer) Int16() []int16 {
	panic("not implemented")
}

func (b *PCMBuffer) Int32() []int32 {
	panic("not implemented")
}

func (b *PCMBuffer) Float32() []float32 {
	panic("not implemented")
}

func (b *PCMBuffer) Float64() []float64 {
	panic("not implemented")
}
<commit_msg>PCMBuffer: implement int16 to test the API<commit_after>package audio

import (
	"bytes"
	"encoding/binary"
)

// DataFormat is an enum type to indicate the underlying data format used.
type DataFormat int

const (
	// Unknown refers to an unknown format
	Unknown DataFormat = iota
	// Integer represents the int type.
	// it represents the native int format used in audio buffers.
	Integer
	// Float represents the float64 type.
	// It represents the native float format used in audio buffers.
	Float
	// Byte represents the byte type.
	Byte
)

// Format is a high level representation of the underlying data.
type Format struct {
	// Channels is the number of channels contained in the data
	Channels int
	// SampleRate is the sampling rate in Hz
	SampleRate int
	// BitDepth is the number of bits of data for each sample
	BitDepth int
	// Endianess indicate how the byte order of underlying bytes
	Endianness binary.ByteOrder
}

// PCMBuffer provides useful methods to read/manipulate audio buffers in PCM format
type PCMBuffer struct {
	// Format describes the format of the buffer data.
	Format *Format
	// Ints is a store for audio sample data as integers.
	Ints []int
	// Floats is a store for audio samples data as float64.
	Floats []float64
	// Bytes is a store for audio samples data as raw bytes.
	Bytes []byte
	// DataType indicates the primary format used for the underlying data.
	// The consumer of the buffer might want to look at this value to know what store
	// to use to optimaly retrieve data.
	DataType DataFormat
}

// NewPCMIntBuffer returns a new PCM buffer backed by the passed integer samples
func NewPCMIntBuffer(data []int, format *Format) *PCMBuffer {
	return &PCMBuffer{
		Format:   format,
		DataType: Integer,
		Ints:     data,
	}
}

// NewPCMFloatBuffer returns a new PCM buffer backed by the passed float samples
func NewPCMFloatBuffer(data []float64, format *Format) *PCMBuffer {
	return &PCMBuffer{
		Format:   format,
		DataType: Float,
		Floats:   data,
	}
}

// NewPCMByteBuffer returns a new PCM buffer backed by the passed float samples
func NewPCMByteBuffer(data []byte, format *Format) *PCMBuffer {
	return &PCMBuffer{
		Format:   format,
		DataType: Byte,
		Bytes:    data,
	}
}

// Size returns the number of frames contained in the buffer.
func (b *PCMBuffer) Size() (numFrames int) {
	if b == nil || b.Format == nil {
		return 0
	}
	numChannels := b.Format.Channels
	if numChannels == 0 {
		numChannels = 1
	}
	switch b.DataType {
	case Integer:
		numFrames = len(b.Ints) / numChannels
	case Float:
		numFrames = len(b.Floats) / numChannels
	case Byte:
		sampleSize := int((b.Format.BitDepth-1)/8 + 1)
		numFrames = (len(b.Bytes) / sampleSize) / numChannels
	}
	return numFrames
}

// Int16 returns the buffer samples as int16 sample values.
func (b *PCMBuffer) Int16() (out []int16) {
	if b == nil {
		return nil
	}
	switch b.DataType {
	case Integer, Float:
		out = make([]int16, len(b.Ints))
		for i := 0; i < len(b.Ints); i++ {
			out[i] = int16(b.Ints[i])
		}
	case Byte:
		// if the format isn't defined, we can't read the byte data
		if b.Format == nil || b.Format.Endianness == nil || b.Format.BitDepth == 0 {
			return out
		}
		bytesPerSample := int((b.Format.BitDepth-1)/8 + 1)
		buf := bytes.NewBuffer(b.Bytes)
		out := make([]int16, len(b.Bytes)/bytesPerSample)
		binary.Read(buf, b.Format.Endianness, &out)
	}
	return out
}

func (b *PCMBuffer) Int32() []int32 {
	panic("not implemented")
}

func (b *PCMBuffer) Float32() []float32 {
	panic("not implemented")
}

func (b *PCMBuffer) Float64() []float64 {
	panic("not implemented")
}
<|endoftext|>