func SafeCreateSSH(client SFTPClient, name ...string) (file *sftp.File, err error) {
	ssh := sshClientBucket{
		client: client,
	}
	fpath := path.Join(name...)
	basepath := filepath.Dir(fpath)

	if err = ssh.remoteSafeMkdirAll(basepath); err == nil {
		file, err = client.Create(fpath)
	}
	return
}

func SafeCreateSSH ( client SFTPClient , name ... string ) ( file * sftp . File , err error ) { ssh := sshClientBucket { client : client , } fpath := path . Join ( name ... ) basepath := filepath . Dir ( fpath ) if err = ssh . remoteSafeMkdirAll ( basepath ) ; err == nil { file , err = client . Create ( fpath ) } return }

// SafeCreateSSH creates a file, creating parent directories if needed on a remote machine via an ssh client

SafeCreateSSH creates a file creating parent directories if needed on a remote machine via an ssh client


func SafeCreate(name ...string) (file *os.File, err error) {
	p, e := ensurePath(path.Join(name...))

	if e != nil {
		return nil, e
	}
	return os.Create(p)
}

func SafeCreate ( name ... string ) ( file * os . File , err error ) { p , e := ensurePath ( path . Join ( name ... ) ) if e != nil { return nil , e } return os . Create ( p ) }

// SafeCreate creates a file, creating parent directories if needed

SafeCreate creates a file creating parent directories if needed


func HMAC(password string) func(ctx *neptulon.ReqCtx) error {
	pass := []byte(password)

	return func(ctx *neptulon.ReqCtx) error {
		// if user is already authenticated
		if _, ok := ctx.Conn.Session.GetOk("userid"); ok {
			return ctx.Next()
		}

		// if user is not authenticated.. check the JWT token
		var t token
		if err := ctx.Params(&t); err != nil {
			ctx.Conn.Close()
			return err
		}

		jt, err := jwt.Parse(t.Token, func(token *jwt.Token) (interface{}, error) {
			if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
				return nil, fmt.Errorf("mw: jwt: unexpected signing method: %v", token.Header["alg"])
			}
			return pass, nil
		})

		if err != nil || !jt.Valid {
			ctx.Conn.Close()
			return fmt.Errorf("mw: jwt: invalid JWT authentication attempt: %v: %v: %v", err, ctx.Conn.RemoteAddr(), t.Token)
		}

		userID := jt.Claims["userid"].(string)
		ctx.Conn.Session.Set("userid", userID)
		log.Printf("mw: jwt: client authenticated, user: %v, conn: %v, ip: %v", userID, ctx.Conn.ID, ctx.Conn.RemoteAddr())
		return ctx.Next()
	}
}

// HMAC is JSON Web Token authentication using HMAC.
// If successful, token context will be store with the key "userid" in session.
// If unsuccessful, connection will be closed right away.

HMAC is JSON Web Token authentication using HMAC . If successful token context will be store with the key userid in session . If unsuccessful connection will be closed right away .


func Scaffold(d Dispatcher, platform Platform) Handler {
	router := New(d)
	platform.Routes(router)
	return router.dispatcher
}

func Scaffold ( d Dispatcher , platform Platform ) Handler { router := New ( d ) platform . Routes ( router ) return router . dispatcher }

// Scaffold creates a router and passes it to a platorm


func (r *Router) Route(pattern string) *Router {
	c := r.pattern(pattern)
	return r.clone(c)
}

func ( r * Router ) Route ( pattern string ) * Router { c := r . pattern ( pattern ) return r . clone ( c ) }

// Route returns the subrouter for a pettern


func (r *Router) Group(pattern string, group func(*Router)) {
	c := r.pattern(pattern)
	group(r.clone(c))
}

func ( r * Router ) Group ( pattern string , group func ( * Router ) ) { c := r . pattern ( pattern ) group ( r . clone ( c ) ) }

// Group calls the specified function with the subrouter for the given pattern


func (r *Router) Platform(pattern string, platform Platform) {
	c := r.pattern(pattern)
	platform.Routes(r.clone(c))
}

func ( r * Router ) Platform ( pattern string , platform Platform ) { c := r . pattern ( pattern ) platform . Routes ( r . clone ( c ) ) }

// Platform routes the platform object to the given pattern


func (r *Router) Handle(pattern string, handlers ...interface{}) *Router {
	c := r.pattern(pattern)
	clone := r.clone(c)
	clone.handle(handlers)
	return clone
}

func ( r * Router ) Handle ( pattern string , handlers ... interface { } ) * Router { c := r . pattern ( pattern ) clone := r . clone ( c ) clone . handle ( handlers ) return clone }

// Handle all methods with a given pattern


func (r *Router) Options(pattern string, handlers ...interface{}) *Router {
	c := r.pattern(pattern)
	c.Method = "OPTIONS"
	clone := r.clone(c)
	clone.handle(handlers)
	return clone
}

func ( r * Router ) Options ( pattern string , handlers ... interface { } ) * Router { c := r . pattern ( pattern ) c . Method = " " clone := r . clone ( c ) clone . handle ( handlers ) return clone }

// Options handles OPTIONS methods with a given pattern


func (r *Router) Use(middleware ...interface{}) {
	r.dispatcher.Middleware(r.route, r.buildMiddlewares(middleware)...)
}

func ( r * Router ) Use ( middleware ... interface { } ) { r . dispatcher . Middleware ( r . route , r . buildMiddlewares ( middleware ) ... ) }


func (r *Router) NotFound(i interface{}) {
	handler := r.buildHandler(i)
	r.dispatcher.NotFoundHandler(r.route, handler)
}

func ( r * Router ) NotFound ( i interface { } ) { handler := r . buildHandler ( i ) r . dispatcher . NotFoundHandler ( r . route , handler ) }

// NotFound specifys a not found handler for a route


func (r *Router) AddHandlerBuilder(builder func(interface{}) (Handler, error)) {
	r.builders = append(r.builders, &builder)
}

func ( r * Router ) AddHandlerBuilder ( builder func ( interface { } ) ( Handler , error ) ) { r . builders = append ( r . builders , & builder ) }

// AddHandlerBuilder adds a builder to construct handlers


func (e ErrorHandlerFunc) ServeErrorPage(ctx context.Context, w http.ResponseWriter, r *http.Request, status int, err error) {
	e(ctx, w, r, status, err)
}

func ( e ErrorHandlerFunc ) ServeErrorPage ( ctx context . Context , w http . ResponseWriter , r * http . Request , status int , err error ) { e ( ctx , w , r , status , err ) }

// ServeErrorPage Implements ErrorHandler.ServeErrorPage

ServeErrorPage Implements ErrorHandler . ServeErrorPage


func GetErrorHandler(ctx context.Context, status int) ErrorHandler {
	key := fmt.Sprintf("error_handler_%d", status)
	if h, ok := ctx.Value(key).(ErrorHandler); ok {
		return h
	}

	key = fmt.Sprintf("error_handler_%d", AllStatusCodes)
	if h, ok := ctx.Value(key).(ErrorHandler); ok {
		return h
	}

	return DefaultErrorHandler
}

func GetErrorHandler ( ctx context . Context , status int ) ErrorHandler { key := fmt . Sprintf ( " " , status ) if h , ok := ctx . Value ( key ) . ( ErrorHandler ) ; ok { return h } key = fmt . Sprintf ( " " , AllStatusCodes ) if h , ok := ctx . Value ( key ) . ( ErrorHandler ) ; ok { return h } return DefaultErrorHandler }

// GetErrorHandler gets the error handler from the context or returns the default


func SetErrorHandler(status int, handler ErrorHandler) scaffold.Middleware {
	return scaffold.Middleware(func(next scaffold.Handler) scaffold.Handler {
		return scaffold.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) {
			key := fmt.Sprintf("error_handler_%d", status)
			ctx = context.WithValue(ctx, key, handler)

			next.CtxServeHTTP(ctx, w, r)
		})
	})
}

func SetErrorHandler ( status int , handler ErrorHandler ) scaffold . Middleware { return scaffold . Middleware ( func ( next scaffold . Handler ) scaffold . Handler { return scaffold . HandlerFunc ( func ( ctx context . Context , w http . ResponseWriter , r * http . Request ) { key := fmt . Sprintf ( " " , status ) ctx = context . WithValue ( ctx , key , handler ) next . CtxServeHTTP ( ctx , w , r ) } ) } ) }

// SetErrorHandler returns Middleware that can be used to set the error handler


func SetErrorHandlerFunc(status int, handler func(ctx context.Context, w http.ResponseWriter, r *http.Request, status int, err error)) scaffold.Middleware {
	return SetErrorHandler(status, ErrorHandlerFunc(handler))
}

func SetErrorHandlerFunc ( status int , handler func ( ctx context . Context , w http . ResponseWriter , r * http . Request , status int , err error ) ) scaffold . Middleware { return SetErrorHandler ( status , ErrorHandlerFunc ( handler ) ) }

// SetErrorHandlerFunc returns Middleware that can be used to set the error handler


func Echo(ctx *neptulon.ReqCtx) error {
	// unmarshall incoming message into response directly
	if err := ctx.Params(&ctx.Res); err != nil {
		return err
	}
	return ctx.Next()
}

// Echo sends incoming messages back as is.

Echo sends incoming messages back as is .


func (c *ConfigArg) UnmarshalBinary(b []byte) error {
	// Must contain minimum length for argument
	if len(b) < configArgLen {
		return io.ErrUnexpectedEOF
	}

	// Retrieve basic data
	c.BufferCount = binary.BigEndian.Uint16(b[0:2])
	c.FirmwareVersion = binary.BigEndian.Uint16(b[2:4])
	c.SectorCount = b[4]

	// Version is most significant 4 bits
	c.Version = uint8(b[5] >> 4)

	// Command is least significant 4 bits of byte 5
	c.Command = ConfigCommand(b[5] & 0x0f)

	// StringLength cannot be larger than the number of bytes remaining
	// in the buffer
	c.StringLength = binary.BigEndian.Uint16(b[6:8])
	if len(b[8:]) < int(c.StringLength) {
		return io.ErrUnexpectedEOF
	}
	// StringLength must not be greater than 1024, per AoEr11, Section 3.2.
	if c.StringLength > 1024 {
		return ErrorBadArgumentParameter
	}

	// Copy config string for use
	d := make([]byte, c.StringLength)
	copy(d, b[8:])
	c.String = d

	return nil
}

// UnmarshalBinary unmarshals a byte slice into a ConfigArg.
//
// If the byte slice does not contain enough data to form a valid ConfigArg,
// or config string length is greater than the number of remaining bytes in b,
// io.ErrUnexpectedEOF is returned.
//
// If config string length is greater than 1024, ErrorBadArgumentParameter is
// returned.

UnmarshalBinary unmarshals a byte slice into a ConfigArg . If the byte slice does not contain enough data to form a valid ConfigArg or config string length is greater than the number of remaining bytes in b io . ErrUnexpectedEOF is returned . If config string length is greater than 1024 ErrorBadArgumentParameter is returned .


func ataIdentify(r *ATAArg, rs io.ReadSeeker) (*ATAArg, error) {
	// Only ATA device identify allowed here
	if r.CmdStatus != ATACmdStatusIdentify {
		return nil, errATAAbort
	}

	// Request must be for 1 sector (512 bytes)
	if r.SectorCount != 1 {
		return nil, errATAAbort
	}

	// If rs is an Identifier, request its identity directly
	ident, ok := rs.(Identifier)
	if !ok {
		// Currently no generic Identify implementation, as is done in
		// vblade.
		// TODO(mdlayher): add generic Identify implementation
		return nil, ErrNotImplemented
	}

	// Retrieve device identity information
	id, err := ident.Identify()
	if err != nil {
		return nil, err
	}

	return &ATAArg{
		CmdStatus: ATACmdStatusReadyStatus,
		Data:      id[:],
	}, nil
}

// ataIdentify performs an ATA identify request on rs using the argument
// values in r.

ataIdentify performs an ATA identify request on rs using the argument values in r .


func ataRead(r *ATAArg, rs io.ReadSeeker) (*ATAArg, error) {
	// Only ATA reads allowed here
	if r.CmdStatus != ATACmdStatusRead28Bit && r.CmdStatus != ATACmdStatusRead48Bit {
		return nil, errATAAbort
	}

	// Read must not be flagged as a write
	if r.FlagWrite {
		return nil, errATAAbort
	}

	// Convert LBA to byte offset and seek to correct location
	offset := calculateLBA(r.LBA, r.FlagLBA48Extended) * sectorSize
	if _, err := rs.Seek(offset, os.SEEK_SET); err != nil {
		return nil, err
	}

	// Allocate buffer and read exact (sector count * sector size) bytes from
	// stream
	//
	// TODO(mdlayher): use r.Data instead of allocating?
	b := make([]byte, int(r.SectorCount)*sectorSize)
	n, err := rs.Read(b)
	if err != nil {
		return nil, err
	}

	// Verify sector count
	if sectors := n / sectorSize; sectors != int(r.SectorCount) {
		return nil, errATAAbort
	}

	return &ATAArg{
		CmdStatus: ATACmdStatusReadyStatus,
		Data:      b,
	}, nil
}

// ataRead performs an ATA 28-bit or 48-bit read request on rs using the
// argument values in r.

ataRead performs an ATA 28 - bit or 48 - bit read request on rs using the argument values in r .


