xref: /aosp_15_r20/external/lzma/CPP/7zip/Common/OutMemStream.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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