<commit_before>package lfs

// The LFS error system provides a simple wrapper around Go errors and the
// ability to inspect errors. It is strongly influenced by Dave Cheney's post
// at http://dave.cheney.net/2014/12/24/inspecting-errors.
//
// When passing errors out of lfs package functions, the return type should
// always be `error`. The wrappedError details are not exported. If an error is
// the kind of error a caller should need to investigate, an IsXError()
// function is provided that tells the caller if the error is of that type.
// There should only be a handfull of cases where a simple `error` is
// insufficient.
//
// The error behaviors can be nested when created. For example, the not
// implemented error can also be marked as a fatal error:
//
//	func LfsFunction() error {
//		err := functionCall()
//		if err != nil {
//			return newFatalError(newNotImplementedError(err))
//		}
//		return nil
//	}
//
// Then in the caller:
//
//	err := lfs.LfsFunction()
//	if lfs.IsNotImplementedError(err) {
//		log.Print("feature not implemented")
//	}
//	if lfs.IsFatalError(err) {
//		os.Exit(1)
//	}
//
// Wrapped errors contain a context, which is a map[string]string. These
// contexts can be accessed through the Error*Context functions. Calling these
// functions on a regular Go error will have no effect.
//
// Example:
//
//	err := lfs.SomeFunction()
//	lfs.ErrorSetContext(err, "foo", "bar")
//	lfs.ErrorGetContext(err, "foo") // => "bar"
//	lfs.ErrorDelContext(err, "foo")
//
// Wrapped errors also contain the stack from the point at which they are
// called. The stack is accessed via ErrorStack(). Calling ErrorStack() on a
// regular Go error will return an empty byte slice.

import (
	"errors"
	"runtime"
)

// IsFatalError indicates that the error is fatal and the process should exit
// immediately after handling the error.
func IsFatalError(err error) bool {
	if e, ok := err.(interface {
		Fatal() bool
	}); ok {
		return e.Fatal()
	}
	if e, ok := err.(errorWrapper); ok {
		return IsFatalError(e.InnerError())
	}
	return false
}

// IsNotImplementedError indicates the client attempted to use a feature the
// server has not implemented (e.g. the batch endpoint).
func IsNotImplementedError(err error) bool {
	if e, ok := err.(interface {
		NotImplemented() bool
	}); ok {
		return e.NotImplemented()
	}
	if e, ok := err.(errorWrapper); ok {
		return IsNotImplementedError(e.InnerError())
	}
	return false
}

// IsInvalidPointerError indicates an attempt to parse data that was not a
// valid pointer.
func IsInvalidPointerError(err error) bool {
	if e, ok := err.(interface {
		InvalidPointer() bool
	}); ok {
		return e.InvalidPointer()
	}
	if e, ok := err.(errorWrapper); ok {
		return IsInvalidPointerError(e.InnerError())
	}
	return false
}

// IsInvalidRepoError indicates an operation was attempted from outside a git
// repository.
func IsInvalidRepoError(err error) bool {
	if e, ok := err.(interface {
		InvalidRepo() bool
	}); ok {
		return e.InvalidRepo()
	}
	if e, ok := err.(errorWrapper); ok {
		return IsInvalidRepoError(e.InnerError())
	}
	return false
}

// IsSmudgeError indicates an error while smudging a files.
func IsSmudgeError(err error) bool {
	if e, ok := err.(interface {
		SmudgeError() bool
	}); ok {
		return e.SmudgeError()
	}
	if e, ok := err.(errorWrapper); ok {
		return IsSmudgeError(e.InnerError())
	}
	return false
}

// IsCleanPointerError indicates an error while cleaning a file. Because of the
// structure of the code, this check also returns a *CleanPointerError because
// that's how a Pointer and []byte were passed up to the caller. This is not
// very clean and should be refactored. The returned *CleanPointerError MUST
// NOT be accessed if the bool value is false.
func IsCleanPointerError(err error) (*CleanPointerError, bool) {
	if e, ok := err.(interface {
		CleanPointerError() bool
	}); ok {
		cpe := err.(CleanPointerError)
		return &cpe, e.CleanPointerError()
	}
	if e, ok := err.(errorWrapper); ok {
		return IsCleanPointerError(e.InnerError())
	}
	return nil, false
}

// IsNotAPointerError indicates the parsed data is not an LFS pointer.
func IsNotAPointerError(err error) bool {
	if e, ok := err.(interface {
		NotAPointerError() bool
	}); ok {
		return e.NotAPointerError()
	}
	if e, ok := err.(errorWrapper); ok {
		return IsNotAPointerError(e.InnerError())
	}
	return false
}

// IsDownloadDeclinedError indicates that the smudge operation should not download.
// TODO: I don't really like using errors to control that flow, it should be refactored.
func IsDownloadDeclinedError(err error) bool {
	if e, ok := err.(interface {
		DownloadDeclinedError() bool
	}); ok {
		return e.DownloadDeclinedError()
	}
	if e, ok := err.(errorWrapper); ok {
		return IsDownloadDeclinedError(e.InnerError())
	}
	return false
}

// Error wraps an error with an empty message.
func Error(err error) error {
	return Errorf(err, "")
}

// Errorf wraps an error with an additional formatted message.
func Errorf(err error, format string, args ...interface{}) error {
	if err == nil {
		return nil
	}

	e := newWrappedError(err)

	// ERRTODO this isn't right
	/*
		if len(format) > 0 {
			we := e.(wrappedError)
			we.Message = fmt.Sprintf(format, args...)
		}
	*/

	return e
}

// ErrorSetContext sets a value in the error's context. If the error has not
// been wrapped, it does nothing.
func ErrorSetContext(err error, key, value string) {
	if e, ok := err.(errorWrapper); ok {
		e.Set(key, value)
	}
}

// ErrorGetContext gets a value from the error's context. If the error has not
// been wrapped, it returns an empty string.
func ErrorGetContext(err error, key string) string {
	if e, ok := err.(errorWrapper); ok {
		return e.Get(key)
	}
	return ""
}

// ErrorDelContext removes a value from the error's context. If the error has
// not been wrapped, it does nothing.
func ErrorDelContext(err error, key string) {
	if e, ok := err.(errorWrapper); ok {
		e.Del(key)
	}
}

// ErrorStack returns the stack for an error if it is a wrappedError. If it is
// not a wrappedError it will return an empty byte slice.
func ErrorStack(err error) []byte {
	if e, ok := err.(errorWrapper); ok {
		return e.Stack()
	}
	return nil
}

// ErrorContext returns the context map for an error if it is a wrappedError.
// If it is not a wrappedError it will return an empty map.
func ErrorContext(err error) map[string]string {
	if e, ok := err.(errorWrapper); ok {
		return e.Context()
	}
	return nil
}

type errorWrapper interface {
	InnerError() error
	Error() string
	Set(string, string)
	Get(string) string
	Del(string)
	Context() map[string]string
	Stack() []byte
}

// wrappedError is the base error wrapper. It provides a Message string, a
// stack, and a context map around a regular Go error.
type wrappedError struct {
	Message string
	stack   []byte
	context map[string]string
	error
}

// newWrappedError creates a wrappedError. If the error has already been
// wrapped it is simply returned as is.
func newWrappedError(err error) errorWrapper {
	if e, ok := err.(errorWrapper); ok {
		return e
	}

	if err == nil {
		err = errors.New("LFS Error")
	}

	return wrappedError{
		Message: err.Error(),
		stack:   Stack(),
		context: make(map[string]string),
		error:   err,
	}
}

// InnerError returns the underlying error. This could be a Go error or another wrappedError.
func (e wrappedError) InnerError() error {
	return e.error
}

// Set sets the value for the key in the context.
func (e wrappedError) Set(key, val string) {
	e.context[key] = val
}

// Get gets the value for a key in the context.
func (e wrappedError) Get(key string) string {
	return e.context[key]
}

// Del removes a key from the context.
func (e wrappedError) Del(key string) {
	delete(e.context, key)
}

// Context returns the underlying context.
func (e wrappedError) Context() map[string]string {
	return e.context
}

// Stack returns the stack.
func (e wrappedError) Stack() []byte {
	return e.stack
}

// Definitions for IsFatalError()

type fatalError struct {
	errorWrapper
}

func (e fatalError) InnerError() error {
	return e.errorWrapper
}

func (e fatalError) Fatal() bool {
	return true
}

func newFatalError(err error) error {
	return fatalError{newWrappedError(err)}
}

// Definitions for IsNotImplementedError()

type notImplementedError struct {
	errorWrapper
}

func (e notImplementedError) InnerError() error {
	return e.errorWrapper
}

func (e notImplementedError) NotImplemented() bool {
	return true
}

func newNotImplementedError(err error) error {
	return notImplementedError{newWrappedError(err)}
}

// Definitions for IsInvalidPointerError()

type invalidPointerError struct {
	errorWrapper
}

func (e invalidPointerError) InnerError() error {
	return e.errorWrapper
}

func (e invalidPointerError) InvalidPointer() bool {
	return true
}

func newInvalidPointerError(err error) error {
	return invalidPointerError{newWrappedError(err)}
}

// Definitions for IsInvalidRepoError()

type invalidRepoError struct {
	errorWrapper
}

func (e invalidRepoError) InnerError() error {
	return e.errorWrapper
}

func (e invalidRepoError) InvalidRepo() bool {
	return true
}

func newInvalidRepoError(err error) error {
	if err == nil {
		err = errors.New("Not in a repository")
	}

	return invalidRepoError{newWrappedError(err)}
}

// Definitions for IsSmudgeError()

type smudgeError struct {
	errorWrapper
}

func (e smudgeError) InnerError() error {
	return e.errorWrapper
}

func (e smudgeError) SmudgeError() bool {
	return true
}

func newSmudgeError(err error, oid, filename string) error {
	e := smudgeError{newWrappedError(err)}
	ErrorSetContext(e, "OID", oid)
	ErrorSetContext(e, "FileName", filename)
	return e
}

// Definitions for IsCleanPointerError()

// CleanPointerError is used to pass the Pointer and contents back up to the
// caller.
// TODO: This should be refactored to avoid using error types in this way.
type CleanPointerError struct {
	pointer *Pointer
	bytes   []byte
	errorWrapper
}

func (e CleanPointerError) InnerError() error {
	return e.errorWrapper
}

func (e CleanPointerError) CleanPointerError() bool {
	return true
}

func (e CleanPointerError) Pointer() *Pointer {
	return e.pointer
}

func (e CleanPointerError) Bytes() []byte {
	return e.bytes
}

func newCleanPointerError(err error, pointer *Pointer, bytes []byte) error {
	return CleanPointerError{
		pointer,
		bytes,
		newWrappedError(err),
	}
}

// Definitions for IsNotAPointerError()

type notAPointerError struct {
	errorWrapper
}

func (e notAPointerError) InnerError() error {
	return e.errorWrapper
}

func (e notAPointerError) NotAPointerError() bool {
	return true
}

func newNotAPointerError(err error) error {
	if err == nil {
		err = errors.New("Not a valid Git LFS pointer file.")
	}
	return notAPointerError{newWrappedError(err)}
}

// Definitions for IsDownloadDeclinedError()

type downloadDeclinedError struct {
	errorWrapper
}

func (e downloadDeclinedError) InnerError() error {
	return e.errorWrapper
}

func (e downloadDeclinedError) DownloadDeclinedError() bool {
	return true
}

func newDownloadDeclinedError(err error) error {
	if err == nil {
		err = errors.New("File missing and download is not allowed")
	}
	return downloadDeclinedError{newWrappedError(err)}
}

// Stack returns a byte slice containing the runtime.Stack()
func Stack() []byte {
	stackBuf := make([]byte, 1024*1024)
	written := runtime.Stack(stackBuf, false)
	return stackBuf[:written]
}
<commit_msg>ンンンンン ンンンン<commit_after>package lfs

// The LFS error system provides a simple wrapper around Go errors and the
// ability to inspect errors. It is strongly influenced by Dave Cheney's post
// at http://dave.cheney.net/2014/12/24/inspecting-errors.
//
// When passing errors out of lfs package functions, the return type should
// always be `error`. The wrappedError details are not exported. If an error is
// the kind of error a caller should need to investigate, an IsXError()
// function is provided that tells the caller if the error is of that type.
// There should only be a handfull of cases where a simple `error` is
// insufficient.
//
// The error behaviors can be nested when created. For example, the not
// implemented error can also be marked as a fatal error:
//
//	func LfsFunction() error {
//		err := functionCall()
//		if err != nil {
//			return newFatalError(newNotImplementedError(err))
//		}
//		return nil
//	}
//
// Then in the caller:
//
//	err := lfs.LfsFunction()
//	if lfs.IsNotImplementedError(err) {
//		log.Print("feature not implemented")
//	}
//	if lfs.IsFatalError(err) {
//		os.Exit(1)
//	}
//
// Wrapped errors contain a context, which is a map[string]string. These
// contexts can be accessed through the Error*Context functions. Calling these
// functions on a regular Go error will have no effect.
//
// Example:
//
//	err := lfs.SomeFunction()
//	lfs.ErrorSetContext(err, "foo", "bar")
//	lfs.ErrorGetContext(err, "foo") // => "bar"
//	lfs.ErrorDelContext(err, "foo")
//
// Wrapped errors also contain the stack from the point at which they are
// called. The stack is accessed via ErrorStack(). Calling ErrorStack() on a
// regular Go error will return an empty byte slice.

import (
	"errors"
	"fmt"
	"runtime"
)

// IsFatalError indicates that the error is fatal and the process should exit
// immediately after handling the error.
func IsFatalError(err error) bool {
	if e, ok := err.(interface {
		Fatal() bool
	}); ok {
		return e.Fatal()
	}
	if e, ok := err.(errorWrapper); ok {
		return IsFatalError(e.InnerError())
	}
	return false
}

