func NewServiceContainer() ServiceContainer {
	return &dependencyInjector{
		registry:  make(map[reflect.Type]interface{}),
		instances: make(map[reflect.Type]reflect.Value),
		caching:   true,
	}
}

func NewServiceContainer ( ) ServiceContainer { return & dependencyInjector { registry : make ( map [ reflect . Type ] interface { } ) , instances : make ( map [ reflect . Type ] reflect . Value ) , caching : true , } }

// NewServiceContainer returns a new ServiceContainer


func (s *prefixPipeline) AssetUrl(name string) (url string, err error) {
	url, err = s.AssetPipeline.AssetUrl(name)
	if err == nil {
		url = s.prefix + url
	}

	return
}

func ( s * prefixPipeline ) AssetUrl ( name string ) ( url string , err error ) { url , err = s . AssetPipeline . AssetUrl ( name ) if err == nil { url = s . prefix + url } return }


func Prefix(prefix string, p AssetPipeline) AssetPipeline {
	if prefix == "" {
		return p
	}

	return &prefixPipeline{
		prefix:        prefix,
		AssetPipeline: p,
	}
}

func Prefix ( prefix string , p AssetPipeline ) AssetPipeline { if prefix == " " { return p } return & prefixPipeline { prefix : prefix , AssetPipeline : p , } }

// Prefix returns an AssetPipeline that prefixes URLs with the
// given string

Prefix returns an AssetPipeline that prefixes URLs with the given string


func (handler ControllerHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	handler.getResponse(r).Send(w)
}

func ( handler ControllerHandler ) ServeHTTP ( w http . ResponseWriter , r * http . Request ) { handler . getResponse ( r ) . Send ( w ) }


func (handler ControllerHandler) getResponse(r *http.Request) Response {
	controller := handler.factory()
	controller.SetRequest(r)
	controller.Init()
	rController := reflect.ValueOf(controller)
	method := rController.MethodByName(handler.methodName)

	// get args from gorilla mux
	var args []reflect.Value
	for _, val := range mux.Vars(r) {
		args = append(args, reflect.ValueOf(val))
	}

	// make sure number of args matches the controller method
	expected := len(args)
	actual := method.Type().NumIn()
	if expected != actual {
		panic(fmt.Sprintf("Method '%s' has %d args, expected %d", handler.methodName, actual, expected))
	}

	out := method.Call(args)
	if out[0].IsNil() {
		panic("Response from controller was nil")
	}

	resp := out[0].Interface().(Response)
	if resp == nil {
		panic("Response from controller was not Response interface")
	}

	controller.Session().WriteToResponse(resp)
	return resp
}

// getResponse executes the specified controller's method using reflection
// and returns the response object

getResponse executes the specified controller s method using reflection and returns the response object


func (handler ControllerHandler) isValid() bool {
	controller := handler.factory()
	rController := reflect.ValueOf(controller)
	method := rController.MethodByName(handler.methodName)
	if (method == reflect.Value{}) {
		panic("No such method: " + handler.methodName)
	}
	typeOfMethod := method.Type()

	var r *Response
	responseType := reflect.TypeOf(r).Elem()

	return (method.Kind() == reflect.Func) &&
		(typeOfMethod.NumMethod() == 0) &&
		(typeOfMethod.NumOut() == 1) &&
		typeOfMethod.Out(0) == responseType

}

func ( handler ControllerHandler ) isValid ( ) bool { controller := handler . factory ( ) rController := reflect . ValueOf ( controller ) method := rController . MethodByName ( handler . methodName ) if ( method == reflect . Value { } ) { panic ( " " + handler . methodName ) } typeOfMethod := method . Type ( ) var r * Response responseType := reflect . TypeOf ( r ) . Elem ( ) return ( method . Kind ( ) == reflect . Func ) && ( typeOfMethod . NumMethod ( ) == 0 ) && ( typeOfMethod . NumOut ( ) == 1 ) && typeOfMethod . Out ( 0 ) == responseType }

// isValid checks that the controller and method specifies
// will sucessfully execute if getResponse is called on it

isValid checks that the controller and method specifies will sucessfully execute if getResponse is called on it


func NewHandler(factory ControllerFactoryFunc, methodName string) ControllerHandler {
	handler := ControllerHandler{factory: factory, methodName: methodName}
	if !handler.isValid() {
		panic("Invalid handler: " + methodName)
	}
	return handler
}

func NewHandler ( factory ControllerFactoryFunc , methodName string ) ControllerHandler { handler := ControllerHandler { factory : factory , methodName : methodName } if ! handler . isValid ( ) { panic ( " " + methodName ) } return handler }

// NewHandler creates a ControllerHandler from the factory and methodName


func Handler(gf GoannaHandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		gr := &Request{Request: r}
		gf(gr).Send(w)
	}
}

func Handler ( gf GoannaHandlerFunc ) http . HandlerFunc { return func ( w http . ResponseWriter , r * http . Request ) { gr := & Request { Request : r } gf ( gr ) . Send ( w ) } }

// Handler handles functions of type GoannaHandlerFunc


func (c *Controller) SetRequest(req *http.Request) {
	c.Request = &Request{Request: req}
}

func ( c * Controller ) SetRequest ( req * http . Request ) { c . Request = & Request { Request : req } }

// SetRequest injects a request into the controller


func (c *Controller) Session() Session {
	if c.Request.session == nil {
		c.Request.session = c.sessionFinder(c.Request)
	}
	return c.Request.session
}

func ( c * Controller ) Session ( ) Session { if c . Request . session == nil { c . Request . session = c . sessionFinder ( c . Request ) } return c . Request . session }

// Session returns the session for the current request


func (c *Controller) RenderView(templateStr string, vars interface{}) []byte {
	t, err := template.New("RenderView").Parse(templateStr)
	if err != nil {
		panic(err.Error())
	}
	return c.RenderTemplate(t, vars)
}

func ( c * Controller ) RenderView ( templateStr string , vars interface { } ) [ ] byte { t , err := template . New ( " " ) . Parse ( templateStr ) if err != nil { panic ( err . Error ( ) ) } return c . RenderTemplate ( t , vars ) }

// RenderView renders a template string using the provided template and vars struct
// and returns the rendered tamplate

RenderView renders a template string using the provided template and vars struct and returns the rendered tamplate


func RenderTemplate(t *template.Template, vars interface{}) []byte {
	out := bytes.NewBuffer(nil)
	err := t.Execute(out, vars)
	if err != nil {
		panic(err.Error())
	}
	return out.Bytes()
}

func RenderTemplate ( t * template . Template , vars interface { } ) [ ] byte { out := bytes . NewBuffer ( nil ) err := t . Execute ( out , vars ) if err != nil { panic ( err . Error ( ) ) } return out . Bytes ( ) }

// RenderView renders a template using the provided template and vars struct
// and returns the rendered tamplate

RenderView renders a template using the provided template and vars struct and returns the rendered tamplate


func (c *Controller) RedirectRoute(routeName string, args ...string) *RedirectResponse {
	return NewRedirectResponse(c.UrlFor(routeName, args...).String())
}

func ( c * Controller ) RedirectRoute ( routeName string , args ... string ) * RedirectResponse { return NewRedirectResponse ( c . UrlFor ( routeName , args ... ) . String ( ) ) }

// RedirectRoute returns a RedirectResponse to the route


func (c *Controller) UrlFor(routeName string, args ...string) *url.URL {
	return UrlFor(routeName, args...)
}

func ( c * Controller ) UrlFor ( routeName string , args ... string ) * url . URL { return UrlFor ( routeName , args ... ) }

// UrlFor is helper function for controllers


func (r *Request) CookieValue(name string) string {
	c, err := r.Cookie(name)
	if err != nil {
		return ""
	}
	return c.Value
}

func ( r * Request ) CookieValue ( name string ) string { c , err := r . Cookie ( name ) if err != nil { return " " } return c . Value }

// CookieValue returns the value of the named cookie


func (r *Request) BodyData() []byte {
	var err error
	if !r.bodyRead {
		if r.Body != nil {
			r.bodyData, err = ioutil.ReadAll(r.Body)
			if err != nil {
				// catch i/o timeout errors
				neterr, isNetError := err.(net.Error)
				if isNetError && neterr.Timeout() {
					panic(ghttp.NewHttpError(err, http.StatusRequestTimeout))
				} else {
					panic(err)
				}
			}
		}
		r.bodyRead = true
	}

	return r.bodyData
}

func
(
r
*
Request
)
BodyData
(
)
[
]
byte
{
var
err
error
if
!
r
.
bodyRead
{
if
r
.
Body
!=
{
r
.
bodyData
,
err
=
ioutil
.
ReadAll
(
r
.
Body
)
if
err
!=
{
// catch i/o timeout errors
neterr
,
isNetError
:=
err
.
(
net
.
Error
)
if
isNetError
&&
neterr
.
Timeout
(
)
{
panic
(
ghttp
.
NewHttpError
(
err
,
http
.
StatusRequestTimeout
)
)
}
else
{
panic
(
err
)
}
}
}
r
.
bodyRead
=
true
}
return
r
.
bodyData
}

// BodyData returns the full request body


func (r *Request) QueryValue(key string) string {
	return r.URL.Query().Get(key)
}

func ( r * Request ) QueryValue ( key string ) string { return r . URL . Query ( ) . Get ( key ) }

// QueryValue returns the value in the GET query string


func (r *Request) FormValueOrDefault(key string, def string) string {
	val := r.FormValue(key)
	if val == "" {
		val = def
	}

	return val
}

func ( r * Request ) FormValueOrDefault ( key string , def string ) string { val := r . FormValue ( key ) if val == " " { val = def } return val }

// FormValueOrDefault returns the result of Request.FormValue,
// and if the result is empty returns the default string

FormValueOrDefault returns the result of Request . FormValue and if the result is empty returns the default string


func (r *Request) UrlValue(key string) string {
	return mux.Vars(r.Request)[key]
}

func ( r * Request ) UrlValue ( key string ) string { return mux . Vars ( r . Request ) [ key ] }

// UrlValue returns whether the request is PATCH


func Contains(s string, substrs []string) bool {
	for _, substr := range substrs {
		if strings.Contains(s, substr) {
			return true
		}
	}

	return false
}

func Contains ( s string , substrs [ ] string ) bool { for _ , substr := range substrs { if strings . Contains ( s , substr ) { return true } } return false }

// Contains returns true if any string in substrs is within s


func RemoveStringsFromString(s string, substrs []string) string {
	for loop := true; loop; {
		loop = false
		for _, substr := range substrs {
			lastS := s
			s = strings.Join(strings.Split(s, substr), "")
			if lastS != s {
				loop = true
				break
			}
		}
	}

	return s
}

func RemoveStringsFromString ( s string , substrs [ ] string ) string { for loop := true ; loop ; { loop = false for _ , substr := range substrs { lastS := s s = strings . Join ( strings . Split ( s , substr ) , " " ) if lastS != s { loop = true break } } } return s }

// RemoveStringsFromString removes any string in substrs from s


func Map(ss []string, callback func(string) string) []string {
	newStrings := make([]string, len(ss))
	for i, s := range ss {
		newStrings[i] = callback(s)
	}

	return newStrings
}

func Map ( ss [ ] string , callback func ( string ) string ) [ ] string { newStrings := make ( [ ] string , len ( ss ) ) for i , s := range ss { newStrings [ i ] = callback ( s ) } return newStrings }

// Map returns a slice containing all the elements of ss
// after applying the callback function to each one

Map returns a slice containing all the elements of ss after applying the callback function to each one


func Equal(a, b []string) bool {
	if len(a) != len(b) {
		return false
	}
	for i, v := range a {
		if v != b[i] {
			return false
		}
	}
	return true
}

func Equal ( a , b [ ] string ) bool { if len ( a ) != len ( b ) { return false } for i , v := range a { if v != b [ i ] { return false } } return true }

// Equal returns a boolean reporting whether a == b


func Uniq(items []string) (uniqItems []string) {
	sort.Strings(items)

	lastitem := ""
	for _, item := range items {
		if item != lastitem {
			uniqItems = append(uniqItems, item)
			lastitem = item
		}
	}

	return
}

func Uniq ( items [ ] string ) ( uniqItems [ ] string ) { sort . Strings ( items ) lastitem := " " for _ , item := range items { if item != lastitem { uniqItems = append ( uniqItems , item ) lastitem = item } } return }

// Uniq returns a slice containing the unique strings
// found in items

Uniq returns a slice containing the unique strings found in items


func NewCookieSigner(key []byte) CookieSigner {
	return CookieSigner{signer: hmac.New(sha256.New, key)}
}

func NewCookieSigner ( key [ ] byte ) CookieSigner { return CookieSigner { signer : hmac . New ( sha256 . New , key ) } }

// NewCookieSigner returns a new CookieSigner using the given key


func (c CookieSigner) EncodeCookie(cookie *http.Cookie) {
	cookie.Value = c.EncodeValue(cookie.Value)
}

func ( c CookieSigner ) EncodeCookie ( cookie * http . Cookie ) { cookie . Value = c . EncodeValue ( cookie . Value ) }

