<commit_before>package presilo

import (
  "fmt"
  "bytes"
  "strings"
)

/*
  Generates valid Go code for a given schema.
*/
func GenerateGo(schema *ObjectSchema, module string) string {

  var ret bytes.Buffer

  ret.WriteString("package " + module)
  ret.WriteString("\n")
  ret.WriteString(generateGoImports(schema))
  ret.WriteString("\n")
  ret.WriteString(generateGoTypeDeclaration(schema))
  ret.WriteString("\n")
  ret.WriteString(generateGoConstructor(schema))
  ret.WriteString("\n")
  ret.WriteString(generateGoFunctions(schema))
  ret.WriteString("\n")

  return ret.String()
}

func generateGoImports(schema *ObjectSchema) string {

    var ret bytes.Buffer
    return ret.String()
}

func generateGoTypeDeclaration(schema *ObjectSchema) string {

    var ret bytes.Buffer
    var subschema TypeSchema
    var propertyName string
    var isRequired bool

    ret.WriteString("type ")
    ret.WriteString(schema.GetTitle())
    ret.WriteString(" struct {\n")

    // write all required fields as unexported fields.
    for _, propertyName = range schema.RequiredProperties {

      subschema = schema.Properties[propertyName]

      ret.WriteString(generateVariableDeclaration(subschema, propertyName, ToJavaCase))
    }

    // write all non-required fields as exported fields.
    for propertyName, subschema = range schema.Properties {

      isRequired = false

      for _, requiredName := range schema.RequiredProperties {
        if(requiredName == propertyName) {
          isRequired = true
          break
        }
      }

      if(isRequired) {
        continue
      }

      ret.WriteString(generateVariableDeclaration(subschema, propertyName, ToCamelCase))
    }

    ret.WriteString("}\n")
    return ret.String()
}

func generateGoFunctions(schema *ObjectSchema) string {

    var ret bytes.Buffer
    var subschema TypeSchema
    var signature, body string
    var propertyName, casedJavaName, casedCamelName string

    for _, propertyName = range schema.RequiredProperties {

      casedJavaName = ToJavaCase(propertyName)
      casedCamelName = ToCamelCase(propertyName)

      subschema = schema.Properties[propertyName]

      // getter
      signature = fmt.Sprintf("func (this *%s)Get%s()(%s){\n", schema.GetTitle(), casedCamelName, generateGoTypeForSchema(subschema))
      body = fmt.Sprintf("\treturn this.%s\n}\n\n", casedJavaName)

      ret.WriteString(signature)
      ret.WriteString(body)

      // setter
      // TODO: check constraints!
      signature = fmt.Sprintf("func (this *%s)Set%s(value %s){\n", schema.GetTitle(), casedCamelName, generateGoTypeForSchema(subschema))
      body = fmt.Sprintf("\tthis.%s = value\n}\n\n", casedJavaName)

      ret.WriteString(signature)
      ret.WriteString(body)
    }

    return ret.String()
}

func generateGoConstructor(schema *ObjectSchema) string {

  var subschema TypeSchema
  var ret bytes.Buffer
  var parameters, parameterNames []string
  var title, signature, parameterDefinition string

  for _, propertyName := range schema.RequiredProperties {

    subschema = schema.Properties[propertyName]
    propertyName = ToJavaCase(propertyName)

    ret.WriteString(propertyName)
    ret.WriteString(" ")
    ret.WriteString(generateGoTypeForSchema(subschema))

    parameterNames = append(parameterNames, propertyName)
    parameters = append(parameters, ret.String())
    ret.Reset()

  }

  // signature
  title = ToCamelCase(schema.Title)
  signature = fmt.Sprintf("func New%s(%s)(*%s) {\n", title, strings.Join(parameters, ","), title)
  ret.WriteString(signature)

  // body
  parameterDefinition = fmt.Sprintf("\tret := new(%s)\n", title)
  ret.WriteString(parameterDefinition)

  for _, propertyName := range parameterNames {

    parameterDefinition = fmt.Sprintf("\tret.%s = %s\n", propertyName, propertyName)
    ret.WriteString(parameterDefinition)
  }

  ret.WriteString("\treturn ret\n}\n\n")
  return ret.String()
}

func generateGoIntegerFunctions(schema *IntegerSchema) string {

  var ret bytes.Buffer

  if(!schema.HasConstraints()) {
    return ""
  }

  if(schema.Minimum != nil) {

  }

  return ret.String()
}

func generateGoStringFunctions(schema *StringSchema) string {

  var ret bytes.Buffer

  return ret.String()
}

func generateGoTypeForSchema(schema TypeSchema) string {

  switch schema.GetSchemaType() {
  case SCHEMATYPE_STRING:
    return "string"
  case SCHEMATYPE_INTEGER:
    return "int"
  case SCHEMATYPE_OBJECT:
    return "*" + ToCamelCase(schema.GetTitle())
  }

  return "interface{}"
}

func generateVariableDeclaration(subschema TypeSchema, propertyName string, casing func(string)(string)) (string) {

  var structTag string
  var ret bytes.Buffer

  structTag = fmt.Sprintf(" `json:\"%s\";`", ToJavaCase(propertyName))

  // TODO: this means unexported fields will have json deserialization struct tags,
  // which won't work.
  ret.WriteString("\tvar " + casing(propertyName) + " ")
  ret.WriteString(generateGoTypeForSchema(subschema))
  ret.WriteString(structTag)
  ret.WriteString("\n")

  return ret.String()
}
<commit_msg>Spaced out getter/setters, maaan.<commit_after>package presilo

import (
  "fmt"
  "bytes"
  "strings"
)

/*
  Generates valid Go code for a given schema.
*/
func GenerateGo(schema *ObjectSchema, module string) string {

  var ret bytes.Buffer

  ret.WriteString("package " + module)
  ret.WriteString("\n")
  ret.WriteString(generateGoImports(schema))
  ret.WriteString("\n")
  ret.WriteString(generateGoTypeDeclaration(schema))
  ret.WriteString("\n")
  ret.WriteString(generateGoConstructor(schema))
  ret.WriteString("\n")
  ret.WriteString(generateGoFunctions(schema))
  ret.WriteString("\n")

  return ret.String()
}

func generateGoImports(schema *ObjectSchema) string {

    var ret bytes.Buffer
    return ret.String()
}

func generateGoTypeDeclaration(schema *ObjectSchema) string {

    var ret bytes.Buffer
    var subschema TypeSchema
    var propertyName string
    var isRequired bool

    ret.WriteString("type ")
    ret.WriteString(schema.GetTitle())
    ret.WriteString(" struct {\n")

    // write all required fields as unexported fields.
    for _, propertyName = range schema.RequiredProperties {

      subschema = schema.Properties[propertyName]

      ret.WriteString(generateVariableDeclaration(subschema, propertyName, ToJavaCase))
    }

    // write all non-required fields as exported fields.
    for propertyName, subschema = range schema.Properties {

      isRequired = false

      for _, requiredName := range schema.RequiredProperties {
        if(requiredName == propertyName) {
          isRequired = true
          break
        }
      }

      if(isRequired) {
        continue
      }

      ret.WriteString(generateVariableDeclaration(subschema, propertyName, ToCamelCase))
    }

    ret.WriteString("}\n")
    return ret.String()
}

func generateGoFunctions(schema *ObjectSchema) string {

    var ret bytes.Buffer
    var subschema TypeSchema
    var signature, body string
    var propertyName, casedJavaName, casedCamelName string

    for _, propertyName = range schema.RequiredProperties {

      casedJavaName = ToJavaCase(propertyName)
      casedCamelName = ToCamelCase(propertyName)

      subschema = schema.Properties[propertyName]

      // getter
      signature = fmt.Sprintf("func (this *%s) Get%s() (%s) {\n", schema.GetTitle(), casedCamelName, generateGoTypeForSchema(subschema))
      body = fmt.Sprintf("\treturn this.%s\n}\n\n", casedJavaName)

      ret.WriteString(signature)
      ret.WriteString(body)

      // setter
      // TODO: check constraints!
      signature = fmt.Sprintf("func (this *%s) Set%s(value %s) {\n", schema.GetTitle(), casedCamelName, generateGoTypeForSchema(subschema))
      body = fmt.Sprintf("\tthis.%s = value\n}\n\n", casedJavaName)

      ret.WriteString(signature)
      ret.WriteString(body)
    }

    return ret.String()
}

func generateGoConstructor(schema *ObjectSchema) string {

  var subschema TypeSchema
  var ret bytes.Buffer
  var parameters, parameterNames []string
  var title, signature, parameterDefinition string

  for _, propertyName := range schema.RequiredProperties {

    subschema = schema.Properties[propertyName]
    propertyName = ToJavaCase(propertyName)

    ret.WriteString(propertyName)
    ret.WriteString(" ")
    ret.WriteString(generateGoTypeForSchema(subschema))

    parameterNames = append(parameterNames, propertyName)
    parameters = append(parameters, ret.String())
    ret.Reset()

  }

  // signature
  title = ToCamelCase(schema.Title)
  signature = fmt.Sprintf("func New%s(%s)(*%s) {\n", title, strings.Join(parameters, ","), title)
  ret.WriteString(signature)

  // body
  parameterDefinition = fmt.Sprintf("\tret := new(%s)\n", title)
  ret.WriteString(parameterDefinition)

  for _, propertyName := range parameterNames {

    parameterDefinition = fmt.Sprintf("\tret.%s = %s\n", propertyName, propertyName)
    ret.WriteString(parameterDefinition)
  }

  ret.WriteString("\treturn ret\n}\n\n")
  return ret.String()
}

func generateGoIntegerFunctions(schema *IntegerSchema) string {

  var ret bytes.Buffer

  if(!schema.HasConstraints()) {
    return ""
  }

  if(schema.Minimum != nil) {

  }

  return ret.String()
}

func generateGoStringFunctions(schema *StringSchema) string {

  var ret bytes.Buffer

  return ret.String()
}

func generateGoTypeForSchema(schema TypeSchema) string {

  switch schema.GetSchemaType() {
  case SCHEMATYPE_STRING:
    return "string"
  case SCHEMATYPE_INTEGER:
    return "int"
  case SCHEMATYPE_OBJECT:
    return "*" + ToCamelCase(schema.GetTitle())
  }

  return "interface{}"
}

func generateVariableDeclaration(subschema TypeSchema, propertyName string, casing func(string)(string)) (string) {

  var structTag string
  var ret bytes.Buffer

  structTag = fmt.Sprintf(" `json:\"%s\";`", ToJavaCase(propertyName))

  // TODO: this means unexported fields will have json deserialization struct tags,
  // which won't work.
  ret.WriteString("\tvar " + casing(propertyName) + " ")
  ret.WriteString(generateGoTypeForSchema(subschema))
  ret.WriteString(structTag)
  ret.WriteString("\n")

  return ret.String()
}
<|endoftext|>


<commit_before>package stun

import (
	"crypto/md5" // #nosec
	"errors"
	"fmt"
	"strings"

	"github.com/gortc/stun/internal/hmac"
)

// separator for credentials.
const credentialsSep = ":"

// NewLongTermIntegrity returns new MessageIntegrity with key for long-term
// credentials. Password, username, and realm must be SASL-prepared.
func NewLongTermIntegrity(username, realm, password string) MessageIntegrity {
	k := strings.Join(
		[]string{
			username,
			realm,
			password,
		},
		credentialsSep,
	)
	// #nosec
	h := md5.New()
	fmt.Fprint(h, k)
	return MessageIntegrity(h.Sum(nil))
}

// NewShortTermIntegrity returns new MessageIntegrity with key for short-term
// credentials. Password must be SASL-prepared.
func NewShortTermIntegrity(password string) MessageIntegrity {
	return MessageIntegrity(password)
}

// MessageIntegrity represents MESSAGE-INTEGRITY attribute. AddTo and GetFrom
// methods will allocate memory for cryptographic functions. Zero-allocation
// version of MessageIntegrity is not implemented. Implementation and changes
// to it is subject to security review.
//
// RFC 5389 Section 15.4
type MessageIntegrity []byte

// ErrFingerprintBeforeIntegrity means that FINGEPRINT attribute is already in
// message, so MESSAGE-INTEGRITY attribute cannot be added.
var ErrFingerprintBeforeIntegrity = errors.New(
	"FINGERPRINT before MESSAGE-INTEGRITY attribute",
)

func (i MessageIntegrity) String() string {
	return fmt.Sprintf("KEY: 0x%x", []byte(i))
}

const messageIntegritySize = 20

// AddTo adds MESSAGE-INTEGRITY attribute to message. Be advised, CPU
// and allocations costly, can be cause of DOS.
func (i MessageIntegrity) AddTo(m *Message) error {
	for _, a := range m.Attributes {
		// Message should not contain FINGERPRINT attribute
		// before MESSAGE-INTEGRITY.
		if a.Type == AttrFingerprint {
			return ErrFingerprintBeforeIntegrity
		}
	}
	// The text used as input to HMAC is the STUN message,
	// including the header, up to and including the attribute preceding the
	// MESSAGE-INTEGRITY attribute.
	length := m.Length
	// Adjusting m.Length to contain MESSAGE-INTEGRITY TLV.
	m.Length += messageIntegritySize + attributeHeaderSize
	m.WriteLength()        // writing length to m.Raw
	v := newHMAC(i, m.Raw) // calculating HMAC for adjusted m.Raw
	m.Length = length      // changing m.Length back
	m.Add(AttrMessageIntegrity, v)
	return nil
}

