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. It is safe for concurrent use by multiple
18 mutex sync
.Mutex
// each item must be sent atomically
19 w
[]io
.Writer
// where to send the data
20 sent
map[reflect
.Type
]typeId
// which types we've already sent
21 countState
*encoderState
// stage for writing counts
22 freeList
*encoderState
// list of free encoderStates; avoids reallocation
23 byteBuf encBuffer
// buffer for top-level encoderState
27 // Before we encode a message, we reserve space at the head of the
28 // buffer in which to encode its length. This means we can use the
29 // buffer to assemble the message without another allocation.
30 const maxLength
= 9 // Maximum size of an encoded length.
31 var spaceForLength
= make([]byte, maxLength
)
33 // NewEncoder returns a new encoder that will transmit on the io.Writer.
34 func NewEncoder(w io
.Writer
) *Encoder
{
36 enc
.w
= []io
.Writer
{w
}
37 enc
.sent
= make(map[reflect
.Type
]typeId
)
38 enc
.countState
= enc
.newEncoderState(new(encBuffer
))
42 // writer() returns the innermost writer the encoder is using
43 func (enc
*Encoder
) writer() io
.Writer
{
44 return enc
.w
[len(enc
.w
)-1]
47 // pushWriter adds a writer to the encoder.
48 func (enc
*Encoder
) pushWriter(w io
.Writer
) {
49 enc
.w
= append(enc
.w
, w
)
52 // popWriter pops the innermost writer.
53 func (enc
*Encoder
) popWriter() {
54 enc
.w
= enc
.w
[0 : len(enc
.w
)-1]
57 func (enc
*Encoder
) setError(err error
) {
58 if enc
.err
== nil { // remember the first.
63 // writeMessage sends the data item preceded by a unsigned count of its length.
64 func (enc
*Encoder
) writeMessage(w io
.Writer
, b
*encBuffer
) {
65 // Space has been reserved for the length at the head of the message.
66 // This is a little dirty: we grab the slice from the bytes.Buffer and massage
69 messageLen
:= len(message
) - maxLength
70 // Length cannot be bigger than the decoder can handle.
71 if messageLen
>= tooBig
{
72 enc
.setError(errors
.New("gob: encoder: message too big"))
76 enc
.countState
.b
.Reset()
77 enc
.countState
.encodeUint(uint64(messageLen
))
78 // Copy the length to be a prefix of the message.
79 offset
:= maxLength
- enc
.countState
.b
.Len()
80 copy(message
[offset
:], enc
.countState
.b
.Bytes())
82 _
, err
:= w
.Write(message
[offset
:])
83 // Drain the buffer and restore the space at the front for the count of the next message.
85 b
.Write(spaceForLength
)
91 // sendActualType sends the requested type, without further investigation, unless
92 // it's been sent before.
93 func (enc
*Encoder
) sendActualType(w io
.Writer
, state
*encoderState
, ut
*userTypeInfo
, actual reflect
.Type
) (sent
bool) {
94 if _
, alreadySent
:= enc
.sent
[actual
]; alreadySent
{
97 info
, err
:= getTypeInfo(ut
)
102 // Send the pair (-id, type)
104 state
.encodeInt(-int64(info
.id
))
106 enc
.encode(state
.b
, reflect
.ValueOf(info
.wire
), wireTypeUserInfo
)
107 enc
.writeMessage(w
, state
.b
)
112 // Remember we've sent this type, both what the user gave us and the base type.
113 enc
.sent
[ut
.base
] = info
.id
114 if ut
.user
!= ut
.base
{
115 enc
.sent
[ut
.user
] = info
.id
117 // Now send the inner types
118 switch st
:= actual
; st
.Kind() {
120 for i
:= 0; i
< st
.NumField(); i
++ {
121 if isExported(st
.Field(i
).Name
) {
122 enc
.sendType(w
, state
, st
.Field(i
).Type
)
125 case reflect
.Array
, reflect
.Slice
:
126 enc
.sendType(w
, state
, st
.Elem())
128 enc
.sendType(w
, state
, st
.Key())
129 enc
.sendType(w
, state
, st
.Elem())
134 // sendType sends the type info to the other side, if necessary.
135 func (enc
*Encoder
) sendType(w io
.Writer
, state
*encoderState
, origt reflect
.Type
) (sent
bool) {
136 ut
:= userType(origt
)
137 if ut
.externalEnc
!= 0 {
138 // The rules are different: regardless of the underlying type's representation,
139 // we need to tell the other side that the base type is a GobEncoder.
140 return enc
.sendActualType(w
, state
, ut
, ut
.base
)
143 // It's a concrete value, so drill down to the base type.
144 switch rt
:= ut
.base
; rt
.Kind() {
146 // Basic types and interfaces do not need to be described.
149 // If it's []uint8, don't send; it's considered basic.
150 if rt
.Elem().Kind() == reflect
.Uint8
{
153 // Otherwise we do send.
156 // arrays must be sent so we know their lengths and element types.
159 // maps must be sent so we know their lengths and key/value types.
162 // structs must be sent so we know their fields.
164 case reflect
.Chan
, reflect
.Func
:
165 // If we get here, it's a field of a struct; ignore it.
169 return enc
.sendActualType(w
, state
, ut
, ut
.base
)
172 // Encode transmits the data item represented by the empty interface value,
173 // guaranteeing that all necessary type information has been transmitted first.
174 // Passing a nil pointer to Encoder will panic, as they cannot be transmitted by gob.
175 func (enc
*Encoder
) Encode(e any
) error
{
176 return enc
.EncodeValue(reflect
.ValueOf(e
))
179 // sendTypeDescriptor makes sure the remote side knows about this type.
180 // It will send a descriptor if this is the first time the type has been
182 func (enc
*Encoder
) sendTypeDescriptor(w io
.Writer
, state
*encoderState
, ut
*userTypeInfo
) {
183 // Make sure the type is known to the other side.
184 // First, have we already sent this type?
186 if ut
.externalEnc
!= 0 {
189 if _
, alreadySent
:= enc
.sent
[rt
]; !alreadySent
{
191 sent
:= enc
.sendType(w
, state
, rt
)
195 // If the type info has still not been transmitted, it means we have
196 // a singleton basic type (int, []byte etc.) at top level. We don't
197 // need to send the type info but we do need to update enc.sent.
199 info
, err
:= getTypeInfo(ut
)
204 enc
.sent
[rt
] = info
.id
209 // sendTypeId sends the id, which must have already been defined.
210 func (enc
*Encoder
) sendTypeId(state
*encoderState
, ut
*userTypeInfo
) {
211 // Identify the type of this top-level value.
212 state
.encodeInt(int64(enc
.sent
[ut
.base
]))
215 // EncodeValue transmits the data item represented by the reflection value,
216 // guaranteeing that all necessary type information has been transmitted first.
217 // Passing a nil pointer to EncodeValue will panic, as they cannot be transmitted by gob.
218 func (enc
*Encoder
) EncodeValue(value reflect
.Value
) error
{
219 if value
.Kind() == reflect
.Invalid
{
220 return errors
.New("gob: cannot encode nil value")
222 if value
.Kind() == reflect
.Pointer
&& value
.IsNil() {
223 panic("gob: cannot encode nil pointer of type " + value
.Type().String())
226 // Make sure we're single-threaded through here, so multiple
227 // goroutines can share an encoder.
229 defer enc
.mutex
.Unlock()
231 // Remove any nested writers remaining due to previous errors.
234 ut
, err
:= validUserType(value
.Type())
241 enc
.byteBuf
.Write(spaceForLength
)
242 state
:= enc
.newEncoderState(&enc
.byteBuf
)
244 enc
.sendTypeDescriptor(enc
.writer(), state
, ut
)
245 enc
.sendTypeId(state
, ut
)
250 // Encode the object.
251 enc
.encode(state
.b
, value
, ut
)
253 enc
.writeMessage(enc
.writer(), state
.b
)
256 enc
.freeEncoderState(state
)