4#include "InternallySynchronizedOutputStream.h"
6namespace Stroika::Foundation::Streams::TextToBinary {
9 class UnSeekable_CodeCvt_Rep_ final :
public OutputStream::IRep<Character> {
11 UnSeekable_CodeCvt_Rep_ (
const OutputStream::Ptr<byte>& src,
const Characters::CodeCvt<Character>& converter)
13 , _fConverter{converter}
19 virtual bool IsSeekable ()
const override
23 virtual void CloseWrite ()
override
29 Ensure (not IsOpenWrite ());
31 virtual bool IsOpenWrite ()
const override
33 return _fSource.IsOpen ();
38 Require (IsOpenWrite ());
41 virtual SeekOffsetType SeekWrite (Whence , SignedSeekOffsetType )
override
44 Require (IsOpenWrite ());
47 virtual void Write (span<const Character> elts)
override
50 Require (IsOpenWrite ());
51 Memory::StackBuffer<byte> cvtBuf{elts.size () * 5};
53 auto trgSpan = span<byte>{cvtBuf.data (), cvtBuf.size ()};
54 trgSpan = _fConverter.Characters2Bytes (srcSpan, trgSpan);
55 _fSource.Write (trgSpan);
57 virtual void Flush ()
override
60 Require (IsOpenWrite ());
65 OutputStream::Ptr<byte> _fSource;
66 Characters::CodeCvt<Character> _fConverter;
67 std::mbstate_t _fMBState_{};
68 [[no_unique_address]] Debug::AssertExternallySynchronizedMutex fThisAssertExternallySynchronized_;
71 template <Characters ::IUNICODECanUnambiguouslyConvertFrom OUTPUT_CHAR_T>
72 class UnSeekable_UTFConverter_Rep_ final :
public OutputStream::IRep<Character> {
74 template <
typename CONVERTER>
75 UnSeekable_UTFConverter_Rep_ (
const OutputStream::Ptr<byte>& src, CONVERTER&& converter)
77 , _fConverter{forward<CONVERTER> (converter)}
81 UnSeekable_UTFConverter_Rep_ (
const OutputStream::Ptr<byte>& src)
83 , _fConverter{Characters::UTFConvert::kThe}
88 virtual bool IsSeekable ()
const override
92 virtual void CloseWrite ()
override
98 Ensure (not IsOpenWrite ());
100 virtual bool IsOpenWrite ()
const override
102 return _fSource.IsOpen ();
107 Require (IsOpenWrite ());
110 virtual SeekOffsetType SeekWrite (Whence , SignedSeekOffsetType )
override
113 Require (IsOpenWrite ());
116 virtual void Write (span<const Character> elts)
override
119 Require (IsOpenWrite ());
121 Memory::StackBuffer<OUTPUT_CHAR_T> cvtBuf{_fConverter.ComputeTargetBufferSize<OUTPUT_CHAR_T> (srcSpan)};
122 auto trgSpan = span<OUTPUT_CHAR_T>{cvtBuf.data (), cvtBuf.size ()};
123 auto r = _fConverter.ConvertSpan (srcSpan, trgSpan);
124 auto trgBytes = as_bytes (r);
125 _fSource.Write (trgBytes);
127 virtual void Flush ()
override
130 Require (IsOpenWrite ());
135 OutputStream::Ptr<byte> _fSource;
136 Characters::UTFConvert _fConverter;
137 [[no_unique_address]] Debug::AssertExternallySynchronizedMutex fThisAssertExternallySynchronized_;
147 inline auto New (
const OutputStream::Ptr<Character>& src) -> OutputStream::Ptr<Character>
151 inline OutputStream::Ptr<Character> New (
const OutputStream::Ptr<byte>& src,
const Characters::CodeCvt<>& char2OutputConverter)
153 return OutputStream::Ptr<Character>{make_shared<Private_::UnSeekable_CodeCvt_Rep_> (src, char2OutputConverter)};
157 using Ptr = OutputStream::Ptr<Character>;
158 if (bom == Characters::ByteOrderMark::eInclude) {
163 case Characters::UnicodeExternalEncodings::eUTF8:
164 return Ptr{make_shared<Private_::UnSeekable_UTFConverter_Rep_<char8_t>> (src)};
165 case Characters::UnicodeExternalEncodings::eUTF16:
166 return Ptr{make_shared<Private_::UnSeekable_UTFConverter_Rep_<char16_t>> (src)};
167 case Characters::UnicodeExternalEncodings::eUTF32:
168 return Ptr{make_shared<Private_::UnSeekable_UTFConverter_Rep_<char32_t>> (src)};
171 return New (src, Characters::CodeCvt<Character> (e));
174 template <
typename... ARGS>
177 switch (internallySynchronized) {
178 case Execution::eNotKnownInternallySynchronized:
179 return New (forward<ARGS...> (args...));
180 case Execution::eInternallySynchronized:
182 return InternallySynchronizedOutputStream::New ({}, New (forward<ARGS...> (args...)));
#define AssertNotImplemented()
#define RequireNotNull(p)
unique_lock< AssertExternallySynchronizedMutex > WriteContext
Instantiate AssertExternallySynchronizedMutex::WriteContext to designate an area of code where protec...
virtual void Write(span< const ELEMENT_TYPE > elts)=0
constexpr span< const byte > GetByteOrderMark(UnicodeExternalEncodings e) noexcept
UnicodeExternalEncodings
list of external UNICODE character encodings, for file IO (eDEFAULT = eUTF8)
Streams::OutputStream::Ptr< Character > Ptr
TextToBinary::Writer wrap some sink (typically a binary stream), and produce a text sink you can Writ...