ALib C++ Library
by
Library Version:
2402 R1
Documentation generated by
Loading...
Searching...
No Matches
home
dev
A-Worx
ALib
src
alib
lang
format
formatterjavastyle.hpp
Go to the documentation of this file.
1
/** ************************************************************************************************
2
* \file
3
* This header file is part of sub-namespace #alib::lang::format of module \alib_basecamp of
4
* the \aliblong.
5
*
6
* \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
7
* Published under \ref mainpage_license "Boost Software License".
8
**************************************************************************************************/
9
#ifndef HPP_ALIB_LANG_FORMAT_FORMATTER_JAVASTYLE
10
#define HPP_ALIB_LANG_FORMAT_FORMATTER_JAVASTYLE 1
11
12
#if !defined (HPP_ALIB_LANG_FORMAT_FORMATTER_STD)
13
#include "
alib/lang/format/formatterstdimpl.hpp
"
14
#endif
15
16
namespace
alib::lang::format
{
17
18
/** ************************************************************************************************
19
* Implements a \alib{lang::format;Formatter} according to the
20
* \https{formatting standards of the Java language,docs.oracle.com/javase/8/docs/api/java/util/Formatter.html}.
21
*
22
* \note
23
* Inherited, public fields of parent class \b FormatterStdImpl provide important possibilities
24
* for changing the formatting behavior of instances of this class. Therefore, do not forget
25
* to consult the \ref alib::lang::format::FormatterStdImpl "parent classes documentation".
26
*
27
* In general, the original specification is covered quite well. The differences and specialties
28
* are:
29
* - In deviation of the Java specification, after creation, a formatter in this implementation
30
* does not produce locale aware output. Instead, number formatting is set to "computational",
31
* hence the decimal point separator is <c>'.'</c> and the grouping character <c>','</c>.
32
* As the syntax specification does not provide a feature to switch between standard and locale
33
* setting, the corresponding fields of #AlternativeNumberFormat are not used with this formatter.
34
* Instead, to enable localized output, method
35
* \alib{strings;TNumberFormat::SetFromLocale;NumberFormat::SetFromLocale}
36
* has to be invoked on field
37
* \alib{lang::format;FormatterStdImpl::DefaultNumberFormat;FormatterStdImpl::DefaultNumberFormat}.
38
* Alternatively, attributes of this object may be changed manually or by other means to reflect
39
* a desired locale.
40
* - Hexadecimal floating point output (conversion type \c 'a' and \c 'A') is not supported.
41
* - Flag <c>'('</c>, used to write negative numbers in round brackets, is not supported.
42
* - Addressing the previous argument index using \c '%<' is already allowed with the first
43
* placeholder.
44
* This Chooses the first argument. (In Java a \b MissingFormatArgumentException would be thrown.)
45
* - Flag \c '^' is an extension to the standard and denotes
46
* center-alignment - just like \c '-' in the standard denotes left-alignment.
47
* Right-alignment is the default.
48
*
49
*<p>
50
* - <b>Floating point values:</b>
51
* - If standard field type \c 's' is given together with a precision, the field is cut, even if
52
* it cuts the number somewhere. (This is just a warning and same behavior as in original
53
* specification.)
54
* - For lower case floating point format types (\c 'f', \c 'g' and \c 'e'), the values specified
55
* in attributes \b %ExponentSeparator, \b %NANLiteral and \b %INFLiteral of object
56
* \alib{lang::format;FormatterStdImpl::AlternativeNumberFormat;FormatterStdImpl::AlternativeNumberFormat}
57
* are used. For upper case types (\c 'G' and \c 'E'), the corresponding attributes in
58
* \alib{lang::format;FormatterStdImpl::DefaultNumberFormat;FormatterStdImpl::DefaultNumberFormat} apply.
59
* - Fixed point format (\c 'f' ) is not supported to use arbitrary length.
60
* See class \alib{strings;TNumberFormat;NumberFormat} for the limits.
61
* Due to this limitation, the default number of fractional digits is not set with type \c 'f',
62
* while in Java it is set to \c 6. This is to allow higher numbers up to \c 1.e13 to be printed
63
* in non-scientific format
64
* - When both, a \p{width} and a \p{precision} is given, then the \p{precision} determines the
65
* fractional part, even if the type is \b 'g' or \b 'G'. This is different than specified with
66
* Java formatter, which uses \p{precision} as the overall width in case of types
67
* \b 'g' or \b 'G'.
68
*
69
*<p>
70
* - <b>Hexadecimal and Octal Numbers:</b>
71
* - Hexadecimal and octal output is <b>cut in size</b> (!) when a field width is given that
72
* is smaller than the resulting amount of digits of the number arguments provided.
73
* \note This implies that a value written might not be equal to the value given.
74
* This is not a bug but a design decision. The rationale behind this is that with this
75
* behavior, there is no need to mask lower digits when passing the arguments to the
76
* format invocation. In other words, the formatter "assumes" that the given field width
77
* indicates that only a corresponding number of lower digits are of interest.
78
*
79
* - If no width is given and the argument contains a boxed pointer, then the platform-dependent
80
* full output width of pointer types is used.
81
* - The number <b>grouping option</b> (<c>','</c>) can also be used with binary, hexadecimal
82
* and octal output.
83
* The types support different grouping separators for nibbles, bytes, 16-bit and 32-bit words.
84
* Changing the separator symbols, is not possible with the format fields of the format strings
85
* (if it was, this would become very incompatible to Java standards). Changes have to be made
86
* prior to the format operation by modifying field
87
* \alib{lang::format;FormatterStdImpl::AlternativeNumberFormat;FormatterStdImpl::AlternativeNumberFormat}
88
* which is provided through parent class \b %FormatterStdImpl.
89
*
90
* - Alternative form (\c '#') adds prefixes as specified in members
91
* - \alib{strings;TNumberFormat::HexLiteralPrefix;HexLiteralPrefix} and
92
* - \alib{strings;TNumberFormat::OctLiteralPrefix;OctLiteralPrefix}.
93
*
94
* For upper case formats, those are taken from field
95
* \alib{lang::format;FormatterStdImpl::DefaultNumberFormat;FormatterStdImpl::DefaultNumberFormat},
96
* for lower case formats from
97
* \alib{lang::format;FormatterStdImpl::AlternativeNumberFormat;FormatterStdImpl::AlternativeNumberFormat}.
98
* All defaults may be changed by the user.
99
*
100
*<p>
101
* - <b>Time and Date:</b>
102
* - In this C++ version of the class, boxed values of type \alib{time;DateTime} are applicable
103
* to conversion type \c 't'.
104
* - The following time conversion suffix characters are supported:
105
* \c 'H', \c 'k', \c 'I', \c 'l', \c 'M', \c 'S', \c 'B', \c 'b', \c 'h', \c 'A', \c 'a',
106
* \c 'Y', \c 'y', \c 'm', \c 'd', \c 'e', \c 'R', \c 'T', \c 'D' and \c 'F'
107
* - The following time conversion suffix characters are \b not supported:
108
* \c 'L', \c 'N', \c 'p', \c 'z', \c 'Z', \c 's', \c 'Q', \c 'C', \c 'j', \c 'r' and \c 'c'.
109
*
110
\I{################################################################################################}
111
* # Reference Documentation #
112
* @throws <b>alib::lang::format::FMTExceptions</b>
113
* - \alib{lang::format::FMTExceptions;ArgumentIndexIs0}
114
* - \alib{lang::format::FMTExceptions;ArgumentIndexOutOfBounds}
115
* - \alib{lang::format::FMTExceptions;IncompatibleTypeCode}
116
* - \alib{lang::format::FMTExceptions;NegativeValuesInBracketsNotSupported}
117
* - \alib{lang::format::FMTExceptions;MissingPrecisionValueJS}
118
* - \alib{lang::format::FMTExceptions;HexadecimalFloatFormatNotSupported}
119
* - \alib{lang::format::FMTExceptions;NoAlternateFormOfConversion}
120
* - \alib{lang::format::FMTExceptions;NoPrecisionWithConversion}
121
* - \alib{lang::format::FMTExceptions;UnknownDateTimeConversionSuffix}
122
* - \alib{lang::format::FMTExceptions;UnknownConversionJS}
123
*
124
**************************************************************************************************/
125
class
FormatterJavaStyle
:
public
FormatterStdImpl
126
{
127
// #############################################################################################
128
// Protected fields
129
// #############################################################################################
130
protected
:
131
/**
132
* Set of extended placeholder attributes, needed for this type of formatter in
133
* addition to parent's \alib{lang::format::FormatterStdImpl;PlaceholderAttributes}.
134
*/
135
struct
PlaceholderAttributesJS
136
{
137
/** The character after conversion type 't'/'T'. */
138
character
DateTime
;
139
140
/** The value read from the precision field.
141
* This is set to \c -1 in #resetPlaceholder. */
142
int8_t
Precision
;
143
144
/** The default precision if not given.
145
* This is set to \c 6 in #resetPlaceholder, but is changed when specified. */
146
int8_t
DefaultPrecision
;
147
148
/** Convert to upper case. */
149
bool
ConversionUpper
;
150
151
/** Alternate form given ('#'). */
152
bool
AlternateForm
;
153
};
154
155
/** The extended placeholder attributes. */
156
PlaceholderAttributesJS
placeholderJS
;
157
158
159
// #############################################################################################
160
// Constructor/Destructor
161
// #############################################################################################
162
public
:
163
/** ****************************************************************************************
164
* Constructs this formatter.
165
* Inherited field #DefaultNumberFormat is initialized to meet the formatting defaults of
166
* Java.
167
******************************************************************************************/
168
ALIB_API
169
FormatterJavaStyle
();
170
171
/** ****************************************************************************************
172
* Clones and returns a copy of this formatter.
173
*
174
* If the formatter attached to field
175
* \alib{lang::format;Formatter::Next} is of type \b %FormatterStdImpl, then that
176
* formatter is copied as well.
177
*
178
* @returns An object of type \b %FormatterPythonStyle and with the same custom settings
179
* than this.
180
******************************************************************************************/
181
ALIB_API
virtual
182
FormatterStdImpl
*
Clone
()
override
;
183
184
185
186
// #############################################################################################
187
// Implementation of FormatterStdImpl interface
188
// #############################################################################################
189
protected
:
190
191
/** ****************************************************************************************
192
* Invokes parent implementation and then applies some changes to reflect what is defined as
193
* default in the Java string format specification.
194
******************************************************************************************/
195
ALIB_API
196
virtual
void
resetPlaceholder
()
override
;
197
198
/** ****************************************************************************************
199
* Searches for \c '\%' which is not '%%' or '%n'.
200
*
201
* @return The index found, -1 if not found.
202
******************************************************************************************/
203
ALIB_API
204
virtual
integer
findPlaceholder
()
override
;
205
206
/** ****************************************************************************************
207
* Parses placeholder field in Java syntax. The portion \p{format_spec} is not set as this
208
* is not supported by the syntax.
209
*
210
* @return \c true on success, \c false on errors.
211
******************************************************************************************/
212
ALIB_API
213
virtual
bool
parsePlaceholder
()
override
;
214
215
/** ****************************************************************************************
216
* Does nothing. Java does not support custom format specifications.
217
*
218
* @return \c true to indicate success.
219
******************************************************************************************/
220
virtual
bool
parseStdFormatSpec
()
override
221
{
222
return
true
;
223
}
224
225
/** ****************************************************************************************
226
* Implementation of abstract method \alib{lang::format;FormatterStdImpl::writeStringPortion}.<br>
227
* Replaces \c "%%" with \c '\%' and \c "%n" with ascii \c 0x0a. In addition applies
228
* \alib{strings;TFormat::Escape;Format::Escape} on \p{target} which replaces
229
* standard codes like \c "\\n", \c "\\r" or \c "\\t" with corresponding ascii codes.
230
* (The latter is an extension to the standard behavior of Java formatter.)
231
*
232
* @param length The number of characters to write.
233
******************************************************************************************/
234
ALIB_API
235
virtual
void
writeStringPortion
(
integer
length )
override
;
236
237
/** ****************************************************************************************
238
* All that this formatter does with this overridden method is to convert strings to
239
* upper case.
240
*
241
* @param startIdx The index of the start of the field written in #targetString.
242
* \c -1 indicates pre-phase.
243
* @param target The target string, only if different from field #targetString, which
244
* indicates intermediate phase.
245
* @return \c false, if the placeholder should be skipped (nothing is written for it).
246
* \c true otherwise.
247
******************************************************************************************/
248
ALIB_API
249
virtual
bool
preAndPostProcess
(
integer
startIdx,
250
AString
* target )
override
;
251
252
/** ****************************************************************************************
253
* Makes some attribute adjustments and invokes standard implementation
254
* @return \c true if OK, \c false if replacement should be aborted.
255
******************************************************************************************/
256
ALIB_API
257
virtual
bool
checkStdFieldAgainstArgument
()
override
;
258
};
259
260
}
// namespace [alib::lang::format]
261
262
#endif
// HPP_ALIB_LANG_FORMAT_FORMATTER_JAVASTYLE
alib::lang::format::FormatterJavaStyle
Definition
formatterjavastyle.hpp:126
alib::lang::format::FormatterJavaStyle::findPlaceholder
virtual ALIB_API integer findPlaceholder() override
Definition
formatterjavastyle.cpp:85
alib::lang::format::FormatterJavaStyle::preAndPostProcess
virtual ALIB_API bool preAndPostProcess(integer startIdx, AString *target) override
Definition
formatterjavastyle.cpp:407
alib::lang::format::FormatterJavaStyle::checkStdFieldAgainstArgument
virtual ALIB_API bool checkStdFieldAgainstArgument() override
Definition
formatterjavastyle.cpp:415
alib::lang::format::FormatterJavaStyle::placeholderJS
PlaceholderAttributesJS placeholderJS
Definition
formatterjavastyle.hpp:156
alib::lang::format::FormatterJavaStyle::Clone
virtual ALIB_API FormatterStdImpl * Clone() override
Definition
formatterjavastyle.cpp:50
alib::lang::format::FormatterJavaStyle::parsePlaceholder
virtual ALIB_API bool parsePlaceholder() override
Definition
formatterjavastyle.cpp:158
alib::lang::format::FormatterJavaStyle::writeStringPortion
virtual ALIB_API void writeStringPortion(integer length) override
Definition
formatterjavastyle.cpp:99
alib::lang::format::FormatterJavaStyle::FormatterJavaStyle
ALIB_API FormatterJavaStyle()
Definition
formatterjavastyle.cpp:27
alib::lang::format::FormatterJavaStyle::parseStdFormatSpec
virtual bool parseStdFormatSpec() override
Definition
formatterjavastyle.hpp:220
alib::lang::format::FormatterJavaStyle::resetPlaceholder
virtual ALIB_API void resetPlaceholder() override
Definition
formatterjavastyle.cpp:66
alib::lang::format::FormatterStdImpl
Definition
formatterstdimpl.hpp:130
alib::strings::TAString< character >
formatterstdimpl.hpp
ALIB_API
#define ALIB_API
Definition
alib.hpp:538
alib::lang::format
Definition
basecamp.cpp:139
alib::lang::integer
platform_specific integer
Definition
integers.hpp:50
alib::character
characters::character character
Type alias in namespace alib.
Definition
characters.hpp:665
alib::lang::format::FormatterJavaStyle::PlaceholderAttributesJS
Definition
formatterjavastyle.hpp:136
alib::lang::format::FormatterJavaStyle::PlaceholderAttributesJS::DefaultPrecision
int8_t DefaultPrecision
Definition
formatterjavastyle.hpp:146
alib::lang::format::FormatterJavaStyle::PlaceholderAttributesJS::AlternateForm
bool AlternateForm
Definition
formatterjavastyle.hpp:152
alib::lang::format::FormatterJavaStyle::PlaceholderAttributesJS::DateTime
character DateTime
Definition
formatterjavastyle.hpp:138
alib::lang::format::FormatterJavaStyle::PlaceholderAttributesJS::ConversionUpper
bool ConversionUpper
Definition
formatterjavastyle.hpp:149
alib::lang::format::FormatterJavaStyle::PlaceholderAttributesJS::Precision
int8_t Precision
Definition
formatterjavastyle.hpp:142