func NewStack(file *os.File) (*Stack, error) {
	stack := &Stack{file: file, fileName: file.Name()}
	err := stack.Repare()
	if err != nil {
		stack.Close()
		return nil, err
	}
	return stack, nil
}

func NewStack ( file * os . File ) ( * Stack , error ) { stack := & Stack { file : file , fileName : file . Name ( ) } err := stack . Repare ( ) if err != nil { stack . Close ( ) return nil , err } return stack , nil }

// NewStack - create new stack based on file


func NewSessionCache(d time.Duration, salt string) *SessionCache {
	return &SessionCache{
		cache: data.NewCache(d),
		salter: crypt.NewSalter(
			crypt.NewRandomSourceListSecure(), []byte(salt)),
	}
}

func NewSessionCache ( d time . Duration , salt string ) * SessionCache { return & SessionCache { cache : data . NewCache ( d ) , salter : crypt . NewSalter ( crypt . NewRandomSourceListSecure ( ) , [ ] byte ( salt ) ) , } }

// NewSessionCache creates a new instance of SessionCache and defines a lifetime
// for sessions and a initial salt for random input.

NewSessionCache creates a new instance of SessionCache and defines a lifetime for sessions and a initial salt for random input .


func (s *SessionCache) getInvalidTokenError(token string) error {
	return errors.New(fmt.Sprintf(
		"The requested token '%s' is invalid or is expired", token))
}

func ( s * SessionCache ) getInvalidTokenError ( token string ) error { return errors . New ( fmt . Sprintf ( " " , token ) ) }

// getInvalidTokenError gets the default error when an invalid or expired token
// is requested.

getInvalidTokenError gets the default error when an invalid or expired token is requested .


func (s *SessionCache) Get(token string) (interface{}, error) {
	v, err := s.cache.Get(token)
	if err != nil {
		return nil, s.getInvalidTokenError(token)
	}
	return v, err
}

func ( s * SessionCache ) Get ( token string ) ( interface { } , error ) { v , err := s . cache . Get ( token ) if err != nil { return nil , s . getInvalidTokenError ( token ) } return v , err }

// Get gets the value stored by specified token.

Get gets the value stored by specified token .


func (s *SessionCache) Add() string {
	strSum := s.salter.DefaultToken()

	err := s.cache.Add(strSum, nil)
	if err != nil {
		panic("Something is seriously wrong, a duplicated token was generated")
	}

	return strSum
}

func ( s * SessionCache ) Add ( ) string { strSum := s . salter . DefaultToken ( ) err := s . cache . Add ( strSum , nil ) if err != nil { panic ( " " ) } return strSum }

// Add creates a new unique token and stores it into current SessionCache
// instance.
//
// The token creation will take at least 200 microseconds, but could normally
// take 2.5 milliseconds. The token generation function it is built with
// security over performance.

Add creates a new unique token and stores it into current SessionCache instance . The token creation will take at least 200 microseconds but could normally take 2 . 5 milliseconds . The token generation function it is built with security over performance .


func (s *SessionCache) Delete(token string) error {
	err := s.cache.Delete(token)
	if err != nil {
		return s.getInvalidTokenError(token)
	}
	return nil
}

func ( s * SessionCache ) Delete ( token string ) error { err := s . cache . Delete ( token ) if err != nil { return s . getInvalidTokenError ( token ) } return nil }

// Delete deletes specified token from current SessionCache instance.

Delete deletes specified token from current SessionCache instance .


func (s *SessionCache) Set(token string, value interface{}) error {
	err := s.cache.Set(token, value)
	if err != nil {
		return s.getInvalidTokenError(token)
	}
	return nil
}

func ( s * SessionCache ) Set ( token string , value interface { } ) error { err := s . cache . Set ( token , value ) if err != nil { return s . getInvalidTokenError ( token ) } return nil }

// Set store a value to specified token.


func NewClient(nick, serverHost string, serverPort uint16) *Client {
	return &Client{
		nick:       nick,
		serverHost: serverHost,
		serverPort: serverPort,

		writeTimeout: 30 * time.Second,
		readTimeout:  100 * time.Millisecond,

		channels: map[string]struct{}{},
		mutex:    &sync.Mutex{},
	}
}

func NewClient ( nick , serverHost string , serverPort uint16 ) * Client { return & Client { nick : nick , serverHost : serverHost , serverPort : serverPort , writeTimeout : 30 * time . Second , readTimeout : 100 * time . Millisecond , channels : map [ string ] struct { } { } , mutex : & sync . Mutex { } , } }


func (c *Client) connect() error {
	dialer := &net.Dialer{
		Timeout:   30 * time.Second,
		KeepAlive: 30 * time.Second,
	}

	conn, err := dialer.Dial("tcp", fmt.Sprintf("%s:%d", c.serverHost,
		c.serverPort))
	if err != nil {
		return fmt.Errorf("error dialing: %s", err)
	}

	c.conn = conn
	c.rw = bufio.NewReadWriter(bufio.NewReader(c.conn), bufio.NewWriter(c.conn))
	return nil
}

func ( c * Client ) connect ( ) error { dialer := & net . Dialer { Timeout : 30 * time . Second , KeepAlive : 30 * time . Second , } conn , err := dialer . Dial ( " " , fmt . Sprintf ( " " , c . serverHost , c . serverPort ) ) if err != nil { return fmt . Errorf ( " " , err ) } c . conn = conn c . rw = bufio . NewReadWriter ( bufio . NewReader ( c . conn ) , bufio . NewWriter ( c . conn ) ) return nil }

// connect opens a new connection to the server.

connect opens a new connection to the server .


func (c Client) writeMessage(m irc.Message) error {
	buf, err := m.Encode()
	if err != nil && err != irc.ErrTruncated {
		return fmt.Errorf("unable to encode message: %s", err)
	}

	if err := c.conn.SetWriteDeadline(time.Now().Add(
		c.writeTimeout)); err != nil {
		return fmt.Errorf("unable to set deadline: %s", err)
	}

	sz, err := c.rw.WriteString(buf)
	if err != nil {
		return err
	}

	if sz != len(buf) {
		return fmt.Errorf("short write")
	}

	if err := c.rw.Flush(); err != nil {
		return fmt.Errorf("flush error: %s", err)
	}

	log.Printf("client %s: sent: %s", c.nick, strings.TrimRight(buf, "\r\n"))
	return nil
}

func ( c Client ) writeMessage ( m irc . Message ) error { buf , err := m . Encode ( ) if err != nil && err != irc . ErrTruncated { return fmt . Errorf ( " " , err ) } if err := c . conn . SetWriteDeadline ( time . Now ( ) . Add ( c . writeTimeout ) ) ; err != nil { return fmt . Errorf ( " " , err ) } sz , err := c . rw . WriteString ( buf ) if err != nil { return err } if sz != len ( buf ) { return fmt . Errorf ( " " ) } if err := c . rw . Flush ( ) ; err != nil { return fmt . Errorf ( " " , err ) } log . Printf ( " " , c . nick , strings . TrimRight ( buf , " \r \n " ) ) return nil }

// writeMessage writes an IRC message to the connection.

writeMessage writes an IRC message to the connection .


func (c Client) readMessage() (irc.Message, error) {
	if err := c.conn.SetReadDeadline(time.Now().Add(c.readTimeout)); err != nil {
		return irc.Message{}, fmt.Errorf("unable to set deadline: %s", err)
	}

	line, err := c.rw.ReadString('\n')
	if err != nil {
		return irc.Message{}, err
	}

	log.Printf("client %s: read: %s", c.nick, strings.TrimRight(line, "\r\n"))

	m, err := irc.ParseMessage(line)
	if err != nil && err != irc.ErrTruncated {
		return irc.Message{}, fmt.Errorf("unable to parse message: %s: %s", line,
			err)
	}

	return m, nil
}

func ( c Client ) readMessage ( ) ( irc . Message , error ) { if err := c . conn . SetReadDeadline ( time . Now ( ) . Add ( c . readTimeout ) ) ; err != nil { return irc . Message { } , fmt . Errorf ( " " , err ) } line , err := c . rw . ReadString ( '\n' ) if err != nil { return irc . Message { } , err } log . Printf ( " " , c . nick , strings . TrimRight ( line , " \r \n " ) ) m , err := irc . ParseMessage ( line ) if err != nil && err != irc . ErrTruncated { return irc . Message { } , fmt . Errorf ( " " , line , err ) } return m , nil }

// readMessage reads a line from the connection and parses it as an IRC message.

readMessage reads a line from the connection and parses it as an IRC message .


func (c *Client) Stop() {
	// Tell reader and writer to end.
	close(c.doneChan)

	// We won't be sending anything further to writer. Let it clean up.
	close(c.sendChan)

	// Wait for reader and writer to end.
	c.wg.Wait()

	// We know the reader and writer won't be sending on the error channel any
	// more.
	close(c.errChan)

	_ = c.conn.Close()

	for range c.recvChan {
	}
	for range c.errChan {
	}
}

// Stop shuts down the client and cleans up.
//
// You must not send any messages on the send channel after calling this
// function.

Stop shuts down the client and cleans up . You must not send any messages on the send channel after calling this function .


func (c Client) GetChannels() []string {
	var channels []string
	c.mutex.Lock()
	for k := range c.channels {
		channels = append(channels, k)
	}
	c.mutex.Unlock()
	return channels
}

func ( c Client ) GetChannels ( ) [ ] string { var channels [ ] string c . mutex . Lock ( ) for k := range c . channels { channels = append ( channels , k ) } c . mutex . Unlock ( ) return channels }

// GetChannels retrieves the IRC channels the client is on.

GetChannels retrieves the IRC channels the client is on .


func JsonWrite(w http.ResponseWriter, status int, content interface{}) {
	HttpHeader_ContentType_Json().SetWriter(w.Header())
	w.WriteHeader(status)
	if content != nil {
		json.NewEncoder(w).Encode(content)
	}
}

func JsonWrite ( w http . ResponseWriter , status int , content interface { } ) { HttpHeader_ContentType_Json ( ) . SetWriter ( w . Header ( ) ) w . WriteHeader ( status ) if content != nil { json . NewEncoder ( w ) . Encode ( content ) } }

// JsonWrite sets response content type to JSON, sets HTTP status and serializes
// defined content to JSON format.

JsonWrite sets response content type to JSON sets HTTP status and serializes defined content to JSON format .


func JsonRead(body io.ReadCloser, obj interface{}, w http.ResponseWriter) bool {
	content, err := ioutil.ReadAll(io.LimitReader(body, HTTP_BODY_MAX_LENGTH))
	if err != nil {
		jerr := NewJsonErrorFromError(http.StatusInternalServerError, err)
		JsonWrite(w, jerr.Status, jerr)
		return false
	}

	if err := body.Close(); err != nil {
		jerr := NewJsonErrorFromError(http.StatusInternalServerError, err)
		JsonWrite(w, jerr.Status, jerr)
		return false
	}

	if err := json.Unmarshal(content, obj); err != nil {
		jerr := NewJsonErrorFromError(StatusUnprocessableEntity, err)
		JsonWrite(w, jerr.Status, jerr)
		return false
	}

	return true
}

func JsonRead ( body io . ReadCloser , obj interface { } , w http . ResponseWriter ) bool { content , err := ioutil . ReadAll ( io . LimitReader ( body , HTTP_BODY_MAX_LENGTH ) ) if err != nil { jerr := NewJsonErrorFromError ( http . StatusInternalServerError , err ) JsonWrite ( w , jerr . Status , jerr ) return false } if err := body . Close ( ) ; err != nil { jerr := NewJsonErrorFromError ( http . StatusInternalServerError , err ) JsonWrite ( w , jerr . Status , jerr ) return false } if err := json . Unmarshal ( content , obj ) ; err != nil { jerr := NewJsonErrorFromError ( StatusUnprocessableEntity , err ) JsonWrite ( w , jerr . Status , jerr ) return false } return true }

// JsonRead tries to read client sent content using JSON deserialization and
// writes it to defined object.

JsonRead tries to read client sent content using JSON deserialization and writes it to defined object .


func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) (err error) {
	h, err := keySignatureHash(pk, signed, sig.Hash)
	if err != nil {
		return err
	}
	return pk.VerifySignature(h, sig)
}

func ( pk * PublicKey ) VerifyKeySignature ( signed * PublicKey , sig * Signature ) ( err error ) { h , err := keySignatureHash ( pk , signed , sig . Hash ) if err != nil { return err } return pk . VerifySignature ( h , sig ) }

// VerifyKeySignature returns nil iff sig is a valid signature, made by this
// public key, of signed.

VerifyKeySignature returns nil iff sig is a valid signature made by this public key of signed .


