├── AppAddUpdateDemo
├── .gitignore
├── app
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ ├── androidTest
│ │ └── java
│ │ │ └── com
│ │ │ └── wang
│ │ │ └── appaddupdatedemo
│ │ │ └── ApplicationTest.java
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── wang
│ │ │ │ └── appaddupdatedemo
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── PermissionUtil.java
│ │ ├── jniLibs
│ │ │ ├── armeabi-v7a
│ │ │ │ └── libApkPatchLibrary.so
│ │ │ ├── armeabi
│ │ │ │ └── libApkPatchLibrary.so
│ │ │ └── x86
│ │ │ │ └── libApkPatchLibrary.so
│ │ └── res
│ │ │ ├── layout
│ │ │ └── activity_main.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-w820dp
│ │ │ └── dimens.xml
│ │ │ └── values
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── wang
│ │ └── appaddupdatedemo
│ │ └── ExampleUnitTest.java
├── appupdate
│ ├── .gitignore
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ └── com
│ │ │ └── wang
│ │ │ └── appupdate
│ │ │ └── util
│ │ │ ├── ApkUtil.java
│ │ │ ├── PatchUtil.java
│ │ │ └── SignUtil.java
│ │ └── res
│ │ └── values
│ │ └── strings.xml
├── bintray.gradle
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── AppUpdate
├── .gitignore
├── app
│ ├── .gitignore
│ ├── app-release.apk
│ ├── build.gradle
│ ├── proguard-rules.pro
│ └── src
│ │ ├── androidTest
│ │ └── java
│ │ │ └── com
│ │ │ └── wang
│ │ │ └── appupdate
│ │ │ └── ApplicationTest.java
│ │ ├── main
│ │ ├── AndroidManifest.xml
│ │ ├── java
│ │ │ └── com
│ │ │ │ └── wang
│ │ │ │ └── appupdate
│ │ │ │ ├── MainActivity.java
│ │ │ │ └── util
│ │ │ │ ├── ApkUtil.java
│ │ │ │ ├── PatchUtil.java
│ │ │ │ └── SignUtil.java
│ │ ├── jni
│ │ │ ├── bzip2
│ │ │ │ ├── blocksort.c
│ │ │ │ ├── bzip2.c
│ │ │ │ ├── bzip2recover.c
│ │ │ │ ├── bzlib.c
│ │ │ │ ├── bzlib.h
│ │ │ │ ├── bzlib_private.h
│ │ │ │ ├── compress.c
│ │ │ │ ├── crctable.c
│ │ │ │ ├── decompress.c
│ │ │ │ ├── huffman.c
│ │ │ │ ├── randtable.c
│ │ │ │ └── readMe.txt
│ │ │ ├── com_wang_appupdate_util_PatchUtil.h
│ │ │ ├── diff.c
│ │ │ ├── patch.c
│ │ │ └── util
│ │ │ │ └── android_log_print.h
│ │ └── res
│ │ │ ├── layout
│ │ │ └── activity_main.xml
│ │ │ ├── mipmap-hdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-mdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── mipmap-xxxhdpi
│ │ │ └── ic_launcher.png
│ │ │ ├── values-w820dp
│ │ │ └── dimens.xml
│ │ │ └── values
│ │ │ ├── colors.xml
│ │ │ ├── dimens.xml
│ │ │ ├── strings.xml
│ │ │ └── styles.xml
│ │ └── test
│ │ └── java
│ │ └── com
│ │ └── wang
│ │ └── appupdate
│ │ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
│ └── wrapper
│ │ ├── gradle-wrapper.jar
│ │ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
├── LICENSE
└── README.md
/AppAddUpdateDemo/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea
5 | .DS_Store
6 | /build
7 | /captures
8 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'android-apt'
3 |
4 | android {
5 | compileSdkVersion 25
6 | buildToolsVersion "25.0.0"
7 |
8 | defaultConfig {
9 | applicationId "com.wang.appaddupdatedemo"
10 | minSdkVersion 17
11 | targetSdkVersion 25
12 | versionCode 1
13 | versionName "1.0"
14 | }
15 | buildTypes {
16 | release {
17 | minifyEnabled false
18 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
19 | }
20 | }
21 | }
22 |
23 | dependencies {
24 | compile fileTree(dir: 'libs', include: ['*.jar'])
25 | testCompile 'junit:junit:4.12'
26 | compile 'com.android.support:appcompat-v7:25.0.0'
27 | compile project(path: ':appupdate')
28 | compile 'io.reactivex:rxandroid:1.2.1'
29 | // Because RxAndroid releases are few and far between, it is recommended you also
30 | // explicitly depend on RxJava's latest version for bug fixes and new features.
31 | compile 'io.reactivex:rxjava:1.1.10'
32 | compile 'com.jakewharton:butterknife:8.4.0'
33 | apt 'com.jakewharton:butterknife-compiler:8.4.0'
34 | // compile 'com.wang.appupdate:appupdate:1.0.1'
35 | }
36 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/androidTest/java/com/wang/appaddupdatedemo/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.wang.appaddupdatedemo;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/java/com/wang/appaddupdatedemo/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.wang.appaddupdatedemo;
2 |
3 | import android.Manifest;
4 | import android.os.Bundle;
5 | import android.os.Environment;
6 | import android.support.annotation.NonNull;
7 | import android.support.v4.app.ActivityCompat;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.view.View;
10 | import android.widget.Button;
11 | import android.widget.ProgressBar;
12 | import android.widget.TextView;
13 | import android.widget.Toast;
14 |
15 | import com.wang.appupdate.util.PatchUtil;
16 | import com.wang.appupdate.util.SignUtil;
17 |
18 | import java.io.File;
19 | import java.util.Arrays;
20 | import java.util.List;
21 |
22 | import butterknife.BindView;
23 | import butterknife.ButterKnife;
24 | import butterknife.OnClick;
25 | import rx.Observable;
26 | import rx.Subscriber;
27 | import rx.Subscription;
28 | import rx.android.schedulers.AndroidSchedulers;
29 | import rx.functions.Func1;
30 | import rx.schedulers.Schedulers;
31 |
32 | public class MainActivity extends AppCompatActivity {
33 |
34 | private static final String PATH = Environment.getExternalStorageDirectory().getAbsolutePath();
35 |
36 | private static final int REQUEST_PERMISSIONS = 100;
37 |
38 | private String mOldApk = PATH + "/jiudeng1.apk";
39 | private String mNewApk = PATH + "/jiudeng2.apk";
40 | private String mPatchPath = PATH + "/test.patch";
41 | private String mNewApk2 = PATH + "/jiudeng3.apk";
42 |
43 | @BindView(R.id.old_apk_tv)
44 | TextView mOldApkTV;
45 | @BindView(R.id.old_apk_size_tv)
46 | TextView mOldApkSizeTV;
47 | @BindView(R.id.old_apk_md5_tv)
48 | TextView mOldApkMd5TV;
49 | @BindView(R.id.new_apk_tv)
50 | TextView mNewApkTV;
51 | @BindView(R.id.new_apk_size_tv)
52 | TextView mNewApkSizeTV;
53 | @BindView(R.id.new_apk_md5_tv)
54 | TextView mNewApkMd5TV;
55 | @BindView(R.id.patch_tv)
56 | TextView mPatchTV;
57 | @BindView(R.id.patch_size_tv)
58 | TextView mPatchSizeTV;
59 | @BindView(R.id.new_apk_2_tv)
60 | TextView mNewApk2TV;
61 | @BindView(R.id.new_apk_2_size_tv)
62 | TextView mNewApk2SizeTV;
63 | @BindView(R.id.new_apk_2_md5_tv)
64 | TextView mNewApk2Md5TV;
65 | @BindView(R.id.msg_tv)
66 | TextView mMsgTV;
67 | @BindView(R.id.get_patch_btn)
68 | Button mGetPatchBtn;
69 | @BindView(R.id.get_new_apk_btn)
70 | Button mGetNewApkBtn;
71 | @BindView(R.id.delete_btn)
72 | Button mDeleteBtn;
73 | @BindView(R.id.loading)
74 | ProgressBar mLoading;
75 |
76 | private Subscription mSubscription;
77 |
78 | private boolean isSuccess;
79 |
80 | @Override
81 | protected void onCreate(Bundle savedInstanceState) {
82 | super.onCreate(savedInstanceState);
83 | setContentView(R.layout.activity_main);
84 | ButterKnife.bind(this);
85 | requestPermissions(Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE);
86 |
87 | }
88 |
89 | @Override
90 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
91 | List allPermissions = Arrays.asList(permissions);
92 | if (!PermissionUtil.verifyPermissions(allPermissions, grantResults)) {
93 | Toast.makeText(this, "权限请求失败", Toast.LENGTH_SHORT).show();
94 | isSuccess = false;
95 | }
96 | else {
97 | isSuccess = true;
98 | }
99 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
100 | }
101 |
102 | public void requestPermissions(String... permissions) {
103 |
104 | if (PermissionUtil.checkSelfPermission(this, permissions)) {
105 | isSuccess = false;
106 | ActivityCompat.requestPermissions(this, permissions, 0);
107 | }
108 | else {
109 | isSuccess = true;
110 | }
111 | }
112 |
113 | @OnClick({R.id.get_patch_btn, R.id.get_new_apk_btn, R.id.delete_btn})
114 | public void onClick(View view) {
115 | if (!isSuccess){
116 | return;
117 | }
118 | switch (view.getId()) {
119 | case R.id.get_patch_btn:
120 | clearText();
121 | File file = new File(mOldApk);
122 | File newFile = new File(mNewApk);
123 | if (!file.exists()) {
124 | mMsgTV.setText("旧APK不存在");
125 | return;
126 | }
127 | if (!newFile.exists()) {
128 | mMsgTV.setText("新APK不存在");
129 | return;
130 | }
131 | File p = new File(mPatchPath);
132 | if (p.exists()) {
133 | p.delete();
134 | }
135 | setEnabled(false);
136 | mOldApkTV.setText(mOldApk);
137 | mOldApkSizeTV.setText(String.format("%.2f M", getFileSize(file)));
138 | mOldApkMd5TV.setText(SignUtil.getMd5ByFile(file));
139 |
140 | mNewApkTV.setText(mNewApk);
141 | mNewApkSizeTV.setText(String.format("%.2f M", getFileSize(newFile)));
142 | mNewApkMd5TV.setText(SignUtil.getMd5ByFile(newFile));
143 | mSubscription = Observable.just("")
144 | .map(new Func1() {
145 | @Override
146 | public Integer call(String s) {
147 | return PatchUtil.diff(mOldApk, mNewApk, mPatchPath);
148 | }
149 | })
150 | .map(new Func1() {
151 | @Override
152 | public String call(Integer integer) {
153 | return checkResult(integer);
154 | }
155 | })
156 | .subscribeOn(Schedulers.io())
157 | .observeOn(AndroidSchedulers.mainThread())
158 | .subscribe(new Subscriber() {
159 | @Override
160 | public void onCompleted() {
161 |
162 | }
163 |
164 | @Override
165 | public void onError(Throwable e) {
166 | setEnabled(true);
167 | mMsgTV.setText(e.toString());
168 | }
169 |
170 | @Override
171 | public void onNext(String s) {
172 | mMsgTV.setText(s);
173 | setEnabled(true);
174 | if (s.equals("success")) {
175 | mPatchTV.setText(mPatchPath);
176 | mPatchSizeTV.setText(String.format("%.2f M", getFileSize(new File(mPatchPath))));
177 | }
178 | }
179 | });
180 | break;
181 | case R.id.get_new_apk_btn:
182 | File oldApk = new File(mOldApk);
183 | File patch = new File(mPatchPath);
184 | final File newApk2 = new File(mNewApk2);
185 | if (!oldApk.exists()) {
186 | mMsgTV.setText("旧APK不存在");
187 | return;
188 | }
189 | if (!patch.exists()) {
190 | mMsgTV.setText("补丁文件不存在");
191 | return;
192 | }
193 | if (newApk2.exists()) {
194 | newApk2.delete();
195 | }
196 | setEnabled(false);
197 | mSubscription = Observable.just("")
198 | .map(new Func1() {
199 | @Override
200 | public Integer call(String s) {
201 | return PatchUtil.patch(mOldApk, mNewApk2, mPatchPath);
202 | }
203 | })
204 | .map(new Func1() {
205 | @Override
206 | public String call(Integer integer) {
207 | return checkResult(integer);
208 | }
209 | })
210 | .subscribeOn(Schedulers.io())
211 | .observeOn(AndroidSchedulers.mainThread())
212 | .subscribe(new Subscriber() {
213 | @Override
214 | public void onCompleted() {
215 |
216 | }
217 |
218 | @Override
219 | public void onError(Throwable e) {
220 | setEnabled(true);
221 | mMsgTV.setText(e.toString());
222 | }
223 |
224 | @Override
225 | public void onNext(String s) {
226 | mMsgTV.setText(s);
227 | setEnabled(true);
228 | if (s.equals("success")) {
229 | mNewApk2TV.setText(mNewApk2);
230 | mNewApk2SizeTV.setText(String.format("%.2f M", getFileSize(newApk2)));
231 | mNewApk2Md5TV.setText(SignUtil.getMd5ByFile(newApk2));
232 | }
233 | }
234 | });
235 | break;
236 | case R.id.delete_btn:
237 | clearText();
238 | setEnabled(false);
239 | File la = new File(mNewApk2);
240 | if (la.exists()){
241 | la.delete();
242 | }
243 | File ji = new File(mPatchPath);
244 | if (ji.exists()){
245 | ji.delete();
246 | }
247 | setEnabled(true);
248 | break;
249 | }
250 | }
251 |
252 | private String checkResult(int ret) {
253 | switch (ret) {
254 | case 0:
255 | return "success";
256 | case 1:
257 | return "缺少文件路径";
258 | case 2:
259 | return "读取旧apk失败";
260 | case 3:
261 | return "读取新的apk失败";
262 | case 4:
263 | return "打开或读取patch文件失败";
264 | case 5:
265 | return "内存分配失败";
266 | case 6:
267 | return "创建、打开或读取patch文件失败";
268 | case 7:
269 | return "计算文件差异性或者写入patch文件失败";
270 | case 8:
271 | return "计算压缩的大小差异数据失败";
272 | case 9:
273 | return "无用补丁";
274 | case 10:
275 | return "合并apk失败";
276 | }
277 | return "未知错误";
278 | }
279 |
280 | private float getFileSize(File file) {
281 | return (float) (file.length() / (1024 * 1024 * 1.0));
282 | }
283 |
284 | private void clearText() {
285 | mOldApkTV.setText("");
286 | mOldApkSizeTV.setText("");
287 | mOldApkMd5TV.setText("");
288 | mNewApkTV.setText("");
289 | mNewApkSizeTV.setText("");
290 | mNewApkMd5TV.setText("");
291 | mPatchTV.setText("");
292 | mPatchSizeTV.setText("");
293 | mNewApk2TV.setText("");
294 | mNewApk2SizeTV.setText("");
295 | mNewApk2Md5TV.setText("");
296 | mMsgTV.setText("");
297 | }
298 |
299 | private void setEnabled(boolean enabled) {
300 | mLoading.setVisibility(!enabled ? View.VISIBLE : View.GONE);
301 | mGetNewApkBtn.setEnabled(enabled);
302 | mGetPatchBtn.setEnabled(enabled);
303 | mDeleteBtn.setEnabled(enabled);
304 | }
305 |
306 | @Override
307 | public void onBackPressed() {
308 | if (mSubscription != null) {
309 | mSubscription.unsubscribe();
310 | }
311 | super.onBackPressed();
312 | }
313 |
314 | @Override
315 | protected void onDestroy() {
316 | if (mSubscription != null) {
317 | mSubscription.unsubscribe();
318 | }
319 | super.onDestroy();
320 | }
321 |
322 |
323 | }
324 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/java/com/wang/appaddupdatedemo/PermissionUtil.java:
--------------------------------------------------------------------------------
1 | package com.wang.appaddupdatedemo;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.pm.PackageManager;
6 | import android.support.v4.content.ContextCompat;
7 |
8 | import java.util.List;
9 |
10 | /**
11 | * Utility class that wraps access to the runtime permissions API in M and provides basic helper
12 | * methods.
13 | */
14 | public abstract class PermissionUtil {
15 |
16 |
17 | public static boolean checkSelfPermission(Context context, String... permissions){
18 |
19 | if (permissions.length < 1){
20 | return false;
21 | }
22 |
23 | for (String permission : permissions){
24 | if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED){
25 | return true;
26 | }
27 | }
28 |
29 | return false;
30 | }
31 | /**
32 | * Check that all given permissions have been granted by verifying that each entry in the
33 | * given array is of the value {@link PackageManager#PERMISSION_GRANTED}.
34 | *
35 | * @see Activity#onRequestPermissionsResult(int, String[], int[])
36 | */
37 | public static boolean verifyPermissions(int[] grantResults) {
38 | // At least one result must be checked.
39 | if(grantResults.length < 1){
40 | return false;
41 | }
42 |
43 | // Verify that each required permission has been granted, otherwise return false.
44 | for (int result : grantResults) {
45 | if (result != PackageManager.PERMISSION_GRANTED) {
46 | return false;
47 | }
48 | }
49 | return true;
50 | }
51 |
52 | /**
53 | * Check that all given permissions have been granted by verifying that each entry in the
54 | * given array is of the value {@link PackageManager#PERMISSION_GRANTED}.
55 | *
56 | * @see Activity#onRequestPermissionsResult(int, String[], int[])
57 | *
58 | * @param permissions all permissions
59 | */
60 | public static boolean verifyPermissions(List permissions, int[] grantResults) {
61 | // At least one result must be checked.
62 | if(grantResults.length < 1){
63 | return false;
64 | }
65 |
66 | // Verify that each required permission has been granted, otherwise return false.
67 | for (int i = 0; i < grantResults.length ; i++) {
68 | if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
69 | return false;
70 | }
71 | permissions.remove(i);
72 | }
73 | return true;
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/jniLibs/armeabi-v7a/libApkPatchLibrary.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingwang666/AppAddUpdate/2a5fe4dd91c6781eb72b30f452333bbb5f4461da/AppAddUpdateDemo/app/src/main/jniLibs/armeabi-v7a/libApkPatchLibrary.so
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/jniLibs/armeabi/libApkPatchLibrary.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingwang666/AppAddUpdate/2a5fe4dd91c6781eb72b30f452333bbb5f4461da/AppAddUpdateDemo/app/src/main/jniLibs/armeabi/libApkPatchLibrary.so
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/jniLibs/x86/libApkPatchLibrary.so:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingwang666/AppAddUpdate/2a5fe4dd91c6781eb72b30f452333bbb5f4461da/AppAddUpdateDemo/app/src/main/jniLibs/x86/libApkPatchLibrary.so
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
10 |
11 |
12 |
17 |
18 |
24 |
25 |
32 |
33 |
40 |
41 |
48 |
49 |
56 |
57 |
64 |
65 |
71 |
72 |
78 |
79 |
86 |
87 |
94 |
95 |
102 |
103 |
110 |
111 |
119 |
120 |
128 |
129 |
130 |
138 |
139 |
140 |
141 |
142 |
143 |
149 |
150 |
151 |
152 |
153 |
154 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingwang666/AppAddUpdate/2a5fe4dd91c6781eb72b30f452333bbb5f4461da/AppAddUpdateDemo/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingwang666/AppAddUpdate/2a5fe4dd91c6781eb72b30f452333bbb5f4461da/AppAddUpdateDemo/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingwang666/AppAddUpdate/2a5fe4dd91c6781eb72b30f452333bbb5f4461da/AppAddUpdateDemo/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingwang666/AppAddUpdate/2a5fe4dd91c6781eb72b30f452333bbb5f4461da/AppAddUpdateDemo/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingwang666/AppAddUpdate/2a5fe4dd91c6781eb72b30f452333bbb5f4461da/AppAddUpdateDemo/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | AppAddUpdateDemo
3 |
4 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/app/src/test/java/com/wang/appaddupdatedemo/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.wang.appaddupdatedemo;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/AppAddUpdateDemo/appupdate/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/appupdate/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion "25.0.0"
6 |
7 | defaultConfig {
8 | minSdkVersion 17
9 | targetSdkVersion 25
10 | versionCode 102
11 | versionName "1.0.2"
12 |
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | compileOptions {
21 | sourceCompatibility JavaVersion.VERSION_1_7
22 | targetCompatibility JavaVersion.VERSION_1_7
23 | }
24 | }
25 |
26 | dependencies {
27 |
28 | }
29 |
30 | apply from: '../bintray.gradle'
--------------------------------------------------------------------------------
/AppAddUpdateDemo/appupdate/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/appupdate/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/appupdate/src/main/java/com/wang/appupdate/util/ApkUtil.java:
--------------------------------------------------------------------------------
1 | package com.wang.appupdate.util;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.pm.ApplicationInfo;
6 | import android.content.pm.PackageInfo;
7 | import android.content.pm.PackageManager;
8 | import android.content.pm.PackageManager.NameNotFoundException;
9 | import android.net.Uri;
10 | import android.text.TextUtils;
11 |
12 | import java.util.Iterator;
13 | import java.util.List;
14 |
15 | public class ApkUtil {
16 |
17 | /**
18 | * 获取已安装apk的PackageInfo
19 | *
20 | * @param context
21 | * @param packageName
22 | * @return
23 | */
24 | public static PackageInfo getInstalledApkPackageInfo(Context context, String packageName) {
25 | PackageManager pm = context.getPackageManager();
26 | List apps = pm.getInstalledPackages(PackageManager.GET_SIGNATURES);
27 |
28 | Iterator it = apps.iterator();
29 | while (it.hasNext()) {
30 | PackageInfo packageinfo = it.next();
31 | String thisName = packageinfo.packageName;
32 | if (thisName.equals(packageName)) {
33 | return packageinfo;
34 | }
35 | }
36 |
37 | return null;
38 | }
39 |
40 | /**
41 | * 判断apk是否已安装
42 | *
43 | * @param context
44 | * @param packageName
45 | * @return
46 | */
47 | public static boolean isInstalled(Context context, String packageName) {
48 | PackageManager pm = context.getPackageManager();
49 | boolean installed = false;
50 | try {
51 | pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
52 | installed = true;
53 | } catch (Exception e) {
54 | e.printStackTrace();
55 | }
56 |
57 | return installed;
58 | }
59 |
60 | /**
61 | * 获取已安装Apk文件的源Apk文件
62 | * 如:/data/app/com.sina.weibo-1.apk
63 | *
64 | * @param context
65 | * @param packageName
66 | * @return
67 | */
68 | public static String getSourceApkPath(Context context, String packageName) {
69 | if (TextUtils.isEmpty(packageName))
70 | return null;
71 |
72 | try {
73 | ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(packageName, 0);
74 | return appInfo.sourceDir;
75 | } catch (NameNotFoundException e) {
76 | e.printStackTrace();
77 | }
78 |
79 | return null;
80 | }
81 |
82 | public static String getSourceApkPath(Context context){
83 | if (context != null){
84 | try {
85 | ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0);
86 | return appInfo.sourceDir;
87 | } catch (NameNotFoundException e) {
88 | e.printStackTrace();
89 | }
90 | }
91 | return null;
92 | }
93 |
94 | /**
95 | * 安装Apk
96 | *
97 | * @param context
98 | * @param apkPath
99 | */
100 | public static void installApk(Context context, String apkPath) {
101 |
102 | Intent intent = new Intent(Intent.ACTION_VIEW);
103 | intent.setDataAndType(Uri.parse("file://" + apkPath),
104 | "application/vnd.android.package-archive");
105 |
106 | context.startActivity(intent);
107 | }
108 | }
--------------------------------------------------------------------------------
/AppAddUpdateDemo/appupdate/src/main/java/com/wang/appupdate/util/PatchUtil.java:
--------------------------------------------------------------------------------
1 | package com.wang.appupdate.util;
2 |
3 | /**
4 | * Created on 2016/9/8.
5 | * Author: wang
6 | */
7 | public class PatchUtil {
8 |
9 | static {
10 | System.loadLibrary("ApkPatchLibrary");
11 | }
12 | /**
13 | * native方法 比较路径为oldPath的apk与newPath的apk之间差异,并生成patch包,存储于patchPath
14 | *
15 | * 返回:0,说明操作成功
16 | *
17 | * @param oldApkPath
18 | * 示例:/sdcard/old.apk
19 | * @param newApkPath
20 | * 示例:/sdcard/new.apk
21 | * @param patchPath
22 | * 示例:/sdcard/xx.patch
23 | * @return
24 | */
25 | public static native int diff(String oldApkPath, String newApkPath, String patchPath);
26 |
27 | /**
28 | * native方法 使用路径为oldApkPath的apk与路径为patchPath的补丁包,合成新的apk,并存储于newApkPath
29 | *
30 | * 返回:0,说明操作成功
31 | *
32 | * @param oldApkPath 示例:/sdcard/old.apk
33 | * @param newApkPath 示例:/sdcard/new.apk
34 | * @param patchPath 示例:/sdcard/xx.patch
35 | * @return
36 | */
37 | public static native int patch(String oldApkPath, String newApkPath, String patchPath);
38 | }
39 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/appupdate/src/main/java/com/wang/appupdate/util/SignUtil.java:
--------------------------------------------------------------------------------
1 | package com.wang.appupdate.util;
2 |
3 | import android.text.TextUtils;
4 | import android.util.Log;
5 |
6 |
7 | import java.io.File;
8 | import java.io.FileInputStream;
9 | import java.io.IOException;
10 | import java.security.MessageDigest;
11 |
12 | public class SignUtil {
13 |
14 |
15 | private static String bytes2Hex(byte[] src) {
16 | char[] res = new char[src.length * 2];
17 | final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
18 | for (int i = 0, j = 0; i < src.length; i++) {
19 | res[j++] = hexDigits[src[i] >>> 4 & 0x0f];
20 | res[j++] = hexDigits[src[i] & 0x0f];
21 | }
22 |
23 | return new String(res);
24 | }
25 |
26 | public static String getMd5ByFile(File file) {
27 | String value = null;
28 | FileInputStream in = null;
29 | try {
30 | in = new FileInputStream(file);
31 |
32 | MessageDigest digester = MessageDigest.getInstance("MD5");
33 | byte[] bytes = new byte[8192];
34 | int byteCount;
35 | while ((byteCount = in.read(bytes)) > 0) {
36 | digester.update(bytes, 0, byteCount);
37 | }
38 | value = bytes2Hex(digester.digest());
39 | } catch (Exception e) {
40 | e.printStackTrace();
41 | } finally {
42 | if (null != in) {
43 | try {
44 | in.close();
45 | } catch (IOException e) {
46 | e.printStackTrace();
47 | }
48 | }
49 | }
50 | return value;
51 | }
52 |
53 | /**
54 | * 判断文件的MD5是否为指定值
55 | *
56 | * @param file
57 | * @param md5
58 | * @return
59 | */
60 | public static boolean checkMd5(File file, String md5) {
61 | if (TextUtils.isEmpty(md5)) {
62 | throw new RuntimeException("md5 cannot be empty");
63 | }
64 |
65 | String fileMd5 = getMd5ByFile(file);
66 |
67 | Log.d("SignUtil", String.format("file's md5=%s, real md5=%s", fileMd5, md5));
68 |
69 |
70 | if (md5.equals(fileMd5)) {
71 | return true;
72 | } else {
73 | return false;
74 | }
75 | }
76 |
77 | /**
78 | * 判断文件的MD5是否为指定值
79 | *
80 | * @param filePath
81 | * @param md5
82 | * @return
83 | */
84 | public static boolean checkMd5(String filePath, String md5) {
85 | return checkMd5(new File(filePath), md5);
86 | }
87 | }
--------------------------------------------------------------------------------
/AppAddUpdateDemo/appupdate/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | AppUpdate
3 |
4 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/bintray.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.github.dcendents.android-maven'
2 | apply plugin: 'com.jfrog.bintray'
3 |
4 | version = "1.0.2" // 这是库版本部署工件时使用
5 |
6 | def siteUrl = 'https://github.com/kingwang666/AppAddUpdate' // 项目的主页
7 | def gitUrl = 'https://github.com/kingwang666/AppAddUpdate.git' // Git仓库的url
8 | group = "com.wang.appupdate" // Maven Group ID for the artifact,一般填你唯一的包名
9 |
10 | install {
11 | repositories.mavenInstaller {
12 | // This generates POM.xml with proper parameters
13 | pom {
14 | project {
15 | packaging 'aar'
16 | name 'Android App Update' // 项目描述
17 | url siteUrl
18 | licenses {
19 | license {
20 | name 'The Apache Software License, Version 2.0'
21 | url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
22 | }
23 | }
24 | developers {
25 | developer {
26 | id 'kingwang666' // 开发者信息
27 | name 'wangxiaojie' // 开发者信息
28 | email 'wangxiaojielove@hotmail.com' // 开发者信息
29 | }
30 | }
31 | scm {
32 | connection gitUrl
33 | developerConnection gitUrl
34 | url siteUrl
35 | }
36 | }
37 | }
38 | }
39 | }
40 |
41 | task sourcesJar(type: Jar) {
42 | from android.sourceSets.main.java.srcDirs
43 | classifier = 'sources'
44 | }
45 |
46 | task javadoc(type: Javadoc) {
47 | source = android.sourceSets.main.java.srcDirs
48 | classpath += project.files(android.getBootClasspath().join(File.pathSeparator))
49 | }
50 |
51 | task javadocJar(type: Jar, dependsOn: javadoc) {
52 | classifier = 'javadoc'
53 | from javadoc.destinationDir
54 | }
55 |
56 | javadoc {
57 | options {
58 | encoding "UTF-8"
59 | charSet 'UTF-8'
60 | author true
61 | version true
62 | links "http://docs.oracle.com/javase/7/docs/api"
63 | title 'Android App Update' // 文档标题
64 | }
65 | }
66 |
67 | artifacts {
68 | archives javadocJar
69 | archives sourcesJar
70 | }
71 |
72 | Properties properties = new Properties()
73 | properties.load(project.rootProject.file('local.properties').newDataInputStream())
74 | bintray {
75 | user = properties.getProperty("bintray.user")
76 | key = properties.getProperty("bintray.apikey")
77 | configurations = ['archives']
78 | pkg {
79 | repo = "maven"
80 | name = "appupdate" // 发布到JCenter上的项目名字
81 | websiteUrl = siteUrl
82 | vcsUrl = gitUrl
83 | licenses = ["Apache-2.0"]
84 | publish = true
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | mavenCentral()
7 | }
8 | dependencies {
9 | classpath 'com.android.tools.build:gradle:2.2.2'
10 | classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
11 | classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
12 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7'
13 | // NOTE: Do not place your application dependencies here; they belong
14 | // in the individual module build.gradle files
15 | }
16 | }
17 |
18 | allprojects {
19 | repositories {
20 | jcenter()
21 | }
22 | }
23 |
24 | task clean(type: Delete) {
25 | delete rootProject.buildDir
26 | }
27 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
--------------------------------------------------------------------------------
/AppAddUpdateDemo/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingwang666/AppAddUpdate/2a5fe4dd91c6781eb72b30f452333bbb5f4461da/AppAddUpdateDemo/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/AppAddUpdateDemo/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Sep 09 11:31:01 CST 2016
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/AppAddUpdateDemo/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':appupdate'
2 |
--------------------------------------------------------------------------------
/AppUpdate/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea
5 | .DS_Store
6 | /build
7 | /captures
8 |
--------------------------------------------------------------------------------
/AppUpdate/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/AppUpdate/app/app-release.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingwang666/AppAddUpdate/2a5fe4dd91c6781eb72b30f452333bbb5f4461da/AppUpdate/app/app-release.apk
--------------------------------------------------------------------------------
/AppUpdate/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 23
5 | buildToolsVersion "23.0.3"
6 |
7 | defaultConfig {
8 | applicationId "com.wang.appupdate"
9 | minSdkVersion 17
10 | targetSdkVersion 23
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | ndk{
15 | moduleName "ApkPatchLibrary"
16 | ldLibs "log", "z", "m" //添加依赖库文件,因为有log打印等
17 | abiFilters "armeabi", "armeabi-v7a", "x86"
18 | }
19 | }
20 | buildTypes {
21 | release {
22 | minifyEnabled false
23 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
24 | }
25 | }
26 |
27 | // sourceSets {
28 | // main {
29 | // jni.srcDirs = ['src/main/jni', 'src/main/jni/']
30 | // // jniLibs.srcDirs = ['libs'] // 若不想编译jni代码,可直接引用so库,ndk编译相关脚本注释掉
31 | // }
32 | // }
33 | }
34 |
35 | dependencies {
36 | compile fileTree(dir: 'libs', include: ['*.jar'])
37 | testCompile 'junit:junit:4.12'
38 | compile 'com.android.support:appcompat-v7:24.2.0'
39 | }
40 |
--------------------------------------------------------------------------------
/AppUpdate/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/androidTest/java/com/wang/appupdate/ApplicationTest.java:
--------------------------------------------------------------------------------
1 | package com.wang.appupdate;
2 |
3 | import android.app.Application;
4 | import android.test.ApplicationTestCase;
5 |
6 | /**
7 | * Testing Fundamentals
8 | */
9 | public class ApplicationTest extends ApplicationTestCase {
10 | public ApplicationTest() {
11 | super(Application.class);
12 | }
13 | }
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/java/com/wang/appupdate/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.wang.appupdate;
2 |
3 | import android.os.Environment;
4 | import android.support.v4.os.EnvironmentCompat;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.os.Bundle;
7 | import android.util.Log;
8 |
9 |
10 | import com.wang.appupdate.util.ApkUtil;
11 | import com.wang.appupdate.util.PatchUtil;
12 | import com.wang.appupdate.util.SignUtil;
13 |
14 | import java.io.File;
15 |
16 | public class MainActivity extends AppCompatActivity {
17 |
18 | String path = Environment.getExternalStorageDirectory().getAbsolutePath();
19 |
20 | @Override
21 | protected void onCreate(Bundle savedInstanceState) {
22 | super.onCreate(savedInstanceState);
23 | setContentView(R.layout.activity_main);
24 | Log.d("MainActivity", ApkUtil.getSourceApkPath(this));
25 | new Thread(new Runnable() {
26 | @Override
27 | public void run() {
28 | // if (PatchUtil.diff(path + "/jiudeng1.apk", path + "/jiudeng2.apk", path + "/test.patch") == 0) {
29 | // PatchUtil.patch(path + "/jiudeng1.apk", path + "/jiudeng3.apk", path + "/test.patch");
30 | // boolean success = SignUtil.checkMd5(path + "/jiudeng2.apk", SignUtil.getMd5ByFile(new File(path + "/jiudeng3.apk")));
31 | // Log.d("MainActivity", success ? "true" : "false");
32 | // }
33 | boolean success = ApkUtil.saveApk(new File(ApkUtil.getSourceApkPath(MainActivity.this, "com.wang.giftforbestred")), path + "/gift.apk");
34 | if (success){
35 | Log.d("test", "success");
36 | }
37 | else {
38 | Log.d("test", "error");
39 | }
40 | }
41 | }).start();
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/java/com/wang/appupdate/util/ApkUtil.java:
--------------------------------------------------------------------------------
1 | package com.wang.appupdate.util;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.content.pm.ApplicationInfo;
6 | import android.content.pm.PackageInfo;
7 | import android.content.pm.PackageManager;
8 | import android.content.pm.PackageManager.NameNotFoundException;
9 | import android.net.Uri;
10 | import android.text.TextUtils;
11 |
12 | import com.wang.appupdate.BuildConfig;
13 |
14 | import java.io.File;
15 | import java.io.FileDescriptor;
16 | import java.io.FileInputStream;
17 | import java.io.FileNotFoundException;
18 | import java.io.FileOutputStream;
19 | import java.io.IOException;
20 | import java.io.InputStream;
21 | import java.io.RandomAccessFile;
22 | import java.util.Iterator;
23 | import java.util.List;
24 |
25 | public class ApkUtil {
26 |
27 | /**
28 | * 获取已安装apk的PackageInfo
29 | *
30 | * @param context
31 | * @param packageName
32 | * @return
33 | */
34 | public static PackageInfo getInstalledApkPackageInfo(Context context, String packageName) {
35 | PackageManager pm = context.getPackageManager();
36 | List apps = pm.getInstalledPackages(PackageManager.GET_SIGNATURES);
37 |
38 | Iterator it = apps.iterator();
39 | while (it.hasNext()) {
40 | PackageInfo packageinfo = it.next();
41 | String thisName = packageinfo.packageName;
42 | if (thisName.equals(packageName)) {
43 | return packageinfo;
44 | }
45 | }
46 |
47 | return null;
48 | }
49 |
50 | /**
51 | * 判断apk是否已安装
52 | *
53 | * @param context
54 | * @param packageName
55 | * @return
56 | */
57 | public static boolean isInstalled(Context context, String packageName) {
58 | PackageManager pm = context.getPackageManager();
59 | boolean installed = false;
60 | try {
61 | pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
62 | installed = true;
63 | } catch (Exception e) {
64 | e.printStackTrace();
65 | }
66 |
67 | return installed;
68 | }
69 |
70 | /**
71 | * 获取已安装Apk文件的源Apk文件
72 | * 如:/data/app/com.sina.weibo-1.apk
73 | *
74 | * @param context
75 | * @param packageName
76 | * @return
77 | */
78 | public static String getSourceApkPath(Context context, String packageName) {
79 | if (TextUtils.isEmpty(packageName))
80 | return null;
81 |
82 | try {
83 | ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(packageName, 0);
84 | return appInfo.sourceDir;
85 | } catch (NameNotFoundException e) {
86 | e.printStackTrace();
87 | }
88 |
89 | return null;
90 | }
91 |
92 | public static String getSourceApkPath(Context context) {
93 | if (context != null) {
94 | try {
95 | ApplicationInfo appInfo = context.getPackageManager().getApplicationInfo(context.getPackageName(), 0);
96 | return appInfo.sourceDir;
97 | } catch (NameNotFoundException e) {
98 | e.printStackTrace();
99 | }
100 | }
101 | return null;
102 | }
103 |
104 | /**
105 | * 保存apk文件到指定位置
106 | * @param apk apk文件
107 | * @param savePath 保存的位置
108 | * @return
109 | */
110 | public static boolean saveApk(File apk, String savePath) {
111 | FileInputStream in = null;
112 | RandomAccessFile accessFile = null;
113 | try {
114 | in = new FileInputStream(apk);
115 | byte[] buf = new byte[1024 * 4];
116 | int len;
117 | File file = new File(savePath);
118 | accessFile = new RandomAccessFile(file, "rw");
119 | FileDescriptor fd = accessFile.getFD();
120 | while ((len = in.read(buf)) != -1) {
121 | accessFile.write(buf, 0, len);
122 | }
123 | fd.sync();
124 | accessFile.close();
125 | in.close();
126 | return true;
127 | } catch (Exception e) {
128 | e.printStackTrace();
129 | try {
130 | if (in != null){
131 | in.close();
132 | }
133 | if (accessFile != null){
134 | accessFile.close();
135 | }
136 | } catch (IOException e1) {
137 | e1.printStackTrace();
138 | }
139 | return false;
140 | }
141 | }
142 |
143 | /**
144 | * 安装Apk
145 | *
146 | * @param context
147 | * @param apkPath
148 | */
149 | public static void installApk(Context context, String apkPath) {
150 |
151 | Intent intent = new Intent(Intent.ACTION_VIEW);
152 | intent.setDataAndType(Uri.parse("file://" + apkPath),
153 | "application/vnd.android.package-archive");
154 |
155 | context.startActivity(intent);
156 | }
157 | }
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/java/com/wang/appupdate/util/PatchUtil.java:
--------------------------------------------------------------------------------
1 | package com.wang.appupdate.util;
2 |
3 | /**
4 | * Created on 2016/9/8.
5 | * Author: wang
6 | */
7 | public class PatchUtil {
8 |
9 | static {
10 | System.loadLibrary("ApkPatchLibrary");
11 | }
12 | /**
13 | * native方法 比较路径为oldPath的apk与newPath的apk之间差异,并生成patch包,存储于patchPath
14 | *
15 | * 返回:0,说明操作成功
16 | *
17 | * @param oldApkPath
18 | * 示例:/sdcard/old.apk
19 | * @param newApkPath
20 | * 示例:/sdcard/new.apk
21 | * @param patchPath
22 | * 示例:/sdcard/xx.patch
23 | * @return
24 | */
25 | public static native int diff(String oldApkPath, String newApkPath, String patchPath);
26 |
27 | /**
28 | * native方法 使用路径为oldApkPath的apk与路径为patchPath的补丁包,合成新的apk,并存储于newApkPath
29 | *
30 | * 返回:0,说明操作成功
31 | *
32 | * @param oldApkPath 示例:/sdcard/old.apk
33 | * @param newApkPath 示例:/sdcard/new.apk
34 | * @param patchPath 示例:/sdcard/xx.patch
35 | * @return
36 | */
37 | public static native int patch(String oldApkPath, String newApkPath, String patchPath);
38 | }
39 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/java/com/wang/appupdate/util/SignUtil.java:
--------------------------------------------------------------------------------
1 | package com.wang.appupdate.util;
2 |
3 | import android.text.TextUtils;
4 | import android.util.Log;
5 |
6 | import com.wang.appupdate.BuildConfig;
7 |
8 | import java.io.File;
9 | import java.io.FileInputStream;
10 | import java.io.IOException;
11 | import java.security.MessageDigest;
12 |
13 | public class SignUtil {
14 |
15 |
16 | private static String bytes2Hex(byte[] src) {
17 | char[] res = new char[src.length * 2];
18 | final char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
19 | for (int i = 0, j = 0; i < src.length; i++) {
20 | res[j++] = hexDigits[src[i] >>> 4 & 0x0f];
21 | res[j++] = hexDigits[src[i] & 0x0f];
22 | }
23 |
24 | return new String(res);
25 | }
26 |
27 | public static String getMd5ByFile(File file) {
28 | String value = null;
29 | FileInputStream in = null;
30 | try {
31 | in = new FileInputStream(file);
32 |
33 | MessageDigest digester = MessageDigest.getInstance("MD5");
34 | byte[] bytes = new byte[8192];
35 | int byteCount;
36 | while ((byteCount = in.read(bytes)) > 0) {
37 | digester.update(bytes, 0, byteCount);
38 | }
39 | value = bytes2Hex(digester.digest());
40 | } catch (Exception e) {
41 | e.printStackTrace();
42 | } finally {
43 | if (null != in) {
44 | try {
45 | in.close();
46 | } catch (IOException e) {
47 | e.printStackTrace();
48 | }
49 | }
50 | }
51 | return value;
52 | }
53 |
54 | /**
55 | * 判断文件的MD5是否为指定值
56 | *
57 | * @param file
58 | * @param md5
59 | * @return
60 | */
61 | public static boolean checkMd5(File file, String md5) {
62 | if (TextUtils.isEmpty(md5)) {
63 | throw new RuntimeException("md5 cannot be empty");
64 | }
65 |
66 | String fileMd5 = getMd5ByFile(file);
67 |
68 | if (BuildConfig.DEBUG) {
69 | Log.d("SignUtils", String.format("file's md5=%s, real md5=%s", fileMd5, md5));
70 | }
71 |
72 |
73 | if (md5.equals(fileMd5)) {
74 | return true;
75 | } else {
76 | return false;
77 | }
78 | }
79 |
80 | /**
81 | * 判断文件的MD5是否为指定值
82 | *
83 | * @param filePath
84 | * @param md5
85 | * @return
86 | */
87 | public static boolean checkMd5(String filePath, String md5) {
88 | return checkMd5(new File(filePath), md5);
89 | }
90 | }
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/jni/bzip2/bzip2recover.c:
--------------------------------------------------------------------------------
1 | /*-----------------------------------------------------------*/
2 | /*--- Block recoverer program for bzip2 ---*/
3 | /*--- bzip2recover.c ---*/
4 | /*-----------------------------------------------------------*/
5 |
6 | /* ------------------------------------------------------------------
7 | This file is part of bzip2/libbzip2, a program and library for
8 | lossless, block-sorting data compression.
9 |
10 | bzip2/libbzip2 version 1.0.6 of 6 September 2010
11 | Copyright (C) 1996-2010 Julian Seward
12 |
13 | Please read the WARNING, DISCLAIMER and PATENTS sections in the
14 | README file.
15 |
16 | This program is released under the terms of the license contained
17 | in the file LICENSE.
18 | ------------------------------------------------------------------ */
19 |
20 | /* This program is a complete hack and should be rewritten properly.
21 | It isn't very complicated. */
22 |
23 | #include
24 | #include
25 | #include
26 | #include
27 |
28 |
29 | /* This program records bit locations in the file to be recovered.
30 | That means that if 64-bit ints are not supported, we will not
31 | be able to recover .bz2 files over 512MB (2^32 bits) long.
32 | On GNU supported platforms, we take advantage of the 64-bit
33 | int support to circumvent this problem. Ditto MSVC.
34 |
35 | This change occurred in version 1.0.2; all prior versions have
36 | the 512MB limitation.
37 | */
38 | #ifdef __GNUC__
39 | typedef unsigned long long int MaybeUInt64;
40 | # define MaybeUInt64_FMT "%Lu"
41 | #else
42 | #ifdef _MSC_VER
43 | typedef unsigned __int64 MaybeUInt64;
44 | # define MaybeUInt64_FMT "%I64u"
45 | #else
46 | typedef unsigned int MaybeUInt64;
47 | # define MaybeUInt64_FMT "%u"
48 | #endif
49 | #endif
50 |
51 | typedef unsigned int UInt32;
52 | typedef int Int32;
53 | typedef unsigned char UChar;
54 | typedef char Char;
55 | typedef unsigned char Bool;
56 | #define True ((Bool)1)
57 | #define False ((Bool)0)
58 |
59 |
60 | #define BZ_MAX_FILENAME 2000
61 |
62 | Char inFileName[BZ_MAX_FILENAME];
63 | Char outFileName[BZ_MAX_FILENAME];
64 | Char progName[BZ_MAX_FILENAME];
65 |
66 | MaybeUInt64 bytesOut = 0;
67 | MaybeUInt64 bytesIn = 0;
68 |
69 |
70 | /*---------------------------------------------------*/
71 | /*--- Header bytes ---*/
72 | /*---------------------------------------------------*/
73 |
74 | #define BZ_HDR_B 0x42 /* 'B' */
75 | #define BZ_HDR_Z 0x5a /* 'Z' */
76 | #define BZ_HDR_h 0x68 /* 'h' */
77 | #define BZ_HDR_0 0x30 /* '0' */
78 |
79 |
80 | /*---------------------------------------------------*/
81 | /*--- I/O errors ---*/
82 | /*---------------------------------------------------*/
83 |
84 | /*---------------------------------------------*/
85 | static void readError ( void )
86 | {
87 | fprintf ( stderr,
88 | "%s: I/O error reading `%s', possible reason follows.\n",
89 | progName, inFileName );
90 | perror ( progName );
91 | fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
92 | progName );
93 | exit ( 1 );
94 | }
95 |
96 |
97 | /*---------------------------------------------*/
98 | static void writeError ( void )
99 | {
100 | fprintf ( stderr,
101 | "%s: I/O error reading `%s', possible reason follows.\n",
102 | progName, inFileName );
103 | perror ( progName );
104 | fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
105 | progName );
106 | exit ( 1 );
107 | }
108 |
109 |
110 | /*---------------------------------------------*/
111 | static void mallocFail ( Int32 n )
112 | {
113 | fprintf ( stderr,
114 | "%s: malloc failed on request for %d bytes.\n",
115 | progName, n );
116 | fprintf ( stderr, "%s: warning: output file(s) may be incomplete.\n",
117 | progName );
118 | exit ( 1 );
119 | }
120 |
121 |
122 | /*---------------------------------------------*/
123 | static void tooManyBlocks ( Int32 max_handled_blocks )
124 | {
125 | fprintf ( stderr,
126 | "%s: `%s' appears to contain more than %d blocks\n",
127 | progName, inFileName, max_handled_blocks );
128 | fprintf ( stderr,
129 | "%s: and cannot be handled. To fix, increase\n",
130 | progName );
131 | fprintf ( stderr,
132 | "%s: BZ_MAX_HANDLED_BLOCKS in bzip2recover.c, and recompile.\n",
133 | progName );
134 | exit ( 1 );
135 | }
136 |
137 |
138 |
139 | /*---------------------------------------------------*/
140 | /*--- Bit stream I/O ---*/
141 | /*---------------------------------------------------*/
142 |
143 | typedef
144 | struct {
145 | FILE* handle;
146 | Int32 buffer;
147 | Int32 buffLive;
148 | Char mode;
149 | }
150 | BitStream;
151 |
152 |
153 | /*---------------------------------------------*/
154 | static BitStream* bsOpenReadStream ( FILE* stream )
155 | {
156 | BitStream *bs = malloc ( sizeof(BitStream) );
157 | if (bs == NULL) mallocFail ( sizeof(BitStream) );
158 | bs->handle = stream;
159 | bs->buffer = 0;
160 | bs->buffLive = 0;
161 | bs->mode = 'r';
162 | return bs;
163 | }
164 |
165 |
166 | /*---------------------------------------------*/
167 | static BitStream* bsOpenWriteStream ( FILE* stream )
168 | {
169 | BitStream *bs = malloc ( sizeof(BitStream) );
170 | if (bs == NULL) mallocFail ( sizeof(BitStream) );
171 | bs->handle = stream;
172 | bs->buffer = 0;
173 | bs->buffLive = 0;
174 | bs->mode = 'w';
175 | return bs;
176 | }
177 |
178 |
179 | /*---------------------------------------------*/
180 | static void bsPutBit ( BitStream* bs, Int32 bit )
181 | {
182 | if (bs->buffLive == 8) {
183 | Int32 retVal = putc ( (UChar) bs->buffer, bs->handle );
184 | if (retVal == EOF) writeError();
185 | bytesOut++;
186 | bs->buffLive = 1;
187 | bs->buffer = bit & 0x1;
188 | } else {
189 | bs->buffer = ( (bs->buffer << 1) | (bit & 0x1) );
190 | bs->buffLive++;
191 | };
192 | }
193 |
194 |
195 | /*---------------------------------------------*/
196 | /*--
197 | Returns 0 or 1, or 2 to indicate EOF.
198 | --*/
199 | static Int32 bsGetBit ( BitStream* bs )
200 | {
201 | if (bs->buffLive > 0) {
202 | bs->buffLive --;
203 | return ( ((bs->buffer) >> (bs->buffLive)) & 0x1 );
204 | } else {
205 | Int32 retVal = getc ( bs->handle );
206 | if ( retVal == EOF ) {
207 | if (errno != 0) readError();
208 | return 2;
209 | }
210 | bs->buffLive = 7;
211 | bs->buffer = retVal;
212 | return ( ((bs->buffer) >> 7) & 0x1 );
213 | }
214 | }
215 |
216 |
217 | /*---------------------------------------------*/
218 | static void bsClose ( BitStream* bs )
219 | {
220 | Int32 retVal;
221 |
222 | if ( bs->mode == 'w' ) {
223 | while ( bs->buffLive < 8 ) {
224 | bs->buffLive++;
225 | bs->buffer <<= 1;
226 | };
227 | retVal = putc ( (UChar) (bs->buffer), bs->handle );
228 | if (retVal == EOF) writeError();
229 | bytesOut++;
230 | retVal = fflush ( bs->handle );
231 | if (retVal == EOF) writeError();
232 | }
233 | retVal = fclose ( bs->handle );
234 | if (retVal == EOF) {
235 | if (bs->mode == 'w') writeError(); else readError();
236 | }
237 | free ( bs );
238 | }
239 |
240 |
241 | /*---------------------------------------------*/
242 | static void bsPutUChar ( BitStream* bs, UChar c )
243 | {
244 | Int32 i;
245 | for (i = 7; i >= 0; i--)
246 | bsPutBit ( bs, (((UInt32) c) >> i) & 0x1 );
247 | }
248 |
249 |
250 | /*---------------------------------------------*/
251 | static void bsPutUInt32 ( BitStream* bs, UInt32 c )
252 | {
253 | Int32 i;
254 |
255 | for (i = 31; i >= 0; i--)
256 | bsPutBit ( bs, (c >> i) & 0x1 );
257 | }
258 |
259 |
260 | /*---------------------------------------------*/
261 | static Bool endsInBz2 ( Char* name )
262 | {
263 | Int32 n = strlen ( name );
264 | if (n <= 4) return False;
265 | return
266 | (name[n-4] == '.' &&
267 | name[n-3] == 'b' &&
268 | name[n-2] == 'z' &&
269 | name[n-1] == '2');
270 | }
271 |
272 |
273 | /*---------------------------------------------------*/
274 | /*--- ---*/
275 | /*---------------------------------------------------*/
276 |
277 | /* This logic isn't really right when it comes to Cygwin. */
278 | #ifdef _WIN32
279 | # define BZ_SPLIT_SYM '\\' /* path splitter on Windows platform */
280 | #else
281 | # define BZ_SPLIT_SYM '/' /* path splitter on Unix platform */
282 | #endif
283 |
284 | #define BLOCK_HEADER_HI 0x00003141UL
285 | #define BLOCK_HEADER_LO 0x59265359UL
286 |
287 | #define BLOCK_ENDMARK_HI 0x00001772UL
288 | #define BLOCK_ENDMARK_LO 0x45385090UL
289 |
290 | /* Increase if necessary. However, a .bz2 file with > 50000 blocks
291 | would have an uncompressed size of at least 40GB, so the chances
292 | are low you'll need to up this.
293 | */
294 | #define BZ_MAX_HANDLED_BLOCKS 50000
295 |
296 | MaybeUInt64 bStart [BZ_MAX_HANDLED_BLOCKS];
297 | MaybeUInt64 bEnd [BZ_MAX_HANDLED_BLOCKS];
298 | MaybeUInt64 rbStart[BZ_MAX_HANDLED_BLOCKS];
299 | MaybeUInt64 rbEnd [BZ_MAX_HANDLED_BLOCKS];
300 |
301 |
302 | /*-----------------------------------------------------------*/
303 | /*--- end bzip2recover.c ---*/
304 | /*-----------------------------------------------------------*/
305 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/jni/bzip2/bzlib.h:
--------------------------------------------------------------------------------
1 |
2 | /*-------------------------------------------------------------*/
3 | /*--- Public header file for the library. ---*/
4 | /*--- bzlib.h ---*/
5 | /*-------------------------------------------------------------*/
6 |
7 | /* ------------------------------------------------------------------
8 | This file is part of bzip2/libbzip2, a program and library for
9 | lossless, block-sorting data compression.
10 |
11 | bzip2/libbzip2 version 1.0.6 of 6 September 2010
12 | Copyright (C) 1996-2010 Julian Seward
13 |
14 | Please read the WARNING, DISCLAIMER and PATENTS sections in the
15 | README file.
16 |
17 | This program is released under the terms of the license contained
18 | in the file LICENSE.
19 | ------------------------------------------------------------------ */
20 |
21 |
22 | #ifndef _BZLIB_H
23 | #define _BZLIB_H
24 |
25 | #ifdef __cplusplus
26 | extern "C" {
27 | #endif
28 |
29 | #define BZ_RUN 0
30 | #define BZ_FLUSH 1
31 | #define BZ_FINISH 2
32 |
33 | #define BZ_OK 0
34 | #define BZ_RUN_OK 1
35 | #define BZ_FLUSH_OK 2
36 | #define BZ_FINISH_OK 3
37 | #define BZ_STREAM_END 4
38 | #define BZ_SEQUENCE_ERROR (-1)
39 | #define BZ_PARAM_ERROR (-2)
40 | #define BZ_MEM_ERROR (-3)
41 | #define BZ_DATA_ERROR (-4)
42 | #define BZ_DATA_ERROR_MAGIC (-5)
43 | #define BZ_IO_ERROR (-6)
44 | #define BZ_UNEXPECTED_EOF (-7)
45 | #define BZ_OUTBUFF_FULL (-8)
46 | #define BZ_CONFIG_ERROR (-9)
47 |
48 | typedef
49 | struct {
50 | char *next_in;
51 | unsigned int avail_in;
52 | unsigned int total_in_lo32;
53 | unsigned int total_in_hi32;
54 |
55 | char *next_out;
56 | unsigned int avail_out;
57 | unsigned int total_out_lo32;
58 | unsigned int total_out_hi32;
59 |
60 | void *state;
61 |
62 | void *(*bzalloc)(void *,int,int);
63 | void (*bzfree)(void *,void *);
64 | void *opaque;
65 | }
66 | bz_stream;
67 |
68 |
69 | #ifndef BZ_IMPORT
70 | #define BZ_EXPORT
71 | #endif
72 |
73 | #ifndef BZ_NO_STDIO
74 | /* Need a definitition for FILE */
75 | #include
76 | #endif
77 |
78 | #ifdef _WIN32
79 | # include
80 | # ifdef small
81 | /* windows.h define small to char */
82 | # undef small
83 | # endif
84 | # ifdef BZ_EXPORT
85 | # define BZ_API(func) WINAPI func
86 | # define BZ_EXTERN extern
87 | # else
88 | /* import windows dll dynamically */
89 | # define BZ_API(func) (WINAPI * func)
90 | # define BZ_EXTERN
91 | # endif
92 | #else
93 | # define BZ_API(func) func
94 | # define BZ_EXTERN extern
95 | #endif
96 |
97 |
98 | /*-- Core (low-level) library functions --*/
99 |
100 | BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
101 | bz_stream* strm,
102 | int blockSize100k,
103 | int verbosity,
104 | int workFactor
105 | );
106 |
107 | BZ_EXTERN int BZ_API(BZ2_bzCompress) (
108 | bz_stream* strm,
109 | int action
110 | );
111 |
112 | BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
113 | bz_stream* strm
114 | );
115 |
116 | BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
117 | bz_stream *strm,
118 | int verbosity,
119 | int small
120 | );
121 |
122 | BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
123 | bz_stream* strm
124 | );
125 |
126 | BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
127 | bz_stream *strm
128 | );
129 |
130 |
131 |
132 | /*-- High(er) level library functions --*/
133 |
134 | #ifndef BZ_NO_STDIO
135 | #define BZ_MAX_UNUSED 5000
136 |
137 | typedef void BZFILE;
138 |
139 | BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
140 | int* bzerror,
141 | FILE* f,
142 | int verbosity,
143 | int small,
144 | void* unused,
145 | int nUnused
146 | );
147 |
148 | BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
149 | int* bzerror,
150 | BZFILE* b
151 | );
152 |
153 | BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
154 | int* bzerror,
155 | BZFILE* b,
156 | void** unused,
157 | int* nUnused
158 | );
159 |
160 | BZ_EXTERN int BZ_API(BZ2_bzRead) (
161 | int* bzerror,
162 | BZFILE* b,
163 | void* buf,
164 | int len
165 | );
166 |
167 | BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
168 | int* bzerror,
169 | FILE* f,
170 | int blockSize100k,
171 | int verbosity,
172 | int workFactor
173 | );
174 |
175 | BZ_EXTERN void BZ_API(BZ2_bzWrite) (
176 | int* bzerror,
177 | BZFILE* b,
178 | void* buf,
179 | int len
180 | );
181 |
182 | BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
183 | int* bzerror,
184 | BZFILE* b,
185 | int abandon,
186 | unsigned int* nbytes_in,
187 | unsigned int* nbytes_out
188 | );
189 |
190 | BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
191 | int* bzerror,
192 | BZFILE* b,
193 | int abandon,
194 | unsigned int* nbytes_in_lo32,
195 | unsigned int* nbytes_in_hi32,
196 | unsigned int* nbytes_out_lo32,
197 | unsigned int* nbytes_out_hi32
198 | );
199 | #endif
200 |
201 |
202 | /*-- Utility functions --*/
203 |
204 | BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
205 | char* dest,
206 | unsigned int* destLen,
207 | char* source,
208 | unsigned int sourceLen,
209 | int blockSize100k,
210 | int verbosity,
211 | int workFactor
212 | );
213 |
214 | BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
215 | char* dest,
216 | unsigned int* destLen,
217 | char* source,
218 | unsigned int sourceLen,
219 | int small,
220 | int verbosity
221 | );
222 |
223 |
224 | /*--
225 | Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp)
226 | to support better zlib compatibility.
227 | This code is not _officially_ part of libbzip2 (yet);
228 | I haven't tested it, documented it, or considered the
229 | threading-safeness of it.
230 | If this code breaks, please contact both Yoshioka and me.
231 | --*/
232 |
233 | BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
234 | void
235 | );
236 |
237 | #ifndef BZ_NO_STDIO
238 | BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
239 | const char *path,
240 | const char *mode
241 | );
242 |
243 | BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
244 | int fd,
245 | const char *mode
246 | );
247 |
248 | BZ_EXTERN int BZ_API(BZ2_bzread) (
249 | BZFILE* b,
250 | void* buf,
251 | int len
252 | );
253 |
254 | BZ_EXTERN int BZ_API(BZ2_bzwrite) (
255 | BZFILE* b,
256 | void* buf,
257 | int len
258 | );
259 |
260 | BZ_EXTERN int BZ_API(BZ2_bzflush) (
261 | BZFILE* b
262 | );
263 |
264 | BZ_EXTERN void BZ_API(BZ2_bzclose) (
265 | BZFILE* b
266 | );
267 |
268 | BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
269 | BZFILE *b,
270 | int *errnum
271 | );
272 | #endif
273 |
274 | #ifdef __cplusplus
275 | }
276 | #endif
277 |
278 | #endif
279 |
280 | /*-------------------------------------------------------------*/
281 | /*--- end bzlib.h ---*/
282 | /*-------------------------------------------------------------*/
283 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/jni/bzip2/bzlib_private.h:
--------------------------------------------------------------------------------
1 |
2 | /*-------------------------------------------------------------*/
3 | /*--- Private header file for the library. ---*/
4 | /*--- bzlib_private.h ---*/
5 | /*-------------------------------------------------------------*/
6 |
7 | /* ------------------------------------------------------------------
8 | This file is part of bzip2/libbzip2, a program and library for
9 | lossless, block-sorting data compression.
10 |
11 | bzip2/libbzip2 version 1.0.6 of 6 September 2010
12 | Copyright (C) 1996-2010 Julian Seward
13 |
14 | Please read the WARNING, DISCLAIMER and PATENTS sections in the
15 | README file.
16 |
17 | This program is released under the terms of the license contained
18 | in the file LICENSE.
19 | ------------------------------------------------------------------ */
20 |
21 |
22 | #ifndef _BZLIB_PRIVATE_H
23 | #define _BZLIB_PRIVATE_H
24 |
25 | #include
26 |
27 | #ifndef BZ_NO_STDIO
28 | #include
29 | #include
30 | #include
31 | #endif
32 |
33 | #include "bzlib.h"
34 |
35 |
36 |
37 | /*-- General stuff. --*/
38 |
39 | #define BZ_VERSION "1.0.6, 6-Sept-2010"
40 |
41 | typedef char Char;
42 | typedef unsigned char Bool;
43 | typedef unsigned char UChar;
44 | typedef int Int32;
45 | typedef unsigned int UInt32;
46 | typedef short Int16;
47 | typedef unsigned short UInt16;
48 |
49 | #define True ((Bool)1)
50 | #define False ((Bool)0)
51 |
52 | #ifndef __GNUC__
53 | #define __inline__ /* */
54 | #endif
55 |
56 | #ifndef BZ_NO_STDIO
57 |
58 | extern void BZ2_bz__AssertH__fail ( int errcode );
59 | #define AssertH(cond,errcode) \
60 | { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); }
61 |
62 | #if BZ_DEBUG
63 | #define AssertD(cond,msg) \
64 | { if (!(cond)) { \
65 | fprintf ( stderr, \
66 | "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\
67 | exit(1); \
68 | }}
69 | #else
70 | #define AssertD(cond,msg) /* */
71 | #endif
72 |
73 | #define VPrintf0(zf) \
74 | fprintf(stderr,zf)
75 | #define VPrintf1(zf,za1) \
76 | fprintf(stderr,zf,za1)
77 | #define VPrintf2(zf,za1,za2) \
78 | fprintf(stderr,zf,za1,za2)
79 | #define VPrintf3(zf,za1,za2,za3) \
80 | fprintf(stderr,zf,za1,za2,za3)
81 | #define VPrintf4(zf,za1,za2,za3,za4) \
82 | fprintf(stderr,zf,za1,za2,za3,za4)
83 | #define VPrintf5(zf,za1,za2,za3,za4,za5) \
84 | fprintf(stderr,zf,za1,za2,za3,za4,za5)
85 |
86 | #else
87 |
88 | extern void bz_internal_error ( int errcode );
89 | #define AssertH(cond,errcode) \
90 | { if (!(cond)) bz_internal_error ( errcode ); }
91 | #define AssertD(cond,msg) do { } while (0)
92 | #define VPrintf0(zf) do { } while (0)
93 | #define VPrintf1(zf,za1) do { } while (0)
94 | #define VPrintf2(zf,za1,za2) do { } while (0)
95 | #define VPrintf3(zf,za1,za2,za3) do { } while (0)
96 | #define VPrintf4(zf,za1,za2,za3,za4) do { } while (0)
97 | #define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0)
98 |
99 | #endif
100 |
101 |
102 | #define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1)
103 | #define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp))
104 |
105 |
106 | /*-- Header bytes. --*/
107 |
108 | #define BZ_HDR_B 0x42 /* 'B' */
109 | #define BZ_HDR_Z 0x5a /* 'Z' */
110 | #define BZ_HDR_h 0x68 /* 'h' */
111 | #define BZ_HDR_0 0x30 /* '0' */
112 |
113 | /*-- Constants for the back end. --*/
114 |
115 | #define BZ_MAX_ALPHA_SIZE 258
116 | #define BZ_MAX_CODE_LEN 23
117 |
118 | #define BZ_RUNA 0
119 | #define BZ_RUNB 1
120 |
121 | #define BZ_N_GROUPS 6
122 | #define BZ_G_SIZE 50
123 | #define BZ_N_ITERS 4
124 |
125 | #define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE))
126 |
127 |
128 |
129 | /*-- Stuff for randomising repetitive blocks. --*/
130 |
131 | extern Int32 BZ2_rNums[512];
132 |
133 | #define BZ_RAND_DECLS \
134 | Int32 rNToGo; \
135 | Int32 rTPos \
136 |
137 | #define BZ_RAND_INIT_MASK \
138 | s->rNToGo = 0; \
139 | s->rTPos = 0 \
140 |
141 | #define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0)
142 |
143 | #define BZ_RAND_UPD_MASK \
144 | if (s->rNToGo == 0) { \
145 | s->rNToGo = BZ2_rNums[s->rTPos]; \
146 | s->rTPos++; \
147 | if (s->rTPos == 512) s->rTPos = 0; \
148 | } \
149 | s->rNToGo--;
150 |
151 |
152 |
153 | /*-- Stuff for doing CRCs. --*/
154 |
155 | extern UInt32 BZ2_crc32Table[256];
156 |
157 | #define BZ_INITIALISE_CRC(crcVar) \
158 | { \
159 | crcVar = 0xffffffffL; \
160 | }
161 |
162 | #define BZ_FINALISE_CRC(crcVar) \
163 | { \
164 | crcVar = ~(crcVar); \
165 | }
166 |
167 | #define BZ_UPDATE_CRC(crcVar,cha) \
168 | { \
169 | crcVar = (crcVar << 8) ^ \
170 | BZ2_crc32Table[(crcVar >> 24) ^ \
171 | ((UChar)cha)]; \
172 | }
173 |
174 |
175 |
176 | /*-- States and modes for compression. --*/
177 |
178 | #define BZ_M_IDLE 1
179 | #define BZ_M_RUNNING 2
180 | #define BZ_M_FLUSHING 3
181 | #define BZ_M_FINISHING 4
182 |
183 | #define BZ_S_OUTPUT 1
184 | #define BZ_S_INPUT 2
185 |
186 | #define BZ_N_RADIX 2
187 | #define BZ_N_QSORT 12
188 | #define BZ_N_SHELL 18
189 | #define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2)
190 |
191 |
192 |
193 |
194 | /*-- Structure holding all the compression-side stuff. --*/
195 |
196 | typedef
197 | struct {
198 | /* pointer back to the struct bz_stream */
199 | bz_stream* strm;
200 |
201 | /* mode this stream is in, and whether inputting */
202 | /* or outputting data */
203 | Int32 mode;
204 | Int32 state;
205 |
206 | /* remembers avail_in when flush/finish requested */
207 | UInt32 avail_in_expect;
208 |
209 | /* for doing the block sorting */
210 | UInt32* arr1;
211 | UInt32* arr2;
212 | UInt32* ftab;
213 | Int32 origPtr;
214 |
215 | /* aliases for arr1 and arr2 */
216 | UInt32* ptr;
217 | UChar* block;
218 | UInt16* mtfv;
219 | UChar* zbits;
220 |
221 | /* for deciding when to use the fallback sorting algorithm */
222 | Int32 workFactor;
223 |
224 | /* run-length-encoding of the input */
225 | UInt32 state_in_ch;
226 | Int32 state_in_len;
227 | BZ_RAND_DECLS;
228 |
229 | /* input and output limits and current posns */
230 | Int32 nblock;
231 | Int32 nblockMAX;
232 | Int32 numZ;
233 | Int32 state_out_pos;
234 |
235 | /* map of bytes used in block */
236 | Int32 nInUse;
237 | Bool inUse[256];
238 | UChar unseqToSeq[256];
239 |
240 | /* the buffer for bit stream creation */
241 | UInt32 bsBuff;
242 | Int32 bsLive;
243 |
244 | /* block and combined CRCs */
245 | UInt32 blockCRC;
246 | UInt32 combinedCRC;
247 |
248 | /* misc administratium */
249 | Int32 verbosity;
250 | Int32 blockNo;
251 | Int32 blockSize100k;
252 |
253 | /* stuff for coding the MTF values */
254 | Int32 nMTF;
255 | Int32 mtfFreq [BZ_MAX_ALPHA_SIZE];
256 | UChar selector [BZ_MAX_SELECTORS];
257 | UChar selectorMtf[BZ_MAX_SELECTORS];
258 |
259 | UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
260 | Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
261 | Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
262 | /* second dimension: only 3 needed; 4 makes index calculations faster */
263 | UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4];
264 |
265 | }
266 | EState;
267 |
268 |
269 |
270 | /*-- externs for compression. --*/
271 |
272 | extern void
273 | BZ2_blockSort ( EState* );
274 |
275 | extern void
276 | BZ2_compressBlock ( EState*, Bool );
277 |
278 | extern void
279 | BZ2_bsInitWrite ( EState* );
280 |
281 | extern void
282 | BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 );
283 |
284 | extern void
285 | BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 );
286 |
287 |
288 |
289 | /*-- states for decompression. --*/
290 |
291 | #define BZ_X_IDLE 1
292 | #define BZ_X_OUTPUT 2
293 |
294 | #define BZ_X_MAGIC_1 10
295 | #define BZ_X_MAGIC_2 11
296 | #define BZ_X_MAGIC_3 12
297 | #define BZ_X_MAGIC_4 13
298 | #define BZ_X_BLKHDR_1 14
299 | #define BZ_X_BLKHDR_2 15
300 | #define BZ_X_BLKHDR_3 16
301 | #define BZ_X_BLKHDR_4 17
302 | #define BZ_X_BLKHDR_5 18
303 | #define BZ_X_BLKHDR_6 19
304 | #define BZ_X_BCRC_1 20
305 | #define BZ_X_BCRC_2 21
306 | #define BZ_X_BCRC_3 22
307 | #define BZ_X_BCRC_4 23
308 | #define BZ_X_RANDBIT 24
309 | #define BZ_X_ORIGPTR_1 25
310 | #define BZ_X_ORIGPTR_2 26
311 | #define BZ_X_ORIGPTR_3 27
312 | #define BZ_X_MAPPING_1 28
313 | #define BZ_X_MAPPING_2 29
314 | #define BZ_X_SELECTOR_1 30
315 | #define BZ_X_SELECTOR_2 31
316 | #define BZ_X_SELECTOR_3 32
317 | #define BZ_X_CODING_1 33
318 | #define BZ_X_CODING_2 34
319 | #define BZ_X_CODING_3 35
320 | #define BZ_X_MTF_1 36
321 | #define BZ_X_MTF_2 37
322 | #define BZ_X_MTF_3 38
323 | #define BZ_X_MTF_4 39
324 | #define BZ_X_MTF_5 40
325 | #define BZ_X_MTF_6 41
326 | #define BZ_X_ENDHDR_2 42
327 | #define BZ_X_ENDHDR_3 43
328 | #define BZ_X_ENDHDR_4 44
329 | #define BZ_X_ENDHDR_5 45
330 | #define BZ_X_ENDHDR_6 46
331 | #define BZ_X_CCRC_1 47
332 | #define BZ_X_CCRC_2 48
333 | #define BZ_X_CCRC_3 49
334 | #define BZ_X_CCRC_4 50
335 |
336 |
337 |
338 | /*-- Constants for the fast MTF decoder. --*/
339 |
340 | #define MTFA_SIZE 4096
341 | #define MTFL_SIZE 16
342 |
343 |
344 |
345 | /*-- Structure holding all the decompression-side stuff. --*/
346 |
347 | typedef
348 | struct {
349 | /* pointer back to the struct bz_stream */
350 | bz_stream* strm;
351 |
352 | /* state indicator for this stream */
353 | Int32 state;
354 |
355 | /* for doing the final run-length decoding */
356 | UChar state_out_ch;
357 | Int32 state_out_len;
358 | Bool blockRandomised;
359 | BZ_RAND_DECLS;
360 |
361 | /* the buffer for bit stream reading */
362 | UInt32 bsBuff;
363 | Int32 bsLive;
364 |
365 | /* misc administratium */
366 | Int32 blockSize100k;
367 | Bool smallDecompress;
368 | Int32 currBlockNo;
369 | Int32 verbosity;
370 |
371 | /* for undoing the Burrows-Wheeler transform */
372 | Int32 origPtr;
373 | UInt32 tPos;
374 | Int32 k0;
375 | Int32 unzftab[256];
376 | Int32 nblock_used;
377 | Int32 cftab[257];
378 | Int32 cftabCopy[257];
379 |
380 | /* for undoing the Burrows-Wheeler transform (FAST) */
381 | UInt32 *tt;
382 |
383 | /* for undoing the Burrows-Wheeler transform (SMALL) */
384 | UInt16 *ll16;
385 | UChar *ll4;
386 |
387 | /* stored and calculated CRCs */
388 | UInt32 storedBlockCRC;
389 | UInt32 storedCombinedCRC;
390 | UInt32 calculatedBlockCRC;
391 | UInt32 calculatedCombinedCRC;
392 |
393 | /* map of bytes used in block */
394 | Int32 nInUse;
395 | Bool inUse[256];
396 | Bool inUse16[16];
397 | UChar seqToUnseq[256];
398 |
399 | /* for decoding the MTF values */
400 | UChar mtfa [MTFA_SIZE];
401 | Int32 mtfbase[256 / MTFL_SIZE];
402 | UChar selector [BZ_MAX_SELECTORS];
403 | UChar selectorMtf[BZ_MAX_SELECTORS];
404 | UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
405 |
406 | Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
407 | Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
408 | Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
409 | Int32 minLens[BZ_N_GROUPS];
410 |
411 | /* save area for scalars in the main decompress code */
412 | Int32 save_i;
413 | Int32 save_j;
414 | Int32 save_t;
415 | Int32 save_alphaSize;
416 | Int32 save_nGroups;
417 | Int32 save_nSelectors;
418 | Int32 save_EOB;
419 | Int32 save_groupNo;
420 | Int32 save_groupPos;
421 | Int32 save_nextSym;
422 | Int32 save_nblockMAX;
423 | Int32 save_nblock;
424 | Int32 save_es;
425 | Int32 save_N;
426 | Int32 save_curr;
427 | Int32 save_zt;
428 | Int32 save_zn;
429 | Int32 save_zvec;
430 | Int32 save_zj;
431 | Int32 save_gSel;
432 | Int32 save_gMinlen;
433 | Int32* save_gLimit;
434 | Int32* save_gBase;
435 | Int32* save_gPerm;
436 |
437 | }
438 | DState;
439 |
440 |
441 |
442 | /*-- Macros for decompression. --*/
443 |
444 | #define BZ_GET_FAST(cccc) \
445 | /* c_tPos is unsigned, hence test < 0 is pointless. */ \
446 | if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
447 | s->tPos = s->tt[s->tPos]; \
448 | cccc = (UChar)(s->tPos & 0xff); \
449 | s->tPos >>= 8;
450 |
451 | #define BZ_GET_FAST_C(cccc) \
452 | /* c_tPos is unsigned, hence test < 0 is pointless. */ \
453 | if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \
454 | c_tPos = c_tt[c_tPos]; \
455 | cccc = (UChar)(c_tPos & 0xff); \
456 | c_tPos >>= 8;
457 |
458 | #define SET_LL4(i,n) \
459 | { if (((i) & 0x1) == 0) \
460 | s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \
461 | s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \
462 | }
463 |
464 | #define GET_LL4(i) \
465 | ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF)
466 |
467 | #define SET_LL(i,n) \
468 | { s->ll16[i] = (UInt16)(n & 0x0000ffff); \
469 | SET_LL4(i, n >> 16); \
470 | }
471 |
472 | #define GET_LL(i) \
473 | (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16))
474 |
475 | #define BZ_GET_SMALL(cccc) \
476 | /* c_tPos is unsigned, hence test < 0 is pointless. */ \
477 | if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \
478 | cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \
479 | s->tPos = GET_LL(s->tPos);
480 |
481 |
482 | /*-- externs for decompression. --*/
483 |
484 | extern Int32
485 | BZ2_indexIntoF ( Int32, Int32* );
486 |
487 | extern Int32
488 | BZ2_decompress ( DState* );
489 |
490 | extern void
491 | BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*,
492 | Int32, Int32, Int32 );
493 |
494 |
495 | #endif
496 |
497 |
498 | /*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/
499 |
500 | #ifdef BZ_NO_STDIO
501 | #ifndef NULL
502 | #define NULL 0
503 | #endif
504 | #endif
505 |
506 |
507 | /*-------------------------------------------------------------*/
508 | /*--- end bzlib_private.h ---*/
509 | /*-------------------------------------------------------------*/
510 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/jni/bzip2/compress.c:
--------------------------------------------------------------------------------
1 |
2 | /*-------------------------------------------------------------*/
3 | /*--- Compression machinery (not incl block sorting) ---*/
4 | /*--- compress.c ---*/
5 | /*-------------------------------------------------------------*/
6 |
7 | /* ------------------------------------------------------------------
8 | This file is part of bzip2/libbzip2, a program and library for
9 | lossless, block-sorting data compression.
10 |
11 | bzip2/libbzip2 version 1.0.6 of 6 September 2010
12 | Copyright (C) 1996-2010 Julian Seward
13 |
14 | Please read the WARNING, DISCLAIMER and PATENTS sections in the
15 | README file.
16 |
17 | This program is released under the terms of the license contained
18 | in the file LICENSE.
19 | ------------------------------------------------------------------ */
20 |
21 |
22 | /* CHANGES
23 | 0.9.0 -- original version.
24 | 0.9.0a/b -- no changes in this file.
25 | 0.9.0c -- changed setting of nGroups in sendMTFValues()
26 | so as to do a bit better on small files
27 | */
28 |
29 | #include "bzlib_private.h"
30 |
31 |
32 | /*---------------------------------------------------*/
33 | /*--- Bit stream I/O ---*/
34 | /*---------------------------------------------------*/
35 |
36 | /*---------------------------------------------------*/
37 | void BZ2_bsInitWrite ( EState* s )
38 | {
39 | s->bsLive = 0;
40 | s->bsBuff = 0;
41 | }
42 |
43 |
44 | /*---------------------------------------------------*/
45 | static
46 | void bsFinishWrite ( EState* s )
47 | {
48 | while (s->bsLive > 0) {
49 | s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24);
50 | s->numZ++;
51 | s->bsBuff <<= 8;
52 | s->bsLive -= 8;
53 | }
54 | }
55 |
56 |
57 | /*---------------------------------------------------*/
58 | #define bsNEEDW(nz) \
59 | { \
60 | while (s->bsLive >= 8) { \
61 | s->zbits[s->numZ] \
62 | = (UChar)(s->bsBuff >> 24); \
63 | s->numZ++; \
64 | s->bsBuff <<= 8; \
65 | s->bsLive -= 8; \
66 | } \
67 | }
68 |
69 |
70 | /*---------------------------------------------------*/
71 | static
72 | __inline__
73 | void bsW ( EState* s, Int32 n, UInt32 v )
74 | {
75 | bsNEEDW ( n );
76 | s->bsBuff |= (v << (32 - s->bsLive - n));
77 | s->bsLive += n;
78 | }
79 |
80 |
81 | /*---------------------------------------------------*/
82 | static
83 | void bsPutUInt32 ( EState* s, UInt32 u )
84 | {
85 | bsW ( s, 8, (u >> 24) & 0xffL );
86 | bsW ( s, 8, (u >> 16) & 0xffL );
87 | bsW ( s, 8, (u >> 8) & 0xffL );
88 | bsW ( s, 8, u & 0xffL );
89 | }
90 |
91 |
92 | /*---------------------------------------------------*/
93 | static
94 | void bsPutUChar ( EState* s, UChar c )
95 | {
96 | bsW( s, 8, (UInt32)c );
97 | }
98 |
99 |
100 | /*---------------------------------------------------*/
101 | /*--- The back end proper ---*/
102 | /*---------------------------------------------------*/
103 |
104 | /*---------------------------------------------------*/
105 | static
106 | void makeMaps_e ( EState* s )
107 | {
108 | Int32 i;
109 | s->nInUse = 0;
110 | for (i = 0; i < 256; i++)
111 | if (s->inUse[i]) {
112 | s->unseqToSeq[i] = s->nInUse;
113 | s->nInUse++;
114 | }
115 | }
116 |
117 |
118 | /*---------------------------------------------------*/
119 | static
120 | void generateMTFValues ( EState* s )
121 | {
122 | UChar yy[256];
123 | Int32 i, j;
124 | Int32 zPend;
125 | Int32 wr;
126 | Int32 EOB;
127 |
128 | /*
129 | After sorting (eg, here),
130 | s->arr1 [ 0 .. s->nblock-1 ] holds sorted order,
131 | and
132 | ((UChar*)s->arr2) [ 0 .. s->nblock-1 ]
133 | holds the original block data.
134 |
135 | The first thing to do is generate the MTF values,
136 | and put them in
137 | ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ].
138 | Because there are strictly fewer or equal MTF values
139 | than block values, ptr values in this area are overwritten
140 | with MTF values only when they are no longer needed.
141 |
142 | The final compressed bitstream is generated into the
143 | area starting at
144 | (UChar*) (&((UChar*)s->arr2)[s->nblock])
145 |
146 | These storage aliases are set up in bzCompressInit(),
147 | except for the last one, which is arranged in
148 | compressBlock().
149 | */
150 | UInt32* ptr = s->ptr;
151 | UChar* block = s->block;
152 | UInt16* mtfv = s->mtfv;
153 |
154 | makeMaps_e ( s );
155 | EOB = s->nInUse+1;
156 |
157 | for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0;
158 |
159 | wr = 0;
160 | zPend = 0;
161 | for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i;
162 |
163 | for (i = 0; i < s->nblock; i++) {
164 | UChar ll_i;
165 | AssertD ( wr <= i, "generateMTFValues(1)" );
166 | j = ptr[i]-1; if (j < 0) j += s->nblock;
167 | ll_i = s->unseqToSeq[block[j]];
168 | AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" );
169 |
170 | if (yy[0] == ll_i) {
171 | zPend++;
172 | } else {
173 |
174 | if (zPend > 0) {
175 | zPend--;
176 | while (True) {
177 | if (zPend & 1) {
178 | mtfv[wr] = BZ_RUNB; wr++;
179 | s->mtfFreq[BZ_RUNB]++;
180 | } else {
181 | mtfv[wr] = BZ_RUNA; wr++;
182 | s->mtfFreq[BZ_RUNA]++;
183 | }
184 | if (zPend < 2) break;
185 | zPend = (zPend - 2) / 2;
186 | };
187 | zPend = 0;
188 | }
189 | {
190 | register UChar rtmp;
191 | register UChar* ryy_j;
192 | register UChar rll_i;
193 | rtmp = yy[1];
194 | yy[1] = yy[0];
195 | ryy_j = &(yy[1]);
196 | rll_i = ll_i;
197 | while ( rll_i != rtmp ) {
198 | register UChar rtmp2;
199 | ryy_j++;
200 | rtmp2 = rtmp;
201 | rtmp = *ryy_j;
202 | *ryy_j = rtmp2;
203 | };
204 | yy[0] = rtmp;
205 | j = ryy_j - &(yy[0]);
206 | mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++;
207 | }
208 |
209 | }
210 | }
211 |
212 | if (zPend > 0) {
213 | zPend--;
214 | while (True) {
215 | if (zPend & 1) {
216 | mtfv[wr] = BZ_RUNB; wr++;
217 | s->mtfFreq[BZ_RUNB]++;
218 | } else {
219 | mtfv[wr] = BZ_RUNA; wr++;
220 | s->mtfFreq[BZ_RUNA]++;
221 | }
222 | if (zPend < 2) break;
223 | zPend = (zPend - 2) / 2;
224 | };
225 | zPend = 0;
226 | }
227 |
228 | mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++;
229 |
230 | s->nMTF = wr;
231 | }
232 |
233 |
234 | /*---------------------------------------------------*/
235 | #define BZ_LESSER_ICOST 0
236 | #define BZ_GREATER_ICOST 15
237 |
238 | static
239 | void sendMTFValues ( EState* s )
240 | {
241 | Int32 v, t, i, j, gs, ge, totc, bt, bc, iter;
242 | Int32 nSelectors, alphaSize, minLen, maxLen, selCtr;
243 | Int32 nGroups, nBytes;
244 |
245 | /*--
246 | UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
247 | is a global since the decoder also needs it.
248 |
249 | Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
250 | Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE];
251 | are also globals only used in this proc.
252 | Made global to keep stack frame size small.
253 | --*/
254 |
255 |
256 | UInt16 cost[BZ_N_GROUPS];
257 | Int32 fave[BZ_N_GROUPS];
258 |
259 | UInt16* mtfv = s->mtfv;
260 |
261 | if (s->verbosity >= 3)
262 | VPrintf3( " %d in block, %d after MTF & 1-2 coding, "
263 | "%d+2 syms in use\n",
264 | s->nblock, s->nMTF, s->nInUse );
265 |
266 | alphaSize = s->nInUse+2;
267 | for (t = 0; t < BZ_N_GROUPS; t++)
268 | for (v = 0; v < alphaSize; v++)
269 | s->len[t][v] = BZ_GREATER_ICOST;
270 |
271 | /*--- Decide how many coding tables to use ---*/
272 | AssertH ( s->nMTF > 0, 3001 );
273 | if (s->nMTF < 200) nGroups = 2; else
274 | if (s->nMTF < 600) nGroups = 3; else
275 | if (s->nMTF < 1200) nGroups = 4; else
276 | if (s->nMTF < 2400) nGroups = 5; else
277 | nGroups = 6;
278 |
279 | /*--- Generate an initial set of coding tables ---*/
280 | {
281 | Int32 nPart, remF, tFreq, aFreq;
282 |
283 | nPart = nGroups;
284 | remF = s->nMTF;
285 | gs = 0;
286 | while (nPart > 0) {
287 | tFreq = remF / nPart;
288 | ge = gs-1;
289 | aFreq = 0;
290 | while (aFreq < tFreq && ge < alphaSize-1) {
291 | ge++;
292 | aFreq += s->mtfFreq[ge];
293 | }
294 |
295 | if (ge > gs
296 | && nPart != nGroups && nPart != 1
297 | && ((nGroups-nPart) % 2 == 1)) {
298 | aFreq -= s->mtfFreq[ge];
299 | ge--;
300 | }
301 |
302 | if (s->verbosity >= 3)
303 | VPrintf5( " initial group %d, [%d .. %d], "
304 | "has %d syms (%4.1f%%)\n",
305 | nPart, gs, ge, aFreq,
306 | (100.0 * (float)aFreq) / (float)(s->nMTF) );
307 |
308 | for (v = 0; v < alphaSize; v++)
309 | if (v >= gs && v <= ge)
310 | s->len[nPart-1][v] = BZ_LESSER_ICOST; else
311 | s->len[nPart-1][v] = BZ_GREATER_ICOST;
312 |
313 | nPart--;
314 | gs = ge+1;
315 | remF -= aFreq;
316 | }
317 | }
318 |
319 | /*---
320 | Iterate up to BZ_N_ITERS times to improve the tables.
321 | ---*/
322 | for (iter = 0; iter < BZ_N_ITERS; iter++) {
323 |
324 | for (t = 0; t < nGroups; t++) fave[t] = 0;
325 |
326 | for (t = 0; t < nGroups; t++)
327 | for (v = 0; v < alphaSize; v++)
328 | s->rfreq[t][v] = 0;
329 |
330 | /*---
331 | Set up an auxiliary length table which is used to fast-track
332 | the common case (nGroups == 6).
333 | ---*/
334 | if (nGroups == 6) {
335 | for (v = 0; v < alphaSize; v++) {
336 | s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v];
337 | s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v];
338 | s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v];
339 | }
340 | }
341 |
342 | nSelectors = 0;
343 | totc = 0;
344 | gs = 0;
345 | while (True) {
346 |
347 | /*--- Set group start & end marks. --*/
348 | if (gs >= s->nMTF) break;
349 | ge = gs + BZ_G_SIZE - 1;
350 | if (ge >= s->nMTF) ge = s->nMTF-1;
351 |
352 | /*--
353 | Calculate the cost of this group as coded
354 | by each of the coding tables.
355 | --*/
356 | for (t = 0; t < nGroups; t++) cost[t] = 0;
357 |
358 | if (nGroups == 6 && 50 == ge-gs+1) {
359 | /*--- fast track the common case ---*/
360 | register UInt32 cost01, cost23, cost45;
361 | register UInt16 icv;
362 | cost01 = cost23 = cost45 = 0;
363 |
364 | # define BZ_ITER(nn) \
365 | icv = mtfv[gs+(nn)]; \
366 | cost01 += s->len_pack[icv][0]; \
367 | cost23 += s->len_pack[icv][1]; \
368 | cost45 += s->len_pack[icv][2]; \
369 |
370 | BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4);
371 | BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9);
372 | BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14);
373 | BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19);
374 | BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24);
375 | BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29);
376 | BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34);
377 | BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39);
378 | BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44);
379 | BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49);
380 |
381 | # undef BZ_ITER
382 |
383 | cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16;
384 | cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16;
385 | cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16;
386 |
387 | } else {
388 | /*--- slow version which correctly handles all situations ---*/
389 | for (i = gs; i <= ge; i++) {
390 | UInt16 icv = mtfv[i];
391 | for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv];
392 | }
393 | }
394 |
395 | /*--
396 | Find the coding table which is best for this group,
397 | and record its identity in the selector table.
398 | --*/
399 | bc = 999999999; bt = -1;
400 | for (t = 0; t < nGroups; t++)
401 | if (cost[t] < bc) { bc = cost[t]; bt = t; };
402 | totc += bc;
403 | fave[bt]++;
404 | s->selector[nSelectors] = bt;
405 | nSelectors++;
406 |
407 | /*--
408 | Increment the symbol frequencies for the selected table.
409 | --*/
410 | if (nGroups == 6 && 50 == ge-gs+1) {
411 | /*--- fast track the common case ---*/
412 |
413 | # define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++
414 |
415 | BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4);
416 | BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9);
417 | BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14);
418 | BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19);
419 | BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24);
420 | BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29);
421 | BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34);
422 | BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39);
423 | BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44);
424 | BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49);
425 |
426 | # undef BZ_ITUR
427 |
428 | } else {
429 | /*--- slow version which correctly handles all situations ---*/
430 | for (i = gs; i <= ge; i++)
431 | s->rfreq[bt][ mtfv[i] ]++;
432 | }
433 |
434 | gs = ge+1;
435 | }
436 | if (s->verbosity >= 3) {
437 | VPrintf2 ( " pass %d: size is %d, grp uses are ",
438 | iter+1, totc/8 );
439 | for (t = 0; t < nGroups; t++)
440 | VPrintf1 ( "%d ", fave[t] );
441 | VPrintf0 ( "\n" );
442 | }
443 |
444 | /*--
445 | Recompute the tables based on the accumulated frequencies.
446 | --*/
447 | /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See
448 | comment in huffman.c for details. */
449 | for (t = 0; t < nGroups; t++)
450 | BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]),
451 | alphaSize, 17 /*20*/ );
452 | }
453 |
454 |
455 | AssertH( nGroups < 8, 3002 );
456 | AssertH( nSelectors < 32768 &&
457 | nSelectors <= (2 + (900000 / BZ_G_SIZE)),
458 | 3003 );
459 |
460 |
461 | /*--- Compute MTF values for the selectors. ---*/
462 | {
463 | UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp;
464 | for (i = 0; i < nGroups; i++) pos[i] = i;
465 | for (i = 0; i < nSelectors; i++) {
466 | ll_i = s->selector[i];
467 | j = 0;
468 | tmp = pos[j];
469 | while ( ll_i != tmp ) {
470 | j++;
471 | tmp2 = tmp;
472 | tmp = pos[j];
473 | pos[j] = tmp2;
474 | };
475 | pos[0] = tmp;
476 | s->selectorMtf[i] = j;
477 | }
478 | };
479 |
480 | /*--- Assign actual codes for the tables. --*/
481 | for (t = 0; t < nGroups; t++) {
482 | minLen = 32;
483 | maxLen = 0;
484 | for (i = 0; i < alphaSize; i++) {
485 | if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
486 | if (s->len[t][i] < minLen) minLen = s->len[t][i];
487 | }
488 | AssertH ( !(maxLen > 17 /*20*/ ), 3004 );
489 | AssertH ( !(minLen < 1), 3005 );
490 | BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]),
491 | minLen, maxLen, alphaSize );
492 | }
493 |
494 | /*--- Transmit the mapping table. ---*/
495 | {
496 | Bool inUse16[16];
497 | for (i = 0; i < 16; i++) {
498 | inUse16[i] = False;
499 | for (j = 0; j < 16; j++)
500 | if (s->inUse[i * 16 + j]) inUse16[i] = True;
501 | }
502 |
503 | nBytes = s->numZ;
504 | for (i = 0; i < 16; i++)
505 | if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0);
506 |
507 | for (i = 0; i < 16; i++)
508 | if (inUse16[i])
509 | for (j = 0; j < 16; j++) {
510 | if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0);
511 | }
512 |
513 | if (s->verbosity >= 3)
514 | VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes );
515 | }
516 |
517 | /*--- Now the selectors. ---*/
518 | nBytes = s->numZ;
519 | bsW ( s, 3, nGroups );
520 | bsW ( s, 15, nSelectors );
521 | for (i = 0; i < nSelectors; i++) {
522 | for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1);
523 | bsW(s,1,0);
524 | }
525 | if (s->verbosity >= 3)
526 | VPrintf1( "selectors %d, ", s->numZ-nBytes );
527 |
528 | /*--- Now the coding tables. ---*/
529 | nBytes = s->numZ;
530 |
531 | for (t = 0; t < nGroups; t++) {
532 | Int32 curr = s->len[t][0];
533 | bsW ( s, 5, curr );
534 | for (i = 0; i < alphaSize; i++) {
535 | while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ };
536 | while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ };
537 | bsW ( s, 1, 0 );
538 | }
539 | }
540 |
541 | if (s->verbosity >= 3)
542 | VPrintf1 ( "code lengths %d, ", s->numZ-nBytes );
543 |
544 | /*--- And finally, the block data proper ---*/
545 | nBytes = s->numZ;
546 | selCtr = 0;
547 | gs = 0;
548 | while (True) {
549 | if (gs >= s->nMTF) break;
550 | ge = gs + BZ_G_SIZE - 1;
551 | if (ge >= s->nMTF) ge = s->nMTF-1;
552 | AssertH ( s->selector[selCtr] < nGroups, 3006 );
553 |
554 | if (nGroups == 6 && 50 == ge-gs+1) {
555 | /*--- fast track the common case ---*/
556 | UInt16 mtfv_i;
557 | UChar* s_len_sel_selCtr
558 | = &(s->len[s->selector[selCtr]][0]);
559 | Int32* s_code_sel_selCtr
560 | = &(s->code[s->selector[selCtr]][0]);
561 |
562 | # define BZ_ITAH(nn) \
563 | mtfv_i = mtfv[gs+(nn)]; \
564 | bsW ( s, \
565 | s_len_sel_selCtr[mtfv_i], \
566 | s_code_sel_selCtr[mtfv_i] )
567 |
568 | BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4);
569 | BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9);
570 | BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14);
571 | BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19);
572 | BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24);
573 | BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29);
574 | BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34);
575 | BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39);
576 | BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44);
577 | BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49);
578 |
579 | # undef BZ_ITAH
580 |
581 | } else {
582 | /*--- slow version which correctly handles all situations ---*/
583 | for (i = gs; i <= ge; i++) {
584 | bsW ( s,
585 | s->len [s->selector[selCtr]] [mtfv[i]],
586 | s->code [s->selector[selCtr]] [mtfv[i]] );
587 | }
588 | }
589 |
590 |
591 | gs = ge+1;
592 | selCtr++;
593 | }
594 | AssertH( selCtr == nSelectors, 3007 );
595 |
596 | if (s->verbosity >= 3)
597 | VPrintf1( "codes %d\n", s->numZ-nBytes );
598 | }
599 |
600 |
601 | /*---------------------------------------------------*/
602 | void BZ2_compressBlock ( EState* s, Bool is_last_block )
603 | {
604 | if (s->nblock > 0) {
605 |
606 | BZ_FINALISE_CRC ( s->blockCRC );
607 | s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31);
608 | s->combinedCRC ^= s->blockCRC;
609 | if (s->blockNo > 1) s->numZ = 0;
610 |
611 | if (s->verbosity >= 2)
612 | VPrintf4( " block %d: crc = 0x%08x, "
613 | "combined CRC = 0x%08x, size = %d\n",
614 | s->blockNo, s->blockCRC, s->combinedCRC, s->nblock );
615 |
616 | BZ2_blockSort ( s );
617 | }
618 |
619 | s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]);
620 |
621 | /*-- If this is the first block, create the stream header. --*/
622 | if (s->blockNo == 1) {
623 | BZ2_bsInitWrite ( s );
624 | bsPutUChar ( s, BZ_HDR_B );
625 | bsPutUChar ( s, BZ_HDR_Z );
626 | bsPutUChar ( s, BZ_HDR_h );
627 | bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) );
628 | }
629 |
630 | if (s->nblock > 0) {
631 |
632 | bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 );
633 | bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 );
634 | bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 );
635 |
636 | /*-- Now the block's CRC, so it is in a known place. --*/
637 | bsPutUInt32 ( s, s->blockCRC );
638 |
639 | /*--
640 | Now a single bit indicating (non-)randomisation.
641 | As of version 0.9.5, we use a better sorting algorithm
642 | which makes randomisation unnecessary. So always set
643 | the randomised bit to 'no'. Of course, the decoder
644 | still needs to be able to handle randomised blocks
645 | so as to maintain backwards compatibility with
646 | older versions of bzip2.
647 | --*/
648 | bsW(s,1,0);
649 |
650 | bsW ( s, 24, s->origPtr );
651 | generateMTFValues ( s );
652 | sendMTFValues ( s );
653 | }
654 |
655 |
656 | /*-- If this is the last block, add the stream trailer. --*/
657 | if (is_last_block) {
658 |
659 | bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 );
660 | bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 );
661 | bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 );
662 | bsPutUInt32 ( s, s->combinedCRC );
663 | if (s->verbosity >= 2)
664 | VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC );
665 | bsFinishWrite ( s );
666 | }
667 | }
668 |
669 |
670 | /*-------------------------------------------------------------*/
671 | /*--- end compress.c ---*/
672 | /*-------------------------------------------------------------*/
673 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/jni/bzip2/crctable.c:
--------------------------------------------------------------------------------
1 |
2 | /*-------------------------------------------------------------*/
3 | /*--- Table for doing CRCs ---*/
4 | /*--- crctable.c ---*/
5 | /*-------------------------------------------------------------*/
6 |
7 | /* ------------------------------------------------------------------
8 | This file is part of bzip2/libbzip2, a program and library for
9 | lossless, block-sorting data compression.
10 |
11 | bzip2/libbzip2 version 1.0.6 of 6 September 2010
12 | Copyright (C) 1996-2010 Julian Seward
13 |
14 | Please read the WARNING, DISCLAIMER and PATENTS sections in the
15 | README file.
16 |
17 | This program is released under the terms of the license contained
18 | in the file LICENSE.
19 | ------------------------------------------------------------------ */
20 |
21 |
22 | #include "bzlib_private.h"
23 |
24 | /*--
25 | I think this is an implementation of the AUTODIN-II,
26 | Ethernet & FDDI 32-bit CRC standard. Vaguely derived
27 | from code by Rob Warnock, in Section 51 of the
28 | comp.compression FAQ.
29 | --*/
30 |
31 | UInt32 BZ2_crc32Table[256] = {
32 |
33 | /*-- Ugly, innit? --*/
34 |
35 | 0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L,
36 | 0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L,
37 | 0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L,
38 | 0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL,
39 | 0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L,
40 | 0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L,
41 | 0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L,
42 | 0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL,
43 | 0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L,
44 | 0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L,
45 | 0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L,
46 | 0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL,
47 | 0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L,
48 | 0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L,
49 | 0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L,
50 | 0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL,
51 | 0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL,
52 | 0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L,
53 | 0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L,
54 | 0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL,
55 | 0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL,
56 | 0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L,
57 | 0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L,
58 | 0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL,
59 | 0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL,
60 | 0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L,
61 | 0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L,
62 | 0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL,
63 | 0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL,
64 | 0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L,
65 | 0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L,
66 | 0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL,
67 | 0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L,
68 | 0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL,
69 | 0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL,
70 | 0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L,
71 | 0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L,
72 | 0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL,
73 | 0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL,
74 | 0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L,
75 | 0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L,
76 | 0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL,
77 | 0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL,
78 | 0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L,
79 | 0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L,
80 | 0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL,
81 | 0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL,
82 | 0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L,
83 | 0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L,
84 | 0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL,
85 | 0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L,
86 | 0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L,
87 | 0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L,
88 | 0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL,
89 | 0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L,
90 | 0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L,
91 | 0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L,
92 | 0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL,
93 | 0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L,
94 | 0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L,
95 | 0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L,
96 | 0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL,
97 | 0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L,
98 | 0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L
99 | };
100 |
101 |
102 | /*-------------------------------------------------------------*/
103 | /*--- end crctable.c ---*/
104 | /*-------------------------------------------------------------*/
105 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/jni/bzip2/decompress.c:
--------------------------------------------------------------------------------
1 |
2 | /*-------------------------------------------------------------*/
3 | /*--- Decompression machinery ---*/
4 | /*--- decompress.c ---*/
5 | /*-------------------------------------------------------------*/
6 |
7 | /* ------------------------------------------------------------------
8 | This file is part of bzip2/libbzip2, a program and library for
9 | lossless, block-sorting data compression.
10 |
11 | bzip2/libbzip2 version 1.0.6 of 6 September 2010
12 | Copyright (C) 1996-2010 Julian Seward
13 |
14 | Please read the WARNING, DISCLAIMER and PATENTS sections in the
15 | README file.
16 |
17 | This program is released under the terms of the license contained
18 | in the file LICENSE.
19 | ------------------------------------------------------------------ */
20 |
21 |
22 | #include "bzlib_private.h"
23 |
24 |
25 | /*---------------------------------------------------*/
26 | static
27 | void makeMaps_d ( DState* s )
28 | {
29 | Int32 i;
30 | s->nInUse = 0;
31 | for (i = 0; i < 256; i++)
32 | if (s->inUse[i]) {
33 | s->seqToUnseq[s->nInUse] = i;
34 | s->nInUse++;
35 | }
36 | }
37 |
38 |
39 | /*---------------------------------------------------*/
40 | #define RETURN(rrr) \
41 | { retVal = rrr; goto save_state_and_return; };
42 |
43 | #define GET_BITS(lll,vvv,nnn) \
44 | case lll: s->state = lll; \
45 | while (True) { \
46 | if (s->bsLive >= nnn) { \
47 | UInt32 v; \
48 | v = (s->bsBuff >> \
49 | (s->bsLive-nnn)) & ((1 << nnn)-1); \
50 | s->bsLive -= nnn; \
51 | vvv = v; \
52 | break; \
53 | } \
54 | if (s->strm->avail_in == 0) RETURN(BZ_OK); \
55 | s->bsBuff \
56 | = (s->bsBuff << 8) | \
57 | ((UInt32) \
58 | (*((UChar*)(s->strm->next_in)))); \
59 | s->bsLive += 8; \
60 | s->strm->next_in++; \
61 | s->strm->avail_in--; \
62 | s->strm->total_in_lo32++; \
63 | if (s->strm->total_in_lo32 == 0) \
64 | s->strm->total_in_hi32++; \
65 | }
66 |
67 | #define GET_UCHAR(lll,uuu) \
68 | GET_BITS(lll,uuu,8)
69 |
70 | #define GET_BIT(lll,uuu) \
71 | GET_BITS(lll,uuu,1)
72 |
73 | /*---------------------------------------------------*/
74 | #define GET_MTF_VAL(label1,label2,lval) \
75 | { \
76 | if (groupPos == 0) { \
77 | groupNo++; \
78 | if (groupNo >= nSelectors) \
79 | RETURN(BZ_DATA_ERROR); \
80 | groupPos = BZ_G_SIZE; \
81 | gSel = s->selector[groupNo]; \
82 | gMinlen = s->minLens[gSel]; \
83 | gLimit = &(s->limit[gSel][0]); \
84 | gPerm = &(s->perm[gSel][0]); \
85 | gBase = &(s->base[gSel][0]); \
86 | } \
87 | groupPos--; \
88 | zn = gMinlen; \
89 | GET_BITS(label1, zvec, zn); \
90 | while (1) { \
91 | if (zn > 20 /* the longest code */) \
92 | RETURN(BZ_DATA_ERROR); \
93 | if (zvec <= gLimit[zn]) break; \
94 | zn++; \
95 | GET_BIT(label2, zj); \
96 | zvec = (zvec << 1) | zj; \
97 | }; \
98 | if (zvec - gBase[zn] < 0 \
99 | || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \
100 | RETURN(BZ_DATA_ERROR); \
101 | lval = gPerm[zvec - gBase[zn]]; \
102 | }
103 |
104 |
105 | /*---------------------------------------------------*/
106 | Int32 BZ2_decompress ( DState* s )
107 | {
108 | UChar uc;
109 | Int32 retVal;
110 | Int32 minLen, maxLen;
111 | bz_stream* strm = s->strm;
112 |
113 | /* stuff that needs to be saved/restored */
114 | Int32 i;
115 | Int32 j;
116 | Int32 t;
117 | Int32 alphaSize;
118 | Int32 nGroups;
119 | Int32 nSelectors;
120 | Int32 EOB;
121 | Int32 groupNo;
122 | Int32 groupPos;
123 | Int32 nextSym;
124 | Int32 nblockMAX;
125 | Int32 nblock;
126 | Int32 es;
127 | Int32 N;
128 | Int32 curr;
129 | Int32 zt;
130 | Int32 zn;
131 | Int32 zvec;
132 | Int32 zj;
133 | Int32 gSel;
134 | Int32 gMinlen;
135 | Int32* gLimit;
136 | Int32* gBase;
137 | Int32* gPerm;
138 |
139 | if (s->state == BZ_X_MAGIC_1) {
140 | /*initialise the save area*/
141 | s->save_i = 0;
142 | s->save_j = 0;
143 | s->save_t = 0;
144 | s->save_alphaSize = 0;
145 | s->save_nGroups = 0;
146 | s->save_nSelectors = 0;
147 | s->save_EOB = 0;
148 | s->save_groupNo = 0;
149 | s->save_groupPos = 0;
150 | s->save_nextSym = 0;
151 | s->save_nblockMAX = 0;
152 | s->save_nblock = 0;
153 | s->save_es = 0;
154 | s->save_N = 0;
155 | s->save_curr = 0;
156 | s->save_zt = 0;
157 | s->save_zn = 0;
158 | s->save_zvec = 0;
159 | s->save_zj = 0;
160 | s->save_gSel = 0;
161 | s->save_gMinlen = 0;
162 | s->save_gLimit = NULL;
163 | s->save_gBase = NULL;
164 | s->save_gPerm = NULL;
165 | }
166 |
167 | /*restore from the save area*/
168 | i = s->save_i;
169 | j = s->save_j;
170 | t = s->save_t;
171 | alphaSize = s->save_alphaSize;
172 | nGroups = s->save_nGroups;
173 | nSelectors = s->save_nSelectors;
174 | EOB = s->save_EOB;
175 | groupNo = s->save_groupNo;
176 | groupPos = s->save_groupPos;
177 | nextSym = s->save_nextSym;
178 | nblockMAX = s->save_nblockMAX;
179 | nblock = s->save_nblock;
180 | es = s->save_es;
181 | N = s->save_N;
182 | curr = s->save_curr;
183 | zt = s->save_zt;
184 | zn = s->save_zn;
185 | zvec = s->save_zvec;
186 | zj = s->save_zj;
187 | gSel = s->save_gSel;
188 | gMinlen = s->save_gMinlen;
189 | gLimit = s->save_gLimit;
190 | gBase = s->save_gBase;
191 | gPerm = s->save_gPerm;
192 |
193 | retVal = BZ_OK;
194 |
195 | switch (s->state) {
196 |
197 | GET_UCHAR(BZ_X_MAGIC_1, uc);
198 | if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC);
199 |
200 | GET_UCHAR(BZ_X_MAGIC_2, uc);
201 | if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC);
202 |
203 | GET_UCHAR(BZ_X_MAGIC_3, uc)
204 | if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC);
205 |
206 | GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8)
207 | if (s->blockSize100k < (BZ_HDR_0 + 1) ||
208 | s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC);
209 | s->blockSize100k -= BZ_HDR_0;
210 |
211 | if (s->smallDecompress) {
212 | s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) );
213 | s->ll4 = BZALLOC(
214 | ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar)
215 | );
216 | if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR);
217 | } else {
218 | s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) );
219 | if (s->tt == NULL) RETURN(BZ_MEM_ERROR);
220 | }
221 |
222 | GET_UCHAR(BZ_X_BLKHDR_1, uc);
223 |
224 | if (uc == 0x17) goto endhdr_2;
225 | if (uc != 0x31) RETURN(BZ_DATA_ERROR);
226 | GET_UCHAR(BZ_X_BLKHDR_2, uc);
227 | if (uc != 0x41) RETURN(BZ_DATA_ERROR);
228 | GET_UCHAR(BZ_X_BLKHDR_3, uc);
229 | if (uc != 0x59) RETURN(BZ_DATA_ERROR);
230 | GET_UCHAR(BZ_X_BLKHDR_4, uc);
231 | if (uc != 0x26) RETURN(BZ_DATA_ERROR);
232 | GET_UCHAR(BZ_X_BLKHDR_5, uc);
233 | if (uc != 0x53) RETURN(BZ_DATA_ERROR);
234 | GET_UCHAR(BZ_X_BLKHDR_6, uc);
235 | if (uc != 0x59) RETURN(BZ_DATA_ERROR);
236 |
237 | s->currBlockNo++;
238 | if (s->verbosity >= 2)
239 | VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo );
240 |
241 | s->storedBlockCRC = 0;
242 | GET_UCHAR(BZ_X_BCRC_1, uc);
243 | s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
244 | GET_UCHAR(BZ_X_BCRC_2, uc);
245 | s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
246 | GET_UCHAR(BZ_X_BCRC_3, uc);
247 | s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
248 | GET_UCHAR(BZ_X_BCRC_4, uc);
249 | s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc);
250 |
251 | GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1);
252 |
253 | s->origPtr = 0;
254 | GET_UCHAR(BZ_X_ORIGPTR_1, uc);
255 | s->origPtr = (s->origPtr << 8) | ((Int32)uc);
256 | GET_UCHAR(BZ_X_ORIGPTR_2, uc);
257 | s->origPtr = (s->origPtr << 8) | ((Int32)uc);
258 | GET_UCHAR(BZ_X_ORIGPTR_3, uc);
259 | s->origPtr = (s->origPtr << 8) | ((Int32)uc);
260 |
261 | if (s->origPtr < 0)
262 | RETURN(BZ_DATA_ERROR);
263 | if (s->origPtr > 10 + 100000*s->blockSize100k)
264 | RETURN(BZ_DATA_ERROR);
265 |
266 | /*--- Receive the mapping table ---*/
267 | for (i = 0; i < 16; i++) {
268 | GET_BIT(BZ_X_MAPPING_1, uc);
269 | if (uc == 1)
270 | s->inUse16[i] = True; else
271 | s->inUse16[i] = False;
272 | }
273 |
274 | for (i = 0; i < 256; i++) s->inUse[i] = False;
275 |
276 | for (i = 0; i < 16; i++)
277 | if (s->inUse16[i])
278 | for (j = 0; j < 16; j++) {
279 | GET_BIT(BZ_X_MAPPING_2, uc);
280 | if (uc == 1) s->inUse[i * 16 + j] = True;
281 | }
282 | makeMaps_d ( s );
283 | if (s->nInUse == 0) RETURN(BZ_DATA_ERROR);
284 | alphaSize = s->nInUse+2;
285 |
286 | /*--- Now the selectors ---*/
287 | GET_BITS(BZ_X_SELECTOR_1, nGroups, 3);
288 | if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR);
289 | GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15);
290 | if (nSelectors < 1) RETURN(BZ_DATA_ERROR);
291 | for (i = 0; i < nSelectors; i++) {
292 | j = 0;
293 | while (True) {
294 | GET_BIT(BZ_X_SELECTOR_3, uc);
295 | if (uc == 0) break;
296 | j++;
297 | if (j >= nGroups) RETURN(BZ_DATA_ERROR);
298 | }
299 | s->selectorMtf[i] = j;
300 | }
301 |
302 | /*--- Undo the MTF values for the selectors. ---*/
303 | {
304 | UChar pos[BZ_N_GROUPS], tmp, v;
305 | for (v = 0; v < nGroups; v++) pos[v] = v;
306 |
307 | for (i = 0; i < nSelectors; i++) {
308 | v = s->selectorMtf[i];
309 | tmp = pos[v];
310 | while (v > 0) { pos[v] = pos[v-1]; v--; }
311 | pos[0] = tmp;
312 | s->selector[i] = tmp;
313 | }
314 | }
315 |
316 | /*--- Now the coding tables ---*/
317 | for (t = 0; t < nGroups; t++) {
318 | GET_BITS(BZ_X_CODING_1, curr, 5);
319 | for (i = 0; i < alphaSize; i++) {
320 | while (True) {
321 | if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR);
322 | GET_BIT(BZ_X_CODING_2, uc);
323 | if (uc == 0) break;
324 | GET_BIT(BZ_X_CODING_3, uc);
325 | if (uc == 0) curr++; else curr--;
326 | }
327 | s->len[t][i] = curr;
328 | }
329 | }
330 |
331 | /*--- Create the Huffman decoding tables ---*/
332 | for (t = 0; t < nGroups; t++) {
333 | minLen = 32;
334 | maxLen = 0;
335 | for (i = 0; i < alphaSize; i++) {
336 | if (s->len[t][i] > maxLen) maxLen = s->len[t][i];
337 | if (s->len[t][i] < minLen) minLen = s->len[t][i];
338 | }
339 | BZ2_hbCreateDecodeTables (
340 | &(s->limit[t][0]),
341 | &(s->base[t][0]),
342 | &(s->perm[t][0]),
343 | &(s->len[t][0]),
344 | minLen, maxLen, alphaSize
345 | );
346 | s->minLens[t] = minLen;
347 | }
348 |
349 | /*--- Now the MTF values ---*/
350 |
351 | EOB = s->nInUse+1;
352 | nblockMAX = 100000 * s->blockSize100k;
353 | groupNo = -1;
354 | groupPos = 0;
355 |
356 | for (i = 0; i <= 255; i++) s->unzftab[i] = 0;
357 |
358 | /*-- MTF init --*/
359 | {
360 | Int32 ii, jj, kk;
361 | kk = MTFA_SIZE-1;
362 | for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) {
363 | for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
364 | s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj);
365 | kk--;
366 | }
367 | s->mtfbase[ii] = kk + 1;
368 | }
369 | }
370 | /*-- end MTF init --*/
371 |
372 | nblock = 0;
373 | GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym);
374 |
375 | while (True) {
376 |
377 | if (nextSym == EOB) break;
378 |
379 | if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) {
380 |
381 | es = -1;
382 | N = 1;
383 | do {
384 | /* Check that N doesn't get too big, so that es doesn't
385 | go negative. The maximum value that can be
386 | RUNA/RUNB encoded is equal to the block size (post
387 | the initial RLE), viz, 900k, so bounding N at 2
388 | million should guard against overflow without
389 | rejecting any legitimate inputs. */
390 | if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR);
391 | if (nextSym == BZ_RUNA) es = es + (0+1) * N; else
392 | if (nextSym == BZ_RUNB) es = es + (1+1) * N;
393 | N = N * 2;
394 | GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym);
395 | }
396 | while (nextSym == BZ_RUNA || nextSym == BZ_RUNB);
397 |
398 | es++;
399 | uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ];
400 | s->unzftab[uc] += es;
401 |
402 | if (s->smallDecompress)
403 | while (es > 0) {
404 | if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
405 | s->ll16[nblock] = (UInt16)uc;
406 | nblock++;
407 | es--;
408 | }
409 | else
410 | while (es > 0) {
411 | if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
412 | s->tt[nblock] = (UInt32)uc;
413 | nblock++;
414 | es--;
415 | };
416 |
417 | continue;
418 |
419 | } else {
420 |
421 | if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR);
422 |
423 | /*-- uc = MTF ( nextSym-1 ) --*/
424 | {
425 | Int32 ii, jj, kk, pp, lno, off;
426 | UInt32 nn;
427 | nn = (UInt32)(nextSym - 1);
428 |
429 | if (nn < MTFL_SIZE) {
430 | /* avoid general-case expense */
431 | pp = s->mtfbase[0];
432 | uc = s->mtfa[pp+nn];
433 | while (nn > 3) {
434 | Int32 z = pp+nn;
435 | s->mtfa[(z) ] = s->mtfa[(z)-1];
436 | s->mtfa[(z)-1] = s->mtfa[(z)-2];
437 | s->mtfa[(z)-2] = s->mtfa[(z)-3];
438 | s->mtfa[(z)-3] = s->mtfa[(z)-4];
439 | nn -= 4;
440 | }
441 | while (nn > 0) {
442 | s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--;
443 | };
444 | s->mtfa[pp] = uc;
445 | } else {
446 | /* general case */
447 | lno = nn / MTFL_SIZE;
448 | off = nn % MTFL_SIZE;
449 | pp = s->mtfbase[lno] + off;
450 | uc = s->mtfa[pp];
451 | while (pp > s->mtfbase[lno]) {
452 | s->mtfa[pp] = s->mtfa[pp-1]; pp--;
453 | };
454 | s->mtfbase[lno]++;
455 | while (lno > 0) {
456 | s->mtfbase[lno]--;
457 | s->mtfa[s->mtfbase[lno]]
458 | = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1];
459 | lno--;
460 | }
461 | s->mtfbase[0]--;
462 | s->mtfa[s->mtfbase[0]] = uc;
463 | if (s->mtfbase[0] == 0) {
464 | kk = MTFA_SIZE-1;
465 | for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) {
466 | for (jj = MTFL_SIZE-1; jj >= 0; jj--) {
467 | s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj];
468 | kk--;
469 | }
470 | s->mtfbase[ii] = kk + 1;
471 | }
472 | }
473 | }
474 | }
475 | /*-- end uc = MTF ( nextSym-1 ) --*/
476 |
477 | s->unzftab[s->seqToUnseq[uc]]++;
478 | if (s->smallDecompress)
479 | s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else
480 | s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]);
481 | nblock++;
482 |
483 | GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym);
484 | continue;
485 | }
486 | }
487 |
488 | /* Now we know what nblock is, we can do a better sanity
489 | check on s->origPtr.
490 | */
491 | if (s->origPtr < 0 || s->origPtr >= nblock)
492 | RETURN(BZ_DATA_ERROR);
493 |
494 | /*-- Set up cftab to facilitate generation of T^(-1) --*/
495 | /* Check: unzftab entries in range. */
496 | for (i = 0; i <= 255; i++) {
497 | if (s->unzftab[i] < 0 || s->unzftab[i] > nblock)
498 | RETURN(BZ_DATA_ERROR);
499 | }
500 | /* Actually generate cftab. */
501 | s->cftab[0] = 0;
502 | for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1];
503 | for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1];
504 | /* Check: cftab entries in range. */
505 | for (i = 0; i <= 256; i++) {
506 | if (s->cftab[i] < 0 || s->cftab[i] > nblock) {
507 | /* s->cftab[i] can legitimately be == nblock */
508 | RETURN(BZ_DATA_ERROR);
509 | }
510 | }
511 | /* Check: cftab entries non-descending. */
512 | for (i = 1; i <= 256; i++) {
513 | if (s->cftab[i-1] > s->cftab[i]) {
514 | RETURN(BZ_DATA_ERROR);
515 | }
516 | }
517 |
518 | s->state_out_len = 0;
519 | s->state_out_ch = 0;
520 | BZ_INITIALISE_CRC ( s->calculatedBlockCRC );
521 | s->state = BZ_X_OUTPUT;
522 | if (s->verbosity >= 2) VPrintf0 ( "rt+rld" );
523 |
524 | if (s->smallDecompress) {
525 |
526 | /*-- Make a copy of cftab, used in generation of T --*/
527 | for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i];
528 |
529 | /*-- compute the T vector --*/
530 | for (i = 0; i < nblock; i++) {
531 | uc = (UChar)(s->ll16[i]);
532 | SET_LL(i, s->cftabCopy[uc]);
533 | s->cftabCopy[uc]++;
534 | }
535 |
536 | /*-- Compute T^(-1) by pointer reversal on T --*/
537 | i = s->origPtr;
538 | j = GET_LL(i);
539 | do {
540 | Int32 tmp = GET_LL(j);
541 | SET_LL(j, i);
542 | i = j;
543 | j = tmp;
544 | }
545 | while (i != s->origPtr);
546 |
547 | s->tPos = s->origPtr;
548 | s->nblock_used = 0;
549 | if (s->blockRandomised) {
550 | BZ_RAND_INIT_MASK;
551 | BZ_GET_SMALL(s->k0); s->nblock_used++;
552 | BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
553 | } else {
554 | BZ_GET_SMALL(s->k0); s->nblock_used++;
555 | }
556 |
557 | } else {
558 |
559 | /*-- compute the T^(-1) vector --*/
560 | for (i = 0; i < nblock; i++) {
561 | uc = (UChar)(s->tt[i] & 0xff);
562 | s->tt[s->cftab[uc]] |= (i << 8);
563 | s->cftab[uc]++;
564 | }
565 |
566 | s->tPos = s->tt[s->origPtr] >> 8;
567 | s->nblock_used = 0;
568 | if (s->blockRandomised) {
569 | BZ_RAND_INIT_MASK;
570 | BZ_GET_FAST(s->k0); s->nblock_used++;
571 | BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK;
572 | } else {
573 | BZ_GET_FAST(s->k0); s->nblock_used++;
574 | }
575 |
576 | }
577 |
578 | RETURN(BZ_OK);
579 |
580 |
581 |
582 | endhdr_2:
583 |
584 | GET_UCHAR(BZ_X_ENDHDR_2, uc);
585 | if (uc != 0x72) RETURN(BZ_DATA_ERROR);
586 | GET_UCHAR(BZ_X_ENDHDR_3, uc);
587 | if (uc != 0x45) RETURN(BZ_DATA_ERROR);
588 | GET_UCHAR(BZ_X_ENDHDR_4, uc);
589 | if (uc != 0x38) RETURN(BZ_DATA_ERROR);
590 | GET_UCHAR(BZ_X_ENDHDR_5, uc);
591 | if (uc != 0x50) RETURN(BZ_DATA_ERROR);
592 | GET_UCHAR(BZ_X_ENDHDR_6, uc);
593 | if (uc != 0x90) RETURN(BZ_DATA_ERROR);
594 |
595 | s->storedCombinedCRC = 0;
596 | GET_UCHAR(BZ_X_CCRC_1, uc);
597 | s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
598 | GET_UCHAR(BZ_X_CCRC_2, uc);
599 | s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
600 | GET_UCHAR(BZ_X_CCRC_3, uc);
601 | s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
602 | GET_UCHAR(BZ_X_CCRC_4, uc);
603 | s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc);
604 |
605 | s->state = BZ_X_IDLE;
606 | RETURN(BZ_STREAM_END);
607 |
608 | default: AssertH ( False, 4001 );
609 | }
610 |
611 | AssertH ( False, 4002 );
612 |
613 | save_state_and_return:
614 |
615 | s->save_i = i;
616 | s->save_j = j;
617 | s->save_t = t;
618 | s->save_alphaSize = alphaSize;
619 | s->save_nGroups = nGroups;
620 | s->save_nSelectors = nSelectors;
621 | s->save_EOB = EOB;
622 | s->save_groupNo = groupNo;
623 | s->save_groupPos = groupPos;
624 | s->save_nextSym = nextSym;
625 | s->save_nblockMAX = nblockMAX;
626 | s->save_nblock = nblock;
627 | s->save_es = es;
628 | s->save_N = N;
629 | s->save_curr = curr;
630 | s->save_zt = zt;
631 | s->save_zn = zn;
632 | s->save_zvec = zvec;
633 | s->save_zj = zj;
634 | s->save_gSel = gSel;
635 | s->save_gMinlen = gMinlen;
636 | s->save_gLimit = gLimit;
637 | s->save_gBase = gBase;
638 | s->save_gPerm = gPerm;
639 |
640 | return retVal;
641 | }
642 |
643 |
644 | /*-------------------------------------------------------------*/
645 | /*--- end decompress.c ---*/
646 | /*-------------------------------------------------------------*/
647 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/jni/bzip2/huffman.c:
--------------------------------------------------------------------------------
1 |
2 | /*-------------------------------------------------------------*/
3 | /*--- Huffman coding low-level stuff ---*/
4 | /*--- huffman.c ---*/
5 | /*-------------------------------------------------------------*/
6 |
7 | /* ------------------------------------------------------------------
8 | This file is part of bzip2/libbzip2, a program and library for
9 | lossless, block-sorting data compression.
10 |
11 | bzip2/libbzip2 version 1.0.6 of 6 September 2010
12 | Copyright (C) 1996-2010 Julian Seward
13 |
14 | Please read the WARNING, DISCLAIMER and PATENTS sections in the
15 | README file.
16 |
17 | This program is released under the terms of the license contained
18 | in the file LICENSE.
19 | ------------------------------------------------------------------ */
20 |
21 |
22 | #include "bzlib_private.h"
23 |
24 | /*---------------------------------------------------*/
25 | #define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
26 | #define DEPTHOF(zz1) ((zz1) & 0x000000ff)
27 | #define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
28 |
29 | #define ADDWEIGHTS(zw1,zw2) \
30 | (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
31 | (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
32 |
33 | #define UPHEAP(z) \
34 | { \
35 | Int32 zz, tmp; \
36 | zz = z; tmp = heap[zz]; \
37 | while (weight[tmp] < weight[heap[zz >> 1]]) { \
38 | heap[zz] = heap[zz >> 1]; \
39 | zz >>= 1; \
40 | } \
41 | heap[zz] = tmp; \
42 | }
43 |
44 | #define DOWNHEAP(z) \
45 | { \
46 | Int32 zz, yy, tmp; \
47 | zz = z; tmp = heap[zz]; \
48 | while (True) { \
49 | yy = zz << 1; \
50 | if (yy > nHeap) break; \
51 | if (yy < nHeap && \
52 | weight[heap[yy+1]] < weight[heap[yy]]) \
53 | yy++; \
54 | if (weight[tmp] < weight[heap[yy]]) break; \
55 | heap[zz] = heap[yy]; \
56 | zz = yy; \
57 | } \
58 | heap[zz] = tmp; \
59 | }
60 |
61 |
62 | /*---------------------------------------------------*/
63 | void BZ2_hbMakeCodeLengths ( UChar *len,
64 | Int32 *freq,
65 | Int32 alphaSize,
66 | Int32 maxLen )
67 | {
68 | /*--
69 | Nodes and heap entries run from 1. Entry 0
70 | for both the heap and nodes is a sentinel.
71 | --*/
72 | Int32 nNodes, nHeap, n1, n2, i, j, k;
73 | Bool tooLong;
74 |
75 | Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
76 | Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
77 | Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
78 |
79 | for (i = 0; i < alphaSize; i++)
80 | weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
81 |
82 | while (True) {
83 |
84 | nNodes = alphaSize;
85 | nHeap = 0;
86 |
87 | heap[0] = 0;
88 | weight[0] = 0;
89 | parent[0] = -2;
90 |
91 | for (i = 1; i <= alphaSize; i++) {
92 | parent[i] = -1;
93 | nHeap++;
94 | heap[nHeap] = i;
95 | UPHEAP(nHeap);
96 | }
97 |
98 | AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
99 |
100 | while (nHeap > 1) {
101 | n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
102 | n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
103 | nNodes++;
104 | parent[n1] = parent[n2] = nNodes;
105 | weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
106 | parent[nNodes] = -1;
107 | nHeap++;
108 | heap[nHeap] = nNodes;
109 | UPHEAP(nHeap);
110 | }
111 |
112 | AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
113 |
114 | tooLong = False;
115 | for (i = 1; i <= alphaSize; i++) {
116 | j = 0;
117 | k = i;
118 | while (parent[k] >= 0) { k = parent[k]; j++; }
119 | len[i-1] = j;
120 | if (j > maxLen) tooLong = True;
121 | }
122 |
123 | if (! tooLong) break;
124 |
125 | /* 17 Oct 04: keep-going condition for the following loop used
126 | to be 'i < alphaSize', which missed the last element,
127 | theoretically leading to the possibility of the compressor
128 | looping. However, this count-scaling step is only needed if
129 | one of the generated Huffman code words is longer than
130 | maxLen, which up to and including version 1.0.2 was 20 bits,
131 | which is extremely unlikely. In version 1.0.3 maxLen was
132 | changed to 17 bits, which has minimal effect on compression
133 | ratio, but does mean this scaling step is used from time to
134 | time, enough to verify that it works.
135 |
136 | This means that bzip2-1.0.3 and later will only produce
137 | Huffman codes with a maximum length of 17 bits. However, in
138 | order to preserve backwards compatibility with bitstreams
139 | produced by versions pre-1.0.3, the decompressor must still
140 | handle lengths of up to 20. */
141 |
142 | for (i = 1; i <= alphaSize; i++) {
143 | j = weight[i] >> 8;
144 | j = 1 + (j / 2);
145 | weight[i] = j << 8;
146 | }
147 | }
148 | }
149 |
150 |
151 | /*---------------------------------------------------*/
152 | void BZ2_hbAssignCodes ( Int32 *code,
153 | UChar *length,
154 | Int32 minLen,
155 | Int32 maxLen,
156 | Int32 alphaSize )
157 | {
158 | Int32 n, vec, i;
159 |
160 | vec = 0;
161 | for (n = minLen; n <= maxLen; n++) {
162 | for (i = 0; i < alphaSize; i++)
163 | if (length[i] == n) { code[i] = vec; vec++; };
164 | vec <<= 1;
165 | }
166 | }
167 |
168 |
169 | /*---------------------------------------------------*/
170 | void BZ2_hbCreateDecodeTables ( Int32 *limit,
171 | Int32 *base,
172 | Int32 *perm,
173 | UChar *length,
174 | Int32 minLen,
175 | Int32 maxLen,
176 | Int32 alphaSize )
177 | {
178 | Int32 pp, i, j, vec;
179 |
180 | pp = 0;
181 | for (i = minLen; i <= maxLen; i++)
182 | for (j = 0; j < alphaSize; j++)
183 | if (length[j] == i) { perm[pp] = j; pp++; };
184 |
185 | for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
186 | for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
187 |
188 | for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
189 |
190 | for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
191 | vec = 0;
192 |
193 | for (i = minLen; i <= maxLen; i++) {
194 | vec += (base[i+1] - base[i]);
195 | limit[i] = vec-1;
196 | vec <<= 1;
197 | }
198 | for (i = minLen + 1; i <= maxLen; i++)
199 | base[i] = ((limit[i-1] + 1) << 1) - base[i];
200 | }
201 |
202 |
203 | /*-------------------------------------------------------------*/
204 | /*--- end huffman.c ---*/
205 | /*-------------------------------------------------------------*/
206 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/jni/bzip2/randtable.c:
--------------------------------------------------------------------------------
1 |
2 | /*-------------------------------------------------------------*/
3 | /*--- Table for randomising repetitive blocks ---*/
4 | /*--- randtable.c ---*/
5 | /*-------------------------------------------------------------*/
6 |
7 | /* ------------------------------------------------------------------
8 | This file is part of bzip2/libbzip2, a program and library for
9 | lossless, block-sorting data compression.
10 |
11 | bzip2/libbzip2 version 1.0.6 of 6 September 2010
12 | Copyright (C) 1996-2010 Julian Seward
13 |
14 | Please read the WARNING, DISCLAIMER and PATENTS sections in the
15 | README file.
16 |
17 | This program is released under the terms of the license contained
18 | in the file LICENSE.
19 | ------------------------------------------------------------------ */
20 |
21 |
22 | #include "bzlib_private.h"
23 |
24 |
25 | /*---------------------------------------------*/
26 | Int32 BZ2_rNums[512] = {
27 | 619, 720, 127, 481, 931, 816, 813, 233, 566, 247,
28 | 985, 724, 205, 454, 863, 491, 741, 242, 949, 214,
29 | 733, 859, 335, 708, 621, 574, 73, 654, 730, 472,
30 | 419, 436, 278, 496, 867, 210, 399, 680, 480, 51,
31 | 878, 465, 811, 169, 869, 675, 611, 697, 867, 561,
32 | 862, 687, 507, 283, 482, 129, 807, 591, 733, 623,
33 | 150, 238, 59, 379, 684, 877, 625, 169, 643, 105,
34 | 170, 607, 520, 932, 727, 476, 693, 425, 174, 647,
35 | 73, 122, 335, 530, 442, 853, 695, 249, 445, 515,
36 | 909, 545, 703, 919, 874, 474, 882, 500, 594, 612,
37 | 641, 801, 220, 162, 819, 984, 589, 513, 495, 799,
38 | 161, 604, 958, 533, 221, 400, 386, 867, 600, 782,
39 | 382, 596, 414, 171, 516, 375, 682, 485, 911, 276,
40 | 98, 553, 163, 354, 666, 933, 424, 341, 533, 870,
41 | 227, 730, 475, 186, 263, 647, 537, 686, 600, 224,
42 | 469, 68, 770, 919, 190, 373, 294, 822, 808, 206,
43 | 184, 943, 795, 384, 383, 461, 404, 758, 839, 887,
44 | 715, 67, 618, 276, 204, 918, 873, 777, 604, 560,
45 | 951, 160, 578, 722, 79, 804, 96, 409, 713, 940,
46 | 652, 934, 970, 447, 318, 353, 859, 672, 112, 785,
47 | 645, 863, 803, 350, 139, 93, 354, 99, 820, 908,
48 | 609, 772, 154, 274, 580, 184, 79, 626, 630, 742,
49 | 653, 282, 762, 623, 680, 81, 927, 626, 789, 125,
50 | 411, 521, 938, 300, 821, 78, 343, 175, 128, 250,
51 | 170, 774, 972, 275, 999, 639, 495, 78, 352, 126,
52 | 857, 956, 358, 619, 580, 124, 737, 594, 701, 612,
53 | 669, 112, 134, 694, 363, 992, 809, 743, 168, 974,
54 | 944, 375, 748, 52, 600, 747, 642, 182, 862, 81,
55 | 344, 805, 988, 739, 511, 655, 814, 334, 249, 515,
56 | 897, 955, 664, 981, 649, 113, 974, 459, 893, 228,
57 | 433, 837, 553, 268, 926, 240, 102, 654, 459, 51,
58 | 686, 754, 806, 760, 493, 403, 415, 394, 687, 700,
59 | 946, 670, 656, 610, 738, 392, 760, 799, 887, 653,
60 | 978, 321, 576, 617, 626, 502, 894, 679, 243, 440,
61 | 680, 879, 194, 572, 640, 724, 926, 56, 204, 700,
62 | 707, 151, 457, 449, 797, 195, 791, 558, 945, 679,
63 | 297, 59, 87, 824, 713, 663, 412, 693, 342, 606,
64 | 134, 108, 571, 364, 631, 212, 174, 643, 304, 329,
65 | 343, 97, 430, 751, 497, 314, 983, 374, 822, 928,
66 | 140, 206, 73, 263, 980, 736, 876, 478, 430, 305,
67 | 170, 514, 364, 692, 829, 82, 855, 953, 676, 246,
68 | 369, 970, 294, 750, 807, 827, 150, 790, 288, 923,
69 | 804, 378, 215, 828, 592, 281, 565, 555, 710, 82,
70 | 896, 831, 547, 261, 524, 462, 293, 465, 502, 56,
71 | 661, 821, 976, 991, 658, 869, 905, 758, 745, 193,
72 | 768, 550, 608, 933, 378, 286, 215, 979, 792, 961,
73 | 61, 688, 793, 644, 986, 403, 106, 366, 905, 644,
74 | 372, 567, 466, 434, 645, 210, 389, 550, 919, 135,
75 | 780, 773, 635, 389, 707, 100, 626, 958, 165, 504,
76 | 920, 176, 193, 713, 857, 265, 203, 50, 668, 108,
77 | 645, 990, 626, 197, 510, 357, 358, 850, 858, 364,
78 | 936, 638
79 | };
80 |
81 |
82 | /*-------------------------------------------------------------*/
83 | /*--- end randtable.c ---*/
84 | /*-------------------------------------------------------------*/
85 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/jni/bzip2/readMe.txt:
--------------------------------------------------------------------------------
1 | bzip2包中文件来来自:
2 | http://www.bzip.org/downloads.html
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/jni/com_wang_appupdate_util_PatchUtil.h:
--------------------------------------------------------------------------------
1 | /* DO NOT EDIT THIS FILE - it is machine generated */
2 | #include
3 | /* Header for class com_wang_appupdate_util_PatchUtil */
4 |
5 | #ifndef _Included_com_wang_appupdate_util_PatchUtil
6 | #define _Included_com_wang_appupdate_util_PatchUtil
7 | #ifdef __cplusplus
8 | extern "C" {
9 | #endif
10 | /*
11 | * Class: com_wang_appupdate_util_PatchUtil
12 | * Method: diff
13 | * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
14 | */
15 | JNIEXPORT jint JNICALL Java_com_wang_appupdate_util_PatchUtil_diff
16 | (JNIEnv *, jclass, jstring, jstring, jstring);
17 |
18 | /*
19 | * Class: com_wang_appupdate_util_PatchUtil
20 | * Method: patch
21 | * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I
22 | */
23 | JNIEXPORT jint JNICALL Java_com_wang_appupdate_util_PatchUtil_patch
24 | (JNIEnv *, jclass, jstring, jstring, jstring);
25 |
26 | #ifdef __cplusplus
27 | }
28 | #endif
29 | #endif
30 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/jni/diff.c:
--------------------------------------------------------------------------------
1 | //
2 | // Created by wang on 2016/9/9.
3 | //
4 |
5 | #include
6 | #include "bzip2/bzlib.h"
7 | #include
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 | #include "util/android_log_print.h"
14 |
15 | #include "com_wang_appupdate_util_PatchUtil.h"
16 |
17 | #define MIN(x,y) (((x)<(y)) ? (x) : (y))
18 |
19 | static void split(off_t *I, off_t *V, off_t start, off_t len, off_t h) {
20 | off_t i, j, k, x, tmp, jj, kk;
21 |
22 | if (len < 16) {
23 | for (k = start; k < start + len; k += j) {
24 | j = 1;
25 | x = V[I[k] + h];
26 | for (i = 1; k + i < start + len; i++) {
27 | if (V[I[k + i] + h] < x) {
28 | x = V[I[k + i] + h];
29 | j = 0;
30 | };
31 | if (V[I[k + i] + h] == x) {
32 | tmp = I[k + j];
33 | I[k + j] = I[k + i];
34 | I[k + i] = tmp;
35 | j++;
36 | };
37 | };
38 | for (i = 0; i < j; i++)
39 | V[I[k + i]] = k + j - 1;
40 | if (j == 1)
41 | I[k] = -1;
42 | };
43 | return;
44 | };
45 |
46 | x = V[I[start + len / 2] + h];
47 | jj = 0;
48 | kk = 0;
49 | for (i = start; i < start + len; i++) {
50 | if (V[I[i] + h] < x)
51 | jj++;
52 | if (V[I[i] + h] == x)
53 | kk++;
54 | };
55 | jj += start;
56 | kk += jj;
57 |
58 | i = start;
59 | j = 0;
60 | k = 0;
61 | while (i < jj) {
62 | if (V[I[i] + h] < x) {
63 | i++;
64 | } else if (V[I[i] + h] == x) {
65 | tmp = I[i];
66 | I[i] = I[jj + j];
67 | I[jj + j] = tmp;
68 | j++;
69 | } else {
70 | tmp = I[i];
71 | I[i] = I[kk + k];
72 | I[kk + k] = tmp;
73 | k++;
74 | };
75 | };
76 |
77 | while (jj + j < kk) {
78 | if (V[I[jj + j] + h] == x) {
79 | j++;
80 | } else {
81 | tmp = I[jj + j];
82 | I[jj + j] = I[kk + k];
83 | I[kk + k] = tmp;
84 | k++;
85 | };
86 | };
87 |
88 | if (jj > start)
89 | split(I, V, start, jj - start, h);
90 |
91 | for (i = 0; i < kk - jj; i++)
92 | V[I[jj + i]] = kk - 1;
93 | if (jj == kk - 1)
94 | I[jj] = -1;
95 |
96 | if (start + len > kk)
97 | split(I, V, kk, start + len - kk, h);
98 | }
99 |
100 | static void qsufsort(off_t *I, off_t *V, u_char *old, off_t oldsize) {
101 | off_t buckets[256];
102 | off_t i, h, len;
103 |
104 | for (i = 0; i < 256; i++)
105 | buckets[i] = 0;
106 | for (i = 0; i < oldsize; i++)
107 | buckets[old[i]]++;
108 | for (i = 1; i < 256; i++)
109 | buckets[i] += buckets[i - 1];
110 | for (i = 255; i > 0; i--)
111 | buckets[i] = buckets[i - 1];
112 | buckets[0] = 0;
113 |
114 | for (i = 0; i < oldsize; i++)
115 | I[++buckets[old[i]]] = i;
116 | I[0] = oldsize;
117 | for (i = 0; i < oldsize; i++)
118 | V[i] = buckets[old[i]];
119 | V[oldsize] = 0;
120 | for (i = 1; i < 256; i++)
121 | if (buckets[i] == buckets[i - 1] + 1)
122 | I[buckets[i]] = -1;
123 | I[0] = -1;
124 |
125 | for (h = 1; I[0] != -(oldsize + 1); h += h) {
126 | len = 0;
127 | for (i = 0; i < oldsize + 1;) {
128 | if (I[i] < 0) {
129 | len -= I[i];
130 | i -= I[i];
131 | } else {
132 | if (len)
133 | I[i - len] = -len;
134 | len = V[I[i]] + 1 - i;
135 | split(I, V, i, len, h);
136 | i += len;
137 | len = 0;
138 | };
139 | };
140 | if (len)
141 | I[i - len] = -len;
142 | };
143 |
144 | for (i = 0; i < oldsize + 1; i++)
145 | I[V[i]] = i;
146 | }
147 |
148 | static off_t matchlen(u_char *old, off_t oldsize, u_char *new, off_t newsize) {
149 | off_t i;
150 |
151 | for (i = 0; (i < oldsize) && (i < newsize); i++)
152 | if (old[i] != new[i])
153 | break;
154 |
155 | return i;
156 | }
157 |
158 | static off_t search(off_t *I, u_char *old, off_t oldsize, u_char *new,
159 | off_t newsize, off_t st, off_t en, off_t *pos) {
160 | off_t x, y;
161 |
162 | if (en - st < 2) {
163 | x = matchlen(old + I[st], oldsize - I[st], new, newsize);
164 | y = matchlen(old + I[en], oldsize - I[en], new, newsize);
165 |
166 | if (x > y) {
167 | *pos = I[st];
168 | return x;
169 | } else {
170 | *pos = I[en];
171 | return y;
172 | }
173 | };
174 |
175 | x = st + (en - st) / 2;
176 | if (memcmp(old + I[x], new, MIN(oldsize-I[x],newsize)) < 0) {
177 | return search(I, old, oldsize, new, newsize, x, en, pos);
178 | } else {
179 | return search(I, old, oldsize, new, newsize, st, x, pos);
180 | };
181 | }
182 |
183 | static void offtout(off_t x, u_char *buf) {
184 | off_t y;
185 |
186 | if (x < 0)
187 | y = -x;
188 | else
189 | y = x;
190 |
191 | buf[0] = y % 256;
192 | y -= buf[0];
193 | y = y / 256;
194 | buf[1] = y % 256;
195 | y -= buf[1];
196 | y = y / 256;
197 | buf[2] = y % 256;
198 | y -= buf[2];
199 | y = y / 256;
200 | buf[3] = y % 256;
201 | y -= buf[3];
202 | y = y / 256;
203 | buf[4] = y % 256;
204 | y -= buf[4];
205 | y = y / 256;
206 | buf[5] = y % 256;
207 | y -= buf[5];
208 | y = y / 256;
209 | buf[6] = y % 256;
210 | y -= buf[6];
211 | y = y / 256;
212 | buf[7] = y % 256;
213 |
214 | if (x < 0)
215 | buf[7] |= 0x80;
216 | }
217 |
218 | int genpatch(int argc, char *argv[]) {
219 | int fd;
220 | u_char *old, *new;
221 | off_t oldsize, newsize;
222 | off_t *I, *V;
223 | off_t scan, pos, len;
224 | off_t lastscan, lastpos, lastoffset;
225 | off_t oldscore, scsc;
226 | off_t s, Sf, lenf, Sb, lenb;
227 | off_t overlap, Ss, lens;
228 | off_t i;
229 | off_t dblen, eblen;
230 | u_char *db, *eb;
231 | u_char buf[8];
232 | u_char header[32];
233 | FILE * pf;
234 | BZFILE * pfbz2;
235 | int bz2err;
236 |
237 | if (argc != 4){
238 | LOGE("%s please usage: oldfile newfile patchfile three files", argv[0]);
239 | return 1;
240 | }
241 |
242 | /* Allocate oldsize+1 bytes instead of oldsize bytes to ensure
243 | that we never try to malloc(0) and get a NULL pointer */
244 | if (((fd = open(argv[1], O_RDONLY, 0)) < 0)
245 | || ((oldsize = lseek(fd, 0, SEEK_END)) == -1)
246 | || ((old = malloc(oldsize + 1)) == NULL )
247 | || (lseek(fd, 0, SEEK_SET) != 0)
248 | || (read(fd, old, oldsize) != oldsize) || (close(fd) == -1)){
249 | LOGE("read %s is fail", argv[1]);
250 | return 2;
251 | }
252 |
253 | if (((I = malloc((oldsize + 1) * sizeof(off_t))) == NULL )
254 | || ((V = malloc((oldsize + 1) * sizeof(off_t))) == NULL)){
255 | LOGE("Memory allocation is fail");
256 | return 5;
257 | }
258 |
259 | qsufsort(I, V, old, oldsize);
260 |
261 | free(V);
262 |
263 | /* Allocate newsize+1 bytes instead of newsize bytes to ensure
264 | that we never try to malloc(0) and get a NULL pointer */
265 | if (((fd = open(argv[2], O_RDONLY, 0)) < 0)
266 | || ((newsize = lseek(fd, 0, SEEK_END)) == -1)
267 | || ((new = malloc(newsize + 1)) == NULL )
268 | || (lseek(fd, 0, SEEK_SET) != 0)
269 | || (read(fd, new, newsize) != newsize) || (close(fd) == -1)){
270 | LOGE("read %s is fail", argv[2]);
271 | return 3;
272 | }
273 |
274 | if (((db = malloc(newsize + 1)) == NULL )
275 | || ((eb = malloc(newsize + 1)) == NULL)){
276 | LOGE("Memory allocation is fail");
277 | return 5;
278 | }
279 | dblen = 0;
280 | eblen = 0;
281 |
282 | /* Create the patch file */
283 | if ((pf = fopen(argv[3], "w")) == NULL ) {
284 | LOGE("creat %s is fail", argv[3]);
285 | return 6;
286 | }
287 |
288 | /* Header is
289 | 0 8 "BSDIFF40"
290 | 8 8 length of bzip2ed ctrl block
291 | 16 8 length of bzip2ed diff block
292 | 24 8 length of new file */
293 | /* File is
294 | 0 32 Header
295 | 32 ?? Bzip2ed ctrl block
296 | ?? ?? Bzip2ed diff block
297 | ?? ?? Bzip2ed extra block */
298 | memcpy(header, "BSDIFF40", 8);
299 | offtout(0, header + 8);
300 | offtout(0, header + 16);
301 | offtout(newsize, header + 24);
302 | if (fwrite(header, 32, 1, pf) != 1) {
303 | LOGE("write %s is fail", argv[3]);
304 | return 6;
305 | }
306 |
307 | /* Compute the differences, writing ctrl as we go */
308 | if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL ){
309 | LOGE("BZ2_bzWriteOpen, bz2err = %d", bz2err);
310 | return 7;
311 |
312 | }
313 | scan = 0;
314 | len = 0;
315 | lastscan = 0;
316 | lastpos = 0;
317 | lastoffset = 0;
318 | while (scan < newsize) {
319 | oldscore = 0;
320 |
321 | for (scsc = scan += len; scan < newsize; scan++) {
322 | len = search(I, old, oldsize, new + scan, newsize - scan, 0,
323 | oldsize, &pos);
324 |
325 | for (; scsc < scan + len; scsc++)
326 | if ((scsc + lastoffset < oldsize)
327 | && (old[scsc + lastoffset] == new[scsc]))
328 | oldscore++;
329 |
330 | if (((len == oldscore) && (len != 0)) || (len > oldscore + 8))
331 | break;
332 |
333 | if ((scan + lastoffset < oldsize)
334 | && (old[scan + lastoffset] == new[scan]))
335 | oldscore--;
336 | };
337 |
338 | if ((len != oldscore) || (scan == newsize)) {
339 | s = 0;
340 | Sf = 0;
341 | lenf = 0;
342 | for (i = 0; (lastscan + i < scan) && (lastpos + i < oldsize);) {
343 | if (old[lastpos + i] == new[lastscan + i])
344 | s++;
345 | i++;
346 | if (s * 2 - i > Sf * 2 - lenf) {
347 | Sf = s;
348 | lenf = i;
349 | };
350 | };
351 |
352 | lenb = 0;
353 | if (scan < newsize) {
354 | s = 0;
355 | Sb = 0;
356 | for (i = 1; (scan >= lastscan + i) && (pos >= i); i++) {
357 | if (old[pos - i] == new[scan - i])
358 | s++;
359 | if (s * 2 - i > Sb * 2 - lenb) {
360 | Sb = s;
361 | lenb = i;
362 | };
363 | };
364 | };
365 |
366 | if (lastscan + lenf > scan - lenb) {
367 | overlap = (lastscan + lenf) - (scan - lenb);
368 | s = 0;
369 | Ss = 0;
370 | lens = 0;
371 | for (i = 0; i < overlap; i++) {
372 | if (new[lastscan + lenf - overlap + i]
373 | == old[lastpos + lenf - overlap + i])
374 | s++;
375 | if (new[scan - lenb + i] == old[pos - lenb + i])
376 | s--;
377 | if (s > Ss) {
378 | Ss = s;
379 | lens = i + 1;
380 | };
381 | };
382 |
383 | lenf += lens - overlap;
384 | lenb -= lens;
385 | };
386 |
387 | for (i = 0; i < lenf; i++)
388 | db[dblen + i] = new[lastscan + i] - old[lastpos + i];
389 | for (i = 0; i < (scan - lenb) - (lastscan + lenf); i++)
390 | eb[eblen + i] = new[lastscan + lenf + i];
391 |
392 | dblen += lenf;
393 | eblen += (scan - lenb) - (lastscan + lenf);
394 |
395 | offtout(lenf, buf);
396 | BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
397 | if (bz2err != BZ_OK) {
398 | LOGE("BZ2_bzWrite, bz2err = %d", bz2err);
399 | return 7;
400 |
401 | }
402 |
403 | offtout((scan - lenb) - (lastscan + lenf), buf);
404 | BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
405 | if (bz2err != BZ_OK) {
406 | LOGE("BZ2_bzWrite, bz2err = %d", bz2err);
407 | return 7;
408 |
409 | }
410 |
411 | offtout((pos - lenb) - (lastpos + lenf), buf);
412 | BZ2_bzWrite(&bz2err, pfbz2, buf, 8);
413 | if (bz2err != BZ_OK) {
414 | LOGE("BZ2_bzWrite, bz2err = %d", bz2err);
415 | return 7;
416 |
417 | }
418 |
419 | lastscan = scan - lenb;
420 | lastpos = pos - lenb;
421 | lastoffset = pos - scan;
422 | };
423 | };
424 | BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL );
425 | if (bz2err != BZ_OK) {
426 | LOGE("BZ2_bzWriteClose, bz2err = %d", bz2err);
427 | return 7;
428 |
429 | }
430 |
431 | /* Compute size of compressed ctrl data */
432 | if ((len = ftello(pf)) == -1) {
433 | LOGE("Compute size of compressed ctrl data fail");
434 | return 8;
435 | }
436 | offtout(len - 32, header + 8);
437 |
438 | /* Write compressed diff data */
439 | if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL ) {
440 | LOGE("BZ2_bzWriteOpen, bz2err = %d", bz2err);
441 | return 7;
442 |
443 | }
444 | BZ2_bzWrite(&bz2err, pfbz2, db, dblen);
445 | if (bz2err != BZ_OK) {
446 | LOGE("BZ2_bzWrite, bz2err = %d", bz2err);
447 | return 7;
448 |
449 | }
450 | BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL );
451 | if (bz2err != BZ_OK) {
452 | LOGE("BZ2_bzWriteClose, bz2err = %d", bz2err);
453 | return 7;
454 |
455 | }
456 |
457 | /* Compute size of compressed diff data */
458 | if ((newsize = ftello(pf)) == -1) {
459 | LOGE("Compute size of compressed ctrl data fail");
460 | return 8;
461 | }
462 | offtout(newsize - len, header + 16);
463 |
464 | /* Write compressed extra data */
465 | if ((pfbz2 = BZ2_bzWriteOpen(&bz2err, pf, 9, 0, 0)) == NULL ) {
466 | LOGE("BZ2_bzWriteOpen, bz2err = %d", bz2err);
467 | return 7;
468 |
469 | }
470 | BZ2_bzWrite(&bz2err, pfbz2, eb, eblen);
471 | if (bz2err != BZ_OK) {
472 | LOGE("BZ2_bzWrite, bz2err = %d", bz2err);
473 | return 7;
474 |
475 | }
476 | BZ2_bzWriteClose(&bz2err, pfbz2, 0, NULL, NULL );
477 | if (bz2err != BZ_OK) {
478 | LOGE("BZ2_bzWriteClose, bz2err = %d", bz2err);
479 | return 7;
480 | }
481 |
482 | /* Seek to the beginning, write the header, and close the file */
483 | if (fseeko(pf, 0, SEEK_SET)){
484 | LOGE("seek file fail");
485 | return 7;
486 | }
487 | if (fwrite(header, 32, 1, pf) != 1) {
488 | LOGE("write file fail");
489 | return 7;
490 | }
491 | if (fclose(pf)) {
492 | LOGE("close file fail");
493 | return 7;
494 | }
495 |
496 | /* Free the memory we used */
497 | free(db);
498 | free(eb);
499 | free(I);
500 | free(old);
501 | free(new);
502 |
503 | return 0;
504 | }
505 |
506 | JNIEXPORT jint JNICALL Java_com_wang_appupdate_util_PatchUtil_diff
507 | (JNIEnv *env, jclass cls, jstring old, jstring new, jstring patch) {
508 | int argc = 4;
509 | char * argv[argc];
510 | argv[0] = "bsdiff";
511 | argv[1] = (char*) ((*env)->GetStringUTFChars(env, old, 0));
512 | argv[2] = (char*) ((*env)->GetStringUTFChars(env, new, 0));
513 | argv[3] = (char*) ((*env)->GetStringUTFChars(env, patch, 0));
514 |
515 | LOGD("old apk = %s", argv[1]);
516 | LOGD("new apk = %s", argv[2]);
517 | LOGD("patch = %s", argv[3]);
518 |
519 | int ret = genpatch(argc, argv);
520 | LOGD("diff result %d", ret);
521 |
522 | (*env)->ReleaseStringUTFChars(env, old, argv[1]);
523 | (*env)->ReleaseStringUTFChars(env, new, argv[2]);
524 | (*env)->ReleaseStringUTFChars(env, patch, argv[3]);
525 |
526 | return ret;
527 | }
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/jni/patch.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include "bzip2/bzlib.h"
3 | #include
4 | #include
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include "util/android_log_print.h"
10 | #include "com_wang_appupdate_util_PatchUtil.h"
11 |
12 |
13 |
14 |
15 |
16 | static off_t offtin(u_char *buf)
17 | {
18 | off_t y;
19 |
20 | y=buf[7]&0x7F;
21 | y=y*256;y+=buf[6];
22 | y=y*256;y+=buf[5];
23 | y=y*256;y+=buf[4];
24 | y=y*256;y+=buf[3];
25 | y=y*256;y+=buf[2];
26 | y=y*256;y+=buf[1];
27 | y=y*256;y+=buf[0];
28 |
29 | if(buf[7]&0x80) y=-y;
30 |
31 | return y;
32 | }
33 |
34 | int applypatch(int argc,char * argv[])
35 | {
36 | FILE * f, * cpf, * dpf, * epf;
37 | BZFILE * cpfbz2, * dpfbz2, * epfbz2;
38 | int cbz2err, dbz2err, ebz2err;
39 | int fd;
40 | ssize_t oldsize,newsize;
41 | ssize_t bzctrllen,bzdatalen;
42 | u_char header[32],buf[8];
43 | u_char *old, *new;
44 | off_t oldpos,newpos;
45 | off_t ctrl[3];
46 | off_t lenread;
47 | off_t i;
48 |
49 | if(argc!=4) {
50 | LOGE("%s please usage: oldfile newfile patchfile three files", argv[0]);
51 | return 1;
52 | }
53 |
54 | /* Open patch file */
55 | if ((f = fopen(argv[3], "r")) == NULL) {
56 | LOGE("open %s fail", argv[3]);
57 | return 4;
58 | }
59 |
60 | /*
61 | File format:
62 | 0 8 "BSDIFF40"
63 | 8 8 X
64 | 16 8 Y
65 | 24 8 sizeof(newfile)
66 | 32 X bzip2(control block)
67 | 32+X Y bzip2(diff block)
68 | 32+X+Y ??? bzip2(extra block)
69 | with control block a set of triples (x,y,z) meaning "add x bytes
70 | from oldfile to x bytes from the diff block; copy y bytes from the
71 | extra block; seek forwards in oldfile by z bytes".
72 | */
73 |
74 | /* Read header */
75 | if (fread(header, 1, 32, f) < 32) {
76 | if (feof(f)){
77 | LOGE("Corrupt patch");
78 | return 9;
79 | }
80 | LOGE("read %s fail", argv[3]);
81 | return 4;
82 | }
83 |
84 | /* Check for appropriate magic */
85 | if (memcmp(header, "BSDIFF40", 8) != 0) {
86 | LOGE("Corrupt patch");
87 | return 9;
88 | }
89 |
90 | /* Read lengths from header */
91 | bzctrllen=offtin(header+8);
92 | bzdatalen=offtin(header+16);
93 | newsize=offtin(header+24);
94 | if((bzctrllen<0) || (bzdatalen<0) || (newsize<0)) {
95 | LOGE("Corrupt patch");
96 | return 9;
97 | }
98 |
99 | /* Close patch file and re-open it via libbzip2 at the right places */
100 | if (fclose(f)){
101 | LOGE("close %s fail", argv[3]);
102 | return 4;
103 | }
104 | if ((cpf = fopen(argv[3], "r")) == NULL) {
105 | LOGE("open %s fail", argv[3]);
106 | return 4;
107 | }
108 | if (fseeko(cpf, 32, SEEK_SET)){
109 | LOGE("seeko(%s, %lld) fail", argv[3], (long long)32);
110 | return 4;
111 | }
112 | if ((cpfbz2 = BZ2_bzReadOpen(&cbz2err, cpf, 0, 0, NULL, 0)) == NULL) {
113 | LOGE("BZ2_bzReadOpen, bz2err = %d", cbz2err);
114 | return 10;
115 | }
116 | if ((dpf = fopen(argv[3], "r")) == NULL) {
117 | LOGE("open %s fail", argv[3]);
118 | return 4;
119 | }
120 | if (fseeko(dpf, 32 + bzctrllen, SEEK_SET)) {
121 | LOGE("seeko(%s, %lld) fail", argv[3], (long long)32);
122 | return 4;
123 | }
124 | if ((dpfbz2 = BZ2_bzReadOpen(&dbz2err, dpf, 0, 0, NULL, 0)) == NULL) {
125 | LOGE("BZ2_bzReadOpen, bz2err = %d", cbz2err);
126 | return 10;
127 | }
128 | if ((epf = fopen(argv[3], "r")) == NULL) {
129 | LOGE("open %s fail", argv[3]);
130 | return 4;
131 | }
132 | if (fseeko(epf, 32 + bzctrllen + bzdatalen, SEEK_SET)) {
133 | LOGE("seeko(%s, %lld) fail", argv[3], (long long)32);
134 | return 4;
135 | }
136 | if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL) {
137 | LOGE("BZ2_bzReadOpen, bz2err = %d", cbz2err);
138 | return 10;
139 | }
140 |
141 | if(((fd=open(argv[1],O_RDONLY,0))<0) ||
142 | ((oldsize=lseek(fd,0,SEEK_END))==-1) ||
143 | ((old=malloc(oldsize+1))==NULL) ||
144 | (lseek(fd,0,SEEK_SET)!=0) ||
145 | (read(fd,old,oldsize)!=oldsize) ||
146 | (close(fd)==-1)) {
147 | LOGE("read %s is fail", argv[1]);
148 | return 2;
149 | }
150 | if((new=malloc(newsize+1))==NULL) {
151 | LOGE("Memory allocation is fail");
152 | return 5;
153 | }
154 |
155 | oldpos=0;newpos=0;
156 | while(newposnewsize) {
170 | LOGE("Corrupt patch");
171 | return 9;
172 | }
173 |
174 | /* Read diff string */
175 | lenread = BZ2_bzRead(&dbz2err, dpfbz2, new + newpos, ctrl[0]);
176 | if ((lenread < ctrl[0]) ||
177 | ((dbz2err != BZ_OK) && (dbz2err != BZ_STREAM_END))) {
178 | LOGE("Corrupt patch");
179 | return 9;
180 | }
181 |
182 | /* Add old data to diff string */
183 | for(i=0;i=0) && (oldpos+inewsize) {
193 | LOGE("Corrupt patch");
194 | return 9;
195 | }
196 |
197 | /* Read extra string */
198 | lenread = BZ2_bzRead(&ebz2err, epfbz2, new + newpos, ctrl[1]);
199 | if ((lenread < ctrl[1]) ||
200 | ((ebz2err != BZ_OK) && (ebz2err != BZ_STREAM_END))) {
201 | LOGE("Corrupt patch");
202 | return 9;
203 | }
204 |
205 | /* Adjust pointers */
206 | newpos+=ctrl[1];
207 | oldpos+=ctrl[2];
208 | };
209 |
210 | /* Clean up the bzip2 reads */
211 | BZ2_bzReadClose(&cbz2err, cpfbz2);
212 | BZ2_bzReadClose(&dbz2err, dpfbz2);
213 | BZ2_bzReadClose(&ebz2err, epfbz2);
214 | if (fclose(cpf) || fclose(dpf) || fclose(epf)) {
215 | LOGE("close %s fail", argv[3]);
216 | return 4;
217 | }
218 |
219 | /* Write the new file */
220 | if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) ||
221 | (write(fd,new,newsize)!=newsize) || (close(fd)==-1)) {
222 | LOGE("write %s fail", argv[2]);
223 | return 10;
224 | }
225 |
226 | free(new);
227 | free(old);
228 |
229 | return 0;
230 | }
231 |
232 | JNIEXPORT jint JNICALL Java_com_wang_appupdate_util_PatchUtil_patch
233 | (JNIEnv *env, jclass cls,
234 | jstring old, jstring new, jstring patch){
235 | int argc = 4;
236 | char * argv[argc];
237 | argv[0] = "bspatch";
238 | argv[1] = (char*) ((*env)->GetStringUTFChars(env, old, 0));
239 | argv[2] = (char*) ((*env)->GetStringUTFChars(env, new, 0));
240 | argv[3] = (char*) ((*env)->GetStringUTFChars(env, patch, 0));
241 |
242 | LOGD("old apk = %s \n", argv[1]);
243 | LOGD("patch = %s \n", argv[3]);
244 | LOGD("new apk = %s \n", argv[2]);
245 |
246 | int ret = applypatch(argc, argv);
247 | LOGD("patch result = %d ", ret);
248 |
249 | (*env)->ReleaseStringUTFChars(env, old, argv[1]);
250 | (*env)->ReleaseStringUTFChars(env, new, argv[2]);
251 | (*env)->ReleaseStringUTFChars(env, patch, argv[3]);
252 | return ret;
253 | }
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/jni/util/android_log_print.h:
--------------------------------------------------------------------------------
1 | //
2 | // Created by wang on 2016/9/9.
3 | //
4 |
5 | #ifndef APPUPDATE_ANDROID_LOG_PRINT_H
6 | #define APPUPDATE_ANDROID_LOG_PRINT_H
7 |
8 | #include
9 |
10 | #define IS_DEBUG
11 |
12 | #ifdef IS_DEBUG
13 |
14 | #define LOG_TAG ("JNI_LOG")
15 |
16 | #define LOGV(...) ((void)__android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__))
17 |
18 | #define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG , LOG_TAG, __VA_ARGS__))
19 |
20 | #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO , LOG_TAG, __VA_ARGS__))
21 |
22 | #define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN , LOG_TAG, __VA_ARGS__))
23 |
24 | #define LOGE(...) ((void)__android_log_print(ANDROID_LOG_ERROR , LOG_TAG, __VA_ARGS__))
25 |
26 | #else
27 |
28 | #define LOGV(LOG_TAG, ...) NULL
29 |
30 | #define LOGD(LOG_TAG, ...) NULL
31 |
32 | #define LOGI(LOG_TAG, ...) NULL
33 |
34 | #define LOGW(LOG_TAG, ...) NULL
35 |
36 | #define LOGE(LOG_TAG, ...) NULL
37 |
38 | #endif
39 |
40 | #endif //APPUPDATE_ANDROID_LOG_PRINT_H
41 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
12 |
13 |
18 |
19 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingwang666/AppAddUpdate/2a5fe4dd91c6781eb72b30f452333bbb5f4461da/AppUpdate/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingwang666/AppAddUpdate/2a5fe4dd91c6781eb72b30f452333bbb5f4461da/AppUpdate/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingwang666/AppAddUpdate/2a5fe4dd91c6781eb72b30f452333bbb5f4461da/AppUpdate/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingwang666/AppAddUpdate/2a5fe4dd91c6781eb72b30f452333bbb5f4461da/AppUpdate/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingwang666/AppAddUpdate/2a5fe4dd91c6781eb72b30f452333bbb5f4461da/AppUpdate/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | AppUpdate
3 |
4 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/AppUpdate/app/src/test/java/com/wang/appupdate/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package com.wang.appupdate;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * To work on unit tests, switch the Test Artifact in the Build Variants view.
9 | */
10 | public class ExampleUnitTest {
11 | @Test
12 | public void addition_isCorrect() throws Exception {
13 | assertEquals(4, 2 + 2);
14 | }
15 | }
--------------------------------------------------------------------------------
/AppUpdate/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.2'
9 |
10 | // NOTE: Do not place your application dependencies here; they belong
11 | // in the individual module build.gradle files
12 | }
13 | }
14 |
15 | allprojects {
16 | repositories {
17 | jcenter()
18 | }
19 | }
20 |
21 | task clean(type: Delete) {
22 | delete rootProject.buildDir
23 | }
24 |
--------------------------------------------------------------------------------
/AppUpdate/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m
13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
14 |
15 | # When configured, Gradle will run in incubating parallel mode.
16 | # This option should only be used with decoupled projects. More details, visit
17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
18 | # org.gradle.parallel=true
19 | android.useDeprecatedNdk=true
--------------------------------------------------------------------------------
/AppUpdate/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/kingwang666/AppAddUpdate/2a5fe4dd91c6781eb72b30f452333bbb5f4461da/AppUpdate/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/AppUpdate/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Sep 08 14:40:20 CST 2016
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/AppUpdate/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/AppUpdate/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/AppUpdate/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright 2016 kingwang666
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AppAddUpdate #
2 |
3 | [  ](https://bintray.com/kingwang666/maven/appupdate/1.0.2/link)
4 |
5 | Android app 增量更新
6 |
7 | 参考[https://github.com/cundong/SmartAppUpdates](https://github.com/cundong/SmartAppUpdates)
8 |
9 | 该app未提供服务端代码(服务端代码的增量更新实现可参考diff.c和patch.c,原理和客户端一致)
10 |
11 | ## ScreenShoots ##
12 | 
13 |
14 | ## Gradle
15 | `implementation 'com.wang.appupdate:appupdate:1.0.2'`
16 |
17 | ## Android Studio NDK ##
18 | 1. 首先下载NDK
19 | 
20 | 2. 在项目的gradle.properties文件下添加android.useDeprecatedNdk=true
21 | 3. 新建含有native方法的类(如 PatchUtil.java)
22 | 4. 编译一下在`app\build\intermediates\classes\debug`目录下对应类的包名下会自动创建出PatchUtil.clasee
23 | 5. 点击Android Studio的Terminal进入`app\build\intermediates\classes\debug`目录下
24 | 6. Android Studio2.0及以上输入`javah -classpath . -jni om.wang.appupdate.util(packName).PatchUtil(ClassName)` 其他版本输入`javah -jni om.wang.appupdate.util(packName).PatchUtil(ClassName)`创建对应的.h文件(在`app\build\intermediates\classes\debug`根目录下)
25 | 7. 新建jni文件夹
26 | 
27 | 创建的.h文件剪切过来。编写对应的c文件(**命名随意**)
28 | 8. 在app的build.gradle配置
29 | 
30 | 9. 运行即可,对应的.so在文件夹
31 | 
32 |
33 | ## API ##
34 | ### PatchUtil ###
35 | - `int diff(String oldApkPath, String newApkPath,String patchPath)`
36 | 比较路径为oldPath的apk与newPath的apk之间差异,并生成patch包.
37 |
38 |
39 | - `int patch(String oldApkPath, String newApkPath, String patchPath)`
40 | 使用路径为oldApkPath的apk与路径为patchPath的补丁包,合成新的apk,并存储newApkPath
41 | ### 返回码 ###
42 | 0-success
43 | 1-缺少文件路径
44 | 2-读取旧apk失败
45 | 3-读取新的apk失败
46 | 4-打开或读取patch文件失败
47 | 5-内存分配失败
48 | 6-创建、打开或读取patch文件失败
49 | 7-计算文件差异性或者写入patch文件失败
50 | 8-计算压缩的大小差异数据失败
51 | 9-无用的patch补丁
52 | 10-合并apk失败
53 |
54 | ### SignUtil ###
55 | - `String getMd5ByFile(File file)`
56 | 获取对应文件的md5值
57 |
58 | - `boolean checkMd5(File file, String md5)`
59 | 判断文件的MD5是否为指定值
60 |
61 | - `boolean checkMd5(String filePath, String md5)`
62 | 判断文件的MD5是否为指定值
63 |
64 | ### ApkUtil ###
65 |
66 |
67 | - `PackageInfo getInstalledApkPackageInfo(Context context, String packageName)`
68 | 获取已安装apk的PackageInfo
69 |
70 |
71 | - `boolean isInstalled(Context context, String packageName)`
72 | 判断apk是否已安装
73 |
74 |
75 | - `String getSourceApkPath(Context context, String packageName)`
76 | 获取已安装Apk文件的源Apk文件
77 |
78 |
79 | - `String getSourceApkPath(Context context)`
80 | 获取已安装Apk文件的源Apk文件
81 |
82 |
83 | - `void installApk(Context context, String apkPath)`
84 | 安装Apk
85 |
--------------------------------------------------------------------------------