<commit_before>/**
 * (C) Copyright 2014, Deft Labs
 *
 * 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 dlshared

import (
	"sync"
	"time"
)

// The consumer is a generic component that is meant to be embedded into your applications. It
// allows you to create a specific number of goroutines to handle the realtime data/msg processing.
// It also has optional support for spillover processing if the goroutines cannot keep pace with
// the incoming events. If your spillover method blocks (i.e., cannot keep pace), it will cause further
// issues with incoming message processing. If you do not provide a spillover method, data will be dropped
// and a log statement will be generated for each discarded message.
// The contact is that you must call the NewConsumer method to create the struct.
// After that, you must call the Start/Stop methods before attempting to pass in a msg. If the passed
// consume function panics, the consumer will lose a goroutine each time, so don't panic!
type Consumer struct {

	logger Logger

	name string

	quitChannel chan bool

	consumeFunc func(msg interface{})

	spilloverFunc func(msg interface{})

	processorChannel chan interface{}

	receiveChannel chan interface{}

	processedChannel chan bool

	maxGoroutines int

	maxWaitOnStopInMs int64

	waitGroup *sync.WaitGroup
}

// Create the consumer. You must call this method to create a consumer. If you set the maxGoroutines
// to zero (or less) then it will spawn a new goroutine for each request and there is no limit. If maxGoroutines
// is set, these goroutines are created and added to a pool when Start is called. If you set channelBufferSize to something
// greater than zero then a buffered channel is created. The maxWaitOnStopMs is the amount of time the Stop
// method will wait for the goroutines to finish clearing out the processor channel. If the processor channel unbuffered,
// this does not apply. A maxWaitOnStopMs value of zero indicates an unlimited wait.
func NewConsumer(	name string,
					receiveChannel chan interface{},
					consumeFunc func(msg interface{}),
					spilloverFunc func(msg interface{}),
					maxGoroutines, channelBufferSize, maxWaitOnStopInMs int,
					logger Logger) *Consumer {

	if channelBufferSize < 0 {
		channelBufferSize = 0
	}

	if maxWaitOnStopInMs < 0 {
		maxWaitOnStopInMs = 0
	}

	if maxGoroutines <= 0 {
		maxGoroutines = 1
	}

	consumer := &Consumer{
		logger: logger,
		name: name,
		consumeFunc: consumeFunc,
		spilloverFunc: spilloverFunc,
		receiveChannel: receiveChannel,
		processorChannel: make(chan interface{}, channelBufferSize),
		quitChannel: make(chan bool),
		processedChannel: make(chan bool, maxGoroutines),
		maxGoroutines: maxGoroutines,
		maxWaitOnStopInMs: int64(maxWaitOnStopInMs),
		waitGroup: new(sync.WaitGroup),
	}

	return consumer
}

// This method listens to the processor channel and then
// calls the consume function passed. The passed consume
// function should never panic. Don't Panic!
func (self *Consumer) msgProcessor() {
	defer self.waitGroup.Done()
	for msg := range self.processorChannel {
		self.consumeFunc(msg)
		self.processedChannel <- true
	}
}

func (self *Consumer) listenForMsgs() {
	defer self.waitGroup.Done()
	msgsBeingProcessed := 0

    for {
        select {
			case msg := <- self.receiveChannel:
				if msgsBeingProcessed <= self.maxGoroutines {

					self.processorChannel <- msg
					msgsBeingProcessed++

				} else {
					if self.spilloverFunc == nil {
						self.logger.Logf(Warn, "Max concurrent messages (%d) reached in consumer: %s - dropping data (no spillover func set)", self.maxGoroutines, self.name)
					} else {
						// If this blocks, it will further compound problems with the consumer
						self.spilloverFunc(msg)
					}
				}
			case <- self.processedChannel: msgsBeingProcessed--
			case <- self.quitChannel: return
        }
    }
}

func (self *Consumer) Start() error {

	// Create the goroutine pool
	for idx := 0; idx < self.maxGoroutines; idx++ {
		self.waitGroup.Add(1)
		go self.msgProcessor()
	}

	// Create the message listener
	self.waitGroup.Add(1)
	go self.listenForMsgs()

	return nil
}

// This method will block until all goroutines exit. It is up to the
// caller to clear the receiveChannel.
func (self *Consumer) Stop() error {

	// Exit the listen for events select
	self.quitChannel <- true

	// If this is an unbuffered channel, close, wait for the goroutines
	// to exit and then get out of here.
	if cap(self.processorChannel) == 0 {
		close(self.processorChannel)
		self.waitGroup.Wait()
		return nil
	}

	// This is a buffered channel so we need to wait until the channel
	// is emptied (if configured to do so).
	if self.maxWaitOnStopInMs > 0 {
		start := CurrentTimeInMillis()

		for {
			if len(self.processorChannel) == 0 {
				break
			}

		 	if CurrentTimeInMillis() - start >= self.maxWaitOnStopInMs {
				break
			}

			time.Sleep(10 * time.Millisecond)
		}
	}

	// Close the processor channel and wait for all of the goroutines to return
	close(self.processorChannel)
	self.waitGroup.Wait()

	return nil
}

<commit_msg>layout changes.<commit_after>/**
 * (C) Copyright 2014, Deft Labs
 *
 * 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 dlshared

import (
	"sync"
	"time"
)

// The consumer is a generic component that is meant to be embedded into your applications. It
// allows you to create a specific number of goroutines to handle the realtime data/msg processing.
// It also has optional support for spillover processing if the goroutines cannot keep pace with
// the incoming events. If your spillover method blocks (i.e., cannot keep pace), it will cause further
// issues with incoming message processing. If you do not provide a spillover method, data will be dropped
// and a log statement will be generated for each discarded message.
// The contact is that you must call the NewConsumer method to create the struct.
// After that, you must call the Start/Stop methods before attempting to pass in a msg. If the passed
// consume function panics, the consumer will lose a goroutine each time, so don't panic!
type Consumer struct {

	logger Logger

	name string

	quitChannel chan bool

	consumeFunc func(msg interface{})

	spilloverFunc func(msg interface{})

	processorChannel chan interface{}

	receiveChannel chan interface{}

	processedChannel chan bool

	maxGoroutines int

	maxWaitOnStopInMs int64

	waitGroup *sync.WaitGroup
}

// Create the consumer. You must call this method to create a consumer. If you set the maxGoroutines
// to zero (or less) then it will spawn a new goroutine for each request and there is no limit. If maxGoroutines
// is set, these goroutines are created and added to a pool when Start is called. If you set channelBufferSize to something
// greater than zero then a buffered channel is created. The maxWaitOnStopMs is the amount of time the Stop
// method will wait for the goroutines to finish clearing out the processor channel. If the processor channel unbuffered,
// this does not apply. A maxWaitOnStopMs value of zero indicates an unlimited wait.
func NewConsumer(	name string,
					receiveChannel chan interface{},
					consumeFunc func(msg interface{}),
					spilloverFunc func(msg interface{}),
					maxGoroutines, channelBufferSize, maxWaitOnStopInMs int,
					logger Logger) *Consumer {

	if channelBufferSize < 0 { channelBufferSize = 0 }

	if maxWaitOnStopInMs < 0 { maxWaitOnStopInMs = 0 }

	if maxGoroutines <= 0 { maxGoroutines = 1 }

	consumer := &Consumer{
		logger: logger,
		name: name,
		consumeFunc: consumeFunc,
		spilloverFunc: spilloverFunc,
		receiveChannel: receiveChannel,
		processorChannel: make(chan interface{}, channelBufferSize),
		quitChannel: make(chan bool),
		processedChannel: make(chan bool, maxGoroutines),
		maxGoroutines: maxGoroutines,
		maxWaitOnStopInMs: int64(maxWaitOnStopInMs),
		waitGroup: new(sync.WaitGroup),
	}

	return consumer
}

// This method listens to the processor channel and then
// calls the consume function passed. The passed consume
// function should never panic. Don't Panic!
func (self *Consumer) msgProcessor() {
	defer self.waitGroup.Done()
	for msg := range self.processorChannel {
		self.consumeFunc(msg)
		self.processedChannel <- true
	}
}

func (self *Consumer) listenForMsgs() {
	defer self.waitGroup.Done()
	msgsBeingProcessed := 0

    for {
        select {
			case msg := <- self.receiveChannel:
				if msgsBeingProcessed <= self.maxGoroutines {

					self.processorChannel <- msg
					msgsBeingProcessed++

				} else {
					if self.spilloverFunc == nil {
						self.logger.Logf(Warn, "Max concurrent messages (%d) reached in consumer: %s - dropping data (no spillover func set)", self.maxGoroutines, self.name)
					} else {
						// If this blocks, it will further compound problems with the consumer
						self.spilloverFunc(msg)
					}
				}
			case <- self.processedChannel: msgsBeingProcessed--
			case <- self.quitChannel: return
        }
    }
}

func (self *Consumer) Start() error {

	// Create the goroutine pool
	for idx := 0; idx < self.maxGoroutines; idx++ {
		self.waitGroup.Add(1)
		go self.msgProcessor()
	}

	// Create the message listener
	self.waitGroup.Add(1)
	go self.listenForMsgs()

	return nil
}

// This method will block until all goroutines exit. It is up to the
// caller to clear the receiveChannel.
func (self *Consumer) Stop() error {

	// Exit the listen for events select
	self.quitChannel <- true

	// If this is an unbuffered channel, close, wait for the goroutines
	// to exit and then get out of here.
	if cap(self.processorChannel) == 0 {
		close(self.processorChannel)
		self.waitGroup.Wait()
		return nil
	}

	// This is a buffered channel so we need to wait until the channel
	// is emptied (if configured to do so).
	if self.maxWaitOnStopInMs > 0 {
		start := CurrentTimeInMillis()

		for {
			if len(self.processorChannel) == 0 {
				break
			}

		 	if CurrentTimeInMillis() - start >= self.maxWaitOnStopInMs {
				break
			}

			time.Sleep(10 * time.Millisecond)
		}
	}

	// Close the processor channel and wait for all of the goroutines to return
	close(self.processorChannel)
	self.waitGroup.Wait()

	return nil
}

<|endoftext|>


<commit_before>package play

import (
	"log"
	"reflect"
)

// An "interceptor" is a function that is invoked by the framework at a
// designated time (BEFORE or AFTER) an action invcation.
//
// Since an interceptor may be used across many user Controllers, it is a
// function that takes the base Controller, rather than a method on a user
// controller.
//
// An interceptor may optionally return a Result (instead of nil).  Depending on
// when the interceptor was invoked, the response is different:
// 1. BEFORE:  No further interceptors are invoked, and neither is the action.
// 2. AFTER: Further interceptors are still run.
// In all cases, any returned Result will take the place of any existing Result.
// But in the BEFORE case, that returned Result is guaranteed to be final, while
// in the AFTER case it is possible that a further interceptor could emit its
// own Result.
//
// Interceptors are called in the order that they are added.
//
// ***
//
// Two types of interceptors are provided: Funcs and Methods
//
// Func Interceptors may apply to any / all Controllers.
//
//   func example(*play.Controller) play.Result
//
// Method Interceptors are provided so that properties can be set on application
// controllers.
//
//   func (c AppController) example() play.Result
//   func (c *AppController) example() play.Result
//
type InterceptorFunc func(*Controller) Result
type InterceptorMethod interface{}
type InterceptTime int

const (
	BEFORE InterceptTime = iota
	AFTER
)

type Interception struct {
	When InterceptTime

	function InterceptorFunc
	method   InterceptorMethod

	callableValue reflect.Value
	targetType    reflect.Type
}

// Perform the given interception.
// val is a pointer to the App Controller.
func (i Interception) Invoke(val reflect.Value) reflect.Value {
	// Figure out what type of parameter the interceptor needs.
	var arg reflect.Value
	switch i.callableValue.Type().In(0) {
	case reflect.TypeOf(Controller{}):
		arg = val.Elem().Field(0).Elem()
	case reflect.TypeOf(&Controller{}):
		arg = val.Elem().Field(0)
	case val.Type():
		arg = val
	case val.Type().Elem():
		arg = val.Elem()
	default:
		// This should never happen.
		// Validation happens at the time the interceptor is installed.
		log.Fatalln("Unrecognized parameter type.")
	}
	vals := i.callableValue.Call([]reflect.Value{arg})
	return vals[0]
}

var interceptors []*Interception

// Install a general interceptor.
// This can be applied to any Controller.
// It must have the signature of:
// func example(c *play.Controller) play.Result
func InterceptFunc(intc InterceptorFunc, when InterceptTime, target interface{}) {
	interceptors = append(interceptors, &Interception{
		When:          when,
		function:      intc,
		callableValue: reflect.ValueOf(intc),
		targetType:    reflect.TypeOf(target),
	})
}

// Install an interceptor method that applies to its own Controller.
// func (c AppController) example() play.Result
// func (c *AppController) example() play.Result
func InterceptMethod(intc InterceptorMethod, when InterceptTime) {
	methodType := reflect.TypeOf(intc)
	if methodType.Kind() != reflect.Func || methodType.NumOut() != 1 || methodType.NumIn() != 1 {
		log.Fatalln("Interceptor method should have signature like",
			"'func (c *AppController) example() play.Result' but was", methodType)
	}
	interceptors = append(interceptors, &Interception{
		When:          when,
		method:        intc,
		callableValue: reflect.ValueOf(intc),
		targetType:    methodType.In(0),
	})
}

func getInterceptors(when InterceptTime, targetType reflect.Type) []*Interception {
	result := []*Interception{}
	for _, intc := range interceptors {
		if intc.When == when &&
			(intc.targetType == targetType || intc.targetType == targetType.Elem()) {
			result = append(result, intc)
		}
	}
	return result
}
<commit_msg>Make interceptor invocations work with multi-level embedded types<commit_after>package play

import (
	"log"
	"reflect"
)

// An "interceptor" is a function that is invoked by the framework at a
// designated time (BEFORE or AFTER) an action invcation.
//
// Since an interceptor may be used across many user Controllers, it is a
// function that takes the base Controller, rather than a method on a user
// controller.
//
// An interceptor may optionally return a Result (instead of nil).  Depending on
// when the interceptor was invoked, the response is different:
// 1. BEFORE:  No further interceptors are invoked, and neither is the action.
// 2. AFTER: Further interceptors are still run.
// In all cases, any returned Result will take the place of any existing Result.
// But in the BEFORE case, that returned Result is guaranteed to be final, while
// in the AFTER case it is possible that a further interceptor could emit its
// own Result.
//
// Interceptors are called in the order that they are added.
//
// ***
//
// Two types of interceptors are provided: Funcs and Methods
//
// Func Interceptors may apply to any / all Controllers.
//
//   func example(*play.Controller) play.Result
//
// Method Interceptors are provided so that properties can be set on application
// controllers.
//
//   func (c AppController) example() play.Result
//   func (c *AppController) example() play.Result
//
type InterceptorFunc func(*Controller) Result
type InterceptorMethod interface{}
type InterceptTime int

const (
	BEFORE InterceptTime = iota
	AFTER
)

type Interception struct {
	When InterceptTime

	function InterceptorFunc
	method   InterceptorMethod

	callableValue reflect.Value
	targetType    reflect.Type
}

// Perform the given interception.
// val is a pointer to the App Controller.
func (i Interception) Invoke(val reflect.Value) reflect.Value {
	// Figure out what type of parameter the interceptor needs.
	argType := i.callableValue.Type().In(0)

	// Find that arg.
	var arg reflect.Value
	if i.function == nil {
		// If it's an InterceptorMethod, then the type is the app controller.
		if val.Type() == argType {
			arg = val
		} else {
			arg = val.Elem()
		}
	} else {
		// If it's an InterceptorFunc, then the type must be *Controller.
		// We can find that by following the embedded types up the chain.
		for val.Type() != controllerPtrType {
			if val.Kind() == reflect.Ptr {
				val = val.Elem()
			}
			val = val.Field(0)
		}
		arg = val
	}

	vals := i.callableValue.Call([]reflect.Value{arg})
	return vals[0]
}

var interceptors []*Interception

// Install a general interceptor.
// This can be applied to any Controller.
// It must have the signature of:
// func example(c *play.Controller) play.Result
func InterceptFunc(intc InterceptorFunc, when InterceptTime, target interface{}) {
	interceptors = append(interceptors, &Interception{
		When:          when,
		function:      intc,
		callableValue: reflect.ValueOf(intc),
		targetType:    reflect.TypeOf(target),
	})
}

// Install an interceptor method that applies to its own Controller.
// func (c AppController) example() play.Result
// func (c *AppController) example() play.Result
func InterceptMethod(intc InterceptorMethod, when InterceptTime) {
	methodType := reflect.TypeOf(intc)
	if methodType.Kind() != reflect.Func || methodType.NumOut() != 1 || methodType.NumIn() != 1 {
		log.Fatalln("Interceptor method should have signature like",
			"'func (c *AppController) example() play.Result' but was", methodType)
	}
	interceptors = append(interceptors, &Interception{
		When:          when,
		method:        intc,
		callableValue: reflect.ValueOf(intc),
		targetType:    methodType.In(0),
	})
}

func getInterceptors(when InterceptTime, targetType reflect.Type) []*Interception {
	result := []*Interception{}
	for _, intc := range interceptors {
		if intc.When == when &&
			(intc.targetType == targetType || intc.targetType == targetType.Elem()) {
			result = append(result, intc)
		}
	}
	return result
}
<|endoftext|>


<commit_before>package main

import (
	"net/http"

	"github.com/goware/jwtauth"
	"github.com/stefanprodan/chi"
	"github.com/stefanprodan/chi/render"
	"github.com/stefanprodan/syros/models"
)

func (s *HttpServer) releaseRoutes() chi.Router {
	r := chi.NewRouter()

	r.Group(func(r chi.Router) {
		r.Use(s.TokenAuth.Verifier)
		r.Use(jwtauth.Authenticator)

		r.Get("/all", func(w http.ResponseWriter, r *http.Request) {
			rels, err := s.Repository.AllReleases()
			if err != nil {
				render.Status(r, http.StatusInternalServerError)
				render.PlainText(w, r, err.Error())
				return
			}

			chart := models.ChartDto{
				Labels: make([]string, 0),
				Values: make([]int64, 0),
			}
			deployments := 0
			// aggregate chart per day based on release end date
			for _, cont := range rels {
				deployments += cont.Deployments
				date := cont.End.Format("06-01-02")
				found := -1
				for i, s := range chart.Labels {
					if s == date {
						found = i
						break
					}
				}
				if found > -1 {
					chart.Values[found] += int64(cont.Deployments)
				} else {
					chart.Labels = append(chart.Labels, date)
					chart.Values = append(chart.Values, int64(cont.Deployments))
				}
			}

			data := struct {
				Releases    []models.Release `json:"releases"`
				Chart       models.ChartDto  `json:"chart"`
				Deployments int              `json:"deployments"`
			}{
				Releases:    rels,
				Chart:       chart,
				Deployments: deployments,
			}

			render.JSON(w, r, data)
		})

		r.Get("/:releaseID", func(w http.ResponseWriter, r *http.Request) {
			releaseID := chi.URLParam(r, "releaseID")

			payload, err := s.Repository.ReleaseDeployments(releaseID)
			if err != nil {
				render.Status(r, http.StatusInternalServerError)
				render.PlainText(w, r, err.Error())
				return
			}
			render.JSON(w, r, payload)
		})
	})

	return r
}
<commit_msg>releases graph per month view<commit_after>package main

import (
	"net/http"

	"github.com/goware/jwtauth"
	"github.com/stefanprodan/chi"
	"github.com/stefanprodan/chi/render"
	"github.com/stefanprodan/syros/models"
)

func (s *HttpServer) releaseRoutes() chi.Router {
	r := chi.NewRouter()

	r.Group(func(r chi.Router) {
		r.Use(s.TokenAuth.Verifier)
		r.Use(jwtauth.Authenticator)

		r.Get("/all", func(w http.ResponseWriter, r *http.Request) {
			rels, err := s.Repository.AllReleases()
			if err != nil {
				render.Status(r, http.StatusInternalServerError)
				render.PlainText(w, r, err.Error())
				return
			}

			chart := models.ChartDto{
				Labels: make([]string, 0),
				Values: make([]int64, 0),
			}
			deployments := 0
			// aggregate chart per day based on release end date
			for _, cont := range rels {
				deployments += cont.Deployments
				date := cont.End.Format("06-01")
				found := -1
				for i, s := range chart.Labels {
					if s == date {
						found = i
						break
					}
				}
				if found > -1 {
					chart.Values[found] += int64(cont.Deployments)
				} else {
					chart.Labels = append(chart.Labels, date)
					chart.Values = append(chart.Values, int64(cont.Deployments))
				}
			}

			data := struct {
				Releases    []models.Release `json:"releases"`
				Chart       models.ChartDto  `json:"chart"`
				Deployments int              `json:"deployments"`
			}{
				Releases:    rels,
				Chart:       chart,
				Deployments: deployments,
			}

			render.JSON(w, r, data)
		})

		r.Get("/:releaseID", func(w http.ResponseWriter, r *http.Request) {
			releaseID := chi.URLParam(r, "releaseID")

			payload, err := s.Repository.ReleaseDeployments(releaseID)
			if err != nil {
				render.Status(r, http.StatusInternalServerError)
				render.PlainText(w, r, err.Error())
				return
			}
			render.JSON(w, r, payload)
		})
	})

	return r
}
<|endoftext|>


<commit_before>package translator

import (
	"net/http"
	"io/ioutil"
	"strings"
	"encoding/json"
	"log"
	"net/url"
//	"fmt"

	"code.google.com/p/go.text/encoding/charmap"
	"code.google.com/p/go.text/encoding/japanese"
	"code.google.com/p/go.text/encoding/korean"
	"code.google.com/p/go.text/encoding/simplifiedchinese"
	"code.google.com/p/go.text/encoding/traditionalchinese"
	"code.google.com/p/go.text/transform"
)

type TranslateJob struct {
	Srctxt, Srclang, Tgttxt, Tgtlang, Echotxt, Channel, User string
	Echo, Kill, Read, Outgoing bool
}

func HandleRequest(request TranslateJob, queue chan TranslateJob) {
	//Encodes the message
	v := url.Values{}
	v.Set("q", request.Srctxt)
	v.Add("client", "t")
	v.Add("text", "")
	v.Add("sl", request.Srclang)
	v.Add("tl", request.Tgtlang)

	//Google's translation address
	s := "http://translate.google.com/translate_a/t?"
	serverUrl := s + v.Encode()

	err := RunTranslation(serverUrl, false, &request)

	if err != nil {
		//Unable to run translation
		log.Println(err)
		return
	}

	log.Println([]byte(request.Tgttxt))

	if request.Srctxt == request.Tgttxt {
		//Translation failed or it was the same.
		log.Println("Translation failed or never occurred.")
		queue <- request
		return
	}

	//"Echoes" the translation if desired.
	if request.Echo == true {
		v := url.Values{}
		v.Set("q", request.Tgttxt)
		v.Add("client", "t")
		v.Add("text", "")
		v.Add("sl", request.Tgtlang)
		v.Add("tl", request.Srclang)

		serverUrl := s + v.Encode()

		err := RunTranslation(serverUrl, true, &request)

		if err != nil {
			//Echo failed.
			log.Println(err)
			request.Echo = false
		}
	}

	log.Println("Returning Job.")
	queue <- request
}

func RunTranslation(url string, echo bool, request *TranslateJob) error {
	//Contact the server.
	log.Println("Opening URL: " + url)
	resp, err := http.Get(url)

	if err != nil {
		return err
	}

	var tr (*transform.Reader)
	detectedLang := resp.Header.Get("Content-Language")
	log.Println("Switching: " + request.Srclang + " " + request.Tgtlang)

	switch {
		case detectedLang == "ar" || request.Srclang == "ar":
			log.Println("Langauge: " + resp.Header.Get("Content-Language") + ", ISO-8859-6 -> UTF-8.")
			tr = transform.NewReader(resp.Body, charmap.ISO8859_6.NewDecoder())
		case detectedLang == "ja" || request.Srclang == "ja":
			log.Println("Langauge: " + resp.Header.Get("Content-Language") + ", ShiftJIS -> UTF-8")
			tr = transform.NewReader(resp.Body, japanese.ShiftJIS.NewDecoder())
		case detectedLang == "ko" || request.Srclang == "ko":
			log.Println("Langauge: " + resp.Header.Get("Content-Language") + ", EUCKR -> UTF-8.")
			tr = transform.NewReader(resp.Body, korean.EUCKR.NewDecoder())
		case detectedLang == "ru" || request.Srclang == "ru":
			fallthrough
		case detectedLang == "bg" || request.Srclang == "bg":
			fallthrough
		case detectedLang == "uk" || request.Srclang == "uk":
			log.Println("Langauge: " + resp.Header.Get("Content-Language") + ", Windows 1251 -> UTF-8.")
			tr = transform.NewReader(resp.Body, charmap.Windows1251.NewDecoder())
		case detectedLang == "zh" || request.Srclang == "zh":
			fallthrough
		case detectedLang == "zh-CN" || request.Srclang == "zh-CN":
			log.Println("Langauge: " + resp.Header.Get("Content-Language") + ", GBK -> UTF-8.")
			tr = transform.NewReader(resp.Body, simplifiedchinese.GBK.NewDecoder())
		case detectedLang == "zh-TW" || request.Srclang == "zh-TW":
			fallthrough
		case detectedLang == "th" || request.Srclang == "th":
			log.Println("Langauge: " + resp.Header.Get("Content-Language") + ", Big5 -> UTF-8.")
			tr = transform.NewReader(resp.Body, traditionalchinese.Big5.NewDecoder())
		default:
			log.Println("Langauge: " + resp.Header.Get("Content-Language") + ", Windows 1252 -> UTF-8")
			tr = transform.NewReader(resp.Body, charmap.Windows1252.NewDecoder())
	}

	if tr == nil {
		log.Println("Failed to convert the JSON")
		return nil
	}

	contents, err := ioutil.ReadAll(tr)

//	fmt.Printf("contents: %s\n", contents)

	if err != nil {
		log.Println("Read JSON")
		return err
	}

	var f interface{}
	contents = sanitizeReturn(contents, 3)
	err = json.Unmarshal(contents, &f)

//	fmt.Printf("sanitized contents: %s\n", contents)

	if err != nil {
		log.Println("JSON failed sanitized.")
		return err
	}

	//Extract the translated text
	json := f.([]interface{})

	arr := json

	for i := 0; i < 1; i++ {
		s, ok := arr[0].([]interface{})

		if !ok {
			return nil
		}

		arr = s
	}

	if echo == true {
		request.Echotxt = arr[0].(string)
		return nil
	}

	var txt string

	for i := 0; i < cap(arr); i++ {
		arrText := arr[i].([]interface{})
		txt = txt + arrText[0].(string) + " "
	}

	request.Tgttxt = txt
	request.Srclang = json[2].(string)

	return nil
}

func sanitizeReturn(result []byte, iterations int) []byte {
	if(iterations > 1) {
		result = sanitizeReturn(result, iterations - 1)
	}

	str := strings.Replace(string(result), ",,", ",0,", -1)
	str = strings.Replace(str, "[,", "[0,", -1)
	return []byte(str)
}
<commit_msg>Corrected the User-Agent in the header, removing the need to decode the JSON in different encodings.<commit_after>package translator

import (
	"net/http"
	"io/ioutil"
	"strings"
	"encoding/json"
	"log"
	"net/url"
)

type TranslateJob struct {
	Srctxt, Srclang, Tgttxt, Tgtlang, Echotxt, Channel, User string
	Echo, Kill, Read, Outgoing bool
}

func HandleRequest(request TranslateJob, queue chan TranslateJob) {
	//Encodes the message
	v := url.Values{}
	v.Set("q", request.Srctxt)
	v.Add("client", "t")
	v.Add("text", "")
	v.Add("sl", request.Srclang)
	v.Add("tl", request.Tgtlang)

	//Google's translation address
	s := "http://translate.google.com/translate_a/t?"
	serverUrl := s + v.Encode()

	err := RunTranslation(serverUrl, false, &request)

	if err != nil {
		//Unable to run translation
		log.Println(err)
		return
	}

	if request.Srctxt == request.Tgttxt {
		//Translation failed or it was the same.
		log.Println("Translation failed or never occurred.")
		queue <- request
		return
	}

	//"Echoes" the translation if desired.
	if request.Echo == true {
		v := url.Values{}
		v.Set("q", request.Tgttxt)
		v.Add("client", "t")
		v.Add("text", "")
		v.Add("sl", request.Tgtlang)
		v.Add("tl", request.Srclang)

		serverUrl := s + v.Encode()

		err := RunTranslation(serverUrl, true, &request)

		if err != nil {
			//Echo failed.
			log.Println(err)
			request.Echo = false
		}
	}

	log.Println("Returning Job.")
	queue <- request
}

func RunTranslation(url string, echo bool, request *TranslateJob) error {
	//Contact the server.
	log.Println("Opening URL: " + url)

	req, err := http.NewRequest("GET", url, nil)
	req.Header.Add("User-Agent", "Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0")

	resp, err := http.DefaultClient.Do(req)

	if err != nil {
		return err
	}

	defer resp.Body.Close()
	contents, err := ioutil.ReadAll(resp.Body)

	if err != nil {
		log.Println("Failed to read HTTP body.")
		return err
	}

	var f interface{}
	retJson := sanitizeReturn(string(contents), 3)
	err = json.Unmarshal([]byte(retJson), &f)

	if err != nil {
		log.Println("JSON failed to unmarshel.")
		return err
	}

	//Extract the translated text
	json := f.([]interface{})

	arr := json

	for i := 0; i < 1; i++ {
		s, ok := arr[0].([]interface{})

		if !ok {
			return nil
		}

		arr = s
	}

	if echo == true {
		request.Echotxt = arr[0].(string)
		return nil
	}

	var txt string

	for i := 0; i < cap(arr); i++ {
		arrText := arr[i].([]interface{})
		txt = txt + arrText[0].(string) + " "
	}

	request.Tgttxt = txt
	request.Srclang = json[2].(string)

	return nil
}

func sanitizeReturn(result string, iterations int) string {
	if(iterations > 1) {
		result = sanitizeReturn(result, iterations - 1)
	}

	for iterations >= 0 {
		result = strings.Replace(result, ",,", ",0,", -1)
		result = strings.Replace(result, "[,", "[0,", -1)
		iterations = iterations - 1
	}

	return result
}

<|endoftext|>


<commit_before>/*
 * This file is part of remco.
 * © 2016 The Remco Authors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

package main

import (
	"errors"
	"io/ioutil"
	"os"
	"sync"
	"testing"

	"github.com/HeavyHorst/remco/backends"
	"github.com/HeavyHorst/remco/backends/mock"
	"github.com/HeavyHorst/remco/template"

	. "gopkg.in/check.v1"
)

const testFile string = `
log_level = "debug"
log_format = "text"
[[resource]]
  [[resource.template]]
    src = "test12345"
    dst = "test12345"
    checkCmd = ""
    reloadCmd = ""
    mode = "0644"
 [resource.backend]
      [resource.backend.mock]
	    keys = ["/"]
		watch = false
		interval = 1
		onetime = false
`

var expectedTemplates = []*template.ProcessConfig{
	&template.ProcessConfig{
		Src:  "test12345",
		Dst:  "test12345",
		Mode: "0644",
	},
}

var expectedBackend = backends.Config{
	Mock: &mock.Config{
		Backend: template.Backend{
			Watch:    false,
			Keys:     []string{"/"},
			Interval: 1,
			Onetime:  false,
		},
	},
}

var expected = configuration{
	LogLevel:  "debug",
	LogFormat: "text",
	Resource: []resource{
		resource{
			Template: expectedTemplates,
			Backend:  expectedBackend,
		},
	},
}

// Hook up gocheck into the "go test" runner.
func Test(t *testing.T) { TestingT(t) }

type FilterSuite struct {
	cfgPath string
}

var _ = Suite(&FilterSuite{})

func (s *FilterSuite) SetUpSuite(t *C) {
	f, err := ioutil.TempFile("/tmp", "")
	if err != nil {
		t.Error(err)
	}
	defer f.Close()
	_, err = f.WriteString(testFile)
	if err != nil {
		t.Error(err)
	}
	s.cfgPath = f.Name()
}

func (s *FilterSuite) TearDownSuite(t *C) {
	err := os.Remove(s.cfgPath)
	if err != nil {
		t.Log(err)
	}
}

func (s *FilterSuite) TestNewConf(t *C) {
	cfg, err := newConfiguration(s.cfgPath)
	if err != nil {
		t.Error(err)
	}
	t.Check(cfg, DeepEquals, expected)
}

func runTest(cfg configuration, t *C) {
	wait := sync.WaitGroup{}
	stop := make(chan struct{})
	wait.Add(1)
	go func() {
		defer wait.Done()
		cfg.run(stop)
	}()
	close(stop)
	wait.Wait()
}

func (s *FilterSuite) TestRun(t *C) {
	cfg, err := newConfiguration(s.cfgPath)
	if err != nil {
		t.Error(err)
	}
	runTest(cfg, t)
}

// the error should just be logged
func (s *FilterSuite) TestRunWithError(t *C) {
	cfg := expected
	cfg.Resource[0].Backend.Mock.Error = errors.New("test")
	runTest(cfg, t)
}

// should run and exit on its own -- no need to close the stopchan
func (s *FilterSuite) TestRunOnetime(t *C) {
	cfg := expected
	cfg.Resource[0].Backend.Mock.Backend.Onetime = true
	cfg.run(make(chan struct{}))
}
<commit_msg>fixed test<commit_after>/*
 * This file is part of remco.
 * © 2016 The Remco Authors
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

package main

import (
	"errors"
	"io/ioutil"
	"os"
	"sync"
	"testing"

	"github.com/HeavyHorst/remco/backends"
	"github.com/HeavyHorst/remco/backends/mock"
	"github.com/HeavyHorst/remco/template"

	. "gopkg.in/check.v1"
)

const testFile string = `
log_level = "debug"
log_format = "text"
[[resource]]
  [[resource.template]]
    src = "/tmp/test12345.tmpl"
    dst = "/tmp/test12345.cfg"
    checkCmd = ""
    reloadCmd = ""
    mode = "0644"
 [resource.backend]
      [resource.backend.mock]
	    keys = ["/"]
		watch = false
		interval = 1
		onetime = false
`

var expectedTemplates = []*template.ProcessConfig{
	&template.ProcessConfig{
		Src:  "/tmp/test12345.tmpl",
		Dst:  "/tmp/test12345.cfg",
		Mode: "0644",
	},
}

var expectedBackend = backends.Config{
	Mock: &mock.Config{
		Backend: template.Backend{
			Watch:    false,
			Keys:     []string{"/"},
			Interval: 1,
			Onetime:  false,
		},
	},
}

var expected = configuration{
	LogLevel:  "debug",
	LogFormat: "text",
	Resource: []resource{
		resource{
			Template: expectedTemplates,
			Backend:  expectedBackend,
		},
	},
}

// Hook up gocheck into the "go test" runner.
func Test(t *testing.T) { TestingT(t) }

type FilterSuite struct {
	cfgPath string
}

var _ = Suite(&FilterSuite{})

func (s *FilterSuite) SetUpSuite(t *C) {
	// write cfg and tmpl file
	f, err := os.Create("/tmp/test12345.tmpl")
	if err != nil {
		t.Error(err)
	}
	defer f.Close()
	f2, err := os.Create("/tmp/test12345.cfg")
	if err != nil {
		t.Error(err)
	}
	defer f2.Close()

	f3, err := ioutil.TempFile("/tmp", "")
	if err != nil {
		t.Error(err)
	}
	defer f3.Close()
	_, err = f3.WriteString(testFile)
	if err != nil {
		t.Error(err)
	}
	s.cfgPath = f3.Name()
}

func (s *FilterSuite) TearDownSuite(t *C) {
	err := os.Remove(s.cfgPath)
	if err != nil {
		t.Log(err)
	}
}

func (s *FilterSuite) TestNewConf(t *C) {
	cfg, err := newConfiguration(s.cfgPath)
	if err != nil {
		t.Error(err)
	}
	t.Check(cfg, DeepEquals, expected)
}

func runTest(cfg configuration, t *C) {
	wait := sync.WaitGroup{}
	stop := make(chan struct{})
	wait.Add(1)
	go func() {
		defer wait.Done()
		cfg.run(stop)
	}()
	close(stop)
	wait.Wait()
}

func (s *FilterSuite) TestRun(t *C) {
	cfg, err := newConfiguration(s.cfgPath)
	if err != nil {
		t.Error(err)
	}
	runTest(cfg, t)
}

// the error should just be logged
func (s *FilterSuite) TestRunWithError(t *C) {
	cfg := expected
	cfg.Resource[0].Backend.Mock.Error = errors.New("test")
	runTest(cfg, t)
}

// should run and exit on its own -- no need to close the stopchan
func (s *FilterSuite) TestRunOnetime(t *C) {
	cfg := expected
	cfg.Resource[0].Backend.Mock.Backend.Onetime = true
	cfg.run(make(chan struct{}))
}
<|endoftext|>


<commit_before>/*
   Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.

   This file is licensed under the Apache License, Version 2.0 (the "License").
   You may not use this file except in compliance with the License. A copy of
   the License is located at

    http://aws.amazon.com/apache2.0/

   This file 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.
*/
// snippet-start:[sqs.go.receive_messages]
package main

