<commit_before>// Package apherror provides a consistent way to handler JSONAPI
// related http errors.
package apherror

import (
	"encoding/json"
	"net/http"
	"strconv"

	"github.com/spacemonkeygo/errors"
	"github.com/spacemonkeygo/errors/errhttp"
)

var (
	//HTTPError represents generic http errors
	Errhttp = errors.NewClass("HTTP Error", errors.NoCaptureStack())
	//ErrMessagingReply represents error in request reply messaging
	ErrMessagingReply = newErrorClass("messaging reply error", http.StatusInternalServerError)
	//ErrMessagingReq represents error in request reply messaging
	ErrMessagingReq = newErrorClass("messaging request error", http.StatusInternalServerError)
	//ErrMessagingSub represents error in publish subscribe messaging
	ErrMessagingSub = newErrorClass("messaging subscription error", http.StatusInternalServerError)
	//ErrMessagingPub represents error in publish subscribe messaging
	ErrMessagingPub = newErrorClass("messaging publication error", http.StatusInternalServerError)
	//ErrReqContext represents error in extracting context value from http request
	ErrReqContext = newErrorClass("Unable to retrieve context", http.StatusInternalServerError)
	//ErrOuthExchange represents error in exchanging code for token with oauth server
	ErrOauthExchange = newErrorClass("Unable to exchange token for code", http.StatusInternalServerError)
	//ErrUserRetrieval represents error in retrieving user information from oauth provider
	ErrUserRetrieval = newErrorClass("Unable to retrieve user information", http.StatusInternalServerError)
	//ErrDatabaseQuery represents database query related errors
	ErrDatabaseQuery = newErrorClass("Database query error", http.StatusInternalServerError)
	//ErrNotFound represents the absence of an HTTP resource
	ErrNotFound = newErrorClass("Resource not found", http.StatusNotFound)
	//ErrJSONEncoding represents any json encoding error
	ErrJSONEncoding = newErrorClass("Json encoding error", http.StatusInternalServerError)
	//ErrStructMarshal represents any error with marshalling structure
	ErrStructMarshal = newErrorClass("Structure marshalling error", http.StatusInternalServerError)
	// ErrJWTToken represents errors with jwt token
	ErrJWTToken = newErrorClass("Issue with jwt token", http.StatusInternalServerError)
	//ErrIncludeParam represents any error with invalid include query parameter
	ErrIncludeParam = newErrorClassWithParam("Invalid include query parameter", "include", http.StatusBadRequest)
	//ErrSparseFieldSets represents any error with invalid sparse fieldsets query parameter
	ErrSparseFieldSets = newErrorClassWithParam("Invalid sparse fieldsets query parameter", "fieldsets", http.StatusBadRequest)
	//ErrFilterParam represents any error with invalid filter query paramter
	ErrFilterParam = newErrorClassWithParam("Invalid filter query parameter", "filter", http.StatusBadRequest)
	//ErrNotAcceptable represents any error with wrong or inappropriate http Accept header
	ErrNotAcceptable = newErrorClass("Accept header is not acceptable", http.StatusNotAcceptable)
	//ErrUnsupportedMedia represents any error with unsupported media type in http header
	ErrUnsupportedMedia = newErrorClass("Media type is not supported", http.StatusUnsupportedMediaType)
	//ErrQueryParam represents any error with http query parameters
	ErrQueryParam = newErrorClass("Invalid query parameter", http.StatusBadRequest)
	titleErrKey   = errors.GenSym()
	pointerErrKey = errors.GenSym()
	paramErrKey   = errors.GenSym()
)

// HTTPError is used for errors
type HTTPError struct {
	err    error
	msg    string
	status int
	Errors []Error `json:"errors,omitempty"`
}

// Error can be used for all kind of application errors
// e.g. you would use it to define form errors or any
// other semantical application problems
// for more information see http://jsonapi.org/format/#errors
type Error struct {
	ID     string       `json:"id,omitempty"`
	Links  *ErrorLinks  `json:"links,omitempty"`
	Status string       `json:"status,omitempty"`
	Code   string       `json:"code,omitempty"`
	Title  string       `json:"title,omitempty"`
	Detail string       `json:"detail,omitempty"`
	Source *ErrorSource `json:"source,omitempty"`
	Meta   interface{}  `json:"meta,omitempty"`
}

// ErrorLinks is used to provide an About URL that leads to
// further details about the particular occurrence of the problem.
//
// for more information see http://jsonapi.org/format/#error-objects
type ErrorLinks struct {
	About string `json:"about,omitempty"`
}

// ErrorSource is used to provide references to the source of an error.
//
// The Pointer is a JSON Pointer to the associated entity in the request
// document.
// The Paramter is a string indicating which query parameter caused the error.
//
// for more information see http://jsonapi.org/format/#error-objects
type ErrorSource struct {
	Pointer   string `json:"pointer,omitempty"`
	Parameter string `json:"parameter,omitempty"`
}

func newErrorClassWithParam(msg, param string, code int) *errors.ErrorClass {
	err := newErrorClass(msg, code)
	err.MustAddData(paramErrKey, param)
	return err
}

func newErrorClassWithPointer(msg, pointer string, code int) *errors.ErrorClass {
	err := newErrorClass(msg, code)
	err.MustAddData(pointerErrKey, pointer)
	return err
}

func newErrorClass(msg string, code int) *errors.ErrorClass {
	err := Errhttp.NewClass(
		http.StatusText(code),
		errhttp.SetStatusCode(code),
	)
	err.MustAddData(titleErrKey, msg)
	return err
}

//JSONAPIError generate JSONAPI formatted http error from an error object
func JSONAPIError(w http.ResponseWriter, err error) {
	status := errhttp.GetStatusCode(err, http.StatusInternalServerError)
	title, _ := errors.GetData(err, titleErrKey).(string)
	jsnErr := Error{
		Status: strconv.Itoa(status),
		Title:  title,
		Detail: errhttp.GetErrorBody(err),
		Meta: map[string]interface{}{
			"creator": "api error helper",
		},
	}
	errSource := new(ErrorSource)
	pointer, ok := errors.GetData(err, pointerErrKey).(string)
	if ok {
		errSource.Pointer = pointer
	}
	param, ok := errors.GetData(err, paramErrKey).(string)
	if ok {
		errSource.Parameter = param
	}
	jsnErr.Source = errSource
	w.Header().Set("Content-Type", "application/vnd.api+json")
	w.WriteHeader(status)
	encErr := json.NewEncoder(w).Encode(HTTPError{Errors: []Error{jsnErr}})
	if encErr != nil {
		http.Error(w, encErr.Error(), http.StatusInternalServerError)
	}
}

// DatabaseError is for generating JSONAPI formatted error for database related
// errors
//func DatabaseError(w http.ResponseWriter, err error) {
//if err == dbr.ErrNotFound {
//JSONAPIError(w, ErrNotFound.New(err.Error()))
//return
//}
//// possible database query error
//JSONAPIError(w, ErrDatabaseQuery.New(err.Error()))
//}
<commit_msg>Added authentication error constant<commit_after>// Package apherror provides a consistent way to handler JSONAPI
// related http errors.
package apherror

import (
	"encoding/json"
	"net/http"
	"strconv"

	"github.com/spacemonkeygo/errors"
	"github.com/spacemonkeygo/errors/errhttp"
)

var (
	//HTTPError represents generic http errors
	Errhttp = errors.NewClass("HTTP Error", errors.NoCaptureStack())
	//ErrMessagingReply represents error in request reply messaging
	ErrMessagingReply = newErrorClass("messaging reply error", http.StatusInternalServerError)
	//ErrMessagingReq represents error in request reply messaging
	ErrMessagingReq = newErrorClass("messaging request error", http.StatusInternalServerError)
	//ErrMessagingSub represents error in publish subscribe messaging
	ErrMessagingSub = newErrorClass("messaging subscription error", http.StatusInternalServerError)
	//ErrMessagingPub represents error in publish subscribe messaging
	ErrMessagingPub = newErrorClass("messaging publication error", http.StatusInternalServerError)
	//ErrReqContext represents error in extracting context value from http request
	ErrReqContext = newErrorClass("Unable to retrieve context", http.StatusInternalServerError)
	//ErrOuthExchange represents error in exchanging code for token with oauth server
	ErrOauthExchange = newErrorClass("Unable to exchange token for code", http.StatusInternalServerError)
	//ErrUserRetrieval represents error in retrieving user information from oauth provider
	ErrUserRetrieval = newErrorClass("Unable to retrieve user information", http.StatusInternalServerError)
	//ErrDatabaseQuery represents database query related errors
	ErrDatabaseQuery = newErrorClass("Database query error", http.StatusInternalServerError)
	//ErrNotFound represents the absence of an HTTP resource
	ErrNotFound = newErrorClass("Resource not found", http.StatusNotFound)
	//ErrAuthentication represents the absence of valid authentication credentials
	ErrAuthentication = newErrorClass("Invalid credential for authentication", http.StatusUnauthorized)
	//ErrJSONEncoding represents any json encoding error
	ErrJSONEncoding = newErrorClass("Json encoding error", http.StatusInternalServerError)
	//ErrStructMarshal represents any error with marshalling structure
	ErrStructMarshal = newErrorClass("Structure marshalling error", http.StatusInternalServerError)
	// ErrJWTToken represents errors with jwt token
	ErrJWTToken = newErrorClass("Issue with jwt token", http.StatusInternalServerError)
	//ErrIncludeParam represents any error with invalid include query parameter
	ErrIncludeParam = newErrorClassWithParam("Invalid include query parameter", "include", http.StatusBadRequest)
	//ErrSparseFieldSets represents any error with invalid sparse fieldsets query parameter
	ErrSparseFieldSets = newErrorClassWithParam("Invalid sparse fieldsets query parameter", "fieldsets", http.StatusBadRequest)
	//ErrFilterParam represents any error with invalid filter query paramter
	ErrFilterParam = newErrorClassWithParam("Invalid filter query parameter", "filter", http.StatusBadRequest)
	//ErrNotAcceptable represents any error with wrong or inappropriate http Accept header
	ErrNotAcceptable = newErrorClass("Accept header is not acceptable", http.StatusNotAcceptable)
	//ErrUnsupportedMedia represents any error with unsupported media type in http header
	ErrUnsupportedMedia = newErrorClass("Media type is not supported", http.StatusUnsupportedMediaType)
	//ErrQueryParam represents any error with http query parameters
	ErrQueryParam = newErrorClass("Invalid query parameter", http.StatusBadRequest)
	titleErrKey   = errors.GenSym()
	pointerErrKey = errors.GenSym()
	paramErrKey   = errors.GenSym()
)

