4#ifndef _Stroika_Frameworks_Led_StyledTextIO_h_
5#define _Stroika_Frameworks_Led_StyledTextIO_h_ 1
7#include "Stroika/Frameworks/StroikaPreComp.h"
40#include "Stroika/Foundation/Memory/Common.h"
42#include "Stroika/Frameworks/Led/StandardStyledTextImager.h"
43#include "Stroika/Frameworks/Led/StyledTextEmbeddedObjects.h"
44#include "Stroika/Frameworks/Led/StyledTextImager.h"
45#include "Stroika/Frameworks/Led/Support.h"
47namespace Stroika::Frameworks::Led::StyledTextIO {
54 class StyledTextIOReader {
66 virtual ~SrcStream () =
default;
73 virtual size_t current_offset ()
const = 0;
81 virtual void seek_to (
size_t to) = 0;
91 virtual size_t read (
void* buffer,
size_t bytes) = 0;
100 virtual size_t read1 (
char* c)
114 class BadInputHandler {
116 virtual ~BadInputHandler () =
default;
117 virtual void HandleBadlyFormattedInput (
const StyledTextIOReader& reader,
bool unrecoverable);
121 StyledTextIOReader (SrcStream* srcStream, SinkStream* sinkStream,
122 const shared_ptr<BadInputHandler>& badInputHander = shared_ptr<BadInputHandler> ());
126 virtual void Read () = 0;
127 virtual bool QuickLookAppearsToBeRightFormat () = 0;
135 class BufferedIndirectSrcStream :
public SrcStream {
137 BufferedIndirectSrcStream (SrcStream& realSrcStream);
140 virtual size_t current_offset ()
const override;
141 virtual void seek_to (
size_t to)
override;
142 virtual size_t read (
void* buffer,
size_t bytes)
override;
143 virtual size_t read1 (
char* c)
override;
146 nonvirtual
void FillCache ();
149 SrcStream& fRealSrcStream;
150 char fWindowTop_Data[4 * 1024];
151 size_t fWindowTop_Offset;
152 const char* fWindowBottom_Data;
153 size_t fWindowBottom_Offset;
154 const char* fCursor_Data;
155 size_t fCursor_Offset;
159 nonvirtual SrcStream& GetSrcStream ()
const;
160 nonvirtual SinkStream& GetSinkStream ()
const;
163 mutable BufferedIndirectSrcStream fSrcStream;
164 SinkStream* fSinkStream;
167 nonvirtual shared_ptr<BadInputHandler> GetBadInputHandler ()
const;
168 nonvirtual
void SetBadInputHandler (
const shared_ptr<BadInputHandler>& badInputHandler);
171 shared_ptr<BadInputHandler> fBadInputHandler;
174 nonvirtual
void HandleBadlyFormattedInput (
bool unrecoverable =
false)
const;
177 class SrcStreamSeekSaver;
180 struct ReadEOFException {};
184 nonvirtual
void PutBackLastChar ()
const;
185 nonvirtual
char GetNextChar ()
const;
186 nonvirtual
char PeekNextChar ()
const;
187 nonvirtual
void ConsumeNextChar ()
const;
188 nonvirtual
string GrabString (
size_t from,
size_t to =
size_t (-1));
193 class StyledTextIOReader::SrcStreamSeekSaver {
195 SrcStreamSeekSaver (SrcStream& srcStream);
196 ~SrcStreamSeekSaver ();
199 SrcStream& fSrcStream;
208 class StyledTextIOReader::SinkStream {
210 virtual ~SinkStream ()
219 virtual size_t current_offset ()
const = 0;
229 virtual void AppendText (
const Led_tChar* text,
size_t nTChars,
const FontSpecification* fontSpec) = 0;
236 virtual void ApplyStyle (
size_t from,
size_t to,
const vector<StyledInfoSummaryRecord>& styleRuns) = 0;
243 virtual FontSpecification GetDefaultFontSpec ()
const = 0;
245#if qStroika_Frameworks_Led_SupportGDI
251 virtual void InsertEmbeddingForExistingSentinel (SimpleEmbeddedObjectStyleMarker* embedding,
size_t at) = 0;
258 virtual void AppendEmbedding (SimpleEmbeddedObjectStyleMarker* embedding) = 0;
266 virtual void AppendSoftLineBreak () = 0;
269 virtual void StartTable ();
270 virtual void EndTable ();
271 virtual void StartTableRow ();
272 virtual void EndTableRow ();
273 virtual void StartTableCell (
size_t colSpan);
274 virtual void EndTableCell ();
281 virtual void InsertMarker (Marker* m,
size_t at,
size_t length, MarkerOwner* markerOwner) = 0;
284 virtual void SetJustification (Justification justification);
285 virtual void SetStandardTabStopList (
const StandardTabStopList& tabStops);
286 virtual void SetFirstIndent (TWIPS tx);
287 virtual void SetLeftMargin (TWIPS lhs);
288 virtual void SetRightMargin (TWIPS rhs);
289 virtual void SetSpaceBefore (TWIPS sb);
290 virtual void SetSpaceAfter (TWIPS sa);
291 virtual void SetLineSpacing (LineSpacing sl);
292 virtual void SetTextHidden (
bool hidden);
293 virtual void SetListStyle (ListStyle listStyle);
294 virtual void SetListIndentLevel (
unsigned char indentLevel);
297 virtual void SetTableBorderColor (Color c);
298 virtual void SetTableBorderWidth (TWIPS bWidth);
299 virtual void SetCellWidths (
const vector<TWIPS>& cellWidths);
300 virtual void SetCellBackColor (
const Color c);
301 virtual void SetDefaultCellMarginsForCurrentRow (TWIPS top, TWIPS left, TWIPS bottom, TWIPS right);
302 virtual void SetDefaultCellSpacingForCurrentRow (TWIPS top, TWIPS left, TWIPS bottom, TWIPS right);
310 virtual void EndOfBuffer () {};
317 virtual void Flush () = 0;
320 nonvirtual
size_t GetCountOfTCharsInserted ()
const;
329 class StyledTextIOWriter {
335 StyledTextIOWriter (SrcStream* srcStream, SinkStream* sinkStream);
339 virtual void Write () = 0;
342 nonvirtual SrcStream& GetSrcStream ()
const;
343 nonvirtual SinkStream& GetSinkStream ()
const;
346 SrcStream* fSrcStream;
347 SinkStream* fSinkStream;
351 nonvirtual
void write (
const void* data,
size_t nBytes);
352 nonvirtual
void write (
char c);
353 nonvirtual
void write (
const char* str);
354 nonvirtual
void write (
const string& str);
361 class StyledTextIOWriter::SrcStream {
363 virtual ~SrcStream () =
default;
371 virtual size_t readNTChars (Led_tChar* intoBuf,
size_t maxTChars) = 0;
378 virtual size_t current_offset ()
const = 0;
385 virtual void seek_to (
size_t to) = 0;
392 virtual size_t GetTotalTextLength ()
const = 0;
399 virtual vector<StyledInfoSummaryRecord> GetStyleInfo (
size_t from,
size_t len)
const = 0;
401#if qStroika_Frameworks_Led_SupportGDI
407 virtual vector<SimpleEmbeddedObjectStyleMarker*> CollectAllEmbeddingMarkersInRange (
size_t from,
size_t to)
const = 0;
419 virtual Table* GetTableAt (
size_t at)
const = 0;
427 virtual void SummarizeFontAndColorTable (set<SDKString>* fontNames, set<Color>* colorsUsed)
const = 0;
435 virtual size_t GetEmbeddingMarkerPosOffset ()
const = 0;
438 virtual Justification GetJustification ()
const;
439 virtual StandardTabStopList GetStandardTabStopList ()
const;
440 virtual TWIPS GetFirstIndent ()
const;
441 virtual void GetMargins (TWIPS* lhs, TWIPS* rhs)
const;
442 virtual TWIPS GetSpaceBefore ()
const;
443 virtual TWIPS GetSpaceAfter ()
const;
444 virtual LineSpacing GetLineSpacing ()
const;
445 virtual void GetListStyleInfo (ListStyle* listStyle,
unsigned char* indentLevel)
const;
446 virtual Led_tChar GetSoftLineBreakCharacter ()
const;
447 virtual DiscontiguousRun<bool> GetHidableTextRuns ()
const;
454 class StyledTextIOWriter::SrcStream::Table {
456 virtual ~Table () =
default;
470 virtual size_t GetRows ()
const = 0;
476 virtual size_t GetColumns (
size_t row)
const = 0;
484 virtual void GetRowInfo (
size_t row, vector<CellInfo>* cellInfos) = 0;
490 virtual StyledTextIOWriter::SrcStream* MakeCellSubSrcStream (
size_t row,
size_t column) = 0;
496 virtual size_t GetOffsetEnd ()
const = 0;
502 virtual TWIPS_Rect GetDefaultCellMarginsForRow (
size_t row)
const = 0;
508 virtual TWIPS_Rect GetDefaultCellSpacingForRow (
size_t row)
const = 0;
516 class StyledTextIOWriter::SinkStream {
518 virtual ~SinkStream ()
527 virtual size_t current_offset ()
const = 0;
534 virtual void seek_to (
size_t to) = 0;
541 virtual void write (
const void* buffer,
size_t bytes) = 0;
557 class StyledTextIOSrcStream_Memory :
public StyledTextIOReader::SrcStream {
559 StyledTextIOSrcStream_Memory (
const void* data,
size_t nBytes);
562 virtual size_t current_offset ()
const override;
563 virtual void seek_to (
size_t to)
override;
564 virtual size_t read (
void* buffer,
size_t bytes)
override;
565 virtual size_t read1 (
char* c)
override;
569 const void* fDataEnd;
570 size_t fBytesInBuffer;
574 inline StyledTextIOReader::BufferedIndirectSrcStream::BufferedIndirectSrcStream (SrcStream& realSrcStream)
575 : fRealSrcStream (realSrcStream)
578 fWindowTop_Offset (size_t (-1))
579 , fWindowBottom_Data (nullptr)
580 , fWindowBottom_Offset (size_t (-1))
581 , fCursor_Data (nullptr)
585 inline void StyledTextIOReader::BufferedIndirectSrcStream::FillCache ()
587 fWindowTop_Offset = fCursor_Offset;
588 fRealSrcStream.seek_to (fWindowTop_Offset);
589 size_t bytesRead = fRealSrcStream.read (fWindowTop_Data, Foundation::Memory::NEltsOf (fWindowTop_Data));
590 fWindowBottom_Data = fWindowTop_Data + bytesRead;
591 fWindowBottom_Offset = fWindowTop_Offset + bytesRead;
592 Assert (fCursor_Offset >= fWindowTop_Offset and fCursor_Offset <= fWindowBottom_Offset);
593 Assert (fCursor_Offset == fWindowTop_Offset);
594 if (fCursor_Offset >= fWindowTop_Offset and fCursor_Offset <= fWindowBottom_Offset) {
595 fCursor_Data = fWindowTop_Data + (fCursor_Offset - fWindowTop_Offset);
597 Ensure (fWindowTop_Data <= fCursor_Data and fCursor_Data <= fWindowBottom_Data);
598 Ensure (fWindowTop_Offset <= fCursor_Offset and fCursor_Offset <= fWindowBottom_Offset);
600 inline size_t StyledTextIOReader::BufferedIndirectSrcStream::current_offset ()
const
602 return fCursor_Offset;
604 inline void StyledTextIOReader::BufferedIndirectSrcStream::seek_to (
size_t to)
608 if (fWindowTop_Offset <= to and to <= fWindowBottom_Offset) {
609 fCursor_Data = fWindowTop_Data + (to - fWindowTop_Offset);
612 fCursor_Data =
nullptr;
616 inline size_t StyledTextIOReader::BufferedIndirectSrcStream::read (
void* buffer,
size_t bytes)
620 byte* destCursor =
reinterpret_cast<byte*
> (buffer);
621 size_t bytesReadSoFar = 0;
627 if (fCursor_Data !=
nullptr and fWindowTop_Offset >= fCursor_Offset and fCursor_Offset < fWindowBottom_Offset) {
628 size_t bytesAvail = fWindowBottom_Offset - fCursor_Offset;
629 size_t thisReadCount = min (bytesAvail, bytes);
631 (void)::memcpy (destCursor, fCursor_Data, thisReadCount);
632 destCursor += thisReadCount;
633 fCursor_Data += thisReadCount;
634 fCursor_Offset += thisReadCount;
635 bytesReadSoFar += thisReadCount;
642 if (bytesReadSoFar < bytes) {
643 size_t bytesLeftToRead = bytes - bytesReadSoFar;
644 if (bytesLeftToRead < Foundation::Memory::NEltsOf (fWindowTop_Data)) {
646 size_t bytesAvail = fWindowBottom_Offset - fCursor_Offset;
647 size_t thisReadCount = min (bytesAvail, bytesLeftToRead);
649 DISABLE_COMPILER_MSC_WARNING_START (6387)
650 (void)::memcpy (destCursor, fCursor_Data, thisReadCount);
651 DISABLE_COMPILER_MSC_WARNING_END (6387)
652 destCursor += thisReadCount;
653 fCursor_Data += thisReadCount;
654 fCursor_Offset += thisReadCount;
655 bytesReadSoFar += thisReadCount;
658 fRealSrcStream.seek_to (fCursor_Offset);
659 size_t bytesRead = fRealSrcStream.read (destCursor, bytesLeftToRead);
660 bytesReadSoFar += bytesRead;
661 fCursor_Offset += bytesRead;
663 fCursor_Data =
nullptr;
666 return bytesReadSoFar;
668 inline size_t StyledTextIOReader::BufferedIndirectSrcStream::read1 (
char* c)
677 if ((fCursor_Data ==
nullptr) or (fCursor_Offset < fWindowTop_Offset or fCursor_Offset >= fWindowBottom_Offset)) {
680 Assert (fWindowTop_Offset <= fCursor_Offset and fCursor_Offset <= fWindowBottom_Offset);
681 if (fWindowBottom_Offset == fCursor_Offset) {
701 class StyledTextIOWriterSinkStream_Memory :
public StyledTextIOWriter::SinkStream {
703 StyledTextIOWriterSinkStream_Memory ();
704 ~StyledTextIOWriterSinkStream_Memory ();
707 StyledTextIOWriterSinkStream_Memory (
const StyledTextIOWriterSinkStream_Memory&) =
delete;
708 void operator= (
const StyledTextIOWriterSinkStream_Memory&) =
delete;
711 virtual size_t current_offset ()
const override;
712 virtual void seek_to (
size_t to)
override;
713 virtual void write (
const void* buffer,
size_t bytes)
override;
715 nonvirtual
const void* PeekAtData ()
const;
716 nonvirtual
size_t GetLength ()
const;
721 size_t fBytesAllocated;
725#if qStroika_Frameworks_Led_SupportGDI
731 class EmbeddingSinkStream :
public SimpleEmbeddedObjectStyleMarker::SinkStream {
733 EmbeddingSinkStream (StyledTextIOWriter::SinkStream& realSinkStream);
735 virtual void write (
const void* buffer,
size_t bytes)
override;
738 StyledTextIOWriter::SinkStream& fRealSinkStream;
748 inline StyledTextIOReader::SrcStreamSeekSaver::SrcStreamSeekSaver (SrcStream& srcStream)
749 : fSrcStream (srcStream)
750 , fSavedPos (srcStream.current_offset ())
753 inline StyledTextIOReader::SrcStreamSeekSaver::~SrcStreamSeekSaver ()
756 fSrcStream.seek_to (fSavedPos);
766 inline StyledTextIOReader::StyledTextIOReader (SrcStream* srcStream, SinkStream* sinkStream,
const shared_ptr<BadInputHandler>& badInputHander)
767 : fSrcStream (*srcStream)
768 , fSinkStream (sinkStream)
769 , fBadInputHandler (badInputHander)
772 if (fBadInputHandler.get () ==
nullptr) {
773 fBadInputHandler = make_shared<BadInputHandler> ();
776 inline StyledTextIOReader::SrcStream& StyledTextIOReader::GetSrcStream ()
const
780 inline StyledTextIOReader::SinkStream& StyledTextIOReader::GetSinkStream ()
const
792 inline shared_ptr<StyledTextIOReader::BadInputHandler> StyledTextIOReader::GetBadInputHandler ()
const
794 Ensure (fBadInputHandler.get () !=
nullptr);
795 return fBadInputHandler;
801 inline void StyledTextIOReader::SetBadInputHandler (
const shared_ptr<BadInputHandler>& badInputHandler)
803 fBadInputHandler = badInputHandler;
804 if (fBadInputHandler ==
nullptr) {
805 fBadInputHandler = make_shared<BadInputHandler> ();
814 inline void StyledTextIOReader::HandleBadlyFormattedInput (
bool unrecoverable)
const
816 GetBadInputHandler ()->HandleBadlyFormattedInput (*
this, unrecoverable);
823 inline void StyledTextIOReader::PutBackLastChar ()
const
825 Require (fSrcStream.current_offset () > 0);
826 fSrcStream.seek_to (fSrcStream.current_offset () - 1);
828 inline char StyledTextIOReader::GetNextChar ()
const
832 if (fSrcStream.read1 (&c) == 1) {
836 throw ReadEOFException ();
841 inline char StyledTextIOReader::PeekNextChar ()
const
845 if (fSrcStream.read1 (&c) == 1) {
850 throw ReadEOFException ();
855 inline void StyledTextIOReader::ConsumeNextChar ()
const
857 (void)GetNextChar ();
861 inline StyledTextIOWriter::StyledTextIOWriter (SrcStream* srcStream, SinkStream* sinkStream)
862 : fSrcStream (srcStream)
863 , fSinkStream (sinkStream)
868 inline StyledTextIOWriter::SrcStream& StyledTextIOWriter::GetSrcStream ()
const
873 inline StyledTextIOWriter::SinkStream& StyledTextIOWriter::GetSinkStream ()
const
884 inline size_t StyledTextIOReader::SinkStream::GetCountOfTCharsInserted ()
const
886 return current_offset ();
890 inline StyledTextIOWriter::SrcStream::Table::CellInfo::CellInfo ()
891 : f_cellx (TWIPS (0))
892 , f_clcbpat (Color::kWhite)
897 inline const void* StyledTextIOWriterSinkStream_Memory::PeekAtData ()
const
901 inline size_t StyledTextIOWriterSinkStream_Memory::GetLength ()
const
#define RequireNotNull(p)
#define AssertNotReached()