// snippet-start:[sqs.go.receive_messages.imports]
import (
	"flag"
	"fmt"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/sqs"
)
// snippet-end:[sqs.go.receive_messages.imports]

// GetQueueURL gets the URL of an Amazon SQS queue
// Inputs:
//     sess is the current session, which provides configuration for the SDK's service clients
//     queueName is the name of the queue
// Output:
//     If success, the URL of the queue and nil
//     Otherwise, an empty string and an error from the call to
func GetQueueURL(sess *session.Session, queue *string) (*sqs.GetQueueUrlOutput, error) {
	// snippet-start:[sqs.go.receive_messages.queue_url]
	svc := sqs.New(sess)

	urlResult, err := svc.GetQueueUrl(&sqs.GetQueueUrlInput{
		QueueName: queue,
	})
	// snippet-end:[sqs.go.receive_messages.queue_url]
	if err != nil {
		return nil, err
	}

	return urlResult, nil
}

// GetMessages gets the messages from an Amazon SQS queue
// Inputs:
//     sess is the current session, which provides configuration for the SDK's service clients
//     queueURL is the URL of the queue
//     timeout is how long, in seconds, the message is unavailable to other consumers
// Output:
//     If success, the latest message and nil
//     Otherwise, nil and an error from the call to ReceiveMessage
func GetMessages(sess *session.Session, queueURL *string, timeout *int64) (*sqs.ReceiveMessageOutput, error) {
	// Create an SQS service client
	svc := sqs.New(sess)

	// snippet-start:[sqs.go.receive_messages.call]
	msgResult, err := svc.ReceiveMessage(&sqs.ReceiveMessageInput{
		AttributeNames: []*string{
			aws.String(sqs.MessageSystemAttributeNameSentTimestamp),
		},
		MessageAttributeNames: []*string{
			aws.String(sqs.QueueAttributeNameAll),
		},
		QueueUrl:            queueURL,
		MaxNumberOfMessages: aws.Int64(1),
		VisibilityTimeout:   timeout,
	})
	// snippet-end:[sqs.go.receive_messages.call]
	if err != nil {
		return nil, err
	}

	return msgResult, nil
}

