<commit_before>package main

import (
	"os"
	"path"
	"path/filepath"
	"strings"
	"time"

	"bazil.org/fuse"
	"bazil.org/fuse/fs"
	"golang.org/x/net/context"
)

type Dir struct {
	*Node
}

// Lookup returns file or dir if exists; fuse.EEXIST if not. Required by Fuse.
func (d *Dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
	d.RLock()
	defer d.RUnlock()

	// TODO: how to deal with resource files
	if strings.HasPrefix(name, "._") {
		return NewNode(d.Transport), nil
	}

	defer debug(time.Now(), "Lookup="+name)

	n := NewNode(d.Transport)
	n.Name = name
	n.InternalPath = filepath.Join(d.InternalPath, name)
	n.ExternalPath = filepath.Join(d.ExternalPath, name)

	req := struct{ Path string }{n.ExternalPath}
	res := fsGetInfoRes{}

	// TODO: lookup name in cache, ask Klient only if not in cache
	if err := n.Trip("fs.getInfo", req, &res); err != nil {
		return nil, err
	}

	n.Name = path.Base(n.ExternalPath)
	n.attr.Size = uint64(res.Size)
	n.attr.Mode = os.FileMode(res.Mode)

	if res.IsDir {
		return &Dir{n}, nil
	}

	return &File{n}, nil
}

// ReadDirAll returns metadata for files and directories. Required by Fuse.
func (d *Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
	defer debug(time.Now(), "ReadDirAll="+d.Name)

	d.RLock()
	defer d.RUnlock()

	req := struct{ Path string }{d.ExternalPath}
	res := fsReadDirectoryRes{}

	if err := d.Trip("fs.readDirectory", req, &res); err != nil {
		return nil, err
	}

	// TODO: cache these results
	var dirents []fuse.Dirent
	for _, file := range res.Files {
		ent := fuse.Dirent{Name: file.Name, Type: fuse.DT_File}
		if file.IsDir {
			ent.Type = fuse.DT_Dir
		}
		dirents = append(dirents, ent)
	}

	return dirents, nil
}
<commit_msg>return full Node when returning early for resources files<commit_after>package main

import (
	"os"
	"path"
	"path/filepath"
	"strings"
	"time"

	"bazil.org/fuse"
	"bazil.org/fuse/fs"
	"golang.org/x/net/context"
)

type Dir struct {
	*Node
}

// Lookup returns file or dir if exists; fuse.EEXIST if not. Required by Fuse.
func (d *Dir) Lookup(ctx context.Context, name string) (fs.Node, error) {
	d.RLock()
	defer d.RUnlock()

	n := NewNode(d.Transport)
	n.Name = name
	n.InternalPath = filepath.Join(d.InternalPath, name)
	n.ExternalPath = filepath.Join(d.ExternalPath, name)

	// TODO: how to deal with resource files
	if strings.HasPrefix(name, "._") {
		return n, nil
	}

	defer debug(time.Now(), "Lookup="+name)

	req := struct{ Path string }{n.ExternalPath}
	res := fsGetInfoRes{}

	// TODO: lookup name in cache, ask Klient only if not in cache
	if err := n.Trip("fs.getInfo", req, &res); err != nil {
		return nil, err
	}

	n.Name = path.Base(n.ExternalPath)
	n.attr.Size = uint64(res.Size)
	n.attr.Mode = os.FileMode(res.Mode)

	if res.IsDir {
		return &Dir{n}, nil
	}

	return &File{n}, nil
}

// ReadDirAll returns metadata for files and directories. Required by Fuse.
func (d *Dir) ReadDirAll(ctx context.Context) ([]fuse.Dirent, error) {
	defer debug(time.Now(), "ReadDirAll="+d.Name)

	d.RLock()
	defer d.RUnlock()

	req := struct{ Path string }{d.ExternalPath}
	res := fsReadDirectoryRes{}

	if err := d.Trip("fs.readDirectory", req, &res); err != nil {
		return nil, err
	}

	// TODO: cache these results
	var dirents []fuse.Dirent
	for _, file := range res.Files {
		ent := fuse.Dirent{Name: file.Name, Type: fuse.DT_File}
		if file.IsDir {
			ent.Type = fuse.DT_Dir
		}
		dirents = append(dirents, ent)
	}

	return dirents, nil
}
<|endoftext|>


<commit_before>package cloudflare

import (
	"encoding/json"
	"net/url"
	"strconv"
	"time"

	"github.com/pkg/errors"
)

// DNSRecord represents a DNS record in a zone.
type DNSRecord struct {
	ID         string      `json:"id,omitempty"`
	Type       string      `json:"type,omitempty"`
	Name       string      `json:"name,omitempty"`
	Content    string      `json:"content,omitempty"`
	Proxiable  bool        `json:"proxiable,omitempty"`
	Proxied    bool        `json:"proxied,omitempty"`
	TTL        int         `json:"ttl,omitempty"`
	Locked     bool        `json:"locked,omitempty"`
	ZoneID     string      `json:"zone_id,omitempty"`
	ZoneName   string      `json:"zone_name,omitempty"`
	CreatedOn  time.Time   `json:"created_on,omitempty"`
	ModifiedOn time.Time   `json:"modified_on,omitempty"`
	Data       interface{} `json:"data,omitempty"` // data returned by: SRV, LOC
	Meta       interface{} `json:"meta,omitempty"`
	Priority   int         `json:"priority,omitempty"`
}

// DNSRecordResponse represents the response from the DNS endpoint.
type DNSRecordResponse struct {
	Result DNSRecord `json:"result"`
	Response
	ResultInfo `json:"result_info"`
}

// DNSListResponse represents the response from the list DNS records endpoint.
type DNSListResponse struct {
	Result []DNSRecord `json:"result"`
	Response
	ResultInfo `json:"result_info"`
}

// CreateDNSRecord creates a DNS record for the zone identifier.
//
// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-create-dns-record
func (api *API) CreateDNSRecord(zoneID string, rr DNSRecord) (*DNSRecordResponse, error) {
	uri := "/zones/" + zoneID + "/dns_records"
	res, err := api.makeRequest("POST", uri, rr)
	if err != nil {
		return nil, errors.Wrap(err, errMakeRequestError)
	}

	var recordResp *DNSRecordResponse
	err = json.Unmarshal(res, &recordResp)
	if err != nil {
		return nil, errors.Wrap(err, errUnmarshalError)
	}

	return recordResp, nil
}

// DNSRecords returns a slice of DNS records for the given zone identifier.
//
// This takes a DNSRecord to allow filtering of the results returned.
//
// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-list-dns-records
func (api *API) DNSRecords(zoneID string, rr DNSRecord) ([]DNSRecord, error) {
	// Construct a query string
	v := url.Values{}
	// Request as many records as possible per page - API max is 50
	v.Set("per_page", "50")
	if rr.Name != "" {
		v.Set("name", rr.Name)
	}
	if rr.Type != "" {
		v.Set("type", rr.Type)
	}
	if rr.Content != "" {
		v.Set("content", rr.Content)
	}

	var query string
	var records []DNSRecord
	page := 1

	// Loop over makeRequest until what we've fetched all records
	for {
		v.Set("page", strconv.Itoa(page))
		query = "?" + v.Encode()
		uri := "/zones/" + zoneID + "/dns_records" + query
		res, err := api.makeRequest("GET", uri, nil)
		if err != nil {
			return []DNSRecord{}, errors.Wrap(err, errMakeRequestError)
		}
		var r DNSListResponse
		err = json.Unmarshal(res, &r)
		if err != nil {
			return []DNSRecord{}, errors.Wrap(err, errUnmarshalError)
		}
		records = append(records, r.Result...)
		if r.ResultInfo.Page >= r.ResultInfo.TotalPages {
			break
		}
		// Loop around and fetch the next page
		page++
	}
	return records, nil
}

// DNSRecord returns a single DNS record for the given zone & record
// identifiers.
//
// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-dns-record-details
func (api *API) DNSRecord(zoneID, recordID string) (DNSRecord, error) {
	uri := "/zones/" + zoneID + "/dns_records/" + recordID
	res, err := api.makeRequest("GET", uri, nil)
	if err != nil {
		return DNSRecord{}, errors.Wrap(err, errMakeRequestError)
	}
	var r DNSRecordResponse
	err = json.Unmarshal(res, &r)
	if err != nil {
		return DNSRecord{}, errors.Wrap(err, errUnmarshalError)
	}
	return r.Result, nil
}

// UpdateDNSRecord updates a single DNS record for the given zone & record
// identifiers.
//
// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-update-dns-record
func (api *API) UpdateDNSRecord(zoneID, recordID string, rr DNSRecord) error {
	rec, err := api.DNSRecord(zoneID, recordID)
	if err != nil {
		return err
	}
	// Populate the record name from the existing one if the update didn't
	// specify it.
	if rr.Name == "" {
		rr.Name = rec.Name
	}
	rr.Type = rec.Type
	uri := "/zones/" + zoneID + "/dns_records/" + recordID
	res, err := api.makeRequest("PUT", uri, rr)
	if err != nil {
		return errors.Wrap(err, errMakeRequestError)
	}
	var r DNSRecordResponse
	err = json.Unmarshal(res, &r)
	if err != nil {
		return errors.Wrap(err, errUnmarshalError)
	}
	return nil
}

// DeleteDNSRecord deletes a single DNS record for the given zone & record
// identifiers.
//
// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-delete-dns-record
func (api *API) DeleteDNSRecord(zoneID, recordID string) error {
	uri := "/zones/" + zoneID + "/dns_records/" + recordID
	res, err := api.makeRequest("DELETE", uri, nil)
	if err != nil {
		return errors.Wrap(err, errMakeRequestError)
	}
	var r DNSRecordResponse
	err = json.Unmarshal(res, &r)
	if err != nil {
		return errors.Wrap(err, errUnmarshalError)
	}
	return nil
}
<commit_msg>Change UpdateDNSRecord to use PATCH instead of PUT<commit_after>package cloudflare

