<commit_before>package model

import (
	"bytes"
	"fmt"
	"go/format"
	"io"
	"os"
	"text/template"
)

// TODO: support client-side validation
// TODO: support enum values
// TODO: support exceptions

func Generate(w io.Writer) error {
	t := template.New("root").Funcs(template.FuncMap{
		"godoc":      godoc,
		"exportable": exportable,
	})
	t, err := t.Parse(awsTmpl)
	if err != nil {
		return err
	}

	out := bytes.NewBuffer(nil)
	if err := t.ExecuteTemplate(out, service.Metadata.Protocol, service); err != nil {
		return err
	}

	b, err := format.Source(out.Bytes())
	if err != nil {
		fmt.Fprint(os.Stderr, out.String())
		return err
	}

	_, err = io.Copy(w, bytes.NewReader(b))
	return err
}

const (
	awsTmpl = `

#################### REST-XML CLIENT

{{ define "rest-xml" }}
{{ template "header" $ }}

import (
  "bytes"
  "fmt"
  "io"
  "io/ioutil"
  "net/url"
  "strconv"
  "strings"
)

// {{ .Name }} is a client for {{ .FullName }}.
type {{ .Name }} struct {
  client *aws.RestXMLClient
}

// New returns a new {{ .Name }} client.
func New(key, secret, region string, client *http.Client) *{{ .Name }} {
  if client == nil {
     client = http.DefaultClient
  }

  service := "{{ .Metadata.EndpointPrefix }}"
  endpoint, service, region := endpoints.Lookup("{{ .Metadata.EndpointPrefix }}", region)

  return &{{ .Name }}{
    client: &aws.RestXMLClient{
      Signer: &aws.V4Signer{
        Key: key,
        Secret: secret,
        Service: service,
        Region: region,
        IncludeXAmzContentSha256: true,
      },
      Client: client,
      Endpoint: endpoint,
      APIVersion: "{{ .Metadata.APIVersion }}",
    },
  }
}

{{ range $name, $op := .Operations }}

{{ godoc $name $op.Documentation }} func (c *{{ $.Name }}) {{ exportable $name }}({{ if $op.Input }}req {{ exportable $op.Input.Type }}{{ end }}) ({{ if $op.Output }}resp *{{ exportable $op.Output.Type }},{{ end }} err error) {
  {{ if $op.Output }}resp = &{{ $op.Output.Type }}{}{{ else }}// NRE{{ end }}

  var body io.Reader
  {{ if $op.Input }}
  {{ if $op.Input.Payload }}
  {{ with $m := index $op.Input.Members $op.Input.Payload }}
  {{ if $m.Streaming }}
  body = req.{{ exportable $m.Name  }}
  {{ else }}
  b, err := xml.Marshal(req.{{ exportable $m.Name  }})
  if err != nil {
    return
  }
  body = bytes.NewReader(b)
  {{ end }}
  {{ end }}
  {{ end }}
  {{ end }}

  uri := c.client.Endpoint + "{{ $op.HTTP.RequestURI }}"
  {{ if $op.Input }}
  {{ range $name, $m := $op.Input.Members }}
  {{ if eq $m.Location "uri" }}

  uri = strings.Replace(uri, "{"+"{{ $m.LocationName }}"+"}", req.{{ exportable $name }}, -1)
  uri = strings.Replace(uri, "{"+"{{ $m.LocationName }}+"+"}", req.{{ exportable $name }}, -1)

  {{ end }}
  {{ end }}
  {{ end }}

  q := url.Values{}

  {{ if $op.Input }}
  {{ range $name, $m := $op.Input.Members }}
  {{ if eq $m.Location "querystring" }}

  {{ if eq $m.Shape.ShapeType "string" }}
  if s := req.{{ exportable $name }}; s != "" {
  {{ else if eq $m.Shape.ShapeType "timestamp" }}
  if s := req.{{ exportable $name }}.Format(time.RFC822); s != "01 Jan 01 00:00 UTC" {
  {{ else if eq $m.Shape.ShapeType "integer" }}
  if s := strconv.Itoa(req.{{ exportable $name }}); req.{{ exportable $name }} != 0 {
  {{ else }}
  if s := fmt.Sprintf("%v", req.{{ exportable $name }}); s != "" {
  {{ end }}
    q.Set("{{ $m.LocationName }}", s)
  }

  {{ end }}
  {{ end }}
  {{ end }}

  if len(q) > 0 {
    uri += "?" + q.Encode()
  }

  httpReq, err := http.NewRequest("{{ $op.HTTP.Method }}", uri, body)
  if err != nil {
    return
  }
  {{ if $op.Input }}
  {{ range $name, $m := $op.Input.Members }}
  {{ if eq $m.Location "header" }}

  {{ if eq $m.Shape.ShapeType "string" }}
  if s := req.{{ exportable $name }}; s != "" {
  {{ else if eq $m.Shape.ShapeType "timestamp" }}
  if s := req.{{ exportable $name }}.Format(time.RFC822); s != "01 Jan 01 00:00 UTC" {
  {{ else if eq $m.Shape.ShapeType "integer" }}
  if s := strconv.Itoa(req.{{ exportable $name }}); req.{{ exportable $name }} != 0 {
  {{ else }}
  if s := fmt.Sprintf("%v", req.{{ exportable $name }}); s != "" {
  {{ end }}
    httpReq.Header.Set("{{ $m.LocationName }}", s)
  }

  {{ end }}
  {{ end }}
  {{ end }}

  httpResp, err := c.client.Do(httpReq)
  if err != nil {
    return
  }

  {{ if $op.Output }}
    {{ with $name := "Body" }}
    {{ with $m := index $op.Output.Members $name }}
    {{ if $m }}

      {{ if $m.Streaming }}
  resp.Body = httpResp.Body
      {{ else }}
  defer httpResp.Body.Close()
  err = xml.NewDecoder(httpResp.Body).Decode(resp)
      {{ end }}

    {{ else }}
  defer httpResp.Body.Close()
    {{ end }}
    {{ end }}

  {{ range $name, $m := $op.Output.Members }}
    {{ if ne $name "Body" }}
      {{ if eq $m.Location "header" }}
        if s := httpResp.Header.Get("{{ $m.LocationName }}"); s != "" {
         {{ if eq $m.Shape.ShapeType "string" }}
          resp.{{ exportable $name }} = s
         {{ else if eq $m.Shape.ShapeType "timestamp" }}
          if t, e := time.Parse(s, time.RFC822); e != nil {
           err = e
           return
          } else {
           resp.{{ exportable $name }} = t
          }
         {{ else if eq $m.Shape.ShapeType "integer" }}
          if n, e := strconv.Atoi(s); e != nil {
           err = e
           return
          } else {
           resp.{{ exportable $name }} = n
          }
         {{ else if eq $m.Shape.ShapeType "boolean" }}
         if v, e := strconv.ParseBool(s); e != nil {
           err = e
           return
          } else {
           resp.{{ exportable $name }} = v
          }
         {{ else }}
         // TODO: add support for {{ $m.Shape.ShapeType }} headers
         {{ end }}
        }
      {{ else if eq $m.Location "headers" }}
      resp.{{ exportable $name }} = {{ $m.Shape.Type }}{}
      for name := range httpResp.Header {
        if strings.HasPrefix(name, "{{ $m.Location  }}") {
          resp.{{ exportable $name }}[name] = httpResp.Header.Get(name)
        }
      }
      {{ else if ne $m.Location "" }}
      // TODO: add support for extracting output members from {{ $m.Location }} to support {{ exportable $name }}
      {{ end }}

    {{ end }}
  {{ end }}
  {{ end }}
  {{ else }}
  defer httpResp.Body.Close()
  {{ end }}

  return
}

{{ end }}

{{ range $name, $s := .Shapes }}
{{ if eq $s.ShapeType "structure" }}
{{ if not $s.Exception }}

// {{ exportable $name }} is undocumented.
type {{ exportable $name }} struct {
{{ range $name, $m := $s.Members }}
{{ exportable $name }} {{ $m.Type }} {{ $m.XMLTag $s.ResultWrapper }}  {{ end }}
}

{{ end }}
{{ end }}
{{ end }}

{{ template "footer" }}
var _ bytes.Reader
var _ url.URL
var _ fmt.Stringer
var _ strings.Reader
var _ strconv.NumError
var _ = ioutil.Discard
{{ end }}

#################### QUERY CLIENT

{{ define "query" }}
{{ template "header" $ }}

// {{ .Name }} is a client for {{ .FullName }}.
type {{ .Name }} struct {
  client *aws.QueryClient
}

// New returns a new {{ .Name }} client.
func New(key, secret, region string, client *http.Client) *{{ .Name }} {
  if client == nil {
     client = http.DefaultClient
  }

  service := "{{ .Metadata.EndpointPrefix }}"
  endpoint, service, region := endpoints.Lookup("{{ .Metadata.EndpointPrefix }}", region)

  return &{{ .Name }}{
    client: &aws.QueryClient{
      Signer: &aws.V4Signer{
        Key: key,
        Secret: secret,
        Service: service,
        Region: region,
        IncludeXAmzContentSha256: true,
      },
      Client: client,
      Endpoint: endpoint,
      APIVersion: "{{ .Metadata.APIVersion }}",
    },
  }
}

{{ range $name, $op := .Operations }}

{{ godoc $name $op.Documentation }} func (c *{{ $.Name }}) {{ exportable $name }}({{ if $op.InputRef }}req {{ exportable $op.InputRef.WrappedType }}{{ end }}) ({{ if $op.OutputRef }}resp *{{ exportable $op.OutputRef.WrappedType }},{{ end }} err error) {
  {{ if $op.Output }}resp = &{{ exportable $op.OutputRef.WrappedType }}{}{{ else }}// NRE{{ end }}
  err = c.client.Do("{{ $name }}", "{{ $op.HTTP.Method }}", "{{ $op.HTTP.RequestURI }}", {{ if $op.Input }} req {{ else }} nil {{ end }}, {{ if $op.Output }} resp {{ else }} nil {{ end }})
  return
}

{{ end }}

{{ range $name, $s := .Shapes }}
{{ if eq $s.ShapeType "structure" }}
{{ if not $s.Exception }}

// {{ exportable $name }} is undocumented.
type {{ exportable $name }} struct {
{{ range $name, $m := $s.Members }}
{{ exportable $name }} {{ $m.Type }} {{ $m.XMLTag $s.ResultWrapper }}  {{ end }}
}

{{ end }}
{{ end }}
{{ end }}

{{ range $wname, $s := .Wrappers }}

// {{ exportable $wname }} is a wrapper for {{ $s.Name }}.
type {{ exportable $wname }} struct {
    XMLName xml.Name {{ $s.MessageTag }}
{{ range $name, $m := $s.Members }}
{{ exportable $name }} {{ $m.Type }} {{ $m.XMLTag $wname }}  {{ end }}
}

{{ end }}

{{ template "footer" }}
{{ end }}

#################### JSON CLIENT

{{ define "json" }}
{{ template "header" $ }}

// {{ .Name }} is a client for {{ .FullName }}.
type {{ .Name }} struct {
  client *aws.JSONClient
}

// New returns a new {{ .Name }} client.
func New(key, secret, region string, client *http.Client) *{{ .Name }} {
  if client == nil {
     client = http.DefaultClient
  }

  service := "{{ .Metadata.EndpointPrefix }}"
  endpoint, service, region := endpoints.Lookup("{{ .Metadata.EndpointPrefix }}", region)

  return &{{ .Name }}{
    client: &aws.JSONClient{
      Signer: &aws.V4Signer{
        Key: key,
        Secret: secret,
        Service: service,
        Region: region,
        IncludeXAmzContentSha256: true,
      },
      Client: client,
      Endpoint: endpoint,
      JSONVersion: "{{ .Metadata.JSONVersion }}",
      TargetPrefix: "{{ .Metadata.TargetPrefix }}",
    },
  }
}

{{ range $name, $op := .Operations }}

{{ godoc $name $op.Documentation }} func (c *{{ $.Name }}) {{ exportable $name }}({{ if $op.Input }}req {{ exportable $op.Input.Type }}{{ end }}) ({{ if $op.Output }}resp *{{ exportable $op.Output.Type }},{{ end }} err error) {
  {{ if $op.Output }}resp = &{{ $op.Output.Type }}{}{{ else }}// NRE{{ end }}
  err = c.client.Do("{{ $name }}", "{{ $op.HTTP.Method }}", "{{ $op.HTTP.RequestURI }}", {{ if $op.Input }} req {{ else }} nil {{ end }}, {{ if $op.Output }} resp {{ else }} nil {{ end }})
  return
}

{{ end }}

{{ range $name, $s := .Shapes }}
{{ if eq $s.ShapeType "structure" }}
{{ if not $s.Exception }}

// {{ exportable $name }} is undocumented.
type {{ exportable $name }} struct {
{{ range $name, $m := $s.Members }}
{{ exportable $name }} {{ $m.Type }} {{ $m.JSONTag }}  {{ end }}
}

{{ end }}
{{ end }}
{{ end }}

{{ template "footer" }}
{{ end }}

#################### COMMON TEMPLATES

{{ define "header" }}
// Package {{ .PackageName }} provides a client for {{ .FullName }}.
package {{ .PackageName }}

import (
  "encoding/xml"
  "net/http"
  "time"

  "github.com/stripe/aws-go/aws"
  "github.com/stripe/aws-go/aws/gen/endpoints"
)

{{ end }}

{{ define "footer" }}
// avoid errors if the packages aren't referenced
var _ time.Time
var _ xml.Name
{{ end }}
`
)
<commit_msg>Clean up templating a bit.<commit_after>package model

