4#ifndef _Stroika_Frameworks_Led_StyledTextIO_h_
5#define _Stroika_Frameworks_Led_StyledTextIO_h_ 1
7#include "Stroika/Frameworks/StroikaPreComp.h"
41#include "Stroika/Foundation/Memory/Common.h"
43#include "Stroika/Frameworks/Led/StandardStyledTextImager.h"
44#include "Stroika/Frameworks/Led/StyledTextEmbeddedObjects.h"
45#include "Stroika/Frameworks/Led/StyledTextImager.h"
46#include "Stroika/Frameworks/Led/Support.h"
48namespace Stroika::Frameworks::Led::StyledTextIO {
55 class StyledTextIOReader {
67 virtual ~SrcStream () =
default;
74 virtual size_t current_offset ()
const = 0;
82 virtual void seek_to (
size_t to) = 0;
92 virtual size_t read (
void* buffer,
size_t bytes) = 0;
101 virtual size_t read1 (
char* c)
115 class BadInputHandler {
117 virtual ~BadInputHandler () =
default;
118 virtual void HandleBadlyFormattedInput (
const StyledTextIOReader& reader,
bool unrecoverable);
122 StyledTextIOReader (SrcStream* srcStream, SinkStream* sinkStream,
123 const shared_ptr<BadInputHandler>& badInputHander = shared_ptr<BadInputHandler> ());
127 virtual void Read () = 0;
128 virtual bool QuickLookAppearsToBeRightFormat () = 0;
136 class BufferedIndirectSrcStream :
public SrcStream {
138 BufferedIndirectSrcStream (SrcStream& realSrcStream);
141 virtual size_t current_offset ()
const override;
142 virtual void seek_to (
size_t to)
override;
143 virtual size_t read (
void* buffer,
size_t bytes)
override;
144 virtual size_t read1 (
char* c)
override;
147 nonvirtual
void FillCache ();
150 SrcStream& fRealSrcStream;
151 char fWindowTop_Data[4 * 1024];
152 size_t fWindowTop_Offset;
153 const char* fWindowBottom_Data;
154 size_t fWindowBottom_Offset;
155 const char* fCursor_Data;
156 size_t fCursor_Offset;
160 nonvirtual SrcStream& GetSrcStream ()
const;
161 nonvirtual SinkStream& GetSinkStream ()
const;
164 mutable BufferedIndirectSrcStream fSrcStream;
165 SinkStream* fSinkStream;
168 nonvirtual shared_ptr<BadInputHandler> GetBadInputHandler ()
const;
169 nonvirtual
void SetBadInputHandler (
const shared_ptr<BadInputHandler>& badInputHandler);
172 shared_ptr<BadInputHandler> fBadInputHandler;
175 nonvirtual
void HandleBadlyFormattedInput (
bool unrecoverable =
false)
const;
178 class SrcStreamSeekSaver;
181 struct ReadEOFException {};
185 nonvirtual
void PutBackLastChar ()
const;
186 nonvirtual
char GetNextChar ()
const;
187 nonvirtual
char PeekNextChar ()
const;
188 nonvirtual
void ConsumeNextChar ()
const;
189 nonvirtual
string GrabString (
size_t from,
size_t to =
size_t (-1));
194 class StyledTextIOReader::SrcStreamSeekSaver {
196 SrcStreamSeekSaver (SrcStream& srcStream);
197 ~SrcStreamSeekSaver ();
200 SrcStream& fSrcStream;
209 class StyledTextIOReader::SinkStream {
211 virtual ~SinkStream ()
220 virtual size_t current_offset ()
const = 0;
230 virtual void AppendText (
const Led_tChar* text,
size_t nTChars,
const FontSpecification* fontSpec) = 0;
237 virtual void ApplyStyle (
size_t from,
size_t to,
const vector<StyledInfoSummaryRecord>& styleRuns) = 0;
244 virtual FontSpecification GetDefaultFontSpec ()
const = 0;
246#if qStroika_Frameworks_Led_SupportGDI
252 virtual void InsertEmbeddingForExistingSentinel (SimpleEmbeddedObjectStyleMarker* embedding,
size_t at) = 0;
259 virtual void AppendEmbedding (SimpleEmbeddedObjectStyleMarker* embedding) = 0;
267 virtual void AppendSoftLineBreak () = 0;
270 virtual void StartTable ();
271 virtual void EndTable ();
272 virtual void StartTableRow ();
273 virtual void EndTableRow ();
274 virtual void StartTableCell (
size_t colSpan);
275 virtual void EndTableCell ();
282 virtual void InsertMarker (Marker* m,
size_t at,
size_t length, MarkerOwner* markerOwner) = 0;
285 virtual void SetJustification (Justification justification);
286 virtual void SetStandardTabStopList (
const StandardTabStopList& tabStops);
287 virtual void SetFirstIndent (TWIPS tx);
288 virtual void SetLeftMargin (TWIPS lhs);
289 virtual void SetRightMargin (TWIPS rhs);
290 virtual void SetSpaceBefore (TWIPS sb);
291 virtual void SetSpaceAfter (TWIPS sa);
292 virtual void SetLineSpacing (LineSpacing sl);
293 virtual void SetTextHidden (
bool hidden);
294 virtual void SetListStyle (ListStyle listStyle);
295 virtual void SetListIndentLevel (
unsigned char indentLevel);
298 virtual void SetTableBorderColor (Color c);
299 virtual void SetTableBorderWidth (TWIPS bWidth);
300 virtual void SetCellWidths (
const vector<TWIPS>& cellWidths);
301 virtual void SetCellBackColor (
const Color c);
302 virtual void SetDefaultCellMarginsForCurrentRow (TWIPS top, TWIPS left, TWIPS bottom, TWIPS right);
303 virtual void SetDefaultCellSpacingForCurrentRow (TWIPS top, TWIPS left, TWIPS bottom, TWIPS right);
311 virtual void EndOfBuffer () {};
318 virtual void Flush () = 0;
321 nonvirtual
size_t GetCountOfTCharsInserted ()
const;
330 class StyledTextIOWriter {
336 StyledTextIOWriter (SrcStream* srcStream, SinkStream* sinkStream);
340 virtual void Write () = 0;
343 nonvirtual SrcStream& GetSrcStream ()
const;
344 nonvirtual SinkStream& GetSinkStream ()
const;
347 SrcStream* fSrcStream;
348 SinkStream* fSinkStream;
352 nonvirtual
void write (
const void* data,
size_t nBytes);
353 nonvirtual
void write (
char c);
354 nonvirtual
void write (
const char* str);
355 nonvirtual
void write (
const string& str);
362 class StyledTextIOWriter::SrcStream {
364 virtual ~SrcStream () =
default;
372 virtual size_t readNTChars (Led_tChar* intoBuf,
size_t maxTChars) = 0;
379 virtual size_t current_offset ()
const = 0;
386 virtual void seek_to (
size_t to) = 0;
393 virtual size_t GetTotalTextLength ()
const = 0;
400 virtual vector<StyledInfoSummaryRecord> GetStyleInfo (
size_t from,
size_t len)
const = 0;
402#if qStroika_Frameworks_Led_SupportGDI
408 virtual vector<SimpleEmbeddedObjectStyleMarker*> CollectAllEmbeddingMarkersInRange (
size_t from,
size_t to)
const = 0;
420 virtual Table* GetTableAt (
size_t at)
const = 0;
428 virtual void SummarizeFontAndColorTable (set<SDKString>* fontNames, set<Color>* colorsUsed)
const = 0;
436 virtual size_t GetEmbeddingMarkerPosOffset ()
const = 0;
439 virtual Justification GetJustification ()
const;
440 virtual StandardTabStopList GetStandardTabStopList ()
const;
441 virtual TWIPS GetFirstIndent ()
const;
442 virtual void GetMargins (TWIPS* lhs, TWIPS* rhs)
const;
443 virtual TWIPS GetSpaceBefore ()
const;
444 virtual TWIPS GetSpaceAfter ()
const;
445 virtual LineSpacing GetLineSpacing ()
const;
446 virtual void GetListStyleInfo (ListStyle* listStyle,
unsigned char* indentLevel)
const;
447 virtual Led_tChar GetSoftLineBreakCharacter ()
const;
448 virtual DiscontiguousRun<bool> GetHidableTextRuns ()
const;
455 class StyledTextIOWriter::SrcStream::Table {
457 virtual ~Table () =
default;
471 virtual size_t GetRows ()
const = 0;
477 virtual size_t GetColumns (
size_t row)
const = 0;
485 virtual void GetRowInfo (
size_t row, vector<CellInfo>* cellInfos) = 0;
491 virtual StyledTextIOWriter::SrcStream* MakeCellSubSrcStream (
size_t row,
size_t column) = 0;
497 virtual size_t GetOffsetEnd ()
const = 0;
503 virtual TWIPS_Rect GetDefaultCellMarginsForRow (
size_t row)
const = 0;
509 virtual TWIPS_Rect GetDefaultCellSpacingForRow (
size_t row)
const = 0;
517 class StyledTextIOWriter::SinkStream {
519 virtual ~SinkStream ()
528 virtual size_t current_offset ()
const = 0;
535 virtual void seek_to (
size_t to) = 0;
542 virtual void write (
const void* buffer,
size_t bytes) = 0;
558 class StyledTextIOSrcStream_Memory :
public StyledTextIOReader::SrcStream {
560 StyledTextIOSrcStream_Memory (
const void* data,
size_t nBytes);
563 virtual size_t current_offset ()
const override;
564 virtual void seek_to (
size_t to)
override;
565 virtual size_t read (
void* buffer,
size_t bytes)
override;
566 virtual size_t read1 (
char* c)
override;
570 const void* fDataEnd;
571 size_t fBytesInBuffer;
575 inline StyledTextIOReader::BufferedIndirectSrcStream::BufferedIndirectSrcStream (SrcStream& realSrcStream)
576 : fRealSrcStream (realSrcStream)
579 fWindowTop_Offset (size_t (-1))
580 , fWindowBottom_Data (nullptr)
581 , fWindowBottom_Offset (size_t (-1))
582 , fCursor_Data (nullptr)
586 inline void StyledTextIOReader::BufferedIndirectSrcStream::FillCache ()
588 fWindowTop_Offset = fCursor_Offset;
589 fRealSrcStream.seek_to (fWindowTop_Offset);
590 size_t bytesRead = fRealSrcStream.read (fWindowTop_Data, std::size (fWindowTop_Data));
591 fWindowBottom_Data = fWindowTop_Data + bytesRead;
592 fWindowBottom_Offset = fWindowTop_Offset + bytesRead;
593 Assert (fCursor_Offset >= fWindowTop_Offset and fCursor_Offset <= fWindowBottom_Offset);
594 Assert (fCursor_Offset == fWindowTop_Offset);
595 if (fCursor_Offset >= fWindowTop_Offset and fCursor_Offset <= fWindowBottom_Offset) {
596 fCursor_Data = fWindowTop_Data + (fCursor_Offset - fWindowTop_Offset);
598 Ensure (fWindowTop_Data <= fCursor_Data and fCursor_Data <= fWindowBottom_Data);
599 Ensure (fWindowTop_Offset <= fCursor_Offset and fCursor_Offset <= fWindowBottom_Offset);
601 inline size_t StyledTextIOReader::BufferedIndirectSrcStream::current_offset ()
const
603 return fCursor_Offset;
605 inline void StyledTextIOReader::BufferedIndirectSrcStream::seek_to (
size_t to)
609 if (fWindowTop_Offset <= to and to <= fWindowBottom_Offset) {
610 fCursor_Data = fWindowTop_Data + (to - fWindowTop_Offset);
613 fCursor_Data =
nullptr;
617 inline size_t StyledTextIOReader::BufferedIndirectSrcStream::read (
void* buffer,
size_t bytes)
621 byte* destCursor =
reinterpret_cast<byte*
> (buffer);
622 size_t bytesReadSoFar = 0;
628 if (fCursor_Data !=
nullptr and fWindowTop_Offset >= fCursor_Offset and fCursor_Offset < fWindowBottom_Offset) {
629 size_t bytesAvail = fWindowBottom_Offset - fCursor_Offset;
630 size_t thisReadCount = min (bytesAvail, bytes);
632 (void)::memcpy (destCursor, fCursor_Data, thisReadCount);
633 destCursor += thisReadCount;
634 fCursor_Data += thisReadCount;
635 fCursor_Offset += thisReadCount;
636 bytesReadSoFar += thisReadCount;
643 if (bytesReadSoFar < bytes) {
644 size_t bytesLeftToRead = bytes - bytesReadSoFar;
645 if (bytesLeftToRead < std::size (fWindowTop_Data)) {
647 size_t bytesAvail = fWindowBottom_Offset - fCursor_Offset;
648 size_t thisReadCount = min (bytesAvail, bytesLeftToRead);
650 DISABLE_COMPILER_MSC_WARNING_START (6387)
651 (void)::memcpy (destCursor, fCursor_Data, thisReadCount);
652 DISABLE_COMPILER_MSC_WARNING_END (6387)
653 destCursor += thisReadCount;
654 fCursor_Data += thisReadCount;
655 fCursor_Offset += thisReadCount;
656 bytesReadSoFar += thisReadCount;
659 fRealSrcStream.seek_to (fCursor_Offset);
660 size_t bytesRead = fRealSrcStream.read (destCursor, bytesLeftToRead);
661 bytesReadSoFar += bytesRead;
662 fCursor_Offset += bytesRead;
664 fCursor_Data =
nullptr;
667 return bytesReadSoFar;
669 inline size_t StyledTextIOReader::BufferedIndirectSrcStream::read1 (
char* c)
678 if ((fCursor_Data ==
nullptr) or (fCursor_Offset < fWindowTop_Offset or fCursor_Offset >= fWindowBottom_Offset)) {
681 Assert (fWindowTop_Offset <= fCursor_Offset and fCursor_Offset <= fWindowBottom_Offset);
682 if (fWindowBottom_Offset == fCursor_Offset) {
702 class StyledTextIOWriterSinkStream_Memory :
public StyledTextIOWriter::SinkStream {
704 StyledTextIOWriterSinkStream_Memory ();
705 ~StyledTextIOWriterSinkStream_Memory ();
708 StyledTextIOWriterSinkStream_Memory (
const StyledTextIOWriterSinkStream_Memory&) =
delete;
709 void operator= (
const StyledTextIOWriterSinkStream_Memory&) =
delete;
712 virtual size_t current_offset ()
const override;
713 virtual void seek_to (
size_t to)
override;
714 virtual void write (
const void* buffer,
size_t bytes)
override;
716 nonvirtual
const void* PeekAtData ()
const;
717 nonvirtual
size_t GetLength ()
const;
722 size_t fBytesAllocated;
726#if qStroika_Frameworks_Led_SupportGDI
732 class EmbeddingSinkStream :
public SimpleEmbeddedObjectStyleMarker::SinkStream {
734 EmbeddingSinkStream (StyledTextIOWriter::SinkStream& realSinkStream);
736 virtual void write (
const void* buffer,
size_t bytes)
override;
739 StyledTextIOWriter::SinkStream& fRealSinkStream;
749 inline StyledTextIOReader::SrcStreamSeekSaver::SrcStreamSeekSaver (SrcStream& srcStream)
750 : fSrcStream (srcStream)
751 , fSavedPos (srcStream.current_offset ())
754 inline StyledTextIOReader::SrcStreamSeekSaver::~SrcStreamSeekSaver ()
757 fSrcStream.seek_to (fSavedPos);
767 inline StyledTextIOReader::StyledTextIOReader (SrcStream* srcStream, SinkStream* sinkStream,
const shared_ptr<BadInputHandler>& badInputHander)
768 : fSrcStream (*srcStream)
769 , fSinkStream (sinkStream)
770 , fBadInputHandler (badInputHander)
773 if (fBadInputHandler.get () ==
nullptr) {
774 fBadInputHandler = Memory::MakeSharedPtr<BadInputHandler> ();
777 inline StyledTextIOReader::SrcStream& StyledTextIOReader::GetSrcStream ()
const
781 inline StyledTextIOReader::SinkStream& StyledTextIOReader::GetSinkStream ()
const
793 inline shared_ptr<StyledTextIOReader::BadInputHandler> StyledTextIOReader::GetBadInputHandler ()
const
795 Ensure (fBadInputHandler.get () !=
nullptr);
796 return fBadInputHandler;
802 inline void StyledTextIOReader::SetBadInputHandler (
const shared_ptr<BadInputHandler>& badInputHandler)
804 fBadInputHandler = badInputHandler;
805 if (fBadInputHandler ==
nullptr) {
806 fBadInputHandler = Memory::MakeSharedPtr<BadInputHandler> ();
815 inline void StyledTextIOReader::HandleBadlyFormattedInput (
bool unrecoverable)
const
817 GetBadInputHandler ()->HandleBadlyFormattedInput (*
this, unrecoverable);
824 inline void StyledTextIOReader::PutBackLastChar ()
const
826 Require (fSrcStream.current_offset () > 0);
827 fSrcStream.seek_to (fSrcStream.current_offset () - 1);
829 inline char StyledTextIOReader::GetNextChar ()
const
832 if (fSrcStream.read1 (&c) == 1) {
836 throw ReadEOFException{};
841 inline char StyledTextIOReader::PeekNextChar ()
const
844 if (fSrcStream.read1 (&c) == 1) {
849 throw ReadEOFException ();
854 inline void StyledTextIOReader::ConsumeNextChar ()
const
856 (void)GetNextChar ();
860 inline StyledTextIOWriter::StyledTextIOWriter (SrcStream* srcStream, SinkStream* sinkStream)
861 : fSrcStream (srcStream)
862 , fSinkStream (sinkStream)
867 inline StyledTextIOWriter::SrcStream& StyledTextIOWriter::GetSrcStream ()
const
872 inline StyledTextIOWriter::SinkStream& StyledTextIOWriter::GetSinkStream ()
const
883 inline size_t StyledTextIOReader::SinkStream::GetCountOfTCharsInserted ()
const
885 return current_offset ();
889 inline StyledTextIOWriter::SrcStream::Table::CellInfo::CellInfo ()
890 : f_cellx (TWIPS (0))
891 , f_clcbpat (Color::kWhite)
896 inline const void* StyledTextIOWriterSinkStream_Memory::PeekAtData ()
const
900 inline size_t StyledTextIOWriterSinkStream_Memory::GetLength ()
const
#define RequireNotNull(p)
#define AssertNotReached()
#define Stroika_ATTRIBUTE_INDETERMINATE
Stroika_ATTRIBUTE_INDETERMINATE is used where you would use a C++ attribute for a variable that is in...