<commit_before>package jira

import (
	"fmt"
)

// ProjectService handles projects for the JIRA instance / API.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project
type ProjectService struct {
	client *Client
}

// ProjectList represent a list of Projects
type ProjectList []struct {
	Expand          string          `json:"expand" structs:"expand"`
	Self            string          `json:"self" structs:"self"`
	ID              string          `json:"id" structs:"id"`
	Key             string          `json:"key" structs:"key"`
	Name            string          `json:"name" structs:"name"`
	AvatarUrls      AvatarUrls      `json:"avatarUrls" structs:"avatarUrls"`
	ProjectTypeKey  string          `json:"projectTypeKey" structs:"projectTypeKey"`
	ProjectCategory ProjectCategory `json:"projectCategory,omitempty" structs:"projectsCategory,omitempty"`
}

// ProjectCategory represents a single project category
type ProjectCategory struct {
	Self        string `json:"self" structs:"self"`
	ID          string `json:"id" structs:"id"`
	Name        string `json:"name" structs:"name"`
	Description string `json:"description" structs:"description"`
}

// Project represents a JIRA Project.
type Project struct {
	Expand       string             `json:"expand,omitempty" structs:"expand,omitempty"`
	Self         string             `json:"self,omitempty" structs:"self,omitempty"`
	ID           string             `json:"id,omitempty" structs:"id,omitempty"`
	Key          string             `json:"key,omitempty" structs:"key,omitempty"`
	Description  string             `json:"description,omitempty" structs:"description,omitempty"`
	Lead         User               `json:"lead,omitempty" structs:"lead,omitempty"`
	Components   []ProjectComponent `json:"components,omitempty" structs:"components,omitempty"`
	IssueTypes   []IssueType        `json:"issueTypes,omitempty" structs:"issueTypes,omitempty"`
	URL          string             `json:"url,omitempty" structs:"url,omitempty"`
	Email        string             `json:"email,omitempty" structs:"email,omitempty"`
	AssigneeType string             `json:"assigneeType,omitempty" structs:"assigneeType,omitempty"`
	Versions     []Version          `json:"versions,omitempty" structs:"versions,omitempty"`
	Name         string             `json:"name,omitempty" structs:"name,omitempty"`
	Roles        struct {
		Developers string `json:"Developers,omitempty" structs:"Developers,omitempty"`
	} `json:"roles,omitempty" structs:"roles,omitempty"`
	AvatarUrls      AvatarUrls      `json:"avatarUrls,omitempty" structs:"avatarUrls,omitempty"`
	ProjectCategory ProjectCategory `json:"projectCategory,omitempty" structs:"projectCategory,omitempty"`
}

// Version represents a single release version of a project
type Version struct {
	Self            string `json:"self" structs:"self"`
	ID              string `json:"id" structs:"id"`
	Name            string `json:"name" structs:"name"`
	Archived        bool   `json:"archived" structs:"archived"`
	Released        bool   `json:"released" structs:"released"`
	ReleaseDate     string `json:"releaseDate" structs:"releaseDate"`
	UserReleaseDate string `json:"userReleaseDate" structs:"userReleaseDate"`
	ProjectID       int    `json:"projectId" structs:"projectId"` // Unlike other IDs, this is returned as a number
}

// ProjectComponent represents a single component of a project
type ProjectComponent struct {
	Self                string `json:"self" structs:"self"`
	ID                  string `json:"id" structs:"id"`
	Name                string `json:"name" structs:"name"`
	Description         string `json:"description" structs:"description"`
	Lead                User   `json:"lead" structs:"lead"`
	AssigneeType        string `json:"assigneeType" structs:"assigneeType"`
	Assignee            User   `json:"assignee" structs:"assignee"`
	RealAssigneeType    string `json:"realAssigneeType" structs:"realAssigneeType"`
	RealAssignee        User   `json:"realAssignee" structs:"realAssignee"`
	IsAssigneeTypeValid bool   `json:"isAssigneeTypeValid" structs:"isAssigneeTypeValid"`
	Project             string `json:"project" structs:"project"`
	ProjectID           int    `json:"projectId" structs:"projectId"`
}

// GetList gets all projects form JIRA
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getAllProjects
func (s *ProjectService) GetList() (*ProjectList, *Response, error) {
	apiEndpoint := "rest/api/2/project"
	req, err := s.client.NewRequest("GET", apiEndpoint, nil)
	if err != nil {
		return nil, nil, err
	}

	projectList := new(ProjectList)
	resp, err := s.client.Do(req, projectList)
	if err != nil {
		return nil, resp, err
	}
	return projectList, resp, nil
}

// Get returns a full representation of the project for the given issue key.
// JIRA will attempt to identify the project by the projectIdOrKey path parameter.
// This can be an project id, or an project key.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getProject
func (s *ProjectService) Get(projectID string) (*Project, *Response, error) {
	apiEndpoint := fmt.Sprintf("/rest/api/2/project/%s", projectID)
	req, err := s.client.NewRequest("GET", apiEndpoint, nil)
	if err != nil {
		return nil, nil, err
	}

	project := new(Project)
	resp, err := s.client.Do(req, project)
	if err != nil {
		return nil, resp, err
	}
	return project, resp, nil
}
<commit_msg>Omit more empty attributes when converting from struct to map<commit_after>package jira

import (
	"fmt"
)

// ProjectService handles projects for the JIRA instance / API.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project
type ProjectService struct {
	client *Client
}

// ProjectList represent a list of Projects
type ProjectList []struct {
	Expand          string          `json:"expand" structs:"expand"`
	Self            string          `json:"self" structs:"self"`
	ID              string          `json:"id" structs:"id"`
	Key             string          `json:"key" structs:"key"`
	Name            string          `json:"name" structs:"name"`
	AvatarUrls      AvatarUrls      `json:"avatarUrls" structs:"avatarUrls"`
	ProjectTypeKey  string          `json:"projectTypeKey" structs:"projectTypeKey"`
	ProjectCategory ProjectCategory `json:"projectCategory,omitempty" structs:"projectsCategory,omitempty"`
}

// ProjectCategory represents a single project category
type ProjectCategory struct {
	Self        string `json:"self" structs:"self,omitempty"`
	ID          string `json:"id" structs:"id,omitempty"`
	Name        string `json:"name" structs:"name,omitempty"`
	Description string `json:"description" structs:"description,omitempty"`
}

// Project represents a JIRA Project.
type Project struct {
	Expand       string             `json:"expand,omitempty" structs:"expand,omitempty"`
	Self         string             `json:"self,omitempty" structs:"self,omitempty"`
	ID           string             `json:"id,omitempty" structs:"id,omitempty"`
	Key          string             `json:"key,omitempty" structs:"key,omitempty"`
	Description  string             `json:"description,omitempty" structs:"description,omitempty"`
	Lead         User               `json:"lead,omitempty" structs:"lead,omitempty"`
	Components   []ProjectComponent `json:"components,omitempty" structs:"components,omitempty"`
	IssueTypes   []IssueType        `json:"issueTypes,omitempty" structs:"issueTypes,omitempty"`
	URL          string             `json:"url,omitempty" structs:"url,omitempty"`
	Email        string             `json:"email,omitempty" structs:"email,omitempty"`
	AssigneeType string             `json:"assigneeType,omitempty" structs:"assigneeType,omitempty"`
	Versions     []Version          `json:"versions,omitempty" structs:"versions,omitempty"`
	Name         string             `json:"name,omitempty" structs:"name,omitempty"`
	Roles        struct {
		Developers string `json:"Developers,omitempty" structs:"Developers,omitempty"`
	} `json:"roles,omitempty" structs:"roles,omitempty"`
	AvatarUrls      AvatarUrls      `json:"avatarUrls,omitempty" structs:"avatarUrls,omitempty"`
	ProjectCategory ProjectCategory `json:"projectCategory,omitempty" structs:"projectCategory,omitempty"`
}

// Version represents a single release version of a project
type Version struct {
	Self            string `json:"self" structs:"self,omitempty"`
	ID              string `json:"id" structs:"id,omitempty"`
	Name            string `json:"name" structs:"name,omitempty"`
	Archived        bool   `json:"archived" structs:"archived,omitempty"`
	Released        bool   `json:"released" structs:"released,omitempty"`
	ReleaseDate     string `json:"releaseDate" structs:"releaseDate,omitempty"`
	UserReleaseDate string `json:"userReleaseDate" structs:"userReleaseDate,omitempty"`
	ProjectID       int    `json:"projectId" structs:"projectId,omitempty"` // Unlike other IDs, this is returned as a number
}

// ProjectComponent represents a single component of a project
type ProjectComponent struct {
	Self                string `json:"self" structs:"self,omitempty"`
	ID                  string `json:"id" structs:"id,omitempty"`
	Name                string `json:"name" structs:"name,omitempty"`
	Description         string `json:"description" structs:"description,omitempty"`
	Lead                User   `json:"lead,omitempty" structs:"lead,omitempty"`
	AssigneeType        string `json:"assigneeType" structs:"assigneeType,omitempty"`
	Assignee            User   `json:"assignee" structs:"assignee,omitempty"`
	RealAssigneeType    string `json:"realAssigneeType" structs:"realAssigneeType,omitempty"`
	RealAssignee        User   `json:"realAssignee" structs:"realAssignee,omitempty"`
	IsAssigneeTypeValid bool   `json:"isAssigneeTypeValid" structs:"isAssigneeTypeValid,omitempty"`
	Project             string `json:"project" structs:"project,omitempty"`
	ProjectID           int    `json:"projectId" structs:"projectId,omitempty"`
}

// GetList gets all projects form JIRA
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getAllProjects
func (s *ProjectService) GetList() (*ProjectList, *Response, error) {
	apiEndpoint := "rest/api/2/project"
	req, err := s.client.NewRequest("GET", apiEndpoint, nil)
	if err != nil {
		return nil, nil, err
	}

	projectList := new(ProjectList)
	resp, err := s.client.Do(req, projectList)
	if err != nil {
		return nil, resp, err
	}
	return projectList, resp, nil
}

// Get returns a full representation of the project for the given issue key.
// JIRA will attempt to identify the project by the projectIdOrKey path parameter.
// This can be an project id, or an project key.
//
// JIRA API docs: https://docs.atlassian.com/jira/REST/latest/#api/2/project-getProject
func (s *ProjectService) Get(projectID string) (*Project, *Response, error) {
	apiEndpoint := fmt.Sprintf("/rest/api/2/project/%s", projectID)
	req, err := s.client.NewRequest("GET", apiEndpoint, nil)
	if err != nil {
		return nil, nil, err
	}

	project := new(Project)
	resp, err := s.client.Do(req, project)
	if err != nil {
		return nil, resp, err
	}
	return project, resp, nil
}
<|endoftext|>


<commit_before>// Copyright 2011, Bryan Matsuo. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
/*
*  File: project.go
*  Author: Bryan Matsuo [bmatsuo@soe.ucsc.edu]
*  Created: Sat Jul  2 20:28:54 PDT 2011
 */
import (
    "os"
    "fmt"
    "log"
    "time"
)

var (
    NoUserNameError        = os.NewError("Missing remote repository username.")
    NoRemoteError          = os.NewError("Missing remote repository url")
    DirPermissions  uint32 = 0755
    FilePermissions uint32 = 0644
)

type ProjectType int

const (
    NilProjectType ProjectType = iota
    CmdType
    PkgType
    //LibType
    //MainType
)

func (ptype ProjectType) String() string {
    switch ptype {
    case CmdType:
        return "cmd"
    case PkgType:
        return "pkg"
    }
    return ""
}

func DefaultTarget(pname string) string {
    // TODO strip special characters from the prjoect name.
    return pname
}

type Project struct {
    Name    string
    Target  string
    User    string
    Remote  string
    License LicenseType
    Type    ProjectType
    Host    RepoHost
    Repo    RepoType
}

func (p Project) Create() os.Error {
    var dict = p.GenerateDictionary()

    // Make the directory and change the working directory.
    if DEBUG || VERBOSE {
        fmt.Print("Creating project directory.\n")
    }

    var err os.Error
    if err = os.Mkdir(p.Name, DirPermissions); err != nil {
        return err
    }

    if DEBUG || VERBOSE {
        fmt.Print("Entering project directory.\n")
    }

    if err = os.Chdir(p.Name); err != nil {
        return err
    }
    if err = p.CreateFiles(dict); err != nil {
        return err
    }
    if userepo {
        if err = p.InitializeRepo(true, true, true); err != nil {
            return err
        }
    }

    if DEBUG || VERBOSE {
        fmt.Print("Leaving project directory.\n")
    }

    return os.Chdir("..")
}
func (p Project) CreateFiles(dict map[string]string) os.Error {
    var err os.Error
    if err = p.CreateMakefile(dict); err != nil {
        return err
    }
    if err = p.CreateMainFile(dict); err != nil {
        return err
    }
    if err = p.CreateOptionsFile(dict); err != nil {
        return err
    }
    if err = p.CreateDocFile(dict); err != nil {
        return err
    }
    if err = p.CreateTestFile(dict); err != nil {
        return err
    }
    if err = p.CreateReadme(dict); err != nil {
        return err
    }
    if err = p.CreateOtherFiles(dict); err != nil {
        return err
    }
    if err = p.CreateLicense(dict); err != nil {
        return err
    }
    return nil
}

