From 8e60956af0ceb5c61ac067df0410141852805fe6 Mon Sep 17 00:00:00 2001 From: sunnylqm Date: Tue, 13 Apr 2021 16:53:32 +0800 Subject: [PATCH] Remove bsdiff in android --- Example/testHotUpdate/package.json | 2 +- android/jni/Android.mk | 8 - android/jni/Application.mk | 2 +- android/jni/DownloadTask.c | 109 -- android/jni/blocksort.c | 1094 ------------ android/jni/bspatch.c | 187 -- android/jni/bspatch.h | 41 - android/jni/bzlib.c | 1573 ----------------- android/jni/bzlib.h | 282 --- android/jni/bzlib_private.h | 509 ------ ..._reactnative_modules_update_DownloadTask.h | 8 - android/jni/compress.c | 672 ------- android/jni/crctable.c | 104 -- android/jni/decompress.c | 646 ------- android/jni/huffman.c | 205 --- android/jni/randtable.c | 84 - android/lib/arm64-v8a/librnupdate.so | Bin 70576 -> 26544 bytes android/lib/armeabi-v7a/librnupdate.so | Bin 49876 -> 30420 bytes android/lib/x86/librnupdate.so | Bin 57908 -> 30260 bytes android/lib/x86_64/librnupdate.so | Bin 66760 -> 35008 bytes .../modules/update/DownloadTask.java | 27 +- .../modules/update/DownloadTaskParams.java | 6 - .../modules/update/UpdateContext.java | 31 +- .../modules/update/UpdateModule.java | 32 +- 24 files changed, 23 insertions(+), 5599 deletions(-) delete mode 100644 android/jni/blocksort.c delete mode 100644 android/jni/bspatch.c delete mode 100644 android/jni/bspatch.h delete mode 100644 android/jni/bzlib.c delete mode 100644 android/jni/bzlib.h delete mode 100644 android/jni/bzlib_private.h delete mode 100644 android/jni/compress.c delete mode 100644 android/jni/crctable.c delete mode 100644 android/jni/decompress.c delete mode 100644 android/jni/huffman.c delete mode 100644 android/jni/randtable.c diff --git a/Example/testHotUpdate/package.json b/Example/testHotUpdate/package.json index 44ac7a7..e25ae3b 100644 --- a/Example/testHotUpdate/package.json +++ b/Example/testHotUpdate/package.json @@ -8,7 +8,7 @@ "start": "react-native start", "test": "jest", "lint": "eslint .", - "apk": "(npx jetify && cd android && ./gradlew aR)" + "apk": "(cd android && ./gradlew aR)" }, "dependencies": { "react": "17.0.1", diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 9970cd6..acb8996 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -13,14 +13,6 @@ Hdp_Files := \ LOCAL_SRC_FILES := \ DownloadTask.c \ - blocksort.c \ - bspatch.c \ - bzlib.c \ - crctable.c \ - compress.c \ - decompress.c \ - huffman.c \ - randtable.c \ $(Hdp_Files) include $(BUILD_SHARED_LIBRARY) \ No newline at end of file diff --git a/android/jni/Application.mk b/android/jni/Application.mk index f28e446..3c3e329 100644 --- a/android/jni/Application.mk +++ b/android/jni/Application.mk @@ -1,4 +1,4 @@ -APP_PLATFORM := android-14 +APP_PLATFORM := android-16 APP_CFLAGS += -Wno-error=format-security APP_CFLAGS += -fvisibility=hidden -fvisibility-inlines-hidden APP_CFLAGS += -ffunction-sections -fdata-sections diff --git a/android/jni/DownloadTask.c b/android/jni/DownloadTask.c index 562714f..a8a7f1f 100644 --- a/android/jni/DownloadTask.c +++ b/android/jni/DownloadTask.c @@ -3,117 +3,8 @@ // #include "cn_reactnative_modules_update_DownloadTask.h" -#include -#include "bzlib.h" -#include "bspatch.h" -#include //for memcmp -#include #include "hpatch.h" - -static int64_t offtin(uint8_t *buf) -{ - int64_t y; - - y=buf[7]&0x7F; - y=y*256;y+=buf[6]; - y=y*256;y+=buf[5]; - y=y*256;y+=buf[4]; - y=y*256;y+=buf[3]; - y=y*256;y+=buf[2]; - y=y*256;y+=buf[1]; - y=y*256;y+=buf[0]; - - if(buf[7]&0x80) y=-y; - - return y; -} - -const size_t BUFFER_SIZE = 4096; - -static int bz2_read(const struct bspatch_stream* stream, void* buffer, int length) -{ - int n; - int bz2err; - bz_stream* zip; - - if (length == 0) { - return 0; - } - - zip = (bz_stream*)stream->opaque; - zip->next_out = (char*)buffer; - zip->avail_out = length; - - int bz2Ret = BZ2_bzDecompress(zip); - - if (bz2Ret != BZ_OK && (bz2Ret != BZ_STREAM_END || zip->avail_out > 0)) - return -1; - - return 0; -} - -JNIEXPORT jbyteArray JNICALL Java_cn_reactnative_modules_update_DownloadTask_bsdiffPatch - (JNIEnv *env, jobject self, jbyteArray origin, jbyteArray patch){ - jclass newExcCls; - jbyte* outPtr; - struct bspatch_stream stream; - bz_stream zip; - - jbyte* originPtr = (*env)->GetByteArrayElements(env, origin, NULL); - size_t originLength = (*env)->GetArrayLength(env, origin); - jbyte* patchPtr = (*env)->GetByteArrayElements(env, patch, NULL); - size_t patchLength = (*env)->GetArrayLength(env, patch); - jbyteArray ret = NULL; - - if (patchLength < 32) { - newExcCls = (*env)->FindClass(env,"java/lang/Error"); - if (newExcCls != NULL) /* Unable to find the new exception class, give up. */ - (*env)->ThrowNew(env,newExcCls, "Corrupt patch"); - (*env)->ReleaseByteArrayElements(env, origin, originPtr, JNI_ABORT); - (*env)->ReleaseByteArrayElements(env, patch, patchPtr, JNI_ABORT); - return NULL; - } - int64_t newsize=offtin((uint8_t*)patchPtr + 16); - if (memcmp(patchPtr, "ENDSLEY/BSDIFF43", 16) != 0 || newsize<0) { - newExcCls = (*env)->FindClass(env, "java/lang/Error"); - if (newExcCls != NULL) /* Unable to find the new exception class, give up. */ - (*env)->ThrowNew(env, newExcCls, "Corrupt patch"); - (*env)->ReleaseByteArrayElements(env, origin, originPtr, JNI_ABORT); - (*env)->ReleaseByteArrayElements(env, patch, patchPtr, JNI_ABORT); - return NULL; - } - ret = (*env)->NewByteArray(env, newsize); - if (ret == NULL) { - return NULL; // out of memory error thrown - } - outPtr = (*env)->GetByteArrayElements(env, ret, NULL); - - zip.bzalloc = NULL; - zip.bzfree = NULL; - zip.opaque = NULL; - BZ2_bzDecompressInit(&zip, 0, 1); - - zip.next_in = (char*)patchPtr + 32; - zip.avail_in = patchLength - 32; - - stream.read = bz2_read; - stream.opaque = &zip; - if (bspatch((const uint8_t*)originPtr, originLength, (uint8_t*)outPtr, newsize, &stream)) { - newExcCls = (*env)->FindClass(env, "java/lang/Error"); - if (newExcCls != NULL) /* Unable to find the new exception class, give up. */ - (*env)->ThrowNew(env, newExcCls, "bspatch"); - } - - BZ2_bzDecompressEnd(&zip); - - (*env)->ReleaseByteArrayElements(env, ret, outPtr, 0); - (*env)->ReleaseByteArrayElements(env, origin, originPtr, JNI_ABORT); - (*env)->ReleaseByteArrayElements(env, patch, patchPtr, JNI_ABORT); - return ret; -} - - #define _check(v,errInfo) do{ if (!(v)) { _isError=hpatch_TRUE; _errInfo=errInfo; goto _clear; } }while(0) JNIEXPORT jbyteArray JNICALL Java_cn_reactnative_modules_update_DownloadTask_hdiffPatch diff --git a/android/jni/blocksort.c b/android/jni/blocksort.c deleted file mode 100644 index d0d662c..0000000 --- a/android/jni/blocksort.c +++ /dev/null @@ -1,1094 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Block sorting machinery ---*/ -/*--- blocksort.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - -/*---------------------------------------------*/ -/*--- Fallback O(N log(N)^2) sorting ---*/ -/*--- algorithm, for repetitive blocks ---*/ -/*---------------------------------------------*/ - -/*---------------------------------------------*/ -static -__inline__ -void fallbackSimpleSort ( UInt32* fmap, - UInt32* eclass, - Int32 lo, - Int32 hi ) -{ - Int32 i, j, tmp; - UInt32 ec_tmp; - - if (lo == hi) return; - - if (hi - lo > 3) { - for ( i = hi-4; i >= lo; i-- ) { - tmp = fmap[i]; - ec_tmp = eclass[tmp]; - for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 ) - fmap[j-4] = fmap[j]; - fmap[j-4] = tmp; - } - } - - for ( i = hi-1; i >= lo; i-- ) { - tmp = fmap[i]; - ec_tmp = eclass[tmp]; - for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ ) - fmap[j-1] = fmap[j]; - fmap[j-1] = tmp; - } -} - - -/*---------------------------------------------*/ -#define fswap(zz1, zz2) \ - { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } - -#define fvswap(zzp1, zzp2, zzn) \ -{ \ - Int32 yyp1 = (zzp1); \ - Int32 yyp2 = (zzp2); \ - Int32 yyn = (zzn); \ - while (yyn > 0) { \ - fswap(fmap[yyp1], fmap[yyp2]); \ - yyp1++; yyp2++; yyn--; \ - } \ -} - - -#define fmin(a,b) ((a) < (b)) ? (a) : (b) - -#define fpush(lz,hz) { stackLo[sp] = lz; \ - stackHi[sp] = hz; \ - sp++; } - -#define fpop(lz,hz) { sp--; \ - lz = stackLo[sp]; \ - hz = stackHi[sp]; } - -#define FALLBACK_QSORT_SMALL_THRESH 10 -#define FALLBACK_QSORT_STACK_SIZE 100 - - -static -void fallbackQSort3 ( UInt32* fmap, - UInt32* eclass, - Int32 loSt, - Int32 hiSt ) -{ - Int32 unLo, unHi, ltLo, gtHi, n, m; - Int32 sp, lo, hi; - UInt32 med, r, r3; - Int32 stackLo[FALLBACK_QSORT_STACK_SIZE]; - Int32 stackHi[FALLBACK_QSORT_STACK_SIZE]; - - r = 0; - - sp = 0; - fpush ( loSt, hiSt ); - - while (sp > 0) { - - AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 ); - - fpop ( lo, hi ); - if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) { - fallbackSimpleSort ( fmap, eclass, lo, hi ); - continue; - } - - /* Random partitioning. Median of 3 sometimes fails to - avoid bad cases. Median of 9 seems to help but - looks rather expensive. This too seems to work but - is cheaper. Guidance for the magic constants - 7621 and 32768 is taken from Sedgewick's algorithms - book, chapter 35. - */ - r = ((r * 7621) + 1) % 32768; - r3 = r % 3; - if (r3 == 0) med = eclass[fmap[lo]]; else - if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else - med = eclass[fmap[hi]]; - - unLo = ltLo = lo; - unHi = gtHi = hi; - - while (1) { - while (1) { - if (unLo > unHi) break; - n = (Int32)eclass[fmap[unLo]] - (Int32)med; - if (n == 0) { - fswap(fmap[unLo], fmap[ltLo]); - ltLo++; unLo++; - continue; - }; - if (n > 0) break; - unLo++; - } - while (1) { - if (unLo > unHi) break; - n = (Int32)eclass[fmap[unHi]] - (Int32)med; - if (n == 0) { - fswap(fmap[unHi], fmap[gtHi]); - gtHi--; unHi--; - continue; - }; - if (n < 0) break; - unHi--; - } - if (unLo > unHi) break; - fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--; - } - - AssertD ( unHi == unLo-1, "fallbackQSort3(2)" ); - - if (gtHi < ltLo) continue; - - n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n); - m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m); - - n = lo + unLo - ltLo - 1; - m = hi - (gtHi - unHi) + 1; - - if (n - lo > hi - m) { - fpush ( lo, n ); - fpush ( m, hi ); - } else { - fpush ( m, hi ); - fpush ( lo, n ); - } - } -} - -#undef fmin -#undef fpush -#undef fpop -#undef fswap -#undef fvswap -#undef FALLBACK_QSORT_SMALL_THRESH -#undef FALLBACK_QSORT_STACK_SIZE - - -/*---------------------------------------------*/ -/* Pre: - nblock > 0 - eclass exists for [0 .. nblock-1] - ((UChar*)eclass) [0 .. nblock-1] holds block - ptr exists for [0 .. nblock-1] - - Post: - ((UChar*)eclass) [0 .. nblock-1] holds block - All other areas of eclass destroyed - fmap [0 .. nblock-1] holds sorted order - bhtab [ 0 .. 2+(nblock/32) ] destroyed -*/ - -#define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31)) -#define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31)) -#define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31))) -#define WORD_BH(zz) bhtab[(zz) >> 5] -#define UNALIGNED_BH(zz) ((zz) & 0x01f) - -static -void fallbackSort ( UInt32* fmap, - UInt32* eclass, - UInt32* bhtab, - Int32 nblock, - Int32 verb ) -{ - Int32 ftab[257]; - Int32 ftabCopy[256]; - Int32 H, i, j, k, l, r, cc, cc1; - Int32 nNotDone; - Int32 nBhtab; - UChar* eclass8 = (UChar*)eclass; - - /*-- - Initial 1-char radix sort to generate - initial fmap and initial BH bits. - --*/ - if (verb >= 4) - VPrintf0 ( " bucket sorting ...\n" ); - for (i = 0; i < 257; i++) ftab[i] = 0; - for (i = 0; i < nblock; i++) ftab[eclass8[i]]++; - for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i]; - for (i = 1; i < 257; i++) ftab[i] += ftab[i-1]; - - for (i = 0; i < nblock; i++) { - j = eclass8[i]; - k = ftab[j] - 1; - ftab[j] = k; - fmap[k] = i; - } - - nBhtab = 2 + (nblock / 32); - for (i = 0; i < nBhtab; i++) bhtab[i] = 0; - for (i = 0; i < 256; i++) SET_BH(ftab[i]); - - /*-- - Inductively refine the buckets. Kind-of an - "exponential radix sort" (!), inspired by the - Manber-Myers suffix array construction algorithm. - --*/ - - /*-- set sentinel bits for block-end detection --*/ - for (i = 0; i < 32; i++) { - SET_BH(nblock + 2*i); - CLEAR_BH(nblock + 2*i + 1); - } - - /*-- the log(N) loop --*/ - H = 1; - while (1) { - - if (verb >= 4) - VPrintf1 ( " depth %6d has ", H ); - - j = 0; - for (i = 0; i < nblock; i++) { - if (ISSET_BH(i)) j = i; - k = fmap[i] - H; if (k < 0) k += nblock; - eclass[k] = j; - } - - nNotDone = 0; - r = -1; - while (1) { - - /*-- find the next non-singleton bucket --*/ - k = r + 1; - while (ISSET_BH(k) && UNALIGNED_BH(k)) k++; - if (ISSET_BH(k)) { - while (WORD_BH(k) == 0xffffffff) k += 32; - while (ISSET_BH(k)) k++; - } - l = k - 1; - if (l >= nblock) break; - while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++; - if (!ISSET_BH(k)) { - while (WORD_BH(k) == 0x00000000) k += 32; - while (!ISSET_BH(k)) k++; - } - r = k - 1; - if (r >= nblock) break; - - /*-- now [l, r] bracket current bucket --*/ - if (r > l) { - nNotDone += (r - l + 1); - fallbackQSort3 ( fmap, eclass, l, r ); - - /*-- scan bucket and generate header bits-- */ - cc = -1; - for (i = l; i <= r; i++) { - cc1 = eclass[fmap[i]]; - if (cc != cc1) { SET_BH(i); cc = cc1; }; - } - } - } - - if (verb >= 4) - VPrintf1 ( "%6d unresolved strings\n", nNotDone ); - - H *= 2; - if (H > nblock || nNotDone == 0) break; - } - - /*-- - Reconstruct the original block in - eclass8 [0 .. nblock-1], since the - previous phase destroyed it. - --*/ - if (verb >= 4) - VPrintf0 ( " reconstructing block ...\n" ); - j = 0; - for (i = 0; i < nblock; i++) { - while (ftabCopy[j] == 0) j++; - ftabCopy[j]--; - eclass8[fmap[i]] = (UChar)j; - } - AssertH ( j < 256, 1005 ); -} - -#undef SET_BH -#undef CLEAR_BH -#undef ISSET_BH -#undef WORD_BH -#undef UNALIGNED_BH - - -/*---------------------------------------------*/ -/*--- The main, O(N^2 log(N)) sorting ---*/ -/*--- algorithm. Faster for "normal" ---*/ -/*--- non-repetitive blocks. ---*/ -/*---------------------------------------------*/ - -/*---------------------------------------------*/ -static -__inline__ -Bool mainGtU ( UInt32 i1, - UInt32 i2, - UChar* block, - UInt16* quadrant, - UInt32 nblock, - Int32* budget ) -{ - Int32 k; - UChar c1, c2; - UInt16 s1, s2; - - AssertD ( i1 != i2, "mainGtU" ); - /* 1 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 2 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 3 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 4 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 5 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 6 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 7 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 8 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 9 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 10 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 11 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 12 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - - k = nblock + 8; - - do { - /* 1 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 2 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 3 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 4 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 5 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 6 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 7 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 8 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - - if (i1 >= nblock) i1 -= nblock; - if (i2 >= nblock) i2 -= nblock; - - k -= 8; - (*budget)--; - } - while (k >= 0); - - return False; -} - - -/*---------------------------------------------*/ -/*-- - Knuth's increments seem to work better - than Incerpi-Sedgewick here. Possibly - because the number of elems to sort is - usually small, typically <= 20. ---*/ -static -Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280, - 9841, 29524, 88573, 265720, - 797161, 2391484 }; - -static -void mainSimpleSort ( UInt32* ptr, - UChar* block, - UInt16* quadrant, - Int32 nblock, - Int32 lo, - Int32 hi, - Int32 d, - Int32* budget ) -{ - Int32 i, j, h, bigN, hp; - UInt32 v; - - bigN = hi - lo + 1; - if (bigN < 2) return; - - hp = 0; - while (incs[hp] < bigN) hp++; - hp--; - - for (; hp >= 0; hp--) { - h = incs[hp]; - - i = lo + h; - while (True) { - - /*-- copy 1 --*/ - if (i > hi) break; - v = ptr[i]; - j = i; - while ( mainGtU ( - ptr[j-h]+d, v+d, block, quadrant, nblock, budget - ) ) { - ptr[j] = ptr[j-h]; - j = j - h; - if (j <= (lo + h - 1)) break; - } - ptr[j] = v; - i++; - - /*-- copy 2 --*/ - if (i > hi) break; - v = ptr[i]; - j = i; - while ( mainGtU ( - ptr[j-h]+d, v+d, block, quadrant, nblock, budget - ) ) { - ptr[j] = ptr[j-h]; - j = j - h; - if (j <= (lo + h - 1)) break; - } - ptr[j] = v; - i++; - - /*-- copy 3 --*/ - if (i > hi) break; - v = ptr[i]; - j = i; - while ( mainGtU ( - ptr[j-h]+d, v+d, block, quadrant, nblock, budget - ) ) { - ptr[j] = ptr[j-h]; - j = j - h; - if (j <= (lo + h - 1)) break; - } - ptr[j] = v; - i++; - - if (*budget < 0) return; - } - } -} - - -/*---------------------------------------------*/ -/*-- - The following is an implementation of - an elegant 3-way quicksort for strings, - described in a paper "Fast Algorithms for - Sorting and Searching Strings", by Robert - Sedgewick and Jon L. Bentley. ---*/ - -#define mswap(zz1, zz2) \ - { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } - -#define mvswap(zzp1, zzp2, zzn) \ -{ \ - Int32 yyp1 = (zzp1); \ - Int32 yyp2 = (zzp2); \ - Int32 yyn = (zzn); \ - while (yyn > 0) { \ - mswap(ptr[yyp1], ptr[yyp2]); \ - yyp1++; yyp2++; yyn--; \ - } \ -} - -static -__inline__ -UChar mmed3 ( UChar a, UChar b, UChar c ) -{ - UChar t; - if (a > b) { t = a; a = b; b = t; }; - if (b > c) { - b = c; - if (a > b) b = a; - } - return b; -} - -#define mmin(a,b) ((a) < (b)) ? (a) : (b) - -#define mpush(lz,hz,dz) { stackLo[sp] = lz; \ - stackHi[sp] = hz; \ - stackD [sp] = dz; \ - sp++; } - -#define mpop(lz,hz,dz) { sp--; \ - lz = stackLo[sp]; \ - hz = stackHi[sp]; \ - dz = stackD [sp]; } - - -#define mnextsize(az) (nextHi[az]-nextLo[az]) - -#define mnextswap(az,bz) \ - { Int32 tz; \ - tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \ - tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \ - tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; } - - -#define MAIN_QSORT_SMALL_THRESH 20 -#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT) -#define MAIN_QSORT_STACK_SIZE 100 - -static -void mainQSort3 ( UInt32* ptr, - UChar* block, - UInt16* quadrant, - Int32 nblock, - Int32 loSt, - Int32 hiSt, - Int32 dSt, - Int32* budget ) -{ - Int32 unLo, unHi, ltLo, gtHi, n, m, med; - Int32 sp, lo, hi, d; - - Int32 stackLo[MAIN_QSORT_STACK_SIZE]; - Int32 stackHi[MAIN_QSORT_STACK_SIZE]; - Int32 stackD [MAIN_QSORT_STACK_SIZE]; - - Int32 nextLo[3]; - Int32 nextHi[3]; - Int32 nextD [3]; - - sp = 0; - mpush ( loSt, hiSt, dSt ); - - while (sp > 0) { - - AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 ); - - mpop ( lo, hi, d ); - if (hi - lo < MAIN_QSORT_SMALL_THRESH || - d > MAIN_QSORT_DEPTH_THRESH) { - mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget ); - if (*budget < 0) return; - continue; - } - - med = (Int32) - mmed3 ( block[ptr[ lo ]+d], - block[ptr[ hi ]+d], - block[ptr[ (lo+hi)>>1 ]+d] ); - - unLo = ltLo = lo; - unHi = gtHi = hi; - - while (True) { - while (True) { - if (unLo > unHi) break; - n = ((Int32)block[ptr[unLo]+d]) - med; - if (n == 0) { - mswap(ptr[unLo], ptr[ltLo]); - ltLo++; unLo++; continue; - }; - if (n > 0) break; - unLo++; - } - while (True) { - if (unLo > unHi) break; - n = ((Int32)block[ptr[unHi]+d]) - med; - if (n == 0) { - mswap(ptr[unHi], ptr[gtHi]); - gtHi--; unHi--; continue; - }; - if (n < 0) break; - unHi--; - } - if (unLo > unHi) break; - mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--; - } - - AssertD ( unHi == unLo-1, "mainQSort3(2)" ); - - if (gtHi < ltLo) { - mpush(lo, hi, d+1 ); - continue; - } - - n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n); - m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m); - - n = lo + unLo - ltLo - 1; - m = hi - (gtHi - unHi) + 1; - - nextLo[0] = lo; nextHi[0] = n; nextD[0] = d; - nextLo[1] = m; nextHi[1] = hi; nextD[1] = d; - nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1; - - if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); - if (mnextsize(1) < mnextsize(2)) mnextswap(1,2); - if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); - - AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" ); - AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" ); - - mpush (nextLo[0], nextHi[0], nextD[0]); - mpush (nextLo[1], nextHi[1], nextD[1]); - mpush (nextLo[2], nextHi[2], nextD[2]); - } -} - -#undef mswap -#undef mvswap -#undef mpush -#undef mpop -#undef mmin -#undef mnextsize -#undef mnextswap -#undef MAIN_QSORT_SMALL_THRESH -#undef MAIN_QSORT_DEPTH_THRESH -#undef MAIN_QSORT_STACK_SIZE - - -/*---------------------------------------------*/ -/* Pre: - nblock > N_OVERSHOOT - block32 exists for [0 .. nblock-1 +N_OVERSHOOT] - ((UChar*)block32) [0 .. nblock-1] holds block - ptr exists for [0 .. nblock-1] - - Post: - ((UChar*)block32) [0 .. nblock-1] holds block - All other areas of block32 destroyed - ftab [0 .. 65536 ] destroyed - ptr [0 .. nblock-1] holds sorted order - if (*budget < 0), sorting was abandoned -*/ - -#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8]) -#define SETMASK (1 << 21) -#define CLEARMASK (~(SETMASK)) - -static -void mainSort ( UInt32* ptr, - UChar* block, - UInt16* quadrant, - UInt32* ftab, - Int32 nblock, - Int32 verb, - Int32* budget ) -{ - Int32 i, j, k, ss, sb; - Int32 runningOrder[256]; - Bool bigDone[256]; - Int32 copyStart[256]; - Int32 copyEnd [256]; - UChar c1; - Int32 numQSorted; - UInt16 s; - if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" ); - - /*-- set up the 2-byte frequency table --*/ - for (i = 65536; i >= 0; i--) ftab[i] = 0; - - j = block[0] << 8; - i = nblock-1; - for (; i >= 3; i -= 4) { - quadrant[i] = 0; - j = (j >> 8) | ( ((UInt16)block[i]) << 8); - ftab[j]++; - quadrant[i-1] = 0; - j = (j >> 8) | ( ((UInt16)block[i-1]) << 8); - ftab[j]++; - quadrant[i-2] = 0; - j = (j >> 8) | ( ((UInt16)block[i-2]) << 8); - ftab[j]++; - quadrant[i-3] = 0; - j = (j >> 8) | ( ((UInt16)block[i-3]) << 8); - ftab[j]++; - } - for (; i >= 0; i--) { - quadrant[i] = 0; - j = (j >> 8) | ( ((UInt16)block[i]) << 8); - ftab[j]++; - } - - /*-- (emphasises close relationship of block & quadrant) --*/ - for (i = 0; i < BZ_N_OVERSHOOT; i++) { - block [nblock+i] = block[i]; - quadrant[nblock+i] = 0; - } - - if (verb >= 4) VPrintf0 ( " bucket sorting ...\n" ); - - /*-- Complete the initial radix sort --*/ - for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1]; - - s = block[0] << 8; - i = nblock-1; - for (; i >= 3; i -= 4) { - s = (s >> 8) | (block[i] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i; - s = (s >> 8) | (block[i-1] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i-1; - s = (s >> 8) | (block[i-2] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i-2; - s = (s >> 8) | (block[i-3] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i-3; - } - for (; i >= 0; i--) { - s = (s >> 8) | (block[i] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i; - } - - /*-- - Now ftab contains the first loc of every small bucket. - Calculate the running order, from smallest to largest - big bucket. - --*/ - for (i = 0; i <= 255; i++) { - bigDone [i] = False; - runningOrder[i] = i; - } - - { - Int32 vv; - Int32 h = 1; - do h = 3 * h + 1; while (h <= 256); - do { - h = h / 3; - for (i = h; i <= 255; i++) { - vv = runningOrder[i]; - j = i; - while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) { - runningOrder[j] = runningOrder[j-h]; - j = j - h; - if (j <= (h - 1)) goto zero; - } - zero: - runningOrder[j] = vv; - } - } while (h != 1); - } - - /*-- - The main sorting loop. - --*/ - - numQSorted = 0; - - for (i = 0; i <= 255; i++) { - - /*-- - Process big buckets, starting with the least full. - Basically this is a 3-step process in which we call - mainQSort3 to sort the small buckets [ss, j], but - also make a big effort to avoid the calls if we can. - --*/ - ss = runningOrder[i]; - - /*-- - Step 1: - Complete the big bucket [ss] by quicksorting - any unsorted small buckets [ss, j], for j != ss. - Hopefully previous pointer-scanning phases have already - completed many of the small buckets [ss, j], so - we don't have to sort them at all. - --*/ - for (j = 0; j <= 255; j++) { - if (j != ss) { - sb = (ss << 8) + j; - if ( ! (ftab[sb] & SETMASK) ) { - Int32 lo = ftab[sb] & CLEARMASK; - Int32 hi = (ftab[sb+1] & CLEARMASK) - 1; - if (hi > lo) { - if (verb >= 4) - VPrintf4 ( " qsort [0x%x, 0x%x] " - "done %d this %d\n", - ss, j, numQSorted, hi - lo + 1 ); - mainQSort3 ( - ptr, block, quadrant, nblock, - lo, hi, BZ_N_RADIX, budget - ); - numQSorted += (hi - lo + 1); - if (*budget < 0) return; - } - } - ftab[sb] |= SETMASK; - } - } - - AssertH ( !bigDone[ss], 1006 ); - - /*-- - Step 2: - Now scan this big bucket [ss] so as to synthesise the - sorted order for small buckets [t, ss] for all t, - including, magically, the bucket [ss,ss] too. - This will avoid doing Real Work in subsequent Step 1's. - --*/ - { - for (j = 0; j <= 255; j++) { - copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK; - copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1; - } - for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) { - k = ptr[j]-1; if (k < 0) k += nblock; - c1 = block[k]; - if (!bigDone[c1]) - ptr[ copyStart[c1]++ ] = k; - } - for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) { - k = ptr[j]-1; if (k < 0) k += nblock; - c1 = block[k]; - if (!bigDone[c1]) - ptr[ copyEnd[c1]-- ] = k; - } - } - - AssertH ( (copyStart[ss]-1 == copyEnd[ss]) - || - /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1. - Necessity for this case is demonstrated by compressing - a sequence of approximately 48.5 million of character - 251; 1.0.0/1.0.1 will then die here. */ - (copyStart[ss] == 0 && copyEnd[ss] == nblock-1), - 1007 ) - - for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK; - - /*-- - Step 3: - The [ss] big bucket is now done. Record this fact, - and update the quadrant descriptors. Remember to - update quadrants in the overshoot area too, if - necessary. The "if (i < 255)" test merely skips - this updating for the last bucket processed, since - updating for the last bucket is pointless. - - The quadrant array provides a way to incrementally - cache sort orderings, as they appear, so as to - make subsequent comparisons in fullGtU() complete - faster. For repetitive blocks this makes a big - difference (but not big enough to be able to avoid - the fallback sorting mechanism, exponential radix sort). - - The precise meaning is: at all times: - - for 0 <= i < nblock and 0 <= j <= nblock - - if block[i] != block[j], - - then the relative values of quadrant[i] and - quadrant[j] are meaningless. - - else { - if quadrant[i] < quadrant[j] - then the string starting at i lexicographically - precedes the string starting at j - - else if quadrant[i] > quadrant[j] - then the string starting at j lexicographically - precedes the string starting at i - - else - the relative ordering of the strings starting - at i and j has not yet been determined. - } - --*/ - bigDone[ss] = True; - - if (i < 255) { - Int32 bbStart = ftab[ss << 8] & CLEARMASK; - Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart; - Int32 shifts = 0; - - while ((bbSize >> shifts) > 65534) shifts++; - - for (j = bbSize-1; j >= 0; j--) { - Int32 a2update = ptr[bbStart + j]; - UInt16 qVal = (UInt16)(j >> shifts); - quadrant[a2update] = qVal; - if (a2update < BZ_N_OVERSHOOT) - quadrant[a2update + nblock] = qVal; - } - AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 ); - } - - } - - if (verb >= 4) - VPrintf3 ( " %d pointers, %d sorted, %d scanned\n", - nblock, numQSorted, nblock - numQSorted ); -} - -#undef BIGFREQ -#undef SETMASK -#undef CLEARMASK - - -/*---------------------------------------------*/ -/* Pre: - nblock > 0 - arr2 exists for [0 .. nblock-1 +N_OVERSHOOT] - ((UChar*)arr2) [0 .. nblock-1] holds block - arr1 exists for [0 .. nblock-1] - - Post: - ((UChar*)arr2) [0 .. nblock-1] holds block - All other areas of block destroyed - ftab [ 0 .. 65536 ] destroyed - arr1 [0 .. nblock-1] holds sorted order -*/ -void BZ2_blockSort ( EState* s ) -{ - UInt32* ptr = s->ptr; - UChar* block = s->block; - UInt32* ftab = s->ftab; - Int32 nblock = s->nblock; - Int32 verb = s->verbosity; - Int32 wfact = s->workFactor; - UInt16* quadrant; - Int32 budget; - Int32 budgetInit; - Int32 i; - - if (nblock < 10000) { - fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb ); - } else { - /* Calculate the location for quadrant, remembering to get - the alignment right. Assumes that &(block[0]) is at least - 2-byte aligned -- this should be ok since block is really - the first section of arr2. - */ - i = nblock+BZ_N_OVERSHOOT; - if (i & 1) i++; - quadrant = (UInt16*)(&(block[i])); - - /* (wfact-1) / 3 puts the default-factor-30 - transition point at very roughly the same place as - with v0.1 and v0.9.0. - Not that it particularly matters any more, since the - resulting compressed stream is now the same regardless - of whether or not we use the main sort or fallback sort. - */ - if (wfact < 1 ) wfact = 1; - if (wfact > 100) wfact = 100; - budgetInit = nblock * ((wfact-1) / 3); - budget = budgetInit; - - mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget ); - if (verb >= 3) - VPrintf3 ( " %d work, %d block, ratio %5.2f\n", - budgetInit - budget, - nblock, - (float)(budgetInit - budget) / - (float)(nblock==0 ? 1 : nblock) ); - if (budget < 0) { - if (verb >= 2) - VPrintf0 ( " too repetitive; using fallback" - " sorting algorithm\n" ); - fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb ); - } - } - - s->origPtr = -1; - for (i = 0; i < s->nblock; i++) - if (ptr[i] == 0) - { s->origPtr = i; break; }; - - AssertH( s->origPtr != -1, 1003 ); -} - - -/*-------------------------------------------------------------*/ -/*--- end blocksort.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/android/jni/bspatch.c b/android/jni/bspatch.c deleted file mode 100644 index b29f81d..0000000 --- a/android/jni/bspatch.c +++ /dev/null @@ -1,187 +0,0 @@ -/*- - * Copyright 2003-2005 Colin Percival - * Copyright 2012 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "bspatch.h" - -static int64_t offtin(uint8_t *buf) -{ - int64_t y; - - y=buf[7]&0x7F; - y=y*256;y+=buf[6]; - y=y*256;y+=buf[5]; - y=y*256;y+=buf[4]; - y=y*256;y+=buf[3]; - y=y*256;y+=buf[2]; - y=y*256;y+=buf[1]; - y=y*256;y+=buf[0]; - - if(buf[7]&0x80) y=-y; - - return y; -} - -int bspatch(const uint8_t* old, int64_t oldsize, uint8_t* new, int64_t newsize, struct bspatch_stream* stream) -{ - uint8_t buf[8]; - int64_t oldpos,newpos; - int64_t ctrl[3]; - int64_t i; - - oldpos=0;newpos=0; - while(newposread(stream, buf, 8)) - return -1; - ctrl[i]=offtin(buf); - }; - - /* Sanity-check */ - if(newpos+ctrl[0]>newsize) - return -1; - - /* Read diff string */ - if (stream->read(stream, new + newpos, ctrl[0])) - return -1; - - /* Add old data to diff string */ - for(i=0;i=0) && (oldpos+inewsize) - return -1; - - /* Read extra string */ - if (stream->read(stream, new + newpos, ctrl[1])) - return -1; - - /* Adjust pointers */ - newpos+=ctrl[1]; - oldpos+=ctrl[2]; - }; - - return 0; -} - -#if defined(BSPATCH_EXECUTABLE) - -#include -#include -#include -#include -#include -#include -#include -#include - -static int bz2_read(const struct bspatch_stream* stream, void* buffer, int length) -{ - int n; - int bz2err; - BZFILE* bz2; - - bz2 = (BZFILE*)stream->opaque; - n = BZ2_bzRead(&bz2err, bz2, buffer, length); - if (n != length) - return -1; - - return 0; -} - -int main(int argc,char * argv[]) -{ - FILE * f; - int fd; - int bz2err; - uint8_t header[24]; - uint8_t *old, *new; - int64_t oldsize, newsize; - BZFILE* bz2; - struct bspatch_stream stream; - - if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]); - - /* Open patch file */ - if ((f = fopen(argv[3], "r")) == NULL) - err(1, "fopen(%s)", argv[3]); - - /* Read header */ - if (fread(header, 1, 24, f) != 24) { - if (feof(f)) - errx(1, "Corrupt patch\n"); - err(1, "fread(%s)", argv[3]); - } - - /* Check for appropriate magic */ - if (memcmp(header, "ENDSLEY/BSDIFF43", 16) != 0) - errx(1, "Corrupt patch\n"); - - /* Read lengths from header */ - newsize=offtin(header+16); - if(newsize<0) - errx(1,"Corrupt patch\n"); - - /* Close patch file and re-open it via libbzip2 at the right places */ - if(((fd=open(argv[1],O_RDONLY,0))<0) || - ((oldsize=lseek(fd,0,SEEK_END))==-1) || - ((old=malloc(oldsize+1))==NULL) || - (lseek(fd,0,SEEK_SET)!=0) || - (read(fd,old,oldsize)!=oldsize) || - (close(fd)==-1)) err(1,"%s",argv[1]); - if((new=malloc(newsize+1))==NULL) err(1,NULL); - - if (NULL == (bz2 = BZ2_bzReadOpen(&bz2err, f, 0, 0, NULL, 0))) - errx(1, "BZ2_bzReadOpen, bz2err=%d", bz2err); - - stream.read = bz2_read; - stream.opaque = bz2; - if (bspatch(old, oldsize, new, newsize, &stream)) - errx(1, "bspatch"); - - /* Clean up the bzip2 reads */ - BZ2_bzReadClose(&bz2err, bz2); - fclose(f); - - /* Write the new file */ - if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) || - (write(fd,new,newsize)!=newsize) || (close(fd)==-1)) - err(1,"%s",argv[2]); - - free(new); - free(old); - - return 0; -} - -#endif \ No newline at end of file diff --git a/android/jni/bspatch.h b/android/jni/bspatch.h deleted file mode 100644 index 08e78bd..0000000 --- a/android/jni/bspatch.h +++ /dev/null @@ -1,41 +0,0 @@ -/*- - * Copyright 2003-2005 Colin Percival - * Copyright 2012 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BSPATCH_H -# define BSPATCH_H - -# include - -struct bspatch_stream -{ - void* opaque; - int (*read)(const struct bspatch_stream* stream, void* buffer, int length); -}; - -int bspatch(const uint8_t* old, int64_t oldsize, uint8_t* newBuf, int64_t newsize, struct bspatch_stream* stream); - -#endif \ No newline at end of file diff --git a/android/jni/bzlib.c b/android/jni/bzlib.c deleted file mode 100644 index cf33558..0000000 --- a/android/jni/bzlib.c +++ /dev/null @@ -1,1573 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Library top-level functions. ---*/ -/*--- bzlib.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - -/* CHANGES - 0.9.0 -- original version. - 0.9.0a/b -- no changes in this file. - 0.9.0c -- made zero-length BZ_FLUSH work correctly in bzCompress(). - fixed bzWrite/bzRead to ignore zero-length requests. - fixed bzread to correctly handle read requests after EOF. - wrong parameter order in call to bzDecompressInit in - bzBuffToBuffDecompress. Fixed. -*/ - -#include "bzlib_private.h" - - -/*---------------------------------------------------*/ -/*--- Compression stuff ---*/ -/*---------------------------------------------------*/ - - -/*---------------------------------------------------*/ -#ifndef BZ_NO_STDIO -void BZ2_bz__AssertH__fail ( int errcode ) -{ - fprintf(stderr, - "\n\nbzip2/libbzip2: internal error number %d.\n" - "This is a bug in bzip2/libbzip2, %s.\n" - "Please report it to me at: jseward@bzip.org. If this happened\n" - "when you were using some program which uses libbzip2 as a\n" - "component, you should also report this bug to the author(s)\n" - "of that program. Please make an effort to report this bug;\n" - "timely and accurate bug reports eventually lead to higher\n" - "quality software. Thanks. Julian Seward, 10 December 2007.\n\n", - errcode, - BZ2_bzlibVersion() - ); - - if (errcode == 1007) { - fprintf(stderr, - "\n*** A special note about internal error number 1007 ***\n" - "\n" - "Experience suggests that a common cause of i.e. 1007\n" - "is unreliable memory or other hardware. The 1007 assertion\n" - "just happens to cross-check the results of huge numbers of\n" - "memory reads/writes, and so acts (unintendedly) as a stress\n" - "test of your memory system.\n" - "\n" - "I suggest the following: try compressing the file again,\n" - "possibly monitoring progress in detail with the -vv flag.\n" - "\n" - "* If the error cannot be reproduced, and/or happens at different\n" - " points in compression, you may have a flaky memory system.\n" - " Try a memory-test program. I have used Memtest86\n" - " (www.memtest86.com). At the time of writing it is free (GPLd).\n" - " Memtest86 tests memory much more thorougly than your BIOSs\n" - " power-on test, and may find failures that the BIOS doesn't.\n" - "\n" - "* If the error can be repeatably reproduced, this is a bug in\n" - " bzip2, and I would very much like to hear about it. Please\n" - " let me know, and, ideally, save a copy of the file causing the\n" - " problem -- without which I will be unable to investigate it.\n" - "\n" - ); - } - - exit(3); -} -#endif - - -/*---------------------------------------------------*/ -static -int bz_config_ok ( void ) -{ - if (sizeof(int) != 4) return 0; - if (sizeof(short) != 2) return 0; - if (sizeof(char) != 1) return 0; - return 1; -} - - -/*---------------------------------------------------*/ -static -void* default_bzalloc ( void* opaque, Int32 items, Int32 size ) -{ - void* v = malloc ( items * size ); - return v; -} - -static -void default_bzfree ( void* opaque, void* addr ) -{ - if (addr != NULL) free ( addr ); -} - - -/*---------------------------------------------------*/ -static -void prepare_new_block ( EState* s ) -{ - Int32 i; - s->nblock = 0; - s->numZ = 0; - s->state_out_pos = 0; - BZ_INITIALISE_CRC ( s->blockCRC ); - for (i = 0; i < 256; i++) s->inUse[i] = False; - s->blockNo++; -} - - -/*---------------------------------------------------*/ -static -void init_RL ( EState* s ) -{ - s->state_in_ch = 256; - s->state_in_len = 0; -} - - -static -Bool isempty_RL ( EState* s ) -{ - if (s->state_in_ch < 256 && s->state_in_len > 0) - return False; else - return True; -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzCompressInit) - ( bz_stream* strm, - int blockSize100k, - int verbosity, - int workFactor ) -{ - Int32 n; - EState* s; - - if (!bz_config_ok()) return BZ_CONFIG_ERROR; - - if (strm == NULL || - blockSize100k < 1 || blockSize100k > 9 || - workFactor < 0 || workFactor > 250) - return BZ_PARAM_ERROR; - - if (workFactor == 0) workFactor = 30; - if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc; - if (strm->bzfree == NULL) strm->bzfree = default_bzfree; - - s = BZALLOC( sizeof(EState) ); - if (s == NULL) return BZ_MEM_ERROR; - s->strm = strm; - - s->arr1 = NULL; - s->arr2 = NULL; - s->ftab = NULL; - - n = 100000 * blockSize100k; - s->arr1 = BZALLOC( n * sizeof(UInt32) ); - s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) ); - s->ftab = BZALLOC( 65537 * sizeof(UInt32) ); - - if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) { - if (s->arr1 != NULL) BZFREE(s->arr1); - if (s->arr2 != NULL) BZFREE(s->arr2); - if (s->ftab != NULL) BZFREE(s->ftab); - if (s != NULL) BZFREE(s); - return BZ_MEM_ERROR; - } - - s->blockNo = 0; - s->state = BZ_S_INPUT; - s->mode = BZ_M_RUNNING; - s->combinedCRC = 0; - s->blockSize100k = blockSize100k; - s->nblockMAX = 100000 * blockSize100k - 19; - s->verbosity = verbosity; - s->workFactor = workFactor; - - s->block = (UChar*)s->arr2; - s->mtfv = (UInt16*)s->arr1; - s->zbits = NULL; - s->ptr = (UInt32*)s->arr1; - - strm->state = s; - strm->total_in_lo32 = 0; - strm->total_in_hi32 = 0; - strm->total_out_lo32 = 0; - strm->total_out_hi32 = 0; - init_RL ( s ); - prepare_new_block ( s ); - return BZ_OK; -} - - -/*---------------------------------------------------*/ -static -void add_pair_to_block ( EState* s ) -{ - Int32 i; - UChar ch = (UChar)(s->state_in_ch); - for (i = 0; i < s->state_in_len; i++) { - BZ_UPDATE_CRC( s->blockCRC, ch ); - } - s->inUse[s->state_in_ch] = True; - switch (s->state_in_len) { - case 1: - s->block[s->nblock] = (UChar)ch; s->nblock++; - break; - case 2: - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - break; - case 3: - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - break; - default: - s->inUse[s->state_in_len-4] = True; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = ((UChar)(s->state_in_len-4)); - s->nblock++; - break; - } -} - - -/*---------------------------------------------------*/ -static -void flush_RL ( EState* s ) -{ - if (s->state_in_ch < 256) add_pair_to_block ( s ); - init_RL ( s ); -} - - -/*---------------------------------------------------*/ -#define ADD_CHAR_TO_BLOCK(zs,zchh0) \ -{ \ - UInt32 zchh = (UInt32)(zchh0); \ - /*-- fast track the common case --*/ \ - if (zchh != zs->state_in_ch && \ - zs->state_in_len == 1) { \ - UChar ch = (UChar)(zs->state_in_ch); \ - BZ_UPDATE_CRC( zs->blockCRC, ch ); \ - zs->inUse[zs->state_in_ch] = True; \ - zs->block[zs->nblock] = (UChar)ch; \ - zs->nblock++; \ - zs->state_in_ch = zchh; \ - } \ - else \ - /*-- general, uncommon cases --*/ \ - if (zchh != zs->state_in_ch || \ - zs->state_in_len == 255) { \ - if (zs->state_in_ch < 256) \ - add_pair_to_block ( zs ); \ - zs->state_in_ch = zchh; \ - zs->state_in_len = 1; \ - } else { \ - zs->state_in_len++; \ - } \ -} - - -/*---------------------------------------------------*/ -static -Bool copy_input_until_stop ( EState* s ) -{ - Bool progress_in = False; - - if (s->mode == BZ_M_RUNNING) { - - /*-- fast track the common case --*/ - while (True) { - /*-- block full? --*/ - if (s->nblock >= s->nblockMAX) break; - /*-- no input? --*/ - if (s->strm->avail_in == 0) break; - progress_in = True; - ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); - s->strm->next_in++; - s->strm->avail_in--; - s->strm->total_in_lo32++; - if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++; - } - - } else { - - /*-- general, uncommon case --*/ - while (True) { - /*-- block full? --*/ - if (s->nblock >= s->nblockMAX) break; - /*-- no input? --*/ - if (s->strm->avail_in == 0) break; - /*-- flush/finish end? --*/ - if (s->avail_in_expect == 0) break; - progress_in = True; - ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); - s->strm->next_in++; - s->strm->avail_in--; - s->strm->total_in_lo32++; - if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++; - s->avail_in_expect--; - } - } - return progress_in; -} - - -/*---------------------------------------------------*/ -static -Bool copy_output_until_stop ( EState* s ) -{ - Bool progress_out = False; - - while (True) { - - /*-- no output space? --*/ - if (s->strm->avail_out == 0) break; - - /*-- block done? --*/ - if (s->state_out_pos >= s->numZ) break; - - progress_out = True; - *(s->strm->next_out) = s->zbits[s->state_out_pos]; - s->state_out_pos++; - s->strm->avail_out--; - s->strm->next_out++; - s->strm->total_out_lo32++; - if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; - } - - return progress_out; -} - - -/*---------------------------------------------------*/ -static -Bool handle_compress ( bz_stream* strm ) -{ - Bool progress_in = False; - Bool progress_out = False; - EState* s = strm->state; - - while (True) { - - if (s->state == BZ_S_OUTPUT) { - progress_out |= copy_output_until_stop ( s ); - if (s->state_out_pos < s->numZ) break; - if (s->mode == BZ_M_FINISHING && - s->avail_in_expect == 0 && - isempty_RL(s)) break; - prepare_new_block ( s ); - s->state = BZ_S_INPUT; - if (s->mode == BZ_M_FLUSHING && - s->avail_in_expect == 0 && - isempty_RL(s)) break; - } - - if (s->state == BZ_S_INPUT) { - progress_in |= copy_input_until_stop ( s ); - if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) { - flush_RL ( s ); - BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) ); - s->state = BZ_S_OUTPUT; - } - else - if (s->nblock >= s->nblockMAX) { - BZ2_compressBlock ( s, False ); - s->state = BZ_S_OUTPUT; - } - else - if (s->strm->avail_in == 0) { - break; - } - } - - } - - return progress_in || progress_out; -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action ) -{ - Bool progress; - EState* s; - if (strm == NULL) return BZ_PARAM_ERROR; - s = strm->state; - if (s == NULL) return BZ_PARAM_ERROR; - if (s->strm != strm) return BZ_PARAM_ERROR; - - preswitch: - switch (s->mode) { - - case BZ_M_IDLE: - return BZ_SEQUENCE_ERROR; - - case BZ_M_RUNNING: - if (action == BZ_RUN) { - progress = handle_compress ( strm ); - return progress ? BZ_RUN_OK : BZ_PARAM_ERROR; - } - else - if (action == BZ_FLUSH) { - s->avail_in_expect = strm->avail_in; - s->mode = BZ_M_FLUSHING; - goto preswitch; - } - else - if (action == BZ_FINISH) { - s->avail_in_expect = strm->avail_in; - s->mode = BZ_M_FINISHING; - goto preswitch; - } - else - return BZ_PARAM_ERROR; - - case BZ_M_FLUSHING: - if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR; - if (s->avail_in_expect != s->strm->avail_in) - return BZ_SEQUENCE_ERROR; - progress = handle_compress ( strm ); - if (s->avail_in_expect > 0 || !isempty_RL(s) || - s->state_out_pos < s->numZ) return BZ_FLUSH_OK; - s->mode = BZ_M_RUNNING; - return BZ_RUN_OK; - - case BZ_M_FINISHING: - if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR; - if (s->avail_in_expect != s->strm->avail_in) - return BZ_SEQUENCE_ERROR; - progress = handle_compress ( strm ); - if (!progress) return BZ_SEQUENCE_ERROR; - if (s->avail_in_expect > 0 || !isempty_RL(s) || - s->state_out_pos < s->numZ) return BZ_FINISH_OK; - s->mode = BZ_M_IDLE; - return BZ_STREAM_END; - } - return BZ_OK; /*--not reached--*/ -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm ) -{ - EState* s; - if (strm == NULL) return BZ_PARAM_ERROR; - s = strm->state; - if (s == NULL) return BZ_PARAM_ERROR; - if (s->strm != strm) return BZ_PARAM_ERROR; - - if (s->arr1 != NULL) BZFREE(s->arr1); - if (s->arr2 != NULL) BZFREE(s->arr2); - if (s->ftab != NULL) BZFREE(s->ftab); - BZFREE(strm->state); - - strm->state = NULL; - - return BZ_OK; -} - - -/*---------------------------------------------------*/ -/*--- Decompression stuff ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzDecompressInit) - ( bz_stream* strm, - int verbosity, - int small ) -{ - DState* s; - - if (!bz_config_ok()) return BZ_CONFIG_ERROR; - - if (strm == NULL) return BZ_PARAM_ERROR; - if (small != 0 && small != 1) return BZ_PARAM_ERROR; - if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR; - - if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc; - if (strm->bzfree == NULL) strm->bzfree = default_bzfree; - - s = BZALLOC( sizeof(DState) ); - if (s == NULL) return BZ_MEM_ERROR; - - s->strm = strm; - strm->state = s; - s->state = BZ_X_MAGIC_1; - s->bsLive = 0; - s->bsBuff = 0; - s->calculatedCombinedCRC = 0; - strm->total_in_lo32 = 0; - strm->total_in_hi32 = 0; - strm->total_out_lo32 = 0; - strm->total_out_hi32 = 0; - s->smallDecompress = (Bool)small; - s->ll4 = NULL; - s->ll16 = NULL; - s->tt = NULL; - s->currBlockNo = 0; - s->verbosity = verbosity; - - return BZ_OK; -} - - -/*---------------------------------------------------*/ -/* Return True iff data corruption is discovered. - Returns False if there is no problem. -*/ -static -Bool unRLE_obuf_to_output_FAST ( DState* s ) -{ - UChar k1; - - if (s->blockRandomised) { - - while (True) { - /* try to finish existing run */ - while (True) { - if (s->strm->avail_out == 0) return False; - if (s->state_out_len == 0) break; - *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; - BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); - s->state_out_len--; - s->strm->next_out++; - s->strm->avail_out--; - s->strm->total_out_lo32++; - if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; - } - - /* can a new run be started? */ - if (s->nblock_used == s->save_nblock+1) return False; - - /* Only caused by corrupt data stream? */ - if (s->nblock_used > s->save_nblock+1) - return True; - - s->state_out_len = 1; - s->state_out_ch = s->k0; - BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 2; - BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 3; - BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - s->state_out_len = ((Int32)k1) + 4; - BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK; - s->k0 ^= BZ_RAND_MASK; s->nblock_used++; - } - - } else { - - /* restore */ - UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC; - UChar c_state_out_ch = s->state_out_ch; - Int32 c_state_out_len = s->state_out_len; - Int32 c_nblock_used = s->nblock_used; - Int32 c_k0 = s->k0; - UInt32* c_tt = s->tt; - UInt32 c_tPos = s->tPos; - char* cs_next_out = s->strm->next_out; - unsigned int cs_avail_out = s->strm->avail_out; - Int32 ro_blockSize100k = s->blockSize100k; - /* end restore */ - - UInt32 avail_out_INIT = cs_avail_out; - Int32 s_save_nblockPP = s->save_nblock+1; - unsigned int total_out_lo32_old; - - while (True) { - - /* try to finish existing run */ - if (c_state_out_len > 0) { - while (True) { - if (cs_avail_out == 0) goto return_notr; - if (c_state_out_len == 1) break; - *( (UChar*)(cs_next_out) ) = c_state_out_ch; - BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch ); - c_state_out_len--; - cs_next_out++; - cs_avail_out--; - } - s_state_out_len_eq_one: - { - if (cs_avail_out == 0) { - c_state_out_len = 1; goto return_notr; - }; - *( (UChar*)(cs_next_out) ) = c_state_out_ch; - BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch ); - cs_next_out++; - cs_avail_out--; - } - } - /* Only caused by corrupt data stream? */ - if (c_nblock_used > s_save_nblockPP) - return True; - - /* can a new run be started? */ - if (c_nblock_used == s_save_nblockPP) { - c_state_out_len = 0; goto return_notr; - }; - c_state_out_ch = c_k0; - BZ_GET_FAST_C(k1); c_nblock_used++; - if (k1 != c_k0) { - c_k0 = k1; goto s_state_out_len_eq_one; - }; - if (c_nblock_used == s_save_nblockPP) - goto s_state_out_len_eq_one; - - c_state_out_len = 2; - BZ_GET_FAST_C(k1); c_nblock_used++; - if (c_nblock_used == s_save_nblockPP) continue; - if (k1 != c_k0) { c_k0 = k1; continue; }; - - c_state_out_len = 3; - BZ_GET_FAST_C(k1); c_nblock_used++; - if (c_nblock_used == s_save_nblockPP) continue; - if (k1 != c_k0) { c_k0 = k1; continue; }; - - BZ_GET_FAST_C(k1); c_nblock_used++; - c_state_out_len = ((Int32)k1) + 4; - BZ_GET_FAST_C(c_k0); c_nblock_used++; - } - - return_notr: - total_out_lo32_old = s->strm->total_out_lo32; - s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out); - if (s->strm->total_out_lo32 < total_out_lo32_old) - s->strm->total_out_hi32++; - - /* save */ - s->calculatedBlockCRC = c_calculatedBlockCRC; - s->state_out_ch = c_state_out_ch; - s->state_out_len = c_state_out_len; - s->nblock_used = c_nblock_used; - s->k0 = c_k0; - s->tt = c_tt; - s->tPos = c_tPos; - s->strm->next_out = cs_next_out; - s->strm->avail_out = cs_avail_out; - /* end save */ - } - return False; -} - - - -/*---------------------------------------------------*/ -__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab ) -{ - Int32 nb, na, mid; - nb = 0; - na = 256; - do { - mid = (nb + na) >> 1; - if (indx >= cftab[mid]) nb = mid; else na = mid; - } - while (na - nb != 1); - return nb; -} - - -/*---------------------------------------------------*/ -/* Return True iff data corruption is discovered. - Returns False if there is no problem. -*/ -static -Bool unRLE_obuf_to_output_SMALL ( DState* s ) -{ - UChar k1; - - if (s->blockRandomised) { - - while (True) { - /* try to finish existing run */ - while (True) { - if (s->strm->avail_out == 0) return False; - if (s->state_out_len == 0) break; - *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; - BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); - s->state_out_len--; - s->strm->next_out++; - s->strm->avail_out--; - s->strm->total_out_lo32++; - if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; - } - - /* can a new run be started? */ - if (s->nblock_used == s->save_nblock+1) return False; - - /* Only caused by corrupt data stream? */ - if (s->nblock_used > s->save_nblock+1) - return True; - - s->state_out_len = 1; - s->state_out_ch = s->k0; - BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 2; - BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 3; - BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - s->state_out_len = ((Int32)k1) + 4; - BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK; - s->k0 ^= BZ_RAND_MASK; s->nblock_used++; - } - - } else { - - while (True) { - /* try to finish existing run */ - while (True) { - if (s->strm->avail_out == 0) return False; - if (s->state_out_len == 0) break; - *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; - BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); - s->state_out_len--; - s->strm->next_out++; - s->strm->avail_out--; - s->strm->total_out_lo32++; - if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; - } - - /* can a new run be started? */ - if (s->nblock_used == s->save_nblock+1) return False; - - /* Only caused by corrupt data stream? */ - if (s->nblock_used > s->save_nblock+1) - return True; - - s->state_out_len = 1; - s->state_out_ch = s->k0; - BZ_GET_SMALL(k1); s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 2; - BZ_GET_SMALL(k1); s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 3; - BZ_GET_SMALL(k1); s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - BZ_GET_SMALL(k1); s->nblock_used++; - s->state_out_len = ((Int32)k1) + 4; - BZ_GET_SMALL(s->k0); s->nblock_used++; - } - - } -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzDecompress) ( bz_stream *strm ) -{ - Bool corrupt; - DState* s; - if (strm == NULL) return BZ_PARAM_ERROR; - s = strm->state; - if (s == NULL) return BZ_PARAM_ERROR; - if (s->strm != strm) return BZ_PARAM_ERROR; - - while (True) { - if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR; - if (s->state == BZ_X_OUTPUT) { - if (s->smallDecompress) - corrupt = unRLE_obuf_to_output_SMALL ( s ); else - corrupt = unRLE_obuf_to_output_FAST ( s ); - if (corrupt) return BZ_DATA_ERROR; - if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) { - BZ_FINALISE_CRC ( s->calculatedBlockCRC ); - if (s->verbosity >= 3) - VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, - s->calculatedBlockCRC ); - if (s->verbosity >= 2) VPrintf0 ( "]" ); - if (s->calculatedBlockCRC != s->storedBlockCRC) - return BZ_DATA_ERROR; - s->calculatedCombinedCRC - = (s->calculatedCombinedCRC << 1) | - (s->calculatedCombinedCRC >> 31); - s->calculatedCombinedCRC ^= s->calculatedBlockCRC; - s->state = BZ_X_BLKHDR_1; - } else { - return BZ_OK; - } - } - if (s->state >= BZ_X_MAGIC_1) { - Int32 r = BZ2_decompress ( s ); - if (r == BZ_STREAM_END) { - if (s->verbosity >= 3) - VPrintf2 ( "\n combined CRCs: stored = 0x%08x, computed = 0x%08x", - s->storedCombinedCRC, s->calculatedCombinedCRC ); - if (s->calculatedCombinedCRC != s->storedCombinedCRC) - return BZ_DATA_ERROR; - return r; - } - if (s->state != BZ_X_OUTPUT) return r; - } - } - - AssertH ( 0, 6001 ); - - return 0; /*NOTREACHED*/ -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm ) -{ - DState* s; - if (strm == NULL) return BZ_PARAM_ERROR; - s = strm->state; - if (s == NULL) return BZ_PARAM_ERROR; - if (s->strm != strm) return BZ_PARAM_ERROR; - - if (s->tt != NULL) BZFREE(s->tt); - if (s->ll16 != NULL) BZFREE(s->ll16); - if (s->ll4 != NULL) BZFREE(s->ll4); - - BZFREE(strm->state); - strm->state = NULL; - - return BZ_OK; -} - - -#ifndef BZ_NO_STDIO -/*---------------------------------------------------*/ -/*--- File I/O stuff ---*/ -/*---------------------------------------------------*/ - -#define BZ_SETERR(eee) \ -{ \ - if (bzerror != NULL) *bzerror = eee; \ - if (bzf != NULL) bzf->lastErr = eee; \ -} - -typedef - struct { - FILE* handle; - Char buf[BZ_MAX_UNUSED]; - Int32 bufN; - Bool writing; - bz_stream strm; - Int32 lastErr; - Bool initialisedOk; - } - bzFile; - - -/*---------------------------------------------*/ -static Bool myfeof ( FILE* f ) -{ - Int32 c = fgetc ( f ); - if (c == EOF) return True; - ungetc ( c, f ); - return False; -} - - -/*---------------------------------------------------*/ -BZFILE* BZ_API(BZ2_bzWriteOpen) - ( int* bzerror, - FILE* f, - int blockSize100k, - int verbosity, - int workFactor ) -{ - Int32 ret; - bzFile* bzf = NULL; - - BZ_SETERR(BZ_OK); - - if (f == NULL || - (blockSize100k < 1 || blockSize100k > 9) || - (workFactor < 0 || workFactor > 250) || - (verbosity < 0 || verbosity > 4)) - { BZ_SETERR(BZ_PARAM_ERROR); return NULL; }; - - if (ferror(f)) - { BZ_SETERR(BZ_IO_ERROR); return NULL; }; - - bzf = malloc ( sizeof(bzFile) ); - if (bzf == NULL) - { BZ_SETERR(BZ_MEM_ERROR); return NULL; }; - - BZ_SETERR(BZ_OK); - bzf->initialisedOk = False; - bzf->bufN = 0; - bzf->handle = f; - bzf->writing = True; - bzf->strm.bzalloc = NULL; - bzf->strm.bzfree = NULL; - bzf->strm.opaque = NULL; - - if (workFactor == 0) workFactor = 30; - ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k, - verbosity, workFactor ); - if (ret != BZ_OK) - { BZ_SETERR(ret); free(bzf); return NULL; }; - - bzf->strm.avail_in = 0; - bzf->initialisedOk = True; - return bzf; -} - - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzWrite) - ( int* bzerror, - BZFILE* b, - void* buf, - int len ) -{ - Int32 n, n2, ret; - bzFile* bzf = (bzFile*)b; - - BZ_SETERR(BZ_OK); - if (bzf == NULL || buf == NULL || len < 0) - { BZ_SETERR(BZ_PARAM_ERROR); return; }; - if (!(bzf->writing)) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - - if (len == 0) - { BZ_SETERR(BZ_OK); return; }; - - bzf->strm.avail_in = len; - bzf->strm.next_in = buf; - - while (True) { - bzf->strm.avail_out = BZ_MAX_UNUSED; - bzf->strm.next_out = bzf->buf; - ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN ); - if (ret != BZ_RUN_OK) - { BZ_SETERR(ret); return; }; - - if (bzf->strm.avail_out < BZ_MAX_UNUSED) { - n = BZ_MAX_UNUSED - bzf->strm.avail_out; - n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), - n, bzf->handle ); - if (n != n2 || ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - } - - if (bzf->strm.avail_in == 0) - { BZ_SETERR(BZ_OK); return; }; - } -} - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzWriteClose) - ( int* bzerror, - BZFILE* b, - int abandon, - unsigned int* nbytes_in, - unsigned int* nbytes_out ) -{ - BZ2_bzWriteClose64 ( bzerror, b, abandon, - nbytes_in, NULL, nbytes_out, NULL ); -} - - -void BZ_API(BZ2_bzWriteClose64) - ( int* bzerror, - BZFILE* b, - int abandon, - unsigned int* nbytes_in_lo32, - unsigned int* nbytes_in_hi32, - unsigned int* nbytes_out_lo32, - unsigned int* nbytes_out_hi32 ) -{ - Int32 n, n2, ret; - bzFile* bzf = (bzFile*)b; - - if (bzf == NULL) - { BZ_SETERR(BZ_OK); return; }; - if (!(bzf->writing)) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - - if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0; - if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0; - if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0; - if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0; - - if ((!abandon) && bzf->lastErr == BZ_OK) { - while (True) { - bzf->strm.avail_out = BZ_MAX_UNUSED; - bzf->strm.next_out = bzf->buf; - ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH ); - if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END) - { BZ_SETERR(ret); return; }; - - if (bzf->strm.avail_out < BZ_MAX_UNUSED) { - n = BZ_MAX_UNUSED - bzf->strm.avail_out; - n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), - n, bzf->handle ); - if (n != n2 || ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - } - - if (ret == BZ_STREAM_END) break; - } - } - - if ( !abandon && !ferror ( bzf->handle ) ) { - fflush ( bzf->handle ); - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - } - - if (nbytes_in_lo32 != NULL) - *nbytes_in_lo32 = bzf->strm.total_in_lo32; - if (nbytes_in_hi32 != NULL) - *nbytes_in_hi32 = bzf->strm.total_in_hi32; - if (nbytes_out_lo32 != NULL) - *nbytes_out_lo32 = bzf->strm.total_out_lo32; - if (nbytes_out_hi32 != NULL) - *nbytes_out_hi32 = bzf->strm.total_out_hi32; - - BZ_SETERR(BZ_OK); - BZ2_bzCompressEnd ( &(bzf->strm) ); - free ( bzf ); -} - - -/*---------------------------------------------------*/ -BZFILE* BZ_API(BZ2_bzReadOpen) - ( int* bzerror, - FILE* f, - int verbosity, - int small, - void* unused, - int nUnused ) -{ - bzFile* bzf = NULL; - int ret; - - BZ_SETERR(BZ_OK); - - if (f == NULL || - (small != 0 && small != 1) || - (verbosity < 0 || verbosity > 4) || - (unused == NULL && nUnused != 0) || - (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED))) - { BZ_SETERR(BZ_PARAM_ERROR); return NULL; }; - - if (ferror(f)) - { BZ_SETERR(BZ_IO_ERROR); return NULL; }; - - bzf = malloc ( sizeof(bzFile) ); - if (bzf == NULL) - { BZ_SETERR(BZ_MEM_ERROR); return NULL; }; - - BZ_SETERR(BZ_OK); - - bzf->initialisedOk = False; - bzf->handle = f; - bzf->bufN = 0; - bzf->writing = False; - bzf->strm.bzalloc = NULL; - bzf->strm.bzfree = NULL; - bzf->strm.opaque = NULL; - - while (nUnused > 0) { - bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++; - unused = ((void*)( 1 + ((UChar*)(unused)) )); - nUnused--; - } - - ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small ); - if (ret != BZ_OK) - { BZ_SETERR(ret); free(bzf); return NULL; }; - - bzf->strm.avail_in = bzf->bufN; - bzf->strm.next_in = bzf->buf; - - bzf->initialisedOk = True; - return bzf; -} - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b ) -{ - bzFile* bzf = (bzFile*)b; - - BZ_SETERR(BZ_OK); - if (bzf == NULL) - { BZ_SETERR(BZ_OK); return; }; - - if (bzf->writing) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; - - if (bzf->initialisedOk) - (void)BZ2_bzDecompressEnd ( &(bzf->strm) ); - free ( bzf ); -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzRead) - ( int* bzerror, - BZFILE* b, - void* buf, - int len ) -{ - Int32 n, ret; - bzFile* bzf = (bzFile*)b; - - BZ_SETERR(BZ_OK); - - if (bzf == NULL || buf == NULL || len < 0) - { BZ_SETERR(BZ_PARAM_ERROR); return 0; }; - - if (bzf->writing) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; }; - - if (len == 0) - { BZ_SETERR(BZ_OK); return 0; }; - - bzf->strm.avail_out = len; - bzf->strm.next_out = buf; - - while (True) { - - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return 0; }; - - if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) { - n = fread ( bzf->buf, sizeof(UChar), - BZ_MAX_UNUSED, bzf->handle ); - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return 0; }; - bzf->bufN = n; - bzf->strm.avail_in = bzf->bufN; - bzf->strm.next_in = bzf->buf; - } - - ret = BZ2_bzDecompress ( &(bzf->strm) ); - - if (ret != BZ_OK && ret != BZ_STREAM_END) - { BZ_SETERR(ret); return 0; }; - - if (ret == BZ_OK && myfeof(bzf->handle) && - bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0) - { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; }; - - if (ret == BZ_STREAM_END) - { BZ_SETERR(BZ_STREAM_END); - return len - bzf->strm.avail_out; }; - if (bzf->strm.avail_out == 0) - { BZ_SETERR(BZ_OK); return len; }; - - } - - return 0; /*not reached*/ -} - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzReadGetUnused) - ( int* bzerror, - BZFILE* b, - void** unused, - int* nUnused ) -{ - bzFile* bzf = (bzFile*)b; - if (bzf == NULL) - { BZ_SETERR(BZ_PARAM_ERROR); return; }; - if (bzf->lastErr != BZ_STREAM_END) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; - if (unused == NULL || nUnused == NULL) - { BZ_SETERR(BZ_PARAM_ERROR); return; }; - - BZ_SETERR(BZ_OK); - *nUnused = bzf->strm.avail_in; - *unused = bzf->strm.next_in; -} -#endif - - -/*---------------------------------------------------*/ -/*--- Misc convenience stuff ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzBuffToBuffCompress) - ( char* dest, - unsigned int* destLen, - char* source, - unsigned int sourceLen, - int blockSize100k, - int verbosity, - int workFactor ) -{ - bz_stream strm; - int ret; - - if (dest == NULL || destLen == NULL || - source == NULL || - blockSize100k < 1 || blockSize100k > 9 || - verbosity < 0 || verbosity > 4 || - workFactor < 0 || workFactor > 250) - return BZ_PARAM_ERROR; - - if (workFactor == 0) workFactor = 30; - strm.bzalloc = NULL; - strm.bzfree = NULL; - strm.opaque = NULL; - ret = BZ2_bzCompressInit ( &strm, blockSize100k, - verbosity, workFactor ); - if (ret != BZ_OK) return ret; - - strm.next_in = source; - strm.next_out = dest; - strm.avail_in = sourceLen; - strm.avail_out = *destLen; - - ret = BZ2_bzCompress ( &strm, BZ_FINISH ); - if (ret == BZ_FINISH_OK) goto output_overflow; - if (ret != BZ_STREAM_END) goto errhandler; - - /* normal termination */ - *destLen -= strm.avail_out; - BZ2_bzCompressEnd ( &strm ); - return BZ_OK; - - output_overflow: - BZ2_bzCompressEnd ( &strm ); - return BZ_OUTBUFF_FULL; - - errhandler: - BZ2_bzCompressEnd ( &strm ); - return ret; -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzBuffToBuffDecompress) - ( char* dest, - unsigned int* destLen, - char* source, - unsigned int sourceLen, - int small, - int verbosity ) -{ - bz_stream strm; - int ret; - - if (dest == NULL || destLen == NULL || - source == NULL || - (small != 0 && small != 1) || - verbosity < 0 || verbosity > 4) - return BZ_PARAM_ERROR; - - strm.bzalloc = NULL; - strm.bzfree = NULL; - strm.opaque = NULL; - ret = BZ2_bzDecompressInit ( &strm, verbosity, small ); - if (ret != BZ_OK) return ret; - - strm.next_in = source; - strm.next_out = dest; - strm.avail_in = sourceLen; - strm.avail_out = *destLen; - - ret = BZ2_bzDecompress ( &strm ); - if (ret == BZ_OK) goto output_overflow_or_eof; - if (ret != BZ_STREAM_END) goto errhandler; - - /* normal termination */ - *destLen -= strm.avail_out; - BZ2_bzDecompressEnd ( &strm ); - return BZ_OK; - - output_overflow_or_eof: - if (strm.avail_out > 0) { - BZ2_bzDecompressEnd ( &strm ); - return BZ_UNEXPECTED_EOF; - } else { - BZ2_bzDecompressEnd ( &strm ); - return BZ_OUTBUFF_FULL; - }; - - errhandler: - BZ2_bzDecompressEnd ( &strm ); - return ret; -} - - -/*---------------------------------------------------*/ -/*-- - Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp) - to support better zlib compatibility. - This code is not _officially_ part of libbzip2 (yet); - I haven't tested it, documented it, or considered the - threading-safeness of it. - If this code breaks, please contact both Yoshioka and me. ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -/*-- - return version like "0.9.5d, 4-Sept-1999". ---*/ -const char * BZ_API(BZ2_bzlibVersion)(void) -{ - return BZ_VERSION; -} - - -#ifndef BZ_NO_STDIO -/*---------------------------------------------------*/ - -#if defined(_WIN32) || defined(OS2) || defined(MSDOS) -# include -# include -# define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY) -#else -# define SET_BINARY_MODE(file) -#endif -static -BZFILE * bzopen_or_bzdopen - ( const char *path, /* no use when bzdopen */ - int fd, /* no use when bzdopen */ - const char *mode, - int open_mode) /* bzopen: 0, bzdopen:1 */ -{ - int bzerr; - char unused[BZ_MAX_UNUSED]; - int blockSize100k = 9; - int writing = 0; - char mode2[10] = ""; - FILE *fp = NULL; - BZFILE *bzfp = NULL; - int verbosity = 0; - int workFactor = 30; - int smallMode = 0; - int nUnused = 0; - - if (mode == NULL) return NULL; - while (*mode) { - switch (*mode) { - case 'r': - writing = 0; break; - case 'w': - writing = 1; break; - case 's': - smallMode = 1; break; - default: - if (isdigit((int)(*mode))) { - blockSize100k = *mode-BZ_HDR_0; - } - } - mode++; - } - strcat(mode2, writing ? "w" : "r" ); - strcat(mode2,"b"); /* binary mode */ - - if (open_mode==0) { - if (path==NULL || strcmp(path,"")==0) { - fp = (writing ? stdout : stdin); - SET_BINARY_MODE(fp); - } else { - fp = fopen(path,mode2); - } - } else { -#ifdef BZ_STRICT_ANSI - fp = NULL; -#else - fp = fdopen(fd,mode2); -#endif - } - if (fp == NULL) return NULL; - - if (writing) { - /* Guard against total chaos and anarchy -- JRS */ - if (blockSize100k < 1) blockSize100k = 1; - if (blockSize100k > 9) blockSize100k = 9; - bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k, - verbosity,workFactor); - } else { - bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode, - unused,nUnused); - } - if (bzfp == NULL) { - if (fp != stdin && fp != stdout) fclose(fp); - return NULL; - } - return bzfp; -} - - -/*---------------------------------------------------*/ -/*-- - open file for read or write. - ex) bzopen("file","w9") - case path="" or NULL => use stdin or stdout. ---*/ -BZFILE * BZ_API(BZ2_bzopen) - ( const char *path, - const char *mode ) -{ - return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0); -} - - -/*---------------------------------------------------*/ -BZFILE * BZ_API(BZ2_bzdopen) - ( int fd, - const char *mode ) -{ - return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1); -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len ) -{ - int bzerr, nread; - if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0; - nread = BZ2_bzRead(&bzerr,b,buf,len); - if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) { - return nread; - } else { - return -1; - } -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len ) -{ - int bzerr; - - BZ2_bzWrite(&bzerr,b,buf,len); - if(bzerr == BZ_OK){ - return len; - }else{ - return -1; - } -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzflush) (BZFILE *b) -{ - /* do nothing now... */ - return 0; -} - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzclose) (BZFILE* b) -{ - int bzerr; - FILE *fp; - - if (b==NULL) {return;} - fp = ((bzFile *)b)->handle; - if(((bzFile*)b)->writing){ - BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL); - if(bzerr != BZ_OK){ - BZ2_bzWriteClose(NULL,b,1,NULL,NULL); - } - }else{ - BZ2_bzReadClose(&bzerr,b); - } - if(fp!=stdin && fp!=stdout){ - fclose(fp); - } -} - - -/*---------------------------------------------------*/ -/*-- - return last error code ---*/ -static const char *bzerrorstrings[] = { - "OK" - ,"SEQUENCE_ERROR" - ,"PARAM_ERROR" - ,"MEM_ERROR" - ,"DATA_ERROR" - ,"DATA_ERROR_MAGIC" - ,"IO_ERROR" - ,"UNEXPECTED_EOF" - ,"OUTBUFF_FULL" - ,"CONFIG_ERROR" - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ -}; - - -const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum) -{ - int err = ((bzFile *)b)->lastErr; - - if(err>0) err = 0; - *errnum = err; - return bzerrorstrings[err*-1]; -} -#endif - - -/*-------------------------------------------------------------*/ -/*--- end bzlib.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/android/jni/bzlib.h b/android/jni/bzlib.h deleted file mode 100644 index 8277123..0000000 --- a/android/jni/bzlib.h +++ /dev/null @@ -1,282 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Public header file for the library. ---*/ -/*--- bzlib.h ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#ifndef _BZLIB_H -#define _BZLIB_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define BZ_RUN 0 -#define BZ_FLUSH 1 -#define BZ_FINISH 2 - -#define BZ_OK 0 -#define BZ_RUN_OK 1 -#define BZ_FLUSH_OK 2 -#define BZ_FINISH_OK 3 -#define BZ_STREAM_END 4 -#define BZ_SEQUENCE_ERROR (-1) -#define BZ_PARAM_ERROR (-2) -#define BZ_MEM_ERROR (-3) -#define BZ_DATA_ERROR (-4) -#define BZ_DATA_ERROR_MAGIC (-5) -#define BZ_IO_ERROR (-6) -#define BZ_UNEXPECTED_EOF (-7) -#define BZ_OUTBUFF_FULL (-8) -#define BZ_CONFIG_ERROR (-9) - -typedef - struct { - char *next_in; - unsigned int avail_in; - unsigned int total_in_lo32; - unsigned int total_in_hi32; - - char *next_out; - unsigned int avail_out; - unsigned int total_out_lo32; - unsigned int total_out_hi32; - - void *state; - - void *(*bzalloc)(void *,int,int); - void (*bzfree)(void *,void *); - void *opaque; - } - bz_stream; - - -#ifndef BZ_IMPORT -#define BZ_EXPORT -#endif - -#ifndef BZ_NO_STDIO -/* Need a definitition for FILE */ -#include -#endif - -#ifdef _WIN32 -# include -# ifdef small - /* windows.h define small to char */ -# undef small -# endif -# ifdef BZ_EXPORT -# define BZ_API(func) WINAPI func -# define BZ_EXTERN extern -# else - /* import windows dll dynamically */ -# define BZ_API(func) (WINAPI * func) -# define BZ_EXTERN -# endif -#else -# define BZ_API(func) func -# define BZ_EXTERN extern -#endif - - -/*-- Core (low-level) library functions --*/ - -BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( - bz_stream* strm, - int blockSize100k, - int verbosity, - int workFactor - ); - -BZ_EXTERN int BZ_API(BZ2_bzCompress) ( - bz_stream* strm, - int action - ); - -BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( - bz_stream* strm - ); - -BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( - bz_stream *strm, - int verbosity, - int small - ); - -BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( - bz_stream* strm - ); - -BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( - bz_stream *strm - ); - - - -/*-- High(er) level library functions --*/ - -#ifndef BZ_NO_STDIO -#define BZ_MAX_UNUSED 5000 - -typedef void BZFILE; - -BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( - int* bzerror, - FILE* f, - int verbosity, - int small, - void* unused, - int nUnused - ); - -BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( - int* bzerror, - BZFILE* b - ); - -BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( - int* bzerror, - BZFILE* b, - void** unused, - int* nUnused - ); - -BZ_EXTERN int BZ_API(BZ2_bzRead) ( - int* bzerror, - BZFILE* b, - void* buf, - int len - ); - -BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( - int* bzerror, - FILE* f, - int blockSize100k, - int verbosity, - int workFactor - ); - -BZ_EXTERN void BZ_API(BZ2_bzWrite) ( - int* bzerror, - BZFILE* b, - void* buf, - int len - ); - -BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( - int* bzerror, - BZFILE* b, - int abandon, - unsigned int* nbytes_in, - unsigned int* nbytes_out - ); - -BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( - int* bzerror, - BZFILE* b, - int abandon, - unsigned int* nbytes_in_lo32, - unsigned int* nbytes_in_hi32, - unsigned int* nbytes_out_lo32, - unsigned int* nbytes_out_hi32 - ); -#endif - - -/*-- Utility functions --*/ - -BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( - char* dest, - unsigned int* destLen, - char* source, - unsigned int sourceLen, - int blockSize100k, - int verbosity, - int workFactor - ); - -BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( - char* dest, - unsigned int* destLen, - char* source, - unsigned int sourceLen, - int small, - int verbosity - ); - - -/*-- - Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp) - to support better zlib compatibility. - This code is not _officially_ part of libbzip2 (yet); - I haven't tested it, documented it, or considered the - threading-safeness of it. - If this code breaks, please contact both Yoshioka and me. ---*/ - -BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) ( - void - ); - -#ifndef BZ_NO_STDIO -BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) ( - const char *path, - const char *mode - ); - -BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) ( - int fd, - const char *mode - ); - -BZ_EXTERN int BZ_API(BZ2_bzread) ( - BZFILE* b, - void* buf, - int len - ); - -BZ_EXTERN int BZ_API(BZ2_bzwrite) ( - BZFILE* b, - void* buf, - int len - ); - -BZ_EXTERN int BZ_API(BZ2_bzflush) ( - BZFILE* b - ); - -BZ_EXTERN void BZ_API(BZ2_bzclose) ( - BZFILE* b - ); - -BZ_EXTERN const char * BZ_API(BZ2_bzerror) ( - BZFILE *b, - int *errnum - ); -#endif - -#ifdef __cplusplus -} -#endif - -#endif - -/*-------------------------------------------------------------*/ -/*--- end bzlib.h ---*/ -/*-------------------------------------------------------------*/ diff --git a/android/jni/bzlib_private.h b/android/jni/bzlib_private.h deleted file mode 100644 index 5d0217f..0000000 --- a/android/jni/bzlib_private.h +++ /dev/null @@ -1,509 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Private header file for the library. ---*/ -/*--- bzlib_private.h ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#ifndef _BZLIB_PRIVATE_H -#define _BZLIB_PRIVATE_H - -#include - -#ifndef BZ_NO_STDIO -#include -#include -#include -#endif - -#include "bzlib.h" - - - -/*-- General stuff. --*/ - -#define BZ_VERSION "1.0.6, 6-Sept-2010" - -typedef char Char; -typedef unsigned char Bool; -typedef unsigned char UChar; -typedef int Int32; -typedef unsigned int UInt32; -typedef short Int16; -typedef unsigned short UInt16; - -#define True ((Bool)1) -#define False ((Bool)0) - -#ifndef __GNUC__ -#define __inline__ /* */ -#endif - -#ifndef BZ_NO_STDIO - -extern void BZ2_bz__AssertH__fail ( int errcode ); -#define AssertH(cond,errcode) \ - { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); } - -#if BZ_DEBUG -#define AssertD(cond,msg) \ - { if (!(cond)) { \ - fprintf ( stderr, \ - "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\ - exit(1); \ - }} -#else -#define AssertD(cond,msg) /* */ -#endif - -#define VPrintf0(zf) \ - fprintf(stderr,zf) -#define VPrintf1(zf,za1) \ - fprintf(stderr,zf,za1) -#define VPrintf2(zf,za1,za2) \ - fprintf(stderr,zf,za1,za2) -#define VPrintf3(zf,za1,za2,za3) \ - fprintf(stderr,zf,za1,za2,za3) -#define VPrintf4(zf,za1,za2,za3,za4) \ - fprintf(stderr,zf,za1,za2,za3,za4) -#define VPrintf5(zf,za1,za2,za3,za4,za5) \ - fprintf(stderr,zf,za1,za2,za3,za4,za5) - -#else - -extern void bz_internal_error ( int errcode ); -#define AssertH(cond,errcode) \ - { if (!(cond)) bz_internal_error ( errcode ); } -#define AssertD(cond,msg) do { } while (0) -#define VPrintf0(zf) do { } while (0) -#define VPrintf1(zf,za1) do { } while (0) -#define VPrintf2(zf,za1,za2) do { } while (0) -#define VPrintf3(zf,za1,za2,za3) do { } while (0) -#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0) -#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0) - -#endif - - -#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1) -#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp)) - - -/*-- Header bytes. --*/ - -#define BZ_HDR_B 0x42 /* 'B' */ -#define BZ_HDR_Z 0x5a /* 'Z' */ -#define BZ_HDR_h 0x68 /* 'h' */ -#define BZ_HDR_0 0x30 /* '0' */ - -/*-- Constants for the back end. --*/ - -#define BZ_MAX_ALPHA_SIZE 258 -#define BZ_MAX_CODE_LEN 23 - -#define BZ_RUNA 0 -#define BZ_RUNB 1 - -#define BZ_N_GROUPS 6 -#define BZ_G_SIZE 50 -#define BZ_N_ITERS 4 - -#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE)) - - - -/*-- Stuff for randomising repetitive blocks. --*/ - -extern Int32 BZ2_rNums[512]; - -#define BZ_RAND_DECLS \ - Int32 rNToGo; \ - Int32 rTPos \ - -#define BZ_RAND_INIT_MASK \ - s->rNToGo = 0; \ - s->rTPos = 0 \ - -#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0) - -#define BZ_RAND_UPD_MASK \ - if (s->rNToGo == 0) { \ - s->rNToGo = BZ2_rNums[s->rTPos]; \ - s->rTPos++; \ - if (s->rTPos == 512) s->rTPos = 0; \ - } \ - s->rNToGo--; - - - -/*-- Stuff for doing CRCs. --*/ - -extern UInt32 BZ2_crc32Table[256]; - -#define BZ_INITIALISE_CRC(crcVar) \ -{ \ - crcVar = 0xffffffffL; \ -} - -#define BZ_FINALISE_CRC(crcVar) \ -{ \ - crcVar = ~(crcVar); \ -} - -#define BZ_UPDATE_CRC(crcVar,cha) \ -{ \ - crcVar = (crcVar << 8) ^ \ - BZ2_crc32Table[(crcVar >> 24) ^ \ - ((UChar)cha)]; \ -} - - - -/*-- States and modes for compression. --*/ - -#define BZ_M_IDLE 1 -#define BZ_M_RUNNING 2 -#define BZ_M_FLUSHING 3 -#define BZ_M_FINISHING 4 - -#define BZ_S_OUTPUT 1 -#define BZ_S_INPUT 2 - -#define BZ_N_RADIX 2 -#define BZ_N_QSORT 12 -#define BZ_N_SHELL 18 -#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2) - - - - -/*-- Structure holding all the compression-side stuff. --*/ - -typedef - struct { - /* pointer back to the struct bz_stream */ - bz_stream* strm; - - /* mode this stream is in, and whether inputting */ - /* or outputting data */ - Int32 mode; - Int32 state; - - /* remembers avail_in when flush/finish requested */ - UInt32 avail_in_expect; - - /* for doing the block sorting */ - UInt32* arr1; - UInt32* arr2; - UInt32* ftab; - Int32 origPtr; - - /* aliases for arr1 and arr2 */ - UInt32* ptr; - UChar* block; - UInt16* mtfv; - UChar* zbits; - - /* for deciding when to use the fallback sorting algorithm */ - Int32 workFactor; - - /* run-length-encoding of the input */ - UInt32 state_in_ch; - Int32 state_in_len; - BZ_RAND_DECLS; - - /* input and output limits and current posns */ - Int32 nblock; - Int32 nblockMAX; - Int32 numZ; - Int32 state_out_pos; - - /* map of bytes used in block */ - Int32 nInUse; - Bool inUse[256]; - UChar unseqToSeq[256]; - - /* the buffer for bit stream creation */ - UInt32 bsBuff; - Int32 bsLive; - - /* block and combined CRCs */ - UInt32 blockCRC; - UInt32 combinedCRC; - - /* misc administratium */ - Int32 verbosity; - Int32 blockNo; - Int32 blockSize100k; - - /* stuff for coding the MTF values */ - Int32 nMTF; - Int32 mtfFreq [BZ_MAX_ALPHA_SIZE]; - UChar selector [BZ_MAX_SELECTORS]; - UChar selectorMtf[BZ_MAX_SELECTORS]; - - UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - /* second dimension: only 3 needed; 4 makes index calculations faster */ - UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4]; - - } - EState; - - - -/*-- externs for compression. --*/ - -extern void -BZ2_blockSort ( EState* ); - -extern void -BZ2_compressBlock ( EState*, Bool ); - -extern void -BZ2_bsInitWrite ( EState* ); - -extern void -BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 ); - -extern void -BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 ); - - - -/*-- states for decompression. --*/ - -#define BZ_X_IDLE 1 -#define BZ_X_OUTPUT 2 - -#define BZ_X_MAGIC_1 10 -#define BZ_X_MAGIC_2 11 -#define BZ_X_MAGIC_3 12 -#define BZ_X_MAGIC_4 13 -#define BZ_X_BLKHDR_1 14 -#define BZ_X_BLKHDR_2 15 -#define BZ_X_BLKHDR_3 16 -#define BZ_X_BLKHDR_4 17 -#define BZ_X_BLKHDR_5 18 -#define BZ_X_BLKHDR_6 19 -#define BZ_X_BCRC_1 20 -#define BZ_X_BCRC_2 21 -#define BZ_X_BCRC_3 22 -#define BZ_X_BCRC_4 23 -#define BZ_X_RANDBIT 24 -#define BZ_X_ORIGPTR_1 25 -#define BZ_X_ORIGPTR_2 26 -#define BZ_X_ORIGPTR_3 27 -#define BZ_X_MAPPING_1 28 -#define BZ_X_MAPPING_2 29 -#define BZ_X_SELECTOR_1 30 -#define BZ_X_SELECTOR_2 31 -#define BZ_X_SELECTOR_3 32 -#define BZ_X_CODING_1 33 -#define BZ_X_CODING_2 34 -#define BZ_X_CODING_3 35 -#define BZ_X_MTF_1 36 -#define BZ_X_MTF_2 37 -#define BZ_X_MTF_3 38 -#define BZ_X_MTF_4 39 -#define BZ_X_MTF_5 40 -#define BZ_X_MTF_6 41 -#define BZ_X_ENDHDR_2 42 -#define BZ_X_ENDHDR_3 43 -#define BZ_X_ENDHDR_4 44 -#define BZ_X_ENDHDR_5 45 -#define BZ_X_ENDHDR_6 46 -#define BZ_X_CCRC_1 47 -#define BZ_X_CCRC_2 48 -#define BZ_X_CCRC_3 49 -#define BZ_X_CCRC_4 50 - - - -/*-- Constants for the fast MTF decoder. --*/ - -#define MTFA_SIZE 4096 -#define MTFL_SIZE 16 - - - -/*-- Structure holding all the decompression-side stuff. --*/ - -typedef - struct { - /* pointer back to the struct bz_stream */ - bz_stream* strm; - - /* state indicator for this stream */ - Int32 state; - - /* for doing the final run-length decoding */ - UChar state_out_ch; - Int32 state_out_len; - Bool blockRandomised; - BZ_RAND_DECLS; - - /* the buffer for bit stream reading */ - UInt32 bsBuff; - Int32 bsLive; - - /* misc administratium */ - Int32 blockSize100k; - Bool smallDecompress; - Int32 currBlockNo; - Int32 verbosity; - - /* for undoing the Burrows-Wheeler transform */ - Int32 origPtr; - UInt32 tPos; - Int32 k0; - Int32 unzftab[256]; - Int32 nblock_used; - Int32 cftab[257]; - Int32 cftabCopy[257]; - - /* for undoing the Burrows-Wheeler transform (FAST) */ - UInt32 *tt; - - /* for undoing the Burrows-Wheeler transform (SMALL) */ - UInt16 *ll16; - UChar *ll4; - - /* stored and calculated CRCs */ - UInt32 storedBlockCRC; - UInt32 storedCombinedCRC; - UInt32 calculatedBlockCRC; - UInt32 calculatedCombinedCRC; - - /* map of bytes used in block */ - Int32 nInUse; - Bool inUse[256]; - Bool inUse16[16]; - UChar seqToUnseq[256]; - - /* for decoding the MTF values */ - UChar mtfa [MTFA_SIZE]; - Int32 mtfbase[256 / MTFL_SIZE]; - UChar selector [BZ_MAX_SELECTORS]; - UChar selectorMtf[BZ_MAX_SELECTORS]; - UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - - Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 minLens[BZ_N_GROUPS]; - - /* save area for scalars in the main decompress code */ - Int32 save_i; - Int32 save_j; - Int32 save_t; - Int32 save_alphaSize; - Int32 save_nGroups; - Int32 save_nSelectors; - Int32 save_EOB; - Int32 save_groupNo; - Int32 save_groupPos; - Int32 save_nextSym; - Int32 save_nblockMAX; - Int32 save_nblock; - Int32 save_es; - Int32 save_N; - Int32 save_curr; - Int32 save_zt; - Int32 save_zn; - Int32 save_zvec; - Int32 save_zj; - Int32 save_gSel; - Int32 save_gMinlen; - Int32* save_gLimit; - Int32* save_gBase; - Int32* save_gPerm; - - } - DState; - - - -/*-- Macros for decompression. --*/ - -#define BZ_GET_FAST(cccc) \ - /* c_tPos is unsigned, hence test < 0 is pointless. */ \ - if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \ - s->tPos = s->tt[s->tPos]; \ - cccc = (UChar)(s->tPos & 0xff); \ - s->tPos >>= 8; - -#define BZ_GET_FAST_C(cccc) \ - /* c_tPos is unsigned, hence test < 0 is pointless. */ \ - if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \ - c_tPos = c_tt[c_tPos]; \ - cccc = (UChar)(c_tPos & 0xff); \ - c_tPos >>= 8; - -#define SET_LL4(i,n) \ - { if (((i) & 0x1) == 0) \ - s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \ - s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \ - } - -#define GET_LL4(i) \ - ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF) - -#define SET_LL(i,n) \ - { s->ll16[i] = (UInt16)(n & 0x0000ffff); \ - SET_LL4(i, n >> 16); \ - } - -#define GET_LL(i) \ - (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16)) - -#define BZ_GET_SMALL(cccc) \ - /* c_tPos is unsigned, hence test < 0 is pointless. */ \ - if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \ - cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \ - s->tPos = GET_LL(s->tPos); - - -/*-- externs for decompression. --*/ - -extern Int32 -BZ2_indexIntoF ( Int32, Int32* ); - -extern Int32 -BZ2_decompress ( DState* ); - -extern void -BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*, - Int32, Int32, Int32 ); - - -#endif - - -/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/ - -#ifdef BZ_NO_STDIO -#ifndef NULL -#define NULL 0 -#endif -#endif - - -/*-------------------------------------------------------------*/ -/*--- end bzlib_private.h ---*/ -/*-------------------------------------------------------------*/ diff --git a/android/jni/cn_reactnative_modules_update_DownloadTask.h b/android/jni/cn_reactnative_modules_update_DownloadTask.h index 0da7e9e..b4b8771 100644 --- a/android/jni/cn_reactnative_modules_update_DownloadTask.h +++ b/android/jni/cn_reactnative_modules_update_DownloadTask.h @@ -7,14 +7,6 @@ #ifdef __cplusplus extern "C" { #endif -/* - * Class: cn_reactnative_modules_update_DownloadTask - * Method: bsdiffPatch - * Signature: ([B[B)[B - */ -JNIEXPORT jbyteArray JNICALL Java_cn_reactnative_modules_update_DownloadTask_bsdiffPatch - (JNIEnv *, jclass, jbyteArray, jbyteArray); - /* * Class: cn_reactnative_modules_update_DownloadTask * Method: hdiffPatch diff --git a/android/jni/compress.c b/android/jni/compress.c deleted file mode 100644 index caf7696..0000000 --- a/android/jni/compress.c +++ /dev/null @@ -1,672 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Compression machinery (not incl block sorting) ---*/ -/*--- compress.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -/* CHANGES - 0.9.0 -- original version. - 0.9.0a/b -- no changes in this file. - 0.9.0c -- changed setting of nGroups in sendMTFValues() - so as to do a bit better on small files -*/ - -#include "bzlib_private.h" - - -/*---------------------------------------------------*/ -/*--- Bit stream I/O ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -void BZ2_bsInitWrite ( EState* s ) -{ - s->bsLive = 0; - s->bsBuff = 0; -} - - -/*---------------------------------------------------*/ -static -void bsFinishWrite ( EState* s ) -{ - while (s->bsLive > 0) { - s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24); - s->numZ++; - s->bsBuff <<= 8; - s->bsLive -= 8; - } -} - - -/*---------------------------------------------------*/ -#define bsNEEDW(nz) \ -{ \ - while (s->bsLive >= 8) { \ - s->zbits[s->numZ] \ - = (UChar)(s->bsBuff >> 24); \ - s->numZ++; \ - s->bsBuff <<= 8; \ - s->bsLive -= 8; \ - } \ -} - - -/*---------------------------------------------------*/ -static -__inline__ -void bsW ( EState* s, Int32 n, UInt32 v ) -{ - bsNEEDW ( n ); - s->bsBuff |= (v << (32 - s->bsLive - n)); - s->bsLive += n; -} - - -/*---------------------------------------------------*/ -static -void bsPutUInt32 ( EState* s, UInt32 u ) -{ - bsW ( s, 8, (u >> 24) & 0xffL ); - bsW ( s, 8, (u >> 16) & 0xffL ); - bsW ( s, 8, (u >> 8) & 0xffL ); - bsW ( s, 8, u & 0xffL ); -} - - -/*---------------------------------------------------*/ -static -void bsPutUChar ( EState* s, UChar c ) -{ - bsW( s, 8, (UInt32)c ); -} - - -/*---------------------------------------------------*/ -/*--- The back end proper ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -static -void makeMaps_e ( EState* s ) -{ - Int32 i; - s->nInUse = 0; - for (i = 0; i < 256; i++) - if (s->inUse[i]) { - s->unseqToSeq[i] = s->nInUse; - s->nInUse++; - } -} - - -/*---------------------------------------------------*/ -static -void generateMTFValues ( EState* s ) -{ - UChar yy[256]; - Int32 i, j; - Int32 zPend; - Int32 wr; - Int32 EOB; - - /* - After sorting (eg, here), - s->arr1 [ 0 .. s->nblock-1 ] holds sorted order, - and - ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] - holds the original block data. - - The first thing to do is generate the MTF values, - and put them in - ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ]. - Because there are strictly fewer or equal MTF values - than block values, ptr values in this area are overwritten - with MTF values only when they are no longer needed. - - The final compressed bitstream is generated into the - area starting at - (UChar*) (&((UChar*)s->arr2)[s->nblock]) - - These storage aliases are set up in bzCompressInit(), - except for the last one, which is arranged in - compressBlock(). - */ - UInt32* ptr = s->ptr; - UChar* block = s->block; - UInt16* mtfv = s->mtfv; - - makeMaps_e ( s ); - EOB = s->nInUse+1; - - for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0; - - wr = 0; - zPend = 0; - for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i; - - for (i = 0; i < s->nblock; i++) { - UChar ll_i; - AssertD ( wr <= i, "generateMTFValues(1)" ); - j = ptr[i]-1; if (j < 0) j += s->nblock; - ll_i = s->unseqToSeq[block[j]]; - AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" ); - - if (yy[0] == ll_i) { - zPend++; - } else { - - if (zPend > 0) { - zPend--; - while (True) { - if (zPend & 1) { - mtfv[wr] = BZ_RUNB; wr++; - s->mtfFreq[BZ_RUNB]++; - } else { - mtfv[wr] = BZ_RUNA; wr++; - s->mtfFreq[BZ_RUNA]++; - } - if (zPend < 2) break; - zPend = (zPend - 2) / 2; - }; - zPend = 0; - } - { - register UChar rtmp; - register UChar* ryy_j; - register UChar rll_i; - rtmp = yy[1]; - yy[1] = yy[0]; - ryy_j = &(yy[1]); - rll_i = ll_i; - while ( rll_i != rtmp ) { - register UChar rtmp2; - ryy_j++; - rtmp2 = rtmp; - rtmp = *ryy_j; - *ryy_j = rtmp2; - }; - yy[0] = rtmp; - j = ryy_j - &(yy[0]); - mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++; - } - - } - } - - if (zPend > 0) { - zPend--; - while (True) { - if (zPend & 1) { - mtfv[wr] = BZ_RUNB; wr++; - s->mtfFreq[BZ_RUNB]++; - } else { - mtfv[wr] = BZ_RUNA; wr++; - s->mtfFreq[BZ_RUNA]++; - } - if (zPend < 2) break; - zPend = (zPend - 2) / 2; - }; - zPend = 0; - } - - mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++; - - s->nMTF = wr; -} - - -/*---------------------------------------------------*/ -#define BZ_LESSER_ICOST 0 -#define BZ_GREATER_ICOST 15 - -static -void sendMTFValues ( EState* s ) -{ - Int32 v, t, i, j, gs, ge, totc, bt, bc, iter; - Int32 nSelectors, alphaSize, minLen, maxLen, selCtr; - Int32 nGroups, nBytes; - - /*-- - UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - is a global since the decoder also needs it. - - Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - are also globals only used in this proc. - Made global to keep stack frame size small. - --*/ - - - UInt16 cost[BZ_N_GROUPS]; - Int32 fave[BZ_N_GROUPS]; - - UInt16* mtfv = s->mtfv; - - if (s->verbosity >= 3) - VPrintf3( " %d in block, %d after MTF & 1-2 coding, " - "%d+2 syms in use\n", - s->nblock, s->nMTF, s->nInUse ); - - alphaSize = s->nInUse+2; - for (t = 0; t < BZ_N_GROUPS; t++) - for (v = 0; v < alphaSize; v++) - s->len[t][v] = BZ_GREATER_ICOST; - - /*--- Decide how many coding tables to use ---*/ - AssertH ( s->nMTF > 0, 3001 ); - if (s->nMTF < 200) nGroups = 2; else - if (s->nMTF < 600) nGroups = 3; else - if (s->nMTF < 1200) nGroups = 4; else - if (s->nMTF < 2400) nGroups = 5; else - nGroups = 6; - - /*--- Generate an initial set of coding tables ---*/ - { - Int32 nPart, remF, tFreq, aFreq; - - nPart = nGroups; - remF = s->nMTF; - gs = 0; - while (nPart > 0) { - tFreq = remF / nPart; - ge = gs-1; - aFreq = 0; - while (aFreq < tFreq && ge < alphaSize-1) { - ge++; - aFreq += s->mtfFreq[ge]; - } - - if (ge > gs - && nPart != nGroups && nPart != 1 - && ((nGroups-nPart) % 2 == 1)) { - aFreq -= s->mtfFreq[ge]; - ge--; - } - - if (s->verbosity >= 3) - VPrintf5( " initial group %d, [%d .. %d], " - "has %d syms (%4.1f%%)\n", - nPart, gs, ge, aFreq, - (100.0 * (float)aFreq) / (float)(s->nMTF) ); - - for (v = 0; v < alphaSize; v++) - if (v >= gs && v <= ge) - s->len[nPart-1][v] = BZ_LESSER_ICOST; else - s->len[nPart-1][v] = BZ_GREATER_ICOST; - - nPart--; - gs = ge+1; - remF -= aFreq; - } - } - - /*--- - Iterate up to BZ_N_ITERS times to improve the tables. - ---*/ - for (iter = 0; iter < BZ_N_ITERS; iter++) { - - for (t = 0; t < nGroups; t++) fave[t] = 0; - - for (t = 0; t < nGroups; t++) - for (v = 0; v < alphaSize; v++) - s->rfreq[t][v] = 0; - - /*--- - Set up an auxiliary length table which is used to fast-track - the common case (nGroups == 6). - ---*/ - if (nGroups == 6) { - for (v = 0; v < alphaSize; v++) { - s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v]; - s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v]; - s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v]; - } - } - - nSelectors = 0; - totc = 0; - gs = 0; - while (True) { - - /*--- Set group start & end marks. --*/ - if (gs >= s->nMTF) break; - ge = gs + BZ_G_SIZE - 1; - if (ge >= s->nMTF) ge = s->nMTF-1; - - /*-- - Calculate the cost of this group as coded - by each of the coding tables. - --*/ - for (t = 0; t < nGroups; t++) cost[t] = 0; - - if (nGroups == 6 && 50 == ge-gs+1) { - /*--- fast track the common case ---*/ - register UInt32 cost01, cost23, cost45; - register UInt16 icv; - cost01 = cost23 = cost45 = 0; - -# define BZ_ITER(nn) \ - icv = mtfv[gs+(nn)]; \ - cost01 += s->len_pack[icv][0]; \ - cost23 += s->len_pack[icv][1]; \ - cost45 += s->len_pack[icv][2]; \ - - BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4); - BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9); - BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14); - BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19); - BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24); - BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29); - BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34); - BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39); - BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44); - BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49); - -# undef BZ_ITER - - cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16; - cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16; - cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16; - - } else { - /*--- slow version which correctly handles all situations ---*/ - for (i = gs; i <= ge; i++) { - UInt16 icv = mtfv[i]; - for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv]; - } - } - - /*-- - Find the coding table which is best for this group, - and record its identity in the selector table. - --*/ - bc = 999999999; bt = -1; - for (t = 0; t < nGroups; t++) - if (cost[t] < bc) { bc = cost[t]; bt = t; }; - totc += bc; - fave[bt]++; - s->selector[nSelectors] = bt; - nSelectors++; - - /*-- - Increment the symbol frequencies for the selected table. - --*/ - if (nGroups == 6 && 50 == ge-gs+1) { - /*--- fast track the common case ---*/ - -# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++ - - BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4); - BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9); - BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14); - BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19); - BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24); - BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29); - BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34); - BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39); - BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44); - BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49); - -# undef BZ_ITUR - - } else { - /*--- slow version which correctly handles all situations ---*/ - for (i = gs; i <= ge; i++) - s->rfreq[bt][ mtfv[i] ]++; - } - - gs = ge+1; - } - if (s->verbosity >= 3) { - VPrintf2 ( " pass %d: size is %d, grp uses are ", - iter+1, totc/8 ); - for (t = 0; t < nGroups; t++) - VPrintf1 ( "%d ", fave[t] ); - VPrintf0 ( "\n" ); - } - - /*-- - Recompute the tables based on the accumulated frequencies. - --*/ - /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See - comment in huffman.c for details. */ - for (t = 0; t < nGroups; t++) - BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), - alphaSize, 17 /*20*/ ); - } - - - AssertH( nGroups < 8, 3002 ); - AssertH( nSelectors < 32768 && - nSelectors <= (2 + (900000 / BZ_G_SIZE)), - 3003 ); - - - /*--- Compute MTF values for the selectors. ---*/ - { - UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp; - for (i = 0; i < nGroups; i++) pos[i] = i; - for (i = 0; i < nSelectors; i++) { - ll_i = s->selector[i]; - j = 0; - tmp = pos[j]; - while ( ll_i != tmp ) { - j++; - tmp2 = tmp; - tmp = pos[j]; - pos[j] = tmp2; - }; - pos[0] = tmp; - s->selectorMtf[i] = j; - } - }; - - /*--- Assign actual codes for the tables. --*/ - for (t = 0; t < nGroups; t++) { - minLen = 32; - maxLen = 0; - for (i = 0; i < alphaSize; i++) { - if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; - if (s->len[t][i] < minLen) minLen = s->len[t][i]; - } - AssertH ( !(maxLen > 17 /*20*/ ), 3004 ); - AssertH ( !(minLen < 1), 3005 ); - BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), - minLen, maxLen, alphaSize ); - } - - /*--- Transmit the mapping table. ---*/ - { - Bool inUse16[16]; - for (i = 0; i < 16; i++) { - inUse16[i] = False; - for (j = 0; j < 16; j++) - if (s->inUse[i * 16 + j]) inUse16[i] = True; - } - - nBytes = s->numZ; - for (i = 0; i < 16; i++) - if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0); - - for (i = 0; i < 16; i++) - if (inUse16[i]) - for (j = 0; j < 16; j++) { - if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0); - } - - if (s->verbosity >= 3) - VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes ); - } - - /*--- Now the selectors. ---*/ - nBytes = s->numZ; - bsW ( s, 3, nGroups ); - bsW ( s, 15, nSelectors ); - for (i = 0; i < nSelectors; i++) { - for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1); - bsW(s,1,0); - } - if (s->verbosity >= 3) - VPrintf1( "selectors %d, ", s->numZ-nBytes ); - - /*--- Now the coding tables. ---*/ - nBytes = s->numZ; - - for (t = 0; t < nGroups; t++) { - Int32 curr = s->len[t][0]; - bsW ( s, 5, curr ); - for (i = 0; i < alphaSize; i++) { - while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ }; - while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ }; - bsW ( s, 1, 0 ); - } - } - - if (s->verbosity >= 3) - VPrintf1 ( "code lengths %d, ", s->numZ-nBytes ); - - /*--- And finally, the block data proper ---*/ - nBytes = s->numZ; - selCtr = 0; - gs = 0; - while (True) { - if (gs >= s->nMTF) break; - ge = gs + BZ_G_SIZE - 1; - if (ge >= s->nMTF) ge = s->nMTF-1; - AssertH ( s->selector[selCtr] < nGroups, 3006 ); - - if (nGroups == 6 && 50 == ge-gs+1) { - /*--- fast track the common case ---*/ - UInt16 mtfv_i; - UChar* s_len_sel_selCtr - = &(s->len[s->selector[selCtr]][0]); - Int32* s_code_sel_selCtr - = &(s->code[s->selector[selCtr]][0]); - -# define BZ_ITAH(nn) \ - mtfv_i = mtfv[gs+(nn)]; \ - bsW ( s, \ - s_len_sel_selCtr[mtfv_i], \ - s_code_sel_selCtr[mtfv_i] ) - - BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4); - BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9); - BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14); - BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19); - BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24); - BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29); - BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34); - BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39); - BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44); - BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49); - -# undef BZ_ITAH - - } else { - /*--- slow version which correctly handles all situations ---*/ - for (i = gs; i <= ge; i++) { - bsW ( s, - s->len [s->selector[selCtr]] [mtfv[i]], - s->code [s->selector[selCtr]] [mtfv[i]] ); - } - } - - - gs = ge+1; - selCtr++; - } - AssertH( selCtr == nSelectors, 3007 ); - - if (s->verbosity >= 3) - VPrintf1( "codes %d\n", s->numZ-nBytes ); -} - - -/*---------------------------------------------------*/ -void BZ2_compressBlock ( EState* s, Bool is_last_block ) -{ - if (s->nblock > 0) { - - BZ_FINALISE_CRC ( s->blockCRC ); - s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31); - s->combinedCRC ^= s->blockCRC; - if (s->blockNo > 1) s->numZ = 0; - - if (s->verbosity >= 2) - VPrintf4( " block %d: crc = 0x%08x, " - "combined CRC = 0x%08x, size = %d\n", - s->blockNo, s->blockCRC, s->combinedCRC, s->nblock ); - - BZ2_blockSort ( s ); - } - - s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]); - - /*-- If this is the first block, create the stream header. --*/ - if (s->blockNo == 1) { - BZ2_bsInitWrite ( s ); - bsPutUChar ( s, BZ_HDR_B ); - bsPutUChar ( s, BZ_HDR_Z ); - bsPutUChar ( s, BZ_HDR_h ); - bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) ); - } - - if (s->nblock > 0) { - - bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 ); - bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 ); - bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 ); - - /*-- Now the block's CRC, so it is in a known place. --*/ - bsPutUInt32 ( s, s->blockCRC ); - - /*-- - Now a single bit indicating (non-)randomisation. - As of version 0.9.5, we use a better sorting algorithm - which makes randomisation unnecessary. So always set - the randomised bit to 'no'. Of course, the decoder - still needs to be able to handle randomised blocks - so as to maintain backwards compatibility with - older versions of bzip2. - --*/ - bsW(s,1,0); - - bsW ( s, 24, s->origPtr ); - generateMTFValues ( s ); - sendMTFValues ( s ); - } - - - /*-- If this is the last block, add the stream trailer. --*/ - if (is_last_block) { - - bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 ); - bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 ); - bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 ); - bsPutUInt32 ( s, s->combinedCRC ); - if (s->verbosity >= 2) - VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC ); - bsFinishWrite ( s ); - } -} - - -/*-------------------------------------------------------------*/ -/*--- end compress.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/android/jni/crctable.c b/android/jni/crctable.c deleted file mode 100644 index 1fea7e9..0000000 --- a/android/jni/crctable.c +++ /dev/null @@ -1,104 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Table for doing CRCs ---*/ -/*--- crctable.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - -/*-- - I think this is an implementation of the AUTODIN-II, - Ethernet & FDDI 32-bit CRC standard. Vaguely derived - from code by Rob Warnock, in Section 51 of the - comp.compression FAQ. ---*/ - -UInt32 BZ2_crc32Table[256] = { - - /*-- Ugly, innit? --*/ - - 0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L, - 0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L, - 0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L, - 0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL, - 0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L, - 0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L, - 0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L, - 0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL, - 0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L, - 0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L, - 0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L, - 0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL, - 0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L, - 0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L, - 0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L, - 0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL, - 0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL, - 0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L, - 0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L, - 0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL, - 0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL, - 0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L, - 0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L, - 0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL, - 0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL, - 0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L, - 0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L, - 0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL, - 0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL, - 0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L, - 0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L, - 0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL, - 0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L, - 0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL, - 0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL, - 0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L, - 0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L, - 0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL, - 0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL, - 0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L, - 0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L, - 0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL, - 0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL, - 0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L, - 0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L, - 0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL, - 0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL, - 0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L, - 0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L, - 0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL, - 0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L, - 0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L, - 0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L, - 0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL, - 0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L, - 0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L, - 0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L, - 0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL, - 0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L, - 0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L, - 0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L, - 0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL, - 0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L, - 0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L -}; - - -/*-------------------------------------------------------------*/ -/*--- end crctable.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/android/jni/decompress.c b/android/jni/decompress.c deleted file mode 100644 index 311f566..0000000 --- a/android/jni/decompress.c +++ /dev/null @@ -1,646 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Decompression machinery ---*/ -/*--- decompress.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - - -/*---------------------------------------------------*/ -static -void makeMaps_d ( DState* s ) -{ - Int32 i; - s->nInUse = 0; - for (i = 0; i < 256; i++) - if (s->inUse[i]) { - s->seqToUnseq[s->nInUse] = i; - s->nInUse++; - } -} - - -/*---------------------------------------------------*/ -#define RETURN(rrr) \ - { retVal = rrr; goto save_state_and_return; }; - -#define GET_BITS(lll,vvv,nnn) \ - case lll: s->state = lll; \ - while (True) { \ - if (s->bsLive >= nnn) { \ - UInt32 v; \ - v = (s->bsBuff >> \ - (s->bsLive-nnn)) & ((1 << nnn)-1); \ - s->bsLive -= nnn; \ - vvv = v; \ - break; \ - } \ - if (s->strm->avail_in == 0) RETURN(BZ_OK); \ - s->bsBuff \ - = (s->bsBuff << 8) | \ - ((UInt32) \ - (*((UChar*)(s->strm->next_in)))); \ - s->bsLive += 8; \ - s->strm->next_in++; \ - s->strm->avail_in--; \ - s->strm->total_in_lo32++; \ - if (s->strm->total_in_lo32 == 0) \ - s->strm->total_in_hi32++; \ - } - -#define GET_UCHAR(lll,uuu) \ - GET_BITS(lll,uuu,8) - -#define GET_BIT(lll,uuu) \ - GET_BITS(lll,uuu,1) - -/*---------------------------------------------------*/ -#define GET_MTF_VAL(label1,label2,lval) \ -{ \ - if (groupPos == 0) { \ - groupNo++; \ - if (groupNo >= nSelectors) \ - RETURN(BZ_DATA_ERROR); \ - groupPos = BZ_G_SIZE; \ - gSel = s->selector[groupNo]; \ - gMinlen = s->minLens[gSel]; \ - gLimit = &(s->limit[gSel][0]); \ - gPerm = &(s->perm[gSel][0]); \ - gBase = &(s->base[gSel][0]); \ - } \ - groupPos--; \ - zn = gMinlen; \ - GET_BITS(label1, zvec, zn); \ - while (1) { \ - if (zn > 20 /* the longest code */) \ - RETURN(BZ_DATA_ERROR); \ - if (zvec <= gLimit[zn]) break; \ - zn++; \ - GET_BIT(label2, zj); \ - zvec = (zvec << 1) | zj; \ - }; \ - if (zvec - gBase[zn] < 0 \ - || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \ - RETURN(BZ_DATA_ERROR); \ - lval = gPerm[zvec - gBase[zn]]; \ -} - - -/*---------------------------------------------------*/ -Int32 BZ2_decompress ( DState* s ) -{ - UChar uc; - Int32 retVal; - Int32 minLen, maxLen; - bz_stream* strm = s->strm; - - /* stuff that needs to be saved/restored */ - Int32 i; - Int32 j; - Int32 t; - Int32 alphaSize; - Int32 nGroups; - Int32 nSelectors; - Int32 EOB; - Int32 groupNo; - Int32 groupPos; - Int32 nextSym; - Int32 nblockMAX; - Int32 nblock; - Int32 es; - Int32 N; - Int32 curr; - Int32 zt; - Int32 zn; - Int32 zvec; - Int32 zj; - Int32 gSel; - Int32 gMinlen; - Int32* gLimit; - Int32* gBase; - Int32* gPerm; - - if (s->state == BZ_X_MAGIC_1) { - /*initialise the save area*/ - s->save_i = 0; - s->save_j = 0; - s->save_t = 0; - s->save_alphaSize = 0; - s->save_nGroups = 0; - s->save_nSelectors = 0; - s->save_EOB = 0; - s->save_groupNo = 0; - s->save_groupPos = 0; - s->save_nextSym = 0; - s->save_nblockMAX = 0; - s->save_nblock = 0; - s->save_es = 0; - s->save_N = 0; - s->save_curr = 0; - s->save_zt = 0; - s->save_zn = 0; - s->save_zvec = 0; - s->save_zj = 0; - s->save_gSel = 0; - s->save_gMinlen = 0; - s->save_gLimit = NULL; - s->save_gBase = NULL; - s->save_gPerm = NULL; - } - - /*restore from the save area*/ - i = s->save_i; - j = s->save_j; - t = s->save_t; - alphaSize = s->save_alphaSize; - nGroups = s->save_nGroups; - nSelectors = s->save_nSelectors; - EOB = s->save_EOB; - groupNo = s->save_groupNo; - groupPos = s->save_groupPos; - nextSym = s->save_nextSym; - nblockMAX = s->save_nblockMAX; - nblock = s->save_nblock; - es = s->save_es; - N = s->save_N; - curr = s->save_curr; - zt = s->save_zt; - zn = s->save_zn; - zvec = s->save_zvec; - zj = s->save_zj; - gSel = s->save_gSel; - gMinlen = s->save_gMinlen; - gLimit = s->save_gLimit; - gBase = s->save_gBase; - gPerm = s->save_gPerm; - - retVal = BZ_OK; - - switch (s->state) { - - GET_UCHAR(BZ_X_MAGIC_1, uc); - if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC); - - GET_UCHAR(BZ_X_MAGIC_2, uc); - if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC); - - GET_UCHAR(BZ_X_MAGIC_3, uc) - if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC); - - GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8) - if (s->blockSize100k < (BZ_HDR_0 + 1) || - s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC); - s->blockSize100k -= BZ_HDR_0; - - if (s->smallDecompress) { - s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) ); - s->ll4 = BZALLOC( - ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) - ); - if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR); - } else { - s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) ); - if (s->tt == NULL) RETURN(BZ_MEM_ERROR); - } - - GET_UCHAR(BZ_X_BLKHDR_1, uc); - - if (uc == 0x17) goto endhdr_2; - if (uc != 0x31) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_2, uc); - if (uc != 0x41) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_3, uc); - if (uc != 0x59) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_4, uc); - if (uc != 0x26) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_5, uc); - if (uc != 0x53) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_6, uc); - if (uc != 0x59) RETURN(BZ_DATA_ERROR); - - s->currBlockNo++; - if (s->verbosity >= 2) - VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo ); - - s->storedBlockCRC = 0; - GET_UCHAR(BZ_X_BCRC_1, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_2, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_3, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_4, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - - GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1); - - s->origPtr = 0; - GET_UCHAR(BZ_X_ORIGPTR_1, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - GET_UCHAR(BZ_X_ORIGPTR_2, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - GET_UCHAR(BZ_X_ORIGPTR_3, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - - if (s->origPtr < 0) - RETURN(BZ_DATA_ERROR); - if (s->origPtr > 10 + 100000*s->blockSize100k) - RETURN(BZ_DATA_ERROR); - - /*--- Receive the mapping table ---*/ - for (i = 0; i < 16; i++) { - GET_BIT(BZ_X_MAPPING_1, uc); - if (uc == 1) - s->inUse16[i] = True; else - s->inUse16[i] = False; - } - - for (i = 0; i < 256; i++) s->inUse[i] = False; - - for (i = 0; i < 16; i++) - if (s->inUse16[i]) - for (j = 0; j < 16; j++) { - GET_BIT(BZ_X_MAPPING_2, uc); - if (uc == 1) s->inUse[i * 16 + j] = True; - } - makeMaps_d ( s ); - if (s->nInUse == 0) RETURN(BZ_DATA_ERROR); - alphaSize = s->nInUse+2; - - /*--- Now the selectors ---*/ - GET_BITS(BZ_X_SELECTOR_1, nGroups, 3); - if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR); - GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15); - if (nSelectors < 1) RETURN(BZ_DATA_ERROR); - for (i = 0; i < nSelectors; i++) { - j = 0; - while (True) { - GET_BIT(BZ_X_SELECTOR_3, uc); - if (uc == 0) break; - j++; - if (j >= nGroups) RETURN(BZ_DATA_ERROR); - } - s->selectorMtf[i] = j; - } - - /*--- Undo the MTF values for the selectors. ---*/ - { - UChar pos[BZ_N_GROUPS], tmp, v; - for (v = 0; v < nGroups; v++) pos[v] = v; - - for (i = 0; i < nSelectors; i++) { - v = s->selectorMtf[i]; - tmp = pos[v]; - while (v > 0) { pos[v] = pos[v-1]; v--; } - pos[0] = tmp; - s->selector[i] = tmp; - } - } - - /*--- Now the coding tables ---*/ - for (t = 0; t < nGroups; t++) { - GET_BITS(BZ_X_CODING_1, curr, 5); - for (i = 0; i < alphaSize; i++) { - while (True) { - if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR); - GET_BIT(BZ_X_CODING_2, uc); - if (uc == 0) break; - GET_BIT(BZ_X_CODING_3, uc); - if (uc == 0) curr++; else curr--; - } - s->len[t][i] = curr; - } - } - - /*--- Create the Huffman decoding tables ---*/ - for (t = 0; t < nGroups; t++) { - minLen = 32; - maxLen = 0; - for (i = 0; i < alphaSize; i++) { - if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; - if (s->len[t][i] < minLen) minLen = s->len[t][i]; - } - BZ2_hbCreateDecodeTables ( - &(s->limit[t][0]), - &(s->base[t][0]), - &(s->perm[t][0]), - &(s->len[t][0]), - minLen, maxLen, alphaSize - ); - s->minLens[t] = minLen; - } - - /*--- Now the MTF values ---*/ - - EOB = s->nInUse+1; - nblockMAX = 100000 * s->blockSize100k; - groupNo = -1; - groupPos = 0; - - for (i = 0; i <= 255; i++) s->unzftab[i] = 0; - - /*-- MTF init --*/ - { - Int32 ii, jj, kk; - kk = MTFA_SIZE-1; - for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) { - for (jj = MTFL_SIZE-1; jj >= 0; jj--) { - s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj); - kk--; - } - s->mtfbase[ii] = kk + 1; - } - } - /*-- end MTF init --*/ - - nblock = 0; - GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym); - - while (True) { - - if (nextSym == EOB) break; - - if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) { - - es = -1; - N = 1; - do { - /* Check that N doesn't get too big, so that es doesn't - go negative. The maximum value that can be - RUNA/RUNB encoded is equal to the block size (post - the initial RLE), viz, 900k, so bounding N at 2 - million should guard against overflow without - rejecting any legitimate inputs. */ - if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR); - if (nextSym == BZ_RUNA) es = es + (0+1) * N; else - if (nextSym == BZ_RUNB) es = es + (1+1) * N; - N = N * 2; - GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym); - } - while (nextSym == BZ_RUNA || nextSym == BZ_RUNB); - - es++; - uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ]; - s->unzftab[uc] += es; - - if (s->smallDecompress) - while (es > 0) { - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - s->ll16[nblock] = (UInt16)uc; - nblock++; - es--; - } - else - while (es > 0) { - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - s->tt[nblock] = (UInt32)uc; - nblock++; - es--; - }; - - continue; - - } else { - - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - - /*-- uc = MTF ( nextSym-1 ) --*/ - { - Int32 ii, jj, kk, pp, lno, off; - UInt32 nn; - nn = (UInt32)(nextSym - 1); - - if (nn < MTFL_SIZE) { - /* avoid general-case expense */ - pp = s->mtfbase[0]; - uc = s->mtfa[pp+nn]; - while (nn > 3) { - Int32 z = pp+nn; - s->mtfa[(z) ] = s->mtfa[(z)-1]; - s->mtfa[(z)-1] = s->mtfa[(z)-2]; - s->mtfa[(z)-2] = s->mtfa[(z)-3]; - s->mtfa[(z)-3] = s->mtfa[(z)-4]; - nn -= 4; - } - while (nn > 0) { - s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; - }; - s->mtfa[pp] = uc; - } else { - /* general case */ - lno = nn / MTFL_SIZE; - off = nn % MTFL_SIZE; - pp = s->mtfbase[lno] + off; - uc = s->mtfa[pp]; - while (pp > s->mtfbase[lno]) { - s->mtfa[pp] = s->mtfa[pp-1]; pp--; - }; - s->mtfbase[lno]++; - while (lno > 0) { - s->mtfbase[lno]--; - s->mtfa[s->mtfbase[lno]] - = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1]; - lno--; - } - s->mtfbase[0]--; - s->mtfa[s->mtfbase[0]] = uc; - if (s->mtfbase[0] == 0) { - kk = MTFA_SIZE-1; - for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) { - for (jj = MTFL_SIZE-1; jj >= 0; jj--) { - s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj]; - kk--; - } - s->mtfbase[ii] = kk + 1; - } - } - } - } - /*-- end uc = MTF ( nextSym-1 ) --*/ - - s->unzftab[s->seqToUnseq[uc]]++; - if (s->smallDecompress) - s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else - s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]); - nblock++; - - GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym); - continue; - } - } - - /* Now we know what nblock is, we can do a better sanity - check on s->origPtr. - */ - if (s->origPtr < 0 || s->origPtr >= nblock) - RETURN(BZ_DATA_ERROR); - - /*-- Set up cftab to facilitate generation of T^(-1) --*/ - /* Check: unzftab entries in range. */ - for (i = 0; i <= 255; i++) { - if (s->unzftab[i] < 0 || s->unzftab[i] > nblock) - RETURN(BZ_DATA_ERROR); - } - /* Actually generate cftab. */ - s->cftab[0] = 0; - for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1]; - for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1]; - /* Check: cftab entries in range. */ - for (i = 0; i <= 256; i++) { - if (s->cftab[i] < 0 || s->cftab[i] > nblock) { - /* s->cftab[i] can legitimately be == nblock */ - RETURN(BZ_DATA_ERROR); - } - } - /* Check: cftab entries non-descending. */ - for (i = 1; i <= 256; i++) { - if (s->cftab[i-1] > s->cftab[i]) { - RETURN(BZ_DATA_ERROR); - } - } - - s->state_out_len = 0; - s->state_out_ch = 0; - BZ_INITIALISE_CRC ( s->calculatedBlockCRC ); - s->state = BZ_X_OUTPUT; - if (s->verbosity >= 2) VPrintf0 ( "rt+rld" ); - - if (s->smallDecompress) { - - /*-- Make a copy of cftab, used in generation of T --*/ - for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i]; - - /*-- compute the T vector --*/ - for (i = 0; i < nblock; i++) { - uc = (UChar)(s->ll16[i]); - SET_LL(i, s->cftabCopy[uc]); - s->cftabCopy[uc]++; - } - - /*-- Compute T^(-1) by pointer reversal on T --*/ - i = s->origPtr; - j = GET_LL(i); - do { - Int32 tmp = GET_LL(j); - SET_LL(j, i); - i = j; - j = tmp; - } - while (i != s->origPtr); - - s->tPos = s->origPtr; - s->nblock_used = 0; - if (s->blockRandomised) { - BZ_RAND_INIT_MASK; - BZ_GET_SMALL(s->k0); s->nblock_used++; - BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; - } else { - BZ_GET_SMALL(s->k0); s->nblock_used++; - } - - } else { - - /*-- compute the T^(-1) vector --*/ - for (i = 0; i < nblock; i++) { - uc = (UChar)(s->tt[i] & 0xff); - s->tt[s->cftab[uc]] |= (i << 8); - s->cftab[uc]++; - } - - s->tPos = s->tt[s->origPtr] >> 8; - s->nblock_used = 0; - if (s->blockRandomised) { - BZ_RAND_INIT_MASK; - BZ_GET_FAST(s->k0); s->nblock_used++; - BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; - } else { - BZ_GET_FAST(s->k0); s->nblock_used++; - } - - } - - RETURN(BZ_OK); - - - - endhdr_2: - - GET_UCHAR(BZ_X_ENDHDR_2, uc); - if (uc != 0x72) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_3, uc); - if (uc != 0x45) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_4, uc); - if (uc != 0x38) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_5, uc); - if (uc != 0x50) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_6, uc); - if (uc != 0x90) RETURN(BZ_DATA_ERROR); - - s->storedCombinedCRC = 0; - GET_UCHAR(BZ_X_CCRC_1, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_2, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_3, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_4, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - - s->state = BZ_X_IDLE; - RETURN(BZ_STREAM_END); - - default: AssertH ( False, 4001 ); - } - - AssertH ( False, 4002 ); - - save_state_and_return: - - s->save_i = i; - s->save_j = j; - s->save_t = t; - s->save_alphaSize = alphaSize; - s->save_nGroups = nGroups; - s->save_nSelectors = nSelectors; - s->save_EOB = EOB; - s->save_groupNo = groupNo; - s->save_groupPos = groupPos; - s->save_nextSym = nextSym; - s->save_nblockMAX = nblockMAX; - s->save_nblock = nblock; - s->save_es = es; - s->save_N = N; - s->save_curr = curr; - s->save_zt = zt; - s->save_zn = zn; - s->save_zvec = zvec; - s->save_zj = zj; - s->save_gSel = gSel; - s->save_gMinlen = gMinlen; - s->save_gLimit = gLimit; - s->save_gBase = gBase; - s->save_gPerm = gPerm; - - return retVal; -} - - -/*-------------------------------------------------------------*/ -/*--- end decompress.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/android/jni/huffman.c b/android/jni/huffman.c deleted file mode 100644 index 2283fdb..0000000 --- a/android/jni/huffman.c +++ /dev/null @@ -1,205 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Huffman coding low-level stuff ---*/ -/*--- huffman.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - -/*---------------------------------------------------*/ -#define WEIGHTOF(zz0) ((zz0) & 0xffffff00) -#define DEPTHOF(zz1) ((zz1) & 0x000000ff) -#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3)) - -#define ADDWEIGHTS(zw1,zw2) \ - (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \ - (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2))) - -#define UPHEAP(z) \ -{ \ - Int32 zz, tmp; \ - zz = z; tmp = heap[zz]; \ - while (weight[tmp] < weight[heap[zz >> 1]]) { \ - heap[zz] = heap[zz >> 1]; \ - zz >>= 1; \ - } \ - heap[zz] = tmp; \ -} - -#define DOWNHEAP(z) \ -{ \ - Int32 zz, yy, tmp; \ - zz = z; tmp = heap[zz]; \ - while (True) { \ - yy = zz << 1; \ - if (yy > nHeap) break; \ - if (yy < nHeap && \ - weight[heap[yy+1]] < weight[heap[yy]]) \ - yy++; \ - if (weight[tmp] < weight[heap[yy]]) break; \ - heap[zz] = heap[yy]; \ - zz = yy; \ - } \ - heap[zz] = tmp; \ -} - - -/*---------------------------------------------------*/ -void BZ2_hbMakeCodeLengths ( UChar *len, - Int32 *freq, - Int32 alphaSize, - Int32 maxLen ) -{ - /*-- - Nodes and heap entries run from 1. Entry 0 - for both the heap and nodes is a sentinel. - --*/ - Int32 nNodes, nHeap, n1, n2, i, j, k; - Bool tooLong; - - Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ]; - Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ]; - Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; - - for (i = 0; i < alphaSize; i++) - weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8; - - while (True) { - - nNodes = alphaSize; - nHeap = 0; - - heap[0] = 0; - weight[0] = 0; - parent[0] = -2; - - for (i = 1; i <= alphaSize; i++) { - parent[i] = -1; - nHeap++; - heap[nHeap] = i; - UPHEAP(nHeap); - } - - AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 ); - - while (nHeap > 1) { - n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); - n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); - nNodes++; - parent[n1] = parent[n2] = nNodes; - weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]); - parent[nNodes] = -1; - nHeap++; - heap[nHeap] = nNodes; - UPHEAP(nHeap); - } - - AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 ); - - tooLong = False; - for (i = 1; i <= alphaSize; i++) { - j = 0; - k = i; - while (parent[k] >= 0) { k = parent[k]; j++; } - len[i-1] = j; - if (j > maxLen) tooLong = True; - } - - if (! tooLong) break; - - /* 17 Oct 04: keep-going condition for the following loop used - to be 'i < alphaSize', which missed the last element, - theoretically leading to the possibility of the compressor - looping. However, this count-scaling step is only needed if - one of the generated Huffman code words is longer than - maxLen, which up to and including version 1.0.2 was 20 bits, - which is extremely unlikely. In version 1.0.3 maxLen was - changed to 17 bits, which has minimal effect on compression - ratio, but does mean this scaling step is used from time to - time, enough to verify that it works. - - This means that bzip2-1.0.3 and later will only produce - Huffman codes with a maximum length of 17 bits. However, in - order to preserve backwards compatibility with bitstreams - produced by versions pre-1.0.3, the decompressor must still - handle lengths of up to 20. */ - - for (i = 1; i <= alphaSize; i++) { - j = weight[i] >> 8; - j = 1 + (j / 2); - weight[i] = j << 8; - } - } -} - - -/*---------------------------------------------------*/ -void BZ2_hbAssignCodes ( Int32 *code, - UChar *length, - Int32 minLen, - Int32 maxLen, - Int32 alphaSize ) -{ - Int32 n, vec, i; - - vec = 0; - for (n = minLen; n <= maxLen; n++) { - for (i = 0; i < alphaSize; i++) - if (length[i] == n) { code[i] = vec; vec++; }; - vec <<= 1; - } -} - - -/*---------------------------------------------------*/ -void BZ2_hbCreateDecodeTables ( Int32 *limit, - Int32 *base, - Int32 *perm, - UChar *length, - Int32 minLen, - Int32 maxLen, - Int32 alphaSize ) -{ - Int32 pp, i, j, vec; - - pp = 0; - for (i = minLen; i <= maxLen; i++) - for (j = 0; j < alphaSize; j++) - if (length[j] == i) { perm[pp] = j; pp++; }; - - for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0; - for (i = 0; i < alphaSize; i++) base[length[i]+1]++; - - for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1]; - - for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0; - vec = 0; - - for (i = minLen; i <= maxLen; i++) { - vec += (base[i+1] - base[i]); - limit[i] = vec-1; - vec <<= 1; - } - for (i = minLen + 1; i <= maxLen; i++) - base[i] = ((limit[i-1] + 1) << 1) - base[i]; -} - - -/*-------------------------------------------------------------*/ -/*--- end huffman.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/android/jni/randtable.c b/android/jni/randtable.c deleted file mode 100644 index 6d62459..0000000 --- a/android/jni/randtable.c +++ /dev/null @@ -1,84 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Table for randomising repetitive blocks ---*/ -/*--- randtable.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - - -/*---------------------------------------------*/ -Int32 BZ2_rNums[512] = { - 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, - 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, - 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, - 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, - 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, - 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, - 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, - 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, - 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, - 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, - 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, - 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, - 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, - 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, - 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, - 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, - 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, - 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, - 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, - 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, - 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, - 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, - 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, - 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, - 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, - 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, - 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, - 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, - 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, - 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, - 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, - 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, - 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, - 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, - 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, - 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, - 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, - 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, - 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, - 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, - 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, - 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, - 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, - 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, - 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, - 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, - 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, - 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, - 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, - 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, - 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, - 936, 638 -}; - - -/*-------------------------------------------------------------*/ -/*--- end randtable.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/android/lib/arm64-v8a/librnupdate.so b/android/lib/arm64-v8a/librnupdate.so index 02b4eb362c107dadd7986b5e2096620138447e01..e05f95976a860a6131b155cf3f0e9c03a8a67604 100755 GIT binary patch delta 4108 zcmbtXeRNdC6`z^6EFl8>m1F}A$tHXV5h0a8NlRgy0;WJMaHxd}k^s?E1Az#w0*6>j zJr!unWw zzdLj1zI$ih&iY@s_&=trlU<|>F~l1Ik~NF?9vWI^pB~W_5<(3^KCNh#Ga~lN84+G# z6N~T))jUbdd9~)eT63Plwul>IqVM$2oXnJ zz9KWeB7Tjg%{XoyFAlV~?U;W)?O0x6R`B4T+W#rNJJ1p$%aHECu4cb8P}(|~x|ur? z2i=Yqk7h%A0IeH$v_6>VLQlT81Txmr3AvxJ zKC#Cb?nnb9Ifl=d`vBsJ;j2u(e+)m-+-6xZ{6do-4qmQLRHUoq9));gCN!ITUJO6n zbTl!B_nN$aW+a6SnUnil$*y~RnQf@_{Js0*f8mS9vadoY*m)ojrIe5vNT3TIGPw%Z9&Bfoa zrMngpQUQP2%9isZ7e8&A)?4a1&n5U!iG;hhzq))Vy`kp_7k|QD*f|~J(mjd%p#6{T zEcogVeE?b-Aq(OKhPp zdj|2fFmFdt>rqGOsADfuGSuK}2ygh?B(^=wl4SZe@Qn`ZC{9%dSp8n&?{<;bjIb)L3#YS2&i{eU-ndpkEHQLV?`%snphdN9fq_tMdr`Xu!2ZUb11#LkGbHHS$Pk z$^KdyqO{2|u=}WoY{9`0Oh2LCswkN0V2kogq0t@8C~vEoTEe`1P$HvQ8a*@3wMw^k!i4_FXm=^%%vjlfqs%Ps8Ke*%klhkLQy*1+NujIzYm zz_QPmF?YdLp~n&LJ86kz0d4?Oj29l76mXr|M&o{3Qd+ub{z4DG_Qi{~X9|8>Fu1s2 z-qVA}l$Ms1@`m$2DN9D&88}9@0U@%{&wE>lIly}0a^Rc>A+`cXzazvcU=i>R@X&4{ z1~Nk8_6RWnxT#TyrNFJg3Sc8}D=-K=1ibmK5Z?f^_X?4K<8yeQ5TiAGtXt5T4kD`w z4uDgE6~Jm>J@DLqH~=Obz{0?aLs%GJ-zmp24_FLb2&@FI0{VfQfL%`saTK`ftPod# z+3iB4;Ae0ta0GBf2VS&OGCq{(EC*q^B}5glID`c|@p%_Ati^8$QO$Vj#SGroVzEv@ zo=(;C#TR>8i_z`Bldrp&5nq9>f2R;Zss?7h4=TSwh(17)*R_{@16z*}3>k>$IW(Er zIdaPP994({l7g0i)K>1|@t1pAWi{$|@yyGakIRC1knrdazr4aN1#bs$m(xv=UMj%H zf&X9YORgUFuDki!OBq&K(>uG31!Y;2_s9iPWo4J6a*@Cyo~7f_2G8p*_e`CGt}He_ zb$3M$k(;2gQ4UG3LiZeojD}++^7ZS%+p!O__`{cbcQ+Cu8Ek|XyC5O`ta5|oH}l*p znU7(QkhV|09f^E(xn(3TXDgBXLhzPPzdc@#S!M8i_m#{6jp$|_$6`^xyK=};@ReT( zQET|`j(V=Ykd|pd;q2Fi$dju~Fl))J6|xpGmwjL#4to>j8!o!}+^e0f6F?pQnlHZE zGou*Y>EB@I$=RmJwU&d=2VbP|y;u5K>!DV*2hLs{#LCoVOkKWI^2*KWN?#YF*Tm>M zOx?VCk?W@3(?oR%RH2!hh<_aF@%?7hLkf| zoFIH$I5quw^B$wFGhWk++RelHE8$VhW91))Qyn+VC2=TAq?>MhQfo=sM04!_i|QX4 z{y`Wq8W&dd)csW5N7en)yl?g<>Vm26lj{Dc?u%Y$!{n}X8KYJDk?wS`LnTn*Xx(9> zgPkgG3WHRiY@>r5D!&S?x(~zeCPO8qzkURCyvIzS$EwHM=`e>%sKVj;Bs&&Uc~^LX z=;d}S7Mnyrf0MfP7CTLLsy(N$alGzy(82a8Mz%LLT z6gFG*PaJem{JsCXdc2bki&vYla)v%m>Z(AsGxQbE9coKe&W!jg(vLW4mil`^@+0h2 aeUcNe(BDPVSw7LnyXZ((K=hR^+V{Uawa1D8 literal 70576 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 z zP4e|8rJmJMiZ{t8O^!8rai;y)Okeio8UBQPrKXkk6hmO7P{P88%56y}ypP)7gyDD(o!#K*0Q5;Qi z5|u6g(~}R$zGv_FlCV@fRKDw{`JpQNe7<~W@aKb{8!PGyeVvVs2t)N(@ul;}MtWgb z;9_Wz_wL0*aWD^(_(W?$mjnue)<0g;kVO`DOu!?UkJa*|7rMT{2zqh z*aZFY-oSqK5|PhjZ91VlsP%i-8t;^UJxF>>U!c==Q>Ue554A(MyN-A zmST&a76VhvrFU$51O1bXI-d;Mdei4c1L}|D_*ogG9IRydqj>_^jnaD>8$b4{=84Y4 zzsCBUd4d)A^TM0_6erHL%aO+_e-Ky{@oZ*v%lxe7jwF8ae6|A1N?@n>i1G}3(8oVxepE3t>1@|O9mqUbel&)ydKCM@n;#&@F{qf4azkW$%I=ik zTJz=4$KTOhxpYn};fE_mru98~?7>d1ov>4$n&MfaZ^i#K7u^Nkd$27IIe9`E(J1dW z2-kCBO~NYe?3{{+)tFvbsgJ@+n0Yz4!b*0TaQXzEQvRxkmot9@PF)F{Uc!!Q!nW#x z*3O4j=nJ1OR>Ei(_z)L@kH6Z}lw>pftvJbM3iNU9D<{93Scm%Gkce4{My~6HTQZG_ zH-%MioX$s2E*)k$vB+e)5{9C!P{HSq*M9K&G@R7G3(=J9ZPAtDmrl$Cx{6`jPD8fx#qjqQI`C8(W;(Nj)!yxvfaV*AoqJQP~`!C9`T6twcBlDj?+f@ zG2&mv)s=g35ZhmIU}13F_66UZH6oDAn;Xcx=H4<7%MD-`0Z&g4brM5&;^z3xOjI zUq`!~m;-(A{4Dugs#EdocE(3OjqBI@gQ=A1wfO+^5-P79xvG4E-Oz?|!Ig*a%GONI z`-!&{I{v=aTN16E03Y!(c{8}ttjXWZrAN^g69vg;?No$(Vroh|zG zd^ojPIz&1{ZI=#||9Lg#dF@p@)K=c>r$4!x2ZZj5prigyALX}6S2N%4v`_EcQnNzzYuYXFeqi2J7?YNNtdB*po{~H~jRX(Q|OYr*fn0PCV8BNk9=saJn@cvMCBI9#}+O>q732TwaLYW_gpll4*h66`#U(O zufL={UVqhBN3Wl!zZwVOC^`_`c;nrKOq~f9niD!-o0ENi&ll?*s}UV2R+3DQire(h zK0C%|{qJ*auWrUV+5VE>UYSH2y6*Y%UQWAc)a&zw%1tg)`qjfz7Mxb{&L%1C*olpQnx4KdEiWeNk?O{A|T2+}K2KoCXEe4ll;x*{vQfp3UmfL_6`G z-uAH@57BriXU>h4^e#tjQd_)sB;&dZOh%Iv%X(SSH=)C~kS|(C>xJL)u2LeeT)AHD zlrP>=jO?t8^FOoRjcv$HwOz7Wu_V>2{If%jT+Kyx$_Dcz8zfH)g4>CQbujmt zoa@z{$mv!&ifz3{xu@*&=X#0va>4$;Qik%*)d%s2`X`wyK9j6*<6V*ynvW|8{$I2= znu0yU9EtKPSqsDQlhlsMq5->4@Zgqy0qIcLeA1hmdsSY&m)CWeaZpa=^Vsvs_fihh zA!M!ckCa;|n@2vFn~OG(dNsBg=%sAJ7vnTsmTZlPVl9PMvENDUYiYI5Yf|@g` z#QwR3IivTMmRzm(>_l%GgJI0umrON_ly9f}JLQILWX?TOPu}7mYMMT>)9c8ItY&SP z+z7e$&+x7V<$G{&CXb@izm*H4c9r=5rwqQkK(GNXRhGn}}1Ht)OMiad91xOZ)TmFze- zC$10j!p#Fb%($1NrYzFCABu1HuE)!-bza= zedB-s1$uUQNU~7x`gwMyJ07C-dAC{BlZk%^<%cKai-)b&Z|E&s{u;URX)?vjO-aUi zW1qhd&XOs;<;ezcKc75F#{B#;CG#(0E?hV5Gu2Nd+0~L0pC$wTtlnO7KsL8)XSnj9 zx2%ya$b+xOj5Uiq+?9_n8K(D}D|zQyxyT)vgUjUOm9QR9XTl#&ws$25y_^T-xoO>E z+5Pg<6f0nDx1eI-qDSc~y%Q)KxedLgXJtbwPe;6~_7*?)s3>nKOL=N|oH z=i_H6P9^^`k2Vbo%4Xb%ToXU+!zYt(JF)cLBG$v0v*GQ_8anVN+gT@ccGswi06AB` zKz4UfhU}VluztRHMBr8Qo8+h`v!$D5cgXI>|3eQB2+9tZeRS4l^?1r3)cbsmKOg0+ zsbH+-*EinJZ|%zx`#+6zkAI%n-=El*CH8;1I&nR*zdx}rOYHwtmbjkS-=El*CH8+B z5!U>w>Xd$Uaq$Hkn1_PLx3KPM=uhv<=zVOxAF(?@Z;GLL z_v`(Y!_uYDo%jBObi!KEA93Zs`P~Qd@MPPF{`S$1ZtM#8-3Ha=>HCyu8*$1*4jpC$ z1KDPpcuKzP9Nu*ppKdN%HpnbW$G#ZG``_}xmHQ<+tt@?~sIK4g=`*a%Ijvmlg67(P zAYU2%p5)7kzmxU4?8Ia6qx`;3{8!h%^5dJyZY+rQW6Zm_o=nSXx9Il}ICQ=et)qavj|7wOjrEw0F5gOP*~a%)HzN(OVVtJOg^y+74N)g(UeGA*V$0 zFT(gpeo41V7S<)~3BJLTzt>JDr;q+nx9Cf@|DOY75!XD8*RXF7b>HA3sz=DshR6ReZ_eO$T$8Rpr59(Kab@tYE{1C6sV z(pb8_k!(PJ@cZN&h*o9OCBIX;jPp_1ijMrVqS7aN2k8ysOTtCZG`<~d*#6w=>6x{G z@^)+tVy{89Q?gn-!8*k{T{tfAX|L~>yvfUKJk&( zijY00cbqg|B0Z*<{iEcVX}yd%W7>!u6CLS2?p@e`q9^hEA$Z`0&TmJ~r=uh@ym#63 z?)LNb19&gS@Ax_Gc5xa0XxVevk9wad3ca{%Q49z+LNhZGbfR@jlzY^5gg$*EjdeU^ z>q-`6MmIn=$8GFY`ql&A$XC)kS$n~1x2>G?9NO6ze$5U(#@NgL+=7g1CB``)f9fU5 zuEd{uA75%ezSPEGN?<{DsChnq)Isi>SK+=(GaujSH{d)U-)ROkg`T1`!t_ zN1d_QqnIYSyIn`72A;#_k*^_sWsaQo=8?b9pSEX48MA4_OW!M63k^o0ztCai9pf(f z(nDJn3)HyIV0|s|)9~(iwPJe5=;uLXmT2z<;y51dCDVxKx4Sx&9Aa>hd=VC+L+Nhs z-7m>5HwQ#^PT%Nvz&U28v99(Y;s67j^6~MbdQRn?vh#!Tr;gg`jA5=b7r2v{DC?jG z6?+vAiI4UEmgj4G?GYBr=@35%izCp1-aqTs_|c9n#J0ry9jr}P1<%L7$9ERsOLSv! z0PSkmnpzi|`*pk=KWWTqd(lMp6Ip}D+`R32M~}`azR22RrbM5!cKCK%Q--H6ebRoU z^cEJj$*r<78QH*=EF6kDYmyFPwGbtRqIdcBs zJz&1p6xKz_vy{9J;PW~5Y60t#VKcnQyuk_j9EDF_O2}~5PIuW47c4;>#uM!5M%{jqJe?!9c=^r*kUOk>@ipypRE%{8n)p2->*tgT2)PV1mcP9e9V zyTyx?_Z<3Ayy)?vbbxq8vf88jv%JQ5!Hc_ynYp}~kNhqPz6hTkh2Qkvq?>;8OP7Yq$FSDo_7SVlsmQAlj~111{O-1uMawwuWKGA_>85Kvw5)YdFI}PQ znRWTEG!)IS2XuB&UWocv+UX7Hc6v(&vUrQhsJn5*_lws0GU}?gJynGL+vV`bisjRX z-R^(p(JOyEUDy~aqv6p}|2%!tkmb`Y{l4}m(*w7sKjY)KpT1vW`5Sg4v-W_=e@`<{ zHD(NKs7N#6rI{(=Rb$sqA7dAG{)FH8wSlG;lCi{aPq4jOe_Kxv_={KcTWc~Yrnwng zyjg2qT*S8u?EcPoN=EOAKYcmxiL6^c?sO*WUOdYBsl$2iH4B*_Ss`4twpElI(l0K{ zEZ*SDYM9IKo7t{lyK<3c}PoHM)Jzhe1x zVJ5scR$kHY?pGV1X#nrlwY5#@;N3x7DIFQBHPu!zK75;?p|M`?yALRn{2IobXCwB7 zc;Izx4aE)>&pHaWTJNgW*83RD&GQbf-o+KK?t$Lrf9k#B9_$glcOyGjw$Y3Ac|H4y z8%l1iLT<^naAcQd>MD`hl0ovJrKh@(O_D+KZKR((IV5{DdCp0;iX)4N{Sdoy@;{bg z2h>oWa+5V*x(QjR80=s5{w-~iU#;Bw27DXV-AmHJl0BMBOQ)}zCv$V@vY+-w$2 zWKCP$(ApSyM80(k@>65v#b%@%zeIf-pgqU7q3^mj2ijBY#*5o1)}z>tbe;U? z$bVm+*h&Bag*~lHV~A8M?B1*fZ(KP5-uFLoPmsr~k!6(*K^m_VhmM z-bE=hcMbY#P68LrnF#x)ck-L+z(;Wh#cHBSn1~J(TTqOrHx_dfSZH0^zd4R@9xPlr zaux^01JwVCU?ID88L_L0sgK^3%Xo|o|1uv5f4iU)YSBfRDN ziN?jNo}Vw%Wz(j{`e{9Co9I1)+-6RY z-?tO8=G#_Fo$oT>kKNg`hIJPs_0xO&?AyN`ihY+dQgtt~y^rpFAQa=9M9u9BLa}?f zCr!WWLa`nE&d~2~XgyW-vqG`K+Rq5Z`m%4VC$>jf?RWFeq;ve$9_DLejrgMx?788F z^)H=c>Mqcl9`5&tSUa5Wviu|KuYQenSpR|bSnp>E#o6vhr-b=dJ}M`BTJtwwLUV zKYiaHW;aRKY%xW3k|~;>+Il^-jIG{?>`^|Ba?Mrt$Jhyazf>|V2l>nQ&dRjTr}th% zfY?wwIVtMnTKtXZ*YpncAZ+?O@Zs)Y-ZLlo61eWCFMFMsn%=k9`-!Q+WyDjQyiMd! z_wdYs-eZ*Qr}tdtqx+E;hu2z>$m9RRSqGsNd8~Kzhgq4Kjo5q7LmNA3<2vTlnl+{) zzEklrb|&#Fe6TF^4(pv^8!f|DK7}p$4)blqx1dXGRq8*EZ2H*l$34V!$&G*X${tY|or=I|S`J+SdZ`vm) zrsB%zUC@#8OirPTTJ7TK;T&>Tk)xY<{>96`Q-OTn@gnV?XDx5$I|-eW@fl;ZiJY3? zPth;Rp*x%dtvUVh2UTbL1lE292fnw455)Vic3N~UJRPviD87B2uX}Y}?-S^}`sTb3 z!F_5g-#KWgqCSl=vVI48rVC7WRQ*dy(`3$Xw6YpjUmvR2SUbG@eQbQuBJXrZh2fj% zQ#})Td~maeedO_fY_27~%~%G%O8ptwmvz6ZpH6Jdp}CJ~r(-kYt8DOP;;#&ZKMH$P zm)fBE9;d#!*q4u&nu=RE|Dx5m;WrhbipMWbIv&OGz@+0592X=VU(RuE(s6*}?4;vM zIZjVHF6B5i>G)!f`998>`Ui5{RZ@QDxParGNyoVy??^h%=6GAuaXQDZBps)6yxu+D z1Ycc|u=Qo%KNjXZ_|L>=k?hcV%q~BqMaB2&BfeD;$w+Sq-spaFCwL=zg0=qqoL{B6 z1=iRb_J@&+6&r}K4mZD>+8vqOkC+VpDfXP=&03R1^G~u{_h5@Xg>TcwoUPVQR-8~V zL%y>(@(6aG{E1&;lgpRTc=27he4Upp@$H*CzvX=wkd{~75^`4>;u&cVM(Z&3LvTkAQW@iXv6Z)Yi56#$E(Je4*)Df|iDW-Q-%pc`>c4=0AU!5q zU+dJ$N6>ug#xKz~WU!Zq@oVfj;_yx$hV+hdHm3B%3;&iJhm~K{cb$6WBS2%9U~~8O zP2`Wr|M2WA`7+Y|ZhMpaZ8H}+uld$f<{V-afn1f}uWKgvihha7L?e{ni5(tXGN)uN8rUn6_=6?vxV;|Y~i~K z^3jK*vl|m@YYbs+4fAsU@Xj>8C$lZZ`TpykovfRIylNk2M*3F~lSHNsv9@0C2eUwK zzi>%uY1fbhX37g|teoihKaIC!HP7RH7@c!tFX_Q3vMw{W?1Ra*b>%N*WHlVTd17dtb7$?`#gl3;Tb#jfeS2ji&-^pbU>`&ur#+Rlr*iBnr#%7M6Qn&E=vmRU z;%4%NOKC^r^iV~F?~rWadleIhnvq(MHJw;gfH>3^z9s8_D7|=w?XMdLJ+HTKLthjH zv$1m{U*Vf}v}@fsVu!TxGQI^<2^JgqZc!cU*$3!HC3C8gqEIvQX2I3!JMG&*T^p%O zHbjJRj1FGj95_8eHd<}~I>eW9zFijK+hx$vH2KSsBEC1kH;Itfm5tOV-d1dGFPm)W zgXoE#FY!%Bas#zy=`rF7?a+94=J<$m1YgCz;hhcU#cu04nZ|bk;aM;CEuMGtZuuT2 zxST*2xH2Cb4lGYOaRe`Sz|F^T{jdVry1{kW{hF)u<~B92>BUIC=j0#fIPV=NUzbd| zl(Cge@nXI50g}s+%<<+(lXJBuP^NMkct@6aV;a29{0p*8<>)@iIM07jnP+m=>)jZZ zSEh8V>T~r?KK)J&DsHT@gpbPGi(RVn+!)MRzeMvdcOQ1+%wFBe_j+ZjohmoE{d!h0 z9?4r5N8vpvXzh;|>b+&zw?m?emy<){*mIst*BEL{6LG&`lQ`l;*Oz}qbLG?K}ql<<4XTe(i z^KeidN0FEAT)pCSnbE6b@j~yqlN0b;a%iDheIrBTqB^xk(8v5f=EU|?H!)4*rpor{ z#vAJ+PWzSn;?CPCt{0e;GEH@>Ud_=dNA(Hnb>tqln|P}Qdtx6l582B-e!k0)5uAHt zsJxQ6`9@^kW0M|f-gNAHAM~xA*Yq1JJ=nMQ@}|co-2nflp z$%Ke_^<(&7zLt1fbK)LzbMMz)pNfn?d1Et!9TvhVp8<=&Ynmva1+-S|RUK=RPTLNZYD zumg+~Z;~vO4AgvHV=p=A;pAb1-2rW;JNA$;Qfy23oGTCg=ziHc1;Lr%#CxK_5__VP zi>vWhj9s~+vh@@PQ9Mtv2ig1YVe7<+gD7W0JoW>=9e0R0fb7geshOFIvq)amEh)KG z`JIZN`~)9iA7iK7(<1JhO>V4>K3!(|)I~3mFJL>qz+rgfLjHh!fkzX*KyM#FcE9X= z`2zodFCZU4IS)TcW6mF5P@by36(YNTyEn(Fc>;2kWdF%7*IHQ0W$@+(l5_2Z@j?3K z%ndLe?p$Xd=9MJ(G#8%D8odLW6ysD}vo6DooXmWIH&=koFs=7GSp@5ywX!zg4^(BJ z$=9yyM4v04tcut!&*fIR`Py~E9edxMhd(=~h>Srdxw%l}%Q=2d3h^T^&Nw)zd4ve| ze{xLhymJWfnEV_02^rXQdT*_gd4#W6!87v+o_{cxypX@-A9OH3ApcC61hrxlDI-N?D0^SyDt7mS}7onrTl-iQ8u>U*IdRT2YYF0(TO`6)XK zTXLH6e`}YFT#Qd0z6|?X^AvjShpa!-`?*Rm*?_E1dalWP&dVVe-;383|2g;r^e-|) zyy)eccPHl0w1ylsL;N`vA65Qh7FeeR|Ao0B&*ss4W-80Unese6<>)>~2-avX(?dpB6+NUx0 zYz5V$_6%f9lWj21R`U9m4_$h8#f8e2O`-B#8^LX>qyG~&kL-^)<*YTSb(5JtQBI2T zL4<{JM(_`aqn1SH&aNw0o)zCQtFHPzbFt75JdGcb*;&e%&#+SK(9yYd=-&7{KE7j? zO1!)eaq~3d=YHbo>3qj5BcktyePqm{AzL50Zpd=J8MfSP8e*1T&v!MbyHBt-Kcu{s zu7IDIPii9OlZuZ*9S0bXM!xaIw+hJB%8u^mx864(UI}e;oJqbO-}=J#i;^b=|8On` z*~GWLlvBcYYlty$E{|`gX6d_K*-_T@As)mzu{b-E60IuGloMetazJ{ANc# zVbi;q`%9?f*JJs1ST?eW<4a8QW!dAJ_J4_bSOb0kaLRs+J$&{4ui0PCb-w+ze>BIF z*(@j;(3;ov$G9{#ckU$NDMNBqu&zu0QRS06Uv(Z&j2&$r*M}10-)!56-*_N1)U5Fo?GVe%SU z1MM1U_w>?A=z9`$J`sAK0NvljJkgC2_#g}(4o^Lb{)n(uVY^;tG8-Nn5em$((mUaq z@MsKw?R3Bcp z={KdOYtsr7F0C$|GLEhEk#)C>V=H~+x%uNBd4B$iRbw`-=DKWaVk@0n=~o8zgKbN? z$!G|&RZ`#Z8$-m>oft!x?4~;My7iq(bV`%tguZznA8+kAI>kmFq(n~JR=Aq)8m{aw zTgya;8ec=}CHh|B;GR2t=Bb_h)^{TH9ntTnnx}MMr2ZcjlU=lLX-QegT1yU2dgprj ze0nM08<;XaLix_z+^qkMKP_3*TLzu3_l57E&h$e0at40)MSaGiUMsA*`XhE9yLv%dU>*5?fO6h!$J@l$QS{!Ux9uG5Vi>-jdW@1o86Ugd7uoyGSp z{nQhw|A!v6bEnhJbLmBNB3wp0?fvv`K;BKeXH%Zqc9gaqq3ukjViOp?V^Gwy+nCo{ z!BlIF2(x4S9u029JV(CUhjy@e?O4U{M(jMrf<30y z_A#+Rv~7sbY$kW%aQD!w!tFe#Yx-u+a$+aW`Df2PzZHA>2=6P(2Rp)8jbP7r;-ded zHrQrSGvC1M#^&he{ff1AO;^tk))vKm1Lj=wPAI%GZ|xdm6*Xi~FSNS3-8Uek$P_i` zUC(yxl6Nygu{-TS4XyZEU`=0(&;g0|(AU;_jX@FT2S$(c`(G^cl&O}0tqiCxg{hJ4E5qFQq{v-ahe1be|Nn!8J5wCy;pv~Zg=83&I z;#Ya@AokxD$~nDs3p5X(8S`>!s4)CX&Z$0qZ<944Nr+#E&C%%z~Jjq9{ z6hPPg;g`b5>334YcR~ZhXvYcYY^||7C)#|K_Eu9d1Rr3cU$kLE8@_1At;l;T^z%0M zZeI(amlS8rwx*hq?YD+1eu2$a>+9bl8n^_TZWZ|Kn`Oe|kr8d|J&g3tqaonh%`>K8 z<@D!ix4yZ-H@Y`V2Pm&)7=2pz@Wa=wdw3<=57_=2+xOWXVXME+{BXr}X3@6mpM!?p z^%XYE8Zsih)2U+sV^A2}Jk&&9&0wyY@1d@Hc-3{pS!3gJ%u~?aNPTDHX{XMTsQNz1 zcIkM%GX@3G(@Sp$quapht6)}*48ApT>PMj%SUSAbY7dBhnY_6!#^Gy}!*iRDV|*+}w)kn|7~|_~hraK@wh^Bmr4C`%pLzza^My~?7nQv}6dt^Vc!$s5 zX|Ro>&}f}6pYh1-{Pv1fYsNAT8Uyf&R?(IS_crp(Q{We{3Y7=k8M(#8w!y!V!7e5< z`MqT*IC6fiFRybKIdehim)L5oBsbK>yZ6=WUkF74merCDPmkf;I{5k85o^{=w2NCB zr<4B%9Sybp4dYEQ@oIRS7=vVo%21mFR&hfFxiHE0w{&1@tfy|>FWL98LvLFDqa;X9 z=2PpC5AA88*h*wmglETCg`I|Ri%=H&qe1nlozF1`D2&Bx`o5$v?0`?z$5QS;y_A^h zl$*f&MsUA@F&-Z|Nn9XqyYh4IzsH|O_C-(sd%O?~HtToBf5ZzlX6Nu-bz!)bd;g5@ z&`aH!2~<79lax7(|5Asd8VQUUJ(KQ-`A4g9n9@fFt%fp>Q1 zg({HMhsQyql6~KVXC8!SmNDKn4?lXHz9sx|UuYK@Df)fSsk0=i_IEG_!g8i7x8NC9 zUmm}GT%=|C6EQeR9@AKf5LEw|l`vwz@)e`8c2wOu;B;9Xf;+6Ci*Dewd1}&@eIq0R<_>f5% zof92Cbaj}YxKJy!-$vZXvaE(nC{z6F=`oe9I=u4z{2pR`09phRJNsF}W1vCss^mbB@Wim`6^;WH#rRT#R|-OiX5Tj>*-SM@~g0 zTU7I%Qg-d)kR*qaFL(gK)kc6z?9GQZ1Z|_8!^)p-$+Hq_CeOBAq)NJHvISTzOZM1 z{^E9YB6&6X)`Q|C-_Ei^G~ zip|i-%h=)J!1_YXnIhK)a9<(zTnRcvdCz(H=>4(L3Zf^_yL_8G(t(^V#kSswjzFdc zE%caT#C~M5Y*M}uAIo&~h+9_gaxUUoJttjr1UjEBT|+ER@^P#yAF=Bu(f5g9Faa!X zLf_mNQM@sZ{~)@p`lI}d6k;9OT^+m(a2J?#95Fv{HyJJ4qmTZ{|Inmo__iPOA|{%DdSb)#H<`_oto(*{`p(z_VLPD%x{RNrAFGSkoUwM<6lCC4X0N!B>J zy8h0d*}lRS>ANB5>{2VQA&>s^4oI}Min)HS@8p`k6`?WMH6avR#r@-mV>>M;1ndT0DGO{s2Dp6C=WA73W3!!p6g-wcLz+fb);r1HmM(Wriv4Y@?iS zg9r2L(G>coz0Qw6=wjlx@;0;{h*vL5GhG|lcYuNTc@CJ=feGIkk17|g6HMlUNge&E zvj(yiu@$x~1Dm=PtJmxY8+gBEasr#xBh71dBhBW^DT}z?j{U^8CWFmBVyXwgrjvK# z9<>S_8P(nqua@5*unQXU!2CKZt6?SW|FJ!=rNrvrSvcayYcziH4`sKWBu;H{Uk7DRPWwJ0=OR&-Xj$`NYM)m|`mjX%$aBzrG0GU| zl)?LZl%cut?Zo%xw{?7EBCA-Zfp0y-ul+m!=uu&`EKf; z@wL`W_2~9u(Jh!J^R=#@kFU3qqwxTIeZp7d(6FAHVFq=+^Lvkn^ETA*`xH9mtyHsF zu|JELJi5Y>FN5)C`7Qak5?u6+`=8*;bVEaG(?6VwzoxlNJ-^F0s6ljj z&hvxZ=ZX0>s0=-?=h~6?9_@Vy&p$xfJC8yOqtP|+Njow#)*o8D5?M~%zI*ss^2706 zQt?rdeS9A-##~-!{XpLHwEdkE*(=xRBy_vWMpyD&8?tg4{j0tDsWrlQJUUu&iBs@i z2Xfu%U!fV3Q=KQ#Tl?V=%}45Y8@j9w%now>1lMmfMV&Tr#8&uF zyrx*mYp3H+>lx);EwzgpPQo|G(U~_=hWFe)Vz9bL>-KAYyE4^`O6B?-`ZJDL!!^i{ zzE)<#GTuEKx1Dtyl4LXU{)&B_q32b(=C!!5xHH6iSbG0Z_sVYcIW+ByZWm4aijjf- z&h}sF{WVi2epcJZoseJXwq0{yCupnkiXNd4(%EX`M7w{(QnrBAzeVkN`+vr(=TJu# zy!xnB{^dCd-mJ`a+hJI%c^~c2J>>8)FOU)4KwI9U9q7_#*$=;hryX1l-4NMF?#GAF zZ#S5Ven0Z%cfNgwe*1U+`@?@uzcYUSSI{r(V)drq55Yt9dlFt(A8$K{hWq~+4fAf7 zQ^vc{s7J$k?)W7)IR2gJcqug4ADu9EzvLM{1@sQiv0ayhBF=B`;YwJ@z=2VHj5Wuv+wL#Nm;TD#+w1eD+WPl1rA?s#SeYWHvk^& zA65R?G3ZTp$*MHw(y&S95bKbQ+D`myi!Z%Xxd+Bd&p5qwI(F1F?5U~PRa3C9ZXu?A zGcolP$M#a4hZvtz3*O+G#XUamwRwh^^3qgnRVy4%3+;%%V|IA)vQ@knq!?*Ac9-Aw zwUp$hbPXD@YRy~Npe3oHF5dGkQ=EpFDLMrkY{WBbL~l>QON|-u8rQG2@>@FUnM)!5 zaYh?c95fRov1ugErFlZepqy&+1#K!)7loFX4N1 zHQYOZcR5S!L7mKn?ii0PE*YXYmltbXe+#(^X`wLv37=kiBmE?A?Dp~WdmQ~A3pT%U zVuy-X@-9+z>%Z}>TgC(%`H9li#5*MKkf|j*O~ra$!}e7j?Wf|SCS{uN3C1~K4QLs9 zdQ5mWGPg25CR_;pU5O5@Mq z+~2`D)EytGScX@=%KkDm-7&nROyyHg%N*!hHp(RG7)~8N`XIeD{#d+PHpQT0@y!~W z?Y_(g*@+f%Y*=b&hveK{$Tf`>x!Nt>IJJ}ap)nF>$>a1iH0WWjIM_*K$;<@yl?hz; zBWKcS#~84$0$19EZQ0+!`V77an_SqBb}%mN%mJ5s5*Ww9__`H8bZAu=H~y9Q4x>$H zu^n_lY-{$%nI~|^O}JhN(;p*iuRMcmVQ2k5=6z+Svlp(}Rt~Xx)<8(IarU7T@VoLm zIzy2;*rvh~+B&bj9&C@lmfjxU+{yE@)n%V$IJzPuni-d_$Zi=x9aZpzpSFlMXEWYI z!L|e}Yq8z);cfB249sEP5#yZ~{9x#{1Q}Sg;-A)>Kz^OHbI`M_S(g^-k`3>-U3ztG zp#cql{4g1}q6^}-t}Q-t0MGLMnX<{WNAz|8Ie3V%R}Ku{N{g-qAKFo!4$bITJg2rj z*UDTU*Xq~{yS`wewLVrQ=~H1>NIBbmIne6^KUeHm@qmDp-4d{hT2xjYn7Y1C!x`U4 z7|Z{O{%8EPRsR{^+(4Pnu>Cc0 zZy)@vGKAebAG-W}fcu4E701Fb2U)|K=F#oF=uc~(uA-kVhJz9q_H{7)RQx^wzYpS@ zTP{G4!v9@g4m4TZ;J33K9RDIs7C@5@hS?5H7DAJSU?^HVl)%uBPkI(Z(M5K26c~!O z&SF@29t^V`x|Z#@_1E!{hrni80lH$kJ~UtzkT< zm`3Qgi>Yid(PhqG#57}j{I!mEFHDpB!PKM6+4zYK=z+7Co}Vsd7iJ7};}|RD?AOQjaZ5v3KoKVqbaA*P|sHj9yL0g|p5n5X97HvSKfiT%B7*Xs0 z_N}@QXuI3@`v2cr|61IYlYQp1&p!L?v(H%XARFO7jTdPjp{4Mm(Cpr~{WKJsiQ9<# z1)(AFgoZUc{4|Wv_)=-Qk}suiA4gAW&X*^szw~Y4OTVnN?7p&pOW)r0rtjstH~%?r z9y4-|n!JQ|=!Uzm1&3qsLmu?J9vX?PJciCF@>68zWpdN(@8`##a@H}A+3jOYXg6=g z<6F(j7GDd$%w%u28IN9Dvp7J{!;~RqBIEyoKZP&Rvik@g=OsPy1Q!$Iwno3L0eV6| zjlQq?(w~Q(5?|VN(&YtT`UlkI zCg@~RWDYB9=*IPCb#PtRR?ensCF-MG?y{Kf<_=S~Qa=yfV*&0cJ9A0=G6Qb0%Q~bM z7Opf&Ts@BX``%Gmn^e&c4d{tR^u-|bMs(v@>{Z^YF0Y{MxeEF|XJkxw%e&z6JDZ~a zD(j=h1Qj=-2Y<==sV|UGbve%Z{w73nIDO*ys7d&iXKsQ_xOyJHcsJxRUs(##2gy^sjZ$VJ&es zwQ$x;{IhCEN|d2h-UwvIreR8bgWAe!Qd^}wKbW(XlR5t+`BMG}_~i^d=u>TtMZH!% z9;SxXgiR~#&w2Fmsh*zwc^heY5AN))o6I@uq_`T!-{o}?wAaX>;x*_bum7DhIYxO$ zPe~XNrX;Qg55b4F3Ag0WexN&R|J6?`<790wV;*b!N$3i!`LAJ~FoilE61@d|IVRXb zUx-LBv99mvrc~@8ob~l_vj6_pU7V>R&$qx^%6o0Cx}5u|vYy2rQ~SpG%t2%wd>ie2 zH+#LS#wo?`gWEZ1HG*>%QO1bII@S=5Pn+J~?CIP8Bla&BqUQ`6uY4_cs-7@LShvxZ z4;qw2`7P{R&VG2P(?XllhdtbSk5%cDYvDWyb(Au$`^lFWm8N{13=j2|{b6LEVZ5?m z+K4j2gS+AEn@ao+`1$u#{c{`kb|1>%T(Yd;JV<*+nUrF&yWk6dy!Pu~WgqlBXFgW5 zX0eVv^+oWc8TsO%UoL_#<@ej{od^Yk4#*S&!9h3|zQ z+QFy72Rpv;rGJG?ngc)j_t1vXSBKJPhtPME>BEDW<0Ucw_3zOhCob&?-zo{woPGP2 zbQ#F;zia8WcQ_MTQa>q|c}apPsc%iFMn?&g_eo?wQK>(w#gEkXTV&ptaKN`>E4WEI z;Xy4e`jX&$j5KD_{FyYYQw<1nI_pF4;C>c;*}}S&)>jSDmXQ4G()O#N))7N{)foE> zk1?sH{bto!nLE2(8f7L<34(v=>+&wG71^3~ce}I=yjdrADP?XZ{&};lX?fiBdQP?G z#jqc?7T&WB;XJ5n;k;a!gR_EtLV}zFY>IP$f%4UGXH#p|1IOAMB0~&umWIxIB9mCB zQNx@~@dmXfjCabuHg-&iHP}*YH|&Y5RYR<`!8U8{J?+v)4UMhwwWp1dAt#~d*gL%y zg;nj+&cMU6Z!$@CIop*#bX&{eKL+B{E_xxAdB@4Q<*BE}7GInU~(wcTrxGNFH9THWGlgwEe{1T>7 zmf-4)an4-b`f_}Ayi=fO@fv5P)zB&>pZGdG2ZNi?Q}|`E)_$!V`QWy>s&$9uv|ks( zr7afkcUI=n7GBbFPE@1K{C4npAZ_gAcD*gl+HbQO%6*1Q?WyA-?`;S_o~>%7<$olU zd&$uIOiSK)T~+IcZ0K1q0KMS4|y;2lQyr`a8w)$ZEl@y?J$o%$2gdN7QTra z7FQ$vM&38IU+=68GgwosRON};}@S!0v^g}g;cZA5>=nsb^ahUL6@o3QWB!ir+>_&R{cT6CD!0X&v#c(isDgGcQU9}XT-ZIt3H)?}mlD#aml)HLL+^znoSbcj%c() zhR9Jvd)ACn`|Ou-OQ-Rbun2x?-u6;XHS&6sQa#}`a;UjnTPrdmP>-crJwhFMRchK& z)tYjqDk=@VWjyzxEa1?q7T)U&J^39c`lpg0vTZzcxvWnHcuM$Q=PBuv3Vm`pca-Ks zm)0|-eH4eREr(&x%}epCbdOMj1s(i zz3h*pQ{6Fd-s4AUZ_~}(wVbWlcZ9%)3nT#zaWB2Hd=@!o1}ad-h|D?e?EyFJsIXxYjMH9& z+4}q>Z^dTndX}|~`xuK;;e`{l$1=uXbxuf!ROwsryod63wjF70P}=i$OzZV^vtlbm zw`TtE^+Mxs9{2F>VGQpmp5(6RPGmt0@>}+7V;GBLg3Z=jhsD%zKCSpY-d_;ivZ1B3 za&CxH91A|4goh)a1Ba8~&>0*?YdF{(vEWe4IGe26@~&qNPy`P9+NN4h(>F%ahP&F1 zO<4~fC%B(8Pf=4ibL|*=XK96lJQoEii6;X2S&*fjiGSSK(ov_F8*6*7Vx8Dl|3aXvXg-u)Gt#*?lSG)-4Kx|jOwX*=2~ zck)UTc)z!@YsE?Sw7%e-PN|#tFZ+J(hn^^{*;Ay|Z(55>^;<;!;wd9m zu|Xfw$#{#L+t*U5+%c)3Vj1#FZ)4GUF19iKGi;6ueZw^RdXbT_;iIj4X2n%7My8D- z&qWdGDRD|j$}Xu(AYYrsY%v;CYnfuRel)49;vMqmTyNqR(5Zp^lQlXS9q*8TTl!cW&an?}P=yP)f?>;3#B?I-+n4LoQ= zUlu+TdB02WHTm({F{!9x32F4cAv~q`jU}{0LzVDUNS*+ zjY7x16$i|cZ(B!fnAsACO7M|t)9M=nP4zN_rg|A6(Dct$Qs4G@Ymp^7pDZE&edJfG zs-xuXSG~QKK=WO*C_luH|32Dl5BTftC3V)@YY+I>qHBxH5&R2i>yU`C7u!q6U)rj@ zfp(+3C0f319rN1$_uEVG|E2a4{4Eiw8twO}w1dz;?Eew{TL8DutP54Mwdr`R};dB)Gl>ojs!Xtk@7@faPPyHt+u9z>=xosP4!taI z(J}SBr5>E4ah&7ruFuJ@mO9CAj2=c;J59d+a^($clS9Vcxr_r|uh+$T(ZXXlrbxpFg8C+8P66vcG6~4=ySieewpZQ&Fhy!{!7VA_(k~4A?0dgsp^Qk(_3*Cymfu$4DGG! zD`&wwNYhCfw;?IDSroQhYsnk4M+%h`)rf?o0ZMq!FF)1Aenv;vGSEoILcLxu?VY`gpI0BV(9fOW%m2Z`9Hr`WP&2 zp^w3}0lhzozOj}%HP`!P?pS-7o~t_I;rGt)`>)Y+-_~g4*K>v6Mb8x)>AHgGcEXRk zZWnjwuhZ=$UtPD0tMu!3l5cYz$|3#%9jf!4zfOm`9ACc<)f`{ZZ5)-Cbenka{ns+b zuiHqzx^5%*%GfITHXri@-?)IzA@W4VJbm1e@lGFi=E-;$(7pZmUM^20-{#|u*5BLu z`wP0-_*Lu;WwnvBfl&#|Sc6!Vs1z?$mEH@`ze0GwT4Y2FYansFF|d&K*(|ugJEvK5 z)$tMjxrh(^(*=CeRiie~$|g-%#1QLYqs<{}i<@a*c}GU@5*aiPzxxzp%6j}|ygErg zW}l`P^B(IO`m)d@kGRjVj>4QJWeH_BAVXwcxQudjy~048v&JAt5NkLxwvVD;#32`w zs-mumA+IFKN<$zYmO_h3w^?wyecT9}xZ@ zC4Q>BiD7gkP4ZU!D?MD-_19|rucpK^Upve?k@V9LLkMn}Gj-JRN@Wg7ds|b5_9jg?Nl(F2ZFqSWj z9K?O&oyueUPK`P5diZQ1d~^;yK*oM~`$vAe$!rYP&ZnM+7ANr=loZz((`!lOCdJmc zjQL_XXK$7o!*}1Hwy^qCbK?i9IpqlQFP3$(0%LGZQC?a9dF+b~;+)yHEgyOu{wdza zerOW=V|C8hnr`g-iOzKIVqd!Gf0AaE#xbqNUumcUHvak3Icxd|F0$;kE z+Z-ovD;hgFxNqQC0PnAZ_qkK3jh`blox+5^=WGf-Xs8Q{ZW(jU&DNNfUClAFXLAhw ztA$gkkFZ-}PLj^Xy4znBTV5t*%X>Bk^0y6Pe-b)IB?T29gBGTzlj|8OSNcwvXW+xVzHi5Eh#qgZ^eH23D%>e?Z%K-h_){qtnJIjvoE_ZurE7` zu&}_stV8x?ojq!TX`5j7(BFd2N5IR(x?2=?wS@k%H!gd0@7&`*mnrm+xc+^*F|0d| zX8kdRb;wbyM~-BlZbTjHliE4eZ^ymKn&hQB#?hQTRWbf|iT&qBInU6P%ii`p_O9g~ zrJRje6{0lBUCM9Ay{(<=Yzpo0y__Mv@^0#saHZG?4@QSMxAtW%QqECumbJL;yoHf} zoo|%ij!Qp8Uu=HY^ZO}DbxkdYelP2)(f_r4Lhg0HFR6R%u?g?bS+{cGWA!DbpIjfB ztIR87e#-pN(#m9wF`KP|^T!5DN;`O-Gf5Zs=KXIFDC^s+QLX23COtRPSbOAmB6-84Giz+RKWCPk4sou4%;>KvTiN zf2ZAlJ~;zF_HDPU>+$G>_vddc5gM3&%J^`X!IWYO9%VIE1*e(#J*5+!oDZ0zoDWz! z7QN)?Sn-mqLp$bXyj0#sX`05~=sMP_r7YJKbtYZ{{pngchx`revp>x;aP~r3p2nSG z4}0&?*C}nH)}R-$M(cssq^(4s|AKQEF5x}al0`1dxM*Qqq&<6&=)wDQtSuiWu7x+( ztW{xYHe{*dls6BQu z_dbg|f~-v+X03XJ+?S?4@}53#DRCzwh&h&#-!)d6W-9E1Q#av%DT6Z(+WC`X&}Jp| zG*?Eo8N^=fVaENPwAFX)ub*HZb{G5Pa`$gxh_k+?&GrGK)b_ilP=^csRz;?9&eOyC z>xLHJ_q&TbFj1uM%-rA*^%{f>KFr=dZ(%t2?XeXXXYgz!Q(jhLiwGZ_1{pp*Dm;8 zhHeQz7~8IY|7Ty~?ZlC~X!jANE>*_j!z)%r4yrN~9|4{}$2o4sH};C^rCtjx&iW~o z$+~#@G4hl8yA17XzJTB4e8iW=4i4V@TK|KjBfijA$~w>4uNc)-vy*x(l6uD_#f*l& z_@&6(Eeqq+7$vN==p1q;e+VATAJWh zkt4qMC3Ybkde;jbEy$56MoVKdxGtEe)N{_wx^Mz}72vfCyyUEkA2-e$(I&eDH`;zA zdgBaz{jY2yOX{|d2?Wpk^a%hnLXOhO5Rb_Nu^HF=oFHN&|Kud^i83G zjA2ry$OVlq^fBT8*rb{`;hoR?cs{yjwdL zRv*Q0m*ui9VCH^o%*)pBT?2Y)b{SB91}X5$t3AJ`O}*?3lioW;2>-RGKe!tjzMZj;A?o}IB%9xag9FDG9w=#zPNKf!c>juUs3u99aV^m6&b!8so z(}-3UYb-L_W42nO6;lfQk-|GkRu+HTNZZ>+C<8`9d%c`P=%GRbbGUQBAhmOzr&$>C zXn=VL^rD^;NBS!A_F`I7>#(#a=;^1KpQa}AiJ~s^;4!@ng>RZ`x~r$xRWP;Z(2|nE z5+%8?q@=v4%wFUw%gR-TjvbOVdgz@!2d51gIc!*;-b!X^AV4D9Jq0<1{Ilma_bl{g z4{?>b(mXTW{}486?8u=7(+3V5>z*;Vvdo=SQsSzNj=5N<9z5J#b}@LU*PZV!C@WPc zB&#e}u~;%^dWsTydOew%Wgvx=xl0OMUb|aEs-QeS(_LckmK|qF&-Ikr`E%Jb%clx5 zmnV(2cPovvq}8T`uB)iXUEt2P%*b^Y*eeUm?K9jZZhLvDr(mkRw2%ynN(!fzxbp2Yay?nO1h`A> zI?i?%I9aj^^NR`#s9UU-zBIS6+?#E8c}oj*WVDh5bx_Er*!!m_f;OI&4cjXwT}rFQppa4L6s zi34e}C68Rs)LeIor5ImNSta$$DT6R>icQaT737s-8CCA}P;Qz=u~>Vrc>54{mRoCz zg!uS=aTbeWaX1|IBztL*JIh0J6%d1s{djW_9C5~G#1OyiXwN3$6b)+wwIPq zo$4+vEA`jkWrvFSg$4F37ZkQb7Ec^#NlFW?R9;Zx2CYo5nBMab6jTD~N_);I@sznsV>M#au5fUvJ-WO=>RXWQ&h}QuXuM!AEhEQL3vtUNPxz@s z$GEhzw9K6k{YL6_*D%N_^m+?tz-7#Ft)??Jje9y!IKMvRo}~kLlCxIbPRP%5?Y{-W}*$S*`+F&7P@smy*Kl z@+^0@R=J+g)!!xH>@s_{CntyQP*7&E+lvaRtya!O919ElET8YHB-L~fmGbgH(BDXU zm0>Tc<_dWC(5Q2X<45|_((c*zG46Z`?cbLIqi4*R5l2pbk2p$=fj^Vz4A4cGUnndM zBXpp@!zVc9_wBW|FU!-?{*lt9sG$EbzBHgtv z-AueuxF+EIg^sk(&;-hKH#F2x_j-^G(wp6`620SE{+cTri7g!o?Z%D5CIZRq&hhK@}hI%VjD3F9UxsYw%(#sutRhU&H< zN$E)e&r8-RW0HoCOjbsY3xwP@cIX|cLzB~o4w*7^+%RR_ZRvw=8#Zjpu-itDR+7h! z9X4`!AmX4wgJhI#_NfMAP;iTuCbPwAYZVfzI~C<^!#4FE!zYGP!#u+>!!g5o!_Nkj z@fu@C}n!e$$LwC>vG}I$$w>td}@63FcBL5PU5i;iY>g|VV z!xG{ZB_uqmYn-BXFy2(5Dhg{u$|v1?KJJ|=+oFBGKLBkpKHrzX=eqlR;V7He#rb?g zfU|-89-6WMI2-sV@FAeLr_Z+qxEi53 zo&W}Iraa)6TwY<0rkGx&JP!4FU!pwVI$$<%$jg)i91VO9csKA5z-r)^z(-&4`D`rG z9RRXErW9@U`R)cT0G0vw0UrW>4}1>jtOrlveXo%oxP?bS!cngKyi2*jZ$BU%(6-O# zs|EH4J`GF-ZUa7dz~?&&jO9Ro5R1A8&iH(NfY+TxF#{gt;kVhq1t{3OrL8;-+ybr`9m9TScrxh077v*owmf265%Or* zV{IM}Um5WPzwNBW9SuBtgU^==R7UIZP2$q>WA3NeZ}jh+QO+qC>{ zCVVsL`bc=-6TH*$--G|5Rygi%p6-|Fb|3L)5A^w}C69}A^W!b~Jx%yQ!e@JN{F`== z_y>p|{d=F!3qLA`+>p)cKW{jxXAtzw-avfpm(>$zS22WdCY-%PMY-b_>VvnGJDPa? zpQGNC|L^dWa;4uMZNO z^yemYd5C!TA&351J+=_On($v+k1vUDLw@;d=C6m8^JBn&gm~p%PJiha*99SmNEa>P zflt!)!G8$;|14cP;hNl(dImmePvOT$xA=VVzk>c+`%8S}YBdW1|Bjy|{vP5Vd(-FJ zZo!fL3w+v4UP=9aB!0!t%jqKi;mBd}mpt`P{6(JEUJ+m73<>z(O@99lPsvBdfvtO~ z7jj$wB%fOR?a1?W66x-cL;s@NYVwJ9Wt2yc1=`^XxzUv@4idhd@a@0IZz8|LwS0oW zL3T-@ zCtKkiC#57IJ`?ai{t^fD=|7-PpZ{_Cs|l}C;3@^KQs62Du2SGC1+G%yDg~}m;3@^K zQs62Du2SItCkm|Q5Qlur0#KiNpYwZb^KP;Je1*G3Afg_hJ8{|<5{Nf3;O6aB?Mwa1 z@1d^|=xbxLBqColYj5&>_p^^DB3L&FxLKmmzI_1;O9a{%FKY^XvXmp=v_N@*YAE_z zRv?;^>hnhkWUJ%`;>-Gld@OZqA7{+8ubr$Z@#+4L1}w53AzyVMeIVM!^0*tNeR{kL zK7V}z(UqSA?utNuzAM7d2HXP!;Y|T|XdvJJEl?dG?Ef~*2=IwsPm|(rF_SDpYo87k z<<*Wmf(mY$Z~pTQ$*m4f54t8V@7-%(9CLqUaO&_*TThv82tB*=`j0+Z)YG*)rF-^D zTjGcJ@9kw-z2xRM-Wb=v=+oAt|LeVdBRU;=aA@666Ox|W*mg>X%?BpE{m6=m(D%PCv^f9H_4X|d58qP0E4q5%-&Z|(;oPv- zw_f=A*-GEH=Wacm-01u2@x9xQ_1IT+az@epeYWQhk8ht6bj$M--yN`_#rzwu>yX^# z-CLBn68jFv2Tv|(Q&BxGV$HL*4iT^Kjk>0Bk^1zxl;Em;CeyCHJ8dmDtf<)h%EZ~8 zWo?T;Uwoka)6X8v^KPF|`0~-#nT8Ada^4!YYO-n4hy2Fxu@>2A-+ z?eyaFx1}chaAeFkKTkQk?Y(2Cs^0Fk`_>P58*%r&_iz1EpOuySPrWhl;9aXPd~*7b z&2#5Zd-JP5U6Rr7y>ZzIkCZQPtPV`8hIafid+P3hnF{$WeI4}>L&@Y(^n2!nRnMs zH+##9z>A_a7H| zfBd7p`w{moCys9GP}gW}k$dKq*Khn-efH>wpHx5ddEt}Uf0?$o%O5`5cVv6exix!V zYRuR|Exn4|`?Xmfvrv+PwC{z~|c@y|8}I_N~94^;zXp?`8B|SzL8~)w)Sr z9*7!N{zzm*!h(&~Z)(eWY@YW{eDQA{Tej$)xWy@Vp5I_fcfPVSb?DJ0WB-0(+^FuK z*@i!{eQ$E-s`;}X$w;2dZgI)?lXgu1$$Ee8sEFa-2jhcWU3~Ju2{Id`CJNo*B-h-ZOed~hieFGQoThVpk-ih`v z8r$|rKX)Le@`k#18*a+oac#%$dsZta-hU=_<40}Ac>lONujgN9Pe1+Xj@@g%nEp}5 z-!`4?a-!X-Bd0sQ@yyxvtFyl?z5m9hKde0ZlliBu3*S6cxp?Y(1FQFadf~o5)ogn_ z^O36Gy}tR@2W=aDD_#iOys1U2;thZ8p73mL-*49D=WN;bms#aojra6@d5iP>3welv zeHhNkDu)rSPa)`KOz43*j$dEG&IA99`vCU6*xw`G6x@x#ukiajelO$x2>2Q9N!Z5` z_6O|wm|HO;30ngE3+59k2eSnefjNuGBF!I(vlRO};v53sU2{Vg0&*7I(oMNEle=pDj zT#uQ8-Gq6X@Q;B9iT^UN4){Fbzr`-~nu(G6w!!@x@HXPVioFT{H*oV-v$7b!&cL@Y zE3i+){DrU*;J3gD_-AA0VLIb?khE(ty|I6S8G}E+L86=?ZWQh{gx!t%P3&!fpW$9c z*nEu8gx@w)LV$B{r(^#ea078f{LjF?9{3e-DRIJqnS{mQ_Y^P__v6@~A#5G?+b~i_ z4(=}qmp1$qzt^z01PUG6W1h!Ixrgxo6aGVh2GU4<-^5;y-wl|)xT7%*_-(~(!rlQR zy1-n_Ud%(7bL2G~{~4Iw*prFNS$GZKJ=hlHVj(rob8uJ52__PIKdoZFq{td``a~hvW{0#i&0PnSg;|8zgx@yIi-i9UxD1ntIf7Y0xTKMOCcGzY z_D5h6{!Z*3jI`-F+;i~%J@#)Xb1QCX&qDm(#(gvPYK+KD!LvVp!nacHJD3&NcamlY zrX%6+;Jy|ZN7xHM$v1{DkyV`4SNh|(Q_^8%Pg-P=%nv35rM3d;>{|w@f zUCsmDLihyyZU@$5p2kn+K*fYhUz7fS8b6WCH(^8`M*!{kuLMe8or(Qp{BOpdO5FCi z6M@|^?_nhWYQhF#y5J5b+y-m_cEjw)NZSa#AI4w$&OXdvF%RH&0~caMz8uHwAfAHz z2J9Iak$ZweCye0nA?|jV9hh5iZzfKA?Dqlx0u;WQhJOK2@)iFw?EQd$1ipw7IU?iR zZ?H=_D~R`7+%{k^hBpqhFyV`A{Dr^X#Qz!W-;?H1?3=Ogzz7dWe>UU48+QWc3H+q} zrJTLTI?k55;l}j`7l?7n!6Mpym z0oXs_?+n1e-m*P9F@fX5eG=@M9MaCVbF8wYcb~q!`wz&9v1iG-bvx%9OF6P@@6VaP ze)j0xva+JmfjxV2yjeD<8yuIG(`S#vfy$AHparble zbNA|<8K0Bs>f_4lm*|S`<#P4y-#fdXD>1WIudHmczF57{qbH8>*QIoNK@6R^G?&A{ z9R5_|?)PnN3%yN%6y9Yb(nk&~;nybWRR~D4=LZb%DO8g-K(p=`4LKuglT@o>1 zEAo~pab@lb{&TjJgQiNHJ9kPBhu7UxaY3t_qx@Rwu6$1x zB^DCm&kLf<34VWj|EK?DJwc}8u$=$XEdkh7_Yc6JE8N%PmZb|lS#-dn!);fj)7K63 zd}KX=qj)mpYTvPdMTa8-{(5{peZX6Z#v*ml)9dRdI$RwH5FF`Rik`k5cKPBl;;*OI z*I{(1ue(TG`RJmTeImAMC}FZ@qPz8V6CK(mF`wWsW$XBh zpM2>U$y-maujA;jI)JcVzMfvM|KvdW!9e-+bs-(<>qwHm4d%-9S@=m2`nuJX>nUMZ z5G;(i^64-ad-L@AI-L$?`oUvi$q5NMH0fe|jA@KjS1JSD>RT!LND$JA2BXUWbqRofrRKS^io=WbI6N zSU!CnGW93FTc@+%b*X$E579%U?ez5e`cy_Bz03jS6aJG=Pp9YmDt;10Pp_{-rurnd ze{A&I{QvdzIu!ZPJpHAX^cQ@Gt$FH82$yU1G324Z~y=R diff --git a/android/lib/armeabi-v7a/librnupdate.so b/android/lib/armeabi-v7a/librnupdate.so index c1e0215af9810a9fc92754ed11c4ee39c20e4b85..dffb7ab8edb142b151ea6797c4fb962ffeb15804 100755 GIT binary patch delta 7414 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 I2xQwZQe7kq*n?pa{s~Qq~#VuB91z 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 diff --git a/android/lib/x86/librnupdate.so b/android/lib/x86/librnupdate.so index 92c4c5b5464d38075e7279e9936f3105fd4fa9be..7cf6e3be02f52b3160dc7b4aeaccc4a626406686 100755 GIT binary patch delta 4155 zcmai13slrq8o&QPFfuU0kb|NSjKhRlEJ9i8ZYda=b<8l6wakWbn34C4!{Fl_kYUFM z?l>pxtL*90V_R|wAH$Yys35LOXUVWro=lUMThoaYpIOa%_jiZEgPeU_&X3>sxUcWK z_x|sl=A$9a15({&$-YB3Z%$-nbPayDnEYm{H9aqI@H@WdCx|^`tkG^3TRNu ztllgJ36>b}&S3?78}QmF{jE{@?os;QQThj?^h3AmY3y&e8d&Ej{j-reJu2UG_YWg2 zkgtx?e;K7SiT2BB)v?IOa1oIujM9@w>5rgJS2$xgkpJ7*ST+s*ROe6+YIc#|KT1y@ zr89%UwBBeiI?U?}9c&R*hZa{CEqE;E*5M007Wb*&j{fS{I}9c)dx z)$X7%idoem2ss`Q=@DC2na!pNJrNKk&zH7g-uy2HKI(t2^35&9MVIB93EsEfu$<7G@k^2NAdjox{hiyKHJ>tap$0>$9uky;$j|GeD(|HmO9E=sfoByjv?o(+#mU=Y~|w6Jb1_! zqlu^v*u#bW?8-{{$j|ijGm|4v+7W%WKHTl}Q|&V~a`Mjzr@9=4qLN7HrwJe=c>M z8*~k*hjYKfCK4R(afS7Z)K-N1YOmADyo~roaJZN0-H&SB6$u%a+*NTIKV`HkPq@iX zI^(ml`$zH`{qhrx_N|JSo!992s?@o9 z(uax#|70QL8G2vrHJWX@YwU$mQC00;rV^{Q#$=ISxavJ+S}&#j<1#YsNMZjqnBHPE zov#v|9==S~=H%>sLl&%XxUjw|dNBJ}tZWxM<3FUM2K58!h!{@C`pfi6R?H^ODzY$&eGh&1^0O8?Ry12KJx@|`nyj}_M)9P`yqB>x7OOl??JJZE^QUIoQaoFJ z?+0&N@lr{in@{6Q-k8gxjxNldSv5ax%?}NtUfJoIpy_LPn445zx+R2 zAtQ(MHSKcAWAt6kX*s>0j{WX_IkVpz>UvCiItSfHPurxg$2vq$b>;=tx*^pTRGmYr zGoWVcZI)>3fjXf~b=C)Md64%8 z6g4*)$t zr*E5gMi&{^8mE^S%T`aHZ?{|R^hir$Bw7y_`c<;>h4V>?ytizhv?W)kwELB)Ij8lPn zU{eFVcsNDT39(@}?P{H*7=YNZoBCjlL%@xV6xEuj6px=T8#xc7m^KYP+#0PYfTg90 zo0#V>DO(Ol=%?V zUd~Noo-=YWPs~C*Cbq+|9F8o=EGsH}vpjEXSoW5X4XC1rsS*C#;fC~KTcq-HSh`@* zP+O};Ge!#ZC93-2=xF9#3WT6M5~d}RxPRyrAK5Z2hQdXXu**bMI}UE zJJ}&NKuqnRT}LJ#6W)a&`XCoa@m<3(M!6bLSrb*qm>2 z-UuE9e+jO8i}O(2uRVX{JRPjXfye=;VH9g)17~8jYQeU@aNZ2=YC~IL zKZb$uDsh5S!Cl}*VD@*;OTg++IDa0T{srePf^kipyP-z|2r5LLjug)TcY*W3Y9!DJ zcK+y%IyNWt-W(heHGpMhU3g_-=dgvq1VE3M7tZ6&Guw<8n)rEPqZ7xcRQI5XcyJo9 ziXsvsum})y73mcL3Cy7l-AM`&)_Mi)>eeYmKmuBNqk9~k=~gL4#szG2u{%jA z)gjmDCIzB~3J&AW~SD_o=C6UEoQ3rV^SeV6J4w#1UQW*WU zCsBFxmpAqHBq;*F+RI4Mt5XDipqEivuTCi*^_^CPMf=W9SkkGcR~zm` hw|D}k2HY*ZF_Mjr_f832gH;ZgRDChh8cOUN|8IYIS|I=c delta 30685 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ͷr!cR04$%2}yup<$ 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 diff --git a/android/lib/x86_64/librnupdate.so b/android/lib/x86_64/librnupdate.so index 58c25871fc5e9269952fdc967f2cf1d9d60a3b34..29f7fa0f00067ab5204374e0a63023e91a04fd89 100755 GIT binary patch delta 4197 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

u1>ktCXSMW|qBwsjfiZ5B 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 GLH=K)fjGzj diff --git a/android/src/main/java/cn/reactnative/modules/update/DownloadTask.java b/android/src/main/java/cn/reactnative/modules/update/DownloadTask.java index 2f463fa..ba59f51 100644 --- a/android/src/main/java/cn/reactnative/modules/update/DownloadTask.java +++ b/android/src/main/java/cn/reactnative/modules/update/DownloadTask.java @@ -136,7 +136,6 @@ class DownloadTask extends AsyncTask { byte[] buffer = new byte[1024*4]; - private static native byte[] bsdiffPatch(byte[] origin, byte[] patch); private static native byte[] hdiffPatch(byte[] origin, byte[] patch); private void unzipToFile(ZipInputStream zis, File fmd) throws IOException { @@ -301,7 +300,7 @@ class DownloadTask extends AsyncTask { } } - private void doPatchFromApk(DownloadTaskParams param,int apkPatchType) throws IOException, JSONException { + private void doPatchFromApk(DownloadTaskParams param) throws IOException, JSONException { downloadFile(param); ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(param.targetFile))); @@ -350,11 +349,7 @@ class DownloadTask extends AsyncTask { if (fn.equals("index.bundlejs.patch")) { foundBundlePatch = true; - byte[] patched; - if (DownloadTaskParams.isHPatchType(apkPatchType)) // hpatch - patched = hdiffPatch(readOriginBundle(), readBytes(zis)); - else // do bsdiff patch - patched = bsdiffPatch(readOriginBundle(), readBytes(zis)); + byte[] patched = hdiffPatch(readOriginBundle(), readBytes(zis)); FileOutputStream fout = new FileOutputStream(new File(param.unzipDirectory, "index.bundlejs")); fout.write(patched); @@ -391,7 +386,7 @@ class DownloadTask extends AsyncTask { } - private void doPatchFromPpk(DownloadTaskParams param,int ppkPatchType) throws IOException, JSONException { + private void doPatchFromPpk(DownloadTaskParams param) throws IOException, JSONException { downloadFile(param); ZipInputStream zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(param.targetFile))); @@ -431,12 +426,8 @@ class DownloadTask extends AsyncTask { } if (fn.equals("index.bundlejs.patch")) { foundBundlePatch = true; - byte[] patched; - if (DownloadTaskParams.isHPatchType(ppkPatchType)) // hpatch - patched = hdiffPatch(readFile(new File(param.originDirectory, "index.bundlejs")), readBytes(zis)); - else // do bsdiff patch - patched = bsdiffPatch(readFile(new File(param.originDirectory, "index.bundlejs")), readBytes(zis)); - + byte[] patched = hdiffPatch(readFile(new File(param.originDirectory, "index.bundlejs")), readBytes(zis)); + FileOutputStream fout = new FileOutputStream(new File(param.unzipDirectory, "index.bundlejs")); fout.write(patched); fout.close(); @@ -497,12 +488,10 @@ class DownloadTask extends AsyncTask { doFullPatch(params[0]); break; case DownloadTaskParams.TASK_TYPE_PATCH_FROM_APK: - case DownloadTaskParams.TASK_TYPE_HPATCH_FROM_APK: - doPatchFromApk(params[0],taskType); + doPatchFromApk(params[0]); break; case DownloadTaskParams.TASK_TYPE_PATCH_FROM_PPK: - case DownloadTaskParams.TASK_TYPE_HPATCH_FROM_PPK: - doPatchFromPpk(params[0],taskType); + doPatchFromPpk(params[0]); break; case DownloadTaskParams.TASK_TYPE_CLEANUP: doCleanUp(params[0]); @@ -524,8 +513,6 @@ class DownloadTask extends AsyncTask { case DownloadTaskParams.TASK_TYPE_PATCH_FULL: case DownloadTaskParams.TASK_TYPE_PATCH_FROM_APK: case DownloadTaskParams.TASK_TYPE_PATCH_FROM_PPK: - case DownloadTaskParams.TASK_TYPE_HPATCH_FROM_APK: - case DownloadTaskParams.TASK_TYPE_HPATCH_FROM_PPK: try { removeDirectory(params[0].unzipDirectory); } catch (IOException ioException) { diff --git a/android/src/main/java/cn/reactnative/modules/update/DownloadTaskParams.java b/android/src/main/java/cn/reactnative/modules/update/DownloadTaskParams.java index 7d7c538..2d9f80f 100644 --- a/android/src/main/java/cn/reactnative/modules/update/DownloadTaskParams.java +++ b/android/src/main/java/cn/reactnative/modules/update/DownloadTaskParams.java @@ -15,12 +15,6 @@ class DownloadTaskParams { static final int TASK_TYPE_PATCH_FROM_PPK = 3; static final int TASK_TYPE_PLAIN_DOWNLOAD = 4; - static final int TASK_TYPE_HPATCH_FROM_APK = 5; - static final int TASK_TYPE_HPATCH_FROM_PPK = 6; - - static boolean isHPatchType(int patchType){ - return (patchType==TASK_TYPE_HPATCH_FROM_APK)||(patchType==TASK_TYPE_HPATCH_FROM_PPK); - } int type; String url; diff --git a/android/src/main/java/cn/reactnative/modules/update/UpdateContext.java b/android/src/main/java/cn/reactnative/modules/update/UpdateContext.java index ae911cd..ab782fb 100644 --- a/android/src/main/java/cn/reactnative/modules/update/UpdateContext.java +++ b/android/src/main/java/cn/reactnative/modules/update/UpdateContext.java @@ -90,30 +90,13 @@ public class UpdateContext { void onDownloadFailed(Throwable error); } - private String zipExtension(int patchType){ - switch (patchType) { - case DownloadTaskParams.TASK_TYPE_PATCH_FULL: - return ".ppk"; - case DownloadTaskParams.TASK_TYPE_PATCH_FROM_APK: - return ".apk.patch"; - case DownloadTaskParams.TASK_TYPE_PATCH_FROM_PPK: - return ".ppk.patch"; - case DownloadTaskParams.TASK_TYPE_HPATCH_FROM_APK: - return ".apk.hpatch"; - case DownloadTaskParams.TASK_TYPE_HPATCH_FROM_PPK: - return ".ppk.hpatch"; - default: - return "";//unknown type - } - } - public void downloadFullUpdate(String url, String hash, DownloadFileListener listener) { DownloadTaskParams params = new DownloadTaskParams(); params.type = DownloadTaskParams.TASK_TYPE_PATCH_FULL; params.url = url; params.hash = hash; params.listener = listener; - params.targetFile = new File(rootDir, hash + zipExtension(params.type)); + params.targetFile = new File(rootDir, hash + ".ppk"); params.unzipDirectory = new File(rootDir, hash); new DownloadTask(context).executeOnExecutor(this.executor, params); } @@ -129,25 +112,25 @@ public class UpdateContext { new DownloadTask(context).executeOnExecutor(this.executor, params); } - public void downloadPatchFromApk(String url, String hash,int apkPatchType,DownloadFileListener listener) { + public void downloadPatchFromApk(String url, String hash, DownloadFileListener listener) { DownloadTaskParams params = new DownloadTaskParams(); - params.type = apkPatchType; + params.type = DownloadTaskParams.TASK_TYPE_PATCH_FROM_APK; params.url = url; params.hash = hash; params.listener = listener; - params.targetFile = new File(rootDir, hash + zipExtension(params.type)); + params.targetFile = new File(rootDir, hash + ".apk.patch"); params.unzipDirectory = new File(rootDir, hash); new DownloadTask(context).executeOnExecutor(this.executor, params); } - public void downloadPatchFromPpk(String url,String hash,String originHash,int ppkPatchType,DownloadFileListener listener) { + public void downloadPatchFromPpk(String url, String hash, String originHash, DownloadFileListener listener) { DownloadTaskParams params = new DownloadTaskParams(); - params.type = ppkPatchType; + params.type = DownloadTaskParams.TASK_TYPE_PATCH_FROM_PPK; params.url = url; params.hash = hash; params.originHash = originHash; params.listener = listener; - params.targetFile = new File(rootDir, originHash + "-" + hash + zipExtension(params.type)); + params.targetFile = new File(rootDir, originHash + "-" + hash + ".ppk.patch"); params.unzipDirectory = new File(rootDir, hash); params.originDirectory = new File(rootDir, originHash); new DownloadTask(context).executeOnExecutor(this.executor, params); diff --git a/android/src/main/java/cn/reactnative/modules/update/UpdateModule.java b/android/src/main/java/cn/reactnative/modules/update/UpdateModule.java index cb79bb2..7ef735b 100644 --- a/android/src/main/java/cn/reactnative/modules/update/UpdateModule.java +++ b/android/src/main/java/cn/reactnative/modules/update/UpdateModule.java @@ -135,13 +135,14 @@ public class UpdateModule extends ReactContextBaseJavaModule { } } - private void _downloadPatchFromPackage(ReadableMap options, final Promise promise,int apkPatchType) { + @ReactMethod + private void downloadPatchFromPackage(ReadableMap options, final Promise promise) { String url = options.getString("updateUrl"); String hash = options.getString("hash"); if (hash == null) { hash = options.getString("hashName"); } - updateContext.downloadPatchFromApk(url,hash,apkPatchType,new UpdateContext.DownloadFileListener() { + updateContext.downloadPatchFromApk(url, hash, new UpdateContext.DownloadFileListener() { @Override public void onDownloadCompleted(DownloadTaskParams params) { promise.resolve(null); @@ -153,8 +154,9 @@ public class UpdateModule extends ReactContextBaseJavaModule { } }); } - - private void _downloadPatchFromPpk(ReadableMap options, final Promise promise,int ppkPatchType) { + + @ReactMethod + private void downloadPatchFromPpk(ReadableMap options, final Promise promise) { String url = options.getString("updateUrl"); String hash = options.getString("hash"); if (hash == null) { @@ -164,7 +166,7 @@ public class UpdateModule extends ReactContextBaseJavaModule { if (originHash == null) { originHash = options.getString(("originHashName")); } - updateContext.downloadPatchFromPpk(url,hash,originHash,ppkPatchType,new UpdateContext.DownloadFileListener() { + updateContext.downloadPatchFromPpk(url, hash, originHash, new UpdateContext.DownloadFileListener() { @Override public void onDownloadCompleted(DownloadTaskParams params) { promise.resolve(null); @@ -177,26 +179,6 @@ public class UpdateModule extends ReactContextBaseJavaModule { }); } - @ReactMethod - public void downloadPatchFromPackage(ReadableMap options, final Promise promise) { - _downloadPatchFromPackage(options,promise,DownloadTaskParams.TASK_TYPE_PATCH_FROM_APK); - } - - @ReactMethod - public void downloadHPatchFromPackage(ReadableMap options, final Promise promise) { - _downloadPatchFromPackage(options,promise,DownloadTaskParams.TASK_TYPE_HPATCH_FROM_APK); - } - - @ReactMethod - public void downloadPatchFromPpk(ReadableMap options, final Promise promise) { - _downloadPatchFromPpk(options,promise,DownloadTaskParams.TASK_TYPE_PATCH_FROM_PPK); - } - - @ReactMethod - public void downloadHPatchFromPpk(ReadableMap options, final Promise promise) { - _downloadPatchFromPpk(options,promise,DownloadTaskParams.TASK_TYPE_HPATCH_FROM_PPK); - } - @ReactMethod public void reloadUpdate(ReadableMap options) { final String hash = options.getString("hash") == null ?