func main() {
	// snippet-start:[sqs.go.receive_messages.args]
	queue := flag.String("q", "", "The name of the queue")
	timeout := flag.Int64("t", 5, "How long, in seconds, that the message is hidden from others")
	flag.Parse()

	if *queue == "" {
		fmt.Println("You must supply the name of a queue (-q QUEUE)")
		return
	}

	if *timeout < 0 {
		*timeout = 0
	}

	if *timeout > 12*60*60 {
		*timeout = 12 * 60 * 60
	}
	// snippet-end:[sqs.go.receive_messages.args]

	// Create a session that gets credential values from ~/.aws/credentials
	// and the default region from ~/.aws/config
	// snippet-start:[sqs.go.receive_messages.sess]
	sess := session.Must(session.NewSessionWithOptions(session.Options{
		SharedConfigState: session.SharedConfigEnable,
	}))
	// snippet-end:[sqs.go.receive_messages.sess]

	// Get URL of queue
	urlResult, err := GetQueueURL(sess, queue)
	if err != nil {
		fmt.Println("Got an error getting the queue URL:")
		fmt.Println(err)
		return
	}

	// snippet-start:[sqs.go.receive_message.url]
	queueURL := urlResult.QueueUrl
	// snippet-end:[sqs.go.receive_message.url]

	msgResult, err := GetMessages(sess, queueURL, timeout)
	if err != nil {
		fmt.Println("Got an error receiving messages:")
		fmt.Println(err)
		return
	}

	fmt.Println("Message ID:     " + *msgResult.Messages[0].MessageId)

	// snippet-start:[sqs.go.receive_messages.print_handle]
	fmt.Println("Message Handle: " + *msgResult.Messages[0].ReceiptHandle)
	// snippet-end:[sqs.go.receive_messages.print_handle]
}
// snippet-end:[sqs.go.receive_messages]
<commit_msg>Replaced tabs in ReceiveMessage<commit_after>/*
   Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.

   This file is licensed under the Apache License, Version 2.0 (the "License").
   You may not use this file except in compliance with the License. A copy of
   the License is located at

    http://aws.amazon.com/apache2.0/

   This file 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.
*/
// snippet-start:[sqs.go.receive_messages]
package main

