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