1 //===-- runtime/emit-encoded.h ----------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Templates for emitting CHARACTER values with conversion
11 #ifndef FORTRAN_RUNTIME_EMIT_ENCODED_H_
12 #define FORTRAN_RUNTIME_EMIT_ENCODED_H_
14 #include "connection.h"
15 #include "environment.h"
18 namespace Fortran::runtime::io
{
20 template <typename CONTEXT
, typename CHAR
>
21 bool EmitEncoded(CONTEXT
&to
, const CHAR
*data
, std::size_t chars
) {
22 ConnectionState
&connection
{to
.GetConnectionState()};
23 if (connection
.useUTF8
<CHAR
>()) {
24 using UnsignedChar
= std::make_unsigned_t
<CHAR
>;
25 const UnsignedChar
*uData
{reinterpret_cast<const UnsignedChar
*>(data
)};
29 auto len
{EncodeUTF8(buffer
+ at
, *uData
++)};
31 if (at
+ maxUTF8Bytes
> sizeof buffer
) {
32 if (!to
.Emit(buffer
, at
)) {
38 return at
== 0 || to
.Emit(buffer
, at
);
40 std::size_t internalKind
= connection
.internalIoCharKind
;
41 if (internalKind
== 0 || internalKind
== sizeof(CHAR
)) {
42 const char *rawData
{reinterpret_cast<const char *>(data
)};
43 return to
.Emit(rawData
, chars
* sizeof(CHAR
), sizeof(CHAR
));
45 // CHARACTER kind conversion for internal output
47 char32_t buffer
= *data
++;
48 char *p
{reinterpret_cast<char *>(&buffer
)};
49 if constexpr (!isHostLittleEndian
) {
50 p
+= sizeof(buffer
) - internalKind
;
52 if (!to
.Emit(p
, internalKind
)) {
61 template <typename CONTEXT
>
62 bool EmitAscii(CONTEXT
&to
, const char *data
, std::size_t chars
) {
63 ConnectionState
&connection
{to
.GetConnectionState()};
64 if (connection
.internalIoCharKind
<= 1) {
65 return to
.Emit(data
, chars
);
67 return EmitEncoded(to
, data
, chars
);
71 template <typename CONTEXT
>
72 bool EmitRepeated(CONTEXT
&to
, char ch
, std::size_t n
) {
76 ConnectionState
&connection
{to
.GetConnectionState()};
77 if (connection
.internalIoCharKind
<= 1) {
79 if (!to
.Emit(&ch
, 1)) {
85 if (!EmitEncoded(to
, &ch
, 1)) {
93 } // namespace Fortran::runtime::io
94 #endif // FORTRAN_RUNTIME_EMIT_ENCODED_H_