Mercurial > vba-linux
comparison src/win32/7zip/7z/CPP/7zip/Common/OutMemStream.cpp @ 1:f9f4f1b99eed
importing src directory
author | Robert McIntyre <rlm@mit.edu> |
---|---|
date | Sat, 03 Mar 2012 10:31:27 -0600 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
0:8ced16adf2e1 | 1:f9f4f1b99eed |
---|---|
1 // OutMemStream.cpp | |
2 | |
3 #include "StdAfx.h" | |
4 | |
5 #include "OutMemStream.h" | |
6 | |
7 void COutMemStream::Free() | |
8 { | |
9 Blocks.Free(_memManager); | |
10 Blocks.LockMode = true; | |
11 } | |
12 | |
13 void COutMemStream::Init() | |
14 { | |
15 WriteToRealStreamEvent.Reset(); | |
16 _unlockEventWasSent = false; | |
17 _realStreamMode = false; | |
18 Free(); | |
19 _curBlockPos = 0; | |
20 _curBlockIndex = 0; | |
21 } | |
22 | |
23 void COutMemStream::DetachData(CMemLockBlocks &blocks) | |
24 { | |
25 Blocks.Detach(blocks, _memManager); | |
26 Free(); | |
27 } | |
28 | |
29 | |
30 HRESULT COutMemStream::WriteToRealStream() | |
31 { | |
32 RINOK(Blocks.WriteToStream(_memManager->GetBlockSize(), OutSeqStream)); | |
33 Blocks.Free(_memManager); | |
34 return S_OK; | |
35 } | |
36 | |
37 STDMETHODIMP COutMemStream::Write(const void *data, UInt32 size, UInt32 *processedSize) | |
38 { | |
39 if (_realStreamMode) | |
40 return OutSeqStream->Write(data, size, processedSize); | |
41 if (processedSize != 0) | |
42 *processedSize = 0; | |
43 while(size != 0) | |
44 { | |
45 if ((int)_curBlockIndex < Blocks.Blocks.Size()) | |
46 { | |
47 Byte *p = (Byte *)Blocks.Blocks[(int)_curBlockIndex] + _curBlockPos; | |
48 size_t curSize = _memManager->GetBlockSize() - _curBlockPos; | |
49 if (size < curSize) | |
50 curSize = size; | |
51 memmove(p, data, curSize); | |
52 if (processedSize != 0) | |
53 *processedSize += (UInt32)curSize; | |
54 data = (const void *)((const Byte *)data + curSize); | |
55 size -= (UInt32)curSize; | |
56 _curBlockPos += curSize; | |
57 | |
58 UInt64 pos64 = GetPos(); | |
59 if (pos64 > Blocks.TotalSize) | |
60 Blocks.TotalSize = pos64; | |
61 if (_curBlockPos == _memManager->GetBlockSize()) | |
62 { | |
63 _curBlockIndex++; | |
64 _curBlockPos = 0; | |
65 } | |
66 continue; | |
67 } | |
68 HANDLE events[3] = { StopWritingEvent, WriteToRealStreamEvent, /* NoLockEvent, */ _memManager->Semaphore }; | |
69 DWORD waitResult = ::WaitForMultipleObjects((Blocks.LockMode ? 3 : 2), events, FALSE, INFINITE); | |
70 switch (waitResult) | |
71 { | |
72 case (WAIT_OBJECT_0 + 0): | |
73 return StopWriteResult; | |
74 case (WAIT_OBJECT_0 + 1): | |
75 { | |
76 _realStreamMode = true; | |
77 RINOK(WriteToRealStream()); | |
78 UInt32 processedSize2; | |
79 HRESULT res = OutSeqStream->Write(data, size, &processedSize2); | |
80 if (processedSize != 0) | |
81 *processedSize += processedSize2; | |
82 return res; | |
83 } | |
84 /* | |
85 case (WAIT_OBJECT_0 + 2): | |
86 { | |
87 // it has bug: no write. | |
88 if (!Blocks.SwitchToNoLockMode(_memManager)) | |
89 return E_FAIL; | |
90 break; | |
91 } | |
92 */ | |
93 case (WAIT_OBJECT_0 + 2): | |
94 break; | |
95 default: | |
96 return E_FAIL; | |
97 } | |
98 Blocks.Blocks.Add(_memManager->AllocateBlock()); | |
99 if (Blocks.Blocks.Back() == 0) | |
100 return E_FAIL; | |
101 } | |
102 return S_OK; | |
103 } | |
104 | |
105 STDMETHODIMP COutMemStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition) | |
106 { | |
107 if (_realStreamMode) | |
108 { | |
109 if (!OutStream) | |
110 return E_FAIL; | |
111 return OutStream->Seek(offset, seekOrigin, newPosition); | |
112 } | |
113 if (seekOrigin == STREAM_SEEK_CUR) | |
114 { | |
115 if (offset != 0) | |
116 return E_NOTIMPL; | |
117 } | |
118 else if (seekOrigin == STREAM_SEEK_SET) | |
119 { | |
120 if (offset != 0) | |
121 return E_NOTIMPL; | |
122 _curBlockIndex = 0; | |
123 _curBlockPos = 0; | |
124 } | |
125 else | |
126 return E_NOTIMPL; | |
127 if (newPosition != 0) | |
128 *newPosition = GetPos(); | |
129 return S_OK; | |
130 } | |
131 | |
132 STDMETHODIMP COutMemStream::SetSize(Int64 newSize) | |
133 { | |
134 if (_realStreamMode) | |
135 { | |
136 if (!OutStream) | |
137 return E_FAIL; | |
138 return OutStream->SetSize(newSize); | |
139 } | |
140 Blocks.TotalSize = newSize; | |
141 return S_OK; | |
142 } |