Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
MemoryStream.h
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Foundation_Streams_MemoryStream_h_
5#define _Stroika_Foundation_Streams_MemoryStream_h_ 1
6
7#include "Stroika/Foundation/StroikaPreComp.h"
8
9#include <vector>
10
12#include "Stroika/Foundation/Common/Common.h"
14
15#include "InputOutputStream.h"
16
17/*
18 * \file
19 *
20 * \note Code-Status: <a href="Code-Status.md#Beta">Beta</a>
21 */
22
23namespace Stroika::Foundation::Streams::MemoryStream {
24
25 using Characters::Character;
26 using Characters::String;
27 using Memory::BLOB;
28
29 template <typename ELEMENT_TYPE>
30 class Ptr;
31
32 /**
33 * \brief Create the Simplest InputOutputStream; MemoryStream can be written to, and then the raw data retrieved.
34 *
35 * MemoryStream is Seekable.
36 *
37 * Since MemoryStream keeps its data all in memory, it has the limitation that
38 * attempts to seek or write more than will fit in RAM will fail (with an exception).
39 *
40 * Data written to the memory stream can then be read from the memory stream.
41 *
42 * Reads and writes maybe intermixed, but beware to carefully manage (the separate) input/output seek positions.
43 *
44 * \note NB: This class COULD have been called MemoryInputOutputStream.
45 *
46 * \note Despite the somewhat 'low-level' sounding name, this can be used with arbitrary C++ objects (not just POD), so it respects copy-constructors etc.
47 *
48 * \note MemoryStream is NOT suitable for synchronized reading and writing between two threads (producer / consumer pattern).
49 * Reads return EOF instead of blocking (plus the lack of internal synchronization).
50 *
51 * @see SharedMemoryStream for that purpose.
52 *
53 * @see ExternallyOwnedMemoryInputStream
54 *
55 * \par Example Usage
56 * \code
57 * BLOB blob = ReadRaw ();
58 * optional<VariantValue> r = reader.Read (MemoryStream::New<byte> (blob));
59 * \endcode
60 *
61 * \note \em Thread-Safety <a href="Thread-Safety.md#C++-Standard-Thread-Safety-For-Envelope-Plus-Must-Externally-Synchronize-Letter">C++-Standard-Thread-Safety-For-Envelope-Plus-Must-Externally-Synchronize-Letter</a>
62 *
63 * \par Example Usage
64 * \code
65 * Streams::MemoryStream::Ptr<byte> out = Streams::MemoryStream::New<byte> ();
66 * DataExchange::Variant::JSON::Writer{}.Write (v, out);
67 * string xxx = out.As<string> ();
68 * \endcode
69 *
70 * \note \em Thread-Safety <a href="Thread-Safety.md#C++-Standard-Thread-Safety-For-Envelope-Plus-Must-Externally-Synchronize-Letter">C++-Standard-Thread-Safety-For-Envelope-Plus-Must-Externally-Synchronize-Letter</a>
71 *
72 * TODO:
73 * @todo The Rep_ would be a good candidate class to rewrite using new Sequence_ChunkedArray
74 * class (when I implement it) based on Led chunked arrays). But not if allowing access
75 * as a span (???)
76 *
77 * @todo Probably rewrite using InlineBuffer<> class
78 */
79 template <typename ELEMENT_TYPE>
80 Ptr<ELEMENT_TYPE> New ();
81 template <typename ELEMENT_TYPE, size_t EXTENT>
82 Ptr<ELEMENT_TYPE> New (span<const ELEMENT_TYPE, EXTENT> copyFrom);
83 template <typename ELEMENT_TYPE>
84 Ptr<ELEMENT_TYPE> New (const Memory::BLOB& copyFrom)
85 requires (same_as<ELEMENT_TYPE, byte>);
86
87 namespace Private_ {
88 template <typename ELEMENT_TYPE>
89 class Rep_;
90 }
91
92 /**
93 * Ptr is a smart pointer to a MemoryStream shared 'Rep' object.
94 *
95 * \note \em Thread-Safety <a href="Thread-Safety.md#C++-Standard-Thread-Safety-For-Envelope-But-Ambiguous-Thread-Safety-For-Letter">C++-Standard-Thread-Safety-For-Envelope-But-Ambiguous-Thread-Safety-For-Letter/a>
96 */
97 template <typename ELEMENT_TYPE>
98 class Ptr : public InputOutputStream::Ptr<ELEMENT_TYPE> {
99 private:
100 using inherited = typename InputOutputStream::Ptr<ELEMENT_TYPE>;
101
102 public:
103 /**
104 * \par Example Usage
105 * \code
106 * Streams::MemoryStream::Ptr<byte> out = Streams::MemoryStream::New<byte> ();
107 * DataExchange::Variant::JSON::Writer{}.Write (v, out);
108 * string xxx = out.As<string> ();
109 * \endcode
110 */
111 Ptr () = default;
112 Ptr (nullptr_t);
113 Ptr (const Ptr& from) = default;
114 Ptr (const shared_ptr<Private_::Rep_<ELEMENT_TYPE>>& from);
115
116 public:
117 nonvirtual Ptr& operator= (const Ptr& rhs) = default;
118
119 public:
120 /**
121 * Convert the current contents of this MemoryStream into one of the "T" representations.
122 *
123 * Only specifically specialized variants are supported. T can be one of:
124 * o vector<ElementType>
125 *
126 * And if ElementType is byte, then T can also be one of:
127 * o Memory::BLOB
128 * o string
129 *
130 * And if ElementType is Characters::Character, then T can also be one of:
131 * o String
132 */
133 template <typename T>
134 nonvirtual T As () const
135 requires (same_as<T, vector<ELEMENT_TYPE>> or (same_as<ELEMENT_TYPE, byte> and (same_as<T, BLOB> or same_as<T, string>)) or
136 (same_as<ELEMENT_TYPE, Character> and (same_as<T, String>)));
137
138 public:
139 /**
140 * Dump in some debugger friendly format/summary
141 */
142 nonvirtual String ToString () const;
143
144 private:
145 /**
146 * \pre *this != nullptr
147 */
148 nonvirtual const Private_::Rep_<ELEMENT_TYPE>& GetRepConstRef_ () const;
149
150 private:
151 /**
152 * \pre *this != nullptr
153 */
154 nonvirtual Private_::Rep_<ELEMENT_TYPE>& GetRepRWRef_ () const;
155 };
156
157}
158
159/*
160 ********************************************************************************
161 ***************************** Implementation Details ***************************
162 ********************************************************************************
163 */
164#include "MemoryStream.inl"
165
166#endif /*_Stroika_Foundation_Streams_MemoryStream_h_*/
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
InputOutputStream is single stream object that acts much as a InputStream::Ptr and an OutputStream::P...