// EncodeCookie signs and encodes the cookie


func (c CookieSigner) DecodeCookie(cookie *http.Cookie) error {
	data, err := c.DecodeValue(cookie.Value)
	if err != nil {
		return err
	}
	cookie.Value = data

	return nil
}

func ( c CookieSigner ) DecodeCookie ( cookie * http . Cookie ) error { data , err := c . DecodeValue ( cookie . Value ) if err != nil { return err } cookie . Value = data return nil }

// DecodeCookie verifies the signature and decodes the value into the cookie


func (c CookieSigner) DecodeValue(encodedvalue string) (string, error) {
	parts := strings.SplitN(encodedvalue, ".", 2)
	if len(parts) != 2 {
		return "", errors.New("Wrong number of parts")
	}
	mac, err := base64.URLEncoding.DecodeString(parts[0])
	value := parts[1]

	if err != nil {
		return "", err
	}
	if !hmac.Equal(c.mac(value), mac) {
		return "", errors.New("Bad signature")
	}

	return value, nil
}

func ( c CookieSigner ) DecodeValue ( encodedvalue string ) ( string , error ) { parts := strings . SplitN ( encodedvalue , " " , 2 ) if len ( parts ) != 2 { return " " , errors . New ( " " ) } mac , err := base64 . URLEncoding . DecodeString ( parts [ 0 ] ) value := parts [ 1 ] if err != nil { return " " , err } if ! hmac . Equal ( c . mac ( value ) , mac ) { return " " , errors . New ( " " ) } return value , nil }

// DecodeValue validates and decodes a cookie value


func (c CookieSigner) EncodeValue(value string) string {
	return fmt.Sprintf("%s.%s",
		base64.URLEncoding.EncodeToString(c.mac(value)),
		value)
}

func ( c CookieSigner ) EncodeValue ( value string ) string { return fmt . Sprintf ( " " , base64 . URLEncoding . EncodeToString ( c . mac ( value ) ) , value ) }

// EncodeValue signs and encodes a cookie value


func (sh *StatsdLogHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	requestStartTime := time.Now()
	sh.handler.ServeHTTP(w, req)
	requestDuration := time.Now().Sub(requestStartTime)

	description := sh.RequestFormatter(req)
	if description != "" {
		sh.statter.Counter(1.0, sh.prefix+"."+description+".requests", 1)
		sh.statter.Timing(1.0, sh.prefix+"."+description+".responsetime", requestDuration)
	}
}

func ( sh * StatsdLogHandler ) ServeHTTP ( w http . ResponseWriter , req * http . Request ) { requestStartTime := time . Now ( ) sh . handler . ServeHTTP ( w , req ) requestDuration := time . Now ( ) . Sub ( requestStartTime ) description := sh . RequestFormatter ( req ) if description != " " { sh . statter . Counter ( 1.0 , sh . prefix + " " + description + " " , 1 ) sh . statter . Timing ( 1.0 , sh . prefix + " " + description + " " , requestDuration ) } }

// ServeHTTP records the time for a request and sends the result to statsd


func NewSprocketsServer(target *url.URL) (*SprocketsServer, error) {
	s := SprocketsServer{
		Handler: httputil.NewSingleHostReverseProxy(target),
		target:  target,
	}

	return &s, nil
}

func NewSprocketsServer ( target * url . URL ) ( * SprocketsServer , error ) { s := SprocketsServer { Handler : httputil . NewSingleHostReverseProxy ( target ) , target : target , } return & s , nil }

// NewSprocketsServer creates a Sprockets asset pipeline


func normaliseKey(key string) string {
	newkey := url.QueryEscape(key)
	if len(newkey) > 250 {
		newkey = newkey[:250]
	}

	return newkey
}

func normaliseKey ( key string ) string { newkey := url . QueryEscape ( key ) if len ( newkey ) > 250 { newkey = newkey [ : 250 ] } return newkey }

// Keys must be at maximum 250 bytes long, ASCII, and not
// contain whitespace or control characters.

Keys must be at maximum 250 bytes long ASCII and not contain whitespace or control characters .


func (m *Monitor) StopAndLog(sectionName string) error {
	err := m.Stop(sectionName)
	if err == nil {
		m.Log(sectionName)
	}

	return err
}

func ( m * Monitor ) StopAndLog ( sectionName string ) error { err := m . Stop ( sectionName ) if err == nil { m . Log ( sectionName ) } return err }


func (m *Monitor) MonitorFunc(section string, myfunc interface{}) []reflect.Value {
	return m.MonitorReflectedFunc(section, reflect.ValueOf(myfunc), []reflect.Value{})
}

func ( m * Monitor ) MonitorFunc ( section string , myfunc interface { } ) [ ] reflect . Value { return m . MonitorReflectedFunc ( section , reflect . ValueOf ( myfunc ) , [ ] reflect . Value { } ) }

// Function decorator to monitor the execution of an anonymous function
// returns an array of the returned Values

Function decorator to monitor the execution of an anonymous function returns an array of the returned Values


func (m *Monitor) MonitorReflectedFunc(section string, reflectedFunc reflect.Value, args []reflect.Value) []reflect.Value {
	m.Start(section)
	defer m.StopAndLog(section)

	return reflectedFunc.Call(args)
}

func ( m * Monitor ) MonitorReflectedFunc ( section string , reflectedFunc reflect . Value , args [ ] reflect . Value ) [ ] reflect . Value { m . Start ( section ) defer m . StopAndLog ( section ) return reflectedFunc . Call ( args ) }

// Function decorator
// to monitor a reflected function

Function decorator to monitor a reflected function


func LogRequest(r *Request, v ...string) {
	serializedHeaders := bytes.Buffer{}
	r.Header.Write(&serializedHeaders)

	printf := log.Printf
	if Logger != nil {
		printf = Logger.Printf
	}

	printf(
		LogRequestTemplate,
		strings.Join(v, " "),
		r.URL.String(),
		r.Method,
		time.Now(),
		serializedHeaders.String(),
		string(r.BodyData()),
		debug.Stack(),
	)
}

func LogRequest ( r * Request , v ... string ) { serializedHeaders := bytes . Buffer { } r . Header . Write ( & serializedHeaders ) printf := log . Printf if Logger != nil { printf = Logger . Printf } printf ( LogRequestTemplate , strings . Join ( v , " " ) , r . URL . String ( ) , r . Method , time . Now ( ) , serializedHeaders . String ( ) , string ( r . BodyData ( ) ) , debug . Stack ( ) , ) }


func CommonLogHandler(logger *log.Logger, templ string, h http.Handler) http.Handler {
	if logger == nil {
		logger = log.New(os.Stdout, "", 0)
	}
	if templ == "" {
		templ = CommonLogFormat
	}

	return &commonLogHandler{
		handler:  h,
		logger:   logger,
		template: template.Must(template.New("").Parse(templ)),
	}
}

func CommonLogHandler ( logger * log . Logger , templ string , h http . Handler ) http . Handler { if logger == nil { logger = log . New ( os . Stdout , " " , 0 ) } if templ == " " { templ = CommonLogFormat } return & commonLogHandler { handler : h , logger : logger , template : template . Must ( template . New ( " " ) . Parse ( templ ) ) , } }

// CommonLogHandler returns a handler that serves HTTP requests
// If a logger is not provided, stdout will be used

CommonLogHandler returns a handler that serves HTTP requests If a logger is not provided stdout will be used


func (lh *commonLogHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	// take a copy of the request (so it's immutable)
	// watch the writer and capture the status and size
	logData := LogData{
		Request:  *req,
		Response: WatchResponseWriter(w),
	}

	logData.Start = time.Now()
	lh.handler.ServeHTTP(logData.Response, req)
	logData.End = time.Now()

	logOutput := bytes.Buffer{}
	err := lh.template.Execute(&logOutput, logData)
	if err != nil {
		panic(err)
	}

	lh.logger.Println(logOutput.String())
}

// ServeHTTP logs the request and response data to Common Log Format


func (this LogData) UrlUsername() string {
	if this.Request.URL.User != nil {
		return this.Request.URL.User.Username()
	}
	return ""
}

func ( this LogData ) UrlUsername ( ) string { if this . Request . URL . User != nil { return this . Request . URL . User . Username ( ) } return " " }

// Extract username from the request url


func UrlFor(name string, args ...string) *url.URL {
	r := Router.Get(name)
	if r == nil {
		log.Panicf("UrlFor: No such route '%s'\n", name)
	}
	u, err := r.URL(args...)
	if err != nil {
		log.Panicln("UrlFor: " + err.Error())
	}
	return u
}

func UrlFor ( name string , args ... string ) * url . URL { r := Router . Get ( name ) if r == nil { log . Panicf ( " \n " , name ) } u , err := r . URL ( args ... ) if err != nil { log . Panicln ( " " + err . Error ( ) ) } return u }

// UrlFor returns the relative URL for the route name


func AbsoluteUrlFor(name string, args ...string) *url.URL {
	u := UrlFor(name, args...)
	u.Host = UrlBase.Host
	u.Scheme = UrlBase.Scheme
	return u
}

func AbsoluteUrlFor ( name string , args ... string ) * url . URL { u := UrlFor ( name , args ... ) u . Host = UrlBase . Host u . Scheme = UrlBase . Scheme return u }

// UrlFor returns the avsolute URL for the route name.
// UrlBase is used for the URL Host and Scheme

UrlFor returns the avsolute URL for the route name . UrlBase is used for the URL Host and Scheme


func Parse(jsondata []byte, v interface{}) {
	err := json.Unmarshal(jsondata, v)
	if err != nil {
		panic(err.Error())
	}
}

func Parse ( jsondata [ ] byte , v interface { } ) { err := json . Unmarshal ( jsondata , v ) if err != nil { panic ( err . Error ( ) ) } }

// Parse parses the JSON-encoded data and stores the result
// into the value pointed at by c.
// Panics if unsuccessful

Parse parses the JSON - encoded data and stores the result into the value pointed at by c . Panics if unsuccessful


func LoadFromEnv(v interface{}, prefix string) (result []MarshalledEnvironmentVar) {
	pointerValue := reflect.ValueOf(v)
	structValue := pointerValue.Elem()
	structType := structValue.Type()

	for i := 0; i < structValue.NumField(); i++ {
		structField := structType.Field(i)
		fieldValue := structValue.Field(i)

		if fieldValue.CanSet() {
			envKey := strings.ToUpper(prefix) + gocase.ToUpperSnake(structField.Name)
			envVal := os.Getenv(envKey)

			if envVal != "" {
				// create a json blob with the env data
				jsonStr := ""
				if fieldValue.Kind() == reflect.String {
					jsonStr = fmt.Sprintf(`{"%s": "%s"}`, structField.Name, envVal)
				} else {
					jsonStr = fmt.Sprintf(`{"%s": %s}`, structField.Name, envVal)
				}

				err := json.Unmarshal([]byte(jsonStr), v)
				result = append(result, MarshalledEnvironmentVar{envKey, envVal, structField.Name, err})
			}
		}
	}

	return
}

func
LoadFromEnv
(
v
interface
{
}
,
prefix
string
)
(
result
[
]
MarshalledEnvironmentVar
)
{
pointerValue
:=
reflect
.
ValueOf
(
v
)
structValue
:=
pointerValue
.
Elem
(
)
structType
:=
structValue
.
Type
(
)
for
i
:=
0
;
i
<
structValue
.
NumField
(
)
;
i
++
{
structField
:=
structType
.
Field
(
i
)
fieldValue
:=
structValue
.
Field
(
i
)
if
fieldValue
.
CanSet
(
)
{
envKey
:=
strings
.
ToUpper
(
prefix
)
+
gocase
.
ToUpperSnake
(
structField
.
Name
)
envVal
:=
os
.
Getenv
(
envKey
)
if
envVal
!=
"
"
{
// create a json blob with the env data
jsonStr
:=
"
"
if
fieldValue
.
Kind
(
)
==
reflect
.
String
{
jsonStr
=
fmt
.
Sprintf
(
`{"%s": "%s"}`
,
structField
.
Name
,
envVal
)
}
else
{
jsonStr
=
fmt
.
Sprintf
(
`{"%s": %s}`
,
structField
.
Name
,
envVal
)
}
err
:=
json
.
Unmarshal
(
[
]
byte
(
jsonStr
)
,
v
)
result
=
append
(
result
,
MarshalledEnvironmentVar
{
envKey
,
envVal
,
structField
.
Name
,
err
}
)
}
}
}
return
}

// LoadFromEnv iterates through a
// struct's fields and tries to find matching
// environment variables.
// Returns a map of environment key and values that were
// successfully set into the struct

LoadFromEnv iterates through a struct s fields and tries to find matching environment variables . Returns a map of environment key and values that were successfully set into the struct


func RegexPath(reg *regexp.Regexp, h http.Handler) http.Handler {
	if reg == nil {
		return h
	}

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		matches := reg.FindStringSubmatch(r.URL.Path)
		if len(matches) > 1 {
			r.URL.Path = matches[1]
			h.ServeHTTP(w, r)
		} else {
			http.NotFound(w, r)
		}
	})
}