// IsNotImplementedError indicates the client attempted to use a feature the
// server has not implemented (e.g. the batch endpoint).
func IsNotImplementedError(err error) bool {
	if e, ok := err.(interface {
		NotImplemented() bool
	}); ok {
		return e.NotImplemented()
	}
	if e, ok := err.(errorWrapper); ok {
		return IsNotImplementedError(e.InnerError())
	}
	return false
}

// IsInvalidPointerError indicates an attempt to parse data that was not a
// valid pointer.
func IsInvalidPointerError(err error) bool {
	if e, ok := err.(interface {
		InvalidPointer() bool
	}); ok {
		return e.InvalidPointer()
	}
	if e, ok := err.(errorWrapper); ok {
		return IsInvalidPointerError(e.InnerError())
	}
	return false
}

// IsInvalidRepoError indicates an operation was attempted from outside a git
// repository.
func IsInvalidRepoError(err error) bool {
	if e, ok := err.(interface {
		InvalidRepo() bool
	}); ok {
		return e.InvalidRepo()
	}
	if e, ok := err.(errorWrapper); ok {
		return IsInvalidRepoError(e.InnerError())
	}
	return false
}

// IsSmudgeError indicates an error while smudging a files.
func IsSmudgeError(err error) bool {
	if e, ok := err.(interface {
		SmudgeError() bool
	}); ok {
		return e.SmudgeError()
	}
	if e, ok := err.(errorWrapper); ok {
		return IsSmudgeError(e.InnerError())
	}
	return false
}

// IsCleanPointerError indicates an error while cleaning a file. Because of the
// structure of the code, this check also returns a *CleanPointerError because
// that's how a Pointer and []byte were passed up to the caller. This is not
// very clean and should be refactored. The returned *CleanPointerError MUST
// NOT be accessed if the bool value is false.
func IsCleanPointerError(err error) (*CleanPointerError, bool) {
	if e, ok := err.(interface {
		CleanPointerError() bool
	}); ok {
		cpe := err.(CleanPointerError)
		return &cpe, e.CleanPointerError()
	}
	if e, ok := err.(errorWrapper); ok {
		return IsCleanPointerError(e.InnerError())
	}
	return nil, false
}

// IsNotAPointerError indicates the parsed data is not an LFS pointer.
func IsNotAPointerError(err error) bool {
	if e, ok := err.(interface {
		NotAPointerError() bool
	}); ok {
		return e.NotAPointerError()
	}
	if e, ok := err.(errorWrapper); ok {
		return IsNotAPointerError(e.InnerError())
	}
	return false
}

// IsDownloadDeclinedError indicates that the smudge operation should not download.
// TODO: I don't really like using errors to control that flow, it should be refactored.
func IsDownloadDeclinedError(err error) bool {
	if e, ok := err.(interface {
		DownloadDeclinedError() bool
	}); ok {
		return e.DownloadDeclinedError()
	}
	if e, ok := err.(errorWrapper); ok {
		return IsDownloadDeclinedError(e.InnerError())
	}
	return false
}

// Error wraps an error with an empty message.
func Error(err error) error {
	return Errorf(err, "")
}

// Errorf wraps an error with an additional formatted message.
func Errorf(err error, format string, args ...interface{}) error {
	if err == nil {
		err = errors.New("")
	}

	message := ""
	if len(format) > 0 {
		message = fmt.Sprintf(format, args...)
	}

	return newWrappedError(err, message)
}

// ErrorSetContext sets a value in the error's context. If the error has not
// been wrapped, it does nothing.
func ErrorSetContext(err error, key, value string) {
	if e, ok := err.(errorWrapper); ok {
		e.Set(key, value)
	}
}

// ErrorGetContext gets a value from the error's context. If the error has not
// been wrapped, it returns an empty string.
func ErrorGetContext(err error, key string) string {
	if e, ok := err.(errorWrapper); ok {
		return e.Get(key)
	}
	return ""
}

// ErrorDelContext removes a value from the error's context. If the error has
// not been wrapped, it does nothing.
func ErrorDelContext(err error, key string) {
	if e, ok := err.(errorWrapper); ok {
		e.Del(key)
	}
}

// ErrorStack returns the stack for an error if it is a wrappedError. If it is
// not a wrappedError it will return an empty byte slice.
func ErrorStack(err error) []byte {
	if e, ok := err.(errorWrapper); ok {
		return e.Stack()
	}
	return nil
}

// ErrorContext returns the context map for an error if it is a wrappedError.
// If it is not a wrappedError it will return an empty map.
func ErrorContext(err error) map[string]string {
	if e, ok := err.(errorWrapper); ok {
		return e.Context()
	}
	return nil
}

type errorWrapper interface {
	InnerError() error
	Error() string
	Set(string, string)
	Get(string) string
	Del(string)
	Context() map[string]string
	Stack() []byte
}

// wrappedError is the base error wrapper. It provides a Message string, a
// stack, and a context map around a regular Go error.
type wrappedError struct {
	Message string
	stack   []byte
	context map[string]string
	error
}

// newWrappedError creates a wrappedError. If the error has already been
// wrapped it is simply returned as is.
func newWrappedError(err error, message string) errorWrapper {
	if e, ok := err.(errorWrapper); ok {
		return e
	}

	if err == nil {
		err = errors.New("LFS Error")
	}

	if message == "" {
		message = err.Error()
	}

	return wrappedError{
		Message: message,
		stack:   Stack(),
		context: make(map[string]string),
		error:   err,
	}
}

// Error will return the wrapped error's Message if it has one, otherwise it
// will call the underlying error's Error() function.
func (e wrappedError) Error() string {
	if e.Message == "" {
		return e.error.Error()
	}
	return e.Message
}

// InnerError returns the underlying error. This could be a Go error or another wrappedError.
func (e wrappedError) InnerError() error {
	return e.error
}

// Set sets the value for the key in the context.
func (e wrappedError) Set(key, val string) {
	e.context[key] = val
}

// Get gets the value for a key in the context.
func (e wrappedError) Get(key string) string {
	return e.context[key]
}

// Del removes a key from the context.
func (e wrappedError) Del(key string) {
	delete(e.context, key)
}

// Context returns the underlying context.
func (e wrappedError) Context() map[string]string {
	return e.context
}

// Stack returns the stack.
func (e wrappedError) Stack() []byte {
	return e.stack
}

// Definitions for IsFatalError()

type fatalError struct {
	errorWrapper
}

func (e fatalError) InnerError() error {
	return e.errorWrapper
}

func (e fatalError) Fatal() bool {
	return true
}

func newFatalError(err error) error {
	return fatalError{newWrappedError(err, "Fatal error")}
}

// Definitions for IsNotImplementedError()

type notImplementedError struct {
	errorWrapper
}

func (e notImplementedError) InnerError() error {
	return e.errorWrapper
}

func (e notImplementedError) NotImplemented() bool {
	return true
}

func newNotImplementedError(err error) error {
	return notImplementedError{newWrappedError(err, "Not implemented")}
}

// Definitions for IsInvalidPointerError()

type invalidPointerError struct {
	errorWrapper
}

func (e invalidPointerError) InnerError() error {
	return e.errorWrapper
}

func (e invalidPointerError) InvalidPointer() bool {
	return true
}

func newInvalidPointerError(err error) error {
	return invalidPointerError{newWrappedError(err, "Invalid pointer")}
}

// Definitions for IsInvalidRepoError()

type invalidRepoError struct {
	errorWrapper
}

func (e invalidRepoError) InnerError() error {
	return e.errorWrapper
}

func (e invalidRepoError) InvalidRepo() bool {
	return true
}

func newInvalidRepoError(err error) error {
	return invalidRepoError{newWrappedError(err, "Not in a repository")}
}

// Definitions for IsSmudgeError()

type smudgeError struct {
	errorWrapper
}

func (e smudgeError) InnerError() error {
	return e.errorWrapper
}

func (e smudgeError) SmudgeError() bool {
	return true
}

func newSmudgeError(err error, oid, filename string) error {
	e := smudgeError{newWrappedError(err, "Smudge error")}
	ErrorSetContext(e, "OID", oid)
	ErrorSetContext(e, "FileName", filename)
	return e
}

// Definitions for IsCleanPointerError()

// CleanPointerError is used to pass the Pointer and contents back up to the
// caller.
// TODO: This should be refactored to avoid using error types in this way.
type CleanPointerError struct {
	pointer *Pointer
	bytes   []byte
	errorWrapper
}

func (e CleanPointerError) InnerError() error {
	return e.errorWrapper
}

func (e CleanPointerError) CleanPointerError() bool {
	return true
}

func (e CleanPointerError) Pointer() *Pointer {
	return e.pointer
}

func (e CleanPointerError) Bytes() []byte {
	return e.bytes
}

func newCleanPointerError(err error, pointer *Pointer, bytes []byte) error {
	return CleanPointerError{
		pointer,
		bytes,
		newWrappedError(err, "Clean pointer error"),
	}
}

// Definitions for IsNotAPointerError()

type notAPointerError struct {
	errorWrapper
}

func (e notAPointerError) InnerError() error {
	return e.errorWrapper
}

func (e notAPointerError) NotAPointerError() bool {
	return true
}

func newNotAPointerError(err error) error {
	return notAPointerError{newWrappedError(err, "Not a valid Git LFS pointer file.")}
}

// Definitions for IsDownloadDeclinedError()

type downloadDeclinedError struct {
	errorWrapper
}

func (e downloadDeclinedError) InnerError() error {
	return e.errorWrapper
}

func (e downloadDeclinedError) DownloadDeclinedError() bool {
	return true
}

func newDownloadDeclinedError(err error) error {
	return downloadDeclinedError{newWrappedError(err, "File missing and download is not allowed")}
}

// Stack returns a byte slice containing the runtime.Stack()
func Stack() []byte {
	stackBuf := make([]byte, 1024*1024)
	written := runtime.Stack(stackBuf, false)
	return stackBuf[:written]
}
<|endoftext|>


<commit_before>package captcha

import (
	"fmt"
	_ "log"
	"net/http"
	"math/rand"
	"strconv"
	_ "strings"
	"time"
	"encoding/json"
)

type CaptchaHandler struct {
	Masks *MaskIndex
	Links []string
}

func NewCaptchaHandler() *CaptchaHandler {
	ret := CaptchaHandler{}
	ret.Masks = LoadMasks("./masks/")
	ret.Links = []string{
		"http://qyxy.baic.gov.cn/checkCodeServlet?currentTimeMillis=1396966478094",
		"http://www.tjaic.gov.cn/info/inc/checkcode.asp",
		"http://www.hebscztxyxx.gov.cn/notice/img.captcha?ra=0.420229553245008",
		"http://218.26.1.108/Manage/VerifyCode.aspx?",
		"http://www.nmgs.gov.cn:7001/aiccips/verify.html",
		"http://222.171.175.16:9080/ECPS/validateCode.jspx",
		"http://www.jsgsj.gov.cn:58888/ecipplatform/rand_img.jsp?type=2",
		"http://gsxt.zjaic.gov.cn/common/captcha/doReadKaptcha.do",
		"http://www.ahcredit.gov.cn:9090/ECPS/validateCode.jspx",
		"http://wsgs.fjaic.gov.cn/creditpub/govRandValidate",
		"http://gsxt.jxaic.gov.cn/ECPS/rand.action",
		"http://218.57.139.24/shandong/secimg",
		"http://211.141.74.198:8081/aiccips/verify.html",
		"http://gsxt.lngs.gov.cn/saicpub/jcaptcha",
		"http://gsxt.gdgs.gov.cn/verify.html",
		"http://221.232.141.250:9080/ECPS/rand.action",
		"http://gsxt.hnaic.gov.cn/VerifierImage.jpg?noCache=1396969773230",
		"http://gsxt.cqgs.gov.cn/makeCertPic.jsp",
		"http://gsxt.gzgs.gov.cn/validCode?validTag=searchImageCode&1396969875371",
		"http://220.163.86.132:88/admin/_SYSTEM/CheckCode.aspx",
		"http://117.22.252.219:8002/servlet/validateCodeServlet",
		"http://gsxt.ngsh.gov.cn/ECPS/rand.action",
		"http://www.360doc.com/VerifyCode.aspx?",
		"https://omeo.alipay.com/service/checkcode?sessionID=b115901917504f20f792542d74ca2c4b&t=0.5697440346854534",
		"https://uac.10010.com/portal/Service/CreateImage",
		"http://www.189.cn/dqmh/createCheckCode.do?method=checkLoginCode&date=1396338767393",
		"https://ebsnew.boc.cn/BII/ImageValidation/validation1396327587558.gif",
		"https://pbank.95559.com.cn/personbank/DynImage",
		"http://reg.cntv.cn/simple/verificationCode.action?1395911362783",
		"https://ibsbjstar.ccb.com.cn/NCCB_Encoder/Encoder?CODE=Fa1IiPFNPnzuFzsa5HMG2DbNU0qB9zrNMEsBtyiNm0wmWXZcBkaeOShOVkJF70IPVUdZs0fNu0LVb6bOv0EJz3eNc0VJnAqmcG",
		"https://passport.lefeng.com/RandomCode.do?type=reg",
		"http://www.liepin.com/image/randomcode/",
		"http://gsxt.saic.gov.cn/zjgs/verify"
	}
	return &ret
}