func ataWrite(r *ATAArg, rs io.ReadSeeker) (*ATAArg, error) {
	// Only ATA writes allowed here
	if r.CmdStatus != ATACmdStatusWrite28Bit && r.CmdStatus != ATACmdStatusWrite48Bit {
		return nil, errATAAbort
	}

	// Write must be flagged as a write
	if !r.FlagWrite {
		return nil, errATAAbort
	}

	// Verify that request data and sector count match up
	if sectors := len(r.Data) / sectorSize; sectors != int(r.SectorCount) {
		return nil, errATAAbort
	}

	// Determine if io.ReadSeeker is also an io.Writer, and if a write is
	// requested
	rws, ok := rs.(io.ReadWriteSeeker)
	if !ok {
		// A write was requested, but the io.ReadSeeker is not an io.Writer
		return nil, errATAAbort
	}

	// TODO(mdlayher): implement asynchronous writes

	// Convert LBA to byte offset and seek to correct location
	offset := calculateLBA(r.LBA, r.FlagLBA48Extended) * sectorSize
	if _, err := rs.Seek(offset, os.SEEK_SET); err != nil {
		return nil, err
	}

	// Write data to stream
	n, err := rws.Write(r.Data)
	if err != nil {
		return nil, err
	}

	// Verify full sectors written to disk using sector count
	if sectors := n / sectorSize; sectors != int(r.SectorCount) {
		return nil, errATAAbort
	}

	return &ATAArg{
		CmdStatus: ATACmdStatusReadyStatus,
	}, nil
}

// ataWrite performs an ATA 28-bit or 48-bit write request on rs using the
// argument values in r.

ataWrite performs an ATA 28 - bit or 48 - bit write request on rs using the argument values in r .


func calculateLBA(rlba [6]uint8, is48Bit bool) int64 {
	// Pad two bytes at the end to parse as uint64
	b := []byte{
		rlba[0],
		rlba[1],
		rlba[2],
		rlba[3],
		rlba[4],
		rlba[5],
		0,
		0,
	}
	lba := binary.LittleEndian.Uint64(b)

	// Mask off high bits to limit size to either 48 bit or 28 bit,
	// depending on is48Bit's value.
	if is48Bit {
		// 48-bit
		lba &= 0x0000ffffffffffff
	} else {
		// 28-bit
		lba &= 0x0fffffff
	}

	return int64(lba)
}

// calculateLBA calculates a logical block address from the LBA array
// and 48-bit flags from an ATAArg.

calculateLBA calculates a logical block address from the LBA array and 48 - bit flags from an ATAArg .


func (r *ReserveReleaseArg) MarshalBinary() ([]byte, error) {
	// Must indicate correct number of hardware addresses
	if int(r.NMACs) != len(r.MACs) {
		return nil, ErrorBadArgumentParameter
	}

	// Allocate byte slice for argument and hardware addresses
	b := make([]byte, reserveReleaseArgLen+(r.NMACs*6))

	b[0] = uint8(r.Command)
	b[1] = uint8(r.NMACs)

	// Copy each hardware address into byte slice, after verifying exactly
	// 6 bytes in length
	n := 2
	for _, m := range r.MACs {
		if len(m) != 6 {
			return nil, ErrorBadArgumentParameter
		}

		copy(b[n:n+6], m)
		n += 6
	}

	return b, nil
}

// MarshalBinary allocates a byte slice containing the data from a
// ReserveReleaseArg.
//
// If r.NMACs does not indicate the actual length of r.MACs, or one or more
// hardware addresses are not exactly 6 bytes in length,
// ErrorBadArgumentParameter is returned.

MarshalBinary allocates a byte slice containing the data from a ReserveReleaseArg . If r . NMACs does not indicate the actual length of r . MACs or one or more hardware addresses are not exactly 6 bytes in length ErrorBadArgumentParameter is returned .


func (r *ReserveReleaseArg) UnmarshalBinary(b []byte) error {
	// Must contain minimum length for argument
	if len(b) < reserveReleaseArgLen {
		return io.ErrUnexpectedEOF
	}

	r.Command = ReserveReleaseCommand(b[0])
	r.NMACs = b[1]

	// Must have exact number of bytes for hardware addresses with
	// this count
	if len(b[2:]) != (6 * int(r.NMACs)) {
		return io.ErrUnexpectedEOF
	}

	// Copy each hardware address into slice
	r.MACs = make([]net.HardwareAddr, r.NMACs)
	for i := 0; i < int(r.NMACs); i++ {
		m := make(net.HardwareAddr, 6)
		copy(m, b[2+(i*6):2+(i*6)+6])
		r.MACs[i] = m
	}

	return nil
}

// UnmarshalBinary unmarshals a byte slice into a ReserveReleaseArg.
//
// If the byte slice does not contain enough bytes to form a valid
// ReserveReleaseArg, or a hardware address is malformed, io.ErrUnexpectedEOF
// is returned.

UnmarshalBinary unmarshals a byte slice into a ReserveReleaseArg . If the byte slice does not contain enough bytes to form a valid ReserveReleaseArg or a hardware address is malformed io . ErrUnexpectedEOF is returned .


func (a *ATAArg) MarshalBinary() ([]byte, error) {
	// Allocate correct number of bytes for argument and data
	b := make([]byte, ataArgLen+len(a.Data))

	// Add bit flags at appropriate positions
	//
	// 0101 0011
	//  | |   ||
	//  | |   |+-- write flag
	//  | |   +--- asynchronous flag
	//  | +------- device/head register flag
	//  +--------- extended LBA48 flag
	var flags uint8
	if a.FlagLBA48Extended {
		flags |= (1 << 6)
	}
	if a.FlagATADeviceHeadRegister {
		flags |= (1 << 4)
	}
	if a.FlagAsynchronous {
		flags |= (1 << 1)
	}
	if a.FlagWrite {
		flags |= 1
	}
	b[0] = flags

	// Set other ATA data
	b[1] = a.ErrFeature
	b[2] = a.SectorCount
	b[3] = uint8(a.CmdStatus)
	b[4] = a.LBA[0]
	b[5] = a.LBA[1]
	b[6] = a.LBA[2]
	b[7] = a.LBA[3]
	b[8] = a.LBA[4]
	b[9] = a.LBA[5]

	// 2 bytes reserved space

	// Copy raw data after argument header
	copy(b[12:], a.Data)

	return b, nil
}

//  | +------- device/head register flag

// MarshalBinary allocates a byte slice containing the data from an ATAArg.
//
// MarshalBinary never returns an error.

MarshalBinary allocates a byte slice containing the data from an ATAArg . MarshalBinary never returns an error .


func New(db *sql.DB, tables Tables) Fixture {
	fixture := Fixture{db: db, Tables: tables}
	return fixture
}

func New ( db * sql . DB , tables Tables ) Fixture { fixture := Fixture { db : db , Tables : tables } return fixture }

// New fixture instance that will work with the database


func FromYAML(db *sql.DB, yamlIn []byte) (Fixture, error) {
	var tables Tables
	err := yaml.Unmarshal(yamlIn, &tables)
	return New(db, tables), err
}

func FromYAML ( db * sql . DB , yamlIn [ ] byte ) ( Fixture , error ) { var tables Tables err := yaml . Unmarshal ( yamlIn , & tables ) return New ( db , tables ) , err }

// FromYAML allows a fixture to be created from yaml input


func FromJSON(db *sql.DB, jsonIn []byte) (Fixture, error) {
	var tables Tables
	err := json.Unmarshal(jsonIn, &tables)
	return New(db, tables), err
}

func FromJSON ( db * sql . DB , jsonIn [ ] byte ) ( Fixture , error ) { var tables Tables err := json . Unmarshal ( jsonIn , & tables ) return New ( db , tables ) , err }

// FromJSON allows a fixture to be created from json input


func (d *Directive) MarshalBinary() ([]byte, error) {
	// Ethernet hardware addresses must be 6 bytes in length
	if len(d.MAC) != 6 {
		return nil, ErrorBadArgumentParameter
	}

	// Allocate fixed-length byte structure
	b := make([]byte, directiveLen)

	// 1 byte reserved

	// Add command copy hardware address into Directive
	b[1] = uint8(d.Command)
	copy(b[2:], d.MAC)

	return b, nil
}

// MarshalBinary allocates a byte slice containing the data from a Directive.
//
// If d.MAC is not 6 bytes in length, ErrorBadArgumentParameter is returned.

MarshalBinary allocates a byte slice containing the data from a Directive . If d . MAC is not 6 bytes in length ErrorBadArgumentParameter is returned .


func (m *MACMaskArg) MarshalBinary() ([]byte, error) {
	// Must indicate correct number of directives
	if int(m.DirCount) != len(m.Directives) {
		return nil, ErrorBadArgumentParameter
	}

	// Allocate byte slice for argument and all directives
	b := make([]byte, macMaskArgLen+(directiveLen*m.DirCount))

	// 1 byte reserved

	b[1] = uint8(m.Command)
	b[2] = uint8(m.Error)
	b[3] = m.DirCount

	// Marshal each directive into binary and copy into byte slice
	// after argument
	n := 4
	for _, d := range m.Directives {
		db, err := d.MarshalBinary()
		if err != nil {
			return nil, err
		}

		copy(b[n:n+directiveLen], db)
		n += directiveLen
	}

	return b, nil
}

// MarshalBinary allocates a byte slice containing the data from a MACMaskArg.
//
// If m.DirCount does not indicate the actual length of m.Directives, or
// a Directive is malformed, ErrorBadArgumentParameter is returned.

MarshalBinary allocates a byte slice containing the data from a MACMaskArg . If m . DirCount does not indicate the actual length of m . Directives or a Directive is malformed ErrorBadArgumentParameter is returned .


func NewSendToLogger(logger *golog.Logger) LogBackend {
	if logger == nil {
		return &SendToLogger{
			Logger: golog.New(os.Stderr, "", golog.LstdFlags),
		}
	}
	return &SendToLogger{
		Logger: logger,
	}
}

func NewSendToLogger ( logger * golog . Logger ) LogBackend { if logger == nil { return & SendToLogger { Logger : golog . New ( os . Stderr , " " , golog . LstdFlags ) , } } return & SendToLogger { Logger : logger , } }

// NewSendToLogger creates a logger from a go log.

NewSendToLogger creates a logger from a go log .


func NewMulti(vals ...interface{}) LogBackend {
	if len(vals)%2 != 0 {
		Fail(e.New("parameters must be in pair of LogBackend and Formatter"))
		return nil
	}
	l := len(vals) / 2
	mp := make([]LogBackend, 0, l)
	for i := 0; i < len(vals); i += 2 {
		bak, ok := vals[i].(LogBackend)
		if !ok {
			Fail(e.New("not a LogBackend"))
			return nil
		}
		f, ok := vals[i+1].(Formatter)
		if !ok {
			Fail(e.New("not a Formatter"))
			return nil
		}
		bak.F(f)
		mp = append(mp, bak)
	}
	return &MultiLog{
		mp: mp,
	}
}

func NewMulti ( vals ... interface { } ) LogBackend { if len ( vals ) % 2 != 0 { Fail ( e . New ( " " ) ) return nil } l := len ( vals ) / 2 mp := make ( [ ] LogBackend , 0 , l ) for i := 0 ; i < len ( vals ) ; i += 2 { bak , ok := vals [ i ] . ( LogBackend ) if ! ok { Fail ( e . New ( " " ) ) return nil } f , ok := vals [ i + 1 ] . ( Formatter ) if ! ok { Fail ( e . New ( " " ) ) return nil } bak . F ( f ) mp = append ( mp , bak ) } return & MultiLog { mp : mp , } }


func (mp *MultiLog) OuterLog(level Level, tags ...string) io.Writer {
	if mp.chouter != nil {
		return &outer{
			ch:  mp.chouter,
			buf: make([]byte, 0),
		}
	}
	mp.chclose = make(chan chan struct{})
	mp.chouter = make(chan []byte)
	if len(mp.mp) < 2 {
		return nil
	}
	f := mp.mp[0].GetF()
	logger := f.NewEntry(mp).Tag("outer").EntryLevel(level)
	go func() {
		for {
			select {
			case buf := <-mp.chouter:
				logger.Tag(tags...).Println(string(buf))
			case ch := <-mp.chclose:
				ch <- struct{}{}
				return
			}
		}
	}()
	return &outer{
		ch:  mp.chouter,
		buf: make([]byte, 0),
	}
}

func ( mp * MultiLog ) OuterLog ( level Level , tags ... string ) io . Writer { if mp . chouter != nil { return & outer { ch : mp . chouter , buf : make ( [ ] byte , 0 ) , } } mp . chclose = make ( chan chan struct { } ) mp . chouter = make ( chan [ ] byte ) if len ( mp . mp ) < 2 { return nil } f := mp . mp [ 0 ] . GetF ( ) logger := f . NewEntry ( mp ) . Tag ( " " ) . EntryLevel ( level ) go func ( ) { for { select { case buf := <- mp . chouter : logger . Tag ( tags ... ) . Println ( string ( buf ) ) case ch := <- mp . chclose : ch <- struct { } { } return } } } ( ) return & outer { ch : mp . chouter , buf : make ( [ ] byte , 0 ) , } }

// outerLog is like outers outerLogs but the nem entry is
// created from the first BackLog in the list.

outerLog is like outers outerLogs but the nem entry is created from the first BackLog in the list .


func (s *RunConfig) PublishPort(hostPort, containerPort uint16) {
	s.Options = append(s.Options, "-p",
		fmt.Sprintf("%d:%d", hostPort, containerPort))
}

func ( s * RunConfig ) PublishPort ( hostPort , containerPort uint16 ) { s . Options = append ( s . Options , " " , fmt . Sprintf ( " " , hostPort , containerPort ) ) }

// PublishPort publish a container's port to the host.

PublishPort publish a container s port to the host .


func (s *RunConfig) Name(name string) {
	s.Options = append(s.Options, "--name", name)
}

func ( s * RunConfig ) Name ( name string ) { s . Options = append ( s . Options , " " , name ) }


func (s *RunConfig) AddArgs(args ...string) {
	s.Args = append(s.Args, args...)
}

