<commit_before>package middleware

import (
	"fmt"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/admpub/log"
	"github.com/webx-top/echo"
	"github.com/webx-top/echo/engine"
)

type (
	StaticOptions struct {
		// Skipper defines a function to skip middleware.
		Skipper echo.Skipper `json:"-"`

		Path   string `json:"path"` //UrlPath
		Root   string `json:"root"`
		Index  string `json:"index"`
		Browse bool   `json:"browse"`
	}
)

func Static(options ...*StaticOptions) echo.MiddlewareFunc {
	// Default options
	opts := new(StaticOptions)
	if len(options) > 0 {
		opts = options[0]
	}
	hasIndex := len(opts.Index) > 0
	if opts.Skipper == nil {
		opts.Skipper = echo.DefaultSkipper
	}
	opts.Root, _ = filepath.Abs(opts.Root)
	length := len(opts.Path)
	if length > 0 && opts.Path[0] != '/' {
		opts.Path = `/` + opts.Path
		length++
	}

	log.GetLogger("echo").Debugf("Static: %v\t-> %v", opts.Path, opts.Root)

	return func(next echo.Handler) echo.Handler {
		return echo.HandlerFunc(func(c echo.Context) error {
			if opts.Skipper(c) {
				return next.Handle(c)
			}
			file := c.Request().URL().Path()
			if len(file) < length || file[0:length] != opts.Path {
				return next.Handle(c)
			}
			file = file[length:]
			file = path.Clean(file)
			absFile := filepath.Join(opts.Root, file)
			if !strings.HasPrefix(absFile, opts.Root) {
				return next.Handle(c)
			}
			w := c.Response()
			fp, err := os.Open(absFile)
			if err != nil {
				return echo.ErrNotFound
			}
			defer fp.Close()
			fi, err := fp.Stat()
			if err != nil {
				return echo.ErrNotFound
			}
			if fi.IsDir() {
				if hasIndex {
					// Index file
					indexFile := filepath.Join(absFile, opts.Index)
					fi, err = os.Stat(indexFile)
					if err != nil || fi.IsDir() {
						if opts.Browse {
							return listDir(absFile, file, w)
						}
						return echo.ErrNotFound
					}
					absFile = indexFile
				} else {
					if opts.Browse {
						return listDir(absFile, file, w)
					}
					return echo.ErrNotFound
				}
			}
			return c.ServeContent(fp, fi.Name(), fi.ModTime())
		})
	}
}

func listDir(absFile string, file string, w engine.Response) error {
	fs := http.Dir(filepath.Dir(absFile))
	d, err := fs.Open(filepath.Base(absFile))
	if err != nil {
		return echo.ErrNotFound
	}
	defer d.Close()
	dirs, err := d.Readdir(-1)
	if err != nil {
		return echo.ErrNotFound
	}

	// Create a directory index
	w.Header().Set(echo.HeaderContentType, echo.MIMETextHTMLCharsetUTF8)
	if _, err = fmt.Fprintf(w, `<!doctype html>

        <meta charset="UTF-8">
        <title>`+file+`</title>
        <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible" />
        <meta content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport" />
        <link href="/favicon.ico" rel="shortcut icon">

    `); err != nil {
		return err
	}
	if _, err = fmt.Fprintf(w, "
\n"); err != nil {
		return err
	}
	for _, d := range dirs {
		name := d.Name()
		color := "#212121"
		if d.IsDir() {
			color = "#e91e63"
			name += "/"
		}
		if _, err = fmt.Fprintf(w, "
%s
\n", name, color, name); err != nil {
			return err
		}
	}
	if _, err = fmt.Fprintf(w, "
\n"); err != nil {
		return err
	}
	_, err = fmt.Fprintf(w, "\n")
	return err
}
<commit_msg>improved<commit_after>package middleware

import (
	"html/template"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/admpub/log"
	"github.com/webx-top/echo"
	"github.com/webx-top/echo/engine"
)

var ListDirTemplate = `<!doctype html>

        <meta charset="UTF-8">
        <title>{{.file}}</title>
        <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible" />
        <meta content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport" />
        <link href="/favicon.ico" rel="shortcut icon">

		{{range $k, $d := .dirs}}

{{$d.Name}}{{if $d.IsDir}}/{{end}}

		{{end}}

`

type (
	StaticOptions struct {
		// Skipper defines a function to skip middleware.
		Skipper echo.Skipper `json:"-"`

		Path     string `json:"path"` //UrlPath
		Root     string `json:"root"`
		Index    string `json:"index"`
		Browse   bool   `json:"browse"`
		Template string `json:"template"`
	}
)

func Static(options ...*StaticOptions) echo.MiddlewareFunc {
	// Default options
	opts := new(StaticOptions)
	if len(options) > 0 {
		opts = options[0]
	}
	hasIndex := len(opts.Index) > 0
	if opts.Skipper == nil {
		opts.Skipper = echo.DefaultSkipper
	}
	opts.Root, _ = filepath.Abs(opts.Root)
	length := len(opts.Path)
	if length > 0 && opts.Path[0] != '/' {
		opts.Path = `/` + opts.Path
		length++
	}
	var t *template.Template
	if opts.Browse {
		t = template.New(opts.Template)
		var e error
		if len(opts.Template) > 0 {
			t, e = t.ParseFiles(opts.Template)
		} else {
			t, e = t.Parse(ListDirTemplate)
		}
		if e != nil {
			panic(e)
		}
	}

	log.GetLogger("echo").Debugf("Static: %v\t-> %v", opts.Path, opts.Root)

	return func(next echo.Handler) echo.Handler {
		return echo.HandlerFunc(func(c echo.Context) error {
			if opts.Skipper(c) {
				return next.Handle(c)
			}
			file := c.Request().URL().Path()
			if len(file) < length || file[0:length] != opts.Path {
				return next.Handle(c)
			}
			file = file[length:]
			file = path.Clean(file)
			absFile := filepath.Join(opts.Root, file)
			if !strings.HasPrefix(absFile, opts.Root) {
				return next.Handle(c)
			}
			w := c.Response()
			fp, err := os.Open(absFile)
			if err != nil {
				return echo.ErrNotFound
			}
			defer fp.Close()
			fi, err := fp.Stat()
			if err != nil {
				return echo.ErrNotFound
			}
			if fi.IsDir() {
				if hasIndex {
					// Index file
					indexFile := filepath.Join(absFile, opts.Index)
					fi, err = os.Stat(indexFile)
					if err != nil || fi.IsDir() {
						if opts.Browse {
							return listDir(absFile, file, w, t)
						}
						return echo.ErrNotFound
					}
					absFile = indexFile
				} else {
					if opts.Browse {
						return listDir(absFile, file, w, t)
					}
					return echo.ErrNotFound
				}
			}
			return c.ServeContent(fp, fi.Name(), fi.ModTime())
		})
	}
}

func listDir(absFile string, file string, w engine.Response, t *template.Template) error {
	fs := http.Dir(filepath.Dir(absFile))
	d, err := fs.Open(filepath.Base(absFile))
	if err != nil {
		return echo.ErrNotFound
	}
	defer d.Close()
	dirs, err := d.Readdir(-1)
	if err != nil {
		return echo.ErrNotFound
	}

	w.Header().Set(echo.HeaderContentType, echo.MIMETextHTMLCharsetUTF8)
	return t.Execute(w, map[string]interface{}{
		`file`: file,
		`dirs`: dirs,
	})
}
<|endoftext|>


<commit_before>package integration_test

import (
	"fmt"
	"net/http"
	"os"
	"os/exec"

	"github.com/concourse/concourse/atc"

	"github.com/concourse/concourse/fly/version"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"github.com/onsi/gomega/gbytes"
	"github.com/onsi/gomega/gexec"
	"github.com/onsi/gomega/ghttp"
)

var _ = Describe("Version Checks", func() {
	// patch version
	var (
		flyVersion       string
		customAtcVersion string
		flySession       *gexec.Session
	)
	BeforeEach(func() {
		atcServer.AppendHandlers(
			ghttp.CombineHandlers(
				ghttp.VerifyRequest("GET", "/api/v1/teams/main/containers"),
				ghttp.RespondWith(http.StatusOK, "[]"),
			),
		)
	})

	JustBeforeEach(func() {
		atcServer.SetHandler(3,
			ghttp.CombineHandlers(
				ghttp.VerifyRequest("GET", "/api/v1/info"),
				ghttp.RespondWithJSONEncoded(200, atc.Info{Version: customAtcVersion, WorkerVersion: workerVersion}),
			),
		)

		flyCmd := exec.Command(flyPath, "-t", targetName, "containers")
		flyCmd.Env = append(os.Environ(), "FAKE_FLY_VERSION="+flyVersion)

		var err error
		flySession, err = gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
		Expect(err).NotTo(HaveOccurred())
	})

	Describe("when the client and server differ by a patch version", func() {
		BeforeEach(func() {
			major, minor, patch, err := version.GetSemver(atcVersion)
			Expect(err).NotTo(HaveOccurred())

			customAtcVersion = fmt.Sprintf("%d.%d.%d", major, minor, patch+1)
		})

		It("warns the user that there is a difference", func() {
			Eventually(flySession).Should(gexec.Exit(0))
			Expect(flySession.Err).To(gbytes.Say(`fly version \(%s\) is out of sync with the target \(%s\). to sync up, run the following:\n\n    `, flyVersion, customAtcVersion))
			Expect(flySession.Err).To(gbytes.Say(`fly.* -t %s sync\n`, targetName))
		})
	})

	// when then match
	Describe("when the client and server are the same version", func() {
		BeforeEach(func() {
			customAtcVersion = atcVersion
		})

		It("it doesn't give any warning message", func() {
			Eventually(flySession).Should(gexec.Exit(0))
			Expect(flySession.Err).ShouldNot(gbytes.Say("version"))
		})
	})

	// minor version
	Describe("when the client and server differ by a minor version", func() {
		BeforeEach(func() {
			major, minor, patch, err := version.GetSemver(atcVersion)
			Expect(err).NotTo(HaveOccurred())

			customAtcVersion = fmt.Sprintf("%d.%d.%d", major, minor+1, patch)
		})

		It("error and tell the user to sync", func() {
			Eventually(flySession).Should(gexec.Exit(1))
			Expect(flySession.Err).To(gbytes.Say(`fly version \(%s\) is out of sync with the target \(%s\). to sync up, run the following:\n\n    `, flyVersion, customAtcVersion))
			Expect(flySession.Err).To(gbytes.Say(`fly.* -t %s sync\n`, targetName))
			Expect(flySession.Err).To(gbytes.Say("cowardly refusing to run due to significant version discrepancy"))
		})
	})

	// major version (same as minor)
	Describe("when the client and server differ by a major version", func() {
		BeforeEach(func() {
			major, minor, patch, err := version.GetSemver(atcVersion)
			Expect(err).NotTo(HaveOccurred())

			customAtcVersion = fmt.Sprintf("%d.%d.%d", major+1, minor, patch)
		})

		It("error and tell the user to sync", func() {
			Eventually(flySession).Should(gexec.Exit(1))
			Expect(flySession.Err).To(gbytes.Say(`fly version \(%s\) is out of sync with the target \(%s\). to sync up, run the following:\n\n    `, flyVersion, customAtcVersion))
			Expect(flySession.Err).To(gbytes.Say(`fly.* -t %s sync\n`, targetName))
			Expect(flySession.Err).To(gbytes.Say("cowardly refusing to run due to significant version discrepancy"))
		})
	})

	// dev version
	Describe("when the client is a development version", func() {
		BeforeEach(func() {
			flyVersion = "0.0.0-dev"
		})

		It("never complains", func() {
			Eventually(flySession).Should(gexec.Exit(0))
			Expect(flySession.Err).ShouldNot(gbytes.Say("version"))
		})
	})
})
<commit_msg>fly: fix integration tests<commit_after>package integration_test

import (
	"fmt"
	"net/http"
	"os"
	"os/exec"

	"github.com/concourse/concourse/atc"

	"github.com/concourse/concourse/fly/version"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"

	"github.com/onsi/gomega/gbytes"
	"github.com/onsi/gomega/gexec"
	"github.com/onsi/gomega/ghttp"
)

