Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DebugSerializer.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2011 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "precompiled.h"
19 
20 #include "DebugSerializer.h"
21 
23 
24 #include "lib/secure_crt.h"
25 #include "lib/utf8.h"
26 #include "ps/CStr.h"
27 
28 #include <sstream>
29 #include <iomanip>
30 
31 /*
32  * The output format here is intended to be compatible with YAML,
33  * so it is human readable and usable in diff and can also be parsed with
34  * external tools.
35  */
36 
37 // MSVC and GCC give slightly different serializations of floats
38 // (e.g. "1e+010" vs "1e+10"). To make the debug serialization easily comparable
39 // across platforms, we want to convert to a canonical form.
40 // TODO: we just do e+0xx now; ought to handle varying precisions and inf and nan etc too
41 template<typename T>
42 std::string canonfloat(T value, int prec)
43 {
44  std::stringstream str;
45  str << std::setprecision(prec) << value;
46  std::string r = str.str();
47  size_t e = r.find('e');
48  if (e == r.npos) // no "e"
49  return r;
50  if (e == r.length() - 5 && r[e + 2] == '0') // e.g. "1e+010"
51  r.erase(e + 2, 1);
52  return r;
53 }
54 
55 CDebugSerializer::CDebugSerializer(ScriptInterface& scriptInterface, std::ostream& stream, bool includeDebugInfo) :
56  m_ScriptInterface(scriptInterface), m_Stream(stream), m_IsDebug(includeDebugInfo), m_Indent(0)
57 {
58 }
59 
60 void CDebugSerializer::Indent(int spaces)
61 {
62  m_Indent += spaces;
63 }
64 
65 void CDebugSerializer::Dedent(int spaces)
66 {
67  ENSURE(spaces <= m_Indent);
68  m_Indent -= spaces;
69 }
70 
71 #define INDENT std::string(m_Indent, ' ')
72 
73 void CDebugSerializer::Comment(const std::string& comment)
74 {
75  m_Stream << INDENT << "# " << comment << "\n";
76 }
77 
78 void CDebugSerializer::TextLine(const std::string& text)
79 {
80  m_Stream << INDENT << text << "\n";
81 }
82 
83 void CDebugSerializer::PutNumber(const char* name, uint8_t value)
84 {
85  m_Stream << INDENT << name << ": " << (int)value << "\n";
86 }
87 
88 void CDebugSerializer::PutNumber(const char* name, int8_t value)
89 {
90  m_Stream << INDENT << name << ": " << (int)value << "\n";
91 }
92 
93 void CDebugSerializer::PutNumber(const char* name, uint16_t value)
94 {
95  m_Stream << INDENT << name << ": " << value << "\n";
96 }
97 
98 void CDebugSerializer::PutNumber(const char* name, int16_t value)
99 {
100  m_Stream << INDENT << name << ": " << value << "\n";
101 }
102 
103 void CDebugSerializer::PutNumber(const char* name, uint32_t value)
104 {
105  m_Stream << INDENT << name << ": " << value << "\n";
106 }
107 
108 void CDebugSerializer::PutNumber(const char* name, int32_t value)
109 {
110  m_Stream << INDENT << name << ": " << value << "\n";
111 }
112 
113 void CDebugSerializer::PutNumber(const char* name, float value)
114 {
115  m_Stream << INDENT << name << ": " << canonfloat(value, 8) << "\n";
116 }
117 
118 void CDebugSerializer::PutNumber(const char* name, double value)
119 {
120  m_Stream << INDENT << name << ": " << canonfloat(value, 17) << "\n";
121 }
122 
123 void CDebugSerializer::PutNumber(const char* name, fixed value)
124 {
125  m_Stream << INDENT << name << ": " << value.ToString() << "\n";
126 }
127 
128 void CDebugSerializer::PutBool(const char* name, bool value)
129 {
130  m_Stream << INDENT << name << ": " << (value ? "true" : "false") << "\n";
131 }
132 
133 void CDebugSerializer::PutString(const char* name, const std::string& value)
134 {
135  std::string escaped;
136  escaped.reserve(value.size());
137  for (size_t i = 0; i < value.size(); ++i)
138  if (value[i] == '"')
139  escaped += "\\\"";
140  else if (value[i] == '\\')
141  escaped += "\\\\";
142  else if (value[i] == '\n')
143  escaped += "\\n";
144  else
145  escaped += value[i];
146 
147  m_Stream << INDENT << name << ": " << "\"" << escaped << "\"\n";
148 }
149 
150 void CDebugSerializer::PutScriptVal(const char* name, jsval value)
151 {
152  std::wstring source = m_ScriptInterface.ToString(value, true);
153 
154  m_Stream << INDENT << name << ": " << utf8_from_wstring(source) << "\n";
155 }
156 
157 void CDebugSerializer::PutRaw(const char* name, const u8* data, size_t len)
158 {
159  m_Stream << INDENT << name << ": (" << len << " bytes)";
160 
161  char buf[4];
162  for (size_t i = 0; i < len; ++i)
163  {
164  sprintf_s(buf, ARRAY_SIZE(buf), " %02x", (unsigned int)data[i]);
165  m_Stream << buf;
166  }
167 
168  m_Stream << "\n";
169 }
170 
172 {
173  return m_IsDebug;
174 }
175 
177 {
178  return m_Stream;
179 }
signed char int8_t
Definition: wposix_types.h:37
#define u8
Definition: types.h:39
A simple fixed-point number class.
Definition: Fixed.h:115
#define INDENT
std::string utf8_from_wstring(const std::wstring &src, Status *err)
opposite of wstring_from_utf8
Definition: utf8.cpp:208
virtual std::ostream & GetStream()
Returns a stream which can be used to serialize data directly.
virtual void PutBool(const char *name, bool value)
short int16_t
Definition: wposix_types.h:38
void Dedent(int spaces)
int sprintf_s(char *buf, size_t max_chars, const char *fmt,...) PRINTF_ARGS(3)
#define ARRAY_SIZE(name)
std::string canonfloat(T value, int prec)
virtual void PutScriptVal(const char *name, jsval value)
virtual void PutNumber(const char *name, uint8_t value)
#define ENSURE(expr)
ensure the expression &lt;expr&gt; evaluates to non-zero.
Definition: debug.h:282
void Indent(int spaces)
virtual bool IsDebug() const
Returns true if the serializer is being used in debug mode.
unsigned char uint8_t
Definition: wposix_types.h:51
virtual void PutRaw(const char *name, const u8 *data, size_t len)
#define T(string_literal)
Definition: secure_crt.cpp:70
void TextLine(const std::string &text)
std::ostream & m_Stream
void Comment(const std::string &comment)
virtual void PutString(const char *name, const std::string &value)
ScriptInterface & m_ScriptInterface
unsigned int uint32_t
Definition: wposix_types.h:53
CStr8 ToString() const
Returns the shortest string such that FromString will parse to the correct value. ...
Definition: Fixed.cpp:96
Abstraction around a SpiderMonkey JSContext.
std::wstring ToString(jsval obj, bool pretty=false)
unsigned short uint16_t
Definition: wposix_types.h:52
CDebugSerializer(ScriptInterface &scriptInterface, std::ostream &stream, bool includeDebugInfo=true)