func ( s * RunConfig ) AddArgs ( args ... string ) { s . Args = append ( s . Args , args ... ) }

// AddArgs appends arguments to Docker container.

AddArgs appends arguments to Docker container .


func NewCORSHandler() *CORSHandler {
	return &CORSHandler{
		PredicateOrigin: raiqub.TrueForAll,
		Headers: []string{
			"Origin", "X-Requested-With", "Content-Type",
			"Accept", "Authorization",
		},
		ExposedHeaders: make([]string, 0),
	}
}

func NewCORSHandler ( ) * CORSHandler { return & CORSHandler { PredicateOrigin : raiqub . TrueForAll , Headers : [ ] string { " " , " " , " " , " " , " " , } , ExposedHeaders : make ( [ ] string , 0 ) , } }

// NewCORSHandler creates a new CORSHandler with default values.

NewCORSHandler creates a new CORSHandler with default values .


func (s *CORSHandler) CreatePreflight(routes Routes) Routes {
	list := make(Routes, 0, len(routes))
	hList := make(map[string]*CORSPreflight, len(routes))
	for _, v := range routes {
		preflight, ok := hList[v.Path]
		if !ok {
			preflight = &CORSPreflight{
				*s,
				make([]string, 0, 1),
				v.MustAuth,
			}
			hList[v.Path] = preflight
		}

		preflight.Methods = append(preflight.Methods, v.Method)
		if v.MustAuth {
			preflight.UseCredentials = true
		}
	}

	for k, v := range hList {
		list = append(list, Route{
			Name:       "",
			Method:     DEFAULT_CORS_PREFLIGHT_METHOD,
			Path:       k,
			MustAuth:   v.UseCredentials,
			ActionFunc: v.ServeHTTP,
		})
	}
	return list
}

func ( s * CORSHandler ) CreatePreflight ( routes Routes ) Routes { list := make ( Routes , 0 , len ( routes ) ) hList := make ( map [ string ] * CORSPreflight , len ( routes ) ) for _ , v := range routes { preflight , ok := hList [ v . Path ] if ! ok { preflight = & CORSPreflight { * s , make ( [ ] string , 0 , 1 ) , v . MustAuth , } hList [ v . Path ] = preflight } preflight . Methods = append ( preflight . Methods , v . Method ) if v . MustAuth { preflight . UseCredentials = true } } for k , v := range hList { list = append ( list , Route { Name : " " , Method : DEFAULT_CORS_PREFLIGHT_METHOD , Path : k , MustAuth : v . UseCredentials , ActionFunc : v . ServeHTTP , } ) } return list }

// CreatePreflight creates HTTP routes that handles pre-flight requests.

CreatePreflight creates HTTP routes that handles pre - flight requests .


func (s *CORSPreflight) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	origin := HttpHeader_Origin().GetReader(r.Header)
	status := http.StatusBadRequest
	msg := ""
	defer func() {
		w.WriteHeader(status)
		w.Write([]byte(msg))
	}()

	if origin.Value != "" {
		if !s.PredicateOrigin(origin.Value) {
			status = http.StatusForbidden
			return
		}

		method := HttpHeader_AccessControlRequestMethod().
			GetReader(r.Header).Value
		header := strings.Split(
			HttpHeader_AccessControlRequestHeaders().
				GetReader(r.Header).Value, ", ")
		if len(header) == 1 && header[0] == "" {
			header = []string{}
		}

		if !raiqub.StringSlice(s.Methods).Exists(method) {
			msg = "Method not allowed"
			return
		}

		if len(s.Headers) == 0 {
			HttpHeader_AccessControlAllowHeaders().
				SetWriter(w.Header())
		} else {
			if len(header) > 0 &&
				!raiqub.StringSlice(s.Headers).ExistsAllIgnoreCase(header) {
				msg = "Header not allowed"
				return
			}
			HttpHeader_AccessControlAllowHeaders().
				SetValue(strings.Join(s.Headers, ", ")).
				SetWriter(w.Header())
		}

		HttpHeader_AccessControlAllowMethods().
			SetValue(strings.Join(s.Methods, ", ")).
			SetWriter(w.Header())
		HttpHeader_AccessControlAllowOrigin().
			SetValue(origin.Value).
			SetWriter(w.Header())
		HttpHeader_AccessControlAllowCredentials().
			SetValue(strconv.FormatBool(s.UseCredentials)).
			SetWriter(w.Header())
		// Optional
		HttpHeader_AccessControlMaxAge().
			SetValue(strconv.Itoa(int(DEFAULT_CORS_MAX_AGE))).
			SetWriter(w.Header())
		status = http.StatusOK
	} else {
		status = http.StatusNotFound
	}
}

// ServeHTTP handle a pre-flight request.

ServeHTTP handle a pre - flight request .


func (s *CORSMiddleware) Handle(next http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		origin := HttpHeader_Origin().GetReader(r.Header)
		if r.Method != DEFAULT_CORS_PREFLIGHT_METHOD && origin.Value != "" {
			if !s.PredicateOrigin(origin.Value) {
				return
			}

			HttpHeader_AccessControlAllowOrigin().
				SetValue(origin.Value).
				SetWriter(w.Header())
			HttpHeader_AccessControlAllowCredentials().
				SetValue(strconv.FormatBool(s.UseCredentials)).
				SetWriter(w.Header())
			if len(s.Headers) > 0 {
				HttpHeader_AccessControlAllowHeaders().
					SetValue(strings.Join(s.Headers, ", ")).
					SetWriter(w.Header())
			} else {
				HttpHeader_AccessControlAllowHeaders().
					SetWriter(w.Header())
			}
		}
		next.ServeHTTP(w, r)
	}

	return http.HandlerFunc(fn)
}

// Handle is a HTTP handler for CORS-able API.

Handle is a HTTP handler for CORS - able API .


func NewRandomSourceListSecure() RandomSourceList {
	return RandomSourceList{
		RandomSource{
			Reader: rand.Reader,
			Weight: DEFAULT_SYS_RAND_SIZE,
		},
		RandomSource{
			Reader: NewRandom(),
			Weight: DEFAULT_RAIQUB_RAND_SIZE,
		},
	}
}

func NewRandomSourceListSecure ( ) RandomSourceList { return RandomSourceList { RandomSource { Reader : rand . Reader , Weight : DEFAULT_SYS_RAND_SIZE , } , RandomSource { Reader : NewRandom ( ) , Weight : DEFAULT_RAIQUB_RAND_SIZE , } , } }

// NewRandomSourceListSecure returns system provided source of random data
// besides of Raiqub Random source.

NewRandomSourceListSecure returns system provided source of random data besides of Raiqub Random source .


func (handler *SyslogHandler) Handle(record *Record) error {

	if handler.writter == nil {
		writter, err := syslog.Dial(
			handler.Network,
			handler.Address,
			handler.Facility|handler.Severity,
			handler.Tag,
		)

		if err != nil {
			return err
		}
		handler.writter = writter
	}

	msg := handler.Formatter.Format(record)

	switch record.Level {
	case EMERGENCY:
		return handler.writter.Emerg(msg)
	case ALERT:
		return handler.writter.Alert(msg)
	case CRITICAL:
		return handler.writter.Crit(msg)
	case ERROR:
		return handler.writter.Err(msg)
	case WARNING:
		return handler.writter.Warning(msg)
	case NOTICE:
		return handler.writter.Notice(msg)
	case INFO:
		return handler.writter.Info(msg)
	default:
		return handler.writter.Debug(msg)
	}
}

func ( handler * SyslogHandler ) Handle ( record * Record ) error { if handler . writter == nil { writter , err := syslog . Dial ( handler . Network , handler . Address , handler . Facility | handler . Severity , handler . Tag , ) if err != nil { return err } handler . writter = writter } msg := handler . Formatter . Format ( record ) switch record . Level { case EMERGENCY : return handler . writter . Emerg ( msg ) case ALERT : return handler . writter . Alert ( msg ) case CRITICAL : return handler . writter . Crit ( msg ) case ERROR : return handler . writter . Err ( msg ) case WARNING : return handler . writter . Warning ( msg ) case NOTICE : return handler . writter . Notice ( msg ) case INFO : return handler . writter . Info ( msg ) default : return handler . writter . Debug ( msg ) } }

// Handle sends a record message to syslog Writer.

Handle sends a record message to syslog Writer .


func (handler *SyslogHandler) Close() error {
	if handler.writter == nil {
		return nil
	}
	return handler.writter.Close()
}

func ( handler * SyslogHandler ) Close ( ) error { if handler . writter == nil { return nil } return handler . writter . Close ( ) }

// Close closes an associated syslog Writer.

Close closes an associated syslog Writer .


func hasDatePrefix(s string) bool {
	if len(s) < 10 {
		return false
	}
	var count int
	for i, r := range s {
		if count != i {
			return false
		}
		switch i {
		case 4, 7:
			if r != '-' {
				return false
			}
		default:
			if !isDigit(r) {
				return false
			}
		}
		if i == 9 {
			// month
			if s[5] == '1' {
				if s[6] > '2' {
					return false
				}
			} else if s[5] == '0' {
				if s[6] == '0' {
					return false
				}
			} else {
				return false
			}

			// day
			if s[8] == '0' {
				if s[9] == '0' {
					return false
				}
			} else if s[8] == '3' {
				if s[9] > '1' {
					return false
				}
			} else if s[8] != '1' && s[8] != '2' {
				return false
			}

			return true
		}
		count += 1
	}

	return true
}

func
hasDatePrefix
(
s
string
)
bool
{
if
len
(
s
)
<
10
{
return
false
}
var
count
int
for
i
,
r
:=
range
s
{
if
count
!=
i
{
return
false
}
switch
i
{
case
4
,
7
:
if
r
!=
'-'
{
return
false
}
default
:
if
!
isDigit
(
r
)
{
return
false
}
}
if
i
==
9
{
// month
if
s
[
5
]
==
'1'
{
if
s
[
6
]
>
'2'
{
return
false
}
}
else
if
s
[
5
]
==
'0'
{
if
s
[
6
]
==
'0'
{
return
false
}
}
else
{
return
false
}
// day
if
s
[
8
]
==
'0'
{
if
s
[
9
]
==
'0'
{
return
false
}
}
else
if
s
[
8
]
==
'3'
{
if
s
[
9
]
>
'1'
{
return
false
}
}
else
if
s
[
8
]
!=
'1'
&&
s
[
8
]
!=
'2'
{
return
false
}
return
true
}
count
+=
1
}
return
true
}

// date formant YYYY-MM-DD
// mininum date 0000-01-01
// maximum date 9999-12-31


func (f RuneMatcherFunc) Match(str string) (offset int, matchStr string) {
	offset = -1
	length := len(str)
	if length == 0 {
		return
	}

	for i, r := range str {
		if f(r) {
			continue
		}
		if i != 0 {
			offset = i
			matchStr = str[:i]
			return
		}
		return
	}

	offset = length
	matchStr = str
	return
}

func ( f RuneMatcherFunc ) Match ( str string ) ( offset int , matchStr string ) { offset = - 1 length := len ( str ) if length == 0 { return } for i , r := range str { if f ( r ) { continue } if i != 0 { offset = i matchStr = str [ : i ] return } return } offset = length matchStr = str return }

// Match processes the given string until it encounters a rune that doesn't
// match.

Match processes the given string until it encounters a rune that doesn t match .


func (m *SuffixMatcher) Match(str string) (offset int, matchStr string) {
	offset = -1

	// at least 1 character is required to match suffix and matcher
	d := len(str) - len(m.suffix)
	if d < 1 {
		return
	}

	for i, r := range str {
		if i > d {
			return
		}

		// peek string to match to suffix pattern
		if i != 0 && m.suffix == str[i:i+len(m.suffix)] {
			offset = i + len(m.suffix)
			matchStr = str[:i]
			return
		}

		if !m.matcher.MatchRune(r) {
			return
		}
	}
	return
}

// Match processes the given string until it has its suffix in the next or
// encounters a rune that doesn't match.

Match processes the given string until it has its suffix in the next or encounters a rune that doesn t match .


func (m *SuffixMatcher) MatchRune(r rune) bool {
	return m.matcher.MatchRune(r)
}

func ( m * SuffixMatcher ) MatchRune ( r rune ) bool { return m . matcher . MatchRune ( r ) }

// MatchRune simply calls mather.MatchRune

MatchRune simply calls mather . MatchRune


func (m *FixedLengthMatcher) Match(s string) (offset int, matchStr string) {
	if len(s) < m.length || !m.match(s) {
		offset = -1
		return
	}
	return m.length, s[:m.length]
}

func ( m * FixedLengthMatcher ) Match ( s string ) ( offset int , matchStr string ) { if len ( s ) < m . length || ! m . match ( s ) { offset = - 1 return } return m . length , s [ : m . length ] }


func (b *RefCountBox) Alloc() (DB, error) {
	b.Lock()
	defer b.Unlock()

	if b.db.DB == nil {
		if b.DataPath == nil {
			return DB{}, errorsp.WithStacks(ErrBoxDataPathNotSpecified)
		}
		var db DB
		var err error
		if b.OpenFunc == nil {
			db, err = Open(b.DataPath(), 0644, nil)
		} else {
			db, err = b.OpenFunc(b.DataPath())
		}
		if err != nil {
			return DB{}, errorsp.WithStacks(err)
		}
		b.db, b.count = db, 0
	}
	b.count++
	return b.db, nil
}