var _ = Describe("Version Checks", func() {
	// patch version
	var (
		flyVersion       string
		customAtcVersion string
		flySession       *gexec.Session
	)
	BeforeEach(func() {
		flyVersion = atcVersion

		atcServer.AppendHandlers(
			ghttp.CombineHandlers(
				ghttp.VerifyRequest("GET", "/api/v1/teams/main/containers"),
				ghttp.RespondWith(http.StatusOK, "[]"),
			),
		)
	})

	JustBeforeEach(func() {
		atcServer.SetHandler(3,
			ghttp.CombineHandlers(
				ghttp.VerifyRequest("GET", "/api/v1/info"),
				ghttp.RespondWithJSONEncoded(200, atc.Info{Version: customAtcVersion, WorkerVersion: workerVersion}),
			),
		)

		flyCmd := exec.Command(flyPath, "-t", targetName, "containers")
		flyCmd.Env = append(os.Environ(), "FAKE_FLY_VERSION="+flyVersion)

		var err error
		flySession, err = gexec.Start(flyCmd, GinkgoWriter, GinkgoWriter)
		Expect(err).NotTo(HaveOccurred())
	})

	Describe("when the client and server differ by a patch version", func() {
		BeforeEach(func() {
			major, minor, patch, err := version.GetSemver(atcVersion)
			Expect(err).NotTo(HaveOccurred())

			customAtcVersion = fmt.Sprintf("%d.%d.%d", major, minor, patch+1)
		})

		It("warns the user that there is a difference", func() {
			Eventually(flySession).Should(gexec.Exit(0))
			Expect(flySession.Err).To(gbytes.Say(`fly version \(%s\) is out of sync with the target \(%s\). to sync up, run the following:\n\n    `, flyVersion, customAtcVersion))
			Expect(flySession.Err).To(gbytes.Say(`fly.* -t %s sync\n`, targetName))
		})
	})

	// when then match
	Describe("when the client and server are the same version", func() {
		BeforeEach(func() {
			customAtcVersion = atcVersion
		})

		It("it doesn't give any warning message", func() {
			Eventually(flySession).Should(gexec.Exit(0))
			Expect(flySession.Err).ShouldNot(gbytes.Say("version"))
		})
	})

	// minor version
	Describe("when the client and server differ by a minor version", func() {
		BeforeEach(func() {
			major, minor, patch, err := version.GetSemver(atcVersion)
			Expect(err).NotTo(HaveOccurred())

			customAtcVersion = fmt.Sprintf("%d.%d.%d", major, minor+1, patch)
		})

		It("error and tell the user to sync", func() {
			Eventually(flySession).Should(gexec.Exit(1))
			Expect(flySession.Err).To(gbytes.Say(`fly version \(%s\) is out of sync with the target \(%s\). to sync up, run the following:\n\n    `, flyVersion, customAtcVersion))
			Expect(flySession.Err).To(gbytes.Say(`fly.* -t %s sync\n`, targetName))
			Expect(flySession.Err).To(gbytes.Say("cowardly refusing to run due to significant version discrepancy"))
		})
	})

	// major version (same as minor)
	Describe("when the client and server differ by a major version", func() {
		BeforeEach(func() {
			major, minor, patch, err := version.GetSemver(atcVersion)
			Expect(err).NotTo(HaveOccurred())

			customAtcVersion = fmt.Sprintf("%d.%d.%d", major+1, minor, patch)
		})

		It("error and tell the user to sync", func() {
			Eventually(flySession).Should(gexec.Exit(1))
			Expect(flySession.Err).To(gbytes.Say(`fly version \(%s\) is out of sync with the target \(%s\). to sync up, run the following:\n\n    `, flyVersion, customAtcVersion))
			Expect(flySession.Err).To(gbytes.Say(`fly.* -t %s sync\n`, targetName))
			Expect(flySession.Err).To(gbytes.Say("cowardly refusing to run due to significant version discrepancy"))
		})
	})

	// dev version
	Describe("when the client is a development version", func() {
		BeforeEach(func() {
			flyVersion = "0.0.0-dev"
		})

		It("never complains", func() {
			Eventually(flySession).Should(gexec.Exit(0))
			Expect(flySession.Err).ShouldNot(gbytes.Say("version"))
		})
	})
})
<|endoftext|>


<commit_before>package helium

import (
	"bytes"
	"errors"
	"io"
	"strings"

	"github.com/lestrrat/helium/internal/debug"
)

func CreateDocument() *Document {
	return NewDocument("1.0", "", StandaloneImplicitNo)
}

func NewDocument(version, encoding string, standalone DocumentStandaloneType) *Document {
	doc := &Document{
		encoding:   encoding,
		standalone: standalone,
		version:    version,
	}

	doc.etype = DocumentNode
	doc.name = "(document)"
	return doc
}

func (d Document) XMLString() (string, error) {
	out := bytes.Buffer{}
	if err := d.XML(&out); err != nil {
		return "", err
	}
	return out.String(), nil
}

func (d *Document) XML(out io.Writer) error {
	return (&Dumper{}).DumpDoc(out, d)
}

func (d *Document) AddChild(cur Node) error {
	return addChild(d, cur)
}

func (d *Document) AddContent(b []byte) error {
	return addContent(d, b)
}

func (d *Document) AddSibling(n Node) error {
	return errors.New("can't add sibling to a document")
}

func (d *Document) SetTreeDoc(doc *Document) {
	setTreeDoc(d, doc)
}

func (d *Document) Encoding() string {
	// In order to differentiate between a document with explicit
	// encoding in the XML declaration and one without, the XML dump
	// routine must check for d.encoding == "", and not Encoding()
	if enc := d.encoding; enc != "" {
		return d.encoding
	}
	return "utf8"
}

func (d *Document) Standalone() DocumentStandaloneType {
	return d.standalone
}

func (d *Document) Version() string {
	return d.version
}

func (d *Document) IntSubset() *DTD {
	return d.intSubset
}

func (d *Document) ExtSubset() *DTD {
	return d.extSubset
}

func (d *Document) Replace(n Node) {
	panic("d.Replace does not make sense")
}

func (d *Document) SetDocumentElement(root Node) error {
	if d == nil {
		// what are you trying to do?
		return nil
	}

	if root == nil || root.Type() == NamespaceDeclNode {
		return nil
	}

	root.SetParent(d)
	var old Node
	for old = d.firstChild; old != nil; old = old.NextSibling() {
		if old.Type() == ElementNode {
			break
		}
	}

	if old == nil {
		d.AddChild(root)
	} else {
		old.Replace(root)
	}
	return nil
}

func (d *Document) CreateReference(name string) (*EntityRef, error) {
	if debug.Enabled {
		g := debug.IPrintf("START document.CreateReference '%s'", name)
		defer g.IRelease("END document.CreateReference")
	}
	n, err := d.CreateCharRef(name)
	if err != nil {
		return nil, err
	}

	ent, ok := d.GetEntity(n.name)
	if ok {
		n.content = []byte(ent.content)
		// Original code says:
		// The parent pointer in entity is a DTD pointer and thus is NOT
		// updated.  Not sure if this is 100% correct.
		n.setFirstChild(ent)
		n.setLastChild(ent)
	}

	return n, nil
}

func (d *Document) CreateAttribute(name, value string, ns *Namespace) (*Attribute, error) {
	attr := newAttribute(name, ns)
	if value != "" {
		n, err := d.stringToNodeList(value)
		if err != nil {
			return nil, err
		}
		attr.setFirstChild(n)
		for n != nil {
			n.SetParent(attr)
			x := n.NextSibling()
			if x == nil {
				n.setLastChild(x)
			}
			n = x
		}
	}
	return attr, nil
}

func (d *Document) CreateNamespace(prefix, uri string) (*Namespace, error) {
	ns := newNamespace(prefix, uri)
	ns.context = d
	return ns, nil
}

func (d *Document) CreatePI(target, data string) (*ProcessingInstruction, error) {
	return &ProcessingInstruction{
		target: target,
		data:   data,
	}, nil
}

func (d *Document) CreateDTD() (*DTD, error) {
	dtd := newDTD()
	dtd.doc = d
	return dtd, nil
}

func (d *Document) CreateElement(name string) (*Element, error) {
	e := newElement(name)
	e.doc = d
	return e, nil
}

func (d *Document) CreateText(value []byte) (*Text, error) {
	e := newText(value)
	e.doc = d
	return e, nil
}

func (d *Document) CreateComment(value []byte) (*Comment, error) {
	e := newComment(value)
	e.doc = d
	return e, nil
}

func (d *Document) CreateElementContent(name string, etype ElementContentType) (*ElementContent, error) {
	e, err := newElementContent(name, etype)
	if err != nil {
		return nil, err
	}
	return e, nil
}

func (d *Document) GetEntity(name string) (*Entity, bool) {
	if ints := d.intSubset; ints != nil {
		return ints.LookupEntity(name)
	}

	if exts := d.extSubset; exts != nil {
		return exts.LookupEntity(name)
	}

	return nil, false
}

func (d *Document) GetParameterEntity(name string) (*Entity, bool) {
	if ints := d.intSubset; ints != nil {
		return ints.LookupParameterEntity(name)
	}

	if exts := d.extSubset; exts != nil {
		return exts.LookupParameterEntity(name)
	}

	return nil, false
}

func (d *Document) IsMixedElement(name string) (bool, error) {
	if d.intSubset == nil {
		return false, errors.New("element declaration not found")
	}

	edecl, ok := d.intSubset.GetElementDesc(name)
	if !ok {
		return false, errors.New("element declaration not found")
	}

	switch edecl.decltype {
	case UndefinedElementType:
		return false, errors.New("element declaration not found")
	case ElementElementType:
		return false, nil
	case EmptyElementType, AnyElementType, MixedElementType:
		/*
		 * return 1 for EMPTY since we want VC error to pop up
		 * on <empty>     </empty> for example
		 */
		return true, nil
	}
	return true, nil
}

/*
 * @doc:  the document
 * @value:  the value of the attribute
 *
 * Parse the value string and build the node list associated. Should
 * produce a flat tree with only TEXTs and ENTITY_REFs.
 * Returns a pointer to the first child
 */
func (d *Document) stringToNodeList(value string) (Node, error) {
	if debug.Enabled {
		g := debug.IPrintf("START document.stringToNodeList '%s'", value)
		defer g.IRelease("END document.stringToNodeList")
	}
	rdr := strings.NewReader(value)
	buf := bytes.Buffer{}
	var ret Node
	var last Node
	var charval int32
	for rdr.Len() > 0 {
		r, _, err := rdr.ReadRune()
		if err != nil {
			return nil, err
		}

		// if this is not any sort of an entity , just go go go
		if r != '&' {
			buf.WriteRune(r)
			continue
		}

		// well, at least the first rune sure looks like an entity, see what
		// else we have.
		r, _, err = rdr.ReadRune()
		if err != nil {
			return nil, err
		}

		if r == '#' {
			r2, _, err := rdr.ReadRune()
			if err != nil {
				return nil, err
			}

			var accumulator func(int32, rune) (int32, error)
			if r2 == 'x' {
				accumulator = accumulateHexCharRef
			} else {
				rdr.UnreadRune()
				accumulator = accumulateDecimalCharRef
			}
			for {
				r, _, err = rdr.ReadRune()
				if err != nil {
					return nil, err
				}
				if r == ';' {
					break
				}
				charval, err = accumulator(charval, r)
				if err != nil {
					return nil, err
				}
			}
		} else {
			rdr.UnreadRune()
			entbuf := bytes.Buffer{}
			for rdr.Len() > 0 {
				r, _, err = rdr.ReadRune()
				if err != nil {
					return nil, err
				}
				if r == ';' {
					break
				}
				entbuf.WriteRune(r)
			}

			if r != ';' {
				return nil, errors.New("entity was unterminated (could not find terminating semicolon)")
			}

			val := entbuf.String()
			ent, ok := d.GetEntity(val)

			// XXX I *believe* libxml2 SKIPS entities that it can't resolve
			// at this point?
			if ok && ent.EntityType() == int(InternalPredefinedEntity) {
				buf.Write(ent.Content())
			} else {
				// flush the buffer so far
				if buf.Len() > 0 {
					node, err := d.CreateText(buf.Bytes())
					if err != nil {
						return nil, err
					}

					if last == nil {
						last = node
						ret = node
					} else {
						last.AddSibling(node)
						last = node
					}
				}

				// create a new REFERENCE_REF node
				node, err := d.CreateReference(val)
				if err != nil {
					return nil, err
				}

				// no children
				if ok && ent.FirstChild() == nil {
					// XXX WTF am I doing here...?
					refchildren, err := d.stringToNodeList(string(node.Content()))
					if err != nil {
						return nil, err
					}
					ent.setFirstChild(refchildren)
					for n := refchildren; n != nil; {
						ent.AddChild(n)
						if x := n.NextSibling(); x != nil {
							n = x
						} else {
							n = nil
						}
					}
				}

				if last == nil {
					last = node
					ret = node
				} else {
					last.AddSibling(node)
					last = node
				}
			}
		}

		if charval != 0 {
			buf.WriteRune(rune(charval))
			charval = 0
		}
	}

	if buf.Len() > 0 {
		n, err := d.CreateText(buf.Bytes())
		if err != nil {
			return nil, err
		}

		if last == nil {
			ret = n
		} else {
			last.AddSibling(n)
		}
	}

	if debug.Enabled {
		for n := last; n != nil; n = n.PrevSibling() {
			debug.Printf("---> %s (%#v)", n.Name(), n)
		}
	}

	return ret, nil
}

