ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
fmtvarious.cpp
1namespace alib::format {
2
3void FFormat_CallerInfo(const Box& box, const String& formatSpec, NumberFormat&, AString& target) {
4 FMTCallerInfo fmtCI{*box.Unbox<CallerInfo*>() };
5 fmtCI.Format( formatSpec.IsNotEmpty() ? formatSpec
6 #if ALIB_CAMP
7 : BASECAMP.GetResource("FMTCI")
8 #else
9 : A_CHAR( "[@ sf:sl from ''ya'' by ''ta'']")
10 #endif
11 , target );
12}
13
15 lang::CurrentData targetData ) const {
16 if ( targetData == lang::CurrentData::Clear )
17 target.Reset();
18
19 // this ensures that target is not nulled, as all other appends are NC-versions
20 target._("");
21
22 while ( format.IsNotEmpty() ) {
23 // read n equal characters
24 int n= 1;
25 character c= format.ConsumeChar();
26 while ( format.ConsumeChar(c) )
27 ++n;
28
29 switch (c) {
30 case '\'': // single quotes
31 {
32 // one or more pairs of single quotes?
33 if ( n > 1 ) {
34 int pairs= n / 2;
35 target.InsertChars<NC>( '\'', pairs );
36 n-= (pairs * 2);
37 }
38
39 // one single quote?
40 if ( n == 1 ) {
41 // search end
42 integer end= format.IndexOf( '\'' );
43 if ( end < 1 ) {
44 ALIB_WARNING( "ALIB", "Format Error: Missing single Quote" )
45 target << "Format Error: Missing closing single quote character <'>" ;
46 return target;
47 }
48
49 target._<NC>( format, 0, end );
50 format.ConsumeChars<NC>( end + 1 );
51 }
52
53 } break;
54
55 // source information
56 case 's':
57 {
58 if ( n == 1 ) {
59 if ( format.ConsumeChar('f') ) {
60 if( ci.File ) target._<NC>( ci.File );
61 else target._<NC>( "<NULL>" );
62 break;
63 }
64 if ( format.ConsumeChar('l') ) {
65 if( ci.File )
66 target._<NC>( ci.Line );
67 break;
68 }
69 if ( format.ConsumeChar('m') ) {
70 if( ci.File )
71 target._<NC>( ci.Func );
72 break;
73 } }
74 // otherwise: copy what was in
75 target.InsertChars<NC>( c, n );
76 break;
77 }
78
79 #if !ALIB_SINGLE_THREADED
80 // thread information
81 case 't':
82 {
83 if ( n == 1 ) {
84 Thread* thread= Thread::Get(ci.ThreadID);
85
86 // alib thread name
87 if ( format.ConsumeChar('n') ) {
88 target._<NC>( thread ? thread->GetName()
89 #if ALIB_CAMP
90 : BASECAMP.GetResource("FMTCINT")
91 #else
92 : A_CHAR( "<None>" )
93 #endif
94 );
95 break;
96 }
97 // alib thread id
98 if ( format.ConsumeChar('i') ) {
99 if ( thread ) target._<NC>( thread->GetID() );
100 #if ALIB_CAMP
101 else target._<NC>( BASECAMP.GetResource("FMTCINR") );
102 #else
103 else target._<NC>( A_CHAR("<Null>") );
104 #endif
105 break;
106 }
107
108 // native thread id
109 if ( format.ConsumeChar('c') ) {
110 if constexpr ( sizeof(std::thread::id) == sizeof(uint16_t) ) {
111 uint16_t nativeID= 0;
112 std::memcpy(&nativeID, &ci.ThreadID, 2);
113 target._<NC>("0x")._<NC>(Hex(nativeID, 4));
114 }
115 if constexpr ( sizeof(std::thread::id) == sizeof(uint32_t) ) {
116 uint32_t nativeID= 0;
117 std::memcpy(&nativeID, &ci.ThreadID, 4);
118 target._<NC>("0x")._<NC>(Hex(nativeID, 8));
119 }
120 if constexpr ( sizeof(std::thread::id) == sizeof(uint64_t) ) {
121 uint64_t nativeID= 0;
122 std::memcpy(&nativeID, &ci.ThreadID, 8);
123 target._<NC>("0x")._<NC>(Hex(nativeID, 16));
124 }
125
126 break;
127 }
128
129 // all/auto
130 if ( format.ConsumeChar('a') ) {
131 target._<NC>( ci.ThreadID );
132 break;
133 } }
134 // otherwise: copy what was in
135 target.InsertChars<NC>( c, n );
136 break;
137 }
138 #endif // !ALIB_SINGLE_THREADED
139
140 // type information
141 case 'y':
142 {
143 if ( n == 1 ) {
144 // full type name
145 if ( format.ConsumeChar('f') ) {
146 #if !ALIB_DEBUG
147 target._<NC>(
148 #if ALIB_CAMP
149 BASECAMP.GetResource("FMTCINY")
150 #else
151 A_CHAR( "<None>" )
152 #endif
153 );
154 #else
155 if (!ci.TypeInfo) target._<NC>(
156 #if ALIB_CAMP
157 BASECAMP.GetResource("FMTCINY")
158 #else
159 A_CHAR( "<None>" )
160 #endif
161 );
162 else target << lang::DbgTypeDemangler(*ci.TypeInfo).Get();
163 #endif
164 break;
165 }
166
167 // stripped type name
168 if ( format.ConsumeChar('n') ) {
169 #if !ALIB_DEBUG
170 target._<NC>(
171 #if ALIB_CAMP
172 BASECAMP.GetResource("FMTCINY")
173 #else
174 A_CHAR( "<None>" )
175 #endif
176 );
177 #else
178 if (!ci.TypeInfo)
179 target._<NC>(
180 #if ALIB_CAMP
181 BASECAMP.GetResource("FMTCINY")
182 #else
183 A_CHAR( "<None>" )
184 #endif
185 );
186 else {
187 NString2K typeName(*ci.TypeInfo);
188 target._<NC>( typeName );
189 }
190 #endif
191 break;
192 }
193
194 // automatic type together with shortened function name
195 if ( format.ConsumeChar('a') ) {
196 #if !ALIB_DEBUG
197 target._<NC>( ci.Func )._<NC>("()");
198 #else
199 if (ci.TypeInfo)
200 target._<NC>( *ci.TypeInfo )._<NC>("::");
201 target._<NC>( ci.Func )._<NC>("()");
202 #endif
203 break;
204 }
205
206 }
207 // otherwise: copy what was in
208 target.InsertChars<NC>( c, n );
209 break;
210 }
211
212 default: // otherwise: copy what was in
213 target.InsertChars<NC>( c, n );
214 break;
215 }
216
217 }
218
219 return target;
220}
221
222
223//##################################################################################################
224// FFormat_DateTime
225//##################################################################################################
226#if !DOXYGEN
227DOX_MARKER([DOX_BOXING_IFORMAT_DATETIME])
228void FFormat_DateTime( const Box& box, const String& formatSpec, NumberFormat&, AString& target ) {
229 strings::util::CalendarDateTime tct( box.Unbox<DateTime>() );
230 tct.Format( formatSpec.IsNotEmpty() ? formatSpec
231 #if ALIB_CAMP
232 : BASECAMP.GetResource("FMTDT"),
233 #else
234 : A_CHAR( "yyyy-MM-dd HH:mm:ss" ),
235 #endif
236 target );
237}
238DOX_MARKER([DOX_BOXING_IFORMAT_DATETIME])
239#endif
240
241
242//##################################################################################################
243// format::ByteSize
244//##################################################################################################
245#if !DOXYGEN
246
248
249namespace {
250
251double convertTo(uinteger val, ByteSizeUnits unit) {
252 double v= double(val);
253 int loopEnd;
254 double divisor;
255 if( unit < ByteSizeUnits::IEC_END) {
256 loopEnd= int(unit);
257 divisor= double(1024);
258 } else {
259 loopEnd= int(unit - ByteSizeUnits::SI);
260 divisor= double(1000);
261 }
262
263 for (int i = 0; i < loopEnd; ++i)
264 v/= divisor;
265 return v;
266}
267
269std::pair<double,ByteSizeUnits> getMagnitude( uinteger val, uinteger byteLimit, uinteger factor) {
271 if( val < byteLimit )
272 return std::make_pair( double(val), ByteSizeUnits(0) );
273
274 while(val != 0) {
275 ++unit;
276 if( val < byteLimit * factor)
277 return std::make_pair( double(val) / double(factor), unit );
278
279 val/= factor;
280} }
282} // namespace alib::format[::anonymous]
283
284void FormatByteSize(AString& target, uinteger val, uint16_t magnitudeThreshold,
285 char unitSeparator, ByteSizeUnits unit, NumberFormat& nf) {
286 target.EnsureRemainingCapacity(128);
287
288 auto magnitude= (unit == ByteSizeUnits::IEC) ? getMagnitude(val, magnitudeThreshold, 1024ull)
289 : getMagnitude(val, magnitudeThreshold, 1000ull);
290
291 if( magnitude.second == ByteSizeUnits::IEC )
292 target << Dec( val, nullptr );
293 else
294 target.SetLength( strings::detail::WriteFloat( magnitude.first,
295 target.VBuffer(), target.Length(), 0, nf) );
296
297 if( unitSeparator )
298 target << unitSeparator;
299 target << (magnitude.second + unit);
300} // FormatByteSize()
301
302std::pair<double, ByteSizeUnits> ByteSizeIEC::GetMagnitude() {
303 auto result= getMagnitude( Value, MagnitudeThreshold, 1024 );
304 result.second+= ByteSizeUnits::IEC;
305 return result;
306}
307
308std::pair<double,ByteSizeUnits> ByteSizeSI::GetMagnitude() {
309 auto result= getMagnitude( Value, MagnitudeThreshold, 1000 );
310 result.second+= ByteSizeUnits::SI;
311 return result;
312}
313
314double ByteSizeIEC::ConvertTo(ByteSizeUnits unit) { return convertTo(Value, unit); };
315double ByteSizeSI ::ConvertTo(ByteSizeUnits unit) { return convertTo(Value, unit); };
316
317
318} namespace alib::strings {
319
320void AppendableTraits< format::ByteSizeSI, character, lang::HeapAllocator>::operator()( AString& target, const format::ByteSizeSI src )
321{
322 format::FormatByteSize( target, src.Value, src.MagnitudeThreshold, src.UnitSeparator,
323 format::ByteSizeUnits::SI, * format::BYTESIZE_NUMBER_FORMAT );
324}
325void AppendableTraits< format::ByteSizeIEC, character, lang::HeapAllocator>::operator()( AString& target, const format::ByteSizeIEC src )
326{
327 format::FormatByteSize( target, src.Value, src.MagnitudeThreshold, src.UnitSeparator,
328 format::ByteSizeUnits::IEC, * format::BYTESIZE_NUMBER_FORMAT );
329}
330
331} // namespace [alib::strings]
332
333ALIB_BOXING_VTABLE_DEFINE( alib::format::ByteSizeIEC , vt_lang_format_bytesize_iec )
334ALIB_BOXING_VTABLE_DEFINE( alib::format::ByteSizeSI , vt_lang_format_bytesize_si )
335ALIB_BOXING_VTABLE_DEFINE( alib::format::ByteSizeUnits , vt_lang_format_bytesize_units )
336
337
338#endif //!DOXYGEN
#define A_CHAR(STR)
#define ALIB_WARNING(domain,...)
#define ALIB_POP_ALLOWANCE
#define ALIB_CAMP
#define ALIB_ALLOW_NOTHING_RETURNED
#define ALIB_BOXING_VTABLE_DEFINE(TMapped, Identifier)
const String & GetResource(const NString &name)
TAString & _(const TAppendable &src)
static Thread * Get(std::thread::id nativeID)
Definition thread.cpp:253
void typeName(const detail::VTable *vtable, AString &result)
NumberFormat * BYTESIZE_NUMBER_FORMAT
void FFormat_DateTime(const Box &self, const String &formatSpec, NumberFormat &nf, AString &target)
void FFormat_CallerInfo(const Box &self, const String &formatSpec, NumberFormat &nf, AString &target)
void FormatByteSize(AString &target, uinteger byteSize, uint16_t magnitudeThreshold, char unitSeparator, ByteSizeUnits unit, NumberFormat &nf)
@ Clear
Chooses to clear existing data.
integer WriteFloat(double value, TChar *buffer, integer idx, int minWidth, const TNumberFormat< TChar > &nf)
strings::TNumberFormat< character > NumberFormat
Type alias in namespace #"%alib".
threads::Thread Thread
Type alias in namespace #"%alib".
Definition thread.hpp:387
lang::integer integer
Type alias in namespace #"%alib".
Definition integers.hpp:149
boxing::Box Box
Type alias in namespace #"%alib".
Definition box.hpp:1128
strings::TString< character > String
Type alias in namespace #"%alib".
Definition string.hpp:2165
strings::TDec< character > Dec
Type alias in namespace #"%alib".
Definition format.hpp:540
strings::TSubstring< character > Substring
Type alias in namespace #"%alib".
NLocalString< 2048 > NString2K
Type alias name for #"TLocalString;TLocalString<nchar,2048>".
camp::Basecamp BASECAMP
The singleton instance of ALib Camp class #"Basecamp".
Definition basecamp.cpp:2
lang::CallerInfo CallerInfo
Type alias in namespace #"%alib".
strings::THex< character > Hex
Type alias in namespace #"%alib".
Definition format.hpp:549
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace #"%alib".
characters::character character
Type alias in namespace #"%alib".
lang::uinteger uinteger
Type alias in namespace #"%alib".
Definition integers.hpp:152
time::DateTime DateTime
Type alias in namespace #"%alib".
Definition datetime.hpp:188
double ConvertTo(ByteSizeUnits unit)
std::pair< double, ByteSizeUnits > GetMagnitude()
std::pair< double, ByteSizeUnits > GetMagnitude()
const lang::CallerInfo & ci
The wrapped caller information.
AString & Format(Substring format, AString &target, lang::CurrentData targetData=lang::CurrentData::Keep) const