// IntegrityErr occurs when computed HMAC differs from expected.
type IntegrityErr struct {
	Expected []byte
	Actual   []byte
}

func (i *IntegrityErr) Error() string {
	return fmt.Sprintf(
		"Integrity check failed: 0x%x (expected) !- 0x%x (actual)",
		i.Expected, i.Actual,
	)
}

func newHMAC(key, message []byte) []byte {
	mac := hmac.AcquireSHA1(key)
	writeOrPanic(mac, message)
	defer hmac.PutSHA1(mac)
	return mac.Sum(nil)
}

// Check checks MESSAGE-INTEGRITY attribute. Be advised, CPU and allocations
// costly, can be cause of DOS.
func (i MessageIntegrity) Check(m *Message) error {
	v, err := m.Get(AttrMessageIntegrity)
	if err != nil {
		return err
	}

	// Adjusting length in header to match m.Raw that was
	// used when computing HMAC.
	var (
		length         = m.Length
		afterIntegrity = false
		sizeReduced    int
	)
	for _, a := range m.Attributes {
		if afterIntegrity {
			sizeReduced += nearestPaddedValueLength(int(a.Length))
			sizeReduced += attributeHeaderSize
		}
		if a.Type == AttrMessageIntegrity {
			afterIntegrity = true
		}
	}
	m.Length -= uint32(sizeReduced)
	m.WriteLength()
	// startOfHMAC should be first byte of integrity attribute.
	startOfHMAC := messageHeaderSize + m.Length - (attributeHeaderSize + messageIntegritySize)
	b := m.Raw[:startOfHMAC] // data before integrity attribute
	expected := newHMAC(i, b)
	m.Length = length
	m.WriteLength() // writing length back
	if !hmac.Equal(v, expected) {
		return &IntegrityErr{
			Expected: expected,
			Actual:   v,
		}
	}
	return nil
}
<commit_msg>attr.integrity: optimize AddTo<commit_after>package stun

import (
	"crypto/md5" // #nosec
	"errors"
	"fmt"
	"strings"

	"crypto/sha1"

	"github.com/gortc/stun/internal/hmac"
)

// separator for credentials.
const credentialsSep = ":"

// NewLongTermIntegrity returns new MessageIntegrity with key for long-term
// credentials. Password, username, and realm must be SASL-prepared.
func NewLongTermIntegrity(username, realm, password string) MessageIntegrity {
	k := strings.Join(
		[]string{
			username,
			realm,
			password,
		},
		credentialsSep,
	)
	// #nosec
	h := md5.New()
	fmt.Fprint(h, k)
	return MessageIntegrity(h.Sum(nil))
}

// NewShortTermIntegrity returns new MessageIntegrity with key for short-term
// credentials. Password must be SASL-prepared.
func NewShortTermIntegrity(password string) MessageIntegrity {
	return MessageIntegrity(password)
}

// MessageIntegrity represents MESSAGE-INTEGRITY attribute. AddTo and GetFrom
// methods will allocate memory for cryptographic functions. Zero-allocation
// version of MessageIntegrity is not implemented. Implementation and changes
// to it is subject to security review.
//
// RFC 5389 Section 15.4
type MessageIntegrity []byte

// ErrFingerprintBeforeIntegrity means that FINGEPRINT attribute is already in
// message, so MESSAGE-INTEGRITY attribute cannot be added.
var ErrFingerprintBeforeIntegrity = errors.New(
	"FINGERPRINT before MESSAGE-INTEGRITY attribute",
)

func (i MessageIntegrity) String() string {
	return fmt.Sprintf("KEY: 0x%x", []byte(i))
}

const messageIntegritySize = 20

// AddTo adds MESSAGE-INTEGRITY attribute to message. Be advised, CPU
// and allocations costly, can be cause of DOS.
func (i MessageIntegrity) AddTo(m *Message) error {
	for _, a := range m.Attributes {
		// Message should not contain FINGERPRINT attribute
		// before MESSAGE-INTEGRITY.
		if a.Type == AttrFingerprint {
			return ErrFingerprintBeforeIntegrity
		}
	}
	// The text used as input to HMAC is the STUN message,
	// including the header, up to and including the attribute preceding the
	// MESSAGE-INTEGRITY attribute.
	length := m.Length
	// Adjusting m.Length to contain MESSAGE-INTEGRITY TLV.
	m.Length += messageIntegritySize + attributeHeaderSize
	m.WriteLength()                            // writing length to m.Raw
	v := newHMAC(i, m.Raw, m.Raw[len(m.Raw):]) // calculating HMAC for adjusted m.Raw
	m.Length = length                          // changing m.Length back

	// Copy hmac value to temporary variable to protect it from resetting
	// while processing m.Add call.
	vBuf := make([]byte, sha1.Size)
	copy(vBuf, v)

	m.Add(AttrMessageIntegrity, vBuf)
	return nil
}

// IntegrityErr occurs when computed HMAC differs from expected.
type IntegrityErr struct {
	Expected []byte
	Actual   []byte
}

func (i *IntegrityErr) Error() string {
	return fmt.Sprintf(
		"Integrity check failed: 0x%x (expected) !- 0x%x (actual)",
		i.Expected, i.Actual,
	)
}

func newHMAC(key, message, buf []byte) []byte {
	mac := hmac.AcquireSHA1(key)
	writeOrPanic(mac, message)
	defer hmac.PutSHA1(mac)
	return mac.Sum(buf)
}

// Check checks MESSAGE-INTEGRITY attribute. Be advised, CPU and allocations
// costly, can be cause of DOS.
func (i MessageIntegrity) Check(m *Message) error {
	v, err := m.Get(AttrMessageIntegrity)
	if err != nil {
		return err
	}

	// Adjusting length in header to match m.Raw that was
	// used when computing HMAC.
	var (
		length         = m.Length
		afterIntegrity = false
		sizeReduced    int
	)
	for _, a := range m.Attributes {
		if afterIntegrity {
			sizeReduced += nearestPaddedValueLength(int(a.Length))
			sizeReduced += attributeHeaderSize
		}
		if a.Type == AttrMessageIntegrity {
			afterIntegrity = true
		}
	}
	m.Length -= uint32(sizeReduced)
	m.WriteLength()
	// startOfHMAC should be first byte of integrity attribute.
	startOfHMAC := messageHeaderSize + m.Length - (attributeHeaderSize + messageIntegritySize)
	b := m.Raw[:startOfHMAC] // data before integrity attribute
	expected := newHMAC(i, b, m.Raw[len(m.Raw):])
	m.Length = length
	m.WriteLength() // writing length back
	if !hmac.Equal(v, expected) {
		return &IntegrityErr{
			Expected: expected,
			Actual:   v,
		}
	}
	return nil
}
<|endoftext|>


<commit_before>package interfaces

import (
	"errors"
	"fmt"
	"go/types"
	"sort"
	"unicode"

	"golang.org/x/tools/go/loader"
)

// Interface represents a typed interface.
type Interface []Func

// New builds an interface definition for a type specified by the query.
// Supported query format is "package".Type (similar to what gorename
// tool accepts).
//
// The function expects sources for the requested type to be present
// in current GOPATH.
func New(query string) (Interface, error) {
	q, err := ParseQuery(query)
	if err != nil {
		return nil, errors.New("invalid query: " + err.Error())
	}
	opts := &Options{
		Query: q,
	}
	return NewWithOptions(opts)
}

// NewWithOptions builds an interface definition for a type specified by
// the given Options.
//
// The Options may be used to specify e.g. different GOPATH if sources
// for requested type are not available in the current one.
func NewWithOptions(opts *Options) (Interface, error) {
	if opts == nil || opts.Query == nil {
		panic("interfacer: called NewWithOptions with nil Options or nil Query")
	}
	if err := opts.Query.valid(); err != nil {
		return nil, errors.New("invalid query: " + err.Error())
	}
	return buildInterface(opts)
}

// Deps gives a list of packages the interface depends on.
func (i Interface) Deps() []string {
	pkgs := make(map[string]struct{})
	for _, fn := range i {
		for _, pkg := range fn.Deps() {
			pkgs[pkg] = struct{}{}
		}
	}
	if len(pkgs) == 0 {
		return nil
	}
	deps := make([]string, 0, len(pkgs))
	for pkg := range pkgs {
		deps = append(deps, pkg)
	}
	sort.Strings(deps)
	return deps
}

func buildInterface(opts *Options) (Interface, error) {
	cfg := &loader.Config{
		AllowErrors:         true,
		Build:               opts.context(),
		ImportPkgs:          map[string]bool{opts.Query.Package: true},
		TypeCheckFuncBodies: func(string) bool { return false },
	}
	cfg.ImportWithTests(opts.Query.Package)
	prog, err := cfg.Load()
	if err != nil {
		return nil, err
	}
	pkg, ok := prog.Imported[opts.Query.Package]
	if !ok {
		return nil, fmt.Errorf("parsing successful, but package %q not found",
			opts.Query.Package)
	}
	i, err := buildInterfaceForPkg(pkg, opts)
	if err == nil {
		return i, nil
	}
	// If a requested type is defined in an external test package try to
	// build the interface using it before returning an error.
	queryCopy := *opts.Query
	queryCopy.Package += "_test"
	optsCopy := *opts
	optsCopy.Query = &queryCopy
	for _, pkg := range prog.Created {
		if pkg.Pkg.Path() == optsCopy.Query.Package {
			return buildInterfaceForPkg(pkg, &optsCopy)
		}
	}
	return nil, err
}

func buildInterfaceForPkg(pkg *loader.PackageInfo, opts *Options) (Interface, error) {
	var typ *types.Named
	for _, obj := range pkg.Defs {
		if obj == nil {
			continue
		}
		if obj.Name() != opts.Query.TypeName || obj.Pkg().Path() != opts.Query.Package {
			continue
		}
		var ok bool
		typ, ok = obj.Type().(*types.Named)
		if ok {
			break
		}
	}
	if typ == nil {
		return nil, notFoundErr(opts)
	}
	var inter Interface
	var methods = make(map[string]*types.Func)
	collectMethods(methods, typ, 0, nil)
	for _, method := range methods {
		// TODO(rjeczalik): read rune
		if unicode.IsLower(rune(method.Name()[0])) && !opts.Unexported {
			continue
		}
		sig, ok := method.Type().(*types.Signature)
		if !ok {
			continue
		}
		ins := sig.Params()
		outs := sig.Results()
		fn := Func{
			Name:       method.Name(),
			Ins:        make([]Type, ins.Len()),
			Outs:       make([]Type, outs.Len()),
			IsVariadic: sig.Variadic(),
		}
		for i := range fn.Ins {
			fn.Ins[i] = newType(ins.At(i))
			fixup(&fn.Ins[i], opts.Query)
		}
		for i := range fn.Outs {
			fn.Outs[i] = newType(outs.At(i))
			fixup(&fn.Outs[i], opts.Query)
		}
		inter = append(inter, fn)
	}
	if len(inter) == 0 {
		return nil, notFoundErr(opts)
	}
	sort.Sort(funcs(inter))
	return inter, nil
}

func collectMethods(methods map[string]*types.Func, typ *types.Named, depth int, orig types.Type) {
	if orig == nil {
		orig = typ
	}
	// TODO(rjeczalik): recursive types support
	if depth > 128 {
		panic("recursive types not supported: " + orig.String())
	}
	for i := 0; i < typ.NumMethods(); i++ {
		method := typ.Method(i)
		if _, ok := methods[method.Name()]; ok {
			continue
		}
		methods[method.Name()] = method
	}
	if typ, ok := typ.Underlying().(*types.Struct); ok {
		for i := 0; i < typ.NumFields(); i++ {
			field := typ.Field(i)
			if !field.Anonymous() {
				continue
			}
			typ := field.Type()
			if p, ok := typ.(*types.Pointer); ok {
				typ = p.Elem()
			}
			if named, ok := typ.(*types.Named); ok {
				collectMethods(methods, named, depth+1, orig)
			}
		}
	}
}
<commit_msg>interfaces: improve lookup for multiple defs<commit_after>package interfaces

import (
	"errors"
	"fmt"
	"go/types"
	"sort"
	"unicode"

	"golang.org/x/tools/go/loader"
)

// Interface represents a typed interface.
type Interface []Func

// New builds an interface definition for a type specified by the query.
// Supported query format is "package".Type (similar to what gorename
// tool accepts).
//
// The function expects sources for the requested type to be present
// in current GOPATH.
func New(query string) (Interface, error) {
	q, err := ParseQuery(query)
	if err != nil {
		return nil, errors.New("invalid query: " + err.Error())
	}
	opts := &Options{
		Query: q,
	}
	return NewWithOptions(opts)
}

