<commit_before>package main

import (
	"encoding/json"
	"errors"
	"log"
	"time"

	"github.com/apex/go-apex"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/cloudwatch"
	"github.com/buildkite/buildkite-cloudwatch-metrics-publisher/functions/collect-metrics/buildkite"
)

var historicalData = time.Hour * -72

// Generates:
// Buildkite > RunningBuildsCount
// Buildkite > RunningJobsCount
// Buildkite > ScheduledBuildsCount
// Buildkite > ScheduledJobsCount
// Buildkite > (Queue) > RunningBuildsCount
// Buildkite > (Queue) > RunningJobsCount
// Buildkite > (Queue) > ScheduledBuildsCount
// Buildkite > (Queue) > ScheduledJobsCount
// Buildkite > (Pipeline) > RunningBuildsCount
// Buildkite > (Pipeline) > RunningJobsCount
// Buildkite > (Pipeline) > ScheduledBuildsCount
// Buildkite > (Pipeline) > ScheduledJobsCount

func main() {
	apex.HandleFunc(func(event json.RawMessage, ctx *apex.Context) (interface{}, error) {
		svc := cloudwatch.New(session.New())

		var conf Config

		if err := json.Unmarshal(event, &conf); err != nil {
			return nil, err
		}

		if conf.BuildkiteApiAccessToken == "" {
			return nil, errors.New("No BuildkiteApiAccessToken provided")
		}

		if conf.BuildkiteOrgSlug == "" {
			return nil, errors.New("No BuildkiteOrgSlug provided")
		}

		cutoff := time.Now().UTC().Add(time.Minute * -5)

		log.Printf("Querying buildkite for builds for org %s after %s",
			conf.BuildkiteOrgSlug,
			time.Now().UTC().Add(historicalData).String())

		builds, err := buildkite.Builds(&buildkite.BuildsInput{
			OrgSlug:     conf.BuildkiteOrgSlug,
			ApiToken:    conf.BuildkiteApiAccessToken,
			CreatedFrom: time.Now().UTC().Add(historicalData),
			CreatedTo:   time.Now().UTC(),
		})
		if err != nil {
			return nil, err
		}

		var res Result = Result{
			Queues:    map[string]Counts{"default": Counts{}},
			Pipelines: map[string]Counts{},
		}

		log.Printf("Aggregating results from %d builds", len(builds.Builds))

		for _, build := range builds.Builds {
			if _, ok := res.Pipelines[build.Pipeline.Name]; !ok {
				res.Pipelines[build.Pipeline.Name] = Counts{}
			}

			if afterTime(cutoff, build.CreatedAt, build.FinishedAt) {
				log.Printf("Adding build %s to stats", build.ID)
				res.Counts = res.Counts.addBuild(build)
				res.Pipelines[build.Pipeline.Name] = res.Pipelines[build.Pipeline.Name].addBuild(build)
			}

			var buildQueues = map[string]int{}
			for _, job := range build.Jobs {
				if _, ok := res.Queues[job.Queue()]; !ok {
					res.Queues[job.Queue()] = Counts{}
				}

				if afterTime(cutoff, job.CreatedAt, job.FinishedAt, job.ScheduledAt, job.StartedAt) {
					log.Printf("Adding job %s to stats", job.ID)
					res.Counts = res.Counts.addJob(job)
					res.Pipelines[build.Pipeline.Name] = res.Pipelines[build.Pipeline.Name].addJob(job)
					res.Queues[job.Queue()] = res.Queues[job.Queue()].addJob(job)
					buildQueues[job.Queue()]++
				}

			}

			for queue := range buildQueues {
				res.Queues[queue] = res.Queues[queue].addBuild(build)
			}
		}

		log.Printf("Extracting cloudwatch metrics from results")
		metrics := res.extractMetricData()

		for _, chunk := range chunkMetricData(10, metrics) {
			log.Printf("Submitting chunk of %d metrics to Cloudwatch", len(chunk))
			if err = putMetricData(svc, chunk); err != nil {
				return nil, err
			}
		}

		return res, nil
	})
}

func afterTime(after time.Time, times ...*time.Time) bool {
	for _, t := range times {
		if t != nil && t.After(after) {
			return true
		}
	}
	return false
}

type Config struct {
	BuildkiteOrgSlug, BuildkiteApiAccessToken string
}

type Counts struct {
	RunningBuilds, RunningJobs, ScheduledBuilds, ScheduledJobs int
}

func (c Counts) addBuild(build buildkite.Build) Counts {
	switch build.State {
	case "running":
		c.RunningBuilds++
	case "scheduled":
		c.ScheduledBuilds++
	}
	return c
}

func (c Counts) addJob(job buildkite.Job) Counts {
	switch job.State {
	case "running":
		c.RunningJobs++
	case "scheduled":
		c.ScheduledJobs++
	}
	return c
}

func (c Counts) asMetrics(dimensions []*cloudwatch.Dimension) []*cloudwatch.MetricDatum {
	return []*cloudwatch.MetricDatum{
		&cloudwatch.MetricDatum{
			MetricName: aws.String("RunningBuildsCount"),
			Dimensions: dimensions,
			Value:      aws.Float64(float64(c.RunningBuilds)),
			Unit:       aws.String("Count"),
		},
		&cloudwatch.MetricDatum{
			MetricName: aws.String("ScheduledBuildsCount"),
			Dimensions: dimensions,
			Value:      aws.Float64(float64(c.ScheduledBuilds)),
			Unit:       aws.String("Count"),
		},
		&cloudwatch.MetricDatum{
			MetricName: aws.String("RunningJobsCount"),
			Dimensions: dimensions,
			Value:      aws.Float64(float64(c.RunningJobs)),
			Unit:       aws.String("Count"),
		},
		&cloudwatch.MetricDatum{
			MetricName: aws.String("ScheduledJobsCount"),
			Dimensions: dimensions,
			Value:      aws.Float64(float64(c.ScheduledJobs)),
			Unit:       aws.String("Count"),
		},
	}
}

type Result struct {
	Counts
	Queues, Pipelines map[string]Counts
}

func (r Result) extractMetricData() []*cloudwatch.MetricDatum {
	data := []*cloudwatch.MetricDatum{}
	data = append(data, r.Counts.asMetrics(nil)...)

	for name, c := range r.Queues {
		data = append(data, c.asMetrics([]*cloudwatch.Dimension{
			{Name: aws.String("Queue"), Value: aws.String(name)},
		})...)
	}

	for name, c := range r.Pipelines {
		data = append(data, c.asMetrics([]*cloudwatch.Dimension{
			{Name: aws.String("Pipeline"), Value: aws.String(name)},
		})...)
	}

	return data
}

func chunkMetricData(size int, data []*cloudwatch.MetricDatum) [][]*cloudwatch.MetricDatum {
	var chunks = [][]*cloudwatch.MetricDatum{}
	for i := 0; i < len(data); i += size {
		end := i + size
		if end > len(data) {
			end = len(data)
		}
		chunks = append(chunks, data[i:end])
	}
	return chunks
}

func putMetricData(svc *cloudwatch.CloudWatch, data []*cloudwatch.MetricDatum) error {
	_, err := svc.PutMetricData(&cloudwatch.PutMetricDataInput{
		MetricData: data,
		Namespace:  aws.String("Buildkite"),
	})
	if err != nil {
		return err
	}

	return nil
}
<commit_msg>Filter based on jobs times, not builds<commit_after>package main

import (
	"encoding/json"
	"errors"
	"log"
	"time"

	"github.com/apex/go-apex"
	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/cloudwatch"
	"github.com/buildkite/buildkite-cloudwatch-metrics-publisher/functions/collect-metrics/buildkite"
)

var historicalData = time.Hour * -72

// Generates:
// Buildkite > RunningBuildsCount
// Buildkite > RunningJobsCount
// Buildkite > ScheduledBuildsCount
// Buildkite > ScheduledJobsCount
// Buildkite > (Queue) > RunningBuildsCount
// Buildkite > (Queue) > RunningJobsCount
// Buildkite > (Queue) > ScheduledBuildsCount
// Buildkite > (Queue) > ScheduledJobsCount
// Buildkite > (Pipeline) > RunningBuildsCount
// Buildkite > (Pipeline) > RunningJobsCount
// Buildkite > (Pipeline) > ScheduledBuildsCount
// Buildkite > (Pipeline) > ScheduledJobsCount

func main() {
	apex.HandleFunc(func(event json.RawMessage, ctx *apex.Context) (interface{}, error) {
		svc := cloudwatch.New(session.New())

		var conf Config

		if err := json.Unmarshal(event, &conf); err != nil {
			return nil, err
		}

		if conf.BuildkiteApiAccessToken == "" {
			return nil, errors.New("No BuildkiteApiAccessToken provided")
		}

		if conf.BuildkiteOrgSlug == "" {
			return nil, errors.New("No BuildkiteOrgSlug provided")
		}

		cutoff := time.Now().UTC().Add(time.Minute * -5)

		log.Printf("Querying buildkite for builds for org %s after %s",
			conf.BuildkiteOrgSlug,
			time.Now().UTC().Add(historicalData).String())

		builds, err := buildkite.Builds(&buildkite.BuildsInput{
			OrgSlug:     conf.BuildkiteOrgSlug,
			ApiToken:    conf.BuildkiteApiAccessToken,
			CreatedFrom: time.Now().UTC().Add(historicalData),
			CreatedTo:   time.Now().UTC(),
		})
		if err != nil {
			return nil, err
		}

		var res Result = Result{
			Queues:    map[string]Counts{"default": Counts{}},
			Pipelines: map[string]Counts{},
		}

		log.Printf("Aggregating results from %d builds", len(builds.Builds))

		for _, build := range builds.Builds {
			if _, ok := res.Pipelines[build.Pipeline.Name]; !ok {
				res.Pipelines[build.Pipeline.Name] = Counts{}
			}

			var buildQueues = map[string]int{}
			for _, job := range build.Jobs {
				if _, ok := res.Queues[job.Queue()]; !ok {
					res.Queues[job.Queue()] = Counts{}
				}

				if afterTime(cutoff, job.CreatedAt, job.FinishedAt, job.ScheduledAt, job.StartedAt) {
					log.Printf("Adding job to stats (id=%q, pipeline=%q, queue=%s)", job.ID, build.Pipeline.Name, job.Queue())
					res.Counts = res.Counts.addJob(job)
					res.Pipelines[build.Pipeline.Name] = res.Pipelines[build.Pipeline.Name].addJob(job)
					res.Queues[job.Queue()] = res.Queues[job.Queue()].addJob(job)
					buildQueues[job.Queue()]++
				}
			}

			if len(buildQueues) > 0 {
				log.Printf("Adding build to stats (id=%q, pipeline=%q)", build.ID, build.Pipeline.Name)
				res.Counts = res.Counts.addBuild(build)
				res.Pipelines[build.Pipeline.Name] = res.Pipelines[build.Pipeline.Name].addBuild(build)
			}

			for queue := range buildQueues {
				res.Queues[queue] = res.Queues[queue].addBuild(build)
			}
		}

		log.Printf("Extracting cloudwatch metrics from results")
		metrics := res.extractMetricData()

		for _, chunk := range chunkMetricData(10, metrics) {
			log.Printf("Submitting chunk of %d metrics to Cloudwatch", len(chunk))
			if err = putMetricData(svc, chunk); err != nil {
				return nil, err
			}
		}

		return res, nil
	})
}

type Config struct {
	BuildkiteOrgSlug, BuildkiteApiAccessToken string
}

type Counts struct {
	RunningBuilds, RunningJobs, ScheduledBuilds, ScheduledJobs int
}

func (c Counts) addBuild(build buildkite.Build) Counts {
	switch build.State {
	case "running":
		c.RunningBuilds++
	case "scheduled":
		c.ScheduledBuilds++
	}
	return c
}

func (c Counts) addJob(job buildkite.Job) Counts {
	switch job.State {
	case "running":
		c.RunningJobs++
	case "scheduled":
		c.ScheduledJobs++
	}
	return c
}

