<commit_before>package readline

type IHistory interface {
	Len() int
	At(int) string
}

type Editor struct {
	History IHistory
	Prompt  func() (int, error)
}

func KeyFuncHistoryUp(this *Buffer) Result {
	if this.HistoryPointer <= 0 {
		this.HistoryPointer = this.History.Len()
	}
	this.HistoryPointer -= 1
	KeyFuncClear(this)
	if this.HistoryPointer >= 0 {
		this.InsertString(0, this.History.At(this.HistoryPointer))
		this.ViewStart = 0
		this.Cursor = 0
		KeyFuncTail(this)
	}
	return CONTINUE
}

func KeyFuncHistoryDown(this *Buffer) Result {
	this.HistoryPointer += 1
	if this.HistoryPointer > this.History.Len() {
		this.HistoryPointer = 0
	}
	KeyFuncClear(this)
	if this.HistoryPointer < this.History.Len() {
		this.InsertString(0, this.History.At(this.HistoryPointer))
		this.ViewStart = 0
		this.Cursor = 0
		KeyFuncTail(this)
	}
	return CONTINUE
}
<commit_msg>Internal. readline disable Ctrl-P/N if history is empty.<commit_after>package readline

type IHistory interface {
	Len() int
	At(int) string
}

type Editor struct {
	History IHistory
	Prompt  func() (int, error)
}

func KeyFuncHistoryUp(this *Buffer) Result {
	if this.History.Len() <= 0 {
		return CONTINUE
	}
	if this.HistoryPointer <= 0 {
		this.HistoryPointer = this.History.Len()
	}
	this.HistoryPointer -= 1
	KeyFuncClear(this)
	if this.HistoryPointer >= 0 {
		this.InsertString(0, this.History.At(this.HistoryPointer))
		this.ViewStart = 0
		this.Cursor = 0
		KeyFuncTail(this)
	}
	return CONTINUE
}

func KeyFuncHistoryDown(this *Buffer) Result {
	if this.History.Len() <= 0 {
		return CONTINUE
	}
	this.HistoryPointer += 1
	if this.HistoryPointer > this.History.Len() {
		this.HistoryPointer = 0
	}
	KeyFuncClear(this)
	if this.HistoryPointer < this.History.Len() {
		this.InsertString(0, this.History.At(this.HistoryPointer))
		this.ViewStart = 0
		this.Cursor = 0
		KeyFuncTail(this)
	}
	return CONTINUE
}
<|endoftext|>


<commit_before>// (c) 2012 Alexander Solovyov
// under terms of ISC license

// Generating example site

package main

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"unicode"
)

var ExampleConfig = `
TEMPLATES = site.tmpl
SOURCE = src
OUTPUT = site
TITLE = Example Site
URL = http://example.com/
AUTHOR = Your Name

blog/*.md:
	config
	ext .html
	directorify
	tags tags/*.tag
	markdown
	template post
	template page

*.tag: blog/*.md
	ext .html
	directorify
	template tag
	markdown
	template page

blog.atom: blog/*.md
	inner-template

index.html: blog/*.md
	config
	inner-template
	template page
`

var ExampleTemplate = `
{{ define "header" }}<!doctype html>

  <meta charset="utf-8">
  <meta name="author" content="{{ html .Site.Other.Author }}">
  <link rel="alternate" type="application/atom+xml" title="{{ html .Site.Other.Title }} feed" href="{{ .Rel "blog.atom" }}">
  <title>{{ .Site.Other.Title }}{{ if .Title }}: {{ .Title }}{{ end }}</title>
  <link rel="stylesheet" type="text/css" href="{{ .Rel "static/style.css" }}">

{{ end }}

{{ define "footer" }}

{{ end }}

{{define "date"}}
<time datetime="{{ .Format "2006-01-02T15:04:05Z07:00" }}">
  {{ .Format "2006, January 02" }}
</time>
{{end}}

{{ define "page" }}{{ template "header" . }}
  {{ .Content }}
{{ template "footer" . }}{{ end }}

{{ define "post" }}

{{ .Title }}

      {{ template "date" .Date }} —
      {{ range $i, $t := .Tags }}{{if $i}},{{end}}
      {{ $t }}{{ end }}

  {{ .Content }}

{{ end }}

{{define "tag"}}
# Pages tagged with {{ .Title }}
{{ range .Site.Pages.WithTag .Title }}
- [{{ .Title }}](../../{{ .Url }})
{{ end }}
{{ end }}
`

var ExampleIndex = `
title: Main Page
----

{{ range .Site.Pages.Children "blog/" }}

{{ template "date" .Date }} - {{ .Title }}
{{ end }}

`

var ExampleFeed = `
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0">
  <id>{{ .Site.Other.Url }}</id>
  <title>{{ .Site.Other.Title }}</title>
  {{ with .Site.Pages.Children "blog/" }}
  <updated>{{ .First.Date.Format "2006-01-02T15:04:05Z07:00" }}</updated>
  {{ end }}
  <author><name>{{ .Site.Other.Author }}</name></author>
  <link href="{{ .Site.Other.Url }}" rel="alternate"></link>
  <generator uri="http://github.com/piranha/gostatic/">gostatic</generator>

{{ with .Site.Pages.Children "blog/" }}
{{ range .Slice 0 5 }}
<entry>
  <id>{{ .Url }}</id>
  <author><name>{{ or .Other.Author .Site.Other.Author }}</name></author>
  <title type="html">{{ html .Title }}</title>
  <published>{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}</published>
  {{ range .Tags }}
  <category term="{{ . }}"></category>
  {{ end }}
  <link href="{{ .Site.Other.Url }}{{ .Url }}" rel="alternate"></link>
  <content type="html">
    {{/* .Process runs here in case only feed changed */}}
    {{ with cut .Process.Content "
" "
" }}
      {{ html . }}
    {{ end }}
  </content>
</entry>
{{ end }}
{{ end }}
</feed>
`

var ExamplePost = `
title: First Post
date: 2012-12-12
tags: blog
----
My first post with [gostatic](http://github.com/piranha/gostatic/).
`

var ExampleStyle = `
/* put your style rules here */
`

func WriteExample(dir string) error {
	WriteFile(dir, "config", ExampleConfig)
	WriteFile(dir, "site.tmpl", ExampleTemplate)
	WriteFile(dir, "src/index.html", ExampleIndex)
	WriteFile(dir, "src/blog/first.md", ExamplePost)
	WriteFile(dir, "src/blog.atom", ExampleFeed)
	WriteFile(dir, "src/static/style.css", ExampleStyle)
	return nil
}

func WriteFile(dir string, fn string, content string) error {
	path := filepath.Join(dir, filepath.FromSlash(fn))
	dir = filepath.Dir(path)

	if err := os.MkdirAll(dir, 0755); err != nil {
		return err
	}

	towrite := []byte(strings.TrimLeftFunc(content, unicode.IsSpace))
	if err := ioutil.WriteFile(path, towrite, 0644); err != nil {
		return err
	}

	return nil
}
<commit_msg>makefile for example<commit_after>// (c) 2012 Alexander Solovyov
// under terms of ISC license

// Generating example site

package main

import (
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"unicode"
)

var ExampleConfig = `
TEMPLATES = site.tmpl
SOURCE = src
OUTPUT = site
TITLE = Example Site
URL = http://example.com/
AUTHOR = Your Name

blog/*.md:
	config
	ext .html
	directorify
	tags tags/*.tag
	markdown
	template post
	template page

*.tag: blog/*.md
	ext .html
	directorify
	template tag
	markdown
	template page

blog.atom: blog/*.md
	inner-template

index.html: blog/*.md
	config
	inner-template
	template page
`

var ExampleMakefile = `
GS ?= gostatic

compile:
	$(GS) config

w:
	$(GS) -w config
`

var ExampleTemplate = `
{{ define "header" }}<!doctype html>

  <meta charset="utf-8">
  <meta name="author" content="{{ html .Site.Other.Author }}">
  <link rel="alternate" type="application/atom+xml" title="{{ html .Site.Other.Title }} feed" href="{{ .Rel "blog.atom" }}">
  <title>{{ .Site.Other.Title }}{{ if .Title }}: {{ .Title }}{{ end }}</title>
  <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
  <link rel="stylesheet" type="text/css" href="{{ .Rel "static/style.css" }}">

{{ end }}

{{ define "footer" }}

{{ end }}

{{define "date"}}
<time datetime="{{ .Format "2006-01-02T15:04:05Z07:00" }}">
  {{ .Format "2006, January 02" }}
</time>
{{end}}

{{ define "page" }}{{ template "header" . }}
  {{ .Content }}
{{ template "footer" . }}{{ end }}

{{ define "post" }}

{{ .Title }}

      {{ template "date" .Date }} —
      {{ range $i, $t := .Tags }}{{if $i}},{{end}}
      {{ $t }}{{ end }}

  {{ .Content }}

{{ end }}

{{define "tag"}}
# Pages tagged with {{ .Title }}
{{ range .Site.Pages.WithTag .Title }}
- [{{ .Title }}](../../{{ .Url }})
{{ end }}
{{ end }}
`

var ExampleIndex = `
title: Main Page
----

{{ range .Site.Pages.Children "blog/" }}

{{ template "date" .Date }} - {{ .Title }}
{{ end }}

`

var ExampleFeed = `
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0">
  <id>{{ .Site.Other.Url }}</id>
  <title>{{ .Site.Other.Title }}</title>
  {{ with .Site.Pages.Children "blog/" }}
  <updated>{{ .First.Date.Format "2006-01-02T15:04:05Z07:00" }}</updated>
  {{ end }}
  <author><name>{{ .Site.Other.Author }}</name></author>
  <link href="{{ .Site.Other.Url }}" rel="alternate"></link>
  <generator uri="http://github.com/piranha/gostatic/">gostatic</generator>

{{ with .Site.Pages.Children "blog/" }}
{{ range .Slice 0 5 }}
<entry>
  <id>{{ .Url }}</id>
  <author><name>{{ or .Other.Author .Site.Other.Author }}</name></author>
  <title type="html">{{ html .Title }}</title>
  <published>{{ .Date.Format "2006-01-02T15:04:05Z07:00" }}</published>
  {{ range .Tags }}
  <category term="{{ . }}"></category>
  {{ end }}
  <link href="{{ .Site.Other.Url }}{{ .Url }}" rel="alternate"></link>
  <content type="html">
    {{/* .Process runs here in case only feed changed */}}
    {{ with cut .Process.Content "
" "
" }}
      {{ html . }}
    {{ end }}
  </content>
</entry>
{{ end }}
{{ end }}
</feed>
`

var ExamplePost = `
title: First Post
date: 2012-12-12
tags: blog
----
My first post with [gostatic](http://github.com/piranha/gostatic/).
`

var ExampleStyle = `
/* put your style rules here */
`

func WriteExample(dir string) error {
	WriteFile(dir, "config", ExampleConfig)
	WriteFile(dir, "Makefile", ExampleMakefile)
	WriteFile(dir, "site.tmpl", ExampleTemplate)
	WriteFile(dir, "src/index.html", ExampleIndex)
	WriteFile(dir, "src/blog/first.md", ExamplePost)
	WriteFile(dir, "src/blog.atom", ExampleFeed)
	WriteFile(dir, "src/static/style.css", ExampleStyle)
	return nil
}

