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
|
// InOutTempBuffer.cpp
#include "StdAfx.h"
#include "../../../C/7zCrc.h"
#include "../../Common/Defs.h"
#include "InOutTempBuffer.h"
#include "StreamUtils.h"
using namespace NWindows;
using namespace NFile;
using namespace NDir;
static const size_t kTempBufSize = (1 << 20);
#define kTempFilePrefixString FTEXT("7zt")
CInOutTempBuffer::CInOutTempBuffer(): _buf(NULL) { }
void CInOutTempBuffer::Create()
{
if (!_buf)
_buf = new Byte[kTempBufSize];
}
CInOutTempBuffer::~CInOutTempBuffer()
{
delete []_buf;
}
void CInOutTempBuffer::InitWriting()
{
_bufPos = 0;
_tempFileCreated = false;
_size = 0;
_crc = CRC_INIT_VAL;
}
bool CInOutTempBuffer::WriteToFile(const void *data, UInt32 size)
{
if (size == 0)
return true;
if (!_tempFileCreated)
{
if (!_tempFile.CreateRandomInTempFolder(kTempFilePrefixString, &_outFile))
return false;
_tempFileCreated = true;
}
UInt32 processed;
if (!_outFile.Write(data, size, processed))
return false;
_crc = CrcUpdate(_crc, data, processed);
_size += processed;
return (processed == size);
}
bool CInOutTempBuffer::Write(const void *data, UInt32 size)
{
if (size == 0)
return true;
size_t cur = kTempBufSize - _bufPos;
if (cur != 0)
{
if (cur > size)
cur = size;
memcpy(_buf + _bufPos, data, cur);
_crc = CrcUpdate(_crc, data, cur);
_bufPos += cur;
_size += cur;
size -= (UInt32)cur;
data = ((const Byte *)data) + cur;
}
return WriteToFile(data, size);
}
HRESULT CInOutTempBuffer::WriteToStream(ISequentialOutStream *stream)
{
if (!_outFile.Close())
return E_FAIL;
UInt64 size = 0;
UInt32 crc = CRC_INIT_VAL;
if (_bufPos != 0)
{
RINOK(WriteStream(stream, _buf, _bufPos));
crc = CrcUpdate(crc, _buf, _bufPos);
size += _bufPos;
}
if (_tempFileCreated)
{
NIO::CInFile inFile;
if (!inFile.Open(_tempFile.GetPath()))
return E_FAIL;
while (size < _size)
{
UInt32 processed;
if (!inFile.ReadPart(_buf, kTempBufSize, processed))
return E_FAIL;
if (processed == 0)
break;
RINOK(WriteStream(stream, _buf, processed));
crc = CrcUpdate(crc, _buf, processed);
size += processed;
}
}
return (_crc == crc && size == _size) ? S_OK : E_FAIL;
}
/*
STDMETHODIMP CSequentialOutTempBufferImp::Write(const void *data, UInt32 size, UInt32 *processed)
{
if (!_buf->Write(data, size))
{
if (processed)
*processed = 0;
return E_FAIL;
}
if (processed)
*processed = size;
return S_OK;
}
*/
|