ReadStruct reads a struct value with optimized type resolution. This method uses ReadTypeInfoForType to avoid expensive type resolution via map lookups when the expected type is already known.
(value reflect.Value)
| 865 | // This method uses ReadTypeInfoForType to avoid expensive type resolution via map lookups |
| 866 | // when the expected type is already known. |
| 867 | func (c *ReadContext) ReadStruct(value reflect.Value) { |
| 868 | if !value.IsValid() { |
| 869 | c.SetError(DeserializationError("invalid reflect.Value")) |
| 870 | return |
| 871 | } |
| 872 | |
| 873 | // Handle pointer to struct |
| 874 | valueType := value.Type() |
| 875 | isPtr := valueType.Kind() == reflect.Ptr |
| 876 | var structType reflect.Type |
| 877 | if isPtr { |
| 878 | structType = valueType.Elem() |
| 879 | } else { |
| 880 | structType = valueType |
| 881 | } |
| 882 | |
| 883 | refResolver := c.RefResolver() |
| 884 | refID := int32(NotNullValueFlag) |
| 885 | if refResolver.refTracking { |
| 886 | var err error |
| 887 | refID, err = refResolver.TryPreserveRefId(c.buffer) |
| 888 | if err != nil { |
| 889 | c.SetError(FromError(err)) |
| 890 | return |
| 891 | } |
| 892 | if refID == int32(NullFlag) { |
| 893 | if isPtr { |
| 894 | value.Set(reflect.Zero(valueType)) |
| 895 | } |
| 896 | return |
| 897 | } |
| 898 | if refID < int32(NotNullValueFlag) { |
| 899 | obj := refResolver.GetReadObject(refID) |
| 900 | if obj.IsValid() { |
| 901 | value.Set(obj) |
| 902 | } |
| 903 | return |
| 904 | } |
| 905 | } else { |
| 906 | refFlag := c.buffer.ReadInt8(c.Err()) |
| 907 | if refFlag == NullFlag { |
| 908 | if isPtr { |
| 909 | value.Set(reflect.Zero(valueType)) |
| 910 | } |
| 911 | return |
| 912 | } |
| 913 | if refFlag == RefFlag { |
| 914 | c.buffer.ReadVarUint32(c.Err()) |
| 915 | return |
| 916 | } |
| 917 | } |
| 918 | |
| 919 | // Use ReadTypeInfoForType to get serializer directly by type - avoids map lookups |
| 920 | ctxErr := c.Err() |
| 921 | serializer := c.typeResolver.ReadTypeInfoForType(c.buffer, structType, ctxErr) |
| 922 | if ctxErr.HasError() || serializer == nil { |
| 923 | if !ctxErr.HasError() { |
| 924 | c.SetError(DeserializationErrorf("no serializer registered for struct %v", structType)) |
no test coverage detected