Index: flang/runtime/unit.h =================================================================== --- flang/runtime/unit.h +++ flang/runtime/unit.h @@ -133,6 +133,7 @@ void CommitWrites(); bool CheckDirectAccess(IoErrorHandler &); void HitEndOnRead(IoErrorHandler &); + std::int32_t ReadHeaderOrFooter(std::int64_t frameOffset); Lock lock_; // TODO: replace with a thread ID Index: flang/runtime/unit.cpp =================================================================== --- flang/runtime/unit.cpp +++ flang/runtime/unit.cpp @@ -263,7 +263,7 @@ } } -static void SwapEndianness( +static inline void SwapEndianness( char *data, std::size_t bytes, std::size_t elementBytes) { if (elementBytes > 1) { auto half{elementBytes >> 1}; @@ -717,7 +717,7 @@ "record #%jd (file offset %jd): truncated record header"; } } else { - std::memcpy(&header, Frame() + recordOffsetInFrame_, sizeof header); + header = ReadHeaderOrFooter(recordOffsetInFrame_); recordLength = sizeof header + header; // does not include footer need = recordOffsetInFrame_ + *recordLength + sizeof footer; got = ReadFrame(frameOffsetInFile_, need, handler); @@ -726,8 +726,7 @@ "record #%jd (file offset %jd): hit EOF reading record with " "length %jd bytes"; } else { - std::memcpy(&footer, Frame() + recordOffsetInFrame_ + *recordLength, - sizeof footer); + footer = ReadHeaderOrFooter(recordOffsetInFrame_ + *recordLength); if (footer != header) { error = "Unformatted variable-length sequential file input failed at " "record #%jd (file offset %jd): record header has length %jd " @@ -784,7 +783,7 @@ void ExternalFileUnit::BackspaceVariableUnformattedRecord( IoErrorHandler &handler) { - std::int32_t header{0}, footer{0}; + std::int32_t header{0}; auto headerBytes{static_cast(sizeof header)}; frameOffsetInFile_ += recordOffsetInFrame_; recordOffsetInFrame_ = 0; @@ -801,8 +800,7 @@ handler.SignalError(IostatShortRead); return; } - std::memcpy(&footer, Frame(), sizeof footer); - recordLength = footer; + recordLength = ReadHeaderOrFooter(0); if (frameOffsetInFile_ < *recordLength + 2 * headerBytes) { handler.SignalError(IostatBadUnformattedRecord); return; @@ -819,7 +817,7 @@ handler.SignalError(IostatShortRead); return; } - std::memcpy(&header, Frame() + recordOffsetInFrame_, sizeof header); + header = ReadHeaderOrFooter(recordOffsetInFrame_); if (header != *recordLength) { handler.SignalError(IostatBadUnformattedRecord); return; @@ -977,6 +975,16 @@ } } +std::int32_t ExternalFileUnit::ReadHeaderOrFooter(std::int64_t frameOffset) { + std::int32_t word; + char *wordPtr{reinterpret_cast(&word)}; + std::memcpy(wordPtr, Frame() + frameOffset, sizeof word); + if (swapEndianness_) { + SwapEndianness(wordPtr, sizeof word, sizeof word); + } + return word; +} + void ChildIo::EndIoStatement() { io_.reset(); u_.emplace();