4#ifndef _Stroika_Frameworks_Led_StyledTextIO_h_
5#define _Stroika_Frameworks_Led_StyledTextIO_h_ 1
7#include "Stroika/Frameworks/StroikaPreComp.h"
42#include "Stroika/Foundation/Memory/Common.h"
44#include "Stroika/Frameworks/Led/StandardStyledTextImager.h"
45#include "Stroika/Frameworks/Led/StyledTextEmbeddedObjects.h"
46#include "Stroika/Frameworks/Led/StyledTextImager.h"
47#include "Stroika/Frameworks/Led/Support.h"
49namespace Stroika::Frameworks::Led::StyledTextIO {
56 class StyledTextIOReader {
68 virtual ~SrcStream () =
default;
75 virtual size_t current_offset ()
const = 0;
83 virtual void seek_to (
size_t to) = 0;
93 virtual size_t read (
void* buffer,
size_t bytes) = 0;
102 virtual size_t read1 (
char* c)
116 class BadInputHandler {
118 virtual ~BadInputHandler () =
default;
119 virtual void HandleBadlyFormattedInput (
const StyledTextIOReader& reader,
bool unrecoverable);
123 StyledTextIOReader (SrcStream* srcStream, SinkStream* sinkStream,
124 const shared_ptr<BadInputHandler>& badInputHander = shared_ptr<BadInputHandler> ());
128 virtual void Read () = 0;
129 virtual bool QuickLookAppearsToBeRightFormat () = 0;
137 class BufferedIndirectSrcStream :
public SrcStream {
139 BufferedIndirectSrcStream (SrcStream& realSrcStream);
142 virtual size_t current_offset ()
const override;
143 virtual void seek_to (
size_t to)
override;
144 virtual size_t read (
void* buffer,
size_t bytes)
override;
145 virtual size_t read1 (
char* c)
override;
148 nonvirtual
void FillCache ();
151 SrcStream& fRealSrcStream;
152 char fWindowTop_Data[4 * 1024];
153 size_t fWindowTop_Offset;
154 const char* fWindowBottom_Data;
155 size_t fWindowBottom_Offset;
156 const char* fCursor_Data;
157 size_t fCursor_Offset;
161 nonvirtual SrcStream& GetSrcStream ()
const;
162 nonvirtual SinkStream& GetSinkStream ()
const;
165 mutable BufferedIndirectSrcStream fSrcStream;
166 SinkStream* fSinkStream;
169 nonvirtual shared_ptr<BadInputHandler> GetBadInputHandler ()
const;
170 nonvirtual
void SetBadInputHandler (
const shared_ptr<BadInputHandler>& badInputHandler);
173 shared_ptr<BadInputHandler> fBadInputHandler;
176 nonvirtual
void HandleBadlyFormattedInput (
bool unrecoverable =
false)
const;
179 class SrcStreamSeekSaver;
182 struct ReadEOFException {};
186 nonvirtual
void PutBackLastChar ()
const;
187 nonvirtual
char GetNextChar ()
const;
188 nonvirtual
char PeekNextChar ()
const;
189 nonvirtual
void ConsumeNextChar ()
const;
190 nonvirtual
string GrabString (
size_t from,
size_t to =
size_t (-1));
195 class StyledTextIOReader::SrcStreamSeekSaver {
197 SrcStreamSeekSaver (SrcStream& srcStream);
198 ~SrcStreamSeekSaver ();
201 SrcStream& fSrcStream;
210 class StyledTextIOReader::SinkStream {
212 virtual ~SinkStream ()
221 virtual size_t current_offset ()
const = 0;
231 virtual void AppendText (
const Led_tChar* text,
size_t nTChars,
const FontSpecification* fontSpec) = 0;
238 virtual void ApplyStyle (
size_t from,
size_t to,
const vector<StyledInfoSummaryRecord>& styleRuns) = 0;
245 virtual FontSpecification GetDefaultFontSpec ()
const = 0;
247#if qStroika_Frameworks_Led_SupportGDI
253 virtual void InsertEmbeddingForExistingSentinel (SimpleEmbeddedObjectStyleMarker* embedding,
size_t at) = 0;
260 virtual void AppendEmbedding (SimpleEmbeddedObjectStyleMarker* embedding) = 0;
268 virtual void AppendSoftLineBreak () = 0;
271 virtual void StartTable ();
272 virtual void EndTable ();
273 virtual void StartTableRow ();
274 virtual void EndTableRow ();
275 virtual void StartTableCell (
size_t colSpan);
276 virtual void EndTableCell ();
283 virtual void InsertMarker (Marker* m,
size_t at,
size_t length, MarkerOwner* markerOwner) = 0;
286 virtual void SetJustification (Justification justification);
287 virtual void SetStandardTabStopList (
const StandardTabStopList& tabStops);
288 virtual void SetFirstIndent (TWIPS tx);
289 virtual void SetLeftMargin (TWIPS lhs);
290 virtual void SetRightMargin (TWIPS rhs);
291 virtual void SetSpaceBefore (TWIPS sb);
292 virtual void SetSpaceAfter (TWIPS sa);
293 virtual void SetLineSpacing (LineSpacing sl);
294 virtual void SetTextHidden (
bool hidden);
295 virtual void SetListStyle (ListStyle listStyle);
296 virtual void SetListIndentLevel (
unsigned char indentLevel);
299 virtual void SetTableBorderColor (Color c);
300 virtual void SetTableBorderWidth (TWIPS bWidth);
301 virtual void SetCellWidths (
const vector<TWIPS>& cellWidths);
302 virtual void SetCellBackColor (
const Color c);
303 virtual void SetDefaultCellMarginsForCurrentRow (TWIPS top, TWIPS left, TWIPS bottom, TWIPS right);
304 virtual void SetDefaultCellSpacingForCurrentRow (TWIPS top, TWIPS left, TWIPS bottom, TWIPS right);
312 virtual void EndOfBuffer () {};
319 virtual void Flush () = 0;
322 nonvirtual
size_t GetCountOfTCharsInserted ()
const;
331 class StyledTextIOWriter {
337 StyledTextIOWriter (SrcStream* srcStream, SinkStream* sinkStream);
341 virtual void Write () = 0;
344 nonvirtual SrcStream& GetSrcStream ()
const;
345 nonvirtual SinkStream& GetSinkStream ()
const;
348 SrcStream* fSrcStream;
349 SinkStream* fSinkStream;
353 nonvirtual
void write (
const void* data,
size_t nBytes);
354 nonvirtual
void write (
char c);
355 nonvirtual
void write (
const char* str);
356 nonvirtual
void write (
const string& str);
363 class StyledTextIOWriter::SrcStream {
365 virtual ~SrcStream () =
default;
373 virtual size_t readNTChars (Led_tChar* intoBuf,
size_t maxTChars) = 0;
380 virtual size_t current_offset ()
const = 0;
387 virtual void seek_to (
size_t to) = 0;
394 virtual size_t GetTotalTextLength ()
const = 0;
401 virtual vector<StyledInfoSummaryRecord> GetStyleInfo (
size_t from,
size_t len)
const = 0;
403#if qStroika_Frameworks_Led_SupportGDI
409 virtual vector<SimpleEmbeddedObjectStyleMarker*> CollectAllEmbeddingMarkersInRange (
size_t from,
size_t to)
const = 0;
421 virtual Table* GetTableAt (
size_t at)
const = 0;
429 virtual void SummarizeFontAndColorTable (set<SDKString>* fontNames, set<Color>* colorsUsed)
const = 0;
437 virtual size_t GetEmbeddingMarkerPosOffset ()
const = 0;
440 virtual Justification GetJustification ()
const;
441 virtual StandardTabStopList GetStandardTabStopList ()
const;
442 virtual TWIPS GetFirstIndent ()
const;
443 virtual void GetMargins (TWIPS* lhs, TWIPS* rhs)
const;
444 virtual TWIPS GetSpaceBefore ()
const;
445 virtual TWIPS GetSpaceAfter ()
const;
446 virtual LineSpacing GetLineSpacing ()
const;
447 virtual void GetListStyleInfo (ListStyle* listStyle,
unsigned char* indentLevel)
const;
448 virtual Led_tChar GetSoftLineBreakCharacter ()
const;
449 virtual DiscontiguousRun<bool> GetHidableTextRuns ()
const;
456 class StyledTextIOWriter::SrcStream::Table {
458 virtual ~Table () =
default;
472 virtual size_t GetRows ()
const = 0;
478 virtual size_t GetColumns (
size_t row)
const = 0;
486 virtual void GetRowInfo (
size_t row, vector<CellInfo>* cellInfos) = 0;
492 virtual StyledTextIOWriter::SrcStream* MakeCellSubSrcStream (
size_t row,
size_t column) = 0;
498 virtual size_t GetOffsetEnd ()
const = 0;
504 virtual TWIPS_Rect GetDefaultCellMarginsForRow (
size_t row)
const = 0;
510 virtual TWIPS_Rect GetDefaultCellSpacingForRow (
size_t row)
const = 0;
518 class StyledTextIOWriter::SinkStream {
520 virtual ~SinkStream ()
529 virtual size_t current_offset ()
const = 0;
536 virtual void seek_to (
size_t to) = 0;
543 virtual void write (
const void* buffer,
size_t bytes) = 0;
559 class StyledTextIOSrcStream_Memory :
public StyledTextIOReader::SrcStream {
561 StyledTextIOSrcStream_Memory (
const void* data,
size_t nBytes);
564 virtual size_t current_offset ()
const override;
565 virtual void seek_to (
size_t to)
override;
566 virtual size_t read (
void* buffer,
size_t bytes)
override;
567 virtual size_t read1 (
char* c)
override;
571 const void* fDataEnd;
572 size_t fBytesInBuffer;
576 inline StyledTextIOReader::BufferedIndirectSrcStream::BufferedIndirectSrcStream (SrcStream& realSrcStream)
577 : fRealSrcStream (realSrcStream)
580 fWindowTop_Offset (size_t (-1))
581 , fWindowBottom_Data (nullptr)
582 , fWindowBottom_Offset (size_t (-1))
583 , fCursor_Data (nullptr)
587 inline void StyledTextIOReader::BufferedIndirectSrcStream::FillCache ()
589 fWindowTop_Offset = fCursor_Offset;
590 fRealSrcStream.seek_to (fWindowTop_Offset);
591 size_t bytesRead = fRealSrcStream.read (fWindowTop_Data, std::size (fWindowTop_Data));
592 fWindowBottom_Data = fWindowTop_Data + bytesRead;
593 fWindowBottom_Offset = fWindowTop_Offset + bytesRead;
594 Assert (fCursor_Offset >= fWindowTop_Offset and fCursor_Offset <= fWindowBottom_Offset);
595 Assert (fCursor_Offset == fWindowTop_Offset);
596 if (fCursor_Offset >= fWindowTop_Offset and fCursor_Offset <= fWindowBottom_Offset) {
597 fCursor_Data = fWindowTop_Data + (fCursor_Offset - fWindowTop_Offset);
599 Ensure (fWindowTop_Data <= fCursor_Data and fCursor_Data <= fWindowBottom_Data);
600 Ensure (fWindowTop_Offset <= fCursor_Offset and fCursor_Offset <= fWindowBottom_Offset);
602 inline size_t StyledTextIOReader::BufferedIndirectSrcStream::current_offset ()
const
604 return fCursor_Offset;
606 inline void StyledTextIOReader::BufferedIndirectSrcStream::seek_to (
size_t to)
610 if (fWindowTop_Offset <= to and to <= fWindowBottom_Offset) {
611 fCursor_Data = fWindowTop_Data + (to - fWindowTop_Offset);
614 fCursor_Data =
nullptr;
618 inline size_t StyledTextIOReader::BufferedIndirectSrcStream::read (
void* buffer,
size_t bytes)
622 byte* destCursor =
reinterpret_cast<byte*
> (buffer);
623 size_t bytesReadSoFar = 0;
629 if (fCursor_Data !=
nullptr and fWindowTop_Offset >= fCursor_Offset and fCursor_Offset < fWindowBottom_Offset) {
630 size_t bytesAvail = fWindowBottom_Offset - fCursor_Offset;
631 size_t thisReadCount = min (bytesAvail, bytes);
633 (void)::memcpy (destCursor, fCursor_Data, thisReadCount);
634 destCursor += thisReadCount;
635 fCursor_Data += thisReadCount;
636 fCursor_Offset += thisReadCount;
637 bytesReadSoFar += thisReadCount;
644 if (bytesReadSoFar < bytes) {
645 size_t bytesLeftToRead = bytes - bytesReadSoFar;
646 if (bytesLeftToRead < std::size (fWindowTop_Data)) {
648 size_t bytesAvail = fWindowBottom_Offset - fCursor_Offset;
649 size_t thisReadCount = min (bytesAvail, bytesLeftToRead);
651 DISABLE_COMPILER_MSC_WARNING_START (6387)
652 (void)::memcpy (destCursor, fCursor_Data, thisReadCount);
653 DISABLE_COMPILER_MSC_WARNING_END (6387)
654 destCursor += thisReadCount;
655 fCursor_Data += thisReadCount;
656 fCursor_Offset += thisReadCount;
657 bytesReadSoFar += thisReadCount;
660 fRealSrcStream.seek_to (fCursor_Offset);
661 size_t bytesRead = fRealSrcStream.read (destCursor, bytesLeftToRead);
662 bytesReadSoFar += bytesRead;
663 fCursor_Offset += bytesRead;
665 fCursor_Data =
nullptr;
668 return bytesReadSoFar;
670 inline size_t StyledTextIOReader::BufferedIndirectSrcStream::read1 (
char* c)
679 if ((fCursor_Data ==
nullptr) or (fCursor_Offset < fWindowTop_Offset or fCursor_Offset >= fWindowBottom_Offset)) {
682 Assert (fWindowTop_Offset <= fCursor_Offset and fCursor_Offset <= fWindowBottom_Offset);
683 if (fWindowBottom_Offset == fCursor_Offset) {
703 class StyledTextIOWriterSinkStream_Memory :
public StyledTextIOWriter::SinkStream {
705 StyledTextIOWriterSinkStream_Memory ();
706 ~StyledTextIOWriterSinkStream_Memory ();
709 StyledTextIOWriterSinkStream_Memory (
const StyledTextIOWriterSinkStream_Memory&) =
delete;
710 void operator= (
const StyledTextIOWriterSinkStream_Memory&) =
delete;
713 virtual size_t current_offset ()
const override;
714 virtual void seek_to (
size_t to)
override;
715 virtual void write (
const void* buffer,
size_t bytes)
override;
717 nonvirtual
const void* PeekAtData ()
const;
718 nonvirtual
size_t GetLength ()
const;
723 size_t fBytesAllocated;
727#if qStroika_Frameworks_Led_SupportGDI
733 class EmbeddingSinkStream :
public SimpleEmbeddedObjectStyleMarker::SinkStream {
735 EmbeddingSinkStream (StyledTextIOWriter::SinkStream& realSinkStream);
737 virtual void write (
const void* buffer,
size_t bytes)
override;
740 StyledTextIOWriter::SinkStream& fRealSinkStream;
750 inline StyledTextIOReader::SrcStreamSeekSaver::SrcStreamSeekSaver (SrcStream& srcStream)
751 : fSrcStream (srcStream)
752 , fSavedPos (srcStream.current_offset ())
755 inline StyledTextIOReader::SrcStreamSeekSaver::~SrcStreamSeekSaver ()
758 fSrcStream.seek_to (fSavedPos);
768 inline StyledTextIOReader::StyledTextIOReader (SrcStream* srcStream, SinkStream* sinkStream,
const shared_ptr<BadInputHandler>& badInputHander)
769 : fSrcStream (*srcStream)
770 , fSinkStream (sinkStream)
771 , fBadInputHandler (badInputHander)
774 if (fBadInputHandler.get () ==
nullptr) {
775 fBadInputHandler = Memory::MakeSharedPtr<BadInputHandler> ();
778 inline StyledTextIOReader::SrcStream& StyledTextIOReader::GetSrcStream ()
const
782 inline StyledTextIOReader::SinkStream& StyledTextIOReader::GetSinkStream ()
const
794 inline shared_ptr<StyledTextIOReader::BadInputHandler> StyledTextIOReader::GetBadInputHandler ()
const
796 Ensure (fBadInputHandler.get () !=
nullptr);
797 return fBadInputHandler;
803 inline void StyledTextIOReader::SetBadInputHandler (
const shared_ptr<BadInputHandler>& badInputHandler)
805 fBadInputHandler = badInputHandler;
806 if (fBadInputHandler ==
nullptr) {
807 fBadInputHandler = Memory::MakeSharedPtr<BadInputHandler> ();
816 inline void StyledTextIOReader::HandleBadlyFormattedInput (
bool unrecoverable)
const
818 GetBadInputHandler ()->HandleBadlyFormattedInput (*
this, unrecoverable);
825 inline void StyledTextIOReader::PutBackLastChar ()
const
827 Require (fSrcStream.current_offset () > 0);
828 fSrcStream.seek_to (fSrcStream.current_offset () - 1);
830 inline char StyledTextIOReader::GetNextChar ()
const
834 if (fSrcStream.read1 (&c) == 1) {
838 throw ReadEOFException ();
843 inline char StyledTextIOReader::PeekNextChar ()
const
847 if (fSrcStream.read1 (&c) == 1) {
852 throw ReadEOFException ();
857 inline void StyledTextIOReader::ConsumeNextChar ()
const
859 (void)GetNextChar ();
863 inline StyledTextIOWriter::StyledTextIOWriter (SrcStream* srcStream, SinkStream* sinkStream)
864 : fSrcStream (srcStream)
865 , fSinkStream (sinkStream)
870 inline StyledTextIOWriter::SrcStream& StyledTextIOWriter::GetSrcStream ()
const
875 inline StyledTextIOWriter::SinkStream& StyledTextIOWriter::GetSinkStream ()
const
886 inline size_t StyledTextIOReader::SinkStream::GetCountOfTCharsInserted ()
const
888 return current_offset ();
892 inline StyledTextIOWriter::SrcStream::Table::CellInfo::CellInfo ()
893 : f_cellx (TWIPS (0))
894 , f_clcbpat (Color::kWhite)
899 inline const void* StyledTextIOWriterSinkStream_Memory::PeekAtData ()
const
903 inline size_t StyledTextIOWriterSinkStream_Memory::GetLength ()
const
#define RequireNotNull(p)
#define AssertNotReached()