import (
	"encoding/json"
	"net/url"
	"strconv"
	"time"

	"github.com/pkg/errors"
)

// DNSRecord represents a DNS record in a zone.
type DNSRecord struct {
	ID         string      `json:"id,omitempty"`
	Type       string      `json:"type,omitempty"`
	Name       string      `json:"name,omitempty"`
	Content    string      `json:"content,omitempty"`
	Proxiable  bool        `json:"proxiable,omitempty"`
	Proxied    bool        `json:"proxied,omitempty"`
	TTL        int         `json:"ttl,omitempty"`
	Locked     bool        `json:"locked,omitempty"`
	ZoneID     string      `json:"zone_id,omitempty"`
	ZoneName   string      `json:"zone_name,omitempty"`
	CreatedOn  time.Time   `json:"created_on,omitempty"`
	ModifiedOn time.Time   `json:"modified_on,omitempty"`
	Data       interface{} `json:"data,omitempty"` // data returned by: SRV, LOC
	Meta       interface{} `json:"meta,omitempty"`
	Priority   int         `json:"priority,omitempty"`
}

// DNSRecordResponse represents the response from the DNS endpoint.
type DNSRecordResponse struct {
	Result DNSRecord `json:"result"`
	Response
	ResultInfo `json:"result_info"`
}

// DNSListResponse represents the response from the list DNS records endpoint.
type DNSListResponse struct {
	Result []DNSRecord `json:"result"`
	Response
	ResultInfo `json:"result_info"`
}

// CreateDNSRecord creates a DNS record for the zone identifier.
//
// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-create-dns-record
func (api *API) CreateDNSRecord(zoneID string, rr DNSRecord) (*DNSRecordResponse, error) {
	uri := "/zones/" + zoneID + "/dns_records"
	res, err := api.makeRequest("POST", uri, rr)
	if err != nil {
		return nil, errors.Wrap(err, errMakeRequestError)
	}

	var recordResp *DNSRecordResponse
	err = json.Unmarshal(res, &recordResp)
	if err != nil {
		return nil, errors.Wrap(err, errUnmarshalError)
	}

	return recordResp, nil
}

// DNSRecords returns a slice of DNS records for the given zone identifier.
//
// This takes a DNSRecord to allow filtering of the results returned.
//
// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-list-dns-records
func (api *API) DNSRecords(zoneID string, rr DNSRecord) ([]DNSRecord, error) {
	// Construct a query string
	v := url.Values{}
	// Request as many records as possible per page - API max is 50
	v.Set("per_page", "50")
	if rr.Name != "" {
		v.Set("name", rr.Name)
	}
	if rr.Type != "" {
		v.Set("type", rr.Type)
	}
	if rr.Content != "" {
		v.Set("content", rr.Content)
	}

	var query string
	var records []DNSRecord
	page := 1

	// Loop over makeRequest until what we've fetched all records
	for {
		v.Set("page", strconv.Itoa(page))
		query = "?" + v.Encode()
		uri := "/zones/" + zoneID + "/dns_records" + query
		res, err := api.makeRequest("GET", uri, nil)
		if err != nil {
			return []DNSRecord{}, errors.Wrap(err, errMakeRequestError)
		}
		var r DNSListResponse
		err = json.Unmarshal(res, &r)
		if err != nil {
			return []DNSRecord{}, errors.Wrap(err, errUnmarshalError)
		}
		records = append(records, r.Result...)
		if r.ResultInfo.Page >= r.ResultInfo.TotalPages {
			break
		}
		// Loop around and fetch the next page
		page++
	}
	return records, nil
}

// DNSRecord returns a single DNS record for the given zone & record
// identifiers.
//
// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-dns-record-details
func (api *API) DNSRecord(zoneID, recordID string) (DNSRecord, error) {
	uri := "/zones/" + zoneID + "/dns_records/" + recordID
	res, err := api.makeRequest("GET", uri, nil)
	if err != nil {
		return DNSRecord{}, errors.Wrap(err, errMakeRequestError)
	}
	var r DNSRecordResponse
	err = json.Unmarshal(res, &r)
	if err != nil {
		return DNSRecord{}, errors.Wrap(err, errUnmarshalError)
	}
	return r.Result, nil
}

// UpdateDNSRecord updates a single DNS record for the given zone & record
// identifiers.
//
// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-update-dns-record
func (api *API) UpdateDNSRecord(zoneID, recordID string, rr DNSRecord) error {
	rec, err := api.DNSRecord(zoneID, recordID)
	if err != nil {
		return err
	}
	// Populate the record name from the existing one if the update didn't
	// specify it.
	if rr.Name == "" {
		rr.Name = rec.Name
	}
	rr.Type = rec.Type
	uri := "/zones/" + zoneID + "/dns_records/" + recordID
	res, err := api.makeRequest("PATCH", uri, rr)
	if err != nil {
		return errors.Wrap(err, errMakeRequestError)
	}
	var r DNSRecordResponse
	err = json.Unmarshal(res, &r)
	if err != nil {
		return errors.Wrap(err, errUnmarshalError)
	}
	return nil
}

// DeleteDNSRecord deletes a single DNS record for the given zone & record
// identifiers.
//
// API reference: https://api.cloudflare.com/#dns-records-for-a-zone-delete-dns-record
func (api *API) DeleteDNSRecord(zoneID, recordID string) error {
	uri := "/zones/" + zoneID + "/dns_records/" + recordID
	res, err := api.makeRequest("DELETE", uri, nil)
	if err != nil {
		return errors.Wrap(err, errMakeRequestError)
	}
	var r DNSRecordResponse
	err = json.Unmarshal(res, &r)
	if err != nil {
		return errors.Wrap(err, errUnmarshalError)
	}
	return nil
}
<|endoftext|>


<commit_before>// Package facebook implements Facebook Graph API.
//
// Request token url is:
// - https://www.facebook.com/dialog/oauth
//
// access token url is:
// - https://graph.facebook.com/oauth/access_token
//
// These urls are hidden inside Graph struct as they don't change.
//
//     // Example
//     var graph := facebook.New(
//             "AppID",
//             "Secret",
//             "https://example.com/facebook/callback",
//             []string{"email"},
//     )
//
//     // Signup redirects user to facebook
//     func Signup(w http.ResponseWriter, r *http.Request) {
//             http.Redirect(w, r, graph.AuthURL(""), http.StatusFound)
//     }
//
//     // Handle response
//     func HandleOAuth(w http.ResponseWriter, r *http.Request) {
//             var g *facebook.Graph
//             g = graph
//             g.GetAccessToken(r)
//     }
//
package facebook
<commit_msg>put urls inside code block in documentation<commit_after>// Package facebook implements Facebook Graph API.
//
//     - request token url: https://www.facebook.com/dialog/oauth
//     - access token urlhttps://graph.facebook.com/oauth/access_token
//
// These urls are hidden inside Graph struct as they don't change.
//
//     // Example
//     var graph := facebook.New(
//             "AppID",
//             "Secret",
//             "https://example.com/facebook/callback",
//             []string{"email"},
//     )
//
//     // Signup redirects user to facebook
//     func Signup(w http.ResponseWriter, r *http.Request) {
//             http.Redirect(w, r, graph.AuthURL(""), http.StatusFound)
//     }
//
//     // Handle response
//     func HandleOAuth(w http.ResponseWriter, r *http.Request) {
//             var g *facebook.Graph
//             g = graph
//             g.GetAccessToken(r)
//     }
//
package facebook
<|endoftext|>


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

// Package set implements type-safe, non-allocating algorithms that operate
// on ordered sets.
//
// Most functions take a data parameter of type sort.Interface and a pivot
// parameter of type int; data represents two sets covering the ranges
// [0:pivot] and [pivot:Len], each of which is expected to be sorted and
// free of duplicates. sort.Sort may be used for sorting, and set.Uniq may
// be used to filter away duplicates.
//
// All mutating functions swap elements as necessary from the two input sets
// to form a single output set, returning its size: the output set will be
// in the range [0:size], and will be in sorted order and free of
// duplicates. Elements which were moved into the range [size:Len] will have
// undefined order and may contain duplicates.
//
// All pivots must be in the range [0:Len]. A panic may occur when invalid
// panics are passed into any of the functions.
//
// Elements will be considered equal if `!Less(i,j) && !Less(j,i)`.
package set

// BUG(extemporalgenome): All ops should use binary search when runs are detected
<commit_msg>"panics" -> "pivots". Thanks Luna!<commit_after>// Copyright 2015 Kevin Gillette. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package set implements type-safe, non-allocating algorithms that operate
// on ordered sets.
//
// Most functions take a data parameter of type sort.Interface and a pivot
// parameter of type int; data represents two sets covering the ranges
// [0:pivot] and [pivot:Len], each of which is expected to be sorted and
// free of duplicates. sort.Sort may be used for sorting, and set.Uniq may
// be used to filter away duplicates.
//
// All mutating functions swap elements as necessary from the two input sets
// to form a single output set, returning its size: the output set will be
// in the range [0:size], and will be in sorted order and free of
// duplicates. Elements which were moved into the range [size:Len] will have
// undefined order and may contain duplicates.
//
// All pivots must be in the range [0:Len]. A panic may occur when invalid
// pivots are passed into any of the functions.
//
// Elements will be considered equal if `!Less(i,j) && !Less(j,i)`.
package set

// BUG(extemporalgenome): All ops should use binary search when runs are detected
<|endoftext|>


<commit_before>// Copyright 2013 by Dobrosław Żybort. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

