| 230 | } |
| 231 | |
| 232 | inline void IterateObject(const uint8_t *obj, const TypeTable *type_table, |
| 233 | IterationVisitor *visitor) { |
| 234 | visitor->StartSequence(); |
| 235 | const uint8_t *prev_val = nullptr; |
| 236 | size_t set_idx = 0; |
| 237 | size_t array_idx = 0; |
| 238 | for (size_t i = 0; i < type_table->num_elems; i++) { |
| 239 | auto type_code = type_table->type_codes[i]; |
| 240 | auto type = static_cast<ElementaryType>(type_code.base_type); |
| 241 | auto is_repeating = type_code.is_repeating != 0; |
| 242 | auto ref_idx = type_code.sequence_ref; |
| 243 | const TypeTable *ref = nullptr; |
| 244 | if (ref_idx >= 0) { ref = type_table->type_refs[ref_idx](); } |
| 245 | auto name = type_table->names ? type_table->names[i] : nullptr; |
| 246 | const uint8_t *val = nullptr; |
| 247 | if (type_table->st == ST_TABLE) { |
| 248 | val = reinterpret_cast<const Table *>(obj)->GetAddressOf( |
| 249 | FieldIndexToOffset(static_cast<voffset_t>(i))); |
| 250 | } else { |
| 251 | val = obj + type_table->values[i]; |
| 252 | } |
| 253 | visitor->Field(i, set_idx, type, is_repeating, ref, name, val); |
| 254 | if (val) { |
| 255 | set_idx++; |
| 256 | if (is_repeating) { |
| 257 | auto elem_ptr = val; |
| 258 | size_t size = 0; |
| 259 | if (type_table->st == ST_TABLE) { |
| 260 | // variable length vector |
| 261 | val += ReadScalar<uoffset_t>(val); |
| 262 | auto vec = reinterpret_cast<const Vector<uint8_t> *>(val); |
| 263 | elem_ptr = vec->Data(); |
| 264 | size = vec->size(); |
| 265 | } else { |
| 266 | // otherwise fixed size array |
| 267 | size = type_table->array_sizes[array_idx]; |
| 268 | ++array_idx; |
| 269 | } |
| 270 | visitor->StartVector(); |
| 271 | for (size_t j = 0; j < size; j++) { |
| 272 | visitor->Element(j, type, ref, elem_ptr); |
| 273 | IterateValue(type, elem_ptr, ref, prev_val, static_cast<soffset_t>(j), |
| 274 | visitor); |
| 275 | elem_ptr += InlineSize(type, ref); |
| 276 | } |
| 277 | visitor->EndVector(); |
| 278 | } else { |
| 279 | IterateValue(type, val, ref, prev_val, -1, visitor); |
| 280 | } |
| 281 | } |
| 282 | prev_val = val; |
| 283 | } |
| 284 | visitor->EndSequence(); |
| 285 | } |
| 286 | |
| 287 | inline void IterateFlatBuffer(const uint8_t *buffer, |
| 288 | const TypeTable *type_table, |
no test coverage detected