func RegexPath ( reg * regexp . Regexp , h http . Handler ) http . Handler { if reg == nil { return h } return http . HandlerFunc ( func ( w http . ResponseWriter , r * http . Request ) { matches := reg . FindStringSubmatch ( r . URL . Path ) if len ( matches ) > 1 { r . URL . Path = matches [ 1 ] h . ServeHTTP ( w , r ) } else { http . NotFound ( w , r ) } } ) }

// RegexPath returns a handler that serves HTTP requests
// with the first match of the the given regex from the request URL's Path
// and invoking the handler h. RegexPath handles a
// request for a path that doesn't match by
// replying with an HTTP 404 not found error.

RegexPath returns a handler that serves HTTP requests with the first match of the the given regex from the request URL s Path and invoking the handler h . RegexPath handles a request for a path that doesn t match by replying with an HTTP 404 not found error .


func CacheControl(maxage uint, delegate http.Handler) http.Handler {
	return &cacheDecorator{delegate, maxage}
}

func CacheControl ( maxage uint , delegate http . Handler ) http . Handler { return & cacheDecorator { delegate , maxage } }

// CacheControl decorates a handler and adds Cache-Control headers

CacheControl decorates a handler and adds Cache - Control headers


func transform(in interface{}) (_ interface{}, err error) {
	switch in.(type) {
	case map[interface{}]interface{}:
		o := make(map[string]interface{})
		for k, v := range in.(map[interface{}]interface{}) {
			sk := ""
			switch k.(type) {
			case string:
				sk = k.(string)
			case int:
				sk = strconv.Itoa(k.(int))
			default:
				return nil, errors.New(
					fmt.Sprintf("type not match: expect map key string or int get: %T", k))
			}
			v, err = transform(v)
			if err != nil {
				return nil, err
			}
			o[sk] = v
		}
		return o, nil
	case []interface{}:
		in1 := in.([]interface{})
		len1 := len(in1)
		o := make([]interface{}, len1)
		for i := 0; i < len1; i++ {
			o[i], err = transform(in1[i])
			if err != nil {
				return nil, err
			}
		}
		return o, nil
	default:
		return in, nil
	}
}

func transform ( in interface { } ) ( _ interface { } , err error ) { switch in . ( type ) { case map [ interface { } ] interface { } : o := make ( map [ string ] interface { } ) for k , v := range in . ( map [ interface { } ] interface { } ) { sk := " " switch k . ( type ) { case string : sk = k . ( string ) case int : sk = strconv . Itoa ( k . ( int ) ) default : return nil , errors . New ( fmt . Sprintf ( " " , k ) ) } v , err = transform ( v ) if err != nil { return nil , err } o [ sk ] = v } return o , nil case [ ] interface { } : in1 := in . ( [ ] interface { } ) len1 := len ( in1 ) o := make ( [ ] interface { } , len1 ) for i := 0 ; i < len1 ; i ++ { o [ i ] , err = transform ( in1 [ i ] ) if err != nil { return nil , err } } return o , nil default : return in , nil } }


func DiscoverWalk(app App, insecure discovery.InsecureOption, discoverFn DiscoverWalkFunc) (err error) {
	var (
		eps *Endpoints
	)

	parts := strings.Split(string(app.Name), "/")
	for i := range parts {
		end := len(parts) - i
		pre := strings.Join(parts[:end], "/")

		eps, err = doDiscover(pre, app, insecure)
		if derr := discoverFn(pre, eps, err); derr != nil {
			return derr
		}
	}

	return
}

func DiscoverWalk ( app App , insecure discovery . InsecureOption , discoverFn DiscoverWalkFunc ) ( err error ) { var ( eps * Endpoints ) parts := strings . Split ( string ( app . Name ) , " " ) for i := range parts { end := len ( parts ) - i pre := strings . Join ( parts [ : end ] , " " ) eps , err = doDiscover ( pre , app , insecure ) if derr := discoverFn ( pre , eps , err ) ; derr != nil { return derr } } return }

// DiscoverWalk will make HTTPS requests to find discovery meta tags and
// optionally will use HTTP if insecure is set. Based on the response of the
// discoverFn it will continue to recurse up the tree.

DiscoverWalk will make HTTPS requests to find discovery meta tags and optionally will use HTTP if insecure is set . Based on the response of the discoverFn it will continue to recurse up the tree .


func DiscoverEndpoints(app App, insecure discovery.InsecureOption) (out *Endpoints, attempts []FailedAttempt, err error) {
	out = &Endpoints{}
	testFn := func(pre string, eps *Endpoints, err error) error {
		if len(out.ACIEndpoints) != 0 || len(out.Keys) != 0 || len(out.ACIPushEndpoints) != 0 {
			return errEnough
		}
		return nil
	}

	err = DiscoverWalk(app, insecure, walker(out, &attempts, testFn))
	if err != nil && err != errEnough {
		return nil, attempts, err
	}

	return out, attempts, nil
}

func DiscoverEndpoints ( app App , insecure discovery . InsecureOption ) ( out * Endpoints , attempts [ ] FailedAttempt , err error ) { out = & Endpoints { } testFn := func ( pre string , eps * Endpoints , err error ) error { if len ( out . ACIEndpoints ) != 0 || len ( out . Keys ) != 0 || len ( out . ACIPushEndpoints ) != 0 { return errEnough } return nil } err = DiscoverWalk ( app , insecure , walker ( out , & attempts , testFn ) ) if err != nil && err != errEnough { return nil , attempts , err } return out , attempts , nil }

// DiscoverEndpoints will make HTTPS requests to find the ac-discovery meta
// tags and optionally will use HTTP if insecure is set. It will not give up
// until it has exhausted the path or found an image discovery.

DiscoverEndpoints will make HTTPS requests to find the ac - discovery meta tags and optionally will use HTTP if insecure is set . It will not give up until it has exhausted the path or found an image discovery .


func JSONFieldsFromStruct(v reflect.Value) []string {
	if v.Kind() != reflect.Struct {
		return nil
	}

	m := getType2jfm(v.Type())
	m.lock.Lock()
	defer m.lock.Unlock()

	l := make([]string, 0, len(m.fields))
	for k := range m.fields {
		l = append(l, k)
	}
	return l
}

func JSONFieldsFromStruct ( v reflect . Value ) [ ] string { if v . Kind ( ) != reflect . Struct { return nil } m := getType2jfm ( v . Type ( ) ) m . lock . Lock ( ) defer m . lock . Unlock ( ) l := make ( [ ] string , 0 , len ( m . fields ) ) for k := range m . fields { l = append ( l , k ) } return l }

// JSONFieldsFromStruct returns the names of JSON fields associated
// with the given struct. Returns nil if v is not a struct

JSONFieldsFromStruct returns the names of JSON fields associated with the given struct . Returns nil if v is not a struct


func StructFieldFromJSONName(v reflect.Value, name string) string {
	if v.Kind() != reflect.Struct {
		return ""
	}

	m := getType2jfm(v.Type())
	m.lock.Lock()
	defer m.lock.Unlock()

	s, ok := m.fields[name]
	if !ok {
		return ""
	}
	return s
}

func StructFieldFromJSONName ( v reflect . Value , name string ) string { if v . Kind ( ) != reflect . Struct { return " " } m := getType2jfm ( v . Type ( ) ) m . lock . Lock ( ) defer m . lock . Unlock ( ) s , ok := m . fields [ name ] if ! ok { return " " } return s }

// StructFieldFromJSONName returns the struct field name on the
// given struct value. Empty value means the field is either not
// public, or does not exist.
//
// This can be used to map JSON field names to actual struct fields.

StructFieldFromJSONName returns the struct field name on the given struct value . Empty value means the field is either not public or does not exist . This can be used to map JSON field names to actual struct fields .


func (dict Dictionary) Enumerate(cancel <-chan struct{}) Enumerator {
	if dict.root == nil {
		return Empty.Enumerate(cancel)
	}
	return dict.root.Enumerate(cancel)
}

func ( dict Dictionary ) Enumerate ( cancel <- chan struct { } ) Enumerator { if dict . root == nil { return Empty . Enumerate ( cancel ) } return dict . root . Enumerate ( cancel ) }

// Enumerate lists each word in the Dictionary alphabetically.

Enumerate lists each word in the Dictionary alphabetically .


func (m *Message) Release() {
	if m != nil {
		m.Text = nil
		m.List = m.List[:0]
		messagePool.Put(m)
	}
}

func ( m * Message ) Release ( ) { if m != nil { m . Text = nil m . List = m . List [ : 0 ] messagePool . Put ( m ) } }

// Release returns the message to the pool for re-use.

Release returns the message to the pool for re - use .


func Wrap(err error, text ...string) Error {
	return causer(newError(nil, err, text...))
}

func Wrap ( err error , text ... string ) Error { return causer ( newError ( nil , err , text ... ) ) }

// Wrap returns an error that wraps err, optionally annotating
// with the message text.

Wrap returns an error that wraps err optionally annotating with the message text .


func causer(e *errorT) Error {
	if e.err == nil {
		return e
	}
	return &causerT{
		errorT: e,
	}
}

func causer ( e * errorT ) Error { if e . err == nil { return e } return & causerT { errorT : e , } }

// causer detects whether e wraps another error, and if so
// returns an Error that also implements the Causer interface.

causer detects whether e wraps another error and if so returns an Error that also implements the Causer interface .


func From(ctx context.Context) Context {
	if c, ok := ctx.(Context); ok {
		return c
	}
	return &contextT{ctx: ctx}
}

func From ( ctx context . Context ) Context { if c , ok := ctx . ( Context ) ; ok { return c } return & contextT { ctx : ctx } }

// From creates a new context based on ctx. See the Context example.

From creates a new context based on ctx . See the Context example .


func (c *contextT) With(keyvals ...interface{}) context.Context {
	return &contextT{ctx: newContext(c.ctx, keyvals)}
}

func ( c * contextT ) With ( keyvals ... interface { } ) context . Context { return & contextT { ctx : newContext ( c . ctx , keyvals ) } }

// With returns a context.Context with the keyvals attached.

With returns a context . Context with the keyvals attached .


func (c *contextT) Format(f fmt.State, ch rune) {
	if ch == 'v' && f.Flag('+') {
		fmt.Fprint(f, c.ctx)
		return
	}
	buf := pool.AllocBuffer()
	list := List(fromContext(c.ctx))
	list.writeToBuffer(buf)
	f.Write(buf.Bytes())
	pool.ReleaseBuffer(buf)
}

func ( c * contextT ) Format ( f fmt . State , ch rune ) { if ch == 'v' && f . Flag ( '+' ) { fmt . Fprint ( f , c . ctx ) return } buf := pool . AllocBuffer ( ) list := List ( fromContext ( c . ctx ) ) list . writeToBuffer ( buf ) f . Write ( buf . Bytes ( ) ) pool . ReleaseBuffer ( buf ) }

// Format implements the fmt.Formatter interface. If
// the context is printed with "%+v", then it prints
// using the String method of the wrapped context.

Format implements the fmt . Formatter interface . If the context is printed with % + v then it prints using the String method of the wrapped context .


func NewWriter(out io.Writer) *Writer {
	w := &Writer{
		printer: newPrinter(out),
	}
	return w
}

func NewWriter ( out io . Writer ) * Writer { w := & Writer { printer : newPrinter ( out ) , } return w }

// NewWriter creates writer that logs messages to out. If the output writer is a terminal
// device, the output will be formatted for improved readability.

NewWriter creates writer that logs messages to out . If the output writer is a terminal device the output will be formatted for improved readability .


func (w *Writer) Levels() map[string]string {
	w.mutex.Lock()
	defer w.mutex.Unlock()

	if w.levels == nil {
		w.setLevels(Levels)
	}
	levels := make(map[string]string)
	for level, effect := range w.levels {
		levels[level] = effect
	}

	return levels
}

func ( w * Writer ) Levels ( ) map [ string ] string { w . mutex . Lock ( ) defer w . mutex . Unlock ( ) if w . levels == nil { w . setLevels ( Levels ) } levels := make ( map [ string ] string ) for level , effect := range w . levels { levels [ level ] = effect } return levels }

// Levels returns a list of levels and their associated actions.

Levels returns a list of levels and their associated actions .


func (w *Writer) SetLevel(level string, effect string) {
	levels := w.Levels()
	levels[level] = effect
	w.SetLevels(levels)
}

func ( w * Writer ) SetLevel ( level string , effect string ) { levels := w . Levels ( ) levels [ level ] = effect w . SetLevels ( levels ) }

// SetLevel sets an individual level and its associated display effect.

SetLevel sets an individual level and its associated display effect .


func (w *Writer) Suppress(levels ...string) {
	p := w.Levels()
	for _, level := range levels {
		p[level] = "hide"
	}
	w.SetLevels(p)
}

func ( w * Writer ) Suppress ( levels ... string ) { p := w . Levels ( ) for _ , level := range levels { p [ level ] = " " } w . SetLevels ( p ) }