/*
Package slug generate slug from unicode string. URL-friendly slugify with
multiple languages support.

Example:

	package main

	import(
		"bitbucket.org/gosimple/slug"
	    "fmt"
	)

	text := slug.Make("Hellö Wörld хелло ворлд")
	fmt.Println(text) // Will print hello-world-khello-vorld

	someText := slug.Make("影師")
	fmt.Println(someText) // Will print: ying-shi

	enText := slug.MakeLang("This & that", "en")
	fmt.Println(enText) // Will print 'this-and-that'

	deText := slug.MakeLang("Diese & Dass", "de")
	fmt.Println(deText) // Will print 'diese-und-dass'

Requests or bugs?

https://bitbucket.org/gosimple/slug/issues
*/
package slug
<commit_msg>Fix doc<commit_after>// Copyright 2013 by Dobrosław Żybort. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

/*
Package slug generate slug from unicode string. URL-friendly slugify with
multiple languages support.

Example:

	package main

	import(
		"bitbucket.org/gosimple/slug"
		"fmt"
	)

	text := slug.Make("Hellö Wörld хелло ворлд")
	fmt.Println(text) // Will print hello-world-khello-vorld

	someText := slug.Make("影師")
	fmt.Println(someText) // Will print: ying-shi

	enText := slug.MakeLang("This & that", "en")
	fmt.Println(enText) // Will print 'this-and-that'

	deText := slug.MakeLang("Diese & Dass", "de")
	fmt.Println(deText) // Will print 'diese-und-dass'

Requests or bugs?

https://bitbucket.org/gosimple/slug/issues
*/
package slug
<|endoftext|>


<commit_before>// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