func (p Project) GenerateDictionary() map[string]string {
    var td = make(map[string]string, 9)
    td["project"] = p.Name
    td["name"] = AppConfig.Name
    td["email"] = AppConfig.Email
    td["gotarget"] = p.Target
    td["main"] = p.MainFilename()
    td["type"] = p.Type.String()
    td["repo"] = p.HostRepoString()
    td["year"] = YearString()
    td["date"] = DateString()
    return td
}

func (p Project) CreateMakefile(dict map[string]string) os.Error {
    var (
        templatePath = p.MakefileTemplatePath()
        errWrite     = WriteTemplate("Makefile", "makefile", dict, templatePath...)
    )
    return errWrite
}
func (p Project) CreateMainFile(dict map[string]string) os.Error {
    var (
        mainfile      = p.MainFilename()
        ltemplateName = p.GofileLicenseHeadTemplateName()
        templatePath  = p.MainTemplatePath()
    )
    if ltemplateName == "" {
        if DEBUG {
            log.Print("No license template found for %s", p.License.String())
        }
        return WriteTemplate(mainfile, "main file", dict, templatePath...)
    }
    var ltemplatePath = []string{"licenses", ltemplateName}
    errWrite := WriteTemplate(mainfile, "main file license", dict, ltemplatePath...)
    if errWrite != nil {
        return errWrite
    }
    return AppendTemplate(mainfile, "main file contents", dict, templatePath...)
}
func (p Project) CreateTestFile(dict map[string]string) os.Error {
    if !AppConfig.MakeTest {
        if DEBUG || VERBOSE {
            fmt.Printf("Skipping test file generation.")
        }
        return nil
    }
    var (
        testfile      = p.TestFilename()
        ltemplateName = p.GofileLicenseHeadTemplateName()
        templatePath  = p.TestTemplatePath()
    )
    if ltemplateName == "" {
        if DEBUG {
            log.Print("No license template found for %s", p.License.String())
        }
        return WriteTemplate(testfile, "test file", dict, templatePath...)
    }
    var ltemplatePath = []string{"licenses", ltemplateName}
    errWrite := WriteTemplate(testfile, "test file license", dict, ltemplatePath...)
    if errWrite != nil {
        return errWrite
    }
    return AppendTemplate(testfile, "test file contents", dict, templatePath...)
}
func (p Project) CreateReadme(dict map[string]string) os.Error {
    var (
        templatePath = p.ReadmeTemplatePath()
        readme       = p.ReadmeFilename()
    )
    errWrite := WriteTemplate(readme, "README", dict, templatePath...)
    if errWrite != nil {
        return errWrite
    }
    if p.License == NilLicenseType {
        return nil
    }
    ltemplatePath := []string{"licenses", p.ReadmeLicenseTailTemplateName()}
    return AppendTemplate(readme, "README license tail", dict, ltemplatePath...)
}
func (p Project) CreateLicense(dict map[string]string) os.Error {
    var (
        templatePath = []string{"licenses", p.LicenseTemplateName()}
        license      = "LICENSE"
    )
    return WriteTemplate(license, "license", dict, templatePath...)
}
func (p Project) CreateOptionsFile(dict map[string]string) os.Error {
    if p.Type == PkgType {
        return nil
    }
    var (
        doc          = "options.go"
        templatePath = p.OptionsTemplatePath()
    )
    return WriteTemplate(doc, "option parsing file", dict, templatePath...)
}
func (p Project) CreateDocFile(dict map[string]string) os.Error {
    if p.Type == PkgType {
        return nil
    }
    var (
        doc          = "doc.go"
        templatePath = p.DocTemplatePath()
    )
    return WriteTemplate(doc, "documentation file", dict, templatePath...)
}
func (p Project) CreateOtherFiles(dict map[string]string) os.Error {
    templatePaths := p.OtherTemplatePaths()
    if templatePaths == nil {
        return nil
    }
    for _, path := range templatePaths {
        errWrite := WriteTemplate(path[0], "other file", dict, path[1:]...)
        if errWrite != nil {
            return errWrite
        }
    }
    return nil
}
func (p Project) InitializeRepo(add, commit, push bool) os.Error {
    switch p.Repo {
    case GitType:
        git := GitRepo{}
        git.Initialize(add, commit)
    case HgType:
        hg := HgRepo{}
        hg.Initialize(add, commit)
    }
    switch p.Host {
    case GitHubHost:
        origin := p.Remote
        if origin == "" {
            return nil
        }
        github := GitHubRepo{p}
        if err := github.Init(origin); err != nil {
            return err
        }
        if push {
            if err := github.Push(); err != nil {
                return err
            }
        }
        return nil
    }
    return nil
}

func (p Project) MainFilename() string {
    return p.Target + ".go"
}
func (p Project) TestFilename() string {
    switch p.Type {
    case CmdType:
        return "main_test.go"
    case PkgType:
        return p.Target + "_test.go"
    }
    return p.Target + "_test.go"
}
func (p Project) ReadmeFilename() string {
    if p.ReadmeIsMarkdown() {
        return "README.md"
    }
    return "README"
}

func (p Project) LicenseTemplateName() string {
    lstring := p.License.TemplateNamePrefix()
    if lstring == "" {
        return ""
    }
    return lstring + ".t"
}
func (p Project) GofileLicenseHeadTemplateName() string {
    lstring := p.License.TemplateNamePrefix()
    if lstring == "" {
        return ""
    }
    return lstring + ".gohead.t"
}
func (p Project) ReadmeLicenseTailTemplateName() string {
    lstring := p.License.TemplateNamePrefix()
    if lstring == "" {
        return ""
    }
    if p.ReadmeIsMarkdown() {
        return lstring + ".readme.md.t"
    }
    return lstring + ".readme.t"
}
func (p Project) MainTemplateName() string {
    switch p.Type {
    case PkgType:
        return "pkg.t"
    case CmdType:
        return "cmd.t"
    }
    return ""
}
func (p Project) TestTemplateName() string {
    switch p.Type {
    case PkgType:
        return "pkg.t"
    case CmdType:
        return "cmd.t"
    }
    return ""
}
func (p Project) ReadmeTemplateName() string {
    switch p.Type {
    case PkgType:
        if p.ReadmeIsMarkdown() {
            return "pkg.md.t"
        } else {
            return "pkg.t"
        }
    case CmdType:
        if p.ReadmeIsMarkdown() {
            return "cmd.md.t"
        } else {
            return "cmd.t"
        }
    }
    return ""
}

func (p Project) MakefileTemplatePath() []string {
    return []string{"makefiles", p.Type.String() + ".t"}
}
func (p Project) MainTemplatePath() []string {
    return []string{"gofiles", p.MainTemplateName()}
}
func (p Project) TestTemplatePath() []string {
    return []string{"testfiles", p.TestTemplateName()}
}
func (p Project) ReadmeTemplatePath() []string {
    return []string{"README", p.ReadmeTemplateName()}
}
func (p Project) OptionsTemplatePath() []string {
    return []string{"gofiles", "options.t"}
}
func (p Project) DocTemplatePath() []string {
    return []string{"gofiles", "doc.t"}
}
func (p Project) OtherTemplatePaths() [][]string {
    var others = make([][]string, 0, 1)
    switch p.Repo {
    case GitType:
        others = append(others, []string{".gitignore", "otherfiles", "gitignore.t"})
    case HgType:
        others = append(others, []string{".hgignore", "otherfiles", "hgignore.t"})
    }
    if len(others) == 0 {
        return nil
    }
    return others
}

func (p Project) HostString() string {
    switch p.Host {
    case GitHubHost:
        if p.User == "" {
            return ""
        }
        return "github.com/" + p.User
    }
    return "<INSERT REPO HOST HERE>"
}
func (p Project) HostRepoString() string {
    switch p.Host {
    case GitHubHost:
        if p.User == "" {
            return ""
        }
        return "github.com/" + p.User + "/" + p.Target
    }
    return "<INSERT REPO HOST HERE>"
}
func YearString() string {
    return time.LocalTime().Format("2006")
}
func DateString() string {
    return time.LocalTime().String()
}
func (p Project) ReadmeIsMarkdown() bool {
    return userepo && p.Host == GitHubHost
}
<commit_msg>Fix crash when no license type is defined.<commit_after>// Copyright 2011, Bryan Matsuo. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package main
/*
*  File: project.go
*  Author: Bryan Matsuo [bmatsuo@soe.ucsc.edu]
*  Created: Sat Jul  2 20:28:54 PDT 2011
 */
import (
    "os"
    "fmt"
    "log"
    "time"
)

var (
    NoUserNameError        = os.NewError("Missing remote repository username.")
    NoRemoteError          = os.NewError("Missing remote repository url")
    DirPermissions  uint32 = 0755
    FilePermissions uint32 = 0644
)

type ProjectType int

const (
    NilProjectType ProjectType = iota
    CmdType
    PkgType
    //LibType
    //MainType
)

func (ptype ProjectType) String() string {
    switch ptype {
    case CmdType:
        return "cmd"
    case PkgType:
        return "pkg"
    }
    return ""
}

func DefaultTarget(pname string) string {
    // TODO strip special characters from the prjoect name.
    return pname
}

type Project struct {
    Name    string
    Target  string
    User    string
    Remote  string
    License LicenseType
    Type    ProjectType
    Host    RepoHost
    Repo    RepoType
}

func (p Project) Create() os.Error {
    var dict = p.GenerateDictionary()

    // Make the directory and change the working directory.
    if DEBUG || VERBOSE {
        fmt.Print("Creating project directory.\n")
    }

    var err os.Error
    if err = os.Mkdir(p.Name, DirPermissions); err != nil {
        return err
    }

    if DEBUG || VERBOSE {
        fmt.Print("Entering project directory.\n")
    }

    if err = os.Chdir(p.Name); err != nil {
        return err
    }
    if err = p.CreateFiles(dict); err != nil {
        return err
    }
    if userepo {
        if err = p.InitializeRepo(true, true, true); err != nil {
            return err
        }
    }

    if DEBUG || VERBOSE {
        fmt.Print("Leaving project directory.\n")
    }

    return os.Chdir("..")
}
func (p Project) CreateFiles(dict map[string]string) os.Error {
    var err os.Error
    if err = p.CreateMakefile(dict); err != nil {
        return err
    }
    if err = p.CreateMainFile(dict); err != nil {
        return err
    }
    if err = p.CreateOptionsFile(dict); err != nil {
        return err
    }
    if err = p.CreateDocFile(dict); err != nil {
        return err
    }
    if err = p.CreateTestFile(dict); err != nil {
        return err
    }
    if err = p.CreateReadme(dict); err != nil {
        return err
    }
    if err = p.CreateOtherFiles(dict); err != nil {
        return err
    }
    if err = p.CreateLicense(dict); err != nil {
        return err
    }
    return nil
}

func (p Project) GenerateDictionary() map[string]string {
    var td = make(map[string]string, 9)
    td["project"] = p.Name
    td["name"] = AppConfig.Name
    td["email"] = AppConfig.Email
    td["gotarget"] = p.Target
    td["main"] = p.MainFilename()
    td["type"] = p.Type.String()
    td["repo"] = p.HostRepoString()
    td["year"] = YearString()
    td["date"] = DateString()
    return td
}

