ALib C++ Library
Library Version: 2510 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 \ref mainpage_license "Boost Software License".
7//==================================================================================================
8namespace alib::format {
9
10//==================================================================================================
11/// Implements a \alib{format;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 \ref 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/// setting, the corresponding fields of #AlternativeNumberFormat are not used with this formatter.
26/// Instead, to enable localized output, method
27/// \alib{strings;TNumberFormat::SetFromLocale;NumberFormat::SetFromLocale}
28/// has to be invoked on field
29/// \alib{format;FormatterStdImpl::DefaultNumberFormat;FormatterStdImpl::DefaultNumberFormat}.
30/// Alternatively, attributes of this object may be changed manually or by other means to reflect
31/// a desired locale.
32/// - Hexadecimal floating point output (conversion type \c 'a' and \c 'A') is not supported.
33/// - Flag <c>'('</c>, used to write negative numbers in round brackets, is not supported.
34/// - Addressing the previous argument index using \c '%<' is already allowed with the first
35/// placeholder.
36/// This Chooses the first argument. (In Java a \b MissingFormatArgumentException would be thrown.)
37/// - Flag \c '^' is an extension to the standard and denotes
38/// center-alignment - just like \c '-' in the standard denotes left-alignment.
39/// Right-alignment is the default.
40///
41///<p>
42/// - <b>Floating point values:</b>
43/// - If standard field type \c 's' is given together with a precision, the field is cut, even if
44/// it cuts the number somewhere. (This is just a warning and same behavior as in original
45/// specification.)
46/// - For lower case floating point format types (\c 'f', \c 'g' and \c 'e'), the values specified
47/// in attributes \b %ExponentSeparator, \b %NANLiteral and \b %INFLiteral of object
48/// \alib{format;FormatterStdImpl::AlternativeNumberFormat;FormatterStdImpl::AlternativeNumberFormat}
49/// are used. For upper case types (\c 'G' and \c 'E'), the corresponding attributes in
50/// \alib{format;FormatterStdImpl::DefaultNumberFormat;FormatterStdImpl::DefaultNumberFormat} apply.
51/// - Fixed point format (\c 'f' ) is not supported to use arbitrary length.
52/// See class \alib{strings;TNumberFormat;NumberFormat} for the limits.
53/// Due to this limitation, the default number of fractional digits is not set with type \c 'f',
54/// while in Java it is set to \c 6. This is to allow higher numbers up to \c 1.e13 to be printed
55/// in non-scientific format
56/// - When both, a \p{width} and a \p{precision} is given, then the \p{precision} determines the
57/// fractional part, even if the type is \b 'g' or \b 'G'. This is different from the
58/// corresponding specification of Java formatter, which uses \p{precision} as the overall
59/// width in case of types \b 'g' or \b 'G'.
60///
61///<p>
62/// - <b>Hexadecimal and Octal Numbers:</b>
63/// - Hexadecimal and octal output is <b>cut in size</b> (!) when a field width is given that
64/// is smaller than the resulting amount of digits of the number arguments provided.
65/// \note This implies that a value written might not be equal to the value given.
66/// This is not a bug but a design decision. The rationale behind this is that with this
67/// behavior, there is no need to mask lower digits when passing the arguments to the
68/// format invocation. In other words, the formatter "assumes" that the given field width
69/// indicates that only a corresponding number of lower digits are of 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 field
79/// \alib{format;FormatterStdImpl::AlternativeNumberFormat;FormatterStdImpl::AlternativeNumberFormat}
80/// which is provided through parent class \b %FormatterStdImpl.
81///
82/// - Alternative form (\c '#') adds prefixes as specified in members
83/// - \alib{strings;TNumberFormat::HexLiteralPrefix;HexLiteralPrefix} and
84/// - \alib{strings;TNumberFormat::OctLiteralPrefix;OctLiteralPrefix}.
85///
86/// For upper case formats, those are taken from field
87/// \alib{format;FormatterStdImpl::DefaultNumberFormat;FormatterStdImpl::DefaultNumberFormat},
88/// for lower case formats from
89/// \alib{format;FormatterStdImpl::AlternativeNumberFormat;FormatterStdImpl::AlternativeNumberFormat}.
90/// All defaults may be changed by the user.
91///
92///<p>
93/// - <b>Time and Date:</b>
94/// - In this C++ version of the class, boxed values of type \alib{time;DateTime} are applicable
95/// to conversion type \c 't'.
96/// - The following time conversion suffix characters are supported:
97/// \c 'H', \c 'k', \c 'I', \c 'l', \c 'M', \c 'S', \c 'B', \c 'b', \c 'h', \c 'A', \c 'a',
98/// \c 'Y', \c 'y', \c 'm', \c 'd', \c 'e', \c 'R', \c 'T', \c 'D' and \c 'F'
99/// - The following time conversion suffix characters are \b not supported:
100/// \c 'L', \c 'N', \c 'p', \c 'z', \c 'Z', \c 's', \c 'Q', \c 'C', \c 'j', \c 'r' and \c 'c'.
101///
102///\I{##############################################################################################}
103/// # Reference Documentation #
104/// @throws <b>alib::format::FMTExceptions</b>
105/// - \alib{format::FMTExceptions;ArgumentIndexIs0}
106/// - \alib{format::FMTExceptions;ArgumentIndexOutOfBounds}
107/// - \alib{format::FMTExceptions;IncompatibleTypeCode}
108/// - \alib{format::FMTExceptions;NegativeValuesInBracketsNotSupported}
109/// - \alib{format::FMTExceptions;MissingPrecisionValueJS}
110/// - \alib{format::FMTExceptions;HexadecimalFloatFormatNotSupported}
111/// - \alib{format::FMTExceptions;NoAlternateFormOfConversion}
112/// - \alib{format::FMTExceptions;NoPrecisionWithConversion}
113/// - \alib{format::FMTExceptions;UnknownDateTimeConversionSuffix}
114/// - \alib{format::FMTExceptions;UnknownConversionJS}
115///
116//==================================================================================================
118{
119 // #############################################################################################
120 // Protected fields
121 // #############################################################################################
122 protected:
123 /// Set of extended placeholder attributes, needed for this type of formatter in
124 /// addition to parent's \alib{format::FormatterStdImpl;PlaceholderAttributes}.
126 {
127 /// The character after conversion type 't'/'T'.
129
130 /// The value read from the precision field.
131 /// This is set to \c -1 in #resetPlaceholder.
132 int8_t Precision;
133
134 /// The default precision if not given.
135 /// This is set to \c 6 in #resetPlaceholder, but is changed when specified.
137
138 /// Convert to upper case.
140
141 /// Alternate form given ('#').
143 };
144
145 /// The extended placeholder attributes.
147
148
149 // #############################################################################################
150 // Constructor/Destructor
151 // #############################################################################################
152 public:
153 //==========================================================================================
154 /// Constructs this formatter.
155 /// Inherited field #DefaultNumberFormat is initialized to meet the formatting defaults of
156 /// Java.
157 //==========================================================================================
160
161 //==========================================================================================
162 /// Clones and returns a copy of this formatter.
163 ///
164 /// If the formatter attached to field
165 /// \alib{format;Formatter::Next} is of type \b %FormatterStdImpl, then that
166 /// formatter is copied as well.
167 ///
168 /// @returns An object of type \b %FormatterPythonStyle and with the same custom settings
169 /// than this.
170 //==========================================================================================
171 ALIB_DLL virtual
172 SPFormatter Clone() override;
173
174 // #############################################################################################
175 // Implementation of FormatterStdImpl interface
176 // #############################################################################################
177 protected:
178
179 //==========================================================================================
180 /// Invokes parent implementation and then applies some changes to reflect what is defined as
181 /// default in the Java string format specification.
182 //==========================================================================================
184 virtual void resetPlaceholder() override;
185
186 //==========================================================================================
187 /// Searches for \c '\%' which is not '%%' or '%n'.
188 ///
189 /// @return The index found, -1 if not found.
190 //==========================================================================================
192 virtual integer findPlaceholder() override;
193
194 //==========================================================================================
195 /// Parses placeholder field in Java syntax. The portion \p{format_spec} is not set as this
196 /// is not supported by the syntax.
197 ///
198 /// @return \c true on success, \c false on errors.
199 //==========================================================================================
201 virtual bool parsePlaceholder() override;
202
203 //==========================================================================================
204 /// Does nothing. Java does not support custom format specifications.
205 ///
206 /// @return \c true to indicate success.
207 //==========================================================================================
208 virtual bool parseStdFormatSpec() override
209 {
210 return true;
211 }
212
213 //==========================================================================================
214 /// Implementation of abstract method \alib{format;FormatterStdImpl::writeStringPortion}.<br>
215 /// Replaces \c "%%" with \c '\%' and \c "%n" with ascii \c 0x0a. In addition applies
216 /// \alib{strings;TEscape;Escape} on \p{target} which replaces
217 /// standard codes like \c "\\n", \c "\\r" or \c "\\t" with corresponding ascii codes.
218 /// (The latter is an extension to the standard behavior of Java formatter.)
219 ///
220 /// @param length The number of characters to write.
221 //==========================================================================================
223 virtual void writeStringPortion( integer length ) override;
224
225 //==========================================================================================
226 /// All that this formatter does with this overridden method is to convert strings to
227 /// upper case.
228 ///
229 /// @param startIdx The index of the start of the field written in #targetString.
230 /// \c -1 indicates pre-phase.
231 /// @param target The target string, only if different from field #targetString, which
232 /// indicates intermediate phase.
233 /// @return \c false, if the placeholder should be skipped (nothing is written for it).
234 /// \c true otherwise.
235 //==========================================================================================
237 virtual bool preAndPostProcess( integer startIdx,
238 AString* target ) override;
239
240 //==========================================================================================
241 /// Makes some attribute adjustments and invokes standard implementation
242 /// @return \c true if OK, \c false if replacement should be aborted.
243 //==========================================================================================
245 virtual bool checkStdFieldAgainstArgument() override;
246};
247
248} // namespace [alib::format]
249
250ALIB_EXPORT namespace alib {
251/// Type alias in namespace \b alib.
253}
254
virtual ALIB_DLL void writeStringPortion(integer length) override
virtual ALIB_DLL void resetPlaceholder() override
virtual bool parseStdFormatSpec() override
virtual ALIB_DLL SPFormatter Clone() override
PlaceholderAttributesJS placeholderJS
The extended placeholder attributes.
virtual ALIB_DLL bool checkStdFieldAgainstArgument() override
virtual ALIB_DLL integer findPlaceholder() override
virtual ALIB_DLL bool parsePlaceholder() override
virtual ALIB_DLL bool preAndPostProcess(integer startIdx, AString *target) override
FormatterStdImpl(const String &formatterClassName)
#define ALIB_DLL
Definition alib.inl:496
#define ALIB_EXPORT
Definition alib.inl:488
format::FormatterJavaStyle FormatterJavaStyle
Type alias in namespace alib.
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
containers::SharedPtr< format::Formatter > SPFormatter
Definition formatter.inl:42
characters::character character
Type alias in namespace alib.
character DateTime
The character after conversion type 't'/'T'.