OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
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;
224  EOFException(StdStrBuf Pos, StdStrBuf Msg) : Exception(Pos, Msg) { }
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 String(char *szString, size_t iMaxLength, RawCompileType eType = RCT_Escaped) override;
585  void String(char **pszString, RawCompileType eType = RCT_Escaped) override;
586  void String(std::string &str, RawCompileType eType = RCT_Escaped) override;
587  void Raw(void *pData, size_t iSize, RawCompileType eType = RCT_Escaped) override;
588 
589  // Passes
590  void Begin() override;
591  void End() override;
592 
593 protected:
594 
595  // Result
597 
598  // Naming stack
599  struct Naming
600  {
603  };
605  // Recursion depth
606  int iDepth;
607 
608  // Name not put yet (it's not clear wether it is a value or a section)
609  bool fPutName,
610  // Currently inside a section, so raw data can't be printed
611  fInSection;
612 
613  void PrepareForValue();
614  void WriteEscaped(const char *szString, const char *pEnd);
615  void WriteIndent(bool fSectionName);
616  void PutName(bool fSection);
617 };
618 
619 // text reader
621 {
622 public:
623 
625  ~StdCompilerINIRead() override;
626 
627  // Input
628  typedef StdStrBuf InT;
629  void setInput(const InT &In) { Buf.Ref(In); lineBreaks.clear(); }
630 
631  // Properties
632  bool isDeserializer() override { return true; }
633  bool hasNaming() override { return true; }
634 
635  // Naming
636  bool Name(const char *szName) override;
637  void NameEnd(bool fBreak = false) override;
638  bool FollowName(const char *szName) override;
639  const char *GetNameByIndex(size_t idx) const override;
640 
641  // Separators
642  bool Separator(Sep eSep) override;
643  void NoSeparator() override;
644 
645  // Counters
646  int NameCount(const char *szName = nullptr) override;
647 
648  // Data writers
649  void DWord(int32_t &rInt) override;
650  void DWord(uint32_t &rInt) override;
651  void Word(int16_t &rShort) override;
652  void Word(uint16_t &rShort) override;
653  void Byte(int8_t &rByte) override;
654  void Byte(uint8_t &rByte) override;
655  void Boolean(bool &rBool) override;
656  void Character(char &rChar) override;
657  void String(char *szString, size_t iMaxLength, RawCompileType eType = RCT_Escaped) override;
658  void String(char **pszString, RawCompileType eType = RCT_Escaped) override;
659  void String(std::string &str, RawCompileType eType = RCT_Escaped) override;
660  void Raw(void *pData, size_t iSize, RawCompileType eType = RCT_Escaped) override;
661 
662  // Position
663  StdStrBuf getPosition() const override;
664 
665  // Passes
666  void Begin() override;
667  void End() override;
668 
669 protected:
670 
671  // * Data
672 
673  // Name tree
674  struct NameNode
675  {
676  // Name
678  // Section?
679  bool Section{false};
680  // Tree structure
682  *FirstChild{nullptr}, *PrevChild{nullptr}, *NextChild{nullptr}, *LastChild{nullptr};
683  // Indent level
684  int Indent{-1};
685  // Name number in parent map
686  const char *Pos{nullptr};
687  // Constructor
688  NameNode(NameNode *pParent = nullptr) :
689  Parent(pParent)
690  { }
691  };
692  NameNode *pNameRoot{nullptr}, *pName;
693  // Current depth
694  int iDepth{0};
695  // Real depth (depth of recursive Name()-calls - if iDepth != iRealDepth, we are in a nonexistant namespace)
696  int iRealDepth{0};
697 
698  // Data
700  // Position
701  const char *pPos;
702 
703  // Reenter position (if an nonexistant separator was specified)
704  const char *pReenter;
705 
706  // Uppermost name that wasn't found
708 
709  // * Implementation
710 
711  // Name tree
712  void CreateNameTree();
713  void FreeNameTree();
714  void FreeNameNode(NameNode *pNode);
715 
716  // Navigation
717  void SkipWhitespace();
718  void SkipNum();
719  long ReadNum();
720  size_t GetStringLength(RawCompileType eTyped);
721  StdBuf ReadString(size_t iLength, RawCompileType eTyped, bool fAppendNull = true);
722  bool TestStringEnd(RawCompileType eType) { return IsStringEnd(*pPos, eType); }
723  char ReadEscapedChar();
724  unsigned long ReadUNum();
725 
726  void notFound(const char *szWhat);
727 
728 private:
729  uint32_t getLineNumberOfPos(const char *pos) const;
730  mutable std::vector<const char *> lineBreaks;
731 };
732 
733 void StdCompilerWarnCallback(void *pData, const char *szPosition, const char *szError);
734 
735 template <class CompT, class StructT>
736 bool CompileFromBuf_Log(StructT &&TargetStruct, const typename CompT::InT &SrcBuf, const char *szName)
737 {
738  try
739  {
740  CompileFromBuf<CompT>(TargetStruct, SrcBuf);
741  return true;
742  }
743  catch (StdCompiler::Exception *pExc)
744  {
745  if (!pExc->Pos.getLength())
746  LogF("ERROR: %s (in %s)", pExc->Msg.getData(), szName);
747  else
748  LogF("ERROR: %s (in %s, %s)", pExc->Msg.getData(), pExc->Pos.getData(), szName);
749  delete pExc;
750  return false;
751  }
752 }
753 template <class CompT, class StructT>
754 bool CompileFromBuf_LogWarn(StructT &&TargetStruct, const typename CompT::InT &SrcBuf, const char *szName)
755 {
756  try
757  {
758  CompT Compiler;
759  Compiler.setInput(SrcBuf.getRef());
760  Compiler.setWarnCallback(StdCompilerWarnCallback, reinterpret_cast<void *>(const_cast<char *>(szName)));
761  Compiler.Compile(TargetStruct);
762  return true;
763  }
764  catch (StdCompiler::Exception *pExc)
765  {
766  if (!pExc->Pos.getLength())
767  LogF("ERROR: %s (in %s)", pExc->Msg.getData(), szName);
768  else
769  LogF("ERROR: %s (in %s, %s)", pExc->Msg.getData(), pExc->Pos.getData(), szName);
770  delete pExc;
771  return false;
772  }
773 }
774 template <class CompT, class StructT>
775 bool DecompileToBuf_Log(StructT &&TargetStruct, typename CompT::OutT *pOut, const char *szName)
776 {
777  if (!pOut) return false;
778  try
779  {
780  pOut->Take(DecompileToBuf<CompT>(TargetStruct));
781  return true;
782  }
783  catch (StdCompiler::Exception *pExc)
784  {
785  LogF("ERROR: %s (in %s)", pExc->Msg.getData(), szName);
786  delete pExc;
787  return false;
788  }
789 }
790 
791 #endif // STDCOMPILER_H
const char * getData() const
Definition: StdBuf.h:442
void WriteData(const void *pData, size_t iSize)
virtual void End()
Definition: StdCompiler.h:156
void WriteEscaped(const char *szString, const char *pEnd)
void DoCompilation(T &rStruct)
Definition: StdCompiler.h:188
virtual bool Separator(Sep eSep=SEP_SEP)
Definition: StdCompiler.h:119
void Value(uint8_t &rInt)
Definition: StdCompiler.h:169
void setInput(InT &&In)
Definition: StdCompiler.h:491
bool Name(const char *szName) override
virtual bool hasNaming()
Definition: StdCompiler.h:58
Definition: StdBuf.h:29
bool hasNaming() override
Definition: StdCompiler.h:417
StructT * CompileFromBufToNewNamed(const typename CompT::InT &SrcBuf, const char *szName)
Definition: StdCompiler.h:393
virtual void NoSeparator()
Definition: StdCompiler.h:120
void Boolean(bool &rBool) override
virtual ~StdCompiler()=default
void Boolean(bool &rBool) override
void String(char *szString, size_t iMaxLength, RawCompileType eType=RCT_Escaped) override
void DWord(int32_t &rInt) override
Definition: StdCompiler.h:424
bool hasNaming() override
Definition: StdCompiler.h:633
void Character(char &rChar) override
void excCorrupt(const char *szMessage,...)
Definition: StdCompiler.h:249
void WriteIndent(bool fSectionName)
bool hasNaming() override
Definition: StdCompiler.h:566
void Boolean(bool &rBool) override
Definition: StdCompiler.cpp:74
void Word(uint16_t &rShort) override
Definition: StdCompiler.h:427
bool isDeserializer() override
Definition: StdCompiler.h:494
StdBuf ReadString(size_t iLength, RawCompileType eTyped, bool fAppendNull=true)
StdStrBuf getPosition() const override
virtual void Boolean(bool &rBool)=0
void Word(int16_t &rShort) override
void Word(int16_t &rShort) override
void excEOF(const char *szMessage="EOF",...)
Definition: StdCompiler.h:243
const char * pPos
Definition: StdCompiler.h:701
void String(char *szString, size_t iMaxLength, RawCompileType eType=RCT_Escaped) override
Definition: StdCompiler.cpp:76
void setInput(const InT &In)
Definition: StdCompiler.h:629
void Boolean(bool &rBool) override
Definition: StdCompiler.h:430
void Value(T &rStruct)
Definition: StdCompiler.h:162
virtual StdStrBuf getPosition() const
Definition: StdCompiler.h:151
void Byte(int8_t &rByte) override
Definition: StdCompiler.cpp:72
virtual bool Name(const char *szName)
Definition: StdCompiler.h:77
void Character(char &rChar) override
Definition: StdCompiler.h:431
void Value(uint32_t &rInt)
Definition: StdCompiler.h:165
void Byte(int8_t &rByte) override
void StdCompilerWarnCallback(void *pData, const char *szPosition, const char *szError)
virtual void Raw(void *pData, size_t iSize, RawCompileType eType=RCT_Escaped)=0
void String(std::string &str, RawCompileType eType=RCT_Escaped) override
Definition: StdCompiler.h:434
CompT::OutT DecompileToBuf(const StructT &SrcStruct)
Definition: StdCompiler.h:400
size_t getSize() const
Definition: StdBuf.h:101
virtual void String(char *szString, size_t iMaxLength, RawCompileType eType=RCT_Escaped)=0
void NameEnd(bool fBreak=false) override
void String(char *szString, size_t iMaxLength, RawCompileType eType=RCT_Escaped) override
void Begin() override
StdNamingAdapt< T > mkNamingAdapt(T &&rValue, const char *szName)
Definition: StdAdaptors.h:92
void Compile(T &&rStruct)
Definition: StdCompiler.h:173
NameNode * pNameRoot
Definition: StdCompiler.h:692
bool isSerializer()
Definition: StdCompiler.h:54
bool Name(const char *szName) override
void String(char *szString, size_t iMaxLength, RawCompileType eType=RCT_Escaped) override
Definition: StdCompiler.h:432
static char SeparatorToChar(Sep eSep)
Definition: StdCompiler.cpp:32
const char * GetNameByIndex(size_t idx) const override
void WriteValue(const T &rValue)
Definition: StdCompiler.cpp:94
virtual bool isVerbose()
Definition: StdCompiler.h:62
void Value(int16_t &rInt)
Definition: StdCompiler.h:166
void Raw(void *pData, size_t iSize, RawCompileType eType=RCT_Escaped) override
Exception(StdStrBuf Pos, StdStrBuf Msg)
Definition: StdCompiler.h:211
virtual const char * GetNameByIndex(size_t idx) const
Definition: StdCompiler.h:79
~StdCompilerINIRead() override
size_t getPosition()
Definition: StdCompiler.h:517
void Raw(void *pData, size_t iSize, RawCompileType eType=RCT_Escaped) override
Definition: StdCompiler.h:435
bool isDeserializer() override
Definition: StdCompiler.h:632
void End() override
void DWord(int32_t &rInt) override
Definition: StdCompiler.cpp:68
void Character(char &rChar) override
void FreeNameNode(NameNode *pNode)
StdCopyStrBuf NotFoundName
Definition: StdCompiler.h:707
unsigned long ReadUNum()
StdPtrAdapt< T > mkPtrAdaptNoNull(T *&rpObj)
Definition: StdAdaptors.h:606
void Raw(void *pData, size_t iSize, RawCompileType eType=RCT_Escaped) override
void String(char **pszString, RawCompileType eType=RCT_Escaped) override
Definition: StdCompiler.h:433
bool CompileFromBuf_LogWarn(StructT &&TargetStruct, const typename CompT::InT &SrcBuf, const char *szName)
Definition: StdCompiler.h:754
static bool IsStringEnd(char c, RawCompileType eType)
Definition: StdCompiler.cpp:53
bool isDoublePass() override
Definition: StdCompiler.h:453
void Value(int8_t &rInt)
Definition: StdCompiler.h:168
void Boolean(bool &rBool) override
virtual bool isDoublePass()
Definition: StdCompiler.h:50
void setWarnCallback(WarnCBT pnWarnCB, void *pData)
Definition: StdCompiler.h:282
size_t getRemainingBytes()
Definition: StdCompiler.h:518
void BeginSecond() override
NameNode(NameNode *pParent=nullptr)
Definition: StdCompiler.h:688
void excNotFound(const char *szMessage,...)
Definition: StdCompiler.h:233
StdStrBuf FormatStringV(const char *szFmt, va_list args)
Definition: StdBuf.cpp:276
bool CompileFromBuf_Log(StructT &&TargetStruct, const typename CompT::InT &SrcBuf, const char *szName)
Definition: StdCompiler.h:736
bool Name(const char *szName) override
Definition: StdCompiler.h:420
void Value(const T &rStruct)
Definition: StdCompiler.h:161
void Character(char &rChar) override
void Begin() override
void Byte(int8_t &rByte) override
virtual void DWord(int32_t &rInt)=0
virtual bool isDeserializer()
Definition: StdCompiler.h:53
StdCompiler()=default
void Word(int16_t &rShort) override
Definition: StdCompiler.h:426
void Ref(const char *pnData)
Definition: StdBuf.h:455
bool DecompileToBuf_Log(StructT &&TargetStruct, typename CompT::OutT *pOut, const char *szName)
Definition: StdCompiler.h:775
virtual void Character(char &rChar)=0
void notFound(const char *szWhat)
void Byte(int8_t &rByte) override
void DWord(int32_t &rInt) override
void Value(uint16_t &rInt)
Definition: StdCompiler.h:167
void Begin() override
void Value(int32_t &rInt)
Definition: StdCompiler.h:164
void Byte(uint8_t &rByte) override
Definition: StdCompiler.h:429
void Warn(const char *szWarning,...)
Definition: StdCompiler.cpp:21
void Word(int16_t &rShort) override
Definition: StdCompiler.cpp:70
void NoSeparator() override
void Begin() override
virtual void Begin()
Definition: StdCompiler.h:154
void CompileFromBuf(StructT &&TargetStruct, const typename CompT::InT &SrcBuf)
Definition: StdCompiler.h:379
bool Separator(Sep eSep) override
void End() override
void String(char *szString, size_t iMaxLength, RawCompileType eType=RCT_Escaped) override
void PutName(bool fSection)
virtual void setRuntimeWritesAllowed(int32_t iChange)
Definition: StdCompiler.h:68
virtual int NameCount(const char *szName=nullptr)
Definition: StdCompiler.h:91
void Raw(void *pData, size_t iSize, RawCompileType eType=RCT_Escaped) override
virtual bool Default(const char *szName)
Definition: StdCompiler.h:88
void(* WarnCBT)(void *, const char *, const char *)
Definition: StdCompiler.h:281
virtual void BeginSecond()
Definition: StdCompiler.h:155
int NameCount(const char *szName=nullptr) override
Definition: StdCompiler.h:421
bool Separator(Sep eSep) override
StdParameterAdapt< T, P > mkParAdapt(T &&rObj, P &&rPar)
Definition: StdAdaptors.h:458
size_t getLength() const
Definition: StdBuf.h:445
StdStrBuf getPosition() const override
void CompileNewFuncCtx(T *&pStruct, StdCompiler *pComp, const ContextT &rCtx)
Definition: StdCompiler.h:348
void DWord(int32_t &rInt) override
bool TestStringEnd(RawCompileType eType)
Definition: StdCompiler.h:722
bool FollowName(const char *szName) override
virtual void Word(int16_t &rShort)=0
void CompileFunc(T &rStruct, StdCompiler *pComp)
Definition: StdCompiler.h:301
void DWord(uint32_t &rInt) override
Definition: StdCompiler.h:425
void Byte(int8_t &rByte) override
Definition: StdCompiler.h:428
void Word(int16_t &rShort) override
virtual bool FollowName(const char *szName)
Definition: StdCompiler.h:84
StructT * CompileFromBufToNew(const typename CompT::InT &SrcBuf)
Definition: StdCompiler.h:386
bool LogF(const char *strMessage,...)
Definition: C4Log.cpp:250
NameNode * pName
Definition: StdCompiler.h:692
void DWord(int32_t &rInt) override
#define s
size_t GetStringLength(RawCompileType eTyped)
void NameEnd(bool fBreak=false) override
void Decompile(const T &rStruct)
Definition: StdCompiler.h:178
void Raw(void *pData, size_t iSize, RawCompileType eType=RCT_Escaped) override
virtual void NameEnd(bool fBreak=false)
Definition: StdCompiler.h:78
virtual void Byte(int8_t &rByte)=0
int NameCount(const char *szName=nullptr) override
void ReadValue(T &rValue)
bool isDeserializer() override
Definition: StdCompiler.h:416
void CompileNewFunc(T *&pStruct, StdCompiler *pComp)
Definition: StdCompiler.h:320
int iSize
Definition: TstC4NetIO.cpp:32
virtual bool isRegistry()
Definition: StdCompiler.h:65
const char * pReenter
Definition: StdCompiler.h:704
void Character(char &rChar) override
Definition: StdCompiler.cpp:75
void Value(bool &rBool)
Definition: StdCompiler.h:170