[flang-commits] [flang] [llvm] [flang-rt] Split large unformatted sequential records into subrecords (PR #213003)
via flang-commits
flang-commits at lists.llvm.org
Fri Oct 16 03:18:31 PDT 2026
================
@@ -710,40 +877,37 @@ void ExternalFileUnit::BackspaceFixedRecord(IoErrorHandler &handler) {
void ExternalFileUnit::BackspaceVariableUnformattedRecord(
IoErrorHandler &handler) {
- std::uint32_t header{0};
- auto headerBytes{static_cast<std::int64_t>(sizeof header)};
frameOffsetInFile_ += recordOffsetInFrame_;
recordOffsetInFrame_ = 0;
- if (frameOffsetInFile_ <= headerBytes) {
+ if (frameOffsetInFile_ <= static_cast<FileOffset>(kRecMarkSize)) {
handler.SignalError(IostatBackspaceAtFirstRecord);
return;
}
- // Error conditions here cause crashes, not file format errors, because the
- // validity of the file structure before the current record will have been
- // checked informatively in NextSequentialVariableUnformattedInputRecord().
- std::size_t got{
- ReadFrame(frameOffsetInFile_ - headerBytes, headerBytes, handler)};
- if (static_cast<std::int64_t>(got) < headerBytes) {
- handler.SignalError(IostatShortRead);
- return;
- }
- recordLength = ReadHeaderOrFooter(0);
- if (frameOffsetInFile_ < *recordLength + 2 * headerBytes) {
- handler.SignalError(IostatBadUnformattedRecord);
- return;
- }
- frameOffsetInFile_ -= *recordLength + 2 * headerBytes;
- auto need{static_cast<std::size_t>(
- recordOffsetInFrame_ + sizeof header + *recordLength)};
- got = ReadFrame(frameOffsetInFile_, need, handler);
- if (got < need) {
+ std::int32_t marker{0};
+ do {
+ if (ReadFrame(frameOffsetInFile_ - kRecMarkSize, kRecMarkSize, handler) <
+ kRecMarkSize) {
+ handler.SignalError(IostatShortRead);
+ return;
+ }
+ marker = LoadRecordMarker(Frame(), swapEndianness_);
+ auto payload{SubrecordPayloadBytes(marker)};
+ if (frameOffsetInFile_ <
+ static_cast<FileOffset>(payload + 2 * kRecMarkSize)) {
+ handler.SignalError(IostatBadUnformattedRecord);
+ return;
+ }
+ frameOffsetInFile_ -= static_cast<FileOffset>(payload + 2 * kRecMarkSize);
+ } while (marker < 0);
+ auto need{
+ static_cast<std::size_t>(kRecMarkSize + SubrecordPayloadBytes(marker))};
+ if (ReadFrame(frameOffsetInFile_, need, handler) < need) {
----------------
ejose02 wrote:
Done.Now read only the 4-byte header for validation, not 4 + payload.
https://github.com/llvm/llvm-project/pull/213003
More information about the flang-commits
mailing list