func (d *Document) CreateCharRef(name string) (*EntityRef, error) {
	if debug.Enabled {
		g := debug.IPrintf("START document.CreateCharRef '%s'", name)
		defer g.IRelease("END document.CreateCharRef")
	}

	if name == "" {
		return nil, errors.New("empty name")
	}

	n := newEntityRef()
	n.doc = d
	if name[0] != '&' {
		n.name = name
	} else {
		// the name should be everything but '&' and ';'
		if name[len(name)-1] == ';' {
			n.name = name[1 : len(name)-1]
		} else {
			n.name = name[1:]
		}
	}
	return n, nil
}
<commit_msg>Properly reset scratch buffer after consuming it<commit_after>package helium

import (
	"bytes"
	"errors"
	"io"
	"strings"

	"github.com/lestrrat/helium/internal/debug"
)

func CreateDocument() *Document {
	return NewDocument("1.0", "", StandaloneImplicitNo)
}

func NewDocument(version, encoding string, standalone DocumentStandaloneType) *Document {
	doc := &Document{
		encoding:   encoding,
		standalone: standalone,
		version:    version,
	}

	doc.etype = DocumentNode
	doc.name = "(document)"
	return doc
}

func (d Document) XMLString() (string, error) {
	out := bytes.Buffer{}
	if err := d.XML(&out); err != nil {
		return "", err
	}
	return out.String(), nil
}

func (d *Document) XML(out io.Writer) error {
	return (&Dumper{}).DumpDoc(out, d)
}

func (d *Document) AddChild(cur Node) error {
	return addChild(d, cur)
}

func (d *Document) AddContent(b []byte) error {
	return addContent(d, b)
}

func (d *Document) AddSibling(n Node) error {
	return errors.New("can't add sibling to a document")
}

func (d *Document) SetTreeDoc(doc *Document) {
	setTreeDoc(d, doc)
}

func (d *Document) Encoding() string {
	// In order to differentiate between a document with explicit
	// encoding in the XML declaration and one without, the XML dump
	// routine must check for d.encoding == "", and not Encoding()
	if enc := d.encoding; enc != "" {
		return d.encoding
	}
	return "utf8"
}

func (d *Document) Standalone() DocumentStandaloneType {
	return d.standalone
}

func (d *Document) Version() string {
	return d.version
}

func (d *Document) IntSubset() *DTD {
	return d.intSubset
}

func (d *Document) ExtSubset() *DTD {
	return d.extSubset
}

func (d *Document) Replace(n Node) {
	panic("d.Replace does not make sense")
}

func (d *Document) SetDocumentElement(root Node) error {
	if d == nil {
		// what are you trying to do?
		return nil
	}

	if root == nil || root.Type() == NamespaceDeclNode {
		return nil
	}

	root.SetParent(d)
	var old Node
	for old = d.firstChild; old != nil; old = old.NextSibling() {
		if old.Type() == ElementNode {
			break
		}
	}

	if old == nil {
		d.AddChild(root)
	} else {
		old.Replace(root)
	}
	return nil
}

func (d *Document) CreateReference(name string) (*EntityRef, error) {
	if debug.Enabled {
		g := debug.IPrintf("START document.CreateReference '%s'", name)
		defer g.IRelease("END document.CreateReference")
	}
	n, err := d.CreateCharRef(name)
	if err != nil {
		return nil, err
	}

	ent, ok := d.GetEntity(n.name)
	if ok {
		n.content = []byte(ent.content)
		// Original code says:
		// The parent pointer in entity is a DTD pointer and thus is NOT
		// updated.  Not sure if this is 100% correct.
		n.setFirstChild(ent)
		n.setLastChild(ent)
	}

	return n, nil
}

func (d *Document) CreateAttribute(name, value string, ns *Namespace) (attr *Attribute, err error) {
	if debug.Enabled {
		g := debug.IPrintf("START document.CreateAttribute '%s' (%s)", name, value)
		defer func() {
			g.IRelease("END document.CreateAttribute (attr.Value = '%s')", attr.Value())
		}()
	}
	var n Node
	attr = newAttribute(name, ns)
	if value != "" {
		n, err = d.stringToNodeList(value)
		if err != nil {
			attr = nil
			return
		}

		attr.setFirstChild(n)
		for n != nil {
			n.SetParent(attr)
			x := n.NextSibling()
			if x == nil {
				n.setLastChild(x)
			}
			n = x
		}
	}
	return attr, nil
}

func (d *Document) CreateNamespace(prefix, uri string) (*Namespace, error) {
	ns := newNamespace(prefix, uri)
	ns.context = d
	return ns, nil
}

func (d *Document) CreatePI(target, data string) (*ProcessingInstruction, error) {
	return &ProcessingInstruction{
		target: target,
		data:   data,
	}, nil
}

func (d *Document) CreateDTD() (*DTD, error) {
	dtd := newDTD()
	dtd.doc = d
	return dtd, nil
}

func (d *Document) CreateElement(name string) (*Element, error) {
	e := newElement(name)
	e.doc = d
	return e, nil
}

func (d *Document) CreateText(value []byte) (*Text, error) {
	e := newText(value)
	e.doc = d
	return e, nil
}

func (d *Document) CreateComment(value []byte) (*Comment, error) {
	e := newComment(value)
	e.doc = d
	return e, nil
}

func (d *Document) CreateElementContent(name string, etype ElementContentType) (*ElementContent, error) {
	e, err := newElementContent(name, etype)
	if err != nil {
		return nil, err
	}
	return e, nil
}

func (d *Document) GetEntity(name string) (*Entity, bool) {
	if ints := d.intSubset; ints != nil {
		return ints.LookupEntity(name)
	}

	if exts := d.extSubset; exts != nil {
		return exts.LookupEntity(name)
	}

	return nil, false
}

func (d *Document) GetParameterEntity(name string) (*Entity, bool) {
	if ints := d.intSubset; ints != nil {
		return ints.LookupParameterEntity(name)
	}

	if exts := d.extSubset; exts != nil {
		return exts.LookupParameterEntity(name)
	}

	return nil, false
}

func (d *Document) IsMixedElement(name string) (bool, error) {
	if d.intSubset == nil {
		return false, errors.New("element declaration not found")
	}

	edecl, ok := d.intSubset.GetElementDesc(name)
	if !ok {
		return false, errors.New("element declaration not found")
	}

	switch edecl.decltype {
	case UndefinedElementType:
		return false, errors.New("element declaration not found")
	case ElementElementType:
		return false, nil
	case EmptyElementType, AnyElementType, MixedElementType:
		/*
		 * return 1 for EMPTY since we want VC error to pop up
		 * on <empty>     </empty> for example
		 */
		return true, nil
	}
	return true, nil
}

/*
 * @doc:  the document
 * @value:  the value of the attribute
 *
 * Parse the value string and build the node list associated. Should
 * produce a flat tree with only TEXTs and ENTITY_REFs.
 * Returns a pointer to the first child
 */
func (d *Document) stringToNodeList(value string) (Node, error) {
	if debug.Enabled {
		g := debug.IPrintf("START document.stringToNodeList '%s'", value)
		defer g.IRelease("END document.stringToNodeList")
	}
	rdr := strings.NewReader(value)
	buf := bytes.Buffer{}
	var ret Node
	var last Node
	var charval int32
	for rdr.Len() > 0 {
		r, _, err := rdr.ReadRune()
		if err != nil {
			return nil, err
		}

		// if this is not any sort of an entity , just go go go
		if r != '&' {
			buf.WriteRune(r)
			continue
		}

		// well, at least the first rune sure looks like an entity, see what
		// else we have.
		r, _, err = rdr.ReadRune()
		if err != nil {
			return nil, err
		}

		if r == '#' {
			r2, _, err := rdr.ReadRune()
			if err != nil {
				return nil, err
			}

			var accumulator func(int32, rune) (int32, error)
			if r2 == 'x' {
				accumulator = accumulateHexCharRef
			} else {
				rdr.UnreadRune()
				accumulator = accumulateDecimalCharRef
			}
			for {
				r, _, err = rdr.ReadRune()
				if err != nil {
					return nil, err
				}
				if r == ';' {
					break
				}
				charval, err = accumulator(charval, r)
				if err != nil {
					return nil, err
				}
			}
		} else {
			rdr.UnreadRune()
			entbuf := bytes.Buffer{}
			for rdr.Len() > 0 {
				r, _, err = rdr.ReadRune()
				if err != nil {
					return nil, err
				}
				if r == ';' {
					break
				}
				entbuf.WriteRune(r)
			}

			if r != ';' {
				return nil, errors.New("entity was unterminated (could not find terminating semicolon)")
			}

			val := entbuf.String()
			ent, ok := d.GetEntity(val)

			// XXX I *believe* libxml2 SKIPS entities that it can't resolve
			// at this point?
			if ok && ent.EntityType() == int(InternalPredefinedEntity) {
				buf.Write(ent.Content())
			} else {
				// flush the buffer so far
				if buf.Len() > 0 {
					node, err := d.CreateText(buf.Bytes())
					if err != nil {
						return nil, err
					}
					buf.Reset()

					if last == nil {
						last = node
						ret = node
					} else {
						last.AddSibling(node)
						last = node
					}
				}

				// create a new REFERENCE_REF node
				node, err := d.CreateReference(val)
				if err != nil {
					return nil, err
				}

				// no children
				if ok && ent.FirstChild() == nil {
					// XXX WTF am I doing here...?
					refchildren, err := d.stringToNodeList(string(node.Content()))
					if err != nil {
						return nil, err
					}
					ent.setFirstChild(refchildren)
					for n := refchildren; n != nil; {
						ent.AddChild(n)
						if x := n.NextSibling(); x != nil {
							n = x
						} else {
							n = nil
						}
					}
				}

				if last == nil {
					last = node
					ret = node
				} else {
					last.AddSibling(node)
					last = node
				}
			}
		}

		if charval != 0 {
			buf.WriteRune(rune(charval))
			charval = 0
		}
	}

	if buf.Len() > 0 {
		n, err := d.CreateText(buf.Bytes())
		if err != nil {
			return nil, err
		}

		if last == nil {
			ret = n
		} else {
			last.AddSibling(n)
		}
	}

	if debug.Enabled {
		for n := last; n != nil; n = n.PrevSibling() {
			debug.Printf("---> %s (%s)", n.Name(), n.Content())
		}
	}

	return ret, nil
}

func (d *Document) CreateCharRef(name string) (*EntityRef, error) {
	if debug.Enabled {
		g := debug.IPrintf("START document.CreateCharRef '%s'", name)
		defer g.IRelease("END document.CreateCharRef")
	}

	if name == "" {
		return nil, errors.New("empty name")
	}

	n := newEntityRef()
	n.doc = d
	if name[0] != '&' {
		n.name = name
	} else {
		// the name should be everything but '&' and ';'
		if name[len(name)-1] == ';' {
			n.name = name[1 : len(name)-1]
		} else {
			n.name = name[1:]
		}
	}
	return n, nil
}
<|endoftext|>


<commit_before>package jsh

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
)

// DocumentMode allows different specification settings to be enforced
// based on the specified mode.
type DocumentMode int

const (
	// ObjectMode enforces fetch request/response specifications
	ObjectMode DocumentMode = iota
	// ListMode enforces listing request/response specifications
	ListMode
	// ErrorMode enforces error response specifications
	ErrorMode
)

// IncludeJSONAPIVersion is an option that allows consumers to include/remove the `jsonapi`
// top-level member from server responses.
var IncludeJSONAPIVersion = true

// JSONAPI is the top-level member of a JSONAPI document that includes
// the server compatible version of the JSONAPI specification.
type JSONAPI struct {
	Version string `json:"version"`
}

/*
Document represents a top level JSON formatted Document.
Refer to the JSON API Specification for a full descriptor
of each attribute: http://jsonapi.org/format/#document-structure
*/
type Document struct {
	Data List `json:"data"`
	// Object   *Object     `json:"-"`
	Errors   ErrorList   `json:"errors,omitempty"`
	Links    *Links      `json:"links,omitempty"`
	Included []*Object   `json:"included,omitempty"`
	Meta     interface{} `json:"meta,omitempty"`
	JSONAPI  *JSONAPI    `json:"jsonapi,omitempty"`
	// Status is an HTTP Status Code
	Status int `json:"-"`
	// DataMode to enforce for the document
	Mode DocumentMode `json:"-"`
	// empty is used to signify that the response shouldn't contain a json payload
	// in the case that we only want to return an HTTP Status Code in order to bypass
	// validation steps.
	empty bool
	// validated confirms whether or not the document as a whole is validated and
	// in a safe-to-send state.
	validated bool
}

