github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/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 "errors" 9 "io" 10 "reflect" 11 "sync" 12 ) 13 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 16 // goroutines. 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 encBuffer // 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(encBuffer)) 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) setError(err error) { 58 if enc.err == nil { // remember the first. 59 enc.err = err 60 } 61 } 62 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 67 // it by hand. 68 message := b.Bytes() 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")) 73 return 74 } 75 // Encode the length. 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()) 81 // Write the data. 82 _, err := w.Write(message[offset:]) 83 // Drain the buffer and restore the space at the front for the count of the next message. 84 b.Reset() 85 b.Write(spaceForLength) 86 if err != nil { 87 enc.setError(err) 88 } 89 } 90 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 { 95 return false 96 } 97 info, err := getTypeInfo(ut) 98 if err != nil { 99 enc.setError(err) 100 return 101 } 102 // Send the pair (-id, type) 103 // Id: 104 state.encodeInt(-int64(info.id)) 105 // Type: 106 enc.encode(state.b, reflect.ValueOf(info.wire), wireTypeUserInfo) 107 enc.writeMessage(w, state.b) 108 if enc.err != nil { 109 return 110 } 111 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 116 } 117 // Now send the inner types 118 switch st := actual; st.Kind() { 119 case reflect.Struct: 120 for i := 0; i < st.NumField(); i++ { 121 if isExported(st.Field(i).Name) { 122 enc.sendType(w, state, st.Field(i).Type) 123 } 124 } 125 case reflect.Array, reflect.Slice: 126 enc.sendType(w, state, st.Elem()) 127 case reflect.Map: 128 enc.sendType(w, state, st.Key()) 129 enc.sendType(w, state, st.Elem()) 130 } 131 return true 132 } 133 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) 141 } 142 143 // It's a concrete value, so drill down to the base type. 144 switch rt := ut.base; rt.Kind() { 145 default: 146 // Basic types and interfaces do not need to be described. 147 return 148 case reflect.Slice: 149 // If it's []uint8, don't send; it's considered basic. 150 if rt.Elem().Kind() == reflect.Uint8 { 151 return 152 } 153 // Otherwise we do send. 154 break 155 case reflect.Array: 156 // arrays must be sent so we know their lengths and element types. 157 break 158 case reflect.Map: 159 // maps must be sent so we know their lengths and key/value types. 160 break 161 case reflect.Struct: 162 // structs must be sent so we know their fields. 163 break 164 case reflect.Chan, reflect.Func: 165 // If we get here, it's a field of a struct; ignore it. 166 return 167 } 168 169 return enc.sendActualType(w, state, ut, ut.base) 170 } 171 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 interface{}) error { 176 return enc.EncodeValue(reflect.ValueOf(e)) 177 } 178 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 181 // sent. 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? 185 rt := ut.base 186 if ut.externalEnc != 0 { 187 rt = ut.user 188 } 189 if _, alreadySent := enc.sent[rt]; !alreadySent { 190 // No, so send it. 191 sent := enc.sendType(w, state, rt) 192 if enc.err != nil { 193 return 194 } 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. 198 if !sent { 199 info, err := getTypeInfo(ut) 200 if err != nil { 201 enc.setError(err) 202 return 203 } 204 enc.sent[rt] = info.id 205 } 206 } 207 } 208 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])) 213 } 214 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") 221 } 222 if value.Kind() == reflect.Ptr && value.IsNil() { 223 panic("gob: cannot encode nil pointer of type " + value.Type().String()) 224 } 225 226 // Make sure we're single-threaded through here, so multiple 227 // goroutines can share an encoder. 228 enc.mutex.Lock() 229 defer enc.mutex.Unlock() 230 231 // Remove any nested writers remaining due to previous errors. 232 enc.w = enc.w[0:1] 233 234 ut, err := validUserType(value.Type()) 235 if err != nil { 236 return err 237 } 238 239 enc.err = nil 240 enc.byteBuf.Reset() 241 enc.byteBuf.Write(spaceForLength) 242 state := enc.newEncoderState(&enc.byteBuf) 243 244 enc.sendTypeDescriptor(enc.writer(), state, ut) 245 enc.sendTypeId(state, ut) 246 if enc.err != nil { 247 return enc.err 248 } 249 250 // Encode the object. 251 enc.encode(state.b, value, ut) 252 if enc.err == nil { 253 enc.writeMessage(enc.writer(), state.b) 254 } 255 256 enc.freeEncoderState(state) 257 return enc.err 258 }