func (p Project) CreateMakefile(dict map[string]string) os.Error {
    var (
        templatePath = p.MakefileTemplatePath()
        errWrite     = WriteTemplate("Makefile", "makefile", dict, templatePath...)
    )
    return errWrite
}
func (p Project) CreateMainFile(dict map[string]string) os.Error {
    var (
        mainfile      = p.MainFilename()
        ltemplateName = p.GofileLicenseHeadTemplateName()
        templatePath  = p.MainTemplatePath()
    )
    if ltemplateName == "" {
        if DEBUG {
            log.Print("No license template found for %s", p.License.String())
        }
        return WriteTemplate(mainfile, "main file", dict, templatePath...)
    }
    var ltemplatePath = []string{"licenses", ltemplateName}
    errWrite := WriteTemplate(mainfile, "main file license", dict, ltemplatePath...)
    if errWrite != nil {
        return errWrite
    }
    return AppendTemplate(mainfile, "main file contents", dict, templatePath...)
}
func (p Project) CreateTestFile(dict map[string]string) os.Error {
    if !AppConfig.MakeTest {
        if DEBUG || VERBOSE {
            fmt.Printf("Skipping test file generation.")
        }
        return nil
    }
    var (
        testfile      = p.TestFilename()
        ltemplateName = p.GofileLicenseHeadTemplateName()
        templatePath  = p.TestTemplatePath()
    )
    if ltemplateName == "" {
        if DEBUG {
            log.Print("No license template found for %s", p.License.String())
        }
        return WriteTemplate(testfile, "test file", dict, templatePath...)
    }
    var ltemplatePath = []string{"licenses", ltemplateName}
    errWrite := WriteTemplate(testfile, "test file license", dict, ltemplatePath...)
    if errWrite != nil {
        return errWrite
    }
    return AppendTemplate(testfile, "test file contents", dict, templatePath...)
}
func (p Project) CreateReadme(dict map[string]string) os.Error {
    var (
        templatePath = p.ReadmeTemplatePath()
        readme       = p.ReadmeFilename()
    )
    errWrite := WriteTemplate(readme, "README", dict, templatePath...)
    if errWrite != nil {
        return errWrite
    }
    if p.License == NilLicenseType {
        return nil
    }
    ltemplatePath := []string{"licenses", p.ReadmeLicenseTailTemplateName()}
    return AppendTemplate(readme, "README license tail", dict, ltemplatePath...)
}
func (p Project) CreateLicense(dict map[string]string) os.Error {
    if p.License == NilLicenseType {
        return nil
    }
    var (
        templatePath = []string{"licenses", p.LicenseTemplateName()}
        license      = "LICENSE"
    )
    return WriteTemplate(license, "license", dict, templatePath...)
}
func (p Project) CreateOptionsFile(dict map[string]string) os.Error {
    if p.Type == PkgType {
        return nil
    }
    var (
        doc          = "options.go"
        templatePath = p.OptionsTemplatePath()
    )
    return WriteTemplate(doc, "option parsing file", dict, templatePath...)
}
func (p Project) CreateDocFile(dict map[string]string) os.Error {
    if p.Type == PkgType {
        return nil
    }
    var (
        doc          = "doc.go"
        templatePath = p.DocTemplatePath()
    )
    return WriteTemplate(doc, "documentation file", dict, templatePath...)
}
func (p Project) CreateOtherFiles(dict map[string]string) os.Error {
    templatePaths := p.OtherTemplatePaths()
    if templatePaths == nil {
        return nil
    }
    for _, path := range templatePaths {
        errWrite := WriteTemplate(path[0], "other file", dict, path[1:]...)
        if errWrite != nil {
            return errWrite
        }
    }
    return nil
}
func (p Project) InitializeRepo(add, commit, push bool) os.Error {
    switch p.Repo {
    case GitType:
        git := GitRepo{}
        git.Initialize(add, commit)
    case HgType:
        hg := HgRepo{}
        hg.Initialize(add, commit)
    }
    switch p.Host {
    case GitHubHost:
        origin := p.Remote
        if origin == "" {
            return nil
        }
        github := GitHubRepo{p}
        if err := github.Init(origin); err != nil {
            return err
        }
        if push {
            if err := github.Push(); err != nil {
                return err
            }
        }
        return nil
    }
    return nil
}

func (p Project) MainFilename() string {
    return p.Target + ".go"
}
func (p Project) TestFilename() string {
    switch p.Type {
    case CmdType:
        return "main_test.go"
    case PkgType:
        return p.Target + "_test.go"
    }
    return p.Target + "_test.go"
}
func (p Project) ReadmeFilename() string {
    if p.ReadmeIsMarkdown() {
        return "README.md"
    }
    return "README"
}

func (p Project) LicenseTemplateName() string {
    lstring := p.License.TemplateNamePrefix()
    if lstring == "" {
        return ""
    }
    return lstring + ".t"
}
func (p Project) GofileLicenseHeadTemplateName() string {
    lstring := p.License.TemplateNamePrefix()
    if lstring == "" {
        return ""
    }
    return lstring + ".gohead.t"
}
func (p Project) ReadmeLicenseTailTemplateName() string {
    lstring := p.License.TemplateNamePrefix()
    if lstring == "" {
        return ""
    }
    if p.ReadmeIsMarkdown() {
        return lstring + ".readme.md.t"
    }
    return lstring + ".readme.t"
}
func (p Project) MainTemplateName() string {
    switch p.Type {
    case PkgType:
        return "pkg.t"
    case CmdType:
        return "cmd.t"
    }
    return ""
}
func (p Project) TestTemplateName() string {
    switch p.Type {
    case PkgType:
        return "pkg.t"
    case CmdType:
        return "cmd.t"
    }
    return ""
}
func (p Project) ReadmeTemplateName() string {
    switch p.Type {
    case PkgType:
        if p.ReadmeIsMarkdown() {
            return "pkg.md.t"
        } else {
            return "pkg.t"
        }
    case CmdType:
        if p.ReadmeIsMarkdown() {
            return "cmd.md.t"
        } else {
            return "cmd.t"
        }
    }
    return ""
}

func (p Project) MakefileTemplatePath() []string {
    return []string{"makefiles", p.Type.String() + ".t"}
}
func (p Project) MainTemplatePath() []string {
    return []string{"gofiles", p.MainTemplateName()}
}
func (p Project) TestTemplatePath() []string {
    return []string{"testfiles", p.TestTemplateName()}
}
func (p Project) ReadmeTemplatePath() []string {
    return []string{"README", p.ReadmeTemplateName()}
}
func (p Project) OptionsTemplatePath() []string {
    return []string{"gofiles", "options.t"}
}
func (p Project) DocTemplatePath() []string {
    return []string{"gofiles", "doc.t"}
}
func (p Project) OtherTemplatePaths() [][]string {
    var others = make([][]string, 0, 1)
    switch p.Repo {
    case GitType:
        others = append(others, []string{".gitignore", "otherfiles", "gitignore.t"})
    case HgType:
        others = append(others, []string{".hgignore", "otherfiles", "hgignore.t"})
    }
    if len(others) == 0 {
        return nil
    }
    return others
}

func (p Project) HostString() string {
    switch p.Host {
    case GitHubHost:
        if p.User == "" {
            return ""
        }
        return "github.com/" + p.User
    }
    return "<INSERT REPO HOST HERE>"
}
func (p Project) HostRepoString() string {
    switch p.Host {
    case GitHubHost:
        if p.User == "" {
            return ""
        }
        return "github.com/" + p.User + "/" + p.Target
    }
    return "<INSERT REPO HOST HERE>"
}
func YearString() string {
    return time.LocalTime().Format("2006")
}
func DateString() string {
    return time.LocalTime().String()
}
func (p Project) ReadmeIsMarkdown() bool {
    return userepo && p.Host == GitHubHost
}
<|endoftext|>


<commit_before>package pt

import (
	"fmt"
	"math"
	"sort"
)

type Tree struct {
	box  Box
	root *Node
}

func NewTree(shapes []Shape) *Tree {
	fmt.Printf("Building k-d tree (%d shapes)... ", len(shapes))
	defer fmt.Println("OK")
	box := BoxForShapes(shapes)
	node := NewNode(shapes)
	node.Split(0)
	return &Tree{box, node}
}

func (tree *Tree) Intersect(r Ray) Hit {
	tmin, tmax := tree.box.Intersect(r)
	if tmax < tmin || tmax <= 0 {
		return NoHit
	}
	return tree.root.Intersect(r, tmin, tmax)
}

type Node struct {
	axis   Axis
	point  float64
	shapes []Shape
	left   *Node
	right  *Node
}

func NewNode(shapes []Shape) *Node {
	return &Node{AxisNone, 0, shapes, nil, nil}
}

func (node *Node) Intersect(r Ray, tmin, tmax float64) Hit {
	if node.axis == AxisNone {
		hit := NoHit
		for _, shape := range node.shapes {
			h := shape.Intersect(r)
			if h.T < hit.T {
				hit = h
			}
		}
		return hit
	}
	var tsplit float64
	var leftFirst bool
	switch node.axis {
	case AxisX:
		tsplit = (node.point - r.Origin.X) / r.Direction.X
		leftFirst = (r.Origin.X < node.point) || (r.Origin.X == node.point && r.Direction.X <= 0)
	case AxisY:
		tsplit = (node.point - r.Origin.Y) / r.Direction.Y
		leftFirst = (r.Origin.Y < node.point) || (r.Origin.Y == node.point && r.Direction.Y <= 0)
	case AxisZ:
		tsplit = (node.point - r.Origin.Z) / r.Direction.Z
		leftFirst = (r.Origin.Z < node.point) || (r.Origin.Z == node.point && r.Direction.Z <= 0)
	}
	var first, second *Node
	if leftFirst {
		first = node.left
		second = node.right
	} else {
		first = node.right
		second = node.left
	}
	if tsplit > tmax || tsplit <= 0 {
		return first.Intersect(r, tmin, tmax)
	} else if tsplit < tmin {
		return second.Intersect(r, tmin, tmax)
	} else {
		h1 := first.Intersect(r, tmin, tsplit)
		h2 := second.Intersect(r, tsplit, math.Min(tmax, h1.T))
		if h1.T <= h2.T {
			return h1
		} else {
			return h2
		}
	}
}

func (node *Node) PartitionScore(axis Axis, point float64) int {
	left, right := 0, 0
	for _, shape := range node.shapes {
		box := shape.Box()
		l, r := box.Partition(axis, point)
		if l {
			left++
		}
		if r {
			right++
		}
	}
	if left >= right {
		return left
	} else {
		return right
	}
}

func (node *Node) Partition(size int, axis Axis, point float64) (left, right []Shape) {
	left = make([]Shape, 0, size)
	right = make([]Shape, 0, size)
	for _, shape := range node.shapes {
		box := shape.Box()
		l, r := box.Partition(axis, point)
		if l {
			left = append(left, shape)
		}
		if r {
			right = append(right, shape)
		}
	}
	return
}

func (node *Node) Split(depth int) {
	if len(node.shapes) < 10 {
		return
	}
	xs := make([]float64, 0, len(node.shapes)*2)
	ys := make([]float64, 0, len(node.shapes)*2)
	zs := make([]float64, 0, len(node.shapes)*2)
	for _, shape := range node.shapes {
		box := shape.Box()
		xs = append(xs, box.Min.X)
		xs = append(xs, box.Max.X)
		ys = append(ys, box.Min.Y)
		ys = append(ys, box.Max.Y)
		zs = append(zs, box.Min.Z)
		zs = append(zs, box.Max.Z)
	}
	sort.Float64s(xs)
	sort.Float64s(ys)
	sort.Float64s(zs)
	mx, my, mz := Median(xs), Median(ys), Median(zs)
	best := len(node.shapes)
	bestAxis := AxisNone
	bestPoint := 0.0
	sx := node.PartitionScore(AxisX, mx)
	if sx < best {
		best = sx
		bestAxis = AxisX
		bestPoint = mx
	}
	sy := node.PartitionScore(AxisY, my)
	if sy < best {
		best = sy
		bestAxis = AxisY
		bestPoint = my
	}
	sz := node.PartitionScore(AxisZ, mz)
	if sz < best {
		best = sz
		bestAxis = AxisZ
		bestPoint = mz
	}
	if bestAxis == AxisNone {
		return
	}
	l, r := node.Partition(best, bestAxis, bestPoint)
	node.axis = bestAxis
	node.point = bestPoint
	node.left = NewNode(l)
	node.right = NewNode(r)
	node.left.Split(depth + 1)
	node.right.Split(depth + 1)
	node.shapes = nil // only needed at leaf nodes
}
<commit_msg>k-d tree improvement<commit_after>package pt

import (
	"fmt"
	"math"
	"sort"
)

type Tree struct {
	box  Box
	root *Node
}

func NewTree(shapes []Shape) *Tree {
	fmt.Printf("Building k-d tree (%d shapes)... ", len(shapes))
	defer fmt.Println("OK")
	box := BoxForShapes(shapes)
	node := NewNode(shapes)
	node.Split(0)
	return &Tree{box, node}
}

func (tree *Tree) Intersect(r Ray) Hit {
	tmin, tmax := tree.box.Intersect(r)
	if tmax < tmin || tmax <= 0 {
		return NoHit
	}
	return tree.root.Intersect(r, tmin, tmax)
}

type Node struct {
	axis   Axis
	point  float64
	shapes []Shape
	left   *Node
	right  *Node
}

