1
2
3
4
5 package gob
6
7 import (
8 "bytes"
9 "io"
10 "os"
11 "reflect"
12 "sync"
13 )
14
15
16
17 type Encoder struct {
18 mutex sync.Mutex
19 w []io.Writer
20 sent map[reflect.Type]typeId
21 countState *encoderState
22 freeList *encoderState
23 buf []byte
24 byteBuf bytes.Buffer
25 err os.Error
26 }
27
28
29 func NewEncoder(w io.Writer) *Encoder {
30 enc := new(Encoder)
31 enc.w = []io.Writer{w}
32 enc.sent = make(map[reflect.Type]typeId)
33 enc.countState = enc.newEncoderState(new(bytes.Buffer))
34 return enc
35 }
36
37
38 func (enc *Encoder) writer() io.Writer {
39 return enc.w[len(enc.w)-1]
40 }
41
42
43 func (enc *Encoder) pushWriter(w io.Writer) {
44 enc.w = append(enc.w, w)
45 }
46
47
48 func (enc *Encoder) popWriter() {
49 enc.w = enc.w[0 : len(enc.w)-1]
50 }
51
52 func (enc *Encoder) badType(rt reflect.Type) {
53 enc.setError(os.NewError("gob: can't encode type " + rt.String()))
54 }
55
56 func (enc *Encoder) setError(err os.Error) {
57 if enc.err == nil {
58 enc.err = err
59 }
60 }
61
62
63 func (enc *Encoder) writeMessage(w io.Writer, b *bytes.Buffer) {
64 enc.countState.encodeUint(uint64(b.Len()))
65
66 countLen := enc.countState.b.Len()
67 total := countLen + b.Len()
68 if total > len(enc.buf) {
69 enc.buf = make([]byte, total+1000)
70 }
71
72
73 enc.countState.b.Read(enc.buf[0:countLen])
74
75 b.Read(enc.buf[countLen:total])
76
77 _, err := w.Write(enc.buf[0:total])
78 if err != nil {
79 enc.setError(err)
80 }
81 }
82
83
84
85 func (enc *Encoder) sendActualType(w io.Writer, state *encoderState, ut *userTypeInfo, actual reflect.Type) (sent bool) {
86 if _, alreadySent := enc.sent[actual]; alreadySent {
87 return false
88 }
89 typeLock.Lock()
90 info, err := getTypeInfo(ut)
91 typeLock.Unlock()
92 if err != nil {
93 enc.setError(err)
94 return
95 }
96
97
98 state.encodeInt(-int64(info.id))
99
100 enc.encode(state.b, reflect.ValueOf(info.wire), wireTypeUserInfo)
101 enc.writeMessage(w, state.b)
102 if enc.err != nil {
103 return
104 }
105
106
107 enc.sent[ut.base] = info.id
108 if ut.user != ut.base {
109 enc.sent[ut.user] = info.id
110 }
111
112 switch st := actual; st.Kind() {
113 case reflect.Struct:
114 for i := 0; i < st.NumField(); i++ {
115 enc.sendType(w, state, st.Field(i).Type)
116 }
117 case reflect.Array, reflect.Slice:
118 enc.sendType(w, state, st.Elem())
119 case reflect.Map:
120 enc.sendType(w, state, st.Key())
121 enc.sendType(w, state, st.Elem())
122 }
123 return true
124 }
125
126
127 func (enc *Encoder) sendType(w io.Writer, state *encoderState, origt reflect.Type) (sent bool) {
128 ut := userType(origt)
129 if ut.isGobEncoder {
130
131
132 return enc.sendActualType(w, state, ut, ut.user)
133 }
134
135
136 switch rt := ut.base; rt.Kind() {
137 default:
138
139 return
140 case reflect.Slice:
141
142 if rt.Elem().Kind() == reflect.Uint8 {
143 return
144 }
145
146 break
147 case reflect.Array:
148
149 break
150 case reflect.Map:
151
152 break
153 case reflect.Struct:
154
155 break
156 case reflect.Chan, reflect.Func:
157
158 enc.badType(rt)
159 return
160 }
161
162 return enc.sendActualType(w, state, ut, ut.base)
163 }
164
165
166
167 func (enc *Encoder) Encode(e interface{}) os.Error {
168 return enc.EncodeValue(reflect.ValueOf(e))
169 }
170
171
172
173
174 func (enc *Encoder) sendTypeDescriptor(w io.Writer, state *encoderState, ut *userTypeInfo) {
175
176
177 rt := ut.base
178 if ut.isGobEncoder {
179 rt = ut.user
180 }
181 if _, alreadySent := enc.sent[rt]; !alreadySent {
182
183 sent := enc.sendType(w, state, rt)
184 if enc.err != nil {
185 return
186 }
187
188
189
190 if !sent {
191 typeLock.Lock()
192 info, err := getTypeInfo(ut)
193 typeLock.Unlock()
194 if err != nil {
195 enc.setError(err)
196 return
197 }
198 enc.sent[rt] = info.id
199 }
200 }
201 }
202
203
204 func (enc *Encoder) sendTypeId(state *encoderState, ut *userTypeInfo) {
205
206 state.encodeInt(int64(enc.sent[ut.base]))
207 }
208
209
210
211 func (enc *Encoder) EncodeValue(value reflect.Value) os.Error {
212
213
214 enc.mutex.Lock()
215 defer enc.mutex.Unlock()
216
217
218 enc.w = enc.w[0:1]
219
220 ut, err := validUserType(value.Type())
221 if err != nil {
222 return err
223 }
224
225 enc.err = nil
226 enc.byteBuf.Reset()
227 state := enc.newEncoderState(&enc.byteBuf)
228
229 enc.sendTypeDescriptor(enc.writer(), state, ut)
230 enc.sendTypeId(state, ut)
231 if enc.err != nil {
232 return enc.err
233 }
234
235
236 enc.encode(state.b, value, ut)
237 if enc.err == nil {
238 enc.writeMessage(enc.writer(), state.b)
239 }
240
241 enc.freeEncoderState(state)
242 return enc.err
243 }