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