import (
	"bytes"
	"fmt"
	"go/format"
	"io"
	"os"
	"text/template"
)

// TODO: support client-side validation
// TODO: support enum values
// TODO: support exceptions

func Generate(w io.Writer) error {
	t := template.New("root").Funcs(template.FuncMap{
		"godoc":      godoc,
		"exportable": exportable,
	})
	template.Must(common(t))
	template.Must(jsonClient(t))
	template.Must(queryClient(t))
	template.Must(restXMLClient(t))

	out := bytes.NewBuffer(nil)
	if err := t.ExecuteTemplate(out, service.Metadata.Protocol, service); err != nil {
		return err
	}

	b, err := format.Source(out.Bytes())
	if err != nil {
		fmt.Fprint(os.Stderr, out.String())
		return err
	}

	_, err = io.Copy(w, bytes.NewReader(b))
	return err
}

func common(t *template.Template) (*template.Template, error) {
	return t.Parse(`
{{ define "header" }}
// Package {{ .PackageName }} provides a client for {{ .FullName }}.
package {{ .PackageName }}

import (
  "encoding/xml"
  "net/http"
  "time"

  "github.com/stripe/aws-go/aws"
  "github.com/stripe/aws-go/aws/gen/endpoints"
)

{{ end }}

{{ define "footer" }}
// avoid errors if the packages aren't referenced
var _ time.Time
var _ xml.Name
{{ end }}

`)
}

func jsonClient(t *template.Template) (*template.Template, error) {
	return t.Parse(`
{{ define "json" }}
{{ template "header" $ }}

// {{ .Name }} is a client for {{ .FullName }}.
type {{ .Name }} struct {
  client *aws.JSONClient
}

// New returns a new {{ .Name }} client.
func New(key, secret, region string, client *http.Client) *{{ .Name }} {
  if client == nil {
     client = http.DefaultClient
  }

  service := "{{ .Metadata.EndpointPrefix }}"
  endpoint, service, region := endpoints.Lookup("{{ .Metadata.EndpointPrefix }}", region)

  return &{{ .Name }}{
    client: &aws.JSONClient{
      Signer: &aws.V4Signer{
        Key: key,
        Secret: secret,
        Service: service,
        Region: region,
        IncludeXAmzContentSha256: true,
      },
      Client: client,
      Endpoint: endpoint,
      JSONVersion: "{{ .Metadata.JSONVersion }}",
      TargetPrefix: "{{ .Metadata.TargetPrefix }}",
    },
  }
}

{{ range $name, $op := .Operations }}

{{ godoc $name $op.Documentation }} func (c *{{ $.Name }}) {{ exportable $name }}({{ if $op.Input }}req {{ exportable $op.Input.Type }}{{ end }}) ({{ if $op.Output }}resp *{{ exportable $op.Output.Type }},{{ end }} err error) {
  {{ if $op.Output }}resp = &{{ $op.Output.Type }}{}{{ else }}// NRE{{ end }}
  err = c.client.Do("{{ $name }}", "{{ $op.HTTP.Method }}", "{{ $op.HTTP.RequestURI }}", {{ if $op.Input }} req {{ else }} nil {{ end }}, {{ if $op.Output }} resp {{ else }} nil {{ end }})
  return
}

{{ end }}

{{ range $name, $s := .Shapes }}
{{ if eq $s.ShapeType "structure" }}
{{ if not $s.Exception }}

// {{ exportable $name }} is undocumented.
type {{ exportable $name }} struct {
{{ range $name, $m := $s.Members }}
{{ exportable $name }} {{ $m.Type }} {{ $m.JSONTag }}  {{ end }}
}

{{ end }}
{{ end }}
{{ end }}

{{ template "footer" }}
{{ end }}

`)
}

func queryClient(t *template.Template) (*template.Template, error) {
	return t.Parse(`
{{ define "query" }}
{{ template "header" $ }}

// {{ .Name }} is a client for {{ .FullName }}.
type {{ .Name }} struct {
  client *aws.QueryClient
}

// New returns a new {{ .Name }} client.
func New(key, secret, region string, client *http.Client) *{{ .Name }} {
  if client == nil {
     client = http.DefaultClient
  }

  service := "{{ .Metadata.EndpointPrefix }}"
  endpoint, service, region := endpoints.Lookup("{{ .Metadata.EndpointPrefix }}", region)

  return &{{ .Name }}{
    client: &aws.QueryClient{
      Signer: &aws.V4Signer{
        Key: key,
        Secret: secret,
        Service: service,
        Region: region,
        IncludeXAmzContentSha256: true,
      },
      Client: client,
      Endpoint: endpoint,
      APIVersion: "{{ .Metadata.APIVersion }}",
    },
  }
}

{{ range $name, $op := .Operations }}

{{ godoc $name $op.Documentation }} func (c *{{ $.Name }}) {{ exportable $name }}({{ if $op.InputRef }}req {{ exportable $op.InputRef.WrappedType }}{{ end }}) ({{ if $op.OutputRef }}resp *{{ exportable $op.OutputRef.WrappedType }},{{ end }} err error) {
  {{ if $op.Output }}resp = &{{ exportable $op.OutputRef.WrappedType }}{}{{ else }}// NRE{{ end }}
  err = c.client.Do("{{ $name }}", "{{ $op.HTTP.Method }}", "{{ $op.HTTP.RequestURI }}", {{ if $op.Input }} req {{ else }} nil {{ end }}, {{ if $op.Output }} resp {{ else }} nil {{ end }})
  return
}

{{ end }}

{{ range $name, $s := .Shapes }}
{{ if eq $s.ShapeType "structure" }}
{{ if not $s.Exception }}

// {{ exportable $name }} is undocumented.
type {{ exportable $name }} struct {
{{ range $name, $m := $s.Members }}
{{ exportable $name }} {{ $m.Type }} {{ $m.XMLTag $s.ResultWrapper }}  {{ end }}
}

{{ end }}
{{ end }}
{{ end }}

{{ range $wname, $s := .Wrappers }}

// {{ exportable $wname }} is a wrapper for {{ $s.Name }}.
type {{ exportable $wname }} struct {
    XMLName xml.Name {{ $s.MessageTag }}
{{ range $name, $m := $s.Members }}
{{ exportable $name }} {{ $m.Type }} {{ $m.XMLTag $wname }}  {{ end }}
}

{{ end }}

{{ template "footer" }}
{{ end }}

`)
}

func restXMLClient(t *template.Template) (*template.Template, error) {
	return t.Parse(`
{{ define "rest-xml" }}
{{ template "header" $ }}

import (
  "bytes"
  "fmt"
  "io"
  "io/ioutil"
  "net/url"
  "strconv"
  "strings"
)

// {{ .Name }} is a client for {{ .FullName }}.
type {{ .Name }} struct {
  client *aws.RestXMLClient
}

// New returns a new {{ .Name }} client.
func New(key, secret, region string, client *http.Client) *{{ .Name }} {
  if client == nil {
     client = http.DefaultClient
  }

  service := "{{ .Metadata.EndpointPrefix }}"
  endpoint, service, region := endpoints.Lookup("{{ .Metadata.EndpointPrefix }}", region)

  return &{{ .Name }}{
    client: &aws.RestXMLClient{
      Signer: &aws.V4Signer{
        Key: key,
        Secret: secret,
        Service: service,
        Region: region,
        IncludeXAmzContentSha256: true,
      },
      Client: client,
      Endpoint: endpoint,
      APIVersion: "{{ .Metadata.APIVersion }}",
    },
  }
}

{{ range $name, $op := .Operations }}

{{ godoc $name $op.Documentation }} func (c *{{ $.Name }}) {{ exportable $name }}({{ if $op.Input }}req {{ exportable $op.Input.Type }}{{ end }}) ({{ if $op.Output }}resp *{{ exportable $op.Output.Type }},{{ end }} err error) {
  {{ if $op.Output }}resp = &{{ $op.Output.Type }}{}{{ else }}// NRE{{ end }}

  var body io.Reader
  {{ if $op.Input }}
  {{ if $op.Input.Payload }}
  {{ with $m := index $op.Input.Members $op.Input.Payload }}
  {{ if $m.Streaming }}
  body = req.{{ exportable $m.Name  }}
  {{ else }}
  b, err := xml.Marshal(req.{{ exportable $m.Name  }})
  if err != nil {
    return
  }
  body = bytes.NewReader(b)
  {{ end }}
  {{ end }}
  {{ end }}
  {{ end }}

  uri := c.client.Endpoint + "{{ $op.HTTP.RequestURI }}"
  {{ if $op.Input }}
  {{ range $name, $m := $op.Input.Members }}
  {{ if eq $m.Location "uri" }}

  uri = strings.Replace(uri, "{"+"{{ $m.LocationName }}"+"}", req.{{ exportable $name }}, -1)
  uri = strings.Replace(uri, "{"+"{{ $m.LocationName }}+"+"}", req.{{ exportable $name }}, -1)

  {{ end }}
  {{ end }}
  {{ end }}

  q := url.Values{}

  {{ if $op.Input }}
  {{ range $name, $m := $op.Input.Members }}
  {{ if eq $m.Location "querystring" }}

  {{ if eq $m.Shape.ShapeType "string" }}
  if s := req.{{ exportable $name }}; s != "" {
  {{ else if eq $m.Shape.ShapeType "timestamp" }}
  if s := req.{{ exportable $name }}.Format(time.RFC822); s != "01 Jan 01 00:00 UTC" {
  {{ else if eq $m.Shape.ShapeType "integer" }}
  if s := strconv.Itoa(req.{{ exportable $name }}); req.{{ exportable $name }} != 0 {
  {{ else }}
  if s := fmt.Sprintf("%v", req.{{ exportable $name }}); s != "" {
  {{ end }}
    q.Set("{{ $m.LocationName }}", s)
  }

  {{ end }}
  {{ end }}
  {{ end }}

  if len(q) > 0 {
    uri += "?" + q.Encode()
  }

  httpReq, err := http.NewRequest("{{ $op.HTTP.Method }}", uri, body)
  if err != nil {
    return
  }
  {{ if $op.Input }}
  {{ range $name, $m := $op.Input.Members }}
  {{ if eq $m.Location "header" }}

  {{ if eq $m.Shape.ShapeType "string" }}
  if s := req.{{ exportable $name }}; s != "" {
  {{ else if eq $m.Shape.ShapeType "timestamp" }}
  if s := req.{{ exportable $name }}.Format(time.RFC822); s != "01 Jan 01 00:00 UTC" {
  {{ else if eq $m.Shape.ShapeType "integer" }}
  if s := strconv.Itoa(req.{{ exportable $name }}); req.{{ exportable $name }} != 0 {
  {{ else }}
  if s := fmt.Sprintf("%v", req.{{ exportable $name }}); s != "" {
  {{ end }}
    httpReq.Header.Set("{{ $m.LocationName }}", s)
  }

  {{ end }}
  {{ end }}
  {{ end }}

  httpResp, err := c.client.Do(httpReq)
  if err != nil {
    return
  }

  {{ if $op.Output }}
    {{ with $name := "Body" }}
    {{ with $m := index $op.Output.Members $name }}
    {{ if $m }}

      {{ if $m.Streaming }}
  resp.Body = httpResp.Body
      {{ else }}
  defer httpResp.Body.Close()
  err = xml.NewDecoder(httpResp.Body).Decode(resp)
      {{ end }}

    {{ else }}
  defer httpResp.Body.Close()
    {{ end }}
    {{ end }}

  {{ range $name, $m := $op.Output.Members }}
    {{ if ne $name "Body" }}
      {{ if eq $m.Location "header" }}
        if s := httpResp.Header.Get("{{ $m.LocationName }}"); s != "" {
         {{ if eq $m.Shape.ShapeType "string" }}
          resp.{{ exportable $name }} = s
         {{ else if eq $m.Shape.ShapeType "timestamp" }}
          if t, e := time.Parse(s, time.RFC822); e != nil {
           err = e
           return
          } else {
           resp.{{ exportable $name }} = t
          }
         {{ else if eq $m.Shape.ShapeType "integer" }}
          if n, e := strconv.Atoi(s); e != nil {
           err = e
           return
          } else {
           resp.{{ exportable $name }} = n
          }
         {{ else if eq $m.Shape.ShapeType "boolean" }}
         if v, e := strconv.ParseBool(s); e != nil {
           err = e
           return
          } else {
           resp.{{ exportable $name }} = v
          }
         {{ else }}
         // TODO: add support for {{ $m.Shape.ShapeType }} headers
         {{ end }}
        }
      {{ else if eq $m.Location "headers" }}
      resp.{{ exportable $name }} = {{ $m.Shape.Type }}{}
      for name := range httpResp.Header {
        if strings.HasPrefix(name, "{{ $m.Location  }}") {
          resp.{{ exportable $name }}[name] = httpResp.Header.Get(name)
        }
      }
      {{ else if ne $m.Location "" }}
      // TODO: add support for extracting output members from {{ $m.Location }} to support {{ exportable $name }}
      {{ end }}

    {{ end }}
  {{ end }}
  {{ end }}
  {{ else }}
  defer httpResp.Body.Close()
  {{ end }}

  return
}

{{ end }}

{{ range $name, $s := .Shapes }}
{{ if eq $s.ShapeType "structure" }}
{{ if not $s.Exception }}

// {{ exportable $name }} is undocumented.
type {{ exportable $name }} struct {
{{ range $name, $m := $s.Members }}
{{ exportable $name }} {{ $m.Type }} {{ $m.XMLTag $s.ResultWrapper }}  {{ end }}
}

{{ end }}
{{ end }}
{{ end }}

{{ template "footer" }}
var _ bytes.Reader
var _ url.URL
var _ fmt.Stringer
var _ strings.Reader
var _ strconv.NumError
var _ = ioutil.Discard
{{ end }}

`)
}
<|endoftext|>


