Browse code

Add new logging driver: fluentd

Signed-off-by: TAGOMORI Satoshi <tagomoris@gmail.com>

TAGOMORI Satoshi authored on 2015/06/20 13:07:50
Showing 33 changed files
... ...
@@ -3,6 +3,7 @@ package daemon
3 3
 // Importing packages here only to make sure their init gets called and
4 4
 // therefore they register themselves to the logdriver factory.
5 5
 import (
6
+	_ "github.com/docker/docker/daemon/logger/fluentd"
6 7
 	_ "github.com/docker/docker/daemon/logger/gelf"
7 8
 	_ "github.com/docker/docker/daemon/logger/journald"
8 9
 	_ "github.com/docker/docker/daemon/logger/jsonfilelog"
9 10
new file mode 100644
... ...
@@ -0,0 +1,129 @@
0
+package fluentd
1
+
2
+import (
3
+	"bytes"
4
+	"io"
5
+	"math"
6
+	"net"
7
+	"strconv"
8
+	"strings"
9
+	"text/template"
10
+
11
+	"github.com/Sirupsen/logrus"
12
+	"github.com/docker/docker/daemon/logger"
13
+	"github.com/fluent/fluent-logger-golang/fluent"
14
+)
15
+
16
+type Fluentd struct {
17
+	tag           string
18
+	containerID   string
19
+	containerName string
20
+	writer        *fluent.Fluent
21
+}
22
+
23
+type Receiver struct {
24
+	ID     string
25
+	FullID string
26
+	Name   string
27
+}
28
+
29
+const (
30
+	name             = "fluentd"
31
+	defaultHostName  = "localhost"
32
+	defaultPort      = 24224
33
+	defaultTagPrefix = "docker"
34
+)
35
+
36
+func init() {
37
+	if err := logger.RegisterLogDriver(name, New); err != nil {
38
+		logrus.Fatal(err)
39
+	}
40
+}
41
+
42
+func parseConfig(ctx logger.Context) (string, int, string, error) {
43
+	host := defaultHostName
44
+	port := defaultPort
45
+	tag := "docker." + ctx.ContainerID[:12]
46
+
47
+	config := ctx.Config
48
+
49
+	if address := config["fluentd-address"]; address != "" {
50
+		if h, p, err := net.SplitHostPort(address); err != nil {
51
+			if !strings.Contains(err.Error(), "missing port in address") {
52
+				return "", 0, "", err
53
+			}
54
+			host = h
55
+		} else {
56
+			portnum, err := strconv.Atoi(p)
57
+			if err != nil {
58
+				return "", 0, "", err
59
+			}
60
+			host = h
61
+			port = portnum
62
+		}
63
+	}
64
+
65
+	if config["fluentd-tag"] != "" {
66
+		receiver := &Receiver{
67
+			ID:     ctx.ContainerID[:12],
68
+			FullID: ctx.ContainerID,
69
+			Name:   ctx.ContainerName,
70
+		}
71
+		tmpl, err := template.New("tag").Parse(config["fluentd-tag"])
72
+		if err != nil {
73
+			return "", 0, "", err
74
+		}
75
+		buf := new(bytes.Buffer)
76
+		if err := tmpl.Execute(buf, receiver); err != nil {
77
+			return "", 0, "", err
78
+		}
79
+		tag = buf.String()
80
+	}
81
+
82
+	return host, port, tag, nil
83
+}
84
+
85
+func New(ctx logger.Context) (logger.Logger, error) {
86
+	host, port, tag, err := parseConfig(ctx)
87
+	if err != nil {
88
+		return nil, err
89
+	}
90
+	logrus.Debugf("logging driver fluentd configured for container:%s, host:%s, port:%d, tag:%s.", ctx.ContainerID, host, port, tag)
91
+
92
+	// logger tries to recoonect 2**64 - 1 times
93
+	// failed (and panic) after 204 years [ 1.5 ** (2**32 - 1) - 1 seconds]
94
+	log, err := fluent.New(fluent.Config{FluentPort: port, FluentHost: host, RetryWait: 1000, MaxRetry: math.MaxUint32})
95
+	if err != nil {
96
+		return nil, err
97
+	}
98
+	return &Fluentd{
99
+		tag:           tag,
100
+		containerID:   ctx.ContainerID,
101
+		containerName: ctx.ContainerName,
102
+		writer:        log,
103
+	}, nil
104
+}
105
+
106
+func (f *Fluentd) Log(msg *logger.Message) error {
107
+	data := map[string]string{
108
+		"container_id":   f.containerID,
109
+		"container_name": f.containerName,
110
+		"source":         msg.Source,
111
+		"log":            string(msg.Line),
112
+	}
113
+	// fluent-logger-golang buffers logs from failures and disconnections,
114
+	// and these are transferred again automatically.
115
+	return f.writer.PostWithTime(f.tag, msg.Timestamp, data)
116
+}
117
+
118
+func (f *Fluentd) Close() error {
119
+	return f.writer.Close()
120
+}
121
+
122
+func (f *Fluentd) Name() string {
123
+	return name
124
+}
125
+
126
+func (s *Fluentd) GetReader() (io.Reader, error) {
127
+	return nil, logger.ReadLogsNotSupported
128
+}
... ...
@@ -884,6 +884,16 @@ container's logging driver. The following options are supported:
884 884
 driver.  For detailed information on working with logging drivers, see
885 885
 [Configure a logging driver](reference/logging/).
886 886
 
887
+#### Logging driver: fluentd
888
+
889
+Fluentd logging driver for Docker. Writes log messages to fluentd (forward input). `docker logs`
890
+command is not available for this logging driver.
891
+
892
+Some options are supported by specifying `--log-opt` as many as needed, like `--log-opt fluentd-address=localhost:24224`.
893
+
894
+ - `fluentd-address`: specify `host:port` to connect [localhost:24224]
895
+ - `fluentd-tag`: specify tag for fluentd message, which interpret some markup, ex `{{.ID}}`, `{{.FullID}}` or `{{.Name}}` [docker.{{.ID}}]
896
+
887 897
 ## Overriding Dockerfile image defaults
888 898
 
889 899
 When a developer builds an image from a [*Dockerfile*](/reference/builder)
... ...
@@ -42,4 +42,9 @@ clone git github.com/syndtr/gocapability 66ef2aa7a23ba682594e2b6f74cf40c0692b49f
42 42
 clone git github.com/golang/protobuf 655cdfa588ea
43 43
 clone git github.com/Graylog2/go-gelf 6c62a85f1d47a67f2a5144c0e745b325889a8120
44 44
 
45
+clone git github.com/fluent/fluent-logger-golang v1.0.0
46
+# fluent-logger-golang deps
47
+clone git github.com/philhofer/fwd 899e4efba8eaa1fea74175308f3fae18ff3319fa
48
+clone git github.com/tinylib/msgp 75ee40d2601edf122ef667e2a07d600d4c44490c
49
+
45 50
 clean
... ...
@@ -155,7 +155,7 @@ two memory nodes.
155 155
 **--lxc-conf**=[]
156 156
    (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
157 157
 
158
-**--log-driver**="|*json-file*|*syslog*|*journald*|*gelf*|*none*"
158
+**--log-driver**="|*json-file*|*syslog*|*journald*|*gelf*|*fluentd*|*none*"
159 159
   Logging driver for container. Default is defined by daemon `--log-driver` flag.
160 160
   **Warning**: `docker logs` command works only for `json-file` logging driver.
161 161
 
... ...
@@ -252,7 +252,7 @@ which interface and port to use.
252 252
 **--lxc-conf**=[]
253 253
    (lxc exec-driver only) Add custom lxc options --lxc-conf="lxc.cgroup.cpuset.cpus = 0,1"
254 254
 
255
-**--log-driver**="|*json-file*|*syslog*|*journald*|*gelf*|*none*"
255
+**--log-driver**="|*json-file*|*syslog*|*journald*|*gelf*|*fluentd*|*none*"
256 256
   Logging driver for container. Default is defined by daemon `--log-driver` flag.
257 257
   **Warning**: `docker logs` command works only for `json-file` logging driver.
258 258
 
... ...
@@ -103,7 +103,7 @@ unix://[/path/to/socket] to use.
103 103
 **--label**="[]"
104 104
   Set key=value labels to the daemon (displayed in `docker info`)
105 105
 
106
-**--log-driver**="*json-file*|*syslog*|*journald*|*gelf*|*none*"
106
+**--log-driver**="*json-file*|*syslog*|*journald*|*gelf*|*fluentd*|*none*"
107 107
   Default driver for container logs. Default is `json-file`.
108 108
   **Warning**: `docker logs` command works only for `json-file` logging driver.
109 109
 
110 110
new file mode 100644
... ...
@@ -0,0 +1,245 @@
0
+package fluent
1
+
2
+import (
3
+	"errors"
4
+	"fmt"
5
+	"math"
6
+	"net"
7
+	"reflect"
8
+	"strconv"
9
+	"sync"
10
+	"time"
11
+)
12
+
13
+const (
14
+	defaultHost                   = "127.0.0.1"
15
+	defaultPort                   = 24224
16
+	defaultTimeout                = 3 * time.Second
17
+	defaultBufferLimit            = 8 * 1024 * 1024
18
+	defaultRetryWait              = 500
19
+	defaultMaxRetry               = 13
20
+	defaultReconnectWaitIncreRate = 1.5
21
+)
22
+
23
+type Config struct {
24
+	FluentPort  int
25
+	FluentHost  string
26
+	Timeout     time.Duration
27
+	BufferLimit int
28
+	RetryWait   int
29
+	MaxRetry    int
30
+	TagPrefix   string
31
+}
32
+
33
+type Fluent struct {
34
+	Config
35
+	conn         net.Conn
36
+	pending      []byte
37
+	reconnecting bool
38
+	mu           sync.Mutex
39
+}
40
+
41
+// New creates a new Logger.
42
+func New(config Config) (f *Fluent, err error) {
43
+	if config.FluentHost == "" {
44
+		config.FluentHost = defaultHost
45
+	}
46
+	if config.FluentPort == 0 {
47
+		config.FluentPort = defaultPort
48
+	}
49
+	if config.Timeout == 0 {
50
+		config.Timeout = defaultTimeout
51
+	}
52
+	if config.BufferLimit == 0 {
53
+		config.BufferLimit = defaultBufferLimit
54
+	}
55
+	if config.RetryWait == 0 {
56
+		config.RetryWait = defaultRetryWait
57
+	}
58
+	if config.MaxRetry == 0 {
59
+		config.MaxRetry = defaultMaxRetry
60
+	}
61
+	f = &Fluent{Config: config, reconnecting: false}
62
+	err = f.connect()
63
+	return
64
+}
65
+
66
+// Post writes the output for a logging event.
67
+//
68
+// Examples:
69
+//
70
+//  // send string
71
+//  f.Post("tag_name", "data")
72
+//
73
+//  // send map[string]
74
+//  mapStringData := map[string]string{
75
+//  	"foo":  "bar",
76
+//  }
77
+//  f.Post("tag_name", mapStringData)
78
+//
79
+//  // send message with specified time
80
+//  mapStringData := map[string]string{
81
+//  	"foo":  "bar",
82
+//  }
83
+//  tm := time.Now()
84
+//  f.PostWithTime("tag_name", tm, mapStringData)
85
+//
86
+//  // send struct
87
+//  structData := struct {
88
+//  		Name string `msg:"name"`
89
+//  } {
90
+//  		"john smith",
91
+//  }
92
+//  f.Post("tag_name", structData)
93
+//
94
+func (f *Fluent) Post(tag string, message interface{}) error {
95
+	timeNow := time.Now()
96
+	return f.PostWithTime(tag, timeNow, message)
97
+}
98
+
99
+func (f *Fluent) PostWithTime(tag string, tm time.Time, message interface{}) error {
100
+	if len(f.TagPrefix) > 0 {
101
+		tag = f.TagPrefix + "." + tag
102
+	}
103
+
104
+	msg := reflect.ValueOf(message)
105
+	msgtype := msg.Type()
106
+
107
+	if msgtype.Kind() == reflect.Struct {
108
+		// message should be tagged by "codec" or "msg"
109
+		kv := make(map[string]interface{})
110
+		fields := msgtype.NumField()
111
+		for i := 0; i < fields; i++ {
112
+			field := msgtype.Field(i)
113
+			name := field.Name
114
+			if n1 := field.Tag.Get("msg"); n1 != "" {
115
+				name = n1
116
+			} else if n2 := field.Tag.Get("codec"); n2 != "" {
117
+				name = n2
118
+			}
119
+			kv[name] = msg.FieldByIndex(field.Index).Interface()
120
+		}
121
+		return f.EncodeAndPostData(tag, tm, kv)
122
+	}
123
+
124
+	if msgtype.Kind() != reflect.Map {
125
+		return errors.New("messge must be a map")
126
+	} else if msgtype.Key().Kind() != reflect.String {
127
+		return errors.New("map keys must be strings")
128
+	}
129
+
130
+	kv := make(map[string]interface{})
131
+	for _, k := range msg.MapKeys() {
132
+		kv[k.String()] = msg.MapIndex(k).Interface()
133
+	}
134
+
135
+	return f.EncodeAndPostData(tag, tm, kv)
136
+}
137
+
138
+func (f *Fluent) EncodeAndPostData(tag string, tm time.Time, message interface{}) error {
139
+	if data, dumperr := f.EncodeData(tag, tm, message); dumperr != nil {
140
+		return fmt.Errorf("fluent#EncodeAndPostData: can't convert '%s' to msgpack:%s", message, dumperr)
141
+		// fmt.Println("fluent#Post: can't convert to msgpack:", message, dumperr)
142
+	} else {
143
+		f.PostRawData(data)
144
+		return nil
145
+	}
146
+}
147
+
148
+func (f *Fluent) PostRawData(data []byte) {
149
+	f.mu.Lock()
150
+	f.pending = append(f.pending, data...)
151
+	f.mu.Unlock()
152
+	if err := f.send(); err != nil {
153
+		f.close()
154
+		if len(f.pending) > f.Config.BufferLimit {
155
+			f.flushBuffer()
156
+		}
157
+	} else {
158
+		f.flushBuffer()
159
+	}
160
+}
161
+
162
+func (f *Fluent) EncodeData(tag string, tm time.Time, message interface{}) (data []byte, err error) {
163
+	timeUnix := tm.Unix()
164
+	msg := &Message{Tag: tag, Time: timeUnix, Record: message}
165
+	data, err = msg.MarshalMsg(nil)
166
+	return
167
+}
168
+
169
+// Close closes the connection.
170
+func (f *Fluent) Close() (err error) {
171
+	if len(f.pending) > 0 {
172
+		_ = f.send()
173
+	}
174
+	err = f.close()
175
+	return
176
+}
177
+
178
+// close closes the connection.
179
+func (f *Fluent) close() (err error) {
180
+	if f.conn != nil {
181
+		f.mu.Lock()
182
+		defer f.mu.Unlock()
183
+	} else {
184
+		return
185
+	}
186
+	if f.conn != nil {
187
+		f.conn.Close()
188
+		f.conn = nil
189
+	}
190
+	return
191
+}
192
+
193
+// connect establishes a new connection using the specified transport.
194
+func (f *Fluent) connect() (err error) {
195
+	f.conn, err = net.DialTimeout("tcp", f.Config.FluentHost+":"+strconv.Itoa(f.Config.FluentPort), f.Config.Timeout)
196
+	return
197
+}
198
+
199
+func e(x, y float64) int {
200
+	return int(math.Pow(x, y))
201
+}
202
+
203
+func (f *Fluent) reconnect() {
204
+	go func() {
205
+		for i := 0; ; i++ {
206
+			err := f.connect()
207
+			if err == nil {
208
+				f.mu.Lock()
209
+				f.reconnecting = false
210
+				f.mu.Unlock()
211
+				break
212
+			} else {
213
+				if i == f.Config.MaxRetry {
214
+					panic("fluent#reconnect: failed to reconnect!")
215
+				}
216
+				waitTime := f.Config.RetryWait * e(defaultReconnectWaitIncreRate, float64(i-1))
217
+				time.Sleep(time.Duration(waitTime) * time.Millisecond)
218
+			}
219
+		}
220
+	}()
221
+}
222
+
223
+func (f *Fluent) flushBuffer() {
224
+	f.mu.Lock()
225
+	defer f.mu.Unlock()
226
+	f.pending = f.pending[0:0]
227
+}
228
+
229
+func (f *Fluent) send() (err error) {
230
+	if f.conn == nil {
231
+		if f.reconnecting == false {
232
+			f.mu.Lock()
233
+			f.reconnecting = true
234
+			f.mu.Unlock()
235
+			f.reconnect()
236
+		}
237
+		err = errors.New("fluent#send: can't send logs, client is reconnecting")
238
+	} else {
239
+		f.mu.Lock()
240
+		_, err = f.conn.Write(f.pending)
241
+		f.mu.Unlock()
242
+	}
243
+	return
244
+}
0 245
new file mode 100644
... ...
@@ -0,0 +1,24 @@
0
+//go:generate msgp
1
+
2
+package fluent
3
+
4
+//msgp:tuple Entry
5
+type Entry struct {
6
+	Time   int64       `msg:"time"`
7
+	Record interface{} `msg:"record"`
8
+}
9
+
10
+//msgp:tuple Forward
11
+type Forward struct {
12
+	Tag     string      `msg:"tag"`
13
+	Entries []Entry     `msg:"entries"`
14
+	Option  interface{} `msg:"option"`
15
+}
16
+
17
+//msgp:tuple Message
18
+type Message struct {
19
+	Tag    string      `msg:"tag"`
20
+	Time   int64       `msg:"time"`
21
+	Record interface{} `msg:"record"`
22
+	Option interface{} `msg:"option"`
23
+}
0 24
new file mode 100644
... ...
@@ -0,0 +1,372 @@
0
+package fluent
1
+
2
+// NOTE: THIS FILE WAS PRODUCED BY THE
3
+// MSGP CODE GENERATION TOOL (github.com/tinylib/msgp)
4
+// DO NOT EDIT
5
+
6
+import (
7
+	"github.com/tinylib/msgp/msgp"
8
+)
9
+
10
+// DecodeMsg implements msgp.Decodable
11
+func (z *Entry) DecodeMsg(dc *msgp.Reader) (err error) {
12
+	var ssz uint32
13
+	ssz, err = dc.ReadArrayHeader()
14
+	if err != nil {
15
+		return
16
+	}
17
+	if ssz != 2 {
18
+		err = msgp.ArrayError{Wanted: 2, Got: ssz}
19
+		return
20
+	}
21
+	z.Time, err = dc.ReadInt64()
22
+	if err != nil {
23
+		return
24
+	}
25
+	z.Record, err = dc.ReadIntf()
26
+	if err != nil {
27
+		return
28
+	}
29
+	return
30
+}
31
+
32
+// EncodeMsg implements msgp.Encodable
33
+func (z Entry) EncodeMsg(en *msgp.Writer) (err error) {
34
+	err = en.WriteArrayHeader(2)
35
+	if err != nil {
36
+		return
37
+	}
38
+	err = en.WriteInt64(z.Time)
39
+	if err != nil {
40
+		return
41
+	}
42
+	err = en.WriteIntf(z.Record)
43
+	if err != nil {
44
+		return
45
+	}
46
+	return
47
+}
48
+
49
+// MarshalMsg implements msgp.Marshaler
50
+func (z Entry) MarshalMsg(b []byte) (o []byte, err error) {
51
+	o = msgp.Require(b, z.Msgsize())
52
+	o = msgp.AppendArrayHeader(o, 2)
53
+	o = msgp.AppendInt64(o, z.Time)
54
+	o, err = msgp.AppendIntf(o, z.Record)
55
+	if err != nil {
56
+		return
57
+	}
58
+	return
59
+}
60
+
61
+// UnmarshalMsg implements msgp.Unmarshaler
62
+func (z *Entry) UnmarshalMsg(bts []byte) (o []byte, err error) {
63
+	{
64
+		var ssz uint32
65
+		ssz, bts, err = msgp.ReadArrayHeaderBytes(bts)
66
+		if err != nil {
67
+			return
68
+		}
69
+		if ssz != 2 {
70
+			err = msgp.ArrayError{Wanted: 2, Got: ssz}
71
+			return
72
+		}
73
+	}
74
+	z.Time, bts, err = msgp.ReadInt64Bytes(bts)
75
+	if err != nil {
76
+		return
77
+	}
78
+	z.Record, bts, err = msgp.ReadIntfBytes(bts)
79
+	if err != nil {
80
+		return
81
+	}
82
+	o = bts
83
+	return
84
+}
85
+
86
+func (z Entry) Msgsize() (s int) {
87
+	s = msgp.ArrayHeaderSize + msgp.Int64Size + msgp.GuessSize(z.Record)
88
+	return
89
+}
90
+
91
+// DecodeMsg implements msgp.Decodable
92
+func (z *Forward) DecodeMsg(dc *msgp.Reader) (err error) {
93
+	var ssz uint32
94
+	ssz, err = dc.ReadArrayHeader()
95
+	if err != nil {
96
+		return
97
+	}
98
+	if ssz != 3 {
99
+		err = msgp.ArrayError{Wanted: 3, Got: ssz}
100
+		return
101
+	}
102
+	z.Tag, err = dc.ReadString()
103
+	if err != nil {
104
+		return
105
+	}
106
+	var xsz uint32
107
+	xsz, err = dc.ReadArrayHeader()
108
+	if err != nil {
109
+		return
110
+	}
111
+	if cap(z.Entries) >= int(xsz) {
112
+		z.Entries = z.Entries[:xsz]
113
+	} else {
114
+		z.Entries = make([]Entry, xsz)
115
+	}
116
+	for xvk := range z.Entries {
117
+		var ssz uint32
118
+		ssz, err = dc.ReadArrayHeader()
119
+		if err != nil {
120
+			return
121
+		}
122
+		if ssz != 2 {
123
+			err = msgp.ArrayError{Wanted: 2, Got: ssz}
124
+			return
125
+		}
126
+		z.Entries[xvk].Time, err = dc.ReadInt64()
127
+		if err != nil {
128
+			return
129
+		}
130
+		z.Entries[xvk].Record, err = dc.ReadIntf()
131
+		if err != nil {
132
+			return
133
+		}
134
+	}
135
+	z.Option, err = dc.ReadIntf()
136
+	if err != nil {
137
+		return
138
+	}
139
+	return
140
+}
141
+
142
+// EncodeMsg implements msgp.Encodable
143
+func (z *Forward) EncodeMsg(en *msgp.Writer) (err error) {
144
+	err = en.WriteArrayHeader(3)
145
+	if err != nil {
146
+		return
147
+	}
148
+	err = en.WriteString(z.Tag)
149
+	if err != nil {
150
+		return
151
+	}
152
+	err = en.WriteArrayHeader(uint32(len(z.Entries)))
153
+	if err != nil {
154
+		return
155
+	}
156
+	for xvk := range z.Entries {
157
+		err = en.WriteArrayHeader(2)
158
+		if err != nil {
159
+			return
160
+		}
161
+		err = en.WriteInt64(z.Entries[xvk].Time)
162
+		if err != nil {
163
+			return
164
+		}
165
+		err = en.WriteIntf(z.Entries[xvk].Record)
166
+		if err != nil {
167
+			return
168
+		}
169
+	}
170
+	err = en.WriteIntf(z.Option)
171
+	if err != nil {
172
+		return
173
+	}
174
+	return
175
+}
176
+
177
+// MarshalMsg implements msgp.Marshaler
178
+func (z *Forward) MarshalMsg(b []byte) (o []byte, err error) {
179
+	o = msgp.Require(b, z.Msgsize())
180
+	o = msgp.AppendArrayHeader(o, 3)
181
+	o = msgp.AppendString(o, z.Tag)
182
+	o = msgp.AppendArrayHeader(o, uint32(len(z.Entries)))
183
+	for xvk := range z.Entries {
184
+		o = msgp.AppendArrayHeader(o, 2)
185
+		o = msgp.AppendInt64(o, z.Entries[xvk].Time)
186
+		o, err = msgp.AppendIntf(o, z.Entries[xvk].Record)
187
+		if err != nil {
188
+			return
189
+		}
190
+	}
191
+	o, err = msgp.AppendIntf(o, z.Option)
192
+	if err != nil {
193
+		return
194
+	}
195
+	return
196
+}
197
+
198
+// UnmarshalMsg implements msgp.Unmarshaler
199
+func (z *Forward) UnmarshalMsg(bts []byte) (o []byte, err error) {
200
+	{
201
+		var ssz uint32
202
+		ssz, bts, err = msgp.ReadArrayHeaderBytes(bts)
203
+		if err != nil {
204
+			return
205
+		}
206
+		if ssz != 3 {
207
+			err = msgp.ArrayError{Wanted: 3, Got: ssz}
208
+			return
209
+		}
210
+	}
211
+	z.Tag, bts, err = msgp.ReadStringBytes(bts)
212
+	if err != nil {
213
+		return
214
+	}
215
+	var xsz uint32
216
+	xsz, bts, err = msgp.ReadArrayHeaderBytes(bts)
217
+	if err != nil {
218
+		return
219
+	}
220
+	if cap(z.Entries) >= int(xsz) {
221
+		z.Entries = z.Entries[:xsz]
222
+	} else {
223
+		z.Entries = make([]Entry, xsz)
224
+	}
225
+	for xvk := range z.Entries {
226
+		{
227
+			var ssz uint32
228
+			ssz, bts, err = msgp.ReadArrayHeaderBytes(bts)
229
+			if err != nil {
230
+				return
231
+			}
232
+			if ssz != 2 {
233
+				err = msgp.ArrayError{Wanted: 2, Got: ssz}
234
+				return
235
+			}
236
+		}
237
+		z.Entries[xvk].Time, bts, err = msgp.ReadInt64Bytes(bts)
238
+		if err != nil {
239
+			return
240
+		}
241
+		z.Entries[xvk].Record, bts, err = msgp.ReadIntfBytes(bts)
242
+		if err != nil {
243
+			return
244
+		}
245
+	}
246
+	z.Option, bts, err = msgp.ReadIntfBytes(bts)
247
+	if err != nil {
248
+		return
249
+	}
250
+	o = bts
251
+	return
252
+}
253
+
254
+func (z *Forward) Msgsize() (s int) {
255
+	s = msgp.ArrayHeaderSize + msgp.StringPrefixSize + len(z.Tag) + msgp.ArrayHeaderSize
256
+	for xvk := range z.Entries {
257
+		s += msgp.ArrayHeaderSize + msgp.Int64Size + msgp.GuessSize(z.Entries[xvk].Record)
258
+	}
259
+	s += msgp.GuessSize(z.Option)
260
+	return
261
+}
262
+
263
+// DecodeMsg implements msgp.Decodable
264
+func (z *Message) DecodeMsg(dc *msgp.Reader) (err error) {
265
+	var ssz uint32
266
+	ssz, err = dc.ReadArrayHeader()
267
+	if err != nil {
268
+		return
269
+	}
270
+	if ssz != 4 {
271
+		err = msgp.ArrayError{Wanted: 4, Got: ssz}
272
+		return
273
+	}
274
+	z.Tag, err = dc.ReadString()
275
+	if err != nil {
276
+		return
277
+	}
278
+	z.Time, err = dc.ReadInt64()
279
+	if err != nil {
280
+		return
281
+	}
282
+	z.Record, err = dc.ReadIntf()
283
+	if err != nil {
284
+		return
285
+	}
286
+	z.Option, err = dc.ReadIntf()
287
+	if err != nil {
288
+		return
289
+	}
290
+	return
291
+}
292
+
293
+// EncodeMsg implements msgp.Encodable
294
+func (z *Message) EncodeMsg(en *msgp.Writer) (err error) {
295
+	err = en.WriteArrayHeader(4)
296
+	if err != nil {
297
+		return
298
+	}
299
+	err = en.WriteString(z.Tag)
300
+	if err != nil {
301
+		return
302
+	}
303
+	err = en.WriteInt64(z.Time)
304
+	if err != nil {
305
+		return
306
+	}
307
+	err = en.WriteIntf(z.Record)
308
+	if err != nil {
309
+		return
310
+	}
311
+	err = en.WriteIntf(z.Option)
312
+	if err != nil {
313
+		return
314
+	}
315
+	return
316
+}
317
+
318
+// MarshalMsg implements msgp.Marshaler
319
+func (z *Message) MarshalMsg(b []byte) (o []byte, err error) {
320
+	o = msgp.Require(b, z.Msgsize())
321
+	o = msgp.AppendArrayHeader(o, 4)
322
+	o = msgp.AppendString(o, z.Tag)
323
+	o = msgp.AppendInt64(o, z.Time)
324
+	o, err = msgp.AppendIntf(o, z.Record)
325
+	if err != nil {
326
+		return
327
+	}
328
+	o, err = msgp.AppendIntf(o, z.Option)
329
+	if err != nil {
330
+		return
331
+	}
332
+	return
333
+}
334
+
335
+// UnmarshalMsg implements msgp.Unmarshaler
336
+func (z *Message) UnmarshalMsg(bts []byte) (o []byte, err error) {
337
+	{
338
+		var ssz uint32
339
+		ssz, bts, err = msgp.ReadArrayHeaderBytes(bts)
340
+		if err != nil {
341
+			return
342
+		}
343
+		if ssz != 4 {
344
+			err = msgp.ArrayError{Wanted: 4, Got: ssz}
345
+			return
346
+		}
347
+	}
348
+	z.Tag, bts, err = msgp.ReadStringBytes(bts)
349
+	if err != nil {
350
+		return
351
+	}
352
+	z.Time, bts, err = msgp.ReadInt64Bytes(bts)
353
+	if err != nil {
354
+		return
355
+	}
356
+	z.Record, bts, err = msgp.ReadIntfBytes(bts)
357
+	if err != nil {
358
+		return
359
+	}
360
+	z.Option, bts, err = msgp.ReadIntfBytes(bts)
361
+	if err != nil {
362
+		return
363
+	}
364
+	o = bts
365
+	return
366
+}
367
+
368
+func (z *Message) Msgsize() (s int) {
369
+	s = msgp.ArrayHeaderSize + msgp.StringPrefixSize + len(z.Tag) + msgp.Int64Size + msgp.GuessSize(z.Record) + msgp.GuessSize(z.Option)
370
+	return
371
+}
0 372
new file mode 100644
... ...
@@ -0,0 +1,3 @@
0
+package fluent
1
+
2
+const Version = "0.5.1"
0 3
new file mode 100644
... ...
@@ -0,0 +1,311 @@
0
+
1
+# fwd
2
+    import "github.com/philhofer/fwd"
3
+
4
+The `fwd` package provides a buffered reader
5
+and writer. Each has methods that help improve
6
+the encoding/decoding performance of some binary
7
+protocols.
8
+
9
+The `fwd.Writer` and `fwd.Reader` type provide similar
10
+functionality to their counterparts in `bufio`, plus
11
+a few extra utility methods that simplify read-ahead
12
+and write-ahead. I wrote this package to improve serialization
13
+performance for <a href="http://github.com/philhofer/msgp">http://github.com/philhofer/msgp</a>,
14
+where it provided about a 2x speedup over `bufio`. However,
15
+care must be taken to understand the semantics of the
16
+extra methods provided by this package, as they allow
17
+the user to access and manipulate the buffer memory
18
+directly.
19
+
20
+The extra methods for `fwd.Reader` are `Peek`, `Skip`
21
+and `Next`. `(*fwd.Reader).Peek`, unlike `(*bufio.Reader).Peek`,
22
+will re-allocate the read buffer in order to accommodate arbitrarily
23
+large read-ahead. `(*fwd.Reader).Skip` skips the next `n` bytes
24
+in the stream, and uses the `io.Seeker` interface if the underlying
25
+stream implements it. `(*fwd.Reader).Next` returns a slice pointing
26
+to the next `n` bytes in the read buffer (like `Peek`), but also
27
+increments the read position. This allows users to process streams
28
+in aribtrary block sizes without having to manage appropriately-sized
29
+slices. Additionally, obviating the need to copy the data from the
30
+buffer to another location in memory can improve performance dramatically
31
+in CPU-bound applications.
32
+
33
+`fwd.Writer` only has one extra method, which is `(*fwd.Writer).Next`, which
34
+returns a slice pointing to the next `n` bytes of the writer, and increments
35
+the write position by the length of the returned slice. This allows users
36
+to write directly to the end of the buffer.
37
+
38
+
39
+
40
+
41
+## Constants
42
+``` go
43
+const (
44
+    // DefaultReaderSize is the default size of the read buffer
45
+    DefaultReaderSize = 2048
46
+)
47
+```
48
+``` go
49
+const (
50
+    // DefaultWriterSize is the
51
+    // default write buffer size.
52
+    DefaultWriterSize = 2048
53
+)
54
+```
55
+
56
+
57
+
58
+## type Reader
59
+``` go
60
+type Reader struct {
61
+    // contains filtered or unexported fields
62
+}
63
+```
64
+Reader is a buffered look-ahead reader
65
+
66
+
67
+
68
+
69
+
70
+
71
+
72
+
73
+
74
+### func NewReader
75
+``` go
76
+func NewReader(r io.Reader) *Reader
77
+```
78
+NewReader returns a new *Reader that reads from 'r'
79
+
80
+
81
+### func NewReaderSize
82
+``` go
83
+func NewReaderSize(r io.Reader, n int) *Reader
84
+```
85
+NewReaderSize returns a new *Reader that
86
+reads from 'r' and has a buffer size 'n'
87
+
88
+
89
+
90
+
91
+### func (\*Reader) BufferSize
92
+``` go
93
+func (r *Reader) BufferSize() int
94
+```
95
+BufferSize returns the total size of the buffer
96
+
97
+
98
+
99
+### func (\*Reader) Buffered
100
+``` go
101
+func (r *Reader) Buffered() int
102
+```
103
+Buffered returns the number of bytes currently in the buffer
104
+
105
+
106
+
107
+### func (\*Reader) Next
108
+``` go
109
+func (r *Reader) Next(n int) ([]byte, error)
110
+```
111
+Next returns the next 'n' bytes in the stream.
112
+If the returned slice has a length less than 'n',
113
+an error will also be returned.
114
+Unlike Peek, Next advances the reader position.
115
+The returned bytes point to the same
116
+data as the buffer, so the slice is
117
+only valid until the next reader method call.
118
+An EOF is considered an unexpected error.
119
+
120
+
121
+
122
+### func (\*Reader) Peek
123
+``` go
124
+func (r *Reader) Peek(n int) ([]byte, error)
125
+```
126
+Peek returns the next 'n' buffered bytes,
127
+reading from the underlying reader if necessary.
128
+It will only return a slice shorter than 'n' bytes
129
+if it also returns an error. Peek does not advance
130
+the reader. EOF errors are *not* returned as
131
+io.ErrUnexpectedEOF.
132
+
133
+
134
+
135
+### func (\*Reader) Read
136
+``` go
137
+func (r *Reader) Read(b []byte) (int, error)
138
+```
139
+Read implements `io.Reader`
140
+
141
+
142
+
143
+### func (\*Reader) ReadByte
144
+``` go
145
+func (r *Reader) ReadByte() (byte, error)
146
+```
147
+ReadByte implements `io.ByteReader`
148
+
149
+
150
+
151
+### func (\*Reader) ReadFull
152
+``` go
153
+func (r *Reader) ReadFull(b []byte) (int, error)
154
+```
155
+ReadFull attempts to read len(b) bytes into
156
+'b'. It returns the number of bytes read into
157
+'b', and an error if it does not return len(b).
158
+
159
+
160
+
161
+### func (\*Reader) Reset
162
+``` go
163
+func (r *Reader) Reset(rd io.Reader)
164
+```
165
+Reset resets the underlying reader
166
+and the read buffer.
167
+
168
+
169
+
170
+### func (\*Reader) Skip
171
+``` go
172
+func (r *Reader) Skip(n int) (int, error)
173
+```
174
+Skip moves the reader forward 'n' bytes.
175
+Returns the number of bytes skipped and any
176
+errors encountered. It is analagous to Seek(n, 1).
177
+If the underlying reader implements io.Seeker, then
178
+that method will be used to skip forward.
179
+
180
+If the reader encounters
181
+an EOF before skipping 'n' bytes, it
182
+returns io.ErrUnexpectedEOF. If the
183
+underlying reader implements io.Seeker, then
184
+those rules apply instead. (Many implementations
185
+will not return `io.EOF` until the next call
186
+to Read.)
187
+
188
+
189
+
190
+### func (\*Reader) WriteTo
191
+``` go
192
+func (r *Reader) WriteTo(w io.Writer) (int64, error)
193
+```
194
+WriteTo implements `io.WriterTo`
195
+
196
+
197
+
198
+## type Writer
199
+``` go
200
+type Writer struct {
201
+    // contains filtered or unexported fields
202
+}
203
+```
204
+Writer is a buffered writer
205
+
206
+
207
+
208
+
209
+
210
+
211
+
212
+
213
+
214
+### func NewWriter
215
+``` go
216
+func NewWriter(w io.Writer) *Writer
217
+```
218
+NewWriter returns a new writer
219
+that writes to 'w' and has a buffer
220
+that is `DefaultWriterSize` bytes.
221
+
222
+
223
+### func NewWriterSize
224
+``` go
225
+func NewWriterSize(w io.Writer, size int) *Writer
226
+```
227
+NewWriterSize returns a new writer
228
+that writes to 'w' and has a buffer
229
+that is 'size' bytes.
230
+
231
+
232
+
233
+
234
+### func (\*Writer) BufferSize
235
+``` go
236
+func (w *Writer) BufferSize() int
237
+```
238
+BufferSize returns the maximum size of the buffer.
239
+
240
+
241
+
242
+### func (\*Writer) Buffered
243
+``` go
244
+func (w *Writer) Buffered() int
245
+```
246
+Buffered returns the number of buffered bytes
247
+in the reader.
248
+
249
+
250
+
251
+### func (\*Writer) Flush
252
+``` go
253
+func (w *Writer) Flush() error
254
+```
255
+Flush flushes any buffered bytes
256
+to the underlying writer.
257
+
258
+
259
+
260
+### func (\*Writer) Next
261
+``` go
262
+func (w *Writer) Next(n int) ([]byte, error)
263
+```
264
+Next returns the next 'n' free bytes
265
+in the write buffer, flushing the writer
266
+as necessary. Next will return `io.ErrShortBuffer`
267
+if 'n' is greater than the size of the write buffer.
268
+
269
+
270
+
271
+### func (\*Writer) ReadFrom
272
+``` go
273
+func (w *Writer) ReadFrom(r io.Reader) (int64, error)
274
+```
275
+ReadFrom implements `io.ReaderFrom`
276
+
277
+
278
+
279
+### func (\*Writer) Write
280
+``` go
281
+func (w *Writer) Write(p []byte) (int, error)
282
+```
283
+Write implements `io.Writer`
284
+
285
+
286
+
287
+### func (\*Writer) WriteByte
288
+``` go
289
+func (w *Writer) WriteByte(b byte) error
290
+```
291
+WriteByte implements `io.ByteWriter`
292
+
293
+
294
+
295
+### func (\*Writer) WriteString
296
+``` go
297
+func (w *Writer) WriteString(s string) (int, error)
298
+```
299
+WriteString is analagous to Write, but it takes a string.
300
+
301
+
302
+
303
+
304
+
305
+
306
+
307
+
308
+
309
+- - -
310
+Generated by [godoc2md](http://godoc.org/github.com/davecheney/godoc2md)
0 311
\ No newline at end of file
1 312
new file mode 100644
... ...
@@ -0,0 +1,358 @@
0
+// The `fwd` package provides a buffered reader
1
+// and writer. Each has methods that help improve
2
+// the encoding/decoding performance of some binary
3
+// protocols.
4
+//
5
+// The `fwd.Writer` and `fwd.Reader` type provide similar
6
+// functionality to their counterparts in `bufio`, plus
7
+// a few extra utility methods that simplify read-ahead
8
+// and write-ahead. I wrote this package to improve serialization
9
+// performance for http://github.com/tinylib/msgp,
10
+// where it provided about a 2x speedup over `bufio` for certain
11
+// workloads. However, care must be taken to understand the semantics of the
12
+// extra methods provided by this package, as they allow
13
+// the user to access and manipulate the buffer memory
14
+// directly.
15
+//
16
+// The extra methods for `fwd.Reader` are `Peek`, `Skip`
17
+// and `Next`. `(*fwd.Reader).Peek`, unlike `(*bufio.Reader).Peek`,
18
+// will re-allocate the read buffer in order to accommodate arbitrarily
19
+// large read-ahead. `(*fwd.Reader).Skip` skips the next `n` bytes
20
+// in the stream, and uses the `io.Seeker` interface if the underlying
21
+// stream implements it. `(*fwd.Reader).Next` returns a slice pointing
22
+// to the next `n` bytes in the read buffer (like `Peek`), but also
23
+// increments the read position. This allows users to process streams
24
+// in aribtrary block sizes without having to manage appropriately-sized
25
+// slices. Additionally, obviating the need to copy the data from the
26
+// buffer to another location in memory can improve performance dramatically
27
+// in CPU-bound applications.
28
+//
29
+// `fwd.Writer` only has one extra method, which is `(*fwd.Writer).Next`, which
30
+// returns a slice pointing to the next `n` bytes of the writer, and increments
31
+// the write position by the length of the returned slice. This allows users
32
+// to write directly to the end of the buffer.
33
+//
34
+package fwd
35
+
36
+import "io"
37
+
38
+const (
39
+	// DefaultReaderSize is the default size of the read buffer
40
+	DefaultReaderSize = 2048
41
+
42
+	// minimum read buffer; straight from bufio
43
+	minReaderSize = 16
44
+)
45
+
46
+// NewReader returns a new *Reader that reads from 'r'
47
+func NewReader(r io.Reader) *Reader {
48
+	return NewReaderSize(r, DefaultReaderSize)
49
+}
50
+
51
+// NewReaderSize returns a new *Reader that
52
+// reads from 'r' and has a buffer size 'n'
53
+func NewReaderSize(r io.Reader, n int) *Reader {
54
+	rd := &Reader{
55
+		r:    r,
56
+		data: make([]byte, 0, max(minReaderSize, n)),
57
+	}
58
+	if s, ok := r.(io.Seeker); ok {
59
+		rd.rs = s
60
+	}
61
+	return rd
62
+}
63
+
64
+// Reader is a buffered look-ahead reader
65
+type Reader struct {
66
+	r io.Reader // underlying reader
67
+
68
+	// data[n:len(data)] is buffered data; data[len(data):cap(data)] is free buffer space
69
+	data  []byte // data
70
+	n     int    // read offset
71
+	state error  // last read error
72
+
73
+	// if the reader past to NewReader was
74
+	// also an io.Seeker, this is non-nil
75
+	rs io.Seeker
76
+}
77
+
78
+// Reset resets the underlying reader
79
+// and the read buffer.
80
+func (r *Reader) Reset(rd io.Reader) {
81
+	r.r = rd
82
+	r.data = r.data[0:0]
83
+	r.n = 0
84
+	r.state = nil
85
+	if s, ok := rd.(io.Seeker); ok {
86
+		r.rs = s
87
+	} else {
88
+		r.rs = nil
89
+	}
90
+}
91
+
92
+// more() does one read on the underlying reader
93
+func (r *Reader) more() {
94
+	// move data backwards so that
95
+	// the read offset is 0; this way
96
+	// we can supply the maximum number of
97
+	// bytes to the reader
98
+	if r.n != 0 {
99
+		r.data = r.data[:copy(r.data[0:], r.data[r.n:])]
100
+		r.n = 0
101
+	}
102
+	var a int
103
+	a, r.state = r.r.Read(r.data[len(r.data):cap(r.data)])
104
+	if a == 0 && r.state == nil {
105
+		r.state = io.ErrNoProgress
106
+		return
107
+	}
108
+	r.data = r.data[:len(r.data)+a]
109
+}
110
+
111
+// pop error
112
+func (r *Reader) err() (e error) {
113
+	e, r.state = r.state, nil
114
+	return
115
+}
116
+
117
+// pop error; EOF -> io.ErrUnexpectedEOF
118
+func (r *Reader) noEOF() (e error) {
119
+	e, r.state = r.state, nil
120
+	if e == io.EOF {
121
+		e = io.ErrUnexpectedEOF
122
+	}
123
+	return
124
+}
125
+
126
+// buffered bytes
127
+func (r *Reader) buffered() int { return len(r.data) - r.n }
128
+
129
+// Buffered returns the number of bytes currently in the buffer
130
+func (r *Reader) Buffered() int { return len(r.data) - r.n }
131
+
132
+// BufferSize returns the total size of the buffer
133
+func (r *Reader) BufferSize() int { return cap(r.data) }
134
+
135
+// Peek returns the next 'n' buffered bytes,
136
+// reading from the underlying reader if necessary.
137
+// It will only return a slice shorter than 'n' bytes
138
+// if it also returns an error. Peek does not advance
139
+// the reader. EOF errors are *not* returned as
140
+// io.ErrUnexpectedEOF.
141
+func (r *Reader) Peek(n int) ([]byte, error) {
142
+	// in the degenerate case,
143
+	// we may need to realloc
144
+	// (the caller asked for more
145
+	// bytes than the size of the buffer)
146
+	if cap(r.data) < n {
147
+		old := r.data[r.n:]
148
+		r.data = make([]byte, n+r.buffered())
149
+		r.data = r.data[:copy(r.data, old)]
150
+	}
151
+
152
+	// keep filling until
153
+	// we hit an error or
154
+	// read enough bytes
155
+	for r.buffered() < n && r.state == nil {
156
+		r.more()
157
+	}
158
+
159
+	// we must have hit an error
160
+	if r.buffered() < n {
161
+		return r.data[r.n:], r.err()
162
+	}
163
+
164
+	return r.data[r.n : r.n+n], nil
165
+}
166
+
167
+// Skip moves the reader forward 'n' bytes.
168
+// Returns the number of bytes skipped and any
169
+// errors encountered. It is analagous to Seek(n, 1).
170
+// If the underlying reader implements io.Seeker, then
171
+// that method will be used to skip forward.
172
+//
173
+// If the reader encounters
174
+// an EOF before skipping 'n' bytes, it
175
+// returns io.ErrUnexpectedEOF. If the
176
+// underlying reader implements io.Seeker, then
177
+// those rules apply instead. (Many implementations
178
+// will not return `io.EOF` until the next call
179
+// to Read.)
180
+func (r *Reader) Skip(n int) (int, error) {
181
+
182
+	// fast path
183
+	if r.buffered() >= n {
184
+		r.n += n
185
+		return n, nil
186
+	}
187
+
188
+	// use seeker implementation
189
+	// if we can
190
+	if r.rs != nil {
191
+		return r.skipSeek(n)
192
+	}
193
+
194
+	// loop on filling
195
+	// and then erasing
196
+	o := n
197
+	for r.buffered() < n && r.state == nil {
198
+		r.more()
199
+		// we can skip forward
200
+		// up to r.buffered() bytes
201
+		step := min(r.buffered(), n)
202
+		r.n += step
203
+		n -= step
204
+	}
205
+	// at this point, n should be
206
+	// 0 if everything went smoothly
207
+	return o - n, r.noEOF()
208
+}
209
+
210
+// Next returns the next 'n' bytes in the stream.
211
+// Unlike Peek, Next advances the reader position.
212
+// The returned bytes point to the same
213
+// data as the buffer, so the slice is
214
+// only valid until the next reader method call.
215
+// An EOF is considered an unexpected error.
216
+// If an the returned slice is less than the
217
+// length asked for, an error will be returned,
218
+// and the reader position will not be incremented.
219
+func (r *Reader) Next(n int) ([]byte, error) {
220
+
221
+	// in case the buffer is too small
222
+	if cap(r.data) < n {
223
+		old := r.data[r.n:]
224
+		r.data = make([]byte, n+r.buffered())
225
+		r.data = r.data[:copy(r.data, old)]
226
+	}
227
+
228
+	// fill at least 'n' bytes
229
+	for r.buffered() < n && r.state == nil {
230
+		r.more()
231
+	}
232
+
233
+	if r.buffered() < n {
234
+		return r.data[r.n:], r.noEOF()
235
+	}
236
+	out := r.data[r.n : r.n+n]
237
+	r.n += n
238
+	return out, nil
239
+}
240
+
241
+// skipSeek uses the io.Seeker to seek forward.
242
+// only call this function when n > r.buffered()
243
+func (r *Reader) skipSeek(n int) (int, error) {
244
+	o := r.buffered()
245
+	// first, clear buffer
246
+	n -= o
247
+	r.n = 0
248
+	r.data = r.data[:0]
249
+
250
+	// then seek forward remaning bytes
251
+	i, err := r.rs.Seek(int64(n), 1)
252
+	return int(i) + o, err
253
+}
254
+
255
+// Read implements `io.Reader`
256
+func (r *Reader) Read(b []byte) (int, error) {
257
+	if len(b) <= r.buffered() {
258
+		x := copy(b, r.data[r.n:])
259
+		r.n += x
260
+		return x, nil
261
+	}
262
+	r.more()
263
+	if r.buffered() > 0 {
264
+		x := copy(b, r.data[r.n:])
265
+		r.n += x
266
+		return x, nil
267
+	}
268
+
269
+	// io.Reader is supposed to return
270
+	// 0 read bytes on error
271
+	return 0, r.err()
272
+}
273
+
274
+// ReadFull attempts to read len(b) bytes into
275
+// 'b'. It returns the number of bytes read into
276
+// 'b', and an error if it does not return len(b).
277
+// EOF is considered an unexpected error.
278
+func (r *Reader) ReadFull(b []byte) (int, error) {
279
+	var x int
280
+	l := len(b)
281
+	for x < l {
282
+		if r.buffered() == 0 {
283
+			r.more()
284
+		}
285
+		c := copy(b[x:], r.data[r.n:])
286
+		x += c
287
+		r.n += c
288
+		if r.state != nil {
289
+			return x, r.noEOF()
290
+		}
291
+	}
292
+	return x, nil
293
+}
294
+
295
+// ReadByte implements `io.ByteReader`
296
+func (r *Reader) ReadByte() (byte, error) {
297
+	for r.buffered() < 1 && r.state == nil {
298
+		r.more()
299
+	}
300
+	if r.buffered() < 1 {
301
+		return 0, r.err()
302
+	}
303
+	b := r.data[r.n]
304
+	r.n++
305
+	return b, nil
306
+}
307
+
308
+// WriteTo implements `io.WriterTo`
309
+func (r *Reader) WriteTo(w io.Writer) (int64, error) {
310
+	var (
311
+		i   int64
312
+		ii  int
313
+		err error
314
+	)
315
+	// first, clear buffer
316
+	if r.buffered() > 0 {
317
+		ii, err = w.Write(r.data[r.n:])
318
+		i += int64(ii)
319
+		if err != nil {
320
+			return i, err
321
+		}
322
+		r.data = r.data[0:0]
323
+		r.n = 0
324
+	}
325
+	for r.state == nil {
326
+		// here we just do
327
+		// 1:1 reads and writes
328
+		r.more()
329
+		if r.buffered() > 0 {
330
+			ii, err = w.Write(r.data)
331
+			i += int64(ii)
332
+			if err != nil {
333
+				return i, err
334
+			}
335
+			r.data = r.data[0:0]
336
+			r.n = 0
337
+		}
338
+	}
339
+	if r.state != io.EOF {
340
+		return i, r.err()
341
+	}
342
+	return i, nil
343
+}
344
+
345
+func min(a int, b int) int {
346
+	if a < b {
347
+		return a
348
+	}
349
+	return b
350
+}
351
+
352
+func max(a int, b int) int {
353
+	if a < b {
354
+		return b
355
+	}
356
+	return a
357
+}
0 358
new file mode 100644
... ...
@@ -0,0 +1,224 @@
0
+package fwd
1
+
2
+import "io"
3
+
4
+const (
5
+	// DefaultWriterSize is the
6
+	// default write buffer size.
7
+	DefaultWriterSize = 2048
8
+
9
+	minWriterSize = minReaderSize
10
+)
11
+
12
+// Writer is a buffered writer
13
+type Writer struct {
14
+	w   io.Writer // writer
15
+	buf []byte    // 0:len(buf) is bufered data
16
+}
17
+
18
+// NewWriter returns a new writer
19
+// that writes to 'w' and has a buffer
20
+// that is `DefaultWriterSize` bytes.
21
+func NewWriter(w io.Writer) *Writer {
22
+	if wr, ok := w.(*Writer); ok {
23
+		return wr
24
+	}
25
+	return &Writer{
26
+		w:   w,
27
+		buf: make([]byte, 0, DefaultWriterSize),
28
+	}
29
+}
30
+
31
+// NewWriterSize returns a new writer
32
+// that writes to 'w' and has a buffer
33
+// that is 'size' bytes.
34
+func NewWriterSize(w io.Writer, size int) *Writer {
35
+	if wr, ok := w.(*Writer); ok && cap(wr.buf) >= size {
36
+		return wr
37
+	}
38
+	return &Writer{
39
+		w:   w,
40
+		buf: make([]byte, 0, max(size, minWriterSize)),
41
+	}
42
+}
43
+
44
+// Buffered returns the number of buffered bytes
45
+// in the reader.
46
+func (w *Writer) Buffered() int { return len(w.buf) }
47
+
48
+// BufferSize returns the maximum size of the buffer.
49
+func (w *Writer) BufferSize() int { return cap(w.buf) }
50
+
51
+// Flush flushes any buffered bytes
52
+// to the underlying writer.
53
+func (w *Writer) Flush() error {
54
+	l := len(w.buf)
55
+	if l > 0 {
56
+		n, err := w.w.Write(w.buf)
57
+
58
+		// if we didn't write the whole
59
+		// thing, copy the unwritten
60
+		// bytes to the beginnning of the
61
+		// buffer.
62
+		if n < l && n > 0 {
63
+			w.pushback(n)
64
+			if err == nil {
65
+				err = io.ErrShortWrite
66
+			}
67
+		}
68
+		if err != nil {
69
+			return err
70
+		}
71
+		w.buf = w.buf[:0]
72
+		return nil
73
+	}
74
+	return nil
75
+}
76
+
77
+// Write implements `io.Writer`
78
+func (w *Writer) Write(p []byte) (int, error) {
79
+	c, l, ln := cap(w.buf), len(w.buf), len(p)
80
+	avail := c - l
81
+
82
+	// requires flush
83
+	if avail < ln {
84
+		if err := w.Flush(); err != nil {
85
+			return 0, err
86
+		}
87
+		l = len(w.buf)
88
+	}
89
+	// too big to fit in buffer;
90
+	// write directly to w.w
91
+	if c < ln {
92
+		return w.w.Write(p)
93
+	}
94
+
95
+	// grow buf slice; copy; return
96
+	w.buf = w.buf[:l+ln]
97
+	return copy(w.buf[l:], p), nil
98
+}
99
+
100
+// WriteString is analagous to Write, but it takes a string.
101
+func (w *Writer) WriteString(s string) (int, error) {
102
+	c, l, ln := cap(w.buf), len(w.buf), len(s)
103
+	avail := c - l
104
+
105
+	// requires flush
106
+	if avail < ln {
107
+		if err := w.Flush(); err != nil {
108
+			return 0, err
109
+		}
110
+		l = len(w.buf)
111
+	}
112
+	// too big to fit in buffer;
113
+	// write directly to w.w
114
+	//
115
+	// yes, this is unsafe. *but*
116
+	// io.Writer is not allowed
117
+	// to mutate its input or
118
+	// maintain a reference to it,
119
+	// per the spec in package io.
120
+	//
121
+	// plus, if the string is really
122
+	// too big to fit in the buffer, then
123
+	// creating a copy to write it is
124
+	// expensive (and, strictly speaking,
125
+	// unnecessary)
126
+	if c < ln {
127
+		return w.w.Write(unsafestr(s))
128
+	}
129
+
130
+	// grow buf slice; copy; return
131
+	w.buf = w.buf[:l+ln]
132
+	return copy(w.buf[l:], s), nil
133
+}
134
+
135
+// WriteByte implements `io.ByteWriter`
136
+func (w *Writer) WriteByte(b byte) error {
137
+	if len(w.buf) == cap(w.buf) {
138
+		if err := w.Flush(); err != nil {
139
+			return err
140
+		}
141
+	}
142
+	w.buf = append(w.buf, b)
143
+	return nil
144
+}
145
+
146
+// Next returns the next 'n' free bytes
147
+// in the write buffer, flushing the writer
148
+// as necessary. Next will return `io.ErrShortBuffer`
149
+// if 'n' is greater than the size of the write buffer.
150
+// Calls to 'next' increment the write position by
151
+// the size of the returned buffer.
152
+func (w *Writer) Next(n int) ([]byte, error) {
153
+	c, l := cap(w.buf), len(w.buf)
154
+	if n > c {
155
+		return nil, io.ErrShortBuffer
156
+	}
157
+	avail := c - l
158
+	if avail < n {
159
+		if err := w.Flush(); err != nil {
160
+			return nil, err
161
+		}
162
+		l = len(w.buf)
163
+	}
164
+	w.buf = w.buf[:l+n]
165
+	return w.buf[l:], nil
166
+}
167
+
168
+// take the bytes from w.buf[n:len(w.buf)]
169
+// and put them at the beginning of w.buf,
170
+// and resize to the length of the copied segment.
171
+func (w *Writer) pushback(n int) {
172
+	w.buf = w.buf[:copy(w.buf, w.buf[n:])]
173
+}
174
+
175
+// ReadFrom implements `io.ReaderFrom`
176
+func (w *Writer) ReadFrom(r io.Reader) (int64, error) {
177
+	// anticipatory flush
178
+	if err := w.Flush(); err != nil {
179
+		return 0, err
180
+	}
181
+
182
+	w.buf = w.buf[0:cap(w.buf)] // expand buffer
183
+
184
+	var nn int64  // written
185
+	var err error // error
186
+	var x int     // read
187
+
188
+	// 1:1 reads and writes
189
+	for err == nil {
190
+		x, err = r.Read(w.buf)
191
+		if x > 0 {
192
+			n, werr := w.w.Write(w.buf[:x])
193
+			nn += int64(n)
194
+
195
+			if err != nil {
196
+				if n < x && n > 0 {
197
+					w.pushback(n - x)
198
+				}
199
+				return nn, werr
200
+			}
201
+			if n < x {
202
+				w.pushback(n - x)
203
+				return nn, io.ErrShortWrite
204
+			}
205
+		} else if err == nil {
206
+			err = io.ErrNoProgress
207
+			break
208
+		}
209
+	}
210
+	if err != io.EOF {
211
+		return nn, err
212
+	}
213
+
214
+	// we only clear here
215
+	// because we are sure
216
+	// the writes have
217
+	// suceeded. otherwise,
218
+	// we retain the data in case
219
+	// future writes succeed.
220
+	w.buf = w.buf[0:0]
221
+
222
+	return nn, nil
223
+}
0 224
new file mode 100644
... ...
@@ -0,0 +1,5 @@
0
+// +build appengine
1
+
2
+package fwd
3
+
4
+func unsafestr(s string) []byte { return []byte(s) }
0 5
new file mode 100644
... ...
@@ -0,0 +1,18 @@
0
+// +build !appengine
1
+
2
+package fwd
3
+
4
+import (
5
+	"reflect"
6
+	"unsafe"
7
+)
8
+
9
+// unsafe cast string as []byte
10
+func unsafestr(b string) []byte {
11
+	l := len(b)
12
+	return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
13
+		Len:  l,
14
+		Cap:  l,
15
+		Data: (*reflect.StringHeader)(unsafe.Pointer(&b)).Data,
16
+	}))
17
+}
0 18
new file mode 100644
... ...
@@ -0,0 +1,38 @@
0
+package msgp
1
+
2
+import (
3
+	"testing"
4
+)
5
+
6
+// EndlessReader is an io.Reader
7
+// that loops over the same data
8
+// endlessly. It is used for benchmarking.
9
+type EndlessReader struct {
10
+	tb     *testing.B
11
+	data   []byte
12
+	offset int
13
+}
14
+
15
+// NewEndlessReader returns a new endless reader
16
+func NewEndlessReader(b []byte, tb *testing.B) *EndlessReader {
17
+	return &EndlessReader{tb: tb, data: b, offset: 0}
18
+}
19
+
20
+// Read implements io.Reader. In practice, it
21
+// always returns (len(p), nil), although it
22
+// fills the supplied slice while the benchmark
23
+// timer is stopped.
24
+func (c *EndlessReader) Read(p []byte) (int, error) {
25
+	c.tb.StopTimer()
26
+	var n int
27
+	l := len(p)
28
+	m := len(c.data)
29
+	for n < l {
30
+		nn := copy(p[n:], c.data[c.offset:])
31
+		n += nn
32
+		c.offset += nn
33
+		c.offset %= m
34
+	}
35
+	c.tb.StartTimer()
36
+	return n, nil
37
+}
0 38
new file mode 100644
... ...
@@ -0,0 +1,142 @@
0
+// This package is the support library for the msgp code generator (http://github.com/tinylib/msgp).
1
+//
2
+// This package defines the utilites used by the msgp code generator for encoding and decoding MessagePack
3
+// from []byte and io.Reader/io.Writer types. Much of this package is devoted to helping the msgp code
4
+// generator implement the Marshaler/Unmarshaler and Encodable/Decodable interfaces.
5
+//
6
+// This package defines four "families" of functions:
7
+// 	- AppendXxxx() appends an object to a []byte in MessagePack encoding.
8
+// 	- ReadXxxxBytes() reads an object from a []byte and returns the remaining bytes.
9
+// 	- (*Writer).WriteXxxx() writes an object to the buffered *Writer type.
10
+// 	- (*Reader).ReadXxxx() reads an object from a buffered *Reader type.
11
+//
12
+// Once a type has satisfied the `Encodable` and `Decodable` interfaces,
13
+// it can be written and read from arbitrary `io.Writer`s and `io.Reader`s using
14
+// 		msgp.Encode(io.Writer, msgp.Encodable)
15
+// and
16
+//		msgp.Decode(io.Reader, msgp.Decodable)
17
+//
18
+// There are also methods for converting MessagePack to JSON without
19
+// an explicit de-serialization step.
20
+//
21
+// For additional tips, tricks, and gotchas, please visit
22
+// the wiki at http://github.com/tinylib/msgp
23
+package msgp
24
+
25
+const last4 = 0x0f
26
+const first4 = 0xf0
27
+const last5 = 0x1f
28
+const first3 = 0xe0
29
+const last7 = 0x7f
30
+
31
+func isfixint(b byte) bool {
32
+	return b>>7 == 0
33
+}
34
+
35
+func isnfixint(b byte) bool {
36
+	return b&first3 == mnfixint
37
+}
38
+
39
+func isfixmap(b byte) bool {
40
+	return b&first4 == mfixmap
41
+}
42
+
43
+func isfixarray(b byte) bool {
44
+	return b&first4 == mfixarray
45
+}
46
+
47
+func isfixstr(b byte) bool {
48
+	return b&first3 == mfixstr
49
+}
50
+
51
+func wfixint(u uint8) byte {
52
+	return u & last7
53
+}
54
+
55
+func rfixint(b byte) uint8 {
56
+	return b
57
+}
58
+
59
+func wnfixint(i int8) byte {
60
+	return byte(i) | mnfixint
61
+}
62
+
63
+func rnfixint(b byte) int8 {
64
+	return int8(b)
65
+}
66
+
67
+func rfixmap(b byte) uint8 {
68
+	return b & last4
69
+}
70
+
71
+func wfixmap(u uint8) byte {
72
+	return mfixmap | (u & last4)
73
+}
74
+
75
+func rfixstr(b byte) uint8 {
76
+	return b & last5
77
+}
78
+
79
+func wfixstr(u uint8) byte {
80
+	return (u & last5) | mfixstr
81
+}
82
+
83
+func rfixarray(b byte) uint8 {
84
+	return (b & last4)
85
+}
86
+
87
+func wfixarray(u uint8) byte {
88
+	return (u & last4) | mfixarray
89
+}
90
+
91
+// These are all the byte
92
+// prefixes defined by the
93
+// msgpack standard
94
+const (
95
+	// 0XXXXXXX
96
+	mfixint uint8 = 0x00
97
+
98
+	// 111XXXXX
99
+	mnfixint uint8 = 0xe0
100
+
101
+	// 1000XXXX
102
+	mfixmap uint8 = 0x80
103
+
104
+	// 1001XXXX
105
+	mfixarray uint8 = 0x90
106
+
107
+	// 101XXXXX
108
+	mfixstr uint8 = 0xa0
109
+
110
+	mnil      uint8 = 0xc0
111
+	mfalse    uint8 = 0xc2
112
+	mtrue     uint8 = 0xc3
113
+	mbin8     uint8 = 0xc4
114
+	mbin16    uint8 = 0xc5
115
+	mbin32    uint8 = 0xc6
116
+	mext8     uint8 = 0xc7
117
+	mext16    uint8 = 0xc8
118
+	mext32    uint8 = 0xc9
119
+	mfloat32  uint8 = 0xca
120
+	mfloat64  uint8 = 0xcb
121
+	muint8    uint8 = 0xcc
122
+	muint16   uint8 = 0xcd
123
+	muint32   uint8 = 0xce
124
+	muint64   uint8 = 0xcf
125
+	mint8     uint8 = 0xd0
126
+	mint16    uint8 = 0xd1
127
+	mint32    uint8 = 0xd2
128
+	mint64    uint8 = 0xd3
129
+	mfixext1  uint8 = 0xd4
130
+	mfixext2  uint8 = 0xd5
131
+	mfixext4  uint8 = 0xd6
132
+	mfixext8  uint8 = 0xd7
133
+	mfixext16 uint8 = 0xd8
134
+	mstr8     uint8 = 0xd9
135
+	mstr16    uint8 = 0xda
136
+	mstr32    uint8 = 0xdb
137
+	marray16  uint8 = 0xdc
138
+	marray32  uint8 = 0xdd
139
+	mmap16    uint8 = 0xde
140
+	mmap32    uint8 = 0xdf
141
+)
0 142
new file mode 100644
... ...
@@ -0,0 +1,241 @@
0
+package msgp
1
+
2
+import (
3
+	"math"
4
+)
5
+
6
+// Locate returns a []byte pointing to the field
7
+// in a messagepack map with the provided key. (The returned []byte
8
+// points to a sub-slice of 'raw'; Locate does no allocations.) If the
9
+// key doesn't exist in the map, a zero-length []byte will be returned.
10
+func Locate(key string, raw []byte) []byte {
11
+	s, n := locate(raw, key)
12
+	return raw[s:n]
13
+}
14
+
15
+// Replace takes a key ("key") in a messagepack map ("raw")
16
+// and replaces its value with the one provided and returns
17
+// the new []byte. The returned []byte may point to the same
18
+// memory as "raw". Replace makes no effort to evaluate the validity
19
+// of the contents of 'val'. It may use up to the full capacity of 'raw.'
20
+// Replace returns 'nil' if the field doesn't exist or if the object in 'raw'
21
+// is not a map.
22
+func Replace(key string, raw []byte, val []byte) []byte {
23
+	start, end := locate(raw, key)
24
+	if start == end {
25
+		return nil
26
+	}
27
+	return replace(raw, start, end, val, true)
28
+}
29
+
30
+// CopyReplace works similarly to Replace except that the returned
31
+// byte slice does not point to the same memory as 'raw'. CopyReplace
32
+// returns 'nil' if the field doesn't exist or 'raw' isn't a map.
33
+func CopyReplace(key string, raw []byte, val []byte) []byte {
34
+	start, end := locate(raw, key)
35
+	if start == end {
36
+		return nil
37
+	}
38
+	return replace(raw, start, end, val, false)
39
+}
40
+
41
+// Remove removes a key-value pair from 'raw'. It returns
42
+// 'raw' unchanged if the key didn't exist.
43
+func Remove(key string, raw []byte) []byte {
44
+	start, end := locateKV(raw, key)
45
+	if start == end {
46
+		return raw
47
+	}
48
+	raw = raw[:start+copy(raw[start:], raw[end:])]
49
+	return resizeMap(raw, -1)
50
+}
51
+
52
+// HasKey returns whether the map in 'raw' has
53
+// a field with key 'key'
54
+func HasKey(key string, raw []byte) bool {
55
+	sz, bts, err := ReadMapHeaderBytes(raw)
56
+	if err != nil {
57
+		return false
58
+	}
59
+	var field []byte
60
+	for i := uint32(0); i < sz; i++ {
61
+		field, bts, err = ReadStringZC(bts)
62
+		if err != nil {
63
+			return false
64
+		}
65
+		if UnsafeString(field) == key {
66
+			return true
67
+		}
68
+	}
69
+	return false
70
+}
71
+
72
+func replace(raw []byte, start int, end int, val []byte, inplace bool) []byte {
73
+	ll := end - start // length of segment to replace
74
+	lv := len(val)
75
+
76
+	if inplace {
77
+		extra := lv - ll
78
+
79
+		// fastest case: we're doing
80
+		// a 1:1 replacement
81
+		if extra == 0 {
82
+			copy(raw[start:], val)
83
+			return raw
84
+
85
+		} else if extra < 0 {
86
+			// 'val' smaller than replaced value
87
+			// copy in place and shift back
88
+
89
+			x := copy(raw[start:], val)
90
+			y := copy(raw[start+x:], raw[end:])
91
+			return raw[:start+x+y]
92
+
93
+		} else if extra < cap(raw)-len(raw) {
94
+			// 'val' less than (cap-len) extra bytes
95
+			// copy in place and shift forward
96
+			raw = raw[0 : len(raw)+extra]
97
+			// shift end forward
98
+			copy(raw[end+extra:], raw[end:])
99
+			copy(raw[start:], val)
100
+			return raw
101
+		}
102
+	}
103
+
104
+	// we have to allocate new space
105
+	out := make([]byte, len(raw)+len(val)-ll)
106
+	x := copy(out, raw[:start])
107
+	y := copy(out[x:], val)
108
+	copy(out[x+y:], raw[end:])
109
+	return out
110
+}
111
+
112
+// locate does a naive O(n) search for the map key; returns start, end
113
+// (returns 0,0 on error)
114
+func locate(raw []byte, key string) (start int, end int) {
115
+	var (
116
+		sz    uint32
117
+		bts   []byte
118
+		field []byte
119
+		err   error
120
+	)
121
+	sz, bts, err = ReadMapHeaderBytes(raw)
122
+	if err != nil {
123
+		return
124
+	}
125
+
126
+	// loop and locate field
127
+	for i := uint32(0); i < sz; i++ {
128
+		field, bts, err = ReadStringZC(bts)
129
+		if err != nil {
130
+			return 0, 0
131
+		}
132
+		if UnsafeString(field) == key {
133
+			// start location
134
+			l := len(raw)
135
+			start = l - len(bts)
136
+			bts, err = Skip(bts)
137
+			if err != nil {
138
+				return 0, 0
139
+			}
140
+			end = l - len(bts)
141
+			return
142
+		}
143
+		bts, err = Skip(bts)
144
+		if err != nil {
145
+			return 0, 0
146
+		}
147
+	}
148
+	return 0, 0
149
+}
150
+
151
+// locate key AND value
152
+func locateKV(raw []byte, key string) (start int, end int) {
153
+	var (
154
+		sz    uint32
155
+		bts   []byte
156
+		field []byte
157
+		err   error
158
+	)
159
+	sz, bts, err = ReadMapHeaderBytes(raw)
160
+	if err != nil {
161
+		return 0, 0
162
+	}
163
+
164
+	for i := uint32(0); i < sz; i++ {
165
+		tmp := len(bts)
166
+		field, bts, err = ReadStringZC(bts)
167
+		if err != nil {
168
+			return 0, 0
169
+		}
170
+		if UnsafeString(field) == key {
171
+			start = len(raw) - tmp
172
+			bts, err = Skip(bts)
173
+			if err != nil {
174
+				return 0, 0
175
+			}
176
+			end = len(raw) - len(bts)
177
+			return
178
+		}
179
+		bts, err = Skip(bts)
180
+		if err != nil {
181
+			return 0, 0
182
+		}
183
+	}
184
+	return 0, 0
185
+}
186
+
187
+// delta is delta on map size
188
+func resizeMap(raw []byte, delta int64) []byte {
189
+	var sz int64
190
+	switch raw[0] {
191
+	case mmap16:
192
+		sz = int64(big.Uint16(raw[1:]))
193
+		if sz+delta <= math.MaxUint16 {
194
+			big.PutUint16(raw[1:], uint16(sz+delta))
195
+			return raw
196
+		}
197
+		if cap(raw)-len(raw) >= 2 {
198
+			raw = raw[0 : len(raw)+2]
199
+			copy(raw[5:], raw[3:])
200
+			big.PutUint32(raw[1:], uint32(sz+delta))
201
+			return raw
202
+		}
203
+		n := make([]byte, 0, len(raw)+5)
204
+		n = AppendMapHeader(n, uint32(sz+delta))
205
+		return append(n, raw[3:]...)
206
+
207
+	case mmap32:
208
+		sz = int64(big.Uint32(raw[1:]))
209
+		big.PutUint32(raw[1:], uint32(sz+delta))
210
+		return raw
211
+
212
+	default:
213
+		sz = int64(rfixmap(raw[0]))
214
+		if sz+delta < 16 {
215
+			raw[0] = wfixmap(uint8(sz + delta))
216
+			return raw
217
+		} else if sz+delta <= math.MaxUint16 {
218
+			if cap(raw)-len(raw) >= 2 {
219
+				raw = raw[0 : len(raw)+2]
220
+				copy(raw[3:], raw[1:])
221
+				raw[0] = mmap16
222
+				big.PutUint16(raw[1:], uint16(sz+delta))
223
+				return raw
224
+			}
225
+			n := make([]byte, 0, len(raw)+5)
226
+			n = AppendMapHeader(n, uint32(sz+delta))
227
+			return append(n, raw[1:]...)
228
+		}
229
+		if cap(raw)-len(raw) >= 4 {
230
+			raw = raw[0 : len(raw)+4]
231
+			copy(raw[5:], raw[1:])
232
+			raw[0] = mmap32
233
+			big.PutUint32(raw[1:], uint32(sz+delta))
234
+			return raw
235
+		}
236
+		n := make([]byte, 0, len(raw)+5)
237
+		n = AppendMapHeader(n, uint32(sz+delta))
238
+		return append(n, raw[1:]...)
239
+	}
240
+}
0 241
new file mode 100644
... ...
@@ -0,0 +1,99 @@
0
+package msgp
1
+
2
+// size of every object on the wire,
3
+// plus type information. gives us
4
+// constant-time type information
5
+// for traversing composite objects.
6
+//
7
+var sizes = [256]bytespec{
8
+	mnil:      {size: 1, extra: constsize, typ: NilType},
9
+	mfalse:    {size: 1, extra: constsize, typ: BoolType},
10
+	mtrue:     {size: 1, extra: constsize, typ: BoolType},
11
+	mbin8:     {size: 2, extra: extra8, typ: BinType},
12
+	mbin16:    {size: 3, extra: extra16, typ: BinType},
13
+	mbin32:    {size: 5, extra: extra32, typ: BinType},
14
+	mext8:     {size: 3, extra: extra8, typ: ExtensionType},
15
+	mext16:    {size: 4, extra: extra16, typ: ExtensionType},
16
+	mext32:    {size: 6, extra: extra32, typ: ExtensionType},
17
+	mfloat32:  {size: 5, extra: constsize, typ: Float32Type},
18
+	mfloat64:  {size: 9, extra: constsize, typ: Float64Type},
19
+	muint8:    {size: 2, extra: constsize, typ: UintType},
20
+	muint16:   {size: 3, extra: constsize, typ: UintType},
21
+	muint32:   {size: 5, extra: constsize, typ: UintType},
22
+	muint64:   {size: 9, extra: constsize, typ: UintType},
23
+	mint8:     {size: 2, extra: constsize, typ: IntType},
24
+	mint16:    {size: 3, extra: constsize, typ: IntType},
25
+	mint32:    {size: 5, extra: constsize, typ: IntType},
26
+	mint64:    {size: 9, extra: constsize, typ: IntType},
27
+	mfixext1:  {size: 3, extra: constsize, typ: ExtensionType},
28
+	mfixext2:  {size: 4, extra: constsize, typ: ExtensionType},
29
+	mfixext4:  {size: 6, extra: constsize, typ: ExtensionType},
30
+	mfixext8:  {size: 10, extra: constsize, typ: ExtensionType},
31
+	mfixext16: {size: 18, extra: constsize, typ: ExtensionType},
32
+	mstr8:     {size: 2, extra: extra8, typ: StrType},
33
+	mstr16:    {size: 3, extra: extra16, typ: StrType},
34
+	mstr32:    {size: 5, extra: extra32, typ: StrType},
35
+	marray16:  {size: 3, extra: array16v, typ: ArrayType},
36
+	marray32:  {size: 5, extra: array32v, typ: ArrayType},
37
+	mmap16:    {size: 3, extra: map16v, typ: MapType},
38
+	mmap32:    {size: 5, extra: map32v, typ: MapType},
39
+}
40
+
41
+func init() {
42
+	// set up fixed fields
43
+
44
+	// fixint
45
+	for i := mfixint; i < 0x80; i++ {
46
+		sizes[i] = bytespec{size: 1, extra: constsize, typ: IntType}
47
+	}
48
+
49
+	// nfixint
50
+	for i := uint16(mnfixint); i < 0x100; i++ {
51
+		sizes[uint8(i)] = bytespec{size: 1, extra: constsize, typ: IntType}
52
+	}
53
+
54
+	// fixstr gets constsize,
55
+	// since the prefix yields the size
56
+	for i := mfixstr; i < 0xc0; i++ {
57
+		sizes[i] = bytespec{size: 1 + rfixstr(i), extra: constsize, typ: StrType}
58
+	}
59
+
60
+	// fixmap
61
+	for i := mfixmap; i < 0x90; i++ {
62
+		sizes[i] = bytespec{size: 1, extra: varmode(2 * rfixmap(i)), typ: MapType}
63
+	}
64
+
65
+	// fixarray
66
+	for i := mfixarray; i < 0xa0; i++ {
67
+		sizes[i] = bytespec{size: 1, extra: varmode(rfixarray(i)), typ: ArrayType}
68
+	}
69
+}
70
+
71
+// a valid bytespsec has
72
+// non-zero 'size' and
73
+// non-zero 'typ'
74
+type bytespec struct {
75
+	size  uint8   // prefix size information
76
+	extra varmode // extra size information
77
+	typ   Type    // type
78
+	_     byte    // makes bytespec 4 bytes (yes, this matters)
79
+}
80
+
81
+// size mode
82
+// if positive, # elements for composites
83
+type varmode int8
84
+
85
+const (
86
+	constsize varmode = 0  // constant size (size bytes + uint8(varmode) objects)
87
+	extra8            = -1 // has uint8(p[1]) extra bytes
88
+	extra16           = -2 // has be16(p[1:]) extra bytes
89
+	extra32           = -3 // has be32(p[1:]) extra bytes
90
+	map16v            = -4 // use map16
91
+	map32v            = -5 // use map32
92
+	array16v          = -6 // use array16
93
+	array32v          = -7 // use array32
94
+)
95
+
96
+func getType(v byte) Type {
97
+	return sizes[v].typ
98
+}
0 99
new file mode 100644
... ...
@@ -0,0 +1,142 @@
0
+package msgp
1
+
2
+import (
3
+	"fmt"
4
+	"reflect"
5
+)
6
+
7
+var (
8
+	// ErrShortBytes is returned when the
9
+	// slice being decoded is too short to
10
+	// contain the contents of the message
11
+	ErrShortBytes error = errShort{}
12
+
13
+	// this error is only returned
14
+	// if we reach code that should
15
+	// be unreachable
16
+	fatal error = errFatal{}
17
+)
18
+
19
+// Error is the interface satisfied
20
+// by all of the errors that originate
21
+// from this package.
22
+type Error interface {
23
+	error
24
+
25
+	// Resumable returns whether
26
+	// or not the error means that
27
+	// the stream of data is malformed
28
+	// and  the information is unrecoverable.
29
+	Resumable() bool
30
+}
31
+
32
+type errShort struct{}
33
+
34
+func (e errShort) Error() string   { return "msgp: too few bytes left to read object" }
35
+func (e errShort) Resumable() bool { return false }
36
+
37
+type errFatal struct{}
38
+
39
+func (f errFatal) Error() string   { return "msgp: fatal decoding error (unreachable code)" }
40
+func (f errFatal) Resumable() bool { return false }
41
+
42
+// ArrayError is an error returned
43
+// when decoding a fix-sized array
44
+// of the wrong size
45
+type ArrayError struct {
46
+	Wanted uint32
47
+	Got    uint32
48
+}
49
+
50
+// Error implements the error interface
51
+func (a ArrayError) Error() string {
52
+	return fmt.Sprintf("msgp: wanted array of size %d; got %d", a.Wanted, a.Got)
53
+}
54
+
55
+// Resumable is always 'true' for ArrayErrors
56
+func (a ArrayError) Resumable() bool { return true }
57
+
58
+// IntOverflow is returned when a call
59
+// would downcast an integer to a type
60
+// with too few bits to hold its value.
61
+type IntOverflow struct {
62
+	Value         int64 // the value of the integer
63
+	FailedBitsize int   // the bit size that the int64 could not fit into
64
+}
65
+
66
+// Error implements the error interface
67
+func (i IntOverflow) Error() string {
68
+	return fmt.Sprintf("msgp: %d overflows int%d", i.Value, i.FailedBitsize)
69
+}
70
+
71
+// Resumable is always 'true' for overflows
72
+func (i IntOverflow) Resumable() bool { return true }
73
+
74
+// UintOverflow is returned when a call
75
+// would downcast an unsigned integer to a type
76
+// with too few bits to hold its value
77
+type UintOverflow struct {
78
+	Value         uint64 // value of the uint
79
+	FailedBitsize int    // the bit size that couldn't fit the value
80
+}
81
+
82
+// Error implements the error interface
83
+func (u UintOverflow) Error() string {
84
+	return fmt.Sprintf("msgp: %d overflows uint%d", u.Value, u.FailedBitsize)
85
+}
86
+
87
+// Resumable is always 'true' for overflows
88
+func (u UintOverflow) Resumable() bool { return true }
89
+
90
+// A TypeError is returned when a particular
91
+// decoding method is unsuitable for decoding
92
+// a particular MessagePack value.
93
+type TypeError struct {
94
+	Method  Type // Type expected by method
95
+	Encoded Type // Type actually encoded
96
+}
97
+
98
+// Error implements the error interface
99
+func (t TypeError) Error() string {
100
+	return fmt.Sprintf("msgp: attempted to decode type %q with method for %q", t.Encoded, t.Method)
101
+}
102
+
103
+// Resumable returns 'true' for TypeErrors
104
+func (t TypeError) Resumable() bool { return true }
105
+
106
+// returns either InvalidPrefixError or
107
+// TypeError depending on whether or not
108
+// the prefix is recognized
109
+func badPrefix(want Type, lead byte) error {
110
+	t := sizes[lead].typ
111
+	if t == InvalidType {
112
+		return InvalidPrefixError(lead)
113
+	}
114
+	return TypeError{Method: want, Encoded: t}
115
+}
116
+
117
+// InvalidPrefixError is returned when a bad encoding
118
+// uses a prefix that is not recognized in the MessagePack standard.
119
+// This kind of error is unrecoverable.
120
+type InvalidPrefixError byte
121
+
122
+// Error implements the error interface
123
+func (i InvalidPrefixError) Error() string {
124
+	return fmt.Sprintf("msgp: unrecognized type prefix 0x%x", byte(i))
125
+}
126
+
127
+// Resumable returns 'false' for InvalidPrefixErrors
128
+func (i InvalidPrefixError) Resumable() bool { return false }
129
+
130
+// ErrUnsupportedType is returned
131
+// when a bad argument is supplied
132
+// to a function that takes `interface{}`.
133
+type ErrUnsupportedType struct {
134
+	T reflect.Type
135
+}
136
+
137
+// Error implements error
138
+func (e *ErrUnsupportedType) Error() string { return fmt.Sprintf("msgp: type %q not supported", e.T) }
139
+
140
+// Resumable returns 'true' for ErrUnsupportedType
141
+func (e *ErrUnsupportedType) Resumable() bool { return true }
0 142
new file mode 100644
... ...
@@ -0,0 +1,548 @@
0
+package msgp
1
+
2
+import (
3
+	"fmt"
4
+	"math"
5
+)
6
+
7
+const (
8
+	// Complex64Extension is the extension number used for complex64
9
+	Complex64Extension = 3
10
+
11
+	// Complex128Extension is the extension number used for complex128
12
+	Complex128Extension = 4
13
+
14
+	// TimeExtension is the extension number used for time.Time
15
+	TimeExtension = 5
16
+)
17
+
18
+// our extensions live here
19
+var extensionReg = make(map[int8]func() Extension)
20
+
21
+// RegisterExtension registers extensions so that they
22
+// can be initialized and returned by methods that
23
+// decode `interface{}` values. This should only
24
+// be called during initialization. f() should return
25
+// a newly-initialized zero value of the extension. Keep in
26
+// mind that extensions 3, 4, and 5 are reserved for
27
+// complex64, complex128, and time.Time, respectively,
28
+// and that MessagePack reserves extension types from -127 to -1.
29
+//
30
+// For example, if you wanted to register a user-defined struct:
31
+//
32
+//  msgp.RegisterExtension(10, func() msgp.Extension { &MyExtension{} })
33
+//
34
+// RegisterExtension will panic if you call it multiple times
35
+// with the same 'typ' argument, or if you use a reserved
36
+// type (3, 4, or 5).
37
+func RegisterExtension(typ int8, f func() Extension) {
38
+	switch typ {
39
+	case Complex64Extension, Complex128Extension, TimeExtension:
40
+		panic(fmt.Sprint("msgp: forbidden extension type:", typ))
41
+	}
42
+	if _, ok := extensionReg[typ]; ok {
43
+		panic(fmt.Sprint("msgp: RegisterExtension() called with typ", typ, "more than once"))
44
+	}
45
+	extensionReg[typ] = f
46
+}
47
+
48
+// ExtensionTypeError is an error type returned
49
+// when there is a mis-match between an extension type
50
+// and the type encoded on the wire
51
+type ExtensionTypeError struct {
52
+	Got  int8
53
+	Want int8
54
+}
55
+
56
+// Error implements the error interface
57
+func (e ExtensionTypeError) Error() string {
58
+	return fmt.Sprintf("msgp: error decoding extension: wanted type %d; got type %d", e.Want, e.Got)
59
+}
60
+
61
+// Resumable returns 'true' for ExtensionTypeErrors
62
+func (e ExtensionTypeError) Resumable() bool { return true }
63
+
64
+func errExt(got int8, wanted int8) error {
65
+	return ExtensionTypeError{Got: got, Want: wanted}
66
+}
67
+
68
+// Extension is the interface fulfilled
69
+// by types that want to define their
70
+// own binary encoding.
71
+type Extension interface {
72
+	// ExtensionType should return
73
+	// a int8 that identifies the concrete
74
+	// type of the extension. (Types <0 are
75
+	// officially reserved by the MessagePack
76
+	// specifications.)
77
+	ExtensionType() int8
78
+
79
+	// Len should return the length
80
+	// of the data to be encoded
81
+	Len() int
82
+
83
+	// MarshalBinaryTo should copy
84
+	// the data into the supplied slice,
85
+	// assuming that the slice has length Len()
86
+	MarshalBinaryTo([]byte) error
87
+
88
+	UnmarshalBinary([]byte) error
89
+}
90
+
91
+// RawExtension implements the Extension interface
92
+type RawExtension struct {
93
+	Data []byte
94
+	Type int8
95
+}
96
+
97
+// ExtensionType implements Extension.ExtensionType, and returns r.Type
98
+func (r *RawExtension) ExtensionType() int8 { return r.Type }
99
+
100
+// Len implements Extension.Len, and returns len(r.Data)
101
+func (r *RawExtension) Len() int { return len(r.Data) }
102
+
103
+// MarshalBinaryTo implements Extension.MarshalBinaryTo,
104
+// and returns a copy of r.Data
105
+func (r *RawExtension) MarshalBinaryTo(d []byte) error {
106
+	copy(d, r.Data)
107
+	return nil
108
+}
109
+
110
+// UnmarshalBinary implements Extension.UnmarshalBinary,
111
+// and sets r.Data to the contents of the provided slice
112
+func (r *RawExtension) UnmarshalBinary(b []byte) error {
113
+	if cap(r.Data) >= len(b) {
114
+		r.Data = r.Data[0:len(b)]
115
+	} else {
116
+		r.Data = make([]byte, len(b))
117
+	}
118
+	copy(r.Data, b)
119
+	return nil
120
+}
121
+
122
+// WriteExtension writes an extension type to the writer
123
+func (mw *Writer) WriteExtension(e Extension) error {
124
+	l := e.Len()
125
+	var err error
126
+	switch l {
127
+	case 0:
128
+		o, err := mw.require(3)
129
+		if err != nil {
130
+			return err
131
+		}
132
+		mw.buf[o] = mext8
133
+		mw.buf[o+1] = 0
134
+		mw.buf[o+2] = byte(e.ExtensionType())
135
+	case 1:
136
+		o, err := mw.require(2)
137
+		if err != nil {
138
+			return err
139
+		}
140
+		mw.buf[o] = mfixext1
141
+		mw.buf[o+1] = byte(e.ExtensionType())
142
+	case 2:
143
+		o, err := mw.require(2)
144
+		if err != nil {
145
+			return err
146
+		}
147
+		mw.buf[o] = mfixext2
148
+		mw.buf[o+1] = byte(e.ExtensionType())
149
+	case 4:
150
+		o, err := mw.require(2)
151
+		if err != nil {
152
+			return err
153
+		}
154
+		mw.buf[o] = mfixext4
155
+		mw.buf[o+1] = byte(e.ExtensionType())
156
+	case 8:
157
+		o, err := mw.require(2)
158
+		if err != nil {
159
+			return err
160
+		}
161
+		mw.buf[o] = mfixext8
162
+		mw.buf[o+1] = byte(e.ExtensionType())
163
+	case 16:
164
+		o, err := mw.require(2)
165
+		if err != nil {
166
+			return err
167
+		}
168
+		mw.buf[o] = mfixext16
169
+		mw.buf[o+1] = byte(e.ExtensionType())
170
+	default:
171
+		switch {
172
+		case l < math.MaxUint8:
173
+			o, err := mw.require(3)
174
+			if err != nil {
175
+				return err
176
+			}
177
+			mw.buf[o] = mext8
178
+			mw.buf[o+1] = byte(uint8(l))
179
+			mw.buf[o+2] = byte(e.ExtensionType())
180
+		case l < math.MaxUint16:
181
+			o, err := mw.require(4)
182
+			if err != nil {
183
+				return err
184
+			}
185
+			mw.buf[o] = mext16
186
+			big.PutUint16(mw.buf[o+1:], uint16(l))
187
+			mw.buf[o+3] = byte(e.ExtensionType())
188
+		default:
189
+			o, err := mw.require(6)
190
+			if err != nil {
191
+				return err
192
+			}
193
+			mw.buf[o] = mext32
194
+			big.PutUint32(mw.buf[o+1:], uint32(l))
195
+			mw.buf[o+5] = byte(e.ExtensionType())
196
+		}
197
+	}
198
+	// we can only write directly to the
199
+	// buffer if we're sure that it
200
+	// fits the object
201
+	if l <= mw.bufsize() {
202
+		o, err := mw.require(l)
203
+		if err != nil {
204
+			return err
205
+		}
206
+		return e.MarshalBinaryTo(mw.buf[o:])
207
+	}
208
+	// here we create a new buffer
209
+	// just large enough for the body
210
+	// and save it as the write buffer
211
+	err = mw.flush()
212
+	if err != nil {
213
+		return err
214
+	}
215
+	buf := make([]byte, l)
216
+	err = e.MarshalBinaryTo(buf)
217
+	if err != nil {
218
+		return err
219
+	}
220
+	mw.buf = buf
221
+	mw.wloc = l
222
+	return nil
223
+}
224
+
225
+// peek at the extension type, assuming the next
226
+// kind to be read is Extension
227
+func (m *Reader) peekExtensionType() (int8, error) {
228
+	p, err := m.r.Peek(2)
229
+	if err != nil {
230
+		return 0, err
231
+	}
232
+	spec := sizes[p[0]]
233
+	if spec.typ != ExtensionType {
234
+		return 0, badPrefix(ExtensionType, p[0])
235
+	}
236
+	if spec.extra == constsize {
237
+		return int8(p[1]), nil
238
+	}
239
+	size := spec.size
240
+	p, err = m.r.Peek(int(size))
241
+	if err != nil {
242
+		return 0, err
243
+	}
244
+	return int8(p[size-1]), nil
245
+}
246
+
247
+// peekExtension peeks at the extension encoding type
248
+// (must guarantee at least 1 byte in 'b')
249
+func peekExtension(b []byte) (int8, error) {
250
+	spec := sizes[b[0]]
251
+	size := spec.size
252
+	if spec.typ != ExtensionType {
253
+		return 0, badPrefix(ExtensionType, b[0])
254
+	}
255
+	if len(b) < int(size) {
256
+		return 0, ErrShortBytes
257
+	}
258
+	// for fixed extensions,
259
+	// the type information is in
260
+	// the second byte
261
+	if spec.extra == constsize {
262
+		return int8(b[1]), nil
263
+	}
264
+	// otherwise, it's in the last
265
+	// part of the prefix
266
+	return int8(b[size-1]), nil
267
+}
268
+
269
+// ReadExtension reads the next object from the reader
270
+// as an extension. ReadExtension will fail if the next
271
+// object in the stream is not an extension, or if
272
+// e.Type() is not the same as the wire type.
273
+func (m *Reader) ReadExtension(e Extension) (err error) {
274
+	var p []byte
275
+	p, err = m.r.Peek(2)
276
+	if err != nil {
277
+		return
278
+	}
279
+	lead := p[0]
280
+	var read int
281
+	var off int
282
+	switch lead {
283
+	case mfixext1:
284
+		if int8(p[1]) != e.ExtensionType() {
285
+			err = errExt(int8(p[1]), e.ExtensionType())
286
+			return
287
+		}
288
+		p, err = m.r.Peek(3)
289
+		if err != nil {
290
+			return
291
+		}
292
+		err = e.UnmarshalBinary(p[2:])
293
+		if err == nil {
294
+			_, err = m.r.Skip(3)
295
+		}
296
+		return
297
+
298
+	case mfixext2:
299
+		if int8(p[1]) != e.ExtensionType() {
300
+			err = errExt(int8(p[1]), e.ExtensionType())
301
+			return
302
+		}
303
+		p, err = m.r.Peek(4)
304
+		if err != nil {
305
+			return
306
+		}
307
+		err = e.UnmarshalBinary(p[2:])
308
+		if err == nil {
309
+			_, err = m.r.Skip(4)
310
+		}
311
+		return
312
+
313
+	case mfixext4:
314
+		if int8(p[1]) != e.ExtensionType() {
315
+			err = errExt(int8(p[1]), e.ExtensionType())
316
+			return
317
+		}
318
+		p, err = m.r.Peek(6)
319
+		if err != nil {
320
+			return
321
+		}
322
+		err = e.UnmarshalBinary(p[2:])
323
+		if err == nil {
324
+			_, err = m.r.Skip(6)
325
+		}
326
+		return
327
+
328
+	case mfixext8:
329
+		if int8(p[1]) != e.ExtensionType() {
330
+			err = errExt(int8(p[1]), e.ExtensionType())
331
+			return
332
+		}
333
+		p, err = m.r.Peek(10)
334
+		if err != nil {
335
+			return
336
+		}
337
+		err = e.UnmarshalBinary(p[2:])
338
+		if err == nil {
339
+			_, err = m.r.Skip(10)
340
+		}
341
+		return
342
+
343
+	case mfixext16:
344
+		if int8(p[1]) != e.ExtensionType() {
345
+			err = errExt(int8(p[1]), e.ExtensionType())
346
+			return
347
+		}
348
+		p, err = m.r.Peek(18)
349
+		if err != nil {
350
+			return
351
+		}
352
+		err = e.UnmarshalBinary(p[2:])
353
+		if err == nil {
354
+			_, err = m.r.Skip(18)
355
+		}
356
+		return
357
+
358
+	case mext8:
359
+		p, err = m.r.Peek(3)
360
+		if err != nil {
361
+			return
362
+		}
363
+		if int8(p[2]) != e.ExtensionType() {
364
+			err = errExt(int8(p[2]), e.ExtensionType())
365
+			return
366
+		}
367
+		read = int(uint8(p[1]))
368
+		off = 3
369
+
370
+	case mext16:
371
+		p, err = m.r.Peek(4)
372
+		if err != nil {
373
+			return
374
+		}
375
+		if int8(p[3]) != e.ExtensionType() {
376
+			err = errExt(int8(p[3]), e.ExtensionType())
377
+			return
378
+		}
379
+		read = int(big.Uint16(p[1:]))
380
+		off = 4
381
+
382
+	case mext32:
383
+		p, err = m.r.Peek(6)
384
+		if err != nil {
385
+			return
386
+		}
387
+		if int8(p[5]) != e.ExtensionType() {
388
+			err = errExt(int8(p[5]), e.ExtensionType())
389
+			return
390
+		}
391
+		read = int(big.Uint32(p[1:]))
392
+		off = 6
393
+
394
+	default:
395
+		err = badPrefix(ExtensionType, lead)
396
+		return
397
+	}
398
+
399
+	p, err = m.r.Peek(read + off)
400
+	if err != nil {
401
+		return
402
+	}
403
+	err = e.UnmarshalBinary(p[off:])
404
+	if err == nil {
405
+		_, err = m.r.Skip(read + off)
406
+	}
407
+	return
408
+}
409
+
410
+// AppendExtension appends a MessagePack extension to the provided slice
411
+func AppendExtension(b []byte, e Extension) ([]byte, error) {
412
+	l := e.Len()
413
+	var o []byte
414
+	var n int
415
+	switch l {
416
+	case 0:
417
+		o, n = ensure(b, 3)
418
+		o[n] = mext8
419
+		o[n+1] = 0
420
+		o[n+2] = byte(e.ExtensionType())
421
+		return o[:n+3], nil
422
+	case 1:
423
+		o, n = ensure(b, 3)
424
+		o[n] = mfixext1
425
+		o[n+1] = byte(e.ExtensionType())
426
+		n += 2
427
+	case 2:
428
+		o, n = ensure(b, 4)
429
+		o[n] = mfixext2
430
+		o[n+1] = byte(e.ExtensionType())
431
+		n += 2
432
+	case 4:
433
+		o, n = ensure(b, 6)
434
+		o[n] = mfixext4
435
+		o[n+1] = byte(e.ExtensionType())
436
+		n += 2
437
+	case 8:
438
+		o, n = ensure(b, 10)
439
+		o[n] = mfixext8
440
+		o[n+1] = byte(e.ExtensionType())
441
+		n += 2
442
+	case 16:
443
+		o, n = ensure(b, 18)
444
+		o[n] = mfixext16
445
+		o[n+1] = byte(e.ExtensionType())
446
+		n += 2
447
+	}
448
+	switch {
449
+	case l < math.MaxUint8:
450
+		o, n = ensure(b, l+3)
451
+		o[n] = mext8
452
+		o[n+1] = byte(uint8(l))
453
+		o[n+2] = byte(e.ExtensionType())
454
+		n += 3
455
+	case l < math.MaxUint16:
456
+		o, n = ensure(b, l+4)
457
+		o[n] = mext16
458
+		big.PutUint16(o[n+1:], uint16(l))
459
+		o[n+3] = byte(e.ExtensionType())
460
+		n += 4
461
+	default:
462
+		o, n = ensure(b, l+6)
463
+		o[n] = mext32
464
+		big.PutUint32(o[n+1:], uint32(l))
465
+		o[n+5] = byte(e.ExtensionType())
466
+		n += 6
467
+	}
468
+	return o, e.MarshalBinaryTo(o[n:])
469
+}
470
+
471
+// ReadExtensionBytes reads an extension from 'b' into 'e'
472
+// and returns any remaining bytes.
473
+// Possible errors:
474
+// - ErrShortBytes ('b' not long enough)
475
+// - ExtensionTypeErorr{} (wire type not the same as e.Type())
476
+// - TypeErorr{} (next object not an extension)
477
+// - InvalidPrefixError
478
+// - An umarshal error returned from e.UnmarshalBinary
479
+func ReadExtensionBytes(b []byte, e Extension) ([]byte, error) {
480
+	l := len(b)
481
+	if l < 3 {
482
+		return b, ErrShortBytes
483
+	}
484
+	lead := b[0]
485
+	var (
486
+		sz  int // size of 'data'
487
+		off int // offset of 'data'
488
+		typ int8
489
+	)
490
+	switch lead {
491
+	case mfixext1:
492
+		typ = int8(b[1])
493
+		sz = 1
494
+		off = 2
495
+	case mfixext2:
496
+		typ = int8(b[1])
497
+		sz = 2
498
+		off = 2
499
+	case mfixext4:
500
+		typ = int8(b[1])
501
+		sz = 4
502
+		off = 2
503
+	case mfixext8:
504
+		typ = int8(b[1])
505
+		sz = 8
506
+		off = 2
507
+	case mfixext16:
508
+		typ = int8(b[1])
509
+		sz = 16
510
+		off = 2
511
+	case mext8:
512
+		sz = int(uint8(b[1]))
513
+		typ = int8(b[2])
514
+		off = 3
515
+		if sz == 0 {
516
+			return b[3:], e.UnmarshalBinary(b[3:3])
517
+		}
518
+	case mext16:
519
+		if l < 4 {
520
+			return b, ErrShortBytes
521
+		}
522
+		sz = int(big.Uint16(b[1:]))
523
+		typ = int8(b[3])
524
+		off = 4
525
+	case mext32:
526
+		if l < 6 {
527
+			return b, ErrShortBytes
528
+		}
529
+		sz = int(big.Uint32(b[1:]))
530
+		typ = int8(b[5])
531
+		off = 6
532
+	default:
533
+		return b, badPrefix(ExtensionType, lead)
534
+	}
535
+
536
+	if typ != e.ExtensionType() {
537
+		return b, errExt(typ, e.ExtensionType())
538
+	}
539
+
540
+	// the data of the extension starts
541
+	// at 'off' and is 'sz' bytes long
542
+	if len(b[off:]) < sz {
543
+		return b, ErrShortBytes
544
+	}
545
+	tot := off + sz
546
+	return b[tot:], e.UnmarshalBinary(b[off:tot])
547
+}
0 548
new file mode 100644
... ...
@@ -0,0 +1,174 @@
0
+package msgp
1
+
2
+/* ----------------------------------
3
+	integer encoding utilities
4
+	(inline-able)
5
+
6
+	TODO(tinylib): there are faster,
7
+	albeit non-portable solutions
8
+	to the code below. implement
9
+	byteswap?
10
+   ---------------------------------- */
11
+
12
+func putMint64(b []byte, i int64) {
13
+	b[0] = mint64
14
+	b[1] = byte(i >> 56)
15
+	b[2] = byte(i >> 48)
16
+	b[3] = byte(i >> 40)
17
+	b[4] = byte(i >> 32)
18
+	b[5] = byte(i >> 24)
19
+	b[6] = byte(i >> 16)
20
+	b[7] = byte(i >> 8)
21
+	b[8] = byte(i)
22
+}
23
+
24
+func getMint64(b []byte) int64 {
25
+	return (int64(b[1]) << 56) | (int64(b[2]) << 48) |
26
+		(int64(b[3]) << 40) | (int64(b[4]) << 32) |
27
+		(int64(b[5]) << 24) | (int64(b[6]) << 16) |
28
+		(int64(b[7]) << 8) | (int64(b[8]))
29
+}
30
+
31
+func putMint32(b []byte, i int32) {
32
+	b[0] = mint32
33
+	b[1] = byte(i >> 24)
34
+	b[2] = byte(i >> 16)
35
+	b[3] = byte(i >> 8)
36
+	b[4] = byte(i)
37
+}
38
+
39
+func getMint32(b []byte) int32 {
40
+	return (int32(b[1]) << 24) | (int32(b[2]) << 16) | (int32(b[3]) << 8) | (int32(b[4]))
41
+}
42
+
43
+func putMint16(b []byte, i int16) {
44
+	b[0] = mint16
45
+	b[1] = byte(i >> 8)
46
+	b[2] = byte(i)
47
+}
48
+
49
+func getMint16(b []byte) (i int16) {
50
+	return (int16(b[1]) << 8) | int16(b[2])
51
+}
52
+
53
+func putMint8(b []byte, i int8) {
54
+	b[0] = mint8
55
+	b[1] = byte(i)
56
+}
57
+
58
+func getMint8(b []byte) (i int8) {
59
+	return int8(b[1])
60
+}
61
+
62
+func putMuint64(b []byte, u uint64) {
63
+	b[0] = muint64
64
+	b[1] = byte(u >> 56)
65
+	b[2] = byte(u >> 48)
66
+	b[3] = byte(u >> 40)
67
+	b[4] = byte(u >> 32)
68
+	b[5] = byte(u >> 24)
69
+	b[6] = byte(u >> 16)
70
+	b[7] = byte(u >> 8)
71
+	b[8] = byte(u)
72
+}
73
+
74
+func getMuint64(b []byte) uint64 {
75
+	return (uint64(b[1]) << 56) | (uint64(b[2]) << 48) |
76
+		(uint64(b[3]) << 40) | (uint64(b[4]) << 32) |
77
+		(uint64(b[5]) << 24) | (uint64(b[6]) << 16) |
78
+		(uint64(b[7]) << 8) | (uint64(b[8]))
79
+}
80
+
81
+func putMuint32(b []byte, u uint32) {
82
+	b[0] = muint32
83
+	b[1] = byte(u >> 24)
84
+	b[2] = byte(u >> 16)
85
+	b[3] = byte(u >> 8)
86
+	b[4] = byte(u)
87
+}
88
+
89
+func getMuint32(b []byte) uint32 {
90
+	return (uint32(b[1]) << 24) | (uint32(b[2]) << 16) | (uint32(b[3]) << 8) | (uint32(b[4]))
91
+}
92
+
93
+func putMuint16(b []byte, u uint16) {
94
+	b[0] = muint16
95
+	b[1] = byte(u >> 8)
96
+	b[2] = byte(u)
97
+}
98
+
99
+func getMuint16(b []byte) uint16 {
100
+	return (uint16(b[1]) << 8) | uint16(b[2])
101
+}
102
+
103
+func putMuint8(b []byte, u uint8) {
104
+	b[0] = muint8
105
+	b[1] = byte(u)
106
+}
107
+
108
+func getMuint8(b []byte) uint8 {
109
+	return uint8(b[1])
110
+}
111
+
112
+func getUnix(b []byte) (sec int64, nsec int32) {
113
+	sec = (int64(b[0]) << 56) | (int64(b[1]) << 48) |
114
+		(int64(b[2]) << 40) | (int64(b[3]) << 32) |
115
+		(int64(b[4]) << 24) | (int64(b[5]) << 16) |
116
+		(int64(b[6]) << 8) | (int64(b[7]))
117
+
118
+	nsec = (int32(b[8]) << 24) | (int32(b[9]) << 16) | (int32(b[10]) << 8) | (int32(b[11]))
119
+	return
120
+}
121
+
122
+func putUnix(b []byte, sec int64, nsec int32) {
123
+	b[0] = byte(sec >> 56)
124
+	b[1] = byte(sec >> 48)
125
+	b[2] = byte(sec >> 40)
126
+	b[3] = byte(sec >> 32)
127
+	b[4] = byte(sec >> 24)
128
+	b[5] = byte(sec >> 16)
129
+	b[6] = byte(sec >> 8)
130
+	b[7] = byte(sec)
131
+	b[8] = byte(nsec >> 24)
132
+	b[9] = byte(nsec >> 16)
133
+	b[10] = byte(nsec >> 8)
134
+	b[11] = byte(nsec)
135
+}
136
+
137
+/* -----------------------------
138
+		prefix utilities
139
+   ----------------------------- */
140
+
141
+// write prefix and uint8
142
+func prefixu8(b []byte, pre byte, sz uint8) {
143
+	b[0] = pre
144
+	b[1] = byte(sz)
145
+}
146
+
147
+// write prefix and big-endian uint16
148
+func prefixu16(b []byte, pre byte, sz uint16) {
149
+	b[0] = pre
150
+	b[1] = byte(sz >> 8)
151
+	b[2] = byte(sz)
152
+}
153
+
154
+// write prefix and big-endian uint32
155
+func prefixu32(b []byte, pre byte, sz uint32) {
156
+	b[0] = pre
157
+	b[1] = byte(sz >> 24)
158
+	b[2] = byte(sz >> 16)
159
+	b[3] = byte(sz >> 8)
160
+	b[4] = byte(sz)
161
+}
162
+
163
+func prefixu64(b []byte, pre byte, sz uint64) {
164
+	b[0] = pre
165
+	b[1] = byte(sz >> 56)
166
+	b[2] = byte(sz >> 48)
167
+	b[3] = byte(sz >> 40)
168
+	b[4] = byte(sz >> 32)
169
+	b[5] = byte(sz >> 24)
170
+	b[6] = byte(sz >> 16)
171
+	b[7] = byte(sz >> 8)
172
+	b[8] = byte(sz)
173
+}
0 174
new file mode 100644
... ...
@@ -0,0 +1,542 @@
0
+package msgp
1
+
2
+import (
3
+	"bufio"
4
+	"encoding/base64"
5
+	"encoding/json"
6
+	"io"
7
+	"strconv"
8
+	"unicode/utf8"
9
+)
10
+
11
+var (
12
+	null = []byte("null")
13
+	hex  = []byte("0123456789abcdef")
14
+)
15
+
16
+var defuns [_maxtype]func(jsWriter, *Reader) (int, error)
17
+
18
+// note: there is an initialization loop if
19
+// this isn't set up during init()
20
+func init() {
21
+	// since none of these functions are inline-able,
22
+	// there is not much of a penalty to the indirect
23
+	// call. however, this is best expressed as a jump-table...
24
+	defuns = [_maxtype]func(jsWriter, *Reader) (int, error){
25
+		StrType:        rwString,
26
+		BinType:        rwBytes,
27
+		MapType:        rwMap,
28
+		ArrayType:      rwArray,
29
+		Float64Type:    rwFloat64,
30
+		Float32Type:    rwFloat32,
31
+		BoolType:       rwBool,
32
+		IntType:        rwInt,
33
+		UintType:       rwUint,
34
+		NilType:        rwNil,
35
+		ExtensionType:  rwExtension,
36
+		Complex64Type:  rwExtension,
37
+		Complex128Type: rwExtension,
38
+		TimeType:       rwTime,
39
+	}
40
+}
41
+
42
+// this is the interface
43
+// used to write json
44
+type jsWriter interface {
45
+	io.Writer
46
+	io.ByteWriter
47
+	WriteString(string) (int, error)
48
+}
49
+
50
+// CopyToJSON reads MessagePack from 'src' and copies it
51
+// as JSON to 'dst' until EOF.
52
+func CopyToJSON(dst io.Writer, src io.Reader) (n int64, err error) {
53
+	r := NewReader(src)
54
+	n, err = r.WriteToJSON(dst)
55
+	freeR(r)
56
+	return
57
+}
58
+
59
+// WriteToJSON translates MessagePack from 'r' and writes it as
60
+// JSON to 'w' until the underlying reader returns io.EOF. It returns
61
+// the number of bytes written, and an error if it stopped before EOF.
62
+func (r *Reader) WriteToJSON(w io.Writer) (n int64, err error) {
63
+	var j jsWriter
64
+	var bf *bufio.Writer
65
+	if jsw, ok := w.(jsWriter); ok {
66
+		j = jsw
67
+	} else {
68
+		bf = bufio.NewWriterSize(w, 512)
69
+		j = bf
70
+	}
71
+	var nn int
72
+	for err == nil {
73
+		nn, err = rwNext(j, r)
74
+		n += int64(nn)
75
+	}
76
+	if err != io.EOF {
77
+		if bf != nil {
78
+			bf.Flush()
79
+		}
80
+		return
81
+	}
82
+	err = nil
83
+	if bf != nil {
84
+		err = bf.Flush()
85
+	}
86
+	return
87
+}
88
+
89
+func rwNext(w jsWriter, src *Reader) (int, error) {
90
+	t, err := src.NextType()
91
+	if err != nil {
92
+		return 0, err
93
+	}
94
+	return defuns[t](w, src)
95
+}
96
+
97
+func rwMap(dst jsWriter, src *Reader) (n int, err error) {
98
+	var comma bool
99
+	var sz uint32
100
+	var field []byte
101
+
102
+	sz, err = src.ReadMapHeader()
103
+	if err != nil {
104
+		return
105
+	}
106
+
107
+	if sz == 0 {
108
+		return dst.WriteString("{}")
109
+	}
110
+
111
+	err = dst.WriteByte('{')
112
+	if err != nil {
113
+		return
114
+	}
115
+	n++
116
+	var nn int
117
+	for i := uint32(0); i < sz; i++ {
118
+		if comma {
119
+			err = dst.WriteByte(',')
120
+			if err != nil {
121
+				return
122
+			}
123
+			n++
124
+		}
125
+
126
+		field, err = src.ReadMapKeyPtr()
127
+		if err != nil {
128
+			return
129
+		}
130
+		nn, err = rwquoted(dst, field)
131
+		n += nn
132
+		if err != nil {
133
+			return
134
+		}
135
+
136
+		err = dst.WriteByte(':')
137
+		if err != nil {
138
+			return
139
+		}
140
+		n++
141
+		nn, err = rwNext(dst, src)
142
+		n += nn
143
+		if err != nil {
144
+			return
145
+		}
146
+		if !comma {
147
+			comma = true
148
+		}
149
+	}
150
+
151
+	err = dst.WriteByte('}')
152
+	if err != nil {
153
+		return
154
+	}
155
+	n++
156
+	return
157
+}
158
+
159
+func rwArray(dst jsWriter, src *Reader) (n int, err error) {
160
+	err = dst.WriteByte('[')
161
+	if err != nil {
162
+		return
163
+	}
164
+	var sz uint32
165
+	var nn int
166
+	sz, err = src.ReadArrayHeader()
167
+	if err != nil {
168
+		return
169
+	}
170
+	comma := false
171
+	for i := uint32(0); i < sz; i++ {
172
+		if comma {
173
+			err = dst.WriteByte(',')
174
+			if err != nil {
175
+				return
176
+			}
177
+			n++
178
+		}
179
+		nn, err = rwNext(dst, src)
180
+		n += nn
181
+		if err != nil {
182
+			return
183
+		}
184
+		comma = true
185
+	}
186
+
187
+	err = dst.WriteByte(']')
188
+	if err != nil {
189
+		return
190
+	}
191
+	n++
192
+	return
193
+}
194
+
195
+func rwNil(dst jsWriter, src *Reader) (int, error) {
196
+	err := src.ReadNil()
197
+	if err != nil {
198
+		return 0, err
199
+	}
200
+	return dst.Write(null)
201
+}
202
+
203
+func rwFloat32(dst jsWriter, src *Reader) (int, error) {
204
+	f, err := src.ReadFloat32()
205
+	if err != nil {
206
+		return 0, err
207
+	}
208
+	src.scratch = strconv.AppendFloat(src.scratch[:0], float64(f), 'f', -1, 64)
209
+	return dst.Write(src.scratch)
210
+}
211
+
212
+func rwFloat64(dst jsWriter, src *Reader) (int, error) {
213
+	f, err := src.ReadFloat64()
214
+	if err != nil {
215
+		return 0, err
216
+	}
217
+	src.scratch = strconv.AppendFloat(src.scratch[:0], f, 'f', -1, 32)
218
+	return dst.Write(src.scratch)
219
+}
220
+
221
+func rwInt(dst jsWriter, src *Reader) (int, error) {
222
+	i, err := src.ReadInt64()
223
+	if err != nil {
224
+		return 0, err
225
+	}
226
+	src.scratch = strconv.AppendInt(src.scratch[:0], i, 10)
227
+	return dst.Write(src.scratch)
228
+}
229
+
230
+func rwUint(dst jsWriter, src *Reader) (int, error) {
231
+	u, err := src.ReadUint64()
232
+	if err != nil {
233
+		return 0, err
234
+	}
235
+	src.scratch = strconv.AppendUint(src.scratch[:0], u, 10)
236
+	return dst.Write(src.scratch)
237
+}
238
+
239
+func rwBool(dst jsWriter, src *Reader) (int, error) {
240
+	b, err := src.ReadBool()
241
+	if err != nil {
242
+		return 0, err
243
+	}
244
+	if b {
245
+		return dst.WriteString("true")
246
+	}
247
+	return dst.WriteString("false")
248
+}
249
+
250
+func rwTime(dst jsWriter, src *Reader) (int, error) {
251
+	t, err := src.ReadTime()
252
+	if err != nil {
253
+		return 0, err
254
+	}
255
+	bts, err := t.MarshalJSON()
256
+	if err != nil {
257
+		return 0, err
258
+	}
259
+	return dst.Write(bts)
260
+}
261
+
262
+func rwExtension(dst jsWriter, src *Reader) (n int, err error) {
263
+	et, err := src.peekExtensionType()
264
+	if err != nil {
265
+		return 0, err
266
+	}
267
+
268
+	// registered extensions can override
269
+	// the JSON encoding
270
+	if j, ok := extensionReg[et]; ok {
271
+		var bts []byte
272
+		e := j()
273
+		err = src.ReadExtension(e)
274
+		if err != nil {
275
+			return
276
+		}
277
+		bts, err = json.Marshal(e)
278
+		if err != nil {
279
+			return
280
+		}
281
+		return dst.Write(bts)
282
+	}
283
+
284
+	e := RawExtension{}
285
+	e.Type = et
286
+	err = src.ReadExtension(&e)
287
+	if err != nil {
288
+		return
289
+	}
290
+
291
+	var nn int
292
+	err = dst.WriteByte('{')
293
+	if err != nil {
294
+		return
295
+	}
296
+	n++
297
+
298
+	nn, err = dst.WriteString(`"type:"`)
299
+	n += nn
300
+	if err != nil {
301
+		return
302
+	}
303
+
304
+	src.scratch = strconv.AppendInt(src.scratch[0:0], int64(e.Type), 10)
305
+	nn, err = dst.Write(src.scratch)
306
+	n += nn
307
+	if err != nil {
308
+		return
309
+	}
310
+
311
+	nn, err = dst.WriteString(`,"data":"`)
312
+	n += nn
313
+	if err != nil {
314
+		return
315
+	}
316
+
317
+	enc := base64.NewEncoder(base64.StdEncoding, dst)
318
+
319
+	nn, err = enc.Write(e.Data)
320
+	n += nn
321
+	if err != nil {
322
+		return
323
+	}
324
+	err = enc.Close()
325
+	if err != nil {
326
+		return
327
+	}
328
+	nn, err = dst.WriteString(`"}`)
329
+	n += nn
330
+	return
331
+}
332
+
333
+func rwString(dst jsWriter, src *Reader) (n int, err error) {
334
+	var p []byte
335
+	p, err = src.r.Peek(1)
336
+	if err != nil {
337
+		return
338
+	}
339
+	lead := p[0]
340
+	var read int
341
+
342
+	if isfixstr(lead) {
343
+		read = int(rfixstr(lead))
344
+		src.r.Skip(1)
345
+		goto write
346
+	}
347
+
348
+	switch lead {
349
+	case mstr8:
350
+		p, err = src.r.Next(2)
351
+		if err != nil {
352
+			return
353
+		}
354
+		read = int(uint8(p[1]))
355
+	case mstr16:
356
+		p, err = src.r.Next(3)
357
+		if err != nil {
358
+			return
359
+		}
360
+		read = int(big.Uint16(p[1:]))
361
+	case mstr32:
362
+		p, err = src.r.Next(5)
363
+		if err != nil {
364
+			return
365
+		}
366
+		read = int(big.Uint32(p[1:]))
367
+	default:
368
+		err = badPrefix(StrType, lead)
369
+		return
370
+	}
371
+write:
372
+	p, err = src.r.Next(read)
373
+	if err != nil {
374
+		return
375
+	}
376
+	n, err = rwquoted(dst, p)
377
+	return
378
+}
379
+
380
+func rwBytes(dst jsWriter, src *Reader) (n int, err error) {
381
+	var nn int
382
+	err = dst.WriteByte('"')
383
+	if err != nil {
384
+		return
385
+	}
386
+	n++
387
+	src.scratch, err = src.ReadBytes(src.scratch[:0])
388
+	if err != nil {
389
+		return
390
+	}
391
+	enc := base64.NewEncoder(base64.StdEncoding, dst)
392
+	nn, err = enc.Write(src.scratch)
393
+	n += nn
394
+	if err != nil {
395
+		return
396
+	}
397
+	err = enc.Close()
398
+	if err != nil {
399
+		return
400
+	}
401
+	err = dst.WriteByte('"')
402
+	if err != nil {
403
+		return
404
+	}
405
+	n++
406
+	return
407
+}
408
+
409
+// Below (c) The Go Authors, 2009-2014
410
+// Subject to the BSD-style license found at http://golang.org
411
+//
412
+// see: encoding/json/encode.go:(*encodeState).stringbytes()
413
+func rwquoted(dst jsWriter, s []byte) (n int, err error) {
414
+	var nn int
415
+	err = dst.WriteByte('"')
416
+	if err != nil {
417
+		return
418
+	}
419
+	n++
420
+	start := 0
421
+	for i := 0; i < len(s); {
422
+		if b := s[i]; b < utf8.RuneSelf {
423
+			if 0x20 <= b && b != '\\' && b != '"' && b != '<' && b != '>' && b != '&' {
424
+				i++
425
+				continue
426
+			}
427
+			if start < i {
428
+				nn, err = dst.Write(s[start:i])
429
+				n += nn
430
+				if err != nil {
431
+					return
432
+				}
433
+			}
434
+			switch b {
435
+			case '\\', '"':
436
+				err = dst.WriteByte('\\')
437
+				if err != nil {
438
+					return
439
+				}
440
+				n++
441
+				err = dst.WriteByte(b)
442
+				if err != nil {
443
+					return
444
+				}
445
+				n++
446
+			case '\n':
447
+				err = dst.WriteByte('\\')
448
+				if err != nil {
449
+					return
450
+				}
451
+				n++
452
+				err = dst.WriteByte('n')
453
+				if err != nil {
454
+					return
455
+				}
456
+				n++
457
+			case '\r':
458
+				err = dst.WriteByte('\\')
459
+				if err != nil {
460
+					return
461
+				}
462
+				n++
463
+				err = dst.WriteByte('r')
464
+				if err != nil {
465
+					return
466
+				}
467
+				n++
468
+			default:
469
+				nn, err = dst.WriteString(`\u00`)
470
+				n += nn
471
+				if err != nil {
472
+					return
473
+				}
474
+				err = dst.WriteByte(hex[b>>4])
475
+				if err != nil {
476
+					return
477
+				}
478
+				n++
479
+				err = dst.WriteByte(hex[b&0xF])
480
+				if err != nil {
481
+					return
482
+				}
483
+				n++
484
+			}
485
+			i++
486
+			start = i
487
+			continue
488
+		}
489
+		c, size := utf8.DecodeRune(s[i:])
490
+		if c == utf8.RuneError && size == 1 {
491
+			if start < i {
492
+				nn, err = dst.Write(s[start:i])
493
+				n += nn
494
+				if err != nil {
495
+					return
496
+				}
497
+				nn, err = dst.WriteString(`\ufffd`)
498
+				n += nn
499
+				if err != nil {
500
+					return
501
+				}
502
+				i += size
503
+				start = i
504
+				continue
505
+			}
506
+		}
507
+		if c == '\u2028' || c == '\u2029' {
508
+			if start < i {
509
+				nn, err = dst.Write(s[start:i])
510
+				n += nn
511
+				if err != nil {
512
+					return
513
+				}
514
+				nn, err = dst.WriteString(`\u202`)
515
+				n += nn
516
+				if err != nil {
517
+					return
518
+				}
519
+				err = dst.WriteByte(hex[c&0xF])
520
+				if err != nil {
521
+					return
522
+				}
523
+				n++
524
+			}
525
+		}
526
+		i += size
527
+	}
528
+	if start < len(s) {
529
+		nn, err = dst.Write(s[start:])
530
+		n += nn
531
+		if err != nil {
532
+			return
533
+		}
534
+	}
535
+	err = dst.WriteByte('"')
536
+	if err != nil {
537
+		return
538
+	}
539
+	n++
540
+	return
541
+}
0 542
new file mode 100644
... ...
@@ -0,0 +1,363 @@
0
+package msgp
1
+
2
+import (
3
+	"bufio"
4
+	"encoding/base64"
5
+	"encoding/json"
6
+	"io"
7
+	"strconv"
8
+	"time"
9
+)
10
+
11
+var unfuns [_maxtype]func(jsWriter, []byte, []byte) ([]byte, []byte, error)
12
+
13
+func init() {
14
+
15
+	// NOTE(pmh): this is best expressed as a jump table,
16
+	// but gc doesn't do that yet. revisit post-go1.5.
17
+	unfuns = [_maxtype]func(jsWriter, []byte, []byte) ([]byte, []byte, error){
18
+		StrType:        rwStringBytes,
19
+		BinType:        rwBytesBytes,
20
+		MapType:        rwMapBytes,
21
+		ArrayType:      rwArrayBytes,
22
+		Float64Type:    rwFloat64Bytes,
23
+		Float32Type:    rwFloat32Bytes,
24
+		BoolType:       rwBoolBytes,
25
+		IntType:        rwIntBytes,
26
+		UintType:       rwUintBytes,
27
+		NilType:        rwNullBytes,
28
+		ExtensionType:  rwExtensionBytes,
29
+		Complex64Type:  rwExtensionBytes,
30
+		Complex128Type: rwExtensionBytes,
31
+		TimeType:       rwTimeBytes,
32
+	}
33
+}
34
+
35
+// UnmarshalAsJSON takes raw messagepack and writes
36
+// it as JSON to 'w'. If an error is returned, the
37
+// bytes not translated will also be returned. If
38
+// no errors are encountered, the length of the returned
39
+// slice will be zero.
40
+func UnmarshalAsJSON(w io.Writer, msg []byte) ([]byte, error) {
41
+	var (
42
+		scratch []byte
43
+		cast    bool
44
+		dst     jsWriter
45
+		err     error
46
+	)
47
+	if jsw, ok := w.(jsWriter); ok {
48
+		dst = jsw
49
+		cast = true
50
+	} else {
51
+		dst = bufio.NewWriterSize(w, 512)
52
+	}
53
+	for len(msg) > 0 && err == nil {
54
+		msg, scratch, err = writeNext(dst, msg, scratch)
55
+	}
56
+	if !cast && err == nil {
57
+		err = dst.(*bufio.Writer).Flush()
58
+	}
59
+	return msg, err
60
+}
61
+
62
+func writeNext(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
63
+	if len(msg) < 1 {
64
+		return msg, scratch, ErrShortBytes
65
+	}
66
+	t := getType(msg[0])
67
+	if t == InvalidType {
68
+		return msg, scratch, InvalidPrefixError(msg[0])
69
+	}
70
+	if t == ExtensionType {
71
+		et, err := peekExtension(msg)
72
+		if err != nil {
73
+			return nil, scratch, err
74
+		}
75
+		if et == TimeExtension {
76
+			t = TimeType
77
+		}
78
+	}
79
+	return unfuns[t](w, msg, scratch)
80
+}
81
+
82
+func rwArrayBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
83
+	sz, msg, err := ReadArrayHeaderBytes(msg)
84
+	if err != nil {
85
+		return msg, scratch, err
86
+	}
87
+	err = w.WriteByte('[')
88
+	if err != nil {
89
+		return msg, scratch, err
90
+	}
91
+	for i := uint32(0); i < sz; i++ {
92
+		if i != 0 {
93
+			err = w.WriteByte(',')
94
+			if err != nil {
95
+				return msg, scratch, err
96
+			}
97
+		}
98
+		msg, scratch, err = writeNext(w, msg, scratch)
99
+		if err != nil {
100
+			return msg, scratch, err
101
+		}
102
+	}
103
+	err = w.WriteByte(']')
104
+	return msg, scratch, err
105
+}
106
+
107
+func rwMapBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
108
+	sz, msg, err := ReadMapHeaderBytes(msg)
109
+	if err != nil {
110
+		return msg, scratch, err
111
+	}
112
+	err = w.WriteByte('{')
113
+	if err != nil {
114
+		return msg, scratch, err
115
+	}
116
+	for i := uint32(0); i < sz; i++ {
117
+		if i != 0 {
118
+			err = w.WriteByte(',')
119
+			if err != nil {
120
+				return msg, scratch, err
121
+			}
122
+		}
123
+		msg, scratch, err = rwMapKeyBytes(w, msg, scratch)
124
+		if err != nil {
125
+			return msg, scratch, err
126
+		}
127
+		err = w.WriteByte(':')
128
+		if err != nil {
129
+			return msg, scratch, err
130
+		}
131
+		msg, scratch, err = writeNext(w, msg, scratch)
132
+		if err != nil {
133
+			return msg, scratch, err
134
+		}
135
+	}
136
+	err = w.WriteByte('}')
137
+	return msg, scratch, err
138
+}
139
+
140
+func rwMapKeyBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
141
+	msg, scratch, err := rwStringBytes(w, msg, scratch)
142
+	if err != nil {
143
+		if tperr, ok := err.(TypeError); ok && tperr.Encoded == BinType {
144
+			return rwBytesBytes(w, msg, scratch)
145
+		}
146
+	}
147
+	return msg, scratch, err
148
+}
149
+
150
+func rwStringBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
151
+	str, msg, err := ReadStringZC(msg)
152
+	if err != nil {
153
+		return msg, scratch, err
154
+	}
155
+	_, err = rwquoted(w, str)
156
+	return msg, scratch, err
157
+}
158
+
159
+func rwBytesBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
160
+	bts, msg, err := ReadBytesZC(msg)
161
+	if err != nil {
162
+		return msg, scratch, err
163
+	}
164
+	l := base64.StdEncoding.EncodedLen(len(bts))
165
+	if cap(scratch) >= l {
166
+		scratch = scratch[0:l]
167
+	} else {
168
+		scratch = make([]byte, l)
169
+	}
170
+	base64.StdEncoding.Encode(scratch, bts)
171
+	err = w.WriteByte('"')
172
+	if err != nil {
173
+		return msg, scratch, err
174
+	}
175
+	_, err = w.Write(scratch)
176
+	if err != nil {
177
+		return msg, scratch, err
178
+	}
179
+	err = w.WriteByte('"')
180
+	return msg, scratch, err
181
+}
182
+
183
+func rwNullBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
184
+	msg, err := ReadNilBytes(msg)
185
+	if err != nil {
186
+		return msg, scratch, err
187
+	}
188
+	_, err = w.Write(null)
189
+	return msg, scratch, err
190
+}
191
+
192
+func rwBoolBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
193
+	b, msg, err := ReadBoolBytes(msg)
194
+	if err != nil {
195
+		return msg, scratch, err
196
+	}
197
+	if b {
198
+		_, err = w.WriteString("true")
199
+		return msg, scratch, err
200
+	}
201
+	_, err = w.WriteString("false")
202
+	return msg, scratch, err
203
+}
204
+
205
+func rwIntBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
206
+	i, msg, err := ReadInt64Bytes(msg)
207
+	if err != nil {
208
+		return msg, scratch, err
209
+	}
210
+	scratch = strconv.AppendInt(scratch[0:0], i, 10)
211
+	_, err = w.Write(scratch)
212
+	return msg, scratch, err
213
+}
214
+
215
+func rwUintBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
216
+	u, msg, err := ReadUint64Bytes(msg)
217
+	if err != nil {
218
+		return msg, scratch, err
219
+	}
220
+	scratch = strconv.AppendUint(scratch[0:0], u, 10)
221
+	_, err = w.Write(scratch)
222
+	return msg, scratch, err
223
+}
224
+
225
+func rwFloatBytes(w jsWriter, msg []byte, f64 bool, scratch []byte) ([]byte, []byte, error) {
226
+	var f float64
227
+	var err error
228
+	var sz int
229
+	if f64 {
230
+		sz = 64
231
+		f, msg, err = ReadFloat64Bytes(msg)
232
+	} else {
233
+		sz = 32
234
+		var v float32
235
+		v, msg, err = ReadFloat32Bytes(msg)
236
+		f = float64(v)
237
+	}
238
+	if err != nil {
239
+		return msg, scratch, err
240
+	}
241
+	scratch = strconv.AppendFloat(scratch, f, 'f', -1, sz)
242
+	_, err = w.Write(scratch)
243
+	return msg, scratch, err
244
+}
245
+
246
+func rwFloat32Bytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
247
+	var f float32
248
+	var err error
249
+	f, msg, err = ReadFloat32Bytes(msg)
250
+	if err != nil {
251
+		return msg, scratch, err
252
+	}
253
+	scratch = strconv.AppendFloat(scratch[:0], float64(f), 'f', -1, 32)
254
+	_, err = w.Write(scratch)
255
+	return msg, scratch, err
256
+}
257
+
258
+func rwFloat64Bytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
259
+	var f float64
260
+	var err error
261
+	f, msg, err = ReadFloat64Bytes(msg)
262
+	if err != nil {
263
+		return msg, scratch, err
264
+	}
265
+	scratch = strconv.AppendFloat(scratch[:0], f, 'f', -1, 64)
266
+	_, err = w.Write(scratch)
267
+	return msg, scratch, err
268
+}
269
+
270
+func rwTimeBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
271
+	var t time.Time
272
+	var err error
273
+	t, msg, err = ReadTimeBytes(msg)
274
+	if err != nil {
275
+		return msg, scratch, err
276
+	}
277
+	bts, err := t.MarshalJSON()
278
+	if err != nil {
279
+		return msg, scratch, err
280
+	}
281
+	_, err = w.Write(bts)
282
+	return msg, scratch, err
283
+}
284
+
285
+func rwExtensionBytes(w jsWriter, msg []byte, scratch []byte) ([]byte, []byte, error) {
286
+	var err error
287
+	var et int8
288
+	et, err = peekExtension(msg)
289
+	if err != nil {
290
+		return msg, scratch, err
291
+	}
292
+
293
+	// if it's time.Time
294
+	if et == TimeExtension {
295
+		var tm time.Time
296
+		tm, msg, err = ReadTimeBytes(msg)
297
+		if err != nil {
298
+			return msg, scratch, err
299
+		}
300
+		bts, err := tm.MarshalJSON()
301
+		if err != nil {
302
+			return msg, scratch, err
303
+		}
304
+		_, err = w.Write(bts)
305
+		return msg, scratch, err
306
+	}
307
+
308
+	// if the extension is registered,
309
+	// use its canonical JSON form
310
+	if f, ok := extensionReg[et]; ok {
311
+		e := f()
312
+		msg, err = ReadExtensionBytes(msg, e)
313
+		if err != nil {
314
+			return msg, scratch, err
315
+		}
316
+		bts, err := json.Marshal(e)
317
+		if err != nil {
318
+			return msg, scratch, err
319
+		}
320
+		_, err = w.Write(bts)
321
+		return msg, scratch, err
322
+	}
323
+
324
+	// otherwise, write `{"type": <num>, "data": "<base64data>"}`
325
+	r := RawExtension{}
326
+	r.Type = et
327
+	msg, err = ReadExtensionBytes(msg, &r)
328
+	if err != nil {
329
+		return msg, scratch, err
330
+	}
331
+	scratch, err = writeExt(w, r, scratch)
332
+	return msg, scratch, err
333
+}
334
+
335
+func writeExt(w jsWriter, r RawExtension, scratch []byte) ([]byte, error) {
336
+	_, err := w.WriteString(`{"type":`)
337
+	if err != nil {
338
+		return scratch, err
339
+	}
340
+	scratch = strconv.AppendInt(scratch[0:0], int64(r.Type), 10)
341
+	_, err = w.Write(scratch)
342
+	if err != nil {
343
+		return scratch, err
344
+	}
345
+	_, err = w.WriteString(`,"data":"`)
346
+	if err != nil {
347
+		return scratch, err
348
+	}
349
+	l := base64.StdEncoding.EncodedLen(len(r.Data))
350
+	if cap(scratch) >= l {
351
+		scratch = scratch[0:l]
352
+	} else {
353
+		scratch = make([]byte, l)
354
+	}
355
+	base64.StdEncoding.Encode(scratch, r.Data)
356
+	_, err = w.Write(scratch)
357
+	if err != nil {
358
+		return scratch, err
359
+	}
360
+	_, err = w.WriteString(`"}`)
361
+	return scratch, err
362
+}
0 363
new file mode 100644
... ...
@@ -0,0 +1,140 @@
0
+package msgp
1
+
2
+import (
3
+	"strconv"
4
+)
5
+
6
+// The portable parts of the Number implementation
7
+
8
+// DecodeMsg implements msgp.Decodable
9
+func (n *Number) DecodeMsg(r *Reader) error {
10
+	typ, err := r.NextType()
11
+	if err != nil {
12
+		return err
13
+	}
14
+	switch typ {
15
+	case Float32Type:
16
+		f, err := r.ReadFloat32()
17
+		if err != nil {
18
+			return err
19
+		}
20
+		n.AsFloat32(f)
21
+		return nil
22
+	case Float64Type:
23
+		f, err := r.ReadFloat64()
24
+		if err != nil {
25
+			return err
26
+		}
27
+		n.AsFloat64(f)
28
+		return nil
29
+	case IntType:
30
+		i, err := r.ReadInt64()
31
+		if err != nil {
32
+			return err
33
+		}
34
+		n.AsInt(i)
35
+		return nil
36
+	case UintType:
37
+		u, err := r.ReadUint64()
38
+		if err != nil {
39
+			return err
40
+		}
41
+		n.AsUint(u)
42
+		return nil
43
+	default:
44
+		return TypeError{Encoded: typ, Method: IntType}
45
+	}
46
+}
47
+
48
+// UnmarshalMsg implements msgp.Unmarshaler
49
+func (n *Number) UnmarshalMsg(b []byte) ([]byte, error) {
50
+	typ := NextType(b)
51
+	switch typ {
52
+	case IntType:
53
+		i, o, err := ReadInt64Bytes(b)
54
+		if err != nil {
55
+			return b, err
56
+		}
57
+		n.AsInt(i)
58
+		return o, nil
59
+	case UintType:
60
+		u, o, err := ReadUint64Bytes(b)
61
+		if err != nil {
62
+			return b, err
63
+		}
64
+		n.AsUint(u)
65
+		return o, nil
66
+	case Float64Type:
67
+		f, o, err := ReadFloat64Bytes(b)
68
+		if err != nil {
69
+			return b, err
70
+		}
71
+		n.AsFloat64(f)
72
+		return o, nil
73
+	case Float32Type:
74
+		f, o, err := ReadFloat32Bytes(b)
75
+		if err != nil {
76
+			return b, err
77
+		}
78
+		n.AsFloat32(f)
79
+		return o, nil
80
+	default:
81
+		return b, TypeError{Method: IntType, Encoded: typ}
82
+	}
83
+}
84
+
85
+// Msgsize implements msgp.Sizer
86
+func (n *Number) Msgsize() int {
87
+	switch n.typ {
88
+	case Float32Type:
89
+		return Float32Size
90
+	case Float64Type:
91
+		return Float64Size
92
+	case IntType:
93
+		return Int64Size
94
+	case UintType:
95
+		return Uint64Size
96
+	default:
97
+		return 1 // fixint(0)
98
+	}
99
+}
100
+
101
+// MarshalJSON implements json.Marshaler
102
+func (n *Number) MarshalJSON() ([]byte, error) {
103
+	t := n.Type()
104
+	if t == InvalidType {
105
+		return []byte{'0'}, nil
106
+	}
107
+	out := make([]byte, 0, 32)
108
+	switch t {
109
+	case Float32Type, Float64Type:
110
+		f, _ := n.Float()
111
+		return strconv.AppendFloat(out, f, 'f', -1, 64), nil
112
+	case IntType:
113
+		i, _ := n.Int()
114
+		return strconv.AppendInt(out, i, 10), nil
115
+	case UintType:
116
+		u, _ := n.Uint()
117
+		return strconv.AppendUint(out, u, 10), nil
118
+	default:
119
+		panic("(*Number).typ is invalid")
120
+	}
121
+}
122
+
123
+func (n *Number) String() string {
124
+	switch n.typ {
125
+	case InvalidType:
126
+		return "0"
127
+	case Float32Type, Float64Type:
128
+		f, _ := n.Float()
129
+		return strconv.FormatFloat(f, 'f', -1, 64)
130
+	case IntType:
131
+		i, _ := n.Int()
132
+		return strconv.FormatInt(i, 10)
133
+	case UintType:
134
+		u, _ := n.Uint()
135
+		return strconv.FormatUint(u, 10)
136
+	default:
137
+		panic("(*Number).typ is invalid")
138
+	}
139
+}
0 140
new file mode 100644
... ...
@@ -0,0 +1,101 @@
0
+// +build appengine
1
+
2
+package msgp
3
+
4
+// let's just assume appengine
5
+// uses 64-bit hardware...
6
+const smallint = false
7
+
8
+func UnsafeString(b []byte) string {
9
+	return string(b)
10
+}
11
+
12
+func UnsafeBytes(s string) []byte {
13
+	return []byte(s)
14
+}
15
+
16
+type Number struct {
17
+	ibits uint64  // zero or bits
18
+	fbits float64 // zero or bits
19
+	typ   Type    // zero or type
20
+}
21
+
22
+func (n *Number) AsFloat64(f float64) {
23
+	n.typ = Float64Type
24
+	n.fbits = f
25
+	n.ibits = 0
26
+}
27
+
28
+func (n *Number) AsFloat32(f float32) {
29
+	n.typ = Float32Type
30
+	n.fbits = float64(f)
31
+	n.ibits = 0
32
+}
33
+
34
+func (n *Number) AsInt(i int64) {
35
+	n.fbits = 0
36
+	if i == 0 {
37
+		n.typ = InvalidType
38
+		n.ibits = 0
39
+		return
40
+	}
41
+	n.ibits = uint64(i)
42
+	n.typ = IntType
43
+}
44
+
45
+func (n *Number) AsUint(u uint64) {
46
+	n.ibits = u
47
+	n.fbits = 0
48
+	n.typ = UintType
49
+}
50
+
51
+func (n *Number) Float() (float64, bool) {
52
+	return n.fbits, n.typ == Float64Type || n.typ == Float32Type
53
+}
54
+
55
+func (n *Number) Int() (int64, bool) {
56
+	return int64(n.ibits), n.typ == IntType
57
+}
58
+
59
+func (n *Number) Uint() (uint64, bool) {
60
+	return n.ibits, n.typ == UintType
61
+}
62
+
63
+func (n *Number) Type() Type {
64
+	if n.typ == InvalidType {
65
+		return IntType
66
+	}
67
+	return n.typ
68
+}
69
+
70
+func (n *Number) MarshalMsg(o []byte) ([]byte, error) {
71
+	switch n.typ {
72
+	case InvalidType:
73
+		return AppendInt64(o, 0), nil
74
+	case IntType:
75
+		return AppendInt64(o, int64(n.ibits)), nil
76
+	case UintType:
77
+		return AppendUint64(o, n.ibits), nil
78
+	case Float32Type:
79
+		return AppendFloat32(o, float32(n.fbits)), nil
80
+	case Float64Type:
81
+		return AppendFloat64(o, n.fbits), nil
82
+	}
83
+	panic("unreachable code!")
84
+}
85
+
86
+func (n *Number) EncodeMsg(w *Writer) error {
87
+	switch n.typ {
88
+	case InvalidType:
89
+		return w.WriteInt64(0)
90
+	case IntType:
91
+		return w.WriteInt64(int64(n.ibits))
92
+	case UintType:
93
+		return w.WriteUint64(n.ibits)
94
+	case Float32Type:
95
+		return w.WriteFloat32(float32(n.fbits))
96
+	case Float64Type:
97
+		return w.WriteFloat64(n.fbits)
98
+	}
99
+	panic("unreachable code!")
100
+}
0 101
new file mode 100644
... ...
@@ -0,0 +1,159 @@
0
+// +build !appengine
1
+
2
+package msgp
3
+
4
+import (
5
+	"reflect"
6
+	"unsafe"
7
+)
8
+
9
+const (
10
+	// spec says int and uint are always
11
+	// the same size, but that int/uint
12
+	// size may not be machine word size
13
+	smallint = unsafe.Sizeof(int(0)) == 4
14
+)
15
+
16
+// UnsafeString returns the byte slice as a volatile string
17
+// THIS SHOULD ONLY BE USED BY THE CODE GENERATOR.
18
+// THIS IS EVIL CODE.
19
+// YOU HAVE BEEN WARNED.
20
+func UnsafeString(b []byte) string {
21
+	return *(*string)(unsafe.Pointer(&reflect.StringHeader{Data: uintptr(unsafe.Pointer(&b[0])), Len: len(b)}))
22
+}
23
+
24
+// UnsafeBytes returns the string as a byte slice
25
+// THIS SHOULD ONLY BE USED BY THE CODE GENERATOR.
26
+// THIS IS EVIL CODE.
27
+// YOU HAVE BEEN WARNED.
28
+func UnsafeBytes(s string) []byte {
29
+	return *(*[]byte)(unsafe.Pointer(&reflect.SliceHeader{
30
+		Len:  len(s),
31
+		Cap:  len(s),
32
+		Data: (*(*reflect.StringHeader)(unsafe.Pointer(&s))).Data,
33
+	}))
34
+}
35
+
36
+// Number can be
37
+// an int64, uint64, float32,
38
+// or float64 internally.
39
+// It can decode itself
40
+// from any of the native
41
+// messagepack number types.
42
+// The zero-value of Number
43
+// is Int(0). Using the equality
44
+// operator with Number compares
45
+// both the type and the value
46
+// of the number.
47
+type Number struct {
48
+	// internally, this
49
+	// is just a tagged union.
50
+	// the raw bits of the number
51
+	// are stored the same way regardless.
52
+	bits uint64
53
+	typ  Type
54
+}
55
+
56
+// AsFloat64 sets the number to
57
+// a float64.
58
+func (n *Number) AsFloat64(f float64) {
59
+	n.typ = Float64Type
60
+	n.bits = *(*uint64)(unsafe.Pointer(&f))
61
+}
62
+
63
+// AsInt sets the number to an int64.
64
+func (n *Number) AsInt(i int64) {
65
+
66
+	// we always store int(0)
67
+	// as {0, InvalidType} in
68
+	// order to preserve
69
+	// the behavior of the == operator
70
+	if i == 0 {
71
+		n.typ = InvalidType
72
+		n.bits = 0
73
+		return
74
+	}
75
+
76
+	n.typ = IntType
77
+	n.bits = uint64(i)
78
+}
79
+
80
+// AsUint sets the number to a uint64.
81
+func (n *Number) AsUint(u uint64) {
82
+	n.typ = UintType
83
+	n.bits = u
84
+}
85
+
86
+// AsFloat32 sets the number to a float32.
87
+func (n *Number) AsFloat32(f float32) {
88
+	n.typ = Float32Type
89
+	g := float64(f)
90
+	n.bits = *(*uint64)(unsafe.Pointer(&g))
91
+}
92
+
93
+// Type will return one of:
94
+// Float64Type, Float32Type, UintType, or IntType.
95
+func (n *Number) Type() Type {
96
+	if n.typ == InvalidType {
97
+		return IntType
98
+	}
99
+	return n.typ
100
+}
101
+
102
+// Float casts the number of the float,
103
+// and returns whether or not that was
104
+// the underlying type. (This is legal
105
+// for both float32 and float64 types.)
106
+func (n *Number) Float() (float64, bool) {
107
+	return *(*float64)(unsafe.Pointer(&n.bits)), n.typ == Float64Type || n.typ == Float32Type
108
+}
109
+
110
+// Int casts the number as an int64, and
111
+// returns whether or not that was the
112
+// underlying type.
113
+func (n *Number) Int() (int64, bool) {
114
+	return int64(n.bits), n.typ == IntType || n.typ == InvalidType
115
+}
116
+
117
+// Uint casts the number as a uint64, and returns
118
+// whether or not that was the underlying type.
119
+func (n *Number) Uint() (uint64, bool) {
120
+	return n.bits, n.typ == UintType
121
+}
122
+
123
+// EncodeMsg implements msgp.Encodable
124
+func (n *Number) EncodeMsg(w *Writer) error {
125
+	switch n.typ {
126
+	case InvalidType:
127
+		return w.WriteInt(0)
128
+	case IntType:
129
+		return w.WriteInt64(int64(n.bits))
130
+	case UintType:
131
+		return w.WriteUint64(n.bits)
132
+	case Float64Type:
133
+		return w.WriteFloat64(*(*float64)(unsafe.Pointer(&n.bits)))
134
+	case Float32Type:
135
+		return w.WriteFloat32(float32(*(*float64)(unsafe.Pointer(&n.bits))))
136
+	default:
137
+		// this should never ever happen
138
+		panic("(*Number).typ is invalid")
139
+	}
140
+}
141
+
142
+// MarshalMsg implements msgp.Marshaler
143
+func (n *Number) MarshalMsg(b []byte) ([]byte, error) {
144
+	switch n.typ {
145
+	case InvalidType:
146
+		return AppendInt(b, 0), nil
147
+	case IntType:
148
+		return AppendInt64(b, int64(n.bits)), nil
149
+	case UintType:
150
+		return AppendUint64(b, n.bits), nil
151
+	case Float64Type:
152
+		return AppendFloat64(b, *(*float64)(unsafe.Pointer(&n.bits))), nil
153
+	case Float32Type:
154
+		return AppendFloat32(b, float32(*(*float64)(unsafe.Pointer(&n.bits)))), nil
155
+	default:
156
+		panic("(*Number).typ is invalid")
157
+	}
158
+}
0 159
new file mode 100644
... ...
@@ -0,0 +1,1118 @@
0
+package msgp
1
+
2
+import (
3
+	"github.com/philhofer/fwd"
4
+	"io"
5
+	"math"
6
+	"sync"
7
+	"time"
8
+)
9
+
10
+// where we keep old *Readers
11
+var readerPool = sync.Pool{New: func() interface{} { return &Reader{} }}
12
+
13
+// Type is a MessagePack wire type,
14
+// including this package's built-in
15
+// extension types.
16
+type Type byte
17
+
18
+// MessagePack Types
19
+//
20
+// The zero value of Type
21
+// is InvalidType.
22
+const (
23
+	InvalidType Type = iota
24
+
25
+	// MessagePack built-in types
26
+
27
+	StrType
28
+	BinType
29
+	MapType
30
+	ArrayType
31
+	Float64Type
32
+	Float32Type
33
+	BoolType
34
+	IntType
35
+	UintType
36
+	NilType
37
+	ExtensionType
38
+
39
+	// pseudo-types provided
40
+	// by extensions
41
+
42
+	Complex64Type
43
+	Complex128Type
44
+	TimeType
45
+
46
+	_maxtype
47
+)
48
+
49
+// String implements fmt.Stringer
50
+func (t Type) String() string {
51
+	switch t {
52
+	case StrType:
53
+		return "str"
54
+	case BinType:
55
+		return "bin"
56
+	case MapType:
57
+		return "map"
58
+	case ArrayType:
59
+		return "array"
60
+	case Float64Type:
61
+		return "float64"
62
+	case Float32Type:
63
+		return "float32"
64
+	case BoolType:
65
+		return "bool"
66
+	case UintType:
67
+		return "uint"
68
+	case IntType:
69
+		return "int"
70
+	case ExtensionType:
71
+		return "ext"
72
+	case NilType:
73
+		return "nil"
74
+	default:
75
+		return "<invalid>"
76
+	}
77
+}
78
+
79
+func freeR(m *Reader) {
80
+	readerPool.Put(m)
81
+}
82
+
83
+// Unmarshaler is the interface fulfilled
84
+// by objects that know how to unmarshal
85
+// themselves from MessagePack.
86
+// UnmarshalMsg unmarshals the object
87
+// from binary, returing any leftover
88
+// bytes and any errors encountered.
89
+type Unmarshaler interface {
90
+	UnmarshalMsg([]byte) ([]byte, error)
91
+}
92
+
93
+// Decodable is the interface fulfilled
94
+// by objects that know how to read
95
+// themselves from a *Reader.
96
+type Decodable interface {
97
+	DecodeMsg(*Reader) error
98
+}
99
+
100
+// Decode decodes 'd' from 'r'.
101
+func Decode(r io.Reader, d Decodable) error {
102
+	rd := NewReader(r)
103
+	err := d.DecodeMsg(rd)
104
+	freeR(rd)
105
+	return err
106
+}
107
+
108
+// NewReader returns a *Reader that
109
+// reads from the provided reader. The
110
+// reader will be buffered.
111
+func NewReader(r io.Reader) *Reader {
112
+	p := readerPool.Get().(*Reader)
113
+	if p.r == nil {
114
+		p.r = fwd.NewReader(r)
115
+	} else {
116
+		p.r.Reset(r)
117
+	}
118
+	return p
119
+}
120
+
121
+// NewReaderSize returns a *Reader with a buffer of the given size.
122
+// (This is vastly preferable to passing the decoder a reader that is already buffered.)
123
+func NewReaderSize(r io.Reader, sz int) *Reader {
124
+	return &Reader{r: fwd.NewReaderSize(r, sz)}
125
+}
126
+
127
+// Reader wraps an io.Reader and provides
128
+// methods to read MessagePack-encoded values
129
+// from it. Readers are buffered.
130
+type Reader struct {
131
+	r       *fwd.Reader
132
+	scratch []byte
133
+}
134
+
135
+// Read implements `io.Reader`
136
+func (m *Reader) Read(p []byte) (int, error) {
137
+	return m.r.Read(p)
138
+}
139
+
140
+// ReadFull implements `io.ReadFull`
141
+func (m *Reader) ReadFull(p []byte) (int, error) {
142
+	return m.r.ReadFull(p)
143
+}
144
+
145
+// Reset resets the underlying reader.
146
+func (m *Reader) Reset(r io.Reader) { m.r.Reset(r) }
147
+
148
+// Buffered returns the number of bytes currently in the read buffer.
149
+func (m *Reader) Buffered() int { return m.r.Buffered() }
150
+
151
+// BufferSize returns the capacity of the read buffer.
152
+func (m *Reader) BufferSize() int { return m.r.BufferSize() }
153
+
154
+// NextType returns the next object type to be decoded.
155
+func (m *Reader) NextType() (Type, error) {
156
+	p, err := m.r.Peek(1)
157
+	if err != nil {
158
+		return InvalidType, err
159
+	}
160
+	t := getType(p[0])
161
+	if t == InvalidType {
162
+		return t, InvalidPrefixError(p[0])
163
+	}
164
+	if t == ExtensionType {
165
+		v, err := m.peekExtensionType()
166
+		if err != nil {
167
+			return InvalidType, err
168
+		}
169
+		switch v {
170
+		case Complex64Extension:
171
+			return Complex64Type, nil
172
+		case Complex128Extension:
173
+			return Complex128Type, nil
174
+		case TimeExtension:
175
+			return TimeType, nil
176
+		}
177
+	}
178
+	return t, nil
179
+}
180
+
181
+// IsNil returns whether or not
182
+// the next byte is a null messagepack byte
183
+func (m *Reader) IsNil() bool {
184
+	p, err := m.r.Peek(1)
185
+	return err == nil && p[0] == mnil
186
+}
187
+
188
+// returns (obj size, obj elements, error)
189
+// only maps and arrays have non-zero obj elements
190
+//
191
+// use uintptr b/c it's guaranteed to be large enough
192
+// to hold whatever we can fit in memory.
193
+func getNextSize(r *fwd.Reader) (uintptr, uintptr, error) {
194
+	b, err := r.Peek(1)
195
+	if err != nil {
196
+		return 0, 0, err
197
+	}
198
+	lead := b[0]
199
+	spec := &sizes[lead]
200
+	size, mode := spec.size, spec.extra
201
+	if size == 0 {
202
+		return 0, 0, InvalidPrefixError(lead)
203
+	}
204
+	if mode >= 0 {
205
+		return uintptr(size), uintptr(mode), nil
206
+	}
207
+	b, err = r.Peek(int(size))
208
+	if err != nil {
209
+		return 0, 0, err
210
+	}
211
+	switch mode {
212
+	case extra8:
213
+		return uintptr(size) + uintptr(b[1]), 0, nil
214
+	case extra16:
215
+		return uintptr(size) + uintptr(big.Uint16(b[1:])), 0, nil
216
+	case extra32:
217
+		return uintptr(size) + uintptr(big.Uint32(b[1:])), 0, nil
218
+	case map16v:
219
+		return uintptr(size), 2 * uintptr(big.Uint16(b[1:])), nil
220
+	case map32v:
221
+		return uintptr(size), 2 * uintptr(big.Uint32(b[1:])), nil
222
+	case array16v:
223
+		return uintptr(size), uintptr(big.Uint16(b[1:])), nil
224
+	case array32v:
225
+		return uintptr(size), uintptr(big.Uint32(b[1:])), nil
226
+	default:
227
+		return 0, 0, fatal
228
+	}
229
+}
230
+
231
+// Skip skips over the next object, regardless of
232
+// its type. If it is an array or map, the whole array
233
+// or map will be skipped.
234
+func (m *Reader) Skip() error {
235
+	var (
236
+		v   uintptr // bytes
237
+		o   uintptr // objects
238
+		err error
239
+		p   []byte
240
+	)
241
+
242
+	// we can use the faster
243
+	// method if we have enough
244
+	// buffered data
245
+	if m.r.Buffered() >= 5 {
246
+		p, err = m.r.Peek(5)
247
+		if err != nil {
248
+			return err
249
+		}
250
+		v, o, err = getSize(p)
251
+		if err != nil {
252
+			return err
253
+		}
254
+	} else {
255
+		v, o, err = getNextSize(m.r)
256
+		if err != nil {
257
+			return err
258
+		}
259
+	}
260
+
261
+	// 'v' is always non-zero
262
+	// if err == nil
263
+	_, err = m.r.Skip(int(v))
264
+	if err != nil {
265
+		return err
266
+	}
267
+
268
+	// for maps and slices, skip elements
269
+	for x := uintptr(0); x < o; x++ {
270
+		err = m.Skip()
271
+		if err != nil {
272
+			return err
273
+		}
274
+	}
275
+	return nil
276
+}
277
+
278
+// ReadMapHeader reads the next object
279
+// as a map header and returns the size
280
+// of the map and the number of bytes written.
281
+// It will return a TypeError{} if the next
282
+// object is not a map.
283
+func (m *Reader) ReadMapHeader() (sz uint32, err error) {
284
+	var p []byte
285
+	var lead byte
286
+	p, err = m.r.Peek(1)
287
+	if err != nil {
288
+		return
289
+	}
290
+	lead = p[0]
291
+	if isfixmap(lead) {
292
+		sz = uint32(rfixmap(lead))
293
+		_, err = m.r.Skip(1)
294
+		return
295
+	}
296
+	switch lead {
297
+	case mmap16:
298
+		p, err = m.r.Next(3)
299
+		if err != nil {
300
+			return
301
+		}
302
+		sz = uint32(big.Uint16(p[1:]))
303
+		return
304
+	case mmap32:
305
+		p, err = m.r.Next(5)
306
+		if err != nil {
307
+			return
308
+		}
309
+		sz = big.Uint32(p[1:])
310
+		return
311
+	default:
312
+		err = badPrefix(MapType, lead)
313
+		return
314
+	}
315
+}
316
+
317
+// ReadMapKey reads either a 'str' or 'bin' field from
318
+// the reader and returns the value as a []byte. It uses
319
+// scratch for storage if it is large enough.
320
+func (m *Reader) ReadMapKey(scratch []byte) ([]byte, error) {
321
+	out, err := m.ReadStringAsBytes(scratch)
322
+	if err != nil {
323
+		if tperr, ok := err.(TypeError); ok && tperr.Encoded == BinType {
324
+			return m.ReadBytes(scratch)
325
+		}
326
+		return nil, err
327
+	}
328
+	return out, nil
329
+}
330
+
331
+// MapKeyPtr returns a []byte pointing to the contents
332
+// of a valid map key. The key cannot be empty, and it
333
+// must be shorter than the total buffer size of the
334
+// *Reader. Additionally, the returned slice is only
335
+// valid until the next *Reader method call. Users
336
+// should exercise extreme care when using this
337
+// method; writing into the returned slice may
338
+// corrupt future reads.
339
+func (m *Reader) ReadMapKeyPtr() ([]byte, error) {
340
+	p, err := m.r.Peek(1)
341
+	if err != nil {
342
+		return nil, err
343
+	}
344
+	lead := p[0]
345
+	var read int
346
+	if isfixstr(lead) {
347
+		read = int(rfixstr(lead))
348
+		m.r.Skip(1)
349
+		goto fill
350
+	}
351
+	switch lead {
352
+	case mstr8, mbin8:
353
+		p, err = m.r.Next(2)
354
+		if err != nil {
355
+			return nil, err
356
+		}
357
+		read = int(p[1])
358
+	case mstr16, mbin16:
359
+		p, err = m.r.Next(3)
360
+		if err != nil {
361
+			return nil, err
362
+		}
363
+		read = int(big.Uint16(p[1:]))
364
+	case mstr32, mbin32:
365
+		p, err = m.r.Next(5)
366
+		if err != nil {
367
+			return nil, err
368
+		}
369
+		read = int(big.Uint32(p[1:]))
370
+	default:
371
+		return nil, badPrefix(StrType, lead)
372
+	}
373
+fill:
374
+	if read == 0 {
375
+		return nil, ErrShortBytes
376
+	}
377
+	return m.r.Next(read)
378
+}
379
+
380
+// ReadArrayHeader reads the next object as an
381
+// array header and returns the size of the array
382
+// and the number of bytes read.
383
+func (m *Reader) ReadArrayHeader() (sz uint32, err error) {
384
+	var lead byte
385
+	var p []byte
386
+	p, err = m.r.Peek(1)
387
+	if err != nil {
388
+		return
389
+	}
390
+	lead = p[0]
391
+	if isfixarray(lead) {
392
+		sz = uint32(rfixarray(lead))
393
+		_, err = m.r.Skip(1)
394
+		return
395
+	}
396
+	switch lead {
397
+	case marray16:
398
+		p, err = m.r.Next(3)
399
+		if err != nil {
400
+			return
401
+		}
402
+		sz = uint32(big.Uint16(p[1:]))
403
+		return
404
+
405
+	case marray32:
406
+		p, err = m.r.Next(5)
407
+		if err != nil {
408
+			return
409
+		}
410
+		sz = big.Uint32(p[1:])
411
+		return
412
+
413
+	default:
414
+		err = badPrefix(ArrayType, lead)
415
+		return
416
+	}
417
+}
418
+
419
+// ReadNil reads a 'nil' MessagePack byte from the reader
420
+func (m *Reader) ReadNil() error {
421
+	p, err := m.r.Peek(1)
422
+	if err != nil {
423
+		return err
424
+	}
425
+	if p[0] != mnil {
426
+		return badPrefix(NilType, p[0])
427
+	}
428
+	_, err = m.r.Skip(1)
429
+	return err
430
+}
431
+
432
+// ReadFloat64 reads a float64 from the reader.
433
+// (If the value on the wire is encoded as a float32,
434
+// it will be up-cast to a float64.)
435
+func (m *Reader) ReadFloat64() (f float64, err error) {
436
+	var p []byte
437
+	p, err = m.r.Peek(9)
438
+	if err != nil {
439
+		// we'll allow a coversion from float32 to float64,
440
+		// since we don't lose any precision
441
+		if err == io.EOF && len(p) > 0 && p[0] == mfloat32 {
442
+			ef, err := m.ReadFloat32()
443
+			return float64(ef), err
444
+		}
445
+		return
446
+	}
447
+	if p[0] != mfloat64 {
448
+		// see above
449
+		if p[0] == mfloat32 {
450
+			ef, err := m.ReadFloat32()
451
+			return float64(ef), err
452
+		}
453
+		err = badPrefix(Float64Type, p[0])
454
+		return
455
+	}
456
+	f = math.Float64frombits(getMuint64(p))
457
+	_, err = m.r.Skip(9)
458
+	return
459
+}
460
+
461
+// ReadFloat32 reads a float32 from the reader
462
+func (m *Reader) ReadFloat32() (f float32, err error) {
463
+	var p []byte
464
+	p, err = m.r.Peek(5)
465
+	if err != nil {
466
+		return
467
+	}
468
+	if p[0] != mfloat32 {
469
+		err = badPrefix(Float32Type, p[0])
470
+		return
471
+	}
472
+	f = math.Float32frombits(getMuint32(p))
473
+	_, err = m.r.Skip(5)
474
+	return
475
+}
476
+
477
+// ReadBool reads a bool from the reader
478
+func (m *Reader) ReadBool() (b bool, err error) {
479
+	var p []byte
480
+	p, err = m.r.Peek(1)
481
+	if err != nil {
482
+		return
483
+	}
484
+	switch p[0] {
485
+	case mtrue:
486
+		b = true
487
+	case mfalse:
488
+	default:
489
+		err = badPrefix(BoolType, p[0])
490
+		return
491
+	}
492
+	_, err = m.r.Skip(1)
493
+	return
494
+}
495
+
496
+// ReadInt64 reads an int64 from the reader
497
+func (m *Reader) ReadInt64() (i int64, err error) {
498
+	var p []byte
499
+	var lead byte
500
+	p, err = m.r.Peek(1)
501
+	if err != nil {
502
+		return
503
+	}
504
+	lead = p[0]
505
+
506
+	if isfixint(lead) {
507
+		i = int64(rfixint(lead))
508
+		_, err = m.r.Skip(1)
509
+		return
510
+	} else if isnfixint(lead) {
511
+		i = int64(rnfixint(lead))
512
+		_, err = m.r.Skip(1)
513
+		return
514
+	}
515
+
516
+	switch lead {
517
+	case mint8:
518
+		p, err = m.r.Next(2)
519
+		if err != nil {
520
+			return
521
+		}
522
+		i = int64(getMint8(p))
523
+		return
524
+
525
+	case mint16:
526
+		p, err = m.r.Next(3)
527
+		if err != nil {
528
+			return
529
+		}
530
+		i = int64(getMint16(p))
531
+		return
532
+
533
+	case mint32:
534
+		p, err = m.r.Next(5)
535
+		if err != nil {
536
+			return
537
+		}
538
+		i = int64(getMint32(p))
539
+		return
540
+
541
+	case mint64:
542
+		p, err = m.r.Next(9)
543
+		if err != nil {
544
+			return
545
+		}
546
+		i = getMint64(p)
547
+		return
548
+
549
+	default:
550
+		err = badPrefix(IntType, lead)
551
+		return
552
+	}
553
+}
554
+
555
+// ReadInt32 reads an int32 from the reader
556
+func (m *Reader) ReadInt32() (i int32, err error) {
557
+	var in int64
558
+	in, err = m.ReadInt64()
559
+	if in > math.MaxInt32 || in < math.MinInt32 {
560
+		err = IntOverflow{Value: in, FailedBitsize: 32}
561
+		return
562
+	}
563
+	i = int32(in)
564
+	return
565
+}
566
+
567
+// ReadInt16 reads an int16 from the reader
568
+func (m *Reader) ReadInt16() (i int16, err error) {
569
+	var in int64
570
+	in, err = m.ReadInt64()
571
+	if in > math.MaxInt16 || in < math.MinInt16 {
572
+		err = IntOverflow{Value: in, FailedBitsize: 16}
573
+		return
574
+	}
575
+	i = int16(in)
576
+	return
577
+}
578
+
579
+// ReadInt8 reads an int8 from the reader
580
+func (m *Reader) ReadInt8() (i int8, err error) {
581
+	var in int64
582
+	in, err = m.ReadInt64()
583
+	if in > math.MaxInt8 || in < math.MinInt8 {
584
+		err = IntOverflow{Value: in, FailedBitsize: 8}
585
+		return
586
+	}
587
+	i = int8(in)
588
+	return
589
+}
590
+
591
+// ReadInt reads an int from the reader
592
+func (m *Reader) ReadInt() (i int, err error) {
593
+	if smallint {
594
+		var in int32
595
+		in, err = m.ReadInt32()
596
+		i = int(in)
597
+		return
598
+	}
599
+	var in int64
600
+	in, err = m.ReadInt64()
601
+	i = int(in)
602
+	return
603
+}
604
+
605
+// ReadUint64 reads a uint64 from the reader
606
+func (m *Reader) ReadUint64() (u uint64, err error) {
607
+	var p []byte
608
+	var lead byte
609
+	p, err = m.r.Peek(1)
610
+	if err != nil {
611
+		return
612
+	}
613
+	lead = p[0]
614
+	if isfixint(lead) {
615
+		u = uint64(rfixint(lead))
616
+		_, err = m.r.Skip(1)
617
+		return
618
+	}
619
+	switch lead {
620
+	case muint8:
621
+		p, err = m.r.Next(2)
622
+		if err != nil {
623
+			return
624
+		}
625
+		u = uint64(getMuint8(p))
626
+		return
627
+
628
+	case muint16:
629
+		p, err = m.r.Next(3)
630
+		if err != nil {
631
+			return
632
+		}
633
+		u = uint64(getMuint16(p))
634
+		return
635
+
636
+	case muint32:
637
+		p, err = m.r.Next(5)
638
+		if err != nil {
639
+			return
640
+		}
641
+		u = uint64(getMuint32(p))
642
+		return
643
+
644
+	case muint64:
645
+		p, err = m.r.Next(9)
646
+		if err != nil {
647
+			return
648
+		}
649
+		u = getMuint64(p)
650
+		return
651
+
652
+	default:
653
+		err = badPrefix(UintType, lead)
654
+		return
655
+
656
+	}
657
+}
658
+
659
+// ReadUint32 reads a uint32 from the reader
660
+func (m *Reader) ReadUint32() (u uint32, err error) {
661
+	var in uint64
662
+	in, err = m.ReadUint64()
663
+	if in > math.MaxUint32 {
664
+		err = UintOverflow{Value: in, FailedBitsize: 32}
665
+		return
666
+	}
667
+	u = uint32(in)
668
+	return
669
+}
670
+
671
+// ReadUint16 reads a uint16 from the reader
672
+func (m *Reader) ReadUint16() (u uint16, err error) {
673
+	var in uint64
674
+	in, err = m.ReadUint64()
675
+	if in > math.MaxUint16 {
676
+		err = UintOverflow{Value: in, FailedBitsize: 16}
677
+		return
678
+	}
679
+	u = uint16(in)
680
+	return
681
+}
682
+
683
+// ReadUint8 reads a uint8 from the reader
684
+func (m *Reader) ReadUint8() (u uint8, err error) {
685
+	var in uint64
686
+	in, err = m.ReadUint64()
687
+	if in > math.MaxUint8 {
688
+		err = UintOverflow{Value: in, FailedBitsize: 8}
689
+		return
690
+	}
691
+	u = uint8(in)
692
+	return
693
+}
694
+
695
+// ReadUint reads a uint from the reader
696
+func (m *Reader) ReadUint() (u uint, err error) {
697
+	if smallint {
698
+		var un uint32
699
+		un, err = m.ReadUint32()
700
+		u = uint(un)
701
+		return
702
+	}
703
+	var un uint64
704
+	un, err = m.ReadUint64()
705
+	u = uint(un)
706
+	return
707
+}
708
+
709
+func (m *Reader) ReadByte() (b byte, err error) {
710
+	var in uint64
711
+	in, err = m.ReadUint64()
712
+	if in > math.MaxUint8 {
713
+		err = UintOverflow{Value: in, FailedBitsize: 8}
714
+		return
715
+	}
716
+	b = byte(in)
717
+	return
718
+}
719
+
720
+// ReadBytes reads a MessagePack 'bin' object
721
+// from the reader and returns its value. It may
722
+// use 'scratch' for storage if it is non-nil.
723
+func (m *Reader) ReadBytes(scratch []byte) (b []byte, err error) {
724
+	var p []byte
725
+	var lead byte
726
+	p, err = m.r.Peek(2)
727
+	if err != nil {
728
+		return
729
+	}
730
+	lead = p[0]
731
+	var read int64
732
+	switch lead {
733
+	case mbin8:
734
+		read = int64(p[1])
735
+		m.r.Skip(2)
736
+	case mbin16:
737
+		p, err = m.r.Next(3)
738
+		if err != nil {
739
+			return
740
+		}
741
+		read = int64(big.Uint16(p[1:]))
742
+	case mbin32:
743
+		p, err = m.r.Next(5)
744
+		if err != nil {
745
+			return
746
+		}
747
+		read = int64(big.Uint32(p[1:]))
748
+	default:
749
+		err = badPrefix(BinType, lead)
750
+		return
751
+	}
752
+	if int64(cap(scratch)) < read {
753
+		b = make([]byte, read)
754
+	} else {
755
+		b = scratch[0:read]
756
+	}
757
+	_, err = m.r.ReadFull(b)
758
+	return
759
+}
760
+
761
+// ReadExactBytes reads a MessagePack 'bin'-encoded
762
+// object off of the wire into the provided slice. An
763
+// ArrayError will be returned if the object is not
764
+// exactly the length of the input slice.
765
+func (m *Reader) ReadExactBytes(into []byte) error {
766
+	p, err := m.r.Peek(2)
767
+	if err != nil {
768
+		return err
769
+	}
770
+	lead := p[0]
771
+	var read int64 // bytes to read
772
+	var skip int   // prefix size to skip
773
+	switch lead {
774
+	case mbin8:
775
+		read = int64(p[1])
776
+		skip = 2
777
+	case mbin16:
778
+		p, err = m.r.Peek(3)
779
+		if err != nil {
780
+			return err
781
+		}
782
+		read = int64(big.Uint16(p[1:]))
783
+		skip = 3
784
+	case mbin32:
785
+		p, err = m.r.Peek(5)
786
+		if err != nil {
787
+			return err
788
+		}
789
+		read = int64(big.Uint32(p[1:]))
790
+		skip = 5
791
+	default:
792
+		return badPrefix(BinType, lead)
793
+	}
794
+	if read != int64(len(into)) {
795
+		return ArrayError{Wanted: uint32(len(into)), Got: uint32(read)}
796
+	}
797
+	m.r.Skip(skip)
798
+	_, err = m.r.ReadFull(into)
799
+	return err
800
+}
801
+
802
+// ReadStringAsBytes reads a MessagePack 'str' (utf-8) string
803
+// and returns its value as bytes. It may use 'scratch' for storage
804
+// if it is non-nil.
805
+func (m *Reader) ReadStringAsBytes(scratch []byte) (b []byte, err error) {
806
+	var p []byte
807
+	var lead byte
808
+	p, err = m.r.Peek(1)
809
+	if err != nil {
810
+		return
811
+	}
812
+	lead = p[0]
813
+	var read int64
814
+
815
+	if isfixstr(lead) {
816
+		read = int64(rfixstr(lead))
817
+		m.r.Skip(1)
818
+		goto fill
819
+	}
820
+
821
+	switch lead {
822
+	case mstr8:
823
+		p, err = m.r.Next(2)
824
+		if err != nil {
825
+			return
826
+		}
827
+		read = int64(uint8(p[1]))
828
+	case mstr16:
829
+		p, err = m.r.Next(3)
830
+		if err != nil {
831
+			return
832
+		}
833
+		read = int64(big.Uint16(p[1:]))
834
+	case mstr32:
835
+		p, err = m.r.Next(5)
836
+		if err != nil {
837
+			return
838
+		}
839
+		read = int64(big.Uint32(p[1:]))
840
+	default:
841
+		err = badPrefix(StrType, lead)
842
+		return
843
+	}
844
+fill:
845
+	if int64(cap(scratch)) < read {
846
+		b = make([]byte, read)
847
+	} else {
848
+		b = scratch[0:read]
849
+	}
850
+	_, err = m.r.ReadFull(b)
851
+	return
852
+}
853
+
854
+// ReadString reads a utf-8 string from the reader
855
+func (m *Reader) ReadString() (s string, err error) {
856
+	var p []byte
857
+	var lead byte
858
+	var read int64
859
+	p, err = m.r.Peek(1)
860
+	if err != nil {
861
+		return
862
+	}
863
+	lead = p[0]
864
+
865
+	if isfixstr(lead) {
866
+		read = int64(rfixstr(lead))
867
+		m.r.Skip(1)
868
+		goto fill
869
+	}
870
+
871
+	switch lead {
872
+	case mstr8:
873
+		p, err = m.r.Next(2)
874
+		if err != nil {
875
+			return
876
+		}
877
+		read = int64(uint8(p[1]))
878
+	case mstr16:
879
+		p, err = m.r.Next(3)
880
+		if err != nil {
881
+			return
882
+		}
883
+		read = int64(big.Uint16(p[1:]))
884
+	case mstr32:
885
+		p, err = m.r.Next(5)
886
+		if err != nil {
887
+			return
888
+		}
889
+		read = int64(big.Uint32(p[1:]))
890
+	default:
891
+		err = badPrefix(StrType, lead)
892
+		return
893
+	}
894
+fill:
895
+	if read == 0 {
896
+		s, err = "", nil
897
+		return
898
+	}
899
+	// reading into the memory
900
+	// that will become the string
901
+	// itself has vastly superior
902
+	// worst-case performance, because
903
+	// the reader buffer doesn't have
904
+	// to be large enough to hold the string.
905
+	// the idea here is to make it more
906
+	// difficult for someone malicious
907
+	// to cause the system to run out of
908
+	// memory by sending very large strings.
909
+	//
910
+	// NOTE: this works because the argument
911
+	// passed to (*fwd.Reader).ReadFull escapes
912
+	// to the heap; its argument may, in turn,
913
+	// be passed to the underlying reader, and
914
+	// thus escape analysis *must* conclude that
915
+	// 'out' escapes.
916
+	out := make([]byte, read)
917
+	_, err = m.r.ReadFull(out)
918
+	if err != nil {
919
+		return
920
+	}
921
+	s = UnsafeString(out)
922
+	return
923
+}
924
+
925
+// ReadComplex64 reads a complex64 from the reader
926
+func (m *Reader) ReadComplex64() (f complex64, err error) {
927
+	var p []byte
928
+	p, err = m.r.Peek(10)
929
+	if err != nil {
930
+		return
931
+	}
932
+	if p[0] != mfixext8 {
933
+		err = badPrefix(Complex64Type, p[0])
934
+		return
935
+	}
936
+	if int8(p[1]) != Complex64Extension {
937
+		err = errExt(int8(p[1]), Complex64Extension)
938
+		return
939
+	}
940
+	f = complex(math.Float32frombits(big.Uint32(p[2:])),
941
+		math.Float32frombits(big.Uint32(p[6:])))
942
+	_, err = m.r.Skip(10)
943
+	return
944
+}
945
+
946
+// ReadComplex128 reads a complex128 from the reader
947
+func (m *Reader) ReadComplex128() (f complex128, err error) {
948
+	var p []byte
949
+	p, err = m.r.Peek(18)
950
+	if err != nil {
951
+		return
952
+	}
953
+	if p[0] != mfixext16 {
954
+		err = badPrefix(Complex128Type, p[0])
955
+		return
956
+	}
957
+	if int8(p[1]) != Complex128Extension {
958
+		err = errExt(int8(p[1]), Complex128Extension)
959
+		return
960
+	}
961
+	f = complex(math.Float64frombits(big.Uint64(p[2:])),
962
+		math.Float64frombits(big.Uint64(p[10:])))
963
+	_, err = m.r.Skip(18)
964
+	return
965
+}
966
+
967
+// ReadMapStrIntf reads a MessagePack map into a map[string]interface{}.
968
+// (You must pass a non-nil map into the function.)
969
+func (m *Reader) ReadMapStrIntf(mp map[string]interface{}) (err error) {
970
+	var sz uint32
971
+	sz, err = m.ReadMapHeader()
972
+	if err != nil {
973
+		return
974
+	}
975
+	for key := range mp {
976
+		delete(mp, key)
977
+	}
978
+	for i := uint32(0); i < sz; i++ {
979
+		var key string
980
+		var val interface{}
981
+		key, err = m.ReadString()
982
+		if err != nil {
983
+			return
984
+		}
985
+		val, err = m.ReadIntf()
986
+		if err != nil {
987
+			return
988
+		}
989
+		mp[key] = val
990
+	}
991
+	return
992
+}
993
+
994
+// ReadTime reads a time.Time object from the reader.
995
+// The returned time's location will be set to time.Local.
996
+func (m *Reader) ReadTime() (t time.Time, err error) {
997
+	var p []byte
998
+	p, err = m.r.Peek(15)
999
+	if err != nil {
1000
+		return
1001
+	}
1002
+	if p[0] != mext8 || p[1] != 12 {
1003
+		err = badPrefix(TimeType, p[0])
1004
+		return
1005
+	}
1006
+	if int8(p[2]) != TimeExtension {
1007
+		err = errExt(int8(p[2]), TimeExtension)
1008
+		return
1009
+	}
1010
+	sec, nsec := getUnix(p[3:])
1011
+	t = time.Unix(sec, int64(nsec)).Local()
1012
+	_, err = m.r.Skip(15)
1013
+	return
1014
+}
1015
+
1016
+// ReadIntf reads out the next object as a raw interface{}.
1017
+// Arrays are decoded as []interface{}, and maps are decoded
1018
+// as map[string]interface{}. Integers are decoded as int64
1019
+// and unsigned integers are decoded as uint64.
1020
+func (m *Reader) ReadIntf() (i interface{}, err error) {
1021
+	var t Type
1022
+	t, err = m.NextType()
1023
+	if err != nil {
1024
+		return
1025
+	}
1026
+	switch t {
1027
+	case BoolType:
1028
+		i, err = m.ReadBool()
1029
+		return
1030
+
1031
+	case IntType:
1032
+		i, err = m.ReadInt64()
1033
+		return
1034
+
1035
+	case UintType:
1036
+		i, err = m.ReadUint64()
1037
+		return
1038
+
1039
+	case BinType:
1040
+		i, err = m.ReadBytes(nil)
1041
+		return
1042
+
1043
+	case StrType:
1044
+		i, err = m.ReadString()
1045
+		return
1046
+
1047
+	case Complex64Type:
1048
+		i, err = m.ReadComplex64()
1049
+		return
1050
+
1051
+	case Complex128Type:
1052
+		i, err = m.ReadComplex128()
1053
+		return
1054
+
1055
+	case TimeType:
1056
+		i, err = m.ReadTime()
1057
+		return
1058
+
1059
+	case ExtensionType:
1060
+		var t int8
1061
+		t, err = m.peekExtensionType()
1062
+		if err != nil {
1063
+			return
1064
+		}
1065
+		f, ok := extensionReg[t]
1066
+		if ok {
1067
+			e := f()
1068
+			err = m.ReadExtension(e)
1069
+			i = e
1070
+			return
1071
+		}
1072
+		var e RawExtension
1073
+		e.Type = t
1074
+		err = m.ReadExtension(&e)
1075
+		i = &e
1076
+		return
1077
+
1078
+	case MapType:
1079
+		mp := make(map[string]interface{})
1080
+		err = m.ReadMapStrIntf(mp)
1081
+		i = mp
1082
+		return
1083
+
1084
+	case NilType:
1085
+		err = m.ReadNil()
1086
+		i = nil
1087
+		return
1088
+
1089
+	case Float32Type:
1090
+		i, err = m.ReadFloat32()
1091
+		return
1092
+
1093
+	case Float64Type:
1094
+		i, err = m.ReadFloat64()
1095
+		return
1096
+
1097
+	case ArrayType:
1098
+		var sz uint32
1099
+		sz, err = m.ReadArrayHeader()
1100
+
1101
+		if err != nil {
1102
+			return
1103
+		}
1104
+		out := make([]interface{}, int(sz))
1105
+		for j := range out {
1106
+			out[j], err = m.ReadIntf()
1107
+			if err != nil {
1108
+				return
1109
+			}
1110
+		}
1111
+		i = out
1112
+		return
1113
+
1114
+	default:
1115
+		return nil, fatal // unreachable
1116
+	}
1117
+}
0 1118
new file mode 100644
... ...
@@ -0,0 +1,1073 @@
0
+package msgp
1
+
2
+import (
3
+	"bytes"
4
+	"encoding/binary"
5
+	"math"
6
+	"time"
7
+)
8
+
9
+var big = binary.BigEndian
10
+
11
+// NextType returns the type of the next
12
+// object in the slice. If the length
13
+// of the input is zero, it returns
14
+// InvalidType.
15
+func NextType(b []byte) Type {
16
+	if len(b) == 0 {
17
+		return InvalidType
18
+	}
19
+	spec := sizes[b[0]]
20
+	t := spec.typ
21
+	if t == ExtensionType && len(b) > int(spec.size) {
22
+		var tp int8
23
+		if spec.extra == constsize {
24
+			tp = int8(b[1])
25
+		} else {
26
+			tp = int8(b[spec.size-1])
27
+		}
28
+		switch tp {
29
+		case TimeExtension:
30
+			return TimeType
31
+		case Complex128Extension:
32
+			return Complex128Type
33
+		case Complex64Extension:
34
+			return Complex64Type
35
+		default:
36
+			return ExtensionType
37
+		}
38
+	}
39
+	return t
40
+}
41
+
42
+// IsNil returns true if len(b)>0 and
43
+// the leading byte is a 'nil' MessagePack
44
+// byte; false otherwise
45
+func IsNil(b []byte) bool {
46
+	if len(b) != 0 && b[0] == mnil {
47
+		return true
48
+	}
49
+	return false
50
+}
51
+
52
+// Raw is raw MessagePack.
53
+// Raw allows you to read and write
54
+// data without interpreting its contents.
55
+type Raw []byte
56
+
57
+// MarshalMsg implements msgp.Marshaler.
58
+// It appends the raw contents of 'raw'
59
+// to the provided byte slice. If 'raw'
60
+// is 0 bytes, 'nil' will be appended instead.
61
+func (r Raw) MarshalMsg(b []byte) ([]byte, error) {
62
+	i := len(r)
63
+	if i == 0 {
64
+		return AppendNil(b), nil
65
+	}
66
+	o, l := ensure(b, i)
67
+	copy(o[l:], []byte(r))
68
+	return o, nil
69
+}
70
+
71
+// UnmarshalMsg implements msgp.Unmarshaler.
72
+// It sets the contents of *Raw to be the next
73
+// object in the provided byte slice.
74
+func (r *Raw) UnmarshalMsg(b []byte) ([]byte, error) {
75
+	l := len(b)
76
+	out, err := Skip(b)
77
+	if err != nil {
78
+		return b, err
79
+	}
80
+	rlen := l - len(out)
81
+	if cap(*r) < rlen {
82
+		*r = make(Raw, rlen)
83
+	} else {
84
+		*r = (*r)[0:rlen]
85
+	}
86
+	copy(*r, b[:rlen])
87
+	return out, nil
88
+}
89
+
90
+// EncodeMsg implements msgp.Encodable.
91
+// It writes the raw bytes to the writer.
92
+// If r is empty, it writes 'nil' instead.
93
+func (r Raw) EncodeMsg(w *Writer) error {
94
+	if len(r) == 0 {
95
+		return w.WriteNil()
96
+	}
97
+	_, err := w.Write([]byte(r))
98
+	return err
99
+}
100
+
101
+// DecodeMsg implements msgp.Decodable.
102
+// It sets the value of *Raw to be the
103
+// next object on the wire.
104
+func (r *Raw) DecodeMsg(f *Reader) error {
105
+	*r = (*r)[:0]
106
+	return appendNext(f, (*[]byte)(r))
107
+}
108
+
109
+// Msgsize implements msgp.Sizer
110
+func (r Raw) Msgsize() int {
111
+	l := len(r)
112
+	if l == 0 {
113
+		return 1 // for 'nil'
114
+	}
115
+	return l
116
+}
117
+
118
+func appendNext(f *Reader, d *[]byte) error {
119
+	amt, o, err := getNextSize(f.r)
120
+	if err != nil {
121
+		return err
122
+	}
123
+	var i int
124
+	*d, i = ensure(*d, int(amt))
125
+	_, err = f.r.ReadFull((*d)[i:])
126
+	if err != nil {
127
+		return err
128
+	}
129
+	for o > 0 {
130
+		err = appendNext(f, d)
131
+		if err != nil {
132
+			return err
133
+		}
134
+		o--
135
+	}
136
+	return nil
137
+}
138
+
139
+// MarshalJSON implements json.Marshaler
140
+func (r *Raw) MarshalJSON() ([]byte, error) {
141
+	var buf bytes.Buffer
142
+	_, err := UnmarshalAsJSON(&buf, []byte(*r))
143
+	return buf.Bytes(), err
144
+}
145
+
146
+// ReadMapHeaderBytes reads a map header size
147
+// from 'b' and returns the remaining bytes.
148
+// Possible errors:
149
+// - ErrShortBytes (too few bytes)
150
+// - TypeError{} (not a map)
151
+func ReadMapHeaderBytes(b []byte) (sz uint32, o []byte, err error) {
152
+	l := len(b)
153
+	if l < 1 {
154
+		err = ErrShortBytes
155
+		return
156
+	}
157
+
158
+	lead := b[0]
159
+	if isfixmap(lead) {
160
+		sz = uint32(rfixmap(lead))
161
+		o = b[1:]
162
+		return
163
+	}
164
+
165
+	switch lead {
166
+	case mmap16:
167
+		if l < 3 {
168
+			err = ErrShortBytes
169
+			return
170
+		}
171
+		sz = uint32(big.Uint16(b[1:]))
172
+		o = b[3:]
173
+		return
174
+
175
+	case mmap32:
176
+		if l < 5 {
177
+			err = ErrShortBytes
178
+			return
179
+		}
180
+		sz = big.Uint32(b[1:])
181
+		o = b[5:]
182
+		return
183
+
184
+	default:
185
+		err = badPrefix(MapType, lead)
186
+		return
187
+	}
188
+}
189
+
190
+// ReadMapKeyZC attempts to read a map key
191
+// from 'b' and returns the key bytes and the remaining bytes
192
+// Possible errors:
193
+// - ErrShortBytes (too few bytes)
194
+// - TypeError{} (not a str or bin)
195
+func ReadMapKeyZC(b []byte) ([]byte, []byte, error) {
196
+	o, b, err := ReadStringZC(b)
197
+	if err != nil {
198
+		if tperr, ok := err.(TypeError); ok && tperr.Encoded == BinType {
199
+			return ReadBytesZC(b)
200
+		}
201
+		return nil, b, err
202
+	}
203
+	return o, b, nil
204
+}
205
+
206
+// ReadArrayHeaderBytes attempts to read
207
+// the array header size off of 'b' and return
208
+// the size and remaining bytes.
209
+// Possible errors:
210
+// - ErrShortBytes (too few bytes)
211
+// - TypeError{} (not an array)
212
+func ReadArrayHeaderBytes(b []byte) (sz uint32, o []byte, err error) {
213
+	if len(b) < 1 {
214
+		return 0, nil, ErrShortBytes
215
+	}
216
+	lead := b[0]
217
+	if isfixarray(lead) {
218
+		sz = uint32(rfixarray(lead))
219
+		o = b[1:]
220
+		return
221
+	}
222
+
223
+	switch lead {
224
+	case marray16:
225
+		if len(b) < 3 {
226
+			err = ErrShortBytes
227
+			return
228
+		}
229
+		sz = uint32(big.Uint16(b[1:]))
230
+		o = b[3:]
231
+		return
232
+
233
+	case marray32:
234
+		if len(b) < 5 {
235
+			err = ErrShortBytes
236
+			return
237
+		}
238
+		sz = big.Uint32(b[1:])
239
+		o = b[5:]
240
+		return
241
+
242
+	default:
243
+		err = badPrefix(ArrayType, lead)
244
+		return
245
+	}
246
+}
247
+
248
+// ReadNilBytes tries to read a "nil" byte
249
+// off of 'b' and return the remaining bytes.
250
+// Possible errors:
251
+// - ErrShortBytes (too few bytes)
252
+// - TypeError{} (not a 'nil')
253
+// - InvalidPrefixError
254
+func ReadNilBytes(b []byte) ([]byte, error) {
255
+	if len(b) < 1 {
256
+		return nil, ErrShortBytes
257
+	}
258
+	if b[0] != mnil {
259
+		return b, badPrefix(NilType, b[0])
260
+	}
261
+	return b[1:], nil
262
+}
263
+
264
+// ReadFloat64Bytes tries to read a float64
265
+// from 'b' and return the value and the remaining bytes.
266
+// Possible errors:
267
+// - ErrShortBytes (too few bytes)
268
+// - TypeError{} (not a float64)
269
+func ReadFloat64Bytes(b []byte) (f float64, o []byte, err error) {
270
+	if len(b) < 9 {
271
+		if len(b) >= 5 && b[0] == mfloat32 {
272
+			var tf float32
273
+			tf, o, err = ReadFloat32Bytes(b)
274
+			f = float64(tf)
275
+			return
276
+		}
277
+		err = ErrShortBytes
278
+		return
279
+	}
280
+
281
+	if b[0] != mfloat64 {
282
+		if b[0] == mfloat32 {
283
+			var tf float32
284
+			tf, o, err = ReadFloat32Bytes(b)
285
+			f = float64(tf)
286
+			return
287
+		}
288
+		err = badPrefix(Float64Type, b[0])
289
+		return
290
+	}
291
+
292
+	f = math.Float64frombits(getMuint64(b))
293
+	o = b[9:]
294
+	return
295
+}
296
+
297
+// ReadFloat32Bytes tries to read a float64
298
+// from 'b' and return the value and the remaining bytes.
299
+// Possible errors:
300
+// - ErrShortBytes (too few bytes)
301
+// - TypeError{} (not a float32)
302
+func ReadFloat32Bytes(b []byte) (f float32, o []byte, err error) {
303
+	if len(b) < 5 {
304
+		err = ErrShortBytes
305
+		return
306
+	}
307
+
308
+	if b[0] != mfloat32 {
309
+		err = TypeError{Method: Float32Type, Encoded: getType(b[0])}
310
+		return
311
+	}
312
+
313
+	f = math.Float32frombits(getMuint32(b))
314
+	o = b[5:]
315
+	return
316
+}
317
+
318
+// ReadBoolBytes tries to read a float64
319
+// from 'b' and return the value and the remaining bytes.
320
+// Possible errors:
321
+// - ErrShortBytes (too few bytes)
322
+// - TypeError{} (not a bool)
323
+func ReadBoolBytes(b []byte) (bool, []byte, error) {
324
+	if len(b) < 1 {
325
+		return false, b, ErrShortBytes
326
+	}
327
+	switch b[0] {
328
+	case mtrue:
329
+		return true, b[1:], nil
330
+	case mfalse:
331
+		return false, b[1:], nil
332
+	default:
333
+		return false, b, badPrefix(BoolType, b[0])
334
+	}
335
+}
336
+
337
+// ReadInt64Bytes tries to read an int64
338
+// from 'b' and return the value and the remaining bytes.
339
+// Possible errors:
340
+// - ErrShortBytes (too few bytes)
341
+// - TypeError (not a int)
342
+func ReadInt64Bytes(b []byte) (i int64, o []byte, err error) {
343
+	l := len(b)
344
+	if l < 1 {
345
+		return 0, nil, ErrShortBytes
346
+	}
347
+
348
+	lead := b[0]
349
+	if isfixint(lead) {
350
+		i = int64(rfixint(lead))
351
+		o = b[1:]
352
+		return
353
+	}
354
+	if isnfixint(lead) {
355
+		i = int64(rnfixint(lead))
356
+		o = b[1:]
357
+		return
358
+	}
359
+
360
+	switch lead {
361
+	case mint8:
362
+		if l < 2 {
363
+			err = ErrShortBytes
364
+			return
365
+		}
366
+		i = int64(getMint8(b))
367
+		o = b[2:]
368
+		return
369
+
370
+	case mint16:
371
+		if l < 3 {
372
+			err = ErrShortBytes
373
+			return
374
+		}
375
+		i = int64(getMint16(b))
376
+		o = b[3:]
377
+		return
378
+
379
+	case mint32:
380
+		if l < 5 {
381
+			err = ErrShortBytes
382
+			return
383
+		}
384
+		i = int64(getMint32(b))
385
+		o = b[5:]
386
+		return
387
+
388
+	case mint64:
389
+		if l < 9 {
390
+			err = ErrShortBytes
391
+			return
392
+		}
393
+		i = getMint64(b)
394
+		o = b[9:]
395
+		return
396
+
397
+	default:
398
+		err = badPrefix(IntType, lead)
399
+		return
400
+	}
401
+}
402
+
403
+// ReadInt32Bytes tries to read an int32
404
+// from 'b' and return the value and the remaining bytes.
405
+// Possible errors:
406
+// - ErrShortBytes (too few bytes)
407
+// - TypeError{} (not a int)
408
+// - IntOverflow{} (value doesn't fit in int32)
409
+func ReadInt32Bytes(b []byte) (int32, []byte, error) {
410
+	i, o, err := ReadInt64Bytes(b)
411
+	if i > math.MaxInt32 || i < math.MinInt32 {
412
+		return 0, o, IntOverflow{Value: i, FailedBitsize: 32}
413
+	}
414
+	return int32(i), o, err
415
+}
416
+
417
+// ReadInt16Bytes tries to read an int16
418
+// from 'b' and return the value and the remaining bytes.
419
+// Possible errors:
420
+// - ErrShortBytes (too few bytes)
421
+// - TypeError{} (not a int)
422
+// - IntOverflow{} (value doesn't fit in int16)
423
+func ReadInt16Bytes(b []byte) (int16, []byte, error) {
424
+	i, o, err := ReadInt64Bytes(b)
425
+	if i > math.MaxInt16 || i < math.MinInt16 {
426
+		return 0, o, IntOverflow{Value: i, FailedBitsize: 16}
427
+	}
428
+	return int16(i), o, err
429
+}
430
+
431
+// ReadInt8Bytes tries to read an int16
432
+// from 'b' and return the value and the remaining bytes.
433
+// Possible errors:
434
+// - ErrShortBytes (too few bytes)
435
+// - TypeError{} (not a int)
436
+// - IntOverflow{} (value doesn't fit in int8)
437
+func ReadInt8Bytes(b []byte) (int8, []byte, error) {
438
+	i, o, err := ReadInt64Bytes(b)
439
+	if i > math.MaxInt8 || i < math.MinInt8 {
440
+		return 0, o, IntOverflow{Value: i, FailedBitsize: 8}
441
+	}
442
+	return int8(i), o, err
443
+}
444
+
445
+// ReadIntBytes tries to read an int
446
+// from 'b' and return the value and the remaining bytes.
447
+// Possible errors:
448
+// - ErrShortBytes (too few bytes)
449
+// - TypeError{} (not a int)
450
+// - IntOverflow{} (value doesn't fit in int; 32-bit platforms only)
451
+func ReadIntBytes(b []byte) (int, []byte, error) {
452
+	if smallint {
453
+		i, b, err := ReadInt32Bytes(b)
454
+		return int(i), b, err
455
+	}
456
+	i, b, err := ReadInt64Bytes(b)
457
+	return int(i), b, err
458
+}
459
+
460
+// ReadUint64Bytes tries to read a uint64
461
+// from 'b' and return the value and the remaining bytes.
462
+// Possible errors:
463
+// - ErrShortBytes (too few bytes)
464
+// - TypeError{} (not a uint)
465
+func ReadUint64Bytes(b []byte) (u uint64, o []byte, err error) {
466
+	l := len(b)
467
+	if l < 1 {
468
+		return 0, nil, ErrShortBytes
469
+	}
470
+
471
+	lead := b[0]
472
+	if isfixint(lead) {
473
+		u = uint64(rfixint(lead))
474
+		o = b[1:]
475
+		return
476
+	}
477
+
478
+	switch lead {
479
+	case muint8:
480
+		if l < 2 {
481
+			err = ErrShortBytes
482
+			return
483
+		}
484
+		u = uint64(getMuint8(b))
485
+		o = b[2:]
486
+		return
487
+
488
+	case muint16:
489
+		if l < 3 {
490
+			err = ErrShortBytes
491
+			return
492
+		}
493
+		u = uint64(getMuint16(b))
494
+		o = b[3:]
495
+		return
496
+
497
+	case muint32:
498
+		if l < 5 {
499
+			err = ErrShortBytes
500
+			return
501
+		}
502
+		u = uint64(getMuint32(b))
503
+		o = b[5:]
504
+		return
505
+
506
+	case muint64:
507
+		if l < 9 {
508
+			err = ErrShortBytes
509
+			return
510
+		}
511
+		u = getMuint64(b)
512
+		o = b[9:]
513
+		return
514
+
515
+	default:
516
+		err = badPrefix(UintType, lead)
517
+		return
518
+	}
519
+}
520
+
521
+// ReadUint32Bytes tries to read a uint32
522
+// from 'b' and return the value and the remaining bytes.
523
+// Possible errors:
524
+// - ErrShortBytes (too few bytes)
525
+// - TypeError{} (not a uint)
526
+// - UintOverflow{} (value too large for uint32)
527
+func ReadUint32Bytes(b []byte) (uint32, []byte, error) {
528
+	v, o, err := ReadUint64Bytes(b)
529
+	if v > math.MaxUint32 {
530
+		return 0, nil, UintOverflow{Value: v, FailedBitsize: 32}
531
+	}
532
+	return uint32(v), o, err
533
+}
534
+
535
+// ReadUint16Bytes tries to read a uint16
536
+// from 'b' and return the value and the remaining bytes.
537
+// Possible errors:
538
+// - ErrShortBytes (too few bytes)
539
+// - TypeError{} (not a uint)
540
+// - UintOverflow{} (value too large for uint16)
541
+func ReadUint16Bytes(b []byte) (uint16, []byte, error) {
542
+	v, o, err := ReadUint64Bytes(b)
543
+	if v > math.MaxUint16 {
544
+		return 0, nil, UintOverflow{Value: v, FailedBitsize: 16}
545
+	}
546
+	return uint16(v), o, err
547
+}
548
+
549
+// ReadUint8Bytes tries to read a uint8
550
+// from 'b' and return the value and the remaining bytes.
551
+// Possible errors:
552
+// - ErrShortBytes (too few bytes)
553
+// - TypeError{} (not a uint)
554
+// - UintOverflow{} (value too large for uint8)
555
+func ReadUint8Bytes(b []byte) (uint8, []byte, error) {
556
+	v, o, err := ReadUint64Bytes(b)
557
+	if v > math.MaxUint8 {
558
+		return 0, nil, UintOverflow{Value: v, FailedBitsize: 8}
559
+	}
560
+	return uint8(v), o, err
561
+}
562
+
563
+// ReadUintBytes tries to read a uint
564
+// from 'b' and return the value and the remaining bytes.
565
+// Possible errors:
566
+// - ErrShortBytes (too few bytes)
567
+// - TypeError{} (not a uint)
568
+// - UintOverflow{} (value too large for uint; 32-bit platforms only)
569
+func ReadUintBytes(b []byte) (uint, []byte, error) {
570
+	if smallint {
571
+		u, b, err := ReadUint32Bytes(b)
572
+		return uint(u), b, err
573
+	}
574
+	u, b, err := ReadUint64Bytes(b)
575
+	return uint(u), b, err
576
+}
577
+
578
+// ReadByteBytes is analagous to ReadUint8Bytes
579
+func ReadByteBytes(b []byte) (byte, []byte, error) {
580
+	return ReadUint8Bytes(b)
581
+}
582
+
583
+// ReadBytesBytes reads a 'bin' object
584
+// from 'b' and returns its vaue and
585
+// the remaining bytes in 'b'.
586
+// Possible errors:
587
+// - ErrShortBytes (too few bytes)
588
+// - TypeError{} (not a 'bin' object)
589
+func ReadBytesBytes(b []byte, scratch []byte) (v []byte, o []byte, err error) {
590
+	return readBytesBytes(b, scratch, false)
591
+}
592
+
593
+func readBytesBytes(b []byte, scratch []byte, zc bool) (v []byte, o []byte, err error) {
594
+	l := len(b)
595
+	if l < 1 {
596
+		return nil, nil, ErrShortBytes
597
+	}
598
+
599
+	lead := b[0]
600
+	var read int
601
+	switch lead {
602
+	case mbin8:
603
+		if l < 2 {
604
+			err = ErrShortBytes
605
+			return
606
+		}
607
+
608
+		read = int(b[1])
609
+		b = b[2:]
610
+
611
+	case mbin16:
612
+		if l < 3 {
613
+			err = ErrShortBytes
614
+			return
615
+		}
616
+		read = int(big.Uint16(b[1:]))
617
+		b = b[3:]
618
+
619
+	case mbin32:
620
+		if l < 5 {
621
+			err = ErrShortBytes
622
+			return
623
+		}
624
+		read = int(big.Uint32(b[1:]))
625
+		b = b[5:]
626
+
627
+	default:
628
+		err = badPrefix(BinType, lead)
629
+		return
630
+	}
631
+
632
+	if len(b) < read {
633
+		err = ErrShortBytes
634
+		return
635
+	}
636
+
637
+	// zero-copy
638
+	if zc {
639
+		v = b[0:read]
640
+		o = b[read:]
641
+		return
642
+	}
643
+
644
+	if cap(scratch) >= read {
645
+		v = scratch[0:read]
646
+	} else {
647
+		v = make([]byte, read)
648
+	}
649
+
650
+	o = b[copy(v, b):]
651
+	return
652
+}
653
+
654
+// ReadBytesZC extracts the messagepack-encoded
655
+// binary field without copying. The returned []byte
656
+// points to the same memory as the input slice.
657
+// Possible errors:
658
+// - ErrShortBytes (b not long enough)
659
+// - TypeError{} (object not 'bin')
660
+func ReadBytesZC(b []byte) (v []byte, o []byte, err error) {
661
+	return readBytesBytes(b, nil, true)
662
+}
663
+
664
+func ReadExactBytes(b []byte, into []byte) (o []byte, err error) {
665
+	l := len(b)
666
+	if l < 1 {
667
+		err = ErrShortBytes
668
+		return
669
+	}
670
+
671
+	lead := b[0]
672
+	var read uint32
673
+	var skip int
674
+	switch lead {
675
+	case mbin8:
676
+		if l < 2 {
677
+			err = ErrShortBytes
678
+			return
679
+		}
680
+
681
+		read = uint32(b[1])
682
+		skip = 2
683
+
684
+	case mbin16:
685
+		if l < 3 {
686
+			err = ErrShortBytes
687
+			return
688
+		}
689
+		read = uint32(big.Uint16(b[1:]))
690
+		skip = 3
691
+
692
+	case mbin32:
693
+		if l < 5 {
694
+			err = ErrShortBytes
695
+			return
696
+		}
697
+		read = uint32(big.Uint32(b[1:]))
698
+		skip = 5
699
+
700
+	default:
701
+		err = badPrefix(BinType, lead)
702
+		return
703
+	}
704
+
705
+	if read != uint32(len(into)) {
706
+		err = ArrayError{Wanted: uint32(len(into)), Got: read}
707
+		return
708
+	}
709
+
710
+	o = b[skip+copy(into, b[skip:]):]
711
+	return
712
+}
713
+
714
+// ReadStringZC reads a messagepack string field
715
+// without copying. The returned []byte points
716
+// to the same memory as the input slice.
717
+// Possible errors:
718
+// - ErrShortBytes (b not long enough)
719
+// - TypeError{} (object not 'str')
720
+func ReadStringZC(b []byte) (v []byte, o []byte, err error) {
721
+	l := len(b)
722
+	if l < 1 {
723
+		return nil, nil, ErrShortBytes
724
+	}
725
+
726
+	lead := b[0]
727
+	var read int
728
+
729
+	if isfixstr(lead) {
730
+		read = int(rfixstr(lead))
731
+		b = b[1:]
732
+	} else {
733
+		switch lead {
734
+		case mstr8:
735
+			if l < 2 {
736
+				err = ErrShortBytes
737
+				return
738
+			}
739
+			read = int(b[1])
740
+			b = b[2:]
741
+
742
+		case mstr16:
743
+			if l < 3 {
744
+				err = ErrShortBytes
745
+				return
746
+			}
747
+			read = int(big.Uint16(b[1:]))
748
+			b = b[3:]
749
+
750
+		case mstr32:
751
+			if l < 5 {
752
+				err = ErrShortBytes
753
+				return
754
+			}
755
+			read = int(big.Uint32(b[1:]))
756
+			b = b[5:]
757
+
758
+		default:
759
+			err = TypeError{Method: StrType, Encoded: getType(lead)}
760
+			return
761
+		}
762
+	}
763
+
764
+	if len(b) < read {
765
+		err = ErrShortBytes
766
+		return
767
+	}
768
+
769
+	v = b[0:read]
770
+	o = b[read:]
771
+	return
772
+}
773
+
774
+// ReadStringBytes reads a 'str' object
775
+// from 'b' and returns its value and the
776
+// remaining bytes in 'b'.
777
+// Possible errors:
778
+// - ErrShortBytes (b not long enough)
779
+// - TypeError{} (not 'str' type)
780
+// - InvalidPrefixError
781
+func ReadStringBytes(b []byte) (string, []byte, error) {
782
+	v, o, err := ReadStringZC(b)
783
+	return string(v), o, err
784
+}
785
+
786
+// ReadComplex128Bytes reads a complex128
787
+// extension object from 'b' and returns the
788
+// remaining bytes.
789
+// Possible errors:
790
+// - ErrShortBytes (not enough bytes in 'b')
791
+// - TypeError{} (object not a complex128)
792
+// - InvalidPrefixError
793
+// - ExtensionTypeError{} (object an extension of the correct size, but not a complex128)
794
+func ReadComplex128Bytes(b []byte) (c complex128, o []byte, err error) {
795
+	if len(b) < 18 {
796
+		err = ErrShortBytes
797
+		return
798
+	}
799
+	if b[0] != mfixext16 {
800
+		err = badPrefix(Complex128Type, b[0])
801
+		return
802
+	}
803
+	if int8(b[1]) != Complex128Extension {
804
+		err = errExt(int8(b[1]), Complex128Extension)
805
+		return
806
+	}
807
+	c = complex(math.Float64frombits(big.Uint64(b[2:])),
808
+		math.Float64frombits(big.Uint64(b[10:])))
809
+	o = b[18:]
810
+	return
811
+}
812
+
813
+// ReadComplex64Bytes reads a complex64
814
+// extension object from 'b' and returns the
815
+// remaining bytes.
816
+// Possible errors:
817
+// - ErrShortBytes (not enough bytes in 'b')
818
+// - TypeError{} (object not a complex64)
819
+// - ExtensionTypeError{} (object an extension of the correct size, but not a complex64)
820
+func ReadComplex64Bytes(b []byte) (c complex64, o []byte, err error) {
821
+	if len(b) < 10 {
822
+		err = ErrShortBytes
823
+		return
824
+	}
825
+	if b[0] != mfixext8 {
826
+		err = badPrefix(Complex64Type, b[0])
827
+		return
828
+	}
829
+	if b[1] != Complex64Extension {
830
+		err = errExt(int8(b[1]), Complex64Extension)
831
+		return
832
+	}
833
+	c = complex(math.Float32frombits(big.Uint32(b[2:])),
834
+		math.Float32frombits(big.Uint32(b[6:])))
835
+	o = b[10:]
836
+	return
837
+}
838
+
839
+// ReadTimeBytes reads a time.Time
840
+// extension object from 'b' and returns the
841
+// remaining bytes.
842
+// Possible errors:
843
+// - ErrShortBytes (not enough bytes in 'b')
844
+// - TypeError{} (object not a complex64)
845
+// - ExtensionTypeError{} (object an extension of the correct size, but not a time.Time)
846
+func ReadTimeBytes(b []byte) (t time.Time, o []byte, err error) {
847
+	if len(b) < 15 {
848
+		err = ErrShortBytes
849
+		return
850
+	}
851
+	if b[0] != mext8 || b[1] != 12 {
852
+		err = badPrefix(TimeType, b[0])
853
+		return
854
+	}
855
+	if int8(b[2]) != TimeExtension {
856
+		err = errExt(int8(b[2]), TimeExtension)
857
+		return
858
+	}
859
+	sec, nsec := getUnix(b[3:])
860
+	t = time.Unix(sec, int64(nsec)).Local()
861
+	o = b[15:]
862
+	return
863
+}
864
+
865
+// ReadMapStrIntfBytes reads a map[string]interface{}
866
+// out of 'b' and returns the map and remaining bytes.
867
+// If 'old' is non-nil, the values will be read into that map.
868
+func ReadMapStrIntfBytes(b []byte, old map[string]interface{}) (v map[string]interface{}, o []byte, err error) {
869
+	var sz uint32
870
+	o = b
871
+	sz, o, err = ReadMapHeaderBytes(o)
872
+
873
+	if err != nil {
874
+		return
875
+	}
876
+
877
+	if old != nil {
878
+		for key := range old {
879
+			delete(old, key)
880
+		}
881
+		v = old
882
+	} else {
883
+		v = make(map[string]interface{}, int(sz))
884
+	}
885
+
886
+	for z := uint32(0); z < sz; z++ {
887
+		if len(o) < 1 {
888
+			err = ErrShortBytes
889
+			return
890
+		}
891
+		var key []byte
892
+		key, o, err = ReadMapKeyZC(o)
893
+		if err != nil {
894
+			return
895
+		}
896
+		var val interface{}
897
+		val, o, err = ReadIntfBytes(o)
898
+		if err != nil {
899
+			return
900
+		}
901
+		v[string(key)] = val
902
+	}
903
+	return
904
+}
905
+
906
+// ReadIntfBytes attempts to read
907
+// the next object out of 'b' as a raw interface{} and
908
+// return the remaining bytes.
909
+func ReadIntfBytes(b []byte) (i interface{}, o []byte, err error) {
910
+	if len(b) < 1 {
911
+		err = ErrShortBytes
912
+		return
913
+	}
914
+
915
+	k := NextType(b)
916
+
917
+	switch k {
918
+	case MapType:
919
+		i, o, err = ReadMapStrIntfBytes(b, nil)
920
+		return
921
+
922
+	case ArrayType:
923
+		var sz uint32
924
+		sz, b, err = ReadArrayHeaderBytes(b)
925
+		if err != nil {
926
+			return
927
+		}
928
+		j := make([]interface{}, int(sz))
929
+		i = j
930
+		for d := range j {
931
+			j[d], b, err = ReadIntfBytes(b)
932
+			if err != nil {
933
+				return
934
+			}
935
+		}
936
+		return
937
+
938
+	case Float32Type:
939
+		i, o, err = ReadFloat32Bytes(b)
940
+		return
941
+
942
+	case Float64Type:
943
+		i, o, err = ReadFloat64Bytes(b)
944
+		return
945
+
946
+	case IntType:
947
+		i, o, err = ReadInt64Bytes(b)
948
+		return
949
+
950
+	case UintType:
951
+		i, o, err = ReadUint64Bytes(b)
952
+		return
953
+
954
+	case BoolType:
955
+		i, o, err = ReadBoolBytes(b)
956
+		return
957
+
958
+	case TimeType:
959
+		i, o, err = ReadTimeBytes(b)
960
+		return
961
+
962
+	case Complex64Type:
963
+		i, o, err = ReadComplex64Bytes(b)
964
+		return
965
+
966
+	case Complex128Type:
967
+		i, o, err = ReadComplex128Bytes(b)
968
+		return
969
+
970
+	case ExtensionType:
971
+		var t int8
972
+		t, err = peekExtension(b)
973
+		if err != nil {
974
+			return
975
+		}
976
+		// use a user-defined extension,
977
+		// if it's been registered
978
+		f, ok := extensionReg[t]
979
+		if ok {
980
+			e := f()
981
+			o, err = ReadExtensionBytes(b, e)
982
+			i = e
983
+			return
984
+		}
985
+		// last resort is a raw extension
986
+		e := RawExtension{}
987
+		e.Type = int8(t)
988
+		o, err = ReadExtensionBytes(b, &e)
989
+		i = &e
990
+		return
991
+
992
+	case NilType:
993
+		o, err = ReadNilBytes(b)
994
+		return
995
+
996
+	case BinType:
997
+		i, o, err = ReadBytesBytes(b, nil)
998
+		return
999
+
1000
+	case StrType:
1001
+		i, o, err = ReadStringBytes(b)
1002
+		return
1003
+
1004
+	default:
1005
+		err = InvalidPrefixError(b[0])
1006
+		return
1007
+	}
1008
+}
1009
+
1010
+// Skip skips the next object in 'b' and
1011
+// returns the remaining bytes. If the object
1012
+// is a map or array, all of its elements
1013
+// will be skipped.
1014
+// Possible Errors:
1015
+// - ErrShortBytes (not enough bytes in b)
1016
+// - InvalidPrefixError (bad encoding)
1017
+func Skip(b []byte) ([]byte, error) {
1018
+	sz, asz, err := getSize(b)
1019
+	if err != nil {
1020
+		return b, err
1021
+	}
1022
+	if uintptr(len(b)) < sz {
1023
+		return b, ErrShortBytes
1024
+	}
1025
+	b = b[sz:]
1026
+	for asz > 0 {
1027
+		b, err = Skip(b)
1028
+		if err != nil {
1029
+			return b, err
1030
+		}
1031
+		asz--
1032
+	}
1033
+	return b, nil
1034
+}
1035
+
1036
+// returns (skip N bytes, skip M objects, error)
1037
+func getSize(b []byte) (uintptr, uintptr, error) {
1038
+	l := len(b)
1039
+	if l == 0 {
1040
+		return 0, 0, ErrShortBytes
1041
+	}
1042
+	lead := b[0]
1043
+	spec := &sizes[lead] // get type information
1044
+	size, mode := spec.size, spec.extra
1045
+	if size == 0 {
1046
+		return 0, 0, InvalidPrefixError(lead)
1047
+	}
1048
+	if mode >= 0 { // fixed composites
1049
+		return uintptr(size), uintptr(mode), nil
1050
+	}
1051
+	if l < int(size) {
1052
+		return 0, 0, ErrShortBytes
1053
+	}
1054
+	switch mode {
1055
+	case extra8:
1056
+		return uintptr(size) + uintptr(b[1]), 0, nil
1057
+	case extra16:
1058
+		return uintptr(size) + uintptr(big.Uint16(b[1:])), 0, nil
1059
+	case extra32:
1060
+		return uintptr(size) + uintptr(big.Uint32(b[1:])), 0, nil
1061
+	case map16v:
1062
+		return uintptr(size), 2 * uintptr(big.Uint16(b[1:])), nil
1063
+	case map32v:
1064
+		return uintptr(size), 2 * uintptr(big.Uint32(b[1:])), nil
1065
+	case array16v:
1066
+		return uintptr(size), uintptr(big.Uint16(b[1:])), nil
1067
+	case array32v:
1068
+		return uintptr(size), uintptr(big.Uint32(b[1:])), nil
1069
+	default:
1070
+		return 0, 0, fatal
1071
+	}
1072
+}
0 1073
new file mode 100644
... ...
@@ -0,0 +1,38 @@
0
+package msgp
1
+
2
+// The sizes provided
3
+// are the worst-case
4
+// encoded sizes for
5
+// each type. For variable-
6
+// length types ([]byte, string),
7
+// the total encoded size is
8
+// the prefix size plus the
9
+// length of the object.
10
+const (
11
+	Int64Size      = 9
12
+	IntSize        = Int64Size
13
+	UintSize       = Int64Size
14
+	Int8Size       = 2
15
+	Int16Size      = 3
16
+	Int32Size      = 5
17
+	Uint8Size      = 2
18
+	ByteSize       = Uint8Size
19
+	Uint16Size     = 3
20
+	Uint32Size     = 5
21
+	Uint64Size     = Int64Size
22
+	Float64Size    = 9
23
+	Float32Size    = 5
24
+	Complex64Size  = 10
25
+	Complex128Size = 18
26
+
27
+	TimeSize = 15
28
+	BoolSize = 1
29
+	NilSize  = 1
30
+
31
+	MapHeaderSize   = 5
32
+	ArrayHeaderSize = 5
33
+
34
+	BytesPrefixSize     = 5
35
+	StringPrefixSize    = 5
36
+	ExtensionPrefixSize = 6
37
+)
0 38
new file mode 100644
... ...
@@ -0,0 +1,768 @@
0
+package msgp
1
+
2
+import (
3
+	"errors"
4
+	"fmt"
5
+	"io"
6
+	"math"
7
+	"reflect"
8
+	"sync"
9
+	"time"
10
+)
11
+
12
+func abs(i int64) int64 {
13
+	if i < 0 {
14
+		return -i
15
+	}
16
+	return i
17
+}
18
+
19
+// Sizer is an interface implemented
20
+// by types that can estimate their
21
+// size when MessagePack encoded.
22
+// This interface is optional, but
23
+// encoding/marshaling implementations
24
+// may use this as a way to pre-allocate
25
+// memory for serialization.
26
+type Sizer interface {
27
+	Msgsize() int
28
+}
29
+
30
+var (
31
+	// Nowhere is an io.Writer to nowhere
32
+	Nowhere io.Writer = nwhere{}
33
+
34
+	btsType    = reflect.TypeOf(([]byte)(nil))
35
+	writerPool = sync.Pool{
36
+		New: func() interface{} {
37
+			return &Writer{buf: make([]byte, 2048)}
38
+		},
39
+	}
40
+)
41
+
42
+func popWriter(w io.Writer) *Writer {
43
+	wr := writerPool.Get().(*Writer)
44
+	wr.Reset(w)
45
+	return wr
46
+}
47
+
48
+func pushWriter(wr *Writer) {
49
+	wr.w = nil
50
+	wr.wloc = 0
51
+	writerPool.Put(wr)
52
+}
53
+
54
+// freeW frees a writer for use
55
+// by other processes. It is not necessary
56
+// to call freeW on a writer. However, maintaining
57
+// a reference to a *Writer after calling freeW on
58
+// it will cause undefined behavior.
59
+func freeW(w *Writer) { pushWriter(w) }
60
+
61
+// Require ensures that cap(old)-len(old) >= extra
62
+func Require(old []byte, extra int) []byte {
63
+	if cap(old)-len(old) >= extra {
64
+		return old
65
+	}
66
+	if len(old) == 0 {
67
+		return make([]byte, 0, extra)
68
+	}
69
+	n := make([]byte, len(old), cap(old)-len(old)+extra)
70
+	copy(n, old)
71
+	return n
72
+}
73
+
74
+// nowhere writer
75
+type nwhere struct{}
76
+
77
+func (n nwhere) Write(p []byte) (int, error) { return len(p), nil }
78
+
79
+// Marshaler is the interface implemented
80
+// by types that know how to marshal themselves
81
+// as MessagePack. MarshalMsg appends the marshalled
82
+// form of the object to the provided
83
+// byte slice, returning the extended
84
+// slice and any errors encountered.
85
+type Marshaler interface {
86
+	MarshalMsg([]byte) ([]byte, error)
87
+}
88
+
89
+// Encodable is the interface implemented
90
+// by types that know how to write themselves
91
+// as MessagePack using a *msgp.Writer.
92
+type Encodable interface {
93
+	EncodeMsg(*Writer) error
94
+}
95
+
96
+// Writer is a buffered writer
97
+// that can be used to write
98
+// MessagePack objects to an io.Writer.
99
+// You must call *Writer.Flush() in order
100
+// to flush all of the buffered data
101
+// to the underlying writer.
102
+type Writer struct {
103
+	w    io.Writer
104
+	buf  []byte
105
+	wloc int
106
+}
107
+
108
+// NewWriter returns a new *Writer.
109
+func NewWriter(w io.Writer) *Writer {
110
+	if wr, ok := w.(*Writer); ok {
111
+		return wr
112
+	}
113
+	return popWriter(w)
114
+}
115
+
116
+// NewWriterSize returns a writer with a custom buffer size.
117
+func NewWriterSize(w io.Writer, sz int) *Writer {
118
+	// we must be able to require() 18
119
+	// contiguous bytes, so that is the
120
+	// practical minimum buffer size
121
+	if sz < 18 {
122
+		sz = 18
123
+	}
124
+
125
+	return &Writer{
126
+		w:   w,
127
+		buf: make([]byte, sz),
128
+	}
129
+}
130
+
131
+// Encode encodes an Encodable to an io.Writer.
132
+func Encode(w io.Writer, e Encodable) error {
133
+	wr := NewWriter(w)
134
+	err := e.EncodeMsg(wr)
135
+	if err == nil {
136
+		err = wr.Flush()
137
+	}
138
+	freeW(wr)
139
+	return err
140
+}
141
+
142
+func (mw *Writer) flush() error {
143
+	if mw.wloc == 0 {
144
+		return nil
145
+	}
146
+	n, err := mw.w.Write(mw.buf[:mw.wloc])
147
+	if err != nil {
148
+		if n > 0 {
149
+			mw.wloc = copy(mw.buf, mw.buf[n:mw.wloc])
150
+		}
151
+		return err
152
+	}
153
+	mw.wloc = 0
154
+	return nil
155
+}
156
+
157
+// Flush flushes all of the buffered
158
+// data to the underlying writer.
159
+func (mw *Writer) Flush() error { return mw.flush() }
160
+
161
+// Buffered returns the number bytes in the write buffer
162
+func (mw *Writer) Buffered() int { return len(mw.buf) - mw.wloc }
163
+
164
+func (mw *Writer) avail() int { return len(mw.buf) - mw.wloc }
165
+
166
+func (mw *Writer) bufsize() int { return len(mw.buf) }
167
+
168
+// NOTE: this should only be called with
169
+// a number that is guaranteed to be less than
170
+// len(mw.buf). typically, it is called with a constant.
171
+//
172
+// NOTE: this is a hot code path
173
+func (mw *Writer) require(n int) (int, error) {
174
+	c := len(mw.buf)
175
+	wl := mw.wloc
176
+	if c-wl < n {
177
+		if err := mw.flush(); err != nil {
178
+			return 0, err
179
+		}
180
+		wl = mw.wloc
181
+	}
182
+	mw.wloc += n
183
+	return wl, nil
184
+}
185
+
186
+// push one byte onto the buffer
187
+//
188
+// NOTE: this is a hot code path
189
+func (mw *Writer) push(b byte) error {
190
+	if mw.wloc == len(mw.buf) {
191
+		if err := mw.flush(); err != nil {
192
+			return err
193
+		}
194
+	}
195
+	mw.buf[mw.wloc] = b
196
+	mw.wloc++
197
+	return nil
198
+}
199
+
200
+func (mw *Writer) prefix8(b byte, u uint8) error {
201
+	const need = 2
202
+	if len(mw.buf)-mw.wloc < need {
203
+		if err := mw.flush(); err != nil {
204
+			return err
205
+		}
206
+	}
207
+	prefixu8(mw.buf[mw.wloc:], b, u)
208
+	mw.wloc += need
209
+	return nil
210
+}
211
+
212
+func (mw *Writer) prefix16(b byte, u uint16) error {
213
+	const need = 3
214
+	if len(mw.buf)-mw.wloc < need {
215
+		if err := mw.flush(); err != nil {
216
+			return err
217
+		}
218
+	}
219
+	prefixu16(mw.buf[mw.wloc:], b, u)
220
+	mw.wloc += need
221
+	return nil
222
+}
223
+
224
+func (mw *Writer) prefix32(b byte, u uint32) error {
225
+	const need = 5
226
+	if len(mw.buf)-mw.wloc < need {
227
+		if err := mw.flush(); err != nil {
228
+			return err
229
+		}
230
+	}
231
+	prefixu32(mw.buf[mw.wloc:], b, u)
232
+	mw.wloc += need
233
+	return nil
234
+}
235
+
236
+func (mw *Writer) prefix64(b byte, u uint64) error {
237
+	const need = 9
238
+	if len(mw.buf)-mw.wloc < need {
239
+		if err := mw.flush(); err != nil {
240
+			return err
241
+		}
242
+	}
243
+	prefixu64(mw.buf[mw.wloc:], b, u)
244
+	mw.wloc += need
245
+	return nil
246
+}
247
+
248
+// Write implements io.Writer, and writes
249
+// data directly to the buffer.
250
+func (mw *Writer) Write(p []byte) (int, error) {
251
+	l := len(p)
252
+	if mw.avail() < l {
253
+		if err := mw.flush(); err != nil {
254
+			return 0, err
255
+		}
256
+		if l > len(mw.buf) {
257
+			return mw.w.Write(p)
258
+		}
259
+	}
260
+	mw.wloc += copy(mw.buf[mw.wloc:], p)
261
+	return l, nil
262
+}
263
+
264
+// implements io.WriteString
265
+func (mw *Writer) writeString(s string) error {
266
+	l := len(s)
267
+	if mw.avail() < l {
268
+		if err := mw.flush(); err != nil {
269
+			return err
270
+		}
271
+		if l > len(mw.buf) {
272
+			_, err := io.WriteString(mw.w, s)
273
+			return err
274
+		}
275
+	}
276
+	mw.wloc += copy(mw.buf[mw.wloc:], s)
277
+	return nil
278
+}
279
+
280
+// Reset changes the underlying writer used by the Writer
281
+func (mw *Writer) Reset(w io.Writer) {
282
+	mw.buf = mw.buf[:cap(mw.buf)]
283
+	mw.w = w
284
+	mw.wloc = 0
285
+}
286
+
287
+// WriteMapHeader writes a map header of the given
288
+// size to the writer
289
+func (mw *Writer) WriteMapHeader(sz uint32) error {
290
+	switch {
291
+	case sz < 16:
292
+		return mw.push(wfixmap(uint8(sz)))
293
+	case sz < math.MaxUint16:
294
+		return mw.prefix16(mmap16, uint16(sz))
295
+	default:
296
+		return mw.prefix32(mmap32, sz)
297
+	}
298
+}
299
+
300
+// WriteArrayHeader writes an array header of the
301
+// given size to the writer
302
+func (mw *Writer) WriteArrayHeader(sz uint32) error {
303
+	switch {
304
+	case sz < 16:
305
+		return mw.push(wfixarray(uint8(sz)))
306
+	case sz < math.MaxUint16:
307
+		return mw.prefix16(marray16, uint16(sz))
308
+	default:
309
+		return mw.prefix32(marray32, sz)
310
+	}
311
+}
312
+
313
+// WriteNil writes a nil byte to the buffer
314
+func (mw *Writer) WriteNil() error {
315
+	return mw.push(mnil)
316
+}
317
+
318
+// WriteFloat64 writes a float64 to the writer
319
+func (mw *Writer) WriteFloat64(f float64) error {
320
+	return mw.prefix64(mfloat64, math.Float64bits(f))
321
+}
322
+
323
+// WriteFloat32 writes a float32 to the writer
324
+func (mw *Writer) WriteFloat32(f float32) error {
325
+	return mw.prefix32(mfloat32, math.Float32bits(f))
326
+}
327
+
328
+// WriteInt64 writes an int64 to the writer
329
+func (mw *Writer) WriteInt64(i int64) error {
330
+	a := abs(i)
331
+	switch {
332
+	case i < 0 && i > -32:
333
+		return mw.push(wnfixint(int8(i)))
334
+	case i >= 0 && i < 128:
335
+		return mw.push(wfixint(uint8(i)))
336
+	case a < math.MaxInt8:
337
+		return mw.prefix8(mint8, uint8(i))
338
+	case a < math.MaxInt16:
339
+		return mw.prefix16(mint16, uint16(i))
340
+	case a < math.MaxInt32:
341
+		return mw.prefix32(mint32, uint32(i))
342
+	default:
343
+		return mw.prefix64(mint64, uint64(i))
344
+	}
345
+}
346
+
347
+// WriteInt8 writes an int8 to the writer
348
+func (mw *Writer) WriteInt8(i int8) error { return mw.WriteInt64(int64(i)) }
349
+
350
+// WriteInt16 writes an int16 to the writer
351
+func (mw *Writer) WriteInt16(i int16) error { return mw.WriteInt64(int64(i)) }
352
+
353
+// WriteInt32 writes an int32 to the writer
354
+func (mw *Writer) WriteInt32(i int32) error { return mw.WriteInt64(int64(i)) }
355
+
356
+// WriteInt writes an int to the writer
357
+func (mw *Writer) WriteInt(i int) error { return mw.WriteInt64(int64(i)) }
358
+
359
+// WriteUint64 writes a uint64 to the writer
360
+func (mw *Writer) WriteUint64(u uint64) error {
361
+	switch {
362
+	case u < (1 << 7):
363
+		return mw.push(wfixint(uint8(u)))
364
+	case u < math.MaxUint8:
365
+		return mw.prefix8(muint8, uint8(u))
366
+	case u < math.MaxUint16:
367
+		return mw.prefix16(muint16, uint16(u))
368
+	case u < math.MaxUint32:
369
+		return mw.prefix32(muint32, uint32(u))
370
+	default:
371
+		return mw.prefix64(muint64, u)
372
+	}
373
+}
374
+
375
+// WriteByte is analagous to WriteUint8
376
+func (mw *Writer) WriteByte(u byte) error { return mw.WriteUint8(uint8(u)) }
377
+
378
+// WriteUint8 writes a uint8 to the writer
379
+func (mw *Writer) WriteUint8(u uint8) error { return mw.WriteUint64(uint64(u)) }
380
+
381
+// WriteUint16 writes a uint16 to the writer
382
+func (mw *Writer) WriteUint16(u uint16) error { return mw.WriteUint64(uint64(u)) }
383
+
384
+// WriteUint32 writes a uint32 to the writer
385
+func (mw *Writer) WriteUint32(u uint32) error { return mw.WriteUint64(uint64(u)) }
386
+
387
+// WriteUint writes a uint to the writer
388
+func (mw *Writer) WriteUint(u uint) error { return mw.WriteUint64(uint64(u)) }
389
+
390
+// WriteBytes writes binary as 'bin' to the writer
391
+func (mw *Writer) WriteBytes(b []byte) error {
392
+	sz := uint32(len(b))
393
+	var err error
394
+	switch {
395
+	case sz < math.MaxUint8:
396
+		err = mw.prefix8(mbin8, uint8(sz))
397
+	case sz < math.MaxUint16:
398
+		err = mw.prefix16(mbin16, uint16(sz))
399
+	default:
400
+		err = mw.prefix32(mbin32, sz)
401
+	}
402
+	if err != nil {
403
+		return err
404
+	}
405
+	_, err = mw.Write(b)
406
+	return err
407
+}
408
+
409
+// WriteBool writes a bool to the writer
410
+func (mw *Writer) WriteBool(b bool) error {
411
+	if b {
412
+		return mw.push(mtrue)
413
+	}
414
+	return mw.push(mfalse)
415
+}
416
+
417
+// WriteString writes a messagepack string to the writer.
418
+// (This is NOT an implementation of io.StringWriter)
419
+func (mw *Writer) WriteString(s string) error {
420
+	sz := uint32(len(s))
421
+	var err error
422
+	switch {
423
+	case sz < 32:
424
+		err = mw.push(wfixstr(uint8(sz)))
425
+	case sz < math.MaxUint8:
426
+		err = mw.prefix8(mstr8, uint8(sz))
427
+	case sz < math.MaxUint16:
428
+		err = mw.prefix16(mstr16, uint16(sz))
429
+	default:
430
+		err = mw.prefix32(mstr32, sz)
431
+	}
432
+	if err != nil {
433
+		return err
434
+	}
435
+	return mw.writeString(s)
436
+}
437
+
438
+// WriteComplex64 writes a complex64 to the writer
439
+func (mw *Writer) WriteComplex64(f complex64) error {
440
+	o, err := mw.require(10)
441
+	if err != nil {
442
+		return err
443
+	}
444
+	mw.buf[o] = mfixext8
445
+	mw.buf[o+1] = Complex64Extension
446
+	big.PutUint32(mw.buf[o+2:], math.Float32bits(real(f)))
447
+	big.PutUint32(mw.buf[o+6:], math.Float32bits(imag(f)))
448
+	return nil
449
+}
450
+
451
+// WriteComplex128 writes a complex128 to the writer
452
+func (mw *Writer) WriteComplex128(f complex128) error {
453
+	o, err := mw.require(18)
454
+	if err != nil {
455
+		return err
456
+	}
457
+	mw.buf[o] = mfixext16
458
+	mw.buf[o+1] = Complex128Extension
459
+	big.PutUint64(mw.buf[o+2:], math.Float64bits(real(f)))
460
+	big.PutUint64(mw.buf[o+10:], math.Float64bits(imag(f)))
461
+	return nil
462
+}
463
+
464
+// WriteMapStrStr writes a map[string]string to the writer
465
+func (mw *Writer) WriteMapStrStr(mp map[string]string) (err error) {
466
+	err = mw.WriteMapHeader(uint32(len(mp)))
467
+	if err != nil {
468
+		return
469
+	}
470
+	for key, val := range mp {
471
+		err = mw.WriteString(key)
472
+		if err != nil {
473
+			return
474
+		}
475
+		err = mw.WriteString(val)
476
+		if err != nil {
477
+			return
478
+		}
479
+	}
480
+	return nil
481
+}
482
+
483
+// WriteMapStrIntf writes a map[string]interface to the writer
484
+func (mw *Writer) WriteMapStrIntf(mp map[string]interface{}) (err error) {
485
+	err = mw.WriteMapHeader(uint32(len(mp)))
486
+	if err != nil {
487
+		return
488
+	}
489
+	for key, val := range mp {
490
+		err = mw.WriteString(key)
491
+		if err != nil {
492
+			return
493
+		}
494
+		err = mw.WriteIntf(val)
495
+		if err != nil {
496
+			return
497
+		}
498
+	}
499
+	return
500
+}
501
+
502
+// WriteTime writes a time.Time object to the wire.
503
+//
504
+// Time is encoded as Unix time, which means that
505
+// location (time zone) data is removed from the object.
506
+// The encoded object itself is 12 bytes: 8 bytes for
507
+// a big-endian 64-bit integer denoting seconds
508
+// elapsed since "zero" Unix time, followed by 4 bytes
509
+// for a big-endian 32-bit signed integer denoting
510
+// the nanosecond offset of the time. This encoding
511
+// is intended to ease portability accross languages.
512
+// (Note that this is *not* the standard time.Time
513
+// binary encoding, because its implementation relies
514
+// heavily on the internal representation used by the
515
+// time package.)
516
+func (mw *Writer) WriteTime(t time.Time) error {
517
+	t = t.UTC()
518
+	o, err := mw.require(15)
519
+	if err != nil {
520
+		return err
521
+	}
522
+	mw.buf[o] = mext8
523
+	mw.buf[o+1] = 12
524
+	mw.buf[o+2] = TimeExtension
525
+	putUnix(mw.buf[o+3:], t.Unix(), int32(t.Nanosecond()))
526
+	return nil
527
+}
528
+
529
+// WriteIntf writes the concrete type of 'v'.
530
+// WriteIntf will error if 'v' is not one of the following:
531
+//  - A bool, float, string, []byte, int, uint, or complex
532
+//  - A map of supported types (with string keys)
533
+//  - An array or slice of supported types
534
+//  - A pointer to a supported type
535
+//  - A type that satisfies the msgp.Encodable interface
536
+//  - A type that satisfies the msgp.Extension interface
537
+func (mw *Writer) WriteIntf(v interface{}) error {
538
+	if v == nil {
539
+		return mw.WriteNil()
540
+	}
541
+	switch v := v.(type) {
542
+
543
+	// preferred interfaces
544
+
545
+	case Encodable:
546
+		return v.EncodeMsg(mw)
547
+	case Extension:
548
+		return mw.WriteExtension(v)
549
+
550
+	// concrete types
551
+
552
+	case bool:
553
+		return mw.WriteBool(v)
554
+	case float32:
555
+		return mw.WriteFloat32(v)
556
+	case float64:
557
+		return mw.WriteFloat64(v)
558
+	case complex64:
559
+		return mw.WriteComplex64(v)
560
+	case complex128:
561
+		return mw.WriteComplex128(v)
562
+	case uint8:
563
+		return mw.WriteUint8(v)
564
+	case uint16:
565
+		return mw.WriteUint16(v)
566
+	case uint32:
567
+		return mw.WriteUint32(v)
568
+	case uint64:
569
+		return mw.WriteUint64(v)
570
+	case uint:
571
+		return mw.WriteUint(v)
572
+	case int8:
573
+		return mw.WriteInt8(v)
574
+	case int16:
575
+		return mw.WriteInt16(v)
576
+	case int32:
577
+		return mw.WriteInt32(v)
578
+	case int64:
579
+		return mw.WriteInt64(v)
580
+	case int:
581
+		return mw.WriteInt(v)
582
+	case string:
583
+		return mw.WriteString(v)
584
+	case []byte:
585
+		return mw.WriteBytes(v)
586
+	case map[string]string:
587
+		return mw.WriteMapStrStr(v)
588
+	case map[string]interface{}:
589
+		return mw.WriteMapStrIntf(v)
590
+	case time.Time:
591
+		return mw.WriteTime(v)
592
+	}
593
+
594
+	val := reflect.ValueOf(v)
595
+	if !isSupported(val.Kind()) || !val.IsValid() {
596
+		return fmt.Errorf("msgp: type %s not supported", val)
597
+	}
598
+
599
+	switch val.Kind() {
600
+	case reflect.Ptr:
601
+		if val.IsNil() {
602
+			return mw.WriteNil()
603
+		}
604
+		return mw.WriteIntf(val.Elem().Interface())
605
+	case reflect.Slice:
606
+		return mw.writeSlice(val)
607
+	case reflect.Map:
608
+		return mw.writeMap(val)
609
+	}
610
+	return &ErrUnsupportedType{val.Type()}
611
+}
612
+
613
+func (mw *Writer) writeMap(v reflect.Value) (err error) {
614
+	if v.Elem().Kind() != reflect.String {
615
+		return errors.New("msgp: map keys must be strings")
616
+	}
617
+	ks := v.MapKeys()
618
+	err = mw.WriteMapHeader(uint32(len(ks)))
619
+	if err != nil {
620
+		return
621
+	}
622
+	for _, key := range ks {
623
+		val := v.MapIndex(key)
624
+		err = mw.WriteString(key.String())
625
+		if err != nil {
626
+			return
627
+		}
628
+		err = mw.WriteIntf(val.Interface())
629
+		if err != nil {
630
+			return
631
+		}
632
+	}
633
+	return
634
+}
635
+
636
+func (mw *Writer) writeSlice(v reflect.Value) (err error) {
637
+	// is []byte
638
+	if v.Type().ConvertibleTo(btsType) {
639
+		return mw.WriteBytes(v.Bytes())
640
+	}
641
+
642
+	sz := uint32(v.Len())
643
+	err = mw.WriteArrayHeader(sz)
644
+	if err != nil {
645
+		return
646
+	}
647
+	for i := uint32(0); i < sz; i++ {
648
+		err = mw.WriteIntf(v.Index(int(i)).Interface())
649
+		if err != nil {
650
+			return
651
+		}
652
+	}
653
+	return
654
+}
655
+
656
+func (mw *Writer) writeStruct(v reflect.Value) error {
657
+	if enc, ok := v.Interface().(Encodable); ok {
658
+		return enc.EncodeMsg(mw)
659
+	}
660
+	return fmt.Errorf("msgp: unsupported type: %s", v.Type())
661
+}
662
+
663
+func (mw *Writer) writeVal(v reflect.Value) error {
664
+	if !isSupported(v.Kind()) {
665
+		return fmt.Errorf("msgp: msgp/enc: type %q not supported", v.Type())
666
+	}
667
+
668
+	// shortcut for nil values
669
+	if v.IsNil() {
670
+		return mw.WriteNil()
671
+	}
672
+	switch v.Kind() {
673
+	case reflect.Bool:
674
+		return mw.WriteBool(v.Bool())
675
+
676
+	case reflect.Float32, reflect.Float64:
677
+		return mw.WriteFloat64(v.Float())
678
+
679
+	case reflect.Complex64, reflect.Complex128:
680
+		return mw.WriteComplex128(v.Complex())
681
+
682
+	case reflect.Int, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int8:
683
+		return mw.WriteInt64(v.Int())
684
+
685
+	case reflect.Interface, reflect.Ptr:
686
+		if v.IsNil() {
687
+			mw.WriteNil()
688
+		}
689
+		return mw.writeVal(v.Elem())
690
+
691
+	case reflect.Map:
692
+		return mw.writeMap(v)
693
+
694
+	case reflect.Uint, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint8:
695
+		return mw.WriteUint64(v.Uint())
696
+
697
+	case reflect.String:
698
+		return mw.WriteString(v.String())
699
+
700
+	case reflect.Slice, reflect.Array:
701
+		return mw.writeSlice(v)
702
+
703
+	case reflect.Struct:
704
+		return mw.writeStruct(v)
705
+
706
+	}
707
+	return fmt.Errorf("msgp: msgp/enc: type %q not supported", v.Type())
708
+}
709
+
710
+// is the reflect.Kind encodable?
711
+func isSupported(k reflect.Kind) bool {
712
+	switch k {
713
+	case reflect.Func, reflect.Chan, reflect.Invalid, reflect.UnsafePointer:
714
+		return false
715
+	default:
716
+		return true
717
+	}
718
+}
719
+
720
+// GuessSize guesses the size of the underlying
721
+// value of 'i'. If the underlying value is not
722
+// a simple builtin (or []byte), GuessSize defaults
723
+// to 512.
724
+func GuessSize(i interface{}) int {
725
+	if i == nil {
726
+		return NilSize
727
+	}
728
+
729
+	switch i := i.(type) {
730
+	case Sizer:
731
+		return i.Msgsize()
732
+	case Extension:
733
+		return ExtensionPrefixSize + i.Len()
734
+	case float64:
735
+		return Float64Size
736
+	case float32:
737
+		return Float32Size
738
+	case uint8, uint16, uint32, uint64, uint:
739
+		return UintSize
740
+	case int8, int16, int32, int64, int:
741
+		return IntSize
742
+	case []byte:
743
+		return BytesPrefixSize + len(i)
744
+	case string:
745
+		return StringPrefixSize + len(i)
746
+	case complex64:
747
+		return Complex64Size
748
+	case complex128:
749
+		return Complex128Size
750
+	case bool:
751
+		return BoolSize
752
+	case map[string]interface{}:
753
+		s := MapHeaderSize
754
+		for key, val := range i {
755
+			s += StringPrefixSize + len(key) + GuessSize(val)
756
+		}
757
+		return s
758
+	case map[string]string:
759
+		s := MapHeaderSize
760
+		for key, val := range i {
761
+			s += 2*StringPrefixSize + len(key) + len(val)
762
+		}
763
+		return s
764
+	default:
765
+		return 512
766
+	}
767
+}
0 768
new file mode 100644
... ...
@@ -0,0 +1,369 @@
0
+package msgp
1
+
2
+import (
3
+	"math"
4
+	"reflect"
5
+	"time"
6
+)
7
+
8
+// ensure 'sz' extra bytes in 'b' btw len(b) and cap(b)
9
+func ensure(b []byte, sz int) ([]byte, int) {
10
+	l := len(b)
11
+	c := cap(b)
12
+	if c-l < sz {
13
+		o := make([]byte, (2*c)+sz) // exponential growth
14
+		n := copy(o, b)
15
+		return o[:n+sz], n
16
+	}
17
+	return b[:l+sz], l
18
+}
19
+
20
+// AppendMapHeader appends a map header with the
21
+// given size to the slice
22
+func AppendMapHeader(b []byte, sz uint32) []byte {
23
+	switch {
24
+	case sz < 16:
25
+		return append(b, wfixmap(uint8(sz)))
26
+
27
+	case sz < math.MaxUint16:
28
+		o, n := ensure(b, 3)
29
+		prefixu16(o[n:], mmap16, uint16(sz))
30
+		return o
31
+
32
+	default:
33
+		o, n := ensure(b, 5)
34
+		prefixu32(o[n:], mmap32, sz)
35
+		return o
36
+	}
37
+}
38
+
39
+// AppendArrayHeader appends an array header with
40
+// the given size to the slice
41
+func AppendArrayHeader(b []byte, sz uint32) []byte {
42
+	switch {
43
+	case sz < 16:
44
+		return append(b, wfixarray(uint8(sz)))
45
+
46
+	case sz < math.MaxUint16:
47
+		o, n := ensure(b, 3)
48
+		prefixu16(o[n:], marray16, uint16(sz))
49
+		return o
50
+
51
+	default:
52
+		o, n := ensure(b, 5)
53
+		prefixu32(o[n:], marray32, sz)
54
+		return o
55
+	}
56
+}
57
+
58
+// AppendNil appends a 'nil' byte to the slice
59
+func AppendNil(b []byte) []byte { return append(b, mnil) }
60
+
61
+// AppendFloat64 appends a float64 to the slice
62
+func AppendFloat64(b []byte, f float64) []byte {
63
+	o, n := ensure(b, Float64Size)
64
+	prefixu64(o[n:], mfloat64, math.Float64bits(f))
65
+	return o
66
+}
67
+
68
+// AppendFloat32 appends a float32 to the slice
69
+func AppendFloat32(b []byte, f float32) []byte {
70
+	o, n := ensure(b, Float32Size)
71
+	prefixu32(o[n:], mfloat32, math.Float32bits(f))
72
+	return o
73
+}
74
+
75
+// AppendInt64 appends an int64 to the slice
76
+func AppendInt64(b []byte, i int64) []byte {
77
+	a := abs(i)
78
+	switch {
79
+	case i < 0 && i > -32:
80
+		return append(b, wnfixint(int8(i)))
81
+
82
+	case i >= 0 && i < 128:
83
+		return append(b, wfixint(uint8(i)))
84
+
85
+	case a < math.MaxInt8:
86
+		o, n := ensure(b, 2)
87
+		putMint8(o[n:], int8(i))
88
+		return o
89
+
90
+	case a < math.MaxInt16:
91
+		o, n := ensure(b, 3)
92
+		putMint16(o[n:], int16(i))
93
+		return o
94
+
95
+	case a < math.MaxInt32:
96
+		o, n := ensure(b, 5)
97
+		putMint32(o[n:], int32(i))
98
+		return o
99
+
100
+	default:
101
+		o, n := ensure(b, 9)
102
+		putMint64(o[n:], i)
103
+		return o
104
+	}
105
+}
106
+
107
+// AppendInt appends an int to the slice
108
+func AppendInt(b []byte, i int) []byte { return AppendInt64(b, int64(i)) }
109
+
110
+// AppendInt8 appends an int8 to the slice
111
+func AppendInt8(b []byte, i int8) []byte { return AppendInt64(b, int64(i)) }
112
+
113
+// AppendInt16 appends an int16 to the slice
114
+func AppendInt16(b []byte, i int16) []byte { return AppendInt64(b, int64(i)) }
115
+
116
+// AppendInt32 appends an int32 to the slice
117
+func AppendInt32(b []byte, i int32) []byte { return AppendInt64(b, int64(i)) }
118
+
119
+// AppendUint64 appends a uint64 to the slice
120
+func AppendUint64(b []byte, u uint64) []byte {
121
+	switch {
122
+	case u < (1 << 7):
123
+		return append(b, wfixint(uint8(u)))
124
+
125
+	case u < math.MaxUint8:
126
+		o, n := ensure(b, 2)
127
+		putMuint8(o[n:], uint8(u))
128
+		return o
129
+
130
+	case u < math.MaxUint16:
131
+		o, n := ensure(b, 3)
132
+		putMuint16(o[n:], uint16(u))
133
+		return o
134
+
135
+	case u < math.MaxUint32:
136
+		o, n := ensure(b, 5)
137
+		putMuint32(o[n:], uint32(u))
138
+		return o
139
+
140
+	default:
141
+		o, n := ensure(b, 9)
142
+		putMuint64(o[n:], u)
143
+		return o
144
+
145
+	}
146
+}
147
+
148
+// AppendUint appends a uint to the slice
149
+func AppendUint(b []byte, u uint) []byte { return AppendUint64(b, uint64(u)) }
150
+
151
+// AppendUint8 appends a uint8 to the slice
152
+func AppendUint8(b []byte, u uint8) []byte { return AppendUint64(b, uint64(u)) }
153
+
154
+// AppendByte is analagous to AppendUint8
155
+func AppendByte(b []byte, u byte) []byte { return AppendUint8(b, uint8(u)) }
156
+
157
+// AppendUint16 appends a uint16 to the slice
158
+func AppendUint16(b []byte, u uint16) []byte { return AppendUint64(b, uint64(u)) }
159
+
160
+// AppendUint32 appends a uint32 to the slice
161
+func AppendUint32(b []byte, u uint32) []byte { return AppendUint64(b, uint64(u)) }
162
+
163
+// AppendBytes appends bytes to the slice as MessagePack 'bin' data
164
+func AppendBytes(b []byte, bts []byte) []byte {
165
+	sz := len(bts)
166
+	var o []byte
167
+	var n int
168
+	switch {
169
+	case sz < math.MaxUint8:
170
+		o, n = ensure(b, 2+sz)
171
+		prefixu8(o[n:], mbin8, uint8(sz))
172
+		n += 2
173
+	case sz < math.MaxUint16:
174
+		o, n = ensure(b, 3+sz)
175
+		prefixu16(o[n:], mbin16, uint16(sz))
176
+		n += 3
177
+	default:
178
+		o, n = ensure(b, 5+sz)
179
+		prefixu32(o[n:], mbin32, uint32(sz))
180
+		n += 5
181
+	}
182
+	return o[:n+copy(o[n:], bts)]
183
+}
184
+
185
+// AppendBool appends a bool to the slice
186
+func AppendBool(b []byte, t bool) []byte {
187
+	if t {
188
+		return append(b, mtrue)
189
+	}
190
+	return append(b, mfalse)
191
+}
192
+
193
+// AppendString appends a string as a MessagePack 'str' to the slice
194
+func AppendString(b []byte, s string) []byte {
195
+	sz := len(s)
196
+	var n int
197
+	var o []byte
198
+	switch {
199
+	case sz < 32:
200
+		o, n = ensure(b, 1+sz)
201
+		o[n] = wfixstr(uint8(sz))
202
+		n++
203
+	case sz < math.MaxUint8:
204
+		o, n = ensure(b, 2+sz)
205
+		prefixu8(o[n:], mstr8, uint8(sz))
206
+		n += 2
207
+	case sz < math.MaxUint16:
208
+		o, n = ensure(b, 3+sz)
209
+		prefixu16(o[n:], mstr16, uint16(sz))
210
+		n += 3
211
+	default:
212
+		o, n = ensure(b, 5+sz)
213
+		prefixu32(o[n:], mstr32, uint32(sz))
214
+		n += 5
215
+	}
216
+	return o[:n+copy(o[n:], s)]
217
+}
218
+
219
+// AppendComplex64 appends a complex64 to the slice as a MessagePack extension
220
+func AppendComplex64(b []byte, c complex64) []byte {
221
+	o, n := ensure(b, Complex64Size)
222
+	o[n] = mfixext8
223
+	o[n+1] = Complex64Extension
224
+	big.PutUint32(o[n+2:], math.Float32bits(real(c)))
225
+	big.PutUint32(o[n+6:], math.Float32bits(imag(c)))
226
+	return o
227
+}
228
+
229
+// AppendComplex128 appends a complex128 to the slice as a MessagePack extension
230
+func AppendComplex128(b []byte, c complex128) []byte {
231
+	o, n := ensure(b, Complex128Size)
232
+	o[n] = mfixext16
233
+	o[n+1] = Complex128Extension
234
+	big.PutUint64(o[n+2:], math.Float64bits(real(c)))
235
+	big.PutUint64(o[n+10:], math.Float64bits(imag(c)))
236
+	return o
237
+}
238
+
239
+// AppendTime appends a time.Time to the slice as a MessagePack extension
240
+func AppendTime(b []byte, t time.Time) []byte {
241
+	o, n := ensure(b, TimeSize)
242
+	t = t.UTC()
243
+	o[n] = mext8
244
+	o[n+1] = 12
245
+	o[n+2] = TimeExtension
246
+	putUnix(o[n+3:], t.Unix(), int32(t.Nanosecond()))
247
+	return o
248
+}
249
+
250
+// AppendMapStrStr appends a map[string]string to the slice
251
+// as a MessagePack map with 'str'-type keys and values
252
+func AppendMapStrStr(b []byte, m map[string]string) []byte {
253
+	sz := uint32(len(m))
254
+	b = AppendMapHeader(b, sz)
255
+	for key, val := range m {
256
+		b = AppendString(b, key)
257
+		b = AppendString(b, val)
258
+	}
259
+	return b
260
+}
261
+
262
+// AppendMapStrIntf appends a map[string]interface{} to the slice
263
+// as a MessagePack map with 'str'-type keys.
264
+func AppendMapStrIntf(b []byte, m map[string]interface{}) ([]byte, error) {
265
+	sz := uint32(len(m))
266
+	b = AppendMapHeader(b, sz)
267
+	var err error
268
+	for key, val := range m {
269
+		b = AppendString(b, key)
270
+		b, err = AppendIntf(b, val)
271
+		if err != nil {
272
+			return b, err
273
+		}
274
+	}
275
+	return b, nil
276
+}
277
+
278
+// AppendIntf appends the concrete type of 'i' to the
279
+// provided []byte. 'i' must be one of the following:
280
+//  - 'nil'
281
+//  - A bool, float, string, []byte, int, uint, or complex
282
+//  - A map[string]interface{} or map[string]string
283
+//  - A []T, where T is another supported type
284
+//  - A *T, where T is another supported type
285
+//  - A type that satisfieds the msgp.Marshaler interface
286
+//  - A type that satisfies the msgp.Extension interface
287
+func AppendIntf(b []byte, i interface{}) ([]byte, error) {
288
+	if i == nil {
289
+		return AppendNil(b), nil
290
+	}
291
+
292
+	// all the concrete types
293
+	// for which we have methods
294
+	switch i := i.(type) {
295
+	case Marshaler:
296
+		return i.MarshalMsg(b)
297
+	case Extension:
298
+		return AppendExtension(b, i)
299
+	case bool:
300
+		return AppendBool(b, i), nil
301
+	case float32:
302
+		return AppendFloat32(b, i), nil
303
+	case float64:
304
+		return AppendFloat64(b, i), nil
305
+	case complex64:
306
+		return AppendComplex64(b, i), nil
307
+	case complex128:
308
+		return AppendComplex128(b, i), nil
309
+	case string:
310
+		return AppendString(b, i), nil
311
+	case []byte:
312
+		return AppendBytes(b, i), nil
313
+	case int8:
314
+		return AppendInt8(b, i), nil
315
+	case int16:
316
+		return AppendInt16(b, i), nil
317
+	case int32:
318
+		return AppendInt32(b, i), nil
319
+	case int64:
320
+		return AppendInt64(b, i), nil
321
+	case int:
322
+		return AppendInt64(b, int64(i)), nil
323
+	case uint:
324
+		return AppendUint64(b, uint64(i)), nil
325
+	case uint8:
326
+		return AppendUint8(b, i), nil
327
+	case uint16:
328
+		return AppendUint16(b, i), nil
329
+	case uint32:
330
+		return AppendUint32(b, i), nil
331
+	case uint64:
332
+		return AppendUint64(b, i), nil
333
+	case time.Time:
334
+		return AppendTime(b, i), nil
335
+	case map[string]interface{}:
336
+		return AppendMapStrIntf(b, i)
337
+	case map[string]string:
338
+		return AppendMapStrStr(b, i), nil
339
+	case []interface{}:
340
+		b = AppendArrayHeader(b, uint32(len(i)))
341
+		var err error
342
+		for _, k := range i {
343
+			b, err = AppendIntf(b, k)
344
+			if err != nil {
345
+				return b, err
346
+			}
347
+		}
348
+		return b, nil
349
+	}
350
+
351
+	var err error
352
+	v := reflect.ValueOf(i)
353
+	switch v.Kind() {
354
+	case reflect.Array, reflect.Slice:
355
+		l := v.Len()
356
+		b = AppendArrayHeader(b, uint32(l))
357
+		for i := 0; i < l; i++ {
358
+			b, err = AppendIntf(b, v.Index(i).Interface())
359
+			if err != nil {
360
+				return b, err
361
+			}
362
+		}
363
+		return b, nil
364
+
365
+	default:
366
+		return b, &ErrUnsupportedType{T: v.Type()}
367
+	}
368
+}