/*
New instantiates a new JSON Document object.
*/
func New() *Document {
	json := &Document{}
	if IncludeJSONAPIVersion {
		json.JSONAPI = &JSONAPI{
			Version: JSONAPIVersion,
		}
	}

	return json
}

/*
Build creates a Sendable Document with the provided sendable payload, either Data or
errors. Build also assumes you've already validated your data with .Validate() so
it should be used carefully.
*/
func Build(payload Sendable) *Document {
	document := New()
	document.validated = true

	switch p := payload.(type) {
	case *Document:
		document = p
	case *Object:
		document.Data = List{p}
		document.Status = p.Status
		document.Mode = ObjectMode
	case List:
		document.Data = p
		document.Status = http.StatusOK
		document.Mode = ListMode
	case *IDObject:
		if p == nil {
			document.Data = nil
		} else {
			document.Data = List{p.ToObject()}
		}
		document.Status = http.StatusOK
		document.Mode = ObjectMode
	case IDList:
		document.Data = p.ToList()
		document.Status = http.StatusOK
		document.Mode = ListMode
	case *Error:
		document.Errors = ErrorList{p}
		document.Status = p.Status
		document.Mode = ErrorMode
	case ErrorList:
		document.Errors = p
		document.Status = p[0].Status
		document.Mode = ErrorMode
	}
	return document
}

/*
Validate performs document level checks against the JSONAPI specification. It is
assumed that if this call returns without an error, your document is valid and
can be sent as a request or response.
*/
func (d *Document) Validate(r *http.Request, isResponse bool) *Error {

	// if sending a response, we must have a valid HTTP status at the very least
	// to send
	if isResponse && d.Status < 100 || d.Status > 600 {
		return ISE("Response HTTP Status is outside of valid range")
	}

	// There are certain cases such as HTTP 204 that send without a payload,
	// this is the short circuit to make sure we don't false alarm on those cases
	if d.empty {
		return nil
	}

	// if we have errors, and they have been added in a way that does not trigger
	// error mode, set it now so we perform the proper validations.
	if d.HasErrors() && d.Mode != ErrorMode {
		d.Mode = ErrorMode
	}

	switch d.Mode {
	case ErrorMode:
		if d.HasData() {
			return ISE("Attempting to respond with 'data' in an error response")
		}
	case ObjectMode:
		if d.HasData() && len(d.Data) > 1 {
			return ISE("Cannot set more than one data object in 'ObjectMode'")
		}
	case ListMode:
		if !d.HasErrors() && d.Data == nil {
			return ISE("Data cannot be nil in 'ListMode', use empty array")
		}
	}

	if !d.HasData() && d.Included != nil {
		return ISE("'included' should only be set for a response if 'data' is as well")
	}

	err := d.Data.Validate(r, isResponse)
	if err != nil {
		return err
	}

	err = d.Errors.Validate(r, isResponse)
	if err != nil {
		return err
	}

	d.validated = true

	return nil
}

// AddObject adds another object to the JSON Document after validating it.
func (d *Document) AddObject(object *Object) *Error {

	if d.Mode == ErrorMode {
		return ISE("Cannot add data to a document already possessing errors")
	}

	if d.Mode == ObjectMode && len(d.Data) == 1 {
		return ISE("Single 'data' object response is expected, you are attempting to add more than one element to be returned")
	}

	// if not yet set, add the associated HTTP status with the object
	if d.Status == 0 {
		d.Status = object.Status
	}

	// finally, actually add the object to data List
	if d.Data == nil {
		d.Data = List{object}
	} else {
		d.Data = append(d.Data, object)
	}

	return nil
}

/*
AddError adds an error to the Document. It will also set the document Mode to
"ErrorMode" if not done so already.
*/
func (d *Document) AddError(newErr *Error) *Error {

	if d.HasData() {
		return ISE("Attempting to set an error, when the document has prepared response data")
	}

	if newErr.Status == 0 {
		return ISE("No HTTP Status code provided for error, cannot add to document")
	}

	if d.Status == 0 {
		d.Status = newErr.Status
	}

	if d.Errors == nil {
		d.Errors = []*Error{newErr}
	} else {
		d.Errors = append(d.Errors, newErr)
	}

	// set document to error mode
	d.Mode = ErrorMode

	return nil
}

/*
First will return the first object from the document data if possible.
*/
func (d *Document) First() *Object {
	if !d.HasData() {
		return nil
	}

	return d.Data[0]
}

// HasData will return true if the JSON document's Data field is set
func (d *Document) HasData() bool {
	return d.Data != nil && len(d.Data) > 0
}

// HasErrors will return true if the Errors attribute is not nil.
func (d *Document) HasErrors() bool {
	return d.Errors != nil && len(d.Errors) > 0
}

func (d *Document) Error() string {
	errStr := "Errors:"
	for _, err := range d.Errors {
		errStr = strings.Join([]string{errStr, fmt.Sprintf("%s;", err.Error())}, "\n")
	}
	return errStr
}

/*
MarshalJSON handles the custom serialization case caused by case where the "data"
element of a document might be either a single resource object, or a collection of
them.
*/
func (d *Document) MarshalJSON() ([]byte, error) {
	// we use the MarshalDoc type to avoid recursively calling this function below
	// when we marshal
	type MarshalDoc Document
	doc := MarshalDoc(*d)

	switch d.Mode {
	case ObjectMode:
		var data *Object
		if len(d.Data) > 0 {
			data = d.Data[0]
		}

		// subtype that overrides regular data List with a single Object for
		// fetch style request/responses
		type MarshalObject struct {
			MarshalDoc
			Data *Object `json:"data"`
		}

		return json.Marshal(MarshalObject{
			MarshalDoc: doc,
			Data:       data,
		})

	case ErrorMode:
		// subtype that omits data as expected for error responses. We cannot simply
		// use json:"-" for the data attribute otherwise it will not override the
		// default struct tag of it the composed MarshalDoc struct.
		type MarshalError struct {
			MarshalDoc
			Data *Object `json:"data,omitempty"`
		}

		return json.Marshal(MarshalError{
			MarshalDoc: doc,
		})

	case ListMode:
		return json.Marshal(doc)
	default:
		return nil, ISE(fmt.Sprintf("Unexpected DocumentMode value when marshaling: %d", d.Mode))
	}
}
<commit_msg>Document go-style review<commit_after>package jsh

import (
	"encoding/json"
	"fmt"
	"net/http"
	"strings"
)

// DocumentMode allows different specification settings to be enforced
// based on the specified mode.
type DocumentMode int

const (
	// ObjectMode enforces fetch request/response specifications
	ObjectMode DocumentMode = iota
	// ListMode enforces listing request/response specifications
	ListMode
	// ErrorMode enforces error response specifications
	ErrorMode
)

// IncludeJSONAPIVersion is an option that allows consumers to include/remove the `jsonapi`
// top-level member from server responses.
var IncludeJSONAPIVersion = true

// JSONAPI is the top-level member of a JSONAPI document that includes
// the server compatible version of the JSONAPI specification.
type JSONAPI struct {
	Version string `json:"version"`
}

/*
Document represents a top level JSON formatted Document.
Refer to the JSON API Specification for a full descriptor
of each attribute: http://jsonapi.org/format/#document-structure
*/
type Document struct {
	Data List `json:"data"`
	// Object   *Object     `json:"-"`
	Errors   ErrorList   `json:"errors,omitempty"`
	Links    *Links      `json:"links,omitempty"`
	Included []*Object   `json:"included,omitempty"`
	Meta     interface{} `json:"meta,omitempty"`
	JSONAPI  *JSONAPI    `json:"jsonapi,omitempty"`
	// Status is an HTTP Status Code
	Status int `json:"-"`
	// DataMode to enforce for the document
	Mode DocumentMode `json:"-"`
	// empty is used to signify that the response shouldn't contain a json payload
	// in the case that we only want to return an HTTP Status Code in order to bypass
	// validation steps.
	empty bool
	// validated confirms whether or not the document as a whole is validated and
	// in a safe-to-send state.
	validated bool
}

/*
New instantiates a new JSON Document object.
*/
func New() *Document {
	json := &Document{}
	if IncludeJSONAPIVersion {
		json.JSONAPI = &JSONAPI{
			Version: JSONAPIVersion,
		}
	}

	return json
}

/*
Build creates a Sendable Document with the provided sendable payload, either Data or
errors. Build also assumes you've already validated your data with .Validate() so
it should be used carefully.
*/
func Build(payload Sendable) *Document {
	document := New()
	document.validated = true

	switch p := payload.(type) {
	case *Document:
		document = p
	case *Object:
		document.Data = List{p}
		document.Status = p.Status
		document.Mode = ObjectMode
	case List:
		document.Data = p
		document.Status = http.StatusOK
		document.Mode = ListMode
	case *IDObject:
		if p == nil {
			document.Data = nil
		} else {
			document.Data = List{p.ToObject()}
		}
		document.Status = http.StatusOK
		document.Mode = ObjectMode
	case IDList:
		document.Data = p.ToList()
		document.Status = http.StatusOK
		document.Mode = ListMode
	case *Error:
		document.Errors = ErrorList{p}
		document.Status = p.Status
		document.Mode = ErrorMode
	case ErrorList:
		document.Errors = p
		document.Status = p[0].Status
		document.Mode = ErrorMode
	}
	return document
}

/*
Validate performs document level checks against the JSONAPI specification. It is
assumed that if this call returns without an error, your document is valid and
can be sent as a request or response.
*/
func (d *Document) Validate(r *http.Request, isResponse bool) *Error {

	// if sending a response, we must have a valid HTTP status at the very least
	// to send
	if isResponse && d.Status < 100 || d.Status > 600 {
		return ISE("Response HTTP Status is outside of valid range")
	}

	// There are certain cases such as HTTP 204 that send without a payload,
	// this is the short circuit to make sure we don't false alarm on those cases
	if d.empty {
		return nil
	}

	// if we have errors, and they have been added in a way that does not trigger
	// error mode, set it now so we perform the proper validations.
	if d.HasErrors() && d.Mode != ErrorMode {
		d.Mode = ErrorMode
	}

	switch d.Mode {
	case ErrorMode:
		if d.HasData() {
			return ISE("Attempting to respond with 'data' in an error response")
		}
	case ObjectMode:
		if d.HasData() && len(d.Data) > 1 {
			return ISE("Cannot set more than one data object in 'ObjectMode'")
		}
	case ListMode:
		if !d.HasErrors() && d.Data == nil {
			return ISE("Data cannot be nil in 'ListMode', use empty array")
		}
	}

	if !d.HasData() && d.Included != nil {
		return ISE("'included' should only be set for a response if 'data' is as well")
	}

	err := d.Data.Validate(r, isResponse)
	if err != nil {
		return err
	}

	err = d.Errors.Validate(r, isResponse)
	if err != nil {
		return err
	}

	d.validated = true

	return nil
}

// AddObject adds another object to the JSON Document.
func (d *Document) AddObject(object *Object) *Error {
	if d.Mode == ErrorMode {
		return ISE("Invalid attempt to add data to an error document")
	}
	if d.Mode == ObjectMode && len(d.Data) == 1 {
		return ISE("Invalid attempt to add multiple objects to a single object document")
	}

	// if not yet set, add the associated HTTP status with the object
	if d.Status == 0 {
		d.Status = object.Status
	}

	// finally, actually add the object to data List
	d.Data = append(d.Data, object)
	return nil
}

// AddError adds an error to the Document. It will also set the document Mode to
// "ErrorMode" if not done so already.
func (d *Document) AddError(newErr *Error) *Error {
	if d.HasData() {
		return ISE("Invalid attempt to add an error to a document containing data")
	}

	if newErr.Status == 0 {
		return ISE("No HTTP Status code provided for error, cannot add to document")
	}
	if d.Status == 0 {
		d.Status = newErr.Status
	}

	// set document to error mode
	d.Errors = append(d.Errors, newErr)
	d.Mode = ErrorMode
	return nil
}

// First will return the first object from the document data if possible.
func (d *Document) First() *Object {
	if !d.HasData() {
		return nil
	}

	return d.Data[0]
}

// HasData will return true if the JSON document's Data field is set
func (d *Document) HasData() bool {
	return d.Data != nil && len(d.Data) > 0
}