func ( b * RefCountBox ) Alloc ( ) ( DB , error ) { b . Lock ( ) defer b . Unlock ( ) if b . db . DB == nil { if b . DataPath == nil { return DB { } , errorsp . WithStacks ( ErrBoxDataPathNotSpecified ) } var db DB var err error if b . OpenFunc == nil { db , err = Open ( b . DataPath ( ) , 0644 , nil ) } else { db , err = b . OpenFunc ( b . DataPath ( ) ) } if err != nil { return DB { } , errorsp . WithStacks ( err ) } b . db , b . count = db , 0 } b . count ++ return b . db , nil }

// Alloc opens a DB if not openned yet. It adds a reference if already openned.

Alloc opens a DB if not openned yet . It adds a reference if already openned .


func (b *RefCountBox) Free() {
	b.Lock()
	defer b.Unlock()

	b.count--
	if b.count == 0 {
		b.db.Close()
		b.db = DB{}
	}
}

func ( b * RefCountBox ) Free ( ) { b . Lock ( ) defer b . Unlock ( ) b . count -- if b . count == 0 { b . db . Close ( ) b . db = DB { } } }

// Free decreases the reference count. It close the DB if the count reaches
// zero.

Free decreases the reference count . It close the DB if the count reaches zero .


func (g GRPCLoggerV2) Infof(format string, args ...interface{}) {
	g.l.Infof(format, args...)
}

func ( g GRPCLoggerV2 ) Infof ( format string , args ... interface { } ) { g . l . Infof ( format , args ... ) }

// Infof calls Logger.Infof method with provided arguments.

Infof calls Logger . Infof method with provided arguments .


func (g GRPCLoggerV2) Warningf(format string, args ...interface{}) {
	g.l.Warningf(format, args...)
}

func ( g GRPCLoggerV2 ) Warningf ( format string , args ... interface { } ) { g . l . Warningf ( format , args ... ) }

// Warningf calls Logger.Warningf method with provided arguments.

Warningf calls Logger . Warningf method with provided arguments .


func (g GRPCLoggerV2) Errorf(format string, args ...interface{}) {
	g.l.Errorf(format, args...)
}

func ( g GRPCLoggerV2 ) Errorf ( format string , args ... interface { } ) { g . l . Errorf ( format , args ... ) }

// Errorf calls Logger.Errorf method with provided arguments.

Errorf calls Logger . Errorf method with provided arguments .


func (g GRPCLoggerV2) Fatalf(format string, args ...interface{}) {
	g.l.Criticalf(format, args...)
}

func ( g GRPCLoggerV2 ) Fatalf ( format string , args ... interface { } ) { g . l . Criticalf ( format , args ... ) }

// Fatalf calls Logger.Criticalf method with provided arguments.

Fatalf calls Logger . Criticalf method with provided arguments .


func ToPhone(theString, delimiter string) (string, error) {
	f := New(theString)
	f.removeNonDigits()

	if f.length < 10 {
		return "", errors.New(lengthError)
	}

	var buffer bytes.Buffer
	count := 0
	switch f.length {
	case 10:
		buffer.WriteString("(")
		for _, i := range f.theString {
			count++
			buffer.WriteString(string(i))
			switch count {
			case 3:
				buffer.WriteString(") ")
			case 6:
				buffer.WriteString(fmt.Sprintf("%s", delimiter))
			}
		}
	case 11:
		for _, i := range f.theString {
			count++
			buffer.WriteString(string(i))
			switch count {
			case 1:
				buffer.WriteString(" (")
			case 4:
				buffer.WriteString(") ")
			case 7:
				buffer.WriteString(fmt.Sprintf("%s", delimiter))
			}
		}
	default:
		return "", errors.New("non US number given")
	}
	return buffer.String(), nil
}

func ToPhone ( theString , delimiter string ) ( string , error ) { f := New ( theString ) f . removeNonDigits ( ) if f . length < 10 { return " " , errors . New ( lengthError ) } var buffer bytes . Buffer count := 0 switch f . length { case 10 : buffer . WriteString ( " " ) for _ , i := range f . theString { count ++ buffer . WriteString ( string ( i ) ) switch count { case 3 : buffer . WriteString ( " " ) case 6 : buffer . WriteString ( fmt . Sprintf ( " " , delimiter ) ) } } case 11 : for _ , i := range f . theString { count ++ buffer . WriteString ( string ( i ) ) switch count { case 1 : buffer . WriteString ( " " ) case 4 : buffer . WriteString ( " " ) case 7 : buffer . WriteString ( fmt . Sprintf ( " " , delimiter ) ) } } default : return " " , errors . New ( " " ) } return buffer . String ( ) , nil }

// ToPhone will format the provided string as a Phone Number.  Only supports
// US numbers currently.

ToPhone will format the provided string as a Phone Number . Only supports US numbers currently .


func ToURL(theString, subdomain string, secure bool) (string, error) {
	f := New(theString)

	if f.length < 4 {
		return "", errors.New(lengthError)
	}

	f.makeLower()

	if secure {
		if len(subdomain) > 0 {
			return fmt.Sprintf("https://%s.%s", subdomain, f.theString), nil
		}
		return fmt.Sprintf("https://%s", f.theString), nil
	}

	if len(subdomain) > 0 {
		return fmt.Sprintf("http://%s.%s", subdomain, f.theString), nil
	}
	return fmt.Sprintf("http://%s", f.theString), nil
}

func ToURL ( theString , subdomain string , secure bool ) ( string , error ) { f := New ( theString ) if f . length < 4 { return " " , errors . New ( lengthError ) } f . makeLower ( ) if secure { if len ( subdomain ) > 0 { return fmt . Sprintf ( " " , subdomain , f . theString ) , nil } return fmt . Sprintf ( " " , f . theString ) , nil } if len ( subdomain ) > 0 { return fmt . Sprintf ( " " , subdomain , f . theString ) , nil } return fmt . Sprintf ( " " , f . theString ) , nil }

// ToURL will format the provided string as a URL.  HTTP and HTTPS
// are the only supported protocols at this time.

ToURL will format the provided string as a URL . HTTP and HTTPS are the only supported protocols at this time .


func ToSSN(theString, delimiter string) (string, error) {
	f := New(theString)
	f.removeNonDigits()

	if f.length != 9 {
		return "", errors.New("string needs to be 9 digits for Social Security Numbers")
	}

	var buffer bytes.Buffer
	count := 0

	for _, i := range f.theString {
		count++

		buffer.WriteString(string(i))

		if count == 3 || count == 5 {
			buffer.WriteString(delimiter)
		}
	}
	return buffer.String(), nil
}

func ToSSN ( theString , delimiter string ) ( string , error ) { f := New ( theString ) f . removeNonDigits ( ) if f . length != 9 { return " " , errors . New ( " " ) } var buffer bytes . Buffer count := 0 for _ , i := range f . theString { count ++ buffer . WriteString ( string ( i ) ) if count == 3 || count == 5 { buffer . WriteString ( delimiter ) } } return buffer . String ( ) , nil }

// ToSSN will format the provided string as a SSN.

ToSSN will format the provided string as a SSN .


func ToMorseCode(theString string) (string, error) {
	f := New(theString)

	if f.length < 1 {
		return "", errors.New(lengthError)
	}

	f.makeLower()

	var buffer bytes.Buffer

	for _, i := range f.theString {
		key := string(i)
		if _, ok := morse[key]; ok {
			buffer.WriteString(morse[key])
		} else if key == " " {
			buffer.WriteString(" ")
		}
	}
	return buffer.String(), nil
}

func ToMorseCode ( theString string ) ( string , error ) { f := New ( theString ) if f . length < 1 { return " " , errors . New ( lengthError ) } f . makeLower ( ) var buffer bytes . Buffer for _ , i := range f . theString { key := string ( i ) if _ , ok := morse [ key ] ; ok { buffer . WriteString ( morse [ key ] ) } else if key == " " { buffer . WriteString ( " " ) } } return buffer . String ( ) , nil }

// ToMorseCode will format the provided string in Morse Code.

ToMorseCode will format the provided string in Morse Code .


func ToPirateSpeak(theString string) (string, error) {
	f := New(theString)

	if f.length < 1 {
		return "", errors.New(lengthError)
	}

	f.urlEncodeSpaces()

	response, err := http.Get(fmt.Sprintf(pirateLink, f.theString))
	if err != nil {
		return "", errors.New("unable to convert")
	}
	defer response.Body.Close()

	contents, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return "", err
	}
	return string(contents), nil
}

func ToPirateSpeak ( theString string ) ( string , error ) { f := New ( theString ) if f . length < 1 { return " " , errors . New ( lengthError ) } f . urlEncodeSpaces ( ) response , err := http . Get ( fmt . Sprintf ( pirateLink , f . theString ) ) if err != nil { return " " , errors . New ( " " ) } defer response . Body . Close ( ) contents , err := ioutil . ReadAll ( response . Body ) if err != nil { return " " , err } return string ( contents ) , nil }

// ToPirateSpeak will format the provided string in Pirate Speak.

ToPirateSpeak will format the provided string in Pirate Speak .


func ToIRSA(theString string) (string, error) {
	f := New(theString)

	if f.length < 1 {
		return "", errors.New(lengthError)
	}

	f.makeLower()

	var buffer bytes.Buffer

	for _, i := range f.theString {
		key := strings.ToLower(string(i))
		if _, ok := irsa[key]; ok {
			buffer.WriteString(irsa[key] + " ")
		}
	}
	return buffer.String(), nil
}

func ToIRSA ( theString string ) ( string , error ) { f := New ( theString ) if f . length < 1 { return " " , errors . New ( lengthError ) } f . makeLower ( ) var buffer bytes . Buffer for _ , i := range f . theString { key := strings . ToLower ( string ( i ) ) if _ , ok := irsa [ key ] ; ok { buffer . WriteString ( irsa [ key ] + " " ) } } return buffer . String ( ) , nil }

// ToIRSA will format the provided string in IRSA.
// International Radio-Telephony Spelling Alphabet

ToIRSA will format the provided string in IRSA . International Radio - Telephony Spelling Alphabet


func newDefaultLogger() *Logger {
	return NewLogger("default", DEBUG, []Handler{
		&WriteHandler{
			Level:     DEBUG,
			Formatter: &StandardFormatter{TimeFormat: StandardTimeFormat},
			Writer:    os.Stderr,
		},
	}, 0)
}

func newDefaultLogger ( ) * Logger { return NewLogger ( " " , DEBUG , [ ] Handler { & WriteHandler { Level : DEBUG , Formatter : & StandardFormatter { TimeFormat : StandardTimeFormat } , Writer : os . Stderr , } , } , 0 ) }

// newDefaultLogger creates new logger that writes log messages to
// standard output in DEBUG level. This logger is automatically created and
// this function needs to be called only if all loggers were removed
// and default logger needs recreating.

newDefaultLogger creates new logger that writes log messages to standard output in DEBUG level . This logger is automatically created and this function needs to be called only if all loggers were removed and default logger needs recreating .


func Logf(level Level, format string, a ...interface{}) {
	getDefaultLogger().log(level, format, a...)
}

func Logf ( level Level , format string , a ... interface { } ) { getDefaultLogger ( ) . log ( level , format , a ... ) }

// Logf logs provided message with formatting with default logger.

Logf logs provided message with formatting with default logger .


func (c *Config) Sections() []string {
	var sections []string
	for _, sect := range c.sections {
		sections = append(sections, sect.name)
	}
	return sections
}

func ( c * Config ) Sections ( ) [ ] string { var sections [ ] string for _ , sect := range c . sections { sections = append ( sections , sect . name ) } return sections }

// Sections returns the list of sections in the file.

Sections returns the list of sections in the file .


func (c *Config) Options(section string) []string {
	var options []string
	for _, sect := range c.sections {
		if sect.name == section {
			for _, opt := range sect.options {
				options = append(options, opt.name)
			}
			break
		}
	}
	return options
}

func ( c * Config ) Options ( section string ) [ ] string { var options [ ] string for _ , sect := range c . sections { if sect . name == section { for _ , opt := range sect . options { options = append ( options , opt . name ) } break } } return options }

// Options returns the list of options in a given section.

Options returns the list of options in a given section .


func (c *Config) OptionMap(section string) map[string]string {
	options := make(map[string]string)
	for _, sect := range c.sections {
		if sect.name == section {
			for _, opt := range sect.options {
				options[opt.name] = opt.value
			}
			break
		}
	}
	return options
}

func ( c * Config ) OptionMap ( section string ) map [ string ] string { options := make ( map [ string ] string ) for _ , sect := range c . sections { if sect . name == section { for _ , opt := range sect . options { options [ opt . name ] = opt . value } break } } return options }

// OptionMap returns the map option => value for a given section.

OptionMap returns the map option = > value for a given section .


func (c *Config) Comments(section string) []string {
	if section == "" {
		return c.comments
	}
	for _, sect := range c.sections {
		if sect.name == section {
			return sect.comments
		}
	}
	return nil
}

func ( c * Config ) Comments ( section string ) [ ] string { if section == " " { return c . comments } for _ , sect := range c . sections { if sect . name == section { return sect . comments } } return nil }

// Comments returns the list of comments in a given section.
// For the empty string, returns the file comments.

Comments returns the list of comments in a given section . For the empty string returns the file comments .


func (c *Config) AddComment(sect, comment string) {
	if sect == "" {
		c.comments = append(c.comments, comment)
		return
	}

	for i, s := range c.sections {
		if s.name == sect {
			c.sections[i].comments = append(s.comments, comment)
			return
		}
	}

	c.sections = append(c.sections, section{
		name:     sect,
		comments: []string{comment},
	})
}

func ( c * Config ) AddComment ( sect , comment string ) { if sect == " " { c . comments = append ( c . comments , comment ) return } for i , s := range c . sections { if s . name == sect { c . sections [ i ] . comments = append ( s . comments , comment ) return } } c . sections = append ( c . sections , section { name : sect , comments : [ ] string { comment } , } ) }

