Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Variant/INI/Reader.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. 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"
11
12#include "Reader.h"
13
14using namespace Stroika::Foundation;
17using namespace Stroika::Foundation::Streams;
18
19// Comment this in to turn on aggressive noisy DbgTrace in this module
20//#define USE_NOISY_TRACE_IN_THIS_MODULE_ 1
21
22/*
23 ********************************************************************************
24 ************************** DataExchange::INI::Reader ***************************
25 ********************************************************************************
26 */
27class Variant::INI::Reader::Rep_ : public Variant::Reader::_IRep, public Memory::UseBlockAllocationIfAppropriate<Rep_> {
28public:
29 virtual _SharedPtrIRep Clone () const override
30 {
31 return make_shared<Rep_> (); // no instance data
32 }
33 virtual optional<filesystem::path> GetDefaultFileSuffix () const override
34 {
35 return ".ini"sv;
36 }
37 virtual VariantValue Read (const InputStream::Ptr<byte>& in) override
38 {
39 return Read (BinaryToText::Reader::New (in));
40 }
41 virtual VariantValue Read (const InputStream::Ptr<Character>& in) override
42 {
43#if USE_NOISY_TRACE_IN_THIS_MODULE_
44 Debug::TraceContextBumper ctx{"DataExchange::INI::Reader::Rep_::Read"};
45#endif
46 Profile p;
47 optional<String> readingSection;
48 Section currentSection;
49 for (String line : in.ReadLines ()) {
50 line = line.Trim ();
51 if (line.StartsWith ("["sv) and line.EndsWith ("]"sv)) {
52 if (readingSection.has_value ()) {
53 p.fNamedSections.Add (*readingSection, currentSection);
54 currentSection.fProperties.clear ();
55 }
56 readingSection = line.SubString (1, -1);
57 }
58 else if (line.StartsWith (";"sv)) {
59 // drop comments on the floor
60 }
61 else if (line.Contains ("="sv)) {
62 size_t i = *line.Find ('=');
63 String key = line.SubString (0, i).Trim ();
64 String value = line.SubString (i + 1).Trim ();
65 if (value.StartsWith ("\""sv) and value.EndsWith ("\""sv)) {
66 value = value.SubString (1, -1);
67 }
68 if (readingSection.has_value ()) {
69 currentSection.fProperties.Add (key, value);
70 }
71 else {
72 p.fUnnamedSection.fProperties.Add (key, value);
73 }
74 }
75 else {
76 // @todo not sure what todo with other sorts of lines??
77 }
78 }
79 if (readingSection.has_value ()) {
80 p.fNamedSections.Add (*readingSection, currentSection);
81 }
82 return Convert (p);
83 }
84};
85Variant::INI::Reader::Reader ()
86 : inherited{make_shared<Rep_> ()}
87{
88}
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:1088
nonvirtual String SubString(SZ from) const
nonvirtual String Trim(bool(*shouldBeTrimmed)(Character)=Character::IsWhitespace) const
Definition String.cpp:1592
nonvirtual bool StartsWith(const Character &c, CompareOptions co=eWithCase) const
Definition String.cpp:1059
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 ...