// snippet-start:[sqs.go.receive_messages.imports]
import (
    "flag"
    "fmt"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/sqs"
)
// snippet-end:[sqs.go.receive_messages.imports]

// GetQueueURL gets the URL of an Amazon SQS queue
// Inputs:
//     sess is the current session, which provides configuration for the SDK's service clients
//     queueName is the name of the queue
// Output:
//     If success, the URL of the queue and nil
//     Otherwise, an empty string and an error from the call to
func GetQueueURL(sess *session.Session, queue *string) (*sqs.GetQueueUrlOutput, error) {
    // snippet-start:[sqs.go.receive_messages.queue_url]
    svc := sqs.New(sess)

    urlResult, err := svc.GetQueueUrl(&sqs.GetQueueUrlInput{
        QueueName: queue,
    })
    // snippet-end:[sqs.go.receive_messages.queue_url]
    if err != nil {
        return nil, err
    }

    return urlResult, nil
}

// GetMessages gets the messages from an Amazon SQS queue
// Inputs:
//     sess is the current session, which provides configuration for the SDK's service clients
//     queueURL is the URL of the queue
//     timeout is how long, in seconds, the message is unavailable to other consumers
// Output:
//     If success, the latest message and nil
//     Otherwise, nil and an error from the call to ReceiveMessage
func GetMessages(sess *session.Session, queueURL *string, timeout *int64) (*sqs.ReceiveMessageOutput, error) {
    // Create an SQS service client
    svc := sqs.New(sess)

    // snippet-start:[sqs.go.receive_messages.call]
    msgResult, err := svc.ReceiveMessage(&sqs.ReceiveMessageInput{
        AttributeNames: []*string{
            aws.String(sqs.MessageSystemAttributeNameSentTimestamp),
        },
        MessageAttributeNames: []*string{
            aws.String(sqs.QueueAttributeNameAll),
        },
        QueueUrl:            queueURL,
        MaxNumberOfMessages: aws.Int64(1),
        VisibilityTimeout:   timeout,
    })
    // snippet-end:[sqs.go.receive_messages.call]
    if err != nil {
        return nil, err
    }

    return msgResult, nil
}

func main() {
    // snippet-start:[sqs.go.receive_messages.args]
    queue := flag.String("q", "", "The name of the queue")
    timeout := flag.Int64("t", 5, "How long, in seconds, that the message is hidden from others")
    flag.Parse()

    if *queue == "" {
        fmt.Println("You must supply the name of a queue (-q QUEUE)")
        return
    }

    if *timeout < 0 {
        *timeout = 0
    }

    if *timeout > 12*60*60 {
        *timeout = 12 * 60 * 60
    }
    // snippet-end:[sqs.go.receive_messages.args]

    // Create a session that gets credential values from ~/.aws/credentials
    // and the default region from ~/.aws/config
    // snippet-start:[sqs.go.receive_messages.sess]
    sess := session.Must(session.NewSessionWithOptions(session.Options{
        SharedConfigState: session.SharedConfigEnable,
    }))
    // snippet-end:[sqs.go.receive_messages.sess]

    // Get URL of queue
    urlResult, err := GetQueueURL(sess, queue)
    if err != nil {
        fmt.Println("Got an error getting the queue URL:")
        fmt.Println(err)
        return
    }

    // snippet-start:[sqs.go.receive_message.url]
    queueURL := urlResult.QueueUrl
    // snippet-end:[sqs.go.receive_message.url]

    msgResult, err := GetMessages(sess, queueURL, timeout)
    if err != nil {
        fmt.Println("Got an error receiving messages:")
        fmt.Println(err)
        return
    }

    fmt.Println("Message ID:     " + *msgResult.Messages[0].MessageId)

    // snippet-start:[sqs.go.receive_messages.print_handle]
    fmt.Println("Message Handle: " + *msgResult.Messages[0].ReceiptHandle)
    // snippet-end:[sqs.go.receive_messages.print_handle]
}
// snippet-end:[sqs.go.receive_messages]
<|endoftext|>


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

// This file contains the code to check canonical methods.

package main

import (
	"fmt"
	"go/ast"
	"go/printer"
	"strings"
)

type MethodSig struct {
	args    []string
	results []string
}

// canonicalMethods lists the input and output types for Go methods
// that are checked using dynamic interface checks.  Because the
// checks are dynamic, such methods would not cause a compile error
// if they have the wrong signature: instead the dynamic check would
// fail, sometimes mysteriously.  If a method is found with a name listed
// here but not the input/output types listed here, vet complains.
//
// A few of the canonical methods have very common names.
// For example, a type might implement a Scan method that
// has nothing to do with fmt.Scanner, but we still want to check
// the methods that are intended to implement fmt.Scanner.
// To do that, the arguments that have a + prefix are treated as
// signals that the canonical meaning is intended: if a Scan
// method doesn't have a fmt.ScanState as its first argument,
// we let it go.  But if it does have a fmt.ScanState, then the
// rest has to match.
var canonicalMethods = map[string]MethodSig{
	// "Flush": {{}, {"error"}}, // http.Flusher and jpeg.writer conflict
	"Format":        {[]string{"=fmt.State", "rune"}, []string{}},            // fmt.Formatter
	"GobDecode":     {[]string{"[]byte"}, []string{"error"}},                 // gob.GobDecoder
	"GobEncode":     {[]string{}, []string{"[]byte", "error"}},               // gob.GobEncoder
	"MarshalJSON":   {[]string{}, []string{"[]byte", "error"}},               // json.Marshaler
	"MarshalXML":    {[]string{}, []string{"[]byte", "error"}},               // xml.Marshaler
	"Peek":          {[]string{"=int"}, []string{"[]byte", "error"}},         // image.reader (matching bufio.Reader)
	"ReadByte":      {[]string{}, []string{"byte", "error"}},                 // io.ByteReader
	"ReadFrom":      {[]string{"=io.Reader"}, []string{"int64", "error"}},    // io.ReaderFrom
	"ReadRune":      {[]string{}, []string{"rune", "int", "error"}},          // io.RuneReader
	"Scan":          {[]string{"=fmt.ScanState", "rune"}, []string{"error"}}, // fmt.Scanner
	"Seek":          {[]string{"=int64", "int"}, []string{"int64", "error"}}, // io.Seeker
	"UnmarshalJSON": {[]string{"[]byte"}, []string{"error"}},                 // json.Unmarshaler
	"UnreadByte":    {[]string{}, []string{"error"}},
	"UnreadRune":    {[]string{}, []string{"error"}},
	"WriteByte":     {[]string{"byte"}, []string{"error"}},                // jpeg.writer (matching bufio.Writer)
	"WriteTo":       {[]string{"=io.Writer"}, []string{"int64", "error"}}, // io.WriterTo
}

