xref: /aosp_15_r20/external/lzma/CPP/7zip/Compress/CopyCoder.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // Compress/CopyCoder.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 "../../../C/Alloc.h"
6*f6dc9357SAndroid Build Coastguard Worker 
7*f6dc9357SAndroid Build Coastguard Worker #include "CopyCoder.h"
8*f6dc9357SAndroid Build Coastguard Worker 
9*f6dc9357SAndroid Build Coastguard Worker namespace NCompress {
10*f6dc9357SAndroid Build Coastguard Worker 
11*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kBufSize = 1 << 17;
12*f6dc9357SAndroid Build Coastguard Worker 
~CCopyCoder()13*f6dc9357SAndroid Build Coastguard Worker CCopyCoder::~CCopyCoder()
14*f6dc9357SAndroid Build Coastguard Worker {
15*f6dc9357SAndroid Build Coastguard Worker   ::MidFree(_buf);
16*f6dc9357SAndroid Build Coastguard Worker }
17*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CCopyCoder::SetFinishMode (UInt32))18*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CCopyCoder::SetFinishMode(UInt32 /* finishMode */))
19*f6dc9357SAndroid Build Coastguard Worker {
20*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
21*f6dc9357SAndroid Build Coastguard Worker }
22*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CCopyCoder::Code (ISequentialInStream * inStream,ISequentialOutStream * outStream,const UInt64 *,const UInt64 * outSize,ICompressProgressInfo * progress))23*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CCopyCoder::Code(ISequentialInStream *inStream,
24*f6dc9357SAndroid Build Coastguard Worker     ISequentialOutStream *outStream,
25*f6dc9357SAndroid Build Coastguard Worker     const UInt64 * /* inSize */, const UInt64 *outSize,
26*f6dc9357SAndroid Build Coastguard Worker     ICompressProgressInfo *progress))
27*f6dc9357SAndroid Build Coastguard Worker {
28*f6dc9357SAndroid Build Coastguard Worker   if (!_buf)
29*f6dc9357SAndroid Build Coastguard Worker   {
30*f6dc9357SAndroid Build Coastguard Worker     _buf = (Byte *)::MidAlloc(kBufSize);
31*f6dc9357SAndroid Build Coastguard Worker     if (!_buf)
32*f6dc9357SAndroid Build Coastguard Worker       return E_OUTOFMEMORY;
33*f6dc9357SAndroid Build Coastguard Worker   }
34*f6dc9357SAndroid Build Coastguard Worker 
35*f6dc9357SAndroid Build Coastguard Worker   TotalSize = 0;
36*f6dc9357SAndroid Build Coastguard Worker 
37*f6dc9357SAndroid Build Coastguard Worker   for (;;)
38*f6dc9357SAndroid Build Coastguard Worker   {
39*f6dc9357SAndroid Build Coastguard Worker     UInt32 size = kBufSize;
40*f6dc9357SAndroid Build Coastguard Worker     if (outSize)
41*f6dc9357SAndroid Build Coastguard Worker     {
42*f6dc9357SAndroid Build Coastguard Worker       const UInt64 rem = *outSize - TotalSize;
43*f6dc9357SAndroid Build Coastguard Worker       if (size > rem)
44*f6dc9357SAndroid Build Coastguard Worker       {
45*f6dc9357SAndroid Build Coastguard Worker         size = (UInt32)rem;
46*f6dc9357SAndroid Build Coastguard Worker         if (size == 0)
47*f6dc9357SAndroid Build Coastguard Worker         {
48*f6dc9357SAndroid Build Coastguard Worker           /* if we enable the following check,
49*f6dc9357SAndroid Build Coastguard Worker              we will make one call of Read(_buf, 0) for empty stream */
50*f6dc9357SAndroid Build Coastguard Worker           // if (TotalSize != 0)
51*f6dc9357SAndroid Build Coastguard Worker           return S_OK;
52*f6dc9357SAndroid Build Coastguard Worker         }
53*f6dc9357SAndroid Build Coastguard Worker       }
54*f6dc9357SAndroid Build Coastguard Worker     }
55*f6dc9357SAndroid Build Coastguard Worker 
56*f6dc9357SAndroid Build Coastguard Worker     HRESULT readRes;
57*f6dc9357SAndroid Build Coastguard Worker     {
58*f6dc9357SAndroid Build Coastguard Worker       UInt32 pos = 0;
59*f6dc9357SAndroid Build Coastguard Worker       do
60*f6dc9357SAndroid Build Coastguard Worker       {
61*f6dc9357SAndroid Build Coastguard Worker         const UInt32 curSize = size - pos;
62*f6dc9357SAndroid Build Coastguard Worker         UInt32 processed = 0;
63*f6dc9357SAndroid Build Coastguard Worker         readRes = inStream->Read(_buf + pos, curSize, &processed);
64*f6dc9357SAndroid Build Coastguard Worker         if (processed > curSize)
65*f6dc9357SAndroid Build Coastguard Worker           return E_FAIL; // internal code failure
66*f6dc9357SAndroid Build Coastguard Worker         pos += processed;
67*f6dc9357SAndroid Build Coastguard Worker         if (readRes != S_OK || processed == 0)
68*f6dc9357SAndroid Build Coastguard Worker           break;
69*f6dc9357SAndroid Build Coastguard Worker       }
70*f6dc9357SAndroid Build Coastguard Worker       while (pos < kBufSize);
71*f6dc9357SAndroid Build Coastguard Worker       size = pos;
72*f6dc9357SAndroid Build Coastguard Worker     }
73*f6dc9357SAndroid Build Coastguard Worker 
74*f6dc9357SAndroid Build Coastguard Worker     if (size == 0)
75*f6dc9357SAndroid Build Coastguard Worker       return readRes;
76*f6dc9357SAndroid Build Coastguard Worker 
77*f6dc9357SAndroid Build Coastguard Worker     if (outStream)
78*f6dc9357SAndroid Build Coastguard Worker     {
79*f6dc9357SAndroid Build Coastguard Worker       UInt32 pos = 0;
80*f6dc9357SAndroid Build Coastguard Worker       do
81*f6dc9357SAndroid Build Coastguard Worker       {
82*f6dc9357SAndroid Build Coastguard Worker         const UInt32 curSize = size - pos;
83*f6dc9357SAndroid Build Coastguard Worker         UInt32 processed = 0;
84*f6dc9357SAndroid Build Coastguard Worker         const HRESULT res = outStream->Write(_buf + pos, curSize, &processed);
85*f6dc9357SAndroid Build Coastguard Worker         if (processed > curSize)
86*f6dc9357SAndroid Build Coastguard Worker           return E_FAIL; // internal code failure
87*f6dc9357SAndroid Build Coastguard Worker         pos += processed;
88*f6dc9357SAndroid Build Coastguard Worker         TotalSize += processed;
89*f6dc9357SAndroid Build Coastguard Worker         RINOK(res)
90*f6dc9357SAndroid Build Coastguard Worker         if (processed == 0)
91*f6dc9357SAndroid Build Coastguard Worker           return E_FAIL;
92*f6dc9357SAndroid Build Coastguard Worker       }
93*f6dc9357SAndroid Build Coastguard Worker       while (pos < size);
94*f6dc9357SAndroid Build Coastguard Worker     }
95*f6dc9357SAndroid Build Coastguard Worker     else
96*f6dc9357SAndroid Build Coastguard Worker       TotalSize += size;
97*f6dc9357SAndroid Build Coastguard Worker 
98*f6dc9357SAndroid Build Coastguard Worker     RINOK(readRes)
99*f6dc9357SAndroid Build Coastguard Worker 
100*f6dc9357SAndroid Build Coastguard Worker     if (size != kBufSize)
101*f6dc9357SAndroid Build Coastguard Worker       return S_OK;
102*f6dc9357SAndroid Build Coastguard Worker 
103*f6dc9357SAndroid Build Coastguard Worker     if (progress && (TotalSize & (((UInt32)1 << 22) - 1)) == 0)
104*f6dc9357SAndroid Build Coastguard Worker     {
105*f6dc9357SAndroid Build Coastguard Worker       RINOK(progress->SetRatioInfo(&TotalSize, &TotalSize))
106*f6dc9357SAndroid Build Coastguard Worker     }
107*f6dc9357SAndroid Build Coastguard Worker   }
108*f6dc9357SAndroid Build Coastguard Worker }
109*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CCopyCoder::SetInStream (ISequentialInStream * inStream))110*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CCopyCoder::SetInStream(ISequentialInStream *inStream))
111*f6dc9357SAndroid Build Coastguard Worker {
112*f6dc9357SAndroid Build Coastguard Worker   _inStream = inStream;
113*f6dc9357SAndroid Build Coastguard Worker   TotalSize = 0;
114*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
115*f6dc9357SAndroid Build Coastguard Worker }
116*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CCopyCoder::ReleaseInStream ())117*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CCopyCoder::ReleaseInStream())
118*f6dc9357SAndroid Build Coastguard Worker {
119*f6dc9357SAndroid Build Coastguard Worker   _inStream.Release();
120*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
121*f6dc9357SAndroid Build Coastguard Worker }
122*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CCopyCoder::Read (void * data,UInt32 size,UInt32 * processedSize))123*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CCopyCoder::Read(void *data, UInt32 size, UInt32 *processedSize))
124*f6dc9357SAndroid Build Coastguard Worker {
125*f6dc9357SAndroid Build Coastguard Worker   UInt32 realProcessedSize = 0;
126*f6dc9357SAndroid Build Coastguard Worker   HRESULT res = _inStream->Read(data, size, &realProcessedSize);
127*f6dc9357SAndroid Build Coastguard Worker   TotalSize += realProcessedSize;
128*f6dc9357SAndroid Build Coastguard Worker   if (processedSize)
129*f6dc9357SAndroid Build Coastguard Worker     *processedSize = realProcessedSize;
130*f6dc9357SAndroid Build Coastguard Worker   return res;
131*f6dc9357SAndroid Build Coastguard Worker }
132*f6dc9357SAndroid Build Coastguard Worker 
Z7_COM7F_IMF(CCopyCoder::GetInStreamProcessedSize (UInt64 * value))133*f6dc9357SAndroid Build Coastguard Worker Z7_COM7F_IMF(CCopyCoder::GetInStreamProcessedSize(UInt64 *value))
134*f6dc9357SAndroid Build Coastguard Worker {
135*f6dc9357SAndroid Build Coastguard Worker   *value = TotalSize;
136*f6dc9357SAndroid Build Coastguard Worker   return S_OK;
137*f6dc9357SAndroid Build Coastguard Worker }
138*f6dc9357SAndroid Build Coastguard Worker 
CopyStream(ISequentialInStream * inStream,ISequentialOutStream * outStream,ICompressProgressInfo * progress)139*f6dc9357SAndroid Build Coastguard Worker HRESULT CopyStream(ISequentialInStream *inStream, ISequentialOutStream *outStream, ICompressProgressInfo *progress)
140*f6dc9357SAndroid Build Coastguard Worker {
141*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ICompressCoder> copyCoder = new CCopyCoder;
142*f6dc9357SAndroid Build Coastguard Worker   return copyCoder->Code(inStream, outStream, NULL, NULL, progress);
143*f6dc9357SAndroid Build Coastguard Worker }
144*f6dc9357SAndroid Build Coastguard Worker 
CopyStream_ExactSize(ISequentialInStream * inStream,ISequentialOutStream * outStream,UInt64 size,ICompressProgressInfo * progress)145*f6dc9357SAndroid Build Coastguard Worker HRESULT CopyStream_ExactSize(ISequentialInStream *inStream, ISequentialOutStream *outStream, UInt64 size, ICompressProgressInfo *progress)
146*f6dc9357SAndroid Build Coastguard Worker {
147*f6dc9357SAndroid Build Coastguard Worker   NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
148*f6dc9357SAndroid Build Coastguard Worker   CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
149*f6dc9357SAndroid Build Coastguard Worker   RINOK(copyCoder->Code(inStream, outStream, NULL, &size, progress))
150*f6dc9357SAndroid Build Coastguard Worker   return copyCoderSpec->TotalSize == size ? S_OK : E_FAIL;
151*f6dc9357SAndroid Build Coastguard Worker }
152*f6dc9357SAndroid Build Coastguard Worker 
153*f6dc9357SAndroid Build Coastguard Worker }
154