(ctx *ReadContext, value reflect.Value)
| 1373 | } |
| 1374 | |
| 1375 | func (s *structSerializer) ReadData(ctx *ReadContext, value reflect.Value) { |
| 1376 | // Early error check - skip all intermediate checks for normal path performance |
| 1377 | if ctx.HasError() { |
| 1378 | return |
| 1379 | } |
| 1380 | |
| 1381 | // Lazy initialization |
| 1382 | if !s.initialized { |
| 1383 | if err := s.initialize(ctx.TypeResolver()); err != nil { |
| 1384 | ctx.SetError(FromError(err)) |
| 1385 | return |
| 1386 | } |
| 1387 | } |
| 1388 | |
| 1389 | buf := ctx.Buffer() |
| 1390 | if value.Kind() == reflect.Ptr { |
| 1391 | if value.IsNil() { |
| 1392 | value.Set(reflect.New(value.Type().Elem())) |
| 1393 | } |
| 1394 | value = value.Elem() |
| 1395 | } |
| 1396 | |
| 1397 | // In compatible mode with meta share, struct hash is not written |
| 1398 | if !ctx.Compatible() { |
| 1399 | err := ctx.Err() |
| 1400 | structHash := buf.ReadInt32(err) |
| 1401 | if structHash != s.structHash { |
| 1402 | ctx.SetError(HashMismatchError(structHash, s.structHash, s.type_.String())) |
| 1403 | return |
| 1404 | } |
| 1405 | } |
| 1406 | |
| 1407 | // Fail fast if value is not addressable - we require unsafe pointer access |
| 1408 | if !value.CanAddr() { |
| 1409 | ctx.SetError(SerializationError("cannot deserialize struct " + s.type_.Name() + " into non-addressable value")) |
| 1410 | return |
| 1411 | } |
| 1412 | |
| 1413 | // Use ordered reading when TypeDef differs from local type (schema evolution) |
| 1414 | if s.typeDefDiffers { |
| 1415 | s.readFieldsInOrder(ctx, value) |
| 1416 | return |
| 1417 | } |
| 1418 | |
| 1419 | // ========================================================================== |
| 1420 | // Grouped reading for matching types (optimized path) |
| 1421 | // - Types match, so all fields exist locally (no FieldIndex < 0 checks) |
| 1422 | // - Use UnsafeGet at pre-computed offsets, update reader index once per phase |
| 1423 | // ========================================================================== |
| 1424 | ptr := unsafe.Pointer(value.UnsafeAddr()) |
| 1425 | |
| 1426 | // Phase 1: Fixed-size primitives (inline unsafe reads with endian handling) |
| 1427 | if s.fieldGroup.FixedSize > 0 { |
| 1428 | var errOut Error |
| 1429 | if !buf.CheckReadable(int(s.fieldGroup.FixedSize), &errOut) { |
| 1430 | ctx.SetError(errOut) |
| 1431 | return |
| 1432 | } |
no test coverage detected