// HTTPError is used for errors
type HTTPError struct {
	err    error
	msg    string
	status int
	Errors []Error `json:"errors,omitempty"`
}

// Error can be used for all kind of application errors
// e.g. you would use it to define form errors or any
// other semantical application problems
// for more information see http://jsonapi.org/format/#errors
type Error struct {
	ID     string       `json:"id,omitempty"`
	Links  *ErrorLinks  `json:"links,omitempty"`
	Status string       `json:"status,omitempty"`
	Code   string       `json:"code,omitempty"`
	Title  string       `json:"title,omitempty"`
	Detail string       `json:"detail,omitempty"`
	Source *ErrorSource `json:"source,omitempty"`
	Meta   interface{}  `json:"meta,omitempty"`
}

// ErrorLinks is used to provide an About URL that leads to
// further details about the particular occurrence of the problem.
//
// for more information see http://jsonapi.org/format/#error-objects
type ErrorLinks struct {
	About string `json:"about,omitempty"`
}

// ErrorSource is used to provide references to the source of an error.
//
// The Pointer is a JSON Pointer to the associated entity in the request
// document.
// The Paramter is a string indicating which query parameter caused the error.
//
// for more information see http://jsonapi.org/format/#error-objects
type ErrorSource struct {
	Pointer   string `json:"pointer,omitempty"`
	Parameter string `json:"parameter,omitempty"`
}

func newErrorClassWithParam(msg, param string, code int) *errors.ErrorClass {
	err := newErrorClass(msg, code)
	err.MustAddData(paramErrKey, param)
	return err
}

func newErrorClassWithPointer(msg, pointer string, code int) *errors.ErrorClass {
	err := newErrorClass(msg, code)
	err.MustAddData(pointerErrKey, pointer)
	return err
}

func newErrorClass(msg string, code int) *errors.ErrorClass {
	err := Errhttp.NewClass(
		http.StatusText(code),
		errhttp.SetStatusCode(code),
	)
	err.MustAddData(titleErrKey, msg)
	return err
}

//JSONAPIError generate JSONAPI formatted http error from an error object
func JSONAPIError(w http.ResponseWriter, err error) {
	status := errhttp.GetStatusCode(err, http.StatusInternalServerError)
	title, _ := errors.GetData(err, titleErrKey).(string)
	jsnErr := Error{
		Status: strconv.Itoa(status),
		Title:  title,
		Detail: errhttp.GetErrorBody(err),
		Meta: map[string]interface{}{
			"creator": "api error helper",
		},
	}
	errSource := new(ErrorSource)
	pointer, ok := errors.GetData(err, pointerErrKey).(string)
	if ok {
		errSource.Pointer = pointer
	}
	param, ok := errors.GetData(err, paramErrKey).(string)
	if ok {
		errSource.Parameter = param
	}
	jsnErr.Source = errSource
	w.Header().Set("Content-Type", "application/vnd.api+json")
	w.WriteHeader(status)
	encErr := json.NewEncoder(w).Encode(HTTPError{Errors: []Error{jsnErr}})
	if encErr != nil {
		http.Error(w, encErr.Error(), http.StatusInternalServerError)
	}
}

// DatabaseError is for generating JSONAPI formatted error for database related
// errors
//func DatabaseError(w http.ResponseWriter, err error) {
//if err == dbr.ErrNotFound {
//JSONAPIError(w, ErrNotFound.New(err.Error()))
//return
//}
//// possible database query error
//JSONAPIError(w, ErrDatabaseQuery.New(err.Error()))
//}
<|endoftext|>


<commit_before>package dbr

import (
	"database/sql"
	"encoding/json"

	"github.com/go-sql-driver/mysql"
)

//
// Your app can use these Null types instead of the defaults. The sole benefit you get is a MarshalJSON method that is not retarded.
//

// NullString is a type that can be null or a string
type NullString struct {
	sql.NullString
}

// NullInt64 is a type that can be null or an int
type NullInt64 struct {
	sql.NullInt64
}

// NullTime is a type that can be null or a time
type NullTime struct {
	mysql.NullTime
}

// NullBool is a type that can be null or a bool
type NullBool struct {
	sql.NullBool
}

var nullString = []byte("null")

// MarshalJSON correctly serializes a NullString to JSON
func (n *NullString) MarshalJSON() ([]byte, error) {
	if n.Valid {
		j, e := json.Marshal(n.String)
		return j, e
	}
	return nullString, nil
}

// MarshalJSON correctly serializes a NullInt64 to JSON
func (n *NullInt64) MarshalJSON() ([]byte, error) {
	if n.Valid {
		j, e := json.Marshal(n.Int64)
		return j, e
	}
	return nullString, nil
}

// MarshalJSON correctly serializes a NullTime to JSON
func (n *NullTime) MarshalJSON() ([]byte, error) {
	if n.Valid {
		j, e := json.Marshal(n.Time)
		return j, e
	}
	return nullString, nil
}

// MarshalJSON correctly serializes a NullBool to JSON
func (n *NullBool) MarshalJSON() ([]byte, error) {
	if n.Valid {
		j, e := json.Marshal(n.Bool)
		return j, e
	}
	return nullString, nil
}
<commit_msg>Add NullFloat64 type<commit_after>package dbr

import (
	"database/sql"
	"encoding/json"

	"github.com/go-sql-driver/mysql"
)

//
// Your app can use these Null types instead of the defaults. The sole benefit you get is a MarshalJSON method that is not retarded.
//

// NullString is a type that can be null or a string
type NullString struct {
	sql.NullString
}

// NullFloat64 is a type that can be null or a float64
type NullFloat64 struct {
	sql.NullFloat64
}

// NullInt64 is a type that can be null or an int
type NullInt64 struct {
	sql.NullInt64
}

// NullTime is a type that can be null or a time
type NullTime struct {
	mysql.NullTime
}

// NullBool is a type that can be null or a bool
type NullBool struct {
	sql.NullBool
}

var nullString = []byte("null")

// MarshalJSON correctly serializes a NullString to JSON
func (n *NullString) MarshalJSON() ([]byte, error) {
	if n.Valid {
		j, e := json.Marshal(n.String)
		return j, e
	}
	return nullString, nil
}

// MarshalJSON correctly serializes a NullFloat64 to JSON
func (n *NullFloat64) MarshalJSON() ([]byte, error) {
	if n.Valid {
		j, e := json.Marshal(n.Float64)
		return j, e
	}
	return nullString, nil
}

// MarshalJSON correctly serializes a NullInt64 to JSON
func (n *NullInt64) MarshalJSON() ([]byte, error) {
	if n.Valid {
		j, e := json.Marshal(n.Int64)
		return j, e
	}
	return nullString, nil
}

// MarshalJSON correctly serializes a NullTime to JSON
func (n *NullTime) MarshalJSON() ([]byte, error) {
	if n.Valid {
		j, e := json.Marshal(n.Time)
		return j, e
	}
	return nullString, nil
}

// MarshalJSON correctly serializes a NullBool to JSON
func (n *NullBool) MarshalJSON() ([]byte, error) {
	if n.Valid {
		j, e := json.Marshal(n.Bool)
		return j, e
	}
	return nullString, nil
}
<|endoftext|>


<commit_before>// Package hammer generates ipfix packets
//: ----------------------------------------------------------------------------
//: Copyright (C) 2017 Verizon.  All Rights Reserved.
//: All Rights Reserved
//:
//: file:    hammer.go
//: details: TODO
//: author:  Mehrdad Arshad Rad
//: date:    02/01/2017
//:
//: 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 hammer

import (
	"fmt"
	"net"
	"sync"
	"time"

	"github.com/VerizonDigital/vflow/mirror"
)

const (
	dataType = iota
	templateType
	templateOptType
	sFlowDataType
)

type Packet struct {
	payload []byte
	length  int
}

type IPFIX struct {
	conn  mirror.Conn
	ch    chan Packet
	srcs  []net.IP
	vflow net.IP

	MaxRouter int
	Tick      time.Duration
	Port      int
	RateLimit int
}

type SFlow struct {
	conn  mirror.Conn
	ch    chan Packet
	srcs  []net.IP
	vflow net.IP

	MaxRouter int
	Port      int
	RateLimit int
}

func NewIPFIX(raddr net.IP) (*IPFIX, error) {

	conn, err := mirror.NewRawConn(raddr)
	if err != nil {
		return nil, err
	}

	return &IPFIX{
		conn:      conn,
		ch:        make(chan Packet, 10000),
		vflow:     raddr,
		MaxRouter: 10,
		RateLimit: 25 * 10e3,
	}, nil
}

func (i *IPFIX) Run() {
	var wg sync.WaitGroup

	for j := 1; j < i.MaxRouter; j++ {
		i.srcs = append(i.srcs, net.ParseIP(fmt.Sprintf("192.168.1.%d", j)))
	}

	wg.Add(1)
	go func() {
		var p Packet
		defer wg.Done()
		for {
			p = <-i.ch
			i.conn.Send(p.payload[:p.length])
		}
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		i.sendTemplate()
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		i.sendTemplateOpt()
	}()

	time.Sleep(1 * time.Second)

	wg.Add(1)
	go func() {
		defer wg.Done()
		i.sendData()
	}()

	wg.Wait()
}

func (i *IPFIX) sendData() {
	var (
		throttle <-chan time.Time
		packets  = i.genPackets(dataType)
	)

	if i.RateLimit > 0 {
		throttle = time.Tick(time.Duration(1e6/(i.RateLimit)) * time.Microsecond)
	}

	for {
		for j := range packets {
			<-throttle
			i.ch <- packets[j]
		}
	}
}

func (i *IPFIX) sendTemplate() {
	c := time.Tick(i.Tick)
	packets := i.genPackets(templateType)

	for j := range packets {
		i.ch <- packets[j]
	}

	for range c {
		for j := range packets {
			i.ch <- packets[j]
		}
	}
}

func (i *IPFIX) sendTemplateOpt() {
	c := time.Tick(i.Tick)
	packets := i.genPackets(templateOptType)

	for j := range packets {
		i.ch <- packets[j]
	}

	for range c {
		for j := range packets {
			i.ch <- packets[j]
		}
	}
}

