<commit_before>// Copyright Published at floating-point-gui.de
// under the Creative Commons Attribution License (BY)
// http://creativecommons.org/licenses/by/3.0/

package math

//------------------------------------------------------------------------------

// Returns true if the relative error between a and b is less than epsilon.
//
// Handles special cases: zero, infinites, denormals.
func NearlyEqual(a, b float32, epsilon float32) bool {
	// Source: http://floating-point-gui.de/errors/comparison/

	if a < 0 { a = -a }
	if b < 0 { b = -b }
	diff := a - b
	if diff < 0 { diff = - diff }

	if a == b {
		// Shortcut, handles infinities.
		return true
	} else if a == 0 || b == 0 || diff < SmallestNormalFloat32 {
		// a or b is zero or both are extremely close to it.
		// Relative error is less meaningful here.
		return diff < (epsilon * SmallestNormalFloat32)
	} else {
		// Use relative error.
		return diff / (absA + absB) < epsilon;
	}
}

//------------------------------------------------------------------------------
<commit_msg>Fixed copy/paste bug.<commit_after>// Copyright Published at floating-point-gui.de
// under the Creative Commons Attribution License (BY)
// http://creativecommons.org/licenses/by/3.0/

package math

//------------------------------------------------------------------------------

// Returns true if the relative error between a and b is less than epsilon.
//
// Handles special cases: zero, infinites, denormals.
func NearlyEqual(a, b float32, epsilon float32) bool {
	// Source: http://floating-point-gui.de/errors/comparison/

	absA := a
	if absA < 0 {
		absA = -absA
	}
	absB := b
	if absB < 0 {
		absB = -absB
	}
	diff := a - b
	if diff < 0 {
		diff = -diff
	}

	if a == b {
		// Shortcut, handles infinities.
		return true
	} else if a == 0 || b == 0 || diff < SmallestNormalFloat32 {
		// a or b is zero or both are extremely close to it.
		// Relative error is less meaningful here.
		return diff < (epsilon * SmallestNormalFloat32)
	} else {
		// Use relative error.
		return diff/(absA+absB) < epsilon
	}
}

//------------------------------------------------------------------------------
<|endoftext|>


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

// +build ignore

package main

// This file replaces main.go when running godoc under app-engine.
// See README.godoc-app for details.

import (
	"archive/zip"
	"log"
	"net/http"
	"path"
)

func serveError(w http.ResponseWriter, r *http.Request, relpath string, err error) {
	contents := applyTemplate(errorHTML, "errorHTML", err) // err may contain an absolute path!
	w.WriteHeader(http.StatusNotFound)
	servePage(w, "File "+relpath, "", "", contents)
}

func init() {
	log.Println("initializing godoc ...")
	log.Printf(".zip file   = %s", zipFilename)
	log.Printf(".zip GOROOT = %s", zipGoroot)
	log.Printf("index files = %s", indexFilenames)

	// initialize flags for app engine
	*goroot = path.Join("/", zipGoroot) // fsHttp paths are relative to '/'
	*indexEnabled = true
	*indexFiles = indexFilenames
	*maxResults = 100    // reduce latency by limiting the number of fulltext search results
	*indexThrottle = 0.3 // in case *indexFiles is empty (and thus the indexer is run)

	// read .zip file and set up file systems
	const zipfile = zipFilename
	rc, err := zip.OpenReader(zipfile)
	if err != nil {
		log.Fatalf("%s: %s\n", zipfile, err)
	}
	// rc is never closed (app running forever)
	fs.Bind("/", NewZipFS(rc, zipFilename), "/", bindReplace)

	// initialize http handlers
	readTemplates()
	initHandlers()
	registerPublicHandlers(http.DefaultServeMux)

	// initialize default directory tree with corresponding timestamp.
	initFSTree()

	// Immediately update metadata.
	updateMetadata()

	// initialize search index
	if *indexEnabled {
		go indexer()
	}

	log.Println("godoc initialization complete")
}
<commit_msg>cmd/godoc: s/ignore/appengine/ in appinit.go +build constraint<commit_after>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// +build appengine

package main

// This file replaces main.go when running godoc under app-engine.
// See README.godoc-app for details.

import (
	"archive/zip"
	"log"
	"net/http"
	"path"
)

func serveError(w http.ResponseWriter, r *http.Request, relpath string, err error) {
	contents := applyTemplate(errorHTML, "errorHTML", err) // err may contain an absolute path!
	w.WriteHeader(http.StatusNotFound)
	servePage(w, "File "+relpath, "", "", contents)
}

func init() {
	log.Println("initializing godoc ...")
	log.Printf(".zip file   = %s", zipFilename)
	log.Printf(".zip GOROOT = %s", zipGoroot)
	log.Printf("index files = %s", indexFilenames)

	// initialize flags for app engine
	*goroot = path.Join("/", zipGoroot) // fsHttp paths are relative to '/'
	*indexEnabled = true
	*indexFiles = indexFilenames
	*maxResults = 100    // reduce latency by limiting the number of fulltext search results
	*indexThrottle = 0.3 // in case *indexFiles is empty (and thus the indexer is run)

	// read .zip file and set up file systems
	const zipfile = zipFilename
	rc, err := zip.OpenReader(zipfile)
	if err != nil {
		log.Fatalf("%s: %s\n", zipfile, err)
	}
	// rc is never closed (app running forever)
	fs.Bind("/", NewZipFS(rc, zipFilename), "/", bindReplace)

	// initialize http handlers
	readTemplates()
	initHandlers()
	registerPublicHandlers(http.DefaultServeMux)

	// initialize default directory tree with corresponding timestamp.
	initFSTree()

	// Immediately update metadata.
	updateMetadata()

	// initialize search index
	if *indexEnabled {
		go indexer()
	}

	log.Println("godoc initialization complete")
}
<|endoftext|>


<commit_before>package blueprint

import (
	"errors"
	"fmt"
	"sort"
	"strconv"
	"strings"
)

// A Deps value indicates the dependency file format that Ninja should expect to
// be output by a compiler.
type Deps int

const (
	DepsNone Deps = iota
	DepsGCC
	DepsMSVC
)

func (d Deps) String() string {
	switch d {
	case DepsNone:
		return "none"
	case DepsGCC:
		return "gcc"
	case DepsMSVC:
		return "msvc"
	default:
		panic(fmt.Sprintf("unknown deps value: %d", d))
	}
}

// A PoolParams object contains the set of parameters that make up a Ninja pool
// definition.
type PoolParams struct {
	Comment string // The comment that will appear above the definition.
	Depth   int    // The Ninja pool depth.
}

// A RuleParams object contains the set of parameters that make up a Ninja rule
// definition.  Each field except for Comment corresponds with a Ninja variable
// of the same name.
type RuleParams struct {
	Comment        string // The comment that will appear above the definition.
	Command        string // The command that Ninja will run for the rule.
	Depfile        string // The dependency file name.
	Deps           Deps   // The format of the dependency file.
	Description    string // The description that Ninja will print for the rule.
	Generator      bool   // Whether the rule generates the Ninja manifest file.
	Pool           Pool   // The Ninja pool to which the rule belongs.
	Restat         bool   // Whether Ninja should re-stat the rule's outputs.
	Rspfile        string // The response file.
	RspfileContent string // The response file content.
}

// A BuildParams object contains the set of parameters that make up a Ninja
// build statement.  Each field except for Args corresponds with a part of the
// Ninja build statement.  The Args field contains variable names and values
// that are set within the build statement's scope in the Ninja file.
type BuildParams struct {
	Rule      Rule              // The rule to invoke.
	Outputs   []string          // The list of output targets.
	Inputs    []string          // The list of explicit input dependencies.
	Implicits []string          // The list of implicit dependencies.
	OrderOnly []string          // The list of order-only dependencies.
	Args      map[string]string // The variable/value pairs to set.
}

// A poolDef describes a pool definition.  It does not include the name of the
// pool.
type poolDef struct {
	Comment string
	Depth   int
}

func parsePoolParams(scope scope, params *PoolParams) (*poolDef,
	error) {

	def := &poolDef{
		Comment: params.Comment,
		Depth:   params.Depth,
	}

	return def, nil
}

func (p *poolDef) WriteTo(nw *ninjaWriter, name string) error {
	if p.Comment != "" {
		err := nw.Comment(p.Comment)
		if err != nil {
			return err
		}
	}

	err := nw.Pool(name)
	if err != nil {
		return err
	}

	return nw.ScopedAssign("depth", strconv.Itoa(p.Depth))
}

// A ruleDef describes a rule definition.  It does not include the name of the
// rule.
type ruleDef struct {
	Comment   string
	Pool      Pool
	Variables map[string]*ninjaString
}

func parseRuleParams(scope scope, params *RuleParams) (*ruleDef,
	error) {

	r := &ruleDef{
		Comment:   params.Comment,
		Pool:      params.Pool,
		Variables: make(map[string]*ninjaString),
	}

	if params.Command == "" {
		return nil, fmt.Errorf("encountered rule params with no command " +
			"specified")
	}

	if r.Pool != nil && !scope.IsPoolVisible(r.Pool) {
		return nil, fmt.Errorf("Pool %s is not visible in this scope", r.Pool)
	}

	value, err := parseNinjaString(scope, params.Command)
	if err != nil {
		return nil, fmt.Errorf("error parsing Command param: %s", err)
	}
	r.Variables["command"] = value

	if params.Depfile != "" {
		value, err = parseNinjaString(scope, params.Depfile)
		if err != nil {
			return nil, fmt.Errorf("error parsing Depfile param: %s", err)
		}
		r.Variables["depfile"] = value
	}

	if params.Deps != DepsNone {
		r.Variables["deps"] = simpleNinjaString(params.Deps.String())
	}

	if params.Description != "" {
		value, err = parseNinjaString(scope, params.Description)
		if err != nil {
			return nil, fmt.Errorf("error parsing Description param: %s", err)
		}
		r.Variables["description"] = value
	}

	if params.Generator {
		r.Variables["generator"] = simpleNinjaString("true")
	}

	if params.Restat {
		r.Variables["restat"] = simpleNinjaString("true")
	}

	if params.Rspfile != "" {
		value, err = parseNinjaString(scope, params.Rspfile)
		if err != nil {
			return nil, fmt.Errorf("error parsing Rspfile param: %s", err)
		}
		r.Variables["rspfile"] = value
	}

	if params.RspfileContent != "" {
		value, err = parseNinjaString(scope, params.RspfileContent)
		if err != nil {
			return nil, fmt.Errorf("error parsing RspfileContent param: %s",
				err)
		}
		r.Variables["rspfile_content"] = value
	}

	return r, nil
}