func (c Counts) asMetrics(dimensions []*cloudwatch.Dimension) []*cloudwatch.MetricDatum {
	return []*cloudwatch.MetricDatum{
		&cloudwatch.MetricDatum{
			MetricName: aws.String("RunningBuildsCount"),
			Dimensions: dimensions,
			Value:      aws.Float64(float64(c.RunningBuilds)),
			Unit:       aws.String("Count"),
		},
		&cloudwatch.MetricDatum{
			MetricName: aws.String("ScheduledBuildsCount"),
			Dimensions: dimensions,
			Value:      aws.Float64(float64(c.ScheduledBuilds)),
			Unit:       aws.String("Count"),
		},
		&cloudwatch.MetricDatum{
			MetricName: aws.String("RunningJobsCount"),
			Dimensions: dimensions,
			Value:      aws.Float64(float64(c.RunningJobs)),
			Unit:       aws.String("Count"),
		},
		&cloudwatch.MetricDatum{
			MetricName: aws.String("ScheduledJobsCount"),
			Dimensions: dimensions,
			Value:      aws.Float64(float64(c.ScheduledJobs)),
			Unit:       aws.String("Count"),
		},
	}
}

type Result struct {
	Counts
	Queues, Pipelines map[string]Counts
}

func (r Result) extractMetricData() []*cloudwatch.MetricDatum {
	data := []*cloudwatch.MetricDatum{}
	data = append(data, r.Counts.asMetrics(nil)...)

	for name, c := range r.Queues {
		data = append(data, c.asMetrics([]*cloudwatch.Dimension{
			{Name: aws.String("Queue"), Value: aws.String(name)},
		})...)
	}

	for name, c := range r.Pipelines {
		data = append(data, c.asMetrics([]*cloudwatch.Dimension{
			{Name: aws.String("Pipeline"), Value: aws.String(name)},
		})...)
	}

	return data
}

func chunkMetricData(size int, data []*cloudwatch.MetricDatum) [][]*cloudwatch.MetricDatum {
	var chunks = [][]*cloudwatch.MetricDatum{}
	for i := 0; i < len(data); i += size {
		end := i + size
		if end > len(data) {
			end = len(data)
		}
		chunks = append(chunks, data[i:end])
	}
	return chunks
}

