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