func NewUser(player uuid.UUID, userdata *User) (*User, error) {
	p, err := storage.Load(player)
	if err != nil {
		return nil, err
	}
	p.User = *userdata
	//fmt.Println("Creating user:")
	//fmt.Printf("%v", p.User)
	err = storage.Store(p)
	if err != nil {
		return nil,
			errors.New(err.Error() + " - Could not write user to storage")
	}
	return &p.User, nil
}

func
NewUser
(
player
uuid
.
UUID
,
userdata
*
User
)
(
*
User
,
error
)
{
p
,
err
:=
storage
.
Load
(
player
)
if
err
!=
{
return
,
err
}
p
.
User
=
*
userdata
//fmt.Println("Creating user:")
//fmt.Printf("%v", p.User)
err
=
storage
.
Store
(
p
)
if
err
!=
{
return
,
errors
.
New
(
err
.
Error
(
)
+
"
"
)
}
return
&
p
.
User
,
}


func (c *Context) Next(w http.ResponseWriter, r *http.Request) {
	if c.route == nil {
		return
	}

	if next := c.route.next; next != nil {
		c.route = next
		next.ServeHTTPContext(w, r, c)
	} else {
		c.holdUp = true
	}
}

func ( c * Context ) Next ( w http . ResponseWriter , r * http . Request ) { if c . route == nil { return } if next := c . route . next ; next != nil { c . route = next next . ServeHTTPContext ( w , r , c ) } else { c . holdUp = true } }

// Next invoke next route with the given ResponseWriter and Request


func (route *Route) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	c := &Context{route: route}
	route.ServeHTTPContext(w, r, c)
}

func ( route * Route ) ServeHTTP ( w http . ResponseWriter , r * http . Request ) { c := & Context { route : route } route . ServeHTTPContext ( w , r , c ) }

// ServeHTTP implement http.Handler interface

ServeHTTP implement http . Handler interface


func (r *Route) UseHandler(h Handler) {
	if r.f == nil {
		r.f = h
		return
	}

	route := r.getLeaf()
	route.next = &Route{f: h}
}

func ( r * Route ) UseHandler ( h Handler ) { if r . f == nil { r . f = h return } route := r . getLeaf ( ) route . next = & Route { f : h } }

// UseHandler appends a Handler to the route.

UseHandler appends a Handler to the route .


func (r *Route) HandleMethod(pat, method string, f ...HandlerFunc) {
	entry := r.addPattern(pat)
	batch := batchRoute(f)
	if err := entry.SetMethodHandler(method, batch); err != nil {
		panic(err)
	}
}

func ( r * Route ) HandleMethod ( pat , method string , f ... HandlerFunc ) { entry := r . addPattern ( pat ) batch := batchRoute ( f ) if err := entry . SetMethodHandler ( method , batch ) ; err != nil { panic ( err ) } }

// HandleMethod registers handler funcs with the given pattern and method.

HandleMethod registers handler funcs with the given pattern and method .


func (r *Route) Handle(pat string, f ...HandlerFunc) {
	entry := r.addPattern(pat)
	batch := batchRoute(f)
	if err := entry.SetHandler(batch); err != nil {
		panic(err)
	}
}

func ( r * Route ) Handle ( pat string , f ... HandlerFunc ) { entry := r . addPattern ( pat ) batch := batchRoute ( f ) if err := entry . SetHandler ( batch ) ; err != nil { panic ( err ) } }

// Handle registers handler funcs with the given pattern.

Handle registers handler funcs with the given pattern .


func (r *Route) Get(pat string, f ...HandlerFunc) {
	r.HandleMethod(pat, "GET", f...)
	r.HandleMethod(pat, "HEAD", f...)
}

func ( r * Route ) Get ( pat string , f ... HandlerFunc ) { r . HandleMethod ( pat , " " , f ... ) r . HandleMethod ( pat , " " , f ... ) }

// Get registers handlers with the given pattern for GET and HEAD method


func (r *Route) Post(pat string, f ...HandlerFunc) {
	r.HandleMethod(pat, "POST", f...)
}

func ( r * Route ) Post ( pat string , f ... HandlerFunc ) { r . HandleMethod ( pat , " " , f ... ) }

// Post registers handlers with the given pattern for POST method


func (r *Route) Put(pat string, f ...HandlerFunc) {
	r.HandleMethod(pat, "PUT", f...)
}

func ( r * Route ) Put ( pat string , f ... HandlerFunc ) { r . HandleMethod ( pat , " " , f ... ) }

// Put registers handlers with the given pattern for PUT method


func (r *Route) Patch(pat string, f ...HandlerFunc) {
	r.HandleMethod(pat, "PATCH", f...)
}

func ( r * Route ) Patch ( pat string , f ... HandlerFunc ) { r . HandleMethod ( pat , " " , f ... ) }

// Patch registers handlers with the given pattern for PATCH method


func (r *Route) Delete(pat string, f ...HandlerFunc) {
	r.HandleMethod(pat, "DELETE", f...)
}

func ( r * Route ) Delete ( pat string , f ... HandlerFunc ) { r . HandleMethod ( pat , " " , f ... ) }

// Delete registers handlers with the given pattern for DELETE method


func (r *Route) Options(pat string, f ...HandlerFunc) {
	r.HandleMethod(pat, "OPTIONS", f...)
}

func ( r * Route ) Options ( pat string , f ... HandlerFunc ) { r . HandleMethod ( pat , " " , f ... ) }

// Options registers handlers with the given pattern for OPTIONS method


func NewSalter(sources RandomSourceList, input []byte) *Salter {
	if input == nil {
		input = []byte("")
	}

	hash := sha256.New()
	hash.Write(input)

	sum := 0
	for _, v := range sources {
		sum += v.Weight
	}

	return &Salter{
		salt:       hash.Sum(nil),
		rndSources: sources,
		sumWeight:  sum,
	}
}

func NewSalter ( sources RandomSourceList , input [ ] byte ) * Salter { if input == nil { input = [ ] byte ( " " ) } hash := sha256 . New ( ) hash . Write ( input ) sum := 0 for _ , v := range sources { sum += v . Weight } return & Salter { salt : hash . Sum ( nil ) , rndSources : sources , sumWeight : sum , } }

// NewSalter creates a new instance of Salter. It requires a list of sources of
// random data and optionally an input to salt next token.

NewSalter creates a new instance of Salter . It requires a list of sources of random data and optionally an input to salt next token .


func (self *Salter) BToken(size int) []byte {
	mac := hmac.New(sha256.New, self.salt)

	for _, v := range self.rndSources {
		itemSize := float32(size) * (float32(v.Weight) / float32(self.sumWeight))
		mac.Write(getRandomBytes(v.Reader, int(itemSize)))
	}
	macSum := mac.Sum(nil)

	self.salt = macSum
	return macSum
}

func ( self * Salter ) BToken ( size int ) [ ] byte { mac := hmac . New ( sha256 . New , self . salt ) for _ , v := range self . rndSources { itemSize := float32 ( size ) * ( float32 ( v . Weight ) / float32 ( self . sumWeight ) ) mac . Write ( getRandomBytes ( v . Reader , int ( itemSize ) ) ) } macSum := mac . Sum ( nil ) self . salt = macSum return macSum }

// BToken generates an array of random bytes with length as specified by size
// parameter.

BToken generates an array of random bytes with length as specified by size parameter .


func (self *Salter) Token(size int) string {
	return base64.URLEncoding.EncodeToString(self.BToken(size))
}

func ( self * Salter ) Token ( size int ) string { return base64 . URLEncoding . EncodeToString ( self . BToken ( size ) ) }

// Token generates a base-64 string of random bytes with length as specified by
// size parameter.

Token generates a base - 64 string of random bytes with length as specified by size parameter .


func getRandomBytes(r io.Reader, n int) []byte {
	b := make([]byte, n)
	_, err := r.Read(b)
	if err != nil {
		panic("Could not access secure random generator")
	}

	return b
}

func getRandomBytes ( r io . Reader , n int ) [ ] byte { b := make ( [ ] byte , n ) _ , err := r . Read ( b ) if err != nil { panic ( " " ) } return b }

// getRandomBytes gets secure random bytes.

getRandomBytes gets secure random bytes .


func NewNewsItem(itemdata NewsItem, author uuid.UUID) (*NewsItem, error) {
	c := new(NewsItem)
	if err := mergo.MergeWithOverwrite(c, itemdata); err != nil {
		return nil, errors.New(err.Error() + " - Could not set initial NewsItem data")
	}
	c.UUID, _ = uuid.V4()
	c.Author = author
	c.Created = time.Now()
	if err := storage.Store(c); err != nil {
		return nil, errors.New(err.Error() + " - Could not write NewsItem to storage")
	}
	eventqueue.Publish(utils.CKPTEvent{
		Type:    utils.NEWS_EVENT,
		Subject: "Nytt bidrag lagt ut",
		Message: "Det er lagt ut et nytt bidrag på ckpt.no!"})
	return c, nil
}

