1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
|
/*****************************************************************************/
/* DumpContext.cpp Copyright (c) Ladislav Zezula 2015 */
/*---------------------------------------------------------------------------*/
/* Implementation of dump context */
/*---------------------------------------------------------------------------*/
/* Date Ver Who Comment */
/* -------- ---- --- ------- */
/* 16.03.15 1.00 Lad Created */
/*****************************************************************************/
#define __CASCLIB_SELF__
#include "../CascLib.h"
#include "../CascCommon.h"
//-----------------------------------------------------------------------------
// Local functions
static TCHAR * FormatFileName(TCascStorage * hs, const TCHAR * szNameFormat)
{
TCHAR * szFileName;
TCHAR * szSrc;
TCHAR * szTrg;
// Create copy of the file name
szFileName = szSrc = szTrg = CascNewStr(szNameFormat, 0);
if(szFileName != NULL)
{
// Format the file name
while(szSrc[0] != 0)
{
if(szSrc[0] == _T('%'))
{
// Replace "%build%" with a build number
if(!_tcsncmp(szSrc, _T("%build%"), 7))
{
szTrg += _stprintf(szTrg, _T("%u"), hs->dwBuildNumber);
szSrc += 7;
continue;
}
}
// Just copy the character
*szTrg++ = *szSrc++;
}
// Terminate the target file name
szTrg[0] = 0;
}
return szFileName;
}
//-----------------------------------------------------------------------------
// Public functions
TDumpContext * CreateDumpContext(TCascStorage * hs, const TCHAR * szNameFormat)
{
TDumpContext * dc;
TCHAR * szFileName;
// Validate the storage handle
if(hs != NULL)
{
// Calculate the number of bytes needed for dump context
dc = CASC_ALLOC(TDumpContext, 1);
if(dc != NULL)
{
// Initialize the dump context
memset(dc, 0, sizeof(TDumpContext));
// Format the real file name
szFileName = FormatFileName(hs, szNameFormat);
if(szFileName != NULL)
{
// Create the file
dc->pStream = FileStream_CreateFile(szFileName, 0);
if(dc->pStream != NULL)
{
// Initialize buffers
dc->pbBufferBegin =
dc->pbBufferPtr = dc->DumpBuffer;
dc->pbBufferEnd = dc->DumpBuffer + CASC_DUMP_BUFFER_SIZE;
// Success
CASC_FREE(szFileName);
return dc;
}
// File create failed --> delete the file name
CASC_FREE(szFileName);
}
// Free the dump context
CASC_FREE(dc);
}
}
return NULL;
}
int dump_print(TDumpContext * dc, const char * szFormat, ...)
{
va_list argList;
char szBuffer[0x200];
int nLength = 0;
// Only if the dump context is valid
if(dc != NULL)
{
// Print the buffer using sprintf
va_start(argList, szFormat);
nLength = vsprintf(szBuffer, szFormat, argList);
assert(nLength < 0x200);
va_end(argList);
// Copy the string. Replace "\n" with "\n\r"
for(int i = 0; i < nLength; i++)
{
// Flush the buffer, if needed
if((dc->pbBufferPtr + 2) >= dc->pbBufferEnd)
{
FileStream_Write(dc->pStream, NULL, dc->pbBufferBegin, (DWORD)(dc->pbBufferPtr - dc->pbBufferBegin));
dc->pbBufferPtr = dc->pbBufferBegin;
}
// Copy the char
if(szBuffer[i] == 0x0A)
*dc->pbBufferPtr++ = 0x0D;
*dc->pbBufferPtr++ = szBuffer[i];
}
}
return nLength;
}
int dump_close(TDumpContext * dc)
{
// Only if the dump context is valid
if(dc != NULL)
{
// Flush the dump context if there are some data
if(dc->pbBufferPtr > dc->pbBufferBegin)
FileStream_Write(dc->pStream, NULL, dc->pbBufferBegin, (DWORD)(dc->pbBufferPtr - dc->pbBufferBegin));
dc->pbBufferPtr = dc->pbBufferBegin;
// Free the file stream and the entire context
if(dc->pStream != NULL)
FileStream_Close(dc->pStream);
CASC_FREE(dc);
}
return 0;
}
|