Enable golint part of #14756
pkg/broadcastwriter pkg/graphdb pkg/httputils pkg/ioutils Signed-off-by: Lei Jitang <leijitang@huawei.com>
This commit is contained in:
parent
fca8ba94b3
commit
fcb8d8d48e
11 changed files with 60 additions and 32 deletions
|
@ -44,6 +44,7 @@ func (w *BroadcastWriter) Clean() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// New creates a new BroadcastWriter.
|
||||||
func New() *BroadcastWriter {
|
func New() *BroadcastWriter {
|
||||||
return &BroadcastWriter{
|
return &BroadcastWriter{
|
||||||
writers: make(map[io.WriteCloser]struct{}),
|
writers: make(map[io.WriteCloser]struct{}),
|
||||||
|
|
|
@ -2,4 +2,6 @@
|
||||||
|
|
||||||
package graphdb
|
package graphdb
|
||||||
|
|
||||||
import _ "code.google.com/p/gosqlite/sqlite3" // registers sqlite
|
import (
|
||||||
|
_ "code.google.com/p/gosqlite/sqlite3" // registers sqlite
|
||||||
|
)
|
||||||
|
|
|
@ -2,4 +2,6 @@
|
||||||
|
|
||||||
package graphdb
|
package graphdb
|
||||||
|
|
||||||
import _ "github.com/mattn/go-sqlite3" // registers sqlite
|
import (
|
||||||
|
_ "github.com/mattn/go-sqlite3" // registers sqlite
|
||||||
|
)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
package graphdb
|
package graphdb
|
||||||
|
|
||||||
|
// NewSqliteConn return a new sqlite connection.
|
||||||
func NewSqliteConn(root string) (*Database, error) {
|
func NewSqliteConn(root string) (*Database, error) {
|
||||||
panic("Not implemented")
|
panic("Not implemented")
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,28 +29,28 @@ const (
|
||||||
`
|
`
|
||||||
)
|
)
|
||||||
|
|
||||||
// Entity with a unique id
|
// Entity with a unique id.
|
||||||
type Entity struct {
|
type Entity struct {
|
||||||
id string
|
id string
|
||||||
}
|
}
|
||||||
|
|
||||||
// An Edge connects two entities together
|
// An Edge connects two entities together.
|
||||||
type Edge struct {
|
type Edge struct {
|
||||||
EntityID string
|
EntityID string
|
||||||
Name string
|
Name string
|
||||||
ParentID string
|
ParentID string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entities stores the list of entities
|
// Entities stores the list of entities.
|
||||||
type Entities map[string]*Entity
|
type Entities map[string]*Entity
|
||||||
|
|
||||||
// Edges stores the relationships between entities
|
// Edges stores the relationships between entities.
|
||||||
type Edges []*Edge
|
type Edges []*Edge
|
||||||
|
|
||||||
// WalkFunc is a function invoked to process an individual entity
|
// WalkFunc is a function invoked to process an individual entity.
|
||||||
type WalkFunc func(fullPath string, entity *Entity) error
|
type WalkFunc func(fullPath string, entity *Entity) error
|
||||||
|
|
||||||
// Database is a graph database for storing entities and their relationships
|
// Database is a graph database for storing entities and their relationships.
|
||||||
type Database struct {
|
type Database struct {
|
||||||
conn *sql.DB
|
conn *sql.DB
|
||||||
mux sync.RWMutex
|
mux sync.RWMutex
|
||||||
|
@ -80,7 +80,7 @@ func IsNonUniqueNameError(err error) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDatabase creates a new graph database initialized with a root entity
|
// NewDatabase creates a new graph database initialized with a root entity.
|
||||||
func NewDatabase(conn *sql.DB) (*Database, error) {
|
func NewDatabase(conn *sql.DB) (*Database, error) {
|
||||||
if conn == nil {
|
if conn == nil {
|
||||||
return nil, fmt.Errorf("Database connection cannot be nil")
|
return nil, fmt.Errorf("Database connection cannot be nil")
|
||||||
|
@ -130,12 +130,12 @@ func NewDatabase(conn *sql.DB) (*Database, error) {
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close the underlying connection to the database
|
// Close the underlying connection to the database.
|
||||||
func (db *Database) Close() error {
|
func (db *Database) Close() error {
|
||||||
return db.conn.Close()
|
return db.conn.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the entity id for a given path
|
// Set the entity id for a given path.
|
||||||
func (db *Database) Set(fullPath, id string) (*Entity, error) {
|
func (db *Database) Set(fullPath, id string) (*Entity, error) {
|
||||||
db.mux.Lock()
|
db.mux.Lock()
|
||||||
defer db.mux.Unlock()
|
defer db.mux.Unlock()
|
||||||
|
@ -171,7 +171,7 @@ func (db *Database) Set(fullPath, id string) (*Entity, error) {
|
||||||
return e, nil
|
return e, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exists returns true if a name already exists in the database
|
// Exists returns true if a name already exists in the database.
|
||||||
func (db *Database) Exists(name string) bool {
|
func (db *Database) Exists(name string) bool {
|
||||||
db.mux.RLock()
|
db.mux.RLock()
|
||||||
defer db.mux.RUnlock()
|
defer db.mux.RUnlock()
|
||||||
|
@ -198,14 +198,14 @@ func (db *Database) setEdge(parentPath, name string, e *Entity, tx *sql.Tx) erro
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// RootEntity returns the root "/" entity for the database
|
// RootEntity returns the root "/" entity for the database.
|
||||||
func (db *Database) RootEntity() *Entity {
|
func (db *Database) RootEntity() *Entity {
|
||||||
return &Entity{
|
return &Entity{
|
||||||
id: "0",
|
id: "0",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns the entity for a given path
|
// Get returns the entity for a given path.
|
||||||
func (db *Database) Get(name string) *Entity {
|
func (db *Database) Get(name string) *Entity {
|
||||||
db.mux.RLock()
|
db.mux.RLock()
|
||||||
defer db.mux.RUnlock()
|
defer db.mux.RUnlock()
|
||||||
|
@ -242,8 +242,8 @@ func (db *Database) get(name string) (*Entity, error) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// List all entities by from the name
|
// List all entities by from the name.
|
||||||
// The key will be the full path of the entity
|
// The key will be the full path of the entity.
|
||||||
func (db *Database) List(name string, depth int) Entities {
|
func (db *Database) List(name string, depth int) Entities {
|
||||||
db.mux.RLock()
|
db.mux.RLock()
|
||||||
defer db.mux.RUnlock()
|
defer db.mux.RUnlock()
|
||||||
|
@ -282,7 +282,7 @@ func (db *Database) Walk(name string, walkFunc WalkFunc, depth int) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Children returns the children of the specified entity
|
// Children returns the children of the specified entity.
|
||||||
func (db *Database) Children(name string, depth int) ([]WalkMeta, error) {
|
func (db *Database) Children(name string, depth int) ([]WalkMeta, error) {
|
||||||
db.mux.RLock()
|
db.mux.RLock()
|
||||||
defer db.mux.RUnlock()
|
defer db.mux.RUnlock()
|
||||||
|
@ -295,7 +295,7 @@ func (db *Database) Children(name string, depth int) ([]WalkMeta, error) {
|
||||||
return db.children(e, name, depth, nil)
|
return db.children(e, name, depth, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parents returns the parents of a specified entity
|
// Parents returns the parents of a specified entity.
|
||||||
func (db *Database) Parents(name string) ([]string, error) {
|
func (db *Database) Parents(name string) ([]string, error) {
|
||||||
db.mux.RLock()
|
db.mux.RLock()
|
||||||
defer db.mux.RUnlock()
|
defer db.mux.RUnlock()
|
||||||
|
@ -307,7 +307,7 @@ func (db *Database) Parents(name string) ([]string, error) {
|
||||||
return db.parents(e)
|
return db.parents(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Refs returns the refrence count for a specified id
|
// Refs returns the refrence count for a specified id.
|
||||||
func (db *Database) Refs(id string) int {
|
func (db *Database) Refs(id string) int {
|
||||||
db.mux.RLock()
|
db.mux.RLock()
|
||||||
defer db.mux.RUnlock()
|
defer db.mux.RUnlock()
|
||||||
|
@ -319,7 +319,7 @@ func (db *Database) Refs(id string) int {
|
||||||
return count
|
return count
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefPaths returns all the id's path references
|
// RefPaths returns all the id's path references.
|
||||||
func (db *Database) RefPaths(id string) Edges {
|
func (db *Database) RefPaths(id string) Edges {
|
||||||
db.mux.RLock()
|
db.mux.RLock()
|
||||||
defer db.mux.RUnlock()
|
defer db.mux.RUnlock()
|
||||||
|
@ -347,7 +347,7 @@ func (db *Database) RefPaths(id string) Edges {
|
||||||
return refs
|
return refs
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete the reference to an entity at a given path
|
// Delete the reference to an entity at a given path.
|
||||||
func (db *Database) Delete(name string) error {
|
func (db *Database) Delete(name string) error {
|
||||||
db.mux.Lock()
|
db.mux.Lock()
|
||||||
defer db.mux.Unlock()
|
defer db.mux.Unlock()
|
||||||
|
@ -446,6 +446,7 @@ func (db *Database) Rename(currentName, newName string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WalkMeta stores the walk metadata.
|
||||||
type WalkMeta struct {
|
type WalkMeta struct {
|
||||||
Parent *Entity
|
Parent *Entity
|
||||||
Entity *Entity
|
Entity *Entity
|
||||||
|
@ -522,7 +523,7 @@ func (db *Database) parents(e *Entity) (parents []string, err error) {
|
||||||
return parents, nil
|
return parents, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the entity based on the parent path and name
|
// Return the entity based on the parent path and name.
|
||||||
func (db *Database) child(parent *Entity, name string) *Entity {
|
func (db *Database) child(parent *Entity, name string) *Entity {
|
||||||
var id string
|
var id string
|
||||||
if err := db.conn.QueryRow("SELECT entity_id FROM edge WHERE parent_id = ? AND name = ?;", parent.id, name).Scan(&id); err != nil {
|
if err := db.conn.QueryRow("SELECT entity_id FROM edge WHERE parent_id = ? AND name = ?;", parent.id, name).Scan(&id); err != nil {
|
||||||
|
@ -531,12 +532,12 @@ func (db *Database) child(parent *Entity, name string) *Entity {
|
||||||
return &Entity{id}
|
return &Entity{id}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ID returns the id used to reference this entity
|
// ID returns the id used to reference this entity.
|
||||||
func (e *Entity) ID() string {
|
func (e *Entity) ID() string {
|
||||||
return e.id
|
return e.id
|
||||||
}
|
}
|
||||||
|
|
||||||
// Paths returns the paths sorted by depth
|
// Paths returns the paths sorted by depth.
|
||||||
func (e Entities) Paths() []string {
|
func (e Entities) Paths() []string {
|
||||||
out := make([]string, len(e))
|
out := make([]string, len(e))
|
||||||
var i int
|
var i int
|
||||||
|
|
|
@ -10,7 +10,7 @@ import (
|
||||||
"github.com/docker/docker/pkg/jsonmessage"
|
"github.com/docker/docker/pkg/jsonmessage"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Download requests a given URL and returns an io.Reader
|
// Download requests a given URL and returns an io.Reader.
|
||||||
func Download(url string) (resp *http.Response, err error) {
|
func Download(url string) (resp *http.Response, err error) {
|
||||||
if resp, err = http.Get(url); err != nil {
|
if resp, err = http.Get(url); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -21,7 +21,7 @@ func Download(url string) (resp *http.Response, err error) {
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHTTPRequestError returns a JSON response error
|
// NewHTTPRequestError returns a JSON response error.
|
||||||
func NewHTTPRequestError(msg string, res *http.Response) error {
|
func NewHTTPRequestError(msg string, res *http.Response) error {
|
||||||
return &jsonmessage.JSONError{
|
return &jsonmessage.JSONError{
|
||||||
Message: msg,
|
Message: msg,
|
||||||
|
@ -29,14 +29,15 @@ func NewHTTPRequestError(msg string, res *http.Response) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ServerHeader contains the server information.
|
||||||
type ServerHeader struct {
|
type ServerHeader struct {
|
||||||
App string // docker
|
App string // docker
|
||||||
Ver string // 1.8.0-dev
|
Ver string // 1.8.0-dev
|
||||||
OS string // windows or linux
|
OS string // windows or linux
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseServerHeader extracts pieces from am HTTP server header
|
// ParseServerHeader extracts pieces from an HTTP server header
|
||||||
// which is in the format "docker/version (os)" eg docker/1.8.0-dev (windows)
|
// which is in the format "docker/version (os)" eg docker/1.8.0-dev (windows).
|
||||||
func ParseServerHeader(hdr string) (*ServerHeader, error) {
|
func ParseServerHeader(hdr string) (*ServerHeader, error) {
|
||||||
re := regexp.MustCompile(`.*\((.+)\).*$`)
|
re := regexp.MustCompile(`.*\((.+)\).*$`)
|
||||||
r := &ServerHeader{}
|
r := &ServerHeader{}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// MimeTypes stores the MIME content type.
|
||||||
var MimeTypes = struct {
|
var MimeTypes = struct {
|
||||||
TextPlain string
|
TextPlain string
|
||||||
Tar string
|
Tar string
|
||||||
|
|
|
@ -53,7 +53,7 @@ func (r *multiReadSeeker) Seek(offset int64, whence int) (int64, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if rdrOffset == s && i != len(r.readers)-1 {
|
if rdrOffset == s && i != len(r.readers)-1 {
|
||||||
idx += 1
|
idx++
|
||||||
rdrOffset = 0
|
rdrOffset = 0
|
||||||
}
|
}
|
||||||
r.pos = &pos{idx, rdrOffset}
|
r.pos = &pos{idx, rdrOffset}
|
||||||
|
|
|
@ -23,6 +23,7 @@ func (r *readCloserWrapper) Close() error {
|
||||||
return r.closer()
|
return r.closer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewReadCloserWrapper returns a new io.ReadCloser.
|
||||||
func NewReadCloserWrapper(r io.Reader, closer func() error) io.ReadCloser {
|
func NewReadCloserWrapper(r io.Reader, closer func() error) io.ReadCloser {
|
||||||
return &readCloserWrapper{
|
return &readCloserWrapper{
|
||||||
Reader: r,
|
Reader: r,
|
||||||
|
@ -43,6 +44,7 @@ func (r *readerErrWrapper) Read(p []byte) (int, error) {
|
||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewReaderErrWrapper returns a new io.Reader.
|
||||||
func NewReaderErrWrapper(r io.Reader, closer func()) io.Reader {
|
func NewReaderErrWrapper(r io.Reader, closer func()) io.Reader {
|
||||||
return &readerErrWrapper{
|
return &readerErrWrapper{
|
||||||
reader: r,
|
reader: r,
|
||||||
|
@ -68,7 +70,8 @@ type bufReader struct {
|
||||||
maxReadDataReset int64
|
maxReadDataReset int64
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBufReader(r io.Reader) *bufReader {
|
// NewBufReader returns a new bufReader.
|
||||||
|
func NewBufReader(r io.Reader) io.ReadCloser {
|
||||||
timeout := rand.New(rndSrc).Intn(120) + 180
|
timeout := rand.New(rndSrc).Intn(120) + 180
|
||||||
|
|
||||||
reader := &bufReader{
|
reader := &bufReader{
|
||||||
|
@ -86,7 +89,8 @@ func NewBufReader(r io.Reader) *bufReader {
|
||||||
return reader
|
return reader
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewBufReaderWithDrainbufAndBuffer(r io.Reader, drainBuffer []byte, buffer *bytes.Buffer) *bufReader {
|
// NewBufReaderWithDrainbufAndBuffer returns a BufReader with drainBuffer and buffer.
|
||||||
|
func NewBufReaderWithDrainbufAndBuffer(r io.Reader, drainBuffer []byte, buffer *bytes.Buffer) io.ReadCloser {
|
||||||
reader := &bufReader{
|
reader := &bufReader{
|
||||||
buf: buffer,
|
buf: buffer,
|
||||||
drainBuf: drainBuffer,
|
drainBuf: drainBuffer,
|
||||||
|
@ -210,6 +214,7 @@ func (r *bufReader) Read(p []byte) (n int, err error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close closes the bufReader
|
||||||
func (r *bufReader) Close() error {
|
func (r *bufReader) Close() error {
|
||||||
closer, ok := r.reader.(io.ReadCloser)
|
closer, ok := r.reader.(io.ReadCloser)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -218,6 +223,7 @@ func (r *bufReader) Close() error {
|
||||||
return closer.Close()
|
return closer.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HashData returns the sha256 sum of src.
|
||||||
func HashData(src io.Reader) (string, error) {
|
func HashData(src io.Reader) (string, error) {
|
||||||
h := sha256.New()
|
h := sha256.New()
|
||||||
if _, err := io.Copy(h, src); err != nil {
|
if _, err := io.Copy(h, src); err != nil {
|
||||||
|
@ -226,6 +232,8 @@ func HashData(src io.Reader) (string, error) {
|
||||||
return "sha256:" + hex.EncodeToString(h.Sum(nil)), nil
|
return "sha256:" + hex.EncodeToString(h.Sum(nil)), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// OnEOFReader wraps a io.ReadCloser and a function
|
||||||
|
// the fuction will run at the end of file or close the file.
|
||||||
type OnEOFReader struct {
|
type OnEOFReader struct {
|
||||||
Rc io.ReadCloser
|
Rc io.ReadCloser
|
||||||
Fn func()
|
Fn func()
|
||||||
|
@ -239,6 +247,7 @@ func (r *OnEOFReader) Read(p []byte) (n int, err error) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close closes the file and run the function.
|
||||||
func (r *OnEOFReader) Close() error {
|
func (r *OnEOFReader) Close() error {
|
||||||
err := r.Rc.Close()
|
err := r.Rc.Close()
|
||||||
r.runFunc()
|
r.runFunc()
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// WriteFlusher wraps the Write and Flush operation.
|
||||||
type WriteFlusher struct {
|
type WriteFlusher struct {
|
||||||
sync.Mutex
|
sync.Mutex
|
||||||
w io.Writer
|
w io.Writer
|
||||||
|
@ -30,12 +31,15 @@ func (wf *WriteFlusher) Flush() {
|
||||||
wf.flusher.Flush()
|
wf.flusher.Flush()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flushed returns the state of flushed.
|
||||||
|
// If it's flushed, return true, or else it return false.
|
||||||
func (wf *WriteFlusher) Flushed() bool {
|
func (wf *WriteFlusher) Flushed() bool {
|
||||||
wf.Lock()
|
wf.Lock()
|
||||||
defer wf.Unlock()
|
defer wf.Unlock()
|
||||||
return wf.flushed
|
return wf.flushed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewWriteFlusher returns a new WriteFlusher.
|
||||||
func NewWriteFlusher(w io.Writer) *WriteFlusher {
|
func NewWriteFlusher(w io.Writer) *WriteFlusher {
|
||||||
var flusher http.Flusher
|
var flusher http.Flusher
|
||||||
if f, ok := w.(http.Flusher); ok {
|
if f, ok := w.(http.Flusher); ok {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package ioutils
|
||||||
|
|
||||||
import "io"
|
import "io"
|
||||||
|
|
||||||
|
// NopWriter represents a type which write operation is nop.
|
||||||
type NopWriter struct{}
|
type NopWriter struct{}
|
||||||
|
|
||||||
func (*NopWriter) Write(buf []byte) (int, error) {
|
func (*NopWriter) Write(buf []byte) (int, error) {
|
||||||
|
@ -14,12 +15,15 @@ type nopWriteCloser struct {
|
||||||
|
|
||||||
func (w *nopWriteCloser) Close() error { return nil }
|
func (w *nopWriteCloser) Close() error { return nil }
|
||||||
|
|
||||||
|
// NopWriteCloser returns a nopWriteCloser.
|
||||||
func NopWriteCloser(w io.Writer) io.WriteCloser {
|
func NopWriteCloser(w io.Writer) io.WriteCloser {
|
||||||
return &nopWriteCloser{w}
|
return &nopWriteCloser{w}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NopFlusher represents a type which flush opetatin is nop.
|
||||||
type NopFlusher struct{}
|
type NopFlusher struct{}
|
||||||
|
|
||||||
|
// Flush is a nop operation.
|
||||||
func (f *NopFlusher) Flush() {}
|
func (f *NopFlusher) Flush() {}
|
||||||
|
|
||||||
type writeCloserWrapper struct {
|
type writeCloserWrapper struct {
|
||||||
|
@ -31,6 +35,7 @@ func (r *writeCloserWrapper) Close() error {
|
||||||
return r.closer()
|
return r.closer()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewWriteCloserWrapper returns a new io.WriteCloser.
|
||||||
func NewWriteCloserWrapper(r io.Writer, closer func() error) io.WriteCloser {
|
func NewWriteCloserWrapper(r io.Writer, closer func() error) io.WriteCloser {
|
||||||
return &writeCloserWrapper{
|
return &writeCloserWrapper{
|
||||||
Writer: r,
|
Writer: r,
|
||||||
|
@ -38,7 +43,7 @@ func NewWriteCloserWrapper(r io.Writer, closer func() error) io.WriteCloser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wrap a concrete io.Writer and hold a count of the number
|
// WriteCounter wraps a concrete io.Writer and hold a count of the number
|
||||||
// of bytes written to the writer during a "session".
|
// of bytes written to the writer during a "session".
|
||||||
// This can be convenient when write return is masked
|
// This can be convenient when write return is masked
|
||||||
// (e.g., json.Encoder.Encode())
|
// (e.g., json.Encoder.Encode())
|
||||||
|
@ -47,6 +52,7 @@ type WriteCounter struct {
|
||||||
Writer io.Writer
|
Writer io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewWriteCounter returns a new WriteCounter.
|
||||||
func NewWriteCounter(w io.Writer) *WriteCounter {
|
func NewWriteCounter(w io.Writer) *WriteCounter {
|
||||||
return &WriteCounter{
|
return &WriteCounter{
|
||||||
Writer: w,
|
Writer: w,
|
||||||
|
|
Loading…
Reference in a new issue