lzma 压缩封装

程序生成的minidump要debug的话还是比较大的,客户端的需要压缩一下再上传到服务端,不过相对于zlib的话lzma的压缩比更好,所以我选择用lzma.

http://www.7-zip.org/sdk.html

7-zip的多文件打包接口在CPP封装内:ListArchives(加密),DecompressArchives(解密)

轻量级的单文件加解密还是自己封装下简单:

 1 #pragma once
 2 
 3 #include <vector>
 4 #include <xstring>
 5 
 6 class SLzma
 7 {
 8 public:
 9     SLzma(void);
10     ~SLzma(void);
11 
12     static int CompressFile(const std::wstring& outfile, const std::wstring& infile, bool is_lzma = true);
13     
14     static int UncompressFile(const std::wstring& outfile, const std::wstring& infile, bool is_lzma = true);
15 
16     static int CompressInc1(std::vector<unsigned char> &outBuf,    const std::vector<unsigned char> &inBuf);
17 
18     static int Uncompress1(std::vector<unsigned char> &outBuf, const std::vector<unsigned char> &inBuf);
19 
20     static int CompressInc2(std::vector<unsigned char> &outBuf,    const std::vector<unsigned char> &inBuf);
21 
22     static int Uncompress2(std::vector<unsigned char> &outBuf, const std::vector<unsigned char> &inBuf);
23 
24     static unsigned long CompressBuffer(unsigned char *inBuffer, unsigned long inSize,
25         unsigned char *outBuffer, unsigned long outSize, size_t *outSizeProcessed);
26 
27     static unsigned long UncompressBuffer(unsigned char *inBuffer, unsigned long inSize,
28         unsigned char *outBuffer, unsigned long outSize, size_t *outSizeProcessed);
29 };
SLzma.h
  1 #include "stdafx.h"
  2 #include "SLzma.h"
  3 
  4 #include <LzmaLib.h>
  5 #include <Lzma86.h>
  6 #include <LzmaEnc.h>
  7 #include <alloc.h>
  8 #include <LzmaDec.h>
  9 #include <boost/filesystem.hpp>
 10 #include <iostream>
 11 
 12 using namespace std;
 13 using namespace boost;
 14 
 15 SLzma::SLzma(void)
 16 {
 17 }
 18 
 19 
 20 SLzma::~SLzma(void)
 21 {
 22 }
 23 
 24 static void * AllocForLzma(void *p, size_t size) { return MyAlloc(size); }
 25 static void FreeForLzma(void *p, void *address) { MyFree(address); }
 26 static ISzAlloc SzAllocForLzma = { &AllocForLzma, &FreeForLzma };
 27 const int FILE_LEN_BUF_SIZE = 8;
 28 
 29 typedef struct
 30 {
 31     ISeqInStream SeqInStream;
 32     const std::vector<unsigned char> *Buf;
 33     unsigned BufPos;
 34 } VectorInStream;
 35 
 36 SRes VectorInStream_Read(void *p, void *buf, size_t *size)
 37 {
 38     VectorInStream *ctx = (VectorInStream*)p;
 39     *size = min(*size, ctx->Buf->size() - ctx->BufPos);
 40     if (*size)
 41         memcpy(buf, &(*ctx->Buf)[ctx->BufPos], *size);
 42     ctx->BufPos += *size;
 43     return SZ_OK;
 44 }
 45 
 46 typedef struct
 47 {
 48     ISeqOutStream SeqOutStream;
 49     std::vector<unsigned char> *Buf;
 50 } VectorOutStream;
 51 
 52 size_t VectorOutStream_Write(void *p, const void *buf, size_t size)
 53 {
 54     VectorOutStream *ctx = (VectorOutStream*)p;
 55     if (size)
 56     {
 57         unsigned oldSize = ctx->Buf->size();
 58         ctx->Buf->resize(oldSize + size);
 59         memcpy(&(*ctx->Buf)[oldSize], buf, size);
 60     }
 61     return size;
 62 }
 63 
 64 //
 65 //
 66 
 67 int SLzma::CompressInc1(
 68     std::vector<unsigned char> &outBuf,
 69     const std::vector<unsigned char> &inBuf)
 70 {
 71     unsigned propsSize = LZMA_PROPS_SIZE;
 72     unsigned destLen = inBuf.size() + inBuf.size() / 3 + 128;
 73     outBuf.resize(propsSize + FILE_LEN_BUF_SIZE + destLen);
 74 
 75     UInt64 filelen = inBuf.size();
 76     for (int i = 0; i < FILE_LEN_BUF_SIZE; i++)
 77     {
 78         Byte b = Byte(filelen >> (FILE_LEN_BUF_SIZE * i));
 79         outBuf[LZMA_PROPS_SIZE+i] = b;
 80     }
 81 
 82     int res = LzmaCompress(
 83         &outBuf[LZMA_PROPS_SIZE+FILE_LEN_BUF_SIZE], &destLen,
 84         &inBuf[0], inBuf.size(),
 85         &outBuf[0], &propsSize,
 86         5,      /* 0 <= level <= 9, default = 5 */
 87         (1 << 24),  /* default = (1 << 24) */
 88         3,        /* 0 <= lc <= 8, default = 3  */
 89         0,        /* 0 <= lp <= 4, default = 0  */
 90         2,        /* 0 <= pb <= 4, default = 2  */
 91         32,        /* 5 <= fb <= 273, default = 32 */
 92         2 /* 1 or 2, default = 2 */
 93         );
 94 
 95     if(res == SZ_OK)
 96         outBuf.resize(propsSize + 8 + destLen);
 97 
 98     return res;
 99 }
