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