// Suppress instructs the writer to suppress any message with the specified level.

Suppress instructs the writer to suppress any message with the specified level .


func (w *Writer) IsSuppressed(level string) bool {
	_, ok := w.suppressMap[level]
	return ok
}

func ( w * Writer ) IsSuppressed ( level string ) bool { _ , ok := w . suppressMap [ level ] return ok }

// IsSuppressed reports true if level should be suppressed.

IsSuppressed reports true if level should be suppressed .


func (w *Writer) Handle(h Handler) {
	w.mutex.Lock()
	defer w.mutex.Unlock()

	if h != nil {
		w.handlers = append(w.handlers, h)
	}
}

func ( w * Writer ) Handle ( h Handler ) { w . mutex . Lock ( ) defer w . mutex . Unlock ( ) if h != nil { w . handlers = append ( w . handlers , h ) } }

// Handle registers a handler that will be called for every logging
// event. The function receives a message, which is a structured
// representation of the log message text.
//
// This function is useful for registering handlers that send log
// information to external sources.

Handle registers a handler that will be called for every logging event . The function receives a message which is a structured representation of the log message text . This function is useful for registering handlers that send log information to external sources .


func (w *Writer) SetOutput(out io.Writer) {
	w.mutex.Lock()
	w.printer = newPrinter(out)
	w.mutex.Unlock()
}

func ( w * Writer ) SetOutput ( out io . Writer ) { w . mutex . Lock ( ) w . printer = newPrinter ( out ) w . mutex . Unlock ( ) }

// SetOutput sets the output destination for log messages.

SetOutput sets the output destination for log messages .


func (d Directory) Enumerate(cancel <-chan struct{}) Enumerator {
	results := make(chan interface{})

	go func() {
		defer close(results)

		filepath.Walk(d.Location, func(currentLocation string, info os.FileInfo, openErr error) (err error) {
			if openErr != nil {
				err = openErr
				return
			}

			if d.Location == currentLocation {
				return
			}

			if info.IsDir() && 0 == d.Options&DirectoryOptionsRecursive {
				err = filepath.SkipDir
			}

			if d.applyOptions(currentLocation, info) {
				select {
				case results <- currentLocation:
					// Intentionally Left Blank
				case <-cancel:
					err = errors.New("directory enumeration cancelled")
				}
			}

			return
		})
	}()

	return results
}

func
(
d
Directory
)
Enumerate
(
cancel
<-
chan
struct
{
}
)
Enumerator
{
results
:=
make
(
chan
interface
{
}
)
go
func
(
)
{
defer
close
(
results
)
filepath
.
Walk
(
d
.
Location
,
func
(
currentLocation
string
,
info
os
.
FileInfo
,
openErr
error
)
(
err
error
)
{
if
openErr
!=
{
err
=
openErr
return
}
if
d
.
Location
==
currentLocation
{
return
}
if
info
.
IsDir
(
)
&&
0
==
d
.
Options
&
DirectoryOptionsRecursive
{
err
=
filepath
.
SkipDir
}
if
d
.
applyOptions
(
currentLocation
,
info
)
{
select
{
case
results
<-
currentLocation
:
// Intentionally Left Blank
case
<-
cancel
:
err
=
errors
.
New
(
"
"
)
}
}
return
}
)
}
(
)
return
results
}

// Enumerate lists the items in a `Directory`

Enumerate lists the items in a Directory


func All(subject Enumerable, p Predicate) bool {
	done := make(chan struct{})
	defer close(done)

	return subject.Enumerate(done).All(p)
}

func All ( subject Enumerable , p Predicate ) bool { done := make ( chan struct { } ) defer close ( done ) return subject . Enumerate ( done ) . All ( p ) }

// All tests whether or not all items present in an Enumerable meet a criteria.

All tests whether or not all items present in an Enumerable meet a criteria .


func (iter Enumerator) All(p Predicate) bool {
	for entry := range iter {
		if !p(entry) {
			return false
		}
	}
	return true
}

func ( iter Enumerator ) All ( p Predicate ) bool { for entry := range iter { if ! p ( entry ) { return false } } return true }

// All tests whether or not all items present meet a criteria.

All tests whether or not all items present meet a criteria .


func Any(iterator Enumerable) bool {
	done := make(chan struct{})
	defer close(done)

	for range iterator.Enumerate(done) {
		return true
	}
	return false
}

func Any ( iterator Enumerable ) bool { done := make ( chan struct { } ) defer close ( done ) for range iterator . Enumerate ( done ) { return true } return false }

// Any tests an Enumerable to see if there are any elements present.

Any tests an Enumerable to see if there are any elements present .


func Anyp(iterator Enumerable, p Predicate) bool {
	done := make(chan struct{})
	defer close(done)

	for element := range iterator.Enumerate(done) {
		if p(element) {
			return true
		}
	}
	return false
}

func Anyp ( iterator Enumerable , p Predicate ) bool { done := make ( chan struct { } ) defer close ( done ) for element := range iterator . Enumerate ( done ) { if p ( element ) { return true } } return false }

// Anyp tests an Enumerable to see if there are any elements present that meet a criteria.

Anyp tests an Enumerable to see if there are any elements present that meet a criteria .


func AsEnumerable(entries ...interface{}) Enumerable {
	if len(entries) != 1 {
		return enumerableSlice(entries)
	}

	val := reflect.ValueOf(entries[0])

	if kind := val.Kind(); kind == reflect.Slice || kind == reflect.Array {
		return enumerableValue{
			Value: val,
		}
	}
	return enumerableSlice(entries)
}

func AsEnumerable ( entries ... interface { } ) Enumerable { if len ( entries ) != 1 { return enumerableSlice ( entries ) } val := reflect . ValueOf ( entries [ 0 ] ) if kind := val . Kind ( ) ; kind == reflect . Slice || kind == reflect . Array { return enumerableValue { Value : val , } } return enumerableSlice ( entries ) }

// AsEnumerable allows for easy conversion of a slice to a re-usable Enumerable object.

AsEnumerable allows for easy conversion of a slice to a re - usable Enumerable object .


func First(subject Enumerable) (retval interface{}, err error) {
	done := make(chan struct{})

	err = errNoElements

	var isOpen bool

	if retval, isOpen = <-subject.Enumerate(done); isOpen {
		err = nil
	}
	close(done)

	return
}

func First ( subject Enumerable ) ( retval interface { } , err error ) { done := make ( chan struct { } ) err = errNoElements var isOpen bool if retval , isOpen = <- subject . Enumerate ( done ) ; isOpen { err = nil } close ( done ) return }

// First retrieves just the first item in the list, or returns an error if there are no elements in the array.

First retrieves just the first item in the list or returns an error if there are no elements in the array .


func (iter Enumerator) Merge(others ...Enumerator) Enumerator {
	retval := make(chan interface{})

	var wg sync.WaitGroup
	wg.Add(len(others) + 1)

	funnel := func(prevResult Enumerator) {
		for entry := range prevResult {
			retval <- entry
		}
		wg.Done()
	}

	go funnel(iter)
	for _, item := range others {
		go funnel(item)
	}

	go func() {
		wg.Wait()
		close(retval)
	}()
	return retval
}

func ( iter Enumerator ) Merge ( others ... Enumerator ) Enumerator { retval := make ( chan interface { } ) var wg sync . WaitGroup wg . Add ( len ( others ) + 1 ) funnel := func ( prevResult Enumerator ) { for entry := range prevResult { retval <- entry } wg . Done ( ) } go funnel ( iter ) for _ , item := range others { go funnel ( item ) } go func ( ) { wg . Wait ( ) close ( retval ) } ( ) return retval }

// Merge takes the results of this Enumerator and others, and funnels them into
// a single Enumerator. The order of in which they will be combined is non-deterministic.

Merge takes the results of this Enumerator and others and funnels them into a single Enumerator . The order of in which they will be combined is non - deterministic .


func ParallelSelect(original Enumerable, operation Transform) Enumerable {
	return parallelSelecter{
		original:  original,
		operation: operation,
	}
}

func ParallelSelect ( original Enumerable , operation Transform ) Enumerable { return parallelSelecter { original : original , operation : operation , } }

// ParallelSelect creates an Enumerable which will use all logically available CPUs to
// execute a Transform.

ParallelSelect creates an Enumerable which will use all logically available CPUs to execute a Transform .


func (iter Enumerator) ParallelSelect(operation Transform) Enumerator {
	if cpus := runtime.NumCPU(); cpus != 1 {
		intermediate := iter.splitN(operation, uint(cpus))
		return intermediate[0].Merge(intermediate[1:]...)
	}
	return iter
}

func ( iter Enumerator ) ParallelSelect ( operation Transform ) Enumerator { if cpus := runtime . NumCPU ( ) ; cpus != 1 { intermediate := iter . splitN ( operation , uint ( cpus ) ) return intermediate [ 0 ] . Merge ( intermediate [ 1 : ] ... ) } return iter }

// ParallelSelect will execute a Transform across all logical CPUs available to the current process.

ParallelSelect will execute a Transform across all logical CPUs available to the current process .


func (iter Enumerator) Reverse() Enumerator {
	cache := NewStack()
	for entry := range iter {
		cache.Push(entry)
	}

	retval := make(chan interface{})

	go func() {
		for !cache.IsEmpty() {
			val, _ := cache.Pop()
			retval <- val
		}
		close(retval)
	}()
	return retval
}

func ( iter Enumerator ) Reverse ( ) Enumerator { cache := NewStack ( ) for entry := range iter { cache . Push ( entry ) } retval := make ( chan interface { } ) go func ( ) { for ! cache . IsEmpty ( ) { val , _ := cache . Pop ( ) retval <- val } close ( retval ) } ( ) return retval }

// Reverse returns items in the opposite order it encountered them in.

Reverse returns items in the opposite order it encountered them in .


func Select(subject Enumerable, transform Transform) Enumerable {
	return selecter{
		original:  subject,
		transform: transform,
	}
}

func Select ( subject Enumerable , transform Transform ) Enumerable { return selecter { original : subject , transform : transform , } }

// Select creates a reusable stream of transformed values.

Select creates a reusable stream of transformed values .


func (iter Enumerator) Select(transform Transform) Enumerator {
	retval := make(chan interface{})

	go func() {
		for item := range iter {
			retval <- transform(item)
		}
		close(retval)
	}()

	return retval
}

func ( iter Enumerator ) Select ( transform Transform ) Enumerator { retval := make ( chan interface { } ) go func ( ) { for item := range iter { retval <- transform ( item ) } close ( retval ) } ( ) return retval }

// Select iterates over a list and returns a transformed item.

Select iterates over a list and returns a transformed item .


func SelectMany(subject Enumerable, toMany Unfolder) Enumerable {
	return selectManyer{
		original: subject,
		toMany:   toMany,
	}
}

func SelectMany ( subject Enumerable , toMany Unfolder ) Enumerable { return selectManyer { original : subject , toMany : toMany , } }

// SelectMany allows for unfolding of values.

SelectMany allows for unfolding of values .


func (iter Enumerator) SelectMany(lister Unfolder) Enumerator {
	retval := make(chan interface{})

	go func() {
		for parent := range iter {
			for child := range lister(parent) {
				retval <- child
			}
		}
		close(retval)
	}()

	return retval
}

func ( iter Enumerator ) SelectMany ( lister Unfolder ) Enumerator { retval := make ( chan interface { } ) go func ( ) { for parent := range iter { for child := range lister ( parent ) { retval <- child } } close ( retval ) } ( ) return retval }

// SelectMany allows for flattening of data structures.

SelectMany allows for flattening of data structures .


func Single(iter Enumerable) (retval interface{}, err error) {
	done := make(chan struct{})
	defer close(done)

	err = errNoElements

	firstPass := true
	for entry := range iter.Enumerate(done) {
		if firstPass {
			retval = entry
			err = nil
		} else {
			retval = nil
			err = errMultipleElements
			break
		}
		firstPass = false
	}
	return
}

func Single ( iter Enumerable ) ( retval interface { } , err error ) { done := make ( chan struct { } ) defer close ( done ) err = errNoElements firstPass := true for entry := range iter . Enumerate ( done ) { if firstPass { retval = entry err = nil } else { retval = nil err = errMultipleElements break } firstPass = false } return }

// Single retreives the only element from a list, or returns nil and an error.

Single retreives the only element from a list or returns nil and an error .


func Singlep(iter Enumerable, pred Predicate) (retval interface{}, err error) {
	iter = Where(iter, pred)
	return Single(iter)
}

func Singlep ( iter Enumerable , pred Predicate ) ( retval interface { } , err error ) { iter = Where ( iter , pred ) return Single ( iter ) }

// Singlep retrieces the only element from a list that matches a criteria. If
// no match is found, or two or more are found, `Singlep` returns nil and an
// error.

Singlep retrieces the only element from a list that matches a criteria . If no match is found or two or more are found Singlep returns nil and an error .


func Skip(subject Enumerable, n uint) Enumerable {
	return skipper{
		original:  subject,
		skipCount: n,
	}
}