func (self *CaptchaHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if rand.Intn(10) == 1 {
		self.Masks.Clear()
		self.Masks = LoadMasks("./masks/")
	}
	link := req.FormValue("link")
	if len(link) == 0 {
		link = self.Links[rand.Intn(len(self.Links))]
	}
	chType := GetChType(req.FormValue("type"))
	format := req.FormValue("format")
	if format == "" {
		format = "html"
	}
	img := LoadImageFromURL(link, "", "")

	output := "./imgs/" + strconv.FormatInt(time.Now().UnixNano(), 10)
	SaveImage(img, output)

	predictor := NewMetaPredictor()
	results := predictor.Predict(img, self.Masks, chType)

	if format == "html" {
		html := "
"
		for _, result := range results {
			for _, component := range result.Components{
				component.Save("./unknown/" + component.Encode())
				html += " "
			}
			html += "
"
			html += result.Label + " : " + strconv.FormatFloat(result.GetWeight(), 'g', 5, 64) + "
"
		}
		html += "Begin to Label";
		html += ""
		fmt.Fprint(w, html)
	} else if format == "json" {
		output, _ := json.Marshal(results)
		fmt.Fprint(w, string(output))
	}
}
<commit_msg>add links<commit_after>package captcha

import (
	"fmt"
	_ "log"
	"net/http"
	"math/rand"
	"strconv"
	_ "strings"
	"time"
	"encoding/json"
)

type CaptchaHandler struct {
	Masks *MaskIndex
	Links []string
}

func NewCaptchaHandler() *CaptchaHandler {
	ret := CaptchaHandler{}
	ret.Masks = LoadMasks("./masks/")
	ret.Links = []string{
		"http://qyxy.baic.gov.cn/checkCodeServlet?currentTimeMillis=1396966478094",
		"http://www.tjaic.gov.cn/info/inc/checkcode.asp",
		"http://www.hebscztxyxx.gov.cn/notice/img.captcha?ra=0.420229553245008",
		"http://218.26.1.108/Manage/VerifyCode.aspx?",
		"http://www.nmgs.gov.cn:7001/aiccips/verify.html",
		"http://222.171.175.16:9080/ECPS/validateCode.jspx",
		"http://www.jsgsj.gov.cn:58888/ecipplatform/rand_img.jsp?type=2",
		"http://gsxt.zjaic.gov.cn/common/captcha/doReadKaptcha.do",
		"http://www.ahcredit.gov.cn:9090/ECPS/validateCode.jspx",
		"http://wsgs.fjaic.gov.cn/creditpub/govRandValidate",
		"http://gsxt.jxaic.gov.cn/ECPS/rand.action",
		"http://218.57.139.24/shandong/secimg",
		"http://211.141.74.198:8081/aiccips/verify.html",
		"http://gsxt.lngs.gov.cn/saicpub/jcaptcha",
		"http://gsxt.gdgs.gov.cn/verify.html",
		"http://221.232.141.250:9080/ECPS/rand.action",
		"http://gsxt.hnaic.gov.cn/VerifierImage.jpg?noCache=1396969773230",
		"http://gsxt.cqgs.gov.cn/makeCertPic.jsp",
		"http://gsxt.gzgs.gov.cn/validCode?validTag=searchImageCode&1396969875371",
		"http://220.163.86.132:88/admin/_SYSTEM/CheckCode.aspx",
		"http://117.22.252.219:8002/servlet/validateCodeServlet",
		"http://gsxt.ngsh.gov.cn/ECPS/rand.action",
		"http://www.360doc.com/VerifyCode.aspx?",
		"https://omeo.alipay.com/service/checkcode?sessionID=b115901917504f20f792542d74ca2c4b&t=0.5697440346854534",
		"https://uac.10010.com/portal/Service/CreateImage",
		"http://www.189.cn/dqmh/createCheckCode.do?method=checkLoginCode&date=1396338767393",
		"https://ebsnew.boc.cn/BII/ImageValidation/validation1396327587558.gif",
		"https://pbank.95559.com.cn/personbank/DynImage",
		"http://reg.cntv.cn/simple/verificationCode.action?1395911362783",
		"https://ibsbjstar.ccb.com.cn/NCCB_Encoder/Encoder?CODE=Fa1IiPFNPnzuFzsa5HMG2DbNU0qB9zrNMEsBtyiNm0wmWXZcBkaeOShOVkJF70IPVUdZs0fNu0LVb6bOv0EJz3eNc0VJnAqmcG",
		"https://passport.lefeng.com/RandomCode.do?type=reg",
		"http://www.liepin.com/image/randomcode/",
		"http://gsxt.saic.gov.cn/zjgs/verify",
	}
	return &ret
}

func (self *CaptchaHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if rand.Intn(10) == 1 {
		self.Masks.Clear()
		self.Masks = LoadMasks("./masks/")
	}
	link := req.FormValue("link")
	if len(link) == 0 {
		link = self.Links[rand.Intn(len(self.Links))]
	}
	chType := GetChType(req.FormValue("type"))
	format := req.FormValue("format")
	if format == "" {
		format = "html"
	}
	img := LoadImageFromURL(link, "", "")

	output := "./imgs/" + strconv.FormatInt(time.Now().UnixNano(), 10)
	SaveImage(img, output)

	predictor := NewMetaPredictor()
	results := predictor.Predict(img, self.Masks, chType)

	if format == "html" {
		html := "
"
		for _, result := range results {
			for _, component := range result.Components{
				component.Save("./unknown/" + component.Encode())
				html += " "
			}
			html += "
"
			html += result.Label + " : " + strconv.FormatFloat(result.GetWeight(), 'g', 5, 64) + "
"
		}
		html += "Begin to Label";
		html += ""
		fmt.Fprint(w, html)
	} else if format == "json" {
		output, _ := json.Marshal(results)
		fmt.Fprint(w, string(output))
	}
}
<|endoftext|>


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

package cas

import (
	"bufio"
	"bytes"
	"crypto/sha512"
	"database/sql"
	"encoding/json"
	"fmt"
	"hash"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/coreos/rocket/Godeps/_workspace/src/github.com/appc/spec/aci"
	"github.com/coreos/rocket/Godeps/_workspace/src/github.com/appc/spec/schema"

	"github.com/coreos/rocket/Godeps/_workspace/src/github.com/peterbourgon/diskv"
)

// TODO(philips): use a database for the secondary indexes like remoteType and
// appType. This is OK for now though.
const (
	blobType int64 = iota
	imageManifestType

	defaultPathPerm os.FileMode = 0777

	// To ameliorate excessively long paths, keys for the (blob)store use
	// only the first half of a sha512 rather than the entire sum
	hashPrefix = "sha512-"
	lenHash    = sha512.Size       // raw byte size
	lenHashKey = (lenHash / 2) * 2 // half length, in hex characters
	lenKey     = len(hashPrefix) + lenHashKey
	minlenKey  = len(hashPrefix) + 2 // at least sha512-aa
)

var diskvStores = [...]string{
	"blob",
	"imageManifest",
}

// Store encapsulates a content-addressable-storage for storing ACIs on disk.
type Store struct {
	base   string
	stores []*diskv.Diskv
	db     *DB
}

func NewStore(base string) (*Store, error) {
	ds := &Store{
		base:   base,
		stores: make([]*diskv.Diskv, len(diskvStores)),
	}

	for i, p := range diskvStores {
		ds.stores[i] = diskv.New(diskv.Options{
			BasePath:  filepath.Join(base, "cas", p),
			Transform: blockTransform,
		})
	}
	db, err := NewDB(filepath.Join(base, "cas", "db"))
	if err != nil {
		return nil, err
	}
	ds.db = db

	fn := func(tx *sql.Tx) error {
		ok, err := dbIsPopulated(tx)
		if err != nil {
			return err
		}
		// populate the db
		if !ok {
			for _, stmt := range dbCreateStmts {
				_, err = tx.Exec(stmt)
				if err != nil {
					return err
				}
			}
		}
		// if db is populated check its version
		version, err := getDBVersion(tx)
		if err != nil {
			return err
		}
		if version < dbVersion {
			// TODO(sgotti) execute migration functions
			return fmt.Errorf("Current cas db version: %d lesser than the current rkt expected version: %d", version, dbVersion)
		}
		if version > dbVersion {
			return fmt.Errorf("Current cas db version: %d greater than the current rkt expected version: %d", version, dbVersion)
		}
		return nil
	}

	if err = db.Do(fn); err != nil {
		return nil, err
	}

	return ds, nil
}

func (ds Store) tmpFile() (*os.File, error) {
	dir, err := ds.tmpDir()
	if err != nil {
		return nil, err
	}
	return ioutil.TempFile(dir, "")
}

func (ds Store) tmpDir() (string, error) {
	dir := filepath.Join(ds.base, "tmp")
	if err := os.MkdirAll(dir, defaultPathPerm); err != nil {
		return "", err
	}
	return dir, nil
}

// ResolveKey resolves a partial key (of format `sha512-0c45e8c0ab2`) to a full
// key by considering the key a prefix and using the store for resolution.
// If the key is longer than the full key length, it is first truncated.
func (ds Store) ResolveKey(key string) (string, error) {
	if !strings.HasPrefix(key, hashPrefix) {
		return "", fmt.Errorf("wrong key prefix")
	}
	if len(key) < minlenKey {
		return "", fmt.Errorf("key too short")
	}
	if len(key) > lenKey {
		key = key[:lenKey]
	}

	cancel := make(chan struct{})
	var k string
	keyCount := 0
	for k = range ds.stores[blobType].KeysPrefix(key, cancel) {
		keyCount++
		if keyCount > 1 {
			close(cancel)
			break
		}
	}
	if keyCount == 0 {
		return "", fmt.Errorf("no keys found")
	}
	if keyCount != 1 {
		return "", fmt.Errorf("ambiguous key: %q", key)
	}
	return k, nil
}

func (ds Store) ReadStream(key string) (io.ReadCloser, error) {
	return ds.stores[blobType].ReadStream(key, false)
}

func (ds Store) WriteStream(key string, r io.Reader) error {
	return ds.stores[blobType].WriteStream(key, r, true)
}

// WriteACI takes an ACI encapsulated in an io.Reader, decompresses it if
// necessary, and then stores it in the store under a key based on the image ID
// (i.e. the hash of the uncompressed ACI)
func (ds Store) WriteACI(r io.Reader) (string, error) {
	// Peek at the first 512 bytes of the reader to detect filetype
	br := bufio.NewReaderSize(r, 512)
	hd, err := br.Peek(512)
	switch err {
	case nil:
	case io.EOF: // We may have still peeked enough to guess some types, so fall through
	default:
		return "", fmt.Errorf("error reading image header: %v", err)
	}
	typ, err := aci.DetectFileType(bytes.NewBuffer(hd))
	if err != nil {
		return "", fmt.Errorf("error detecting image type: %v", err)
	}
	dr, err := decompress(br, typ)
	if err != nil {
		return "", fmt.Errorf("error decompressing image: %v", err)
	}

	// Write the decompressed image (tar) to a temporary file on disk, and
	// tee so we can generate the hash
	h := sha512.New()
	tr := io.TeeReader(dr, h)
	fh, err := ds.tmpFile()
	if err != nil {
		return "", fmt.Errorf("error creating image: %v", err)
	}
	if _, err := io.Copy(fh, tr); err != nil {
		return "", fmt.Errorf("error copying image: %v", err)
	}
	im, err := aci.ManifestFromImage(fh)
	if err != nil {
		return "", fmt.Errorf("error extracting image manifest: %v", err)
	}
	if err := fh.Close(); err != nil {
		return "", fmt.Errorf("error closing image: %v", err)
	}

	// Import the uncompressed image into the store at the real key
	key := HashToKey(h)
	if err = ds.stores[blobType].Import(fh.Name(), key, true); err != nil {
		return "", fmt.Errorf("error importing image: %v", err)
	}

	// Save the imagemanifest using the same key used for the image
	imj, err := json.Marshal(im)
	if err != nil {
		return "", fmt.Errorf("error marshalling image manifest: %v", err)
	}
	if err = ds.stores[imageManifestType].Write(key, imj); err != nil {
		return "", fmt.Errorf("error importing image manifest: %v", err)
	}

	// Save aciinfo
	if err = ds.db.Do(func(tx *sql.Tx) error {
		aciinfo := &ACIInfo{
			BlobKey:    key,
			AppName:    im.Name.String(),
			ImportTime: time.Now(),
		}
		return WriteACIInfo(tx, aciinfo)
	}); err != nil {
		return "", fmt.Errorf("error writing ACI Info: %v", err)
	}
	return key, nil
}

// GetRemote tries to retrieve a remote with the given ACIURL. found will be
// false if remote doesn't exist.
func (ds Store) GetRemote(aciURL string) (*Remote, bool, error) {
	var remote *Remote
	found := false
	err := ds.db.Do(func(tx *sql.Tx) error {
		var err error
		remote, found, err = GetRemote(tx, aciURL)
		return err
	})
	return remote, found, err
}

// WriteRemote adds or updates the provided Remote.
func (ds Store) WriteRemote(remote *Remote) error {
	err := ds.db.Do(func(tx *sql.Tx) error {
		return WriteRemote(tx, remote)
	})
	return err
}

// Get the ImageManifest with the specified key.
func (ds Store) GetImageManifest(key string) (*schema.ImageManifest, error) {
	imj, err := ds.stores[imageManifestType].Read(key)
	if err != nil {
		return nil, fmt.Errorf("error retrieving image manifest: %v", err)
	}
	var im *schema.ImageManifest
	if err = json.Unmarshal(imj, &im); err != nil {
		return nil, fmt.Errorf("error unmarshalling image manifest: %v", err)
	}
	return im, nil
}

func (ds Store) Dump(hex bool) {
	for _, s := range ds.stores {
		var keyCount int
		for key := range s.Keys(nil) {
			val, err := s.Read(key)
			if err != nil {
				panic(fmt.Sprintf("key %s had no value", key))
			}
			if len(val) > 128 {
				val = val[:128]
			}
			out := string(val)
			if hex {
				out = fmt.Sprintf("%x", val)
			}
			fmt.Printf("%s/%s: %s\n", s.BasePath, key, out)
			keyCount++
		}
		fmt.Printf("%d total keys\n", keyCount)
	}
}