func (i *IPFIX) genPackets(typ int) []Packet {
	var (
		packets []Packet
		samples [][]byte
	)

	ipHLen := mirror.IPv4HLen
	udp := mirror.UDP{55117, i.Port, 0, 0}
	udpHdr := udp.Marshal()

	ip := mirror.NewIPv4HeaderTpl(mirror.UDPProto)
	ipHdr := ip.Marshal()

	switch typ {
	case dataType:
		samples = ipfixDataSamples
	case templateType:
		samples = ipfixTemplates
	case templateOptType:
		samples = ipfixTemplatesOpt
	case sFlowDataType:
		samples = sFlowDataSamples
	}

	for j := 0; j < len(samples); j++ {
		for _, src := range i.srcs {
			data := samples[j]
			payload := make([]byte, 1500)

			udp.SetLen(udpHdr, len(data))

			ip.SetAddrs(ipHdr, src, i.vflow)

			copy(payload[0:ipHLen], ipHdr)
			copy(payload[ipHLen:ipHLen+8], udpHdr)
			copy(payload[ipHLen+8:], data)

			packets = append(packets, Packet{
				payload: payload,
				length:  ipHLen + 8 + len(data),
			})

		}
	}

	return packets
}

func NewSFlow(raddr net.IP) (*SFlow, error) {

	conn, err := mirror.NewRawConn(raddr)
	if err != nil {
		return nil, err
	}

	return &SFlow{
		conn:      conn,
		ch:        make(chan Packet, 10000),
		vflow:     raddr,
		MaxRouter: 10,
		RateLimit: 25 * 10e3,
	}, nil
}

func (s *SFlow) Run() {
	var wg sync.WaitGroup

	for j := 1; j < s.MaxRouter; j++ {
		s.srcs = append(s.srcs, net.ParseIP(fmt.Sprintf("192.168.1.%d", j)))
	}

	wg.Add(1)
	go func() {
		var p Packet
		defer wg.Done()
		for {
			p = <-s.ch
			s.conn.Send(p.payload[:p.length])
		}
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		s.sendData()
	}()

	wg.Wait()
}

func (s *SFlow) genPackets() []Packet {
	var packets []Packet
	ipHLen := mirror.IPv4HLen
	udp := mirror.UDP{55117, s.Port, 0, 0}
	udpHdr := udp.Marshal()

	ip := mirror.NewIPv4HeaderTpl(mirror.UDPProto)
	ipHdr := ip.Marshal()

	for j := 0; j < len(sFlowDataSamples); j++ {
		for _, src := range s.srcs {
			data := sFlowDataSamples[j]
			payload := make([]byte, 1500)

			udp.SetLen(udpHdr, len(data))

			ip.SetAddrs(ipHdr, src, s.vflow)

			copy(payload[0:ipHLen], ipHdr)
			copy(payload[ipHLen:ipHLen+8], udpHdr)
			copy(payload[ipHLen+8:], data)

			packets = append(packets, Packet{
				payload: payload,
				length:  ipHLen + 8 + len(data),
			})

		}
	}

	return packets
}

func (s *SFlow) sendData() {
	var (
		throttle <-chan time.Time
		packets  = s.genPackets()
	)

	if s.RateLimit > 0 {
		throttle = time.Tick(time.Duration(1e6/(s.RateLimit)) * time.Microsecond)
	}

	for {
		for j := range packets {
			<-throttle
			s.ch <- packets[j]
		}
	}
}
<commit_msg>add more comments - golint<commit_after>// Package hammer generates ipfix packets
//: ----------------------------------------------------------------------------
//: Copyright (C) 2017 Verizon.  All Rights Reserved.
//: All Rights Reserved
//:
//: file:    hammer.go
//: details: TODO
//: author:  Mehrdad Arshad Rad
//: date:    02/01/2017
//:
//: 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 hammer

import (
	"fmt"
	"net"
	"sync"
	"time"

	"github.com/VerizonDigital/vflow/mirror"
)

const (
	dataType = iota
	templateType
	templateOptType
	sFlowDataType
)

// Packet represents generated packet
type Packet struct {
	payload []byte
	length  int
}

// IPFIX represents IPFIX packet generator
type IPFIX struct {
	conn  mirror.Conn
	ch    chan Packet
	srcs  []net.IP
	vflow net.IP

	MaxRouter int
	Tick      time.Duration
	Port      int
	RateLimit int
}

// SFlow represents SFlow packet generator
type SFlow struct {
	conn  mirror.Conn
	ch    chan Packet
	srcs  []net.IP
	vflow net.IP

	MaxRouter int
	Port      int
	RateLimit int
}

// NewIPFIX constructs new IPFIX packet generator
func NewIPFIX(raddr net.IP) (*IPFIX, error) {

	conn, err := mirror.NewRawConn(raddr)
	if err != nil {
		return nil, err
	}

	return &IPFIX{
		conn:      conn,
		ch:        make(chan Packet, 10000),
		vflow:     raddr,
		MaxRouter: 10,
		RateLimit: 25 * 10e3,
	}, nil
}

// Run starts IPFIX simulator - attacking
func (i *IPFIX) Run() {
	var wg sync.WaitGroup

	for j := 1; j < i.MaxRouter; j++ {
		i.srcs = append(i.srcs, net.ParseIP(fmt.Sprintf("192.168.1.%d", j)))
	}

	wg.Add(1)
	go func() {
		var p Packet
		defer wg.Done()
		for {
			p = <-i.ch
			i.conn.Send(p.payload[:p.length])
		}
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		i.sendTemplate()
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		i.sendTemplateOpt()
	}()

	time.Sleep(1 * time.Second)

	wg.Add(1)
	go func() {
		defer wg.Done()
		i.sendData()
	}()

	wg.Wait()
}

func (i *IPFIX) sendData() {
	var (
		throttle <-chan time.Time
		packets  = i.genPackets(dataType)
	)

	if i.RateLimit > 0 {
		throttle = time.Tick(time.Duration(1e6/(i.RateLimit)) * time.Microsecond)
	}

	for {
		for j := range packets {
			<-throttle
			i.ch <- packets[j]
		}
	}
}

func (i *IPFIX) sendTemplate() {
	c := time.Tick(i.Tick)
	packets := i.genPackets(templateType)

	for j := range packets {
		i.ch <- packets[j]
	}

	for range c {
		for j := range packets {
			i.ch <- packets[j]
		}
	}
}

func (i *IPFIX) sendTemplateOpt() {
	c := time.Tick(i.Tick)
	packets := i.genPackets(templateOptType)

	for j := range packets {
		i.ch <- packets[j]
	}

	for range c {
		for j := range packets {
			i.ch <- packets[j]
		}
	}
}

func (i *IPFIX) genPackets(typ int) []Packet {
	var (
		packets []Packet
		samples [][]byte
	)

	ipHLen := mirror.IPv4HLen
	udp := mirror.UDP{55117, i.Port, 0, 0}
	udpHdr := udp.Marshal()

	ip := mirror.NewIPv4HeaderTpl(mirror.UDPProto)
	ipHdr := ip.Marshal()

	switch typ {
	case dataType:
		samples = ipfixDataSamples
	case templateType:
		samples = ipfixTemplates
	case templateOptType:
		samples = ipfixTemplatesOpt
	case sFlowDataType:
		samples = sFlowDataSamples
	}

	for j := 0; j < len(samples); j++ {
		for _, src := range i.srcs {
			data := samples[j]
			payload := make([]byte, 1500)

			udp.SetLen(udpHdr, len(data))

			ip.SetAddrs(ipHdr, src, i.vflow)

			copy(payload[0:ipHLen], ipHdr)
			copy(payload[ipHLen:ipHLen+8], udpHdr)
			copy(payload[ipHLen+8:], data)

			packets = append(packets, Packet{
				payload: payload,
				length:  ipHLen + 8 + len(data),
			})

		}
	}

	return packets
}

// NewSFlow constructs SFlow packet generator
func NewSFlow(raddr net.IP) (*SFlow, error) {

	conn, err := mirror.NewRawConn(raddr)
	if err != nil {
		return nil, err
	}

	return &SFlow{
		conn:      conn,
		ch:        make(chan Packet, 10000),
		vflow:     raddr,
		MaxRouter: 10,
		RateLimit: 25 * 10e3,
	}, nil
}

// Run starts sFlow simulator - attacking
func (s *SFlow) Run() {
	var wg sync.WaitGroup

	for j := 1; j < s.MaxRouter; j++ {
		s.srcs = append(s.srcs, net.ParseIP(fmt.Sprintf("192.168.1.%d", j)))
	}

	wg.Add(1)
	go func() {
		var p Packet
		defer wg.Done()
		for {
			p = <-s.ch
			s.conn.Send(p.payload[:p.length])
		}
	}()

	wg.Add(1)
	go func() {
		defer wg.Done()
		s.sendData()
	}()

	wg.Wait()
}

func (s *SFlow) genPackets() []Packet {
	var packets []Packet
	ipHLen := mirror.IPv4HLen
	udp := mirror.UDP{55117, s.Port, 0, 0}
	udpHdr := udp.Marshal()

	ip := mirror.NewIPv4HeaderTpl(mirror.UDPProto)
	ipHdr := ip.Marshal()

	for j := 0; j < len(sFlowDataSamples); j++ {
		for _, src := range s.srcs {
			data := sFlowDataSamples[j]
			payload := make([]byte, 1500)

			udp.SetLen(udpHdr, len(data))

			ip.SetAddrs(ipHdr, src, s.vflow)

			copy(payload[0:ipHLen], ipHdr)
			copy(payload[ipHLen:ipHLen+8], udpHdr)
			copy(payload[ipHLen+8:], data)

			packets = append(packets, Packet{
				payload: payload,
				length:  ipHLen + 8 + len(data),
			})

		}
	}

	return packets
}

func (s *SFlow) sendData() {
	var (
		throttle <-chan time.Time
		packets  = s.genPackets()
	)

	if s.RateLimit > 0 {
		throttle = time.Tick(time.Duration(1e6/(s.RateLimit)) * time.Microsecond)
	}

	for {
		for j := range packets {
			<-throttle
			s.ch <- packets[j]
		}
	}
}
<|endoftext|>


<commit_before>package parse

import (
	"encoding/json"
	"fmt"
	"path"
	"reflect"
	"time"
)

// An interface for custom Parse types. Contains a single method:
//
// ClassName() - returns a string containing the class name as it appears in your
// Parse database.
//
// Implement this interface if your class name does not match your struct
// name. If this class is not implemented, the name of the struct will
// be used when interacting with the Parse API
type iClassName interface {
	ClassName() string
}

// An interface for custom Parse types to override the endpoint used for querying.
//
// Contains a single method:
//
// Endpoint() - returns the endpoint to use when querying the Parse REST API.
//
// If this method is not implented, the endpoint is constructed as follows:
//
// /classes/{ClassName} - where {ClassName} is the name of the struct or the value returned by the ClassName
// method if implemented
type iParseEp interface {
	Endpoint() string
}

