decompress_plugin_demo.h 62 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333
  1. //decompress_plugin_demo.h
  2. // decompress plugin demo for HDiffz\HPatchz
  3. /*
  4. The MIT License (MIT)
  5. Copyright (c) 2012-2017 HouSisong
  6. Permission is hereby granted, free of charge, to any person
  7. obtaining a copy of this software and associated documentation
  8. files (the "Software"), to deal in the Software without
  9. restriction, including without limitation the rights to use,
  10. copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. copies of the Software, and to permit persons to whom the
  12. Software is furnished to do so, subject to the following
  13. conditions:
  14. The above copyright notice and this permission notice shall be
  15. included in all copies of the Software.
  16. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  17. EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
  18. OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  19. NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  20. HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
  21. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  22. FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  23. OTHER DEALINGS IN THE SOFTWARE.
  24. */
  25. #ifndef HPatch_decompress_plugin_demo_h
  26. #define HPatch_decompress_plugin_demo_h
  27. //decompress plugin demo:
  28. // zlibDecompressPlugin;
  29. // bz2DecompressPlugin;
  30. // lzmaDecompressPlugin;
  31. // lzma2DecompressPlugin;
  32. // lz4DecompressPlugin;
  33. // zstdDecompressPlugin;
  34. // brotliDecompressPlugin;
  35. // lzhamDecompressPlugin;
  36. // tuzDecompressPlugin;
  37. // _bz2DecompressPlugin_unsz : support for bspatch_with_cache()
  38. // _7zXZDecompressPlugin : support for vcpatch_with_cache(), diffData created by "xdelta3 -S lzma ..."
  39. // _7zXZDecompressPlugin_a : support for vcpatch_with_cache(), diffData created by "hdiffz -VCD-compressLevel ..."
  40. #include <stdlib.h> //malloc free
  41. #include <stdio.h> //fprintf
  42. #include "patch_types.h"
  43. #ifndef kDecompressBufSize
  44. # define kDecompressBufSize (1024*32)
  45. #endif
  46. #ifndef _IsNeedIncludeDefaultCompressHead
  47. # define _IsNeedIncludeDefaultCompressHead 1
  48. #endif
  49. #define _dec_memErr() _hpatch_update_decError(decompressPlugin,hpatch_dec_mem_error)
  50. #define _dec_memErr_rt() do { _dec_memErr(); return 0; } while(0)
  51. #define _dec_openErr_rt() do { _hpatch_update_decError(decompressPlugin,hpatch_dec_open_error); return 0; } while(0)
  52. #define _dec_close_check(value) { if (!(value)) { LOG_ERR("check "#value " ERROR!\n"); \
  53. result=hpatch_FALSE; _hpatch_update_decError(decompressPlugin,hpatch_dec_close_error); } }
  54. #define _dec_onDecErr_rt() do { if (!(self)->decError) (self)->decError=hpatch_dec_error; return 0; } while(0)
  55. #define _dec_onDecErr_up() do { if ((self)->decError) _hpatch_update_decError(decompressPlugin,(self)->decError); } while(0)
  56. static void* _dec_malloc(hpatch_size_t size) {
  57. void* result=malloc(size);
  58. if (!result) LOG_ERRNO(errno);
  59. return result;
  60. }
  61. #define __dec_Alloc_fun(_type_TDecompress,p,size) { \
  62. void* result=_dec_malloc(size); \
  63. if (!result) \
  64. ((_type_TDecompress*)p)->decError=hpatch_dec_mem_error; \
  65. return result; }
  66. static void __dec_free(void* _, void* address){
  67. if (address) free(address); }
  68. #ifdef _CompressPlugin_zlib
  69. #if (_IsNeedIncludeDefaultCompressHead)
  70. # include "zlib.h" // http://zlib.net/ https://github.com/madler/zlib
  71. #endif
  72. typedef struct _zlib_TDecompress{
  73. hpatch_StreamPos_t code_begin;
  74. hpatch_StreamPos_t code_end;
  75. const struct hpatch_TStreamInput* codeStream;
  76. unsigned char* dec_buf;
  77. size_t dec_buf_size;
  78. z_stream d_stream;
  79. signed char windowBits;
  80. hpatch_dec_error_t decError;
  81. } _zlib_TDecompress;
  82. static void * __zlib_dec_Alloc(void* p,uInt items,uInt size)
  83. __dec_Alloc_fun(_zlib_TDecompress,p,((items)*(size_t)(size)))
  84. static hpatch_BOOL _zlib_is_can_open(const char* compressType){
  85. return (0==strcmp(compressType,"zlib"))||(0==strcmp(compressType,"pzlib"));
  86. }
  87. static _zlib_TDecompress* _zlib_decompress_open_at(hpatch_TDecompress* decompressPlugin,
  88. const hpatch_TStreamInput* codeStream,
  89. hpatch_StreamPos_t code_begin,
  90. hpatch_StreamPos_t code_end,
  91. int isSavedWindowBits,
  92. _zlib_TDecompress* self,size_t _self_and_buf_size){
  93. int ret;
  94. signed char kWindowBits=-MAX_WBITS;
  95. assert(_self_and_buf_size>sizeof(_zlib_TDecompress));
  96. if (isSavedWindowBits){//load kWindowBits
  97. if (code_end-code_begin<1) _dec_openErr_rt();
  98. if (!codeStream->read(codeStream,code_begin,(unsigned char*)&kWindowBits,
  99. (unsigned char*)&kWindowBits+1)) return 0;
  100. ++code_begin;
  101. }
  102. memset(self,0,sizeof(_zlib_TDecompress));
  103. self->dec_buf=((unsigned char*)self)+sizeof(_zlib_TDecompress);
  104. self->dec_buf_size=_self_and_buf_size-sizeof(_zlib_TDecompress);
  105. self->codeStream=codeStream;
  106. self->code_begin=code_begin;
  107. self->code_end=code_end;
  108. self->windowBits=kWindowBits;
  109. self->d_stream.zalloc=__zlib_dec_Alloc;
  110. self->d_stream.zfree=__dec_free;
  111. self->d_stream.opaque=self;
  112. ret = inflateInit2(&self->d_stream,self->windowBits);
  113. if (ret!=Z_OK) { _dec_onDecErr_up(); _dec_openErr_rt(); }
  114. return self;
  115. }
  116. static hpatch_decompressHandle _zlib_decompress_open(hpatch_TDecompress* decompressPlugin,
  117. hpatch_StreamPos_t dataSize,
  118. const hpatch_TStreamInput* codeStream,
  119. hpatch_StreamPos_t code_begin,
  120. hpatch_StreamPos_t code_end){
  121. _zlib_TDecompress* self=0;
  122. unsigned char* _mem_buf=(unsigned char*)_dec_malloc(sizeof(_zlib_TDecompress)+kDecompressBufSize);
  123. if (!_mem_buf) _dec_memErr_rt();
  124. self=_zlib_decompress_open_at(decompressPlugin,codeStream,code_begin,code_end,1,
  125. (_zlib_TDecompress*)_mem_buf,sizeof(_zlib_TDecompress)+kDecompressBufSize);
  126. if (!self)
  127. free(_mem_buf);
  128. return self;
  129. }
  130. static hpatch_decompressHandle _zlib_decompress_open_deflate(hpatch_TDecompress* decompressPlugin,
  131. hpatch_StreamPos_t dataSize,
  132. const hpatch_TStreamInput* codeStream,
  133. hpatch_StreamPos_t code_begin,
  134. hpatch_StreamPos_t code_end){
  135. _zlib_TDecompress* self=0;
  136. unsigned char* _mem_buf=(unsigned char*)_dec_malloc(sizeof(_zlib_TDecompress)+kDecompressBufSize);
  137. if (!_mem_buf) _dec_memErr_rt();
  138. self=_zlib_decompress_open_at(decompressPlugin,codeStream,code_begin,code_end,0,
  139. (_zlib_TDecompress*)_mem_buf,sizeof(_zlib_TDecompress)+kDecompressBufSize);
  140. if (!self)
  141. free(_mem_buf);
  142. return self;
  143. }
  144. static _zlib_TDecompress* _zlib_decompress_open_by(hpatch_TDecompress* decompressPlugin,
  145. const hpatch_TStreamInput* codeStream,
  146. hpatch_StreamPos_t code_begin,
  147. hpatch_StreamPos_t code_end,
  148. int isSavedWindowBits,
  149. unsigned char* _mem_buf,size_t _mem_buf_size){
  150. #define __MAX_TS(a,b) ((a)>=(b)?(a):(b))
  151. const hpatch_size_t kZlibAlign=__MAX_TS(__MAX_TS(sizeof(hpatch_StreamPos_t),sizeof(void*)),sizeof(uLongf));
  152. #undef __MAX_TS
  153. unsigned char* _mem_buf_end=_mem_buf+_mem_buf_size;
  154. unsigned char* self_at=(unsigned char*)_hpatch_align_upper(_mem_buf,kZlibAlign);
  155. if (self_at>=_mem_buf_end) return 0;
  156. return _zlib_decompress_open_at(decompressPlugin,codeStream,code_begin,code_end,isSavedWindowBits,
  157. (_zlib_TDecompress*)self_at,_mem_buf_end-self_at);
  158. }
  159. static hpatch_BOOL _zlib_decompress_close_by(struct hpatch_TDecompress* decompressPlugin,
  160. _zlib_TDecompress* self){
  161. hpatch_BOOL result=hpatch_TRUE;
  162. if (!self) return result;
  163. _dec_onDecErr_up();
  164. if (self->d_stream.state!=0){
  165. _dec_close_check(Z_OK==inflateEnd(&self->d_stream));
  166. }
  167. memset(self,0,sizeof(_zlib_TDecompress));
  168. return result;
  169. }
  170. static hpatch_BOOL _zlib_decompress_close(struct hpatch_TDecompress* decompressPlugin,
  171. hpatch_decompressHandle decompressHandle){
  172. _zlib_TDecompress* self=(_zlib_TDecompress*)decompressHandle;
  173. hpatch_BOOL result=_zlib_decompress_close_by(decompressPlugin,self);
  174. if (self) free(self);
  175. return result;
  176. }
  177. static hpatch_BOOL _zlib_reset_for_next_node(_zlib_TDecompress* self){
  178. //backup
  179. Bytef* next_out_back=self->d_stream.next_out;
  180. Bytef* next_in_back=self->d_stream.next_in;
  181. unsigned int avail_out_back=self->d_stream.avail_out;
  182. unsigned int avail_in_back=self->d_stream.avail_in;
  183. //reset
  184. if (Z_OK!=inflateReset(&self->d_stream)) _dec_onDecErr_rt();
  185. //restore
  186. self->d_stream.next_out=next_out_back;
  187. self->d_stream.next_in=next_in_back;
  188. self->d_stream.avail_out=avail_out_back;
  189. self->d_stream.avail_in=avail_in_back;
  190. return hpatch_TRUE;
  191. }
  192. static hpatch_BOOL __zlib_do_inflate(hpatch_decompressHandle decompressHandle){
  193. _zlib_TDecompress* self=(_zlib_TDecompress*)decompressHandle;
  194. uInt avail_out_back,avail_in_back;
  195. int ret;
  196. hpatch_StreamPos_t codeLen=(self->code_end - self->code_begin);
  197. if ((self->d_stream.avail_in==0)&&(codeLen>0)) {
  198. size_t readLen=self->dec_buf_size;
  199. if (readLen>codeLen) readLen=(size_t)codeLen;
  200. self->d_stream.next_in=self->dec_buf;
  201. if (!self->codeStream->read(self->codeStream,self->code_begin,self->dec_buf,
  202. self->dec_buf+readLen)) return hpatch_FALSE;//error;
  203. self->d_stream.avail_in=(uInt)readLen;
  204. self->code_begin+=readLen;
  205. codeLen-=readLen;
  206. }
  207. avail_out_back=self->d_stream.avail_out;
  208. avail_in_back=self->d_stream.avail_in;
  209. ret=inflate(&self->d_stream,Z_NO_FLUSH);
  210. if (ret==Z_OK){
  211. if ((self->d_stream.avail_in==avail_in_back)&&(self->d_stream.avail_out==avail_out_back))
  212. _dec_onDecErr_rt();//error;
  213. }else if (ret==Z_STREAM_END){
  214. if (self->d_stream.avail_in+codeLen>0){ //next compress node!
  215. if (!_zlib_reset_for_next_node(self))
  216. return hpatch_FALSE;//error;
  217. }else{//all end
  218. if (self->d_stream.avail_out!=0)
  219. _dec_onDecErr_rt();//error;
  220. }
  221. }else{
  222. _dec_onDecErr_rt();//error;
  223. }
  224. return hpatch_TRUE;
  225. }
  226. static hpatch_BOOL _zlib_decompress_part(hpatch_decompressHandle decompressHandle,
  227. unsigned char* out_part_data,unsigned char* out_part_data_end){
  228. _zlib_TDecompress* self=(_zlib_TDecompress*)decompressHandle;
  229. assert(out_part_data<=out_part_data_end);
  230. self->d_stream.next_out = out_part_data;
  231. self->d_stream.avail_out =(uInt)(out_part_data_end-out_part_data);
  232. while (self->d_stream.avail_out>0) {
  233. if (!__zlib_do_inflate(self))
  234. return hpatch_FALSE;//error;
  235. }
  236. return hpatch_TRUE;
  237. }
  238. static hpatch_inline int _zlib_is_decompress_finish(const hpatch_TDecompress* decompressPlugin,
  239. hpatch_decompressHandle decompressHandle){
  240. _zlib_TDecompress* self=(_zlib_TDecompress*)decompressHandle;
  241. while (self->code_begin!=self->code_end){ //for end tag code
  242. unsigned char _empty;
  243. self->d_stream.next_out = &_empty;
  244. self->d_stream.avail_out=0;
  245. if (!__zlib_do_inflate(self))
  246. return hpatch_FALSE;//error;
  247. }
  248. return (self->code_begin==self->code_end)
  249. &(self->d_stream.avail_in==0)
  250. &(self->d_stream.avail_out==0);
  251. }
  252. static hpatch_TDecompress zlibDecompressPlugin={_zlib_is_can_open,_zlib_decompress_open,
  253. _zlib_decompress_close,_zlib_decompress_part};
  254. static hpatch_TDecompress zlibDecompressPlugin_deflate={_zlib_is_can_open,_zlib_decompress_open_deflate,
  255. _zlib_decompress_close,_zlib_decompress_part};
  256. #endif//_CompressPlugin_zlib
  257. #ifdef _CompressPlugin_bz2
  258. #if (_IsNeedIncludeDefaultCompressHead)
  259. # include "bzlib.h" // http://www.bzip.org/ https://github.com/sisong/bzip2
  260. #endif
  261. typedef struct _bz2_TDecompress{
  262. const struct hpatch_TStreamInput* codeStream;
  263. hpatch_StreamPos_t code_begin;
  264. hpatch_StreamPos_t code_end;
  265. bz_stream d_stream;
  266. hpatch_dec_error_t decError;
  267. unsigned char dec_buf[kDecompressBufSize];
  268. } _bz2_TDecompress;
  269. static hpatch_BOOL _bz2_is_can_open(const char* compressType){
  270. return (0==strcmp(compressType,"bz2"))||(0==strcmp(compressType,"bzip2"))
  271. ||(0==strcmp(compressType,"pbz2"))||(0==strcmp(compressType,"pbzip2"));
  272. }
  273. static hpatch_decompressHandle _bz2_open(struct hpatch_TDecompress* decompressPlugin,
  274. hpatch_StreamPos_t dataSize,
  275. const hpatch_TStreamInput* codeStream,
  276. hpatch_StreamPos_t code_begin,
  277. hpatch_StreamPos_t code_end){
  278. int ret;
  279. _bz2_TDecompress* self=(_bz2_TDecompress*)_dec_malloc(sizeof(_bz2_TDecompress));
  280. if (!self) _dec_memErr_rt();
  281. memset(self,0,sizeof(_bz2_TDecompress)-kDecompressBufSize);
  282. self->codeStream=codeStream;
  283. self->code_begin=code_begin;
  284. self->code_end=code_end;
  285. ret=BZ2_bzDecompressInit(&self->d_stream,0,0);
  286. if (ret!=BZ_OK){ free(self); _dec_openErr_rt(); }
  287. return self;
  288. }
  289. static hpatch_BOOL _bz2_close(struct hpatch_TDecompress* decompressPlugin,
  290. hpatch_decompressHandle decompressHandle){
  291. hpatch_BOOL result=hpatch_TRUE;
  292. _bz2_TDecompress* self=(_bz2_TDecompress*)decompressHandle;
  293. if (!self) return result;
  294. _dec_onDecErr_up();
  295. _dec_close_check(BZ_OK==BZ2_bzDecompressEnd(&self->d_stream));
  296. free(self);
  297. return result;
  298. }
  299. static hpatch_BOOL _bz2_reset_for_next_node(_bz2_TDecompress* self){
  300. //backup
  301. char* next_out_back=self->d_stream.next_out;
  302. char* next_in_back=self->d_stream.next_in;
  303. unsigned int avail_out_back=self->d_stream.avail_out;
  304. unsigned int avail_in_back=self->d_stream.avail_in;
  305. //reset
  306. if (BZ_OK!=BZ2_bzDecompressEnd(&self->d_stream)) _dec_onDecErr_rt();
  307. if (BZ_OK!=BZ2_bzDecompressInit(&self->d_stream,0,0)) _dec_onDecErr_rt();
  308. //restore
  309. self->d_stream.next_out=next_out_back;
  310. self->d_stream.next_in=next_in_back;
  311. self->d_stream.avail_out=avail_out_back;
  312. self->d_stream.avail_in=avail_in_back;
  313. return hpatch_TRUE;
  314. }
  315. static hpatch_BOOL _bz2_decompress_part_(hpatch_decompressHandle decompressHandle,
  316. unsigned char* out_part_data,unsigned char* out_part_data_end,
  317. hpatch_BOOL isMustOutData){
  318. _bz2_TDecompress* self=(_bz2_TDecompress*)decompressHandle;
  319. assert(out_part_data<=out_part_data_end);
  320. self->d_stream.next_out =(char*)out_part_data;
  321. self->d_stream.avail_out =(unsigned int)(out_part_data_end-out_part_data);
  322. while (self->d_stream.avail_out>0) {
  323. unsigned int avail_out_back,avail_in_back;
  324. int ret;
  325. hpatch_StreamPos_t codeLen=(self->code_end - self->code_begin);
  326. if ((self->d_stream.avail_in==0)&&(codeLen>0)) {
  327. size_t readLen=kDecompressBufSize;
  328. self->d_stream.next_in=(char*)self->dec_buf;
  329. if (readLen>codeLen) readLen=(size_t)codeLen;
  330. if (!self->codeStream->read(self->codeStream,self->code_begin,self->dec_buf,
  331. self->dec_buf+readLen)) return hpatch_FALSE;//error;
  332. self->d_stream.avail_in=(unsigned int)readLen;
  333. self->code_begin+=readLen;
  334. codeLen-=readLen;
  335. }
  336. avail_out_back=self->d_stream.avail_out;
  337. avail_in_back=self->d_stream.avail_in;
  338. ret=BZ2_bzDecompress(&self->d_stream);
  339. if (ret==BZ_OK){
  340. if ((self->d_stream.avail_in==avail_in_back)&&(self->d_stream.avail_out==avail_out_back))
  341. _dec_onDecErr_rt();//error;
  342. }else if (ret==BZ_STREAM_END){
  343. if (self->d_stream.avail_in+codeLen>0){ //next compress node!
  344. if (!_bz2_reset_for_next_node(self))
  345. return hpatch_FALSE;//error;
  346. }else{//all end
  347. if (self->d_stream.avail_out!=0){
  348. if (isMustOutData){ //fill out 0
  349. memset(self->d_stream.next_out,0,self->d_stream.avail_out);
  350. self->d_stream.next_out+=self->d_stream.avail_out;
  351. self->d_stream.avail_out=0;
  352. }else{
  353. _dec_onDecErr_rt();//error;
  354. }
  355. }
  356. }
  357. }else{
  358. _dec_onDecErr_rt();//error;
  359. }
  360. }
  361. return hpatch_TRUE;
  362. }
  363. static hpatch_BOOL _bz2_decompress_part(hpatch_decompressHandle decompressHandle,
  364. unsigned char* out_part_data,unsigned char* out_part_data_end){
  365. return _bz2_decompress_part_(decompressHandle,out_part_data,out_part_data_end,hpatch_FALSE);
  366. }
  367. static hpatch_BOOL _bz2_decompress_part_unsz(hpatch_decompressHandle decompressHandle,
  368. unsigned char* out_part_data,unsigned char* out_part_data_end){
  369. return _bz2_decompress_part_(decompressHandle,out_part_data,out_part_data_end,hpatch_TRUE);
  370. }
  371. static hpatch_TDecompress bz2DecompressPlugin={_bz2_is_can_open,_bz2_open,
  372. _bz2_close,_bz2_decompress_part};
  373. //unkown uncompress data size
  374. static hpatch_TDecompress _bz2DecompressPlugin_unsz={_bz2_is_can_open,_bz2_open,
  375. _bz2_close,_bz2_decompress_part_unsz};
  376. #endif//_CompressPlugin_bz2
  377. #if (defined _CompressPlugin_lzma) || (defined _CompressPlugin_lzma2)
  378. #if (_IsNeedIncludeDefaultCompressHead)
  379. # include "LzmaDec.h" // "lzma/C/LzmaDec.h" https://github.com/sisong/lzma
  380. # ifdef _CompressPlugin_lzma2
  381. # include "Lzma2Dec.h"
  382. # endif
  383. #endif
  384. #endif
  385. #ifdef _CompressPlugin_lzma
  386. typedef struct _lzma_TDecompress{
  387. ISzAlloc memAllocBase;
  388. const struct hpatch_TStreamInput* codeStream;
  389. hpatch_StreamPos_t code_begin;
  390. hpatch_StreamPos_t code_end;
  391. CLzmaDec decEnv;
  392. SizeT decCopyPos;
  393. SizeT decReadPos;
  394. hpatch_dec_error_t decError;
  395. unsigned char dec_buf[kDecompressBufSize];
  396. } _lzma_TDecompress;
  397. static void * __lzma1_dec_Alloc(ISzAllocPtr p, size_t size)
  398. __dec_Alloc_fun(_lzma_TDecompress,p,size)
  399. static hpatch_BOOL _lzma_is_can_open(const char* compressType){
  400. return (0==strcmp(compressType,"lzma"));
  401. }
  402. static hpatch_decompressHandle _lzma_open(hpatch_TDecompress* decompressPlugin,
  403. hpatch_StreamPos_t dataSize,
  404. const hpatch_TStreamInput* codeStream,
  405. hpatch_StreamPos_t code_begin,
  406. hpatch_StreamPos_t code_end){
  407. _lzma_TDecompress* self=0;
  408. SRes ret;
  409. unsigned char propsSize=0;
  410. unsigned char props[256];
  411. //load propsSize
  412. if (code_end-code_begin<1) _dec_openErr_rt();
  413. if (!codeStream->read(codeStream,code_begin,&propsSize,&propsSize+1)) return 0;
  414. ++code_begin;
  415. if (propsSize>(code_end-code_begin)) _dec_openErr_rt();
  416. //load props
  417. if (!codeStream->read(codeStream,code_begin,props,props+propsSize)) return 0;
  418. code_begin+=propsSize;
  419. self=(_lzma_TDecompress*)_dec_malloc(sizeof(_lzma_TDecompress));
  420. if (!self) _dec_memErr_rt();
  421. memset(self,0,sizeof(_lzma_TDecompress)-kDecompressBufSize);
  422. self->memAllocBase.Alloc=__lzma1_dec_Alloc;
  423. *((void**)&self->memAllocBase.Free)=(void*)__dec_free;
  424. self->codeStream=codeStream;
  425. self->code_begin=code_begin;
  426. self->code_end=code_end;
  427. self->decCopyPos=0;
  428. self->decReadPos=kDecompressBufSize;
  429. LzmaDec_Construct(&self->decEnv);
  430. ret=LzmaDec_Allocate(&self->decEnv,props,propsSize,&self->memAllocBase);
  431. if (ret!=SZ_OK){ _dec_onDecErr_up(); free(self); _dec_openErr_rt(); }
  432. LzmaDec_Init(&self->decEnv);
  433. return self;
  434. }
  435. static hpatch_BOOL _lzma_close(struct hpatch_TDecompress* decompressPlugin,
  436. hpatch_decompressHandle decompressHandle){
  437. _lzma_TDecompress* self=(_lzma_TDecompress*)decompressHandle;
  438. if (!self) return hpatch_TRUE;
  439. LzmaDec_Free(&self->decEnv,&self->memAllocBase);
  440. _dec_onDecErr_up();
  441. free(self);
  442. return hpatch_TRUE;
  443. }
  444. static hpatch_BOOL _lzma_decompress_part(hpatch_decompressHandle decompressHandle,
  445. unsigned char* out_part_data,unsigned char* out_part_data_end){
  446. _lzma_TDecompress* self=(_lzma_TDecompress*)decompressHandle;
  447. unsigned char* out_cur=out_part_data;
  448. assert(out_part_data<=out_part_data_end);
  449. while (out_cur<out_part_data_end){
  450. size_t copyLen=(self->decEnv.dicPos-self->decCopyPos);
  451. if (copyLen>0){
  452. if (copyLen>(size_t)(out_part_data_end-out_cur))
  453. copyLen=(out_part_data_end-out_cur);
  454. memcpy(out_cur,self->decEnv.dic+self->decCopyPos,copyLen);
  455. out_cur+=copyLen;
  456. self->decCopyPos+=copyLen;
  457. if ((self->decEnv.dicPos==self->decEnv.dicBufSize)
  458. &&(self->decEnv.dicPos==self->decCopyPos)){
  459. self->decEnv.dicPos=0;
  460. self->decCopyPos=0;
  461. }
  462. }else{
  463. ELzmaStatus status;
  464. SizeT inSize,dicPos_back;
  465. SRes res;
  466. hpatch_StreamPos_t codeLen=(self->code_end - self->code_begin);
  467. if ((self->decReadPos==kDecompressBufSize)&&(codeLen>0)) {
  468. size_t readLen=kDecompressBufSize;
  469. if (readLen>codeLen) readLen=(size_t)codeLen;
  470. self->decReadPos=kDecompressBufSize-readLen;
  471. if (!self->codeStream->read(self->codeStream,self->code_begin,self->dec_buf+self->decReadPos,
  472. self->dec_buf+self->decReadPos+readLen)) return hpatch_FALSE;//error;
  473. self->code_begin+=readLen;
  474. }
  475. inSize=kDecompressBufSize-self->decReadPos;
  476. dicPos_back=self->decEnv.dicPos;
  477. res=LzmaDec_DecodeToDic(&self->decEnv,self->decEnv.dicBufSize,
  478. self->dec_buf+self->decReadPos,&inSize,LZMA_FINISH_ANY,&status);
  479. if(res==SZ_OK){
  480. if ((inSize==0)&&(self->decEnv.dicPos==dicPos_back))
  481. _dec_onDecErr_rt();//error;
  482. }else{
  483. _dec_onDecErr_rt();//error;
  484. }
  485. self->decReadPos+=inSize;
  486. }
  487. }
  488. return hpatch_TRUE;
  489. }
  490. static hpatch_TDecompress lzmaDecompressPlugin={_lzma_is_can_open,_lzma_open,
  491. _lzma_close,_lzma_decompress_part};
  492. #endif//_CompressPlugin_lzma
  493. #ifdef _CompressPlugin_lzma2
  494. typedef struct _lzma2_TDecompress{
  495. ISzAlloc memAllocBase;
  496. const struct hpatch_TStreamInput* codeStream;
  497. hpatch_StreamPos_t code_begin;
  498. hpatch_StreamPos_t code_end;
  499. CLzma2Dec decEnv;
  500. SizeT decCopyPos;
  501. SizeT decReadPos;
  502. hpatch_dec_error_t decError;
  503. unsigned char dec_buf[kDecompressBufSize];
  504. } _lzma2_TDecompress;
  505. static void * __lzma2_dec_Alloc(ISzAllocPtr p, size_t size)
  506. __dec_Alloc_fun(_lzma2_TDecompress,p,size)
  507. static hpatch_BOOL _lzma2_is_can_open(const char* compressType){
  508. return (0==strcmp(compressType,"lzma2"));
  509. }
  510. static hpatch_decompressHandle _lzma2_open(hpatch_TDecompress* decompressPlugin,
  511. hpatch_StreamPos_t dataSize,
  512. const hpatch_TStreamInput* codeStream,
  513. hpatch_StreamPos_t code_begin,
  514. hpatch_StreamPos_t code_end){
  515. _lzma2_TDecompress* self=0;
  516. SRes ret;
  517. unsigned char propsSize=0;
  518. //load propsSize
  519. if (code_end-code_begin<1) _dec_openErr_rt();
  520. if (!codeStream->read(codeStream,code_begin,&propsSize,&propsSize+1)) return 0;
  521. ++code_begin;
  522. self=(_lzma2_TDecompress*)_dec_malloc(sizeof(_lzma2_TDecompress));
  523. if (!self) _dec_memErr_rt();
  524. memset(self,0,sizeof(_lzma2_TDecompress)-kDecompressBufSize);
  525. self->memAllocBase.Alloc=__lzma2_dec_Alloc;
  526. *((void**)&self->memAllocBase.Free)=(void*)__dec_free;
  527. self->codeStream=codeStream;
  528. self->code_begin=code_begin;
  529. self->code_end=code_end;
  530. self->decCopyPos=0;
  531. self->decReadPos=kDecompressBufSize;
  532. Lzma2Dec_Construct(&self->decEnv);
  533. ret=Lzma2Dec_Allocate(&self->decEnv,propsSize,&self->memAllocBase);
  534. if (ret!=SZ_OK){ _dec_onDecErr_up(); free(self); _dec_openErr_rt(); }
  535. Lzma2Dec_Init(&self->decEnv);
  536. return self;
  537. }
  538. static hpatch_BOOL _lzma2_close(struct hpatch_TDecompress* decompressPlugin,
  539. hpatch_decompressHandle decompressHandle){
  540. _lzma2_TDecompress* self=(_lzma2_TDecompress*)decompressHandle;
  541. if (!self) return hpatch_TRUE;
  542. Lzma2Dec_Free(&self->decEnv,&self->memAllocBase);
  543. _dec_onDecErr_up();
  544. free(self);
  545. return hpatch_TRUE;
  546. }
  547. static hpatch_BOOL _lzma2_decompress_part(hpatch_decompressHandle decompressHandle,
  548. unsigned char* out_part_data,unsigned char* out_part_data_end){
  549. _lzma2_TDecompress* self=(_lzma2_TDecompress*)decompressHandle;
  550. unsigned char* out_cur=out_part_data;
  551. assert(out_part_data<=out_part_data_end);
  552. while (out_cur<out_part_data_end){
  553. size_t copyLen=(self->decEnv.decoder.dicPos-self->decCopyPos);
  554. if (copyLen>0){
  555. if (copyLen>(size_t)(out_part_data_end-out_cur))
  556. copyLen=(out_part_data_end-out_cur);
  557. memcpy(out_cur,self->decEnv.decoder.dic+self->decCopyPos,copyLen);
  558. out_cur+=copyLen;
  559. self->decCopyPos+=copyLen;
  560. if ((self->decEnv.decoder.dicPos==self->decEnv.decoder.dicBufSize)
  561. &&(self->decEnv.decoder.dicPos==self->decCopyPos)){
  562. self->decEnv.decoder.dicPos=0;
  563. self->decCopyPos=0;
  564. }
  565. }else{
  566. ELzmaStatus status;
  567. SizeT inSize,dicPos_back;
  568. SRes res;
  569. hpatch_StreamPos_t codeLen=(self->code_end - self->code_begin);
  570. if ((self->decReadPos==kDecompressBufSize)&&(codeLen>0)) {
  571. size_t readLen=kDecompressBufSize;
  572. if (readLen>codeLen) readLen=(size_t)codeLen;
  573. self->decReadPos=kDecompressBufSize-readLen;
  574. if (!self->codeStream->read(self->codeStream,self->code_begin,self->dec_buf+self->decReadPos,
  575. self->dec_buf+self->decReadPos+readLen)) return hpatch_FALSE;//error;
  576. self->code_begin+=readLen;
  577. }
  578. inSize=kDecompressBufSize-self->decReadPos;
  579. dicPos_back=self->decEnv.decoder.dicPos;
  580. res=Lzma2Dec_DecodeToDic(&self->decEnv,self->decEnv.decoder.dicBufSize,
  581. self->dec_buf+self->decReadPos,&inSize,LZMA_FINISH_ANY,&status);
  582. if(res==SZ_OK){
  583. if ((inSize==0)&&(self->decEnv.decoder.dicPos==dicPos_back))
  584. _dec_onDecErr_rt();//error;
  585. }else{
  586. _dec_onDecErr_rt();//error;
  587. }
  588. self->decReadPos+=inSize;
  589. }
  590. }
  591. return hpatch_TRUE;
  592. }
  593. static hpatch_TDecompress lzma2DecompressPlugin={_lzma2_is_can_open,_lzma2_open,
  594. _lzma2_close,_lzma2_decompress_part};
  595. #endif//_CompressPlugin_lzma2
  596. #ifdef _CompressPlugin_7zXZ
  597. #if (_IsNeedIncludeDefaultCompressHead)
  598. # include "Xz.h" // "lzma/C/Xz.h" https://github.com/sisong/lzma
  599. # include "7zCrc.h" // CrcGenerateTable()
  600. #endif
  601. #ifndef _init_CompressPlugin_7zXZ_DEF
  602. # define _init_CompressPlugin_7zXZ_DEF
  603. static int _init_CompressPlugin_7zXZ(){
  604. static hpatch_BOOL _isInit=hpatch_FALSE;
  605. if (!_isInit){
  606. CrcGenerateTable();
  607. _isInit=hpatch_TRUE;
  608. }
  609. return 0;
  610. }
  611. #endif
  612. typedef struct _7zXZ_TDecompress{
  613. ISzAlloc memAllocBase;
  614. const struct hpatch_TStreamInput* codeStream;
  615. hpatch_StreamPos_t code_begin;
  616. hpatch_StreamPos_t code_end;
  617. hpatch_TDecompress* decompressPlugin;
  618. hpatch_BOOL isResetState;
  619. CXzUnpacker decEnv;
  620. SizeT decCopyPos;
  621. SizeT decReadPos;
  622. hpatch_dec_error_t decError;
  623. unsigned char dec_buf[kDecompressBufSize];
  624. } _7zXZ_TDecompress;
  625. static void * __7zXZ_dec_Alloc(ISzAllocPtr p, size_t size)
  626. __dec_Alloc_fun(_7zXZ_TDecompress,p,size)
  627. static hpatch_BOOL _7zXZ_is_can_open(const char* compressType){
  628. return (0==strcmp(compressType,"7zXZ"));
  629. }
  630. static void _7zXZ_open_at(_7zXZ_TDecompress* self, hpatch_TDecompress* decompressPlugin,hpatch_StreamPos_t dataSize,
  631. const hpatch_TStreamInput* codeStream,hpatch_StreamPos_t code_begin,
  632. hpatch_StreamPos_t code_end,hpatch_BOOL isResetState,hpatch_BOOL isParseHead){
  633. memset(self,0,sizeof(_7zXZ_TDecompress)-kDecompressBufSize);
  634. self->memAllocBase.Alloc=__7zXZ_dec_Alloc;
  635. *((void**)&self->memAllocBase.Free)=(void*)__dec_free;
  636. self->codeStream=codeStream;
  637. self->code_begin=code_begin;
  638. self->code_end=code_end;
  639. self->decompressPlugin=decompressPlugin;
  640. self->isResetState=isResetState;
  641. self->decCopyPos=0;
  642. self->decReadPos=kDecompressBufSize;
  643. XzUnpacker_Construct(&self->decEnv,&self->memAllocBase);
  644. XzUnpacker_Init(&self->decEnv);
  645. if (!isParseHead)
  646. self->decEnv.state=XZ_STATE_BLOCK_HEADER;
  647. }
  648. static void _7zXZ_close_at(hpatch_decompressHandle decompressHandle){
  649. _7zXZ_TDecompress* self=(_7zXZ_TDecompress*)decompressHandle;
  650. if (self){
  651. hpatch_TDecompress* decompressPlugin=self->decompressPlugin;
  652. XzUnpacker_Free(&self->decEnv);
  653. _dec_onDecErr_up();
  654. }
  655. }
  656. static hpatch_decompressHandle _7zXZ_open(hpatch_TDecompress* decompressPlugin,
  657. hpatch_StreamPos_t dataSize,
  658. const hpatch_TStreamInput* codeStream,
  659. hpatch_StreamPos_t code_begin,
  660. hpatch_StreamPos_t code_end){
  661. _7zXZ_TDecompress* self=0;
  662. self=(_7zXZ_TDecompress*)_dec_malloc(sizeof(_7zXZ_TDecompress));
  663. if (!self) _dec_memErr_rt();
  664. _7zXZ_open_at(self,decompressPlugin,dataSize,codeStream,
  665. code_begin,code_end,hpatch_FALSE,hpatch_TRUE);
  666. return self;
  667. }
  668. static hpatch_decompressHandle _7zXZ_a_open(hpatch_TDecompress* decompressPlugin,
  669. hpatch_StreamPos_t dataSize,
  670. const hpatch_TStreamInput* codeStream,
  671. hpatch_StreamPos_t code_begin,
  672. hpatch_StreamPos_t code_end){
  673. _7zXZ_TDecompress* self=0;
  674. self=(_7zXZ_TDecompress*)_dec_malloc(sizeof(_7zXZ_TDecompress));
  675. if (!self) _dec_memErr_rt();
  676. _7zXZ_open_at(self,decompressPlugin,dataSize,codeStream,
  677. code_begin,code_end,hpatch_TRUE,hpatch_TRUE);
  678. return self;
  679. }
  680. static hpatch_BOOL _7zXZ_close(struct hpatch_TDecompress* decompressPlugin,
  681. hpatch_decompressHandle decompressHandle){
  682. if (decompressHandle){
  683. _7zXZ_close_at(decompressHandle);
  684. free(decompressHandle);
  685. }
  686. return hpatch_TRUE;
  687. }
  688. static hpatch_BOOL _7zXZ_reset_code(hpatch_decompressHandle decompressHandle,
  689. hpatch_StreamPos_t dataSize,
  690. const struct hpatch_TStreamInput* codeStream,
  691. hpatch_StreamPos_t code_begin,
  692. hpatch_StreamPos_t code_end){
  693. _7zXZ_TDecompress* self=(_7zXZ_TDecompress*)decompressHandle;
  694. hpatch_BOOL isResetState=self->isResetState;
  695. if (isResetState){
  696. hpatch_TDecompress* decompressPlugin=self->decompressPlugin;
  697. _7zXZ_close_at(self);
  698. _7zXZ_open_at(self,decompressPlugin,dataSize,codeStream,
  699. code_begin,code_end,isResetState,hpatch_FALSE);
  700. }else{
  701. self->codeStream=codeStream;
  702. self->code_begin=code_begin;
  703. self->code_end=code_end;
  704. self->decCopyPos=0;
  705. self->decReadPos=kDecompressBufSize;
  706. }
  707. return hpatch_TRUE;
  708. }
  709. static hpatch_BOOL _7zXZ_decompress_part(hpatch_decompressHandle decompressHandle,
  710. unsigned char* out_part_data,unsigned char* out_part_data_end){
  711. _7zXZ_TDecompress* self=(_7zXZ_TDecompress*)decompressHandle;
  712. unsigned char* out_cur=out_part_data;
  713. assert(out_part_data<=out_part_data_end);
  714. while (out_cur<out_part_data_end){
  715. ECoderStatus status;
  716. SizeT inSize;
  717. SizeT outSize=out_part_data_end-out_cur;
  718. SRes res;
  719. hpatch_StreamPos_t codeLen=(self->code_end-self->code_begin);
  720. if ((self->decReadPos==kDecompressBufSize)&&(codeLen>0)) {
  721. size_t readLen=kDecompressBufSize;
  722. if (readLen>codeLen) readLen=(size_t)codeLen;
  723. self->decReadPos=kDecompressBufSize-readLen;
  724. if (!self->codeStream->read(self->codeStream,self->code_begin,self->dec_buf+self->decReadPos,
  725. self->dec_buf+self->decReadPos+readLen)) return hpatch_FALSE;//error;
  726. self->code_begin+=readLen;
  727. codeLen-=readLen;
  728. }
  729. inSize=kDecompressBufSize-self->decReadPos;
  730. res=XzUnpacker_Code(&self->decEnv,out_cur,&outSize,self->dec_buf+self->decReadPos,&inSize,
  731. codeLen==0,CODER_FINISH_ANY,&status);
  732. if(res==SZ_OK){
  733. if ((inSize==0)&&(outSize==0))
  734. _dec_onDecErr_rt();//error;
  735. }else{
  736. _dec_onDecErr_rt();//error;
  737. }
  738. self->decReadPos+=inSize;
  739. out_cur+=outSize;
  740. }
  741. return hpatch_TRUE;
  742. }
  743. static hpatch_TDecompress _7zXZDecompressPlugin={_7zXZ_is_can_open,_7zXZ_open,
  744. _7zXZ_close,_7zXZ_decompress_part,_7zXZ_reset_code};
  745. static hpatch_TDecompress _7zXZDecompressPlugin_a={_7zXZ_is_can_open,_7zXZ_a_open,
  746. _7zXZ_close,_7zXZ_decompress_part,_7zXZ_reset_code};
  747. #endif//_CompressPlugin_7zXZ
  748. #if (defined(_CompressPlugin_lz4) || defined(_CompressPlugin_lz4hc))
  749. #if (_IsNeedIncludeDefaultCompressHead)
  750. # include "lz4.h" // "lz4/lib/lz4.h" https://github.com/lz4/lz4
  751. #endif
  752. typedef struct _lz4_TDecompress{
  753. const struct hpatch_TStreamInput* codeStream;
  754. hpatch_StreamPos_t code_begin;
  755. hpatch_StreamPos_t code_end;
  756. LZ4_streamDecode_t *s;
  757. int kLz4CompressBufSize;
  758. int code_buf_size;
  759. int data_begin;
  760. int data_end;
  761. hpatch_dec_error_t decError;
  762. unsigned char buf[1];
  763. } _lz4_TDecompress;
  764. static hpatch_BOOL _lz4_is_can_open(const char* compressType){
  765. return (0==strcmp(compressType,"lz4"));
  766. }
  767. #define _lz4_read_len4(len,in_code,code_begin,code_end,__dec_err_rt) { \
  768. unsigned char _temp_buf4[4]; \
  769. if (4>code_end-code_begin) __dec_err_rt(); \
  770. if (!in_code->read(in_code,code_begin,_temp_buf4,_temp_buf4+4)) \
  771. return hpatch_FALSE; \
  772. len=_temp_buf4[0]|(_temp_buf4[1]<<8)|(_temp_buf4[2]<<16)|(_temp_buf4[3]<<24); \
  773. code_begin+=4; \
  774. }
  775. static hpatch_decompressHandle _lz4_open(hpatch_TDecompress* decompressPlugin,
  776. hpatch_StreamPos_t dataSize,
  777. const hpatch_TStreamInput* codeStream,
  778. hpatch_StreamPos_t code_begin,
  779. hpatch_StreamPos_t code_end){
  780. const int kMaxLz4CompressBufSize=(1<<20)*64; //defence attack
  781. _lz4_TDecompress* self=0;
  782. int kLz4CompressBufSize=0;
  783. int code_buf_size=0;
  784. assert(code_begin<code_end);
  785. {//read kLz4CompressBufSize
  786. _lz4_read_len4(kLz4CompressBufSize,codeStream,code_begin,code_end,_dec_openErr_rt);
  787. if ((kLz4CompressBufSize<0)||(kLz4CompressBufSize>=kMaxLz4CompressBufSize)) _dec_openErr_rt();
  788. code_buf_size=LZ4_compressBound(kLz4CompressBufSize);
  789. }
  790. self=(_lz4_TDecompress*)_dec_malloc(sizeof(_lz4_TDecompress)+kLz4CompressBufSize+code_buf_size);
  791. if (!self) _dec_memErr_rt();
  792. memset(self,0,sizeof(_lz4_TDecompress));
  793. self->codeStream=codeStream;
  794. self->code_begin=code_begin;
  795. self->code_end=code_end;
  796. self->kLz4CompressBufSize=kLz4CompressBufSize;
  797. self->code_buf_size=code_buf_size;
  798. self->data_begin=0;
  799. self->data_end=0;
  800. self->s = LZ4_createStreamDecode();
  801. if (!self->s){ free(self); _dec_openErr_rt(); }
  802. return self;
  803. }
  804. static hpatch_BOOL _lz4_close(struct hpatch_TDecompress* decompressPlugin,
  805. hpatch_decompressHandle decompressHandle){
  806. hpatch_BOOL result=hpatch_TRUE;
  807. _lz4_TDecompress* self=(_lz4_TDecompress*)decompressHandle;
  808. if (!self) return result;
  809. _dec_onDecErr_up();
  810. _dec_close_check(0==LZ4_freeStreamDecode(self->s));
  811. free(self);
  812. return result;
  813. }
  814. static hpatch_BOOL _lz4_decompress_part(hpatch_decompressHandle decompressHandle,
  815. unsigned char* out_part_data,unsigned char* out_part_data_end){
  816. _lz4_TDecompress* self=(_lz4_TDecompress*)decompressHandle;
  817. unsigned char* data_buf=self->buf;
  818. unsigned char* code_buf=self->buf+self->kLz4CompressBufSize;
  819. while (out_part_data<out_part_data_end) {
  820. size_t dataLen=self->data_end-self->data_begin;
  821. if (dataLen>0){
  822. if (dataLen>(out_part_data_end-out_part_data))
  823. dataLen=(out_part_data_end-out_part_data);
  824. memcpy(out_part_data,data_buf+self->data_begin,dataLen);
  825. out_part_data+=(size_t)dataLen;
  826. self->data_begin+=dataLen;
  827. }else{
  828. int codeLen;
  829. _lz4_read_len4(codeLen,self->codeStream,self->code_begin,self->code_end,_dec_onDecErr_rt);
  830. if ((codeLen<=0)||(codeLen>self->code_buf_size)
  831. ||((size_t)codeLen>(self->code_end-self->code_begin))) _dec_onDecErr_rt();
  832. if (!self->codeStream->read(self->codeStream,self->code_begin,
  833. code_buf,code_buf+codeLen)) return hpatch_FALSE;
  834. self->code_begin+=codeLen;
  835. self->data_begin=0;
  836. self->data_end=LZ4_decompress_safe_continue(self->s,(const char*)code_buf,(char*)data_buf,
  837. codeLen,self->kLz4CompressBufSize);
  838. if (self->data_end<=0) _dec_onDecErr_rt();
  839. }
  840. }
  841. return hpatch_TRUE;
  842. }
  843. static hpatch_TDecompress lz4DecompressPlugin={_lz4_is_can_open,_lz4_open,
  844. _lz4_close,_lz4_decompress_part};
  845. #endif//_CompressPlugin_lz4 or _CompressPlugin_lz4hc
  846. #ifdef _CompressPlugin_zstd
  847. #if (_IsNeedIncludeDefaultCompressHead)
  848. //# define ZSTD_STATIC_LINKING_ONLY //for ZSTD_customMem
  849. # include "zstd.h" // "zstd/lib/zstd.h" https://github.com/sisong/zstd
  850. #endif
  851. typedef struct _zstd_TDecompress{
  852. const struct hpatch_TStreamInput* codeStream;
  853. hpatch_StreamPos_t code_begin;
  854. hpatch_StreamPos_t code_end;
  855. ZSTD_inBuffer s_input;
  856. ZSTD_outBuffer s_output;
  857. size_t data_begin;
  858. ZSTD_DStream* s;
  859. hpatch_dec_error_t decError;
  860. unsigned char buf[1];
  861. } _zstd_TDecompress;
  862. #ifdef ZSTD_STATIC_LINKING_ONLY
  863. static void* __ZSTD_alloc(void* opaque, size_t size)
  864. __dec_Alloc_fun(_zstd_TDecompress,opaque,size)
  865. #endif
  866. static hpatch_BOOL _zstd_is_can_open(const char* compressType){
  867. return (0==strcmp(compressType,"zstd"));
  868. }
  869. static hpatch_decompressHandle _zstd_open(hpatch_TDecompress* decompressPlugin,
  870. hpatch_StreamPos_t dataSize,
  871. const hpatch_TStreamInput* codeStream,
  872. hpatch_StreamPos_t code_begin,
  873. hpatch_StreamPos_t code_end){
  874. _zstd_TDecompress* self=0;
  875. size_t ret;
  876. size_t _input_size=ZSTD_DStreamInSize();
  877. size_t _output_size=ZSTD_DStreamOutSize();
  878. self=(_zstd_TDecompress*)_dec_malloc(sizeof(_zstd_TDecompress)+_input_size+_output_size);
  879. if (!self) _dec_memErr_rt();
  880. memset(self,0,sizeof(_zstd_TDecompress));
  881. self->codeStream=codeStream;
  882. self->code_begin=code_begin;
  883. self->code_end=code_end;
  884. self->s_input.src=self->buf;
  885. self->s_input.size=_input_size;
  886. self->s_input.pos=_input_size;
  887. self->s_output.dst=self->buf+_input_size;
  888. self->s_output.size=_output_size;
  889. self->s_output.pos=0;
  890. self->data_begin=0;
  891. #ifdef ZSTD_STATIC_LINKING_ONLY
  892. {
  893. ZSTD_customMem customMem={__ZSTD_alloc,__dec_free,self};
  894. self->s=ZSTD_createDStream_advanced(customMem);
  895. }
  896. #else
  897. self->s=ZSTD_createDStream();
  898. #endif
  899. if (!self->s){ _dec_onDecErr_up(); free(self); _dec_openErr_rt(); }
  900. ret=ZSTD_initDStream(self->s);
  901. if (ZSTD_isError(ret)) { ZSTD_freeDStream(self->s); _dec_onDecErr_up(); free(self); _dec_openErr_rt(); }
  902. #define _ZSTD_WINDOWLOG_MAX 30
  903. ret=ZSTD_DCtx_setParameter(self->s,ZSTD_d_windowLogMax,_ZSTD_WINDOWLOG_MAX);
  904. //if (ZSTD_isError(ret)) { printf("WARNING: ZSTD_DCtx_setMaxWindowSize() error!"); }
  905. return self;
  906. }
  907. static hpatch_BOOL _zstd_close(struct hpatch_TDecompress* decompressPlugin,
  908. hpatch_decompressHandle decompressHandle){
  909. hpatch_BOOL result=hpatch_TRUE;
  910. _zstd_TDecompress* self=(_zstd_TDecompress*)decompressHandle;
  911. if (!self) return result;
  912. _dec_onDecErr_up();
  913. _dec_close_check(0==ZSTD_freeDStream(self->s));
  914. free(self);
  915. return result;
  916. }
  917. static hpatch_BOOL _zstd_decompress_part(hpatch_decompressHandle decompressHandle,
  918. unsigned char* out_part_data,unsigned char* out_part_data_end){
  919. _zstd_TDecompress* self=(_zstd_TDecompress*)decompressHandle;
  920. while (out_part_data<out_part_data_end) {
  921. size_t dataLen=(self->s_output.pos-self->data_begin);
  922. if (dataLen>0){
  923. if (dataLen>(size_t)(out_part_data_end-out_part_data))
  924. dataLen=(out_part_data_end-out_part_data);
  925. memcpy(out_part_data,(const unsigned char*)self->s_output.dst+self->data_begin,dataLen);
  926. out_part_data+=dataLen;
  927. self->data_begin+=dataLen;
  928. }else{
  929. size_t ret;
  930. if (self->s_input.pos==self->s_input.size) {
  931. self->s_input.pos=0;
  932. if (self->s_input.size>self->code_end-self->code_begin)
  933. self->s_input.size=(size_t)(self->code_end-self->code_begin);
  934. if (self->s_input.size>0){
  935. if (!self->codeStream->read(self->codeStream,self->code_begin,(unsigned char*)self->s_input.src,
  936. (unsigned char*)self->s_input.src+self->s_input.size))
  937. return hpatch_FALSE;
  938. self->code_begin+=self->s_input.size;
  939. }
  940. }
  941. self->s_output.pos=0;
  942. self->data_begin=0;
  943. ret=ZSTD_decompressStream(self->s,&self->s_output,&self->s_input);
  944. if (ZSTD_isError(ret)) _dec_onDecErr_rt();
  945. if (self->s_output.pos==self->data_begin) _dec_onDecErr_rt();
  946. }
  947. }
  948. return hpatch_TRUE;
  949. }
  950. static hpatch_TDecompress zstdDecompressPlugin={_zstd_is_can_open,_zstd_open,
  951. _zstd_close,_zstd_decompress_part};
  952. #endif//_CompressPlugin_zstd
  953. #ifdef _CompressPlugin_brotli
  954. #if (_IsNeedIncludeDefaultCompressHead)
  955. # include "brotli/decode.h" // "brotli/c/include/brotli/decode.h" https://github.com/google/brotli
  956. #endif
  957. typedef struct _brotli_TDecompress{
  958. const struct hpatch_TStreamInput* codeStream;
  959. hpatch_StreamPos_t code_begin;
  960. hpatch_StreamPos_t code_end;
  961. unsigned char* input;
  962. unsigned char* output;
  963. size_t available_in;
  964. size_t available_out;
  965. const unsigned char* next_in;
  966. unsigned char* next_out;
  967. unsigned char* data_begin;
  968. BrotliDecoderState* s;
  969. hpatch_dec_error_t decError;
  970. unsigned char buf[1];
  971. } _brotli_TDecompress;
  972. static hpatch_BOOL _brotli_is_can_open(const char* compressType){
  973. return (0==strcmp(compressType,"brotli"));
  974. }
  975. static hpatch_decompressHandle _brotli_open(hpatch_TDecompress* decompressPlugin,
  976. hpatch_StreamPos_t dataSize,
  977. const hpatch_TStreamInput* codeStream,
  978. hpatch_StreamPos_t code_begin,
  979. hpatch_StreamPos_t code_end){
  980. const size_t kBufSize=kDecompressBufSize;
  981. _brotli_TDecompress* self=0;
  982. assert(code_begin<code_end);
  983. self=(_brotli_TDecompress*)_dec_malloc(sizeof(_brotli_TDecompress)+kBufSize*2);
  984. if (!self) _dec_memErr_rt();
  985. memset(self,0,sizeof(_brotli_TDecompress));
  986. self->codeStream=codeStream;
  987. self->code_begin=code_begin;
  988. self->input=self->buf;
  989. self->output=self->buf+kBufSize;
  990. self->code_end=code_end;
  991. self->available_in = 0;
  992. self->next_in = 0;
  993. self->available_out = (self->output-self->input);
  994. self->next_out =self->output;
  995. self->data_begin=self->output;
  996. self->s = BrotliDecoderCreateInstance(0,0,0);
  997. if (!self->s){ free(self); _dec_openErr_rt(); }
  998. if (!BrotliDecoderSetParameter(self->s, BROTLI_DECODER_PARAM_LARGE_WINDOW, 1u))
  999. { BrotliDecoderDestroyInstance(self->s); free(self); _dec_openErr_rt(); }
  1000. return self;
  1001. }
  1002. static hpatch_BOOL _brotli_close(struct hpatch_TDecompress* decompressPlugin,
  1003. hpatch_decompressHandle decompressHandle){
  1004. _brotli_TDecompress* self=(_brotli_TDecompress*)decompressHandle;
  1005. if (!self) return hpatch_TRUE;
  1006. _dec_onDecErr_up();
  1007. BrotliDecoderDestroyInstance(self->s);
  1008. free(self);
  1009. return hpatch_TRUE;
  1010. }
  1011. static hpatch_BOOL _brotli_decompress_part(hpatch_decompressHandle decompressHandle,
  1012. unsigned char* out_part_data,unsigned char* out_part_data_end){
  1013. _brotli_TDecompress* self=(_brotli_TDecompress*)decompressHandle;
  1014. while (out_part_data<out_part_data_end) {
  1015. size_t dataLen=(self->next_out-self->data_begin);
  1016. if (dataLen>0){
  1017. if (dataLen>(size_t)(out_part_data_end-out_part_data))
  1018. dataLen=(out_part_data_end-out_part_data);
  1019. memcpy(out_part_data,self->data_begin,dataLen);
  1020. out_part_data+=dataLen;
  1021. self->data_begin+=dataLen;
  1022. }else{
  1023. BrotliDecoderResult ret;
  1024. if (self->available_in==0) {
  1025. self->available_in=(self->output-self->input);
  1026. if (self->available_in>self->code_end-self->code_begin)
  1027. self->available_in=(size_t)(self->code_end-self->code_begin);
  1028. if (self->available_in>0){
  1029. if (!self->codeStream->read(self->codeStream,self->code_begin,(unsigned char*)self->input,
  1030. self->input+self->available_in))
  1031. return hpatch_FALSE;
  1032. self->code_begin+=self->available_in;
  1033. }
  1034. self->next_in=self->input;
  1035. }
  1036. self->available_out = (self->output-self->input);
  1037. self->next_out =self->output;
  1038. self->data_begin=self->output;
  1039. ret=BrotliDecoderDecompressStream(self->s,&self->available_in,&self->next_in,
  1040. &self->available_out,&self->next_out, 0);
  1041. switch (ret){
  1042. case BROTLI_DECODER_RESULT_SUCCESS:
  1043. case BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT: {
  1044. if (self->next_out==self->data_begin) _dec_onDecErr_rt();
  1045. } break;
  1046. case BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT: {
  1047. if (self->code_end==self->code_begin) _dec_onDecErr_rt();
  1048. } break;
  1049. default:
  1050. _dec_onDecErr_rt();
  1051. }
  1052. }
  1053. }
  1054. return hpatch_TRUE;
  1055. }
  1056. static hpatch_TDecompress brotliDecompressPlugin={_brotli_is_can_open,_brotli_open,
  1057. _brotli_close,_brotli_decompress_part};
  1058. #endif//_CompressPlugin_brotli
  1059. #ifdef _CompressPlugin_lzham
  1060. #if (_IsNeedIncludeDefaultCompressHead)
  1061. # include "lzham.h" // "lzham_codec/include/lzham.h" https://github.com/richgel999/lzham_codec
  1062. #endif
  1063. typedef struct _lzham_TDecompress{
  1064. const struct hpatch_TStreamInput* codeStream;
  1065. hpatch_StreamPos_t code_begin;
  1066. hpatch_StreamPos_t code_end;
  1067. unsigned char* input;
  1068. unsigned char* output;
  1069. size_t available_in;
  1070. size_t available_out;
  1071. const unsigned char* next_in;
  1072. unsigned char* next_out;
  1073. unsigned char* data_begin;
  1074. lzham_decompress_state_ptr s;
  1075. hpatch_dec_error_t decError;
  1076. unsigned char buf[1];
  1077. } _lzham_TDecompress;
  1078. static hpatch_BOOL _lzham_is_can_open(const char* compressType){
  1079. return (0==strcmp(compressType,"lzham"));
  1080. }
  1081. static hpatch_decompressHandle _lzham_open(hpatch_TDecompress* decompressPlugin,
  1082. hpatch_StreamPos_t dataSize,
  1083. const hpatch_TStreamInput* codeStream,
  1084. hpatch_StreamPos_t code_begin,
  1085. hpatch_StreamPos_t code_end){
  1086. const size_t kBufSize=kDecompressBufSize;
  1087. lzham_decompress_params params;
  1088. unsigned char dict_bits;
  1089. _lzham_TDecompress* self=0;
  1090. assert(code_begin<code_end);
  1091. {//load head
  1092. if (code_end-code_begin<1) _dec_openErr_rt();
  1093. if (!codeStream->read(codeStream,code_begin,&dict_bits,(&dict_bits)+1))
  1094. return 0;
  1095. ++code_begin;
  1096. }
  1097. self=(_lzham_TDecompress*)_dec_malloc(sizeof(_lzham_TDecompress)+kBufSize*2);
  1098. if (!self) _dec_memErr_rt();
  1099. memset(self,0,sizeof(_lzham_TDecompress));
  1100. self->codeStream=codeStream;
  1101. self->code_begin=code_begin;
  1102. self->input=self->buf;
  1103. self->output=self->buf+kBufSize;
  1104. self->code_end=code_end;
  1105. self->available_in = 0;
  1106. self->next_in = 0;
  1107. self->available_out = (self->output-self->input);
  1108. self->next_out =self->output;
  1109. self->data_begin=self->output;
  1110. memset(&params, 0, sizeof(params));
  1111. params.m_struct_size = sizeof(params);
  1112. params.m_dict_size_log2 = dict_bits;
  1113. self->s = lzham_decompress_init(&params);
  1114. if (!self->s){ free(self); _dec_openErr_rt(); }
  1115. return self;
  1116. }
  1117. static hpatch_BOOL _lzham_close(struct hpatch_TDecompress* decompressPlugin,
  1118. hpatch_decompressHandle decompressHandle){
  1119. _lzham_TDecompress* self=(_lzham_TDecompress*)decompressHandle;
  1120. if (!self) return hpatch_TRUE;
  1121. _dec_onDecErr_up();
  1122. lzham_decompress_deinit(self->s);
  1123. free(self);
  1124. return hpatch_TRUE;
  1125. }
  1126. static hpatch_BOOL _lzham_decompress_part(hpatch_decompressHandle decompressHandle,
  1127. unsigned char* out_part_data,unsigned char* out_part_data_end){
  1128. _lzham_TDecompress* self=(_lzham_TDecompress*)decompressHandle;
  1129. while (out_part_data<out_part_data_end) {
  1130. size_t dataLen=(self->next_out-self->data_begin);
  1131. if (dataLen>0){
  1132. if (dataLen>(size_t)(out_part_data_end-out_part_data))
  1133. dataLen=(out_part_data_end-out_part_data);
  1134. memcpy(out_part_data,self->data_begin,dataLen);
  1135. out_part_data+=dataLen;
  1136. self->data_begin+=dataLen;
  1137. }else{
  1138. lzham_decompress_status_t ret;
  1139. if (self->available_in==0) {
  1140. self->available_in=(self->output-self->input);
  1141. if (self->available_in>self->code_end-self->code_begin)
  1142. self->available_in=(size_t)(self->code_end-self->code_begin);
  1143. if (self->available_in>0){
  1144. if (!self->codeStream->read(self->codeStream,self->code_begin,(unsigned char*)self->input,
  1145. self->input+self->available_in))
  1146. return hpatch_FALSE;
  1147. self->code_begin+=self->available_in;
  1148. }
  1149. self->next_in=self->input;
  1150. }
  1151. {
  1152. size_t available_in_back=self->available_in;
  1153. self->available_out = (self->output-self->input);
  1154. ret=lzham_decompress(self->s,self->next_in,&self->available_in,
  1155. self->output,&self->available_out,(self->code_begin==self->code_end));
  1156. self->next_out=self->output+self->available_out;
  1157. self->next_in+=self->available_in;
  1158. self->available_in=available_in_back-self->available_in;
  1159. self->available_out=(self->output-self->input) - self->available_out;
  1160. self->data_begin=self->output;
  1161. }
  1162. switch (ret){
  1163. case LZHAM_DECOMP_STATUS_SUCCESS:
  1164. case LZHAM_DECOMP_STATUS_HAS_MORE_OUTPUT:
  1165. case LZHAM_DECOMP_STATUS_NOT_FINISHED: {
  1166. if (self->next_out==self->data_begin) _dec_onDecErr_rt();
  1167. } break;
  1168. case LZHAM_DECOMP_STATUS_NEEDS_MORE_INPUT: {
  1169. if (self->code_end==self->code_begin) _dec_onDecErr_rt();
  1170. } break;
  1171. default:
  1172. _dec_onDecErr_rt();
  1173. }
  1174. }
  1175. }
  1176. return hpatch_TRUE;
  1177. }
  1178. static hpatch_TDecompress lzhamDecompressPlugin={_lzham_is_can_open,_lzham_open,
  1179. _lzham_close,_lzham_decompress_part};
  1180. #endif//_CompressPlugin_lzham
  1181. #ifdef _CompressPlugin_tuz
  1182. #if (_IsNeedIncludeDefaultCompressHead)
  1183. # include "tuz_dec.h" // "tinyuz/decompress/tuz_dec.h" https://github.com/sisong/tinyuz
  1184. #endif
  1185. typedef struct _tuz_TDecompress{
  1186. const struct hpatch_TStreamInput* codeStream;
  1187. hpatch_StreamPos_t code_begin;
  1188. hpatch_StreamPos_t code_end;
  1189. tuz_byte* dec_mem;
  1190. tuz_TStream s;
  1191. hpatch_dec_error_t decError;
  1192. } _tuz_TDecompress;
  1193. static tuz_BOOL _tuz_TDecompress_read_code(tuz_TInputStreamHandle listener,
  1194. tuz_byte* out_code,tuz_size_t* code_size){
  1195. _tuz_TDecompress* self=(_tuz_TDecompress*)listener;
  1196. tuz_size_t r_size=*code_size;
  1197. hpatch_StreamPos_t s_size=self->code_end-self->code_begin;
  1198. if (r_size>s_size){
  1199. r_size=(tuz_size_t)s_size;
  1200. *code_size=r_size;
  1201. }
  1202. if (!self->codeStream->read(self->codeStream,self->code_begin,
  1203. out_code,out_code+r_size)) return tuz_FALSE;
  1204. self->code_begin+=r_size;
  1205. return tuz_TRUE;
  1206. }
  1207. static hpatch_BOOL _tuz_is_can_open(const char* compressType){
  1208. return (0==strcmp(compressType,"tuz"));
  1209. }
  1210. static hpatch_decompressHandle _tuz_open(hpatch_TDecompress* decompressPlugin,
  1211. hpatch_StreamPos_t dataSize,
  1212. const hpatch_TStreamInput* codeStream,
  1213. hpatch_StreamPos_t code_begin,
  1214. hpatch_StreamPos_t code_end){
  1215. tuz_size_t dictSize;
  1216. _tuz_TDecompress* self=0;
  1217. self=(_tuz_TDecompress*)_dec_malloc(sizeof(_tuz_TDecompress));
  1218. if (!self) _dec_memErr_rt();
  1219. self->dec_mem=0;
  1220. self->codeStream=codeStream;
  1221. self->code_begin=code_begin;
  1222. self->code_end=code_end;
  1223. self->decError=hpatch_dec_ok;
  1224. dictSize=tuz_TStream_read_dict_size(self,_tuz_TDecompress_read_code);
  1225. if (((tuz_size_t)(dictSize-1))>=tuz_kMaxOfDictSize) { free(self); _dec_openErr_rt(); }
  1226. self->dec_mem=(tuz_byte*)_dec_malloc(dictSize+kDecompressBufSize);
  1227. if (self->dec_mem==0){ free(self); _dec_memErr_rt(); }
  1228. if (tuz_OK!=tuz_TStream_open(&self->s,self,_tuz_TDecompress_read_code,
  1229. self->dec_mem,dictSize,kDecompressBufSize)){
  1230. free(self->dec_mem); free(self); _dec_openErr_rt(); }
  1231. return self;
  1232. }
  1233. static hpatch_BOOL _tuz_close(struct hpatch_TDecompress* decompressPlugin,
  1234. hpatch_decompressHandle decompressHandle){
  1235. _tuz_TDecompress* self=(_tuz_TDecompress*)decompressHandle;
  1236. if (!self) return hpatch_TRUE;
  1237. _dec_onDecErr_up();
  1238. if (self->dec_mem) free(self->dec_mem);
  1239. free(self);
  1240. return hpatch_TRUE;
  1241. }
  1242. static hpatch_BOOL _tuz_decompress_part(hpatch_decompressHandle decompressHandle,
  1243. unsigned char* out_part_data,unsigned char* out_part_data_end){
  1244. tuz_TResult ret;
  1245. _tuz_TDecompress* self=(_tuz_TDecompress*)decompressHandle;
  1246. size_t out_size=out_part_data_end-out_part_data;
  1247. tuz_size_t data_size=(tuz_size_t)out_size;
  1248. assert(data_size==out_size);
  1249. ret=tuz_TStream_decompress_partial(&self->s,out_part_data,&data_size);
  1250. if (!((ret<=tuz_STREAM_END)&&(data_size==out_size)))
  1251. _dec_onDecErr_rt();
  1252. return hpatch_TRUE;
  1253. }
  1254. static hpatch_TDecompress tuzDecompressPlugin={_tuz_is_can_open,_tuz_open,
  1255. _tuz_close,_tuz_decompress_part};
  1256. #endif//_CompressPlugin_tuz
  1257. #endif