<commit_before>package model

import (
	"bytes"
	"go/format"
	"io"
	"os"
	"path"
	"text/template"
)

// Generate writes a Go file with a client for using the parsed service.
func Generate(prefix string, forceService bool) error {
	pkg := service.PackageName()
	pkgDir := path.Join(prefix, pkg)
	os.MkdirAll(pkgDir, 0775)

	apiFile := path.Join(pkgDir, "api.go")
	apiWriter, err := os.Create(apiFile)
	if err != nil {
		panic(err)
	}
	defer apiWriter.Close()

	var svcWriter io.WriteCloser
	svcFile := path.Join(pkgDir, "service.go")
	if _, err := os.Stat(svcFile); forceService || (err != nil && os.IsNotExist(err)) {
		svcWriter, err = os.Create(svcFile)
		if err != nil {
			panic(err)
		}
		defer svcWriter.Close()
	}

	return generateSource(apiWriter, svcWriter)
}

func generateSource(api io.Writer, svc io.Writer) error {
	t := template.New("root").Funcs(template.FuncMap{
		"godoc":            godoc,
		"exportable":       exportable,
		"structName":       structName,
		"enumList":         enumList,
		"shapeList":        shapeList,
		"shapeAlias":       shapeAlias,
		"protocolPackage":  protocolPackage,
		"requiredTraits":   requiredTraits,
		"locationTraits":   locationTraits,
		"hasRequiredTrait": hasRequiredTrait,
	})
	template.Must(commonAPI(t))
	template.Must(queryClient(t))
	template.Must(ec2Client(t))

	if api != nil {
		apiOut := new(bytes.Buffer)
		if err := t.ExecuteTemplate(apiOut, "api", service); err != nil {
			return err
		}
		apiFormatted, err := format.Source(apiOut.Bytes())
		if err != nil {
			return err
		}
		_, err = api.Write(apiFormatted)
		if err != nil {
			_, _ = api.Write(apiOut.Bytes())
			return err
		}
	}

	if svc != nil {
		svcOut := new(bytes.Buffer)
		if err := t.ExecuteTemplate(svcOut, "service", service); err != nil {
			return err
		}

		svcFormatted, err := format.Source(svcOut.Bytes())
		if err != nil {
			return err
		}

		_, err = svc.Write(svcFormatted)
		if err != nil {
			_, _ = svc.Write(svcOut.Bytes())
			return err
		}
	}

	return nil
}

func commonAPI(t *template.Template) (*template.Template, error) {
	return t.Parse(`
{{ define "service" }}
package {{ .PackageName }}

import (
    "github.com/awslabs/aws-sdk-go/aws"
    "github.com/awslabs/aws-sdk-go/aws/signer/v4"
    "github.com/awslabs/aws-sdk-go/aws/protocol/{{ protocolPackage $.Metadata.Protocol }}"
)

// {{ .Name }} is a client for {{ .FullName }}.
type {{ .Name }} struct {
    *aws.Service
}

type {{ .Name }}Config struct {
    *aws.Config
}

// New returns a new {{ .Name }} client.
func New(config *{{ .Name }}Config) *{{ .Name }} {
  if config == nil {
    config = &{{ .Name }}Config{}
  }

  service := &aws.Service{
    Config:       aws.DefaultConfig.Merge(config.Config),
    ServiceName:  "{{ .Metadata.EndpointPrefix }}",
    APIVersion:   "{{ .Metadata.APIVersion }}",
{{ if $.Metadata.Protocol eq "json" }}JSONVersion:  "{{ .Metadata.JSONVersion }}",
    TargetPrefix: "{{ .Metadata.TargetPrefix }}",
{{ end }}
  }
  service.Initialize()

  // Handlers
  service.Handlers.Sign.PushBack(v4.Sign)
  service.Handlers.Build.PushBack({{ protocolPackage $.Metadata.Protocol }}.Build)
  service.Handlers.Unmarshal.PushBack({{ protocolPackage $.Metadata.Protocol }}.Unmarshal)

  return &{{ .Name }}{service}
}
{{ end }}

{{ define "header" }}
////////////////////////////////////////////////////////
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. //
////////////////////////////////////////////////////////

{{ godoc .Name .Documentation }} package {{ .PackageName }}

import (
  "time"

  "github.com/awslabs/aws-sdk-go/aws"
)

{{ end }}

{{ define "footer" }}
// avoid errors if the packages aren't referenced
var _ time.Time
{{ end }}

{{ define "operations" }}

{{ range $name, $op := .Operations }}

// {{ exportable $name }}Request generates a request for the {{ exportable $name }} operation.
func (c *{{ $.Name }}) {{ exportable $name }}Request({{ if $op.Input }}input {{ $op.Input.Type }}{{ end }}) (req *aws.Request{{ if $op.Output }}, output {{ structName $op.Output.Type }}{{ end }}) {
    if op{{ exportable $name }} == nil {
      op{{ exportable $name }} = &aws.Operation{
        Name:       "{{ $name }}",
        HTTPMethod: "{{ $op.HTTP.Method }}",
        HTTPPath:   "{{ $op.HTTP.RequestURI }}",
        {{ if eq $.Metadata.Protocol "rest-xml" "rest-json" }}
        OperationBindings: &aws.OperationBindings{
          {{ if $op.Input }}  InPayload:   "{{ $op.Input.Payload }}", {{ end }}
          {{ if $op.Output }} OutPayload:  "{{ $op.Output.Payload }}", {{ end }}
          Required:    []string{ {{ requiredTraits $op.Input }} },
          QueryParams: []string{ {{ locationTraits "query" $op.Input }} },
          URIParams:   []string{ {{ locationTraits "uri" $op.Input }} },
          InHeaders:   []string{ {{ locationTraits "header" $op.Input }} },
          OutHeaders:  []string{ {{ locationTraits "header" $op.Output }} },
        }, {{ else if hasRequiredTrait $op.Input }}
        OperationBindings: &aws.OperationBindings{
          Required:    []string{ {{ requiredTraits $op.Input }} },
        }, {{ end }}
      }
    }

    req = aws.NewRequest(c.Service, op{{ exportable $name }}, {{ if $op.Input }}input{{ else }}nil{{ end }}, {{ if $op.Output }}output{{ else }}nil{{ end }})
    {{ if $op.Output }}output = {{ structName $op.Output.Literal }}
    req.Data = output{{ end }}
    return
}

{{ godoc $name $op.Documentation }} func (c *{{ $.Name }}) {{ exportable $name }}({{ if $op.Input }}input {{ $op.Input.Type }}{{ end }}) ({{ if $op.Output }}output {{ structName $op.Output.Type }},{{ end }} err error) {
  req{{ if $op.Output }}, out{{ end }} := c.{{ exportable $name }}Request({{ if $op.Input }}input{{ end }})
  {{ if $op.Output }}output = out
  {{ end }}err = req.Send()
  return
}

{{ end }}

var (
{{ range $name, $op := .Operations }}op{{ exportable $name }} *aws.Operation
{{ end }}
)

{{ range $_, $s := enumList }}
// Possible values for {{ exportable $s.Alias }}.
const (
    {{ range $name, $value := $s.Shape.Enums }}
    {{ $name }} = {{ $value }}{{ end }}
)
{{ end }}

{{ end }}

{{ define "shapes" }}

{{ range $_, $s := shapeList }}
{{ if eq $s.Shape.ShapeType "structure" }}

// {{ $s.Alias }} is undocumented.
type {{ $s.Alias }} struct {
{{ range $name, $m := $s.Shape.Members }}
{{ exportable $name }} {{ $m.Shape.Type }} {{ $m.Tag $.Metadata.Protocol $name }}  {{ end }}
}

{{ end }}
{{ end }}

{{ end }}

{{ define "api" }}
{{ template "header" $ }}
{{ template "operations" $ }}
{{ template "shapes" $ }}
{{ template "footer" }}
{{ end }}
`)
}

func queryClient(t *template.Template) (*template.Template, error) {
	return t.Parse(`
{{ define "query" }}
{{ template "header" $ }}

import (
	"io"
	"encoding/xml"
)

{{ template "operations" $ }}

{{ range $name, $s := .Shapes }}
{{ if eq $s.ShapeType "map" }}

type {{ exportable $name }} map[{{ $s.Key.ElementType }}]{{ $s.Value.ElementType }}

// UnmarshalXML implements xml.UnmarshalXML interface for map
func (m *{{ exportable $name }}) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
	if *m == nil {
		(*m) = make({{ exportable $name }})
	}
	for {
		var e struct {
			{{ or $s.KeyRef.LocationName "Key" }} {{ $s.Key.ElementType }} {{ $s.KeyXMLTag }}
			{{ or $s.ValueRef.LocationName "Value" }} {{ $s.Value.ElementType }} {{ $s.ValueXMLTag }}
		}
		err := d.DecodeElement(&e, &start)
		if err != nil && err != io.EOF {
			return err
		}
		if err == io.EOF {
			break
		}
		(*m)[e.{{ or $s.KeyRef.LocationName "Key" }}] = e.{{ or $s.ValueRef.LocationName "Value" }}
	}
	return nil
}
{{ end }}

{{ if eq $s.ShapeType "structure" }}

// {{ exportable $name }} is undocumented.
type {{ structName $name }} struct {
{{ range $name, $m := $s.Members }}
{{ exportable $name }} {{ $m.Type }} {{ $m.QueryTag $s.ResultWrapper }}  {{ end }}
}

{{ end }}
{{ end }}

{{ range $wname, $s := .Wrappers }}

// {{ exportable $wname }} is a wrapper for {{ $s.Name }}.
type {{ exportable $wname }} struct {
{{ range $name, $m := $s.Members }}
{{ exportable $name }} {{ $m.Type }} {{ $m.QueryTag $wname }}  {{ end }}
}

{{ end }}

{{ template "footer" }}
var _ xml.Decoder
var _ = io.EOF
{{ end }}

`)
}

func ec2Client(t *template.Template) (*template.Template, error) {
	return t.Parse(`
{{ define "ec2" }}
{{ template "header" $ }}

// {{ .Name }} is a client for {{ .FullName }}.
type {{ .Name }} struct {
  client *aws.EC2Client
}

// New returns a new {{ .Name }} client.
func New(creds aws.CredentialsProvider, region string, client *http.Client) *{{ .Name }} {
  if client == nil {
     client = http.DefaultClient
  }

  endpoint, service, region := endpoints.Lookup("{{ .Metadata.EndpointPrefix }}", region)

  return &{{ .Name }}{
    client: &aws.EC2Client{
      Context: aws.Context{
        Credentials: creds,
        Service: service,
        Region: region,
      },
      Client: client,
      Endpoint: endpoint,
      APIVersion: "{{ .Metadata.APIVersion }}",
    },
  }
}

{{ range $name, $op := .Operations }}

{{ godoc $name $op.Documentation }} func (c *{{ $.Name }}) {{ exportable $name }}({{ if $op.InputRef }}req {{ $op.InputRef.WrappedType }}{{ end }}) ({{ if $op.OutputRef }}resp {{ $op.OutputRef.WrappedType }},{{ end }} err error) {
  {{ if $op.Output }}resp = {{ $op.OutputRef.WrappedLiteral }}{{ else }}// NRE{{ end }}
  err = c.client.Do("{{ $name }}", "{{ $op.HTTP.Method }}", "{{ $op.HTTP.RequestURI }}", {{ if $op.Input }} req {{ else }} nil {{ end }}, {{ if $op.Output }} resp {{ else }} nil {{ end }})
  return
}

{{ end }}

{{ range $name, $s := .Shapes }}
{{ if eq $s.ShapeType "structure" }}

// {{ exportable $name }} is undocumented.
type {{ exportable $name }} struct {
{{ range $name, $m := $s.Members }}
{{ exportable $name }} {{ $m.Type }} {{ $m.EC2Tag }}  {{ end }}
}

{{ end }}
{{ end }}

{{ range $wname, $s := .Wrappers }}

// {{ exportable $wname }} is a wrapper for {{ $s.Name }}.
type {{ exportable $wname }} struct {
{{ range $name, $m := $s.Members }}
{{ exportable $name }} {{ $m.Type }} {{ $m.EC2Tag }}  {{ end }}
}

{{ end }}

{{ template "footer" }}
{{ end }}

`)
}
<commit_msg>Cleanup associated templates into separate function for readability<commit_after>package model

