Stroika Library 3.0d25
 
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 optional<filesystem::path> GetDefaultFileSuffix () const override
34 {
35 return nullopt;
36 }
37 virtual void Write (const VariantValue& v, const OutputStream::Ptr<byte>& out) const override
38 {
39#if USE_NOISY_TRACE_IN_THIS_MODULE_
40 Debug::TraceContextBumper ctx{"DataExchange::Variant::FormURLEncoded::Reader::Rep_::Write"};
41#endif
42 Association<String, String> assoc = v.As<Mapping<String, VariantValue>> ().Map<Association<String, String>> (
43 [] (auto i) { return KeyValuePair<String, String>{i.fKey, i.fValue.template As<String> ()}; });
44 Write (assoc, out);
45 }
46 virtual void Write ([[maybe_unused]] const VariantValue& v, [[maybe_unused]] const OutputStream::Ptr<Character>& out) const override
47 {
48 AssertNotImplemented (); // not sure if this makes sense ---
49 }
50 nonvirtual void Write (const Association<String, String>& m, const OutputStream::Ptr<byte>& out) const
51 {
52#if USE_NOISY_TRACE_IN_THIS_MODULE_
53 Debug::TraceContextBumper ctx{"DataExchange::Variant::FormURLEncoded::Reader::Rep_::Write"};
54#endif
55 // @todo this would be a good place to have a StreamWriter - instead of having to use a buffer manually
57 for (const KeyValuePair<String, String>& kvp : m) {
58 using namespace IO::Network::UniformResourceIdentification;
59 constexpr auto kOpts_ = PCTEncodeOptions{};
60 if (!buf.empty ()) {
61 buf.push_back (static_cast<byte> ('&'));
62 }
63 buf.push_back (Memory::SpanBytesCast<span<const byte>> (span<const char8_t>{PCTEncode (kvp.fKey, kOpts_)}));
64 buf.push_back (static_cast<byte> ('='));
65 buf.push_back (Memory::SpanBytesCast<span<const byte>> (span<const char8_t>{PCTEncode (kvp.fValue, kOpts_)}));
66 }
67 out.Write (buf);
68 }
69 /*nonvirtual void Write (const Iterable<String>& line, const OutputStream::Ptr<Characters::Character>& out) const
70 {
71#if USE_NOISY_TRACE_IN_THIS_MODULE_
72 Debug::TraceContextBumper ctx{"DataExchange::Variant::FormURLEncoded::Reader::Rep_::Write"};
73#endif
74 StringBuilder sb;
75 for (Iterator<String> i = line.begin (); i != line.end (); ++i) {
76 sb << *i;
77 if (i + 1 != line.end ()) {
78 sb << fOptions_.fSeparator;
79 if (fOptions_.fSpaceSeparate) {
80 sb << " "sv;
81 }
82 }
83 }
84 out.WriteLn (sb);
85 }*/
86};
87
88FormURLEncoded::Writer::Writer ()
89 : inherited{MakeSharedPtr<Rep_> ()}
90{
91}
92
93void FormURLEncoded::Writer::Write (const Association<String, String>& m, const OutputStream::Ptr<byte>& out) const
94{
95 Debug::UncheckedDynamicCast<const Rep_&> (_ConstGetRep ()).Write (m, out);
96}
97
98Memory::BLOB FormURLEncoded::Writer::WriteAsBLOB (const Association<String, String>& m) const
99{
100 return _WriteAsBLOBHelper ([&m, this] (const OutputStream::Ptr<byte>& out) { Write (m, out); });
101}
#define AssertNotImplemented()
Definition Assertions.h:404
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.
A Mapping uniquely associates two elements: a key and a value (use Assocation to allow multiple value...
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