github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/encoding/gob/encoder.go (about) 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. 4 5 package gob 6 7 import ( 8 "bytes" 9 "errors" 10 "io" 11 "reflect" 12 "sync" 13 ) 14 15 // An Encoder manages the transmission of type and data information to the 16 // other side of a connection. 17 type Encoder struct { 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 bytes.Buffer // buffer for top-level encoderState 24 err error 25 } 26 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) 32 33 // NewEncoder returns a new encoder that will transmit on the io.Writer. 34 func NewEncoder(w io.Writer) *Encoder { 35 enc := new(Encoder) 36 enc.w = []io.Writer{w} 37 enc.sent = make(map[reflect.Type]typeId) 38 enc.countState = enc.newEncoderState(new(bytes.Buffer)) 39 return enc 40 } 41 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] 45 } 46 47 // pushWriter adds a writer to the encoder. 48 func (enc *Encoder) pushWriter(w io.Writer) { 49 enc.w = append(enc.w, w) 50 } 51 52 // popWriter pops the innermost writer. 53 func (enc *Encoder) popWriter() { 54 enc.w = enc.w[0 : len(enc.w)-1] 55 } 56 57 func (enc *Encoder) badType(rt reflect.Type) { 58 enc.setError(errors.New("gob: can't encode type " + rt.String())) 59 } 60 61 func (enc *Encoder) setError(err error) { 62 if enc.err == nil { // remember the first. 63 enc.err = err 64 } 65 } 66 67 // writeMessage sends the data item preceded by a unsigned count of its length. 68 func (enc *Encoder) writeMessage(w io.Writer, b *bytes.Buffer) { 69 // Space has been reserved for the length at the head of the message. 70 // This is a little dirty: we grab the slice from the bytes.Buffer and massage 71 // it by hand. 72 message := b.Bytes() 73 messageLen := len(message) - maxLength 74 // Encode the length. 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()) 80 // Write the data. 81 _, err := w.Write(message[offset:]) 82 // Drain the buffer and restore the space at the front for the count of the next message. 83 b.Reset() 84 b.Write(spaceForLength) 85 if err != nil { 86 enc.setError(err) 87 } 88 } 89 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 { 94 return false 95 } 96 typeLock.Lock() 97 info, err := getTypeInfo(ut) 98 typeLock.Unlock() 99 if err != nil { 100 enc.setError(err) 101 return 102 } 103 // Send the pair (-id, type) 104 // Id: 105 state.encodeInt(-int64(info.id)) 106 // Type: 107 enc.encode(state.b, reflect.ValueOf(info.wire), wireTypeUserInfo) 108 enc.writeMessage(w, state.b) 109 if enc.err != nil { 110 return 111 } 112 113 // Remember we've sent this type, both what the user gave us and the base type. 114 enc.sent[ut.base] = info.id 115 if ut.user != ut.base { 116 enc.sent[ut.user] = info.id 117 } 118 // Now send the inner types 119 switch st := actual; st.Kind() { 120 case reflect.Struct: 121 for i := 0; i < st.NumField(); i++ { 122 if isExported(st.Field(i).Name) { 123 enc.sendType(w, state, st.Field(i).Type) 124 } 125 } 126 case reflect.Array, reflect.Slice: 127 enc.sendType(w, state, st.Elem()) 128 case reflect.Map: 129 enc.sendType(w, state, st.Key()) 130 enc.sendType(w, state, st.Elem()) 131 } 132 return true 133 } 134 135 // sendType sends the type info to the other side, if necessary. 136 func (enc *Encoder) sendType(w io.Writer, state *encoderState, origt reflect.Type) (sent bool) { 137 ut := userType(origt) 138 if ut.externalEnc != 0 { 139 // The rules are different: regardless of the underlying type's representation, 140 // we need to tell the other side that the base type is a GobEncoder. 141 return enc.sendActualType(w, state, ut, ut.base) 142 } 143 144 // It's a concrete value, so drill down to the base type. 145 switch rt := ut.base; rt.Kind() { 146 default: 147 // Basic types and interfaces do not need to be described. 148 return 149 case reflect.Slice: 150 // If it's []uint8, don't send; it's considered basic. 151 if rt.Elem().Kind() == reflect.Uint8 { 152 return 153 } 154 // Otherwise we do send. 155 break 156 case reflect.Array: 157 // arrays must be sent so we know their lengths and element types. 158 break 159 case reflect.Map: 160 // maps must be sent so we know their lengths and key/value types. 161 break 162 case reflect.Struct: 163 // structs must be sent so we know their fields. 164 break 165 case reflect.Chan, reflect.Func: 166 // Probably a bad field in a struct. 167 enc.badType(rt) 168 return 169 } 170 171 return enc.sendActualType(w, state, ut, ut.base) 172 } 173 174 // Encode transmits the data item represented by the empty interface value, 175 // guaranteeing that all necessary type information has been transmitted first. 176 func (enc *Encoder) Encode(e interface{}) error { 177 return enc.EncodeValue(reflect.ValueOf(e)) 178 } 179 180 // sendTypeDescriptor makes sure the remote side knows about this type. 181 // It will send a descriptor if this is the first time the type has been 182 // sent. 183 func (enc *Encoder) sendTypeDescriptor(w io.Writer, state *encoderState, ut *userTypeInfo) { 184 // Make sure the type is known to the other side. 185 // First, have we already sent this type? 186 rt := ut.base 187 if ut.externalEnc != 0 { 188 rt = ut.user 189 } 190 if _, alreadySent := enc.sent[rt]; !alreadySent { 191 // No, so send it. 192 sent := enc.sendType(w, state, rt) 193 if enc.err != nil { 194 return 195 } 196 // If the type info has still not been transmitted, it means we have 197 // a singleton basic type (int, []byte etc.) at top level. We don't 198 // need to send the type info but we do need to update enc.sent. 199 if !sent { 200 typeLock.Lock() 201 info, err := getTypeInfo(ut) 202 typeLock.Unlock() 203 if err != nil { 204 enc.setError(err) 205 return 206 } 207 enc.sent[rt] = info.id 208 } 209 } 210 } 211 212 // sendTypeId sends the id, which must have already been defined. 213 func (enc *Encoder) sendTypeId(state *encoderState, ut *userTypeInfo) { 214 // Identify the type of this top-level value. 215 state.encodeInt(int64(enc.sent[ut.base])) 216 } 217 218 // EncodeValue transmits the data item represented by the reflection value, 219 // guaranteeing that all necessary type information has been transmitted first. 220 func (enc *Encoder) EncodeValue(value reflect.Value) error { 221 // Gobs contain values. They cannot represent nil pointers, which 222 // have no value to encode. 223 if value.Kind() == reflect.Ptr && value.IsNil() { 224 panic("gob: cannot encode nil pointer of type " + value.Type().String()) 225 } 226 227 // Make sure we're single-threaded through here, so multiple 228 // goroutines can share an encoder. 229 enc.mutex.Lock() 230 defer enc.mutex.Unlock() 231 232 // Remove any nested writers remaining due to previous errors. 233 enc.w = enc.w[0:1] 234 235 ut, err := validUserType(value.Type()) 236 if err != nil { 237 return err 238 } 239 240 enc.err = nil 241 enc.byteBuf.Reset() 242 enc.byteBuf.Write(spaceForLength) 243 state := enc.newEncoderState(&enc.byteBuf) 244 245 enc.sendTypeDescriptor(enc.writer(), state, ut) 246 enc.sendTypeId(state, ut) 247 if enc.err != nil { 248 return enc.err 249 } 250 251 // Encode the object. 252 enc.encode(state.b, value, ut) 253 if enc.err == nil { 254 enc.writeMessage(enc.writer(), state.b) 255 } 256 257 enc.freeEncoderState(state) 258 return enc.err 259 }