// 2020-06-29 // random sample golang code. // collected from different files, for counting character frequency purposes // source // git/go/src/container/heap/example_intheap_test.go // git/go/src/database/sql/sql.go // git/go/src/fmt/scan.go // git/go/src/image/image.go // git/go/src/net/dial.go // git/go/src/path/path.go // git/go/src/regexp/regexp.go // ssss--------------------------------------------------- // /Users/xah/git/go/src/container/heap/example_intheap_test.go // This example demonstrates an integer heap built using the heap interface. package heap_test import ( "container/heap" "fmt" ) // An IntHeap is a min-heap of ints. type IntHeap []int func (h IntHeap) Len() int { return len(h) } func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] } func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } func (h *IntHeap) Push(x interface{}) { // Push and Pop use pointer receivers because they modify the slice's length, // not just its contents. *h = append(*h, x.(int)) } func (h *IntHeap) Pop() interface{} { old := *h n := len(old) x := old[n-1] *h = old[0 : n-1] return x } // This example inserts several ints into an IntHeap, checks the minimum, // and removes them in order of priority. func Example_intHeap() { h := &IntHeap{2, 1, 5} heap.Init(h) heap.Push(h, 3) fmt.Printf("minimum: %d\n", (*h)[0]) for h.Len() > 0 { fmt.Printf("%d ", heap.Pop(h)) } // Output: // minimum: 1 // 1 2 3 5 } // ssss--------------------------------------------------- // /Users/xah/git/go/src/database/sql/sql.go // Copyright 2011 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package sql provides a generic interface around SQL (or SQL-like) // databases. // // The sql package must be used in conjunction with a database driver. // See https://golang.org/s/sqldrivers for a list of drivers. // // Drivers that do not support context cancelation will not return until // after the query is completed. // // For usage examples, see the wiki page at // https://golang.org/s/sqlwiki. package sql import ( "context" "database/sql/driver" "errors" "fmt" "io" "reflect" "runtime" "sort" "sync" "sync/atomic" "time" ) var ( driversMu sync.RWMutex drivers = make(map[string]driver.Driver) ) // nowFunc returns the current time; it's overridden in tests. var nowFunc = time.Now // Register makes a database driver available by the provided name. // If Register is called twice with the same name or if driver is nil, // it panics. func Register(name string, driver driver.Driver) { driversMu.Lock() defer driversMu.Unlock() if driver == nil { panic("sql: Register driver is nil") } if _, dup := drivers[name]; dup { panic("sql: Register called twice for driver " + name) } drivers[name] = driver } func unregisterAllDrivers() { driversMu.Lock() defer driversMu.Unlock() // For tests. drivers = make(map[string]driver.Driver) } // Drivers returns a sorted list of the names of the registered drivers. func Drivers() []string { driversMu.RLock() defer driversMu.RUnlock() var list []string for name := range drivers { list = append(list, name) } sort.Strings(list) return list } // A NamedArg is a named argument. NamedArg values may be used as // arguments to Query or Exec and bind to the corresponding named // parameter in the SQL statement. // // For a more concise way to create NamedArg values, see // the Named function. type NamedArg struct { _Named_Fields_Required struct{} // Name is the name of the parameter placeholder. // // If empty, the ordinal position in the argument list will be // used. // // Name must omit any symbol prefix. Name string // Value is the value of the parameter. // It may be assigned the same value types as the query // arguments. Value interface{} } // Named provides a more concise way to create NamedArg values. // // Example usage: // // db.ExecContext(ctx, ` // delete from Invoice // where // TimeCreated < @end // and TimeCreated >= @start;`, // sql.Named("start", startTime), // sql.Named("end", endTime), // ) func Named(name string, value interface{}) NamedArg { // This method exists because the go1compat promise // doesn't guarantee that structs don't grow more fields, // so unkeyed struct literals are a vet error. Thus, we don't // want to allow sql.NamedArg{name, value}. return NamedArg{Name: name, Value: value} } // IsolationLevel is the transaction isolation level used in TxOptions. type IsolationLevel int // Various isolation levels that drivers may support in BeginTx. // If a driver does not support a given isolation level an error may be returned. // // See https://en.wikipedia.org/wiki/Isolation_(database_systems)#Isolation_levels. const ( LevelDefault IsolationLevel = iota LevelReadUncommitted LevelReadCommitted LevelWriteCommitted LevelRepeatableRead LevelSnapshot LevelSerializable LevelLinearizable ) // TxOptions holds the transaction options to be used in DB.BeginTx. type TxOptions struct { // Isolation is the transaction isolation level. // If zero, the driver or database's default level is used. Isolation IsolationLevel ReadOnly bool } // RawBytes is a byte slice that holds a reference to memory owned by // the database itself. After a Scan into a RawBytes, the slice is only // valid until the next call to Next, Scan, or Close. type RawBytes []byte // NullString represents a string that may be null. // NullString implements the Scanner interface so // it can be used as a scan destination: // // var s NullString // err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s) // ... // if s.Valid { // // use s.String // } else { // // NULL value // } // type NullString struct { String string Valid bool // Valid is true if String is not NULL } // Scan implements the Scanner interface. func (ns *NullString) Scan(value interface{}) error { if value == nil { ns.String, ns.Valid = "", false return nil } ns.Valid = true return convertAssign(&ns.String, value) } // Value implements the driver Valuer interface. func (ns NullString) Value() (driver.Value, error) { if !ns.Valid { return nil, nil } return ns.String, nil } // NullInt64 represents an int64 that may be null. // NullInt64 implements the Scanner interface so // it can be used as a scan destination, similar to NullString. type NullInt64 struct { Int64 int64 Valid bool // Valid is true if Int64 is not NULL } // Scan implements the Scanner interface. func (n *NullInt64) Scan(value interface{}) error { if value == nil { n.Int64, n.Valid = 0, false return nil } n.Valid = true return convertAssign(&n.Int64, value) } // Value implements the driver Valuer interface. func (n NullInt64) Value() (driver.Value, error) { if !n.Valid { return nil, nil } return n.Int64, nil } // NullFloat64 represents a float64 that may be null. // NullFloat64 implements the Scanner interface so // it can be used as a scan destination, similar to NullString. type NullFloat64 struct { Float64 float64 Valid bool // Valid is true if Float64 is not NULL } // Scan implements the Scanner interface. func (n *NullFloat64) Scan(value interface{}) error { if value == nil { n.Float64, n.Valid = 0, false return nil } n.Valid = true return convertAssign(&n.Float64, value) } // Value implements the driver Valuer interface. func (n NullFloat64) Value() (driver.Value, error) { if !n.Valid { return nil, nil } return n.Float64, nil } // NullBool represents a bool that may be null. // NullBool implements the Scanner interface so // it can be used as a scan destination, similar to NullString. type NullBool struct { Bool bool Valid bool // Valid is true if Bool is not NULL } // Scan implements the Scanner interface. func (n *NullBool) Scan(value interface{}) error { if value == nil { n.Bool, n.Valid = false, false return nil } n.Valid = true return convertAssign(&n.Bool, value) } // Value implements the driver Valuer interface. func (n NullBool) Value() (driver.Value, error) { if !n.Valid { return nil, nil } return n.Bool, nil } // Scanner is an interface used by Scan. type Scanner interface { // Scan assigns a value from a database driver. // // The src value will be of one of the following types: // // int64 // float64 // bool // []byte // string // time.Time // nil - for NULL values // // An error should be returned if the value cannot be stored // without loss of information. Scan(src interface{}) error } // Out may be used to retrieve OUTPUT value parameters from stored procedures. // // Not all drivers and databases support OUTPUT value parameters. // // Example usage: // // var outArg string // _, err := db.ExecContext(ctx, "ProcName", sql.Named("Arg1", sql.Out{Dest: &outArg})) type Out struct { _Named_Fields_Required struct{} // Dest is a pointer to the value that will be set to the result of the // stored procedure's OUTPUT parameter. Dest interface{} // In is whether the parameter is an INOUT parameter. If so, the input value to the stored // procedure is the dereferenced value of Dest's pointer, which is then replaced with // the output value. In bool } // ErrNoRows is returned by Scan when QueryRow doesn't return a // row. In such a case, QueryRow returns a placeholder *Row value that // defers this error until a Scan. var ErrNoRows = errors.New("sql: no rows in result set") // DB is a database handle representing a pool of zero or more // underlying connections. It's safe for concurrent use by multiple // goroutines. // // The sql package creates and frees connections automatically; it // also maintains a free pool of idle connections. If the database has // a concept of per-connection state, such state can only be reliably // observed within a transaction. Once DB.Begin is called, the // returned Tx is bound to a single connection. Once Commit or // Rollback is called on the transaction, that transaction's // connection is returned to DB's idle connection pool. The pool size // can be controlled with SetMaxIdleConns. type DB struct { connector driver.Connector // numClosed is an atomic counter which represents a total number of // closed connections. Stmt.openStmt checks it before cleaning closed // connections in Stmt.css. numClosed uint64 mu sync.Mutex // protects following fields freeConn []*driverConn connRequests map[uint64]chan connRequest nextRequest uint64 // Next key to use in connRequests. numOpen int // number of opened and pending open connections // Used to signal the need for new connections // a goroutine running connectionOpener() reads on this chan and // maybeOpenNewConnections sends on the chan (one send per needed connection) // It is closed during db.Close(). The close tells the connectionOpener // goroutine to exit. openerCh chan struct{} resetterCh chan *driverConn closed bool dep map[finalCloser]depSet lastPut map[*driverConn]string // stacktrace of last conn's put; debug only maxIdle int // zero means defaultMaxIdleConns; negative means 0 maxOpen int // <= 0 means unlimited maxLifetime time.Duration // maximum amount of time a connection may be reused cleanerCh chan struct{} stop func() // stop cancels the connection opener and the session resetter. } // connReuseStrategy determines how (*DB).conn returns database connections. type connReuseStrategy uint8 const ( // alwaysNewConn forces a new connection to the database. alwaysNewConn connReuseStrategy = iota // cachedOrNewConn returns a cached connection, if available, else waits // for one to become available (if MaxOpenConns has been reached) or // creates a new database connection. cachedOrNewConn ) // driverConn wraps a driver.Conn with a mutex, to // be held during all calls into the Conn. (including any calls onto // interfaces returned via that Conn, such as calls on Tx, Stmt, // Result, Rows) type driverConn struct { db *DB createdAt time.Time sync.Mutex // guards following ci driver.Conn closed bool finalClosed bool // ci.Close has been called openStmt map[*driverStmt]bool lastErr error // lastError captures the result of the session resetter. // guarded by db.mu inUse bool onPut []func() // code (with db.mu held) run when conn is next returned dbmuClosed bool // same as closed, but guarded by db.mu, for removeClosedStmtLocked } func (dc *driverConn) releaseConn(err error) { dc.db.putConn(dc, err, true) } func (dc *driverConn) removeOpenStmt(ds *driverStmt) { dc.Lock() defer dc.Unlock() delete(dc.openStmt, ds) } func (dc *driverConn) expired(timeout time.Duration) bool { if timeout <= 0 { return false } return dc.createdAt.Add(timeout).Before(nowFunc()) } // prepareLocked prepares the query on dc. When cg == nil the dc must keep track of // the prepared statements in a pool. func (dc *driverConn) prepareLocked(ctx context.Context, cg stmtConnGrabber, query string) (*driverStmt, error) { si, err := ctxDriverPrepare(ctx, dc.ci, query) if err != nil { return nil, err } ds := &driverStmt{Locker: dc, si: si} // No need to manage open statements if there is a single connection grabber. if cg != nil { return ds, nil } // Track each driverConn's open statements, so we can close them // before closing the conn. // // Wrap all driver.Stmt is *driverStmt to ensure they are only closed once. if dc.openStmt == nil { dc.openStmt = make(map[*driverStmt]bool) } dc.openStmt[ds] = true return ds, nil } // resetSession resets the connection session and sets the lastErr // that is checked before returning the connection to another query. // // resetSession assumes that the embedded mutex is locked when the connection // was returned to the pool. This unlocks the mutex. func (dc *driverConn) resetSession(ctx context.Context) { defer dc.Unlock() // In case of panic. if dc.closed { // Check if the database has been closed. return } dc.lastErr = dc.ci.(driver.SessionResetter).ResetSession(ctx) } // the dc.db's Mutex is held. func (dc *driverConn) closeDBLocked() func() error { dc.Lock() defer dc.Unlock() if dc.closed { return func() error { return errors.New("sql: duplicate driverConn close") } } dc.closed = true return dc.db.removeDepLocked(dc, dc) } func (dc *driverConn) Close() error { dc.Lock() if dc.closed { dc.Unlock() return errors.New("sql: duplicate driverConn close") } dc.closed = true dc.Unlock() // not defer; removeDep finalClose calls may need to lock // And now updates that require holding dc.mu.Lock. dc.db.mu.Lock() dc.dbmuClosed = true fn := dc.db.removeDepLocked(dc, dc) dc.db.mu.Unlock() return fn() } func (dc *driverConn) finalClose() error { var err error // Each *driverStmt has a lock to the dc. Copy the list out of the dc // before calling close on each stmt. var openStmt []*driverStmt withLock(dc, func() { openStmt = make([]*driverStmt, 0, len(dc.openStmt)) for ds := range dc.openStmt { openStmt = append(openStmt, ds) } dc.openStmt = nil }) for _, ds := range openStmt { ds.Close() } withLock(dc, func() { dc.finalClosed = true err = dc.ci.Close() dc.ci = nil }) dc.db.mu.Lock() dc.db.numOpen-- dc.db.maybeOpenNewConnections() dc.db.mu.Unlock() atomic.AddUint64(&dc.db.numClosed, 1) return err } // driverStmt associates a driver.Stmt with the // *driverConn from which it came, so the driverConn's lock can be // held during calls. type driverStmt struct { sync.Locker // the *driverConn si driver.Stmt closed bool closeErr error // return value of previous Close call } // Close ensures dirver.Stmt is only closed once any always returns the same // result. func (ds *driverStmt) Close() error { ds.Lock() defer ds.Unlock() if ds.closed { return ds.closeErr } ds.closed = true ds.closeErr = ds.si.Close() return ds.closeErr } // depSet is a finalCloser's outstanding dependencies type depSet map[interface{}]bool // set of true bools // The finalCloser interface is used by (*DB).addDep and related // dependency reference counting. type finalCloser interface { // finalClose is called when the reference count of an object // goes to zero. (*DB).mu is not held while calling it. finalClose() error } // addDep notes that x now depends on dep, and x's finalClose won't be // called until all of x's dependencies are removed with removeDep. func (db *DB) addDep(x finalCloser, dep interface{}) { //println(fmt.Sprintf("addDep(%T %p, %T %p)", x, x, dep, dep)) db.mu.Lock() defer db.mu.Unlock() db.addDepLocked(x, dep) } func (db *DB) addDepLocked(x finalCloser, dep interface{}) { if db.dep == nil { db.dep = make(map[finalCloser]depSet) } xdep := db.dep[x] if xdep == nil { xdep = make(depSet) db.dep[x] = xdep } xdep[dep] = true } // removeDep notes that x no longer depends on dep. // If x still has dependencies, nil is returned. // If x no longer has any dependencies, its finalClose method will be // called and its error value will be returned. func (db *DB) removeDep(x finalCloser, dep interface{}) error { db.mu.Lock() fn := db.removeDepLocked(x, dep) db.mu.Unlock() return fn() } func (db *DB) removeDepLocked(x finalCloser, dep interface{}) func() error { //println(fmt.Sprintf("removeDep(%T %p, %T %p)", x, x, dep, dep)) xdep, ok := db.dep[x] if !ok { panic(fmt.Sprintf("unpaired removeDep: no deps for %T", x)) } l0 := len(xdep) delete(xdep, dep) switch len(xdep) { case l0: // Nothing removed. Shouldn't happen. panic(fmt.Sprintf("unpaired removeDep: no %T dep on %T", dep, x)) case 0: // No more dependencies. delete(db.dep, x) return x.finalClose default: // Dependencies remain. return func() error { return nil } } } // This is the size of the connectionOpener request chan (DB.openerCh). // This value should be larger than the maximum typical value // used for db.maxOpen. If maxOpen is significantly larger than // connectionRequestQueueSize then it is possible for ALL calls into the *DB // to block until the connectionOpener can satisfy the backlog of requests. var connectionRequestQueueSize = 1000000 type dsnConnector struct { dsn string driver driver.Driver } func (t dsnConnector) Connect(_ context.Context) (driver.Conn, error) { return t.driver.Open(t.dsn) } func (t dsnConnector) Driver() driver.Driver { return t.driver } // OpenDB opens a database using a Connector, allowing drivers to // bypass a string based data source name. // // Most users will open a database via a driver-specific connection // helper function that returns a *DB. No database drivers are included // in the Go standard library. See https://golang.org/s/sqldrivers for // a list of third-party drivers. // // OpenDB may just validate its arguments without creating a connection // to the database. To verify that the data source name is valid, call // Ping. // // The returned DB is safe for concurrent use by multiple goroutines // and maintains its own pool of idle connections. Thus, the OpenDB // function should be called just once. It is rarely necessary to // close a DB. func OpenDB(c driver.Connector) *DB { ctx, cancel := context.WithCancel(context.Background()) db := &DB{ connector: c, openerCh: make(chan struct{}, connectionRequestQueueSize), resetterCh: make(chan *driverConn, 50), lastPut: make(map[*driverConn]string), connRequests: make(map[uint64]chan connRequest), stop: cancel, } go db.connectionOpener(ctx) go db.connectionResetter(ctx) return db } // Open opens a database specified by its database driver name and a // driver-specific data source name, usually consisting of at least a // database name and connection information. // // Most users will open a database via a driver-specific connection // helper function that returns a *DB. No database drivers are included // in the Go standard library. See https://golang.org/s/sqldrivers for // a list of third-party drivers. // // Open may just validate its arguments without creating a connection // to the database. To verify that the data source name is valid, call // Ping. // // The returned DB is safe for concurrent use by multiple goroutines // and maintains its own pool of idle connections. Thus, the Open // function should be called just once. It is rarely necessary to // close a DB. func Open(driverName, dataSourceName string) (*DB, error) { driversMu.RLock() driveri, ok := drivers[driverName] driversMu.RUnlock() if !ok { return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName) } if driverCtx, ok := driveri.(driver.DriverContext); ok { connector, err := driverCtx.OpenConnector(dataSourceName) if err != nil { return nil, err } return OpenDB(connector), nil } return OpenDB(dsnConnector{dsn: dataSourceName, driver: driveri}), nil } func (db *DB) pingDC(ctx context.Context, dc *driverConn, release func(error)) error { var err error if pinger, ok := dc.ci.(driver.Pinger); ok { withLock(dc, func() { err = pinger.Ping(ctx) }) } release(err) return err } // PingContext verifies a connection to the database is still alive, // establishing a connection if necessary. func (db *DB) PingContext(ctx context.Context) error { var dc *driverConn var err error for i := 0; i < maxBadConnRetries; i++ { dc, err = db.conn(ctx, cachedOrNewConn) if err != driver.ErrBadConn { break } } if err == driver.ErrBadConn { dc, err = db.conn(ctx, alwaysNewConn) } if err != nil { return err } return db.pingDC(ctx, dc, dc.releaseConn) } // Ping verifies a connection to the database is still alive, // establishing a connection if necessary. func (db *DB) Ping() error { return db.PingContext(context.Background()) } // Close closes the database, releasing any open resources. // // It is rare to Close a DB, as the DB handle is meant to be // long-lived and shared between many goroutines. func (db *DB) Close() error { db.mu.Lock() if db.closed { // Make DB.Close idempotent db.mu.Unlock() return nil } if db.cleanerCh != nil { close(db.cleanerCh) } var err error fns := make([]func() error, 0, len(db.freeConn)) for _, dc := range db.freeConn { fns = append(fns, dc.closeDBLocked()) } db.freeConn = nil db.closed = true for _, req := range db.connRequests { close(req) } db.mu.Unlock() for _, fn := range fns { err1 := fn() if err1 != nil { err = err1 } } db.stop() return err } const defaultMaxIdleConns = 2 func (db *DB) maxIdleConnsLocked() int { n := db.maxIdle switch { case n == 0: // TODO(bradfitz): ask driver, if supported, for its default preference return defaultMaxIdleConns case n < 0: return 0 default: return n } } // SetMaxIdleConns sets the maximum number of connections in the idle // connection pool. // // If MaxOpenConns is greater than 0 but less than the new MaxIdleConns // then the new MaxIdleConns will be reduced to match the MaxOpenConns limit // // If n <= 0, no idle connections are retained. func (db *DB) SetMaxIdleConns(n int) { db.mu.Lock() if n > 0 { db.maxIdle = n } else { // No idle connections. db.maxIdle = -1 } // Make sure maxIdle doesn't exceed maxOpen if db.maxOpen > 0 && db.maxIdleConnsLocked() > db.maxOpen { db.maxIdle = db.maxOpen } var closing []*driverConn idleCount := len(db.freeConn) maxIdle := db.maxIdleConnsLocked() if idleCount > maxIdle { closing = db.freeConn[maxIdle:] db.freeConn = db.freeConn[:maxIdle] } db.mu.Unlock() for _, c := range closing { c.Close() } } // SetMaxOpenConns sets the maximum number of open connections to the database. // // If MaxIdleConns is greater than 0 and the new MaxOpenConns is less than // MaxIdleConns, then MaxIdleConns will be reduced to match the new // MaxOpenConns limit // // If n <= 0, then there is no limit on the number of open connections. // The default is 0 (unlimited). func (db *DB) SetMaxOpenConns(n int) { db.mu.Lock() db.maxOpen = n if n < 0 { db.maxOpen = 0 } syncMaxIdle := db.maxOpen > 0 && db.maxIdleConnsLocked() > db.maxOpen db.mu.Unlock() if syncMaxIdle { db.SetMaxIdleConns(n) } } // SetConnMaxLifetime sets the maximum amount of time a connection may be reused. // // Expired connections may be closed lazily before reuse. // // If d <= 0, connections are reused forever. func (db *DB) SetConnMaxLifetime(d time.Duration) { if d < 0 { d = 0 } db.mu.Lock() // wake cleaner up when lifetime is shortened. if d > 0 && d < db.maxLifetime && db.cleanerCh != nil { select { case db.cleanerCh <- struct{}{}: default: } } db.maxLifetime = d db.startCleanerLocked() db.mu.Unlock() } // startCleanerLocked starts connectionCleaner if needed. func (db *DB) startCleanerLocked() { if db.maxLifetime > 0 && db.numOpen > 0 && db.cleanerCh == nil { db.cleanerCh = make(chan struct{}, 1) go db.connectionCleaner(db.maxLifetime) } } func (db *DB) connectionCleaner(d time.Duration) { const minInterval = time.Second if d < minInterval { d = minInterval } t := time.NewTimer(d) for { select { case <-t.C: case <-db.cleanerCh: // maxLifetime was changed or db was closed. } db.mu.Lock() d = db.maxLifetime if db.closed || db.numOpen == 0 || d <= 0 { db.cleanerCh = nil db.mu.Unlock() return } expiredSince := nowFunc().Add(-d) var closing []*driverConn for i := 0; i < len(db.freeConn); i++ { c := db.freeConn[i] if c.createdAt.Before(expiredSince) { closing = append(closing, c) last := len(db.freeConn) - 1 db.freeConn[i] = db.freeConn[last] db.freeConn[last] = nil db.freeConn = db.freeConn[:last] i-- } } db.mu.Unlock() for _, c := range closing { c.Close() } if d < minInterval { d = minInterval } t.Reset(d) } } // DBStats contains database statistics. type DBStats struct { // OpenConnections is the number of open connections to the database. OpenConnections int } // Stats returns database statistics. func (db *DB) Stats() DBStats { db.mu.Lock() stats := DBStats{ OpenConnections: db.numOpen, } db.mu.Unlock() return stats } // Assumes db.mu is locked. // If there are connRequests and the connection limit hasn't been reached, // then tell the connectionOpener to open new connections. func (db *DB) maybeOpenNewConnections() { numRequests := len(db.connRequests) if db.maxOpen > 0 { numCanOpen := db.maxOpen - db.numOpen if numRequests > numCanOpen { numRequests = numCanOpen } } for numRequests > 0 { db.numOpen++ // optimistically numRequests-- if db.closed { return } db.openerCh <- struct{}{} } } // Runs in a separate goroutine, opens new connections when requested. func (db *DB) connectionOpener(ctx context.Context) { for { select { case <-ctx.Done(): return case <-db.openerCh: db.openNewConnection(ctx) } } } // connectionResetter runs in a separate goroutine to reset connections async // to exported API. func (db *DB) connectionResetter(ctx context.Context) { for { select { case <-ctx.Done(): close(db.resetterCh) for dc := range db.resetterCh { dc.Unlock() } return case dc := <-db.resetterCh: dc.resetSession(ctx) } } } // Open one new connection func (db *DB) openNewConnection(ctx context.Context) { // maybeOpenNewConnctions has already executed db.numOpen++ before it sent // on db.openerCh. This function must execute db.numOpen-- if the // connection fails or is closed before returning. ci, err := db.connector.Connect(ctx) db.mu.Lock() defer db.mu.Unlock() if db.closed { if err == nil { ci.Close() } db.numOpen-- return } if err != nil { db.numOpen-- db.putConnDBLocked(nil, err) db.maybeOpenNewConnections() return } dc := &driverConn{ db: db, createdAt: nowFunc(), ci: ci, } if db.putConnDBLocked(dc, err) { db.addDepLocked(dc, dc) } else { db.numOpen-- ci.Close() } } // connRequest represents one request for a new connection // When there are no idle connections available, DB.conn will create // a new connRequest and put it on the db.connRequests list. type connRequest struct { conn *driverConn err error } var errDBClosed = errors.New("sql: database is closed") // nextRequestKeyLocked returns the next connection request key. // It is assumed that nextRequest will not overflow. func (db *DB) nextRequestKeyLocked() uint64 { next := db.nextRequest db.nextRequest++ return next } // conn returns a newly-opened or cached *driverConn. func (db *DB) conn(ctx context.Context, strategy connReuseStrategy) (*driverConn, error) { db.mu.Lock() if db.closed { db.mu.Unlock() return nil, errDBClosed } // Check if the context is expired. select { default: case <-ctx.Done(): db.mu.Unlock() return nil, ctx.Err() } lifetime := db.maxLifetime // Prefer a free connection, if possible. numFree := len(db.freeConn) if strategy == cachedOrNewConn && numFree > 0 { conn := db.freeConn[0] copy(db.freeConn, db.freeConn[1:]) db.freeConn = db.freeConn[:numFree-1] conn.inUse = true db.mu.Unlock() if conn.expired(lifetime) { conn.Close() return nil, driver.ErrBadConn } // Lock around reading lastErr to ensure the session resetter finished. conn.Lock() err := conn.lastErr conn.Unlock() if err == driver.ErrBadConn { conn.Close() return nil, driver.ErrBadConn } return conn, nil } // Out of free connections or we were asked not to use one. If we're not // allowed to open any more connections, make a request and wait. if db.maxOpen > 0 && db.numOpen >= db.maxOpen { // Make the connRequest channel. It's buffered so that the // connectionOpener doesn't block while waiting for the req to be read. req := make(chan connRequest, 1) reqKey := db.nextRequestKeyLocked() db.connRequests[reqKey] = req db.mu.Unlock() // Timeout the connection request with the context. select { case <-ctx.Done(): // Remove the connection request and ensure no value has been sent // on it after removing. db.mu.Lock() delete(db.connRequests, reqKey) db.mu.Unlock() select { default: case ret, ok := <-req: if ok { db.putConn(ret.conn, ret.err, false) } } return nil, ctx.Err() case ret, ok := <-req: if !ok { return nil, errDBClosed } if ret.err == nil && ret.conn.expired(lifetime) { ret.conn.Close() return nil, driver.ErrBadConn } if ret.conn == nil { return nil, ret.err } // Lock around reading lastErr to ensure the session resetter finished. ret.conn.Lock() err := ret.conn.lastErr ret.conn.Unlock() if err == driver.ErrBadConn { ret.conn.Close() return nil, driver.ErrBadConn } return ret.conn, ret.err } } db.numOpen++ // optimistically db.mu.Unlock() ci, err := db.connector.Connect(ctx) if err != nil { db.mu.Lock() db.numOpen-- // correct for earlier optimism db.maybeOpenNewConnections() db.mu.Unlock() return nil, err } db.mu.Lock() dc := &driverConn{ db: db, createdAt: nowFunc(), ci: ci, inUse: true, } db.addDepLocked(dc, dc) db.mu.Unlock() return dc, nil } // putConnHook is a hook for testing. var putConnHook func(*DB, *driverConn) // noteUnusedDriverStatement notes that ds is no longer used and should // be closed whenever possible (when c is next not in use), unless c is // already closed. func (db *DB) noteUnusedDriverStatement(c *driverConn, ds *driverStmt) { db.mu.Lock() defer db.mu.Unlock() if c.inUse { c.onPut = append(c.onPut, func() { ds.Close() }) } else { c.Lock() fc := c.finalClosed c.Unlock() if !fc { ds.Close() } } } // debugGetPut determines whether getConn & putConn calls' stack traces // are returned for more verbose crashes. const debugGetPut = false // putConn adds a connection to the db's free pool. // err is optionally the last error that occurred on this connection. func (db *DB) putConn(dc *driverConn, err error, resetSession bool) { db.mu.Lock() if !dc.inUse { if debugGetPut { fmt.Printf("putConn(%v) DUPLICATE was: %s\n\nPREVIOUS was: %s", dc, stack(), db.lastPut[dc]) } panic("sql: connection returned that was never out") } if debugGetPut { db.lastPut[dc] = stack() } dc.inUse = false for _, fn := range dc.onPut { fn() } dc.onPut = nil if err == driver.ErrBadConn { // Don't reuse bad connections. // Since the conn is considered bad and is being discarded, treat it // as closed. Don't decrement the open count here, finalClose will // take care of that. db.maybeOpenNewConnections() db.mu.Unlock() dc.Close() return } if putConnHook != nil { putConnHook(db, dc) } if db.closed { // Connections do not need to be reset if they will be closed. // Prevents writing to resetterCh after the DB has closed. resetSession = false } if resetSession { if _, resetSession = dc.ci.(driver.SessionResetter); resetSession { // Lock the driverConn here so it isn't released until // the connection is reset. // The lock must be taken before the connection is put into // the pool to prevent it from being taken out before it is reset. dc.Lock() } } added := db.putConnDBLocked(dc, nil) db.mu.Unlock() if !added { if resetSession { dc.Unlock() } dc.Close() return } if !resetSession { return } select { default: // If the resetterCh is blocking then mark the connection // as bad and continue on. dc.lastErr = driver.ErrBadConn dc.Unlock() case db.resetterCh <- dc: } } // Satisfy a connRequest or put the driverConn in the idle pool and return true // or return false. // putConnDBLocked will satisfy a connRequest if there is one, or it will // return the *driverConn to the freeConn list if err == nil and the idle // connection limit will not be exceeded. // If err != nil, the value of dc is ignored. // If err == nil, then dc must not equal nil. // If a connRequest was fulfilled or the *driverConn was placed in the // freeConn list, then true is returned, otherwise false is returned. func (db *DB) putConnDBLocked(dc *driverConn, err error) bool { if db.closed { return false } if db.maxOpen > 0 && db.numOpen > db.maxOpen { return false } if c := len(db.connRequests); c > 0 { var req chan connRequest var reqKey uint64 for reqKey, req = range db.connRequests { break } delete(db.connRequests, reqKey) // Remove from pending requests. if err == nil { dc.inUse = true } req <- connRequest{ conn: dc, err: err, } return true } else if err == nil && !db.closed && db.maxIdleConnsLocked() > len(db.freeConn) { db.freeConn = append(db.freeConn, dc) db.startCleanerLocked() return true } return false } // maxBadConnRetries is the number of maximum retries if the driver returns // driver.ErrBadConn to signal a broken connection before forcing a new // connection to be opened. const maxBadConnRetries = 2 // PrepareContext creates a prepared statement for later queries or executions. // Multiple queries or executions may be run concurrently from the // returned statement. // The caller must call the statement's Close method // when the statement is no longer needed. // // The provided context is used for the preparation of the statement, not for the // execution of the statement. func (db *DB) PrepareContext(ctx context.Context, query string) (*Stmt, error) { var stmt *Stmt var err error for i := 0; i < maxBadConnRetries; i++ { stmt, err = db.prepare(ctx, query, cachedOrNewConn) if err != driver.ErrBadConn { break } } if err == driver.ErrBadConn { return db.prepare(ctx, query, alwaysNewConn) } return stmt, err } // Prepare creates a prepared statement for later queries or executions. // Multiple queries or executions may be run concurrently from the // returned statement. // The caller must call the statement's Close method // when the statement is no longer needed. func (db *DB) Prepare(query string) (*Stmt, error) { return db.PrepareContext(context.Background(), query) } func (db *DB) prepare(ctx context.Context, query string, strategy connReuseStrategy) (*Stmt, error) { // TODO: check if db.driver supports an optional // driver.Preparer interface and call that instead, if so, // otherwise we make a prepared statement that's bound // to a connection, and to execute this prepared statement // we either need to use this connection (if it's free), else // get a new connection + re-prepare + execute on that one. dc, err := db.conn(ctx, strategy) if err != nil { return nil, err } return db.prepareDC(ctx, dc, dc.releaseConn, nil, query) } // prepareDC prepares a query on the driverConn and calls release before // returning. When cg == nil it implies that a connection pool is used, and // when cg != nil only a single driver connection is used. func (db *DB) prepareDC(ctx context.Context, dc *driverConn, release func(error), cg stmtConnGrabber, query string) (*Stmt, error) { var ds *driverStmt var err error defer func() { release(err) }() withLock(dc, func() { ds, err = dc.prepareLocked(ctx, cg, query) }) if err != nil { return nil, err } stmt := &Stmt{ db: db, query: query, cg: cg, cgds: ds, } // When cg == nil this statement will need to keep track of various // connections they are prepared on and record the stmt dependency on // the DB. if cg == nil { stmt.css = []connStmt{{dc, ds}} stmt.lastNumClosed = atomic.LoadUint64(&db.numClosed) db.addDep(stmt, stmt) } return stmt, nil } // ExecContext executes a query without returning any rows. // The args are for any placeholder parameters in the query. func (db *DB) ExecContext(ctx context.Context, query string, args ...interface{}) (Result, error) { var res Result var err error for i := 0; i < maxBadConnRetries; i++ { res, err = db.exec(ctx, query, args, cachedOrNewConn) if err != driver.ErrBadConn { break } } if err == driver.ErrBadConn { return db.exec(ctx, query, args, alwaysNewConn) } return res, err } // Exec executes a query without returning any rows. // The args are for any placeholder parameters in the query. func (db *DB) Exec(query string, args ...interface{}) (Result, error) { return db.ExecContext(context.Background(), query, args...) } func (db *DB) exec(ctx context.Context, query string, args []interface{}, strategy connReuseStrategy) (Result, error) { dc, err := db.conn(ctx, strategy) if err != nil { return nil, err } return db.execDC(ctx, dc, dc.releaseConn, query, args) } func (db *DB) execDC(ctx context.Context, dc *driverConn, release func(error), query string, args []interface{}) (res Result, err error) { defer func() { release(err) }() execerCtx, ok := dc.ci.(driver.ExecerContext) var execer driver.Execer if !ok { execer, ok = dc.ci.(driver.Execer) } if ok { var nvdargs []driver.NamedValue var resi driver.Result withLock(dc, func() { nvdargs, err = driverArgsConnLocked(dc.ci, nil, args) if err != nil { return } resi, err = ctxDriverExec(ctx, execerCtx, execer, query, nvdargs) }) if err != driver.ErrSkip { if err != nil { return nil, err } return driverResult{dc, resi}, nil } } var si driver.Stmt withLock(dc, func() { si, err = ctxDriverPrepare(ctx, dc.ci, query) }) if err != nil { return nil, err } ds := &driverStmt{Locker: dc, si: si} defer ds.Close() return resultFromStatement(ctx, dc.ci, ds, args...) } // QueryContext executes a query that returns rows, typically a SELECT. // The args are for any placeholder parameters in the query. func (db *DB) QueryContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) { var rows *Rows var err error for i := 0; i < maxBadConnRetries; i++ { rows, err = db.query(ctx, query, args, cachedOrNewConn) if err != driver.ErrBadConn { break } } if err == driver.ErrBadConn { return db.query(ctx, query, args, alwaysNewConn) } return rows, err } // Query executes a query that returns rows, typically a SELECT. // The args are for any placeholder parameters in the query. func (db *DB) Query(query string, args ...interface{}) (*Rows, error) { return db.QueryContext(context.Background(), query, args...) } func (db *DB) query(ctx context.Context, query string, args []interface{}, strategy connReuseStrategy) (*Rows, error) { dc, err := db.conn(ctx, strategy) if err != nil { return nil, err } return db.queryDC(ctx, nil, dc, dc.releaseConn, query, args) } // queryDC executes a query on the given connection. // The connection gets released by the releaseConn function. // The ctx context is from a query method and the txctx context is from an // optional transaction context. func (db *DB) queryDC(ctx, txctx context.Context, dc *driverConn, releaseConn func(error), query string, args []interface{}) (*Rows, error) { queryerCtx, ok := dc.ci.(driver.QueryerContext) var queryer driver.Queryer if !ok { queryer, ok = dc.ci.(driver.Queryer) } if ok { var nvdargs []driver.NamedValue var rowsi driver.Rows var err error withLock(dc, func() { nvdargs, err = driverArgsConnLocked(dc.ci, nil, args) if err != nil { return } rowsi, err = ctxDriverQuery(ctx, queryerCtx, queryer, query, nvdargs) }) if err != driver.ErrSkip { if err != nil { releaseConn(err) return nil, err } // Note: ownership of dc passes to the *Rows, to be freed // with releaseConn. rows := &Rows{ dc: dc, releaseConn: releaseConn, rowsi: rowsi, } rows.initContextClose(ctx, txctx) return rows, nil } } var si driver.Stmt var err error withLock(dc, func() { si, err = ctxDriverPrepare(ctx, dc.ci, query) }) if err != nil { releaseConn(err) return nil, err } ds := &driverStmt{Locker: dc, si: si} rowsi, err := rowsiFromStatement(ctx, dc.ci, ds, args...) if err != nil { ds.Close() releaseConn(err) return nil, err } // Note: ownership of ci passes to the *Rows, to be freed // with releaseConn. rows := &Rows{ dc: dc, releaseConn: releaseConn, rowsi: rowsi, closeStmt: ds, } rows.initContextClose(ctx, txctx) return rows, nil } // QueryRowContext executes a query that is expected to return at most one row. // QueryRowContext always returns a non-nil value. Errors are deferred until // Row's Scan method is called. // If the query selects no rows, the *Row's Scan will return ErrNoRows. // Otherwise, the *Row's Scan scans the first selected row and discards // the rest. func (db *DB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *Row { rows, err := db.QueryContext(ctx, query, args...) return &Row{rows: rows, err: err} } // QueryRow executes a query that is expected to return at most one row. // QueryRow always returns a non-nil value. Errors are deferred until // Row's Scan method is called. // If the query selects no rows, the *Row's Scan will return ErrNoRows. // Otherwise, the *Row's Scan scans the first selected row and discards // the rest. func (db *DB) QueryRow(query string, args ...interface{}) *Row { return db.QueryRowContext(context.Background(), query, args...) } // BeginTx starts a transaction. // // The provided context is used until the transaction is committed or rolled back. // If the context is canceled, the sql package will roll back // the transaction. Tx.Commit will return an error if the context provided to // BeginTx is canceled. // // The provided TxOptions is optional and may be nil if defaults should be used. // If a non-default isolation level is used that the driver doesn't support, // an error will be returned. func (db *DB) BeginTx(ctx context.Context, opts *TxOptions) (*Tx, error) { var tx *Tx var err error for i := 0; i < maxBadConnRetries; i++ { tx, err = db.begin(ctx, opts, cachedOrNewConn) if err != driver.ErrBadConn { break } } if err == driver.ErrBadConn { return db.begin(ctx, opts, alwaysNewConn) } return tx, err } // Begin starts a transaction. The default isolation level is dependent on // the driver. func (db *DB) Begin() (*Tx, error) { return db.BeginTx(context.Background(), nil) } func (db *DB) begin(ctx context.Context, opts *TxOptions, strategy connReuseStrategy) (tx *Tx, err error) { dc, err := db.conn(ctx, strategy) if err != nil { return nil, err } return db.beginDC(ctx, dc, dc.releaseConn, opts) } // beginDC starts a transaction. The provided dc must be valid and ready to use. func (db *DB) beginDC(ctx context.Context, dc *driverConn, release func(error), opts *TxOptions) (tx *Tx, err error) { var txi driver.Tx withLock(dc, func() { txi, err = ctxDriverBegin(ctx, opts, dc.ci) }) if err != nil { release(err) return nil, err } // Schedule the transaction to rollback when the context is cancelled. // The cancel function in Tx will be called after done is set to true. ctx, cancel := context.WithCancel(ctx) tx = &Tx{ db: db, dc: dc, releaseConn: release, txi: txi, cancel: cancel, ctx: ctx, } go tx.awaitDone() return tx, nil } // Driver returns the database's underlying driver. func (db *DB) Driver() driver.Driver { return db.connector.Driver() } // ErrConnDone is returned by any operation that is performed on a connection // that has already been returned to the connection pool. var ErrConnDone = errors.New("database/sql: connection is already closed") // Conn returns a single connection by either opening a new connection // or returning an existing connection from the connection pool. Conn will // block until either a connection is returned or ctx is canceled. // Queries run on the same Conn will be run in the same database session. // // Every Conn must be returned to the database pool after use by // calling Conn.Close. func (db *DB) Conn(ctx context.Context) (*Conn, error) { var dc *driverConn var err error for i := 0; i < maxBadConnRetries; i++ { dc, err = db.conn(ctx, cachedOrNewConn) if err != driver.ErrBadConn { break } } if err == driver.ErrBadConn { dc, err = db.conn(ctx, cachedOrNewConn) } if err != nil { return nil, err } conn := &Conn{ db: db, dc: dc, } return conn, nil } type releaseConn func(error) // Conn represents a single database connection rather than a pool of database // connections. Prefer running queries from DB unless there is a specific // need for a continuous single database connection. // // A Conn must call Close to return the connection to the database pool // and may do so concurrently with a running query. // // After a call to Close, all operations on the // connection fail with ErrConnDone. type Conn struct { db *DB // closemu prevents the connection from closing while there // is an active query. It is held for read during queries // and exclusively during close. closemu sync.RWMutex // dc is owned until close, at which point // it's returned to the connection pool. dc *driverConn // done transitions from 0 to 1 exactly once, on close. // Once done, all operations fail with ErrConnDone. // Use atomic operations on value when checking value. done int32 } func (c *Conn) grabConn(context.Context) (*driverConn, releaseConn, error) { if atomic.LoadInt32(&c.done) != 0 { return nil, nil, ErrConnDone } c.closemu.RLock() return c.dc, c.closemuRUnlockCondReleaseConn, nil } // PingContext verifies the connection to the database is still alive. func (c *Conn) PingContext(ctx context.Context) error { dc, release, err := c.grabConn(ctx) if err != nil { return err } return c.db.pingDC(ctx, dc, release) } // ExecContext executes a query without returning any rows. // The args are for any placeholder parameters in the query. func (c *Conn) ExecContext(ctx context.Context, query string, args ...interface{}) (Result, error) { dc, release, err := c.grabConn(ctx) if err != nil { return nil, err } return c.db.execDC(ctx, dc, release, query, args) } // QueryContext executes a query that returns rows, typically a SELECT. // The args are for any placeholder parameters in the query. func (c *Conn) QueryContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) { dc, release, err := c.grabConn(ctx) if err != nil { return nil, err } return c.db.queryDC(ctx, nil, dc, release, query, args) } // QueryRowContext executes a query that is expected to return at most one row. // QueryRowContext always returns a non-nil value. Errors are deferred until // Row's Scan method is called. // If the query selects no rows, the *Row's Scan will return ErrNoRows. // Otherwise, the *Row's Scan scans the first selected row and discards // the rest. func (c *Conn) QueryRowContext(ctx context.Context, query string, args ...interface{}) *Row { rows, err := c.QueryContext(ctx, query, args...) return &Row{rows: rows, err: err} } // PrepareContext creates a prepared statement for later queries or executions. // Multiple queries or executions may be run concurrently from the // returned statement. // The caller must call the statement's Close method // when the statement is no longer needed. // // The provided context is used for the preparation of the statement, not for the // execution of the statement. func (c *Conn) PrepareContext(ctx context.Context, query string) (*Stmt, error) { dc, release, err := c.grabConn(ctx) if err != nil { return nil, err } return c.db.prepareDC(ctx, dc, release, c, query) } // BeginTx starts a transaction. // // The provided context is used until the transaction is committed or rolled back. // If the context is canceled, the sql package will roll back // the transaction. Tx.Commit will return an error if the context provided to // BeginTx is canceled. // // The provided TxOptions is optional and may be nil if defaults should be used. // If a non-default isolation level is used that the driver doesn't support, // an error will be returned. func (c *Conn) BeginTx(ctx context.Context, opts *TxOptions) (*Tx, error) { dc, release, err := c.grabConn(ctx) if err != nil { return nil, err } return c.db.beginDC(ctx, dc, release, opts) } // closemuRUnlockCondReleaseConn read unlocks closemu // as the sql operation is done with the dc. func (c *Conn) closemuRUnlockCondReleaseConn(err error) { c.closemu.RUnlock() if err == driver.ErrBadConn { c.close(err) } } func (c *Conn) txCtx() context.Context { return nil } func (c *Conn) close(err error) error { if !atomic.CompareAndSwapInt32(&c.done, 0, 1) { return ErrConnDone } // Lock around releasing the driver connection // to ensure all queries have been stopped before doing so. c.closemu.Lock() defer c.closemu.Unlock() c.dc.releaseConn(err) c.dc = nil c.db = nil return err } // Close returns the connection to the connection pool. // All operations after a Close will return with ErrConnDone. // Close is safe to call concurrently with other operations and will // block until all other operations finish. It may be useful to first // cancel any used context and then call close directly after. func (c *Conn) Close() error { return c.close(nil) } // Tx is an in-progress database transaction. // // A transaction must end with a call to Commit or Rollback. // // After a call to Commit or Rollback, all operations on the // transaction fail with ErrTxDone. // // The statements prepared for a transaction by calling // the transaction's Prepare or Stmt methods are closed // by the call to Commit or Rollback. type Tx struct { db *DB // closemu prevents the transaction from closing while there // is an active query. It is held for read during queries // and exclusively during close. closemu sync.RWMutex // dc is owned exclusively until Commit or Rollback, at which point // it's returned with putConn. dc *driverConn txi driver.Tx // releaseConn is called once the Tx is closed to release // any held driverConn back to the pool. releaseConn func(error) // done transitions from 0 to 1 exactly once, on Commit // or Rollback. once done, all operations fail with // ErrTxDone. // Use atomic operations on value when checking value. done int32 // All Stmts prepared for this transaction. These will be closed after the // transaction has been committed or rolled back. stmts struct { sync.Mutex v []*Stmt } // cancel is called after done transitions from 0 to 1. cancel func() // ctx lives for the life of the transaction. ctx context.Context } // awaitDone blocks until the context in Tx is canceled and rolls back // the transaction if it's not already done. func (tx *Tx) awaitDone() { // Wait for either the transaction to be committed or rolled // back, or for the associated context to be closed. <-tx.ctx.Done() // Discard and close the connection used to ensure the // transaction is closed and the resources are released. This // rollback does nothing if the transaction has already been // committed or rolled back. tx.rollback(true) } func (tx *Tx) isDone() bool { return atomic.LoadInt32(&tx.done) != 0 } // ErrTxDone is returned by any operation that is performed on a transaction // that has already been committed or rolled back. var ErrTxDone = errors.New("sql: Transaction has already been committed or rolled back") // close returns the connection to the pool and // must only be called by Tx.rollback or Tx.Commit. func (tx *Tx) close(err error) { tx.cancel() tx.closemu.Lock() defer tx.closemu.Unlock() tx.releaseConn(err) tx.dc = nil tx.txi = nil } // hookTxGrabConn specifies an optional hook to be called on // a successful call to (*Tx).grabConn. For tests. var hookTxGrabConn func() func (tx *Tx) grabConn(ctx context.Context) (*driverConn, releaseConn, error) { select { default: case <-ctx.Done(): return nil, nil, ctx.Err() } // closeme.RLock must come before the check for isDone to prevent the Tx from // closing while a query is executing. tx.closemu.RLock() if tx.isDone() { tx.closemu.RUnlock() return nil, nil, ErrTxDone } if hookTxGrabConn != nil { // test hook hookTxGrabConn() } return tx.dc, tx.closemuRUnlockRelease, nil } func (tx *Tx) txCtx() context.Context { return tx.ctx } // closemuRUnlockRelease is used as a func(error) method value in // ExecContext and QueryContext. Unlocking in the releaseConn keeps // the driver conn from being returned to the connection pool until // the Rows has been closed. func (tx *Tx) closemuRUnlockRelease(error) { tx.closemu.RUnlock() } // Closes all Stmts prepared for this transaction. func (tx *Tx) closePrepared() { tx.stmts.Lock() defer tx.stmts.Unlock() for _, stmt := range tx.stmts.v { stmt.Close() } } // Commit commits the transaction. func (tx *Tx) Commit() error { // Check context first to avoid transaction leak. // If put it behind tx.done CompareAndSwap statement, we cant't ensure // the consistency between tx.done and the real COMMIT operation. select { default: case <-tx.ctx.Done(): if atomic.LoadInt32(&tx.done) == 1 { return ErrTxDone } return tx.ctx.Err() } if !atomic.CompareAndSwapInt32(&tx.done, 0, 1) { return ErrTxDone } var err error withLock(tx.dc, func() { err = tx.txi.Commit() }) if err != driver.ErrBadConn { tx.closePrepared() } tx.close(err) return err } // rollback aborts the transaction and optionally forces the pool to discard // the connection. func (tx *Tx) rollback(discardConn bool) error { if !atomic.CompareAndSwapInt32(&tx.done, 0, 1) { return ErrTxDone } var err error withLock(tx.dc, func() { err = tx.txi.Rollback() }) if err != driver.ErrBadConn { tx.closePrepared() } if discardConn { err = driver.ErrBadConn } tx.close(err) return err } // Rollback aborts the transaction. func (tx *Tx) Rollback() error { return tx.rollback(false) } // PrepareContext creates a prepared statement for use within a transaction. // // The returned statement operates within the transaction and will be closed // when the transaction has been committed or rolled back. // // To use an existing prepared statement on this transaction, see Tx.Stmt. // // The provided context will be used for the preparation of the context, not // for the execution of the returned statement. The returned statement // will run in the transaction context. func (tx *Tx) PrepareContext(ctx context.Context, query string) (*Stmt, error) { dc, release, err := tx.grabConn(ctx) if err != nil { return nil, err } stmt, err := tx.db.prepareDC(ctx, dc, release, tx, query) if err != nil { return nil, err } tx.stmts.Lock() tx.stmts.v = append(tx.stmts.v, stmt) tx.stmts.Unlock() return stmt, nil } // Prepare creates a prepared statement for use within a transaction. // // The returned statement operates within the transaction and can no longer // be used once the transaction has been committed or rolled back. // // To use an existing prepared statement on this transaction, see Tx.Stmt. func (tx *Tx) Prepare(query string) (*Stmt, error) { return tx.PrepareContext(context.Background(), query) } // StmtContext returns a transaction-specific prepared statement from // an existing statement. // // Example: // updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?") // ... // tx, err := db.Begin() // ... // res, err := tx.StmtContext(ctx, updateMoney).Exec(123.45, 98293203) // // The provided context is used for the preparation of the statement, not for the // execution of the statement. // // The returned statement operates within the transaction and will be closed // when the transaction has been committed or rolled back. func (tx *Tx) StmtContext(ctx context.Context, stmt *Stmt) *Stmt { dc, release, err := tx.grabConn(ctx) if err != nil { return &Stmt{stickyErr: err} } defer release(nil) if tx.db != stmt.db { return &Stmt{stickyErr: errors.New("sql: Tx.Stmt: statement from different database used")} } var si driver.Stmt var parentStmt *Stmt stmt.mu.Lock() if stmt.closed || stmt.cg != nil { // If the statement has been closed or already belongs to a // transaction, we can't reuse it in this connection. // Since tx.StmtContext should never need to be called with a // Stmt already belonging to tx, we ignore this edge case and // re-prepare the statement in this case. No need to add // code-complexity for this. stmt.mu.Unlock() withLock(dc, func() { si, err = ctxDriverPrepare(ctx, dc.ci, stmt.query) }) if err != nil { return &Stmt{stickyErr: err} } } else { stmt.removeClosedStmtLocked() // See if the statement has already been prepared on this connection, // and reuse it if possible. for _, v := range stmt.css { if v.dc == dc { si = v.ds.si break } } stmt.mu.Unlock() if si == nil { var ds *driverStmt withLock(dc, func() { ds, err = stmt.prepareOnConnLocked(ctx, dc) }) if err != nil { return &Stmt{stickyErr: err} } si = ds.si } parentStmt = stmt } txs := &Stmt{ db: tx.db, cg: tx, cgds: &driverStmt{ Locker: dc, si: si, }, parentStmt: parentStmt, query: stmt.query, } if parentStmt != nil { tx.db.addDep(parentStmt, txs) } tx.stmts.Lock() tx.stmts.v = append(tx.stmts.v, txs) tx.stmts.Unlock() return txs } // Stmt returns a transaction-specific prepared statement from // an existing statement. // // Example: // updateMoney, err := db.Prepare("UPDATE balance SET money=money+? WHERE id=?") // ... // tx, err := db.Begin() // ... // res, err := tx.Stmt(updateMoney).Exec(123.45, 98293203) // // The returned statement operates within the transaction and will be closed // when the transaction has been committed or rolled back. func (tx *Tx) Stmt(stmt *Stmt) *Stmt { return tx.StmtContext(context.Background(), stmt) } // ExecContext executes a query that doesn't return rows. // For example: an INSERT and UPDATE. func (tx *Tx) ExecContext(ctx context.Context, query string, args ...interface{}) (Result, error) { dc, release, err := tx.grabConn(ctx) if err != nil { return nil, err } return tx.db.execDC(ctx, dc, release, query, args) } // Exec executes a query that doesn't return rows. // For example: an INSERT and UPDATE. func (tx *Tx) Exec(query string, args ...interface{}) (Result, error) { return tx.ExecContext(context.Background(), query, args...) } // QueryContext executes a query that returns rows, typically a SELECT. func (tx *Tx) QueryContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) { dc, release, err := tx.grabConn(ctx) if err != nil { return nil, err } return tx.db.queryDC(ctx, tx.ctx, dc, release, query, args) } // Query executes a query that returns rows, typically a SELECT. func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) { return tx.QueryContext(context.Background(), query, args...) } // QueryRowContext executes a query that is expected to return at most one row. // QueryRowContext always returns a non-nil value. Errors are deferred until // Row's Scan method is called. // If the query selects no rows, the *Row's Scan will return ErrNoRows. // Otherwise, the *Row's Scan scans the first selected row and discards // the rest. func (tx *Tx) QueryRowContext(ctx context.Context, query string, args ...interface{}) *Row { rows, err := tx.QueryContext(ctx, query, args...) return &Row{rows: rows, err: err} } // QueryRow executes a query that is expected to return at most one row. // QueryRow always returns a non-nil value. Errors are deferred until // Row's Scan method is called. // If the query selects no rows, the *Row's Scan will return ErrNoRows. // Otherwise, the *Row's Scan scans the first selected row and discards // the rest. func (tx *Tx) QueryRow(query string, args ...interface{}) *Row { return tx.QueryRowContext(context.Background(), query, args...) } // connStmt is a prepared statement on a particular connection. type connStmt struct { dc *driverConn ds *driverStmt } // stmtConnGrabber represents a Tx or Conn that will return the underlying // driverConn and release function. type stmtConnGrabber interface { // grabConn returns the driverConn and the associated release function // that must be called when the operation completes. grabConn(context.Context) (*driverConn, releaseConn, error) // txCtx returns the transaction context if available. // The returned context should be selected on along with // any query context when awaiting a cancel. txCtx() context.Context } var ( _ stmtConnGrabber = &Tx{} _ stmtConnGrabber = &Conn{} ) // Stmt is a prepared statement. // A Stmt is safe for concurrent use by multiple goroutines. type Stmt struct { // Immutable: db *DB // where we came from query string // that created the Stmt stickyErr error // if non-nil, this error is returned for all operations closemu sync.RWMutex // held exclusively during close, for read otherwise. // If Stmt is prepared on a Tx or Conn then cg is present and will // only ever grab a connection from cg. // If cg is nil then the Stmt must grab an arbitrary connection // from db and determine if it must prepare the stmt again by // inspecting css. cg stmtConnGrabber cgds *driverStmt // parentStmt is set when a transaction-specific statement // is requested from an identical statement prepared on the same // conn. parentStmt is used to track the dependency of this statement // on its originating ("parent") statement so that parentStmt may // be closed by the user without them having to know whether or not // any transactions are still using it. parentStmt *Stmt mu sync.Mutex // protects the rest of the fields closed bool // css is a list of underlying driver statement interfaces // that are valid on particular connections. This is only // used if cg == nil and one is found that has idle // connections. If cg != nil, cgds is always used. css []connStmt // lastNumClosed is copied from db.numClosed when Stmt is created // without tx and closed connections in css are removed. lastNumClosed uint64 } // ExecContext executes a prepared statement with the given arguments and // returns a Result summarizing the effect of the statement. func (s *Stmt) ExecContext(ctx context.Context, args ...interface{}) (Result, error) { s.closemu.RLock() defer s.closemu.RUnlock() var res Result strategy := cachedOrNewConn for i := 0; i < maxBadConnRetries+1; i++ { if i == maxBadConnRetries { strategy = alwaysNewConn } dc, releaseConn, ds, err := s.connStmt(ctx, strategy) if err != nil { if err == driver.ErrBadConn { continue } return nil, err } res, err = resultFromStatement(ctx, dc.ci, ds, args...) releaseConn(err) if err != driver.ErrBadConn { return res, err } } return nil, driver.ErrBadConn } // Exec executes a prepared statement with the given arguments and // returns a Result summarizing the effect of the statement. func (s *Stmt) Exec(args ...interface{}) (Result, error) { return s.ExecContext(context.Background(), args...) } func resultFromStatement(ctx context.Context, ci driver.Conn, ds *driverStmt, args ...interface{}) (Result, error) { ds.Lock() defer ds.Unlock() dargs, err := driverArgsConnLocked(ci, ds, args) if err != nil { return nil, err } // -1 means the driver doesn't know how to count the number of // placeholders, so we won't sanity check input here and instead let the // driver deal with errors. if want := ds.si.NumInput(); want >= 0 && want != len(dargs) { return nil, fmt.Errorf("sql: statement expects %d inputs; got %d", want, len(dargs)) } resi, err := ctxDriverStmtExec(ctx, ds.si, dargs) if err != nil { return nil, err } return driverResult{ds.Locker, resi}, nil } // removeClosedStmtLocked removes closed conns in s.css. // // To avoid lock contention on DB.mu, we do it only when // s.db.numClosed - s.lastNum is large enough. func (s *Stmt) removeClosedStmtLocked() { t := len(s.css)/2 + 1 if t > 10 { t = 10 } dbClosed := atomic.LoadUint64(&s.db.numClosed) if dbClosed-s.lastNumClosed < uint64(t) { return } s.db.mu.Lock() for i := 0; i < len(s.css); i++ { if s.css[i].dc.dbmuClosed { s.css[i] = s.css[len(s.css)-1] s.css = s.css[:len(s.css)-1] i-- } } s.db.mu.Unlock() s.lastNumClosed = dbClosed } // connStmt returns a free driver connection on which to execute the // statement, a function to call to release the connection, and a // statement bound to that connection. func (s *Stmt) connStmt(ctx context.Context, strategy connReuseStrategy) (dc *driverConn, releaseConn func(error), ds *driverStmt, err error) { if err = s.stickyErr; err != nil { return } s.mu.Lock() if s.closed { s.mu.Unlock() err = errors.New("sql: statement is closed") return } // In a transaction or connection, we always use the connection that the // the stmt was created on. if s.cg != nil { s.mu.Unlock() dc, releaseConn, err = s.cg.grabConn(ctx) // blocks, waiting for the connection. if err != nil { return } return dc, releaseConn, s.cgds, nil } s.removeClosedStmtLocked() s.mu.Unlock() dc, err = s.db.conn(ctx, strategy) if err != nil { return nil, nil, nil, err } s.mu.Lock() for _, v := range s.css { if v.dc == dc { s.mu.Unlock() return dc, dc.releaseConn, v.ds, nil } } s.mu.Unlock() // No luck; we need to prepare the statement on this connection withLock(dc, func() { ds, err = s.prepareOnConnLocked(ctx, dc) }) if err != nil { dc.releaseConn(err) return nil, nil, nil, err } return dc, dc.releaseConn, ds, nil } // prepareOnConnLocked prepares the query in Stmt s on dc and adds it to the list of // open connStmt on the statement. It assumes the caller is holding the lock on dc. func (s *Stmt) prepareOnConnLocked(ctx context.Context, dc *driverConn) (*driverStmt, error) { si, err := dc.prepareLocked(ctx, s.cg, s.query) if err != nil { return nil, err } cs := connStmt{dc, si} s.mu.Lock() s.css = append(s.css, cs) s.mu.Unlock() return cs.ds, nil } // QueryContext executes a prepared query statement with the given arguments // and returns the query results as a *Rows. func (s *Stmt) QueryContext(ctx context.Context, args ...interface{}) (*Rows, error) { s.closemu.RLock() defer s.closemu.RUnlock() var rowsi driver.Rows strategy := cachedOrNewConn for i := 0; i < maxBadConnRetries+1; i++ { if i == maxBadConnRetries { strategy = alwaysNewConn } dc, releaseConn, ds, err := s.connStmt(ctx, strategy) if err != nil { if err == driver.ErrBadConn { continue } return nil, err } rowsi, err = rowsiFromStatement(ctx, dc.ci, ds, args...) if err == nil { // Note: ownership of ci passes to the *Rows, to be freed // with releaseConn. rows := &Rows{ dc: dc, rowsi: rowsi, // releaseConn set below } // addDep must be added before initContextClose or it could attempt // to removeDep before it has been added. s.db.addDep(s, rows) // releaseConn must be set before initContextClose or it could // release the connection before it is set. rows.releaseConn = func(err error) { releaseConn(err) s.db.removeDep(s, rows) } var txctx context.Context if s.cg != nil { txctx = s.cg.txCtx() } rows.initContextClose(ctx, txctx) return rows, nil } releaseConn(err) if err != driver.ErrBadConn { return nil, err } } return nil, driver.ErrBadConn } // Query executes a prepared query statement with the given arguments // and returns the query results as a *Rows. func (s *Stmt) Query(args ...interface{}) (*Rows, error) { return s.QueryContext(context.Background(), args...) } func rowsiFromStatement(ctx context.Context, ci driver.Conn, ds *driverStmt, args ...interface{}) (driver.Rows, error) { ds.Lock() defer ds.Unlock() dargs, err := driverArgsConnLocked(ci, ds, args) if err != nil { return nil, err } // -1 means the driver doesn't know how to count the number of // placeholders, so we won't sanity check input here and instead let the // driver deal with errors. if want := ds.si.NumInput(); want >= 0 && want != len(dargs) { return nil, fmt.Errorf("sql: statement expects %d inputs; got %d", want, len(dargs)) } rowsi, err := ctxDriverStmtQuery(ctx, ds.si, dargs) if err != nil { return nil, err } return rowsi, nil } // QueryRowContext executes a prepared query statement with the given arguments. // If an error occurs during the execution of the statement, that error will // be returned by a call to Scan on the returned *Row, which is always non-nil. // If the query selects no rows, the *Row's Scan will return ErrNoRows. // Otherwise, the *Row's Scan scans the first selected row and discards // the rest. // // Example usage: // // var name string // err := nameByUseridStmt.QueryRowContext(ctx, id).Scan(&name) func (s *Stmt) QueryRowContext(ctx context.Context, args ...interface{}) *Row { rows, err := s.QueryContext(ctx, args...) if err != nil { return &Row{err: err} } return &Row{rows: rows} } // QueryRow executes a prepared query statement with the given arguments. // If an error occurs during the execution of the statement, that error will // be returned by a call to Scan on the returned *Row, which is always non-nil. // If the query selects no rows, the *Row's Scan will return ErrNoRows. // Otherwise, the *Row's Scan scans the first selected row and discards // the rest. // // Example usage: // // var name string // err := nameByUseridStmt.QueryRow(id).Scan(&name) func (s *Stmt) QueryRow(args ...interface{}) *Row { return s.QueryRowContext(context.Background(), args...) } // Close closes the statement. func (s *Stmt) Close() error { s.closemu.Lock() defer s.closemu.Unlock() if s.stickyErr != nil { return s.stickyErr } s.mu.Lock() if s.closed { s.mu.Unlock() return nil } s.closed = true txds := s.cgds s.cgds = nil s.mu.Unlock() if s.cg == nil { return s.db.removeDep(s, s) } if s.parentStmt != nil { // If parentStmt is set, we must not close s.txds since it's stored // in the css array of the parentStmt. return s.db.removeDep(s.parentStmt, s) } return txds.Close() } func (s *Stmt) finalClose() error { s.mu.Lock() defer s.mu.Unlock() if s.css != nil { for _, v := range s.css { s.db.noteUnusedDriverStatement(v.dc, v.ds) v.dc.removeOpenStmt(v.ds) } s.css = nil } return nil } // Rows is the result of a query. Its cursor starts before the first row // of the result set. Use Next to advance through the rows: // // rows, err := db.Query("SELECT ...") // ... // defer rows.Close() // for rows.Next() { // var id int // var name string // err = rows.Scan(&id, &name) // ... // } // err = rows.Err() // get any error encountered during iteration // ... type Rows struct { dc *driverConn // owned; must call releaseConn when closed to release releaseConn func(error) rowsi driver.Rows cancel func() // called when Rows is closed, may be nil. closeStmt *driverStmt // if non-nil, statement to Close on close // closemu prevents Rows from closing while there // is an active streaming result. It is held for read during non-close operations // and exclusively during close. // // closemu guards lasterr and closed. closemu sync.RWMutex closed bool lasterr error // non-nil only if closed is true // lastcols is only used in Scan, Next, and NextResultSet which are expected // not to be called concurrently. lastcols []driver.Value } func (rs *Rows) initContextClose(ctx, txctx context.Context) { ctx, rs.cancel = context.WithCancel(ctx) go rs.awaitDone(ctx, txctx) } // awaitDone blocks until either ctx or txctx is canceled. The ctx is provided // from the query context and is canceled when the query Rows is closed. // If the query was issued in a transaction, the transaction's context // is also provided in txctx to ensure Rows is closed if the Tx is closed. func (rs *Rows) awaitDone(ctx, txctx context.Context) { var txctxDone <-chan struct{} if txctx != nil { txctxDone = txctx.Done() } select { case <-ctx.Done(): case <-txctxDone: } rs.close(ctx.Err()) } // Next prepares the next result row for reading with the Scan method. It // returns true on success, or false if there is no next result row or an error // happened while preparing it. Err should be consulted to distinguish between // the two cases. // // Every call to Scan, even the first one, must be preceded by a call to Next. func (rs *Rows) Next() bool { var doClose, ok bool withLock(rs.closemu.RLocker(), func() { doClose, ok = rs.nextLocked() }) if doClose { rs.Close() } return ok } func (rs *Rows) nextLocked() (doClose, ok bool) { if rs.closed { return false, false } // Lock the driver connection before calling the driver interface // rowsi to prevent a Tx from rolling back the connection at the same time. rs.dc.Lock() defer rs.dc.Unlock() if rs.lastcols == nil { rs.lastcols = make([]driver.Value, len(rs.rowsi.Columns())) } rs.lasterr = rs.rowsi.Next(rs.lastcols) if rs.lasterr != nil { // Close the connection if there is a driver error. if rs.lasterr != io.EOF { return true, false } nextResultSet, ok := rs.rowsi.(driver.RowsNextResultSet) if !ok { return true, false } // The driver is at the end of the current result set. // Test to see if there is another result set after the current one. // Only close Rows if there is no further result sets to read. if !nextResultSet.HasNextResultSet() { doClose = true } return doClose, false } return false, true } // NextResultSet prepares the next result set for reading. It returns true if // there is further result sets, or false if there is no further result set // or if there is an error advancing to it. The Err method should be consulted // to distinguish between the two cases. // // After calling NextResultSet, the Next method should always be called before // scanning. If there are further result sets they may not have rows in the result // set. func (rs *Rows) NextResultSet() bool { var doClose bool defer func() { if doClose { rs.Close() } }() rs.closemu.RLock() defer rs.closemu.RUnlock() if rs.closed { return false } rs.lastcols = nil nextResultSet, ok := rs.rowsi.(driver.RowsNextResultSet) if !ok { doClose = true return false } // Lock the driver connection before calling the driver interface // rowsi to prevent a Tx from rolling back the connection at the same time. rs.dc.Lock() defer rs.dc.Unlock() rs.lasterr = nextResultSet.NextResultSet() if rs.lasterr != nil { doClose = true return false } return true } // Err returns the error, if any, that was encountered during iteration. // Err may be called after an explicit or implicit Close. func (rs *Rows) Err() error { rs.closemu.RLock() defer rs.closemu.RUnlock() if rs.lasterr == io.EOF { return nil } return rs.lasterr } // Columns returns the column names. // Columns returns an error if the rows are closed, or if the rows // are from QueryRow and there was a deferred error. func (rs *Rows) Columns() ([]string, error) { rs.closemu.RLock() defer rs.closemu.RUnlock() if rs.closed { return nil, errors.New("sql: Rows are closed") } if rs.rowsi == nil { return nil, errors.New("sql: no Rows available") } rs.dc.Lock() defer rs.dc.Unlock() return rs.rowsi.Columns(), nil } // ColumnTypes returns column information such as column type, length, // and nullable. Some information may not be available from some drivers. func (rs *Rows) ColumnTypes() ([]*ColumnType, error) { rs.closemu.RLock() defer rs.closemu.RUnlock() if rs.closed { return nil, errors.New("sql: Rows are closed") } if rs.rowsi == nil { return nil, errors.New("sql: no Rows available") } rs.dc.Lock() defer rs.dc.Unlock() return rowsColumnInfoSetupConnLocked(rs.rowsi), nil } // ColumnType contains the name and type of a column. type ColumnType struct { name string hasNullable bool hasLength bool hasPrecisionScale bool nullable bool length int64 databaseType string precision int64 scale int64 scanType reflect.Type } // Name returns the name or alias of the column. func (ci *ColumnType) Name() string { return ci.name } // Length returns the column type length for variable length column types such // as text and binary field types. If the type length is unbounded the value will // be math.MaxInt64 (any database limits will still apply). // If the column type is not variable length, such as an int, or if not supported // by the driver ok is false. func (ci *ColumnType) Length() (length int64, ok bool) { return ci.length, ci.hasLength } // DecimalSize returns the scale and precision of a decimal type. // If not applicable or if not supported ok is false. func (ci *ColumnType) DecimalSize() (precision, scale int64, ok bool) { return ci.precision, ci.scale, ci.hasPrecisionScale } // ScanType returns a Go type suitable for scanning into using Rows.Scan. // If a driver does not support this property ScanType will return // the type of an empty interface. func (ci *ColumnType) ScanType() reflect.Type { return ci.scanType } // Nullable returns whether the column may be null. // If a driver does not support this property ok will be false. func (ci *ColumnType) Nullable() (nullable, ok bool) { return ci.nullable, ci.hasNullable } // DatabaseTypeName returns the database system name of the column type. If an empty // string is returned the driver type name is not supported. // Consult your driver documentation for a list of driver data types. Length specifiers // are not included. // Common type include "VARCHAR", "TEXT", "NVARCHAR", "DECIMAL", "BOOL", "INT", "BIGINT". func (ci *ColumnType) DatabaseTypeName() string { return ci.databaseType } func rowsColumnInfoSetupConnLocked(rowsi driver.Rows) []*ColumnType { names := rowsi.Columns() list := make([]*ColumnType, len(names)) for i := range list { ci := &ColumnType{ name: names[i], } list[i] = ci if prop, ok := rowsi.(driver.RowsColumnTypeScanType); ok { ci.scanType = prop.ColumnTypeScanType(i) } else { ci.scanType = reflect.TypeOf(new(interface{})).Elem() } if prop, ok := rowsi.(driver.RowsColumnTypeDatabaseTypeName); ok { ci.databaseType = prop.ColumnTypeDatabaseTypeName(i) } if prop, ok := rowsi.(driver.RowsColumnTypeLength); ok { ci.length, ci.hasLength = prop.ColumnTypeLength(i) } if prop, ok := rowsi.(driver.RowsColumnTypeNullable); ok { ci.nullable, ci.hasNullable = prop.ColumnTypeNullable(i) } if prop, ok := rowsi.(driver.RowsColumnTypePrecisionScale); ok { ci.precision, ci.scale, ci.hasPrecisionScale = prop.ColumnTypePrecisionScale(i) } } return list } // Scan copies the columns in the current row into the values pointed // at by dest. The number of values in dest must be the same as the // number of columns in Rows. // // Scan converts columns read from the database into the following // common Go types and special types provided by the sql package: // // *string // *[]byte // *int, *int8, *int16, *int32, *int64 // *uint, *uint8, *uint16, *uint32, *uint64 // *bool // *float32, *float64 // *interface{} // *RawBytes // any type implementing Scanner (see Scanner docs) // // In the most simple case, if the type of the value from the source // column is an integer, bool or string type T and dest is of type *T, // Scan simply assigns the value through the pointer. // // Scan also converts between string and numeric types, as long as no // information would be lost. While Scan stringifies all numbers // scanned from numeric database columns into *string, scans into // numeric types are checked for overflow. For example, a float64 with // value 300 or a string with value "300" can scan into a uint16, but // not into a uint8, though float64(255) or "255" can scan into a // uint8. One exception is that scans of some float64 numbers to // strings may lose information when stringifying. In general, scan // floating point columns into *float64. // // If a dest argument has type *[]byte, Scan saves in that argument a // copy of the corresponding data. The copy is owned by the caller and // can be modified and held indefinitely. The copy can be avoided by // using an argument of type *RawBytes instead; see the documentation // for RawBytes for restrictions on its use. // // If an argument has type *interface{}, Scan copies the value // provided by the underlying driver without conversion. When scanning // from a source value of type []byte to *interface{}, a copy of the // slice is made and the caller owns the result. // // Source values of type time.Time may be scanned into values of type // *time.Time, *interface{}, *string, or *[]byte. When converting to // the latter two, time.Format3339Nano is used. // // Source values of type bool may be scanned into types *bool, // *interface{}, *string, *[]byte, or *RawBytes. // // For scanning into *bool, the source may be true, false, 1, 0, or // string inputs parseable by strconv.ParseBool. func (rs *Rows) Scan(dest ...interface{}) error { rs.closemu.RLock() if rs.closed { rs.closemu.RUnlock() return errors.New("sql: Rows are closed") } rs.closemu.RUnlock() if rs.lastcols == nil { return errors.New("sql: Scan called without calling Next") } if len(dest) != len(rs.lastcols) { return fmt.Errorf("sql: expected %d destination arguments in Scan, not %d", len(rs.lastcols), len(dest)) } for i, sv := range rs.lastcols { err := convertAssign(dest[i], sv) if err != nil { return fmt.Errorf("sql: Scan error on column index %d: %v", i, err) } } return nil } // rowsCloseHook returns a function so tests may install the // hook through a test only mutex. var rowsCloseHook = func() func(*Rows, *error) { return nil } // Close closes the Rows, preventing further enumeration. If Next is called // and returns false and there are no further result sets, // the Rows are closed automatically and it will suffice to check the // result of Err. Close is idempotent and does not affect the result of Err. func (rs *Rows) Close() error { return rs.close(nil) } func (rs *Rows) close(err error) error { rs.closemu.Lock() defer rs.closemu.Unlock() if rs.closed { return nil } rs.closed = true if rs.lasterr == nil { rs.lasterr = err } withLock(rs.dc, func() { err = rs.rowsi.Close() }) if fn := rowsCloseHook(); fn != nil { fn(rs, &err) } if rs.cancel != nil { rs.cancel() } if rs.closeStmt != nil { rs.closeStmt.Close() } rs.releaseConn(err) return err } // Row is the result of calling QueryRow to select a single row. type Row struct { // One of these two will be non-nil: err error // deferred error for easy chaining rows *Rows } // Scan copies the columns from the matched row into the values // pointed at by dest. See the documentation on Rows.Scan for details. // If more than one row matches the query, // Scan uses the first row and discards the rest. If no row matches // the query, Scan returns ErrNoRows. func (r *Row) Scan(dest ...interface{}) error { if r.err != nil { return r.err } // TODO(bradfitz): for now we need to defensively clone all // []byte that the driver returned (not permitting // *RawBytes in Rows.Scan), since we're about to close // the Rows in our defer, when we return from this function. // the contract with the driver.Next(...) interface is that it // can return slices into read-only temporary memory that's // only valid until the next Scan/Close. But the TODO is that // for a lot of drivers, this copy will be unnecessary. We // should provide an optional interface for drivers to // implement to say, "don't worry, the []bytes that I return // from Next will not be modified again." (for instance, if // they were obtained from the network anyway) But for now we // don't care. defer r.rows.Close() for _, dp := range dest { if _, ok := dp.(*RawBytes); ok { return errors.New("sql: RawBytes isn't allowed on Row.Scan") } } if !r.rows.Next() { if err := r.rows.Err(); err != nil { return err } return ErrNoRows } err := r.rows.Scan(dest...) if err != nil { return err } // Make sure the query can be processed to completion with no errors. if err := r.rows.Close(); err != nil { return err } return nil } // A Result summarizes an executed SQL command. type Result interface { // LastInsertId returns the integer generated by the database // in response to a command. Typically this will be from an // "auto increment" column when inserting a new row. Not all // databases support this feature, and the syntax of such // statements varies. LastInsertId() (int64, error) // RowsAffected returns the number of rows affected by an // update, insert, or delete. Not every database or database // driver may support this. RowsAffected() (int64, error) } type driverResult struct { sync.Locker // the *driverConn resi driver.Result } func (dr driverResult) LastInsertId() (int64, error) { dr.Lock() defer dr.Unlock() return dr.resi.LastInsertId() } func (dr driverResult) RowsAffected() (int64, error) { dr.Lock() defer dr.Unlock() return dr.resi.RowsAffected() } func stack() string { var buf [2 << 10]byte return string(buf[:runtime.Stack(buf[:], false)]) } // withLock runs while holding lk. func withLock(lk sync.Locker, fn func()) { lk.Lock() defer lk.Unlock() // in case fn panics fn() } // ssss--------------------------------------------------- // /Users/xah/git/go/src/fmt/scan.go package fmt import ( "errors" "io" "math" "os" "reflect" "strconv" "sync" "unicode/utf8" ) // ScanState represents the scanner state passed to custom scanners. // Scanners may do rune-at-a-time scanning or ask the ScanState // to discover the next space-delimited token. type ScanState interface { // ReadRune reads the next rune (Unicode code point) from the input. // If invoked during Scanln, Fscanln, or Sscanln, ReadRune() will // return EOF after returning the first '\n' or when reading beyond // the specified width. ReadRune() (r rune, size int, err error) // UnreadRune causes the next call to ReadRune to return the same rune. UnreadRune() error // SkipSpace skips space in the input. Newlines are treated appropriately // for the operation being performed; see the package documentation // for more information. SkipSpace() // Token skips space in the input if skipSpace is true, then returns the // run of Unicode code points c satisfying f(c). If f is nil, // !unicode.IsSpace(c) is used; that is, the token will hold non-space // characters. Newlines are treated appropriately for the operation being // performed; see the package documentation for more information. // The returned slice points to shared data that may be overwritten // by the next call to Token, a call to a Scan function using the ScanState // as input, or when the calling Scan method returns. Token(skipSpace bool, f func(rune) bool) (token []byte, err error) // Width returns the value of the width option and whether it has been set. // The unit is Unicode code points. Width() (wid int, ok bool) // Because ReadRune is implemented by the interface, Read should never be // called by the scanning routines and a valid implementation of // ScanState may choose always to return an error from Read. Read(buf []byte) (n int, err error) } // Scanner is implemented by any value that has a Scan method, which scans // the input for the representation of a value and stores the result in the // receiver, which must be a pointer to be useful. The Scan method is called // for any argument to Scan, Scanf, or Scanln that implements it. type Scanner interface { Scan(state ScanState, verb rune) error } // Scan scans text read from standard input, storing successive // space-separated values into successive arguments. Newlines count // as space. It returns the number of items successfully scanned. // If that is less than the number of arguments, err will report why. func Scan(a ...interface{}) (n int, err error) { return Fscan(os.Stdin, a...) } // Scanln is similar to Scan, but stops scanning at a newline and // after the final item there must be a newline or EOF. func Scanln(a ...interface{}) (n int, err error) { return Fscanln(os.Stdin, a...) } // Scanf scans text read from standard input, storing successive // space-separated values into successive arguments as determined by // the format. It returns the number of items successfully scanned. // If that is less than the number of arguments, err will report why. // Newlines in the input must match newlines in the format. // The one exception: the verb %c always scans the next rune in the // input, even if it is a space (or tab etc.) or newline. func Scanf(format string, a ...interface{}) (n int, err error) { return Fscanf(os.Stdin, format, a...) } type stringReader string func (r *stringReader) Read(b []byte) (n int, err error) { n = copy(b, *r) *r = (*r)[n:] if n == 0 { err = io.EOF } return } // Sscan scans the argument string, storing successive space-separated // values into successive arguments. Newlines count as space. It // returns the number of items successfully scanned. If that is less // than the number of arguments, err will report why. func Sscan(str string, a ...interface{}) (n int, err error) { return Fscan((*stringReader)(&str), a...) } // Sscanln is similar to Sscan, but stops scanning at a newline and // after the final item there must be a newline or EOF. func Sscanln(str string, a ...interface{}) (n int, err error) { return Fscanln((*stringReader)(&str), a...) } // Sscanf scans the argument string, storing successive space-separated // values into successive arguments as determined by the format. It // returns the number of items successfully parsed. // Newlines in the input must match newlines in the format. func Sscanf(str string, format string, a ...interface{}) (n int, err error) { return Fscanf((*stringReader)(&str), format, a...) } // Fscan scans text read from r, storing successive space-separated // values into successive arguments. Newlines count as space. It // returns the number of items successfully scanned. If that is less // than the number of arguments, err will report why. func Fscan(r io.Reader, a ...interface{}) (n int, err error) { s, old := newScanState(r, true, false) n, err = s.doScan(a) s.free(old) return } // Fscanln is similar to Fscan, but stops scanning at a newline and // after the final item there must be a newline or EOF. func Fscanln(r io.Reader, a ...interface{}) (n int, err error) { s, old := newScanState(r, false, true) n, err = s.doScan(a) s.free(old) return } // Fscanf scans text read from r, storing successive space-separated // values into successive arguments as determined by the format. It // returns the number of items successfully parsed. // Newlines in the input must match newlines in the format. func Fscanf(r io.Reader, format string, a ...interface{}) (n int, err error) { s, old := newScanState(r, false, false) n, err = s.doScanf(format, a) s.free(old) return } // scanError represents an error generated by the scanning software. // It's used as a unique signature to identify such errors when recovering. type scanError struct { err error } const eof = -1 // ss is the internal implementation of ScanState. type ss struct { rs io.RuneScanner // where to read input buf buffer // token accumulator count int // runes consumed so far. atEOF bool // already read EOF ssave } // ssave holds the parts of ss that need to be // saved and restored on recursive scans. type ssave struct { validSave bool // is or was a part of an actual ss. nlIsEnd bool // whether newline terminates scan nlIsSpace bool // whether newline counts as white space argLimit int // max value of ss.count for this arg; argLimit <= limit limit int // max value of ss.count. maxWid int // width of this arg. } // The Read method is only in ScanState so that ScanState // satisfies io.Reader. It will never be called when used as // intended, so there is no need to make it actually work. func (s *ss) Read(buf []byte) (n int, err error) { return 0, errors.New("ScanState's Read should not be called. Use ReadRune") } func (s *ss) ReadRune() (r rune, size int, err error) { if s.atEOF || s.count >= s.argLimit { err = io.EOF return } r, size, err = s.rs.ReadRune() if err == nil { s.count++ if s.nlIsEnd && r == '\n' { s.atEOF = true } } else if err == io.EOF { s.atEOF = true } return } func (s *ss) Width() (wid int, ok bool) { if s.maxWid == hugeWid { return 0, false } return s.maxWid, true } // The public method returns an error; this private one panics. // If getRune reaches EOF, the return value is EOF (-1). func (s *ss) getRune() (r rune) { r, _, err := s.ReadRune() if err != nil { if err == io.EOF { return eof } s.error(err) } return } // mustReadRune turns io.EOF into a panic(io.ErrUnexpectedEOF). // It is called in cases such as string scanning where an EOF is a // syntax error. func (s *ss) mustReadRune() (r rune) { r = s.getRune() if r == eof { s.error(io.ErrUnexpectedEOF) } return } func (s *ss) UnreadRune() error { s.rs.UnreadRune() s.atEOF = false s.count-- return nil } func (s *ss) error(err error) { panic(scanError{err}) } func (s *ss) errorString(err string) { panic(scanError{errors.New(err)}) } func (s *ss) Token(skipSpace bool, f func(rune) bool) (tok []byte, err error) { defer func() { if e := recover(); e != nil { if se, ok := e.(scanError); ok { err = se.err } else { panic(e) } } }() if f == nil { f = notSpace } s.buf = s.buf[:0] tok = s.token(skipSpace, f) return } // space is a copy of the unicode.White_Space ranges, // to avoid depending on package unicode. var space = [][2]uint16{ {0x0009, 0x000d}, {0x0020, 0x0020}, {0x0085, 0x0085}, {0x00a0, 0x00a0}, {0x1680, 0x1680}, {0x2000, 0x200a}, {0x2028, 0x2029}, {0x202f, 0x202f}, {0x205f, 0x205f}, {0x3000, 0x3000}, } func isSpace(r rune) bool { if r >= 1<<16 { return false } rx := uint16(r) for _, rng := range space { if rx < rng[0] { return false } if rx <= rng[1] { return true } } return false } // notSpace is the default scanning function used in Token. func notSpace(r rune) bool { return !isSpace(r) } // readRune is a structure to enable reading UTF-8 encoded code points // from an io.Reader. It is used if the Reader given to the scanner does // not already implement io.RuneScanner. type readRune struct { reader io.Reader buf [utf8.UTFMax]byte // used only inside ReadRune pending int // number of bytes in pendBuf; only >0 for bad UTF-8 pendBuf [utf8.UTFMax]byte // bytes left over peekRune rune // if >=0 next rune; when <0 is ^(previous Rune) } // readByte returns the next byte from the input, which may be // left over from a previous read if the UTF-8 was ill-formed. func (r *readRune) readByte() (b byte, err error) { if r.pending > 0 { b = r.pendBuf[0] copy(r.pendBuf[0:], r.pendBuf[1:]) r.pending-- return } n, err := io.ReadFull(r.reader, r.pendBuf[:1]) if n != 1 { return 0, err } return r.pendBuf[0], err } // ReadRune returns the next UTF-8 encoded code point from the // io.Reader inside r. func (r *readRune) ReadRune() (rr rune, size int, err error) { if r.peekRune >= 0 { rr = r.peekRune r.peekRune = ^r.peekRune size = utf8.RuneLen(rr) return } r.buf[0], err = r.readByte() if err != nil { return } if r.buf[0] < utf8.RuneSelf { // fast check for common ASCII case rr = rune(r.buf[0]) size = 1 // Known to be 1. // Flip the bits of the rune so it's available to UnreadRune. r.peekRune = ^rr return } var n int for n = 1; !utf8.FullRune(r.buf[:n]); n++ { r.buf[n], err = r.readByte() if err != nil { if err == io.EOF { err = nil break } return } } rr, size = utf8.DecodeRune(r.buf[:n]) if size < n { // an error, save the bytes for the next read copy(r.pendBuf[r.pending:], r.buf[size:n]) r.pending += n - size } // Flip the bits of the rune so it's available to UnreadRune. r.peekRune = ^rr return } func (r *readRune) UnreadRune() error { if r.peekRune >= 0 { return errors.New("fmt: scanning called UnreadRune with no rune available") } // Reverse bit flip of previously read rune to obtain valid >=0 state. r.peekRune = ^r.peekRune return nil } var ssFree = sync.Pool{ New: func() interface{} { return new(ss) }, } // newScanState allocates a new ss struct or grab a cached one. func newScanState(r io.Reader, nlIsSpace, nlIsEnd bool) (s *ss, old ssave) { s = ssFree.Get().(*ss) if rs, ok := r.(io.RuneScanner); ok { s.rs = rs } else { s.rs = &readRune{reader: r, peekRune: -1} } s.nlIsSpace = nlIsSpace s.nlIsEnd = nlIsEnd s.atEOF = false s.limit = hugeWid s.argLimit = hugeWid s.maxWid = hugeWid s.validSave = true s.count = 0 return } // free saves used ss structs in ssFree; avoid an allocation per invocation. func (s *ss) free(old ssave) { // If it was used recursively, just restore the old state. if old.validSave { s.ssave = old return } // Don't hold on to ss structs with large buffers. if cap(s.buf) > 1024 { return } s.buf = s.buf[:0] s.rs = nil ssFree.Put(s) } // SkipSpace provides Scan methods the ability to skip space and newline // characters in keeping with the current scanning mode set by format strings // and Scan/Scanln. func (s *ss) SkipSpace() { for { r := s.getRune() if r == eof { return } if r == '\r' && s.peek("\n") { continue } if r == '\n' { if s.nlIsSpace { continue } s.errorString("unexpected newline") return } if !isSpace(r) { s.UnreadRune() break } } } // token returns the next space-delimited string from the input. It // skips white space. For Scanln, it stops at newlines. For Scan, // newlines are treated as spaces. func (s *ss) token(skipSpace bool, f func(rune) bool) []byte { if skipSpace { s.SkipSpace() } // read until white space or newline for { r := s.getRune() if r == eof { break } if !f(r) { s.UnreadRune() break } s.buf.WriteRune(r) } return s.buf } var complexError = errors.New("syntax error scanning complex number") var boolError = errors.New("syntax error scanning boolean") func indexRune(s string, r rune) int { for i, c := range s { if c == r { return i } } return -1 } // consume reads the next rune in the input and reports whether it is in the ok string. // If accept is true, it puts the character into the input token. func (s *ss) consume(ok string, accept bool) bool { r := s.getRune() if r == eof { return false } if indexRune(ok, r) >= 0 { if accept { s.buf.WriteRune(r) } return true } if r != eof && accept { s.UnreadRune() } return false } // peek reports whether the next character is in the ok string, without consuming it. func (s *ss) peek(ok string) bool { r := s.getRune() if r != eof { s.UnreadRune() } return indexRune(ok, r) >= 0 } func (s *ss) notEOF() { // Guarantee there is data to be read. if r := s.getRune(); r == eof { panic(io.EOF) } s.UnreadRune() } // accept checks the next rune in the input. If it's a byte (sic) in the string, it puts it in the // buffer and returns true. Otherwise it return false. func (s *ss) accept(ok string) bool { return s.consume(ok, true) } // okVerb verifies that the verb is present in the list, setting s.err appropriately if not. func (s *ss) okVerb(verb rune, okVerbs, typ string) bool { for _, v := range okVerbs { if v == verb { return true } } s.errorString("bad verb '%" + string(verb) + "' for " + typ) return false } // scanBool returns the value of the boolean represented by the next token. func (s *ss) scanBool(verb rune) bool { s.SkipSpace() s.notEOF() if !s.okVerb(verb, "tv", "boolean") { return false } // Syntax-checking a boolean is annoying. We're not fastidious about case. switch s.getRune() { case '0': return false case '1': return true case 't', 'T': if s.accept("rR") && (!s.accept("uU") || !s.accept("eE")) { s.error(boolError) } return true case 'f', 'F': if s.accept("aA") && (!s.accept("lL") || !s.accept("sS") || !s.accept("eE")) { s.error(boolError) } return false } return false } // Numerical elements const ( binaryDigits = "01" octalDigits = "01234567" decimalDigits = "0123456789" hexadecimalDigits = "0123456789aAbBcCdDeEfF" sign = "+-" period = "." exponent = "eEp" ) // getBase returns the numeric base represented by the verb and its digit string. func (s *ss) getBase(verb rune) (base int, digits string) { s.okVerb(verb, "bdoUxXv", "integer") // sets s.err base = 10 digits = decimalDigits switch verb { case 'b': base = 2 digits = binaryDigits case 'o': base = 8 digits = octalDigits case 'x', 'X', 'U': base = 16 digits = hexadecimalDigits } return } // scanNumber returns the numerical string with specified digits starting here. func (s *ss) scanNumber(digits string, haveDigits bool) string { if !haveDigits { s.notEOF() if !s.accept(digits) { s.errorString("expected integer") } } for s.accept(digits) { } return string(s.buf) } // scanRune returns the next rune value in the input. func (s *ss) scanRune(bitSize int) int64 { s.notEOF() r := int64(s.getRune()) n := uint(bitSize) x := (r << (64 - n)) >> (64 - n) if x != r { s.errorString("overflow on character value " + string(r)) } return r } // scanBasePrefix reports whether the integer begins with a 0 or 0x, // and returns the base, digit string, and whether a zero was found. // It is called only if the verb is %v. func (s *ss) scanBasePrefix() (base int, digits string, found bool) { if !s.peek("0") { return 10, decimalDigits, false } s.accept("0") found = true // We've put a digit into the token buffer. // Special cases for '0' && '0x' base, digits = 8, octalDigits if s.peek("xX") { s.consume("xX", false) base, digits = 16, hexadecimalDigits } return } // scanInt returns the value of the integer represented by the next // token, checking for overflow. Any error is stored in s.err. func (s *ss) scanInt(verb rune, bitSize int) int64 { if verb == 'c' { return s.scanRune(bitSize) } s.SkipSpace() s.notEOF() base, digits := s.getBase(verb) haveDigits := false if verb == 'U' { if !s.consume("U", false) || !s.consume("+", false) { s.errorString("bad unicode format ") } } else { s.accept(sign) // If there's a sign, it will be left in the token buffer. if verb == 'v' { base, digits, haveDigits = s.scanBasePrefix() } } tok := s.scanNumber(digits, haveDigits) i, err := strconv.ParseInt(tok, base, 64) if err != nil { s.error(err) } n := uint(bitSize) x := (i << (64 - n)) >> (64 - n) if x != i { s.errorString("integer overflow on token " + tok) } return i } // scanUint returns the value of the unsigned integer represented // by the next token, checking for overflow. Any error is stored in s.err. func (s *ss) scanUint(verb rune, bitSize int) uint64 { if verb == 'c' { return uint64(s.scanRune(bitSize)) } s.SkipSpace() s.notEOF() base, digits := s.getBase(verb) haveDigits := false if verb == 'U' { if !s.consume("U", false) || !s.consume("+", false) { s.errorString("bad unicode format ") } } else if verb == 'v' { base, digits, haveDigits = s.scanBasePrefix() } tok := s.scanNumber(digits, haveDigits) i, err := strconv.ParseUint(tok, base, 64) if err != nil { s.error(err) } n := uint(bitSize) x := (i << (64 - n)) >> (64 - n) if x != i { s.errorString("unsigned integer overflow on token " + tok) } return i } // floatToken returns the floating-point number starting here, no longer than swid // if the width is specified. It's not rigorous about syntax because it doesn't check that // we have at least some digits, but Atof will do that. func (s *ss) floatToken() string { s.buf = s.buf[:0] // NaN? if s.accept("nN") && s.accept("aA") && s.accept("nN") { return string(s.buf) } // leading sign? s.accept(sign) // Inf? if s.accept("iI") && s.accept("nN") && s.accept("fF") { return string(s.buf) } // digits? for s.accept(decimalDigits) { } // decimal point? if s.accept(period) { // fraction? for s.accept(decimalDigits) { } } // exponent? if s.accept(exponent) { // leading sign? s.accept(sign) // digits? for s.accept(decimalDigits) { } } return string(s.buf) } // complexTokens returns the real and imaginary parts of the complex number starting here. // The number might be parenthesized and has the format (N+Ni) where N is a floating-point // number and there are no spaces within. func (s *ss) complexTokens() (real, imag string) { // TODO: accept N and Ni independently? parens := s.accept("(") real = s.floatToken() s.buf = s.buf[:0] // Must now have a sign. if !s.accept("+-") { s.error(complexError) } // Sign is now in buffer imagSign := string(s.buf) imag = s.floatToken() if !s.accept("i") { s.error(complexError) } if parens && !s.accept(")") { s.error(complexError) } return real, imagSign + imag } // convertFloat converts the string to a float64value. func (s *ss) convertFloat(str string, n int) float64 { if p := indexRune(str, 'p'); p >= 0 { // Atof doesn't handle power-of-2 exponents, // but they're easy to evaluate. f, err := strconv.ParseFloat(str[:p], n) if err != nil { // Put full string into error. if e, ok := err.(*strconv.NumError); ok { e.Num = str } s.error(err) } m, err := strconv.Atoi(str[p+1:]) if err != nil { // Put full string into error. if e, ok := err.(*strconv.NumError); ok { e.Num = str } s.error(err) } return math.Ldexp(f, m) } f, err := strconv.ParseFloat(str, n) if err != nil { s.error(err) } return f } // convertComplex converts the next token to a complex128 value. // The atof argument is a type-specific reader for the underlying type. // If we're reading complex64, atof will parse float32s and convert them // to float64's to avoid reproducing this code for each complex type. func (s *ss) scanComplex(verb rune, n int) complex128 { if !s.okVerb(verb, floatVerbs, "complex") { return 0 } s.SkipSpace() s.notEOF() sreal, simag := s.complexTokens() real := s.convertFloat(sreal, n/2) imag := s.convertFloat(simag, n/2) return complex(real, imag) } // convertString returns the string represented by the next input characters. // The format of the input is determined by the verb. func (s *ss) convertString(verb rune) (str string) { if !s.okVerb(verb, "svqxX", "string") { return "" } s.SkipSpace() s.notEOF() switch verb { case 'q': str = s.quotedString() case 'x', 'X': str = s.hexString() default: str = string(s.token(true, notSpace)) // %s and %v just return the next word } return } // quotedString returns the double- or back-quoted string represented by the next input characters. func (s *ss) quotedString() string { s.notEOF() quote := s.getRune() switch quote { case '`': // Back-quoted: Anything goes until EOF or back quote. for { r := s.mustReadRune() if r == quote { break } s.buf.WriteRune(r) } return string(s.buf) case '"': // Double-quoted: Include the quotes and let strconv.Unquote do the backslash escapes. s.buf.WriteByte('"') for { r := s.mustReadRune() s.buf.WriteRune(r) if r == '\\' { // In a legal backslash escape, no matter how long, only the character // immediately after the escape can itself be a backslash or quote. // Thus we only need to protect the first character after the backslash. s.buf.WriteRune(s.mustReadRune()) } else if r == '"' { break } } result, err := strconv.Unquote(string(s.buf)) if err != nil { s.error(err) } return result default: s.errorString("expected quoted string") } return "" } // hexDigit returns the value of the hexadecimal digit. func hexDigit(d rune) (int, bool) { digit := int(d) switch digit { case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': return digit - '0', true case 'a', 'b', 'c', 'd', 'e', 'f': return 10 + digit - 'a', true case 'A', 'B', 'C', 'D', 'E', 'F': return 10 + digit - 'A', true } return -1, false } // hexByte returns the next hex-encoded (two-character) byte from the input. // It returns ok==false if the next bytes in the input do not encode a hex byte. // If the first byte is hex and the second is not, processing stops. func (s *ss) hexByte() (b byte, ok bool) { rune1 := s.getRune() if rune1 == eof { return } value1, ok := hexDigit(rune1) if !ok { s.UnreadRune() return } value2, ok := hexDigit(s.mustReadRune()) if !ok { s.errorString("illegal hex digit") return } return byte(value1<<4 | value2), true } // hexString returns the space-delimited hexpair-encoded string. func (s *ss) hexString() string { s.notEOF() for { b, ok := s.hexByte() if !ok { break } s.buf.WriteByte(b) } if len(s.buf) == 0 { s.errorString("no hex data for %x string") return "" } return string(s.buf) } const ( floatVerbs = "beEfFgGv" hugeWid = 1 << 30 intBits = 32 << (^uint(0) >> 63) uintptrBits = 32 << (^uintptr(0) >> 63) ) // scanOne scans a single value, deriving the scanner from the type of the argument. func (s *ss) scanOne(verb rune, arg interface{}) { s.buf = s.buf[:0] var err error // If the parameter has its own Scan method, use that. if v, ok := arg.(Scanner); ok { err = v.Scan(s, verb) if err != nil { if err == io.EOF { err = io.ErrUnexpectedEOF } s.error(err) } return } switch v := arg.(type) { case *bool: *v = s.scanBool(verb) case *complex64: *v = complex64(s.scanComplex(verb, 64)) case *complex128: *v = s.scanComplex(verb, 128) case *int: *v = int(s.scanInt(verb, intBits)) case *int8: *v = int8(s.scanInt(verb, 8)) case *int16: *v = int16(s.scanInt(verb, 16)) case *int32: *v = int32(s.scanInt(verb, 32)) case *int64: *v = s.scanInt(verb, 64) case *uint: *v = uint(s.scanUint(verb, intBits)) case *uint8: *v = uint8(s.scanUint(verb, 8)) case *uint16: *v = uint16(s.scanUint(verb, 16)) case *uint32: *v = uint32(s.scanUint(verb, 32)) case *uint64: *v = s.scanUint(verb, 64) case *uintptr: *v = uintptr(s.scanUint(verb, uintptrBits)) // Floats are tricky because you want to scan in the precision of the result, not // scan in high precision and convert, in order to preserve the correct error condition. case *float32: if s.okVerb(verb, floatVerbs, "float32") { s.SkipSpace() s.notEOF() *v = float32(s.convertFloat(s.floatToken(), 32)) } case *float64: if s.okVerb(verb, floatVerbs, "float64") { s.SkipSpace() s.notEOF() *v = s.convertFloat(s.floatToken(), 64) } case *string: *v = s.convertString(verb) case *[]byte: // We scan to string and convert so we get a copy of the data. // If we scanned to bytes, the slice would point at the buffer. *v = []byte(s.convertString(verb)) default: val := reflect.ValueOf(v) ptr := val if ptr.Kind() != reflect.Ptr { s.errorString("type not a pointer: " + val.Type().String()) return } switch v := ptr.Elem(); v.Kind() { case reflect.Bool: v.SetBool(s.scanBool(verb)) case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: v.SetInt(s.scanInt(verb, v.Type().Bits())) case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr: v.SetUint(s.scanUint(verb, v.Type().Bits())) case reflect.String: v.SetString(s.convertString(verb)) case reflect.Slice: // For now, can only handle (renamed) []byte. typ := v.Type() if typ.Elem().Kind() != reflect.Uint8 { s.errorString("can't scan type: " + val.Type().String()) } str := s.convertString(verb) v.Set(reflect.MakeSlice(typ, len(str), len(str))) for i := 0; i < len(str); i++ { v.Index(i).SetUint(uint64(str[i])) } case reflect.Float32, reflect.Float64: s.SkipSpace() s.notEOF() v.SetFloat(s.convertFloat(s.floatToken(), v.Type().Bits())) case reflect.Complex64, reflect.Complex128: v.SetComplex(s.scanComplex(verb, v.Type().Bits())) default: s.errorString("can't scan type: " + val.Type().String()) } } } // errorHandler turns local panics into error returns. func errorHandler(errp *error) { if e := recover(); e != nil { if se, ok := e.(scanError); ok { // catch local error *errp = se.err } else if eof, ok := e.(error); ok && eof == io.EOF { // out of input *errp = eof } else { panic(e) } } } // doScan does the real work for scanning without a format string. func (s *ss) doScan(a []interface{}) (numProcessed int, err error) { defer errorHandler(&err) for _, arg := range a { s.scanOne('v', arg) numProcessed++ } // Check for newline (or EOF) if required (Scanln etc.). if s.nlIsEnd { for { r := s.getRune() if r == '\n' || r == eof { break } if !isSpace(r) { s.errorString("expected newline") break } } } return } // advance determines whether the next characters in the input match // those of the format. It returns the number of bytes (sic) consumed // in the format. All runs of space characters in either input or // format behave as a single space. Newlines are special, though: // newlines in the format must match those in the input and vice versa. // This routine also handles the %% case. If the return value is zero, // either format starts with a % (with no following %) or the input // is empty. If it is negative, the input did not match the string. func (s *ss) advance(format string) (i int) { for i < len(format) { fmtc, w := utf8.DecodeRuneInString(format[i:]) // Space processing. // In the rest of this comment "space" means spaces other than newline. // Newline in the format matches input of zero or more spaces and then newline or end-of-input. // Spaces in the format before the newline are collapsed into the newline. // Spaces in the format after the newline match zero or more spaces after the corresponding input newline. // Other spaces in the format match input of one or more spaces or end-of-input. if isSpace(fmtc) { newlines := 0 trailingSpace := false for isSpace(fmtc) && i < len(format) { if fmtc == '\n' { newlines++ trailingSpace = false } else { trailingSpace = true } i += w fmtc, w = utf8.DecodeRuneInString(format[i:]) } for j := 0; j < newlines; j++ { inputc := s.getRune() for isSpace(inputc) && inputc != '\n' { inputc = s.getRune() } if inputc != '\n' && inputc != eof { s.errorString("newline in format does not match input") } } if trailingSpace { inputc := s.getRune() if newlines == 0 { // If the trailing space stood alone (did not follow a newline), // it must find at least one space to consume. if !isSpace(inputc) && inputc != eof { s.errorString("expected space in input to match format") } if inputc == '\n' { s.errorString("newline in input does not match format") } } for isSpace(inputc) && inputc != '\n' { inputc = s.getRune() } if inputc != eof { s.UnreadRune() } } continue } // Verbs. if fmtc == '%' { // % at end of string is an error. if i+w == len(format) { s.errorString("missing verb: % at end of format string") } // %% acts like a real percent nextc, _ := utf8.DecodeRuneInString(format[i+w:]) // will not match % if string is empty if nextc != '%' { return } i += w // skip the first % } // Literals. inputc := s.mustReadRune() if fmtc != inputc { s.UnreadRune() return -1 } i += w } return } // doScanf does the real work when scanning with a format string. // At the moment, it handles only pointers to basic types. func (s *ss) doScanf(format string, a []interface{}) (numProcessed int, err error) { defer errorHandler(&err) end := len(format) - 1 // We process one item per non-trivial format for i := 0; i <= end; { w := s.advance(format[i:]) if w > 0 { i += w continue } // Either we failed to advance, we have a percent character, or we ran out of input. if format[i] != '%' { // Can't advance format. Why not? if w < 0 { s.errorString("input does not match format") } // Otherwise at EOF; "too many operands" error handled below break } i++ // % is one byte // do we have 20 (width)? var widPresent bool s.maxWid, widPresent, i = parsenum(format, i, end) if !widPresent { s.maxWid = hugeWid } c, w := utf8.DecodeRuneInString(format[i:]) i += w if c != 'c' { s.SkipSpace() } s.argLimit = s.limit if f := s.count + s.maxWid; f < s.argLimit { s.argLimit = f } if numProcessed >= len(a) { // out of operands s.errorString("too few operands for format '%" + format[i-w:] + "'") break } arg := a[numProcessed] s.scanOne(c, arg) numProcessed++ s.argLimit = s.limit } if numProcessed < len(a) { s.errorString("too many operands") } return } // ssss--------------------------------------------------- // /Users/xah/git/go/src/image/image.go // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package image implements a basic 2-D image library. // // The fundamental interface is called Image. An Image contains colors, which // are described in the image/color package. // // Values of the Image interface are created either by calling functions such // as NewRGBA and NewPaletted, or by calling Decode on an io.Reader containing // image data in a format such as GIF, JPEG or PNG. Decoding any particular // image format requires the prior registration of a decoder function. // Registration is typically automatic as a side effect of initializing that // format's package so that, to decode a PNG image, it suffices to have // import _ "image/png" // in a program's main package. The _ means to import a package purely for its // initialization side effects. // // See "The Go image package" for more details: // https://golang.org/doc/articles/image_package.html package image import ( "image/color" ) // Config holds an image's color model and dimensions. type Config struct { ColorModel color.Model Width, Height int } // Image is a finite rectangular grid of color.Color values taken from a color // model. type Image interface { // ColorModel returns the Image's color model. ColorModel() color.Model // Bounds returns the domain for which At can return non-zero color. // The bounds do not necessarily contain the point (0, 0). Bounds() Rectangle // At returns the color of the pixel at (x, y). // At(Bounds().Min.X, Bounds().Min.Y) returns the upper-left pixel of the grid. // At(Bounds().Max.X-1, Bounds().Max.Y-1) returns the lower-right one. At(x, y int) color.Color } // PalettedImage is an image whose colors may come from a limited palette. // If m is a PalettedImage and m.ColorModel() returns a color.Palette p, // then m.At(x, y) should be equivalent to p[m.ColorIndexAt(x, y)]. If m's // color model is not a color.Palette, then ColorIndexAt's behavior is // undefined. type PalettedImage interface { // ColorIndexAt returns the palette index of the pixel at (x, y). ColorIndexAt(x, y int) uint8 Image } // RGBA is an in-memory image whose At method returns color.RGBA values. type RGBA struct { // Pix holds the image's pixels, in R, G, B, A order. The pixel at // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4]. Pix []uint8 // Stride is the Pix stride (in bytes) between vertically adjacent pixels. Stride int // Rect is the image's bounds. Rect Rectangle } func (p *RGBA) ColorModel() color.Model { return color.RGBAModel } func (p *RGBA) Bounds() Rectangle { return p.Rect } func (p *RGBA) At(x, y int) color.Color { return p.RGBAAt(x, y) } func (p *RGBA) RGBAAt(x, y int) color.RGBA { if !(Point{x, y}.In(p.Rect)) { return color.RGBA{} } i := p.PixOffset(x, y) return color.RGBA{p.Pix[i+0], p.Pix[i+1], p.Pix[i+2], p.Pix[i+3]} } // PixOffset returns the index of the first element of Pix that corresponds to // the pixel at (x, y). func (p *RGBA) PixOffset(x, y int) int { return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4 } func (p *RGBA) Set(x, y int, c color.Color) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) c1 := color.RGBAModel.Convert(c).(color.RGBA) p.Pix[i+0] = c1.R p.Pix[i+1] = c1.G p.Pix[i+2] = c1.B p.Pix[i+3] = c1.A } func (p *RGBA) SetRGBA(x, y int, c color.RGBA) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) p.Pix[i+0] = c.R p.Pix[i+1] = c.G p.Pix[i+2] = c.B p.Pix[i+3] = c.A } // SubImage returns an image representing the portion of the image p visible // through r. The returned value shares pixels with the original image. func (p *RGBA) SubImage(r Rectangle) Image { r = r.Intersect(p.Rect) // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside // either r1 or r2 if the intersection is empty. Without explicitly checking for // this, the Pix[i:] expression below can panic. if r.Empty() { return &RGBA{} } i := p.PixOffset(r.Min.X, r.Min.Y) return &RGBA{ Pix: p.Pix[i:], Stride: p.Stride, Rect: r, } } // Opaque scans the entire image and reports whether it is fully opaque. func (p *RGBA) Opaque() bool { if p.Rect.Empty() { return true } i0, i1 := 3, p.Rect.Dx()*4 for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ { for i := i0; i < i1; i += 4 { if p.Pix[i] != 0xff { return false } } i0 += p.Stride i1 += p.Stride } return true } // NewRGBA returns a new RGBA image with the given bounds. func NewRGBA(r Rectangle) *RGBA { w, h := r.Dx(), r.Dy() buf := make([]uint8, 4*w*h) return &RGBA{buf, 4 * w, r} } // RGBA64 is an in-memory image whose At method returns color.RGBA64 values. type RGBA64 struct { // Pix holds the image's pixels, in R, G, B, A order and big-endian format. The pixel at // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*8]. Pix []uint8 // Stride is the Pix stride (in bytes) between vertically adjacent pixels. Stride int // Rect is the image's bounds. Rect Rectangle } func (p *RGBA64) ColorModel() color.Model { return color.RGBA64Model } func (p *RGBA64) Bounds() Rectangle { return p.Rect } func (p *RGBA64) At(x, y int) color.Color { return p.RGBA64At(x, y) } func (p *RGBA64) RGBA64At(x, y int) color.RGBA64 { if !(Point{x, y}.In(p.Rect)) { return color.RGBA64{} } i := p.PixOffset(x, y) return color.RGBA64{ uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1]), uint16(p.Pix[i+2])<<8 | uint16(p.Pix[i+3]), uint16(p.Pix[i+4])<<8 | uint16(p.Pix[i+5]), uint16(p.Pix[i+6])<<8 | uint16(p.Pix[i+7]), } } // PixOffset returns the index of the first element of Pix that corresponds to // the pixel at (x, y). func (p *RGBA64) PixOffset(x, y int) int { return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*8 } func (p *RGBA64) Set(x, y int, c color.Color) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) c1 := color.RGBA64Model.Convert(c).(color.RGBA64) p.Pix[i+0] = uint8(c1.R >> 8) p.Pix[i+1] = uint8(c1.R) p.Pix[i+2] = uint8(c1.G >> 8) p.Pix[i+3] = uint8(c1.G) p.Pix[i+4] = uint8(c1.B >> 8) p.Pix[i+5] = uint8(c1.B) p.Pix[i+6] = uint8(c1.A >> 8) p.Pix[i+7] = uint8(c1.A) } func (p *RGBA64) SetRGBA64(x, y int, c color.RGBA64) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) p.Pix[i+0] = uint8(c.R >> 8) p.Pix[i+1] = uint8(c.R) p.Pix[i+2] = uint8(c.G >> 8) p.Pix[i+3] = uint8(c.G) p.Pix[i+4] = uint8(c.B >> 8) p.Pix[i+5] = uint8(c.B) p.Pix[i+6] = uint8(c.A >> 8) p.Pix[i+7] = uint8(c.A) } // SubImage returns an image representing the portion of the image p visible // through r. The returned value shares pixels with the original image. func (p *RGBA64) SubImage(r Rectangle) Image { r = r.Intersect(p.Rect) // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside // either r1 or r2 if the intersection is empty. Without explicitly checking for // this, the Pix[i:] expression below can panic. if r.Empty() { return &RGBA64{} } i := p.PixOffset(r.Min.X, r.Min.Y) return &RGBA64{ Pix: p.Pix[i:], Stride: p.Stride, Rect: r, } } // Opaque scans the entire image and reports whether it is fully opaque. func (p *RGBA64) Opaque() bool { if p.Rect.Empty() { return true } i0, i1 := 6, p.Rect.Dx()*8 for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ { for i := i0; i < i1; i += 8 { if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff { return false } } i0 += p.Stride i1 += p.Stride } return true } // NewRGBA64 returns a new RGBA64 image with the given bounds. func NewRGBA64(r Rectangle) *RGBA64 { w, h := r.Dx(), r.Dy() pix := make([]uint8, 8*w*h) return &RGBA64{pix, 8 * w, r} } // NRGBA is an in-memory image whose At method returns color.NRGBA values. type NRGBA struct { // Pix holds the image's pixels, in R, G, B, A order. The pixel at // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4]. Pix []uint8 // Stride is the Pix stride (in bytes) between vertically adjacent pixels. Stride int // Rect is the image's bounds. Rect Rectangle } func (p *NRGBA) ColorModel() color.Model { return color.NRGBAModel } func (p *NRGBA) Bounds() Rectangle { return p.Rect } func (p *NRGBA) At(x, y int) color.Color { return p.NRGBAAt(x, y) } func (p *NRGBA) NRGBAAt(x, y int) color.NRGBA { if !(Point{x, y}.In(p.Rect)) { return color.NRGBA{} } i := p.PixOffset(x, y) return color.NRGBA{p.Pix[i+0], p.Pix[i+1], p.Pix[i+2], p.Pix[i+3]} } // PixOffset returns the index of the first element of Pix that corresponds to // the pixel at (x, y). func (p *NRGBA) PixOffset(x, y int) int { return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4 } func (p *NRGBA) Set(x, y int, c color.Color) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) c1 := color.NRGBAModel.Convert(c).(color.NRGBA) p.Pix[i+0] = c1.R p.Pix[i+1] = c1.G p.Pix[i+2] = c1.B p.Pix[i+3] = c1.A } func (p *NRGBA) SetNRGBA(x, y int, c color.NRGBA) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) p.Pix[i+0] = c.R p.Pix[i+1] = c.G p.Pix[i+2] = c.B p.Pix[i+3] = c.A } // SubImage returns an image representing the portion of the image p visible // through r. The returned value shares pixels with the original image. func (p *NRGBA) SubImage(r Rectangle) Image { r = r.Intersect(p.Rect) // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside // either r1 or r2 if the intersection is empty. Without explicitly checking for // this, the Pix[i:] expression below can panic. if r.Empty() { return &NRGBA{} } i := p.PixOffset(r.Min.X, r.Min.Y) return &NRGBA{ Pix: p.Pix[i:], Stride: p.Stride, Rect: r, } } // Opaque scans the entire image and reports whether it is fully opaque. func (p *NRGBA) Opaque() bool { if p.Rect.Empty() { return true } i0, i1 := 3, p.Rect.Dx()*4 for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ { for i := i0; i < i1; i += 4 { if p.Pix[i] != 0xff { return false } } i0 += p.Stride i1 += p.Stride } return true } // NewNRGBA returns a new NRGBA image with the given bounds. func NewNRGBA(r Rectangle) *NRGBA { w, h := r.Dx(), r.Dy() pix := make([]uint8, 4*w*h) return &NRGBA{pix, 4 * w, r} } // NRGBA64 is an in-memory image whose At method returns color.NRGBA64 values. type NRGBA64 struct { // Pix holds the image's pixels, in R, G, B, A order and big-endian format. The pixel at // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*8]. Pix []uint8 // Stride is the Pix stride (in bytes) between vertically adjacent pixels. Stride int // Rect is the image's bounds. Rect Rectangle } func (p *NRGBA64) ColorModel() color.Model { return color.NRGBA64Model } func (p *NRGBA64) Bounds() Rectangle { return p.Rect } func (p *NRGBA64) At(x, y int) color.Color { return p.NRGBA64At(x, y) } func (p *NRGBA64) NRGBA64At(x, y int) color.NRGBA64 { if !(Point{x, y}.In(p.Rect)) { return color.NRGBA64{} } i := p.PixOffset(x, y) return color.NRGBA64{ uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1]), uint16(p.Pix[i+2])<<8 | uint16(p.Pix[i+3]), uint16(p.Pix[i+4])<<8 | uint16(p.Pix[i+5]), uint16(p.Pix[i+6])<<8 | uint16(p.Pix[i+7]), } } // PixOffset returns the index of the first element of Pix that corresponds to // the pixel at (x, y). func (p *NRGBA64) PixOffset(x, y int) int { return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*8 } func (p *NRGBA64) Set(x, y int, c color.Color) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) c1 := color.NRGBA64Model.Convert(c).(color.NRGBA64) p.Pix[i+0] = uint8(c1.R >> 8) p.Pix[i+1] = uint8(c1.R) p.Pix[i+2] = uint8(c1.G >> 8) p.Pix[i+3] = uint8(c1.G) p.Pix[i+4] = uint8(c1.B >> 8) p.Pix[i+5] = uint8(c1.B) p.Pix[i+6] = uint8(c1.A >> 8) p.Pix[i+7] = uint8(c1.A) } func (p *NRGBA64) SetNRGBA64(x, y int, c color.NRGBA64) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) p.Pix[i+0] = uint8(c.R >> 8) p.Pix[i+1] = uint8(c.R) p.Pix[i+2] = uint8(c.G >> 8) p.Pix[i+3] = uint8(c.G) p.Pix[i+4] = uint8(c.B >> 8) p.Pix[i+5] = uint8(c.B) p.Pix[i+6] = uint8(c.A >> 8) p.Pix[i+7] = uint8(c.A) } // SubImage returns an image representing the portion of the image p visible // through r. The returned value shares pixels with the original image. func (p *NRGBA64) SubImage(r Rectangle) Image { r = r.Intersect(p.Rect) // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside // either r1 or r2 if the intersection is empty. Without explicitly checking for // this, the Pix[i:] expression below can panic. if r.Empty() { return &NRGBA64{} } i := p.PixOffset(r.Min.X, r.Min.Y) return &NRGBA64{ Pix: p.Pix[i:], Stride: p.Stride, Rect: r, } } // Opaque scans the entire image and reports whether it is fully opaque. func (p *NRGBA64) Opaque() bool { if p.Rect.Empty() { return true } i0, i1 := 6, p.Rect.Dx()*8 for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ { for i := i0; i < i1; i += 8 { if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff { return false } } i0 += p.Stride i1 += p.Stride } return true } // NewNRGBA64 returns a new NRGBA64 image with the given bounds. func NewNRGBA64(r Rectangle) *NRGBA64 { w, h := r.Dx(), r.Dy() pix := make([]uint8, 8*w*h) return &NRGBA64{pix, 8 * w, r} } // Alpha is an in-memory image whose At method returns color.Alpha values. type Alpha struct { // Pix holds the image's pixels, as alpha values. The pixel at // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1]. Pix []uint8 // Stride is the Pix stride (in bytes) between vertically adjacent pixels. Stride int // Rect is the image's bounds. Rect Rectangle } func (p *Alpha) ColorModel() color.Model { return color.AlphaModel } func (p *Alpha) Bounds() Rectangle { return p.Rect } func (p *Alpha) At(x, y int) color.Color { return p.AlphaAt(x, y) } func (p *Alpha) AlphaAt(x, y int) color.Alpha { if !(Point{x, y}.In(p.Rect)) { return color.Alpha{} } i := p.PixOffset(x, y) return color.Alpha{p.Pix[i]} } // PixOffset returns the index of the first element of Pix that corresponds to // the pixel at (x, y). func (p *Alpha) PixOffset(x, y int) int { return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1 } func (p *Alpha) Set(x, y int, c color.Color) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) p.Pix[i] = color.AlphaModel.Convert(c).(color.Alpha).A } func (p *Alpha) SetAlpha(x, y int, c color.Alpha) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) p.Pix[i] = c.A } // SubImage returns an image representing the portion of the image p visible // through r. The returned value shares pixels with the original image. func (p *Alpha) SubImage(r Rectangle) Image { r = r.Intersect(p.Rect) // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside // either r1 or r2 if the intersection is empty. Without explicitly checking for // this, the Pix[i:] expression below can panic. if r.Empty() { return &Alpha{} } i := p.PixOffset(r.Min.X, r.Min.Y) return &Alpha{ Pix: p.Pix[i:], Stride: p.Stride, Rect: r, } } // Opaque scans the entire image and reports whether it is fully opaque. func (p *Alpha) Opaque() bool { if p.Rect.Empty() { return true } i0, i1 := 0, p.Rect.Dx() for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ { for i := i0; i < i1; i++ { if p.Pix[i] != 0xff { return false } } i0 += p.Stride i1 += p.Stride } return true } // NewAlpha returns a new Alpha image with the given bounds. func NewAlpha(r Rectangle) *Alpha { w, h := r.Dx(), r.Dy() pix := make([]uint8, 1*w*h) return &Alpha{pix, 1 * w, r} } // Alpha16 is an in-memory image whose At method returns color.Alpha16 values. type Alpha16 struct { // Pix holds the image's pixels, as alpha values in big-endian format. The pixel at // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*2]. Pix []uint8 // Stride is the Pix stride (in bytes) between vertically adjacent pixels. Stride int // Rect is the image's bounds. Rect Rectangle } func (p *Alpha16) ColorModel() color.Model { return color.Alpha16Model } func (p *Alpha16) Bounds() Rectangle { return p.Rect } func (p *Alpha16) At(x, y int) color.Color { return p.Alpha16At(x, y) } func (p *Alpha16) Alpha16At(x, y int) color.Alpha16 { if !(Point{x, y}.In(p.Rect)) { return color.Alpha16{} } i := p.PixOffset(x, y) return color.Alpha16{uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1])} } // PixOffset returns the index of the first element of Pix that corresponds to // the pixel at (x, y). func (p *Alpha16) PixOffset(x, y int) int { return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*2 } func (p *Alpha16) Set(x, y int, c color.Color) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) c1 := color.Alpha16Model.Convert(c).(color.Alpha16) p.Pix[i+0] = uint8(c1.A >> 8) p.Pix[i+1] = uint8(c1.A) } func (p *Alpha16) SetAlpha16(x, y int, c color.Alpha16) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) p.Pix[i+0] = uint8(c.A >> 8) p.Pix[i+1] = uint8(c.A) } // SubImage returns an image representing the portion of the image p visible // through r. The returned value shares pixels with the original image. func (p *Alpha16) SubImage(r Rectangle) Image { r = r.Intersect(p.Rect) // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside // either r1 or r2 if the intersection is empty. Without explicitly checking for // this, the Pix[i:] expression below can panic. if r.Empty() { return &Alpha16{} } i := p.PixOffset(r.Min.X, r.Min.Y) return &Alpha16{ Pix: p.Pix[i:], Stride: p.Stride, Rect: r, } } // Opaque scans the entire image and reports whether it is fully opaque. func (p *Alpha16) Opaque() bool { if p.Rect.Empty() { return true } i0, i1 := 0, p.Rect.Dx()*2 for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ { for i := i0; i < i1; i += 2 { if p.Pix[i+0] != 0xff || p.Pix[i+1] != 0xff { return false } } i0 += p.Stride i1 += p.Stride } return true } // NewAlpha16 returns a new Alpha16 image with the given bounds. func NewAlpha16(r Rectangle) *Alpha16 { w, h := r.Dx(), r.Dy() pix := make([]uint8, 2*w*h) return &Alpha16{pix, 2 * w, r} } // Gray is an in-memory image whose At method returns color.Gray values. type Gray struct { // Pix holds the image's pixels, as gray values. The pixel at // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1]. Pix []uint8 // Stride is the Pix stride (in bytes) between vertically adjacent pixels. Stride int // Rect is the image's bounds. Rect Rectangle } func (p *Gray) ColorModel() color.Model { return color.GrayModel } func (p *Gray) Bounds() Rectangle { return p.Rect } func (p *Gray) At(x, y int) color.Color { return p.GrayAt(x, y) } func (p *Gray) GrayAt(x, y int) color.Gray { if !(Point{x, y}.In(p.Rect)) { return color.Gray{} } i := p.PixOffset(x, y) return color.Gray{p.Pix[i]} } // PixOffset returns the index of the first element of Pix that corresponds to // the pixel at (x, y). func (p *Gray) PixOffset(x, y int) int { return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1 } func (p *Gray) Set(x, y int, c color.Color) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) p.Pix[i] = color.GrayModel.Convert(c).(color.Gray).Y } func (p *Gray) SetGray(x, y int, c color.Gray) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) p.Pix[i] = c.Y } // SubImage returns an image representing the portion of the image p visible // through r. The returned value shares pixels with the original image. func (p *Gray) SubImage(r Rectangle) Image { r = r.Intersect(p.Rect) // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside // either r1 or r2 if the intersection is empty. Without explicitly checking for // this, the Pix[i:] expression below can panic. if r.Empty() { return &Gray{} } i := p.PixOffset(r.Min.X, r.Min.Y) return &Gray{ Pix: p.Pix[i:], Stride: p.Stride, Rect: r, } } // Opaque scans the entire image and reports whether it is fully opaque. func (p *Gray) Opaque() bool { return true } // NewGray returns a new Gray image with the given bounds. func NewGray(r Rectangle) *Gray { w, h := r.Dx(), r.Dy() pix := make([]uint8, 1*w*h) return &Gray{pix, 1 * w, r} } // Gray16 is an in-memory image whose At method returns color.Gray16 values. type Gray16 struct { // Pix holds the image's pixels, as gray values in big-endian format. The pixel at // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*2]. Pix []uint8 // Stride is the Pix stride (in bytes) between vertically adjacent pixels. Stride int // Rect is the image's bounds. Rect Rectangle } func (p *Gray16) ColorModel() color.Model { return color.Gray16Model } func (p *Gray16) Bounds() Rectangle { return p.Rect } func (p *Gray16) At(x, y int) color.Color { return p.Gray16At(x, y) } func (p *Gray16) Gray16At(x, y int) color.Gray16 { if !(Point{x, y}.In(p.Rect)) { return color.Gray16{} } i := p.PixOffset(x, y) return color.Gray16{uint16(p.Pix[i+0])<<8 | uint16(p.Pix[i+1])} } // PixOffset returns the index of the first element of Pix that corresponds to // the pixel at (x, y). func (p *Gray16) PixOffset(x, y int) int { return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*2 } func (p *Gray16) Set(x, y int, c color.Color) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) c1 := color.Gray16Model.Convert(c).(color.Gray16) p.Pix[i+0] = uint8(c1.Y >> 8) p.Pix[i+1] = uint8(c1.Y) } func (p *Gray16) SetGray16(x, y int, c color.Gray16) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) p.Pix[i+0] = uint8(c.Y >> 8) p.Pix[i+1] = uint8(c.Y) } // SubImage returns an image representing the portion of the image p visible // through r. The returned value shares pixels with the original image. func (p *Gray16) SubImage(r Rectangle) Image { r = r.Intersect(p.Rect) // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside // either r1 or r2 if the intersection is empty. Without explicitly checking for // this, the Pix[i:] expression below can panic. if r.Empty() { return &Gray16{} } i := p.PixOffset(r.Min.X, r.Min.Y) return &Gray16{ Pix: p.Pix[i:], Stride: p.Stride, Rect: r, } } // Opaque scans the entire image and reports whether it is fully opaque. func (p *Gray16) Opaque() bool { return true } // NewGray16 returns a new Gray16 image with the given bounds. func NewGray16(r Rectangle) *Gray16 { w, h := r.Dx(), r.Dy() pix := make([]uint8, 2*w*h) return &Gray16{pix, 2 * w, r} } // CMYK is an in-memory image whose At method returns color.CMYK values. type CMYK struct { // Pix holds the image's pixels, in C, M, Y, K order. The pixel at // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*4]. Pix []uint8 // Stride is the Pix stride (in bytes) between vertically adjacent pixels. Stride int // Rect is the image's bounds. Rect Rectangle } func (p *CMYK) ColorModel() color.Model { return color.CMYKModel } func (p *CMYK) Bounds() Rectangle { return p.Rect } func (p *CMYK) At(x, y int) color.Color { return p.CMYKAt(x, y) } func (p *CMYK) CMYKAt(x, y int) color.CMYK { if !(Point{x, y}.In(p.Rect)) { return color.CMYK{} } i := p.PixOffset(x, y) return color.CMYK{p.Pix[i+0], p.Pix[i+1], p.Pix[i+2], p.Pix[i+3]} } // PixOffset returns the index of the first element of Pix that corresponds to // the pixel at (x, y). func (p *CMYK) PixOffset(x, y int) int { return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*4 } func (p *CMYK) Set(x, y int, c color.Color) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) c1 := color.CMYKModel.Convert(c).(color.CMYK) p.Pix[i+0] = c1.C p.Pix[i+1] = c1.M p.Pix[i+2] = c1.Y p.Pix[i+3] = c1.K } func (p *CMYK) SetCMYK(x, y int, c color.CMYK) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) p.Pix[i+0] = c.C p.Pix[i+1] = c.M p.Pix[i+2] = c.Y p.Pix[i+3] = c.K } // SubImage returns an image representing the portion of the image p visible // through r. The returned value shares pixels with the original image. func (p *CMYK) SubImage(r Rectangle) Image { r = r.Intersect(p.Rect) // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside // either r1 or r2 if the intersection is empty. Without explicitly checking for // this, the Pix[i:] expression below can panic. if r.Empty() { return &CMYK{} } i := p.PixOffset(r.Min.X, r.Min.Y) return &CMYK{ Pix: p.Pix[i:], Stride: p.Stride, Rect: r, } } // Opaque scans the entire image and reports whether it is fully opaque. func (p *CMYK) Opaque() bool { return true } // NewCMYK returns a new CMYK image with the given bounds. func NewCMYK(r Rectangle) *CMYK { w, h := r.Dx(), r.Dy() buf := make([]uint8, 4*w*h) return &CMYK{buf, 4 * w, r} } // Paletted is an in-memory image of uint8 indices into a given palette. type Paletted struct { // Pix holds the image's pixels, as palette indices. The pixel at // (x, y) starts at Pix[(y-Rect.Min.Y)*Stride + (x-Rect.Min.X)*1]. Pix []uint8 // Stride is the Pix stride (in bytes) between vertically adjacent pixels. Stride int // Rect is the image's bounds. Rect Rectangle // Palette is the image's palette. Palette color.Palette } func (p *Paletted) ColorModel() color.Model { return p.Palette } func (p *Paletted) Bounds() Rectangle { return p.Rect } func (p *Paletted) At(x, y int) color.Color { if len(p.Palette) == 0 { return nil } if !(Point{x, y}.In(p.Rect)) { return p.Palette[0] } i := p.PixOffset(x, y) return p.Palette[p.Pix[i]] } // PixOffset returns the index of the first element of Pix that corresponds to // the pixel at (x, y). func (p *Paletted) PixOffset(x, y int) int { return (y-p.Rect.Min.Y)*p.Stride + (x-p.Rect.Min.X)*1 } func (p *Paletted) Set(x, y int, c color.Color) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) p.Pix[i] = uint8(p.Palette.Index(c)) } func (p *Paletted) ColorIndexAt(x, y int) uint8 { if !(Point{x, y}.In(p.Rect)) { return 0 } i := p.PixOffset(x, y) return p.Pix[i] } func (p *Paletted) SetColorIndex(x, y int, index uint8) { if !(Point{x, y}.In(p.Rect)) { return } i := p.PixOffset(x, y) p.Pix[i] = index } // SubImage returns an image representing the portion of the image p visible // through r. The returned value shares pixels with the original image. func (p *Paletted) SubImage(r Rectangle) Image { r = r.Intersect(p.Rect) // If r1 and r2 are Rectangles, r1.Intersect(r2) is not guaranteed to be inside // either r1 or r2 if the intersection is empty. Without explicitly checking for // this, the Pix[i:] expression below can panic. if r.Empty() { return &Paletted{ Palette: p.Palette, } } i := p.PixOffset(r.Min.X, r.Min.Y) return &Paletted{ Pix: p.Pix[i:], Stride: p.Stride, Rect: p.Rect.Intersect(r), Palette: p.Palette, } } // Opaque scans the entire image and reports whether it is fully opaque. func (p *Paletted) Opaque() bool { var present [256]bool i0, i1 := 0, p.Rect.Dx() for y := p.Rect.Min.Y; y < p.Rect.Max.Y; y++ { for _, c := range p.Pix[i0:i1] { present[c] = true } i0 += p.Stride i1 += p.Stride } for i, c := range p.Palette { if !present[i] { continue } _, _, _, a := c.RGBA() if a != 0xffff { return false } } return true } // NewPaletted returns a new Paletted image with the given width, height and // palette. func NewPaletted(r Rectangle, p color.Palette) *Paletted { w, h := r.Dx(), r.Dy() pix := make([]uint8, 1*w*h) return &Paletted{pix, 1 * w, r, p} } // ssss--------------------------------------------------- // /Users/xah/git/go/src/net/dial.go // Copyright 2010 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package net import ( "context" "internal/nettrace" "internal/poll" "time" ) // A Dialer contains options for connecting to an address. // // The zero value for each field is equivalent to dialing // without that option. Dialing with the zero value of Dialer // is therefore equivalent to just calling the Dial function. type Dialer struct { // Timeout is the maximum amount of time a dial will wait for // a connect to complete. If Deadline is also set, it may fail // earlier. // // The default is no timeout. // // When using TCP and dialing a host name with multiple IP // addresses, the timeout may be divided between them. // // With or without a timeout, the operating system may impose // its own earlier timeout. For instance, TCP timeouts are // often around 3 minutes. Timeout time.Duration // Deadline is the absolute point in time after which dials // will fail. If Timeout is set, it may fail earlier. // Zero means no deadline, or dependent on the operating system // as with the Timeout option. Deadline time.Time // LocalAddr is the local address to use when dialing an // address. The address must be of a compatible type for the // network being dialed. // If nil, a local address is automatically chosen. LocalAddr Addr // DualStack enables RFC 6555-compliant "Happy Eyeballs" // dialing when the network is "tcp" and the host in the // address parameter resolves to both IPv4 and IPv6 addresses. // This allows a client to tolerate networks where one address // family is silently broken. DualStack bool // FallbackDelay specifies the length of time to wait before // spawning a fallback connection, when DualStack is enabled. // If zero, a default delay of 300ms is used. FallbackDelay time.Duration // KeepAlive specifies the keep-alive period for an active // network connection. // If zero, keep-alives are not enabled. Network protocols // that do not support keep-alives ignore this field. KeepAlive time.Duration // Resolver optionally specifies an alternate resolver to use. Resolver *Resolver // Cancel is an optional channel whose closure indicates that // the dial should be canceled. Not all types of dials support // cancelation. // // Deprecated: Use DialContext instead. Cancel <-chan struct{} } func minNonzeroTime(a, b time.Time) time.Time { if a.IsZero() { return b } if b.IsZero() || a.Before(b) { return a } return b } // deadline returns the earliest of: // - now+Timeout // - d.Deadline // - the context's deadline // Or zero, if none of Timeout, Deadline, or context's deadline is set. func (d *Dialer) deadline(ctx context.Context, now time.Time) (earliest time.Time) { if d.Timeout != 0 { // including negative, for historical reasons earliest = now.Add(d.Timeout) } if d, ok := ctx.Deadline(); ok { earliest = minNonzeroTime(earliest, d) } return minNonzeroTime(earliest, d.Deadline) } func (d *Dialer) resolver() *Resolver { if d.Resolver != nil { return d.Resolver } return DefaultResolver } // partialDeadline returns the deadline to use for a single address, // when multiple addresses are pending. func partialDeadline(now, deadline time.Time, addrsRemaining int) (time.Time, error) { if deadline.IsZero() { return deadline, nil } timeRemaining := deadline.Sub(now) if timeRemaining <= 0 { return time.Time{}, poll.ErrTimeout } // Tentatively allocate equal time to each remaining address. timeout := timeRemaining / time.Duration(addrsRemaining) // If the time per address is too short, steal from the end of the list. const saneMinimum = 2 * time.Second if timeout < saneMinimum { if timeRemaining < saneMinimum { timeout = timeRemaining } else { timeout = saneMinimum } } return now.Add(timeout), nil } func (d *Dialer) fallbackDelay() time.Duration { if d.FallbackDelay > 0 { return d.FallbackDelay } else { return 300 * time.Millisecond } } func parseNetwork(ctx context.Context, network string, needsProto bool) (afnet string, proto int, err error) { i := last(network, ':') if i < 0 { // no colon switch network { case "tcp", "tcp4", "tcp6": case "udp", "udp4", "udp6": case "ip", "ip4", "ip6": if needsProto { return "", 0, UnknownNetworkError(network) } case "unix", "unixgram", "unixpacket": default: return "", 0, UnknownNetworkError(network) } return network, 0, nil } afnet = network[:i] switch afnet { case "ip", "ip4", "ip6": protostr := network[i+1:] proto, i, ok := dtoi(protostr) if !ok || i != len(protostr) { proto, err = lookupProtocol(ctx, protostr) if err != nil { return "", 0, err } } return afnet, proto, nil } return "", 0, UnknownNetworkError(network) } // resolveAddrList resolves addr using hint and returns a list of // addresses. The result contains at least one address when error is // nil. func (r *Resolver) resolveAddrList(ctx context.Context, op, network, addr string, hint Addr) (addrList, error) { afnet, _, err := parseNetwork(ctx, network, true) if err != nil { return nil, err } if op == "dial" && addr == "" { return nil, errMissingAddress } switch afnet { case "unix", "unixgram", "unixpacket": addr, err := ResolveUnixAddr(afnet, addr) if err != nil { return nil, err } if op == "dial" && hint != nil && addr.Network() != hint.Network() { return nil, &AddrError{Err: "mismatched local address type", Addr: hint.String()} } return addrList{addr}, nil } addrs, err := r.internetAddrList(ctx, afnet, addr) if err != nil || op != "dial" || hint == nil { return addrs, err } var ( tcp *TCPAddr udp *UDPAddr ip *IPAddr wildcard bool ) switch hint := hint.(type) { case *TCPAddr: tcp = hint wildcard = tcp.isWildcard() case *UDPAddr: udp = hint wildcard = udp.isWildcard() case *IPAddr: ip = hint wildcard = ip.isWildcard() } naddrs := addrs[:0] for _, addr := range addrs { if addr.Network() != hint.Network() { return nil, &AddrError{Err: "mismatched local address type", Addr: hint.String()} } switch addr := addr.(type) { case *TCPAddr: if !wildcard && !addr.isWildcard() && !addr.IP.matchAddrFamily(tcp.IP) { continue } naddrs = append(naddrs, addr) case *UDPAddr: if !wildcard && !addr.isWildcard() && !addr.IP.matchAddrFamily(udp.IP) { continue } naddrs = append(naddrs, addr) case *IPAddr: if !wildcard && !addr.isWildcard() && !addr.IP.matchAddrFamily(ip.IP) { continue } naddrs = append(naddrs, addr) } } if len(naddrs) == 0 { return nil, &AddrError{Err: errNoSuitableAddress.Error(), Addr: hint.String()} } return naddrs, nil } // Dial connects to the address on the named network. // // Known networks are "tcp", "tcp4" (IPv4-only), "tcp6" (IPv6-only), // "udp", "udp4" (IPv4-only), "udp6" (IPv6-only), "ip", "ip4" // (IPv4-only), "ip6" (IPv6-only), "unix", "unixgram" and // "unixpacket". // // For TCP and UDP networks, the address has the form "host:port". // The host must be a literal IP address, or a host name that can be // resolved to IP addresses. // The port must be a literal port number or a service name. // If the host is a literal IPv6 address it must be enclosed in square // brackets, as in "[2001:db8::1]:80" or "[fe80::1%zone]:80". // The zone specifies the scope of the literal IPv6 address as defined // in RFC 4007. // The functions JoinHostPort and SplitHostPort manipulate a pair of // host and port in this form. // When using TCP, and the host resolves to multiple IP addresses, // Dial will try each IP address in order until one succeeds. // // Examples: // Dial("tcp", "golang.org:http") // Dial("tcp", "192.0.2.1:http") // Dial("tcp", "198.51.100.1:80") // Dial("udp", "[2001:db8::1]:domain") // Dial("udp", "[fe80::1%lo0]:53") // Dial("tcp", ":80") // // For IP networks, the network must be "ip", "ip4" or "ip6" followed // by a colon and a literal protocol number or a protocol name, and // the address has the form "host". The host must be a literal IP // address or a literal IPv6 address with zone. // It depends on each operating system how the operating system // behaves with a non-well known protocol number such as "0" or "255". // // Examples: // Dial("ip4:1", "192.0.2.1") // Dial("ip6:ipv6-icmp", "2001:db8::1") // Dial("ip6:58", "fe80::1%lo0") // // For TCP, UDP and IP networks, if the host is empty or a literal // unspecified IP address, as in ":80", "0.0.0.0:80" or "[::]:80" for // TCP and UDP, "", "0.0.0.0" or "::" for IP, the local system is // assumed. // // For Unix networks, the address must be a file system path. func Dial(network, address string) (Conn, error) { var d Dialer return d.Dial(network, address) } // DialTimeout acts like Dial but takes a timeout. // // The timeout includes name resolution, if required. // When using TCP, and the host in the address parameter resolves to // multiple IP addresses, the timeout is spread over each consecutive // dial, such that each is given an appropriate fraction of the time // to connect. // // See func Dial for a description of the network and address // parameters. func DialTimeout(network, address string, timeout time.Duration) (Conn, error) { d := Dialer{Timeout: timeout} return d.Dial(network, address) } // dialParam contains a Dial's parameters and configuration. type dialParam struct { Dialer network, address string } // Dial connects to the address on the named network. // // See func Dial for a description of the network and address // parameters. func (d *Dialer) Dial(network, address string) (Conn, error) { return d.DialContext(context.Background(), network, address) } // DialContext connects to the address on the named network using // the provided context. // // The provided Context must be non-nil. If the context expires before // the connection is complete, an error is returned. Once successfully // connected, any expiration of the context will not affect the // connection. // // When using TCP, and the host in the address parameter resolves to multiple // network addresses, any dial timeout (from d.Timeout or ctx) is spread // over each consecutive dial, such that each is given an appropriate // fraction of the time to connect. // For example, if a host has 4 IP addresses and the timeout is 1 minute, // the connect to each single address will be given 15 seconds to complete // before trying the next one. // // See func Dial for a description of the network and address // parameters. func (d *Dialer) DialContext(ctx context.Context, network, address string) (Conn, error) { if ctx == nil { panic("nil context") } deadline := d.deadline(ctx, time.Now()) if !deadline.IsZero() { if d, ok := ctx.Deadline(); !ok || deadline.Before(d) { subCtx, cancel := context.WithDeadline(ctx, deadline) defer cancel() ctx = subCtx } } if oldCancel := d.Cancel; oldCancel != nil { subCtx, cancel := context.WithCancel(ctx) defer cancel() go func() { select { case <-oldCancel: cancel() case <-subCtx.Done(): } }() ctx = subCtx } // Shadow the nettrace (if any) during resolve so Connect events don't fire for DNS lookups. resolveCtx := ctx if trace, _ := ctx.Value(nettrace.TraceKey{}).(*nettrace.Trace); trace != nil { shadow := *trace shadow.ConnectStart = nil shadow.ConnectDone = nil resolveCtx = context.WithValue(resolveCtx, nettrace.TraceKey{}, &shadow) } addrs, err := d.resolver().resolveAddrList(resolveCtx, "dial", network, address, d.LocalAddr) if err != nil { return nil, &OpError{Op: "dial", Net: network, Source: nil, Addr: nil, Err: err} } dp := &dialParam{ Dialer: *d, network: network, address: address, } var primaries, fallbacks addrList if d.DualStack && network == "tcp" { primaries, fallbacks = addrs.partition(isIPv4) } else { primaries = addrs } var c Conn if len(fallbacks) > 0 { c, err = dialParallel(ctx, dp, primaries, fallbacks) } else { c, err = dialSerial(ctx, dp, primaries) } if err != nil { return nil, err } if tc, ok := c.(*TCPConn); ok && d.KeepAlive > 0 { setKeepAlive(tc.fd, true) setKeepAlivePeriod(tc.fd, d.KeepAlive) testHookSetKeepAlive() } return c, nil } // dialParallel races two copies of dialSerial, giving the first a // head start. It returns the first established connection and // closes the others. Otherwise it returns an error from the first // primary address. func dialParallel(ctx context.Context, dp *dialParam, primaries, fallbacks addrList) (Conn, error) { if len(fallbacks) == 0 { return dialSerial(ctx, dp, primaries) } returned := make(chan struct{}) defer close(returned) type dialResult struct { Conn error primary bool done bool } results := make(chan dialResult) // unbuffered startRacer := func(ctx context.Context, primary bool) { ras := primaries if !primary { ras = fallbacks } c, err := dialSerial(ctx, dp, ras) select { case results <- dialResult{Conn: c, error: err, primary: primary, done: true}: case <-returned: if c != nil { c.Close() } } } var primary, fallback dialResult // Start the main racer. primaryCtx, primaryCancel := context.WithCancel(ctx) defer primaryCancel() go startRacer(primaryCtx, true) // Start the timer for the fallback racer. fallbackTimer := time.NewTimer(dp.fallbackDelay()) defer fallbackTimer.Stop() for { select { case <-fallbackTimer.C: fallbackCtx, fallbackCancel := context.WithCancel(ctx) defer fallbackCancel() go startRacer(fallbackCtx, false) case res := <-results: if res.error == nil { return res.Conn, nil } if res.primary { primary = res } else { fallback = res } if primary.done && fallback.done { return nil, primary.error } if res.primary && fallbackTimer.Stop() { // If we were able to stop the timer, that means it // was running (hadn't yet started the fallback), but // we just got an error on the primary path, so start // the fallback immediately (in 0 nanoseconds). fallbackTimer.Reset(0) } } } } // dialSerial connects to a list of addresses in sequence, returning // either the first successful connection, or the first error. func dialSerial(ctx context.Context, dp *dialParam, ras addrList) (Conn, error) { var firstErr error // The error from the first address is most relevant. for i, ra := range ras { select { case <-ctx.Done(): return nil, &OpError{Op: "dial", Net: dp.network, Source: dp.LocalAddr, Addr: ra, Err: mapErr(ctx.Err())} default: } deadline, _ := ctx.Deadline() partialDeadline, err := partialDeadline(time.Now(), deadline, len(ras)-i) if err != nil { // Ran out of time. if firstErr == nil { firstErr = &OpError{Op: "dial", Net: dp.network, Source: dp.LocalAddr, Addr: ra, Err: err} } break } dialCtx := ctx if partialDeadline.Before(deadline) { var cancel context.CancelFunc dialCtx, cancel = context.WithDeadline(ctx, partialDeadline) defer cancel() } c, err := dialSingle(dialCtx, dp, ra) if err == nil { return c, nil } if firstErr == nil { firstErr = err } } if firstErr == nil { firstErr = &OpError{Op: "dial", Net: dp.network, Source: nil, Addr: nil, Err: errMissingAddress} } return nil, firstErr } // dialSingle attempts to establish and returns a single connection to // the destination address. func dialSingle(ctx context.Context, dp *dialParam, ra Addr) (c Conn, err error) { trace, _ := ctx.Value(nettrace.TraceKey{}).(*nettrace.Trace) if trace != nil { raStr := ra.String() if trace.ConnectStart != nil { trace.ConnectStart(dp.network, raStr) } if trace.ConnectDone != nil { defer func() { trace.ConnectDone(dp.network, raStr, err) }() } } la := dp.LocalAddr switch ra := ra.(type) { case *TCPAddr: la, _ := la.(*TCPAddr) c, err = dialTCP(ctx, dp.network, la, ra) case *UDPAddr: la, _ := la.(*UDPAddr) c, err = dialUDP(ctx, dp.network, la, ra) case *IPAddr: la, _ := la.(*IPAddr) c, err = dialIP(ctx, dp.network, la, ra) case *UnixAddr: la, _ := la.(*UnixAddr) c, err = dialUnix(ctx, dp.network, la, ra) default: return nil, &OpError{Op: "dial", Net: dp.network, Source: la, Addr: ra, Err: &AddrError{Err: "unexpected address type", Addr: dp.address}} } if err != nil { return nil, &OpError{Op: "dial", Net: dp.network, Source: la, Addr: ra, Err: err} // c is non-nil interface containing nil pointer } return c, nil } // Listen announces on the local network address. // // The network must be "tcp", "tcp4", "tcp6", "unix" or "unixpacket". // // For TCP networks, if the host in the address parameter is empty or // a literal unspecified IP address, Listen listens on all available // unicast and anycast IP addresses of the local system. // To only use IPv4, use network "tcp4". // The address can use a host name, but this is not recommended, // because it will create a listener for at most one of the host's IP // addresses. // If the port in the address parameter is empty or "0", as in // "127.0.0.1:" or "[::1]:0", a port number is automatically chosen. // The Addr method of Listener can be used to discover the chosen // port. // // See func Dial for a description of the network and address // parameters. func Listen(network, address string) (Listener, error) { addrs, err := DefaultResolver.resolveAddrList(context.Background(), "listen", network, address, nil) if err != nil { return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: nil, Err: err} } var l Listener switch la := addrs.first(isIPv4).(type) { case *TCPAddr: l, err = ListenTCP(network, la) case *UnixAddr: l, err = ListenUnix(network, la) default: return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: address}} } if err != nil { return nil, err // l is non-nil interface containing nil pointer } return l, nil } // ListenPacket announces on the local network address. // // The network must be "udp", "udp4", "udp6", "unixgram", or an IP // transport. The IP transports are "ip", "ip4", or "ip6" followed by // a colon and a literal protocol number or a protocol name, as in // "ip:1" or "ip:icmp". // // For UDP and IP networks, if the host in the address parameter is // empty or a literal unspecified IP address, ListenPacket listens on // all available IP addresses of the local system except multicast IP // addresses. // To only use IPv4, use network "udp4" or "ip4:proto". // The address can use a host name, but this is not recommended, // because it will create a listener for at most one of the host's IP // addresses. // If the port in the address parameter is empty or "0", as in // "127.0.0.1:" or "[::1]:0", a port number is automatically chosen. // The LocalAddr method of PacketConn can be used to discover the // chosen port. // // See func Dial for a description of the network and address // parameters. func ListenPacket(network, address string) (PacketConn, error) { addrs, err := DefaultResolver.resolveAddrList(context.Background(), "listen", network, address, nil) if err != nil { return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: nil, Err: err} } var l PacketConn switch la := addrs.first(isIPv4).(type) { case *UDPAddr: l, err = ListenUDP(network, la) case *IPAddr: l, err = ListenIP(network, la) case *UnixAddr: l, err = ListenUnixgram(network, la) default: return nil, &OpError{Op: "listen", Net: network, Source: nil, Addr: la, Err: &AddrError{Err: "unexpected address type", Addr: address}} } if err != nil { return nil, err // l is non-nil interface containing nil pointer } return l, nil } // ssss--------------------------------------------------- // /Users/xah/git/go/src/path/path.go // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package path implements utility routines for manipulating slash-separated // paths. // // The path package should only be used for paths separated by forward // slashes, such as the paths in URLs. This package does not deal with // Windows paths with drive letters or backslashes; to manipulate // operating system paths, use the path/filepath package. package path import ( "strings" ) // A lazybuf is a lazily constructed path buffer. // It supports append, reading previously appended bytes, // and retrieving the final string. It does not allocate a buffer // to hold the output until that output diverges from s. type lazybuf struct { s string buf []byte w int } func (b *lazybuf) index(i int) byte { if b.buf != nil { return b.buf[i] } return b.s[i] } func (b *lazybuf) append(c byte) { if b.buf == nil { if b.w < len(b.s) && b.s[b.w] == c { b.w++ return } b.buf = make([]byte, len(b.s)) copy(b.buf, b.s[:b.w]) } b.buf[b.w] = c b.w++ } func (b *lazybuf) string() string { if b.buf == nil { return b.s[:b.w] } return string(b.buf[:b.w]) } // Clean returns the shortest path name equivalent to path // by purely lexical processing. It applies the following rules // iteratively until no further processing can be done: // // 1. Replace multiple slashes with a single slash. // 2. Eliminate each . path name element (the current directory). // 3. Eliminate each inner .. path name element (the parent directory) // along with the non-.. element that precedes it. // 4. Eliminate .. elements that begin a rooted path: // that is, replace "/.." by "/" at the beginning of a path. // // The returned path ends in a slash only if it is the root "/". // // If the result of this process is an empty string, Clean // returns the string ".". // // See also Rob Pike, ``Lexical File Names in Plan 9 or // Getting Dot-Dot Right,'' // https://9p.io/sys/doc/lexnames.html func Clean(path string) string { if path == "" { return "." } rooted := path[0] == '/' n := len(path) // Invariants: // reading from path; r is index of next byte to process. // writing to buf; w is index of next byte to write. // dotdot is index in buf where .. must stop, either because // it is the leading slash or it is a leading ../../.. prefix. out := lazybuf{s: path} r, dotdot := 0, 0 if rooted { out.append('/') r, dotdot = 1, 1 } for r < n { switch { case path[r] == '/': // empty path element r++ case path[r] == '.' && (r+1 == n || path[r+1] == '/'): // . element r++ case path[r] == '.' && path[r+1] == '.' && (r+2 == n || path[r+2] == '/'): // .. element: remove to last / r += 2 switch { case out.w > dotdot: // can backtrack out.w-- for out.w > dotdot && out.index(out.w) != '/' { out.w-- } case !rooted: // cannot backtrack, but not rooted, so append .. element. if out.w > 0 { out.append('/') } out.append('.') out.append('.') dotdot = out.w } default: // real path element. // add slash if needed if rooted && out.w != 1 || !rooted && out.w != 0 { out.append('/') } // copy element for ; r < n && path[r] != '/'; r++ { out.append(path[r]) } } } // Turn empty string into "." if out.w == 0 { return "." } return out.string() } // Split splits path immediately following the final slash, // separating it into a directory and file name component. // If there is no slash in path, Split returns an empty dir and // file set to path. // The returned values have the property that path = dir+file. func Split(path string) (dir, file string) { i := strings.LastIndex(path, "/") return path[:i+1], path[i+1:] } // Join joins any number of path elements into a single path, adding a // separating slash if necessary. The result is Cleaned; in particular, // all empty strings are ignored. func Join(elem ...string) string { for i, e := range elem { if e != "" { return Clean(strings.Join(elem[i:], "/")) } } return "" } // Ext returns the file name extension used by path. // The extension is the suffix beginning at the final dot // in the final slash-separated element of path; // it is empty if there is no dot. func Ext(path string) string { for i := len(path) - 1; i >= 0 && path[i] != '/'; i-- { if path[i] == '.' { return path[i:] } } return "" } // Base returns the last element of path. // Trailing slashes are removed before extracting the last element. // If the path is empty, Base returns ".". // If the path consists entirely of slashes, Base returns "/". func Base(path string) string { if path == "" { return "." } // Strip trailing slashes. for len(path) > 0 && path[len(path)-1] == '/' { path = path[0 : len(path)-1] } // Find the last element if i := strings.LastIndex(path, "/"); i >= 0 { path = path[i+1:] } // If empty now, it had only slashes. if path == "" { return "/" } return path } // IsAbs reports whether the path is absolute. func IsAbs(path string) bool { return len(path) > 0 && path[0] == '/' } // Dir returns all but the last element of path, typically the path's directory. // After dropping the final element using Split, the path is Cleaned and trailing // slashes are removed. // If the path is empty, Dir returns ".". // If the path consists entirely of slashes followed by non-slash bytes, Dir // returns a single slash. In any other case, the returned path does not end in a // slash. func Dir(path string) string { dir, _ := Split(path) return Clean(dir) } // ssss--------------------------------------------------- // /Users/xah/git/go/src/regexp/regexp.go // Copyright 2009 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. // Package regexp implements regular expression search. // // The syntax of the regular expressions accepted is the same // general syntax used by Perl, Python, and other languages. // More precisely, it is the syntax accepted by RE2 and described at // https://golang.org/s/re2syntax, except for \C. // For an overview of the syntax, run // go doc regexp/syntax // // The regexp implementation provided by this package is // guaranteed to run in time linear in the size of the input. // (This is a property not guaranteed by most open source // implementations of regular expressions.) For more information // about this property, see // http://swtch.com/~rsc/regexp/regexp1.html // or any book about automata theory. // // All characters are UTF-8-encoded code points. // // There are 16 methods of Regexp that match a regular expression and identify // the matched text. Their names are matched by this regular expression: // // Find(All)?(String)?(Submatch)?(Index)? // // If 'All' is present, the routine matches successive non-overlapping // matches of the entire expression. Empty matches abutting a preceding // match are ignored. The return value is a slice containing the successive // return values of the corresponding non-'All' routine. These routines take // an extra integer argument, n; if n >= 0, the function returns at most n // matches/submatches. // // If 'String' is present, the argument is a string; otherwise it is a slice // of bytes; return values are adjusted as appropriate. // // If 'Submatch' is present, the return value is a slice identifying the // successive submatches of the expression. Submatches are matches of // parenthesized subexpressions (also known as capturing groups) within the // regular expression, numbered from left to right in order of opening // parenthesis. Submatch 0 is the match of the entire expression, submatch 1 // the match of the first parenthesized subexpression, and so on. // // If 'Index' is present, matches and submatches are identified by byte index // pairs within the input string: result[2*n:2*n+1] identifies the indexes of // the nth submatch. The pair for n==0 identifies the match of the entire // expression. If 'Index' is not present, the match is identified by the // text of the match/submatch. If an index is negative, it means that // subexpression did not match any string in the input. // // There is also a subset of the methods that can be applied to text read // from a RuneReader: // // MatchReader, FindReaderIndex, FindReaderSubmatchIndex // // This set may grow. Note that regular expression matches may need to // examine text beyond the text returned by a match, so the methods that // match text from a RuneReader may read arbitrarily far into the input // before returning. // // (There are a few other methods that do not match this pattern.) // package regexp import ( "bytes" "io" "regexp/syntax" "strconv" "strings" "sync" "unicode" "unicode/utf8" ) // Regexp is the representation of a compiled regular expression. // A Regexp is safe for concurrent use by multiple goroutines, // except for configuration methods, such as Longest. type Regexp struct { // read-only after Compile regexpRO // cache of machines for running regexp mu sync.Mutex machine []*machine } type regexpRO struct { expr string // as passed to Compile prog *syntax.Prog // compiled program onepass *onePassProg // onepass program or nil prefix string // required prefix in unanchored matches prefixBytes []byte // prefix, as a []byte prefixComplete bool // prefix is the entire regexp prefixRune rune // first rune in prefix prefixEnd uint32 // pc for last rune in prefix cond syntax.EmptyOp // empty-width conditions required at start of match numSubexp int subexpNames []string longest bool } // String returns the source text used to compile the regular expression. func (re *Regexp) String() string { return re.expr } // Copy returns a new Regexp object copied from re. // // When using a Regexp in multiple goroutines, giving each goroutine // its own copy helps to avoid lock contention. func (re *Regexp) Copy() *Regexp { // It is not safe to copy Regexp by value // since it contains a sync.Mutex. return &Regexp{ regexpRO: re.regexpRO, } } // Compile parses a regular expression and returns, if successful, // a Regexp object that can be used to match against text. // // When matching against text, the regexp returns a match that // begins as early as possible in the input (leftmost), and among those // it chooses the one that a backtracking search would have found first. // This so-called leftmost-first matching is the same semantics // that Perl, Python, and other implementations use, although this // package implements it without the expense of backtracking. // For POSIX leftmost-longest matching, see CompilePOSIX. func Compile(expr string) (*Regexp, error) { return compile(expr, syntax.Perl, false) } // CompilePOSIX is like Compile but restricts the regular expression // to POSIX ERE (egrep) syntax and changes the match semantics to // leftmost-longest. // // That is, when matching against text, the regexp returns a match that // begins as early as possible in the input (leftmost), and among those // it chooses a match that is as long as possible. // This so-called leftmost-longest matching is the same semantics // that early regular expression implementations used and that POSIX // specifies. // // However, there can be multiple leftmost-longest matches, with different // submatch choices, and here this package diverges from POSIX. // Among the possible leftmost-longest matches, this package chooses // the one that a backtracking search would have found first, while POSIX // specifies that the match be chosen to maximize the length of the first // subexpression, then the second, and so on from left to right. // The POSIX rule is computationally prohibitive and not even well-defined. // See http://swtch.com/~rsc/regexp/regexp2.html#posix for details. func CompilePOSIX(expr string) (*Regexp, error) { return compile(expr, syntax.POSIX, true) } // Longest makes future searches prefer the leftmost-longest match. // That is, when matching against text, the regexp returns a match that // begins as early as possible in the input (leftmost), and among those // it chooses a match that is as long as possible. // This method modifies the Regexp and may not be called concurrently // with any other methods. func (re *Regexp) Longest() { re.longest = true } func compile(expr string, mode syntax.Flags, longest bool) (*Regexp, error) { re, err := syntax.Parse(expr, mode) if err != nil { return nil, err } maxCap := re.MaxCap() capNames := re.CapNames() re = re.Simplify() prog, err := syntax.Compile(re) if err != nil { return nil, err } regexp := &Regexp{ regexpRO: regexpRO{ expr: expr, prog: prog, onepass: compileOnePass(prog), numSubexp: maxCap, subexpNames: capNames, cond: prog.StartCond(), longest: longest, }, } if regexp.onepass == notOnePass { regexp.prefix, regexp.prefixComplete = prog.Prefix() } else { regexp.prefix, regexp.prefixComplete, regexp.prefixEnd = onePassPrefix(prog) } if regexp.prefix != "" { // TODO(rsc): Remove this allocation by adding // IndexString to package bytes. regexp.prefixBytes = []byte(regexp.prefix) regexp.prefixRune, _ = utf8.DecodeRuneInString(regexp.prefix) } return regexp, nil } // get returns a machine to use for matching re. // It uses the re's machine cache if possible, to avoid // unnecessary allocation. func (re *Regexp) get() *machine { re.mu.Lock() if n := len(re.machine); n > 0 { z := re.machine[n-1] re.machine = re.machine[:n-1] re.mu.Unlock() return z } re.mu.Unlock() z := progMachine(re.prog, re.onepass) z.re = re return z } // put returns a machine to the re's machine cache. // There is no attempt to limit the size of the cache, so it will // grow to the maximum number of simultaneous matches // run using re. (The cache empties when re gets garbage collected.) func (re *Regexp) put(z *machine) { re.mu.Lock() re.machine = append(re.machine, z) re.mu.Unlock() } // MustCompile is like Compile but panics if the expression cannot be parsed. // It simplifies safe initialization of global variables holding compiled regular // expressions. func MustCompile(str string) *Regexp { regexp, error := Compile(str) if error != nil { panic(`regexp: Compile(` + quote(str) + `): ` + error.Error()) } return regexp } // MustCompilePOSIX is like CompilePOSIX but panics if the expression cannot be parsed. // It simplifies safe initialization of global variables holding compiled regular // expressions. func MustCompilePOSIX(str string) *Regexp { regexp, error := CompilePOSIX(str) if error != nil { panic(`regexp: CompilePOSIX(` + quote(str) + `): ` + error.Error()) } return regexp } func quote(s string) string { if strconv.CanBackquote(s) { return "`" + s + "`" } return strconv.Quote(s) } // NumSubexp returns the number of parenthesized subexpressions in this Regexp. func (re *Regexp) NumSubexp() int { return re.numSubexp } // SubexpNames returns the names of the parenthesized subexpressions // in this Regexp. The name for the first sub-expression is names[1], // so that if m is a match slice, the name for m[i] is SubexpNames()[i]. // Since the Regexp as a whole cannot be named, names[0] is always // the empty string. The slice should not be modified. func (re *Regexp) SubexpNames() []string { return re.subexpNames } const endOfText rune = -1 // input abstracts different representations of the input text. It provides // one-character lookahead. type input interface { step(pos int) (r rune, width int) // advance one rune canCheckPrefix() bool // can we look ahead without losing info? hasPrefix(re *Regexp) bool index(re *Regexp, pos int) int context(pos int) syntax.EmptyOp } // inputString scans a string. type inputString struct { str string } func (i *inputString) step(pos int) (rune, int) { if pos < len(i.str) { c := i.str[pos] if c < utf8.RuneSelf { return rune(c), 1 } return utf8.DecodeRuneInString(i.str[pos:]) } return endOfText, 0 } func (i *inputString) canCheckPrefix() bool { return true } func (i *inputString) hasPrefix(re *Regexp) bool { return strings.HasPrefix(i.str, re.prefix) } func (i *inputString) index(re *Regexp, pos int) int { return strings.Index(i.str[pos:], re.prefix) } func (i *inputString) context(pos int) syntax.EmptyOp { r1, r2 := endOfText, endOfText // 0 < pos && pos <= len(i.str) if uint(pos-1) < uint(len(i.str)) { r1 = rune(i.str[pos-1]) if r1 >= utf8.RuneSelf { r1, _ = utf8.DecodeLastRuneInString(i.str[:pos]) } } // 0 <= pos && pos < len(i.str) if uint(pos) < uint(len(i.str)) { r2 = rune(i.str[pos]) if r2 >= utf8.RuneSelf { r2, _ = utf8.DecodeRuneInString(i.str[pos:]) } } return syntax.EmptyOpContext(r1, r2) } // inputBytes scans a byte slice. type inputBytes struct { str []byte } func (i *inputBytes) step(pos int) (rune, int) { if pos < len(i.str) { c := i.str[pos] if c < utf8.RuneSelf { return rune(c), 1 } return utf8.DecodeRune(i.str[pos:]) } return endOfText, 0 } func (i *inputBytes) canCheckPrefix() bool { return true } func (i *inputBytes) hasPrefix(re *Regexp) bool { return bytes.HasPrefix(i.str, re.prefixBytes) } func (i *inputBytes) index(re *Regexp, pos int) int { return bytes.Index(i.str[pos:], re.prefixBytes) } func (i *inputBytes) context(pos int) syntax.EmptyOp { r1, r2 := endOfText, endOfText // 0 < pos && pos <= len(i.str) if uint(pos-1) < uint(len(i.str)) { r1 = rune(i.str[pos-1]) if r1 >= utf8.RuneSelf { r1, _ = utf8.DecodeLastRune(i.str[:pos]) } } // 0 <= pos && pos < len(i.str) if uint(pos) < uint(len(i.str)) { r2 = rune(i.str[pos]) if r2 >= utf8.RuneSelf { r2, _ = utf8.DecodeRune(i.str[pos:]) } } return syntax.EmptyOpContext(r1, r2) } // inputReader scans a RuneReader. type inputReader struct { r io.RuneReader atEOT bool pos int } func (i *inputReader) step(pos int) (rune, int) { if !i.atEOT && pos != i.pos { return endOfText, 0 } r, w, err := i.r.ReadRune() if err != nil { i.atEOT = true return endOfText, 0 } i.pos += w return r, w } func (i *inputReader) canCheckPrefix() bool { return false } func (i *inputReader) hasPrefix(re *Regexp) bool { return false } func (i *inputReader) index(re *Regexp, pos int) int { return -1 } func (i *inputReader) context(pos int) syntax.EmptyOp { return 0 } // LiteralPrefix returns a literal string that must begin any match // of the regular expression re. It returns the boolean true if the // literal string comprises the entire regular expression. func (re *Regexp) LiteralPrefix() (prefix string, complete bool) { return re.prefix, re.prefixComplete } // MatchReader reports whether the Regexp matches the text read by the // RuneReader. func (re *Regexp) MatchReader(r io.RuneReader) bool { return re.doMatch(r, nil, "") } // MatchString reports whether the Regexp matches the string s. func (re *Regexp) MatchString(s string) bool { return re.doMatch(nil, nil, s) } // Match reports whether the Regexp matches the byte slice b. func (re *Regexp) Match(b []byte) bool { return re.doMatch(nil, b, "") } // MatchReader checks whether a textual regular expression matches the text // read by the RuneReader. More complicated queries need to use Compile and // the full Regexp interface. func MatchReader(pattern string, r io.RuneReader) (matched bool, err error) { re, err := Compile(pattern) if err != nil { return false, err } return re.MatchReader(r), nil } // MatchString checks whether a textual regular expression // matches a string. More complicated queries need // to use Compile and the full Regexp interface. func MatchString(pattern string, s string) (matched bool, err error) { re, err := Compile(pattern) if err != nil { return false, err } return re.MatchString(s), nil } // Match checks whether a textual regular expression // matches a byte slice. More complicated queries need // to use Compile and the full Regexp interface. func Match(pattern string, b []byte) (matched bool, err error) { re, err := Compile(pattern) if err != nil { return false, err } return re.Match(b), nil } // ReplaceAllString returns a copy of src, replacing matches of the Regexp // with the replacement string repl. Inside repl, $ signs are interpreted as // in Expand, so for instance $1 represents the text of the first submatch. func (re *Regexp) ReplaceAllString(src, repl string) string { n := 2 if strings.Contains(repl, "$") { n = 2 * (re.numSubexp + 1) } b := re.replaceAll(nil, src, n, func(dst []byte, match []int) []byte { return re.expand(dst, repl, nil, src, match) }) return string(b) } // ReplaceAllLiteralString returns a copy of src, replacing matches of the Regexp // with the replacement string repl. The replacement repl is substituted directly, // without using Expand. func (re *Regexp) ReplaceAllLiteralString(src, repl string) string { return string(re.replaceAll(nil, src, 2, func(dst []byte, match []int) []byte { return append(dst, repl...) })) } // ReplaceAllStringFunc returns a copy of src in which all matches of the // Regexp have been replaced by the return value of function repl applied // to the matched substring. The replacement returned by repl is substituted // directly, without using Expand. func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string { b := re.replaceAll(nil, src, 2, func(dst []byte, match []int) []byte { return append(dst, repl(src[match[0]:match[1]])...) }) return string(b) } func (re *Regexp) replaceAll(bsrc []byte, src string, nmatch int, repl func(dst []byte, m []int) []byte) []byte { lastMatchEnd := 0 // end position of the most recent match searchPos := 0 // position where we next look for a match var buf []byte var endPos int if bsrc != nil { endPos = len(bsrc) } else { endPos = len(src) } if nmatch > re.prog.NumCap { nmatch = re.prog.NumCap } var dstCap [2]int for searchPos <= endPos { a := re.doExecute(nil, bsrc, src, searchPos, nmatch, dstCap[:0]) if len(a) == 0 { break // no more matches } // Copy the unmatched characters before this match. if bsrc != nil { buf = append(buf, bsrc[lastMatchEnd:a[0]]...) } else { buf = append(buf, src[lastMatchEnd:a[0]]...) } // Now insert a copy of the replacement string, but not for a // match of the empty string immediately after another match. // (Otherwise, we get double replacement for patterns that // match both empty and nonempty strings.) if a[1] > lastMatchEnd || a[0] == 0 { buf = repl(buf, a) } lastMatchEnd = a[1] // Advance past this match; always advance at least one character. var width int if bsrc != nil { _, width = utf8.DecodeRune(bsrc[searchPos:]) } else { _, width = utf8.DecodeRuneInString(src[searchPos:]) } if searchPos+width > a[1] { searchPos += width } else if searchPos+1 > a[1] { // This clause is only needed at the end of the input // string. In that case, DecodeRuneInString returns width=0. searchPos++ } else { searchPos = a[1] } } // Copy the unmatched characters after the last match. if bsrc != nil { buf = append(buf, bsrc[lastMatchEnd:]...) } else { buf = append(buf, src[lastMatchEnd:]...) } return buf } // ReplaceAll returns a copy of src, replacing matches of the Regexp // with the replacement text repl. Inside repl, $ signs are interpreted as // in Expand, so for instance $1 represents the text of the first submatch. func (re *Regexp) ReplaceAll(src, repl []byte) []byte { n := 2 if bytes.IndexByte(repl, '$') >= 0 { n = 2 * (re.numSubexp + 1) } srepl := "" b := re.replaceAll(src, "", n, func(dst []byte, match []int) []byte { if len(srepl) != len(repl) { srepl = string(repl) } return re.expand(dst, srepl, src, "", match) }) return b } // ReplaceAllLiteral returns a copy of src, replacing matches of the Regexp // with the replacement bytes repl. The replacement repl is substituted directly, // without using Expand. func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte { return re.replaceAll(src, "", 2, func(dst []byte, match []int) []byte { return append(dst, repl...) }) } // ReplaceAllFunc returns a copy of src in which all matches of the // Regexp have been replaced by the return value of function repl applied // to the matched byte slice. The replacement returned by repl is substituted // directly, without using Expand. func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte { return re.replaceAll(src, "", 2, func(dst []byte, match []int) []byte { return append(dst, repl(src[match[0]:match[1]])...) }) } // Bitmap used by func special to check whether a character needs to be escaped. var specialBytes [16]byte // special reports whether byte b needs to be escaped by QuoteMeta. func special(b byte) bool { return b < utf8.RuneSelf && specialBytes[b%16]&(1<<(b/16)) != 0 } func init() { for _, b := range []byte(`\.+*?()|[]{}^$`) { specialBytes[b%16] |= 1 << (b / 16) } } // QuoteMeta returns a string that quotes all regular expression metacharacters // inside the argument text; the returned string is a regular expression matching // the literal text. For example, QuoteMeta(`[foo]`) returns `\[foo\]`. func QuoteMeta(s string) string { // A byte loop is correct because all metacharacters are ASCII. var i int for i = 0; i < len(s); i++ { if special(s[i]) { break } } // No meta characters found, so return original string. if i >= len(s) { return s } b := make([]byte, 2*len(s)-i) copy(b, s[:i]) j := i for ; i < len(s); i++ { if special(s[i]) { b[j] = '\\' j++ } b[j] = s[i] j++ } return string(b[:j]) } // The number of capture values in the program may correspond // to fewer capturing expressions than are in the regexp. // For example, "(a){0}" turns into an empty program, so the // maximum capture in the program is 0 but we need to return // an expression for \1. Pad appends -1s to the slice a as needed. func (re *Regexp) pad(a []int) []int { if a == nil { // No match. return nil } n := (1 + re.numSubexp) * 2 for len(a) < n { a = append(a, -1) } return a } // Find matches in slice b if b is non-nil, otherwise find matches in string s. func (re *Regexp) allMatches(s string, b []byte, n int, deliver func([]int)) { var end int if b == nil { end = len(s) } else { end = len(b) } for pos, i, prevMatchEnd := 0, 0, -1; i < n && pos <= end; { matches := re.doExecute(nil, b, s, pos, re.prog.NumCap, nil) if len(matches) == 0 { break } accept := true if matches[1] == pos { // We've found an empty match. if matches[0] == prevMatchEnd { // We don't allow an empty match right // after a previous match, so ignore it. accept = false } var width int // TODO: use step() if b == nil { _, width = utf8.DecodeRuneInString(s[pos:end]) } else { _, width = utf8.DecodeRune(b[pos:end]) } if width > 0 { pos += width } else { pos = end + 1 } } else { pos = matches[1] } prevMatchEnd = matches[1] if accept { deliver(re.pad(matches)) i++ } } } // Find returns a slice holding the text of the leftmost match in b of the regular expression. // A return value of nil indicates no match. func (re *Regexp) Find(b []byte) []byte { var dstCap [2]int a := re.doExecute(nil, b, "", 0, 2, dstCap[:0]) if a == nil { return nil } return b[a[0]:a[1]] } // FindIndex returns a two-element slice of integers defining the location of // the leftmost match in b of the regular expression. The match itself is at // b[loc[0]:loc[1]]. // A return value of nil indicates no match. func (re *Regexp) FindIndex(b []byte) (loc []int) { a := re.doExecute(nil, b, "", 0, 2, nil) if a == nil { return nil } return a[0:2] } // FindString returns a string holding the text of the leftmost match in s of the regular // expression. If there is no match, the return value is an empty string, // but it will also be empty if the regular expression successfully matches // an empty string. Use FindStringIndex or FindStringSubmatch if it is // necessary to distinguish these cases. func (re *Regexp) FindString(s string) string { var dstCap [2]int a := re.doExecute(nil, nil, s, 0, 2, dstCap[:0]) if a == nil { return "" } return s[a[0]:a[1]] } // FindStringIndex returns a two-element slice of integers defining the // location of the leftmost match in s of the regular expression. The match // itself is at s[loc[0]:loc[1]]. // A return value of nil indicates no match. func (re *Regexp) FindStringIndex(s string) (loc []int) { a := re.doExecute(nil, nil, s, 0, 2, nil) if a == nil { return nil } return a[0:2] } // FindReaderIndex returns a two-element slice of integers defining the // location of the leftmost match of the regular expression in text read from // the RuneReader. The match text was found in the input stream at // byte offset loc[0] through loc[1]-1. // A return value of nil indicates no match. func (re *Regexp) FindReaderIndex(r io.RuneReader) (loc []int) { a := re.doExecute(r, nil, "", 0, 2, nil) if a == nil { return nil } return a[0:2] } // FindSubmatch returns a slice of slices holding the text of the leftmost // match of the regular expression in b and the matches, if any, of its // subexpressions, as defined by the 'Submatch' descriptions in the package // comment. // A return value of nil indicates no match. func (re *Regexp) FindSubmatch(b []byte) [][]byte { var dstCap [4]int a := re.doExecute(nil, b, "", 0, re.prog.NumCap, dstCap[:0]) if a == nil { return nil } ret := make([][]byte, 1+re.numSubexp) for i := range ret { if 2*i < len(a) && a[2*i] >= 0 { ret[i] = b[a[2*i]:a[2*i+1]] } } return ret } // Expand appends template to dst and returns the result; during the // append, Expand replaces variables in the template with corresponding // matches drawn from src. The match slice should have been returned by // FindSubmatchIndex. // // In the template, a variable is denoted by a substring of the form // $name or ${name}, where name is a non-empty sequence of letters, // digits, and underscores. A purely numeric name like $1 refers to // the submatch with the corresponding index; other names refer to // capturing parentheses named with the (?P...) syntax. A // reference to an out of range or unmatched index or a name that is not // present in the regular expression is replaced with an empty slice. // // In the $name form, name is taken to be as long as possible: $1x is // equivalent to ${1x}, not ${1}x, and, $10 is equivalent to ${10}, not ${1}0. // // To insert a literal $ in the output, use $$ in the template. func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte { return re.expand(dst, string(template), src, "", match) } // ExpandString is like Expand but the template and source are strings. // It appends to and returns a byte slice in order to give the calling // code control over allocation. func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte { return re.expand(dst, template, nil, src, match) } func (re *Regexp) expand(dst []byte, template string, bsrc []byte, src string, match []int) []byte { for len(template) > 0 { i := strings.Index(template, "$") if i < 0 { break } dst = append(dst, template[:i]...) template = template[i:] if len(template) > 1 && template[1] == '$' { // Treat $$ as $. dst = append(dst, '$') template = template[2:] continue } name, num, rest, ok := extract(template) if !ok { // Malformed; treat $ as raw text. dst = append(dst, '$') template = template[1:] continue } template = rest if num >= 0 { if 2*num+1 < len(match) && match[2*num] >= 0 { if bsrc != nil { dst = append(dst, bsrc[match[2*num]:match[2*num+1]]...) } else { dst = append(dst, src[match[2*num]:match[2*num+1]]...) } } } else { for i, namei := range re.subexpNames { if name == namei && 2*i+1 < len(match) && match[2*i] >= 0 { if bsrc != nil { dst = append(dst, bsrc[match[2*i]:match[2*i+1]]...) } else { dst = append(dst, src[match[2*i]:match[2*i+1]]...) } break } } } } dst = append(dst, template...) return dst } // extract returns the name from a leading "$name" or "${name}" in str. // If it is a number, extract returns num set to that number; otherwise num = -1. func extract(str string) (name string, num int, rest string, ok bool) { if len(str) < 2 || str[0] != '$' { return } brace := false if str[1] == '{' { brace = true str = str[2:] } else { str = str[1:] } i := 0 for i < len(str) { rune, size := utf8.DecodeRuneInString(str[i:]) if !unicode.IsLetter(rune) && !unicode.IsDigit(rune) && rune != '_' { break } i += size } if i == 0 { // empty name is not okay return } name = str[:i] if brace { if i >= len(str) || str[i] != '}' { // missing closing brace return } i++ } // Parse number. num = 0 for i := 0; i < len(name); i++ { if name[i] < '0' || '9' < name[i] || num >= 1e8 { num = -1 break } num = num*10 + int(name[i]) - '0' } // Disallow leading zeros. if name[0] == '0' && len(name) > 1 { num = -1 } rest = str[i:] ok = true return } // FindSubmatchIndex returns a slice holding the index pairs identifying the // leftmost match of the regular expression in b and the matches, if any, of // its subexpressions, as defined by the 'Submatch' and 'Index' descriptions // in the package comment. // A return value of nil indicates no match. func (re *Regexp) FindSubmatchIndex(b []byte) []int { return re.pad(re.doExecute(nil, b, "", 0, re.prog.NumCap, nil)) } // FindStringSubmatch returns a slice of strings holding the text of the // leftmost match of the regular expression in s and the matches, if any, of // its subexpressions, as defined by the 'Submatch' description in the // package comment. // A return value of nil indicates no match. func (re *Regexp) FindStringSubmatch(s string) []string { var dstCap [4]int a := re.doExecute(nil, nil, s, 0, re.prog.NumCap, dstCap[:0]) if a == nil { return nil } ret := make([]string, 1+re.numSubexp) for i := range ret { if 2*i < len(a) && a[2*i] >= 0 { ret[i] = s[a[2*i]:a[2*i+1]] } } return ret } // FindStringSubmatchIndex returns a slice holding the index pairs // identifying the leftmost match of the regular expression in s and the // matches, if any, of its subexpressions, as defined by the 'Submatch' and // 'Index' descriptions in the package comment. // A return value of nil indicates no match. func (re *Regexp) FindStringSubmatchIndex(s string) []int { return re.pad(re.doExecute(nil, nil, s, 0, re.prog.NumCap, nil)) } // FindReaderSubmatchIndex returns a slice holding the index pairs // identifying the leftmost match of the regular expression of text read by // the RuneReader, and the matches, if any, of its subexpressions, as defined // by the 'Submatch' and 'Index' descriptions in the package comment. A // return value of nil indicates no match. func (re *Regexp) FindReaderSubmatchIndex(r io.RuneReader) []int { return re.pad(re.doExecute(r, nil, "", 0, re.prog.NumCap, nil)) } const startSize = 10 // The size at which to start a slice in the 'All' routines. // FindAll is the 'All' version of Find; it returns a slice of all successive // matches of the expression, as defined by the 'All' description in the // package comment. // A return value of nil indicates no match. func (re *Regexp) FindAll(b []byte, n int) [][]byte { if n < 0 { n = len(b) + 1 } result := make([][]byte, 0, startSize) re.allMatches("", b, n, func(match []int) { result = append(result, b[match[0]:match[1]]) }) if len(result) == 0 { return nil } return result } // FindAllIndex is the 'All' version of FindIndex; it returns a slice of all // successive matches of the expression, as defined by the 'All' description // in the package comment. // A return value of nil indicates no match. func (re *Regexp) FindAllIndex(b []byte, n int) [][]int { if n < 0 { n = len(b) + 1 } result := make([][]int, 0, startSize) re.allMatches("", b, n, func(match []int) { result = append(result, match[0:2]) }) if len(result) == 0 { return nil } return result } // FindAllString is the 'All' version of FindString; it returns a slice of all // successive matches of the expression, as defined by the 'All' description // in the package comment. // A return value of nil indicates no match. func (re *Regexp) FindAllString(s string, n int) []string { if n < 0 { n = len(s) + 1 } result := make([]string, 0, startSize) re.allMatches(s, nil, n, func(match []int) { result = append(result, s[match[0]:match[1]]) }) if len(result) == 0 { return nil } return result } // FindAllStringIndex is the 'All' version of FindStringIndex; it returns a // slice of all successive matches of the expression, as defined by the 'All' // description in the package comment. // A return value of nil indicates no match. func (re *Regexp) FindAllStringIndex(s string, n int) [][]int { if n < 0 { n = len(s) + 1 } result := make([][]int, 0, startSize) re.allMatches(s, nil, n, func(match []int) { result = append(result, match[0:2]) }) if len(result) == 0 { return nil } return result } // FindAllSubmatch is the 'All' version of FindSubmatch; it returns a slice // of all successive matches of the expression, as defined by the 'All' // description in the package comment. // A return value of nil indicates no match. func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte { if n < 0 { n = len(b) + 1 } result := make([][][]byte, 0, startSize) re.allMatches("", b, n, func(match []int) { slice := make([][]byte, len(match)/2) for j := range slice { if match[2*j] >= 0 { slice[j] = b[match[2*j]:match[2*j+1]] } } result = append(result, slice) }) if len(result) == 0 { return nil } return result } // FindAllSubmatchIndex is the 'All' version of FindSubmatchIndex; it returns // a slice of all successive matches of the expression, as defined by the // 'All' description in the package comment. // A return value of nil indicates no match. func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int { if n < 0 { n = len(b) + 1 } result := make([][]int, 0, startSize) re.allMatches("", b, n, func(match []int) { result = append(result, match) }) if len(result) == 0 { return nil } return result } // FindAllStringSubmatch is the 'All' version of FindStringSubmatch; it // returns a slice of all successive matches of the expression, as defined by // the 'All' description in the package comment. // A return value of nil indicates no match. func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string { if n < 0 { n = len(s) + 1 } result := make([][]string, 0, startSize) re.allMatches(s, nil, n, func(match []int) { slice := make([]string, len(match)/2) for j := range slice { if match[2*j] >= 0 { slice[j] = s[match[2*j]:match[2*j+1]] } } result = append(result, slice) }) if len(result) == 0 { return nil } return result } // FindAllStringSubmatchIndex is the 'All' version of // FindStringSubmatchIndex; it returns a slice of all successive matches of // the expression, as defined by the 'All' description in the package // comment. // A return value of nil indicates no match. func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int { if n < 0 { n = len(s) + 1 } result := make([][]int, 0, startSize) re.allMatches(s, nil, n, func(match []int) { result = append(result, match) }) if len(result) == 0 { return nil } return result } // Split slices s into substrings separated by the expression and returns a slice of // the substrings between those expression matches. // // The slice returned by this method consists of all the substrings of s // not contained in the slice returned by FindAllString. When called on an expression // that contains no metacharacters, it is equivalent to strings.SplitN. // // Example: // s := regexp.MustCompile("a*").Split("abaabaccadaaae", 5) // // s: ["", "b", "b", "c", "cadaaae"] // // The count determines the number of substrings to return: // n > 0: at most n substrings; the last substring will be the unsplit remainder. // n == 0: the result is nil (zero substrings) // n < 0: all substrings func (re *Regexp) Split(s string, n int) []string { if n == 0 { return nil } if len(re.expr) > 0 && len(s) == 0 { return []string{""} } matches := re.FindAllStringIndex(s, n) strings := make([]string, 0, len(matches)) beg := 0 end := 0 for _, match := range matches { if n > 0 && len(strings) >= n-1 { break } end = match[0] if match[1] != 0 { strings = append(strings, s[beg:end]) } beg = match[1] } if end != len(s) { strings = append(strings, s[beg:]) } return strings }