func (f *File) checkCanonicalMethod(id *ast.Ident, t *ast.FuncType) {
	// Expected input/output.
	expect, ok := canonicalMethods[id.Name]
	if !ok {
		return
	}

	// Actual input/output
	args := typeFlatten(t.Params.List)
	var results []ast.Expr
	if t.Results != nil {
		results = typeFlatten(t.Results.List)
	}

	// Do the =s (if any) all match?
	if !f.matchParams(expect.args, args, "=") || !f.matchParams(expect.results, results, "=") {
		return
	}

	// Everything must match.
	if !f.matchParams(expect.args, args, "") || !f.matchParams(expect.results, results, "") {
		expectFmt := id.Name + "(" + argjoin(expect.args) + ")"
		if len(expect.results) == 1 {
			expectFmt += " " + argjoin(expect.results)
		} else if len(expect.results) > 1 {
			expectFmt += " (" + argjoin(expect.results) + ")"
		}

		f.b.Reset()
		if err := printer.Fprint(&f.b, f.fset, t); err != nil {
			fmt.Fprintf(&f.b, "<%s>", err)
		}
		actual := f.b.String()
		if strings.HasPrefix(actual, "func(") {
			actual = actual[4:]
		}
		actual = id.Name + actual

		f.Warnf(id.Pos(), "method %s should have signature %s", actual, expectFmt)
	}
}

func argjoin(x []string) string {
	y := make([]string, len(x))
	for i, s := range x {
		if s[0] == '=' {
			s = s[1:]
		}
		y[i] = s
	}
	return strings.Join(y, ", ")
}

// Turn parameter list into slice of types
// (in the ast, types are Exprs).
// Have to handle f(int, bool) and f(x, y, z int)
// so not a simple 1-to-1 conversion.
func typeFlatten(l []*ast.Field) []ast.Expr {
	var t []ast.Expr
	for _, f := range l {
		if len(f.Names) == 0 {
			t = append(t, f.Type)
			continue
		}
		for _ = range f.Names {
			t = append(t, f.Type)
		}
	}
	return t
}

// Does each type in expect with the given prefix match the corresponding type in actual?
func (f *File) matchParams(expect []string, actual []ast.Expr, prefix string) bool {
	for i, x := range expect {
		if !strings.HasPrefix(x, prefix) {
			continue
		}
		if i >= len(actual) {
			return false
		}
		if !f.matchParamType(x, actual[i]) {
			return false
		}
	}
	if prefix == "" && len(actual) > len(expect) {
		return false
	}
	return true
}

// Does this one type match?
func (f *File) matchParamType(expect string, actual ast.Expr) bool {
	if strings.HasPrefix(expect, "=") {
		expect = expect[1:]
	}
	// Strip package name if we're in that package.
	if n := len(f.file.Name.Name); len(expect) > n && expect[:n] == f.file.Name.Name && expect[n] == '.' {
		expect = expect[n+1:]
	}

	// Overkill but easy.
	f.b.Reset()
	printer.Fprint(&f.b, f.fset, actual)
	return f.b.String() == expect
}
<commit_msg>vet: fix comment typo.<commit_after>// Copyright 2010 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file contains the code to check canonical methods.

package main

import (
	"fmt"
	"go/ast"
	"go/printer"
	"strings"
)

type MethodSig struct {
	args    []string
	results []string
}

// canonicalMethods lists the input and output types for Go methods
// that are checked using dynamic interface checks.  Because the
// checks are dynamic, such methods would not cause a compile error
// if they have the wrong signature: instead the dynamic check would
// fail, sometimes mysteriously.  If a method is found with a name listed
// here but not the input/output types listed here, vet complains.
//
// A few of the canonical methods have very common names.
// For example, a type might implement a Scan method that
// has nothing to do with fmt.Scanner, but we still want to check
// the methods that are intended to implement fmt.Scanner.
// To do that, the arguments that have a = prefix are treated as
// signals that the canonical meaning is intended: if a Scan
// method doesn't have a fmt.ScanState as its first argument,
// we let it go.  But if it does have a fmt.ScanState, then the
// rest has to match.
var canonicalMethods = map[string]MethodSig{
	// "Flush": {{}, {"error"}}, // http.Flusher and jpeg.writer conflict
	"Format":        {[]string{"=fmt.State", "rune"}, []string{}},            // fmt.Formatter
	"GobDecode":     {[]string{"[]byte"}, []string{"error"}},                 // gob.GobDecoder
	"GobEncode":     {[]string{}, []string{"[]byte", "error"}},               // gob.GobEncoder
	"MarshalJSON":   {[]string{}, []string{"[]byte", "error"}},               // json.Marshaler
	"MarshalXML":    {[]string{}, []string{"[]byte", "error"}},               // xml.Marshaler
	"Peek":          {[]string{"=int"}, []string{"[]byte", "error"}},         // image.reader (matching bufio.Reader)
	"ReadByte":      {[]string{}, []string{"byte", "error"}},                 // io.ByteReader
	"ReadFrom":      {[]string{"=io.Reader"}, []string{"int64", "error"}},    // io.ReaderFrom
	"ReadRune":      {[]string{}, []string{"rune", "int", "error"}},          // io.RuneReader
	"Scan":          {[]string{"=fmt.ScanState", "rune"}, []string{"error"}}, // fmt.Scanner
	"Seek":          {[]string{"=int64", "int"}, []string{"int64", "error"}}, // io.Seeker
	"UnmarshalJSON": {[]string{"[]byte"}, []string{"error"}},                 // json.Unmarshaler
	"UnreadByte":    {[]string{}, []string{"error"}},
	"UnreadRune":    {[]string{}, []string{"error"}},
	"WriteByte":     {[]string{"byte"}, []string{"error"}},                // jpeg.writer (matching bufio.Writer)
	"WriteTo":       {[]string{"=io.Writer"}, []string{"int64", "error"}}, // io.WriterTo
}

func (f *File) checkCanonicalMethod(id *ast.Ident, t *ast.FuncType) {
	// Expected input/output.
	expect, ok := canonicalMethods[id.Name]
	if !ok {
		return
	}

	// Actual input/output
	args := typeFlatten(t.Params.List)
	var results []ast.Expr
	if t.Results != nil {
		results = typeFlatten(t.Results.List)
	}

	// Do the =s (if any) all match?
	if !f.matchParams(expect.args, args, "=") || !f.matchParams(expect.results, results, "=") {
		return
	}

	// Everything must match.
	if !f.matchParams(expect.args, args, "") || !f.matchParams(expect.results, results, "") {
		expectFmt := id.Name + "(" + argjoin(expect.args) + ")"
		if len(expect.results) == 1 {
			expectFmt += " " + argjoin(expect.results)
		} else if len(expect.results) > 1 {
			expectFmt += " (" + argjoin(expect.results) + ")"
		}

		f.b.Reset()
		if err := printer.Fprint(&f.b, f.fset, t); err != nil {
			fmt.Fprintf(&f.b, "<%s>", err)
		}
		actual := f.b.String()
		if strings.HasPrefix(actual, "func(") {
			actual = actual[4:]
		}
		actual = id.Name + actual

		f.Warnf(id.Pos(), "method %s should have signature %s", actual, expectFmt)
	}
}

func argjoin(x []string) string {
	y := make([]string, len(x))
	for i, s := range x {
		if s[0] == '=' {
			s = s[1:]
		}
		y[i] = s
	}
	return strings.Join(y, ", ")
}

// Turn parameter list into slice of types
// (in the ast, types are Exprs).
// Have to handle f(int, bool) and f(x, y, z int)
// so not a simple 1-to-1 conversion.
func typeFlatten(l []*ast.Field) []ast.Expr {
	var t []ast.Expr
	for _, f := range l {
		if len(f.Names) == 0 {
			t = append(t, f.Type)
			continue
		}
		for _ = range f.Names {
			t = append(t, f.Type)
		}
	}
	return t
}

// Does each type in expect with the given prefix match the corresponding type in actual?
func (f *File) matchParams(expect []string, actual []ast.Expr, prefix string) bool {
	for i, x := range expect {
		if !strings.HasPrefix(x, prefix) {
			continue
		}
		if i >= len(actual) {
			return false
		}
		if !f.matchParamType(x, actual[i]) {
			return false
		}
	}
	if prefix == "" && len(actual) > len(expect) {
		return false
	}
	return true
}

// Does this one type match?
func (f *File) matchParamType(expect string, actual ast.Expr) bool {
	if strings.HasPrefix(expect, "=") {
		expect = expect[1:]
	}
	// Strip package name if we're in that package.
	if n := len(f.file.Name.Name); len(expect) > n && expect[:n] == f.file.Name.Name && expect[n] == '.' {
		expect = expect[n+1:]
	}

	// Overkill but easy.
	f.b.Reset()
	printer.Fprint(&f.b, f.fset, actual)
	return f.b.String() == expect
}
<|endoftext|>


<commit_before>package punter

import (
	"fmt"
	"log"

	"github.com/streadway/amqp"
)

// MsgHander function which is supplied to handle delivers.
type MsgHander func(deliveries <-chan amqp.Delivery, done chan error)

// Consumer holds state for the AMQP consumer
type Consumer struct {
	conn    *amqp.Connection
	channel *amqp.Channel
	tag     string
	done    chan error
	count   int
}

// Config is the settings for the consumer
type Config struct {
	AmqpURI      string
	Exchange     string
	ExchangeType string
	QueueName    string
	Key          string
	Ctag         string
	MessageTTL   int32 // How long to retain messages in the queue
	Durable      bool  // Queue durable?
}

// NewConsumer create and configure a new consumer, this also triggers a connection to AMQP server
func NewConsumer(config *Config, msgHandler MsgHander) (*Consumer, error) {

	c := &Consumer{
		conn:    nil,
		channel: nil,
		tag:     config.Ctag,
		done:    make(chan error),
	}

	var err error

	log.Printf("dialing %q", config.AmqpURI)
	c.conn, err = amqp.Dial(config.AmqpURI)
	if err != nil {
		return nil, fmt.Errorf("Dial: %s", err)
	}

	go func() {
		fmt.Printf("closing: %s", <-c.conn.NotifyClose(make(chan *amqp.Error)))
	}()

	log.Printf("got Connection, getting Channel")
	c.channel, err = c.conn.Channel()
	if err != nil {
		return nil, fmt.Errorf("Channel: %s", err)
	}

	log.Printf("got Channel, declaring Exchange (%q)", config.Exchange)
	if err = c.channel.ExchangeDeclare(
		config.Exchange,     // name of the exchange
		config.ExchangeType, // type
		config.Durable,      // durable
		false,               // delete when complete
		false,               // internal
		false,               // noWait
		nil,                 // arguments
	); err != nil {
		return nil, fmt.Errorf("Exchange Declare: %s", err)
	}
	qargs := amqp.Table{}

	// if the value is set then configure the argument
	if config.MessageTTL > 0 {
		qargs["x-message-ttl"] = config.MessageTTL
	}

	log.Printf("declared Exchange, declaring Queue %q", config.QueueName)
	queue, err := c.channel.QueueDeclare(
		config.QueueName, // name of the queue
		true,             // durable
		false,            // delete when usused
		false,            // exclusive
		false,            // noWait
		qargs,            // arguments
	)
	if err != nil {
		return nil, fmt.Errorf("Queue Declare: %s", err)
	}

	log.Printf("declared Queue (%q %d messages, %d consumers), binding to Exchange (key %q)",
		queue.Name, queue.Messages, queue.Consumers, config.Key)

	args := amqp.Table{}
	// TODO make this configurable.
	args["x-expires"] = int32(30000) // 30 second

	if err = c.channel.QueueBind(
		queue.Name,      // name of the queue
		config.Key,      // bindingKey
		config.Exchange, // sourceExchange
		false,           // noWait
		args,            // arguments
	); err != nil {
		return nil, fmt.Errorf("Queue Bind: %s", err)
	}

	log.Printf("Queue bound to Exchange, starting Consume (consumer tag %q)", c.tag)
	deliveries, err := c.channel.Consume(
		queue.Name, // name
		c.tag,      // consumerTag,
		false,      // noAck
		false,      // exclusive
		false,      // noLocal
		false,      // noWait
		nil,        // arguments
	)
	if err != nil {
		return nil, fmt.Errorf("Queue Consume: %s", err)
	}

	go msgHandler(deliveries, c.done)

	return c, nil
}

// Shutdown enables cleanup of AMQP connection
func (c *Consumer) Shutdown() error {
	// will close() the deliveries channel
	if err := c.channel.Cancel(c.tag, true); err != nil {
		return fmt.Errorf("Consumer cancel failed: %s", err)
	}

	if err := c.conn.Close(); err != nil {
		return fmt.Errorf("AMQP connection close error: %s", err)
	}

	defer log.Printf("AMQP shutdown OK")

	// wait for handle() to exit
	return <-c.done
}
<commit_msg>Updated api to enable common config and tag passed per consumer.<commit_after>package punter