// NewWithOptions builds an interface definition for a type specified by
// the given Options.
//
// The Options may be used to specify e.g. different GOPATH if sources
// for requested type are not available in the current one.
func NewWithOptions(opts *Options) (Interface, error) {
	if opts == nil || opts.Query == nil {
		panic("interfacer: called NewWithOptions with nil Options or nil Query")
	}
	if err := opts.Query.valid(); err != nil {
		return nil, errors.New("invalid query: " + err.Error())
	}
	return buildInterface(opts)
}

// Deps gives a list of packages the interface depends on.
func (i Interface) Deps() []string {
	pkgs := make(map[string]struct{})
	for _, fn := range i {
		for _, pkg := range fn.Deps() {
			pkgs[pkg] = struct{}{}
		}
	}
	if len(pkgs) == 0 {
		return nil
	}
	deps := make([]string, 0, len(pkgs))
	for pkg := range pkgs {
		deps = append(deps, pkg)
	}
	sort.Strings(deps)
	return deps
}

func buildInterface(opts *Options) (Interface, error) {
	cfg := &loader.Config{
		AllowErrors:         true,
		Build:               opts.context(),
		ImportPkgs:          map[string]bool{opts.Query.Package: true},
		TypeCheckFuncBodies: func(string) bool { return false },
	}
	cfg.ImportWithTests(opts.Query.Package)
	prog, err := cfg.Load()
	if err != nil {
		return nil, err
	}
	pkg, ok := prog.Imported[opts.Query.Package]
	if !ok {
		return nil, fmt.Errorf("parsing successful, but package %q not found",
			opts.Query.Package)
	}
	i, err := buildInterfaceForPkg(pkg, opts)
	if err == nil {
		return i, nil
	}
	// If a requested type is defined in an external test package try to
	// build the interface using it before returning an error.
	queryCopy := *opts.Query
	queryCopy.Package += "_test"
	optsCopy := *opts
	optsCopy.Query = &queryCopy
	for _, pkg := range prog.Created {
		if pkg.Pkg.Path() == optsCopy.Query.Package {
			return buildInterfaceForPkg(pkg, &optsCopy)
		}
	}
	return nil, err
}

func buildInterfaceForPkg(pkg *loader.PackageInfo, opts *Options) (Interface, error) {
	var typ *types.Named
	for _, obj := range pkg.Defs {
		if obj == nil {
			continue
		}
		if obj.Name() != opts.Query.TypeName || obj.Pkg().Path() != opts.Query.Package {
			continue
		}
		tmp, ok := obj.Type().(*types.Named)
		if !ok {
			continue
		}
		if tmp.Obj() == obj {
			typ = tmp
			break
		}
	}
	if typ == nil {
		return nil, notFoundErr(opts)
	}
	var inter Interface
	var methods = make(map[string]*types.Func)
	collectMethods(methods, typ, 0, nil)
	for _, method := range methods {
		// TODO(rjeczalik): read rune
		if unicode.IsLower(rune(method.Name()[0])) && !opts.Unexported {
			continue
		}
		sig, ok := method.Type().(*types.Signature)
		if !ok {
			continue
		}
		ins := sig.Params()
		outs := sig.Results()
		fn := Func{
			Name:       method.Name(),
			Ins:        make([]Type, ins.Len()),
			Outs:       make([]Type, outs.Len()),
			IsVariadic: sig.Variadic(),
		}
		for i := range fn.Ins {
			fn.Ins[i] = newType(ins.At(i))
			fixup(&fn.Ins[i], opts.Query)
		}
		for i := range fn.Outs {
			fn.Outs[i] = newType(outs.At(i))
			fixup(&fn.Outs[i], opts.Query)
		}
		inter = append(inter, fn)
	}
	if len(inter) == 0 {
		return nil, notFoundErr(opts)
	}
	sort.Sort(funcs(inter))
	return inter, nil
}

func collectMethods(methods map[string]*types.Func, typ *types.Named, depth int, orig types.Type) {
	if orig == nil {
		orig = typ
	}
	// TODO(rjeczalik): recursive types support
	if depth > 128 {
		panic("recursive types not supported: " + orig.String())
	}
	for i := 0; i < typ.NumMethods(); i++ {
		method := typ.Method(i)
		if _, ok := methods[method.Name()]; ok {
			continue
		}
		methods[method.Name()] = method
	}
	if typ, ok := typ.Underlying().(*types.Struct); ok {
		for i := 0; i < typ.NumFields(); i++ {
			field := typ.Field(i)
			if !field.Anonymous() {
				continue
			}
			typ := field.Type()
			if p, ok := typ.(*types.Pointer); ok {
				typ = p.Elem()
			}
			if named, ok := typ.(*types.Named); ok {
				collectMethods(methods, named, depth+1, orig)
			}
		}
	}
}
<|endoftext|>


<commit_before>// **********************************************************************
//    Copyright (c) 2017 Henry Seurer
//
//   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 wiringpi

/*
#include <time.h>

unsigned long long as_nanoseconds(struct timespec* ts) {
    return ts->tv_sec * (unsigned long long)1000000000L + ts->tv_nsec;
}

unsigned long long monotonic_time() {
    struct timespec last_t;
    clock_gettime(CLOCK_MONOTONIC, &last_t);
    return as_nanoseconds(&last_t);
}
*/
import "C"
import (
	"fmt"
	"os"
)

