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