mirror of
https://github.com/lwch/natpass.git
synced 2024-04-21 12:41:54 +00:00
1. 增加代码注释
2. 增加通用encoding层
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
package encoding
|
||||
|
||||
import "io"
|
||||
|
||||
// Codec format data to []byte, decode data from []byte
|
||||
type Codec interface {
|
||||
// Marshal format data to []byte
|
||||
Marshal(interface{}) ([]byte, error)
|
||||
// Unmarshal decode data from []byte
|
||||
Unmarshal([]byte, interface{}) error
|
||||
}
|
||||
|
||||
// Compressor compressor interface
|
||||
type Compressor interface {
|
||||
// Compress get compress writer
|
||||
Compress(io.Writer) (io.WriteCloser, error)
|
||||
// Decompress get decompress reader
|
||||
Decompress(io.Reader) (io.ReadCloser, error)
|
||||
// SetLevel set compress level
|
||||
SetLevel(int) error
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package gzip
|
||||
|
||||
import (
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/lwch/natpass/code/network/encoding"
|
||||
"github.com/lwch/runtime"
|
||||
)
|
||||
|
||||
type writer struct {
|
||||
*gzip.Writer
|
||||
pool *sync.Pool
|
||||
}
|
||||
|
||||
// Close close write and put writer to pool
|
||||
func (w *writer) Close() error {
|
||||
w.pool.Put(w)
|
||||
return w.Writer.Close()
|
||||
}
|
||||
|
||||
type reader struct {
|
||||
*gzip.Reader
|
||||
pool *sync.Pool
|
||||
}
|
||||
|
||||
// Close close reader and put reader to pool
|
||||
func (r *reader) Close() error {
|
||||
r.pool.Put(r)
|
||||
return r.Reader.Close()
|
||||
}
|
||||
|
||||
type compressor struct {
|
||||
level int
|
||||
poolWriter [gzip.BestCompression]sync.Pool
|
||||
poolReader sync.Pool
|
||||
}
|
||||
|
||||
// New create compressor
|
||||
func New(level ...int) (encoding.Compressor, error) {
|
||||
if len(level) > 0 {
|
||||
if level[0] < 0 || level[0] > gzip.BestCompression {
|
||||
return nil, fmt.Errorf("invalid gzip compress level: %d", level[0])
|
||||
}
|
||||
} else {
|
||||
level = append(level, 6)
|
||||
}
|
||||
ret := new(compressor)
|
||||
ret.level = level[0]
|
||||
for i := 0; i < gzip.BestCompression; i++ {
|
||||
ret.poolWriter[i].New = func() interface{} {
|
||||
w, err := gzip.NewWriterLevel(io.Discard, i)
|
||||
runtime.Assert(err)
|
||||
return &writer{Writer: w, pool: &ret.poolWriter[i]}
|
||||
}
|
||||
}
|
||||
ret.poolReader.New = func() interface{} {
|
||||
r, err := gzip.NewReader(io.NopCloser(nil))
|
||||
runtime.Assert(err)
|
||||
return &reader{Reader: r, pool: &ret.poolReader}
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// Compress gzip compress
|
||||
func (c *compressor) Compress(w io.Writer) (io.WriteCloser, error) {
|
||||
pw := c.poolWriter[c.level].Get().(*writer)
|
||||
pw.Writer.Reset(w)
|
||||
return pw, nil
|
||||
}
|
||||
|
||||
// Decompress gzip decompress
|
||||
func (c *compressor) Decompress(r io.Reader) (io.ReadCloser, error) {
|
||||
pr := c.poolReader.Get().(*reader)
|
||||
pr.Reader.Reset(r)
|
||||
return pr, nil
|
||||
}
|
||||
|
||||
// SetLevel set compress level
|
||||
func (c *compressor) SetLevel(level int) error {
|
||||
if level < 0 || level > gzip.BestCompression {
|
||||
return fmt.Errorf("invalid gzip compress level: %d", level)
|
||||
}
|
||||
c.level = level
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package proto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/lwch/natpass/code/network/encoding"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
type codec struct{}
|
||||
|
||||
// New create protobuf codec
|
||||
func New() encoding.Codec {
|
||||
return &codec{}
|
||||
}
|
||||
|
||||
// Marshal protobuf marshal
|
||||
func (*codec) Marshal(v interface{}) ([]byte, error) {
|
||||
vv, ok := v.(proto.Message)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("invalid value type, want proto.Message, got %T", v)
|
||||
}
|
||||
return proto.Marshal(vv)
|
||||
}
|
||||
|
||||
// Unmarshal protobuf unmarshal
|
||||
func (*codec) Unmarshal(data []byte, v interface{}) error {
|
||||
vv, ok := v.(proto.Message)
|
||||
if !ok {
|
||||
return fmt.Errorf("invalid value type, want proto.Message, got %T", v)
|
||||
}
|
||||
return proto.Unmarshal(data, vv)
|
||||
}
|
||||
Reference in New Issue
Block a user