func NewNode(shapes []Shape) *Node {
	return &Node{AxisNone, 0, shapes, nil, nil}
}

func (node *Node) Intersect(r Ray, tmin, tmax float64) Hit {
	if node.axis == AxisNone {
		hit := NoHit
		for _, shape := range node.shapes {
			h := shape.Intersect(r)
			if h.T < hit.T {
				hit = h
			}
		}
		return hit
	}
	var tsplit float64
	var leftFirst bool
	switch node.axis {
	case AxisX:
		tsplit = (node.point - r.Origin.X) / r.Direction.X
		leftFirst = (r.Origin.X < node.point) || (r.Origin.X == node.point && r.Direction.X <= 0)
	case AxisY:
		tsplit = (node.point - r.Origin.Y) / r.Direction.Y
		leftFirst = (r.Origin.Y < node.point) || (r.Origin.Y == node.point && r.Direction.Y <= 0)
	case AxisZ:
		tsplit = (node.point - r.Origin.Z) / r.Direction.Z
		leftFirst = (r.Origin.Z < node.point) || (r.Origin.Z == node.point && r.Direction.Z <= 0)
	}
	var first, second *Node
	if leftFirst {
		first = node.left
		second = node.right
	} else {
		first = node.right
		second = node.left
	}
	if tsplit > tmax || tsplit <= 0 {
		return first.Intersect(r, tmin, tmax)
	} else if tsplit < tmin {
		return second.Intersect(r, tmin, tmax)
	} else {
		h1 := first.Intersect(r, tmin, tsplit)
		h2 := second.Intersect(r, tsplit, math.Min(tmax, h1.T))
		if h1.T <= h2.T {
			return h1
		} else {
			return h2
		}
	}
}

func (node *Node) PartitionScore(axis Axis, point float64) int {
	left, right := 0, 0
	for _, shape := range node.shapes {
		box := shape.Box()
		l, r := box.Partition(axis, point)
		if l {
			left++
		}
		if r {
			right++
		}
	}
	if left >= right {
		return left
	} else {
		return right
	}
}

func (node *Node) Partition(size int, axis Axis, point float64) (left, right []Shape) {
	left = make([]Shape, 0, size)
	right = make([]Shape, 0, size)
	for _, shape := range node.shapes {
		box := shape.Box()
		l, r := box.Partition(axis, point)
		if l {
			left = append(left, shape)
		}
		if r {
			right = append(right, shape)
		}
	}
	return
}

func (node *Node) Split(depth int) {
	if len(node.shapes) < 10 {
		return
	}
	xs := make([]float64, 0, len(node.shapes)*2)
	ys := make([]float64, 0, len(node.shapes)*2)
	zs := make([]float64, 0, len(node.shapes)*2)
	for _, shape := range node.shapes {
		box := shape.Box()
		xs = append(xs, box.Min.X)
		xs = append(xs, box.Max.X)
		ys = append(ys, box.Min.Y)
		ys = append(ys, box.Max.Y)
		zs = append(zs, box.Min.Z)
		zs = append(zs, box.Max.Z)
	}
	sort.Float64s(xs)
	sort.Float64s(ys)
	sort.Float64s(zs)
	mx, my, mz := Median(xs), Median(ys), Median(zs)
	best := int(float64(len(node.shapes)) * 0.8)
	bestAxis := AxisNone
	bestPoint := 0.0
	sx := node.PartitionScore(AxisX, mx)
	if sx < best {
		best = sx
		bestAxis = AxisX
		bestPoint = mx
	}
	sy := node.PartitionScore(AxisY, my)
	if sy < best {
		best = sy
		bestAxis = AxisY
		bestPoint = my
	}
	sz := node.PartitionScore(AxisZ, mz)
	if sz < best {
		best = sz
		bestAxis = AxisZ
		bestPoint = mz
	}
	if bestAxis == AxisNone {
		return
	}
	l, r := node.Partition(best, bestAxis, bestPoint)
	node.axis = bestAxis
	node.point = bestPoint
	node.left = NewNode(l)
	node.right = NewNode(r)
	node.left.Split(depth + 1)
	node.right.Split(depth + 1)
	node.shapes = nil // only needed at leaf nodes
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"strconv"

	"github.com/eyetoe/foobarbaz/affects"
	"github.com/eyetoe/foobarbaz/agents"
	"github.com/eyetoe/foobarbaz/inv"
)

func main() {
	Char := agents.Agent{}
	Char.Load("Izro")
	Char.StatusBar()
	Char.Describe()

	Foe := agents.Minotaur

	// Take first arg as hit point adjust
	//[1:] is the slice from 2nd argument (skipping prog name)
	//[0] is the first element in the array that is returned
	arg1, err := strconv.Atoi(os.Args[1:][0])
	if err != nil {
		Usage()
		fmt.Printf("%q\n", err)
	} else {
		Char.AdjHp(arg1)
	}

	// create Agent struct
	Char.Armor = "Tshirt"

	//Char.adjhp(5)

	Char.Save("Izro")
	Char.StatusBar()

	fmt.Println(affects.OnFire)
	fmt.Println(inv.Staff)
	fmt.Println("Foe is:\n", Foe)

	Foe.StatusBar()
	Foe.Save("Minotaur")
	Foe.Describe()

	fmt.Printf("You roll the dice: %d\n", Roll())
	fmt.Printf("You roll the dice: %d\n", Roll())
	fmt.Printf("You roll the dice: %d\n", Roll())
	fmt.Printf("You roll the dice: %d\n", Roll())
	fmt.Printf("You roll the dice: %d\n", Roll())
	fmt.Printf("You roll the dice: %d\n", Roll())
	fmt.Printf("You roll the dice: %d\n", Roll())
	fmt.Printf("You roll the dice: %d\n", Roll())

	// working on flow for a wrapper function to display combat dialog
	atk := &Char
	def := &Foe

	fmt.Printf("%s attacks %s with %s.\n", atk.Name, def.Name, atk.Weap)
	winner, loser := Attack(&Char, &Foe)
	fmt.Printf("%s has prevailed!\n", winner.Name)
	fmt.Printf("Alas %s has fallen short!\n", loser.Name)
	//

	return
}

func Usage() {
	fmt.Println("Usage: fbb (int hp adjust)")
}
<commit_msg>tweak wording<commit_after>package main

import (
	"fmt"
	"os"
	"strconv"

	"github.com/eyetoe/foobarbaz/affects"
	"github.com/eyetoe/foobarbaz/agents"
	"github.com/eyetoe/foobarbaz/inv"
)

func main() {
	Char := agents.Agent{}
	Char.Load("Izro")
	Char.StatusBar()
	Char.Describe()

	Foe := agents.Minotaur

	// Take first arg as hit point adjust
	//[1:] is the slice from 2nd argument (skipping prog name)
	//[0] is the first element in the array that is returned
	arg1, err := strconv.Atoi(os.Args[1:][0])
	if err != nil {
		Usage()
		fmt.Printf("%q\n", err)
	} else {
		Char.AdjHp(arg1)
	}

	// create Agent struct
	Char.Armor = "Tshirt"

	//Char.adjhp(5)

	Char.Save("Izro")
	Char.StatusBar()

	fmt.Println(affects.OnFire)
	fmt.Println(inv.Staff)
	fmt.Println("Foe is:\n", Foe)

	Foe.StatusBar()
	Foe.Save("Minotaur")
	Foe.Describe()

	fmt.Printf("You roll the dice: %d\n", Roll())
	fmt.Printf("You roll the dice: %d\n", Roll())
	fmt.Printf("You roll the dice: %d\n", Roll())
	fmt.Printf("You roll the dice: %d\n", Roll())
	fmt.Printf("You roll the dice: %d\n", Roll())
	fmt.Printf("You roll the dice: %d\n", Roll())
	fmt.Printf("You roll the dice: %d\n", Roll())
	fmt.Printf("You roll the dice: %d\n", Roll())

	// working on flow for a wrapper function to display combat dialog
	atk := &Char
	def := &Foe

	fmt.Printf("%s attacks %s with %s.\n", atk.Name, def.Name, atk.Weap)
	winner, loser := Attack(&Char, &Foe)
	fmt.Printf("%s has prevailed!\n", winner.Name)
	fmt.Printf("Alas, %s has fallen short!\n", loser.Name)
	//

	return
}

func Usage() {
	fmt.Println("Usage: fbb (int hp adjust)")
}
<|endoftext|>


<commit_before>package agree

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/hashicorp/raft"
	"io"
	"reflect"
	"time"
)

var (
	//ErrNotLeader is returned when a command is mistakenly sent to a follower. You should never receive this as Go-Agree takes care of following commands to the leader.
	ErrNotLeader = errors.New("Commands should be sent to leader and cannot be sent to followers")

	//ErrIncorrectType is returned when a Raft snapshot cannot be unmarshalled to the expected type.
	ErrIncorrectType = errors.New("Snapshot contained data of an incorrect type")
)

const raftTimeout = time.Second * 10

//ForwardingClient is a client that forwards commands to the Raft leader. Should not be used,
//the only reason it is exported is because the rpc package requires it.
type ForwardingClient struct {
	fsm *fsm
}

type fsm struct {
	fsmRPC  *ForwardingClient
	config  *Config
	raft    *raft.Raft
	wrapper *Wrapper
}

//command represents a mutating command (log entry) in the Raft commit log.
type command struct {
	Method string
	Args   []interface{}
}

type fsmSnapshot struct {
	store interface{}
}

//Apply forwards the given mutating command to the Raft leader.
func (r *ForwardingClient) Apply(cmd []byte, reply *struct{}) error {
	if r.fsm.raft.State() != raft.Leader {
		return ErrNotLeader
	}

	if errF := r.fsm.raft.Apply(cmd, raftTimeout); errF != nil {
		return errF.(error)
	}

	return nil
}

//AddPeer accepts a forwarded request to add a peer, sent to the Raft leader.
func (r *ForwardingClient) AddPeer(addr string, reply *struct{}) error {
	if r.fsm.raft.State() != raft.Leader {
		return ErrNotLeader
	}
	return r.fsm.wrapper.AddNode(addr)
}

//RemovePeer accepts a forwarded request to remove a peer, sent to the Raft leader.
func (r ForwardingClient) RemovePeer(addr string, reply *struct{}) error {
	if r.fsm.raft.State() != raft.Leader {
		return ErrNotLeader
	}
	return r.fsm.wrapper.RemoveNode(addr)
}

func (f *fsmSnapshot) Persist(sink raft.SnapshotSink) error {
	err := func() error {
		// Encode data.
		b, err := json.Marshal(f.store)
		if err != nil {
			return err
		}

		// Write data to sink.
		if _, err := sink.Write(b); err != nil {
			return err
		}

		// Close the sink.
		if err := sink.Close(); err != nil {
			return err
		}

		return nil
	}()

	if err != nil {
		sink.Cancel()
		return err
	}

	return nil
}

func (f *fsmSnapshot) Release() {}

func (f *fsm) Snapshot() (raft.FSMSnapshot, error) {

	data, err := f.wrapper.Marshal()

	if err != nil {
		return nil, err
	}

	return &fsmSnapshot{store: data}, nil

}

func (f *fsm) Restore(rc io.ReadCloser) error {
	var err error
	e := f.wrapper.reflectType.Elem()
	o := reflect.New(e).Interface()
	if err := json.NewDecoder(rc).Decode(&o); err != nil {
		return err
	}

	if !reflect.TypeOf(o).AssignableTo(f.wrapper.reflectType) {
		return ErrIncorrectType
	}

	// Set the state from the snapshot, no lock required according to
	// Hashicorp docs.
	f.wrapper.Lock()
	f.wrapper.value = o
	f.wrapper.Unlock()
	return err
}

func (f *fsm) Apply(l *raft.Log) interface{} {
	var (
		cmd   command
		m     reflect.Value
		found bool
	)
	if err := json.Unmarshal(l.Data, &cmd); err != nil {
		panic(fmt.Sprintf("Could not unmarshal command: %s", err.Error()))
	}

	t := f.wrapper
	if m, found = t.methods[cmd.Method]; !found {
		return ErrMethodNotFound
	}

	var callArgs []reflect.Value

	for i := range cmd.Args {
		callArgs = append(callArgs, reflect.ValueOf(cmd.Args[i]))
	}

	f.wrapper.Lock()
	defer f.wrapper.Unlock()
	ret := m.Call(callArgs)

	for _, callback := range f.wrapper.callbacks[cmd.Method] {
		callback(Mutation{
			NewValue:   f.wrapper.value,
			Method:     cmd.Method,
			MethodArgs: cmd.Args,
		})
	}

	for _, c := range f.wrapper.callbackChans[cmd.Method] {
		c <- &Mutation{
			NewValue:   f.wrapper.value,
			Method:     cmd.Method,
			MethodArgs: cmd.Args,
		}
	}

	switch {
	case len(ret) == 0:
		return nil
	case len(ret) > 1:
		panic("Applied methods should have at most one return parameter, and it should satisfy error interface")
	default:
		//one return param, which should satisfy error interface
		return ret[0].Interface().(error)
	}

}
<commit_msg>Fix incorrect type assertion.<commit_after>package agree

