4#include "Stroika/Frameworks/StroikaPreComp.h"
13#include "Stroika/Foundation/Characters/LineEndings.h"
15#include "Stroika/Foundation/DataExchange/BadFormatException.h"
16#include "Stroika/Foundation/Execution/Exceptions.h"
18#include "Stroika/Frameworks/Led/StyledTextEmbeddedObjects.h"
20#include "StyledTextIO_LedNative.h"
25using namespace Stroika::Frameworks;
26using namespace Stroika::Frameworks::Led;
27using namespace Stroika::Frameworks::Led::StyledTextIO;
32 inline void OutputStandardToSinkStream_size_t_ (StyledTextIOWriter::SinkStream& sinkStream,
size_t n)
36 sinkStream.write (&buf,
sizeof (buf));
38 inline unsigned long InputStandardFromSrcStream_ULONG (StyledTextIOReader::SrcStream& srcStream)
41 if (srcStream.read (&buf, sizeof (buf)) !=
sizeof (buf)) {
44 return (BufToUInt32 (&buf));
57using LedFormatMagicCookie =
char[16];
58const LedFormatMagicCookie kLedPartFormatVersion_4_MagicNumber =
"\01Version4";
59const LedFormatMagicCookie kLedPartFormatVersion_5_MagicNumber =
"\01Version5";
60const LedFormatMagicCookie kLedPartFormatVersion_6_MagicNumber =
"\01Version6";
65struct PortableStyleRunData_Version4 {
67 unsigned char fItalic;
68 unsigned char fBoldWeight;
70 eBoldnessNormal = 400 / 4,
71 eBoldnessBold = 700 / 4
79inline void _DO_ALIGN_ASSERTS_Version4_ ()
81 Assert (
sizeof (PortableStyleRunData_Version4) == 268);
82 Assert (offsetof (PortableStyleRunData_Version4, fItalic) == 256);
83 Assert (offsetof (PortableStyleRunData_Version4, fBoldWeight) == 257);
84 Assert (offsetof (PortableStyleRunData_Version4, fUnderline) == 258);
85 Assert (offsetof (PortableStyleRunData_Version4, fFontSize) == 260);
86 Assert (offsetof (PortableStyleRunData_Version4, fLength) == 264);
88inline StyledInfoSummaryRecord mkInfoSummaryRecordFromPortData (
const PortableStyleRunData_Version4& srcData)
90 _DO_ALIGN_ASSERTS_Version4_ ();
92 fsp.SetStyle_Plain ();
93 fsp.SetStyle_Bold (srcData.fBoldWeight >= PortableStyleRunData_Version4::eBoldnessBold);
94 fsp.SetStyle_Italic (!!srcData.fItalic);
95 fsp.SetStyle_Underline (!!srcData.fUnderline);
96 short fontSize = BufToUInt16 (&srcData.fFontSize);
97 if (fontSize < 3 or fontSize > 128) {
100 fsp.SetPointSize (fontSize);
101 fsp.SetFontName (String::FromNarrowSDKString (srcData.fFontName).AsSDKString ());
102 return (StyledInfoSummaryRecord (fsp, BufToUInt32 (&srcData.fLength)));
109struct PortableStyleRunData_Version5 {
110 unsigned char fThisRecordLength;
128 unsigned char fStyleSet;
129 unsigned short fPointSize;
133 static size_t NameLenFromRecordLen (
unsigned char len)
135 size_t xtra = offsetof (PortableStyleRunData_Version5, fFontName);
137 return static_cast<unsigned char> (len - xtra);
139 static unsigned char RecordLenFromNameLen (
size_t len)
144 size_t xtra = offsetof (PortableStyleRunData_Version5, fFontName);
145 return (
unsigned char)min (xtra +
size_t (len),
size_t (256));
148inline void _DO_ALIGN_ASSERTS_Version5_ ()
150 Assert (offsetof (PortableStyleRunData_Version5, fThisRecordLength) == 0);
151 Assert (offsetof (PortableStyleRunData_Version5, fStyleSet) == 1);
152 Assert (offsetof (PortableStyleRunData_Version5, fPointSize) == 2);
153 Assert (offsetof (PortableStyleRunData_Version5, fLength) == 4);
154 Assert (offsetof (PortableStyleRunData_Version5, fFontName) == 8);
157 Assert (
sizeof (PortableStyleRunData_Version5) == 8 + 256);
159inline PortableStyleRunData_Version5 mkPortableStyleRunData_Version5 (
const StyledInfoSummaryRecord& isr)
161 _DO_ALIGN_ASSERTS_Version5_ ();
162 PortableStyleRunData_Version5 data;
163 (void)::memset (&data, 0,
sizeof data);
166 string fontName = String::FromSDKString (isr.GetFontName ()).AsNarrowSDKString ();
167 Characters::CString::Copy (data.fFontName, Memory::NEltsOf (data.fFontName), fontName.c_str ());
168 data.fThisRecordLength = data.RecordLenFromNameLen (fontName.length ());
170 data.fStyleSet |= isr.GetStyle_Bold () ? (1 << data.eBold) : 0;
171 data.fStyleSet |= isr.GetStyle_Italic () ? (1 << data.eItalic) : 0;
172 data.fStyleSet |= isr.GetStyle_Underline () ? (1 << data.eUnderline) : 0;
174#if qStroika_Foundation_Common_Platform_Windows
175 data.fStyleSet |= isr.GetStyle_Strikeout () ? (1 << data.eStrikeout) : 0;
177 UInt16ToBuf (isr.GetPointSize (), &data.fPointSize);
178 SizeTToBuf (isr.fLength, &data.fLength);
181inline StyledInfoSummaryRecord mkInfoSummaryRecordFromPortData (
const PortableStyleRunData_Version5& srcData)
183 _DO_ALIGN_ASSERTS_Version5_ ();
185 fsp.SetStyle_Plain ();
186 fsp.SetStyle_Bold (!!(srcData.fStyleSet & (1 << srcData.eBold)));
187 fsp.SetStyle_Italic (!!(srcData.fStyleSet & (1 << srcData.eItalic)));
188 fsp.SetStyle_Underline (!!(srcData.fStyleSet & (1 << srcData.eUnderline)));
189#if qStroika_Foundation_Common_Platform_Windows
190 fsp.SetStyle_Strikeout (!!(srcData.fStyleSet & (1 << srcData.eStrikeout)));
192 short fontSize = BufToUInt16 (&srcData.fPointSize);
193 if (fontSize < 3 or fontSize > 128) {
196 fsp.SetPointSize (fontSize);
198 size_t fontNameLen = srcData.NameLenFromRecordLen (srcData.fThisRecordLength);
199 fsp.SetFontName (String::FromNarrowSDKString (
string{srcData.fFontName, fontNameLen}).AsSDKString ());
201 return (StyledInfoSummaryRecord (fsp, BufToUInt32 (&srcData.fLength)));
208struct PortableStyleRunData_Version6 {
209 unsigned char fThisRecordLength;
235 static size_t NameLenFromRecordLen (
unsigned char len)
237 size_t xtra = offsetof (PortableStyleRunData_Version6, fFontName);
239 return static_cast<unsigned char> (len - xtra);
241 static unsigned char RecordLenFromNameLen (
size_t len)
246 size_t xtra = offsetof (PortableStyleRunData_Version6, fFontName);
247 return (
unsigned char)min (xtra +
size_t (len),
size_t (256));
250inline void _DO_ALIGN_ASSERTS_Version6_ ()
252 Assert (offsetof (PortableStyleRunData_Version6, fThisRecordLength) == 0);
253 Assert (offsetof (PortableStyleRunData_Version6, fStyleSet) == 2);
254 Assert (offsetof (PortableStyleRunData_Version6, fPointSize) == 4);
255 Assert (offsetof (PortableStyleRunData_Version6, fColor) == 6);
256 Assert (offsetof (PortableStyleRunData_Version6, fLength) == 12);
257 Assert (offsetof (PortableStyleRunData_Version6, fFontName) == 16);
258 Assert (
sizeof (PortableStyleRunData_Version6) == 16 + 256);
260inline PortableStyleRunData_Version6 mkPortableStyleRunData_Version6 (
const StyledInfoSummaryRecord& isr)
262 _DO_ALIGN_ASSERTS_Version6_ ();
263 PortableStyleRunData_Version6 data;
264 (void)::memset (&data, 0,
sizeof data);
267 string fontName = String::FromSDKString (isr.GetFontName ()).AsNarrowSDKString ();
268 Characters::CString::Copy (data.fFontName, Memory::NEltsOf (data.fFontName), fontName.c_str ());
269 data.fThisRecordLength = data.RecordLenFromNameLen (fontName.length ());
271 data.fStyleSet |= isr.GetStyle_Bold () ? (1 << data.eBold) : 0;
272 data.fStyleSet |= isr.GetStyle_Italic () ? (1 << data.eItalic) : 0;
273 data.fStyleSet |= isr.GetStyle_Underline () ? (1 << data.eUnderline) : 0;
275#if qStroika_Foundation_Common_Platform_Windows
276 data.fStyleSet |= isr.GetStyle_Strikeout () ? (1 << data.eStrikeout) : 0;
278 data.fStyleSet |= (isr.GetStyle_SubOrSuperScript () == FontSpecification::eSubscript) ? (1 << data.eSubscript) : 0;
279 data.fStyleSet |= (isr.GetStyle_SubOrSuperScript () == FontSpecification::eSuperscript) ? (1 << data.eSuperscript) : 0;
280 UInt16ToBuf (isr.GetTextColor ().GetRed (), &data.fColor[0]);
281 UInt16ToBuf (isr.GetTextColor ().GetGreen (), &data.fColor[1]);
282 UInt16ToBuf (isr.GetTextColor ().GetBlue (), &data.fColor[2]);
283 UInt16ToBuf (isr.GetPointSize (), &data.fPointSize);
284 SizeTToBuf (isr.fLength, &data.fLength);
287inline StyledInfoSummaryRecord mkInfoSummaryRecordFromPortData (
const PortableStyleRunData_Version6& srcData)
289 _DO_ALIGN_ASSERTS_Version6_ ();
291 fsp.SetStyle_Plain ();
292 fsp.SetStyle_Bold (!!(srcData.fStyleSet & (1 << srcData.eBold)));
293 fsp.SetStyle_Italic (!!(srcData.fStyleSet & (1 << srcData.eItalic)));
294 fsp.SetStyle_Underline (!!(srcData.fStyleSet & (1 << srcData.eUnderline)));
295#if qStroika_Foundation_Common_Platform_Windows
296 fsp.SetStyle_Strikeout (!!(srcData.fStyleSet & (1 << srcData.eStrikeout)));
298 if (srcData.fStyleSet & (1 << srcData.eSubscript)) {
299 fsp.SetStyle_SubOrSuperScript (FontSpecification::eSubscript);
301 if (srcData.fStyleSet & (1 << srcData.eSuperscript)) {
302 fsp.SetStyle_SubOrSuperScript (FontSpecification::eSuperscript);
305 fsp.SetTextColor (
Color (BufToUInt16 (&srcData.fColor[0]), BufToUInt16 (&srcData.fColor[1]), BufToUInt16 (&srcData.fColor[2])));
307 short fontSize = BufToUInt16 (&srcData.fPointSize);
308 if (fontSize < 3 or fontSize > 128) {
311 fsp.SetPointSize (fontSize);
313 size_t fontNameLen = srcData.NameLenFromRecordLen (srcData.fThisRecordLength);
314 fsp.SetFontName (String::FromNarrowSDKString (
string{srcData.fFontName, fontNameLen}).AsSDKString ());
316 return (StyledInfoSummaryRecord (fsp, BufToUInt32 (&srcData.fLength)));
324StyledTextIOReader_LedNativeFileFormat::StyledTextIOReader_LedNativeFileFormat (SrcStream* srcStream, SinkStream* sinkStream)
325 : StyledTextIOReader (srcStream, sinkStream)
329void StyledTextIOReader_LedNativeFileFormat::Read ()
331 _DO_ALIGN_ASSERTS_Version4_ ();
332 _DO_ALIGN_ASSERTS_Version5_ ();
334 LedFormatMagicCookie cookie;
335 if (GetSrcStream ().read (cookie,
sizeof (cookie)) !=
sizeof (cookie)) {
338 bool isVersion4 = memcmp (cookie, kLedPartFormatVersion_4_MagicNumber,
sizeof (kLedPartFormatVersion_4_MagicNumber)) == 0;
339 bool isVersion5 = memcmp (cookie, kLedPartFormatVersion_5_MagicNumber,
sizeof (kLedPartFormatVersion_5_MagicNumber)) == 0;
340 bool isVersion6 = memcmp (cookie, kLedPartFormatVersion_6_MagicNumber,
sizeof (kLedPartFormatVersion_6_MagicNumber)) == 0;
341 bool isFormatGood = isVersion4 or isVersion5 or isVersion6;
342 if (not isFormatGood) {
346 Read_Version4 (cookie);
349 Read_Version5 (cookie);
352 Read_Version6 (cookie);
354 GetSinkStream ().EndOfBuffer ();
357bool StyledTextIOReader_LedNativeFileFormat::QuickLookAppearsToBeRightFormat ()
359 SrcStreamSeekSaver savePos (GetSrcStream ());
361 LedFormatMagicCookie cookie;
362 if (GetSrcStream ().read (cookie,
sizeof (cookie)) !=
sizeof (cookie)) {
365 bool isVersion4 = memcmp (cookie, kLedPartFormatVersion_4_MagicNumber,
sizeof (kLedPartFormatVersion_4_MagicNumber)) == 0;
366 bool isVersion5 = memcmp (cookie, kLedPartFormatVersion_5_MagicNumber,
sizeof (kLedPartFormatVersion_5_MagicNumber)) == 0;
367 bool isVersion6 = memcmp (cookie, kLedPartFormatVersion_6_MagicNumber,
sizeof (kLedPartFormatVersion_6_MagicNumber)) == 0;
368 bool isFormatGood = isVersion4 or isVersion5 or isVersion6;
372void StyledTextIOReader_LedNativeFileFormat::Read_Version4 (
const char* cookie)
377 size_t totalTextLength = 0;
380 if (GetSrcStream ().read (&lenAsBuf,
sizeof (lenAsBuf)) !=
sizeof (lenAsBuf)) {
383 totalTextLength = BufToUInt32 (&lenAsBuf);
385 const size_t kMaxBufSize = 64 * 1024 * 1024;
388 if (totalTextLength > kMaxBufSize) {
392 StackBuffer<char> buf{Memory::eUninitialized, totalTextLength};
393 if (GetSrcStream ().read (buf.data (), totalTextLength) != totalTextLength) {
396 size_t nChars = totalTextLength;
397 StackBuffer<Led_tChar> unicodeText{Memory::eUninitialized, nChars};
398#if qStroika_Foundation_Common_Platform_Windows
403 GetSinkStream ().AppendText (text.data (), text.size (),
nullptr);
408 size_t nStyleRuns = InputStandardFromSrcStream_ULONG (GetSrcStream ());
409 if (nStyleRuns > totalTextLength + 1) {
412 vector<StyledInfoSummaryRecord> styleRunInfo;
414 StackBuffer<PortableStyleRunData_Version4> portableStyleRuns{Memory::eUninitialized, nStyleRuns};
415 if (GetSrcStream ().read (portableStyleRuns.data (), nStyleRuns * sizeof (PortableStyleRunData_Version4)) !=
416 nStyleRuns *
sizeof (PortableStyleRunData_Version4)) {
419 for (
size_t i = 0; i < nStyleRuns; ++i) {
420 styleRunInfo.push_back (mkInfoSummaryRecordFromPortData (portableStyleRuns[i]));
423 GetSinkStream ().ApplyStyle (0, totalTextLength, styleRunInfo);
427#if qStroika_Frameworks_Led_SupportGDI
429 size_t nEmbeddings = InputStandardFromSrcStream_ULONG (GetSrcStream ());
430 if (nEmbeddings > totalTextLength) {
434 for (
size_t i = 0; i < nEmbeddings; ++i) {
435 size_t whereAt = InputStandardFromSrcStream_ULONG (GetSrcStream ());
436 size_t howManyBytes = InputStandardFromSrcStream_ULONG (GetSrcStream ());
438 size_t justBeforeEmbedding = GetSrcStream ().current_offset ();
440 Led_PrivateEmbeddingTag tag;
441 if (howManyBytes <
sizeof (tag)) {
444 if (GetSrcStream ().read (tag,
sizeof (tag)) !=
sizeof (tag)) {
447 SimpleEmbeddedObjectStyleMarker* embedding = InternalizeEmbedding (tag, howManyBytes -
sizeof (tag));
448 if (embedding == NULL) {
452 GetSrcStream ().seek_to (justBeforeEmbedding + howManyBytes);
455 GetSinkStream ().InsertEmbeddingForExistingSentinel (embedding, whereAt);
462 LedFormatMagicCookie endCookie;
463 if (GetSrcStream ().read (endCookie,
sizeof (endCookie)) !=
sizeof (endCookie)) {
466 if (memcmp (endCookie, cookie,
sizeof (endCookie)) != 0) {
473void StyledTextIOReader_LedNativeFileFormat::Read_Version5 (
const char* cookie)
478 size_t totalTextLength = 0;
481 if (GetSrcStream ().read (&lenAsBuf,
sizeof (lenAsBuf)) !=
sizeof (lenAsBuf)) {
484 totalTextLength = BufToUInt32 (&lenAsBuf);
486 const size_t kMaxBufSize = 64 * 1024 * 1024;
489 if (totalTextLength > kMaxBufSize) {
493 StackBuffer<char> buf{Memory::eUninitialized, totalTextLength};
494 if (GetSrcStream ().read (buf.data (), totalTextLength) != totalTextLength) {
497 size_t nChars = totalTextLength;
498 StackBuffer<Led_tChar> unicodeText{Memory::eUninitialized, nChars};
499#if qStroika_Foundation_Common_Platform_Windows
504 GetSinkStream ().AppendText (text.data (), text.size (),
nullptr);
509 size_t howManyBytesOfStyleInfo = InputStandardFromSrcStream_ULONG (GetSrcStream ());
510 StackBuffer<char> portableStyleRunsBuffer{Memory::eUninitialized, howManyBytesOfStyleInfo};
511 if (GetSrcStream ().read (portableStyleRunsBuffer.data (), howManyBytesOfStyleInfo) != howManyBytesOfStyleInfo) {
515 size_t offsetInText = 0;
517 for (; i < howManyBytesOfStyleInfo;) {
518 const PortableStyleRunData_Version5* thisBucket = (PortableStyleRunData_Version5*)(((
char*)portableStyleRunsBuffer) + i);
519 if (i + thisBucket->fThisRecordLength > howManyBytesOfStyleInfo) {
522 StyledInfoSummaryRecord isr = mkInfoSummaryRecordFromPortData (*thisBucket);
524 vector<StyledInfoSummaryRecord> list;
525 list.push_back (isr);
526 GetSinkStream ().ApplyStyle (offsetInText, offsetInText + isr.fLength, list);
528 offsetInText += isr.fLength;
529 i += thisBucket->fThisRecordLength;
531 if (i != howManyBytesOfStyleInfo) {
536#if qStroika_Frameworks_Led_SupportGDI
539 size_t nEmbeddings = InputStandardFromSrcStream_ULONG (GetSrcStream ());
540 if (nEmbeddings > totalTextLength) {
544 for (
size_t i = 0; i < nEmbeddings; ++i) {
545 size_t whereAt = InputStandardFromSrcStream_ULONG (GetSrcStream ()) - 1;
546 size_t howManyBytes = InputStandardFromSrcStream_ULONG (GetSrcStream ());
548 size_t justBeforeEmbedding = GetSrcStream ().current_offset ();
550 Led_PrivateEmbeddingTag tag;
551 if (howManyBytes <
sizeof (tag)) {
554 if (GetSrcStream ().read (tag,
sizeof (tag)) !=
sizeof (tag)) {
557 SimpleEmbeddedObjectStyleMarker* embedding = InternalizeEmbedding (tag, howManyBytes -
sizeof (tag));
558 if (embedding ==
nullptr) {
562 GetSrcStream ().seek_to (justBeforeEmbedding + howManyBytes);
565 GetSinkStream ().InsertEmbeddingForExistingSentinel (embedding, whereAt);
572 LedFormatMagicCookie endCookie;
573 if (GetSrcStream ().read (endCookie,
sizeof (endCookie)) !=
sizeof (endCookie)) {
576 if (memcmp (endCookie, cookie,
sizeof (endCookie)) != 0) {
583void StyledTextIOReader_LedNativeFileFormat::Read_Version6 (
const char* cookie)
588 size_t totalTextLength = 0;
591 if (GetSrcStream ().read (&lenAsBuf,
sizeof (lenAsBuf)) !=
sizeof (lenAsBuf)) {
594 totalTextLength = BufToUInt32 (&lenAsBuf);
596 const size_t kMaxBufSize = 64 * 1024 * 1024;
599 if (totalTextLength > kMaxBufSize) {
603 StackBuffer<char> buf{Memory::eUninitialized, totalTextLength};
604 if (GetSrcStream ().read (buf.data (), totalTextLength) != totalTextLength) {
607 size_t nChars = totalTextLength;
608 StackBuffer<Led_tChar> unicodeText{Memory::eUninitialized, nChars};
609#if qStroika_Foundation_Common_Platform_Windows
614 GetSinkStream ().AppendText (text.data (), text.size (),
nullptr);
619 size_t howManyBytesOfStyleInfo = InputStandardFromSrcStream_ULONG (GetSrcStream ());
620 StackBuffer<char> portableStyleRunsBuffer{Memory::eUninitialized, howManyBytesOfStyleInfo};
621 if (GetSrcStream ().read (portableStyleRunsBuffer.data (), howManyBytesOfStyleInfo) != howManyBytesOfStyleInfo) {
625 size_t offsetInText = 0;
627 for (; i < howManyBytesOfStyleInfo;) {
628 const PortableStyleRunData_Version6* thisBucket = (PortableStyleRunData_Version6*)(((
char*)portableStyleRunsBuffer) + i);
629 if (i + thisBucket->fThisRecordLength > howManyBytesOfStyleInfo) {
632 StyledInfoSummaryRecord isr = mkInfoSummaryRecordFromPortData (*thisBucket);
634 vector<StyledInfoSummaryRecord> list;
635 list.push_back (isr);
636 GetSinkStream ().ApplyStyle (offsetInText, offsetInText + isr.fLength, list);
638 offsetInText += isr.fLength;
639 i += thisBucket->fThisRecordLength;
641 if (i != howManyBytesOfStyleInfo) {
646#if qStroika_Frameworks_Led_SupportGDI
649 size_t nEmbeddings = InputStandardFromSrcStream_ULONG (GetSrcStream ());
650 if (nEmbeddings > totalTextLength) {
654 for (
size_t i = 0; i < nEmbeddings; ++i) {
655 size_t whereAt = InputStandardFromSrcStream_ULONG (GetSrcStream ());
656 size_t howManyBytes = InputStandardFromSrcStream_ULONG (GetSrcStream ());
658 size_t justBeforeEmbedding = GetSrcStream ().current_offset ();
660 Led_PrivateEmbeddingTag tag;
661 if (howManyBytes <
sizeof (tag)) {
664 if (GetSrcStream ().read (tag,
sizeof (tag)) !=
sizeof (tag)) {
667 SimpleEmbeddedObjectStyleMarker* embedding = InternalizeEmbedding (tag, howManyBytes -
sizeof (tag));
668 if (embedding == NULL) {
672 GetSrcStream ().seek_to (justBeforeEmbedding + howManyBytes);
675 GetSinkStream ().InsertEmbeddingForExistingSentinel (embedding, whereAt);
682 LedFormatMagicCookie endCookie;
683 if (GetSrcStream ().read (endCookie,
sizeof (endCookie)) !=
sizeof (endCookie)) {
686 if (memcmp (endCookie, cookie,
sizeof (endCookie)) != 0) {
693#if qStroika_Frameworks_Led_SupportGDI
694SimpleEmbeddedObjectStyleMarker* StyledTextIOReader_LedNativeFileFormat::InternalizeEmbedding (Led_PrivateEmbeddingTag tag,
size_t howManyBytes)
696 StackBuffer<char> dataBuf{Memory::eUninitialized, howManyBytes};
697 if (GetSrcStream ().read (dataBuf.data (), howManyBytes) != howManyBytes) {
701 const vector<EmbeddedObjectCreatorRegistry::Assoc>& types = EmbeddedObjectCreatorRegistry::Get ().GetAssocList ();
702 for (
size_t i = 0; i < types.size (); ++i) {
703 EmbeddedObjectCreatorRegistry::Assoc assoc = types[i];
704 if (memcmp (assoc.fEmbeddingTag, tag, sizeof (assoc.fEmbeddingTag)) == 0) {
706 return (assoc.fReadFromMemory) (tag, dataBuf.data (), howManyBytes);
709 return new StandardUnknownTypeStyleMarker{0, tag, dataBuf.data (), howManyBytes};
718StyledTextIOWriter_LedNativeFileFormat::StyledTextIOWriter_LedNativeFileFormat (SrcStream* srcStream, SinkStream* sinkStream)
719 : StyledTextIOWriter (srcStream, sinkStream)
723void StyledTextIOWriter_LedNativeFileFormat::Write ()
728void StyledTextIOWriter_LedNativeFileFormat::Write_Version6 ()
731 write (kLedPartFormatVersion_6_MagicNumber,
sizeof (kLedPartFormatVersion_6_MagicNumber));
733 size_t totalTextLength = GetSrcStream ().GetTotalTextLength ();
736 StackBuffer<Led_tChar> buf{Memory::eUninitialized, totalTextLength};
737 if (GetSrcStream ().readNTChars (buf.data (), totalTextLength) != totalTextLength) {
740 size_t nChars = totalTextLength *
sizeof (wchar_t);
741 StackBuffer<char> result{Memory::eUninitialized, nChars};
742#if qStroika_Foundation_Common_Platform_Windows
743 nChars =
CodeCvt<Led_tChar>{
static_cast<CodePage> (CP_ACP)}.Characters2Bytes (span{buf}, as_writable_bytes (span{result})).size ();
745 nChars =
CodeCvt<Led_tChar>{locale{}}.Characters2Bytes (span{buf}, as_writable_bytes (span{result})).size ();
748 uint32_t encodedTL = 0;
749 SizeTToBuf (nChars, &encodedTL);
750 write (&encodedTL,
sizeof (encodedTL));
752 write (result.data (), nChars);
757 vector<StyledInfoSummaryRecord> styleRunInfo = GetSrcStream ().GetStyleInfo (0, totalTextLength);
759 size_t howManyBytes = 0;
760 size_t styleRunInfoSectionCursor = GetSinkStream ().current_offset ();
761 OutputStandardToSinkStream_size_t_ (GetSinkStream (), howManyBytes);
763 size_t styleRuns = styleRunInfo.size ();
764 for (
size_t i = 0; i < styleRuns; ++i) {
765 PortableStyleRunData_Version6 data = mkPortableStyleRunData_Version6 (styleRunInfo[i]);
766 write (&data, data.fThisRecordLength);
771 size_t here = GetSinkStream ().current_offset ();
772 howManyBytes = here - (styleRunInfoSectionCursor + 4);
773 GetSinkStream ().seek_to (styleRunInfoSectionCursor);
774 OutputStandardToSinkStream_size_t_ (GetSinkStream (), howManyBytes);
775 GetSinkStream ().seek_to (here);
779#if qStroika_Frameworks_Led_SupportGDI
781 vector<SimpleEmbeddedObjectStyleMarker*> embeddings = GetSrcStream ().CollectAllEmbeddingMarkersInRange (0, totalTextLength);
782 OutputStandardToSinkStream_size_t_ (GetSinkStream (), embeddings.size ());
783 size_t markerPosOffset = GetSrcStream ().GetEmbeddingMarkerPosOffset ();
784 for (
size_t i = 0; i < embeddings.size (); ++i) {
785 SimpleEmbeddedObjectStyleMarker* embedding = embeddings[i];
787 size_t whereAt = embedding->GetStart () - markerPosOffset;
788 OutputStandardToSinkStream_size_t_ (GetSinkStream (), whereAt);
791 size_t howManyBytes = 0;
792 size_t embeddingSizeCursor = GetSinkStream ().current_offset ();
793 OutputStandardToSinkStream_size_t_ (GetSinkStream (), howManyBytes);
795 size_t embeddingCursor = GetSinkStream ().current_offset ();
796 write (embedding->GetTag (), sizeof (Led_PrivateEmbeddingTag));
797 ExternalizeEmbedding (embedding);
801 size_t here = GetSinkStream ().current_offset ();
802 howManyBytes = here - embeddingCursor;
803 GetSinkStream ().seek_to (embeddingSizeCursor);
804 OutputStandardToSinkStream_size_t_ (GetSinkStream (), howManyBytes);
805 GetSinkStream ().seek_to (here);
811 write (kLedPartFormatVersion_6_MagicNumber,
sizeof (kLedPartFormatVersion_6_MagicNumber));
814#if qStroika_Frameworks_Led_SupportGDI
815void StyledTextIOWriter_LedNativeFileFormat::ExternalizeEmbedding (SimpleEmbeddedObjectStyleMarker* embedding)
817 EmbeddingSinkStream embeddingSinkStream (GetSinkStream ());
818 embedding->Write (embeddingSinkStream);
CodeCvt unifies byte <-> unicode conversions, vaguely inspired by (and wraps) std::codecvt,...
nonvirtual size_t Bytes2Characters(span< const byte > from) const
convert span byte (external serialized format) parameters to characters (like std::codecvt<>::in () -...
Exception<> is a replacement (subclass) for any std c++ exception class (e.g. the default 'std::excep...
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...