OpenClonk
StdCompiler.h
Go to the documentation of this file.
1 /*
2  * OpenClonk, http://www.openclonk.org
3  *
4  * Copyright (c) 2001-2009, RedWolf Design GmbH, http://www.clonk.de/
5  * Copyright (c) 2009-2016, The OpenClonk Team and contributors
6  *
7  * Distributed under the terms of the ISC license; see accompanying file
8  * "COPYING" for details.
9  *
10  * "Clonk" is a registered trademark of Matthes Bender, used with permission.
11  * See accompanying file "TRADEMARK" for details.
12  *
13  * To redistribute this file separately, substitute the full license texts
14  * for the above references.
15  */
16 #ifndef STDCOMPILER_H
17 #define STDCOMPILER_H
18 
19 // Try to avoid casting NotFoundExceptions for trivial cases (MSVC log flood workaround)
20 #if defined(_MSC_VER)
21 #define STDCOMPILER_EXCEPTION_WORKAROUND
22 #endif
23 
24 // Provides an interface of generalized compiling/decompiling
25 // (serialization/deserialization - note that the term "compile" is used for both directions)
26 
27 // The interface is designed to allow both text-type (INI) and binary
28 // compilation. Structures that want to support StdCompiler must provide
29 // a function "void CompileFunc(StdCompiler *)" and therein issue calls
30 // to the data, naming and separation functions as appropriate. If the structure
31 // in question cannot be changed, it is equally valid to define a function
32 // void CompileFunc(StdCompiler *, T *) where T is the type of the structure.
33 
34 // Most details can be hidden inside adaptors (see StdAdaptors.h), so
35 // the structure can re-use common compiling patterns (namings, arrays...).
36 
38 {
39 
40 public:
41 
42  StdCompiler() = default;
43 
44  // *** Overridables (Interface)
45  virtual ~StdCompiler() = default;
46 
47  // * Properties
48 
49  // Needs two passes? Binary compiler uses this for calculating the size.
50  virtual bool isDoublePass() { return false; }
51 
52  // Changes the target?
53  virtual bool isDeserializer() { return false; }
54  inline bool isSerializer() { return !isDeserializer(); }
55 
56  // Does the compiler support naming, so values can be omitted without harm to
57  // the data structure? Is separation implemented?
58  virtual bool hasNaming() { return false; }
59 
60  // Does the compiler encourage verbosity (like producing more text instead of
61  // just a numerical value)?
62  virtual bool isVerbose() { return hasNaming(); }
63 
64  // Is it a registry compiler with special handling for arrays?
65  virtual bool isRegistry() { return false; }
66 
67  // callback by runtime-write-allowed adaptor used by compilers that may set runtime values only
68  virtual void setRuntimeWritesAllowed(int32_t iChange) { }
69 
70  // * Naming
71  // Provides extra data for the compiler so he can deal with reordered data.
72  // Note that sections stack and each section will get compiled only once.
73  // StartSection won't fail if the naming isn't found while compiling. Name and
74  // all value compiling functions will fail, though.
75  // Set the NameEnd parameter to true if you are stopping to parse the structure
76  // for whatever reason (suppress warning messages).
77  virtual bool Name(const char *szName) { return true; }
78  virtual void NameEnd(bool fBreak = false) { }
79  virtual const char *GetNameByIndex(size_t idx) const { return nullptr; }
80 
81  // Special: A naming that follows to the currently active naming (on the same level).
82  // Note this will end the current naming, so no additional NameEnd() is needed.
83  // Only used to maintain backwards compatibility, should not be used in new code.
84  virtual bool FollowName(const char *szName) { NameEnd(); return Name(szName); }
85 
86  // Called when a named value omitted because of defaulting (compiler only)
87  // Returns whether the value has been handled
88  virtual bool Default(const char *szName) { return true; }
89 
90  // Return count of sub-namings. May be unimplemented.
91  virtual int NameCount(const char *szName = nullptr) { assert(false); return 0; }
92 
93 
94  // * Separation
95  // Some data types need separation (note that naming makes this unnecessary).
96  // Compilers that implement naming must implement separation. Others may just
97  // always return success.
98  // If a separator wasn't found, some compilers might react by throwing a
99  // NotFound exception for all attempts to read a value. This behaviour will
100  // stop when NoSeparator() is called (which just resets this state) or
101  // Separator() is called successfully. This behaviour will reset after
102  // ending the naming, too.
103  enum Sep
104  {
105  SEP_NONE=0, // No separator ("")
106  SEP_SEP, // Array separation (",")
107  SEP_SEP2, // Array separation 2 (";")
108  SEP_SET, // Map pair separation ("=")
109  SEP_PART, // Value part separation (".")
110  SEP_PART2, // Value part separation 2 (":")
111  SEP_PLUS, // Value separation with a '+' char ("+")
112  SEP_START, // Start some sort of list ('(')
113  SEP_END, // End some sort of list ('(')
114  SEP_START2, // Start some sort of list ('[')
115  SEP_END2, // End some sort of list (']')
116  SEP_VLINE, // Vertical line separator ('|')
117  SEP_DOLLAR // Dollar sign ('$')
118  };
119  virtual bool Separator(Sep eSep = SEP_SEP) { return true; }
120  virtual void NoSeparator() { }
121 
122  // * Data
123  // Compiling functions for different data types
124  virtual void DWord(int32_t &rInt) = 0; // Needs separator!
125  virtual void DWord(uint32_t &rInt) = 0; // Needs separator!
126  virtual void Word(int16_t &rShort) = 0; // Needs separator!
127  virtual void Word(uint16_t &rShort) = 0; // Needs separator!
128  virtual void Byte(int8_t &rByte) = 0; // Needs separator!
129  virtual void Byte(uint8_t &rByte) = 0; // Needs separator!
130  virtual void Boolean(bool &rBool) = 0;
131  virtual void Character(char &rChar) = 0; // Alphanumerical only!
132 
133 
134  // Compile raw data (strings)
136  {
137  RCT_Escaped=0,// Any data allowed, no separator needed (default)
138  RCT_All, // Printable characters only, must be last element in naming.
139  RCT_Idtf, // Alphanumerical characters or '_', separator needed.
140  RCT_IdtfAllowEmpty, // Like RCT_Idtf, but empty strings are also allowed
141  RCT_ID // Like RCT_Idtf (only used for special compilers that treat IDs differently)
142  };
143  // Note that string won't allow '\0' inside the buffer, even with escaped compiling!
144  virtual void String(char *szString, size_t iMaxLength, RawCompileType eType = RCT_Escaped) = 0;
145  virtual void String(char **pszString, RawCompileType eType = RCT_Escaped) = 0;
146  virtual void String(std::string &str, RawCompileType type = RCT_Escaped) = 0;
147  virtual void Raw(void *pData, size_t iSize, RawCompileType eType = RCT_Escaped) = 0;
148 
149  // * Position
150  // May return information about the current position of compilation (used for errors and warnings)
151  virtual StdStrBuf getPosition() const { return StdStrBuf(); }
152 
153  // * Passes
154  virtual void Begin() { }
155  virtual void BeginSecond() { }
156  virtual void End() { }
157 
158  // *** Composed
159 
160  // Generic compiler function (plus specializations)
161  template <class T> void Value(const T &rStruct) { rStruct.CompileFunc(this); }
162  template <class T> void Value(T &rStruct) { CompileFunc(rStruct, this); }
163 
164  void Value(int32_t &rInt) { DWord(rInt); }
165  void Value(uint32_t &rInt) { DWord(rInt); }
166  void Value(int16_t &rInt) { Word(rInt); }
167  void Value(uint16_t &rInt) { Word(rInt); }
168  void Value(int8_t &rInt) { Byte(rInt); }
169  void Value(uint8_t &rInt) { Byte(rInt); }
170  void Value(bool &rBool) { Boolean(rBool); }
171 
172  // Compiling/Decompiling (may throw a data format exception!)
173  template <class T> inline void Compile(T &&rStruct)
174  {
175  assert(isDeserializer());
176  DoCompilation(rStruct);
177  }
178  template <class T> inline void Decompile(const T &rStruct)
179  {
180  assert(!isDeserializer());
181  DoCompilation(const_cast<T &>(rStruct));
182  }
183 
184 protected:
185 
186  // Compilation process
187  template <class T>
188  inline void DoCompilation(T &rStruct)
189  {
190  // Start compilation, do first pass
191  Begin();
192  Value(rStruct);
193  // Second pass needed?
194  if (isDoublePass())
195  {
196  BeginSecond();
197  Value(rStruct);
198  }
199  // Finish
200  End();
201  }
202 
203 public:
204 
205  // Compiler exception - thrown when something is wrong with the data to compile
206  struct Exception
207  {
210 protected:
211  Exception(StdStrBuf Pos, StdStrBuf Msg) : Pos(std::move(Pos)), Msg(std::move(Msg)) { }
212 private:
213  // do not copy
214  Exception(const Exception &Exc) { }
215  };
217  {
218  friend class StdCompiler;
220  };
221  class EOFException : public Exception
222  {
223  friend class StdCompiler;
225  };
227  {
228  friend class StdCompiler;
230  };
231 
232  // Throw helpers (might redirect)
233  void excNotFound(const char *szMessage, ...)
234  {
235 #ifdef STDCOMPILER_EXCEPTION_WORKAROUND
236  // Exception workaround: Just set a flag in failesafe mode.
237  if (fFailSafe) { fFail = true; return; }
238 #endif
239  // Throw the appropriate exception
240  va_list args; va_start(args, szMessage);
241  throw new NotFoundException(getPosition(), FormatStringV(szMessage, args));
242  }
243  void excEOF(const char *szMessage = "EOF", ...)
244  {
245  // Throw the appropriate exception
246  va_list args; va_start(args, szMessage);
247  throw new EOFException(getPosition(), FormatStringV(szMessage, args));
248  }
249  void excCorrupt(const char *szMessage, ...)
250  {
251  // Throw the appropriate exception
252  va_list args; va_start(args, szMessage);
253  throw new CorruptException(getPosition(), FormatStringV(szMessage, args));
254  }
255 
256 protected:
257 
258  // Exception workaround
259 #ifdef STDCOMPILER_EXCEPTION_WORKAROUND
260  bool fFailSafe{false}, fFail{false};
261 
262  void beginFailSafe() { fFailSafe = true; fFail = false; }
263  bool endFailSafe() { fFailSafe = false; return !fFail; }
264 
265 public:
266  template <class T> bool ValueSafe(const T &rStruct) { rStruct.CompileFunc(this); return true; }
267  template <class T> bool ValueSafe(T &rStruct) { CompileFunc(rStruct, this); return true; }
268 
269  bool ValueSafe(int32_t &rInt) { beginFailSafe(); DWord(rInt); return endFailSafe(); }
270  bool ValueSafe(uint32_t &rInt) { beginFailSafe(); DWord(rInt); return endFailSafe(); }
271  bool ValueSafe(int16_t &rInt) { beginFailSafe(); Word(rInt); return endFailSafe(); }
272  bool ValueSafe(uint16_t &rInt) { beginFailSafe(); Word(rInt); return endFailSafe(); }
273  bool ValueSafe(int8_t &rInt) { beginFailSafe(); Byte(rInt); return endFailSafe(); }
274  bool ValueSafe(uint8_t &rInt) { beginFailSafe(); Byte(rInt); return endFailSafe(); }
275  bool ValueSafe(bool &rBool) { beginFailSafe(); Boolean(rBool); return endFailSafe(); }
276 #endif
277 
278 public:
279 
280  // * Warnings
281  typedef void (*WarnCBT)(void *, const char *, const char *);
282  void setWarnCallback(WarnCBT pnWarnCB, void *pData) { pWarnCB = pnWarnCB; pWarnData = pData; }
283  void Warn(const char *szWarning, ...);
284 
285 private:
286 
287  // Warnings
288  WarnCBT pWarnCB{nullptr};
289  void *pWarnData{nullptr};
290 
291 protected:
292 
293  // Standard separator character
294  static char SeparatorToChar(Sep eSep);
295  // String end test depending on encoding type
296  static bool IsStringEnd(char c, RawCompileType eType);
297 };
298 
299 // Standard compile funcs
300 template <class T>
301 inline void CompileFunc(T &rStruct, StdCompiler *pComp)
302 {
303  // If the compiler doesn't like this line, you tried to compile
304  // something the compiler doesn't know how to handle.
305  // Possible reasons:
306  // a) You are compiling a class/structure without a CompileFunc
307  // (you may add a specialization of this function, too)
308  // b) You are trying to compile a pointer. Use a PtrAdapt instead.
309  // c) You are trying to compile a simple value that has no
310  // fixed representation (float, int). Use safe types instead.
311  rStruct.CompileFunc(pComp);
312 }
313 
314 inline void CompileFunc(std::string &s, StdCompiler *comp)
315 {
316  comp->String(s);
317 }
318 
319 template <class T>
320 void CompileNewFunc(T *&pStruct, StdCompiler *pComp)
321 {
322  // Create new object.
323  // If this line doesn't compile, you either have to
324  // a) Define a standard constructor for T
325  // b) Specialize this function to do whatever the correct
326  // behaviour is to construct the object from compiler data
327  std::unique_ptr<T> temp(new T); // exception-safety
328  // Compile
329  pComp->Value(*temp);
330  pStruct = temp.release();
331 }
332 
333 template <class T, typename ... P>
334 void CompileNewFunc(T *&pStruct, StdCompiler *pComp, P && ... pars)
335 {
336  // Create new object.
337  // If this line doesn't compile, you either have to
338  // a) Define a standard constructor for T
339  // b) Specialize this function to do whatever the correct
340  // behaviour is to construct the object from compiler data
341  std::unique_ptr<T> temp(new T); // exception-safety
342  // Compile
343  pComp->Value(mkParAdapt(*temp, std::forward<P>(pars)...));
344  pStruct = temp.release();
345 }
346 
347 template <class T, class ContextT>
348 void CompileNewFuncCtx(T *&pStruct, StdCompiler *pComp, const ContextT& rCtx)
349 {
350  // Create new object.
351  // If this line doesn't compile, you either have to
352  // a) Define an appropriate constructor for T
353  // b) Specialize this function to do whatever the correct
354  // behaviour is to construct the object from compiler data
355  // and context
356  std::unique_ptr<T> temp(new T(rCtx)); // exception-safety
357  // Compile
358  pComp->Value(*temp);
359  pStruct = temp.release();
360 }
361 
362 template <class T, class ContextT, class P>
363 void CompileNewFuncCtx(T *&pStruct, StdCompiler *pComp, const ContextT& rCtx, const P& rPar)
364 {
365  // Create new object.
366  // If this line doesn't compile, you either have to
367  // a) Define an appropriate constructor for T
368  // b) Specialize this function to do whatever the correct
369  // behaviour is to construct the object from compiler data
370  // and context
371  std::unique_ptr<T> temp(new T(rCtx)); // exception-safety
372  // Compile
373  pComp->Value(mkParAdapt(*temp, rPar));
374  pStruct = temp.release();
375 }
376 
377 // Helpers for buffer-based compiling (may throw a data format exception!)
378 template <class CompT, class StructT>
379 void CompileFromBuf(StructT &&TargetStruct, const typename CompT::InT &SrcBuf)
380 {
381  CompT Compiler;
382  Compiler.setInput(SrcBuf.getRef());
383  Compiler.Compile(TargetStruct);
384 }
385 template <class CompT, class StructT>
386 StructT * CompileFromBufToNew(const typename CompT::InT &SrcBuf)
387 {
388  StructT *pStruct = nullptr;
389  CompileFromBuf<CompT>(mkPtrAdaptNoNull(pStruct), SrcBuf);
390  return pStruct;
391 }
392 template <class CompT, class StructT>
393 StructT * CompileFromBufToNewNamed(const typename CompT::InT &SrcBuf, const char *szName)
394 {
395  StructT *pStruct = nullptr;
396  CompileFromBuf<CompT>(mkNamingAdapt(mkPtrAdaptNoNull(pStruct), szName), SrcBuf);
397  return pStruct;
398 }
399 template <class CompT, class StructT>
400 typename CompT::OutT DecompileToBuf(const StructT &SrcStruct)
401 {
402  CompT Compiler;
403  Compiler.Decompile(SrcStruct);
404  return Compiler.getOutput();
405 }
406 
407 // *** Null compiler
408 
409 // Naming supported, nothing is returned. Used for setting default values.
410 
412 {
413 public:
414 
415  // Properties
416  bool isDeserializer() override { return true; }
417  bool hasNaming() override { return true; }
418 
419  // Naming
420  bool Name(const char *szName) override { return false; }
421  int NameCount(const char *szName = nullptr) override { return 0; }
422 
423  // Data readers
424  void DWord(int32_t &rInt) override { }
425  void DWord(uint32_t &rInt) override { }
426  void Word(int16_t &rShort) override { }
427  void Word(uint16_t &rShort) override { }
428  void Byte(int8_t &rByte) override { }
429  void Byte(uint8_t &rByte) override { }
430  void Boolean(bool &rBool) override { }
431  void Character(char &rChar) override { }
432  void String(char *szString, size_t iMaxLength, RawCompileType eType = RCT_Escaped) override { }
433  void String(char **pszString, RawCompileType eType = RCT_Escaped) override { }
434  void String(std::string &str, RawCompileType eType = RCT_Escaped) override {}
435  void Raw(void *pData, size_t iSize, RawCompileType eType = RCT_Escaped) override { }
436 };
437 
438 // *** Binary compiler
439 
440 // No naming supported, everything is read/written binary.
441 
442 
443 // binary writer
445 {
446 public:
447 
448  // Result
449  typedef StdBuf OutT;
450  inline OutT getOutput() { return Buf; }
451 
452  // Properties
453  bool isDoublePass() override { return true; }
454 
455  // Data writers
456  void DWord(int32_t &rInt) override;
457  void DWord(uint32_t &rInt) override;
458  void Word(int16_t &rShort) override;
459  void Word(uint16_t &rShort) override;
460  void Byte(int8_t &rByte) override;
461  void Byte(uint8_t &rByte) override;
462  void Boolean(bool &rBool) override;
463  void Character(char &rChar) override;
464  void String(char *szString, size_t iMaxLength, RawCompileType eType = RCT_Escaped) override;
465  void String(char **pszString, RawCompileType eType = RCT_Escaped) override;
466  void String(std::string &str, RawCompileType eType = RCT_Escaped) override;
467  void Raw(void *pData, size_t iSize, RawCompileType eType = RCT_Escaped) override;
468 
469  // Passes
470  void Begin() override;
471  void BeginSecond() override;
472 
473 protected:
474  // Process data
476  int iPos;
478 
479  // Helpers
480  template <class T> void WriteValue(const T &rValue);
481  void WriteData(const void *pData, size_t iSize);
482 };
483 
484 // binary read
486 {
487 public:
488 
489  // Input
490  typedef StdBuf InT;
491  void setInput(InT &&In) { Buf = std::move(In); }
492 
493  // Properties
494  bool isDeserializer() override { return true; }
495 
496  // Data readers
497  void DWord(int32_t &rInt) override;
498  void DWord(uint32_t &rInt) override;
499  void Word(int16_t &rShort) override;
500  void Word(uint16_t &rShort) override;
501  void Byte(int8_t &rByte) override;
502  void Byte(uint8_t &rByte) override;
503  void Boolean(bool &rBool) override;
504  void Character(char &rChar) override;
505  void String(char *szString, size_t iMaxLength, RawCompileType eType = RCT_Escaped) override;
506  void String(char **pszString, RawCompileType eType = RCT_Escaped) override;
507  void String(std::string &str, RawCompileType eType = RCT_Escaped) override;
508  void Raw(void *pData, size_t iSize, RawCompileType eType = RCT_Escaped) override;
509 
510  // Position
511  StdStrBuf getPosition() const override;
512 
513  // Passes
514  void Begin() override;
515 
516  // Data
517  size_t getPosition() { return iPos; }
518  size_t getRemainingBytes() { return Buf.getSize() - iPos; }
519 
520 protected:
521  // Process data
522  size_t iPos;
524 
525  // Helper
526  template <class T> void ReadValue(T &rValue);
527 };
528 
529 // *** INI compiler
530 
531 // Naming and separators supported, so defaulting can be used through
532 // the appropriate adaptors.
533 
534 // Example:
535 
536 // [Sect1]
537 // [Sect1a]
538 // Val1=4
539 // Val2=5
540 // Val4=3,5
541 
542 // will result from:
543 
544 // int v1=4, v2=5, v3=0, v4[3] = { 3, 5, 0 };
545 // DecompileToBuf<StdCompilerINIWrite>(
546 // mkNamingAdapt(
547 // mkNamingAdapt(
548 // mkNamingAdapt(v1, "Val1", 0) +
549 // mkNamingAdapt(v2, "Val2", 0) +
550 // mkNamingAdapt(v3, "Val3", 0),
551 // "Sect1a") +
552 // mkNamingAdapt(mkArrayAdapt(v4, 3, 0), "Val4", 0),
553 // "Sect1")
554 // )
555 
556 
557 // text writer
559 {
560 public:
561  // Input
562  typedef StdStrBuf OutT;
563  inline OutT getOutput() { return Buf; }
564 
565  // Properties
566  bool hasNaming() override { return true; }
567 
568  // Naming
569  bool Name(const char *szName) override;
570  void NameEnd(bool fBreak = false) override;
571 
572  // Separators
573  bool Separator(Sep eSep) override;
574 
575  // Data writers
576  void DWord(int32_t &rInt) override;
577  void DWord(uint32_t &rInt) override;
578  void Word(int16_t &rShort) override;
579  void Word(uint16_t &rShort) override;
580  void Byte(int8_t &rByte) override;
581  void Byte(uint8_t &rByte) override;
582  void Boolean(bool &rBool) override;
583  void Character(char &rChar) override;
584  void StringN(const char *szString, size_t iMaxLength, RawCompileType eType = RCT_Escaped);
585  void String(char *szString, size_t iMaxLength, RawCompileType eType = RCT_Escaped) override;
586  void String(char **pszString, RawCompileType eType = RCT_Escaped) override;
587  void String(std::string &str, RawCompileType eType = RCT_Escaped) override;
588  void Raw(void *pData, size_t iSize, RawCompileType eType = RCT_Escaped) override;
589 
590  // Passes
591  void Begin() override;
592  void End() override;
593 
594 protected:
595 
596  // Result
598 
599  // Naming stack
600  struct Naming
601  {
604  };
606  // Recursion depth
607  int iDepth;
608 
609  // Name not put yet (it's not clear wether it is a value or a section)
610  bool fPutName,
611  // Currently inside a section, so raw data can't be printed
613 
614  void PrepareForValue();
615  void WriteEscaped(const char *szString, const char *pEnd);
616  void WriteIndent(bool fSectionName);
617  void PutName(bool fSection);
618 };
619 
620 // text reader
622 {
623 public:
624 
626  ~StdCompilerINIRead() override;
627 
628  // Input
629  typedef StdStrBuf InT;
630  void setInput(const InT &In) { Buf.Ref(In); lineBreaks.clear(); }
631 
632  // Properties
633  bool isDeserializer() override { return true; }
634  bool hasNaming() override { return true; }
635 
636  // Naming
637  bool Name(const char *szName) override;
638  void NameEnd(bool fBreak = false) override;
639  bool FollowName(const char *szName) override;
640  const char *GetNameByIndex(size_t idx) const override;
641 
642  // Separators
643  bool Separator(Sep eSep) override;
644  void NoSeparator() override;
645 
646  // Counters
647  int NameCount(const char *szName = nullptr) override;
648 
649  // Data writers
650  void DWord(int32_t &rInt) override;
651  void DWord(uint32_t &rInt) override;
652  void Word(int16_t &rShort) override;
653  void Word(uint16_t &rShort) override;
654  void Byte(int8_t &rByte) override;
655  void Byte(uint8_t &rByte) override;
656  void Boolean(bool &rBool) override;
657  void Character(char &rChar) override;
658  void String(char *szString, size_t iMaxLength, RawCompileType eType = RCT_Escaped) override;
659  void String(char **pszString, RawCompileType eType = RCT_Escaped) override;
660  void String(std::string &str, RawCompileType eType = RCT_Escaped) override;
661  void Raw(void *pData, size_t iSize, RawCompileType eType = RCT_Escaped) override;
662 
663  // Position
664  StdStrBuf getPosition() const override;
665 
666  // Passes
667  void Begin() override;
668  void End() override;
669 
670 protected:
671 
672  // * Data
673 
674  // Name tree
675  struct NameNode
676  {
677  // Name
679  // Section?
680  bool Section{false};
681  // Tree structure
683  *FirstChild{nullptr}, *PrevChild{nullptr}, *NextChild{nullptr}, *LastChild{nullptr};
684  // Indent level
685  int Indent{-1};
686  // Name number in parent map
687  const char *Pos{nullptr};
688  // Constructor
689  NameNode(NameNode *pParent = nullptr) :
690  Parent(pParent)
691  { }
692  };
693  NameNode *pNameRoot{nullptr}, *pName;
694  // Current depth
695  int iDepth{0};
696  // Real depth (depth of recursive Name()-calls - if iDepth != iRealDepth, we are in a nonexistant namespace)
697  int iRealDepth{0};
698 
699  // Data
701  // Position
702  const char *pPos;
703 
704  // Reenter position (if an nonexistant separator was specified)
705  const char *pReenter;
706 
707  // Uppermost name that wasn't found
709 
710  // * Implementation
711 
712  // Name tree
713  void CreateNameTree();
714  void FreeNameTree();
715  void FreeNameNode(NameNode *pNode);
716 
717  // Navigation
718  void SkipWhitespace();
719  void SkipNum();
720  long ReadNum();
721  size_t GetStringLength(RawCompileType eTyped);
722  StdBuf ReadString(size_t iLength, RawCompileType eTyped, bool fAppendNull = true);
723  bool TestStringEnd(RawCompileType eType) { return IsStringEnd(*pPos, eType); }
724  char ReadEscapedChar();
725  unsigned long ReadUNum();
726 
727  void notFound(const char *szWhat);
728 
729 private:
730  uint32_t getLineNumberOfPos(const char *pos) const;
731  mutable std::vector<const char *> lineBreaks;
732 };
733 
734 void StdCompilerWarnCallback(void *pData, const char *szPosition, const char *szError);
735 
736 template <class CompT, class StructT>
737 bool CompileFromBuf_Log(StructT &&TargetStruct, const typename CompT::InT &SrcBuf, const char *szName)
738 {
739  try
740  {
741  CompileFromBuf<CompT>(TargetStruct, SrcBuf);
742  return true;
743  }
744  catch (StdCompiler::Exception *pExc)
745  {
746  if (!pExc->Pos.getLength())
747  LogF("ERROR: %s (in %s)", pExc->Msg.getData(), szName);
748  else
749  LogF("ERROR: %s (in %s, %s)", pExc->Msg.getData(), pExc->Pos.getData(), szName);
750  delete pExc;
751  return false;
752  }
753 }
754 template <class CompT, class StructT>
755 bool CompileFromBuf_LogWarn(StructT &&TargetStruct, const typename CompT::InT &SrcBuf, const char *szName)
756 {
757  try
758  {
759  CompT Compiler;
760  Compiler.setInput(SrcBuf.getRef());
761  Compiler.setWarnCallback(StdCompilerWarnCallback, reinterpret_cast<void *>(const_cast<char *>(szName)));
762  Compiler.Compile(TargetStruct);
763  return true;
764  }
765  catch (StdCompiler::Exception *pExc)
766  {
767  if (!pExc->Pos.getLength())
768  LogF("ERROR: %s (in %s)", pExc->Msg.getData(), szName);
769  else
770  LogF("ERROR: %s (in %s, %s)", pExc->Msg.getData(), pExc->Pos.getData(), szName);
771  delete pExc;
772  return false;
773  }
774 }
775 template <class CompT, class StructT>
776 bool DecompileToBuf_Log(StructT &&TargetStruct, typename CompT::OutT *pOut, const char *szName)
777 {
778  if (!pOut) return false;
779  try
780  {
781  pOut->Take(DecompileToBuf<CompT>(TargetStruct));
782  return true;
783  }
784  catch (StdCompiler::Exception *pExc)
785  {
786  LogF("ERROR: %s (in %s)", pExc->Msg.getData(), szName);
787  delete pExc;
788  return false;
789  }
790 }
791 
792 #endif // STDCOMPILER_H
#define s
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:262
StdPtrAdapt< T > mkPtrAdaptNoNull(T *&rpObj)
Definition: StdAdaptors.h:638
StdParameterAdapt< T, P > mkParAdapt(T &&rObj, P &&rPar)
Definition: StdAdaptors.h:490
StdNamingAdapt< T > mkNamingAdapt(T &&rValue, const char *szName)
Definition: StdAdaptors.h:92
StdStrBuf FormatStringV(const char *szFmt, va_list args)
Definition: StdBuf.cpp:276
StructT * CompileFromBufToNewNamed(const typename CompT::InT &SrcBuf, const char *szName)
Definition: StdCompiler.h:393
void CompileNewFuncCtx(T *&pStruct, StdCompiler *pComp, const ContextT &rCtx)
Definition: StdCompiler.h:348
bool DecompileToBuf_Log(StructT &&TargetStruct, typename CompT::OutT *pOut, const char *szName)
Definition: StdCompiler.h:776
StructT * CompileFromBufToNew(const typename CompT::InT &SrcBuf)
Definition: StdCompiler.h:386
void CompileFunc(T &rStruct, StdCompiler *pComp)
Definition: StdCompiler.h:301
bool CompileFromBuf_LogWarn(StructT &&TargetStruct, const typename CompT::InT &SrcBuf, const char *szName)
Definition: StdCompiler.h:755
void CompileNewFunc(T *&pStruct, StdCompiler *pComp)
Definition: StdCompiler.h:320
bool CompileFromBuf_Log(StructT &&TargetStruct, const typename CompT::InT &SrcBuf, const char *szName)
Definition: StdCompiler.h:737
void StdCompilerWarnCallback(void *pData, const char *szPosition, const char *szError)
CompT::OutT DecompileToBuf(const StructT &SrcStruct)
Definition: StdCompiler.h:400
void CompileFromBuf(StructT &&TargetStruct, const typename CompT::InT &SrcBuf)
Definition: StdCompiler.h:379
int iSize
Definition: TstC4NetIO.cpp:32
Definition: StdBuf.h:30
size_t getSize() const
Definition: StdBuf.h:101
void ReadValue(T &rValue)
void setInput(InT &&In)
Definition: StdCompiler.h:491
void DWord(int32_t &rInt) override
void Raw(void *pData, size_t iSize, RawCompileType eType=RCT_Escaped) override
StdStrBuf getPosition() const override
void Begin() override
void Byte(int8_t &rByte) override
void String(char *szString, size_t iMaxLength, RawCompileType eType=RCT_Escaped) override
void Word(int16_t &rShort) override
size_t getRemainingBytes()
Definition: StdCompiler.h:518
size_t getPosition()
Definition: StdCompiler.h:517
bool isDeserializer() override
Definition: StdCompiler.h:494
void Character(char &rChar) override
void Boolean(bool &rBool) override
void DWord(int32_t &rInt) override
Definition: StdCompiler.cpp:68
void BeginSecond() override
void Boolean(bool &rBool) override
Definition: StdCompiler.cpp:74
void Begin() override
void String(char *szString, size_t iMaxLength, RawCompileType eType=RCT_Escaped) override
Definition: StdCompiler.cpp:76
bool isDoublePass() override
Definition: StdCompiler.h:453
void Byte(int8_t &rByte) override
Definition: StdCompiler.cpp:72
void WriteValue(const T &rValue)
Definition: StdCompiler.cpp:94
void WriteData(const void *pData, size_t iSize)
void Character(char &rChar) override
Definition: StdCompiler.cpp:75
void Raw(void *pData, size_t iSize, RawCompileType eType=RCT_Escaped) override
void Word(int16_t &rShort) override
Definition: StdCompiler.cpp:70
virtual void String(std::string &str, RawCompileType type=RCT_Escaped)=0
virtual void String(char **pszString, RawCompileType eType=RCT_Escaped)=0
void Decompile(const T &rStruct)
Definition: StdCompiler.h:178
void Value(int16_t &rInt)
Definition: StdCompiler.h:166
virtual void Raw(void *pData, size_t iSize, RawCompileType eType=RCT_Escaped)=0
virtual bool Separator(Sep eSep=SEP_SEP)
Definition: StdCompiler.h:119
virtual void BeginSecond()
Definition: StdCompiler.h:155
static bool IsStringEnd(char c, RawCompileType eType)
Definition: StdCompiler.cpp:53
void Value(bool &rBool)
Definition: StdCompiler.h:170
virtual void Character(char &rChar)=0
static char SeparatorToChar(Sep eSep)
Definition: StdCompiler.cpp:32
StdCompiler()=default
virtual bool Default(const char *szName)
Definition: StdCompiler.h:88
void Value(uint32_t &rInt)
Definition: StdCompiler.h:165
void excCorrupt(const char *szMessage,...)
Definition: StdCompiler.h:249
virtual void Word(int16_t &rShort)=0
virtual void NoSeparator()
Definition: StdCompiler.h:120
void Value(const T &rStruct)
Definition: StdCompiler.h:161
virtual void End()
Definition: StdCompiler.h:156
virtual void NameEnd(bool fBreak=false)
Definition: StdCompiler.h:78
virtual ~StdCompiler()=default
virtual void Byte(int8_t &rByte)=0
bool isSerializer()
Definition: StdCompiler.h:54
virtual bool isDoublePass()
Definition: StdCompiler.h:50
virtual void DWord(uint32_t &rInt)=0
virtual void Begin()
Definition: StdCompiler.h:154
void Value(uint16_t &rInt)
Definition: StdCompiler.h:167
void Value(int8_t &rInt)
Definition: StdCompiler.h:168
virtual StdStrBuf getPosition() const
Definition: StdCompiler.h:151
void Value(int32_t &rInt)
Definition: StdCompiler.h:164
void Value(T &rStruct)
Definition: StdCompiler.h:162
virtual bool FollowName(const char *szName)
Definition: StdCompiler.h:84
void Value(uint8_t &rInt)
Definition: StdCompiler.h:169
void DoCompilation(T &rStruct)
Definition: StdCompiler.h:188
virtual bool isVerbose()
Definition: StdCompiler.h:62
void(* WarnCBT)(void *, const char *, const char *)
Definition: StdCompiler.h:281
virtual void String(char *szString, size_t iMaxLength, RawCompileType eType=RCT_Escaped)=0
virtual void DWord(int32_t &rInt)=0
void excNotFound(const char *szMessage,...)
Definition: StdCompiler.h:233
void Warn(const char *szWarning,...)
Definition: StdCompiler.cpp:21
virtual bool isDeserializer()
Definition: StdCompiler.h:53
virtual void Byte(uint8_t &rByte)=0
virtual int NameCount(const char *szName=nullptr)
Definition: StdCompiler.h:91
@ RCT_IdtfAllowEmpty
Definition: StdCompiler.h:140
void Compile(T &&rStruct)
Definition: StdCompiler.h:173
virtual const char * GetNameByIndex(size_t idx) const
Definition: StdCompiler.h:79
virtual bool isRegistry()
Definition: StdCompiler.h:65
virtual void Word(uint16_t &rShort)=0
virtual void setRuntimeWritesAllowed(int32_t iChange)
Definition: StdCompiler.h:68
virtual void Boolean(bool &rBool)=0
virtual bool Name(const char *szName)
Definition: StdCompiler.h:77
void setWarnCallback(WarnCBT pnWarnCB, void *pData)
Definition: StdCompiler.h:282
void excEOF(const char *szMessage="EOF",...)
Definition: StdCompiler.h:243
virtual bool hasNaming()
Definition: StdCompiler.h:58
bool Name(const char *szName) override
NameNode * pNameRoot
Definition: StdCompiler.h:693
StdStrBuf getPosition() const override
size_t GetStringLength(RawCompileType eTyped)
void Raw(void *pData, size_t iSize, RawCompileType eType=RCT_Escaped) override
bool hasNaming() override
Definition: StdCompiler.h:634
NameNode * pName
Definition: StdCompiler.h:693
void End() override
const char * pPos
Definition: StdCompiler.h:702
StdCopyStrBuf NotFoundName
Definition: StdCompiler.h:708
const char * GetNameByIndex(size_t idx) const override
void notFound(const char *szWhat)
void setInput(const InT &In)
Definition: StdCompiler.h:630
void FreeNameNode(NameNode *pNode)
bool isDeserializer() override
Definition: StdCompiler.h:633
void Begin() override
int NameCount(const char *szName=nullptr) override
void Byte(int8_t &rByte) override
void NameEnd(bool fBreak=false) override
void Word(int16_t &rShort) override
bool Separator(Sep eSep) override
~StdCompilerINIRead() override
StdBuf ReadString(size_t iLength, RawCompileType eTyped, bool fAppendNull=true)
void Character(char &rChar) override
void String(char *szString, size_t iMaxLength, RawCompileType eType=RCT_Escaped) override
const char * pReenter
Definition: StdCompiler.h:705
void DWord(int32_t &rInt) override
void NoSeparator() override
bool TestStringEnd(RawCompileType eType)
Definition: StdCompiler.h:723
bool FollowName(const char *szName) override
unsigned long ReadUNum()
void Boolean(bool &rBool) override
void PutName(bool fSection)
void Boolean(bool &rBool) override
void NameEnd(bool fBreak=false) override
void WriteIndent(bool fSectionName)
void Byte(int8_t &rByte) override
bool Name(const char *szName) override
void Word(int16_t &rShort) override
void Raw(void *pData, size_t iSize, RawCompileType eType=RCT_Escaped) override
void DWord(int32_t &rInt) override
bool Separator(Sep eSep) override
void String(char *szString, size_t iMaxLength, RawCompileType eType=RCT_Escaped) override
void Begin() override
void Character(char &rChar) override
void WriteEscaped(const char *szString, const char *pEnd)
bool hasNaming() override
Definition: StdCompiler.h:566
void StringN(const char *szString, size_t iMaxLength, RawCompileType eType=RCT_Escaped)
void End() override
void Byte(int8_t &rByte) override
Definition: StdCompiler.h:428
void Raw(void *pData, size_t iSize, RawCompileType eType=RCT_Escaped) override
Definition: StdCompiler.h:435
bool Name(const char *szName) override
Definition: StdCompiler.h:420
bool hasNaming() override
Definition: StdCompiler.h:417
void Boolean(bool &rBool) override
Definition: StdCompiler.h:430
void DWord(int32_t &rInt) override
Definition: StdCompiler.h:424
void String(std::string &str, RawCompileType eType=RCT_Escaped) override
Definition: StdCompiler.h:434
void Word(uint16_t &rShort) override
Definition: StdCompiler.h:427
int NameCount(const char *szName=nullptr) override
Definition: StdCompiler.h:421
void DWord(uint32_t &rInt) override
Definition: StdCompiler.h:425
void Byte(uint8_t &rByte) override
Definition: StdCompiler.h:429
void Character(char &rChar) override
Definition: StdCompiler.h:431
void Word(int16_t &rShort) override
Definition: StdCompiler.h:426
void String(char **pszString, RawCompileType eType=RCT_Escaped) override
Definition: StdCompiler.h:433
bool isDeserializer() override
Definition: StdCompiler.h:416
void String(char *szString, size_t iMaxLength, RawCompileType eType=RCT_Escaped) override
Definition: StdCompiler.h:432
void Ref(const char *pnData)
Definition: StdBuf.h:455
const char * getData() const
Definition: StdBuf.h:442
size_t getLength() const
Definition: StdBuf.h:445
Exception(StdStrBuf Pos, StdStrBuf Msg)
Definition: StdCompiler.h:211
NameNode(NameNode *pParent=nullptr)
Definition: StdCompiler.h:689