import (
	"encoding/json"
	"errors"
	"fmt"
	"github.com/hashicorp/raft"
	"io"
	"reflect"
	"time"
)

var (
	//ErrNotLeader is returned when a command is mistakenly sent to a follower. You should never receive this as Go-Agree takes care of following commands to the leader.
	ErrNotLeader = errors.New("Commands should be sent to leader and cannot be sent to followers")

	//ErrIncorrectType is returned when a Raft snapshot cannot be unmarshalled to the expected type.
	ErrIncorrectType = errors.New("Snapshot contained data of an incorrect type")
)

const raftTimeout = time.Second * 10

//ForwardingClient is a client that forwards commands to the Raft leader. Should not be used,
//the only reason it is exported is because the rpc package requires it.
type ForwardingClient struct {
	fsm *fsm
}

type fsm struct {
	fsmRPC  *ForwardingClient
	config  *Config
	raft    *raft.Raft
	wrapper *Wrapper
}

//command represents a mutating command (log entry) in the Raft commit log.
type command struct {
	Method string
	Args   []interface{}
}

type fsmSnapshot struct {
	store interface{}
}

//Apply forwards the given mutating command to the Raft leader.
func (r *ForwardingClient) Apply(cmd []byte, reply *struct{}) error {
	if r.fsm.raft.State() != raft.Leader {
		return ErrNotLeader
	}

	if errF := r.fsm.raft.Apply(cmd, raftTimeout); errF.Error() != nil {
		return errF.Error()
	}

	return nil
}

//AddPeer accepts a forwarded request to add a peer, sent to the Raft leader.
func (r *ForwardingClient) AddPeer(addr string, reply *struct{}) error {
	if r.fsm.raft.State() != raft.Leader {
		return ErrNotLeader
	}
	return r.fsm.wrapper.AddNode(addr)
}

//RemovePeer accepts a forwarded request to remove a peer, sent to the Raft leader.
func (r ForwardingClient) RemovePeer(addr string, reply *struct{}) error {
	if r.fsm.raft.State() != raft.Leader {
		return ErrNotLeader
	}
	return r.fsm.wrapper.RemoveNode(addr)
}

func (f *fsmSnapshot) Persist(sink raft.SnapshotSink) error {
	err := func() error {
		// Encode data.
		b, err := json.Marshal(f.store)
		if err != nil {
			return err
		}

		// Write data to sink.
		if _, err := sink.Write(b); err != nil {
			return err
		}

		// Close the sink.
		if err := sink.Close(); err != nil {
			return err
		}

		return nil
	}()

	if err != nil {
		sink.Cancel()
		return err
	}

	return nil
}

func (f *fsmSnapshot) Release() {}

func (f *fsm) Snapshot() (raft.FSMSnapshot, error) {

	data, err := f.wrapper.Marshal()

	if err != nil {
		return nil, err
	}

	return &fsmSnapshot{store: data}, nil

}

func (f *fsm) Restore(rc io.ReadCloser) error {
	var err error
	e := f.wrapper.reflectType.Elem()
	o := reflect.New(e).Interface()
	if err := json.NewDecoder(rc).Decode(&o); err != nil {
		return err
	}

	if !reflect.TypeOf(o).AssignableTo(f.wrapper.reflectType) {
		return ErrIncorrectType
	}

	// Set the state from the snapshot, no lock required according to
	// Hashicorp docs.
	f.wrapper.Lock()
	f.wrapper.value = o
	f.wrapper.Unlock()
	return err
}

func (f *fsm) Apply(l *raft.Log) interface{} {
	var (
		cmd   command
		m     reflect.Value
		found bool
	)
	if err := json.Unmarshal(l.Data, &cmd); err != nil {
		panic(fmt.Sprintf("Could not unmarshal command: %s", err.Error()))
	}

	t := f.wrapper
	if m, found = t.methods[cmd.Method]; !found {
		return ErrMethodNotFound
	}
	fmt.Println(cmd)

	var callArgs []reflect.Value

	for i := range cmd.Args {
		callArgs = append(callArgs, reflect.ValueOf(cmd.Args[i]))
	}

	f.wrapper.Lock()
	defer f.wrapper.Unlock()
	ret := m.Call(callArgs)

	for _, callback := range f.wrapper.callbacks[cmd.Method] {
		callback(Mutation{
			NewValue:   f.wrapper.value,
			Method:     cmd.Method,
			MethodArgs: cmd.Args,
		})
	}

	for _, c := range f.wrapper.callbackChans[cmd.Method] {
		c <- &Mutation{
			NewValue:   f.wrapper.value,
			Method:     cmd.Method,
			MethodArgs: cmd.Args,
		}
	}

	switch {
	case len(ret) == 0:
		return nil
	case len(ret) > 1:
		panic("Applied methods should have at most one return parameter, and it should satisfy error interface")
	default:
		//one return param, which should satisfy error interface
		return ret[0].Interface().(error)
	}

}
<|endoftext|>


<commit_before>package main

import (
	"github.com/gotk3/gotk3/gdk"
	"github.com/gotk3/gotk3/gtk"
	"log"
	"math/cmplx"
	"fmt"
	"math"
	"time"
	"sync"
	"runtime"
)

type ma struct {
	pb *gdk.Pixbuf

	maxx float64
	maxy float64

	minx float64
	miny float64

	sx float64
	sy float64

	iter int

	h int
	w int

	lastDuration time.Duration

	label struct {
		l, r, t, b, i, d *gtk.Label
	}
}

func newma() *ma {
	ma := &ma{}

	pb, err := gdk.PixbufNew(gdk.COLORSPACE_RGB, false, 8, 256, 256)
	if err != nil {
		log.Fatal("pixbuf: ", err)
	}

	ma.pb = pb
	ma.setCoords(-0.5, 0.0, 3.0)

	return ma
}

func (ma *ma)setCoords(cx float64, cy float64, zw float64) {
	ma.w = ma.pb.GetWidth()
	ma.h = ma.pb.GetHeight()

	ma.minx = cx - (zw / 2)
	ma.maxx = cx + (zw / 2)
	ma.miny = cy - ((ma.maxx - ma.minx) * float64(ma.h) / float64(ma.w) / 2)
	ma.maxy = cy + ((ma.maxx - ma.minx) * float64(ma.h) / float64(ma.w) / 2)

	ma.sx = (ma.maxx - ma.minx)/float64(ma.w - 1)
	ma.sy = (ma.maxy - ma.miny)/float64(ma.h - 1)

	// http://math.stackexchange.com/a/30560
	ma.iter = int(math.Sqrt(math.Abs(2.0 * math.Sqrt(math.Abs(1 - math.Sqrt(5.0 / zw))))) * 66.5)
}

func (ma *ma)screenCoords(x float64, y float64) (float64, float64) {
	return (ma.minx + x * ma.sx), (ma.miny + y * ma.sy)
}

var palette = [...][3]float64{
	{ 1.00, 0.00, 0.00 },
	{ 1.00, 0.25, 0.00 },
	{ 1.00, 0.50, 0.00 },
	{ 1.00, 0.75, 0.00 },
	{ 1.00, 1.00, 0.00 },
	{ 0.25, 1.00, 0.25 },
	{ 0.50, 1.00, 0.50 },
	{ 0.75, 1.00, 0.75 },
	{ 0.00, 1.00, 1.00 },
	{ 0.25, 0.75, 0.75 },
	{ 0.50, 0.50, 0.50 },
	{ 0.75, 0.25, 0.25 },
}

var log_escape = math.Log(2)

func (ma *ma)getColor(z, c complex128, i int) (byte, byte, byte) {
	for extra := 0; extra < 3; extra++ {
		z = z * z + c
		i++
	}
	mu := float64(i + 1) - math.Log(math.Log(cmplx.Abs(z))) / log_escape
	mu /= 4
	clr1 := int(mu)

	t2 := mu - float64(clr1)
	t1 := 1.0 - t2

	c1 := palette[clr1 % len(palette)]
	c2 := palette[(clr1 + 1) % len(palette)]

	return byte(255 * (c1[0] * t1 + c2[0] * t2)),
		byte(255 * (c1[1] * t1 + c2[1] * t2)),
		byte(255 * (c1[2] * t1 + c2[2] * t2))
}

func (ma *ma)redrawRange(starty int, endy int, nc int, rs int, px []byte, wg *sync.WaitGroup) {
	for y := starty; y < endy; y++ {
		cy := ma.miny + float64(y) * ma.sy
		for x := 0; x < ma.w; x++ {
			cx := ma.minx + float64(x) * ma.sx
			o := y * rs + x * nc

			c := complex(cx, cy)
			z := c
			px[o], px[o + 1], px[o +2] = 0, 0, 0
			for i := 0; i < ma.iter; i++ {
				if cmplx.Abs(z) > 2.0 {
					px[o], px[o + 1], px[o + 2] = ma.getColor(z, c, i)
					break
				}
				z = z * z + c
			}
		}
	}
	wg.Done()
}

func (ma *ma)redraw() {
	nc := ma.pb.GetNChannels()
	rs := ma.pb.GetRowstride()
	px := ma.pb.GetPixels()

	startt := time.Now()

	var wg sync.WaitGroup

	steps := runtime.NumCPU()
	for i := 0; i < steps; i++ {
		wg.Add(1)
		go ma.redrawRange(i * ma.h / steps, (i + 1) * ma.h / steps, nc, rs, px, &wg)
	}

	wg.Wait()
	ma.lastDuration = time.Since(startt)
}

func label(s string, w int) *gtk.Label {
	l, err := gtk.LabelNew(s)
	if err != nil {
		log.Fatal(err)
	}
	l.SetLineWrap(false)
	l.SetMaxWidthChars(w)
	return l
}

func (ma *ma)updateLabels(gr *gtk.Grid) {
	if gr != nil {
		ma.label.l = label("", 10)
		ma.label.r = label("", 10)
		ma.label.t = label("", 10)
		ma.label.b = label("", 10)
		ma.label.i = label("", 10)
		ma.label.d = label("", 10)
		gr.Attach(label("minx:", 5), 0, 0, 1, 1)
		gr.Attach(label("maxx:", 5), 0, 1, 1, 1)
		gr.Attach(label("miny:", 5), 0, 2, 1, 1)
		gr.Attach(label("maxy:", 5), 0, 3, 1, 1)
		gr.Attach(label("iter:", 5), 0, 4, 1, 1)
		gr.Attach(label("time:", 5), 0, 5, 1, 1)
		gr.Attach(ma.label.l, 1, 0, 1, 1)
		gr.Attach(ma.label.r, 1, 1, 1, 1)
		gr.Attach(ma.label.t, 1, 2, 1, 1)
		gr.Attach(ma.label.b, 1, 3, 1, 1)
		gr.Attach(ma.label.i, 1, 4, 1, 1)
		gr.Attach(ma.label.d, 1, 5, 1, 1)
	}
	ma.label.l.SetText(fmt.Sprintf("%8.4E", ma.minx))
	ma.label.r.SetText(fmt.Sprintf("%8.4E", ma.maxx))
	ma.label.t.SetText(fmt.Sprintf("%8.4E", ma.miny))
	ma.label.b.SetText(fmt.Sprintf("%8.4E", ma.maxy))
	ma.label.i.SetText(fmt.Sprintf("%d", ma.iter))
	ma.label.d.SetText(fmt.Sprintf("%v", ma.lastDuration))
}

func (ma *ma)widget() gtk.IWidget {
	hb, err := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 5)
	if err != nil {
		log.Fatal(err)
	}

	gr, err := gtk.GridNew()
	if err != nil {
		log.Fatal(err)
	}
	ma.updateLabels(gr)

	hb.PackStart(gr, false, false, 0)
	hb.PackEnd(ma.pictureWidget(), true, false, 0)

	return hb
}

