1*f6dc9357SAndroid Build Coastguard Worker // OutMemStream.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker // #include <stdio.h>
6*f6dc9357SAndroid Build Coastguard Worker
7*f6dc9357SAndroid Build Coastguard Worker #include "OutMemStream.h"
8*f6dc9357SAndroid Build Coastguard Worker
Free()9*f6dc9357SAndroid Build Coastguard Worker void COutMemStream::Free()
10*f6dc9357SAndroid Build Coastguard Worker {
11*f6dc9357SAndroid Build Coastguard Worker Blocks.Free(_memManager);
12*f6dc9357SAndroid Build Coastguard Worker Blocks.LockMode = true;
13*f6dc9357SAndroid Build Coastguard Worker }
14*f6dc9357SAndroid Build Coastguard Worker
Init()15*f6dc9357SAndroid Build Coastguard Worker void COutMemStream::Init()
16*f6dc9357SAndroid Build Coastguard Worker {
17*f6dc9357SAndroid Build Coastguard Worker WriteToRealStreamEvent.Reset();
18*f6dc9357SAndroid Build Coastguard Worker _unlockEventWasSent = false;
19*f6dc9357SAndroid Build Coastguard Worker _realStreamMode = false;
20*f6dc9357SAndroid Build Coastguard Worker Free();
21*f6dc9357SAndroid Build Coastguard Worker _curBlockPos = 0;
22*f6dc9357SAndroid Build Coastguard Worker _curBlockIndex = 0;
23*f6dc9357SAndroid Build Coastguard Worker }
24*f6dc9357SAndroid Build Coastguard Worker
DetachData(CMemLockBlocks & blocks)25*f6dc9357SAndroid Build Coastguard Worker void COutMemStream::DetachData(CMemLockBlocks &blocks)
26*f6dc9357SAndroid Build Coastguard Worker {
27*f6dc9357SAndroid Build Coastguard Worker Blocks.Detach(blocks, _memManager);
28*f6dc9357SAndroid Build Coastguard Worker Free();
29*f6dc9357SAndroid Build Coastguard Worker }
30*f6dc9357SAndroid Build Coastguard Worker
31*f6dc9357SAndroid Build Coastguard Worker
WriteToRealStream()32*f6dc9357SAndroid Build Coastguard Worker HRESULT COutMemStream::WriteToRealStream()
33*f6dc9357SAndroid Build Coastguard Worker {
34*f6dc9357SAndroid Build Coastguard Worker RINOK(Blocks.WriteToStream(_memManager->GetBlockSize(), OutSeqStream))
35*f6dc9357SAndroid Build Coastguard Worker Blocks.Free(_memManager);
36*f6dc9357SAndroid Build Coastguard Worker return S_OK;
37*f6dc9357SAndroid Build Coastguard Worker }
38*f6dc9357SAndroid Build Coastguard Worker
39*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(COutMemStream::Write (const void * data,UInt32 size,UInt32 * processedSize))40*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(COutMemStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
41*f6dc9357SAndroid Build Coastguard Worker {
42*f6dc9357SAndroid Build Coastguard Worker if (_realStreamMode)
43*f6dc9357SAndroid Build Coastguard Worker return OutSeqStream->Write(data, size, processedSize);
44*f6dc9357SAndroid Build Coastguard Worker if (processedSize)
45*f6dc9357SAndroid Build Coastguard Worker *processedSize = 0;
46*f6dc9357SAndroid Build Coastguard Worker while (size != 0)
47*f6dc9357SAndroid Build Coastguard Worker {
48*f6dc9357SAndroid Build Coastguard Worker if (_curBlockIndex < Blocks.Blocks.Size())
49*f6dc9357SAndroid Build Coastguard Worker {
50*f6dc9357SAndroid Build Coastguard Worker Byte *p = (Byte *)Blocks.Blocks[_curBlockIndex] + _curBlockPos;
51*f6dc9357SAndroid Build Coastguard Worker size_t curSize = _memManager->GetBlockSize() - _curBlockPos;
52*f6dc9357SAndroid Build Coastguard Worker if (size < curSize)
53*f6dc9357SAndroid Build Coastguard Worker curSize = size;
54*f6dc9357SAndroid Build Coastguard Worker memcpy(p, data, curSize);
55*f6dc9357SAndroid Build Coastguard Worker if (processedSize)
56*f6dc9357SAndroid Build Coastguard Worker *processedSize += (UInt32)curSize;
57*f6dc9357SAndroid Build Coastguard Worker data = (const void *)((const Byte *)data + curSize);
58*f6dc9357SAndroid Build Coastguard Worker size -= (UInt32)curSize;
59*f6dc9357SAndroid Build Coastguard Worker _curBlockPos += curSize;
60*f6dc9357SAndroid Build Coastguard Worker
61*f6dc9357SAndroid Build Coastguard Worker const UInt64 pos64 = GetPos();
62*f6dc9357SAndroid Build Coastguard Worker if (pos64 > Blocks.TotalSize)
63*f6dc9357SAndroid Build Coastguard Worker Blocks.TotalSize = pos64;
64*f6dc9357SAndroid Build Coastguard Worker if (_curBlockPos == _memManager->GetBlockSize())
65*f6dc9357SAndroid Build Coastguard Worker {
66*f6dc9357SAndroid Build Coastguard Worker _curBlockIndex++;
67*f6dc9357SAndroid Build Coastguard Worker _curBlockPos = 0;
68*f6dc9357SAndroid Build Coastguard Worker }
69*f6dc9357SAndroid Build Coastguard Worker continue;
70*f6dc9357SAndroid Build Coastguard Worker }
71*f6dc9357SAndroid Build Coastguard Worker
72*f6dc9357SAndroid Build Coastguard Worker const NWindows::NSynchronization::CHandle_WFMO events[3] =
73*f6dc9357SAndroid Build Coastguard Worker { StopWritingEvent, WriteToRealStreamEvent, /* NoLockEvent, */ _memManager->Semaphore };
74*f6dc9357SAndroid Build Coastguard Worker const DWORD waitResult = NWindows::NSynchronization::WaitForMultiObj_Any_Infinite(
75*f6dc9357SAndroid Build Coastguard Worker ((Blocks.LockMode /* && _memManager->Semaphore.IsCreated() */) ? 3 : 2), events);
76*f6dc9357SAndroid Build Coastguard Worker
77*f6dc9357SAndroid Build Coastguard Worker // printf("\n 1- outMemStream %d\n", waitResult - WAIT_OBJECT_0);
78*f6dc9357SAndroid Build Coastguard Worker
79*f6dc9357SAndroid Build Coastguard Worker switch (waitResult)
80*f6dc9357SAndroid Build Coastguard Worker {
81*f6dc9357SAndroid Build Coastguard Worker case (WAIT_OBJECT_0 + 0):
82*f6dc9357SAndroid Build Coastguard Worker return StopWriteResult;
83*f6dc9357SAndroid Build Coastguard Worker case (WAIT_OBJECT_0 + 1):
84*f6dc9357SAndroid Build Coastguard Worker {
85*f6dc9357SAndroid Build Coastguard Worker _realStreamMode = true;
86*f6dc9357SAndroid Build Coastguard Worker RINOK(WriteToRealStream())
87*f6dc9357SAndroid Build Coastguard Worker UInt32 processedSize2;
88*f6dc9357SAndroid Build Coastguard Worker const HRESULT res = OutSeqStream->Write(data, size, &processedSize2);
89*f6dc9357SAndroid Build Coastguard Worker if (processedSize)
90*f6dc9357SAndroid Build Coastguard Worker *processedSize += processedSize2;
91*f6dc9357SAndroid Build Coastguard Worker return res;
92*f6dc9357SAndroid Build Coastguard Worker }
93*f6dc9357SAndroid Build Coastguard Worker case (WAIT_OBJECT_0 + 2):
94*f6dc9357SAndroid Build Coastguard Worker {
95*f6dc9357SAndroid Build Coastguard Worker // it has bug: no write.
96*f6dc9357SAndroid Build Coastguard Worker /*
97*f6dc9357SAndroid Build Coastguard Worker if (!Blocks.SwitchToNoLockMode(_memManager))
98*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
99*f6dc9357SAndroid Build Coastguard Worker */
100*f6dc9357SAndroid Build Coastguard Worker break;
101*f6dc9357SAndroid Build Coastguard Worker }
102*f6dc9357SAndroid Build Coastguard Worker default:
103*f6dc9357SAndroid Build Coastguard Worker {
104*f6dc9357SAndroid Build Coastguard Worker if (waitResult == WAIT_FAILED)
105*f6dc9357SAndroid Build Coastguard Worker {
106*f6dc9357SAndroid Build Coastguard Worker const DWORD res = ::GetLastError();
107*f6dc9357SAndroid Build Coastguard Worker if (res != 0)
108*f6dc9357SAndroid Build Coastguard Worker return HRESULT_FROM_WIN32(res);
109*f6dc9357SAndroid Build Coastguard Worker }
110*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
111*f6dc9357SAndroid Build Coastguard Worker }
112*f6dc9357SAndroid Build Coastguard Worker }
113*f6dc9357SAndroid Build Coastguard Worker void *p = _memManager->AllocateBlock();
114*f6dc9357SAndroid Build Coastguard Worker if (!p)
115*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
116*f6dc9357SAndroid Build Coastguard Worker Blocks.Blocks.Add(p);
117*f6dc9357SAndroid Build Coastguard Worker }
118*f6dc9357SAndroid Build Coastguard Worker return S_OK;
119*f6dc9357SAndroid Build Coastguard Worker }
120*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(COutMemStream::Seek (Int64 offset,UInt32 seekOrigin,UInt64 * newPosition))121*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(COutMemStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition))
122*f6dc9357SAndroid Build Coastguard Worker {
123*f6dc9357SAndroid Build Coastguard Worker if (_realStreamMode)
124*f6dc9357SAndroid Build Coastguard Worker {
125*f6dc9357SAndroid Build Coastguard Worker if (!OutStream)
126*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
127*f6dc9357SAndroid Build Coastguard Worker return OutStream->Seek(offset, seekOrigin, newPosition);
128*f6dc9357SAndroid Build Coastguard Worker }
129*f6dc9357SAndroid Build Coastguard Worker if (seekOrigin == STREAM_SEEK_CUR)
130*f6dc9357SAndroid Build Coastguard Worker {
131*f6dc9357SAndroid Build Coastguard Worker if (offset != 0)
132*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
133*f6dc9357SAndroid Build Coastguard Worker }
134*f6dc9357SAndroid Build Coastguard Worker else if (seekOrigin == STREAM_SEEK_SET)
135*f6dc9357SAndroid Build Coastguard Worker {
136*f6dc9357SAndroid Build Coastguard Worker if (offset != 0)
137*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
138*f6dc9357SAndroid Build Coastguard Worker _curBlockIndex = 0;
139*f6dc9357SAndroid Build Coastguard Worker _curBlockPos = 0;
140*f6dc9357SAndroid Build Coastguard Worker }
141*f6dc9357SAndroid Build Coastguard Worker else
142*f6dc9357SAndroid Build Coastguard Worker return E_NOTIMPL;
143*f6dc9357SAndroid Build Coastguard Worker if (newPosition)
144*f6dc9357SAndroid Build Coastguard Worker *newPosition = GetPos();
145*f6dc9357SAndroid Build Coastguard Worker return S_OK;
146*f6dc9357SAndroid Build Coastguard Worker }
147*f6dc9357SAndroid Build Coastguard Worker
Z7_COM7F_IMF(COutMemStream::SetSize (UInt64 newSize))148*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(COutMemStream::SetSize(UInt64 newSize))
149*f6dc9357SAndroid Build Coastguard Worker {
150*f6dc9357SAndroid Build Coastguard Worker if (_realStreamMode)
151*f6dc9357SAndroid Build Coastguard Worker {
152*f6dc9357SAndroid Build Coastguard Worker if (!OutStream)
153*f6dc9357SAndroid Build Coastguard Worker return E_FAIL;
154*f6dc9357SAndroid Build Coastguard Worker return OutStream->SetSize(newSize);
155*f6dc9357SAndroid Build Coastguard Worker }
156*f6dc9357SAndroid Build Coastguard Worker Blocks.TotalSize = newSize;
157*f6dc9357SAndroid Build Coastguard Worker return S_OK;
158*f6dc9357SAndroid Build Coastguard Worker }
159