import (
	"fmt"
	"log"

	"github.com/streadway/amqp"
)

// MsgHander function which is supplied to handle delivers.
type MsgHander func(deliveries <-chan amqp.Delivery, done chan error)

// Consumer holds state for the AMQP consumer
type Consumer struct {
	conn    *amqp.Connection
	channel *amqp.Channel
	tag     string
	done    chan error
	count   int
}

// Config is the settings for the consumer
type Config struct {
	AmqpURI      string
	Exchange     string
	ExchangeType string
	QueueName    string
	Key          string
	MessageTTL   int32 // How long to retain messages in the queue
	Durable      bool  // Queue durable?
}

// NewConsumer create and configure a new consumer, this also triggers a connection to AMQP server
func NewConsumer(config *Config, ctag string, msgHandler MsgHander) (*Consumer, error) {

	c := &Consumer{
		conn:    nil,
		channel: nil,
		tag:     ctag,
		done:    make(chan error),
	}

	var err error

	log.Printf("dialing %q", config.AmqpURI)
	c.conn, err = amqp.Dial(config.AmqpURI)
	if err != nil {
		return nil, fmt.Errorf("Dial: %s", err)
	}

	go func() {
		fmt.Printf("closing: %s", <-c.conn.NotifyClose(make(chan *amqp.Error)))
	}()

	log.Printf("got Connection, getting Channel")
	c.channel, err = c.conn.Channel()
	if err != nil {
		return nil, fmt.Errorf("Channel: %s", err)
	}

	log.Printf("got Channel, declaring Exchange (%q)", config.Exchange)
	if err = c.channel.ExchangeDeclare(
		config.Exchange,     // name of the exchange
		config.ExchangeType, // type
		config.Durable,      // durable
		false,               // delete when complete
		false,               // internal
		false,               // noWait
		nil,                 // arguments
	); err != nil {
		return nil, fmt.Errorf("Exchange Declare: %s", err)
	}
	qargs := amqp.Table{}

	// if the value is set then configure the argument
	if config.MessageTTL > 0 {
		qargs["x-message-ttl"] = config.MessageTTL
	}

	log.Printf("declared Exchange, declaring Queue %q", config.QueueName)
	queue, err := c.channel.QueueDeclare(
		config.QueueName, // name of the queue
		true,             // durable
		false,            // delete when usused
		false,            // exclusive
		false,            // noWait
		qargs,            // arguments
	)
	if err != nil {
		return nil, fmt.Errorf("Queue Declare: %s", err)
	}

	log.Printf("declared Queue (%q %d messages, %d consumers), binding to Exchange (key %q)",
		queue.Name, queue.Messages, queue.Consumers, config.Key)

	args := amqp.Table{}
	// TODO make this configurable.
	args["x-expires"] = int32(30000) // 30 second

	if err = c.channel.QueueBind(
		queue.Name,      // name of the queue
		config.Key,      // bindingKey
		config.Exchange, // sourceExchange
		false,           // noWait
		args,            // arguments
	); err != nil {
		return nil, fmt.Errorf("Queue Bind: %s", err)
	}

	log.Printf("Queue bound to Exchange, starting Consume (consumer tag %q)", c.tag)
	deliveries, err := c.channel.Consume(
		queue.Name, // name
		c.tag,      // consumerTag,
		false,      // noAck
		false,      // exclusive
		false,      // noLocal
		false,      // noWait
		nil,        // arguments
	)
	if err != nil {
		return nil, fmt.Errorf("Queue Consume: %s", err)
	}

	go msgHandler(deliveries, c.done)

	return c, nil
}

// Shutdown enables cleanup of AMQP connection
func (c *Consumer) Shutdown() error {
	// will close() the deliveries channel
	if err := c.channel.Cancel(c.tag, true); err != nil {
		return fmt.Errorf("Consumer cancel failed: %s", err)
	}

	if err := c.conn.Close(); err != nil {
		return fmt.Errorf("AMQP connection close error: %s", err)
	}

	defer log.Printf("AMQP shutdown OK")

	// wait for handle() to exit
	return <-c.done
}
<|endoftext|>


<commit_before>// Use of this source code is governed by a MIT license that can be found in the LICENSE file.
// Giorgis (habtom@giorgis.io)

package avutil

/*
	#cgo pkg-config: libavutil
	#include <libavutil/frame.h>
	#include <stdlib.h>
*/
import "C"
import (
	"unsafe"
)

type (
	AvBuffer            C.struct_AVBuffer
	AvBufferRef         C.struct_AVBufferRef
	AvBufferPool        C.struct_AVBufferPool
	Frame               C.struct_AVFrame
	AvFrameSideData     C.struct_AVFrameSideData
	AvFrameSideDataType C.enum_AVFrameSideDataType
)

func AvprivFrameGetMetadatap(f *Frame) **Dictionary {
	return (**Dictionary)(unsafe.Pointer(C.avpriv_frame_get_metadatap((*C.struct_AVFrame)(unsafe.Pointer(f)))))
}

func AvFrameSetQpTable(f *Frame, b *AvBufferRef, s, q int) int {
	return int(C.av_frame_set_qp_table((*C.struct_AVFrame)(unsafe.Pointer(f)), (*C.struct_AVBufferRef)(unsafe.Pointer(b)), C.int(s), C.int(q)))
}

func AvFrameGetQpTable(f *Frame, s, t *int) int8 {
	return int8(*C.av_frame_get_qp_table((*C.struct_AVFrame)(unsafe.Pointer(f)), (*C.int)(unsafe.Pointer(s)), (*C.int)(unsafe.Pointer(t))))
}

//Allocate an Frame and set its fields to default values.
func AvFrameAlloc() *Frame {
	return (*Frame)(unsafe.Pointer(C.av_frame_alloc()))
}

//Free the frame and any dynamically allocated objects in it, e.g.
func AvFrameFree(f *Frame) {
	C.av_frame_free((**C.struct_AVFrame)(unsafe.Pointer(f)))
}

//Allocate new buffer(s) for audio or video data.
func AvFrameGetBuffer(f *Frame, a int) int {
	return int(C.av_frame_get_buffer((*C.struct_AVFrame)(unsafe.Pointer(f)), C.int(a)))
}

//Setup a new reference to the data described by an given frame.
func AvFrameRef(d, s *Frame) int {
	return int(C.av_frame_ref((*C.struct_AVFrame)(unsafe.Pointer(d)), (*C.struct_AVFrame)(unsafe.Pointer(s))))
}

//Create a new frame that references the same data as src.
func AvFrameClone(f *Frame) *Frame {
	return (*Frame)(C.av_frame_clone((*C.struct_AVFrame)(unsafe.Pointer(f))))
}

//Unreference all the buffers referenced by frame and reset the frame fields.
func AvFrameUnref(f *Frame) {
	cf := (*C.struct_AVFrame)(unsafe.Pointer(f))
	C.av_frame_unref(cf)
}

//Move everythnig contained in src to dst and reset src.
func AvFrameMoveRef(d, s *Frame) {
	C.av_frame_move_ref((*C.struct_AVFrame)(unsafe.Pointer(d)), (*C.struct_AVFrame)(unsafe.Pointer(s)))
}

//Check if the frame data is writable.
func AvFrameIsWritable(f *Frame) int {
	return int(C.av_frame_is_writable((*C.struct_AVFrame)(unsafe.Pointer(f))))
}

//Ensure that the frame data is writable, avoiding data copy if possible.
func AvFrameMakeWritable(f *Frame) int {
	return int(C.av_frame_make_writable((*C.struct_AVFrame)(unsafe.Pointer(f))))
}

//Copy only "metadata" fields from src to dst.
func AvFrameCopyProps(d, s *Frame) int {
	return int(C.av_frame_copy_props((*C.struct_AVFrame)(unsafe.Pointer(d)), (*C.struct_AVFrame)(unsafe.Pointer(s))))
}

//Get the buffer reference a given data plane is stored in.
func AvFrameGetPlaneBuffer(f *Frame, p int) *AvBufferRef {
	return (*AvBufferRef)(C.av_frame_get_plane_buffer((*C.struct_AVFrame)(unsafe.Pointer(f)), C.int(p)))
}

//Add a new side data to a frame.
func AvFrameNewSideData(f *Frame, d AvFrameSideDataType, s int) *AvFrameSideData {
	return (*AvFrameSideData)(C.av_frame_new_side_data((*C.struct_AVFrame)(unsafe.Pointer(f)), (C.enum_AVFrameSideDataType)(d), C.int(s)))
}

func AvFrameGetSideData(f *Frame, t AvFrameSideDataType) *AvFrameSideData {
	return (*AvFrameSideData)(C.av_frame_get_side_data((*C.struct_AVFrame)(unsafe.Pointer(f)), (C.enum_AVFrameSideDataType)(t)))
}

func Data(f *Frame) *uint8 {
	return (*uint8)(unsafe.Pointer((*C.uint8_t)(unsafe.Pointer(&f.data))))
}
func Linesize(f *Frame) int {
	return int(*(*C.int)(unsafe.Pointer(&f.linesize)))
}

// //static int get_video_buffer (Frame *frame, int align)
// func GetVideoBuffer(f *Frame, a int) int {
// 	return int(C.get_video_buffer(f, C.int(a)))
// }

// //static int get_audio_buffer (Frame *frame, int align)
// func GetAudioBuffer(f *Frame, a int) int {
// 	return C.get_audio_buffer(f, C.int(a))
// }

// //static void get_frame_defaults (Frame *frame)
// func GetFrameDefaults(f *Frame) {
// 	C.get_frame_defaults(*C.struct_AVFrame(f))
// }
<commit_msg>[AvUtil] Fix segmentation fault with AvFrameFree<commit_after>// Use of this source code is governed by a MIT license that can be found in the LICENSE file.
// Giorgis (habtom@giorgis.io)

package avutil

/*
	#cgo pkg-config: libavutil
	#include <libavutil/frame.h>
	#include <stdlib.h>
*/
import "C"
import (
	"unsafe"
)

type (
	AvBuffer            C.struct_AVBuffer
	AvBufferRef         C.struct_AVBufferRef
	AvBufferPool        C.struct_AVBufferPool
	Frame               C.struct_AVFrame
	AvFrameSideData     C.struct_AVFrameSideData
	AvFrameSideDataType C.enum_AVFrameSideDataType
)

func AvprivFrameGetMetadatap(f *Frame) **Dictionary {
	return (**Dictionary)(unsafe.Pointer(C.avpriv_frame_get_metadatap((*C.struct_AVFrame)(unsafe.Pointer(f)))))
}

func AvFrameSetQpTable(f *Frame, b *AvBufferRef, s, q int) int {
	return int(C.av_frame_set_qp_table((*C.struct_AVFrame)(unsafe.Pointer(f)), (*C.struct_AVBufferRef)(unsafe.Pointer(b)), C.int(s), C.int(q)))
}

func AvFrameGetQpTable(f *Frame, s, t *int) int8 {
	return int8(*C.av_frame_get_qp_table((*C.struct_AVFrame)(unsafe.Pointer(f)), (*C.int)(unsafe.Pointer(s)), (*C.int)(unsafe.Pointer(t))))
}

//Allocate an Frame and set its fields to default values.
func AvFrameAlloc() *Frame {
	return (*Frame)(unsafe.Pointer(C.av_frame_alloc()))
}

//Free the frame and any dynamically allocated objects in it, e.g.
func AvFrameFree(f *Frame) {
	C.av_frame_free((**C.struct_AVFrame)(unsafe.Pointer(&f)))
}

//Allocate new buffer(s) for audio or video data.
func AvFrameGetBuffer(f *Frame, a int) int {
	return int(C.av_frame_get_buffer((*C.struct_AVFrame)(unsafe.Pointer(f)), C.int(a)))
}

//Setup a new reference to the data described by an given frame.
func AvFrameRef(d, s *Frame) int {
	return int(C.av_frame_ref((*C.struct_AVFrame)(unsafe.Pointer(d)), (*C.struct_AVFrame)(unsafe.Pointer(s))))
}

//Create a new frame that references the same data as src.
func AvFrameClone(f *Frame) *Frame {
	return (*Frame)(C.av_frame_clone((*C.struct_AVFrame)(unsafe.Pointer(f))))
}