// HashToKey takes a hash.Hash (which currently _MUST_ represent a full SHA512),
// calculates its sum, and returns a string which should be used as the key to
// store the data matching the hash.
func HashToKey(h hash.Hash) string {
	s := h.Sum(nil)
	return keyToString(s)
}

// keyToString takes a key and returns a shortened and prefixed hexadecimal string version
func keyToString(k []byte) string {
	if len(k) != lenHash {
		panic(fmt.Sprintf("bad hash passed to hashToKey: %x", k))
	}
	return fmt.Sprintf("%s%x", hashPrefix, k)[0:lenKey]
}
<commit_msg>cas: increase reader iobuf size in WriteACI to 32KiB<commit_after>// Copyright 2014 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cas

import (
	"bufio"
	"bytes"
	"crypto/sha512"
	"database/sql"
	"encoding/json"
	"fmt"
	"hash"
	"io"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"time"

	"github.com/coreos/rocket/Godeps/_workspace/src/github.com/appc/spec/aci"
	"github.com/coreos/rocket/Godeps/_workspace/src/github.com/appc/spec/schema"

	"github.com/coreos/rocket/Godeps/_workspace/src/github.com/peterbourgon/diskv"
)

// TODO(philips): use a database for the secondary indexes like remoteType and
// appType. This is OK for now though.
const (
	blobType int64 = iota
	imageManifestType

	defaultPathPerm os.FileMode = 0777

	// To ameliorate excessively long paths, keys for the (blob)store use
	// only the first half of a sha512 rather than the entire sum
	hashPrefix = "sha512-"
	lenHash    = sha512.Size       // raw byte size
	lenHashKey = (lenHash / 2) * 2 // half length, in hex characters
	lenKey     = len(hashPrefix) + lenHashKey
	minlenKey  = len(hashPrefix) + 2 // at least sha512-aa
)

var diskvStores = [...]string{
	"blob",
	"imageManifest",
}

// Store encapsulates a content-addressable-storage for storing ACIs on disk.
type Store struct {
	base   string
	stores []*diskv.Diskv
	db     *DB
}

func NewStore(base string) (*Store, error) {
	ds := &Store{
		base:   base,
		stores: make([]*diskv.Diskv, len(diskvStores)),
	}

	for i, p := range diskvStores {
		ds.stores[i] = diskv.New(diskv.Options{
			BasePath:  filepath.Join(base, "cas", p),
			Transform: blockTransform,
		})
	}
	db, err := NewDB(filepath.Join(base, "cas", "db"))
	if err != nil {
		return nil, err
	}
	ds.db = db

	fn := func(tx *sql.Tx) error {
		ok, err := dbIsPopulated(tx)
		if err != nil {
			return err
		}
		// populate the db
		if !ok {
			for _, stmt := range dbCreateStmts {
				_, err = tx.Exec(stmt)
				if err != nil {
					return err
				}
			}
		}
		// if db is populated check its version
		version, err := getDBVersion(tx)
		if err != nil {
			return err
		}
		if version < dbVersion {
			// TODO(sgotti) execute migration functions
			return fmt.Errorf("Current cas db version: %d lesser than the current rkt expected version: %d", version, dbVersion)
		}
		if version > dbVersion {
			return fmt.Errorf("Current cas db version: %d greater than the current rkt expected version: %d", version, dbVersion)
		}
		return nil
	}

	if err = db.Do(fn); err != nil {
		return nil, err
	}

	return ds, nil
}

func (ds Store) tmpFile() (*os.File, error) {
	dir, err := ds.tmpDir()
	if err != nil {
		return nil, err
	}
	return ioutil.TempFile(dir, "")
}

func (ds Store) tmpDir() (string, error) {
	dir := filepath.Join(ds.base, "tmp")
	if err := os.MkdirAll(dir, defaultPathPerm); err != nil {
		return "", err
	}
	return dir, nil
}

// ResolveKey resolves a partial key (of format `sha512-0c45e8c0ab2`) to a full
// key by considering the key a prefix and using the store for resolution.
// If the key is longer than the full key length, it is first truncated.
func (ds Store) ResolveKey(key string) (string, error) {
	if !strings.HasPrefix(key, hashPrefix) {
		return "", fmt.Errorf("wrong key prefix")
	}
	if len(key) < minlenKey {
		return "", fmt.Errorf("key too short")
	}
	if len(key) > lenKey {
		key = key[:lenKey]
	}

	cancel := make(chan struct{})
	var k string
	keyCount := 0
	for k = range ds.stores[blobType].KeysPrefix(key, cancel) {
		keyCount++
		if keyCount > 1 {
			close(cancel)
			break
		}
	}
	if keyCount == 0 {
		return "", fmt.Errorf("no keys found")
	}
	if keyCount != 1 {
		return "", fmt.Errorf("ambiguous key: %q", key)
	}
	return k, nil
}

func (ds Store) ReadStream(key string) (io.ReadCloser, error) {
	return ds.stores[blobType].ReadStream(key, false)
}

func (ds Store) WriteStream(key string, r io.Reader) error {
	return ds.stores[blobType].WriteStream(key, r, true)
}

// WriteACI takes an ACI encapsulated in an io.Reader, decompresses it if
// necessary, and then stores it in the store under a key based on the image ID
// (i.e. the hash of the uncompressed ACI)
func (ds Store) WriteACI(r io.Reader) (string, error) {
	// Peek at the first 512 bytes of the reader to detect filetype
	br := bufio.NewReaderSize(r, 32768)
	hd, err := br.Peek(512)
	switch err {
	case nil:
	case io.EOF: // We may have still peeked enough to guess some types, so fall through
	default:
		return "", fmt.Errorf("error reading image header: %v", err)
	}
	typ, err := aci.DetectFileType(bytes.NewBuffer(hd))
	if err != nil {
		return "", fmt.Errorf("error detecting image type: %v", err)
	}
	dr, err := decompress(br, typ)
	if err != nil {
		return "", fmt.Errorf("error decompressing image: %v", err)
	}

	// Write the decompressed image (tar) to a temporary file on disk, and
	// tee so we can generate the hash
	h := sha512.New()
	tr := io.TeeReader(dr, h)
	fh, err := ds.tmpFile()
	if err != nil {
		return "", fmt.Errorf("error creating image: %v", err)
	}
	if _, err := io.Copy(fh, tr); err != nil {
		return "", fmt.Errorf("error copying image: %v", err)
	}
	im, err := aci.ManifestFromImage(fh)
	if err != nil {
		return "", fmt.Errorf("error extracting image manifest: %v", err)
	}
	if err := fh.Close(); err != nil {
		return "", fmt.Errorf("error closing image: %v", err)
	}

	// Import the uncompressed image into the store at the real key
	key := HashToKey(h)
	if err = ds.stores[blobType].Import(fh.Name(), key, true); err != nil {
		return "", fmt.Errorf("error importing image: %v", err)
	}

	// Save the imagemanifest using the same key used for the image
	imj, err := json.Marshal(im)
	if err != nil {
		return "", fmt.Errorf("error marshalling image manifest: %v", err)
	}
	if err = ds.stores[imageManifestType].Write(key, imj); err != nil {
		return "", fmt.Errorf("error importing image manifest: %v", err)
	}

	// Save aciinfo
	if err = ds.db.Do(func(tx *sql.Tx) error {
		aciinfo := &ACIInfo{
			BlobKey:    key,
			AppName:    im.Name.String(),
			ImportTime: time.Now(),
		}
		return WriteACIInfo(tx, aciinfo)
	}); err != nil {
		return "", fmt.Errorf("error writing ACI Info: %v", err)
	}
	return key, nil
}

// GetRemote tries to retrieve a remote with the given ACIURL. found will be
// false if remote doesn't exist.
func (ds Store) GetRemote(aciURL string) (*Remote, bool, error) {
	var remote *Remote
	found := false
	err := ds.db.Do(func(tx *sql.Tx) error {
		var err error
		remote, found, err = GetRemote(tx, aciURL)
		return err
	})
	return remote, found, err
}

// WriteRemote adds or updates the provided Remote.
func (ds Store) WriteRemote(remote *Remote) error {
	err := ds.db.Do(func(tx *sql.Tx) error {
		return WriteRemote(tx, remote)
	})
	return err
}

// Get the ImageManifest with the specified key.
func (ds Store) GetImageManifest(key string) (*schema.ImageManifest, error) {
	imj, err := ds.stores[imageManifestType].Read(key)
	if err != nil {
		return nil, fmt.Errorf("error retrieving image manifest: %v", err)
	}
	var im *schema.ImageManifest
	if err = json.Unmarshal(imj, &im); err != nil {
		return nil, fmt.Errorf("error unmarshalling image manifest: %v", err)
	}
	return im, nil
}

func (ds Store) Dump(hex bool) {
	for _, s := range ds.stores {
		var keyCount int
		for key := range s.Keys(nil) {
			val, err := s.Read(key)
			if err != nil {
				panic(fmt.Sprintf("key %s had no value", key))
			}
			if len(val) > 128 {
				val = val[:128]
			}
			out := string(val)
			if hex {
				out = fmt.Sprintf("%x", val)
			}
			fmt.Printf("%s/%s: %s\n", s.BasePath, key, out)
			keyCount++
		}
		fmt.Printf("%d total keys\n", keyCount)
	}
}

// HashToKey takes a hash.Hash (which currently _MUST_ represent a full SHA512),
// calculates its sum, and returns a string which should be used as the key to
// store the data matching the hash.
func HashToKey(h hash.Hash) string {
	s := h.Sum(nil)
	return keyToString(s)
}

// keyToString takes a key and returns a shortened and prefixed hexadecimal string version
func keyToString(k []byte) string {
	if len(k) != lenHash {
		panic(fmt.Sprintf("bad hash passed to hashToKey: %x", k))
	}
	return fmt.Sprintf("%s%x", hashPrefix, k)[0:lenKey]
}
<|endoftext|>


<commit_before>// Copyright 2015 The caslock 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 caslock

import (
	"errors"
	"fmt"
	"log"
	"time"

	"github.com/gocql/gocql"
)

var (
	// LockColumn is the name of the column used to control row locks. It
	// must added to the desired column family before using caslock.
	LockColumn = "[lock]"

	// RetryTime is time beteween retries when a row has been locked by
	// another process.
	RetryTime = 500 * time.Millisecond

	// Log is the logger used to register warnings and info messages. If it is nil,
	// no messages will be logged.
	Log *log.Logger
)

// Lock represents a cassandra's row lock.
type Lock struct {
	lockID   gocql.UUID
	keyspace string
	table    string
	rowKeys  []interface{}
	ttl      time.Duration
	timeout  time.Duration
	session  *gocql.Session
}

var errTimeout = errors.New("cannot satisfy timeout value")

// Acquire locks the rows in rowKeys on the table keyspace.table. The parameter
// timeout defines the minimum time that the rows will locked before being
// automatically released.
func Acquire(session *gocql.Session, keyspace, table string, timeout time.Duration, rowKeys ...interface{}) (*Lock, error) {
	l := &Lock{
		lockID:   gocql.TimeUUID(),
		keyspace: keyspace,
		table:    table,
		rowKeys:  rowKeys,
		ttl:      timeout * 2,
		timeout:  timeout,
		session:  session,
	}

loop:
	for {
		switch err := l.acquireLoop(); err {
		case nil:
			break loop
		case errTimeout:
			continue loop
		default:
			return nil, err
		}
	}
	return l, nil
}

func (l *Lock) acquireLoop() error {
	var maxTime time.Time
	for i, k := range l.rowKeys {
		for {
			if i == 0 {
				maxTime = time.Now().Add(l.ttl)
			} else if maxTime.Sub(time.Now()) < l.timeout {
				logf("cannot satisfy timeout, restarting acquire")
				l.Release()
				return errTimeout
			}

			applied, err := l.lockRow(k)
			if err != nil {
				l.Release()
				return err
			}
			if applied {
				break
			}

			// check if the rows really exist before retrying
			if err := l.checkRows(); err != nil {
				l.Release()
				return err
			}

			time.Sleep(RetryTime)
		}
	}
	return nil
}

func (l *Lock) lockRow(row interface{}) (applied bool, err error) {
	var prevLockID gocql.UUID
	q := fmt.Sprintf("UPDATE %q.%q USING TTL ? SET %q = ?"+
		" WHERE id = ? IF %q = null",
		l.keyspace, l.table, LockColumn, LockColumn)
	applied, err = l.session.Query(q, int(l.ttl.Seconds()),
		l.lockID, row).ScanCAS(&prevLockID)
	if !applied {
		logf("cannot lock row: lock key=%v lockID=%v prevLockID=%v\n",
			row, l.lockID, prevLockID)
	}
	return
}

func (l *Lock) checkRows() error {
	var countRows int
	q := fmt.Sprintf("SELECT COUNT(*) FROM %q.%q WHERE id in ?",
		l.keyspace, l.table)
	if err := l.session.Query(q, l.rowKeys).Scan(&countRows); err != nil {
		return err
	}
	if countRows != len(l.rowKeys) {
		return errors.New("key not found")
	}
	return nil
}

// Release releases the lock.
func (l *Lock) Release() error {
	for _, k := range l.rowKeys {
		q := fmt.Sprintf("UPDATE %q.%q SET %q = null WHERE id = ? IF %q = ?",
			l.keyspace, l.table, LockColumn, LockColumn)
		if _, err := l.session.Query(q, k, l.lockID).ScanCAS(); err != nil {
			return err
		}
	}
	return nil
}