// A base type containing fields common to all Parse types
//
// Embed this struct in custom types to avoid having to declare
// these fields everywhere.
type Base struct {
	Id        string    `parse:"objectId"`
	CreatedAt time.Time `parse:"-"`
	UpdatedAt time.Time `parse:"-"`
	ACL       *ACL
	Extra     map[string]interface{} `parse:"-"`
}

// Represents the built-in Parse "User" class. Embed this type in a custom
// type containing any custom fields. When fetching user objects, any retrieved
// fields with no matching struct field will be stored in User.Extra (map[string]interface{})
type User struct {
	Base
	Username      string
	Email         string
	EmailVerified bool
}

func (u *User) ClassName() string {
	return "_User"
}

func (u *User) Endpoint() string {
	return "users"
}

// Represents the built-in Parse "Installation" class. Embed this type in a custom
// type containing any custom fields. When fetching user objects, any retrieved
// fields with no matching struct field will be stored in User.Extra (map[string]interface{})
type Installation struct {
	Base
}

func (i *Installation) ClassName() string {
	return "_Installation"
}

func (i *Installation) Endpoint() string {
	return "installations"
}

type ACL struct {
}

// Represents the Parse GeoPoint type
type GeoPoint struct {
	Latitude  float64
	Longitude float64
}

func (g GeoPoint) MarshalJSON() ([]byte, error) {
	return json.Marshal(&struct {
		Type      string  `json:"__type"`
		Latitude  float64 `json:"latitude"`
		Longitude float64 `json:"longitude"`
	}{
		"GeoPoint",
		g.Latitude,
		g.Longitude,
	})
}

func (g *GeoPoint) UnmarshalJSON(b []byte) error {
	s := struct {
		Type      string  `json:"__type"`
		Latitude  float64 `json:"latitude"`
		Longitude float64 `json:"longitude"`
	}{}
	err := json.Unmarshal(b, &s)
	if err != nil {
		return err
	}
	if s.Type != "GeoPoint" {
		return fmt.Errorf("cannot unmarshal type %s to type GeoPoint", s.Type)
	}

	g.Latitude = s.Latitude
	g.Longitude = s.Longitude
	return nil
}

// Represents the Parse File type
type File struct {
}

// Represents a Parse Pointer type. When querying, creating, or updating
// objects, any struct types will be automatically converted to and from Pointer
// types as required. Direct use of this type should not be necessary
type Pointer struct {
	Id        string
	ClassName string
}

func (p Pointer) MarshalJSON() ([]byte, error) {
	return json.Marshal(&struct {
		Type      string `json:"__type"`
		ClassName string `json:"className"`
		Id        string `json:"objectId"`
	}{
		"Pointer",
		p.ClassName,
		p.Id,
	})
}

// Represents the Parse Date type. Values of type time.Time will
// automatically converted to a Date type when constructing queries
// or creating objects. The inverse is true for retrieving objects.
// Direct use of this type should not be necessary
type Date time.Time

func (d Date) MarshalJSON() ([]byte, error) {
	return json.Marshal(&struct {
		Type string `json:"__type"`
		Iso  string `json:"iso"`
	}{
		"Date",
		time.Time(d).In(time.UTC).Format("2006-01-02T15:04:05.000Z"),
	})
}

func (d *Date) UnmarshalJSON(b []byte) error {
	s := struct {
		Type string `json:"__type"`
		Iso  string `json:"iso"`
	}{}
	err := json.Unmarshal(b, &s)
	if err != nil {
		return err
	}
	if s.Type != "Date" {
		return fmt.Errorf("cannot unmarshal type %s to type Date", s.Type)
	}

	t, err := time.Parse(s.Iso, "2006-01-02T15:04:05.000Z")
	if err != nil {
		return err
	}

	*d = Date(t)
	return nil
}

func getEndpointBase(v interface{}) string {
	var p string
	var inst interface{}

	rt := reflect.TypeOf(v)
	rt = rt.Elem()
	if rt.Kind() == reflect.Slice || rt.Kind() == reflect.Array {
		rte := rt.Elem()
		var rv reflect.Value
		if rte.Kind() == reflect.Ptr {
			rv = reflect.New(rte.Elem())
		} else {
			rv = reflect.New(rte)
		}
		inst = rv.Interface()
	} else {
		inst = v
	}

	if iv, ok := inst.(iParseEp); ok {
		p = iv.Endpoint()
	} else {
		var cname string
		if v, ok := inst.(iClassName); ok {
			cname = v.ClassName()
		} else {
			t := reflect.TypeOf(inst)
			cname = t.Elem().Name()
		}
		p = path.Join("classes", cname)
	}

	p = path.Join(ParseVersion, p)
	return p
}
<commit_msg>extract class name code into its own function<commit_after>package parse

import (
	"encoding/json"
	"fmt"
	"path"
	"reflect"
	"time"
)

// An interface for custom Parse types. Contains a single method:
//
// ClassName() - returns a string containing the class name as it appears in your
// Parse database.
//
// Implement this interface if your class name does not match your struct
// name. If this class is not implemented, the name of the struct will
// be used when interacting with the Parse API
type iClassName interface {
	ClassName() string
}

// An interface for custom Parse types to override the endpoint used for querying.
//
// Contains a single method:
//
// Endpoint() - returns the endpoint to use when querying the Parse REST API.
//
// If this method is not implented, the endpoint is constructed as follows:
//
// /classes/{ClassName} - where {ClassName} is the name of the struct or the value returned by the ClassName
// method if implemented
type iParseEp interface {
	Endpoint() string
}

// A base type containing fields common to all Parse types
//
// Embed this struct in custom types to avoid having to declare
// these fields everywhere.
type Base struct {
	Id        string    `parse:"objectId"`
	CreatedAt time.Time `parse:"-"`
	UpdatedAt time.Time `parse:"-"`
	ACL       *ACL
	Extra     map[string]interface{} `parse:"-"`
}

// Represents the built-in Parse "User" class. Embed this type in a custom
// type containing any custom fields. When fetching user objects, any retrieved
// fields with no matching struct field will be stored in User.Extra (map[string]interface{})
type User struct {
	Base
	Username      string
	Email         string
	EmailVerified bool
}

func (u *User) ClassName() string {
	return "_User"
}

func (u *User) Endpoint() string {
	return "users"
}

// Represents the built-in Parse "Installation" class. Embed this type in a custom
// type containing any custom fields. When fetching user objects, any retrieved
// fields with no matching struct field will be stored in User.Extra (map[string]interface{})
type Installation struct {
	Base
}

func (i *Installation) ClassName() string {
	return "_Installation"
}

func (i *Installation) Endpoint() string {
	return "installations"
}

type ACL struct {
}

// Represents the Parse GeoPoint type
type GeoPoint struct {
	Latitude  float64
	Longitude float64
}

func (g GeoPoint) MarshalJSON() ([]byte, error) {
	return json.Marshal(&struct {
		Type      string  `json:"__type"`
		Latitude  float64 `json:"latitude"`
		Longitude float64 `json:"longitude"`
	}{
		"GeoPoint",
		g.Latitude,
		g.Longitude,
	})
}

func (g *GeoPoint) UnmarshalJSON(b []byte) error {
	s := struct {
		Type      string  `json:"__type"`
		Latitude  float64 `json:"latitude"`
		Longitude float64 `json:"longitude"`
	}{}
	err := json.Unmarshal(b, &s)
	if err != nil {
		return err
	}
	if s.Type != "GeoPoint" {
		return fmt.Errorf("cannot unmarshal type %s to type GeoPoint", s.Type)
	}

	g.Latitude = s.Latitude
	g.Longitude = s.Longitude
	return nil
}

// Represents the Parse File type
type File struct {
}

// Represents a Parse Pointer type. When querying, creating, or updating
// objects, any struct types will be automatically converted to and from Pointer
// types as required. Direct use of this type should not be necessary
type Pointer struct {
	Id        string
	ClassName string
}

func (p Pointer) MarshalJSON() ([]byte, error) {
	return json.Marshal(&struct {
		Type      string `json:"__type"`
		ClassName string `json:"className"`
		Id        string `json:"objectId"`
	}{
		"Pointer",
		p.ClassName,
		p.Id,
	})
}

// Represents the Parse Date type. Values of type time.Time will
// automatically converted to a Date type when constructing queries
// or creating objects. The inverse is true for retrieving objects.
// Direct use of this type should not be necessary
type Date time.Time

func (d Date) MarshalJSON() ([]byte, error) {
	return json.Marshal(&struct {
		Type string `json:"__type"`
		Iso  string `json:"iso"`
	}{
		"Date",
		time.Time(d).In(time.UTC).Format("2006-01-02T15:04:05.000Z"),
	})
}

func (d *Date) UnmarshalJSON(b []byte) error {
	s := struct {
		Type string `json:"__type"`
		Iso  string `json:"iso"`
	}{}
	err := json.Unmarshal(b, &s)
	if err != nil {
		return err
	}
	if s.Type != "Date" {
		return fmt.Errorf("cannot unmarshal type %s to type Date", s.Type)
	}

	t, err := time.Parse(s.Iso, "2006-01-02T15:04:05.000Z")
	if err != nil {
		return err
	}

	*d = Date(t)
	return nil
}

func getClassName(v interface{}) string {
	if tmp, ok := v.(iClassName); ok {
		return tmp.ClassName()
	} else {
		t := reflect.TypeOf(v)
		return t.Elem().Name()
	}
}

func getEndpointBase(v interface{}) string {
	var p string
	var inst interface{}

	rt := reflect.TypeOf(v)
	rt = rt.Elem()
	if rt.Kind() == reflect.Slice || rt.Kind() == reflect.Array {
		rte := rt.Elem()
		var rv reflect.Value
		if rte.Kind() == reflect.Ptr {
			rv = reflect.New(rte.Elem())
		} else {
			rv = reflect.New(rte)
		}
		inst = rv.Interface()
	} else {
		inst = v
	}

	if iv, ok := inst.(iParseEp); ok {
		p = iv.Endpoint()
	} else {
		cname := getClassName(v)
		p = path.Join("classes", cname)
	}

	p = path.Join(ParseVersion, p)
	return p
}
<|endoftext|>


<commit_before>package tw

import (
	"fmt"
	"log"
	"strings"
	"time"
)

type twitterTime struct {
	value time.Time
}

func (t twitterTime) MarshalJSON() ([]byte, error) {
	return []byte(`"` + t.value.Format(time.RubyDate) + `"`), nil
}

func (t twitterTime) UnmarshalJSON(data []byte) error {
	ts := strings.Trim(string(data), `"`)
	var err error
	t.value, err = time.Parse(time.RubyDate, ts)
	return err
}

