1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
14 // An Encoder manages the transmission of type and data information to the
15 // other side of a connection.
17 mutex sync
.Mutex
// each item must be sent atomically
18 w
[]io
.Writer
// where to send the data
19 sent
map[reflect
.Type
]typeId
// which types we've already sent
20 countState
*encoderState
// stage for writing counts
21 freeList
*encoderState
// list of free encoderStates; avoids reallocation
22 byteBuf encBuffer
// buffer for top-level encoderState
26 // Before we encode a message, we reserve space at the head of the
27 // buffer in which to encode its length. This means we can use the
28 // buffer to assemble the message without another allocation.
29 const maxLength
= 9 // Maximum size of an encoded length.
30 var spaceForLength
= make([]byte, maxLength
)
32 // NewEncoder returns a new encoder that will transmit on the io.Writer.
33 func NewEncoder(w io
.Writer
) *Encoder
{
35 enc
.w
= []io
.Writer
{w
}
36 enc
.sent
= make(map[reflect
.Type
]typeId
)
37 enc
.countState
= enc
.newEncoderState(new(encBuffer
))
41 // writer() returns the innermost writer the encoder is using
42 func (enc
*Encoder
) writer() io
.Writer
{
43 return enc
.w
[len(enc
.w
)-1]
46 // pushWriter adds a writer to the encoder.
47 func (enc
*Encoder
) pushWriter(w io
.Writer
) {
48 enc
.w
= append(enc
.w
, w
)
51 // popWriter pops the innermost writer.
52 func (enc
*Encoder
) popWriter() {
53 enc
.w
= enc
.w
[0 : len(enc
.w
)-1]
56 func (enc
*Encoder
) setError(err error
) {
57 if enc
.err
== nil { // remember the first.
62 // writeMessage sends the data item preceded by a unsigned count of its length.
63 func (enc
*Encoder
) writeMessage(w io
.Writer
, b
*encBuffer
) {
64 // Space has been reserved for the length at the head of the message.
65 // This is a little dirty: we grab the slice from the bytes.Buffer and massage
68 messageLen
:= len(message
) - maxLength
69 // Length cannot be bigger than the decoder can handle.
70 if messageLen
>= tooBig
{
71 enc
.setError(errors
.New("gob: encoder: message too big"))
75 enc
.countState
.b
.Reset()
76 enc
.countState
.encodeUint(uint64(messageLen
))
77 // Copy the length to be a prefix of the message.
78 offset
:= maxLength
- enc
.countState
.b
.Len()
79 copy(message
[offset
:], enc
.countState
.b
.Bytes())
81 _
, err
:= w
.Write(message
[offset
:])
82 // Drain the buffer and restore the space at the front for the count of the next message.
84 b
.Write(spaceForLength
)
90 // sendActualType sends the requested type, without further investigation, unless
91 // it's been sent before.
92 func (enc
*Encoder
) sendActualType(w io
.Writer
, state
*encoderState
, ut
*userTypeInfo
, actual reflect
.Type
) (sent
bool) {
93 if _
, alreadySent
:= enc
.sent
[actual
]; alreadySent
{
96 info
, err
:= getTypeInfo(ut
)
101 // Send the pair (-id, type)
103 state
.encodeInt(-int64(info
.id
))
105 enc
.encode(state
.b
, reflect
.ValueOf(info
.wire
), wireTypeUserInfo
)
106 enc
.writeMessage(w
, state
.b
)
111 // Remember we've sent this type, both what the user gave us and the base type.
112 enc
.sent
[ut
.base
] = info
.id
113 if ut
.user
!= ut
.base
{
114 enc
.sent
[ut
.user
] = info
.id
116 // Now send the inner types
117 switch st
:= actual
; st
.Kind() {
119 for i
:= 0; i
< st
.NumField(); i
++ {
120 if isExported(st
.Field(i
).Name
) {
121 enc
.sendType(w
, state
, st
.Field(i
).Type
)
124 case reflect
.Array
, reflect
.Slice
:
125 enc
.sendType(w
, state
, st
.Elem())
127 enc
.sendType(w
, state
, st
.Key())
128 enc
.sendType(w
, state
, st
.Elem())
133 // sendType sends the type info to the other side, if necessary.
134 func (enc
*Encoder
) sendType(w io
.Writer
, state
*encoderState
, origt reflect
.Type
) (sent
bool) {
135 ut
:= userType(origt
)
136 if ut
.externalEnc
!= 0 {
137 // The rules are different: regardless of the underlying type's representation,
138 // we need to tell the other side that the base type is a GobEncoder.
139 return enc
.sendActualType(w
, state
, ut
, ut
.base
)
142 // It's a concrete value, so drill down to the base type.
143 switch rt
:= ut
.base
; rt
.Kind() {
145 // Basic types and interfaces do not need to be described.
148 // If it's []uint8, don't send; it's considered basic.
149 if rt
.Elem().Kind() == reflect
.Uint8
{
152 // Otherwise we do send.
155 // arrays must be sent so we know their lengths and element types.
158 // maps must be sent so we know their lengths and key/value types.
161 // structs must be sent so we know their fields.
163 case reflect
.Chan
, reflect
.Func
:
164 // If we get here, it's a field of a struct; ignore it.
168 return enc
.sendActualType(w
, state
, ut
, ut
.base
)
171 // Encode transmits the data item represented by the empty interface value,
172 // guaranteeing that all necessary type information has been transmitted first.
173 // Passing a nil pointer to Encoder will panic, as they cannot be transmitted by gob.
174 func (enc
*Encoder
) Encode(e
interface{}) error
{
175 return enc
.EncodeValue(reflect
.ValueOf(e
))
178 // sendTypeDescriptor makes sure the remote side knows about this type.
179 // It will send a descriptor if this is the first time the type has been
181 func (enc
*Encoder
) sendTypeDescriptor(w io
.Writer
, state
*encoderState
, ut
*userTypeInfo
) {
182 // Make sure the type is known to the other side.
183 // First, have we already sent this type?
185 if ut
.externalEnc
!= 0 {
188 if _
, alreadySent
:= enc
.sent
[rt
]; !alreadySent
{
190 sent
:= enc
.sendType(w
, state
, rt
)
194 // If the type info has still not been transmitted, it means we have
195 // a singleton basic type (int, []byte etc.) at top level. We don't
196 // need to send the type info but we do need to update enc.sent.
198 info
, err
:= getTypeInfo(ut
)
203 enc
.sent
[rt
] = info
.id
208 // sendTypeId sends the id, which must have already been defined.
209 func (enc
*Encoder
) sendTypeId(state
*encoderState
, ut
*userTypeInfo
) {
210 // Identify the type of this top-level value.
211 state
.encodeInt(int64(enc
.sent
[ut
.base
]))
214 // EncodeValue transmits the data item represented by the reflection value,
215 // guaranteeing that all necessary type information has been transmitted first.
216 // Passing a nil pointer to EncodeValue will panic, as they cannot be transmitted by gob.
217 func (enc
*Encoder
) EncodeValue(value reflect
.Value
) error
{
218 if value
.Kind() == reflect
.Invalid
{
219 return errors
.New("gob: cannot encode nil value")
221 if value
.Kind() == reflect
.Ptr
&& value
.IsNil() {
222 panic("gob: cannot encode nil pointer of type " + value
.Type().String())
225 // Make sure we're single-threaded through here, so multiple
226 // goroutines can share an encoder.
228 defer enc
.mutex
.Unlock()
230 // Remove any nested writers remaining due to previous errors.
233 ut
, err
:= validUserType(value
.Type())
240 enc
.byteBuf
.Write(spaceForLength
)
241 state
:= enc
.newEncoderState(&enc
.byteBuf
)
243 enc
.sendTypeDescriptor(enc
.writer(), state
, ut
)
244 enc
.sendTypeId(state
, ut
)
249 // Encode the object.
250 enc
.encode(state
.b
, value
, ut
)
252 enc
.writeMessage(enc
.writer(), state
.b
)
255 enc
.freeEncoderState(state
)