5#include "Stroika/Foundation/Streams/InternallySynchronizedOutputStream.h"
7namespace Stroika::Foundation::Streams::TextToBinary {
10 class UnSeekable_CodeCvt_Rep_ final :
public OutputStream::IRep<Character> {
12 UnSeekable_CodeCvt_Rep_ (
const OutputStream::Ptr<byte>& src,
const Characters::CodeCvt<Character>& converter)
14 , _fConverter{converter}
20 virtual bool IsSeekable ()
const override
24 virtual void CloseWrite ()
override
30 Ensure (not IsOpenWrite ());
32 virtual bool IsOpenWrite ()
const override
34 return _fSource.IsOpen ();
39 Require (IsOpenWrite ());
42 virtual SeekOffsetType SeekWrite (Whence , SignedSeekOffsetType )
override
45 Require (IsOpenWrite ());
48 virtual void Write (span<const Character> elts)
override
51 Require (IsOpenWrite ());
52 Memory::StackBuffer<byte> cvtBuf{elts.size () * 5};
54 auto trgSpan = span<byte>{cvtBuf.data (), cvtBuf.size ()};
55 trgSpan = _fConverter.Characters2Bytes (srcSpan, trgSpan);
56 _fSource.Write (trgSpan);
58 virtual void Flush ()
override
61 Require (IsOpenWrite ());
66 OutputStream::Ptr<byte> _fSource;
67 Characters::CodeCvt<Character> _fConverter;
68 std::mbstate_t _fMBState_{};
69 [[no_unique_address]] Debug::AssertExternallySynchronizedMutex fThisAssertExternallySynchronized_;
72 template <Characters ::IUNICODECanUnambiguouslyConvertFrom OUTPUT_CHAR_T>
73 class UnSeekable_UTFConverter_Rep_ final :
public OutputStream::IRep<Character> {
75 template <
typename CONVERTER>
76 UnSeekable_UTFConverter_Rep_ (
const OutputStream::Ptr<byte>& src, CONVERTER&& converter)
78 , _fConverter{forward<CONVERTER> (converter)}
82 UnSeekable_UTFConverter_Rep_ (
const OutputStream::Ptr<byte>& src)
84 , _fConverter{Characters::UTFConvert::kThe}
89 virtual bool IsSeekable ()
const override
93 virtual void CloseWrite ()
override
99 Ensure (not IsOpenWrite ());
101 virtual bool IsOpenWrite ()
const override
103 return _fSource.IsOpen ();
108 Require (IsOpenWrite ());
111 virtual SeekOffsetType SeekWrite (Whence , SignedSeekOffsetType )
override
114 Require (IsOpenWrite ());
117 virtual void Write (span<const Character> elts)
override
120 Require (IsOpenWrite ());
122 Memory::StackBuffer<OUTPUT_CHAR_T> cvtBuf{_fConverter.ComputeTargetBufferSize<OUTPUT_CHAR_T> (srcSpan)};
123 auto trgSpan = span<OUTPUT_CHAR_T>{cvtBuf.data (), cvtBuf.size ()};
124 auto r = _fConverter.ConvertSpan (srcSpan, trgSpan);
125 auto trgBytes = as_bytes (r);
126 _fSource.Write (trgBytes);
128 virtual void Flush ()
override
131 Require (IsOpenWrite ());
136 OutputStream::Ptr<byte> _fSource;
137 Characters::UTFConvert _fConverter;
138 [[no_unique_address]] Debug::AssertExternallySynchronizedMutex fThisAssertExternallySynchronized_;
148 inline auto New (
const OutputStream::Ptr<Character>& src) -> OutputStream::Ptr<Character>
159 if (bom == Characters::ByteOrderMark::eInclude) {
164 case Characters::UnicodeExternalEncodings::eUTF8:
165 return Ptr{Memory::MakeSharedPtr<Private_::UnSeekable_UTFConverter_Rep_<char8_t>> (src)};
166 case Characters::UnicodeExternalEncodings::eUTF16:
167 return Ptr{Memory::MakeSharedPtr<Private_::UnSeekable_UTFConverter_Rep_<char16_t>> (src)};
168 case Characters::UnicodeExternalEncodings::eUTF32:
169 return Ptr{Memory::MakeSharedPtr<Private_::UnSeekable_UTFConverter_Rep_<char32_t>> (src)};
172 return New (src, Characters::CodeCvt<Character> (e));
175 template <
typename... ARGS>
178 switch (internallySynchronized) {
179 case Execution::eNotKnownInternallySynchronized:
180 return New (forward<ARGS...> (args...));
181 case Execution::eInternallySynchronized:
183 return InternallySynchronizedOutputStream::New ({},
New (forward<ARGS...> (args...)));
#define AssertNotImplemented()
#define RequireNotNull(p)
CodeCvt unifies byte <-> unicode conversions, vaguely inspired by (and wraps) std::codecvt,...
unique_lock< AssertExternallySynchronizedMutex > WriteContext
Instantiate AssertExternallySynchronizedMutex::WriteContext to designate an area of code where protec...
virtual void Write(span< const ELEMENT_TYPE > elts)=0
OutputStream<>::Ptr is Smart pointer to a stream-based sink of data.
nonvirtual void Write(span< ELEMENT_TYPE2, EXTENT_2 > elts) const
A Streams::Ptr<ELEMENT_TYPE> is a smart-pointer to a stream of elements of type T.
constexpr span< const byte > GetByteOrderMark(UnicodeExternalEncodings e) noexcept
UnicodeExternalEncodings
list of external UNICODE character encodings, for file IO (eDEFAULT = eUTF8)
Ptr New(const Streams::OutputStream::Ptr< byte > &src, const Characters::CodeCvt<> &char2OutputConverter)
Streams::OutputStream::Ptr< Character > Ptr
TextToBinary::Writer wrap some sink (typically a binary stream), and produce a text sink you can Writ...