Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Characters/CString/Utilities.h
Go to the documentation of this file.
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Characters_CString_Utilities_h_
5#define _Stroika_Foundation_Characters_CString_Utilities_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
9#include <cstdarg>
10#include <cstring>
11#include <string>
12
14#include "Stroika/Foundation/Common/Common.h"
15
16/**
17 * \file
18 *
19 * Legacy "C_String" string utilities.
20 *
21 * TODO:
22 * @todo Consider losing StringToFloat() or making it look/act like String/Format version.
23 *
24 * @todo Many of these CString utilities should be removed? Review each one and its use. See if
25 * Stroika-string is just better? Maybe leave - but review.
26 *
27 * @todo DOCUMENT BEHAVIOR OF STRING2INT() for bad strings. What does it do?
28 * AND SIMILARPT FOR hexString2Int. And for both - probably rewrite to use strtoul/strtol etc
29 *
30 * @todo Same changes to HexString2Int() as we did with String2Int()
31 *
32 * @todo Consdier if we should have variants of these funtions taking a locale, or
33 * always using C/currnet locale. For the most part - I find it best to use the C locale.
34 * But DOCUMENT in all cases!!! And maybe implement variants...
35 */
36
37namespace Stroika::Foundation::Characters::CString {
38
39 /**
40 * \brief Measure the length of the argument c-string (NUL-terminated string).
41 *
42 * Measure the length of the argument c-string (NUL-terminated string). Overloaded version of strlen/wcslen.
43 *
44 * Only implemented for char/wchar_t. Reason for this is so code using old-style C++ strings can leverage overloading!
45 */
46 template <IPossibleCharacterRepresentation T>
47 size_t Length (const T* p);
48
49 /**
50 * \brief strcmp or wsccmp() as appropriate == 0
51 */
52 template <typename T>
53 bool Equals (const T* lhs, const T* rhs);
54 template <>
55 bool Equals (const char8_t* lhs, const char8_t* rhs);
56 template <>
57 bool Equals (const char* lhs, const char* rhs);
58 template <>
59 bool Equals (const char16_t* lhs, const char16_t* rhs);
60 template <>
61 bool Equals (const char32_t* lhs, const char32_t* rhs);
62 template <>
63 bool Equals (const wchar_t* lhs, const wchar_t* rhs);
64
65 /**
66 * \brief Safe variant of strncpy() - which always NUL-terminates the string
67 *
68 * Copy the C-string pointed to by 'src' to the location pointed to by 'dest'. 'nEltsInDest' -
69 * as the name suggests - is the number of elements in the array pointed to by 'dest' - not
70 * the max string length for 'dest.
71 *
72 * This function will always nul-terminate, and it is illegal to call it with a value
73 * of zero for nEltsInDest.
74 *
75 * This is basically like strcpy/strncpy, except with better logic for nul-termination.
76 *
77 * Note - the arguments are not in exactly the same order as strncpy() - with the length of the buffer for the first string before
78 * the second string.
79 *
80 * \par Example Usage
81 * \code
82 * char urlBuf[1024];
83 * CString::Copy (urlBuf, NEltsOf (urlBuf), url.c_str ());
84 * \endcode
85 */
86 template <typename T>
87 void Copy (T* dest, size_t nEltsInDest, const T* src);
88 template <>
89 void Copy (char* dest, size_t nEltsInDest, const char* src);
90 template <>
91 void Copy (wchar_t* dest, size_t nEltsInDest, const wchar_t* src);
92
93 /**
94 * \brief Safe variant of strncat() - which always NUL-terminates the string. DIFFERNT arguments however, so not safe direct substitution.
95 *
96 * Note - the arguments are not in exactly the same order as strncpy() - with the length of the buffer for the first string before
97 * the second string.
98 */
99 template <typename T>
100 void Cat (T* dest, size_t nEltsInDest, const T* src2Append);
101 template <>
102 void Cat (char* dest, size_t nEltsInDest, const char* src2Append);
103 template <>
104 void Cat (wchar_t* dest, size_t nEltsInDest, const wchar_t* src2Append);
105
106 /*
107 * Format is the Stroika wrapper on sprintf().
108 * The main differences between sprintf () and Format are:
109 * (1) No need for buffer management. ANY sized buffer will be automatically allocated internally and returned as a
110 * string (eventually probably using Stroika::String - but for now std::string).
111 *
112 * (2) This version of format has a SUBTLE - but important difference from std::c++ / sprintf() in the interpretation of
113 * %s format strings in Format(const wchar_t*). The interpretation of Format (const char*,...) is the same
114 * but for Format (const wchar_t* format, ...) - %s is assumed to match a const wchar_t* string in the variable
115 * argument list.
116 *
117 * This deviation from the c++ standard (technically not a deviation because Stroika::Foundation::Characters::Format() isn't
118 * covered by the stdc++ ;-)) - is because of two reasons:
119 * a) Microsoft has this interpretation.
120 * b) Its a BETTER interpretation (allowing for stuff like (Format (SDKSTR("time%s"), count==1? SDKSTR (""): SDKSTR ("s"));
121 */
122 string FormatV (const char* format, va_list argsList);
123 u8string FormatV (const char8_t* format, va_list argsList);
124 wstring FormatV (const wchar_t* format, va_list argsList);
125 string Format (const char* format, ...);
126 u8string Format (const char8_t* format, ...);
127 wstring Format (const wchar_t* format, ...);
128
129 /**
130 * @see String::LimitLength()
131 */
132 string LimitLength (const string& str, size_t maxLen, bool keepLeft = true);
133 wstring LimitLength (const wstring& str, size_t maxLen, bool keepLeft = true);
134
135 /**
136 * @see String::LTrim()
137 * @see String::RTrim()
138 * @see String::Trim()
139 */
140 template <typename TCHAR>
141 basic_string<TCHAR> LTrim (const basic_string<TCHAR>& text);
142 template <typename TCHAR>
143 basic_string<TCHAR> RTrim (const basic_string<TCHAR>& text);
144 template <typename TCHAR>
145 basic_string<TCHAR> Trim (const basic_string<TCHAR>& text);
146
147 /**
148 * This could be generalized to accomodate TRIM/merge with TRIM, but it sometimes used to trim other
149 * characters (like trailing CRLF, or trailing '.').
150 */
151 string StripTrailingCharIfAny (const string& s, char c);
152 wstring StripTrailingCharIfAny (const wstring& s, wchar_t c);
153
154 /**
155 * Convert the given hex-format string to an unsigned integer.
156 * String2Int will return 0 if no valid parse, and UINT_MAX on overflow.
157 *
158 * @see strtoul(), or @see wcstol (). This is a simple wrapper on strtoul() or wcstoul().
159 * strtoul() etc are more flexible. This is merely meant to be an often convenient wrapper.
160 * Use strtoul etc directly to see if the string parsed properly.
161 */
162 unsigned int HexString2Int (const string& s);
163 unsigned int HexString2Int (const wchar_t* s);
164 unsigned int HexString2Int (const wstring& s);
165
166 /**
167 * Convert the given decimal-format integral string to any integer type
168 * ( e.g. signed char, unsigned short int, long long int, uint32_t etc).
169 *
170 * String2Int will return 0 if no valid parse, and numeric_limits<T>::min on underflow,
171 * numeric_limits<T>::max on overflow.
172 * @todo consider if this is unwise - it seems we ought to throw? Or have a variant
173 * perhaps that does no throw?
174 *
175 * CONSIDER!
176 *
177 * @see strtoll(), or @see wcstoll (). This is a simple wrapper on strtoll() / wcstoll ().
178 * strtoll() is more flexible. This is merely meant to be an often convenient wrapper.
179 * Use strtoll etc directly to see if the string parsed properly.
180 */
181 template <typename T>
182 T String2Int (const string& s);
183 template <typename T>
184 T String2Int (const wchar_t* s);
185 template <typename T>
186 T String2Int (const wstring& s);
187
188}
189
190/*
191 ********************************************************************************
192 ***************************** Implementation Details ***************************
193 ********************************************************************************
194 */
195#include "Utilities.inl"
196
197#endif /*_Stroika_Foundation_Characters_CString_Utilities_h_*/
void Cat(T *dest, size_t nEltsInDest, const T *src2Append)
Safe variant of strncat() - which always NUL-terminates the string. DIFFERNT arguments however,...
string LimitLength(const string &str, size_t maxLen, bool keepLeft=true)
basic_string< TCHAR > LTrim(const basic_string< TCHAR > &text)
size_t Length(const T *p)
Measure the length of the argument c-string (NUL-terminated string).
void Copy(T *dest, size_t nEltsInDest, const T *src)
Safe variant of strncpy() - which always NUL-terminates the string.
bool Equals(const T *lhs, const T *rhs)
strcmp or wsccmp() as appropriate == 0