import (
	"bytes"
	"go/format"
	"io"
	"os"
	"path"
	"text/template"
)

// Generate writes a Go file with a client for using the parsed service.
func Generate(prefix string, forceService bool) error {
	pkg := service.PackageName()
	pkgDir := path.Join(prefix, pkg)
	os.MkdirAll(pkgDir, 0775)

	apiFile := path.Join(pkgDir, "api.go")
	apiWriter, err := os.Create(apiFile)
	if err != nil {
		panic(err)
	}
	defer apiWriter.Close()

	var svcWriter io.WriteCloser
	svcFile := path.Join(pkgDir, "service.go")
	if _, err := os.Stat(svcFile); forceService || (err != nil && os.IsNotExist(err)) {
		svcWriter, err = os.Create(svcFile)
		if err != nil {
			panic(err)
		}
		defer svcWriter.Close()
	}

	return generateSource(apiWriter, svcWriter)
}

func generateSource(api io.Writer, svc io.Writer) error {
	fmap := template.FuncMap{
		"godoc":            godoc,
		"exportable":       exportable,
		"structName":       structName,
		"enumList":         enumList,
		"shapeList":        shapeList,
		"shapeAlias":       shapeAlias,
		"protocolPackage":  protocolPackage,
		"requiredTraits":   requiredTraits,
		"locationTraits":   locationTraits,
		"hasRequiredTrait": hasRequiredTrait,
	}

	apiTemplate := template.New("api-root").Funcs(fmap)
	template.Must(tplAPI(apiTemplate))

	svcTemplate := template.New("service-root").Funcs(fmap)
	template.Must(tplService(svcTemplate))

	if api != nil {
		apiOut := new(bytes.Buffer)
		if err := apiTemplate.Execute(apiOut, service); err != nil {
			return err
		}
		apiFormatted, err := format.Source(apiOut.Bytes())
		if err != nil {
			return err
		}
		_, err = api.Write(apiFormatted)
		if err != nil {
			_, _ = api.Write(apiOut.Bytes())
			return err
		}
	}

	if svc != nil {
		svcOut := new(bytes.Buffer)
		if err := svcTemplate.Execute(svcOut, service); err != nil {
			return err
		}

		svcFormatted, err := format.Source(svcOut.Bytes())
		if err != nil {
			return err
		}

		_, err = svc.Write(svcFormatted)
		if err != nil {
			_, _ = svc.Write(svcOut.Bytes())
			return err
		}
	}

	return nil
}

func tplService(t *template.Template) (*template.Template, error) {
	return t.Parse(`
package {{ .PackageName }}

import (
    "github.com/awslabs/aws-sdk-go/aws"
    "github.com/awslabs/aws-sdk-go/aws/signer/v4"
    "github.com/awslabs/aws-sdk-go/aws/protocol/{{ protocolPackage .Metadata.Protocol }}"
)

// {{ .Name }} is a client for {{ .FullName }}.
type {{ .Name }} struct {
    *aws.Service
}

type {{ .Name }}Config struct {
    *aws.Config
}

// New returns a new {{ .Name }} client.
func New(config *{{ .Name }}Config) *{{ .Name }} {
  if config == nil {
    config = &{{ .Name }}Config{}
  }

  service := &aws.Service{
    Config:       aws.DefaultConfig.Merge(config.Config),
    ServiceName:  "{{ .Metadata.EndpointPrefix }}",
    APIVersion:   "{{ .Metadata.APIVersion }}",
{{ if eq .Metadata.Protocol "json" }}JSONVersion:  "{{ .Metadata.JSONVersion }}",
    TargetPrefix: "{{ .Metadata.TargetPrefix }}",
{{ end }}
  }
  service.Initialize()

  // Handlers
  service.Handlers.Sign.PushBack(v4.Sign)
  service.Handlers.Build.PushBack({{ protocolPackage .Metadata.Protocol }}.Build)
  service.Handlers.Unmarshal.PushBack({{ protocolPackage .Metadata.Protocol }}.Unmarshal)

  return &{{ .Name }}{service}
}
`)
}

func tplAPI(t *template.Template) (*template.Template, error) {
	template.Must(tplAPIHeader(t))
	template.Must(tplAPIOperations(t))
	template.Must(tplAPIShapes(t))
	template.Must(tplAPIFooter(t))
	return t.Parse(`
{{ template "api-header" $ }}
{{ template "api-operations" $ }}
{{ template "api-shapes" $ }}
{{ template "api-footer" }}
`)
}

func tplAPIHeader(t *template.Template) (*template.Template, error) {
	return t.Parse(`
{{ define "api-header" }}
////////////////////////////////////////////////////////
// THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. //
////////////////////////////////////////////////////////

{{ godoc .Name .Documentation }} package {{ .PackageName }}

import (
  "time"

  "github.com/awslabs/aws-sdk-go/aws"
)

{{ end }}
`)
}

func tplAPIFooter(t *template.Template) (*template.Template, error) {
	return t.Parse(`
{{ define "api-footer" }}
// avoid errors if the packages aren't referenced
var _ time.Time
var _ xml.Decoder
var _ = io.EOF
{{ end }}
`)
}

func tplAPIOperations(t *template.Template) (*template.Template, error) {
	return t.Parse(`
{{ define "api-operations" }}

{{ range $name, $op := .Operations }}

// {{ exportable $name }}Request generates a request for the {{ exportable $name }} operation.
func (c *{{ $.Name }}) {{ exportable $name }}Request({{ if $op.Input }}input {{ $op.Input.Type }}{{ end }}) (req *aws.Request{{ if $op.Output }}, output {{ structName $op.Output.Type }}{{ end }}) {
    if op{{ exportable $name }} == nil {
      op{{ exportable $name }} = &aws.Operation{
        Name:       "{{ $name }}",
        HTTPMethod: "{{ $op.HTTP.Method }}",
        HTTPPath:   "{{ $op.HTTP.RequestURI }}",
        {{ if eq $.Metadata.Protocol "rest-xml" "rest-json" }}
        OperationBindings: &aws.OperationBindings{
          {{ if $op.Input }}  InPayload:   "{{ $op.Input.Payload }}", {{ end }}
          {{ if $op.Output }} OutPayload:  "{{ $op.Output.Payload }}", {{ end }}
          Required:    []string{ {{ requiredTraits $op.Input }} },
          QueryParams: []string{ {{ locationTraits "query" $op.Input }} },
          URIParams:   []string{ {{ locationTraits "uri" $op.Input }} },
          InHeaders:   []string{ {{ locationTraits "header" $op.Input }} },
          OutHeaders:  []string{ {{ locationTraits "header" $op.Output }} },
        }, {{ else if hasRequiredTrait $op.Input }}
        OperationBindings: &aws.OperationBindings{
          Required:    []string{ {{ requiredTraits $op.Input }} },
        }, {{ end }}
      }
    }

    req = aws.NewRequest(c.Service, op{{ exportable $name }}, {{ if $op.Input }}input{{ else }}nil{{ end }}, {{ if $op.Output }}output{{ else }}nil{{ end }})
    {{ if $op.Output }}output = {{ structName $op.Output.Literal }}
    req.Data = output{{ end }}
    return
}

{{ godoc $name $op.Documentation }} func (c *{{ $.Name }}) {{ exportable $name }}({{ if $op.Input }}input {{ $op.Input.Type }}{{ end }}) ({{ if $op.Output }}output {{ structName $op.Output.Type }},{{ end }} err error) {
  req{{ if $op.Output }}, out{{ end }} := c.{{ exportable $name }}Request({{ if $op.Input }}input{{ end }})
  {{ if $op.Output }}output = out
  {{ end }}err = req.Send()
  return
}

{{ end }}

var (
{{ range $name, $op := .Operations }}op{{ exportable $name }} *aws.Operation
{{ end }}
)

{{ end }}
`)
}

func tplAPIShapes(t *template.Template) (*template.Template, error) {
	return t.Parse(`
{{ define "api-shapes" }}

{{ range $_, $s := enumList }}
// Possible values for {{ exportable $s.Alias }}.
const (
    {{ range $name, $value := $s.Shape.Enums }}
    {{ $name }} = {{ $value }}{{ end }}
)
{{ end }}

{{ range $_, $s := shapeList }}
{{ if eq $s.Shape.ShapeType "structure" }}

// {{ $s.Alias }} is undocumented.
type {{ $s.Alias }} struct {
{{ range $name, $m := $s.Shape.Members }}
{{ exportable $name }} {{ $m.Shape.Type }} {{ $m.Tag $.Metadata.Protocol $name }}  {{ end }}
}

{{ end }}
{{ end }}

{{ end }}
`)
}
<|endoftext|>


<commit_before>package imgscale

import (
	"fmt"
	"net/http"
	"regexp"
	"strconv"
)

type Format struct {
	Prefix string
	Height int
	Ratio  float64
}

type Config struct {
	Path    string
	Prefix  string
	Formats []*Format
	Exts    []string
	Comment string
}

var supportedExts = map[string]string{"jpg": "image/jpg", "png": "image/png"}

type Handler struct {
	Config        *Config
	Formats       map[string]*Format
	Path          string
	regexp        *regexp.Regexp
	supportedExts map[string]string
}

func (h *Handler) Match(url string) (bool, *ImageInfo) {
	matches := h.regexp.FindStringSubmatch(url)

	if len(matches) == 0 {
		return false, nil
	}

	return true, h.GetImageInfo(matches[1], matches[2], matches[3])
}

func (h *Handler) GetContentType(ext string) string {
	return h.supportedExts[ext]
}

func (h *Handler) GetFormat(format string) *Format {
	return h.Formats[format]
}

func (h *Handler) GetImageInfo(format, filename, ext string) *ImageInfo {
	f := h.GetFormat(format)
	return &ImageInfo{fmt.Sprintf("%s/%s.%s", h.Config.Path, filename, ext), f.Height, f.Ratio, ext, h.Config.Comment}
}

func (h *Handler) Serve(res http.ResponseWriter, req *http.Request, info *ImageInfo) {
	img, err := GetImage(info)
	defer img.Destroy()
	if err == nil {
		imgData := img.GetImageBlob()
		res.Header().Set("Content-Type", h.GetContentType(info.Ext))
		res.Header().Set("Content-Length", strconv.Itoa(len(imgData)))
		res.Write(imgData)
	} else {
		panic(err)
	}
}
<commit_msg>Fix image type<commit_after>package imgscale

import (
	"fmt"
	"net/http"
	"regexp"
	"strconv"
)

type Format struct {
	Prefix string
	Height int
	Ratio  float64
}

type Config struct {
	Path    string
	Prefix  string
	Formats []*Format
	Exts    []string
	Comment string
}

var supportedExts = map[string]string{"jpg": "image/jpeg", "png": "image/png"}

type Handler struct {
	Config        *Config
	Formats       map[string]*Format
	Path          string
	regexp        *regexp.Regexp
	supportedExts map[string]string
}

func (h *Handler) Match(url string) (bool, *ImageInfo) {
	matches := h.regexp.FindStringSubmatch(url)

	if len(matches) == 0 {
		return false, nil
	}

	return true, h.GetImageInfo(matches[1], matches[2], matches[3])
}

func (h *Handler) GetContentType(ext string) string {
	return h.supportedExts[ext]
}

func (h *Handler) GetFormat(format string) *Format {
	return h.Formats[format]
}

func (h *Handler) GetImageInfo(format, filename, ext string) *ImageInfo {
	f := h.GetFormat(format)
	return &ImageInfo{fmt.Sprintf("%s/%s.%s", h.Config.Path, filename, ext), f.Height, f.Ratio, ext, h.Config.Comment}
}

