github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/fix/testdata/reflect.encoder.go.in (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 "io" 10 "os" 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 buf []byte // for collecting the output. 24 byteBuf bytes.Buffer // buffer for top-level encoderState 25 err os.Error 26 } 27 28 // NewEncoder returns a new encoder that will transmit on the io.Writer. 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 // writer() returns the innermost writer the encoder is using 38 func (enc *Encoder) writer() io.Writer { 39 return enc.w[len(enc.w)-1] 40 } 41 42 // pushWriter adds a writer to the encoder. 43 func (enc *Encoder) pushWriter(w io.Writer) { 44 enc.w = append(enc.w, w) 45 } 46 47 // popWriter pops the innermost writer. 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 { // remember the first. 58 enc.err = err 59 } 60 } 61 62 // writeMessage sends the data item preceded by a unsigned count of its length. 63 func (enc *Encoder) writeMessage(w io.Writer, b *bytes.Buffer) { 64 enc.countState.encodeUint(uint64(b.Len())) 65 // Build the buffer. 66 countLen := enc.countState.b.Len() 67 total := countLen + b.Len() 68 if total > len(enc.buf) { 69 enc.buf = make([]byte, total+1000) // extra for growth 70 } 71 // Place the length before the data. 72 // TODO(r): avoid the extra copy here. 73 enc.countState.b.Read(enc.buf[0:countLen]) 74 // Now the data. 75 b.Read(enc.buf[countLen:total]) 76 // Write the data. 77 _, err := w.Write(enc.buf[0:total]) 78 if err != nil { 79 enc.setError(err) 80 } 81 } 82 83 // sendActualType sends the requested type, without further investigation, unless 84 // it's been sent before. 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 // Send the pair (-id, type) 97 // Id: 98 state.encodeInt(-int64(info.id)) 99 // Type: 100 enc.encode(state.b, reflect.NewValue(info.wire), wireTypeUserInfo) 101 enc.writeMessage(w, state.b) 102 if enc.err != nil { 103 return 104 } 105 106 // Remember we've sent this type, both what the user gave us and the base type. 107 enc.sent[ut.base] = info.id 108 if ut.user != ut.base { 109 enc.sent[ut.user] = info.id 110 } 111 // Now send the inner types 112 switch st := actual.(type) { 113 case *reflect.StructType: 114 for i := 0; i < st.NumField(); i++ { 115 enc.sendType(w, state, st.Field(i).Type) 116 } 117 case reflect.ArrayOrSliceType: 118 enc.sendType(w, state, st.Elem()) 119 } 120 return true 121 } 122 123 // sendType sends the type info to the other side, if necessary. 124 func (enc *Encoder) sendType(w io.Writer, state *encoderState, origt reflect.Type) (sent bool) { 125 ut := userType(origt) 126 if ut.isGobEncoder { 127 // The rules are different: regardless of the underlying type's representation, 128 // we need to tell the other side that this exact type is a GobEncoder. 129 return enc.sendActualType(w, state, ut, ut.user) 130 } 131 132 // It's a concrete value, so drill down to the base type. 133 switch rt := ut.base.(type) { 134 default: 135 // Basic types and interfaces do not need to be described. 136 return 137 case *reflect.SliceType: 138 // If it's []uint8, don't send; it's considered basic. 139 if rt.Elem().Kind() == reflect.Uint8 { 140 return 141 } 142 // Otherwise we do send. 143 break 144 case *reflect.ArrayType: 145 // arrays must be sent so we know their lengths and element types. 146 break 147 case *reflect.MapType: 148 // maps must be sent so we know their lengths and key/value types. 149 break 150 case *reflect.StructType: 151 // structs must be sent so we know their fields. 152 break 153 case *reflect.ChanType, *reflect.FuncType: 154 // Probably a bad field in a struct. 155 enc.badType(rt) 156 return 157 } 158 159 return enc.sendActualType(w, state, ut, ut.base) 160 } 161 162 // Encode transmits the data item represented by the empty interface value, 163 // guaranteeing that all necessary type information has been transmitted first. 164 func (enc *Encoder) Encode(e interface{}) os.Error { 165 return enc.EncodeValue(reflect.NewValue(e)) 166 } 167 168 // sendTypeDescriptor makes sure the remote side knows about this type. 169 // It will send a descriptor if this is the first time the type has been 170 // sent. 171 func (enc *Encoder) sendTypeDescriptor(w io.Writer, state *encoderState, ut *userTypeInfo) { 172 // Make sure the type is known to the other side. 173 // First, have we already sent this type? 174 rt := ut.base 175 if ut.isGobEncoder { 176 rt = ut.user 177 } 178 if _, alreadySent := enc.sent[rt]; !alreadySent { 179 // No, so send it. 180 sent := enc.sendType(w, state, rt) 181 if enc.err != nil { 182 return 183 } 184 // If the type info has still not been transmitted, it means we have 185 // a singleton basic type (int, []byte etc.) at top level. We don't 186 // need to send the type info but we do need to update enc.sent. 187 if !sent { 188 typeLock.Lock() 189 info, err := getTypeInfo(ut) 190 typeLock.Unlock() 191 if err != nil { 192 enc.setError(err) 193 return 194 } 195 enc.sent[rt] = info.id 196 } 197 } 198 } 199 200 // sendTypeId sends the id, which must have already been defined. 201 func (enc *Encoder) sendTypeId(state *encoderState, ut *userTypeInfo) { 202 // Identify the type of this top-level value. 203 state.encodeInt(int64(enc.sent[ut.base])) 204 } 205 206 // EncodeValue transmits the data item represented by the reflection value, 207 // guaranteeing that all necessary type information has been transmitted first. 208 func (enc *Encoder) EncodeValue(value reflect.Value) os.Error { 209 // Make sure we're single-threaded through here, so multiple 210 // goroutines can share an encoder. 211 enc.mutex.Lock() 212 defer enc.mutex.Unlock() 213 214 // Remove any nested writers remaining due to previous errors. 215 enc.w = enc.w[0:1] 216 217 ut, err := validUserType(value.Type()) 218 if err != nil { 219 return err 220 } 221 222 enc.err = nil 223 enc.byteBuf.Reset() 224 state := enc.newEncoderState(&enc.byteBuf) 225 226 enc.sendTypeDescriptor(enc.writer(), state, ut) 227 enc.sendTypeId(state, ut) 228 if enc.err != nil { 229 return enc.err 230 } 231 232 // Encode the object. 233 enc.encode(state.b, value, ut) 234 if enc.err == nil { 235 enc.writeMessage(enc.writer(), state.b) 236 } 237 238 enc.freeEncoderState(state) 239 return enc.err 240 }