Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cIniSection.h
Go to the documentation of this file.
1 //
4 //
5 
6 #ifndef _INC_cIniSection_H
7 #define _INC_cIniSection_H
8 #ifndef NO_PRAGMA_ONCE
9 #pragma once
10 #endif
11 
12 #include "cIniBase.h"
13 #include "StrArg.h"
14 #include "cHeap.h"
15 #include "cTextPos.h"
16 
17 namespace Gray
18 {
19 #define INI_CR "\r\n"
20 
21  class cStreamOutput;
22 
24  {
28 
29  protected:
32 
33  public:
35  : m_pOut(pOut)
36  , m_bStartedSection(false)
37  {
38  ASSERT(pOut != nullptr);
39  }
40 
41  HRESULT WriteSectionHead0(const IniChar_t* pszSectionData);
42  HRESULT WriteSectionHead1(const IniChar_t* pszSectionType, const IniChar_t* pszSectionName);
43  HRESULT WriteSectionHead1Q(const IniChar_t* pszSection, const IniChar_t* pszArg);
44  HRESULT _cdecl WriteSectionHeadFormat(const IniChar_t* pszSectionType, const IniChar_t* pszArgFormat, ...);
45 
46  HRESULT WriteKeyUnk(const IniChar_t* pszKey, const IniChar_t* pszData);
47  HRESULT WriteKeyStrQ(const IniChar_t* pszKey, const IniChar_t* pszVal);
48  HRESULT WriteKeyInt(const IniChar_t* pszKey, int nVal);
49  HRESULT WriteKeyUInt(const IniChar_t* pszKey, UINT nVal);
50  };
51 
52  struct GRAYCORE_LINK cIniReader // static
53  {
56 
57  static bool GRAYCALL IsSectionHeader(const IniChar_t* pszLine);
58 
59  static bool GRAYCALL IsLineComment(const IniChar_t* pszLine);
60  static IniChar_t* GRAYCALL FindLineArg(const IniChar_t* pszLine, bool bAllowSpace = false);
61  static StrLen_t GRAYCALL FindScriptLineEnd(const IniChar_t* pLineStr);
62  static cStringI GRAYCALL GetLineParse2(const IniChar_t* pszLine, IniChar_t** ppszArgs = nullptr);
63  static cStringI GRAYCALL GetLineParse3(const IniChar_t* pszLine, OUT cStringI& rsArgs);
64  };
65 
67  : public IIniBaseEnumerator
68  , public IIniBaseGetter
69  , public IIniBaseSetter
70  , public cIniReader
71  {
80 
81  friend class cIniFile;
82  public:
83  static const StrLen_t k_SECTION_SIZE_MAX = (256 * 1024);
84  static const ITERATE_t k_LINE_QTY_MAX = (8 * 1024);
85  static const StrLen_t k_LINE_LEN_MAX = (4 * 1024);
86  static const StrLen_t k_LINE_LEN_DEF = (1024);
87 
88  protected:
90 
91  private:
92  cHeapBlock m_Buffer;
93  StrLen_t m_iBufferUsed;
94 
95  IniChar_t** m_ppLines;
96  ITERATE_t m_iLinesAlloc;
97  ITERATE_t m_iLinesUsed;
98 
99  private:
100  void MoveLineOffsets(ITERATE_t iLineStart, INT_PTR iDiffChars);
101 
102  protected:
104  IniChar_t* AllocBuffer(StrLen_t nSizeChars);
105  void AllocLines(ITERATE_t iLinesAlloc);
106 
107  IniChar_t* AllocBeginMin(StrLen_t nSizeChars);
108 
109  public:
110  cIniSectionData(bool bStripComments = false) noexcept;
111  virtual ~cIniSectionData();
112  void DisposeThis();
113 
114  bool isStripped() const noexcept
115  {
117  return m_bStripComments;
118  }
119 
120  StrLen_t get_BufferUsed() const noexcept
121  {
123  if (m_iLinesUsed <= 0)
124  return 0;
125  return m_iBufferUsed;
126  }
127  StrLen_t get_BufferSize() const noexcept
128  {
130  if (m_iLinesUsed <= 0)
131  return 0;
132  return (StrLen_t)m_Buffer.get_DataSize();
133  }
134 
135  ITERATE_t get_LineQty() const noexcept
136  {
138  return m_iLinesUsed;
139  }
140  IniChar_t* GetLineEnum(ITERATE_t iLine = 0) const noexcept
141  {
145  if (IS_INDEX_BAD(iLine, m_iLinesUsed))
146  return nullptr;
147  return m_ppLines[iLine];
148  }
149 
150  static StrLen_t GRAYCALL IsLineTrigger(const IniChar_t* pszLine);
151  ITERATE_t FindTriggerName(const IniChar_t* pszTrigName) const;
152 
153  virtual HRESULT PropEnum(IPROPIDX_t ePropIdx, OUT cStringI& rsValue, cStringI* psKey = nullptr) const override;
154  void ClearLineQty();
155 
156  ITERATE_t FindKeyLine(const IniChar_t* pszKeyName, bool bPrefixOnly = false) const;
157  const IniChar_t* FindKeyLinePtr(const IniChar_t* pszKey) const;
158  const IniChar_t* FindArgForKey(const IniChar_t* pszKey, const IniChar_t* pszDefault = nullptr) const;
159  int FindIntForKey(const IniChar_t* pszKey, int iDefault = 0) const;
160 
161  virtual HRESULT PropGet(const IniChar_t* pszPropTag, OUT cStringI& rsValue) const override;
162 
163  bool IsValidLines() const;
164  void SetLinesCopy(const cIniSectionData& section); // Dupe another section.
165  ITERATE_t AddLine(const IniChar_t* pszLine);
166  bool SetLine(ITERATE_t iLine, const IniChar_t* pszLine = nullptr);
167  bool RemoveLine(ITERATE_t iLine)
168  {
169  return SetLine(iLine, nullptr);
170  }
171 
172  static StrLen_t GRAYCALL MakeLine(IniChar_t* pszTmp, StrLen_t iSizeMax, const IniChar_t* pszKey, const IniChar_t* pszArg, IniChar_t chSep = '=');
173 
174  ITERATE_t AddKeyArg(const IniChar_t* pszKey, const IniChar_t* pszArg);
175  ITERATE_t AddKeyInt(const IniChar_t* pszKey, int iArg)
176  {
177  return AddKeyArg(pszKey, StrArg<IniChar_t>(iArg));
178  }
179  ITERATE_t SetKeyArg(const IniChar_t* pszKey, const IniChar_t* pszArg);
180  ITERATE_t SetKeyInt(const IniChar_t* pszKey, int iArg)
181  {
182  return SetKeyArg(pszKey, StrArg<IniChar_t>(iArg));
183  }
184  void AllocComplete();
185  virtual HRESULT PropSet(const IniChar_t* pszPropTag, const IniChar_t* pszValue) override;
186 
187  StrLen_t SetLinesParse(const IniChar_t* pszData, StrLen_t iLen = k_StrLen_UNK, const IniChar_t* pszSep = nullptr, STRP_MASK_t uFlags = (STRP_START_WHITE | STRP_MERGE_CRNL | STRP_END_WHITE | STRP_EMPTY_STOP));
188  cStringA GetStringAll(const IniChar_t* pszSep = nullptr) const;
189 
190  HRESULT ReadSectionData(cStringA& rsSectionNext, cStreamInput& stream, bool bStripComments);
191  HRESULT WriteSectionData(cStreamOutput& file);
192  };
193 
195  {
198  typedef cIniSectionData SUPER_t;
199 
200  protected:
202 
203  public:
204  cIniSection(bool bStripComments = false) noexcept
205  : cIniSectionData(bStripComments)
206  {
207  }
208  cIniSection(cStringI sSectionTitle, bool bStripComments = false)
209  : cIniSectionData(bStripComments)
210  , m_sSectionTitle(sSectionTitle)
211  {
212  }
213  cIniSection(const cIniSection& rSectionCopy);
214 
215  const cStringI& get_SectionTitle() const noexcept
216  {
218  return m_sSectionTitle;
219  }
220  cString get_Name() const noexcept
221  {
222  return cString(get_SectionTitle());
223  }
224 
225  static cStringI GRAYCALL GetSectionTitleParse(cStringI sSectionTitle, cStringI* psPropTag);
226 
227  static bool GRAYCALL IsSectionTypeRoot(const IniChar_t* pszSection) noexcept
228  {
230  return StrT::IsNullOrEmpty(pszSection);
231  }
232  static bool GRAYCALL IsSectionTypeMatch(const IniChar_t* pszSection1, const IniChar_t* pszSection2) noexcept;
233 
234  HRESULT WriteSection(cStreamOutput& file);
235 
236  bool IsSectionType(const IniChar_t* pszSectionType) const noexcept
237  {
238  return IsSectionTypeMatch(m_sSectionTitle, pszSectionType);
239  }
241  };
242 
244  {
248 
249  public:
251 
252  public:
253  cIniSectionEntry(cStringI sSectionTitle, bool bStripComments = false, int iLine = 0)
254  : cIniSection(sSectionTitle, bStripComments)
255  , m_FilePos(0, iLine)
256  {
257  }
258  cIniSectionEntry(const cIniSectionEntry& rSectionCopy)
259  : cIniSection(rSectionCopy)
260  , m_FilePos(rSectionCopy.m_FilePos)
261  {
262  }
264  {
265  }
266 
267  int get_HashCode() const noexcept
268  {
269  return (int)m_FilePos.get_Line1();
270  }
271  };
273 };
274 
275 #endif
#define GRAYCORE_LINK
Definition: GrayCore.h:47
#define GRAYCALL
declare calling convention for static functions so everyone knows the arg passing scheme....
Definition: GrayCore.h:36
#define IS_INDEX_BAD(i, q)
cast the (likely) int to unsigned to check for negatives.
Definition: Index.h:34
INT32 HRESULT
_WIN32 style error codes. INT32
Definition: SysTypes.h:465
#define ASSERT(exp)
Definition: cDebugAssert.h:87
#define UNITTEST_FRIEND(n)
Define this in the class body to be unit tested. Allow the unit test to access private/protected stuf...
Definition: cUnitTestDecl.h:17
Definition: cHeap.h:156
Definition: cIniFile.h:22
Definition: cIniSection.h:71
bool m_bStripComments
has been stripped of blank lines, comments, leading and trailing line spaces.
Definition: cIniSection.h:89
StrLen_t get_BufferSize() const noexcept
Definition: cIniSection.h:127
ITERATE_t get_LineQty() const noexcept
Definition: cIniSection.h:135
IniChar_t * GetLineEnum(ITERATE_t iLine=0) const noexcept
Definition: cIniSection.h:140
ITERATE_t AddKeyInt(const IniChar_t *pszKey, int iArg)
Definition: cIniSection.h:175
ITERATE_t SetKeyInt(const IniChar_t *pszKey, int iArg)
Definition: cIniSection.h:180
StrLen_t get_BufferUsed() const noexcept
Definition: cIniSection.h:120
bool RemoveLine(ITERATE_t iLine)
Definition: cIniSection.h:167
Definition: cIniSection.h:244
int get_HashCode() const noexcept
Definition: cIniSection.h:267
virtual ~cIniSectionEntry()
Definition: cIniSection.h:263
cTextPos m_FilePos
Where in parent/source file is this? for error reporting. 1 based. ITERATE_t.
Definition: cIniSection.h:250
cIniSectionEntry(const cIniSectionEntry &rSectionCopy)
Definition: cIniSection.h:258
cIniSectionEntry(cStringI sSectionTitle, bool bStripComments=false, int iLine=0)
Definition: cIniSection.h:253
Definition: cIniSection.h:195
cStringI m_sSectionTitle
"SECTIONTYPE SECTIONNAME" = everything that was inside [] without the []
Definition: cIniSection.h:201
const cStringI & get_SectionTitle() const noexcept
Definition: cIniSection.h:215
cIniSection(cStringI sSectionTitle, bool bStripComments=false)
Definition: cIniSection.h:208
cString get_Name() const noexcept
Definition: cIniSection.h:220
static bool __stdcall IsSectionTypeRoot(const IniChar_t *pszSection) noexcept
Definition: cIniSection.h:227
bool IsSectionType(const IniChar_t *pszSectionType) const noexcept
Definition: cIniSection.h:236
cIniSection(bool bStripComments=false) noexcept
Definition: cIniSection.h:204
Definition: cIniSection.h:24
bool m_bStartedSection
Must write a newline to close the previous section when we start a new one.
Definition: cIniSection.h:31
cIniWriter(cStreamOutput *pOut)
Definition: cIniSection.h:34
cStreamOutput * m_pOut
write out to this stream.
Definition: cIniSection.h:30
size_t get_DataSize() const noexcept
Definition: cMem.h:344
Definition: cRefPtr.h:22
Definition: cRefPtr.h:225
Definition: cStream.h:306
Definition: cStream.h:126
Definition: cTextPos.h:18
ITERATE_t get_Line1() const noexcept
< Get 1 based line.
Definition: cTextPos.h:69
< The main namespace for all Core functions.
Definition: GrayCore.cpp:14
const StrLen_t k_StrLen_UNK
use the default/current length of the string argument.
Definition: StrConst.h:34
int StrLen_t
the length of a string in chars (bytes for UTF8, wchar_t for UNICODE). or offset in characters....
Definition: StrConst.h:32
UINT32 STRP_MASK_t
bit mask of STRP_TYPE_
Definition: StrT.h:64
class __DECL_IMPORT cStreamOutput
Definition: cString.h:27
@ STRP_END_WHITE
trim end whitespace off token.
Definition: StrT.h:55
@ STRP_MERGE_CRNL
merge "\r\n" (may also be separators.) (newline = linefeed)
Definition: StrT.h:59
@ STRP_EMPTY_STOP
Stop when we hit an empty token.
Definition: StrT.h:61
@ STRP_START_WHITE
remove start whitespace from each token
Definition: StrT.h:53
int ITERATE_t
like size_t but signed
Definition: Index.h:28
char IniChar_t
char format even on UNICODE system! Screw M$, INI files should ALWAYS have UTF8 contents
Definition: cIniBase.h:17
int IPROPIDX_t
enumerate known properties for some interface/object/class. similar to SCRIPTPROPID_t
Definition: cIniBase.h:16
cRefPtr< cIniSectionEntry > cIniSectionEntryPtr
Definition: cIniSection.h:272
cStringT< GChar_t > cString
Definition: cString.h:636
Definition: cIniBase.h:35
Definition: cIniBase.h:28
Definition: cIniBase.h:21
static bool IsNullOrEmpty(const TYPE *pszStr) noexcept
Definition: StrT.h:102
Definition: cIniSection.h:53