// Package yarpc provides the YARPC service framework.
//
// With hundreds to thousands of services communicating with RPC, transport
// protocols (like HTTP and TChannel), encoding protocols (like JSON or
// Thrift), and peer choosers are the concepts that vary year over year.
// Separating these concerns allows services to change transports and wire
// protocols without changing call sites or request handlers, build proxies and
// wire protocol bridges, or experiment with load balancing strategies.
// YARPC is a toolkit for services and proxies.
//
// YARPC breaks RPC into interchangeable encodings, transports, and peer
// choosers.
// YARPC for Go provides reference implementations for HTTP/1.1 and TChannel
// transports, and also raw, JSON, and Thrift encodings.
// YARPC for Go provides experimental implementations for a Redis transport and a
// round robin peer chooser.
// YARPC for Go plans to provide a Protobuf 3 encoding, a gRPC transport, and a
// load balancer that uses a least-pending-requests strategy.
// Peer choosers can implement any strategy, including load balancing or sharding,
// in turn bound to any peer list updater.
//
// Regardless of transport, every RPC has some common properties: caller name,
// service name, procedure name, encoding name, deadline or TTL, headers,
// baggage (multi-hop headers), and tracing.
// Each RPC can also have an optional shard key, routing key, or routing
// delegate for advanced routing.
// YARPC transports use a shared API for capturing RPC metadata, so middleware
// can apply to requests over any transport.
//
// Each YARPC transport protocol can implement inbound handlers and outbound
// callers. Each of these can support different RPC types, like unary (request and
// response) or oneway (request and receipt) RPC. A future release of YARPC will
// add support for other RPC types including variations on streaming and pubsub.
package yarpc
<commit_msg>Update go doc (#1340)<commit_after>// Copyright (c) 2017 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

// Package yarpc provides the YARPC service framework.
//
// With hundreds to thousands of services communicating with RPC, transport
// protocols (like HTTP and TChannel), encoding protocols (like JSON or
// Thrift), and peer choosers are the concepts that vary year over year.
// Separating these concerns allows services to change transports and wire
// protocols without changing call sites or request handlers, build proxies and
// wire protocol bridges, or experiment with load balancing strategies.
// YARPC is a toolkit for services and proxies.
//
// YARPC breaks RPC into interchangeable encodings, transports, and peer
// choosers.
// YARPC for Go provides reference implementations for HTTP/1.1, TChannel and gRPC
// transports, and also raw, JSON, Thrift, and Protobuf encodings.
// YARPC for Go provides a round robin peer chooser and experimental
// implementations for debug pages and rate limiting.
// YARPC for Go plans to provide a load balancer that uses a
// least-pending-requests strategy.
// Peer choosers can implement any strategy, including load balancing or sharding,
// in turn bound to any peer list updater.
//
// Regardless of transport, every RPC has some common properties: caller name,
// service name, procedure name, encoding name, deadline or TTL, headers,
// baggage (multi-hop headers), and tracing.
// Each RPC can also have an optional shard key, routing key, or routing
// delegate for advanced routing.
// YARPC transports use a shared API for capturing RPC metadata, so middleware
// can apply to requests over any transport.
//
// Each YARPC transport protocol can implement inbound handlers and outbound
// callers. Each of these can support different RPC types, like unary (request and
// response) or oneway (request and receipt) RPC. A future release of YARPC will
// add support for other RPC types including variations on streaming and pubsub.
package yarpc
<|endoftext|>


<commit_before>//Gphoto let you control your digital camera or webcam from your PC.
//
//Package gphoto is a go wrapper for libgphoto2 library (http://www.gphoto.org/proj/libgphoto2/)
//It is supporting most of modern cameras supporting PTP protocol and connecting to PC with an USB cable
//
//Gphoto lets you inspect and modify camera settings ( shutter speed, aperture, iso, image quality etc.),
//capture photos and download them to the PC.
//
//You can also capture image previews and by doing it in a loop you can have live view on your computer screen
//
//For more information about installing required dependencies and troubleshooting please read readme file avaiable in  the
//github repo under this link: https://github.com/szank/libgphoto2-go/blob/master/README.md
package gphoto
<commit_msg>update documentation<commit_after>//Package Gphoto let you control your digital camera or webcam from your PC.
//
//Package gphoto is a go wrapper for libgphoto2 library (http://www.gphoto.org/proj/libgphoto2/)
//It is supporting most of modern cameras supporting PTP protocol and connecting to PC with an USB cable
//
//Gphoto lets you inspect and modify camera settings ( shutter speed, aperture, iso, image quality etc.),
//capture photos and download them to the PC.
//
//You can also capture image previews and by doing it in a loop you can have live view on your computer screen
//
//For more information about installing required dependencies and troubleshooting please read readme file avaiable in  the
//github repo under this link: https://github.com/szank/libgphoto2-go/blob/master/README.md
package gphoto
<|endoftext|>


<commit_before>// Package kingpin provides command line interfaces like this:
//
//     $ chat
//     usage: chat [<flags>] <command> [<flags>] [<args> ...]
//
//     Flags:
//       --debug              enable debug mode
//       --help               Show help.
//       --server=127.0.0.1   server address
//
//     Commands:
//       help <command>
//         Show help for a command.
//
//       post [<flags>] <channel>
//         Post a message to a channel.
//
//       register <nick> <name>
//         Register a new user.
//
//     $ chat help post
//     usage: chat [<flags>] post [<flags>] <channel> [<text>]
//
//     Post a message to a channel.
//
//     Flags:
//       --image=IMAGE   image to post
//
//     Args:
//       <channel>   channel to post to
//       [<text>]    text to post
//     $ chat post --image=~/Downloads/owls.jpg pics
//
// From code like this:
//
//     package main
//
//     import "gopkg.in/alecthomas/kingpin.v1"
//
//     var (
//       debug    = kingpin.Flag("debug", "enable debug mode").Default("false").Bool()
//       serverIP = kingpin.Flag("server", "server address").Default("127.0.0.1").IP()
//
//       register     = kingpin.Command("register", "Register a new user.")
//       registerNick = register.Arg("nick", "nickname for user").Required().String()
//       registerName = register.Arg("name", "name of user").Required().String()
//
//       post        = kingpin.Command("post", "Post a message to a channel.")
//       postImage   = post.Flag("image", "image to post").ExistingFile()
//       postChannel = post.Arg("channel", "channel to post to").Required().String()
//       postText    = post.Arg("text", "text to post").String()
//     )
//
//     func main() {
//       switch kingpin.Parse() {
//       // Register user
//       case "register":
//         println(*registerNick)
//
//       // Post message
//       case "post":
//         if *postImage != nil {
//         }
//         if *postText != "" {
//         }
//       }
//     }
package kingpin
<commit_msg>Update doc.go<commit_after>// Package kingpin provides command line interfaces like this:
//
//     $ chat
//     usage: chat [<flags>] <command> [<flags>] [<args> ...]
//
//     Flags:
//       --debug              enable debug mode
//       --help               Show help.
//       --server=127.0.0.1   server address
//
//     Commands:
//       help <command>
//         Show help for a command.
//
//       post [<flags>] <channel>
//         Post a message to a channel.
//
//       register <nick> <name>
//         Register a new user.
//
//     $ chat help post
//     usage: chat [<flags>] post [<flags>] <channel> [<text>]
//
//     Post a message to a channel.
//
//     Flags:
//       --image=IMAGE   image to post
//
//     Args:
//       <channel>   channel to post to
//       [<text>]    text to post
//     $ chat post --image=~/Downloads/owls.jpg pics
//
// From code like this:
//
//     package main
//
//     import "gopkg.in/alecthomas/kingpin.v2"
//
//     var (
//       debug    = kingpin.Flag("debug", "enable debug mode").Default("false").Bool()
//       serverIP = kingpin.Flag("server", "server address").Default("127.0.0.1").IP()
//
//       register     = kingpin.Command("register", "Register a new user.")
//       registerNick = register.Arg("nick", "nickname for user").Required().String()
//       registerName = register.Arg("name", "name of user").Required().String()
//
//       post        = kingpin.Command("post", "Post a message to a channel.")
//       postImage   = post.Flag("image", "image to post").ExistingFile()
//       postChannel = post.Arg("channel", "channel to post to").Required().String()
//       postText    = post.Arg("text", "text to post").String()
//     )
//
//     func main() {
//       switch kingpin.Parse() {
//       // Register user
//       case "register":
//         println(*registerNick)
//
//       // Post message
//       case "post":
//         if *postImage != nil {
//         }
//         if *postText != "" {
//         }
//       }
//     }
package kingpin
<|endoftext|>


<commit_before>/*
Package godirwalk provides functions to read and traverse directory trees.

In short, why do I use this library?

* It's faster than `filepath.Walk`.

* It's more correct on Windows than `filepath.Walk`.

* It's more easy to use than `filepath.Walk`.

* It's more flexible than `filepath.Walk`.

USAGE

This library will normalize the provided top level directory name based on the
os-specific path separator by calling `filepath.Clean` on its first
argument. However it always provides the pathname created by using the correct
os-specific path separator when invoking the provided callback function.

    dirname := "some/directory/root"
    err := godirwalk.Walk(dirname, &godirwalk.Options{
        Callback: func(osPathname string, de *godirwalk.Dirent) error {
            fmt.Printf("%s %s\n", de.ModeType(), osPathname)
            return nil
        },
    })

This library not only provides functions for traversing a file system directory
tree, but also for obtaining a list of immediate descendants of a particular
directory, typically much more quickly than using `os.ReadDir` or
`os.ReadDirnames`.

    dirname := "some/directory"
    names, err := godirwalk.ReadDirnames()
*/
package godirwalk
<commit_msg>updated project level documentation<commit_after>/*
Package godirwalk provides functions to read and traverse directory trees.

In short, why do I use this library?

* It's faster than `filepath.Walk`.

* It's more correct on Windows than `filepath.Walk`.

* It's more easy to use than `filepath.Walk`.

* It's more flexible than `filepath.Walk`.

USAGE

This library will normalize the provided top level directory name based on the
os-specific path separator by calling `filepath.Clean` on its first
argument. However it always provides the pathname created by using the correct
os-specific path separator when invoking the provided callback function.

    dirname := "some/directory/root"
    err := godirwalk.Walk(dirname, &godirwalk.Options{
        Callback: func(osPathname string, de *godirwalk.Dirent) error {
            fmt.Printf("%s %s\n", de.ModeType(), osPathname)
            return nil
        },
    })

This library not only provides functions for traversing a file system directory
tree, but also for obtaining a list of immediate descendants of a particular
directory, typically much more quickly than using `os.ReadDir` or
`os.ReadDirnames`.

    scratchBuffer := make([]byte, godirwalk.MinimumScratchBufferSize)

    names, err := godirwalk.ReadDirnames("some/directory", scratchBuffer)
    // ...

    entries, err := godirwalk.ReadDirents("another/directory", scratchBuffer)
    // ...
*/
package godirwalk
<|endoftext|>


<commit_before>// Copyright 2015 Tim Heckman. All rights reserved.
// Use of this source code is governed by the BSD 3-Clause
// license that can be found in the LICENSE file.

// Package packets is a package for the creation/manipulation of raw TCP packets for sending over the network.
// It was designed to have a idiomatic (or so I think) interface.
package packets
<commit_msg>improve package docs<commit_after>// Copyright 2015 Tim Heckman. All rights reserved.
// Use of this source code is governed by the BSD 3-Clause
// license that can be found in the LICENSE file.

// Package packets is for the creation/manipulation of raw TCP packets for sending over the network.
// It was designed to have a idiomatic (or so I think) interface.
package packets
<|endoftext|>


<commit_before>package kcp

import (
	"encoding/binary"
	"log"
	"sync"

	"github.com/klauspost/reedsolomon"
)

const (
	fecHeaderSize      = 6
	fecHeaderSizePlus2 = fecHeaderSize + 2 // plus 2B data size
	typeData           = 0xf1
	typeFEC            = 0xf2
	fecExpire          = 30000 // 30s
)

type (
	// FEC defines forward error correction for packets
	FEC struct {
		rx           []fecPacket // ordered receive queue
		rxlimit      int         // queue size limit
		dataShards   int
		parityShards int
		shardSize    int
		next         uint32 // next seqid
		enc          reedsolomon.Encoder
		shards       [][]byte
		shardsflag   []bool
		paws         uint32 // Protect Against Wrapped Sequence numbers
		lastCheck    uint32
		xmitBuf      sync.Pool
	}

	fecPacket struct {
		seqid uint32
		flag  uint16
		data  []byte
		ts    uint32
	}
)

func newFEC(rxlimit, dataShards, parityShards int) *FEC {
	if dataShards <= 0 || parityShards <= 0 {
		return nil
	}
	if rxlimit < dataShards+parityShards {
		return nil
	}

	fec := new(FEC)
	fec.rxlimit = rxlimit
	fec.dataShards = dataShards
	fec.parityShards = parityShards
	fec.shardSize = dataShards + parityShards
	fec.paws = (0xffffffff/uint32(fec.shardSize) - 1) * uint32(fec.shardSize)
	enc, err := reedsolomon.New(dataShards, parityShards)
	if err != nil {
		log.Println(err)
		return nil
	}
	fec.enc = enc
	fec.shards = make([][]byte, fec.shardSize)
	fec.shardsflag = make([]bool, fec.shardSize)
	fec.xmitBuf.New = func() interface{} {
		return make([]byte, mtuLimit)
	}

	return fec
}

// decode a fec packet
func (fec *FEC) decode(data []byte) fecPacket {
	var pkt fecPacket
	pkt.seqid = binary.LittleEndian.Uint32(data)
	pkt.flag = binary.LittleEndian.Uint16(data[4:])
	pkt.ts = currentMs()
	// allocate memory & copy
	buf := fec.xmitBuf.Get().([]byte)
	xorBytes(buf, buf, buf)
	copy(buf, data[6:])
	pkt.data = buf
	return pkt
}

func (fec *FEC) markData(data []byte) {
	binary.LittleEndian.PutUint32(data, fec.next)
	binary.LittleEndian.PutUint16(data[4:], typeData)
	fec.next++
}

func (fec *FEC) markFEC(data []byte) {
	binary.LittleEndian.PutUint32(data, fec.next)
	binary.LittleEndian.PutUint16(data[4:], typeFEC)
	fec.next++
	if fec.next >= fec.paws { // paws would only occurs in markFEC
		fec.next = 0
	}
}

// input a fec packet
func (fec *FEC) input(pkt fecPacket) (recovered [][]byte) {
	// expiration
	now := currentMs()
	if now-fec.lastCheck >= fecExpire {
		var rx []fecPacket
		for k := range fec.rx {
			if now-fec.rx[k].ts < fecExpire {
				rx = append(rx, fec.rx[k])
			} else {
				fec.xmitBuf.Put(fec.rx[k].data)
			}
		}
		fec.rx = rx
		fec.lastCheck = now
	}

	// insertion
	n := len(fec.rx) - 1
	insertIdx := 0
	for i := n; i >= 0; i-- {
		if pkt.seqid == fec.rx[i].seqid { // de-duplicate
			fec.xmitBuf.Put(pkt.data)
			return nil
		} else if pkt.seqid > fec.rx[i].seqid { // insertion
			insertIdx = i + 1
			break
		}
	}

	// insert into ordered rx queue
	if insertIdx == n+1 {
		fec.rx = append(fec.rx, pkt)
	} else {
		fec.rx = append(fec.rx, fecPacket{})
		copy(fec.rx[insertIdx+1:], fec.rx[insertIdx:])
		fec.rx[insertIdx] = pkt
	}

	shardBegin := pkt.seqid - pkt.seqid%uint32(fec.shardSize)
	shardEnd := shardBegin + uint32(fec.shardSize) - 1

	searchBegin := insertIdx - fec.shardSize
	if searchBegin < 0 {
		searchBegin = 0
	}

	searchEnd := insertIdx + fec.shardSize
	if searchEnd >= len(fec.rx) {
		searchEnd = len(fec.rx) - 1
	}

	if len(fec.rx) >= fec.dataShards && shardBegin < shardEnd {
		numshard := 0
		numDataShard := 0
		first := -1
		maxlen := 0
		shards := fec.shards
		shardsflag := fec.shardsflag
		for k := range fec.shards {
			shards[k] = nil
			shardsflag[k] = false
		}

		for i := searchBegin; i <= searchEnd; i++ {
			seqid := fec.rx[i].seqid
			if seqid > shardEnd {
				break
			} else if seqid >= shardBegin {
				shards[seqid%uint32(fec.shardSize)] = fec.rx[i].data
				shardsflag[seqid%uint32(fec.shardSize)] = true
				numshard++
				if fec.rx[i].flag == typeData {
					numDataShard++
				}
				if numshard == 1 {
					first = i
				}
				if len(fec.rx[i].data) > maxlen {
					maxlen = len(fec.rx[i].data)
				}
			}
		}

		if numDataShard == fec.dataShards { // no lost
			for i := first; i < first+numshard; i++ { // free
				fec.xmitBuf.Put(fec.rx[i].data)
			}
			copy(fec.rx[first:], fec.rx[first+numshard:])
			fec.rx = fec.rx[:len(fec.rx)-numshard]
		} else if numshard >= fec.dataShards { // recoverable
			for k := range shards {
				if shards[k] != nil {
					shards[k] = shards[k][:maxlen]
				}
			}
			if err := fec.enc.Reconstruct(shards); err == nil {
				for k := range shards[:fec.dataShards] {
					if !shardsflag[k] {
						recovered = append(recovered, shards[k])
					}
				}
			} else {
				log.Println(err)
			}

			for i := first; i < first+numshard; i++ { // free
				fec.xmitBuf.Put(fec.rx[i].data)
			}
			copy(fec.rx[first:], fec.rx[first+numshard:])
			fec.rx = fec.rx[:len(fec.rx)-numshard]
		}
	}

	// keep rxlimit
	if len(fec.rx) > fec.rxlimit {
		fec.xmitBuf.Put(fec.rx[0].data) // free
		fec.rx = fec.rx[1:]
	}
	return
}

func (fec *FEC) calcECC(data [][]byte, offset, maxlen int) (ecc [][]byte) {
	if len(data) != fec.shardSize {
		log.Println("mismatch", len(data), fec.shardSize)
		return nil
	}
	shards := make([][]byte, fec.shardSize)
	for k := range shards {
		shards[k] = data[k][offset:maxlen]
	}

	if err := fec.enc.Encode(shards); err != nil {
		log.Println(err)
		return nil
	}
	return data[fec.dataShards:]
}
<commit_msg>precise FEC search boundary<commit_after>package kcp

import (
	"encoding/binary"
	"log"
	"sync"

	"github.com/klauspost/reedsolomon"
)

const (
	fecHeaderSize      = 6
	fecHeaderSizePlus2 = fecHeaderSize + 2 // plus 2B data size
	typeData           = 0xf1
	typeFEC            = 0xf2
	fecExpire          = 30000 // 30s
)

type (
	// FEC defines forward error correction for packets
	FEC struct {
		rx           []fecPacket // ordered receive queue
		rxlimit      int         // queue size limit
		dataShards   int
		parityShards int
		shardSize    int
		next         uint32 // next seqid
		enc          reedsolomon.Encoder
		shards       [][]byte
		shardsflag   []bool
		paws         uint32 // Protect Against Wrapped Sequence numbers
		lastCheck    uint32
		xmitBuf      sync.Pool
	}

	fecPacket struct {
		seqid uint32
		flag  uint16
		data  []byte
		ts    uint32
	}
)

func newFEC(rxlimit, dataShards, parityShards int) *FEC {
	if dataShards <= 0 || parityShards <= 0 {
		return nil
	}
	if rxlimit < dataShards+parityShards {
		return nil
	}

	fec := new(FEC)
	fec.rxlimit = rxlimit
	fec.dataShards = dataShards
	fec.parityShards = parityShards
	fec.shardSize = dataShards + parityShards
	fec.paws = (0xffffffff/uint32(fec.shardSize) - 1) * uint32(fec.shardSize)
	enc, err := reedsolomon.New(dataShards, parityShards)
	if err != nil {
		log.Println(err)
		return nil
	}
	fec.enc = enc
	fec.shards = make([][]byte, fec.shardSize)
	fec.shardsflag = make([]bool, fec.shardSize)
	fec.xmitBuf.New = func() interface{} {
		return make([]byte, mtuLimit)
	}

	return fec
}

// decode a fec packet
func (fec *FEC) decode(data []byte) fecPacket {
	var pkt fecPacket
	pkt.seqid = binary.LittleEndian.Uint32(data)
	pkt.flag = binary.LittleEndian.Uint16(data[4:])
	pkt.ts = currentMs()
	// allocate memory & copy
	buf := fec.xmitBuf.Get().([]byte)
	xorBytes(buf, buf, buf)
	copy(buf, data[6:])
	pkt.data = buf
	return pkt
}

func (fec *FEC) markData(data []byte) {
	binary.LittleEndian.PutUint32(data, fec.next)
	binary.LittleEndian.PutUint16(data[4:], typeData)
	fec.next++
}

func (fec *FEC) markFEC(data []byte) {
	binary.LittleEndian.PutUint32(data, fec.next)
	binary.LittleEndian.PutUint16(data[4:], typeFEC)
	fec.next++
	if fec.next >= fec.paws { // paws would only occurs in markFEC
		fec.next = 0
	}
}

// input a fec packet
func (fec *FEC) input(pkt fecPacket) (recovered [][]byte) {
	// expiration
	now := currentMs()
	if now-fec.lastCheck >= fecExpire {
		var rx []fecPacket
		for k := range fec.rx {
			if now-fec.rx[k].ts < fecExpire {
				rx = append(rx, fec.rx[k])
			} else {
				fec.xmitBuf.Put(fec.rx[k].data)
			}
		}
		fec.rx = rx
		fec.lastCheck = now
	}

	// insertion
	n := len(fec.rx) - 1
	insertIdx := 0
	for i := n; i >= 0; i-- {
		if pkt.seqid == fec.rx[i].seqid { // de-duplicate
			fec.xmitBuf.Put(pkt.data)
			return nil
		} else if pkt.seqid > fec.rx[i].seqid { // insertion
			insertIdx = i + 1
			break
		}
	}

	// insert into ordered rx queue
	if insertIdx == n+1 {
		fec.rx = append(fec.rx, pkt)
	} else {
		fec.rx = append(fec.rx, fecPacket{})
		copy(fec.rx[insertIdx+1:], fec.rx[insertIdx:])
		fec.rx[insertIdx] = pkt
	}

	shardBegin := pkt.seqid - pkt.seqid%uint32(fec.shardSize)
	shardEnd := shardBegin + uint32(fec.shardSize) - 1

	searchBegin := insertIdx - (fec.shardSize - 1)
	if searchBegin < 0 {
		searchBegin = 0
	}

	searchEnd := insertIdx + (fec.shardSize - 1)
	if searchEnd >= len(fec.rx) {
		searchEnd = len(fec.rx) - 1
	}

	if len(fec.rx) >= fec.dataShards && shardBegin < shardEnd {
		numshard := 0
		numDataShard := 0
		first := -1
		maxlen := 0
		shards := fec.shards
		shardsflag := fec.shardsflag
		for k := range fec.shards {
			shards[k] = nil
			shardsflag[k] = false
		}

		for i := searchBegin; i <= searchEnd; i++ {
			seqid := fec.rx[i].seqid
			if seqid > shardEnd {
				break
			} else if seqid >= shardBegin {
				shards[seqid%uint32(fec.shardSize)] = fec.rx[i].data
				shardsflag[seqid%uint32(fec.shardSize)] = true
				numshard++
				if fec.rx[i].flag == typeData {
					numDataShard++
				}
				if numshard == 1 {
					first = i
				}
				if len(fec.rx[i].data) > maxlen {
					maxlen = len(fec.rx[i].data)
				}
			}
		}

		if numDataShard == fec.dataShards { // no lost
			for i := first; i < first+numshard; i++ { // free
				fec.xmitBuf.Put(fec.rx[i].data)
			}
			copy(fec.rx[first:], fec.rx[first+numshard:])
			fec.rx = fec.rx[:len(fec.rx)-numshard]
		} else if numshard >= fec.dataShards { // recoverable
			for k := range shards {
				if shards[k] != nil {
					shards[k] = shards[k][:maxlen]
				}
			}
			if err := fec.enc.Reconstruct(shards); err == nil {
				for k := range shards[:fec.dataShards] {
					if !shardsflag[k] {
						recovered = append(recovered, shards[k])
					}
				}
			} else {
				log.Println(err)
			}

			for i := first; i < first+numshard; i++ { // free
				fec.xmitBuf.Put(fec.rx[i].data)
			}
			copy(fec.rx[first:], fec.rx[first+numshard:])
			fec.rx = fec.rx[:len(fec.rx)-numshard]
		}
	}

	// keep rxlimit
	if len(fec.rx) > fec.rxlimit {
		fec.xmitBuf.Put(fec.rx[0].data) // free
		fec.rx = fec.rx[1:]
	}
	return
}

func (fec *FEC) calcECC(data [][]byte, offset, maxlen int) (ecc [][]byte) {
	if len(data) != fec.shardSize {
		log.Println("mismatch", len(data), fec.shardSize)
		return nil
	}
	shards := make([][]byte, fec.shardSize)
	for k := range shards {
		shards[k] = data[k][offset:maxlen]
	}

	if err := fec.enc.Encode(shards); err != nil {
		log.Println(err)
		return nil
	}
	return data[fec.dataShards:]
}
<|endoftext|>


<commit_before>package main

import "fmt"

func main() {
	soma := 0
	for i := 0; i < 16; i++ { // HL
		soma += i
	} // HL
	fmt.Println(soma)
}
<commit_msg>minor<commit_after>package main

import "fmt"
//
func main() {
	soma := 0
	for i := 0; i < 16; i++ { // HL
		soma += i
	} // HL
	fmt.Println(soma)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"syscall"
	"unsafe"
)

const (
	ansiEraseDisplay = "\033[2J"
	ansiResetCursor  = "\033[H"
	carriageReturn   = "\015"
)

var originalSttyState bytes.Buffer
var winRows uint16
var winCols uint16

func getSttyState(state *bytes.Buffer) (err error) {
	cmd := exec.Command("stty", "-g")
	cmd.Stdin = os.Stdin
	cmd.Stdout = state
	return cmd.Run()
}

func setSttyState(state *bytes.Buffer) (err error) {
	cmd := exec.Command("stty", state.String())
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func drawInitialScreen() (err error) {
	_, err = io.WriteString(os.Stdout, ansiEraseDisplay)
	if err != nil {
		return err
	}
	_, err = io.WriteString(os.Stdout, ansiResetCursor)

	return err
}

func setCursorPos(line int, col int) (err error) {
	str := fmt.Sprintf("\033[%d;%dH", line+1, col+1)
	_, err = io.WriteString(os.Stdout, str)
	return err
}

type winsize struct {
	rows, cols, xpixel, ypixel uint16
}

func getWinsize() winsize {
	ws := winsize{}
	syscall.Syscall(syscall.SYS_IOCTL,
		uintptr(0), uintptr(syscall.TIOCGWINSZ),
		uintptr(unsafe.Pointer(&ws)))
	return ws
}

func init() {
	ws := getWinsize()
	winRows = ws.rows
	winCols = ws.cols
}

func main() {
	err := getSttyState(&originalSttyState)
	if err != nil {
		log.Fatal(err)
	}
	defer setSttyState(&originalSttyState)

	setSttyState(bytes.NewBufferString("cbreak"))
	setSttyState(bytes.NewBufferString("-echo"))

	var input []byte = make([]byte, 0)
	var b []byte = make([]byte, 1)

	// TODO: Do not print results and input to STDOUT, only to TTY, only print
	// selected result to STDOUT

	// TODO: Run command in the background, draw as long as no new input given
	// if input is given, cancel command in background

	// TODO: Only print as many result lines as we have lines on the screen

	for {
		// Clear screen and set cursor to first row, first col
		err = drawInitialScreen()
		if err != nil {
			log.Fatal(err)
		}

		// Print prompt with already typed input
		prompt := fmt.Sprintf(">> %s", input[:len(input)])
		fmt.Printf("%s", prompt)

		// Print results
		iname := fmt.Sprintf("*%s*", input[:len(input)])
		out, err := exec.Command("find", ".", "-iname", iname).Output()
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("\n%s", out)

		// Jump back to last typing position
		setCursorPos(0, len(prompt))

		os.Stdin.Read(b)
		switch b[0] {
		case 127:
			// Backspace
			if len(input) > 0 {
				input = input[:len(input)-1]
			}
		case 4, 13:
			// Return or Ctrl-D
			fmt.Println("Result:")
			fmt.Printf("%s%s\n", carriageReturn, string(input[:len(input)]))
			return
		default:
			// TODO: Default is wrong here. Only append printable characters to
			// input

			// Everything else
			input = append(input, b...)
		}
	}
}
<commit_msg>More TODOs in code<commit_after>package main

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"syscall"
	"unsafe"
)

const (
	ansiEraseDisplay = "\033[2J"
	ansiResetCursor  = "\033[H"
	carriageReturn   = "\015"
)

var originalSttyState bytes.Buffer
var winRows uint16
var winCols uint16

func getSttyState(state *bytes.Buffer) (err error) {
	cmd := exec.Command("stty", "-g")
	cmd.Stdin = os.Stdin
	cmd.Stdout = state
	return cmd.Run()
}

func setSttyState(state *bytes.Buffer) (err error) {
	cmd := exec.Command("stty", state.String())
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	return cmd.Run()
}

func drawInitialScreen() (err error) {
	_, err = io.WriteString(os.Stdout, ansiEraseDisplay)
	if err != nil {
		return err
	}
	_, err = io.WriteString(os.Stdout, ansiResetCursor)

	return err
}

func setCursorPos(line int, col int) (err error) {
	str := fmt.Sprintf("\033[%d;%dH", line+1, col+1)
	_, err = io.WriteString(os.Stdout, str)
	return err
}

type winsize struct {
	rows, cols, xpixel, ypixel uint16
}

func getWinsize() winsize {
	ws := winsize{}
	syscall.Syscall(syscall.SYS_IOCTL,
		uintptr(0), uintptr(syscall.TIOCGWINSZ),
		uintptr(unsafe.Pointer(&ws)))
	return ws
}

func init() {
	ws := getWinsize()
	winRows = ws.rows
	winCols = ws.cols
}

func main() {
	err := getSttyState(&originalSttyState)
	if err != nil {
		log.Fatal(err)
	}
	defer setSttyState(&originalSttyState)

	setSttyState(bytes.NewBufferString("cbreak"))
	setSttyState(bytes.NewBufferString("-echo"))

	var input []byte = make([]byte, 0)
	var b []byte = make([]byte, 1)

	// TODO: Do not print results and input to STDOUT, only to TTY, only print
	// selected result to STDOUT

	// TODO: Run command in the background, draw as long as no new input given
	// if input is given, cancel command in background

	// TODO: Only print as many result lines as we have lines on the screen

	for {
		// Clear screen and set cursor to first row, first col
		err = drawInitialScreen()
		if err != nil {
			log.Fatal(err)
		}

		// Print prompt with already typed input
		prompt := fmt.Sprintf(">> %s", input[:len(input)])
		fmt.Printf("%s", prompt)

		// Print results
		// TODO: move this in a goroutine, give it a quit-channel, stream the output
		// to the current position (line after prompt)
		iname := fmt.Sprintf("*%s*", input[:len(input)])
		out, err := exec.Command("find", ".", "-iname", iname).Output()
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("\n%s", out)

		// Jump back to last typing position
		setCursorPos(0, len(prompt))

		os.Stdin.Read(b)
		switch b[0] {
		case 127:
			// Backspace
			if len(input) > 0 {
				input = input[:len(input)-1]
			}
		case 4, 13:
			// Return or Ctrl-D
			fmt.Println("Result:")
			fmt.Printf("%s%s\n", carriageReturn, string(input[:len(input)]))
			return
		default:
			// TODO: Default is wrong here. Only append printable characters to
			// input

			// TODO: Send a signal through the quit channel to the command in the background,
			// to cancel it
			// Everything else
			input = append(input, b...)
		}
	}
}
<|endoftext|>


<commit_before>package main

import "fmt"
import "os"
import "log"
import "os/exec"
import "strings"

func cmd(cmd string) string {
	out, err := exec.Command("sh", "-c", cmd).Output()
	if err != nil {
		log.Fatal(fmt.Sprintf("out='%s', err='%s'", out, err))
	}
	return string(out)
}

// docker run --rm -i -t -v `pwd`:`pwd` -w `pwd` --entrypoint="/bin/bash" go -c 'go build gcl.go'
func main() {
	args := os.Args
	id := args[1]
	fmt.Printf("container id: %s\n", id)
	out := cmd(fmt.Sprintf("docker inspect -f '{{ .Name }}' %s", id))
	name := strings.TrimSpace(out)[1:]
	fmt.Printf("  name: '%s'\n", name)
	out = cmd(fmt.Sprintf("docker inspect -f '{{ range $key, $value := .Volumes }}{{ $key }},{{ $value }}##~#{{ end }}' %s", name))
	volumes := strings.Split(out, "##~#")
	volumes = volumes[:len(volumes)-1]
	fmt.Printf("    volumes: '%v': %d\n", volumes, len(volumes))
	for i, volume := range volumes {
		vols := strings.Split(volume, ",")
		path := vols[0]
		vfs := vols[1]
		fmt.Printf("      volume %d: '%v'=>'%v'\n", i, path, vfs)
		if strings.Contains(vfs, "/var/lib/docker/vfs/dir/") {
			link := name + "###" + strings.Replace(path, "/", ",#,", -1)
			fmt.Printf("      link '%s'\n", link)
		}
	}
}
<commit_msg>gcl.go: make it standalone<commit_after>package main

import "fmt"

import "path/filepath"
import "log"

import "os/exec"
import "strings"

func mustcmd(acmd string) string {
	fmt.Println(acmd)
	out, err := cmd(acmd)
	if err != nil {
		log.Fatal(fmt.Sprintf("out='%s', err='%s'", out, err))
	}
	return string(out)
}

func cmd(cmd string) (string, error) {
	out, err := exec.Command("sh", "-c", cmd).Output()
	return string(out), err
}

// docker run --rm -i -t -v `pwd`:`pwd` -w `pwd` --entrypoint="/bin/bash" go -c 'go build gcl.go'
func main() {
	out := mustcmd("docker ps -qa --no-trunc")
	containers := strings.Split(out, "\n")
	containers = containers[:len(containers)-1]
	for _, id := range containers {
		fmt.Printf("container id: %s\n", id)
		out = mustcmd(fmt.Sprintf("docker inspect -f '{{ .Name }}' %s", id))
		name := strings.TrimSpace(out)[1:]
		fmt.Printf("  name: '%s'\n", name)
		out = mustcmd(fmt.Sprintf("docker inspect -f '{{ range $key, $value := .Volumes }}{{ $key }},{{ $value }}##~#{{ end }}' %s", name))
		volumes := strings.Split(out, "##~#")
		volumes = volumes[:len(volumes)-1]
		fmt.Printf("    volumes: '%v': %d\n", volumes, len(volumes))
		for i, volume := range volumes {
			vols := strings.Split(volume, ",")
			path := vols[0]
			vfs := vols[1]
			fmt.Printf("      volume %d: '%v'=>'%v'\n", i, path, vfs)
			if strings.Contains(vfs, "/var/lib/docker/vfs/dir/") {
				link := "." + name + "###" + strings.Replace(path, "/", ",#,", -1)
				fmt.Printf("      link '%s'\n", link)
				ls, _ := cmd(fmt.Sprintf("sudo ls /var/lib/docker/vfs/dir/%s 2> /dev/null", link))
				ls = strings.TrimSpace(ls)
				fmt.Printf("      ls link '%s'\n", ls)
				dir := filepath.Base(vfs)
				if ls == "" {
					fmt.Printf("      ln '%s' to '%s'\n", link, dir)
					mustcmd(fmt.Sprintf("sudo ln -s %s /var/lib/docker/vfs/dir/%s", dir, link))
				}
				if ls != dir && ls != "" {
					apathdir := fmt.Sprintf("/var/lib/docker/vfs/dir/%s", dir)
					mustcmd(fmt.Sprintf("sudo rm -Rf %s", apathdir))
					acmd := fmt.Sprintf("sudo ln -s %s %s", ls, apathdir)
					fmt.Printf("      must redirect '%s' to '%s'\n%s\n", dir, ls, acmd)
					mustcmd(acmd)
				}
			}
		}
	}
}
<|endoftext|>


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

package main

import (
	"flag"
	"fmt"
	"os"
    "crypto/sha256"
    "encoding/hex"

	"github.com/FactomProject/factom"
)

func get(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("get")
		return
	}

	switch args[0] {
	case "head":
		getHead()
	case "dblock":
		getDBlock(args)
	case "chain":
		getChain(args)
	case "eblock":
		getEBlock(args)
	case "entry":
		getEntry(args)
    case "chainid":
        getChainId(args)
	default:
		man("get")
	}
}

