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.
15 // An Encoder manages the transmission of type and data information to the
16 // other side of a connection.
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 state
*encoderState
// so we can encode integers, strings directly
22 countState
*encoderState
// stage for writing counts
23 buf
[]byte // for collecting the output.
27 // NewEncoder returns a new encoder that will transmit on the io.Writer.
28 func NewEncoder(w io
.Writer
) *Encoder
{
31 enc
.sent
= make(map[reflect
.Type
]typeId
)
32 enc
.state
= newEncoderState(enc
, new(bytes
.Buffer
))
33 enc
.countState
= newEncoderState(enc
, new(bytes
.Buffer
))
37 func (enc
*Encoder
) badType(rt reflect
.Type
) {
38 enc
.setError(os
.ErrorString("gob: can't encode type " + rt
.String()))
41 func (enc
*Encoder
) setError(err os
.Error
) {
42 if enc
.err
== nil { // remember the first.
48 // Send the data item preceded by a unsigned count of its length.
49 func (enc
*Encoder
) send() {
51 encodeUint(enc
.countState
, uint64(enc
.state
.b
.Len()))
53 countLen
:= enc
.countState
.b
.Len()
54 total
:= countLen
+ enc
.state
.b
.Len()
55 if total
> len(enc
.buf
) {
56 enc
.buf
= make([]byte, total
+1000) // extra for growth
58 // Place the length before the data.
59 // TODO(r): avoid the extra copy here.
60 enc
.countState
.b
.Read(enc
.buf
[0:countLen
])
62 enc
.state
.b
.Read(enc
.buf
[countLen
:total
])
64 _
, err
:= enc
.w
.Write(enc
.buf
[0:total
])
70 func (enc
*Encoder
) sendType(origt reflect
.Type
) (sent
bool) {
71 // Drill down to the base type.
72 rt
, _
:= indirect(origt
)
74 switch rt
:= rt
.(type) {
76 // Basic types and interfaces do not need to be described.
78 case *reflect
.SliceType
:
79 // If it's []uint8, don't send; it's considered basic.
80 if rt
.Elem().Kind() == reflect
.Uint8
{
83 // Otherwise we do send.
85 case *reflect
.ArrayType
:
86 // arrays must be sent so we know their lengths and element types.
88 case *reflect
.MapType
:
89 // maps must be sent so we know their lengths and key/value types.
91 case *reflect
.StructType
:
92 // structs must be sent so we know their fields.
94 case *reflect
.ChanType
, *reflect
.FuncType
:
95 // Probably a bad field in a struct.
100 // Have we already sent this type? This time we ask about the base type.
101 if _
, alreadySent
:= enc
.sent
[rt
]; alreadySent
{
107 info
, err
:= getTypeInfo(rt
)
113 // Send the pair (-id, type)
115 encodeInt(enc
.state
, -int64(info
.id
))
117 enc
.encode(enc
.state
.b
, reflect
.NewValue(info
.wire
))
123 // Remember we've sent this type.
124 enc
.sent
[rt
] = info
.id
125 // Remember we've sent the top-level, possibly indirect type too.
126 enc
.sent
[origt
] = info
.id
127 // Now send the inner types
128 switch st
:= rt
.(type) {
129 case *reflect
.StructType
:
130 for i
:= 0; i
< st
.NumField(); i
++ {
131 enc
.sendType(st
.Field(i
).Type
)
133 case reflect
.ArrayOrSliceType
:
134 enc
.sendType(st
.Elem())
139 // Encode transmits the data item represented by the empty interface value,
140 // guaranteeing that all necessary type information has been transmitted first.
141 func (enc
*Encoder
) Encode(e
interface{}) os
.Error
{
142 return enc
.EncodeValue(reflect
.NewValue(e
))
145 // sendTypeId makes sure the remote side knows about this type.
146 // It will send a descriptor if this is the first time the type has been
147 // sent. Regardless, it sends the id.
148 func (enc
*Encoder
) sendTypeDescriptor(rt reflect
.Type
) {
149 // Make sure the type is known to the other side.
150 // First, have we already sent this type?
151 if _
, alreadySent
:= enc
.sent
[rt
]; !alreadySent
{
153 sent
:= enc
.sendType(rt
)
157 // If the type info has still not been transmitted, it means we have
158 // a singleton basic type (int, []byte etc.) at top level. We don't
159 // need to send the type info but we do need to update enc.sent.
162 info
, err
:= getTypeInfo(rt
)
168 enc
.sent
[rt
] = info
.id
172 // Identify the type of this top-level value.
173 encodeInt(enc
.state
, int64(enc
.sent
[rt
]))
176 // EncodeValue transmits the data item represented by the reflection value,
177 // guaranteeing that all necessary type information has been transmitted first.
178 func (enc
*Encoder
) EncodeValue(value reflect
.Value
) os
.Error
{
179 // Make sure we're single-threaded through here, so multiple
180 // goroutines can share an encoder.
182 defer enc
.mutex
.Unlock()
185 rt
, _
:= indirect(value
.Type())
187 // Sanity check only: encoder should never come in with data present.
188 if enc
.state
.b
.Len() > 0 || enc
.countState
.b
.Len() > 0 {
189 enc
.err
= os
.ErrorString("encoder: buffer not empty")
193 enc
.sendTypeDescriptor(rt
)
198 // Encode the object.
199 err
:= enc
.encode(enc
.state
.b
, value
)