type User struct {
	ID              uint64      `json:"id"                bson:"id"`
	Name            string      `json:"name"              bson:"name"`
	ScreenName      string      `json:"screen_name"       bson:"screen_name"`
	Description     string      `json:"description"       bson:"description"`
	ProfileImageURL string      `json:"profile_image_url" bson:"profile_image_url"`
	Location        string      `json:"location"          bson:"location"`
	Lang            string      `json:"lang"              bson:"lang"`
	TimeZone        string      `json:"time_zone"         bson:"time_zone"`
	URL             string      `json:"url"               bson:"url"`
	Protected       bool        `json:"protected"         bson:"protected"`
	Verified        bool        `json:"verified"          bson:"verified"`
	FriendsCount    int         `json:"friends_count"     bson:"friends_count"`
	ListedCount     int         `json:"listed_count"      bson:"listed_count"`
	FavouritesCount int         `json:"favourites_count"  bson:"favourites_count"`
	FollowersCount  int         `json:"followers_count"   bson:"followers_count"`
	StatusesCount   int         `json:"statuses_count"    bson:"statuses_count"`
	CreatedAt       twitterTime `json:"created_at"        bson:"created_at"`
}
<commit_msg>Fix broken tests for unused imports<commit_after>package tw

import (
	"strings"
	"time"
)

type twitterTime struct {
	value time.Time
}

func (t twitterTime) MarshalJSON() ([]byte, error) {
	return []byte(`"` + t.value.Format(time.RubyDate) + `"`), nil
}

func (t twitterTime) UnmarshalJSON(data []byte) error {
	ts := strings.Trim(string(data), `"`)
	var err error
	t.value, err = time.Parse(time.RubyDate, ts)
	return err
}

type User struct {
	ID              uint64      `json:"id"                bson:"id"`
	Name            string      `json:"name"              bson:"name"`
	ScreenName      string      `json:"screen_name"       bson:"screen_name"`
	Description     string      `json:"description"       bson:"description"`
	ProfileImageURL string      `json:"profile_image_url" bson:"profile_image_url"`
	Location        string      `json:"location"          bson:"location"`
	Lang            string      `json:"lang"              bson:"lang"`
	TimeZone        string      `json:"time_zone"         bson:"time_zone"`
	URL             string      `json:"url"               bson:"url"`
	Protected       bool        `json:"protected"         bson:"protected"`
	Verified        bool        `json:"verified"          bson:"verified"`
	FriendsCount    int         `json:"friends_count"     bson:"friends_count"`
	ListedCount     int         `json:"listed_count"      bson:"listed_count"`
	FavouritesCount int         `json:"favourites_count"  bson:"favourites_count"`
	FollowersCount  int         `json:"followers_count"   bson:"followers_count"`
	StatusesCount   int         `json:"statuses_count"    bson:"statuses_count"`
	CreatedAt       twitterTime `json:"created_at"        bson:"created_at"`
}
<|endoftext|>


<commit_before>package pkcs11

/*
#define CK_PTR *
#ifndef NULL_PTR
#define NULL_PTR 0
#endif
#define CK_DEFINE_FUNCTION(returnType, name) returnType name
#define CK_DECLARE_FUNCTION(returnType, name) returnType name
#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)

#include <stdlib.h>
#include "pkcs11.h"

CK_ULONG Index(CK_ULONG_PTR array, CK_ULONG i)
{
	return array[i];
}

CK_ULONG Sizeof()
{
	return sizeof(CK_ULONG);
}
*/
import "C"

import (
	"fmt"
	"unsafe"
)

// toList converts from a C style array to a []uint.
func toList(clist C.CK_ULONG_PTR, size C.CK_ULONG) []uint {
	l := make([]uint, int(size))
	for i := 0; i < len(l); i++ {
		l[i] = uint(C.Index(clist, C.CK_ULONG(i)))
	}
	defer C.free(unsafe.Pointer(clist))
	return l
}

// cBBool converts a bool to a CK_BBOOL.
func cBBool(x bool) C.CK_BBOOL {
	if x {
		return C.CK_BBOOL(C.CK_TRUE)
	}
	return C.CK_BBOOL(C.CK_FALSE)
}

// Error represents an PKCS#11 error.
type Error uint

func (e Error) Error() string {
	return "pkcs11: " + fmt.Sprintf("pkcs11: 0x%X: %s", uint(e), strerror[uint(e)])
}

func toError(e C.CK_RV) error {
	if e == C.CKR_OK {
		return nil
	}
	return Error(e)
}

/* SessionHandle is a Cryptoki-assigned value that identifies a session. */
type SessionHandle uint

/* ObjectHandle is a token-specific identifier for an object.  */
type ObjectHandle uint

type Version struct {
	Major byte
	Minor byte
}

type SlotEvent struct {
	SlotID uint
}

// Info provides information about the library and hardware used.
type Info struct {
	CryptokiVersion    Version
	ManufacturerID     [32]byte
	Flags              uint
	LibraryDescription [32]byte
	LibraryVersion     Version
}

/* SlotInfo provides information about a slot. */
type SlotInfo struct {
	SlotDescription [64]byte
	ManufacturerID  [32]byte
	Flags           uint
	HardwareVersion Version
	FirmwareVersion Version
}

/* TokenInfo provides information about a token. */
type TokenInfo struct {
	Label              [32]byte
	ManufacturerID     [32]byte
	Model              [16]byte
	SerialNumber       [16]byte
	Flags              uint
	MaxSessionCount    uint
	SessionCount       uint
	MaxRwSessionCount  uint
	RwSessionCount     uint
	MaxPinLen          uint
	MinPinLen          uint
	TotalPublicMemory  uint
	FreePublicMemory   uint
	TotalPrivateMemory uint
	FreePrivateMemory  uint
	hardwareVersion    Version
	firmwareVersion    Version
	UTCTime            [16]byte
}

/* SesionInfo provides information about a session. */
type SessionInfo struct {
	SlotID      uint
	Sate        uint
	Flags       uint
	DeviceError uint
}

// Attribute holds an attribute type/value combination.
type Attribute struct {
	Type  uint
	Value []byte
}

func NewAttribute(typ uint, x interface{}) *Attribute {
	a := new(Attribute)
	a.Type = typ
	if x == nil {
		return a
	}
	switch x.(type) {
	case bool: // create bbool
		if x.(bool) {
			a.Value = []byte{1}
			break
		}
		a.Value = []byte{0}
	case uint, int:
		var y uint
		if _, ok := x.(int); ok {
			y = uint(x.(int))
		}
		if _, ok := x.(uint); ok {
			y = x.(uint)
		}
		switch int(C.Sizeof()) {
		case 4:
			a.Value = make([]byte, 4)
			a.Value[0] = byte(y)
			a.Value[1] = byte(y >> 8)
			a.Value[2] = byte(y >> 16)
			a.Value[3] = byte(y >> 24)
		case 8:
			a.Value = make([]byte, 8)
			a.Value[0] = byte(y)
			a.Value[1] = byte(y >> 8)
			a.Value[2] = byte(y >> 16)
			a.Value[3] = byte(y >> 24)
			a.Value[4] = byte(y >> 32)
			a.Value[5] = byte(y >> 40)
			a.Value[6] = byte(y >> 48)
			a.Value[7] = byte(y >> 56)
		}
	case string:
		a.Value = []byte(x.(string))
	case []byte: // just copy
		a.Value = x.([]byte)
	default:
		panic("pkcs11: unhandled attribute type")
	}
	return a
}

// cAttribute returns the start address and the length of an attribute list.
func cAttributeList(a []*Attribute) (C.CK_ATTRIBUTE_PTR, C.CK_ULONG) {
	if len(a) == 0 {
		return nil, 0
	}
	pa := make([]C.CK_ATTRIBUTE, len(a))
	for i := 0; i < len(a); i++ {
		pa[i]._type = C.CK_ATTRIBUTE_TYPE(a[i].Type)
		if a[i].Value == nil {
			continue
		}
		pa[i].pValue = C.CK_VOID_PTR((&a[i].Value[0]))
		pa[i].ulValueLen = C.CK_ULONG(len(a[i].Value))
	}
	return C.CK_ATTRIBUTE_PTR(&pa[0]), C.CK_ULONG(len(a))
}

/* Date is a structure that defines a date. */
type Date struct {
	Year  [4]byte // the year ("1900" - "9999")
	Month [2]byte // the month ("01" - "12")
	Day   [2]byte // the day   ("01" - "31")
}

// Mechanism holds an mechanism type/value combination.
type Mechanism struct {
	Mechanism uint
	Parameter []byte
}

func NewMechanism(mech uint, x interface{}) *Mechanism {
	m := new(Mechanism)
	m.Mechanism = mech
	if x == nil {
		return m
	}
	// TODO(miek): Not seen anything as elaborate as Attributes, so for know do nothing.
	return m
}

func cMechanismList(m []*Mechanism) (C.CK_MECHANISM_PTR, C.CK_ULONG) {
	if len(m) == 0 {
		return nil, 0
	}
	pm := make([]C.CK_MECHANISM, len(m))
	for i := 0; i < len(m); i++ {
		pm[i].mechanism = C.CK_MECHANISM_TYPE(m[i].Mechanism)
		if m[i].Parameter == nil {
			continue
		}
		pm[i].pParameter = C.CK_VOID_PTR(&(m[i].Parameter[0]))
		pm[i].ulParameterLen = C.CK_ULONG(len(m[i].Parameter))
	}
	return C.CK_MECHANISM_PTR(&pm[0]), C.CK_ULONG(len(m))
}

type MechanismInfo struct {
	MinKeySize uint
	MaxKeySize uint
	Flags      uint
}
<commit_msg>Slight documentation tweaks<commit_after>package pkcs11

/*
#define CK_PTR *
#ifndef NULL_PTR
#define NULL_PTR 0
#endif
#define CK_DEFINE_FUNCTION(returnType, name) returnType name
#define CK_DECLARE_FUNCTION(returnType, name) returnType name
#define CK_DECLARE_FUNCTION_POINTER(returnType, name) returnType (* name)
#define CK_CALLBACK_FUNCTION(returnType, name) returnType (* name)

#include <stdlib.h>
#include "pkcs11.h"

CK_ULONG Index(CK_ULONG_PTR array, CK_ULONG i)
{
	return array[i];
}

CK_ULONG Sizeof()
{
	return sizeof(CK_ULONG);
}
*/
import "C"

import (
	"fmt"
	"unsafe"
)

// toList converts from a C style array to a []uint.
func toList(clist C.CK_ULONG_PTR, size C.CK_ULONG) []uint {
	l := make([]uint, int(size))
	for i := 0; i < len(l); i++ {
		l[i] = uint(C.Index(clist, C.CK_ULONG(i)))
	}
	defer C.free(unsafe.Pointer(clist))
	return l
}