func getHead() {
	head, err := factom.GetDBlockHead()
	if err != nil {
		errorln(err)
		return
	}
	fmt.Println(head.KeyMR)
}

// We expect each element to be its own part in a chain ID
func getChainId(args [] string) {
    if len(args)<2 {
        fmt.Printf("No Chain Specification provided.  See help")
    }
    sum := sha256.New()
    fmt.Println("The chain components:")
    for i, str := range args {
        if i > 0 {
            fmt.Println("    ",str)
            x := sha256.Sum256([]byte(str))
            sum.Write(x[:])
        }
    }
    chainId := sum.Sum(nil)
    fmt.Println("produce the ChainID:")

    fmt.Println("    ",hex.EncodeToString(chainId),"\n")
}

func getDBlock(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("getDBlock")
		return
	}

	keymr := args[0]
	dblock, err := factom.GetDBlock(keymr)
	if err != nil {
		errorln(err)
		return
	}

	fmt.Println("PrevBlockKeyMR:", dblock.Header.PrevBlockKeyMR)
	fmt.Println("TimeStamp:", dblock.Header.TimeStamp)
	fmt.Println("SequenceNumber:", dblock.Header.SequenceNumber)

	for _, v := range dblock.EntryBlockList {
		fmt.Println("EntryBlock {")
		fmt.Println("	ChainID", v.ChainID)
		fmt.Println("	KeyMR", v.KeyMR)
		fmt.Println("}")
	}
}

