gwnavruntime/kernel/SF_MsgFormat.h Source File

SF_MsgFormat.h
Go to the documentation of this file.
1 /*
2 * Copyright 2015 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 /**************************************************************************
8 
9 PublicHeader: None
10 Filename : KY_MsgFormat.h
11 Content : Formatting of strings
12 Created : January 26, 2009
13 Authors : Sergey Sikorskiy
14 
15 **************************************************************************/
16 
17 #ifndef INC_KY_Kernel_MsgFormat_H
18 #define INC_KY_Kernel_MsgFormat_H
19 
20 #include <stdarg.h>
21 
27 
28 
29 namespace Kaim {
30 
32 // Forward declaration.
33 
34 // ***** FmtInfo
35 // Formatter traits class.
36 template <typename T> struct FmtInfo;
37 
38 class MsgFormat;
39 
40 
42 
43 // ***** FmtResource
44 
45 // Base class for all formatting resources.
46 // Main purpose of this class is to declare method Reflect, which "reflects"/returns
47 // set of available attributes.
48 
49 class FmtResource
50 {
51 public:
52  virtual ~FmtResource() {};
53 
54 public:
55  struct TAttrs
56  {
57  TAttrs() : Num(0), Attrs(NULL) {}
58 
59  unsigned Num; // Number of attributes.
60  UPInt* Attrs; // Array of UPInt values.
61  };
62 
63 public:
64  // attrs - pointer to a structure, which containts size on an array of
65  // attributes and a pointer to the array.
66  // Return number of attributes.
67  virtual unsigned Reflect(const TAttrs*& attrs) const;
68 };
69 
70 // ***** Formatter
71 
72 // Abstract base class for all formatters.
73 // Formatter can be used as a standalone object and as a part of MsgFormat.
74 // Formatters can be organized into trees.
75 class Formatter : public FmtResource
76 {
77 public:
78  enum requirement_t
79  {
80  rtNone = 0, // No requirements.
81  rtPrevStr = 1, // Previous string.
82  rtPrevStrSS = 2, // Sentence separator. It is used to prevent cyclic dependencies.
83  rtNextStr = 4, // Next string.
84  rtParent = 8 // Parent formatter.
85  };
86  // Set of requirements.
87  typedef UInt8 requirements_t;
88 
89  // Position of a parent formatter.
90  enum ParentRef
91  {
92  prNone, // No parent formatter.
93  prPrev, // Previous. Relative position.
94  prNext, // Next. Relative position.
95  prPos // Absolute position (from the left).
96  };
97 
98 public:
99  Formatter()
100  : pParentFmt(NULL)
101  , IsConverted(false)
102  {
103  }
104  Formatter(MsgFormat& f)
105  : pParentFmt(&f)
106  , IsConverted(false)
107  {
108  }
109  virtual ~Formatter();
110 
111 public:
112  // Parse formatting string.
113  virtual void Parse(const StringDataPtr& str);
114  // Convert value.
115  virtual void Convert() = 0;
116  // Retrieve conversion result.
117  virtual StringDataPtr GetResult() const = 0;
118  // Retrieve size of a converted value.
119  // May be called only after Convert().
120  virtual UPInt GetSize() const = 0;
121  // Retrieve formatter's requirements.
122  virtual requirements_t GetRequirements() const;
123  // Check conversion status for optimization purposes.
124  bool Converted() const { return IsConverted; }
125 
126 public:
127  // Dependency-related ...
128 
129  // Prev string ...
130  virtual void SetPrevStr(const StringDataPtr& /*ptr*/);
131  virtual StringDataPtr GetPrevStr() const;
132 
133  // Next string ...
134  virtual void SetNextStr(const StringDataPtr& /*ptr*/);
135  virtual StringDataPtr GetNextStr() const;
136 
137  // Parent formatter ...
138  virtual ParentRef GetParentRef() const;
139  virtual unsigned char GetParentPos() const;
140  virtual void SetParent(const FmtResource&);
141 
142 protected:
143  bool HasParent() const
144  {
145  return pParentFmt != NULL;
146  }
147  // Non-const version is required for formatter substitution.
148  MsgFormat& GetParent()
149  {
150  KY_ASSERT(pParentFmt);
151  return *pParentFmt;
152  }
153  const MsgFormat& GetParent() const
154  {
155  KY_ASSERT(pParentFmt);
156  return *pParentFmt;
157  }
158 
159  // Parent formatter ...
160  // Set relative position.
161  virtual void SetParentRef(ParentRef);
162  // Set absolute position of a parent formatter.
163  virtual void SetParentPos(unsigned char);
164 
165  // Set IsConverted flag.
166  void SetConverted(bool value = true)
167  {
168  IsConverted = value;
169  }
170 
171 private:
172  Formatter& operator = (const Formatter&);
173 
174 private:
175  MsgFormat* pParentFmt;
176  bool IsConverted;
177 };
178 
180 
181 // ***** StrFormatter
182 
183 // String formatter. Implementation of Formatter, which serves as a proxy
184 // for string data types.
185 
186 class StrFormatter : public Formatter
187 {
188 public:
189  StrFormatter(const char* v);
190  StrFormatter(const StringDataPtr& v);
191  StrFormatter(const String& v);
192 
193  StrFormatter(MsgFormat& f, const char* v);
194  StrFormatter(MsgFormat& f, const StringDataPtr& v);
195  StrFormatter(MsgFormat& f, const String& v);
196 
197 public:
198  virtual void Parse(const StringDataPtr& str);
199  virtual void Convert();
200  virtual StringDataPtr GetResult() const;
201  virtual UPInt GetSize() const;
202 
203 private:
204  StrFormatter& operator = (const StrFormatter&);
205 
206 private:
207  const StringDataPtr Value;
208 };
209 
210 template <>
211 struct FmtInfo<const char*>
212 {
213  typedef StrFormatter formatter;
214 };
215 
216 template <>
217 struct FmtInfo<char*>
218 {
219  typedef StrFormatter formatter;
220 };
221 
222 template <>
223 struct FmtInfo<const unsigned char*>
224 {
225  typedef StrFormatter formatter;
226 };
227 
228 template <>
229 struct FmtInfo<unsigned char*>
230 {
231  typedef StrFormatter formatter;
232 };
233 
234 template <>
235 struct FmtInfo<const signed char*>
236 {
237  typedef StrFormatter formatter;
238 };
239 
240 template <>
241 struct FmtInfo<signed char*>
242 {
243  typedef StrFormatter formatter;
244 };
245 
246 template <int N>
247 struct FmtInfo<const char[N]>
248 {
249  typedef StrFormatter formatter;
250 };
251 
252 template <int N>
253 struct FmtInfo<char[N]>
254 {
255  typedef StrFormatter formatter;
256 };
257 
258 template <int N>
259 struct FmtInfo<const unsigned char[N]>
260 {
261  typedef StrFormatter formatter;
262 };
263 
264 template <int N>
265 struct FmtInfo<unsigned char[N]>
266 {
267  typedef StrFormatter formatter;
268 };
269 
270 template <int N>
271 struct FmtInfo<const signed char[N]>
272 {
273  typedef StrFormatter formatter;
274 };
275 
276 template <int N>
277 struct FmtInfo<signed char[N]>
278 {
279  typedef StrFormatter formatter;
280 };
281 
282 template <>
283 struct FmtInfo<const StringDataPtr>
284 {
285  typedef StrFormatter formatter;
286 };
287 
288 template <>
289 struct FmtInfo<StringDataPtr>
290 {
291  typedef StrFormatter formatter;
292 };
293 
294 template <>
295 struct FmtInfo<const String>
296 {
297  typedef StrFormatter formatter;
298 };
299 
300 template <>
301 struct FmtInfo<String>
302 {
303  typedef StrFormatter formatter;
304 };
305 
306 template <>
307 struct FmtInfo<const StringLH>
308 {
309  typedef StrFormatter formatter;
310 };
311 
312 template <>
313 struct FmtInfo<StringLH>
314 {
315  typedef StrFormatter formatter;
316 };
317 
318 template <>
319 struct FmtInfo<const StringDH>
320 {
321  typedef StrFormatter formatter;
322 };
323 
324 template <>
325 struct FmtInfo<StringDH>
326 {
327  typedef StrFormatter formatter;
328 };
329 
330 
332 
333 // ***** BoolFormatter
334 
335 // Bool formatter. Implementation of Formatter, which can transform boolean value
336 // into a string. By default true is transformed into string "true", and false
337 // into "false" accordingly. This default behavior can be changed by using a build-in
338 // switch formatter. For example:
339 //
340 // Format(sink, "{0:sw:yes:no}", true);
341 // Format(sink, "{0:sw:yes:no}", false);
342 //
343 // where "sw" is a argument, which enables "switch-formatter". Next two arguments are
344 // string values corresponding to true and false.
345 
346 class BoolFormatter : public Formatter
347 {
348 public:
349  BoolFormatter(MsgFormat& f, bool v);
350 
351 public:
352  virtual void Parse(const StringDataPtr& str);
353  virtual void Convert();
354  virtual StringDataPtr GetResult() const;
355  virtual UPInt GetSize() const;
356 
357 private:
358  BoolFormatter& operator = (const BoolFormatter&);
359 
360 private:
361  bool Value:1;
362  bool SwitchStmt:1;
363  StringDataPtr result;
364 };
365 
366 template <>
367 struct FmtInfo<bool>
368 {
369  typedef BoolFormatter formatter;
370 };
371 
372 
374 
375 // ***** NumericBase
376 // Base class for LongFormatter and DoubleFormatter.
377 // It just keeps data common to its children.
378 class NumericBase
379 {
380 public:
381  NumericBase();
382 
383 public:
384  char* ToCStr() const { return ValueStr; }
385 
386 public:
387  void SetPrecision(unsigned prec = 1)
388  {
389  Precision = prec;
390  }
391  void SetWidth(unsigned width = 1)
392  {
393  Width = width;
394  }
395  // In case of hexadecimal and octal numbers it also means "show prefix".
396  void SetShowSign(bool flag = true)
397  {
398  ShowSign = flag;
399  }
400  void SetPrefixChar(char prefix = ' ')
401  {
402  PrefixChar = prefix;
403  }
404  void SetSeparatorChar(char sep = ',')
405  {
406  SeparatorChar = sep;
407  }
408  void SetBigLetters(bool flag = true)
409  {
410  BigLetters = flag;
411  }
412  void SetBlankPrefix(bool flag = true)
413  {
414  BlankPrefix = flag;
415  }
416  void SetAlignLeft(bool flag = true)
417  {
418  AlignLeft = flag;
419  }
420  void SetSharpSign(bool flag = true)
421  {
422  SharpSign = flag;
423  }
424 
425 protected:
426  void ReadPrintFormat(StringDataPtr token);
427  void ReadWidth(StringDataPtr token);
428 
429  void ULongLong2String(char* buff, UInt64 value, bool separator, unsigned base = 10);
430  void ULong2String(char* buff, UInt32 value, bool separator, unsigned base = 10);
431 
432 protected:
433  unsigned Precision:5;
434  unsigned Width:5;
435  char PrefixChar:7;
436  char SeparatorChar:7;
437  bool ShowSign:1;
438  bool BigLetters:1;
439  bool BlankPrefix:1;
440  bool AlignLeft:1; // Required for sprintf().
441  bool SharpSign:1; // Required for sprintf().
442 
443  char* ValueStr;
444 };
445 
447 
448 // ***** LongFormatter
449 
450 // Long formatter. This class is capable of formatting of integer data types.
451 // This class can be used either with Format or as a standalone formatter.
452 // It also has a built-in switch formatter. Example:
453 //
454 // Format(sink, "{0:sw:0:zero:1:one:2:two:many}", int_value);
455 //
456 // Where argument "sw" enables switch formatter. Arguments of the switch formatter
457 // should follow the format below.
458 //
459 // sw:(int_value:str_value)+(:default_str_value)?
460 //
461 // For each pair "int_value:str_value" int_value will be replaced with the str_value.
462 // If a value does not correspond to any of int_value, it will be replaced with
463 // a default string value "default_str_value".
464 class LongFormatter : public Formatter, public NumericBase, public String::InitStruct
465 {
466 public:
467  LongFormatter(int v);
468  LongFormatter(unsigned int v);
469 
470  LongFormatter(long v);
471  LongFormatter(unsigned long v);
472 
473 #if !defined(KY_64BIT_POINTERS) || defined(KY_OS_WIN32)
474  // SInt64 and UInt64 on PS2 are equivalent to long and unsigned long.
475  LongFormatter(SInt64 v);
476  LongFormatter(UInt64 v);
477 #endif
478 
479  LongFormatter(MsgFormat& f, int v);
480  LongFormatter(MsgFormat& f, unsigned int v);
481 
482  LongFormatter(MsgFormat& f, long v);
483  LongFormatter(MsgFormat& f, unsigned long v);
484 
485 #if !defined(KY_64BIT_POINTERS) || defined(KY_OS_WIN32)
486  // SInt64 and UInt64 on PS2 are equivalent to long and unsigned long.
487  LongFormatter(MsgFormat& f, SInt64 v);
488  LongFormatter(MsgFormat& f, UInt64 v);
489 #endif
490 
491 public:
492  virtual void Parse(const StringDataPtr& str);
493  virtual void Convert();
494  virtual StringDataPtr GetResult() const;
495  virtual UPInt GetSize() const;
496  virtual void InitString(char* pbuffer, UPInt size) const;
497 
498 public:
499  LongFormatter& SetPrecision(unsigned prec = 1)
500  {
501  KY_ASSERT(prec <= 20);
502  NumericBase::SetPrecision(prec);
503  return *this;
504  }
505  LongFormatter& SetWidth(unsigned width = 1)
506  {
507  KY_ASSERT(width <= 20);
508  NumericBase::SetWidth(width);
509  return *this;
510  }
511  LongFormatter& SetShowSign(bool flag = true)
512  {
513  NumericBase::SetShowSign(flag);
514  return *this;
515  }
516 
517  // base should be in range [2..16].
518  LongFormatter& SetBase(unsigned base)
519  {
520  KY_ASSERT(base >= 2 && base <= 16);
521  Base = base;
522  return *this;
523  }
524  LongFormatter& SetPrefixChar(char prefix = ' ')
525  {
526  NumericBase::SetPrefixChar(prefix);
527  return *this;
528  }
529  LongFormatter& SetSeparatorChar(char sep = ',')
530  {
531  NumericBase::SetSeparatorChar(sep);
532  return *this;
533  }
534  LongFormatter& SetBigLetters(bool flag = true)
535  {
536  NumericBase::SetBigLetters(flag);
537  return *this;
538  }
539 
540 private:
541  void AppendSignCharLeft(bool negative);
542  LongFormatter& operator = (const LongFormatter&);
543 
544  UPInt GetSizeInternal() const
545  {
546  return Buff + sizeof(Buff) - 1 - ValueStr;
547  }
548 
549 private:
550  unsigned Base:5;
551  const bool SignedValue:1;
552  bool IsLongLong:1;
553 
554  const SInt64 Value;
555  // Big-enough to keep signed long long with separators plus zero terminator.
556  // Should be increased for Unicode separators.
557  char Buff[29];
558 };
559 
560 template <>
561 struct FmtInfo<char>
562 {
563  typedef LongFormatter formatter;
564 };
565 
566 template <>
567 struct FmtInfo<unsigned char>
568 {
569  typedef LongFormatter formatter;
570 };
571 
572 template <>
573 struct FmtInfo<signed char>
574 {
575  typedef LongFormatter formatter;
576 };
577 
578 template <>
579 struct FmtInfo<short>
580 {
581  typedef LongFormatter formatter;
582 };
583 
584 template <>
585 struct FmtInfo<unsigned short>
586 {
587  typedef LongFormatter formatter;
588 };
589 
590 template <>
591 struct FmtInfo<int>
592 {
593  typedef LongFormatter formatter;
594 };
595 
596 template <>
597 struct FmtInfo<unsigned int>
598 {
599  typedef LongFormatter formatter;
600 };
601 
602 template <>
603 struct FmtInfo<long>
604 {
605  typedef LongFormatter formatter;
606 };
607 
608 template <>
609 struct FmtInfo<unsigned long>
610 {
611  typedef LongFormatter formatter;
612 };
613 
614 #if !defined(KY_64BIT_POINTERS) || defined(KY_OS_WIN32)
615 template <>
616 struct FmtInfo<SInt64>
617 {
618  typedef LongFormatter formatter;
619 };
620 
621 template <>
622 struct FmtInfo<UInt64>
623 {
624  typedef LongFormatter formatter;
625 };
626 #endif
627 
629 //#define INTERNAL_D2A
630 
631 // ***** DoubleFormatter
632 
633 // Double formatter. This class is capable of formatting of numeric data types with
634 // floating point.
635 class DoubleFormatter : public Formatter, public NumericBase, public String::InitStruct
636 {
637 public:
638  enum PresentationType { FmtDecimal, FmtScientific, FmtSignificant };
639 
640 public:
641  DoubleFormatter(Double v);
642  DoubleFormatter(MsgFormat& f, Double v);
643 
644 public:
645  virtual void Parse(const StringDataPtr& str);
646  virtual void Convert();
647  virtual StringDataPtr GetResult() const;
648  virtual UPInt GetSize() const;
649  virtual void InitString(char* pbuffer, UPInt size) const;
650 
651 public:
652  DoubleFormatter& SetType(PresentationType ptype)
653  {
654  Type = ptype;
655  return *this;
656  }
657  DoubleFormatter& SetPrecision(unsigned prec = 1)
658  {
659  NumericBase::SetPrecision(prec);
660  return *this;
661  }
662  DoubleFormatter& SetWidth(unsigned width = 1)
663  {
664  NumericBase::SetWidth(width);
665  return *this;
666  }
667  DoubleFormatter& SetShowSign(bool flag = true)
668  {
669  NumericBase::SetShowSign(flag);
670  return *this;
671  }
672  DoubleFormatter& SetPrefixChar(char prefix = ' ')
673  {
674  NumericBase::SetPrefixChar(prefix);
675  return *this;
676  }
677  DoubleFormatter& SetSeparatorChar(char sep = ',')
678  {
679  NumericBase::SetSeparatorChar(sep);
680  return *this;
681  }
682  DoubleFormatter& SetBigLetters(bool flag = true)
683  {
684  NumericBase::SetBigLetters(flag);
685  return *this;
686  }
687  DoubleFormatter& SetAlignLeft(bool flag = true)
688  {
689  NumericBase::SetAlignLeft(flag);
690  return *this;
691  }
692 
693 private:
694  DoubleFormatter& operator = (const DoubleFormatter&);
695 
696  void AppendSignCharLeft(bool negative, bool show_sign = false);
697 
698 #ifdef INTERNAL_D2A
699  // In case of underflow it can switch to scientific format.
700  void DecimalFormat(Double v);
701  void ScientificFormat();
702 #endif
703 
704  UPInt GetSizeInternal() const
705  {
706  return Buff + sizeof(Buff) - 1 - ValueStr;
707  }
708 
709 private:
710  PresentationType Type;
711  const Double Value;
712  UPInt Len;
713 
714  char Buff[347 + 1];
715 };
716 
717 template <>
718 struct FmtInfo<float>
719 {
720  typedef DoubleFormatter formatter;
721 };
722 
723 template <>
724 struct FmtInfo<double>
725 {
726  typedef DoubleFormatter formatter;
727 };
728 
729 
731 class ResouceProvider;
732 
734 
735 // ***** ResourceFormatter
736 
737 // Formatter, which is responsible for formatting of localization resources.
738 
739 class ResourceFormatter : public Formatter
740 {
741 public:
742  class ValueType
743  {
744  public:
745  ValueType(UPInt rc);
746  ValueType(UPInt rc, const ResouceProvider& provider);
747  // int version of RC is supposed to be used with NULL argument only.
748  // It is interpreted as a string pointer.
749  explicit ValueType(int rc);
750  // int version of RC is supposed to be used with NULL argument only.
751  // It is interpreted as a string pointer.
752  explicit ValueType(int rc, const ResouceProvider& provider);
753  ValueType(const char* rc);
754  ValueType(const char* rc, const ResouceProvider& provider);
755 
756  public:
757  bool IsStrResource() const
758  {
759  return IsString;
760  }
761  const char* GetStrResource() const
762  {
763  KY_ASSERT(IsStrResource());
764  return Resource.RStr;
765  }
766  UPInt GetLongResource() const
767  {
768  KY_ASSERT(!IsStrResource());
769  return Resource.RLong;
770  }
771 
772  public:
773  const ResouceProvider* GetResouceProvider() const
774  {
775  return RC_Provider;
776  }
777  void SetResouceProvider(const ResouceProvider* rp)
778  {
779  RC_Provider = rp;
780  }
781 
782  private:
783  ValueType& operator = (const ValueType&);
784 
785  private:
786  union ResourceType
787  {
788  const char* RStr;
789  UPInt RLong;
790  };
791 
792  ResourceType Resource;
793  const bool IsString;
794  const ResouceProvider* RC_Provider;
795  };
796 
797 public:
798  ResourceFormatter(MsgFormat& f, const ValueType& v);
799  virtual ~ResourceFormatter();
800 
801 public:
802  virtual void Parse(const StringDataPtr& str);
803  virtual void Convert();
804  virtual StringDataPtr GetResult() const;
805  virtual UPInt GetSize() const;
806 
807 private:
808  StringDataPtr MakeString(const TAttrs& attrs) const;
809 
810 private:
811  ResourceFormatter& operator = (const ResourceFormatter&);
812 
813 private:
814  const ValueType Value;
815  const ResouceProvider* pRP;
816 
817  StringDataPtr Result;
818 };
819 
820 template <>
821 struct FmtInfo<ResourceFormatter::ValueType>
822 {
823  typedef ResourceFormatter formatter;
824 };
825 
827 
828 // ***** ResouceProvider
829 
830 // Localization resource provider.
831 
832 class ResouceProvider : public NewOverrideBase<Stat_Default_Mem>
833 {
834 public:
835  ResouceProvider(const ResouceProvider* next = NULL) : nextRP(next) {}
836  virtual ~ResouceProvider() {}
837 
838 public:
839  virtual unsigned Reflect(const ResourceFormatter::ValueType& /*rc*/, const FmtResource::TAttrs** attrs) const = 0;
840  virtual StringDataPtr MakeString(const ResourceFormatter::ValueType& /*rc*/, const FmtResource::TAttrs& /*attrs*/) const = 0;
841 
842 protected:
843  const ResouceProvider* GetNext() const { return nextRP; }
844 
845 private:
846  const ResouceProvider* nextRP;
847 };
848 
849 
851 
852 // ***** FormatterFactory
853 
854 // Abstract base class for all formatter factories.
855 class FormatterFactory
856 {
857 public:
858  virtual ~FormatterFactory() {}
859 
860 public:
861  struct Args
862  {
863  Args(MsgFormat&f, const StringDataPtr& n, const ResourceFormatter::ValueType& v)
864  : Fmt(f), Name(n), Value(v)
865  {
866  }
867 
868  MsgFormat& Fmt;
869  const StringDataPtr& Name;
870  const ResourceFormatter::ValueType& Value;
871 
872  private:
873  Args& operator = (const Args&);
874  };
875 
876 public:
877  virtual Formatter* MakeFormatter(const Args& args) const = 0;
878 };
879 
881 
882 // ***** LocaleProvider
883 
884 // Formatter factory, which is also aware of locale. This class is supposed to
885 // provide all information related to localization.
886 
887 class LocaleProvider : public FormatterFactory
888 {
889 public:
890  virtual ~LocaleProvider() {}
891 
892 public:
893  virtual const Locale& GetLocale() const = 0;
894  virtual ResouceProvider* GetDefaultRCProvider() const = 0;
895 };
896 
897 
899 
900 // ***** MsgFormat
901 
902 // Class, which parses formatting string, applies formatter's values, and
903 // puts final formatted string into a Sink.
904 //
905 // Sink can be of three data types:
906 // 1) String. Resulting string will be copied into String.
907 // 2) StringBuffer. Resulting string will be added to StringBuffer.
908 // 3) StringDataPtr. This data type represents a buffer. Resulting string will
909 // be copied into the buffer.
910 class MsgFormat : String::InitStruct
911 {
912 public:
913  class Sink
914  {
915  friend class MsgFormat;
916 
917  public:
918  Sink(String& str)
919  : Type(tStr), SinkData(str) {}
920  Sink(StringBuffer& buffer)
921  : Type(tStrBuffer), SinkData(buffer) {}
922  Sink(const StringDataPtr& strData)
923  : Type(tDataPtr), SinkData(strData) {}
924  template <typename T, int N>
925  Sink(const T (&v)[N])
926  : Type(tDataPtr), SinkData(StringDataPtr(v, N)) {}
927 
928  private:
929  enum DataType {tStr, tStrBuffer, tDataPtr};
930 
931  struct StrDataType
932  {
933  const char* pStr;
934  UPInt Size;
935  };
936 
937  union SinkDataType
938  {
939  public:
940  SinkDataType(String& str)
941  : pStr(&str)
942  {
943  }
944  SinkDataType(StringBuffer& buffer)
945  : pStrBuffer(&buffer)
946  {
947  }
948  SinkDataType(const StringDataPtr& strData)
949  {
950  DataPtr.pStr = strData.ToCStr();
951  DataPtr.Size = strData.GetSize();
952  }
953 
954  public:
955  String* pStr;
956  StringBuffer* pStrBuffer;
957  StrDataType DataPtr;
958  };
959 
960  DataType Type;
961  SinkDataType SinkData;
962  };
963 
964 public:
965  MsgFormat(const Sink& r);
966  MsgFormat(const Sink& r, const LocaleProvider& loc);
967  ~MsgFormat();
968 
969 public:
970  typedef UInt8 ArgNumType;
971  typedef StackMemPool<> MemoryPoolType;
972 
973  // Parse formatting string in "Scaleform" format.
974  // Split a string onto tokens, which can be of two types:
975  // text and parameter. For parameters retrieve an argument number.
976  void Parse(const char* fmt);
977 
978  // Parse formatting string in "sprintf" format.
979  // This function creates all necessary formatters.
980  void FormatF(const StringDataPtr& fmt, va_list argList);
981 
982  // Replace an old formatter with the new one.
983  // Argument "allocated" should be true if new formatter is dynamically allocated.
984  // Return value: true on success.
985  bool ReplaceFormatter(Formatter* oldf, Formatter* newf, bool allocated);
986 
987  ArgNumType GetFirstArgNum() const
988  {
989  return FirstArgNum;
990  }
991  void SetFirstArgNum(ArgNumType num)
992  {
993  FirstArgNum = num;
994  }
995 
996  // Get current locale provider if any.
997  const LocaleProvider* GetLocaleProvider() const
998  {
999  return pLocaleProvider;
1000  }
1001 
1002  // Get memory pool, which can be used by formatters.
1003  MemoryPoolType& GetMemoryPool()
1004  {
1005  return MemPool;
1006  }
1007 
1008  // Get formatted string size.
1009  UPInt GetStrSize() const
1010  {
1011  return StrSize;
1012  }
1013 
1014 public:
1015  UInt8 GetEscapeChar() const
1016  {
1017  return EscapeChar;
1018  }
1019  void SetEscapeChar(UInt8 c)
1020  {
1021  EscapeChar = c;
1022  }
1023 
1024 public:
1025  // "D" stands for "Dynamic".
1026 
1027  // Create a binding for one argument.
1028  // This function will allocate a formatter only if this argument is mentioned in a
1029  // formatting string.
1030  template <typename T>
1031  void FormatD1(const T& v)
1032  {
1033  while (NextFormatter())
1034  {
1035  Bind(new (GetMemoryPool()) typename FmtInfo<T>::formatter(*this, v), true);
1036  }
1037 
1038  ++FirstArgNum;
1039  }
1040 
1041  void FinishFormatD();
1042 
1043 private:
1044  enum ERecType {eStrType, eParamStrType, eFmtType};
1045 
1046  struct str_ptr
1047  {
1048  const char* Str;
1049  unsigned char Len;
1050  unsigned char ArgNum;
1051  };
1052 
1053  struct fmt_ptr
1054  {
1055  Kaim::Formatter* Formatter;
1056  bool Allocated;
1057  };
1058 
1059  union fmt_value
1060  {
1061  str_ptr String;
1062  fmt_ptr Formatter;
1063  };
1064 
1065  class fmt_record
1066  {
1067  public:
1068  fmt_record(ERecType type, const fmt_value& value)
1069  : RecType(type)
1070  , RecValue(value)
1071  {
1072  }
1073 
1074  ERecType GetType() const
1075  {
1076  return RecType;
1077  }
1078  const fmt_value& GetValue() const
1079  {
1080  return RecValue;
1081  }
1082 
1083  private:
1084  ERecType RecType;
1085  fmt_value RecValue;
1086  };
1087 
1088 private:
1089  // Function with side effects.
1090  // Calculate next DataInd, which is supposed to be used by Bind().
1091  bool NextFormatter();
1092  // Bind a formatter at DataInd,
1093  void Bind(Formatter* formatter, const bool allocated);
1094  void BindNonPos();
1095  void MakeString();
1096  void Evaluate(UPInt ind);
1097 
1098  void AddStringRecord(const StringDataPtr& str);
1099  void AddFormatterRecord(Formatter* f, bool allocated);
1100 
1101  // InitStruct-related.
1102  virtual void InitString(char* pbuffer, UPInt size) const;
1103 
1104 private:
1105  MsgFormat& operator = (const MsgFormat&);
1106 
1107 private:
1108  // Minimalistic implementation of Array, which allocates first SS elements
1109  // on stack.
1110  template <typename T, UPInt SS = 8, class DA = Array<T> >
1111  class StackArray
1112  {
1113  public:
1114  typedef T ValueType;
1115 
1116  public:
1117  StackArray()
1118  : Size(0)
1119  {
1120  }
1121 
1122  UPInt GetSize() const { return Size; }
1123 
1124  void PushBack(const ValueType& val)
1125  {
1126  if (Size < SS)
1127  * reinterpret_cast<ValueType*>(StaticArray + Size * sizeof(T)) = val;
1128  else
1129  DynamicArray.PushBack(val);
1130 
1131  ++Size;
1132  }
1133 
1134  ValueType& operator [] (UPInt index)
1135  {
1136  if (index < SS)
1137  return * reinterpret_cast<ValueType*>(StaticArray + index * sizeof(T));
1138 
1139  return DynamicArray[index - SS];
1140  }
1141  const ValueType& operator [] (UPInt index) const
1142  {
1143  if (index < SS)
1144  return * reinterpret_cast<const ValueType*>(StaticArray + index * sizeof(T));
1145 
1146  return DynamicArray[index - SS];
1147  }
1148 
1149  private:
1150  UPInt Size;
1151  DA DynamicArray;
1152  char StaticArray[SS * sizeof(T)];
1153  };
1154 
1155 private:
1156  // StackArray, which allocates first 16 elements on stack.
1157  typedef StackArray<fmt_record, 16, ArrayPOD<fmt_record> > DataType;
1158 
1159  UInt8 EscapeChar;
1160  UInt8 FirstArgNum;
1161  UInt16 NonPosParamNum;
1162  UInt16 UnboundFmtrInd;
1163  UPInt StrSize;
1164  SPInt DataInd;
1165  const LocaleProvider* pLocaleProvider;
1166  const Sink Result;
1167 
1168  DataType Data;
1169  MemoryPoolType MemPool;
1170 };
1171 
1172 
1174 // Formatter type traits.
1175 
1176 template <typename T>
1177 struct FmtInfo
1178 {
1179 };
1180 
1182 
1183 // ***** Format
1184 
1185 // Format is supposed to replace the sprintf function.
1186 // It doesn't not to declare argument's data types in a formatted string.
1187 
1188 // 0
1189 inline
1190 UPInt Format(
1191  const MsgFormat::Sink& result,
1192  const char* fmt
1193  )
1194 {
1195  MsgFormat parsed_format(result);
1196 
1197  parsed_format.Parse(fmt);
1198  parsed_format.FinishFormatD();
1199  return parsed_format.GetStrSize();
1200 }
1201 
1202 inline
1203 UPInt Format(
1204  const MsgFormat::Sink& result,
1205  const LocaleProvider& loc,
1206  const char* fmt
1207  )
1208 {
1209  MsgFormat parsed_format(result, loc);
1210 
1211  parsed_format.Parse(fmt);
1212  parsed_format.FinishFormatD();
1213  return parsed_format.GetStrSize();
1214 }
1215 
1217 // Format is developed as a list of FormatD1 calls in order to produce smaller
1218 // code with CodeWarrior for Wii.
1219 
1220 // 1 ...
1221 template <typename T1>
1222 inline
1223 UPInt Format(
1224  const MsgFormat::Sink& result,
1225  const char* fmt,
1226  const T1& v1
1227  )
1228 {
1229  MsgFormat parsed_format(result);
1230 
1231  parsed_format.Parse(fmt);
1232  parsed_format.FormatD1(v1);
1233  parsed_format.FinishFormatD();
1234  return parsed_format.GetStrSize();
1235 }
1236 
1237 template <typename T1>
1238 inline
1239 UPInt Format(
1240  const MsgFormat::Sink& result,
1241  const LocaleProvider& loc,
1242  const char* fmt,
1243  const T1& v1
1244  )
1245 {
1246  MsgFormat parsed_format(result, loc);
1247 
1248  parsed_format.Parse(fmt);
1249  parsed_format.FormatD1(v1);
1250  parsed_format.FinishFormatD();
1251  return parsed_format.GetStrSize();
1252 }
1253 
1254 // 2 ...
1255 template <typename T1, typename T2>
1256 inline
1257 UPInt Format(
1258  const MsgFormat::Sink& result,
1259  const char* fmt,
1260  const T1& v1,
1261  const T2& v2
1262  )
1263 {
1264  MsgFormat parsed_format(result);
1265 
1266  parsed_format.Parse(fmt);
1267  parsed_format.FormatD1(v1);
1268  parsed_format.FormatD1(v2);
1269  parsed_format.FinishFormatD();
1270  return parsed_format.GetStrSize();
1271 }
1272 
1273 template <typename T1, typename T2>
1274 inline
1275 UPInt Format(
1276  const MsgFormat::Sink& result,
1277  const LocaleProvider& loc,
1278  const char* fmt,
1279  const T1& v1,
1280  const T2& v2
1281  )
1282 {
1283  MsgFormat parsed_format(result, loc);
1284 
1285  parsed_format.Parse(fmt);
1286  parsed_format.FormatD1(v1);
1287  parsed_format.FormatD1(v2);
1288  parsed_format.FinishFormatD();
1289  return parsed_format.GetStrSize();
1290 }
1291 
1292 // 3 ...
1293 template <typename T1, typename T2, typename T3>
1294 inline
1295 UPInt Format(
1296  const MsgFormat::Sink& result,
1297  const char* fmt,
1298  const T1& v1,
1299  const T2& v2,
1300  const T3& v3
1301  )
1302 {
1303  MsgFormat parsed_format(result);
1304 
1305  parsed_format.Parse(fmt);
1306  parsed_format.FormatD1(v1);
1307  parsed_format.FormatD1(v2);
1308  parsed_format.FormatD1(v3);
1309  parsed_format.FinishFormatD();
1310  return parsed_format.GetStrSize();
1311 }
1312 
1313 template <typename T1, typename T2, typename T3>
1314 inline
1315 UPInt Format(
1316  const MsgFormat::Sink& result,
1317  const LocaleProvider& loc,
1318  const char* fmt,
1319  const T1& v1,
1320  const T2& v2,
1321  const T3& v3
1322  )
1323 {
1324  MsgFormat parsed_format(result, loc);
1325 
1326  parsed_format.Parse(fmt);
1327  parsed_format.FormatD1(v1);
1328  parsed_format.FormatD1(v2);
1329  parsed_format.FormatD1(v3);
1330  parsed_format.FinishFormatD();
1331  return parsed_format.GetStrSize();
1332 }
1333 
1334 // 4 ...
1335 template <typename T1, typename T2, typename T3, typename T4>
1336 inline
1337 UPInt Format(
1338  const MsgFormat::Sink& result,
1339  const char* fmt,
1340  const T1& v1,
1341  const T2& v2,
1342  const T3& v3,
1343  const T4& v4
1344  )
1345 {
1346  MsgFormat parsed_format(result);
1347 
1348  parsed_format.Parse(fmt);
1349  parsed_format.FormatD1(v1);
1350  parsed_format.FormatD1(v2);
1351  parsed_format.FormatD1(v3);
1352  parsed_format.FormatD1(v4);
1353  parsed_format.FinishFormatD();
1354  return parsed_format.GetStrSize();
1355 }
1356 
1357 template <typename T1, typename T2, typename T3, typename T4>
1358 inline
1359 UPInt Format(
1360  const MsgFormat::Sink& result,
1361  const LocaleProvider& loc,
1362  const char* fmt,
1363  const T1& v1,
1364  const T2& v2,
1365  const T3& v3,
1366  const T4& v4
1367  )
1368 {
1369  MsgFormat parsed_format(result, loc);
1370 
1371  parsed_format.Parse(fmt);
1372  parsed_format.FormatD1(v1);
1373  parsed_format.FormatD1(v2);
1374  parsed_format.FormatD1(v3);
1375  parsed_format.FormatD1(v4);
1376  parsed_format.FinishFormatD();
1377  return parsed_format.GetStrSize();
1378 }
1379 
1380 // 5 ...
1381 template <typename T1, typename T2, typename T3, typename T4, typename T5>
1382 inline
1383 UPInt Format(
1384  const MsgFormat::Sink& result,
1385  const char* fmt,
1386  const T1& v1,
1387  const T2& v2,
1388  const T3& v3,
1389  const T4& v4,
1390  const T5& v5
1391  )
1392 {
1393  MsgFormat parsed_format(result);
1394 
1395  parsed_format.Parse(fmt);
1396  parsed_format.FormatD1(v1);
1397  parsed_format.FormatD1(v2);
1398  parsed_format.FormatD1(v3);
1399  parsed_format.FormatD1(v4);
1400  parsed_format.FormatD1(v5);
1401  parsed_format.FinishFormatD();
1402  return parsed_format.GetStrSize();
1403 }
1404 
1405 template <typename T1, typename T2, typename T3, typename T4, typename T5>
1406 inline
1407 UPInt Format(
1408  const MsgFormat::Sink& result,
1409  const LocaleProvider& loc,
1410  const char* fmt,
1411  const T1& v1,
1412  const T2& v2,
1413  const T3& v3,
1414  const T4& v4,
1415  const T5& v5
1416  )
1417 {
1418  MsgFormat parsed_format(result, loc);
1419 
1420  parsed_format.Parse(fmt);
1421  parsed_format.FormatD1(v1);
1422  parsed_format.FormatD1(v2);
1423  parsed_format.FormatD1(v3);
1424  parsed_format.FormatD1(v4);
1425  parsed_format.FormatD1(v5);
1426  parsed_format.FinishFormatD();
1427  return parsed_format.GetStrSize();
1428 }
1429 
1430 // 6 ...
1431 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
1432 inline
1433 UPInt Format(
1434  const MsgFormat::Sink& result,
1435  const char* fmt,
1436  const T1& v1,
1437  const T2& v2,
1438  const T3& v3,
1439  const T4& v4,
1440  const T5& v5,
1441  const T6& v6
1442  )
1443 {
1444  MsgFormat parsed_format(result);
1445 
1446  parsed_format.Parse(fmt);
1447  parsed_format.FormatD1(v1);
1448  parsed_format.FormatD1(v2);
1449  parsed_format.FormatD1(v3);
1450  parsed_format.FormatD1(v4);
1451  parsed_format.FormatD1(v5);
1452  parsed_format.FormatD1(v6);
1453  parsed_format.FinishFormatD();
1454  return parsed_format.GetStrSize();
1455 }
1456 
1457 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
1458 inline
1459 UPInt Format(
1460  const MsgFormat::Sink& result,
1461  const LocaleProvider& loc,
1462  const char* fmt,
1463  const T1& v1,
1464  const T2& v2,
1465  const T3& v3,
1466  const T4& v4,
1467  const T5& v5,
1468  const T6& v6
1469  )
1470 {
1471  MsgFormat parsed_format(result, loc);
1472 
1473  parsed_format.Parse(fmt);
1474  parsed_format.FormatD1(v1);
1475  parsed_format.FormatD1(v2);
1476  parsed_format.FormatD1(v3);
1477  parsed_format.FormatD1(v4);
1478  parsed_format.FormatD1(v5);
1479  parsed_format.FormatD1(v6);
1480  parsed_format.FinishFormatD();
1481  return parsed_format.GetStrSize();
1482 }
1483 
1484 // 7 ...
1485 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
1486 inline
1487 UPInt Format(
1488  const MsgFormat::Sink& result,
1489  const char* fmt,
1490  const T1& v1,
1491  const T2& v2,
1492  const T3& v3,
1493  const T4& v4,
1494  const T5& v5,
1495  const T6& v6,
1496  const T7& v7
1497  )
1498 {
1499  MsgFormat parsed_format(result);
1500 
1501  parsed_format.Parse(fmt);
1502  parsed_format.FormatD1(v1);
1503  parsed_format.FormatD1(v2);
1504  parsed_format.FormatD1(v3);
1505  parsed_format.FormatD1(v4);
1506  parsed_format.FormatD1(v5);
1507  parsed_format.FormatD1(v6);
1508  parsed_format.FormatD1(v7);
1509  parsed_format.FinishFormatD();
1510  return parsed_format.GetStrSize();
1511 }
1512 
1513 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
1514 inline
1515 UPInt Format(
1516  const MsgFormat::Sink& result,
1517  const LocaleProvider& loc,
1518  const char* fmt,
1519  const T1& v1,
1520  const T2& v2,
1521  const T3& v3,
1522  const T4& v4,
1523  const T5& v5,
1524  const T6& v6,
1525  const T7& v7
1526  )
1527 {
1528  MsgFormat parsed_format(result, loc);
1529 
1530  parsed_format.Parse(fmt);
1531  parsed_format.FormatD1(v1);
1532  parsed_format.FormatD1(v2);
1533  parsed_format.FormatD1(v3);
1534  parsed_format.FormatD1(v4);
1535  parsed_format.FormatD1(v5);
1536  parsed_format.FormatD1(v6);
1537  parsed_format.FormatD1(v7);
1538  parsed_format.FinishFormatD();
1539  return parsed_format.GetStrSize();
1540 }
1541 
1542 // 8 ...
1543 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
1544 inline
1545 UPInt Format(
1546  const MsgFormat::Sink& result,
1547  const char* fmt,
1548  const T1& v1,
1549  const T2& v2,
1550  const T3& v3,
1551  const T4& v4,
1552  const T5& v5,
1553  const T6& v6,
1554  const T7& v7,
1555  const T8& v8
1556  )
1557 {
1558  MsgFormat parsed_format(result);
1559 
1560  parsed_format.Parse(fmt);
1561  parsed_format.FormatD1(v1);
1562  parsed_format.FormatD1(v2);
1563  parsed_format.FormatD1(v3);
1564  parsed_format.FormatD1(v4);
1565  parsed_format.FormatD1(v5);
1566  parsed_format.FormatD1(v6);
1567  parsed_format.FormatD1(v7);
1568  parsed_format.FormatD1(v8);
1569  parsed_format.FinishFormatD();
1570  return parsed_format.GetStrSize();
1571 }
1572 
1573 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8>
1574 inline
1575 UPInt Format(
1576  const MsgFormat::Sink& result,
1577  const LocaleProvider& loc,
1578  const char* fmt,
1579  const T1& v1,
1580  const T2& v2,
1581  const T3& v3,
1582  const T4& v4,
1583  const T5& v5,
1584  const T6& v6,
1585  const T7& v7,
1586  const T8& v8
1587  )
1588 {
1589  MsgFormat parsed_format(result, loc);
1590 
1591  parsed_format.Parse(fmt);
1592  parsed_format.FormatD1(v1);
1593  parsed_format.FormatD1(v2);
1594  parsed_format.FormatD1(v3);
1595  parsed_format.FormatD1(v4);
1596  parsed_format.FormatD1(v5);
1597  parsed_format.FormatD1(v6);
1598  parsed_format.FormatD1(v7);
1599  parsed_format.FormatD1(v8);
1600  parsed_format.FinishFormatD();
1601  return parsed_format.GetStrSize();
1602 }
1603 
1604 // 9 ...
1605 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
1606 inline
1607 UPInt Format(
1608  const MsgFormat::Sink& result,
1609  const char* fmt,
1610  const T1& v1,
1611  const T2& v2,
1612  const T3& v3,
1613  const T4& v4,
1614  const T5& v5,
1615  const T6& v6,
1616  const T7& v7,
1617  const T8& v8,
1618  const T9& v9
1619  )
1620 {
1621  MsgFormat parsed_format(result);
1622 
1623  parsed_format.Parse(fmt);
1624  parsed_format.FormatD1(v1);
1625  parsed_format.FormatD1(v2);
1626  parsed_format.FormatD1(v3);
1627  parsed_format.FormatD1(v4);
1628  parsed_format.FormatD1(v5);
1629  parsed_format.FormatD1(v6);
1630  parsed_format.FormatD1(v7);
1631  parsed_format.FormatD1(v8);
1632  parsed_format.FormatD1(v9);
1633  parsed_format.FinishFormatD();
1634  return parsed_format.GetStrSize();
1635 }
1636 
1637 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9>
1638 inline
1639 UPInt Format(
1640  const MsgFormat::Sink& result,
1641  const LocaleProvider& loc,
1642  const char* fmt,
1643  const T1& v1,
1644  const T2& v2,
1645  const T3& v3,
1646  const T4& v4,
1647  const T5& v5,
1648  const T6& v6,
1649  const T7& v7,
1650  const T8& v8,
1651  const T9& v9
1652  )
1653 {
1654  MsgFormat parsed_format(result, loc);
1655 
1656  parsed_format.Parse(fmt);
1657  parsed_format.FormatD1(v1);
1658  parsed_format.FormatD1(v2);
1659  parsed_format.FormatD1(v3);
1660  parsed_format.FormatD1(v4);
1661  parsed_format.FormatD1(v5);
1662  parsed_format.FormatD1(v6);
1663  parsed_format.FormatD1(v7);
1664  parsed_format.FormatD1(v8);
1665  parsed_format.FormatD1(v9);
1666  parsed_format.FinishFormatD();
1667  return parsed_format.GetStrSize();
1668 }
1669 
1670 // 10 ...
1671 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
1672 inline
1673 UPInt Format(
1674  const MsgFormat::Sink& result,
1675  const char* fmt,
1676  const T1& v1,
1677  const T2& v2,
1678  const T3& v3,
1679  const T4& v4,
1680  const T5& v5,
1681  const T6& v6,
1682  const T7& v7,
1683  const T8& v8,
1684  const T9& v9,
1685  const T10& v10
1686  )
1687 {
1688  MsgFormat parsed_format(result);
1689 
1690  parsed_format.Parse(fmt);
1691  parsed_format.FormatD1(v1);
1692  parsed_format.FormatD1(v2);
1693  parsed_format.FormatD1(v3);
1694  parsed_format.FormatD1(v4);
1695  parsed_format.FormatD1(v5);
1696  parsed_format.FormatD1(v6);
1697  parsed_format.FormatD1(v7);
1698  parsed_format.FormatD1(v8);
1699  parsed_format.FormatD1(v9);
1700  parsed_format.FormatD1(v10);
1701  parsed_format.FinishFormatD();
1702  return parsed_format.GetStrSize();
1703 }
1704 
1705 template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7, typename T8, typename T9, typename T10>
1706 inline
1707 UPInt Format(
1708  const MsgFormat::Sink& result,
1709  const LocaleProvider& loc,
1710  const char* fmt,
1711  const T1& v1,
1712  const T2& v2,
1713  const T3& v3,
1714  const T4& v4,
1715  const T5& v5,
1716  const T6& v6,
1717  const T7& v7,
1718  const T8& v8,
1719  const T9& v9,
1720  const T10& v10
1721  )
1722 {
1723  MsgFormat parsed_format(result, loc);
1724 
1725  parsed_format.Parse(fmt);
1726  parsed_format.FormatD1(v1);
1727  parsed_format.FormatD1(v2);
1728  parsed_format.FormatD1(v3);
1729  parsed_format.FormatD1(v4);
1730  parsed_format.FormatD1(v5);
1731  parsed_format.FormatD1(v6);
1732  parsed_format.FormatD1(v7);
1733  parsed_format.FormatD1(v8);
1734  parsed_format.FormatD1(v9);
1735  parsed_format.FormatD1(v10);
1736  parsed_format.FinishFormatD();
1737  return parsed_format.GetStrSize();
1738 }
1739 
1741 
1742 // ***** SPrintF
1743 
1744 // This function behaves identically to sprintf.
1745 // Return value: size of resulting string.
1746 UPInt SPrintF(const MsgFormat::Sink& result, const char* fmt, ...);
1747 
1749 
1750 // ***** ReadInteger
1751 
1752 // Utility function, which tries to read an integer.
1753 // It returns read integer value on success, or defaultValue otherwise.
1754 // It will trim string if an integer was successfully read.
1755 int ReadInteger(StringDataPtr& str, int defaultValue, char separator = ':');
1756 
1757 template <typename T>
1758 String AsString(const T& v)
1759 {
1760  String sink;
1761  Format(sink, "{0}", v);
1762  return sink;
1763 }
1764 
1765 } // Scaleform
1766 
1767 #endif //INC_SF_Kernel_MsgFormat_H
Definition: gamekitcrowddispersion.h:20