func NewNewsItem ( itemdata NewsItem , author uuid . UUID ) ( * NewsItem , error ) { c := new ( NewsItem ) if err := mergo . MergeWithOverwrite ( c , itemdata ) ; err != nil { return nil , errors . New ( err . Error ( ) + " " ) } c . UUID , _ = uuid . V4 ( ) c . Author = author c . Created = time . Now ( ) if err := storage . Store ( c ) ; err != nil { return nil , errors . New ( err . Error ( ) + " " ) } eventqueue . Publish ( utils . CKPTEvent { Type : utils . NEWS_EVENT , Subject : " " , Message : " } ) return c , nil }

//
// NewsItem related functions and methods
//
// Create a NewsItem

NewsItem related functions and methods Create a NewsItem


func (lw DebugLogWriter) Write(p []byte) (int, error) {
	lw.Debug(string(bytes.TrimRightFunc(p, unicode.IsSpace)))
	return len(p), nil
}

func ( lw DebugLogWriter ) Write ( p [ ] byte ) ( int , error ) { lw . Debug ( string ( bytes . TrimRightFunc ( p , unicode . IsSpace ) ) ) return len ( p ) , nil }

// Write logs an Debug message to a logger.

Write logs an Debug message to a logger .


func (lw InfoLogWriter) Write(p []byte) (int, error) {
	lw.Info(string(bytes.TrimRightFunc(p, unicode.IsSpace)))
	return len(p), nil
}

func ( lw InfoLogWriter ) Write ( p [ ] byte ) ( int , error ) { lw . Info ( string ( bytes . TrimRightFunc ( p , unicode . IsSpace ) ) ) return len ( p ) , nil }

// Write logs an Info message to a logger.

Write logs an Info message to a logger .


func (lw WarningLogWriter) Write(p []byte) (int, error) {
	lw.Warning(string(bytes.TrimRightFunc(p, unicode.IsSpace)))
	return len(p), nil
}

func ( lw WarningLogWriter ) Write ( p [ ] byte ) ( int , error ) { lw . Warning ( string ( bytes . TrimRightFunc ( p , unicode . IsSpace ) ) ) return len ( p ) , nil }

// Write logs an Warning message to a logger.

Write logs an Warning message to a logger .


func (lw ErrorLogWriter) Write(p []byte) (int, error) {
	lw.Error(string(bytes.TrimRightFunc(p, unicode.IsSpace)))
	return len(p), nil
}

func ( lw ErrorLogWriter ) Write ( p [ ] byte ) ( int , error ) { lw . Error ( string ( bytes . TrimRightFunc ( p , unicode . IsSpace ) ) ) return len ( p ) , nil }

// Write logs an Error message to a logger.

Write logs an Error message to a logger .


func GetLogger(name string) (*Logger, error) {
	if name == "default" {
		return getDefaultLogger(), nil
	}
	lock.RLock()
	logger, ok := loggers[name]
	lock.RUnlock()
	if !ok {
		return nil, fmt.Errorf("unknown logger %s", name)
	}
	return logger, nil
}

func GetLogger ( name string ) ( * Logger , error ) { if name == " " { return getDefaultLogger ( ) , nil } lock . RLock ( ) logger , ok := loggers [ name ] lock . RUnlock ( ) if ! ok { return nil , fmt . Errorf ( " " , name ) } return logger , nil }

// GetLogger returns logger instance based on provided name.
// If logger does not exist, error will be returned.

GetLogger returns logger instance based on provided name . If logger does not exist error will be returned .


func RemoveLogger(name string) {
	lock.Lock()
	delete(loggers, name)
	if name == "default" {
		defaultLogger = nil
	}
	lock.Unlock()
}

func RemoveLogger ( name string ) { lock . Lock ( ) delete ( loggers , name ) if name == " " { defaultLogger = nil } lock . Unlock ( ) }

// RemoveLogger deletes logger from global logger registry.

RemoveLogger deletes logger from global logger registry .


func WaitForAllUnprocessedRecords() {
	lock.Lock()
	var wg sync.WaitGroup
	for _, logger := range loggers {
		wg.Add(1)
		go func(logger *Logger) {
			logger.WaitForUnprocessedRecords()
			wg.Done()
		}(logger)
	}
	wg.Wait()
	lock.Unlock()
}

func WaitForAllUnprocessedRecords ( ) { lock . Lock ( ) var wg sync . WaitGroup for _ , logger := range loggers { wg . Add ( 1 ) go func ( logger * Logger ) { logger . WaitForUnprocessedRecords ( ) wg . Done ( ) } ( logger ) } wg . Wait ( ) lock . Unlock ( ) }

// WaitForAllUnprocessedRecords blocks execution until all unprocessed
// log records are processed.
// Since this library implements async logging, it is possible to have
// unprocessed logs at the moment when application is terminating.
// In that case, log messages can be lost. This mehtods blocks execution
// until all log records are processed, to ensure that all log messages
// are handled.

WaitForAllUnprocessedRecords blocks execution until all unprocessed log records are processed . Since this library implements async logging it is possible to have unprocessed logs at the moment when application is terminating . In that case log messages can be lost . This mehtods blocks execution until all log records are processed to ensure that all log messages are handled .


func (logger *Logger) run() {
	defer func() {
		logger.WaitForUnprocessedRecords()
		logger.closeHandlers()
	}()
recordLoop:
	for {
		select {
		case record := <-logger.recordChannel:
			record.process(logger)
		case state := <-logger.stateChannel:
			switch state {
			case stopped:
				break recordLoop
			case paused:
			stateLoop:
				for {
					select {
					case state := <-logger.stateChannel:
						switch state {
						case stopped:
							break recordLoop
						case running:
							break stateLoop
						default:
							continue
						}
					}
				}
			}
		}
	}
}

func ( logger * Logger ) run ( ) { defer func ( ) { logger . WaitForUnprocessedRecords ( ) logger . closeHandlers ( ) } ( ) recordLoop : for { select { case record := <- logger . recordChannel : record . process ( logger ) case state := <- logger . stateChannel : switch state { case stopped : break recordLoop case paused : stateLoop : for { select { case state := <- logger . stateChannel : switch state { case stopped : break recordLoop case running : break stateLoop default : continue } } } } } } }

// run starts async log records processing.

run starts async log records processing .


func (logger *Logger) WaitForUnprocessedRecords() {
	runtime.Gosched()
	var (
		diff     uint64
		diffPrev uint64
		i        uint8
	)
	for {
		diff = atomic.LoadUint64(&logger.countIn) - atomic.LoadUint64(&logger.countOut)
		if diff == diffPrev {
			i++
		}
		if i >= 100 {
			return
		}
		if diff > 0 {
			diffPrev = diff
			time.Sleep(10 * time.Millisecond)
		} else {
			return
		}
	}
}

func ( logger * Logger ) WaitForUnprocessedRecords ( ) { runtime . Gosched ( ) var ( diff uint64 diffPrev uint64 i uint8 ) for { diff = atomic . LoadUint64 ( & logger . countIn ) - atomic . LoadUint64 ( & logger . countOut ) if diff == diffPrev { i ++ } if i >= 100 { return } if diff > 0 { diffPrev = diff time . Sleep ( 10 * time . Millisecond ) } else { return } } }

// WaitForUnprocessedRecords block execution until all unprocessed log records
// for this logger are processed.
// In order to wait for processing in all loggers, logging.WaitForAllUnprocessedRecords
// can be used.

WaitForUnprocessedRecords block execution until all unprocessed log records for this logger are processed . In order to wait for processing in all loggers logging . WaitForAllUnprocessedRecords can be used .


func (logger *Logger) SetBufferLength(length int) {
	logger.lock.Lock()

	if length == 0 {
		logger.buffer = nil
	} else if length != logger.buffer.Len() {
		logger.buffer = ring.New(length)
	}

	logger.lock.Unlock()
}

func ( logger * Logger ) SetBufferLength ( length int ) { logger . lock . Lock ( ) if length == 0 { logger . buffer = nil } else if length != logger . buffer . Len ( ) { logger . buffer = ring . New ( length ) } logger . lock . Unlock ( ) }

// SetBufferLength sets length of buffer for accepting log records.

SetBufferLength sets length of buffer for accepting log records .


func (logger *Logger) AddHandler(handler Handler) {
	logger.lock.Lock()
	logger.Handlers = append(logger.Handlers, handler)
	logger.flushBuffer()
	logger.lock.Unlock()
}

func ( logger * Logger ) AddHandler ( handler Handler ) { logger . lock . Lock ( ) logger . Handlers = append ( logger . Handlers , handler ) logger . flushBuffer ( ) logger . lock . Unlock ( ) }

// AddHandler add new handler to current logger.

AddHandler add new handler to current logger .


func (logger *Logger) ClearHandlers() {
	logger.lock.Lock()
	logger.closeHandlers()
	logger.Handlers = make([]Handler, 0)
	logger.flushBuffer()
	logger.lock.Unlock()
}

func ( logger * Logger ) ClearHandlers ( ) { logger . lock . Lock ( ) logger . closeHandlers ( ) logger . Handlers = make ( [ ] Handler , 0 ) logger . flushBuffer ( ) logger . lock . Unlock ( ) }

// ClearHandlers removes all handlers from current logger.

ClearHandlers removes all handlers from current logger .


func (logger *Logger) SetLevel(level Level) {
	logger.lock.Lock()
	logger.Level = level
	logger.flushBuffer()
	logger.lock.Unlock()
}

func ( logger * Logger ) SetLevel ( level Level ) { logger . lock . Lock ( ) logger . Level = level logger . flushBuffer ( ) logger . lock . Unlock ( ) }

// SetLevel sets lower level that current logger will process.

SetLevel sets lower level that current logger will process .


func (logger *Logger) log(level Level, format string, a ...interface{}) {
	var message string
	if format == "" {
		message = fmt.Sprint(a...)
	} else {
		message = fmt.Sprintf(format, a...)
	}

	atomic.AddUint64(&logger.countIn, 1)
	logger.recordChannel <- &Record{
		Level:   level,
		Message: message,
		Time:    time.Now(),
	}
}

func ( logger * Logger ) log ( level Level , format string , a ... interface { } ) { var message string if format == " " { message = fmt . Sprint ( a ... ) } else { message = fmt . Sprintf ( format , a ... ) } atomic . AddUint64 ( & logger . countIn , 1 ) logger . recordChannel <- & Record { Level : level , Message : message , Time : time . Now ( ) , } }

// log creates log record and submits it for processing.

log creates log record and submits it for processing .


func (logger *Logger) Logf(level Level, format string, a ...interface{}) {
	logger.log(level, format, a...)
}

func ( logger * Logger ) Logf ( level Level , format string , a ... interface { } ) { logger . log ( level , format , a ... ) }

// Logf logs provided message with formatting.

Logf logs provided message with formatting .


func (logger *Logger) Log(level Level, a ...interface{}) {
	logger.log(level, "", a...)
}

func ( logger * Logger ) Log ( level Level , a ... interface { } ) { logger . log ( level , " " , a ... ) }


func (logger *Logger) Emergencyf(format string, a ...interface{}) {
	logger.log(EMERGENCY, format, a...)
}

func ( logger * Logger ) Emergencyf ( format string , a ... interface { } ) { logger . log ( EMERGENCY , format , a ... ) }

// Emergencyf logs provided message with formatting in EMERGENCY level.

Emergencyf logs provided message with formatting in EMERGENCY level .


func (logger *Logger) Alertf(format string, a ...interface{}) {
	logger.log(ALERT, format, a...)
}

func ( logger * Logger ) Alertf ( format string , a ... interface { } ) { logger . log ( ALERT , format , a ... ) }

// Alertf logs provided message with formatting in ALERT level.

Alertf logs provided message with formatting in ALERT level .


func (logger *Logger) Criticalf(format string, a ...interface{}) {
	logger.log(CRITICAL, format, a...)
}

func ( logger * Logger ) Criticalf ( format string , a ... interface { } ) { logger . log ( CRITICAL , format , a ... ) }

// Criticalf logs provided message with formatting in CRITICAL level.

Criticalf logs provided message with formatting in CRITICAL level .


func (logger *Logger) Errorf(format string, a ...interface{}) {
	logger.log(ERROR, format, a...)
}

func ( logger * Logger ) Errorf ( format string , a ... interface { } ) { logger . log ( ERROR , format , a ... ) }

// Errorf logs provided message with formatting in ERROR level.

Errorf logs provided message with formatting in ERROR level .


func (logger *Logger) Warningf(format string, a ...interface{}) {
	logger.log(WARNING, format, a...)
}

func ( logger * Logger ) Warningf ( format string , a ... interface { } ) { logger . log ( WARNING , format , a ... ) }

// Warningf logs provided message with formatting in WARNING level.

Warningf logs provided message with formatting in WARNING level .


func (logger *Logger) Noticef(format string, a ...interface{}) {
	logger.log(NOTICE, format, a...)
}

func ( logger * Logger ) Noticef ( format string , a ... interface { } ) { logger . log ( NOTICE , format , a ... ) }

// Noticef logs provided message with formatting in NOTICE level.

Noticef logs provided message with formatting in NOTICE level .


func (logger *Logger) Infof(format string, a ...interface{}) {
	logger.log(INFO, format, a...)
}

func ( logger * Logger ) Infof ( format string , a ... interface { } ) { logger . log ( INFO , format , a ... ) }

// Infof logs provided message with formatting in INFO level.

Infof logs provided message with formatting in INFO level .


func (logger *Logger) Debugf(format string, a ...interface{}) {
	logger.log(DEBUG, format, a...)
}

func ( logger * Logger ) Debugf ( format string , a ... interface { } ) { logger . log ( DEBUG , format , a ... ) }

// Debugf logs provided message with formatting in DEBUG level.

Debugf logs provided message with formatting in DEBUG level .


func (e *Entry) SetHandler(h *Route) error {
	if e.handler != nil {
		return errors.New("Duplicate Route registration")
	}
	e.handler = h
	return nil
}

func ( e * Entry ) SetHandler ( h * Route ) error { if e . handler != nil { return errors . New ( " " ) } e . handler = h return nil }

// SetHandler reigsters the given handler that matches with any method.

SetHandler reigsters the given handler that matches with any method .


func (e *Entry) SetMethodHandler(method string, h *Route) error {
	if e.GetHandler(method) != nil {
		return errors.New("Duplicate Route registration")
	}
	e.handlers[method] = h
	return nil
}

func ( e * Entry ) SetMethodHandler ( method string , h * Route ) error { if e . GetHandler ( method ) != nil { return errors . New ( " " ) } e . handlers [ method ] = h return nil }

// SetMethodHandler reigsters the given handler for the method.

SetMethodHandler reigsters the given handler for the method .


func (e *Entry) GetHandler(method string) *Route {
	handler := e.handlers[method]
	if handler == nil {
		handler = e.handler
	}
	return handler
}

func ( e * Entry ) GetHandler ( method string ) * Route { handler := e . handlers [ method ] if handler == nil { handler = e . handler } return handler }

// GetHandler returns a handler with given method.

GetHandler returns a handler with given method .


func (e *Entry) getChildEntry(pat string) *Entry {
	for _, entry := range e.entries {
		if pat == entry.Pattern() {
			return entry
		}
	}
	return nil
}

func ( e * Entry ) getChildEntry ( pat string ) * Entry { for _ , entry := range e . entries { if pat == entry . Pattern ( ) { return entry } } return nil }

// getChildEntry returns a child Entry that matches the given pattern string.

getChildEntry returns a child Entry that matches the given pattern string .


func (e *Entry) MergePatterns(patterns []string) *Entry {
	pat, size := PeekNextPattern(patterns)
	if child := e.getChildEntry(pat); child != nil {
		if len(patterns) == size {
			return child
		}
		return child.MergePatterns(patterns[size:])
	}
	return e.addPatterns(patterns)
}

func ( e * Entry ) MergePatterns ( patterns [ ] string ) * Entry { pat , size := PeekNextPattern ( patterns ) if child := e . getChildEntry ( pat ) ; child != nil { if len ( patterns ) == size { return child } return child . MergePatterns ( patterns [ size : ] ) } return e . addPatterns ( patterns ) }

// MergePattern add entry patterns with given pattern strings. If a pattern
// already exists on the entry, it adds remaining patterns to the existing entry.

MergePattern add entry patterns with given pattern strings . If a pattern already exists on the entry it adds remaining patterns to the existing entry .


func (e *Entry) AddEntry(child *Entry) {
	length := len(e.entries)
	if length == 0 {
		e.entries = append(e.entries, child)
		return
	}

	index := sort.Search(length, func(i int) bool {
		return child.weight > e.entries[i].weight
	})

	if index == length {
		e.entries = append(e.entries, child)
		return
	}

	e.entries = append(e.entries, nil)
	copy(e.entries[index+1:], e.entries[index:])
	e.entries[index] = child
}

func ( e * Entry ) AddEntry ( child * Entry ) { length := len ( e . entries ) if length == 0 { e . entries = append ( e . entries , child ) return } index := sort . Search ( length , func ( i int ) bool { return child . weight > e . entries [ i ] . weight } ) if index == length { e . entries = append ( e . entries , child ) return } e . entries = append ( e . entries , nil ) copy ( e . entries [ index + 1 : ] , e . entries [ index : ] ) e . entries [ index ] = child }

// AddEntry add new child entry. Child entries are sorted irrespective of order
// they are added. Static patterns would be indexed ahead of match patterns.

AddEntry add new child entry . Child entries are sorted irrespective of order they are added . Static patterns would be indexed ahead of match patterns .


func (e *Entry) addPatterns(patterns []string) *Entry {
	var currentNode *Entry = e

	for len(patterns) > 0 {
		var entry *Entry
		pat, size := PeekNextPattern(patterns)

		// suffix entry
		if size == 2 {
			matcher, name := parseMatcher(patterns[0])
			suffixMatcher := &SuffixMatcher{patterns[1], matcher}
			entry = newSuffixMatchEntry(pat, name, suffixMatcher)
		} else if isMatchPattern(pat) {
			entry = newMatchEntry(pat)
		} else {
			entry = newStaticEntry(pat)
		}

		currentNode.AddEntry(entry)
		currentNode = entry
		patterns = patterns[size:]
	}

	return currentNode
}

func
(
e
*
Entry
)
addPatterns
(
patterns
[
]
string
)
*
Entry
{
var
currentNode
*
Entry
=
e
for
len
(
patterns
)
>
0
{
var
entry
*
Entry
pat
,
size
:=
PeekNextPattern
(
patterns
)
// suffix entry
if
size
==
2
{
matcher
,
name
:=
parseMatcher
(
patterns
[
0
]
)
suffixMatcher
:=
&
SuffixMatcher
{
patterns
[
1
]
,
matcher
}
entry
=
newSuffixMatchEntry
(
pat
,
name
,
suffixMatcher
)
}
else
if
isMatchPattern
(
pat
)
{
entry
=
newMatchEntry
(
pat
)
}
else
{
entry
=
newStaticEntry
(
pat
)
}
currentNode
.
AddEntry
(
entry
)
currentNode
=
entry
patterns
=
patterns
[
size
:
]
}
return
currentNode
}

// addPatterns adds entry children with the pattern strings.

addPatterns adds entry children with the pattern strings .


func (e *Entry) execPrefix(method, urlStr string) (*Route, []string) {
	if !strings.HasPrefix(urlStr, e.pattern) {
		return nil, nil
	}
	if len(urlStr) == len(e.pattern) {
		return e.GetHandler(method), nil
	}
	return e.traverse(method, urlStr[len(e.pattern):])
}

func ( e * Entry ) execPrefix ( method , urlStr string ) ( * Route , [ ] string ) { if ! strings . HasPrefix ( urlStr , e . pattern ) { return nil , nil } if len ( urlStr ) == len ( e . pattern ) { return e . GetHandler ( method ) , nil } return e . traverse ( method , urlStr [ len ( e . pattern ) : ] ) }

// execPrefix simply see if the given urlStr has a leading pattern.

execPrefix simply see if the given urlStr has a leading pattern .


func (e *Entry) traverse(method, urlStr string) (*Route, []string) {
	for _, entry := range e.entries {
		if h, params := entry.exec(method, urlStr); h != nil {
			return h, params
		}
	}
	return nil, nil
}

func ( e * Entry ) traverse ( method , urlStr string ) ( * Route , [ ] string ) { for _ , entry := range e . entries { if h , params := entry . exec ( method , urlStr ) ; h != nil { return h , params } } return nil , nil }

// traverse tries matches to child entries.

traverse tries matches to child entries .


func (e *Entry) getExecMatch(name string, matcher Matcher) ExecFunc {
	return func(method, urlStr string) (*Route, []string) {
		offset, matchStr := matcher.Match(urlStr)
		if offset == -1 {
			return nil, nil
		}

		// finish parsing
		if len(urlStr) == offset {
			if h := e.GetHandler(method); h != nil {
				return h, []string{name, matchStr}
			}
			return nil, nil
		}

		for _, entry := range e.entries {
			if h, params := entry.exec(method, urlStr[offset:]); h != nil {
				params = append(params, name, matchStr)
				return h, params
			}
		}
		return nil, nil
	}
}

func
(
e
*
Entry
)
getExecMatch
(
name
string
,
matcher
Matcher
)
ExecFunc
{
return
func
(
method
,
urlStr
string
)
(
*
Route
,
[
]
string
)
{
offset
,
matchStr
:=
matcher
.
Match
(
urlStr
)
if
offset
==
1
{
return
,
}
// finish parsing
if
len
(
urlStr
)
==
offset
{
if
h
:=
e
.
GetHandler
(
method
)
;
h
!=
{
return
h
,
[
]
string
{
name
,
matchStr
}
}
return
,
}
for
_
,
entry
:=
range
e
.
entries
{
if
h
,
params
:=
entry
.
exec
(
method
,
urlStr
[
offset
:
]
)
;
h
!=
{
params
=
append
(
params
,
name
,
matchStr
)
return
h
,
params
}
}
return
,
}
}

// getExecMatch returns ExecFunc with the given name and mather.

getExecMatch returns ExecFunc with the given name and mather .


func MergeRoutes(r ...Routable) Routes {
	routes := make(Routes, 0)
	for _, v := range r {
		routes = append(routes, v.Routes()...)
	}
	return routes
}

func MergeRoutes ( r ... Routable ) Routes { routes := make ( Routes , 0 ) for _ , v := range r { routes = append ( routes , v . Routes ( ) ... ) } return routes }

// MergeRoutes returns a slice with all routes returned by Routable objects.

MergeRoutes returns a slice with all routes returned by Routable objects .


func (l *logger) Debugln(vals ...interface{}) {
	l.mut.Lock()
	defer l.mut.Unlock()
	s := fmt.Sprintln(vals...)
	l.logger.Output(2, "DEBUG: "+s)
	l.callHandlers(LevelDebug, s)
}

func ( l * logger ) Debugln ( vals ... interface { } ) { l . mut . Lock ( ) defer l . mut . Unlock ( ) s := fmt . Sprintln ( vals ... ) l . logger . Output ( 2 , " " + s ) l . callHandlers ( LevelDebug , s ) }

// Debugln logs a line with a DEBUG prefix.

Debugln logs a line with a DEBUG prefix .


func (l *logger) Debugf(format string, vals ...interface{}) {
	l.mut.Lock()
	defer l.mut.Unlock()
	s := fmt.Sprintf(format, vals...)
	l.logger.Output(2, "DEBUG: "+s)
	l.callHandlers(LevelDebug, s)
}

func ( l * logger ) Debugf ( format string , vals ... interface { } ) { l . mut . Lock ( ) defer l . mut . Unlock ( ) s := fmt . Sprintf ( format , vals ... ) l . logger . Output ( 2 , " " + s ) l . callHandlers ( LevelDebug , s ) }

// Debugf logs a formatted line with a DEBUG prefix.

Debugf logs a formatted line with a DEBUG prefix .


func (l *logger) Verbosef(format string, vals ...interface{}) {
	l.mut.Lock()
	defer l.mut.Unlock()
	s := fmt.Sprintf(format, vals...)
	l.logger.Output(2, "VERBOSE: "+s)
	l.callHandlers(LevelVerbose, s)
}

func ( l * logger ) Verbosef ( format string , vals ... interface { } ) { l . mut . Lock ( ) defer l . mut . Unlock ( ) s := fmt . Sprintf ( format , vals ... ) l . logger . Output ( 2 , " " + s ) l . callHandlers ( LevelVerbose , s ) }

// Infof logs a formatted line with a VERBOSE prefix.

Infof logs a formatted line with a VERBOSE prefix .


func (l *logger) Infoln(vals ...interface{}) {
	l.mut.Lock()
	defer l.mut.Unlock()
	s := fmt.Sprintln(vals...)
	l.logger.Output(2, "INFO: "+s)
	l.callHandlers(LevelInfo, s)
}

func ( l * logger ) Infoln ( vals ... interface { } ) { l . mut . Lock ( ) defer l . mut . Unlock ( ) s := fmt . Sprintln ( vals ... ) l . logger . Output ( 2 , " " + s ) l . callHandlers ( LevelInfo , s ) }

// Infoln logs a line with an INFO prefix.

Infoln logs a line with an INFO prefix .


func (l *logger) Infof(format string, vals ...interface{}) {
	l.mut.Lock()
	defer l.mut.Unlock()
	s := fmt.Sprintf(format, vals...)
	l.logger.Output(2, "INFO: "+s)
	l.callHandlers(LevelInfo, s)
}

func ( l * logger ) Infof ( format string , vals ... interface { } ) { l . mut . Lock ( ) defer l . mut . Unlock ( ) s := fmt . Sprintf ( format , vals ... ) l . logger . Output ( 2 , " " + s ) l . callHandlers ( LevelInfo , s ) }

// Infof logs a formatted line with an INFO prefix.

Infof logs a formatted line with an INFO prefix .


func (l *logger) Okln(vals ...interface{}) {
	l.mut.Lock()
	defer l.mut.Unlock()
	s := fmt.Sprintln(vals...)
	l.logger.Output(2, "OK: "+s)
	l.callHandlers(LevelOK, s)
}

func ( l * logger ) Okln ( vals ... interface { } ) { l . mut . Lock ( ) defer l . mut . Unlock ( ) s := fmt . Sprintln ( vals ... ) l . logger . Output ( 2 , " " + s ) l . callHandlers ( LevelOK , s ) }


func (l *logger) Okf(format string, vals ...interface{}) {
	l.mut.Lock()
	defer l.mut.Unlock()
	s := fmt.Sprintf(format, vals...)
	l.logger.Output(2, "OK: "+s)
	l.callHandlers(LevelOK, s)
}

func ( l * logger ) Okf ( format string , vals ... interface { } ) { l . mut . Lock ( ) defer l . mut . Unlock ( ) s := fmt . Sprintf ( format , vals ... ) l . logger . Output ( 2 , " " + s ) l . callHandlers ( LevelOK , s ) }

// Okf logs a formatted line with an OK prefix.

Okf logs a formatted line with an OK prefix .


func (l *logger) Fatalln(vals ...interface{}) {
	l.mut.Lock()
	defer l.mut.Unlock()
	s := fmt.Sprintln(vals...)
	l.logger.Output(2, "FATAL: "+s)
	l.callHandlers(LevelFatal, s)
	os.Exit(1)
}

func ( l * logger ) Fatalln ( vals ... interface { } ) { l . mut . Lock ( ) defer l . mut . Unlock ( ) s := fmt . Sprintln ( vals ... ) l . logger . Output ( 2 , " " + s ) l . callHandlers ( LevelFatal , s ) os . Exit ( 1 ) }

// Fatalln logs a line with a FATAL prefix and exits the process with exit
// code 1.

Fatalln logs a line with a FATAL prefix and exits the process with exit code 1 .


func (l *logger) Fatalf(format string, vals ...interface{}) {
	l.mut.Lock()
	defer l.mut.Unlock()
	s := fmt.Sprintf(format, vals...)
	l.logger.Output(2, "FATAL: "+s)
	l.callHandlers(LevelFatal, s)
	os.Exit(1)
}

func ( l * logger ) Fatalf ( format string , vals ... interface { } ) { l . mut . Lock ( ) defer l . mut . Unlock ( ) s := fmt . Sprintf ( format , vals ... ) l . logger . Output ( 2 , " " + s ) l . callHandlers ( LevelFatal , s ) os . Exit ( 1 ) }

// Fatalf logs a formatted line with a FATAL prefix and exits the process with
// exit code 1.

Fatalf logs a formatted line with a FATAL prefix and exits the process with exit code 1 .


func (l *logger) ShouldDebug(facility string) bool {
	l.mut.Lock()
	res := l.debug[facility]
	l.mut.Unlock()
	return res
}

func ( l * logger ) ShouldDebug ( facility string ) bool { l . mut . Lock ( ) res := l . debug [ facility ] l . mut . Unlock ( ) return res }

// ShouldDebug returns true if the given facility has debugging enabled.

ShouldDebug returns true if the given facility has debugging enabled .


func (l *logger) SetDebug(facility string, enabled bool) {
	l.mut.Lock()
	l.debug[facility] = enabled
	l.mut.Unlock()
}

func ( l * logger ) SetDebug ( facility string , enabled bool ) { l . mut . Lock ( ) l . debug [ facility ] = enabled l . mut . Unlock ( ) }

// SetDebug enabled or disables debugging for the given facility name.

SetDebug enabled or disables debugging for the given facility name .


func (l *logger) Facilities() (enabled, disabled []string) {
	l.mut.Lock()
	for facility, isEnabled := range l.debug {
		if isEnabled {
			enabled = append(enabled, facility)
		} else {
			disabled = append(disabled, facility)
		}
	}
	l.mut.Unlock()
	return
}

func ( l * logger ) Facilities ( ) ( enabled , disabled [ ] string ) { l . mut . Lock ( ) for facility , isEnabled := range l . debug { if isEnabled { enabled = append ( enabled , facility ) } else { disabled = append ( disabled , facility ) } } l . mut . Unlock ( ) return }

// Facilities returns the currently known set of facilities, both those for
// which debug is enabled and those for which it is disabled.

Facilities returns the currently known set of facilities both those for which debug is enabled and those for which it is disabled .


func (l *logger) NewFacility(facility string) Logger {
	l.mut.Lock()
	if l.debug == nil {
		l.debug = make(map[string]bool)
	}
	l.debug[facility] = false
	l.mut.Unlock()

	return &facilityLogger{
		logger:   l,
		facility: facility,
	}
}

func ( l * logger ) NewFacility ( facility string ) Logger { l . mut . Lock ( ) if l . debug == nil { l . debug = make ( map [ string ] bool ) } l . debug [ facility ] = false l . mut . Unlock ( ) return & facilityLogger { logger : l , facility : facility , } }

// NewFacility returns a new logger bound to the named facility.

NewFacility returns a new logger bound to the named facility .


func (f *formatifier) removeNonDigits() {
	rp := regexp.MustCompile(`\D`)
	f.theString = rp.ReplaceAllString(f.theString, "")
}

func ( f * formatifier ) removeNonDigits ( ) { rp := regexp . MustCompile ( `\D` ) f . theString = rp . ReplaceAllString ( f . theString , " " ) }

// removeNonDigits removes any non digit characters from the string.

removeNonDigits removes any non digit characters from the string .


func (f *formatifier) removeNonWordChars() {
	if len(f.theString) > 0 {
		rp := regexp.MustCompile(`\W|\s|_`)
		f.theString = rp.ReplaceAllString(f.theString, "")
	}
}

func ( f * formatifier ) removeNonWordChars ( ) { if len ( f . theString ) > 0 { rp := regexp . MustCompile ( `\W|\s|_` ) f . theString = rp . ReplaceAllString ( f . theString , " " ) } }

// removeNonWordChars removes all non word characters.

removeNonWordChars removes all non word characters .


func (f *formatifier) urlEncodeSpaces() {
	rp := regexp.MustCompile(`\s`)
	f.theString = rp.ReplaceAllString(f.theString, "%20")
}

func ( f * formatifier ) urlEncodeSpaces ( ) { rp := regexp . MustCompile ( `\s` ) f . theString = rp . ReplaceAllString ( f . theString , " " ) }

// urlEncodeSpaces will replace spaces with "%20"'s

urlEncodeSpaces will replace spaces with %20 s


func randomSelect(a []int) int {
	var tmpIndex int
	length := len(a)
	randBytes := make([]byte, length)
	if _, err := rand.Read(randBytes); err == nil {
		tmpIndex = int(randBytes[0]) % length
	}
	return a[tmpIndex]
}

func randomSelect ( a [ ] int ) int { var tmpIndex int length := len ( a ) randBytes := make ( [ ] byte , length ) if _ , err := rand . Read ( randBytes ) ; err == nil { tmpIndex = int ( randBytes [ 0 ] ) % length } return a [ tmpIndex ] }

// random select will return a random selection from an int slice


func NewStdFormatter(delim, tmpl string, entry Entry, values map[string]interface{}, timeformat string) (Formatter, error) {
	if delim == "" {
		return nil, e.New("invalid delimitator")
	}
	if tmpl == "" {
		return nil, e.New("invalid template")
	}
	if entry == nil {
		return nil, e.New("invalid entry")
	}
	if values == nil {
		return nil, e.New("invalid values")
	}
	if timeformat == "" {
		timeformat = TimeDateFormat
	}
	return &StdFormatter{
		Delim:      []byte(delim),
		Tmpl:       []byte(tmpl),
		E:          entry,
		Map:        values,
		Idx:        mkindex(entry),
		TimeFormat: timeformat,
	}, nil
}

func NewStdFormatter ( delim , tmpl string , entry Entry , values map [ string ] interface { } , timeformat string ) ( Formatter , error ) { if delim == " " { return nil , e . New ( " " ) } if tmpl == " " { return nil , e . New ( " " ) } if entry == nil { return nil , e . New ( " " ) } if values == nil { return nil , e . New ( " " ) } if timeformat == " " { timeformat = TimeDateFormat } return & StdFormatter { Delim : [ ] byte ( delim ) , Tmpl : [ ] byte ( tmpl ) , E : entry , Map : values , Idx : mkindex ( entry ) , TimeFormat : timeformat , } , nil }

// NewStdFormatter crete a new formatter.


func (s Chain) Get(handler http.Handler) http.Handler {
	for i := len(s) - 1; i >= 0; i-- {
		handler = s[i](handler)
	}
	return handler
}

func ( s Chain ) Get ( handler http . Handler ) http . Handler { for i := len ( s ) - 1 ; i >= 0 ; i -- { handler = s [ i ] ( handler ) } return handler }

// Get returns a HTTP handler which is a chain of middlewares and then the
// specified handler.

Get returns a HTTP handler which is a chain of middlewares and then the specified handler .


func parseMatcher(pat string) (matcher Matcher, name string) {
	if !isMatchPattern(pat) {
		panic("pattern \"" + pat + "\" is not a matcher pattern")
	}

	s := pat[1 : len(pat)-1]
	ss := strings.Split(s, ":")
	var matchType string
	if len(ss) == 1 {
		name = ss[0]
	} else {
		matchType = ss[0]
		name = ss[1]
	}
	if matchType == "" {
		matchType = "default"
	}

	matcher = MatcherMap[matchType]
	if matcher == nil {
		panic(errors.New("no such match type: " + matchType))
	}

	return matcher, name
}

func parseMatcher ( pat string ) ( matcher Matcher , name string ) { if ! isMatchPattern ( pat ) { panic ( " \" " + pat + " \" " ) } s := pat [ 1 : len ( pat ) - 1 ] ss := strings . Split ( s , " " ) var matchType string if len ( ss ) == 1 { name = ss [ 0 ] } else { matchType = ss [ 0 ] name = ss [ 1 ] } if matchType == " " { matchType = " " } matcher = MatcherMap [ matchType ] if matcher == nil { panic ( errors . New ( " " + matchType ) ) } return matcher , name }

// parseMatcher returns matcher and name from the given pattern string.

parseMatcher returns matcher and name from the given pattern string .


func isMatchPattern(s string) bool {
	return len(s) > 2 && s[0] == '<' && s[len(s)-1] == '>'
}

func isMatchPattern ( s string ) bool { return len ( s ) > 2 && s [ 0 ] == '<' && s [ len ( s ) - 1 ] == '>' }

// isMatchPattern see if given string is match pattern.

isMatchPattern see if given string is match pattern .


func routeSplitFunc(data []byte, atEOF bool) (int, []byte, error) {
	if atEOF || data == nil {
		return 0, nil, io.EOF
	}

	r, _ := utf8.DecodeRune(data)

	// matcher
	if r == '<' {
		i := bytes.IndexRune(data, '>')
		if i == -1 {
			return 0, nil, NoClosingBracket
		}
		return (i + 1), data[:(i + 1)], nil
	}

	// one char
	if len(data) == 1 {
		return 1, data, nil
	}

	// should ignore first '/'
	slashIndex := bytes.IndexRune(data[1:], '/')
	if slashIndex != -1 {
		slashIndex++
	}

	matchIndex := bytes.IndexRune(data, '<')

	// remaining string would be a static entry
	if slashIndex == -1 && matchIndex == -1 {
		return len(data), data, nil
	}

	// split by '<'
	// return data before '<'
	if matchIndex != -1 && (slashIndex == -1 || slashIndex > matchIndex) {
		return matchIndex, data[:matchIndex], nil
	}

	// split by '/'
	// return data before '/' including '/'
	return slashIndex + 1, data[:(slashIndex + 1)], nil
}

// routeSplitFunc is the SplitFunc to scan url pattern.

routeSplitFunc is the SplitFunc to scan url pattern .


func SplitPath(pat string) (routes []string, err error) {
	scanner := bufio.NewScanner(strings.NewReader(pat))
	scanner.Split(routeSplitFunc)
	for scanner.Scan() {
		routes = append(routes, scanner.Text())
	}
	err = scanner.Err()
	return
}

func SplitPath ( pat string ) ( routes [ ] string , err error ) { scanner := bufio . NewScanner ( strings . NewReader ( pat ) ) scanner . Split ( routeSplitFunc ) for scanner . Scan ( ) { routes = append ( routes , scanner . Text ( ) ) } err = scanner . Err ( ) return }


func isNextSuffixPattern(p []string) bool {
	if len(p) >= 2 && isMatchPattern(p[0]) && !isMatchPattern(p[1]) {
		matcher, _ := parseMatcher(p[0])
		if _, ok := matcher.(*FixedLengthMatcher); ok {
			return false
		}
		r, _ := utf8.DecodeRuneInString(p[1])
		return matcher.MatchRune(r)
	}
	return false
}

func isNextSuffixPattern ( p [ ] string ) bool { if len ( p ) >= 2 && isMatchPattern ( p [ 0 ] ) && ! isMatchPattern ( p [ 1 ] ) { matcher , _ := parseMatcher ( p [ 0 ] ) if _ , ok := matcher . ( * FixedLengthMatcher ) ; ok { return false } r , _ := utf8 . DecodeRuneInString ( p [ 1 ] ) return matcher . MatchRune ( r ) } return false }

// isNextSuffixPattern see next 2 patterns can be suffix matcher. If following
// two cases are both true, it could possibly become a suffix matcher.
//   1. the first pattern is a Matcher.
//   2. the next pattern is a static pattern.
// If the first matcher can't match the first rune of the second static pattern,
// next pattern should be a suffix matcher combined the two patterns.

isNextSuffixPattern see next 2 patterns can be suffix matcher . If following two cases are both true it could possibly become a suffix matcher . 1 . the first pattern is a Matcher . 2 . the next pattern is a static pattern . If the first matcher can t match the first rune of the second static pattern next pattern should be a suffix matcher combined the two patterns .


func PeekNextPattern(p []string) (pat string, size int) {
	if isNextSuffixPattern(p) {
		pat, size = (p[0] + p[1]), 2
	} else {
		pat, size = p[0], 1
	}
	return
}

func PeekNextPattern ( p [ ] string ) ( pat string , size int ) { if isNextSuffixPattern ( p ) { pat , size = ( p [ 0 ] + p [ 1 ] ) , 2 } else { pat , size = p [ 0 ] , 1 } return }

// PeekNextPattern returns next entry pattern with offset size


func NewPlayer(nick string, profile Profile) (*Player, error) {
	p := new(Player)
	newUUID, err := uuid.V4()
	if err != nil {
		// FIXME: Handle error
	}
	p.UUID = newUUID
	p.Nick = nick
	p.Profile = profile
	err = storage.Store(p)
	if err != nil {
		return nil, errors.New(err.Error() + " - Could not write player to storage")
	}
	return p, nil
}

func
NewPlayer
(
nick
string
,
profile
Profile
)
(
*
Player
,
error
)
{
p
:=
new
(
Player
)
newUUID
,
err
:=
uuid
.
V4
(
)
if
err
!=
{
// FIXME: Handle error
}
p
.
UUID
=
newUUID
p
.
Nick
=
nick
p
.
Profile
=
profile
err
=
storage
.
Store
(
p
)
if
err
!=
{
return
,
errors
.
New
(
err
.
Error
(
)
+
"
"
)
}
return
p
,
}

//
// Player related functions and methods
//
// Create a player

Player related functions and methods Create a player


func (r *Reader) Push(reader io.Reader) {
	r.readers = append(r.readers, reader)
}

func ( r * Reader ) Push ( reader io . Reader ) { r . readers = append ( r . readers , reader ) }

// Push causes the Reader to start reading from a new io.Reader. When an EOF
// error is seen from the new io.Reader, it is popped and the Reader continues
// to read from the next most recent io.Reader.

Push causes the Reader to start reading from a new io . Reader . When an EOF error is seen from the new io . Reader it is popped and the Reader continues to read from the next most recent io . Reader .


func NewCatering(tournament uuid.UUID, ci Info) (*Catering, error) {
	c := new(Catering)
	c.UUID, _ = uuid.V4()
	c.Tournament = tournament
	if err := mergo.MergeWithOverwrite(&c.Info, ci); err != nil {
		return nil, errors.New(err.Error() + " - Could not set initial catering info")
	}
	if err := storage.Store(c); err != nil {
		return nil, errors.New(err.Error() + " - Could not write catering to storage")
	}
	return c, nil
}

func NewCatering ( tournament uuid . UUID , ci Info ) ( * Catering , error ) { c := new ( Catering ) c . UUID , _ = uuid . V4 ( ) c . Tournament = tournament if err := mergo . MergeWithOverwrite ( & c . Info , ci ) ; err != nil { return nil , errors . New ( err . Error ( ) + " " ) } if err := storage . Store ( c ) ; err != nil { return nil , errors . New ( err . Error ( ) + " " ) } return c , nil }

//
// Catering related functions and methods
//
// Create a Catering

Catering related functions and methods Create a Catering


func (t Tournaments) GroupByMonths(season int) map[time.Month]Tournaments {
	byMonth := make(map[time.Month]Tournaments)

	for _, entry := range t {
		y, m := entry.Info.Scheduled.Year(), entry.Info.Scheduled.Month()
		if y == season {
			byMonth[m] = append(byMonth[m], entry)
		}
	}

	return byMonth
}

func ( t Tournaments ) GroupByMonths ( season int ) map [ time . Month ] Tournaments { byMonth := make ( map [ time . Month ] Tournaments ) for _ , entry := range t { y , m := entry . Info . Scheduled . Year ( ) , entry . Info . Scheduled . Month ( ) if y == season { byMonth [ m ] = append ( byMonth [ m ] , entry ) } } return byMonth }

//
// Tournaments related functions and methods
//


func validateTournamentInfo(info Info) error {
	if info.Scheduled.IsZero() {
		return errors.New("Tournament needs scheduled date")
	}
	if info.Stake == 0 {
		return errors.New("Tournament needs a stake")
	}
	if info.Season == 0 {
		return errors.New("Tournament needs a season")
	}
	return nil
}

func validateTournamentInfo ( info Info ) error { if info . Scheduled . IsZero ( ) { return errors . New ( " " ) } if info . Stake == 0 { return errors . New ( " " ) } if info . Season == 0 { return errors . New ( " " ) } return nil }

//
// Tournament related functions and methods
//
// Helpers

Tournament related functions and methods Helpers


func NewTournament(tdata Info) (*Tournament, error) {
	if err := validateTournamentInfo(tdata); err != nil {
		return nil, errors.New(err.Error() + " - Could not create tournament")
	}

	t := new(Tournament)
	t.UUID, _ = uuid.V4()
	if err := mergo.MergeWithOverwrite(&t.Info, tdata); err != nil {
		return nil, errors.New(err.Error() + " - Could not set initial tournament data")
	}
	// Merge seems to not handle time.Time for some reason, thus fixup
	fixupTournamentInfo(&t.Info, tdata)
	if err := storage.Store(t); err != nil {
		return nil, errors.New(err.Error() + " - Could not write tournament to storage")
	}
	return t, nil
}


func (s StringSlice) IndexOf(str string) int {
	for i, v := range s {
		if str == v {
			return i
		}
	}

	return -1
}

func ( s StringSlice ) IndexOf ( str string ) int { for i , v := range s { if str == v { return i } } return - 1 }

// IndexOf looks for specified string into current slice.

IndexOf looks for specified string into current slice .


func (s StringSlice) IndexOfIgnoreCase(str string) int {
	str = strings.ToLower(str)
	for i, v := range s {
		if str == strings.ToLower(v) {
			return i
		}
	}

	return -1
}

func ( s StringSlice ) IndexOfIgnoreCase ( str string ) int { str = strings . ToLower ( str ) for i , v := range s { if str == strings . ToLower ( v ) { return i } } return - 1 }

// IndexOfIgnoreCase looks for specified string, disregarding letter casing,
// into current slice.

IndexOfIgnoreCase looks for specified string disregarding letter casing into current slice .


func NewCache(d time.Duration) *Cache {
	return &Cache{
		values:   make(map[string]*cacheItem),
		lifetime: d,
	}
}

func NewCache ( d time . Duration ) * Cache { return & Cache { values : make ( map [ string ] * cacheItem ) , lifetime : d , } }

// NewCache creates a new instance of Cache and defines the default lifetime for
// new cached items.

NewCache creates a new instance of Cache and defines the default lifetime for new cached items .


func (s *Cache) Count() int {
	if s.removeExpired() == raiqub.WriteLocked {
		defer s.Unlock()
	} else {
		defer s.RUnlock()
	}

	return len(s.values)
}

func ( s * Cache ) Count ( ) int { if s . removeExpired ( ) == raiqub . WriteLocked { defer s . Unlock ( ) } else { defer s . RUnlock ( ) } return len ( s . values ) }

// Count gets the number of cached values by current instance.

Count gets the number of cached values by current instance .


func (s *Cache) Flush() {
	s.Lock()
	defer s.Unlock()

	s.values = make(map[string]*cacheItem)
}

func ( s * Cache ) Flush ( ) { s . Lock ( ) defer s . Unlock ( ) s . values = make ( map [ string ] * cacheItem ) }

// Flush deletes any cached value into current instance.

Flush deletes any cached value into current instance .


func (s *Cache) removeExpired() raiqub.LockStatus {
	writeLocked := false
	s.RLock()
	for i := range s.values {
		if s.values[i].IsExpired() {
			if !writeLocked {
				s.RUnlock()
				s.Lock()
				writeLocked = true
			}
			delete(s.values, i)
		}
	}

	if writeLocked {
		return raiqub.WriteLocked
	} else {
		return raiqub.ReadLocked
	}
}

func ( s * Cache ) removeExpired ( ) raiqub . LockStatus { writeLocked := false s . RLock ( ) for i := range s . values { if s . values [ i ] . IsExpired ( ) { if ! writeLocked { s . RUnlock ( ) s . Lock ( ) writeLocked = true } delete ( s . values , i ) } } if writeLocked { return raiqub . WriteLocked } else { return raiqub . ReadLocked } }

// removeExpired remove all expired values from current Cache instance list.
// Returns the locking status of current instance.

removeExpired remove all expired values from current Cache instance list . Returns the locking status of current instance .


func NewImage(d *Docker, name string) *Image {
	return &Image{
		docker: d,
		name:   name,
	}
}

func NewImage ( d * Docker , name string ) * Image { return & Image { docker : d , name : name , } }

// NewImage creates a new instance of Image.

NewImage creates a new instance of Image .


func (s *Image) Exists() bool {
	out, err := s.docker.Run("images", "--no-trunc")
	if err != nil {
		return false
	}

	return strings.Contains(out, s.name)
}

func ( s * Image ) Exists ( ) bool { out , err := s . docker . Run ( " " , " " ) if err != nil { return false } return strings . Contains ( out , s . name ) }

// Exists check whether current Docker image is available.

Exists check whether current Docker image is available .


func (s *Image) Pull() error {
	_, err := s.docker.Run("pull", s.name)
	if err != nil {
		return err
	}

	return nil
}

func ( s * Image ) Pull ( ) error { _ , err := s . docker . Run ( " " , s . name ) if err != nil { return err } return nil }

// Pull retrieves current Docker image from Docker repository.
//
// Returns ExternalCmdError on error.

Pull retrieves current Docker image from Docker repository . Returns ExternalCmdError on error .


func (s *Image) Run(cfg *RunConfig) (*Container, error) {
	args := make([]string, 0, len(cfg.Options)+len(cfg.Args)+1)
	args = append(args, cfg.Options...)
	args = append(args, s.name)
	args = append(args, cfg.Args...)

	out, err := s.docker.Run("run", args...)
	if err != nil {
		return nil, err
	}

	container := &Container{
		docker: s.docker,
		id:     strings.TrimSpace(out),
	}
	if container.id == "" {
		return nil, UnexpectedOutputError(
			"Unexpected empty output when running docker container")
	}

	return container, nil
}

func ( s * Image ) Run ( cfg * RunConfig ) ( * Container , error ) { args := make ( [ ] string , 0 , len ( cfg . Options ) + len ( cfg . Args ) + 1 ) args = append ( args , cfg . Options ... ) args = append ( args , s . name ) args = append ( args , cfg . Args ... ) out , err := s . docker . Run ( " " , args ... ) if err != nil { return nil , err } container := & Container { docker : s . docker , id : strings . TrimSpace ( out ) , } if container . id == " " { return nil , UnexpectedOutputError ( " " ) } return container , nil }

// Run creates a new Docker container as defined by current image and container
// template.
//
// Returns ExternalCmdError or UnexpectedOutputError on error.

Run creates a new Docker container as defined by current image and container template . Returns ExternalCmdError or UnexpectedOutputError on error .


func (s *Image) Setup() error {
	if !s.docker.HasBin() {
		return DockerBinNotFound(s.docker.binCmd)
	}

	if !s.Exists() {
		if err := s.Pull(); err != nil {
			return err
		}
	}

	return nil
}

func ( s * Image ) Setup ( ) error { if ! s . docker . HasBin ( ) { return DockerBinNotFound ( s . docker . binCmd ) } if ! s . Exists ( ) { if err := s . Pull ( ) ; err != nil { return err } } return nil }

// Setup check if Docker binary is available and pull current image from Docker
// repository in case it is not already available.

Setup check if Docker binary is available and pull current image from Docker repository in case it is not already available .


func NewLocation(host uuid.UUID, lp Profile) (*Location, error) {
	l := new(Location)
	l.UUID, _ = uuid.V4()
	l.Active = true
	l.Host = host
	if err := mergo.MergeWithOverwrite(&l.Profile, lp); err != nil {
		return nil, errors.New(err.Error() + " - Could not set initial location profile")
	}
	if err := storage.Store(l); err != nil {
		return nil, errors.New(err.Error() + " - Could not write location to storage")
	}
	return l, nil
}

func NewLocation ( host uuid . UUID , lp Profile ) ( * Location , error ) { l := new ( Location ) l . UUID , _ = uuid . V4 ( ) l . Active = true l . Host = host if err := mergo . MergeWithOverwrite ( & l . Profile , lp ) ; err != nil { return nil , errors . New ( err . Error ( ) + " " ) } if err := storage . Store ( l ) ; err != nil { return nil , errors . New ( err . Error ( ) + " " ) } return l , nil }

//
// Location related functions and methods
//
// Create a Location

Location related functions and methods Create a Location


func (s NetworkSettings) PortAt(index int) (string, *HostPublish) {
	counter := 0
	for k, v := range s.Ports {
		if counter != index {
			counter++
			continue
		}

		return k, v
	}

	return "", nil
}

func ( s NetworkSettings ) PortAt ( index int ) ( string , * HostPublish ) { counter := 0 for k , v := range s . Ports { if counter != index { counter ++ continue } return k , v } return " " , nil }

// PortAt returns expose and publish port information at especified index.

PortAt returns expose and publish port information at especified index .


func (s NetworkSettings) SplitPort(index int) (uint16, string) {
	ptProt, _ := s.PortAt(index)
	vect := strings.Split(ptProt, "/")
	port, _ := strconv.ParseUint(vect[0], 10, 16)
	return uint16(port), vect[1]
}

func ( s NetworkSettings ) SplitPort ( index int ) ( uint16 , string ) { ptProt , _ := s . PortAt ( index ) vect := strings . Split ( ptProt , " " ) port , _ := strconv . ParseUint ( vect [ 0 ] , 10 , 16 ) return uint16 ( port ) , vect [ 1 ] }

// SplitPort splits port number and protocol name from Ports string.

SplitPort splits port number and protocol name from Ports string .


func (s SyslogFacility) Priority() syslog.Priority {
	return syslogPriorities[strings.ToLower(s.String())]
}

func ( s SyslogFacility ) Priority ( ) syslog . Priority { return syslogPriorities [ strings . ToLower ( s . String ( ) ) ] }

// Priority returns a syslog.Priority representation of SyslogFacility.

Priority returns a syslog . Priority representation of SyslogFacility .


func (s SyslogFacility) OK() (ok bool) {
	_, ok = syslogPriorities[strings.ToLower(s.String())]
	return
}

func ( s SyslogFacility ) OK ( ) ( ok bool ) { _ , ok = syslogPriorities [ strings . ToLower ( s . String ( ) ) ] return }

// OK checks if SyslogFacility is valid.


func (formatter *JSONFormatter) Format(record *Record) string {
	data, _ := json.Marshal(record)
	return string(data)
}

func ( formatter * JSONFormatter ) Format ( record * Record ) string { data , _ := json . Marshal ( record ) return string ( data ) }

// Format creates JSON struct from provided record and returns it.

Format creates JSON struct from provided record and returns it .


func Open(path string, mode os.FileMode, options *bolt.Options) (DB, error) {
	db, err := bolt.Open(path, mode, options)
	return DB{db}, errorsp.WithStacks(err)
}

func Open ( path string , mode os . FileMode , options * bolt . Options ) ( DB , error ) { db , err := bolt . Open ( path , mode , options ) return DB { db } , errorsp . WithStacks ( err ) }

// Open creates and opens a database at the given path. If the file does
// not exist then it will be created automatically. Passing in nil options
// will cause Bolt to open the database with the default options.

Open creates and opens a database at the given path . If the file does not exist then it will be created automatically . Passing in nil options will cause Bolt to open the database with the default options .


func (db DB) Begin(writable bool) (Tx, error) {
	tx, err := db.DB.Begin(writable)
	return Tx{tx}, errorsp.WithStacks(err)
}

func ( db DB ) Begin ( writable bool ) ( Tx , error ) { tx , err := db . DB . Begin ( writable ) return Tx { tx } , errorsp . WithStacks ( err ) }


func (db DB) View(f func(Tx) error) error {
	return errorsp.WithStacks(db.DB.View(func(tx *bolt.Tx) error {
		return errorsp.WithStacks(f(Tx{tx}))
	}))
}

func ( db DB ) View ( f func ( Tx ) error ) error { return errorsp . WithStacks ( db . DB . View ( func ( tx * bolt . Tx ) error { return errorsp . WithStacks ( f ( Tx { tx } ) ) } ) ) }


func (tx Tx) CopyFile(path string, mode os.FileMode) error {
	return errorsp.WithStacks(tx.Tx.CopyFile(path, mode))
}

func ( tx Tx ) CopyFile ( path string , mode os . FileMode ) error { return errorsp . WithStacks ( tx . Tx . CopyFile ( path , mode ) ) }

// CopyFile copies the entire database to file at the given path. A reader
// transaction is maintained during the copy so it is safe to continue
// using the database while a copy is in progress.

CopyFile copies the entire database to file at the given path . A reader transaction is maintained during the copy so it is safe to continue using the database while a copy is in progress .


func (tx Tx) CreateBucketIfNotExists(folders [][]byte) (Bucket, error) {
	b, err := tx.Tx.CreateBucketIfNotExists(folders[0])
	if err != nil {
		return Bucket{}, nil
	}
	if len(folders) == 1 {
		return Bucket{b}, nil
	}
	return Bucket{b}.CreateBucketIfNotExists(folders[1:])
}

func ( tx Tx ) CreateBucketIfNotExists ( folders [ ] [ ] byte ) ( Bucket , error ) { b , err := tx . Tx . CreateBucketIfNotExists ( folders [ 0 ] ) if err != nil { return Bucket { } , nil } if len ( folders ) == 1 { return Bucket { b } , nil } return Bucket { b } . CreateBucketIfNotExists ( folders [ 1 : ] ) }

// CreateBucketIfNotExists creates a new bucket if it doesn't already
// exist. Returns an error if the bucket name is blank, or if the bucket
// name is too long. The bucket instance is only valid for the lifetime of
// the transaction.

CreateBucketIfNotExists creates a new bucket if it doesn t already exist . Returns an error if the bucket name is blank or if the bucket name is too long . The bucket instance is only valid for the lifetime of the transaction .


func (tx Tx) Delete(k [][]byte) error {
	if len(k) == 1 {
		return errorsp.WithStacks(tx.Tx.DeleteBucket(k[0]))
	}
	return tx.Bucket(k[:len(k)-1], func(b Bucket) error {
		return errorsp.WithStacks(b.Bucket.Delete(k[len(k)-1]))
	})
}

func ( tx Tx ) Delete ( k [ ] [ ] byte ) error { if len ( k ) == 1 { return errorsp . WithStacks ( tx . Tx . DeleteBucket ( k [ 0 ] ) ) } return tx . Bucket ( k [ : len ( k ) - 1 ] , func ( b Bucket ) error { return errorsp . WithStacks ( b . Bucket . Delete ( k [ len ( k ) - 1 ] ) ) } ) }


func (tx Tx) ForEach(folders [][]byte, f func(Bucket, bytesp.Slice, bytesp.Slice) error) error {
	return tx.Bucket(folders, func(b Bucket) error {
		return errorsp.WithStacks(b.Bucket.ForEach(func(k, v []byte) error {
			return errorsp.WithStacks(f(b, bytesp.Slice(k), bytesp.Slice(v)))
		}))
	})
}

func ( tx Tx ) ForEach ( folders [ ] [ ] byte , f func ( Bucket , bytesp . Slice , bytesp . Slice ) error ) error { return tx . Bucket ( folders , func ( b Bucket ) error { return errorsp . WithStacks ( b . Bucket . ForEach ( func ( k , v [ ] byte ) error { return errorsp . WithStacks ( f ( b , bytesp . Slice ( k ) , bytesp . Slice ( v ) ) ) } ) ) } ) }

// ForEach iterates over all key values of a folder.

ForEach iterates over all key values of a folder .


func (tx Tx) ForEachGob(folders [][]byte, f func(Bucket, bytesp.Slice, interface{}) error) error {
	return tx.ForEach(folders, func(b Bucket, k, bs bytesp.Slice) error {
		var v interface{}
		if err := gob.NewDecoder(&bs).Decode(&v); err != nil {
			return errorsp.WithStacksAndMessage(err, "decoding %d bytes value for key %q failed", len(bs), string(k))
		}
		return errorsp.WithStacks(f(b, k, v))
	})
}

func ( tx Tx ) ForEachGob ( folders [ ] [ ] byte , f func ( Bucket , bytesp . Slice , interface { } ) error ) error { return tx . ForEach ( folders , func ( b Bucket , k , bs bytesp . Slice ) error { var v interface { } if err := gob . NewDecoder ( & bs ) . Decode ( & v ) ; err != nil { return errorsp . WithStacksAndMessage ( err , " " , len ( bs ) , string ( k ) ) } return errorsp . WithStacks ( f ( b , k , v ) ) } ) }

// ForEach iterates over all key values of a folder, decode non-nil values using gob.

ForEach iterates over all key values of a folder decode non - nil values using gob .


func (tx Tx) Put(k [][]byte, v []byte) error {
	b, err := tx.CreateBucketIfNotExists(k[:len(k)-1])
	if err != nil {
		return err
	}
	return errorsp.WithStacks(b.Bucket.Put(k[len(k)-1], v))
}

func ( tx Tx ) Put ( k [ ] [ ] byte , v [ ] byte ) error { b , err := tx . CreateBucketIfNotExists ( k [ : len ( k ) - 1 ] ) if err != nil { return err } return errorsp . WithStacks ( b . Bucket . Put ( k [ len ( k ) - 1 ] , v ) ) }

// Put sets the value for a key in the transaction.
// If the key exist then its previous value will be overwritten.
// Supplied value must remain valid for the life of the transaction.
// Returns an error if the bucket was created from a read-only transaction,
// if the key is blank, if the key is too large, or if the value is too
// large.

Put sets the value for a key in the transaction . If the key exist then its previous value will be overwritten . Supplied value must remain valid for the life of the transaction . Returns an error if the bucket was created from a read - only transaction if the key is blank if the key is too large or if the value is too large .


func (tx Tx) Value(k [][]byte, f func(v bytesp.Slice) error) error {
	return tx.Bucket(k[:len(k)-1], func(b Bucket) error {
		v := b.Bucket.Get(k[len(k)-1])
		if v == nil {
			return nil
		}
		return errorsp.WithStacks(f(bytesp.Slice(v)))
	})
}

func ( tx Tx ) Value ( k [ ] [ ] byte , f func ( v bytesp . Slice ) error ) error { return tx . Bucket ( k [ : len ( k ) - 1 ] , func ( b Bucket ) error { v := b . Bucket . Get ( k [ len ( k ) - 1 ] ) if v == nil { return nil } return errorsp . WithStacks ( f ( bytesp . Slice ( v ) ) ) } ) }

// Value tries to get a value from the transaction. If the key does not
// exist, the f is not called and nil is return.

Value tries to get a value from the transaction . If the key does not exist the f is not called and nil is return .


func (tx Tx) Update(k [][]byte, f func(bytesp.Slice) (bytesp.Slice, error)) error {
	b, err := tx.CreateBucketIfNotExists(k[:len(k)-1])
	if err != nil {
		return err
	}
	v, err := f(b.Bucket.Get(k[len(k)-1]))
	if err != nil {
		return errorsp.WithStacks(err)
	}
	if v == nil {
		return errorsp.WithStacks(b.Bucket.Delete(k[len(k)-1]))
	}
	return errorsp.WithStacks(b.Bucket.Put(k[len(k)-1], v))
}

func ( tx Tx ) Update ( k [ ] [ ] byte , f func ( bytesp . Slice ) ( bytesp . Slice , error ) ) error { b , err := tx . CreateBucketIfNotExists ( k [ : len ( k ) - 1 ] ) if err != nil { return err } v , err := f ( b . Bucket . Get ( k [ len ( k ) - 1 ] ) ) if err != nil { return errorsp . WithStacks ( err ) } if v == nil { return errorsp . WithStacks ( b . Bucket . Delete ( k [ len ( k ) - 1 ] ) ) } return errorsp . WithStacks ( b . Bucket . Put ( k [ len ( k ) - 1 ] , v ) ) }

// Updates fetches the current value and updates to a new value. If a nil
// value is returned by f, the item is deleted.

Updates fetches the current value and updates to a new value . If a nil value is returned by f the item is deleted .


func (b Bucket) OpenBucket(folders [][]byte, f func(Bucket) error) error {
	bb := b.Bucket
	for _, fld := range folders {
		bb = bb.Bucket(fld)
		if bb == nil {
			return nil
		}
	}
	return errorsp.WithStacks(f(Bucket{bb}))
}

func ( b Bucket ) OpenBucket ( folders [ ] [ ] byte , f func ( Bucket ) error ) error { bb := b . Bucket for _ , fld := range folders { bb = bb . Bucket ( fld ) if bb == nil { return nil } } return errorsp . WithStacks ( f ( Bucket { bb } ) ) }

// Bucket retrieves a nested bucket by name. Returns nil if the bucket
// does not exist. The bucket instance is only valid for the lifetime of
// the transaction. folders can be empty, in which case the b itself is
// sent to f.

Bucket retrieves a nested bucket by name . Returns nil if the bucket does not exist . The bucket instance is only valid for the lifetime of the transaction . folders can be empty in which case the b itself is sent to f .


func (b Bucket) CreateBucketIfNotExists(folders [][]byte) (Bucket, error) {
	bb := b.Bucket
	for _, fld := range folders {
		var err error
		if bb, err = bb.CreateBucketIfNotExists(fld); err != nil {
			return Bucket{}, errorsp.WithStacks(err)
		}
	}
	return Bucket{bb}, nil
}

func ( b Bucket ) CreateBucketIfNotExists ( folders [ ] [ ] byte ) ( Bucket , error ) { bb := b . Bucket for _ , fld := range folders { var err error if bb , err = bb . CreateBucketIfNotExists ( fld ) ; err != nil { return Bucket { } , errorsp . WithStacks ( err ) } } return Bucket { bb } , nil }

// CreateBucketIfNotExists creates a new bucket if it doesn't already
// exist and returns a reference to it. Returns an error if the bucket
// name is blank, or if the bucket name is too long. The bucket instance
// is only valid for the lifetime of the transaction.

CreateBucketIfNotExists creates a new bucket if it doesn t already exist and returns a reference to it . Returns an error if the bucket name is blank or if the bucket name is too long . The bucket instance is only valid for the lifetime of the transaction .


func (b Bucket) Delete(k [][]byte) error {
	return b.OpenBucket(k[:len(k)-1], func(b Bucket) error {
		return errorsp.WithStacks(b.Bucket.Delete(k[len(k)-1]))
	})
}

func ( b Bucket ) Delete ( k [ ] [ ] byte ) error { return b . OpenBucket ( k [ : len ( k ) - 1 ] , func ( b Bucket ) error { return errorsp . WithStacks ( b . Bucket . Delete ( k [ len ( k ) - 1 ] ) ) } ) }

// Delete removes a key from the bucket. If the key does not exist then
// nothing is done and a nil error is returned. Returns an error if the
// bucket was created from a read-only transaction.

Delete removes a key from the bucket . If the key does not exist then nothing is done and a nil error is returned . Returns an error if the bucket was created from a read - only transaction .


func (b Bucket) GobValue(k [][]byte, f func(interface{}) error) error {
	return b.Value(k, func(bs bytesp.Slice) error {
		var v interface{}
		if err := gob.NewDecoder(&bs).Decode(&v); err != nil {
			return errorsp.WithStacksAndMessage(err, "decoding %d bytes buffer failed", len(bs))
		}
		return f(v)
	})
}

func ( b Bucket ) GobValue ( k [ ] [ ] byte , f func ( interface { } ) error ) error { return b . Value ( k , func ( bs bytesp . Slice ) error { var v interface { } if err := gob . NewDecoder ( & bs ) . Decode ( & v ) ; err != nil { return errorsp . WithStacksAndMessage ( err , " " , len ( bs ) ) } return f ( v ) } ) }

// GobValue retrieves a value written by PutGob and decode it.

GobValue retrieves a value written by PutGob and decode it .


func (b Bucket) NextSequence() (uint64, error) {
	s, err := b.Bucket.NextSequence()
	return s, errorsp.WithStacks(err)
}

func ( b Bucket ) NextSequence ( ) ( uint64 , error ) { s , err := b . Bucket . NextSequence ( ) return s , errorsp . WithStacks ( err ) }

// NextSequence returns an autoincrementing integer for the bucket.

NextSequence returns an autoincrementing integer for the bucket .


func (b Bucket) Put(k [][]byte, v []byte) error {
	bb, err := b.CreateBucketIfNotExists(k[:len(k)-1])
	if err != nil {
		return errorsp.WithStacksAndMessage(err, "CreateBucketIfNotExists %q failed", string(bytes.Join(k[:len(k)-1], []byte(" "))))
	}
	return errorsp.WithStacks(bb.Bucket.Put(k[len(k)-1], v))
}

func ( b Bucket ) Put ( k [ ] [ ] byte , v [ ] byte ) error { bb , err := b . CreateBucketIfNotExists ( k [ : len ( k ) - 1 ] ) if err != nil { return errorsp . WithStacksAndMessage ( err , " " , string ( bytes . Join ( k [ : len ( k ) - 1 ] , [ ] byte ( " " ) ) ) ) } return errorsp . WithStacks ( bb . Bucket . Put ( k [ len ( k ) - 1 ] , v ) ) }

// Put sets the value for a key in the bucket. If the key exist then its
// previous value will be overwritten. Supplied value must remain valid
// for the life of the transaction. Returns an error if the bucket was
// created from a read-only transaction, if the key is blank, if the key
// is too large, or if the value is too large.

Put sets the value for a key in the bucket . If the key exist then its previous value will be overwritten . Supplied value must remain valid for the life of the transaction . Returns an error if the bucket was created from a read - only transaction if the key is blank if the key is too large or if the value is too large .


func (b Bucket) PutGob(k [][]byte, v interface{}) error {
	var bs bytesp.Slice
	if err := gob.NewEncoder(&bs).Encode(&v); err != nil {
		return errorsp.WithStacksAndMessage(err, "encoding %+v failed", v)
	}
	return b.Put(k, bs)
}

func ( b Bucket ) PutGob ( k [ ] [ ] byte , v interface { } ) error { var bs bytesp . Slice if err := gob . NewEncoder ( & bs ) . Encode ( & v ) ; err != nil { return errorsp . WithStacksAndMessage ( err , " " , v ) } return b . Put ( k , bs ) }

// PutGob serialize v using gob and put it into the key.

PutGob serialize v using gob and put it into the key .


func (m *MongoDb) Drop() error {
	err := m.db.DropDatabase()
	if err != nil {
		return e.New(err)
	}
	m.db = m.session.DB(m.dbname)
	m.c = m.db.C(m.collection)
	return nil
}

func ( m * MongoDb ) Drop ( ) error { err := m . db . DropDatabase ( ) if err != nil { return e . New ( err ) } m . db = m . session . DB ( m . dbname ) m . c = m . db . C ( m . collection ) return nil }


func (handler *NullHandler) HandleError(err error) error {
	os.Stderr.WriteString(fmt.Sprintf("%s %s\n", time.Now(), err.Error()))
	return nil
}

func ( handler * NullHandler ) HandleError ( err error ) error { os . Stderr . WriteString ( fmt . Sprintf ( " \n " , time . Now ( ) , err . Error ( ) ) ) return nil }

// HandleError prints provided error to stderr.

HandleError prints provided error to stderr .


func (handler *WriteHandler) Handle(record *Record) error {
	_, err := handler.Writer.Write([]byte(handler.Formatter.Format(record) + "\n"))
	return err
}

func ( handler * WriteHandler ) Handle ( record * Record ) error { _ , err := handler . Writer . Write ( [ ] byte ( handler . Formatter . Format ( record ) + " \n " ) ) return err }

// Handle writes all provided log records to writer provided during creation.

Handle writes all provided log records to writer provided during creation .


func (handler *MemoryHandler) Handle(record *Record) error {
	handler.lock.Lock()
	handler.Messages = append(handler.Messages, handler.Formatter.Format(record))
	handler.lock.Unlock()
	return nil
}

func ( handler * MemoryHandler ) Handle ( record * Record ) error { handler . lock . Lock ( ) handler . Messages = append ( handler . Messages , handler . Formatter . Format ( record ) ) handler . lock . Unlock ( ) return nil }

// Handle appends message to Messages array.

Handle appends message to Messages array .


func WaitPeerListening(network, address string, timeout time.Duration) bool {
	return WaitFunc(100*time.Millisecond, timeout, func() bool {
		c, err := net.Dial(network, address)
		if err == nil {
			c.Close()
			return true
		}

		return false
	})
}

func WaitPeerListening ( network , address string , timeout time . Duration ) bool { return WaitFunc ( 100 * time . Millisecond , timeout , func ( ) bool { c , err := net . Dial ( network , address ) if err == nil { c . Close ( ) return true } return false } ) }

// WaitPeerListening wait for specified peer be ready for new connections.

WaitPeerListening wait for specified peer be ready for new connections .


func NewEvent(name string, body interface{}) Event {
	return Event{
		name:        name,
		body:        body,
		occuredTime: time.Now(),
	}
}

func NewEvent ( name string , body interface { } ) Event { return Event { name : name , body : body , occuredTime : time . Now ( ) , } }


func (b *Bus) Subscribe(h Handler) bool {
	b.mu.Lock()
	defer b.mu.Unlock()

	for _, v := range b.handlers {
		if v == h {
			return false
		}
	}

	b.handlers = append(b.handlers, h)
	return true
}

func ( b * Bus ) Subscribe ( h Handler ) bool { b . mu . Lock ( ) defer b . mu . Unlock ( ) for _ , v := range b . handlers { if v == h { return false } } b . handlers = append ( b . handlers , h ) return true }

// Subscribe to events.
// It will return true if successfully subscribed, means the handler haven't subscribed before.

Subscribe to events . It will return true if successfully subscribed means the handler haven t subscribed before .


func (b *Bus) Unsubscribe(h Handler) bool {
	b.mu.Lock()
	defer b.mu.Unlock()

	for i, v := range b.handlers {
		if v == h {
			b.handlers = append(b.handlers[:i], b.handlers[i+1:]...)
			return true
		}
	}

	return false
}

func ( b * Bus ) Unsubscribe ( h Handler ) bool { b . mu . Lock ( ) defer b . mu . Unlock ( ) for i , v := range b . handlers { if v == h { b . handlers = append ( b . handlers [ : i ] , b . handlers [ i + 1 : ] ... ) return true } } return false }

// Unsubscribe handler from the bus.
// It will return false if the handler not subscribed.

Unsubscribe handler from the bus . It will return false if the handler not subscribed .


func (b *Bus) Publish(eventName string, eventBody interface{}) {
	e := NewEvent(eventName, eventBody)

	b.mu.RLock()
	defer b.mu.RUnlock()
	for _, h := range b.handlers {
		h.Handle(e)
	}
}

func ( b * Bus ) Publish ( eventName string , eventBody interface { } ) { e := NewEvent ( eventName , eventBody ) b . mu . RLock ( ) defer b . mu . RUnlock ( ) for _ , h := range b . handlers { h . Handle ( e ) } }


func HandleOnly(h Handler, names ...string) Handler {
	return HandlerFunc(func(e Event) {
		for _, name := range names {
			if e.Name() == name {
				h.Handle(e)
				break
			}
		}
	})
}

func HandleOnly ( h Handler , names ... string ) Handler { return HandlerFunc ( func ( e Event ) { for _ , name := range names { if e . Name ( ) == name { h . Handle ( e ) break } } } ) }


func ContextWithPublisher(ctx context.Context, pub Publisher) context.Context {
	return context.WithValue(ctx, KeyPublisher, pub)
}

func ContextWithPublisher ( ctx context . Context , pub Publisher ) context . Context { return context . WithValue ( ctx , KeyPublisher , pub ) }

// ContextWithPublisher constructs new context with bus.

ContextWithPublisher constructs new context with bus .


func PublisherContext(ctx context.Context) Publisher {
	pub, ok := ctx.Value(KeyPublisher).(Publisher)
	if !ok {
		return nil
	}

	return pub
}

func PublisherContext ( ctx context . Context ) Publisher { pub , ok := ctx . Value ( KeyPublisher ) . ( Publisher ) if ! ok { return nil } return pub }

// PublisherContext return the publisher.


func PublishNamedEvent(pub Publisher, eventBody interface{}) {
	name := reflect.TypeOf(eventBody).Name()
	pub.Publish(name, eventBody)
}

func PublishNamedEvent ( pub Publisher , eventBody interface { } ) { name := reflect . TypeOf ( eventBody ) . Name ( ) pub . Publish ( name , eventBody ) }

// PublishNamedEvent which name infered from eventBody interface name.

PublishNamedEvent which name infered from eventBody interface name .


func PublishEventContext(ctx context.Context, eventName string, eventBody interface{}) {
	pub := PublisherContext(ctx)
	if pub == nil {
		return
	}

	pub.Publish(eventName, eventBody)
}

func PublishEventContext ( ctx context . Context , eventName string , eventBody interface { } ) { pub := PublisherContext ( ctx ) if pub == nil { return } pub . Publish ( eventName , eventBody ) }

// PublishEventContext publish event for given ctx.

PublishEventContext publish event for given ctx .


func PublishNamedEventContext(ctx context.Context, eventBody interface{}) {
	name := reflect.TypeOf(eventBody).Name()
	PublishEventContext(ctx, name, eventBody)
}

func PublishNamedEventContext ( ctx context . Context , eventBody interface { } ) { name := reflect . TypeOf ( eventBody ) . Name ( ) PublishEventContext ( ctx , name , eventBody ) }

// PublishNamedEventContext publish named event for given ctx. The name infered from eventBody interface name.

PublishNamedEventContext publish named event for given ctx . The name infered from eventBody interface name .


func (level Level) String() string {
	switch level {
	case EMERGENCY:
		return "EMERGENCY"
	case ALERT:
		return "ALERT"
	case CRITICAL:
		return "CRITICAL"
	case ERROR:
		return "ERROR"
	case WARNING:
		return "WARNING"
	case NOTICE:
		return "NOTICE"
	case INFO:
		return "INFO"
	default:
		return "DEBUG"
	}
}

func ( level Level ) String ( ) string { switch level { case EMERGENCY : return " " case ALERT : return " " case CRITICAL : return " " case ERROR : return " " case WARNING : return " " case NOTICE : return " " case INFO : return " " default : return " " } }

// String returns stirng representation of log level.

String returns stirng representation of log level .


func (level *Level) UnmarshalJSON(data []byte) error {
	switch string(bytes.ToUpper(data)) {
	case `"EMERGENCY"`, "0":
		*level = EMERGENCY
	case `"ALERT"`, "1":
		*level = ALERT
	case `"CRITICAL"`, "2":
		*level = CRITICAL
	case `"ERROR"`, "3":
		*level = ERROR
	case `"WARNING"`, "4":
		*level = WARNING
	case `"NOTICE"`, "5":
		*level = NOTICE
	case `"INFO"`, "6":
		*level = INFO
	case `"DEBUG"`, "7":
		*level = DEBUG
	default:
		return ErrInvalidLevel
	}
	return nil
}

func ( level * Level ) UnmarshalJSON ( data [ ] byte ) error { switch string ( bytes . ToUpper ( data ) ) { case `"EMERGENCY"` , " " : * level = EMERGENCY case `"ALERT"` , " " : * level = ALERT case `"CRITICAL"` , " " : * level = CRITICAL case `"ERROR"` , " " : * level = ERROR case `"WARNING"` , " " : * level = WARNING case `"NOTICE"` , " " : * level = NOTICE case `"INFO"` , " " : * level = INFO case `"DEBUG"` , " " : * level = DEBUG default : return ErrInvalidLevel } return nil }

// UnmarshalJSON implements json.Unamrshaler interface.

UnmarshalJSON implements json . Unamrshaler interface .