func (ma *ma)pictureWidget() gtk.IWidget {
	eb, err := gtk.EventBoxNew()
	if err != nil {
		log.Fatal(err)
	}

	im, err := gtk.ImageNewFromPixbuf(ma.pb)
	if err != nil {
		log.Fatal(err)
	}

	eb.Add(im)

	eb.AddEvents(int(gdk.SCROLL_MASK))

	zw := 3.0
	cx := -0.5
	cy := 0.0

	redraw := func() {
		ma.setCoords(cx, cy, zw)
		ma.redraw()
		ma.updateLabels(nil)
		im.SetFromPixbuf(ma.pb)
		eb.QueueDraw()
	}

	redraw()

	_, err = eb.Connect("button_press_event", func(win *gtk.Window, ev *gdk.Event) {
		e := &gdk.EventButton{ev}
		cx, cy = ma.screenCoords(e.X(), e.Y())
		redraw()
	})
	_, err = eb.Connect("scroll-event", func(win *gtk.Window, ev *gdk.Event) {
		e := &gdk.EventScroll{ev}
		delta := e.DeltaY()
		if delta > 0.5 {
			delta = 0.5
		}
		delta *= (zw / 5.0)

		switch e.Direction() {
		case gdk.SCROLL_UP:
			delta = -delta
		case gdk.SCROLL_DOWN:
			// nothing
		default:
			delta = 0
		}

		// We want the screen to canvas translated coordinate be the same before and after the zoom.
		// This means: ominx + EX * osx = nminx + EX * nsx  (o-prefix is old, n is new) after some
		// algebra we get this:
		cx += delta * (0.5 - e.X() / float64(ma.w - 1))
		cy += delta * (0.5 - e.Y() / float64(ma.h - 1))
		zw += delta
		redraw()
	})
	if err != nil {
		log.Fatal("connect: ", err)
	}
	return eb
}

func main() {
	runtime.LockOSThread()
	gtk.Init(nil)
	win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
	if err != nil {
		log.Fatal(err)
	}
	win.Connect("destroy", gtk.MainQuit)

	ma := newma()

	win.Add(ma.widget())
	win.ShowAll()

	gtk.Main()
}
<commit_msg>Maybe better building of the ui?<commit_after>package main

import (
	"github.com/gotk3/gotk3/cairo"
	"github.com/gotk3/gotk3/gdk"
	"github.com/gotk3/gotk3/gtk"
	"log"
	"math/cmplx"
	"fmt"
	"math"
	"time"
	"sync"
	"runtime"
	"reflect"
)

type ma struct {
	pb *gdk.Pixbuf

	Maxx float64
	Maxy float64

	Minx float64
	Miny float64

	sx float64
	sy float64

	Iter int

	h int
	w int

	LastDuration time.Duration

	label struct {
		l, r, t, b, i, d *gtk.Label
	}

	dl dataLabels
}

func newma() *ma {
	ma := &ma{}

	pb, err := gdk.PixbufNew(gdk.COLORSPACE_RGB, false, 8, 256, 256)
	if err != nil {
		log.Fatal("pixbuf: ", err)
	}

	ma.pb = pb
	ma.setCoords(-0.5, 0.0, 3.0)

	return ma
}

func (ma *ma)setCoords(cx float64, cy float64, zw float64) {
	ma.w = ma.pb.GetWidth()
	ma.h = ma.pb.GetHeight()

	ma.Minx = cx - (zw / 2)
	ma.Maxx = cx + (zw / 2)
	ma.Miny = cy - ((ma.Maxx - ma.Minx) * float64(ma.h) / float64(ma.w) / 2)
	ma.Maxy = cy + ((ma.Maxx - ma.Minx) * float64(ma.h) / float64(ma.w) / 2)

	ma.sx = (ma.Maxx - ma.Minx)/float64(ma.w - 1)
	ma.sy = (ma.Maxy - ma.Miny)/float64(ma.h - 1)

	// http://math.stackexchange.com/a/30560
	ma.Iter = int(math.Sqrt(math.Abs(2.0 * math.Sqrt(math.Abs(1 - math.Sqrt(5.0 / zw))))) * 66.5)
}

func (ma *ma)screenCoords(x float64, y float64) (float64, float64) {
	return (ma.Minx + x * ma.sx), (ma.Miny + y * ma.sy)
}

var palette = [...][3]float64{
	{ 1.00, 0.00, 0.00 },
	{ 1.00, 0.25, 0.00 },
	{ 1.00, 0.50, 0.00 },
	{ 1.00, 0.75, 0.00 },
	{ 1.00, 1.00, 0.00 },
	{ 0.25, 1.00, 0.25 },
	{ 0.50, 1.00, 0.50 },
	{ 0.75, 1.00, 0.75 },
	{ 0.00, 1.00, 1.00 },
	{ 0.25, 0.75, 0.75 },
	{ 0.50, 0.50, 0.50 },
	{ 0.75, 0.25, 0.25 },
}

var log_escape = math.Log(2)

func (ma *ma)getColor(z, c complex128, i int) (byte, byte, byte) {
	for extra := 0; extra < 3; extra++ {
		z = z * z + c
		i++
	}
	mu := float64(i + 1) - math.Log(math.Log(cmplx.Abs(z))) / log_escape
	mu /= 4
	clr1 := int(mu)

	t2 := mu - float64(clr1)
	t1 := 1.0 - t2

	c1 := palette[clr1 % len(palette)]
	c2 := palette[(clr1 + 1) % len(palette)]

	return byte(255 * (c1[0] * t1 + c2[0] * t2)),
		byte(255 * (c1[1] * t1 + c2[1] * t2)),
		byte(255 * (c1[2] * t1 + c2[2] * t2))
}

func (ma *ma)redrawRange(starty int, endy int, nc int, rs int, px []byte, wg *sync.WaitGroup) {
	for y := starty; y < endy; y++ {
		cy := ma.Miny + float64(y) * ma.sy
		for x := 0; x < ma.w; x++ {
			cx := ma.Minx + float64(x) * ma.sx
			o := y * rs + x * nc

			c := complex(cx, cy)
			z := c
			px[o], px[o + 1], px[o +2] = 0, 0, 0
			for i := 0; i < ma.Iter; i++ {
				if cmplx.Abs(z) > 2.0 {
					px[o], px[o + 1], px[o + 2] = ma.getColor(z, c, i)
					break
				}
				z = z * z + c
			}
		}
	}
	wg.Done()
}

func (ma *ma)redraw() {
	nc := ma.pb.GetNChannels()
	rs := ma.pb.GetRowstride()
	px := ma.pb.GetPixels()

	startt := time.Now()

	var wg sync.WaitGroup

	steps := runtime.NumCPU()
	for i := 0; i < steps; i++ {
		wg.Add(1)
		go ma.redrawRange(i * ma.h / steps, (i + 1) * ma.h / steps, nc, rs, px, &wg)
	}

	wg.Wait()
	ma.LastDuration = time.Since(startt)
}

func label(s string, w int) *gtk.Label {
	l, err := gtk.LabelNew(s)
	if err != nil {
		log.Fatal(err)
	}
	l.SetLineWrap(false)
	l.SetMaxWidthChars(w)
	return l
}

type dataLabels map[string]*struct {
	fmt string
	label *gtk.Label
	data interface{}
}

func (dl *dataLabels)addBuilder(b *gtk.Builder) {
	for ln, d := range *dl {
		w, err := b.GetObject(ln)
		if err != nil {
			log.Fatalf("label object not found: %s", ln)
		}
		d.label = w.(*gtk.Label)
	}
}

func (dl dataLabels)update(obj interface{}) {
	v := reflect.ValueOf(obj)

	for ln, d := range dl {
		d.label.SetText(fmt.Sprintf(d.fmt, v.FieldByName(ln).Interface()))
	}
}

const build = `
<interface>
  <object class="GtkBox" id="everything">
    <property name="orientation">horizontal</property>
    <child>
      <object class="GtkDrawingArea">
        <signal name="draw" handler="drawArea" />
        <property name="width-request">256</property>
        <property name="height-request">256</property>
      </object>
    </child>

   <child>
     <object class="GtkGrid" id="labels">

       <child>
         <object class="GtkLabel">
           <property name="width-chars">10</property>
	   <property name="label">Minx:</property>
         </object>
         <packing>
           <property name="left-attach">0</property>
           <property name="top-attach">0</property>
         </packing>
       </child>
       <child>
         <object class="GtkLabel" id="Minx">
           <property name="width-chars">10</property>
         </object>
         <packing>
           <property name="left-attach">1</property>
           <property name="top-attach">0</property>
         </packing>
       </child>

       <child>
         <object class="GtkLabel">
           <property name="width-chars">10</property>
	   <property name="label">Maxx:</property>
         </object>
         <packing>
           <property name="left-attach">0</property>
           <property name="top-attach">1</property>
         </packing>
       </child>
       <child>
         <object class="GtkLabel" id="Maxx">
           <property name="width-chars">10</property>
         </object>
         <packing>
           <property name="left-attach">1</property>
           <property name="top-attach">1</property>
         </packing>
       </child>

       <child>
         <object class="GtkLabel">
           <property name="width-chars">10</property>
	   <property name="label">Miny:</property>
         </object>
         <packing>
           <property name="left-attach">0</property>
           <property name="top-attach">2</property>
         </packing>
       </child>
       <child>
         <object class="GtkLabel" id="Miny">
           <property name="width-chars">10</property>
         </object>
         <packing>
           <property name="left-attach">1</property>
           <property name="top-attach">2</property>
         </packing>
       </child>

       <child>
         <object class="GtkLabel">
           <property name="width-chars">10</property>
	   <property name="label">Maxy:</property>
         </object>
         <packing>
           <property name="left-attach">0</property>
           <property name="top-attach">3</property>
         </packing>
       </child>
       <child>
         <object class="GtkLabel" id="Maxy">
           <property name="width-chars">10</property>
         </object>
         <packing>
           <property name="left-attach">1</property>
           <property name="top-attach">3</property>
         </packing>
       </child>

       <child>
         <object class="GtkLabel">
           <property name="width-chars">10</property>
	   <property name="label">Iter:</property>
         </object>
         <packing>
           <property name="left-attach">0</property>
           <property name="top-attach">4</property>
         </packing>
       </child>
       <child>
         <object class="GtkLabel" id="Iter">
           <property name="width-chars">10</property>
         </object>
         <packing>
           <property name="left-attach">1</property>
           <property name="top-attach">4</property>
         </packing>
       </child>

       <child>
         <object class="GtkLabel">
           <property name="width-chars">10</property>
	   <property name="label">Time:</property>
         </object>
         <packing>
           <property name="left-attach">0</property>
           <property name="top-attach">5</property>
         </packing>
       </child>
       <child>
         <object class="GtkLabel" id="LastDuration">
           <property name="width-chars">10</property>
         </object>
         <packing>
           <property name="left-attach">1</property>
           <property name="top-attach">5</property>
         </packing>
       </child>

     </object>
   </child>

  </object>
</interface>
`

func (ma *ma)buildWidgets() gtk.IWidget {
	builder, err := gtk.BuilderNew()
	if err != nil {
		log.Fatal(err)
	}
	err = builder.AddFromString(build)
	if err != nil {
		log.Fatal(err)
	}
	obj, err := builder.GetObject("everything")
	if err != nil {
		log.Fatal(err)
	}

	builder.ConnectSignals(map[string]interface{}{
		"drawArea": func(da *gtk.DrawingArea, cr *cairo.Context) {
			gtk.GdkCairoSetSourcePixBuf(cr, ma.pb, 0, 0)
			cr.Paint()
		},
	})

	ma.dl = dataLabels{
		"Minx": { fmt: "%8.4E" },
		"Maxx": { fmt: "%8.4E" },
		"Miny": { fmt: "%8.4E" },
		"Maxy": { fmt: "%8.4E" },
		"Iter": { fmt: "%d" },
		"LastDuration": { fmt: "%v" },
	}
	ma.dl.addBuilder(builder)
	ma.dl.update(*ma)

	return obj.(gtk.IWidget)
}

func (ma *ma)widget() gtk.IWidget {
	hb, err := gtk.BoxNew(gtk.ORIENTATION_HORIZONTAL, 5)
	if err != nil {
		log.Fatal(err)
	}

	hb.PackStart(ma.pictureWidget(), true, false, 0)
	hb.PackStart(ma.buildWidgets(), false, false, 0)

	return hb
}

