MCPcopy Create free account
hub / github.com/TombEngine/TombEngine / EndTable

Function EndTable

Libs/flatbuffers/flatbuffers.h:1518–1580  ·  view source on GitHub ↗

This finishes one serialized object by generating the vtable if it's a table, comparing it against existing vtables, and writing the resulting vtable offset.

Source from the content-addressed store, hash-verified

1516 // table, comparing it against existing vtables, and writing the
1517 // resulting vtable offset.
1518 uoffset_t EndTable(uoffset_t start) {
1519 // If you get this assert, a corresponding StartTable wasn't called.
1520 FLATBUFFERS_ASSERT(nested);
1521 // Write the vtable offset, which is the start of any Table.
1522 // We fill it's value later.
1523 auto vtableoffsetloc = PushElement<soffset_t>(0);
1524 // Write a vtable, which consists entirely of voffset_t elements.
1525 // It starts with the number of offsets, followed by a type id, followed
1526 // by the offsets themselves. In reverse:
1527 // Include space for the last offset and ensure empty tables have a
1528 // minimum size.
1529 max_voffset_ =
1530 (std::max)(static_cast<voffset_t>(max_voffset_ + sizeof(voffset_t)),
1531 FieldIndexToOffset(0));
1532 buf_.fill_big(max_voffset_);
1533 auto table_object_size = vtableoffsetloc - start;
1534 // Vtable use 16bit offsets.
1535 FLATBUFFERS_ASSERT(table_object_size < 0x10000);
1536 WriteScalar<voffset_t>(buf_.data() + sizeof(voffset_t),
1537 static_cast<voffset_t>(table_object_size));
1538 WriteScalar<voffset_t>(buf_.data(), max_voffset_);
1539 // Write the offsets into the table
1540 for (auto it = buf_.scratch_end() - num_field_loc * sizeof(FieldLoc);
1541 it < buf_.scratch_end(); it += sizeof(FieldLoc)) {
1542 auto field_location = reinterpret_cast<FieldLoc *>(it);
1543 auto pos = static_cast<voffset_t>(vtableoffsetloc - field_location->off);
1544 // If this asserts, it means you've set a field twice.
1545 FLATBUFFERS_ASSERT(
1546 !ReadScalar<voffset_t>(buf_.data() + field_location->id));
1547 WriteScalar<voffset_t>(buf_.data() + field_location->id, pos);
1548 }
1549 ClearOffsets();
1550 auto vt1 = reinterpret_cast<voffset_t *>(buf_.data());
1551 auto vt1_size = ReadScalar<voffset_t>(vt1);
1552 auto vt_use = GetSize();
1553 // See if we already have generated a vtable with this exact same
1554 // layout before. If so, make it point to the old one, remove this one.
1555 if (dedup_vtables_) {
1556 for (auto it = buf_.scratch_data(); it < buf_.scratch_end();
1557 it += sizeof(uoffset_t)) {
1558 auto vt_offset_ptr = reinterpret_cast<uoffset_t *>(it);
1559 auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr));
1560 auto vt2_size = ReadScalar<voffset_t>(vt2);
1561 if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue;
1562 vt_use = *vt_offset_ptr;
1563 buf_.pop(GetSize() - vtableoffsetloc);
1564 break;
1565 }
1566 }
1567 // If this is a new vtable, remember it.
1568 if (vt_use == GetSize()) { buf_.scratch_push_small(vt_use); }
1569 // Fill the vtable offset we created above.
1570 // The offset points from the beginning of the object to where the
1571 // vtable is stored.
1572 // Offsets default direction is downward in memory for future format
1573 // flexibility (storing all vtables at the start of the file).
1574 WriteScalar(buf_.data_at(vtableoffsetloc),
1575 static_cast<soffset_t>(vt_use) -

Callers

nothing calls this directly

Calls 6

FieldIndexToOffsetFunction · 0.85
ClearOffsetsFunction · 0.85
WriteScalarFunction · 0.85
GetSizeFunction · 0.70
dataMethod · 0.45
popMethod · 0.45

Tested by

no test coverage detected