blob: c812312de91dc273ff5f78842085b2867b451db8 [file] [log] [blame]
peter klausler95696d52020-02-05 00:55:451//===-- runtime/connection.h ------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
peter klausler3b635712020-02-13 22:41:569// Fortran I/O connection state (abstracted over internal & external units)
peter klausler95696d52020-02-05 00:55:4510
11#ifndef FORTRAN_RUNTIME_IO_CONNECTION_H_
12#define FORTRAN_RUNTIME_IO_CONNECTION_H_
13
14#include "format.h"
15#include <cinttypes>
16#include <optional>
17
18namespace Fortran::runtime::io {
19
Peter Klauslere7823602021-11-03 22:33:2920class IoStatementState;
21
peter klausler3b635712020-02-13 22:41:5622enum class Direction { Output, Input };
peter klausler95696d52020-02-05 00:55:4523enum class Access { Sequential, Direct, Stream };
24
25inline bool IsRecordFile(Access a) { return a != Access::Stream; }
26
27// These characteristics of a connection are immutable after being
Peter Klausler06ca9f22021-12-03 00:36:0928// established in an OPEN statement.
peter klausler95696d52020-02-05 00:55:4529struct ConnectionAttributes {
Tim Keith1f879002020-03-29 04:00:1630 Access access{Access::Sequential}; // ACCESS='SEQUENTIAL', 'DIRECT', 'STREAM'
peter klausler199a6232021-05-05 18:33:0031 std::optional<bool> isUnformatted; // FORM='UNFORMATTED' if true
Tim Keith1f879002020-03-29 04:00:1632 bool isUTF8{false}; // ENCODING='UTF-8'
Peter Klausler06ca9f22021-12-03 00:36:0933 std::optional<std::int64_t> openRecl; // RECL= on OPEN
peter klausler95696d52020-02-05 00:55:4534};
35
36struct ConnectionState : public ConnectionAttributes {
Tim Keith1f879002020-03-29 04:00:1637 bool IsAtEOF() const; // true when read has hit EOF or endfile record
Peter Klauslerac4202f2022-01-07 18:29:2338 bool IsAfterEndfile() const; // true after ENDFILE until repositioned
peter klausler95696d52020-02-05 00:55:4539 std::size_t RemainingSpaceInRecord() const;
peter klausler6a1c3ef2021-05-05 18:37:4940 bool NeedAdvance(std::size_t) const;
peter klausler3b635712020-02-13 22:41:5641 void HandleAbsolutePosition(std::int64_t);
42 void HandleRelativePosition(std::int64_t);
43
peter klausler37f98f62020-07-02 21:11:1444 void BeginRecord() {
45 positionInRecord = 0;
46 furthestPositionInRecord = 0;
47 leftTabLimit.reset();
48 }
49
Peter Klausler06ca9f22021-12-03 00:36:0950 std::optional<std::int64_t> EffectiveRecordLength() const {
51 // When an input record is longer than an explicit RECL= from OPEN
52 // it is effectively truncated on input.
53 return openRecl && recordLength && *openRecl < *recordLength ? openRecl
54 : recordLength;
55 }
56
57 std::optional<std::int64_t> recordLength;
58
peter klausler3b635712020-02-13 22:41:5659 // Positions in a record file (sequential or direct, not stream)
Tim Keith1f879002020-03-29 04:00:1660 std::int64_t currentRecordNumber{1}; // 1 is first
61 std::int64_t positionInRecord{0}; // offset in current record
peter klausler27505562020-06-18 19:19:4962 std::int64_t furthestPositionInRecord{0}; // max(position+bytes)
peter klausler3b635712020-02-13 22:41:5663
peter klausler95696d52020-02-05 00:55:4564 // Set at end of non-advancing I/O data transfer
Tim Keith1f879002020-03-29 04:00:1665 std::optional<std::int64_t> leftTabLimit; // offset in current record
peter klausler3b635712020-02-13 22:41:5666
peter klausler95696d52020-02-05 00:55:4567 // currentRecordNumber value captured after ENDFILE/REWIND/BACKSPACE statement
peter klausler3b635712020-02-13 22:41:5668 // or an end-of-file READ condition on a sequential access file
peter klausler95696d52020-02-05 00:55:4569 std::optional<std::int64_t> endfileRecordNumber;
peter klausler3b635712020-02-13 22:41:5670
Peter Klauslere7823602021-11-03 22:33:2971 // Mutable modes set at OPEN() that can be overridden in READ/WRITE & FORMAT
72 MutableModes modes; // BLANK=, DECIMAL=, SIGN=, ROUND=, PAD=, DELIM=, kP
73
peter klauslerdfea0112021-08-16 20:15:0174 // Set when processing repeated items during list-directed & NAMELIST input
75 // in order to keep a span of records in frame on a non-positionable file,
76 // so that backspacing to the beginning of the repeated item doesn't require
77 // repositioning the external storage medium when that's impossible.
Peter Klauslere7823602021-11-03 22:33:2978 bool pinnedFrame{false};
peter klausler95696d52020-02-05 00:55:4579};
peter klauslerb8452db2021-10-20 20:56:4780
81// Utility class for capturing and restoring a position in an input stream.
82class SavedPosition {
83public:
Peter Klauslere7823602021-11-03 22:33:2984 explicit SavedPosition(IoStatementState &);
85 ~SavedPosition();
peter klauslerb8452db2021-10-20 20:56:4786
87private:
Peter Klauslere7823602021-11-03 22:33:2988 IoStatementState &io_;
89 ConnectionState saved_;
peter klauslerb8452db2021-10-20 20:56:4790};
91
Tim Keith1f879002020-03-29 04:00:1692} // namespace Fortran::runtime::io
93#endif // FORTRAN_RUNTIME_IO_CONNECTION_H_