func (ma *ma)pictureWidget() gtk.IWidget {
	eb, err := gtk.EventBoxNew()
	if err != nil {
		log.Fatal(err)
	}

	im, err := gtk.ImageNewFromPixbuf(ma.pb)
	if err != nil {
		log.Fatal(err)
	}

	eb.Add(im)

	eb.AddEvents(int(gdk.SCROLL_MASK))

	zw := 3.0
	cx := -0.5
	cy := 0.0

	redraw := func() {
		ma.setCoords(cx, cy, zw)
		ma.redraw()
		ma.dl.update(*ma)
		im.SetFromPixbuf(ma.pb)
		eb.QueueDraw()
	}

	redraw()

	_, err = eb.Connect("button_press_event", func(win *gtk.Window, ev *gdk.Event) {
		e := &gdk.EventButton{ev}
		cx, cy = ma.screenCoords(e.X(), e.Y())
		redraw()
	})
	_, err = eb.Connect("scroll-event", func(win *gtk.Window, ev *gdk.Event) {
		e := &gdk.EventScroll{ev}
		delta := e.DeltaY()
		if delta > 0.5 {
			delta = 0.5
		}
		delta *= (zw / 5.0)

		switch e.Direction() {
		case gdk.SCROLL_UP:
			delta = -delta
		case gdk.SCROLL_DOWN:
			// nothing
		default:
			delta = 0
		}

		// We want the screen to canvas translated coordinate be the same before and after the zoom.
		// This means: ominx + EX * osx = nminx + EX * nsx  (o-prefix is old, n is new) after some
		// algebra we get this:
		cx += delta * (0.5 - e.X() / float64(ma.w - 1))
		cy += delta * (0.5 - e.Y() / float64(ma.h - 1))
		zw += delta
		redraw()
	})
	if err != nil {
		log.Fatal("connect: ", err)
	}
	return eb
}

func main() {
	runtime.LockOSThread()
	gtk.Init(nil)
	win, err := gtk.WindowNew(gtk.WINDOW_TOPLEVEL)
	if err != nil {
		log.Fatal(err)
	}
	win.Connect("destroy", gtk.MainQuit)

	ma := newma()

	win.Add(ma.widget())
	win.ShowAll()

	gtk.Main()
}
<|endoftext|>


<commit_before>package gin

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"errors"
	"fmt"
	"github.com/julienschmidt/httprouter"
	"html/template"
	"log"
	"math"
	"net/http"
	"path"
)

const (
	AbortIndex = math.MaxInt8 / 2
)

type (
	HandlerFunc func(*Context)

	H map[string]interface{}

	// Used internally to collect errors that occurred during an http request.
	ErrorMsg struct {
		Err  string      `json:"error"`
		Meta interface{} `json:"meta"`
	}

	ErrorMsgs []ErrorMsg

	// Context is the most important part of gin. It allows us to pass variables between middleware,
	// manage the flow, validate the JSON of a request and render a JSON response for example.
	Context struct {
		Req      *http.Request
		Writer   http.ResponseWriter
		Keys     map[string]interface{}
		Errors   ErrorMsgs
		Params   httprouter.Params
		handlers []HandlerFunc
		engine   *Engine
		index    int8
	}

	// Used internally to configure router, a RouterGroup is associated with a prefix
	// and an array of handlers (middlewares)
	RouterGroup struct {
		Handlers []HandlerFunc
		prefix   string
		parent   *RouterGroup
		engine   *Engine
	}

	// Represents the web framework, it wraps the blazing fast httprouter multiplexer and a list of global middlewares.
	Engine struct {
		*RouterGroup
		handlers404   []HandlerFunc
		router        *httprouter.Router
		HTMLTemplates *template.Template
	}
)

func (a ErrorMsgs) String() string {
	var buffer bytes.Buffer
	for i, msg := range a {
		text := fmt.Sprintf("Error #%02d: %s \n     Meta: %v\n\n", (i + 1), msg.Err, msg.Meta)
		buffer.WriteString(text)
	}
	return buffer.String()
}

// Returns a new blank Engine instance without any middleware attached.
// The most basic configuration
func New() *Engine {
	engine := &Engine{}
	engine.RouterGroup = &RouterGroup{nil, "/", nil, engine}
	engine.router = httprouter.New()
	engine.router.NotFound = engine.handle404
	return engine
}

// Returns a Engine instance with the Logger and Recovery already attached.
func Default() *Engine {
	engine := New()
	engine.Use(Recovery(), Logger())
	return engine
}

func (engine *Engine) LoadHTMLTemplates(pattern string) {
	engine.HTMLTemplates = template.Must(template.ParseGlob(pattern))
}

// Adds handlers for NotFound. It return a 404 code by default.
func (engine *Engine) NotFound404(handlers ...HandlerFunc) {
	engine.handlers404 = handlers
}

func (engine *Engine) handle404(w http.ResponseWriter, req *http.Request) {
	handlers := engine.combineHandlers(engine.handlers404)
	c := engine.createContext(w, req, nil, handlers)
	if engine.handlers404 == nil {
		http.NotFound(c.Writer, c.Req)
	} else {
		c.Writer.WriteHeader(404)
	}

	c.Next()
}

// ServeFiles serves files from the given file system root.
// The path must end with "/*filepath", files are then served from the local
// path /defined/root/dir/*filepath.
// For example if root is "/etc" and *filepath is "passwd", the local file
// "/etc/passwd" would be served.
// Internally a http.FileServer is used, therefore http.NotFound is used instead
// of the Router's NotFound handler.
// To use the operating system's file system implementation,
// use http.Dir:
//     router.ServeFiles("/src/*filepath", http.Dir("/var/www"))
func (engine *Engine) ServeFiles(path string, root http.FileSystem) {
	engine.router.ServeFiles(path, root)
}

// ServeHTTP makes the router implement the http.Handler interface.
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	engine.router.ServeHTTP(w, req)
}

func (engine *Engine) Run(addr string) {
	http.ListenAndServe(addr, engine)
}

/************************************/
/********** ROUTES GROUPING *********/
/************************************/

func (group *RouterGroup) createContext(w http.ResponseWriter, req *http.Request, params httprouter.Params, handlers []HandlerFunc) *Context {
	return &Context{
		Writer:   w,
		Req:      req,
		index:    -1,
		engine:   group.engine,
		Params:   params,
		handlers: handlers,
	}
}

// Adds middlewares to the group, see example code in github.
func (group *RouterGroup) Use(middlewares ...HandlerFunc) {
	group.Handlers = append(group.Handlers, middlewares...)
}

// Creates a new router group. You should add all the routes that have common middlwares or the same path prefix.
// For example, all the routes that use a common middlware for authorization could be grouped.
func (group *RouterGroup) Group(component string, handlers ...HandlerFunc) *RouterGroup {
	prefix := path.Join(group.prefix, component)
	return &RouterGroup{
		Handlers: group.combineHandlers(handlers),
		parent:   group,
		prefix:   prefix,
		engine:   group.engine,
	}
}

// Handle registers a new request handle and middlewares with the given path and method.
// The last handler should be the real handler, the other ones should be middlewares that can and should be shared among different routes.
// See the example code in github.
//
// For GET, POST, PUT, PATCH and DELETE requests the respective shortcut
// functions can be used.
//
// This function is intended for bulk loading and to allow the usage of less
// frequently used, non-standardized or custom methods (e.g. for internal
// communication with a proxy).
func (group *RouterGroup) Handle(method, p string, handlers []HandlerFunc) {
	p = path.Join(group.prefix, p)
	handlers = group.combineHandlers(handlers)
	group.engine.router.Handle(method, p, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
		group.createContext(w, req, params, handlers).Next()
	})
}

// POST is a shortcut for router.Handle("POST", path, handle)
func (group *RouterGroup) POST(path string, handlers ...HandlerFunc) {
	group.Handle("POST", path, handlers)
}

// GET is a shortcut for router.Handle("GET", path, handle)
func (group *RouterGroup) GET(path string, handlers ...HandlerFunc) {
	group.Handle("GET", path, handlers)
}

// DELETE is a shortcut for router.Handle("DELETE", path, handle)
func (group *RouterGroup) DELETE(path string, handlers ...HandlerFunc) {
	group.Handle("DELETE", path, handlers)
}

// PATCH is a shortcut for router.Handle("PATCH", path, handle)
func (group *RouterGroup) PATCH(path string, handlers ...HandlerFunc) {
	group.Handle("PATCH", path, handlers)
}

// PUT is a shortcut for router.Handle("PUT", path, handle)
func (group *RouterGroup) PUT(path string, handlers ...HandlerFunc) {
	group.Handle("PUT", path, handlers)
}

func (group *RouterGroup) combineHandlers(handlers []HandlerFunc) []HandlerFunc {
	s := len(group.Handlers) + len(handlers)
	h := make([]HandlerFunc, 0, s)
	h = append(h, group.Handlers...)
	h = append(h, handlers...)
	return h
}

/************************************/
/****** FLOW AND ERROR MANAGEMENT****/
/************************************/

// Next should be used only in the middlewares.
// It executes the pending handlers in the chain inside the calling handler.
// See example in github.
func (c *Context) Next() {
	c.index++
	s := int8(len(c.handlers))
	for ; c.index < s; c.index++ {
		c.handlers[c.index](c)
	}
}

// Forces the system to do not continue calling the pending handlers.
// For example, the first handler checks if the request is authorized. If it's not, context.Abort(401) should be called.
// The rest of pending handlers would never be called for that request.
func (c *Context) Abort(code int) {
	c.Writer.WriteHeader(code)
	c.index = AbortIndex
}

// Fail is the same as Abort plus an error message.
// Calling `context.Fail(500, err)` is equivalent to:
// ```
// context.Error("Operation aborted", err)
// context.Abort(500)
// ```
func (c *Context) Fail(code int, err error) {
	c.Error(err, "Operation aborted")
	c.Abort(code)
}

// Attaches an error to the current context. The error is pushed to a list of errors.
// It's a good idea to call Error for each error that occurred during the resolution of a request.
// A middleware can be used to collect all the errors and push them to a database together, print a log, or append it in the HTTP response.
func (c *Context) Error(err error, meta interface{}) {
	c.Errors = append(c.Errors, ErrorMsg{
		Err:  err.Error(),
		Meta: meta,
	})
}

func (c *Context) LastError() error {
	s := len(c.Errors)
	if s > 0 {
		return errors.New(c.Errors[s-1].Err)
	} else {
		return nil
	}
}

/************************************/
/******** METADATA MANAGEMENT********/
/************************************/

// Sets a new pair key/value just for the specified context.
// It also lazy initializes the hashmap.
func (c *Context) Set(key string, item interface{}) {
	if c.Keys == nil {
		c.Keys = make(map[string]interface{})
	}
	c.Keys[key] = item
}

// Returns the value for the given key.
// It panics if the value doesn't exist.
func (c *Context) Get(key string) interface{} {
	var ok bool
	var item interface{}
	if c.Keys != nil {
		item, ok = c.Keys[key]
	} else {
		item, ok = nil, false
	}
	if !ok || item == nil {
		log.Panicf("Key %s doesn't exist", key)
	}
	return item
}

/************************************/
/******** ENCOGING MANAGEMENT********/
/************************************/

// Like ParseBody() but this method also writes a 400 error if the json is not valid.
func (c *Context) EnsureBody(item interface{}) bool {
	if err := c.ParseBody(item); err != nil {
		c.Fail(400, err)
		return false
	}
	return true
}

// Parses the body content as a JSON input. It decodes the json payload into the struct specified as a pointer.
func (c *Context) ParseBody(item interface{}) error {
	decoder := json.NewDecoder(c.Req.Body)
	if err := decoder.Decode(&item); err == nil {
		return Validate(c, item)
	} else {
		return err
	}
}

// Serializes the given struct as JSON into the response body in a fast and efficient way.
// It also sets the Content-Type as "application/json".
func (c *Context) JSON(code int, obj interface{}) {
	c.Writer.Header().Set("Content-Type", "application/json")
	if code >= 0 {
		c.Writer.WriteHeader(code)
	}
	encoder := json.NewEncoder(c.Writer)
	if err := encoder.Encode(obj); err != nil {
		c.Error(err, obj)
		http.Error(c.Writer, err.Error(), 500)
	}
}

// Serializes the given struct as XML into the response body in a fast and efficient way.
// It also sets the Content-Type as "application/xml".
func (c *Context) XML(code int, obj interface{}) {
	c.Writer.Header().Set("Content-Type", "application/xml")
	if code >= 0 {
		c.Writer.WriteHeader(code)
	}
	encoder := xml.NewEncoder(c.Writer)
	if err := encoder.Encode(obj); err != nil {
		c.Error(err, obj)
		http.Error(c.Writer, err.Error(), 500)
	}
}

// Renders the HTTP template specified by its file name.
// It also updates the HTTP code and sets the Content-Type as "text/html".
// See http://golang.org/doc/articles/wiki/
func (c *Context) HTML(code int, name string, data interface{}) {
	c.Writer.Header().Set("Content-Type", "text/html")
	if code >= 0 {
		c.Writer.WriteHeader(code)
	}
	if err := c.engine.HTMLTemplates.ExecuteTemplate(c.Writer, name, data); err != nil {
		c.Error(err, map[string]interface{}{
			"name": name,
			"data": data,
		})
		http.Error(c.Writer, err.Error(), 500)
	}
}

