Stroika Library 3.0d23x
 
Loading...
Searching...
No Matches
ObjectReader.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4#include "Stroika/Foundation/StroikaPreComp.h"
5
7#include "Stroika/Foundation/Characters/FloatConversion.h"
9#include "Stroika/Foundation/Characters/String2Int.h"
10#include "Stroika/Foundation/DataExchange/BadFormatException.h"
16
17#include "ObjectReader.h"
18
19using namespace Stroika::Foundation;
22using namespace Stroika::Foundation::DataExchange::StructuredStreamEvents;
24
25using Memory::MakeSharedPtr;
26using Time::Date;
27using Time::DateTime;
28using Time::Duration;
29using Time::TimeOfDay;
30
31// Comment this in to turn on aggressive noisy DbgTrace in this module
32//#define USE_NOISY_TRACE_IN_THIS_MODULE_ 1
33
34/*
35 ********************************************************************************
36 *********************** ObjectReaderIElementConsumer ***************************
37 ********************************************************************************
38 */
39shared_ptr<IElementConsumer> IElementConsumer::HandleChildStart ([[maybe_unused]] const Name& name)
40{
41 return nullptr;
42}
43
44void IElementConsumer::HandleTextInside ([[maybe_unused]] const String& text)
45{
46}
47
48void IElementConsumer::Activated ([[maybe_unused]] Context& r)
49{
50}
51
55
56/*
57 ********************************************************************************
58 **************************** Registry::SimpleReader_<> *************************
59 ********************************************************************************
60 */
61template <>
62void Registry::SimpleReader_<String>::Deactivating ()
63{
64 *fValue_ = fBuf_.str ();
65}
66
67template <>
68void Registry::SimpleReader_<char>::Deactivating ()
69{
70 *fValue_ = Characters::String2Int<char> (fBuf_.str ());
71}
72
73template <>
74void Registry::SimpleReader_<unsigned char>::Deactivating ()
75{
76 *fValue_ = Characters::String2Int<unsigned char> (fBuf_.str ());
77}
78
79template <>
80void Registry::SimpleReader_<short>::Deactivating ()
81{
82 *fValue_ = Characters::String2Int<short> (fBuf_.str ());
83}
84
85template <>
86void Registry::SimpleReader_<unsigned short>::Deactivating ()
87{
88 *fValue_ = Characters::String2Int<unsigned short> (fBuf_.str ());
89}
90
91template <>
92void Registry::SimpleReader_<int>::Deactivating ()
93{
94 *fValue_ = Characters::String2Int<int> (fBuf_.str ());
95}
96
97template <>
98void Registry::SimpleReader_<unsigned int>::Deactivating ()
99{
100 *fValue_ = Characters::String2Int<unsigned int> (fBuf_.str ());
101}
102
103template <>
104void Registry::SimpleReader_<long int>::Deactivating ()
105{
106 *fValue_ = Characters::String2Int<long int> (fBuf_.str ());
107}
108
109template <>
110void Registry::SimpleReader_<unsigned long int>::Deactivating ()
111{
112 *fValue_ = Characters::String2Int<unsigned long int> (fBuf_.str ());
113}
114
115template <>
116void Registry::SimpleReader_<long long int>::Deactivating ()
117{
118 *fValue_ = Characters::String2Int<long long int> (fBuf_.str ());
119}
120
121template <>
122void Registry::SimpleReader_<unsigned long long int>::Deactivating ()
123{
124 *fValue_ = Characters::String2Int<unsigned long long int> (fBuf_.str ());
125}
126
127template <>
128void Registry::SimpleReader_<bool>::Deactivating ()
129{
130 *fValue_ = (fBuf_.str ().ToLowerCase () == "true"sv);
131}
132
133template <>
134void Registry::SimpleReader_<float>::Deactivating ()
135{
136 (*fValue_) = Characters::FloatConversion::ToFloat<float> (fBuf_.str ());
137}
138
139template <>
140void Registry::SimpleReader_<double>::Deactivating ()
141{
142 (*fValue_) = Characters::FloatConversion::ToFloat<double> (fBuf_.str ());
143}
144
145template <>
146void Registry::SimpleReader_<long double>::Deactivating ()
147{
148 (*fValue_) = Characters::FloatConversion::ToFloat<long double> (fBuf_.str ());
149}
150
151template <>
152void Registry::SimpleReader_<IO::Network::URI>::Deactivating ()
153{
154 // not 100% right to ignore exceptions, but tricky to do more right (cuz not necesarily all text given us at once)
155 IgnoreExceptionsForCall (*fValue_ = IO::Network::URI::Parse (fBuf_.str ()));
156}
157
158template <>
159void Registry::SimpleReader_<Time::DateTime>::Deactivating ()
160{
161 // not 100% right to ignore exceptions, but tricky to do more right (cuz not necesarily all text given us at once)
162 IgnoreExceptionsForCall (*fValue_ = Time::DateTime::Parse (fBuf_.str (), Time::DateTime::kISO8601Format));
163}
164
165template <>
166void Registry::SimpleReader_<Time::Duration>::Deactivating ()
167{
168 // not 100% right to ignore exceptions, but tricky to do more right (cuz not necesarily all text given us at once)
169 IgnoreExceptionsForCall (*fValue_ = Time::Duration{fBuf_.str ()});
170}
171
172/*
173 ********************************************************************************
174 ****************************** IgnoreNodeReader ********************************
175 ********************************************************************************
176 */
177shared_ptr<IElementConsumer> IgnoreNodeReader::HandleChildStart ([[maybe_unused]] const StructuredStreamEvents::Name& name)
178{
179 return shared_from_this ();
180}
181
182/*
183 ********************************************************************************
184 *********************************** Context ************************************
185 ********************************************************************************
186 */
187Context::Context (const Registry& registry, const shared_ptr<IElementConsumer>& initialTop)
188 : fObjectReaderRegistry_ (registry)
189{
190 Push (initialTop);
191}
192
193#if qStroika_Foundation_DataExchange_StructuredStreamEvents_SupportTracing
194String Context::TraceLeader_ () const
195{
196 static const String kOneTabLevel_{" "sv};
197 return kOneTabLevel_.Repeat (static_cast<unsigned int> (fStack_.size ()));
198}
199#endif
200
201/*
202 ********************************************************************************
203 ********************* Registry::IConsumerDelegateToContext *********************
204 ********************************************************************************
205 */
207{
208 AssertNotNull (fContext.GetTop ());
209#if qStroika_Foundation_DataExchange_StructuredStreamEvents_SupportTracing
210 if (fContext.fTraceThisReader) {
211 DbgTrace ("{}Calling IConsumerDelegateToContext::HandleChildStart ('{}')..."_f, fContext.TraceLeader_ (), name.fLocalName);
212 }
213#endif
214 shared_ptr<IElementConsumer> eltToPush = fContext.GetTop ()->HandleChildStart (name);
215 AssertNotNull (eltToPush);
216 fContext.Push (eltToPush);
217 // and push each attribute, as if called with StartElement (as was done before Stroika v3.0d5)
218 for (auto attr : attributes) {
219 static const Mapping<Name, String> kEmpty_;
220 StartElement (attr.fKey, kEmpty_);
221 TextInsideElement (attr.fValue);
222 EndElement (attr.fKey);
223 }
224}
226{
227 AssertNotNull (fContext.GetTop ());
228#if qStroika_Foundation_DataExchange_StructuredStreamEvents_SupportTracing
229 if (fContext.fTraceThisReader) {
230 DbgTrace ("{}Calling IConsumerDelegateToContext::EndElement ('{}')..."_f, fContext.TraceLeader_ (), name.fLocalName);
231 }
232#endif
233 fContext.Pop ();
234}
236{
237 AssertNotNull (fContext.GetTop ());
238#if qStroika_Foundation_DataExchange_StructuredStreamEvents_SupportTracing
239 if (fContext.fTraceThisReader) {
240 DbgTrace ("{}Calling IConsumerDelegateToContext::TextInsideElement ('{}')..."_f, fContext.TraceLeader_ (), text.LimitLength (50));
241 }
242#endif
243 fContext.GetTop ()->HandleTextInside (text);
244}
245
246/*
247 ********************************************************************************
248 ****************************** Registry::ReadDownToReader **********************
249 ********************************************************************************
250 */
251ReadDownToReader::ReadDownToReader (const shared_ptr<IElementConsumer>& theUseReader)
252 : fReader2Delegate2_ (theUseReader)
253{
254 RequireNotNull (theUseReader);
255}
256
257ReadDownToReader::ReadDownToReader (const shared_ptr<IElementConsumer>& theUseReader, const Name& tagToHandOff)
258 : fReader2Delegate2_ (theUseReader)
259 , fTagToHandOff_ (tagToHandOff)
260{
261 RequireNotNull (theUseReader);
262}
263
264ReadDownToReader::ReadDownToReader (const shared_ptr<IElementConsumer>& theUseReader, const Name& contextTag, const Name& tagToHandOff)
265 : ReadDownToReader (MakeSharedPtr<ReadDownToReader> (theUseReader, tagToHandOff), contextTag)
266{
267 RequireNotNull (theUseReader);
268}
269
270ReadDownToReader::ReadDownToReader (const shared_ptr<IElementConsumer>& theUseReader, const Name& contextTag1, const Name& contextTag2, const Name& tagToHandOff)
271 : ReadDownToReader (MakeSharedPtr<ReadDownToReader> (theUseReader, contextTag2, tagToHandOff), contextTag1)
272{
273 RequireNotNull (theUseReader);
274}
275
276shared_ptr<IElementConsumer> ReadDownToReader::HandleChildStart (const Name& name)
277{
278 if (not fTagToHandOff_.has_value () or *fTagToHandOff_ == name) {
279 return fReader2Delegate2_;
280 }
281 else {
282 return shared_from_this ();
283 }
284}
285
286/*
287 ********************************************************************************
288 ****** StructuredStreamEvents::ObjectReader::ThrowUnRecognizedStartElt *********
289 ********************************************************************************
290 */
291[[noreturn]] void StructuredStreamEvents::ObjectReader::ThrowUnRecognizedStartElt (const StructuredStreamEvents::Name& name)
292{
293 Execution::Throw (BadFormatException{Characters::CString::Format (L"Unrecognized start tag '%s'", name.fLocalName.As<wstring> ().c_str ())});
294}
#define AssertNotNull(p)
Definition Assertions.h:333
#define RequireNotNull(p)
Definition Assertions.h:347
#define DbgTrace
Definition Trace.h:309
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
nonvirtual String Repeat(unsigned int count) const
Definition String.cpp:1425
nonvirtual String LimitLength(size_t maxLen, StringShorteningPreference keepPref=StringShorteningPreference::ePreferKeepLeft) const
return the first maxLen (or fewer if string shorter) characters of this string (adding ellipsis if tr...
Definition String.inl:745
virtual void StartElement(const Name &name, const Mapping< Name, String > &attributes) override
static URI Parse(const String &rawURL)
Definition URI.cpp:119
Duration is a chrono::duration<double> (=.
Definition Duration.h:96
Create a format-string (see std::wformat_string or Stroika FormatString, or python 'f' strings.
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...
Definition Throw.inl:43