4#include "Stroika/Frameworks/StroikaPreComp.h"
8#include "Stroika/Foundation/Characters/LineEndings.h"
12#include "Stroika/Frameworks/Led/Config.h"
14#if qStroika_Platform_Windows
20#include "Stroika/Frameworks/Led/Marker.h"
21#include "Stroika/Frameworks/Led/TextStore.h"
23#include "FlavorPackage.h"
30using namespace Stroika::Frameworks;
31using namespace Stroika::Frameworks::Led;
39TextStore* FlavorPackageExternalizer::PeekAtTextStore ()
const
50void FlavorPackageExternalizer::ExternalizeFlavors (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
52 ExternalizeFlavor_TEXT (flavorPackage, from, to);
61void FlavorPackageExternalizer::ExternalizeBestFlavor (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
63 ExternalizeFlavor_TEXT (flavorPackage, from, to);
74void FlavorPackageExternalizer::ExternalizeFlavor_TEXT (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
79 Require (end <= GetTextStore ().GetEnd ());
80 Require (start <= end);
81 size_t length = end - start;
82#if qStroika_Platform_Windows
89 GetTextStore ().CopyOut (start, length, buf2.data ());
90#if qStroika_Platform_Windows
91 length = Characters::NLToNative<Led_tChar> (buf2.data (), length, buf.data (), 2 * length + 1);
99 length = Led_SkrunchOutSpecialChars (buf.data (), length,
'\0');
101#if qStroika_Platform_Windows
105 flavorPackage.AddFlavorData (kTEXTClipFormat, length *
sizeof (Led_tChar), buf.data ());
113TextStore* FlavorPackageInternalizer::PeekAtTextStore ()
const
118bool FlavorPackageInternalizer::InternalizeBestFlavor (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
120 if (InternalizeFlavor_FILE (flavorPackage, from, to)) {
123 else if (InternalizeFlavor_TEXT (flavorPackage, from, to)) {
129bool FlavorPackageInternalizer::InternalizeFlavor_TEXT (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
131 if (flavorPackage.GetFlavorAvailable_TEXT ()) {
132 size_t length = flavorPackage.
GetFlavorSize (kTEXTClipFormat);
133 Led_ClipFormat textFormat = kTEXTClipFormat;
138 length = flavorPackage.ReadFlavorData (textFormat, length, buf.data ());
140 Led_tChar* buffp =
reinterpret_cast<Led_tChar*
> (
static_cast<char*
> (buf));
141 size_t nTChars = length /
sizeof (Led_tChar);
142#if qStroika_Platform_Windows
147 nTChars = min (nTChars, Led_tStrlen (buffp));
153 Require (start <= end);
155 nTChars = Characters::NormalizeTextToNL<Led_tChar> (buffp, nTChars, buffp, nTChars);
156 GetTextStore ().Replace (start, end, buffp, nTChars);
164bool FlavorPackageInternalizer::InternalizeFlavor_FILE (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
167 if (flavorPackage.GetFlavorAvailable (kFILEClipFormat)) {
168 size_t fileSpecBufferLength = flavorPackage.
GetFlavorSize (kFILEClipFormat);
170 fileSpecBufferLength = flavorPackage.ReadFlavorData (kFILEClipFormat, fileSpecBufferLength, fileSpecBuffer.data ());
173#if qStroika_Platform_Windows
174 TCHAR realFileName[_MAX_PATH + 1];
176 HDROP hdrop = (HDROP)::GlobalAlloc (GMEM_FIXED, fileSpecBufferLength);
178 (void)::memcpy (hdrop, fileSpecBuffer.data (), fileSpecBufferLength);
179 size_t nChars = ::DragQueryFile (hdrop, 0,
nullptr, 0);
180 Verify (::DragQueryFile (hdrop, 0, realFileName,
static_cast<UINT
> (nChars + 1)) == nChars);
181 ::GlobalFree (hdrop);
183 Led_ClipFormat suggestedClipFormat = kBadClipFormat;
185 char realFileName[1000];
186 realFileName[0] =
'\0';
187 Led_ClipFormat suggestedClipFormat = kBadClipFormat;
190 return InternalizeFlavor_FILEData (realFileName, &suggestedClipFormat, nullopt, from, to);
197bool FlavorPackageInternalizer::InternalizeFlavor_FILEData (filesystem::path fileName, Led_ClipFormat* suggestedClipFormat,
198 optional<CodePage> suggestedCodePage,
size_t from,
size_t to)
200 Memory::BLOB b = IO::FileSystem::FileInputStream::New (filesystem::path (fileName)).ReadAll ();
201 const byte* fileBuf = b.
begin ();
202 size_t fileLen = b.
size ();
204 InternalizeFlavor_FILEGuessFormatsFromName (fileName, suggestedClipFormat, suggestedCodePage);
208 InternalizeFlavor_FILEGuessFormatsFromStartOfData (suggestedClipFormat, suggestedCodePage, fileBuf, fileBuf + fileLen);
213 return InternalizeFlavor_FILEDataRawBytes (suggestedClipFormat, suggestedCodePage, from, to, fileBuf, fileLen);
216void FlavorPackageInternalizer::InternalizeFlavor_FILEGuessFormatsFromName (filesystem::path fileName, Led_ClipFormat* suggestedClipFormat,
217 [[maybe_unused]] optional<CodePage> suggestedCodePage)
219#if qStroika_Platform_Windows
220 if (suggestedClipFormat !=
nullptr and *suggestedClipFormat == kBadClipFormat) {
221 TCHAR drive[_MAX_DRIVE];
223 TCHAR fname[_MAX_FNAME];
225 ::_tsplitpath_s (fileName.native ().c_str (), drive, dir, fname, ext);
226 if (::_tcsicmp (ext, Led_SDK_TCHAROF (
".txt")) == 0) {
227 *suggestedClipFormat = kTEXTClipFormat;
233void FlavorPackageInternalizer::InternalizeFlavor_FILEGuessFormatsFromStartOfData (Led_ClipFormat* suggestedClipFormat,
234 [[maybe_unused]] optional<CodePage> suggestedCodePage,
235 const byte* ,
const byte*
238 if (suggestedClipFormat !=
nullptr) {
239 if (*suggestedClipFormat == kBadClipFormat) {
247bool FlavorPackageInternalizer::InternalizeFlavor_FILEDataRawBytes (Led_ClipFormat* suggestedClipFormat, optional<CodePage> suggestedCodePage,
248 size_t from,
size_t to,
const void* rawBytes,
size_t nRawBytes)
257 Led_ClipFormat cf = (suggestedClipFormat ==
nullptr or *suggestedClipFormat == kBadClipFormat) ? kTEXTClipFormat : *suggestedClipFormat;
258 if (cf != kTEXTClipFormat) {
260 package.AddFlavorData (cf, nRawBytes, rawBytes);
261 if (InternalizeBestFlavor (package, from, to)) {
273 span<const byte> rawByteSpan{
reinterpret_cast<const byte*
> (rawBytes), nRawBytes};
274#if qStroika_Platform_Windows
279 size_t outCharCnt = converter.ComputeTargetCharacterBufferSize (rawByteSpan);
281 auto charsRead = converter.Bytes2Characters (&rawByteSpan, span{fileData2}).size ();
282 charsRead = Characters::NormalizeTextToNL<Led_tChar> (fileData2.data (), charsRead, fileData2.data (), charsRead);
283 GetTextStore ().Replace (from, to, fileData2.data (), charsRead);
287#if qStroika_Frameworks_Led_SupportClipboard
294bool ReaderClipboardFlavorPackage::GetFlavorAvailable (Led_ClipFormat clipFormat)
const
296 return Led_ClipboardObjectAcquire::FormatAvailable (clipFormat);
299size_t ReaderClipboardFlavorPackage::GetFlavorSize (Led_ClipFormat clipFormat)
const
301 Led_ClipboardObjectAcquire clip (clipFormat);
302 if (clip.GoodClip ()) {
303 return clip.GetDataLength ();
310size_t ReaderClipboardFlavorPackage::ReadFlavorData (Led_ClipFormat clipFormat,
size_t bufSize,
void* buf)
const
312 Led_ClipboardObjectAcquire clip{clipFormat};
313 if (clip.GoodClip ()) {
314 size_t copyNBytes = min (bufSize, clip.GetDataLength ());
315 (void)::memcpy (buf, clip.GetData (), copyNBytes);
316 Ensure (copyNBytes <= bufSize);
325#if qStroika_Frameworks_Led_SupportClipboard
331void WriterClipboardFlavorPackage::AddFlavorData (Led_ClipFormat clipFormat,
size_t bufSize,
const void* buf)
333#if qStroika_Platform_Windows
336 HANDLE h = ::GlobalAlloc (GHND | GMEM_MOVEABLE, bufSize);
339 char* clipBuf = (
char*)::GlobalLock (h);
340 if (clipBuf ==
nullptr) {
344 memcpy (clipBuf, buf, bufSize);
347 if (::SetClipboardData (clipFormat, h) ==
nullptr) {
348 DWORD err = ::GetLastError ();
360ReadWriteMemBufferPackage::ReadWriteMemBufferPackage ()
373 fPackages.reserve (1);
376ReadWriteMemBufferPackage::~ReadWriteMemBufferPackage ()
380bool ReadWriteMemBufferPackage::GetFlavorAvailable (Led_ClipFormat clipFormat)
const
382 for (
size_t i = 0; i < fPackages.size (); i++) {
383 if (fPackages[i].fFormat == clipFormat) {
392 for (
size_t i = 0; i < fPackages.size (); i++) {
393 if (fPackages[i].fFormat == clipFormat) {
394 return fPackages[i].fData.size ();
401size_t ReadWriteMemBufferPackage::ReadFlavorData (Led_ClipFormat clipFormat,
size_t bufSize,
void* buf)
const
403 for (
size_t i = 0; i < fPackages.size (); i++) {
404 if (fPackages[i].fFormat == clipFormat) {
405 size_t copyNBytes = min (bufSize, fPackages[i].fData.size ());
406 memcpy (buf, Traversal::Iterator2Pointer (fPackages[i].fData.begin ()), copyNBytes);
407 Ensure (copyNBytes <= bufSize);
415void ReadWriteMemBufferPackage::AddFlavorData (Led_ClipFormat clipFormat,
size_t bufSize,
const void* buf)
418 pr.fFormat = clipFormat;
419 const char* cb =
reinterpret_cast<const char*
> (buf);
420 pr.fData = vector<char> (cb, cb + bufSize);
421 fPackages.push_back (pr);
CodeCvt unifies byte <-> unicode conversions, vaguely inspired by (and wraps) std::codecvt,...
nonvirtual const byte * begin() const
nonvirtual size_t size() const
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...
virtual size_t GetFlavorSize(Led_ClipFormat clipFormat) const override
virtual size_t GetFlavorSize(Led_ClipFormat clipFormat) const =0
void Throw(T &&e2Throw)
like the builtin C++ 'throw', but stamps in the current Activity context and does helpful,...
void ThrowIfNull(const Private_::ConstVoidStar &p, const HRESULT &hr)
Template specialization for ThrowIfNull (), for thing being thrown HRESULT - really throw HRESULTErro...