// Writes the given string into the response body and sets the Content-Type to "text/plain".
func (c *Context) String(code int, msg string) {
	if code >= 0 {
		c.Writer.WriteHeader(code)
	}
	c.Writer.Header().Set("Content-Type", "text/plain")
	c.Writer.Write([]byte(msg))
}

// Writes some data into the body stream and updates the HTTP code.
func (c *Context) Data(code int, data []byte) {
	c.Writer.WriteHeader(code)
	c.Writer.Write(data)
}
<commit_msg>Fix XML Marshal to work with gin.H<commit_after>package gin

import (
	"bytes"
	"encoding/json"
	"encoding/xml"
	"errors"
	"fmt"
	"github.com/julienschmidt/httprouter"
	"html/template"
	"log"
	"math"
	"net/http"
	"path"
)

const (
	AbortIndex = math.MaxInt8 / 2
)

type (
	HandlerFunc func(*Context)

	H map[string]interface{}

	// Used internally to collect errors that occurred during an http request.
	ErrorMsg struct {
		Err  string      `json:"error"`
		Meta interface{} `json:"meta"`
	}

	ErrorMsgs []ErrorMsg

	// Context is the most important part of gin. It allows us to pass variables between middleware,
	// manage the flow, validate the JSON of a request and render a JSON response for example.
	Context struct {
		Req      *http.Request
		Writer   http.ResponseWriter
		Keys     map[string]interface{}
		Errors   ErrorMsgs
		Params   httprouter.Params
		handlers []HandlerFunc
		engine   *Engine
		index    int8
	}

	// Used internally to configure router, a RouterGroup is associated with a prefix
	// and an array of handlers (middlewares)
	RouterGroup struct {
		Handlers []HandlerFunc
		prefix   string
		parent   *RouterGroup
		engine   *Engine
	}

	// Represents the web framework, it wraps the blazing fast httprouter multiplexer and a list of global middlewares.
	Engine struct {
		*RouterGroup
		handlers404   []HandlerFunc
		router        *httprouter.Router
		HTMLTemplates *template.Template
	}
)

// Allows type H to be used with xml.Marshal
func (h H) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
	e.EncodeToken(start)
	for key, value := range h {
		elem := xml.StartElement{Name: xml.Name{Local: key}}
		e.EncodeElement(value, elem)
	}
	e.EncodeToken(xml.EndElement{start.Name})
	return nil
}

func (a ErrorMsgs) String() string {
	var buffer bytes.Buffer
	for i, msg := range a {
		text := fmt.Sprintf("Error #%02d: %s \n     Meta: %v\n\n", (i + 1), msg.Err, msg.Meta)
		buffer.WriteString(text)
	}
	return buffer.String()
}

// Returns a new blank Engine instance without any middleware attached.
// The most basic configuration
func New() *Engine {
	engine := &Engine{}
	engine.RouterGroup = &RouterGroup{nil, "/", nil, engine}
	engine.router = httprouter.New()
	engine.router.NotFound = engine.handle404
	return engine
}

// Returns a Engine instance with the Logger and Recovery already attached.
func Default() *Engine {
	engine := New()
	engine.Use(Recovery(), Logger())
	return engine
}

func (engine *Engine) LoadHTMLTemplates(pattern string) {
	engine.HTMLTemplates = template.Must(template.ParseGlob(pattern))
}

// Adds handlers for NotFound. It return a 404 code by default.
func (engine *Engine) NotFound404(handlers ...HandlerFunc) {
	engine.handlers404 = handlers
}

func (engine *Engine) handle404(w http.ResponseWriter, req *http.Request) {
	handlers := engine.combineHandlers(engine.handlers404)
	c := engine.createContext(w, req, nil, handlers)
	if engine.handlers404 == nil {
		http.NotFound(c.Writer, c.Req)
	} else {
		c.Writer.WriteHeader(404)
	}

	c.Next()
}

// ServeFiles serves files from the given file system root.
// The path must end with "/*filepath", files are then served from the local
// path /defined/root/dir/*filepath.
// For example if root is "/etc" and *filepath is "passwd", the local file
// "/etc/passwd" would be served.
// Internally a http.FileServer is used, therefore http.NotFound is used instead
// of the Router's NotFound handler.
// To use the operating system's file system implementation,
// use http.Dir:
//     router.ServeFiles("/src/*filepath", http.Dir("/var/www"))
func (engine *Engine) ServeFiles(path string, root http.FileSystem) {
	engine.router.ServeFiles(path, root)
}

// ServeHTTP makes the router implement the http.Handler interface.
func (engine *Engine) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	engine.router.ServeHTTP(w, req)
}

func (engine *Engine) Run(addr string) {
	http.ListenAndServe(addr, engine)
}

/************************************/
/********** ROUTES GROUPING *********/
/************************************/

func (group *RouterGroup) createContext(w http.ResponseWriter, req *http.Request, params httprouter.Params, handlers []HandlerFunc) *Context {
	return &Context{
		Writer:   w,
		Req:      req,
		index:    -1,
		engine:   group.engine,
		Params:   params,
		handlers: handlers,
	}
}

// Adds middlewares to the group, see example code in github.
func (group *RouterGroup) Use(middlewares ...HandlerFunc) {
	group.Handlers = append(group.Handlers, middlewares...)
}

// Creates a new router group. You should add all the routes that have common middlwares or the same path prefix.
// For example, all the routes that use a common middlware for authorization could be grouped.
func (group *RouterGroup) Group(component string, handlers ...HandlerFunc) *RouterGroup {
	prefix := path.Join(group.prefix, component)
	return &RouterGroup{
		Handlers: group.combineHandlers(handlers),
		parent:   group,
		prefix:   prefix,
		engine:   group.engine,
	}
}

// Handle registers a new request handle and middlewares with the given path and method.
// The last handler should be the real handler, the other ones should be middlewares that can and should be shared among different routes.
// See the example code in github.
//
// For GET, POST, PUT, PATCH and DELETE requests the respective shortcut
// functions can be used.
//
// This function is intended for bulk loading and to allow the usage of less
// frequently used, non-standardized or custom methods (e.g. for internal
// communication with a proxy).
func (group *RouterGroup) Handle(method, p string, handlers []HandlerFunc) {
	p = path.Join(group.prefix, p)
	handlers = group.combineHandlers(handlers)
	group.engine.router.Handle(method, p, func(w http.ResponseWriter, req *http.Request, params httprouter.Params) {
		group.createContext(w, req, params, handlers).Next()
	})
}

// POST is a shortcut for router.Handle("POST", path, handle)
func (group *RouterGroup) POST(path string, handlers ...HandlerFunc) {
	group.Handle("POST", path, handlers)
}

// GET is a shortcut for router.Handle("GET", path, handle)
func (group *RouterGroup) GET(path string, handlers ...HandlerFunc) {
	group.Handle("GET", path, handlers)
}

// DELETE is a shortcut for router.Handle("DELETE", path, handle)
func (group *RouterGroup) DELETE(path string, handlers ...HandlerFunc) {
	group.Handle("DELETE", path, handlers)
}

// PATCH is a shortcut for router.Handle("PATCH", path, handle)
func (group *RouterGroup) PATCH(path string, handlers ...HandlerFunc) {
	group.Handle("PATCH", path, handlers)
}

// PUT is a shortcut for router.Handle("PUT", path, handle)
func (group *RouterGroup) PUT(path string, handlers ...HandlerFunc) {
	group.Handle("PUT", path, handlers)
}

func (group *RouterGroup) combineHandlers(handlers []HandlerFunc) []HandlerFunc {
	s := len(group.Handlers) + len(handlers)
	h := make([]HandlerFunc, 0, s)
	h = append(h, group.Handlers...)
	h = append(h, handlers...)
	return h
}

/************************************/
/****** FLOW AND ERROR MANAGEMENT****/
/************************************/

// Next should be used only in the middlewares.
// It executes the pending handlers in the chain inside the calling handler.
// See example in github.
func (c *Context) Next() {
	c.index++
	s := int8(len(c.handlers))
	for ; c.index < s; c.index++ {
		c.handlers[c.index](c)
	}
}

// Forces the system to do not continue calling the pending handlers.
// For example, the first handler checks if the request is authorized. If it's not, context.Abort(401) should be called.
// The rest of pending handlers would never be called for that request.
func (c *Context) Abort(code int) {
	c.Writer.WriteHeader(code)
	c.index = AbortIndex
}

// Fail is the same as Abort plus an error message.
// Calling `context.Fail(500, err)` is equivalent to:
// ```
// context.Error("Operation aborted", err)
// context.Abort(500)
// ```
func (c *Context) Fail(code int, err error) {
	c.Error(err, "Operation aborted")
	c.Abort(code)
}

// Attaches an error to the current context. The error is pushed to a list of errors.
// It's a good idea to call Error for each error that occurred during the resolution of a request.
// A middleware can be used to collect all the errors and push them to a database together, print a log, or append it in the HTTP response.
func (c *Context) Error(err error, meta interface{}) {
	c.Errors = append(c.Errors, ErrorMsg{
		Err:  err.Error(),
		Meta: meta,
	})
}

func (c *Context) LastError() error {
	s := len(c.Errors)
	if s > 0 {
		return errors.New(c.Errors[s-1].Err)
	} else {
		return nil
	}
}

/************************************/
/******** METADATA MANAGEMENT********/
/************************************/

// Sets a new pair key/value just for the specified context.
// It also lazy initializes the hashmap.
func (c *Context) Set(key string, item interface{}) {
	if c.Keys == nil {
		c.Keys = make(map[string]interface{})
	}
	c.Keys[key] = item
}

// Returns the value for the given key.
// It panics if the value doesn't exist.
func (c *Context) Get(key string) interface{} {
	var ok bool
	var item interface{}
	if c.Keys != nil {
		item, ok = c.Keys[key]
	} else {
		item, ok = nil, false
	}
	if !ok || item == nil {
		log.Panicf("Key %s doesn't exist", key)
	}
	return item
}

/************************************/
/******** ENCOGING MANAGEMENT********/
/************************************/

// Like ParseBody() but this method also writes a 400 error if the json is not valid.
func (c *Context) EnsureBody(item interface{}) bool {
	if err := c.ParseBody(item); err != nil {
		c.Fail(400, err)
		return false
	}
	return true
}

// Parses the body content as a JSON input. It decodes the json payload into the struct specified as a pointer.
func (c *Context) ParseBody(item interface{}) error {
	decoder := json.NewDecoder(c.Req.Body)
	if err := decoder.Decode(&item); err == nil {
		return Validate(c, item)
	} else {
		return err
	}
}

// Serializes the given struct as JSON into the response body in a fast and efficient way.
// It also sets the Content-Type as "application/json".
func (c *Context) JSON(code int, obj interface{}) {
	c.Writer.Header().Set("Content-Type", "application/json")
	if code >= 0 {
		c.Writer.WriteHeader(code)
	}
	encoder := json.NewEncoder(c.Writer)
	if err := encoder.Encode(obj); err != nil {
		c.Error(err, obj)
		http.Error(c.Writer, err.Error(), 500)
	}
}

// Serializes the given struct as XML into the response body in a fast and efficient way.
// It also sets the Content-Type as "application/xml".
func (c *Context) XML(code int, obj interface{}) {
	c.Writer.Header().Set("Content-Type", "application/xml")
	if code >= 0 {
		c.Writer.WriteHeader(code)
	}
	encoder := xml.NewEncoder(c.Writer)
	if err := encoder.Encode(obj); err != nil {
		c.Error(err, obj)
		http.Error(c.Writer, err.Error(), 500)
	}
}

// Renders the HTTP template specified by its file name.
// It also updates the HTTP code and sets the Content-Type as "text/html".
// See http://golang.org/doc/articles/wiki/
func (c *Context) HTML(code int, name string, data interface{}) {
	c.Writer.Header().Set("Content-Type", "text/html")
	if code >= 0 {
		c.Writer.WriteHeader(code)
	}
	if err := c.engine.HTMLTemplates.ExecuteTemplate(c.Writer, name, data); err != nil {
		c.Error(err, map[string]interface{}{
			"name": name,
			"data": data,
		})
		http.Error(c.Writer, err.Error(), 500)
	}
}

// Writes the given string into the response body and sets the Content-Type to "text/plain".
func (c *Context) String(code int, msg string) {
	if code >= 0 {
		c.Writer.WriteHeader(code)
	}
	c.Writer.Header().Set("Content-Type", "text/plain")
	c.Writer.Write([]byte(msg))
}

// Writes some data into the body stream and updates the HTTP code.
func (c *Context) Data(code int, data []byte) {
	c.Writer.WriteHeader(code)
	c.Writer.Write(data)
}
<|endoftext|>