func putMetricData(svc *cloudwatch.CloudWatch, data []*cloudwatch.MetricDatum) error {
	_, err := svc.PutMetricData(&cloudwatch.PutMetricDataInput{
		MetricData: data,
		Namespace:  aws.String("Buildkite"),
	})
	if err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>package fasthttputil

import (
	"errors"
	"io"
	"net"
	"sync"
	"time"
)

func newPipeConns() *pipeConns {
	ch1 := acquirePipeChan()
	ch2 := acquirePipeChan()

	pc := &pipeConns{}
	pc.c1.r = ch1
	pc.c1.w = ch2
	pc.c2.r = ch2
	pc.c2.w = ch1
	pc.c1.parent = pc
	pc.c2.parent = pc
	return pc
}

type pipeConns struct {
	c1 pipeConn
	c2 pipeConn
}

func (pc *pipeConns) release() {
	pc.c1.wlock.Lock()
	pc.c2.wlock.Lock()
	mustRelease := pc.c1.wclosed && pc.c2.wclosed
	pc.c1.wlock.Unlock()
	pc.c2.wlock.Unlock()

	if mustRelease {
		pc.c1.release()
		pc.c2.release()
	}
}

type pipeConn struct {
	r  *pipeChan
	w  *pipeChan
	b  *byteBuffer
	bb []byte

	rclosed bool

	wlock   sync.Mutex
	wclosed bool

	parent *pipeConns
}

func (c *pipeConn) Write(p []byte) (int, error) {
	b := acquireByteBuffer()
	b.b = append(b.b[:0], p...)

	c.wlock.Lock()
	if c.wclosed {
		c.wlock.Unlock()
		releaseByteBuffer(b)
		return 0, errors.New("connection closed for writing")
	}
	c.w.ch <- b
	c.wlock.Unlock()

	return len(p), nil
}

func (c *pipeConn) Read(p []byte) (int, error) {
	mayBlock := true
	nn := 0
	for len(p) > 0 {
		n, err := c.read(p, mayBlock)
		nn += n
		if err != nil {
			if !mayBlock && err == errWouldBlock {
				err = nil
			} else {
			}
			return nn, err
		}
		p = p[n:]
		mayBlock = false
	}

	return nn, nil
}

func (c *pipeConn) read(p []byte, mayBlock bool) (int, error) {
	if len(c.bb) == 0 {
		releaseByteBuffer(c.b)
		c.b = nil

		if c.rclosed {
			return 0, io.EOF
		}

		if mayBlock {
			c.b = <-c.r.ch
		} else {
			select {
			case c.b = <-c.r.ch:
			default:
				return 0, errWouldBlock
			}
		}

		if c.b == nil {
			c.rclosed = true
			return 0, io.EOF
		}
		c.bb = c.b.b
	}
	n := copy(p, c.bb)
	c.bb = c.bb[n:]

	return n, nil
}

var errWouldBlock = errors.New("would block")

func (c *pipeConn) Close() error {
	c.wlock.Lock()
	c.wclosed = true
	c.w.ch <- nil
	c.wlock.Unlock()

	c.parent.release()
	return nil
}

func (c *pipeConn) release() {
	releaseByteBuffer(c.b)
	releasePipeChan(c.r)

	c.r = nil
	c.w = nil
	c.b = nil
	c.bb = nil
}

func (p *pipeConn) LocalAddr() net.Addr {
	return pipeAddr(0)
}

func (p *pipeConn) RemoteAddr() net.Addr {
	return pipeAddr(0)
}

func (p *pipeConn) SetDeadline(t time.Time) error {
	return errors.New("deadline not supported")
}

func (p *pipeConn) SetReadDeadline(t time.Time) error {
	return p.SetDeadline(t)
}

func (p *pipeConn) SetWriteDeadline(t time.Time) error {
	return p.SetDeadline(t)
}

type pipeAddr int

func (pipeAddr) Network() string {
	return "pipe"
}

func (pipeAddr) String() string {
	return "pipe"
}

type byteBuffer struct {
	b []byte
}

func acquireByteBuffer() *byteBuffer {
	return byteBufferPool.Get().(*byteBuffer)
}

func releaseByteBuffer(b *byteBuffer) {
	if b != nil {
		byteBufferPool.Put(b)
	}
}

var byteBufferPool = &sync.Pool{
	New: func() interface{} {
		return &byteBuffer{}
	},
}

func acquirePipeChan() *pipeChan {
	ch := pipeChanPool.Get().(*pipeChan)
	if len(ch.ch) > 0 {
		panic("BUG: non-empty pipeChan acquired")
	}
	return ch
}

func releasePipeChan(ch *pipeChan) {
	for b := range ch.ch {
		releaseByteBuffer(b)
	}
	pipeChanPool.Put(ch)
}

var pipeChanPool = &sync.Pool{
	New: func() interface{} {
		return &pipeChan{
			ch: make(chan *byteBuffer, 4),
		}
	},
}

type pipeChan struct {
	ch chan *byteBuffer
}
<commit_msg>InmemoryListener: fixed races in pipe implementation<commit_after>package fasthttputil

import (
	"errors"
	"io"
	"net"
	"sync"
	"time"
)

func newPipeConns() *pipeConns {
	ch1 := acquirePipeChan()
	ch2 := acquirePipeChan()

	pc := &pipeConns{}
	pc.c1.r = ch1
	pc.c1.w = ch2
	pc.c2.r = ch2
	pc.c2.w = ch1
	pc.c1.parent = pc
	pc.c2.parent = pc
	return pc
}

type pipeConns struct {
	c1 pipeConn
	c2 pipeConn
}

func (pc *pipeConns) release() {
	pc.c1.wlock.Lock()
	pc.c2.wlock.Lock()
	mustRelease := pc.c1.wclosed && pc.c2.wclosed
	pc.c1.wlock.Unlock()
	pc.c2.wlock.Unlock()

	if mustRelease {
		pc.c1.release()
		pc.c2.release()
	}
}

type pipeConn struct {
	r  *pipeChan
	w  *pipeChan
	b  *byteBuffer
	bb []byte

	rlock   sync.Mutex
	rclosed bool

	wlock   sync.Mutex
	wclosed bool

	parent *pipeConns
}

func (c *pipeConn) Write(p []byte) (int, error) {
	b := acquireByteBuffer()
	b.b = append(b.b[:0], p...)

	c.wlock.Lock()
	if c.wclosed {
		c.wlock.Unlock()
		releaseByteBuffer(b)
		return 0, errors.New("connection closed for writing")
	}
	c.w.ch <- b
	c.wlock.Unlock()

	return len(p), nil
}

func (c *pipeConn) Read(p []byte) (int, error) {
	mayBlock := true
	nn := 0
	for len(p) > 0 {
		n, err := c.read(p, mayBlock)
		nn += n
		if err != nil {
			if !mayBlock && err == errWouldBlock {
				err = nil
			}
			return nn, err
		}
		p = p[n:]
		mayBlock = false
	}

	return nn, nil
}

func (c *pipeConn) read(p []byte, mayBlock bool) (int, error) {
	if len(c.bb) == 0 {
		releaseByteBuffer(c.b)
		c.b = nil

		c.rlock.Lock()
		if c.rclosed {
			c.rlock.Unlock()
			return 0, io.EOF
		}

		if mayBlock {
			c.b = <-c.r.ch
		} else {
			select {
			case c.b = <-c.r.ch:
			default:
				c.rlock.Unlock()
				return 0, errWouldBlock
			}
		}

		if c.b == nil {
			c.rclosed = true
			c.rlock.Unlock()
			return 0, io.EOF
		}
		c.rlock.Unlock()

		c.bb = c.b.b
	}
	n := copy(p, c.bb)
	c.bb = c.bb[n:]

	return n, nil
}

var errWouldBlock = errors.New("would block")

func (c *pipeConn) Close() error {
	c.wlock.Lock()
	c.wclosed = true
	c.w.ch <- nil
	c.wlock.Unlock()

	c.parent.release()
	return nil
}

func (c *pipeConn) release() {
	c.rlock.Lock()

	releaseByteBuffer(c.b)
	c.b = nil
	c.bb = nil

	if !c.rclosed {
		c.rclosed = true
		releasePipeChan(c.r)
	}

	c.r = nil
	c.w = nil
	c.rlock.Unlock()
}

func (p *pipeConn) LocalAddr() net.Addr {
	return pipeAddr(0)
}

func (p *pipeConn) RemoteAddr() net.Addr {
	return pipeAddr(0)
}

func (p *pipeConn) SetDeadline(t time.Time) error {
	return errors.New("deadline not supported")
}

func (p *pipeConn) SetReadDeadline(t time.Time) error {
	return p.SetDeadline(t)
}

func (p *pipeConn) SetWriteDeadline(t time.Time) error {
	return p.SetDeadline(t)
}

type pipeAddr int

func (pipeAddr) Network() string {
	return "pipe"
}

func (pipeAddr) String() string {
	return "pipe"
}

type byteBuffer struct {
	b []byte
}

func acquireByteBuffer() *byteBuffer {
	return byteBufferPool.Get().(*byteBuffer)
}

func releaseByteBuffer(b *byteBuffer) {
	if b != nil {
		byteBufferPool.Put(b)
	}
}

var byteBufferPool = &sync.Pool{
	New: func() interface{} {
		return &byteBuffer{}
	},
}

func acquirePipeChan() *pipeChan {
	ch := pipeChanPool.Get().(*pipeChan)
	if len(ch.ch) > 0 {
		panic("BUG: non-empty pipeChan acquired")
	}
	return ch
}

func releasePipeChan(ch *pipeChan) {
	for b := range ch.ch {
		releaseByteBuffer(b)
		if b == nil {
			break
		}
	}
	pipeChanPool.Put(ch)
}

var pipeChanPool = &sync.Pool{
	New: func() interface{} {
		return &pipeChan{
			ch: make(chan *byteBuffer, 4),
		}
	},
}

type pipeChan struct {
	ch chan *byteBuffer
}
<|endoftext|>


<commit_before>package main

import (
	"errors"
	"fmt"
	"os"
	"path"
	"runtime"
	"strconv"
	"strings"
)

// The extension of files created by the Go compiler (.5 .6 .8 .o)
var o_ext string

// The Go compiler (5g, 6g, 8g, gccgo)
var goCompiler_name string
var goCompiler_flags []string

// The Go archiver (gopack, ar)
var goArchiver_name string
var goArchiver_flags []string
var goArchiver_libNamePrefix string

// The Go linker (5l, 6l, 8l, gccgo)
var goLinker_name string

// The directory where to put/find installed libraries
var libInstallRoot string = path.Join(runtime.GOROOT(), "pkg", runtime.GOOS+"_"+runtime.GOARCH)

// The directory where to put remote packages
var remotePkgInstallRoot string = path.Join(runtime.GOROOT(), "src", "pkg")

// The directory where to put executables
var exeInstallDir string

var goCompiler_exe *Executable = nil
var goArchiver_exe *Executable = nil
var goLinker_exe *Executable = nil

func initArch() {
	if !(*flag_gcc) {
		goArchiver_name = "gopack"
		goArchiver_flags = []string{"grc"}
		goArchiver_libNamePrefix = ""

		switch runtime.GOARCH {
		case "386":
			o_ext = ".8"
			goCompiler_name = "8g"
			goLinker_name = "8l"

		case "amd64":
			o_ext = ".6"
			goCompiler_name = "6g"
			goLinker_name = "6l"

		case "arm":
			o_ext = ".5"
			goCompiler_name = "5g"
			goLinker_name = "5l"

		default:
			fmt.Fprintf(os.Stderr, "unknown GOARCH: %s\n", runtime.GOARCH)
			os.Exit(1)
		}
	} else {
		o_ext = ".o"
		goCompiler_name = "gccgo"
		goCompiler_flags = []string{"-c"}
		goArchiver_name = "ar"
		goArchiver_flags = []string{"rc"}
		goArchiver_libNamePrefix = "lib"
		goLinker_name = "gccgo"
	}

	exeInstallDir = os.Getenv("GOBIN")
	if len(exeInstallDir) == 0 {
		exeInstallDir = path.Join(runtime.GOROOT(), "bin")
	}

	goCompiler_exe = &Executable{name: goCompiler_name}
	goArchiver_exe = &Executable{name: goArchiver_name}
	goLinker_exe = &Executable{name: goLinker_name}
}

var goCompilerVersion *uint = nil

// Requires Go release.2010-12-15.1
const min_compiler_version_for_cgo = 6980

func getGoCompilerVersion() (uint, error) {
	if goCompilerVersion == nil {
		args := []string{goCompiler_exe.name, "-V"}
		stdout, _, err := goCompiler_exe.run(args, /*dir*/ "", /*in*/ "", /*mergeStdoutAndStderr*/ true)
		if err != nil {
			return 0, errors.New("failed to determine Go compiler version: " + err.Error())
		}

		stdout = strings.TrimSpace(stdout)
		var stdout_split []string = strings.Split(stdout, " ")
		if len(stdout_split) < 3 {
			return 0, errors.New("failed to extract [Go compiler version] from string \"" + stdout + "\"" +
				" (possible cause: you didn't have the Mercurial versioning system installed when you were compiling the Go distribution)")
		}

		version, err := strconv.Atoui(strings.TrimRight(stdout_split[2], "+"))
		if (err != nil) && (len(stdout_split) >= 4) {
			version, err = strconv.Atoui(strings.TrimRight(stdout_split[3], "+"))
		}
		if err != nil {
			return 0, errors.New("failed to extract [Go compiler version] from string \"" + stdout + "\"")
		}

		goCompilerVersion = new(uint)
		*goCompilerVersion = version
	}

	return *goCompilerVersion, nil
}
<commit_msg>Update in response to Go weekly.2011-12-06<commit_after>package main

import (
	"errors"
	"fmt"
	"os"
	"path"
	"runtime"
	"strconv"
	"strings"
)

// The extension of files created by the Go compiler (.5 .6 .8 .o)
var o_ext string

// The Go compiler (5g, 6g, 8g, gccgo)
var goCompiler_name string
var goCompiler_flags []string

// The Go archiver (gopack, ar)
var goArchiver_name string
var goArchiver_flags []string
var goArchiver_libNamePrefix string

// The Go linker (5l, 6l, 8l, gccgo)
var goLinker_name string

// The directory where to put/find installed libraries
var libInstallRoot string = path.Join(runtime.GOROOT(), "pkg", runtime.GOOS+"_"+runtime.GOARCH)

// The directory where to put remote packages
var remotePkgInstallRoot string = path.Join(runtime.GOROOT(), "src", "pkg")

// The directory where to put executables
var exeInstallDir string

var goCompiler_exe *Executable = nil
var goArchiver_exe *Executable = nil
var goLinker_exe *Executable = nil

func initArch() {
	if !(*flag_gcc) {
		goArchiver_name = "gopack"
		goArchiver_flags = []string{"grc"}
		goArchiver_libNamePrefix = ""

		switch runtime.GOARCH {
		case "386":
			o_ext = ".8"
			goCompiler_name = "8g"
			goLinker_name = "8l"

		case "amd64":
			o_ext = ".6"
			goCompiler_name = "6g"
			goLinker_name = "6l"

		case "arm":
			o_ext = ".5"
			goCompiler_name = "5g"
			goLinker_name = "5l"

		default:
			fmt.Fprintf(os.Stderr, "unknown GOARCH: %s\n", runtime.GOARCH)
			os.Exit(1)
		}
	} else {
		o_ext = ".o"
		goCompiler_name = "gccgo"
		goCompiler_flags = []string{"-c"}
		goArchiver_name = "ar"
		goArchiver_flags = []string{"rc"}
		goArchiver_libNamePrefix = "lib"
		goLinker_name = "gccgo"
	}

	exeInstallDir = os.Getenv("GOBIN")
	if len(exeInstallDir) == 0 {
		exeInstallDir = path.Join(runtime.GOROOT(), "bin")
	}

	goCompiler_exe = &Executable{name: goCompiler_name}
	goArchiver_exe = &Executable{name: goArchiver_name}
	goLinker_exe = &Executable{name: goLinker_name}
}

var goCompilerVersion *uint = nil

// Requires Go release.2010-12-15.1
const min_compiler_version_for_cgo = 6980

func getGoCompilerVersion() (uint, error) {
	if goCompilerVersion == nil {
		args := []string{goCompiler_exe.name, "-V"}
		stdout, _, err := goCompiler_exe.run(args, /*dir*/ "", /*in*/ "", /*mergeStdoutAndStderr*/ true)
		if err != nil {
			return 0, errors.New("failed to determine Go compiler version: " + err.Error())
		}

		stdout = strings.TrimSpace(stdout)
		var stdout_split []string = strings.Split(stdout, " ")
		if len(stdout_split) < 3 {
			return 0, errors.New("failed to extract [Go compiler version] from string \"" + stdout + "\"" +
				" (possible cause: you didn't have the Mercurial versioning system installed when you were compiling the Go distribution)")
		}

		version, err := strconv.ParseUint(strings.TrimRight(stdout_split[2], "+"), 10, 0)
		if (err != nil) && (len(stdout_split) >= 4) {
			version, err = strconv.ParseUint(strings.TrimRight(stdout_split[3], "+"), 10, 0)
		}
		if err != nil {
			return 0, errors.New("failed to extract [Go compiler version] from string \"" + stdout + "\"")
		}

		goCompilerVersion = new(uint)
		*goCompilerVersion = uint(version)
	}

	return *goCompilerVersion, nil
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"lambda.sx/marcus/lambdago/migrate"
	"lambda.sx/marcus/lambdago/settings"
	"lambda.sx/marcus/lambdago/sql"
	"lambda.sx/marcus/lambdago/views"
	"net/http"
	"strings"
)

// Function that is called for a view
type ViewFunc func(*http.Request, http.ResponseWriter) (error, string)

var urlMap = map[string]ViewFunc{
	"/":              views.HandleIndex,
	"/register":      views.HandleRegister,
	"/login":         views.HandleLogin,
	"/logout":        views.HandleLogout,
	"/usercp":        views.HandleUserCP,
	"/toggleencrypt": views.HandleToggleEncryption,
	"/settheme":      views.HandleSetTheme,
	"/keycheck":      views.HandleVerifyKey,
	"/getkey":        views.HandleGetKey,
	"/upload":        views.HandleUpload,
	"/paste":         views.HandlePaste,
	"/p":             views.HandlePaste,
	"/about":         views.HandleAbout,
	"/manageuploads": views.HandleManageUploads,
	"/delete":        views.HandleDelete,
}

func main() {
	settings.Init()
	// Start up SQL connection
	sql.Init()
	migrate.MigrateDB()

	// Create a static server for serving things in the static/ directory
	staticServer := http.FileServer(http.Dir("static"))
	// Use a static file server for /static/
	http.Handle("/static/", http.StripPrefix("/static/", staticServer))
	// Use handler for everything else
	http.HandleFunc("/", handler)

	// Start listening on port 9000 on every interface
	http.ListenAndServe(":9000", nil)
}

// handler dispatches requests to their view or serves an error
func handler(w http.ResponseWriter, r *http.Request) {
	vfunc := urlMap[strings.Split(strings.ToLower(r.URL.String()), "?")[0]]
	if vfunc == nil { // 404, no view to handle request
		vfunc = views.HandleDefault
	}
	err, responseHtml := vfunc(r, w)
	if err != nil { // 500, server dun goofed
		//TODO 500 page
		fmt.Println("500 at " + r.URL.String())
		panic(err)
	}
	fmt.Fprint(w, responseHtml) // Print the html to the response writer
}
<commit_msg>Use the same number of processes as the number of CPUs<commit_after>package main

import (
	"fmt"
	"lambda.sx/marcus/lambdago/migrate"
	"lambda.sx/marcus/lambdago/settings"
	"lambda.sx/marcus/lambdago/sql"
	"lambda.sx/marcus/lambdago/views"
	"net/http"
	"runtime"
	"strings"
)

// Function that is called for a view
type ViewFunc func(*http.Request, http.ResponseWriter) (error, string)

var urlMap = map[string]ViewFunc{
	"/":              views.HandleIndex,
	"/register":      views.HandleRegister,
	"/login":         views.HandleLogin,
	"/logout":        views.HandleLogout,
	"/usercp":        views.HandleUserCP,
	"/toggleencrypt": views.HandleToggleEncryption,
	"/settheme":      views.HandleSetTheme,
	"/keycheck":      views.HandleVerifyKey,
	"/getkey":        views.HandleGetKey,
	"/upload":        views.HandleUpload,
	"/paste":         views.HandlePaste,
	"/p":             views.HandlePaste,
	"/about":         views.HandleAbout,
	"/manageuploads": views.HandleManageUploads,
	"/delete":        views.HandleDelete,
}

func main() {
	runtime.GOMAXPROCS(runtime.NumCPU())
	settings.Init()
	// Start up SQL connection
	sql.Init()
	migrate.MigrateDB()

	// Create a static server for serving things in the static/ directory
	staticServer := http.FileServer(http.Dir("static"))
	// Use a static file server for /static/
	http.Handle("/static/", http.StripPrefix("/static/", staticServer))
	// Use handler for everything else
	http.HandleFunc("/", handler)

	// Start listening on port 9000 on every interface
	http.ListenAndServe(":9000", nil)
}

// handler dispatches requests to their view or serves an error
func handler(w http.ResponseWriter, r *http.Request) {
	vfunc := urlMap[strings.Split(strings.ToLower(r.URL.String()), "?")[0]]
	if vfunc == nil { // 404, no view to handle request
		vfunc = views.HandleDefault
	}
	err, responseHtml := vfunc(r, w)
	if err != nil { // 500, server dun goofed
		//TODO 500 page
		fmt.Println("500 at " + r.URL.String())
		panic(err)
	}
	fmt.Fprint(w, responseHtml) // Print the html to the response writer
}
<|endoftext|>


<commit_before>package message

import (
	"GoOnchain/common"
	"GoOnchain/common/log"
	. "GoOnchain/net/protocol"
	"bytes"
	"crypto/sha256"
	"encoding/binary"
	"encoding/hex"
	"errors"
	"fmt"
)

type Messager interface {
	Verify([]byte) error
	Serialization() ([]byte, error)
	Deserialization([]byte) error
	Handle(Noder) error
}

// The network communication message header
type msgHdr struct {
	Magic    uint32
	//ID	 uint64
	CMD      [MSGCMDLEN]byte // The message type
	Length   uint32
	Checksum [CHECKSUMLEN]byte
}

// The message body and header
type msgCont struct {
	hdr msgHdr
	p   interface{}
}

type varStr struct {
	len uint
	buf []byte
}

type filteradd struct {
	msgHdr
	//TBD
}

type filterclear struct {
	msgHdr
	//TBD
}

type filterload struct {
	msgHdr
	//TBD
}

// Alloc different message stucture
// @t the message name or type
// @len the message length only valid for varible length structure
//
// Return:
// @messager the messager interface
// @error  error code
// FixMe fix the ugly multiple return.
func AllocMsg(t string, length int) Messager {
	switch t {
	case "msgheader":
		var msg msgHdr
		return &msg
	case "version":
		var msg version
		// TODO fill the header and type
		copy(msg.Hdr.CMD[0:len(t)], t)
		return &msg
	case "verack":
		var msg verACK
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "getheaders":
		var msg headersReq
		// TODO fill the header and type
		copy(msg.hdr.CMD[0:len(t)], t)
		return &msg
	case "headers":
		var msg blkHeader
		copy(msg.hdr.CMD[0:len(t)], t)
		return &msg
	case "getaddr":
		var msg addrReq
		copy(msg.Hdr.CMD[0:len(t)], t)
		return &msg
	case "addr":
		var msg addr
		copy(msg.hdr.CMD[0:len(t)], t)
		return &msg
	case "inv":
		var msg Inv
		copy(msg.Hdr.CMD[0:len(t)], t)
		// the 1 is the inv type lenght
		msg.P.Blk = make([]byte, length-MSGHDRLEN-1)
		return &msg
	case "getdata":
		var msg dataReq
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "block":
		var msg block
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "tx":
		var msg trn
		copy(msg.msgHdr.CMD[0:len(t)], t)
		//if (message.Payload.Length <= 1024 * 1024)
		//OnInventoryReceived(Transaction.DeserializeFrom(message.Payload));
		return &msg
	case "consensus":
		var msg consensus
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "filteradd":
		var msg filteradd
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "filterclear":
		var msg filterclear
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "filterload":
		var msg filterload
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "getblocks":
		var msg blockReq
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "mempool":
		var msg memPool
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "alert":
		errors.New("Not supported message type")
		return nil
	case "merkleblock":
		errors.New("Not supported message type")
		return nil
	case "notfound":
		errors.New("Not supported message type")
		return nil
	case "ping":
		errors.New("Not supported message type")
		return nil
	case "pong":
		errors.New("Not supported message type")
		return nil
	case "reject":
		errors.New("Not supported message type")
		return nil
	default:
		errors.New("Unknown message type")
		return nil
	}
}

func MsgType(buf []byte) (string, error) {
	cmd := buf[CMDOFFSET : CMDOFFSET+MSGCMDLEN]
	n := bytes.IndexByte(cmd, 0)
	if n < 0 || n >= MSGCMDLEN {
		return "", errors.New("Unexpected length of CMD command")
	}
	s := string(cmd[:n])
	return s, nil
}

// TODO combine all of message alloc in one function via interface
func NewMsg(t string, n Noder) ([]byte, error) {
	switch t {
	case "version":
		return NewVersion(n)
	case "verack":
		return NewVerack()
	case "getheaders":
		return NewHeadersReq(n)
	case "getaddr":
		return newGetAddr()

	default:
		return nil, errors.New("Unknown message type")
	}
}

// FIXME the length exceed int32 case?
func HandleNodeMsg(node Noder, buf []byte, len int) error {
	if len < MSGHDRLEN {
		log.Warn("Unexpected size of received message")
		return errors.New("Unexpected size of received message")
	}

	str := hex.EncodeToString(buf[:len])
	log.Debug("Received data len: ", len, "\n", str)

	s, err := MsgType(buf)
	if err != nil {
		fmt.Println(err.Error())
		return err
	}

	msg := AllocMsg(s, len)
	if msg == nil {
		fmt.Println(err.Error())
		return err
	}
	// Todo attach a ndoe pointer to each message
	// Todo drop the message when verify/deseria packet error
	msg.Deserialization(buf[:len])
	msg.Verify(buf[:len])

	return msg.Handle(node)
}

func magicVerify(magic uint32) bool {
	if magic != NETMAGIC {
		return false
	}
	return true
}

func PayloadLen(buf []byte) int {
	var h msgHdr
	h.Deserialization(buf)
	return int(h.Length)
}

func checkSum(p []byte) []byte {
	t := sha256.Sum256(p)
	s := sha256.Sum256(t[:])

	// Currently we only need the front 4 bytes as checksum
	return s[:CHECKSUMLEN]
}

func reverse(input []byte) []byte {
	if len(input) == 0 {
		return input
	}
	return append(reverse(input[1:]), input[0])
}

func (hdr *msgHdr) init(cmd string, checksum []byte, length uint32) {
	hdr.Magic = NETMAGIC
	copy(hdr.CMD[0:uint32(len(cmd))], cmd)
	copy(hdr.Checksum[:], checksum[:CHECKSUMLEN])
	hdr.Length = length
	//hdr.ID = id
}

// Verify the message header information
// @p payload of the message
func (hdr msgHdr) Verify(buf []byte) error {
	if magicVerify(hdr.Magic) == false {
		log.Warn(fmt.Sprintf("Unmatched magic number 0x%0x", hdr.Magic))
		return errors.New("Unmatched magic number")
	}
	log.Debug(fmt.Sprintf("Magic number 0x%0x", hdr.Magic))
	checkSum := checkSum(buf)
	if bytes.Equal(hdr.Checksum[:], checkSum[:]) == false {
		str1 := hex.EncodeToString(hdr.Checksum[:])
		str2 := hex.EncodeToString(checkSum[:])
		log.Warn(fmt.Sprintf("Message Checksum error, Received checksum %s Wanted checksum: %s",
			str1, str2))
		return errors.New("Message Checksum error")
	}

	return nil
}

func (msg *msgHdr) Deserialization(p []byte) error {

	buf := bytes.NewBuffer(p[0:MSGHDRLEN])
	err := binary.Read(buf, binary.LittleEndian, msg)
	return err
}

// FIXME how to avoid duplicate serial/deserial function as
// most of them are the same
func (hdr msgHdr) Serialization() ([]byte, error) {
	var buf bytes.Buffer
	err := binary.Write(&buf, binary.LittleEndian, hdr)
	if err != nil {
		return nil, err
	}

	return buf.Bytes(), err
}

func (hdr msgHdr) Handle(n Noder) error {
	common.Trace()
	// TBD
	return nil
}
<commit_msg>Revert back a previous modification as it is correctly<commit_after>package message

import (
	"GoOnchain/common"
	"GoOnchain/common/log"
	. "GoOnchain/net/protocol"
	"bytes"
	"crypto/sha256"
	"encoding/binary"
	"encoding/hex"
	"errors"
	"fmt"
)

type Messager interface {
	Verify([]byte) error
	Serialization() ([]byte, error)
	Deserialization([]byte) error
	Handle(Noder) error
}

// The network communication message header
type msgHdr struct {
	Magic    uint32
	//ID	 uint64
	CMD      [MSGCMDLEN]byte // The message type
	Length   uint32
	Checksum [CHECKSUMLEN]byte
}

// The message body and header
type msgCont struct {
	hdr msgHdr
	p   interface{}
}

type varStr struct {
	len uint
	buf []byte
}

type filteradd struct {
	msgHdr
	//TBD
}

type filterclear struct {
	msgHdr
	//TBD
}

type filterload struct {
	msgHdr
	//TBD
}

// Alloc different message stucture
// @t the message name or type
// @len the message length only valid for varible length structure
//
// Return:
// @messager the messager interface
// @error  error code
// FixMe fix the ugly multiple return.
func AllocMsg(t string, length int) Messager {
	switch t {
	case "msgheader":
		var msg msgHdr
		return &msg
	case "version":
		var msg version
		// TODO fill the header and type
		copy(msg.Hdr.CMD[0:len(t)], t)
		return &msg
	case "verack":
		var msg verACK
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "getheaders":
		var msg headersReq
		// TODO fill the header and type
		copy(msg.hdr.CMD[0:len(t)], t)
		return &msg
	case "headers":
		var msg blkHeader
		copy(msg.hdr.CMD[0:len(t)], t)
		return &msg
	case "getaddr":
		var msg addrReq
		copy(msg.Hdr.CMD[0:len(t)], t)
		return &msg
	case "addr":
		var msg addr
		copy(msg.hdr.CMD[0:len(t)], t)
		return &msg
	case "inv":
		var msg Inv
		copy(msg.Hdr.CMD[0:len(t)], t)
		// the 1 is the inv type lenght
		msg.P.Blk = make([]byte, length-MSGHDRLEN-1)
		return &msg
	case "getdata":
		var msg dataReq
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "block":
		var msg block
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "tx":
		var msg trn
		copy(msg.msgHdr.CMD[0:len(t)], t)
		//if (message.Payload.Length <= 1024 * 1024)
		//OnInventoryReceived(Transaction.DeserializeFrom(message.Payload));
		return &msg
	case "consensus":
		var msg consensus
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "filteradd":
		var msg filteradd
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "filterclear":
		var msg filterclear
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "filterload":
		var msg filterload
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "getblocks":
		var msg blockReq
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "mempool":
		var msg memPool
		copy(msg.msgHdr.CMD[0:len(t)], t)
		return &msg
	case "alert":
		errors.New("Not supported message type")
		return nil
	case "merkleblock":
		errors.New("Not supported message type")
		return nil
	case "notfound":
		errors.New("Not supported message type")
		return nil
	case "ping":
		errors.New("Not supported message type")
		return nil
	case "pong":
		errors.New("Not supported message type")
		return nil
	case "reject":
		errors.New("Not supported message type")
		return nil
	default:
		errors.New("Unknown message type")
		return nil
	}
}

func MsgType(buf []byte) (string, error) {
	cmd := buf[CMDOFFSET : CMDOFFSET+MSGCMDLEN]
	n := bytes.IndexByte(cmd, 0)
	if n < 0 || n >= MSGCMDLEN {
		return "", errors.New("Unexpected length of CMD command")
	}
	s := string(cmd[:n])
	return s, nil
}

// TODO combine all of message alloc in one function via interface
func NewMsg(t string, n Noder) ([]byte, error) {
	switch t {
	case "version":
		return NewVersion(n)
	case "verack":
		return NewVerack()
	case "getheaders":
		return NewHeadersReq(n)
	case "getaddr":
		return newGetAddr()

	default:
		return nil, errors.New("Unknown message type")
	}
}

// FIXME the length exceed int32 case?
func HandleNodeMsg(node Noder, buf []byte, len int) error {
	if len < MSGHDRLEN {
		log.Warn("Unexpected size of received message")
		return errors.New("Unexpected size of received message")
	}

	str := hex.EncodeToString(buf[:len])
	log.Debug("Received data len: ", len, "\n", str)

	s, err := MsgType(buf)
	if err != nil {
		fmt.Println(err.Error())
		return err
	}

	msg := AllocMsg(s, len)
	if msg == nil {
		fmt.Println(err.Error())
		return err
	}
	// Todo attach a ndoe pointer to each message
	// Todo drop the message when verify/deseria packet error
	msg.Deserialization(buf[:len])
	msg.Verify(buf[MSGHDRLEN : len])

	return msg.Handle(node)
}

func magicVerify(magic uint32) bool {
	if magic != NETMAGIC {
		return false
	}
	return true
}

func PayloadLen(buf []byte) int {
	var h msgHdr
	h.Deserialization(buf)
	return int(h.Length)
}

func checkSum(p []byte) []byte {
	t := sha256.Sum256(p)
	s := sha256.Sum256(t[:])

	// Currently we only need the front 4 bytes as checksum
	return s[:CHECKSUMLEN]
}

func reverse(input []byte) []byte {
	if len(input) == 0 {
		return input
	}
	return append(reverse(input[1:]), input[0])
}

func (hdr *msgHdr) init(cmd string, checksum []byte, length uint32) {
	hdr.Magic = NETMAGIC
	copy(hdr.CMD[0:uint32(len(cmd))], cmd)
	copy(hdr.Checksum[:], checksum[:CHECKSUMLEN])
	hdr.Length = length
	//hdr.ID = id
}

// Verify the message header information
// @p payload of the message
func (hdr msgHdr) Verify(buf []byte) error {
	if magicVerify(hdr.Magic) == false {
		log.Warn(fmt.Sprintf("Unmatched magic number 0x%0x", hdr.Magic))
		return errors.New("Unmatched magic number")
	}
	log.Debug(fmt.Sprintf("Magic number 0x%0x", hdr.Magic))
	checkSum := checkSum(buf)
	if bytes.Equal(hdr.Checksum[:], checkSum[:]) == false {
		str1 := hex.EncodeToString(hdr.Checksum[:])
		str2 := hex.EncodeToString(checkSum[:])
		log.Warn(fmt.Sprintf("Message Checksum error, Received checksum %s Wanted checksum: %s",
			str1, str2))
		return errors.New("Message Checksum error")
	}

	return nil
}

func (msg *msgHdr) Deserialization(p []byte) error {

	buf := bytes.NewBuffer(p[0:MSGHDRLEN])
	err := binary.Read(buf, binary.LittleEndian, msg)
	return err
}

// FIXME how to avoid duplicate serial/deserial function as
// most of them are the same
func (hdr msgHdr) Serialization() ([]byte, error) {
	var buf bytes.Buffer
	err := binary.Write(&buf, binary.LittleEndian, hdr)
	if err != nil {
		return nil, err
	}

	return buf.Bytes(), err
}

func (hdr msgHdr) Handle(n Noder) error {
	common.Trace()
	// TBD
	return nil
}
<|endoftext|>


<commit_before>package mapgen

import (
	"buildblast/lib/coords"
)

type FlatWorld struct {}

// Take seed to be consistent with all the other world types
func NewFlatWorld(seed float64) *FlatWorld {
	_ = seed
	return new(FlatWorld)
}

func (fw *FlatWorld) Block(bc coords.Block) (Block, bool) {
	if bc.X == 0 && bc.Y == 16 && bc.Z == 0 {
		return BLOCK_AIR, true
	}
	if bc.Y < 16 {
		return BLOCK_DIRT, false
	}
	return BLOCK_AIR, false
}

func (fw *FlatWorld) Chunk(cc coords.Chunk) (Chunk, []coords.World) {
	return generateChunk(fw, cc)
}
<commit_msg>Give you something to orient yourself by.<commit_after>package mapgen

import (
	"buildblast/lib/coords"
)

type FlatWorld struct {}

// Take seed to be consistent with all the other world types
func NewFlatWorld(seed float64) *FlatWorld {
	_ = seed
	return new(FlatWorld)
}

func (fw *FlatWorld) Block(bc coords.Block) (Block, bool) {
	if bc.X == 0 && bc.Y == 16 && bc.Z == 0 {
		return BLOCK_AIR, true
	}
	if bc.Y < 16 {
		return BLOCK_DIRT, false
	}
	if bc.X % 4 == 0 && bc.Z % 4 == 0 && bc.Y < 17 {
		return BLOCK_STONE, false
	}
	return BLOCK_AIR, false
}

func (fw *FlatWorld) Chunk(cc coords.Chunk) (Chunk, []coords.World) {
	return generateChunk(fw, cc)
}
<|endoftext|>


<commit_before><commit_msg>[]interface{} Types<commit_after><|endoftext|>


<commit_before>// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package lxdclient

import (
	"crypto/x509"

	"github.com/juju/errors"
	"github.com/lxc/lxd"
	"github.com/lxc/lxd/shared"
)

type rawClientServerMethods interface {
	WaitForSuccess(waitURL string) error

	SetServerConfig(key string, value string) (*lxd.Response, error)

	CertificateList() ([]shared.CertInfo, error)
	CertificateAdd(cert *x509.Certificate, name string) error
	CertificateRemove(fingerprint string) error
}

type clientServerMethods struct {
	raw rawServerMethods
}

func (c clientServerMethods) setUpRemote(cert *x509.Certificate, name string) error {
	resp, err := c.raw.SetServerConfig("core.https_address", "[::]")
	if err != nil {
		return errors.Trace(err)
	}
	if resp.Operation != "" {
		if err := c.raw.WaitForSuccess(resp.Operation); err != nil {
			// TODO(ericsnow) Handle different failures (from the async
			// operation) differently?
			return errors.Trace(err)
		}
	}

	if err := c.raw.CertificateAdd(cert, name); err != nil {
		return errors.Trace(err)
	}

	return nil
}

// ListCerts returns the list of cert fingerprints from the server.
func (c clientServerMethods) ListCerts() ([]string, error) {
	certs, err := c.raw.CertificateList()
	if err != nil {
		return nil, errors.Trace(err)
	}

	var fingerprints []string
	for _, cert := range certs {
		fingerprints = append(fingerprints, cert.Fingerprint)
	}
	return fingerprints, nil
}

// RemoveCert removes the cert from the server.
func (c clientServerMethods) RemoveCert(cert *Cert) error {
	fingerprint, err := cert.Fingerprint()
	if err != nil {
		return errors.Trace(err)
	}

	if err := c.raw.CertificateRemove(fingerprint); err != nil {
		return errors.Trace(err)
	}
	return nil
}

// RemoveCertByFingerprint removes the cert from the server.
func (c clientServerMethods) RemoveCertByFingerprint(fingerprint string) error {
	if err := c.raw.CertificateRemove(fingerprint); err != nil {
		return errors.Trace(err)
	}
	return nil
}
<commit_msg>Add a doc comment to clientServerMethods.<commit_after>// Copyright 2015 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.

package lxdclient

import (
	"crypto/x509"

	"github.com/juju/errors"
	"github.com/lxc/lxd"
	"github.com/lxc/lxd/shared"
)

type rawClientServerMethods interface {
	WaitForSuccess(waitURL string) error

	SetServerConfig(key string, value string) (*lxd.Response, error)

	CertificateList() ([]shared.CertInfo, error)
	CertificateAdd(cert *x509.Certificate, name string) error
	CertificateRemove(fingerprint string) error
}

// clientServerMethods implements the Client methods related
// to server operations.
type clientServerMethods struct {
	raw rawServerMethods
}

func (c clientServerMethods) setUpRemote(cert *x509.Certificate, name string) error {
	resp, err := c.raw.SetServerConfig("core.https_address", "[::]")
	if err != nil {
		return errors.Trace(err)
	}
	if resp.Operation != "" {
		if err := c.raw.WaitForSuccess(resp.Operation); err != nil {
			// TODO(ericsnow) Handle different failures (from the async
			// operation) differently?
			return errors.Trace(err)
		}
	}

	if err := c.raw.CertificateAdd(cert, name); err != nil {
		return errors.Trace(err)
	}

	return nil
}

// ListCerts returns the list of cert fingerprints from the server.
func (c clientServerMethods) ListCerts() ([]string, error) {
	certs, err := c.raw.CertificateList()
	if err != nil {
		return nil, errors.Trace(err)
	}

	var fingerprints []string
	for _, cert := range certs {
		fingerprints = append(fingerprints, cert.Fingerprint)
	}
	return fingerprints, nil
}

// RemoveCert removes the cert from the server.
func (c clientServerMethods) RemoveCert(cert *Cert) error {
	fingerprint, err := cert.Fingerprint()
	if err != nil {
		return errors.Trace(err)
	}

	if err := c.raw.CertificateRemove(fingerprint); err != nil {
		return errors.Trace(err)
	}
	return nil
}

// RemoveCertByFingerprint removes the cert from the server.
func (c clientServerMethods) RemoveCertByFingerprint(fingerprint string) error {
	if err := c.raw.CertificateRemove(fingerprint); err != nil {
		return errors.Trace(err)
	}
	return nil
}
<|endoftext|>


<commit_before>package filesystem

import (
	"bytes"
	"fmt"
	logger "github.com/Sirupsen/logrus"
	"github.com/abates/bms/database"
	"github.com/lunixbochs/struc"
	"io"
	"os"
	"path"
	"time"
)

var (
	ErrIsFolder  = fmt.Errorf("Asset is a folder")
	ErrNotFolder = fmt.Errorf("Asset is not a folder")
)

type FolderEntry struct {
	ID       database.ID `struc:"[16]byte"`
	NameLen  int         `struc:"uint16,sizeof=Name"`
	Name     string
	IsFolder bool
}

func NewFolderEntry(id database.ID, name string, isFolder bool) *FolderEntry {
	return &FolderEntry{
		ID:       id,
		NameLen:  len(name),
		Name:     name,
		IsFolder: isFolder,
	}
}

func (fe *FolderEntry) Asset() (asset Asset, err error) {
	if fe.IsFolder {
		asset = &Folder{}
		err = Db.Find(fe.ID, asset.(*Folder))
	} else {
		asset = &File{}
		err = Db.Find(fe.ID, asset.(*File))
	}
	return asset, err
}

func (fe *FolderEntry) Remove() (err error) {
	asset, _ := fe.Asset()
	switch file := asset.(type) {
	case *Folder:
		file.RemoveAll()
	case *File:
		BackendFs.Remove(file.RealPath())
	}

	if err == nil {
		err = Db.Delete(fe.ID)
	}
	return
}

func (fe *FolderEntry) SetName(name string) {
	fe.NameLen = len(name)
	fe.Name = name
}

type Folder struct {
	metadata *Metadata
	entries  map[string]*FolderEntry
}

func NewFolder(name string, perm os.FileMode) *Folder {
	return &Folder{
		metadata: NewMetadata(name, os.ModeDir|perm),
		entries:  make(map[string]*FolderEntry),
	}
}

func (folder *Folder) addAsset(asset Asset) error {
	if _, found := folder.entries[asset.Name()]; found {
		return os.ErrExist
	}

	switch file := asset.(type) {
	case *Folder:
		folder.entries[asset.Name()] = NewFolderEntry(file.ID(), asset.Name(), true)
	case *File:
		folder.entries[asset.Name()] = NewFolderEntry(file.ID(), asset.Name(), false)
	default:
		logger.Warnf("Unknown asset type %T", asset)
	}

	folder.metadata.ModTime = time.Now().Unix()
	Db.Save(folder.ID(), folder)
	return nil
}

func (folder *Folder) Close() error {
	return nil
}

func (folder *Folder) Find(name []string) (Asset, error) {
	if folder == nil {
		return nil, os.ErrNotExist
	}

	if len(name) == 0 {
		return folder, nil
	}

	if entry, found := folder.entries[name[0]]; found {
		asset, _ := entry.Asset()
		if asset == nil {
			logger.Warnf("Folder entry %s/%s points to non-existant folder %s", folder.Name(), name[0], entry.ID)
		} else if folder, ok := asset.(*Folder); ok {
			return folder.Find(name[1:])
		} else if len(name) == 1 {
			return asset, nil
		}
	}
	return nil, os.ErrNotExist
}

func (folder *Folder) ID() database.ID { return folder.metadata.ID }

func (folder *Folder) MarshalBinary() ([]byte, error) {
	buffer := &bytes.Buffer{}
	err := folder.metadata.Pack(buffer)
	if err == nil {
		for _, entry := range folder.entries {
			err = struc.Pack(buffer, entry)
			if err != nil {
				break
			}
		}
	}
	return buffer.Bytes(), err
}

func (folder *Folder) Mkfolder(name string, perm os.FileMode) (newFolder *Folder, err error) {
	newFolder = NewFolder(name, perm)
	err = folder.addAsset(newFolder)
	err = Db.Save(newFolder.ID(), newFolder)
	return
}

func (folder *Folder) Mode() os.FileMode  { return folder.metadata.Mode }
func (folder *Folder) ModTime() time.Time { return time.Unix(folder.metadata.ModTime, 0) }

func (folder *Folder) Move(name string, newFolder *Folder) (err error) {
	if entry, found := folder.entries[name]; found {
		delete(folder.entries, name)
		newFolder.entries[name] = entry
		Db.Save(folder.ID(), folder)
		Db.Save(newFolder.ID(), newFolder)
	} else {
		err = os.ErrNotExist
	}
	return err
}

func (folder *Folder) Name() string       { return folder.metadata.Name }
func (folder *Folder) Owner() database.ID { return folder.metadata.Owner }

func (folder *Folder) Readdir(count int) ([]os.FileInfo, error) {
	entries := make([]os.FileInfo, 0)
	for name, entry := range folder.entries {
		asset, err := entry.Asset()
		if err != nil {
			return entries, err
		}
		if asset == nil {
			logger.Warnf("Folder entry %s/%s points to non-existant folder %s", folder.Name(), name, entry.ID)
		} else if fi, err := asset.Stat(); err == nil {
			entries = append(entries, fi)
		} else {
			logger.WithFields(map[string]interface{}{
				"parent": folder.Name(),
				"child":  name,
				"error":  err,
			}).Warn("Readdir failed to stat %s/%s", folder.Name(), name)
		}
	}
	return entries, nil
}

func (folder *Folder) Read([]byte) (int, error) { return 0, ErrIsFolder }

func (folder *Folder) Remove(name string) error {
	err := os.ErrNotExist
	if entry, found := folder.entries[name]; found {
		err = entry.Remove()
		if err == nil {
			delete(folder.entries, name)
			Db.Save(folder.ID(), folder)
		}
	}
	return err
}

func (folder *Folder) RemoveAll() (err error) {
	for _, entry := range folder.entries {
		err1 := entry.Remove()
		if err == nil {
			err = err1
		}
	}
	return
}

func (folder *Folder) Rename(oldName, newName string) error {
	err := os.ErrNotExist
	if entry, found := folder.entries[oldName]; found {
		asset, _ := entry.Asset()
		if asset != nil {
			err = asset.SetName(newName)
		}

		if err == nil {
			entry.SetName(newName)
			delete(folder.entries, oldName)
			folder.entries[newName] = entry
			Db.Save(folder.ID(), folder)
		}
	}
	return err
}

func (folder *Folder) UnmarshalBinary(data []byte) error {
	folder.metadata = &Metadata{}
	buffer := bytes.NewBuffer(data)
	err := folder.metadata.Unpack(buffer)
	folder.entries = make(map[string]*FolderEntry)
	for err == nil {
		entry := &FolderEntry{}
		err = struc.Unpack(buffer, entry)
		if err == nil {
			folder.entries[entry.Name] = entry
		}
	}

	if err == io.EOF {
		err = nil
	}
	return err
}

func (folder *Folder) Seek(int64, int) (int64, error)   { return 0, ErrIsFolder }
func (folder *Folder) SetName(name string) error        { folder.metadata.SetName(name); return nil }
func (folder *Folder) SetOwner(owner database.ID) error { folder.metadata.Owner = owner; return nil }

func (folder *Folder) Stat() (os.FileInfo, error) {
	return NewFolderInfo(folder)
}

func (folder *Folder) Write([]byte) (int, error) { return 0, ErrIsFolder }

type FolderInfo struct {
	folder *Folder
}

func NewFolderInfo(folder *Folder) (*FolderInfo, error) {
	return &FolderInfo{folder}, nil
}

func (fi *FolderInfo) Mode() os.FileMode  { return fi.folder.Mode() }
func (fi *FolderInfo) ModTime() time.Time { return fi.folder.ModTime() }
func (fi *FolderInfo) Name() string       { return fi.folder.Name() }
func (fi *FolderInfo) Size() int64        { return 0 }
func (fi *FolderInfo) Sys() interface{}   { return nil }

func (fi *FolderInfo) IsDir() bool { return true }

type FolderFileSystem struct {
	userid database.ID
	root   *Folder
}

func NewFolderFileSystem(root *Folder, userid database.ID) *FolderFileSystem {
	return &FolderFileSystem{
		userid: userid,
		root:   root,
	}
}

func cleanPath(name string) (string, string) {
	name = path.Clean(name)
	return path.Dir(name), path.Base(name)
}

func (fs *FolderFileSystem) Mkdir(name string, perm os.FileMode) error {
	dirname, filename := cleanPath(name)
	if name == "/" {
		return os.ErrExist
	}

	asset, err := fs.root.Find(splitPath(dirname))
	if parent, ok := asset.(*Folder); ok {
		var newFolder *Folder
		newFolder, err = parent.Mkfolder(filename, perm)
		if err == nil {
			err = newFolder.SetOwner(fs.userid)
		}
	}
	return err
}

func validatePermissions(asset Asset, perm os.FileMode) error {
	return nil
}

func flagString(flag int) string {
	s := ""

	for name, i := range map[string]int{
		"RDONLY": os.O_RDONLY,
		"WRONLY": os.O_WRONLY,
		"RDWR":   os.O_RDWR,
		"APPEND": os.O_APPEND,
		"CREATE": os.O_CREATE,
		"EXCL":   os.O_EXCL,
		"SYNC":   os.O_SYNC,
		"TRUNC":  os.O_TRUNC} {
		if flag&i > 0 {
			if s != "" {
				s += "|"
			}
			s += name
		}
	}
	return s
}

func hasFlags(flag, search int) bool {
	return flag&search > 0
}

func (fs *FolderFileSystem) OpenFile(name string, flag int, perm os.FileMode) (asset Asset, err error) {
	dirname, filename := cleanPath(name)

	if name == "/" {
		if hasFlags(flag, os.O_WRONLY|os.O_RDWR|os.O_APPEND|os.O_CREATE|os.O_TRUNC) {
			return nil, &os.PathError{"open", name, ErrIsFolder}
		}
		return fs.root, nil
	}

	asset, err = fs.root.Find(splitPath(dirname))

	var base *Folder
	if folder, ok := asset.(*Folder); ok {
		base = folder
	} else {
		return nil, &os.PathError{"open", dirname, ErrNotFolder}
	}

	asset, err = base.Find([]string{filename})
	if os.IsNotExist(err) {
		if hasFlags(flag, os.O_CREATE) {
			err = nil
			file := NewFile(BackendFs, filename, perm)
			err = BackendFs.MkdirAll(path.Dir(file.RealPath()), 0700)
			if err == nil {
				asset = file
				err = base.addAsset(file)
				if err == nil {
					Db.Save(file.ID(), file)
				}
			}
		}
	}

	switch file := asset.(type) {
	case *Folder:
		if hasFlags(flag, os.O_WRONLY|os.O_RDWR|os.O_APPEND|os.O_CREATE|os.O_TRUNC) {
			return nil, &os.PathError{"open", name, ErrIsFolder}
		}
	case *File:
		file.File, err = BackendFs.OpenFile(file.RealPath(), flag, 0600)
	}
	return asset, err
}

func (fs *FolderFileSystem) RemoveAll(name string) error {
	dirname, filename := cleanPath(name)
	asset, err := fs.root.Find(splitPath(dirname))
	if err == nil {
		switch file := asset.(type) {
		case *Folder:
			err = file.Remove(filename)
		case *File:
			err = &os.PathError{"removeall", dirname, ErrNotFolder}
		}
	}
	return err
}

func (fs *FolderFileSystem) Rename(oldName, newName string) (err error) {
	oldDirname, oldFilename := cleanPath(oldName)
	newDirname, newFilename := cleanPath(newName)

	asset, err := fs.root.Find(splitPath(oldDirname))
	if err != nil {
		return
	}

	if oldDir, ok := asset.(*Folder); ok {
		if oldName != newName {
			err = oldDir.Rename(oldFilename, newFilename)
		}

		if err == nil && oldDirname != newDirname {
			asset, err = fs.root.Find(splitPath(newDirname))
			if err != nil {
				return err
			}

			if newDir, ok := asset.(*Folder); ok {
				err = oldDir.Move(newFilename, newDir)
			} else {
				err = &os.PathError{"rename", newDirname, ErrNotFolder}
			}
		}
	} else {
		err = &os.PathError{"rename", newDirname, ErrNotFolder}
	}
	return
}

func (fs *FolderFileSystem) Stat(name string) (os.FileInfo, error) {
	asset, err := fs.root.Find(splitPath(name))
	if err == nil {
		return asset.Stat()
	}

	return nil, err
}
<commit_msg>Refactoring<commit_after><|endoftext|>


<commit_before>package rss

import (
	"bytes"
	"encoding/xml"
	"fmt"
	"time"
)

func parseAtom(data []byte, read *db) (*Feed, error) {
	warnings := false
	feed := atomFeed{}
	p := xml.NewDecoder(bytes.NewReader(data))
	p.CharsetReader = charsetReader
	err := p.Decode(&feed)
	if err != nil {
		return nil, err
	}

	out := new(Feed)
	out.Title = feed.Title
	out.Description = feed.Description
	out.Link = feed.Link.Href
	out.Image = feed.Image.Image()
	out.Refresh = time.Now().Add(10 * time.Minute)

	if feed.Items == nil {
		return nil, fmt.Errorf("Error: no feeds found in %q.", string(data))
	}

	out.Items = make([]*Item, 0, len(feed.Items))
	out.ItemMap = make(map[string]struct{})

	// Process items.
	for _, item := range feed.Items {

		// Skip items already known.
		if read.req <- item.ID; <-read.res {
			continue
		}

		next := new(Item)
		next.Title = item.Title
		next.Summary = item.Summary
		next.Content = item.Content
		if item.Date != "" {
			next.Date, err = parseTime(item.Date)
			if err != nil {
				return nil, err
			}
		}
		next.ID = item.ID
		for _, link := range item.Links {
			if link.Rel == "" {
				next.Link = link.Href
			} else {
				next.Enclosures = append(next.Enclosures, &Enclosure{
					Url:    link.Href,
					Type:   link.Type,
					Rel:    link.Rel,
					Length: link.Length,
				})
			}
		}
		next.Read = false

		if next.ID == "" {
			if debug {
				fmt.Printf("[w] Item %q has no ID and will be ignored.\n", next.Title)
				fmt.Printf("[w] %#v\n", item)
			}
			warnings = true
			continue
		}

		if _, ok := out.ItemMap[next.ID]; ok {
			if debug {
				fmt.Printf("[w] Item %q has duplicate ID.\n", next.Title)
				fmt.Printf("[w] %#v\n", next)
			}
			warnings = true
			continue
		}

		out.Items = append(out.Items, next)
		out.ItemMap[next.ID] = struct{}{}
		out.Unread++
	}

	if warnings && debug {
		fmt.Printf("[i] Encountered warnings:\n%s\n", data)
	}

	return out, nil
}

type atomFeed struct {
	XMLName     xml.Name   `xml:"feed"`
	Title       string     `xml:"title"`
	Description string     `xml:"subtitle"`
	Link        atomLink   `xml:"link"`
	Image       atomImage  `xml:"image"`
	Items       []atomItem `xml:"entry"`
	Updated     string     `xml:"updated"`
}

type atomItem struct {
	XMLName xml.Name   `xml:"entry"`
	Title   string     `xml:"title"`
	Summary string     `xml:"summary"`
	Content string     `xml:"content"`
	Links   []atomLink `xml:"link"`
	Date    string     `xml:"updated"`
	ID      string     `xml:"id"`
}

type atomImage struct {
	XMLName xml.Name `xml:"image"`
	Title   string   `xml:"title"`
	Url     string   `xml:"url"`
	Height  int      `xml:"height"`
	Width   int      `xml:"width"`
}

type atomLink struct {
	Href   string `xml:"href,attr"`
	Rel    string `xml:"rel,attr"`
	Type   string `xml:"type,attr"`
	Length int    `xml:"length,attr"`
}

func (a *atomImage) Image() *Image {
	out := new(Image)
	out.Title = a.Title
	out.Url = a.Url
	out.Height = uint32(a.Height)
	out.Width = uint32(a.Width)
	return out
}
<commit_msg>Switched to using published for date of atom posts<commit_after>package rss

import (
	"bytes"
	"encoding/xml"
	"fmt"
	"time"
)

func parseAtom(data []byte, read *db) (*Feed, error) {
	warnings := false
	feed := atomFeed{}
	p := xml.NewDecoder(bytes.NewReader(data))
	p.CharsetReader = charsetReader
	err := p.Decode(&feed)
	if err != nil {
		return nil, err
	}

	out := new(Feed)
	out.Title = feed.Title
	out.Description = feed.Description
	out.Link = feed.Link.Href
	out.Image = feed.Image.Image()
	out.Refresh = time.Now().Add(10 * time.Minute)

	if feed.Items == nil {
		return nil, fmt.Errorf("Error: no feeds found in %q.", string(data))
	}

	out.Items = make([]*Item, 0, len(feed.Items))
	out.ItemMap = make(map[string]struct{})

	// Process items.
	for _, item := range feed.Items {

		// Skip items already known.
		if read.req <- item.ID; <-read.res {
			continue
		}

		next := new(Item)
		next.Title = item.Title
		next.Summary = item.Summary
		next.Content = item.Content
		if item.Date != "" {
			next.Date, err = parseTime(item.Date)
			if err != nil {
				return nil, err
			}
		}
		next.ID = item.ID
		for _, link := range item.Links {
			if link.Rel == "" {
				next.Link = link.Href
			} else {
				next.Enclosures = append(next.Enclosures, &Enclosure{
					Url:    link.Href,
					Type:   link.Type,
					Rel:    link.Rel,
					Length: link.Length,
				})
			}
		}
		next.Read = false

		if next.ID == "" {
			if debug {
				fmt.Printf("[w] Item %q has no ID and will be ignored.\n", next.Title)
				fmt.Printf("[w] %#v\n", item)
			}
			warnings = true
			continue
		}

		if _, ok := out.ItemMap[next.ID]; ok {
			if debug {
				fmt.Printf("[w] Item %q has duplicate ID.\n", next.Title)
				fmt.Printf("[w] %#v\n", next)
			}
			warnings = true
			continue
		}

		out.Items = append(out.Items, next)
		out.ItemMap[next.ID] = struct{}{}
		out.Unread++
	}

	if warnings && debug {
		fmt.Printf("[i] Encountered warnings:\n%s\n", data)
	}

	return out, nil
}

type atomFeed struct {
	XMLName     xml.Name   `xml:"feed"`
	Title       string     `xml:"title"`
	Description string     `xml:"subtitle"`
	Link        atomLink   `xml:"link"`
	Image       atomImage  `xml:"image"`
	Items       []atomItem `xml:"entry"`
	Updated     string     `xml:"updated"`
}

type atomItem struct {
	XMLName xml.Name   `xml:"entry"`
	Title   string     `xml:"title"`
	Summary string     `xml:"summary"`
	Content string     `xml:"content"`
	Links   []atomLink `xml:"link"`
	Date    string     `xml:"published"`
	ID      string     `xml:"id"`
}

type atomImage struct {
	XMLName xml.Name `xml:"image"`
	Title   string   `xml:"title"`
	Url     string   `xml:"url"`
	Height  int      `xml:"height"`
	Width   int      `xml:"width"`
}

type atomLink struct {
	Href   string `xml:"href,attr"`
	Rel    string `xml:"rel,attr"`
	Type   string `xml:"type,attr"`
	Length int    `xml:"length,attr"`
}

func (a *atomImage) Image() *Image {
	out := new(Image)
	out.Title = a.Title
	out.Url = a.Url
	out.Height = uint32(a.Height)
	out.Width = uint32(a.Width)
	return out
}
<|endoftext|>


<commit_before>package rects

import (
	"github.com/hajimehoshi/go-ebiten"
	"github.com/hajimehoshi/go-ebiten/graphics"
	"github.com/hajimehoshi/go-ebiten/graphics/matrix"
	"image/color"
	"math"
	"math/rand"
	"time"
)

type Rects struct {
	rectTexture       graphics.RenderTarget
	rectTextureInited bool
	offscreen         graphics.RenderTarget
	offscreenInited   bool
	rectBounds        *graphics.Rect
	rectColor         *color.RGBA
}

func New() *Rects {
	return &Rects{
		rectTextureInited: false,
		offscreenInited:   false,
		rectBounds:        &graphics.Rect{},
		rectColor:         &color.RGBA{},
	}
}

func (game *Rects) Init(tf graphics.TextureFactory) {
	game.rectTexture = tf.NewRenderTarget(16, 16)
	game.offscreen = tf.NewRenderTarget(256, 240)
}

func (game *Rects) Update(context ebiten.GameContext) {
	game.rectBounds.X = rand.Intn(context.ScreenWidth())
	game.rectBounds.Y = rand.Intn(context.ScreenHeight())
	game.rectBounds.Width =
		rand.Intn(context.ScreenWidth() - game.rectBounds.X)
	game.rectBounds.Height =
		rand.Intn(context.ScreenHeight() - game.rectBounds.Y)

	game.rectColor.R = uint8(rand.Intn(256))
	game.rectColor.G = uint8(rand.Intn(256))
	game.rectColor.B = uint8(rand.Intn(256))
	game.rectColor.A = uint8(rand.Intn(256))
}

func (game *Rects) rectGeometryMatrix() matrix.Geometry {
	geometryMatrix := matrix.IdentityGeometry()
	scaleX := float64(game.rectBounds.Width) /
		float64(game.rectTexture.Width())
	scaleY := float64(game.rectBounds.Height) /
		float64(game.rectTexture.Height())
	geometryMatrix.Scale(scaleX, scaleY)
	geometryMatrix.Translate(
		float64(game.rectBounds.X), float64(game.rectBounds.Y))
	return geometryMatrix
}

func (game *Rects) rectColorMatrix() matrix.Color {
	colorMatrix := matrix.IdentityColor()
	colorMatrix.Elements[0][0] =
		float64(game.rectColor.R) / float64(math.MaxUint8)
	colorMatrix.Elements[1][1] =
		float64(game.rectColor.G) / float64(math.MaxUint8)
	colorMatrix.Elements[2][2] =
		float64(game.rectColor.B) / float64(math.MaxUint8)
	colorMatrix.Elements[3][3] =
		float64(game.rectColor.A) / float64(math.MaxUint8)
	return colorMatrix
}

func (game *Rects) Draw(g graphics.Context) {
	if !game.rectTextureInited {
		g.SetOffscreen(game.rectTexture.ID())
		g.Fill(255, 255, 255)
		game.rectTextureInited = true
	}

	g.SetOffscreen(game.offscreen.ID())
	if !game.offscreenInited {
		g.Fill(0, 0, 0)
		game.offscreenInited = true
	}
	g.DrawTexture(game.rectTexture.Texture().ID(),
		game.rectGeometryMatrix(),
		game.rectColorMatrix())

	g.SetOffscreen(g.Screen().ID())
	g.DrawTexture(game.offscreen.Texture().ID(),
		matrix.IdentityGeometry(),
		matrix.IdentityColor())
}

func init() {
	rand.Seed(time.Now().UnixNano())
}
<commit_msg>Replace Screen/ResetOffscreen<commit_after>package rects

import (
	"github.com/hajimehoshi/go-ebiten"
	"github.com/hajimehoshi/go-ebiten/graphics"
	"github.com/hajimehoshi/go-ebiten/graphics/matrix"
	"image/color"
	"math"
	"math/rand"
	"time"
)

type Rects struct {
	rectTexture       graphics.RenderTarget
	rectTextureInited bool
	offscreen         graphics.RenderTarget
	offscreenInited   bool
	rectBounds        *graphics.Rect
	rectColor         *color.RGBA
}

func New() *Rects {
	return &Rects{
		rectTextureInited: false,
		offscreenInited:   false,
		rectBounds:        &graphics.Rect{},
		rectColor:         &color.RGBA{},
	}
}

func (game *Rects) Init(tf graphics.TextureFactory) {
	game.rectTexture = tf.NewRenderTarget(16, 16)
	game.offscreen = tf.NewRenderTarget(256, 240)
}

func (game *Rects) Update(context ebiten.GameContext) {
	game.rectBounds.X = rand.Intn(context.ScreenWidth())
	game.rectBounds.Y = rand.Intn(context.ScreenHeight())
	game.rectBounds.Width =
		rand.Intn(context.ScreenWidth() - game.rectBounds.X)
	game.rectBounds.Height =
		rand.Intn(context.ScreenHeight() - game.rectBounds.Y)

	game.rectColor.R = uint8(rand.Intn(256))
	game.rectColor.G = uint8(rand.Intn(256))
	game.rectColor.B = uint8(rand.Intn(256))
	game.rectColor.A = uint8(rand.Intn(256))
}

func (game *Rects) rectGeometryMatrix() matrix.Geometry {
	geometryMatrix := matrix.IdentityGeometry()
	scaleX := float64(game.rectBounds.Width) /
		float64(game.rectTexture.Width())
	scaleY := float64(game.rectBounds.Height) /
		float64(game.rectTexture.Height())
	geometryMatrix.Scale(scaleX, scaleY)
	geometryMatrix.Translate(
		float64(game.rectBounds.X), float64(game.rectBounds.Y))
	return geometryMatrix
}

func (game *Rects) rectColorMatrix() matrix.Color {
	colorMatrix := matrix.IdentityColor()
	colorMatrix.Elements[0][0] =
		float64(game.rectColor.R) / float64(math.MaxUint8)
	colorMatrix.Elements[1][1] =
		float64(game.rectColor.G) / float64(math.MaxUint8)
	colorMatrix.Elements[2][2] =
		float64(game.rectColor.B) / float64(math.MaxUint8)
	colorMatrix.Elements[3][3] =
		float64(game.rectColor.A) / float64(math.MaxUint8)
	return colorMatrix
}

func (game *Rects) Draw(g graphics.Context) {
	if !game.rectTextureInited {
		g.SetOffscreen(game.rectTexture.ID())
		g.Fill(255, 255, 255)
		game.rectTextureInited = true
	}

	g.SetOffscreen(game.offscreen.ID())
	if !game.offscreenInited {
		g.Fill(0, 0, 0)
		game.offscreenInited = true
	}
	g.DrawTexture(game.rectTexture.Texture().ID(),
		game.rectGeometryMatrix(),
		game.rectColorMatrix())

	g.ResetOffscreen()
	g.DrawTexture(game.offscreen.Texture().ID(),
		matrix.IdentityGeometry(),
		matrix.IdentityColor())
}

func init() {
	rand.Seed(time.Now().UnixNano())
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"sort"
	"strings"
	"time"

	"github.com/spf13/pflag"
	"golang.org/x/sync/errgroup"
)

var opts = struct {
	Verbose   bool
	SourceDir string
	OutputDir string
}{}

func init() {
	pflag.BoolVarP(&opts.Verbose, "verbose", "v", false, "be verbose")
	pflag.StringVarP(&opts.SourceDir, "source", "s", "/restic", "path to the source code `directory`")
	pflag.StringVarP(&opts.OutputDir, "output", "o", "/output", "path to the output `directory`")
	pflag.Parse()
}

func die(f string, args ...interface{}) {
	if !strings.HasSuffix(f, "\n") {
		f += "\n"
	}
	f = "\x1b[31m" + f + "\x1b[0m"
	fmt.Fprintf(os.Stderr, f, args...)
	os.Exit(1)
}

func msg(f string, args ...interface{}) {
	if !strings.HasSuffix(f, "\n") {
		f += "\n"
	}
	f = "\x1b[32m" + f + "\x1b[0m"
	fmt.Printf(f, args...)
}

func verbose(f string, args ...interface{}) {
	if !opts.Verbose {
		return
	}
	if !strings.HasSuffix(f, "\n") {
		f += "\n"
	}
	f = "\x1b[32m" + f + "\x1b[0m"
	fmt.Printf(f, args...)
}

func run(cmd string, args ...string) {
	c := exec.Command(cmd, args...)
	c.Stdout = os.Stdout
	c.Stderr = os.Stderr
	err := c.Run()
	if err != nil {
		die("error running %s %s: %v", cmd, args, err)
	}
}

func rm(file string) {
	err := os.Remove(file)

	if os.IsNotExist(err) {
		err = nil
	}

	if err != nil {
		die("error removing %v: %v", file, err)
	}
}

func rmdir(dir string) {
	err := os.RemoveAll(dir)
	if err != nil {
		die("error removing %v: %v", dir, err)
	}
}

func mkdir(dir string) {
	err := os.MkdirAll(dir, 0755)
	if err != nil {
		die("mkdir %v: %v", dir, err)
	}
}

func getwd() string {
	pwd, err := os.Getwd()
	if err != nil {
		die("Getwd(): %v", err)
	}
	return pwd
}

func abs(dir string) string {
	absDir, err := filepath.Abs(dir)
	if err != nil {
		die("unable to find absolute path for %v: %v", dir, err)
	}
	return absDir
}

func build(sourceDir, outputDir, goos, goarch string) (filename string) {
	filename = fmt.Sprintf("%v_%v_%v", "restic", goos, goarch)
	if goos == "windows" {
		filename += ".exe"
	}
	outputFile := filepath.Join(outputDir, filename)

	c := exec.Command("go", "build",
		"-mod=vendor",
		"-o", outputFile,
		"-ldflags", "-s -w",
		"-tags", "selfupdate",
		"./cmd/restic",
	)
	c.Stdout = os.Stdout
	c.Stderr = os.Stderr
	c.Dir = sourceDir

	verbose("run %v %v in %v", "go", c.Args, c.Dir)

	c.Dir = sourceDir
	c.Env = append(os.Environ(),
		"CGO_ENABLED=0",
		"GOPROXY=off",
		"GOOS="+goos,
		"GOARCH="+goarch,
	)

	err := c.Run()
	if err != nil {
		die("error building %v/%v: %v", goos, goarch, err)
	}

	return filename
}

func modTime(file string) time.Time {
	fi, err := os.Lstat(file)
	if err != nil {
		die("unable to get modtime of %v: %v", file, err)
	}

	return fi.ModTime()
}

func touch(file string, t time.Time) {
	err := os.Chtimes(file, t, t)
	if err != nil {
		die("unable to update timestamps for %v: %v", file, err)
	}
}

func chmod(file string, mode os.FileMode) {
	err := os.Chmod(file, mode)
	if err != nil {
		die("unable to chmod %v to %s: %v", file, mode, err)
	}
}

func compress(goos, inputDir, filename string) (outputFile string) {
	var c *exec.Cmd
	switch goos {
	case "windows":
		outputFile = strings.TrimSuffix(filename, ".exe") + ".zip"
		c = exec.Command("zip", "-q", "-X", outputFile, filename)
		c.Dir = inputDir
	default:
		outputFile = filename + ".bz2"
		c = exec.Command("bzip2", filename)
		c.Dir = inputDir
	}

	rm(filepath.Join(inputDir, outputFile))

	c.Stdout = os.Stdout
	c.Stderr = os.Stderr
	c.Dir = inputDir

	verbose("run %v %v in %v", "go", c.Args, c.Dir)

	err := c.Run()
	if err != nil {
		die("error compressing: %v", err)
	}

	rm(filepath.Join(inputDir, filename))

	return outputFile
}

func buildForTarget(sourceDir, outputDir, goos, goarch string) (filename string) {
	mtime := modTime(filepath.Join(sourceDir, "VERSION"))

	filename = build(sourceDir, outputDir, goos, goarch)
	touch(filepath.Join(outputDir, filename), mtime)
	chmod(filepath.Join(outputDir, filename), 0755)
	filename = compress(goos, outputDir, filename)
	return filename
}

func sha256sums(outputFile, inputDir string, filenames []string) {
	verbose("runnnig sha256sum in %v", inputDir)
	f, err := os.Create(outputFile)
	if err != nil {
		die("unable to create %v: %v", outputFile, err)
	}

	c := exec.Command("sha256sum", filenames...)
	c.Stdout = f
	c.Stderr = os.Stderr
	c.Dir = inputDir

	err = c.Run()
	if err != nil {
		die("error running sha256sums: %v", err)
	}

	err = f.Close()
	if err != nil {
		die("close %v: %v", outputFile, err)
	}
}

func buildTargets(sourceDir, outputDir string, targets map[string][]string) {
	msg("building with %d workers", runtime.NumCPU())

	type Job struct{ GOOS, GOARCH string }

	var wg errgroup.Group
	ch := make(chan Job)
	res := make(chan string)

	for i := 0; i < runtime.NumCPU(); i++ {
		wg.Go(func() error {
			for job := range ch {
				start := time.Now()
				verbose("build %v/%v", job.GOOS, job.GOARCH)
				file := buildForTarget(sourceDir, outputDir, job.GOOS, job.GOARCH)
				msg("built %v/%v in %.3fs", job.GOOS, job.GOARCH, time.Since(start).Seconds())
				res <- file
			}
			return nil
		})
	}

	wg.Go(func() error {
		for goos, archs := range targets {
			for _, goarch := range archs {
				ch <- Job{goos, goarch}
			}
		}
		close(ch)
		return nil
	})

	go func() {
		_ = wg.Wait()
		close(res)
	}()

	start := time.Now()
	var filenames []string
	for filename := range res {
		filenames = append(filenames, filename)
	}
	sort.Strings(filenames)

	msg("build finished in %.3fs, create SHA256SUMS", time.Since(start).Seconds())
	sha256sums(filepath.Join(outputDir, "SHA256SUMS"), outputDir, filenames)
}

var defaultBuildTargets = map[string][]string{
	"darwin":  []string{"386", "amd64"},
	"freebsd": []string{"386", "amd64", "arm"},
	"linux":   []string{"386", "amd64", "arm", "arm64"},
	"openbsd": []string{"386", "amd64"},
	"windows": []string{"386", "amd64"},
}

func main() {
	if len(pflag.Args()) != 0 {
		die("USAGE: build-release-binaries [OPTIONS]")
	}

	sourceDir := abs(opts.SourceDir)
	outputDir := abs(opts.OutputDir)
	mkdir(outputDir)

	buildTargets(sourceDir, outputDir, defaultBuildTargets)
}
<commit_msg>helpers: Don't run sha256sums in build<commit_after>package main

import (
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"runtime"
	"strings"
	"time"

	"github.com/spf13/pflag"
	"golang.org/x/sync/errgroup"
)

var opts = struct {
	Verbose   bool
	SourceDir string
	OutputDir string
}{}

func init() {
	pflag.BoolVarP(&opts.Verbose, "verbose", "v", false, "be verbose")
	pflag.StringVarP(&opts.SourceDir, "source", "s", "/restic", "path to the source code `directory`")
	pflag.StringVarP(&opts.OutputDir, "output", "o", "/output", "path to the output `directory`")
	pflag.Parse()
}

func die(f string, args ...interface{}) {
	if !strings.HasSuffix(f, "\n") {
		f += "\n"
	}
	f = "\x1b[31m" + f + "\x1b[0m"
	fmt.Fprintf(os.Stderr, f, args...)
	os.Exit(1)
}

func msg(f string, args ...interface{}) {
	if !strings.HasSuffix(f, "\n") {
		f += "\n"
	}
	f = "\x1b[32m" + f + "\x1b[0m"
	fmt.Printf(f, args...)
}

func verbose(f string, args ...interface{}) {
	if !opts.Verbose {
		return
	}
	if !strings.HasSuffix(f, "\n") {
		f += "\n"
	}
	f = "\x1b[32m" + f + "\x1b[0m"
	fmt.Printf(f, args...)
}

func run(cmd string, args ...string) {
	c := exec.Command(cmd, args...)
	c.Stdout = os.Stdout
	c.Stderr = os.Stderr
	err := c.Run()
	if err != nil {
		die("error running %s %s: %v", cmd, args, err)
	}
}

func rm(file string) {
	err := os.Remove(file)

	if os.IsNotExist(err) {
		err = nil
	}

	if err != nil {
		die("error removing %v: %v", file, err)
	}
}

func rmdir(dir string) {
	err := os.RemoveAll(dir)
	if err != nil {
		die("error removing %v: %v", dir, err)
	}
}

func mkdir(dir string) {
	err := os.MkdirAll(dir, 0755)
	if err != nil {
		die("mkdir %v: %v", dir, err)
	}
}

func getwd() string {
	pwd, err := os.Getwd()
	if err != nil {
		die("Getwd(): %v", err)
	}
	return pwd
}

func abs(dir string) string {
	absDir, err := filepath.Abs(dir)
	if err != nil {
		die("unable to find absolute path for %v: %v", dir, err)
	}
	return absDir
}

func build(sourceDir, outputDir, goos, goarch string) (filename string) {
	filename = fmt.Sprintf("%v_%v_%v", "restic", goos, goarch)
	if goos == "windows" {
		filename += ".exe"
	}
	outputFile := filepath.Join(outputDir, filename)

	c := exec.Command("go", "build",
		"-mod=vendor",
		"-o", outputFile,
		"-ldflags", "-s -w",
		"-tags", "selfupdate",
		"./cmd/restic",
	)
	c.Stdout = os.Stdout
	c.Stderr = os.Stderr
	c.Dir = sourceDir

	verbose("run %v %v in %v", "go", c.Args, c.Dir)

	c.Dir = sourceDir
	c.Env = append(os.Environ(),
		"CGO_ENABLED=0",
		"GOPROXY=off",
		"GOOS="+goos,
		"GOARCH="+goarch,
	)

	err := c.Run()
	if err != nil {
		die("error building %v/%v: %v", goos, goarch, err)
	}

	return filename
}

func modTime(file string) time.Time {
	fi, err := os.Lstat(file)
	if err != nil {
		die("unable to get modtime of %v: %v", file, err)
	}

	return fi.ModTime()
}

func touch(file string, t time.Time) {
	err := os.Chtimes(file, t, t)
	if err != nil {
		die("unable to update timestamps for %v: %v", file, err)
	}
}

func chmod(file string, mode os.FileMode) {
	err := os.Chmod(file, mode)
	if err != nil {
		die("unable to chmod %v to %s: %v", file, mode, err)
	}
}

func compress(goos, inputDir, filename string) (outputFile string) {
	var c *exec.Cmd
	switch goos {
	case "windows":
		outputFile = strings.TrimSuffix(filename, ".exe") + ".zip"
		c = exec.Command("zip", "-q", "-X", outputFile, filename)
		c.Dir = inputDir
	default:
		outputFile = filename + ".bz2"
		c = exec.Command("bzip2", filename)
		c.Dir = inputDir
	}

	rm(filepath.Join(inputDir, outputFile))

	c.Stdout = os.Stdout
	c.Stderr = os.Stderr
	c.Dir = inputDir

	verbose("run %v %v in %v", "go", c.Args, c.Dir)

	err := c.Run()
	if err != nil {
		die("error compressing: %v", err)
	}

	rm(filepath.Join(inputDir, filename))

	return outputFile
}

func buildForTarget(sourceDir, outputDir, goos, goarch string) (filename string) {
	mtime := modTime(filepath.Join(sourceDir, "VERSION"))

	filename = build(sourceDir, outputDir, goos, goarch)
	touch(filepath.Join(outputDir, filename), mtime)
	chmod(filepath.Join(outputDir, filename), 0755)
	filename = compress(goos, outputDir, filename)
	return filename
}

func buildTargets(sourceDir, outputDir string, targets map[string][]string) {
	start := time.Now()
	msg("building with %d workers", runtime.NumCPU())

	type Job struct{ GOOS, GOARCH string }

	var wg errgroup.Group
	ch := make(chan Job)

	for i := 0; i < runtime.NumCPU(); i++ {
		wg.Go(func() error {
			for job := range ch {
				start := time.Now()
				verbose("build %v/%v", job.GOOS, job.GOARCH)
				buildForTarget(sourceDir, outputDir, job.GOOS, job.GOARCH)
				msg("built %v/%v in %.3fs", job.GOOS, job.GOARCH, time.Since(start).Seconds())
			}
			return nil
		})
	}

	wg.Go(func() error {
		for goos, archs := range targets {
			for _, goarch := range archs {
				ch <- Job{goos, goarch}
			}
		}
		close(ch)
		return nil
	})

	_ = wg.Wait()
	msg("build finished in %.3fs", time.Since(start).Seconds())
}

var defaultBuildTargets = map[string][]string{
	"darwin":  []string{"386", "amd64"},
	"freebsd": []string{"386", "amd64", "arm"},
	"linux":   []string{"386", "amd64", "arm", "arm64"},
	"openbsd": []string{"386", "amd64"},
	"windows": []string{"386", "amd64"},
}

func main() {
	if len(pflag.Args()) != 0 {
		die("USAGE: build-release-binaries [OPTIONS]")
	}

	sourceDir := abs(opts.SourceDir)
	outputDir := abs(opts.OutputDir)
	mkdir(outputDir)

	buildTargets(sourceDir, outputDir, defaultBuildTargets)
}
<|endoftext|>


<commit_before>package plaintext

import (
	"bytes"
	"strings"
	"text/scanner"
)

// GolangText extracts plaintext from Golang and other similar C or Java like files
type GolangText struct {
}

// NewGolangText creates a new extractor
func NewGolangText() (*GolangText, error) {
	return &GolangText{}, nil
}

// Text satifies the Extractor interface
//
//ReplaceGo is a specialized routine for correcting Golang source
// files.  Currently only checks comments, not identifiers for
// spelling.
//
// Other items:
//   - check strings, but need to ignore
//      * import "statements" blocks
//      * import ( "blocks" )
//   - skip first comment (line 0) if build comment
//
func (p *GolangText) Text(raw []byte) []byte {
	out := bytes.Buffer{}
	var s scanner.Scanner
	s.Init(strings.NewReader(string(raw)))
	s.Mode = scanner.ScanIdents | scanner.ScanFloats | scanner.ScanChars | scanner.ScanStrings | scanner.ScanRawStrings | scanner.ScanComments
	for {
		switch s.Scan() {
		case scanner.Comment:
			out.WriteString(s.TokenText())
			out.WriteByte('\n')
		case scanner.EOF:
			return out.Bytes()
		}
	}
}
<commit_msg>simplify<commit_after>package plaintext

import (
	"bytes"
	"text/scanner"
)

// GolangText extracts plaintext from Golang and other similar C or Java like files
type GolangText struct {
}

// NewGolangText creates a new extractor
func NewGolangText() (*GolangText, error) {
	return &GolangText{}, nil
}

// Text satifies the Extractor interface
//
//ReplaceGo is a specialized routine for correcting Golang source
// files.  Currently only checks comments, not identifiers for
// spelling.
//
// Other items:
//   - check strings, but need to ignore
//      * import "statements" blocks
//      * import ( "blocks" )
//   - skip first comment (line 0) if build comment
//
func (p *GolangText) Text(raw []byte) []byte {
	out := bytes.Buffer{}
	s := scanner.Scanner{}
	s.Init(bytes.NewReader(raw))
	s.Mode = scanner.ScanIdents | scanner.ScanFloats | scanner.ScanChars | scanner.ScanStrings | scanner.ScanRawStrings | scanner.ScanComments
	for {
		switch s.Scan() {
		case scanner.Comment:
			out.WriteString(s.TokenText())
			out.WriteByte('\n')
		case scanner.EOF:
			return out.Bytes()
		}
	}
}
<|endoftext|>