func getChain(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("getChain")
		return
	}

	chainid := args[0]
	chain, err := factom.GetChainHead(chainid)
	if err != nil {
		errorln(err)
		return
	}

	fmt.Println(chain.ChainHead)
}

func getEBlock(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("getEBlock")
		return
	}

	keymr := args[0]
	eblock, err := factom.GetEBlock(keymr)
	if err != nil {
		errorln(err)
		return
	}

	fmt.Println("BlockSequenceNumber:", eblock.Header.BlockSequenceNumber)
	fmt.Println("ChainID:", eblock.Header.ChainID)
	fmt.Println("PrevKeyMR:", eblock.Header.PrevKeyMR)
	fmt.Println("TimeStamp:", eblock.Header.TimeStamp)

	for _, v := range eblock.EntryList {
		fmt.Println("EBEntry {")
		fmt.Println("	TimeStamp", v.TimeStamp)
		fmt.Println("	EntryHash", v.EntryHash)
		fmt.Println("}")
	}
}

func getEntry(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("getEntry")
		return
	}

	hash := args[0]
	entry, err := factom.GetEntry(hash)
	if err != nil {
		errorln(err)
		return
	}

	fmt.Println("ChainID:", entry.ChainID)
	for _, v := range entry.ExtIDs {
		fmt.Println("ExtID:", v)
	}
	fmt.Println("Content:", entry.Content)
}
<commit_msg>Better output looking at entries<commit_after>// Copyright 2015 Factom Foundation
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package main