// AddComments appends the comment to the list of comments for the section.

AddComments appends the comment to the list of comments for the section .


func Parse(stream io.Reader) Config {
	var cfg Config
	var curSection string

	scanner := bufio.NewScanner(bufio.NewReader(stream))
	for scanner.Scan() {
		line := strings.TrimSpace(scanner.Text())
		if strings.HasPrefix(line, "#") || strings.HasPrefix(line, ";") {
			comment := strings.TrimLeft(line, ";# ")
			cfg.AddComment(curSection, comment)
		} else if len(line) > 0 {
			if m := iniSectionRe.FindStringSubmatch(line); len(m) > 0 {
				curSection = m[1]
			} else if m := iniOptionRe.FindStringSubmatch(line); len(m) > 0 {
				key := m[1]
				val := m[2]
				if !strings.Contains(val, "\"") {
					// If val does not contain any quote characers, we can make it
					// a quoted string and safely let strconv.Unquote sort out any
					// escapes
					val = "\"" + val + "\""
				}
				if val[0] == '"' {
					val, _ = strconv.Unquote(val)
				}

				cfg.Set(curSection, key, val)
			}
		}
	}
	return cfg
}

// Parse reads the given io.Reader and returns a parsed Config object.

Parse reads the given io . Reader and returns a parsed Config object .


func (c *Config) Write(out io.Writer) error {
	for _, cmt := range c.comments {
		fmt.Fprintln(out, "; "+cmt)
	}
	if len(c.comments) > 0 {
		fmt.Fprintln(out)
	}

	for _, sect := range c.sections {
		fmt.Fprintf(out, "[%s]\n", sect.name)
		for _, cmt := range sect.comments {
			fmt.Fprintln(out, "; "+cmt)
		}
		for _, opt := range sect.options {
			val := opt.value
			if len(val) == 0 {
				continue
			}

			// Quote the string if it begins or ends with space
			needsQuoting := val[0] == ' ' || val[len(val)-1] == ' '

			if !needsQuoting {
				// Quote the string if it contains any unprintable characters
				for _, r := range val {
					if !strconv.IsPrint(r) {
						needsQuoting = true
						break
					}
				}
			}

			if needsQuoting {
				val = strconv.Quote(val)
			}

			fmt.Fprintf(out, "%s=%s\n", opt.name, val)
		}
		fmt.Fprintln(out)
	}
	return nil
}

// Write writes the sections and options to the io.Writer in INI format.

Write writes the sections and options to the io . Writer in INI format .


func (c *Config) Get(section, key string) string {
	for _, sect := range c.sections {
		if sect.name == section {
			for _, opt := range sect.options {
				if opt.name == key {
					return opt.value
				}
			}
			return ""
		}
	}
	return ""
}

func ( c * Config ) Get ( section , key string ) string { for _ , sect := range c . sections { if sect . name == section { for _ , opt := range sect . options { if opt . name == key { return opt . value } } return " " } } return " " }

// Get gets the value from the specified section and key name, or the empty
// string if either the section or the key is missing.

Get gets the value from the specified section and key name or the empty string if either the section or the key is missing .


func (c *Config) Set(sectionName, key, value string) {
	for i, sect := range c.sections {
		if sect.name == sectionName {
			for j, opt := range sect.options {
				if opt.name == key {
					c.sections[i].options[j].value = value
					return
				}
			}
			c.sections[i].options = append(sect.options, option{key, value})
			return
		}
	}

	c.sections = append(c.sections, section{
		name:    sectionName,
		options: []option{{key, value}},
	})
}

func ( c * Config ) Set ( sectionName , key , value string ) { for i , sect := range c . sections { if sect . name == sectionName { for j , opt := range sect . options { if opt . name == key { c . sections [ i ] . options [ j ] . value = value return } } c . sections [ i ] . options = append ( sect . options , option { key , value } ) return } } c . sections = append ( c . sections , section { name : sectionName , options : [ ] option { { key , value } } , } ) }

// Set sets a value for an option in a section. If the option exists, it's
// value will be overwritten. If the option does not exist, it will be added.
// If the section does not exist, it will be added and the option added to it.

Set sets a value for an option in a section . If the option exists it s value will be overwritten . If the option does not exist it will be added . If the section does not exist it will be added and the option added to it .


func (c *Config) Delete(section, key string) {
	for sn, sect := range c.sections {
		if sect.name == section {
			for i, opt := range sect.options {
				if opt.name == key {
					c.sections[sn].options = append(sect.options[:i], sect.options[i+1:]...)
					return
				}
			}
			return
		}
	}
}

func ( c * Config ) Delete ( section , key string ) { for sn , sect := range c . sections { if sect . name == section { for i , opt := range sect . options { if opt . name == key { c . sections [ sn ] . options = append ( sect . options [ : i ] , sect . options [ i + 1 : ] ... ) return } } return } } }

// Delete removes the option from the specified section.

Delete removes the option from the specified section .


func Convert(val interface{}, targetType reflect.Type) reflect.Value {
	value := reflect.ValueOf(val)
	if !value.IsValid() {
		return reflect.Zero(targetType)
	}

	valType := value.Type()
	if valType.ConvertibleTo(targetType) {
		return value.Convert(targetType)
	}

	//fmt.Printf("Value type is %v, emptyInterfaceType is %v, equals %v\n", valType, emptyInterfaceType, valType == emptyInterfaceType)
	interfaceVal := value.Interface()

	switch realVal := interfaceVal.(type) {
	case float64:
		return reflect.ValueOf(realVal).Convert(targetType)
	case []interface{}:
		// val is of type []interface{}, try to convert to typ
		sliceSize := len(realVal)
		targetSlice := reflect.MakeSlice(targetType, 0, sliceSize)
		elemType := targetType.Elem()
		for i := 0; i < sliceSize; i++ {
			targetSlice = reflect.Append(targetSlice, Convert(value.Index(i), elemType))
		}
		return targetSlice
	}

	panic(fmt.Errorf("convert from type %v to %v failed: %v", valType, targetType, value))
}

// try to convert value to target type, panic if fail

try to convert value to target type panic if fail


func (i *cacheItem) Postpone() {
	i.expireAt = time.Now().Add(i.lifetime)
}

func ( i * cacheItem ) Postpone ( ) { i . expireAt = time . Now ( ) . Add ( i . lifetime ) }

// Postpone value expiration time to current time added to its lifetime
// duration.

Postpone value expiration time to current time added to its lifetime duration .


func Filter(l LogBackend, r Ruler) LogBackend {
	return &filter{
		LogBackend: l,
		r:          r,
	}
}

func Filter ( l LogBackend , r Ruler ) LogBackend { return & filter { LogBackend : l , r : r , } }

// Filter creates a new filter with rules r for l backend.

Filter creates a new filter with rules r for l backend .


func Op(o Operation, field string, vleft ...interface{}) Ruler {
	if len(vleft) > 1 {
		panic("Op accept only zero or one val")
	}
	var val reflect.Value
	if len(vleft) == 1 {
		val = reflect.Indirect(reflect.ValueOf(vleft[0]))
		if val.IsValid() && val.Kind() == reflect.Interface {
			val = val.Elem()
		}
	}
	return &op{
		field:  field,
		vright: val,
		op:     o,
	}
}

func Op ( o Operation , field string , vleft ... interface { } ) Ruler { if len ( vleft ) > 1 { panic ( " " ) } var val reflect . Value if len ( vleft ) == 1 { val = reflect . Indirect ( reflect . ValueOf ( vleft [ 0 ] ) ) if val . IsValid ( ) && val . Kind ( ) == reflect . Interface { val = val . Elem ( ) } } return & op { field : field , vright : val , op : o , } }

// Op is an operation in some field and with some value.

Op is an operation in some field and with some value .


func ApplyRuleIf(condition, rule Ruler) Ruler {
	return &apply{
		condition: condition,
		rule:      rule,
	}
}

func ApplyRuleIf ( condition , rule Ruler ) Ruler { return & apply { condition : condition , rule : rule , } }

// ApplyRuleIf test if condition is true than apply rule. If condition is false
// do nothing, return true.

ApplyRuleIf test if condition is true than apply rule . If condition is false do nothing return true .


func ApplyRuleIfElse(condition, rule, el Ruler) Ruler {
	return &applyelse{
		condition: condition,
		rule:      rule,
		el:        el,
	}
}

func ApplyRuleIfElse ( condition , rule , el Ruler ) Ruler { return & applyelse { condition : condition , rule : rule , el : el , } }

// ApplyRuleIfElse test if condition is true than apply rule. If condition is false
// run else rule.

ApplyRuleIfElse test if condition is true than apply rule . If condition is false run else rule .


func (self HttpBasicAuthenticator) AuthHandler(next http.Handler) http.Handler {
	if self.HttpAuthenticable == nil {
		panic("HttpAuthenticable cannot be nil")
	}

	f := func(w http.ResponseWriter, r *http.Request) {
		user, secret := self.parseAuthHeader(r.Header.Get("Authorization"))
		if len(user) > 0 &&
			len(secret) > 0 &&
			self.TryAuthentication(r, user, secret) {
			next.ServeHTTP(w, r)
			return
		}

		HttpHeader_WwwAuthenticate().
			SetValue(BASIC_REALM).
			SetWriter(w.Header())
		http.Error(w, http.StatusText(http.StatusUnauthorized),
			http.StatusUnauthorized)
	}

	return http.HandlerFunc(f)
}

func ( self HttpBasicAuthenticator ) AuthHandler ( next http . Handler ) http . Handler { if self . HttpAuthenticable == nil { panic ( " " ) } f := func ( w http . ResponseWriter , r * http . Request ) { user , secret := self . parseAuthHeader ( r . Header . Get ( " " ) ) if len ( user ) > 0 && len ( secret ) > 0 && self . TryAuthentication ( r , user , secret ) { next . ServeHTTP ( w , r ) return } HttpHeader_WwwAuthenticate ( ) . SetValue ( BASIC_REALM ) . SetWriter ( w . Header ( ) ) http . Error ( w , http . StatusText ( http . StatusUnauthorized ) , http . StatusUnauthorized ) } return http . HandlerFunc ( f ) }

// AuthHandler is a HTTP request middleware that enforces authentication.

AuthHandler is a HTTP request middleware that enforces authentication .


func (s *Docker) HasBin() bool {
	_, err := exec.LookPath(s.binCmd)
	return err == nil
}

func ( s * Docker ) HasBin ( ) bool { _ , err := exec . LookPath ( s . binCmd ) return err == nil }

// HasBin check whether Docker binary is available.

HasBin check whether Docker binary is available .


func (s *Docker) Run(cmd string, args ...string) (string, error) {
	cmdArgs := make([]string, 0, len(args)+1)
	cmdArgs = append(cmdArgs, cmd)
	cmdArgs = append(cmdArgs, args...)

	exe := exec.Command(s.binCmd, cmdArgs...)
	var stdout, stderr bytes.Buffer
	exe.Stdout, exe.Stderr = &stdout, &stderr

	if err := exe.Run(); err != nil {
		return stdout.String(), ExternalCmdError{
			err, stderr.String(), stdout.String()}
	}
	return stdout.String(), nil
}

func ( s * Docker ) Run ( cmd string , args ... string ) ( string , error ) { cmdArgs := make ( [ ] string , 0 , len ( args ) + 1 ) cmdArgs = append ( cmdArgs , cmd ) cmdArgs = append ( cmdArgs , args ... ) exe := exec . Command ( s . binCmd , cmdArgs ... ) var stdout , stderr bytes . Buffer exe . Stdout , exe . Stderr = & stdout , & stderr if err := exe . Run ( ) ; err != nil { return stdout . String ( ) , ExternalCmdError { err , stderr . String ( ) , stdout . String ( ) } } return stdout . String ( ) , nil }

// Run executes especified command on Docker.
//
// Returns ExternalCmdError on error.

Run executes especified command on Docker . Returns ExternalCmdError on error .


func (s *HttpHeader) GetReader(h http.Header) *HttpHeader {
	s.Value = h.Get(s.Name)
	return s
}

func ( s * HttpHeader ) GetReader ( h http . Header ) * HttpHeader { s . Value = h . Get ( s . Name ) return s }

// GetReader gets HTTP header value, as defined by current instance, from
// Request Header and sets to current instance.

GetReader gets HTTP header value as defined by current instance from Request Header and sets to current instance .


func (s *HttpHeader) SetName(name string) *HttpHeader {
	s.Name = name
	return s
}

func ( s * HttpHeader ) SetName ( name string ) * HttpHeader { s . Name = name return s }

// SetName sets header name of current instance.

SetName sets header name of current instance .


func (s *HttpHeader) SetValue(value string) *HttpHeader {
	s.Value = value
	return s
}

func ( s * HttpHeader ) SetValue ( value string ) * HttpHeader { s . Value = value return s }

// SetValue sets header value of current instance.

SetValue sets header value of current instance .


func (s *HttpHeader) SetWriter(h http.Header) *HttpHeader {
	h.Set(s.Name, s.Value)
	return s
}

func ( s * HttpHeader ) SetWriter ( h http . Header ) * HttpHeader { h . Set ( s . Name , s . Value ) return s }

// SetWriter sets HTTP header, as defined by current instance, to ResponseWriter
// Header.

SetWriter sets HTTP header as defined by current instance to ResponseWriter Header .


