Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Support.inl
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
6
7namespace Stroika::Frameworks::Led {
8
9 /*
10 ********************************************************************************
11 ************************************* Led_tStrlen ******************************
12 ********************************************************************************
13 */
14 inline size_t Led_tStrlen (const Led_tChar* s)
15 {
17 return ::wcslen (s);
18 }
19
20 inline int Led_tStrCmp (const Led_tChar* l, const Led_tChar* r)
21 {
24 return ::wcscmp (l, r);
25 }
26
27 inline int Led_tStrnCmp (const Led_tChar* l, const Led_tChar* r, size_t n)
28 {
31 return ::wcsncmp (l, r, n);
32 }
33
34 inline const Led_tChar* Led_tStrChr (const Led_tChar* s, Led_tChar c)
35 {
37 return ::wcschr (s, c);
38 }
39 inline Led_tString Led_WideString2tString (const wstring& s)
40 {
41 return s;
42 }
43 inline wstring Led_tString2WideString (const Led_tString& s)
44 {
45 return s;
46 }
47
48#if qTargetPlatformSDKUseswchar_t
49 inline SDKString Led_tString2SDKString (const Led_tString& s)
50 {
51 return Foundation::Characters::String{s}.AsSDKString ();
52 }
53#endif
54
55 inline Led_tString Led_SDKString2tString (const SDKString& s)
56 {
58 }
59
60 inline unsigned short Led_ByteSwapFromMac (unsigned short src)
61 {
62 return Common::EndianConverter (src, Common::Endian::eBig, Common::GetEndianness ());
63 }
64 inline short Led_ByteSwapFromMac (short src)
65 {
66 return Common::EndianConverter (src, Common::Endian::eBig, Common::GetEndianness ());
67 }
68
69 /*
70 ********************************************************************************
71 ************************** Led_ByteSwapFromWindows *****************************
72 ********************************************************************************
73 */
74 inline unsigned short Led_ByteSwapFromWindows (unsigned short src)
75 {
76 return Common::EndianConverter (src, Common::Endian::eLittle, Common::GetEndianness ());
77 }
78 inline short Led_ByteSwapFromWindows (short src)
79 {
80 return Common::EndianConverter (src, Common::Endian::eLittle, Common::GetEndianness ());
81 }
82 inline unsigned long Led_ByteSwapFromWindows (unsigned long src)
83 {
84 return Common::EndianConverter (src, Common::Endian::eLittle, Common::GetEndianness ());
85 }
86 inline long Led_ByteSwapFromWindows (long src)
87 {
88 return Common::EndianConverter (src, Common::Endian::eLittle, Common::GetEndianness ());
89 }
90
91 inline void UInt16ToBuf (uint16_t u, uint16_t* realBuf)
92 {
93 unsigned char* buf = (unsigned char*)realBuf;
94 buf[0] = (unsigned char)(u >> 8);
95 buf[1] = (unsigned char)u;
96 }
97 inline uint16_t BufToUInt16 (const uint16_t* realBuf)
98 {
99 const unsigned char* buf = (const unsigned char*)realBuf;
100 return (uint16_t)((((uint16_t)buf[0]) << 8) + (uint16_t)buf[1]);
101 }
102 inline void UInt32ToBuf (uint32_t ul, uint32_t* realBuf)
103 {
104 unsigned short* buf = (unsigned short*)realBuf;
105 UInt16ToBuf ((unsigned short)(ul >> 16), buf);
106 UInt16ToBuf ((unsigned short)(ul), buf + 1);
107 }
108 inline uint32_t BufToUInt32 (const uint32_t* buf)
109 {
110 unsigned short* bufAsShortArray = (unsigned short*)buf;
111 return (((unsigned long)BufToUInt16 (bufAsShortArray)) << 16) + BufToUInt16 (bufAsShortArray + 1);
112 }
113
114 inline void SizeTToBuf (size_t ul, uint32_t* realBuf)
115 {
117 if (ul > numeric_limits<uint32_t>::max ()) {
118 Throw (range_error ("size_t wont fit in 32-bits"));
119 }
120 UInt32ToBuf (static_cast<uint32_t> (ul), realBuf);
121 }
122 inline size_t BufToSizeT (const uint32_t* buf)
123 {
125 uint32_t r = BufToUInt32 (buf);
126 return static_cast<size_t> (r);
127 }
128
129 template <typename ARRAY_CONTAINER, class T>
130 size_t IndexOf (const ARRAY_CONTAINER& array, T item)
131 {
132 for (auto i = array.begin (); i != array.end (); ++i) {
133 if (*i == item) {
134 return (i - array.begin ());
135 }
136 }
137 return kBadIndex;
138 }
139
140 inline Led_tChar* Led_NextChar (Led_tChar* fromHere)
141 {
142 AssertNotNull (fromHere);
143 return fromHere + 1;
144 }
145 inline const Led_tChar* Led_NextChar (const Led_tChar* fromHere)
146 {
147 AssertNotNull (fromHere);
148 return fromHere + 1;
149 }
150 /*
151
152 FIXUP COMMENT - FROM EMAIL - AND ABOUT PREV_CHAR IMPLEMENTATION...
153 Bytes can be:
154
155 (1) Ascii (0-0x7f)
156 (2) FirstByte of DoubleByte Char
157 (c >= 0x81 and c <= 0x9f) or (c >= 0xe0 and c <= 0xfc)
158 (3) SecondByte of DoubleByte Char
159 (c >= 0x40 and c <= 0x7e) or (c >= 0x80 and c <= 0xfc)
160
161 (NB: This clasification counts on the fact that we filter out all bad SJIS)
162
163 note that class of ASCII bytes and the class of FirstBytes does not overlap, but the class of SecondBytes DOES overlap with both others.
164
165 Our task in scanning backward is to be able to UNIQUELY tell by looking at a byte - WITHOUT KNOWING ITS CONTEXT BEFOREHAND - if it is an ASCII byte, FirstByte, or a SecondByte.
166
167 This analysis makes our job a little easier. Most bytes just by looking at them - can be immediately clasified.
168
169 0x00-0x3f ==> ASCII
170 0x40-0x7e ==> ASCII or SecondByte
171 0x7f ==> ASCII
172 0x80 ==> SecondByte
173 0x81-0x9f ==> FirstByte or SecondByte
174 0xa0-0xdf ==> SecondByte
175 0xe0-0xfc ==> FirstByte or SecondByte
176
177 * This Algoritm assumes that mbyte character sets have at most two bytes per character. This
178 * is true for SJIS - but I'm not posative it is always true - LGP 950216.
179
180 */
181 inline const Led_tChar* Led_PreviousChar ([[maybe_unused]] const Led_tChar* startOfString, const Led_tChar* fromHere)
182 {
183 AssertNotNull (startOfString);
184 AssertNotNull (fromHere);
185 Assert (startOfString < fromHere); // Must be room for previous character to exist!
186 return fromHere - 1; // address arithmatic does the magic for wide characters
187 }
188 inline Led_tChar* Led_PreviousChar (Led_tChar* startOfString, Led_tChar* fromHere)
189 {
190 // We could duplicate all the code above - but its simpler to just cast and invoke
191 // the above impemenation...
192 return ((Led_tChar*)Led_PreviousChar ((const Led_tChar*)startOfString, (const Led_tChar*)fromHere));
193 }
194
195 inline bool ValidateTextForCharsetConformance (const Led_tChar*, size_t)
196 {
197 return true; // probably should do SOME validation here for other character sets - at least
198 // for plain ascii!!! - LGP 950212
199 }
200
201 inline unsigned Led_DigitCharToNumber (char digitChar)
202 {
203 // assume '0'..'9' are consecutive - true for ascii at least - LGP 961015
204
205 // require input is valid decimal digit
206 Require (digitChar >= '0');
207 Require (digitChar <= '9');
208 return (digitChar - '0');
209 }
210 inline char Led_NumberToDigitChar (unsigned digitValue)
211 {
212 // assume '0'..'9' are consecutive - true for ascii at least - LGP 961015
213
214 // require input is valid decimal digit value
215 Require (digitValue <= 9);
216 return static_cast<char> (digitValue + '0');
217 }
218
219#if qStroika_Frameworks_Led_SupportClipboard
220 /*
221 ********************************************************************************
222 ************************** Led_ClipboardObjectAcquire **************************
223 ********************************************************************************
224 */
225 inline bool Led_ClipboardObjectAcquire::FormatAvailable (Led_ClipFormat clipType)
226 {
227#if qStroika_Foundation_Common_Platform_Windows
228 return (!!::IsClipboardFormatAvailable (clipType));
229#elif qStroika_FeatureSupported_XWindows
230 // Wild guess - no good answer yet - LGP 2003-05-06
231 return true;
232#endif
233 }
234 inline bool Led_ClipboardObjectAcquire::FormatAvailable_TEXT ()
235 {
236 if (FormatAvailable (kTEXTClipFormat)) {
237 return true;
238 }
239 return false;
240 }
241 inline Led_ClipboardObjectAcquire::~Led_ClipboardObjectAcquire ()
242 {
243// For windows me must unlock, but not delete
244#if qStroika_Foundation_Common_Platform_Windows
245 if (fLockedData != nullptr) {
246 ::GlobalUnlock (fLockedData);
247 }
248#endif
249 }
250 inline bool Led_ClipboardObjectAcquire::GoodClip () const
251 {
252#if qStroika_Foundation_Common_Platform_Windows
253 return (fOSClipHandle != nullptr and fLockedData != nullptr);
254#else
255 return false; // X-TMP-HACK-LGP991213
256#endif
257 }
258 inline void* Led_ClipboardObjectAcquire::GetData () const
259 {
260 Assert (GoodClip ());
261 return (fLockedData);
262 }
263 inline size_t Led_ClipboardObjectAcquire::GetDataLength () const
264 {
265 Assert (GoodClip ());
266#if qStroika_Foundation_Common_Platform_Windows
267 return (::GlobalSize (fOSClipHandle));
268#endif
269 }
270#endif
271
272 /*
273 ********************************************************************************
274 ******************************* Led_CasedStringsEqual **************************
275 ********************************************************************************
276 */
277 namespace {
278 template <typename LHS_STRINGISH, typename RHS_STRINGISH>
279 bool Led_CasedStringsEqual_ (const LHS_STRINGISH& lhs, const RHS_STRINGISH& rhs, bool ignoreCase)
280 {
281 if (lhs.length () != rhs.length ()) {
282 return false;
283 }
284 for (size_t i = 0; i < lhs.length (); ++i) {
285 if (not Led_CasedCharsEqual (lhs[i], rhs[i], ignoreCase)) {
286 return false;
287 }
288 }
289 return true;
290 }
291 }
292 inline bool Led_CasedStringsEqual (const string& lhs, const string& rhs, bool ignoreCase)
293 {
294 return Led_CasedStringsEqual_ (lhs, rhs, ignoreCase);
295 }
296 inline bool Led_CasedStringsEqual (const string_view& lhs, const string_view& rhs, bool ignoreCase)
297 {
298 return Led_CasedStringsEqual_ (lhs, rhs, ignoreCase);
299 }
300 inline bool Led_CasedStringsEqual (const string_view& lhs, const string& rhs, bool ignoreCase)
301 {
302 return Led_CasedStringsEqual_ (lhs, rhs, ignoreCase);
303 }
304 inline bool Led_CasedStringsEqual (const string& lhs, const string_view& rhs, bool ignoreCase)
305 {
306 return Led_CasedStringsEqual_ (lhs, rhs, ignoreCase);
307 }
308 inline bool Led_CasedStringsEqual (const char* lhs, const string& rhs, bool ignoreCase)
309 {
310 return Led_CasedStringsEqual_ (string_view{lhs}, rhs, ignoreCase);
311 }
312 inline bool Led_CasedStringsEqual (const string& lhs, const char* rhs, bool ignoreCase)
313 {
314 return Led_CasedStringsEqual_ (lhs, string_view{rhs}, ignoreCase);
315 }
316 inline bool Led_CasedStringsEqual (const char* lhs, const string_view& rhs, bool ignoreCase)
317 {
318 return Led_CasedStringsEqual_ (string_view{lhs}, rhs, ignoreCase);
319 }
320 inline bool Led_CasedStringsEqual (const string_view& lhs, const char* rhs, bool ignoreCase)
321 {
322 return Led_CasedStringsEqual_ (lhs, string_view{rhs}, ignoreCase);
323 }
324 inline bool Led_CasedStringsEqual (const char* lhs, const char* rhs, bool ignoreCase)
325 {
326 return Led_CasedStringsEqual_ (string_view{lhs}, string_view{rhs}, ignoreCase);
327 }
328}
329CompileTimeFlagChecker_HEADER (Stroika::Frameworks::Led, qStroika_Frameworks_Led_ProvideIMESupport, qStroika_Frameworks_Led_ProvideIMESupport);
#define AssertNotNull(p)
Definition Assertions.h:333
#define RequireNotNull(p)
Definition Assertions.h:347
#define CompileTimeFlagChecker_HEADER(NS_PREFIX, NAME, VALUE)
CompileTimeFlagChecker_HEADER () will generate a LINK ERROR if you ever compile a header with one val...
static String FromSDKString(const SDKChar *from)
Definition String.inl:447
basic_string< SDKChar > SDKString
Definition SDKString.h:38
constexpr Endian GetEndianness()
returns native (std::endian::native) Endianness flag. Can be complicated (mixed, etc)....
Definition Endian.inl:25
constexpr T EndianConverter(T value, Endian from, Endian to)
Definition Endian.inl:60
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...
Definition Throw.inl:43