5#include "Stroika/Frameworks/StroikaPreComp.h"
9#include "Stroika/Foundation/Characters/LineEndings.h"
12#include "Stroika/Frameworks/Led/StyledTextIO/StyledTextIO_MIMETextEnriched.h"
16using namespace Stroika::Frameworks;
17using namespace Stroika::Frameworks::Led;
18using namespace Stroika::Frameworks::Led::StyledTextIO;
28StyledTextIOReader_MIMETextEnriched::StyledTextIOReader_MIMETextEnriched (SrcStream* srcStream, SinkStream* sinkStream)
29 : StyledTextIOReader (srcStream, sinkStream)
39void StyledTextIOReader_MIMETextEnriched::Read ()
42 ScanFor (
"Content-type:");
44 ScanFor (
"text/enriched");
54 size_t lastOffset = GetSrcStream ().current_offset ();
55 bool gotCmdStart = ScanFor (
"<");
57 size_t currentOffset = GetSrcStream ().current_offset ();
58 if (currentOffset == lastOffset and not gotCmdStart) {
70 size_t len = currentOffset - lastOffset;
71 StackBuffer<Led_tChar> buf{Memory::eUninitialized, len};
72 GetSrcStream ().seek_to (lastOffset);
73 GetSrcStream ().read (buf.data (), len);
74 len = Characters::NormalizeTextToNL<Led_tChar> (buf.data (), len, buf.data (), len);
75 if (fNoFillMode == 0) {
79 StackBuffer<Led_tChar> buf2{Memory::eUninitialized, len};
81 for (
size_t i = 0; i < len; ++i) {
82 Led_tChar prevChar = (i == 0) ?
'\0' : buf[i - 1];
83 Led_tChar nextChar = (i == len - 1) ?
'\0' : buf[i + 1];
85 if (buf[i] ==
'\n' and nextChar !=
'\n') {
89 if (isspace (prevChar) and isspace (buf[i])) {
94 GetSinkStream ().AppendText (buf2.data (), i2, &fontSpec);
97 GetSinkStream ().AppendText (buf.data (), len, &fontSpec);
105 GetSrcStream ().seek_to (currentOffset + 1);
106 if (GetSrcStream ().read (&c, 1) != 0 and c ==
'<') {
109 GetSinkStream ().AppendText (&wc, 1, &fontSpec);
113 GetSrcStream ().seek_to (currentOffset);
116 size_t len = GetSrcStream ().current_offset () - currentOffset;
117 StackBuffer<char> cmdBuf{Memory::eUninitialized, len + 1};
118 GetSrcStream ().seek_to (currentOffset);
119 GetSrcStream ().read (cmdBuf.data (), len);
121 if (strcmp (cmdBuf.data (),
"<bold>") == 0) {
124 else if (strcmp (cmdBuf.data (),
"</bold>") == 0 and fBoldMode > 0) {
127 else if (strcmp (cmdBuf.data (),
"<italic>") == 0) {
130 else if (strcmp (cmdBuf.data (),
"</italic>") == 0 and fItalicMode > 0) {
133 else if (strcmp (cmdBuf.data (),
"<underline>") == 0) {
136 else if (strcmp (cmdBuf.data (),
"</underline>") == 0 and fUnderlineMode > 0) {
139 else if (strcmp (cmdBuf.data (),
"<fixed>") == 0) {
142 else if (strcmp (cmdBuf.data (),
"</fixed>") == 0 and fFixedWidthMode > 0) {
145 else if ((strcmp (cmdBuf.data (),
"<smaller>") == 0) or (strcmp (cmdBuf.data (),
"</bigger>") == 0)) {
146 fFontSizeAdjust -= 2;
148 else if ((strcmp (cmdBuf.data (),
"</smaller>") == 0) or (strcmp (cmdBuf.data (),
"<bigger>") == 0)) {
149 fFontSizeAdjust += 2;
151 else if (strcmp (cmdBuf.data (),
"<nofill>") == 0) {
154 else if (strcmp (cmdBuf.data (),
"</nofill>") == 0 and fNoFillMode > 0) {
157 else if (strcmp (cmdBuf.data (),
"<param>") == 0) {
158 ScanFor (
"</param>");
163 GetSinkStream ().EndOfBuffer ();
166bool StyledTextIOReader_MIMETextEnriched::QuickLookAppearsToBeRightFormat ()
168 SrcStreamSeekSaver savePos (GetSrcStream ());
170 if (LookingAt (
"Content-type:")) {
172 return LookingAt (
"text/enriched");
181void StyledTextIOReader_MIMETextEnriched::SkipWhitespace ()
184 while (GetSrcStream ().read (&c, 1) != 0) {
185 if (not isascii (c) or not isspace (c)) {
187 GetSrcStream ().seek_to (GetSrcStream ().current_offset () - 1);
193void StyledTextIOReader_MIMETextEnriched::SkipOneLine ()
196 while (GetSrcStream ().read (&c, 1) != 0) {
199 GetSrcStream ().read (&nextChar, 1);
200 if (nextChar !=
'\n') {
202 GetSrcStream ().seek_to (GetSrcStream ().current_offset () - 1);
212bool StyledTextIOReader_MIMETextEnriched::ScanFor (
const char* matchMe,
bool ignoreCase)
217 while (GetSrcStream ().read (&c, 1) != 0) {
218 if (Led_CasedCharsEqual (c, matchMe[0], ignoreCase)) {
219 size_t savedOffset = GetSrcStream ().current_offset ();
220 if (LookingAt (&matchMe[1], ignoreCase)) {
224 GetSrcStream ().seek_to (savedOffset);
231bool StyledTextIOReader_MIMETextEnriched::LookingAt (
const char* matchMe,
bool ignoreCase)
234 size_t nBytesToMatch = ::strlen (matchMe);
236 if (nBytesToMatch == 0) {
241 if (GetSrcStream ().read (&c, 1) != 0) {
242 if (Led_CasedCharsEqual (c, matchMe[0], ignoreCase)) {
243 size_t savedOffset = GetSrcStream ().current_offset ();
244 if (LookingAt (&matchMe[1], ignoreCase)) {
248 GetSrcStream ().seek_to (savedOffset);
256FontSpecification StyledTextIOReader_MIMETextEnriched::GetAdjustedCurrentFontSpec ()
const
260 fsp.SetStyle_Bold (
true);
262 if (fItalicMode > 0) {
263 fsp.SetStyle_Italic (
true);
265 if (fUnderlineMode > 0) {
266 fsp.SetStyle_Underline (
true);
268 if (fFixedWidthMode > 0) {
273 int resultSize = fsp.GetPointSize () + fFontSizeAdjust;
274 if (resultSize < 5) {
277 if (resultSize > 64) {
280 fsp.SetPointSize (
static_cast<uint8_t
> (resultSize));
#define RequireNotNull(p)
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...