MCPcopy Create free account
hub / github.com/apache/fory / read_struct_fields_impl

Function read_struct_fields_impl

cpp/fory/serialization/struct_serializer.h:4175–4228  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

4173/// Both paths pre-check bounds and update reader_index once at the end.
4174template <typename T, size_t... Indices>
4175void read_struct_fields_impl(T &obj, ReadContext &ctx,
4176 std::index_sequence<Indices...>) {
4177 using Helpers = CompileTimeFieldHelpers<T>;
4178 constexpr size_t fixed_count = Helpers::leading_fixed_count;
4179 constexpr size_t fixed_bytes = Helpers::leading_fixed_size_bytes;
4180 constexpr size_t varint_count = Helpers::varint_count;
4181 constexpr size_t total_count = sizeof...(Indices);
4182
4183 // FAST PATH: When compatible=false, use optimized batch reading
4184 if (!ctx.is_compatible()) {
4185 Buffer &buffer = ctx.buffer();
4186
4187 // Phase 1: Read leading fixed-size primitives if any
4188 if constexpr (fixed_count > 0 && fixed_bytes > 0) {
4189 if (FORY_PREDICT_FALSE(!buffer.ensure_readable(
4190 static_cast<uint32_t>(fixed_bytes), ctx.error()))) {
4191 return;
4192 }
4193 // Fast read fixed-size primitives
4194 read_fixed_primitive_fields<T>(obj, buffer,
4195 std::make_index_sequence<fixed_count>{});
4196 }
4197
4198 // Phase 2: Read consecutive varint primitives (int32, int64) if any
4199 // Note: varint bounds checking is done per-byte during reading since
4200 // varint lengths are variable (actual size << max possible size)
4201 if constexpr (varint_count > 0) {
4202 if (FORY_PREDICT_FALSE(buffer.has_input_stream())) {
4203 // Stream-backed buffers may not have all varint bytes materialized yet.
4204 // Fall back to per-field readers that propagate stream read errors.
4205 read_remaining_fields<T, fixed_count, total_count>(obj, ctx);
4206 return;
4207 }
4208 // Track offset locally for batch varint reading
4209 uint32_t offset = buffer.reader_index();
4210 // Fast read varint primitives (bounds checking happens in
4211 // get_var_uint32/64)
4212 read_varint_primitive_fields<T, fixed_count>(
4213 obj, buffer, offset, std::make_index_sequence<varint_count>{});
4214 // Update reader_index once after all varints
4215 buffer.reader_index(offset);
4216 }
4217
4218 // Phase 3: Read remaining fields (if any) with normal path
4219 constexpr size_t fast_count = fixed_count + varint_count;
4220 if constexpr (fast_count < total_count) {
4221 read_remaining_fields<T, fast_count, total_count>(obj, ctx);
4222 }
4223 return;
4224 }
4225
4226 // NORMAL PATH: compatible mode - all fields need full serialization
4227 (read_field_at_sorted_position<T, Indices>(obj, ctx), ...);
4228}
4229
4230/// Read struct fields in sorted order using the fast primitive paths.
4231/// Used when compatible mode is enabled but the remote schema matches locally.

Callers 1

read_dataMethod · 0.85

Calls 6

ensure_readableMethod · 0.80
has_input_streamMethod · 0.80
reader_indexMethod · 0.80
errorMethod · 0.65
is_compatibleMethod · 0.45
bufferMethod · 0.45

Tested by

no test coverage detected