ALib C++ Framework
by
Library Version: 2605 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
formatterjavastyle.hpp
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/// Copyright 2013-2026 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 #"%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. This Chooses the first argument. (In Java a \c MissingFormatArgumentException
35/// 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 #"%ExponentSeparator", #"%NANLiteral" and #"%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 #"%format::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 // Protected fields
118 //################################################################################################
119 protected:
120 /// Set of extended placeholder attributes, needed for this type of formatter in
121 /// addition to parent's #"FormatterStdImpl::PlaceholderAttributes".
123 /// The character after conversion type 't'/'T'.
125
126 /// The value read from the precision field.
127 /// This is set to \c -1 in #"resetPlaceholder".
128 int8_t Precision;
129
130 /// The default precision if not given.
131 /// This is set to \c 6 in #"resetPlaceholder", but is changed when specified.
133
134 /// Convert to upper case.
136
137 /// Alternate form given ('#"')".
139 };
140
141 /// The extended placeholder attributes.
143
144
145 //################################################################################################
146 // Constructor/Destructor
147 //################################################################################################
148 public:
149 /// Constructs this formatter.
150 /// Inherited field #"DefaultNumberFormat" is initialized to meet the formatting defaults of
151 /// Java.
154
155 /// Clones and returns a copy of this formatter.
156 ///
157 /// If the formatter attached to field
158 /// #"Formatter::Next;*" is of type #"%FormatterStdImpl", then that
159 /// formatter is copied as well.
160 ///
161 /// @returns An object of type #"%FormatterPythonStyle" and with the same custom settings
162 /// than this.
163 ALIB_DLL virtual
164 SPFormatter Clone() override;
165
166 //################################################################################################
167 // Implementation of FormatterStdImpl interface
168 //################################################################################################
169 protected:
170
171 /// Invokes parent implementation and then applies some changes to reflect what is defined as
172 /// default in the Java string format specification.
174 virtual void resetPlaceholder() override;
175
176 /// Searches for \c '\%' which is not '%%' or '%n'.
177 ///
178 /// @return The index found, -1 if not found.
180 virtual integer findPlaceholder() override;
181
182 /// Parses placeholder field in Java syntax. The portion \p{format_spec} is not set as this
183 /// is not supported by the syntax.
184 ///
185 /// @return \c true on success, \c false on errors.
187 virtual bool parsePlaceholder() override;
188
189 /// Does nothing. Java does not support custom format specifications.
190 ///
191 /// @return \c true to indicate success.
192 virtual bool parseStdFormatSpec() override { return true; }
193
194 /// Implementation of abstract method #"FormatterStdImpl::writeStringPortion;*".<br>
195 /// Replaces \c "%%" with \c '\%' and \c "%n" with ascii \c 0x0a. In addition applies
196 /// #"TEscape;Escape" on \p{target} which replaces
197 /// standard codes like \c "\\n", \c "\\r" or \c "\\t" with corresponding ascii codes.
198 /// (The latter is an extension to the standard behavior of Java formatter.)
199 ///
200 /// @param length The number of characters to write.
202 virtual void writeStringPortion( integer length ) override;
203
204 /// All that this formatter does with this overridden method is to convert strings to
205 /// upper case.
206 ///
207 /// @param startIdx The index of the start of the field written in #"targetString".
208 /// \c -1 indicates pre-phase.
209 /// @param target The target string, only if different from field #"targetString", which
210 /// indicates intermediate phase.
211 /// @return \c false, if the placeholder should be skipped (nothing is written for it).
212 /// \c true otherwise.
214 virtual bool preAndPostProcess( integer startIdx,
215 AString* target ) override;
216
217 /// Makes some attribute adjustments and invokes standard implementation
218 /// @return \c true if OK, \c false if replacement should be aborted.
220 virtual bool checkStdFieldAgainstArgument() override;
221};
222
223} // namespace [alib::format]
224
225ALIB_EXPORT namespace alib {
226/// Type alias in namespace #"%alib".
228}
#define ALIB_DLL
#define ALIB_EXPORT
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)
Definition alox.cpp:14
containers::SharedPtr< format::Formatter > SPFormatter
Definition formatter.hpp:41
lang::integer integer
Type alias in namespace #"%alib".
Definition integers.hpp: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'.