100 
101 int SLzma::Uncompress1(
102     std::vector<unsigned char> &outBuf,
103     const std::vector<unsigned char> &inBuf)
104 {
105     UInt64 fileSize = 0;
106     for (int i = 0; i < FILE_LEN_BUF_SIZE; i++)
107     {
108         unsigned char b = inBuf[LZMA_PROPS_SIZE + i];
109         fileSize += (b) << (i * FILE_LEN_BUF_SIZE);
110     }
111 
112     outBuf.resize(fileSize);
113     unsigned dstLen = outBuf.size();
114     unsigned srcLen = inBuf.size() - LZMA_PROPS_SIZE - FILE_LEN_BUF_SIZE;
115     SRes res = LzmaUncompress(
116         &outBuf[0], &dstLen,
117         &inBuf[LZMA_PROPS_SIZE+FILE_LEN_BUF_SIZE], &srcLen,
118         &inBuf[0], LZMA_PROPS_SIZE);
119     if(res == SZ_OK);
120     outBuf.resize(dstLen); // If uncompressed data can be smaller
121     return res;
122 }
123 
124 //
125 //
126 int SLzma::CompressInc2(
127     std::vector<unsigned char> &outBuf,
128     const std::vector<unsigned char> &inBuf)
129 {
130     CLzmaEncHandle enc = LzmaEnc_Create(&SzAllocForLzma);
131     if(!enc) return -1;
132 
133     CLzmaEncProps props;
134     LzmaEncProps_Init(&props);
135     props.writeEndMark = 1; // 0 or 1
136 
137     SRes res = LzmaEnc_SetProps(enc, &props);
138     if(res != SZ_OK) return res;
139 
140     unsigned propsSize = LZMA_PROPS_SIZE+8;
141     outBuf.resize(propsSize);
142 
143     res = LzmaEnc_WriteProperties(enc, &outBuf[0], &propsSize);
144     if(res != SZ_OK || propsSize != LZMA_PROPS_SIZE) return -1;
145 
146     UInt64 filelen = inBuf.size();
147     for (int i = 0; i < FILE_LEN_BUF_SIZE; i++)
148     {
149         Byte b = Byte(filelen >> (FILE_LEN_BUF_SIZE * i));
150         outBuf[LZMA_PROPS_SIZE+i] = b;
151     }
152 
153     VectorInStream inStream = { &VectorInStream_Read, &inBuf, 0 };
154     VectorOutStream outStream = { &VectorOutStream_Write, &outBuf };
155 
156     res = LzmaEnc_Encode(enc,
157         (ISeqOutStream*)&outStream, (ISeqInStream*)&inStream,
158         0, &SzAllocForLzma, &SzAllocForLzma);
159 
160     LzmaEnc_Destroy(enc, &SzAllocForLzma, &SzAllocForLzma);
161 
162     return res;
163 }
164 
165 int SLzma::Uncompress2(
166     std::vector<unsigned char> &outBuf,
167     const std::vector<unsigned char> &inBuf)
168 {
169     CLzmaDec dec;  
170     LzmaDec_Construct(&dec);
171 
172     SRes res = LzmaDec_Allocate(&dec, &inBuf[0], LZMA_PROPS_SIZE, &SzAllocForLzma);
173     if(res != SZ_OK)
174         return res;
175 
176     LzmaDec_Init(&dec);
177 
178     UInt64 fileSize = 0;
179     for (int i = 0; i < FILE_LEN_BUF_SIZE; i++)
180     {
181         unsigned char b = inBuf[LZMA_PROPS_SIZE + i];
182         fileSize += (b) << (i * FILE_LEN_BUF_SIZE);
183     }
184 
185     outBuf.resize(fileSize);
186     unsigned outPos = 0, inPos = LZMA_PROPS_SIZE+FILE_LEN_BUF_SIZE;
187     ELzmaStatus status;
188     const unsigned BUF_SIZE = 10240;
189     while (outPos < outBuf.size())
190     {
191         unsigned destLen = min(BUF_SIZE, outBuf.size() - outPos);
192         unsigned srcLen  = min(BUF_SIZE, inBuf.size() - inPos);
193         unsigned srcLenOld = srcLen, destLenOld = destLen;
194         res = LzmaDec_DecodeToBuf(&dec,
195             &outBuf[outPos], &destLen,
196             &inBuf[inPos], &srcLen,
197             (outPos + destLen == outBuf.size())
198             ? LZMA_FINISH_END : LZMA_FINISH_ANY, &status);
199         if(res != SZ_OK)
200             break;
201         inPos += srcLen;
202         outPos += destLen;
203         if (status == LZMA_STATUS_FINISHED_WITH_MARK)
204             break;
205     }
206 
207     LzmaDec_Free(&dec, &SzAllocForLzma);
208     outBuf.resize(outPos);
209 
210     return res;
211 }
212 
213 //
214 //
215 unsigned long SLzma::CompressBuffer(unsigned char *inBuffer, unsigned long inSize,
216                                     unsigned char *outBuffer, unsigned long outSize, size_t *outSizeProcessed)
217 {
218     bool dictDefined = false;
219     UInt32 dict = (UInt32)-1;
220 
221     if ((inSize == 0) || (inBuffer == 0)) return 1;
222     if (/*(outSize == 0) || */(outBuffer == 0)) return 1;
223 
224     Byte *outBuffer2 = 0;
225     size_t outSize2;
226 
227     // we allocate 105% of original size for output buffer
228     outSize2 = (size_t)inSize / 20 * 21 + (1 << 16); //fileSize / 20 * 21 + (1 << 16)
229     if (outSize2 != 0)
230     {
231         outBuffer2 = (Byte *)MyAlloc((size_t)outSize2);
232         if (outBuffer2 == 0) return 1;//throw "Can not allocate memory";
233     }
234 
235     if (!dictDefined) dict = 1 << 23;
236 
237     *outSizeProcessed = outSize2; // !!
238     int res = Lzma86_Encode(outBuffer2, outSizeProcessed, inBuffer, inSize,
239         5, dict, SZ_FILTER_AUTO);
240     if (res != 0)
241     {
242         // Encoder error = (int)res
243         return 1;
244     }
245 
246     memcpy(outBuffer, outBuffer2, *outSizeProcessed);
247 
248     MyFree(outBuffer2);
249 
250     return *outSizeProcessed == 0 ?1:0;
251 }
252 
253 unsigned long SLzma::UncompressBuffer(unsigned char *inBuffer, unsigned long inSize,
254                                       unsigned char *outBuffer, unsigned long outSize, size_t *outSizeProcessed)
255 {
256     if ((inSize == 0) || (inBuffer == 0)) return 1;
257     if (/*(outSize == 0) || */(outBuffer == 0)) return 1;
258 
259     Byte *outBuffer2 = 0;
260     size_t outSize2;
261 
262     UInt64 outSize64;
263     if (Lzma86_GetUnpackSize(inBuffer, inSize, &outSize64) != 0)
264         return 1;//throw "data error";
265     outSize2 = (size_t)outSize64;
266     if (outSize2 != outSize64)
267         return 1;//throw "too big";
268     if (outSize2 != 0)
269     {
270         outBuffer2 = (Byte *)MyAlloc(outSize2);
271         if (outBuffer2 == 0)
272             return 1;//throw "Can not allocate memory";
273     }
274 
275     size_t inSize2 = inSize;
276     *outSizeProcessed = outSize2;
277     int res = Lzma86_Decode(outBuffer2, outSizeProcessed, inBuffer, &inSize2);
278     if (inSize2 != (size_t)inSize)
279         return 1;//throw "incorrect processed size";
280     if (res != 0)
281         return 1;//throw "LzmaDecoder error";
282 
283     memcpy(outBuffer, outBuffer2, *outSizeProcessed);
284 
285     MyFree(outBuffer2);
286 
287     return *outSizeProcessed == 0 ?1:0;
288 }
289 
290 //
291 //
292 int SLzma::CompressFile(const std::wstring& outfile, const std::wstring& infile, bool is_lzma)
293 {
294 
295     filesystem::path pt(infile);        
296     size_t srclen = filesystem::file_size(pt);
297 
298     ifstream inputStream(infile.c_str(),ios::ios_base::binary |ios::ios_base::in);
299 
300     vector<UCHAR> intbuf;        
301     if(inputStream.fail() || srclen <= 0)
302     {
303         inputStream.clear();
304         inputStream.close();
305         return -1;
306     }
307     else
308     {
309         intbuf.resize(srclen);
310         int readBytes = 0;
311 
312         while(!inputStream.eof() && readBytes < srclen)
313         {
314             inputStream.read((char*)&intbuf[readBytes],srclen - readBytes);
315             if (inputStream.fail())
316             {
317                 break;
318             }
319             readBytes += inputStream.gcount();
320         }            
321 
322         inputStream.clear();
323         inputStream.close();
324     }
325 
326     vector<UCHAR> outbuf;
327     int result = 0;
328     if(is_lzma)
329         result = SLzma::CompressInc1(outbuf, intbuf);
330     else
331         result = SLzma::CompressInc2(outbuf, intbuf);
332     if (0 == result)
333     {
334         ofstream outfile(outfile.c_str(), ios::ios_base::binary |ios::ios_base::out);
335         if(!outfile.fail())
336         {                
337             outfile.write((const char*)outbuf.data(), outbuf.size());            
338             outfile.flush();
339             outfile.clear();
340             outfile.close();
341         }
342     }
343     return result;
344 }
345 
346 
347 int SLzma::UncompressFile(const std::wstring& outfile, const std::wstring& infile, bool is_lzma)
348 {
349 
350     filesystem::path pt(infile);        
351     size_t srclen = filesystem::file_size(pt);
352 
353     ifstream inputStream(infile.c_str(),ios::ios_base::binary |ios::ios_base::in);
354 
355     vector<UCHAR> intbuf;        
356     if(inputStream.fail() || srclen <= 0)
357     {
358         inputStream.clear();
359         inputStream.close();
360         return -1;
361     }
362     else
363     {
364         intbuf.resize(srclen);
365         int readBytes = 0;
366 
367         while(!inputStream.eof() && readBytes < srclen)
368         {
369             inputStream.read((char*)&intbuf[readBytes],srclen - readBytes);
370             if (inputStream.fail())
371             {
372                 break;
373             }
374             readBytes += inputStream.gcount();
375         }            
376 
377         inputStream.clear();
378         inputStream.close();
379     }
380 
381     vector<UCHAR> outbuf;
382     int result = 0;
383     if(is_lzma)
384         result = SLzma::Uncompress1(outbuf, intbuf);
385     else
386         result = SLzma::Uncompress2(outbuf, intbuf);
387     if (0 == result)
388     {
389         ofstream outfile(outfile.c_str(), ios::ios_base::binary |ios::ios_base::out);
390         if(!outfile.fail())
391         {                
392             outfile.write((const char*)outbuf.data(), outbuf.size());            
393             outfile.flush();
394             outfile.clear();
395             outfile.close();
396         }
397     }
398     return result;
399 }
SLzma.cpp

 

转载于:https://www.cnblogs.com/zhangchengxin/p/3649644.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值