aboutsummaryrefslogtreecommitdiff
path: root/dep/CascLib/src/common/DumpContext.cpp
blob: 8783ff201ba2bb6aa25ab0c7b84393d2e544aa2c (plain)
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;
}