func (h *Handler) Serve(res http.ResponseWriter, req *http.Request, info *ImageInfo) {
	img, err := GetImage(info)
	defer img.Destroy()
	if err == nil {
		imgData := img.GetImageBlob()
		res.Header().Set("Content-Type", h.GetContentType(info.Ext))
		res.Header().Set("Content-Length", strconv.Itoa(len(imgData)))
		res.Write(imgData)
	} else {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package modules

import (
	"net"

	"github.com/rivine/rivine/build"
)

const (
	// GatewayDir is the name of the directory used to store the gateway's
	// persistent data.
	GatewayDir = "gateway"
)

var (
	// BootstrapPeers is a list of peers that can be used to find other peers -
	// when a client first connects to the network, the only options for
	// finding peers are either manual entry of peers or to use a hardcoded
	// bootstrap point. While the bootstrap point could be a central service,
	// it can also be a list of peers that are known to be stable. We have
	// chosen to hardcode known-stable peers.
	BootstrapPeers = func() []NetAddress {
		switch build.Release {
		case "dev":
			return nil
		case "standard":
			return []NetAddress{
				"bootstrap1.rivine.io:23112",
				"bootstrap2.rivine.io:23112",
				"bootstrap3.rivine.io:23112",
			}
		case "testing":
			return nil
		default:
			panic("unrecognized build.Release constant in BootstrapPeers")
		}
	}()
)

type (
	// Peer contains all the info necessary to Broadcast to a peer.
	Peer struct {
		Inbound    bool                  `json:"inbound"`
		Local      bool                  `json:"local"`
		NetAddress NetAddress            `json:"netaddress"`
		Version    build.ProtocolVersion `json:"version"`
	}

	// A PeerConn is the connection type used when communicating with peers during
	// an RPC. It is identical to a net.Conn with the additional RPCAddr method.
	// This method acts as an identifier for peers and is the address that the
	// peer can be dialed on. It is also the address that should be used when
	// calling an RPC on the peer.
	PeerConn interface {
		net.Conn
		RPCAddr() NetAddress
	}

	// RPCFunc is the type signature of functions that handle RPCs. It is used for
	// both the caller and the callee. RPCFuncs may perform locking. RPCFuncs may
	// close the connection early, and it is recommended that they do so to avoid
	// keeping the connection open after all necessary I/O has been performed.
	RPCFunc func(PeerConn) error

	// A Gateway facilitates the interactions between the local node and remote
	// nodes (peers). It relays incoming blocks and transactions to local modules,
	// and broadcasts outgoing blocks and transactions to peers. In a broad sense,
	// it is responsible for ensuring that the local consensus set is consistent
	// with the "network" consensus set.
	Gateway interface {
		// Connect establishes a persistent connection to a peer.
		Connect(NetAddress) error

		// Disconnect terminates a connection to a peer.
		Disconnect(NetAddress) error

		// Address returns the Gateway's address.
		Address() NetAddress

		// Peers returns the addresses that the Gateway is currently connected to.
		Peers() []Peer

		// RegisterRPC registers a function to handle incoming connections that
		// supply the given RPC ID.
		RegisterRPC(string, RPCFunc)

		// UnregisterRPC unregisters an RPC and removes all references to the RPCFunc
		// supplied in the corresponding RegisterRPC call. References to RPCFuncs
		// registered with RegisterConnectCall are not removed and should be removed
		// with UnregisterConnectCall. If the RPC does not exist no action is taken.
		UnregisterRPC(string)

		// RegisterConnectCall registers an RPC name and function to be called
		// upon connecting to a peer.
		RegisterConnectCall(string, RPCFunc)

		// UnregisterConnectCall unregisters an RPC and removes all references to the
		// RPCFunc supplied in the corresponding RegisterConnectCall call. References
		// to RPCFuncs registered with RegisterRPC are not removed and should be
		// removed with UnregisterRPC. If the RPC does not exist no action is taken.
		UnregisterConnectCall(string)

		// RPC calls an RPC on the given address. RPC cannot be called on an
		// address that the Gateway is not connected to.
		RPC(NetAddress, string, RPCFunc) error

		// Broadcast transmits obj, prefaced by the RPC name, to all of the
		// given peers in parallel.
		Broadcast(name string, obj interface{}, peers []Peer)

		// Close safely stops the Gateway's listener process.
		Close() error
	}
)
<commit_msg>No dns entries allowed for bootstrap nodes yet, change the first bootstrap to it’s IP address<commit_after>package modules

import (
	"net"

	"github.com/rivine/rivine/build"
)

const (
	// GatewayDir is the name of the directory used to store the gateway's
	// persistent data.
	GatewayDir = "gateway"
)

var (
	// BootstrapPeers is a list of peers that can be used to find other peers -
	// when a client first connects to the network, the only options for
	// finding peers are either manual entry of peers or to use a hardcoded
	// bootstrap point. While the bootstrap point could be a central service,
	// it can also be a list of peers that are known to be stable. We have
	// chosen to hardcode known-stable peers.
	BootstrapPeers = func() []NetAddress {
		switch build.Release {
		case "dev":
			return nil
		case "standard":
			return []NetAddress{
				"136.243.144.132:23112",
				"bootstrap2.rivine.io:23112",
				"bootstrap3.rivine.io:23112",
			}
		case "testing":
			return nil
		default:
			panic("unrecognized build.Release constant in BootstrapPeers")
		}
	}()
)

type (
	// Peer contains all the info necessary to Broadcast to a peer.
	Peer struct {
		Inbound    bool                  `json:"inbound"`
		Local      bool                  `json:"local"`
		NetAddress NetAddress            `json:"netaddress"`
		Version    build.ProtocolVersion `json:"version"`
	}

	// A PeerConn is the connection type used when communicating with peers during
	// an RPC. It is identical to a net.Conn with the additional RPCAddr method.
	// This method acts as an identifier for peers and is the address that the
	// peer can be dialed on. It is also the address that should be used when
	// calling an RPC on the peer.
	PeerConn interface {
		net.Conn
		RPCAddr() NetAddress
	}

	// RPCFunc is the type signature of functions that handle RPCs. It is used for
	// both the caller and the callee. RPCFuncs may perform locking. RPCFuncs may
	// close the connection early, and it is recommended that they do so to avoid
	// keeping the connection open after all necessary I/O has been performed.
	RPCFunc func(PeerConn) error

	// A Gateway facilitates the interactions between the local node and remote
	// nodes (peers). It relays incoming blocks and transactions to local modules,
	// and broadcasts outgoing blocks and transactions to peers. In a broad sense,
	// it is responsible for ensuring that the local consensus set is consistent
	// with the "network" consensus set.
	Gateway interface {
		// Connect establishes a persistent connection to a peer.
		Connect(NetAddress) error

		// Disconnect terminates a connection to a peer.
		Disconnect(NetAddress) error

		// Address returns the Gateway's address.
		Address() NetAddress

		// Peers returns the addresses that the Gateway is currently connected to.
		Peers() []Peer

		// RegisterRPC registers a function to handle incoming connections that
		// supply the given RPC ID.
		RegisterRPC(string, RPCFunc)

		// UnregisterRPC unregisters an RPC and removes all references to the RPCFunc
		// supplied in the corresponding RegisterRPC call. References to RPCFuncs
		// registered with RegisterConnectCall are not removed and should be removed
		// with UnregisterConnectCall. If the RPC does not exist no action is taken.
		UnregisterRPC(string)

		// RegisterConnectCall registers an RPC name and function to be called
		// upon connecting to a peer.
		RegisterConnectCall(string, RPCFunc)

		// UnregisterConnectCall unregisters an RPC and removes all references to the
		// RPCFunc supplied in the corresponding RegisterConnectCall call. References
		// to RPCFuncs registered with RegisterRPC are not removed and should be
		// removed with UnregisterRPC. If the RPC does not exist no action is taken.
		UnregisterConnectCall(string)

		// RPC calls an RPC on the given address. RPC cannot be called on an
		// address that the Gateway is not connected to.
		RPC(NetAddress, string, RPCFunc) error

		// Broadcast transmits obj, prefaced by the RPC name, to all of the
		// given peers in parallel.
		Broadcast(name string, obj interface{}, peers []Peer)

		// Close safely stops the Gateway's listener process.
		Close() error
	}
)
<|endoftext|>


<commit_before>// Copyright 2014 Unknwon
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

package log

import (
	"fmt"
	"io"
	"os"
	"runtime"
	"time"
)

const (
	PREFIX      = "[GOPM]"
	TIME_FORMAT = "06-01-02 15:04:05"
)

var (
	Verbose, NonColor bool
	Output            io.Writer = os.Stdout

	LEVEL_FLAGS = [...]string{"DEBUG", " INFO", " WARN", "ERROR", "FATAL"}
)

func init() {
	if runtime.GOOS == "windows" {
		NonColor = true
	}
}

const (
	DEBUG = iota
	INFO
	WARNING
	ERROR
	FATAL
)

func Print(level int, format string, args ...interface{}) {
	if !Verbose && level < WARNING {
		return
	}

	if NonColor {
		fmt.Fprintf(Output, "%s %s [%s] %s\n",
			PREFIX, time.Now().Format(TIME_FORMAT), LEVEL_FLAGS[level],
			fmt.Sprintf(format, args...))
		if level == FATAL {
			os.Exit(1)
		}
		return
	}

	switch level {
	case DEBUG:
		fmt.Fprintf(Output, "%s \033[36m%s\033[0m [\033[34m%s\033[0m] %s\n",
			PREFIX, time.Now().Format(TIME_FORMAT), LEVEL_FLAGS[level],
			fmt.Sprintf(format, args...))
	case INFO:
		fmt.Fprintf(Output, "%s \033[36m%s\033[0m [\033[32m%s\033[0m] %s\n",
			PREFIX, time.Now().Format(TIME_FORMAT), LEVEL_FLAGS[level],
			fmt.Sprintf(format, args...))
	case WARNING:
		fmt.Fprintf(Output, "%s \033[36m%s\033[0m [\033[33m%s\033[0m] %s\n",
			PREFIX, time.Now().Format(TIME_FORMAT), LEVEL_FLAGS[level],
			fmt.Sprintf(format, args...))
	case ERROR:
		fmt.Fprintf(Output, "%s \033[36m%s\033[0m [\033[31m%s\033[0m] %s\n",
			PREFIX, time.Now().Format(TIME_FORMAT), LEVEL_FLAGS[level],
			fmt.Sprintf(format, args...))
	case FATAL:
		fmt.Fprintf(Output, "%s \033[36m%s\033[0m [\033[35m%s\033[0m] %s\n",
			PREFIX, time.Now().Format(TIME_FORMAT), LEVEL_FLAGS[level],
			fmt.Sprintf(format, args...))
		os.Exit(1)
	default:
		fmt.Fprintf(Output, "%s %s [%s] %s\n",
			PREFIX, time.Now().Format(TIME_FORMAT), LEVEL_FLAGS[level],
			fmt.Sprintf(format, args...))
	}
}

func Debug(format string, args ...interface{}) {
	Print(DEBUG, format, args...)
}

func Warn(format string, args ...interface{}) {
	Print(WARNING, format, args...)
}

func Info(format string, args ...interface{}) {
	Print(INFO, format, args...)
}

func Error(format string, args ...interface{}) {
	Print(ERROR, format, args...)
}

func Fatal(format string, args ...interface{}) {
	Print(FATAL, format, args...)
}
<commit_msg>Clean code in module 'log'.<commit_after>// Copyright 2014 Unknwon
//
// Licensed under the Apache License, Version 2.0 (the "License"): you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

package log

import (
	"fmt"
	"io"
	"os"
	"runtime"
	"time"
)

const (
	PREFIX      = "[GOPM]"
	TIME_FORMAT = "06-01-02 15:04:05"
)

var (
	Verbose, NonColor bool
	Output            io.Writer = os.Stdout

	LEVEL_FLAGS = [...]string{"DEBUG", " INFO", " WARN", "ERROR", "FATAL"}
)

func init() {
	if runtime.GOOS == "windows" {
		NonColor = true
	}
}

const (
	DEBUG = iota
	INFO
	WARNING
	ERROR
	FATAL
)

func Print(level int, format string, args ...interface{}) {
	if !Verbose && level < WARNING {
		return
	}

	var logFormat = "%s %s [%s] %s\n"
	if !NonColor {
		switch level {
		case DEBUG:
			logFormat = "%s \033[36m%s\033[0m [\033[34m%s\033[0m] %s\n"
		case INFO:
			logFormat = "%s \033[36m%s\033[0m [\033[32m%s\033[0m] %s\n"
		case WARNING:
			logFormat = "%s \033[36m%s\033[0m [\033[33m%s\033[0m] %s\n"
		case ERROR:
			logFormat = "%s \033[36m%s\033[0m [\033[31m%s\033[0m] %s\n"
		case FATAL:
			logFormat = "%s \033[36m%s\033[0m [\033[35m%s\033[0m] %s\n"
		}
	}

	fmt.Fprintf(Output, logFormat, PREFIX, time.Now().Format(TIME_FORMAT),
		LEVEL_FLAGS[level], fmt.Sprintf(format, args...))

	if level == FATAL {
		os.Exit(1)
	}
}

func Debug(format string, args ...interface{}) {
	Print(DEBUG, format, args...)
}

func Warn(format string, args ...interface{}) {
	Print(WARNING, format, args...)
}

func Info(format string, args ...interface{}) {
	Print(INFO, format, args...)
}

func Error(format string, args ...interface{}) {
	Print(ERROR, format, args...)
}

func Fatal(format string, args ...interface{}) {
	Print(FATAL, format, args...)
}
<|endoftext|>


<commit_before>// +build linux

package fs2

import (
	"bufio"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/opencontainers/runc/libcontainer/cgroups"
	"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
	"github.com/opencontainers/runc/libcontainer/configs"
	"github.com/pkg/errors"
)

// numToStr converts an int64 value to a string for writing to a
// cgroupv2 files with .min, .max, .low, or .high suffix.
// Negative values are converted to "max" for cgroupv1 compatibility
// (which used to write -1 to remove the limit).
func numToStr(value int64) (ret string) {
	if value > 0 {
		ret = strconv.FormatInt(value, 10)
	} else if value < 0 {
		ret = "max"
	} else {
		ret = ""
	}

	return ret
}

func setMemory(dirPath string, cgroup *configs.Cgroup) error {
	if val := numToStr(cgroup.Resources.MemorySwap); val != "" {
		if err := fscommon.WriteFile(dirPath, "memory.swap.max", val); err != nil {
			return err
		}
	}
	if val := numToStr(cgroup.Resources.Memory); val != "" {
		if err := fscommon.WriteFile(dirPath, "memory.max", val); err != nil {
			return err
		}
	}

	// cgroup.Resources.KernelMemory is ignored

	if val := numToStr(cgroup.Resources.MemoryReservation); val != "" {
		if err := fscommon.WriteFile(dirPath, "memory.low", val); err != nil {
			return err
		}
	}

	return nil
}

func statMemory(dirPath string, stats *cgroups.Stats) error {
	// Set stats from memory.stat.
	statsFile, err := os.Open(filepath.Join(dirPath, "memory.stat"))
	if err != nil {
		return err
	}
	defer statsFile.Close()

	sc := bufio.NewScanner(statsFile)
	for sc.Scan() {
		t, v, err := fscommon.GetCgroupParamKeyValue(sc.Text())
		if err != nil {
			return errors.Wrapf(err, "failed to parse memory.stat (%q)", sc.Text())
		}
		stats.MemoryStats.Stats[t] = v
	}
	stats.MemoryStats.Cache = stats.MemoryStats.Stats["cache"]

	memoryUsage, err := getMemoryDataV2(dirPath, "")
	if err != nil {
		return err
	}
	stats.MemoryStats.Usage = memoryUsage
	swapUsage, err := getMemoryDataV2(dirPath, "swap")
	if err != nil {
		return err
	}
	stats.MemoryStats.SwapUsage = swapUsage

	stats.MemoryStats.UseHierarchy = true
	return nil
}

func getMemoryDataV2(path, name string) (cgroups.MemoryData, error) {
	memoryData := cgroups.MemoryData{}

	moduleName := "memory"
	if name != "" {
		moduleName = strings.Join([]string{"memory", name}, ".")
	}
	usage := strings.Join([]string{moduleName, "current"}, ".")
	limit := strings.Join([]string{moduleName, "max"}, ".")

	value, err := fscommon.GetCgroupParamUint(path, usage)
	if err != nil {
		if moduleName != "memory" && os.IsNotExist(err) {
			return cgroups.MemoryData{}, nil
		}
		return cgroups.MemoryData{}, errors.Wrapf(err, "failed to parse %s", usage)
	}
	memoryData.Usage = value

	value, err = fscommon.GetCgroupParamUint(path, limit)
	if err != nil {
		if moduleName != "memory" && os.IsNotExist(err) {
			return cgroups.MemoryData{}, nil
		}
		return cgroups.MemoryData{}, errors.Wrapf(err, "failed to parse %s", limit)
	}
	memoryData.Limit = value

	return memoryData, nil
}
<commit_msg>cgroupv2: only treat -1 as "max"<commit_after>// +build linux

package fs2

import (
	"bufio"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/opencontainers/runc/libcontainer/cgroups"
	"github.com/opencontainers/runc/libcontainer/cgroups/fscommon"
	"github.com/opencontainers/runc/libcontainer/configs"
	"github.com/pkg/errors"
)

// numToStr converts an int64 value to a string for writing to a
// cgroupv2 files with .min, .max, .low, or .high suffix.
// The value of -1 is converted to "max" for cgroupv1 compatibility
// (which used to write -1 to remove the limit).
func numToStr(value int64) (ret string) {
	switch {
	case value == 0:
		ret = ""
	case value == -1:
		ret = "max"
	default:
		ret = strconv.FormatInt(value, 10)
	}

	return ret
}

func setMemory(dirPath string, cgroup *configs.Cgroup) error {
	if val := numToStr(cgroup.Resources.MemorySwap); val != "" {
		if err := fscommon.WriteFile(dirPath, "memory.swap.max", val); err != nil {
			return err
		}
	}
	if val := numToStr(cgroup.Resources.Memory); val != "" {
		if err := fscommon.WriteFile(dirPath, "memory.max", val); err != nil {
			return err
		}
	}

	// cgroup.Resources.KernelMemory is ignored

	if val := numToStr(cgroup.Resources.MemoryReservation); val != "" {
		if err := fscommon.WriteFile(dirPath, "memory.low", val); err != nil {
			return err
		}
	}

	return nil
}

func statMemory(dirPath string, stats *cgroups.Stats) error {
	// Set stats from memory.stat.
	statsFile, err := os.Open(filepath.Join(dirPath, "memory.stat"))
	if err != nil {
		return err
	}
	defer statsFile.Close()

	sc := bufio.NewScanner(statsFile)
	for sc.Scan() {
		t, v, err := fscommon.GetCgroupParamKeyValue(sc.Text())
		if err != nil {
			return errors.Wrapf(err, "failed to parse memory.stat (%q)", sc.Text())
		}
		stats.MemoryStats.Stats[t] = v
	}
	stats.MemoryStats.Cache = stats.MemoryStats.Stats["cache"]

	memoryUsage, err := getMemoryDataV2(dirPath, "")
	if err != nil {
		return err
	}
	stats.MemoryStats.Usage = memoryUsage
	swapUsage, err := getMemoryDataV2(dirPath, "swap")
	if err != nil {
		return err
	}
	stats.MemoryStats.SwapUsage = swapUsage

	stats.MemoryStats.UseHierarchy = true
	return nil
}

func getMemoryDataV2(path, name string) (cgroups.MemoryData, error) {
	memoryData := cgroups.MemoryData{}

	moduleName := "memory"
	if name != "" {
		moduleName = strings.Join([]string{"memory", name}, ".")
	}
	usage := strings.Join([]string{moduleName, "current"}, ".")
	limit := strings.Join([]string{moduleName, "max"}, ".")

	value, err := fscommon.GetCgroupParamUint(path, usage)
	if err != nil {
		if moduleName != "memory" && os.IsNotExist(err) {
			return cgroups.MemoryData{}, nil
		}
		return cgroups.MemoryData{}, errors.Wrapf(err, "failed to parse %s", usage)
	}
	memoryData.Usage = value

	value, err = fscommon.GetCgroupParamUint(path, limit)
	if err != nil {
		if moduleName != "memory" && os.IsNotExist(err) {
			return cgroups.MemoryData{}, nil
		}
		return cgroups.MemoryData{}, errors.Wrapf(err, "failed to parse %s", limit)
	}
	memoryData.Limit = value

	return memoryData, nil
}
<|endoftext|>


<commit_before>package libvirt

import (
	"encoding/xml"
	"fmt"
	"io"
	"log"
	"net/http"
	"strconv"
	//"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
	libvirt "gopkg.in/alexzorin/libvirt-go.v2"
)

func resourceLibvirtVolume() *schema.Resource {
	return &schema.Resource{
		Create: resourceLibvirtVolumeCreate,
		Read:   resourceLibvirtVolumeRead,
		Update: resourceLibvirtVolumeUpdate,
		Delete: resourceLibvirtVolumeDelete,
		Schema: map[string]*schema.Schema{
			"name": &schema.Schema{
				Type:     schema.TypeString,
				Required: true,
			},
			"pool": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
				Default:  "default",
			},
			"source": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
			"size": &schema.Schema{
				Type:     schema.TypeInt,
				Optional: true,
				Default:  -1,
			},
			"base_volume": &schema.Schema{
				Type:     schema.TypeString,
				Optional: true,
			},
		},
	}
}

func remoteImageSize(url string) (int, error) {
	response, err := http.Head(url)
	if err != nil {
		return 0, err
	}
	length, err := strconv.Atoi(response.Header.Get("Content-Length"))
	if err != nil {
		return 0, err
	}
	return length, nil
}

func resourceLibvirtVolumeCreate(d *schema.ResourceData, meta interface{}) error {
	virConn := meta.(*Client).libvirt
	if virConn == nil {
		return fmt.Errorf("The libvirt connection was nil.")
	}

	poolName := d.Get("pool").(string)
	if poolName == "" {
		poolName = "default"
	}
	pool, err := virConn.LookupStoragePoolByName(poolName)
	if err != nil {
		return fmt.Errorf("can't find storage pool '%s'", poolName)
	}

	volumeDef := newDefVolume()
	volumeDef.Name = d.Get("name").(string)

	// an existing image was given, this mean we can't choose size
	url := d.Get("source").(string)
	if url != "" {

		// source and size conflict
		if d.Get("size").(int) != -1 {
			return fmt.Errorf("'size' can't be specified when also 'source' is given (the size will be set to the size of the source image.")
		}

		size, err := remoteImageSize(url)
		if err != nil {
			return err
		}
		log.Printf("Remote image is: %d bytes", size)
		volumeDef.Capacity.Unit = "B"
		volumeDef.Capacity.Amount = size

	} else {
		if d.Get("size").(int) == -1 {
			return fmt.Errorf("'size' needs to be specified if no 'source' is given.")
		}

		volumeDef.Capacity.Amount = d.Get("size").(int)
	}

	volumeDefXml, err := xml.Marshal(volumeDef)
	if err != nil {
		return fmt.Errorf("Error serializing libvirt volume: %s", err)
	}

	// create the volume
	volume, err := pool.StorageVolCreateXML(string(volumeDefXml), 0)
	if err != nil {
		return fmt.Errorf("Error creating libvirt volume: %s", err)
	}
	// we use the key as the id
	key, err := volume.GetKey()
	if err != nil {
		return fmt.Errorf("Error retrieving volume key: %s", err)
	}
	d.SetId(key)
	log.Printf("[INFO] Volume ID: %s", d.Id())

	// upload source if present
	if url != "" {
		stream, err := libvirt.NewVirStream(virConn, 0)
		defer stream.Close()

		volume.Upload(stream, 0, uint64(volumeDef.Capacity.Amount), 0)
		response, err := http.Get(url)
		defer response.Body.Close()
		if err != nil {
			return fmt.Errorf("Error while downloading %s: %s", url, err)
		}

		n, err := io.Copy(stream, response.Body)
		if err != nil {
			return fmt.Errorf("Error while downloading %s: %s", url, err)
		}
		log.Printf("%d bytes uploaded\n", n)
	}

	return resourceLibvirtVolumeRead(d, meta)
}

func resourceLibvirtVolumeRead(d *schema.ResourceData, meta interface{}) error {
	virConn := meta.(*Client).libvirt
	if virConn == nil {
		return fmt.Errorf("The libvirt connection was nil.")
	}

	_, err := virConn.LookupStorageVolByKey(d.Id())
	if err != nil {
		return fmt.Errorf("Can't retrieve volume %s", d.Id())
	}

	return nil
}

func resourceLibvirtVolumeUpdate(d *schema.ResourceData, meta interface{}) error {
	return fmt.Errorf("Couldn't update libvirt domain")
}

func resourceLibvirtVolumeDelete(d *schema.ResourceData, meta interface{}) error {
	virConn := meta.(*Client).libvirt
	if virConn == nil {
		return fmt.Errorf("The libvirt connection was nil.")
	}

	volume, err := virConn.LookupStorageVolByKey(d.Id())
	if err != nil {
		return fmt.Errorf("Can't retrieve volume %s", d.Id())
	}

	err = volume.Delete(0)
	if err != nil {
		return fmt.Errorf("Can't delete volume %s", d.Id())
	}

	return nil
}
<commit_msg>move out the volume schema to reuse it inside instances<commit_after>package libvirt

import (
	"encoding/xml"
	"fmt"
	"io"
	"log"
	"net/http"
	"strconv"
	//"github.com/hashicorp/terraform/helper/resource"
	"github.com/hashicorp/terraform/helper/schema"
	libvirt "gopkg.in/alexzorin/libvirt-go.v2"
)

func volumeCommonSchema() map[string]*schema.Schema {
	return map[string]*schema.Schema{
		"name": &schema.Schema{
			Type:     schema.TypeString,
			Required: true,
		},
		"pool": &schema.Schema{
			Type:     schema.TypeString,
			Optional: true,
		Default:  "default",
		},
		"source": &schema.Schema{
			Type:     schema.TypeString,
			Optional: true,
		},
		"size": &schema.Schema{
			Type:     schema.TypeInt,
			Optional: true,
		Default:  -1,
		},
		"base_volume": &schema.Schema{
			Type:     schema.TypeString,
			Optional: true,
		},
	}
}

func resourceLibvirtVolume() *schema.Resource {
	return &schema.Resource{
		Create: resourceLibvirtVolumeCreate,
		Read:   resourceLibvirtVolumeRead,
		Update: resourceLibvirtVolumeUpdate,
		Delete: resourceLibvirtVolumeDelete,
		Schema: volumeCommonSchema(),
	}
}

func remoteImageSize(url string) (int, error) {
	response, err := http.Head(url)
	if err != nil {
		return 0, err
	}
	length, err := strconv.Atoi(response.Header.Get("Content-Length"))
	if err != nil {
		return 0, err
	}
	return length, nil
}

func resourceLibvirtVolumeCreate(d *schema.ResourceData, meta interface{}) error {
	virConn := meta.(*Client).libvirt
	if virConn == nil {
		return fmt.Errorf("The libvirt connection was nil.")
	}

	poolName := d.Get("pool").(string)
	if poolName == "" {
		poolName = "default"
	}
	pool, err := virConn.LookupStoragePoolByName(poolName)
	if err != nil {
		return fmt.Errorf("can't find storage pool '%s'", poolName)
	}

	volumeDef := newDefVolume()
	volumeDef.Name = d.Get("name").(string)

	// an existing image was given, this mean we can't choose size
	url := d.Get("source").(string)
	if url != "" {

		// source and size conflict
		if d.Get("size").(int) != -1 {
			return fmt.Errorf("'size' can't be specified when also 'source' is given (the size will be set to the size of the source image.")
		}

		size, err := remoteImageSize(url)
		if err != nil {
			return err
		}
		log.Printf("Remote image is: %d bytes", size)
		volumeDef.Capacity.Unit = "B"
		volumeDef.Capacity.Amount = size

	} else {
		if d.Get("size").(int) == -1 {
			return fmt.Errorf("'size' needs to be specified if no 'source' is given.")
		}

		volumeDef.Capacity.Amount = d.Get("size").(int)
	}

	volumeDefXml, err := xml.Marshal(volumeDef)
	if err != nil {
		return fmt.Errorf("Error serializing libvirt volume: %s", err)
	}

	// create the volume
	volume, err := pool.StorageVolCreateXML(string(volumeDefXml), 0)
	if err != nil {
		return fmt.Errorf("Error creating libvirt volume: %s", err)
	}
	// we use the key as the id
	key, err := volume.GetKey()
	if err != nil {
		return fmt.Errorf("Error retrieving volume key: %s", err)
	}
	d.SetId(key)
	log.Printf("[INFO] Volume ID: %s", d.Id())

	// upload source if present
	if url != "" {
		stream, err := libvirt.NewVirStream(virConn, 0)
		defer stream.Close()

		volume.Upload(stream, 0, uint64(volumeDef.Capacity.Amount), 0)
		response, err := http.Get(url)
		defer response.Body.Close()
		if err != nil {
			return fmt.Errorf("Error while downloading %s: %s", url, err)
		}

		n, err := io.Copy(stream, response.Body)
		if err != nil {
			return fmt.Errorf("Error while downloading %s: %s", url, err)
		}
		log.Printf("%d bytes uploaded\n", n)
	}

	return resourceLibvirtVolumeRead(d, meta)
}

func resourceLibvirtVolumeRead(d *schema.ResourceData, meta interface{}) error {
	virConn := meta.(*Client).libvirt
	if virConn == nil {
		return fmt.Errorf("The libvirt connection was nil.")
	}

	_, err := virConn.LookupStorageVolByKey(d.Id())
	if err != nil {
		return fmt.Errorf("Can't retrieve volume %s", d.Id())
	}

	return nil
}

func resourceLibvirtVolumeUpdate(d *schema.ResourceData, meta interface{}) error {
	return fmt.Errorf("Couldn't update libvirt domain")
}

func resourceLibvirtVolumeDelete(d *schema.ResourceData, meta interface{}) error {
	virConn := meta.(*Client).libvirt
	if virConn == nil {
		return fmt.Errorf("The libvirt connection was nil.")
	}

	volume, err := virConn.LookupStorageVolByKey(d.Id())
	if err != nil {
		return fmt.Errorf("Can't retrieve volume %s", d.Id())
	}

	err = volume.Delete(0)
	if err != nil {
		return fmt.Errorf("Can't delete volume %s", d.Id())
	}

	return nil
}
<|endoftext|>


<commit_before>package main

import "testing"

func BenchmarkPlaceNextQueen04(b *testing.B) {
	const n_size int = 4
	board := InitializeBoard(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}

func BenchmarkPlaceNextQueen05(b *testing.B) {
	const n_size int = 5
	board := InitializeBoard(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}

func BenchmarkPlaceNextQueen06(b *testing.B) {
	const n_size int = 6
	board := InitializeBoard(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}

func BenchmarkPlaceNextQueen07(b *testing.B) {
	const n_size int = 7
	board := InitializeBoard(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}

func BenchmarkPlaceNextQueen08(b *testing.B) {
	const n_size int = 8
	board := InitializeBoard(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}

func BenchmarkPlaceNextQueen09(b *testing.B) {
	const n_size int = 9
	board := InitializeBoard(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}

func BenchmarkPlaceNextQueen10(b *testing.B) {
	const n_size int = 10
	board := InitializeBoard(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}

func BenchmarkPlaceNextQueen11(b *testing.B) {
	const n_size int = 11
	board := InitializeBoard(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}

func BenchmarkPlaceNextQueen12(b *testing.B) {
	const n_size int = 12
	board := InitializeBoard(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}
<commit_msg>Update method names for benchmarks<commit_after>package main

// Go Standard Library Imports
import "testing"

func BenchmarkPlaceNextQueen04(b *testing.B) {
	const n_size int = 4
	board := InitializeCounter(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}

func BenchmarkPlaceNextQueen05(b *testing.B) {
	const n_size int = 5
	board := InitializeCounter(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}

func BenchmarkPlaceNextQueen06(b *testing.B) {
	const n_size int = 6
	board := InitializeCounter(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}

func BenchmarkPlaceNextQueen07(b *testing.B) {
	const n_size int = 7
	board := InitializeCounter(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}

func BenchmarkPlaceNextQueen08(b *testing.B) {
	const n_size int = 8
	board := InitializeCounter(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}

func BenchmarkPlaceNextQueen09(b *testing.B) {
	const n_size int = 9
	board := InitializeCounter(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}

func BenchmarkPlaceNextQueen10(b *testing.B) {
	const n_size int = 10
	board := InitializeCounter(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}

func BenchmarkPlaceNextQueen11(b *testing.B) {
	const n_size int = 11
	board := InitializeCounter(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}

func BenchmarkPlaceNextQueen12(b *testing.B) {
	const n_size int = 12
	board := InitializeCounter(n_size)
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		board.PlaceNextQueen()
	}
}
<|endoftext|>


<commit_before>package device

import (
	"bufio"
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/pkg/errors"

	"github.com/lxc/lxd/lxd/revert"
	"github.com/lxc/lxd/shared"
)

// deviceJoinPath joins together prefix and text delimited by a "." for device path generation.
func deviceJoinPath(parts ...string) string {
	return strings.Join(parts, ".")
}

// pciDevice represents info about a PCI uevent device.
type pciDevice struct {
	ID       string
	SlotName string
	Driver   string
}

// pciParseUeventFile returns the PCI device info for a given uevent file.
func pciParseUeventFile(ueventFilePath string) (pciDevice, error) {
	dev := pciDevice{}

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

	scanner := bufio.NewScanner(file)
	for scanner.Scan() {
		// Looking for something like this "PCI_SLOT_NAME=0000:05:10.0"
		fields := strings.SplitN(scanner.Text(), "=", 2)
		if len(fields) == 2 {
			if fields[0] == "PCI_SLOT_NAME" {
				dev.SlotName = fields[1]
			} else if fields[0] == "PCI_ID" {
				dev.ID = fields[1]
			} else if fields[0] == "DRIVER" {
				dev.Driver = fields[1]
			}
		}
	}

	err = scanner.Err()
	if err != nil {
		return dev, err
	}

	if dev.SlotName == "" {
		return dev, fmt.Errorf("Device uevent file could not be parsed")
	}

	return dev, nil
}

// pciDeviceUnbind unbinds a PCI device from the OS using its PCI Slot Name.
func pciDeviceUnbind(pciDev pciDevice) error {
	driverUnbindPath := fmt.Sprintf("/sys/bus/pci/devices/%s/driver/unbind", pciDev.SlotName)
	err := ioutil.WriteFile(driverUnbindPath, []byte(pciDev.SlotName), 0600)
	if err != nil {
		return errors.Wrapf(err, "Failed unbinding device %q via %q", pciDev.SlotName, driverUnbindPath)
	}

	return nil
}

// pciDeviceSetDriverOverride registers an override driver for a PCI device using its PCI Slot Name.
func pciDeviceSetDriverOverride(pciDev pciDevice, driverOverride string) error {
	overridePath := filepath.Join("/sys/bus/pci/devices", pciDev.SlotName, "driver_override")

	// The "\n" at end is important to allow the driver override to be cleared by passing "" in.
	err := ioutil.WriteFile(overridePath, []byte(fmt.Sprintf("%s\n", driverOverride)), 0600)
	if err != nil {
		return errors.Wrapf(err, "Failed setting driver override %q for device %q via %q", driverOverride, pciDev.SlotName, overridePath)
	}

	return nil
}

// pciDeviceProbe probes a PCI device using its PCI Slot Name.
func pciDeviceProbe(pciDev pciDevice) error {
	driveProbePath := "/sys/bus/pci/drivers_probe"
	err := ioutil.WriteFile(driveProbePath, []byte(pciDev.SlotName), 0600)
	if err != nil {
		return errors.Wrapf(err, "Failed probing device %q via %q", pciDev.SlotName, driveProbePath)
	}

	return nil
}

// pciDeviceProbeWait waits for PCI device to be activated with the specified driver after being probed.
func pciDeviceProbeWait(pciDev pciDevice) error {
	driverPath := fmt.Sprintf("/sys/bus/pci/drivers/%s/%s", pciDev.Driver, pciDev.SlotName)

	for i := 0; i < 10; i++ {
		if shared.PathExists(driverPath) {
			return nil
		}

		time.Sleep(50 * time.Millisecond)
	}

	return fmt.Errorf("Device took too long to activate at %q", driverPath)
}

// pciDeviceDriverOverride unbinds the device, sets the driver override preference, then probes the device, and
// waits for it to be activated with the specified driver.
func pciDeviceDriverOverride(pciDev pciDevice, driverOverride string) error {
	revert := revert.New()
	defer revert.Fail()

	// Unbind the device from the host (ignore if not bound).
	err := pciDeviceUnbind(pciDev)
	if err != nil && os.IsNotExist(err) {
		return err
	}

	revert.Add(func() {
		// Reset the driver override and rebind to original driver (if needed).
		pciDeviceUnbind(pciDev)
		pciDeviceSetDriverOverride(pciDev, pciDev.Driver)
		pciDeviceProbe(pciDev)
	})

	// Set driver override.
	err = pciDeviceSetDriverOverride(pciDev, driverOverride)
	if err != nil {
		return err
	}

	// Probe device to bind it to overridden driver.
	err = pciDeviceProbe(pciDev)
	if err != nil {
		return err
	}

	vfioDev := pciDevice{
		Driver:   driverOverride,
		SlotName: pciDev.SlotName,
	}

	// Wait for the device to be bound to the overridden driver if specified.
	if vfioDev.Driver != "" {
		err = pciDeviceProbeWait(vfioDev)
		if err != nil {
			return err
		}
	}

	revert.Success()
	return nil
}
<commit_msg>lxd/device/device/utils/generic: Removes pci functions<commit_after>package device

import (
	"strings"
)

// deviceJoinPath joins together prefix and text delimited by a "." for device path generation.
func deviceJoinPath(parts ...string) string {
	return strings.Join(parts, ".")
}
<|endoftext|>


<commit_before>package phdremote

    const ClientHTML = `

        <meta name="viewport" content="initial-scale=0.5, width=640, user-scalable=no">
        <meta name="apple-mobile-web-app-status-bar-style" content="black">
        <meta name="apple-mobile-web-app-capable" content="yes">

        <svg id="bull" width="100%%" height="100%%" style="opacity:0; position: absolute; top: 0; left: 0;">
            <g >
                <line x1="0px" y1="50%%" x2="100%%" y2="50%%" stroke="red" stroke-width="1" />
                <line x1="50%%" y1="0px" x2="50%%" y2="100%%" stroke="red" stroke-width="1" />
                <circle cx="50%%" cy="50%%" r="10%%" stroke="red" stroke-width="1" fill="none" />
                <circle cx="50%%" cy="50%%" r="4%%" stroke="red" stroke-width="1" fill="none" />
                <circle cx="50%%" cy="50%%" r="2%%" stroke="red" stroke-width="1" fill="none" />
            </g>
        </svg>
        <svg id="marker" width="20" height="20" style="position: absolute; top: 0; left: 0;">
            <g id="m-select" style="opacity:0">
                <rect x="-4" y="-4" width="10" height="10" stroke="white" stroke-width="2" fill="none" />
                <rect x="14" y="-4" width="10" height="10" stroke="white" stroke-width="2" fill="none" />
                <rect x="-4" y="14" width="10" height="10" stroke="white" stroke-width="2" fill="none" />
                <rect x="14" y="14" width="10" height="10" stroke="white" stroke-width="2" fill="none" />
            </g>
            <g id="m-calib" style="opacity:0">
                <rect x="0" y="0" width="20" height="20" stroke="yellow" stroke-width="4" stroke-dasharray="2 2" fill="none" />
            </g>
            <g id="m-guide" style="opacity:0">
                <line x1="10" y1="0" x2="10" y2="20" stroke="green" stroke-width="2" />
                <line x1="0" y1="10" x2="20" y2="10" stroke="green" stroke-width="2" />
                <rect x="4" y="4" width="12" height="12" stroke="green" stroke-width="2" fill="none" />
            </g>
            <g id="m-lost"  style="opacity:0">
                <line x1="0" y1="0" x2="20" y2="20" stroke="red" stroke-width="2" />
                <line x1="20" y1="0" x2="0" y2="20" stroke="red" stroke-width="2" />
                <rect x="0" y="0" width="20" height="20" stroke="red" stroke-width="4" fill="none" />
            </g>
        </svg>

        0.5s
        1.0s
        2.0s

        GUIDE
        STOP
        LOOP

          <svg width="60px" height="60px">
            <g >
                <path d="M30,10 L30,50 A20,20 0 0,1 30,10 z" fill="black" />
                <path d="M30,50 L30,10 A20,20 0 0,1 30,50 z" fill="firebrick" />
            </g>
          </svg>

            <svg width="40px" height="40px">
            <g >
                <line x1="60%%" y1="30%%" x2="20%%" y2="60%%" stroke="black" stroke-width="1" />
                <line x1="20%%" y1="60%%" x2="80%%" y2="80%%" stroke="black" stroke-width="1" />
                <line x1="80%%" y1="80%%" x2="60%%" y2="30%%" stroke="black" stroke-width="1" />
                <circle cx="60%%" cy="30%%" r="8%%" stroke="black" stroke-width="1" fill="firebrick" />
                <circle cx="20%%" cy="60%%" r="8%%" stroke="black" stroke-width="1" fill="firebrick" />
                <circle cx="80%%" cy="80%%" r="8%%" stroke="black" stroke-width="1" fill="firebrick" />
            </g>

            </svg>

            <svg width="40px" height="40px">
            <g >
                <line x1="0px" y1="50%%" x2="100%%" y2="50%%" stroke="black" stroke-width="1" />
                <line x1="50%%" y1="0px" x2="50%%" y2="100%%" stroke="black" stroke-width="1" />
                <circle cx="50%%" cy="50%%" r="20%%" stroke="black" stroke-width="1" fill="none" />
                <circle cx="50%%" cy="50%%" r="10%%" stroke="black" stroke-width="1" fill="none" />
            </g>
            </svg>

`
<commit_msg>spin icon while plate solving<commit_after>package phdremote

    const ClientHTML = `

        <meta name="viewport" content="initial-scale=0.5, width=640, user-scalable=no">
        <meta name="apple-mobile-web-app-status-bar-style" content="black">
        <meta name="apple-mobile-web-app-capable" content="yes">

        <svg id="bull" width="100%%" height="100%%" style="opacity:0; position: absolute; top: 0; left: 0;">
            <g >
                <line x1="0px" y1="50%%" x2="100%%" y2="50%%" stroke="red" stroke-width="1" />
                <line x1="50%%" y1="0px" x2="50%%" y2="100%%" stroke="red" stroke-width="1" />
                <circle cx="50%%" cy="50%%" r="10%%" stroke="red" stroke-width="1" fill="none" />
                <circle cx="50%%" cy="50%%" r="4%%" stroke="red" stroke-width="1" fill="none" />
                <circle cx="50%%" cy="50%%" r="2%%" stroke="red" stroke-width="1" fill="none" />
            </g>
        </svg>
        <svg id="marker" width="20" height="20" style="position: absolute; top: 0; left: 0;">
            <g id="m-select" style="opacity:0">
                <rect x="-4" y="-4" width="10" height="10" stroke="white" stroke-width="2" fill="none" />
                <rect x="14" y="-4" width="10" height="10" stroke="white" stroke-width="2" fill="none" />
                <rect x="-4" y="14" width="10" height="10" stroke="white" stroke-width="2" fill="none" />
                <rect x="14" y="14" width="10" height="10" stroke="white" stroke-width="2" fill="none" />
            </g>
            <g id="m-calib" style="opacity:0">
                <rect x="0" y="0" width="20" height="20" stroke="yellow" stroke-width="4" stroke-dasharray="2 2" fill="none" />
            </g>
            <g id="m-guide" style="opacity:0">
                <line x1="10" y1="0" x2="10" y2="20" stroke="green" stroke-width="2" />
                <line x1="0" y1="10" x2="20" y2="10" stroke="green" stroke-width="2" />
                <rect x="4" y="4" width="12" height="12" stroke="green" stroke-width="2" fill="none" />
            </g>
            <g id="m-lost"  style="opacity:0">
                <line x1="0" y1="0" x2="20" y2="20" stroke="red" stroke-width="2" />
                <line x1="20" y1="0" x2="0" y2="20" stroke="red" stroke-width="2" />
                <rect x="0" y="0" width="20" height="20" stroke="red" stroke-width="4" fill="none" />
            </g>
        </svg>

        0.5s
        1.0s
        2.0s

        GUIDE
        STOP
        LOOP

          <svg width="60px" height="60px">
            <g >
                <path d="M30,10 L30,50 A20,20 0 0,1 30,10 z" fill="black" />
                <path d="M30,50 L30,10 A20,20 0 0,1 30,50 z" fill="firebrick" />
            </g>
          </svg>

            <svg width="40px" height="40px">
            <g >
                <animateTransform id="solvedspinner"
                    attributeName="transform"
                    attributeType="XML"
                    type="rotate"
                    from="0 20 20"
                    to="360 20 20"
                    dur="10s"
                    begin="indefinite"
                    repeatCount="indefinite"/>
                <line x1="60%%" y1="30%%" x2="20%%" y2="60%%" stroke="black" stroke-width="1" />
                <line x1="20%%" y1="60%%" x2="80%%" y2="80%%" stroke="black" stroke-width="1" />
                <line x1="80%%" y1="80%%" x2="60%%" y2="30%%" stroke="black" stroke-width="1" />
                <circle cx="60%%" cy="30%%" r="8%%" stroke="black" stroke-width="1" fill="firebrick" />
                <circle cx="20%%" cy="60%%" r="8%%" stroke="black" stroke-width="1" fill="firebrick" />
                <circle cx="80%%" cy="80%%" r="8%%" stroke="black" stroke-width="1" fill="firebrick" />
            </g>

            </svg>

            <svg width="40px" height="40px">
            <g >
                <line x1="0px" y1="50%%" x2="100%%" y2="50%%" stroke="black" stroke-width="1" />
                <line x1="50%%" y1="0px" x2="50%%" y2="100%%" stroke="black" stroke-width="1" />
                <circle cx="50%%" cy="50%%" r="20%%" stroke="black" stroke-width="1" fill="none" />
                <circle cx="50%%" cy="50%%" r="10%%" stroke="black" stroke-width="1" fill="none" />
            </g>
            </svg>

`
<|endoftext|>


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

// Package build gathers information about Go packages.
//
// Go Path
//
// The Go path is a list of directory trees containing Go source code.
// It is consulted to resolve imports that cannot be found in the standard
// Go tree.  The default path is the value of the GOPATH environment
// variable, interpreted as a path list appropriate to the operating system
// (on Unix, the variable is a colon-separated string;
// on Windows, a semicolon-separated string;
// on Plan 9, a list).
//
// Each directory listed in the Go path must have a prescribed structure:
//
// The src/ directory holds source code.  The path below 'src' determines
// the import path or executable name.
//
// The pkg/ directory holds installed package objects.
// As in the Go tree, each target operating system and
// architecture pair has its own subdirectory of pkg
// (pkg/GOOS_GOARCH).
//
// If DIR is a directory listed in the Go path, a package with
// source in DIR/src/foo/bar can be imported as "foo/bar" and
// has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a"
// (or, for gccgo, "DIR/pkg/gccgo/foo/libbar.a").
//
// The bin/ directory holds compiled commands.
// Each command is named for its source directory, but only
// using the final element, not the entire path.  That is, the
// command with source in DIR/src/foo/quux is installed into
// DIR/bin/quux, not DIR/bin/foo/quux.  The foo/ is stripped
// so that you can add DIR/bin to your PATH to get at the
// installed commands.
//
// Here's an example directory layout:
//
//	GOPATH=/home/user/gocode
//
//	/home/user/gocode/
//	    src/
//	        foo/
//	            bar/               (go code in package bar)
//	                x.go
//	            quux/              (go code in package main)
//	                y.go
//	    bin/
//	        quux                   (installed command)
//	    pkg/
//	        linux_amd64/
//	            foo/
//	                bar.a          (installed package object)
//
// Build Constraints
//
// A build constraint is a line comment beginning with the directive +build
// that lists the conditions under which a file should be included in the package.
// Constraints may appear in any kind of source file (not just Go), but
// they must appear near the top of the file, preceded
// only by blank lines and other line comments.
//
// A build constraint is evaluated as the OR of space-separated options;
// each option evaluates as the AND of its comma-separated terms;
// and each term is an alphanumeric word or, preceded by !, its negation.
// That is, the build constraint:
//
//	// +build linux,386 darwin,!cgo
//
// corresponds to the boolean formula:
//
//	(linux AND 386) OR (darwin AND (NOT cgo))
//
// A file may have multiple build constraints. The overall constraint is the AND
// of the individual constraints. That is, the build constraints:
//
//	// +build linux darwin
//	// +build 386
//
// corresponds to the boolean formula:
//
//	(linux OR darwin) AND 386
//
// During a particular build, the following words are satisfied:
//
//	- the target operating system, as spelled by runtime.GOOS
//	- the target architecture, as spelled by runtime.GOARCH
//	- the compiler being used, currently either "gc" or "gccgo"
//	- "cgo", if ctxt.CgoEnabled is true
//	- any additional words listed in ctxt.BuildTags
//
// If a file's name, after stripping the extension and a possible _test suffix,
// matches *_GOOS, *_GOARCH, or *_GOOS_GOARCH for any known operating
// system and architecture values, then the file is considered to have an implicit
// build constraint requiring those terms.
//
// To keep a file from being considered for the build:
//
//	// +build ignore
//
// (any other unsatisfied word will work as well, but ``ignore'' is conventional.)
//
// To build a file only when using cgo, and only on Linux and OS X:
//
//	// +build linux,cgo darwin,cgo
//
// Such a file is usually paired with another file implementing the
// default functionality for other systems, which in this case would
// carry the constraint:
//
//	// +build !linux,!darwin !cgo
//
// Naming a file dns_windows.go will cause it to be included only when
// building the package for Windows; similarly, math_386.s will be included
// only when building the package for 32-bit x86.
//
package build
<commit_msg>go/build: document blank line required after build constraints<commit_after>// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package build gathers information about Go packages.
//
// Go Path
//
// The Go path is a list of directory trees containing Go source code.
// It is consulted to resolve imports that cannot be found in the standard
// Go tree.  The default path is the value of the GOPATH environment
// variable, interpreted as a path list appropriate to the operating system
// (on Unix, the variable is a colon-separated string;
// on Windows, a semicolon-separated string;
// on Plan 9, a list).
//
// Each directory listed in the Go path must have a prescribed structure:
//
// The src/ directory holds source code.  The path below 'src' determines
// the import path or executable name.
//
// The pkg/ directory holds installed package objects.
// As in the Go tree, each target operating system and
// architecture pair has its own subdirectory of pkg
// (pkg/GOOS_GOARCH).
//
// If DIR is a directory listed in the Go path, a package with
// source in DIR/src/foo/bar can be imported as "foo/bar" and
// has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a"
// (or, for gccgo, "DIR/pkg/gccgo/foo/libbar.a").
//
// The bin/ directory holds compiled commands.
// Each command is named for its source directory, but only
// using the final element, not the entire path.  That is, the
// command with source in DIR/src/foo/quux is installed into
// DIR/bin/quux, not DIR/bin/foo/quux.  The foo/ is stripped
// so that you can add DIR/bin to your PATH to get at the
// installed commands.
//
// Here's an example directory layout:
//
//	GOPATH=/home/user/gocode
//
//	/home/user/gocode/
//	    src/
//	        foo/
//	            bar/               (go code in package bar)
//	                x.go
//	            quux/              (go code in package main)
//	                y.go
//	    bin/
//	        quux                   (installed command)
//	    pkg/
//	        linux_amd64/
//	            foo/
//	                bar.a          (installed package object)
//
// Build Constraints
//
// A build constraint is a line comment beginning with the directive +build
// that lists the conditions under which a file should be included in the package.
// Constraints may appear in any kind of source file (not just Go), but
// they must appear near the top of the file, preceded
// only by blank lines and other line comments.
//
// To distinguish build constraints from package documentation, a series of
// build constraints must be followed by a blank line.
//
// A build constraint is evaluated as the OR of space-separated options;
// each option evaluates as the AND of its comma-separated terms;
// and each term is an alphanumeric word or, preceded by !, its negation.
// That is, the build constraint:
//
//	// +build linux,386 darwin,!cgo
//
// corresponds to the boolean formula:
//
//	(linux AND 386) OR (darwin AND (NOT cgo))
//
// A file may have multiple build constraints. The overall constraint is the AND
// of the individual constraints. That is, the build constraints:
//
//	// +build linux darwin
//	// +build 386
//
// corresponds to the boolean formula:
//
//	(linux OR darwin) AND 386
//
// During a particular build, the following words are satisfied:
//
//	- the target operating system, as spelled by runtime.GOOS
//	- the target architecture, as spelled by runtime.GOARCH
//	- the compiler being used, currently either "gc" or "gccgo"
//	- "cgo", if ctxt.CgoEnabled is true
//	- any additional words listed in ctxt.BuildTags
//
// If a file's name, after stripping the extension and a possible _test suffix,
// matches *_GOOS, *_GOARCH, or *_GOOS_GOARCH for any known operating
// system and architecture values, then the file is considered to have an implicit
// build constraint requiring those terms.
//
// To keep a file from being considered for the build:
//
//	// +build ignore
//
// (any other unsatisfied word will work as well, but ``ignore'' is conventional.)
//
// To build a file only when using cgo, and only on Linux and OS X:
//
//	// +build linux,cgo darwin,cgo
//
// Such a file is usually paired with another file implementing the
// default functionality for other systems, which in this case would
// carry the constraint:
//
//	// +build !linux,!darwin !cgo
//
// Naming a file dns_windows.go will cause it to be included only when
// building the package for Windows; similarly, math_386.s will be included
// only when building the package for 32-bit x86.
//
package build
<|endoftext|>