func Skip ( subject Enumerable , n uint ) Enumerable { return skipper { original : subject , skipCount : n , } }

// Skip creates a reusable stream which will skip the first `n` elements before iterating
// over the rest of the elements in an Enumerable.

Skip creates a reusable stream which will skip the first n elements before iterating over the rest of the elements in an Enumerable .


func (iter Enumerator) splitN(operation Transform, n uint) []Enumerator {
	results, cast := make([]chan interface{}, n, n), make([]Enumerator, n, n)

	for i := uint(0); i < n; i++ {
		results[i] = make(chan interface{})
		cast[i] = results[i]
	}

	go func() {
		for i := uint(0); i < n; i++ {
			go func(addr uint) {
				defer close(results[addr])
				for {
					read, ok := <-iter
					if !ok {
						return
					}
					results[addr] <- operation(read)
				}
			}(i)
		}
	}()

	return cast
}

func ( iter Enumerator ) splitN ( operation Transform , n uint ) [ ] Enumerator { results , cast := make ( [ ] chan interface { } , n , n ) , make ( [ ] Enumerator , n , n ) for i := uint ( 0 ) ; i < n ; i ++ { results [ i ] = make ( chan interface { } ) cast [ i ] = results [ i ] } go func ( ) { for i := uint ( 0 ) ; i < n ; i ++ { go func ( addr uint ) { defer close ( results [ addr ] ) for { read , ok := <- iter if ! ok { return } results [ addr ] <- operation ( read ) } } ( i ) } } ( ) return cast }

// splitN creates N Enumerators, each will be a subset of the original Enumerator and will have
// distinct populations from one another.

splitN creates N Enumerators each will be a subset of the original Enumerator and will have distinct populations from one another .


func Take(subject Enumerable, n uint) Enumerable {
	return taker{
		original: subject,
		n:        n,
	}
}

func Take ( subject Enumerable , n uint ) Enumerable { return taker { original : subject , n : n , } }

// Take retreives just the first `n` elements from an Enumerable.

Take retreives just the first n elements from an Enumerable .


func (iter Enumerator) Take(n uint) Enumerator {
	results := make(chan interface{})

	go func() {
		defer close(results)
		i := uint(0)
		for entry := range iter {
			if i >= n {
				return
			}
			i++
			results <- entry
		}
	}()

	return results
}

func ( iter Enumerator ) Take ( n uint ) Enumerator { results := make ( chan interface { } ) go func ( ) { defer close ( results ) i := uint ( 0 ) for entry := range iter { if i >= n { return } i ++ results <- entry } } ( ) return results }

// Take retreives just the first 'n' elements from an Enumerator.

Take retreives just the first n elements from an Enumerator .


func TakeWhile(subject Enumerable, criteria func(interface{}, uint) bool) Enumerable {
	return takeWhiler{
		original: subject,
		criteria: criteria,
	}
}

func TakeWhile ( subject Enumerable , criteria func ( interface { } , uint ) bool ) Enumerable { return takeWhiler { original : subject , criteria : criteria , } }

// TakeWhile creates a reusable stream which will halt once some criteria is no longer met.

TakeWhile creates a reusable stream which will halt once some criteria is no longer met .


func (iter Enumerator) TakeWhile(criteria func(interface{}, uint) bool) Enumerator {
	results := make(chan interface{})

	go func() {
		defer close(results)
		i := uint(0)
		for entry := range iter {
			if !criteria(entry, i) {
				return
			}
			i++
			results <- entry
		}
	}()

	return results
}

func ( iter Enumerator ) TakeWhile ( criteria func ( interface { } , uint ) bool ) Enumerator { results := make ( chan interface { } ) go func ( ) { defer close ( results ) i := uint ( 0 ) for entry := range iter { if ! criteria ( entry , i ) { return } i ++ results <- entry } } ( ) return results }

// TakeWhile continues returning items as long as 'criteria' holds true.

TakeWhile continues returning items as long as criteria holds true .


func (iter Enumerator) Tee() (Enumerator, Enumerator) {
	left, right := make(chan interface{}), make(chan interface{})

	go func() {
		for entry := range iter {
			left <- entry
			right <- entry
		}
		close(left)
		close(right)
	}()

	return left, right
}

func ( iter Enumerator ) Tee ( ) ( Enumerator , Enumerator ) { left , right := make ( chan interface { } ) , make ( chan interface { } ) go func ( ) { for entry := range iter { left <- entry right <- entry } close ( left ) close ( right ) } ( ) return left , right }

// Tee creates two Enumerators which will have identical contents as one another.

Tee creates two Enumerators which will have identical contents as one another .


func (iter Enumerator) ToSlice() []interface{} {
	retval := make([]interface{}, 0)
	for entry := range iter {
		retval = append(retval, entry)
	}
	return retval
}

func ( iter Enumerator ) ToSlice ( ) [ ] interface { } { retval := make ( [ ] interface { } , 0 ) for entry := range iter { retval = append ( retval , entry ) } return retval }

// ToSlice places all iterated over values in a Slice for easy consumption.

ToSlice places all iterated over values in a Slice for easy consumption .


func Where(original Enumerable, p Predicate) Enumerable {
	return wherer{
		original: original,
		filter:   p,
	}
}

func Where ( original Enumerable , p Predicate ) Enumerable { return wherer { original : original , filter : p , } }

// Where creates a reusable means of filtering a stream.

Where creates a reusable means of filtering a stream .


func (iter Enumerator) Where(predicate Predicate) Enumerator {
	retval := make(chan interface{})
	go func() {
		for item := range iter {
			if predicate(item) {
				retval <- item
			}
		}
		close(retval)
	}()

	return retval
}

func ( iter Enumerator ) Where ( predicate Predicate ) Enumerator { retval := make ( chan interface { } ) go func ( ) { for item := range iter { if predicate ( item ) { retval <- item } } close ( retval ) } ( ) return retval }

// Where iterates over a list and returns only the elements that satisfy a
// predicate.

Where iterates over a list and returns only the elements that satisfy a predicate .


func ReleaseBuffer(buf *bytes.Buffer) {
	if buf != nil {
		buf.Reset()
		bufferPool.Put(buf)
	}
}

func ReleaseBuffer ( buf * bytes . Buffer ) { if buf != nil { buf . Reset ( ) bufferPool . Put ( buf ) } }

// ReleaseBuffer returns a buffer to the pool to be re-used.

ReleaseBuffer returns a buffer to the pool to be re - used .


func NewStack(entries ...interface{}) *Stack {
	retval := &Stack{}
	retval.underlyer = NewLinkedList()

	for _, entry := range entries {
		retval.Push(entry)
	}
	return retval
}

func NewStack ( entries ... interface { } ) * Stack { retval := & Stack { } retval . underlyer = NewLinkedList ( ) for _ , entry := range entries { retval . Push ( entry ) } return retval }

// NewStack instantiates a new FILO structure.

NewStack instantiates a new FILO structure .


func (stack *Stack) Enumerate(cancel <-chan struct{}) Enumerator {
	stack.key.RLock()
	defer stack.key.RUnlock()

	return stack.underlyer.Enumerate(cancel)
}

func ( stack * Stack ) Enumerate ( cancel <- chan struct { } ) Enumerator { stack . key . RLock ( ) defer stack . key . RUnlock ( ) return stack . underlyer . Enumerate ( cancel ) }

// Enumerate peeks at each element in the stack without mutating it.

Enumerate peeks at each element in the stack without mutating it .


func (stack *Stack) IsEmpty() bool {
	stack.key.RLock()
	defer stack.key.RUnlock()
	return stack.underlyer == nil || stack.underlyer.IsEmpty()
}

func ( stack * Stack ) IsEmpty ( ) bool { stack . key . RLock ( ) defer stack . key . RUnlock ( ) return stack . underlyer == nil || stack . underlyer . IsEmpty ( ) }

// IsEmpty tests the Stack to determine if it is populate or not.

IsEmpty tests the Stack to determine if it is populate or not .


func (stack *Stack) Push(entry interface{}) {
	stack.key.Lock()
	defer stack.key.Unlock()

	if nil == stack.underlyer {
		stack.underlyer = NewLinkedList()
	}
	stack.underlyer.AddFront(entry)
}

func ( stack * Stack ) Push ( entry interface { } ) { stack . key . Lock ( ) defer stack . key . Unlock ( ) if nil == stack . underlyer { stack . underlyer = NewLinkedList ( ) } stack . underlyer . AddFront ( entry ) }

// Push adds an entry to the top of the Stack.

Push adds an entry to the top of the Stack .


func (stack *Stack) Pop() (interface{}, bool) {
	stack.key.Lock()
	defer stack.key.Unlock()

	if nil == stack.underlyer {
		return nil, false
	}
	return stack.underlyer.RemoveFront()
}

func ( stack * Stack ) Pop ( ) ( interface { } , bool ) { stack . key . Lock ( ) defer stack . key . Unlock ( ) if nil == stack . underlyer { return nil , false } return stack . underlyer . RemoveFront ( ) }

// Pop returns the entry at the top of the Stack then removes it.

Pop returns the entry at the top of the Stack then removes it .


func (stack *Stack) Peek() (interface{}, bool) {
	stack.key.RLock()
	defer stack.key.RUnlock()
	return stack.underlyer.PeekFront()
}

func ( stack * Stack ) Peek ( ) ( interface { } , bool ) { stack . key . RLock ( ) defer stack . key . RUnlock ( ) return stack . underlyer . PeekFront ( ) }

// Peek returns the entry at the top of the Stack without removing it.

Peek returns the entry at the top of the Stack without removing it .


func (stack *Stack) Size() uint {
	stack.key.RLock()
	defer stack.key.RUnlock()
	if stack.underlyer == nil {
		return 0
	}
	return stack.underlyer.Length()
}

func ( stack * Stack ) Size ( ) uint { stack . key . RLock ( ) defer stack . key . RUnlock ( ) if stack . underlyer == nil { return 0 } return stack . underlyer . Length ( ) }

// Size returns the number of entries populating the Stack.

Size returns the number of entries populating the Stack .


func NewLinkedList(entries ...interface{}) *LinkedList {
	list := &LinkedList{}

	for _, entry := range entries {
		list.AddBack(entry)
	}

	return list
}

func NewLinkedList ( entries ... interface { } ) * LinkedList { list := & LinkedList { } for _ , entry := range entries { list . AddBack ( entry ) } return list }

// NewLinkedList instantiates a new LinkedList with the entries provided.

NewLinkedList instantiates a new LinkedList with the entries provided .


func (list *LinkedList) AddBack(entry interface{}) {
	toAppend := &llNode{
		payload: entry,
	}

	list.key.Lock()
	defer list.key.Unlock()

	list.length++

	if list.first == nil {
		list.first = toAppend
		list.last = toAppend
		return
	}

	list.last.next = toAppend
	list.last = toAppend
}

func ( list * LinkedList ) AddBack ( entry interface { } ) { toAppend := & llNode { payload : entry , } list . key . Lock ( ) defer list . key . Unlock ( ) list . length ++ if list . first == nil { list . first = toAppend list . last = toAppend return } list . last . next = toAppend list . last = toAppend }

// AddBack creates an entry in the LinkedList that is logically at the back of the list.

AddBack creates an entry in the LinkedList that is logically at the back of the list .


func (list *LinkedList) Enumerate(cancel <-chan struct{}) Enumerator {
	retval := make(chan interface{})

	go func() {
		list.key.RLock()
		defer list.key.RUnlock()
		defer close(retval)

		current := list.first
		for current != nil {
			select {
			case retval <- current.payload:
				break
			case <-cancel:
				return
			}
			current = current.next
		}
	}()

	return retval
}

func ( list * LinkedList ) Enumerate ( cancel <- chan struct { } ) Enumerator { retval := make ( chan interface { } ) go func ( ) { list . key . RLock ( ) defer list . key . RUnlock ( ) defer close ( retval ) current := list . first for current != nil { select { case retval <- current . payload : break case <- cancel : return } current = current . next } } ( ) return retval }

// Enumerate creates a new instance of Enumerable which can be executed on.

Enumerate creates a new instance of Enumerable which can be executed on .


func (list *LinkedList) Get(pos uint) (interface{}, bool) {
	list.key.RLock()
	defer list.key.RUnlock()
	node, ok := get(list.first, pos)
	if ok {
		return node.payload, true
	}
	return nil, false
}

func ( list * LinkedList ) Get ( pos uint ) ( interface { } , bool ) { list . key . RLock ( ) defer list . key . RUnlock ( ) node , ok := get ( list . first , pos ) if ok { return node . payload , true } return nil , false }

// Get finds the value from the LinkedList.
// pos is expressed as a zero-based index begining from the 'front' of the list.

Get finds the value from the LinkedList . pos is expressed as a zero - based index begining from the front of the list .


func (list *LinkedList) IsEmpty() bool {
	list.key.RLock()
	defer list.key.RUnlock()

	return list.first == nil
}

func ( list * LinkedList ) IsEmpty ( ) bool { list . key . RLock ( ) defer list . key . RUnlock ( ) return list . first == nil }