func (e *Entity) encryptionKey(now time.Time) (Key, bool) {
	candidateSubkey := -1

	for i, subkey := range e.Subkeys {
		if subkey.Sig.FlagsValid &&
			subkey.Sig.FlagEncryptCommunications &&
			subkey.PublicKey.PubKeyAlgo.CanEncrypt() &&
			!subkey.Sig.KeyExpired(now) {
			candidateSubkey = i
			break
		}
	}

	if candidateSubkey != -1 {
		subkey := e.Subkeys[candidateSubkey]
		return Key{e, subkey.PublicKey, subkey.PrivateKey, subkey.Sig}, true
	}

	// If we don't have any candidate subkeys for encryption and
	// the primary key doesn't have any usage metadata then we
	// assume that the primary key is ok. Or, if the primary key is
	// marked as ok to encrypt to, then we can obviously use it.
	i := e.primaryIdentity()
	if !i.SelfSignature.FlagsValid || i.SelfSignature.FlagEncryptCommunications &&
		e.PrimaryKey.PubKeyAlgo.CanEncrypt() &&
		!i.SelfSignature.KeyExpired(now) {
		return Key{e, e.PrimaryKey, e.PrivateKey, i.SelfSignature}, true
	}

	// This Entity appears to be signing only.
	return Key{}, false
}

// encryptionKey returns the best candidate Key for encrypting a message to the
// given Entity.

encryptionKey returns the best candidate Key for encrypting a message to the given Entity .


func NewContentNegotiator(defaultEncoder Encoder, responseWriter http.ResponseWriter) *ContentNegotiator {
	result := &ContentNegotiator{}
	result.DefaultEncoder = defaultEncoder
	result.ResponseWriter = responseWriter
	return result
}

func NewContentNegotiator ( defaultEncoder Encoder , responseWriter http . ResponseWriter ) * ContentNegotiator { result := & ContentNegotiator { } result . DefaultEncoder = defaultEncoder result . ResponseWriter = responseWriter return result }

// NewContentNegotiator creates a basic ContentNegotiator with out any attached
// encoders

NewContentNegotiator creates a basic ContentNegotiator with out any attached encoders


func NewJsonXmlContentNegotiator(defaultEncoder Encoder, responseWriter http.ResponseWriter, prettyPrint bool) *ContentNegotiator {
	result := NewContentNegotiator(defaultEncoder, responseWriter)
	result.AddEncoder(MimeJSON, JsonEncoder{prettyPrint})
	result.AddEncoder(MimeXML, XmlEncoder{prettyPrint})
	return result
}

func NewJsonXmlContentNegotiator ( defaultEncoder Encoder , responseWriter http . ResponseWriter , prettyPrint bool ) * ContentNegotiator { result := NewContentNegotiator ( defaultEncoder , responseWriter ) result . AddEncoder ( MimeJSON , JsonEncoder { prettyPrint } ) result . AddEncoder ( MimeXML , XmlEncoder { prettyPrint } ) return result }

// NewJsonXmlContentNegotiator creates a basic ContentNegotiator and attaches
// a JSON and an XML encoder to it.

NewJsonXmlContentNegotiator creates a basic ContentNegotiator and attaches a JSON and an XML encoder to it .


func (cn *ContentNegotiator) Negotiate(req *http.Request, data interface{}) ([]byte, error) {
	if len(cn.encoderMap) <= 0 {
		panic("No Encoders present. Please add them using ContentNegotiator.AddEncoder()")
	}
	var e = cn.getEncoder(req)
	cn.ResponseWriter.Header().Set("Content-Type", e.ContentType())
	return e.Encode(data)
}

func ( cn * ContentNegotiator ) Negotiate ( req * http . Request , data interface { } ) ( [ ] byte , error ) { if len ( cn . encoderMap ) <= 0 { panic ( " " ) } var e = cn . getEncoder ( req ) cn . ResponseWriter . Header ( ) . Set ( " " , e . ContentType ( ) ) return e . Encode ( data ) }

// Negotiate inspects the request for the accept header and
// encodes the response appropriately.

Negotiate inspects the request for the accept header and encodes the response appropriately .


func (cn *ContentNegotiator) AddEncoder(mimeType string, enc Encoder) {
	if cn.encoderMap == nil {
		cn.encoderMap = make(map[string]Encoder)
	}
	cn.encoderMap[mimeType] = enc
}

func ( cn * ContentNegotiator ) AddEncoder ( mimeType string , enc Encoder ) { if cn . encoderMap == nil { cn . encoderMap = make ( map [ string ] Encoder ) } cn . encoderMap [ mimeType ] = enc }

// AddEncoder registers a mimetype and its encoder to be used if a client
// requests that mimetype

AddEncoder registers a mimetype and its encoder to be used if a client requests that mimetype


func (cn *ContentNegotiator) getEncoder(req *http.Request) Encoder {
	var result = cn.DefaultEncoder
	accept := req.Header.Get("Accept")

	for k, v := range cn.encoderMap {
		if strings.Contains(accept, k) {
			result = v
			break
		}
	}
	return result
}

func ( cn * ContentNegotiator ) getEncoder ( req * http . Request ) Encoder { var result = cn . DefaultEncoder accept := req . Header . Get ( " " ) for k , v := range cn . encoderMap { if strings . Contains ( accept , k ) { result = v break } } return result }

// getEncoder parses the Accept header an returns the appropriate encoder to use


func (pka PublicKeyAlgorithm) CanSign() bool {
	switch pka {
	case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA:
		return true
	}
	return false
}

func ( pka PublicKeyAlgorithm ) CanSign ( ) bool { switch pka { case PubKeyAlgoRSA , PubKeyAlgoRSASignOnly , PubKeyAlgoDSA : return true } return false }

// CanSign returns true if it's possible for a public key of the given type to
// sign a message.

CanSign returns true if it s possible for a public key of the given type to sign a message .


func (s PlayerStandings) ByWinnings(oldTieBreak bool) {
	if oldTieBreak {
		sort.Sort(sort.Reverse(ByWinningsOld{s}))
	} else {
		sort.Sort(sort.Reverse(ByWinnings{s}))
	}
}

func ( s PlayerStandings ) ByWinnings ( oldTieBreak bool ) { if oldTieBreak { sort . Sort ( sort . Reverse ( ByWinningsOld { s } ) ) } else { sort . Sort ( sort . Reverse ( ByWinnings { s } ) ) } }

// Various ways to sort the player standings using helper structs that
// implement different comparison methods.

Various ways to sort the player standings using helper structs that implement different comparison methods .


func WaitFunc(interval, timeout time.Duration, f func() bool) bool {
	after := time.After(timeout)
	for {
		select {
		case <-time.After(interval):
			if f() {
				return true
			}
		case <-after:
			return false
		}
	}

	return false
}

func WaitFunc ( interval , timeout time . Duration , f func ( ) bool ) bool { after := time . After ( timeout ) for { select { case <- time . After ( interval ) : if f ( ) { return true } case <- after : return false } } return false }

// WaitFunc waits until specified function returns true.

WaitFunc waits until specified function returns true .


func (s NetworkNode) FormatDialAddress() string {
	return fmt.Sprintf("%s:%d", s.IpAddress, s.Port)
}

func ( s NetworkNode ) FormatDialAddress ( ) string { return fmt . Sprintf ( " " , s . IpAddress , s . Port ) }

// FormatDialAddress returns an address as expected by net.Dial.

FormatDialAddress returns an address as expected by net . Dial .


func (s *NetworkNode) SetFromDocker(port string) error {
	split := strings.Split(port, "/")
	iPort, err := strconv.ParseUint(split[0], 10, 16)
	if err != nil {
		return err
	}

	s.Port, s.Protocol = uint16(iPort), split[1]
	return nil
}

func ( s * NetworkNode ) SetFromDocker ( port string ) error { split := strings . Split ( port , " " ) iPort , err := strconv . ParseUint ( split [ 0 ] , 10 , 16 ) if err != nil { return err } s . Port , s . Protocol = uint16 ( iPort ) , split [ 1 ] return nil }

// SetFromDocker parses port as provided by Docker and extract protocol and port
// number.

SetFromDocker parses port as provided by Docker and extract protocol and port number .


func (s *Random) Read(b []byte) (n int, err error) {
	s.mutex.Lock()
	defer s.mutex.Unlock()

	for i, _ := range b {
		b[i] = s.readByte()
	}

	return len(b), nil
}

func ( s * Random ) Read ( b [ ] byte ) ( n int , err error ) { s . mutex . Lock ( ) defer s . mutex . Unlock ( ) for i , _ := range b { b [ i ] = s . readByte ( ) } return len ( b ) , nil }

// Read fills specified byte array with random data.
// Always return parameter array length and no errors.

Read fills specified byte array with random data . Always return parameter array length and no errors .


func (s *Random) readByte() byte {
	before := time.Now()
	rndDuration := time.Duration(getUInt16FromBytes(s.val))

	time.Sleep(DEFAULT_SLEEP_TIME + rndDuration)
	diff := time.Now().Sub(before)
	n := byte(diff.Nanoseconds())

	s.val[s.index] = n
	s.index ^= 1

	return n
}

func ( s * Random ) readByte ( ) byte { before := time . Now ( ) rndDuration := time . Duration ( getUInt16FromBytes ( s . val ) ) time . Sleep ( DEFAULT_SLEEP_TIME + rndDuration ) diff := time . Now ( ) . Sub ( before ) n := byte ( diff . Nanoseconds ( ) ) s . val [ s . index ] = n s . index ^= 1 return n }

// readByte creates a single random byte.


func RecoverHandlerJson(next http.Handler) http.Handler {
	fn := func(w http.ResponseWriter, r *http.Request) {
		defer func() {
			if err := recover(); err != nil {
				jerr := NewJsonErrorFromError(
					http.StatusInternalServerError, fmt.Errorf("panic: %+v", err))
				JsonWrite(w, jerr.Status, jerr)
			}
		}()

		next.ServeHTTP(w, r)
	}

	return http.HandlerFunc(fn)
}

func RecoverHandlerJson ( next http . Handler ) http . Handler { fn := func ( w http . ResponseWriter , r * http . Request ) { defer func ( ) { if err := recover ( ) ; err != nil { jerr := NewJsonErrorFromError ( http . StatusInternalServerError , fmt . Errorf ( " " , err ) ) JsonWrite ( w , jerr . Status , jerr ) } } ( ) next . ServeHTTP ( w , r ) } return http . HandlerFunc ( fn ) }

// RecoverHandlerJson is a HTTP request middleware that captures panic errors
// and returns it as HTTP JSON response.

RecoverHandlerJson is a HTTP request middleware that captures panic errors and returns it as HTTP JSON response .


func DefaultServiceConfig() ServiceConfig {
	return ServiceConfig{
		// Dependencies.
		BackoffFactory: func() Backoff {
			return &backoff.StopBackOff{}
		},
		RandFactory: rand.Int,

		// Settings.
		RandReader: rand.Reader,
		Timeout:    1 * time.Second,
	}
}

func
DefaultServiceConfig
(
)
ServiceConfig
{
return
ServiceConfig
{
// Dependencies.
BackoffFactory
:
func
(
)
Backoff
{
return
&
backoff
.
StopBackOff
{
}
}
,
RandFactory
:
rand
.
Int
,
// Settings.
RandReader
:
rand
.
Reader
,
Timeout
:
1
*
time
.
Second
,
}
}

// DefaultServiceConfig provides a default configuration to create a new random
// service by best effort.

DefaultServiceConfig provides a default configuration to create a new random service by best effort .


func NewService(config ServiceConfig) (Service, error) {
	// Dependencies.
	if config.BackoffFactory == nil {
		return nil, maskAnyf(invalidConfigError, "backoff factory must not be empty")
	}
	if config.RandFactory == nil {
		return nil, maskAnyf(invalidConfigError, "rand factory must not be empty")
	}

	// Settings.
	if config.RandReader == nil {
		return nil, maskAnyf(invalidConfigError, "rand reader must not be empty")
	}

	newService := &service{
		// Dependencies.
		backoffFactory: config.BackoffFactory,
		randFactory:    config.RandFactory,

		// Settings.
		randReader: config.RandReader,
		timeout:    config.Timeout,
	}

	return newService, nil
}

func
NewService
(
config
ServiceConfig
)
(
Service
,
error
)
{
// Dependencies.
if
config
.
BackoffFactory
==
{
return
,
maskAnyf
(
invalidConfigError
,
"
"
)
}
if
config
.
RandFactory
==
{
return
,
maskAnyf
(
invalidConfigError
,
"
"
)
}
// Settings.
if
config
.
RandReader
==
{
return
,
maskAnyf
(
invalidConfigError
,
"
"
)
}
newService
:=
&
service
{
// Dependencies.
backoffFactory
:
config
.
BackoffFactory
,
randFactory
:
config
.
RandFactory
,
// Settings.
randReader
:
config
.
RandReader
,
timeout
:
config
.
Timeout
,
}
return
newService
,
}

// NewService creates a new configured random service.

NewService creates a new configured random service .


func (s *ImageMongoDB) RunLight(cfg *RunConfig) (*Container, error) {
	cfg.AddArgs("--smallfiles", "--nojournal")
	return s.Image.Run(cfg)
}

func ( s * ImageMongoDB ) RunLight ( cfg * RunConfig ) ( * Container , error ) { cfg . AddArgs ( " " , " " ) return s . Image . Run ( cfg ) }

// RunLight creates a light instance of MongoDB image.

RunLight creates a light instance of MongoDB image .


func initConfig() {
	if cfgFile != "" { // enable ability to specify config file via flag
		viper.SetConfigFile(cfgFile)
	}

	viper.SetConfigName(".fstack") // name of config file (without extension)
	viper.AddConfigPath("$HOME")   // adding home directory as first search path
	viper.AutomaticEnv()           // read in environment variables that match

	// If a config file is found, read it in.
	if err := viper.ReadInConfig(); err == nil {
		fmt.Println("Using config file:", viper.ConfigFileUsed())
	}

	fs, err := fstack.OpenStack(stackFile)
	if err != nil {
		panic(err)
	}
	stack = fs
}

// initConfig reads in config file and ENV variables if set.

