1651f58bfSDiana Picus //===-- runtime/connection.cpp --------------------------------------------===//
295696d56Speter klausler //
395696d56Speter klausler // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
495696d56Speter klausler // See https://llvm.org/LICENSE.txt for license information.
595696d56Speter klausler // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
695696d56Speter klausler //
795696d56Speter klausler //===----------------------------------------------------------------------===//
895696d56Speter klausler 
995696d56Speter klausler #include "connection.h"
1095696d56Speter klausler #include "environment.h"
11e7823608SPeter Klausler #include "io-stmt.h"
12231fae90SIsuru Fernando #include <algorithm>
1395696d56Speter klausler 
1495696d56Speter klausler namespace Fortran::runtime::io {
1595696d56Speter klausler 
RemainingSpaceInRecord() const1695696d56Speter klausler std::size_t ConnectionState::RemainingSpaceInRecord() const {
17*3a96446dSPeter Klausler   auto recl{recordLength.value_or(openRecl.value_or(
18*3a96446dSPeter Klausler       executionEnvironment.listDirectedOutputLineLengthLimit))};
193b635714Speter klausler   return positionInRecord >= recl ? 0 : recl - positionInRecord;
203b635714Speter klausler }
213b635714Speter klausler 
NeedAdvance(std::size_t width) const226a1c3efaSpeter klausler bool ConnectionState::NeedAdvance(std::size_t width) const {
236a1c3efaSpeter klausler   return positionInRecord > 0 && width > RemainingSpaceInRecord();
246a1c3efaSpeter klausler }
256a1c3efaSpeter klausler 
IsAtEOF() const263b635714Speter klausler bool ConnectionState::IsAtEOF() const {
273b635714Speter klausler   return endfileRecordNumber && currentRecordNumber >= *endfileRecordNumber;
283b635714Speter klausler }
293b635714Speter klausler 
IsAfterEndfile() const30ac4202feSPeter Klausler bool ConnectionState::IsAfterEndfile() const {
31ac4202feSPeter Klausler   return endfileRecordNumber && currentRecordNumber > *endfileRecordNumber;
32ac4202feSPeter Klausler }
33ac4202feSPeter Klausler 
HandleAbsolutePosition(std::int64_t n)343b635714Speter klausler void ConnectionState::HandleAbsolutePosition(std::int64_t n) {
353b635714Speter klausler   positionInRecord = std::max(n, std::int64_t{0}) + leftTabLimit.value_or(0);
363b635714Speter klausler }
373b635714Speter klausler 
HandleRelativePosition(std::int64_t n)383b635714Speter klausler void ConnectionState::HandleRelativePosition(std::int64_t n) {
393b635714Speter klausler   positionInRecord = std::max(leftTabLimit.value_or(0), positionInRecord + n);
4095696d56Speter klausler }
41e7823608SPeter Klausler 
SavedPosition(IoStatementState & io)42e7823608SPeter Klausler SavedPosition::SavedPosition(IoStatementState &io) : io_{io} {
43e7823608SPeter Klausler   ConnectionState &conn{io_.GetConnectionState()};
44e7823608SPeter Klausler   saved_ = conn;
45e7823608SPeter Klausler   conn.pinnedFrame = true;
46e7823608SPeter Klausler }
47e7823608SPeter Klausler 
~SavedPosition()48e7823608SPeter Klausler SavedPosition::~SavedPosition() {
49e7823608SPeter Klausler   ConnectionState &conn{io_.GetConnectionState()};
50e7823608SPeter Klausler   while (conn.currentRecordNumber > saved_.currentRecordNumber) {
51e7823608SPeter Klausler     io_.BackspaceRecord();
52e7823608SPeter Klausler   }
53e7823608SPeter Klausler   conn.leftTabLimit = saved_.leftTabLimit;
54e7823608SPeter Klausler   conn.furthestPositionInRecord = saved_.furthestPositionInRecord;
55e7823608SPeter Klausler   conn.positionInRecord = saved_.positionInRecord;
56e7823608SPeter Klausler   conn.pinnedFrame = saved_.pinnedFrame;
57e7823608SPeter Klausler }
581f879005STim Keith } // namespace Fortran::runtime::io
59