Stroika Library 3.0d23x
 
Loading...
Searching...
No Matches
Variant/FormURLEncoded/Writer.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4#include "Stroika/Foundation/StroikaPreComp.h"
5
9#include "Stroika/Foundation/Streams/MemoryStream.h"
10#include "Stroika/Foundation/Streams/TextToBinary.h"
11
12#include "Writer.h"
13
14using namespace Stroika::Foundation;
16using namespace Stroika::Foundation::Common;
18using namespace Stroika::Foundation::Streams;
19using namespace Stroika::Foundation::Traversal;
20
21using namespace DataExchange::Variant;
22
23using Memory::MakeSharedPtr;
24
25/*
26 ********************************************************************************
27 ************** DataExchange::Variant::FormURLEncoded::Writer *******************
28 ********************************************************************************
29 */
30class FormURLEncoded::Writer::Rep_ final : public Variant::Writer::_IRep, public Memory::UseBlockAllocationIfAppropriate<Rep_> {
31public:
32 Rep_ () = default;
33 virtual _SharedPtrIRep Clone () const override
34 {
35 return MakeSharedPtr<Rep_> (); // no instance data
36 }
37 virtual optional<filesystem::path> GetDefaultFileSuffix () const override
38 {
39 return nullopt;
40 }
41 virtual void Write (const VariantValue& v, const OutputStream::Ptr<byte>& out) const override
42 {
43#if USE_NOISY_TRACE_IN_THIS_MODULE_
44 Debug::TraceContextBumper ctx{"DataExchange::Variant::FormURLEncoded::Reader::Rep_::Write"};
45#endif
46 Association<String, String> assoc = v.As<Mapping<String, VariantValue>> ().Map<Association<String, String>> (
47 [] (auto i) { return KeyValuePair<String, String>{i.fKey, i.fValue.template As<String> ()}; });
48 Write (assoc, out);
49 }
50 virtual void Write ([[maybe_unused]] const VariantValue& v, [[maybe_unused]] const OutputStream::Ptr<Character>& out) const override
51 {
52 AssertNotImplemented (); // not sure if this makes sense ---
53 }
54 nonvirtual void Write (const Association<String, String>& m, const OutputStream::Ptr<byte>& out) const
55 {
56#if USE_NOISY_TRACE_IN_THIS_MODULE_
57 Debug::TraceContextBumper ctx{"DataExchange::Variant::FormURLEncoded::Reader::Rep_::Write"};
58#endif
59 // @todo this would be a good place to have a StreamWriter - instead of having to use a buffer manually
61 for (const KeyValuePair<String, String>& kvp : m) {
62 using namespace IO::Network::UniformResourceIdentification;
63 constexpr auto kOpts_ = PCTEncodeOptions{};
64 if (!buf.empty ()) {
65 buf.push_back (static_cast<byte> ('&'));
66 }
67 buf.push_back (Memory::SpanBytesCast<span<const byte>> (span<const char8_t>{PCTEncode (kvp.fKey, kOpts_)}));
68 buf.push_back (static_cast<byte> ('='));
69 buf.push_back (Memory::SpanBytesCast<span<const byte>> (span<const char8_t>{PCTEncode (kvp.fValue, kOpts_)}));
70 }
71 out.Write (buf);
72 }
73 /*nonvirtual void Write (const Iterable<String>& line, const OutputStream::Ptr<Characters::Character>& out) const
74 {
75#if USE_NOISY_TRACE_IN_THIS_MODULE_
76 Debug::TraceContextBumper ctx{"DataExchange::Variant::FormURLEncoded::Reader::Rep_::Write"};
77#endif
78 StringBuilder sb;
79 for (Iterator<String> i = line.begin (); i != line.end (); ++i) {
80 sb << *i;
81 if (i + 1 != line.end ()) {
82 sb << fOptions_.fSeparator;
83 if (fOptions_.fSpaceSeparate) {
84 sb << " "sv;
85 }
86 }
87 }
88 out.WriteLn (sb);
89 }*/
90};
91
92FormURLEncoded::Writer::Writer ()
93 : inherited{MakeSharedPtr<Rep_> ()}
94{
95}
96
97void FormURLEncoded::Writer::Write (const Association<String, String>& m, const OutputStream::Ptr<byte>& out)
98{
99 Debug::UncheckedDynamicCast<Rep_&> (_GetRep ()).Write (m, out);
100}
101
102Memory::BLOB FormURLEncoded::Writer::WriteAsBLOB (const Association<String, String>& m)
103{
104 return _WriteAsBLOBHelper ([&m, this] (const OutputStream::Ptr<byte>& out) { Write (m, out); });
105}
#define AssertNotImplemented()
Definition Assertions.h:401
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.
Simple variant-value (case variant union) object, with (variant) basic types analogous to a value in ...
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...
nonvirtual void push_back(Common::ArgByValueType< T > e)
nonvirtual bool empty() const noexcept
OutputStream<>::Ptr is Smart pointer to a stream-based sink of data.
nonvirtual void Write(span< ELEMENT_TYPE2, EXTENT_2 > elts) const