initConfig reads in config file and ENV variables if set .


func (s *Container) HasExposedPorts() bool {
	nodes, err := s.NetworkNodes()
	if err != nil {
		return false
	}

	for _, v := range nodes {
		if v.Port > 0 || len(v.Protocol) > 0 {
			return true
		}
	}

	return false
}

func ( s * Container ) HasExposedPorts ( ) bool { nodes , err := s . NetworkNodes ( ) if err != nil { return false } for _ , v := range nodes { if v . Port > 0 || len ( v . Protocol ) > 0 { return true } } return false }

// HasExposedPorts returns whether current container has exposed ports.

HasExposedPorts returns whether current container has exposed ports .


func (s *Container) Inspect() ([]Inspect, error) {
	out, err := s.docker.Run("inspect", s.id)
	if err != nil {
		return nil, err
	}

	var list []Inspect
	err = json.NewDecoder(strings.NewReader(out)).Decode(&list)
	if err != nil {
		return nil, UnexpectedOutputError(fmt.Sprintf(
			"Error parsing output when inspecting container: %v", err))
	}
	if len(list) == 0 {
		return nil, UnexpectedOutputError(
			"Empty output when inspecting container")
	}

	return list, nil
}

func ( s * Container ) Inspect ( ) ( [ ] Inspect , error ) { out , err := s . docker . Run ( " " , s . id ) if err != nil { return nil , err } var list [ ] Inspect err = json . NewDecoder ( strings . NewReader ( out ) ) . Decode ( & list ) if err != nil { return nil , UnexpectedOutputError ( fmt . Sprintf ( " " , err ) ) } if len ( list ) == 0 { return nil , UnexpectedOutputError ( " " ) } return list , nil }

// Inspect returns container configuration.

Inspect returns container configuration .


func (s *Container) Kill() error {
	err := exec.Command(s.docker.binCmd, "kill", s.id).Run()
	if err != nil {
		return err
	}

	stopped := raiqub.WaitFunc(
		250*time.Millisecond, 30*time.Second, func() bool {
			inspect, err := s.Inspect()
			if err != nil || len(inspect) == 0 {
				return true
			}
			if !inspect[0].State.Running {
				return true
			}

			return false
		})
	if !stopped {
		err = fmt.Errorf("Timeout waiting '%s' container to stop", s.id)
	}

	return err
}

func ( s * Container ) Kill ( ) error { err := exec . Command ( s . docker . binCmd , " " , s . id ) . Run ( ) if err != nil { return err } stopped := raiqub . WaitFunc ( 250 * time . Millisecond , 30 * time . Second , func ( ) bool { inspect , err := s . Inspect ( ) if err != nil || len ( inspect ) == 0 { return true } if ! inspect [ 0 ] . State . Running { return true } return false } ) if ! stopped { err = fmt . Errorf ( " " , s . id ) } return err }

// Kill terminates current container process.

Kill terminates current container process .


func (s *Container) NetworkNodes() ([]NetworkNode, error) {
	inspect, err := s.Inspect()
	if err != nil {
		return nil, err
	}

	if len(inspect) == 0 {
		return nil, fmt.Errorf("Container inspect is empty")
	}

	nodes := make([]NetworkNode, 0)
	for _, i := range inspect {
		ip := i.NetworkSettings.IPAddress
		if ip == "" {
			continue
		}

		if len(i.NetworkSettings.Ports) == 0 {
			nodes = append(nodes, NetworkNode{
				IpAddress: ip,
			})
		} else {
			for k, _ := range i.NetworkSettings.Ports {
				node := NetworkNode{}
				node.IpAddress = ip
				node.SetFromDocker(k)
				nodes = append(nodes, node)
			}
		}
	}

	return nodes, nil
}

func ( s * Container ) NetworkNodes ( ) ( [ ] NetworkNode , error ) { inspect , err := s . Inspect ( ) if err != nil { return nil , err } if len ( inspect ) == 0 { return nil , fmt . Errorf ( " " ) } nodes := make ( [ ] NetworkNode , 0 ) for _ , i := range inspect { ip := i . NetworkSettings . IPAddress if ip == " " { continue } if len ( i . NetworkSettings . Ports ) == 0 { nodes = append ( nodes , NetworkNode { IpAddress : ip , } ) } else { for k , _ := range i . NetworkSettings . Ports { node := NetworkNode { } node . IpAddress = ip node . SetFromDocker ( k ) nodes = append ( nodes , node ) } } } return nodes , nil }

// NetworkNodes returns the network addresses and exposed ports of current
// container.

NetworkNodes returns the network addresses and exposed ports of current container .


func (s *Container) Remove() error {
	return exec.Command(s.docker.binCmd, "rm", s.id).Run()
}

func ( s * Container ) Remove ( ) error { return exec . Command ( s . docker . binCmd , " " , s . id ) . Run ( ) }

// Remove erases current container from Docker.

Remove erases current container from Docker .


func (s *Container) WaitStartup(timeout time.Duration) error {
	nodes, err := s.NetworkNodes()
	if err != nil {
		return fmt.Errorf("Error getting network nodes: %v", err)
	}

	if !s.HasExposedPorts() {
		return fmt.Errorf("Current container has no exposed ports")
	}

	ok := raiqub.WaitPeerListening(
		nodes[0].Protocol, nodes[0].FormatDialAddress(), timeout)
	if !ok {
		err = fmt.Errorf("%s unreachable for %v",
			nodes[0].FormatDialAddress(), timeout)
	}

	return err
}

func ( s * Container ) WaitStartup ( timeout time . Duration ) error { nodes , err := s . NetworkNodes ( ) if err != nil { return fmt . Errorf ( " " , err ) } if ! s . HasExposedPorts ( ) { return fmt . Errorf ( " " ) } ok := raiqub . WaitPeerListening ( nodes [ 0 ] . Protocol , nodes [ 0 ] . FormatDialAddress ( ) , timeout ) if ! ok { err = fmt . Errorf ( " " , nodes [ 0 ] . FormatDialAddress ( ) , timeout ) } return err }

// WaitStartup blocks current thread until current container begins to listen
// exposed port.

WaitStartup blocks current thread until current container begins to listen exposed port .


func NewHandler(counter *Counter, level logging.Level) (h *Handler) {
	return &Handler{
		Counter: counter,
		Level:   level,
	}
}

func NewHandler ( counter * Counter , level logging . Level ) ( h * Handler ) { return & Handler { Counter : counter , Level : level , } }

// NewHandler returns new Handler instance.

NewHandler returns new Handler instance .


func (h *Handler) Handle(record *logging.Record) error {
	switch record.Level {
	case logging.EMERGENCY:
		h.Counter.emergencyCounter.Inc()
	case logging.ALERT:
		h.Counter.alertCounter.Inc()
	case logging.CRITICAL:
		h.Counter.criticalCounter.Inc()
	case logging.ERROR:
		h.Counter.errorCounter.Inc()
	case logging.WARNING:
		h.Counter.warningCounter.Inc()
	case logging.NOTICE:
		h.Counter.noticeCounter.Inc()
	case logging.INFO:
		h.Counter.infoCounter.Inc()
	case logging.DEBUG:
		h.Counter.debugCounter.Inc()
	}
	return nil
}

func ( h * Handler ) Handle ( record * logging . Record ) error { switch record . Level { case logging . EMERGENCY : h . Counter . emergencyCounter . Inc ( ) case logging . ALERT : h . Counter . alertCounter . Inc ( ) case logging . CRITICAL : h . Counter . criticalCounter . Inc ( ) case logging . ERROR : h . Counter . errorCounter . Inc ( ) case logging . WARNING : h . Counter . warningCounter . Inc ( ) case logging . NOTICE : h . Counter . noticeCounter . Inc ( ) case logging . INFO : h . Counter . infoCounter . Inc ( ) case logging . DEBUG : h . Counter . debugCounter . Inc ( ) } return nil }

// Handle increments Prometheus counter metrics based on
// record log level.

Handle increments Prometheus counter metrics based on record log level .


func NewCounter(options *CounterOptions) (c *Counter) {
	if options == nil {
		options = new(CounterOptions)
	}
	if options.Name == "" {
		options.Name = "logging_messages_total"
	}
	if options.Help == "" {
		options.Help = "Number of log messages processed, partitioned by log level."
	}
	vector := prometheus.NewCounterVec(
		prometheus.CounterOpts{
			Name: options.Name,
			Help: options.Help,
		},
		[]string{"level"},
	)
	return &Counter{
		vector:           vector,
		emergencyCounter: vector.WithLabelValues("emergency"),
		alertCounter:     vector.WithLabelValues("alert"),
		criticalCounter:  vector.WithLabelValues("critical"),
		errorCounter:     vector.WithLabelValues("error"),
		warningCounter:   vector.WithLabelValues("warning"),
		noticeCounter:    vector.WithLabelValues("notice"),
		infoCounter:      vector.WithLabelValues("info"),
		debugCounter:     vector.WithLabelValues("debug"),
	}
}

func NewCounter ( options * CounterOptions ) ( c * Counter ) { if options == nil { options = new ( CounterOptions ) } if options . Name == " " { options . Name = " " } if options . Help == " " { options . Help = " " } vector := prometheus . NewCounterVec ( prometheus . CounterOpts { Name : options . Name , Help : options . Help , } , [ ] string { " " } , ) return & Counter { vector : vector , emergencyCounter : vector . WithLabelValues ( " " ) , alertCounter : vector . WithLabelValues ( " " ) , criticalCounter : vector . WithLabelValues ( " " ) , errorCounter : vector . WithLabelValues ( " " ) , warningCounter : vector . WithLabelValues ( " " ) , noticeCounter : vector . WithLabelValues ( " " ) , infoCounter : vector . WithLabelValues ( " " ) , debugCounter : vector . WithLabelValues ( " " ) , } }

// NewCounter creates new Counter instance.
// Options value can be nil.

NewCounter creates new Counter instance . Options value can be nil .


func (c *Counter) Metrics() (cs []prometheus.Collector) {
	return []prometheus.Collector{c.vector}
}

func ( c * Counter ) Metrics ( ) ( cs [ ] prometheus . Collector ) { return [ ] prometheus . Collector { c . vector } }

// Metrics retuns all Prometheus metrics that
// should be registered.

Metrics retuns all Prometheus metrics that should be registered .


func Retrieve(sources []*Source) (http.FileSystem, error) {
	files := make(mfs.Files)

	for i, source := range sources {
		log.Printf("Processing asset source (%d/%d): %s ...", i+1, len(sources), source.Location)

		// Retrieve the file or files
		retFiles, err := retrieve(source.Location)
		if err != nil {
			return nil, &RetrieveError{source.Location, err}
		}

		// If multiple files are returned store them and finish processing.
		// Chekcsum and archive not supported for multiple files.
		if len(retFiles) > 1 {
			for _, file := range retFiles {
				path := strings.TrimSuffix(source.Path, "/") + "/" + file.path
				log.Printf("Created asset: %s ...", path)
				files[path] = &mfs.File{file.data, file.modTime}
			}
			continue
		}

		// Process the single returned file
		file := retFiles[0]

		// Verify the file checksum if requested
		if source.Checksum != nil {
			err = verifyChecksum(source.Checksum, file.data)
			if err != nil {
				return nil, &ChecksumError{source.Location, err}
			}
		}

		// If the file is not an archive store it and finish processing.
		if source.Archive == nil {
			log.Printf("Created asset: %s ...", source.Path)
			files[source.Path] = &mfs.File{file.data, file.modTime}
			continue
		}

		// Extract files from the archive and store them.
		archFiles, err := processArchive(source.Archive, file.data)
		if err != nil {
			return nil, &ArchiveError{source.Location, err}
		}

		for _, file := range archFiles {
			log.Printf("Created asset: %s ...", file.path)
			files[file.path] = &mfs.File{file.data, file.modTime}
		}

	}

	fs, err := mfs.New(files)
	if err != nil {
		return nil, err
	}

	return httpfs.New(fs), nil
}

// Retrieve retrieves and processes the specified asset sources, and returns
// them using a http.FileSystem interface.

Retrieve retrieves and processes the specified asset sources and returns them using a http . FileSystem interface .


func Compile(sources []*Source, filePath string, pkgName string, varName string, opts *Opts) error {

	fs, err := Retrieve(sources)
	if err != nil {
		return err
	}

	if opts == nil {
		opts = &Opts{}
	}

	if opts.VariableComment == "" {
		opts.VariableComment = fmt.Sprintf("%s implements a http.FileSystem.", varName)
	}

	err = vfsgen.Generate(fs, vfsgen.Options{
		Filename:        filePath,
		PackageName:     pkgName,
		BuildTags:       opts.BuildTags,
		VariableName:    varName,
		VariableComment: opts.VariableComment,
	})
	if err != nil {
		return err
	}

	return nil
}

func Compile ( sources [ ] * Source , filePath string , pkgName string , varName string , opts * Opts ) error { fs , err := Retrieve ( sources ) if err != nil { return err } if opts == nil { opts = & Opts { } } if opts . VariableComment == " " { opts . VariableComment = fmt . Sprintf ( " " , varName ) } err = vfsgen . Generate ( fs , vfsgen . Options { Filename : filePath , PackageName : pkgName , BuildTags : opts . BuildTags , VariableName : varName , VariableComment : opts . VariableComment , } ) if err != nil { return err } return nil }

// Compile retrieves and processes the specified asset sources, and
// compiles them to the specified variable in the source file.

Compile retrieves and processes the specified asset sources and compiles them to the specified variable in the source file .


func readBlockAt(reader io.ReadSeeker, offset int64) (fileBlock, error) {
	var block fileBlock
	_, err := reader.Seek(offset, os.SEEK_SET)
	if err != nil {
		return block, err
	}
	return block, binary.Read(reader, binary.LittleEndian, &block)
}