// IsEmpty tests the list to determine if it is populate or not.

IsEmpty tests the list to determine if it is populate or not .


func (list *LinkedList) Length() uint {
	list.key.RLock()
	defer list.key.RUnlock()

	return list.length
}

func ( list * LinkedList ) Length ( ) uint { list . key . RLock ( ) defer list . key . RUnlock ( ) return list . length }

// Length returns the number of elements present in the LinkedList.

Length returns the number of elements present in the LinkedList .


func (list *LinkedList) PeekBack() (interface{}, bool) {
	list.key.RLock()
	defer list.key.RUnlock()

	if list.last == nil {
		return nil, false
	}
	return list.last.payload, true
}

func ( list * LinkedList ) PeekBack ( ) ( interface { } , bool ) { list . key . RLock ( ) defer list . key . RUnlock ( ) if list . last == nil { return nil , false } return list . last . payload , true }

// PeekBack returns the entry logicall stored at the back of the list without removing it.

PeekBack returns the entry logicall stored at the back of the list without removing it .


func (list *LinkedList) PeekFront() (interface{}, bool) {
	list.key.RLock()
	defer list.key.RUnlock()

	if list.first == nil {
		return nil, false
	}
	return list.first.payload, true
}

func ( list * LinkedList ) PeekFront ( ) ( interface { } , bool ) { list . key . RLock ( ) defer list . key . RUnlock ( ) if list . first == nil { return nil , false } return list . first . payload , true }

// PeekFront returns the entry logically stored at the front of this list without removing it.

PeekFront returns the entry logically stored at the front of this list without removing it .


func (list *LinkedList) RemoveFront() (interface{}, bool) {
	list.key.Lock()
	defer list.key.Unlock()

	if list.first == nil {
		return nil, false
	}

	retval := list.first.payload

	list.first = list.first.next
	list.length--

	if 0 == list.length {
		list.last = nil
	}

	return retval, true
}

func ( list * LinkedList ) RemoveFront ( ) ( interface { } , bool ) { list . key . Lock ( ) defer list . key . Unlock ( ) if list . first == nil { return nil , false } retval := list . first . payload list . first = list . first . next list . length -- if 0 == list . length { list . last = nil } return retval , true }

// RemoveFront returns the entry logically stored at the front of this list and removes it.

RemoveFront returns the entry logically stored at the front of this list and removes it .


func (list *LinkedList) RemoveBack() (interface{}, bool) {
	list.key.Lock()
	defer list.key.Unlock()

	if list.last == nil {
		return nil, false
	}

	retval := list.last.payload
	list.length--

	if list.length == 0 {
		list.first = nil
	} else {
		node, _ := get(list.first, list.length-1)
		node.next = nil
	}
	return retval, true
}

func ( list * LinkedList ) RemoveBack ( ) ( interface { } , bool ) { list . key . Lock ( ) defer list . key . Unlock ( ) if list . last == nil { return nil , false } retval := list . last . payload list . length -- if list . length == 0 { list . first = nil } else { node , _ := get ( list . first , list . length - 1 ) node . next = nil } return retval , true }

// RemoveBack returns the entry logically stored at the back of this list and removes it.

RemoveBack returns the entry logically stored at the back of this list and removes it .


func (list *LinkedList) Sort(comparator Comparator) error {
	list.key.Lock()
	defer list.key.Unlock()
	var err error
	list.first, err = mergeSort(list.first, comparator)
	if err != nil {
		return err
	}
	list.last = findLast(list.first)
	return err
}

func ( list * LinkedList ) Sort ( comparator Comparator ) error { list . key . Lock ( ) defer list . key . Unlock ( ) var err error list . first , err = mergeSort ( list . first , comparator ) if err != nil { return err } list . last = findLast ( list . first ) return err }

// Sort rearranges the positions of the entries in this list so that they are
// ascending.

Sort rearranges the positions of the entries in this list so that they are ascending .


func (list *LinkedList) Sorta() error {
	list.key.Lock()
	defer list.key.Unlock()

	var err error
	list.first, err = mergeSort(list.first, func(a, b interface{}) (int, error) {
		castA, ok := a.(string)
		if !ok {
			return 0, ErrUnexpectedType
		}
		castB, ok := b.(string)
		if !ok {
			return 0, ErrUnexpectedType
		}

		return strings.Compare(castA, castB), nil
	})
	list.last = findLast(list.first)
	return err
}

func ( list * LinkedList ) Sorta ( ) error { list . key . Lock ( ) defer list . key . Unlock ( ) var err error list . first , err = mergeSort ( list . first , func ( a , b interface { } ) ( int , error ) { castA , ok := a . ( string ) if ! ok { return 0 , ErrUnexpectedType } castB , ok := b . ( string ) if ! ok { return 0 , ErrUnexpectedType } return strings . Compare ( castA , castB ) , nil } ) list . last = findLast ( list . first ) return err }

// Sorta rearranges the position of string entries in this list so that they
// are ascending.

Sorta rearranges the position of string entries in this list so that they are ascending .


func (list *LinkedList) Sorti() (err error) {
	list.key.Lock()
	defer list.key.Unlock()

	list.first, err = mergeSort(list.first, func(a, b interface{}) (int, error) {
		castA, ok := a.(int)
		if !ok {
			return 0, ErrUnexpectedType
		}
		castB, ok := b.(int)
		if !ok {
			return 0, ErrUnexpectedType
		}

		return castA - castB, nil
	})
	if err != nil {
		return
	}
	list.last = findLast(list.first)
	return
}

func ( list * LinkedList ) Sorti ( ) ( err error ) { list . key . Lock ( ) defer list . key . Unlock ( ) list . first , err = mergeSort ( list . first , func ( a , b interface { } ) ( int , error ) { castA , ok := a . ( int ) if ! ok { return 0 , ErrUnexpectedType } castB , ok := b . ( int ) if ! ok { return 0 , ErrUnexpectedType } return castA - castB , nil } ) if err != nil { return } list . last = findLast ( list . first ) return }

// Sorti rearranges the position of integer entries in this list so that they
// are ascending.

Sorti rearranges the position of integer entries in this list so that they are ascending .


func (list *LinkedList) String() string {
	list.key.RLock()
	defer list.key.RUnlock()

	builder := bytes.NewBufferString("[")
	current := list.first
	for i := 0; i < 15 && current != nil; i++ {
		builder.WriteString(fmt.Sprintf("%v ", current.payload))
		current = current.next
	}
	if current == nil || current.next == nil {
		builder.Truncate(builder.Len() - 1)
	} else {
		builder.WriteString("...")
	}
	builder.WriteRune(']')
	return builder.String()
}

func ( list * LinkedList ) String ( ) string { list . key . RLock ( ) defer list . key . RUnlock ( ) builder := bytes . NewBufferString ( " " ) current := list . first for i := 0 ; i < 15 && current != nil ; i ++ { builder . WriteString ( fmt . Sprintf ( " " , current . payload ) ) current = current . next } if current == nil || current . next == nil { builder . Truncate ( builder . Len ( ) - 1 ) } else { builder . WriteString ( " " ) } builder . WriteRune ( ']' ) return builder . String ( ) }

// String prints upto the first fifteen elements of the list in string format.

String prints upto the first fifteen elements of the list in string format .


func (list *LinkedList) Swap(x, y uint) error {
	list.key.Lock()
	defer list.key.Unlock()

	var xNode, yNode *llNode
	if temp, ok := get(list.first, x); ok {
		xNode = temp
	} else {
		return fmt.Errorf("index out of bounds 'x', wanted less than %d got %d", list.length, x)
	}
	if temp, ok := get(list.first, y); ok {
		yNode = temp
	} else {
		return fmt.Errorf("index out of bounds 'y', wanted less than %d got %d", list.length, y)
	}

	temp := xNode.payload
	xNode.payload = yNode.payload
	yNode.payload = temp
	return nil
}

func ( list * LinkedList ) Swap ( x , y uint ) error { list . key . Lock ( ) defer list . key . Unlock ( ) var xNode , yNode * llNode if temp , ok := get ( list . first , x ) ; ok { xNode = temp } else { return fmt . Errorf ( " " , list . length , x ) } if temp , ok := get ( list . first , y ) ; ok { yNode = temp } else { return fmt . Errorf ( " " , list . length , y ) } temp := xNode . payload xNode . payload = yNode . payload yNode . payload = temp return nil }

// Swap switches the positions in which two values are stored in this list.
// x and y represent the indexes of the items that should be swapped.

Swap switches the positions in which two values are stored in this list . x and y represent the indexes of the items that should be swapped .


func merge(left, right *llNode, comparator Comparator) (first *llNode, err error) {
	curLeft := left
	curRight := right

	var last *llNode

	appendResults := func(updated *llNode) {
		if last == nil {
			last = updated
		} else {
			last.next = updated
			last = last.next
		}
		if first == nil {
			first = last
		}
	}

	for curLeft != nil && curRight != nil {
		var res int
		if res, err = comparator(curLeft.payload, curRight.payload); nil != err {
			break // Don't return, stitch the remaining elements back on.
		} else if res < 0 {
			appendResults(curLeft)
			curLeft = curLeft.next
		} else {
			appendResults(curRight)
			curRight = curRight.next
		}
	}

	if curLeft != nil {
		appendResults(curLeft)
	}
	if curRight != nil {
		appendResults(curRight)
	}
	return
}

// merge takes two sorted lists and merges them into one sorted list.
// Behavior is undefined when you pass a non-sorted list as `left` or `right`

merge takes two sorted lists and merges them into one sorted list . Behavior is undefined when you pass a non - sorted list as left or right


func split(head *llNode) (left, right *llNode) {
	left = head
	if head == nil || head.next == nil {
		return
	}
	right = head
	sprinter := head
	prev := head
	for sprinter != nil && sprinter.next != nil {
		prev = right
		right = right.next
		sprinter = sprinter.next.next
	}
	prev.next = nil
	return
}

func split ( head * llNode ) ( left , right * llNode ) { left = head if head == nil || head . next == nil { return } right = head sprinter := head prev := head for sprinter != nil && sprinter . next != nil { prev = right right = right . next sprinter = sprinter . next . next } prev . next = nil return }


func (q *Queue) Add(entry interface{}) {
	q.key.Lock()
	defer q.key.Unlock()
	if nil == q.underlyer {
		q.underlyer = NewLinkedList()
	}
	q.underlyer.AddBack(entry)
}

func ( q * Queue ) Add ( entry interface { } ) { q . key . Lock ( ) defer q . key . Unlock ( ) if nil == q . underlyer { q . underlyer = NewLinkedList ( ) } q . underlyer . AddBack ( entry ) }

// Add places an item at the back of the Queue.

Add places an item at the back of the Queue .


func (q *Queue) Enumerate(cancel <-chan struct{}) Enumerator {
	q.key.RLock()
	defer q.key.RUnlock()
	return q.underlyer.Enumerate(cancel)
}

func ( q * Queue ) Enumerate ( cancel <- chan struct { } ) Enumerator { q . key . RLock ( ) defer q . key . RUnlock ( ) return q . underlyer . Enumerate ( cancel ) }

// Enumerate peeks at each element of this queue without mutating it.

Enumerate peeks at each element of this queue without mutating it .


func (q *Queue) IsEmpty() bool {
	q.key.RLock()
	defer q.key.RUnlock()
	return q.underlyer == nil || q.underlyer.IsEmpty()
}

func ( q * Queue ) IsEmpty ( ) bool { q . key . RLock ( ) defer q . key . RUnlock ( ) return q . underlyer == nil || q . underlyer . IsEmpty ( ) }

// IsEmpty tests the Queue to determine if it is populate or not.

IsEmpty tests the Queue to determine if it is populate or not .


func (q *Queue) Length() uint {
	q.key.RLock()
	defer q.key.RUnlock()
	if nil == q.underlyer {
		return 0
	}
	return q.underlyer.length
}

func ( q * Queue ) Length ( ) uint { q . key . RLock ( ) defer q . key . RUnlock ( ) if nil == q . underlyer { return 0 } return q . underlyer . length }

// Length returns the number of items in the Queue.

Length returns the number of items in the Queue .


func (q *Queue) Next() (interface{}, bool) {
	q.key.Lock()
	defer q.key.Unlock()
	if q.underlyer == nil {
		return nil, false
	}
	return q.underlyer.RemoveFront()
}

func ( q * Queue ) Next ( ) ( interface { } , bool ) { q . key . Lock ( ) defer q . key . Unlock ( ) if q . underlyer == nil { return nil , false } return q . underlyer . RemoveFront ( ) }

// Next removes and returns the next item in the Queue.

Next removes and returns the next item in the Queue .


func (q *Queue) Peek() (interface{}, bool) {
	q.key.RLock()
	defer q.key.RUnlock()
	if q.underlyer == nil {
		return nil, false
	}
	return q.underlyer.PeekFront()
}

func ( q * Queue ) Peek ( ) ( interface { } , bool ) { q . key . RLock ( ) defer q . key . RUnlock ( ) if q . underlyer == nil { return nil , false } return q . underlyer . PeekFront ( ) }