var (
	board2pin = []int{
		-1,
		-1,
		-1,
		8,
		-1,
		9,
		-1,
		7,
		15,
		-1,
		16,
		0,
		1,
		2,
		-1,
		-1,
		4,
		-1,
		5,
		12,
		-1,
		13,
		6,
		14,
		10,
		-1,
		11,
	}
	gpio2pin = []int{
		8,
		9,
		-1,
		-1,
		7,
		-1,
		-1,
		11,
		10,
		13,
		12,
		14,
		-1,
		-1,
		15,
		16,
		-1,
		0,
		1,
		-1,
		-1,
		2,
		3,
		4,
		5,
		6,
		-1,
		-1,
		17,
		18,
		19,
		20,
	}

	gpioModes = []string{"IN", "OUT", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3"}
)

//noinspection GoUnusedConst
const (
	PIN_GPIO_0  = 0
	PIN_GPIO_1  = 1
	PIN_GPIO_2  = 2
	PIN_GPIO_3  = 3
	PIN_GPIO_4  = 4
	PIN_GPIO_5  = 5
	PIN_GPIO_6  = 6
	PIN_GPIO_7  = 7
	PIN_SDA     = 8
	PIN_SCL     = 9
	PIN_CE0     = 10
	PIN_CE1     = 11
	PIN_MOSI    = 12
	PIN_MOSO    = 13
	PIN_SCLK    = 14
	PIN_TXD     = 15
	PIN_RXD     = 16
	PIN_GPIO_8  = 17
	PIN_GPIO_9  = 18
	PIN_GPIO_10 = 19
	PIN_GPIO_11 = 20

	MODE_IN   = 0
	MODE_OUT  = 1
	MODE_ALT5 = 2
	MODE_ALT4 = 3
	MODE_ALT0 = 4
	MODE_ALT1 = 5
	MODE_ALT2 = 6
	MODE_ALT3 = 7
)

//use RPi.GPIO's BOARD numbering
//noinspection GoUnusedExportedFunction
func BoardToPin(pin int) int {
	if pin < 1 || pin >= len(board2pin) {
		panic(fmt.Sprintf("Invalid board pin number: %d", pin))
	}
	return board2pin[pin]
}

//noinspection GoUnusedExportedFunction
func GpioToPin(pin int) int {
	if pin < 0 || pin >= len(gpio2pin) {
		panic(fmt.Sprintf("Invalid bcm gpio number: %d", pin))
	}
	return gpio2pin[pin]
}

//noinspection GoUnusedExportedFunction
func PinToGpio(pin int) int {
	return internalPinToGpio(pin)
}

// This initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme.
// This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real
// underlying Broadcom GPIO pin numbers. See the pins page for a table which maps the wiringPi pin number to the
// Broadcom GPIO pin number to the physical location on the edge connector.
//
// This function needs to be called with root privileges.
//
//noinspection GoUnusedExportedFunction
func Setup() int {
	return internalSetup()
}

//This is identical to above, however it allows the calling programs to use the Broadcom GPIO pin numbers
// directly with no re-mapping.
//
// As above, this function needs to be called with root privileges, and note that some pins are different
// from revision 1 to revision 2 boards.
//
//noinspection GoUnusedExportedFunction
func SetupGpio() int {
	return internalSetupGpio()
}

// Identical to above, however it allows the calling programs to use the physical pin numbers on the P1 connector only.
//
// As above, this function needs to be called with root privileges.
//
//noinspection GoUnusedExportedFunction
func SetupPhys() int {
	return internalSetupPhys()
}

// This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly.
// This can be called as a non-root user provided the GPIO pins have been exported before-hand using the gpio program.
// Pin numbering in this mode is the native Broadcom GPIO numbers – the same as wiringPiSetupGpio() above, so be
// aware of the differences between Rev 1 and Rev 2 boards.
//
// Note: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface
// before you run your program. You can do this in a separate shell-script, or by using the system() function
// from inside your program to call the gpio program.
//
//Also note that some functions have no effect when using this mode as they’re not currently possible to action unless called with root privileges. (although you can use system() to call gpio to set/change modes if needed)
//
//noinspection GoUnusedExportedFunction
func SetupSys() int {
	return internalSetupSys()
}

// This sets the mode of a pin to either INPUT, OUTPUT, PWM_OUTPUT or GPIO_CLOCK. Note that only wiringPi pin 1
// (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes.
//
// This function has no effect when in Sys mode. If you need to change the pin mode, then you can do it with the
// gpio program in a script before you start your program.
//
//noinspection GoUnusedExportedFunction
func PinMode(pin int, mode int) {
	internalPinMode(pin, mode)
}

// This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an input. Unlike the
// Arduino, the BCM2835 has both pull-up an down internal resistors. The parameter pud should be; PUD_OFF, (no pull up/down), PUD_DOWN (pull to ground) or PUD_UP (pull to 3.3v) The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi.
//
// This function has no effect on the Raspberry Pi’s GPIO pins when in Sys mode. If you need to activate a
// pull-up/pull-down, then you can do it with the gpio program in a script before you start your program.
//
//noinspection GoUnusedExportedFunction
func PullUpDnControl(pin int, pud int) {
	internalPullUpDnControl(pin, pud)
}

//Writes the value HIGH or LOW (1 or 0) to the given pin which must have been previously set as an output.
//
//WiringPi treats any non-zero number as HIGH, however 0 is the only representation of LOW.
//
//noinspection GoUnusedExportedFunction
func DigitalWrite(pin int, mode int) {
	internalDigitalWrite(pin, mode)
}

// Writes the value to the PWM register for the given pin. The Raspberry Pi has one on-board PWM pin, pin 1
// (BMC_GPIO 18, Phys 12) and the range is 0-1024. Other PWM devices may have other PWM ranges.
//
// This function is not able to control the Pi’s on-board PWM when in Sys mode.
//
//noinspection GoUnusedExportedFunction
func PwmWrite(pin int, value int) {
	internalPwmWrite(pin, value)
}

//noinspection GoUnusedExportedFunction
func DigitalRead(pin int) int {
	return internalDigitalRead(pin)
}

//noinspection GoUnusedExportedFunction
func DigitalReadStr(pin int) string {
	if internalDigitalRead(pin) == LOW {
		return "LOW"
	}
	return "HIGH"
}

func GetMode(pin int) int {
	return internalGetMode(pin)
}

//noinspection GoUnusedExportedFunction
func GetModeStr(pin int) string {
	var mode = internalGetMode(pin)

	if mode > len(gpioModes) {
		return "INVALID"
	}

	return gpioModes[GetMode(pin)]
}

//noinspection GoUnusedExportedFunction
func Delay(ms int) {
	internalDelay(ms)
}

//noinspection GoUnusedExportedFunction
func DelayMicroseconds(microSec int) {
	internalDelayMicroseconds(microSec)
}

//noinspection GoUnusedExportedFunction
func WiringISR(pin int, mode int) chan int {
	return internalWiringISR(pin, mode)
}

//noinspection GoUnusedExportedFunction
func IsRaspberryPi() bool {
	_, err := os.Stat("/opt/vc/include/bcm_host.h")
	return !os.IsNotExist(err)
}

//noinspection GoUnusedExportedFunction
func SetupI2C(devId int) int {
	return internalSetupI2C(devId)
}

//noinspection GoUnusedExportedFunction
func I2cRead(fd int) int {
	return internalI2CRead(fd)
}

//noinspection GoUnusedExportedFunction
func MonotonicTime() uint64 {
	return uint64(C.monotonic_time())
}

//noinspection GoUnusedExportedFunction
func ConvertMonotonicTimeToUSec(time uint64) uint64 {
	return time / 1000
}
<commit_msg>Trying to check the godebug.<commit_after>// **********************************************************************
//    Copyright (c) 2017 Henry Seurer
//
//   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 wiringpi

/*
#include <time.h>

unsigned long long as_nanoseconds(struct timespec* ts) {
    return ts->tv_sec * (unsigned long long)1000000000L + ts->tv_nsec;
}

unsigned long long monotonic_time() {
    struct timespec last_t;
    clock_gettime(CLOCK_MONOTONIC, &last_t);
    return as_nanoseconds(&last_t);
}
*/
import "C"
import "unsafe"

import (
	"fmt"
	"os"
)

var (
	board2pin = []int{
		-1,
		-1,
		-1,
		8,
		-1,
		9,
		-1,
		7,
		15,
		-1,
		16,
		0,
		1,
		2,
		-1,
		-1,
		4,
		-1,
		5,
		12,
		-1,
		13,
		6,
		14,
		10,
		-1,
		11,
	}
	gpio2pin = []int{
		8,
		9,
		-1,
		-1,
		7,
		-1,
		-1,
		11,
		10,
		13,
		12,
		14,
		-1,
		-1,
		15,
		16,
		-1,
		0,
		1,
		-1,
		-1,
		2,
		3,
		4,
		5,
		6,
		-1,
		-1,
		17,
		18,
		19,
		20,
	}

	gpioModes = []string{"IN", "OUT", "ALT5", "ALT4", "ALT0", "ALT1", "ALT2", "ALT3"}
)

//noinspection GoUnusedConst
const (
	PIN_GPIO_0  = 0
	PIN_GPIO_1  = 1
	PIN_GPIO_2  = 2
	PIN_GPIO_3  = 3
	PIN_GPIO_4  = 4
	PIN_GPIO_5  = 5
	PIN_GPIO_6  = 6
	PIN_GPIO_7  = 7
	PIN_SDA     = 8
	PIN_SCL     = 9
	PIN_CE0     = 10
	PIN_CE1     = 11
	PIN_MOSI    = 12
	PIN_MOSO    = 13
	PIN_SCLK    = 14
	PIN_TXD     = 15
	PIN_RXD     = 16
	PIN_GPIO_8  = 17
	PIN_GPIO_9  = 18
	PIN_GPIO_10 = 19
	PIN_GPIO_11 = 20

	MODE_IN   = 0
	MODE_OUT  = 1
	MODE_ALT5 = 2
	MODE_ALT4 = 3
	MODE_ALT0 = 4
	MODE_ALT1 = 5
	MODE_ALT2 = 6
	MODE_ALT3 = 7
)

//use RPi.GPIO's BOARD numbering
//noinspection GoUnusedExportedFunction
func BoardToPin(pin int) int {
	if pin < 1 || pin >= len(board2pin) {
		panic(fmt.Sprintf("Invalid board pin number: %d", pin))
	}
	return board2pin[pin]
}

//noinspection GoUnusedExportedFunction
func GpioToPin(pin int) int {
	if pin < 0 || pin >= len(gpio2pin) {
		panic(fmt.Sprintf("Invalid bcm gpio number: %d", pin))
	}
	return gpio2pin[pin]
}

//noinspection GoUnusedExportedFunction
func PinToGpio(pin int) int {
	return internalPinToGpio(pin)
}

// This initialises wiringPi and assumes that the calling program is going to be using the wiringPi pin numbering scheme.
// This is a simplified numbering scheme which provides a mapping from virtual pin numbers 0 through 16 to the real
// underlying Broadcom GPIO pin numbers. See the pins page for a table which maps the wiringPi pin number to the
// Broadcom GPIO pin number to the physical location on the edge connector.
//
// This function needs to be called with root privileges.
//
//noinspection GoUnusedExportedFunction
func Setup() int {
	return internalSetup()
}

//This is identical to above, however it allows the calling programs to use the Broadcom GPIO pin numbers
// directly with no re-mapping.
//
// As above, this function needs to be called with root privileges, and note that some pins are different
// from revision 1 to revision 2 boards.
//
//noinspection GoUnusedExportedFunction
func SetupGpio() int {
	return internalSetupGpio()
}

// Identical to above, however it allows the calling programs to use the physical pin numbers on the P1 connector only.
//
// As above, this function needs to be called with root privileges.
//
//noinspection GoUnusedExportedFunction
func SetupPhys() int {
	return internalSetupPhys()
}

// This initialises wiringPi but uses the /sys/class/gpio interface rather than accessing the hardware directly.
// This can be called as a non-root user provided the GPIO pins have been exported before-hand using the gpio program.
// Pin numbering in this mode is the native Broadcom GPIO numbers – the same as wiringPiSetupGpio() above, so be
// aware of the differences between Rev 1 and Rev 2 boards.
//
// Note: In this mode you can only use the pins which have been exported via the /sys/class/gpio interface
// before you run your program. You can do this in a separate shell-script, or by using the system() function
// from inside your program to call the gpio program.
//
//Also note that some functions have no effect when using this mode as they’re not currently possible to action unless called with root privileges. (although you can use system() to call gpio to set/change modes if needed)
//
//noinspection GoUnusedExportedFunction
func SetupSys() int {
	return internalSetupSys()
}

// This sets the mode of a pin to either INPUT, OUTPUT, PWM_OUTPUT or GPIO_CLOCK. Note that only wiringPi pin 1
// (BCM_GPIO 18) supports PWM output and only wiringPi pin 7 (BCM_GPIO 4) supports CLOCK output modes.
//
// This function has no effect when in Sys mode. If you need to change the pin mode, then you can do it with the
// gpio program in a script before you start your program.
//
//noinspection GoUnusedExportedFunction
func PinMode(pin int, mode int) {
	internalPinMode(pin, mode)
}

// This sets the pull-up or pull-down resistor mode on the given pin, which should be set as an input. Unlike the
// Arduino, the BCM2835 has both pull-up an down internal resistors. The parameter pud should be; PUD_OFF, (no pull up/down), PUD_DOWN (pull to ground) or PUD_UP (pull to 3.3v) The internal pull up/down resistors have a value of approximately 50KΩ on the Raspberry Pi.
//
// This function has no effect on the Raspberry Pi’s GPIO pins when in Sys mode. If you need to activate a
// pull-up/pull-down, then you can do it with the gpio program in a script before you start your program.
//
//noinspection GoUnusedExportedFunction
func PullUpDnControl(pin int, pud int) {
	internalPullUpDnControl(pin, pud)
}

//Writes the value HIGH or LOW (1 or 0) to the given pin which must have been previously set as an output.
//
//WiringPi treats any non-zero number as HIGH, however 0 is the only representation of LOW.
//
//noinspection GoUnusedExportedFunction
func DigitalWrite(pin int, mode int) {
	internalDigitalWrite(pin, mode)
}

// Writes the value to the PWM register for the given pin. The Raspberry Pi has one on-board PWM pin, pin 1
// (BMC_GPIO 18, Phys 12) and the range is 0-1024. Other PWM devices may have other PWM ranges.
//
// This function is not able to control the Pi’s on-board PWM when in Sys mode.
//
//noinspection GoUnusedExportedFunction
func PwmWrite(pin int, value int) {
	internalPwmWrite(pin, value)
}

//noinspection GoUnusedExportedFunction
func DigitalRead(pin int) int {
	return internalDigitalRead(pin)
}

//noinspection GoUnusedExportedFunction
func DigitalReadStr(pin int) string {
	if internalDigitalRead(pin) == LOW {
		return "LOW"
	}
	return "HIGH"
}

func GetMode(pin int) int {
	return internalGetMode(pin)
}

//noinspection GoUnusedExportedFunction
func GetModeStr(pin int) string {
	var mode = internalGetMode(pin)

	if mode > len(gpioModes) {
		return "INVALID"
	}

	return gpioModes[GetMode(pin)]
}

//noinspection GoUnusedExportedFunction
func Delay(ms int) {
	internalDelay(ms)
}

//noinspection GoUnusedExportedFunction
func DelayMicroseconds(microSec int) {
	internalDelayMicroseconds(microSec)
}

//noinspection GoUnusedExportedFunction
func WiringISR(pin int, mode int) chan int {
	return internalWiringISR(pin, mode)
}

//noinspection GoUnusedExportedFunction
func IsRaspberryPi() bool {
	_, err := os.Stat("/opt/vc/include/bcm_host.h")
	return !os.IsNotExist(err)
}

//noinspection GoUnusedExportedFunction
func SetupI2C(devId int) int {
	return internalSetupI2C(devId)
}

//noinspection GoUnusedExportedFunction
func I2cRead(fd int) int {
	return internalI2CRead(fd)
}

//noinspection GoUnusedExportedFunction
func MonotonicTime() uint64 {
	return uint64(C.monotonic_time())
}

//noinspection GoUnusedExportedFunction
func ConvertMonotonicTimeToUSec(time uint64) uint64 {
	return time / 1000
}
<|endoftext|>


<commit_before>package psdock

import (
	"code.google.com/p/go.crypto/ssh/terminal"
	"errors"
	"io"
	"net"
	"net/url"
	"os"
)

type ioContext struct {
	term         *terminal.Terminal
	oldTermState *terminal.State
	stdinOutput  *os.File
	log          *Logger
}

func newIOContext(stdinStr string, pty *os.File, stdout, logPrefix, logRotation, logColor string,
	statusChannel chan ProcessStatus, eofChannel chan bool) (*ioContext, error) {
	var err error
	result := &ioContext{}

	if err = result.redirectStdin(pty, stdinStr, statusChannel); err != nil {
		return nil, errors.New("Can't redirect stdin:" + err.Error())
	}

	if err = result.redirectStdout(pty, stdout, logPrefix, logRotation, logColor, statusChannel, eofChannel); err != nil {
		return nil, errors.New("Can't redirect stdout:" + err.Error())
	}

	return result, nil
}

func (ioC *ioContext) restoreIO() error {
	err := terminal.Restore(int(ioC.stdinOutput.Fd()), ioC.oldTermState)
	return err
}

func (ioC *ioContext) redirectStdin(pty *os.File, stdinStr string, statusChannel chan ProcessStatus) error {
	url, err := url.Parse(stdinStr)
	if err != nil {
		return err
	}
	if url.Path == "os.Stdin" {
		//We don't need to do anything here
	} else if url.Scheme == "tcp" {
		conn, err := net.Dial("tcp", url.Host+url.Path)
		if err != nil {
			return err
		}
		//Directly copy from the connection to the pty. Escape chars won't be available
		go func() {
			io.Copy(pty, conn)
			//When the remote stdin closes, terminate the process through the status Channel
			statusChannel <- ProcessStatus{Status: PROCESS_STOPPED, Err: errors.New("Remote stdin closed")}
		}()
	} else {
		//default case, the protocol is not supported
		return errors.New("The protocol " + url.Scheme + " is not supported")
	}
	ioC.stdinOutput = os.Stdin

	//Set up the tty
	ioC.oldTermState, err = terminal.MakeRaw(int(ioC.stdinOutput.Fd()))
	if err != nil {
		return errors.New("Can't create terminal:" + err.Error())
	}
	ioC.term = terminal.NewTerminal(ioC.stdinOutput, "")
	cb := func(s string, i int, r rune) (string, int, bool) {
		car := []byte{byte(r)}
		ioC.term.Write(car)
		return s, i, false
	}
	ioC.term.AutoCompleteCallback = cb

	//Copy everything from os.Stdin to the pty
	go io.Copy(pty, ioC.stdinOutput)

	return nil
}

func (ioC *ioContext) redirectStdout(pty *os.File, stdout, logPrefix, logRotation, logColor string,
	statusChannel chan ProcessStatus, eofChannel chan bool) error {
	url, err := url.Parse(stdout)
	if err != nil {
		return err
	}
	ioC.log, err = newLogger(*url, logPrefix, logRotation, statusChannel)
	if err != nil {
		return err
	}
	go ioC.log.startCopy(pty, eofChannel, ioC, logColor)

	return nil
}

func (ioC *ioContext) setTerminalColor(color string) error {
	var err error
	switch color {
	case "red":
		_, err = ioC.term.Write(ioC.term.Escape.Red)
	case "green":
		_, err = ioC.term.Write(ioC.term.Escape.Green)
	case "blue":
		_, err = ioC.term.Write(ioC.term.Escape.Blue)
	case "yellow":
		_, err = ioC.term.Write(ioC.term.Escape.Yellow)
	case "magenta":
		_, err = ioC.term.Write(ioC.term.Escape.Magenta)
	case "cyan":
		_, err = ioC.term.Write(ioC.term.Escape.Cyan)
	case "white":
		_, err = ioC.term.Write(ioC.term.Escape.White)
	default:
		_, err = ioC.term.Write(ioC.term.Escape.Black)
	}
	return err
}

func (ioC *ioContext) resetTerminal() error {
	var err error
	_, err = ioC.term.Write(ioC.term.Escape.Reset)
	return err
}
<commit_msg>restoreIO can now be called multiple times<commit_after>package psdock

import (
	"code.google.com/p/go.crypto/ssh/terminal"
	"errors"
	"io"
	"net"
	"net/url"
	"os"
)

type ioContext struct {
	term         *terminal.Terminal
	oldTermState *terminal.State
	stdinOutput  *os.File
	log          *Logger
}

func newIOContext(stdinStr string, pty *os.File, stdout, logPrefix, logRotation, logColor string,
	statusChannel chan ProcessStatus, eofChannel chan bool) (*ioContext, error) {
	var err error
	result := &ioContext{}

	if err = result.redirectStdin(pty, stdinStr, statusChannel); err != nil {
		return nil, errors.New("Can't redirect stdin:" + err.Error())
	}

	if err = result.redirectStdout(pty, stdout, logPrefix, logRotation, logColor, statusChannel, eofChannel); err != nil {
		return nil, errors.New("Can't redirect stdout:" + err.Error())
	}

	return result, nil
}

func (ioC *ioContext) restoreIO() error {
	if ioC.oldTermState == nil {
		return nil
	}
	err := terminal.Restore(int(ioC.stdinOutput.Fd()), ioC.oldTermState)
	ioC.oldTermState = nil
	return err
}

func (ioC *ioContext) redirectStdin(pty *os.File, stdinStr string, statusChannel chan ProcessStatus) error {
	url, err := url.Parse(stdinStr)
	if err != nil {
		return err
	}
	if url.Path == "os.Stdin" {
		//We don't need to do anything here
	} else if url.Scheme == "tcp" {
		conn, err := net.Dial("tcp", url.Host+url.Path)
		if err != nil {
			return err
		}
		//Directly copy from the connection to the pty. Escape chars won't be available
		go func() {
			io.Copy(pty, conn)
			//When the remote stdin closes, terminate the process through the status Channel
			statusChannel <- ProcessStatus{Status: PROCESS_STOPPED, Err: errors.New("Remote stdin closed")}
		}()
	} else {
		//default case, the protocol is not supported
		return errors.New("The protocol " + url.Scheme + " is not supported")
	}
	ioC.stdinOutput = os.Stdin

	//Set up the tty
	ioC.oldTermState, err = terminal.MakeRaw(int(ioC.stdinOutput.Fd()))
	if err != nil {
		return errors.New("Can't create terminal:" + err.Error())
	}
	ioC.term = terminal.NewTerminal(ioC.stdinOutput, "")
	cb := func(s string, i int, r rune) (string, int, bool) {
		car := []byte{byte(r)}
		ioC.term.Write(car)
		return s, i, false
	}
	ioC.term.AutoCompleteCallback = cb

	//Copy everything from os.Stdin to the pty
	go io.Copy(pty, ioC.stdinOutput)

	return nil
}

func (ioC *ioContext) redirectStdout(pty *os.File, stdout, logPrefix, logRotation, logColor string,
	statusChannel chan ProcessStatus, eofChannel chan bool) error {
	url, err := url.Parse(stdout)
	if err != nil {
		return err
	}
	ioC.log, err = newLogger(*url, logPrefix, logRotation, statusChannel)
	if err != nil {
		return err
	}
	go ioC.log.startCopy(pty, eofChannel, ioC, logColor)

	return nil
}

func (ioC *ioContext) setTerminalColor(color string) error {
	var err error
	switch color {
	case "red":
		_, err = ioC.term.Write(ioC.term.Escape.Red)
	case "green":
		_, err = ioC.term.Write(ioC.term.Escape.Green)
	case "blue":
		_, err = ioC.term.Write(ioC.term.Escape.Blue)
	case "yellow":
		_, err = ioC.term.Write(ioC.term.Escape.Yellow)
	case "magenta":
		_, err = ioC.term.Write(ioC.term.Escape.Magenta)
	case "cyan":
		_, err = ioC.term.Write(ioC.term.Escape.Cyan)
	case "white":
		_, err = ioC.term.Write(ioC.term.Escape.White)
	default:
		_, err = ioC.term.Write(ioC.term.Escape.Black)
	}
	return err
}

func (ioC *ioContext) resetTerminal() error {
	var err error
	_, err = ioC.term.Write(ioC.term.Escape.Reset)
	return err
}
<|endoftext|>


<commit_before>package main

import (
	"github.com/jamesandariese/issh"
	"flag"
	"bytes"
	"regexp"
	"strconv"
	"fmt"
	"os"
)

var user_host_port_re, _ = regexp.Compile("(([^@]+)@)?" +
	"([a-zA-Z0-9.-]+)" +
	"(:(6553[0-5]|" +
	"655[0-2][0-9]|" +
	"65[0-4][0-9][0-9]|" +
	"6[0-4][0-9][0-9][0-9]|" +
	"[1-5][0-9]{0,4}))?")

func parseUserHostPort(str string) (user, host string, port int) {
	matches := user_host_port_re.FindStringSubmatch(str)
	user = matches[2]
	host = matches[3]
	port, _ = strconv.Atoi(matches[5])
	return
}

var show_key = flag.Bool("K", false, "Display the public key associated with the provided arguments")

func main() {
	flag.Parse()
	if *show_key {
		if flag.NArg() < 1 {
			flag.Usage()
			os.Exit(1)
		}
		for _, seed := range flag.Args() {
			key, err := issh.GetAuthorizedKey(seed)
			if err != nil {
				panic("Failed to create a key: " + err.Error())
			}
			fmt.Printf("public key for \"%s\"\n" +
				"command=\"exit 1\",no-port-forwarding,no-X11-forwarding,no-pty %s " +
				"issh generated from seed: '%s'\n",
				seed, bytes.TrimRight(key, "\r\n \t"), seed);
		}
		return
	}

	if flag.NArg() != 2 {
		flag.Usage()
		os.Exit(1)
	}

	user, host, port := parseUserHostPort(flag.Arg(1))
	stdout, exitcode, err := issh.Run(user, host, uint16(port), flag.Arg(0))
	if err != nil {
		panic("Failed to execute remote command: " + err.Error())
	}

	os.Stdout.Write(stdout)
	os.Exit(exitcode)
}
<commit_msg>cleaned up the user host port code<commit_after>package main

import (
	"github.com/jamesandariese/issh"
	"flag"
	"bytes"
	"regexp"
	"strconv"
	"fmt"
	"os"
)

var user_host_port_re, _ = regexp.Compile("(([^@]+)@)?" +
	"([a-zA-Z0-9.-]+)" +
	"(:(6553[0-5]|" +
	"655[0-2][0-9]|" +
	"65[0-4][0-9][0-9]|" +
	"6[0-4][0-9][0-9][0-9]|" +
	"[1-5][0-9]{0,4}))?")

func parseUserHostPort(str string) (user, host string, port uint16) {
        // should we allow people to use a space as a username?
        // is that valuable?  not really but I don't want to change
        // the char class in the regex and inconsistency is terrible
        // so the only invalid username in issh will be anything with
        // @ in it.

	// defaults
	user = "root"
        port = 22

	matches := user_host_port_re.FindStringSubmatch(str)

        if len(matches[2]) > 0 {
            user = matches[2]
        }

	host = matches[3]

        // the port can only be a valid uint16 but go is a bit set in its ways already
        if len(matches[5]) > 0 {
	    portint, _ := strconv.Atoi(matches[5])
            port = uint16(portint)
        }
	return
}

var show_key = flag.Bool("K", false, "Display the public key associated with the provided arguments")

func main() {
	flag.Parse()
	if *show_key {
		if flag.NArg() < 1 {
			flag.Usage()
			os.Exit(1)
		}
		for _, seed := range flag.Args() {
			key, err := issh.GetAuthorizedKey(seed)
			if err != nil {
				panic("Failed to create a key: " + err.Error())
			}
			fmt.Printf("public key for \"%s\"\n" +
				"command=\"exit 1\",no-port-forwarding,no-X11-forwarding,no-pty %s " +
				"issh generated from seed: '%s'\n",
				seed, bytes.TrimRight(key, "\r\n \t"), seed);
		}
		return
	}

	if flag.NArg() != 2 {
		flag.Usage()
		os.Exit(1)
	}

	user, host, port := parseUserHostPort(flag.Arg(1))
	stdout, exitcode, err := issh.Run(user, host, port, flag.Arg(0))
	if err != nil {
		panic("Failed to execute remote command: " + err.Error())
	}

	os.Stdout.Write(stdout)
	os.Exit(exitcode)
}
<|endoftext|>


<commit_before>package itau

import (
	"errors"
	"strings"

	. "github.com/PMoneda/flow"
	"github.com/mundipagg/boleto-api/config"
	"github.com/mundipagg/boleto-api/log"
	"github.com/mundipagg/boleto-api/metrics"
	"github.com/mundipagg/boleto-api/models"
	"github.com/mundipagg/boleto-api/tmpl"
	"github.com/mundipagg/boleto-api/util"
	"github.com/mundipagg/boleto-api/validations"
)

type bankItau struct {
	validate *models.Validator
	log      *log.Log
}

func New() bankItau {
	b := bankItau{
		validate: models.NewValidator(),
		log:      log.CreateLog(),
	}
	b.validate.Push(validations.ValidateAmount)
	b.validate.Push(validations.ValidateExpireDate)
	b.validate.Push(validations.ValidateBuyerDocumentNumber)
	b.validate.Push(validations.ValidateRecipientDocumentNumber)
	b.validate.Push(itauValidateAccount)
	b.validate.Push(itauValidateAgency)
	return b
}

//Log retorna a referencia do log
func (b bankItau) Log() *log.Log {
	return b.log
}

func (b bankItau) GetTicket(boleto *models.BoletoRequest) (string, error) {
	timing := metrics.GetTimingMetrics()
	pipe := NewFlow()
	url := config.Get().URLTicketItau
	pipe.From("message://?source=inline", boleto, getRequestTicket(), tmpl.GetFuncMaps())
	pipe.To("logseq://?type=request&url="+url, b.log)
	duration := util.Duration(func() {
		pipe.To(url, map[string]string{"method": "POST", "insecureSkipVerify": "true"})
	})
	timing.Push("itau-get-ticket-boleto-time", duration.Seconds())
	pipe.To("logseq://?type=response&url="+url, b.log)
	ch := pipe.Choice()
	ch.When(Header("status").IsEqualTo("200"))
	ch.To("transform://?format=json", getTicketResponse(), `{{.access_token}}`, tmpl.GetFuncMaps())
	ch.When(Header("status").IsEqualTo("400"))
	ch.To("transform://?format=json", getTicketResponse(), `{{.errorMessage}}`, tmpl.GetFuncMaps())
	ch.To("set://?prop=body", errors.New(pipe.GetBody().(string)))
	ch.When(Header("status").IsEqualTo("403"))
	ch.To("set://?prop=body", errors.New("403 Forbidden"))
	ch.When(Header("status").IsEqualTo("500"))
	ch.To("transform://?format=json", getTicketErrorResponse(), `{{.errorMessage}}`, tmpl.GetFuncMaps())
	ch.To("set://?prop=body", errors.New(pipe.GetBody().(string)))
	ch.Otherwise()
	ch.To("logseq://?type=request&url="+url, b.log).To("print://?msg=${body}").To("set://?prop=body", errors.New("integration error"))
	switch t := pipe.GetBody().(type) {
	case string:
		return t, nil
	case error:
		return "", t
	}
	return "", nil
}

func (b bankItau) RegisterBoleto(input *models.BoletoRequest) (models.BoletoResponse, error) {
	timing := metrics.GetTimingMetrics()
	itauURL := config.Get().URLRegisterBoletoItau
	fromResponse := getResponseItau()
	fromResponseError := getResponseErrorItau()
	toAPI := getAPIResponseItau()
	inputTemplate := getRequestItau()
	exec := NewFlow().From("message://?source=inline", input, inputTemplate, tmpl.GetFuncMaps())
	exec.To("logseq://?type=request&url="+itauURL, b.log)
	duration := util.Duration(func() {
		exec.To(itauURL, map[string]string{"method": "POST", "insecureSkipVerify": "true"})
	})
	timing.Push("itau-register-boleto-time", duration.Seconds())
	exec.To("logseq://?type=response&url="+itauURL, b.log)

	ch := exec.Choice()
	ch.When(Header("status").IsEqualTo("200"))
	ch.To("transform://?format=json", fromResponse, toAPI, tmpl.GetFuncMaps())
	ch.To("unmarshall://?format=json", new(models.BoletoResponse))

	headerMap := exec.GetHeader()

	if status, exist := headerMap["Content-Type"]; exist && strings.Contains(status, "text/html") {
		exec.To("set://?prop=body", `{"codigo":"501","mensagem":"Error"}`)
		ch.When(Header("Content-Type").IsEqualTo(status))
		ch.To("transform://?format=json", fromResponseError, toAPI, tmpl.GetFuncMaps())
	} else if status, exist = headerMap["status"]; exist && status != "200" {
		ch.When(Header("status").IsEqualTo(status))
		ch.To("transform://?format=json", fromResponseError, toAPI, tmpl.GetFuncMaps())
		ch.To("unmarshall://?format=json", new(models.BoletoResponse))
	}

	ch.Otherwise()
	ch.To("logseq://?type=response&url="+itauURL, b.log).To("apierro://")

	switch t := exec.GetBody().(type) {
	case *models.BoletoResponse:
		return *t, nil
	case error:
		return models.BoletoResponse{}, t
	}
	return models.BoletoResponse{}, models.NewInternalServerError("MP500", "Internal error")
}

func (b bankItau) ProcessBoleto(boleto *models.BoletoRequest) (models.BoletoResponse, error) {
	errs := b.ValidateBoleto(boleto)
	if len(errs) > 0 {
		return models.BoletoResponse{Errors: errs}, nil
	}
	if ticket, err := b.GetTicket(boleto); err != nil {
		return models.BoletoResponse{Errors: errs}, err
	} else {
		boleto.Authentication.AuthorizationToken = ticket
	}
	return b.RegisterBoleto(boleto)
}

func (b bankItau) ValidateBoleto(boleto *models.BoletoRequest) models.Errors {
	return models.Errors(b.validate.Assert(boleto))
}

//GetBankNumber retorna o codigo do banco
func (b bankItau) GetBankNumber() models.BankNumber {
	return models.Itau
}

func (b bankItau) GetBankNameIntegration() string {
	return "Itau"
}
<commit_msg>:sparkles: Implementa timeout Itau<commit_after>package itau

import (
	"errors"
	"strings"

	. "github.com/PMoneda/flow"
	"github.com/mundipagg/boleto-api/config"
	"github.com/mundipagg/boleto-api/log"
	"github.com/mundipagg/boleto-api/metrics"
	"github.com/mundipagg/boleto-api/models"
	"github.com/mundipagg/boleto-api/tmpl"
	"github.com/mundipagg/boleto-api/util"
	"github.com/mundipagg/boleto-api/validations"
)

type bankItau struct {
	validate *models.Validator
	log      *log.Log
}

func New() bankItau {
	b := bankItau{
		validate: models.NewValidator(),
		log:      log.CreateLog(),
	}
	b.validate.Push(validations.ValidateAmount)
	b.validate.Push(validations.ValidateExpireDate)
	b.validate.Push(validations.ValidateBuyerDocumentNumber)
	b.validate.Push(validations.ValidateRecipientDocumentNumber)
	b.validate.Push(itauValidateAccount)
	b.validate.Push(itauValidateAgency)
	return b
}

//Log retorna a referencia do log
func (b bankItau) Log() *log.Log {
	return b.log
}

func (b bankItau) GetTicket(boleto *models.BoletoRequest) (string, error) {
	timing := metrics.GetTimingMetrics()
	pipe := NewFlow()
	url := config.Get().URLTicketItau
	pipe.From("message://?source=inline", boleto, getRequestTicket(), tmpl.GetFuncMaps())
	pipe.To("logseq://?type=request&url="+url, b.log)
	duration := util.Duration(func() {
		pipe.To(url, map[string]string{"method": "POST", "insecureSkipVerify": "true", "timeout": config.Get().TimeoutToken})
	})
	timing.Push("itau-get-ticket-boleto-time", duration.Seconds())
	pipe.To("logseq://?type=response&url="+url, b.log)
	ch := pipe.Choice()
	ch.When(Header("status").IsEqualTo("200"))
	ch.To("transform://?format=json", getTicketResponse(), `{{.access_token}}`, tmpl.GetFuncMaps())
	ch.When(Header("status").IsEqualTo("400"))
	ch.To("transform://?format=json", getTicketResponse(), `{{.errorMessage}}`, tmpl.GetFuncMaps())
	ch.To("set://?prop=body", errors.New(pipe.GetBody().(string)))
	ch.When(Header("status").IsEqualTo("403"))
	ch.To("set://?prop=body", errors.New("403 Forbidden"))
	ch.When(Header("status").IsEqualTo("500"))
	ch.To("transform://?format=json", getTicketErrorResponse(), `{{.errorMessage}}`, tmpl.GetFuncMaps())
	ch.To("set://?prop=body", errors.New(pipe.GetBody().(string)))
	ch.Otherwise()
	ch.To("logseq://?type=request&url="+url, b.log).To("print://?msg=${body}").To("set://?prop=body", errors.New("integration error"))
	switch t := pipe.GetBody().(type) {
	case string:
		return t, nil
	case error:
		return "", t
	}
	return "", nil
}

func (b bankItau) RegisterBoleto(input *models.BoletoRequest) (models.BoletoResponse, error) {
	timing := metrics.GetTimingMetrics()
	itauURL := config.Get().URLRegisterBoletoItau
	fromResponse := getResponseItau()
	fromResponseError := getResponseErrorItau()
	toAPI := getAPIResponseItau()
	inputTemplate := getRequestItau()
	exec := NewFlow().From("message://?source=inline", input, inputTemplate, tmpl.GetFuncMaps())
	exec.To("logseq://?type=request&url="+itauURL, b.log)
	duration := util.Duration(func() {
		exec.To(itauURL, map[string]string{"method": "POST", "insecureSkipVerify": "true", "timeout": config.Get().TimeoutRegister})
	})
	timing.Push("itau-register-boleto-time", duration.Seconds())
	exec.To("logseq://?type=response&url="+itauURL, b.log)

	ch := exec.Choice()
	ch.When(Header("status").IsEqualTo("200"))
	ch.To("transform://?format=json", fromResponse, toAPI, tmpl.GetFuncMaps())
	ch.To("unmarshall://?format=json", new(models.BoletoResponse))

	headerMap := exec.GetHeader()

	if status, exist := headerMap["Content-Type"]; exist && strings.Contains(status, "text/html") {
		exec.To("set://?prop=body", `{"codigo":"501","mensagem":"Error"}`)
		ch.When(Header("Content-Type").IsEqualTo(status))
		ch.To("transform://?format=json", fromResponseError, toAPI, tmpl.GetFuncMaps())
	} else if status, exist = headerMap["status"]; exist && status != "200" {
		ch.When(Header("status").IsEqualTo(status))
		ch.To("transform://?format=json", fromResponseError, toAPI, tmpl.GetFuncMaps())
		ch.To("unmarshall://?format=json", new(models.BoletoResponse))
	}

	ch.Otherwise()
	ch.To("logseq://?type=response&url="+itauURL, b.log).To("apierro://")

	switch t := exec.GetBody().(type) {
	case *models.BoletoResponse:
		return *t, nil
	case error:
		return models.BoletoResponse{}, t
	}
	return models.BoletoResponse{}, models.NewInternalServerError("MP500", "Internal error")
}

func (b bankItau) ProcessBoleto(boleto *models.BoletoRequest) (models.BoletoResponse, error) {
	errs := b.ValidateBoleto(boleto)
	if len(errs) > 0 {
		return models.BoletoResponse{Errors: errs}, nil
	}
	if ticket, err := b.GetTicket(boleto); err != nil {
		return models.BoletoResponse{Errors: errs}, err
	} else {
		boleto.Authentication.AuthorizationToken = ticket
	}
	return b.RegisterBoleto(boleto)
}

func (b bankItau) ValidateBoleto(boleto *models.BoletoRequest) models.Errors {
	return models.Errors(b.validate.Assert(boleto))
}

//GetBankNumber retorna o codigo do banco
func (b bankItau) GetBankNumber() models.BankNumber {
	return models.Itau
}

func (b bankItau) GetBankNameIntegration() string {
	return "Itau"
}
<|endoftext|>


<commit_before>package util

import (
	"fmt"
	"io"
	"strings"

	"github.com/glycerine/rbuf"
	"github.com/orktes/orlang/parser/ast"
	"github.com/orktes/orlang/parser/parser"
)

type HistoryReader struct {
	io.Reader
	column int
	line   int
	buf    *rbuf.FixedSizeRingBuf
}

func NewHistoryReader(in io.Reader) (r *HistoryReader) {
	r = &HistoryReader{
		buf: rbuf.NewFixedSizeRingBuf(1024 * 5), // TODO figure out proper size
	}
	r.Reader = io.TeeReader(in, r)
	return
}

func (hr *HistoryReader) Write(p []byte) (n int, err error) {
	for _, b := range p {
		hr.column++
		if b == byte('\n') {
			hr.line++
			hr.column = 0
		}
	}

	return hr.buf.Write(p)
}

func (hr *HistoryReader) FindLineForPosition(pos ast.Position) string {
	line := hr.line
	bytes := hr.buf.Bytes()
	correctLine := false
	correctLineEndIndex := 0

	for i := len(bytes) - 1; i >= 0; i-- {
		b := bytes[i]
		if correctLine == false && line == pos.Line {
			correctLineEndIndex = i + 1
			correctLine = true
		}
		if b == '\n' {
			if correctLine {
				return string(bytes[i+1 : correctLineEndIndex])
			}
			line--
		}
	}

	return ""
}

func (hr *HistoryReader) FormatParseError(filePath string, pos ast.Position, err string) string {
	line := hr.FindLineForPosition(pos)
	if line != "" {
		return fmt.Sprintf(
			`%s:%d:%d
----------------------------------------------------------
%s
%s
%s
----------------------------------------------------------`, filePath, pos.Line+1, pos.Column+1, strings.Replace(line, "\t", " ", -1), pointer(pos.Column), pad(pos.Column-int(len(err)/2), err))
	}
	return fmt.Sprintf("%s %#v %s", filePath, pos, err)
}

func (hr *HistoryReader) FormatError(filePath string, err error) string {
	if posErr, ok := err.(*parser.PosError); ok && hr != nil {
		return hr.FormatParseError(filePath, posErr.Position, posErr.Message)
	}
	return fmt.Sprintf("%s:%s", filePath, err.Error())
}

func pad(padding int, str string) (res string) {
	if padding < 0 {
		padding = 0
	}
	res = strings.Repeat(" ", padding)
	return res + str
}

func pointer(padding int) (res string) {
	return pad(padding, "^")
}
<commit_msg>Code style<commit_after>package util

import (
	"fmt"
	"io"
	"strings"

	"github.com/glycerine/rbuf"
	"github.com/orktes/orlang/parser/ast"
	"github.com/orktes/orlang/parser/parser"
)

type HistoryReader struct {
	io.Reader
	column int
	line   int
	buf    *rbuf.FixedSizeRingBuf
}

func NewHistoryReader(in io.Reader) (r *HistoryReader) {
	r = &HistoryReader{
		buf: rbuf.NewFixedSizeRingBuf(1024 * 5), // TODO figure out proper size
	}
	r.Reader = io.TeeReader(in, r)
	return
}

func (hr *HistoryReader) Write(p []byte) (n int, err error) {
	for _, b := range p {
		hr.column++
		if b == byte('\n') {
			hr.line++
			hr.column = 0
		}
	}

	return hr.buf.Write(p)
}

func (hr *HistoryReader) FindLineForPosition(pos ast.Position) string {
	line := hr.line
	bytes := hr.buf.Bytes()
	correctLine := false
	correctLineEndIndex := 0

	for i := len(bytes) - 1; i >= 0; i-- {
		b := bytes[i]
		if correctLine == false && line == pos.Line {
			correctLineEndIndex = i + 1
			correctLine = true
		}
		if b == '\n' || i == 0 {
			if correctLine {
				if i != 0 {
					i++
				}
				return string(bytes[i:correctLineEndIndex])
			}
			line--
		}
	}

	return ""
}

func (hr *HistoryReader) FormatParseError(filePath string, pos ast.Position, err string) string {
	line := hr.FindLineForPosition(pos)
	if line != "" {
		return fmt.Sprintf(
			`%s:%d:%d
----------------------------------------------------------
%s
%s
%s
----------------------------------------------------------`, filePath, pos.Line+1, pos.Column+1, strings.Replace(line, "\t", " ", -1), pointer(pos.Column), pad(pos.Column-int(len(err)/2), err))
	}
	return fmt.Sprintf("%s %#v %s", filePath, pos, err)
}

func (hr *HistoryReader) FormatError(filePath string, err error) string {
	if posErr, ok := err.(*parser.PosError); ok && hr != nil {
		return hr.FormatParseError(filePath, posErr.Position, posErr.Message)
	}
	return fmt.Sprintf("%s:%s", filePath, err.Error())
}

func pad(padding int, str string) (res string) {
	if padding < 0 {
		padding = 0
	}
	res = strings.Repeat(" ", padding)
	return res + str
}

func pointer(padding int) (res string) {
	return pad(padding, "^")
}
<|endoftext|>


<commit_before>/*
Copyright 2018 Google Inc.

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

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

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

package endpoints

import (
	"golang.org/x/net/context"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"os"
	"strings"
	"time"

	"google.golang.org/appengine"
	"google.golang.org/appengine/log"
	"cloud.google.com/go/pubsub"
	"github.com/google/splice/appengine/server"
	basic "github.com/google/splice/appengine/validators"
	"github.com/google/splice/models"
)

// AttendedRequestHandler implements http.Handler for user interactive joins.
type AttendedRequestHandler struct{}

func (ah AttendedRequestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)
	checks, err := validatorsNewAttended()
	if err != nil {
		log.Errorf(ctx, "Validator setup returned %v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	requestResponse(ctx, w, r, checks)
}

// UnattendedRequestHandler implements http.Handler for unattended joins.
type UnattendedRequestHandler struct{}

func (uh UnattendedRequestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)
	checks, err := validatorsNewUnattended()
	if err != nil {
		log.Errorf(ctx, "Validator setup returned %v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	requestResponse(ctx, w, r, checks)
}

// requestResponse performs necessary cleanup and provides a response to the client.
func requestResponse(ctx context.Context, w http.ResponseWriter, r *http.Request, checks []basic.Validator) {
	resp := ProcessRequest(ctx, w, r, checks)
	if resp.ErrorCode != server.StatusSuccess {
		log.Warningf(ctx, "could not process request %v", resp)
	}

	jsonResponse, err := json.Marshal(resp)
	if err != nil {
		log.Errorf(ctx, "json.Marshal(%v) failed: %v", resp, err)
		http.Error(
			w,
			fmt.Sprintf("json.Marshal(%v) failed: %v", resp, err),
			http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	w.Write(jsonResponse)

	if resp.ErrorCode == server.StatusSuccess {
		log.Infof(ctx, "successfully processed requestID '%q'", resp.RequestID)
	}
}

// ProcessRequest takes a models.Request that is provided by the client,
// and validates it. A response is provided using models.Response.
func ProcessRequest(ctx context.Context, w http.ResponseWriter, r *http.Request, checks []basic.Validator) models.Response {
	request, code, err := unmarshalRequest(r)
	if err != nil {
		return models.Response{
			ErrorCode: code,
			Status:    err.Error(),
		}
	}

	if err := verifyCert(ctx, request.ClientID, r); err != nil {
		return models.Response{
			ErrorCode: server.StatusInvalidCertError,
			Status:    err.Error(),
		}
	}

	// Run this request through all validators
	for _, c := range checks {
		status, err := c.Check(ctx, &request)
		if err != nil {
			return models.Response{
				ErrorCode: status,
				Status:    err.Error(),
			}
		}
	}

	// New requests require a cryptographically secure requestID
	// of a sufficient length. Existing requests re-use their
	// existing requestID.
	//
	request.RequestID, err = generateReqID(reqIDLen)
	if err != nil {
		return models.Response{
			ErrorCode: server.StatusReqProcessingError,
			Status:    fmt.Sprintf("generateReqID(%d) returned %v", reqIDLen, err),
		}
	}

	request.AcceptTime = time.Now()
	request.Status = models.RequestStatusAccepted

	// Initialize an empty datastore client at the appropriate scope.
	dc := &Client{Req: &models.Request{}}
	log.Infof(ctx, "AttemptReuse returned %t in the App Engine request", request.AttemptReuse)
	if useDatastore {
		var status server.StatusCode
		dc, status, err = NewClient(ctx, &request)
		if err != nil {
			return models.Response{
				ErrorCode: status,
				Status:    err.Error(),
			}
		}
		defer dc.Close()

		if err = dc.StartTx(ctx); err != nil {
			return models.Response{
				ErrorCode: server.StatusDatastoreTxCreateError,
				Status:    err.Error(),
			}
		}
		defer dc.RollbackTx()

		if status, err := dc.Save(ctx); err != nil {
			return models.Response{
				ErrorCode: status,
				Status:    err.Error(),
			}
		}

		if err := dc.CommitTx(); err != nil {
			return models.Response{
				ErrorCode: server.StatusDatastoreTxCommitError,
				Status:    err.Error(),
			}
		}

		// Failure to cleanup orphans should be reported
		// but should not stop processing.
		if err := cleanupOrphans(ctx, dc); err != nil {
			log.Warningf(ctx, "cleanupOrphans failed with %v ", err)
		}
	}

	if usePubsub {
		if err := publishRequest(ctx, request.RequestID); err != nil {
			return models.Response{
				ErrorCode: server.StatusPubsubFailure,
				Status:    err.Error(),
			}
		}
	}

	return models.Response{
		Status:    models.RequestStatusAccepted,
		RequestID: request.RequestID,
		ErrorCode: server.StatusSuccess,
	}
}

// GenerateReqID returns a URL-safe, base64 encoded
// securely generated random requestID to identify a request.
// It takes as input the length in bytes of the token to be
// generated. E.G. 64 bytes (512 bit), or 128 bytes (1024 bit).
func generateReqID(n uint) (string, error) {
	if n <= 0 {
		return "", fmt.Errorf("invalid length %d requested", n)
	}
	rand.Seed(time.Now().UnixNano())
	b := make([]byte, n)
	_, err := rand.Read(b)
	if err != nil {
		return "", fmt.Errorf("rand.Read returned %v", err)
	}
	return base64.URLEncoding.EncodeToString(b), nil
}

// unmarshalRequest takes a raw inbound request and returns
// a models.Request for processing
func unmarshalRequest(r *http.Request) (models.Request, server.StatusCode, error) {
	var clientRequest models.ClientRequest

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return models.Request{},
			server.StatusRequestUnreadable,
			errors.New("unable to read HTTP request body")
	}

	if len(body) == 0 {
		return models.Request{},
			server.StatusJSONEmpty,
			errors.New("empty HTTP JSON request body")
	}

	if err = json.Unmarshal(body, &clientRequest); err != nil {
		return models.Request{},
			server.StatusJSONUmarshalError,
			errors.New("unable to unmarshal JSON request")
	}

	return models.Request{
			Hostname:      clientRequest.Hostname,
			ClientID:      clientRequest.ClientID,
			ClientCert:    clientRequest.ClientCert,
			GCEMetadata:   clientRequest.GCEMetadata,
			GeneratorID:   clientRequest.GeneratorID,
			GeneratorData: clientRequest.GeneratorData,
		},
		server.StatusSuccess,
		nil
}

// cleanupOrphans looks for requests that are too old or were
// tried once and not re-tried and makes sure that they are not
// left in an indeterminate state.
func cleanupOrphans(ctx context.Context, dc *Client) error {
	// Orphans older than 24 hours are cleaned up.
	olderThan := 24 * time.Hour

	// Check the following statuses for orphaned entries.
	s := []string{
		models.RequestStatusAccepted,
		models.RequestStatusProcessing,
		models.RequestStatusCompleted,
	}

	if err := dc.StartTx(ctx); err != nil {
		return fmt.Errorf("dc.StartTx returned %v", err)
	}
	defer dc.RollbackTx()

	// Cleanup requests by type because the datastore GetAll
	// func contcatenates filters using AND.
	for _, kind := range s {
		keys, requests, err := dc.FindOrphans(ctx, olderThan, kind)
		if err != nil {
			return fmt.Errorf("FindOrphans(%d, %s) = %v", olderThan, kind, err)
		}

		if len(requests) > 0 {
			for i, orphan := range requests {
				orphan.Status = models.RequestStatusFailed
				dc.Req = nil
				dc.Req = &orphan
				dc.Keys[0] = keys[i]
				if _, err = dc.Save(ctx); err != nil {
					return err
				}
				log.Infof(ctx, "cleaned up orphan with reqID = %q ", orphan.RequestID)
			}
		}
	}

	if err := dc.CommitTx(); err != nil {
		return fmt.Errorf("dc.CommitTx returned %v", err)
	}

	return nil
}

// Publishes a request to the pubsub channel.
func publishRequest(ctx context.Context, reqID string) error {
	envProject := appengine.AppID(ctx)
	envTopic := os.Getenv("PUBSUB_TOPIC")
	if envTopic == "" {
		return errors.New("PUBSUB_TOPIC environment variable not set")
	}

	ps, err := pubsub.NewClient(ctx, envProject)
	if err != nil {
		return fmt.Errorf("pubsub.NewClient(%q) returned: %v", envProject, err)
	}

	// Create topic if it doesn't exist.
	_, err = ps.CreateTopic(ctx, envTopic)
	if err != nil && !strings.Contains(err.Error(), "AlreadyExists") {
		return fmt.Errorf("failed to create topic %q: %v", envTopic, err)
	}

	// CreateTopic doesn't return the topic if it already exists
	topic := ps.Topic(envTopic)
	defer topic.Stop()
	res := topic.Publish(ctx, &pubsub.Message{Data: []byte(reqID)})

	msgID, err := res.Get(ctx)
	if err != nil {
		return fmt.Errorf("topic.Publish error publishing to topic %s: %v, %v", envTopic, res, err)
	}

	log.Infof(ctx, "request id %q published with msg id %q", reqID, msgID)
	return nil
}
<commit_msg>Remove CreateTopic which causes errors in the cloud console once the topic exists.<commit_after>/*
Copyright 2018 Google Inc.

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

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

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

package endpoints

import (
	"golang.org/x/net/context"
	"encoding/base64"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"math/rand"
	"net/http"
	"os"
	"time"

	"google.golang.org/appengine"
	"google.golang.org/appengine/log"
	"cloud.google.com/go/pubsub"
	"github.com/google/splice/appengine/server"
	basic "github.com/google/splice/appengine/validators"
	"github.com/google/splice/models"
)

// AttendedRequestHandler implements http.Handler for user interactive joins.
type AttendedRequestHandler struct{}

func (ah AttendedRequestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)
	checks, err := validatorsNewAttended()
	if err != nil {
		log.Errorf(ctx, "Validator setup returned %v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	requestResponse(ctx, w, r, checks)
}

// UnattendedRequestHandler implements http.Handler for unattended joins.
type UnattendedRequestHandler struct{}

func (uh UnattendedRequestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	ctx := appengine.NewContext(r)
	checks, err := validatorsNewUnattended()
	if err != nil {
		log.Errorf(ctx, "Validator setup returned %v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	requestResponse(ctx, w, r, checks)
}

// requestResponse performs necessary cleanup and provides a response to the client.
func requestResponse(ctx context.Context, w http.ResponseWriter, r *http.Request, checks []basic.Validator) {
	resp := ProcessRequest(ctx, w, r, checks)
	if resp.ErrorCode != server.StatusSuccess {
		log.Warningf(ctx, "could not process request %v", resp)
	}

	jsonResponse, err := json.Marshal(resp)
	if err != nil {
		log.Errorf(ctx, "json.Marshal(%v) failed: %v", resp, err)
		http.Error(
			w,
			fmt.Sprintf("json.Marshal(%v) failed: %v", resp, err),
			http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(http.StatusOK)
	w.Write(jsonResponse)

	if resp.ErrorCode == server.StatusSuccess {
		log.Infof(ctx, "successfully processed requestID '%q'", resp.RequestID)
	}
}

// ProcessRequest takes a models.Request that is provided by the client,
// and validates it. A response is provided using models.Response.
func ProcessRequest(ctx context.Context, w http.ResponseWriter, r *http.Request, checks []basic.Validator) models.Response {
	request, code, err := unmarshalRequest(r)
	if err != nil {
		return models.Response{
			ErrorCode: code,
			Status:    err.Error(),
		}
	}

	if err := verifyCert(ctx, request.ClientID, r); err != nil {
		return models.Response{
			ErrorCode: server.StatusInvalidCertError,
			Status:    err.Error(),
		}
	}

	// Run this request through all validators
	for _, c := range checks {
		status, err := c.Check(ctx, &request)
		if err != nil {
			return models.Response{
				ErrorCode: status,
				Status:    err.Error(),
			}
		}
	}

	// New requests require a cryptographically secure requestID
	// of a sufficient length. Existing requests re-use their
	// existing requestID.
	//
	request.RequestID, err = generateReqID(reqIDLen)
	if err != nil {
		return models.Response{
			ErrorCode: server.StatusReqProcessingError,
			Status:    fmt.Sprintf("generateReqID(%d) returned %v", reqIDLen, err),
		}
	}

	request.AcceptTime = time.Now()
	request.Status = models.RequestStatusAccepted

	// Initialize an empty datastore client at the appropriate scope.
	dc := &Client{Req: &models.Request{}}
	log.Infof(ctx, "AttemptReuse returned %t in the App Engine request", request.AttemptReuse)
	if useDatastore {
		var status server.StatusCode
		dc, status, err = NewClient(ctx, &request)
		if err != nil {
			return models.Response{
				ErrorCode: status,
				Status:    err.Error(),
			}
		}
		defer dc.Close()

		if err = dc.StartTx(ctx); err != nil {
			return models.Response{
				ErrorCode: server.StatusDatastoreTxCreateError,
				Status:    err.Error(),
			}
		}
		defer dc.RollbackTx()

		if status, err := dc.Save(ctx); err != nil {
			return models.Response{
				ErrorCode: status,
				Status:    err.Error(),
			}
		}

		if err := dc.CommitTx(); err != nil {
			return models.Response{
				ErrorCode: server.StatusDatastoreTxCommitError,
				Status:    err.Error(),
			}
		}

		// Failure to cleanup orphans should be reported
		// but should not stop processing.
		if err := cleanupOrphans(ctx, dc); err != nil {
			log.Warningf(ctx, "cleanupOrphans failed with %v ", err)
		}
	}

	if usePubsub {
		if err := publishRequest(ctx, request.RequestID); err != nil {
			return models.Response{
				ErrorCode: server.StatusPubsubFailure,
				Status:    err.Error(),
			}
		}
	}

	return models.Response{
		Status:    models.RequestStatusAccepted,
		RequestID: request.RequestID,
		ErrorCode: server.StatusSuccess,
	}
}

// GenerateReqID returns a URL-safe, base64 encoded
// securely generated random requestID to identify a request.
// It takes as input the length in bytes of the token to be
// generated. E.G. 64 bytes (512 bit), or 128 bytes (1024 bit).
func generateReqID(n uint) (string, error) {
	if n <= 0 {
		return "", fmt.Errorf("invalid length %d requested", n)
	}
	rand.Seed(time.Now().UnixNano())
	b := make([]byte, n)
	_, err := rand.Read(b)
	if err != nil {
		return "", fmt.Errorf("rand.Read returned %v", err)
	}
	return base64.URLEncoding.EncodeToString(b), nil
}

// unmarshalRequest takes a raw inbound request and returns
// a models.Request for processing
func unmarshalRequest(r *http.Request) (models.Request, server.StatusCode, error) {
	var clientRequest models.ClientRequest

	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return models.Request{},
			server.StatusRequestUnreadable,
			errors.New("unable to read HTTP request body")
	}

	if len(body) == 0 {
		return models.Request{},
			server.StatusJSONEmpty,
			errors.New("empty HTTP JSON request body")
	}

	if err = json.Unmarshal(body, &clientRequest); err != nil {
		return models.Request{},
			server.StatusJSONUmarshalError,
			errors.New("unable to unmarshal JSON request")
	}

	return models.Request{
			Hostname:      clientRequest.Hostname,
			ClientID:      clientRequest.ClientID,
			ClientCert:    clientRequest.ClientCert,
			GCEMetadata:   clientRequest.GCEMetadata,
			GeneratorID:   clientRequest.GeneratorID,
			GeneratorData: clientRequest.GeneratorData,
		},
		server.StatusSuccess,
		nil
}

// cleanupOrphans looks for requests that are too old or were
// tried once and not re-tried and makes sure that they are not
// left in an indeterminate state.
func cleanupOrphans(ctx context.Context, dc *Client) error {
	// Orphans older than 24 hours are cleaned up.
	olderThan := 24 * time.Hour

	// Check the following statuses for orphaned entries.
	s := []string{
		models.RequestStatusAccepted,
		models.RequestStatusProcessing,
		models.RequestStatusCompleted,
	}

	if err := dc.StartTx(ctx); err != nil {
		return fmt.Errorf("dc.StartTx returned %v", err)
	}
	defer dc.RollbackTx()

	// Cleanup requests by type because the datastore GetAll
	// func contcatenates filters using AND.
	for _, kind := range s {
		keys, requests, err := dc.FindOrphans(ctx, olderThan, kind)
		if err != nil {
			return fmt.Errorf("FindOrphans(%d, %s) = %v", olderThan, kind, err)
		}

		if len(requests) > 0 {
			for i, orphan := range requests {
				orphan.Status = models.RequestStatusFailed
				dc.Req = nil
				dc.Req = &orphan
				dc.Keys[0] = keys[i]
				if _, err = dc.Save(ctx); err != nil {
					return err
				}
				log.Infof(ctx, "cleaned up orphan with reqID = %q ", orphan.RequestID)
			}
		}
	}

	if err := dc.CommitTx(); err != nil {
		return fmt.Errorf("dc.CommitTx returned %v", err)
	}

	return nil
}

// Publishes a request to the pubsub channel.
func publishRequest(ctx context.Context, reqID string) error {
	envProject := appengine.AppID(ctx)
	envTopic := os.Getenv("PUBSUB_TOPIC")
	if envTopic == "" {
		return errors.New("PUBSUB_TOPIC environment variable not set")
	}

	ps, err := pubsub.NewClient(ctx, envProject)
	if err != nil {
		return fmt.Errorf("pubsub.NewClient(%q) returned: %v", envProject, err)
	}

	topic := ps.Topic(envTopic)
	defer topic.Stop()
	res := topic.Publish(ctx, &pubsub.Message{Data: []byte(reqID)})

	msgID, err := res.Get(ctx)
	if err != nil {
		return fmt.Errorf("topic.Publish error publishing to topic %s: %v, %v", envTopic, res, err)
	}

	log.Infof(ctx, "request id %q published with msg id %q", reqID, msgID)
	return nil
}
<|endoftext|>


<commit_before>package sensu

import (
	"os"
	"os/signal"
	"time"

	"github.com/upfluence/sensu-client-go/Godeps/_workspace/src/github.com/upfluence/goutils/log"
	"github.com/upfluence/sensu-client-go/Godeps/_workspace/src/github.com/upfluence/sensu-go/sensu/transport"
)

const (
	currentVersion    = "1.1.1"
	connectionTimeout = 5 * time.Second
)

type Client struct {
	Transport transport.Transport
	Config    *Config
}

func NewClient(transport transport.Transport, cfg *Config) *Client {
	client := Client{
		transport,
		cfg,
	}

	return &client
}

func (c *Client) buildProcessors() []Processor {
	processors := []Processor{NewKeepAlive(c)}

	for _, s := range c.Config.Client().Subscriptions {
		processors = append(processors, NewSubscriber(s, c))
	}

	for _, check := range c.Config.Checks() {
		if check.Standalone {
			processors = append(processors, NewStandalone(check, c))
		}
	}

	return processors
}

func (c *Client) Start() error {
	sig := make(chan os.Signal)
	signal.Notify(sig, os.Kill, os.Interrupt)

	for {
		c.Transport.Connect()

		for !c.Transport.IsConnected() {
			select {
			case <-time.After(connectionTimeout):
				c.Transport.Connect()
			case <-sig:
				return c.Transport.Close()
			}
		}

		processors := c.buildProcessors()
		for _, processor := range processors {
			go processor.Start()
		}

		select {
		case s := <-sig:
			log.Noticef("Signal %s received", s.String())

			for _, processor := range processors {
				processor.Close()
			}

			return c.Transport.Close()
		case <-c.Transport.GetClosingChan():
			log.Notice("Transport disconnected")

			for _, processor := range processors {
				processor.Close()
			}

			c.Transport.Close()
		}
	}
}
<commit_msg>Bump version to v1.2.0<commit_after>package sensu

import (
	"os"
	"os/signal"
	"time"

	"github.com/upfluence/sensu-client-go/Godeps/_workspace/src/github.com/upfluence/goutils/log"
	"github.com/upfluence/sensu-client-go/Godeps/_workspace/src/github.com/upfluence/sensu-go/sensu/transport"
)

const (
	currentVersion    = "1.2.0"
	connectionTimeout = 5 * time.Second
)

type Client struct {
	Transport transport.Transport
	Config    *Config
}

func NewClient(transport transport.Transport, cfg *Config) *Client {
	client := Client{
		transport,
		cfg,
	}

	return &client
}

func (c *Client) buildProcessors() []Processor {
	processors := []Processor{NewKeepAlive(c)}

	for _, s := range c.Config.Client().Subscriptions {
		processors = append(processors, NewSubscriber(s, c))
	}

	for _, check := range c.Config.Checks() {
		if check.Standalone {
			processors = append(processors, NewStandalone(check, c))
		}
	}

	return processors
}

func (c *Client) Start() error {
	sig := make(chan os.Signal)
	signal.Notify(sig, os.Kill, os.Interrupt)

	for {
		c.Transport.Connect()

		for !c.Transport.IsConnected() {
			select {
			case <-time.After(connectionTimeout):
				c.Transport.Connect()
			case <-sig:
				return c.Transport.Close()
			}
		}

		processors := c.buildProcessors()
		for _, processor := range processors {
			go processor.Start()
		}

		select {
		case s := <-sig:
			log.Noticef("Signal %s received", s.String())

			for _, processor := range processors {
				processor.Close()
			}

			return c.Transport.Close()
		case <-c.Transport.GetClosingChan():
			log.Notice("Transport disconnected")

			for _, processor := range processors {
				processor.Close()
			}

			c.Transport.Close()
		}
	}
}
<|endoftext|>


<commit_before>package server

import (
	"fmt"
	"log"
	"net/http"

	"github.com/sqs/mux"
	"sourcegraph.com/sourcegraph/go-vcs/vcs"
)

func (h *Handler) serveRepoMergeBase(w http.ResponseWriter, r *http.Request) error {
	v := mux.Vars(r)

	repo, cloneURL, done, err := h.getRepo(r)
	if err != nil {
		return err
	}
	defer done()

	if repo, ok := repo.(vcs.Merger); ok {
		a, b := vcs.CommitID(v["CommitIDA"]), vcs.CommitID(v["CommitIDB"])

		mb, err := repo.MergeBase(a, b)
		if err != nil {
			return err
		}

		var statusCode int
		if commitIDIsCanon(string(a)) && commitIDIsCanon(string(b)) {
			setLongCache(w)
			statusCode = http.StatusMovedPermanently
		} else {
			setShortCache(w)
			statusCode = http.StatusFound
		}
		http.Redirect(w, r, h.router.URLToRepoCommit(v["VCS"], cloneURL, mb).String(), statusCode)
		return nil
	}

	return &httpError{http.StatusNotImplemented, fmt.Errorf("Merger not yet implemented by %T", repo)}
}

func (h *Handler) serveRepoCrossRepoMergeBase(w http.ResponseWriter, r *http.Request) error {
	v := mux.Vars(r)

	repoA, cloneURLA, doneA, err := h.getRepo(r)
	if err != nil {
		return err
	}
	defer doneA()

	repoB, _, doneB, err := h.getRepoLabeled(r, "B")
	if err != nil {
		return err
	}
	defer doneB()

	log.Printf("repoA = %T %p", repoA, repoA)
	log.Printf("repoB = %T %p", repoB, repoB)

	if repoA, ok := repoA.(vcs.CrossRepoMerger); ok {
		a, b := vcs.CommitID(v["CommitIDA"]), vcs.CommitID(v["CommitIDB"])

		mb, err := repoA.CrossRepoMergeBase(a, repoB.(vcs.Repository), b)
		if err != nil {
			return err
		}

		var statusCode int
		if commitIDIsCanon(string(a)) && commitIDIsCanon(string(b)) {
			setLongCache(w)
			statusCode = http.StatusMovedPermanently
		} else {
			setShortCache(w)
			statusCode = http.StatusFound
		}
		http.Redirect(w, r, h.router.URLToRepoCommit(v["VCS"], cloneURLA, mb).String(), statusCode)
		return nil
	}

	return &httpError{http.StatusNotImplemented, fmt.Errorf("CrossRepoMerger not yet implemented by %T", repoA)}
}
<commit_msg>remove log<commit_after>package server

import (
	"fmt"
	"net/http"

	"github.com/sqs/mux"
	"sourcegraph.com/sourcegraph/go-vcs/vcs"
)

func (h *Handler) serveRepoMergeBase(w http.ResponseWriter, r *http.Request) error {
	v := mux.Vars(r)

	repo, cloneURL, done, err := h.getRepo(r)
	if err != nil {
		return err
	}
	defer done()

	if repo, ok := repo.(vcs.Merger); ok {
		a, b := vcs.CommitID(v["CommitIDA"]), vcs.CommitID(v["CommitIDB"])

		mb, err := repo.MergeBase(a, b)
		if err != nil {
			return err
		}

		var statusCode int
		if commitIDIsCanon(string(a)) && commitIDIsCanon(string(b)) {
			setLongCache(w)
			statusCode = http.StatusMovedPermanently
		} else {
			setShortCache(w)
			statusCode = http.StatusFound
		}
		http.Redirect(w, r, h.router.URLToRepoCommit(v["VCS"], cloneURL, mb).String(), statusCode)
		return nil
	}

	return &httpError{http.StatusNotImplemented, fmt.Errorf("Merger not yet implemented by %T", repo)}
}

func (h *Handler) serveRepoCrossRepoMergeBase(w http.ResponseWriter, r *http.Request) error {
	v := mux.Vars(r)

	repoA, cloneURLA, doneA, err := h.getRepo(r)
	if err != nil {
		return err
	}
	defer doneA()

	repoB, _, doneB, err := h.getRepoLabeled(r, "B")
	if err != nil {
		return err
	}
	defer doneB()

	if repoA, ok := repoA.(vcs.CrossRepoMerger); ok {
		a, b := vcs.CommitID(v["CommitIDA"]), vcs.CommitID(v["CommitIDB"])

		mb, err := repoA.CrossRepoMergeBase(a, repoB.(vcs.Repository), b)
		if err != nil {
			return err
		}

		var statusCode int
		if commitIDIsCanon(string(a)) && commitIDIsCanon(string(b)) {
			setLongCache(w)
			statusCode = http.StatusMovedPermanently
		} else {
			setShortCache(w)
			statusCode = http.StatusFound
		}
		http.Redirect(w, r, h.router.URLToRepoCommit(v["VCS"], cloneURLA, mb).String(), statusCode)
		return nil
	}

	return &httpError{http.StatusNotImplemented, fmt.Errorf("CrossRepoMerger not yet implemented by %T", repoA)}
}
<|endoftext|>