11#ifndef FORTRAN_RUNTIME_EMIT_ENCODED_H_
12#define FORTRAN_RUNTIME_EMIT_ENCODED_H_
14#include "connection.h"
15#include "environment.h"
19namespace Fortran::runtime::io {
21template <
typename CONTEXT,
typename CHAR,
bool NL_ADVANCES_RECORD = true>
22RT_API_ATTRS
bool EmitEncoded(
23 CONTEXT &to,
const CHAR *data, std::size_t chars) {
24 ConnectionState &connection{to.GetConnectionState()};
25 if constexpr (NL_ADVANCES_RECORD) {
26 if (connection.access == Access::Stream &&
27 connection.internalIoCharKind == 0) {
30 while (
const CHAR * nl{FindCharacter(data, CHAR{
'\n'}, chars)}) {
31 auto pos{
static_cast<std::size_t
>(nl - data)};
34 if (!EmitEncoded<CONTEXT, CHAR, false>(to, data, pos)) {
43 if (connection.useUTF8<CHAR>()) {
44 using UnsignedChar = std::make_unsigned_t<CHAR>;
45 const UnsignedChar *uData{
reinterpret_cast<const UnsignedChar *
>(data)};
49 auto len{EncodeUTF8(buffer + at, *uData++)};
51 if (at + maxUTF8Bytes >
sizeof buffer) {
52 if (!to.Emit(buffer, at)) {
58 return at == 0 || to.Emit(buffer, at);
60 std::size_t internalKind = connection.internalIoCharKind;
61 if (internalKind == 0 || internalKind ==
sizeof(CHAR)) {
62 const char *rawData{
reinterpret_cast<const char *
>(data)};
63 return to.Emit(rawData, chars *
sizeof(CHAR),
sizeof(CHAR));
67 char32_t buffer = *data++;
68 char *p{
reinterpret_cast<char *
>(&buffer)};
69 if constexpr (!isHostLittleEndian) {
70 p +=
sizeof(buffer) - internalKind;
72 if (!to.Emit(p, internalKind)) {
81template <
typename CONTEXT>
82RT_API_ATTRS
bool EmitAscii(CONTEXT &to,
const char *data, std::size_t chars) {
83 ConnectionState &connection{to.GetConnectionState()};
84 if (connection.internalIoCharKind <= 1 &&
85 connection.access != Access::Stream) {
86 return to.Emit(data, chars);
88 return EmitEncoded(to, data, chars);
92template <
typename CONTEXT>
93RT_API_ATTRS
bool EmitRepeated(CONTEXT &to,
char ch, std::size_t n) {
97 ConnectionState &connection{to.GetConnectionState()};
98 if (connection.internalIoCharKind <= 1 &&
99 connection.access != Access::Stream) {
102 if (!to.Emit(&ch, 1)) {
108 if (!EmitEncoded(to, &ch, 1)) {