ReadData deserializes map data using chunk protocol
(ctx *ReadContext, value reflect.Value)
| 287 | |
| 288 | // ReadData deserializes map data using chunk protocol |
| 289 | func (s mapSerializer) ReadData(ctx *ReadContext, value reflect.Value) { |
| 290 | buf := ctx.Buffer() |
| 291 | ctxErr := ctx.Err() |
| 292 | refResolver := ctx.RefResolver() |
| 293 | typeResolver := ctx.TypeResolver() |
| 294 | type_ := value.Type() |
| 295 | |
| 296 | size := ctx.ReadCollectionLength() |
| 297 | if ctx.HasError() { |
| 298 | return |
| 299 | } |
| 300 | mapType := type_ |
| 301 | // For any maps without declared types, use map[any]any. |
| 302 | if !s.hasGenerics && type_.Key().Kind() == reflect.Interface && type_.Elem().Kind() == reflect.Interface { |
| 303 | iface := reflect.TypeOf((*any)(nil)).Elem() |
| 304 | mapType = reflect.MapOf(iface, iface) |
| 305 | } |
| 306 | if size == 0 { |
| 307 | if value.IsNil() { |
| 308 | value.Set(reflect.MakeMap(mapType)) |
| 309 | } |
| 310 | refResolver.Reference(value) |
| 311 | return |
| 312 | } |
| 313 | |
| 314 | chunkHeader := buf.ReadUint8(ctxErr) |
| 315 | if ctx.HasError() { |
| 316 | return |
| 317 | } |
| 318 | if !buf.CheckReadable(size, ctxErr) { |
| 319 | return |
| 320 | } |
| 321 | if value.IsNil() { |
| 322 | value.Set(reflect.MakeMapWithSize(mapType, size)) |
| 323 | } |
| 324 | refResolver.Reference(value) |
| 325 | |
| 326 | keyType := type_.Key() |
| 327 | valueType := type_.Elem() |
| 328 | |
| 329 | for size > 0 { |
| 330 | // Phase 1: Handle null entries |
| 331 | for { |
| 332 | keyHasNull := (chunkHeader & KEY_HAS_NULL) != 0 |
| 333 | valueHasNull := (chunkHeader & VALUE_HAS_NULL) != 0 |
| 334 | |
| 335 | if !keyHasNull && !valueHasNull { |
| 336 | break // Proceed to regular chunk |
| 337 | } |
| 338 | |
| 339 | if keyHasNull && valueHasNull { |
| 340 | value.SetMapIndex(reflect.Zero(keyType), reflect.Zero(valueType)) |
| 341 | } else if valueHasNull { |
| 342 | k := s.readNullValueEntry(ctx, chunkHeader, keyType, typeResolver, refResolver) |
| 343 | if ctx.HasError() { |
| 344 | return |
| 345 | } |
| 346 | value.SetMapIndex(k, reflect.Zero(valueType)) |
no test coverage detected