func logf(format string, args ...interface{}) {
	if Log == nil {
		return
	}
	Log.Printf(format, args...)
}
<commit_msg>Fix typo in doc<commit_after>// Copyright 2015 The caslock 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 caslock

import (
	"errors"
	"fmt"
	"log"
	"time"

	"github.com/gocql/gocql"
)

var (
	// LockColumn is the name of the column used to control row locks. It
	// must added to the desired column family before using caslock.
	LockColumn = "[lock]"

	// RetryTime is the time beteween retries when a row has been locked by
	// another process.
	RetryTime = 500 * time.Millisecond

	// Log is the logger used to register warnings and info messages. If it is nil,
	// no messages will be logged.
	Log *log.Logger
)

// Lock represents a cassandra's row lock.
type Lock struct {
	lockID   gocql.UUID
	keyspace string
	table    string
	rowKeys  []interface{}
	ttl      time.Duration
	timeout  time.Duration
	session  *gocql.Session
}

var errTimeout = errors.New("cannot satisfy timeout value")

// Acquire locks the rows in rowKeys on the table keyspace.table. The parameter
// timeout defines the minimum time that the rows will locked before being
// automatically released.
func Acquire(session *gocql.Session, keyspace, table string, timeout time.Duration, rowKeys ...interface{}) (*Lock, error) {
	l := &Lock{
		lockID:   gocql.TimeUUID(),
		keyspace: keyspace,
		table:    table,
		rowKeys:  rowKeys,
		ttl:      timeout * 2,
		timeout:  timeout,
		session:  session,
	}

loop:
	for {
		switch err := l.acquireLoop(); err {
		case nil:
			break loop
		case errTimeout:
			continue loop
		default:
			return nil, err
		}
	}
	return l, nil
}

func (l *Lock) acquireLoop() error {
	var maxTime time.Time
	for i, k := range l.rowKeys {
		for {
			if i == 0 {
				maxTime = time.Now().Add(l.ttl)
			} else if maxTime.Sub(time.Now()) < l.timeout {
				logf("cannot satisfy timeout, restarting acquire")
				l.Release()
				return errTimeout
			}

			applied, err := l.lockRow(k)
			if err != nil {
				l.Release()
				return err
			}
			if applied {
				break
			}

			// check if the rows really exist before retrying
			if err := l.checkRows(); err != nil {
				l.Release()
				return err
			}

			time.Sleep(RetryTime)
		}
	}
	return nil
}

func (l *Lock) lockRow(row interface{}) (applied bool, err error) {
	var prevLockID gocql.UUID
	q := fmt.Sprintf("UPDATE %q.%q USING TTL ? SET %q = ?"+
		" WHERE id = ? IF %q = null",
		l.keyspace, l.table, LockColumn, LockColumn)
	applied, err = l.session.Query(q, int(l.ttl.Seconds()),
		l.lockID, row).ScanCAS(&prevLockID)
	if !applied {
		logf("cannot lock row: lock key=%v lockID=%v prevLockID=%v\n",
			row, l.lockID, prevLockID)
	}
	return
}

func (l *Lock) checkRows() error {
	var countRows int
	q := fmt.Sprintf("SELECT COUNT(*) FROM %q.%q WHERE id in ?",
		l.keyspace, l.table)
	if err := l.session.Query(q, l.rowKeys).Scan(&countRows); err != nil {
		return err
	}
	if countRows != len(l.rowKeys) {
		return errors.New("key not found")
	}
	return nil
}

// Release releases the lock.
func (l *Lock) Release() error {
	for _, k := range l.rowKeys {
		q := fmt.Sprintf("UPDATE %q.%q SET %q = null WHERE id = ? IF %q = ?",
			l.keyspace, l.table, LockColumn, LockColumn)
		if _, err := l.session.Query(q, k, l.lockID).ScanCAS(); err != nil {
			return err
		}
	}
	return nil
}

func logf(format string, args ...interface{}) {
	if Log == nil {
		return
	}
	Log.Printf(format, args...)
}
<|endoftext|>


<commit_before>package graph

import (
	"strconv"
	"os"
	"time"
)

// A Facebook Page.
// http://developers.facebook.com/docs/reference/api/page
type Page struct {
	// ID
	ID string
	// Name
	Name string
	// Profile picture
	Picture string
	// Category
	Category string
	// Number of fans the page has
	FanCount float64

	// Undocumented properties but streamed
	Link            string
	Website         string
	Username        string
	Founded         *time.Time
	CompanyOverview string
	Mission         string
	Products        string
	feed            string
	picture         string
	tagged          string
	links           string
	photos          string
	groups          string // Not yet implemented
	albums          string
	statuses        string
	videos          string
	notes           string
	posts           string
	events          string
	checkins        string
}

// Gets the page's wall. Available to everyone on Facebook.
// Returns an array of Post objects.
func (p *Page) GetWall() (ps []Post, err os.Error) {
	if p.feed == "" {
		err = os.NewError("Error: Page.GetWall: The feed URL is empty.")
	}
	return fetchPosts(p.feed)
}

// Gets the page's profile picture. Publicly available.
// Returns an HTTP 302 URL string with the location set to the picture URL.
func (p *Page) GetPicture() (pic *Picture, err os.Error) {
	if p.picture == "" {
		err = os.NewError("Error: Page.GetPicture: The picture URL is empty.")
	}
	return NewPicture(p.picture), err
}

// Gets the photos, videos, and posts in which this page has been tagged. Publicly available.
// Returns an heterogeneous array of Photo, Video or Post objects.
func (p *Page) GetTagged() (t []interface{}, err os.Error) {
	if p.tagged == "" {
		err = os.NewError("Error: Page.GetTagged: The tagged URL is empty.")
	}
	data, err := getData(p.tagged)
	if err != nil {
		return
	}
	t = make([]interface{}, len(data))
	for i, v := range data {
		tag := v.(map[string]interface{})
		switch tag["type"].(string) {
		case "status":
			t[i], err = parsePost(tag)
			if err != nil {
				return
			}
		case "link":
		case "photo":
			t[i], err = parsePhoto(tag)
			if err != nil {
				return
			}
		case "video":
			t[i], err = parseVideo(tag)
			if err != nil {
				return
			}
		}
	}
	return
}

// Gets the page's posted links. Publicly available.
// Returns an array of Link objects.
func (p *Page) GetLinks() (ls []Link, err os.Error) {
	if p.links == "" {
		err = os.NewError("Error: Page.GetLinks: The links URL is empty.")
	}
	return getLinks(p.links)
}

// Gets the photos this page has uploaded. Publicly available.
// Returns an array of Photo objects.
func (p *Page) GetPhotos() (ps []Photo, err os.Error) {
	if p.photos == "" {
		err = os.NewError("Error: Page.GetPhotos: The photos URL is empty.")
	}
	return getPhotos(p.photos)
}

// Gets the groups this page is a member of. Available to everyone on Facebook.
// Returns an array of objects containing group id, version, name and unread fields.
// TODO: function for GetGroups

// Gets the page albums this page has created. Publicly available.
// Returns an array of Album objects.
func (p *Page) GetAlbums() (as []Album, err os.Error) {
	if p.albums == "" {
		err = os.NewError("Error: Page.GetAlbums: The albums URL is empty.")
	}
	return getAlbums(p.albums)
}

// Gets the page's status updates. Publicly available.
// Returns an array of StatusMessage objects.
func (p *Page) GetStatuses() (sms []StatusMessage, err os.Error) {
	if p.statuses == "" {
		err = os.NewError("Error: Page.GetStatuses: The statuses URL is empty.")
	}
	return getStatusMessages(p.statuses)
}

// Gets the videos this page has created. Publicly available.
// Returns an array of Video objects.
func (p *Page) GetVideos() (vs []Video, err os.Error) {
	if p.videos == "" {
		err = os.NewError("Error: Page.GetVideos: The videos URL is empty.")
	}
	return getVideos(p.videos)
}

// Gets the page's notes. Publicly available.
// Returns an array of Note objects.
func (p *Page) GetNotes() (ns []Note, err os.Error) {
	if p.notes == "" {
		err = os.NewError("Error: Page.GetNotes: The notes URL is empty.")
	}
	return getNotes(p.notes)
}

// Gets the page's own posts. Publicly available.
// Returns an array of Post objects.
func (p *Page) GetPosts() (feed []Post, err os.Error) {
	if p.posts == "" {
		err = os.NewError("Error: Page.GetPosts: The posts URL is empty.")
	}
	return fetchPosts(p.posts)
}

// Gets the events this page is managing. Publicly available.
// Returns an array of Event objects.
func (p *Page) GetEvents() (es []Event, err os.Error) {
	if p.events == "" {
		err = os.NewError("Error: Page.GetEvents: The events URL is empty.")
	}
	return getEvents(p.events)
}

// Gets Checkins made by friends of the current session user. Requires friends_checkins permissions.
// Returns an array of Checkin objects.
func (p *Page) GetCheckins() (cs []Checkin, err os.Error) {
	if p.checkins == "" {
		err = os.NewError("Error: Page.GetCheckins: The checkins URL is empty.")
	}
	return getCheckins(p.checkins)
}

func (p *Page) String() string {
	return "ID: " + p.ID + "\tName: " + p.Name + "\tPicture: " + p.Picture +
		"\tLink: " + p.Link + "\tCategory: " + p.Category + "\tWebsite: " +
		p.Website + "\tUsername: " + p.Username + "\tFounded: " + p.Founded.String() +
		"\tCompany overview: " + p.CompanyOverview + "\tMission: " + p.Mission +
		"\tProducts: " + p.Products + "\tFan count:" +
		strconv.Ftoa64(p.FanCount, 'e', -1) + "\n"
}

func parsePage(data map[string]interface{}) (p Page, err os.Error) {
	for key, value := range data {
		switch key {
		case "website":
			p.Website = value.(string)
		case "picture":
			p.Picture = value.(string)
		case "fan_count":
			p.FanCount = value.(float64)
		case "mission":
			p.Mission = value.(string)
		case "category":
			p.Category = value.(string)
		case "name":
			p.Name = value.(string)
		case "username":
			p.Username = value.(string)
		case "link":
			p.Link = value.(string)
		case "id":
			p.ID = value.(string)
		case "products":
			p.Products = value.(string)
		case "founded":
			p.Founded, err = parseTime(value.(string))
		case "company_overview":
			p.CompanyOverview = value.(string)
		case "type":
			// TODO: Look into type
		case "metadata":
			// TODO: get and parse connections
		default:
			debugInterface(value, key, "Page")
		}
	}
	return
}
<commit_msg>Add metadata.connections parsing to Page.<commit_after>package graph

import (
	"strconv"
	"os"
	"time"
)

// A Facebook Page.
// http://developers.facebook.com/docs/reference/api/page
type Page struct {
	// ID
	ID string
	// Name
	Name string
	// Profile picture
	Picture string
	// Category
	Category string
	// Number of fans the page has
	FanCount float64

	// Undocumented properties but streamed
	Link            string
	Website         string
	Username        string
	Founded         *time.Time
	CompanyOverview string
	Mission         string
	Products        string

	// Connections
	feed     string
	picture  string
	tagged   string
	links    string
	photos   string
	groups   string // Not yet implemented
	albums   string
	statuses string
	videos   string
	notes    string
	posts    string
	events   string
	checkins string
}

// Gets the page's wall. Available to everyone on Facebook.
// Returns an array of Post objects.
func (p *Page) GetWall() (ps []Post, err os.Error) {
	if p.feed == "" {
		err = os.NewError("Error: Page.GetWall: The feed URL is empty.")
	}
	return fetchPosts(p.feed)
}

// Gets the page's profile picture. Publicly available.
// Returns an HTTP 302 URL string with the location set to the picture URL.
func (p *Page) GetPicture() (pic *Picture, err os.Error) {
	if p.picture == "" {
		err = os.NewError("Error: Page.GetPicture: The picture URL is empty.")
	}
	return NewPicture(p.picture), err
}

// Gets the photos, videos, and posts in which this page has been tagged. Publicly available.
// Returns an heterogeneous array of Photo, Video or Post objects.
func (p *Page) GetTagged() (t []interface{}, err os.Error) {
	if p.tagged == "" {
		err = os.NewError("Error: Page.GetTagged: The tagged URL is empty.")
	}
	data, err := getData(p.tagged)
	if err != nil {
		return
	}
	t = make([]interface{}, len(data))
	for i, v := range data {
		tag := v.(map[string]interface{})
		switch tag["type"].(string) {
		case "status":
			t[i], err = parsePost(tag)
			if err != nil {
				return
			}
		case "link":
		case "photo":
			t[i], err = parsePhoto(tag)
			if err != nil {
				return
			}
		case "video":
			t[i], err = parseVideo(tag)
			if err != nil {
				return
			}
		}
	}
	return
}

// Gets the page's posted links. Publicly available.
// Returns an array of Link objects.
func (p *Page) GetLinks() (ls []Link, err os.Error) {
	if p.links == "" {
		err = os.NewError("Error: Page.GetLinks: The links URL is empty.")
	}
	return getLinks(p.links)
}

// Gets the photos this page has uploaded. Publicly available.
// Returns an array of Photo objects.
func (p *Page) GetPhotos() (ps []Photo, err os.Error) {
	if p.photos == "" {
		err = os.NewError("Error: Page.GetPhotos: The photos URL is empty.")
	}
	return getPhotos(p.photos)
}

// Gets the groups this page is a member of. Available to everyone on Facebook.
// Returns an array of objects containing group id, version, name and unread fields.
// TODO: function for GetGroups

// Gets the page albums this page has created. Publicly available.
// Returns an array of Album objects.
func (p *Page) GetAlbums() (as []Album, err os.Error) {
	if p.albums == "" {
		err = os.NewError("Error: Page.GetAlbums: The albums URL is empty.")
	}
	return getAlbums(p.albums)
}

