4#include "Stroika/Foundation/StroikaPreComp.h"
6#include "Stroika/Foundation/Characters/FloatConversion.h"
8#include "Stroika/Foundation/Containers/SortedMapping.h"
10#include "Stroika/Foundation/Streams/TextToBinary.h"
19using namespace Stroika::Foundation::Streams;
23using Memory::MakeSharedPtr;
33 DISABLE_COMPILER_GCC_WARNING_START (
"GCC diagnostic ignored \"-Wdeprecated-declarations\"");
34 DISABLE_COMPILER_CLANG_WARNING_START (
"clang diagnostic ignored \"-Wdeprecated-declarations\"");
35 struct OptionValues_ final {
36 OptionValues_ (
const Variant::JSON::Writer::Options& o)
37 : fFloatOptions{o.fFloatOptions.value_or (Characters::FloatConversion::ToStringOptions{})}
38 , fPrettyPrint{o.fPrettyPrint.value_or (o.fJSONPrettyPrint.value_or (true))}
39 , fCanonicalize{o.fCanonicalize.value_or (false)}
40 , fSpacesPerIndent{o.fSpacesPerIndent.value_or (4)}
41 , fAllowNANInf{o.fAllowNANInf.value_or (true)}
42 , fLineTermination{o.fLineTermination.value_or (Characters::
kEOL<char>)}
44 if (not fPrettyPrint) {
47 if (fSpacesPerIndent != 0) {
54 unsigned int fSpacesPerIndent;
59 DISABLE_COMPILER_MSC_WARNING_END (4996);
60 DISABLE_COMPILER_GCC_WARNING_END (
"GCC diagnostic ignored \"-Wdeprecated-declarations\"");
61 DISABLE_COMPILER_CLANG_WARNING_END (
"clang diagnostic ignored \"-Wdeprecated-declarations\"");
73 if (options.fSpacesPerIndent != 0) {
74 constexpr bool kSpeedTweak_ =
true;
75 if constexpr (kSpeedTweak_) {
76 for (
int i = 0; i < indentLevel; ++i) {
77 out.
Write (options.fIndentSpace);
81 out.
Write (options.fIndentSpace.Repeat (indentLevel));
98 out.
Write (
"false"sv);
104 (void)::swprintf (buf, std::size (buf), L
"%lld", v);
110 (void)::swprintf (buf, std::size (buf), L
"%llu", v);
117 if (isnan (v) or isinf (v)) {
118 Require (options.fAllowNANInf);
119 PrettyPrint_ (options, tmp, out);
125 template <
typename CHARITERATOR>
131 for (
auto i = start; i != end; ++i) {
164 (void)::swprintf (buf, std::size (buf), L
"\\u%04x",
static_cast<char16_t> (c.
GetCharacterCode ()));
179 PrettyPrint_ (options, v.begin (), v.end (), out);
184 span<const char32_t> p = v.
GetData (&ignored);
185 PrettyPrint_ (options, p.data (), p.data () + p.size (), out);
187 void PrettyPrint_ (
const OptionValues_& options,
const vector<VariantValue>& v,
const OutputStream::Ptr<Character>& out,
int indentLevel)
190 if (options.fPrettyPrint) {
191 out.
Write (options.fLineTermination);
193 for (
auto i = v.begin (); i != v.end (); ++i) {
194 Indent_ (options, out, indentLevel + 1);
195 PrettyPrint_ (options, *i, out, indentLevel + 1);
196 if (i + 1 != v.end ()) {
199 if (options.fPrettyPrint) {
200 out.
Write (options.fLineTermination);
203 Indent_ (options, out, indentLevel);
209 if (options.fPrettyPrint) {
210 out.
Write (options.fLineTermination);
213 if (options.fCanonicalize) {
216 for (
auto i = vv.begin (); i != vv.end ();) {
217 Indent_ (options, out, indentLevel + 1);
218 PrettyPrint_ (options, i->fKey, out, indentLevel + 1);
220 PrettyPrint_ (options, i->fValue, out, indentLevel + 1);
225 if (options.fPrettyPrint) {
226 out.
Write (options.fLineTermination);
229 Indent_ (options, out, indentLevel);
234 switch (v.GetType ()) {
235 case VariantValue::eNull:
236 PrettyPrint_Null_ (options, out);
238 case VariantValue::eBoolean:
239 PrettyPrint_ (options, v.
As<
bool> (), out);
241 case VariantValue::eInteger:
242 PrettyPrint_ (options, v.
As<
long long int> (), out);
244 case VariantValue::eUnsignedInteger:
245 PrettyPrint_ (options, v.
As<
unsigned long long int> (), out);
247 case VariantValue::eFloat:
248 PrettyPrint_ (options, v.
As<
long double> (), out);
250 case VariantValue::eMap:
253 case VariantValue::eArray:
254 PrettyPrint_ (options, v.
As<vector<VariantValue>> (), out, indentLevel);
257 PrettyPrint_ (options, v.
As<
String> (), out);
269 OptionValues_ fOptions_;
270 Rep_ (
const Options& options)
274 Rep_ (
const OptionValues_& options)
278 virtual _SharedPtrIRep Clone ()
const override
280 return MakeSharedPtr<Rep_> (fOptions_);
282 virtual optional<filesystem::path> GetDefaultFileSuffix ()
const override
289 PrettyPrint_ (fOptions_, v, textOut, 0);
290 if (fOptions_.fPrettyPrint) {
291 textOut.
Write (fOptions_.fLineTermination);
296 PrettyPrint_ (fOptions_, v, out, 0);
300Variant::JSON::Writer::Writer (
const Options& options)
auto MakeSharedPtr(ARGS_TYPE &&... args) -> shared_ptr< T >
same as make_shared, but if type T has block allocation, then use block allocation for the 'shared pa...
conditional_t< qStroika_Foundation_Memory_PreferBlockAllocation and andTrueCheck, BlockAllocationUseHelper< T >, Common::Empty > UseBlockAllocationIfAppropriate
Use this to enable block allocation for a particular class. Beware of subclassing.
constexpr bool IsSurrogatePair() const
constexpr bool IsControl() const noexcept
constexpr char32_t GetCharacterCode() const noexcept
Return the char32_t UNICODE code-point associated with this character.
constexpr pair< char16_t, char16_t > GetSurrogatePair() const
Similar to String, but intended to more efficiently construct a String. Mutable type (String is large...
nonvirtual span< const CHAR_T > GetData(Memory::StackBuffer< CHAR_T > *probablyIgnoredBuf) const
access a span of data located inside the StringBuilder. Return internal pointer, or pointer internal ...
nonvirtual void Append(span< const CHAR_T > s)
String is like std::u32string, except it is much easier to use, often much more space efficient,...
nonvirtual String Repeat(unsigned int count) const
static span< const CHAR_TYPE > GetData(const PeekSpanData &pds, Memory::StackBuffer< CHAR_TYPE, STACK_BUFFER_SZ > *possiblyUsedBuffer)
return the constant character data inside the string (rep) in the form of a span, possibly quickly an...
Simple variant-value (case variant union) object, with (variant) basic types analogous to a value in ...
nonvirtual RETURNTYPE As() const
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...
OutputStream<>::Ptr is Smart pointer to a stream-based sink of data.
nonvirtual void Write(span< ELEMENT_TYPE2, EXTENT_2 > elts) const
static constexpr default_sentinel_t end() noexcept
Support for ranged for, and STL syntax in general.
STRING_TYPE ToString(FLOAT_TYPE f, const ToStringOptions &options={})
DISABLE_COMPILER_MSC_WARNING_START(4996)
static constexpr T kEOL[]
null-terminated String constant for current compiled platform - Windows (CRLF) or POSIX (NL) - macos ...
Ptr New(const Streams::OutputStream::Ptr< byte > &src, const Characters::CodeCvt<> &char2OutputConverter)