-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathIStreamStdWrapper.cpp
More file actions
101 lines (86 loc) · 3.12 KB
/
IStreamStdWrapper.cpp
File metadata and controls
101 lines (86 loc) · 3.12 KB
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
#include "IStreamStdWrapper.h"
UnbufferedOLEStreamBuf::UnbufferedOLEStreamBuf(IStream* stream, std::ios_base::openmode which)
: std::streambuf(), stream_(stream), readOnly_(!(which& std::ios_base::out)) {}
UnbufferedOLEStreamBuf::~UnbufferedOLEStreamBuf() { if (!readOnly_) UnbufferedOLEStreamBuf::sync(); stream_->Release(); }
bool UnbufferedOLEStreamBuf::backup() {
LARGE_INTEGER liMove;
liMove.QuadPart = -1LL;
return SUCCEEDED(stream_->Seek(liMove, STREAM_SEEK_CUR, NULL));
}
int UnbufferedOLEStreamBuf::overflow(int ch) {
if (ch != traits_type::eof()) {
if (SUCCEEDED(stream_->Write(&ch, 1, NULL))) {
return ch;
}
}
return traits_type::eof();
}
int UnbufferedOLEStreamBuf::underflow() {
char ch = UnbufferedOLEStreamBuf::uflow();
if (ch != traits_type::eof()) {
ch = backup() ? ch : traits_type::eof();
}
return ch;
}
int UnbufferedOLEStreamBuf::uflow() {
char ch;
ULONG cbRead;
// S_FALSE indicates we've reached end of stream
return (S_OK == stream_->Read(&ch, 1, &cbRead))
? ch : traits_type::eof();
}
int UnbufferedOLEStreamBuf::pbackfail(int ch) {
if (ch != traits_type::eof()) {
ch = backup() ? ch : traits_type::eof();
}
return ch;
}
int UnbufferedOLEStreamBuf::sync() {
return SUCCEEDED(stream_->Commit(STGC_DEFAULT)) ? 0 : -1;
}
std::ios::streampos UnbufferedOLEStreamBuf::seekpos(std::ios::streampos sp, std::ios_base::openmode which) {
LARGE_INTEGER liMove;
liMove.QuadPart = sp;
return SUCCEEDED(stream_->Seek(liMove, STREAM_SEEK_SET, NULL)) ? sp : std::streampos(-1);
}
std::streampos UnbufferedOLEStreamBuf::seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which) {
STREAM_SEEK sk;
switch (way) {
case std::ios_base::beg: sk = STREAM_SEEK_SET; break;
case std::ios_base::cur: sk = STREAM_SEEK_CUR; break;
case std::ios_base::end: sk = STREAM_SEEK_END; break;
default: return -1;
}
LARGE_INTEGER liMove;
liMove.QuadPart = static_cast<LONGLONG>(off);
ULARGE_INTEGER uliNewPos;
return SUCCEEDED(stream_->Seek(liMove, sk, &uliNewPos))
? static_cast<std::streampos>(uliNewPos.QuadPart) : std::streampos (-1);
}
std::streamsize UnbufferedOLEStreamBuf::xsgetn(char* s, std::streamsize n) {
ULONG cbRead;
return SUCCEEDED(stream_->Read(s, static_cast<ULONG>(n), &cbRead))
? static_cast<std::streamsize>(cbRead) : 0;
}
std::streamsize UnbufferedOLEStreamBuf::xsputn(const char* s, std::streamsize n) {
ULONG cbWritten;
return SUCCEEDED(stream_->Write(s, static_cast<ULONG>(n), &cbWritten))
? static_cast<std::streamsize>(cbWritten) : 0;
}
std::streamsize UnbufferedOLEStreamBuf::showmanyc() {
STATSTG stat;
if (SUCCEEDED(stream_->Stat(&stat, STATFLAG_NONAME))) {
std::streampos lastPos = static_cast<std::streampos>(stat.cbSize.QuadPart - 1);
LARGE_INTEGER liMove;
liMove.QuadPart = 0LL;
ULARGE_INTEGER uliNewPos;
if (SUCCEEDED(stream_->Seek(liMove, STREAM_SEEK_CUR, &uliNewPos))) {
return std::max<std::streamsize>(lastPos - static_cast<std::streampos>(uliNewPos.QuadPart), 0);
}
}
return 0;
}
std::streambuf* StdStreamBufFromOLEStream(IStream* pStream, std::ios_base::openmode which)
{
return new (std::nothrow) UnbufferedOLEStreamBuf(pStream, which);
}