writeChunk writes a chunk of entries with the same key/value types
(ctx *WriteContext, iter *reflect.MapIter, entryKey, entryVal *reflect.Value, resolver *TypeResolver, trackRef bool)
| 194 | |
| 195 | // writeChunk writes a chunk of entries with the same key/value types |
| 196 | func (s mapSerializer) writeChunk(ctx *WriteContext, iter *reflect.MapIter, entryKey, entryVal *reflect.Value, resolver *TypeResolver, trackRef bool) bool { |
| 197 | buf := ctx.Buffer() |
| 198 | keyType := (*entryKey).Type() |
| 199 | valueType := (*entryVal).Type() |
| 200 | |
| 201 | // Reserve space: header (1 byte) + size (1 byte) |
| 202 | headerOffset := buf.writerIndex |
| 203 | buf.WriteInt16(-1) |
| 204 | |
| 205 | header := 0 |
| 206 | var keySer, valSer Serializer |
| 207 | keyWriteRef := s.keyReferencable |
| 208 | valueWriteRef := s.valueReferencable |
| 209 | |
| 210 | // Determine key serializer and write type info if needed |
| 211 | if s.hasGenerics && s.keySerializer != nil { |
| 212 | header |= KEY_DECL_TYPE |
| 213 | keySer = s.keySerializer |
| 214 | } else { |
| 215 | keyTypeInfo, _ := getTypeInfoForValue(*entryKey, resolver) |
| 216 | resolver.WriteTypeInfo(buf, keyTypeInfo, ctx.Err()) |
| 217 | keySer = keyTypeInfo.Serializer |
| 218 | keyWriteRef = s.keyReferencable && keyTypeInfo.NeedWriteRef |
| 219 | } |
| 220 | |
| 221 | // Determine value serializer and write type info if needed |
| 222 | if s.hasGenerics && s.valueSerializer != nil { |
| 223 | header |= VALUE_DECL_TYPE |
| 224 | valSer = s.valueSerializer |
| 225 | } else { |
| 226 | valueTypeInfo, _ := getTypeInfoForValue(*entryVal, resolver) |
| 227 | resolver.WriteTypeInfo(buf, valueTypeInfo, ctx.Err()) |
| 228 | valSer = valueTypeInfo.Serializer |
| 229 | valueWriteRef = s.valueReferencable && valueTypeInfo.NeedWriteRef |
| 230 | } |
| 231 | |
| 232 | // Set ref tracking flags |
| 233 | keyRefMode := RefModeNone |
| 234 | if keyWriteRef && trackRef { |
| 235 | header |= TRACKING_KEY_REF |
| 236 | keyRefMode = RefModeTracking |
| 237 | } |
| 238 | valueRefMode := RefModeNone |
| 239 | if valueWriteRef && trackRef { |
| 240 | header |= TRACKING_VALUE_REF |
| 241 | valueRefMode = RefModeTracking |
| 242 | } |
| 243 | |
| 244 | buf.PutUint8(headerOffset, uint8(header)) |
| 245 | |
| 246 | // Write entries with same type |
| 247 | chunkSize := 0 |
| 248 | for chunkSize < MAX_CHUNK_SIZE { |
| 249 | k := *entryKey |
| 250 | v := *entryVal |
| 251 | |
| 252 | // Break if null or type changed |
| 253 | if !k.IsValid() || !v.IsValid() || k.Type() != keyType || v.Type() != valueType { |
no test coverage detected