// cBBool converts a bool to a CK_BBOOL.
func cBBool(x bool) C.CK_BBOOL {
	if x {
		return C.CK_BBOOL(C.CK_TRUE)
	}
	return C.CK_BBOOL(C.CK_FALSE)
}

// Error represents an PKCS#11 error.
type Error uint

func (e Error) Error() string {
	return "pkcs11: " + fmt.Sprintf("pkcs11: 0x%X: %s", uint(e), strerror[uint(e)])
}

func toError(e C.CK_RV) error {
	if e == C.CKR_OK {
		return nil
	}
	return Error(e)
}

/* SessionHandle is a Cryptoki-assigned value that identifies a session. */
type SessionHandle uint

/* ObjectHandle is a token-specific identifier for an object.  */
type ObjectHandle uint

// Version represents any version information from the library.
type Version struct {
	Major byte
	Minor byte
}

type SlotEvent struct {
	SlotID uint
}

// Info provides information about the library and hardware used.
type Info struct {
	CryptokiVersion    Version
	ManufacturerID     [32]byte
	Flags              uint
	LibraryDescription [32]byte
	LibraryVersion     Version
}

/* SlotInfo provides information about a slot. */
type SlotInfo struct {
	SlotDescription [64]byte
	ManufacturerID  [32]byte
	Flags           uint
	HardwareVersion Version
	FirmwareVersion Version
}

/* TokenInfo provides information about a token. */
type TokenInfo struct {
	Label              [32]byte
	ManufacturerID     [32]byte
	Model              [16]byte
	SerialNumber       [16]byte
	Flags              uint
	MaxSessionCount    uint
	SessionCount       uint
	MaxRwSessionCount  uint
	RwSessionCount     uint
	MaxPinLen          uint
	MinPinLen          uint
	TotalPublicMemory  uint
	FreePublicMemory   uint
	TotalPrivateMemory uint
	FreePrivateMemory  uint
	hardwareVersion    Version
	firmwareVersion    Version
	UTCTime            [16]byte
}

/* SesionInfo provides information about a session. */
type SessionInfo struct {
	SlotID      uint
	Sate        uint
	Flags       uint
	DeviceError uint
}

// Attribute holds an attribute type/value combination.
type Attribute struct {
	Type  uint
	Value []byte
}

func NewAttribute(typ uint, x interface{}) *Attribute {
	a := new(Attribute)
	a.Type = typ
	if x == nil {
		return a
	}
	switch x.(type) {
	case bool: // create bbool
		if x.(bool) {
			a.Value = []byte{1}
			break
		}
		a.Value = []byte{0}
	case uint, int:
		var y uint
		if _, ok := x.(int); ok {
			y = uint(x.(int))
		}
		if _, ok := x.(uint); ok {
			y = x.(uint)
		}
		switch int(C.Sizeof()) {
		case 4:
			a.Value = make([]byte, 4)
			a.Value[0] = byte(y)
			a.Value[1] = byte(y >> 8)
			a.Value[2] = byte(y >> 16)
			a.Value[3] = byte(y >> 24)
		case 8:
			a.Value = make([]byte, 8)
			a.Value[0] = byte(y)
			a.Value[1] = byte(y >> 8)
			a.Value[2] = byte(y >> 16)
			a.Value[3] = byte(y >> 24)
			a.Value[4] = byte(y >> 32)
			a.Value[5] = byte(y >> 40)
			a.Value[6] = byte(y >> 48)
			a.Value[7] = byte(y >> 56)
		}
	case string:
		a.Value = []byte(x.(string))
	case []byte: // just copy
		a.Value = x.([]byte)
	default:
		panic("pkcs11: unhandled attribute type")
	}
	return a
}

// cAttribute returns the start address and the length of an attribute list.
func cAttributeList(a []*Attribute) (C.CK_ATTRIBUTE_PTR, C.CK_ULONG) {
	if len(a) == 0 {
		return nil, 0
	}
	pa := make([]C.CK_ATTRIBUTE, len(a))
	for i := 0; i < len(a); i++ {
		pa[i]._type = C.CK_ATTRIBUTE_TYPE(a[i].Type)
		if a[i].Value == nil {
			continue
		}
		pa[i].pValue = C.CK_VOID_PTR((&a[i].Value[0]))
		pa[i].ulValueLen = C.CK_ULONG(len(a[i].Value))
	}
	return C.CK_ATTRIBUTE_PTR(&pa[0]), C.CK_ULONG(len(a))
}

/* Date is a structure that defines a date. */
type Date struct {
	Year  [4]byte // the year ("1900" - "9999")
	Month [2]byte // the month ("01" - "12")
	Day   [2]byte // the day   ("01" - "31")
}

// Mechanism holds an mechanism type/value combination.
type Mechanism struct {
	Mechanism uint
	Parameter []byte
}

func NewMechanism(mech uint, x interface{}) *Mechanism {
	m := new(Mechanism)
	m.Mechanism = mech
	if x == nil {
		return m
	}
	// TODO(miek): Not seen anything as elaborate as Attributes, so for know do nothing.
	return m
}

func cMechanismList(m []*Mechanism) (C.CK_MECHANISM_PTR, C.CK_ULONG) {
	if len(m) == 0 {
		return nil, 0
	}
	pm := make([]C.CK_MECHANISM, len(m))
	for i := 0; i < len(m); i++ {
		pm[i].mechanism = C.CK_MECHANISM_TYPE(m[i].Mechanism)
		if m[i].Parameter == nil {
			continue
		}
		pm[i].pParameter = C.CK_VOID_PTR(&(m[i].Parameter[0]))
		pm[i].ulParameterLen = C.CK_ULONG(len(m[i].Parameter))
	}
	return C.CK_MECHANISM_PTR(&pm[0]), C.CK_ULONG(len(m))
}

type MechanismInfo struct {
	MinKeySize uint
	MaxKeySize uint
	Flags      uint
}
<|endoftext|>


<commit_before>package graphql

import (
	"github.com/graphql-go/graphql/gqlerrors"
)

// type Schema interface{}

// Result has the response, errors and extensions from the resolved schema
type Result struct {
	Data       interface{}                `json:"data"`
	Errors     []gqlerrors.FormattedError `json:"errors,omitempty"`
	Extensions map[string]interface{}     `json:"extensions,omitempty"`
}

// HasErrors just a simple function to help you decide if the result has errors or not
func (r *Result) HasErrors() bool {
	return len(r.Errors) > 0
}

func (r *Result) addExtensionResults(p *ExecuteParams) {
	r.Extensions = map[string]interface{}{}
	for _, ext := range p.Schema.extensions {
		if ext.HasResult() {
			r.Extensions[ext.Name()] = ext.GetResult(p.Context)
		}
	}
}
<commit_msg>Fix tests<commit_after>package graphql

import (
	"github.com/graphql-go/graphql/gqlerrors"
)

// type Schema interface{}

// Result has the response, errors and extensions from the resolved schema
type Result struct {
	Data       interface{}                `json:"data"`
	Errors     []gqlerrors.FormattedError `json:"errors,omitempty"`
	Extensions map[string]interface{}     `json:"extensions,omitempty"`
}

// HasErrors just a simple function to help you decide if the result has errors or not
func (r *Result) HasErrors() bool {
	return len(r.Errors) > 0
}

func (r *Result) addExtensionResults(p *ExecuteParams) {
	if len(p.Schema.extensions) != 0 {
		r.Extensions = map[string]interface{}{}
		for _, ext := range p.Schema.extensions {
			if ext.HasResult() {
				r.Extensions[ext.Name()] = ext.GetResult(p.Context)
			}
		}
	} else {
		r.Extensions = nil
	}
}
<|endoftext|>


<commit_before>package gameprocessor

import (
	"fmt"
	"strings"

	"github.com/beevee/switchers"
)

func (gp *GameProcessor) executeTrumpCommand(cmd command, player *switchers.Player) {
	if player.State == switchers.PlayerStateModerating {
		round, err := gp.RoundRepository.GetActiveRound()
		if round.ID == "" {
			gp.Bot.SendMessage(player.ID, responseTrumpNothingToModerate)
			return
		}
		if err != nil {
			gp.Bot.SendMessage(player.ID, fmt.Sprintf(responseTrumpSomethingWrong, err))
			return
		}

		team := round.Teams[player.ModeratingTeamIndex]
		if team.State != teamStateModeration {
			gp.Bot.SendMessage(player.ID, responseTrumpAlreadyModerated)
		} else {
			switch strings.ToLower(cmd.text) {
			case commandYes:
				if err = gp.RoundRepository.SetTeamState(round, player.ModeratingTeamIndex, teamStateWon); err != nil {
					gp.Logger.Log("msg", "failed to set won team state (playing)", "teamindex", player.ModeratingTeamIndex, "error", err)
				}
				gp.Logger.Log("msg", "team won by answering correctly after moderation", "teamindex", player.ModeratingTeamIndex, "answer", team.Answer)
				gp.notifyTrumps(fmt.Sprintf(responseTrumpTeamWon, player.ModeratingTeamIndex))
				gp.updateActualTeamMemberStates(team, switchers.PlayerStateIdle)
				gp.increaseActualTeamMemberScores(team)
				gp.notifyActualTeamMembers(team, responseTeamWon)

			case commandNo:
				if err = gp.RoundRepository.SetTeamState(round, player.ModeratingTeamIndex, teamStateLost); err != nil {
					gp.Logger.Log("msg", "failed to set lost team state (playing)", "teamindex", player.ModeratingTeamIndex, "error", err)
				}
				gp.Logger.Log("msg", "team lost by answering incorrectly after moderation (playing)", "teamindex", player.ModeratingTeamIndex)
				gp.notifyTrumps(fmt.Sprintf(responseTrumpTeamLost, player.ModeratingTeamIndex))
				gp.updateActualTeamMemberStates(team, switchers.PlayerStateIdle)
				gp.notifyActualTeamMembers(team, responseTeamLost)
			}
		}

		gp.Bot.SendMessage(player.ID, "We made America great again!")
		if err := gp.PlayerRepository.SetState(player, switchers.PlayerStateIdle); err != nil {
			gp.Bot.SendMessage(player.ID, fmt.Sprintf(responseTrumpSomethingWrong, err))
		}
		return
	}

	switch cmd.text {
	case commandNewRound:
		if err := gp.startNewRound(); err != nil {
			gp.Bot.SendMessage(player.ID, fmt.Sprintf(responseTrumpSomethingWrong, err))
			return
		}
		gp.Bot.SendMessage(player.ID, responseTrumpRoundStarted)
		return

	case commandModerate:
		round, err := gp.RoundRepository.GetActiveRound()
		if round.ID == "" {
			gp.Bot.SendMessage(player.ID, responseTrumpNothingToModerate)
			return
		}
		if err != nil {
			gp.Bot.SendMessage(player.ID, fmt.Sprintf(responseTrumpSomethingWrong, err))
			return
		}
		for i, team := range round.Teams {
			if team.State == teamStateModeration {
				if err := gp.PlayerRepository.SetModeratingTeamIndex(player, i); err != nil {
					gp.Bot.SendMessage(player.ID, fmt.Sprintf(responseTrumpSomethingWrong, err))
					return
				}
				if err := gp.PlayerRepository.SetState(player, switchers.PlayerStateModerating); err != nil {
					gp.Bot.SendMessage(player.ID, fmt.Sprintf(responseTrumpSomethingWrong, err))
					return
				}
				gp.Bot.SendMessage(player.ID, responseTrumpTaskPrefix+team.ActualTask.Text)
				gp.Bot.ForwardMessage(player.ID, team.Answer.Text, team.Answer.MessageID, team.Answer.OwnerID)
				gp.Bot.SendMessage(player.ID, responseTrumpModerationInstructions)
				return
			}
		}

	case commandLeaders:
		leaders, err := gp.PlayerRepository.GetTop(500)
		if err != nil {
			gp.Bot.SendMessage(player.ID, fmt.Sprintf(responseTrumpSomethingWrong, err))
			return
		}
		var response string
		i := 1
		for _, leader := range leaders {
			response += fmt.Sprintf("%d. %s — %d\n", i, leader.Name, leader.Score)
			i++
		}
		gp.Bot.SendMessage(player.ID, response)
		return

	case commandResign:
		if err := gp.PlayerRepository.SetTrump(player, false); err != nil {
			gp.Bot.SendMessage(player.ID, fmt.Sprintf(responseTrumpSomethingWrong, err))
			return
		}
		gp.Bot.SendMessage(player.ID, responseTrumpResigned)
		return
	}

	gp.Bot.SendMessage(player.ID, responseTrumpDefault)
}