func WriteFile(dir string, fn string, content string) error {
	path := filepath.Join(dir, filepath.FromSlash(fn))
	dir = filepath.Dir(path)

	if err := os.MkdirAll(dir, 0755); err != nil {
		return err
	}

	towrite := []byte(strings.TrimLeftFunc(content, unicode.IsSpace))
	if err := ioutil.WriteFile(path, towrite, 0644); err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>// Copyright 2016 Joel Scoble and The JoeFriday authors.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package cpuinfo handles processing of /proc/cpuinfo. The Info struct will
// have one entry per processor.
package cpuinfo

import (
	"io"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/SermoDigital/helpers"
	joe "github.com/mohae/joefriday"
)

const procFile = "/proc/cpuinfo"

// CPUInfo holds information about the system's cpus; CPU will have one entry
// per processor.
type CPUInfo struct {
	Timestamp int64
	CPU       []CPU `json:"cpus"`
}

// CPU holds the /proc/cpuinfo for a single processor.
type CPU struct {
	Processor       int16    `json:"processor"`
	VendorID        string   `json:"vendor_id"`
	CPUFamily       string   `json:"cpu_family"`
	Model           string   `json:"model"`
	ModelName       string   `json:"model_name"`
	Stepping        string   `json:"stepping"`
	Microcode       string   `json:"microcode"`
	CPUMHz          float32  `json:"cpu_mhz"`
	CacheSize       string   `json:"cache_size"`
	PhysicalID      int16    `json:"physical_id"`
	Siblings        int16    `json:"siblings"`
	CoreID          int16    `json:"core_id"`
	CPUCores        int16    `json:"cpu_cores"`
	APICID          int16    `json:"apicid"`
	InitialAPICID   int16    `json:"initial_apicid"`
	FPU             string   `json:"fpu"`
	FPUException    string   `json:"fpu_exception"`
	CPUIDLevel      string   `json:"cpuid_level"`
	WP              string   `json:"wp"`
	Flags           []string `json:"flags"`
	BogoMIPS        float32  `json:"bogomips"`
	Bugs            []string `json:"bugs"`
	CLFlushSize     string   `json:"clflush_size"`
	CacheAlignment  string   `json:"cache_alignment"`
	AddressSizes    []string   `json:"address_sizes"`
	PowerManagement []string   `json:"power_management"`
	TLBSize         string   `json:"tlb_size"`
}

// Profiler is used to process the /proc/cpuinfo file.
type Profiler struct {
	joe.Procer
	Line []byte
	Val []byte
}

// Returns an initialized Profiler; ready to use.
func NewProfiler() (prof *Profiler, err error) {
	proc, err := joe.New(procFile)
	if err != nil {
		return nil, err
	}
	return &Profiler{Procer: proc, Val: make([]byte, 0, 32)}, nil
}

// Reset resources; after reset the profiler is ready to be used again.
func (prof *Profiler) Reset() error {
	prof.Val = prof.Val[:0]
	return prof.Procer.Reset()
}

// Get returns the current cpuinfo.
func (prof *Profiler) Get() (inf *CPUInfo, err error) {
	var (
		cpuCnt, i, pos, nameLen int
		n                       uint64
		v                       byte
		cpu                     CPU
	)
	err = prof.Reset()
	if err != nil {
		return nil, err
	}
	inf = &CPUInfo{Timestamp: time.Now().UTC().UnixNano()}
	for {
		prof.Line, err = prof.ReadSlice('\n')
		if err != nil {
			if err == io.EOF {
				break
			}
			return nil, &joe.ReadError{Err: err}
		}
		prof.Val = prof.Val[:0]
		// First grab the attribute name; everything up to the ':'.  The key may have
		// spaces and has trailing spaces; that gets trimmed.
		for i, v = range prof.Line {
			if v == 0x3A {
				prof.Val = prof.Line[:i]
				pos = i + 1
				break
			}
			//prof.Val = append(prof.Val, v)
		}
		prof.Val = joe.TrimTrailingSpaces(prof.Val[:])
		nameLen = len(prof.Val)
		// if there's no name; skip.
		if nameLen == 0 {
			continue
		}
		// if there's anything left, the value is everything else; trim spaces
		if pos+1 < len(prof.Line) {
			prof.Val = append(prof.Val, joe.TrimTrailingSpaces(prof.Line[pos+1:])...)
		}
		v = prof.Val[0]
		if v == 'a' {
			v = prof.Val[1]
			if v == 'd' { // address sizes
				cpu.AddressSizes = strings.Split(string(prof.Val[nameLen:]), ", ")
				continue
			}
			if v == 'p' { // apicid
				n, err = helpers.ParseUint(prof.Val[nameLen:])
				if err != nil {
					return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
				}
				cpu.APICID = int16(n)
			}
			continue
		}
		if v == 'c' {
			v = prof.Val[1]
			if v == 'p' {
				v = prof.Val[4]
				if v == 'c' { // cpu cores
					n, err = helpers.ParseUint(prof.Val[nameLen:])
					if err != nil {
						return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
					}
					cpu.CPUCores = int16(n)
					continue
				}
				if v == 'f' { // cpu family
					cpu.CPUFamily = string(prof.Val[nameLen:])
					continue
				}
				if v == 'M' { // cpu MHz
					f, err := strconv.ParseFloat(string(prof.Val[nameLen:]), 32)
					if err != nil {
						return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
					}
					cpu.CPUMHz = float32(f)
					continue
				}
				if v == 'd' { // cpuid level
					cpu.CPUIDLevel = string(prof.Val[nameLen:])
				}
				continue
			}
			v = prof.Val[5]
			if v == '_' { // cache_alignment
				cpu.CacheAlignment = string(prof.Val[nameLen:])
				continue
			}
			if v == ' ' { // cache size
				cpu.CacheSize = string(prof.Val[nameLen:])
				continue
			}
			if v == 's' { // clflush size
				cpu.CLFlushSize = string(prof.Val[nameLen:])
				continue
			}
			if v == 'i' { // core id
				n, err = helpers.ParseUint(prof.Val[nameLen:])
				if err != nil {
					return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
				}
				cpu.CoreID = int16(n)
			}
			continue
		}
		if v == 'f' {
			v = prof.Val[1]
			if v == 'l' { // flags
				cpu.Flags = strings.Split(string(prof.Val[nameLen:]), " ")
				continue
			}
			if v == 'p' {
				if nameLen == 3 { // fpu
					cpu.FPU = string(prof.Val[nameLen:])
				} else { // fpu_exception
					cpu.FPUException = string(prof.Val[nameLen:])
				}
			}
			continue
		}
		if v == 'm' {
			v = prof.Val[1]
			if v == 'i' { // microcode
				cpu.Microcode = string(prof.Val[nameLen:])
				continue
			}
			if v == 'o' {
				if nameLen == 5 { // model
					cpu.Model = string(prof.Val[nameLen:])
					continue
				}
				cpu.ModelName = string(prof.Val[nameLen:])
			}
			continue
		}
		if v == 'p' {
			v = prof.Val[1]
			if v == 'h' { // physical id
				n, err = helpers.ParseUint(prof.Val[nameLen:])
				if err != nil {
					return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
				}
				cpu.PhysicalID = int16(n)
				continue
			}
			if v == 'o' { // power management
				tmp := string(prof.Val[nameLen:])
				if tmp == "" {
					continue
				}
				cpu.PowerManagement = strings.Split(tmp, " ")
				continue
			}
			// processor starts information about a processor.
			if v == 'r' { // processor
				if cpuCnt > 0 {
					inf.CPU = append(inf.CPU, cpu)
				}
				cpuCnt++
				n, err = helpers.ParseUint(prof.Val[nameLen:])
				if err != nil {
					return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
				}
				cpu = CPU{Processor: int16(n)}
			}
			continue
		}
		if v == 's' {
			v = prof.Val[1]
			if v == 'i' { // siblings
				n, err = helpers.ParseUint(prof.Val[nameLen:])
				if err != nil {
					return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
				}
				cpu.Siblings = int16(n)
				continue
			}
			if v == 't' { // stepping
				cpu.Stepping = string(prof.Val[nameLen:])
			}
			continue
		}
		if v == 'b' {
			if prof.Val[1] == 'o' { // bogomips
				f, err := strconv.ParseFloat(string(prof.Val[nameLen:]), 32)
				if err != nil {
					return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
				}
				cpu.BogoMIPS = float32(f)
				continue
			}
			if prof.Val[1] == 'u' { // bugs
				cpu.Bugs = strings.Split(string(prof.Val[nameLen:]), " ")
			}
			continue
		}
		if v == 'i' { // initial apicid
			n, err = helpers.ParseUint(prof.Val[nameLen:])
			if err != nil {
				return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
			}
			cpu.InitialAPICID = int16(n)
			continue
		}
		if v == 'w' { // WP
			cpu.WP = string(prof.Val[nameLen:])
			continue
		}
		if v == 'v' { // vendor_id
			cpu.VendorID = string(prof.Val[nameLen:])
		}
		if v == 'T' { //tlb size
			cpu.TLBSize = string(prof.Val[nameLen:])
		}
	}
	// append the current processor informatin
	inf.CPU = append(inf.CPU, cpu)
	return inf, nil
}

var std *Profiler
var stdMu sync.Mutex

// Get returns the current cpuinfo using the package's global Profiler.
func Get() (inf *CPUInfo, err error) {
	stdMu.Lock()
	defer stdMu.Unlock()
	if std == nil {
		std, err = NewProfiler()
		if err != nil {
			return nil, err
		}
	}
	return std.Get()
}
<commit_msg>have profiler use joe.Buffer<commit_after>// Copyright 2016 Joel Scoble and The JoeFriday authors.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// Package cpuinfo handles processing of /proc/cpuinfo. The Info struct will
// have one entry per processor.
package cpuinfo

import (
	"io"
	"strconv"
	"strings"
	"sync"
	"time"

	"github.com/SermoDigital/helpers"
	joe "github.com/mohae/joefriday"
)

const procFile = "/proc/cpuinfo"

// CPUInfo holds information about the system's cpus; CPU will have one entry
// per processor.
type CPUInfo struct {
	Timestamp int64
	CPU       []CPU `json:"cpus"`
}

// CPU holds the /proc/cpuinfo for a single processor.
type CPU struct {
	Processor       int16    `json:"processor"`
	VendorID        string   `json:"vendor_id"`
	CPUFamily       string   `json:"cpu_family"`
	Model           string   `json:"model"`
	ModelName       string   `json:"model_name"`
	Stepping        string   `json:"stepping"`
	Microcode       string   `json:"microcode"`
	CPUMHz          float32  `json:"cpu_mhz"`
	CacheSize       string   `json:"cache_size"`
	PhysicalID      int16    `json:"physical_id"`
	Siblings        int16    `json:"siblings"`
	CoreID          int16    `json:"core_id"`
	CPUCores        int16    `json:"cpu_cores"`
	APICID          int16    `json:"apicid"`
	InitialAPICID   int16    `json:"initial_apicid"`
	FPU             string   `json:"fpu"`
	FPUException    string   `json:"fpu_exception"`
	CPUIDLevel      string   `json:"cpuid_level"`
	WP              string   `json:"wp"`
	Flags           []string `json:"flags"`
	BogoMIPS        float32  `json:"bogomips"`
	Bugs            []string `json:"bugs"`
	CLFlushSize     string   `json:"clflush_size"`
	CacheAlignment  string   `json:"cache_alignment"`
	AddressSizes    []string   `json:"address_sizes"`
	PowerManagement []string   `json:"power_management"`
	TLBSize         string   `json:"tlb_size"`
}

// Profiler is used to process the /proc/cpuinfo file.
type Profiler struct {
	joe.Procer
	*joe.Buffer
}

// Returns an initialized Profiler; ready to use.
func NewProfiler() (prof *Profiler, err error) {
	proc, err := joe.New(procFile)
	if err != nil {
		return nil, err
	}
	return &Profiler{Procer: proc, Buffer: joe.NewBuffer()}, nil
}

// Reset resources; after reset the profiler is ready to be used again.
func (prof *Profiler) Reset() error {
	prof.Buffer.Reset()
	return prof.Procer.Reset()
}

// Get returns the current cpuinfo.
func (prof *Profiler) Get() (inf *CPUInfo, err error) {
	var (
		cpuCnt, i, pos, nameLen int
		n                       uint64
		v                       byte
		cpu                     CPU
	)
	err = prof.Reset()
	if err != nil {
		return nil, err
	}
	inf = &CPUInfo{Timestamp: time.Now().UTC().UnixNano()}
	for {
		prof.Line, err = prof.ReadSlice('\n')
		if err != nil {
			if err == io.EOF {
				break
			}
			return nil, &joe.ReadError{Err: err}
		}
		prof.Val = prof.Val[:0]
		// First grab the attribute name; everything up to the ':'.  The key may have
		// spaces and has trailing spaces; that gets trimmed.
		for i, v = range prof.Line {
			if v == 0x3A {
				prof.Val = prof.Line[:i]
				pos = i + 1
				break
			}
			//prof.Val = append(prof.Val, v)
		}
		prof.Val = joe.TrimTrailingSpaces(prof.Val[:])
		nameLen = len(prof.Val)
		// if there's no name; skip.
		if nameLen == 0 {
			continue
		}
		// if there's anything left, the value is everything else; trim spaces
		if pos+1 < len(prof.Line) {
			prof.Val = append(prof.Val, joe.TrimTrailingSpaces(prof.Line[pos+1:])...)
		}
		v = prof.Val[0]
		if v == 'a' {
			v = prof.Val[1]
			if v == 'd' { // address sizes
				cpu.AddressSizes = strings.Split(string(prof.Val[nameLen:]), ", ")
				continue
			}
			if v == 'p' { // apicid
				n, err = helpers.ParseUint(prof.Val[nameLen:])
				if err != nil {
					return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
				}
				cpu.APICID = int16(n)
			}
			continue
		}
		if v == 'c' {
			v = prof.Val[1]
			if v == 'p' {
				v = prof.Val[4]
				if v == 'c' { // cpu cores
					n, err = helpers.ParseUint(prof.Val[nameLen:])
					if err != nil {
						return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
					}
					cpu.CPUCores = int16(n)
					continue
				}
				if v == 'f' { // cpu family
					cpu.CPUFamily = string(prof.Val[nameLen:])
					continue
				}
				if v == 'M' { // cpu MHz
					f, err := strconv.ParseFloat(string(prof.Val[nameLen:]), 32)
					if err != nil {
						return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
					}
					cpu.CPUMHz = float32(f)
					continue
				}
				if v == 'd' { // cpuid level
					cpu.CPUIDLevel = string(prof.Val[nameLen:])
				}
				continue
			}
			v = prof.Val[5]
			if v == '_' { // cache_alignment
				cpu.CacheAlignment = string(prof.Val[nameLen:])
				continue
			}
			if v == ' ' { // cache size
				cpu.CacheSize = string(prof.Val[nameLen:])
				continue
			}
			if v == 's' { // clflush size
				cpu.CLFlushSize = string(prof.Val[nameLen:])
				continue
			}
			if v == 'i' { // core id
				n, err = helpers.ParseUint(prof.Val[nameLen:])
				if err != nil {
					return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
				}
				cpu.CoreID = int16(n)
			}
			continue
		}
		if v == 'f' {
			v = prof.Val[1]
			if v == 'l' { // flags
				cpu.Flags = strings.Split(string(prof.Val[nameLen:]), " ")
				continue
			}
			if v == 'p' {
				if nameLen == 3 { // fpu
					cpu.FPU = string(prof.Val[nameLen:])
				} else { // fpu_exception
					cpu.FPUException = string(prof.Val[nameLen:])
				}
			}
			continue
		}
		if v == 'm' {
			v = prof.Val[1]
			if v == 'i' { // microcode
				cpu.Microcode = string(prof.Val[nameLen:])
				continue
			}
			if v == 'o' {
				if nameLen == 5 { // model
					cpu.Model = string(prof.Val[nameLen:])
					continue
				}
				cpu.ModelName = string(prof.Val[nameLen:])
			}
			continue
		}
		if v == 'p' {
			v = prof.Val[1]
			if v == 'h' { // physical id
				n, err = helpers.ParseUint(prof.Val[nameLen:])
				if err != nil {
					return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
				}
				cpu.PhysicalID = int16(n)
				continue
			}
			if v == 'o' { // power management
				tmp := string(prof.Val[nameLen:])
				if tmp == "" {
					continue
				}
				cpu.PowerManagement = strings.Split(tmp, " ")
				continue
			}
			// processor starts information about a processor.
			if v == 'r' { // processor
				if cpuCnt > 0 {
					inf.CPU = append(inf.CPU, cpu)
				}
				cpuCnt++
				n, err = helpers.ParseUint(prof.Val[nameLen:])
				if err != nil {
					return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
				}
				cpu = CPU{Processor: int16(n)}
			}
			continue
		}
		if v == 's' {
			v = prof.Val[1]
			if v == 'i' { // siblings
				n, err = helpers.ParseUint(prof.Val[nameLen:])
				if err != nil {
					return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
				}
				cpu.Siblings = int16(n)
				continue
			}
			if v == 't' { // stepping
				cpu.Stepping = string(prof.Val[nameLen:])
			}
			continue
		}
		if v == 'b' {
			if prof.Val[1] == 'o' { // bogomips
				f, err := strconv.ParseFloat(string(prof.Val[nameLen:]), 32)
				if err != nil {
					return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
				}
				cpu.BogoMIPS = float32(f)
				continue
			}
			if prof.Val[1] == 'u' { // bugs
				cpu.Bugs = strings.Split(string(prof.Val[nameLen:]), " ")
			}
			continue
		}
		if v == 'i' { // initial apicid
			n, err = helpers.ParseUint(prof.Val[nameLen:])
			if err != nil {
				return nil, &joe.ParseError{Info: string(prof.Val[:nameLen]), Err: err}
			}
			cpu.InitialAPICID = int16(n)
			continue
		}
		if v == 'w' { // WP
			cpu.WP = string(prof.Val[nameLen:])
			continue
		}
		if v == 'v' { // vendor_id
			cpu.VendorID = string(prof.Val[nameLen:])
		}
		if v == 'T' { //tlb size
			cpu.TLBSize = string(prof.Val[nameLen:])
		}
	}
	// append the current processor informatin
	inf.CPU = append(inf.CPU, cpu)
	return inf, nil
}

var std *Profiler
var stdMu sync.Mutex

// Get returns the current cpuinfo using the package's global Profiler.
func Get() (inf *CPUInfo, err error) {
	stdMu.Lock()
	defer stdMu.Unlock()
	if std == nil {
		std, err = NewProfiler()
		if err != nil {
			return nil, err
		}
	}
	return std.Get()
}
<|endoftext|>


<commit_before>package allergies

import (
	"fmt"
	"sort"
	"testing"
)

const targetTestVersion = 1

var allergiesTests = []struct {
	expected []string
	input    uint
}{
	{[]string{}, 0},
	{[]string{"eggs"}, 1},
	{[]string{"peanuts"}, 2},
	{[]string{"strawberries"}, 8},
	{[]string{"eggs", "peanuts"}, 3},
	{[]string{"eggs", "shellfish"}, 5},
	{[]string{"strawberries", "tomatoes", "chocolate", "pollen", "cats"}, 248},
	{[]string{"eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"}, 255},
	{[]string{"eggs", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"}, 509},
}

func TestAllergies(t *testing.T) {
	if testVersion != targetTestVersion {
		t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
	}
	for _, test := range allergiesTests {
		actual := Allergies(test.input)
		sort.Strings(actual)
		sort.Strings(test.expected)
		if fmt.Sprintf("%s", actual) != fmt.Sprintf("%s", test.expected) {
			t.Fatalf("FAIL: Allergies(%d): expected %s, actual %s", test.input, test.expected, actual)
		} else {
			t.Logf("PASS: Allergic to %v", test.expected)
		}
	}
}

func BenchmarkAllergies(b *testing.B) {
	b.StopTimer()
	for _, test := range allergicToTests {
		b.StartTimer()

		for i := 0; i < b.N; i++ {
			Allergies(test.i)
		}
		b.StopTimer()
	}
}

var allergicToTests = []struct {
	expected bool
	i        uint
	allergen string
}{
	{false, 0, "peanuts"},
	{false, 0, "cats"},
	{false, 0, "strawberries"},
	{true, 1, "eggs"},
	{true, 5, "eggs"},
}

func TestAllergicTo(t *testing.T) {
	for _, test := range allergicToTests {
		actual := AllergicTo(test.i, test.allergen)
		if actual != test.expected {
			t.Fatalf("FAIL: AllergicTo(%d, %s): expected %t, actual %t", test.i, test.allergen, test.expected, actual)
		} else {
			t.Logf("PASS: AllergicTo(%d, %s) %t", test.i, test.allergen, actual)
		}
	}
}

func BenchmarkAllergicTo(b *testing.B) {
	b.StopTimer()
	for _, test := range allergicToTests {
		b.StartTimer()

		for i := 0; i < b.N; i++ {
			AllergicTo(test.i, test.allergen)
		}
		b.StopTimer()
	}
}
<commit_msg>update allergies_test to use %q, response to #414<commit_after>package allergies

import (
	"fmt"
	"sort"
	"testing"
)

const targetTestVersion = 1

var allergiesTests = []struct {
	expected []string
	input    uint
}{
	{[]string{}, 0},
	{[]string{"eggs"}, 1},
	{[]string{"peanuts"}, 2},
	{[]string{"strawberries"}, 8},
	{[]string{"eggs", "peanuts"}, 3},
	{[]string{"eggs", "shellfish"}, 5},
	{[]string{"strawberries", "tomatoes", "chocolate", "pollen", "cats"}, 248},
	{[]string{"eggs", "peanuts", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"}, 255},
	{[]string{"eggs", "shellfish", "strawberries", "tomatoes", "chocolate", "pollen", "cats"}, 509},
}

func TestAllergies(t *testing.T) {
	if testVersion != targetTestVersion {
		t.Fatalf("Found testVersion = %v, want %v", testVersion, targetTestVersion)
	}
	for _, test := range allergiesTests {
		actual := Allergies(test.input)
		sort.Strings(actual)
		sort.Strings(test.expected)
		if fmt.Sprintf("%s", actual) != fmt.Sprintf("%s", test.expected) {
			t.Fatalf("FAIL: Allergies(%d): expected %q, actual %q", test.input, test.expected, actual)
		} else {
			t.Logf("PASS: Allergic to %q", test.expected)
		}
	}
}

func BenchmarkAllergies(b *testing.B) {
	b.StopTimer()
	for _, test := range allergicToTests {
		b.StartTimer()

		for i := 0; i < b.N; i++ {
			Allergies(test.i)
		}
		b.StopTimer()
	}
}

var allergicToTests = []struct {
	expected bool
	i        uint
	allergen string
}{
	{false, 0, "peanuts"},
	{false, 0, "cats"},
	{false, 0, "strawberries"},
	{true, 1, "eggs"},
	{true, 5, "eggs"},
}

func TestAllergicTo(t *testing.T) {
	for _, test := range allergicToTests {
		actual := AllergicTo(test.i, test.allergen)
		if actual != test.expected {
			t.Fatalf("FAIL: AllergicTo(%d, %s): expected %t, actual %t", test.i, test.allergen, test.expected, actual)
		} else {
			t.Logf("PASS: AllergicTo(%d, %s) %t", test.i, test.allergen, actual)
		}
	}
}

func BenchmarkAllergicTo(b *testing.B) {
	b.StopTimer()
	for _, test := range allergicToTests {
		b.StartTimer()

		for i := 0; i < b.N; i++ {
			AllergicTo(test.i, test.allergen)
		}
		b.StopTimer()
	}
}
<|endoftext|>


<commit_before>package feature

import "github.com/lightningnetwork/lnd/lnwire"

// setDesc describes which feature bits should be advertised in which feature
// sets.
type setDesc map[lnwire.FeatureBit]map[Set]struct{}

// defaultSetDesc are the default set descriptors for generating feature
// vectors. Each set is annotated with the corresponding identifier from BOLT 9
// indicating where it should be advertised.
var defaultSetDesc = setDesc{
	lnwire.DataLossProtectRequired: {
		SetInit:    {}, // I
		SetNodeAnn: {}, // N
	},
	lnwire.GossipQueriesOptional: {
		SetInit:    {}, // I
		SetNodeAnn: {}, // N
	},
	lnwire.TLVOnionPayloadOptional: {
		SetInit:         {}, // I
		SetNodeAnn:      {}, // N
		SetInvoice:      {}, // 9
		SetLegacyGlobal: {},
	},
	lnwire.StaticRemoteKeyRequired: {
		SetInit:         {}, // I
		SetNodeAnn:      {}, // N
		SetLegacyGlobal: {},
	},
	lnwire.UpfrontShutdownScriptOptional: {
		SetInit:    {}, // I
		SetNodeAnn: {}, // N
	},
	lnwire.PaymentAddrOptional: {
		SetInit:    {}, // I
		SetNodeAnn: {}, // N
		SetInvoice: {}, // 9
	},
	lnwire.MPPOptional: {
		SetInit:    {}, // I
		SetNodeAnn: {}, // N
		SetInvoice: {}, // 9
	},
	lnwire.AnchorsOptional: {
		SetInit:    {}, // I
		SetNodeAnn: {}, // N
	},
	lnwire.WumboChannelsOptional: {
		SetInit:    {}, // I
		SetNodeAnn: {}, // N
	},
}
<commit_msg>feature: flip the required bit for payment addr in invoices/payload<commit_after>package feature

import "github.com/lightningnetwork/lnd/lnwire"

// setDesc describes which feature bits should be advertised in which feature
// sets.
type setDesc map[lnwire.FeatureBit]map[Set]struct{}

// defaultSetDesc are the default set descriptors for generating feature
// vectors. Each set is annotated with the corresponding identifier from BOLT 9
// indicating where it should be advertised.
var defaultSetDesc = setDesc{
	lnwire.DataLossProtectRequired: {
		SetInit:    {}, // I
		SetNodeAnn: {}, // N
	},
	lnwire.GossipQueriesOptional: {
		SetInit:    {}, // I
		SetNodeAnn: {}, // N
	},
	lnwire.TLVOnionPayloadOptional: {
		SetInit:         {}, // I
		SetNodeAnn:      {}, // N
		SetInvoice:      {}, // 9
		SetLegacyGlobal: {},
	},
	lnwire.StaticRemoteKeyRequired: {
		SetInit:         {}, // I
		SetNodeAnn:      {}, // N
		SetLegacyGlobal: {},
	},
	lnwire.UpfrontShutdownScriptOptional: {
		SetInit:    {}, // I
		SetNodeAnn: {}, // N
	},
	lnwire.PaymentAddrRequired: {
		SetInit:    {}, // I
		SetNodeAnn: {}, // N
		SetInvoice: {}, // 9
	},
	lnwire.MPPOptional: {
		SetInit:    {}, // I
		SetNodeAnn: {}, // N
		SetInvoice: {}, // 9
	},
	lnwire.AnchorsOptional: {
		SetInit:    {}, // I
		SetNodeAnn: {}, // N
	},
	lnwire.WumboChannelsOptional: {
		SetInit:    {}, // I
		SetNodeAnn: {}, // N
	},
}
<|endoftext|>


<commit_before>// clock counts down to or up from a target time.
package main

import (
	"fmt"
	"os"
	"time"
)

func main() {
	target := time.Date(2016, 5, 1, 0, 0, 0, 0, time.UTC)
	printTargetTime(target)
	exitOnEnterKey()

	var previous time.Time
	for {
		now := time.Now()
		now = now.Add(time.Duration(-now.Nanosecond())) // truncate to second
		if now != previous {
			previous = now
			remaining := target.Sub(now)
			printTimeRemaining(now, remaining)
		}
		time.Sleep(50 * time.Millisecond)
	}
}

func exitOnEnterKey() {
	go func() {
		buf := make([]byte, 1)
		_, _ = os.Stdin.Read(buf)
		os.Exit(0)
	}()
}

const (
	indent          = "\t"
	highlight_start = "\x1b[1;36m"
	highlight_end   = "\x1b[0m"
)

func printTargetTime(target time.Time) {
	fmt.Print(indent, highlight_start, "Just Go", highlight_end, "\n")
	fmt.Print(indent, target.Format(time.UnixDate), "\n")
}

func printTimeRemaining(now time.Time, remaining time.Duration) {
	var sign string
	if remaining > 0 {
		sign = "-" // countdown is "T minus..."
	} else {
		sign = "+" // count up is "T plus..."
		remaining = -remaining
	}

	var days int
	if remaining >= 24*time.Hour {
		days = int(remaining / (24 * time.Hour))
		remaining = remaining % (24 * time.Hour)
	}

	fmt.Print(indent, now.Format(time.UnixDate), "  ", sign)
	if days > 0 {
		fmt.Print(days, "d")
	}
	fmt.Print(remaining, "          \r")
}
<commit_msg>early start<commit_after>// clock counts down to or up from a target time.
package main

import (
	"fmt"
	"os"
	"time"
)

func main() {
	target := time.Date(2016, 4, 28, 0, 0, 0, 0, time.UTC)
	printTargetTime(target)
	exitOnEnterKey()

	var previous time.Time
	for {
		now := time.Now()
		now = now.Add(time.Duration(-now.Nanosecond())) // truncate to second
		if now != previous {
			previous = now
			remaining := target.Sub(now)
			printTimeRemaining(now, remaining)
		}
		time.Sleep(50 * time.Millisecond)
	}
}

func exitOnEnterKey() {
	go func() {
		buf := make([]byte, 1)
		_, _ = os.Stdin.Read(buf)
		os.Exit(0)
	}()
}

const (
	indent          = "\t"
	highlight_start = "\x1b[1;36m"
	highlight_end   = "\x1b[0m"
)

func printTargetTime(target time.Time) {
	fmt.Print(indent, highlight_start, "Just Go", highlight_end, "\n")
	fmt.Print(indent, target.Format(time.UnixDate), "\n")
}

func printTimeRemaining(now time.Time, remaining time.Duration) {
	var sign string
	if remaining > 0 {
		sign = "-" // countdown is "T minus..."
	} else {
		sign = "+" // count up is "T plus..."
		remaining = -remaining
	}

	var days int
	if remaining >= 24*time.Hour {
		days = int(remaining / (24 * time.Hour))
		remaining = remaining % (24 * time.Hour)
	}

	fmt.Print(indent, now.Format(time.UnixDate), "  ", sign)
	if days > 0 {
		fmt.Print(days, "d")
	}
	fmt.Print(remaining, "          \r")
}
<|endoftext|>


<commit_before>// Clock counts down to or up from a target time.
package main

import (
	"fmt"
	"os"
	"time"
)

func main() {
	target := time.Date(2019, 2, 1, 0, 0, 0, 0, time.Local)
	motto := "Just Go"
	printTargetTime(target, motto)
	exitOnEnterKey()

	var previous time.Time
	for {
		now := time.Now().Truncate(time.Second)
		if now != previous {
			previous = now
			countdown := now.Sub(target) // Negative times are before the target
			printCountdown(now, countdown)
		}
		time.Sleep(100 * time.Millisecond)
	}
}

func exitOnEnterKey() {
	go func() {
		buf := make([]byte, 1)
		_, _ = os.Stdin.Read(buf)
		os.Exit(0)
	}()
}

const (
	highlightStart = "\x1b[1;35m"
	highlightEnd   = "\x1b[0m"
	indent         = "\t"
)

func printTargetTime(target time.Time, motto string) {
	fmt.Print(indent, highlightStart, motto, highlightEnd, "\n")
	fmt.Print(indent, target.Format(time.UnixDate), "\n")
}

func printCountdown(now time.Time, countdown time.Duration) {
	var sign string
	if countdown >= 0 {
		sign = "+"
	} else {
		sign = "-"
		countdown = -countdown
	}

	days := int(countdown / (24 * time.Hour))
	countdown = countdown % (24 * time.Hour)

	fmt.Print(indent, now.Format(time.UnixDate), "  ", sign)
	if days > 0 {
		fmt.Print(days, "d")
	}
	fmt.Print(countdown, "          \r")
	os.Stdout.Sync()
}
<commit_msg>Go 1.12rc1<commit_after>// Clock counts down to or up from a target time.
package main

import (
	"fmt"
	"os"
	"time"
)

func main() {
	target := time.Date(2019, 2, 12, 0, 0, 0, 0, time.UTC)
	motto := "Just Go"
	printTargetTime(target, motto)
	exitOnEnterKey()

	var previous time.Time
	for {
		now := time.Now().Truncate(time.Second)
		if now != previous {
			previous = now
			countdown := now.Sub(target) // Negative times are before the target
			printCountdown(now, countdown)
		}
		time.Sleep(100 * time.Millisecond)
	}
}

func exitOnEnterKey() {
	go func() {
		buf := make([]byte, 1)
		_, _ = os.Stdin.Read(buf)
		os.Exit(0)
	}()
}

const (
	highlightStart = "\x1b[1;35m"
	highlightEnd   = "\x1b[0m"
	indent         = "\t"
)

func printTargetTime(target time.Time, motto string) {
	fmt.Print(indent, highlightStart, motto, highlightEnd, "\n")
	fmt.Print(indent, target.Format(time.UnixDate), "\n")
}

func printCountdown(now time.Time, countdown time.Duration) {
	var sign string
	if countdown >= 0 {
		sign = "+"
	} else {
		sign = "-"
		countdown = -countdown
	}

	days := int(countdown / (24 * time.Hour))
	countdown = countdown % (24 * time.Hour)

	fmt.Print(indent, now.UTC().Format(time.UnixDate), "  ", sign)
	if days > 0 {
		fmt.Print(days, "d")
	}
	fmt.Print(countdown, "          \r")
	os.Stdout.Sync()
}
<|endoftext|>


<commit_before>package main

import (
	"crypto/md5"
	"encoding/hex"
	"flag"
	csv "github.com/whosonfirst/go-whosonfirst-csv"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"strings"
	"sync"
	"sync/atomic"
	"time"
)

type WOFClone struct {
	Count          int
	Success        int
	Error          int
	Skipped        int
	Source         string
	Dest           string
	Client         *http.Client
	connections    int64
	maxconnections int64
	cond           *sync.Cond
}

func NewWOFClone(source string, dest string) *WOFClone {

	// to do - add logging

	cd := &sync.Cond{L: &sync.Mutex{}}

	cl := &http.Client{}

	c := WOFClone{
		Count:          0,
		Success:        0,
		Error:          0,
		Skipped:        0,
		Source:         source,
		Dest:           dest,
		Client:         cl,
		connections:    0,
		maxconnections: 200,
		cond:           cd,
	}

	return &c
}

func (c *WOFClone) ParseMetaFile(file string) error {

	abs_path, _ := filepath.Abs(file)
	reader, read_err := csv.NewDictReader(abs_path)

	if read_err != nil {
		log.Println(read_err)
		return read_err
	}

	wg := new(sync.WaitGroup)

	for {
		row, err := reader.Read()

		if err == io.EOF {
			break
		}

		if err != nil {
			return err
		}

		rel_path, ok := row["path"]

		if !ok {
			continue
		}

		wg.Add(1)

		go func() {
			defer wg.Done()
			c.PreProcess(rel_path)
		}()
	}

	wg.Wait()

	return nil
}

func (c *WOFClone) PreProcess(rel_path string) error {

	c.Count += 1

	remote := c.Source + rel_path
	local := path.Join(c.Dest, rel_path)

	_, err := os.Stat(local)

	if !os.IsNotExist(err) {

		change, _ := c.HasChanged(local, remote)

		if !change {
			return nil
		}

	}

	c.Process(remote, local)

	return nil
}

func (c *WOFClone) HasChanged(local string, remote string) (bool, error) {

	change := true

	body, err := ioutil.ReadFile(local)

	if err != nil {
		return change, err
	}

	hash := md5.Sum(body)
	local_hash := hex.EncodeToString(hash[:])

	rsp, err := c.Fetch("HEAD", remote)

	if err != nil {
		return change, err
	}

	defer rsp.Body.Close()

	etag := rsp.Header.Get("Etag")
	remote_hash := strings.Replace(etag, "\"", "", -1)

	if local_hash == remote_hash {
		change = false
	}

	// log.Printf("hash %s etag %s change %t\n", local_hash, remote_hash, change)

	return change, nil
}

func (c *WOFClone) Process(remote string, local string) error {

	local_root := path.Dir(local)

	_, err := os.Stat(local_root)

	if os.IsNotExist(err) {
		log.Printf("create %s\n", local_root)
		os.MkdirAll(local_root, 0755)
	}

	log.Printf("fetch '%s' and store in %s\n", remote, local)

	rsp, fetch_err := c.Fetch("GET", remote)

	if fetch_err != nil {
		log.Println(fetch_err)
		return fetch_err
	}

	defer rsp.Body.Close()

	contents, read_err := ioutil.ReadAll(rsp.Body)

	if read_err != nil {
		log.Println(read_err)
		return read_err
	}

	go func() {
		write_err := ioutil.WriteFile(local, contents, 0644)

		if write_err != nil {
			log.Println(write_err)
		}
	}()

	return nil
}

func (c *WOFClone) Fetch(method string, url string) (*http.Response, error) {

	for {
		c.cond.L.Lock()

		for c.connections >= c.maxconnections {
			c.cond.Wait()
		}

		atomic.AddInt64(&c.connections, 1)

		c.cond.L.Unlock()
		c.cond.Signal()
		break
	}

	req, _ := http.NewRequest(method, url, nil)
	req.Close = true

	rsp, err := c.Client.Do(req)

	atomic.AddInt64(&c.connections, -1)

	return rsp, err
}

func main() {

	var source = flag.String("source", "http://whosonfirst.mapzen.com/data/", "Where to look for files")
	var dest = flag.String("dest", "", "Where to write files")

	flag.Parse()
	args := flag.Args()

	cl := NewWOFClone(*source, *dest)

	start := time.Now()

	wg := new(sync.WaitGroup)

	for _, file := range args {

		wg.Add(1)

		go func() {
			defer wg.Done()
			log.Println(file)
			cl.ParseMetaFile(file)
		}()
	}

	wg.Wait()

	since := time.Since(start)
	secs := float64(since) / 1e9

	log.Printf("processed %d files in %f seconds\n", cl.Count, secs)
}
<commit_msg>more better logging; wake up all the go routines<commit_after>package main

import (
	"crypto/md5"
	"encoding/hex"
	"flag"
	csv "github.com/whosonfirst/go-whosonfirst-csv"
	"io"
	"io/ioutil"
	log "github.com/whosonfirst/go-whosonfirst-log"
	"net/http"
	"os"
	"path"
	"path/filepath"
	"strings"
	"sync"
	"sync/atomic"
	"time"
)

type WOFClone struct {
	Source         string
	Dest           string
	Count          int64
	Success        int64
	Error          int64
	Skipped        int64
	Scheduled      int64
	Completed      int64
	client         *http.Client
	connections    int64
	maxconnections int64
	cond           *sync.Cond
	logger	       *log.WOFLogger
}

func NewWOFClone(source string, dest string, logger *log.WOFLogger) *WOFClone {

	// to do - add logging

	cd := &sync.Cond{L: &sync.Mutex{}}

	cl := &http.Client{Timeout: 0}

	c := WOFClone{
		Count:          0,
		Success:        0,
		Error:          0,
		Skipped:        0,
		Source:         source,
		Dest:           dest,
		logger:		logger,
		client:         cl,
		connections:    0,
		maxconnections: 200,
		cond:           cd,
	}

	return &c
}

func (c *WOFClone) ParseMetaFile(file string) error {

	abs_path, _ := filepath.Abs(file)
	c.logger.Debug("Parse meta file %s", abs_path)

	reader, read_err := csv.NewDictReader(abs_path)

	if read_err != nil {
		c.logger.Error("Failed to read %s, because %v", abs_path, read_err)
		return read_err
	}

	wg := new(sync.WaitGroup)

	for {
		row, err := reader.Read()

		if err == io.EOF {
			break
		}

		if err != nil {
			return err
		}

		rel_path, ok := row["path"]

		if !ok {
			continue
		}

		wg.Add(1)

		go func() {

			atomic.AddInt64(&c.Scheduled, 1)

			defer wg.Done()
			complete, _ := c.Clone(rel_path)

			c.logger.Debug("Finised cloning %s: %t", rel_path, complete)

			atomic.AddInt64(&c.Completed, 1)
		}()
	}

	go func (){

		for c.Completed < c.Scheduled {
			c.logger.Info("scheduled: %d completed: %d connections: %d", c.Scheduled, c.Completed, c.connections)
		}
	}()

	wg.Wait()

	return nil
}

func (c *WOFClone) Clone(rel_path string) (bool, error) {

     	c.logger.Debug("Pre-process %s", rel_path)

	atomic.AddInt64(&c.Count, 1)

	remote := c.Source + rel_path
	local := path.Join(c.Dest, rel_path)

	/*
	_, err := os.Stat(local)

	if !os.IsNotExist(err) {

		change, _ := c.HasChanged(local, remote)

		if ! change {
			atomic.AddInt64(&c.Skipped, 1)
			return true, nil
		}

	}
	*/

	process_err := c.Process(remote, local)

	if process_err != nil {
		atomic.AddInt64(&c.Error, 1)
		return false, process_err
	}

	atomic.AddInt64(&c.Success, 1)
	return true, nil
}

func (c *WOFClone) HasChanged(local string, remote string) (bool, error) {

	change := true

	body, err := ioutil.ReadFile(local)

	if err != nil {
		c.logger.Error("Failed to read %s, becase %v", local, err)
		return change, err
	}

	hash := md5.Sum(body)
	local_hash := hex.EncodeToString(hash[:])

	rsp, err := c.Fetch("HEAD", remote)

	if err != nil {
		return change, err
	}

	defer rsp.Body.Close()

	etag := rsp.Header.Get("Etag")
	remote_hash := strings.Replace(etag, "\"", "", -1)

	if local_hash == remote_hash {
		change = false
	}

	// log.Printf("hash %s etag %s change %t\n", local_hash, remote_hash, change)

	return change, nil
}

func (c *WOFClone) Process(remote string, local string) error {

     	c.logger.Debug("fetch %s and store in %s", remote, local)

	local_root := path.Dir(local)

	_, err := os.Stat(local_root)

	if os.IsNotExist(err) {
		c.logger.Info("create %s", local_root)
		os.MkdirAll(local_root, 0755)
	}

	rsp, fetch_err := c.Fetch("GET", remote)

	if fetch_err != nil {
		return fetch_err
	}

	defer rsp.Body.Close()

	contents, read_err := ioutil.ReadAll(rsp.Body)

	if read_err != nil {
		c.logger.Error("failed to read body for %s, because %v", remote, read_err)
		return read_err
	}

	go func() error {

		write_err := ioutil.WriteFile(local, contents, 0644)

		if write_err != nil {
			c.logger.Error("Failed to write %s, because %v", local, write_err)

			// See the way we're in a goroutine? That means the parent function
			// will return 'okay' without an error. So we're just going to account
			// for that here...

			atomic.AddInt64(&c.Success, -1)
			atomic.AddInt64(&c.Error, 1)

			return write_err
		}

		c.logger.Debug("Wrote %s to disk", local)
		return nil
	}()

	return nil
}

func (c *WOFClone) Fetch(method string, url string) (*http.Response, error) {

     	c.logger.Debug("%s %s", method, url)

	for {
		c.cond.L.Lock()

		for c.connections > c.maxconnections {
		    	c.logger.Debug("%d still > %d", c.connections, c.maxconnections)
			c.cond.Wait()
		}

		atomic.AddInt64(&c.connections, 1)

		c.cond.L.Unlock()
		c.cond.Broadcast()
		break
	}

	req, _ := http.NewRequest(method, url, nil)
	req.Close = true

	rsp, err := c.client.Do(req)

	atomic.AddInt64(&c.connections, -1)

	if err != nil {
	   c.logger.Error("Failed to %s %s, because %v", method, url, err)
	   return nil, err
	}

	return rsp, err
}

func main() {

	var source = flag.String("source", "http://whosonfirst.mapzen.com/data/", "Where to look for files")
	var dest = flag.String("dest", "", "Where to write files")
	var loglevel = flag.String("loglevel", "debug", "The level of detail for logging")

	flag.Parse()
	args := flag.Args()

	writer := io.MultiWriter(os.Stdout)

	lg := log.NewWOFLogger(writer, "[clone] ", *loglevel)

	cl := NewWOFClone(*source, *dest, lg)

	start := time.Now()

	wg := new(sync.WaitGroup)

	for _, file := range args {

		wg.Add(1)

		go func() {
			defer wg.Done()
			cl.ParseMetaFile(file)
		}()
	}

	wg.Wait()

	since := time.Since(start)
	secs := float64(since) / 1e9

	cl.logger.Info("processed %d files in %f seconds\n", cl.Count, secs)
}
<|endoftext|>


<commit_before>// Copyright © 2013 Steve Francia <spf@spf13.com>.
//
// 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.

// Commands similar to git, go tools and other modern CLI tools
// inspired by go, go-Commander, gh and subcommand

package cobra

import (
	"bytes"
	"fmt"
	flag "github.com/spf13/pflag"
	"os"
	"strings"
)

var _ = flag.ContinueOnError

type Flag interface {
	Args() []string
}

type Flags interface {
	Lookup(string) *Flag
	VisitAll(fn func(*Flag))
	Parse(arguments []string) error
}

// A Commander holds the configuration for the command line tool.
type Commander struct {
	// A Commander is also a Command for top level and global help & flags
	Command
	//ExitOnError, ContinueOnError or PanicOnError
	behavior flag.ErrorHandling

	args []string
}

func NewCommander() (c *Commander) {
	c = new(Commander)
	return
}

func (c *Commander) setFlagBehavior(b flag.ErrorHandling) error {
	if b == flag.ExitOnError || b == flag.ContinueOnError || b == flag.PanicOnError {
		c.behavior = b
		return nil
	}
	return fmt.Errorf("%v is not a valid behavior", b)
}

func (c *Commander) SetName(name string) {
	c.name = name
}

func (c *Commander) SetArgs(a []string) {
	c.args = a
}

func (c *Commander) Execute() (err error) {
	if len(c.args) == 0 {
		err = c.execute(os.Args[1:])
	} else {
		err = c.execute(c.args)
	}
	return
}

// Command is just that, a command for your application.
// eg.  'go run' ... 'run' is the command. Cobra requires
// you to define the usage and description as part of your command
// definition to ensure usability.
type Command struct {
	// Name is the command name, usually the executable's name.
	name string
	// The one-line usage message.
	Use string
	// The short description shown in the 'help' output.
	Short string
	// The long message shown in the 'help <this-command>' output.
	Long string
	// Set of flags specific to this command.
	flags *flag.FlagSet
	// Set of flags children commands will inherit
	pflags *flag.FlagSet
	// Run runs the command.
	// The args are the arguments after the command name.
	Run func(cmd *Command, args []string)
	// Commands is the list of commands supported by this Commander program.
	commands []*Command
	// Parent Command for this command
	parent *Command
	// Commander
	//cmdr *Commander
	flagErrorBuf *bytes.Buffer
}

// find the target command given the args and command tree
func (c *Command) Find(args []string) (cmd *Command, a []string, err error) {
	if c == nil {
		return nil, nil, fmt.Errorf("Called find() on a nil Command")
	}

	validSubCommand := false
	if len(args) > 1 && c.HasSubCommands() {
		for _, cmd := range c.commands {
			if cmd.Name() == args[0] {
				validSubCommand = true
				return cmd.Find(args[1:])
			}
		}
	}
	if !validSubCommand && c.Runnable() {
		return c, args, nil
	}

	return nil, nil, nil
}

// execute the command determined by args and the command tree
func (c *Command) execute(args []string) (err error) {
	err = fmt.Errorf("unknown subcommand %q\nRun 'help' for usage.\n", args[0])

	if c == nil {
		return fmt.Errorf("Called Execute() on a nil Command")
	}

	cmd, a, e := c.Find(args)
	if e == nil {
		err = cmd.ParseFlags(a)
		if err != nil {
			return err
		} else {
			argWoFlags := cmd.Flags().Args()
			cmd.Run(cmd, argWoFlags)
			return nil
		}
	}
	err = e
	return err
}

// Used for testing
func (c *Command) ResetCommands() {
	c.commands = nil
}

// Add one or many commands as children of this
func (c *Command) AddCommand(cmds ...*Command) {
	for i, x := range cmds {
		cmds[i].parent = c
		c.commands = append(c.commands, x)
	}
}

// The full usage for a given command (including parents)
func (c *Command) Usage(depth ...int) string {
	i := 0
	if len(depth) > 0 {
		i = depth[0]
	}

	if c.HasParent() {
		return c.parent.Usage(i+1) + " " + c.Use
	} else if i > 0 {
		return c.Name()
	} else {
		return c.Use
	}
}

func (c *Command) DebugFlags() {
	fmt.Println("called on", c.Name())
	if c.HasSubCommands() {
		for _, x := range c.commands {
			fmt.Println(x.Name())
			x.flags.VisitAll(func(f *flag.Flag) { fmt.Println("   l:"+f.Name, f.Shorthand, f.DefValue, ":", f.Value) })
			x.pflags.VisitAll(func(f *flag.Flag) { fmt.Println("   p:"+f.Name, f.Shorthand, f.DefValue, ":", f.Value) })
			fmt.Println(x.flagErrorBuf)
			if x.HasSubCommands() {
				x.DebugFlags()
			}
		}
	}
}

// Usage prints the usage details to the standard output.
func (c *Command) PrintUsage() {
	if c.Runnable() {
		fmt.Printf("usage: %s\n\n", c.Usage())
	}

	fmt.Println(strings.Trim(c.Long, "\n"))
}

// Name returns the command's name: the first word in the use line.
func (c *Command) Name() string {
	if c.name != "" {
		return c.name
	}
	name := c.Use
	i := strings.Index(name, " ")
	if i >= 0 {
		name = name[:i]
	}
	return name
}

// Determine if the command is itself runnable
func (c *Command) Runnable() bool {
	return c.Run != nil
}

// Determine if the command has children commands
func (c *Command) HasSubCommands() bool {
	return len(c.commands) > 0
}

// Determine if the command has children commands
func (c *Command) HasParent() bool {
	return c.parent != nil
}

// Get the Commands FlagSet
func (c *Command) Flags() *flag.FlagSet {
	if c.flags == nil {
		c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
		if c.flagErrorBuf == nil {
			c.flagErrorBuf = new(bytes.Buffer)
		}
		c.flags.SetOutput(c.flagErrorBuf)
	}
	return c.flags
}

// Get the Commands Persistent FlagSet
func (c *Command) PersistentFlags() *flag.FlagSet {
	if c.pflags == nil {
		c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
		if c.flagErrorBuf == nil {
			c.flagErrorBuf = new(bytes.Buffer)
		}
		c.pflags.SetOutput(c.flagErrorBuf)
	}
	return c.pflags
}

// Intended for use in testing
func (c *Command) ResetFlags() {
	c.flagErrorBuf = new(bytes.Buffer)
	c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
	c.flags.SetOutput(c.flagErrorBuf)
	c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
	c.pflags.SetOutput(c.flagErrorBuf)
}

func (c *Command) HasFlags() bool {
	return c.Flags().HasFlags()
}

func (c *Command) HasPersistentFlags() bool {
	return c.PersistentFlags().HasFlags()
}

// Climbs up the command tree looking for matching flag
func (c *Command) Flag(name string) (flag *flag.Flag) {
	flag = c.Flags().Lookup(name)

	if flag == nil {
		flag = c.persistentFlag(name)
	}

	return
}

// recursively find matching persistent flag
func (c *Command) persistentFlag(name string) (flag *flag.Flag) {
	if c.HasPersistentFlags() {
		flag = c.PersistentFlags().Lookup(name)
	}

	if flag == nil && c.HasParent() {
		flag = c.parent.persistentFlag(name)
	}
	return
}

// Parses persistent flag tree & local flags
func (c *Command) ParseFlags(args []string) (err error) {
	c.mergePersistentFlags()

	err = c.Flags().Parse(args)
	if err != nil {
		return err
	}
	return nil
}

func (c *Command) mergePersistentFlags() {
	var rmerge func(x *Command)

	rmerge = func(x *Command) {
		if x.HasPersistentFlags() {
			x.PersistentFlags().VisitAll(func(f *flag.Flag) {
				if c.Flags().Lookup(f.Name) == nil {
					c.Flags().AddFlag(f)
				}
			})
		}
		if x.HasParent() {
			rmerge(x.parent)
		}
	}

	rmerge(c)
}

// Climbs up the command tree parsing flags from top to bottom
func (c *Command) ParsePersistentFlags(args []string) (err error) {
	if !c.HasParent() || (c.parent.HasPersistentFlags() && c.parent.PersistentFlags().Parsed()) {
		if c.HasPersistentFlags() {
			err = c.PersistentFlags().Parse(args)
			if err != nil {
				return err
			}
		}
	} else {
		if c.HasParent() && c.parent.HasPersistentFlags() {
			err = c.parent.ParsePersistentFlags(args)
			if err != nil {
				return err
			}
		}
	}
	return
}
<commit_msg>Rewrote DebugFlags() function<commit_after>// Copyright © 2013 Steve Francia <spf@spf13.com>.
//
// 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.

// Commands similar to git, go tools and other modern CLI tools
// inspired by go, go-Commander, gh and subcommand

package cobra

import (
	"bytes"
	"fmt"
	flag "github.com/spf13/pflag"
	"os"
	"strings"
)

var _ = flag.ContinueOnError

type Flag interface {
	Args() []string
}

type Flags interface {
	Lookup(string) *Flag
	VisitAll(fn func(*Flag))
	Parse(arguments []string) error
}

// A Commander holds the configuration for the command line tool.
type Commander struct {
	// A Commander is also a Command for top level and global help & flags
	Command
	//ExitOnError, ContinueOnError or PanicOnError
	behavior flag.ErrorHandling

	args []string
}

func NewCommander() (c *Commander) {
	c = new(Commander)
	return
}

func (c *Commander) setFlagBehavior(b flag.ErrorHandling) error {
	if b == flag.ExitOnError || b == flag.ContinueOnError || b == flag.PanicOnError {
		c.behavior = b
		return nil
	}
	return fmt.Errorf("%v is not a valid behavior", b)
}

func (c *Commander) SetName(name string) {
	c.name = name
}

func (c *Commander) SetArgs(a []string) {
	c.args = a
}

func (c *Commander) Execute() (err error) {
	if len(c.args) == 0 {
		err = c.execute(os.Args[1:])
	} else {
		err = c.execute(c.args)
	}
	return
}

// Command is just that, a command for your application.
// eg.  'go run' ... 'run' is the command. Cobra requires
// you to define the usage and description as part of your command
// definition to ensure usability.
type Command struct {
	// Name is the command name, usually the executable's name.
	name string
	// The one-line usage message.
	Use string
	// The short description shown in the 'help' output.
	Short string
	// The long message shown in the 'help <this-command>' output.
	Long string
	// Set of flags specific to this command.
	flags *flag.FlagSet
	// Set of flags children commands will inherit
	pflags *flag.FlagSet
	// Run runs the command.
	// The args are the arguments after the command name.
	Run func(cmd *Command, args []string)
	// Commands is the list of commands supported by this Commander program.
	commands []*Command
	// Parent Command for this command
	parent *Command
	// Commander
	//cmdr *Commander
	flagErrorBuf *bytes.Buffer
}

// find the target command given the args and command tree
func (c *Command) Find(args []string) (cmd *Command, a []string, err error) {
	if c == nil {
		return nil, nil, fmt.Errorf("Called find() on a nil Command")
	}

	validSubCommand := false
	if len(args) > 1 && c.HasSubCommands() {
		for _, cmd := range c.commands {
			if cmd.Name() == args[0] {
				validSubCommand = true
				return cmd.Find(args[1:])
			}
		}
	}
	if !validSubCommand && c.Runnable() {
		return c, args, nil
	}

	return nil, nil, nil
}

// execute the command determined by args and the command tree
func (c *Command) execute(args []string) (err error) {
	err = fmt.Errorf("unknown subcommand %q\nRun 'help' for usage.\n", args[0])

	if c == nil {
		return fmt.Errorf("Called Execute() on a nil Command")
	}

	cmd, a, e := c.Find(args)
	if e == nil {
		err = cmd.ParseFlags(a)
		if err != nil {
			return err
		} else {
			argWoFlags := cmd.Flags().Args()
			cmd.Run(cmd, argWoFlags)
			return nil
		}
	}
	err = e
	return err
}

// Used for testing
func (c *Command) ResetCommands() {
	c.commands = nil
}

// Add one or many commands as children of this
func (c *Command) AddCommand(cmds ...*Command) {
	for i, x := range cmds {
		cmds[i].parent = c
		c.commands = append(c.commands, x)
	}
}

// The full usage for a given command (including parents)
func (c *Command) Usage(depth ...int) string {
	i := 0
	if len(depth) > 0 {
		i = depth[0]
	}

	if c.HasParent() {
		return c.parent.Usage(i+1) + " " + c.Use
	} else if i > 0 {
		return c.Name()
	} else {
		return c.Use
	}
}

func (c *Command) DebugFlags() {
	fmt.Println("DebugFlags called on", c.Name())
	var debugflags func(*Command)

	debugflags = func(x *Command) {
		if x.HasFlags() || x.HasPersistentFlags() {
			fmt.Println(x.Name())
		}
		if x.HasFlags() {
			x.flags.VisitAll(func(f *flag.Flag) {
				if x.HasPersistentFlags() {
					if x.persistentFlag(f.Name) == nil {
						fmt.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [L]")
					} else {
						fmt.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [LP]")
					}
				} else {
					fmt.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [L]")
				}
			})
		}
		if x.HasPersistentFlags() {
			x.pflags.VisitAll(func(f *flag.Flag) {
				if x.HasFlags() {
					if x.flags.Lookup(f.Name) == nil {
						fmt.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [P]")
					}
				} else {
					fmt.Println("  -"+f.Shorthand+",", "--"+f.Name, "["+f.DefValue+"]", "", f.Value, "  [P]")
				}
			})
		}
		fmt.Println(x.flagErrorBuf)
		if x.HasSubCommands() {
			for _, y := range x.commands {
				debugflags(y)
			}
		}
	}

	debugflags(c)
}

// Usage prints the usage details to the standard output.
func (c *Command) PrintUsage() {
	if c.Runnable() {
		fmt.Printf("usage: %s\n\n", c.Usage())
	}

	fmt.Println(strings.Trim(c.Long, "\n"))
}

// Name returns the command's name: the first word in the use line.
func (c *Command) Name() string {
	if c.name != "" {
		return c.name
	}
	name := c.Use
	i := strings.Index(name, " ")
	if i >= 0 {
		name = name[:i]
	}
	return name
}

// Determine if the command is itself runnable
func (c *Command) Runnable() bool {
	return c.Run != nil
}

// Determine if the command has children commands
func (c *Command) HasSubCommands() bool {
	return len(c.commands) > 0
}

// Determine if the command has children commands
func (c *Command) HasParent() bool {
	return c.parent != nil
}

// Get the Commands FlagSet
func (c *Command) Flags() *flag.FlagSet {
	if c.flags == nil {
		c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
		if c.flagErrorBuf == nil {
			c.flagErrorBuf = new(bytes.Buffer)
		}
		c.flags.SetOutput(c.flagErrorBuf)
	}
	return c.flags
}

// Get the Commands Persistent FlagSet
func (c *Command) PersistentFlags() *flag.FlagSet {
	if c.pflags == nil {
		c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
		if c.flagErrorBuf == nil {
			c.flagErrorBuf = new(bytes.Buffer)
		}
		c.pflags.SetOutput(c.flagErrorBuf)
	}
	return c.pflags
}

// Intended for use in testing
func (c *Command) ResetFlags() {
	c.flagErrorBuf = new(bytes.Buffer)
	c.flags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
	c.flags.SetOutput(c.flagErrorBuf)
	c.pflags = flag.NewFlagSet(c.Name(), flag.ContinueOnError)
	c.pflags.SetOutput(c.flagErrorBuf)
}

func (c *Command) HasFlags() bool {
	return c.Flags().HasFlags()
}

func (c *Command) HasPersistentFlags() bool {
	return c.PersistentFlags().HasFlags()
}

// Climbs up the command tree looking for matching flag
func (c *Command) Flag(name string) (flag *flag.Flag) {
	flag = c.Flags().Lookup(name)

	if flag == nil {
		flag = c.persistentFlag(name)
	}

	return
}

// recursively find matching persistent flag
func (c *Command) persistentFlag(name string) (flag *flag.Flag) {
	if c.HasPersistentFlags() {
		flag = c.PersistentFlags().Lookup(name)
	}

	if flag == nil && c.HasParent() {
		flag = c.parent.persistentFlag(name)
	}
	return
}

// Parses persistent flag tree & local flags
func (c *Command) ParseFlags(args []string) (err error) {
	c.mergePersistentFlags()

	err = c.Flags().Parse(args)
	if err != nil {
		return err
	}
	return nil
}

func (c *Command) mergePersistentFlags() {
	var rmerge func(x *Command)

	rmerge = func(x *Command) {
		if x.HasPersistentFlags() {
			x.PersistentFlags().VisitAll(func(f *flag.Flag) {
				if c.Flags().Lookup(f.Name) == nil {
					c.Flags().AddFlag(f)
				}
			})
		}
		if x.HasParent() {
			rmerge(x.parent)
		}
	}

	rmerge(c)
}

// Climbs up the command tree parsing flags from top to bottom
func (c *Command) ParsePersistentFlags(args []string) (err error) {
	if !c.HasParent() || (c.parent.HasPersistentFlags() && c.parent.PersistentFlags().Parsed()) {
		if c.HasPersistentFlags() {
			err = c.PersistentFlags().Parse(args)
			if err != nil {
				return err
			}
		}
	} else {
		if c.HasParent() && c.parent.HasPersistentFlags() {
			err = c.parent.ParsePersistentFlags(args)
			if err != nil {
				return err
			}
		}
	}
	return
}
<|endoftext|>


<commit_before>// This package is maintained by Sijan Shrestha <sijanshrestha2@gmail.com>. This package helps u decide if u want to set default value for the cgroups. I dont take resposnibilty for any damage due to modification of the below code
package fs

import (
	//"bufio"
	"fmt"
	"github.com/Sirupsen/logrus"
	"github.com/memoryLimitBySijan"
	"os"
	//"reflect"
	"strings"

	"strconv"
)

func SetToDefaultValue(d *data) {
	dir, err := d.join("memory")

	defer func() {
		if err != nil {
			os.RemoveAll(dir)
		}
	}()

	logrus.Debugf("!!!!!called set default value")
	logrus.Debugf("Change is imminent")

	file, err := os.Open("/etc/default/docker")
	if err != nil {
		logrus.Debugf("i!!!!!cnsid epanic")
		defaultfunction(d)

	} else {

		data := make([]byte, 10000)
		file.Read(data)
		s := string(data)
		start := strings.Index(s, "MEMDEFAULT") + 12
		end := strings.Index(s, "DEFAULTMEM") - 1

		option := s[start:end]
		if option == "default" {
			defaultfunction(d)

		} else {
			logrus.Debugf("!!!!!setting value to %v", option)
			writeFile(dir, "memory.limit_in_bytes", option)

		}
	}
	//this is going to set default values

}
func Num64(n interface{}) int64 {
	s := fmt.Sprintf("%d", n)
	i, err := strconv.ParseInt(s, 10, 64)
	if err != nil {
		return 0
	} else {
		return i
	}
}

func defaultfunction(d *data) {
	dir, err := d.join("memory")

	defer func() {
		if err != nil {
			os.RemoveAll(dir)
		}
	}()

	logrus.Debugf("go do default")
	si := memoryLimitBySijan.Get()
	TotalMemory := si.TotalRam - 300
	logrus.Debugf("!!!!!!!!!!!!!!!!!!set default value%v\n", si.TotalRam)
	LimitForEachContainer := TotalMemory * 20 / 100
	ByteConverter := 1000 * LimitForEachContainer
	var a int64
	a = Num64(ByteConverter)
	str := strconv.FormatInt(a, 10)
	writeFile(dir, "memory.limit_in_bytes", str)
	logrus.Debugf("!!!!!setting value to %v", str)

}

/*func main() {
	file, err := os.Open("/etc/default/docker")
	check(err)
	data := make([]byte, 10000)
	file.Read(data)
	check(err)
	s := string(data)
	start := strings.Index(s, "MEMDEFAULT") + 12
	end := strings.Index(s, "DEFAULTMEM") - 1
	option := s[start:end]

	if option == "default" {
		fmt.Println("go do default")
	} else {
		fmt.Println(option)
		fmt.Println(reflect.TypeOf(option))

	}
}
*/
<commit_msg>Removed Unnecessar Log files. Clean codes<commit_after>// This package is maintained by Sijan Shrestha <sijanshrestha2@gmail.com>. This package helps u decide if u want to set default value for the cgroups. I dont take resposnibilty for any damage due to modification of the below code
package fs

import (
	"fmt"
	"github.com/Sirupsen/logrus"
	"github.com/memoryLimitBySijan"
	"os"
	"strings"
	"strconv"
)

func SetToDefaultValue(d *data) {
	dir, err := d.join("memory")

	defer func() {
		if err != nil {
			os.RemoveAll(dir)
		}
	}()

	file, err := os.Open("/etc/default/docker")
	if err != nil {
		defaultfunction(d)
	} else {

		data := make([]byte, 10000)
		file.Read(data)
		s := string(data)
		start := strings.Index(s, "MEMDEFAULT") + 12
		end := strings.Index(s, "DEFAULTMEM") - 1

		option := s[start:end]
		if option == "default" {
			defaultfunction(d)

		} else {
			writeFile(dir, "memory.limit_in_bytes", option)
		}
	}
	//this is going to set default values

}
func Num64(n interface{}) int64 {
	s := fmt.Sprintf("%d", n)
	i, err := strconv.ParseInt(s, 10, 64)
	if err != nil {
		return 0
	} else {
		return i
	}
}

func defaultfunction(d *data) {
	dir, err := d.join("memory")

	defer func() {
		if err != nil {
			os.RemoveAll(dir)
		}
	}()

	logrus.Debugf("go do default")
	si := memoryLimitBySijan.Get()
	TotalMemory := si.TotalRam - 300
	LimitForEachContainer := TotalMemory * 20 / 100
	ByteConverter := 1000 * LimitForEachContainer
	var a int64
	a = Num64(ByteConverter)
	str := strconv.FormatInt(a, 10)
	writeFile(dir, "memory.limit_in_bytes", str)
	logrus.Debugf("!!!!!setting value to %v", str)

}

/*func main() {
	file, err := os.Open("/etc/default/docker")
	check(err)
	data := make([]byte, 10000)
	file.Read(data)
	check(err)
	s := string(data)
	start := strings.Index(s, "MEMDEFAULT") + 12
	end := strings.Index(s, "DEFAULTMEM") - 1
	option := s[start:end]

	if option == "default" {
		fmt.Println("go do default")
	} else {
		fmt.Println(option)
		fmt.Println(reflect.TypeOf(option))

	}
}
*/
<|endoftext|>


<commit_before>package main

const NGINX_BUILD_VERSION = "0.3.4"

// nginx
const (
	NGINX_VERSION             = "1.9.1"
	NGINX_DOWNLOAD_URL_PREFIX = "http://nginx.org/download"
)

// pcre
const (
	PCRE_VERSION             = "8.37"
	PCRE_DOWNLOAD_URL_PREFIX = "http://ftp.csx.cam.ac.uk/pub/software/programming/pcre"
)

// openssl
const (
	OPENSSL_VERSION             = "1.0.2a"
	OPENSSL_DOWNLOAD_URL_PREFIX = "http://www.openssl.org/source"
)

// zlib
const (
	ZLIB_VERSION             = "1.2.8"
	ZLIB_DOWNLOAD_URL_PREFIX = "http://zlib.net"
)

// openResty
const (
	OPENRESTY_VERSION             = "1.7.10.1"
	OPENRESTY_DOWNLOAD_URL_PREFIX = "http://openresty.org/download"
)

// tengine
const (
	TENGINE_VERSION             = "2.1.0"
	TENGINE_DOWNLOAD_URL_PREFIX = "http://tengine.taobao.org/download"
)

// component enumerations
const (
	COMPONENT_NGINX = iota
	COMPONENT_OPENRESTY
	COMPONENT_TENGINE
	COMPONENT_PCRE
	COMPONENT_OPENSSL
	COMPONENT_ZLIB
	COMPONENT_MAX
)
<commit_msg>bumped version to 0.3.5.<commit_after>package main

const NGINX_BUILD_VERSION = "0.3.5"

// nginx
const (
	NGINX_VERSION             = "1.9.1"
	NGINX_DOWNLOAD_URL_PREFIX = "http://nginx.org/download"
)

// pcre
const (
	PCRE_VERSION             = "8.37"
	PCRE_DOWNLOAD_URL_PREFIX = "http://ftp.csx.cam.ac.uk/pub/software/programming/pcre"
)

// openssl
const (
	OPENSSL_VERSION             = "1.0.2a"
	OPENSSL_DOWNLOAD_URL_PREFIX = "http://www.openssl.org/source"
)

// zlib
const (
	ZLIB_VERSION             = "1.2.8"
	ZLIB_DOWNLOAD_URL_PREFIX = "http://zlib.net"
)

// openResty
const (
	OPENRESTY_VERSION             = "1.7.10.1"
	OPENRESTY_DOWNLOAD_URL_PREFIX = "http://openresty.org/download"
)

// tengine
const (
	TENGINE_VERSION             = "2.1.0"
	TENGINE_DOWNLOAD_URL_PREFIX = "http://tengine.taobao.org/download"
)

// component enumerations
const (
	COMPONENT_NGINX = iota
	COMPONENT_OPENRESTY
	COMPONENT_TENGINE
	COMPONENT_PCRE
	COMPONENT_OPENSSL
	COMPONENT_ZLIB
	COMPONENT_MAX
)
<|endoftext|>


<commit_before>package relay

import (
	"errors"
	"net/http"

	"github.com/gorilla/websocket"
)

// ErrPatternBound is returned when the pattern is bound
var ErrPatternBound = errors.New("Pattern is already bound")

var dupgrade = websocket.Upgrader{
	ReadBufferSize:  1024 * 1024,
	WriteBufferSize: 1024 * 1024,
}

// Controller provides a nice overlay on top of the behaviour of a requestlevel
type Controller struct {
	*Routes
}

// NewController returns a controller with the default config settings
func NewController(name string) *Controller {
	return &Controller{
		Routes: NewRoutes(name),
	}
}

// BindSocket returns provides a handle that turns http requests into websocket requests using relay.socketworkers
func (c *Controller) BindSocket(mo, pattern string, fx SocketHandler, ho http.Header) FlatChains {
	do := dupgrade
	so := NewSockets(&do, ho, fx)
	c.Add(mo, pattern, so.Handle)
	return so
}

//UpgradeSocket provides a refined control of the arguments passed to the relay.NewSocket provider
func (c *Controller) UpgradeSocket(mo, pattern string, fx SocketHandler, up websocket.Upgrader, ho http.Header) FlatChains {
	so := NewSockets(&up, ho, fx)
	c.Add(mo, pattern, so.Handle)
	return so
}

// BindHTTP binds a pattern/route to a websocket port and registers that into the controllers router, requiring the supply of a codec for handling encoding/decoding process but if not supplied uses a default http codec
func (c *Controller) BindHTTP(mo, pattern string, fx FlatHandler) FlatChains {
	hs := NewFlatChain(fx)
	c.Add(mo, pattern, hs.Handle)
	return hs
}
<commit_msg>fix proxy code listener bug<commit_after>package relay

import (
	"errors"
	"net/http"

	"net/http/pprof"

	"github.com/gorilla/websocket"
	"github.com/influx6/relay/relay"
)

// ErrPatternBound is returned when the pattern is bound
var ErrPatternBound = errors.New("Pattern is already bound")

var dupgrade = websocket.Upgrader{
	ReadBufferSize:  1024 * 1024,
	WriteBufferSize: 1024 * 1024,
}

// Controller provides a nice overlay on top of the behaviour of a requestlevel
type Controller struct {
	*Routes
}

// NewController returns a controller with the default config settings
func NewController(name string) *Controller {
	return &Controller{
		Routes: NewRoutes(name),
	}
}

// BindSocket returns provides a handle that turns http requests into websocket requests using relay.socketworkers
func (c *Controller) BindSocket(mo, pattern string, fx SocketHandler, ho http.Header) FlatChains {
	do := dupgrade
	so := NewSockets(&do, ho, fx)
	c.Add(mo, pattern, so.Handle)
	return so
}

//UpgradeSocket provides a refined control of the arguments passed to the relay.NewSocket provider
func (c *Controller) UpgradeSocket(mo, pattern string, fx SocketHandler, up websocket.Upgrader, ho http.Header) FlatChains {
	so := NewSockets(&up, ho, fx)
	c.Add(mo, pattern, so.Handle)
	return so
}

// BindHTTP binds a pattern/route to a websocket port and registers that into the controllers router, requiring the supply of a codec for handling encoding/decoding process but if not supplied uses a default http codec
func (c *Controller) BindHTTP(mo, pattern string, fx FlatHandler) FlatChains {
	hs := NewFlatChain(fx)
	c.Add(mo, pattern, hs.Handle)
	return hs
}

// NewPProfController provides an instantiated endpoint for pprofiles
func NewPProfController() *PProfController {
	return PProfController{NewController("debug")}
}

// PProfController provide pprofile handlers
type PProfController struct {
	*Controller
}

// Profile provides the pprof Profile endpoint
func (p *PProfController) Profile(c *Context, next relay.NextHandler) {
	pprof.Profile(c.Res, c.Req)
	next(c)
}

// Index provides the pprof Index endpoint
func (p *PProfController) Index(c *Context, next relay.NextHandler) {
	pprof.Index(c.Res, c.Req)
	next(c)
}

// Symbol provides the pprof Symbol endpoint
func (p *PProfController) Symbol(c *Context, next relay.NextHandler) {
	pprof.Symbol(c.Res, c.Req)
	next(c)
}

// Trace provides the pprof Trace endpoint
func (p *PProfController) Trace(c *Context, next relay.NextHandler) {
	pprof.Trace(c.Res, c.Req)
	next(c)
}
<|endoftext|>


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

package crc16

// Predefined polynomials.
const (
	// IBM is used by Bisync, Modbus, USB, ANSI X3.28, SIA DC-07, ...
	IBM = 0xA001

	// CCITT is used by X.25, V.41, HDLC FCS, XMODEM, Bluetooth, PACTOR, SD, ...
	// CCITT forward is 0x8408. Reverse is 0x1021.
	CCITT      = 0x8408
	CCITTFalse = 0x1021

	// SCSI is used by SCSI
	SCSI = 0xEDD1

	// MBUS is used by Meter-Bus, DNP, ...
	MBUS = 0x3D65
)

// Table is a 256-word table representing the polynomial for efficient processing.
type Table struct {
	entries  [256]uint16
	reversed bool
}

// IBMTable is the table for the IBM polynomial.
var IBMTable = makeTable(IBM)

// CCITTTable is the table for the CCITT polynomial.
var CCITTTable = makeTable(CCITT)

// CCITTFalseTable is the table for CCITT-FALSE.
var CCITTFalseTable = makeBitsReversedTable(CCITTFalse)

// SCSITable is the table for the SCSI polynomial.
var SCSITable = makeTable(SCSI)

// MBusTable is the tabe used for Meter-Bus polynomial.
var MBusTable = makeBitsReversedTable(MBUS)

// MakeTable returns the Table constructed from the specified polynomial.
func MakeTable(poly uint16) *Table {
	return makeTable(poly)
}

// MakeTable returns the Table constructed from the specified polynomial.
func MakeBitsReversedTable(poly uint16) *Table {
	return makeBitsReversedTable(poly)
}

// makeTable returns the Table constructed from the specified polynomial.
func makeBitsReversedTable(poly uint16) *Table {
	t := &Table{
		reversed: true,
	}
	width := uint16(16)
	for i := uint16(0); i < 256; i++ {
		crc := i << (width - 8)
		for j := 0; j < 8; j++ {
			if crc&(1<<(width-1)) != 0 {
				crc = (crc << 1) ^ poly
			} else {
				crc <<= 1
			}
		}
		t.entries[i] = crc
	}
	return t
}

func makeTable(poly uint16) *Table {
	t := &Table{
		reversed: false,
	}
	for i := 0; i < 256; i++ {
		crc := uint16(i)
		for j := 0; j < 8; j++ {
			if crc&1 == 1 {
				crc = (crc >> 1) ^ poly
			} else {
				crc >>= 1
			}
		}
		t.entries[i] = crc
	}
	return t
}

func updateBitsReversed(crc uint16, tab *Table, p []byte) uint16 {
	for _, v := range p {
		crc = tab.entries[byte(crc>>8)^v] ^ (crc << 8)
	}
	return crc
}

func update(crc uint16, tab *Table, p []byte) uint16 {
	crc = ^crc

	for _, v := range p {
		crc = tab.entries[byte(crc)^v] ^ (crc >> 8)
	}

	return ^crc
}

func updateNoXOR(crc uint16, tab *Table, p []byte) uint16 {
	for _, v := range p {
		crc = tab.entries[byte(crc)^v] ^ (crc >> 8)
	}

	return crc
}

// UpdateNoXOR is the same Update, but without XOR in and XOR out
func UpdateNoXOR(crc uint16, tab *Table, p []byte) uint16 {
	return updateNoXOR(crc, tab, p)
}

// Update returns the result of adding the bytes in p to the crc.
func Update(crc uint16, tab *Table, p []byte) uint16 {
	if tab.reversed {
		return updateBitsReversed(crc, tab, p)
	} else {
		return update(crc, tab, p)
	}
}

// Checksum returns the CRC-16 checksum of data
// using the polynomial represented by the Table.
func Checksum(data []byte, tab *Table) uint16 { return Update(0, tab, data) }

// ChecksumNoXOR is the same as Checksum, but with no XOR in and no XOR out
func ChecksumNoXOR(data []byte, tab *Table) uint16 { return UpdateNoXOR(0, tab, data) }

// ChecksumIBM returns the CRC-16 checksum of data
// using the IBM polynomial.
func ChecksumIBM(data []byte) uint16 { return Update(0, IBMTable, data) }

// ChecksumCCITTFalse returns the CRC-16 checksum using
// what some call the CCITT-False polynomial, which matches what is used
// by Perl Digest/CRC and Boost for example.
func ChecksumCCITTFalse(data []byte) uint16 { return Update(0xffff, CCITTFalseTable, data) }

// ChecksumCCITT returns the CRC-16 checksum of data
// using the CCITT polynomial.
func ChecksumCCITT(data []byte) uint16 { return Update(0, CCITTTable, data) }

// ChecksumSCSI returns the CRC-16 checksum of data
// using the SCSI polynomial.
func ChecksumSCSI(data []byte) uint16 { return Update(0, SCSITable, data) }

// ChecksumMBus returns the CRC-16 checksum of data
// using the MBus polynomial.
func ChecksumMBus(data []byte) uint16 { return Update(0, MBusTable, data) }
<commit_msg>Add feature for no XOR in and no XOR out<commit_after>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package crc16

// Predefined polynomials.
const (
	// IBM is used by Bisync, Modbus, USB, ANSI X3.28, SIA DC-07, ...
	IBM = 0xA001

	// CCITT is used by X.25, V.41, HDLC FCS, XMODEM, Bluetooth, PACTOR, SD, ...
	// CCITT forward is 0x8408. Reverse is 0x1021.
	CCITT      = 0x8408
	CCITTFalse = 0x1021

	// SCSI is used by SCSI
	SCSI = 0xEDD1

	// MBUS is used by Meter-Bus, DNP, ...
	MBUS = 0x3D65
)

// Table is a 256-word table representing the polynomial for efficient processing.
type Table struct {
	entries  [256]uint16
	reversed bool
	noXOR    bool
}

// IBMTable is the table for the IBM polynomial.
var IBMTable = makeTable(IBM)

// CCITTTable is the table for the CCITT polynomial.
var CCITTTable = makeTable(CCITT)

// CCITTFalseTable is the table for CCITT-FALSE.
var CCITTFalseTable = makeBitsReversedTable(CCITTFalse)

// SCSITable is the table for the SCSI polynomial.
var SCSITable = makeTable(SCSI)

// MBusTable is the tabe used for Meter-Bus polynomial.
var MBusTable = makeBitsReversedTable(MBUS)

// MakeTable returns the Table constructed from the specified polynomial.
func MakeTable(poly uint16) *Table {
	return makeTable(poly)
}

// MakeBitsReversedTable returns the Table constructed from the specified polynomial.
func MakeBitsReversedTable(poly uint16) *Table {
	return makeBitsReversedTable(poly)
}

// MakeTableNoXOR returns the Table constructed from the specified polynomial.
// Updates happen without XOR in and XOR out.
func MakeTableNoXOR(poly uint16) *Table {
	tab := makeTable(poly)
	tab.noXOR = true
	return tab
}

// makeTable returns the Table constructed from the specified polynomial.
func makeBitsReversedTable(poly uint16) *Table {
	t := &Table{
		reversed: true,
	}
	width := uint16(16)
	for i := uint16(0); i < 256; i++ {
		crc := i << (width - 8)
		for j := 0; j < 8; j++ {
			if crc&(1<<(width-1)) != 0 {
				crc = (crc << 1) ^ poly
			} else {
				crc <<= 1
			}
		}
		t.entries[i] = crc
	}
	return t
}

func makeTable(poly uint16) *Table {
	t := &Table{
		reversed: false,
	}
	for i := 0; i < 256; i++ {
		crc := uint16(i)
		for j := 0; j < 8; j++ {
			if crc&1 == 1 {
				crc = (crc >> 1) ^ poly
			} else {
				crc >>= 1
			}
		}
		t.entries[i] = crc
	}
	return t
}

func updateBitsReversed(crc uint16, tab *Table, p []byte) uint16 {
	for _, v := range p {
		crc = tab.entries[byte(crc>>8)^v] ^ (crc << 8)
	}
	return crc
}

func update(crc uint16, tab *Table, p []byte) uint16 {
	crc = ^crc

	for _, v := range p {
		crc = tab.entries[byte(crc)^v] ^ (crc >> 8)
	}

	return ^crc
}

func updateNoXOR(crc uint16, tab *Table, p []byte) uint16 {
	for _, v := range p {
		crc = tab.entries[byte(crc)^v] ^ (crc >> 8)
	}

	return crc
}

// Update returns the result of adding the bytes in p to the crc.
func Update(crc uint16, tab *Table, p []byte) uint16 {
	if tab.reversed {
		return updateBitsReversed(crc, tab, p)
	} else if tab.noXOR {
		return updateNoXOR(crc, tab, p)
	} else {
		return update(crc, tab, p)
	}
}

// Checksum returns the CRC-16 checksum of data
// using the polynomial represented by the Table.
func Checksum(data []byte, tab *Table) uint16 { return Update(0, tab, data) }

// ChecksumIBM returns the CRC-16 checksum of data
// using the IBM polynomial.
func ChecksumIBM(data []byte) uint16 { return Update(0, IBMTable, data) }

// ChecksumCCITTFalse returns the CRC-16 checksum using
// what some call the CCITT-False polynomial, which matches what is used
// by Perl Digest/CRC and Boost for example.
func ChecksumCCITTFalse(data []byte) uint16 { return Update(0xffff, CCITTFalseTable, data) }

// ChecksumCCITT returns the CRC-16 checksum of data
// using the CCITT polynomial.
func ChecksumCCITT(data []byte) uint16 { return Update(0, CCITTTable, data) }

// ChecksumSCSI returns the CRC-16 checksum of data
// using the SCSI polynomial.
func ChecksumSCSI(data []byte) uint16 { return Update(0, SCSITable, data) }

// ChecksumMBus returns the CRC-16 checksum of data
// using the MBus polynomial.
func ChecksumMBus(data []byte) uint16 { return Update(0, MBusTable, data) }
<|endoftext|>


<commit_before>package public

type OpenId string

type UserList struct {
	Total int `json:"total"`
	Count int `json:"count"`

	Data struct {
		Ids []string `json:"openid,omitempty"`
	} `json:"data"`

	NextId string `json:"next_openid"`
}

func (c *client) GetUserList(nextId string) (*UserList, error) {
	u := BASE_URL.Join("/usr/get")
	if nextId != "" {
		u = u.Query("next_openid", nextId)
	}

	var rep struct {
		Err
		UserList
	}
	err := c.Get(u, &rep)
	if err != nil {
		return nil, err
	}

	return &rep.UserList, nil
}
<commit_msg>Update<commit_after>package public

import "fmt"

type OpenId string

type UserList struct {
	Total int `json:"total"`
	Count int `json:"count"`

	Data struct {
		Ids []string `json:"openid,omitempty"`
	} `json:"data"`

	NextId string `json:"next_openid"`
}

func (c *client) GetUserList(nextId string) (*UserList, error) {
	u := BASE_URL.Join("/user/get")
	if nextId != "" {
		u = u.Query("next_openid", nextId)
	}

	var rep struct {
		Err
		UserList
	}

	err := c.Get(u, &rep)
	if err != nil {
		return nil, err
	}

	return &rep.UserList, nil
}

func (c *client) UpdateUserRemark(openId, remark string) error {
	u := BASE_URL.Join("/user/info/updateremark")

	var req = struct {
		OpenId string `json:"openid"`
		Remark string `json:"remark"`
	}{
		OpenId: openId,
		Remark: remark,
	}

	var rep Err
	err := c.Post(u, &req, &rep)
	return err
}

const (
	LangZhCN = "zh_CN"
	LangZhTW = "zh_TW"
	LangEN   = "en"
)

type User struct {
	IsSubscriber  int    `json:"subscribe"` // 0 represents not a subscriber and the following infos do not exist
	OpenId        string `json:"openid"`
	Nickname      string `json:"nickname"`
	Sex           int    `json:"sex"`      // 1: male, 2: female, 3: unknown
	Language      string `json:"language"` // zh_CN, zh_TW, en
	City          string `json:"city"`
	Province      string `json:"province"`
	Country       string `json:"country"`
	HeadImageURL  string `json:"headimgurl"`
	SubscribeTime int64  `json:"subscribe_time"`
	UnionId       string `json:"unionid,omitempty"` // exists only when the WeChat public account has been bound to WeChat open platform account
	Remark        string `json:"remark"`
	GroupId       int  `json:"groupid"`
}

func (c *client) GetUser(openId string, lang ...string) (*User, error) {
	u := BASE_URL.Join("/user/info")
	u = u.Query("openid", openId)
	if len(lang) > 0 {
		u = u.Query("lang", lang[0])
	} else {
		u = u.Query("lang", LangZhCN)
	}

	var rep struct {
		Err
		User
	}
	err := c.Get(u, &rep)
	if err != nil {
		return nil, err
	}
	return &rep.User, nil
}

func (c *client) GetUsers(openIds string, lang ...string) ([]User, error) {
	u := BASE_URL.Join("/user/info/batchget")
	language := LangZhCN
	if len(lang) > 0 {
		language = lang[0]
	}

	type Item struct {
		OpenId   string `json:"openid"`
		Language string `json:"lang,omitempty"`
	}

	var req = struct {
		UserList []Item `json:"user_list,omitempty"`
	}{
		UserList: make([]Item, 0, len(openIds)),
	}
	for i := 0; i < len(openIds); i++ {
		req.UserList = append(req.UserList, Item{openIds[i], language})
	}

	var rep struct {
		Err
		Users []User `json:"user_info_list"`
	}

	err := c.Post(u, &req, &rep)
	if err != nil {
		return nil, err
	}

	return rep.Users, nil
}

type Group struct {
	Id        int    `json:"id"`
	Name      string `json:"name"`
	UserCount int    `json:"count"`
}

func (c *client) GetGroups() ([]Group, error) {
	u := BASE_URL.Join("/groups/get")

	var rep struct {
		Err
		Groups []Group `json:"groups"`
	}

	err := c.Get(u, &rep)
	if err != nil {
		return nil, err
	}

	return &rep.Groups, nil
}

func (c *client) GetGroupByUser(openId string) (groupId int, err error) {
	u := BASE_URL.Join("/groups/getid")

	var req = struct {
		OpenId string `json:"openid"`
	}{
		OpenId: openId,
	}

	var rep struct {
		Err
		GroupId int `json:"groupid"`
	}

	err = c.Post(u, &req, &rep)
	if err != nil {
		return
	}
	groupId = rep.GroupId
	return
}

func (c *client) CreateGroup(name string) (*Group, error) {
	u := BASE_URL.Join("/groups/create")

	var req = struct {
		Group struct {
			Name string `json:"name"`
		} `json:"group"`
	}{
		Group{
			Name: name,
		},
	}

	var rep struct {
		Err
		Group `json:"group"`
	}

	err := c.Post(u, &req, &rep)
	if err != nil {
		return nil, err
	}

	return &rep.Group, nil
}

func (c *client) UpdateGroup(id int, name string) error {
	u := BASE_URL.Join("/groups/update")

	var req = struct {
		Group struct {
			Id   string `json:"id"`
			Name string `json:"name"`
		} `json:"group"`
	}{
		Group{
			Id:   id,
			Name: name,
		},
	}

	var rep Err
	err := c.Post(u, &req, &rep)
	return err
}

func (c *client) ChangeGroupForUser(openId string, groupId int) error {
	u := BASE_URL.Join("/groups/members/update")

	var req = struct {
		OpenId    string `json:"openid"`
		ToGroupId int    `json:"to_groupid"`
	}{
		OpenId:    openId,
		ToGroupId: groupId,
	}

	var rep Err
	err := c.Post(u, &req, &rep)
	return err
}

func (c *client) ChangeGroupForUsers(openIds []string, groupId int) error {
	if len(openIds) > 50 {
		return fmt.Errorf("openIds num too big: %d", len(openIds))
	}

	u := BASE_URL.Join("/groups/members/update")

	var req = struct {
		OpenIdList []string `json:"openid_list"`
		ToGroupId  int      `json:"to_groupid"`
	}{
		OpenIdList: openIds,
		ToGroupId:  groupId,
	}

	var rep Err
	err := c.Post(u, &req, &rep)
	return err
}

func (c *client) DeleteCroup(id int) error {
	u := BASE_URL.Join("/groups/delete")

	var req = struct {
		Group struct {
			Id string `json:"id"`
		} `json:"group"`
	}{
		Group{
			Id: id,
		},
	}

	var rep Err
	err := c.Post(u, &req, &rep)
	return err
}
<|endoftext|>