// Gets the page's status updates. Publicly available.
// Returns an array of StatusMessage objects.
func (p *Page) GetStatuses() (sms []StatusMessage, err os.Error) {
	if p.statuses == "" {
		err = os.NewError("Error: Page.GetStatuses: The statuses URL is empty.")
	}
	return getStatusMessages(p.statuses)
}

// Gets the videos this page has created. Publicly available.
// Returns an array of Video objects.
func (p *Page) GetVideos() (vs []Video, err os.Error) {
	if p.videos == "" {
		err = os.NewError("Error: Page.GetVideos: The videos URL is empty.")
	}
	return getVideos(p.videos)
}

// Gets the page's notes. Publicly available.
// Returns an array of Note objects.
func (p *Page) GetNotes() (ns []Note, err os.Error) {
	if p.notes == "" {
		err = os.NewError("Error: Page.GetNotes: The notes URL is empty.")
	}
	return getNotes(p.notes)
}

// Gets the page's own posts. Publicly available.
// Returns an array of Post objects.
func (p *Page) GetPosts() (feed []Post, err os.Error) {
	if p.posts == "" {
		err = os.NewError("Error: Page.GetPosts: The posts URL is empty.")
	}
	return fetchPosts(p.posts)
}

// Gets the events this page is managing. Publicly available.
// Returns an array of Event objects.
func (p *Page) GetEvents() (es []Event, err os.Error) {
	if p.events == "" {
		err = os.NewError("Error: Page.GetEvents: The events URL is empty.")
	}
	return getEvents(p.events)
}

// Gets Checkins made by friends of the current session user. Requires friends_checkins permissions.
// Returns an array of Checkin objects.
func (p *Page) GetCheckins() (cs []Checkin, err os.Error) {
	if p.checkins == "" {
		err = os.NewError("Error: Page.GetCheckins: The checkins URL is empty.")
	}
	return getCheckins(p.checkins)
}

func (p *Page) String() string {
	return "ID: " + p.ID + "\tName: " + p.Name + "\tPicture: " + p.Picture +
		"\tLink: " + p.Link + "\tCategory: " + p.Category + "\tWebsite: " +
		p.Website + "\tUsername: " + p.Username + "\tFounded: " + p.Founded.String() +
		"\tCompany overview: " + p.CompanyOverview + "\tMission: " + p.Mission +
		"\tProducts: " + p.Products + "\tFan count:" +
		strconv.Ftoa64(p.FanCount, 'e', -1) + "\n"
}

func parsePage(data map[string]interface{}) (p Page, err os.Error) {
	for key, value := range data {
		switch key {
		case "website":
			p.Website = value.(string)
		case "picture":
			p.Picture = value.(string)
		case "fan_count":
			p.FanCount = value.(float64)
		case "mission":
			p.Mission = value.(string)
		case "category":
			p.Category = value.(string)
		case "name":
			p.Name = value.(string)
		case "username":
			p.Username = value.(string)
		case "link":
			p.Link = value.(string)
		case "id":
			p.ID = value.(string)
		case "products":
			p.Products = value.(string)
		case "founded":
			p.Founded, err = parseTime(value.(string))
		case "company_overview":
			p.CompanyOverview = value.(string)
		case "metadata":
			metadata := value.(map[string]interface{})
			for k, va := range metadata["connections"].(map[string]interface{}) {
				switch k {
				case "feed":
					p.feed = va.(string)
				case "picture":
					p.picture = va.(string)
				case "links":
					p.links = va.(string)
				case "photos":
					p.photos = va.(string)
				case "groups":
					p.groups = va.(string)
				case "albums":
					p.albums = va.(string)
				case "statuses":
					p.statuses = va.(string)
				case "videos":
					p.videos = va.(string)
				case "notes":
					p.notes = va.(string)
				case "posts":
					p.notes = va.(string)
				case "events":
					p.events = va.(string)
				case "checkins":
					p.checkins = va.(string)
				}
			}
		}
	}
	return
}
<|endoftext|>


<commit_before>// Copyright 2012, Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package sqlparser

// analyzer.go contains utility analysis functions.

import (
	"fmt"

	"github.com/youtube/vitess/go/sqltypes"
)

// GetTableName returns the table name from the SimpleTableExpr
// only if it's a simple expression. Otherwise, it returns "".
func GetTableName(node SimpleTableExpr) string {
	if n, ok := node.(*TableName); ok && n.Qualifier == nil {
		return string(n.Name)
	}
	// sub-select or '.' expression
	return ""
}

// GetColName returns the column name, only if
// it's a simple expression. Otherwise, it returns "".
func GetColName(node Expr) string {
	if n, ok := node.(*ColName); ok {
		return string(n.Name)
	}
	return ""
}

// IsColName returns true if the ValExpr is a *ColName.
func IsColName(node ValExpr) bool {
	_, ok := node.(*ColName)
	return ok
}

// IsValue returns true if the ValExpr is a string, number or value arg.
// NULL is not considered to be a value.
func IsValue(node ValExpr) bool {
	switch node.(type) {
	case StrVal, NumVal, ValArg:
		return true
	}
	return false
}

// HasINCaluse returns true if any of the conditions has an IN clause.
func HasINClause(conditions []BoolExpr) bool {
	for _, node := range conditions {
		if c, ok := node.(*ComparisonExpr); ok && c.Operator == AST_IN {
			return true
		}
	}
	return false
}

// IsSimpleTuple returns true if the ValExpr is a ValTuple that
// contains simple values or if it's a list arg.
func IsSimpleTuple(node ValExpr) bool {
	switch vals := node.(type) {
	case ValTuple:
		for _, n := range vals {
			if !IsValue(n) {
				return false
			}
		}
		return true
	case ListArg:
		return true
	}
	// It's a subquery
	return false
}

// AsInterface converts the ValExpr to an interface. It converts
// ValTuple to []interface{}, ValArg to string, StrVal to sqltypes.String,
// NumVal to sqltypes.Numeric, NullVal to nil.
// Otherwise, it returns an error.
func AsInterface(node ValExpr) (interface{}, error) {
	switch node := node.(type) {
	case ValTuple:
		vals := make([]interface{}, 0, len(node))
		for _, val := range node {
			v, err := AsInterface(val)
			if err != nil {
				return nil, err
			}
			vals = append(vals, v)
		}
		return vals, nil
	case ValArg:
		return string(node), nil
	case ListArg:
		return string(node), nil
	case StrVal:
		return sqltypes.MakeString(node), nil
	case NumVal:
		n, err := sqltypes.BuildNumeric(string(node))
		if err != nil {
			return nil, fmt.Errorf("type mismatch: %s", err)
		}
		return n, nil
	case *NullVal:
		return nil, nil
	}
	return nil, fmt.Errorf("unexpected node %v", node)
}

// StringIn is a convenience function that returns
// true if str matches any of the values.
func StringIn(str string, values ...string) bool {
	for _, val := range values {
		if str == val {
			return true
		}
	}
	return false
}
<commit_msg>renameされた sqltypes.BuildIntegral<commit_after>// Copyright 2012, Google Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package sqlparser

// analyzer.go contains utility analysis functions.

import (
	"fmt"

	"github.com/youtube/vitess/go/sqltypes"
)

// GetTableName returns the table name from the SimpleTableExpr
// only if it's a simple expression. Otherwise, it returns "".
func GetTableName(node SimpleTableExpr) string {
	if n, ok := node.(*TableName); ok && n.Qualifier == nil {
		return string(n.Name)
	}
	// sub-select or '.' expression
	return ""
}

// GetColName returns the column name, only if
// it's a simple expression. Otherwise, it returns "".
func GetColName(node Expr) string {
	if n, ok := node.(*ColName); ok {
		return string(n.Name)
	}
	return ""
}

// IsColName returns true if the ValExpr is a *ColName.
func IsColName(node ValExpr) bool {
	_, ok := node.(*ColName)
	return ok
}

// IsValue returns true if the ValExpr is a string, number or value arg.
// NULL is not considered to be a value.
func IsValue(node ValExpr) bool {
	switch node.(type) {
	case StrVal, NumVal, ValArg:
		return true
	}
	return false
}

// HasINCaluse returns true if any of the conditions has an IN clause.
func HasINClause(conditions []BoolExpr) bool {
	for _, node := range conditions {
		if c, ok := node.(*ComparisonExpr); ok && c.Operator == AST_IN {
			return true
		}
	}
	return false
}

// IsSimpleTuple returns true if the ValExpr is a ValTuple that
// contains simple values or if it's a list arg.
func IsSimpleTuple(node ValExpr) bool {
	switch vals := node.(type) {
	case ValTuple:
		for _, n := range vals {
			if !IsValue(n) {
				return false
			}
		}
		return true
	case ListArg:
		return true
	}
	// It's a subquery
	return false
}

// AsInterface converts the ValExpr to an interface. It converts
// ValTuple to []interface{}, ValArg to string, StrVal to sqltypes.String,
// NumVal to sqltypes.Numeric, NullVal to nil.
// Otherwise, it returns an error.
func AsInterface(node ValExpr) (interface{}, error) {
	switch node := node.(type) {
	case ValTuple:
		vals := make([]interface{}, 0, len(node))
		for _, val := range node {
			v, err := AsInterface(val)
			if err != nil {
				return nil, err
			}
			vals = append(vals, v)
		}
		return vals, nil
	case ValArg:
		return string(node), nil
	case ListArg:
		return string(node), nil
	case StrVal:
		return sqltypes.MakeString(node), nil
	case NumVal:
		n, err := sqltypes.BuildIntegral(string(node))
		if err != nil {
			return nil, fmt.Errorf("type mismatch: %s", err)
		}
		return n, nil
	case *NullVal:
		return nil, nil
	}
	return nil, fmt.Errorf("unexpected node %v", node)
}

// StringIn is a convenience function that returns
// true if str matches any of the values.
func StringIn(str string, values ...string) bool {
	for _, val := range values {
		if str == val {
			return true
		}
	}
	return false
}
<|endoftext|>


<commit_before>package main
<commit_msg>quicksort-pt-1 main method skeleton<commit_after>package main

import (
	"strings"
	"fmt"
	"github.com/samurang87/playground_go"
)

func main() {

	input := hackerrank_utils.Read()

	for _, item := range input[1:] {

		d := strings.Split(item, " ")
		fmt.Println(d)

	}

}
<|endoftext|>


<commit_before>package emoji

import (
	"bytes"
	"fmt"
	"math"
	"strings"
	"sync"
	"testing"
)

const (
	beerKey  = ":beer:"
	beerText = " ビール!!!"
	flag     = ":flag-us:"
	plusOne  = ":+1:"
)

var testFText = "test " + emojize(beerKey) + beerText
var testText = emojize(beerKey) + beerText

func TestFlag(t *testing.T) {
	f := emojize(flag)
	expected := "\U0001f1fA\U0001f1f8"
	if f != expected {
		t.Error("emojize ", f, "!=", expected)
	}
}

func TestPlusOne(t *testing.T) {
	f := emojize(plusOne)
	expected := "\U0001f44d "
	if f != expected {
		t.Error("emojize ", f, "!=", expected)
	}
}

func TestMultiColons(t *testing.T) {
	var buf bytes.Buffer
	_, err := Fprint(&buf, "A :smile: and another: :smile:")
	if err != nil {
		t.Error("Fprint ", err)
	}

	testCase := "A " + emojize(":smile:") + " and another: " + emojize(":smile:")
	if buf.String() != testCase {
		t.Error("Fprint ", buf.String(), "!=", testCase)
	}
}

func TestContinuityColons(t *testing.T) {
	var buf bytes.Buffer
	_, err := Fprint(&buf, "::smile:")
	if err != nil {
		t.Error("Fprint ", err)
	}

	testCase := ":" + emojize(":smile:")
	if buf.String() != testCase {
		t.Error("Fprint ", buf.String(), "!=", testCase)
	}
}

func TestCodeMap(t *testing.T) {
	m := CodeMap()
	if &emojiCodeMap == &m {
		t.Error("emojiCodeMap != EmojiCodeMap")
	}
}

func TestRevCodeMap(t *testing.T) {
	m := RevCodeMap()
	if &emojiRevCodeMap == &m {
		t.Error("emojiRevCodeMap != EmojiRevCodeMap")
	}
}

func TestHasAlias(t *testing.T) {
	hasAlias := HasAlias(":+1:")
	if !hasAlias {
		t.Error(":+1: doesn't have an alias")
	}
	hasAlias = HasAlias(":no-good:")
	if hasAlias {
		t.Error(":no-good: has an alias")
	}
}

func TestNoramlizeShortCode(t *testing.T) {
	test := ":thumbs_up:"
	expected := ":+1:"
	normalized := NormalizeShortCode(test)
	if normalized != expected {
		t.Errorf("Normalized %q != %q", test, expected)
	}
	test = ":no-good:"
	normalized = NormalizeShortCode(test)
	if normalized != test {
		t.Errorf("Normalized %q != %q", test, normalized)
	}
}

func TestPrint(t *testing.T) {
	_, err := Print(beerKey, beerText)
	if err != nil {
		t.Error("Print ", err)
	}
}

func TestPrintln(t *testing.T) {
	_, err := Println(beerKey, beerText)
	if err != nil {
		t.Error("Println ", err)
	}
}

func TestPrintf(t *testing.T) {
	_, err := Printf("%s "+beerKey+beerText, "test")
	if err != nil {
		t.Error("Printf ", err)
	}
}

func TestFprint(t *testing.T) {
	var buf bytes.Buffer
	_, err := Fprint(&buf, beerKey+beerText)
	if err != nil {
		t.Error("Fprint ", err)
	}

	if buf.String() != testText {
		t.Error("Fprint ", buf.String(), testText)
	}
}