//Unreference all the buffers referenced by frame and reset the frame fields.
func AvFrameUnref(f *Frame) {
	cf := (*C.struct_AVFrame)(unsafe.Pointer(f))
	C.av_frame_unref(cf)
}

//Move everythnig contained in src to dst and reset src.
func AvFrameMoveRef(d, s *Frame) {
	C.av_frame_move_ref((*C.struct_AVFrame)(unsafe.Pointer(d)), (*C.struct_AVFrame)(unsafe.Pointer(s)))
}

//Check if the frame data is writable.
func AvFrameIsWritable(f *Frame) int {
	return int(C.av_frame_is_writable((*C.struct_AVFrame)(unsafe.Pointer(f))))
}

//Ensure that the frame data is writable, avoiding data copy if possible.
func AvFrameMakeWritable(f *Frame) int {
	return int(C.av_frame_make_writable((*C.struct_AVFrame)(unsafe.Pointer(f))))
}

//Copy only "metadata" fields from src to dst.
func AvFrameCopyProps(d, s *Frame) int {
	return int(C.av_frame_copy_props((*C.struct_AVFrame)(unsafe.Pointer(d)), (*C.struct_AVFrame)(unsafe.Pointer(s))))
}

//Get the buffer reference a given data plane is stored in.
func AvFrameGetPlaneBuffer(f *Frame, p int) *AvBufferRef {
	return (*AvBufferRef)(C.av_frame_get_plane_buffer((*C.struct_AVFrame)(unsafe.Pointer(f)), C.int(p)))
}

//Add a new side data to a frame.
func AvFrameNewSideData(f *Frame, d AvFrameSideDataType, s int) *AvFrameSideData {
	return (*AvFrameSideData)(C.av_frame_new_side_data((*C.struct_AVFrame)(unsafe.Pointer(f)), (C.enum_AVFrameSideDataType)(d), C.int(s)))
}

func AvFrameGetSideData(f *Frame, t AvFrameSideDataType) *AvFrameSideData {
	return (*AvFrameSideData)(C.av_frame_get_side_data((*C.struct_AVFrame)(unsafe.Pointer(f)), (C.enum_AVFrameSideDataType)(t)))
}

func Data(f *Frame) *uint8 {
	return (*uint8)(unsafe.Pointer((*C.uint8_t)(unsafe.Pointer(&f.data))))
}
func Linesize(f *Frame) int {
	return int(*(*C.int)(unsafe.Pointer(&f.linesize)))
}

// //static int get_video_buffer (Frame *frame, int align)
// func GetVideoBuffer(f *Frame, a int) int {
// 	return int(C.get_video_buffer(f, C.int(a)))
// }

// //static int get_audio_buffer (Frame *frame, int align)
// func GetAudioBuffer(f *Frame, a int) int {
// 	return C.get_audio_buffer(f, C.int(a))
// }

// //static void get_frame_defaults (Frame *frame)
// func GetFrameDefaults(f *Frame) {
// 	C.get_frame_defaults(*C.struct_AVFrame(f))
// }
<|endoftext|>


<commit_before>package main

import (
	"bufio"
	"bytes"
	"database/sql"
	"flag"
	"fmt"
	"log"
	"os"
	"regexp"
	"sort"
	"strings"
	"time"

	// "database/sql"

	_ "github.com/lib/pq"

	"github.com/DimShadoWWW/power-pg/proxy"
	"github.com/parnurzeal/gorequest"
)

var (
	localHost     = flag.String("l", ":5432", "puerto local para escuchar")
	dbHostname    = flag.String("h", "localhost", "hostname del servidor PostgreSQL")
	dbPort        = flag.String("r", "5432", "puerto del servidor PostgreSQL")
	dbName        = flag.String("d", "dbname", "nombre de la base de datos")
	dbUsername    = flag.String("u", "username", "usuario para acceder al servidor PostgreSQL")
	dbPassword    = flag.String("p", "password", "password para acceder al servidor PostgreSQL")
	remoteService = flag.String("s", "", "http://localhost:8080/query")
	// messages      = []string{}
)

type msgStruct struct {
	Type    string
	Content string
}

var (
	db *sql.DB
)