// Peek returns the next item in the Queue without removing it.

Peek returns the next item in the Queue without removing it .


func (q *Queue) ToSlice() []interface{} {
	q.key.RLock()
	defer q.key.RUnlock()

	if q.underlyer == nil {
		return []interface{}{}
	}
	return q.underlyer.ToSlice()
}

func ( q * Queue ) ToSlice ( ) [ ] interface { } { q . key . RLock ( ) defer q . key . RUnlock ( ) if q . underlyer == nil { return [ ] interface { } { } } return q . underlyer . ToSlice ( ) }

// ToSlice converts a Queue into a slice.


func EnableVirtualTerminalProcessing(fd int) error {
	var st uint32
	err := windows.GetConsoleMode(windows.Handle(fd), &st)
	if err != nil {
		return err
	}
	if st&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0 {
		return windows.SetConsoleMode(windows.Handle(fd), st|windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING)
	}
	return nil
}

func EnableVirtualTerminalProcessing ( fd int ) error { var st uint32 err := windows . GetConsoleMode ( windows . Handle ( fd ) , & st ) if err != nil { return err } if st & windows . ENABLE_VIRTUAL_TERMINAL_PROCESSING == 0 { return windows . SetConsoleMode ( windows . Handle ( fd ) , st | windows . ENABLE_VIRTUAL_TERMINAL_PROCESSING ) } return nil }

// EnableVirtualTerminalProcessing configures the terminal to accept ANSI
// sequences. This is a no-op for all operating systems other than Windows.

EnableVirtualTerminalProcessing configures the terminal to accept ANSI sequences . This is a no - op for all operating systems other than Windows .


func unquote(input []byte, buf []byte) (unquoted []byte, remainder []byte) {
	var (
		errorIndicator = []byte("???")
	)
	if len(input) < 2 {
		return errorIndicator, buf

	}
	quote := input[0]
	input = input[1:]
	if input[len(input)-1] == quote {
		input = input[:len(input)-1]
	}
	index := bytes.IndexRune(input, '\\')
	if index < 0 {
		// input does not contain any escaped chars
		remainder = buf
		unquoted = input
		return unquoted, remainder
	}
	if len(buf) > 0 {
		unquoted = buf[:0]
	}
	strinput := toString(input)
	for len(strinput) > 0 {
		r, mb, tail, err := strconv.UnquoteChar(strinput, quote)
		if err != nil {
			return errorIndicator, buf
		}
		strinput = tail
		if mb {
			// ensure that there is enough room for the multibyte char
			runeLen := utf8.RuneLen(r)
			unquotedLen := len(unquoted)
			for i := 0; i < runeLen; i++ {
				unquoted = append(unquoted, 0)
			}
			utf8.EncodeRune(unquoted[unquotedLen:], r)
		} else {
			unquoted = append(unquoted, byte(r))
		}
	}

	if len(buf) < len(unquoted) {
		// used buf up and resorted to memory allocation
		remainder = nil
	} else {
		remainder = buf[len(unquoted):]
	}

	return unquoted, remainder
}

// unquote the input. If possible the unquoted value points to the same
// backing array as input. Otherwise it points to buf. The remainder is
// the unused portion of buf.

unquote the input . If possible the unquoted value points to the same backing array as input . Otherwise it points to buf . The remainder is the unused portion of buf .


func countScalars(input []interface{}) int {
	for i := 0; i < len(input); i++ {
		switch input[i].(type) {
		case keyvalser:
			return i
		}
	}
	return len(input)
}

func countScalars ( input [ ] interface { } ) int { for i := 0 ; i < len ( input ) ; i ++ { switch input [ i ] . ( type ) { case keyvalser : return i } } return len ( input ) }

// countScalars returns the count of items in input up to but
// not including the first non-scalar item. A scalar is a single
// value item, ie not a keyvalser.

countScalars returns the count of items in input up to but not including the first non - scalar item . A scalar is a single value item ie not a keyvalser .


func IsTerminal(writer io.Writer) bool {
	if fd, ok := fileDescriptor(writer); ok {
		return terminal.IsTerminal(fd)
	}
	return false
}

func IsTerminal ( writer io . Writer ) bool { if fd , ok := fileDescriptor ( writer ) ; ok { return terminal . IsTerminal ( fd ) } return false }

// IsTerminal returns true if the writer is a terminal.

IsTerminal returns true if the writer is a terminal .


func (l *List) Add(entries ...interface{}) {
	l.key.Lock()
	defer l.key.Unlock()
	l.underlyer = append(l.underlyer, entries...)
}

func ( l * List ) Add ( entries ... interface { } ) { l . key . Lock ( ) defer l . key . Unlock ( ) l . underlyer = append ( l . underlyer , entries ... ) }

// Add appends an entry to the logical end of the List.

Add appends an entry to the logical end of the List .


func (l *List) AddAt(pos uint, entries ...interface{}) {
	l.key.Lock()
	defer l.key.Unlock()

	l.underlyer = append(l.underlyer[:pos], append(entries, l.underlyer[pos:]...)...)
}

func ( l * List ) AddAt ( pos uint , entries ... interface { } ) { l . key . Lock ( ) defer l . key . Unlock ( ) l . underlyer = append ( l . underlyer [ : pos ] , append ( entries , l . underlyer [ pos : ] ... ) ... ) }

// AddAt injects values beginning at `pos`. If multiple values
// are provided in `entries` they are placed in the same order
// they are provided.

AddAt injects values beginning at pos . If multiple values are provided in entries they are placed in the same order they are provided .


func (l *List) Enumerate(cancel <-chan struct{}) Enumerator {
	retval := make(chan interface{})

	go func() {
		l.key.RLock()
		defer l.key.RUnlock()
		defer close(retval)

		for _, entry := range l.underlyer {
			select {
			case retval <- entry:
				break
			case <-cancel:
				return
			}
		}
	}()

	return retval
}

func ( l * List ) Enumerate ( cancel <- chan struct { } ) Enumerator { retval := make ( chan interface { } ) go func ( ) { l . key . RLock ( ) defer l . key . RUnlock ( ) defer close ( retval ) for _ , entry := range l . underlyer { select { case retval <- entry : break case <- cancel : return } } } ( ) return retval }

// Enumerate lists each element present in the collection


func (l *List) Get(pos uint) (interface{}, bool) {
	l.key.RLock()
	defer l.key.RUnlock()

	if pos > uint(len(l.underlyer)) {
		return nil, false
	}
	return l.underlyer[pos], true
}

func ( l * List ) Get ( pos uint ) ( interface { } , bool ) { l . key . RLock ( ) defer l . key . RUnlock ( ) if pos > uint ( len ( l . underlyer ) ) { return nil , false } return l . underlyer [ pos ] , true }

// Get retreives the value stored in a particular position of the list.
// If no item exists at the given position, the second parameter will be
// returned as false.

Get retreives the value stored in a particular position of the list . If no item exists at the given position the second parameter will be returned as false .


func (l *List) IsEmpty() bool {
	l.key.RLock()
	defer l.key.RUnlock()
	return 0 == len(l.underlyer)
}

func ( l * List ) IsEmpty ( ) bool { l . key . RLock ( ) defer l . key . RUnlock ( ) return 0 == len ( l . underlyer ) }

// IsEmpty tests to see if this List has any elements present.

IsEmpty tests to see if this List has any elements present .


func (l *List) Length() uint {
	l.key.RLock()
	defer l.key.RUnlock()
	return uint(len(l.underlyer))
}

func ( l * List ) Length ( ) uint { l . key . RLock ( ) defer l . key . RUnlock ( ) return uint ( len ( l . underlyer ) ) }

// Length returns the number of elements in the List.

Length returns the number of elements in the List .


func (l *List) Remove(pos uint) (interface{}, bool) {
	l.key.Lock()
	defer l.key.Unlock()

	if pos > uint(len(l.underlyer)) {
		return nil, false
	}
	retval := l.underlyer[pos]
	l.underlyer = append(l.underlyer[:pos], l.underlyer[pos+1:]...)
	return retval, true
}

func ( l * List ) Remove ( pos uint ) ( interface { } , bool ) { l . key . Lock ( ) defer l . key . Unlock ( ) if pos > uint ( len ( l . underlyer ) ) { return nil , false } retval := l . underlyer [ pos ] l . underlyer = append ( l . underlyer [ : pos ] , l . underlyer [ pos + 1 : ] ... ) return retval , true }

// Remove retreives a value from this List and shifts all other values.

Remove retreives a value from this List and shifts all other values .


func (l *List) Set(pos uint, val interface{}) bool {
	l.key.Lock()
	defer l.key.Unlock()
	var retval bool
	count := uint(len(l.underlyer))
	if pos > count {
		retval = false
	} else {
		l.underlyer[pos] = val
		retval = true
	}
	return retval
}

func ( l * List ) Set ( pos uint , val interface { } ) bool { l . key . Lock ( ) defer l . key . Unlock ( ) var retval bool count := uint ( len ( l . underlyer ) ) if pos > count { retval = false } else { l . underlyer [ pos ] = val retval = true } return retval }

// Set updates the value stored at a given position in the List.

Set updates the value stored at a given position in the List .


func (l *List) String() string {
	l.key.RLock()
	defer l.key.RUnlock()

	builder := bytes.NewBufferString("[")

	for i, entry := range l.underlyer {
		if i >= 15 {
			builder.WriteString("... ")
			break
		}
		builder.WriteString(fmt.Sprintf("%v ", entry))
	}
	builder.Truncate(builder.Len() - 1)
	builder.WriteRune(']')
	return builder.String()
}

func ( l * List ) String ( ) string { l . key . RLock ( ) defer l . key . RUnlock ( ) builder := bytes . NewBufferString ( " " ) for i , entry := range l . underlyer { if i >= 15 { builder . WriteString ( " " ) break } builder . WriteString ( fmt . Sprintf ( " " , entry ) ) } builder . Truncate ( builder . Len ( ) - 1 ) builder . WriteRune ( ']' ) return builder . String ( ) }

// String generates a textual representation of the List for the sake of debugging.

String generates a textual representation of the List for the sake of debugging .


func (l *List) Swap(x, y uint) bool {
	l.key.Lock()
	defer l.key.Unlock()
	return l.swap(x, y)
}

func ( l * List ) Swap ( x , y uint ) bool { l . key . Lock ( ) defer l . key . Unlock ( ) return l . swap ( x , y ) }

// Swap switches the values that are stored at positions `x` and `y`

Swap switches the values that are stored at positions x and y


func (l List) MarshalText() (text []byte, err error) {
	var buf bytes.Buffer
	l.writeToBuffer(&buf)
	return buf.Bytes(), nil
}

func ( l List ) MarshalText ( ) ( text [ ] byte , err error ) { var buf bytes . Buffer l . writeToBuffer ( & buf ) return buf . Bytes ( ) , nil }

// MarshalText implements the TextMarshaler interface.

MarshalText implements the TextMarshaler interface .


func (l *List) UnmarshalText(text []byte) error {
	m := parse.Bytes(text)
	defer m.Release()
	capacity := len(m.List)
	if len(m.Text) == 0 {
		capacity += 2
	}
	list := make(List, 0, capacity)

	if len(m.Text) > 0 {
		list = append(list, "msg", string(m.Text))
	}
	for _, v := range m.List {
		list = append(list, string(v))
	}
	*l = list
	return nil
}

func ( l * List ) UnmarshalText ( text [ ] byte ) error { m := parse . Bytes ( text ) defer m . Release ( ) capacity := len ( m . List ) if len ( m . Text ) == 0 { capacity += 2 } list := make ( List , 0 , capacity ) if len ( m . Text ) > 0 { list = append ( list , " " , string ( m . Text ) ) } for _ , v := range m . List { list = append ( list , string ( v ) ) } * l = list return nil }

// UnmarshalText implements the TextUnmarshaler interface.

UnmarshalText implements the TextUnmarshaler interface .


func repl(match string, t time.Time) string {
	if match == "%%" {
		return "%"
	}

	formatFunc, ok := formats[match]
	if ok {
		return formatFunc(t)
	}
	return formatNanoForMatch(match, t)
}

func repl ( match string , t time . Time ) string { if match == " " { return " " } formatFunc , ok := formats [ match ] if ok { return formatFunc ( t ) } return formatNanoForMatch ( match , t ) }

// repl replaces % directives with right time


func Format(format string, t time.Time) string {
	fn := func(match string) string {
		return repl(match, t)
	}
	return fmtRe.ReplaceAllStringFunc(format, fn)
}

func Format ( format string , t time . Time ) string { fn := func ( match string ) string { return repl ( match , t ) } return fmtRe . ReplaceAllStringFunc ( format , fn ) }

// Format return string with % directives expanded.
// Will return error on unknown directive.

Format return string with % directives expanded . Will return error on unknown directive .


