1 //===-- runtime/internal-unit.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 9 // Fortran internal I/O "units" 10 11 #ifndef FORTRAN_RUNTIME_IO_INTERNAL_UNIT_H_ 12 #define FORTRAN_RUNTIME_IO_INTERNAL_UNIT_H_ 13 14 #include "connection.h" 15 #include "flang/Runtime/descriptor.h" 16 #include <cinttypes> 17 #include <type_traits> 18 19 namespace Fortran::runtime::io { 20 21 class IoErrorHandler; 22 23 // Points to (but does not own) a CHARACTER scalar or array for internal I/O. 24 // Does not buffer. 25 template <Direction DIR> class InternalDescriptorUnit : public ConnectionState { 26 public: 27 using Scalar = 28 std::conditional_t<DIR == Direction::Input, const char *, char *>; 29 RT_API_ATTRS InternalDescriptorUnit(Scalar, std::size_t chars, int kind); 30 RT_API_ATTRS InternalDescriptorUnit(const Descriptor &, const Terminator &); 31 32 RT_API_ATTRS bool Emit(const char *, std::size_t, IoErrorHandler &); 33 RT_API_ATTRS std::size_t GetNextInputBytes(const char *&, IoErrorHandler &); 34 RT_API_ATTRS std::size_t ViewBytesInRecord(const char *&, bool forward) const; 35 RT_API_ATTRS bool AdvanceRecord(IoErrorHandler &); 36 RT_API_ATTRS void BackspaceRecord(IoErrorHandler &); 37 RT_API_ATTRS std::int64_t InquirePos(); 38 39 private: 40 RT_API_ATTRS Descriptor &descriptor() { 41 return staticDescriptor_.descriptor(); 42 } 43 RT_API_ATTRS const Descriptor &descriptor() const { 44 return staticDescriptor_.descriptor(); 45 } 46 RT_API_ATTRS Scalar CurrentRecord() const { 47 return descriptor().template ZeroBasedIndexedElement<char>( 48 currentRecordNumber - 1); 49 } 50 RT_API_ATTRS void BlankFill(char *, std::size_t); 51 RT_API_ATTRS void BlankFillOutputRecord(); 52 53 StaticDescriptor<maxRank, true /*addendum*/> staticDescriptor_; 54 }; 55 56 extern template class InternalDescriptorUnit<Direction::Output>; 57 extern template class InternalDescriptorUnit<Direction::Input>; 58 } // namespace Fortran::runtime::io 59 #endif // FORTRAN_RUNTIME_IO_INTERNAL_UNIT_H_ 60