Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
trace.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2010 Wildfire Games
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining
4  * a copy of this software and associated documentation files (the
5  * "Software"), to deal in the Software without restriction, including
6  * without limitation the rights to use, copy, modify, merge, publish,
7  * distribute, sublicense, and/or sell copies of the Software, and to
8  * permit persons to whom the Software is furnished to do so, subject to
9  * the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 /*
24  * IO event recording
25  */
26 
27 #include "precompiled.h"
28 #include "lib/file/common/trace.h"
29 
30 #include <cstdio>
31 #include <sstream>
32 
33 #include "lib/allocators/pool.h"
34 #include "lib/timer.h" // timer_Time
35 #include "lib/sysdep/sysdep.h" // sys_OpenFile
36 
37 
38 /*virtual*/ ITrace::~ITrace()
39 {
40 
41 }
42 
43 
44 //-----------------------------------------------------------------------------
45 
46 TraceEntry::TraceEntry(EAction action, const Path& pathname, size_t size)
47 : m_timestamp((float)timer_Time())
48 , m_action(action)
49 , m_pathname(pathname)
50 , m_size(size)
51 {
52 }
53 
54 
55 TraceEntry::TraceEntry(const std::wstring& text)
56 {
57  // swscanf is far too awkward to get working cross-platform,
58  // so use iostreams here instead
59 
60  wchar_t dummy;
61  wchar_t action;
62 
63  std::wstringstream stream(text);
64  stream >> m_timestamp;
65 
66  stream >> dummy;
67  ENSURE(dummy == ':');
68 
69  stream >> action;
70  ENSURE(action == 'L' || action == 'S');
71  m_action = (EAction)action;
72 
73  stream >> dummy;
74  ENSURE(dummy == '"');
75 
76  Path::String pathname;
77  std::getline(stream, pathname, L'"');
78  m_pathname = Path(pathname);
79 
80  stream >> m_size;
81 
82  ENSURE(stream.get() == '\n');
83  ENSURE(stream.good());
84  ENSURE(stream.get() == WEOF);
85 }
86 
87 
88 std::wstring TraceEntry::EncodeAsText() const
89 {
90  const wchar_t action = (wchar_t)m_action;
91  wchar_t buf[1000];
92  swprintf_s(buf, ARRAY_SIZE(buf), L"%#010f: %c \"%ls\" %lu\n", m_timestamp, action, m_pathname.string().c_str(), (unsigned long)m_size);
93  return buf;
94 }
95 
96 
97 //-----------------------------------------------------------------------------
98 
99 class Trace_Dummy : public ITrace
100 {
101 public:
102  Trace_Dummy(size_t UNUSED(maxSize))
103  {
104 
105  }
106 
107  virtual void NotifyLoad(const Path& UNUSED(pathname), size_t UNUSED(size))
108  {
109  }
110 
111  virtual void NotifyStore(const Path& UNUSED(pathname), size_t UNUSED(size))
112  {
113  }
114 
115  virtual Status Load(const OsPath& UNUSED(pathname))
116  {
117  return INFO::OK;
118  }
119 
120  virtual Status Store(const OsPath& UNUSED(pathname)) const
121  {
122  return INFO::OK;
123  }
124 
125  virtual const TraceEntry* Entries() const
126  {
127  return 0;
128  }
129 
130  virtual size_t NumEntries() const
131  {
132  return 0;
133  }
134 };
135 
136 
137 //-----------------------------------------------------------------------------
138 
139 class Trace : public ITrace
140 {
141 public:
142  Trace(size_t maxSize)
143  {
144  (void)pool_create(&m_pool, maxSize, sizeof(TraceEntry));
145  }
146 
147  virtual ~Trace()
148  {
149  for(size_t i = 0; i < NumEntries(); i++)
150  {
151  TraceEntry* entry = (TraceEntry*)(uintptr_t(m_pool.da.base) + i*m_pool.el_size);
152  entry->~TraceEntry();
153  }
154 
155  (void)pool_destroy(&m_pool);
156  }
157 
158  virtual void NotifyLoad(const Path& pathname, size_t size)
159  {
160  new(Allocate()) TraceEntry(TraceEntry::Load, pathname, size);
161  }
162 
163  virtual void NotifyStore(const Path& pathname, size_t size)
164  {
165  new(Allocate()) TraceEntry(TraceEntry::Store, pathname, size);
166  }
167 
168  virtual Status Load(const OsPath& pathname)
169  {
171 
172  errno = 0;
173  FILE* file = sys_OpenFile(pathname, "rt");
174  if(!file)
176 
177  for(;;)
178  {
179  wchar_t text[500];
180  if(!fgetws(text, ARRAY_SIZE(text)-1, file))
181  break;
182  new(Allocate()) TraceEntry(text);
183  }
184  fclose(file);
185 
186  return INFO::OK;
187  }
188 
189  virtual Status Store(const OsPath& pathname) const
190  {
191  errno = 0;
192  FILE* file = sys_OpenFile(pathname, "at");
193  if(!file)
195  for(size_t i = 0; i < NumEntries(); i++)
196  {
197  std::wstring text = Entries()[i].EncodeAsText();
198  fputws(text.c_str(), file);
199  }
200  (void)fclose(file);
201  return INFO::OK;
202  }
203 
204  virtual const TraceEntry* Entries() const
205  {
206  return (const TraceEntry*)m_pool.da.base;
207  }
208 
209  virtual size_t NumEntries() const
210  {
211  return m_pool.da.pos / m_pool.el_size;
212  }
213 
214 private:
215  void* Allocate()
216  {
217  void* p = pool_alloc(&m_pool, 0);
218  ENSURE(p);
219  return p;
220  }
221 
223 };
224 
225 
226 PITrace CreateDummyTrace(size_t maxSize)
227 {
228  return PITrace(new Trace_Dummy(maxSize));
229 }
230 
231 PITrace CreateTrace(size_t maxSize)
232 {
233  return PITrace(new Trace(maxSize));
234 }
virtual size_t NumEntries() const
Definition: trace.cpp:130
Path m_pathname
Definition: trace.h:81
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
const Status OK
Definition: status.h:386
shared_ptr< ITrace > PITrace
Definition: trace.h:123
virtual const TraceEntry * Entries() const
Definition: trace.cpp:204
virtual Status Load(const OsPath &pathname)
load entries from file.
Definition: trace.cpp:168
EAction m_action
Definition: trace.h:79
void * pool_alloc(Pool *p, size_t size)
Dole out memory from the pool.
Definition: pool.cpp:120
virtual Status Store(const OsPath &pathname) const
store all entries into a file.
Definition: trace.cpp:120
virtual void NotifyLoad(const Path &pathname, size_t size)
Definition: trace.cpp:107
int swprintf_s(wchar_t *buf, size_t max_chars, const wchar_t *fmt,...) WPRINTF_ARGS(3)
std::wstring EncodeAsText() const
Definition: trace.cpp:88
Status pool_create(Pool *p, size_t max_size, size_t el_size)
Ready Pool for use.
Definition: pool.cpp:86
#define ARRAY_SIZE(name)
FILE * sys_OpenFile(const OsPath &pathname, const char *mode)
open a file like with fopen (but taking an OsPath argument).
Definition: unix.cpp:373
virtual void NotifyStore(const Path &pathname, size_t size)
Definition: trace.cpp:163
Definition: trace.h:92
virtual size_t NumEntries() const
Definition: trace.cpp:209
TraceEntry(EAction action, const Path &pathname, size_t size)
Definition: trace.cpp:46
virtual void NotifyStore(const Path &pathname, size_t size)
Definition: trace.cpp:111
float m_timestamp
Definition: trace.h:77
#define ENSURE(expr)
ensure the expression &lt;expr&gt; evaluates to non-zero.
Definition: debug.h:282
u8 * base
Definition: dynarray.h:41
Definition: path.h:75
const String & string() const
Definition: path.h:123
std::wstring String
Definition: path.h:78
virtual ~ITrace()
Definition: trace.cpp:38
Definition: trace.cpp:139
void * Allocate()
Definition: trace.cpp:215
i64 Status
Error handling system.
Definition: status.h:171
double timer_Time()
Definition: timer.cpp:98
allocator design parameters:
Definition: pool.h:114
size_t pos
Definition: dynarray.h:46
virtual const TraceEntry * Entries() const
Definition: trace.cpp:125
Status StatusFromErrno()
Definition: status.cpp:105
virtual ~Trace()
Definition: trace.cpp:147
DynArray da
Definition: pool.h:116
Trace(size_t maxSize)
Definition: trace.cpp:142
virtual void NotifyLoad(const Path &pathname, size_t size)
Definition: trace.cpp:158
virtual Status Store(const OsPath &pathname) const
store all entries into a file.
Definition: trace.cpp:189
size_t m_size
Definition: trace.h:86
unsigned short wchar_t
Definition: wgl.h:78
size_t el_size
size of elements.
Definition: pool.h:122
void pool_free_all(Pool *p)
&quot;free&quot; all user allocations that ensued from the given Pool.
Definition: pool.cpp:164
PITrace CreateTrace(size_t maxSize)
Definition: trace.cpp:231
#define WARN_RETURN(status)
Definition: status.h:255
PITrace CreateDummyTrace(size_t maxSize)
Definition: trace.cpp:226
Status pool_destroy(Pool *p)
free all memory (address space + physical) that constitutes the given Pool.
Definition: pool.cpp:98
virtual Status Load(const OsPath &pathname)
load entries from file.
Definition: trace.cpp:115
Pool m_pool
Definition: trace.cpp:222