func logName(logger, tag string, t time.Time) (name, link string) {
	name = fmt.Sprintf("%s.%s.%s.log.%s.%s.%04d%02d%02d-%02d%02d%02d.%d",
		program,
		host,
		userName,
		logger,
		tag,
		t.Year(),
		t.Month(),
		t.Day(),
		t.Hour(),
		t.Minute(),
		t.Second(),
		pid)
	return name, program + "." + tag
}

func logName ( logger , tag string , t time . Time ) ( name , link string ) { name = fmt . Sprintf ( " " , program , host , userName , logger , tag , t . Year ( ) , t . Month ( ) , t . Day ( ) , t . Hour ( ) , t . Minute ( ) , t . Second ( ) , pid ) return name , program + " " + tag }

// logName returns a new log file name containing tag, with start time t, and
// the name for the symlink for tag.

logName returns a new log file name containing tag with start time t and the name for the symlink for tag .


func Monotonic() time.Duration {
	sec, nsec := monotime()
	return time.Duration(sec*1000000000 + int64(nsec))
}

func Monotonic ( ) time . Duration { sec , nsec := monotime ( ) return time . Duration ( sec * 1000000000 + int64 ( nsec ) ) }

// Monotonic returns a time duration from some fixed point in the past.

Monotonic returns a time duration from some fixed point in the past .


func (s *Severity) set(val Severity) {
	atomic.StoreInt32((*int32)(s), int32(val))
}

func ( s * Severity ) set ( val Severity ) { atomic . StoreInt32 ( ( * int32 ) ( s ) , int32 ( val ) ) }


func (s *Severity) Set(value string) error {
	var threshold Severity
	// Is it a known name?
	if v, ok := severityByName(value); ok {
		threshold = v
	} else {
		v, err := strconv.Atoi(value)
		if err != nil {
			return err
		}
		threshold = Severity(v)
	}
	*s = threshold
	return nil
}

func
(
s
*
Severity
)
Set
(
value
string
)
error
{
var
threshold
Severity
// Is it a known name?
if
v
,
ok
:=
severityByName
(
value
)
;
ok
{
threshold
=
v
}
else
{
v
,
err
:=
strconv
.
Atoi
(
value
)
if
err
!=
{
return
err
}
threshold
=
Severity
(
v
)
}
*
s
=
threshold
return
}

// Set is part of the flag.Value interface.

Set is part of the flag . Value interface .


func (l *Level) set(val Level) {
	atomic.StoreInt32((*int32)(l), int32(val))
}

func ( l * Level ) set ( val Level ) { atomic . StoreInt32 ( ( * int32 ) ( l ) , int32 ( val ) ) }


func (m *modulePat) match(file string) bool {
	if m.literal {
		return file == m.pattern
	}
	match, _ := filepath.Match(m.pattern, file)
	return match
}

func ( m * modulePat ) match ( file string ) bool { if m . literal { return file == m . pattern } match , _ := filepath . Match ( m . pattern , file ) return match }

// match reports whether the file matches the pattern. It uses a string
// comparison if the pattern contains no metacharacters.

match reports whether the file matches the pattern . It uses a string comparison if the pattern contains no metacharacters .


func (f *filepathPat) match(path string) bool {
	return f.regexp.MatchString(path)
}

func ( f * filepathPat ) match ( path string ) bool { return f . regexp . MatchString ( path ) }

// match reports whether the file path matches the regexp.

match reports whether the file path matches the regexp .


func (t *TraceLocation) match(file string, line int) bool {
	if t.line != line {
		return false
	}
	if i := strings.LastIndex(file, "/"); i >= 0 {
		file = file[i+1:]
	}
	return t.file == file
}

func ( t * TraceLocation ) match ( file string , line int ) bool { if t . line != line { return false } if i := strings . LastIndex ( file , " " ) ; i >= 0 { file = file [ i + 1 : ] } return t . file == file }

// match reports whether the specified file and line matches the trace location.
// The argument file name is the full path, not the basename specified in the flag.

match reports whether the specified file and line matches the trace location . The argument file name is the full path not the basename specified in the flag .


func NewLogger(name string, skip int) *Log {
	logging := &Log{stats: new(Stats)}
	logging.setVState(0, nil, nil, false)
	logging.skip = 2 + skip
	logging.maxStackBufSize = 4096 * 1024
	logging.name = name

	// Default stderrThreshold is ERROR.
	logging.stderrThreshold = ErrorLog
	logging.setVState(0, nil, nil, false)

	logging.severityStats[InfoLog] = &logging.stats.Info
	logging.severityStats[WarningLog] = &logging.stats.Warning
	logging.severityStats[ErrorLog] = &logging.stats.Error

	logging.logDirs = append(logging.logDirs, os.TempDir())
	go logging.flushDaemon()
	return logging
}

func
NewLogger
(
name
string
,
skip
int
)
*
Log
{
logging
:=
&
Log
{
stats
:
new
(
Stats
)
}
logging
.
setVState
(
0
,
,
,
false
)
logging
.
skip
=
2
+
skip
logging
.
maxStackBufSize
=
4096
*
1024
logging
.
name
=
name
// Default stderrThreshold is ERROR.
logging
.
stderrThreshold
=
ErrorLog
logging
.
setVState
(
0
,
,
,
false
)
logging
.
severityStats
[
InfoLog
]
=
&
logging
.
stats
.
Info
logging
.
severityStats
[
WarningLog
]
=
&
logging
.
stats
.
Warning
logging
.
severityStats
[
ErrorLog
]
=
&
logging
.
stats
.
Error
logging
.
logDirs
=
append
(
logging
.
logDirs
,
os
.
TempDir
(
)
)
go
logging
.
flushDaemon
(
)
return
logging
}

// NewLogger creates a new logger.
// name is a non-empty string that appears in the names of log files
// to distinguish between separate instances of the logger writing to the
// same directory.
// skip is the number of stack frames to skip in order to reach the
// call point to be logged. 0 will log the caller of the logging methods,
// 1 their caller etc.

NewLogger creates a new logger . name is a non - empty string that appears in the names of log files to distinguish between separate instances of the logger writing to the same directory . skip is the number of stack frames to skip in order to reach the call point to be logged . 0 will log the caller of the logging methods 1 their caller etc .


func (l *Log) SetLogDir(logDir string) {
	if logDir != "" {
		l.mu.Lock()
		defer l.mu.Unlock()
		l.logDirs = append([]string{logDir}, l.logDirs...)
	}
}

func ( l * Log ) SetLogDir ( logDir string ) { if logDir != " " { l . mu . Lock ( ) defer l . mu . Unlock ( ) l . logDirs = append ( [ ] string { logDir } , l . logDirs ... ) } }

// logDir if non-empty, write log files to this directory.

logDir if non - empty write log files to this directory .


func (l *Log) SetLogToStderr(f bool) {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.toStderr = f

}

func ( l * Log ) SetLogToStderr ( f bool ) { l . mu . Lock ( ) defer l . mu . Unlock ( ) l . toStderr = f }

// SetLogToStderr sets the flag that, if true, logs to standard error instead of files

SetLogToStderr sets the flag that if true logs to standard error instead of files


func (l *Log) SetAlsoLogToStderr(f bool) {
	l.mu.Lock()
	defer l.mu.Unlock()
	l.alsoToStderr = f

}

func ( l * Log ) SetAlsoLogToStderr ( f bool ) { l . mu . Lock ( ) defer l . mu . Unlock ( ) l . alsoToStderr = f }

// SetAlsoLogToStderr sets the flag that, if true, logs to standard error as well as files

SetAlsoLogToStderr sets the flag that if true logs to standard error as well as files


func (l *Log) setVState(verbosity Level, modules []modulePat, filepaths []filepathPat, setFilter bool) {
	// Turn verbosity off so V will not fire while we are in transition.
	l.verbosity.set(0)
	// Ditto for filter length.
	atomic.StoreInt32(&l.filterLength, 0)

	// Set the new filters and wipe the pc->Level map if the filter has changed.
	nfilters := 0
	if setFilter {
		if modules != nil {
			l.vmodule.filter = modules
		}
		if filepaths != nil {
			l.vfilepath.filter = filepaths
		}
		nfilters = len(l.vmodule.filter) + len(l.vfilepath.filter)
		l.vmap = make(map[uintptr]Level)
	}

	// Things are consistent now, so enable filtering and verbosity.
	// They are enabled in order opposite to that in V.
	atomic.StoreInt32(&l.filterLength, int32(nfilters))
	l.verbosity.set(verbosity)
}

// setVState sets a consistent state for V logging. A nil value for
// modules or filepaths will result in that filter not being changed.
// l.mu is held.

setVState sets a consistent state for V logging . A nil value for modules or filepaths will result in that filter not being changed . l . mu is held .


func (l *Log) getBuffer() *buffer {
	l.freeListMu.Lock()
	b := l.freeList
	if b != nil {
		l.freeList = b.next
	}
	l.freeListMu.Unlock()
	if b == nil {
		b = new(buffer)
	} else {
		b.next = nil
		b.Reset()
	}
	return b
}

func ( l * Log ) getBuffer ( ) * buffer { l . freeListMu . Lock ( ) b := l . freeList if b != nil { l . freeList = b . next } l . freeListMu . Unlock ( ) if b == nil { b = new ( buffer ) } else { b . next = nil b . Reset ( ) } return b }

// getBuffer returns a new, ready-to-use buffer.

getBuffer returns a new ready - to - use buffer .


func (l *Log) putBuffer(b *buffer) {
	if b.Len() >= 256 {
		// Let big buffers die a natural death.
		return
	}
	l.freeListMu.Lock()
	b.next = l.freeList
	l.freeList = b
	l.freeListMu.Unlock()
}

func
(
l
*
Log
)
putBuffer
(
b
*
buffer
)
{
if
b
.
Len
(
)
>=
256
{
// Let big buffers die a natural death.
return
}
l
.
freeListMu
.
Lock
(
)
b
.
next
=
l
.
freeList
l
.
freeList
=
b
l
.
freeListMu
.
Unlock
(
)
}

// putBuffer returns a buffer to the free list.

putBuffer returns a buffer to the free list .


func (l *Log) output(s Severity, buf *buffer, file string, line int) {
	l.mu.Lock()
	if l.traceLocation.isSet() {
		if l.traceLocation.match(file, line) {
			buf.Write(stacks(false, l.maxStackBufSize))
		}
	}
	data := buf.Bytes()
	if l.toStderr {
		os.Stderr.Write(data)
	} else {
		if l.alsoToStderr || s >= l.stderrThreshold.get() {
			os.Stderr.Write(data)
		}
		if l.file[s] == nil {
			if err := l.createFiles(s); err != nil {
				os.Stderr.Write(data) // Make sure the message appears somewhere.
				l.exit(err)
			}
		}
		switch s {
		case FatalLog:
			l.file[FatalLog].Write(data)
			fallthrough
		case ErrorLog:
			l.file[ErrorLog].Write(data)
			fallthrough
		case WarningLog:
			l.file[WarningLog].Write(data)
			fallthrough
		case InfoLog:
			l.file[InfoLog].Write(data)
		}
	}
	if s == FatalLog {
		// Make sure we see the trace for the current goroutine on standard error.
		if !l.toStderr {
			os.Stderr.Write(stacks(false, l.maxStackBufSize))
		}
		// Write the stack trace for all goroutines to the files.
		trace := stacks(true, l.maxStackBufSize)
		logExitFunc = func(error) {} // If we get a write error, we'll still exit below.
		for log := FatalLog; log >= InfoLog; log-- {
			if f := l.file[log]; f != nil { // Can be nil if -logtostderr is set.
				f.Write(trace)
			}
		}
		l.mu.Unlock()
		timeoutFlush(l, 10*time.Second)
		os.Exit(255) // C++ uses -1, which is silly because it's anded with 255 anyway.
	}
	l.putBuffer(buf)
	l.mu.Unlock()
	if stats := l.severityStats[s]; stats != nil {
		atomic.AddInt64(&stats.lines, 1)
		atomic.AddInt64(&stats.bytes, int64(len(data)))
	}
}

// output writes the data to the log files and releases the buffer.

output writes the data to the log files and releases the buffer .


func timeoutFlush(l *Log, timeout time.Duration) {
	done := make(chan bool, 1)
	go func() {
		l.lockAndFlushAll()
		done <- true
	}()
	select {
	case <-done:
	case <-time.After(timeout):
		fmt.Fprintln(os.Stderr, "glog: Flush took longer than", timeout)
	}
}

func timeoutFlush ( l * Log , timeout time . Duration ) { done := make ( chan bool , 1 ) go func ( ) { l . lockAndFlushAll ( ) done <- true } ( ) select { case <- done : case <- time . After ( timeout ) : fmt . Fprintln ( os . Stderr , " " , timeout ) } }

// timeoutFlush calls Flush and returns when it completes or after timeout
// elapses, whichever happens first.  This is needed because the hooks invoked
// by Flush may deadlock when glog.Fatal is called from a hook that holds
// a lock.

timeoutFlush calls Flush and returns when it completes or after timeout elapses whichever happens first . This is needed because the hooks invoked by Flush may deadlock when glog . Fatal is called from a hook that holds a lock .