Stroika Library 3.0d23
 
Loading...
Searching...
No Matches
Variant/INI/Reader.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3 */
4#include "Stroika/Foundation/StroikaPreComp.h"
5
6#include "Stroika/Foundation/Characters/FloatConversion.h"
8#include "Stroika/Foundation/Characters/String2Int.h"
9#include "Stroika/Foundation/DataExchange/BadFormatException.h"
12
13#include "Reader.h"
14
15using namespace Stroika::Foundation;
18using namespace Stroika::Foundation::Streams;
19
20// Comment this in to turn on aggressive noisy DbgTrace in this module
21//#define USE_NOISY_TRACE_IN_THIS_MODULE_ 1
22
23/*
24 ********************************************************************************
25 ************************** DataExchange::INI::Reader ***************************
26 ********************************************************************************
27 */
28class Variant::INI::Reader::Rep_ final : public Variant::Reader::_IRep, public Memory::UseBlockAllocationIfAppropriate<Rep_> {
29public:
30 virtual _SharedPtrIRep Clone () const override
31 {
32 return Memory::MakeSharedPtr<Rep_> (); // no instance data
33 }
34 virtual optional<filesystem::path> GetDefaultFileSuffix () const override
35 {
36 return ".ini"sv;
37 }
38 virtual VariantValue Read (const InputStream::Ptr<byte>& in) const override
39 {
40 return Read (BinaryToText::Reader::New (in));
41 }
42 virtual VariantValue Read (const InputStream::Ptr<Character>& in) const override
43 {
44#if USE_NOISY_TRACE_IN_THIS_MODULE_
45 Debug::TraceContextBumper ctx{"DataExchange::INI::Reader::Rep_::Read"};
46#endif
47 Profile p;
48 optional<String> readingSection;
49 Section currentSection;
50 for (String line : in.ReadLines ()) {
51 line = line.Trim ();
52 if (line.StartsWith ("["sv) and line.EndsWith ("]"sv)) {
53 if (readingSection.has_value ()) {
54 p.fNamedSections.Add (*readingSection, currentSection);
55 currentSection.fProperties.clear ();
56 }
57 readingSection = line.SubString (1, -1);
58 }
59 else if (line.StartsWith (";"sv)) {
60 // drop comments on the floor
61 }
62 else if (line.Contains ("="sv)) {
63 size_t i = *line.Find ('=');
64 String key = line.SubString (0, i).Trim ();
65 String value = line.SubString (i + 1).Trim ();
66 if (value.StartsWith ("\""sv) and value.EndsWith ("\""sv)) {
67 value = value.SubString (1, -1);
68 }
69 if (readingSection.has_value ()) {
70 currentSection.fProperties.Add (key, value);
71 }
72 else {
73 p.fUnnamedSection.fProperties.Add (key, value);
74 }
75 }
76 else {
77 // @todo not sure what todo with other sorts of lines??
78 }
79 }
80 if (readingSection.has_value ()) {
81 p.fNamedSections.Add (*readingSection, currentSection);
82 }
83 return Convert (p);
84 }
85};
86Variant::INI::Reader::Reader ()
87 : inherited{Memory::MakeSharedPtr<Rep_> ()}
88{
89}
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.
Profile Convert(const VariantValue &v)
Definition Profile.cpp:50
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Definition String.h:201
nonvirtual bool EndsWith(const Character &c, CompareOptions co=eWithCase) const
Definition String.cpp:1089
nonvirtual String SubString(SZ from) const
nonvirtual String Trim(bool(*shouldBeTrimmed)(Character)=Character::IsWhitespace) const
Definition String.cpp:1593
nonvirtual bool StartsWith(const Character &c, CompareOptions co=eWithCase) const
Definition String.cpp:1060
Simple variant-value (case variant union) object, with (variant) basic types analogous to a value in ...
InputStream<>::Ptr is Smart pointer (with abstract Rep) class defining the interface to reading from ...
Ptr New(const InputStream::Ptr< byte > &src, optional< AutomaticCodeCvtFlags > codeCvtFlags={}, optional< SeekableFlag > seekable={}, ReadAhead readAhead=eReadAheadAllowed)
Create an InputStream::Ptr<Character> from the arguments (usually binary source) - which can be used ...