import (
	"flag"
	"fmt"
	"os"
    "crypto/sha256"
    "encoding/hex"

	"github.com/FactomProject/factom"
)

func get(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("get")
		return
	}

	switch args[0] {
	case "head":
		getHead()
	case "dblock":
		getDBlock(args)
	case "chain":
		getChain(args)
	case "eblock":
		getEBlock(args)
	case "entry":
		getEntry(args)
    case "chainid":
        getChainId(args)
	default:
		man("get")
	}
}

func getHead() {
	head, err := factom.GetDBlockHead()
	if err != nil {
		errorln(err)
		return
	}
	fmt.Println(head.KeyMR)
}

// We expect each element to be its own part in a chain ID
func getChainId(args [] string) {
    if len(args)<2 {
        fmt.Printf("No Chain Specification provided.  See help")
    }
    sum := sha256.New()
    fmt.Println("The chain components:")
    for i, str := range args {
        if i > 0 {
            fmt.Println("    ",str)
            x := sha256.Sum256([]byte(str))
            sum.Write(x[:])
        }
    }
    chainId := sum.Sum(nil)
    fmt.Println("produce the ChainID:")

    fmt.Println("    ",hex.EncodeToString(chainId),"\n")
}

func getDBlock(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("getDBlock")
		return
	}

	keymr := args[0]
	dblock, err := factom.GetDBlock(keymr)
	if err != nil {
		errorln(err)
		return
	}

	fmt.Println("PrevBlockKeyMR:", dblock.Header.PrevBlockKeyMR)
	fmt.Println("TimeStamp:", dblock.Header.TimeStamp)
	fmt.Println("SequenceNumber:", dblock.Header.SequenceNumber)

	for _, v := range dblock.EntryBlockList {
		fmt.Println("EntryBlock {")
		fmt.Println("	ChainID", v.ChainID)
		fmt.Println("	KeyMR", v.KeyMR)
		fmt.Println("}")
	}
}

func getChain(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("getChain")
		return
	}

	chainid := args[0]
	chain, err := factom.GetChainHead(chainid)
	if err != nil {
		errorln(err)
		return
	}

	fmt.Println(chain.ChainHead)
}

func getEBlock(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("getEBlock")
		return
	}

	keymr := args[0]
	eblock, err := factom.GetEBlock(keymr)
	if err != nil {
		errorln(err)
		return
	}

	fmt.Println("BlockSequenceNumber:", eblock.Header.BlockSequenceNumber)
	fmt.Println("ChainID:", eblock.Header.ChainID)
	fmt.Println("PrevKeyMR:", eblock.Header.PrevKeyMR)
	fmt.Println("TimeStamp:", eblock.Header.TimeStamp)

	for _, v := range eblock.EntryList {
		fmt.Println("EBEntry {")
		fmt.Println("	TimeStamp", v.TimeStamp)
		fmt.Println("	EntryHash", v.EntryHash)
		fmt.Println("}")
	}
}

func getEntry(args []string) {
	os.Args = args
	flag.Parse()
	args = flag.Args()
	if len(args) < 1 {
		man("getEntry")
		return
	}

	hash := args[0]
	entry, err := factom.GetEntry(hash)
	if err != nil {
		errorln(err)
		return
	}

	fmt.Println("ChainID:", entry.ChainID)
	for _, v := range entry.ExtIDs {
		fmt.Println("ExtID:", v)
    }
    data, _ := hex.DecodeString(entry.Content)

    str := fmt.Sprintf("Content:\n")
    p := data
    for len(p) >= 16 {
        str = str + fmt.Sprintf("% x | % x  || ",p[:8],p[8:16])
        str = str + fmt.Sprintf("%+q\n",p[:16])
        p = p[:16]
    }
    if len(p) > 8 {
        str = str + fmt.Sprintf("% x | % x",p[:8],p[8:])
        for i:=len(p); i < 16; i++ { str = str + "   " }
        str = str + fmt.Sprintf("  || %+q\n",p)
    }else{
        str = str + fmt.Sprintf("% x\n",p)
        for i:=len(p); i < 8; i++ { str = str + "   " }
        str = str + fmt.Sprintf(" |                           || %+q\n",p)
    }
    fmt.Print(str)
}
<|endoftext|>


<commit_before>package main

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

type ma struct {
	pb *gdk.Pixbuf

	maxx float64
	maxy float64

	minx float64
	miny float64

	sx float64
	sy float64

	iter int

	h int
	w int

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

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

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

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

	return ma
}

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

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

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

	ma.iter = 100
}

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

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

	for y := 0; y < ma.h; y++ {
		cy := ma.maxy - float64(y) * ma.sy
		for x := 0; x < ma.w; x++ {
			cx := ma.minx + float64(x) * ma.sx
			o := y * rs + x * nc

			c := complex(cx, cy)
			z := c
			i := 0
			for ; i < ma.iter; i++ {
				if cmplx.Abs(z) > 2.0 {
					break
				}
				z = z * z + c
			}

			rc := byte(0)
			if i < ma.iter {
				c := 1.0 - float64(i) / float64(ma.iter)
				rc = byte(c * 255)
			}

			px[o + 0] = rc
			px[o + 1] = rc
			px[o + 2] = rc
		}
	}
}

func (ma *ma)updateLabels() {
	ma.label.l.SetText(fmt.Sprintf("%6.4E", ma.minx))
	ma.label.r.SetText(fmt.Sprintf("%6.4E", ma.maxx))
	ma.label.t.SetText(fmt.Sprintf("%6.4E", ma.miny))
	ma.label.b.SetText(fmt.Sprintf("%6.4E", ma.maxy))
}

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

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

	ph := fmt.Sprintf("%6.4E", 1.0)

	ma.label.l = label(ph)
	ma.label.r = label(ph)
	ma.label.t = label(ph)
	ma.label.b = label(ph)

	ma.updateLabels()

	gr.Attach(label("minx:"), 0, 0, 1, 1)
	gr.Attach(label("maxx:"), 0, 1, 1, 1)
	gr.Attach(label("miny:"), 0, 2, 1, 1)
	gr.Attach(label("maxy:"), 0, 3, 1, 1)
	gr.Attach(ma.label.l, 1, 0, 1, 1)
	gr.Attach(ma.label.r, 1, 1, 1, 1)
	gr.Attach(ma.label.b, 1, 3, 1, 1)
	gr.Attach(ma.label.t, 1, 2, 1, 1)

	hb.PackStart(gr, false, false, 0)

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

	return hb
}

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

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

	eb.Add(im)

	eb.AddEvents(int(gdk.SCROLL_MASK))

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

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

	redraw()

	_, err = eb.Connect("button_press_event", func(win *gtk.Window, ev *gdk.Event) {
		e := &gdk.EventButton{ev}
		cx, cy = ma.screenCoords(e.X(), e.Y())
		redraw()
	})
	_, err = eb.Connect("scroll-event", func(win *gtk.Window, ev *gdk.Event) {
		es := &gdk.EventScroll{ev}
		delta := es.DeltaY() * (zw / 5.0)
		switch es.Direction() {
		case gdk.SCROLL_UP:
			zw -= delta
		case gdk.SCROLL_DOWN:
			zw += delta
		}
		redraw()
	})
	if err != nil {
		log.Fatal("connect: ", err)
	}
	return eb
}

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

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

	ma := newma()

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

	gtk.Main()
}
<commit_msg>Add some colors.<commit_after>package main

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