// HasErrors will return true if the Errors attribute is not nil.
func (d *Document) HasErrors() bool {
	return d.Errors != nil && len(d.Errors) > 0
}

// Error implements error for the Document type.
func (d *Document) Error() string {
	errStr := "Errors:"
	for _, err := range d.Errors {
		errStr = strings.Join([]string{errStr, fmt.Sprintf("%s;", err.Error())}, "\n")
	}
	return errStr
}

/*
MarshalJSON handles the custom serialization case caused by case where the "data"
element of a document might be either a single resource object, or a collection of
them.
*/
func (d *Document) MarshalJSON() ([]byte, error) {
	// we use the MarshalDoc type to avoid recursively calling this function below
	// when we marshal
	type MarshalDoc Document
	doc := MarshalDoc(*d)

	switch d.Mode {
	case ObjectMode:
		var data *Object
		if len(d.Data) > 0 {
			data = d.Data[0]
		}

		// subtype that overrides regular data List with a single Object for
		// fetch style request/responses
		type MarshalObject struct {
			MarshalDoc
			Data *Object `json:"data"`
		}

		return json.Marshal(MarshalObject{
			MarshalDoc: doc,
			Data:       data,
		})

	case ErrorMode:
		// subtype that omits data as expected for error responses. We cannot simply
		// use json:"-" for the data attribute otherwise it will not override the
		// default struct tag of it the composed MarshalDoc struct.
		type MarshalError struct {
			MarshalDoc
			Data *Object `json:"data,omitempty"`
		}

		return json.Marshal(MarshalError{
			MarshalDoc: doc,
		})

	case ListMode:
		return json.Marshal(doc)
	default:
		return nil, ISE(fmt.Sprintf("Unexpected DocumentMode value when marshaling: %d", d.Mode))
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 The Serviced Authors.
// 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 web

import (
	"crypto/tls"
	"errors"
	"fmt"
	"net"
	"time"

	"github.com/control-center/serviced/auth"
	"github.com/control-center/serviced/logging"
	"github.com/control-center/serviced/proxy"
	"github.com/control-center/serviced/utils"
	"github.com/control-center/serviced/zzk/registry"
)

// initialize the logger
var plog = logging.PackageLogger()

// ipmap keeps track of all ipv4 addresses on this host
var ipmap = make(map[string]struct{})

func init() {
	// set up the ipmap
	ips, err := utils.GetIPv4Addresses()
	if err != nil {
		plog.WithError(err).Fatal("Could not get interface ip addresses")
	}
	for _, ip := range ips {
		ipmap[ip] = struct{}{}
	}
}

// IsLocalAddress returns true if the ip address is available on this host
func IsLocalAddress(ip string) bool {
	_, ok := ipmap[ip]
	return ok
}

// GetCertFiles returns the cert and key file if none is specified
func GetCertFiles(certFile, keyFile string) (string, string) {

	// set the cert file if it doesn't exist
	if certFile == "" {
		var err error
		certFile, err = proxy.TempCertFile()
		if err != nil {
			plog.WithError(err).Fatal("Could not create temp cert file")
		}
	}

	// set the key file if it doesn't exist
	if keyFile == "" {
		var err error
		keyFile, err = proxy.TempKeyFile()
		if err != nil {
			plog.WithError(err).Fatal("Could not create temp key file")
		}
	}

	return certFile, keyFile
}

// Dialer interface to make getRemoteConnection testable.
type dialerInterface interface {
	Dial(string, string) (net.Conn, error)
}

type netDialer struct{}

func (d *netDialer) Dial(network, address string) (net.Conn, error) {
	return net.Dial(network, address)
}

func newNetDialer() dialerInterface {
	return &netDialer{}
}

type tlsDialer struct {
	config *tls.Config
}

func (d *tlsDialer) Dial(network, address string) (net.Conn, error) {
	return tls.Dial(network, address, d.config)
}

func newTlsDialer(config *tls.Config) dialerInterface {
	return &tlsDialer{config: config}
}

// GetRemoteConnection returns a connection to a remote address
func GetRemoteConnection(useTLS bool, export *registry.ExportDetails) (remote net.Conn, err error) {
	var dialer dialerInterface
	if useTLS {
		config := tls.Config{InsecureSkipVerify: true}
		dialer = newTlsDialer(&config)
	} else {
		dialer = newNetDialer()
	}
	return getRemoteConnection(export, dialer)
}

func getRemoteConnection(export *registry.ExportDetails, dialer dialerInterface) (net.Conn, error) {
	// If the exported endpoint is on this Host, we don't go through the mux.
	if IsLocalAddress(export.HostIP) {
		// if the address is local return a connection directly to the container
		address := fmt.Sprintf("%s:%d", export.PrivateIP, export.PortNumber)
		return dialer.Dial("tcp4", address)
	}

	// Set up the remote address for the mux
	remoteAddress := fmt.Sprintf("%s:%d", export.HostIP, export.MuxPort)
	remote, err := dialer.Dial("tcp4", remoteAddress)

	// Prevent a panic if we couldn't connect to the mux.
	if err != nil {
		return nil, err
	}

	// Set the muxHeader on the remote connection so it knows what service to
	// proxy the connection to.
	muxHeader, err := utils.PackTCPAddress(export.PrivateIP, export.PortNumber)
	if err != nil {
		return nil, err
	}

	muxHeader, err = auth.BuildMuxHeader(muxHeader)
	if err != nil {
		plog.WithError(err).Error("Error building authenticated mux header.")
		return nil, err
	}
	remote.Write(muxHeader)

	// Check for errors writing the mux header.
	if _, err = remote.Write(muxHeader); err != nil {
		return nil, err
	}

	return remote, nil
}

// TCPKeepAliveListener keeps a listener connection alive for the duration
// of a cancellable
type TCPKeepAliveListener struct {
	*net.TCPListener
	cancel <-chan struct{}
}

// Accept returns the connection to the listener
func (ln TCPKeepAliveListener) Accept() (c net.Conn, err error) {
	for {
		ln.SetDeadline(time.Now().Add(time.Second))
		select {
		case <-ln.cancel:
			return nil, errors.New("port closed")
		default:
		}

		conn, err := ln.AcceptTCP()
		if err != nil {
			switch err := err.(type) {
			case net.Error:
				if err.Timeout() {
					continue
				}
			}
			return nil, err
		}
		conn.SetKeepAlive(true)
		conn.SetKeepAlivePeriod(3 * time.Minute)

		// and return the connection.
		return conn, nil
	}
}
<commit_msg>Remove double header write from merge<commit_after>// Copyright 2016 The Serviced Authors.
// 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 web

import (
	"crypto/tls"
	"errors"
	"fmt"
	"net"
	"time"

	"github.com/control-center/serviced/auth"
	"github.com/control-center/serviced/logging"
	"github.com/control-center/serviced/proxy"
	"github.com/control-center/serviced/utils"
	"github.com/control-center/serviced/zzk/registry"
)

// initialize the logger
var plog = logging.PackageLogger()

// ipmap keeps track of all ipv4 addresses on this host
var ipmap = make(map[string]struct{})

func init() {
	// set up the ipmap
	ips, err := utils.GetIPv4Addresses()
	if err != nil {
		plog.WithError(err).Fatal("Could not get interface ip addresses")
	}
	for _, ip := range ips {
		ipmap[ip] = struct{}{}
	}
}

// IsLocalAddress returns true if the ip address is available on this host
func IsLocalAddress(ip string) bool {
	_, ok := ipmap[ip]
	return ok
}

// GetCertFiles returns the cert and key file if none is specified
func GetCertFiles(certFile, keyFile string) (string, string) {

	// set the cert file if it doesn't exist
	if certFile == "" {
		var err error
		certFile, err = proxy.TempCertFile()
		if err != nil {
			plog.WithError(err).Fatal("Could not create temp cert file")
		}
	}

	// set the key file if it doesn't exist
	if keyFile == "" {
		var err error
		keyFile, err = proxy.TempKeyFile()
		if err != nil {
			plog.WithError(err).Fatal("Could not create temp key file")
		}
	}

	return certFile, keyFile
}

// Dialer interface to make getRemoteConnection testable.
type dialerInterface interface {
	Dial(string, string) (net.Conn, error)
}

type netDialer struct{}

func (d *netDialer) Dial(network, address string) (net.Conn, error) {
	return net.Dial(network, address)
}

func newNetDialer() dialerInterface {
	return &netDialer{}
}

type tlsDialer struct {
	config *tls.Config
}

func (d *tlsDialer) Dial(network, address string) (net.Conn, error) {
	return tls.Dial(network, address, d.config)
}

func newTlsDialer(config *tls.Config) dialerInterface {
	return &tlsDialer{config: config}
}

// GetRemoteConnection returns a connection to a remote address
func GetRemoteConnection(useTLS bool, export *registry.ExportDetails) (remote net.Conn, err error) {
	var dialer dialerInterface
	if useTLS {
		config := tls.Config{InsecureSkipVerify: true}
		dialer = newTlsDialer(&config)
	} else {
		dialer = newNetDialer()
	}
	return getRemoteConnection(export, dialer)
}

func getRemoteConnection(export *registry.ExportDetails, dialer dialerInterface) (net.Conn, error) {
	// If the exported endpoint is on this Host, we don't go through the mux.
	if IsLocalAddress(export.HostIP) {
		// if the address is local return a connection directly to the container
		address := fmt.Sprintf("%s:%d", export.PrivateIP, export.PortNumber)
		return dialer.Dial("tcp4", address)
	}

	// Set up the remote address for the mux
	remoteAddress := fmt.Sprintf("%s:%d", export.HostIP, export.MuxPort)
	remote, err := dialer.Dial("tcp4", remoteAddress)

	// Prevent a panic if we couldn't connect to the mux.
	if err != nil {
		return nil, err
	}

	// Set the muxHeader on the remote connection so it knows what service to
	// proxy the connection to.
	muxHeader, err := utils.PackTCPAddress(export.PrivateIP, export.PortNumber)
	if err != nil {
		return nil, err
	}

	muxHeader, err = auth.BuildMuxHeader(muxHeader)
	if err != nil {
		plog.WithError(err).Error("Error building authenticated mux header.")
		return nil, err
	}

	// Check for errors writing the mux header.
	if _, err = remote.Write(muxHeader); err != nil {
		return nil, err
	}

	return remote, nil
}

// TCPKeepAliveListener keeps a listener connection alive for the duration
// of a cancellable
type TCPKeepAliveListener struct {
	*net.TCPListener
	cancel <-chan struct{}
}

// Accept returns the connection to the listener
func (ln TCPKeepAliveListener) Accept() (c net.Conn, err error) {
	for {
		ln.SetDeadline(time.Now().Add(time.Second))
		select {
		case <-ln.cancel:
			return nil, errors.New("port closed")
		default:
		}

		conn, err := ln.AcceptTCP()
		if err != nil {
			switch err := err.(type) {
			case net.Error:
				if err.Timeout() {
					continue
				}
			}
			return nil, err
		}
		conn.SetKeepAlive(true)
		conn.SetKeepAlivePeriod(3 * time.Minute)

		// and return the connection.
		return conn, nil
	}
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"image"
	"image/color"
	"image/png"
	"math"
	"os"
	"strconv"
	"time"
)

// WIDTH defines the width of the created image
const WIDTH = 640

// HEIGHT defines the height of the created image
const HEIGHT = 400

func euclideanDistance(x1, y1, x2, y2 int) float64 {
	return math.Sqrt(math.Pow(float64(x2-x1), 2) + math.Pow(float64(y2-y1), 2))
}

func fivePoints(randNum int64) [5][2]int {
	var result [5][2]int
	for i, d := range [5]int64{7, 11, 13, 17, 19} {
		x := (int64(randNum/d) + (randNum % (135 * d))) % WIDTH
		y := (int64(3*randNum/d) + (randNum % (287 * d))) % HEIGHT
		result[i][0] = int(x)
		result[i][1] = int(y)
	}
	return result
}

func drawRandom(img *image.RGBA, randNum int64) {
	five := fivePoints(randNum)
	moreWhite := func(v int64) int64 {
		return int64((220*v)/256) + 36
	}

	for x := 0; x < WIDTH; x++ {
		for y := 0; y < HEIGHT; y++ {
			d1 := euclideanDistance(x, y, five[0][0], five[0][1]) + 2*euclideanDistance(x, y, five[1][0], five[1][1])
			d2 := euclideanDistance(x, y, five[2][0], five[2][1]) + d1 - 5*euclideanDistance(x, y, five[3][0], five[3][1])
			d3 := euclideanDistance(x, y, five[4][0], five[4][1])

			r := moreWhite(int64(d1) % 256)
			g := moreWhite(int64(d2) % 256)
			b := moreWhite(int64(d3) % 256)

			c := color.RGBA{uint8(r), uint8(g), uint8(b), 255}
			img.Set(x, y, c)
		}
	}
}

// Draw actually draws an image based on `randNum` and stores the result at `filepath`
func Draw(filepath string, randNum int64) error {
	img := image.NewRGBA(image.Rectangle{image.Point{0, 0}, image.Point{WIDTH, HEIGHT}})

	drawRandom(img, randNum)

	fd, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer fd.Close()

	return png.Encode(fd, img)
}

func main() {
	var num int64
	var filepath string

	switch len(os.Args) {
	case 1:
		num = time.Now().Unix()
		fmt.Printf("Using current time as random seed: %d\n", num)
	case 2:
		filepath = "randimg.png"
		fallthrough
	case 3:
		n, err := strconv.Atoi(os.Args[1])
		if err != nil {
			panic(fmt.Errorf("Expected integer as positional argument; got '%s'", os.Args[1]))
		}
		num = int64(n)
		if len(os.Args) > 2 {
			filepath = os.Args[2]
		}
	default:
		panic(fmt.Errorf("usage: ./randimg <integer> <output.png>"))
	}

	if err := Draw(filepath, num); err != nil {
		panic(err)
	}
}
<commit_msg>Prefer non-capitalized text in error messages.<commit_after>package main

import (
	"fmt"
	"image"
	"image/color"
	"image/png"
	"math"
	"os"
	"strconv"
	"time"
)

// WIDTH defines the width of the created image
const WIDTH = 640

// HEIGHT defines the height of the created image
const HEIGHT = 400

func euclideanDistance(x1, y1, x2, y2 int) float64 {
	return math.Sqrt(math.Pow(float64(x2-x1), 2) + math.Pow(float64(y2-y1), 2))
}

func fivePoints(randNum int64) [5][2]int {
	var result [5][2]int
	for i, d := range [5]int64{7, 11, 13, 17, 19} {
		x := (int64(randNum/d) + (randNum % (135 * d))) % WIDTH
		y := (int64(3*randNum/d) + (randNum % (287 * d))) % HEIGHT
		result[i][0] = int(x)
		result[i][1] = int(y)
	}
	return result
}

func drawRandom(img *image.RGBA, randNum int64) {
	five := fivePoints(randNum)
	moreWhite := func(v int64) int64 {
		return int64((220*v)/256) + 36
	}

	for x := 0; x < WIDTH; x++ {
		for y := 0; y < HEIGHT; y++ {
			d1 := euclideanDistance(x, y, five[0][0], five[0][1]) + 2*euclideanDistance(x, y, five[1][0], five[1][1])
			d2 := euclideanDistance(x, y, five[2][0], five[2][1]) + d1 - 5*euclideanDistance(x, y, five[3][0], five[3][1])
			d3 := euclideanDistance(x, y, five[4][0], five[4][1])

			r := moreWhite(int64(d1) % 256)
			g := moreWhite(int64(d2) % 256)
			b := moreWhite(int64(d3) % 256)

			c := color.RGBA{uint8(r), uint8(g), uint8(b), 255}
			img.Set(x, y, c)
		}
	}
}

// Draw actually draws an image based on `randNum` and stores the result at `filepath`
func Draw(filepath string, randNum int64) error {
	img := image.NewRGBA(image.Rectangle{image.Point{0, 0}, image.Point{WIDTH, HEIGHT}})

	drawRandom(img, randNum)

	fd, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer fd.Close()

	return png.Encode(fd, img)
}

func main() {
	var num int64
	var filepath string

	switch len(os.Args) {
	case 1:
		num = time.Now().Unix()
		fmt.Printf("using current time as random seed: %d\n", num)
	case 2:
		filepath = "randimg.png"
		fallthrough
	case 3:
		n, err := strconv.Atoi(os.Args[1])
		if err != nil {
			panic(fmt.Errorf("expected integer as positional argument; got '%s'", os.Args[1]))
		}
		num = int64(n)
		if len(os.Args) > 2 {
			filepath = os.Args[2]
		}
	default:
		panic(fmt.Errorf("usage: ./randimg <integer> <output.png>"))
	}

	if err := Draw(filepath, num); err != nil {
		panic(err)
	}
}
<|endoftext|>


<commit_before>package domaincheck

import (
	"strings"
)

// Valid return true if domain is valid
func Valid(domain string) bool {
	// strip "*." prefix if exists
	if len(domain) >= 2 && domain[:2] == "*." {
		domain = domain[2:]
	}

	// should not see any '*' any more
	if strings.ContainsAny(domain, "*") {
		return false
	}

	// should not contain '@'
	if strings.ContainsAny(domain, "@") {
		return false
	}

	tokens := strings.Split(domain, ".")
	// should have at least two tokens
	if len(tokens) < 2 {
		return false
	}

	for _, token := range tokens {
		if len(token) == 0 {
			return false // consecutive '.' is forbidden
		}

		// token begins or ends with '-' is bad
		if token[0] == '-' || token[len(token)-1] == '-' {
			return false
		}
	}

	return true
}

// ValidWildcard returns true if domain is a valid wildcard one
func ValidWildcard(domain string) bool {
	if Valid(domain) && domain[:2] == "*." {
		return true
	}
	return false
}

// StemDomain returns the stem domain with wildcard prefix stripped (if any).
func StemDomain(domain string) string {
	if ValidWildcard(domain) {
		return domain[2:]
	}

	if Valid(domain) {
		return domain
	}

	return ""
}
<commit_msg>add one comment<commit_after>package domaincheck

import (
	"strings"
)

// Valid return true if domain is valid
func Valid(domain string) bool {
	// strip "*." prefix if exists
	if len(domain) >= 2 && domain[:2] == "*." {
		domain = domain[2:]
	}

	// should not see any '*' any more
	if strings.ContainsAny(domain, "*") {
		return false
	}

	// should not contain '@'
	if strings.ContainsAny(domain, "@") {
		return false
	}

	tokens := strings.Split(domain, ".")
	// should have at least two tokens
	if len(tokens) < 2 {
		return false
	}

	for _, token := range tokens {
		if len(token) == 0 {
			return false // consecutive '.' is forbidden
		}

		// token begins or ends with '-' is bad
		if token[0] == '-' || token[len(token)-1] == '-' {
			return false
		}
	}

	return true
}

// ValidWildcard returns true if domain is a valid wildcard one
func ValidWildcard(domain string) bool {
	// valid domain should be at least 3 characters long.
	if Valid(domain) && domain[:2] == "*." {
		return true
	}
	return false
}

// StemDomain returns the stem domain with wildcard prefix stripped (if any).
func StemDomain(domain string) string {
	if ValidWildcard(domain) {
		return domain[2:]
	}

	if Valid(domain) {
		return domain
	}

	return ""
}
<|endoftext|>


<commit_before>package draw2dgl

import (
	"image"
	"image/color"
	"image/draw"
	"runtime"

	"code.google.com/p/freetype-go/freetype/raster"
	"github.com/go-gl/gl/v2.1/gl"
	"github.com/llgcode/draw2d/draw2d"
)

func init() {
	runtime.LockOSThread()
}

type GLPainter struct {
	// The Porter-Duff composition operator.
	Op draw.Op
	// The 16-bit color to paint the spans.
	cr, cg, cb uint8
	ca         uint32
	colors     []uint8
	vertices   []int32
}

const M16 uint32 = 1<<16 - 1

// Paint satisfies the Painter interface by painting ss onto an image.RGBA.
func (p *GLPainter) Paint(ss []raster.Span, done bool) {
	//gl.Begin(gl.LINES)
	sslen := len(ss)
	clenrequired := sslen * 8
	vlenrequired := sslen * 4
	if clenrequired >= (cap(p.colors) - len(p.colors)) {
		p.Flush()

		if clenrequired >= cap(p.colors) {
			p.vertices = make([]int32, 0, vlenrequired+(vlenrequired/2))
			p.colors = make([]uint8, 0, clenrequired+(clenrequired/2))
		}
	}
	vi := len(p.vertices)
	ci := len(p.colors)
	p.vertices = p.vertices[0 : vi+vlenrequired]
	p.colors = p.colors[0 : ci+clenrequired]
	var (
		colors   []uint8
		vertices []int32
	)
	for _, s := range ss {
		ma := s.A >> 16
		a := uint8((ma * p.ca / M16) >> 8)
		colors = p.colors[ci:]
		colors[0] = p.cr
		colors[1] = p.cg
		colors[2] = p.cb
		colors[3] = a
		colors[4] = p.cr
		colors[5] = p.cg
		colors[6] = p.cb
		colors[7] = a
		ci += 8
		vertices = p.vertices[vi:]
		vertices[0] = int32(s.X0)
		vertices[1] = int32(s.Y)
		vertices[2] = int32(s.X1)
		vertices[3] = int32(s.Y)
		vi += 4
	}
}

func (p *GLPainter) Flush() {
	if len(p.vertices) != 0 {
		gl.EnableClientState(gl.COLOR_ARRAY)
		gl.EnableClientState(gl.VERTEX_ARRAY)
		gl.ColorPointer(4, gl.UNSIGNED_BYTE, 0, gl.Ptr(p.colors))
		gl.VertexPointer(2, gl.INT, 0, gl.Ptr(p.vertices))

		// draw lines
		gl.DrawArrays(gl.LINES, 0, int32(len(p.vertices)/2))
		gl.DisableClientState(gl.VERTEX_ARRAY)
		gl.DisableClientState(gl.COLOR_ARRAY)
		p.vertices = p.vertices[0:0]
		p.colors = p.colors[0:0]
	}
}

// SetColor sets the color to paint the spans.
func (p *GLPainter) SetColor(c color.Color) {
	r, g, b, a := c.RGBA()
	if a == 0 {
		p.cr = 0
		p.cg = 0
		p.cb = 0
		p.ca = a
	} else {
		p.cr = uint8((r * M16 / a) >> 8)
		p.cg = uint8((g * M16 / a) >> 8)
		p.cb = uint8((b * M16 / a) >> 8)
		p.ca = a
	}
}

// NewRGBAPainter creates a new RGBAPainter for the given image.
func NewGLPainter() *GLPainter {
	p := new(GLPainter)
	p.vertices = make([]int32, 0, 1024)
	p.colors = make([]uint8, 0, 1024)
	return p
}

type GraphicContext struct {
	*draw2d.StackGraphicContext
	painter          *GLPainter
	fillRasterizer   *raster.Rasterizer
	strokeRasterizer *raster.Rasterizer
}

type GLVertex struct {
	x, y float64
}

func NewGLVertex() *GLVertex {
	return &GLVertex{}
}

func (glVertex *GLVertex) NextCommand(cmd draw2d.VertexCommand) {

}

func (glVertex *GLVertex) Vertex(x, y float64) {
	gl.Vertex2d(x, y)
}

/**
 * Create a new Graphic context from an image
 */
func NewGraphicContext(width, height int) *GraphicContext {
	gc := &GraphicContext{
		draw2d.NewStackGraphicContext(),
		NewGLPainter(),
		raster.NewRasterizer(width, height),
		raster.NewRasterizer(width, height),
	}
	return gc
}

func (gc *GraphicContext) CreateStringPath(s string, x, y float64) float64 {
	panic("not implemented")
}

func (gc *GraphicContext) FillStringAt(text string, x, y float64) (cursor float64) {
	panic("not implemented")
}

func (gc *GraphicContext) GetStringBounds(s string) (left, top, right, bottom float64) {
	panic("not implemented")
}

func (gc *GraphicContext) StrokeString(text string) (cursor float64) {
	return gc.StrokeStringAt(text, 0, 0)
}

func (gc *GraphicContext) StrokeStringAt(text string, x, y float64) (cursor float64) {
	width := gc.CreateStringPath(text, x, y)
	gc.Stroke()
	return width
}

func (gc *GraphicContext) SetDPI(dpi int) {

}

func (gc *GraphicContext) GetDPI() int {
	return -1
}

func (gc *GraphicContext) Clear() {

}

func (gc *GraphicContext) ClearRect(x1, y1, x2, y2 int) {

}

func (gc *GraphicContext) DrawImage(img image.Image) {

}

func (gc *GraphicContext) FillString(text string) (cursor float64) {
	return 0
}

func (gc *GraphicContext) paint(rasterizer *raster.Rasterizer, color color.Color) {
	gc.painter.SetColor(color)
	rasterizer.Rasterize(gc.painter)
	rasterizer.Clear()
	gc.painter.Flush()
}

func (gc *GraphicContext) Stroke(paths ...*draw2d.PathStorage) {
	paths = append(paths, gc.Current.Path)
	gc.strokeRasterizer.UseNonZeroWinding = true

	stroker := draw2d.NewLineStroker(gc.Current.Cap, gc.Current.Join, draw2d.NewVertexMatrixTransform(gc.Current.Tr, draw2d.NewVertexAdder(gc.strokeRasterizer)))
	stroker.HalfLineWidth = gc.Current.LineWidth / 2
	var pathConverter *draw2d.PathConverter
	if gc.Current.Dash != nil && len(gc.Current.Dash) > 0 {
		dasher := draw2d.NewDashConverter(gc.Current.Dash, gc.Current.DashOffset, stroker)
		pathConverter = draw2d.NewPathConverter(dasher)
	} else {
		pathConverter = draw2d.NewPathConverter(stroker)
	}
	pathConverter.ApproximationScale = gc.Current.Tr.GetScale() // From agg code
	pathConverter.Convert(paths...)

	gc.paint(gc.strokeRasterizer, gc.Current.StrokeColor)
	gc.Current.Path.Clear()
}

func (gc *GraphicContext) Fill(paths ...*draw2d.PathStorage) {
	paths = append(paths, gc.Current.Path)
	gc.fillRasterizer.UseNonZeroWinding = gc.Current.FillRule.UseNonZeroWinding()

	pathConverter := draw2d.NewPathConverter(draw2d.NewVertexMatrixTransform(gc.Current.Tr, draw2d.NewVertexAdder(gc.fillRasterizer)))
	pathConverter.ApproximationScale = gc.Current.Tr.GetScale() // From agg code
	pathConverter.Convert(paths...)

	gc.paint(gc.fillRasterizer, gc.Current.FillColor)
	gc.Current.Path.Clear()
}

/*
func (gc *GraphicContext) Fill(paths ...*draw2d.PathStorage) {
	paths = append(paths, gc.Current.Path)
	gc.fillRasterizer.UseNonZeroWinding = gc.Current.FillRule.UseNonZeroWinding()

	pathConverter := draw2d.NewPathAdder(draw2d.NewMatrixTransformAdder(gc.Current.Tr, gc.fillRasterizer))
	pathConverter.ApproximationScale = gc.Current.Tr.GetScale()
	pathConverter.Convert(paths...)

	gc.paint(gc.fillRasterizer, gc.Current.FillColor)
	gc.Current.Path.Clear()
}
*/

func (gc *GraphicContext) FillStroke(paths ...*draw2d.PathStorage) {
	gc.fillRasterizer.UseNonZeroWinding = gc.Current.FillRule.UseNonZeroWinding()
	gc.strokeRasterizer.UseNonZeroWinding = true

	filler := draw2d.NewVertexMatrixTransform(gc.Current.Tr, draw2d.NewVertexAdder(gc.fillRasterizer))

	stroker := draw2d.NewLineStroker(gc.Current.Cap, gc.Current.Join, draw2d.NewVertexMatrixTransform(gc.Current.Tr, draw2d.NewVertexAdder(gc.strokeRasterizer)))
	stroker.HalfLineWidth = gc.Current.LineWidth / 2

	demux := draw2d.NewDemuxConverter(filler, stroker)
	paths = append(paths, gc.Current.Path)
	pathConverter := draw2d.NewPathConverter(demux)
	pathConverter.ApproximationScale = gc.Current.Tr.GetScale() // From agg code
	pathConverter.Convert(paths...)

	gc.paint(gc.fillRasterizer, gc.Current.FillColor)
	gc.paint(gc.strokeRasterizer, gc.Current.StrokeColor)
	gc.Current.Path = draw2d.NewPathStorage()
}
<commit_msg>draw2dgl: de-stutter types<commit_after>package draw2dgl

import (
	"image"
	"image/color"
	"image/draw"
	"runtime"

	"code.google.com/p/freetype-go/freetype/raster"
	"github.com/go-gl/gl/v2.1/gl"
	"github.com/llgcode/draw2d/draw2d"
)

func init() {
	runtime.LockOSThread()
}

type Painter struct {
	// The Porter-Duff composition operator.
	Op draw.Op
	// The 16-bit color to paint the spans.
	cr, cg, cb uint8
	ca         uint32
	colors     []uint8
	vertices   []int32
}

const M16 uint32 = 1<<16 - 1

// Paint satisfies the Painter interface by painting ss onto an image.RGBA.
func (p *Painter) Paint(ss []raster.Span, done bool) {
	//gl.Begin(gl.LINES)
	sslen := len(ss)
	clenrequired := sslen * 8
	vlenrequired := sslen * 4
	if clenrequired >= (cap(p.colors) - len(p.colors)) {
		p.Flush()

		if clenrequired >= cap(p.colors) {
			p.vertices = make([]int32, 0, vlenrequired+(vlenrequired/2))
			p.colors = make([]uint8, 0, clenrequired+(clenrequired/2))
		}
	}
	vi := len(p.vertices)
	ci := len(p.colors)
	p.vertices = p.vertices[0 : vi+vlenrequired]
	p.colors = p.colors[0 : ci+clenrequired]
	var (
		colors   []uint8
		vertices []int32
	)
	for _, s := range ss {
		ma := s.A >> 16
		a := uint8((ma * p.ca / M16) >> 8)
		colors = p.colors[ci:]
		colors[0] = p.cr
		colors[1] = p.cg
		colors[2] = p.cb
		colors[3] = a
		colors[4] = p.cr
		colors[5] = p.cg
		colors[6] = p.cb
		colors[7] = a
		ci += 8
		vertices = p.vertices[vi:]
		vertices[0] = int32(s.X0)
		vertices[1] = int32(s.Y)
		vertices[2] = int32(s.X1)
		vertices[3] = int32(s.Y)
		vi += 4
	}
}

func (p *Painter) Flush() {
	if len(p.vertices) != 0 {
		gl.EnableClientState(gl.COLOR_ARRAY)
		gl.EnableClientState(gl.VERTEX_ARRAY)
		gl.ColorPointer(4, gl.UNSIGNED_BYTE, 0, gl.Ptr(p.colors))
		gl.VertexPointer(2, gl.INT, 0, gl.Ptr(p.vertices))

		// draw lines
		gl.DrawArrays(gl.LINES, 0, int32(len(p.vertices)/2))
		gl.DisableClientState(gl.VERTEX_ARRAY)
		gl.DisableClientState(gl.COLOR_ARRAY)
		p.vertices = p.vertices[0:0]
		p.colors = p.colors[0:0]
	}
}

// SetColor sets the color to paint the spans.
func (p *Painter) SetColor(c color.Color) {
	r, g, b, a := c.RGBA()
	if a == 0 {
		p.cr = 0
		p.cg = 0
		p.cb = 0
		p.ca = a
	} else {
		p.cr = uint8((r * M16 / a) >> 8)
		p.cg = uint8((g * M16 / a) >> 8)
		p.cb = uint8((b * M16 / a) >> 8)
		p.ca = a
	}
}

// NewRGBAPainter creates a new RGBAPainter for the given image.
func NewPainter() *Painter {
	p := new(Painter)
	p.vertices = make([]int32, 0, 1024)
	p.colors = make([]uint8, 0, 1024)
	return p
}

type GraphicContext struct {
	*draw2d.StackGraphicContext
	painter          *Painter
	fillRasterizer   *raster.Rasterizer
	strokeRasterizer *raster.Rasterizer
}

type Vertex struct {
	x, y float64
}

func NewVertex() *Vertex {
	return &Vertex{}
}

func (*Vertex) NextCommand(cmd draw2d.VertexCommand) {

}

func (*Vertex) Vertex(x, y float64) {
	gl.Vertex2d(x, y)
}

/**
 * Create a new Graphic context from an image
 */
func NewGraphicContext(width, height int) *GraphicContext {
	gc := &GraphicContext{
		draw2d.NewStackGraphicContext(),
		NewPainter(),
		raster.NewRasterizer(width, height),
		raster.NewRasterizer(width, height),
	}
	return gc
}

func (gc *GraphicContext) CreateStringPath(s string, x, y float64) float64 {
	panic("not implemented")
}

func (gc *GraphicContext) FillStringAt(text string, x, y float64) (cursor float64) {
	panic("not implemented")
}

func (gc *GraphicContext) GetStringBounds(s string) (left, top, right, bottom float64) {
	panic("not implemented")
}

func (gc *GraphicContext) StrokeString(text string) (cursor float64) {
	return gc.StrokeStringAt(text, 0, 0)
}

func (gc *GraphicContext) StrokeStringAt(text string, x, y float64) (cursor float64) {
	width := gc.CreateStringPath(text, x, y)
	gc.Stroke()
	return width
}

func (gc *GraphicContext) SetDPI(dpi int) {

}

func (gc *GraphicContext) GetDPI() int {
	return -1
}

func (gc *GraphicContext) Clear() {

}

func (gc *GraphicContext) ClearRect(x1, y1, x2, y2 int) {

}

func (gc *GraphicContext) DrawImage(img image.Image) {

}

func (gc *GraphicContext) FillString(text string) (cursor float64) {
	return 0
}

func (gc *GraphicContext) paint(rasterizer *raster.Rasterizer, color color.Color) {
	gc.painter.SetColor(color)
	rasterizer.Rasterize(gc.painter)
	rasterizer.Clear()
	gc.painter.Flush()
}

func (gc *GraphicContext) Stroke(paths ...*draw2d.PathStorage) {
	paths = append(paths, gc.Current.Path)
	gc.strokeRasterizer.UseNonZeroWinding = true

	stroker := draw2d.NewLineStroker(gc.Current.Cap, gc.Current.Join, draw2d.NewVertexMatrixTransform(gc.Current.Tr, draw2d.NewVertexAdder(gc.strokeRasterizer)))
	stroker.HalfLineWidth = gc.Current.LineWidth / 2
	var pathConverter *draw2d.PathConverter
	if gc.Current.Dash != nil && len(gc.Current.Dash) > 0 {
		dasher := draw2d.NewDashConverter(gc.Current.Dash, gc.Current.DashOffset, stroker)
		pathConverter = draw2d.NewPathConverter(dasher)
	} else {
		pathConverter = draw2d.NewPathConverter(stroker)
	}
	pathConverter.ApproximationScale = gc.Current.Tr.GetScale() // From agg code
	pathConverter.Convert(paths...)

	gc.paint(gc.strokeRasterizer, gc.Current.StrokeColor)
	gc.Current.Path.Clear()
}

func (gc *GraphicContext) Fill(paths ...*draw2d.PathStorage) {
	paths = append(paths, gc.Current.Path)
	gc.fillRasterizer.UseNonZeroWinding = gc.Current.FillRule.UseNonZeroWinding()

	pathConverter := draw2d.NewPathConverter(draw2d.NewVertexMatrixTransform(gc.Current.Tr, draw2d.NewVertexAdder(gc.fillRasterizer)))
	pathConverter.ApproximationScale = gc.Current.Tr.GetScale() // From agg code
	pathConverter.Convert(paths...)

	gc.paint(gc.fillRasterizer, gc.Current.FillColor)
	gc.Current.Path.Clear()
}

/*
func (gc *GraphicContext) Fill(paths ...*draw2d.PathStorage) {
	paths = append(paths, gc.Current.Path)
	gc.fillRasterizer.UseNonZeroWinding = gc.Current.FillRule.UseNonZeroWinding()

	pathConverter := draw2d.NewPathAdder(draw2d.NewMatrixTransformAdder(gc.Current.Tr, gc.fillRasterizer))
	pathConverter.ApproximationScale = gc.Current.Tr.GetScale()
	pathConverter.Convert(paths...)

	gc.paint(gc.fillRasterizer, gc.Current.FillColor)
	gc.Current.Path.Clear()
}
*/

func (gc *GraphicContext) FillStroke(paths ...*draw2d.PathStorage) {
	gc.fillRasterizer.UseNonZeroWinding = gc.Current.FillRule.UseNonZeroWinding()
	gc.strokeRasterizer.UseNonZeroWinding = true

	filler := draw2d.NewVertexMatrixTransform(gc.Current.Tr, draw2d.NewVertexAdder(gc.fillRasterizer))

	stroker := draw2d.NewLineStroker(gc.Current.Cap, gc.Current.Join, draw2d.NewVertexMatrixTransform(gc.Current.Tr, draw2d.NewVertexAdder(gc.strokeRasterizer)))
	stroker.HalfLineWidth = gc.Current.LineWidth / 2

	demux := draw2d.NewDemuxConverter(filler, stroker)
	paths = append(paths, gc.Current.Path)
	pathConverter := draw2d.NewPathConverter(demux)
	pathConverter.ApproximationScale = gc.Current.Tr.GetScale() // From agg code
	pathConverter.Convert(paths...)

	gc.paint(gc.fillRasterizer, gc.Current.FillColor)
	gc.paint(gc.strokeRasterizer, gc.Current.StrokeColor)
	gc.Current.Path = draw2d.NewPathStorage()
}
<|endoftext|>


<commit_before>// Copyright 2013-2015 Aerospike, Inc.
//
// 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 aerospike

import (
	"sync"

	. "github.com/aerospike/aerospike-client-go/types/atomic"
)

type Result struct {
	Record *Record
	Err    error
}

// Recordset encapsulates the result of Scan and Query commands.
type Recordset struct {
	// Records is a channel on which the resulting records will be sent back.
	// NOTE: Do not use Records directly. Range on channel returned by Results() instead.
	// Will be unexported in the future
	Records chan *Record
	// Errors is a channel on which all errors will be sent back.
	// NOTE: Do not use Records directly. Range on channel returned by Results() instead.
	// Will be unexported in the future
	Errors chan error

	wgGoroutines sync.WaitGroup
	goroutines   *AtomicInt

	active    *AtomicBool
	cancelled chan struct{}

	chanLock sync.Mutex
}

// NewRecordset generates a new RecordSet instance.
func newRecordset(recSize, goroutines int) *Recordset {
	rs := &Recordset{
		Records:    make(chan *Record, recSize),
		Errors:     make(chan error, goroutines),
		active:     NewAtomicBool(true),
		goroutines: NewAtomicInt(goroutines),
		cancelled:  make(chan struct{}),
	}
	rs.wgGoroutines.Add(goroutines)

	return rs
}

// IsActive returns true if the operation hasn't been finished or cancelled.
func (rcs *Recordset) IsActive() bool {
	return rcs.active.Get()
}

// Results returns a new receive-only channel with the results of the Scan/Query.
// This is a more idiomatic approach to the iterator pattern in getting the
// results back from the recordset, and doesn't require the user to write the
// ugly select in their code.
// Result contains a Record and an error reference.
//
// Example:
//
//  recordset, err := client.ScanAll(nil, namespace, set)
//  handleError(err)
//  for res := range recordset.Results() {
//    if res.Err != nil {
//      // handle error here
//    } else {
//      // process record here
//      fmt.Println(res.Record.Bins)
//    }
//  }
func (rcs *Recordset) Results() <-chan *Result {
	res := make(chan *Result, len(rcs.Records))

	go func() {
	L:
		for {
			select {
			case r := <-rcs.Records:
				if r != nil {
					res <- &Result{Record: r, Err: nil}
				} else {
					close(res)
					break L
				}
			case e := <-rcs.Errors:
				if e != nil {
					res <- &Result{Record: nil, Err: e}
				}
			}
		}
	}()

	return (<-chan *Result)(res)
}

// Close all streams from different nodes.
func (rcs *Recordset) Close() {
	// do it only once
	if rcs.active.CompareAndToggle(true) {
		// this will broadcast to all commands listening to the channel
		close(rcs.cancelled)

		// wait till all goroutines are done
		rcs.wgGoroutines.Wait()

		rcs.chanLock.Lock()
		defer rcs.chanLock.Unlock()
		close(rcs.Records)
		close(rcs.Errors)
	}
}

func (rcs *Recordset) signalEnd() {
	rcs.wgGoroutines.Done()
	if rcs.goroutines.DecrementAndGet() == 0 {
		rcs.Close()
	}
}

func (rcs *Recordset) sendError(err error) {
	rcs.chanLock.Lock()
	defer rcs.chanLock.Unlock()
	if rcs.IsActive() {
		rcs.Errors <- err
	}
}
<commit_msg>Fix skipping of errors/records in (*recordset).Results() select.<commit_after>// Copyright 2013-2015 Aerospike, Inc.
//
// 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 aerospike

import (
	"sync"

	. "github.com/aerospike/aerospike-client-go/types/atomic"
)

type Result struct {
	Record *Record
	Err    error
}

// Recordset encapsulates the result of Scan and Query commands.
type Recordset struct {
	// Records is a channel on which the resulting records will be sent back.
	// NOTE: Do not use Records directly. Range on channel returned by Results() instead.
	// This field is deprecated and will be unexported in the future
	Records chan *Record
	// Errors is a channel on which all errors will be sent back.
	// NOTE: Do not use Errors directly. Range on channel returned by Results() instead.
	// This field is deprecated and will be unexported in the future
	Errors chan error

	wgGoroutines sync.WaitGroup
	goroutines   *AtomicInt

	active    *AtomicBool
	cancelled chan struct{}

	chanLock sync.Mutex
}

// NewRecordset generates a new RecordSet instance.
func newRecordset(recSize, goroutines int) *Recordset {
	rs := &Recordset{
		Records:    make(chan *Record, recSize),
		Errors:     make(chan error, goroutines),
		active:     NewAtomicBool(true),
		goroutines: NewAtomicInt(goroutines),
		cancelled:  make(chan struct{}),
	}
	rs.wgGoroutines.Add(goroutines)

	return rs
}

// IsActive returns true if the operation hasn't been finished or cancelled.
func (rcs *Recordset) IsActive() bool {
	return rcs.active.Get()
}

// Results returns a new receive-only channel with the results of the Scan/Query.
// This is a more idiomatic approach to the iterator pattern in getting the
// results back from the recordset, and doesn't require the user to write the
// ugly select in their code.
// Result contains a Record and an error reference.
//
// Example:
//
//  recordset, err := client.ScanAll(nil, namespace, set)
//  handleError(err)
//  for res := range recordset.Results() {
//    if res.Err != nil {
//      // handle error here
//    } else {
//      // process record here
//      fmt.Println(res.Record.Bins)
//    }
//  }
func (rcs *Recordset) Results() <-chan *Result {
	res := make(chan *Result, len(rcs.Records))

	go func() {
		defer close(res)
		for {
			select {
			case r, ok := <-rcs.Records:
				if !ok {
					for e := range rcs.Errors {
						// empty Errors channel and/or wait until it's also closed
						res <- &Result{Record: nil, Err: e}
					}
					return
				}
				res <- &Result{Record: r, Err: nil}
			case e, ok := <-rcs.Errors:
				if !ok {
					for r := range rcs.Records {
						// empty Records channel and/or wait until it's also closed
						res <- &Result{Record: r, Err: nil}
					}
					return
				}
				res <- &Result{Record: nil, Err: e}
			}
		}
	}()

	return (<-chan *Result)(res)
}

// Close all streams from different nodes.
func (rcs *Recordset) Close() {
	// do it only once
	if rcs.active.CompareAndToggle(true) {
		// this will broadcast to all commands listening to the channel
		close(rcs.cancelled)

		// wait till all goroutines are done
		rcs.wgGoroutines.Wait()

		rcs.chanLock.Lock()
		defer rcs.chanLock.Unlock()
		close(rcs.Records)
		close(rcs.Errors)
	}
}

func (rcs *Recordset) signalEnd() {
	rcs.wgGoroutines.Done()
	if rcs.goroutines.DecrementAndGet() == 0 {
		rcs.Close()
	}
}

func (rcs *Recordset) sendError(err error) {
	rcs.chanLock.Lock()
	defer rcs.chanLock.Unlock()
	if rcs.IsActive() {
		rcs.Errors <- err
	}
}
<|endoftext|>


<commit_before>// Copyright 2016 Google Inc. All Rights Reserved.
//
// 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 fake

import (
	"context"
	"fmt"

	"github.com/google/trillian"
	"github.com/google/trillian/client"
)

// logClient implements trillian/client.VerifyingLogClient.
type logClient struct {
	leaves []*trillian.LogLeaf
}

// NewFakeVerifyingLogClient returns a client that mimicks a trillian log.
func NewFakeVerifyingLogClient() client.VerifyingLogClient {
	return &logClient{
		leaves: make([]*trillian.LogLeaf, 0),
	}
}

// AddLeaf adds a leaf to the log.
func (l *logClient) AddLeaf(ctx context.Context, data []byte) error {
	l.leaves = append(l.leaves, &trillian.LogLeaf{
		LeafValue: data,
	})
	return nil
}

// GetByIndex returns the requested leaf.
func (l *logClient) GetByIndex(ctx context.Context, index int64) (*trillian.LogLeaf, error) {
	if got, want := index, int64(len(l.leaves)); got > want {
		return nil, fmt.Errorf("Index out of range. Got %v, want <= %v", got, want)
	}
	if got, want := index, int64(0); got < want {
		return nil, fmt.Errorf("Index out of range. Got %v, want >= %v", got, want)
	}
	return l.leaves[index], nil
}

// ListByIndex returns the set of requested leaves.
func (l *logClient) ListByIndex(ctx context.Context, start int64, count int64) ([]*trillian.LogLeaf, error) {
	if got, want := start+count, int64(len(l.leaves)); got > want {
		return nil, fmt.Errorf("Index out of range. Got %v, want <= %v", got, want)
	}
	if got, want := start, int64(0); got < want {
		return nil, fmt.Errorf("Index out of range. Got %v, want >= %v", got, want)
	}
	return l.leaves[start : start+count], nil
}

// UpdateRoot fetches the latest signed tree root.
func (l *logClient) UpdateRoot(ctx context.Context) error {
	return nil
}

// Root returns the latest local copy of the signed log root.
func (l *logClient) Root() trillian.SignedLogRoot {
	return trillian.SignedLogRoot{
		TreeSize: int64(len(l.leaves)),
	}
}

// VerifyInclusion returns nil.
func (l *logClient) VerifyInclusion(ctx context.Context, data []byte) error {
	return nil
}

// VerifyInclusionAtIndex returns nil.
func (l *logClient) VerifyInclusionAtIndex(ctx context.Context, data []byte, index int64) error {
	return nil
}
<commit_msg>Remove fake verifying log client<commit_after><|endoftext|>


<commit_before>package main

import (
	"github.com/white-pony/go-fann"
	"fmt"
)

func main() {
	const numLayers = 3
	const numNeuronsHidden = 32
	const desiredError = 0.0001
	const maxEpochs = 300
	const epochsBetweenReports = 10

	fmt.Println("Creating network.")

	trainData := fann.ReadTrainFromFile("../../datasets/mushroom.train")
	ann := fann.CreateStandard(numLayers, []uint32{trainData.GetNumInput(), numNeuronsHidden, 1})

	fmt.Println("Training network.")
	ann.SetActivationFunctionHidden(fann.SIGMOID_SYMMETRIC_STEPWISE)
	ann.SetActivationFunctionOutput(fann.SIGMOID_SYMMETRIC)

	ann.TrainOnData(trainData, maxEpochs, epochsBetweenReports, desiredError)

	fmt.Println("Testing network")

	testData := fann.ReadTrainFromFile("../../datasets/mushroom.test")

	ann.ResetMSE()

	var i uint32
	for i = 0; i < testData.Length(); i++ {
		ann.Test(testData.GetInput(i), testData.GetOutput(i))
	}

	fmt.Printf("MSE error on test data: %f\n", ann.GetMSE())

	fmt.Println("Saving network.")

	ann.Save("mushroom_float.net")

	fmt.Println("Cleaning up.")

	trainData.Destroy()
	testData.Destroy()
	ann.Destroy()
}
<commit_msg>fix mushroom.go output layer size<commit_after>package main

import (
	"github.com/white-pony/go-fann"
	"fmt"
)

func main() {
	const numLayers = 3
	const numNeuronsHidden = 32
	const desiredError = 0.0001
	const maxEpochs = 300
	const epochsBetweenReports = 10

	fmt.Println("Creating network.")

	trainData := fann.ReadTrainFromFile("../../datasets/mushroom.train")
	ann := fann.CreateStandard(numLayers, []uint32{trainData.GetNumInput(), numNeuronsHidden, trainData.GetNumOutput()})

	fmt.Println("Training network.")
	ann.SetActivationFunctionHidden(fann.SIGMOID_SYMMETRIC_STEPWISE)
	ann.SetActivationFunctionOutput(fann.SIGMOID_SYMMETRIC)

	ann.TrainOnData(trainData, maxEpochs, epochsBetweenReports, desiredError)

	fmt.Println("Testing network")

	testData := fann.ReadTrainFromFile("../../datasets/mushroom.test")

	ann.ResetMSE()

	var i uint32
	for i = 0; i < testData.Length(); i++ {
		ann.Test(testData.GetInput(i), testData.GetOutput(i))
	}

	fmt.Printf("MSE error on test data: %f\n", ann.GetMSE())

	fmt.Println("Saving network.")

	ann.Save("mushroom_float.net")

	fmt.Println("Cleaning up.")

	trainData.Destroy()
	testData.Destroy()
	ann.Destroy()
}
<|endoftext|>