11#ifndef FORTRAN_RUNTIME_IO_UNIT_H_
12#define FORTRAN_RUNTIME_IO_UNIT_H_
15#include "connection.h"
16#include "environment.h"
22#include "terminator.h"
23#include "flang/Common/constexpr-bitset.h"
24#include "flang/Common/optional.h"
25#include "flang/Runtime/memory.h"
28#include <flang/Common/variant.h>
30namespace Fortran::runtime::io {
34class ExternalFileUnit;
36RT_OFFLOAD_VAR_GROUP_BEGIN
38extern RT_VAR_ATTRS ExternalFileUnit *defaultInput;
39extern RT_VAR_ATTRS ExternalFileUnit *defaultOutput;
40extern RT_VAR_ATTRS ExternalFileUnit *errorOutput;
41RT_OFFLOAD_VAR_GROUP_END
43#if defined(RT_USE_PSEUDO_FILE_UNIT)
52 using FileOffset = std::int64_t;
54 RT_API_ATTRS
const char *path()
const {
return nullptr; }
55 RT_API_ATTRS std::size_t pathLength()
const {
return 0; }
56 RT_API_ATTRS
void set_path(OwningPtr<char> &&, std::size_t bytes) {}
57 RT_API_ATTRS
bool mayRead()
const {
return false; }
58 RT_API_ATTRS
bool mayWrite()
const {
return true; }
59 RT_API_ATTRS
bool mayPosition()
const {
return false; }
60 RT_API_ATTRS
bool mayAsynchronous()
const {
return false; }
61 RT_API_ATTRS
void set_mayAsynchronous(
bool yes);
64 RT_API_ATTRS
bool isTerminal()
const {
return true; }
65 RT_API_ATTRS
bool isWindowsTextFile()
const {
return false; }
66 RT_API_ATTRS Fortran::common::optional<FileOffset> knownSize()
const;
67 RT_API_ATTRS
bool IsConnected()
const {
return false; }
68 RT_API_ATTRS
void Open(OpenStatus, Fortran::common::optional<Action>,
69 Position, IoErrorHandler &);
70 RT_API_ATTRS
void Predefine(
int fd) {}
71 RT_API_ATTRS
void Close(CloseStatus, IoErrorHandler &);
72 RT_API_ATTRS std::size_t Read(FileOffset,
char *, std::size_t minBytes,
73 std::size_t maxBytes, IoErrorHandler &);
74 RT_API_ATTRS std::size_t Write(
75 FileOffset,
const char *, std::size_t, IoErrorHandler &);
76 RT_API_ATTRS
void Truncate(FileOffset, IoErrorHandler &);
77 RT_API_ATTRS
int ReadAsynchronously(
78 FileOffset,
char *, std::size_t, IoErrorHandler &);
79 RT_API_ATTRS
int WriteAsynchronously(
80 FileOffset,
const char *, std::size_t, IoErrorHandler &);
81 RT_API_ATTRS
void Wait(
int id, IoErrorHandler &);
82 RT_API_ATTRS
void WaitAll(IoErrorHandler &);
83 RT_API_ATTRS Position InquirePosition()
const;
87#if !defined(RT_USE_PSEUDO_FILE_UNIT)
88using OpenFileClass = OpenFile;
89using FileFrameClass = FileFrame<ExternalFileUnit>;
91using OpenFileClass = PseudoOpenFile;
93using FileFrameClass = FileFrame<ExternalFileUnit, 1024>;
100 static constexpr int maxAsyncIds{64 * 16};
103 : unitNumber_{unitNumber} {
104 isUTF8 = executionEnvironment.defaultUTF8;
105 for (
int j{0}; 64 * j < maxAsyncIds; ++j) {
106 asyncIdAvailable_[j].set();
108 asyncIdAvailable_[0].reset(0);
112 RT_API_ATTRS
int unitNumber()
const {
return unitNumber_; }
113 RT_API_ATTRS
bool swapEndianness()
const {
return swapEndianness_; }
114 RT_API_ATTRS
bool createdForInternalChildIo()
const {
115 return createdForInternalChildIo_;
120 int unit,
const Terminator &,
bool &wasExtant);
122 Direction, Fortran::common::optional<bool> isUnformatted,
125 const char *path, std::size_t pathLen);
134 RT_API_ATTRS
bool OpenUnit(Fortran::common::optional<OpenStatus>,
137 RT_API_ATTRS
bool OpenAnonymousUnit(Fortran::common::optional<OpenStatus>,
138 Fortran::common::optional<Action>, Position, Convert,
IoErrorHandler &);
140 RT_API_ATTRS
void DestroyClosed();
142 RT_API_ATTRS Iostat SetDirection(Direction);
144 template <
typename A,
typename... X>
149 if (!lock_.TakeIfNoDeadlock()) {
150 terminator.Crash(
"Recursive I/O attempted on unit %d", unitNumber_);
155 A &state{u_.emplace<A>(std::forward<X>(xs)...)};
156 if constexpr (!std::is_same_v<A, OpenStatementState>) {
157 state.mutableModes() = ConnectionState::modes;
159 directAccessRecWasSet_ =
false;
164 RT_API_ATTRS
bool Emit(
165 const char *, std::size_t, std::size_t elementBytes,
IoErrorHandler &);
166 RT_API_ATTRS
bool Receive(
168 RT_API_ATTRS std::size_t GetNextInputBytes(
const char *&,
IoErrorHandler &);
169 RT_API_ATTRS std::size_t ViewBytesInRecord(
const char *&,
bool forward)
const;
178 RT_API_ATTRS
void EndIoStatement();
179 RT_API_ATTRS
bool SetStreamPos(
181 RT_API_ATTRS
bool SetDirectRec(
183 RT_API_ATTRS std::int64_t InquirePos()
const {
185 return frameOffsetInFile_ + recordOffsetInFrame_ + positionInRecord + 1;
188 RT_API_ATTRS
ChildIo *GetChildIo() {
return child_.get(); }
190 RT_API_ATTRS
void PopChildIo(
ChildIo &);
193 RT_API_ATTRS
bool Wait(
int);
196 static RT_API_ATTRS
UnitMap &CreateUnitMap();
197 static RT_API_ATTRS
UnitMap &GetUnitMap();
198 RT_API_ATTRS
const char *FrameNextInput(
IoErrorHandler &, std::size_t);
200 RT_API_ATTRS
void BeginSequentialVariableUnformattedInputRecord(
202 RT_API_ATTRS
void BeginVariableFormattedInputRecord(
IoErrorHandler &);
204 RT_API_ATTRS
void BackspaceVariableUnformattedRecord(
IoErrorHandler &);
205 RT_API_ATTRS
void BackspaceVariableFormattedRecord(
IoErrorHandler &);
206 RT_API_ATTRS
bool SetVariableFormattedRecordLength();
208 template <
bool ANY_DIR = true, Direction DIR = Direction::Output>
210 RT_API_ATTRS
void CommitWrites();
213 RT_API_ATTRS std::int32_t ReadHeaderOrFooter(std::int64_t frameOffset);
218 Direction direction_{Direction::Output};
219 bool impliedEndfile_{
false};
220 bool beganReadingRecord_{
false};
221 bool anyWriteSinceLastPositioning_{
false};
222 bool directAccessRecWasSet_{
false};
227 std::int64_t frameOffsetInFile_{0};
228 std::size_t recordOffsetInFrame_{0};
229 bool swapEndianness_{
false};
230 bool createdForInternalChildIo_{
false};
246 Fortran::common::optional<IoStatementState> io_;
259 : parent_{parent}, previous_{std::move(previous)} {}
263 RT_API_ATTRS
void EndIoStatement();
265 template <
typename A,
typename... X>
267 A &state{u_.emplace<A>(std::forward<X>(xs)...)};
273 return std::move(previous_);
276 RT_API_ATTRS Iostat CheckFormattingAndDirection(
bool unformatted, Direction);
281 std::variant<std::monostate,
290 Fortran::common::optional<IoStatementState> io_;
Definition: constexpr-bitset.h:25
Definition: terminator.h:23
Definition: io-stmt.h:581
Definition: io-stmt.h:635
Definition: io-stmt.h:776
Definition: io-stmt.h:520
Definition: io-stmt.h:763
Definition: io-stmt.h:717
Definition: io-error.h:26
Definition: io-stmt.h:596
Definition: unit-map.h:24
Definition: connection.h:47