func TestFprintln(t *testing.T) {
	var buf bytes.Buffer
	_, err := Fprintln(&buf, beerKey+beerText)
	if err != nil {
		t.Error("Fprintln ", err)
	}

	if buf.String() != (testText + "\n") {
		t.Error("Fprintln ", buf.String(), (testText + "\n"))
	}
}

func TestFprintf(t *testing.T) {
	var buf bytes.Buffer
	_, err := Fprintf(&buf, "%s "+beerKey+beerText, "test")
	if err != nil {
		t.Error("Fprintf ", err)
	}

	if buf.String() != testFText {
		t.Error("Fprintf ", buf.String(), testFText)
	}
}

func TestSprint(t *testing.T) {
	convertBeer := Sprint(beerKey, beerText)
	if convertBeer != testText {
		t.Error("Sprint ", convertBeer, testText)
	}
}

func TestSprintf(t *testing.T) {
	convertBeer := Sprintf("%s "+beerKey+beerText, "test")
	if convertBeer != testFText {
		t.Error("Sprintf ", convertBeer, testFText)
	}
}

func TestErrorf(t *testing.T) {
	error := Errorf("%s "+beerKey+beerText, "test")
	if error.Error() != testFText {
		t.Error("Errorf ", error, testFText)
	}
}

func TestSprintMulti(t *testing.T) {
	convertBeer := Sprint(beerKey, beerText, beerKey, beerText)
	if convertBeer != (testText + testText) {
		t.Error("Sprint ", convertBeer, testText)
	}
	fmt.Println(convertBeer)
}

// Copyright 2016 The Hugo Authors. All rights reserved.
// source: https://github.com/spf13/hugo/blob/master/helpers/emoji_test.go

func BenchmarkFprint(b *testing.B) {
	f := func(in []byte) []byte {
		buff := getBuffer()
		defer putBuffer(buff)
		Fprint(buff, string(in))

		bc := make([]byte, buff.Len())
		copy(bc, buff.Bytes())
		return bc
	}

	doBenchmarkEmoji(b, f)
}

func BenchmarkSprint(b *testing.B) {
	f := func(in []byte) []byte {
		return []byte(Sprint(string(in)))
	}

	doBenchmarkEmoji(b, f)
}

func doBenchmarkEmoji(b *testing.B, f func(in []byte) []byte) {
	type input struct {
		in     []byte
		expect []byte
	}

	data := []struct {
		input  string
		expect string
	}{
		{"A :smile: a day", Sprint("A :smile: a day")},
		{"A :smile: and a :beer: day keeps the doctor away", Sprint("A :smile: and a :beer: day keeps the doctor away")},
		{"A :smile: a day and 10 " + strings.Repeat(":beer: ", 10), Sprint("A :smile: a day and 10 " + strings.Repeat(":beer: ", 10))},
		{"No smiles today.", "No smiles today."},
		{"No smiles for you or " + strings.Repeat("you ", 1000), "No smiles for you or " + strings.Repeat("you ", 1000)},
	}

	var in = make([]input, b.N*len(data))
	var cnt = 0
	for i := 0; i < b.N; i++ {
		for _, this := range data {
			in[cnt] = input{[]byte(this.input), []byte(this.expect)}
			cnt++
		}
	}

	b.ResetTimer()
	cnt = 0
	for i := 0; i < b.N; i++ {
		for j := range data {
			currIn := in[cnt]
			cnt++
			result := f(currIn.in)
			// The Emoji implementations gives slightly different output.
			diffLen := len(result) - len(currIn.expect)
			diffLen = int(math.Abs(float64(diffLen)))
			if diffLen > 30 {
				b.Fatalf("[%d] emoji std, got \n%q but expected \n%q", j, result, currIn.expect)
			}
		}
	}
}

var bufferPool = &sync.Pool{
	New: func() interface{} {
		return &bytes.Buffer{}
	},
}

func getBuffer() (buf *bytes.Buffer) {
	return bufferPool.Get().(*bytes.Buffer)
}

func putBuffer(buf *bytes.Buffer) {
	buf.Reset()
	bufferPool.Put(buf)
}
<commit_msg>fix lint<commit_after>package emoji

import (
	"bytes"
	"fmt"
	"math"
	"strings"
	"sync"
	"testing"
)

const (
	beerKey  = ":beer:"
	beerText = " ビール!!!"
	flag     = ":flag-us:"
	plusOne  = ":+1:"
)

var testFText = "test " + emojize(beerKey) + beerText
var testText = emojize(beerKey) + beerText

func TestFlag(t *testing.T) {
	f := emojize(flag)
	expected := "\U0001f1fA\U0001f1f8"
	if f != expected {
		t.Error("emojize ", f, "!=", expected)
	}
}

func TestPlusOne(t *testing.T) {
	f := emojize(plusOne)
	expected := "\U0001f44d "
	if f != expected {
		t.Error("emojize ", f, "!=", expected)
	}
}

func TestMultiColons(t *testing.T) {
	var buf bytes.Buffer
	_, err := Fprint(&buf, "A :smile: and another: :smile:")
	if err != nil {
		t.Error("Fprint ", err)
	}

	testCase := "A " + emojize(":smile:") + " and another: " + emojize(":smile:")
	if buf.String() != testCase {
		t.Error("Fprint ", buf.String(), "!=", testCase)
	}
}

func TestContinuityColons(t *testing.T) {
	var buf bytes.Buffer
	_, err := Fprint(&buf, "::smile:")
	if err != nil {
		t.Error("Fprint ", err)
	}

	testCase := ":" + emojize(":smile:")
	if buf.String() != testCase {
		t.Error("Fprint ", buf.String(), "!=", testCase)
	}
}

func TestCodeMap(t *testing.T) {
	m := CodeMap()
	if &emojiCodeMap == &m {
		t.Error("emojiCodeMap != EmojiCodeMap")
	}
}

func TestRevCodeMap(t *testing.T) {
	m := RevCodeMap()
	if &emojiRevCodeMap == &m {
		t.Error("emojiRevCodeMap != EmojiRevCodeMap")
	}
}

func TestHasAlias(t *testing.T) {
	hasAlias := HasAlias(":+1:")
	if !hasAlias {
		t.Error(":+1: doesn't have an alias")
	}
	hasAlias = HasAlias(":no-good:")
	if hasAlias {
		t.Error(":no-good: has an alias")
	}
}

func TestNoramlizeShortCode(t *testing.T) {
	test := ":thumbs_up:"
	expected := ":+1:"
	normalized := NormalizeShortCode(test)
	if normalized != expected {
		t.Errorf("Normalized %q != %q", test, expected)
	}
	test = ":no-good:"
	normalized = NormalizeShortCode(test)
	if normalized != test {
		t.Errorf("Normalized %q != %q", test, normalized)
	}
}

func TestPrint(t *testing.T) {
	_, err := Print(beerKey, beerText)
	if err != nil {
		t.Error("Print ", err)
	}
}

func TestPrintln(t *testing.T) {
	_, err := Println(beerKey, beerText)
	if err != nil {
		t.Error("Println ", err)
	}
}

func TestPrintf(t *testing.T) {
	_, err := Printf("%s "+beerKey+beerText, "test")
	if err != nil {
		t.Error("Printf ", err)
	}
}

func TestFprint(t *testing.T) {
	var buf bytes.Buffer
	_, err := Fprint(&buf, beerKey+beerText)
	if err != nil {
		t.Error("Fprint ", err)
	}

	if buf.String() != testText {
		t.Error("Fprint ", buf.String(), testText)
	}
}

func TestFprintln(t *testing.T) {
	var buf bytes.Buffer
	_, err := Fprintln(&buf, beerKey+beerText)
	if err != nil {
		t.Error("Fprintln ", err)
	}

	if buf.String() != (testText + "\n") {
		t.Error("Fprintln ", buf.String(), (testText + "\n"))
	}
}

func TestFprintf(t *testing.T) {
	var buf bytes.Buffer
	_, err := Fprintf(&buf, "%s "+beerKey+beerText, "test")
	if err != nil {
		t.Error("Fprintf ", err)
	}

	if buf.String() != testFText {
		t.Error("Fprintf ", buf.String(), testFText)
	}
}

func TestSprint(t *testing.T) {
	convertBeer := Sprint(beerKey, beerText)
	if convertBeer != testText {
		t.Error("Sprint ", convertBeer, testText)
	}
}

func TestSprintf(t *testing.T) {
	convertBeer := Sprintf("%s "+beerKey+beerText, "test")
	if convertBeer != testFText {
		t.Error("Sprintf ", convertBeer, testFText)
	}
}

func TestErrorf(t *testing.T) {
	error := Errorf("%s "+beerKey+beerText, "test")
	if error.Error() != testFText {
		t.Error("Errorf ", error, testFText)
	}
}

func TestSprintMulti(t *testing.T) {
	convertBeer := Sprint(beerKey, beerText, beerKey, beerText)
	if convertBeer != (testText + testText) {
		t.Error("Sprint ", convertBeer, testText)
	}
	fmt.Println(convertBeer)
}

// Copyright 2016 The Hugo Authors. All rights reserved.
// source: https://github.com/spf13/hugo/blob/master/helpers/emoji_test.go

func BenchmarkFprint(b *testing.B) {
	f := func(in []byte) []byte {
		buff := getBuffer()
		defer putBuffer(buff)
		if _, err := Fprint(buff, string(in)); err != nil {
			return nil
		}

		bc := make([]byte, buff.Len())
		copy(bc, buff.Bytes())
		return bc
	}

	doBenchmarkEmoji(b, f)
}

func BenchmarkSprint(b *testing.B) {
	f := func(in []byte) []byte {
		return []byte(Sprint(string(in)))
	}

	doBenchmarkEmoji(b, f)
}

func doBenchmarkEmoji(b *testing.B, f func(in []byte) []byte) {
	type input struct {
		in     []byte
		expect []byte
	}

	data := []struct {
		input  string
		expect string
	}{
		{"A :smile: a day", Sprint("A :smile: a day")},
		{"A :smile: and a :beer: day keeps the doctor away", Sprint("A :smile: and a :beer: day keeps the doctor away")},
		{"A :smile: a day and 10 " + strings.Repeat(":beer: ", 10), Sprint("A :smile: a day and 10 " + strings.Repeat(":beer: ", 10))},
		{"No smiles today.", "No smiles today."},
		{"No smiles for you or " + strings.Repeat("you ", 1000), "No smiles for you or " + strings.Repeat("you ", 1000)},
	}

	var in = make([]input, b.N*len(data))
	var cnt = 0
	for i := 0; i < b.N; i++ {
		for _, this := range data {
			in[cnt] = input{[]byte(this.input), []byte(this.expect)}
			cnt++
		}
	}

	b.ResetTimer()
	cnt = 0
	for i := 0; i < b.N; i++ {
		for j := range data {
			currIn := in[cnt]
			cnt++
			result := f(currIn.in)
			// The Emoji implementations gives slightly different output.
			diffLen := len(result) - len(currIn.expect)
			diffLen = int(math.Abs(float64(diffLen)))
			if diffLen > 30 {
				b.Fatalf("[%d] emoji std, got \n%q but expected \n%q", j, result, currIn.expect)
			}
		}
	}
}

var bufferPool = &sync.Pool{
	New: func() interface{} {
		return &bytes.Buffer{}
	},
}

func getBuffer() (buf *bytes.Buffer) {
	return bufferPool.Get().(*bytes.Buffer)
}

func putBuffer(buf *bytes.Buffer) {
	buf.Reset()
	bufferPool.Put(buf)
}
<|endoftext|>


<commit_before>package apns_test

import (
	"bytes"
	"encoding/binary"
	"math/rand"
	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/timehop/apns"
)

var _ = Describe("Error", func() {
	Describe(".NewError", func() {
		ShouldBeErrorWithErrStr := func(status int, errStr string) {
			var errPayload = func(command int, status int, identifier int) []byte {
				buffer := bytes.NewBuffer([]byte{})
				binary.Write(buffer, binary.BigEndian, uint8(command))
				binary.Write(buffer, binary.BigEndian, uint8(status))
				binary.Write(buffer, binary.BigEndian, uint32(identifier))
				return buffer.Bytes()
			}

			command := rand.Int()
			identifier := rand.Int()

			p := errPayload(command, status, identifier)
			e := apns.NewError(p)

			It("should parse the field out correctly", func() {
				Expect(e.Command).To(Equal(uint8(command)))
				Expect(e.Status).To(Equal(uint8(status)))
				Expect(e.Identifier).To(Equal(uint32(identifier)))
			})

			It("should have picked the right error string", func() {
				Expect(e.ErrStr).To(Equal(errStr))
			})
		}

		Context("processing error", func() {
			ShouldBeErrorWithErrStr(1, apns.ErrProcessing)
		})

		Context("device token error", func() {
			ShouldBeErrorWithErrStr(2, apns.ErrMissingDeviceToken)
		})

		Context("missing topic error", func() {
			ShouldBeErrorWithErrStr(3, apns.ErrMissingTopic)
		})

		Context("missing payload error", func() {
			ShouldBeErrorWithErrStr(4, apns.ErrMissingPayload)
		})

		Context("invalid token size error", func() {
			ShouldBeErrorWithErrStr(5, apns.ErrInvalidTokenSize)
		})

		Context("invalid topic size error", func() {
			ShouldBeErrorWithErrStr(6, apns.ErrInvalidTopicSize)
		})

		Context("invalid payload size error", func() {
			ShouldBeErrorWithErrStr(7, apns.ErrInvalidPayloadSize)
		})

		Context("invalid token error", func() {
			ShouldBeErrorWithErrStr(8, apns.ErrInvalidToken)
		})

		Context("shutdown error", func() {
			ShouldBeErrorWithErrStr(10, apns.ErrShutdown)
		})

		Context("unknown error", func() {
			ShouldBeErrorWithErrStr(255, apns.ErrUnknown)
		})

		Context("error with unrecognized code", func() {
			ShouldBeErrorWithErrStr(300, apns.ErrUnknown)
		})

		Context("not enough bytes", func() {
			e := apns.NewError([]byte{})
			Expect(e).NotTo(BeNil())
			Expect(e.ErrStr).To(Equal(apns.ErrUnknown))
		})
	})

	Describe("#Error", func() {
		e := apns.Error{ErrStr: "this is an error string"}
		Expect(e.Error()).To(Equal("this is an error string"))
	})
})
<commit_msg>put assertions inside an It()<commit_after>package apns_test

