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