func (r *ruleDef) WriteTo(nw *ninjaWriter, name string,
	pkgNames map[*PackageContext]string) error {

	if r.Comment != "" {
		err := nw.Comment(r.Comment)
		if err != nil {
			return err
		}
	}

	err := nw.Rule(name)
	if err != nil {
		return err
	}

	if r.Pool != nil {
		err = nw.ScopedAssign("pool", r.Pool.fullName(pkgNames))
		if err != nil {
			return err
		}
	}

	var keys []string
	for k := range r.Variables {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	for _, name := range keys {
		err = nw.ScopedAssign(name, r.Variables[name].Value(pkgNames))
		if err != nil {
			return err
		}
	}

	return nil
}

// A buildDef describes a build target definition.
type buildDef struct {
	Rule      Rule
	Outputs   []*ninjaString
	Inputs    []*ninjaString
	Implicits []*ninjaString
	OrderOnly []*ninjaString
	Args      map[Variable]*ninjaString
}

func parseBuildParams(scope scope, params *BuildParams) (*buildDef,
	error) {

	rule := params.Rule

	b := &buildDef{
		Rule: rule,
	}

	if !scope.IsRuleVisible(rule) {
		return nil, fmt.Errorf("Rule %s is not visible in this scope", rule)
	}

	if len(params.Outputs) == 0 {
		return nil, errors.New("Outputs param has no elements")
	}

	var err error
	b.Outputs, err = parseNinjaStrings(scope, params.Outputs)
	if err != nil {
		return nil, fmt.Errorf("error parsing Outputs param: %s", err)
	}

	b.Inputs, err = parseNinjaStrings(scope, params.Inputs)
	if err != nil {
		return nil, fmt.Errorf("error parsing Inputs param: %s", err)
	}

	b.Implicits, err = parseNinjaStrings(scope, params.Implicits)
	if err != nil {
		return nil, fmt.Errorf("error parsing Implicits param: %s", err)
	}

	b.OrderOnly, err = parseNinjaStrings(scope, params.OrderOnly)
	if err != nil {
		return nil, fmt.Errorf("error parsing OrderOnly param: %s", err)
	}

	argNameScope := rule.scope()

	if len(params.Args) > 0 {
		b.Args = make(map[Variable]*ninjaString)
		for name, value := range params.Args {
			if !rule.isArg(name) {
				return nil, fmt.Errorf("unknown argument %q", name)
			}

			argVar, err := argNameScope.LookupVariable(name)
			if err != nil {
				// This shouldn't happen.
				return nil, fmt.Errorf("argument lookup error: %s", err)
			}

			ninjaValue, err := parseNinjaString(scope, value)
			if err != nil {
				return nil, fmt.Errorf("error parsing variable %q: %s", name,
					err)
			}

			b.Args[argVar] = ninjaValue
		}
	}

	return b, nil
}

func (b *buildDef) WriteTo(nw *ninjaWriter, pkgNames map[*PackageContext]string) error {
	var (
		rule          = b.Rule.fullName(pkgNames)
		outputs       = valueList(b.Outputs, pkgNames, outputEscaper)
		explicitDeps  = valueList(b.Inputs, pkgNames, inputEscaper)
		implicitDeps  = valueList(b.Implicits, pkgNames, inputEscaper)
		orderOnlyDeps = valueList(b.OrderOnly, pkgNames, inputEscaper)
	)
	err := nw.Build(rule, outputs, explicitDeps, implicitDeps, orderOnlyDeps)
	if err != nil {
		return err
	}

	args := make(map[string]string)

	for argVar, value := range b.Args {
		args[argVar.fullName(pkgNames)] = value.Value(pkgNames)
	}

	var keys []string
	for k := range args {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	for _, name := range keys {
		err = nw.ScopedAssign(name, args[name])
		if err != nil {
			return err
		}
	}

	return nil
}

func valueList(list []*ninjaString, pkgNames map[*PackageContext]string,
	escaper *strings.Replacer) []string {

	result := make([]string, len(list))
	for i, ninjaStr := range list {
		result[i] = ninjaStr.ValueWithEscaper(pkgNames, escaper)
	}
	return result
}
<commit_msg>Add support for Optional parameter to build definitions<commit_after>package blueprint

import (
	"errors"
	"fmt"
	"sort"
	"strconv"
	"strings"
)

// A Deps value indicates the dependency file format that Ninja should expect to
// be output by a compiler.
type Deps int

const (
	DepsNone Deps = iota
	DepsGCC
	DepsMSVC
)

func (d Deps) String() string {
	switch d {
	case DepsNone:
		return "none"
	case DepsGCC:
		return "gcc"
	case DepsMSVC:
		return "msvc"
	default:
		panic(fmt.Sprintf("unknown deps value: %d", d))
	}
}

// A PoolParams object contains the set of parameters that make up a Ninja pool
// definition.
type PoolParams struct {
	Comment string // The comment that will appear above the definition.
	Depth   int    // The Ninja pool depth.
}

// A RuleParams object contains the set of parameters that make up a Ninja rule
// definition.  Each field except for Comment corresponds with a Ninja variable
// of the same name.
type RuleParams struct {
	Comment        string // The comment that will appear above the definition.
	Command        string // The command that Ninja will run for the rule.
	Depfile        string // The dependency file name.
	Deps           Deps   // The format of the dependency file.
	Description    string // The description that Ninja will print for the rule.
	Generator      bool   // Whether the rule generates the Ninja manifest file.
	Pool           Pool   // The Ninja pool to which the rule belongs.
	Restat         bool   // Whether Ninja should re-stat the rule's outputs.
	Rspfile        string // The response file.
	RspfileContent string // The response file content.
}

// A BuildParams object contains the set of parameters that make up a Ninja
// build statement.  Each field except for Args corresponds with a part of the
// Ninja build statement.  The Args field contains variable names and values
// that are set within the build statement's scope in the Ninja file.
type BuildParams struct {
	Rule      Rule              // The rule to invoke.
	Outputs   []string          // The list of output targets.
	Inputs    []string          // The list of explicit input dependencies.
	Implicits []string          // The list of implicit dependencies.
	OrderOnly []string          // The list of order-only dependencies.
	Args      map[string]string // The variable/value pairs to set.
}

// A poolDef describes a pool definition.  It does not include the name of the
// pool.
type poolDef struct {
	Comment string
	Depth   int
}

func parsePoolParams(scope scope, params *PoolParams) (*poolDef,
	error) {

	def := &poolDef{
		Comment: params.Comment,
		Depth:   params.Depth,
	}

	return def, nil
}

func (p *poolDef) WriteTo(nw *ninjaWriter, name string) error {
	if p.Comment != "" {
		err := nw.Comment(p.Comment)
		if err != nil {
			return err
		}
	}

	err := nw.Pool(name)
	if err != nil {
		return err
	}

	return nw.ScopedAssign("depth", strconv.Itoa(p.Depth))
}

// A ruleDef describes a rule definition.  It does not include the name of the
// rule.
type ruleDef struct {
	Comment   string
	Pool      Pool
	Variables map[string]*ninjaString
}

func parseRuleParams(scope scope, params *RuleParams) (*ruleDef,
	error) {

	r := &ruleDef{
		Comment:   params.Comment,
		Pool:      params.Pool,
		Variables: make(map[string]*ninjaString),
	}

	if params.Command == "" {
		return nil, fmt.Errorf("encountered rule params with no command " +
			"specified")
	}

	if r.Pool != nil && !scope.IsPoolVisible(r.Pool) {
		return nil, fmt.Errorf("Pool %s is not visible in this scope", r.Pool)
	}

	value, err := parseNinjaString(scope, params.Command)
	if err != nil {
		return nil, fmt.Errorf("error parsing Command param: %s", err)
	}
	r.Variables["command"] = value

	if params.Depfile != "" {
		value, err = parseNinjaString(scope, params.Depfile)
		if err != nil {
			return nil, fmt.Errorf("error parsing Depfile param: %s", err)
		}
		r.Variables["depfile"] = value
	}

	if params.Deps != DepsNone {
		r.Variables["deps"] = simpleNinjaString(params.Deps.String())
	}

	if params.Description != "" {
		value, err = parseNinjaString(scope, params.Description)
		if err != nil {
			return nil, fmt.Errorf("error parsing Description param: %s", err)
		}
		r.Variables["description"] = value
	}

	if params.Generator {
		r.Variables["generator"] = simpleNinjaString("true")
	}

	if params.Restat {
		r.Variables["restat"] = simpleNinjaString("true")
	}

	if params.Rspfile != "" {
		value, err = parseNinjaString(scope, params.Rspfile)
		if err != nil {
			return nil, fmt.Errorf("error parsing Rspfile param: %s", err)
		}
		r.Variables["rspfile"] = value
	}

	if params.RspfileContent != "" {
		value, err = parseNinjaString(scope, params.RspfileContent)
		if err != nil {
			return nil, fmt.Errorf("error parsing RspfileContent param: %s",
				err)
		}
		r.Variables["rspfile_content"] = value
	}

	return r, nil
}

func (r *ruleDef) WriteTo(nw *ninjaWriter, name string,
	pkgNames map[*PackageContext]string) error {

	if r.Comment != "" {
		err := nw.Comment(r.Comment)
		if err != nil {
			return err
		}
	}

	err := nw.Rule(name)
	if err != nil {
		return err
	}

	if r.Pool != nil {
		err = nw.ScopedAssign("pool", r.Pool.fullName(pkgNames))
		if err != nil {
			return err
		}
	}

	var keys []string
	for k := range r.Variables {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	for _, name := range keys {
		err = nw.ScopedAssign(name, r.Variables[name].Value(pkgNames))
		if err != nil {
			return err
		}
	}

	return nil
}

// A buildDef describes a build target definition.
type buildDef struct {
	Rule      Rule
	Outputs   []*ninjaString
	Inputs    []*ninjaString
	Implicits []*ninjaString
	OrderOnly []*ninjaString
	Args      map[Variable]*ninjaString
	Optional  bool
}

func parseBuildParams(scope scope, params *BuildParams) (*buildDef,
	error) {

	rule := params.Rule

	b := &buildDef{
		Rule: rule,
	}

	if !scope.IsRuleVisible(rule) {
		return nil, fmt.Errorf("Rule %s is not visible in this scope", rule)
	}

	if len(params.Outputs) == 0 {
		return nil, errors.New("Outputs param has no elements")
	}

	var err error
	b.Outputs, err = parseNinjaStrings(scope, params.Outputs)
	if err != nil {
		return nil, fmt.Errorf("error parsing Outputs param: %s", err)
	}

	b.Inputs, err = parseNinjaStrings(scope, params.Inputs)
	if err != nil {
		return nil, fmt.Errorf("error parsing Inputs param: %s", err)
	}

	b.Implicits, err = parseNinjaStrings(scope, params.Implicits)
	if err != nil {
		return nil, fmt.Errorf("error parsing Implicits param: %s", err)
	}

	b.OrderOnly, err = parseNinjaStrings(scope, params.OrderOnly)
	if err != nil {
		return nil, fmt.Errorf("error parsing OrderOnly param: %s", err)
	}

	argNameScope := rule.scope()

	if len(params.Args) > 0 {
		b.Args = make(map[Variable]*ninjaString)
		for name, value := range params.Args {
			if !rule.isArg(name) {
				return nil, fmt.Errorf("unknown argument %q", name)
			}

			argVar, err := argNameScope.LookupVariable(name)
			if err != nil {
				// This shouldn't happen.
				return nil, fmt.Errorf("argument lookup error: %s", err)
			}

			ninjaValue, err := parseNinjaString(scope, value)
			if err != nil {
				return nil, fmt.Errorf("error parsing variable %q: %s", name,
					err)
			}

			b.Args[argVar] = ninjaValue
		}
	}

	return b, nil
}

func (b *buildDef) WriteTo(nw *ninjaWriter, pkgNames map[*PackageContext]string) error {
	var (
		rule          = b.Rule.fullName(pkgNames)
		outputs       = valueList(b.Outputs, pkgNames, outputEscaper)
		explicitDeps  = valueList(b.Inputs, pkgNames, inputEscaper)
		implicitDeps  = valueList(b.Implicits, pkgNames, inputEscaper)
		orderOnlyDeps = valueList(b.OrderOnly, pkgNames, inputEscaper)
	)
	err := nw.Build(rule, outputs, explicitDeps, implicitDeps, orderOnlyDeps)
	if err != nil {
		return err
	}

	args := make(map[string]string)

	for argVar, value := range b.Args {
		args[argVar.fullName(pkgNames)] = value.Value(pkgNames)
	}

	var keys []string
	for k := range args {
		keys = append(keys, k)
	}
	sort.Strings(keys)

	for _, name := range keys {
		err = nw.ScopedAssign(name, args[name])
		if err != nil {
			return err
		}
	}

	if !b.Optional {
		nw.Default(outputs...)
	}

	return nil
}

func valueList(list []*ninjaString, pkgNames map[*PackageContext]string,
	escaper *strings.Replacer) []string {

	result := make([]string, len(list))
	for i, ninjaStr := range list {
		result[i] = ninjaStr.ValueWithEscaper(pkgNames, escaper)
	}
	return result
}
<|endoftext|>


<commit_before>/*
Copyright The Helm Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package registry // import "helm.sh/helm/v3/internal/experimental/registry"

import (
	"encoding/json"
	"fmt"

	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
	"github.com/pkg/errors"
	"oras.land/oras-go/pkg/content"
	"oras.land/oras-go/pkg/oras"

	"helm.sh/helm/v3/pkg/chart"
)

// Pull downloads a chart from a registry
func (c *Client) Pull(ref string, options ...PullOption) (*PullResult, error) {
	operation := &pullOperation{
		withChart: true, // By default, always download the chart layer
	}
	for _, option := range options {
		option(operation)
	}
	if !operation.withChart && !operation.withProv {
		return nil, errors.New(
			"must specify at least one layer to pull (chart/prov)")
	}
	store := content.NewMemoryStore()
	allowedMediaTypes := []string{
		ConfigMediaType,
	}
	minNumDescriptors := 1 // 1 for the config
	if operation.withChart {
		minNumDescriptors++
		allowedMediaTypes = append(allowedMediaTypes, ChartLayerMediaType)
	}
	if operation.withProv {
		if !operation.ignoreMissingProv {
			minNumDescriptors++
		}
		allowedMediaTypes = append(allowedMediaTypes, ProvLayerMediaType)
	}
	manifest, descriptors, err := oras.Pull(ctx(c.out, c.debug), c.resolver, ref, store,
		oras.WithPullEmptyNameAllowed(),
		oras.WithAllowedMediaTypes(allowedMediaTypes))
	if err != nil {
		return nil, err
	}
	numDescriptors := len(descriptors)
	if numDescriptors < minNumDescriptors {
		return nil, errors.New(
			fmt.Sprintf("manifest does not contain minimum number of descriptors (%d), descriptors found: %d",
				minNumDescriptors, numDescriptors))
	}
	var configDescriptor *ocispec.Descriptor
	var chartDescriptor *ocispec.Descriptor
	var provDescriptor *ocispec.Descriptor
	for _, descriptor := range descriptors {
		d := descriptor
		switch d.MediaType {
		case ConfigMediaType:
			configDescriptor = &d
		case ChartLayerMediaType:
			chartDescriptor = &d
		case ProvLayerMediaType:
			provDescriptor = &d
		}
	}
	if configDescriptor == nil {
		return nil, errors.New(
			fmt.Sprintf("could not load config with mediatype %s", ConfigMediaType))
	}
	if operation.withChart && chartDescriptor == nil {
		return nil, errors.New(
			fmt.Sprintf("manifest does not contain a layer with mediatype %s",
				ChartLayerMediaType))
	}
	var provMissing bool
	if operation.withProv && provDescriptor == nil {
		if operation.ignoreMissingProv {
			provMissing = true
		} else {
			return nil, errors.New(
				fmt.Sprintf("manifest does not contain a layer with mediatype %s",
					ProvLayerMediaType))
		}
	}
	result := &PullResult{
		Manifest: &descriptorPullSummary{
			Digest: manifest.Digest.String(),
			Size:   manifest.Size,
		},
		Config: &descriptorPullSummary{
			Digest: configDescriptor.Digest.String(),
			Size:   configDescriptor.Size,
		},
		Chart: &descriptorPullSummaryWithMeta{},
		Prov: &descriptorPullSummary{},
		Ref:  ref,
	}
	if _, manifestData, ok := store.Get(manifest); !ok {
		return nil, errors.Errorf("Unable to retrieve blob with digest %s", manifest.Digest)
	} else {
		result.Manifest.Data = manifestData
	}
	if _, configData, ok := store.Get(*configDescriptor); !ok {
		return nil, errors.Errorf("Unable to retrieve blob with digest %s", configDescriptor.Digest)
	} else {
		result.Config.Data = configData
		var meta *chart.Metadata
		if err := json.Unmarshal(configData, &meta); err != nil {
			return nil, err
		}
		result.Chart.Meta = meta
	}
	if operation.withChart {
		if _, chartData, ok := store.Get(*chartDescriptor); !ok {
			return nil, errors.Errorf("Unable to retrieve blob with digest %s", chartDescriptor.Digest)
		} else {
			result.Chart.Data = chartData
			result.Chart.Digest = chartDescriptor.Digest.String()
			result.Chart.Size = chartDescriptor.Size
		}
	}
	if operation.withProv && !provMissing {
		if _, provData, ok := store.Get(*provDescriptor); !ok {
			return nil, errors.Errorf("Unable to retrieve blob with digest %s", provDescriptor.Digest)
		} else {
			result.Prov.Data = provData
			result.Prov.Digest = provDescriptor.Digest.String()
			result.Prov.Size = provDescriptor.Size
		}
	}
	fmt.Fprintf(c.out, "Pulled: %s\n", result.Ref)
	fmt.Fprintf(c.out, "Digest: %s\n", result.Manifest.Digest)
	return result, nil
}
<commit_msg>resolve golint errors<commit_after>/*
Copyright The Helm Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package registry // import "helm.sh/helm/v3/internal/experimental/registry"

import (
	"encoding/json"
	"fmt"

	ocispec "github.com/opencontainers/image-spec/specs-go/v1"
	"github.com/pkg/errors"
	"oras.land/oras-go/pkg/content"
	"oras.land/oras-go/pkg/oras"

	"helm.sh/helm/v3/pkg/chart"
)

// Pull downloads a chart from a registry
func (c *Client) Pull(ref string, options ...PullOption) (*PullResult, error) {
	operation := &pullOperation{
		withChart: true, // By default, always download the chart layer
	}
	for _, option := range options {
		option(operation)
	}
	if !operation.withChart && !operation.withProv {
		return nil, errors.New(
			"must specify at least one layer to pull (chart/prov)")
	}
	store := content.NewMemoryStore()
	allowedMediaTypes := []string{
		ConfigMediaType,
	}
	minNumDescriptors := 1 // 1 for the config
	if operation.withChart {
		minNumDescriptors++
		allowedMediaTypes = append(allowedMediaTypes, ChartLayerMediaType)
	}
	if operation.withProv {
		if !operation.ignoreMissingProv {
			minNumDescriptors++
		}
		allowedMediaTypes = append(allowedMediaTypes, ProvLayerMediaType)
	}
	manifest, descriptors, err := oras.Pull(ctx(c.out, c.debug), c.resolver, ref, store,
		oras.WithPullEmptyNameAllowed(),
		oras.WithAllowedMediaTypes(allowedMediaTypes))
	if err != nil {
		return nil, err
	}
	numDescriptors := len(descriptors)
	if numDescriptors < minNumDescriptors {
		return nil, errors.New(
			fmt.Sprintf("manifest does not contain minimum number of descriptors (%d), descriptors found: %d",
				minNumDescriptors, numDescriptors))
	}
	var configDescriptor *ocispec.Descriptor
	var chartDescriptor *ocispec.Descriptor
	var provDescriptor *ocispec.Descriptor
	for _, descriptor := range descriptors {
		d := descriptor
		switch d.MediaType {
		case ConfigMediaType:
			configDescriptor = &d
		case ChartLayerMediaType:
			chartDescriptor = &d
		case ProvLayerMediaType:
			provDescriptor = &d
		}
	}
	if configDescriptor == nil {
		return nil, errors.New(
			fmt.Sprintf("could not load config with mediatype %s", ConfigMediaType))
	}
	if operation.withChart && chartDescriptor == nil {
		return nil, errors.New(
			fmt.Sprintf("manifest does not contain a layer with mediatype %s",
				ChartLayerMediaType))
	}
	var provMissing bool
	if operation.withProv && provDescriptor == nil {
		if operation.ignoreMissingProv {
			provMissing = true
		} else {
			return nil, errors.New(
				fmt.Sprintf("manifest does not contain a layer with mediatype %s",
					ProvLayerMediaType))
		}
	}
	result := &PullResult{
		Manifest: &descriptorPullSummary{
			Digest: manifest.Digest.String(),
			Size:   manifest.Size,
		},
		Config: &descriptorPullSummary{
			Digest: configDescriptor.Digest.String(),
			Size:   configDescriptor.Size,
		},
		Chart: &descriptorPullSummaryWithMeta{},
		Prov:  &descriptorPullSummary{},
		Ref:   ref,
	}
	var getManifestErr error
	if _, manifestData, ok := store.Get(manifest); !ok {
		getManifestErr = errors.Errorf("Unable to retrieve blob with digest %s", manifest.Digest)
	} else {
		result.Manifest.Data = manifestData
	}
	if getManifestErr != nil {
		return nil, getManifestErr
	}
	var getConfigDescriptorErr error
	if _, configData, ok := store.Get(*configDescriptor); !ok {
		getConfigDescriptorErr = errors.Errorf("Unable to retrieve blob with digest %s", configDescriptor.Digest)
	} else {
		result.Config.Data = configData
		var meta *chart.Metadata
		if err := json.Unmarshal(configData, &meta); err != nil {
			return nil, err
		}
		result.Chart.Meta = meta
	}
	if getConfigDescriptorErr != nil {
		return nil, getConfigDescriptorErr
	}
	if operation.withChart {
		var getChartDescriptorErr error
		if _, chartData, ok := store.Get(*chartDescriptor); !ok {
			getChartDescriptorErr = errors.Errorf("Unable to retrieve blob with digest %s", chartDescriptor.Digest)
		} else {
			result.Chart.Data = chartData
			result.Chart.Digest = chartDescriptor.Digest.String()
			result.Chart.Size = chartDescriptor.Size
		}
		if getChartDescriptorErr != nil {
			return nil, getChartDescriptorErr
		}
	}
	if operation.withProv && !provMissing {
		var getProvDescriptorErr error
		if _, provData, ok := store.Get(*provDescriptor); !ok {
			getProvDescriptorErr = errors.Errorf("Unable to retrieve blob with digest %s", provDescriptor.Digest)
		} else {
			result.Prov.Data = provData
			result.Prov.Digest = provDescriptor.Digest.String()
			result.Prov.Size = provDescriptor.Size
		}
		if getProvDescriptorErr != nil {
			return nil, getProvDescriptorErr
		}
	}
	fmt.Fprintf(c.out, "Pulled: %s\n", result.Ref)
	fmt.Fprintf(c.out, "Digest: %s\n", result.Manifest.Digest)
	return result, nil
}
<|endoftext|>


<commit_before>package ble

import (
	"github.com/paypal/gatt"
	"log"
	"sync"
	"time"
)

const (
	pwmService  = "000015231212efde1523785feabcd123"
	pwmLedChar  = "000015251212efde1523785feabcd123"
	pwmTempChar = "000015261212efde1523785feabcd123"
	pwmFanChar  = "000015241212efde1523785feabcd123"
)

type bleChannel struct {
	device           gatt.Device
	connectedPeriph  map[string]blePeriph
	knownPeriph      map[string]bool
	ignoredPeriph    map[string]bool
	connectingPeriph map[string]gatt.Peripheral
	idleTicker       *time.Ticker

	lock sync.Mutex
}

type blePeriph struct {
	gp       gatt.Peripheral
	ledChar  *gatt.Characteristic
	fanChar  *gatt.Characteristic
	tempChar *gatt.Characteristic

	temperature int
	fanRpm int
}

type BLEChannel interface {
}

var DefaultClientOptions = []gatt.Option{
	gatt.LnxMaxConnections(10),
	gatt.LnxDeviceID(-1, true),
}

func NewBLEChannel() BLEChannel {
	d, err := gatt.NewDevice(DefaultClientOptions...)
	if err != nil {
		log.Fatalf("Failed to open the bluetooth HCI device: %s\n", err)
		return nil
	}

	ble := &bleChannel{device: d,
		connectedPeriph:  make(map[string]blePeriph),
		knownPeriph:      make(map[string]bool),
		ignoredPeriph:    make(map[string]bool),
		connectingPeriph: make(map[string]gatt.Peripheral),
		idleTicker:       time.NewTicker(500 * time.Millisecond),
	}

	d.Handle(
		gatt.PeripheralDiscovered(ble.onPeriphDiscovered),
		gatt.PeripheralConnected(ble.onPeriphConnected),
		gatt.PeripheralDisconnected(ble.onPeriphDisconnected),
	)

	d.Init(ble.onStateChanged)

	go func() {
		var i = 0.0

		for _ = range ble.idleTicker.C {
			for _, p := range ble.connectedPeriph {
				i += 0.1
				ble.lock.Lock()
				for c := 0; c <= 8; c++ {
					value := int(i) % 0xe0
					err := p.gp.WriteCharacteristic(p.ledChar, []byte{byte(c), byte(value)}, true)
					if err != nil {
						log.Println(err)
					}

				}
				ble.lock.Unlock()
			}
		}
	}()

	return &bleChannel{device: d}
}

// Force Gatt to enter scanning mode
func (ble *bleChannel) onStateChanged(d gatt.Device, s gatt.State) {
	log.Println("State:", s)
	switch s {
	case gatt.StatePoweredOn:
		log.Println("Scanning...")
		d.Scan([]gatt.UUID{}, true)
		return
	default:
		log.Println("Stop scanning")
		d.StopScanning()
	}
}

func (ble *bleChannel) onPeriphConnected(p gatt.Peripheral, err error) {
	ble.lock.Lock()
	defer ble.lock.Unlock()

	log.Println("Connected ", p.ID())
	// Remove from the connecting pool
	delete(ble.connectingPeriph, p.ID())

	bp := blePeriph{gp: p}

	// Discovery services
	ss, err := p.DiscoverServices(nil)
	if err != nil {
		log.Printf("Failed to discover services, err: %s\n", err)
		return
	}

	for _, s := range ss {
		msg := "Service: " + s.UUID().String()
		if len(s.Name()) > 0 {
			msg += " (" + s.Name() + ")"
		}
		log.Println(msg)

		// Discovery characteristics
		cs, err := p.DiscoverCharacteristics(nil, s)
		if err != nil {
			log.Printf("Failed to discover characteristics, err: %s\n", err)
			return
		}

		for _, c := range cs {
			msg := "  Characteristic  " + c.UUID().String()

			// Grab and store the three characteristics we
			// case about by matching by UUID
			switch c.UUID().String() {
			case pwmLedChar:
				bp.ledChar = c
			case pwmTempChar:
				bp.tempChar = c
			case pwmFanChar:
				bp.fanChar = c
			}

			if len(c.Name()) > 0 {
				msg += " (" + c.Name() + ")"
			}
			msg += "\n    properties    " + c.Properties().String()
			log.Println(msg)

			// Read the characteristic, if possible.
			if (c.Properties() & gatt.CharRead) != 0 {
				b, err := p.ReadCharacteristic(c)
				if err != nil {
					log.Printf("Failed to read characteristic, err: %s\n", err)
					return
				}
				log.Printf("    value         %x | %q\n", b, b)
			}

			// Discovery descriptors
			ds, err := p.DiscoverDescriptors(nil, c)
			if err != nil {
				log.Printf("Failed to discover descriptors, err: %s\n", err)
				return
			}

			for _, d := range ds {
				msg := "  Descriptor      " + d.UUID().String()
				if len(d.Name()) > 0 {
					msg += " (" + d.Name() + ")"
				}
				log.Println(msg)

				// Read descriptor (could fail, if it's not readable)
				b, err := p.ReadDescriptor(d)
				if err != nil {
					log.Printf("Failed to read descriptor, err: %s\n", err)
					return
				}
				log.Printf("    value         %x | %q\n", b, b)
			}

			// Subscribe the characteristic, if possible.
			if (c.Properties() & (gatt.CharNotify | gatt.CharIndicate)) != 0 {
				f := func(c *gatt.Characteristic, b []byte, err error) {
					//log.Printf("%s: % X | %q\n", p.ID(), b, b)
					switch c.UUID().String() {
					case pwmTempChar:
						bp.temperature = int(b[0])
						log.Printf("%s: temperature: %d C", p.ID(), bp.temperature)
					case pwmFanChar:
						bp.fanRpm = int(b[0]) | (int(b[1]) << 8)
						log.Printf("%s: fan speed: %d rpm", p.ID(), bp.fanRpm)
					default:
						log.Printf("unknown notification from %s", p.ID())
					}
				}
				if err := p.SetNotifyValue(c, f); err != nil {
					log.Printf("Failed to subscribe characteristic, err: %s\n", err)
					return
				}
			}

		}
	}

	ble.connectedPeriph[p.ID()] = bp
}

func (ble *bleChannel) onPeriphDiscovered(p gatt.Peripheral, a *gatt.Advertisement, rssi int) {
	ble.lock.Lock()
	defer ble.lock.Unlock()

	if _, ok := ble.ignoredPeriph[p.ID()]; ok {
		return
	}

	log.Printf("Peripheral ID:%s, NAME:(%s)\n", p.ID(), p.Name())
	log.Println("  Local Name        =", a.LocalName)
	log.Println("  TX Power Level    =", a.TxPowerLevel)
	log.Println("  Manufacturer Data =", a.ManufacturerData)
	log.Println("  Service Data      =", a.ServiceData)
	log.Println("")

	if p.Name() != "LEDBrick-PWM" {
		ble.ignoredPeriph[p.ID()] = true
		log.Println("Ignoring this device.")
		return
	}

	ble.knownPeriph[p.ID()] = true
	if _, ok := ble.connectingPeriph[p.ID()]; ok {
		log.Printf("Peripheral is in connecting state: %s", p.ID())
	}

	log.Printf("Connecting to %s", p.ID())
	ble.connectingPeriph[p.ID()] = p
	go func() {
		time.Sleep(30 * time.Second)
		if _, ok := ble.connectedPeriph[p.ID()]; ok {
			return
		} else {
			delete(ble.connectingPeriph, p.ID())
			log.Printf("Haven't heard back about connection to  %s", p.ID())
		}
	}()
	p.Device().Connect(p)
}

func (ble *bleChannel) onPeriphDisconnected(p gatt.Peripheral, err error) {
	ble.lock.Lock()
	defer ble.lock.Unlock()

	log.Println("Disconnected ", p.ID())
	delete(ble.connectedPeriph, p.ID())
	p.Device().CancelConnection(p)
}
<commit_msg>Flesh out interfaces<commit_after>package ble

import (
	"errors"
	"github.com/paypal/gatt"
	"log"
	"sync"
	"time"
)

const (
	pwmService  = "000015231212efde1523785feabcd123"
	pwmLedChar  = "000015251212efde1523785feabcd123"
	pwmTempChar = "000015261212efde1523785feabcd123"
	pwmFanChar  = "000015241212efde1523785feabcd123"
)

var DefaultClientOptions = []gatt.Option{
	gatt.LnxMaxConnections(10),
	gatt.LnxDeviceID(-1, true),
}

type bleChannel struct {
	device           gatt.Device
	connectedPeriph  map[string]*blePeriph
	knownPeriph      map[string]bool
	ignoredPeriph    map[string]bool
	connectingPeriph map[string]gatt.Peripheral
	idleTicker       *time.Ticker

	channelSetting map[int]float64

	lock sync.Mutex
}

type blePeriph struct {
	active   bool
	gp       gatt.Peripheral
	ledChar  *gatt.Characteristic
	fanChar  *gatt.Characteristic
	tempChar *gatt.Characteristic

	temperature int
	fanRpm      int
}

type BLEPeripheral interface {
	Active() bool
	Temperature() int
	FanRPM() int
}

func (p *blePeriph) Active() bool     { return p.active }
func (p *blePeriph) Temperature() int { return p.temperature }
func (p *blePeriph) FanRPM() int      { return p.fanRpm }

type BLEChannel interface {
	Perhipherals() []BLEPeripheral
	SetChannel(channel int, percent float64) error
}

func NewBLEChannel() BLEChannel {
	d, err := gatt.NewDevice(DefaultClientOptions...)
	if err != nil {
		log.Fatalf("Failed to open the bluetooth HCI device: %s\n", err)
		return nil
	}

	ble := &bleChannel{device: d,
		connectedPeriph:  make(map[string]*blePeriph),
		knownPeriph:      make(map[string]bool),
		ignoredPeriph:    make(map[string]bool),
		connectingPeriph: make(map[string]gatt.Peripheral),
		idleTicker:       time.NewTicker(500 * time.Millisecond),
		channelSetting:   make(map[int]float64),
	}

	d.Handle(
		gatt.PeripheralDiscovered(ble.onPeriphDiscovered),
		gatt.PeripheralConnected(ble.onPeriphConnected),
		gatt.PeripheralDisconnected(ble.onPeriphDisconnected),
	)

	d.Init(ble.onStateChanged)

	go func() {
		var i = 0.0

		for _ = range ble.idleTicker.C {
			for _, p := range ble.connectedPeriph {
				i += 0.1
				ble.lock.Lock()
				for c := 0; c <= 8; c++ {
					value := int(i) % 0x80
					err := p.gp.WriteCharacteristic(p.ledChar, []byte{byte(c), byte(value)}, true)
					if err != nil {
						log.Println(err)
					}

				}
				ble.lock.Unlock()
			}
		}
	}()

	return &bleChannel{device: d}
}

func (ble *bleChannel) writeLedState() error {

	ble.lock.Lock()
	defer ble.lock.Unlock()

	for _, p := range ble.connectedPeriph {
		for channel := 0; channel <= 8; channel++ {
			// Max intensity limit is about 0xfa
			value := int((ble.channelSetting[channel] / 100.0) * 0xfa)
			err := p.gp.WriteCharacteristic(p.ledChar,
				[]byte{byte(channel), byte(value)}, true)
			if err != nil {
				log.Println("Command send error: %s", err)
				return err
			}
		}

	}
	return nil
}

func (ble *bleChannel) Perhipherals() []BLEPeripheral {
	p := make([]BLEPeripheral, 0)
	for _, periph := range ble.connectedPeriph {
		p = append(p, periph)
	}
	return p
}

func (ble *bleChannel) SetChannel(channel int, percent float64) error {
	if percent < 0 || percent > 100 {
		return errors.New("Out of range percent (0-100)")
	}
	ble.channelSetting[channel] = percent
	return ble.writeLedState()
}

// Force Gatt to enter scanning mode
func (ble *bleChannel) onStateChanged(d gatt.Device, s gatt.State) {
	log.Println("State:", s)
	switch s {
	case gatt.StatePoweredOn:
		log.Println("Scanning...")
		d.Scan([]gatt.UUID{}, true)
		return
	default:
		log.Println("Stop scanning")
		d.StopScanning()
	}
}

func (ble *bleChannel) onPeriphConnected(p gatt.Peripheral, err error) {

	log.Println("Connected, starting interrogation of ", p.ID())
	bp := blePeriph{gp: p,
		active: true}

	// Discovery services
	ss, err := p.DiscoverServices(nil)
	if err != nil {
		log.Printf("Failed to discover services, err: %s\n", err)
		return
	}

	for _, s := range ss {
		msg := "Service: " + s.UUID().String()
		if len(s.Name()) > 0 {
			msg += " (" + s.Name() + ")"
		}
		log.Println(msg)

		// Discovery characteristics
		cs, err := p.DiscoverCharacteristics(nil, s)
		if err != nil {
			log.Printf("Failed to discover characteristics, err: %s\n", err)
			return
		}

		for _, c := range cs {
			msg := "  Characteristic  " + c.UUID().String()

			// Grab and store the three characteristics we
			// case about by matching by UUID
			switch c.UUID().String() {
			case pwmLedChar:
				bp.ledChar = c
			case pwmTempChar:
				bp.tempChar = c
			case pwmFanChar:
				bp.fanChar = c
			}

			if len(c.Name()) > 0 {
				msg += " (" + c.Name() + ")"
			}
			msg += "\n    properties    " + c.Properties().String()
			log.Println(msg)

			// Read the characteristic, if possible.
			if (c.Properties() & gatt.CharRead) != 0 {
				b, err := p.ReadCharacteristic(c)
				if err != nil {
					log.Printf("Failed to read characteristic, err: %s\n", err)
					return
				}
				log.Printf("    value         %x | %q\n", b, b)
			}

			// Discovery descriptors
			ds, err := p.DiscoverDescriptors(nil, c)
			if err != nil {
				log.Printf("Failed to discover descriptors, err: %s\n", err)
				return
			}

			for _, d := range ds {
				msg := "  Descriptor      " + d.UUID().String()
				if len(d.Name()) > 0 {
					msg += " (" + d.Name() + ")"
				}
				log.Println(msg)

				// Read descriptor (could fail, if it's not readable)
				b, err := p.ReadDescriptor(d)
				if err != nil {
					log.Printf("Failed to read descriptor, err: %s\n", err)
					return
				}
				log.Printf("    value         %x | %q\n", b, b)
			}

			// Subscribe the characteristic, if possible.
			if (c.Properties() & (gatt.CharNotify | gatt.CharIndicate)) != 0 {
				f := func(c *gatt.Characteristic, b []byte, err error) {
					//log.Printf("%s: % X | %q\n", p.ID(), b, b)
					switch c.UUID().String() {
					case pwmTempChar:
						bp.temperature = int(b[0])
						log.Printf("%s: temperature: %d C", p.ID(), bp.temperature)
					case pwmFanChar:
						bp.fanRpm = int(b[0]) | (int(b[1]) << 8)
						log.Printf("%s: fan speed: %d rpm", p.ID(), bp.fanRpm)
					default:
						log.Printf("unknown notification from %s", p.ID())
					}
				}
				if err := p.SetNotifyValue(c, f); err != nil {
					log.Printf("Failed to subscribe characteristic, err: %s\n", err)
					return
				}
			}

		}
	}

	ble.lock.Lock()
	defer ble.lock.Unlock()

	// Remove from the connecting pool
	delete(ble.connectingPeriph, p.ID())

	ble.connectedPeriph[p.ID()] = &bp
	log.Printf("Peripheral connection conomplete: %s", p.ID())
}

func (ble *bleChannel) onPeriphDiscovered(p gatt.Peripheral, a *gatt.Advertisement, rssi int) {
	ble.lock.Lock()
	defer ble.lock.Unlock()

	if _, ok := ble.ignoredPeriph[p.ID()]; ok {
		return
	}

	log.Printf("Peripheral ID:%s, NAME:(%s)\n", p.ID(), p.Name())
	log.Println("  Local Name        =", a.LocalName)
	log.Println("  TX Power Level    =", a.TxPowerLevel)
	log.Println("  Manufacturer Data =", a.ManufacturerData)
	log.Println("  Service Data      =", a.ServiceData)
	log.Println("")

	if p.Name() != "LEDBrick-PWM" {
		ble.ignoredPeriph[p.ID()] = true
		log.Println("Ignoring this device.")
		return
	}

	ble.knownPeriph[p.ID()] = true
	if _, ok := ble.connectingPeriph[p.ID()]; ok {
		log.Printf("Peripheral is in connecting state: %s", p.ID())
		return
	}

	log.Printf("Connecting to %s", p.ID())
	ble.connectingPeriph[p.ID()] = p
	go func() {
		time.Sleep(30 * time.Second)
		if _, ok := ble.connectedPeriph[p.ID()]; ok {
			return
		} else {
			delete(ble.connectingPeriph, p.ID())
			log.Printf("Haven't heard back about connection to %s, removing from pending pool", p.ID())
		}
	}()
	p.Device().Connect(p)
}

func (ble *bleChannel) onPeriphDisconnected(p gatt.Peripheral, err error) {
	ble.lock.Lock()
	defer ble.lock.Unlock()

	log.Println("Disconnected ", p.ID())

	localPeriph := ble.connectedPeriph[p.ID()]
	// If the API has given an active handle to this peripheral out,
	// we need to be able to flag it as no longer active. A simple
	// boolean suffices.
	localPeriph.active = false

	delete(ble.connectedPeriph, p.ID())
	// We re-cancel the connection here, which will free any associated
	// channels if this disconnect is due to the peripheral initiating the disconnect
	p.Device().CancelConnection(p)
}
<|endoftext|>


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

// Package linkedin provides constants for using OAuth2 to access LinkedIn.
package linkedin // import "golang.org/x/oauth2/linkedin"

import (
	"golang.org/x/oauth2"
)

// Endpoint is LinkedIn's OAuth 2.0 endpoint.
var Endpoint = oauth2.Endpoint{
	AuthURL:  "https://www.linkedin.com/uas/oauth2/authorization",
	TokenURL: "https://www.linkedin.com/uas/oauth2/accessToken",
}
<commit_msg>linkedin: Update to new endpoint<commit_after>// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package linkedin provides constants for using OAuth2 to access LinkedIn.
package linkedin // import "golang.org/x/oauth2/linkedin"

import (
	"golang.org/x/oauth2"
)

// Endpoint is LinkedIn's OAuth 2.0 endpoint.
var Endpoint = oauth2.Endpoint{
	AuthURL:  "https://www.linkedin.com/oauth/v2/authorization",
	TokenURL: "https://www.linkedin.com/oauth/v2/accessToken",
}
<|endoftext|>


<commit_before>/*
http://www.apache.org/licenses/LICENSE-2.0.txt

Copyright 2015 Intel Corporation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package movingaverage

import (
	"bytes"
	"encoding/gob"
	"errors"

	log "github.com/Sirupsen/logrus"

	"github.com/intelsdi-x/pulse/control/plugin"
	"github.com/intelsdi-x/pulse/control/plugin/cpolicy"
	"github.com/intelsdi-x/pulse/core/ctypes"
)

const (
	name       = "movingaverage"
	version    = 2
	pluginType = plugin.ProcessorPluginType
)

// Meta returns a plugin meta data
func Meta() *plugin.PluginMeta {
	return plugin.NewPluginMeta(name, version, pluginType, []string{plugin.PulseGOBContentType}, []string{plugin.PulseGOBContentType})
}

func NewMovingaverageProcessor() *movingAverageProcessor {
	a := make(map[string]*average)
	return &movingAverageProcessor{
		movingAverageMap: a,
		movingBufLength:  10,
	}
}

//The default buffer length is assumed to be 10

func newmovingAverage(length int) *average {
	initCounter := 0
	return &average{
		movingAverageBuf: make([]interface{}, length),
		counter:          initCounter,
	}
}

//movingAverageProcessor is a struct which has a map that acts like a buffer for storage of values for different namespace
// key is a namespace (type: string)
//value is a pointer average struct which stores values of the namespace key
type movingAverageProcessor struct {
	movingAverageMap map[string]*average
	movingBufLength  int
}

//Each Namespace would have its own buffer-length and counter . Counter is used for the purpose of
//replacing the oldest (when buffer is full) with the new value using mod operation
type average struct {
	movingAverageBuf []interface{}
	counter          int
}

//Gets the current counter for the particular namespace
func (p *movingAverageProcessor) getCounter(namespace string) (int, error) {
	if _, ok := p.movingAverageMap[namespace]; ok {
		return p.movingAverageMap[namespace].counter, nil
	} else {
		return -1, errors.New("Namespace is not present in the map")
	}
}

//Sets the counter for the particular namespace
func (p *movingAverageProcessor) setCounter(namespace string, counter int) error {
	if _, ok := p.movingAverageMap[namespace]; ok {
		p.movingAverageMap[namespace].counter = counter
		return nil
	} else {
		return errors.New("Namespace is not present in the map")
	}
}

func (p *movingAverageProcessor) getBufferLength() int {
	return p.movingBufLength
}

func (p *movingAverageProcessor) setBufferLength(length int) error {
	p.movingBufLength = length
	return nil
}

//Adds data in the buffer for a particular namespace
func (p *movingAverageProcessor) addBufferData(index int, data interface{}, namespace string) error {

	if _, ok := p.movingAverageMap[namespace]; ok {
		counter, _ := p.getCounter(namespace)
		p.movingAverageMap[namespace].movingAverageBuf[counter] = data
		return nil
	} else {
		return errors.New("Namespace is not present in the map")
	}
}

//Retrieves the buffer data for a particular namespace
func (p *movingAverageProcessor) getBufferData(index int, namespace string) interface{} {

	return p.movingAverageMap[namespace].movingAverageBuf[index]
}

//Since namespace is an array of string. Its required to concatenate to make it a primary unique key
func concatNameSpace(namespace []string) string {
	completeNamespace := ""
	for i := 0; i < len(namespace); i++ {
		completeNamespace += namespace[i]
	}
	return completeNamespace
}

func (p *movingAverageProcessor) calculateMovingAverage(m plugin.PluginMetricType, logger *log.Logger) (float64, error) {

	namespace := concatNameSpace(m.Namespace())
	switch v := m.Data().(type) {
	default:
		logger.Printf("Unknown data received: Type %T", v)
		return 0.0, errors.New("Unknown data received: Type")
	case int:
		if _, ok := p.movingAverageMap[namespace]; ok {
			counter, err := p.getCounter(namespace)
			counterCurrent := counter % p.movingBufLength
			p.addBufferData(counterCurrent, m.Data(), namespace)
			sum := int(0)
			//Initial Counter is used to give correct average for initial iterations ie when the buffer is not full
			initialCounter := 0
			for i := 0; i < p.movingBufLength; i++ {
				if p.getBufferData(i, namespace) != nil {
					initialCounter++
					sum += p.getBufferData(i, namespace).(int)
				}
			}
			movingAvg := float64(sum) / float64(initialCounter)
			counterCurrent++
			p.setCounter(namespace, counterCurrent)
			return movingAvg, err

		} else {

			//Since map doesnot have an entry of this namespace, its creating an entry for the namespace.
			//Also m.data value is inserted into 0th position of the buffer because we know that this buffer is being used for the first time
			p.movingAverageMap[namespace] = newmovingAverage(p.getBufferLength())
			p.addBufferData(0, m.Data(), namespace)
			sum := p.getBufferData(0, namespace).(int)
			p.setCounter(namespace, 1)
			return float64(sum), nil
		}

	case float64:

		if _, ok := p.movingAverageMap[namespace]; ok {
			counter, err := p.getCounter(namespace)
			counterCurrent := counter % p.movingBufLength
			p.addBufferData(counterCurrent, m.Data(), namespace)
			sum := float64(0)
			initialCounter := 0
			for i := 0; i < p.movingBufLength; i++ {
				if p.getBufferData(i, namespace) != nil {
					initialCounter++
					sum += p.getBufferData(i, namespace).(float64)
				}
			}
			movingAvg := float64(sum) / float64(initialCounter)
			counterCurrent++
			p.setCounter(namespace, counterCurrent)
			return movingAvg, err

		} else {
			p.movingAverageMap[namespace] = newmovingAverage(p.getBufferLength())
			p.addBufferData(0, m.Data(), namespace)
			sum := p.getBufferData(0, namespace).(float64)
			p.setCounter(namespace, 1)
			return float64(sum), nil
		}

	case float32:
		if _, ok := p.movingAverageMap[namespace]; ok {
			counter, err := p.getCounter(namespace)
			counterCurrent := counter % p.movingBufLength
			p.addBufferData(counterCurrent, m.Data(), namespace)
			sum := float32(0)

			initialCounter := 0
			for i := 0; i < p.movingBufLength; i++ {
				if p.getBufferData(i, namespace) != nil {
					initialCounter++
					sum += p.getBufferData(i, namespace).(float32)
				}
			}
			movingAvg := float64(sum) / float64(initialCounter)
			p.setCounter(namespace, counterCurrent)
			return movingAvg, err

		} else {
			p.movingAverageMap[namespace] = newmovingAverage(p.getBufferLength())
			p.addBufferData(0, m.Data(), namespace)
			sum := p.getBufferData(0, namespace).(float32)
			p.setCounter(namespace, 1)
			return float64(sum), nil
		}

	case uint32:
		if _, ok := p.movingAverageMap[namespace]; ok {
			counter, err := p.getCounter(namespace)
			counterCurrent := counter % p.movingBufLength
			p.addBufferData(counterCurrent, m.Data(), namespace)
			sum := uint32(0)
			initialCounter := 0
			for i := 0; i < p.movingBufLength; i++ {
				if p.getBufferData(i, namespace) != nil {
					initialCounter++
					sum += p.getBufferData(i, namespace).(uint32)
				}
			}
			movingAvg := float64(sum) / float64(initialCounter)
			counterCurrent++
			p.setCounter(namespace, counterCurrent)
			return movingAvg, err

		} else {
			p.movingAverageMap[namespace] = newmovingAverage(p.getBufferLength())
			p.addBufferData(0, m.Data(), namespace)
			sum := p.getBufferData(0, namespace).(uint32)
			p.setCounter(namespace, 1)
			return float64(sum), nil
		}

	case uint64:
		if _, ok := p.movingAverageMap[namespace]; ok {
			counter, err := p.getCounter(namespace)
			counterCurrent := counter % p.movingBufLength
			p.addBufferData(counterCurrent, m.Data(), namespace)
			sum := uint64(0)
			initialCounter := 0
			for i := 0; i < p.movingBufLength; i++ {
				if p.getBufferData(i, namespace) != nil {
					initialCounter++
					sum += p.getBufferData(i, namespace).(uint64)
				}
			}
			movingAvg := float64(sum) / float64(initialCounter)
			counterCurrent++
			p.setCounter(namespace, counterCurrent)
			return movingAvg, err

		} else {
			p.movingAverageMap[namespace] = newmovingAverage(p.getBufferLength())
			p.addBufferData(0, m.Data(), namespace)
			sum := p.getBufferData(0, namespace).(uint64)
			p.setCounter(namespace, 1)
			return float64(sum), nil
		}

	}
}
func handleErr(e error) {
	if e != nil {
		panic(e)
	}
}

func (p *movingAverageProcessor) GetConfigPolicy() (*cpolicy.ConfigPolicy, error) {
	cp := cpolicy.New()
	config := cpolicy.NewPolicyNode()
	r1, err := cpolicy.NewIntegerRule("MovingAvgBufLength", true)
	handleErr(err)
	r1.Description = "Buffer Length for moving average "
	config.Add(r1)
	cp.Add([]string{""}, config)
	return cp, nil
}

func (p *movingAverageProcessor) Process(contentType string, content []byte, config map[string]ctypes.ConfigValue) (string, []byte, error) {
	logger := log.New()
	logger.Println("movingAverage Processor started")

	var metrics []plugin.PluginMetricType
	//if the MovingAvgBufLength is set to number less than or equal to 0 then the MovingAvgBufferLength is set to 10
	if config != nil {
		if config["MovingAvgBufLength"].(ctypes.ConfigValueInt).Value > 0 {
			p.setBufferLength(config["MovingAvgBufLength"].(ctypes.ConfigValueInt).Value)

		} else {
			p.setBufferLength(10)
		}

	} else {
		p.setBufferLength(10)
	}

	//Decodes the content into pluginMetricType
	dec := gob.NewDecoder(bytes.NewBuffer(content))
	if err := dec.Decode(&metrics); err != nil {
		logger.Printf("Error decoding: error=%v content=%v", err, content)
		return "", nil, err
	}

	for i, m := range metrics {
		//Determining the type of data
		logger.Printf("Data received %v", metrics[i].Data())

		metrics[i].Data_, _ = p.calculateMovingAverage(m, logger)
		logger.Printf("Moving Average %v", metrics[i].Data())

	}
	var buf bytes.Buffer
	enc := gob.NewEncoder(&buf)
	enc.Encode(metrics)
	return contentType, buf.Bytes(), nil
}
<commit_msg>Update version to 3<commit_after>/*
http://www.apache.org/licenses/LICENSE-2.0.txt

Copyright 2015 Intel Corporation

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

	http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package movingaverage

import (
	"bytes"
	"encoding/gob"
	"errors"

	log "github.com/Sirupsen/logrus"

	"github.com/intelsdi-x/pulse/control/plugin"
	"github.com/intelsdi-x/pulse/control/plugin/cpolicy"
	"github.com/intelsdi-x/pulse/core/ctypes"
)

const (
	name       = "movingaverage"
	version    = 3
	pluginType = plugin.ProcessorPluginType
)

// Meta returns a plugin meta data
func Meta() *plugin.PluginMeta {
	return plugin.NewPluginMeta(name, version, pluginType, []string{plugin.PulseGOBContentType}, []string{plugin.PulseGOBContentType})
}

func NewMovingaverageProcessor() *movingAverageProcessor {
	a := make(map[string]*average)
	return &movingAverageProcessor{
		movingAverageMap: a,
		movingBufLength:  10,
	}
}

//The default buffer length is assumed to be 10

func newmovingAverage(length int) *average {
	initCounter := 0
	return &average{
		movingAverageBuf: make([]interface{}, length),
		counter:          initCounter,
	}
}

//movingAverageProcessor is a struct which has a map that acts like a buffer for storage of values for different namespace
// key is a namespace (type: string)
//value is a pointer average struct which stores values of the namespace key
type movingAverageProcessor struct {
	movingAverageMap map[string]*average
	movingBufLength  int
}

//Each Namespace would have its own buffer-length and counter . Counter is used for the purpose of
//replacing the oldest (when buffer is full) with the new value using mod operation
type average struct {
	movingAverageBuf []interface{}
	counter          int
}

//Gets the current counter for the particular namespace
func (p *movingAverageProcessor) getCounter(namespace string) (int, error) {
	if _, ok := p.movingAverageMap[namespace]; ok {
		return p.movingAverageMap[namespace].counter, nil
	} else {
		return -1, errors.New("Namespace is not present in the map")
	}
}

//Sets the counter for the particular namespace
func (p *movingAverageProcessor) setCounter(namespace string, counter int) error {
	if _, ok := p.movingAverageMap[namespace]; ok {
		p.movingAverageMap[namespace].counter = counter
		return nil
	} else {
		return errors.New("Namespace is not present in the map")
	}
}

func (p *movingAverageProcessor) getBufferLength() int {
	return p.movingBufLength
}

func (p *movingAverageProcessor) setBufferLength(length int) error {
	p.movingBufLength = length
	return nil
}

//Adds data in the buffer for a particular namespace
func (p *movingAverageProcessor) addBufferData(index int, data interface{}, namespace string) error {

	if _, ok := p.movingAverageMap[namespace]; ok {
		counter, _ := p.getCounter(namespace)
		p.movingAverageMap[namespace].movingAverageBuf[counter] = data
		return nil
	} else {
		return errors.New("Namespace is not present in the map")
	}
}

//Retrieves the buffer data for a particular namespace
func (p *movingAverageProcessor) getBufferData(index int, namespace string) interface{} {

	return p.movingAverageMap[namespace].movingAverageBuf[index]
}

//Since namespace is an array of string. Its required to concatenate to make it a primary unique key
func concatNameSpace(namespace []string) string {
	completeNamespace := ""
	for i := 0; i < len(namespace); i++ {
		completeNamespace += namespace[i]
	}
	return completeNamespace
}

func (p *movingAverageProcessor) calculateMovingAverage(m plugin.PluginMetricType, logger *log.Logger) (float64, error) {

	namespace := concatNameSpace(m.Namespace())
	switch v := m.Data().(type) {
	default:
		logger.Printf("Unknown data received: Type %T", v)
		return 0.0, errors.New("Unknown data received: Type")
	case int:
		if _, ok := p.movingAverageMap[namespace]; ok {
			counter, err := p.getCounter(namespace)
			counterCurrent := counter % p.movingBufLength
			p.addBufferData(counterCurrent, m.Data(), namespace)
			sum := int(0)
			//Initial Counter is used to give correct average for initial iterations ie when the buffer is not full
			initialCounter := 0
			for i := 0; i < p.movingBufLength; i++ {
				if p.getBufferData(i, namespace) != nil {
					initialCounter++
					sum += p.getBufferData(i, namespace).(int)
				}
			}
			movingAvg := float64(sum) / float64(initialCounter)
			counterCurrent++
			p.setCounter(namespace, counterCurrent)
			return movingAvg, err

		} else {

			//Since map doesnot have an entry of this namespace, its creating an entry for the namespace.
			//Also m.data value is inserted into 0th position of the buffer because we know that this buffer is being used for the first time
			p.movingAverageMap[namespace] = newmovingAverage(p.getBufferLength())
			p.addBufferData(0, m.Data(), namespace)
			sum := p.getBufferData(0, namespace).(int)
			p.setCounter(namespace, 1)
			return float64(sum), nil
		}

	case float64:

		if _, ok := p.movingAverageMap[namespace]; ok {
			counter, err := p.getCounter(namespace)
			counterCurrent := counter % p.movingBufLength
			p.addBufferData(counterCurrent, m.Data(), namespace)
			sum := float64(0)
			initialCounter := 0
			for i := 0; i < p.movingBufLength; i++ {
				if p.getBufferData(i, namespace) != nil {
					initialCounter++
					sum += p.getBufferData(i, namespace).(float64)
				}
			}
			movingAvg := float64(sum) / float64(initialCounter)
			counterCurrent++
			p.setCounter(namespace, counterCurrent)
			return movingAvg, err

		} else {
			p.movingAverageMap[namespace] = newmovingAverage(p.getBufferLength())
			p.addBufferData(0, m.Data(), namespace)
			sum := p.getBufferData(0, namespace).(float64)
			p.setCounter(namespace, 1)
			return float64(sum), nil
		}

	case float32:
		if _, ok := p.movingAverageMap[namespace]; ok {
			counter, err := p.getCounter(namespace)
			counterCurrent := counter % p.movingBufLength
			p.addBufferData(counterCurrent, m.Data(), namespace)
			sum := float32(0)

			initialCounter := 0
			for i := 0; i < p.movingBufLength; i++ {
				if p.getBufferData(i, namespace) != nil {
					initialCounter++
					sum += p.getBufferData(i, namespace).(float32)
				}
			}
			movingAvg := float64(sum) / float64(initialCounter)
			p.setCounter(namespace, counterCurrent)
			return movingAvg, err

		} else {
			p.movingAverageMap[namespace] = newmovingAverage(p.getBufferLength())
			p.addBufferData(0, m.Data(), namespace)
			sum := p.getBufferData(0, namespace).(float32)
			p.setCounter(namespace, 1)
			return float64(sum), nil
		}

	case uint32:
		if _, ok := p.movingAverageMap[namespace]; ok {
			counter, err := p.getCounter(namespace)
			counterCurrent := counter % p.movingBufLength
			p.addBufferData(counterCurrent, m.Data(), namespace)
			sum := uint32(0)
			initialCounter := 0
			for i := 0; i < p.movingBufLength; i++ {
				if p.getBufferData(i, namespace) != nil {
					initialCounter++
					sum += p.getBufferData(i, namespace).(uint32)
				}
			}
			movingAvg := float64(sum) / float64(initialCounter)
			counterCurrent++
			p.setCounter(namespace, counterCurrent)
			return movingAvg, err

		} else {
			p.movingAverageMap[namespace] = newmovingAverage(p.getBufferLength())
			p.addBufferData(0, m.Data(), namespace)
			sum := p.getBufferData(0, namespace).(uint32)
			p.setCounter(namespace, 1)
			return float64(sum), nil
		}

	case uint64:
		if _, ok := p.movingAverageMap[namespace]; ok {
			counter, err := p.getCounter(namespace)
			counterCurrent := counter % p.movingBufLength
			p.addBufferData(counterCurrent, m.Data(), namespace)
			sum := uint64(0)
			initialCounter := 0
			for i := 0; i < p.movingBufLength; i++ {
				if p.getBufferData(i, namespace) != nil {
					initialCounter++
					sum += p.getBufferData(i, namespace).(uint64)
				}
			}
			movingAvg := float64(sum) / float64(initialCounter)
			counterCurrent++
			p.setCounter(namespace, counterCurrent)
			return movingAvg, err

		} else {
			p.movingAverageMap[namespace] = newmovingAverage(p.getBufferLength())
			p.addBufferData(0, m.Data(), namespace)
			sum := p.getBufferData(0, namespace).(uint64)
			p.setCounter(namespace, 1)
			return float64(sum), nil
		}

	}
}
func handleErr(e error) {
	if e != nil {
		panic(e)
	}
}

func (p *movingAverageProcessor) GetConfigPolicy() (*cpolicy.ConfigPolicy, error) {
	cp := cpolicy.New()
	config := cpolicy.NewPolicyNode()
	r1, err := cpolicy.NewIntegerRule("MovingAvgBufLength", true)
	handleErr(err)
	r1.Description = "Buffer Length for moving average "
	config.Add(r1)
	cp.Add([]string{""}, config)
	return cp, nil
}

func (p *movingAverageProcessor) Process(contentType string, content []byte, config map[string]ctypes.ConfigValue) (string, []byte, error) {
	logger := log.New()
	logger.Println("movingAverage Processor started")

	var metrics []plugin.PluginMetricType
	//if the MovingAvgBufLength is set to number less than or equal to 0 then the MovingAvgBufferLength is set to 10
	if config != nil {
		if config["MovingAvgBufLength"].(ctypes.ConfigValueInt).Value > 0 {
			p.setBufferLength(config["MovingAvgBufLength"].(ctypes.ConfigValueInt).Value)

		} else {
			p.setBufferLength(10)
		}

	} else {
		p.setBufferLength(10)
	}

	//Decodes the content into pluginMetricType
	dec := gob.NewDecoder(bytes.NewBuffer(content))
	if err := dec.Decode(&metrics); err != nil {
		logger.Printf("Error decoding: error=%v content=%v", err, content)
		return "", nil, err
	}

	for i, m := range metrics {
		//Determining the type of data
		logger.Printf("Data received %v", metrics[i].Data())

		metrics[i].Data_, _ = p.calculateMovingAverage(m, logger)
		logger.Printf("Moving Average %v", metrics[i].Data())

	}
	var buf bytes.Buffer
	enc := gob.NewEncoder(&buf)
	enc.Encode(metrics)
	return contentType, buf.Bytes(), nil
}
<|endoftext|>


<commit_before>/*
Package uinput is a pure go package that provides access to the userland input device driver uinput on linux systems.
Virtual keyboard devices as well as virtual mouse input devices may be created using this package.
The keycodes and other event definitions, that are available and can be used to trigger input events,
are part of this package ("Key1" for number 1, for example).

In order to use the virtual keyboard, you will need to follow these three steps:

	1. Initialize the device
		Example: vk, err := CreateKeyboard("/dev/uinput", "Virtual Keyboard")

	2. Send Button events to the device
		Example (print a single D):
			err = vk.KeyPress(uinput.KeyD)

		Example (keep moving right by holding down right arrow key):
				 err = vk.KeyDown(uinput.KeyRight)

		Example (stop moving right by releasing the right arrow key):
				 err = vk.KeyUp(uinput.KeyRight)

	3. Close the device
		Example: err = vk.Close()

A virtual mouse input device is just as easy to create and use:

	1. Initialize the device:
		Example: vm, err := CreateMouse("/dev/uinput", "DangerMouse")

	2. Move the cursor around and issue click events
		Example (move mouse right):
			err = vm.MoveRight(42)

		Example (move mouse left):
			err = vm.MoveLeft(42)

		Example (move mouse up):
			err = vm.MoveUp(42)

		Example (move mouse down):
			err = vm.MoveDown(42)

		Example (trigger a left click):
			err = vm.LeftClick()

		Example (trigger a right click):
			err = vm.RightClick()

	3. Close the device
		Example: err = vm.Close()

If you'd like to use absolute input events (move the cursor to specific positions on screen), use the touch pad.
Note that you'll need to specify the size of the screen area you want to use when you initialize the
device. Here are a few examples of how to use the virtual touch pad:

	1. Initialize the device:
		Example: vt, err := CreateTouchPad("/dev/uinput", "DontTouchThis", 0, 1024, 0, 768)

	2. Move the cursor around and issue click events
		Example (move cursor to the top left corner of the screen):
			err = vt.MoveTo(0, 0)

		Example (move cursor to the position x: 100, y: 250):
			err = vt.MoveTo(100, 250)

		Example (trigger a left click):
			err = vt.LeftClick()

		Example (trigger a right click):
			err = vt.RightClick()

	3. Close the device
		Example: err = vt.Close()

*/
package uinput

import (
	"errors"
	"fmt"
	"io"
	"os"
)

// A Keyboard is an key event output device. It is used to
// enable a program to simulate HID keyboard input events.
type Keyboard interface {
	// KeyPress will cause the key to be pressed and immediately released.
	KeyPress(key int) error

	// KeyDown will send a keypress event to an existing keyboard device.
	// The key can be any of the predefined keycodes from uinputdefs.
	// Note that the key will be "held down" until "KeyUp" is called.
	KeyDown(key int) error

	// KeyUp will send a keyrelease event to an existing keyboard device.
	// The key can be any of the predefined keycodes from uinputdefs.
	KeyUp(key int) error

	io.Closer
}

type vKeyboard struct {
	name       []byte
	deviceFile *os.File
}

// A Mouse is a device that will trigger an absolute change event.
// For details see: https://www.kernel.org/doc/Documentation/input/event-codes.txt
type Mouse interface {
	// MoveLeft will move the mouse cursor left by the given number of pixel.
	MoveLeft(pixel int32) error

	// MoveRight will move the mouse cursor right by the given number of pixel.
	MoveRight(pixel int32) error

	// MoveUp will move the mouse cursor up by the given number of pixel.
	MoveUp(pixel int32) error

	// MoveDown will move the mouse cursor down by the given number of pixel.
	MoveDown(pixel int32) error

	// LeftClick will issue a single left click.
	LeftClick() error

	// RightClick will issue a right click.
	RightClick() error

	io.Closer
}

type vMouse struct {
	name       []byte
	deviceFile *os.File
}

// A TouchPad is an input device that uses absolute axis events, meaning that you can specify
// the exact position the cursor should move to. Therefore, it is necessary to define the size
// of the rectangle in which the cursor may move upon creation of the device.
type TouchPad interface {
	// MoveTo will move the cursor to the specified position on the screen
	MoveTo(x int32, y int32) error

	// LeftClick will issue a single left click.
	LeftClick() error

	// RightClick will issue a right click.
	RightClick() error

	io.Closer
}

type vTouchPad struct {
	name       []byte
	deviceFile *os.File
}

// CreateTouchPad will create a new touch pad device. note that you will need to define the x and y axis boundaries
// (min and max) within which the cursor maybe moved around.
func CreateTouchPad(path string, name []byte, minX int32, maxX int32, minY int32, maxY int32) (TouchPad, error) {
	if path == "" {
		return nil, errors.New("device path must not be empty")
	}
	if len(name) > uinputMaxNameSize {
		return nil, fmt.Errorf("device name %s is too long (maximum of %d characters allowed)", name, uinputMaxNameSize)
	}

	fd, err := createTouchPad(path, name, minX, maxX, minY, maxY)
	if err != nil {
		return nil, err
	}

	return vTouchPad{name: name, deviceFile: fd}, nil
}

func (vTouch vTouchPad) MoveTo(x int32, y int32) error {
	return sendAbsEvent(vTouch.deviceFile, x, y)
}

func (vTouch vTouchPad) LeftClick() error {
	err := sendBtnEvent(vTouch.deviceFile, evBtnLeft, btnStatePressed)
	if err != nil {
		return fmt.Errorf("Failed to issue the LeftClick event: %v", err)
	}

	err = sendBtnEvent(vTouch.deviceFile, evBtnLeft, btnStateReleased)
	if err != nil {
		return fmt.Errorf("Failed to issue the KeyUp event: %v", err)
	}

	err = syncEvents(vTouch.deviceFile)
	if err != nil {
		return fmt.Errorf("sync to device file failed: %v", err)
	}
	return nil
}

func (vTouch vTouchPad) RightClick() error {
	err := sendBtnEvent(vTouch.deviceFile, evBtnRight, btnStatePressed)
	if err != nil {
		return fmt.Errorf("Failed to issue the RightClick event: %v", err)
	}

	err = sendBtnEvent(vTouch.deviceFile, evBtnRight, btnStateReleased)
	if err != nil {
		return fmt.Errorf("Failed to issue the KeyUp event: %v", err)
	}

	err = syncEvents(vTouch.deviceFile)
	if err != nil {
		return fmt.Errorf("sync to device file failed: %v", err)
	}
	return nil
}

func (vTouch vTouchPad) Close() error {
	return closeDevice(vTouch.deviceFile)
}

// CreateMouse will create a new mouse input device. A mouse is a device that allows relative input.
// Relative input means that all changes to the x and y coordinates of the mouse pointer will be
func CreateMouse(path string, name []byte) (Mouse, error) {
	if path == "" {
		return nil, errors.New("device path must not be empty")
	}
	if len(name) > uinputMaxNameSize {
		return nil, fmt.Errorf("device name %s is too long (maximum of %d characters allowed)", name, uinputMaxNameSize)
	}

	fd, err := createMouse(path, name)
	if err != nil {
		return nil, err
	}

	return vMouse{name: name, deviceFile: fd}, nil
}

// MoveLeft will move the cursor left by the number of pixel specified.
func (vRel vMouse) MoveLeft(pixel int32) error {
	return sendRelEvent(vRel.deviceFile, relX, -pixel)
}

// MoveRight will move the cursor right by the number of pixel specified.
func (vRel vMouse) MoveRight(pixel int32) error {
	return sendRelEvent(vRel.deviceFile, relX, pixel)
}

// MoveUp will move the cursor up by the number of pixel specified.
func (vRel vMouse) MoveUp(pixel int32) error {
	return sendRelEvent(vRel.deviceFile, relY, -pixel)
}

// MoveDown will move the cursor down by the number of pixel specified.
func (vRel vMouse) MoveDown(pixel int32) error {
	return sendRelEvent(vRel.deviceFile, relY, pixel)
}

// LeftClick will issue a LeftClick.
func (vRel vMouse) LeftClick() error {
	err := sendBtnEvent(vRel.deviceFile, evBtnLeft, btnStatePressed)
	if err != nil {
		return fmt.Errorf("Failed to issue the LeftClick event: %v", err)
	}

	err = sendBtnEvent(vRel.deviceFile, evBtnLeft, btnStateReleased)
	if err != nil {
		return fmt.Errorf("Failed to issue the KeyUp event: %v", err)
	}

	err = syncEvents(vRel.deviceFile)
	if err != nil {
		return fmt.Errorf("sync to device file failed: %v", err)
	}
	return nil
}

// RightClick will issue a RightClick
func (vRel vMouse) RightClick() error {
	err := sendBtnEvent(vRel.deviceFile, evBtnRight, btnStatePressed)
	if err != nil {
		return fmt.Errorf("Failed to issue the RightClick event: %v", err)
	}

	err = sendBtnEvent(vRel.deviceFile, evBtnRight, btnStateReleased)
	if err != nil {
		return fmt.Errorf("Failed to issue the KeyUp event: %v", err)
	}

	err = syncEvents(vRel.deviceFile)
	if err != nil {
		return fmt.Errorf("sync to device file failed: %v", err)
	}
	return nil
}

// Close closes the device and releases the device.
func (vRel vMouse) Close() error {
	return closeDevice(vRel.deviceFile)
}

// CreateKeyboard will create a new keyboard using the given uinput
// device path of the uinput device.
func CreateKeyboard(path string, name []byte) (Keyboard, error) {
	if path == "" {
		return nil, errors.New("device path must not be empty")
	}
	if len(name) > uinputMaxNameSize {
		return nil, fmt.Errorf("device name %s is too long (maximum of %d characters allowed)", name, uinputMaxNameSize)
	}

	fd, err := createVKeyboardDevice(path, name)
	if err != nil {
		return nil, err
	}

	return vKeyboard{name: name, deviceFile: fd}, nil
}

// KeyPress will issue a single key press (push down a key and then immediately release it).
func (vk vKeyboard) KeyPress(key int) error {
	err := sendBtnEvent(vk.deviceFile, key, btnStatePressed)
	if err != nil {
		return fmt.Errorf("Failed to issue the KeyDown event: %v", err)
	}

	err = sendBtnEvent(vk.deviceFile, key, btnStateReleased)
	if err != nil {
		return fmt.Errorf("Failed to issue the KeyUp event: %v", err)
	}

	err = syncEvents(vk.deviceFile)
	if err != nil {
		return fmt.Errorf("sync to device file failed: %v", err)
	}
	return nil
}

// KeyDown will send the key code passed (see uinputdefs.go for available keycodes). Note that unless a key release
// event is sent to the device, the key will remain pressed and therefore input will continuously be generated. Therefore,
// do not forget to call "KeyUp" afterwards.
func (vk vKeyboard) KeyDown(key int) error {
	err := sendBtnEvent(vk.deviceFile, key, btnStatePressed)
	if err != nil {
		return fmt.Errorf("Failed to issue the KeyDown event: %v", err)
	}

	err = syncEvents(vk.deviceFile)
	if err != nil {
		return fmt.Errorf("sync to device file failed: %v", err)
	}
	return nil
}

// KeyUp will release the given key passed as a parameter (see uinputdefs.go for available keycodes). In most
// cases it is recommended to call this function immediately after the "KeyDown" function in order to only issue a
// single key press.
func (vk vKeyboard) KeyUp(key int) error {
	err := sendBtnEvent(vk.deviceFile, key, btnStatePressed)
	if err != nil {
		return fmt.Errorf("Failed to issue the KeyUp event: %v", err)
	}

	err = syncEvents(vk.deviceFile)
	if err != nil {
		return fmt.Errorf("sync to device file failed: %v", err)
	}
	return nil
}

// Close will close the device and free resources.
// It's usually a good idea to use defer to call this function.
func (vk vKeyboard) Close() error {
	return closeDevice(vk.deviceFile)
}
<commit_msg>fix the KeyUp fun<commit_after>/*
Package uinput is a pure go package that provides access to the userland input device driver uinput on linux systems.
Virtual keyboard devices as well as virtual mouse input devices may be created using this package.
The keycodes and other event definitions, that are available and can be used to trigger input events,
are part of this package ("Key1" for number 1, for example).

In order to use the virtual keyboard, you will need to follow these three steps:

	1. Initialize the device
		Example: vk, err := CreateKeyboard("/dev/uinput", "Virtual Keyboard")

	2. Send Button events to the device
		Example (print a single D):
			err = vk.KeyPress(uinput.KeyD)

		Example (keep moving right by holding down right arrow key):
				 err = vk.KeyDown(uinput.KeyRight)

		Example (stop moving right by releasing the right arrow key):
				 err = vk.KeyUp(uinput.KeyRight)

	3. Close the device
		Example: err = vk.Close()

A virtual mouse input device is just as easy to create and use:

	1. Initialize the device:
		Example: vm, err := CreateMouse("/dev/uinput", "DangerMouse")

	2. Move the cursor around and issue click events
		Example (move mouse right):
			err = vm.MoveRight(42)

		Example (move mouse left):
			err = vm.MoveLeft(42)

		Example (move mouse up):
			err = vm.MoveUp(42)

		Example (move mouse down):
			err = vm.MoveDown(42)

		Example (trigger a left click):
			err = vm.LeftClick()

		Example (trigger a right click):
			err = vm.RightClick()

	3. Close the device
		Example: err = vm.Close()

If you'd like to use absolute input events (move the cursor to specific positions on screen), use the touch pad.
Note that you'll need to specify the size of the screen area you want to use when you initialize the
device. Here are a few examples of how to use the virtual touch pad:

	1. Initialize the device:
		Example: vt, err := CreateTouchPad("/dev/uinput", "DontTouchThis", 0, 1024, 0, 768)

	2. Move the cursor around and issue click events
		Example (move cursor to the top left corner of the screen):
			err = vt.MoveTo(0, 0)

		Example (move cursor to the position x: 100, y: 250):
			err = vt.MoveTo(100, 250)

		Example (trigger a left click):
			err = vt.LeftClick()

		Example (trigger a right click):
			err = vt.RightClick()

	3. Close the device
		Example: err = vt.Close()

*/
package uinput

import (
	"errors"
	"fmt"
	"io"
	"os"
)

// A Keyboard is an key event output device. It is used to
// enable a program to simulate HID keyboard input events.
type Keyboard interface {
	// KeyPress will cause the key to be pressed and immediately released.
	KeyPress(key int) error

	// KeyDown will send a keypress event to an existing keyboard device.
	// The key can be any of the predefined keycodes from uinputdefs.
	// Note that the key will be "held down" until "KeyUp" is called.
	KeyDown(key int) error

	// KeyUp will send a keyrelease event to an existing keyboard device.
	// The key can be any of the predefined keycodes from uinputdefs.
	KeyUp(key int) error

	io.Closer
}

type vKeyboard struct {
	name       []byte
	deviceFile *os.File
}

// A Mouse is a device that will trigger an absolute change event.
// For details see: https://www.kernel.org/doc/Documentation/input/event-codes.txt
type Mouse interface {
	// MoveLeft will move the mouse cursor left by the given number of pixel.
	MoveLeft(pixel int32) error

	// MoveRight will move the mouse cursor right by the given number of pixel.
	MoveRight(pixel int32) error

	// MoveUp will move the mouse cursor up by the given number of pixel.
	MoveUp(pixel int32) error

	// MoveDown will move the mouse cursor down by the given number of pixel.
	MoveDown(pixel int32) error

	// LeftClick will issue a single left click.
	LeftClick() error

	// RightClick will issue a right click.
	RightClick() error

	io.Closer
}

type vMouse struct {
	name       []byte
	deviceFile *os.File
}

// A TouchPad is an input device that uses absolute axis events, meaning that you can specify
// the exact position the cursor should move to. Therefore, it is necessary to define the size
// of the rectangle in which the cursor may move upon creation of the device.
type TouchPad interface {
	// MoveTo will move the cursor to the specified position on the screen
	MoveTo(x int32, y int32) error

	// LeftClick will issue a single left click.
	LeftClick() error

	// RightClick will issue a right click.
	RightClick() error

	io.Closer
}

type vTouchPad struct {
	name       []byte
	deviceFile *os.File
}

// CreateTouchPad will create a new touch pad device. note that you will need to define the x and y axis boundaries
// (min and max) within which the cursor maybe moved around.
func CreateTouchPad(path string, name []byte, minX int32, maxX int32, minY int32, maxY int32) (TouchPad, error) {
	if path == "" {
		return nil, errors.New("device path must not be empty")
	}
	if len(name) > uinputMaxNameSize {
		return nil, fmt.Errorf("device name %s is too long (maximum of %d characters allowed)", name, uinputMaxNameSize)
	}

	fd, err := createTouchPad(path, name, minX, maxX, minY, maxY)
	if err != nil {
		return nil, err
	}

	return vTouchPad{name: name, deviceFile: fd}, nil
}

func (vTouch vTouchPad) MoveTo(x int32, y int32) error {
	return sendAbsEvent(vTouch.deviceFile, x, y)
}

func (vTouch vTouchPad) LeftClick() error {
	err := sendBtnEvent(vTouch.deviceFile, evBtnLeft, btnStatePressed)
	if err != nil {
		return fmt.Errorf("Failed to issue the LeftClick event: %v", err)
	}

	err = sendBtnEvent(vTouch.deviceFile, evBtnLeft, btnStateReleased)
	if err != nil {
		return fmt.Errorf("Failed to issue the KeyUp event: %v", err)
	}

	err = syncEvents(vTouch.deviceFile)
	if err != nil {
		return fmt.Errorf("sync to device file failed: %v", err)
	}
	return nil
}

func (vTouch vTouchPad) RightClick() error {
	err := sendBtnEvent(vTouch.deviceFile, evBtnRight, btnStatePressed)
	if err != nil {
		return fmt.Errorf("Failed to issue the RightClick event: %v", err)
	}

	err = sendBtnEvent(vTouch.deviceFile, evBtnRight, btnStateReleased)
	if err != nil {
		return fmt.Errorf("Failed to issue the KeyUp event: %v", err)
	}

	err = syncEvents(vTouch.deviceFile)
	if err != nil {
		return fmt.Errorf("sync to device file failed: %v", err)
	}
	return nil
}

func (vTouch vTouchPad) Close() error {
	return closeDevice(vTouch.deviceFile)
}

// CreateMouse will create a new mouse input device. A mouse is a device that allows relative input.
// Relative input means that all changes to the x and y coordinates of the mouse pointer will be
func CreateMouse(path string, name []byte) (Mouse, error) {
	if path == "" {
		return nil, errors.New("device path must not be empty")
	}
	if len(name) > uinputMaxNameSize {
		return nil, fmt.Errorf("device name %s is too long (maximum of %d characters allowed)", name, uinputMaxNameSize)
	}

	fd, err := createMouse(path, name)
	if err != nil {
		return nil, err
	}

	return vMouse{name: name, deviceFile: fd}, nil
}

// MoveLeft will move the cursor left by the number of pixel specified.
func (vRel vMouse) MoveLeft(pixel int32) error {
	return sendRelEvent(vRel.deviceFile, relX, -pixel)
}

// MoveRight will move the cursor right by the number of pixel specified.
func (vRel vMouse) MoveRight(pixel int32) error {
	return sendRelEvent(vRel.deviceFile, relX, pixel)
}

// MoveUp will move the cursor up by the number of pixel specified.
func (vRel vMouse) MoveUp(pixel int32) error {
	return sendRelEvent(vRel.deviceFile, relY, -pixel)
}

// MoveDown will move the cursor down by the number of pixel specified.
func (vRel vMouse) MoveDown(pixel int32) error {
	return sendRelEvent(vRel.deviceFile, relY, pixel)
}

// LeftClick will issue a LeftClick.
func (vRel vMouse) LeftClick() error {
	err := sendBtnEvent(vRel.deviceFile, evBtnLeft, btnStatePressed)
	if err != nil {
		return fmt.Errorf("Failed to issue the LeftClick event: %v", err)
	}

	err = sendBtnEvent(vRel.deviceFile, evBtnLeft, btnStateReleased)
	if err != nil {
		return fmt.Errorf("Failed to issue the KeyUp event: %v", err)
	}

	err = syncEvents(vRel.deviceFile)
	if err != nil {
		return fmt.Errorf("sync to device file failed: %v", err)
	}
	return nil
}

// RightClick will issue a RightClick
func (vRel vMouse) RightClick() error {
	err := sendBtnEvent(vRel.deviceFile, evBtnRight, btnStatePressed)
	if err != nil {
		return fmt.Errorf("Failed to issue the RightClick event: %v", err)
	}

	err = sendBtnEvent(vRel.deviceFile, evBtnRight, btnStateReleased)
	if err != nil {
		return fmt.Errorf("Failed to issue the KeyUp event: %v", err)
	}

	err = syncEvents(vRel.deviceFile)
	if err != nil {
		return fmt.Errorf("sync to device file failed: %v", err)
	}
	return nil
}

// Close closes the device and releases the device.
func (vRel vMouse) Close() error {
	return closeDevice(vRel.deviceFile)
}

// CreateKeyboard will create a new keyboard using the given uinput
// device path of the uinput device.
func CreateKeyboard(path string, name []byte) (Keyboard, error) {
	if path == "" {
		return nil, errors.New("device path must not be empty")
	}
	if len(name) > uinputMaxNameSize {
		return nil, fmt.Errorf("device name %s is too long (maximum of %d characters allowed)", name, uinputMaxNameSize)
	}

	fd, err := createVKeyboardDevice(path, name)
	if err != nil {
		return nil, err
	}

	return vKeyboard{name: name, deviceFile: fd}, nil
}

// KeyPress will issue a single key press (push down a key and then immediately release it).
func (vk vKeyboard) KeyPress(key int) error {
	err := sendBtnEvent(vk.deviceFile, key, btnStatePressed)
	if err != nil {
		return fmt.Errorf("Failed to issue the KeyDown event: %v", err)
	}

	err = sendBtnEvent(vk.deviceFile, key, btnStateReleased)
	if err != nil {
		return fmt.Errorf("Failed to issue the KeyUp event: %v", err)
	}

	err = syncEvents(vk.deviceFile)
	if err != nil {
		return fmt.Errorf("sync to device file failed: %v", err)
	}
	return nil
}

// KeyDown will send the key code passed (see uinputdefs.go for available keycodes). Note that unless a key release
// event is sent to the device, the key will remain pressed and therefore input will continuously be generated. Therefore,
// do not forget to call "KeyUp" afterwards.
func (vk vKeyboard) KeyDown(key int) error {
	err := sendBtnEvent(vk.deviceFile, key, btnStatePressed)
	if err != nil {
		return fmt.Errorf("Failed to issue the KeyDown event: %v", err)
	}

	err = syncEvents(vk.deviceFile)
	if err != nil {
		return fmt.Errorf("sync to device file failed: %v", err)
	}
	return nil
}

// KeyUp will release the given key passed as a parameter (see uinputdefs.go for available keycodes). In most
// cases it is recommended to call this function immediately after the "KeyDown" function in order to only issue a
// single key press.
func (vk vKeyboard) KeyUp(key int) error {
	err := sendBtnEvent(vk.deviceFile, key, btnStateReleased)
	if err != nil {
		return fmt.Errorf("Failed to issue the KeyUp event: %v", err)
	}

	err = syncEvents(vk.deviceFile)
	if err != nil {
		return fmt.Errorf("sync to device file failed: %v", err)
	}
	return nil
}

// Close will close the device and free resources.
// It's usually a good idea to use defer to call this function.
func (vk vKeyboard) Close() error {
	return closeDevice(vk.deviceFile)
}
<|endoftext|>