func (gp *GameProcessor) notifyTrumps(message string) {
	trumpIDs, err := gp.PlayerRepository.GetAllTrumps()
	if err != nil {
		gp.Logger.Log("msg", "failed to notify Trumps", "message", message, "error", err)
	} else {
		for trumpID := range trumpIDs {
			gp.Bot.SendMessage(trumpID, message)
		}
	}
}
<commit_msg>Fix unsupported data type in logging<commit_after>package gameprocessor

import (
	"fmt"
	"strings"

	"github.com/beevee/switchers"
)

func (gp *GameProcessor) executeTrumpCommand(cmd command, player *switchers.Player) {
	if player.State == switchers.PlayerStateModerating {
		round, err := gp.RoundRepository.GetActiveRound()
		if round.ID == "" {
			gp.Bot.SendMessage(player.ID, responseTrumpNothingToModerate)
			return
		}
		if err != nil {
			gp.Bot.SendMessage(player.ID, fmt.Sprintf(responseTrumpSomethingWrong, err))
			return
		}

		team := round.Teams[player.ModeratingTeamIndex]
		if team.State != teamStateModeration {
			gp.Bot.SendMessage(player.ID, responseTrumpAlreadyModerated)
		} else {
			switch strings.ToLower(cmd.text) {
			case commandYes:
				if err = gp.RoundRepository.SetTeamState(round, player.ModeratingTeamIndex, teamStateWon); err != nil {
					gp.Logger.Log("msg", "failed to set won team state (playing)", "teamindex", player.ModeratingTeamIndex, "error", err)
				}
				gp.Logger.Log("msg", "team won by answering correctly after moderation", "teamindex", player.ModeratingTeamIndex, "answer", team.Answer.Text)
				gp.notifyTrumps(fmt.Sprintf(responseTrumpTeamWon, player.ModeratingTeamIndex))
				gp.updateActualTeamMemberStates(team, switchers.PlayerStateIdle)
				gp.increaseActualTeamMemberScores(team)
				gp.notifyActualTeamMembers(team, responseTeamWon)

			case commandNo:
				if err = gp.RoundRepository.SetTeamState(round, player.ModeratingTeamIndex, teamStateLost); err != nil {
					gp.Logger.Log("msg", "failed to set lost team state (playing)", "teamindex", player.ModeratingTeamIndex, "error", err)
				}
				gp.Logger.Log("msg", "team lost by answering incorrectly after moderation (playing)", "teamindex", player.ModeratingTeamIndex)
				gp.notifyTrumps(fmt.Sprintf(responseTrumpTeamLost, player.ModeratingTeamIndex))
				gp.updateActualTeamMemberStates(team, switchers.PlayerStateIdle)
				gp.notifyActualTeamMembers(team, responseTeamLost)
			}
		}

		gp.Bot.SendMessage(player.ID, "We made America great again!")
		if err := gp.PlayerRepository.SetState(player, switchers.PlayerStateIdle); err != nil {
			gp.Bot.SendMessage(player.ID, fmt.Sprintf(responseTrumpSomethingWrong, err))
		}
		return
	}

	switch cmd.text {
	case commandNewRound:
		if err := gp.startNewRound(); err != nil {
			gp.Bot.SendMessage(player.ID, fmt.Sprintf(responseTrumpSomethingWrong, err))
			return
		}
		gp.Bot.SendMessage(player.ID, responseTrumpRoundStarted)
		return

	case commandModerate:
		round, err := gp.RoundRepository.GetActiveRound()
		if round.ID == "" {
			gp.Bot.SendMessage(player.ID, responseTrumpNothingToModerate)
			return
		}
		if err != nil {
			gp.Bot.SendMessage(player.ID, fmt.Sprintf(responseTrumpSomethingWrong, err))
			return
		}
		for i, team := range round.Teams {
			if team.State == teamStateModeration {
				if err := gp.PlayerRepository.SetModeratingTeamIndex(player, i); err != nil {
					gp.Bot.SendMessage(player.ID, fmt.Sprintf(responseTrumpSomethingWrong, err))
					return
				}
				if err := gp.PlayerRepository.SetState(player, switchers.PlayerStateModerating); err != nil {
					gp.Bot.SendMessage(player.ID, fmt.Sprintf(responseTrumpSomethingWrong, err))
					return
				}
				gp.Bot.SendMessage(player.ID, responseTrumpTaskPrefix+team.ActualTask.Text)
				gp.Bot.ForwardMessage(player.ID, team.Answer.Text, team.Answer.MessageID, team.Answer.OwnerID)
				gp.Bot.SendMessage(player.ID, responseTrumpModerationInstructions)
				return
			}
		}

	case commandLeaders:
		leaders, err := gp.PlayerRepository.GetTop(500)
		if err != nil {
			gp.Bot.SendMessage(player.ID, fmt.Sprintf(responseTrumpSomethingWrong, err))
			return
		}
		var response string
		i := 1
		for _, leader := range leaders {
			response += fmt.Sprintf("%d. %s — %d\n", i, leader.Name, leader.Score)
			i++
		}
		gp.Bot.SendMessage(player.ID, response)
		return

	case commandResign:
		if err := gp.PlayerRepository.SetTrump(player, false); err != nil {
			gp.Bot.SendMessage(player.ID, fmt.Sprintf(responseTrumpSomethingWrong, err))
			return
		}
		gp.Bot.SendMessage(player.ID, responseTrumpResigned)
		return
	}

	gp.Bot.SendMessage(player.ID, responseTrumpDefault)
}

func (gp *GameProcessor) notifyTrumps(message string) {
	trumpIDs, err := gp.PlayerRepository.GetAllTrumps()
	if err != nil {
		gp.Logger.Log("msg", "failed to notify Trumps", "message", message, "error", err)
	} else {
		for trumpID := range trumpIDs {
			gp.Bot.SendMessage(trumpID, message)
		}
	}
}
<|endoftext|>


<commit_before>// Copyright (C) 2017 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 sync provides interfaces for managing externally synchronized APIs.
//
// The methods allow queries to be performed on an API to allow
// the determination of where blocking operations between threads
// of execution happen. These methods allow us to reason about
// execution in a non-linear way.
package sync

import (
	"context"

	"github.com/google/gapid/core/app/status"
	"github.com/google/gapid/gapis/api"
	"github.com/google/gapid/gapis/api/transform"
	"github.com/google/gapid/gapis/capture"
	"github.com/google/gapid/gapis/service/path"
)

// NoMECSubcommandsError is used to notify the caller that this API does not
// support MEC subcomands.
type NoMECSubcommandsError struct{}

func (e NoMECSubcommandsError) Error() string {
	return "This api does not have MEC subcommands"
}

// SynchronizedAPI defines an API that explicitly has multiple threads of
// execution. This means that replays are not necessarily linear in terms
// of commands.
type SynchronizedAPI interface {
	// GetTerminator returns a transform that will allow the given capture to be terminated
	// after a command.
	GetTerminator(ctx context.Context, c *path.Capture) (transform.Terminator, error)

	// ResolveSynchronization resolve all of the synchronization information for
	// the given API.
	ResolveSynchronization(ctx context.Context, d *Data, c *path.Capture) error

	// MutateSubcommands mutates the given Cmd and calls callbacks for subcommands
	// attached to that Cmd. preSubCmdCallback and postSubCmdCallback will be
	// called before and after executing each subcommand callback.
	MutateSubcommands(ctx context.Context, id api.CmdID, cmd api.Cmd, s *api.GlobalState,
		preSubCmdCallback func(*api.GlobalState, api.SubCmdIdx, api.Cmd),
		postSubCmdCallback func(*api.GlobalState, api.SubCmdIdx, api.Cmd)) error

	// FlattenSubcommandIdx returns the flatten command id for the subcommand
	// specified by the given SubCmdIdx. If flattening succeeded, the flatten
	// command id and true will be returned, otherwise, zero and false will be
	// returned.
	FlattenSubcommandIdx(idx api.SubCmdIdx, d *Data, initialCall bool) (api.CmdID, bool)

	// RecoverMidExecutionCommand returns a virtual command, used to describe the
	// a subcommand that was created before the start of the trace.
	// If the api does not have mid-execution commands, NoMECSubcommandsError should be returned.
	RecoverMidExecutionCommand(ctx context.Context, c *path.Capture, data interface{}) (api.Cmd, error)

	// IsTrivialTerminator returns true if stopping at the given command is trivial.
	IsTrivialTerminator(ctx context.Context, c *path.Capture, cmd api.SubCmdIdx) (bool, error)
}

type writer struct {
	state *api.GlobalState
	cmds  []api.Cmd
}

