-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCFileStreamReader.cpp
172 lines (132 loc) · 3.72 KB
/
CFileStreamReader.cpp
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include "stdafx.h"
#include "CFileStreamReader.h"
extern int g_cLocks;
// IUnknown
// ********
ULONG __stdcall CFileStreamReader::AddRef()
{
return ++m_cRef;
}
ULONG __stdcall CFileStreamReader::Release()
{
if (--m_cRef != 0)
return m_cRef;
delete this;
return 0;
}
HRESULT __stdcall CFileStreamReader::QueryInterface(REFIID riid, void** ppv)
{
if(riid == IID_IUnknown)
*ppv = (IUnknown*)this;
else if(riid == IID_StreamReader)
*ppv = (StreamReader*)this;
else if(riid == IID_SeekableStreamReader)
*ppv = (SeekableStreamReader*)this;
else
{
*ppv = NULL;
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
// StreamReader
// ************
HRESULT CFileStreamReader::Read(int numBytes, int pBuffer, int *numBytesRead)
{
BOOL bResult;
unsigned long numberOfBytesRead;
// Read in the info
bResult = ReadFile(hFile, (void*)pBuffer, numBytes, &numberOfBytesRead, NULL);
*numBytesRead = numberOfBytesRead;
// Adjust the status of the stream
if ((bResult == 0) || (*numBytesRead < numBytes))
{
if (bResult == 0)
OutputDebugStringW(L"Error. ReadFile error.");
else if (*numBytesRead < numBytes)
OutputDebugStringW(L"End of file reached.");
// An error occured or a read past EOF occured
status = 1; // Nonzero denotes error
}
return S_OK;
}
HRESULT CFileStreamReader::get_Status(int *status)
{
*status = this->status;
return S_OK;
}
// SeekableStreamReader
// ********************
HRESULT CFileStreamReader::get_ReadOffset(int *readOffset)
{
*readOffset = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
return S_OK;
}
HRESULT CFileStreamReader::get_StreamSize(int *streamSize)
{
*streamSize = GetFileSize(hFile, NULL);
return S_OK;
}
HRESULT CFileStreamReader::Seek(int offset)
{
if (SetFilePointer(hFile, offset, NULL, FILE_BEGIN) == -1)
{
// Seek error.
status = 1; // Error
return E_FAIL;
}
return S_OK;
}
// Class specific
// **************
CFileStreamReader::CFileStreamReader(BSTR fileName) : m_cRef(1)
{
// Initialize class variables
status = 0;
// Open the file
hFile = CreateFileW(fileName, // lpFileName
GENERIC_READ, // dwDesired access
FILE_SHARE_READ,// dwShareMode
NULL, // lpSecurityAttributes
OPEN_EXISTING, // dwCreationDisposition
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_SEQUENTIAL_SCAN,
// dwFlagsAndAttributes
NULL // hTemplate
);
// Check if the file was opened successfully
if (hFile == INVALID_HANDLE_VALUE)
throw L"Could not open file for writing.";
// Check for alternate error
if (hFile == 0)
{
// Try to open the file using ANSI version of CreateFile
// Allocate space for a temporary ASCII fileName string
int stringLength = SysStringLen(fileName);
char *tempString = new char[stringLength+1];
tempString[stringLength] = 0; // NULL terminate it
// Convert the BSTR to ASCII
WideCharToMultiByte(CP_ACP, 0, fileName, stringLength, tempString, stringLength, 0, 0);
// Try to open the file with ANSI version of CreateFile
hFile = CreateFileA(tempString, // lpFileName
GENERIC_READ, // dwDesired access
FILE_SHARE_READ,// dwShareMode
NULL, // lpSecurityAttributes
OPEN_EXISTING, // dwCreationDisposition
FILE_ATTRIBUTE_NORMAL |
FILE_FLAG_SEQUENTIAL_SCAN,
// dwFlagsAndAttributes
NULL // hTemplate
);
// Check for errors
if (hFile == INVALID_HANDLE_VALUE)
throw L"Could not open file for writing.";
}
g_cLocks++;
}
CFileStreamReader::~CFileStreamReader()
{
CloseHandle(hFile);
g_cLocks--;
}