func readBlockAt ( reader io . ReadSeeker , offset int64 ) ( fileBlock , error ) { var block fileBlock _ , err := reader . Seek ( offset , os . SEEK_SET ) if err != nil { return block , err } return block , binary . Read ( reader , binary . LittleEndian , & block ) }


func (fb *fileBlock) writeTo(writer io.WriteSeeker, offset int64) error {
	_, err := writer.Seek(offset, os.SEEK_SET)
	if err != nil {
		return err
	}
	return binary.Write(writer, binary.LittleEndian, *fb)
}

func ( fb * fileBlock ) writeTo ( writer io . WriteSeeker , offset int64 ) error { _ , err := writer . Seek ( offset , os . SEEK_SET ) if err != nil { return err } return binary . Write ( writer , binary . LittleEndian , * fb ) }


func (s *Stack) Push(header, data []byte) (depth int, err error) {
	s.guard.Lock()
	defer s.guard.Unlock()
	s.lastAccess = time.Now()
	file, err := s.getFile()
	if err != nil {
		return -1, err
	}
	// Seek to place for next block
	currentOffset, err := file.Seek(s.currentBlock.NextBlockPoint(), os.SEEK_SET)
	if err != nil {
		return -1, err
	}
	// Get place for payload
	bodyOffset := currentOffset + fileBlockDefineSize
	block := fileBlock{
		PrevBlock:   uint64(s.currentBlockPos),
		HeaderPoint: uint64(bodyOffset),
		HeaderSize:  uint64(len(header)),
		DataPoint:   uint64(bodyOffset) + uint64(len(header)),
		DataSize:    uint64(len(data)),
	}
	// Write block meta-info
	err = binary.Write(file, binary.LittleEndian, block)
	if err != nil {
		file.Seek(currentOffset, os.SEEK_SET)
		return -1, err
	}
	// Write header
	_, err = file.Write(header)
	if err != nil {
		file.Seek(currentOffset, os.SEEK_SET)
		return -1, err
	}
	// Write data
	_, err = file.Write(data)
	if err != nil {
		file.Seek(currentOffset, os.SEEK_SET)
		return -1, err
	}
	s.depth++
	s.currentBlockPos = currentOffset
	s.currentBlock = block
	return s.depth, nil
}

func
(
s
*
Stack
)
Push
(
header
,
data
[
]
byte
)
(
depth
int
,
err
error
)
{
s
.
guard
.
Lock
(
)
defer
s
.
guard
.
Unlock
(
)
s
.
lastAccess
=
time
.
Now
(
)
file
,
err
:=
s
.
getFile
(
)
if
err
!=
{
return
1
,
err
}
// Seek to place for next block
currentOffset
,
err
:=
file
.
Seek
(
s
.
currentBlock
.
NextBlockPoint
(
)
,
os
.
SEEK_SET
)
if
err
!=
{
return
1
,
err
}
// Get place for payload
bodyOffset
:=
currentOffset
+
fileBlockDefineSize
block
:=
fileBlock
{
PrevBlock
:
uint64
(
s
.
currentBlockPos
)
,
HeaderPoint
:
uint64
(
bodyOffset
)
,
HeaderSize
:
uint64
(
len
(
header
)
)
,
DataPoint
:
uint64
(
bodyOffset
)
+
uint64
(
len
(
header
)
)
,
DataSize
:
uint64
(
len
(
data
)
)
,
}
// Write block meta-info
err
=
binary
.
Write
(
file
,
binary
.
LittleEndian
,
block
)
if
err
!=
{
file
.
Seek
(
currentOffset
,
os
.
SEEK_SET
)
return
1
,
err
}
// Write header
_
,
err
=
file
.
Write
(
header
)
if
err
!=
{
file
.
Seek
(
currentOffset
,
os
.
SEEK_SET
)
return
1
,
err
}
// Write data
_
,
err
=
file
.
Write
(
data
)
if
err
!=
{
file
.
Seek
(
currentOffset
,
os
.
SEEK_SET
)
return
1
,
err
}
s
.
depth
++
s
.
currentBlockPos
=
currentOffset
s
.
currentBlock
=
block
return
s
.
depth
,
}

// Push header and body to stack. Returns new value of stack depth

Push header and body to stack . Returns new value of stack depth


func (s *Stack) Pop() (header, data []byte, err error) {
	if s.depth == 0 {
		return nil, nil, nil
	}
	s.guard.Lock()
	defer s.guard.Unlock()
	s.lastAccess = time.Now()
	file, err := s.getFile()
	if err != nil {
		return nil, nil, err
	}
	data = make([]byte, s.currentBlock.DataSize)
	header = make([]byte, s.currentBlock.HeaderSize)
	// Read header
	_, err = file.ReadAt(header, int64(s.currentBlock.HeaderPoint))
	if err != nil {
		return nil, nil, err
	}
	// Read data
	_, err = file.ReadAt(data, int64(s.currentBlock.DataPoint))
	if err != nil {
		return nil, nil, err
	}
	// Read new block if current block is not head
	var newBlock fileBlock
	if s.currentBlockPos != 0 {
		newBlock, err = readBlockAt(file, int64(s.currentBlock.PrevBlock))
		if err != nil {
			return nil, nil, err
		}
	}
	// Remove tail
	err = file.Truncate(int64(s.currentBlockPos))
	if err != nil {
		return nil, nil, err
	}
	s.depth--
	s.currentBlockPos = int64(s.currentBlock.PrevBlock)
	s.currentBlock = newBlock

	return header, data, nil
}

// Pop one segment from tail of stack. Returns nil,nil,nil if depth is 0

Pop one segment from tail of stack . Returns nil nil nil if depth is 0


func (s *Stack) Peak() (header, data []byte, err error) {
	if s.depth == 0 {
		return nil, nil, nil
	}
	s.guard.Lock()
	defer s.guard.Unlock()
	s.lastAccess = time.Now()
	file, err := s.getFile()
	if err != nil {
		return nil, nil, err
	}
	data = make([]byte, s.currentBlock.DataSize)
	header = make([]byte, s.currentBlock.HeaderSize)
	// Read header
	_, err = file.ReadAt(header, int64(s.currentBlock.HeaderPoint))
	if err != nil {
		return nil, nil, err
	}
	// Read data
	_, err = file.ReadAt(data, int64(s.currentBlock.DataPoint))
	if err != nil {
		return nil, nil, err
	}
	return header, data, nil
}

func
(
s
*
Stack
)
Peak
(
)
(
header
,
data
[
]
byte
,
err
error
)
{
if
s
.
depth
==
0
{
return
,
,
}
s
.
guard
.
Lock
(
)
defer
s
.
guard
.
Unlock
(
)
s
.
lastAccess
=
time
.
Now
(
)
file
,
err
:=
s
.
getFile
(
)
if
err
!=
{
return
,
,
err
}
data
=
make
(
[
]
byte
,
s
.
currentBlock
.
DataSize
)
header
=
make
(
[
]
byte
,
s
.
currentBlock
.
HeaderSize
)
// Read header
_
,
err
=
file
.
ReadAt
(
header
,
int64
(
s
.
currentBlock
.
HeaderPoint
)
)
if
err
!=
{
return
,
,
err
}
// Read data
_
,
err
=
file
.
ReadAt
(
data
,
int64
(
s
.
currentBlock
.
DataPoint
)
)
if
err
!=
{
return
,
,
err
}
return
header
,
data
,
}

// Peak of stack - get one segment from stack but not remove


func (s *Stack) PeakHeader() (header []byte, err error) {
	if s.depth == 0 {
		return nil, nil
	}
	s.guard.Lock()
	defer s.guard.Unlock()
	s.lastAccess = time.Now()
	file, err := s.getFile()
	if err != nil {
		return nil, err
	}
	header = make([]byte, s.currentBlock.HeaderSize)
	// Read header
	_, err = file.ReadAt(header, int64(s.currentBlock.HeaderPoint))
	if err != nil {
		return nil, err
	}
	return header, nil
}

func
(
s
*
Stack
)
PeakHeader
(
)
(
header
[
]
byte
,
err
error
)
{
if
s
.
depth
==
0
{
return
,
}
s
.
guard
.
Lock
(
)
defer
s
.
guard
.
Unlock
(
)
s
.
lastAccess
=
time
.
Now
(
)
file
,
err
:=
s
.
getFile
(
)
if
err
!=
{
return
,
err
}
header
=
make
(
[
]
byte
,
s
.
currentBlock
.
HeaderSize
)
// Read header
_
,
err
=
file
.
ReadAt
(
header
,
int64
(
s
.
currentBlock
.
HeaderPoint
)
)
if
err
!=
{
return
,
err
}
return
header
,
}

// PeakHeader get only header part from tail segment from stack without remove


func (s *Stack) IterateBackward(handler func(depth int, header io.Reader, body io.Reader) bool) error {
	s.guard.Lock()
	defer s.guard.Unlock()
	if s.depth == 0 {
		return nil
	}
	file, err := s.getFile()
	if err != nil {
		return err
	}
	defer file.Seek(0, os.SEEK_END)
	var (
		currentBlock       fileBlock // Current block description
		currentBlockOffset uint64    // Current block offset from begining of file
	)
	currentBlock = s.currentBlock
	currentBlockOffset = uint64(s.currentBlockPos)
	depth := s.depth
	for {
		body := io.NewSectionReader(file, int64(currentBlock.DataPoint), int64(currentBlock.DataSize))
		header := io.NewSectionReader(file, int64(currentBlock.HeaderPoint), int64(currentBlock.HeaderSize))
		// invoke block processor
		if handler != nil && !handler(depth, header, body) {
			return nil
		}
		if currentBlock.PrevBlock > currentBlockOffset {
			log.Printf("Danger back-ref link: prev block %v has greater index then current %v", currentBlock.PrevBlock, currentBlockOffset)
		}

		depth--
		if currentBlock.PrevBlock == currentBlockOffset {
			// First block has prev block = 0
			break
		}
		currentBlockOffset = currentBlock.PrevBlock
		currentBlock, err = readBlockAt(file, int64(currentBlock.PrevBlock))
		if err != nil {
			return err
		}
	}
	if depth != 0 {
		log.Println("Broker back path detected at", depth, "depth index")
	}
	return nil
}

// IterateBackward - iterate over hole stack segment-by-segment from end to begining

IterateBackward - iterate over hole stack segment - by - segment from end to begining


func (s *Stack) IterateForward(handler func(depth int, header io.Reader, body io.Reader) bool) error {
	// This operation does not relies on depth counter, so can be used for repare
	s.guard.Lock()
	defer s.guard.Unlock()
	s.lastAccess = time.Now()
	file, err := s.getFile()
	if err != nil {
		return err
	}
	//Get file size
	fileSize, err := file.Seek(0, os.SEEK_END)
	if err != nil {
		return err
	}
	_, err = file.Seek(0, os.SEEK_SET)
	if err != nil {
		return err
	}
	defer file.Seek(0, os.SEEK_END)
	var (
		currentBlock       fileBlock // Current block description
		currentBlockOffset uint64    // Current block offset from begining of file
	)
	var depth int
	for currentBlock.NextBlockPoint() < fileSize {
		newPos := currentBlock.NextBlockPoint()
		if newPos > fileSize {
			log.Println("Bad reference to next block at", currentBlockOffset, "!trunc!")
			file.Truncate(int64(currentBlockOffset))
			break
		}
		block, err := readBlockAt(file, newPos)
		// Non-full meta-info?
		if err == io.EOF {
			log.Println("Broken meta info at", newPos, "!trunc!")
			file.Truncate(newPos)
			break
		}
		// I/O error
		if err != nil {
			log.Println("Can't read block at", newPos)
			return err
		}
		// Check back-ref
		if block.PrevBlock != currentBlockOffset {
			log.Println("Bad back reference", block.PrevBlock, "!=", currentBlockOffset, "!upd!")
			block.PrevBlock = currentBlockOffset
			block.writeTo(file, newPos)
		}
		// Update current state
		currentBlockOffset = uint64(newPos)
		currentBlock = block
		body := io.NewSectionReader(file, int64(currentBlock.DataPoint), int64(currentBlock.DataSize))
		header := io.NewSectionReader(file, int64(currentBlock.HeaderPoint), int64(currentBlock.HeaderSize))
		// invoke block processor
		if handler != nil && !handler(depth, header, body) {
			return nil
		}
		depth++
	}
	s.depth = depth
	s.currentBlock = currentBlock
	s.currentBlockPos = int64(currentBlockOffset)
	return nil
}

// IterateForward - iterate over hole stack segment-by-segment from begining to end. If all segments
// iterated stack may be repaired

IterateForward - iterate over hole stack segment - by - segment from begining to end . If all segments iterated stack may be repaired


func (s *Stack) Close() error {
	s.guard.Lock()
	defer s.guard.Unlock()
	if s.file != nil {
		err := s.file.Close()
		s.file = nil
		return err
	}
	return nil
}

func ( s * Stack ) Close ( ) error { s . guard . Lock ( ) defer s . guard . Unlock ( ) if s . file != nil { err := s . file . Close ( ) s . file = nil return err } return nil }

// Close backend stack file. If access is requried, file will automatically reopened

Close backend stack file . If access is requried file will automatically reopened


func OpenStack(filename string) (*Stack, error) {
	file, err := os.OpenFile(filename, os.O_CREATE|os.O_RDWR, 0755)
	if err != nil {
		return nil, err
	}
	return NewStack(file)
}

func OpenStack ( filename string ) ( * Stack , error ) { file , err := os . OpenFile ( filename , os . O_CREATE | os . O_RDWR , 0755 ) if err != nil { return nil , err } return NewStack ( file ) }