import (
	"bytes"
	"encoding/binary"
	"math/rand"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
	"github.com/timehop/apns"
)

var _ = Describe("Error", func() {
	Describe(".NewError", func() {
		ShouldBeErrorWithErrStr := func(status int, errStr string) {
			var errPayload = func(command int, status int, identifier int) []byte {
				buffer := bytes.NewBuffer([]byte{})
				binary.Write(buffer, binary.BigEndian, uint8(command))
				binary.Write(buffer, binary.BigEndian, uint8(status))
				binary.Write(buffer, binary.BigEndian, uint32(identifier))
				return buffer.Bytes()
			}

			command := rand.Int()
			identifier := rand.Int()

			p := errPayload(command, status, identifier)
			e := apns.NewError(p)

			It("should parse the field out correctly", func() {
				Expect(e.Command).To(Equal(uint8(command)))
				Expect(e.Status).To(Equal(uint8(status)))
				Expect(e.Identifier).To(Equal(uint32(identifier)))
			})

			It("should have picked the right error string", func() {
				Expect(e.ErrStr).To(Equal(errStr))
			})
		}

		Context("processing error", func() {
			ShouldBeErrorWithErrStr(1, apns.ErrProcessing)
		})

		Context("device token error", func() {
			ShouldBeErrorWithErrStr(2, apns.ErrMissingDeviceToken)
		})

		Context("missing topic error", func() {
			ShouldBeErrorWithErrStr(3, apns.ErrMissingTopic)
		})

		Context("missing payload error", func() {
			ShouldBeErrorWithErrStr(4, apns.ErrMissingPayload)
		})

		Context("invalid token size error", func() {
			ShouldBeErrorWithErrStr(5, apns.ErrInvalidTokenSize)
		})

		Context("invalid topic size error", func() {
			ShouldBeErrorWithErrStr(6, apns.ErrInvalidTopicSize)
		})

		Context("invalid payload size error", func() {
			ShouldBeErrorWithErrStr(7, apns.ErrInvalidPayloadSize)
		})

		Context("invalid token error", func() {
			ShouldBeErrorWithErrStr(8, apns.ErrInvalidToken)
		})

		Context("shutdown error", func() {
			ShouldBeErrorWithErrStr(10, apns.ErrShutdown)
		})

		Context("unknown error", func() {
			ShouldBeErrorWithErrStr(255, apns.ErrUnknown)
		})

		Context("error with unrecognized code", func() {
			ShouldBeErrorWithErrStr(300, apns.ErrUnknown)
		})

		Context("not enough bytes", func() {
			It("should be ErrUnknown", func() {
				e := apns.NewError([]byte{})
				Expect(e).NotTo(BeNil())
				Expect(e.ErrStr).To(Equal(apns.ErrUnknown))
			})
		})
	})

	Describe("#Error", func() {
		It("should have an error string", func() {
			e := apns.Error{ErrStr: "this is an error string"}
			Expect(e.Error()).To(Equal("this is an error string"))
		})
	})
})
<|endoftext|>


<commit_before>package ethpub

import (
	"github.com/ethereum/eth-go/ethchain"
	"github.com/ethereum/eth-go/ethutil"
)

type PEthereum struct {
	stateManager *ethchain.StateManager
	blockChain   *ethchain.BlockChain
	txPool       *ethchain.TxPool
}

func NewPEthereum(sm *ethchain.StateManager, bc *ethchain.BlockChain, txp *ethchain.TxPool) *PEthereum {
	return &PEthereum{
		sm,
		bc,
		txp,
	}
}

func (lib *PEthereum) GetBlock(hexHash string) *PBlock {
	hash := ethutil.FromHex(hexHash)

	block := lib.blockChain.GetBlock(hash)

	var blockInfo *PBlock

	if block != nil {
		blockInfo = &PBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
	} else {
		blockInfo = &PBlock{Number: -1, Hash: ""}
	}

	return blockInfo
}

func (lib *PEthereum) GetKey() *PKey {
	keyPair, err := ethchain.NewKeyPairFromSec(ethutil.Config.Db.GetKeys()[0].PrivateKey)
	if err != nil {
		return nil
	}

	return NewPKey(keyPair)
}

func (lib *PEthereum) GetStateObject(address string) *PStateObject {
	stateObject := lib.stateManager.ProcState().GetContract(ethutil.FromHex(address))
	if stateObject != nil {
		return NewPStateObject(stateObject)
	}

	// See GetStorage for explanation on "nil"
	return NewPStateObject(nil)
}

func (lib *PEthereum) GetStorage(address, storageAddress string) string {
	return lib.GetStateObject(address).GetStorage(storageAddress)
}

func (lib *PEthereum) GetTxCount(address string) int {
	return lib.GetStateObject(address).Nonce()
}

func (lib *PEthereum) IsContract(address string) bool {
	return lib.GetStateObject(address).IsContract()
}

func (lib *PEthereum) SecretToAddress(key string) string {
	pair, err := ethchain.NewKeyPairFromSec(ethutil.FromHex(key))
	if err != nil {
		return ""
	}

	return ethutil.Hex(pair.Address())
}

func (lib *PEthereum) Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr string) (*PReceipt, error) {
	return lib.createTx(key, recipient, valueStr, gasStr, gasPriceStr, dataStr, "")
}

func (lib *PEthereum) Create(key, valueStr, gasStr, gasPriceStr, initStr, bodyStr string) (*PReceipt, error) {
	return lib.createTx(key, "", valueStr, gasStr, gasPriceStr, initStr, bodyStr)
}

func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, initStr, scriptStr string) (*PReceipt, error) {
	var hash []byte
	var contractCreation bool
	if len(recipient) == 0 {
		contractCreation = true
	} else {
		hash = ethutil.FromHex(recipient)
	}

	var keyPair *ethchain.KeyPair
	var err error
	if key[0:2] == "0x" {
		keyPair, err = ethchain.NewKeyPairFromSec([]byte(ethutil.FromHex(key[0:2])))
	} else {
		keyPair, err = ethchain.NewKeyPairFromSec([]byte(ethutil.FromHex(key)))
	}

	if err != nil {
		return nil, err
	}

	value := ethutil.Big(valueStr)
	gas := ethutil.Big(gasStr)
	gasPrice := ethutil.Big(gasPriceStr)
	var tx *ethchain.Transaction
	// Compile and assemble the given data
	if contractCreation {
		var initScript, mainScript []byte
		var err error
		if ethutil.IsHex(initStr) {
			initScript = ethutil.FromHex(initStr[2:])
		} else {
			initScript, err = ethutil.Compile(initStr)
			if err != nil {
				return nil, err
			}
		}

		if ethutil.IsHex(scriptStr) {
			mainScript = ethutil.FromHex(scriptStr[2:])
		} else {
			mainScript, err = ethutil.Compile(scriptStr)
			if err != nil {
				return nil, err
			}
		}

		tx = ethchain.NewContractCreationTx(value, gas, gasPrice, mainScript, initScript)
	} else {
		// Just in case it was submitted as a 0x prefixed string
		if len(initStr) > 0 && initStr[0:2] == "0x" {
			initStr = initStr[2:len(initStr)]
		}
		tx = ethchain.NewTransactionMessage(hash, value, gas, gasPrice, ethutil.FromHex(initStr))
	}

	acc := lib.stateManager.TransState().GetStateObject(keyPair.Address())
	//acc := lib.stateManager.GetAddrState(keyPair.Address())
	tx.Nonce = acc.Nonce
	lib.stateManager.TransState().SetStateObject(acc)

	tx.Sign(keyPair.PrivateKey)
	lib.txPool.QueueTransaction(tx)

	if contractCreation {
		ethutil.Config.Log.Infof("Contract addr %x", tx.CreationAddress())
	} else {
		ethutil.Config.Log.Infof("Tx hash %x", tx.Hash())
	}

	return NewPReciept(contractCreation, tx.CreationAddress(), tx.Hash(), keyPair.Address()), nil
}
<commit_msg>Use EthManager interface instead<commit_after>package ethpub

import (
	"github.com/ethereum/eth-go/ethchain"
	"github.com/ethereum/eth-go/ethutil"
)

type PEthereum struct {
	manager      ethchain.EthManager
	stateManager *ethchain.StateManager
	blockChain   *ethchain.BlockChain
	txPool       *ethchain.TxPool
}

func NewPEthereum(manager ethchain.EthManager) *PEthereum {
	return &PEthereum{
		manager,
		manager.StateManager(),
		manager.BlockChain(),
		manager.TxPool(),
	}
}

func (lib *PEthereum) GetBlock(hexHash string) *PBlock {
	hash := ethutil.FromHex(hexHash)

	block := lib.blockChain.GetBlock(hash)

	var blockInfo *PBlock

	if block != nil {
		blockInfo = &PBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
	} else {
		blockInfo = &PBlock{Number: -1, Hash: ""}
	}

	return blockInfo
}

func (lib *PEthereum) GetKey() *PKey {
	keyPair, err := ethchain.NewKeyPairFromSec(ethutil.Config.Db.GetKeys()[0].PrivateKey)
	if err != nil {
		return nil
	}

	return NewPKey(keyPair)
}

func (lib *PEthereum) GetStateObject(address string) *PStateObject {
	stateObject := lib.stateManager.ProcState().GetContract(ethutil.FromHex(address))
	if stateObject != nil {
		return NewPStateObject(stateObject)
	}

	// See GetStorage for explanation on "nil"
	return NewPStateObject(nil)
}

func (lib *PEthereum) GetStorage(address, storageAddress string) string {
	return lib.GetStateObject(address).GetStorage(storageAddress)
}

func (lib *PEthereum) GetTxCount(address string) int {
	return lib.GetStateObject(address).Nonce()
}

func (lib *PEthereum) IsContract(address string) bool {
	return lib.GetStateObject(address).IsContract()
}

func (lib *PEthereum) SecretToAddress(key string) string {
	pair, err := ethchain.NewKeyPairFromSec(ethutil.FromHex(key))
	if err != nil {
		return ""
	}

	return ethutil.Hex(pair.Address())
}

func (lib *PEthereum) Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr string) (*PReceipt, error) {
	return lib.createTx(key, recipient, valueStr, gasStr, gasPriceStr, dataStr, "")
}

func (lib *PEthereum) Create(key, valueStr, gasStr, gasPriceStr, initStr, bodyStr string) (*PReceipt, error) {
	return lib.createTx(key, "", valueStr, gasStr, gasPriceStr, initStr, bodyStr)
}

func (lib *PEthereum) createTx(key, recipient, valueStr, gasStr, gasPriceStr, initStr, scriptStr string) (*PReceipt, error) {
	var hash []byte
	var contractCreation bool
	if len(recipient) == 0 {
		contractCreation = true
	} else {
		hash = ethutil.FromHex(recipient)
	}

	var keyPair *ethchain.KeyPair
	var err error
	if key[0:2] == "0x" {
		keyPair, err = ethchain.NewKeyPairFromSec([]byte(ethutil.FromHex(key[0:2])))
	} else {
		keyPair, err = ethchain.NewKeyPairFromSec([]byte(ethutil.FromHex(key)))
	}

	if err != nil {
		return nil, err
	}

	value := ethutil.Big(valueStr)
	gas := ethutil.Big(gasStr)
	gasPrice := ethutil.Big(gasPriceStr)
	var tx *ethchain.Transaction
	// Compile and assemble the given data
	if contractCreation {
		var initScript, mainScript []byte
		var err error
		if ethutil.IsHex(initStr) {
			initScript = ethutil.FromHex(initStr[2:])
		} else {
			initScript, err = ethutil.Compile(initStr)
			if err != nil {
				return nil, err
			}
		}

		if ethutil.IsHex(scriptStr) {
			mainScript = ethutil.FromHex(scriptStr[2:])
		} else {
			mainScript, err = ethutil.Compile(scriptStr)
			if err != nil {
				return nil, err
			}
		}

		tx = ethchain.NewContractCreationTx(value, gas, gasPrice, mainScript, initScript)
	} else {
		// Just in case it was submitted as a 0x prefixed string
		if len(initStr) > 0 && initStr[0:2] == "0x" {
			initStr = initStr[2:len(initStr)]
		}
		tx = ethchain.NewTransactionMessage(hash, value, gas, gasPrice, ethutil.FromHex(initStr))
	}

	acc := lib.stateManager.TransState().GetStateObject(keyPair.Address())
	//acc := lib.stateManager.GetAddrState(keyPair.Address())
	tx.Nonce = acc.Nonce
	lib.stateManager.TransState().SetStateObject(acc)

	tx.Sign(keyPair.PrivateKey)
	lib.txPool.QueueTransaction(tx)

	if contractCreation {
		ethutil.Config.Log.Infof("Contract addr %x", tx.CreationAddress())
	} else {
		ethutil.Config.Log.Infof("Tx hash %x", tx.Hash())
	}

	return NewPReciept(contractCreation, tx.CreationAddress(), tx.Hash(), keyPair.Address()), nil
}
<|endoftext|>