type ma struct {
	pb *gdk.Pixbuf

	maxx float64
	maxy float64

	minx float64
	miny float64

	sx float64
	sy float64

	iter int

	h int
	w int

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

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

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

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

	return ma
}

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

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

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

	ma.iter = 100
}

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

var palette = [...][3]float64{
	{ 1.0, 0.0, 0.0 },
	{ 1.0, 1.0, 0.0 },
	{ 0.0, 1.0, 0.0 },
	{ 0.0, 1.0, 1.0 },
	{ 0.0, 0.0, 1.0 },
	{ 1.0, 0.0, 1.0 },
}

var log_escape = math.Log(2)

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

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

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

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

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

	for y := 0; y < ma.h; y++ {
		cy := ma.maxy - float64(y) * ma.sy
		for x := 0; x < ma.w; x++ {
			cx := ma.minx + float64(x) * ma.sx
			o := y * rs + x * nc

			c := complex(cx, cy)
			z := c
			i := 0
			for ; i < ma.iter; i++ {
				if cmplx.Abs(z) > 2.0 {
					break
				}
				z = z * z + c
			}

			copy(px[o:], ma.getColor(z, c, i))
		}
	}
}

func (ma *ma)updateLabels() {
	ma.label.l.SetText(fmt.Sprintf("%6.4E", ma.minx))
	ma.label.r.SetText(fmt.Sprintf("%6.4E", ma.maxx))
	ma.label.t.SetText(fmt.Sprintf("%6.4E", ma.miny))
	ma.label.b.SetText(fmt.Sprintf("%6.4E", ma.maxy))
}

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

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

	ph := fmt.Sprintf("%6.4E", 1.0)

	ma.label.l = label(ph)
	ma.label.r = label(ph)
	ma.label.t = label(ph)
	ma.label.b = label(ph)

	ma.updateLabels()

	gr.Attach(label("minx:"), 0, 0, 1, 1)
	gr.Attach(label("maxx:"), 0, 1, 1, 1)
	gr.Attach(label("miny:"), 0, 2, 1, 1)
	gr.Attach(label("maxy:"), 0, 3, 1, 1)
	gr.Attach(ma.label.l, 1, 0, 1, 1)
	gr.Attach(ma.label.r, 1, 1, 1, 1)
	gr.Attach(ma.label.b, 1, 3, 1, 1)
	gr.Attach(ma.label.t, 1, 2, 1, 1)

	hb.PackStart(gr, false, false, 0)

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

	return hb
}

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

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

	eb.Add(im)

	eb.AddEvents(int(gdk.SCROLL_MASK))

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

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

	redraw()

	_, err = eb.Connect("button_press_event", func(win *gtk.Window, ev *gdk.Event) {
		e := &gdk.EventButton{ev}
		cx, cy = ma.screenCoords(e.X(), e.Y())
		redraw()
	})
	_, err = eb.Connect("scroll-event", func(win *gtk.Window, ev *gdk.Event) {
		es := &gdk.EventScroll{ev}
		delta := es.DeltaY() * (zw / 5.0)
		switch es.Direction() {
		case gdk.SCROLL_UP:
			zw -= delta
		case gdk.SCROLL_DOWN:
			zw += delta
		}
		redraw()
	})
	if err != nil {
		log.Fatal("connect: ", err)
	}
	return eb
}

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

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

	ma := newma()

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

	gtk.Main()
}
<|endoftext|>


<commit_before>package gin

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

const (
	AbortIndex = math.MaxInt8 / 2
)

type (
	HandlerFunc func(*Context)

	H map[string]interface{}

	// Used internally to collect a error ocurred during a http request.
	ErrorMsg struct {
		Err  string      `json:"error"`
		Meta interface{} `json:"meta"`
	}

	ErrorMsgs []ErrorMsg

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

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

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

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

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

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

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

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

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

	c.Next()
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// Writes some data into the body stream and updates the HTTP code
func (c *Context) Data(code int, data []byte) {
	c.Writer.WriteHeader(code)
	c.Writer.Write(data)
}
<commit_msg>Adds context.LastError()<commit_after>package gin

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

const (
	AbortIndex = math.MaxInt8 / 2
)

type (
	HandlerFunc func(*Context)

	H map[string]interface{}

	// Used internally to collect a error ocurred during a http request.
	ErrorMsg struct {
		Err  string      `json:"error"`
		Meta interface{} `json:"meta"`
	}

	ErrorMsgs []ErrorMsg

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

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

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

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

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

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

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

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

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

	c.Next()
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


<commit_before>package main

import (
	"errors"
	"io/ioutil"
	"os/exec"

	"golang.org/x/crypto/ssh"

	"os"

	"path/filepath"

	"gopkg.in/src-d/go-git.v4"
	gitssh "gopkg.in/src-d/go-git.v4/plumbing/transport/ssh"
)

func getAuth() (*gitssh.PublicKeys, error) {
	pem, err := ioutil.ReadFile(cfg.SSH.PrivateKey)
	if err != nil {
		return nil, errors.New("couldn't read private key '" + cfg.SSH.PrivateKey + "'")
	}

	signer, err := ssh.ParsePrivateKey(pem)
	if err != nil {
		return nil, err
	}

	auth := &gitssh.PublicKeys{
		User:   cfg.SSH.Username,
		Signer: signer,
	}

	return auth, nil
}

// gitClone uses go-git functions to clone.
func gitClone(url, path string) error {
	auth, err := getAuth()
	if err != nil {
		return err
	}

	o := git.CloneOptions{
		URL:  url,
		Auth: auth,
	}

	path = filepath.Join(cfg.Repos, path)
	_, err = git.PlainClone(path, false, &o)
	if err != nil {
		return err
	}

	return nil
}

// gitPull updates a repository via go-git functions.
func gitPull(path string) error {
	auth, err := getAuth()
	if err != nil {
		return err
	}

	o := git.PullOptions{
		Auth: auth,
	}

	path = filepath.Join(cfg.Repos, path)
	repo, err := git.PlainOpen(path)
	if err != nil {
		return err
	}

	err = repo.Pull(&o)
	return err
}

// gitExternalClone clones via whichever command line git is installed in the user's path.
// Use with anything which go-git can't handle, like VSTS.
func gitExternalClone(url, path string) error {
	cmd := exec.Command("git", "-C", cfg.Repos, "clone", url, path)

	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err := cmd.Run()
	if err != nil {
		return err
	}

	return nil
}

// gitExternalPull updates via the installed git command.
func gitExternalPull(path string) error {
	cmd := exec.Command("git", "-C", cfg.Repos, "pull")

	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err := cmd.Run()
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>Corrected path for external pull.<commit_after>package main

import (
	"errors"
	"io/ioutil"
	"os/exec"

	"golang.org/x/crypto/ssh"

	"os"

	"path/filepath"

	"gopkg.in/src-d/go-git.v4"
	gitssh "gopkg.in/src-d/go-git.v4/plumbing/transport/ssh"
)

func getAuth() (*gitssh.PublicKeys, error) {
	pem, err := ioutil.ReadFile(cfg.SSH.PrivateKey)
	if err != nil {
		return nil, errors.New("couldn't read private key '" + cfg.SSH.PrivateKey + "'")
	}

	signer, err := ssh.ParsePrivateKey(pem)
	if err != nil {
		return nil, err
	}

	auth := &gitssh.PublicKeys{
		User:   cfg.SSH.Username,
		Signer: signer,
	}

	return auth, nil
}

// gitClone uses go-git functions to clone.
func gitClone(url, path string) error {
	auth, err := getAuth()
	if err != nil {
		return err
	}

	o := git.CloneOptions{
		URL:  url,
		Auth: auth,
	}

	path = filepath.Join(cfg.Repos, path)
	_, err = git.PlainClone(path, false, &o)
	if err != nil {
		return err
	}

	return nil
}

// gitPull updates a repository via go-git functions.
func gitPull(path string) error {
	auth, err := getAuth()
	if err != nil {
		return err
	}

	o := git.PullOptions{
		Auth: auth,
	}

	path = filepath.Join(cfg.Repos, path)
	repo, err := git.PlainOpen(path)
	if err != nil {
		return err
	}

	err = repo.Pull(&o)
	return err
}

// gitExternalClone clones via whichever command line git is installed in the user's path.
// Use with anything which go-git can't handle, like VSTS.
func gitExternalClone(url, path string) error {
	cmd := exec.Command("git", "-C", cfg.Repos, "clone", url, path)

	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err := cmd.Run()
	if err != nil {
		return err
	}

	return nil
}

// gitExternalPull updates via the installed git command.
func gitExternalPull(path string) error {
	path = filepath.Join(cfg.Repos, path)
	cmd := exec.Command("git", "-C", path, "pull")

	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	err := cmd.Run()
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>