func (s *writer) State() *api.GlobalState { return s.state }

func (s *writer) MutateAndWrite(ctx context.Context, id api.CmdID, cmd api.Cmd) {
	cmd.Mutate(ctx, id, s.state, nil)
	s.cmds = append(s.cmds, cmd)
}

// MutationCmdsFor returns a list of command that represent the correct
// mutations to have the state for all commands before and including the given
// index.
func MutationCmdsFor(ctx context.Context, c *path.Capture, data *Data, cmds []api.Cmd, id api.CmdID, subindex api.SubCmdIdx, initialCall bool) ([]api.Cmd, error) {
	// This is where we want to handle sub-states
	// This involves transforming the tree for the given Indices, and
	//   then mutating that.
	rc, err := capture.ResolveFromPath(ctx, c)
	if err != nil {
		return nil, err
	}

	fullCommand := api.SubCmdIdx{uint64(id)}
	fullCommand = append(fullCommand, subindex...)

	lastCmd := cmds[len(cmds)-1]
	if api.CmdID(len(cmds)) > id {
		lastCmd = cmds[id]
	}

	if sync, ok := lastCmd.API().(SynchronizedAPI); ok {
		// For Vulkan, when preparing the mutation for memory view, we need to get
		// the initial call ID for the requesting subcommand.
		if flattenIdx, ok := sync.FlattenSubcommandIdx(fullCommand, data, initialCall); ok {
			id = flattenIdx
			subindex = api.SubCmdIdx{}
		}
	}

	terminators := make([]transform.Terminator, 0)
	transforms := transform.Transforms{}
	isTrivial := true
	for _, api := range rc.APIs {
		if sync, ok := api.(SynchronizedAPI); ok {
			term, err := sync.GetTerminator(ctx, c)
			if err != nil {
				return nil, err
			}

			t, err := sync.IsTrivialTerminator(ctx, c, fullCommand)
			if err != nil {
				return nil, err
			}
			isTrivial = t && isTrivial
			if term != nil {
				terminators = append(terminators, term)
				continue
			}
		}
		terminators = append(terminators, transform.NewEarlyTerminator(api.ID()))
	}
	for _, t := range terminators {
		if err := t.Add(ctx, 0, id, subindex); err != nil {
			return nil, err
		}
		transforms.Add(t)
	}
	if isTrivial {
		return cmds[0:id], nil
	}
	w := &writer{rc.NewState(ctx), nil}
	transforms.Transform(ctx, cmds, w)

	return w.cmds, nil
}

// MutateWithSubcommands mutates a list of commands. And after mutating each
// Cmd, the given post-Cmd callback will be called. And the given
// pre-subcommand callback and the post-subcommand callback will be called
// before and after calling each subcommand callback function.
func MutateWithSubcommands(ctx context.Context, c *path.Capture, cmds []api.Cmd,
	postCmdCb func(*api.GlobalState, api.SubCmdIdx, api.Cmd),
	preSubCmdCb func(*api.GlobalState, api.SubCmdIdx, api.Cmd),
	postSubCmdCb func(*api.GlobalState, api.SubCmdIdx, api.Cmd)) error {

	ctx = status.Start(ctx, "Sync.MutateWithSubcommands")
	defer status.Finish(ctx)

	// This is where we want to handle sub-states
	// This involves transforming the tree for the given Indices, and
	//   then mutating that.
	rc, err := capture.ResolveFromPath(ctx, c)
	if err != nil {
		return err
	}
	s := rc.NewState(ctx)

	return api.ForeachCmd(ctx, cmds, func(ctx context.Context, id api.CmdID, cmd api.Cmd) error {
		if sync, ok := cmd.API().(SynchronizedAPI); ok {
			sync.MutateSubcommands(ctx, id, cmd, s, preSubCmdCb, postSubCmdCb)
		} else {
			cmd.Mutate(ctx, id, s, nil)
		}
		postCmdCb(s, api.SubCmdIdx{uint64(id)}, cmd)
		return nil
	})
}
<commit_msg>Fix MutationCmdsFor chopping of a command.<commit_after>// Copyright (C) 2017 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 sync provides interfaces for managing externally synchronized APIs.
//
// The methods allow queries to be performed on an API to allow
// the determination of where blocking operations between threads
// of execution happen. These methods allow us to reason about
// execution in a non-linear way.
package sync

import (
	"context"

	"github.com/google/gapid/core/app/status"
	"github.com/google/gapid/gapis/api"
	"github.com/google/gapid/gapis/api/transform"
	"github.com/google/gapid/gapis/capture"
	"github.com/google/gapid/gapis/service/path"
)

// NoMECSubcommandsError is used to notify the caller that this API does not
// support MEC subcomands.
type NoMECSubcommandsError struct{}

func (e NoMECSubcommandsError) Error() string {
	return "This api does not have MEC subcommands"
}

// SynchronizedAPI defines an API that explicitly has multiple threads of
// execution. This means that replays are not necessarily linear in terms
// of commands.
type SynchronizedAPI interface {
	// GetTerminator returns a transform that will allow the given capture to be terminated
	// after a command.
	GetTerminator(ctx context.Context, c *path.Capture) (transform.Terminator, error)

	// ResolveSynchronization resolve all of the synchronization information for
	// the given API.
	ResolveSynchronization(ctx context.Context, d *Data, c *path.Capture) error

	// MutateSubcommands mutates the given Cmd and calls callbacks for subcommands
	// attached to that Cmd. preSubCmdCallback and postSubCmdCallback will be
	// called before and after executing each subcommand callback.
	MutateSubcommands(ctx context.Context, id api.CmdID, cmd api.Cmd, s *api.GlobalState,
		preSubCmdCallback func(*api.GlobalState, api.SubCmdIdx, api.Cmd),
		postSubCmdCallback func(*api.GlobalState, api.SubCmdIdx, api.Cmd)) error

	// FlattenSubcommandIdx returns the flatten command id for the subcommand
	// specified by the given SubCmdIdx. If flattening succeeded, the flatten
	// command id and true will be returned, otherwise, zero and false will be
	// returned.
	FlattenSubcommandIdx(idx api.SubCmdIdx, d *Data, initialCall bool) (api.CmdID, bool)

	// RecoverMidExecutionCommand returns a virtual command, used to describe the
	// a subcommand that was created before the start of the trace.
	// If the api does not have mid-execution commands, NoMECSubcommandsError should be returned.
	RecoverMidExecutionCommand(ctx context.Context, c *path.Capture, data interface{}) (api.Cmd, error)

	// IsTrivialTerminator returns true if stopping at the given command is trivial.
	IsTrivialTerminator(ctx context.Context, c *path.Capture, cmd api.SubCmdIdx) (bool, error)
}

type writer struct {
	state *api.GlobalState
	cmds  []api.Cmd
}

func (s *writer) State() *api.GlobalState { return s.state }

func (s *writer) MutateAndWrite(ctx context.Context, id api.CmdID, cmd api.Cmd) {
	cmd.Mutate(ctx, id, s.state, nil)
	s.cmds = append(s.cmds, cmd)
}

// MutationCmdsFor returns a list of command that represent the correct
// mutations to have the state for all commands before and including the given
// index.
func MutationCmdsFor(ctx context.Context, c *path.Capture, data *Data, cmds []api.Cmd, id api.CmdID, subindex api.SubCmdIdx, initialCall bool) ([]api.Cmd, error) {
	// This is where we want to handle sub-states
	// This involves transforming the tree for the given Indices, and
	//   then mutating that.
	rc, err := capture.ResolveFromPath(ctx, c)
	if err != nil {
		return nil, err
	}

	fullCommand := api.SubCmdIdx{uint64(id)}
	fullCommand = append(fullCommand, subindex...)

	lastCmd := cmds[len(cmds)-1]
	if api.CmdID(len(cmds)) > id {
		lastCmd = cmds[id]
	}

	if sync, ok := lastCmd.API().(SynchronizedAPI); ok {
		// For Vulkan, when preparing the mutation for memory view, we need to get
		// the initial call ID for the requesting subcommand.
		if flattenIdx, ok := sync.FlattenSubcommandIdx(fullCommand, data, initialCall); ok {
			id = flattenIdx
			subindex = api.SubCmdIdx{}
		}
	}

	terminators := make([]transform.Terminator, 0)
	transforms := transform.Transforms{}
	isTrivial := true
	for _, api := range rc.APIs {
		if sync, ok := api.(SynchronizedAPI); ok {
			term, err := sync.GetTerminator(ctx, c)
			if err != nil {
				return nil, err
			}

			t, err := sync.IsTrivialTerminator(ctx, c, fullCommand)
			if err != nil {
				return nil, err
			}
			isTrivial = t && isTrivial
			if term != nil {
				terminators = append(terminators, term)
				continue
			}
		}
		terminators = append(terminators, transform.NewEarlyTerminator(api.ID()))
	}
	for _, t := range terminators {
		if err := t.Add(ctx, 0, id, subindex); err != nil {
			return nil, err
		}
		transforms.Add(t)
	}
	if isTrivial {
		return cmds[0 : id+1], nil
	}
	w := &writer{rc.NewState(ctx), nil}
	transforms.Transform(ctx, cmds, w)

	return w.cmds, nil
}

// MutateWithSubcommands mutates a list of commands. And after mutating each
// Cmd, the given post-Cmd callback will be called. And the given
// pre-subcommand callback and the post-subcommand callback will be called
// before and after calling each subcommand callback function.
func MutateWithSubcommands(ctx context.Context, c *path.Capture, cmds []api.Cmd,
	postCmdCb func(*api.GlobalState, api.SubCmdIdx, api.Cmd),
	preSubCmdCb func(*api.GlobalState, api.SubCmdIdx, api.Cmd),
	postSubCmdCb func(*api.GlobalState, api.SubCmdIdx, api.Cmd)) error {

	ctx = status.Start(ctx, "Sync.MutateWithSubcommands")
	defer status.Finish(ctx)

	// This is where we want to handle sub-states
	// This involves transforming the tree for the given Indices, and
	//   then mutating that.
	rc, err := capture.ResolveFromPath(ctx, c)
	if err != nil {
		return err
	}
	s := rc.NewState(ctx)

	return api.ForeachCmd(ctx, cmds, func(ctx context.Context, id api.CmdID, cmd api.Cmd) error {
		if sync, ok := cmd.API().(SynchronizedAPI); ok {
			sync.MutateSubcommands(ctx, id, cmd, s, preSubCmdCb, postSubCmdCb)
		} else {
			cmd.Mutate(ctx, id, s, nil)
		}
		postCmdCb(s, api.SubCmdIdx{uint64(id)}, cmd)
		return nil
	})
}
<|endoftext|>