func main() {
	flag.Parse()
	// dbinfo := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable",
	// 	*dbUsername, *dbPassword, *dbName)
	// db, err := sql.Open("postgres", dbinfo)

	msgs := make(chan string)
	msgCh := make(chan proxy.Pkg)
	msgOut := make(chan msgStruct)
	if *remoteService != "" {
		go func() {
			time.Sleep(time.Second * 3)
			inFile, _ := os.Open("canales_list.txt")
			defer inFile.Close()
			scanner := bufio.NewScanner(inFile)
			scanner.Split(bufio.ScanLines)

			for scanner.Scan() {
				time.Sleep(time.Second * 1)
				// messages = []string{}
				// fmt.Println(scanner.Text())
				// msgOut <- fmt.Sprintf("# %s\n", scanner.Text())
				msgOut <- msgStruct{Type: "C", Content: scanner.Text()}
				_, _, errs := gorequest.New().Get(fmt.Sprintf("%s%s", *remoteService, scanner.Text())).End()
				if errs != nil {
					log.Fatalf("log failed: %v", errs)
				}
			}
			log.Println("done")
			os.Exit(0)
		}()
	}

	go func() {
		f, err := os.OpenFile("/all.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
		if err != nil {
			panic(err)
		}
		defer f.Close()
		for msg := range msgs {
			// fmt.Println(msg)
			_, err := f.WriteString(fmt.Sprintf("%s\n", msg))
			if err != nil {
				log.Fatalf("log failed: %v", err)
			}
		}
	}()

	go func() {
		f, err := os.OpenFile("/reports/report.md", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
		// c := 0
		spaces := regexp.MustCompile("[\t]+")
		multipleSpaces := regexp.MustCompile("    ")
		for {
			// select {
			// case msg1 := <-msgOut:
			msg := <-msgOut
			if msg.Type == "C" {
				// c = 0
				f.Close()
				f, err = os.OpenFile(fmt.Sprintf("/reports/report-%s.md", msg.Content), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
				// c = 0
				if err != nil {
					panic(err)
				}
				_, err := f.WriteString(fmt.Sprintf("# %s\n", msg.Content))
				if err != nil {
					log.Fatalf("log failed: %v", err)
				}
			} else {
				// case msg2 := <-msgOut:
				// c = c + 1
				m := spaces.ReplaceAll([]byte(msg.Content), []byte{' '})
				m = multipleSpaces.ReplaceAll(m, []byte{' '})
				_, err := f.WriteString(fmt.Sprintf("\n```sql\n%s\n```\n", string(m)))
				if err != nil {
					log.Fatalf("log failed: %v", err)
				}
			}
		}
	}()

	go func() {
		temp := ""
		for msg := range msgCh {
			if msg.Type == 'P' {
				if strings.Contains(string(msg.Content), "$1") {
					var newMsg proxy.ReadBuf
					newMsg = msg.Content
					_ = newMsg.Int32()

					// The name of the destination portal (an empty string selects the unnamed portal).
					p := bytes.Index(newMsg, []byte{0})
					// remove first string
					msgs <- fmt.Sprintf("msg ---->%#v\n", newMsg)
					msgs <- fmt.Sprintf("msg ---->%s\n", string(newMsg))
					msgs <- fmt.Sprintf("first string ---->%#v\n", newMsg[:p+1])
					msgs <- fmt.Sprintf("first string ---->%s\n", string(newMsg[:p+1]))
					newMsg = newMsg[p+1:]
					fmt.Printf("0 newMsg   ----->%#v\n", newMsg)

					// The name of the source prepared statement (an empty string selects the unnamed prepared statement).
					p = bytes.Index(newMsg, []byte{0})
					// remove second string
					msgs <- fmt.Sprintf("second string: message ---->%#v\n", newMsg[:p])
					temp = string(newMsg[:p])
					msgs <- fmt.Sprintf("second string: message temp ---->%s\n", temp)

				} else {
					temp = ""
					selectIdx := strings.Index(string(msg.Content), string([]byte{83, 69, 76, 69, 67, 84, 32}))
					if selectIdx == -1 {
						selectIdx = 0
					}
					sepIdx := strings.Index(string(msg.Content), string([]byte{0, 0, 1, 0, 0}))
					if sepIdx == -1 || sepIdx+5 > len(msg.Content) {
						sepIdx := strings.Index(string(msg.Content), string([]byte{0, 1, 0, 0}))
						if sepIdx == -1 || sepIdx+4 > len(msg.Content) {
							sepIdx = len(msg.Content) - 4
						} else {
							sepIdx = len(msg.Content) - 1
						}
					}
					if sepIdx == -1 {
						sepIdx = len(msg.Content)
					}
					if selectIdx == -1 {
						selectIdx = 0
					}

					fmt.Printf("SEP index ----->%v\n", sepIdx)
					fmt.Printf("SEP len   ----->%v\n", len(msg.Content))
					fmt.Printf("SEP CONT  ----->%v\n", msg.Content)
					// messages = append(messages, string(bytes.Trim(msg.Content[selectIdx:sepIdx], "\x00")))
					msgOut <- msgStruct{Type: "M", Content: string(bytes.Trim(msg.Content[selectIdx:sepIdx], "\x00"))}
				}
			} else {
				if msg.Type == 'B' && temp != "" {
					var newMsg proxy.ReadBuf
					newMsg = msg.Content

					// The name of the destination portal (an empty string selects the unnamed portal).
					p := bytes.Index(newMsg, []byte{0})
					// remove first string
					msgs <- fmt.Sprintf("msg ---->%#v\n", newMsg)
					msgs <- fmt.Sprintf("first string ---->%#v\n", newMsg[:p+1])
					newMsg = newMsg[p:]
					fmt.Printf("0 newMsg   ----->%#v\n", newMsg)

					// The name of the source prepared statement (an empty string selects the unnamed prepared statement).
					p = bytes.Index(newMsg, []byte{0})
					// remove second string
					msgs <- fmt.Sprintf("second string ---->%#v\n", newMsg[:p+1])
					newMsg = newMsg[p+1:]
					fmt.Printf("1 newMsg   ----->%#v\n", newMsg)

					t := newMsg.Int16()
					msgs <- fmt.Sprintf("vars types numbers ---->%#v\n", t)
					for i := 0; i < t; i++ {
						t = newMsg.Int16()
						msgs <- fmt.Sprintf("22 newMsg   ----->%#v\n", newMsg)
					}

					msgs <- fmt.Sprintf("23 newMsg   ----->%#v\n", newMsg)
					totalVar := newMsg.Int16()
					vars := make(map[int]string)
					var varsIdx []int
					if totalVar == 0 && len(newMsg) > 4 {
						totalVar = newMsg.Int16()
					}
					if totalVar == 0 && len(newMsg) > 4 {
						totalVar = newMsg.Int32()
					}
					msgs <- fmt.Sprintf("totalVar   ----->%d\n", totalVar)
					for i := 0; i < totalVar; i++ {
						msgs <- fmt.Sprintf("2 newMsg   ----->%#v\n", newMsg)
						varLen := newMsg.Int32()
						// var1 := newMsg.Next(4)
						// // fmt.Printf("aa   -----> %#v\n", aa)
						// // fmt.Printf("aa bits ----->%8b\n", aa[len(aa)-1])
						// varLen := int(binary.BigEndian.Uint32(var1))
						// if varLen > len(newMsg) {
						// 	varLen = int(binary.BigEndian.Uint16(var1[:2]))
						// }
						msgs <- fmt.Sprintf("varLen ----->%v\n", varLen)
						msgs <- fmt.Sprintf("newMsg   ----->%#v\n", newMsg)
						if varLen > len(newMsg) {
							varLen = len(newMsg) - 4
							msgs <- fmt.Sprintf("1 varLen ----->%v\n", varLen)
							msgs <- fmt.Sprintf("1 newMsg   ----->%#v\n", newMsg)
						}
						vars[i] = string(newMsg.Next(varLen))
						msgs <- fmt.Sprintf("vars   ----->%#v\n", vars)
						varsIdx = append(varsIdx, i)
						msgs <- fmt.Sprintf("varIdx  ----->%#v\n", varsIdx)
					}

					sort.Sort(sort.Reverse(sort.IntSlice(varsIdx)))
					for _, k := range varsIdx {
						// messages = append(messages, strings.Replace(temp, fmt.Sprintf("$%d", k+1), fmt.Sprintf("'%s'", string(newMsg[k+1])), -1))
						temp = strings.Replace(temp, fmt.Sprintf("$%d", k+1), fmt.Sprintf("'%s'", string(vars[k])), -1)
						msgs <- fmt.Sprintf("message subst k ----->%v\n", k)
						msgs <- fmt.Sprintf("message subst newMsg ----->%#v\n", newMsg)
						msgs <- fmt.Sprintf("message subst msg ----->%v\n", vars[k+1])
						msgs <- fmt.Sprintf("message subst temp ----->%v\n", temp)
						msgs <- fmt.Sprintf("message subst param %s ----->%v\n", fmt.Sprintf("$%d", k+1), fmt.Sprintf("'%s'", vars[k]))
					}
					msgs <- fmt.Sprintf("end message  ----->%v\n", temp)
					msgOut <- msgStruct{Type: "M", Content: temp}
				}
				temp = ""
			}
		}
	}()

	proxy.Start(localHost, dbHostname, dbPort, getQueryModificada, msgs, msgCh)
}

func getQueryModificada(queryOriginal string) string {
	// log.Println("aa")
	// if queryOriginal[:5] != "power" {
	// 	return queryOriginal
	// }

	// log.Println(queryOriginal)
	fmt.Println(queryOriginal)
	return queryOriginal
}
<commit_msg>Update<commit_after>package main

import (
	"bufio"
	"bytes"
	"database/sql"
	"flag"
	"fmt"
	"log"
	"os"
	"regexp"
	"sort"
	"strings"
	"time"

	// "database/sql"

	_ "github.com/lib/pq"

	"github.com/DimShadoWWW/power-pg/proxy"
	"github.com/parnurzeal/gorequest"
)

var (
	localHost     = flag.String("l", ":5432", "puerto local para escuchar")
	dbHostname    = flag.String("h", "localhost", "hostname del servidor PostgreSQL")
	dbPort        = flag.String("r", "5432", "puerto del servidor PostgreSQL")
	dbName        = flag.String("d", "dbname", "nombre de la base de datos")
	dbUsername    = flag.String("u", "username", "usuario para acceder al servidor PostgreSQL")
	dbPassword    = flag.String("p", "password", "password para acceder al servidor PostgreSQL")
	remoteService = flag.String("s", "", "http://localhost:8080/query")
	// messages      = []string{}
)

type msgStruct struct {
	Type    string
	Content string
}

var (
	db *sql.DB
)

func main() {
	flag.Parse()
	// dbinfo := fmt.Sprintf("user=%s password=%s dbname=%s sslmode=disable",
	// 	*dbUsername, *dbPassword, *dbName)
	// db, err := sql.Open("postgres", dbinfo)

	msgs := make(chan string)
	msgCh := make(chan proxy.Pkg)
	msgOut := make(chan msgStruct)
	if *remoteService != "" {
		go func() {
			time.Sleep(time.Second * 3)
			inFile, _ := os.Open("canales_list.txt")
			defer inFile.Close()
			scanner := bufio.NewScanner(inFile)
			scanner.Split(bufio.ScanLines)

			for scanner.Scan() {
				time.Sleep(time.Second * 1)
				// messages = []string{}
				// fmt.Println(scanner.Text())
				// msgOut <- fmt.Sprintf("# %s\n", scanner.Text())
				msgOut <- msgStruct{Type: "C", Content: scanner.Text()}
				_, _, errs := gorequest.New().Get(fmt.Sprintf("%s%s", *remoteService, scanner.Text())).End()
				if errs != nil {
					log.Fatalf("log failed: %v", errs)
				}
			}
			log.Println("done")
			os.Exit(0)
		}()
	}

	go func() {
		f, err := os.OpenFile("/all.txt", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
		if err != nil {
			panic(err)
		}
		defer f.Close()
		for msg := range msgs {
			// fmt.Println(msg)
			_, err := f.WriteString(fmt.Sprintf("%s\n", msg))
			if err != nil {
				log.Fatalf("log failed: %v", err)
			}
		}
	}()

	go func() {
		f, err := os.OpenFile("/reports/report.md", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
		// c := 0
		spaces := regexp.MustCompile("[\t]+")
		multipleSpaces := regexp.MustCompile("    ")
		for {
			// select {
			// case msg1 := <-msgOut:
			msg := <-msgOut
			if msg.Type == "C" {
				// c = 0
				f.Close()
				f, err = os.OpenFile(fmt.Sprintf("/reports/report-%s.md", msg.Content), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0777)
				// c = 0
				if err != nil {
					panic(err)
				}
				_, err := f.WriteString(fmt.Sprintf("# %s\n", msg.Content))
				if err != nil {
					log.Fatalf("log failed: %v", err)
				}
			} else {
				// case msg2 := <-msgOut:
				// c = c + 1
				m := spaces.ReplaceAll([]byte(msg.Content), []byte{' '})
				m = multipleSpaces.ReplaceAll(m, []byte{' '})
				_, err := f.WriteString(fmt.Sprintf("\n```sql\n%s\n```\n", string(m)))
				if err != nil {
					log.Fatalf("log failed: %v", err)
				}
			}
		}
	}()

	go func() {
		temp := ""
		for msg := range msgCh {
			if msg.Type == 'P' {
				if strings.Contains(string(msg.Content), "$1") {
					var newMsg proxy.ReadBuf
					newMsg = msg.Content
					_ = newMsg.Int32()

					// The name of the destination portal (an empty string selects the unnamed portal).
					p := bytes.Index(newMsg, []byte{0})
					// remove first string
					msgs <- fmt.Sprintf("msg ---->%#v\n", newMsg)
					msgs <- fmt.Sprintf("msg ---->%s\n", string(newMsg))
					msgs <- fmt.Sprintf("first string ---->%#v\n", newMsg[:p+1])
					msgs <- fmt.Sprintf("first string ---->%s\n", string(newMsg[:p+1]))
					newMsg = newMsg[p+1:]
					fmt.Printf("0 newMsg   ----->%#v\n", newMsg)

					// The name of the source prepared statement (an empty string selects the unnamed prepared statement).
					p = bytes.Index(newMsg, []byte{0})
					// remove second string
					msgs <- fmt.Sprintf("second string: message ---->%#v\n", newMsg[:p])
					temp = string(newMsg[:p])
					msgs <- fmt.Sprintf("second string: message temp ---->%s\n", temp)

				} else {
					temp = ""
					selectIdx := strings.Index(string(msg.Content), string([]byte{83, 69, 76, 69, 67, 84, 32}))
					if selectIdx == -1 {
						selectIdx = 0
					}
					sepIdx := strings.Index(string(msg.Content), string([]byte{0, 0, 1, 0, 0}))
					if sepIdx == -1 || sepIdx+5 > len(msg.Content) {
						sepIdx := strings.Index(string(msg.Content), string([]byte{0, 1, 0, 0}))
						if sepIdx == -1 || sepIdx+4 > len(msg.Content) {
							sepIdx = len(msg.Content) - 4
						} else {
							sepIdx = len(msg.Content) - 1
						}
					}
					if sepIdx == -1 {
						sepIdx = len(msg.Content)
					}
					if selectIdx == -1 {
						selectIdx = 0
					}

					fmt.Printf("SEP index ----->%v\n", sepIdx)
					fmt.Printf("SEP len   ----->%v\n", len(msg.Content))
					fmt.Printf("SEP CONT  ----->%v\n", msg.Content)
					// messages = append(messages, string(bytes.Trim(msg.Content[selectIdx:sepIdx], "\x00")))
					msgOut <- msgStruct{Type: "M", Content: string(bytes.Trim(msg.Content[selectIdx:sepIdx], "\x00"))}
				}
			} else {
				if msg.Type == 'B' && temp != "" {
					var newMsg proxy.ReadBuf
					newMsg = msg.Content

					// The name of the destination portal (an empty string selects the unnamed portal).
					p := bytes.Index(newMsg, []byte{0})
					// remove first string
					msgs <- fmt.Sprintf("msg ---->%#v\n", newMsg)
					msgs <- fmt.Sprintf("first string ---->%#v\n", newMsg[:p+1])
					newMsg = newMsg[p:]
					fmt.Printf("0 newMsg   ----->%#v\n", newMsg)

					// The name of the source prepared statement (an empty string selects the unnamed prepared statement).
					p = bytes.Index(newMsg, []byte{0})
					// remove second string
					msgs <- fmt.Sprintf("second string ---->%#v\n", newMsg[:p+1])
					newMsg = newMsg[p+1:]
					fmt.Printf("1 newMsg   ----->%#v\n", newMsg)

					t := newMsg.Int16()
					msgs <- fmt.Sprintf("vars types numbers ---->%#v\n", t)
					for i := 0; i < t; i++ {
						t = newMsg.Int16()
						msgs <- fmt.Sprintf("22 newMsg   ----->%#v\n", newMsg)
					}

					msgs <- fmt.Sprintf("23 newMsg   ----->%#v\n", newMsg)
					totalVar := newMsg.Int16()
					vars := make(map[int]string)
					var varsIdx []int
					for totalVar := 0; (totalVar == 0 && len(newMsg) > 4) || totalVar > len(newMsg); {
						totalVar = newMsg.Int16()
					}
					//
					// if totalVar == 0 && len(newMsg) > 4 {
					// 	totalVar = newMsg.Int16()
					// }
					// if totalVar == 0 && len(newMsg) > 4 {
					// 	totalVar = newMsg.Int32()
					// }
					msgs <- fmt.Sprintf("totalVar   ----->%d\n", totalVar)
					for i := 0; i < totalVar; i++ {
						msgs <- fmt.Sprintf("2 newMsg   ----->%#v\n", newMsg)
						varLen := newMsg.Int32()
						// var1 := newMsg.Next(4)
						// // fmt.Printf("aa   -----> %#v\n", aa)
						// // fmt.Printf("aa bits ----->%8b\n", aa[len(aa)-1])
						// varLen := int(binary.BigEndian.Uint32(var1))
						// if varLen > len(newMsg) {
						// 	varLen = int(binary.BigEndian.Uint16(var1[:2]))
						// }
						msgs <- fmt.Sprintf("varLen ----->%v\n", varLen)
						msgs <- fmt.Sprintf("newMsg   ----->%#v\n", newMsg)
						if varLen > len(newMsg) {
							varLen = len(newMsg) - 4
							msgs <- fmt.Sprintf("1 varLen ----->%v\n", varLen)
							msgs <- fmt.Sprintf("1 newMsg   ----->%#v\n", newMsg)
						}
						vars[i] = string(newMsg.Next(varLen))
						msgs <- fmt.Sprintf("vars   ----->%#v\n", vars)
						varsIdx = append(varsIdx, i)
						msgs <- fmt.Sprintf("varIdx  ----->%#v\n", varsIdx)
					}

					sort.Sort(sort.Reverse(sort.IntSlice(varsIdx)))
					for _, k := range varsIdx {
						// messages = append(messages, strings.Replace(temp, fmt.Sprintf("$%d", k+1), fmt.Sprintf("'%s'", string(newMsg[k+1])), -1))
						temp = strings.Replace(temp, fmt.Sprintf("$%d", k+1), fmt.Sprintf("'%s'", string(vars[k])), -1)
						msgs <- fmt.Sprintf("message subst k ----->%v\n", k)
						msgs <- fmt.Sprintf("message subst newMsg ----->%#v\n", newMsg)
						msgs <- fmt.Sprintf("message subst msg ----->%v\n", vars[k+1])
						msgs <- fmt.Sprintf("message subst temp ----->%v\n", temp)
						msgs <- fmt.Sprintf("message subst param %s ----->%v\n", fmt.Sprintf("$%d", k+1), fmt.Sprintf("'%s'", vars[k]))
					}
					msgs <- fmt.Sprintf("end message  ----->%v\n", temp)
					msgOut <- msgStruct{Type: "M", Content: temp}
				}
				temp = ""
			}
		}
	}()

	proxy.Start(localHost, dbHostname, dbPort, getQueryModificada, msgs, msgCh)
}

func getQueryModificada(queryOriginal string) string {
	// log.Println("aa")
	// if queryOriginal[:5] != "power" {
	// 	return queryOriginal
	// }

	// log.Println(queryOriginal)
	fmt.Println(queryOriginal)
	return queryOriginal
}
<|endoftext|>